diff --git a/examples/AnimationAppExample/AnimationAppExample.jucer b/examples/AnimationAppExample/AnimationAppExample.jucer index 491ebc68d7..bbcd3166ba 100644 --- a/examples/AnimationAppExample/AnimationAppExample.jucer +++ b/examples/AnimationAppExample/AnimationAppExample.jucer @@ -82,19 +82,19 @@ - - - - - - - - - - - - - + + + + + + + + + + + + + diff --git a/examples/AnimationAppExample/Builds/MacOSX/AnimationAppExample.xcodeproj/project.pbxproj b/examples/AnimationAppExample/Builds/MacOSX/AnimationAppExample.xcodeproj/project.pbxproj index 9ebfb5e93e..d3d611fd91 100644 --- a/examples/AnimationAppExample/Builds/MacOSX/AnimationAppExample.xcodeproj/project.pbxproj +++ b/examples/AnimationAppExample/Builds/MacOSX/AnimationAppExample.xcodeproj/project.pbxproj @@ -22,1303 +22,1303 @@ 6B6DC7D7A606A7D832929888 = {isa = PBXBuildFile; fileRef = 7E8B563CE147A7C733E6EFB1; }; 328BFAEA24EDCBF7B69F4960 = {isa = PBXBuildFile; fileRef = B766DBADE0BD743FAC004870; }; 84E6553798838003062A7791 = {isa = PBXBuildFile; fileRef = F7B6DBDC7439C90B4E01752E; }; - EF96289AD85C80471CACC5B6 = {isa = PBXBuildFile; fileRef = 50CCC0CC14D17378013CFD72; }; - 6E1751B19D4AF902E028A7C7 = {isa = PBXBuildFile; fileRef = 08216A0328094D5809860DEB; }; - B1220D75CDAD50F3CA57D1A1 = {isa = PBXBuildFile; fileRef = BC3EB76C434A2FDAC6C46DB2; }; - 1C90AD3A9B9B5E9DE33BD2DE = {isa = PBXBuildFile; fileRef = CB3D07088AB905BD96AD3A90; }; - 777C7919C5F3C67E528286A1 = {isa = PBXBuildFile; fileRef = 7FB3628856C8E532EB8421CA; }; - E3AF28976801708F8CD9A656 = {isa = PBXBuildFile; fileRef = D728D4777A842A58EC01454A; }; - A8E9942AA157F768897FBBA2 = {isa = PBXBuildFile; fileRef = B6B4BC87EEA6BFF7A739D118; }; - 937B4A84B983E2AAA040F976 = {isa = PBXBuildFile; fileRef = 369EE12DB339DA919C8BF5F6; }; - EBFF0D5A17F1D61FC28BA178 = {isa = PBXBuildFile; fileRef = 1291E6270CA79ACEEEFB2636; }; - 129DFE2B7F1FDEE81E188D21 = {isa = PBXBuildFile; fileRef = 1DAF43BE112A30BC560E95ED; }; - 79A28D1FFAEAC8D7127BDE2F = {isa = PBXBuildFile; fileRef = 5A8383F3E5B628DE60DB8291; }; - 526057FC6638B0BB7B984637 = {isa = PBXBuildFile; fileRef = 1A355A0DDA216F713372DF88; }; - 2FCBB2DDE322D55AFEF262AF = {isa = PBXBuildFile; fileRef = 98FBBFD68CCC9D52B62BFFEE; }; - 000879A4FF2FFA74721C7CB5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioFormatManager.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_formats/format/juce_AudioFormatManager.cpp"; sourceTree = "SOURCE_ROOT"; }; - 005BC9B639854EA82BE9D1C4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DragAndDropTarget.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/mouse/juce_DragAndDropTarget.h"; sourceTree = "SOURCE_ROOT"; }; - 0125A6E329679354E74D2FB4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_VST3Headers.h"; path = "../../JuceLibraryCode/modules/juce_audio_processors/format_types/juce_VST3Headers.h"; sourceTree = "SOURCE_ROOT"; }; - 015EBD22B273B9E6FA96D62F = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Application.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/application/juce_Application.h"; sourceTree = "SOURCE_ROOT"; }; - 0180E266C4D70BE9C67AB07A = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Quaternion.h"; path = "../../JuceLibraryCode/modules/juce_opengl/geometry/juce_Quaternion.h"; sourceTree = "SOURCE_ROOT"; }; - 01E3FAE5B663BB39B4317ADD = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Toolbar.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/widgets/juce_Toolbar.cpp"; sourceTree = "SOURCE_ROOT"; }; - 01E5B72E5D7115CFF884BB86 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_SpinLock.h"; path = "../../JuceLibraryCode/modules/juce_core/threads/juce_SpinLock.h"; sourceTree = "SOURCE_ROOT"; }; - 01FF42E4D2A331779AB0A72C = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_OpenGLGraphicsContext.cpp"; path = "../../JuceLibraryCode/modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.cpp"; sourceTree = "SOURCE_ROOT"; }; - 0207C77289467D58A696794B = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ArrowButton.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/buttons/juce_ArrowButton.h"; sourceTree = "SOURCE_ROOT"; }; - 024386A2F47243403C1E2A51 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_mac_CoreAudio.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_devices/native/juce_mac_CoreAudio.cpp"; sourceTree = "SOURCE_ROOT"; }; - 02BE2D3F87C20BD46CEC2981 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TextDiff.h"; path = "../../JuceLibraryCode/modules/juce_core/text/juce_TextDiff.h"; sourceTree = "SOURCE_ROOT"; }; - 0356E85B3D1970B78228D974 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AiffAudioFormat.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_formats/codecs/juce_AiffAudioFormat.cpp"; sourceTree = "SOURCE_ROOT"; }; - 036DAC2B35EB0E89897CDAF7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_MouseCursor.mm"; path = "../../JuceLibraryCode/modules/juce_gui_basics/native/juce_mac_MouseCursor.mm"; sourceTree = "SOURCE_ROOT"; }; - 037977A3CA69858654B749F2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ComponentMovementWatcher.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/layout/juce_ComponentMovementWatcher.h"; sourceTree = "SOURCE_ROOT"; }; - 03D53D0D12365594CC24EA4D = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OggVorbisAudioFormat.h"; path = "../../JuceLibraryCode/modules/juce_audio_formats/codecs/juce_OggVorbisAudioFormat.h"; sourceTree = "SOURCE_ROOT"; }; - 03D597E4C12113FB74016803 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AlertWindow.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/windows/juce_AlertWindow.cpp"; sourceTree = "SOURCE_ROOT"; }; - 03E3F0BF99B3C180F9531411 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ShapeButton.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/buttons/juce_ShapeButton.h"; sourceTree = "SOURCE_ROOT"; }; - 03F15E955CC6905BAC120050 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_CommonFile.cpp"; path = "../../JuceLibraryCode/modules/juce_core/native/juce_linux_CommonFile.cpp"; sourceTree = "SOURCE_ROOT"; }; - 042881A3BC502717D187F4DF = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OpenGL_win32.h"; path = "../../JuceLibraryCode/modules/juce_opengl/native/juce_OpenGL_win32.h"; sourceTree = "SOURCE_ROOT"; }; - 053C2C09700A8BD5DB4B416B = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_NormalisableRange.h"; path = "../../JuceLibraryCode/modules/juce_core/maths/juce_NormalisableRange.h"; sourceTree = "SOURCE_ROOT"; }; - 057EDA2ADAE5945C87E9E94C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_NotificationType.h"; path = "../../JuceLibraryCode/modules/juce_events/messages/juce_NotificationType.h"; sourceTree = "SOURCE_ROOT"; }; - 05D3F009C15785143F3D31E3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Value.cpp"; path = "../../JuceLibraryCode/modules/juce_data_structures/values/juce_Value.cpp"; sourceTree = "SOURCE_ROOT"; }; - 064D5359A45F91751130CB6C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_SortedSet.h"; path = "../../JuceLibraryCode/modules/juce_core/containers/juce_SortedSet.h"; sourceTree = "SOURCE_ROOT"; }; - 0654450BCEE57AB7EC882CBC = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_AudioCDBurner.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_devices/native/juce_win32_AudioCDBurner.cpp"; sourceTree = "SOURCE_ROOT"; }; - 069199E3E835739AF23FAC10 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_VST3PluginFormat.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_processors/format_types/juce_VST3PluginFormat.cpp"; sourceTree = "SOURCE_ROOT"; }; - 069F8377EE5A3A1B8417E1BB = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_FileChooser.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/native/juce_linux_FileChooser.cpp"; sourceTree = "SOURCE_ROOT"; }; - 06D18753FCA84429B281A7CB = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_NSViewComponentPeer.mm"; path = "../../JuceLibraryCode/modules/juce_gui_basics/native/juce_mac_NSViewComponentPeer.mm"; sourceTree = "SOURCE_ROOT"; }; - 071119F515B16F354C9D5D22 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ResizableEdgeComponent.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/layout/juce_ResizableEdgeComponent.h"; sourceTree = "SOURCE_ROOT"; }; - 076626EB667106684FC3F5C5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DropShadowEffect.h"; path = "../../JuceLibraryCode/modules/juce_graphics/effects/juce_DropShadowEffect.h"; sourceTree = "SOURCE_ROOT"; }; - 076B1F9E89390D3CFE7B6F8E = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_StretchableObjectResizer.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/layout/juce_StretchableObjectResizer.h"; sourceTree = "SOURCE_ROOT"; }; - 077B15886A49C2DF26EB7186 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TemporaryFile.h"; path = "../../JuceLibraryCode/modules/juce_core/files/juce_TemporaryFile.h"; sourceTree = "SOURCE_ROOT"; }; - 07DB1C038E8EF1D3628F6B7A = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_File.h"; path = "../../JuceLibraryCode/modules/juce_core/files/juce_File.h"; sourceTree = "SOURCE_ROOT"; }; - 0801100E90790AD44224848A = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DirectoryIterator.h"; path = "../../JuceLibraryCode/modules/juce_core/files/juce_DirectoryIterator.h"; sourceTree = "SOURCE_ROOT"; }; - 08216A0328094D5809860DEB = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_audio_devices.mm"; path = "../../JuceLibraryCode/modules/juce_audio_devices/juce_audio_devices.mm"; sourceTree = "SOURCE_ROOT"; }; - 08684D02269A6462E874F392 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AsyncUpdater.h"; path = "../../JuceLibraryCode/modules/juce_events/broadcasters/juce_AsyncUpdater.h"; sourceTree = "SOURCE_ROOT"; }; - 08BB70992D33D8DEF932E9BB = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AttributedString.h"; path = "../../JuceLibraryCode/modules/juce_graphics/fonts/juce_AttributedString.h"; sourceTree = "SOURCE_ROOT"; }; - 08CAAD932D355E493366CEF3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_LeakedObjectDetector.h"; path = "../../JuceLibraryCode/modules/juce_core/memory/juce_LeakedObjectDetector.h"; sourceTree = "SOURCE_ROOT"; }; - 08CE1157B27F232F61111F04 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FileDragAndDropTarget.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/mouse/juce_FileDragAndDropTarget.h"; sourceTree = "SOURCE_ROOT"; }; - 09043DFD1720837A928ECA06 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioFormat.h"; path = "../../JuceLibraryCode/modules/juce_audio_formats/format/juce_AudioFormat.h"; sourceTree = "SOURCE_ROOT"; }; - 0906C93F178388D7783BCC92 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MD5.cpp"; path = "../../JuceLibraryCode/modules/juce_cryptography/hashing/juce_MD5.cpp"; sourceTree = "SOURCE_ROOT"; }; - 094EBE616E535FEACF39583B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_InterprocessConnectionServer.cpp"; path = "../../JuceLibraryCode/modules/juce_events/interprocess/juce_InterprocessConnectionServer.cpp"; sourceTree = "SOURCE_ROOT"; }; - 09BB7D020FA96EB044330205 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_XmlElement.h"; path = "../../JuceLibraryCode/modules/juce_core/xml/juce_XmlElement.h"; sourceTree = "SOURCE_ROOT"; }; - 0A431A685E635E51B2E20FB7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioUnitPluginFormat.h"; path = "../../JuceLibraryCode/modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.h"; sourceTree = "SOURCE_ROOT"; }; - 0A5ED9AFC5906343E514100D = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ApplicationCommandTarget.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/commands/juce_ApplicationCommandTarget.cpp"; sourceTree = "SOURCE_ROOT"; }; - 0A79B3C2BCCFF8C8D9837210 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_Files.cpp"; path = "../../JuceLibraryCode/modules/juce_core/native/juce_linux_Files.cpp"; sourceTree = "SOURCE_ROOT"; }; - 0A7FBABADCBBF00C2A842D37 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_StringArray.h"; path = "../../JuceLibraryCode/modules/juce_core/text/juce_StringArray.h"; sourceTree = "SOURCE_ROOT"; }; - 0B22BB6E27076BA1B6459249 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_PropertyPanel.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/properties/juce_PropertyPanel.h"; sourceTree = "SOURCE_ROOT"; }; - 0B4FA008BF447F4334E24693 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_GlowEffect.cpp"; path = "../../JuceLibraryCode/modules/juce_graphics/effects/juce_GlowEffect.cpp"; sourceTree = "SOURCE_ROOT"; }; - 0C4D86B553BCA2945973736E = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_core.h"; path = "../../JuceLibraryCode/modules/juce_core/juce_core.h"; sourceTree = "SOURCE_ROOT"; }; - 0C8CE60E5ADA256EC7311C40 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ResizableBorderComponent.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/layout/juce_ResizableBorderComponent.h"; sourceTree = "SOURCE_ROOT"; }; - 0CB666093FEE15ED3782D60C = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioFormatReader.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_formats/format/juce_AudioFormatReader.cpp"; sourceTree = "SOURCE_ROOT"; }; - 0CF71E055B7DC5BB25E8CC20 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Font.h"; path = "../../JuceLibraryCode/modules/juce_graphics/fonts/juce_Font.h"; sourceTree = "SOURCE_ROOT"; }; - 0E261C336A94816F61F6D1F9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_XMLCodeTokeniser.h"; path = "../../JuceLibraryCode/modules/juce_gui_extra/code_editor/juce_XMLCodeTokeniser.h"; sourceTree = "SOURCE_ROOT"; }; - 0E4F0DA9ECA921AF8E835E19 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ChildProcess.h"; path = "../../JuceLibraryCode/modules/juce_core/threads/juce_ChildProcess.h"; sourceTree = "SOURCE_ROOT"; }; - 0FF684B2342825C25B6D5DBA = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_QuickTimeMovieComponent.h"; path = "../../JuceLibraryCode/modules/juce_video/playback/juce_QuickTimeMovieComponent.h"; sourceTree = "SOURCE_ROOT"; }; - 106CB8DA346ABAC39F9CBF67 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_QuickTimeMovieComponent.cpp"; path = "../../JuceLibraryCode/modules/juce_video/native/juce_win32_QuickTimeMovieComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; - 112A4FE3483942AF43D513DA = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MidiInput.h"; path = "../../JuceLibraryCode/modules/juce_audio_devices/midi_io/juce_MidiInput.h"; sourceTree = "SOURCE_ROOT"; }; - 11736C186EBE80F228E1D782 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_UnitTest.h"; path = "../../JuceLibraryCode/modules/juce_core/unit_tests/juce_UnitTest.h"; sourceTree = "SOURCE_ROOT"; }; - 1173B2E45074397470CD6EA6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Image.cpp"; path = "../../JuceLibraryCode/modules/juce_graphics/images/juce_Image.cpp"; sourceTree = "SOURCE_ROOT"; }; - 117555C684D0E7FB5ADDB891 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_mac_CoreMidi.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_devices/native/juce_mac_CoreMidi.cpp"; sourceTree = "SOURCE_ROOT"; }; - 11930669FC3C726CD1F9712F = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AnimatedAppComponent.h"; path = "../../JuceLibraryCode/modules/juce_gui_extra/misc/juce_AnimatedAppComponent.h"; sourceTree = "SOURCE_ROOT"; }; - 12503429614C443A89A28FB2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_RelativeTime.cpp"; path = "../../JuceLibraryCode/modules/juce_core/time/juce_RelativeTime.cpp"; sourceTree = "SOURCE_ROOT"; }; - 1291E6270CA79ACEEEFB2636 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_graphics.mm"; path = "../../JuceLibraryCode/modules/juce_graphics/juce_graphics.mm"; sourceTree = "SOURCE_ROOT"; }; - 12967F8EBAF9698288C8A5D0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_StringArray.cpp"; path = "../../JuceLibraryCode/modules/juce_core/text/juce_StringArray.cpp"; sourceTree = "SOURCE_ROOT"; }; - 13287EAB1073ED487FE17034 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MidiOutput.h"; path = "../../JuceLibraryCode/modules/juce_audio_devices/midi_io/juce_MidiOutput.h"; sourceTree = "SOURCE_ROOT"; }; - 134C3956C7C8E7CF6CEE8868 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_OggVorbisAudioFormat.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_formats/codecs/juce_OggVorbisAudioFormat.cpp"; sourceTree = "SOURCE_ROOT"; }; - 135F8FB24D69C7E8BE59185F = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TooltipClient.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/mouse/juce_TooltipClient.h"; sourceTree = "SOURCE_ROOT"; }; - 13BC4980571374E9F0243F0E = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_NativeMessageBox.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/windows/juce_NativeMessageBox.h"; sourceTree = "SOURCE_ROOT"; }; - 14875F3B31704358EBBB4F9C = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_PathIterator.cpp"; path = "../../JuceLibraryCode/modules/juce_graphics/geometry/juce_PathIterator.cpp"; sourceTree = "SOURCE_ROOT"; }; - 150E68F9290BA3701DCABDAE = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_IPAddress.h"; path = "../../JuceLibraryCode/modules/juce_core/network/juce_IPAddress.h"; sourceTree = "SOURCE_ROOT"; }; - 150EE812D88AFDBB98C0A539 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ToolbarItemFactory.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/widgets/juce_ToolbarItemFactory.h"; sourceTree = "SOURCE_ROOT"; }; - 1557FF99F272F107A90B15DF = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Identifier.h"; path = "../../JuceLibraryCode/modules/juce_core/text/juce_Identifier.h"; sourceTree = "SOURCE_ROOT"; }; - 158D17EA6E11AEEEA7D524D3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ImageFileFormat.cpp"; path = "../../JuceLibraryCode/modules/juce_graphics/images/juce_ImageFileFormat.cpp"; sourceTree = "SOURCE_ROOT"; }; + 9B303E67BC0058053878030C = {isa = PBXBuildFile; fileRef = C1070E62B763F1CCE0BB18F0; }; + ACA92239BEB4C05C418642E2 = {isa = PBXBuildFile; fileRef = DD19124F0A7FD43F31BDEB87; }; + 1EFD155B1968AEC88851F831 = {isa = PBXBuildFile; fileRef = 987AD2821B6419D5FEDCBD7A; }; + 0C7388B5872921063FF273B8 = {isa = PBXBuildFile; fileRef = AD405DDE86D07F955E27EBF8; }; + 9EE1754A8E5230FA1C50713F = {isa = PBXBuildFile; fileRef = B7DD84C8B05ABA4A6915E77E; }; + 1852E56533842FDFBE9A6EE3 = {isa = PBXBuildFile; fileRef = 33E449DEA1FC0CD4CAA3A829; }; + CB79C1D77F4FBF0C64B69E1D = {isa = PBXBuildFile; fileRef = 14BB261A450674034E6080F2; }; + 5E9EFF0130B8CBBEAA0D321B = {isa = PBXBuildFile; fileRef = CC0B7738BD544B955D81BF1E; }; + EF8AB3F393E946FE4A21AA17 = {isa = PBXBuildFile; fileRef = 4B27A11ADAC0D9957BBBCD3E; }; + B70DDF51EDD940F5EF96B96D = {isa = PBXBuildFile; fileRef = 27B720A5E8CF81ABF9E50848; }; + E28816D62DAA38A2794ED6D2 = {isa = PBXBuildFile; fileRef = D8BAA82AC820CEF315BD9DCB; }; + A911433D03B3314558DB8850 = {isa = PBXBuildFile; fileRef = 21CF5364CD4910E49D19F8E2; }; + 590ABC7E64B05F4814FA919E = {isa = PBXBuildFile; fileRef = 6018A3A37F34AE52B39A14D5; }; + 0054E026B84A3A87020CCE48 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MenuBarComponent.h"; path = "../../../../modules/juce_gui_basics/menus/juce_MenuBarComponent.h"; sourceTree = "SOURCE_ROOT"; }; + 0060F61BFBCEF4E9EF8B3CC0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_KeyListener.cpp"; path = "../../../../modules/juce_gui_basics/keyboard/juce_KeyListener.cpp"; sourceTree = "SOURCE_ROOT"; }; + 02AC998E808CAF5C148CFFC5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_Files.cpp"; path = "../../../../modules/juce_core/native/juce_win32_Files.cpp"; sourceTree = "SOURCE_ROOT"; }; + 02C14E49091F42750CD72F00 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Button.h"; path = "../../../../modules/juce_gui_basics/buttons/juce_Button.h"; sourceTree = "SOURCE_ROOT"; }; + 0311666DB95BFAE686267D7C = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_LagrangeInterpolator.cpp"; path = "../../../../modules/juce_audio_basics/effects/juce_LagrangeInterpolator.cpp"; sourceTree = "SOURCE_ROOT"; }; + 03457E9DD2B35D7C1B0C7393 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_PathStrokeType.h"; path = "../../../../modules/juce_graphics/geometry/juce_PathStrokeType.h"; sourceTree = "SOURCE_ROOT"; }; + 0346DBE09BEC27EA93676FEB = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ThreadWithProgressWindow.cpp"; path = "../../../../modules/juce_gui_basics/windows/juce_ThreadWithProgressWindow.cpp"; sourceTree = "SOURCE_ROOT"; }; + 03B79DBA48F6C4122DABEE90 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_SystemStats.h"; path = "../../../../modules/juce_core/system/juce_SystemStats.h"; sourceTree = "SOURCE_ROOT"; }; + 03D03AF17C5E899ED9481518 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FloatVectorOperations.h"; path = "../../../../modules/juce_audio_basics/buffers/juce_FloatVectorOperations.h"; sourceTree = "SOURCE_ROOT"; }; + 03E91AE23ECCF51E3AF9FC90 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_XmlDocument.cpp"; path = "../../../../modules/juce_core/xml/juce_XmlDocument.cpp"; sourceTree = "SOURCE_ROOT"; }; + 04C105672DA409FE8593DB04 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_SystemAudioVolume.h"; path = "../../../../modules/juce_audio_devices/audio_io/juce_SystemAudioVolume.h"; sourceTree = "SOURCE_ROOT"; }; + 0700C7069E1CF3FF8966C0E3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_LookAndFeel.cpp"; path = "../../../../modules/juce_gui_basics/lookandfeel/juce_LookAndFeel.cpp"; sourceTree = "SOURCE_ROOT"; }; + 07342D914D2A5AF6075CDB2D = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_StandardHeader.h"; path = "../../../../modules/juce_core/system/juce_StandardHeader.h"; sourceTree = "SOURCE_ROOT"; }; + 0790EC941834B64EA1AC8D5A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_PreferencesPanel.cpp"; path = "../../../../modules/juce_gui_extra/misc/juce_PreferencesPanel.cpp"; sourceTree = "SOURCE_ROOT"; }; + 07C83735435D264F28158F79 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_WildcardFileFilter.cpp"; path = "../../../../modules/juce_core/files/juce_WildcardFileFilter.cpp"; sourceTree = "SOURCE_ROOT"; }; + 07E19FB806980020A47AA47D = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_OutputStream.cpp"; path = "../../../../modules/juce_core/streams/juce_OutputStream.cpp"; sourceTree = "SOURCE_ROOT"; }; + 0852A866937712A0D30684A0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_XMLCodeTokeniser.cpp"; path = "../../../../modules/juce_gui_extra/code_editor/juce_XMLCodeTokeniser.cpp"; sourceTree = "SOURCE_ROOT"; }; + 086CE5C768CF5889BDEF8955 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioSource.h"; path = "../../../../modules/juce_audio_basics/sources/juce_AudioSource.h"; sourceTree = "SOURCE_ROOT"; }; + 08C7B33308A32555A7CA21B5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OpenGLShaderProgram.h"; path = "../../../../modules/juce_opengl/opengl/juce_OpenGLShaderProgram.h"; sourceTree = "SOURCE_ROOT"; }; + 08EC867C77B028C336B79752 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ContainerDeletePolicy.h"; path = "../../../../modules/juce_core/memory/juce_ContainerDeletePolicy.h"; sourceTree = "SOURCE_ROOT"; }; + 097237CCE04B9020343CB28D = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OptionalScopedPointer.h"; path = "../../../../modules/juce_core/memory/juce_OptionalScopedPointer.h"; sourceTree = "SOURCE_ROOT"; }; + 09846FF5D2FFB83242A02FF4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ApplicationProperties.cpp"; path = "../../../../modules/juce_data_structures/app_properties/juce_ApplicationProperties.cpp"; sourceTree = "SOURCE_ROOT"; }; + 0993051FFD1B0C5E92474DBD = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_OpenGLImage.cpp"; path = "../../../../modules/juce_opengl/opengl/juce_OpenGLImage.cpp"; sourceTree = "SOURCE_ROOT"; }; + 0AD4B355DBB0AED4C90E5657 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ScopedReadLock.h"; path = "../../../../modules/juce_core/threads/juce_ScopedReadLock.h"; sourceTree = "SOURCE_ROOT"; }; + 0AE6516868244378D09124A0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FlacAudioFormat.cpp"; path = "../../../../modules/juce_audio_formats/codecs/juce_FlacAudioFormat.cpp"; sourceTree = "SOURCE_ROOT"; }; + 0B7637C0030C06BE612E41E8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ModalComponentManager.h"; path = "../../../../modules/juce_gui_basics/components/juce_ModalComponentManager.h"; sourceTree = "SOURCE_ROOT"; }; + 0B7E069D09A7E46448EAE230 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_HyperlinkButton.cpp"; path = "../../../../modules/juce_gui_basics/buttons/juce_HyperlinkButton.cpp"; sourceTree = "SOURCE_ROOT"; }; + 0B933FCCF82100D67C0B7D34 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_KnownPluginList.cpp"; path = "../../../../modules/juce_audio_processors/scanning/juce_KnownPluginList.cpp"; sourceTree = "SOURCE_ROOT"; }; + 0BC32F0BB0B5393D25E09D00 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_CoreAudioFormat.cpp"; path = "../../../../modules/juce_audio_formats/codecs/juce_CoreAudioFormat.cpp"; sourceTree = "SOURCE_ROOT"; }; + 0C61EC70BD4EA59AEEBB6669 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_BooleanPropertyComponent.h"; path = "../../../../modules/juce_gui_basics/properties/juce_BooleanPropertyComponent.h"; sourceTree = "SOURCE_ROOT"; }; + 0C89377A44F26612524DA129 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Array.h"; path = "../../../../modules/juce_core/containers/juce_Array.h"; sourceTree = "SOURCE_ROOT"; }; + 0C9B04C3B7D8E1CE4FAC6FF6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ComboBox.cpp"; path = "../../../../modules/juce_gui_basics/widgets/juce_ComboBox.cpp"; sourceTree = "SOURCE_ROOT"; }; + 0CBC9EB8F2C55E88DB0F49BD = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_LookAndFeel_V1.h"; path = "../../../../modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V1.h"; sourceTree = "SOURCE_ROOT"; }; + 0D0FAC9754D9469774B8DD2F = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_BubbleMessageComponent.cpp"; path = "../../../../modules/juce_gui_extra/misc/juce_BubbleMessageComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; + 0D265DF78A9FE5E669F76FC3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ApplicationCommandTarget.h"; path = "../../../../modules/juce_gui_basics/commands/juce_ApplicationCommandTarget.h"; sourceTree = "SOURCE_ROOT"; }; + 0D35F0A502484A40B09F3EBF = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FileChooser.cpp"; path = "../../../../modules/juce_gui_basics/filebrowser/juce_FileChooser.cpp"; sourceTree = "SOURCE_ROOT"; }; + 0D530396A7BA6BA190100C6E = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_WavAudioFormat.cpp"; path = "../../../../modules/juce_audio_formats/codecs/juce_WavAudioFormat.cpp"; sourceTree = "SOURCE_ROOT"; }; + 0D88ABF90B476D03D3684ABE = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OpenGLFrameBuffer.h"; path = "../../../../modules/juce_opengl/opengl/juce_OpenGLFrameBuffer.h"; sourceTree = "SOURCE_ROOT"; }; + 0DB1323191C133E48F07C062 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ApplicationCommandInfo.h"; path = "../../../../modules/juce_gui_basics/commands/juce_ApplicationCommandInfo.h"; sourceTree = "SOURCE_ROOT"; }; + 0E70A4BFB2F7D1AB6188E72C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioFormat.h"; path = "../../../../modules/juce_audio_formats/format/juce_AudioFormat.h"; sourceTree = "SOURCE_ROOT"; }; + 0E894AC7229948568720E294 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ActiveXControlComponent.h"; path = "../../../../modules/juce_gui_extra/embedding/juce_ActiveXControlComponent.h"; sourceTree = "SOURCE_ROOT"; }; + 0E8D536FEBD11AEA3C90B5A8 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_module_info"; path = "../../../../modules/juce_gui_basics/juce_module_info"; sourceTree = "SOURCE_ROOT"; }; + 0ECA7867513EFA30BEA0BE78 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ChoicePropertyComponent.cpp"; path = "../../../../modules/juce_gui_basics/properties/juce_ChoicePropertyComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; + 0EF8E3646F6099E89A743D99 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_MouseCursor.mm"; path = "../../../../modules/juce_gui_basics/native/juce_mac_MouseCursor.mm"; sourceTree = "SOURCE_ROOT"; }; + 0F16DEEC2C4B95E3A9F28CE5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Label.h"; path = "../../../../modules/juce_gui_basics/widgets/juce_Label.h"; sourceTree = "SOURCE_ROOT"; }; + 0F67C59CB48583941B8656EF = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_VSTMidiEventList.h"; path = "../../../../modules/juce_audio_processors/format_types/juce_VSTMidiEventList.h"; sourceTree = "SOURCE_ROOT"; }; + 102919EC5BCD10DA703688CF = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioProcessorParameter.h"; path = "../../../../modules/juce_audio_processors/processors/juce_AudioProcessorParameter.h"; sourceTree = "SOURCE_ROOT"; }; + 109C128BB4A7A05127A0C485 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_PropertyComponent.h"; path = "../../../../modules/juce_gui_basics/properties/juce_PropertyComponent.h"; sourceTree = "SOURCE_ROOT"; }; + 11ACB77A3D91503A3DF673C8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_QuickTimeMovieComponent.mm"; path = "../../../../modules/juce_video/native/juce_mac_QuickTimeMovieComponent.mm"; sourceTree = "SOURCE_ROOT"; }; + 11D8AE26FA8880E7E8F3B4EB = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MissingGLDefinitions.h"; path = "../../../../modules/juce_opengl/native/juce_MissingGLDefinitions.h"; sourceTree = "SOURCE_ROOT"; }; + 123B63088FA1C4D1AD225CDB = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_LowLevelGraphicsSoftwareRenderer.cpp"; path = "../../../../modules/juce_graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.cpp"; sourceTree = "SOURCE_ROOT"; }; + 13430EC7CBFEF46874F53731 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_Network.cpp"; path = "../../../../modules/juce_core/native/juce_linux_Network.cpp"; sourceTree = "SOURCE_ROOT"; }; + 135DC8543A904B7BBAA0FD7B = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_StretchableLayoutManager.h"; path = "../../../../modules/juce_gui_basics/layout/juce_StretchableLayoutManager.h"; sourceTree = "SOURCE_ROOT"; }; + 13BF0388489EB44A816C9AF6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CodeDocument.h"; path = "../../../../modules/juce_gui_extra/code_editor/juce_CodeDocument.h"; sourceTree = "SOURCE_ROOT"; }; + 14245CED80854EC5291657FA = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_StringArray.h"; path = "../../../../modules/juce_core/text/juce_StringArray.h"; sourceTree = "SOURCE_ROOT"; }; + 142D03BC875BD387BD10C51F = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ChangeBroadcaster.cpp"; path = "../../../../modules/juce_events/broadcasters/juce_ChangeBroadcaster.cpp"; sourceTree = "SOURCE_ROOT"; }; + 1450CD0879661355CD52DD8D = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_StringPool.h"; path = "../../../../modules/juce_core/text/juce_StringPool.h"; sourceTree = "SOURCE_ROOT"; }; + 14AB997C7EB22777C1EF533C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_RelativeCoordinate.h"; path = "../../../../modules/juce_gui_basics/positioning/juce_RelativeCoordinate.h"; sourceTree = "SOURCE_ROOT"; }; + 14BB261A450674034E6080F2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_data_structures.mm"; path = "../../../../modules/juce_data_structures/juce_data_structures.mm"; sourceTree = "SOURCE_ROOT"; }; + 15029C3F041B27DD7191482F = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioProcessorGraph.cpp"; path = "../../../../modules/juce_audio_processors/processors/juce_AudioProcessorGraph.cpp"; sourceTree = "SOURCE_ROOT"; }; 15D92586D187B0D8758C6F18 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = System/Library/Frameworks/WebKit.framework; sourceTree = SDKROOT; }; - 15F7EA4ECAB7AD7E50A11065 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_SystemStats.cpp"; path = "../../JuceLibraryCode/modules/juce_core/system/juce_SystemStats.cpp"; sourceTree = "SOURCE_ROOT"; }; - 160E2EF9685EDF05E2A5EF32 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ContainerDeletePolicy.h"; path = "../../JuceLibraryCode/modules/juce_core/memory/juce_ContainerDeletePolicy.h"; sourceTree = "SOURCE_ROOT"; }; - 16DA31B062407BE595BD2E6B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_RectanglePlacement.cpp"; path = "../../JuceLibraryCode/modules/juce_graphics/placement/juce_RectanglePlacement.cpp"; sourceTree = "SOURCE_ROOT"; }; - 16F835A428874C108CE94490 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_WildcardFileFilter.cpp"; path = "../../JuceLibraryCode/modules/juce_core/files/juce_WildcardFileFilter.cpp"; sourceTree = "SOURCE_ROOT"; }; - 1717C592DF6E9FB0825104A3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_LookAndFeel_V2.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V2.cpp"; sourceTree = "SOURCE_ROOT"; }; - 171DE29200A3E7A8FB2D82F6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_OpenGLContext.cpp"; path = "../../JuceLibraryCode/modules/juce_opengl/opengl/juce_OpenGLContext.cpp"; sourceTree = "SOURCE_ROOT"; }; - 17CF86369ED4F4A6DFD8E44F = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_PluginDescription.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_processors/processors/juce_PluginDescription.cpp"; sourceTree = "SOURCE_ROOT"; }; - 17E9D0C9AC68F13FB1A763CD = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_audio_processors.h"; path = "../../JuceLibraryCode/modules/juce_audio_processors/juce_audio_processors.h"; sourceTree = "SOURCE_ROOT"; }; - 189CFDE7D3BC22BFE5CD87AD = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_osx_ObjCHelpers.h"; path = "../../JuceLibraryCode/modules/juce_core/native/juce_osx_ObjCHelpers.h"; sourceTree = "SOURCE_ROOT"; }; - 19553003D814DD6A3D1CE28D = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_SystemClipboard.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/keyboard/juce_SystemClipboard.h"; sourceTree = "SOURCE_ROOT"; }; - 19DA53917D0F1D8438EF83FA = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ToolbarButton.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/buttons/juce_ToolbarButton.cpp"; sourceTree = "SOURCE_ROOT"; }; - 19F49DDF17B56B3F0EC5D80D = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AsyncUpdater.cpp"; path = "../../JuceLibraryCode/modules/juce_events/broadcasters/juce_AsyncUpdater.cpp"; sourceTree = "SOURCE_ROOT"; }; - 1A23B74D25E6B0C55F1A1186 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FileTreeComponent.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/filebrowser/juce_FileTreeComponent.h"; sourceTree = "SOURCE_ROOT"; }; - 1A355A0DDA216F713372DF88 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_opengl.mm"; path = "../../JuceLibraryCode/modules/juce_opengl/juce_opengl.mm"; sourceTree = "SOURCE_ROOT"; }; - 1A491D8A6C3223CF582E050D = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MidiMessageSequence.h"; path = "../../JuceLibraryCode/modules/juce_audio_basics/midi/juce_MidiMessageSequence.h"; sourceTree = "SOURCE_ROOT"; }; - 1A632A95CA812B23E08E0C7A = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AlertWindow.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/windows/juce_AlertWindow.h"; sourceTree = "SOURCE_ROOT"; }; - 1A7BABC358CA895F30655093 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ConcertinaPanel.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/layout/juce_ConcertinaPanel.cpp"; sourceTree = "SOURCE_ROOT"; }; - 1AA4BEC9E981D64B98626682 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Colours.cpp"; path = "../../JuceLibraryCode/modules/juce_graphics/colour/juce_Colours.cpp"; sourceTree = "SOURCE_ROOT"; }; - 1B01AB28846416D9B0050D4A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_HighResolutionTimer.cpp"; path = "../../JuceLibraryCode/modules/juce_core/threads/juce_HighResolutionTimer.cpp"; sourceTree = "SOURCE_ROOT"; }; - 1B14F64034753EEA8B94AFAA = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CallbackMessage.h"; path = "../../JuceLibraryCode/modules/juce_events/messages/juce_CallbackMessage.h"; sourceTree = "SOURCE_ROOT"; }; - 1B5BCDA8B68284F2FAF17FE4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FileInputSource.cpp"; path = "../../JuceLibraryCode/modules/juce_core/streams/juce_FileInputSource.cpp"; sourceTree = "SOURCE_ROOT"; }; - 1B96C0BBFE3E1A61E50E61A4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_UndoManager.h"; path = "../../JuceLibraryCode/modules/juce_data_structures/undomanager/juce_UndoManager.h"; sourceTree = "SOURCE_ROOT"; }; - 1BEF05EF0D439BB92AE09DE4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_PluginListComponent.h"; path = "../../JuceLibraryCode/modules/juce_audio_processors/scanning/juce_PluginListComponent.h"; sourceTree = "SOURCE_ROOT"; }; - 1C96AD5E5DF22AE45779B769 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_QuickTimeAudioFormat.h"; path = "../../JuceLibraryCode/modules/juce_audio_formats/codecs/juce_QuickTimeAudioFormat.h"; sourceTree = "SOURCE_ROOT"; }; - 1C9B9B22D2CD87C0D160892C = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_NamedPipe.cpp"; path = "../../JuceLibraryCode/modules/juce_core/network/juce_NamedPipe.cpp"; sourceTree = "SOURCE_ROOT"; }; - 1CEDC2C77278F47EA71D588C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TableHeaderComponent.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/widgets/juce_TableHeaderComponent.h"; sourceTree = "SOURCE_ROOT"; }; - 1DAF43BE112A30BC560E95ED = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_gui_basics.mm"; path = "../../JuceLibraryCode/modules/juce_gui_basics/juce_gui_basics.mm"; sourceTree = "SOURCE_ROOT"; }; - 1DDEE220B7231E89552E9A07 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ButtonPropertyComponent.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/properties/juce_ButtonPropertyComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; - 1E7287FBD84D26D7C3247D65 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DropShadower.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/misc/juce_DropShadower.cpp"; sourceTree = "SOURCE_ROOT"; }; - 1EF1157A189C1B7D4E20B5AE = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ImageCache.h"; path = "../../JuceLibraryCode/modules/juce_graphics/images/juce_ImageCache.h"; sourceTree = "SOURCE_ROOT"; }; - 1FDD5774A3619E6116D1A542 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MemoryOutputStream.h"; path = "../../JuceLibraryCode/modules/juce_core/streams/juce_MemoryOutputStream.h"; sourceTree = "SOURCE_ROOT"; }; - 2075736FC83122CD98E9448B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_BlowFish.cpp"; path = "../../JuceLibraryCode/modules/juce_cryptography/encryption/juce_BlowFish.cpp"; sourceTree = "SOURCE_ROOT"; }; - 20B34958865F62C6D4CC1C2D = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ListBox.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/widgets/juce_ListBox.cpp"; sourceTree = "SOURCE_ROOT"; }; - 20E9A48DD57A2BD4F3A8EC20 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OpenGLImage.h"; path = "../../JuceLibraryCode/modules/juce_opengl/opengl/juce_OpenGLImage.h"; sourceTree = "SOURCE_ROOT"; }; - 213971DB941D93E214CF2153 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ReverbAudioSource.h"; path = "../../JuceLibraryCode/modules/juce_audio_basics/sources/juce_ReverbAudioSource.h"; sourceTree = "SOURCE_ROOT"; }; - 21E54D17FED6BEB36D5C712B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_CameraDevice.cpp"; path = "../../JuceLibraryCode/modules/juce_video/native/juce_win32_CameraDevice.cpp"; sourceTree = "SOURCE_ROOT"; }; - 223EA3BC50EEE65DFD1BF515 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_SubregionStream.cpp"; path = "../../JuceLibraryCode/modules/juce_core/streams/juce_SubregionStream.cpp"; sourceTree = "SOURCE_ROOT"; }; - 227CEFF1628076DE7A6D5A82 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AttributedString.cpp"; path = "../../JuceLibraryCode/modules/juce_graphics/fonts/juce_AttributedString.cpp"; sourceTree = "SOURCE_ROOT"; }; - 227F70FEE9D1F967CFD8DB5A = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FlacAudioFormat.h"; path = "../../JuceLibraryCode/modules/juce_audio_formats/codecs/juce_FlacAudioFormat.h"; sourceTree = "SOURCE_ROOT"; }; - 229DD5C0EF1D6FDA625B85A9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Value.h"; path = "../../JuceLibraryCode/modules/juce_data_structures/values/juce_Value.h"; sourceTree = "SOURCE_ROOT"; }; - 22BCEE7C1CFE9805F0C39F3B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ResizableBorderComponent.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/layout/juce_ResizableBorderComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; - 231F8E834F94B7654941EF55 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_VST3Common.h"; path = "../../JuceLibraryCode/modules/juce_audio_processors/format_types/juce_VST3Common.h"; sourceTree = "SOURCE_ROOT"; }; - 23600EA94396F6E810F1C774 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioProcessorParameter.h"; path = "../../JuceLibraryCode/modules/juce_audio_processors/processors/juce_AudioProcessorParameter.h"; sourceTree = "SOURCE_ROOT"; }; - 23B94851B96CB057621E0EBA = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MACAddress.cpp"; path = "../../JuceLibraryCode/modules/juce_core/network/juce_MACAddress.cpp"; sourceTree = "SOURCE_ROOT"; }; - 23CC00FD68EF7CB9A64D9EED = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_module_info"; path = "../../JuceLibraryCode/modules/juce_audio_processors/juce_module_info"; sourceTree = "SOURCE_ROOT"; }; - 23FA7918C3938E3FA645F003 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ApplicationCommandID.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/commands/juce_ApplicationCommandID.h"; sourceTree = "SOURCE_ROOT"; }; - 24006F32DA24D5C374C7442A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Random.cpp"; path = "../../JuceLibraryCode/modules/juce_core/maths/juce_Random.cpp"; sourceTree = "SOURCE_ROOT"; }; - 24A757C009624117895995B4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DirectShowComponent.h"; path = "../../JuceLibraryCode/modules/juce_video/playback/juce_DirectShowComponent.h"; sourceTree = "SOURCE_ROOT"; }; - 24C7C2F049DB74035187FBC7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DragAndDropContainer.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/mouse/juce_DragAndDropContainer.cpp"; sourceTree = "SOURCE_ROOT"; }; - 24D1B8EBF0B291F684311B9F = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OpenGL_android.h"; path = "../../JuceLibraryCode/modules/juce_opengl/native/juce_OpenGL_android.h"; sourceTree = "SOURCE_ROOT"; }; - 24E811B6B00094848D08D21F = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DrawableText.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/drawables/juce_DrawableText.h"; sourceTree = "SOURCE_ROOT"; }; - 256A686F1026814DA7434C9A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_QuickTimeAudioFormat.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_formats/codecs/juce_QuickTimeAudioFormat.cpp"; sourceTree = "SOURCE_ROOT"; }; - 269DDBC16D9F714A0B057A94 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_posix_SharedCode.h"; path = "../../JuceLibraryCode/modules/juce_core/native/juce_posix_SharedCode.h"; sourceTree = "SOURCE_ROOT"; }; - 26FD20E046F037F67A376081 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MouseEvent.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/mouse/juce_MouseEvent.h"; sourceTree = "SOURCE_ROOT"; }; + 161F35FA23347F495704C26A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_CommonFile.cpp"; path = "../../../../modules/juce_core/native/juce_linux_CommonFile.cpp"; sourceTree = "SOURCE_ROOT"; }; + 166BDAF3B9896BCB3771A061 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ResizableWindow.h"; path = "../../../../modules/juce_gui_basics/windows/juce_ResizableWindow.h"; sourceTree = "SOURCE_ROOT"; }; + 166C141D440846E85F91747E = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_OpenGLFrameBuffer.cpp"; path = "../../../../modules/juce_opengl/opengl/juce_OpenGLFrameBuffer.cpp"; sourceTree = "SOURCE_ROOT"; }; + 16ECB71D0D2C5C8BEFF4B4C6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DrawableRectangle.h"; path = "../../../../modules/juce_gui_basics/drawables/juce_DrawableRectangle.h"; sourceTree = "SOURCE_ROOT"; }; + 1737596EB7F40322C0A5DE20 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_JSON.cpp"; path = "../../../../modules/juce_core/javascript/juce_JSON.cpp"; sourceTree = "SOURCE_ROOT"; }; + 175654F2545AD9C0603BD0B4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_File.h"; path = "../../../../modules/juce_core/files/juce_File.h"; sourceTree = "SOURCE_ROOT"; }; + 176B18B9B61FDA6EC4357EB6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TemporaryFile.h"; path = "../../../../modules/juce_core/files/juce_TemporaryFile.h"; sourceTree = "SOURCE_ROOT"; }; + 17B07A06764A6A7759804033 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_StringArray.cpp"; path = "../../../../modules/juce_core/text/juce_StringArray.cpp"; sourceTree = "SOURCE_ROOT"; }; + 17B2789DEC279EE7DB8D9BE4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_osx_MessageQueue.h"; path = "../../../../modules/juce_events/native/juce_osx_MessageQueue.h"; sourceTree = "SOURCE_ROOT"; }; + 19045B1A4A9E79DB5A44927C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ComponentBoundsConstrainer.h"; path = "../../../../modules/juce_gui_basics/layout/juce_ComponentBoundsConstrainer.h"; sourceTree = "SOURCE_ROOT"; }; + 191B98765219765CD56CCFED = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CodeEditorComponent.h"; path = "../../../../modules/juce_gui_extra/code_editor/juce_CodeEditorComponent.h"; sourceTree = "SOURCE_ROOT"; }; + 19DC6BDBA978DC67B9783340 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_module_info"; path = "../../../../modules/juce_cryptography/juce_module_info"; sourceTree = "SOURCE_ROOT"; }; + 19E9997C0FE3E36156141D64 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MouseInputSource.cpp"; path = "../../../../modules/juce_gui_basics/mouse/juce_MouseInputSource.cpp"; sourceTree = "SOURCE_ROOT"; }; + 1A667A0FBCC8FC7EBBD15B20 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Font.cpp"; path = "../../../../modules/juce_graphics/fonts/juce_Font.cpp"; sourceTree = "SOURCE_ROOT"; }; + 1A7002B936C11924FDC07023 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_AppleRemote.mm"; path = "../../../../modules/juce_gui_extra/native/juce_mac_AppleRemote.mm"; sourceTree = "SOURCE_ROOT"; }; + 1A788BE93E528FDAA62EA02B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_TextPropertyComponent.cpp"; path = "../../../../modules/juce_gui_basics/properties/juce_TextPropertyComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; + 1AB580D4342BFFD41F220358 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_LAMEEncoderAudioFormat.h"; path = "../../../../modules/juce_audio_formats/codecs/juce_LAMEEncoderAudioFormat.h"; sourceTree = "SOURCE_ROOT"; }; + 1AB9713046E08B68A6F672CF = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Identifier.cpp"; path = "../../../../modules/juce_core/text/juce_Identifier.cpp"; sourceTree = "SOURCE_ROOT"; }; + 1B3B7CBA0D25C83B8AF72641 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_IIRFilter.cpp"; path = "../../../../modules/juce_audio_basics/effects/juce_IIRFilter.cpp"; sourceTree = "SOURCE_ROOT"; }; + 1B3CC8F665F23CB86253EBCE = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MathsFunctions.h"; path = "../../../../modules/juce_core/maths/juce_MathsFunctions.h"; sourceTree = "SOURCE_ROOT"; }; + 1B7AFDD8FCA13757D08B8B3E = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DropShadowEffect.cpp"; path = "../../../../modules/juce_graphics/effects/juce_DropShadowEffect.cpp"; sourceTree = "SOURCE_ROOT"; }; + 1C71768A34644733E39EEF4F = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Variant.h"; path = "../../../../modules/juce_core/containers/juce_Variant.h"; sourceTree = "SOURCE_ROOT"; }; + 1D5B751294F84B86ABB11D4A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ReverbAudioSource.cpp"; path = "../../../../modules/juce_audio_basics/sources/juce_ReverbAudioSource.cpp"; sourceTree = "SOURCE_ROOT"; }; + 1D9FABE954892C169D874E35 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ComponentDragger.h"; path = "../../../../modules/juce_gui_basics/mouse/juce_ComponentDragger.h"; sourceTree = "SOURCE_ROOT"; }; + 1DE0CF80B807A4A702DC68BD = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_RelativePoint.h"; path = "../../../../modules/juce_gui_basics/positioning/juce_RelativePoint.h"; sourceTree = "SOURCE_ROOT"; }; + 1E020B9E032C076071700CEC = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_InterprocessConnectionServer.h"; path = "../../../../modules/juce_events/interprocess/juce_InterprocessConnectionServer.h"; sourceTree = "SOURCE_ROOT"; }; + 1E6EF8035485237EA92A1310 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_UnitTest.h"; path = "../../../../modules/juce_core/unit_tests/juce_UnitTest.h"; sourceTree = "SOURCE_ROOT"; }; + 1FD6FD7218AB240D23DF4BAD = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FileListComponent.cpp"; path = "../../../../modules/juce_gui_basics/filebrowser/juce_FileListComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; + 2048DACF787A9BFE011041BC = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_GraphicsContext.h"; path = "../../../../modules/juce_graphics/contexts/juce_GraphicsContext.h"; sourceTree = "SOURCE_ROOT"; }; + 20E10FBD8694E185CA551EDE = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_PropertyComponent.cpp"; path = "../../../../modules/juce_gui_basics/properties/juce_PropertyComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; + 2168310E25BD55C9A46499C6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DrawableComposite.h"; path = "../../../../modules/juce_gui_basics/drawables/juce_DrawableComposite.h"; sourceTree = "SOURCE_ROOT"; }; + 2188A5670214696EFCF6810F = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_OpenGLHelpers.cpp"; path = "../../../../modules/juce_opengl/opengl/juce_OpenGLHelpers.cpp"; sourceTree = "SOURCE_ROOT"; }; + 21CF5364CD4910E49D19F8E2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_opengl.mm"; path = "../../../../modules/juce_opengl/juce_opengl.mm"; sourceTree = "SOURCE_ROOT"; }; + 21D0A71ADD004B35B90F0D1F = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_WebBrowserComponent.mm"; path = "../../../../modules/juce_gui_extra/native/juce_mac_WebBrowserComponent.mm"; sourceTree = "SOURCE_ROOT"; }; + 21D31B64BAD35C6C8E8E8FC0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_RelativePointPath.cpp"; path = "../../../../modules/juce_gui_basics/positioning/juce_RelativePointPath.cpp"; sourceTree = "SOURCE_ROOT"; }; + 221FD10838A8CE36672FABC0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_MainMenu.mm"; path = "../../../../modules/juce_gui_basics/native/juce_mac_MainMenu.mm"; sourceTree = "SOURCE_ROOT"; }; + 2254F8D031DD15BDB278DE3E = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_RecentlyOpenedFilesList.cpp"; path = "../../../../modules/juce_gui_extra/misc/juce_RecentlyOpenedFilesList.cpp"; sourceTree = "SOURCE_ROOT"; }; + 22C4F82B505995F81CD682B5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Identifier.h"; path = "../../../../modules/juce_core/text/juce_Identifier.h"; sourceTree = "SOURCE_ROOT"; }; + 2328C66A446079EDDCC8B14E = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_LiveConstantEditor.cpp"; path = "../../../../modules/juce_gui_extra/misc/juce_LiveConstantEditor.cpp"; sourceTree = "SOURCE_ROOT"; }; + 234D4927B398ED6E9B7B0E6B = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FileLogger.h"; path = "../../../../modules/juce_core/logging/juce_FileLogger.h"; sourceTree = "SOURCE_ROOT"; }; + 236F239E035044438B7CDFCB = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FillType.h"; path = "../../../../modules/juce_graphics/colour/juce_FillType.h"; sourceTree = "SOURCE_ROOT"; }; + 23724FEF549E05851817B4BB = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Slider.cpp"; path = "../../../../modules/juce_gui_basics/widgets/juce_Slider.cpp"; sourceTree = "SOURCE_ROOT"; }; + 23936BBF807CCF5B1EEB9F00 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_BufferedInputStream.cpp"; path = "../../../../modules/juce_core/streams/juce_BufferedInputStream.cpp"; sourceTree = "SOURCE_ROOT"; }; + 241453DBDECBE0CCD5C096DE = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_module_info"; path = "../../../../modules/juce_graphics/juce_module_info"; sourceTree = "SOURCE_ROOT"; }; + 24363F41974FD7A3B634B78B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_PerformanceCounter.cpp"; path = "../../../../modules/juce_core/time/juce_PerformanceCounter.cpp"; sourceTree = "SOURCE_ROOT"; }; + 244B9B4B8307A8C51207D457 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_JPEGLoader.cpp"; path = "../../../../modules/juce_graphics/image_formats/juce_JPEGLoader.cpp"; sourceTree = "SOURCE_ROOT"; }; + 254D157C0CCE3C7EA022F4CE = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_module_info"; path = "../../../../modules/juce_video/juce_module_info"; sourceTree = "SOURCE_ROOT"; }; + 25869F2A5B90C64E857606D8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TopLevelWindow.h"; path = "../../../../modules/juce_gui_basics/windows/juce_TopLevelWindow.h"; sourceTree = "SOURCE_ROOT"; }; + 25B41C0851C004C9D410B7C8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_mac_CoreAudio.cpp"; path = "../../../../modules/juce_audio_devices/native/juce_mac_CoreAudio.cpp"; sourceTree = "SOURCE_ROOT"; }; + 25E6B62A5BF19A0D1E085E10 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_GroupComponent.h"; path = "../../../../modules/juce_gui_basics/layout/juce_GroupComponent.h"; sourceTree = "SOURCE_ROOT"; }; + 260A5BDC20C7B4029DB418E4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ToolbarItemFactory.h"; path = "../../../../modules/juce_gui_basics/widgets/juce_ToolbarItemFactory.h"; sourceTree = "SOURCE_ROOT"; }; + 264F684A80B93F7A189A5FA5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MP3AudioFormat.cpp"; path = "../../../../modules/juce_audio_formats/codecs/juce_MP3AudioFormat.cpp"; sourceTree = "SOURCE_ROOT"; }; + 26C95A2DACFF9773038656E0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_Windowing.cpp"; path = "../../../../modules/juce_gui_basics/native/juce_linux_Windowing.cpp"; sourceTree = "SOURCE_ROOT"; }; + 27240E9968C04288887BFDC7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_TopLevelWindow.cpp"; path = "../../../../modules/juce_gui_basics/windows/juce_TopLevelWindow.cpp"; sourceTree = "SOURCE_ROOT"; }; 274569E245BFB279247B4ECC = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = JuceHeader.h; path = ../../JuceLibraryCode/JuceHeader.h; sourceTree = "SOURCE_ROOT"; }; - 2765ED5E0A7D8759C81EEA40 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ResizableWindow.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/windows/juce_ResizableWindow.h"; sourceTree = "SOURCE_ROOT"; }; - 276DFA694283C37D1B65B46A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_CoreGraphicsContext.mm"; path = "../../JuceLibraryCode/modules/juce_graphics/native/juce_mac_CoreGraphicsContext.mm"; sourceTree = "SOURCE_ROOT"; }; - 27D5D6CE8B6CFF40F8A5B9D0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Reverb.h"; path = "../../JuceLibraryCode/modules/juce_audio_basics/effects/juce_Reverb.h"; sourceTree = "SOURCE_ROOT"; }; - 27ECA38DD6808A358A90E7EF = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_GZIPCompressorOutputStream.cpp"; path = "../../JuceLibraryCode/modules/juce_core/zip/juce_GZIPCompressorOutputStream.cpp"; sourceTree = "SOURCE_ROOT"; }; - 27F470103D4B980E2E8E8AEB = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_Messaging.cpp"; path = "../../JuceLibraryCode/modules/juce_events/native/juce_linux_Messaging.cpp"; sourceTree = "SOURCE_ROOT"; }; - 2837660339370BA9863DC451 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_Fonts.mm"; path = "../../JuceLibraryCode/modules/juce_graphics/native/juce_mac_Fonts.mm"; sourceTree = "SOURCE_ROOT"; }; - 2892D0D481CDCCFCAE374DA8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Drawable.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/drawables/juce_Drawable.h"; sourceTree = "SOURCE_ROOT"; }; - 29054D0D5BB22F6A23808951 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DrawableShape.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/drawables/juce_DrawableShape.h"; sourceTree = "SOURCE_ROOT"; }; - 292236D5B7928EF5C6D73341 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Time.cpp"; path = "../../JuceLibraryCode/modules/juce_core/time/juce_Time.cpp"; sourceTree = "SOURCE_ROOT"; }; - 29B12214BCD1551867246556 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DocumentWindow.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/windows/juce_DocumentWindow.cpp"; sourceTree = "SOURCE_ROOT"; }; - 29D6BB46D3EF49EF86612B12 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_VSTPluginFormat.h"; path = "../../JuceLibraryCode/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.h"; sourceTree = "SOURCE_ROOT"; }; - 2A64A444FB90EFA1B0449A67 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Synthesiser.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_basics/synthesisers/juce_Synthesiser.cpp"; sourceTree = "SOURCE_ROOT"; }; - 2B780483D0584407FBA38106 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_audio_basics.h"; path = "../../JuceLibraryCode/modules/juce_audio_basics/juce_audio_basics.h"; sourceTree = "SOURCE_ROOT"; }; - 2B835DD803DC7C2379F3898A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_Threads.cpp"; path = "../../JuceLibraryCode/modules/juce_core/native/juce_linux_Threads.cpp"; sourceTree = "SOURCE_ROOT"; }; - 2BB91B988601A784CA953116 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FileInputStream.cpp"; path = "../../JuceLibraryCode/modules/juce_core/files/juce_FileInputStream.cpp"; sourceTree = "SOURCE_ROOT"; }; - 2C2E1D130B90B220D70A4D7A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_Midi.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_devices/native/juce_win32_Midi.cpp"; sourceTree = "SOURCE_ROOT"; }; - 2C4196232A1D92FC98E51684 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ModalComponentManager.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/components/juce_ModalComponentManager.cpp"; sourceTree = "SOURCE_ROOT"; }; - 2C43979AA3431CC3D61B94A1 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AnimatedAppComponent.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_extra/misc/juce_AnimatedAppComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; - 2CBBEE67AE711FFD4D554623 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioFormatReaderSource.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_formats/format/juce_AudioFormatReaderSource.cpp"; sourceTree = "SOURCE_ROOT"; }; - 2D2048FA048F8CEF2459EF31 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_GenericAudioProcessorEditor.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_processors/processors/juce_GenericAudioProcessorEditor.cpp"; sourceTree = "SOURCE_ROOT"; }; - 2DADD9644CFA5A770AA513A2 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_module_info"; path = "../../JuceLibraryCode/modules/juce_audio_devices/juce_module_info"; sourceTree = "SOURCE_ROOT"; }; - 2DFA08EB2F2965C76C328560 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_gui_basics.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/juce_gui_basics.h"; sourceTree = "SOURCE_ROOT"; }; - 2E91EB1BBD0ED5BC1D0A95A4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TextLayout.h"; path = "../../JuceLibraryCode/modules/juce_graphics/fonts/juce_TextLayout.h"; sourceTree = "SOURCE_ROOT"; }; - 2F8345DA4FF13DA81612EBB3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MidiFile.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_basics/midi/juce_MidiFile.cpp"; sourceTree = "SOURCE_ROOT"; }; - 2F9BA19AD170D9B9F979B025 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_android_CameraDevice.cpp"; path = "../../JuceLibraryCode/modules/juce_video/native/juce_android_CameraDevice.cpp"; sourceTree = "SOURCE_ROOT"; }; - 30236ADC490891CC1557AE3E = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_StandardHeader.h"; path = "../../JuceLibraryCode/modules/juce_core/system/juce_StandardHeader.h"; sourceTree = "SOURCE_ROOT"; }; - 302960973006B86172FD4A6B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_AudioCDReader.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_devices/native/juce_win32_AudioCDReader.cpp"; sourceTree = "SOURCE_ROOT"; }; - 307C5E375D02896F764B50A2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_PopupMenu.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/menus/juce_PopupMenu.h"; sourceTree = "SOURCE_ROOT"; }; - 30E06EA9F94FA181A6B8F533 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioDataConverters.h"; path = "../../JuceLibraryCode/modules/juce_audio_basics/buffers/juce_AudioDataConverters.h"; sourceTree = "SOURCE_ROOT"; }; - 30EC49300F475411B40273EA = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ImagePreviewComponent.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/filebrowser/juce_ImagePreviewComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; - 313A26829D5268C9E7B28E7E = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_OpenGLPixelFormat.cpp"; path = "../../JuceLibraryCode/modules/juce_opengl/opengl/juce_OpenGLPixelFormat.cpp"; sourceTree = "SOURCE_ROOT"; }; - 31A79A4E5FBBBDAA36B7D273 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_RelativeCoordinate.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/positioning/juce_RelativeCoordinate.cpp"; sourceTree = "SOURCE_ROOT"; }; - 31B95E3446D65E1C0ADC0E4E = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FilenameComponent.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/filebrowser/juce_FilenameComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; - 320CA688772F770F113A99C8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_MessageManager.mm"; path = "../../JuceLibraryCode/modules/juce_events/native/juce_mac_MessageManager.mm"; sourceTree = "SOURCE_ROOT"; }; - 321AC5D0FBCA00E825273253 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OpenGLTexture.h"; path = "../../JuceLibraryCode/modules/juce_opengl/opengl/juce_OpenGLTexture.h"; sourceTree = "SOURCE_ROOT"; }; - 3226060A8CC7B793C5A7A25A = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DocumentWindow.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/windows/juce_DocumentWindow.h"; sourceTree = "SOURCE_ROOT"; }; - 3269E6F38346442BAB611D8C = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ToneGeneratorAudioSource.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_basics/sources/juce_ToneGeneratorAudioSource.cpp"; sourceTree = "SOURCE_ROOT"; }; - 3289B1B53AFC6D7BDBDD850C = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_CodeEditorComponent.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_extra/code_editor/juce_CodeEditorComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; - 3293B0656CFCA5B2303C6E8F = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MidiMessageSequence.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_basics/midi/juce_MidiMessageSequence.cpp"; sourceTree = "SOURCE_ROOT"; }; - 3352C1259B6E110F6B0A835B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ColourGradient.cpp"; path = "../../JuceLibraryCode/modules/juce_graphics/colour/juce_ColourGradient.cpp"; sourceTree = "SOURCE_ROOT"; }; - 3413E3C25DD20925BA622640 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_LAMEEncoderAudioFormat.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_formats/codecs/juce_LAMEEncoderAudioFormat.cpp"; sourceTree = "SOURCE_ROOT"; }; + 27676EBA6012198993C2CBA0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TableHeaderComponent.h"; path = "../../../../modules/juce_gui_basics/widgets/juce_TableHeaderComponent.h"; sourceTree = "SOURCE_ROOT"; }; + 27A9B065352AE36635780373 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FileBrowserComponent.cpp"; path = "../../../../modules/juce_gui_basics/filebrowser/juce_FileBrowserComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; + 27B720A5E8CF81ABF9E50848 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_gui_basics.mm"; path = "../../../../modules/juce_gui_basics/juce_gui_basics.mm"; sourceTree = "SOURCE_ROOT"; }; + 27DC413550834C828252B003 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FileTreeComponent.cpp"; path = "../../../../modules/juce_gui_basics/filebrowser/juce_FileTreeComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; + 2807A00AE6C4539CD935F56D = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ImageCache.h"; path = "../../../../modules/juce_graphics/images/juce_ImageCache.h"; sourceTree = "SOURCE_ROOT"; }; + 2819AE973B501D15AAB8C937 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MouseListener.cpp"; path = "../../../../modules/juce_gui_basics/mouse/juce_MouseListener.cpp"; sourceTree = "SOURCE_ROOT"; }; + 289C3977B67C1898AC3B974D = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_SharedResourcePointer.h"; path = "../../../../modules/juce_core/memory/juce_SharedResourcePointer.h"; sourceTree = "SOURCE_ROOT"; }; + 28BEE3C7BE3AE2BD888AC55C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OpenGLImage.h"; path = "../../../../modules/juce_opengl/opengl/juce_OpenGLImage.h"; sourceTree = "SOURCE_ROOT"; }; + 29215FCE04DC4D267FF25E6C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_RelativePointPath.h"; path = "../../../../modules/juce_gui_basics/positioning/juce_RelativePointPath.h"; sourceTree = "SOURCE_ROOT"; }; + 29685DC8679DB5024B747D0C = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_ActiveXComponent.cpp"; path = "../../../../modules/juce_gui_extra/native/juce_win32_ActiveXComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; + 29710D5E6C3372E4480BF746 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CaretComponent.h"; path = "../../../../modules/juce_gui_basics/keyboard/juce_CaretComponent.h"; sourceTree = "SOURCE_ROOT"; }; + 29D35A5AB22E9443E0ED8F99 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_RSAKey.cpp"; path = "../../../../modules/juce_cryptography/encryption/juce_RSAKey.cpp"; sourceTree = "SOURCE_ROOT"; }; + 29F5A84EE715DA5BCED467A1 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_AudioCDBurner.cpp"; path = "../../../../modules/juce_audio_devices/native/juce_win32_AudioCDBurner.cpp"; sourceTree = "SOURCE_ROOT"; }; + 2A098563977566E9A9E8CD7E = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_android_OpenSL.cpp"; path = "../../../../modules/juce_audio_devices/native/juce_android_OpenSL.cpp"; sourceTree = "SOURCE_ROOT"; }; + 2A2B7F8BCFC785127CA961A9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MultiTouchMapper.h"; path = "../../../../modules/juce_gui_basics/native/juce_MultiTouchMapper.h"; sourceTree = "SOURCE_ROOT"; }; + 2A59F5E28F97A435592E0B58 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CachedComponentImage.h"; path = "../../../../modules/juce_gui_basics/components/juce_CachedComponentImage.h"; sourceTree = "SOURCE_ROOT"; }; + 2A771B60F7C360A111F75AC6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CustomTypeface.h"; path = "../../../../modules/juce_graphics/fonts/juce_CustomTypeface.h"; sourceTree = "SOURCE_ROOT"; }; + 2AB2B4CC891E77E2DD062BE3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Path.cpp"; path = "../../../../modules/juce_graphics/geometry/juce_Path.cpp"; sourceTree = "SOURCE_ROOT"; }; + 2B02634F8DA8660ED42B0AEF = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_VST3Headers.h"; path = "../../../../modules/juce_audio_processors/format_types/juce_VST3Headers.h"; sourceTree = "SOURCE_ROOT"; }; + 2B1494112273ADF380C99FD3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ValueTree.cpp"; path = "../../../../modules/juce_data_structures/values/juce_ValueTree.cpp"; sourceTree = "SOURCE_ROOT"; }; + 2B4FA0E8FB46CBC71A059FE7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_FileChooser.cpp"; path = "../../../../modules/juce_gui_basics/native/juce_linux_FileChooser.cpp"; sourceTree = "SOURCE_ROOT"; }; + 2B57EB41D3962E3518B79FD8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Socket.h"; path = "../../../../modules/juce_core/network/juce_Socket.h"; sourceTree = "SOURCE_ROOT"; }; + 2B69AEC791776F7CF337E38C = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_SystemTrayIcon.cpp"; path = "../../../../modules/juce_gui_extra/native/juce_linux_SystemTrayIcon.cpp"; sourceTree = "SOURCE_ROOT"; }; + 2B9907A25C1C36C1E46BEA65 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_PathStrokeType.cpp"; path = "../../../../modules/juce_graphics/geometry/juce_PathStrokeType.cpp"; sourceTree = "SOURCE_ROOT"; }; + 2B9BAEF9C46C224088F5BB25 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CallOutBox.h"; path = "../../../../modules/juce_gui_basics/windows/juce_CallOutBox.h"; sourceTree = "SOURCE_ROOT"; }; + 2C1B86FD1CB59198522DEF06 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_WebBrowserComponent.cpp"; path = "../../../../modules/juce_gui_extra/native/juce_win32_WebBrowserComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; + 2C246301EE0EC4A9B4058F01 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Matrix3D.h"; path = "../../../../modules/juce_opengl/geometry/juce_Matrix3D.h"; sourceTree = "SOURCE_ROOT"; }; + 2CFC9FB97ED3587D7E0E4E4B = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MD5.h"; path = "../../../../modules/juce_cryptography/hashing/juce_MD5.h"; sourceTree = "SOURCE_ROOT"; }; + 2CFEB3BEABF88B0C41D94E94 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AffineTransform.h"; path = "../../../../modules/juce_graphics/geometry/juce_AffineTransform.h"; sourceTree = "SOURCE_ROOT"; }; + 2D5F3AD1A03B34AE7349DF5F = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioProcessorListener.h"; path = "../../../../modules/juce_audio_processors/processors/juce_AudioProcessorListener.h"; sourceTree = "SOURCE_ROOT"; }; + 2D8FC1F116F882698F5CFEB9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FileListComponent.h"; path = "../../../../modules/juce_gui_basics/filebrowser/juce_FileListComponent.h"; sourceTree = "SOURCE_ROOT"; }; + 2DB2DBF293A77B80E01EBAED = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ResizableBorderComponent.cpp"; path = "../../../../modules/juce_gui_basics/layout/juce_ResizableBorderComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; + 2DCAC1795F1B47C592E65D4E = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ActionBroadcaster.h"; path = "../../../../modules/juce_events/broadcasters/juce_ActionBroadcaster.h"; sourceTree = "SOURCE_ROOT"; }; + 2E2B14A2334528E4405AEDDC = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ColourGradient.cpp"; path = "../../../../modules/juce_graphics/colour/juce_ColourGradient.cpp"; sourceTree = "SOURCE_ROOT"; }; + 2E650C2E92EA2732B66070D4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_PluginDirectoryScanner.cpp"; path = "../../../../modules/juce_audio_processors/scanning/juce_PluginDirectoryScanner.cpp"; sourceTree = "SOURCE_ROOT"; }; + 2E96848340E1C1B1095AC1F3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Value.cpp"; path = "../../../../modules/juce_data_structures/values/juce_Value.cpp"; sourceTree = "SOURCE_ROOT"; }; + 2FDA8843C89E2D7DFBE3FBFD = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_LowLevelGraphicsSoftwareRenderer.h"; path = "../../../../modules/juce_graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.h"; sourceTree = "SOURCE_ROOT"; }; + 301AF9BA843B1955EE001C98 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ReverbAudioSource.h"; path = "../../../../modules/juce_audio_basics/sources/juce_ReverbAudioSource.h"; sourceTree = "SOURCE_ROOT"; }; + 3095D8D2EF68D6ED502EB00B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_EdgeTable.cpp"; path = "../../../../modules/juce_graphics/geometry/juce_EdgeTable.cpp"; sourceTree = "SOURCE_ROOT"; }; + 314E9338935BC33A1C468B3E = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MessageListener.cpp"; path = "../../../../modules/juce_events/messages/juce_MessageListener.cpp"; sourceTree = "SOURCE_ROOT"; }; + 31AE430D2372CF6283185033 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_LookAndFeel_V2.h"; path = "../../../../modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V2.h"; sourceTree = "SOURCE_ROOT"; }; + 326E293A87E18FC3FBB26B47 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_GraphicsContext.cpp"; path = "../../../../modules/juce_graphics/contexts/juce_GraphicsContext.cpp"; sourceTree = "SOURCE_ROOT"; }; + 32A667DB98BC4EB30C51F20B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ListBox.cpp"; path = "../../../../modules/juce_gui_basics/widgets/juce_ListBox.cpp"; sourceTree = "SOURCE_ROOT"; }; + 32C683CBA18109949D53149A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_JackAudio.cpp"; path = "../../../../modules/juce_audio_devices/native/juce_linux_JackAudio.cpp"; sourceTree = "SOURCE_ROOT"; }; + 3324210159E5C546DC5C2065 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DeletedAtShutdown.h"; path = "../../../../modules/juce_events/messages/juce_DeletedAtShutdown.h"; sourceTree = "SOURCE_ROOT"; }; + 3391FA30F4D45A4A77DC2CE1 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_mac_CoreGraphicsHelpers.h"; path = "../../../../modules/juce_graphics/native/juce_mac_CoreGraphicsHelpers.h"; sourceTree = "SOURCE_ROOT"; }; + 33E449DEA1FC0CD4CAA3A829 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_cryptography.mm"; path = "../../../../modules/juce_cryptography/juce_cryptography.mm"; sourceTree = "SOURCE_ROOT"; }; 34227B39C3D697D0DBAC7017 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = System/Library/Frameworks/OpenGL.framework; sourceTree = SDKROOT; }; - 34A980957FE5E141693F3334 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioProcessorEditor.h"; path = "../../JuceLibraryCode/modules/juce_audio_processors/processors/juce_AudioProcessorEditor.h"; sourceTree = "SOURCE_ROOT"; }; - 355AFD562757A4867440E64E = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DynamicLibrary.h"; path = "../../JuceLibraryCode/modules/juce_core/threads/juce_DynamicLibrary.h"; sourceTree = "SOURCE_ROOT"; }; - 358A3AED0462892CFDD11749 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CPlusPlusCodeTokeniser.h"; path = "../../JuceLibraryCode/modules/juce_gui_extra/code_editor/juce_CPlusPlusCodeTokeniser.h"; sourceTree = "SOURCE_ROOT"; }; - 358F95020BB4722C04756E09 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_NamedValueSet.cpp"; path = "../../JuceLibraryCode/modules/juce_core/containers/juce_NamedValueSet.cpp"; sourceTree = "SOURCE_ROOT"; }; - 35F51FC31CE36BDF6D41978C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_KnownPluginList.h"; path = "../../JuceLibraryCode/modules/juce_audio_processors/scanning/juce_KnownPluginList.h"; sourceTree = "SOURCE_ROOT"; }; - 3619D8E6B18F0843E8EAA2A5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioTransportSource.h"; path = "../../JuceLibraryCode/modules/juce_audio_devices/sources/juce_AudioTransportSource.h"; sourceTree = "SOURCE_ROOT"; }; - 3669749528AFEB3D613D773E = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_KeyMappingEditorComponent.h"; path = "../../JuceLibraryCode/modules/juce_gui_extra/misc/juce_KeyMappingEditorComponent.h"; sourceTree = "SOURCE_ROOT"; }; - 369EE12DB339DA919C8BF5F6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_events.mm"; path = "../../JuceLibraryCode/modules/juce_events/juce_events.mm"; sourceTree = "SOURCE_ROOT"; }; - 36E382ACBB77916E0A228CC0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioIODeviceType.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_devices/audio_io/juce_AudioIODeviceType.cpp"; sourceTree = "SOURCE_ROOT"; }; - 3748D31911777A17CD3C20A9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_posix_NamedPipe.cpp"; path = "../../JuceLibraryCode/modules/juce_core/native/juce_posix_NamedPipe.cpp"; sourceTree = "SOURCE_ROOT"; }; - 37665101B192EFA4DC5DFE39 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_ALSA.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_devices/native/juce_linux_ALSA.cpp"; sourceTree = "SOURCE_ROOT"; }; - 376708401BCBF6D7EC1F8725 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioTransportSource.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_devices/sources/juce_AudioTransportSource.cpp"; sourceTree = "SOURCE_ROOT"; }; - 37BBA15CAEBD49401D2F82A5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_graphics.h"; path = "../../JuceLibraryCode/modules/juce_graphics/juce_graphics.h"; sourceTree = "SOURCE_ROOT"; }; - 37BEC08C61F8C221C4BED7C3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_SubregionStream.h"; path = "../../JuceLibraryCode/modules/juce_core/streams/juce_SubregionStream.h"; sourceTree = "SOURCE_ROOT"; }; - 37CFAB9F13EC95665CBAB742 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_BufferedInputStream.h"; path = "../../JuceLibraryCode/modules/juce_core/streams/juce_BufferedInputStream.h"; sourceTree = "SOURCE_ROOT"; }; - 384CF76B2FAEB3A5E935AAD8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_DirectSound.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_devices/native/juce_win32_DirectSound.cpp"; sourceTree = "SOURCE_ROOT"; }; - 3898B672BD3A7FDA95255349 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Sampler.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_formats/sampler/juce_Sampler.cpp"; sourceTree = "SOURCE_ROOT"; }; - 38ED648ECAD68AD30C9139AA = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ComponentListener.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/components/juce_ComponentListener.cpp"; sourceTree = "SOURCE_ROOT"; }; - 3944FFE845F494F9A625EC67 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CharPointer_UTF32.h"; path = "../../JuceLibraryCode/modules/juce_core/text/juce_CharPointer_UTF32.h"; sourceTree = "SOURCE_ROOT"; }; - 39562A408421F133E35C495D = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_InterprocessConnection.cpp"; path = "../../JuceLibraryCode/modules/juce_events/interprocess/juce_InterprocessConnection.cpp"; sourceTree = "SOURCE_ROOT"; }; - 398508292A45E227D66AC0E7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Font.cpp"; path = "../../JuceLibraryCode/modules/juce_graphics/fonts/juce_Font.cpp"; sourceTree = "SOURCE_ROOT"; }; - 39EFC895DB6FA253ACD83729 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_PositionableAudioSource.h"; path = "../../JuceLibraryCode/modules/juce_audio_basics/sources/juce_PositionableAudioSource.h"; sourceTree = "SOURCE_ROOT"; }; - 39F3DADB903ABADD1176B79E = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Viewport.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/layout/juce_Viewport.h"; sourceTree = "SOURCE_ROOT"; }; - 3AEDB68E416A876681F89985 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Line.h"; path = "../../JuceLibraryCode/modules/juce_graphics/geometry/juce_Line.h"; sourceTree = "SOURCE_ROOT"; }; - 3AF3E08820EC2CF94B505DCB = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FileChooser.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/filebrowser/juce_FileChooser.cpp"; sourceTree = "SOURCE_ROOT"; }; + 34A6FFC298D12BF9E4D55AA1 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ComponentAnimator.cpp"; path = "../../../../modules/juce_gui_basics/layout/juce_ComponentAnimator.cpp"; sourceTree = "SOURCE_ROOT"; }; + 35A7FD6EFDE29D2EBD7DFCB8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioCDReader.cpp"; path = "../../../../modules/juce_audio_devices/audio_cd/juce_AudioCDReader.cpp"; sourceTree = "SOURCE_ROOT"; }; + 35AAFB158E16D03C4D977713 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FileSearchPath.h"; path = "../../../../modules/juce_core/files/juce_FileSearchPath.h"; sourceTree = "SOURCE_ROOT"; }; + 35E6F6325AF8463C076BA594 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DrawableButton.cpp"; path = "../../../../modules/juce_gui_basics/buttons/juce_DrawableButton.cpp"; sourceTree = "SOURCE_ROOT"; }; + 369C06F1DC7B3B7EB497D062 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_UndoManager.cpp"; path = "../../../../modules/juce_data_structures/undomanager/juce_UndoManager.cpp"; sourceTree = "SOURCE_ROOT"; }; + 36A0FF58D355147F40981C39 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FileDragAndDropTarget.h"; path = "../../../../modules/juce_gui_basics/mouse/juce_FileDragAndDropTarget.h"; sourceTree = "SOURCE_ROOT"; }; + 36B8F6CFEEA3C1E2A0D09E56 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_VST3Common.h"; path = "../../../../modules/juce_audio_processors/format_types/juce_VST3Common.h"; sourceTree = "SOURCE_ROOT"; }; + 37381332DDDE8F2B3C66CBDE = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_gui_extra.h"; path = "../../../../modules/juce_gui_extra/juce_gui_extra.h"; sourceTree = "SOURCE_ROOT"; }; + 374277A96D9830E45684FDD8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Viewport.h"; path = "../../../../modules/juce_gui_basics/layout/juce_Viewport.h"; sourceTree = "SOURCE_ROOT"; }; + 381AE52C082AE08E724CB954 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ChildProcess.cpp"; path = "../../../../modules/juce_core/threads/juce_ChildProcess.cpp"; sourceTree = "SOURCE_ROOT"; }; + 381B8B8A9D5203E73FED79E9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioPluginFormat.h"; path = "../../../../modules/juce_audio_processors/format/juce_AudioPluginFormat.h"; sourceTree = "SOURCE_ROOT"; }; + 38404F97E5118017DFDCDEC4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_LassoComponent.h"; path = "../../../../modules/juce_gui_basics/mouse/juce_LassoComponent.h"; sourceTree = "SOURCE_ROOT"; }; + 389B4E4055A779D0F6B22C5F = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_StringPool.cpp"; path = "../../../../modules/juce_core/text/juce_StringPool.cpp"; sourceTree = "SOURCE_ROOT"; }; + 38D15A30D4658272F910A7AB = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_KeyboardFocusTraverser.cpp"; path = "../../../../modules/juce_gui_basics/keyboard/juce_KeyboardFocusTraverser.cpp"; sourceTree = "SOURCE_ROOT"; }; + 38EDF1EAB12A05CEE439AF23 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_LADSPAPluginFormat.h"; path = "../../../../modules/juce_audio_processors/format_types/juce_LADSPAPluginFormat.h"; sourceTree = "SOURCE_ROOT"; }; + 3900C9B11914C94DFA1F8C33 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ToneGeneratorAudioSource.h"; path = "../../../../modules/juce_audio_basics/sources/juce_ToneGeneratorAudioSource.h"; sourceTree = "SOURCE_ROOT"; }; + 390351E336C2CF20C38ADB59 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ThreadPool.cpp"; path = "../../../../modules/juce_core/threads/juce_ThreadPool.cpp"; sourceTree = "SOURCE_ROOT"; }; + 393D0CA8D89217F1F2504768 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_TextLayout.cpp"; path = "../../../../modules/juce_graphics/fonts/juce_TextLayout.cpp"; sourceTree = "SOURCE_ROOT"; }; + 394CD5017D81D1CFEBE34894 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_SystemTrayIconComponent.h"; path = "../../../../modules/juce_gui_extra/misc/juce_SystemTrayIconComponent.h"; sourceTree = "SOURCE_ROOT"; }; + 3966D734450E72F5682D2F06 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ImageFileFormat.cpp"; path = "../../../../modules/juce_graphics/images/juce_ImageFileFormat.cpp"; sourceTree = "SOURCE_ROOT"; }; + 3A9FC7EFC378976EE696AE83 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OwnedArray.h"; path = "../../../../modules/juce_core/containers/juce_OwnedArray.h"; sourceTree = "SOURCE_ROOT"; }; + 3AE89D0904EE985359A73B91 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_HighResolutionTimer.cpp"; path = "../../../../modules/juce_core/threads/juce_HighResolutionTimer.cpp"; sourceTree = "SOURCE_ROOT"; }; + 3AF114AC45249CDA77EF940E = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Rectangle.h"; path = "../../../../modules/juce_graphics/geometry/juce_Rectangle.h"; sourceTree = "SOURCE_ROOT"; }; + 3B09334ECC8FB54B4B7D7B59 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ComponentBuilder.h"; path = "../../../../modules/juce_gui_basics/layout/juce_ComponentBuilder.h"; sourceTree = "SOURCE_ROOT"; }; 3B5B55FF08F71060B836F5DB = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; - 3B5DE4A58F1A28D3DC2D5035 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_BubbleMessageComponent.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_extra/misc/juce_BubbleMessageComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; - 3BC29BAC09BDF8518335571D = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Singleton.h"; path = "../../JuceLibraryCode/modules/juce_core/memory/juce_Singleton.h"; sourceTree = "SOURCE_ROOT"; }; - 3C31FCFF8570C5F2281B4774 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_BubbleComponent.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/misc/juce_BubbleComponent.h"; sourceTree = "SOURCE_ROOT"; }; - 3C55CA36E6DF4478E7C2A106 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_UnitTest.cpp"; path = "../../JuceLibraryCode/modules/juce_core/unit_tests/juce_UnitTest.cpp"; sourceTree = "SOURCE_ROOT"; }; - 3CE23C91D3F26953C3BE4A86 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ios_Audio.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_devices/native/juce_ios_Audio.cpp"; sourceTree = "SOURCE_ROOT"; }; - 3D08CF856ED46386AB450F46 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ComponentAnimator.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/layout/juce_ComponentAnimator.h"; sourceTree = "SOURCE_ROOT"; }; - 3D0CCA82BDEA501876257111 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_CameraDevice.mm"; path = "../../JuceLibraryCode/modules/juce_video/native/juce_mac_CameraDevice.mm"; sourceTree = "SOURCE_ROOT"; }; - 3D906BFC50723AC77213FB8E = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_PNGLoader.cpp"; path = "../../JuceLibraryCode/modules/juce_graphics/image_formats/juce_PNGLoader.cpp"; sourceTree = "SOURCE_ROOT"; }; - 3DC4B655D395BCE7D0648755 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_RectangleList.h"; path = "../../JuceLibraryCode/modules/juce_graphics/geometry/juce_RectangleList.h"; sourceTree = "SOURCE_ROOT"; }; - 3DDAC0076D6C914CE76C09D9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_Messaging.cpp"; path = "../../JuceLibraryCode/modules/juce_events/native/juce_win32_Messaging.cpp"; sourceTree = "SOURCE_ROOT"; }; - 3E199BBFEDF370A9853B91E3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_RecentlyOpenedFilesList.h"; path = "../../JuceLibraryCode/modules/juce_gui_extra/misc/juce_RecentlyOpenedFilesList.h"; sourceTree = "SOURCE_ROOT"; }; - 3E25895B1FAD62C2E2DF985E = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_SplashScreen.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_extra/misc/juce_SplashScreen.cpp"; sourceTree = "SOURCE_ROOT"; }; - 3E68E00D0D6613D6A93B3ED1 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_GenericAudioProcessorEditor.h"; path = "../../JuceLibraryCode/modules/juce_audio_processors/processors/juce_GenericAudioProcessorEditor.h"; sourceTree = "SOURCE_ROOT"; }; - 3E9EC18E1C4F444805B36259 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TabbedButtonBar.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/layout/juce_TabbedButtonBar.h"; sourceTree = "SOURCE_ROOT"; }; + 3B9903B0A0252D106C92CAA9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_audio_basics.h"; path = "../../../../modules/juce_audio_basics/juce_audio_basics.h"; sourceTree = "SOURCE_ROOT"; }; + 3BDF8DF3F3C380B1A4CE6C8F = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FileBasedDocument.cpp"; path = "../../../../modules/juce_gui_extra/documents/juce_FileBasedDocument.cpp"; sourceTree = "SOURCE_ROOT"; }; + 3BF23F0B71FB8E526E895905 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FileSearchPathListComponent.cpp"; path = "../../../../modules/juce_gui_basics/filebrowser/juce_FileSearchPathListComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; + 3C825AE2479611DA559164B5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_KeyPressMappingSet.h"; path = "../../../../modules/juce_gui_basics/commands/juce_KeyPressMappingSet.h"; sourceTree = "SOURCE_ROOT"; }; + 3C89D04328C83D2FDD4E5116 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_ios_MessageManager.mm"; path = "../../../../modules/juce_events/native/juce_ios_MessageManager.mm"; sourceTree = "SOURCE_ROOT"; }; + 3CD47BA1CFEFB637DDEAC313 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_SystemStats.cpp"; path = "../../../../modules/juce_core/system/juce_SystemStats.cpp"; sourceTree = "SOURCE_ROOT"; }; + 3D16FF3C64D4248C0C6FF504 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_TableHeaderComponent.cpp"; path = "../../../../modules/juce_gui_basics/widgets/juce_TableHeaderComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; + 3D24784AEA7726A64A340625 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioDeviceManager.h"; path = "../../../../modules/juce_audio_devices/audio_io/juce_AudioDeviceManager.h"; sourceTree = "SOURCE_ROOT"; }; + 3E19A71C4A345EB5C1BA466D = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_WaitableEvent.h"; path = "../../../../modules/juce_core/threads/juce_WaitableEvent.h"; sourceTree = "SOURCE_ROOT"; }; + 3E8E31BB97A86349790D6CC3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_CoreGraphicsContext.mm"; path = "../../../../modules/juce_graphics/native/juce_mac_CoreGraphicsContext.mm"; sourceTree = "SOURCE_ROOT"; }; 3EF6F363BA4F6B10207C0E23 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuickTime.framework; path = System/Library/Frameworks/QuickTime.framework; sourceTree = SDKROOT; }; - 3EFCADD916181E95D684C237 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TextEditor.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/widgets/juce_TextEditor.h"; sourceTree = "SOURCE_ROOT"; }; - 3F1BEF3D596877977723184D = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Array.h"; path = "../../JuceLibraryCode/modules/juce_core/containers/juce_Array.h"; sourceTree = "SOURCE_ROOT"; }; - 3FD4B7D9E2A8CC22D8F0C974 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_android_Misc.cpp"; path = "../../JuceLibraryCode/modules/juce_core/native/juce_android_Misc.cpp"; sourceTree = "SOURCE_ROOT"; }; - 3FEFB6B506459AC93E066C3D = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_android_Audio.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_devices/native/juce_android_Audio.cpp"; sourceTree = "SOURCE_ROOT"; }; - 3FF553F76522FAC43163CE03 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_KeyboardFocusTraverser.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/keyboard/juce_KeyboardFocusTraverser.h"; sourceTree = "SOURCE_ROOT"; }; - 401D5DBEE57DB66AF040885C = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_Direct2DGraphicsContext.cpp"; path = "../../JuceLibraryCode/modules/juce_graphics/native/juce_win32_Direct2DGraphicsContext.cpp"; sourceTree = "SOURCE_ROOT"; }; - 405F7A0C891B13655617BF5F = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_TopLevelWindow.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/windows/juce_TopLevelWindow.cpp"; sourceTree = "SOURCE_ROOT"; }; - 40673853C7079F0A6D8AF2BB = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioSourcePlayer.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_devices/sources/juce_AudioSourcePlayer.cpp"; sourceTree = "SOURCE_ROOT"; }; - 4079EA961E5AFE0A51869E40 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Thread.cpp"; path = "../../JuceLibraryCode/modules/juce_core/threads/juce_Thread.cpp"; sourceTree = "SOURCE_ROOT"; }; - 408F458A6E9A71923FC72D04 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Message.h"; path = "../../JuceLibraryCode/modules/juce_events/messages/juce_Message.h"; sourceTree = "SOURCE_ROOT"; }; - 40B44760A3D17F9F97B857B3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_UndoableAction.h"; path = "../../JuceLibraryCode/modules/juce_data_structures/undomanager/juce_UndoableAction.h"; sourceTree = "SOURCE_ROOT"; }; - 40D6454C05B1D9E3242CDFC8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MP3AudioFormat.h"; path = "../../JuceLibraryCode/modules/juce_audio_formats/codecs/juce_MP3AudioFormat.h"; sourceTree = "SOURCE_ROOT"; }; - 40DDC868EB152DA18FF4832F = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ComponentPeer.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/windows/juce_ComponentPeer.h"; sourceTree = "SOURCE_ROOT"; }; - 4128F91E323A32B6D7189CD5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_NewLine.h"; path = "../../JuceLibraryCode/modules/juce_core/text/juce_NewLine.h"; sourceTree = "SOURCE_ROOT"; }; - 423A70751A8C20A9E1C3E9CB = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AiffAudioFormat.h"; path = "../../JuceLibraryCode/modules/juce_audio_formats/codecs/juce_AiffAudioFormat.h"; sourceTree = "SOURCE_ROOT"; }; - 43234F932D4492E104787435 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ScrollBar.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/layout/juce_ScrollBar.cpp"; sourceTree = "SOURCE_ROOT"; }; - 433E40D469ACDE64A8E40258 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_OpenGLShaderProgram.cpp"; path = "../../JuceLibraryCode/modules/juce_opengl/opengl/juce_OpenGLShaderProgram.cpp"; sourceTree = "SOURCE_ROOT"; }; - 434A87588331CF1CB8118A36 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_RSAKey.cpp"; path = "../../JuceLibraryCode/modules/juce_cryptography/encryption/juce_RSAKey.cpp"; sourceTree = "SOURCE_ROOT"; }; - 438C65CF8B5C0D636F0AC715 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioSourcePlayer.h"; path = "../../JuceLibraryCode/modules/juce_audio_devices/sources/juce_AudioSourcePlayer.h"; sourceTree = "SOURCE_ROOT"; }; - 43BB532CBA295E02FDAC1CFA = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_BigInteger.cpp"; path = "../../JuceLibraryCode/modules/juce_core/maths/juce_BigInteger.cpp"; sourceTree = "SOURCE_ROOT"; }; - 43CC35E1310E10B9422E98C4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ConnectedChildProcess.cpp"; path = "../../JuceLibraryCode/modules/juce_events/interprocess/juce_ConnectedChildProcess.cpp"; sourceTree = "SOURCE_ROOT"; }; - 43F755438129CF5051D3C8D0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_TimeSliceThread.cpp"; path = "../../JuceLibraryCode/modules/juce_core/threads/juce_TimeSliceThread.cpp"; sourceTree = "SOURCE_ROOT"; }; - 442ADB5B235BA350C5FD0BD1 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_VSTPluginFormat.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp"; sourceTree = "SOURCE_ROOT"; }; - 44DE484AE50122D19A902731 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_PluginListComponent.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_processors/scanning/juce_PluginListComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; - 44F0CE6E0BBCE5E596BF70A6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioDataConverters.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_basics/buffers/juce_AudioDataConverters.cpp"; sourceTree = "SOURCE_ROOT"; }; - 45210D0101FB1A0A4AFA4C54 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_PropertyPanel.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/properties/juce_PropertyPanel.cpp"; sourceTree = "SOURCE_ROOT"; }; - 4563BD0A5FB10592A3DC6244 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_InterProcessLock.h"; path = "../../JuceLibraryCode/modules/juce_core/threads/juce_InterProcessLock.h"; sourceTree = "SOURCE_ROOT"; }; - 458072B5FE996673CD03DC28 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_android_OpenSL.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_devices/native/juce_android_OpenSL.cpp"; sourceTree = "SOURCE_ROOT"; }; - 45E9503C1F2B4418E687E9A7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MessageListener.cpp"; path = "../../JuceLibraryCode/modules/juce_events/messages/juce_MessageListener.cpp"; sourceTree = "SOURCE_ROOT"; }; - 45EFD54010FF09B5795B59CD = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_SliderPropertyComponent.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/properties/juce_SliderPropertyComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; - 461440C6B5EE1CF5DB2ECDDA = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TopLevelWindow.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/windows/juce_TopLevelWindow.h"; sourceTree = "SOURCE_ROOT"; }; - 4625F35561AEC875DBEF087B = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ReferenceCountedArray.h"; path = "../../JuceLibraryCode/modules/juce_core/containers/juce_ReferenceCountedArray.h"; sourceTree = "SOURCE_ROOT"; }; - 46A5E45225E1FDA3975F6C83 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_LowLevelGraphicsSoftwareRenderer.cpp"; path = "../../JuceLibraryCode/modules/juce_graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.cpp"; sourceTree = "SOURCE_ROOT"; }; - 46D9408E336E541FAFFB6F1D = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MouseInputSource.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/mouse/juce_MouseInputSource.cpp"; sourceTree = "SOURCE_ROOT"; }; - 476DAA4C7DBFD4BC115090D2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AnimatedPosition.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/layout/juce_AnimatedPosition.h"; sourceTree = "SOURCE_ROOT"; }; - 4784BB8CDAEA553AEA062A56 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MouseCursor.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/mouse/juce_MouseCursor.cpp"; sourceTree = "SOURCE_ROOT"; }; - 478C5F19200D7A3E3D0F3767 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_LuaCodeTokeniser.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_extra/code_editor/juce_LuaCodeTokeniser.cpp"; sourceTree = "SOURCE_ROOT"; }; - 48225D3F1FDE66F5A56A1ABA = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ConcertinaPanel.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/layout/juce_ConcertinaPanel.h"; sourceTree = "SOURCE_ROOT"; }; - 48403410E9FE064527EDCC85 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ReverbAudioSource.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_basics/sources/juce_ReverbAudioSource.cpp"; sourceTree = "SOURCE_ROOT"; }; - 48B1172E10D1795EFD5B4731 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Memory.h"; path = "../../JuceLibraryCode/modules/juce_core/memory/juce_Memory.h"; sourceTree = "SOURCE_ROOT"; }; - 48BDA8E72F3E90C3DF0F9B91 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OwnedArray.h"; path = "../../JuceLibraryCode/modules/juce_core/containers/juce_OwnedArray.h"; sourceTree = "SOURCE_ROOT"; }; - 49C6550365D3B05E7D030E2B = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OpenGL_ios.h"; path = "../../JuceLibraryCode/modules/juce_opengl/native/juce_OpenGL_ios.h"; sourceTree = "SOURCE_ROOT"; }; - 4A0D71E8FA4622C6C7687DD7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_RelativePointPath.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/positioning/juce_RelativePointPath.cpp"; sourceTree = "SOURCE_ROOT"; }; - 4B06A49CE12DBFA2FC861D50 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_SVGParser.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/drawables/juce_SVGParser.cpp"; sourceTree = "SOURCE_ROOT"; }; - 4B09912103F721693FB77FEC = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_SHA256.h"; path = "../../JuceLibraryCode/modules/juce_cryptography/hashing/juce_SHA256.h"; sourceTree = "SOURCE_ROOT"; }; - 4B2CB85C841304CE2E93592F = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_InterprocessConnectionServer.h"; path = "../../JuceLibraryCode/modules/juce_events/interprocess/juce_InterprocessConnectionServer.h"; sourceTree = "SOURCE_ROOT"; }; - 4B4BC465C9478425824F5A82 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ComponentBoundsConstrainer.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/layout/juce_ComponentBoundsConstrainer.cpp"; sourceTree = "SOURCE_ROOT"; }; - 4C41E9A5BA9B4CA47D4A37BB = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DrawablePath.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/drawables/juce_DrawablePath.h"; sourceTree = "SOURCE_ROOT"; }; - 4C512B82D4659142CAAB8390 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_NSViewComponent.mm"; path = "../../JuceLibraryCode/modules/juce_gui_extra/native/juce_mac_NSViewComponent.mm"; sourceTree = "SOURCE_ROOT"; }; - 4C699E969B418C7C5EBE4DB9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MidiMessageCollector.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_devices/midi_io/juce_MidiMessageCollector.cpp"; sourceTree = "SOURCE_ROOT"; }; - 4C93E808908617B457689A69 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ShapeButton.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/buttons/juce_ShapeButton.cpp"; sourceTree = "SOURCE_ROOT"; }; - 4CC30DD2477041D19048C805 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Socket.cpp"; path = "../../JuceLibraryCode/modules/juce_core/network/juce_Socket.cpp"; sourceTree = "SOURCE_ROOT"; }; - 4D67518B8585D2075E450D75 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_PathStrokeType.h"; path = "../../JuceLibraryCode/modules/juce_graphics/geometry/juce_PathStrokeType.h"; sourceTree = "SOURCE_ROOT"; }; + 3F0388309395C138AA68FAD7 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_module_info"; path = "../../../../modules/juce_audio_processors/juce_module_info"; sourceTree = "SOURCE_ROOT"; }; + 3FAA5384DA8B28DEB5E57A5D = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ZipFile.cpp"; path = "../../../../modules/juce_core/zip/juce_ZipFile.cpp"; sourceTree = "SOURCE_ROOT"; }; + 3FECAB20E9C0834676E2D9EB = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_File.cpp"; path = "../../../../modules/juce_core/files/juce_File.cpp"; sourceTree = "SOURCE_ROOT"; }; + 403453363C4785FD451A9BA1 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_LagrangeInterpolator.h"; path = "../../../../modules/juce_audio_basics/effects/juce_LagrangeInterpolator.h"; sourceTree = "SOURCE_ROOT"; }; + 40B9C2276B7EF73860E2606B = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioProcessorEditor.h"; path = "../../../../modules/juce_audio_processors/processors/juce_AudioProcessorEditor.h"; sourceTree = "SOURCE_ROOT"; }; + 40F0E944D041D96F2DA4C6A2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_Threads.cpp"; path = "../../../../modules/juce_core/native/juce_win32_Threads.cpp"; sourceTree = "SOURCE_ROOT"; }; + 412D5D6AA4018C8DF59AB741 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_RelativeRectangle.cpp"; path = "../../../../modules/juce_gui_basics/positioning/juce_RelativeRectangle.cpp"; sourceTree = "SOURCE_ROOT"; }; + 414AAB7000E7FDE7683BE72F = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_UIViewComponent.h"; path = "../../../../modules/juce_gui_extra/embedding/juce_UIViewComponent.h"; sourceTree = "SOURCE_ROOT"; }; + 41C74B59D9B392117441DA2D = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioCDBurner.h"; path = "../../../../modules/juce_audio_devices/audio_cd/juce_AudioCDBurner.h"; sourceTree = "SOURCE_ROOT"; }; + 4228B8952E3FBCDA69C1948B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_SHA256.cpp"; path = "../../../../modules/juce_cryptography/hashing/juce_SHA256.cpp"; sourceTree = "SOURCE_ROOT"; }; + 426283CFD858F482E87F530B = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Thread.h"; path = "../../../../modules/juce_core/threads/juce_Thread.h"; sourceTree = "SOURCE_ROOT"; }; + 42BC8303198293E30AC0B21A = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_GlyphArrangement.h"; path = "../../../../modules/juce_graphics/fonts/juce_GlyphArrangement.h"; sourceTree = "SOURCE_ROOT"; }; + 435858CCF38F47E9AAE1B08F = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ChangeListener.h"; path = "../../../../modules/juce_events/broadcasters/juce_ChangeListener.h"; sourceTree = "SOURCE_ROOT"; }; + 439FC260CD869E30210D98BF = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_PopupMenu.h"; path = "../../../../modules/juce_gui_basics/menus/juce_PopupMenu.h"; sourceTree = "SOURCE_ROOT"; }; + 4408766B366713F55707B7A8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ShapeButton.h"; path = "../../../../modules/juce_gui_basics/buttons/juce_ShapeButton.h"; sourceTree = "SOURCE_ROOT"; }; + 440A182A9068A8FBD011BE1A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_InputStream.cpp"; path = "../../../../modules/juce_core/streams/juce_InputStream.cpp"; sourceTree = "SOURCE_ROOT"; }; + 44185DE135E354DD4758B3EA = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Thread.cpp"; path = "../../../../modules/juce_core/threads/juce_Thread.cpp"; sourceTree = "SOURCE_ROOT"; }; + 442199479D1499B6A44BD150 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_module_info"; path = "../../../../modules/juce_audio_devices/juce_module_info"; sourceTree = "SOURCE_ROOT"; }; + 44443DA5B0FDA2480DFBDFC7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AttributedString.h"; path = "../../../../modules/juce_graphics/fonts/juce_AttributedString.h"; sourceTree = "SOURCE_ROOT"; }; + 44ADFB25768FA3BF27762EBF = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_OpenGLAppComponent.cpp"; path = "../../../../modules/juce_opengl/utils/juce_OpenGLAppComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; + 44B3428E8BB4B70104CD76CF = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ResamplingAudioSource.h"; path = "../../../../modules/juce_audio_basics/sources/juce_ResamplingAudioSource.h"; sourceTree = "SOURCE_ROOT"; }; + 44C6568EC00F1682FBCD3B69 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ToolbarItemPalette.cpp"; path = "../../../../modules/juce_gui_basics/widgets/juce_ToolbarItemPalette.cpp"; sourceTree = "SOURCE_ROOT"; }; + 44FC8BD37CFE8C0D851C46F9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_TextEditor.cpp"; path = "../../../../modules/juce_gui_basics/widgets/juce_TextEditor.cpp"; sourceTree = "SOURCE_ROOT"; }; + 4510E3B6AD441EA03B993692 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_OpenGLGraphicsContext.cpp"; path = "../../../../modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.cpp"; sourceTree = "SOURCE_ROOT"; }; + 4570554FB8438C0692EEDC55 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Variant.cpp"; path = "../../../../modules/juce_core/containers/juce_Variant.cpp"; sourceTree = "SOURCE_ROOT"; }; + 464424DDD6A6678B94CE667F = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_CallOutBox.cpp"; path = "../../../../modules/juce_gui_basics/windows/juce_CallOutBox.cpp"; sourceTree = "SOURCE_ROOT"; }; + 4658E12862C546A62E05E4D3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TabbedComponent.h"; path = "../../../../modules/juce_gui_basics/layout/juce_TabbedComponent.h"; sourceTree = "SOURCE_ROOT"; }; + 46885692CC5FDE30FC3649F6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_WavAudioFormat.h"; path = "../../../../modules/juce_audio_formats/codecs/juce_WavAudioFormat.h"; sourceTree = "SOURCE_ROOT"; }; + 46D8BC7303C892ED3F90E4DA = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_CaretComponent.cpp"; path = "../../../../modules/juce_gui_basics/keyboard/juce_CaretComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; + 47E5FB5735D2EC8B039D2691 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Application.h"; path = "../../../../modules/juce_gui_basics/application/juce_Application.h"; sourceTree = "SOURCE_ROOT"; }; + 47E70AF805B1C5C57566C4CB = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MemoryInputStream.cpp"; path = "../../../../modules/juce_core/streams/juce_MemoryInputStream.cpp"; sourceTree = "SOURCE_ROOT"; }; + 495EAFDB9DE4E8E7DBA562D4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OpenGL_win32.h"; path = "../../../../modules/juce_opengl/native/juce_OpenGL_win32.h"; sourceTree = "SOURCE_ROOT"; }; + 49794569C715BA919A01D72E = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ModifierKeys.cpp"; path = "../../../../modules/juce_gui_basics/keyboard/juce_ModifierKeys.cpp"; sourceTree = "SOURCE_ROOT"; }; + 4A1671B78E589A865FEA3CB1 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioIODevice.cpp"; path = "../../../../modules/juce_audio_devices/audio_io/juce_AudioIODevice.cpp"; sourceTree = "SOURCE_ROOT"; }; + 4A31DFDB7AC330488B8BBEA3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Component.cpp"; path = "../../../../modules/juce_gui_basics/components/juce_Component.cpp"; sourceTree = "SOURCE_ROOT"; }; + 4A36826C3F710B92F0347A16 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Singleton.h"; path = "../../../../modules/juce_core/memory/juce_Singleton.h"; sourceTree = "SOURCE_ROOT"; }; + 4A86B4371AE4FC58D879962C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CharPointer_UTF16.h"; path = "../../../../modules/juce_core/text/juce_CharPointer_UTF16.h"; sourceTree = "SOURCE_ROOT"; }; + 4ABF36D87D2BBEDA4DE28A4E = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FileChooserDialogBox.h"; path = "../../../../modules/juce_gui_basics/filebrowser/juce_FileChooserDialogBox.h"; sourceTree = "SOURCE_ROOT"; }; + 4ADE9EFB6C41DE44D40C9837 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_RelativeTime.cpp"; path = "../../../../modules/juce_core/time/juce_RelativeTime.cpp"; sourceTree = "SOURCE_ROOT"; }; + 4B27A11ADAC0D9957BBBCD3E = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_graphics.mm"; path = "../../../../modules/juce_graphics/juce_graphics.mm"; sourceTree = "SOURCE_ROOT"; }; + 4B27C30CF5AC7BFE0AF537AD = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_QuickTimeAudioFormat.cpp"; path = "../../../../modules/juce_audio_formats/codecs/juce_QuickTimeAudioFormat.cpp"; sourceTree = "SOURCE_ROOT"; }; + 4B8102606812A7964CF8D9CE = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_WindowsMediaAudioFormat.h"; path = "../../../../modules/juce_audio_formats/codecs/juce_WindowsMediaAudioFormat.h"; sourceTree = "SOURCE_ROOT"; }; + 4B8342C50F962C3F0AEE9830 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_NormalisableRange.h"; path = "../../../../modules/juce_core/maths/juce_NormalisableRange.h"; sourceTree = "SOURCE_ROOT"; }; + 4BAF7C54867DA3C275C2F59D = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ComponentPeer.cpp"; path = "../../../../modules/juce_gui_basics/windows/juce_ComponentPeer.cpp"; sourceTree = "SOURCE_ROOT"; }; + 4BDEC9A0A09EEDC9D7BDB826 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ByteOrder.h"; path = "../../../../modules/juce_core/memory/juce_ByteOrder.h"; sourceTree = "SOURCE_ROOT"; }; + 4BF9949E0C30EA64B16004BE = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioIODeviceType.h"; path = "../../../../modules/juce_audio_devices/audio_io/juce_AudioIODeviceType.h"; sourceTree = "SOURCE_ROOT"; }; + 4C40BFAE1E25F166EBB5EC48 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_GroupComponent.cpp"; path = "../../../../modules/juce_gui_basics/layout/juce_GroupComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; + 4C87C8EC24CE0EB64640238A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MD5.cpp"; path = "../../../../modules/juce_cryptography/hashing/juce_MD5.cpp"; sourceTree = "SOURCE_ROOT"; }; + 4CF92825BE7B97AC268C2AA5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_LookAndFeel.h"; path = "../../../../modules/juce_gui_basics/lookandfeel/juce_LookAndFeel.h"; sourceTree = "SOURCE_ROOT"; }; + 4D5901626201478A459CE46C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_LiveConstantEditor.h"; path = "../../../../modules/juce_gui_extra/misc/juce_LiveConstantEditor.h"; sourceTree = "SOURCE_ROOT"; }; 4D755C765B26C765D11BFFC8 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = DiscRecording.framework; path = System/Library/Frameworks/DiscRecording.framework; sourceTree = SDKROOT; }; - 4D7D8DF32996B70112FFA693 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ThreadWithProgressWindow.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/windows/juce_ThreadWithProgressWindow.cpp"; sourceTree = "SOURCE_ROOT"; }; - 4D97C6AE9A54A7F9663B0022 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_module_info"; path = "../../JuceLibraryCode/modules/juce_gui_extra/juce_module_info"; sourceTree = "SOURCE_ROOT"; }; - 4E02D9A4D6D38BACAB9326AC = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Result.h"; path = "../../JuceLibraryCode/modules/juce_core/misc/juce_Result.h"; sourceTree = "SOURCE_ROOT"; }; - 4E3E146079BC92DDE7B47EF9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_android_Fonts.cpp"; path = "../../JuceLibraryCode/modules/juce_graphics/native/juce_android_Fonts.cpp"; sourceTree = "SOURCE_ROOT"; }; - 4E7B7D1DE6EFB7C38845D97A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FileOutputStream.cpp"; path = "../../JuceLibraryCode/modules/juce_core/files/juce_FileOutputStream.cpp"; sourceTree = "SOURCE_ROOT"; }; - 4EA7EB8C8EDE34046AD54E2F = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_TableHeaderComponent.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/widgets/juce_TableHeaderComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; - 4F6BC156DF6D42B5A2E6B9D5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ToolbarItemComponent.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/widgets/juce_ToolbarItemComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; - 4F73548B7300043B5CBD8853 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ToneGeneratorAudioSource.h"; path = "../../JuceLibraryCode/modules/juce_audio_basics/sources/juce_ToneGeneratorAudioSource.h"; sourceTree = "SOURCE_ROOT"; }; - 500556EB77FC460F48E018BE = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_XmlDocument.cpp"; path = "../../JuceLibraryCode/modules/juce_core/xml/juce_XmlDocument.cpp"; sourceTree = "SOURCE_ROOT"; }; - 50923F018EFA0EC66289B8DB = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ResizableCornerComponent.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/layout/juce_ResizableCornerComponent.h"; sourceTree = "SOURCE_ROOT"; }; - 50CCC0CC14D17378013CFD72 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_audio_basics.mm"; path = "../../JuceLibraryCode/modules/juce_audio_basics/juce_audio_basics.mm"; sourceTree = "SOURCE_ROOT"; }; - 517756F0CB6482D0AAF4F6E3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FileSearchPath.cpp"; path = "../../JuceLibraryCode/modules/juce_core/files/juce_FileSearchPath.cpp"; sourceTree = "SOURCE_ROOT"; }; - 5178CA597B45B186FEF4D2CD = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Application.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/application/juce_Application.cpp"; sourceTree = "SOURCE_ROOT"; }; - 519B2190343506FF89DD9796 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ImageButton.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/buttons/juce_ImageButton.h"; sourceTree = "SOURCE_ROOT"; }; - 51EF1B32326BCE4445FD8929 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_URL.h"; path = "../../JuceLibraryCode/modules/juce_core/network/juce_URL.h"; sourceTree = "SOURCE_ROOT"; }; - 52438BC8DDE3E8A8A708D307 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FileBrowserComponent.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/filebrowser/juce_FileBrowserComponent.h"; sourceTree = "SOURCE_ROOT"; }; - 525381C319EDB9B47F9DFCFF = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FileChooserDialogBox.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/filebrowser/juce_FileChooserDialogBox.cpp"; sourceTree = "SOURCE_ROOT"; }; - 52B3E9170C4FF9A60E75030D = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Desktop.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/components/juce_Desktop.cpp"; sourceTree = "SOURCE_ROOT"; }; - 52C131B4F65C596E275CC17C = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_CharacterFunctions.cpp"; path = "../../JuceLibraryCode/modules/juce_core/text/juce_CharacterFunctions.cpp"; sourceTree = "SOURCE_ROOT"; }; - 52CC3D36E2A4DD363F99DA9B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_android_WebBrowserComponent.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_extra/native/juce_android_WebBrowserComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; - 52D6B752BBA03EE32E0186EF = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AffineTransform.h"; path = "../../JuceLibraryCode/modules/juce_graphics/geometry/juce_AffineTransform.h"; sourceTree = "SOURCE_ROOT"; }; - 534EB22CE7A71591FCCBA8E4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ComponentDragger.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/mouse/juce_ComponentDragger.cpp"; sourceTree = "SOURCE_ROOT"; }; - 538353D423AC527D313BE99E = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_StretchableLayoutResizerBar.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/layout/juce_StretchableLayoutResizerBar.cpp"; sourceTree = "SOURCE_ROOT"; }; - 538907D94243347E0BD1136A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_JackAudio.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_devices/native/juce_linux_JackAudio.cpp"; sourceTree = "SOURCE_ROOT"; }; - 53972777A5EAB63C5D1DF5E5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_HeapBlock.h"; path = "../../JuceLibraryCode/modules/juce_core/memory/juce_HeapBlock.h"; sourceTree = "SOURCE_ROOT"; }; - 53C236BFA019E49855DD8A22 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Synthesiser.h"; path = "../../JuceLibraryCode/modules/juce_audio_basics/synthesisers/juce_Synthesiser.h"; sourceTree = "SOURCE_ROOT"; }; - 53C4988130522C6DA28A4BE1 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ChildProcess.cpp"; path = "../../JuceLibraryCode/modules/juce_core/threads/juce_ChildProcess.cpp"; sourceTree = "SOURCE_ROOT"; }; - 53CB2A656137C68DC54B43C9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_PerformanceCounter.h"; path = "../../JuceLibraryCode/modules/juce_core/time/juce_PerformanceCounter.h"; sourceTree = "SOURCE_ROOT"; }; - 54063388CD6D9F64180BC16D = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DropShadowEffect.cpp"; path = "../../JuceLibraryCode/modules/juce_graphics/effects/juce_DropShadowEffect.cpp"; sourceTree = "SOURCE_ROOT"; }; - 5424AA8231E11912CD1C516C = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Drawable.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/drawables/juce_Drawable.cpp"; sourceTree = "SOURCE_ROOT"; }; - 5434B55E1B4DCA4392ADF45D = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_module_info"; path = "../../JuceLibraryCode/modules/juce_audio_formats/juce_module_info"; sourceTree = "SOURCE_ROOT"; }; - 54369A3FBDBDCC0FED963610 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Variant.cpp"; path = "../../JuceLibraryCode/modules/juce_core/containers/juce_Variant.cpp"; sourceTree = "SOURCE_ROOT"; }; - 549AA1BB3A58BFDDDDD1FA32 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OpenGL_osx.h"; path = "../../JuceLibraryCode/modules/juce_opengl/native/juce_OpenGL_osx.h"; sourceTree = "SOURCE_ROOT"; }; - 54C1B379B72BAE39C06D9BB0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_InterprocessConnection.h"; path = "../../JuceLibraryCode/modules/juce_events/interprocess/juce_InterprocessConnection.h"; sourceTree = "SOURCE_ROOT"; }; - 5500A9D5683F5124D0BAEA8B = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_RelativeRectangle.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/positioning/juce_RelativeRectangle.h"; sourceTree = "SOURCE_ROOT"; }; - 552E3A59D6200D3CA42CB2E5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_GroupComponent.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/layout/juce_GroupComponent.h"; sourceTree = "SOURCE_ROOT"; }; - 5550F75596B1C84414059D9C = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_android_Network.cpp"; path = "../../JuceLibraryCode/modules/juce_core/native/juce_android_Network.cpp"; sourceTree = "SOURCE_ROOT"; }; - 555BF349B10EE4EF21DCA398 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioSampleBuffer.h"; path = "../../JuceLibraryCode/modules/juce_audio_basics/buffers/juce_AudioSampleBuffer.h"; sourceTree = "SOURCE_ROOT"; }; - 5586252F2B71502A0C1A69B5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ThreadWithProgressWindow.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/windows/juce_ThreadWithProgressWindow.h"; sourceTree = "SOURCE_ROOT"; }; - 560303C3ABFD2D8DA80F5369 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ByteOrder.h"; path = "../../JuceLibraryCode/modules/juce_core/memory/juce_ByteOrder.h"; sourceTree = "SOURCE_ROOT"; }; - 56207999C7136BA24F53DB94 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_RelativePoint.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/positioning/juce_RelativePoint.h"; sourceTree = "SOURCE_ROOT"; }; - 56872D4E18FFA80AEDD4FF35 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_Fonts.cpp"; path = "../../JuceLibraryCode/modules/juce_graphics/native/juce_linux_Fonts.cpp"; sourceTree = "SOURCE_ROOT"; }; - 568C771CA43B20ED9320E9AD = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_InputStream.cpp"; path = "../../JuceLibraryCode/modules/juce_core/streams/juce_InputStream.cpp"; sourceTree = "SOURCE_ROOT"; }; - 56DCDED7C229BEA998AE9610 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_GraphicsContext.cpp"; path = "../../JuceLibraryCode/modules/juce_graphics/contexts/juce_GraphicsContext.cpp"; sourceTree = "SOURCE_ROOT"; }; - 570EA0ADD7290B6AF6C74960 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_OpenGLAppComponent.cpp"; path = "../../JuceLibraryCode/modules/juce_opengl/utils/juce_OpenGLAppComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; - 572F0A8E449EEE319155A448 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_module_info"; path = "../../JuceLibraryCode/modules/juce_graphics/juce_module_info"; sourceTree = "SOURCE_ROOT"; }; - 572F241637045113CA1101E3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ApplicationBase.cpp"; path = "../../JuceLibraryCode/modules/juce_events/messages/juce_ApplicationBase.cpp"; sourceTree = "SOURCE_ROOT"; }; - 57D9F9DA0E4AC9350182E868 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_FileChooser.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/native/juce_win32_FileChooser.cpp"; sourceTree = "SOURCE_ROOT"; }; - 57F9DFFE80638F013ED82F0B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_CodeDocument.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_extra/code_editor/juce_CodeDocument.cpp"; sourceTree = "SOURCE_ROOT"; }; - 584FB01EADCAFB49A98CED27 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_Registry.cpp"; path = "../../JuceLibraryCode/modules/juce_core/native/juce_win32_Registry.cpp"; sourceTree = "SOURCE_ROOT"; }; - 58F79BEACB41061A067708E4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CodeEditorComponent.h"; path = "../../JuceLibraryCode/modules/juce_gui_extra/code_editor/juce_CodeEditorComponent.h"; sourceTree = "SOURCE_ROOT"; }; - 58FB0E03D5E6CC4122CD00B8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FileListComponent.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/filebrowser/juce_FileListComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; - 5982BD1B4149622A6FD884A4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MouseEvent.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/mouse/juce_MouseEvent.cpp"; sourceTree = "SOURCE_ROOT"; }; - 5A8383F3E5B628DE60DB8291 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_gui_extra.mm"; path = "../../JuceLibraryCode/modules/juce_gui_extra/juce_gui_extra.mm"; sourceTree = "SOURCE_ROOT"; }; - 5B679BA94EFF51894AD674EA = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_PropertiesFile.h"; path = "../../JuceLibraryCode/modules/juce_data_structures/app_properties/juce_PropertiesFile.h"; sourceTree = "SOURCE_ROOT"; }; - 5B70ED35F78822734FD91F6F = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ComboBox.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/widgets/juce_ComboBox.h"; sourceTree = "SOURCE_ROOT"; }; - 5B7A3EE41F87CB2931C1E13C = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioSampleBuffer.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_basics/buffers/juce_AudioSampleBuffer.cpp"; sourceTree = "SOURCE_ROOT"; }; - 5B9FDDF7446043886E09E303 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Vector3D.h"; path = "../../JuceLibraryCode/modules/juce_opengl/geometry/juce_Vector3D.h"; sourceTree = "SOURCE_ROOT"; }; - 5C3EF1C1AEC96D6C8687E242 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_android_Threads.cpp"; path = "../../JuceLibraryCode/modules/juce_core/native/juce_android_Threads.cpp"; sourceTree = "SOURCE_ROOT"; }; - 5C74D5593E152C52854A522F = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MixerAudioSource.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_basics/sources/juce_MixerAudioSource.cpp"; sourceTree = "SOURCE_ROOT"; }; - 5CEC5FFCAF1B33BE9B86CDBE = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_PreferencesPanel.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_extra/misc/juce_PreferencesPanel.cpp"; sourceTree = "SOURCE_ROOT"; }; - 5D4B884A37E3A190B16B34CA = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ListBox.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/widgets/juce_ListBox.h"; sourceTree = "SOURCE_ROOT"; }; - 5D903A277EFDDFA522C67E84 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_KnownPluginList.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_processors/scanning/juce_KnownPluginList.cpp"; sourceTree = "SOURCE_ROOT"; }; - 5DF85E59C6FBA88E394C4FD4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_WaitableEvent.h"; path = "../../JuceLibraryCode/modules/juce_core/threads/juce_WaitableEvent.h"; sourceTree = "SOURCE_ROOT"; }; - 5E135BD422EF904C0FCAD1D0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_GlyphArrangement.h"; path = "../../JuceLibraryCode/modules/juce_graphics/fonts/juce_GlyphArrangement.h"; sourceTree = "SOURCE_ROOT"; }; - 5E3AE8001BCEFBED6A1954DA = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioPluginFormatManager.h"; path = "../../JuceLibraryCode/modules/juce_audio_processors/format/juce_AudioPluginFormatManager.h"; sourceTree = "SOURCE_ROOT"; }; - 5E5F9CA2713C02B4DAAEFF9C = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Result.cpp"; path = "../../JuceLibraryCode/modules/juce_core/misc/juce_Result.cpp"; sourceTree = "SOURCE_ROOT"; }; - 5F1334788D34BA2E6EF83086 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_mac_CoreGraphicsHelpers.h"; path = "../../JuceLibraryCode/modules/juce_graphics/native/juce_mac_CoreGraphicsHelpers.h"; sourceTree = "SOURCE_ROOT"; }; - 5F1E31EAC156296643CA5A5F = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_TreeView.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/widgets/juce_TreeView.cpp"; sourceTree = "SOURCE_ROOT"; }; - 5FD5C6D8A917C60FBF029EC0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ButtonPropertyComponent.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/properties/juce_ButtonPropertyComponent.h"; sourceTree = "SOURCE_ROOT"; }; - 60E972163AE7F32E1AC7BF57 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ElementComparator.h"; path = "../../JuceLibraryCode/modules/juce_core/containers/juce_ElementComparator.h"; sourceTree = "SOURCE_ROOT"; }; - 61E5B74F334DF6387DB68E7C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OutputStream.h"; path = "../../JuceLibraryCode/modules/juce_core/streams/juce_OutputStream.h"; sourceTree = "SOURCE_ROOT"; }; - 620921796E4C408487F2D19D = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_HashMap.h"; path = "../../JuceLibraryCode/modules/juce_core/containers/juce_HashMap.h"; sourceTree = "SOURCE_ROOT"; }; - 621EA7E956C5BA64D95DC755 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MemoryMappedFile.h"; path = "../../JuceLibraryCode/modules/juce_core/files/juce_MemoryMappedFile.h"; sourceTree = "SOURCE_ROOT"; }; - 622800F19C8B24050A92D15B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_BufferingAudioSource.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_basics/sources/juce_BufferingAudioSource.cpp"; sourceTree = "SOURCE_ROOT"; }; - 625D1399D1DC0CE04C2BDF7A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_PerformanceCounter.cpp"; path = "../../JuceLibraryCode/modules/juce_core/time/juce_PerformanceCounter.cpp"; sourceTree = "SOURCE_ROOT"; }; - 62AC3BCA9BBA2BDCEE842496 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TextInputTarget.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/keyboard/juce_TextInputTarget.h"; sourceTree = "SOURCE_ROOT"; }; - 62F3157710E0EB1EEDFC71DA = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_CustomTypeface.cpp"; path = "../../JuceLibraryCode/modules/juce_graphics/fonts/juce_CustomTypeface.cpp"; sourceTree = "SOURCE_ROOT"; }; - 62FAD1304BBC71BEDBB033D0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_SystemStats.h"; path = "../../JuceLibraryCode/modules/juce_core/system/juce_SystemStats.h"; sourceTree = "SOURCE_ROOT"; }; - 62FE07463F39D02D8C6F2CA5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CustomTypeface.h"; path = "../../JuceLibraryCode/modules/juce_graphics/fonts/juce_CustomTypeface.h"; sourceTree = "SOURCE_ROOT"; }; - 637A70321AC8948BA9E033FD = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioPluginFormat.h"; path = "../../JuceLibraryCode/modules/juce_audio_processors/format/juce_AudioPluginFormat.h"; sourceTree = "SOURCE_ROOT"; }; - 63E5D7EEC148FF82E7216095 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioFormatManager.h"; path = "../../JuceLibraryCode/modules/juce_audio_formats/format/juce_AudioFormatManager.h"; sourceTree = "SOURCE_ROOT"; }; - 646046D51C5B2655CC633415 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_LocalisedStrings.cpp"; path = "../../JuceLibraryCode/modules/juce_core/text/juce_LocalisedStrings.cpp"; sourceTree = "SOURCE_ROOT"; }; - 6481FF60536C5296C176F94B = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_BubbleMessageComponent.h"; path = "../../JuceLibraryCode/modules/juce_gui_extra/misc/juce_BubbleMessageComponent.h"; sourceTree = "SOURCE_ROOT"; }; - 65411B7DBE47CE3DF4164F05 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FlacAudioFormat.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_formats/codecs/juce_FlacAudioFormat.cpp"; sourceTree = "SOURCE_ROOT"; }; - 6544288E0768C9FCABE3B081 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ChangeListener.h"; path = "../../JuceLibraryCode/modules/juce_events/broadcasters/juce_ChangeListener.h"; sourceTree = "SOURCE_ROOT"; }; - 659511EADFE62ABB7141CA89 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DeletedAtShutdown.h"; path = "../../JuceLibraryCode/modules/juce_events/messages/juce_DeletedAtShutdown.h"; sourceTree = "SOURCE_ROOT"; }; - 662061336599080D7C0ADB56 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_HighResolutionTimer.h"; path = "../../JuceLibraryCode/modules/juce_core/threads/juce_HighResolutionTimer.h"; sourceTree = "SOURCE_ROOT"; }; - 669C2806A49522217459BB3E = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ReadWriteLock.cpp"; path = "../../JuceLibraryCode/modules/juce_core/threads/juce_ReadWriteLock.cpp"; sourceTree = "SOURCE_ROOT"; }; + 4DB2143B264FC1AE54490BF9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_SortedSet.h"; path = "../../../../modules/juce_core/containers/juce_SortedSet.h"; sourceTree = "SOURCE_ROOT"; }; + 4DB48F6BAEFA120A31259EAE = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_SystemStats.cpp"; path = "../../../../modules/juce_core/native/juce_linux_SystemStats.cpp"; sourceTree = "SOURCE_ROOT"; }; + 4E3C26EE8C6F996F207F0C32 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_RelativePoint.cpp"; path = "../../../../modules/juce_gui_basics/positioning/juce_RelativePoint.cpp"; sourceTree = "SOURCE_ROOT"; }; + 4EAE69CF6B5097A57EBCD27B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ChannelRemappingAudioSource.cpp"; path = "../../../../modules/juce_audio_basics/sources/juce_ChannelRemappingAudioSource.cpp"; sourceTree = "SOURCE_ROOT"; }; + 4EB8D72F57E00C560E370DCB = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_OpenGLShaderProgram.cpp"; path = "../../../../modules/juce_opengl/opengl/juce_OpenGLShaderProgram.cpp"; sourceTree = "SOURCE_ROOT"; }; + 4EBC561A323AEE4D76AD7906 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MixerAudioSource.cpp"; path = "../../../../modules/juce_audio_basics/sources/juce_MixerAudioSource.cpp"; sourceTree = "SOURCE_ROOT"; }; + 4F2D3BD9697AAFA060EAAA59 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ChoicePropertyComponent.h"; path = "../../../../modules/juce_gui_basics/properties/juce_ChoicePropertyComponent.h"; sourceTree = "SOURCE_ROOT"; }; + 4F5C213B72A375A83FE50979 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_Fonts.cpp"; path = "../../../../modules/juce_graphics/native/juce_linux_Fonts.cpp"; sourceTree = "SOURCE_ROOT"; }; + 4F5D668DCEF2B622FD46073D = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ApplicationCommandID.h"; path = "../../../../modules/juce_gui_basics/commands/juce_ApplicationCommandID.h"; sourceTree = "SOURCE_ROOT"; }; + 4F5DED2313FC69EA518E5679 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_InterprocessConnectionServer.cpp"; path = "../../../../modules/juce_events/interprocess/juce_InterprocessConnectionServer.cpp"; sourceTree = "SOURCE_ROOT"; }; + 4F96BFF5D1D40B81C861F92F = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_opengl.h"; path = "../../../../modules/juce_opengl/juce_opengl.h"; sourceTree = "SOURCE_ROOT"; }; + 4FB8B3386156F5702A20F7D8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_PNGLoader.cpp"; path = "../../../../modules/juce_graphics/image_formats/juce_PNGLoader.cpp"; sourceTree = "SOURCE_ROOT"; }; + 500F7CB9F45B62E46F4BBA57 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MenuBarModel.h"; path = "../../../../modules/juce_gui_basics/menus/juce_MenuBarModel.h"; sourceTree = "SOURCE_ROOT"; }; + 51026A3BE98FD70FD916CF45 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_RelativeCoordinatePositioner.cpp"; path = "../../../../modules/juce_gui_basics/positioning/juce_RelativeCoordinatePositioner.cpp"; sourceTree = "SOURCE_ROOT"; }; + 518E9E553CD9F7D215B75B88 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OpenGL_android.h"; path = "../../../../modules/juce_opengl/native/juce_OpenGL_android.h"; sourceTree = "SOURCE_ROOT"; }; + 519CE739793F0797AF1A7957 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ColourSelector.cpp"; path = "../../../../modules/juce_gui_extra/misc/juce_ColourSelector.cpp"; sourceTree = "SOURCE_ROOT"; }; + 52062790A5E737C8846A23A2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MemoryInputStream.h"; path = "../../../../modules/juce_core/streams/juce_MemoryInputStream.h"; sourceTree = "SOURCE_ROOT"; }; + 531BA61B027758A7978052A4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AppleRemote.h"; path = "../../../../modules/juce_gui_extra/misc/juce_AppleRemote.h"; sourceTree = "SOURCE_ROOT"; }; + 5358DE9C9773654731E6F615 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MidiBuffer.h"; path = "../../../../modules/juce_audio_basics/midi/juce_MidiBuffer.h"; sourceTree = "SOURCE_ROOT"; }; + 5383E87DC6DC1D251C271A50 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ComboBox.h"; path = "../../../../modules/juce_gui_basics/widgets/juce_ComboBox.h"; sourceTree = "SOURCE_ROOT"; }; + 5384C065CDEB3032907ECCAF = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Desktop.h"; path = "../../../../modules/juce_gui_basics/components/juce_Desktop.h"; sourceTree = "SOURCE_ROOT"; }; + 553655CA0122E128BC368AD7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ColourSelector.h"; path = "../../../../modules/juce_gui_extra/misc/juce_ColourSelector.h"; sourceTree = "SOURCE_ROOT"; }; + 55417F6D23E7075E5E27BECB = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_AudioCDBurner.mm"; path = "../../../../modules/juce_audio_devices/native/juce_mac_AudioCDBurner.mm"; sourceTree = "SOURCE_ROOT"; }; + 55A4B5CF98FAC1CC23E49C82 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_ios_Windowing.mm"; path = "../../../../modules/juce_gui_basics/native/juce_ios_Windowing.mm"; sourceTree = "SOURCE_ROOT"; }; + 55CEFA60FA0CBA0E6CB71F5D = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_SparseSet.h"; path = "../../../../modules/juce_core/containers/juce_SparseSet.h"; sourceTree = "SOURCE_ROOT"; }; + 55D04DC4EA2F037CCD5DF9A6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_GIFLoader.cpp"; path = "../../../../modules/juce_graphics/image_formats/juce_GIFLoader.cpp"; sourceTree = "SOURCE_ROOT"; }; + 562E99EE1A4B733B7F751955 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_DragAndDrop.cpp"; path = "../../../../modules/juce_gui_basics/native/juce_win32_DragAndDrop.cpp"; sourceTree = "SOURCE_ROOT"; }; + 56545F3F893C3D8CC9215051 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_mac_CoreMidi.cpp"; path = "../../../../modules/juce_audio_devices/native/juce_mac_CoreMidi.cpp"; sourceTree = "SOURCE_ROOT"; }; + 567D63D778B7A22C5D97F1C5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_BlowFish.h"; path = "../../../../modules/juce_cryptography/encryption/juce_BlowFish.h"; sourceTree = "SOURCE_ROOT"; }; + 56985D9599D0D1D00B42F95B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_LookAndFeel_V1.cpp"; path = "../../../../modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V1.cpp"; sourceTree = "SOURCE_ROOT"; }; + 5703889367170F80CAC76898 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_Files.mm"; path = "../../../../modules/juce_core/native/juce_mac_Files.mm"; sourceTree = "SOURCE_ROOT"; }; + 570C35930202882A634FC029 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ResamplingAudioSource.cpp"; path = "../../../../modules/juce_audio_basics/sources/juce_ResamplingAudioSource.cpp"; sourceTree = "SOURCE_ROOT"; }; + 5710CADD28060D8E949D96D5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_LookAndFeel_V2.cpp"; path = "../../../../modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V2.cpp"; sourceTree = "SOURCE_ROOT"; }; + 5719A93B0F6AFE95FC49B673 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_Midi.cpp"; path = "../../../../modules/juce_audio_devices/native/juce_win32_Midi.cpp"; sourceTree = "SOURCE_ROOT"; }; + 57490A9F97D62E7A312EA90C = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FileInputStream.cpp"; path = "../../../../modules/juce_core/files/juce_FileInputStream.cpp"; sourceTree = "SOURCE_ROOT"; }; + 5774E190A351EDF7B7AAB188 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Sampler.cpp"; path = "../../../../modules/juce_audio_formats/sampler/juce_Sampler.cpp"; sourceTree = "SOURCE_ROOT"; }; + 57A0BF533D7A7B57321A8174 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MouseInputSource.h"; path = "../../../../modules/juce_gui_basics/mouse/juce_MouseInputSource.h"; sourceTree = "SOURCE_ROOT"; }; + 5878CA91071620345AB5B3C4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_UnitTest.cpp"; path = "../../../../modules/juce_core/unit_tests/juce_UnitTest.cpp"; sourceTree = "SOURCE_ROOT"; }; + 595A9929C0E873C30AC9AA87 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_PopupMenu.cpp"; path = "../../../../modules/juce_gui_basics/menus/juce_PopupMenu.cpp"; sourceTree = "SOURCE_ROOT"; }; + 59CAB9E5A0CBBC51342FC065 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AsyncUpdater.cpp"; path = "../../../../modules/juce_events/broadcasters/juce_AsyncUpdater.cpp"; sourceTree = "SOURCE_ROOT"; }; + 5A1777E116DA01B554C90CDA = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FillType.cpp"; path = "../../../../modules/juce_graphics/colour/juce_FillType.cpp"; sourceTree = "SOURCE_ROOT"; }; + 5A5749D0A878955C964DD2C5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MouseCursor.cpp"; path = "../../../../modules/juce_gui_basics/mouse/juce_MouseCursor.cpp"; sourceTree = "SOURCE_ROOT"; }; + 5A854859042F6CD761688B25 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_CharacterFunctions.cpp"; path = "../../../../modules/juce_core/text/juce_CharacterFunctions.cpp"; sourceTree = "SOURCE_ROOT"; }; + 5AAE605D230E253D4EAC195E = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ShapeButton.cpp"; path = "../../../../modules/juce_gui_basics/buttons/juce_ShapeButton.cpp"; sourceTree = "SOURCE_ROOT"; }; + 5B5180DAAB935CB6D1DE9AA6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Draggable3DOrientation.h"; path = "../../../../modules/juce_opengl/geometry/juce_Draggable3DOrientation.h"; sourceTree = "SOURCE_ROOT"; }; + 5BBC57B395B553CE08AC4BD7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Drawable.h"; path = "../../../../modules/juce_gui_basics/drawables/juce_Drawable.h"; sourceTree = "SOURCE_ROOT"; }; + 5BBF8CA223EEE4D9C769E453 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ListenerList.h"; path = "../../../../modules/juce_events/broadcasters/juce_ListenerList.h"; sourceTree = "SOURCE_ROOT"; }; + 5C0E42BCF4ED32E1381E7A23 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_OpenGLTexture.cpp"; path = "../../../../modules/juce_opengl/opengl/juce_OpenGLTexture.cpp"; sourceTree = "SOURCE_ROOT"; }; + 5C58E6217AF57BD2A33ED617 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_JSON.h"; path = "../../../../modules/juce_core/javascript/juce_JSON.h"; sourceTree = "SOURCE_ROOT"; }; + 5C62F423D8469A02E55BF59D = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ChangeBroadcaster.h"; path = "../../../../modules/juce_events/broadcasters/juce_ChangeBroadcaster.h"; sourceTree = "SOURCE_ROOT"; }; + 5C8795B0DE5C729CA18FE89B = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Colour.h"; path = "../../../../modules/juce_graphics/colour/juce_Colour.h"; sourceTree = "SOURCE_ROOT"; }; + 5CDC0F220B1EAE847D38D1DE = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Time.h"; path = "../../../../modules/juce_core/time/juce_Time.h"; sourceTree = "SOURCE_ROOT"; }; + 5D1F3BD1476426752ACB1EB2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Path.h"; path = "../../../../modules/juce_graphics/geometry/juce_Path.h"; sourceTree = "SOURCE_ROOT"; }; + 5D43D909CB26D4A07A62A4F7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Logger.cpp"; path = "../../../../modules/juce_core/logging/juce_Logger.cpp"; sourceTree = "SOURCE_ROOT"; }; + 5D4A62D4893C16D7B17C6A43 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Label.cpp"; path = "../../../../modules/juce_gui_basics/widgets/juce_Label.cpp"; sourceTree = "SOURCE_ROOT"; }; + 5EB144BD6AC4D4DE96ABFCA2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_AudioCDReader.mm"; path = "../../../../modules/juce_audio_devices/native/juce_mac_AudioCDReader.mm"; sourceTree = "SOURCE_ROOT"; }; + 6018A3A37F34AE52B39A14D5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_video.mm"; path = "../../../../modules/juce_video/juce_video.mm"; sourceTree = "SOURCE_ROOT"; }; + 605EA4B27D057BCB9263BCFA = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MemoryMappedFile.h"; path = "../../../../modules/juce_core/files/juce_MemoryMappedFile.h"; sourceTree = "SOURCE_ROOT"; }; + 60D8280577C14A7D3F67563D = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ListBox.h"; path = "../../../../modules/juce_gui_basics/widgets/juce_ListBox.h"; sourceTree = "SOURCE_ROOT"; }; + 610F820C21D914E9794A36EE = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Justification.h"; path = "../../../../modules/juce_graphics/placement/juce_Justification.h"; sourceTree = "SOURCE_ROOT"; }; + 611A0824757D50610BB03562 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CameraDevice.h"; path = "../../../../modules/juce_video/capture/juce_CameraDevice.h"; sourceTree = "SOURCE_ROOT"; }; + 61473E0A6AF9B900406695B8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MouseInactivityDetector.cpp"; path = "../../../../modules/juce_gui_basics/mouse/juce_MouseInactivityDetector.cpp"; sourceTree = "SOURCE_ROOT"; }; + 616493921A733162495E7553 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_UndoableAction.h"; path = "../../../../modules/juce_data_structures/undomanager/juce_UndoableAction.h"; sourceTree = "SOURCE_ROOT"; }; + 61797A8C01DC08E83AFA4540 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_NewLine.h"; path = "../../../../modules/juce_core/text/juce_NewLine.h"; sourceTree = "SOURCE_ROOT"; }; + 618839275E13B9DB660001E4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_posix_NamedPipe.cpp"; path = "../../../../modules/juce_core/native/juce_posix_NamedPipe.cpp"; sourceTree = "SOURCE_ROOT"; }; + 61E1C2246CBD45C5A1F40102 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_android_FileChooser.cpp"; path = "../../../../modules/juce_gui_basics/native/juce_android_FileChooser.cpp"; sourceTree = "SOURCE_ROOT"; }; + 61F0D5937E23A6A9EE8D479C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ReferenceCountedObject.h"; path = "../../../../modules/juce_core/memory/juce_ReferenceCountedObject.h"; sourceTree = "SOURCE_ROOT"; }; + 6238740697CA1F0746776243 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_android_Files.cpp"; path = "../../../../modules/juce_core/native/juce_android_Files.cpp"; sourceTree = "SOURCE_ROOT"; }; + 62B6E8B6269ADEF23D85FA3E = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_audio_formats.h"; path = "../../../../modules/juce_audio_formats/juce_audio_formats.h"; sourceTree = "SOURCE_ROOT"; }; + 62E534D1F0B31CD4A1B572E1 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioIODevice.h"; path = "../../../../modules/juce_audio_devices/audio_io/juce_AudioIODevice.h"; sourceTree = "SOURCE_ROOT"; }; + 62EA5E33A940F30BBB56E293 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_RectanglePlacement.h"; path = "../../../../modules/juce_graphics/placement/juce_RectanglePlacement.h"; sourceTree = "SOURCE_ROOT"; }; + 63B031ABCF8DE5C94889823B = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_events.h"; path = "../../../../modules/juce_events/juce_events.h"; sourceTree = "SOURCE_ROOT"; }; + 63E66F6D161941FE12465C29 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_BufferingAudioFormatReader.cpp"; path = "../../../../modules/juce_audio_formats/format/juce_BufferingAudioFormatReader.cpp"; sourceTree = "SOURCE_ROOT"; }; + 63EE49826BF4CFBD9D546DAC = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ImageEffectFilter.h"; path = "../../../../modules/juce_graphics/effects/juce_ImageEffectFilter.h"; sourceTree = "SOURCE_ROOT"; }; + 6421EA349C5D558114D36717 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_InputSource.h"; path = "../../../../modules/juce_core/streams/juce_InputSource.h"; sourceTree = "SOURCE_ROOT"; }; + 64807B3EFFBDC3348512901E = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_LowLevelGraphicsPostScriptRenderer.h"; path = "../../../../modules/juce_graphics/contexts/juce_LowLevelGraphicsPostScriptRenderer.h"; sourceTree = "SOURCE_ROOT"; }; + 65DF385E92A4A65760DC3BD0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Slider.h"; path = "../../../../modules/juce_gui_basics/widgets/juce_Slider.h"; sourceTree = "SOURCE_ROOT"; }; + 66897EA1FD2CDFB4CED47F8B = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_RSAKey.h"; path = "../../../../modules/juce_cryptography/encryption/juce_RSAKey.h"; sourceTree = "SOURCE_ROOT"; }; + 66B37CB373F19F65553466C3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_mac_CarbonViewWrapperComponent.h"; path = "../../../../modules/juce_gui_extra/native/juce_mac_CarbonViewWrapperComponent.h"; sourceTree = "SOURCE_ROOT"; }; + 66CEE40E51335F661B5C5C66 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ToolbarItemComponent.h"; path = "../../../../modules/juce_gui_basics/widgets/juce_ToolbarItemComponent.h"; sourceTree = "SOURCE_ROOT"; }; 66DE43B56D8670C78DD3998D = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; }; - 66EFBCF1D3E6A5FF27129EC3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CharacterFunctions.h"; path = "../../JuceLibraryCode/modules/juce_core/text/juce_CharacterFunctions.h"; sourceTree = "SOURCE_ROOT"; }; - 671FF5E5EBF6920BAAA79B4E = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FloatVectorOperations.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_basics/buffers/juce_FloatVectorOperations.cpp"; sourceTree = "SOURCE_ROOT"; }; - 6726A33668AC0DB1B5E30C65 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_GZIPDecompressorInputStream.cpp"; path = "../../JuceLibraryCode/modules/juce_core/zip/juce_GZIPDecompressorInputStream.cpp"; sourceTree = "SOURCE_ROOT"; }; - 67319D5DD2BD8D31706DB34A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DrawableShape.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/drawables/juce_DrawableShape.cpp"; sourceTree = "SOURCE_ROOT"; }; - 675AA4F17363E5F5F8B5C307 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_Midi.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_devices/native/juce_linux_Midi.cpp"; sourceTree = "SOURCE_ROOT"; }; - 678267D32EB2BF8C0D1217DC = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_events.h"; path = "../../JuceLibraryCode/modules/juce_events/juce_events.h"; sourceTree = "SOURCE_ROOT"; }; - 688E8CBA135D8B2265E0B809 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CodeTokeniser.h"; path = "../../JuceLibraryCode/modules/juce_gui_extra/code_editor/juce_CodeTokeniser.h"; sourceTree = "SOURCE_ROOT"; }; - 692A2B951D818FED7DB03481 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_CoreAudioFormat.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_formats/codecs/juce_CoreAudioFormat.cpp"; sourceTree = "SOURCE_ROOT"; }; - 69572C0082E358837174B04E = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_IIRFilterAudioSource.h"; path = "../../JuceLibraryCode/modules/juce_audio_basics/sources/juce_IIRFilterAudioSource.h"; sourceTree = "SOURCE_ROOT"; }; - 696CCA96408572659C97FBB1 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MouseListener.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/mouse/juce_MouseListener.cpp"; sourceTree = "SOURCE_ROOT"; }; - 69EBBAC63BDB225AD7B9B19C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CameraDevice.h"; path = "../../JuceLibraryCode/modules/juce_video/capture/juce_CameraDevice.h"; sourceTree = "SOURCE_ROOT"; }; - 6A207487147E4661842F2EEA = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Toolbar.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/widgets/juce_Toolbar.h"; sourceTree = "SOURCE_ROOT"; }; - 6AEA07E5992D813558940710 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ImageConvolutionKernel.cpp"; path = "../../JuceLibraryCode/modules/juce_graphics/images/juce_ImageConvolutionKernel.cpp"; sourceTree = "SOURCE_ROOT"; }; - 6B0CD9C29CB8715C6E916244 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Javascript.h"; path = "../../JuceLibraryCode/modules/juce_core/javascript/juce_Javascript.h"; sourceTree = "SOURCE_ROOT"; }; - 6B3ADCFFE9EF5870BD04FA95 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FileSearchPath.h"; path = "../../JuceLibraryCode/modules/juce_core/files/juce_FileSearchPath.h"; sourceTree = "SOURCE_ROOT"; }; - 6B3FA3604D7E751B8F18E841 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_NamedValueSet.h"; path = "../../JuceLibraryCode/modules/juce_core/containers/juce_NamedValueSet.h"; sourceTree = "SOURCE_ROOT"; }; - 6B8FAA45DB6613DA449E26FD = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_LowLevelGraphicsPostScriptRenderer.cpp"; path = "../../JuceLibraryCode/modules/juce_graphics/contexts/juce_LowLevelGraphicsPostScriptRenderer.cpp"; sourceTree = "SOURCE_ROOT"; }; - 6BC5245D8E2ACD816BA03475 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MixerAudioSource.h"; path = "../../JuceLibraryCode/modules/juce_audio_basics/sources/juce_MixerAudioSource.h"; sourceTree = "SOURCE_ROOT"; }; - 6C140CB15288D8837DF454C4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_StretchableLayoutManager.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/layout/juce_StretchableLayoutManager.cpp"; sourceTree = "SOURCE_ROOT"; }; - 6CAD1F4452A73BAB29EF5D4B = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ImagePreviewComponent.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/filebrowser/juce_ImagePreviewComponent.h"; sourceTree = "SOURCE_ROOT"; }; - 6CC23E6F664F9114395C5DFD = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_mac_CarbonViewWrapperComponent.h"; path = "../../JuceLibraryCode/modules/juce_gui_extra/native/juce_mac_CarbonViewWrapperComponent.h"; sourceTree = "SOURCE_ROOT"; }; - 6CD9A954A84F5088471631BB = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_PluginDirectoryScanner.h"; path = "../../JuceLibraryCode/modules/juce_audio_processors/scanning/juce_PluginDirectoryScanner.h"; sourceTree = "SOURCE_ROOT"; }; - 6D111AFF5B12430B6A225802 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Atomic.h"; path = "../../JuceLibraryCode/modules/juce_core/memory/juce_Atomic.h"; sourceTree = "SOURCE_ROOT"; }; - 6D4CC9AA8FAC940AA974DF33 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TimeSliceThread.h"; path = "../../JuceLibraryCode/modules/juce_core/threads/juce_TimeSliceThread.h"; sourceTree = "SOURCE_ROOT"; }; - 6D688EBEDAD32DBB4706CD39 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_SystemTrayIcon.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_extra/native/juce_linux_SystemTrayIcon.cpp"; sourceTree = "SOURCE_ROOT"; }; - 6D9056359A751B000DB1E9B3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_WildcardFileFilter.h"; path = "../../JuceLibraryCode/modules/juce_core/files/juce_WildcardFileFilter.h"; sourceTree = "SOURCE_ROOT"; }; - 6DA5BE65E7A6BAAE4797856D = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MemoryInputStream.cpp"; path = "../../JuceLibraryCode/modules/juce_core/streams/juce_MemoryInputStream.cpp"; sourceTree = "SOURCE_ROOT"; }; - 6E0B73556F626E9DDB2F2F4C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ApplicationCommandManager.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/commands/juce_ApplicationCommandManager.h"; sourceTree = "SOURCE_ROOT"; }; - 6EAAEC3D37B6CC538F2BAC98 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ApplicationCommandManager.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/commands/juce_ApplicationCommandManager.cpp"; sourceTree = "SOURCE_ROOT"; }; - 6EC413415C211744AB3B7E4C = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_Strings.mm"; path = "../../JuceLibraryCode/modules/juce_core/native/juce_mac_Strings.mm"; sourceTree = "SOURCE_ROOT"; }; - 6EDF4554CA5AA64920F95E5E = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Expression.h"; path = "../../JuceLibraryCode/modules/juce_core/maths/juce_Expression.h"; sourceTree = "SOURCE_ROOT"; }; - 6F195B4646BF53D1918F1764 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MACAddress.h"; path = "../../JuceLibraryCode/modules/juce_core/network/juce_MACAddress.h"; sourceTree = "SOURCE_ROOT"; }; - 6F2E3A5DC0BE1D6917784F47 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_StringPool.cpp"; path = "../../JuceLibraryCode/modules/juce_core/text/juce_StringPool.cpp"; sourceTree = "SOURCE_ROOT"; }; - 6F6DDA3B78AF47374B959263 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MidiOutput.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_devices/midi_io/juce_MidiOutput.cpp"; sourceTree = "SOURCE_ROOT"; }; - 6F7FBB230E206816379F5C83 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioIODevice.h"; path = "../../JuceLibraryCode/modules/juce_audio_devices/audio_io/juce_AudioIODevice.h"; sourceTree = "SOURCE_ROOT"; }; - 6F8DE38E80B72E6FF126483A = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ImageEffectFilter.h"; path = "../../JuceLibraryCode/modules/juce_graphics/effects/juce_ImageEffectFilter.h"; sourceTree = "SOURCE_ROOT"; }; - 6F906DF202EB6B421F9C5813 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_LuaCodeTokeniser.h"; path = "../../JuceLibraryCode/modules/juce_gui_extra/code_editor/juce_LuaCodeTokeniser.h"; sourceTree = "SOURCE_ROOT"; }; - 6FC349656B1BC972D349E67B = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ComponentBuilder.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/layout/juce_ComponentBuilder.h"; sourceTree = "SOURCE_ROOT"; }; - 70284B038C6F9030F7CEDEE7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ApplicationBase.h"; path = "../../JuceLibraryCode/modules/juce_events/messages/juce_ApplicationBase.h"; sourceTree = "SOURCE_ROOT"; }; - 702AE0E6FC3184CD8E83643B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MemoryOutputStream.cpp"; path = "../../JuceLibraryCode/modules/juce_core/streams/juce_MemoryOutputStream.cpp"; sourceTree = "SOURCE_ROOT"; }; - 703DEBC270B90BCBA7BCF714 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_mac_SystemTrayIcon.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_extra/native/juce_mac_SystemTrayIcon.cpp"; sourceTree = "SOURCE_ROOT"; }; - 705C1BA65E7FB620E01B44A5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AffineTransform.cpp"; path = "../../JuceLibraryCode/modules/juce_graphics/geometry/juce_AffineTransform.cpp"; sourceTree = "SOURCE_ROOT"; }; - 7063EC546938B514B6EE8982 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MultiTouchMapper.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/native/juce_MultiTouchMapper.h"; sourceTree = "SOURCE_ROOT"; }; - 70835A4653D8754BB6C7CFE2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FillType.cpp"; path = "../../JuceLibraryCode/modules/juce_graphics/colour/juce_FillType.cpp"; sourceTree = "SOURCE_ROOT"; }; - 70EAFCD75DD6A7C1FEBAB94F = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AppleRemote.h"; path = "../../JuceLibraryCode/modules/juce_gui_extra/misc/juce_AppleRemote.h"; sourceTree = "SOURCE_ROOT"; }; - 70F88726C73A6517C14B5E56 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Button.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/buttons/juce_Button.cpp"; sourceTree = "SOURCE_ROOT"; }; - 7161ABCDB705E0F81662DC71 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ApplicationCommandInfo.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/commands/juce_ApplicationCommandInfo.h"; sourceTree = "SOURCE_ROOT"; }; - 716BA2221FA9658AEC00A563 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_SystemAudioVolume.h"; path = "../../JuceLibraryCode/modules/juce_audio_devices/audio_io/juce_SystemAudioVolume.h"; sourceTree = "SOURCE_ROOT"; }; - 72173AE89EE7526AB956CAE8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DrawableImage.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/drawables/juce_DrawableImage.h"; sourceTree = "SOURCE_ROOT"; }; - 72208D4BA50D37B9764FB56A = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_StringRef.h"; path = "../../JuceLibraryCode/modules/juce_core/text/juce_StringRef.h"; sourceTree = "SOURCE_ROOT"; }; - 723111ABC4D02840963C6FC2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ThreadPool.h"; path = "../../JuceLibraryCode/modules/juce_core/threads/juce_ThreadPool.h"; sourceTree = "SOURCE_ROOT"; }; - 729AF566D1EB32D59B8776F7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ScopedReadLock.h"; path = "../../JuceLibraryCode/modules/juce_core/threads/juce_ScopedReadLock.h"; sourceTree = "SOURCE_ROOT"; }; - 72ACB726645A64B055B59277 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Decibels.h"; path = "../../JuceLibraryCode/modules/juce_audio_basics/effects/juce_Decibels.h"; sourceTree = "SOURCE_ROOT"; }; - 72B459EF3E90129FBD1A78EA = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_BufferingAudioFormatReader.h"; path = "../../JuceLibraryCode/modules/juce_audio_formats/format/juce_BufferingAudioFormatReader.h"; sourceTree = "SOURCE_ROOT"; }; - 72CF68A2C3240BFA2EBF22AB = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CharPointer_UTF16.h"; path = "../../JuceLibraryCode/modules/juce_core/text/juce_CharPointer_UTF16.h"; sourceTree = "SOURCE_ROOT"; }; - 730F77EEB7313A110A0B5E5F = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioIODeviceType.h"; path = "../../JuceLibraryCode/modules/juce_audio_devices/audio_io/juce_AudioIODeviceType.h"; sourceTree = "SOURCE_ROOT"; }; - 73237A2CB197259364D09A76 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_PreferencesPanel.h"; path = "../../JuceLibraryCode/modules/juce_gui_extra/misc/juce_PreferencesPanel.h"; sourceTree = "SOURCE_ROOT"; }; + 66E854431C2BBDEE56EA43C8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_VST3PluginFormat.h"; path = "../../../../modules/juce_audio_processors/format_types/juce_VST3PluginFormat.h"; sourceTree = "SOURCE_ROOT"; }; + 673759E656DBA5A9377433E5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_GenericAudioProcessorEditor.cpp"; path = "../../../../modules/juce_audio_processors/processors/juce_GenericAudioProcessorEditor.cpp"; sourceTree = "SOURCE_ROOT"; }; + 674E13DA209E762DF15E9E29 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ResizableCornerComponent.h"; path = "../../../../modules/juce_gui_basics/layout/juce_ResizableCornerComponent.h"; sourceTree = "SOURCE_ROOT"; }; + 67771057800F9416E9777625 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ImagePreviewComponent.h"; path = "../../../../modules/juce_gui_basics/filebrowser/juce_ImagePreviewComponent.h"; sourceTree = "SOURCE_ROOT"; }; + 67895BDE8FA4B2A01E3B8B12 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TargetPlatform.h"; path = "../../../../modules/juce_core/system/juce_TargetPlatform.h"; sourceTree = "SOURCE_ROOT"; }; + 6804336FE1AB499087ACE437 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Initialisation.h"; path = "../../../../modules/juce_events/messages/juce_Initialisation.h"; sourceTree = "SOURCE_ROOT"; }; + 68097881EEDDE0FD03100CC5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_HeapBlock.h"; path = "../../../../modules/juce_core/memory/juce_HeapBlock.h"; sourceTree = "SOURCE_ROOT"; }; + 684E11B1CE018B2C46938D80 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MultiDocumentPanel.cpp"; path = "../../../../modules/juce_gui_basics/layout/juce_MultiDocumentPanel.cpp"; sourceTree = "SOURCE_ROOT"; }; + 68743DE3AA833D6F02F754D7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_TableListBox.cpp"; path = "../../../../modules/juce_gui_basics/widgets/juce_TableListBox.cpp"; sourceTree = "SOURCE_ROOT"; }; + 68FAA921E5D8CFAF9CC07C2F = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_CodeEditorComponent.cpp"; path = "../../../../modules/juce_gui_extra/code_editor/juce_CodeEditorComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; + 6911E01E967839199E4C9822 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Image.h"; path = "../../../../modules/juce_graphics/images/juce_Image.h"; sourceTree = "SOURCE_ROOT"; }; + 693B6DC20214C1ED9C1E89F7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_video.h"; path = "../../../../modules/juce_video/juce_video.h"; sourceTree = "SOURCE_ROOT"; }; + 69449AB58A9C0AB552F754F4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_LookAndFeel_V3.h"; path = "../../../../modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V3.h"; sourceTree = "SOURCE_ROOT"; }; + 69A2DA87D304FD486A872C1B = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ScopedLock.h"; path = "../../../../modules/juce_core/threads/juce_ScopedLock.h"; sourceTree = "SOURCE_ROOT"; }; + 69C36A56AE1A2E8CF64FE388 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CPlusPlusCodeTokeniser.h"; path = "../../../../modules/juce_gui_extra/code_editor/juce_CPlusPlusCodeTokeniser.h"; sourceTree = "SOURCE_ROOT"; }; + 6A1D79062B92685A87BEE5F6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MidiKeyboardState.h"; path = "../../../../modules/juce_audio_basics/midi/juce_MidiKeyboardState.h"; sourceTree = "SOURCE_ROOT"; }; + 6A22C06C6FE2B6B494B4878D = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MACAddress.h"; path = "../../../../modules/juce_core/network/juce_MACAddress.h"; sourceTree = "SOURCE_ROOT"; }; + 6A8AC5E55EE51EE0476D852F = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ComponentPeer.h"; path = "../../../../modules/juce_gui_basics/windows/juce_ComponentPeer.h"; sourceTree = "SOURCE_ROOT"; }; + 6B103C0FB5E6E3618ECD3B48 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_PropertyPanel.cpp"; path = "../../../../modules/juce_gui_basics/properties/juce_PropertyPanel.cpp"; sourceTree = "SOURCE_ROOT"; }; + 6B5C2F14A2268F371F1350B5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OpenGLPixelFormat.h"; path = "../../../../modules/juce_opengl/opengl/juce_OpenGLPixelFormat.h"; sourceTree = "SOURCE_ROOT"; }; + 6BE6A3A14057591A3B4EF2C4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_TextButton.cpp"; path = "../../../../modules/juce_gui_basics/buttons/juce_TextButton.cpp"; sourceTree = "SOURCE_ROOT"; }; + 6C03031AAE5A7C3372D4F1CF = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_GZIPCompressorOutputStream.h"; path = "../../../../modules/juce_core/zip/juce_GZIPCompressorOutputStream.h"; sourceTree = "SOURCE_ROOT"; }; + 6C502DF33FB5C14B8A67B25D = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FileInputSource.cpp"; path = "../../../../modules/juce_core/streams/juce_FileInputSource.cpp"; sourceTree = "SOURCE_ROOT"; }; + 6D0D0EC5B978695152A0B84F = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioSampleBuffer.h"; path = "../../../../modules/juce_audio_basics/buffers/juce_AudioSampleBuffer.h"; sourceTree = "SOURCE_ROOT"; }; + 6D3F3D0139FAC58B2BAA6047 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ConnectedChildProcess.cpp"; path = "../../../../modules/juce_events/interprocess/juce_ConnectedChildProcess.cpp"; sourceTree = "SOURCE_ROOT"; }; + 6D5EE68347208091600E94A2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ResizableEdgeComponent.h"; path = "../../../../modules/juce_gui_basics/layout/juce_ResizableEdgeComponent.h"; sourceTree = "SOURCE_ROOT"; }; + 6DE6751E6A4F0DDE9C7F24B3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TreeView.h"; path = "../../../../modules/juce_gui_basics/widgets/juce_TreeView.h"; sourceTree = "SOURCE_ROOT"; }; + 6E0713769EA84EE0471D9811 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Font.h"; path = "../../../../modules/juce_graphics/fonts/juce_Font.h"; sourceTree = "SOURCE_ROOT"; }; + 6E6672E4055AC4F6D8688310 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioSubsectionReader.h"; path = "../../../../modules/juce_audio_formats/format/juce_AudioSubsectionReader.h"; sourceTree = "SOURCE_ROOT"; }; + 6E841DAA09FE06910D94447D = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_audio_processors.h"; path = "../../../../modules/juce_audio_processors/juce_audio_processors.h"; sourceTree = "SOURCE_ROOT"; }; + 6E9C1F4D69A9C99433DC67C6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DrawableShape.h"; path = "../../../../modules/juce_gui_basics/drawables/juce_DrawableShape.h"; sourceTree = "SOURCE_ROOT"; }; + 6EEECDA2EB328FB597208954 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AbstractFifo.cpp"; path = "../../../../modules/juce_core/containers/juce_AbstractFifo.cpp"; sourceTree = "SOURCE_ROOT"; }; + 6EFC227515CACDE0F8664EC2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_IIRFilterAudioSource.cpp"; path = "../../../../modules/juce_audio_basics/sources/juce_IIRFilterAudioSource.cpp"; sourceTree = "SOURCE_ROOT"; }; + 6F6F888BFFA4BB40DD71285E = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ThreadLocalValue.h"; path = "../../../../modules/juce_core/threads/juce_ThreadLocalValue.h"; sourceTree = "SOURCE_ROOT"; }; + 7022B01ECEE7000DE6008C0A = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_graphics.h"; path = "../../../../modules/juce_graphics/juce_graphics.h"; sourceTree = "SOURCE_ROOT"; }; + 70B18C93C5696330A877B330 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FileSearchPath.cpp"; path = "../../../../modules/juce_core/files/juce_FileSearchPath.cpp"; sourceTree = "SOURCE_ROOT"; }; + 7141B07690C1A022A2BFFBBB = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CompilerSupport.h"; path = "../../../../modules/juce_core/system/juce_CompilerSupport.h"; sourceTree = "SOURCE_ROOT"; }; + 71881F8A6973AACD78ABA719 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_QuickTimeMovieComponent.cpp"; path = "../../../../modules/juce_video/native/juce_win32_QuickTimeMovieComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; + 71B0F66C20CF48F49B3152AF = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_mac_SystemTrayIcon.cpp"; path = "../../../../modules/juce_gui_extra/native/juce_mac_SystemTrayIcon.cpp"; sourceTree = "SOURCE_ROOT"; }; + 71DF518DE7A248B97C8E1C2E = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioSubsectionReader.cpp"; path = "../../../../modules/juce_audio_formats/format/juce_AudioSubsectionReader.cpp"; sourceTree = "SOURCE_ROOT"; }; + 72696E2F6E8EB43A8E604390 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_SelectedItemSet.h"; path = "../../../../modules/juce_gui_basics/mouse/juce_SelectedItemSet.h"; sourceTree = "SOURCE_ROOT"; }; 732EEC584A4CE3ED07C5BEFB = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMIDI.framework; path = System/Library/Frameworks/CoreMIDI.framework; sourceTree = SDKROOT; }; - 7349C82FB18B8E194B854DB8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_Network.cpp"; path = "../../JuceLibraryCode/modules/juce_core/native/juce_linux_Network.cpp"; sourceTree = "SOURCE_ROOT"; }; - 738D2ECFD31190494B40BE78 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Socket.h"; path = "../../JuceLibraryCode/modules/juce_core/network/juce_Socket.h"; sourceTree = "SOURCE_ROOT"; }; - 73CD9E5A889A13890247BA55 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ScopedXLock.h"; path = "../../JuceLibraryCode/modules/juce_events/native/juce_ScopedXLock.h"; sourceTree = "SOURCE_ROOT"; }; - 740CEAD6F3EC74AEE5D29F3A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_ASIO.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_devices/native/juce_win32_ASIO.cpp"; sourceTree = "SOURCE_ROOT"; }; - 747EC1715A027D17F0082830 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_PathStrokeType.cpp"; path = "../../JuceLibraryCode/modules/juce_graphics/geometry/juce_PathStrokeType.cpp"; sourceTree = "SOURCE_ROOT"; }; - 74E4F42C4ECF1C1D2C7873AF = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_module_info"; path = "../../JuceLibraryCode/modules/juce_events/juce_module_info"; sourceTree = "SOURCE_ROOT"; }; - 752E683005CC56CA4A552261 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ScopedWriteLock.h"; path = "../../JuceLibraryCode/modules/juce_core/threads/juce_ScopedWriteLock.h"; sourceTree = "SOURCE_ROOT"; }; - 75CC726CB13BFCCF00F99DF3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FillType.h"; path = "../../JuceLibraryCode/modules/juce_graphics/colour/juce_FillType.h"; sourceTree = "SOURCE_ROOT"; }; - 761FA7CC71FAAE37676425AD = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Label.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/widgets/juce_Label.cpp"; sourceTree = "SOURCE_ROOT"; }; - 7632DB6A2EA67505B1A5B4A8 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_module_info"; path = "../../JuceLibraryCode/modules/juce_opengl/juce_module_info"; sourceTree = "SOURCE_ROOT"; }; - 76CD66265F349446088FD5E3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_SliderPropertyComponent.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/properties/juce_SliderPropertyComponent.h"; sourceTree = "SOURCE_ROOT"; }; - 7760FF1BA004BE4D9CDF1AFA = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ApplicationProperties.cpp"; path = "../../JuceLibraryCode/modules/juce_data_structures/app_properties/juce_ApplicationProperties.cpp"; sourceTree = "SOURCE_ROOT"; }; - 776774969BC27F7269A3B520 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_SHA256.cpp"; path = "../../JuceLibraryCode/modules/juce_cryptography/hashing/juce_SHA256.cpp"; sourceTree = "SOURCE_ROOT"; }; - 778A19A79B821CCE6BD27E12 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DrawableButton.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/buttons/juce_DrawableButton.cpp"; sourceTree = "SOURCE_ROOT"; }; - 77B9644758BED4987CEE2FB9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_HyperlinkButton.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/buttons/juce_HyperlinkButton.h"; sourceTree = "SOURCE_ROOT"; }; - 77EF2BBCC5853A84BB8BB561 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MidiDataConcatenator.h"; path = "../../JuceLibraryCode/modules/juce_audio_devices/native/juce_MidiDataConcatenator.h"; sourceTree = "SOURCE_ROOT"; }; - 77F53EB4FD58030721224396 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_UIViewComponent.h"; path = "../../JuceLibraryCode/modules/juce_gui_extra/embedding/juce_UIViewComponent.h"; sourceTree = "SOURCE_ROOT"; }; - 77FD526A14FAB45DF30CDA71 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_android_Files.cpp"; path = "../../JuceLibraryCode/modules/juce_core/native/juce_android_Files.cpp"; sourceTree = "SOURCE_ROOT"; }; - 78CE05F96C7E21DEE8D6A845 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_AudioUnitPluginFormat.mm"; path = "../../JuceLibraryCode/modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.mm"; sourceTree = "SOURCE_ROOT"; }; - 78D9F913D201ABD1349F023E = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_LiveConstantEditor.h"; path = "../../JuceLibraryCode/modules/juce_gui_extra/misc/juce_LiveConstantEditor.h"; sourceTree = "SOURCE_ROOT"; }; - 78E95B5FD8BFF8B51994F2D8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_WASAPI.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_devices/native/juce_win32_WASAPI.cpp"; sourceTree = "SOURCE_ROOT"; }; - 78FE5E020A7D6EB993701276 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_LADSPAPluginFormat.h"; path = "../../JuceLibraryCode/modules/juce_audio_processors/format_types/juce_LADSPAPluginFormat.h"; sourceTree = "SOURCE_ROOT"; }; - 795EA6840D307165BC0BBCD4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OpenGLPixelFormat.h"; path = "../../JuceLibraryCode/modules/juce_opengl/opengl/juce_OpenGLPixelFormat.h"; sourceTree = "SOURCE_ROOT"; }; - 7A2245EA90D757EED0EBE63A = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MenuBarComponent.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/menus/juce_MenuBarComponent.h"; sourceTree = "SOURCE_ROOT"; }; - 7A6DB25F73AC07158A74D006 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_LowLevelGraphicsContext.h"; path = "../../JuceLibraryCode/modules/juce_graphics/contexts/juce_LowLevelGraphicsContext.h"; sourceTree = "SOURCE_ROOT"; }; - 7AB7CD2C0DB9B58AAA1A4B2F = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ColourSelector.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_extra/misc/juce_ColourSelector.cpp"; sourceTree = "SOURCE_ROOT"; }; - 7B00E4D3D066DFB30406ABCC = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FileListComponent.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/filebrowser/juce_FileListComponent.h"; sourceTree = "SOURCE_ROOT"; }; - 7B849D43BE20E398A8B52F52 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_NSViewComponent.h"; path = "../../JuceLibraryCode/modules/juce_gui_extra/embedding/juce_NSViewComponent.h"; sourceTree = "SOURCE_ROOT"; }; - 7BD61B782DE61C73D8475002 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_LowLevelGraphicsPostScriptRenderer.h"; path = "../../JuceLibraryCode/modules/juce_graphics/contexts/juce_LowLevelGraphicsPostScriptRenderer.h"; sourceTree = "SOURCE_ROOT"; }; - 7C36F478BC80A41544C634C5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ConnectedChildProcess.h"; path = "../../JuceLibraryCode/modules/juce_events/interprocess/juce_ConnectedChildProcess.h"; sourceTree = "SOURCE_ROOT"; }; - 7C4D9BAF8818E5750C110343 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FilePreviewComponent.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/filebrowser/juce_FilePreviewComponent.h"; sourceTree = "SOURCE_ROOT"; }; - 7C91E9B82C9B593E082DD74F = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_BooleanPropertyComponent.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/properties/juce_BooleanPropertyComponent.h"; sourceTree = "SOURCE_ROOT"; }; - 7CE1591D180C957070AE60F6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_SplashScreen.h"; path = "../../JuceLibraryCode/modules/juce_gui_extra/misc/juce_SplashScreen.h"; sourceTree = "SOURCE_ROOT"; }; - 7D81388899A711A7C93107EF = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Desktop.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/components/juce_Desktop.h"; sourceTree = "SOURCE_ROOT"; }; - 7DED484895527D5C0BB6662F = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_CallOutBox.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/windows/juce_CallOutBox.cpp"; sourceTree = "SOURCE_ROOT"; }; + 73CA6BCA313B0239842F298C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ValueTree.h"; path = "../../../../modules/juce_data_structures/values/juce_ValueTree.h"; sourceTree = "SOURCE_ROOT"; }; + 73FF82BCB568578396E88C92 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_WASAPI.cpp"; path = "../../../../modules/juce_audio_devices/native/juce_win32_WASAPI.cpp"; sourceTree = "SOURCE_ROOT"; }; + 74302B51B991EA1775AEFC67 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_core.h"; path = "../../../../modules/juce_core/juce_core.h"; sourceTree = "SOURCE_ROOT"; }; + 749854CD2D13BBBA500F353F = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_PropertySet.cpp"; path = "../../../../modules/juce_core/containers/juce_PropertySet.cpp"; sourceTree = "SOURCE_ROOT"; }; + 74AB51B6E97964B27B1CD019 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Toolbar.cpp"; path = "../../../../modules/juce_gui_basics/widgets/juce_Toolbar.cpp"; sourceTree = "SOURCE_ROOT"; }; + 74B477DE4CFC95E20DBB0D91 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_SystemClipboard.h"; path = "../../../../modules/juce_gui_basics/keyboard/juce_SystemClipboard.h"; sourceTree = "SOURCE_ROOT"; }; + 75D038033B2083D5EFE620A8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Vector3D.h"; path = "../../../../modules/juce_opengl/geometry/juce_Vector3D.h"; sourceTree = "SOURCE_ROOT"; }; + 7627F01C1E5383207D2C0BFB = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_MessageManager.mm"; path = "../../../../modules/juce_events/native/juce_mac_MessageManager.mm"; sourceTree = "SOURCE_ROOT"; }; + 7639526FBF7A4F41961483ED = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_IPAddress.h"; path = "../../../../modules/juce_core/network/juce_IPAddress.h"; sourceTree = "SOURCE_ROOT"; }; + 766EE2CCD4E86729C6CE8112 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DocumentWindow.h"; path = "../../../../modules/juce_gui_basics/windows/juce_DocumentWindow.h"; sourceTree = "SOURCE_ROOT"; }; + 768754211363FED3D2188C9D = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_module_info"; path = "../../../../modules/juce_audio_formats/juce_module_info"; sourceTree = "SOURCE_ROOT"; }; + 76F1A69F15F53D17C632A644 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_RelativeCoordinate.cpp"; path = "../../../../modules/juce_gui_basics/positioning/juce_RelativeCoordinate.cpp"; sourceTree = "SOURCE_ROOT"; }; + 7743414F79908801328D9F03 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_TimeSliceThread.cpp"; path = "../../../../modules/juce_core/threads/juce_TimeSliceThread.cpp"; sourceTree = "SOURCE_ROOT"; }; + 77AE8FD7436387126D3BBBAC = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_KeyMappingEditorComponent.cpp"; path = "../../../../modules/juce_gui_extra/misc/juce_KeyMappingEditorComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; + 782E3434FEA190A986EAC816 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ArrowButton.cpp"; path = "../../../../modules/juce_gui_basics/buttons/juce_ArrowButton.cpp"; sourceTree = "SOURCE_ROOT"; }; + 791ADFB0FFAEE65058B6FC8A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ApplicationCommandInfo.cpp"; path = "../../../../modules/juce_gui_basics/commands/juce_ApplicationCommandInfo.cpp"; sourceTree = "SOURCE_ROOT"; }; + 799472026100D7BAE015F6A6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AnimatedPositionBehaviours.h"; path = "../../../../modules/juce_gui_basics/layout/juce_AnimatedPositionBehaviours.h"; sourceTree = "SOURCE_ROOT"; }; + 7A029D97E723C7F1BDDCAA49 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MultiTimer.cpp"; path = "../../../../modules/juce_events/timers/juce_MultiTimer.cpp"; sourceTree = "SOURCE_ROOT"; }; + 7A46778023CF61B3F417F9AC = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioDataConverters.h"; path = "../../../../modules/juce_audio_basics/buffers/juce_AudioDataConverters.h"; sourceTree = "SOURCE_ROOT"; }; + 7A6E1CBA343C07AC187A3EE8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ComponentAnimator.h"; path = "../../../../modules/juce_gui_basics/layout/juce_ComponentAnimator.h"; sourceTree = "SOURCE_ROOT"; }; + 7AC4D7A22EE9E1F4FBD407C7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MidiDataConcatenator.h"; path = "../../../../modules/juce_audio_devices/native/juce_MidiDataConcatenator.h"; sourceTree = "SOURCE_ROOT"; }; + 7AC8C094442A603DE6257BB1 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CharPointer_UTF8.h"; path = "../../../../modules/juce_core/text/juce_CharPointer_UTF8.h"; sourceTree = "SOURCE_ROOT"; }; + 7BA2EA5655704E5358ABAA9D = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_RectanglePlacement.cpp"; path = "../../../../modules/juce_graphics/placement/juce_RectanglePlacement.cpp"; sourceTree = "SOURCE_ROOT"; }; + 7BC8F7015F35BAFF4AEDA0E6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Toolbar.h"; path = "../../../../modules/juce_gui_basics/widgets/juce_Toolbar.h"; sourceTree = "SOURCE_ROOT"; }; + 7C7B6D8D155687966F681F5B = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_module_info"; path = "../../../../modules/juce_events/juce_module_info"; sourceTree = "SOURCE_ROOT"; }; + 7D8D285B8414388FDB083AFF = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ProgressBar.h"; path = "../../../../modules/juce_gui_basics/widgets/juce_ProgressBar.h"; sourceTree = "SOURCE_ROOT"; }; + 7DCF49E37B27971A7E597555 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_Registry.cpp"; path = "../../../../modules/juce_core/native/juce_win32_Registry.cpp"; sourceTree = "SOURCE_ROOT"; }; 7DF561FC0400DD7E678CD690 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; }; - 7E62DD6F1A2FF13D5095D218 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_SystemStats.mm"; path = "../../JuceLibraryCode/modules/juce_core/native/juce_mac_SystemStats.mm"; sourceTree = "SOURCE_ROOT"; }; + 7E0DD06926DAC8EE93BD4F08 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FileInputSource.h"; path = "../../../../modules/juce_core/streams/juce_FileInputSource.h"; sourceTree = "SOURCE_ROOT"; }; 7E8B563CE147A7C733E6EFB1 = {isa = PBXFileReference; lastKnownFileType = file.nib; name = RecentFilesMenuTemplate.nib; path = RecentFilesMenuTemplate.nib; sourceTree = "SOURCE_ROOT"; }; - 7EA85C6C405022532A6F2F3A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_RecentlyOpenedFilesList.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_extra/misc/juce_RecentlyOpenedFilesList.cpp"; sourceTree = "SOURCE_ROOT"; }; - 7EA9B430B1998ECBEF70D2E2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Identifier.cpp"; path = "../../JuceLibraryCode/modules/juce_core/text/juce_Identifier.cpp"; sourceTree = "SOURCE_ROOT"; }; - 7EDB44744DC44FB9DDECF9FF = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_OpenGLFrameBuffer.cpp"; path = "../../JuceLibraryCode/modules/juce_opengl/opengl/juce_OpenGLFrameBuffer.cpp"; sourceTree = "SOURCE_ROOT"; }; - 7F5AF8186ABA8353EC1D4A24 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ListenerList.h"; path = "../../JuceLibraryCode/modules/juce_events/broadcasters/juce_ListenerList.h"; sourceTree = "SOURCE_ROOT"; }; - 7F6B22405102D9B38BE6E113 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_RelativeRectangle.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/positioning/juce_RelativeRectangle.cpp"; sourceTree = "SOURCE_ROOT"; }; - 7F7C09BE9B70312CE6783717 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_Windowing.mm"; path = "../../JuceLibraryCode/modules/juce_gui_basics/native/juce_mac_Windowing.mm"; sourceTree = "SOURCE_ROOT"; }; - 7FB3628856C8E532EB8421CA = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_core.mm"; path = "../../JuceLibraryCode/modules/juce_core/juce_core.mm"; sourceTree = "SOURCE_ROOT"; }; - 7FCD0EF5D09B904A6D437BC9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_BubbleComponent.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/misc/juce_BubbleComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; - 80C52BD7C8AD60FC1584EDDD = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_BigInteger.h"; path = "../../JuceLibraryCode/modules/juce_core/maths/juce_BigInteger.h"; sourceTree = "SOURCE_ROOT"; }; - 81CF3953D1337AD42C542403 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_module_info"; path = "../../JuceLibraryCode/modules/juce_cryptography/juce_module_info"; sourceTree = "SOURCE_ROOT"; }; - 81EE8DCD7B8BB528C9989B47 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MarkerList.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/positioning/juce_MarkerList.h"; sourceTree = "SOURCE_ROOT"; }; - 82D0CF4B57D906FAEBC60666 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_Fonts.cpp"; path = "../../JuceLibraryCode/modules/juce_graphics/native/juce_win32_Fonts.cpp"; sourceTree = "SOURCE_ROOT"; }; - 82E3A19B4D8BA65CE7310D09 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ApplicationCommandInfo.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/commands/juce_ApplicationCommandInfo.cpp"; sourceTree = "SOURCE_ROOT"; }; - 836E25356E7C3A2534792936 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_SystemTrayIconComponent.h"; path = "../../JuceLibraryCode/modules/juce_gui_extra/misc/juce_SystemTrayIconComponent.h"; sourceTree = "SOURCE_ROOT"; }; - 83A10FEA76D527B4E88AD0EF = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_LagrangeInterpolator.h"; path = "../../JuceLibraryCode/modules/juce_audio_basics/effects/juce_LagrangeInterpolator.h"; sourceTree = "SOURCE_ROOT"; }; - 83AF4F43D85DCDBF318BEC8B = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Colour.h"; path = "../../JuceLibraryCode/modules/juce_graphics/colour/juce_Colour.h"; sourceTree = "SOURCE_ROOT"; }; - 83B04EFF25DA63BE3DA37B11 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ComponentAnimator.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/layout/juce_ComponentAnimator.cpp"; sourceTree = "SOURCE_ROOT"; }; - 8438D37046A9F805AAC7401B = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_android_JNIHelpers.h"; path = "../../JuceLibraryCode/modules/juce_core/native/juce_android_JNIHelpers.h"; sourceTree = "SOURCE_ROOT"; }; - 844583A4973FA34A3FF6DCB5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Initialisation.h"; path = "../../JuceLibraryCode/modules/juce_events/messages/juce_Initialisation.h"; sourceTree = "SOURCE_ROOT"; }; - 849A271BDBC9A7AB9514B8CD = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_VSTMidiEventList.h"; path = "../../JuceLibraryCode/modules/juce_audio_processors/format_types/juce_VSTMidiEventList.h"; sourceTree = "SOURCE_ROOT"; }; + 7EB8C7E000F0DDAAB4F47802 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_NSViewComponentPeer.mm"; path = "../../../../modules/juce_gui_basics/native/juce_mac_NSViewComponentPeer.mm"; sourceTree = "SOURCE_ROOT"; }; + 7F0614F4F47EB171B8476BDC = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ComponentBoundsConstrainer.cpp"; path = "../../../../modules/juce_gui_basics/layout/juce_ComponentBoundsConstrainer.cpp"; sourceTree = "SOURCE_ROOT"; }; + 7F162E198ECF41AA895DB94B = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AiffAudioFormat.h"; path = "../../../../modules/juce_audio_formats/codecs/juce_AiffAudioFormat.h"; sourceTree = "SOURCE_ROOT"; }; + 7F171BE6BFAA1E3E2A9BED61 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ComponentMovementWatcher.h"; path = "../../../../modules/juce_gui_basics/layout/juce_ComponentMovementWatcher.h"; sourceTree = "SOURCE_ROOT"; }; + 7F2BBAF79EB32BB9904A76FF = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Timer.h"; path = "../../../../modules/juce_events/timers/juce_Timer.h"; sourceTree = "SOURCE_ROOT"; }; + 7FC89C1EEB42DE3C9628591C = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_SliderPropertyComponent.cpp"; path = "../../../../modules/juce_gui_basics/properties/juce_SliderPropertyComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; + 8001506F637B2516AAC5C0D8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ModalComponentManager.cpp"; path = "../../../../modules/juce_gui_basics/components/juce_ModalComponentManager.cpp"; sourceTree = "SOURCE_ROOT"; }; + 803480FD5E7181E0D64FFC53 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OutputStream.h"; path = "../../../../modules/juce_core/streams/juce_OutputStream.h"; sourceTree = "SOURCE_ROOT"; }; + 805EB95DB4B8045064CE9ED3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_android_WebBrowserComponent.cpp"; path = "../../../../modules/juce_gui_extra/native/juce_android_WebBrowserComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; + 805F27CEEC53F4E659884D7A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_ASIO.cpp"; path = "../../../../modules/juce_audio_devices/native/juce_win32_ASIO.cpp"; sourceTree = "SOURCE_ROOT"; }; + 807E7971CB75C806D7DB5DF2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_RelativeRectangle.h"; path = "../../../../modules/juce_gui_basics/positioning/juce_RelativeRectangle.h"; sourceTree = "SOURCE_ROOT"; }; + 8102EBF90140E78193692AEB = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DragAndDropContainer.h"; path = "../../../../modules/juce_gui_basics/mouse/juce_DragAndDropContainer.h"; sourceTree = "SOURCE_ROOT"; }; + 814E0D982BC2A18B9BAF3E38 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioSourcePlayer.cpp"; path = "../../../../modules/juce_audio_devices/sources/juce_AudioSourcePlayer.cpp"; sourceTree = "SOURCE_ROOT"; }; + 823BBAE97A02475F25E54F9D = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_BasicNativeHeaders.h"; path = "../../../../modules/juce_core/native/juce_BasicNativeHeaders.h"; sourceTree = "SOURCE_ROOT"; }; + 82A390DEE5A3B2EFDF7A65E6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ResizableCornerComponent.cpp"; path = "../../../../modules/juce_gui_basics/layout/juce_ResizableCornerComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; + 830ADB6740EF70992E71895F = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FilePreviewComponent.h"; path = "../../../../modules/juce_gui_basics/filebrowser/juce_FilePreviewComponent.h"; sourceTree = "SOURCE_ROOT"; }; + 8314FE695F91DA2FAB51920E = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AlertWindow.cpp"; path = "../../../../modules/juce_gui_basics/windows/juce_AlertWindow.cpp"; sourceTree = "SOURCE_ROOT"; }; + 83325A69170997E33D73770A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioPluginFormatManager.cpp"; path = "../../../../modules/juce_audio_processors/format/juce_AudioPluginFormatManager.cpp"; sourceTree = "SOURCE_ROOT"; }; + 833CD270A139A70FF4E60D35 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MouseEvent.cpp"; path = "../../../../modules/juce_gui_basics/mouse/juce_MouseEvent.cpp"; sourceTree = "SOURCE_ROOT"; }; + 83BA5BED925F6F827DF98CA8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_PositionableAudioSource.h"; path = "../../../../modules/juce_audio_basics/sources/juce_PositionableAudioSource.h"; sourceTree = "SOURCE_ROOT"; }; + 842433A42308565BF3C1542A = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TextEditor.h"; path = "../../../../modules/juce_gui_basics/widgets/juce_TextEditor.h"; sourceTree = "SOURCE_ROOT"; }; + 843BE36A2285F73A3FBB5660 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_SystemStats.cpp"; path = "../../../../modules/juce_core/native/juce_win32_SystemStats.cpp"; sourceTree = "SOURCE_ROOT"; }; + 84494501A6148DAFE162650B = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_posix_SharedCode.h"; path = "../../../../modules/juce_core/native/juce_posix_SharedCode.h"; sourceTree = "SOURCE_ROOT"; }; + 84ABA9491A70313AD6BF6F9A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MACAddress.cpp"; path = "../../../../modules/juce_core/network/juce_MACAddress.cpp"; sourceTree = "SOURCE_ROOT"; }; + 853D2D1ADD05C320052DD5FC = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioFormatReaderSource.cpp"; path = "../../../../modules/juce_audio_formats/format/juce_AudioFormatReaderSource.cpp"; sourceTree = "SOURCE_ROOT"; }; 859E13C66F2193112084D1B9 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Accelerate.framework; path = System/Library/Frameworks/Accelerate.framework; sourceTree = SDKROOT; }; - 85A0EF72EC932C8A327F8139 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Viewport.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/layout/juce_Viewport.cpp"; sourceTree = "SOURCE_ROOT"; }; - 86318DF533A7BB50B88789BC = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_PropertyComponent.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/properties/juce_PropertyComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; - 8669589118EF641C93336C4B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_OpenGLHelpers.cpp"; path = "../../JuceLibraryCode/modules/juce_opengl/opengl/juce_OpenGLHelpers.cpp"; sourceTree = "SOURCE_ROOT"; }; - 8755EB7CFA4EC3C0AEBF8E26 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_WeakReference.h"; path = "../../JuceLibraryCode/modules/juce_core/memory/juce_WeakReference.h"; sourceTree = "SOURCE_ROOT"; }; - 88046B20D38387F2D2650F8D = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ChangeBroadcaster.cpp"; path = "../../JuceLibraryCode/modules/juce_events/broadcasters/juce_ChangeBroadcaster.cpp"; sourceTree = "SOURCE_ROOT"; }; - 8854EAFDD3B68BC78E0A1F89 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_data_structures.h"; path = "../../JuceLibraryCode/modules/juce_data_structures/juce_data_structures.h"; sourceTree = "SOURCE_ROOT"; }; - 88A8541D309794713923E3D1 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Typeface.cpp"; path = "../../JuceLibraryCode/modules/juce_graphics/fonts/juce_Typeface.cpp"; sourceTree = "SOURCE_ROOT"; }; - 88D72DB7B94A70CD9EE18440 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Colours.h"; path = "../../JuceLibraryCode/modules/juce_graphics/colour/juce_Colours.h"; sourceTree = "SOURCE_ROOT"; }; - 8910FF4F64E6AFD721B91B0D = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_OpenGLImage.cpp"; path = "../../JuceLibraryCode/modules/juce_opengl/opengl/juce_OpenGLImage.cpp"; sourceTree = "SOURCE_ROOT"; }; - 8AC4AFECD0028680DA96CFEE = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_DirectWriteTypeface.cpp"; path = "../../JuceLibraryCode/modules/juce_graphics/native/juce_win32_DirectWriteTypeface.cpp"; sourceTree = "SOURCE_ROOT"; }; - 8AD5A845BBCF5ED0E6AA5922 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_StringPairArray.cpp"; path = "../../JuceLibraryCode/modules/juce_core/text/juce_StringPairArray.cpp"; sourceTree = "SOURCE_ROOT"; }; - 8B28654FCB4605697C82637F = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ImageComponent.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/widgets/juce_ImageComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; - 8BB79E37A824F6CBBB7A97D9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_TextButton.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/buttons/juce_TextButton.cpp"; sourceTree = "SOURCE_ROOT"; }; - 8CAF2B1BDF49EC845F183218 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_WindowsMediaAudioFormat.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_formats/codecs/juce_WindowsMediaAudioFormat.cpp"; sourceTree = "SOURCE_ROOT"; }; - 8CD45DADF91984C72DAE7E09 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_BufferingAudioSource.h"; path = "../../JuceLibraryCode/modules/juce_audio_basics/sources/juce_BufferingAudioSource.h"; sourceTree = "SOURCE_ROOT"; }; - 8D4E99621AAEBA39CCA68C41 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MessageListener.h"; path = "../../JuceLibraryCode/modules/juce_events/messages/juce_MessageListener.h"; sourceTree = "SOURCE_ROOT"; }; - 8D9A85AC7668D98160EC607E = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_android_FileChooser.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/native/juce_android_FileChooser.cpp"; sourceTree = "SOURCE_ROOT"; }; - 8DC8057B78772BA17A3ADDD1 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioFormatWriter.h"; path = "../../JuceLibraryCode/modules/juce_audio_formats/format/juce_AudioFormatWriter.h"; sourceTree = "SOURCE_ROOT"; }; - 8E6D1C56F3FAC7B249F2582B = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_PropertyComponent.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/properties/juce_PropertyComponent.h"; sourceTree = "SOURCE_ROOT"; }; - 8E6D4E8672ADAA47FF421180 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ReferenceCountedObject.h"; path = "../../JuceLibraryCode/modules/juce_core/memory/juce_ReferenceCountedObject.h"; sourceTree = "SOURCE_ROOT"; }; - 8EA752855DD7BA2C1CEFF9D4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_RelativeCoordinate.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/positioning/juce_RelativeCoordinate.h"; sourceTree = "SOURCE_ROOT"; }; - 8F0BDEECFD7200A7BE6FC598 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Range.h"; path = "../../JuceLibraryCode/modules/juce_core/maths/juce_Range.h"; sourceTree = "SOURCE_ROOT"; }; - 8F3E6744F26B7BAA554F4E41 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_android_SystemStats.cpp"; path = "../../JuceLibraryCode/modules/juce_core/native/juce_android_SystemStats.cpp"; sourceTree = "SOURCE_ROOT"; }; - 8F69B5117A8AB4D95316FBAC = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ArrowButton.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/buttons/juce_ArrowButton.cpp"; sourceTree = "SOURCE_ROOT"; }; + 8632589E0C21E3B0A5DA0333 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FileBasedDocument.h"; path = "../../../../modules/juce_gui_extra/documents/juce_FileBasedDocument.h"; sourceTree = "SOURCE_ROOT"; }; + 8683CDE5FD2DFCB2CFC8F410 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_TooltipWindow.cpp"; path = "../../../../modules/juce_gui_basics/windows/juce_TooltipWindow.cpp"; sourceTree = "SOURCE_ROOT"; }; + 868955327EBBD0C2C2447DB3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ApplicationBase.h"; path = "../../../../modules/juce_events/messages/juce_ApplicationBase.h"; sourceTree = "SOURCE_ROOT"; }; + 8741126A9694372E46E3FD32 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioPluginFormat.cpp"; path = "../../../../modules/juce_audio_processors/format/juce_AudioPluginFormat.cpp"; sourceTree = "SOURCE_ROOT"; }; + 877ED7656241F46291022910 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OpenGLExtensions.h"; path = "../../../../modules/juce_opengl/native/juce_OpenGLExtensions.h"; sourceTree = "SOURCE_ROOT"; }; + 87E61959D8EA529461A0D257 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_android_CameraDevice.cpp"; path = "../../../../modules/juce_video/native/juce_android_CameraDevice.cpp"; sourceTree = "SOURCE_ROOT"; }; + 87EDBC629357F63AB8E7B507 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FileOutputStream.cpp"; path = "../../../../modules/juce_core/files/juce_FileOutputStream.cpp"; sourceTree = "SOURCE_ROOT"; }; + 884AA1209A726AEAF76E31B0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioDeviceManager.cpp"; path = "../../../../modules/juce_audio_devices/audio_io/juce_AudioDeviceManager.cpp"; sourceTree = "SOURCE_ROOT"; }; + 8866CF798E9F84C49B9D7DCC = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_android_Windowing.cpp"; path = "../../../../modules/juce_gui_basics/native/juce_android_Windowing.cpp"; sourceTree = "SOURCE_ROOT"; }; + 88CC8BC2EA8CDB378A03FADA = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_android_Messaging.cpp"; path = "../../../../modules/juce_events/native/juce_android_Messaging.cpp"; sourceTree = "SOURCE_ROOT"; }; + 88EF4C8D3A1D2498D8ADB6E0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_PluginListComponent.h"; path = "../../../../modules/juce_audio_processors/scanning/juce_PluginListComponent.h"; sourceTree = "SOURCE_ROOT"; }; + 8945894D17A9407EEEE3B8BD = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MemoryOutputStream.h"; path = "../../../../modules/juce_core/streams/juce_MemoryOutputStream.h"; sourceTree = "SOURCE_ROOT"; }; + 897B10399D1CA882B5B98D0F = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ThreadPool.h"; path = "../../../../modules/juce_core/threads/juce_ThreadPool.h"; sourceTree = "SOURCE_ROOT"; }; + 897C7B6FB012647ED8AB5D05 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_WebBrowserComponent.h"; path = "../../../../modules/juce_gui_extra/misc/juce_WebBrowserComponent.h"; sourceTree = "SOURCE_ROOT"; }; + 89ACAEA951C470AF8683AABD = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CPlusPlusCodeTokeniserFunctions.h"; path = "../../../../modules/juce_gui_extra/code_editor/juce_CPlusPlusCodeTokeniserFunctions.h"; sourceTree = "SOURCE_ROOT"; }; + 89CBCB2D4660B56C1A939011 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_Messaging.cpp"; path = "../../../../modules/juce_events/native/juce_linux_Messaging.cpp"; sourceTree = "SOURCE_ROOT"; }; + 89F5A5C12916F02E579D6394 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ComponentDragger.cpp"; path = "../../../../modules/juce_gui_basics/mouse/juce_ComponentDragger.cpp"; sourceTree = "SOURCE_ROOT"; }; + 8A4A25946040DED54DB8F3B1 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ColourGradient.h"; path = "../../../../modules/juce_graphics/colour/juce_ColourGradient.h"; sourceTree = "SOURCE_ROOT"; }; + 8B155ED74D3D0EB7E890E421 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_IIRFilterAudioSource.h"; path = "../../../../modules/juce_audio_basics/sources/juce_IIRFilterAudioSource.h"; sourceTree = "SOURCE_ROOT"; }; + 8B539DB72CC92EEC7F96C8E6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TooltipClient.h"; path = "../../../../modules/juce_gui_basics/mouse/juce_TooltipClient.h"; sourceTree = "SOURCE_ROOT"; }; + 8B7C0F839098C534A7B4C725 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Random.cpp"; path = "../../../../modules/juce_core/maths/juce_Random.cpp"; sourceTree = "SOURCE_ROOT"; }; + 8BE44C96A60C5D9B9F503409 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DrawableShape.cpp"; path = "../../../../modules/juce_gui_basics/drawables/juce_DrawableShape.cpp"; sourceTree = "SOURCE_ROOT"; }; + 8C105487633A9BD04FDEE50A = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Synthesiser.h"; path = "../../../../modules/juce_audio_basics/synthesisers/juce_Synthesiser.h"; sourceTree = "SOURCE_ROOT"; }; + 8C24F74CB23F1B82C80386FF = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_android_Network.cpp"; path = "../../../../modules/juce_core/native/juce_android_Network.cpp"; sourceTree = "SOURCE_ROOT"; }; + 8C3A6351780E678334FA1406 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_NamedPipe.h"; path = "../../../../modules/juce_core/network/juce_NamedPipe.h"; sourceTree = "SOURCE_ROOT"; }; + 8C547C48DD5B3A854DBFF0F3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MessageManager.cpp"; path = "../../../../modules/juce_events/messages/juce_MessageManager.cpp"; sourceTree = "SOURCE_ROOT"; }; + 8C6A342773288620A8CC2598 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MemoryBlock.cpp"; path = "../../../../modules/juce_core/memory/juce_MemoryBlock.cpp"; sourceTree = "SOURCE_ROOT"; }; + 8C9D252ABA3CDDC81B33884D = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_TabbedButtonBar.cpp"; path = "../../../../modules/juce_gui_basics/layout/juce_TabbedButtonBar.cpp"; sourceTree = "SOURCE_ROOT"; }; + 8C9EC3F9C24081ECEF3FCEFD = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_TabbedComponent.cpp"; path = "../../../../modules/juce_gui_basics/layout/juce_TabbedComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; + 8CA01F9530AC5512C6B74325 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MidiMessage.cpp"; path = "../../../../modules/juce_audio_basics/midi/juce_MidiMessage.cpp"; sourceTree = "SOURCE_ROOT"; }; + 8D3FB0417A39CAEC03D44D73 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_module_info"; path = "../../../../modules/juce_opengl/juce_module_info"; sourceTree = "SOURCE_ROOT"; }; + 8DC827CCF543708CF729FED6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MidiFile.cpp"; path = "../../../../modules/juce_audio_basics/midi/juce_MidiFile.cpp"; sourceTree = "SOURCE_ROOT"; }; + 8DE969191661B557B4222D50 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MouseInactivityDetector.h"; path = "../../../../modules/juce_gui_basics/mouse/juce_MouseInactivityDetector.h"; sourceTree = "SOURCE_ROOT"; }; + 8DEFACA6858D254B4202AF12 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_module_info"; path = "../../../../modules/juce_audio_basics/juce_module_info"; sourceTree = "SOURCE_ROOT"; }; + 8E407C1CF739A93FD2B3B38C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CharPointer_ASCII.h"; path = "../../../../modules/juce_core/text/juce_CharPointer_ASCII.h"; sourceTree = "SOURCE_ROOT"; }; + 8E95A3B7C194244B92D5D65A = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_NativeMessageBox.h"; path = "../../../../modules/juce_gui_basics/windows/juce_NativeMessageBox.h"; sourceTree = "SOURCE_ROOT"; }; + 8EA18CA66CABC9B5087DBDD2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_freetype_Fonts.cpp"; path = "../../../../modules/juce_graphics/native/juce_freetype_Fonts.cpp"; sourceTree = "SOURCE_ROOT"; }; + 8EDD1755AEE1C95660A06BF2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MidiMessageSequence.h"; path = "../../../../modules/juce_audio_basics/midi/juce_MidiMessageSequence.h"; sourceTree = "SOURCE_ROOT"; }; + 8EFB4EBA0836D5401B6D3DFB = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_KeyListener.h"; path = "../../../../modules/juce_gui_basics/keyboard/juce_KeyListener.h"; sourceTree = "SOURCE_ROOT"; }; 8F7B1F20EA4F07C9D37D5260 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = System/Library/Frameworks/Carbon.framework; sourceTree = SDKROOT; }; - 8F8C1B89ADC4FF3D985E4444 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_android_Messaging.cpp"; path = "../../JuceLibraryCode/modules/juce_events/native/juce_android_Messaging.cpp"; sourceTree = "SOURCE_ROOT"; }; - 8F95ADADC0B19BF9D77D1A01 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CachedComponentImage.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/components/juce_CachedComponentImage.h"; sourceTree = "SOURCE_ROOT"; }; - 8FE90269A3BD4CDE641C5847 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_module_info"; path = "../../JuceLibraryCode/modules/juce_video/juce_module_info"; sourceTree = "SOURCE_ROOT"; }; - 90E607BA3727A053395D2A61 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_IIRFilter.h"; path = "../../JuceLibraryCode/modules/juce_audio_basics/effects/juce_IIRFilter.h"; sourceTree = "SOURCE_ROOT"; }; - 90E99C139FF6443FAABA2729 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_MainMenu.mm"; path = "../../JuceLibraryCode/modules/juce_gui_basics/native/juce_mac_MainMenu.mm"; sourceTree = "SOURCE_ROOT"; }; - 92800D0F94BA509EF80613A0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_WebBrowserComponent.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_extra/native/juce_win32_WebBrowserComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; - 92901C506127F45E3F5B258E = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_PropertySet.h"; path = "../../JuceLibraryCode/modules/juce_core/containers/juce_PropertySet.h"; sourceTree = "SOURCE_ROOT"; }; - 92EE84597D647B6CE0CBD4FE = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_LookAndFeel_V3.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V3.h"; sourceTree = "SOURCE_ROOT"; }; - 933A312B0B63B032495B06C1 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Matrix3D.h"; path = "../../JuceLibraryCode/modules/juce_opengl/geometry/juce_Matrix3D.h"; sourceTree = "SOURCE_ROOT"; }; - 940BD46F150595E60976C487 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ActionBroadcaster.h"; path = "../../JuceLibraryCode/modules/juce_events/broadcasters/juce_ActionBroadcaster.h"; sourceTree = "SOURCE_ROOT"; }; - 9444AB597C118C99704EFDF8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Uuid.cpp"; path = "../../JuceLibraryCode/modules/juce_core/misc/juce_Uuid.cpp"; sourceTree = "SOURCE_ROOT"; }; - 94614BC3AAA7263B1D6BDAE7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_SystemTrayIcon.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_extra/native/juce_win32_SystemTrayIcon.cpp"; sourceTree = "SOURCE_ROOT"; }; - 94B52728DAAC5E3BADD03617 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_InputStream.h"; path = "../../JuceLibraryCode/modules/juce_core/streams/juce_InputStream.h"; sourceTree = "SOURCE_ROOT"; }; - 94B8132DD5915F30ED7DD249 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioPluginInstance.h"; path = "../../JuceLibraryCode/modules/juce_audio_processors/processors/juce_AudioPluginInstance.h"; sourceTree = "SOURCE_ROOT"; }; - 95244870E8E9CC3CC6FF33C7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_IPAddress.cpp"; path = "../../JuceLibraryCode/modules/juce_core/network/juce_IPAddress.cpp"; sourceTree = "SOURCE_ROOT"; }; - 9533D4846543EF2F80E7B561 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Draggable3DOrientation.h"; path = "../../JuceLibraryCode/modules/juce_opengl/geometry/juce_Draggable3DOrientation.h"; sourceTree = "SOURCE_ROOT"; }; - 95446442AB833FA3CAF0D949 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FileSearchPathListComponent.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/filebrowser/juce_FileSearchPathListComponent.h"; sourceTree = "SOURCE_ROOT"; }; - 9563B07A9E53D5FFE868F8BE = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_KeyListener.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/keyboard/juce_KeyListener.cpp"; sourceTree = "SOURCE_ROOT"; }; - 95A59141DCE1349CC649FDB2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ScopedValueSetter.h"; path = "../../JuceLibraryCode/modules/juce_core/containers/juce_ScopedValueSetter.h"; sourceTree = "SOURCE_ROOT"; }; - 9613BC80734D26E200E5CE1F = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_LookAndFeel_V1.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V1.h"; sourceTree = "SOURCE_ROOT"; }; - 968B7B6F9C111B514327A382 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Thread.h"; path = "../../JuceLibraryCode/modules/juce_core/threads/juce_Thread.h"; sourceTree = "SOURCE_ROOT"; }; - 96CE2C991445A3994E1FBCB0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ModifierKeys.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/keyboard/juce_ModifierKeys.cpp"; sourceTree = "SOURCE_ROOT"; }; - 96E6A79B5BBBF580E0E11FF6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ToggleButton.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/buttons/juce_ToggleButton.h"; sourceTree = "SOURCE_ROOT"; }; - 971D7A721F741E81AACBDBDA = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Timer.cpp"; path = "../../JuceLibraryCode/modules/juce_events/timers/juce_Timer.cpp"; sourceTree = "SOURCE_ROOT"; }; - 97984A6B910D0D4B48EFB82B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioFormatWriter.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_formats/format/juce_AudioFormatWriter.cpp"; sourceTree = "SOURCE_ROOT"; }; - 97B99BA54C40DB3348086461 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MemoryInputStream.h"; path = "../../JuceLibraryCode/modules/juce_core/streams/juce_MemoryInputStream.h"; sourceTree = "SOURCE_ROOT"; }; - 97BB0621A58441872B96D1EC = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_LassoComponent.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/mouse/juce_LassoComponent.h"; sourceTree = "SOURCE_ROOT"; }; - 97E51A159B596325E90C5BE9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_PluginDirectoryScanner.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_processors/scanning/juce_PluginDirectoryScanner.cpp"; sourceTree = "SOURCE_ROOT"; }; - 97F9A1E6E51FB3D918EC3174 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DrawableText.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/drawables/juce_DrawableText.cpp"; sourceTree = "SOURCE_ROOT"; }; - 980A1CBA9A6D4B421BEB00F7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MountedVolumeListChangeDetector.h"; path = "../../JuceLibraryCode/modules/juce_events/messages/juce_MountedVolumeListChangeDetector.h"; sourceTree = "SOURCE_ROOT"; }; - 98297330C67DF9D0059606DF = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Point.h"; path = "../../JuceLibraryCode/modules/juce_graphics/geometry/juce_Point.h"; sourceTree = "SOURCE_ROOT"; }; - 983D92711EC4B001DEF300DF = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MemoryBlock.h"; path = "../../JuceLibraryCode/modules/juce_core/memory/juce_MemoryBlock.h"; sourceTree = "SOURCE_ROOT"; }; - 9846C2445B7D6E79A66630F9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_GlowEffect.h"; path = "../../JuceLibraryCode/modules/juce_graphics/effects/juce_GlowEffect.h"; sourceTree = "SOURCE_ROOT"; }; - 98594F6F68633ABB8DB9A488 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_PopupMenu.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/menus/juce_PopupMenu.cpp"; sourceTree = "SOURCE_ROOT"; }; - 98622ABC34EA3DD4334580D5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Sampler.h"; path = "../../JuceLibraryCode/modules/juce_audio_formats/sampler/juce_Sampler.h"; sourceTree = "SOURCE_ROOT"; }; - 9871D03E9A1E28B247352407 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ComboBox.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/widgets/juce_ComboBox.cpp"; sourceTree = "SOURCE_ROOT"; }; - 987E21587B07462F5098831E = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Uuid.h"; path = "../../JuceLibraryCode/modules/juce_core/misc/juce_Uuid.h"; sourceTree = "SOURCE_ROOT"; }; - 9898BBBC81128203FC3934B7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioCDBurner.h"; path = "../../JuceLibraryCode/modules/juce_audio_devices/audio_cd/juce_AudioCDBurner.h"; sourceTree = "SOURCE_ROOT"; }; - 98ED7C529B2A40AA4C0527DD = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DynamicObject.cpp"; path = "../../JuceLibraryCode/modules/juce_core/containers/juce_DynamicObject.cpp"; sourceTree = "SOURCE_ROOT"; }; - 98FBBFD68CCC9D52B62BFFEE = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_video.mm"; path = "../../JuceLibraryCode/modules/juce_video/juce_video.mm"; sourceTree = "SOURCE_ROOT"; }; - 991BB887EC327D340E5AA659 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Primes.h"; path = "../../JuceLibraryCode/modules/juce_cryptography/encryption/juce_Primes.h"; sourceTree = "SOURCE_ROOT"; }; - 995501A12A56DED7CDAAF24B = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioProcessorListener.h"; path = "../../JuceLibraryCode/modules/juce_audio_processors/processors/juce_AudioProcessorListener.h"; sourceTree = "SOURCE_ROOT"; }; - 9980F9FB908ED20591475FA8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CharPointer_ASCII.h"; path = "../../JuceLibraryCode/modules/juce_core/text/juce_CharPointer_ASCII.h"; sourceTree = "SOURCE_ROOT"; }; - 9A160557777085A813B1F0B5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_InputSource.h"; path = "../../JuceLibraryCode/modules/juce_core/streams/juce_InputSource.h"; sourceTree = "SOURCE_ROOT"; }; - 9A704CC5117B59E1F5CEBECD = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DrawablePath.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/drawables/juce_DrawablePath.cpp"; sourceTree = "SOURCE_ROOT"; }; - 9B156F9D8794BF1E15A19C5C = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_TableListBox.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/widgets/juce_TableListBox.cpp"; sourceTree = "SOURCE_ROOT"; }; - 9B1820674E3D99D9D4AB8DD9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_AppleRemote.mm"; path = "../../JuceLibraryCode/modules/juce_gui_extra/native/juce_mac_AppleRemote.mm"; sourceTree = "SOURCE_ROOT"; }; - 9BBE7417871F8708335181B0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_KeyListener.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/keyboard/juce_KeyListener.h"; sourceTree = "SOURCE_ROOT"; }; - 9C6E9983521DF4DFDD0C460B = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_gui_extra.h"; path = "../../JuceLibraryCode/modules/juce_gui_extra/juce_gui_extra.h"; sourceTree = "SOURCE_ROOT"; }; - 9C77E1E9F8BAFCD7610F8F76 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ImageComponent.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/widgets/juce_ImageComponent.h"; sourceTree = "SOURCE_ROOT"; }; - 9CE19F2F963112A2442FF86E = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_RectanglePlacement.h"; path = "../../JuceLibraryCode/modules/juce_graphics/placement/juce_RectanglePlacement.h"; sourceTree = "SOURCE_ROOT"; }; - 9D4642C9C308DD3ABB2DF731 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Time.h"; path = "../../JuceLibraryCode/modules/juce_core/time/juce_Time.h"; sourceTree = "SOURCE_ROOT"; }; - 9D4BEB15620ED88F95BDF105 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FileFilter.h"; path = "../../JuceLibraryCode/modules/juce_core/files/juce_FileFilter.h"; sourceTree = "SOURCE_ROOT"; }; - 9D7A8ED2F93993D6BD4818B9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ImageButton.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/buttons/juce_ImageButton.cpp"; sourceTree = "SOURCE_ROOT"; }; - 9E003766817800EDE5F401DA = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_RenderingHelpers.h"; path = "../../JuceLibraryCode/modules/juce_graphics/native/juce_RenderingHelpers.h"; sourceTree = "SOURCE_ROOT"; }; - 9E22E973F5C7E6AF1004EE8D = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_UndoManager.cpp"; path = "../../JuceLibraryCode/modules/juce_data_structures/undomanager/juce_UndoManager.cpp"; sourceTree = "SOURCE_ROOT"; }; - 9E47EC586E11C6F1AD2782C3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ColourSelector.h"; path = "../../JuceLibraryCode/modules/juce_gui_extra/misc/juce_ColourSelector.h"; sourceTree = "SOURCE_ROOT"; }; - 9E6F450E5BEFD67159EAD012 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_BorderSize.h"; path = "../../JuceLibraryCode/modules/juce_graphics/geometry/juce_BorderSize.h"; sourceTree = "SOURCE_ROOT"; }; - 9F077D151CAAB48E1B7A4A45 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_File.cpp"; path = "../../JuceLibraryCode/modules/juce_core/files/juce_File.cpp"; sourceTree = "SOURCE_ROOT"; }; - 9F32845601855AC6DA5F14B0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_CPlusPlusCodeTokeniser.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_extra/code_editor/juce_CPlusPlusCodeTokeniser.cpp"; sourceTree = "SOURCE_ROOT"; }; - 9F69A9E1418A5E3B33EF5B26 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_JSON.cpp"; path = "../../JuceLibraryCode/modules/juce_core/javascript/juce_JSON.cpp"; sourceTree = "SOURCE_ROOT"; }; - A00497528C590CECD253D1ED = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_WebBrowserComponent.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_extra/native/juce_linux_WebBrowserComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; - A04B28778E7EFA87304B177C = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MouseInactivityDetector.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/mouse/juce_MouseInactivityDetector.cpp"; sourceTree = "SOURCE_ROOT"; }; - A0B1470B03C45DEA4B9EE14B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_GroupComponent.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/layout/juce_GroupComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; - A0CB25C077F41F543BFE0ADE = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MultiDocumentPanel.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/layout/juce_MultiDocumentPanel.h"; sourceTree = "SOURCE_ROOT"; }; - A0D91BF6AFEC74B5349A3087 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CPlusPlusCodeTokeniserFunctions.h"; path = "../../JuceLibraryCode/modules/juce_gui_extra/code_editor/juce_CPlusPlusCodeTokeniserFunctions.h"; sourceTree = "SOURCE_ROOT"; }; - A0EC1B71A589996CE32FDD1B = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_EdgeTable.h"; path = "../../JuceLibraryCode/modules/juce_graphics/geometry/juce_EdgeTable.h"; sourceTree = "SOURCE_ROOT"; }; - A13F9E4C92A3DD4C01330208 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioFormat.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_formats/format/juce_AudioFormat.cpp"; sourceTree = "SOURCE_ROOT"; }; - A1C9C360E9B30D43246B9241 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MemoryMappedAudioFormatReader.h"; path = "../../JuceLibraryCode/modules/juce_audio_formats/format/juce_MemoryMappedAudioFormatReader.h"; sourceTree = "SOURCE_ROOT"; }; - A1EF20A764C5B6EDEFC378E3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_TextPropertyComponent.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/properties/juce_TextPropertyComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; - A232BF668A11B7015B65C33B = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_module_info"; path = "../../JuceLibraryCode/modules/juce_gui_basics/juce_module_info"; sourceTree = "SOURCE_ROOT"; }; - A27997058CED5CD80DE7C4B0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ProgressBar.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/widgets/juce_ProgressBar.cpp"; sourceTree = "SOURCE_ROOT"; }; - A2D0912BF511B8AA5CEE9690 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ResamplingAudioSource.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_basics/sources/juce_ResamplingAudioSource.cpp"; sourceTree = "SOURCE_ROOT"; }; - A2E38A6CEB042C6819BF032C = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_ios_UIViewComponentPeer.mm"; path = "../../JuceLibraryCode/modules/juce_gui_basics/native/juce_ios_UIViewComponentPeer.mm"; sourceTree = "SOURCE_ROOT"; }; - A3405DF38FC19128C399E497 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ThreadPool.cpp"; path = "../../JuceLibraryCode/modules/juce_core/threads/juce_ThreadPool.cpp"; sourceTree = "SOURCE_ROOT"; }; - A38AD54C200158953BA0456D = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_TabbedComponent.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/layout/juce_TabbedComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; - A395CC90104B14CC5D5D8F21 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FileBasedDocument.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_extra/documents/juce_FileBasedDocument.cpp"; sourceTree = "SOURCE_ROOT"; }; - A46624CB68D4D4FC6AFDDDB5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_video.h"; path = "../../JuceLibraryCode/modules/juce_video/juce_video.h"; sourceTree = "SOURCE_ROOT"; }; - A4A99FFB9CECAA4B4ACE8402 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DirectoryIterator.cpp"; path = "../../JuceLibraryCode/modules/juce_core/files/juce_DirectoryIterator.cpp"; sourceTree = "SOURCE_ROOT"; }; - A4CACFA409866E77F609126A = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ZipFile.h"; path = "../../JuceLibraryCode/modules/juce_core/zip/juce_ZipFile.h"; sourceTree = "SOURCE_ROOT"; }; - A4DDA56CCF451DCCA2F47D42 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Justification.h"; path = "../../JuceLibraryCode/modules/juce_graphics/placement/juce_Justification.h"; sourceTree = "SOURCE_ROOT"; }; - A4F8C1DE149AD44A83143598 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_PlatformDefs.h"; path = "../../JuceLibraryCode/modules/juce_core/system/juce_PlatformDefs.h"; sourceTree = "SOURCE_ROOT"; }; - A56E50AC91E42206FAD381F1 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_ActiveXComponent.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_extra/native/juce_win32_ActiveXComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; - A5A2DBDF9350F91E9D6109B7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_AudioCDReader.mm"; path = "../../JuceLibraryCode/modules/juce_audio_devices/native/juce_mac_AudioCDReader.mm"; sourceTree = "SOURCE_ROOT"; }; - A60E87D4E2911C3730CE3DB1 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DrawableRectangle.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/drawables/juce_DrawableRectangle.h"; sourceTree = "SOURCE_ROOT"; }; - A610EB8E83CC94E7DFBBC298 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_SelectedItemSet.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/mouse/juce_SelectedItemSet.h"; sourceTree = "SOURCE_ROOT"; }; - A66CD58D6A8F18628AF2BFF7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_win32_HiddenMessageWindow.h"; path = "../../JuceLibraryCode/modules/juce_events/native/juce_win32_HiddenMessageWindow.h"; sourceTree = "SOURCE_ROOT"; }; + 8FA02AA8698232B53D4BFDBB = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MidiMessageSequence.cpp"; path = "../../../../modules/juce_audio_basics/midi/juce_MidiMessageSequence.cpp"; sourceTree = "SOURCE_ROOT"; }; + 90841E3B0B2548A5BD66F15E = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_FileChooser.cpp"; path = "../../../../modules/juce_gui_basics/native/juce_win32_FileChooser.cpp"; sourceTree = "SOURCE_ROOT"; }; + 90B6C81CFB0DE386C673F62E = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_IPAddress.cpp"; path = "../../../../modules/juce_core/network/juce_IPAddress.cpp"; sourceTree = "SOURCE_ROOT"; }; + 90BE189372A13866896CE817 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FileChooserDialogBox.cpp"; path = "../../../../modules/juce_gui_basics/filebrowser/juce_FileChooserDialogBox.cpp"; sourceTree = "SOURCE_ROOT"; }; + 90FEA7DB5EFC4E9B2E933056 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TextInputTarget.h"; path = "../../../../modules/juce_gui_basics/keyboard/juce_TextInputTarget.h"; sourceTree = "SOURCE_ROOT"; }; + 911B308D5222BDFD954DBB32 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioTransportSource.cpp"; path = "../../../../modules/juce_audio_devices/sources/juce_AudioTransportSource.cpp"; sourceTree = "SOURCE_ROOT"; }; + 916001804771DF943551AAEF = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_LocalisedStrings.h"; path = "../../../../modules/juce_core/text/juce_LocalisedStrings.h"; sourceTree = "SOURCE_ROOT"; }; + 91B991143655810C26644D50 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_PixelFormats.h"; path = "../../../../modules/juce_graphics/colour/juce_PixelFormats.h"; sourceTree = "SOURCE_ROOT"; }; + 91CEFA76775CD035E2F9200F = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_LuaCodeTokeniser.h"; path = "../../../../modules/juce_gui_extra/code_editor/juce_LuaCodeTokeniser.h"; sourceTree = "SOURCE_ROOT"; }; + 91D09C7242A24405FB364449 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ScopedWriteLock.h"; path = "../../../../modules/juce_core/threads/juce_ScopedWriteLock.h"; sourceTree = "SOURCE_ROOT"; }; + 9211B175E63E325D4FF6B789 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_KeyPressMappingSet.cpp"; path = "../../../../modules/juce_gui_basics/commands/juce_KeyPressMappingSet.cpp"; sourceTree = "SOURCE_ROOT"; }; + 92172AE93327D4F8008A0AFD = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_BorderSize.h"; path = "../../../../modules/juce_graphics/geometry/juce_BorderSize.h"; sourceTree = "SOURCE_ROOT"; }; + 926063234BAFA6D29366E43E = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_StringPairArray.cpp"; path = "../../../../modules/juce_core/text/juce_StringPairArray.cpp"; sourceTree = "SOURCE_ROOT"; }; + 92BB22C929A3A76CE6F29C7A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DrawableImage.cpp"; path = "../../../../modules/juce_gui_basics/drawables/juce_DrawableImage.cpp"; sourceTree = "SOURCE_ROOT"; }; + 92DF4A828DC5CE370E36044C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DrawableButton.h"; path = "../../../../modules/juce_gui_basics/buttons/juce_DrawableButton.h"; sourceTree = "SOURCE_ROOT"; }; + 932126F914644642A8244676 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_LAMEEncoderAudioFormat.cpp"; path = "../../../../modules/juce_audio_formats/codecs/juce_LAMEEncoderAudioFormat.cpp"; sourceTree = "SOURCE_ROOT"; }; + 935BCEB2593A51E53187ABC2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_String.cpp"; path = "../../../../modules/juce_core/text/juce_String.cpp"; sourceTree = "SOURCE_ROOT"; }; + 93667813A711750790201F8D = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ScopedXLock.h"; path = "../../../../modules/juce_events/native/juce_ScopedXLock.h"; sourceTree = "SOURCE_ROOT"; }; + 93CC262389F622F8AB79CA60 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Button.cpp"; path = "../../../../modules/juce_gui_basics/buttons/juce_Button.cpp"; sourceTree = "SOURCE_ROOT"; }; + 941219816EB5D7A2231019FA = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Result.h"; path = "../../../../modules/juce_core/misc/juce_Result.h"; sourceTree = "SOURCE_ROOT"; }; + 9424FDB8C564B73250B7B20A = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ButtonPropertyComponent.h"; path = "../../../../modules/juce_gui_basics/properties/juce_ButtonPropertyComponent.h"; sourceTree = "SOURCE_ROOT"; }; + 94BFC3162953A5E7E192276A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DrawableComposite.cpp"; path = "../../../../modules/juce_gui_basics/drawables/juce_DrawableComposite.cpp"; sourceTree = "SOURCE_ROOT"; }; + 94FAC7EB87C8EBE67F68AD60 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ImageConvolutionKernel.cpp"; path = "../../../../modules/juce_graphics/images/juce_ImageConvolutionKernel.cpp"; sourceTree = "SOURCE_ROOT"; }; + 95412F7C12937CC7AC22ADCF = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_ALSA.cpp"; path = "../../../../modules/juce_audio_devices/native/juce_linux_ALSA.cpp"; sourceTree = "SOURCE_ROOT"; }; + 95440A40B2FB3CE5E09D57B4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MidiKeyboardState.cpp"; path = "../../../../modules/juce_audio_basics/midi/juce_MidiKeyboardState.cpp"; sourceTree = "SOURCE_ROOT"; }; + 9692128AC24CF671A9C0457B = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_SplashScreen.h"; path = "../../../../modules/juce_gui_extra/misc/juce_SplashScreen.h"; sourceTree = "SOURCE_ROOT"; }; + 96E4B48CF055ED116E5CB3AB = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DropShadower.h"; path = "../../../../modules/juce_gui_basics/misc/juce_DropShadower.h"; sourceTree = "SOURCE_ROOT"; }; + 979A030D4807A573FAA18318 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MixerAudioSource.h"; path = "../../../../modules/juce_audio_basics/sources/juce_MixerAudioSource.h"; sourceTree = "SOURCE_ROOT"; }; + 97EDCA2A04EF5ADAAD9DC594 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_BufferingAudioSource.h"; path = "../../../../modules/juce_audio_basics/sources/juce_BufferingAudioSource.h"; sourceTree = "SOURCE_ROOT"; }; + 987AD2821B6419D5FEDCBD7A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_audio_formats.mm"; path = "../../../../modules/juce_audio_formats/juce_audio_formats.mm"; sourceTree = "SOURCE_ROOT"; }; + 98C77B9D95141EBC60E6AE67 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DirectoryContentsList.cpp"; path = "../../../../modules/juce_gui_basics/filebrowser/juce_DirectoryContentsList.cpp"; sourceTree = "SOURCE_ROOT"; }; + 98D247A4824D969367AFD0FB = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Uuid.h"; path = "../../../../modules/juce_core/misc/juce_Uuid.h"; sourceTree = "SOURCE_ROOT"; }; + 996A274720539E8497291E85 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_QuickTimeAudioFormat.h"; path = "../../../../modules/juce_audio_formats/codecs/juce_QuickTimeAudioFormat.h"; sourceTree = "SOURCE_ROOT"; }; + 99A3B01A6398623F40C528FC = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_FileChooser.mm"; path = "../../../../modules/juce_gui_basics/native/juce_mac_FileChooser.mm"; sourceTree = "SOURCE_ROOT"; }; + 9A4FCF66FF42906A7A2187A5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Value.h"; path = "../../../../modules/juce_data_structures/values/juce_Value.h"; sourceTree = "SOURCE_ROOT"; }; + 9C05D3A33B0D7B6B2EA43C7A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_BlowFish.cpp"; path = "../../../../modules/juce_cryptography/encryption/juce_BlowFish.cpp"; sourceTree = "SOURCE_ROOT"; }; + 9C17E6FC9A4D7C8734800649 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Result.cpp"; path = "../../../../modules/juce_core/misc/juce_Result.cpp"; sourceTree = "SOURCE_ROOT"; }; + 9C3E556586147F27B4EDC982 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_StretchableLayoutManager.cpp"; path = "../../../../modules/juce_gui_basics/layout/juce_StretchableLayoutManager.cpp"; sourceTree = "SOURCE_ROOT"; }; + 9C599E35E8A990404EEF805A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Primes.cpp"; path = "../../../../modules/juce_cryptography/encryption/juce_Primes.cpp"; sourceTree = "SOURCE_ROOT"; }; + 9C8263A9C3210CBC6C909BDF = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_Threads.mm"; path = "../../../../modules/juce_core/native/juce_mac_Threads.mm"; sourceTree = "SOURCE_ROOT"; }; + 9CC0E3267A9D1EF3C8E37601 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OpenGLTexture.h"; path = "../../../../modules/juce_opengl/opengl/juce_OpenGLTexture.h"; sourceTree = "SOURCE_ROOT"; }; + 9CC22BDB1B3FF427D6525D21 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MemoryMappedAudioFormatReader.h"; path = "../../../../modules/juce_audio_formats/format/juce_MemoryMappedAudioFormatReader.h"; sourceTree = "SOURCE_ROOT"; }; + 9D50B3000D941FDCB620068F = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DirectoryIterator.cpp"; path = "../../../../modules/juce_core/files/juce_DirectoryIterator.cpp"; sourceTree = "SOURCE_ROOT"; }; + 9D61877D2691EB78B2ED69EA = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_android_Fonts.cpp"; path = "../../../../modules/juce_graphics/native/juce_android_Fonts.cpp"; sourceTree = "SOURCE_ROOT"; }; + 9D91916A769A7E2967368795 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Synthesiser.cpp"; path = "../../../../modules/juce_audio_basics/synthesisers/juce_Synthesiser.cpp"; sourceTree = "SOURCE_ROOT"; }; + 9DC4092F746AB0F5A73D929D = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ConnectedChildProcess.h"; path = "../../../../modules/juce_events/interprocess/juce_ConnectedChildProcess.h"; sourceTree = "SOURCE_ROOT"; }; + 9DC79DF0A43DA6B06B7B1F44 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OpenGL_linux.h"; path = "../../../../modules/juce_opengl/native/juce_OpenGL_linux.h"; sourceTree = "SOURCE_ROOT"; }; + 9DCDB2CA1444618C4054A114 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Javascript.h"; path = "../../../../modules/juce_core/javascript/juce_Javascript.h"; sourceTree = "SOURCE_ROOT"; }; + 9E44079E499D4F4ECE55354A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Socket.cpp"; path = "../../../../modules/juce_core/network/juce_Socket.cpp"; sourceTree = "SOURCE_ROOT"; }; + 9F522CA5A8E82BF69E7403BF = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Process.h"; path = "../../../../modules/juce_core/threads/juce_Process.h"; sourceTree = "SOURCE_ROOT"; }; + 9F5FD873C8192683DB089745 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MidiBuffer.cpp"; path = "../../../../modules/juce_audio_basics/midi/juce_MidiBuffer.cpp"; sourceTree = "SOURCE_ROOT"; }; + 9F70142818A7806830EEBD7C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TableListBox.h"; path = "../../../../modules/juce_gui_basics/widgets/juce_TableListBox.h"; sourceTree = "SOURCE_ROOT"; }; + 9F7AC745AA0588C821A014D0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_GZIPDecompressorInputStream.h"; path = "../../../../modules/juce_core/zip/juce_GZIPDecompressorInputStream.h"; sourceTree = "SOURCE_ROOT"; }; + 9FBAD3EFE40ACEB06B155A09 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_Files.cpp"; path = "../../../../modules/juce_core/native/juce_linux_Files.cpp"; sourceTree = "SOURCE_ROOT"; }; + 9FC1BB191F1EB657A181866D = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ImageConvolutionKernel.h"; path = "../../../../modules/juce_graphics/images/juce_ImageConvolutionKernel.h"; sourceTree = "SOURCE_ROOT"; }; + A010D6D997B85A393165DAB3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AttributedString.cpp"; path = "../../../../modules/juce_graphics/fonts/juce_AttributedString.cpp"; sourceTree = "SOURCE_ROOT"; }; + A058E50779879A7D9A813A4C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OpenGLAppComponent.h"; path = "../../../../modules/juce_opengl/utils/juce_OpenGLAppComponent.h"; sourceTree = "SOURCE_ROOT"; }; + A0850087D0288361E552BE9A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_SplashScreen.cpp"; path = "../../../../modules/juce_gui_extra/misc/juce_SplashScreen.cpp"; sourceTree = "SOURCE_ROOT"; }; + A09CB6FA9736BD45103AFF46 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_OpenGLContext.cpp"; path = "../../../../modules/juce_opengl/opengl/juce_OpenGLContext.cpp"; sourceTree = "SOURCE_ROOT"; }; + A0F2EAF085969426AC73C85D = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ApplicationCommandManager.h"; path = "../../../../modules/juce_gui_basics/commands/juce_ApplicationCommandManager.h"; sourceTree = "SOURCE_ROOT"; }; + A1A621FDC626245B1B3C1C4D = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ButtonPropertyComponent.cpp"; path = "../../../../modules/juce_gui_basics/properties/juce_ButtonPropertyComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; + A1C77E9A6624B8B1A461C038 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_StretchableLayoutResizerBar.h"; path = "../../../../modules/juce_gui_basics/layout/juce_StretchableLayoutResizerBar.h"; sourceTree = "SOURCE_ROOT"; }; + A2208C87019608EBF813EAA8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_Strings.mm"; path = "../../../../modules/juce_core/native/juce_mac_Strings.mm"; sourceTree = "SOURCE_ROOT"; }; + A23966DF7E681FA878B27B92 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FileOutputStream.h"; path = "../../../../modules/juce_core/files/juce_FileOutputStream.h"; sourceTree = "SOURCE_ROOT"; }; + A281FFA1C7E3AFB8246FD577 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_DirectShowComponent.cpp"; path = "../../../../modules/juce_video/native/juce_win32_DirectShowComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; + A292587AA4633141BA378473 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_HighResolutionTimer.h"; path = "../../../../modules/juce_core/threads/juce_HighResolutionTimer.h"; sourceTree = "SOURCE_ROOT"; }; + A3D0C263C912566AECB57679 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Expression.cpp"; path = "../../../../modules/juce_core/maths/juce_Expression.cpp"; sourceTree = "SOURCE_ROOT"; }; + A3E01235E4AD9DBE2405F792 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_Direct2DGraphicsContext.cpp"; path = "../../../../modules/juce_graphics/native/juce_win32_Direct2DGraphicsContext.cpp"; sourceTree = "SOURCE_ROOT"; }; + A42A97232CE0593D8D989FC1 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CharacterFunctions.h"; path = "../../../../modules/juce_core/text/juce_CharacterFunctions.h"; sourceTree = "SOURCE_ROOT"; }; + A4F394FB62E70E3A3A02E4C7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_NamedPipe.cpp"; path = "../../../../modules/juce_core/network/juce_NamedPipe.cpp"; sourceTree = "SOURCE_ROOT"; }; + A50AF1519D78428A8DCD91BF = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioUnitPluginFormat.h"; path = "../../../../modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.h"; sourceTree = "SOURCE_ROOT"; }; + A53228473B7F7BCF946F15DF = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_PluginListComponent.cpp"; path = "../../../../modules/juce_audio_processors/scanning/juce_PluginListComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; + A54AED02A4929ED6EB693CB9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MessageManager.h"; path = "../../../../modules/juce_events/messages/juce_MessageManager.h"; sourceTree = "SOURCE_ROOT"; }; + A54B5504235B3324635B1DB3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Point.h"; path = "../../../../modules/juce_graphics/geometry/juce_Point.h"; sourceTree = "SOURCE_ROOT"; }; + A587862CF3C96C6C648216A3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_InterprocessConnection.cpp"; path = "../../../../modules/juce_events/interprocess/juce_InterprocessConnection.cpp"; sourceTree = "SOURCE_ROOT"; }; + A5CEADBA23491564FEB6D4EC = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_mac_CoreGraphicsContext.h"; path = "../../../../modules/juce_graphics/native/juce_mac_CoreGraphicsContext.h"; sourceTree = "SOURCE_ROOT"; }; + A5DEEB6DADAA5AB2CF41A880 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DragAndDropContainer.cpp"; path = "../../../../modules/juce_gui_basics/mouse/juce_DragAndDropContainer.cpp"; sourceTree = "SOURCE_ROOT"; }; + A61AD5378601F9DDEB8DED03 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioPlayHead.h"; path = "../../../../modules/juce_audio_processors/processors/juce_AudioPlayHead.h"; sourceTree = "SOURCE_ROOT"; }; A67C5701B28E64F889A92422 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = AppConfig.h; path = ../../JuceLibraryCode/AppConfig.h; sourceTree = "SOURCE_ROOT"; }; - A71DF97DA4CD69A67A1EE763 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TextDragAndDropTarget.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/mouse/juce_TextDragAndDropTarget.h"; sourceTree = "SOURCE_ROOT"; }; - A72F50930E3169EFC9724597 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Javascript.cpp"; path = "../../JuceLibraryCode/modules/juce_core/javascript/juce_Javascript.cpp"; sourceTree = "SOURCE_ROOT"; }; - A751CD8564B7B6B0EBD643E2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ImageFileFormat.h"; path = "../../JuceLibraryCode/modules/juce_graphics/images/juce_ImageFileFormat.h"; sourceTree = "SOURCE_ROOT"; }; - A76327DF3D3A1CB89340C2CB = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_RSAKey.h"; path = "../../JuceLibraryCode/modules/juce_cryptography/encryption/juce_RSAKey.h"; sourceTree = "SOURCE_ROOT"; }; - A77BB927A95DA581268CD729 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioPluginFormat.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_processors/format/juce_AudioPluginFormat.cpp"; sourceTree = "SOURCE_ROOT"; }; - A7D96DBD645622F9EF3B3E88 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_LookAndFeel.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel.h"; sourceTree = "SOURCE_ROOT"; }; - A87251DF370D12DEA68B41A1 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FileTreeComponent.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/filebrowser/juce_FileTreeComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; - A873E57D126C8D931CE6556A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioCDReader.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_devices/audio_cd/juce_AudioCDReader.cpp"; sourceTree = "SOURCE_ROOT"; }; - A8C6E967CBC442F331571870 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Primes.cpp"; path = "../../JuceLibraryCode/modules/juce_cryptography/encryption/juce_Primes.cpp"; sourceTree = "SOURCE_ROOT"; }; - A8DC0ACAAB88D6657355E466 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_LinkedListPointer.h"; path = "../../JuceLibraryCode/modules/juce_core/containers/juce_LinkedListPointer.h"; sourceTree = "SOURCE_ROOT"; }; - A90C3FDE58F6023CE19ECCEF = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_EdgeTable.cpp"; path = "../../JuceLibraryCode/modules/juce_graphics/geometry/juce_EdgeTable.cpp"; sourceTree = "SOURCE_ROOT"; }; - A92EA5F1D1D2ABA2E441DE45 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DrawableComposite.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/drawables/juce_DrawableComposite.cpp"; sourceTree = "SOURCE_ROOT"; }; - A963217BDC628E29845AFA5F = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Path.h"; path = "../../JuceLibraryCode/modules/juce_graphics/geometry/juce_Path.h"; sourceTree = "SOURCE_ROOT"; }; - A97E3E8BDA867CFC443D8D21 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_PropertiesFile.cpp"; path = "../../JuceLibraryCode/modules/juce_data_structures/app_properties/juce_PropertiesFile.cpp"; sourceTree = "SOURCE_ROOT"; }; - AA251B07162ABAA59D3DF432 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_StringPool.h"; path = "../../JuceLibraryCode/modules/juce_core/text/juce_StringPool.h"; sourceTree = "SOURCE_ROOT"; }; - AA67BCD0930A0B3B9D0B12B1 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_AudioCDBurner.mm"; path = "../../JuceLibraryCode/modules/juce_audio_devices/native/juce_mac_AudioCDBurner.mm"; sourceTree = "SOURCE_ROOT"; }; - AB2C5E54CD675401124F26A0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioDeviceManager.h"; path = "../../JuceLibraryCode/modules/juce_audio_devices/audio_io/juce_AudioDeviceManager.h"; sourceTree = "SOURCE_ROOT"; }; - AB7C518F617F260822A67872 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_TextLayout.cpp"; path = "../../JuceLibraryCode/modules/juce_graphics/fonts/juce_TextLayout.cpp"; sourceTree = "SOURCE_ROOT"; }; - ABA9367C4E66F2F18E813816 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ImageCache.cpp"; path = "../../JuceLibraryCode/modules/juce_graphics/images/juce_ImageCache.cpp"; sourceTree = "SOURCE_ROOT"; }; - ABB9E5EBCD9C0F04547E5A90 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MenuBarComponent.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/menus/juce_MenuBarComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; - AC3721AA8206512767A5E5AE = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ResizableCornerComponent.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/layout/juce_ResizableCornerComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; - AC3B9DEF05ED1B18C952FE36 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DirectoryContentsList.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/filebrowser/juce_DirectoryContentsList.h"; sourceTree = "SOURCE_ROOT"; }; - ACA68143C3AEE4F3F3327E66 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MouseInactivityDetector.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/mouse/juce_MouseInactivityDetector.h"; sourceTree = "SOURCE_ROOT"; }; - ACB0BA25EA85951D2A75CC62 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Path.cpp"; path = "../../JuceLibraryCode/modules/juce_graphics/geometry/juce_Path.cpp"; sourceTree = "SOURCE_ROOT"; }; - ACEF6D28EC9FB10B6C0D8EE0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_mac_CoreGraphicsContext.h"; path = "../../JuceLibraryCode/modules/juce_graphics/native/juce_mac_CoreGraphicsContext.h"; sourceTree = "SOURCE_ROOT"; }; - ACF10436974ED4510E3FC4BB = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioProcessorGraph.h"; path = "../../JuceLibraryCode/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h"; sourceTree = "SOURCE_ROOT"; }; - AD6517C175A8D9D5A9D168E6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MidiMessageCollector.h"; path = "../../JuceLibraryCode/modules/juce_audio_devices/midi_io/juce_MidiMessageCollector.h"; sourceTree = "SOURCE_ROOT"; }; - AD6AAB2F586CBD4E35D5167B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MemoryBlock.cpp"; path = "../../JuceLibraryCode/modules/juce_core/memory/juce_MemoryBlock.cpp"; sourceTree = "SOURCE_ROOT"; }; - AD7F976713D7D3B057793A42 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Rectangle.h"; path = "../../JuceLibraryCode/modules/juce_graphics/geometry/juce_Rectangle.h"; sourceTree = "SOURCE_ROOT"; }; - AE7E18FE030834B289424681 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CallOutBox.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/windows/juce_CallOutBox.h"; sourceTree = "SOURCE_ROOT"; }; - AEB7028FB923A6FD7404A84C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MissingGLDefinitions.h"; path = "../../JuceLibraryCode/modules/juce_opengl/native/juce_MissingGLDefinitions.h"; sourceTree = "SOURCE_ROOT"; }; - AEEE72913C595DAE27F43ADC = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ChoicePropertyComponent.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/properties/juce_ChoicePropertyComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; - AFC498B17E8D5B122DB666C1 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ZipFile.cpp"; path = "../../JuceLibraryCode/modules/juce_core/zip/juce_ZipFile.cpp"; sourceTree = "SOURCE_ROOT"; }; - B035D33267C606674E58EE2B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Component.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/components/juce_Component.cpp"; sourceTree = "SOURCE_ROOT"; }; - B063E208C533148EDB5D4B91 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_BooleanPropertyComponent.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/properties/juce_BooleanPropertyComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; - B070645F1A6B85C679B77B21 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_AudioCDReader.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_devices/native/juce_linux_AudioCDReader.cpp"; sourceTree = "SOURCE_ROOT"; }; - B0793B0E00A1410BD054B141 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioIODevice.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_devices/audio_io/juce_AudioIODevice.cpp"; sourceTree = "SOURCE_ROOT"; }; - B08C35519C2E990041F82336 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_CameraDevice.cpp"; path = "../../JuceLibraryCode/modules/juce_video/capture/juce_CameraDevice.cpp"; sourceTree = "SOURCE_ROOT"; }; - B0CD0890EC1297C2C70B741B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MP3AudioFormat.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_formats/codecs/juce_MP3AudioFormat.cpp"; sourceTree = "SOURCE_ROOT"; }; - B14C06A5F45ACD5D93357F96 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MD5.h"; path = "../../JuceLibraryCode/modules/juce_cryptography/hashing/juce_MD5.h"; sourceTree = "SOURCE_ROOT"; }; - B17E7CF3B375FCC6A9178500 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_PluginDescription.h"; path = "../../JuceLibraryCode/modules/juce_audio_processors/processors/juce_PluginDescription.h"; sourceTree = "SOURCE_ROOT"; }; - B1F56F0DD4CC94FF8BB1FBE0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FileSearchPathListComponent.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/filebrowser/juce_FileSearchPathListComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; - B1FDA24AC0EF52652F3DB94E = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ScrollBar.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/layout/juce_ScrollBar.h"; sourceTree = "SOURCE_ROOT"; }; - B2E4733C1FB26F143C0C7344 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_KeyPressMappingSet.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/commands/juce_KeyPressMappingSet.cpp"; sourceTree = "SOURCE_ROOT"; }; - B2F561631B30711F78C118A0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FileChooser.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/filebrowser/juce_FileChooser.h"; sourceTree = "SOURCE_ROOT"; }; - B3669C5F60758B9D20E41583 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ActiveXControlComponent.h"; path = "../../JuceLibraryCode/modules/juce_gui_extra/embedding/juce_ActiveXControlComponent.h"; sourceTree = "SOURCE_ROOT"; }; - B3CFDC682EFECC45C4227288 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_RelativePoint.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/positioning/juce_RelativePoint.cpp"; sourceTree = "SOURCE_ROOT"; }; - B3D51DEA0DE311B017CAB716 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FileOutputStream.h"; path = "../../JuceLibraryCode/modules/juce_core/files/juce_FileOutputStream.h"; sourceTree = "SOURCE_ROOT"; }; - B3E93FD47ACA9498963C8A2C = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ValueTree.cpp"; path = "../../JuceLibraryCode/modules/juce_data_structures/values/juce_ValueTree.cpp"; sourceTree = "SOURCE_ROOT"; }; - B3EB470623EB09A867A9383E = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ScopedLock.h"; path = "../../JuceLibraryCode/modules/juce_core/threads/juce_ScopedLock.h"; sourceTree = "SOURCE_ROOT"; }; - B4554AB60F9524B82FAC071C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OpenGLExtensions.h"; path = "../../JuceLibraryCode/modules/juce_opengl/native/juce_OpenGLExtensions.h"; sourceTree = "SOURCE_ROOT"; }; - B45F7C71FC56F9DCEA7379FF = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AnimatedPositionBehaviours.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/layout/juce_AnimatedPositionBehaviours.h"; sourceTree = "SOURCE_ROOT"; }; - B4AFAA5A74A2E61F0196F4B8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DialogWindow.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/windows/juce_DialogWindow.cpp"; sourceTree = "SOURCE_ROOT"; }; - B4C612999A7FF20800CE507E = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ImageConvolutionKernel.h"; path = "../../JuceLibraryCode/modules/juce_graphics/images/juce_ImageConvolutionKernel.h"; sourceTree = "SOURCE_ROOT"; }; - B4D3C4A6929FB0068E61E5E7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_HyperlinkButton.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/buttons/juce_HyperlinkButton.cpp"; sourceTree = "SOURCE_ROOT"; }; - B4FF9DAF77F9CEFA8FFDA583 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FilenameComponent.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/filebrowser/juce_FilenameComponent.h"; sourceTree = "SOURCE_ROOT"; }; - B53B0352EAA432B0179F0201 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DynamicObject.h"; path = "../../JuceLibraryCode/modules/juce_core/containers/juce_DynamicObject.h"; sourceTree = "SOURCE_ROOT"; }; - B58C5A06F8D666BCB074D981 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OpenGLFrameBuffer.h"; path = "../../JuceLibraryCode/modules/juce_opengl/opengl/juce_OpenGLFrameBuffer.h"; sourceTree = "SOURCE_ROOT"; }; - B65CD1D011475424E927B37E = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Expression.cpp"; path = "../../JuceLibraryCode/modules/juce_core/maths/juce_Expression.cpp"; sourceTree = "SOURCE_ROOT"; }; - B68C18758AC0A7570E067015 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FileBasedDocument.h"; path = "../../JuceLibraryCode/modules/juce_gui_extra/documents/juce_FileBasedDocument.h"; sourceTree = "SOURCE_ROOT"; }; - B6B4BC87EEA6BFF7A739D118 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_data_structures.mm"; path = "../../JuceLibraryCode/modules/juce_data_structures/juce_data_structures.mm"; sourceTree = "SOURCE_ROOT"; }; - B6BB67F1186B3A3DB89DC02B = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_PathIterator.h"; path = "../../JuceLibraryCode/modules/juce_graphics/geometry/juce_PathIterator.h"; sourceTree = "SOURCE_ROOT"; }; - B71187E41B94D7913C1791AE = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Typeface.h"; path = "../../JuceLibraryCode/modules/juce_graphics/fonts/juce_Typeface.h"; sourceTree = "SOURCE_ROOT"; }; + A6AD00FEFB31915AB0F2798F = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ComponentListener.h"; path = "../../../../modules/juce_gui_basics/components/juce_ComponentListener.h"; sourceTree = "SOURCE_ROOT"; }; + A76D6B94991D6E028EE8D1AA = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioFormat.cpp"; path = "../../../../modules/juce_audio_formats/format/juce_AudioFormat.cpp"; sourceTree = "SOURCE_ROOT"; }; + A782FF0CD79464F3E015647E = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_android_JNIHelpers.h"; path = "../../../../modules/juce_core/native/juce_android_JNIHelpers.h"; sourceTree = "SOURCE_ROOT"; }; + A7884EC24DD007D6232DB822 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_Windowing.mm"; path = "../../../../modules/juce_gui_basics/native/juce_mac_Windowing.mm"; sourceTree = "SOURCE_ROOT"; }; + A789D75FEFFFB7E8E835FBAB = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MidiMessageCollector.cpp"; path = "../../../../modules/juce_audio_devices/midi_io/juce_MidiMessageCollector.cpp"; sourceTree = "SOURCE_ROOT"; }; + A7B28AD8606992FBE04C527C = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_CodeDocument.cpp"; path = "../../../../modules/juce_gui_extra/code_editor/juce_CodeDocument.cpp"; sourceTree = "SOURCE_ROOT"; }; + A826C1C083678A4E9279C118 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_TreeView.cpp"; path = "../../../../modules/juce_gui_basics/widgets/juce_TreeView.cpp"; sourceTree = "SOURCE_ROOT"; }; + A8A277CAF10A3FEB258174C2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Typeface.h"; path = "../../../../modules/juce_graphics/fonts/juce_Typeface.h"; sourceTree = "SOURCE_ROOT"; }; + A8C570DF829A8B8581B4E8CC = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioProcessorGraph.h"; path = "../../../../modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h"; sourceTree = "SOURCE_ROOT"; }; + A8CAB6FAB9BC1CC96FDE7BC2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_RenderingHelpers.h"; path = "../../../../modules/juce_graphics/native/juce_RenderingHelpers.h"; sourceTree = "SOURCE_ROOT"; }; + A917646C0153D2A57E3C5677 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MidiFile.h"; path = "../../../../modules/juce_audio_basics/midi/juce_MidiFile.h"; sourceTree = "SOURCE_ROOT"; }; + A95D718F031CB8883DFDE915 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ProgressBar.cpp"; path = "../../../../modules/juce_gui_basics/widgets/juce_ProgressBar.cpp"; sourceTree = "SOURCE_ROOT"; }; + A9608756E1A18BAFCC48A064 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_SpinLock.h"; path = "../../../../modules/juce_core/threads/juce_SpinLock.h"; sourceTree = "SOURCE_ROOT"; }; + A98EED399E310BF85EBBCE12 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OpenGLGraphicsContext.h"; path = "../../../../modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.h"; sourceTree = "SOURCE_ROOT"; }; + AA5CDD430B68BBE10A9026C5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Desktop.cpp"; path = "../../../../modules/juce_gui_basics/components/juce_Desktop.cpp"; sourceTree = "SOURCE_ROOT"; }; + AAA3ED492FF78DBBF86DC612 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_win32_HiddenMessageWindow.h"; path = "../../../../modules/juce_events/native/juce_win32_HiddenMessageWindow.h"; sourceTree = "SOURCE_ROOT"; }; + AB3C130E565756182528752D = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AiffAudioFormat.cpp"; path = "../../../../modules/juce_audio_formats/codecs/juce_AiffAudioFormat.cpp"; sourceTree = "SOURCE_ROOT"; }; + AB856191A15A8C9016D974D5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MountedVolumeListChangeDetector.h"; path = "../../../../modules/juce_events/messages/juce_MountedVolumeListChangeDetector.h"; sourceTree = "SOURCE_ROOT"; }; + ABA2E1FE9912D5C28F177E56 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TextDragAndDropTarget.h"; path = "../../../../modules/juce_gui_basics/mouse/juce_TextDragAndDropTarget.h"; sourceTree = "SOURCE_ROOT"; }; + AC018F2C47CF57EB4A87AC36 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_WildcardFileFilter.h"; path = "../../../../modules/juce_core/files/juce_WildcardFileFilter.h"; sourceTree = "SOURCE_ROOT"; }; + AC2AE970951E20A199938AFB = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioDataConverters.cpp"; path = "../../../../modules/juce_audio_basics/buffers/juce_AudioDataConverters.cpp"; sourceTree = "SOURCE_ROOT"; }; + AC3184BE8D8804394FCCDCB6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MidiMessage.h"; path = "../../../../modules/juce_audio_basics/midi/juce_MidiMessage.h"; sourceTree = "SOURCE_ROOT"; }; + AC42B6006776E1CE3A3A94A0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Expression.h"; path = "../../../../modules/juce_core/maths/juce_Expression.h"; sourceTree = "SOURCE_ROOT"; }; + AC56A48CC01AABBE45F51970 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_Fonts.mm"; path = "../../../../modules/juce_graphics/native/juce_mac_Fonts.mm"; sourceTree = "SOURCE_ROOT"; }; + AC725293BD38E8C66E35EED3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_PropertySet.h"; path = "../../../../modules/juce_core/containers/juce_PropertySet.h"; sourceTree = "SOURCE_ROOT"; }; + ACAC59A1C54DC52E8E2438CC = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_CameraDevice.cpp"; path = "../../../../modules/juce_video/native/juce_win32_CameraDevice.cpp"; sourceTree = "SOURCE_ROOT"; }; + AD405DDE86D07F955E27EBF8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_audio_processors.mm"; path = "../../../../modules/juce_audio_processors/juce_audio_processors.mm"; sourceTree = "SOURCE_ROOT"; }; + AD41400898312123119E987A = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_BigInteger.h"; path = "../../../../modules/juce_core/maths/juce_BigInteger.h"; sourceTree = "SOURCE_ROOT"; }; + AD54DAEAB7840FC18DA65503 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_WebBrowserComponent.cpp"; path = "../../../../modules/juce_gui_extra/native/juce_linux_WebBrowserComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; + AD648ADDD885B93B2EB60C88 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioSampleBuffer.cpp"; path = "../../../../modules/juce_audio_basics/buffers/juce_AudioSampleBuffer.cpp"; sourceTree = "SOURCE_ROOT"; }; + AD8417869D43ED72319C283C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_BufferingAudioFormatReader.h"; path = "../../../../modules/juce_audio_formats/format/juce_BufferingAudioFormatReader.h"; sourceTree = "SOURCE_ROOT"; }; + ADCA2F92E2C17964A4AD750E = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ResizableBorderComponent.h"; path = "../../../../modules/juce_gui_basics/layout/juce_ResizableBorderComponent.h"; sourceTree = "SOURCE_ROOT"; }; + AE381B9D6E2A4DA363C7DD3F = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MessageListener.h"; path = "../../../../modules/juce_events/messages/juce_MessageListener.h"; sourceTree = "SOURCE_ROOT"; }; + AF59758C300E586A7A6338D1 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_PropertiesFile.h"; path = "../../../../modules/juce_data_structures/app_properties/juce_PropertiesFile.h"; sourceTree = "SOURCE_ROOT"; }; + AF885F6112CEA5C2D7934AA3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DirectoryIterator.h"; path = "../../../../modules/juce_core/files/juce_DirectoryIterator.h"; sourceTree = "SOURCE_ROOT"; }; + B004D25E0DC1AA2C4CD3788A = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MidiMessageCollector.h"; path = "../../../../modules/juce_audio_devices/midi_io/juce_MidiMessageCollector.h"; sourceTree = "SOURCE_ROOT"; }; + B0286AC6D04C5D080A299A1C = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_AudioCDReader.cpp"; path = "../../../../modules/juce_audio_devices/native/juce_linux_AudioCDReader.cpp"; sourceTree = "SOURCE_ROOT"; }; + B0589203065E4CF2C002B0D9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OpenGLHelpers.h"; path = "../../../../modules/juce_opengl/opengl/juce_OpenGLHelpers.h"; sourceTree = "SOURCE_ROOT"; }; + B0626D2C611D9E3DF1408BEA = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TextEditorKeyMapper.h"; path = "../../../../modules/juce_gui_basics/keyboard/juce_TextEditorKeyMapper.h"; sourceTree = "SOURCE_ROOT"; }; + B15DC22CA1E52983F4F57A9D = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_Threads.cpp"; path = "../../../../modules/juce_core/native/juce_linux_Threads.cpp"; sourceTree = "SOURCE_ROOT"; }; + B189762C440B38635351E0A3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Application.cpp"; path = "../../../../modules/juce_gui_basics/application/juce_Application.cpp"; sourceTree = "SOURCE_ROOT"; }; + B1A41C6141726A390E2182A2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_audio_devices.h"; path = "../../../../modules/juce_audio_devices/juce_audio_devices.h"; sourceTree = "SOURCE_ROOT"; }; + B1B7C62CA04ACBAC6CD1C2AD = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_KeyPress.h"; path = "../../../../modules/juce_gui_basics/keyboard/juce_KeyPress.h"; sourceTree = "SOURCE_ROOT"; }; + B1C799A152189A282E6CAC76 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_android_Midi.cpp"; path = "../../../../modules/juce_audio_devices/native/juce_android_Midi.cpp"; sourceTree = "SOURCE_ROOT"; }; + B28F34DD7CABFD48B1EE3CCE = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Random.h"; path = "../../../../modules/juce_core/maths/juce_Random.h"; sourceTree = "SOURCE_ROOT"; }; + B2D42B884600CE62E3253DA3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_DirectSound.cpp"; path = "../../../../modules/juce_audio_devices/native/juce_win32_DirectSound.cpp"; sourceTree = "SOURCE_ROOT"; }; + B305ACE053406FF288E500F8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_SubregionStream.cpp"; path = "../../../../modules/juce_core/streams/juce_SubregionStream.cpp"; sourceTree = "SOURCE_ROOT"; }; + B316291E570F37785C40FE88 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_RelativeParallelogram.cpp"; path = "../../../../modules/juce_gui_basics/positioning/juce_RelativeParallelogram.cpp"; sourceTree = "SOURCE_ROOT"; }; + B3261106892038D4F954E6F9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MouseCursor.h"; path = "../../../../modules/juce_gui_basics/mouse/juce_MouseCursor.h"; sourceTree = "SOURCE_ROOT"; }; + B32716A0B0702E6861726529 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ActionBroadcaster.cpp"; path = "../../../../modules/juce_events/broadcasters/juce_ActionBroadcaster.cpp"; sourceTree = "SOURCE_ROOT"; }; + B3FBDBEBC38720E957C15BE9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_LookAndFeel_V3.cpp"; path = "../../../../modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V3.cpp"; sourceTree = "SOURCE_ROOT"; }; + B401E96340B8AB5DE8CBF5C9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AnimatedAppComponent.cpp"; path = "../../../../modules/juce_gui_extra/misc/juce_AnimatedAppComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; + B409D881BE39C4704C94996C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ReadWriteLock.h"; path = "../../../../modules/juce_core/threads/juce_ReadWriteLock.h"; sourceTree = "SOURCE_ROOT"; }; + B471C2AB67E7C68D1C7D729D = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_PathIterator.cpp"; path = "../../../../modules/juce_graphics/geometry/juce_PathIterator.cpp"; sourceTree = "SOURCE_ROOT"; }; + B4769129853D2822D3DB38D1 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ApplicationProperties.h"; path = "../../../../modules/juce_data_structures/app_properties/juce_ApplicationProperties.h"; sourceTree = "SOURCE_ROOT"; }; + B54A14A497368A580B7D9AEB = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DrawableRectangle.cpp"; path = "../../../../modules/juce_gui_basics/drawables/juce_DrawableRectangle.cpp"; sourceTree = "SOURCE_ROOT"; }; + B57640F7EDADCFE17719EE68 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FileBrowserComponent.h"; path = "../../../../modules/juce_gui_basics/filebrowser/juce_FileBrowserComponent.h"; sourceTree = "SOURCE_ROOT"; }; + B5C3814B2174E5127F42D721 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioFormatWriter.cpp"; path = "../../../../modules/juce_audio_formats/format/juce_AudioFormatWriter.cpp"; sourceTree = "SOURCE_ROOT"; }; + B60524021E6FC59416222870 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OpenGLRenderer.h"; path = "../../../../modules/juce_opengl/opengl/juce_OpenGLRenderer.h"; sourceTree = "SOURCE_ROOT"; }; + B6ABBE7782ECD38631EB11BC = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_PluginDescription.h"; path = "../../../../modules/juce_audio_processors/processors/juce_PluginDescription.h"; sourceTree = "SOURCE_ROOT"; }; + B6BE7EF02190070336E63E89 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_RectangleList.h"; path = "../../../../modules/juce_graphics/geometry/juce_RectangleList.h"; sourceTree = "SOURCE_ROOT"; }; + B6C7114A31FD6B1DEB08346F = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ResizableEdgeComponent.cpp"; path = "../../../../modules/juce_gui_basics/layout/juce_ResizableEdgeComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; + B6D9BF4B75784D01B7CDE1AF = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Timer.cpp"; path = "../../../../modules/juce_events/timers/juce_Timer.cpp"; sourceTree = "SOURCE_ROOT"; }; + B70E52FF75D44F0F1F0B31D2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ToolbarButton.h"; path = "../../../../modules/juce_gui_basics/buttons/juce_ToolbarButton.h"; sourceTree = "SOURCE_ROOT"; }; B766DBADE0BD743FAC004870 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = MainComponent.cpp; path = ../../Source/MainComponent.cpp; sourceTree = "SOURCE_ROOT"; }; - B78FA8958102108085ABE489 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_WavAudioFormat.h"; path = "../../JuceLibraryCode/modules/juce_audio_formats/codecs/juce_WavAudioFormat.h"; sourceTree = "SOURCE_ROOT"; }; - B79DB0C1AA34A90D1F3E012B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_StretchableObjectResizer.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/layout/juce_StretchableObjectResizer.cpp"; sourceTree = "SOURCE_ROOT"; }; - B7EA4F63CADAB5B31D3D985F = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Slider.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/widgets/juce_Slider.cpp"; sourceTree = "SOURCE_ROOT"; }; - B7F1AB21699A5EEEA59DA2AD = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_KeyMappingEditorComponent.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_extra/misc/juce_KeyMappingEditorComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; - B852DBE7C0AFD11AB872754A = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioPlayHead.h"; path = "../../JuceLibraryCode/modules/juce_audio_processors/processors/juce_AudioPlayHead.h"; sourceTree = "SOURCE_ROOT"; }; - B87D578105925ED8FFC105AE = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OpenGLContext.h"; path = "../../JuceLibraryCode/modules/juce_opengl/opengl/juce_OpenGLContext.h"; sourceTree = "SOURCE_ROOT"; }; - B8DF17DE3A37A52E3514A492 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Colour.cpp"; path = "../../JuceLibraryCode/modules/juce_graphics/colour/juce_Colour.cpp"; sourceTree = "SOURCE_ROOT"; }; - B973B2A075C1EE23F2AEFF32 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioProcessor.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_processors/processors/juce_AudioProcessor.cpp"; sourceTree = "SOURCE_ROOT"; }; - B989CEE19057D31C6D521BBC = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_ios_MessageManager.mm"; path = "../../JuceLibraryCode/modules/juce_events/native/juce_ios_MessageManager.mm"; sourceTree = "SOURCE_ROOT"; }; - BA97D0B8F59B68F245351F01 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ActionBroadcaster.cpp"; path = "../../JuceLibraryCode/modules/juce_events/broadcasters/juce_ActionBroadcaster.cpp"; sourceTree = "SOURCE_ROOT"; }; - BB586BA19ADC508119BF86CC = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TextEditorKeyMapper.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/keyboard/juce_TextEditorKeyMapper.h"; sourceTree = "SOURCE_ROOT"; }; - BBF1A328A57B8CA11F40D3B0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_opengl.h"; path = "../../JuceLibraryCode/modules/juce_opengl/juce_opengl.h"; sourceTree = "SOURCE_ROOT"; }; - BBF610446898623948599114 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Random.h"; path = "../../JuceLibraryCode/modules/juce_core/maths/juce_Random.h"; sourceTree = "SOURCE_ROOT"; }; - BC3EB76C434A2FDAC6C46DB2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_audio_formats.mm"; path = "../../JuceLibraryCode/modules/juce_audio_formats/juce_audio_formats.mm"; sourceTree = "SOURCE_ROOT"; }; - BC57385BADED3932DB3714EF = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_RelativeParallelogram.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/positioning/juce_RelativeParallelogram.h"; sourceTree = "SOURCE_ROOT"; }; - BCC1C92B775AEA802A0AC917 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CriticalSection.h"; path = "../../JuceLibraryCode/modules/juce_core/threads/juce_CriticalSection.h"; sourceTree = "SOURCE_ROOT"; }; - BCE1A7250DC27CE2B297B999 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_StretchableLayoutManager.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/layout/juce_StretchableLayoutManager.h"; sourceTree = "SOURCE_ROOT"; }; - BCE458AC1B9E30F85B443851 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_Windowing.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/native/juce_win32_Windowing.cpp"; sourceTree = "SOURCE_ROOT"; }; - BCE6AF6A2A5E7156836E5E7F = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ApplicationCommandTarget.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/commands/juce_ApplicationCommandTarget.h"; sourceTree = "SOURCE_ROOT"; }; - BD2B30F77B968E717E713124 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_TabbedButtonBar.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/layout/juce_TabbedButtonBar.cpp"; sourceTree = "SOURCE_ROOT"; }; - BD455C126781EDA150C9298B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_Threads.mm"; path = "../../JuceLibraryCode/modules/juce_core/native/juce_mac_Threads.mm"; sourceTree = "SOURCE_ROOT"; }; - BE22F0B06CBFF0C62A317CAC = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MenuBarModel.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/menus/juce_MenuBarModel.h"; sourceTree = "SOURCE_ROOT"; }; - BE24FC2B4C9D80DC8DC99BC2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_LookAndFeel_V2.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V2.h"; sourceTree = "SOURCE_ROOT"; }; - BE80DA6D586BB1C790B345E2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_XMLCodeTokeniser.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_extra/code_editor/juce_XMLCodeTokeniser.cpp"; sourceTree = "SOURCE_ROOT"; }; - BE990C63B85752BF968C5EC6 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_module_info"; path = "../../JuceLibraryCode/modules/juce_audio_basics/juce_module_info"; sourceTree = "SOURCE_ROOT"; }; - BEDA74674128EDC35C5CCAC0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_KeyPress.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/keyboard/juce_KeyPress.cpp"; sourceTree = "SOURCE_ROOT"; }; - BF64F4ED5DF12FFF99C826AB = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MessageManager.cpp"; path = "../../JuceLibraryCode/modules/juce_events/messages/juce_MessageManager.cpp"; sourceTree = "SOURCE_ROOT"; }; - BFB2A78106121AE2F199055C = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DeletedAtShutdown.cpp"; path = "../../JuceLibraryCode/modules/juce_events/messages/juce_DeletedAtShutdown.cpp"; sourceTree = "SOURCE_ROOT"; }; - BFC021DD9267F5F0D2D2D58D = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_LookAndFeel_V1.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V1.cpp"; sourceTree = "SOURCE_ROOT"; }; - C00122D03A9B2BE3E4ECBE4E = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_android_GraphicsContext.cpp"; path = "../../JuceLibraryCode/modules/juce_graphics/native/juce_android_GraphicsContext.cpp"; sourceTree = "SOURCE_ROOT"; }; - C12AEDA7D0BE5A220AF9D30A = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_StringPairArray.h"; path = "../../JuceLibraryCode/modules/juce_core/text/juce_StringPairArray.h"; sourceTree = "SOURCE_ROOT"; }; - C1505EA2417265BC59135075 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_RelativePointPath.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/positioning/juce_RelativePointPath.h"; sourceTree = "SOURCE_ROOT"; }; - C18E1D4D4D0E4F6B0525C212 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OptionalScopedPointer.h"; path = "../../JuceLibraryCode/modules/juce_core/memory/juce_OptionalScopedPointer.h"; sourceTree = "SOURCE_ROOT"; }; - C1C5A9F18F63CDB9BDF32177 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MidiBuffer.h"; path = "../../JuceLibraryCode/modules/juce_audio_basics/midi/juce_MidiBuffer.h"; sourceTree = "SOURCE_ROOT"; }; - C2375B75F67BAAA9813EEC2B = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ChoicePropertyComponent.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/properties/juce_ChoicePropertyComponent.h"; sourceTree = "SOURCE_ROOT"; }; - C3B0389DB7042B45EFC751AC = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Slider.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/widgets/juce_Slider.h"; sourceTree = "SOURCE_ROOT"; }; - C42F2CE5B179094CEF9786C1 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TextPropertyComponent.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/properties/juce_TextPropertyComponent.h"; sourceTree = "SOURCE_ROOT"; }; - C44BCD4A16768A91B02EE14C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_WindowsRegistry.h"; path = "../../JuceLibraryCode/modules/juce_core/misc/juce_WindowsRegistry.h"; sourceTree = "SOURCE_ROOT"; }; - C56154402FC7B2983160C3E3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ComponentBuilder.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/layout/juce_ComponentBuilder.cpp"; sourceTree = "SOURCE_ROOT"; }; - C57F2A4DB4E9E55D5017A33F = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_FileChooser.mm"; path = "../../JuceLibraryCode/modules/juce_gui_basics/native/juce_mac_FileChooser.mm"; sourceTree = "SOURCE_ROOT"; }; - C5D7E8FD3897F200069DAF62 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_module_info"; path = "../../JuceLibraryCode/modules/juce_data_structures/juce_module_info"; sourceTree = "SOURCE_ROOT"; }; - C609197710C7E8DF361C4556 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Variant.h"; path = "../../JuceLibraryCode/modules/juce_core/containers/juce_Variant.h"; sourceTree = "SOURCE_ROOT"; }; - C6111F5E51935A78B357FE2E = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_BufferingAudioFormatReader.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_formats/format/juce_BufferingAudioFormatReader.cpp"; sourceTree = "SOURCE_ROOT"; }; - C61D46855CAEF3FB4547909B = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FileChooserDialogBox.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/filebrowser/juce_FileChooserDialogBox.h"; sourceTree = "SOURCE_ROOT"; }; - C70A847D3C9EDEFE5B57C1AC = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_StretchableLayoutResizerBar.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/layout/juce_StretchableLayoutResizerBar.h"; sourceTree = "SOURCE_ROOT"; }; - C7B2F4323D69615085F4A633 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ResizableWindow.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/windows/juce_ResizableWindow.cpp"; sourceTree = "SOURCE_ROOT"; }; - C8541CD950B7AB83AECF39E4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ModifierKeys.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/keyboard/juce_ModifierKeys.h"; sourceTree = "SOURCE_ROOT"; }; - C8915F6AB7855AF370A5581B = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OpenGLRenderer.h"; path = "../../JuceLibraryCode/modules/juce_opengl/opengl/juce_OpenGLRenderer.h"; sourceTree = "SOURCE_ROOT"; }; - C8A93F28EB0AE4F99767EE47 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_Threads.cpp"; path = "../../JuceLibraryCode/modules/juce_core/native/juce_win32_Threads.cpp"; sourceTree = "SOURCE_ROOT"; }; - C8AFE60B7174C0006C1C85F3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_Network.mm"; path = "../../JuceLibraryCode/modules/juce_core/native/juce_mac_Network.mm"; sourceTree = "SOURCE_ROOT"; }; - C98FF9CD6E5BC931F600A73D = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioFormatReader.h"; path = "../../JuceLibraryCode/modules/juce_audio_formats/format/juce_AudioFormatReader.h"; sourceTree = "SOURCE_ROOT"; }; + B7855FA22C92F7EE272A866E = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_KnownPluginList.h"; path = "../../../../modules/juce_audio_processors/scanning/juce_KnownPluginList.h"; sourceTree = "SOURCE_ROOT"; }; + B7DD84C8B05ABA4A6915E77E = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_core.mm"; path = "../../../../modules/juce_core/juce_core.mm"; sourceTree = "SOURCE_ROOT"; }; + B83DDFEEA66888E9616BCE82 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DirectShowComponent.h"; path = "../../../../modules/juce_video/playback/juce_DirectShowComponent.h"; sourceTree = "SOURCE_ROOT"; }; + B88950266CC4244E1B5394F2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ToggleButton.h"; path = "../../../../modules/juce_gui_basics/buttons/juce_ToggleButton.h"; sourceTree = "SOURCE_ROOT"; }; + BA7FDBE53073F3261D962FF9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_ios_UIViewComponent.mm"; path = "../../../../modules/juce_gui_extra/native/juce_ios_UIViewComponent.mm"; sourceTree = "SOURCE_ROOT"; }; + BACA17304411EED8B219D2AC = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Uuid.cpp"; path = "../../../../modules/juce_core/misc/juce_Uuid.cpp"; sourceTree = "SOURCE_ROOT"; }; + BAD1E66E3AA09ADD70061A50 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_LuaCodeTokeniser.cpp"; path = "../../../../modules/juce_gui_extra/code_editor/juce_LuaCodeTokeniser.cpp"; sourceTree = "SOURCE_ROOT"; }; + BAE06A3352E39521CE5D94EB = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_BigInteger.cpp"; path = "../../../../modules/juce_core/maths/juce_BigInteger.cpp"; sourceTree = "SOURCE_ROOT"; }; + BB144FF841A99B08D5479777 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_VSTPluginFormat.cpp"; path = "../../../../modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp"; sourceTree = "SOURCE_ROOT"; }; + BC0ED0B33BB83E19D9609152 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Colours.cpp"; path = "../../../../modules/juce_graphics/colour/juce_Colours.cpp"; sourceTree = "SOURCE_ROOT"; }; + BC1DBF05964D3B9130CD8CB6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FileTreeComponent.h"; path = "../../../../modules/juce_gui_basics/filebrowser/juce_FileTreeComponent.h"; sourceTree = "SOURCE_ROOT"; }; + BCFE159BD9F2DA5515E028A4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ConcertinaPanel.h"; path = "../../../../modules/juce_gui_basics/layout/juce_ConcertinaPanel.h"; sourceTree = "SOURCE_ROOT"; }; + BD588F8D5FD1E6FE88E9D3E4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AnimatedAppComponent.h"; path = "../../../../modules/juce_gui_extra/misc/juce_AnimatedAppComponent.h"; sourceTree = "SOURCE_ROOT"; }; + BD7B0136829554046A511588 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Javascript.cpp"; path = "../../../../modules/juce_core/javascript/juce_Javascript.cpp"; sourceTree = "SOURCE_ROOT"; }; + BE61994F6993AE76CBBF1EAB = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Image.cpp"; path = "../../../../modules/juce_graphics/images/juce_Image.cpp"; sourceTree = "SOURCE_ROOT"; }; + BFB12FD84F14C9B31249FC04 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ChannelRemappingAudioSource.h"; path = "../../../../modules/juce_audio_basics/sources/juce_ChannelRemappingAudioSource.h"; sourceTree = "SOURCE_ROOT"; }; + C088D98E527C1DA17B55A9D9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ToolbarButton.cpp"; path = "../../../../modules/juce_gui_basics/buttons/juce_ToolbarButton.cpp"; sourceTree = "SOURCE_ROOT"; }; + C0BA74AF0382D87B0E7BCEB3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_LeakedObjectDetector.h"; path = "../../../../modules/juce_core/memory/juce_LeakedObjectDetector.h"; sourceTree = "SOURCE_ROOT"; }; + C0FDDD3106A13770B141E5F2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TextDiff.h"; path = "../../../../modules/juce_core/text/juce_TextDiff.h"; sourceTree = "SOURCE_ROOT"; }; + C21701DD3A4A2628C63CB70A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_SVGParser.cpp"; path = "../../../../modules/juce_gui_basics/drawables/juce_SVGParser.cpp"; sourceTree = "SOURCE_ROOT"; }; + C3DEEC17595B1AB020ADA47F = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ImagePreviewComponent.cpp"; path = "../../../../modules/juce_gui_basics/filebrowser/juce_ImagePreviewComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; + C51A754A0E65CA141A2C3310 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FilenameComponent.cpp"; path = "../../../../modules/juce_gui_basics/filebrowser/juce_FilenameComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; + C52E8074125FEED4DB727EDF = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FileChooser.h"; path = "../../../../modules/juce_gui_basics/filebrowser/juce_FileChooser.h"; sourceTree = "SOURCE_ROOT"; }; + C52FB75A0A93BB1397D1F962 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_WindowsMediaAudioFormat.cpp"; path = "../../../../modules/juce_audio_formats/codecs/juce_WindowsMediaAudioFormat.cpp"; sourceTree = "SOURCE_ROOT"; }; + C5C3838D0FDC65F44C9D1A9A = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CallbackMessage.h"; path = "../../../../modules/juce_events/messages/juce_CallbackMessage.h"; sourceTree = "SOURCE_ROOT"; }; + C7581A35068A3FB43786F4BE = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AbstractFifo.h"; path = "../../../../modules/juce_core/containers/juce_AbstractFifo.h"; sourceTree = "SOURCE_ROOT"; }; C9F7ABDA09635BC3FAB0B008 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; path = System/Library/Frameworks/CoreAudio.framework; sourceTree = SDKROOT; }; + CA025D4369C240E6FA30CE2B = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Range.h"; path = "../../../../modules/juce_core/maths/juce_Range.h"; sourceTree = "SOURCE_ROOT"; }; CBECD9165897602A506BC41E = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QTKit.framework; path = System/Library/Frameworks/QTKit.framework; sourceTree = SDKROOT; }; - CDDD5A437DEFD1CD65160A9C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MidiFile.h"; path = "../../JuceLibraryCode/modules/juce_audio_basics/midi/juce_MidiFile.h"; sourceTree = "SOURCE_ROOT"; }; - D18648E47B5447E1F6AEEA52 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_OutputStream.cpp"; path = "../../JuceLibraryCode/modules/juce_core/streams/juce_OutputStream.cpp"; sourceTree = "SOURCE_ROOT"; }; - D214FC393B8C9A379FE3C6CE = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_NamedPipe.h"; path = "../../JuceLibraryCode/modules/juce_core/network/juce_NamedPipe.h"; sourceTree = "SOURCE_ROOT"; }; + CCA3065F893912F3E3625C13 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Reverb.h"; path = "../../../../modules/juce_audio_basics/effects/juce_Reverb.h"; sourceTree = "SOURCE_ROOT"; }; + CCF8FB3EA0246D83E3D2E760 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioFormatManager.cpp"; path = "../../../../modules/juce_audio_formats/format/juce_AudioFormatManager.cpp"; sourceTree = "SOURCE_ROOT"; }; + CCF94157A15DD29B6C5DA939 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DynamicObject.h"; path = "../../../../modules/juce_core/containers/juce_DynamicObject.h"; sourceTree = "SOURCE_ROOT"; }; D32C3176FB914F189E0139AF = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = System/Library/Frameworks/IOKit.framework; sourceTree = SDKROOT; }; A748C987924800FDBA2E2184 = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = AnimationAppExample.app; sourceTree = "BUILT_PRODUCTS_DIR"; }; - B9D557438E309657EB68CF7D = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_DirectWriteTypeLayout.cpp"; path = "../../JuceLibraryCode/modules/juce_graphics/native/juce_win32_DirectWriteTypeLayout.cpp"; sourceTree = "SOURCE_ROOT"; }; - C46FC2DAD97DA825D6449A2B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_String.cpp"; path = "../../JuceLibraryCode/modules/juce_core/text/juce_String.cpp"; sourceTree = "SOURCE_ROOT"; }; - C67D83EB019C2F931E5FF290 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MidiMessage.h"; path = "../../JuceLibraryCode/modules/juce_audio_basics/midi/juce_MidiMessage.h"; sourceTree = "SOURCE_ROOT"; }; - C856D47E76BE017D87E77496 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_WavAudioFormat.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_formats/codecs/juce_WavAudioFormat.cpp"; sourceTree = "SOURCE_ROOT"; }; - C920268F5AAE587A04131F34 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_RelativeTime.h"; path = "../../JuceLibraryCode/modules/juce_core/time/juce_RelativeTime.h"; sourceTree = "SOURCE_ROOT"; }; - C97E9F209C271E901D31304E = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MessageManager.h"; path = "../../JuceLibraryCode/modules/juce_events/messages/juce_MessageManager.h"; sourceTree = "SOURCE_ROOT"; }; - C98926DCE80A0B3149961D0F = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_Files.mm"; path = "../../JuceLibraryCode/modules/juce_core/native/juce_mac_Files.mm"; sourceTree = "SOURCE_ROOT"; }; - C989EB89ACD3E1E5122BDBAD = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_DirectShowComponent.cpp"; path = "../../JuceLibraryCode/modules/juce_video/native/juce_win32_DirectShowComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; - CAF194AB75BBCF7A63DFDA43 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioProcessorEditor.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_processors/processors/juce_AudioProcessorEditor.cpp"; sourceTree = "SOURCE_ROOT"; }; - CB04786710DE206E794D272F = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_WebBrowserComponent.mm"; path = "../../JuceLibraryCode/modules/juce_gui_extra/native/juce_mac_WebBrowserComponent.mm"; sourceTree = "SOURCE_ROOT"; }; - CB3D07088AB905BD96AD3A90 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_audio_processors.mm"; path = "../../JuceLibraryCode/modules/juce_audio_processors/juce_audio_processors.mm"; sourceTree = "SOURCE_ROOT"; }; - CBE0FA629B5B2B352EFF53D4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_LAMEEncoderAudioFormat.h"; path = "../../JuceLibraryCode/modules/juce_audio_formats/codecs/juce_LAMEEncoderAudioFormat.h"; sourceTree = "SOURCE_ROOT"; }; - CC464EB86E0DE492BEFC7237 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ComponentDragger.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/mouse/juce_ComponentDragger.h"; sourceTree = "SOURCE_ROOT"; }; - CC726694653F832354878239 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FileBrowserListener.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/filebrowser/juce_FileBrowserListener.h"; sourceTree = "SOURCE_ROOT"; }; - CCD5CC6545DB9D9FFBB99D46 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_module_info"; path = "../../JuceLibraryCode/modules/juce_core/juce_module_info"; sourceTree = "SOURCE_ROOT"; }; - CE696F8D455A2C2D1B8051FB = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MarkerList.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/positioning/juce_MarkerList.cpp"; sourceTree = "SOURCE_ROOT"; }; - CEB12E3A853DD633CD5F3AFB = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Component.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/components/juce_Component.h"; sourceTree = "SOURCE_ROOT"; }; - CEE91A9F1C74260FAC3E30A0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ActionListener.h"; path = "../../JuceLibraryCode/modules/juce_events/broadcasters/juce_ActionListener.h"; sourceTree = "SOURCE_ROOT"; }; - CF768CC6E2EA5664519C1C03 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Process.h"; path = "../../JuceLibraryCode/modules/juce_core/threads/juce_Process.h"; sourceTree = "SOURCE_ROOT"; }; - CFB26A1C32F851E8DDC36BB7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MidiKeyboardState.h"; path = "../../JuceLibraryCode/modules/juce_audio_basics/midi/juce_MidiKeyboardState.h"; sourceTree = "SOURCE_ROOT"; }; - D00090B2DE234305128AB650 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_XmlElement.cpp"; path = "../../JuceLibraryCode/modules/juce_core/xml/juce_XmlElement.cpp"; sourceTree = "SOURCE_ROOT"; }; - D0197C6B54D5A5B8AB15A230 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OpenGLHelpers.h"; path = "../../JuceLibraryCode/modules/juce_opengl/opengl/juce_OpenGLHelpers.h"; sourceTree = "SOURCE_ROOT"; }; - D03AA7DD0628031F75231425 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TooltipWindow.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/windows/juce_TooltipWindow.h"; sourceTree = "SOURCE_ROOT"; }; - D06C2B0C19461F7AA18914A8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MouseListener.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/mouse/juce_MouseListener.h"; sourceTree = "SOURCE_ROOT"; }; - D07A1E2DA76EA9CFBC9E3133 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CodeDocument.h"; path = "../../JuceLibraryCode/modules/juce_gui_extra/code_editor/juce_CodeDocument.h"; sourceTree = "SOURCE_ROOT"; }; - D0D385C5D99B9D9A90C00458 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TabbedComponent.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/layout/juce_TabbedComponent.h"; sourceTree = "SOURCE_ROOT"; }; - D0D3C2CBD0363F82E5D9B092 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CompilerSupport.h"; path = "../../JuceLibraryCode/modules/juce_core/system/juce_CompilerSupport.h"; sourceTree = "SOURCE_ROOT"; }; - D18690CB0E643C9A642F73A6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Image.h"; path = "../../JuceLibraryCode/modules/juce_graphics/images/juce_Image.h"; sourceTree = "SOURCE_ROOT"; }; - D23D5618C7FFFCFD938CD5F1 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_LagrangeInterpolator.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_basics/effects/juce_LagrangeInterpolator.cpp"; sourceTree = "SOURCE_ROOT"; }; - D2BC39EF5E34ACB2BE05539C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CoreAudioFormat.h"; path = "../../JuceLibraryCode/modules/juce_audio_formats/codecs/juce_CoreAudioFormat.h"; sourceTree = "SOURCE_ROOT"; }; - D37E99EBDA572556CA60B942 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ComponentMovementWatcher.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/layout/juce_ComponentMovementWatcher.cpp"; sourceTree = "SOURCE_ROOT"; }; - D3C91BB5D97D3CD7411D718B = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_win32_ComSmartPtr.h"; path = "../../JuceLibraryCode/modules/juce_core/native/juce_win32_ComSmartPtr.h"; sourceTree = "SOURCE_ROOT"; }; - D3DAA92A27A10FBB1AEC0966 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_VST3PluginFormat.h"; path = "../../JuceLibraryCode/modules/juce_audio_processors/format_types/juce_VST3PluginFormat.h"; sourceTree = "SOURCE_ROOT"; }; - D429E0F29213E9058DED8ECC = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ResamplingAudioSource.h"; path = "../../JuceLibraryCode/modules/juce_audio_basics/sources/juce_ResamplingAudioSource.h"; sourceTree = "SOURCE_ROOT"; }; - D4D9555F85A739252C027F45 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Timer.h"; path = "../../JuceLibraryCode/modules/juce_events/timers/juce_Timer.h"; sourceTree = "SOURCE_ROOT"; }; - D4EE8C83FA9A3BB53AA747C0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_KeyPressMappingSet.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/commands/juce_KeyPressMappingSet.h"; sourceTree = "SOURCE_ROOT"; }; - D4FD4193ACDA02D2C3D8B5D6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_QuickTimeMovieComponent.mm"; path = "../../JuceLibraryCode/modules/juce_video/native/juce_mac_QuickTimeMovieComponent.mm"; sourceTree = "SOURCE_ROOT"; }; - D528C603E1870E0BC562CB9D = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_Files.cpp"; path = "../../JuceLibraryCode/modules/juce_core/native/juce_win32_Files.cpp"; sourceTree = "SOURCE_ROOT"; }; - D535D69439B72C799B61DD37 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MathsFunctions.h"; path = "../../JuceLibraryCode/modules/juce_core/maths/juce_MathsFunctions.h"; sourceTree = "SOURCE_ROOT"; }; - D56619E400C7A4619515AFFA = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_SharedResourcePointer.h"; path = "../../JuceLibraryCode/modules/juce_core/memory/juce_SharedResourcePointer.h"; sourceTree = "SOURCE_ROOT"; }; - D568CB3943835ADB2613AEF8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Logger.cpp"; path = "../../JuceLibraryCode/modules/juce_core/logging/juce_Logger.cpp"; sourceTree = "SOURCE_ROOT"; }; - D56DEA7CACE4A86351CDDD5B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_OpenGLTexture.cpp"; path = "../../JuceLibraryCode/modules/juce_opengl/opengl/juce_OpenGLTexture.cpp"; sourceTree = "SOURCE_ROOT"; }; - D61ABCB4D785A183EB967AE7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TargetPlatform.h"; path = "../../JuceLibraryCode/modules/juce_core/system/juce_TargetPlatform.h"; sourceTree = "SOURCE_ROOT"; }; - D6486972C28234B51D512700 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ArrayAllocationBase.h"; path = "../../JuceLibraryCode/modules/juce_core/containers/juce_ArrayAllocationBase.h"; sourceTree = "SOURCE_ROOT"; }; - D65828A1160764381EC4A290 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OpenGLAppComponent.h"; path = "../../JuceLibraryCode/modules/juce_opengl/utils/juce_OpenGLAppComponent.h"; sourceTree = "SOURCE_ROOT"; }; - D69079E0065151480B46F7B7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FileInputStream.h"; path = "../../JuceLibraryCode/modules/juce_core/files/juce_FileInputStream.h"; sourceTree = "SOURCE_ROOT"; }; - D6ECAE5B0CC40752D559ABC4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_DragAndDrop.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/native/juce_win32_DragAndDrop.cpp"; sourceTree = "SOURCE_ROOT"; }; - D720150F1F3647538D037677 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_SystemStats.cpp"; path = "../../JuceLibraryCode/modules/juce_core/native/juce_linux_SystemStats.cpp"; sourceTree = "SOURCE_ROOT"; }; - D728D4777A842A58EC01454A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_cryptography.mm"; path = "../../JuceLibraryCode/modules/juce_cryptography/juce_cryptography.mm"; sourceTree = "SOURCE_ROOT"; }; - D786D6FB9787CEC730CFEDD9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioSource.h"; path = "../../JuceLibraryCode/modules/juce_audio_basics/sources/juce_AudioSource.h"; sourceTree = "SOURCE_ROOT"; }; - D7996C2834C1EE0DAC4BAEDA = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TextButton.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/buttons/juce_TextButton.h"; sourceTree = "SOURCE_ROOT"; }; - D79EAA241B5FA1ECFB84614F = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_LocalisedStrings.h"; path = "../../JuceLibraryCode/modules/juce_core/text/juce_LocalisedStrings.h"; sourceTree = "SOURCE_ROOT"; }; - D7D4E1A29E0B3A33814C7EBF = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_GIFLoader.cpp"; path = "../../JuceLibraryCode/modules/juce_graphics/image_formats/juce_GIFLoader.cpp"; sourceTree = "SOURCE_ROOT"; }; - D8AEA877A6200E6793A56B81 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DirectoryContentsDisplayComponent.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/filebrowser/juce_DirectoryContentsDisplayComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; - D9108E2655D2E4403A4B598A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_RelativeParallelogram.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/positioning/juce_RelativeParallelogram.cpp"; sourceTree = "SOURCE_ROOT"; }; - D97C2B6C906C1C179598C7CC = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_LADSPAPluginFormat.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_processors/format_types/juce_LADSPAPluginFormat.cpp"; sourceTree = "SOURCE_ROOT"; }; - DA088C27651F40F29163E0C2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MouseCursor.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/mouse/juce_MouseCursor.h"; sourceTree = "SOURCE_ROOT"; }; - DA41E1FA66C5B7218625EC70 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_SystemTrayIconComponent.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_extra/misc/juce_SystemTrayIconComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; - DA42AA71E4D47975E018BED0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_CaretComponent.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/keyboard/juce_CaretComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; - DA54722A7C1A958B80B9D10A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_GlyphArrangement.cpp"; path = "../../JuceLibraryCode/modules/juce_graphics/fonts/juce_GlyphArrangement.cpp"; sourceTree = "SOURCE_ROOT"; }; - DA93B8704F3EC4703E2B2DC2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MultiTimer.h"; path = "../../JuceLibraryCode/modules/juce_events/timers/juce_MultiTimer.h"; sourceTree = "SOURCE_ROOT"; }; - DAA6196510C04172905A6BA2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MultiDocumentPanel.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/layout/juce_MultiDocumentPanel.cpp"; sourceTree = "SOURCE_ROOT"; }; - DC078E6D148F784C9843BD8A = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_RelativeCoordinatePositioner.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/positioning/juce_RelativeCoordinatePositioner.h"; sourceTree = "SOURCE_ROOT"; }; - DC4D885D7F7F573E42E13F65 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ToolbarButton.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/buttons/juce_ToolbarButton.h"; sourceTree = "SOURCE_ROOT"; }; - DC4F26260A712654A80A2FF5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_SystemStats.cpp"; path = "../../JuceLibraryCode/modules/juce_core/native/juce_win32_SystemStats.cpp"; sourceTree = "SOURCE_ROOT"; }; - DD4F1D5C6CAD9CEA86F83209 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DrawableRectangle.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/drawables/juce_DrawableRectangle.cpp"; sourceTree = "SOURCE_ROOT"; }; - DDB38AD7F6C5A2E5E3725288 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OpenGLGraphicsContext.h"; path = "../../JuceLibraryCode/modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.h"; sourceTree = "SOURCE_ROOT"; }; - DE3E98A6DCCBE1F461E46E79 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_freetype_Fonts.cpp"; path = "../../JuceLibraryCode/modules/juce_graphics/native/juce_freetype_Fonts.cpp"; sourceTree = "SOURCE_ROOT"; }; - DE41FE4DADD07963905B82D0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CaretComponent.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/keyboard/juce_CaretComponent.h"; sourceTree = "SOURCE_ROOT"; }; - DE48404D34F2CAE314CA4E19 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_XmlDocument.h"; path = "../../JuceLibraryCode/modules/juce_core/xml/juce_XmlDocument.h"; sourceTree = "SOURCE_ROOT"; }; - DE579AF9E1C7F5EA0B7A87A3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_GZIPDecompressorInputStream.h"; path = "../../JuceLibraryCode/modules/juce_core/zip/juce_GZIPDecompressorInputStream.h"; sourceTree = "SOURCE_ROOT"; }; - DE9CB3573085CEA391B49650 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_KeyboardFocusTraverser.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/keyboard/juce_KeyboardFocusTraverser.cpp"; sourceTree = "SOURCE_ROOT"; }; - DECB3C3714353AE5775147AD = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_TemporaryFile.cpp"; path = "../../JuceLibraryCode/modules/juce_core/files/juce_TemporaryFile.cpp"; sourceTree = "SOURCE_ROOT"; }; - DF7A0D14EC237709BAFE9224 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_PixelFormats.h"; path = "../../JuceLibraryCode/modules/juce_graphics/colour/juce_PixelFormats.h"; sourceTree = "SOURCE_ROOT"; }; - DF99FBC1355728976531AD5D = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_WindowsMediaAudioFormat.h"; path = "../../JuceLibraryCode/modules/juce_audio_formats/codecs/juce_WindowsMediaAudioFormat.h"; sourceTree = "SOURCE_ROOT"; }; - DFD3944531485F2F72ECB87A = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioCDReader.h"; path = "../../JuceLibraryCode/modules/juce_audio_devices/audio_cd/juce_AudioCDReader.h"; sourceTree = "SOURCE_ROOT"; }; - E09382FAC0496CC7B1A70087 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DirectoryContentsList.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/filebrowser/juce_DirectoryContentsList.cpp"; sourceTree = "SOURCE_ROOT"; }; - E0D15D4DE8EC3E536812D4FD = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MenuBarModel.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/menus/juce_MenuBarModel.cpp"; sourceTree = "SOURCE_ROOT"; }; - E0DFDD144675EF457B607E50 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AbstractFifo.h"; path = "../../JuceLibraryCode/modules/juce_core/containers/juce_AbstractFifo.h"; sourceTree = "SOURCE_ROOT"; }; - E105D3381CAF5006058DF2FD = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_RelativeCoordinatePositioner.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/positioning/juce_RelativeCoordinatePositioner.cpp"; sourceTree = "SOURCE_ROOT"; }; - E15C23EFF754E1289CE5437C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_GZIPCompressorOutputStream.h"; path = "../../JuceLibraryCode/modules/juce_core/zip/juce_GZIPCompressorOutputStream.h"; sourceTree = "SOURCE_ROOT"; }; - E15E5A1710E50FAB897B4310 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ColourGradient.h"; path = "../../JuceLibraryCode/modules/juce_graphics/colour/juce_ColourGradient.h"; sourceTree = "SOURCE_ROOT"; }; - E16F860A9AA000E590BE321A = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_BasicNativeHeaders.h"; path = "../../JuceLibraryCode/modules/juce_core/native/juce_BasicNativeHeaders.h"; sourceTree = "SOURCE_ROOT"; }; - E19A17B7DFC2E18AFC90946E = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ValueTree.h"; path = "../../JuceLibraryCode/modules/juce_data_structures/values/juce_ValueTree.h"; sourceTree = "SOURCE_ROOT"; }; - E22876603667D88857CA5179 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MidiKeyboardState.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_basics/midi/juce_MidiKeyboardState.cpp"; sourceTree = "SOURCE_ROOT"; }; - E27B4C86E077374F4C5E0F02 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DragAndDropContainer.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/mouse/juce_DragAndDropContainer.h"; sourceTree = "SOURCE_ROOT"; }; - E2940D3353B79053D215093F = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_android_Windowing.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/native/juce_android_Windowing.cpp"; sourceTree = "SOURCE_ROOT"; }; - E34E03B67A82E30F5CD201BF = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ReadWriteLock.h"; path = "../../JuceLibraryCode/modules/juce_core/threads/juce_ReadWriteLock.h"; sourceTree = "SOURCE_ROOT"; }; - E3699DD1D681C7B65A9348C5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MouseInputSource.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/mouse/juce_MouseInputSource.h"; sourceTree = "SOURCE_ROOT"; }; - E39FB683ECD1152137E3853A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioPluginFormatManager.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_processors/format/juce_AudioPluginFormatManager.cpp"; sourceTree = "SOURCE_ROOT"; }; - E3DF0709DECF7FB19A8DBB11 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TreeView.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/widgets/juce_TreeView.h"; sourceTree = "SOURCE_ROOT"; }; - E462CDCA6635D111D6B85C4B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioProcessorGraph.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.cpp"; sourceTree = "SOURCE_ROOT"; }; - E508FDD5269C63F7D0E08E48 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AbstractFifo.cpp"; path = "../../JuceLibraryCode/modules/juce_core/containers/juce_AbstractFifo.cpp"; sourceTree = "SOURCE_ROOT"; }; - E5608726D3CC8DDCA57635BF = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_SparseSet.h"; path = "../../JuceLibraryCode/modules/juce_core/containers/juce_SparseSet.h"; sourceTree = "SOURCE_ROOT"; }; - E63BC85590BE7258F35FA46F = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_LowLevelGraphicsSoftwareRenderer.h"; path = "../../JuceLibraryCode/modules/juce_graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.h"; sourceTree = "SOURCE_ROOT"; }; - E670FE5F095BB2B7F9EB8138 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ChannelRemappingAudioSource.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_basics/sources/juce_ChannelRemappingAudioSource.cpp"; sourceTree = "SOURCE_ROOT"; }; - E7733DCA05641E94C0714362 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ScopedPointer.h"; path = "../../JuceLibraryCode/modules/juce_core/memory/juce_ScopedPointer.h"; sourceTree = "SOURCE_ROOT"; }; - E782C5F53BBED225CABF6587 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioDeviceManager.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_devices/audio_io/juce_AudioDeviceManager.cpp"; sourceTree = "SOURCE_ROOT"; }; - E783E1B6AEFF256939443D39 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_String.h"; path = "../../JuceLibraryCode/modules/juce_core/text/juce_String.h"; sourceTree = "SOURCE_ROOT"; }; - E7B310562519AC9C1FA14CB1 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_GraphicsContext.h"; path = "../../JuceLibraryCode/modules/juce_graphics/contexts/juce_GraphicsContext.h"; sourceTree = "SOURCE_ROOT"; }; - E7C5065D5E153DFF6308D5F3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CharPointer_UTF8.h"; path = "../../JuceLibraryCode/modules/juce_core/text/juce_CharPointer_UTF8.h"; sourceTree = "SOURCE_ROOT"; }; - E7DC2D13A73F3CDA652C9DF5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_BufferedInputStream.cpp"; path = "../../JuceLibraryCode/modules/juce_core/streams/juce_BufferedInputStream.cpp"; sourceTree = "SOURCE_ROOT"; }; - E7E06147F43FCAE8D5B20BAB = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ComponentBoundsConstrainer.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/layout/juce_ComponentBoundsConstrainer.h"; sourceTree = "SOURCE_ROOT"; }; - E8E4F93EF596101FE5333018 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_audio_formats.h"; path = "../../JuceLibraryCode/modules/juce_audio_formats/juce_audio_formats.h"; sourceTree = "SOURCE_ROOT"; }; - E90A5D53778BE390A04B8D30 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ResizableEdgeComponent.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/layout/juce_ResizableEdgeComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; - E965D6B8815E3C5E8A160C48 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FileLogger.h"; path = "../../JuceLibraryCode/modules/juce_core/logging/juce_FileLogger.h"; sourceTree = "SOURCE_ROOT"; }; - E9E6FADE6A6F0B00452C0AD6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_Windowing.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/native/juce_linux_Windowing.cpp"; sourceTree = "SOURCE_ROOT"; }; - E9F7C31F43B7F22018E8170D = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_URL.cpp"; path = "../../JuceLibraryCode/modules/juce_core/network/juce_URL.cpp"; sourceTree = "SOURCE_ROOT"; }; - EA14E79A40FE2177626ADD79 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OpenGLShaderProgram.h"; path = "../../JuceLibraryCode/modules/juce_opengl/opengl/juce_OpenGLShaderProgram.h"; sourceTree = "SOURCE_ROOT"; }; - EA269A07CD83E9F5977889E6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FloatVectorOperations.h"; path = "../../JuceLibraryCode/modules/juce_audio_basics/buffers/juce_FloatVectorOperations.h"; sourceTree = "SOURCE_ROOT"; }; - EB3E426C5FF655F7AD88D843 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioSubsectionReader.h"; path = "../../JuceLibraryCode/modules/juce_audio_formats/format/juce_AudioSubsectionReader.h"; sourceTree = "SOURCE_ROOT"; }; - EB4083E018759B2F9C29C67E = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ThreadLocalValue.h"; path = "../../JuceLibraryCode/modules/juce_core/threads/juce_ThreadLocalValue.h"; sourceTree = "SOURCE_ROOT"; }; - EC60C51FC1AA8BD749F4DEC3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_TooltipWindow.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/windows/juce_TooltipWindow.cpp"; sourceTree = "SOURCE_ROOT"; }; - EC6C43EBC349D5597A1CE53A = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TableListBox.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/widgets/juce_TableListBox.h"; sourceTree = "SOURCE_ROOT"; }; - EC9AF66FDBA32E129D80E59A = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Logger.h"; path = "../../JuceLibraryCode/modules/juce_core/logging/juce_Logger.h"; sourceTree = "SOURCE_ROOT"; }; - ED56CB90240662CE6FBE2A74 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DrawableImage.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/drawables/juce_DrawableImage.cpp"; sourceTree = "SOURCE_ROOT"; }; - EDC826A2266EC4945813EB52 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_android_Midi.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_devices/native/juce_android_Midi.cpp"; sourceTree = "SOURCE_ROOT"; }; - EE7FAE0C413B7370B393CD35 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_LookAndFeel_V3.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V3.cpp"; sourceTree = "SOURCE_ROOT"; }; - F0FA50C01669546088DA6DB3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_JSON.h"; path = "../../JuceLibraryCode/modules/juce_core/javascript/juce_JSON.h"; sourceTree = "SOURCE_ROOT"; }; - F150F0F13B3B18F263086336 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MidiBuffer.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_basics/midi/juce_MidiBuffer.cpp"; sourceTree = "SOURCE_ROOT"; }; - F1E144384FC6A2C42FE4097D = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_KeyPress.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/keyboard/juce_KeyPress.h"; sourceTree = "SOURCE_ROOT"; }; - F2137487557EE18A462259B8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ProgressBar.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/widgets/juce_ProgressBar.h"; sourceTree = "SOURCE_ROOT"; }; - F232D373ED304682C9581DBF = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DrawableButton.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/buttons/juce_DrawableButton.h"; sourceTree = "SOURCE_ROOT"; }; - F27227DC9C5FD1ED9D39644E = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_WebBrowserComponent.h"; path = "../../JuceLibraryCode/modules/juce_gui_extra/misc/juce_WebBrowserComponent.h"; sourceTree = "SOURCE_ROOT"; }; - F27EABE98642759DB9C4DF65 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_JPEGLoader.cpp"; path = "../../JuceLibraryCode/modules/juce_graphics/image_formats/juce_JPEGLoader.cpp"; sourceTree = "SOURCE_ROOT"; }; - F3331BEC83A436D9CB3B9131 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_osx_MessageQueue.h"; path = "../../JuceLibraryCode/modules/juce_events/native/juce_osx_MessageQueue.h"; sourceTree = "SOURCE_ROOT"; }; - F347EE9BC419DB1879790131 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ApplicationProperties.h"; path = "../../JuceLibraryCode/modules/juce_data_structures/app_properties/juce_ApplicationProperties.h"; sourceTree = "SOURCE_ROOT"; }; - F3D6E8D0058A92DE17677894 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_ios_Windowing.mm"; path = "../../JuceLibraryCode/modules/juce_gui_basics/native/juce_ios_Windowing.mm"; sourceTree = "SOURCE_ROOT"; }; - F3DD16E9AF302F242F3D4DBD = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MidiMessage.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_basics/midi/juce_MidiMessage.cpp"; sourceTree = "SOURCE_ROOT"; }; - F42A363007434541AFC1A7A0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DrawableComposite.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/drawables/juce_DrawableComposite.h"; sourceTree = "SOURCE_ROOT"; }; - F44CADD7FDE536377851F6AF = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_TextEditor.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/widgets/juce_TextEditor.cpp"; sourceTree = "SOURCE_ROOT"; }; - F4666836A0E1D98969BF95D0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_ios_UIViewComponent.mm"; path = "../../JuceLibraryCode/modules/juce_gui_extra/native/juce_ios_UIViewComponent.mm"; sourceTree = "SOURCE_ROOT"; }; - F46EB82569549C07A8D04D15 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ToolbarItemPalette.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/widgets/juce_ToolbarItemPalette.h"; sourceTree = "SOURCE_ROOT"; }; - F47A2859B6F0F7800D4FFDAA = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DropShadower.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/misc/juce_DropShadower.h"; sourceTree = "SOURCE_ROOT"; }; - F4DEDFEDF1B16C6C48075EFE = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ChangeBroadcaster.h"; path = "../../JuceLibraryCode/modules/juce_events/broadcasters/juce_ChangeBroadcaster.h"; sourceTree = "SOURCE_ROOT"; }; - F5254F504B56AF6605CBF0EF = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_IIRFilter.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_basics/effects/juce_IIRFilter.cpp"; sourceTree = "SOURCE_ROOT"; }; - F56A1C13CA4FCF50685C2335 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_audio_devices.h"; path = "../../JuceLibraryCode/modules/juce_audio_devices/juce_audio_devices.h"; sourceTree = "SOURCE_ROOT"; }; - F6A17F1B8D8330F6E8DF225B = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ComponentListener.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/components/juce_ComponentListener.h"; sourceTree = "SOURCE_ROOT"; }; - F70EA6F5AF8259555E8A80C2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_PropertySet.cpp"; path = "../../JuceLibraryCode/modules/juce_core/containers/juce_PropertySet.cpp"; sourceTree = "SOURCE_ROOT"; }; - F71DF877F3D13B350F01DFEA = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FileLogger.cpp"; path = "../../JuceLibraryCode/modules/juce_core/logging/juce_FileLogger.cpp"; sourceTree = "SOURCE_ROOT"; }; - F790D306D54E1295F9C7F9E1 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_Clipboard.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/native/juce_linux_Clipboard.cpp"; sourceTree = "SOURCE_ROOT"; }; - F79AAA52220D91666D8B8771 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_Network.cpp"; path = "../../JuceLibraryCode/modules/juce_core/native/juce_win32_Network.cpp"; sourceTree = "SOURCE_ROOT"; }; + B5142BDA7EBA15F2DB1BB3FA = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ToneGeneratorAudioSource.cpp"; path = "../../../../modules/juce_audio_basics/sources/juce_ToneGeneratorAudioSource.cpp"; sourceTree = "SOURCE_ROOT"; }; + B6173E37D15602163B7C0441 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioIODeviceType.cpp"; path = "../../../../modules/juce_audio_devices/audio_io/juce_AudioIODeviceType.cpp"; sourceTree = "SOURCE_ROOT"; }; + B6411B03A6D0185B11DBDA15 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioSourcePlayer.h"; path = "../../../../modules/juce_audio_devices/sources/juce_AudioSourcePlayer.h"; sourceTree = "SOURCE_ROOT"; }; + BC02503FFF515269351DF89B = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MidiInput.h"; path = "../../../../modules/juce_audio_devices/midi_io/juce_MidiInput.h"; sourceTree = "SOURCE_ROOT"; }; + BDA5B0C014F6DCC188465060 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_BufferedInputStream.h"; path = "../../../../modules/juce_core/streams/juce_BufferedInputStream.h"; sourceTree = "SOURCE_ROOT"; }; + BDE0C2D342D03C389560501F = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioCDReader.h"; path = "../../../../modules/juce_audio_devices/audio_cd/juce_AudioCDReader.h"; sourceTree = "SOURCE_ROOT"; }; + BE64EDA4F7260D2D5B7E0410 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_osx_ObjCHelpers.h"; path = "../../../../modules/juce_core/native/juce_osx_ObjCHelpers.h"; sourceTree = "SOURCE_ROOT"; }; + BEC8EC4C23F9AA5C8DFEA15A = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_PathIterator.h"; path = "../../../../modules/juce_graphics/geometry/juce_PathIterator.h"; sourceTree = "SOURCE_ROOT"; }; + BF40FF2E0FA609212C849FBC = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DocumentWindow.cpp"; path = "../../../../modules/juce_gui_basics/windows/juce_DocumentWindow.cpp"; sourceTree = "SOURCE_ROOT"; }; + BFBF32B0E491C9D4527DF9A6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_EdgeTable.h"; path = "../../../../modules/juce_graphics/geometry/juce_EdgeTable.h"; sourceTree = "SOURCE_ROOT"; }; + C1070E62B763F1CCE0BB18F0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_audio_basics.mm"; path = "../../../../modules/juce_audio_basics/juce_audio_basics.mm"; sourceTree = "SOURCE_ROOT"; }; + C186342C3FFB4DE250556D70 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_android_SystemStats.cpp"; path = "../../../../modules/juce_core/native/juce_android_SystemStats.cpp"; sourceTree = "SOURCE_ROOT"; }; + C296F214D5B65857DC3DA585 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_GlowEffect.cpp"; path = "../../../../modules/juce_graphics/effects/juce_GlowEffect.cpp"; sourceTree = "SOURCE_ROOT"; }; + C45AB95F4CDF31A41199E6D4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_NSViewComponent.h"; path = "../../../../modules/juce_gui_extra/embedding/juce_NSViewComponent.h"; sourceTree = "SOURCE_ROOT"; }; + C551CC8801B93AC70F6E4F76 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FilenameComponent.h"; path = "../../../../modules/juce_gui_basics/filebrowser/juce_FilenameComponent.h"; sourceTree = "SOURCE_ROOT"; }; + C6CD42F1DA2F444A59CD4AF0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_CustomTypeface.cpp"; path = "../../../../modules/juce_graphics/fonts/juce_CustomTypeface.cpp"; sourceTree = "SOURCE_ROOT"; }; + C73B4B312C3A4CE4F8E742C2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_GlyphArrangement.cpp"; path = "../../../../modules/juce_graphics/fonts/juce_GlyphArrangement.cpp"; sourceTree = "SOURCE_ROOT"; }; + C776DAD938AD7E1207DBCEEB = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Colours.h"; path = "../../../../modules/juce_graphics/colour/juce_Colours.h"; sourceTree = "SOURCE_ROOT"; }; + C7D5A8B28D0B7DE58629AA04 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Colour.cpp"; path = "../../../../modules/juce_graphics/colour/juce_Colour.cpp"; sourceTree = "SOURCE_ROOT"; }; + C884444C380A4B053DB70D12 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_DirectWriteTypeface.cpp"; path = "../../../../modules/juce_graphics/native/juce_win32_DirectWriteTypeface.cpp"; sourceTree = "SOURCE_ROOT"; }; + C8A5AD5503F33596C4147ACB = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MouseListener.h"; path = "../../../../modules/juce_gui_basics/mouse/juce_MouseListener.h"; sourceTree = "SOURCE_ROOT"; }; + C8F82FBA1E0EF7EEA5BD02B9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ConcertinaPanel.cpp"; path = "../../../../modules/juce_gui_basics/layout/juce_ConcertinaPanel.cpp"; sourceTree = "SOURCE_ROOT"; }; + C9A25E2EF32224159B617D5E = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MenuBarComponent.cpp"; path = "../../../../modules/juce_gui_basics/menus/juce_MenuBarComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; + C9BA40AFF2AD427CE4D480D7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_win32_ComSmartPtr.h"; path = "../../../../modules/juce_core/native/juce_win32_ComSmartPtr.h"; sourceTree = "SOURCE_ROOT"; }; + CB4D4DA89BA649D3F1B2A645 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TextButton.h"; path = "../../../../modules/juce_gui_basics/buttons/juce_TextButton.h"; sourceTree = "SOURCE_ROOT"; }; + CB5874E2A70E8A6A01FE8C9F = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_Network.cpp"; path = "../../../../modules/juce_core/native/juce_win32_Network.cpp"; sourceTree = "SOURCE_ROOT"; }; + CC0B7738BD544B955D81BF1E = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_events.mm"; path = "../../../../modules/juce_events/juce_events.mm"; sourceTree = "SOURCE_ROOT"; }; + CC3F295E9D9E5863779F9ACD = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ComponentBuilder.cpp"; path = "../../../../modules/juce_gui_basics/layout/juce_ComponentBuilder.cpp"; sourceTree = "SOURCE_ROOT"; }; + CC4B3BCEE612C95F27680EA9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_CPlusPlusCodeTokeniser.cpp"; path = "../../../../modules/juce_gui_extra/code_editor/juce_CPlusPlusCodeTokeniser.cpp"; sourceTree = "SOURCE_ROOT"; }; + CC8F24C4E5FC5C12AA30F6CF = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DragAndDropTarget.h"; path = "../../../../modules/juce_gui_basics/mouse/juce_DragAndDropTarget.h"; sourceTree = "SOURCE_ROOT"; }; + CC96E8E65FDFE4376F71D7B0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_OpenGLPixelFormat.cpp"; path = "../../../../modules/juce_opengl/opengl/juce_OpenGLPixelFormat.cpp"; sourceTree = "SOURCE_ROOT"; }; + CCEBEEF441D3FCFE411AAAD6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_android_Threads.cpp"; path = "../../../../modules/juce_core/native/juce_android_Threads.cpp"; sourceTree = "SOURCE_ROOT"; }; + CD3A68C29B7A733E5954BDA3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MarkerList.h"; path = "../../../../modules/juce_gui_basics/positioning/juce_MarkerList.h"; sourceTree = "SOURCE_ROOT"; }; + CD405182963BEB73FB9E368D = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_SystemStats.mm"; path = "../../../../modules/juce_core/native/juce_mac_SystemStats.mm"; sourceTree = "SOURCE_ROOT"; }; + CD4803D5DD14A33CF5AA9FDE = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OggVorbisAudioFormat.h"; path = "../../../../modules/juce_audio_formats/codecs/juce_OggVorbisAudioFormat.h"; sourceTree = "SOURCE_ROOT"; }; + CD965406DB7511EB187919E7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_NotificationType.h"; path = "../../../../modules/juce_events/messages/juce_NotificationType.h"; sourceTree = "SOURCE_ROOT"; }; + CDFAC8C57A364EEE32CE125E = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OpenGLContext.h"; path = "../../../../modules/juce_opengl/opengl/juce_OpenGLContext.h"; sourceTree = "SOURCE_ROOT"; }; + CE0CE24264C96E86062E0250 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_BubbleMessageComponent.h"; path = "../../../../modules/juce_gui_extra/misc/juce_BubbleMessageComponent.h"; sourceTree = "SOURCE_ROOT"; }; + CE19308F9CD1B8F05E6EF6C5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_RelativeTime.h"; path = "../../../../modules/juce_core/time/juce_RelativeTime.h"; sourceTree = "SOURCE_ROOT"; }; + CE4F0A27AAADFD53316A17BC = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DrawableImage.h"; path = "../../../../modules/juce_gui_basics/drawables/juce_DrawableImage.h"; sourceTree = "SOURCE_ROOT"; }; + CE75A83F0AA70025C36151B1 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MidiOutput.h"; path = "../../../../modules/juce_audio_devices/midi_io/juce_MidiOutput.h"; sourceTree = "SOURCE_ROOT"; }; + CEC05A60A0E19B07F6A3CE6B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Drawable.cpp"; path = "../../../../modules/juce_gui_basics/drawables/juce_Drawable.cpp"; sourceTree = "SOURCE_ROOT"; }; + CF4DDBE1126E8C8C3A37DC78 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AffineTransform.cpp"; path = "../../../../modules/juce_graphics/geometry/juce_AffineTransform.cpp"; sourceTree = "SOURCE_ROOT"; }; + CF4E3CDCC9837C7E52197686 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OpenGL_osx.h"; path = "../../../../modules/juce_opengl/native/juce_OpenGL_osx.h"; sourceTree = "SOURCE_ROOT"; }; + CFF4FDD0FC27C36843B20BFC = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Primes.h"; path = "../../../../modules/juce_cryptography/encryption/juce_Primes.h"; sourceTree = "SOURCE_ROOT"; }; + D00157FA3D14BFECB7FE7232 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DrawablePath.cpp"; path = "../../../../modules/juce_gui_basics/drawables/juce_DrawablePath.cpp"; sourceTree = "SOURCE_ROOT"; }; + D01D74EE9A00B0813B00FDD1 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_StretchableLayoutResizerBar.cpp"; path = "../../../../modules/juce_gui_basics/layout/juce_StretchableLayoutResizerBar.cpp"; sourceTree = "SOURCE_ROOT"; }; + D07A5399F09462A5D7041225 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_KeyboardFocusTraverser.h"; path = "../../../../modules/juce_gui_basics/keyboard/juce_KeyboardFocusTraverser.h"; sourceTree = "SOURCE_ROOT"; }; + D0A5B1AE7B7B56633AF2D5E2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_LowLevelGraphicsPostScriptRenderer.cpp"; path = "../../../../modules/juce_graphics/contexts/juce_LowLevelGraphicsPostScriptRenderer.cpp"; sourceTree = "SOURCE_ROOT"; }; + D0AFF0790D81DB8F66173737 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_SubregionStream.h"; path = "../../../../modules/juce_core/streams/juce_SubregionStream.h"; sourceTree = "SOURCE_ROOT"; }; + D0B5B79546163A6DE73D0E2E = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ImageButton.cpp"; path = "../../../../modules/juce_gui_basics/buttons/juce_ImageButton.cpp"; sourceTree = "SOURCE_ROOT"; }; + D1000A39817E9B771A4FB856 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioFormatWriter.h"; path = "../../../../modules/juce_audio_formats/format/juce_AudioFormatWriter.h"; sourceTree = "SOURCE_ROOT"; }; + D10497F87C560FA833756730 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_TemporaryFile.cpp"; path = "../../../../modules/juce_core/files/juce_TemporaryFile.cpp"; sourceTree = "SOURCE_ROOT"; }; + D104C8636576DFE8A2D11430 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_gui_basics.h"; path = "../../../../modules/juce_gui_basics/juce_gui_basics.h"; sourceTree = "SOURCE_ROOT"; }; + D108D5FFE66F80627621DCA0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_OggVorbisAudioFormat.cpp"; path = "../../../../modules/juce_audio_formats/codecs/juce_OggVorbisAudioFormat.cpp"; sourceTree = "SOURCE_ROOT"; }; + D11D931DAED4F636E8A60264 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ChildProcess.h"; path = "../../../../modules/juce_core/threads/juce_ChildProcess.h"; sourceTree = "SOURCE_ROOT"; }; + D12F8398C3EA9BA0FA88B5CF = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DynamicObject.cpp"; path = "../../../../modules/juce_core/containers/juce_DynamicObject.cpp"; sourceTree = "SOURCE_ROOT"; }; + D19705FE67C941DA74C31A9D = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_XmlDocument.h"; path = "../../../../modules/juce_core/xml/juce_XmlDocument.h"; sourceTree = "SOURCE_ROOT"; }; + D219A10E7C41110A1AA4FBB9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_Messaging.cpp"; path = "../../../../modules/juce_events/native/juce_win32_Messaging.cpp"; sourceTree = "SOURCE_ROOT"; }; + D26821159E190113FEBF99BA = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ApplicationCommandManager.cpp"; path = "../../../../modules/juce_gui_basics/commands/juce_ApplicationCommandManager.cpp"; sourceTree = "SOURCE_ROOT"; }; + D298D1DE4D2FE281CA30910C = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MidiOutput.cpp"; path = "../../../../modules/juce_audio_devices/midi_io/juce_MidiOutput.cpp"; sourceTree = "SOURCE_ROOT"; }; + D2A5F78D0EF37F1E45DF39D4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CodeTokeniser.h"; path = "../../../../modules/juce_gui_extra/code_editor/juce_CodeTokeniser.h"; sourceTree = "SOURCE_ROOT"; }; + D3B4D56DE3F90D9A445A47A6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_data_structures.h"; path = "../../../../modules/juce_data_structures/juce_data_structures.h"; sourceTree = "SOURCE_ROOT"; }; + D3C1097E92146B596194A067 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_RelativeCoordinatePositioner.h"; path = "../../../../modules/juce_gui_basics/positioning/juce_RelativeCoordinatePositioner.h"; sourceTree = "SOURCE_ROOT"; }; + D40C36493501EA97A8D1EB50 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TabbedButtonBar.h"; path = "../../../../modules/juce_gui_basics/layout/juce_TabbedButtonBar.h"; sourceTree = "SOURCE_ROOT"; }; + D4BA573C125944E2773D747F = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ApplicationCommandTarget.cpp"; path = "../../../../modules/juce_gui_basics/commands/juce_ApplicationCommandTarget.cpp"; sourceTree = "SOURCE_ROOT"; }; + D52EB7F089EF359EDCB199AF = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Logger.h"; path = "../../../../modules/juce_core/logging/juce_Logger.h"; sourceTree = "SOURCE_ROOT"; }; + D57735149DD4975283A0C754 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_module_info"; path = "../../../../modules/juce_gui_extra/juce_module_info"; sourceTree = "SOURCE_ROOT"; }; + D5C10F9CC5ADFC1B63AD1DB9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ResizableWindow.cpp"; path = "../../../../modules/juce_gui_basics/windows/juce_ResizableWindow.cpp"; sourceTree = "SOURCE_ROOT"; }; + D5EC3B41088855C3D481A73E = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MarkerList.cpp"; path = "../../../../modules/juce_gui_basics/positioning/juce_MarkerList.cpp"; sourceTree = "SOURCE_ROOT"; }; + D64B71F992FF01CB0EE89641 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Decibels.h"; path = "../../../../modules/juce_audio_basics/effects/juce_Decibels.h"; sourceTree = "SOURCE_ROOT"; }; + D6D37626671B0FB1CE8505C9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_URL.cpp"; path = "../../../../modules/juce_core/network/juce_URL.cpp"; sourceTree = "SOURCE_ROOT"; }; + D6ECAF8B2A4E8B6C97B89FFE = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CharPointer_UTF32.h"; path = "../../../../modules/juce_core/text/juce_CharPointer_UTF32.h"; sourceTree = "SOURCE_ROOT"; }; + D763221FDA235D75039D4C46 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_AudioCDReader.cpp"; path = "../../../../modules/juce_audio_devices/native/juce_win32_AudioCDReader.cpp"; sourceTree = "SOURCE_ROOT"; }; + D7C8F6360C455C0F76E35978 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ActionListener.h"; path = "../../../../modules/juce_events/broadcasters/juce_ActionListener.h"; sourceTree = "SOURCE_ROOT"; }; + D7E612935BA192BF5D24B9A3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DirectoryContentsDisplayComponent.cpp"; path = "../../../../modules/juce_gui_basics/filebrowser/juce_DirectoryContentsDisplayComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; + D80EEBBDEC364958AE05AFFB = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CoreAudioFormat.h"; path = "../../../../modules/juce_audio_formats/codecs/juce_CoreAudioFormat.h"; sourceTree = "SOURCE_ROOT"; }; + D8256B8AA794F43A2259638A = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FileBrowserListener.h"; path = "../../../../modules/juce_gui_basics/filebrowser/juce_FileBrowserListener.h"; sourceTree = "SOURCE_ROOT"; }; + D886106C60A496E47C48AFB4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Viewport.cpp"; path = "../../../../modules/juce_gui_basics/layout/juce_Viewport.cpp"; sourceTree = "SOURCE_ROOT"; }; + D8BAA82AC820CEF315BD9DCB = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_gui_extra.mm"; path = "../../../../modules/juce_gui_extra/juce_gui_extra.mm"; sourceTree = "SOURCE_ROOT"; }; + D949A0753DEE4B4AACDDA3AF = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ReferenceCountedArray.h"; path = "../../../../modules/juce_core/containers/juce_ReferenceCountedArray.h"; sourceTree = "SOURCE_ROOT"; }; + D9FAC914CA572410C055D109 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_String.h"; path = "../../../../modules/juce_core/text/juce_String.h"; sourceTree = "SOURCE_ROOT"; }; + DA353BCF838D64BA343AC0E1 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_module_info"; path = "../../../../modules/juce_core/juce_module_info"; sourceTree = "SOURCE_ROOT"; }; + DA9671908F37549C583C61E5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_BufferingAudioSource.cpp"; path = "../../../../modules/juce_audio_basics/sources/juce_BufferingAudioSource.cpp"; sourceTree = "SOURCE_ROOT"; }; + DA98B32DCA0DEF0113C22F9A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MenuBarModel.cpp"; path = "../../../../modules/juce_gui_basics/menus/juce_MenuBarModel.cpp"; sourceTree = "SOURCE_ROOT"; }; + DAB059DA13868A81301513F7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_PlatformDefs.h"; path = "../../../../modules/juce_core/system/juce_PlatformDefs.h"; sourceTree = "SOURCE_ROOT"; }; + DAC4442F8C2F142270E92349 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TextPropertyComponent.h"; path = "../../../../modules/juce_gui_basics/properties/juce_TextPropertyComponent.h"; sourceTree = "SOURCE_ROOT"; }; + DB1C6393173661404927B4B7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_GZIPCompressorOutputStream.cpp"; path = "../../../../modules/juce_core/zip/juce_GZIPCompressorOutputStream.cpp"; sourceTree = "SOURCE_ROOT"; }; + DB4AC9766332105669D51C1E = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Message.h"; path = "../../../../modules/juce_events/messages/juce_Message.h"; sourceTree = "SOURCE_ROOT"; }; + DBB34599E380FB1F37A28B27 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MultiDocumentPanel.h"; path = "../../../../modules/juce_gui_basics/layout/juce_MultiDocumentPanel.h"; sourceTree = "SOURCE_ROOT"; }; + DBDED1D6237A21D03E68D323 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_SystemTrayIcon.cpp"; path = "../../../../modules/juce_gui_extra/native/juce_win32_SystemTrayIcon.cpp"; sourceTree = "SOURCE_ROOT"; }; + DBFBBC58ED4A18EA9FE04D1D = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_URL.h"; path = "../../../../modules/juce_core/network/juce_URL.h"; sourceTree = "SOURCE_ROOT"; }; + DC3B995E7B51FC0B76826C86 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_android_Misc.cpp"; path = "../../../../modules/juce_core/native/juce_android_Misc.cpp"; sourceTree = "SOURCE_ROOT"; }; + DC6461EF11D5745DF8C00E16 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AlertWindow.h"; path = "../../../../modules/juce_gui_basics/windows/juce_AlertWindow.h"; sourceTree = "SOURCE_ROOT"; }; + DC66DC84909A3802527414C2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ComponentMovementWatcher.cpp"; path = "../../../../modules/juce_gui_basics/layout/juce_ComponentMovementWatcher.cpp"; sourceTree = "SOURCE_ROOT"; }; + DC94270BB4A70056907C3CDD = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Quaternion.h"; path = "../../../../modules/juce_opengl/geometry/juce_Quaternion.h"; sourceTree = "SOURCE_ROOT"; }; + DD03B6CE6F750A9CECA7EDEA = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_CameraDevice.cpp"; path = "../../../../modules/juce_video/capture/juce_CameraDevice.cpp"; sourceTree = "SOURCE_ROOT"; }; + DD19124F0A7FD43F31BDEB87 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_audio_devices.mm"; path = "../../../../modules/juce_audio_devices/juce_audio_devices.mm"; sourceTree = "SOURCE_ROOT"; }; + DD2007C851B70E2C71171145 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_NamedValueSet.cpp"; path = "../../../../modules/juce_core/containers/juce_NamedValueSet.cpp"; sourceTree = "SOURCE_ROOT"; }; + DD73087B002B1DB6B90B666E = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_InterprocessConnection.h"; path = "../../../../modules/juce_events/interprocess/juce_InterprocessConnection.h"; sourceTree = "SOURCE_ROOT"; }; + DE1943CA08D7FAB2E3EC0A14 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Line.h"; path = "../../../../modules/juce_graphics/geometry/juce_Line.h"; sourceTree = "SOURCE_ROOT"; }; + DE4C0926D2EFA7649BD3AAA5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TimeSliceThread.h"; path = "../../../../modules/juce_core/threads/juce_TimeSliceThread.h"; sourceTree = "SOURCE_ROOT"; }; + DE4DC23FAE4C420D489ABD17 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ImageFileFormat.h"; path = "../../../../modules/juce_graphics/images/juce_ImageFileFormat.h"; sourceTree = "SOURCE_ROOT"; }; + DEEA654926310D5B37A191C9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FileLogger.cpp"; path = "../../../../modules/juce_core/logging/juce_FileLogger.cpp"; sourceTree = "SOURCE_ROOT"; }; + DFAD61F886BEAAAE535BBF81 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ZipFile.h"; path = "../../../../modules/juce_core/zip/juce_ZipFile.h"; sourceTree = "SOURCE_ROOT"; }; + DFC58448ADEA2B5D2FF5F8D3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioTransportSource.h"; path = "../../../../modules/juce_audio_devices/sources/juce_AudioTransportSource.h"; sourceTree = "SOURCE_ROOT"; }; + DFD9E836DB24F4DE75A94C29 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FileInputStream.h"; path = "../../../../modules/juce_core/files/juce_FileInputStream.h"; sourceTree = "SOURCE_ROOT"; }; + E0A44ED2A465E22D93420F88 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_Network.mm"; path = "../../../../modules/juce_core/native/juce_mac_Network.mm"; sourceTree = "SOURCE_ROOT"; }; + E0EF847C7052C5FFA2A7CF8B = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_PreferencesPanel.h"; path = "../../../../modules/juce_gui_extra/misc/juce_PreferencesPanel.h"; sourceTree = "SOURCE_ROOT"; }; + E0FCA8F19A081CE941B273FA = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_CameraDevice.mm"; path = "../../../../modules/juce_video/native/juce_mac_CameraDevice.mm"; sourceTree = "SOURCE_ROOT"; }; + E109BFE0F2475C97F17CA5AF = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_cryptography.h"; path = "../../../../modules/juce_cryptography/juce_cryptography.h"; sourceTree = "SOURCE_ROOT"; }; + E13860F17C7FC399EF28EC1A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_KeyPress.cpp"; path = "../../../../modules/juce_gui_basics/keyboard/juce_KeyPress.cpp"; sourceTree = "SOURCE_ROOT"; }; + E1868998BA7B20DF7ED0B5E1 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_ios_UIViewComponentPeer.mm"; path = "../../../../modules/juce_gui_basics/native/juce_ios_UIViewComponentPeer.mm"; sourceTree = "SOURCE_ROOT"; }; + E1A153E1CA08E918F65C2B4D = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioFormatReader.cpp"; path = "../../../../modules/juce_audio_formats/format/juce_AudioFormatReader.cpp"; sourceTree = "SOURCE_ROOT"; }; + E1AC4AB03052A8F3FF90FBA4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Atomic.h"; path = "../../../../modules/juce_core/memory/juce_Atomic.h"; sourceTree = "SOURCE_ROOT"; }; + E21A45155C6954C6E50CCAF6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_PerformanceCounter.h"; path = "../../../../modules/juce_core/time/juce_PerformanceCounter.h"; sourceTree = "SOURCE_ROOT"; }; + E2307A386F9B96576696354B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ComponentListener.cpp"; path = "../../../../modules/juce_gui_basics/components/juce_ComponentListener.cpp"; sourceTree = "SOURCE_ROOT"; }; + E29A372A41F835609F81CC43 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_SystemTrayIconComponent.cpp"; path = "../../../../modules/juce_gui_extra/misc/juce_SystemTrayIconComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; + E2E3FA0BA7B7C8EB3C47B642 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioProcessor.cpp"; path = "../../../../modules/juce_audio_processors/processors/juce_AudioProcessor.cpp"; sourceTree = "SOURCE_ROOT"; }; + E323EAC836E3B5BB29B6AE06 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioPluginInstance.h"; path = "../../../../modules/juce_audio_processors/processors/juce_AudioPluginInstance.h"; sourceTree = "SOURCE_ROOT"; }; + E40FB3B047D27337B9A9CACA = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_XmlElement.h"; path = "../../../../modules/juce_core/xml/juce_XmlElement.h"; sourceTree = "SOURCE_ROOT"; }; + E443717EB8EC16A0B1814BAC = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FileFilter.cpp"; path = "../../../../modules/juce_core/files/juce_FileFilter.cpp"; sourceTree = "SOURCE_ROOT"; }; + E4D5FB6A6F806D9400BBF344 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_NamedValueSet.h"; path = "../../../../modules/juce_core/containers/juce_NamedValueSet.h"; sourceTree = "SOURCE_ROOT"; }; + E57F103FCFDEE26617E3F8F2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FlacAudioFormat.h"; path = "../../../../modules/juce_audio_formats/codecs/juce_FlacAudioFormat.h"; sourceTree = "SOURCE_ROOT"; }; + E587838C598E06E7959F2A31 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_AudioUnitPluginFormat.mm"; path = "../../../../modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.mm"; sourceTree = "SOURCE_ROOT"; }; + E5918150BDBDBCC3060C9FB3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_InputStream.h"; path = "../../../../modules/juce_core/streams/juce_InputStream.h"; sourceTree = "SOURCE_ROOT"; }; + E5AF1F5B3F7F2B30606FBF24 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioFormatReader.h"; path = "../../../../modules/juce_audio_formats/format/juce_AudioFormatReader.h"; sourceTree = "SOURCE_ROOT"; }; + E5B323382721E0B714F5D805 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioProcessorEditor.cpp"; path = "../../../../modules/juce_audio_processors/processors/juce_AudioProcessorEditor.cpp"; sourceTree = "SOURCE_ROOT"; }; + E5B84D5F7CF2B74715EEF3B3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ToolbarItemComponent.cpp"; path = "../../../../modules/juce_gui_basics/widgets/juce_ToolbarItemComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; + E652F16998FA1CBF2068C6FC = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_VSTPluginFormat.h"; path = "../../../../modules/juce_audio_processors/format_types/juce_VSTPluginFormat.h"; sourceTree = "SOURCE_ROOT"; }; + E6BA3A4991987C4AB55F5948 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ArrowButton.h"; path = "../../../../modules/juce_gui_basics/buttons/juce_ArrowButton.h"; sourceTree = "SOURCE_ROOT"; }; + E6D8902FFF0C8CDBB3E4BEA3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_BubbleComponent.cpp"; path = "../../../../modules/juce_gui_basics/misc/juce_BubbleComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; + E6E99E6E9BB715D12B35AB4A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_LADSPAPluginFormat.cpp"; path = "../../../../modules/juce_audio_processors/format_types/juce_LADSPAPluginFormat.cpp"; sourceTree = "SOURCE_ROOT"; }; + E70034BF5EF1721B245C3079 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AsyncUpdater.h"; path = "../../../../modules/juce_events/broadcasters/juce_AsyncUpdater.h"; sourceTree = "SOURCE_ROOT"; }; + E7488E12D0F3300AE33E0B9E = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_GlowEffect.h"; path = "../../../../modules/juce_graphics/effects/juce_GlowEffect.h"; sourceTree = "SOURCE_ROOT"; }; + E7EC04A96E1CBFA9428A4B80 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DynamicLibrary.h"; path = "../../../../modules/juce_core/threads/juce_DynamicLibrary.h"; sourceTree = "SOURCE_ROOT"; }; + E958ECCACCCE70690FAE58B9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ImageComponent.h"; path = "../../../../modules/juce_gui_basics/widgets/juce_ImageComponent.h"; sourceTree = "SOURCE_ROOT"; }; + E973909AF8AFFB788A250CB6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ArrayAllocationBase.h"; path = "../../../../modules/juce_core/containers/juce_ArrayAllocationBase.h"; sourceTree = "SOURCE_ROOT"; }; + E9A4C91E94B6D096BD8217D7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ThreadWithProgressWindow.h"; path = "../../../../modules/juce_gui_basics/windows/juce_ThreadWithProgressWindow.h"; sourceTree = "SOURCE_ROOT"; }; + E9C249D9F38B0DFAF0823653 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_android_GraphicsContext.cpp"; path = "../../../../modules/juce_graphics/native/juce_android_GraphicsContext.cpp"; sourceTree = "SOURCE_ROOT"; }; + EA13B2FC256C7BCF0900369E = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TooltipWindow.h"; path = "../../../../modules/juce_gui_basics/windows/juce_TooltipWindow.h"; sourceTree = "SOURCE_ROOT"; }; + EA5874F225E76DED69BD7132 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CriticalSection.h"; path = "../../../../modules/juce_core/threads/juce_CriticalSection.h"; sourceTree = "SOURCE_ROOT"; }; + EA749A33B0E635F691A42C64 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Sampler.h"; path = "../../../../modules/juce_audio_formats/sampler/juce_Sampler.h"; sourceTree = "SOURCE_ROOT"; }; + EA779F8A580E3D22A7CBD51E = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ImageComponent.cpp"; path = "../../../../modules/juce_gui_basics/widgets/juce_ImageComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; + EAAFB86397B191FF3713155B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_XmlElement.cpp"; path = "../../../../modules/juce_core/xml/juce_XmlElement.cpp"; sourceTree = "SOURCE_ROOT"; }; + EBC4E11E36D206EDF01E6EB0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_LowLevelGraphicsContext.h"; path = "../../../../modules/juce_graphics/contexts/juce_LowLevelGraphicsContext.h"; sourceTree = "SOURCE_ROOT"; }; + EBD6F8CE3122B2AA015A62BB = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_PluginDirectoryScanner.h"; path = "../../../../modules/juce_audio_processors/scanning/juce_PluginDirectoryScanner.h"; sourceTree = "SOURCE_ROOT"; }; + EBDC0E12D4ED20F5DB90BC26 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Typeface.cpp"; path = "../../../../modules/juce_graphics/fonts/juce_Typeface.cpp"; sourceTree = "SOURCE_ROOT"; }; + EC11D53A4118E15738CC70BB = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_PluginDescription.cpp"; path = "../../../../modules/juce_audio_processors/processors/juce_PluginDescription.cpp"; sourceTree = "SOURCE_ROOT"; }; + EC9898734E8AFE5215705476 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OpenGL_ios.h"; path = "../../../../modules/juce_opengl/native/juce_OpenGL_ios.h"; sourceTree = "SOURCE_ROOT"; }; + ECD7A374DADD305C66141AF4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MemoryOutputStream.cpp"; path = "../../../../modules/juce_core/streams/juce_MemoryOutputStream.cpp"; sourceTree = "SOURCE_ROOT"; }; + ED5E6273C8910BF1F8CBDB9B = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MemoryBlock.h"; path = "../../../../modules/juce_core/memory/juce_MemoryBlock.h"; sourceTree = "SOURCE_ROOT"; }; + ED773069A737B4877D02DD90 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioProcessor.h"; path = "../../../../modules/juce_audio_processors/processors/juce_AudioProcessor.h"; sourceTree = "SOURCE_ROOT"; }; + ED7E17722B60B7D89188CE60 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_WeakReference.h"; path = "../../../../modules/juce_core/memory/juce_WeakReference.h"; sourceTree = "SOURCE_ROOT"; }; + ED8032A884A03337DAA1D453 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Time.cpp"; path = "../../../../modules/juce_core/time/juce_Time.cpp"; sourceTree = "SOURCE_ROOT"; }; + EE577E6ABD70D104CD83186C = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DrawableText.cpp"; path = "../../../../modules/juce_gui_basics/drawables/juce_DrawableText.cpp"; sourceTree = "SOURCE_ROOT"; }; + EEBBCD11005AE9AD87B36F32 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ApplicationBase.cpp"; path = "../../../../modules/juce_events/messages/juce_ApplicationBase.cpp"; sourceTree = "SOURCE_ROOT"; }; + EF8B8FB4B02133457562E1F4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_PropertyPanel.h"; path = "../../../../modules/juce_gui_basics/properties/juce_PropertyPanel.h"; sourceTree = "SOURCE_ROOT"; }; + EFA1E7B282EF67800F4766AE = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_Midi.cpp"; path = "../../../../modules/juce_audio_devices/native/juce_linux_Midi.cpp"; sourceTree = "SOURCE_ROOT"; }; + F0B46A9181B1707349A20399 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_BubbleComponent.h"; path = "../../../../modules/juce_gui_basics/misc/juce_BubbleComponent.h"; sourceTree = "SOURCE_ROOT"; }; + F0D54DDE8C2AD1D018A61FDB = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DrawableText.h"; path = "../../../../modules/juce_gui_basics/drawables/juce_DrawableText.h"; sourceTree = "SOURCE_ROOT"; }; + F0E4B5B18AAB82215F5C6AE1 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DropShadowEffect.h"; path = "../../../../modules/juce_graphics/effects/juce_DropShadowEffect.h"; sourceTree = "SOURCE_ROOT"; }; + F113DFEACAF2D8230F0DF5E7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_QuickTimeMovieComponent.h"; path = "../../../../modules/juce_video/playback/juce_QuickTimeMovieComponent.h"; sourceTree = "SOURCE_ROOT"; }; + F16734BCF880A8180C06018D = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_HyperlinkButton.h"; path = "../../../../modules/juce_gui_basics/buttons/juce_HyperlinkButton.h"; sourceTree = "SOURCE_ROOT"; }; + F2040E4B76F8783B471CECED = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_Fonts.cpp"; path = "../../../../modules/juce_graphics/native/juce_win32_Fonts.cpp"; sourceTree = "SOURCE_ROOT"; }; + F20F182CBEF008AA1B1BB52A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_BooleanPropertyComponent.cpp"; path = "../../../../modules/juce_gui_basics/properties/juce_BooleanPropertyComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; + F22781915698D59D4CBE984D = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ScopedPointer.h"; path = "../../../../modules/juce_core/memory/juce_ScopedPointer.h"; sourceTree = "SOURCE_ROOT"; }; + F233E88B6F2BC6906819AE6A = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ScrollBar.h"; path = "../../../../modules/juce_gui_basics/layout/juce_ScrollBar.h"; sourceTree = "SOURCE_ROOT"; }; + F257AD1B82D5595FF9C3F1CA = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_NSViewComponent.mm"; path = "../../../../modules/juce_gui_extra/native/juce_mac_NSViewComponent.mm"; sourceTree = "SOURCE_ROOT"; }; + F26953C1E056357A3DFDF35C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ToolbarItemPalette.h"; path = "../../../../modules/juce_gui_basics/widgets/juce_ToolbarItemPalette.h"; sourceTree = "SOURCE_ROOT"; }; + F2A1FCAC1825462CD568D442 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_StringRef.h"; path = "../../../../modules/juce_core/text/juce_StringRef.h"; sourceTree = "SOURCE_ROOT"; }; + F2DDCDF62D2587FB565A442A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ToggleButton.cpp"; path = "../../../../modules/juce_gui_basics/buttons/juce_ToggleButton.cpp"; sourceTree = "SOURCE_ROOT"; }; + F30876EE30580650FD17B801 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ios_Audio.cpp"; path = "../../../../modules/juce_audio_devices/native/juce_ios_Audio.cpp"; sourceTree = "SOURCE_ROOT"; }; + F3154C77D5DFCE8D71084F23 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DirectoryContentsList.h"; path = "../../../../modules/juce_gui_basics/filebrowser/juce_DirectoryContentsList.h"; sourceTree = "SOURCE_ROOT"; }; + F33B267B702055F8CE27BDB8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_StretchableObjectResizer.h"; path = "../../../../modules/juce_gui_basics/layout/juce_StretchableObjectResizer.h"; sourceTree = "SOURCE_ROOT"; }; + F34126F005008CBB1C42B68F = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FloatVectorOperations.cpp"; path = "../../../../modules/juce_audio_basics/buffers/juce_FloatVectorOperations.cpp"; sourceTree = "SOURCE_ROOT"; }; + F36959B167E88B220CF9D8FE = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_DirectWriteTypeLayout.cpp"; path = "../../../../modules/juce_graphics/native/juce_win32_DirectWriteTypeLayout.cpp"; sourceTree = "SOURCE_ROOT"; }; + F36FACCDB4B94286F6042490 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_LinkedListPointer.h"; path = "../../../../modules/juce_core/containers/juce_LinkedListPointer.h"; sourceTree = "SOURCE_ROOT"; }; + F382E14FAFF5CDEBFEA81B00 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DirectoryContentsDisplayComponent.h"; path = "../../../../modules/juce_gui_basics/filebrowser/juce_DirectoryContentsDisplayComponent.h"; sourceTree = "SOURCE_ROOT"; }; + F38F8132499ADBD3344E8449 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MouseEvent.h"; path = "../../../../modules/juce_gui_basics/mouse/juce_MouseEvent.h"; sourceTree = "SOURCE_ROOT"; }; + F3A0B8ADF39FA8F15A6D8E23 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MultiTimer.h"; path = "../../../../modules/juce_events/timers/juce_MultiTimer.h"; sourceTree = "SOURCE_ROOT"; }; + F3BD246F4283B08B1E21C75B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DeletedAtShutdown.cpp"; path = "../../../../modules/juce_events/messages/juce_DeletedAtShutdown.cpp"; sourceTree = "SOURCE_ROOT"; }; + F3C52FC514B9B3A2DFD7E3F6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioPluginFormatManager.h"; path = "../../../../modules/juce_audio_processors/format/juce_AudioPluginFormatManager.h"; sourceTree = "SOURCE_ROOT"; }; + F4454839EB930FC98D63AED3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_StringPairArray.h"; path = "../../../../modules/juce_core/text/juce_StringPairArray.h"; sourceTree = "SOURCE_ROOT"; }; + F49471EE0681DBD1115D927B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_TextDiff.cpp"; path = "../../../../modules/juce_core/text/juce_TextDiff.cpp"; sourceTree = "SOURCE_ROOT"; }; + F4A977844BD67D5C2BEFCDDC = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ImageButton.h"; path = "../../../../modules/juce_gui_basics/buttons/juce_ImageButton.h"; sourceTree = "SOURCE_ROOT"; }; + F4F618373A81FDC73AB27A91 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AnimatedPosition.h"; path = "../../../../modules/juce_gui_basics/layout/juce_AnimatedPosition.h"; sourceTree = "SOURCE_ROOT"; }; + F5091F49E07C6DF8F644BAF0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ReadWriteLock.cpp"; path = "../../../../modules/juce_core/threads/juce_ReadWriteLock.cpp"; sourceTree = "SOURCE_ROOT"; }; + F64C6AC0DC0376A80A74A82A = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TextLayout.h"; path = "../../../../modules/juce_graphics/fonts/juce_TextLayout.h"; sourceTree = "SOURCE_ROOT"; }; + F65A6A3350F6251E8BBF8CF7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MP3AudioFormat.h"; path = "../../../../modules/juce_audio_formats/codecs/juce_MP3AudioFormat.h"; sourceTree = "SOURCE_ROOT"; }; + F73B6D934AEC9887D9EBB5E2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_WindowsRegistry.h"; path = "../../../../modules/juce_core/misc/juce_WindowsRegistry.h"; sourceTree = "SOURCE_ROOT"; }; + F79ADEBA7B305354085FFB8D = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_VST3PluginFormat.cpp"; path = "../../../../modules/juce_audio_processors/format_types/juce_VST3PluginFormat.cpp"; sourceTree = "SOURCE_ROOT"; }; F7B6DBDC7439C90B4E01752E = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = Main.cpp; path = ../../Source/Main.cpp; sourceTree = "SOURCE_ROOT"; }; - F88891B88E872621E6267BF9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioSubsectionReader.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_formats/format/juce_AudioSubsectionReader.cpp"; sourceTree = "SOURCE_ROOT"; }; - F8CC801FFF5B4B004707190B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_TextDiff.cpp"; path = "../../JuceLibraryCode/modules/juce_core/text/juce_TextDiff.cpp"; sourceTree = "SOURCE_ROOT"; }; - F8E876D642B7406D7D706491 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_BlowFish.h"; path = "../../JuceLibraryCode/modules/juce_cryptography/encryption/juce_BlowFish.h"; sourceTree = "SOURCE_ROOT"; }; - F94ED23A0C2454ED44C7B53B = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FileInputSource.h"; path = "../../JuceLibraryCode/modules/juce_core/streams/juce_FileInputSource.h"; sourceTree = "SOURCE_ROOT"; }; - F9C7BCC7CD4D4FC9CDDF77A9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MultiTimer.cpp"; path = "../../JuceLibraryCode/modules/juce_events/timers/juce_MultiTimer.cpp"; sourceTree = "SOURCE_ROOT"; }; - FA4C2A6A58633E63A09EC3FB = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ToolbarItemComponent.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/widgets/juce_ToolbarItemComponent.h"; sourceTree = "SOURCE_ROOT"; }; - FB5014B315A9FB387052F4DD = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ToggleButton.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/buttons/juce_ToggleButton.cpp"; sourceTree = "SOURCE_ROOT"; }; - FBB2451FAA8812635B019B07 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_LiveConstantEditor.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_extra/misc/juce_LiveConstantEditor.cpp"; sourceTree = "SOURCE_ROOT"; }; - FBB34D0E335152A813554244 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioProcessor.h"; path = "../../JuceLibraryCode/modules/juce_audio_processors/processors/juce_AudioProcessor.h"; sourceTree = "SOURCE_ROOT"; }; - FBC39ED8BF25B886702E335B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_LookAndFeel.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel.cpp"; sourceTree = "SOURCE_ROOT"; }; - FC5A39F51E480EB25A4A2656 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DialogWindow.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/windows/juce_DialogWindow.h"; sourceTree = "SOURCE_ROOT"; }; - FCD0D87F9B7A473885F5A95E = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ComponentPeer.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/windows/juce_ComponentPeer.cpp"; sourceTree = "SOURCE_ROOT"; }; - FCD602F37104023C7B8BE2B6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DirectoryContentsDisplayComponent.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/filebrowser/juce_DirectoryContentsDisplayComponent.h"; sourceTree = "SOURCE_ROOT"; }; - FD096043D0EA583C06AEFDAC = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_IIRFilterAudioSource.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_basics/sources/juce_IIRFilterAudioSource.cpp"; sourceTree = "SOURCE_ROOT"; }; - FD596755997053D5C6F9D460 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Button.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/buttons/juce_Button.h"; sourceTree = "SOURCE_ROOT"; }; - FE00E8025F597B2AD2D00063 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Label.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/widgets/juce_Label.h"; sourceTree = "SOURCE_ROOT"; }; - FE44E4AE499848D27FB7A985 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FileBrowserComponent.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/filebrowser/juce_FileBrowserComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; - FE78C65011B44BD909EC2062 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ModalComponentManager.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/components/juce_ModalComponentManager.h"; sourceTree = "SOURCE_ROOT"; }; - FEF0FE795764A633EA32AD4C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioFormatReaderSource.h"; path = "../../JuceLibraryCode/modules/juce_audio_formats/format/juce_AudioFormatReaderSource.h"; sourceTree = "SOURCE_ROOT"; }; - FEFA7D5743E1801CB7CE041E = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_cryptography.h"; path = "../../JuceLibraryCode/modules/juce_cryptography/juce_cryptography.h"; sourceTree = "SOURCE_ROOT"; }; - FF0D0A3EFBB77DFC905FAFD8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OpenGL_linux.h"; path = "../../JuceLibraryCode/modules/juce_opengl/native/juce_OpenGL_linux.h"; sourceTree = "SOURCE_ROOT"; }; + F7E781AFAA34B511C812896A = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_UndoManager.h"; path = "../../../../modules/juce_data_structures/undomanager/juce_UndoManager.h"; sourceTree = "SOURCE_ROOT"; }; + F831631700830F81994D9980 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_StretchableObjectResizer.cpp"; path = "../../../../modules/juce_gui_basics/layout/juce_StretchableObjectResizer.cpp"; sourceTree = "SOURCE_ROOT"; }; + F83392D9825422AF0DB638D0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_Clipboard.cpp"; path = "../../../../modules/juce_gui_basics/native/juce_linux_Clipboard.cpp"; sourceTree = "SOURCE_ROOT"; }; + F838183EDFF5937C2879EE41 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_RecentlyOpenedFilesList.h"; path = "../../../../modules/juce_gui_extra/misc/juce_RecentlyOpenedFilesList.h"; sourceTree = "SOURCE_ROOT"; }; + F8EB370470B7928A80032F7C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_SHA256.h"; path = "../../../../modules/juce_cryptography/hashing/juce_SHA256.h"; sourceTree = "SOURCE_ROOT"; }; + F95533D725E548643CA584D7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_Windowing.cpp"; path = "../../../../modules/juce_gui_basics/native/juce_win32_Windowing.cpp"; sourceTree = "SOURCE_ROOT"; }; + F9609B0A0387932B86A6FABE = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_InterProcessLock.h"; path = "../../../../modules/juce_core/threads/juce_InterProcessLock.h"; sourceTree = "SOURCE_ROOT"; }; + F994D2E0DF00D0A7765068EF = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ImageCache.cpp"; path = "../../../../modules/juce_graphics/images/juce_ImageCache.cpp"; sourceTree = "SOURCE_ROOT"; }; + F9B00F8F537F74527F6C463C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_KeyMappingEditorComponent.h"; path = "../../../../modules/juce_gui_extra/misc/juce_KeyMappingEditorComponent.h"; sourceTree = "SOURCE_ROOT"; }; + FA2DB83279928FFB76A4BC6E = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_RelativeParallelogram.h"; path = "../../../../modules/juce_gui_basics/positioning/juce_RelativeParallelogram.h"; sourceTree = "SOURCE_ROOT"; }; + FAB998A70437EE4D89CABE2F = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DropShadower.cpp"; path = "../../../../modules/juce_gui_basics/misc/juce_DropShadower.cpp"; sourceTree = "SOURCE_ROOT"; }; + FAC04A1B47255DA7A6397737 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_GenericAudioProcessorEditor.h"; path = "../../../../modules/juce_audio_processors/processors/juce_GenericAudioProcessorEditor.h"; sourceTree = "SOURCE_ROOT"; }; + FAF4C6D8D1D59932F12DF6A7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Memory.h"; path = "../../../../modules/juce_core/memory/juce_Memory.h"; sourceTree = "SOURCE_ROOT"; }; + FB3BE7E3D0A04791487E9E0C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_SliderPropertyComponent.h"; path = "../../../../modules/juce_gui_basics/properties/juce_SliderPropertyComponent.h"; sourceTree = "SOURCE_ROOT"; }; + FB459E95101C8A92E5B39A67 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FileFilter.h"; path = "../../../../modules/juce_core/files/juce_FileFilter.h"; sourceTree = "SOURCE_ROOT"; }; + FB81D25CF4825A9A186B6790 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_module_info"; path = "../../../../modules/juce_data_structures/juce_module_info"; sourceTree = "SOURCE_ROOT"; }; + FBC55E440EF1EA83FC0DAA5A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_PropertiesFile.cpp"; path = "../../../../modules/juce_data_structures/app_properties/juce_PropertiesFile.cpp"; sourceTree = "SOURCE_ROOT"; }; + FBDBD56614E38BB5A5592D32 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_GZIPDecompressorInputStream.cpp"; path = "../../../../modules/juce_core/zip/juce_GZIPDecompressorInputStream.cpp"; sourceTree = "SOURCE_ROOT"; }; + FCA9526394A63B33405F8E58 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_android_Audio.cpp"; path = "../../../../modules/juce_audio_devices/native/juce_android_Audio.cpp"; sourceTree = "SOURCE_ROOT"; }; + FCC9F258531F00BCD91C63DF = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ScrollBar.cpp"; path = "../../../../modules/juce_gui_basics/layout/juce_ScrollBar.cpp"; sourceTree = "SOURCE_ROOT"; }; + FD05E73E3F022E08D70B9569 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FileSearchPathListComponent.h"; path = "../../../../modules/juce_gui_basics/filebrowser/juce_FileSearchPathListComponent.h"; sourceTree = "SOURCE_ROOT"; }; + FD1FFBCE5E94D08B6FB60F70 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ElementComparator.h"; path = "../../../../modules/juce_core/containers/juce_ElementComparator.h"; sourceTree = "SOURCE_ROOT"; }; + FD5262552A90A9DFACB3C07F = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ModifierKeys.h"; path = "../../../../modules/juce_gui_basics/keyboard/juce_ModifierKeys.h"; sourceTree = "SOURCE_ROOT"; }; + FD5E948C1A89B11770A20704 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DrawablePath.h"; path = "../../../../modules/juce_gui_basics/drawables/juce_DrawablePath.h"; sourceTree = "SOURCE_ROOT"; }; + FDA36D1F836D00DE705CD06F = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DialogWindow.cpp"; path = "../../../../modules/juce_gui_basics/windows/juce_DialogWindow.cpp"; sourceTree = "SOURCE_ROOT"; }; + FDE0D8E73B0ED8A938C99AAD = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_IIRFilter.h"; path = "../../../../modules/juce_audio_basics/effects/juce_IIRFilter.h"; sourceTree = "SOURCE_ROOT"; }; + FE1E97C9233F2D472C7C6128 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_XMLCodeTokeniser.h"; path = "../../../../modules/juce_gui_extra/code_editor/juce_XMLCodeTokeniser.h"; sourceTree = "SOURCE_ROOT"; }; + FE41044F09ABE0A6BC0F9293 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ScopedValueSetter.h"; path = "../../../../modules/juce_core/containers/juce_ScopedValueSetter.h"; sourceTree = "SOURCE_ROOT"; }; + FE55A1DFB90A1A5EF37B1741 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioFormatReaderSource.h"; path = "../../../../modules/juce_audio_formats/format/juce_AudioFormatReaderSource.h"; sourceTree = "SOURCE_ROOT"; }; + FEA645D52C593ECCEA779BAF = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Component.h"; path = "../../../../modules/juce_gui_basics/components/juce_Component.h"; sourceTree = "SOURCE_ROOT"; }; + FF1CEE8501CA0F081EE0E3AE = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioFormatManager.h"; path = "../../../../modules/juce_audio_formats/format/juce_AudioFormatManager.h"; sourceTree = "SOURCE_ROOT"; }; + FF1F4F1262BB429E80492B13 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DialogWindow.h"; path = "../../../../modules/juce_gui_basics/windows/juce_DialogWindow.h"; sourceTree = "SOURCE_ROOT"; }; FF3D4768BC96B79F49B10894 = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = Info.plist; path = Info.plist; sourceTree = "SOURCE_ROOT"; }; - FF921DEC61293D650C9BCA7B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ToolbarItemPalette.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/widgets/juce_ToolbarItemPalette.cpp"; sourceTree = "SOURCE_ROOT"; }; - FFA213182EB6CA238D01F488 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ChannelRemappingAudioSource.h"; path = "../../JuceLibraryCode/modules/juce_audio_basics/sources/juce_ChannelRemappingAudioSource.h"; sourceTree = "SOURCE_ROOT"; }; - FFAC8C8B3CC3F05E12744D1F = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FileFilter.cpp"; path = "../../JuceLibraryCode/modules/juce_core/files/juce_FileFilter.cpp"; sourceTree = "SOURCE_ROOT"; }; + FF70C4AB4F37D7C7E1668660 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_HashMap.h"; path = "../../../../modules/juce_core/containers/juce_HashMap.h"; sourceTree = "SOURCE_ROOT"; }; + FF7A26DADF1579C43D80454F = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_LocalisedStrings.cpp"; path = "../../../../modules/juce_core/text/juce_LocalisedStrings.cpp"; sourceTree = "SOURCE_ROOT"; }; 9F41B5C4D3F9CE9C17373AB3 = {isa = PBXGroup; children = ( B766DBADE0BD743FAC004870, F7B6DBDC7439C90B4E01752E, ); name = Source; sourceTree = ""; }; C69760E59D600CF000D468E8 = {isa = PBXGroup; children = ( 9F41B5C4D3F9CE9C17373AB3, ); name = AnimationAppExample; sourceTree = ""; }; 56E5D80A2B5A0AB691ABB90D = {isa = PBXGroup; children = ( - 44F0CE6E0BBCE5E596BF70A6, - 30E06EA9F94FA181A6B8F533, - 5B7A3EE41F87CB2931C1E13C, - 555BF349B10EE4EF21DCA398, - 671FF5E5EBF6920BAAA79B4E, - EA269A07CD83E9F5977889E6, ); name = buffers; sourceTree = ""; }; + AC2AE970951E20A199938AFB, + 7A46778023CF61B3F417F9AC, + AD648ADDD885B93B2EB60C88, + 6D0D0EC5B978695152A0B84F, + F34126F005008CBB1C42B68F, + 03D03AF17C5E899ED9481518, ); name = buffers; sourceTree = ""; }; 976965B1038594B4C210B247 = {isa = PBXGroup; children = ( - F150F0F13B3B18F263086336, - C1C5A9F18F63CDB9BDF32177, - 2F8345DA4FF13DA81612EBB3, - CDDD5A437DEFD1CD65160A9C, - E22876603667D88857CA5179, - CFB26A1C32F851E8DDC36BB7, - F3DD16E9AF302F242F3D4DBD, - C67D83EB019C2F931E5FF290, - 3293B0656CFCA5B2303C6E8F, - 1A491D8A6C3223CF582E050D, ); name = midi; sourceTree = ""; }; + 9F5FD873C8192683DB089745, + 5358DE9C9773654731E6F615, + 8DC827CCF543708CF729FED6, + A917646C0153D2A57E3C5677, + 95440A40B2FB3CE5E09D57B4, + 6A1D79062B92685A87BEE5F6, + 8CA01F9530AC5512C6B74325, + AC3184BE8D8804394FCCDCB6, + 8FA02AA8698232B53D4BFDBB, + 8EDD1755AEE1C95660A06BF2, ); name = midi; sourceTree = ""; }; 26A3DDC7B0D9C11EC02E6407 = {isa = PBXGroup; children = ( - 72ACB726645A64B055B59277, - F5254F504B56AF6605CBF0EF, - 90E607BA3727A053395D2A61, - D23D5618C7FFFCFD938CD5F1, - 83A10FEA76D527B4E88AD0EF, - 27D5D6CE8B6CFF40F8A5B9D0, ); name = effects; sourceTree = ""; }; + D64B71F992FF01CB0EE89641, + 1B3B7CBA0D25C83B8AF72641, + FDE0D8E73B0ED8A938C99AAD, + 0311666DB95BFAE686267D7C, + 403453363C4785FD451A9BA1, + CCA3065F893912F3E3625C13, ); name = effects; sourceTree = ""; }; FE8AB04D3B86B9666AD12C5B = {isa = PBXGroup; children = ( - D786D6FB9787CEC730CFEDD9, - 622800F19C8B24050A92D15B, - 8CD45DADF91984C72DAE7E09, - E670FE5F095BB2B7F9EB8138, - FFA213182EB6CA238D01F488, - FD096043D0EA583C06AEFDAC, - 69572C0082E358837174B04E, - 5C74D5593E152C52854A522F, - 6BC5245D8E2ACD816BA03475, - 39EFC895DB6FA253ACD83729, - A2D0912BF511B8AA5CEE9690, - D429E0F29213E9058DED8ECC, - 48403410E9FE064527EDCC85, - 213971DB941D93E214CF2153, - 3269E6F38346442BAB611D8C, - 4F73548B7300043B5CBD8853, ); name = sources; sourceTree = ""; }; + 086CE5C768CF5889BDEF8955, + DA9671908F37549C583C61E5, + 97EDCA2A04EF5ADAAD9DC594, + 4EAE69CF6B5097A57EBCD27B, + BFB12FD84F14C9B31249FC04, + 6EFC227515CACDE0F8664EC2, + 8B155ED74D3D0EB7E890E421, + 4EBC561A323AEE4D76AD7906, + 979A030D4807A573FAA18318, + 83BA5BED925F6F827DF98CA8, + 570C35930202882A634FC029, + 44B3428E8BB4B70104CD76CF, + 1D5B751294F84B86ABB11D4A, + 301AF9BA843B1955EE001C98, + B5142BDA7EBA15F2DB1BB3FA, + 3900C9B11914C94DFA1F8C33, ); name = sources; sourceTree = ""; }; 11ABF0A415636F8CD40A3097 = {isa = PBXGroup; children = ( - 2A64A444FB90EFA1B0449A67, - 53C236BFA019E49855DD8A22, ); name = synthesisers; sourceTree = ""; }; + 9D91916A769A7E2967368795, + 8C105487633A9BD04FDEE50A, ); name = synthesisers; sourceTree = ""; }; AF12826F0B38E7FC1176C648 = {isa = PBXGroup; children = ( 56E5D80A2B5A0AB691ABB90D, 976965B1038594B4C210B247, 26A3DDC7B0D9C11EC02E6407, FE8AB04D3B86B9666AD12C5B, 11ABF0A415636F8CD40A3097, - BE990C63B85752BF968C5EC6, - 2B780483D0584407FBA38106, ); name = "juce_audio_basics"; sourceTree = ""; }; + 8DEFACA6858D254B4202AF12, + 3B9903B0A0252D106C92CAA9, ); name = "juce_audio_basics"; sourceTree = ""; }; 3B35E0DA3DB0B1509311FBDF = {isa = PBXGroup; children = ( - E782C5F53BBED225CABF6587, - AB2C5E54CD675401124F26A0, - B0793B0E00A1410BD054B141, - 6F7FBB230E206816379F5C83, - 36E382ACBB77916E0A228CC0, - 730F77EEB7313A110A0B5E5F, - 716BA2221FA9658AEC00A563, ); name = "audio_io"; sourceTree = ""; }; + 884AA1209A726AEAF76E31B0, + 3D24784AEA7726A64A340625, + 4A1671B78E589A865FEA3CB1, + 62E534D1F0B31CD4A1B572E1, + B6173E37D15602163B7C0441, + 4BF9949E0C30EA64B16004BE, + 04C105672DA409FE8593DB04, ); name = "audio_io"; sourceTree = ""; }; D487CFDA56FA408A04203A20 = {isa = PBXGroup; children = ( - 112A4FE3483942AF43D513DA, - 4C699E969B418C7C5EBE4DB9, - AD6517C175A8D9D5A9D168E6, - 6F6DDA3B78AF47374B959263, - 13287EAB1073ED487FE17034, ); name = "midi_io"; sourceTree = ""; }; + BC02503FFF515269351DF89B, + A789D75FEFFFB7E8E835FBAB, + B004D25E0DC1AA2C4CD3788A, + D298D1DE4D2FE281CA30910C, + CE75A83F0AA70025C36151B1, ); name = "midi_io"; sourceTree = ""; }; C3D887B6F1284C2394FD72D3 = {isa = PBXGroup; children = ( - 40673853C7079F0A6D8AF2BB, - 438C65CF8B5C0D636F0AC715, - 376708401BCBF6D7EC1F8725, - 3619D8E6B18F0843E8EAA2A5, ); name = sources; sourceTree = ""; }; + 814E0D982BC2A18B9BAF3E38, + B6411B03A6D0185B11DBDA15, + 911B308D5222BDFD954DBB32, + DFC58448ADEA2B5D2FF5F8D3, ); name = sources; sourceTree = ""; }; 09D6686EACFD43021C0E69F3 = {isa = PBXGroup; children = ( - 9898BBBC81128203FC3934B7, - A873E57D126C8D931CE6556A, - DFD3944531485F2F72ECB87A, ); name = "audio_cd"; sourceTree = ""; }; + 41C74B59D9B392117441DA2D, + 35A7FD6EFDE29D2EBD7DFCB8, + BDE0C2D342D03C389560501F, ); name = "audio_cd"; sourceTree = ""; }; A62DE30F63767AFA483DE8C6 = {isa = PBXGroup; children = ( - 3FEFB6B506459AC93E066C3D, - EDC826A2266EC4945813EB52, - 458072B5FE996673CD03DC28, - 3CE23C91D3F26953C3BE4A86, - 37665101B192EFA4DC5DFE39, - B070645F1A6B85C679B77B21, - 538907D94243347E0BD1136A, - 675AA4F17363E5F5F8B5C307, - AA67BCD0930A0B3B9D0B12B1, - A5A2DBDF9350F91E9D6109B7, - 024386A2F47243403C1E2A51, - 117555C684D0E7FB5ADDB891, - 77EF2BBCC5853A84BB8BB561, - 740CEAD6F3EC74AEE5D29F3A, - 0654450BCEE57AB7EC882CBC, - 302960973006B86172FD4A6B, - 384CF76B2FAEB3A5E935AAD8, - 2C2E1D130B90B220D70A4D7A, - 78E95B5FD8BFF8B51994F2D8, ); name = native; sourceTree = ""; }; + FCA9526394A63B33405F8E58, + B1C799A152189A282E6CAC76, + 2A098563977566E9A9E8CD7E, + F30876EE30580650FD17B801, + 95412F7C12937CC7AC22ADCF, + B0286AC6D04C5D080A299A1C, + 32C683CBA18109949D53149A, + EFA1E7B282EF67800F4766AE, + 55417F6D23E7075E5E27BECB, + 5EB144BD6AC4D4DE96ABFCA2, + 25B41C0851C004C9D410B7C8, + 56545F3F893C3D8CC9215051, + 7AC4D7A22EE9E1F4FBD407C7, + 805F27CEEC53F4E659884D7A, + 29F5A84EE715DA5BCED467A1, + D763221FDA235D75039D4C46, + B2D42B884600CE62E3253DA3, + 5719A93B0F6AFE95FC49B673, + 73FF82BCB568578396E88C92, ); name = native; sourceTree = ""; }; 270A86F6A3CE512F0B3EA8DC = {isa = PBXGroup; children = ( 3B35E0DA3DB0B1509311FBDF, D487CFDA56FA408A04203A20, C3D887B6F1284C2394FD72D3, 09D6686EACFD43021C0E69F3, A62DE30F63767AFA483DE8C6, - 2DADD9644CFA5A770AA513A2, - F56A1C13CA4FCF50685C2335, ); name = "juce_audio_devices"; sourceTree = ""; }; + 442199479D1499B6A44BD150, + B1A41C6141726A390E2182A2, ); name = "juce_audio_devices"; sourceTree = ""; }; 72D396CB5861C9C441B3E360 = {isa = PBXGroup; children = ( - A13F9E4C92A3DD4C01330208, - 09043DFD1720837A928ECA06, - 000879A4FF2FFA74721C7CB5, - 63E5D7EEC148FF82E7216095, - 0CB666093FEE15ED3782D60C, - C98FF9CD6E5BC931F600A73D, - 2CBBEE67AE711FFD4D554623, - FEF0FE795764A633EA32AD4C, - 97984A6B910D0D4B48EFB82B, - 8DC8057B78772BA17A3ADDD1, - F88891B88E872621E6267BF9, - EB3E426C5FF655F7AD88D843, - C6111F5E51935A78B357FE2E, - 72B459EF3E90129FBD1A78EA, - A1C9C360E9B30D43246B9241, ); name = format; sourceTree = ""; }; + A76D6B94991D6E028EE8D1AA, + 0E70A4BFB2F7D1AB6188E72C, + CCF8FB3EA0246D83E3D2E760, + FF1CEE8501CA0F081EE0E3AE, + E1A153E1CA08E918F65C2B4D, + E5AF1F5B3F7F2B30606FBF24, + 853D2D1ADD05C320052DD5FC, + FE55A1DFB90A1A5EF37B1741, + B5C3814B2174E5127F42D721, + D1000A39817E9B771A4FB856, + 71DF518DE7A248B97C8E1C2E, + 6E6672E4055AC4F6D8688310, + 63E66F6D161941FE12465C29, + AD8417869D43ED72319C283C, + 9CC22BDB1B3FF427D6525D21, ); name = format; sourceTree = ""; }; 23741F076745FB046C07FB1D = {isa = PBXGroup; children = ( - 0356E85B3D1970B78228D974, - 423A70751A8C20A9E1C3E9CB, - 692A2B951D818FED7DB03481, - D2BC39EF5E34ACB2BE05539C, - 65411B7DBE47CE3DF4164F05, - 227F70FEE9D1F967CFD8DB5A, - 3413E3C25DD20925BA622640, - CBE0FA629B5B2B352EFF53D4, - B0CD0890EC1297C2C70B741B, - 40D6454C05B1D9E3242CDFC8, - 134C3956C7C8E7CF6CEE8868, - 03D53D0D12365594CC24EA4D, - 256A686F1026814DA7434C9A, - 1C96AD5E5DF22AE45779B769, - C856D47E76BE017D87E77496, - B78FA8958102108085ABE489, - 8CAF2B1BDF49EC845F183218, - DF99FBC1355728976531AD5D, ); name = codecs; sourceTree = ""; }; + AB3C130E565756182528752D, + 7F162E198ECF41AA895DB94B, + 0BC32F0BB0B5393D25E09D00, + D80EEBBDEC364958AE05AFFB, + 0AE6516868244378D09124A0, + E57F103FCFDEE26617E3F8F2, + 932126F914644642A8244676, + 1AB580D4342BFFD41F220358, + 264F684A80B93F7A189A5FA5, + F65A6A3350F6251E8BBF8CF7, + D108D5FFE66F80627621DCA0, + CD4803D5DD14A33CF5AA9FDE, + 4B27C30CF5AC7BFE0AF537AD, + 996A274720539E8497291E85, + 0D530396A7BA6BA190100C6E, + 46885692CC5FDE30FC3649F6, + C52FB75A0A93BB1397D1F962, + 4B8102606812A7964CF8D9CE, ); name = codecs; sourceTree = ""; }; EA0CB9DC4E43539FB25FBC68 = {isa = PBXGroup; children = ( - 3898B672BD3A7FDA95255349, - 98622ABC34EA3DD4334580D5, ); name = sampler; sourceTree = ""; }; + 5774E190A351EDF7B7AAB188, + EA749A33B0E635F691A42C64, ); name = sampler; sourceTree = ""; }; D8CF14F51DEE1EA3625BFE6E = {isa = PBXGroup; children = ( 72D396CB5861C9C441B3E360, 23741F076745FB046C07FB1D, EA0CB9DC4E43539FB25FBC68, - 5434B55E1B4DCA4392ADF45D, - E8E4F93EF596101FE5333018, ); name = "juce_audio_formats"; sourceTree = ""; }; + 768754211363FED3D2188C9D, + 62B6E8B6269ADEF23D85FA3E, ); name = "juce_audio_formats"; sourceTree = ""; }; 2127B046D500ADBA07220814 = {isa = PBXGroup; children = ( - B852DBE7C0AFD11AB872754A, - 94B8132DD5915F30ED7DD249, - B973B2A075C1EE23F2AEFF32, - FBB34D0E335152A813554244, - CAF194AB75BBCF7A63DFDA43, - 34A980957FE5E141693F3334, - E462CDCA6635D111D6B85C4B, - ACF10436974ED4510E3FC4BB, - 995501A12A56DED7CDAAF24B, - 23600EA94396F6E810F1C774, - 2D2048FA048F8CEF2459EF31, - 3E68E00D0D6613D6A93B3ED1, - 17CF86369ED4F4A6DFD8E44F, - B17E7CF3B375FCC6A9178500, ); name = processors; sourceTree = ""; }; + A61AD5378601F9DDEB8DED03, + E323EAC836E3B5BB29B6AE06, + E2E3FA0BA7B7C8EB3C47B642, + ED773069A737B4877D02DD90, + E5B323382721E0B714F5D805, + 40B9C2276B7EF73860E2606B, + 15029C3F041B27DD7191482F, + A8C570DF829A8B8581B4E8CC, + 2D5F3AD1A03B34AE7349DF5F, + 102919EC5BCD10DA703688CF, + 673759E656DBA5A9377433E5, + FAC04A1B47255DA7A6397737, + EC11D53A4118E15738CC70BB, + B6ABBE7782ECD38631EB11BC, ); name = processors; sourceTree = ""; }; DB8C9872311AD82A6BE28BCE = {isa = PBXGroup; children = ( - A77BB927A95DA581268CD729, - 637A70321AC8948BA9E033FD, - E39FB683ECD1152137E3853A, - 5E3AE8001BCEFBED6A1954DA, ); name = format; sourceTree = ""; }; + 8741126A9694372E46E3FD32, + 381B8B8A9D5203E73FED79E9, + 83325A69170997E33D73770A, + F3C52FC514B9B3A2DFD7E3F6, ); name = format; sourceTree = ""; }; CD61E634B4D011ABCFA7E39F = {isa = PBXGroup; children = ( - 0A431A685E635E51B2E20FB7, - 78CE05F96C7E21DEE8D6A845, - D97C2B6C906C1C179598C7CC, - 78FE5E020A7D6EB993701276, - 231F8E834F94B7654941EF55, - 0125A6E329679354E74D2FB4, - 069199E3E835739AF23FAC10, - D3DAA92A27A10FBB1AEC0966, - 849A271BDBC9A7AB9514B8CD, - 442ADB5B235BA350C5FD0BD1, - 29D6BB46D3EF49EF86612B12, ); name = "format_types"; sourceTree = ""; }; + A50AF1519D78428A8DCD91BF, + E587838C598E06E7959F2A31, + E6E99E6E9BB715D12B35AB4A, + 38EDF1EAB12A05CEE439AF23, + 36B8F6CFEEA3C1E2A0D09E56, + 2B02634F8DA8660ED42B0AEF, + F79ADEBA7B305354085FFB8D, + 66E854431C2BBDEE56EA43C8, + 0F67C59CB48583941B8656EF, + BB144FF841A99B08D5479777, + E652F16998FA1CBF2068C6FC, ); name = "format_types"; sourceTree = ""; }; 6C9E51DC570947CDBD246B3E = {isa = PBXGroup; children = ( - 5D903A277EFDDFA522C67E84, - 35F51FC31CE36BDF6D41978C, - 97E51A159B596325E90C5BE9, - 6CD9A954A84F5088471631BB, - 44DE484AE50122D19A902731, - 1BEF05EF0D439BB92AE09DE4, ); name = scanning; sourceTree = ""; }; + 0B933FCCF82100D67C0B7D34, + B7855FA22C92F7EE272A866E, + 2E650C2E92EA2732B66070D4, + EBD6F8CE3122B2AA015A62BB, + A53228473B7F7BCF946F15DF, + 88EF4C8D3A1D2498D8ADB6E0, ); name = scanning; sourceTree = ""; }; BA9B6357DA1BF8D6E3120176 = {isa = PBXGroup; children = ( 2127B046D500ADBA07220814, DB8C9872311AD82A6BE28BCE, CD61E634B4D011ABCFA7E39F, 6C9E51DC570947CDBD246B3E, - 23CC00FD68EF7CB9A64D9EED, - 17E9D0C9AC68F13FB1A763CD, ); name = "juce_audio_processors"; sourceTree = ""; }; + 3F0388309395C138AA68FAD7, + 6E841DAA09FE06910D94447D, ); name = "juce_audio_processors"; sourceTree = ""; }; 8C7AB91AFCAF2F99D0E906B0 = {isa = PBXGroup; children = ( - 52C131B4F65C596E275CC17C, - 66EFBCF1D3E6A5FF27129EC3, - 9980F9FB908ED20591475FA8, - E7C5065D5E153DFF6308D5F3, - 72CF68A2C3240BFA2EBF22AB, - 3944FFE845F494F9A625EC67, - 7EA9B430B1998ECBEF70D2E2, - 1557FF99F272F107A90B15DF, - 646046D51C5B2655CC633415, - D79EAA241B5FA1ECFB84614F, - 4128F91E323A32B6D7189CD5, - C46FC2DAD97DA825D6449A2B, - E783E1B6AEFF256939443D39, - 12967F8EBAF9698288C8A5D0, - 0A7FBABADCBBF00C2A842D37, - 8AD5A845BBCF5ED0E6AA5922, - C12AEDA7D0BE5A220AF9D30A, - 6F2E3A5DC0BE1D6917784F47, - AA251B07162ABAA59D3DF432, - 72208D4BA50D37B9764FB56A, - F8CC801FFF5B4B004707190B, - 02BE2D3F87C20BD46CEC2981, ); name = text; sourceTree = ""; }; + 5A854859042F6CD761688B25, + A42A97232CE0593D8D989FC1, + 8E407C1CF739A93FD2B3B38C, + 7AC8C094442A603DE6257BB1, + 4A86B4371AE4FC58D879962C, + D6ECAF8B2A4E8B6C97B89FFE, + 1AB9713046E08B68A6F672CF, + 22C4F82B505995F81CD682B5, + FF7A26DADF1579C43D80454F, + 916001804771DF943551AAEF, + 61797A8C01DC08E83AFA4540, + 935BCEB2593A51E53187ABC2, + D9FAC914CA572410C055D109, + 17B07A06764A6A7759804033, + 14245CED80854EC5291657FA, + 926063234BAFA6D29366E43E, + F4454839EB930FC98D63AED3, + 389B4E4055A779D0F6B22C5F, + 1450CD0879661355CD52DD8D, + F2A1FCAC1825462CD568D442, + F49471EE0681DBD1115D927B, + C0FDDD3106A13770B141E5F2, ); name = text; sourceTree = ""; }; 6898E6C42CC9520DC26F9FBF = {isa = PBXGroup; children = ( - 43BB532CBA295E02FDAC1CFA, - 80C52BD7C8AD60FC1584EDDD, - B65CD1D011475424E927B37E, - 6EDF4554CA5AA64920F95E5E, - D535D69439B72C799B61DD37, - 053C2C09700A8BD5DB4B416B, - 24006F32DA24D5C374C7442A, - BBF610446898623948599114, - 8F0BDEECFD7200A7BE6FC598, ); name = maths; sourceTree = ""; }; + BAE06A3352E39521CE5D94EB, + AD41400898312123119E987A, + A3D0C263C912566AECB57679, + AC42B6006776E1CE3A3A94A0, + 1B3CC8F665F23CB86253EBCE, + 4B8342C50F962C3F0AEE9830, + 8B7C0F839098C534A7B4C725, + B28F34DD7CABFD48B1EE3CCE, + CA025D4369C240E6FA30CE2B, ); name = maths; sourceTree = ""; }; 01A8BF73C8C9D282E9E58D7A = {isa = PBXGroup; children = ( - 6D111AFF5B12430B6A225802, - 560303C3ABFD2D8DA80F5369, - 160E2EF9685EDF05E2A5EF32, - 53972777A5EAB63C5D1DF5E5, - 08CAAD932D355E493366CEF3, - 48B1172E10D1795EFD5B4731, - AD6AAB2F586CBD4E35D5167B, - 983D92711EC4B001DEF300DF, - C18E1D4D4D0E4F6B0525C212, - 8E6D4E8672ADAA47FF421180, - E7733DCA05641E94C0714362, - D56619E400C7A4619515AFFA, - 3BC29BAC09BDF8518335571D, - 8755EB7CFA4EC3C0AEBF8E26, ); name = memory; sourceTree = ""; }; + E1AC4AB03052A8F3FF90FBA4, + 4BDEC9A0A09EEDC9D7BDB826, + 08EC867C77B028C336B79752, + 68097881EEDDE0FD03100CC5, + C0BA74AF0382D87B0E7BCEB3, + FAF4C6D8D1D59932F12DF6A7, + 8C6A342773288620A8CC2598, + ED5E6273C8910BF1F8CBDB9B, + 097237CCE04B9020343CB28D, + 61F0D5937E23A6A9EE8D479C, + F22781915698D59D4CBE984D, + 289C3977B67C1898AC3B974D, + 4A36826C3F710B92F0347A16, + ED7E17722B60B7D89188CE60, ); name = memory; sourceTree = ""; }; DD57AFE6D9A0218912B3DD93 = {isa = PBXGroup; children = ( - E508FDD5269C63F7D0E08E48, - E0DFDD144675EF457B607E50, - 3F1BEF3D596877977723184D, - D6486972C28234B51D512700, - 98ED7C529B2A40AA4C0527DD, - B53B0352EAA432B0179F0201, - 60E972163AE7F32E1AC7BF57, - 620921796E4C408487F2D19D, - A8DC0ACAAB88D6657355E466, - 358F95020BB4722C04756E09, - 6B3FA3604D7E751B8F18E841, - 48BDA8E72F3E90C3DF0F9B91, - F70EA6F5AF8259555E8A80C2, - 92901C506127F45E3F5B258E, - 4625F35561AEC875DBEF087B, - 95A59141DCE1349CC649FDB2, - 064D5359A45F91751130CB6C, - E5608726D3CC8DDCA57635BF, - 54369A3FBDBDCC0FED963610, - C609197710C7E8DF361C4556, ); name = containers; sourceTree = ""; }; + 6EEECDA2EB328FB597208954, + C7581A35068A3FB43786F4BE, + 0C89377A44F26612524DA129, + E973909AF8AFFB788A250CB6, + D12F8398C3EA9BA0FA88B5CF, + CCF94157A15DD29B6C5DA939, + FD1FFBCE5E94D08B6FB60F70, + FF70C4AB4F37D7C7E1668660, + F36FACCDB4B94286F6042490, + DD2007C851B70E2C71171145, + E4D5FB6A6F806D9400BBF344, + 3A9FC7EFC378976EE696AE83, + 749854CD2D13BBBA500F353F, + AC725293BD38E8C66E35EED3, + D949A0753DEE4B4AACDDA3AF, + FE41044F09ABE0A6BC0F9293, + 4DB2143B264FC1AE54490BF9, + 55CEFA60FA0CBA0E6CB71F5D, + 4570554FB8438C0692EEDC55, + 1C71768A34644733E39EEF4F, ); name = containers; sourceTree = ""; }; 7A970EF4CD9FEB460B82CAB2 = {isa = PBXGroup; children = ( - 53C4988130522C6DA28A4BE1, - 0E4F0DA9ECA921AF8E835E19, - BCC1C92B775AEA802A0AC917, - 355AFD562757A4867440E64E, - 1B01AB28846416D9B0050D4A, - 662061336599080D7C0ADB56, - 4563BD0A5FB10592A3DC6244, - CF768CC6E2EA5664519C1C03, - 669C2806A49522217459BB3E, - E34E03B67A82E30F5CD201BF, - B3EB470623EB09A867A9383E, - 729AF566D1EB32D59B8776F7, - 752E683005CC56CA4A552261, - 01E5B72E5D7115CFF884BB86, - 4079EA961E5AFE0A51869E40, - 968B7B6F9C111B514327A382, - EB4083E018759B2F9C29C67E, - A3405DF38FC19128C399E497, - 723111ABC4D02840963C6FC2, - 43F755438129CF5051D3C8D0, - 6D4CC9AA8FAC940AA974DF33, - 5DF85E59C6FBA88E394C4FD4, ); name = threads; sourceTree = ""; }; + 381AE52C082AE08E724CB954, + D11D931DAED4F636E8A60264, + EA5874F225E76DED69BD7132, + E7EC04A96E1CBFA9428A4B80, + 3AE89D0904EE985359A73B91, + A292587AA4633141BA378473, + F9609B0A0387932B86A6FABE, + 9F522CA5A8E82BF69E7403BF, + F5091F49E07C6DF8F644BAF0, + B409D881BE39C4704C94996C, + 69A2DA87D304FD486A872C1B, + 0AD4B355DBB0AED4C90E5657, + 91D09C7242A24405FB364449, + A9608756E1A18BAFCC48A064, + 44185DE135E354DD4758B3EA, + 426283CFD858F482E87F530B, + 6F6F888BFFA4BB40DD71285E, + 390351E336C2CF20C38ADB59, + 897B10399D1CA882B5B98D0F, + 7743414F79908801328D9F03, + DE4C0926D2EFA7649BD3AAA5, + 3E19A71C4A345EB5C1BA466D, ); name = threads; sourceTree = ""; }; A7DDE84C6BDC340DFEAC5C86 = {isa = PBXGroup; children = ( - 625D1399D1DC0CE04C2BDF7A, - 53CB2A656137C68DC54B43C9, - 12503429614C443A89A28FB2, - C920268F5AAE587A04131F34, - 292236D5B7928EF5C6D73341, - 9D4642C9C308DD3ABB2DF731, ); name = time; sourceTree = ""; }; + 24363F41974FD7A3B634B78B, + E21A45155C6954C6E50CCAF6, + 4ADE9EFB6C41DE44D40C9837, + CE19308F9CD1B8F05E6EF6C5, + ED8032A884A03337DAA1D453, + 5CDC0F220B1EAE847D38D1DE, ); name = time; sourceTree = ""; }; 0B90B115C693F54D5DF8E732 = {isa = PBXGroup; children = ( - A4A99FFB9CECAA4B4ACE8402, - 0801100E90790AD44224848A, - 9F077D151CAAB48E1B7A4A45, - 07DB1C038E8EF1D3628F6B7A, - FFAC8C8B3CC3F05E12744D1F, - 9D4BEB15620ED88F95BDF105, - 2BB91B988601A784CA953116, - D69079E0065151480B46F7B7, - 4E7B7D1DE6EFB7C38845D97A, - B3D51DEA0DE311B017CAB716, - 517756F0CB6482D0AAF4F6E3, - 6B3ADCFFE9EF5870BD04FA95, - 621EA7E956C5BA64D95DC755, - DECB3C3714353AE5775147AD, - 077B15886A49C2DF26EB7186, - 16F835A428874C108CE94490, - 6D9056359A751B000DB1E9B3, ); name = files; sourceTree = ""; }; + 9D50B3000D941FDCB620068F, + AF885F6112CEA5C2D7934AA3, + 3FECAB20E9C0834676E2D9EB, + 175654F2545AD9C0603BD0B4, + E443717EB8EC16A0B1814BAC, + FB459E95101C8A92E5B39A67, + 57490A9F97D62E7A312EA90C, + DFD9E836DB24F4DE75A94C29, + 87EDBC629357F63AB8E7B507, + A23966DF7E681FA878B27B92, + 70B18C93C5696330A877B330, + 35AAFB158E16D03C4D977713, + 605EA4B27D057BCB9263BCFA, + D10497F87C560FA833756730, + 176B18B9B61FDA6EC4357EB6, + 07C83735435D264F28158F79, + AC018F2C47CF57EB4A87AC36, ); name = files; sourceTree = ""; }; 9E9C1F84B44CA85F5F472594 = {isa = PBXGroup; children = ( - 95244870E8E9CC3CC6FF33C7, - 150E68F9290BA3701DCABDAE, - 23B94851B96CB057621E0EBA, - 6F195B4646BF53D1918F1764, - 1C9B9B22D2CD87C0D160892C, - D214FC393B8C9A379FE3C6CE, - 4CC30DD2477041D19048C805, - 738D2ECFD31190494B40BE78, - E9F7C31F43B7F22018E8170D, - 51EF1B32326BCE4445FD8929, ); name = network; sourceTree = ""; }; + 90B6C81CFB0DE386C673F62E, + 7639526FBF7A4F41961483ED, + 84ABA9491A70313AD6BF6F9A, + 6A22C06C6FE2B6B494B4878D, + A4F394FB62E70E3A3A02E4C7, + 8C3A6351780E678334FA1406, + 9E44079E499D4F4ECE55354A, + 2B57EB41D3962E3518B79FD8, + D6D37626671B0FB1CE8505C9, + DBFBBC58ED4A18EA9FE04D1D, ); name = network; sourceTree = ""; }; B87CA56B966A881DBF190AE7 = {isa = PBXGroup; children = ( - E7DC2D13A73F3CDA652C9DF5, - 37CFAB9F13EC95665CBAB742, - 1B5BCDA8B68284F2FAF17FE4, - F94ED23A0C2454ED44C7B53B, - 9A160557777085A813B1F0B5, - 568C771CA43B20ED9320E9AD, - 94B52728DAAC5E3BADD03617, - 6DA5BE65E7A6BAAE4797856D, - 97B99BA54C40DB3348086461, - 702AE0E6FC3184CD8E83643B, - 1FDD5774A3619E6116D1A542, - D18648E47B5447E1F6AEEA52, - 61E5B74F334DF6387DB68E7C, - 223EA3BC50EEE65DFD1BF515, - 37BEC08C61F8C221C4BED7C3, ); name = streams; sourceTree = ""; }; + 23936BBF807CCF5B1EEB9F00, + BDA5B0C014F6DCC188465060, + 6C502DF33FB5C14B8A67B25D, + 7E0DD06926DAC8EE93BD4F08, + 6421EA349C5D558114D36717, + 440A182A9068A8FBD011BE1A, + E5918150BDBDBCC3060C9FB3, + 47E70AF805B1C5C57566C4CB, + 52062790A5E737C8846A23A2, + ECD7A374DADD305C66141AF4, + 8945894D17A9407EEEE3B8BD, + 07E19FB806980020A47AA47D, + 803480FD5E7181E0D64FFC53, + B305ACE053406FF288E500F8, + D0AFF0790D81DB8F66173737, ); name = streams; sourceTree = ""; }; C0BC501BDABAB02545D8CED7 = {isa = PBXGroup; children = ( - F71DF877F3D13B350F01DFEA, - E965D6B8815E3C5E8A160C48, - D568CB3943835ADB2613AEF8, - EC9AF66FDBA32E129D80E59A, ); name = logging; sourceTree = ""; }; + DEEA654926310D5B37A191C9, + 234D4927B398ED6E9B7B0E6B, + 5D43D909CB26D4A07A62A4F7, + D52EB7F089EF359EDCB199AF, ); name = logging; sourceTree = ""; }; 314A7534CB4D49F809F0BF86 = {isa = PBXGroup; children = ( - D0D3C2CBD0363F82E5D9B092, - A4F8C1DE149AD44A83143598, - 30236ADC490891CC1557AE3E, - 15F7EA4ECAB7AD7E50A11065, - 62FAD1304BBC71BEDBB033D0, - D61ABCB4D785A183EB967AE7, ); name = system; sourceTree = ""; }; + 7141B07690C1A022A2BFFBBB, + DAB059DA13868A81301513F7, + 07342D914D2A5AF6075CDB2D, + 3CD47BA1CFEFB637DDEAC313, + 03B79DBA48F6C4122DABEE90, + 67895BDE8FA4B2A01E3B8B12, ); name = system; sourceTree = ""; }; 61DC39E8E45840C4E9876585 = {isa = PBXGroup; children = ( - 500556EB77FC460F48E018BE, - DE48404D34F2CAE314CA4E19, - D00090B2DE234305128AB650, - 09BB7D020FA96EB044330205, ); name = xml; sourceTree = ""; }; + 03E91AE23ECCF51E3AF9FC90, + D19705FE67C941DA74C31A9D, + EAAFB86397B191FF3713155B, + E40FB3B047D27337B9A9CACA, ); name = xml; sourceTree = ""; }; 044DA355DFC10789F7E2671A = {isa = PBXGroup; children = ( - A72F50930E3169EFC9724597, - 6B0CD9C29CB8715C6E916244, - 9F69A9E1418A5E3B33EF5B26, - F0FA50C01669546088DA6DB3, ); name = javascript; sourceTree = ""; }; + BD7B0136829554046A511588, + 9DCDB2CA1444618C4054A114, + 1737596EB7F40322C0A5DE20, + 5C58E6217AF57BD2A33ED617, ); name = javascript; sourceTree = ""; }; 9EE7BD032D2E50758043A0FF = {isa = PBXGroup; children = ( - 27ECA38DD6808A358A90E7EF, - E15C23EFF754E1289CE5437C, - 6726A33668AC0DB1B5E30C65, - DE579AF9E1C7F5EA0B7A87A3, - AFC498B17E8D5B122DB666C1, - A4CACFA409866E77F609126A, ); name = zip; sourceTree = ""; }; + DB1C6393173661404927B4B7, + 6C03031AAE5A7C3372D4F1CF, + FBDBD56614E38BB5A5592D32, + 9F7AC745AA0588C821A014D0, + 3FAA5384DA8B28DEB5E57A5D, + DFAD61F886BEAAAE535BBF81, ); name = zip; sourceTree = ""; }; 6BA585E8E2F21352228FF71C = {isa = PBXGroup; children = ( - 3C55CA36E6DF4478E7C2A106, - 11736C186EBE80F228E1D782, ); name = "unit_tests"; sourceTree = ""; }; + 5878CA91071620345AB5B3C4, + 1E6EF8035485237EA92A1310, ); name = "unit_tests"; sourceTree = ""; }; 246C87B7ECF29ACA118F0242 = {isa = PBXGroup; children = ( - 5E5F9CA2713C02B4DAAEFF9C, - 4E02D9A4D6D38BACAB9326AC, - 9444AB597C118C99704EFDF8, - 987E21587B07462F5098831E, - C44BCD4A16768A91B02EE14C, ); name = misc; sourceTree = ""; }; + 9C17E6FC9A4D7C8734800649, + 941219816EB5D7A2231019FA, + BACA17304411EED8B219D2AC, + 98D247A4824D969367AFD0FB, + F73B6D934AEC9887D9EBB5E2, ); name = misc; sourceTree = ""; }; A37D31A95DAA40A87611411B = {isa = PBXGroup; children = ( - 77FD526A14FAB45DF30CDA71, - 8438D37046A9F805AAC7401B, - 3FD4B7D9E2A8CC22D8F0C974, - 5550F75596B1C84414059D9C, - 8F3E6744F26B7BAA554F4E41, - 5C3EF1C1AEC96D6C8687E242, - E16F860A9AA000E590BE321A, - 03F15E955CC6905BAC120050, - 0A79B3C2BCCFF8C8D9837210, - 7349C82FB18B8E194B854DB8, - D720150F1F3647538D037677, - 2B835DD803DC7C2379F3898A, - C98926DCE80A0B3149961D0F, - C8AFE60B7174C0006C1C85F3, - 6EC413415C211744AB3B7E4C, - 7E62DD6F1A2FF13D5095D218, - BD455C126781EDA150C9298B, - 189CFDE7D3BC22BFE5CD87AD, - 3748D31911777A17CD3C20A9, - 269DDBC16D9F714A0B057A94, - D3C91BB5D97D3CD7411D718B, - D528C603E1870E0BC562CB9D, - F79AAA52220D91666D8B8771, - 584FB01EADCAFB49A98CED27, - DC4F26260A712654A80A2FF5, - C8A93F28EB0AE4F99767EE47, ); name = native; sourceTree = ""; }; + 6238740697CA1F0746776243, + A782FF0CD79464F3E015647E, + DC3B995E7B51FC0B76826C86, + 8C24F74CB23F1B82C80386FF, + C186342C3FFB4DE250556D70, + CCEBEEF441D3FCFE411AAAD6, + 823BBAE97A02475F25E54F9D, + 161F35FA23347F495704C26A, + 9FBAD3EFE40ACEB06B155A09, + 13430EC7CBFEF46874F53731, + 4DB48F6BAEFA120A31259EAE, + B15DC22CA1E52983F4F57A9D, + 5703889367170F80CAC76898, + E0A44ED2A465E22D93420F88, + A2208C87019608EBF813EAA8, + CD405182963BEB73FB9E368D, + 9C8263A9C3210CBC6C909BDF, + BE64EDA4F7260D2D5B7E0410, + 618839275E13B9DB660001E4, + 84494501A6148DAFE162650B, + C9BA40AFF2AD427CE4D480D7, + 02AC998E808CAF5C148CFFC5, + CB5874E2A70E8A6A01FE8C9F, + 7DCF49E37B27971A7E597555, + 843BE36A2285F73A3FBB5660, + 40F0E944D041D96F2DA4C6A2, ); name = native; sourceTree = ""; }; 5CF56D8EDFCB4673E75EB0E4 = {isa = PBXGroup; children = ( 8C7AB91AFCAF2F99D0E906B0, 6898E6C42CC9520DC26F9FBF, @@ -1337,182 +1337,182 @@ 6BA585E8E2F21352228FF71C, 246C87B7ECF29ACA118F0242, A37D31A95DAA40A87611411B, - CCD5CC6545DB9D9FFBB99D46, - 0C4D86B553BCA2945973736E, ); name = "juce_core"; sourceTree = ""; }; + DA353BCF838D64BA343AC0E1, + 74302B51B991EA1775AEFC67, ); name = "juce_core"; sourceTree = ""; }; A24377A329F782F1DF1A9E92 = {isa = PBXGroup; children = ( - 2075736FC83122CD98E9448B, - F8E876D642B7406D7D706491, - A8C6E967CBC442F331571870, - 991BB887EC327D340E5AA659, - 434A87588331CF1CB8118A36, - A76327DF3D3A1CB89340C2CB, ); name = encryption; sourceTree = ""; }; + 9C05D3A33B0D7B6B2EA43C7A, + 567D63D778B7A22C5D97F1C5, + 9C599E35E8A990404EEF805A, + CFF4FDD0FC27C36843B20BFC, + 29D35A5AB22E9443E0ED8F99, + 66897EA1FD2CDFB4CED47F8B, ); name = encryption; sourceTree = ""; }; D05EA809F9DB6CFD6B0BFEC0 = {isa = PBXGroup; children = ( - 0906C93F178388D7783BCC92, - B14C06A5F45ACD5D93357F96, - 776774969BC27F7269A3B520, - 4B09912103F721693FB77FEC, ); name = hashing; sourceTree = ""; }; + 4C87C8EC24CE0EB64640238A, + 2CFC9FB97ED3587D7E0E4E4B, + 4228B8952E3FBCDA69C1948B, + F8EB370470B7928A80032F7C, ); name = hashing; sourceTree = ""; }; 752AB8D433735A877FC90255 = {isa = PBXGroup; children = ( A24377A329F782F1DF1A9E92, D05EA809F9DB6CFD6B0BFEC0, - 81CF3953D1337AD42C542403, - FEFA7D5743E1801CB7CE041E, ); name = "juce_cryptography"; sourceTree = ""; }; + 19DC6BDBA978DC67B9783340, + E109BFE0F2475C97F17CA5AF, ); name = "juce_cryptography"; sourceTree = ""; }; 569E6262B6ED4B4C394F150B = {isa = PBXGroup; children = ( - 05D3F009C15785143F3D31E3, - 229DD5C0EF1D6FDA625B85A9, - B3E93FD47ACA9498963C8A2C, - E19A17B7DFC2E18AFC90946E, ); name = values; sourceTree = ""; }; + 2E96848340E1C1B1095AC1F3, + 9A4FCF66FF42906A7A2187A5, + 2B1494112273ADF380C99FD3, + 73CA6BCA313B0239842F298C, ); name = values; sourceTree = ""; }; F3B535506E5F093EB8206BDA = {isa = PBXGroup; children = ( - 40B44760A3D17F9F97B857B3, - 9E22E973F5C7E6AF1004EE8D, - 1B96C0BBFE3E1A61E50E61A4, ); name = undomanager; sourceTree = ""; }; + 616493921A733162495E7553, + 369C06F1DC7B3B7EB497D062, + F7E781AFAA34B511C812896A, ); name = undomanager; sourceTree = ""; }; E4B1CF3D54E0B5547CDF9A87 = {isa = PBXGroup; children = ( - 7760FF1BA004BE4D9CDF1AFA, - F347EE9BC419DB1879790131, - A97E3E8BDA867CFC443D8D21, - 5B679BA94EFF51894AD674EA, ); name = "app_properties"; sourceTree = ""; }; + 09846FF5D2FFB83242A02FF4, + B4769129853D2822D3DB38D1, + FBC55E440EF1EA83FC0DAA5A, + AF59758C300E586A7A6338D1, ); name = "app_properties"; sourceTree = ""; }; 670AA26A4F8D5CF111CE304F = {isa = PBXGroup; children = ( 569E6262B6ED4B4C394F150B, F3B535506E5F093EB8206BDA, E4B1CF3D54E0B5547CDF9A87, - C5D7E8FD3897F200069DAF62, - 8854EAFDD3B68BC78E0A1F89, ); name = "juce_data_structures"; sourceTree = ""; }; + FB81D25CF4825A9A186B6790, + D3B4D56DE3F90D9A445A47A6, ); name = "juce_data_structures"; sourceTree = ""; }; A9C383106F234D341DE730BA = {isa = PBXGroup; children = ( - 572F241637045113CA1101E3, - 70284B038C6F9030F7CEDEE7, - 1B14F64034753EEA8B94AFAA, - BFB2A78106121AE2F199055C, - 659511EADFE62ABB7141CA89, - 844583A4973FA34A3FF6DCB5, - 408F458A6E9A71923FC72D04, - 45E9503C1F2B4418E687E9A7, - 8D4E99621AAEBA39CCA68C41, - BF64F4ED5DF12FFF99C826AB, - C97E9F209C271E901D31304E, - 980A1CBA9A6D4B421BEB00F7, - 057EDA2ADAE5945C87E9E94C, ); name = messages; sourceTree = ""; }; + EEBBCD11005AE9AD87B36F32, + 868955327EBBD0C2C2447DB3, + C5C3838D0FDC65F44C9D1A9A, + F3BD246F4283B08B1E21C75B, + 3324210159E5C546DC5C2065, + 6804336FE1AB499087ACE437, + DB4AC9766332105669D51C1E, + 314E9338935BC33A1C468B3E, + AE381B9D6E2A4DA363C7DD3F, + 8C547C48DD5B3A854DBFF0F3, + A54AED02A4929ED6EB693CB9, + AB856191A15A8C9016D974D5, + CD965406DB7511EB187919E7, ); name = messages; sourceTree = ""; }; F197372050DC8782B9089C8A = {isa = PBXGroup; children = ( - F9C7BCC7CD4D4FC9CDDF77A9, - DA93B8704F3EC4703E2B2DC2, - 971D7A721F741E81AACBDBDA, - D4D9555F85A739252C027F45, ); name = timers; sourceTree = ""; }; + 7A029D97E723C7F1BDDCAA49, + F3A0B8ADF39FA8F15A6D8E23, + B6D9BF4B75784D01B7CDE1AF, + 7F2BBAF79EB32BB9904A76FF, ); name = timers; sourceTree = ""; }; 59EA583396C9C41EDC94D5F6 = {isa = PBXGroup; children = ( - BA97D0B8F59B68F245351F01, - 940BD46F150595E60976C487, - CEE91A9F1C74260FAC3E30A0, - 19F49DDF17B56B3F0EC5D80D, - 08684D02269A6462E874F392, - 88046B20D38387F2D2650F8D, - F4DEDFEDF1B16C6C48075EFE, - 6544288E0768C9FCABE3B081, - 7F5AF8186ABA8353EC1D4A24, ); name = broadcasters; sourceTree = ""; }; + B32716A0B0702E6861726529, + 2DCAC1795F1B47C592E65D4E, + D7C8F6360C455C0F76E35978, + 59CAB9E5A0CBBC51342FC065, + E70034BF5EF1721B245C3079, + 142D03BC875BD387BD10C51F, + 5C62F423D8469A02E55BF59D, + 435858CCF38F47E9AAE1B08F, + 5BBF8CA223EEE4D9C769E453, ); name = broadcasters; sourceTree = ""; }; B90F0A1A63C3408C288F6D8C = {isa = PBXGroup; children = ( - 43CC35E1310E10B9422E98C4, - 7C36F478BC80A41544C634C5, - 39562A408421F133E35C495D, - 54C1B379B72BAE39C06D9BB0, - 094EBE616E535FEACF39583B, - 4B2CB85C841304CE2E93592F, ); name = interprocess; sourceTree = ""; }; + 6D3F3D0139FAC58B2BAA6047, + 9DC4092F746AB0F5A73D929D, + A587862CF3C96C6C648216A3, + DD73087B002B1DB6B90B666E, + 4F5DED2313FC69EA518E5679, + 1E020B9E032C076071700CEC, ); name = interprocess; sourceTree = ""; }; C271DA3D9CE655C433BB4DD3 = {isa = PBXGroup; children = ( - 8F8C1B89ADC4FF3D985E4444, - B989CEE19057D31C6D521BBC, - 27F470103D4B980E2E8E8AEB, - 320CA688772F770F113A99C8, - F3331BEC83A436D9CB3B9131, - 73CD9E5A889A13890247BA55, - A66CD58D6A8F18628AF2BFF7, - 3DDAC0076D6C914CE76C09D9, ); name = native; sourceTree = ""; }; + 88CC8BC2EA8CDB378A03FADA, + 3C89D04328C83D2FDD4E5116, + 89CBCB2D4660B56C1A939011, + 7627F01C1E5383207D2C0BFB, + 17B2789DEC279EE7DB8D9BE4, + 93667813A711750790201F8D, + AAA3ED492FF78DBBF86DC612, + D219A10E7C41110A1AA4FBB9, ); name = native; sourceTree = ""; }; 4F8A65DC4E47B7CB0DB88369 = {isa = PBXGroup; children = ( A9C383106F234D341DE730BA, F197372050DC8782B9089C8A, 59EA583396C9C41EDC94D5F6, B90F0A1A63C3408C288F6D8C, C271DA3D9CE655C433BB4DD3, - 74E4F42C4ECF1C1D2C7873AF, - 678267D32EB2BF8C0D1217DC, ); name = "juce_events"; sourceTree = ""; }; + 7C7B6D8D155687966F681F5B, + 63B031ABCF8DE5C94889823B, ); name = "juce_events"; sourceTree = ""; }; BA53DF8ABDA9DAD0F963BC8B = {isa = PBXGroup; children = ( - B8DF17DE3A37A52E3514A492, - 83AF4F43D85DCDBF318BEC8B, - 3352C1259B6E110F6B0A835B, - E15E5A1710E50FAB897B4310, - 1AA4BEC9E981D64B98626682, - 88D72DB7B94A70CD9EE18440, - 70835A4653D8754BB6C7CFE2, - 75CC726CB13BFCCF00F99DF3, - DF7A0D14EC237709BAFE9224, ); name = colour; sourceTree = ""; }; + C7D5A8B28D0B7DE58629AA04, + 5C8795B0DE5C729CA18FE89B, + 2E2B14A2334528E4405AEDDC, + 8A4A25946040DED54DB8F3B1, + BC0ED0B33BB83E19D9609152, + C776DAD938AD7E1207DBCEEB, + 5A1777E116DA01B554C90CDA, + 236F239E035044438B7CDFCB, + 91B991143655810C26644D50, ); name = colour; sourceTree = ""; }; 88878CC1561F13CF681027E9 = {isa = PBXGroup; children = ( - 56DCDED7C229BEA998AE9610, - E7B310562519AC9C1FA14CB1, - 7A6DB25F73AC07158A74D006, - 6B8FAA45DB6613DA449E26FD, - 7BD61B782DE61C73D8475002, - 46A5E45225E1FDA3975F6C83, - E63BC85590BE7258F35FA46F, ); name = contexts; sourceTree = ""; }; + 326E293A87E18FC3FBB26B47, + 2048DACF787A9BFE011041BC, + EBC4E11E36D206EDF01E6EB0, + D0A5B1AE7B7B56633AF2D5E2, + 64807B3EFFBDC3348512901E, + 123B63088FA1C4D1AD225CDB, + 2FDA8843C89E2D7DFBE3FBFD, ); name = contexts; sourceTree = ""; }; D5CDF20FB8932DEA5810EEE1 = {isa = PBXGroup; children = ( - 1173B2E45074397470CD6EA6, - D18690CB0E643C9A642F73A6, - ABA9367C4E66F2F18E813816, - 1EF1157A189C1B7D4E20B5AE, - 6AEA07E5992D813558940710, - B4C612999A7FF20800CE507E, - 158D17EA6E11AEEEA7D524D3, - A751CD8564B7B6B0EBD643E2, ); name = images; sourceTree = ""; }; + BE61994F6993AE76CBBF1EAB, + 6911E01E967839199E4C9822, + F994D2E0DF00D0A7765068EF, + 2807A00AE6C4539CD935F56D, + 94FAC7EB87C8EBE67F68AD60, + 9FC1BB191F1EB657A181866D, + 3966D734450E72F5682D2F06, + DE4DC23FAE4C420D489ABD17, ); name = images; sourceTree = ""; }; 2C9A23E9808933102222B6EB = {isa = PBXGroup; children = ( - D7D4E1A29E0B3A33814C7EBF, - F27EABE98642759DB9C4DF65, - 3D906BFC50723AC77213FB8E, ); name = "image_formats"; sourceTree = ""; }; + 55D04DC4EA2F037CCD5DF9A6, + 244B9B4B8307A8C51207D457, + 4FB8B3386156F5702A20F7D8, ); name = "image_formats"; sourceTree = ""; }; A0E5437DC111A1AAB63CCD16 = {isa = PBXGroup; children = ( - 705C1BA65E7FB620E01B44A5, - 52D6B752BBA03EE32E0186EF, - 9E6F450E5BEFD67159EAD012, - A90C3FDE58F6023CE19ECCEF, - A0EC1B71A589996CE32FDD1B, - 3AEDB68E416A876681F89985, - ACB0BA25EA85951D2A75CC62, - A963217BDC628E29845AFA5F, - 14875F3B31704358EBBB4F9C, - B6BB67F1186B3A3DB89DC02B, - 747EC1715A027D17F0082830, - 4D67518B8585D2075E450D75, - 98297330C67DF9D0059606DF, - AD7F976713D7D3B057793A42, - 3DC4B655D395BCE7D0648755, ); name = geometry; sourceTree = ""; }; + CF4DDBE1126E8C8C3A37DC78, + 2CFEB3BEABF88B0C41D94E94, + 92172AE93327D4F8008A0AFD, + 3095D8D2EF68D6ED502EB00B, + BFBF32B0E491C9D4527DF9A6, + DE1943CA08D7FAB2E3EC0A14, + 2AB2B4CC891E77E2DD062BE3, + 5D1F3BD1476426752ACB1EB2, + B471C2AB67E7C68D1C7D729D, + BEC8EC4C23F9AA5C8DFEA15A, + 2B9907A25C1C36C1E46BEA65, + 03457E9DD2B35D7C1B0C7393, + A54B5504235B3324635B1DB3, + 3AF114AC45249CDA77EF940E, + B6BE7EF02190070336E63E89, ); name = geometry; sourceTree = ""; }; FD44264B8C9437DCF22CE602 = {isa = PBXGroup; children = ( - A4DDA56CCF451DCCA2F47D42, - 16DA31B062407BE595BD2E6B, - 9CE19F2F963112A2442FF86E, ); name = placement; sourceTree = ""; }; + 610F820C21D914E9794A36EE, + 7BA2EA5655704E5358ABAA9D, + 62EA5E33A940F30BBB56E293, ); name = placement; sourceTree = ""; }; 5BFD15FEDAA57F0C3DA99850 = {isa = PBXGroup; children = ( - 227CEFF1628076DE7A6D5A82, - 08BB70992D33D8DEF932E9BB, - 62F3157710E0EB1EEDFC71DA, - 62FE07463F39D02D8C6F2CA5, - 398508292A45E227D66AC0E7, - 0CF71E055B7DC5BB25E8CC20, - DA54722A7C1A958B80B9D10A, - 5E135BD422EF904C0FCAD1D0, - AB7C518F617F260822A67872, - 2E91EB1BBD0ED5BC1D0A95A4, - 88A8541D309794713923E3D1, - B71187E41B94D7913C1791AE, ); name = fonts; sourceTree = ""; }; + A010D6D997B85A393165DAB3, + 44443DA5B0FDA2480DFBDFC7, + C6CD42F1DA2F444A59CD4AF0, + 2A771B60F7C360A111F75AC6, + 1A667A0FBCC8FC7EBBD15B20, + 6E0713769EA84EE0471D9811, + C73B4B312C3A4CE4F8E742C2, + 42BC8303198293E30AC0B21A, + 393D0CA8D89217F1F2504768, + F64C6AC0DC0376A80A74A82A, + EBDC0E12D4ED20F5DB90BC26, + A8A277CAF10A3FEB258174C2, ); name = fonts; sourceTree = ""; }; 2925596DB97C0571478FCE48 = {isa = PBXGroup; children = ( - 54063388CD6D9F64180BC16D, - 076626EB667106684FC3F5C5, - 0B4FA008BF447F4334E24693, - 9846C2445B7D6E79A66630F9, - 6F8DE38E80B72E6FF126483A, ); name = effects; sourceTree = ""; }; + 1B7AFDD8FCA13757D08B8B3E, + F0E4B5B18AAB82215F5C6AE1, + C296F214D5B65857DC3DA585, + E7488E12D0F3300AE33E0B9E, + 63EE49826BF4CFBD9D546DAC, ); name = effects; sourceTree = ""; }; E62D8A1F0BDD00ABB882F291 = {isa = PBXGroup; children = ( - 4E3E146079BC92DDE7B47EF9, - C00122D03A9B2BE3E4ECBE4E, - DE3E98A6DCCBE1F461E46E79, - 56872D4E18FFA80AEDD4FF35, - ACEF6D28EC9FB10B6C0D8EE0, - 276DFA694283C37D1B65B46A, - 5F1334788D34BA2E6EF83086, - 2837660339370BA9863DC451, - 9E003766817800EDE5F401DA, - 401D5DBEE57DB66AF040885C, - 8AC4AFECD0028680DA96CFEE, - B9D557438E309657EB68CF7D, - 82D0CF4B57D906FAEBC60666, ); name = native; sourceTree = ""; }; + 9D61877D2691EB78B2ED69EA, + E9C249D9F38B0DFAF0823653, + 8EA18CA66CABC9B5087DBDD2, + 4F5C213B72A375A83FE50979, + A5CEADBA23491564FEB6D4EC, + 3E8E31BB97A86349790D6CC3, + 3391FA30F4D45A4A77DC2CE1, + AC56A48CC01AABBE45F51970, + A8CAB6FAB9BC1CC96FDE7BC2, + A3E01235E4AD9DBE2405F792, + C884444C380A4B053DB70D12, + F36959B167E88B220CF9D8FE, + F2040E4B76F8783B471CECED, ); name = native; sourceTree = ""; }; B78A49A94757B1530E3E282B = {isa = PBXGroup; children = ( BA53DF8ABDA9DAD0F963BC8B, 88878CC1561F13CF681027E9, @@ -1523,277 +1523,277 @@ 5BFD15FEDAA57F0C3DA99850, 2925596DB97C0571478FCE48, E62D8A1F0BDD00ABB882F291, - 572F0A8E449EEE319155A448, - 37BBA15CAEBD49401D2F82A5, ); name = "juce_graphics"; sourceTree = ""; }; + 241453DBDECBE0CCD5C096DE, + 7022B01ECEE7000DE6008C0A, ); name = "juce_graphics"; sourceTree = ""; }; 978A5EA7C209E97691DF1580 = {isa = PBXGroup; children = ( - 8F95ADADC0B19BF9D77D1A01, - B035D33267C606674E58EE2B, - CEB12E3A853DD633CD5F3AFB, - 38ED648ECAD68AD30C9139AA, - F6A17F1B8D8330F6E8DF225B, - 52B3E9170C4FF9A60E75030D, - 7D81388899A711A7C93107EF, - 2C4196232A1D92FC98E51684, - FE78C65011B44BD909EC2062, ); name = components; sourceTree = ""; }; + 2A59F5E28F97A435592E0B58, + 4A31DFDB7AC330488B8BBEA3, + FEA645D52C593ECCEA779BAF, + E2307A386F9B96576696354B, + A6AD00FEFB31915AB0F2798F, + AA5CDD430B68BBE10A9026C5, + 5384C065CDEB3032907ECCAF, + 8001506F637B2516AAC5C0D8, + 0B7637C0030C06BE612E41E8, ); name = components; sourceTree = ""; }; 0A15D9E1577644179886B0D6 = {isa = PBXGroup; children = ( - 534EB22CE7A71591FCCBA8E4, - CC464EB86E0DE492BEFC7237, - 24C7C2F049DB74035187FBC7, - E27B4C86E077374F4C5E0F02, - 005BC9B639854EA82BE9D1C4, - 08CE1157B27F232F61111F04, - 97BB0621A58441872B96D1EC, - 4784BB8CDAEA553AEA062A56, - DA088C27651F40F29163E0C2, - 5982BD1B4149622A6FD884A4, - 26FD20E046F037F67A376081, - A04B28778E7EFA87304B177C, - ACA68143C3AEE4F3F3327E66, - 46D9408E336E541FAFFB6F1D, - E3699DD1D681C7B65A9348C5, - 696CCA96408572659C97FBB1, - D06C2B0C19461F7AA18914A8, - A610EB8E83CC94E7DFBBC298, - A71DF97DA4CD69A67A1EE763, - 135F8FB24D69C7E8BE59185F, ); name = mouse; sourceTree = ""; }; + 89F5A5C12916F02E579D6394, + 1D9FABE954892C169D874E35, + A5DEEB6DADAA5AB2CF41A880, + 8102EBF90140E78193692AEB, + CC8F24C4E5FC5C12AA30F6CF, + 36A0FF58D355147F40981C39, + 38404F97E5118017DFDCDEC4, + 5A5749D0A878955C964DD2C5, + B3261106892038D4F954E6F9, + 833CD270A139A70FF4E60D35, + F38F8132499ADBD3344E8449, + 61473E0A6AF9B900406695B8, + 8DE969191661B557B4222D50, + 19E9997C0FE3E36156141D64, + 57A0BF533D7A7B57321A8174, + 2819AE973B501D15AAB8C937, + C8A5AD5503F33596C4147ACB, + 72696E2F6E8EB43A8E604390, + ABA2E1FE9912D5C28F177E56, + 8B539DB72CC92EEC7F96C8E6, ); name = mouse; sourceTree = ""; }; FE8E15A77FCDCB00FBF381DC = {isa = PBXGroup; children = ( - DA42AA71E4D47975E018BED0, - DE41FE4DADD07963905B82D0, - DE9CB3573085CEA391B49650, - 3FF553F76522FAC43163CE03, - 9563B07A9E53D5FFE868F8BE, - 9BBE7417871F8708335181B0, - BEDA74674128EDC35C5CCAC0, - F1E144384FC6A2C42FE4097D, - 96CE2C991445A3994E1FBCB0, - C8541CD950B7AB83AECF39E4, - 19553003D814DD6A3D1CE28D, - BB586BA19ADC508119BF86CC, - 62AC3BCA9BBA2BDCEE842496, ); name = keyboard; sourceTree = ""; }; + 46D8BC7303C892ED3F90E4DA, + 29710D5E6C3372E4480BF746, + 38D15A30D4658272F910A7AB, + D07A5399F09462A5D7041225, + 0060F61BFBCEF4E9EF8B3CC0, + 8EFB4EBA0836D5401B6D3DFB, + E13860F17C7FC399EF28EC1A, + B1B7C62CA04ACBAC6CD1C2AD, + 49794569C715BA919A01D72E, + FD5262552A90A9DFACB3C07F, + 74B477DE4CFC95E20DBB0D91, + B0626D2C611D9E3DF1408BEA, + 90FEA7DB5EFC4E9B2E933056, ); name = keyboard; sourceTree = ""; }; 5D48FC8B43CBDC08DB9531D9 = {isa = PBXGroup; children = ( - 9871D03E9A1E28B247352407, - 5B70ED35F78822734FD91F6F, - 8B28654FCB4605697C82637F, - 9C77E1E9F8BAFCD7610F8F76, - 761FA7CC71FAAE37676425AD, - FE00E8025F597B2AD2D00063, - 20B34958865F62C6D4CC1C2D, - 5D4B884A37E3A190B16B34CA, - A27997058CED5CD80DE7C4B0, - F2137487557EE18A462259B8, - B7EA4F63CADAB5B31D3D985F, - C3B0389DB7042B45EFC751AC, - 4EA7EB8C8EDE34046AD54E2F, - 1CEDC2C77278F47EA71D588C, - 9B156F9D8794BF1E15A19C5C, - EC6C43EBC349D5597A1CE53A, - F44CADD7FDE536377851F6AF, - 3EFCADD916181E95D684C237, - 01E3FAE5B663BB39B4317ADD, - 6A207487147E4661842F2EEA, - 4F6BC156DF6D42B5A2E6B9D5, - FA4C2A6A58633E63A09EC3FB, - 150EE812D88AFDBB98C0A539, - FF921DEC61293D650C9BCA7B, - F46EB82569549C07A8D04D15, - 5F1E31EAC156296643CA5A5F, - E3DF0709DECF7FB19A8DBB11, ); name = widgets; sourceTree = ""; }; + 0C9B04C3B7D8E1CE4FAC6FF6, + 5383E87DC6DC1D251C271A50, + EA779F8A580E3D22A7CBD51E, + E958ECCACCCE70690FAE58B9, + 5D4A62D4893C16D7B17C6A43, + 0F16DEEC2C4B95E3A9F28CE5, + 32A667DB98BC4EB30C51F20B, + 60D8280577C14A7D3F67563D, + A95D718F031CB8883DFDE915, + 7D8D285B8414388FDB083AFF, + 23724FEF549E05851817B4BB, + 65DF385E92A4A65760DC3BD0, + 3D16FF3C64D4248C0C6FF504, + 27676EBA6012198993C2CBA0, + 68743DE3AA833D6F02F754D7, + 9F70142818A7806830EEBD7C, + 44FC8BD37CFE8C0D851C46F9, + 842433A42308565BF3C1542A, + 74AB51B6E97964B27B1CD019, + 7BC8F7015F35BAFF4AEDA0E6, + E5B84D5F7CF2B74715EEF3B3, + 66CEE40E51335F661B5C5C66, + 260A5BDC20C7B4029DB418E4, + 44C6568EC00F1682FBCD3B69, + F26953C1E056357A3DFDF35C, + A826C1C083678A4E9279C118, + 6DE6751E6A4F0DDE9C7F24B3, ); name = widgets; sourceTree = ""; }; F4827EC22DDE876BA01A1012 = {isa = PBXGroup; children = ( - 03D597E4C12113FB74016803, - 1A632A95CA812B23E08E0C7A, - 7DED484895527D5C0BB6662F, - AE7E18FE030834B289424681, - FCD0D87F9B7A473885F5A95E, - 40DDC868EB152DA18FF4832F, - B4AFAA5A74A2E61F0196F4B8, - FC5A39F51E480EB25A4A2656, - 29B12214BCD1551867246556, - 3226060A8CC7B793C5A7A25A, - 13BC4980571374E9F0243F0E, - C7B2F4323D69615085F4A633, - 2765ED5E0A7D8759C81EEA40, - 4D7D8DF32996B70112FFA693, - 5586252F2B71502A0C1A69B5, - EC60C51FC1AA8BD749F4DEC3, - D03AA7DD0628031F75231425, - 405F7A0C891B13655617BF5F, - 461440C6B5EE1CF5DB2ECDDA, ); name = windows; sourceTree = ""; }; + 8314FE695F91DA2FAB51920E, + DC6461EF11D5745DF8C00E16, + 464424DDD6A6678B94CE667F, + 2B9BAEF9C46C224088F5BB25, + 4BAF7C54867DA3C275C2F59D, + 6A8AC5E55EE51EE0476D852F, + FDA36D1F836D00DE705CD06F, + FF1F4F1262BB429E80492B13, + BF40FF2E0FA609212C849FBC, + 766EE2CCD4E86729C6CE8112, + 8E95A3B7C194244B92D5D65A, + D5C10F9CC5ADFC1B63AD1DB9, + 166BDAF3B9896BCB3771A061, + 0346DBE09BEC27EA93676FEB, + E9A4C91E94B6D096BD8217D7, + 8683CDE5FD2DFCB2CFC8F410, + EA13B2FC256C7BCF0900369E, + 27240E9968C04288887BFDC7, + 25869F2A5B90C64E857606D8, ); name = windows; sourceTree = ""; }; EC71C6DC0803DBC6F5B71C8B = {isa = PBXGroup; children = ( - ABB9E5EBCD9C0F04547E5A90, - 7A2245EA90D757EED0EBE63A, - E0D15D4DE8EC3E536812D4FD, - BE22F0B06CBFF0C62A317CAC, - 98594F6F68633ABB8DB9A488, - 307C5E375D02896F764B50A2, ); name = menus; sourceTree = ""; }; + C9A25E2EF32224159B617D5E, + 0054E026B84A3A87020CCE48, + DA98B32DCA0DEF0113C22F9A, + 500F7CB9F45B62E46F4BBA57, + 595A9929C0E873C30AC9AA87, + 439FC260CD869E30210D98BF, ); name = menus; sourceTree = ""; }; E30E1398A3CACDD90FC9C219 = {isa = PBXGroup; children = ( - 476DAA4C7DBFD4BC115090D2, - B45F7C71FC56F9DCEA7379FF, - 83B04EFF25DA63BE3DA37B11, - 3D08CF856ED46386AB450F46, - 4B4BC465C9478425824F5A82, - E7E06147F43FCAE8D5B20BAB, - C56154402FC7B2983160C3E3, - 6FC349656B1BC972D349E67B, - D37E99EBDA572556CA60B942, - 037977A3CA69858654B749F2, - 1A7BABC358CA895F30655093, - 48225D3F1FDE66F5A56A1ABA, - A0B1470B03C45DEA4B9EE14B, - 552E3A59D6200D3CA42CB2E5, - DAA6196510C04172905A6BA2, - A0CB25C077F41F543BFE0ADE, - 22BCEE7C1CFE9805F0C39F3B, - 0C8CE60E5ADA256EC7311C40, - AC3721AA8206512767A5E5AE, - 50923F018EFA0EC66289B8DB, - E90A5D53778BE390A04B8D30, - 071119F515B16F354C9D5D22, - 43234F932D4492E104787435, - B1FDA24AC0EF52652F3DB94E, - 6C140CB15288D8837DF454C4, - BCE1A7250DC27CE2B297B999, - 538353D423AC527D313BE99E, - C70A847D3C9EDEFE5B57C1AC, - B79DB0C1AA34A90D1F3E012B, - 076B1F9E89390D3CFE7B6F8E, - BD2B30F77B968E717E713124, - 3E9EC18E1C4F444805B36259, - A38AD54C200158953BA0456D, - D0D385C5D99B9D9A90C00458, - 85A0EF72EC932C8A327F8139, - 39F3DADB903ABADD1176B79E, ); name = layout; sourceTree = ""; }; + F4F618373A81FDC73AB27A91, + 799472026100D7BAE015F6A6, + 34A6FFC298D12BF9E4D55AA1, + 7A6E1CBA343C07AC187A3EE8, + 7F0614F4F47EB171B8476BDC, + 19045B1A4A9E79DB5A44927C, + CC3F295E9D9E5863779F9ACD, + 3B09334ECC8FB54B4B7D7B59, + DC66DC84909A3802527414C2, + 7F171BE6BFAA1E3E2A9BED61, + C8F82FBA1E0EF7EEA5BD02B9, + BCFE159BD9F2DA5515E028A4, + 4C40BFAE1E25F166EBB5EC48, + 25E6B62A5BF19A0D1E085E10, + 684E11B1CE018B2C46938D80, + DBB34599E380FB1F37A28B27, + 2DB2DBF293A77B80E01EBAED, + ADCA2F92E2C17964A4AD750E, + 82A390DEE5A3B2EFDF7A65E6, + 674E13DA209E762DF15E9E29, + B6C7114A31FD6B1DEB08346F, + 6D5EE68347208091600E94A2, + FCC9F258531F00BCD91C63DF, + F233E88B6F2BC6906819AE6A, + 9C3E556586147F27B4EDC982, + 135DC8543A904B7BBAA0FD7B, + D01D74EE9A00B0813B00FDD1, + A1C77E9A6624B8B1A461C038, + F831631700830F81994D9980, + F33B267B702055F8CE27BDB8, + 8C9D252ABA3CDDC81B33884D, + D40C36493501EA97A8D1EB50, + 8C9EC3F9C24081ECEF3FCEFD, + 4658E12862C546A62E05E4D3, + D886106C60A496E47C48AFB4, + 374277A96D9830E45684FDD8, ); name = layout; sourceTree = ""; }; 3826467DFB859364DD1392F0 = {isa = PBXGroup; children = ( - 8F69B5117A8AB4D95316FBAC, - 0207C77289467D58A696794B, - 70F88726C73A6517C14B5E56, - FD596755997053D5C6F9D460, - 778A19A79B821CCE6BD27E12, - F232D373ED304682C9581DBF, - B4D3C4A6929FB0068E61E5E7, - 77B9644758BED4987CEE2FB9, - 9D7A8ED2F93993D6BD4818B9, - 519B2190343506FF89DD9796, - 4C93E808908617B457689A69, - 03E3F0BF99B3C180F9531411, - 8BB79E37A824F6CBBB7A97D9, - D7996C2834C1EE0DAC4BAEDA, - FB5014B315A9FB387052F4DD, - 96E6A79B5BBBF580E0E11FF6, - 19DA53917D0F1D8438EF83FA, - DC4D885D7F7F573E42E13F65, ); name = buttons; sourceTree = ""; }; + 782E3434FEA190A986EAC816, + E6BA3A4991987C4AB55F5948, + 93CC262389F622F8AB79CA60, + 02C14E49091F42750CD72F00, + 35E6F6325AF8463C076BA594, + 92DF4A828DC5CE370E36044C, + 0B7E069D09A7E46448EAE230, + F16734BCF880A8180C06018D, + D0B5B79546163A6DE73D0E2E, + F4A977844BD67D5C2BEFCDDC, + 5AAE605D230E253D4EAC195E, + 4408766B366713F55707B7A8, + 6BE6A3A14057591A3B4EF2C4, + CB4D4DA89BA649D3F1B2A645, + F2DDCDF62D2587FB565A442A, + B88950266CC4244E1B5394F2, + C088D98E527C1DA17B55A9D9, + B70E52FF75D44F0F1F0B31D2, ); name = buttons; sourceTree = ""; }; B2943EF1FA5DBD81A406374F = {isa = PBXGroup; children = ( - CE696F8D455A2C2D1B8051FB, - 81EE8DCD7B8BB528C9989B47, - 31A79A4E5FBBBDAA36B7D273, - 8EA752855DD7BA2C1CEFF9D4, - E105D3381CAF5006058DF2FD, - DC078E6D148F784C9843BD8A, - D9108E2655D2E4403A4B598A, - BC57385BADED3932DB3714EF, - B3CFDC682EFECC45C4227288, - 56207999C7136BA24F53DB94, - 4A0D71E8FA4622C6C7687DD7, - C1505EA2417265BC59135075, - 7F6B22405102D9B38BE6E113, - 5500A9D5683F5124D0BAEA8B, ); name = positioning; sourceTree = ""; }; + D5EC3B41088855C3D481A73E, + CD3A68C29B7A733E5954BDA3, + 76F1A69F15F53D17C632A644, + 14AB997C7EB22777C1EF533C, + 51026A3BE98FD70FD916CF45, + D3C1097E92146B596194A067, + B316291E570F37785C40FE88, + FA2DB83279928FFB76A4BC6E, + 4E3C26EE8C6F996F207F0C32, + 1DE0CF80B807A4A702DC68BD, + 21D31B64BAD35C6C8E8E8FC0, + 29215FCE04DC4D267FF25E6C, + 412D5D6AA4018C8DF59AB741, + 807E7971CB75C806D7DB5DF2, ); name = positioning; sourceTree = ""; }; B2AAEBDCA5147C75A44D4791 = {isa = PBXGroup; children = ( - 5424AA8231E11912CD1C516C, - 2892D0D481CDCCFCAE374DA8, - A92EA5F1D1D2ABA2E441DE45, - F42A363007434541AFC1A7A0, - ED56CB90240662CE6FBE2A74, - 72173AE89EE7526AB956CAE8, - 9A704CC5117B59E1F5CEBECD, - 4C41E9A5BA9B4CA47D4A37BB, - DD4F1D5C6CAD9CEA86F83209, - A60E87D4E2911C3730CE3DB1, - 67319D5DD2BD8D31706DB34A, - 29054D0D5BB22F6A23808951, - 97F9A1E6E51FB3D918EC3174, - 24E811B6B00094848D08D21F, - 4B06A49CE12DBFA2FC861D50, ); name = drawables; sourceTree = ""; }; + CEC05A60A0E19B07F6A3CE6B, + 5BBC57B395B553CE08AC4BD7, + 94BFC3162953A5E7E192276A, + 2168310E25BD55C9A46499C6, + 92BB22C929A3A76CE6F29C7A, + CE4F0A27AAADFD53316A17BC, + D00157FA3D14BFECB7FE7232, + FD5E948C1A89B11770A20704, + B54A14A497368A580B7D9AEB, + 16ECB71D0D2C5C8BEFF4B4C6, + 8BE44C96A60C5D9B9F503409, + 6E9C1F4D69A9C99433DC67C6, + EE577E6ABD70D104CD83186C, + F0D54DDE8C2AD1D018A61FDB, + C21701DD3A4A2628C63CB70A, ); name = drawables; sourceTree = ""; }; 0EADBF64826A3D243FB6E1DD = {isa = PBXGroup; children = ( - B063E208C533148EDB5D4B91, - 7C91E9B82C9B593E082DD74F, - 1DDEE220B7231E89552E9A07, - 5FD5C6D8A917C60FBF029EC0, - AEEE72913C595DAE27F43ADC, - C2375B75F67BAAA9813EEC2B, - 86318DF533A7BB50B88789BC, - 8E6D1C56F3FAC7B249F2582B, - 45210D0101FB1A0A4AFA4C54, - 0B22BB6E27076BA1B6459249, - 45EFD54010FF09B5795B59CD, - 76CD66265F349446088FD5E3, - A1EF20A764C5B6EDEFC378E3, - C42F2CE5B179094CEF9786C1, ); name = properties; sourceTree = ""; }; + F20F182CBEF008AA1B1BB52A, + 0C61EC70BD4EA59AEEBB6669, + A1A621FDC626245B1B3C1C4D, + 9424FDB8C564B73250B7B20A, + 0ECA7867513EFA30BEA0BE78, + 4F2D3BD9697AAFA060EAAA59, + 20E10FBD8694E185CA551EDE, + 109C128BB4A7A05127A0C485, + 6B103C0FB5E6E3618ECD3B48, + EF8B8FB4B02133457562E1F4, + 7FC89C1EEB42DE3C9628591C, + FB3BE7E3D0A04791487E9E0C, + 1A788BE93E528FDAA62EA02B, + DAC4442F8C2F142270E92349, ); name = properties; sourceTree = ""; }; 1E19112B929FF59057A4B030 = {isa = PBXGroup; children = ( - FBC39ED8BF25B886702E335B, - A7D96DBD645622F9EF3B3E88, - BFC021DD9267F5F0D2D2D58D, - 9613BC80734D26E200E5CE1F, - 1717C592DF6E9FB0825104A3, - BE24FC2B4C9D80DC8DC99BC2, - EE7FAE0C413B7370B393CD35, - 92EE84597D647B6CE0CBD4FE, ); name = lookandfeel; sourceTree = ""; }; + 0700C7069E1CF3FF8966C0E3, + 4CF92825BE7B97AC268C2AA5, + 56985D9599D0D1D00B42F95B, + 0CBC9EB8F2C55E88DB0F49BD, + 5710CADD28060D8E949D96D5, + 31AE430D2372CF6283185033, + B3FBDBEBC38720E957C15BE9, + 69449AB58A9C0AB552F754F4, ); name = lookandfeel; sourceTree = ""; }; 1206D5C335340736A3A574B9 = {isa = PBXGroup; children = ( - D8AEA877A6200E6793A56B81, - FCD602F37104023C7B8BE2B6, - E09382FAC0496CC7B1A70087, - AC3B9DEF05ED1B18C952FE36, - FE44E4AE499848D27FB7A985, - 52438BC8DDE3E8A8A708D307, - CC726694653F832354878239, - 3AF3E08820EC2CF94B505DCB, - B2F561631B30711F78C118A0, - 525381C319EDB9B47F9DFCFF, - C61D46855CAEF3FB4547909B, - 58FB0E03D5E6CC4122CD00B8, - 7B00E4D3D066DFB30406ABCC, - 31B95E3446D65E1C0ADC0E4E, - B4FF9DAF77F9CEFA8FFDA583, - 7C4D9BAF8818E5750C110343, - B1F56F0DD4CC94FF8BB1FBE0, - 95446442AB833FA3CAF0D949, - A87251DF370D12DEA68B41A1, - 1A23B74D25E6B0C55F1A1186, - 30EC49300F475411B40273EA, - 6CAD1F4452A73BAB29EF5D4B, ); name = filebrowser; sourceTree = ""; }; + D7E612935BA192BF5D24B9A3, + F382E14FAFF5CDEBFEA81B00, + 98C77B9D95141EBC60E6AE67, + F3154C77D5DFCE8D71084F23, + 27A9B065352AE36635780373, + B57640F7EDADCFE17719EE68, + D8256B8AA794F43A2259638A, + 0D35F0A502484A40B09F3EBF, + C52E8074125FEED4DB727EDF, + 90BE189372A13866896CE817, + 4ABF36D87D2BBEDA4DE28A4E, + 1FD6FD7218AB240D23DF4BAD, + 2D8FC1F116F882698F5CFEB9, + C51A754A0E65CA141A2C3310, + C551CC8801B93AC70F6E4F76, + 830ADB6740EF70992E71895F, + 3BF23F0B71FB8E526E895905, + FD05E73E3F022E08D70B9569, + 27DC413550834C828252B003, + BC1DBF05964D3B9130CD8CB6, + C3DEEC17595B1AB020ADA47F, + 67771057800F9416E9777625, ); name = filebrowser; sourceTree = ""; }; 53440A90525AC832090A35F2 = {isa = PBXGroup; children = ( - 23FA7918C3938E3FA645F003, - 82E3A19B4D8BA65CE7310D09, - 7161ABCDB705E0F81662DC71, - 6EAAEC3D37B6CC538F2BAC98, - 6E0B73556F626E9DDB2F2F4C, - 0A5ED9AFC5906343E514100D, - BCE6AF6A2A5E7156836E5E7F, - B2E4733C1FB26F143C0C7344, - D4EE8C83FA9A3BB53AA747C0, ); name = commands; sourceTree = ""; }; + 4F5D668DCEF2B622FD46073D, + 791ADFB0FFAEE65058B6FC8A, + 0DB1323191C133E48F07C062, + D26821159E190113FEBF99BA, + A0F2EAF085969426AC73C85D, + D4BA573C125944E2773D747F, + 0D265DF78A9FE5E669F76FC3, + 9211B175E63E325D4FF6B789, + 3C825AE2479611DA559164B5, ); name = commands; sourceTree = ""; }; 815FFA61CB68244C4BFA9A78 = {isa = PBXGroup; children = ( - 7FCD0EF5D09B904A6D437BC9, - 3C31FCFF8570C5F2281B4774, - 1E7287FBD84D26D7C3247D65, - F47A2859B6F0F7800D4FFDAA, ); name = misc; sourceTree = ""; }; + E6D8902FFF0C8CDBB3E4BEA3, + F0B46A9181B1707349A20399, + FAB998A70437EE4D89CABE2F, + 96E4B48CF055ED116E5CB3AB, ); name = misc; sourceTree = ""; }; 8B10235D6698BCD336ECB195 = {isa = PBXGroup; children = ( - 5178CA597B45B186FEF4D2CD, - 015EBD22B273B9E6FA96D62F, ); name = application; sourceTree = ""; }; + B189762C440B38635351E0A3, + 47E5FB5735D2EC8B039D2691, ); name = application; sourceTree = ""; }; 3900F1137E25F9A2DEDF4119 = {isa = PBXGroup; children = ( - 8D9A85AC7668D98160EC607E, - E2940D3353B79053D215093F, - A2E38A6CEB042C6819BF032C, - F3D6E8D0058A92DE17677894, - F790D306D54E1295F9C7F9E1, - 069F8377EE5A3A1B8417E1BB, - E9E6FADE6A6F0B00452C0AD6, - C57F2A4DB4E9E55D5017A33F, - 90E99C139FF6443FAABA2729, - 036DAC2B35EB0E89897CDAF7, - 06D18753FCA84429B281A7CB, - 7F7C09BE9B70312CE6783717, - 7063EC546938B514B6EE8982, - D6ECAE5B0CC40752D559ABC4, - 57D9F9DA0E4AC9350182E868, - BCE458AC1B9E30F85B443851, ); name = native; sourceTree = ""; }; + 61E1C2246CBD45C5A1F40102, + 8866CF798E9F84C49B9D7DCC, + E1868998BA7B20DF7ED0B5E1, + 55A4B5CF98FAC1CC23E49C82, + F83392D9825422AF0DB638D0, + 2B4FA0E8FB46CBC71A059FE7, + 26C95A2DACFF9773038656E0, + 99A3B01A6398623F40C528FC, + 221FD10838A8CE36672FABC0, + 0EF8E3646F6099E89A743D99, + 7EB8C7E000F0DDAAB4F47802, + A7884EC24DD007D6232DB822, + 2A2B7F8BCFC785127CA961A9, + 562E99EE1A4B733B7F751955, + 90841E3B0B2548A5BD66F15E, + F95533D725E548643CA584D7, ); name = native; sourceTree = ""; }; 9A76685D3735D1F1DB8E4DB3 = {isa = PBXGroup; children = ( 978A5EA7C209E97691DF1580, 0A15D9E1577644179886B0D6, @@ -1812,130 +1812,130 @@ 815FFA61CB68244C4BFA9A78, 8B10235D6698BCD336ECB195, 3900F1137E25F9A2DEDF4119, - A232BF668A11B7015B65C33B, - 2DFA08EB2F2965C76C328560, ); name = "juce_gui_basics"; sourceTree = ""; }; + 0E8D536FEBD11AEA3C90B5A8, + D104C8636576DFE8A2D11430, ); name = "juce_gui_basics"; sourceTree = ""; }; 45216CE44016DA606FE98125 = {isa = PBXGroup; children = ( - 57F9DFFE80638F013ED82F0B, - D07A1E2DA76EA9CFBC9E3133, - 3289B1B53AFC6D7BDBDD850C, - 58F79BEACB41061A067708E4, - 688E8CBA135D8B2265E0B809, - 9F32845601855AC6DA5F14B0, - 358A3AED0462892CFDD11749, - A0D91BF6AFEC74B5349A3087, - 478C5F19200D7A3E3D0F3767, - 6F906DF202EB6B421F9C5813, - BE80DA6D586BB1C790B345E2, - 0E261C336A94816F61F6D1F9, ); name = "code_editor"; sourceTree = ""; }; + A7B28AD8606992FBE04C527C, + 13BF0388489EB44A816C9AF6, + 68FAA921E5D8CFAF9CC07C2F, + 191B98765219765CD56CCFED, + D2A5F78D0EF37F1E45DF39D4, + CC4B3BCEE612C95F27680EA9, + 69C36A56AE1A2E8CF64FE388, + 89ACAEA951C470AF8683AABD, + BAD1E66E3AA09ADD70061A50, + 91CEFA76775CD035E2F9200F, + 0852A866937712A0D30684A0, + FE1E97C9233F2D472C7C6128, ); name = "code_editor"; sourceTree = ""; }; 13374F67832C9086375A10EA = {isa = PBXGroup; children = ( - A395CC90104B14CC5D5D8F21, - B68C18758AC0A7570E067015, ); name = documents; sourceTree = ""; }; + 3BDF8DF3F3C380B1A4CE6C8F, + 8632589E0C21E3B0A5DA0333, ); name = documents; sourceTree = ""; }; 5BF35BC9897465D83C81C086 = {isa = PBXGroup; children = ( - B3669C5F60758B9D20E41583, - 7B849D43BE20E398A8B52F52, - 77F53EB4FD58030721224396, ); name = embedding; sourceTree = ""; }; + 0E894AC7229948568720E294, + C45AB95F4CDF31A41199E6D4, + 414AAB7000E7FDE7683BE72F, ); name = embedding; sourceTree = ""; }; 2E8513968E4CDE8852D85EFA = {isa = PBXGroup; children = ( - 2C43979AA3431CC3D61B94A1, - 11930669FC3C726CD1F9712F, - 70EAFCD75DD6A7C1FEBAB94F, - 3B5DE4A58F1A28D3DC2D5035, - 6481FF60536C5296C176F94B, - 7AB7CD2C0DB9B58AAA1A4B2F, - 9E47EC586E11C6F1AD2782C3, - B7F1AB21699A5EEEA59DA2AD, - 3669749528AFEB3D613D773E, - FBB2451FAA8812635B019B07, - 78D9F913D201ABD1349F023E, - 5CEC5FFCAF1B33BE9B86CDBE, - 73237A2CB197259364D09A76, - 7EA85C6C405022532A6F2F3A, - 3E199BBFEDF370A9853B91E3, - 3E25895B1FAD62C2E2DF985E, - 7CE1591D180C957070AE60F6, - DA41E1FA66C5B7218625EC70, - 836E25356E7C3A2534792936, - F27227DC9C5FD1ED9D39644E, ); name = misc; sourceTree = ""; }; + B401E96340B8AB5DE8CBF5C9, + BD588F8D5FD1E6FE88E9D3E4, + 531BA61B027758A7978052A4, + 0D0FAC9754D9469774B8DD2F, + CE0CE24264C96E86062E0250, + 519CE739793F0797AF1A7957, + 553655CA0122E128BC368AD7, + 77AE8FD7436387126D3BBBAC, + F9B00F8F537F74527F6C463C, + 2328C66A446079EDDCC8B14E, + 4D5901626201478A459CE46C, + 0790EC941834B64EA1AC8D5A, + E0EF847C7052C5FFA2A7CF8B, + 2254F8D031DD15BDB278DE3E, + F838183EDFF5937C2879EE41, + A0850087D0288361E552BE9A, + 9692128AC24CF671A9C0457B, + E29A372A41F835609F81CC43, + 394CD5017D81D1CFEBE34894, + 897C7B6FB012647ED8AB5D05, ); name = misc; sourceTree = ""; }; 626453A346165A7A0C138828 = {isa = PBXGroup; children = ( - 52CC3D36E2A4DD363F99DA9B, - F4666836A0E1D98969BF95D0, - 6D688EBEDAD32DBB4706CD39, - A00497528C590CECD253D1ED, - 9B1820674E3D99D9D4AB8DD9, - 6CC23E6F664F9114395C5DFD, - 4C512B82D4659142CAAB8390, - 703DEBC270B90BCBA7BCF714, - CB04786710DE206E794D272F, - A56E50AC91E42206FAD381F1, - 94614BC3AAA7263B1D6BDAE7, - 92800D0F94BA509EF80613A0, ); name = native; sourceTree = ""; }; + 805EB95DB4B8045064CE9ED3, + BA7FDBE53073F3261D962FF9, + 2B69AEC791776F7CF337E38C, + AD54DAEAB7840FC18DA65503, + 1A7002B936C11924FDC07023, + 66B37CB373F19F65553466C3, + F257AD1B82D5595FF9C3F1CA, + 71B0F66C20CF48F49B3152AF, + 21D0A71ADD004B35B90F0D1F, + 29685DC8679DB5024B747D0C, + DBDED1D6237A21D03E68D323, + 2C1B86FD1CB59198522DEF06, ); name = native; sourceTree = ""; }; B8479E2CF92E0AEE774BF1F3 = {isa = PBXGroup; children = ( 45216CE44016DA606FE98125, 13374F67832C9086375A10EA, 5BF35BC9897465D83C81C086, 2E8513968E4CDE8852D85EFA, 626453A346165A7A0C138828, - 4D97C6AE9A54A7F9663B0022, - 9C6E9983521DF4DFDD0C460B, ); name = "juce_gui_extra"; sourceTree = ""; }; + D57735149DD4975283A0C754, + 37381332DDDE8F2B3C66CBDE, ); name = "juce_gui_extra"; sourceTree = ""; }; A33BC9FA8A99B01DC485E60D = {isa = PBXGroup; children = ( - 171DE29200A3E7A8FB2D82F6, - B87D578105925ED8FFC105AE, - 7EDB44744DC44FB9DDECF9FF, - B58C5A06F8D666BCB074D981, - 01FF42E4D2A331779AB0A72C, - DDB38AD7F6C5A2E5E3725288, - 8669589118EF641C93336C4B, - D0197C6B54D5A5B8AB15A230, - 8910FF4F64E6AFD721B91B0D, - 20E9A48DD57A2BD4F3A8EC20, - 313A26829D5268C9E7B28E7E, - 795EA6840D307165BC0BBCD4, - C8915F6AB7855AF370A5581B, - 433E40D469ACDE64A8E40258, - EA14E79A40FE2177626ADD79, - D56DEA7CACE4A86351CDDD5B, - 321AC5D0FBCA00E825273253, ); name = opengl; sourceTree = ""; }; + A09CB6FA9736BD45103AFF46, + CDFAC8C57A364EEE32CE125E, + 166C141D440846E85F91747E, + 0D88ABF90B476D03D3684ABE, + 4510E3B6AD441EA03B993692, + A98EED399E310BF85EBBCE12, + 2188A5670214696EFCF6810F, + B0589203065E4CF2C002B0D9, + 0993051FFD1B0C5E92474DBD, + 28BEE3C7BE3AE2BD888AC55C, + CC96E8E65FDFE4376F71D7B0, + 6B5C2F14A2268F371F1350B5, + B60524021E6FC59416222870, + 4EB8D72F57E00C560E370DCB, + 08C7B33308A32555A7CA21B5, + 5C0E42BCF4ED32E1381E7A23, + 9CC0E3267A9D1EF3C8E37601, ); name = opengl; sourceTree = ""; }; 07ADD7BA5A96F719EDBCA037 = {isa = PBXGroup; children = ( - 9533D4846543EF2F80E7B561, - 933A312B0B63B032495B06C1, - 0180E266C4D70BE9C67AB07A, - 5B9FDDF7446043886E09E303, ); name = geometry; sourceTree = ""; }; + 5B5180DAAB935CB6D1DE9AA6, + 2C246301EE0EC4A9B4058F01, + DC94270BB4A70056907C3CDD, + 75D038033B2083D5EFE620A8, ); name = geometry; sourceTree = ""; }; 03621233E269E436B447C841 = {isa = PBXGroup; children = ( - 570EA0ADD7290B6AF6C74960, - D65828A1160764381EC4A290, ); name = utils; sourceTree = ""; }; + 44ADFB25768FA3BF27762EBF, + A058E50779879A7D9A813A4C, ); name = utils; sourceTree = ""; }; FC95F4C8E60C31B039992722 = {isa = PBXGroup; children = ( - AEB7028FB923A6FD7404A84C, - 24D1B8EBF0B291F684311B9F, - 49C6550365D3B05E7D030E2B, - FF0D0A3EFBB77DFC905FAFD8, - 549AA1BB3A58BFDDDDD1FA32, - 042881A3BC502717D187F4DF, - B4554AB60F9524B82FAC071C, ); name = native; sourceTree = ""; }; + 11D8AE26FA8880E7E8F3B4EB, + 518E9E553CD9F7D215B75B88, + EC9898734E8AFE5215705476, + 9DC79DF0A43DA6B06B7B1F44, + CF4E3CDCC9837C7E52197686, + 495EAFDB9DE4E8E7DBA562D4, + 877ED7656241F46291022910, ); name = native; sourceTree = ""; }; 0707779F272B825E3DF1560B = {isa = PBXGroup; children = ( A33BC9FA8A99B01DC485E60D, 07ADD7BA5A96F719EDBCA037, 03621233E269E436B447C841, FC95F4C8E60C31B039992722, - 7632DB6A2EA67505B1A5B4A8, - BBF1A328A57B8CA11F40D3B0, ); name = "juce_opengl"; sourceTree = ""; }; + 8D3FB0417A39CAEC03D44D73, + 4F96BFF5D1D40B81C861F92F, ); name = "juce_opengl"; sourceTree = ""; }; 62479F93E90EEE65EEC01FDA = {isa = PBXGroup; children = ( - 24A757C009624117895995B4, - 0FF684B2342825C25B6D5DBA, ); name = playback; sourceTree = ""; }; + B83DDFEEA66888E9616BCE82, + F113DFEACAF2D8230F0DF5E7, ); name = playback; sourceTree = ""; }; 616C504727E4806B3BB3980F = {isa = PBXGroup; children = ( - B08C35519C2E990041F82336, - 69EBBAC63BDB225AD7B9B19C, ); name = capture; sourceTree = ""; }; + DD03B6CE6F750A9CECA7EDEA, + 611A0824757D50610BB03562, ); name = capture; sourceTree = ""; }; E545E915D753CB44657CFE99 = {isa = PBXGroup; children = ( - 2F9BA19AD170D9B9F979B025, - 3D0CCA82BDEA501876257111, - D4FD4193ACDA02D2C3D8B5D6, - 21E54D17FED6BEB36D5C712B, - C989EB89ACD3E1E5122BDBAD, - 106CB8DA346ABAC39F9CBF67, ); name = native; sourceTree = ""; }; + 87E61959D8EA529461A0D257, + E0FCA8F19A081CE941B273FA, + 11ACB77A3D91503A3DF673C8, + ACAC59A1C54DC52E8E2438CC, + A281FFA1C7E3AFB8246FD577, + 71881F8A6973AACD78ABA719, ); name = native; sourceTree = ""; }; 397907CF13C78C70801F14D4 = {isa = PBXGroup; children = ( 62479F93E90EEE65EEC01FDA, 616C504727E4806B3BB3980F, E545E915D753CB44657CFE99, - 8FE90269A3BD4CDE641C5847, - A46624CB68D4D4FC6AFDDDB5, ); name = "juce_video"; sourceTree = ""; }; + 254D157C0CCE3C7EA022F4CE, + 693B6DC20214C1ED9C1E89F7, ); name = "juce_video"; sourceTree = ""; }; 7E2ABB7F81888EB9DF84E4C1 = {isa = PBXGroup; children = ( AF12826F0B38E7FC1176C648, 270A86F6A3CE512F0B3EA8DC, @@ -1952,19 +1952,19 @@ 397907CF13C78C70801F14D4, ); name = "Juce Modules"; sourceTree = ""; }; 5B8C542DD6E060115171CF66 = {isa = PBXGroup; children = ( A67C5701B28E64F889A92422, - 50CCC0CC14D17378013CFD72, - 08216A0328094D5809860DEB, - BC3EB76C434A2FDAC6C46DB2, - CB3D07088AB905BD96AD3A90, - 7FB3628856C8E532EB8421CA, - D728D4777A842A58EC01454A, - B6B4BC87EEA6BFF7A739D118, - 369EE12DB339DA919C8BF5F6, - 1291E6270CA79ACEEEFB2636, - 1DAF43BE112A30BC560E95ED, - 5A8383F3E5B628DE60DB8291, - 1A355A0DDA216F713372DF88, - 98FBBFD68CCC9D52B62BFFEE, + C1070E62B763F1CCE0BB18F0, + DD19124F0A7FD43F31BDEB87, + 987AD2821B6419D5FEDCBD7A, + AD405DDE86D07F955E27EBF8, + B7DD84C8B05ABA4A6915E77E, + 33E449DEA1FC0CD4CAA3A829, + 14BB261A450674034E6080F2, + CC0B7738BD544B955D81BF1E, + 4B27A11ADAC0D9957BBBCD3E, + 27B720A5E8CF81ABF9E50848, + D8BAA82AC820CEF315BD9DCB, + 21CF5364CD4910E49D19F8E2, + 6018A3A37F34AE52B39A14D5, 274569E245BFB279247B4ECC, ); name = "Juce Library Code"; sourceTree = ""; }; 9AF618BFAFEABB193C0E7D1A = {isa = PBXGroup; children = ( FF3D4768BC96B79F49B10894, @@ -2007,7 +2007,7 @@ "JUCE_APP_VERSION=1.0.0", "JUCE_APP_VERSION_HEX=0x10000", ); GCC_VERSION = com.apple.compilers.llvm.clang.1_0; - HEADER_SEARCH_PATHS = ("../../JuceLibraryCode", "../../JuceLibraryCode/modules", "$(inherited)"); + HEADER_SEARCH_PATHS = ("../../JuceLibraryCode", "../../../../modules", "$(inherited)"); INFOPLIST_FILE = Info.plist; INSTALL_PATH = "$(HOME)/Applications"; MACOSX_DEPLOYMENT_TARGET_ppc = 10.4; @@ -2028,7 +2028,7 @@ "JUCE_APP_VERSION_HEX=0x10000", ); GCC_SYMBOLS_PRIVATE_EXTERN = YES; GCC_VERSION = com.apple.compilers.llvm.clang.1_0; - HEADER_SEARCH_PATHS = ("../../JuceLibraryCode", "../../JuceLibraryCode/modules", "$(inherited)"); + HEADER_SEARCH_PATHS = ("../../JuceLibraryCode", "../../../../modules", "$(inherited)"); INFOPLIST_FILE = Info.plist; INSTALL_PATH = "$(HOME)/Applications"; MACOSX_DEPLOYMENT_TARGET_ppc = 10.4; @@ -2075,19 +2075,19 @@ BD6EB403A891DBC353F7D06C = {isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 328BFAEA24EDCBF7B69F4960, 84E6553798838003062A7791, - EF96289AD85C80471CACC5B6, - 6E1751B19D4AF902E028A7C7, - B1220D75CDAD50F3CA57D1A1, - 1C90AD3A9B9B5E9DE33BD2DE, - 777C7919C5F3C67E528286A1, - E3AF28976801708F8CD9A656, - A8E9942AA157F768897FBBA2, - 937B4A84B983E2AAA040F976, - EBFF0D5A17F1D61FC28BA178, - 129DFE2B7F1FDEE81E188D21, - 79A28D1FFAEAC8D7127BDE2F, - 526057FC6638B0BB7B984637, - 2FCBB2DDE322D55AFEF262AF, ); runOnlyForDeploymentPostprocessing = 0; }; + 9B303E67BC0058053878030C, + ACA92239BEB4C05C418642E2, + 1EFD155B1968AEC88851F831, + 0C7388B5872921063FF273B8, + 9EE1754A8E5230FA1C50713F, + 1852E56533842FDFBE9A6EE3, + CB79C1D77F4FBF0C64B69E1D, + 5E9EFF0130B8CBBEAA0D321B, + EF8AB3F393E946FE4A21AA17, + B70DDF51EDD940F5EF96B96D, + E28816D62DAA38A2794ED6D2, + A911433D03B3314558DB8850, + 590ABC7E64B05F4814FA919E, ); runOnlyForDeploymentPostprocessing = 0; }; F38385A81FAC837FA1743686 = {isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( E3498B080326636A372B74AE, 828D4B32ECB7ECE234A5A1A9, diff --git a/examples/AnimationAppExample/Builds/VisualStudio2010/AnimationAppExample.vcxproj b/examples/AnimationAppExample/Builds/VisualStudio2010/AnimationAppExample.vcxproj index e37b57e85c..b13bc9f835 100644 --- a/examples/AnimationAppExample/Builds/VisualStudio2010/AnimationAppExample.vcxproj +++ b/examples/AnimationAppExample/Builds/VisualStudio2010/AnimationAppExample.vcxproj @@ -51,7 +51,7 @@ Disabled EditAndContinue - ..\..\JuceLibraryCode;..\..\JuceLibraryCode\modules;%(AdditionalIncludeDirectories) + ..\..\JuceLibraryCode;..\..\..\..\modules;%(AdditionalIncludeDirectories) WIN32;_WINDOWS;DEBUG;_DEBUG;JUCER_VS2010_78A501D=1;JUCE_APP_VERSION=1.0.0;JUCE_APP_VERSION_HEX=0x10000;%(PreprocessorDefinitions) MultiThreadedDebug true @@ -92,7 +92,7 @@ MinSpace - ..\..\JuceLibraryCode;..\..\JuceLibraryCode\modules;%(AdditionalIncludeDirectories) + ..\..\JuceLibraryCode;..\..\..\..\modules;%(AdditionalIncludeDirectories) WIN32;_WINDOWS;NDEBUG;JUCER_VS2010_78A501D=1;JUCE_APP_VERSION=1.0.0;JUCE_APP_VERSION_HEX=0x10000;%(PreprocessorDefinitions) MultiThreaded true @@ -127,1567 +127,1567 @@ - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - - - - - - - - - - - - - + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - + + + + + + + + + + + + + diff --git a/examples/AnimationAppExample/Builds/VisualStudio2010/AnimationAppExample.vcxproj.filters b/examples/AnimationAppExample/Builds/VisualStudio2010/AnimationAppExample.vcxproj.filters index d9638504a8..6613933900 100644 --- a/examples/AnimationAppExample/Builds/VisualStudio2010/AnimationAppExample.vcxproj.filters +++ b/examples/AnimationAppExample/Builds/VisualStudio2010/AnimationAppExample.vcxproj.filters @@ -307,2535 +307,2535 @@ AnimationAppExample\Source - + Juce Modules\juce_audio_basics\buffers - + Juce Modules\juce_audio_basics\buffers - + Juce Modules\juce_audio_basics\buffers - + Juce Modules\juce_audio_basics\midi - + Juce Modules\juce_audio_basics\midi - + Juce Modules\juce_audio_basics\midi - + Juce Modules\juce_audio_basics\midi - + Juce Modules\juce_audio_basics\midi - + Juce Modules\juce_audio_basics\effects - + Juce Modules\juce_audio_basics\effects - + Juce Modules\juce_audio_basics\sources - + Juce Modules\juce_audio_basics\sources - + Juce Modules\juce_audio_basics\sources - + Juce Modules\juce_audio_basics\sources - + Juce Modules\juce_audio_basics\sources - + Juce Modules\juce_audio_basics\sources - + Juce Modules\juce_audio_basics\sources - + Juce Modules\juce_audio_basics\synthesisers - + Juce Modules\juce_audio_devices\audio_io - + Juce Modules\juce_audio_devices\audio_io - + Juce Modules\juce_audio_devices\audio_io - + Juce Modules\juce_audio_devices\midi_io - + Juce Modules\juce_audio_devices\midi_io - + Juce Modules\juce_audio_devices\sources - + Juce Modules\juce_audio_devices\sources - + Juce Modules\juce_audio_devices\audio_cd - + Juce Modules\juce_audio_devices\native - + Juce Modules\juce_audio_devices\native - + Juce Modules\juce_audio_devices\native - + Juce Modules\juce_audio_devices\native - + Juce Modules\juce_audio_devices\native - + Juce Modules\juce_audio_devices\native - + Juce Modules\juce_audio_devices\native - + Juce Modules\juce_audio_devices\native - + Juce Modules\juce_audio_devices\native - + Juce Modules\juce_audio_devices\native - + Juce Modules\juce_audio_devices\native - + Juce Modules\juce_audio_devices\native - + Juce Modules\juce_audio_devices\native - + Juce Modules\juce_audio_devices\native - + Juce Modules\juce_audio_devices\native - + Juce Modules\juce_audio_devices\native - + Juce Modules\juce_audio_devices\native - + Juce Modules\juce_audio_devices\native - + Juce Modules\juce_audio_formats\format - + Juce Modules\juce_audio_formats\format - + Juce Modules\juce_audio_formats\format - + Juce Modules\juce_audio_formats\format - + Juce Modules\juce_audio_formats\format - + Juce Modules\juce_audio_formats\format - + Juce Modules\juce_audio_formats\format - + Juce Modules\juce_audio_formats\codecs - + Juce Modules\juce_audio_formats\codecs - + Juce Modules\juce_audio_formats\codecs - + Juce Modules\juce_audio_formats\codecs - + Juce Modules\juce_audio_formats\codecs - + Juce Modules\juce_audio_formats\codecs - + Juce Modules\juce_audio_formats\codecs - + Juce Modules\juce_audio_formats\codecs - + Juce Modules\juce_audio_formats\codecs - + Juce Modules\juce_audio_formats\sampler - + Juce Modules\juce_audio_processors\processors - + Juce Modules\juce_audio_processors\processors - + Juce Modules\juce_audio_processors\processors - + Juce Modules\juce_audio_processors\processors - + Juce Modules\juce_audio_processors\processors - + Juce Modules\juce_audio_processors\format - + Juce Modules\juce_audio_processors\format - + Juce Modules\juce_audio_processors\format_types - + Juce Modules\juce_audio_processors\format_types - + Juce Modules\juce_audio_processors\format_types - + Juce Modules\juce_audio_processors\format_types - + Juce Modules\juce_audio_processors\scanning - + Juce Modules\juce_audio_processors\scanning - + Juce Modules\juce_audio_processors\scanning - + Juce Modules\juce_core\text - + Juce Modules\juce_core\text - + Juce Modules\juce_core\text - + Juce Modules\juce_core\text - + Juce Modules\juce_core\text - + Juce Modules\juce_core\text - + Juce Modules\juce_core\text - + Juce Modules\juce_core\text - + Juce Modules\juce_core\maths - + Juce Modules\juce_core\maths - + Juce Modules\juce_core\maths - + Juce Modules\juce_core\memory - + Juce Modules\juce_core\containers - + Juce Modules\juce_core\containers - + Juce Modules\juce_core\containers - + Juce Modules\juce_core\containers - + Juce Modules\juce_core\containers - + Juce Modules\juce_core\threads - + Juce Modules\juce_core\threads - + Juce Modules\juce_core\threads - + Juce Modules\juce_core\threads - + Juce Modules\juce_core\threads - + Juce Modules\juce_core\threads - + Juce Modules\juce_core\time - + Juce Modules\juce_core\time - + Juce Modules\juce_core\time - + Juce Modules\juce_core\files - + Juce Modules\juce_core\files - + Juce Modules\juce_core\files - + Juce Modules\juce_core\files - + Juce Modules\juce_core\files - + Juce Modules\juce_core\files - + Juce Modules\juce_core\files - + Juce Modules\juce_core\files - + Juce Modules\juce_core\network - + Juce Modules\juce_core\network - + Juce Modules\juce_core\network - + Juce Modules\juce_core\network - + Juce Modules\juce_core\network - + Juce Modules\juce_core\streams - + Juce Modules\juce_core\streams - + Juce Modules\juce_core\streams - + Juce Modules\juce_core\streams - + Juce Modules\juce_core\streams - + Juce Modules\juce_core\streams - + Juce Modules\juce_core\streams - + Juce Modules\juce_core\logging - + Juce Modules\juce_core\logging - + Juce Modules\juce_core\system - + Juce Modules\juce_core\xml - + Juce Modules\juce_core\xml - + Juce Modules\juce_core\javascript - + Juce Modules\juce_core\javascript - + Juce Modules\juce_core\zip - + Juce Modules\juce_core\zip - + Juce Modules\juce_core\zip - + Juce Modules\juce_core\unit_tests - + Juce Modules\juce_core\misc - + Juce Modules\juce_core\misc - + Juce Modules\juce_core\native - + Juce Modules\juce_core\native - + Juce Modules\juce_core\native - + Juce Modules\juce_core\native - + Juce Modules\juce_core\native - + Juce Modules\juce_core\native - + Juce Modules\juce_core\native - + Juce Modules\juce_core\native - + Juce Modules\juce_core\native - + Juce Modules\juce_core\native - + Juce Modules\juce_core\native - + Juce Modules\juce_core\native - + Juce Modules\juce_core\native - + Juce Modules\juce_core\native - + Juce Modules\juce_core\native - + Juce Modules\juce_core\native - + Juce Modules\juce_core\native - + Juce Modules\juce_core\native - + Juce Modules\juce_core\native - + Juce Modules\juce_core\native - + Juce Modules\juce_core\native - + Juce Modules\juce_cryptography\encryption - + Juce Modules\juce_cryptography\encryption - + Juce Modules\juce_cryptography\encryption - + Juce Modules\juce_cryptography\hashing - + Juce Modules\juce_cryptography\hashing - + Juce Modules\juce_data_structures\values - + Juce Modules\juce_data_structures\values - + Juce Modules\juce_data_structures\undomanager - + Juce Modules\juce_data_structures\app_properties - + Juce Modules\juce_data_structures\app_properties - + Juce Modules\juce_events\messages - + Juce Modules\juce_events\messages - + Juce Modules\juce_events\messages - + Juce Modules\juce_events\messages - + Juce Modules\juce_events\timers - + Juce Modules\juce_events\timers - + Juce Modules\juce_events\broadcasters - + Juce Modules\juce_events\broadcasters - + Juce Modules\juce_events\broadcasters - + Juce Modules\juce_events\interprocess - + Juce Modules\juce_events\interprocess - + Juce Modules\juce_events\interprocess - + Juce Modules\juce_events\native - + Juce Modules\juce_events\native - + Juce Modules\juce_events\native - + Juce Modules\juce_events\native - + Juce Modules\juce_events\native - + Juce Modules\juce_graphics\colour - + Juce Modules\juce_graphics\colour - + Juce Modules\juce_graphics\colour - + Juce Modules\juce_graphics\colour - + Juce Modules\juce_graphics\contexts - + Juce Modules\juce_graphics\contexts - + Juce Modules\juce_graphics\contexts - + Juce Modules\juce_graphics\images - + Juce Modules\juce_graphics\images - + Juce Modules\juce_graphics\images - + Juce Modules\juce_graphics\images - + Juce Modules\juce_graphics\image_formats - + Juce Modules\juce_graphics\image_formats - + Juce Modules\juce_graphics\image_formats - + Juce Modules\juce_graphics\geometry - + Juce Modules\juce_graphics\geometry - + Juce Modules\juce_graphics\geometry - + Juce Modules\juce_graphics\geometry - + Juce Modules\juce_graphics\geometry - + Juce Modules\juce_graphics\placement - + Juce Modules\juce_graphics\fonts - + Juce Modules\juce_graphics\fonts - + Juce Modules\juce_graphics\fonts - + Juce Modules\juce_graphics\fonts - + Juce Modules\juce_graphics\fonts - + Juce Modules\juce_graphics\fonts - + Juce Modules\juce_graphics\effects - + Juce Modules\juce_graphics\effects - + Juce Modules\juce_graphics\native - + Juce Modules\juce_graphics\native - + Juce Modules\juce_graphics\native - + Juce Modules\juce_graphics\native - + Juce Modules\juce_graphics\native - + Juce Modules\juce_graphics\native - + Juce Modules\juce_graphics\native - + Juce Modules\juce_graphics\native - + Juce Modules\juce_graphics\native - + Juce Modules\juce_graphics\native - + Juce Modules\juce_gui_basics\components - + Juce Modules\juce_gui_basics\components - + Juce Modules\juce_gui_basics\components - + Juce Modules\juce_gui_basics\components - + Juce Modules\juce_gui_basics\mouse - + Juce Modules\juce_gui_basics\mouse - + Juce Modules\juce_gui_basics\mouse - + Juce Modules\juce_gui_basics\mouse - + Juce Modules\juce_gui_basics\mouse - + Juce Modules\juce_gui_basics\mouse - + Juce Modules\juce_gui_basics\mouse - + Juce Modules\juce_gui_basics\keyboard - + Juce Modules\juce_gui_basics\keyboard - + Juce Modules\juce_gui_basics\keyboard - + Juce Modules\juce_gui_basics\keyboard - + Juce Modules\juce_gui_basics\keyboard - + Juce Modules\juce_gui_basics\widgets - + Juce Modules\juce_gui_basics\widgets - + Juce Modules\juce_gui_basics\widgets - + Juce Modules\juce_gui_basics\widgets - + Juce Modules\juce_gui_basics\widgets - + Juce Modules\juce_gui_basics\widgets - + Juce Modules\juce_gui_basics\widgets - + Juce Modules\juce_gui_basics\widgets - + Juce Modules\juce_gui_basics\widgets - + Juce Modules\juce_gui_basics\widgets - + Juce Modules\juce_gui_basics\widgets - + Juce Modules\juce_gui_basics\widgets - + Juce Modules\juce_gui_basics\widgets - + Juce Modules\juce_gui_basics\windows - + Juce Modules\juce_gui_basics\windows - + Juce Modules\juce_gui_basics\windows - + Juce Modules\juce_gui_basics\windows - + Juce Modules\juce_gui_basics\windows - + Juce Modules\juce_gui_basics\windows - + Juce Modules\juce_gui_basics\windows - + Juce Modules\juce_gui_basics\windows - + Juce Modules\juce_gui_basics\windows - + Juce Modules\juce_gui_basics\menus - + Juce Modules\juce_gui_basics\menus - + Juce Modules\juce_gui_basics\menus - + Juce Modules\juce_gui_basics\layout - + Juce Modules\juce_gui_basics\layout - + Juce Modules\juce_gui_basics\layout - + Juce Modules\juce_gui_basics\layout - + Juce Modules\juce_gui_basics\layout - + Juce Modules\juce_gui_basics\layout - + Juce Modules\juce_gui_basics\layout - + Juce Modules\juce_gui_basics\layout - + Juce Modules\juce_gui_basics\layout - + Juce Modules\juce_gui_basics\layout - + Juce Modules\juce_gui_basics\layout - + Juce Modules\juce_gui_basics\layout - + Juce Modules\juce_gui_basics\layout - + Juce Modules\juce_gui_basics\layout - + Juce Modules\juce_gui_basics\layout - + Juce Modules\juce_gui_basics\layout - + Juce Modules\juce_gui_basics\layout - + Juce Modules\juce_gui_basics\buttons - + Juce Modules\juce_gui_basics\buttons - + Juce Modules\juce_gui_basics\buttons - + Juce Modules\juce_gui_basics\buttons - + Juce Modules\juce_gui_basics\buttons - + Juce Modules\juce_gui_basics\buttons - + Juce Modules\juce_gui_basics\buttons - + Juce Modules\juce_gui_basics\buttons - + Juce Modules\juce_gui_basics\buttons - + Juce Modules\juce_gui_basics\positioning - + Juce Modules\juce_gui_basics\positioning - + Juce Modules\juce_gui_basics\positioning - + Juce Modules\juce_gui_basics\positioning - + Juce Modules\juce_gui_basics\positioning - + Juce Modules\juce_gui_basics\positioning - + Juce Modules\juce_gui_basics\positioning - + Juce Modules\juce_gui_basics\drawables - + Juce Modules\juce_gui_basics\drawables - + Juce Modules\juce_gui_basics\drawables - + Juce Modules\juce_gui_basics\drawables - + Juce Modules\juce_gui_basics\drawables - + Juce Modules\juce_gui_basics\drawables - + Juce Modules\juce_gui_basics\drawables - + Juce Modules\juce_gui_basics\drawables - + Juce Modules\juce_gui_basics\properties - + Juce Modules\juce_gui_basics\properties - + Juce Modules\juce_gui_basics\properties - + Juce Modules\juce_gui_basics\properties - + Juce Modules\juce_gui_basics\properties - + Juce Modules\juce_gui_basics\properties - + Juce Modules\juce_gui_basics\properties - + Juce Modules\juce_gui_basics\lookandfeel - + Juce Modules\juce_gui_basics\lookandfeel - + Juce Modules\juce_gui_basics\lookandfeel - + Juce Modules\juce_gui_basics\lookandfeel - + Juce Modules\juce_gui_basics\filebrowser - + Juce Modules\juce_gui_basics\filebrowser - + Juce Modules\juce_gui_basics\filebrowser - + Juce Modules\juce_gui_basics\filebrowser - + Juce Modules\juce_gui_basics\filebrowser - + Juce Modules\juce_gui_basics\filebrowser - + Juce Modules\juce_gui_basics\filebrowser - + Juce Modules\juce_gui_basics\filebrowser - + Juce Modules\juce_gui_basics\filebrowser - + Juce Modules\juce_gui_basics\filebrowser - + Juce Modules\juce_gui_basics\commands - + Juce Modules\juce_gui_basics\commands - + Juce Modules\juce_gui_basics\commands - + Juce Modules\juce_gui_basics\commands - + Juce Modules\juce_gui_basics\misc - + Juce Modules\juce_gui_basics\misc - + Juce Modules\juce_gui_basics\application - + Juce Modules\juce_gui_basics\native - + Juce Modules\juce_gui_basics\native - + Juce Modules\juce_gui_basics\native - + Juce Modules\juce_gui_basics\native - + Juce Modules\juce_gui_basics\native - + Juce Modules\juce_gui_basics\native - + Juce Modules\juce_gui_basics\native - + Juce Modules\juce_gui_basics\native - + Juce Modules\juce_gui_basics\native - + Juce Modules\juce_gui_basics\native - + Juce Modules\juce_gui_basics\native - + Juce Modules\juce_gui_basics\native - + Juce Modules\juce_gui_basics\native - + Juce Modules\juce_gui_basics\native - + Juce Modules\juce_gui_basics\native - + Juce Modules\juce_gui_extra\code_editor - + Juce Modules\juce_gui_extra\code_editor - + Juce Modules\juce_gui_extra\code_editor - + Juce Modules\juce_gui_extra\code_editor - + Juce Modules\juce_gui_extra\code_editor - + Juce Modules\juce_gui_extra\documents - + Juce Modules\juce_gui_extra\misc - + Juce Modules\juce_gui_extra\misc - + Juce Modules\juce_gui_extra\misc - + Juce Modules\juce_gui_extra\misc - + Juce Modules\juce_gui_extra\misc - + Juce Modules\juce_gui_extra\misc - + Juce Modules\juce_gui_extra\misc - + Juce Modules\juce_gui_extra\misc - + Juce Modules\juce_gui_extra\misc - + Juce Modules\juce_gui_extra\native - + Juce Modules\juce_gui_extra\native - + Juce Modules\juce_gui_extra\native - + Juce Modules\juce_gui_extra\native - + Juce Modules\juce_gui_extra\native - + Juce Modules\juce_gui_extra\native - + Juce Modules\juce_gui_extra\native - + Juce Modules\juce_gui_extra\native - + Juce Modules\juce_gui_extra\native - + Juce Modules\juce_gui_extra\native - + Juce Modules\juce_gui_extra\native - + Juce Modules\juce_opengl\opengl - + Juce Modules\juce_opengl\opengl - + Juce Modules\juce_opengl\opengl - + Juce Modules\juce_opengl\opengl - + Juce Modules\juce_opengl\opengl - + Juce Modules\juce_opengl\opengl - + Juce Modules\juce_opengl\opengl - + Juce Modules\juce_opengl\opengl - + Juce Modules\juce_opengl\utils - + Juce Modules\juce_video\capture - + Juce Modules\juce_video\native - + Juce Modules\juce_video\native - + Juce Modules\juce_video\native - + Juce Modules\juce_video\native - + Juce Modules\juce_video\native - + Juce Modules\juce_video\native - + Juce Library Code - + Juce Library Code - + Juce Library Code - + Juce Library Code - + Juce Library Code - + Juce Library Code - + Juce Library Code - + Juce Library Code - + Juce Library Code - + Juce Library Code - + Juce Library Code - + Juce Library Code - + Juce Library Code - + Juce Modules\juce_audio_basics\buffers - + Juce Modules\juce_audio_basics\buffers - + Juce Modules\juce_audio_basics\buffers - + Juce Modules\juce_audio_basics\midi - + Juce Modules\juce_audio_basics\midi - + Juce Modules\juce_audio_basics\midi - + Juce Modules\juce_audio_basics\midi - + Juce Modules\juce_audio_basics\midi - + Juce Modules\juce_audio_basics\effects - + Juce Modules\juce_audio_basics\effects - + Juce Modules\juce_audio_basics\effects - + Juce Modules\juce_audio_basics\effects - + Juce Modules\juce_audio_basics\sources - + Juce Modules\juce_audio_basics\sources - + Juce Modules\juce_audio_basics\sources - + Juce Modules\juce_audio_basics\sources - + Juce Modules\juce_audio_basics\sources - + Juce Modules\juce_audio_basics\sources - + Juce Modules\juce_audio_basics\sources - + Juce Modules\juce_audio_basics\sources - + Juce Modules\juce_audio_basics\sources - + Juce Modules\juce_audio_basics\synthesisers - + Juce Modules\juce_audio_basics - + Juce Modules\juce_audio_devices\audio_io - + Juce Modules\juce_audio_devices\audio_io - + Juce Modules\juce_audio_devices\audio_io - + Juce Modules\juce_audio_devices\audio_io - + Juce Modules\juce_audio_devices\midi_io - + Juce Modules\juce_audio_devices\midi_io - + Juce Modules\juce_audio_devices\midi_io - + Juce Modules\juce_audio_devices\sources - + Juce Modules\juce_audio_devices\sources - + Juce Modules\juce_audio_devices\audio_cd - + Juce Modules\juce_audio_devices\audio_cd - + Juce Modules\juce_audio_devices\native - + Juce Modules\juce_audio_devices - + Juce Modules\juce_audio_formats\format - + Juce Modules\juce_audio_formats\format - + Juce Modules\juce_audio_formats\format - + Juce Modules\juce_audio_formats\format - + Juce Modules\juce_audio_formats\format - + Juce Modules\juce_audio_formats\format - + Juce Modules\juce_audio_formats\format - + Juce Modules\juce_audio_formats\format - + Juce Modules\juce_audio_formats\codecs - + Juce Modules\juce_audio_formats\codecs - + Juce Modules\juce_audio_formats\codecs - + Juce Modules\juce_audio_formats\codecs - + Juce Modules\juce_audio_formats\codecs - + Juce Modules\juce_audio_formats\codecs - + Juce Modules\juce_audio_formats\codecs - + Juce Modules\juce_audio_formats\codecs - + Juce Modules\juce_audio_formats\codecs - + Juce Modules\juce_audio_formats\sampler - + Juce Modules\juce_audio_formats - + Juce Modules\juce_audio_processors\processors - + Juce Modules\juce_audio_processors\processors - + Juce Modules\juce_audio_processors\processors - + Juce Modules\juce_audio_processors\processors - + Juce Modules\juce_audio_processors\processors - + Juce Modules\juce_audio_processors\processors - + Juce Modules\juce_audio_processors\processors - + Juce Modules\juce_audio_processors\processors - + Juce Modules\juce_audio_processors\processors - + Juce Modules\juce_audio_processors\format - + Juce Modules\juce_audio_processors\format - + Juce Modules\juce_audio_processors\format_types - + Juce Modules\juce_audio_processors\format_types - + Juce Modules\juce_audio_processors\format_types - + Juce Modules\juce_audio_processors\format_types - + Juce Modules\juce_audio_processors\format_types - + Juce Modules\juce_audio_processors\format_types - + Juce Modules\juce_audio_processors\format_types - + Juce Modules\juce_audio_processors\scanning - + Juce Modules\juce_audio_processors\scanning - + Juce Modules\juce_audio_processors\scanning - + Juce Modules\juce_audio_processors - + Juce Modules\juce_core\text - + Juce Modules\juce_core\text - + Juce Modules\juce_core\text - + Juce Modules\juce_core\text - + Juce Modules\juce_core\text - + Juce Modules\juce_core\text - + Juce Modules\juce_core\text - + Juce Modules\juce_core\text - + Juce Modules\juce_core\text - + Juce Modules\juce_core\text - + Juce Modules\juce_core\text - + Juce Modules\juce_core\text - + Juce Modules\juce_core\text - + Juce Modules\juce_core\text - + Juce Modules\juce_core\maths - + Juce Modules\juce_core\maths - + Juce Modules\juce_core\maths - + Juce Modules\juce_core\maths - + Juce Modules\juce_core\maths - + Juce Modules\juce_core\maths - + Juce Modules\juce_core\memory - + Juce Modules\juce_core\memory - + Juce Modules\juce_core\memory - + Juce Modules\juce_core\memory - + Juce Modules\juce_core\memory - + Juce Modules\juce_core\memory - + Juce Modules\juce_core\memory - + Juce Modules\juce_core\memory - + Juce Modules\juce_core\memory - + Juce Modules\juce_core\memory - + Juce Modules\juce_core\memory - + Juce Modules\juce_core\memory - + Juce Modules\juce_core\memory - + Juce Modules\juce_core\containers - + Juce Modules\juce_core\containers - + Juce Modules\juce_core\containers - + Juce Modules\juce_core\containers - + Juce Modules\juce_core\containers - + Juce Modules\juce_core\containers - + Juce Modules\juce_core\containers - + Juce Modules\juce_core\containers - + Juce Modules\juce_core\containers - + Juce Modules\juce_core\containers - + Juce Modules\juce_core\containers - + Juce Modules\juce_core\containers - + Juce Modules\juce_core\containers - + Juce Modules\juce_core\containers - + Juce Modules\juce_core\containers - + Juce Modules\juce_core\threads - + Juce Modules\juce_core\threads - + Juce Modules\juce_core\threads - + Juce Modules\juce_core\threads - + Juce Modules\juce_core\threads - + Juce Modules\juce_core\threads - + Juce Modules\juce_core\threads - + Juce Modules\juce_core\threads - + Juce Modules\juce_core\threads - + Juce Modules\juce_core\threads - + Juce Modules\juce_core\threads - + Juce Modules\juce_core\threads - + Juce Modules\juce_core\threads - + Juce Modules\juce_core\threads - + Juce Modules\juce_core\threads - + Juce Modules\juce_core\threads - + Juce Modules\juce_core\time - + Juce Modules\juce_core\time - + Juce Modules\juce_core\time - + Juce Modules\juce_core\files - + Juce Modules\juce_core\files - + Juce Modules\juce_core\files - + Juce Modules\juce_core\files - + Juce Modules\juce_core\files - + Juce Modules\juce_core\files - + Juce Modules\juce_core\files - + Juce Modules\juce_core\files - + Juce Modules\juce_core\files - + Juce Modules\juce_core\network - + Juce Modules\juce_core\network - + Juce Modules\juce_core\network - + Juce Modules\juce_core\network - + Juce Modules\juce_core\network - + Juce Modules\juce_core\streams - + Juce Modules\juce_core\streams - + Juce Modules\juce_core\streams - + Juce Modules\juce_core\streams - + Juce Modules\juce_core\streams - + Juce Modules\juce_core\streams - + Juce Modules\juce_core\streams - + Juce Modules\juce_core\streams - + Juce Modules\juce_core\logging - + Juce Modules\juce_core\logging - + Juce Modules\juce_core\system - + Juce Modules\juce_core\system - + Juce Modules\juce_core\system - + Juce Modules\juce_core\system - + Juce Modules\juce_core\system - + Juce Modules\juce_core\xml - + Juce Modules\juce_core\xml - + Juce Modules\juce_core\javascript - + Juce Modules\juce_core\javascript - + Juce Modules\juce_core\zip - + Juce Modules\juce_core\zip - + Juce Modules\juce_core\zip - + Juce Modules\juce_core\unit_tests - + Juce Modules\juce_core\misc - + Juce Modules\juce_core\misc - + Juce Modules\juce_core\misc - + Juce Modules\juce_core\native - + Juce Modules\juce_core\native - + Juce Modules\juce_core\native - + Juce Modules\juce_core\native - + Juce Modules\juce_core\native - + Juce Modules\juce_core - + Juce Modules\juce_cryptography\encryption - + Juce Modules\juce_cryptography\encryption - + Juce Modules\juce_cryptography\encryption - + Juce Modules\juce_cryptography\hashing - + Juce Modules\juce_cryptography\hashing - + Juce Modules\juce_cryptography - + Juce Modules\juce_data_structures\values - + Juce Modules\juce_data_structures\values - + Juce Modules\juce_data_structures\undomanager - + Juce Modules\juce_data_structures\undomanager - + Juce Modules\juce_data_structures\app_properties - + Juce Modules\juce_data_structures\app_properties - + Juce Modules\juce_data_structures - + Juce Modules\juce_events\messages - + Juce Modules\juce_events\messages - + Juce Modules\juce_events\messages - + Juce Modules\juce_events\messages - + Juce Modules\juce_events\messages - + Juce Modules\juce_events\messages - + Juce Modules\juce_events\messages - + Juce Modules\juce_events\messages - + Juce Modules\juce_events\messages - + Juce Modules\juce_events\timers - + Juce Modules\juce_events\timers - + Juce Modules\juce_events\broadcasters - + Juce Modules\juce_events\broadcasters - + Juce Modules\juce_events\broadcasters - + Juce Modules\juce_events\broadcasters - + Juce Modules\juce_events\broadcasters - + Juce Modules\juce_events\broadcasters - + Juce Modules\juce_events\interprocess - + Juce Modules\juce_events\interprocess - + Juce Modules\juce_events\interprocess - + Juce Modules\juce_events\native - + Juce Modules\juce_events\native - + Juce Modules\juce_events\native - + Juce Modules\juce_events - + Juce Modules\juce_graphics\colour - + Juce Modules\juce_graphics\colour - + Juce Modules\juce_graphics\colour - + Juce Modules\juce_graphics\colour - + Juce Modules\juce_graphics\colour - + Juce Modules\juce_graphics\contexts - + Juce Modules\juce_graphics\contexts - + Juce Modules\juce_graphics\contexts - + Juce Modules\juce_graphics\contexts - + Juce Modules\juce_graphics\images - + Juce Modules\juce_graphics\images - + Juce Modules\juce_graphics\images - + Juce Modules\juce_graphics\images - + Juce Modules\juce_graphics\geometry - + Juce Modules\juce_graphics\geometry - + Juce Modules\juce_graphics\geometry - + Juce Modules\juce_graphics\geometry - + Juce Modules\juce_graphics\geometry - + Juce Modules\juce_graphics\geometry - + Juce Modules\juce_graphics\geometry - + Juce Modules\juce_graphics\geometry - + Juce Modules\juce_graphics\geometry - + Juce Modules\juce_graphics\geometry - + Juce Modules\juce_graphics\placement - + Juce Modules\juce_graphics\placement - + Juce Modules\juce_graphics\fonts - + Juce Modules\juce_graphics\fonts - + Juce Modules\juce_graphics\fonts - + Juce Modules\juce_graphics\fonts - + Juce Modules\juce_graphics\fonts - + Juce Modules\juce_graphics\fonts - + Juce Modules\juce_graphics\effects - + Juce Modules\juce_graphics\effects - + Juce Modules\juce_graphics\effects - + Juce Modules\juce_graphics\native - + Juce Modules\juce_graphics\native - + Juce Modules\juce_graphics\native - + Juce Modules\juce_graphics - + Juce Modules\juce_gui_basics\components - + Juce Modules\juce_gui_basics\components - + Juce Modules\juce_gui_basics\components - + Juce Modules\juce_gui_basics\components - + Juce Modules\juce_gui_basics\components - + Juce Modules\juce_gui_basics\mouse - + Juce Modules\juce_gui_basics\mouse - + Juce Modules\juce_gui_basics\mouse - + Juce Modules\juce_gui_basics\mouse - + Juce Modules\juce_gui_basics\mouse - + Juce Modules\juce_gui_basics\mouse - + Juce Modules\juce_gui_basics\mouse - + Juce Modules\juce_gui_basics\mouse - + Juce Modules\juce_gui_basics\mouse - + Juce Modules\juce_gui_basics\mouse - + Juce Modules\juce_gui_basics\mouse - + Juce Modules\juce_gui_basics\mouse - + Juce Modules\juce_gui_basics\mouse - + Juce Modules\juce_gui_basics\keyboard - + Juce Modules\juce_gui_basics\keyboard - + Juce Modules\juce_gui_basics\keyboard - + Juce Modules\juce_gui_basics\keyboard - + Juce Modules\juce_gui_basics\keyboard - + Juce Modules\juce_gui_basics\keyboard - + Juce Modules\juce_gui_basics\keyboard - + Juce Modules\juce_gui_basics\keyboard - + Juce Modules\juce_gui_basics\widgets - + Juce Modules\juce_gui_basics\widgets - + Juce Modules\juce_gui_basics\widgets - + Juce Modules\juce_gui_basics\widgets - + Juce Modules\juce_gui_basics\widgets - + Juce Modules\juce_gui_basics\widgets - + Juce Modules\juce_gui_basics\widgets - + Juce Modules\juce_gui_basics\widgets - + Juce Modules\juce_gui_basics\widgets - + Juce Modules\juce_gui_basics\widgets - + Juce Modules\juce_gui_basics\widgets - + Juce Modules\juce_gui_basics\widgets - + Juce Modules\juce_gui_basics\widgets - + Juce Modules\juce_gui_basics\widgets - + Juce Modules\juce_gui_basics\windows - + Juce Modules\juce_gui_basics\windows - + Juce Modules\juce_gui_basics\windows - + Juce Modules\juce_gui_basics\windows - + Juce Modules\juce_gui_basics\windows - + Juce Modules\juce_gui_basics\windows - + Juce Modules\juce_gui_basics\windows - + Juce Modules\juce_gui_basics\windows - + Juce Modules\juce_gui_basics\windows - + Juce Modules\juce_gui_basics\windows - + Juce Modules\juce_gui_basics\menus - + Juce Modules\juce_gui_basics\menus - + Juce Modules\juce_gui_basics\menus - + Juce Modules\juce_gui_basics\layout - + Juce Modules\juce_gui_basics\layout - + Juce Modules\juce_gui_basics\layout - + Juce Modules\juce_gui_basics\layout - + Juce Modules\juce_gui_basics\layout - + Juce Modules\juce_gui_basics\layout - + Juce Modules\juce_gui_basics\layout - + Juce Modules\juce_gui_basics\layout - + Juce Modules\juce_gui_basics\layout - + Juce Modules\juce_gui_basics\layout - + Juce Modules\juce_gui_basics\layout - + Juce Modules\juce_gui_basics\layout - + Juce Modules\juce_gui_basics\layout - + Juce Modules\juce_gui_basics\layout - + Juce Modules\juce_gui_basics\layout - + Juce Modules\juce_gui_basics\layout - + Juce Modules\juce_gui_basics\layout - + Juce Modules\juce_gui_basics\layout - + Juce Modules\juce_gui_basics\layout - + Juce Modules\juce_gui_basics\buttons - + Juce Modules\juce_gui_basics\buttons - + Juce Modules\juce_gui_basics\buttons - + Juce Modules\juce_gui_basics\buttons - + Juce Modules\juce_gui_basics\buttons - + Juce Modules\juce_gui_basics\buttons - + Juce Modules\juce_gui_basics\buttons - + Juce Modules\juce_gui_basics\buttons - + Juce Modules\juce_gui_basics\buttons - + Juce Modules\juce_gui_basics\positioning - + Juce Modules\juce_gui_basics\positioning - + Juce Modules\juce_gui_basics\positioning - + Juce Modules\juce_gui_basics\positioning - + Juce Modules\juce_gui_basics\positioning - + Juce Modules\juce_gui_basics\positioning - + Juce Modules\juce_gui_basics\positioning - + Juce Modules\juce_gui_basics\drawables - + Juce Modules\juce_gui_basics\drawables - + Juce Modules\juce_gui_basics\drawables - + Juce Modules\juce_gui_basics\drawables - + Juce Modules\juce_gui_basics\drawables - + Juce Modules\juce_gui_basics\drawables - + Juce Modules\juce_gui_basics\drawables - + Juce Modules\juce_gui_basics\properties - + Juce Modules\juce_gui_basics\properties - + Juce Modules\juce_gui_basics\properties - + Juce Modules\juce_gui_basics\properties - + Juce Modules\juce_gui_basics\properties - + Juce Modules\juce_gui_basics\properties - + Juce Modules\juce_gui_basics\properties - + Juce Modules\juce_gui_basics\lookandfeel - + Juce Modules\juce_gui_basics\lookandfeel - + Juce Modules\juce_gui_basics\lookandfeel - + Juce Modules\juce_gui_basics\lookandfeel - + Juce Modules\juce_gui_basics\filebrowser - + Juce Modules\juce_gui_basics\filebrowser - + Juce Modules\juce_gui_basics\filebrowser - + Juce Modules\juce_gui_basics\filebrowser - + Juce Modules\juce_gui_basics\filebrowser - + Juce Modules\juce_gui_basics\filebrowser - + Juce Modules\juce_gui_basics\filebrowser - + Juce Modules\juce_gui_basics\filebrowser - + Juce Modules\juce_gui_basics\filebrowser - + Juce Modules\juce_gui_basics\filebrowser - + Juce Modules\juce_gui_basics\filebrowser - + Juce Modules\juce_gui_basics\filebrowser - + Juce Modules\juce_gui_basics\commands - + Juce Modules\juce_gui_basics\commands - + Juce Modules\juce_gui_basics\commands - + Juce Modules\juce_gui_basics\commands - + Juce Modules\juce_gui_basics\commands - + Juce Modules\juce_gui_basics\misc - + Juce Modules\juce_gui_basics\misc - + Juce Modules\juce_gui_basics\application - + Juce Modules\juce_gui_basics\native - + Juce Modules\juce_gui_basics - + Juce Modules\juce_gui_extra\code_editor - + Juce Modules\juce_gui_extra\code_editor - + Juce Modules\juce_gui_extra\code_editor - + Juce Modules\juce_gui_extra\code_editor - + Juce Modules\juce_gui_extra\code_editor - + Juce Modules\juce_gui_extra\code_editor - + Juce Modules\juce_gui_extra\code_editor - + Juce Modules\juce_gui_extra\documents - + Juce Modules\juce_gui_extra\embedding - + Juce Modules\juce_gui_extra\embedding - + Juce Modules\juce_gui_extra\embedding - + Juce Modules\juce_gui_extra\misc - + Juce Modules\juce_gui_extra\misc - + Juce Modules\juce_gui_extra\misc - + Juce Modules\juce_gui_extra\misc - + Juce Modules\juce_gui_extra\misc - + Juce Modules\juce_gui_extra\misc - + Juce Modules\juce_gui_extra\misc - + Juce Modules\juce_gui_extra\misc - + Juce Modules\juce_gui_extra\misc - + Juce Modules\juce_gui_extra\misc - + Juce Modules\juce_gui_extra\misc - + Juce Modules\juce_gui_extra\native - + Juce Modules\juce_gui_extra - + Juce Modules\juce_opengl\opengl - + Juce Modules\juce_opengl\opengl - + Juce Modules\juce_opengl\opengl - + Juce Modules\juce_opengl\opengl - + Juce Modules\juce_opengl\opengl - + Juce Modules\juce_opengl\opengl - + Juce Modules\juce_opengl\opengl - + Juce Modules\juce_opengl\opengl - + Juce Modules\juce_opengl\opengl - + Juce Modules\juce_opengl\geometry - + Juce Modules\juce_opengl\geometry - + Juce Modules\juce_opengl\geometry - + Juce Modules\juce_opengl\geometry - + Juce Modules\juce_opengl\utils - + Juce Modules\juce_opengl\native - + Juce Modules\juce_opengl\native - + Juce Modules\juce_opengl\native - + Juce Modules\juce_opengl\native - + Juce Modules\juce_opengl\native - + Juce Modules\juce_opengl\native - + Juce Modules\juce_opengl\native - + Juce Modules\juce_opengl - + Juce Modules\juce_video\playback - + Juce Modules\juce_video\playback - + Juce Modules\juce_video\capture - + Juce Modules\juce_video @@ -2846,43 +2846,43 @@ - + Juce Modules\juce_audio_basics - + Juce Modules\juce_audio_devices - + Juce Modules\juce_audio_formats - + Juce Modules\juce_audio_processors - + Juce Modules\juce_core - + Juce Modules\juce_cryptography - + Juce Modules\juce_data_structures - + Juce Modules\juce_events - + Juce Modules\juce_graphics - + Juce Modules\juce_gui_basics - + Juce Modules\juce_gui_extra - + Juce Modules\juce_opengl - + Juce Modules\juce_video diff --git a/examples/AnimationAppExample/Builds/iOS/AnimationAppExample.xcodeproj/project.pbxproj b/examples/AnimationAppExample/Builds/iOS/AnimationAppExample.xcodeproj/project.pbxproj index 695f1026f6..9cbf7b58a5 100644 --- a/examples/AnimationAppExample/Builds/iOS/AnimationAppExample.xcodeproj/project.pbxproj +++ b/examples/AnimationAppExample/Builds/iOS/AnimationAppExample.xcodeproj/project.pbxproj @@ -18,1299 +18,1299 @@ AA420D06B14C6AF978603FB7 = {isa = PBXBuildFile; fileRef = 4F582012EC867318FB3781BB; }; 328BFAEA24EDCBF7B69F4960 = {isa = PBXBuildFile; fileRef = B766DBADE0BD743FAC004870; }; 84E6553798838003062A7791 = {isa = PBXBuildFile; fileRef = F7B6DBDC7439C90B4E01752E; }; - EF96289AD85C80471CACC5B6 = {isa = PBXBuildFile; fileRef = 50CCC0CC14D17378013CFD72; }; - 6E1751B19D4AF902E028A7C7 = {isa = PBXBuildFile; fileRef = 08216A0328094D5809860DEB; }; - B1220D75CDAD50F3CA57D1A1 = {isa = PBXBuildFile; fileRef = BC3EB76C434A2FDAC6C46DB2; }; - 1C90AD3A9B9B5E9DE33BD2DE = {isa = PBXBuildFile; fileRef = CB3D07088AB905BD96AD3A90; }; - 777C7919C5F3C67E528286A1 = {isa = PBXBuildFile; fileRef = 7FB3628856C8E532EB8421CA; }; - E3AF28976801708F8CD9A656 = {isa = PBXBuildFile; fileRef = D728D4777A842A58EC01454A; }; - A8E9942AA157F768897FBBA2 = {isa = PBXBuildFile; fileRef = B6B4BC87EEA6BFF7A739D118; }; - 937B4A84B983E2AAA040F976 = {isa = PBXBuildFile; fileRef = 369EE12DB339DA919C8BF5F6; }; - EBFF0D5A17F1D61FC28BA178 = {isa = PBXBuildFile; fileRef = 1291E6270CA79ACEEEFB2636; }; - 129DFE2B7F1FDEE81E188D21 = {isa = PBXBuildFile; fileRef = 1DAF43BE112A30BC560E95ED; }; - 79A28D1FFAEAC8D7127BDE2F = {isa = PBXBuildFile; fileRef = 5A8383F3E5B628DE60DB8291; }; - 526057FC6638B0BB7B984637 = {isa = PBXBuildFile; fileRef = 1A355A0DDA216F713372DF88; }; - 2FCBB2DDE322D55AFEF262AF = {isa = PBXBuildFile; fileRef = 98FBBFD68CCC9D52B62BFFEE; }; - 000879A4FF2FFA74721C7CB5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioFormatManager.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_formats/format/juce_AudioFormatManager.cpp"; sourceTree = "SOURCE_ROOT"; }; - 005BC9B639854EA82BE9D1C4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DragAndDropTarget.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/mouse/juce_DragAndDropTarget.h"; sourceTree = "SOURCE_ROOT"; }; - 0125A6E329679354E74D2FB4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_VST3Headers.h"; path = "../../JuceLibraryCode/modules/juce_audio_processors/format_types/juce_VST3Headers.h"; sourceTree = "SOURCE_ROOT"; }; + 9B303E67BC0058053878030C = {isa = PBXBuildFile; fileRef = C1070E62B763F1CCE0BB18F0; }; + ACA92239BEB4C05C418642E2 = {isa = PBXBuildFile; fileRef = DD19124F0A7FD43F31BDEB87; }; + 1EFD155B1968AEC88851F831 = {isa = PBXBuildFile; fileRef = 987AD2821B6419D5FEDCBD7A; }; + 0C7388B5872921063FF273B8 = {isa = PBXBuildFile; fileRef = AD405DDE86D07F955E27EBF8; }; + 9EE1754A8E5230FA1C50713F = {isa = PBXBuildFile; fileRef = B7DD84C8B05ABA4A6915E77E; }; + 1852E56533842FDFBE9A6EE3 = {isa = PBXBuildFile; fileRef = 33E449DEA1FC0CD4CAA3A829; }; + CB79C1D77F4FBF0C64B69E1D = {isa = PBXBuildFile; fileRef = 14BB261A450674034E6080F2; }; + 5E9EFF0130B8CBBEAA0D321B = {isa = PBXBuildFile; fileRef = CC0B7738BD544B955D81BF1E; }; + EF8AB3F393E946FE4A21AA17 = {isa = PBXBuildFile; fileRef = 4B27A11ADAC0D9957BBBCD3E; }; + B70DDF51EDD940F5EF96B96D = {isa = PBXBuildFile; fileRef = 27B720A5E8CF81ABF9E50848; }; + E28816D62DAA38A2794ED6D2 = {isa = PBXBuildFile; fileRef = D8BAA82AC820CEF315BD9DCB; }; + A911433D03B3314558DB8850 = {isa = PBXBuildFile; fileRef = 21CF5364CD4910E49D19F8E2; }; + 590ABC7E64B05F4814FA919E = {isa = PBXBuildFile; fileRef = 6018A3A37F34AE52B39A14D5; }; + 0054E026B84A3A87020CCE48 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MenuBarComponent.h"; path = "../../../../modules/juce_gui_basics/menus/juce_MenuBarComponent.h"; sourceTree = "SOURCE_ROOT"; }; + 0060F61BFBCEF4E9EF8B3CC0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_KeyListener.cpp"; path = "../../../../modules/juce_gui_basics/keyboard/juce_KeyListener.cpp"; sourceTree = "SOURCE_ROOT"; }; 012CB8E6966875E4AE099E8C = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGLES.framework; path = System/Library/Frameworks/OpenGLES.framework; sourceTree = SDKROOT; }; - 015EBD22B273B9E6FA96D62F = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Application.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/application/juce_Application.h"; sourceTree = "SOURCE_ROOT"; }; - 0180E266C4D70BE9C67AB07A = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Quaternion.h"; path = "../../JuceLibraryCode/modules/juce_opengl/geometry/juce_Quaternion.h"; sourceTree = "SOURCE_ROOT"; }; - 01E3FAE5B663BB39B4317ADD = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Toolbar.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/widgets/juce_Toolbar.cpp"; sourceTree = "SOURCE_ROOT"; }; - 01E5B72E5D7115CFF884BB86 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_SpinLock.h"; path = "../../JuceLibraryCode/modules/juce_core/threads/juce_SpinLock.h"; sourceTree = "SOURCE_ROOT"; }; - 01FF42E4D2A331779AB0A72C = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_OpenGLGraphicsContext.cpp"; path = "../../JuceLibraryCode/modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.cpp"; sourceTree = "SOURCE_ROOT"; }; - 0207C77289467D58A696794B = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ArrowButton.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/buttons/juce_ArrowButton.h"; sourceTree = "SOURCE_ROOT"; }; - 024386A2F47243403C1E2A51 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_mac_CoreAudio.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_devices/native/juce_mac_CoreAudio.cpp"; sourceTree = "SOURCE_ROOT"; }; - 02BE2D3F87C20BD46CEC2981 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TextDiff.h"; path = "../../JuceLibraryCode/modules/juce_core/text/juce_TextDiff.h"; sourceTree = "SOURCE_ROOT"; }; - 0356E85B3D1970B78228D974 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AiffAudioFormat.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_formats/codecs/juce_AiffAudioFormat.cpp"; sourceTree = "SOURCE_ROOT"; }; - 036DAC2B35EB0E89897CDAF7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_MouseCursor.mm"; path = "../../JuceLibraryCode/modules/juce_gui_basics/native/juce_mac_MouseCursor.mm"; sourceTree = "SOURCE_ROOT"; }; - 037977A3CA69858654B749F2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ComponentMovementWatcher.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/layout/juce_ComponentMovementWatcher.h"; sourceTree = "SOURCE_ROOT"; }; - 03D53D0D12365594CC24EA4D = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OggVorbisAudioFormat.h"; path = "../../JuceLibraryCode/modules/juce_audio_formats/codecs/juce_OggVorbisAudioFormat.h"; sourceTree = "SOURCE_ROOT"; }; - 03D597E4C12113FB74016803 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AlertWindow.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/windows/juce_AlertWindow.cpp"; sourceTree = "SOURCE_ROOT"; }; - 03E3F0BF99B3C180F9531411 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ShapeButton.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/buttons/juce_ShapeButton.h"; sourceTree = "SOURCE_ROOT"; }; - 03F15E955CC6905BAC120050 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_CommonFile.cpp"; path = "../../JuceLibraryCode/modules/juce_core/native/juce_linux_CommonFile.cpp"; sourceTree = "SOURCE_ROOT"; }; - 042881A3BC502717D187F4DF = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OpenGL_win32.h"; path = "../../JuceLibraryCode/modules/juce_opengl/native/juce_OpenGL_win32.h"; sourceTree = "SOURCE_ROOT"; }; - 053C2C09700A8BD5DB4B416B = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_NormalisableRange.h"; path = "../../JuceLibraryCode/modules/juce_core/maths/juce_NormalisableRange.h"; sourceTree = "SOURCE_ROOT"; }; - 057EDA2ADAE5945C87E9E94C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_NotificationType.h"; path = "../../JuceLibraryCode/modules/juce_events/messages/juce_NotificationType.h"; sourceTree = "SOURCE_ROOT"; }; - 05D3F009C15785143F3D31E3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Value.cpp"; path = "../../JuceLibraryCode/modules/juce_data_structures/values/juce_Value.cpp"; sourceTree = "SOURCE_ROOT"; }; - 064D5359A45F91751130CB6C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_SortedSet.h"; path = "../../JuceLibraryCode/modules/juce_core/containers/juce_SortedSet.h"; sourceTree = "SOURCE_ROOT"; }; - 0654450BCEE57AB7EC882CBC = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_AudioCDBurner.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_devices/native/juce_win32_AudioCDBurner.cpp"; sourceTree = "SOURCE_ROOT"; }; - 069199E3E835739AF23FAC10 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_VST3PluginFormat.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_processors/format_types/juce_VST3PluginFormat.cpp"; sourceTree = "SOURCE_ROOT"; }; - 069F8377EE5A3A1B8417E1BB = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_FileChooser.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/native/juce_linux_FileChooser.cpp"; sourceTree = "SOURCE_ROOT"; }; - 06D18753FCA84429B281A7CB = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_NSViewComponentPeer.mm"; path = "../../JuceLibraryCode/modules/juce_gui_basics/native/juce_mac_NSViewComponentPeer.mm"; sourceTree = "SOURCE_ROOT"; }; - 071119F515B16F354C9D5D22 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ResizableEdgeComponent.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/layout/juce_ResizableEdgeComponent.h"; sourceTree = "SOURCE_ROOT"; }; - 076626EB667106684FC3F5C5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DropShadowEffect.h"; path = "../../JuceLibraryCode/modules/juce_graphics/effects/juce_DropShadowEffect.h"; sourceTree = "SOURCE_ROOT"; }; - 076B1F9E89390D3CFE7B6F8E = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_StretchableObjectResizer.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/layout/juce_StretchableObjectResizer.h"; sourceTree = "SOURCE_ROOT"; }; - 077B15886A49C2DF26EB7186 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TemporaryFile.h"; path = "../../JuceLibraryCode/modules/juce_core/files/juce_TemporaryFile.h"; sourceTree = "SOURCE_ROOT"; }; - 07DB1C038E8EF1D3628F6B7A = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_File.h"; path = "../../JuceLibraryCode/modules/juce_core/files/juce_File.h"; sourceTree = "SOURCE_ROOT"; }; - 0801100E90790AD44224848A = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DirectoryIterator.h"; path = "../../JuceLibraryCode/modules/juce_core/files/juce_DirectoryIterator.h"; sourceTree = "SOURCE_ROOT"; }; - 08216A0328094D5809860DEB = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_audio_devices.mm"; path = "../../JuceLibraryCode/modules/juce_audio_devices/juce_audio_devices.mm"; sourceTree = "SOURCE_ROOT"; }; - 08684D02269A6462E874F392 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AsyncUpdater.h"; path = "../../JuceLibraryCode/modules/juce_events/broadcasters/juce_AsyncUpdater.h"; sourceTree = "SOURCE_ROOT"; }; - 08BB70992D33D8DEF932E9BB = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AttributedString.h"; path = "../../JuceLibraryCode/modules/juce_graphics/fonts/juce_AttributedString.h"; sourceTree = "SOURCE_ROOT"; }; - 08CAAD932D355E493366CEF3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_LeakedObjectDetector.h"; path = "../../JuceLibraryCode/modules/juce_core/memory/juce_LeakedObjectDetector.h"; sourceTree = "SOURCE_ROOT"; }; - 08CE1157B27F232F61111F04 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FileDragAndDropTarget.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/mouse/juce_FileDragAndDropTarget.h"; sourceTree = "SOURCE_ROOT"; }; - 09043DFD1720837A928ECA06 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioFormat.h"; path = "../../JuceLibraryCode/modules/juce_audio_formats/format/juce_AudioFormat.h"; sourceTree = "SOURCE_ROOT"; }; - 0906C93F178388D7783BCC92 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MD5.cpp"; path = "../../JuceLibraryCode/modules/juce_cryptography/hashing/juce_MD5.cpp"; sourceTree = "SOURCE_ROOT"; }; - 094EBE616E535FEACF39583B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_InterprocessConnectionServer.cpp"; path = "../../JuceLibraryCode/modules/juce_events/interprocess/juce_InterprocessConnectionServer.cpp"; sourceTree = "SOURCE_ROOT"; }; - 09BB7D020FA96EB044330205 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_XmlElement.h"; path = "../../JuceLibraryCode/modules/juce_core/xml/juce_XmlElement.h"; sourceTree = "SOURCE_ROOT"; }; - 0A431A685E635E51B2E20FB7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioUnitPluginFormat.h"; path = "../../JuceLibraryCode/modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.h"; sourceTree = "SOURCE_ROOT"; }; - 0A5ED9AFC5906343E514100D = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ApplicationCommandTarget.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/commands/juce_ApplicationCommandTarget.cpp"; sourceTree = "SOURCE_ROOT"; }; - 0A79B3C2BCCFF8C8D9837210 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_Files.cpp"; path = "../../JuceLibraryCode/modules/juce_core/native/juce_linux_Files.cpp"; sourceTree = "SOURCE_ROOT"; }; - 0A7FBABADCBBF00C2A842D37 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_StringArray.h"; path = "../../JuceLibraryCode/modules/juce_core/text/juce_StringArray.h"; sourceTree = "SOURCE_ROOT"; }; - 0B22BB6E27076BA1B6459249 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_PropertyPanel.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/properties/juce_PropertyPanel.h"; sourceTree = "SOURCE_ROOT"; }; - 0B4FA008BF447F4334E24693 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_GlowEffect.cpp"; path = "../../JuceLibraryCode/modules/juce_graphics/effects/juce_GlowEffect.cpp"; sourceTree = "SOURCE_ROOT"; }; - 0C4D86B553BCA2945973736E = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_core.h"; path = "../../JuceLibraryCode/modules/juce_core/juce_core.h"; sourceTree = "SOURCE_ROOT"; }; - 0C8CE60E5ADA256EC7311C40 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ResizableBorderComponent.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/layout/juce_ResizableBorderComponent.h"; sourceTree = "SOURCE_ROOT"; }; - 0CB666093FEE15ED3782D60C = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioFormatReader.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_formats/format/juce_AudioFormatReader.cpp"; sourceTree = "SOURCE_ROOT"; }; - 0CF71E055B7DC5BB25E8CC20 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Font.h"; path = "../../JuceLibraryCode/modules/juce_graphics/fonts/juce_Font.h"; sourceTree = "SOURCE_ROOT"; }; - 0E261C336A94816F61F6D1F9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_XMLCodeTokeniser.h"; path = "../../JuceLibraryCode/modules/juce_gui_extra/code_editor/juce_XMLCodeTokeniser.h"; sourceTree = "SOURCE_ROOT"; }; - 0E4F0DA9ECA921AF8E835E19 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ChildProcess.h"; path = "../../JuceLibraryCode/modules/juce_core/threads/juce_ChildProcess.h"; sourceTree = "SOURCE_ROOT"; }; - 0FF684B2342825C25B6D5DBA = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_QuickTimeMovieComponent.h"; path = "../../JuceLibraryCode/modules/juce_video/playback/juce_QuickTimeMovieComponent.h"; sourceTree = "SOURCE_ROOT"; }; - 106CB8DA346ABAC39F9CBF67 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_QuickTimeMovieComponent.cpp"; path = "../../JuceLibraryCode/modules/juce_video/native/juce_win32_QuickTimeMovieComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; - 112A4FE3483942AF43D513DA = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MidiInput.h"; path = "../../JuceLibraryCode/modules/juce_audio_devices/midi_io/juce_MidiInput.h"; sourceTree = "SOURCE_ROOT"; }; - 11736C186EBE80F228E1D782 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_UnitTest.h"; path = "../../JuceLibraryCode/modules/juce_core/unit_tests/juce_UnitTest.h"; sourceTree = "SOURCE_ROOT"; }; - 1173B2E45074397470CD6EA6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Image.cpp"; path = "../../JuceLibraryCode/modules/juce_graphics/images/juce_Image.cpp"; sourceTree = "SOURCE_ROOT"; }; - 117555C684D0E7FB5ADDB891 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_mac_CoreMidi.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_devices/native/juce_mac_CoreMidi.cpp"; sourceTree = "SOURCE_ROOT"; }; - 11930669FC3C726CD1F9712F = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AnimatedAppComponent.h"; path = "../../JuceLibraryCode/modules/juce_gui_extra/misc/juce_AnimatedAppComponent.h"; sourceTree = "SOURCE_ROOT"; }; - 12503429614C443A89A28FB2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_RelativeTime.cpp"; path = "../../JuceLibraryCode/modules/juce_core/time/juce_RelativeTime.cpp"; sourceTree = "SOURCE_ROOT"; }; - 1291E6270CA79ACEEEFB2636 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_graphics.mm"; path = "../../JuceLibraryCode/modules/juce_graphics/juce_graphics.mm"; sourceTree = "SOURCE_ROOT"; }; - 12967F8EBAF9698288C8A5D0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_StringArray.cpp"; path = "../../JuceLibraryCode/modules/juce_core/text/juce_StringArray.cpp"; sourceTree = "SOURCE_ROOT"; }; - 13287EAB1073ED487FE17034 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MidiOutput.h"; path = "../../JuceLibraryCode/modules/juce_audio_devices/midi_io/juce_MidiOutput.h"; sourceTree = "SOURCE_ROOT"; }; - 134C3956C7C8E7CF6CEE8868 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_OggVorbisAudioFormat.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_formats/codecs/juce_OggVorbisAudioFormat.cpp"; sourceTree = "SOURCE_ROOT"; }; - 135F8FB24D69C7E8BE59185F = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TooltipClient.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/mouse/juce_TooltipClient.h"; sourceTree = "SOURCE_ROOT"; }; - 13BC4980571374E9F0243F0E = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_NativeMessageBox.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/windows/juce_NativeMessageBox.h"; sourceTree = "SOURCE_ROOT"; }; - 14875F3B31704358EBBB4F9C = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_PathIterator.cpp"; path = "../../JuceLibraryCode/modules/juce_graphics/geometry/juce_PathIterator.cpp"; sourceTree = "SOURCE_ROOT"; }; - 150E68F9290BA3701DCABDAE = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_IPAddress.h"; path = "../../JuceLibraryCode/modules/juce_core/network/juce_IPAddress.h"; sourceTree = "SOURCE_ROOT"; }; - 150EE812D88AFDBB98C0A539 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ToolbarItemFactory.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/widgets/juce_ToolbarItemFactory.h"; sourceTree = "SOURCE_ROOT"; }; - 1557FF99F272F107A90B15DF = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Identifier.h"; path = "../../JuceLibraryCode/modules/juce_core/text/juce_Identifier.h"; sourceTree = "SOURCE_ROOT"; }; - 158D17EA6E11AEEEA7D524D3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ImageFileFormat.cpp"; path = "../../JuceLibraryCode/modules/juce_graphics/images/juce_ImageFileFormat.cpp"; sourceTree = "SOURCE_ROOT"; }; - 15F7EA4ECAB7AD7E50A11065 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_SystemStats.cpp"; path = "../../JuceLibraryCode/modules/juce_core/system/juce_SystemStats.cpp"; sourceTree = "SOURCE_ROOT"; }; - 160E2EF9685EDF05E2A5EF32 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ContainerDeletePolicy.h"; path = "../../JuceLibraryCode/modules/juce_core/memory/juce_ContainerDeletePolicy.h"; sourceTree = "SOURCE_ROOT"; }; - 16DA31B062407BE595BD2E6B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_RectanglePlacement.cpp"; path = "../../JuceLibraryCode/modules/juce_graphics/placement/juce_RectanglePlacement.cpp"; sourceTree = "SOURCE_ROOT"; }; - 16F835A428874C108CE94490 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_WildcardFileFilter.cpp"; path = "../../JuceLibraryCode/modules/juce_core/files/juce_WildcardFileFilter.cpp"; sourceTree = "SOURCE_ROOT"; }; - 1717C592DF6E9FB0825104A3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_LookAndFeel_V2.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V2.cpp"; sourceTree = "SOURCE_ROOT"; }; - 171DE29200A3E7A8FB2D82F6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_OpenGLContext.cpp"; path = "../../JuceLibraryCode/modules/juce_opengl/opengl/juce_OpenGLContext.cpp"; sourceTree = "SOURCE_ROOT"; }; - 17CF86369ED4F4A6DFD8E44F = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_PluginDescription.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_processors/processors/juce_PluginDescription.cpp"; sourceTree = "SOURCE_ROOT"; }; - 17E9D0C9AC68F13FB1A763CD = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_audio_processors.h"; path = "../../JuceLibraryCode/modules/juce_audio_processors/juce_audio_processors.h"; sourceTree = "SOURCE_ROOT"; }; - 189CFDE7D3BC22BFE5CD87AD = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_osx_ObjCHelpers.h"; path = "../../JuceLibraryCode/modules/juce_core/native/juce_osx_ObjCHelpers.h"; sourceTree = "SOURCE_ROOT"; }; - 19553003D814DD6A3D1CE28D = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_SystemClipboard.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/keyboard/juce_SystemClipboard.h"; sourceTree = "SOURCE_ROOT"; }; - 19DA53917D0F1D8438EF83FA = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ToolbarButton.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/buttons/juce_ToolbarButton.cpp"; sourceTree = "SOURCE_ROOT"; }; - 19F49DDF17B56B3F0EC5D80D = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AsyncUpdater.cpp"; path = "../../JuceLibraryCode/modules/juce_events/broadcasters/juce_AsyncUpdater.cpp"; sourceTree = "SOURCE_ROOT"; }; - 1A23B74D25E6B0C55F1A1186 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FileTreeComponent.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/filebrowser/juce_FileTreeComponent.h"; sourceTree = "SOURCE_ROOT"; }; - 1A355A0DDA216F713372DF88 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_opengl.mm"; path = "../../JuceLibraryCode/modules/juce_opengl/juce_opengl.mm"; sourceTree = "SOURCE_ROOT"; }; - 1A491D8A6C3223CF582E050D = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MidiMessageSequence.h"; path = "../../JuceLibraryCode/modules/juce_audio_basics/midi/juce_MidiMessageSequence.h"; sourceTree = "SOURCE_ROOT"; }; - 1A632A95CA812B23E08E0C7A = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AlertWindow.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/windows/juce_AlertWindow.h"; sourceTree = "SOURCE_ROOT"; }; - 1A7BABC358CA895F30655093 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ConcertinaPanel.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/layout/juce_ConcertinaPanel.cpp"; sourceTree = "SOURCE_ROOT"; }; - 1AA4BEC9E981D64B98626682 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Colours.cpp"; path = "../../JuceLibraryCode/modules/juce_graphics/colour/juce_Colours.cpp"; sourceTree = "SOURCE_ROOT"; }; - 1B01AB28846416D9B0050D4A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_HighResolutionTimer.cpp"; path = "../../JuceLibraryCode/modules/juce_core/threads/juce_HighResolutionTimer.cpp"; sourceTree = "SOURCE_ROOT"; }; - 1B14F64034753EEA8B94AFAA = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CallbackMessage.h"; path = "../../JuceLibraryCode/modules/juce_events/messages/juce_CallbackMessage.h"; sourceTree = "SOURCE_ROOT"; }; - 1B5BCDA8B68284F2FAF17FE4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FileInputSource.cpp"; path = "../../JuceLibraryCode/modules/juce_core/streams/juce_FileInputSource.cpp"; sourceTree = "SOURCE_ROOT"; }; - 1B96C0BBFE3E1A61E50E61A4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_UndoManager.h"; path = "../../JuceLibraryCode/modules/juce_data_structures/undomanager/juce_UndoManager.h"; sourceTree = "SOURCE_ROOT"; }; - 1BEF05EF0D439BB92AE09DE4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_PluginListComponent.h"; path = "../../JuceLibraryCode/modules/juce_audio_processors/scanning/juce_PluginListComponent.h"; sourceTree = "SOURCE_ROOT"; }; - 1C96AD5E5DF22AE45779B769 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_QuickTimeAudioFormat.h"; path = "../../JuceLibraryCode/modules/juce_audio_formats/codecs/juce_QuickTimeAudioFormat.h"; sourceTree = "SOURCE_ROOT"; }; - 1C9B9B22D2CD87C0D160892C = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_NamedPipe.cpp"; path = "../../JuceLibraryCode/modules/juce_core/network/juce_NamedPipe.cpp"; sourceTree = "SOURCE_ROOT"; }; - 1CEDC2C77278F47EA71D588C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TableHeaderComponent.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/widgets/juce_TableHeaderComponent.h"; sourceTree = "SOURCE_ROOT"; }; - 1DAF43BE112A30BC560E95ED = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_gui_basics.mm"; path = "../../JuceLibraryCode/modules/juce_gui_basics/juce_gui_basics.mm"; sourceTree = "SOURCE_ROOT"; }; - 1DDEE220B7231E89552E9A07 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ButtonPropertyComponent.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/properties/juce_ButtonPropertyComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; - 1E7287FBD84D26D7C3247D65 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DropShadower.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/misc/juce_DropShadower.cpp"; sourceTree = "SOURCE_ROOT"; }; - 1EF1157A189C1B7D4E20B5AE = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ImageCache.h"; path = "../../JuceLibraryCode/modules/juce_graphics/images/juce_ImageCache.h"; sourceTree = "SOURCE_ROOT"; }; - 1FDD5774A3619E6116D1A542 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MemoryOutputStream.h"; path = "../../JuceLibraryCode/modules/juce_core/streams/juce_MemoryOutputStream.h"; sourceTree = "SOURCE_ROOT"; }; - 2075736FC83122CD98E9448B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_BlowFish.cpp"; path = "../../JuceLibraryCode/modules/juce_cryptography/encryption/juce_BlowFish.cpp"; sourceTree = "SOURCE_ROOT"; }; - 20B34958865F62C6D4CC1C2D = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ListBox.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/widgets/juce_ListBox.cpp"; sourceTree = "SOURCE_ROOT"; }; - 20E9A48DD57A2BD4F3A8EC20 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OpenGLImage.h"; path = "../../JuceLibraryCode/modules/juce_opengl/opengl/juce_OpenGLImage.h"; sourceTree = "SOURCE_ROOT"; }; - 213971DB941D93E214CF2153 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ReverbAudioSource.h"; path = "../../JuceLibraryCode/modules/juce_audio_basics/sources/juce_ReverbAudioSource.h"; sourceTree = "SOURCE_ROOT"; }; - 21E54D17FED6BEB36D5C712B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_CameraDevice.cpp"; path = "../../JuceLibraryCode/modules/juce_video/native/juce_win32_CameraDevice.cpp"; sourceTree = "SOURCE_ROOT"; }; - 223EA3BC50EEE65DFD1BF515 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_SubregionStream.cpp"; path = "../../JuceLibraryCode/modules/juce_core/streams/juce_SubregionStream.cpp"; sourceTree = "SOURCE_ROOT"; }; - 227CEFF1628076DE7A6D5A82 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AttributedString.cpp"; path = "../../JuceLibraryCode/modules/juce_graphics/fonts/juce_AttributedString.cpp"; sourceTree = "SOURCE_ROOT"; }; - 227F70FEE9D1F967CFD8DB5A = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FlacAudioFormat.h"; path = "../../JuceLibraryCode/modules/juce_audio_formats/codecs/juce_FlacAudioFormat.h"; sourceTree = "SOURCE_ROOT"; }; - 229DD5C0EF1D6FDA625B85A9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Value.h"; path = "../../JuceLibraryCode/modules/juce_data_structures/values/juce_Value.h"; sourceTree = "SOURCE_ROOT"; }; - 22BCEE7C1CFE9805F0C39F3B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ResizableBorderComponent.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/layout/juce_ResizableBorderComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; - 231F8E834F94B7654941EF55 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_VST3Common.h"; path = "../../JuceLibraryCode/modules/juce_audio_processors/format_types/juce_VST3Common.h"; sourceTree = "SOURCE_ROOT"; }; - 23600EA94396F6E810F1C774 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioProcessorParameter.h"; path = "../../JuceLibraryCode/modules/juce_audio_processors/processors/juce_AudioProcessorParameter.h"; sourceTree = "SOURCE_ROOT"; }; - 23B94851B96CB057621E0EBA = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MACAddress.cpp"; path = "../../JuceLibraryCode/modules/juce_core/network/juce_MACAddress.cpp"; sourceTree = "SOURCE_ROOT"; }; - 23CC00FD68EF7CB9A64D9EED = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_module_info"; path = "../../JuceLibraryCode/modules/juce_audio_processors/juce_module_info"; sourceTree = "SOURCE_ROOT"; }; - 23FA7918C3938E3FA645F003 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ApplicationCommandID.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/commands/juce_ApplicationCommandID.h"; sourceTree = "SOURCE_ROOT"; }; - 24006F32DA24D5C374C7442A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Random.cpp"; path = "../../JuceLibraryCode/modules/juce_core/maths/juce_Random.cpp"; sourceTree = "SOURCE_ROOT"; }; - 24A757C009624117895995B4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DirectShowComponent.h"; path = "../../JuceLibraryCode/modules/juce_video/playback/juce_DirectShowComponent.h"; sourceTree = "SOURCE_ROOT"; }; - 24C7C2F049DB74035187FBC7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DragAndDropContainer.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/mouse/juce_DragAndDropContainer.cpp"; sourceTree = "SOURCE_ROOT"; }; - 24D1B8EBF0B291F684311B9F = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OpenGL_android.h"; path = "../../JuceLibraryCode/modules/juce_opengl/native/juce_OpenGL_android.h"; sourceTree = "SOURCE_ROOT"; }; - 24E811B6B00094848D08D21F = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DrawableText.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/drawables/juce_DrawableText.h"; sourceTree = "SOURCE_ROOT"; }; - 256A686F1026814DA7434C9A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_QuickTimeAudioFormat.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_formats/codecs/juce_QuickTimeAudioFormat.cpp"; sourceTree = "SOURCE_ROOT"; }; - 269DDBC16D9F714A0B057A94 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_posix_SharedCode.h"; path = "../../JuceLibraryCode/modules/juce_core/native/juce_posix_SharedCode.h"; sourceTree = "SOURCE_ROOT"; }; - 26FD20E046F037F67A376081 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MouseEvent.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/mouse/juce_MouseEvent.h"; sourceTree = "SOURCE_ROOT"; }; + 02AC998E808CAF5C148CFFC5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_Files.cpp"; path = "../../../../modules/juce_core/native/juce_win32_Files.cpp"; sourceTree = "SOURCE_ROOT"; }; + 02C14E49091F42750CD72F00 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Button.h"; path = "../../../../modules/juce_gui_basics/buttons/juce_Button.h"; sourceTree = "SOURCE_ROOT"; }; + 0311666DB95BFAE686267D7C = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_LagrangeInterpolator.cpp"; path = "../../../../modules/juce_audio_basics/effects/juce_LagrangeInterpolator.cpp"; sourceTree = "SOURCE_ROOT"; }; + 03457E9DD2B35D7C1B0C7393 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_PathStrokeType.h"; path = "../../../../modules/juce_graphics/geometry/juce_PathStrokeType.h"; sourceTree = "SOURCE_ROOT"; }; + 0346DBE09BEC27EA93676FEB = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ThreadWithProgressWindow.cpp"; path = "../../../../modules/juce_gui_basics/windows/juce_ThreadWithProgressWindow.cpp"; sourceTree = "SOURCE_ROOT"; }; + 03B79DBA48F6C4122DABEE90 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_SystemStats.h"; path = "../../../../modules/juce_core/system/juce_SystemStats.h"; sourceTree = "SOURCE_ROOT"; }; + 03D03AF17C5E899ED9481518 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FloatVectorOperations.h"; path = "../../../../modules/juce_audio_basics/buffers/juce_FloatVectorOperations.h"; sourceTree = "SOURCE_ROOT"; }; + 03E91AE23ECCF51E3AF9FC90 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_XmlDocument.cpp"; path = "../../../../modules/juce_core/xml/juce_XmlDocument.cpp"; sourceTree = "SOURCE_ROOT"; }; + 04C105672DA409FE8593DB04 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_SystemAudioVolume.h"; path = "../../../../modules/juce_audio_devices/audio_io/juce_SystemAudioVolume.h"; sourceTree = "SOURCE_ROOT"; }; + 0700C7069E1CF3FF8966C0E3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_LookAndFeel.cpp"; path = "../../../../modules/juce_gui_basics/lookandfeel/juce_LookAndFeel.cpp"; sourceTree = "SOURCE_ROOT"; }; + 07342D914D2A5AF6075CDB2D = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_StandardHeader.h"; path = "../../../../modules/juce_core/system/juce_StandardHeader.h"; sourceTree = "SOURCE_ROOT"; }; + 0790EC941834B64EA1AC8D5A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_PreferencesPanel.cpp"; path = "../../../../modules/juce_gui_extra/misc/juce_PreferencesPanel.cpp"; sourceTree = "SOURCE_ROOT"; }; + 07C83735435D264F28158F79 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_WildcardFileFilter.cpp"; path = "../../../../modules/juce_core/files/juce_WildcardFileFilter.cpp"; sourceTree = "SOURCE_ROOT"; }; + 07E19FB806980020A47AA47D = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_OutputStream.cpp"; path = "../../../../modules/juce_core/streams/juce_OutputStream.cpp"; sourceTree = "SOURCE_ROOT"; }; + 0852A866937712A0D30684A0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_XMLCodeTokeniser.cpp"; path = "../../../../modules/juce_gui_extra/code_editor/juce_XMLCodeTokeniser.cpp"; sourceTree = "SOURCE_ROOT"; }; + 086CE5C768CF5889BDEF8955 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioSource.h"; path = "../../../../modules/juce_audio_basics/sources/juce_AudioSource.h"; sourceTree = "SOURCE_ROOT"; }; + 08C7B33308A32555A7CA21B5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OpenGLShaderProgram.h"; path = "../../../../modules/juce_opengl/opengl/juce_OpenGLShaderProgram.h"; sourceTree = "SOURCE_ROOT"; }; + 08EC867C77B028C336B79752 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ContainerDeletePolicy.h"; path = "../../../../modules/juce_core/memory/juce_ContainerDeletePolicy.h"; sourceTree = "SOURCE_ROOT"; }; + 097237CCE04B9020343CB28D = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OptionalScopedPointer.h"; path = "../../../../modules/juce_core/memory/juce_OptionalScopedPointer.h"; sourceTree = "SOURCE_ROOT"; }; + 09846FF5D2FFB83242A02FF4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ApplicationProperties.cpp"; path = "../../../../modules/juce_data_structures/app_properties/juce_ApplicationProperties.cpp"; sourceTree = "SOURCE_ROOT"; }; + 0993051FFD1B0C5E92474DBD = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_OpenGLImage.cpp"; path = "../../../../modules/juce_opengl/opengl/juce_OpenGLImage.cpp"; sourceTree = "SOURCE_ROOT"; }; + 0AD4B355DBB0AED4C90E5657 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ScopedReadLock.h"; path = "../../../../modules/juce_core/threads/juce_ScopedReadLock.h"; sourceTree = "SOURCE_ROOT"; }; + 0AE6516868244378D09124A0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FlacAudioFormat.cpp"; path = "../../../../modules/juce_audio_formats/codecs/juce_FlacAudioFormat.cpp"; sourceTree = "SOURCE_ROOT"; }; + 0B7637C0030C06BE612E41E8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ModalComponentManager.h"; path = "../../../../modules/juce_gui_basics/components/juce_ModalComponentManager.h"; sourceTree = "SOURCE_ROOT"; }; + 0B7E069D09A7E46448EAE230 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_HyperlinkButton.cpp"; path = "../../../../modules/juce_gui_basics/buttons/juce_HyperlinkButton.cpp"; sourceTree = "SOURCE_ROOT"; }; + 0B933FCCF82100D67C0B7D34 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_KnownPluginList.cpp"; path = "../../../../modules/juce_audio_processors/scanning/juce_KnownPluginList.cpp"; sourceTree = "SOURCE_ROOT"; }; + 0BC32F0BB0B5393D25E09D00 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_CoreAudioFormat.cpp"; path = "../../../../modules/juce_audio_formats/codecs/juce_CoreAudioFormat.cpp"; sourceTree = "SOURCE_ROOT"; }; + 0C61EC70BD4EA59AEEBB6669 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_BooleanPropertyComponent.h"; path = "../../../../modules/juce_gui_basics/properties/juce_BooleanPropertyComponent.h"; sourceTree = "SOURCE_ROOT"; }; + 0C89377A44F26612524DA129 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Array.h"; path = "../../../../modules/juce_core/containers/juce_Array.h"; sourceTree = "SOURCE_ROOT"; }; + 0C9B04C3B7D8E1CE4FAC6FF6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ComboBox.cpp"; path = "../../../../modules/juce_gui_basics/widgets/juce_ComboBox.cpp"; sourceTree = "SOURCE_ROOT"; }; + 0CBC9EB8F2C55E88DB0F49BD = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_LookAndFeel_V1.h"; path = "../../../../modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V1.h"; sourceTree = "SOURCE_ROOT"; }; + 0D0FAC9754D9469774B8DD2F = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_BubbleMessageComponent.cpp"; path = "../../../../modules/juce_gui_extra/misc/juce_BubbleMessageComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; + 0D265DF78A9FE5E669F76FC3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ApplicationCommandTarget.h"; path = "../../../../modules/juce_gui_basics/commands/juce_ApplicationCommandTarget.h"; sourceTree = "SOURCE_ROOT"; }; + 0D35F0A502484A40B09F3EBF = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FileChooser.cpp"; path = "../../../../modules/juce_gui_basics/filebrowser/juce_FileChooser.cpp"; sourceTree = "SOURCE_ROOT"; }; + 0D530396A7BA6BA190100C6E = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_WavAudioFormat.cpp"; path = "../../../../modules/juce_audio_formats/codecs/juce_WavAudioFormat.cpp"; sourceTree = "SOURCE_ROOT"; }; + 0D88ABF90B476D03D3684ABE = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OpenGLFrameBuffer.h"; path = "../../../../modules/juce_opengl/opengl/juce_OpenGLFrameBuffer.h"; sourceTree = "SOURCE_ROOT"; }; + 0DB1323191C133E48F07C062 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ApplicationCommandInfo.h"; path = "../../../../modules/juce_gui_basics/commands/juce_ApplicationCommandInfo.h"; sourceTree = "SOURCE_ROOT"; }; + 0E70A4BFB2F7D1AB6188E72C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioFormat.h"; path = "../../../../modules/juce_audio_formats/format/juce_AudioFormat.h"; sourceTree = "SOURCE_ROOT"; }; + 0E894AC7229948568720E294 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ActiveXControlComponent.h"; path = "../../../../modules/juce_gui_extra/embedding/juce_ActiveXControlComponent.h"; sourceTree = "SOURCE_ROOT"; }; + 0E8D536FEBD11AEA3C90B5A8 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_module_info"; path = "../../../../modules/juce_gui_basics/juce_module_info"; sourceTree = "SOURCE_ROOT"; }; + 0ECA7867513EFA30BEA0BE78 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ChoicePropertyComponent.cpp"; path = "../../../../modules/juce_gui_basics/properties/juce_ChoicePropertyComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; + 0EF8E3646F6099E89A743D99 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_MouseCursor.mm"; path = "../../../../modules/juce_gui_basics/native/juce_mac_MouseCursor.mm"; sourceTree = "SOURCE_ROOT"; }; + 0F16DEEC2C4B95E3A9F28CE5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Label.h"; path = "../../../../modules/juce_gui_basics/widgets/juce_Label.h"; sourceTree = "SOURCE_ROOT"; }; + 0F67C59CB48583941B8656EF = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_VSTMidiEventList.h"; path = "../../../../modules/juce_audio_processors/format_types/juce_VSTMidiEventList.h"; sourceTree = "SOURCE_ROOT"; }; + 102919EC5BCD10DA703688CF = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioProcessorParameter.h"; path = "../../../../modules/juce_audio_processors/processors/juce_AudioProcessorParameter.h"; sourceTree = "SOURCE_ROOT"; }; + 109C128BB4A7A05127A0C485 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_PropertyComponent.h"; path = "../../../../modules/juce_gui_basics/properties/juce_PropertyComponent.h"; sourceTree = "SOURCE_ROOT"; }; + 11ACB77A3D91503A3DF673C8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_QuickTimeMovieComponent.mm"; path = "../../../../modules/juce_video/native/juce_mac_QuickTimeMovieComponent.mm"; sourceTree = "SOURCE_ROOT"; }; + 11D8AE26FA8880E7E8F3B4EB = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MissingGLDefinitions.h"; path = "../../../../modules/juce_opengl/native/juce_MissingGLDefinitions.h"; sourceTree = "SOURCE_ROOT"; }; + 123B63088FA1C4D1AD225CDB = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_LowLevelGraphicsSoftwareRenderer.cpp"; path = "../../../../modules/juce_graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.cpp"; sourceTree = "SOURCE_ROOT"; }; + 13430EC7CBFEF46874F53731 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_Network.cpp"; path = "../../../../modules/juce_core/native/juce_linux_Network.cpp"; sourceTree = "SOURCE_ROOT"; }; + 135DC8543A904B7BBAA0FD7B = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_StretchableLayoutManager.h"; path = "../../../../modules/juce_gui_basics/layout/juce_StretchableLayoutManager.h"; sourceTree = "SOURCE_ROOT"; }; + 13BF0388489EB44A816C9AF6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CodeDocument.h"; path = "../../../../modules/juce_gui_extra/code_editor/juce_CodeDocument.h"; sourceTree = "SOURCE_ROOT"; }; + 14245CED80854EC5291657FA = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_StringArray.h"; path = "../../../../modules/juce_core/text/juce_StringArray.h"; sourceTree = "SOURCE_ROOT"; }; + 142D03BC875BD387BD10C51F = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ChangeBroadcaster.cpp"; path = "../../../../modules/juce_events/broadcasters/juce_ChangeBroadcaster.cpp"; sourceTree = "SOURCE_ROOT"; }; + 1450CD0879661355CD52DD8D = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_StringPool.h"; path = "../../../../modules/juce_core/text/juce_StringPool.h"; sourceTree = "SOURCE_ROOT"; }; + 14AB997C7EB22777C1EF533C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_RelativeCoordinate.h"; path = "../../../../modules/juce_gui_basics/positioning/juce_RelativeCoordinate.h"; sourceTree = "SOURCE_ROOT"; }; + 14BB261A450674034E6080F2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_data_structures.mm"; path = "../../../../modules/juce_data_structures/juce_data_structures.mm"; sourceTree = "SOURCE_ROOT"; }; + 15029C3F041B27DD7191482F = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioProcessorGraph.cpp"; path = "../../../../modules/juce_audio_processors/processors/juce_AudioProcessorGraph.cpp"; sourceTree = "SOURCE_ROOT"; }; + 161F35FA23347F495704C26A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_CommonFile.cpp"; path = "../../../../modules/juce_core/native/juce_linux_CommonFile.cpp"; sourceTree = "SOURCE_ROOT"; }; + 166BDAF3B9896BCB3771A061 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ResizableWindow.h"; path = "../../../../modules/juce_gui_basics/windows/juce_ResizableWindow.h"; sourceTree = "SOURCE_ROOT"; }; + 166C141D440846E85F91747E = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_OpenGLFrameBuffer.cpp"; path = "../../../../modules/juce_opengl/opengl/juce_OpenGLFrameBuffer.cpp"; sourceTree = "SOURCE_ROOT"; }; + 16ECB71D0D2C5C8BEFF4B4C6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DrawableRectangle.h"; path = "../../../../modules/juce_gui_basics/drawables/juce_DrawableRectangle.h"; sourceTree = "SOURCE_ROOT"; }; + 1737596EB7F40322C0A5DE20 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_JSON.cpp"; path = "../../../../modules/juce_core/javascript/juce_JSON.cpp"; sourceTree = "SOURCE_ROOT"; }; + 175654F2545AD9C0603BD0B4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_File.h"; path = "../../../../modules/juce_core/files/juce_File.h"; sourceTree = "SOURCE_ROOT"; }; + 176B18B9B61FDA6EC4357EB6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TemporaryFile.h"; path = "../../../../modules/juce_core/files/juce_TemporaryFile.h"; sourceTree = "SOURCE_ROOT"; }; + 17B07A06764A6A7759804033 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_StringArray.cpp"; path = "../../../../modules/juce_core/text/juce_StringArray.cpp"; sourceTree = "SOURCE_ROOT"; }; + 17B2789DEC279EE7DB8D9BE4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_osx_MessageQueue.h"; path = "../../../../modules/juce_events/native/juce_osx_MessageQueue.h"; sourceTree = "SOURCE_ROOT"; }; + 19045B1A4A9E79DB5A44927C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ComponentBoundsConstrainer.h"; path = "../../../../modules/juce_gui_basics/layout/juce_ComponentBoundsConstrainer.h"; sourceTree = "SOURCE_ROOT"; }; + 191B98765219765CD56CCFED = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CodeEditorComponent.h"; path = "../../../../modules/juce_gui_extra/code_editor/juce_CodeEditorComponent.h"; sourceTree = "SOURCE_ROOT"; }; + 19DC6BDBA978DC67B9783340 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_module_info"; path = "../../../../modules/juce_cryptography/juce_module_info"; sourceTree = "SOURCE_ROOT"; }; + 19E9997C0FE3E36156141D64 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MouseInputSource.cpp"; path = "../../../../modules/juce_gui_basics/mouse/juce_MouseInputSource.cpp"; sourceTree = "SOURCE_ROOT"; }; + 1A667A0FBCC8FC7EBBD15B20 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Font.cpp"; path = "../../../../modules/juce_graphics/fonts/juce_Font.cpp"; sourceTree = "SOURCE_ROOT"; }; + 1A7002B936C11924FDC07023 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_AppleRemote.mm"; path = "../../../../modules/juce_gui_extra/native/juce_mac_AppleRemote.mm"; sourceTree = "SOURCE_ROOT"; }; + 1A788BE93E528FDAA62EA02B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_TextPropertyComponent.cpp"; path = "../../../../modules/juce_gui_basics/properties/juce_TextPropertyComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; + 1AB580D4342BFFD41F220358 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_LAMEEncoderAudioFormat.h"; path = "../../../../modules/juce_audio_formats/codecs/juce_LAMEEncoderAudioFormat.h"; sourceTree = "SOURCE_ROOT"; }; + 1AB9713046E08B68A6F672CF = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Identifier.cpp"; path = "../../../../modules/juce_core/text/juce_Identifier.cpp"; sourceTree = "SOURCE_ROOT"; }; + 1B3B7CBA0D25C83B8AF72641 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_IIRFilter.cpp"; path = "../../../../modules/juce_audio_basics/effects/juce_IIRFilter.cpp"; sourceTree = "SOURCE_ROOT"; }; + 1B3CC8F665F23CB86253EBCE = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MathsFunctions.h"; path = "../../../../modules/juce_core/maths/juce_MathsFunctions.h"; sourceTree = "SOURCE_ROOT"; }; + 1B7AFDD8FCA13757D08B8B3E = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DropShadowEffect.cpp"; path = "../../../../modules/juce_graphics/effects/juce_DropShadowEffect.cpp"; sourceTree = "SOURCE_ROOT"; }; + 1C71768A34644733E39EEF4F = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Variant.h"; path = "../../../../modules/juce_core/containers/juce_Variant.h"; sourceTree = "SOURCE_ROOT"; }; + 1D5B751294F84B86ABB11D4A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ReverbAudioSource.cpp"; path = "../../../../modules/juce_audio_basics/sources/juce_ReverbAudioSource.cpp"; sourceTree = "SOURCE_ROOT"; }; + 1D9FABE954892C169D874E35 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ComponentDragger.h"; path = "../../../../modules/juce_gui_basics/mouse/juce_ComponentDragger.h"; sourceTree = "SOURCE_ROOT"; }; + 1DE0CF80B807A4A702DC68BD = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_RelativePoint.h"; path = "../../../../modules/juce_gui_basics/positioning/juce_RelativePoint.h"; sourceTree = "SOURCE_ROOT"; }; + 1E020B9E032C076071700CEC = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_InterprocessConnectionServer.h"; path = "../../../../modules/juce_events/interprocess/juce_InterprocessConnectionServer.h"; sourceTree = "SOURCE_ROOT"; }; + 1E6EF8035485237EA92A1310 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_UnitTest.h"; path = "../../../../modules/juce_core/unit_tests/juce_UnitTest.h"; sourceTree = "SOURCE_ROOT"; }; + 1FD6FD7218AB240D23DF4BAD = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FileListComponent.cpp"; path = "../../../../modules/juce_gui_basics/filebrowser/juce_FileListComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; + 2048DACF787A9BFE011041BC = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_GraphicsContext.h"; path = "../../../../modules/juce_graphics/contexts/juce_GraphicsContext.h"; sourceTree = "SOURCE_ROOT"; }; + 20E10FBD8694E185CA551EDE = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_PropertyComponent.cpp"; path = "../../../../modules/juce_gui_basics/properties/juce_PropertyComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; + 2168310E25BD55C9A46499C6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DrawableComposite.h"; path = "../../../../modules/juce_gui_basics/drawables/juce_DrawableComposite.h"; sourceTree = "SOURCE_ROOT"; }; + 2188A5670214696EFCF6810F = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_OpenGLHelpers.cpp"; path = "../../../../modules/juce_opengl/opengl/juce_OpenGLHelpers.cpp"; sourceTree = "SOURCE_ROOT"; }; + 21CF5364CD4910E49D19F8E2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_opengl.mm"; path = "../../../../modules/juce_opengl/juce_opengl.mm"; sourceTree = "SOURCE_ROOT"; }; + 21D0A71ADD004B35B90F0D1F = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_WebBrowserComponent.mm"; path = "../../../../modules/juce_gui_extra/native/juce_mac_WebBrowserComponent.mm"; sourceTree = "SOURCE_ROOT"; }; + 21D31B64BAD35C6C8E8E8FC0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_RelativePointPath.cpp"; path = "../../../../modules/juce_gui_basics/positioning/juce_RelativePointPath.cpp"; sourceTree = "SOURCE_ROOT"; }; + 221FD10838A8CE36672FABC0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_MainMenu.mm"; path = "../../../../modules/juce_gui_basics/native/juce_mac_MainMenu.mm"; sourceTree = "SOURCE_ROOT"; }; + 2254F8D031DD15BDB278DE3E = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_RecentlyOpenedFilesList.cpp"; path = "../../../../modules/juce_gui_extra/misc/juce_RecentlyOpenedFilesList.cpp"; sourceTree = "SOURCE_ROOT"; }; + 22C4F82B505995F81CD682B5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Identifier.h"; path = "../../../../modules/juce_core/text/juce_Identifier.h"; sourceTree = "SOURCE_ROOT"; }; + 2328C66A446079EDDCC8B14E = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_LiveConstantEditor.cpp"; path = "../../../../modules/juce_gui_extra/misc/juce_LiveConstantEditor.cpp"; sourceTree = "SOURCE_ROOT"; }; + 234D4927B398ED6E9B7B0E6B = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FileLogger.h"; path = "../../../../modules/juce_core/logging/juce_FileLogger.h"; sourceTree = "SOURCE_ROOT"; }; + 236F239E035044438B7CDFCB = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FillType.h"; path = "../../../../modules/juce_graphics/colour/juce_FillType.h"; sourceTree = "SOURCE_ROOT"; }; + 23724FEF549E05851817B4BB = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Slider.cpp"; path = "../../../../modules/juce_gui_basics/widgets/juce_Slider.cpp"; sourceTree = "SOURCE_ROOT"; }; + 23936BBF807CCF5B1EEB9F00 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_BufferedInputStream.cpp"; path = "../../../../modules/juce_core/streams/juce_BufferedInputStream.cpp"; sourceTree = "SOURCE_ROOT"; }; + 241453DBDECBE0CCD5C096DE = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_module_info"; path = "../../../../modules/juce_graphics/juce_module_info"; sourceTree = "SOURCE_ROOT"; }; + 24363F41974FD7A3B634B78B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_PerformanceCounter.cpp"; path = "../../../../modules/juce_core/time/juce_PerformanceCounter.cpp"; sourceTree = "SOURCE_ROOT"; }; + 244B9B4B8307A8C51207D457 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_JPEGLoader.cpp"; path = "../../../../modules/juce_graphics/image_formats/juce_JPEGLoader.cpp"; sourceTree = "SOURCE_ROOT"; }; + 254D157C0CCE3C7EA022F4CE = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_module_info"; path = "../../../../modules/juce_video/juce_module_info"; sourceTree = "SOURCE_ROOT"; }; + 25869F2A5B90C64E857606D8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TopLevelWindow.h"; path = "../../../../modules/juce_gui_basics/windows/juce_TopLevelWindow.h"; sourceTree = "SOURCE_ROOT"; }; + 25B41C0851C004C9D410B7C8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_mac_CoreAudio.cpp"; path = "../../../../modules/juce_audio_devices/native/juce_mac_CoreAudio.cpp"; sourceTree = "SOURCE_ROOT"; }; + 25E6B62A5BF19A0D1E085E10 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_GroupComponent.h"; path = "../../../../modules/juce_gui_basics/layout/juce_GroupComponent.h"; sourceTree = "SOURCE_ROOT"; }; + 260A5BDC20C7B4029DB418E4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ToolbarItemFactory.h"; path = "../../../../modules/juce_gui_basics/widgets/juce_ToolbarItemFactory.h"; sourceTree = "SOURCE_ROOT"; }; + 264F684A80B93F7A189A5FA5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MP3AudioFormat.cpp"; path = "../../../../modules/juce_audio_formats/codecs/juce_MP3AudioFormat.cpp"; sourceTree = "SOURCE_ROOT"; }; + 26C95A2DACFF9773038656E0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_Windowing.cpp"; path = "../../../../modules/juce_gui_basics/native/juce_linux_Windowing.cpp"; sourceTree = "SOURCE_ROOT"; }; + 27240E9968C04288887BFDC7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_TopLevelWindow.cpp"; path = "../../../../modules/juce_gui_basics/windows/juce_TopLevelWindow.cpp"; sourceTree = "SOURCE_ROOT"; }; 274569E245BFB279247B4ECC = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = JuceHeader.h; path = ../../JuceLibraryCode/JuceHeader.h; sourceTree = "SOURCE_ROOT"; }; - 2765ED5E0A7D8759C81EEA40 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ResizableWindow.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/windows/juce_ResizableWindow.h"; sourceTree = "SOURCE_ROOT"; }; - 276DFA694283C37D1B65B46A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_CoreGraphicsContext.mm"; path = "../../JuceLibraryCode/modules/juce_graphics/native/juce_mac_CoreGraphicsContext.mm"; sourceTree = "SOURCE_ROOT"; }; - 27D5D6CE8B6CFF40F8A5B9D0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Reverb.h"; path = "../../JuceLibraryCode/modules/juce_audio_basics/effects/juce_Reverb.h"; sourceTree = "SOURCE_ROOT"; }; - 27ECA38DD6808A358A90E7EF = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_GZIPCompressorOutputStream.cpp"; path = "../../JuceLibraryCode/modules/juce_core/zip/juce_GZIPCompressorOutputStream.cpp"; sourceTree = "SOURCE_ROOT"; }; - 27F470103D4B980E2E8E8AEB = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_Messaging.cpp"; path = "../../JuceLibraryCode/modules/juce_events/native/juce_linux_Messaging.cpp"; sourceTree = "SOURCE_ROOT"; }; - 2837660339370BA9863DC451 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_Fonts.mm"; path = "../../JuceLibraryCode/modules/juce_graphics/native/juce_mac_Fonts.mm"; sourceTree = "SOURCE_ROOT"; }; + 27676EBA6012198993C2CBA0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TableHeaderComponent.h"; path = "../../../../modules/juce_gui_basics/widgets/juce_TableHeaderComponent.h"; sourceTree = "SOURCE_ROOT"; }; + 27A9B065352AE36635780373 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FileBrowserComponent.cpp"; path = "../../../../modules/juce_gui_basics/filebrowser/juce_FileBrowserComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; + 27B720A5E8CF81ABF9E50848 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_gui_basics.mm"; path = "../../../../modules/juce_gui_basics/juce_gui_basics.mm"; sourceTree = "SOURCE_ROOT"; }; + 27DC413550834C828252B003 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FileTreeComponent.cpp"; path = "../../../../modules/juce_gui_basics/filebrowser/juce_FileTreeComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; + 2807A00AE6C4539CD935F56D = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ImageCache.h"; path = "../../../../modules/juce_graphics/images/juce_ImageCache.h"; sourceTree = "SOURCE_ROOT"; }; + 2819AE973B501D15AAB8C937 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MouseListener.cpp"; path = "../../../../modules/juce_gui_basics/mouse/juce_MouseListener.cpp"; sourceTree = "SOURCE_ROOT"; }; 287976618152E4BA76D627FA = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; - 2892D0D481CDCCFCAE374DA8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Drawable.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/drawables/juce_Drawable.h"; sourceTree = "SOURCE_ROOT"; }; - 29054D0D5BB22F6A23808951 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DrawableShape.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/drawables/juce_DrawableShape.h"; sourceTree = "SOURCE_ROOT"; }; - 292236D5B7928EF5C6D73341 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Time.cpp"; path = "../../JuceLibraryCode/modules/juce_core/time/juce_Time.cpp"; sourceTree = "SOURCE_ROOT"; }; - 29B12214BCD1551867246556 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DocumentWindow.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/windows/juce_DocumentWindow.cpp"; sourceTree = "SOURCE_ROOT"; }; - 29D6BB46D3EF49EF86612B12 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_VSTPluginFormat.h"; path = "../../JuceLibraryCode/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.h"; sourceTree = "SOURCE_ROOT"; }; - 2A64A444FB90EFA1B0449A67 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Synthesiser.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_basics/synthesisers/juce_Synthesiser.cpp"; sourceTree = "SOURCE_ROOT"; }; - 2B780483D0584407FBA38106 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_audio_basics.h"; path = "../../JuceLibraryCode/modules/juce_audio_basics/juce_audio_basics.h"; sourceTree = "SOURCE_ROOT"; }; - 2B835DD803DC7C2379F3898A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_Threads.cpp"; path = "../../JuceLibraryCode/modules/juce_core/native/juce_linux_Threads.cpp"; sourceTree = "SOURCE_ROOT"; }; - 2BB91B988601A784CA953116 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FileInputStream.cpp"; path = "../../JuceLibraryCode/modules/juce_core/files/juce_FileInputStream.cpp"; sourceTree = "SOURCE_ROOT"; }; - 2C2E1D130B90B220D70A4D7A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_Midi.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_devices/native/juce_win32_Midi.cpp"; sourceTree = "SOURCE_ROOT"; }; - 2C4196232A1D92FC98E51684 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ModalComponentManager.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/components/juce_ModalComponentManager.cpp"; sourceTree = "SOURCE_ROOT"; }; - 2C43979AA3431CC3D61B94A1 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AnimatedAppComponent.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_extra/misc/juce_AnimatedAppComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; - 2CBBEE67AE711FFD4D554623 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioFormatReaderSource.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_formats/format/juce_AudioFormatReaderSource.cpp"; sourceTree = "SOURCE_ROOT"; }; - 2D2048FA048F8CEF2459EF31 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_GenericAudioProcessorEditor.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_processors/processors/juce_GenericAudioProcessorEditor.cpp"; sourceTree = "SOURCE_ROOT"; }; - 2DADD9644CFA5A770AA513A2 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_module_info"; path = "../../JuceLibraryCode/modules/juce_audio_devices/juce_module_info"; sourceTree = "SOURCE_ROOT"; }; - 2DFA08EB2F2965C76C328560 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_gui_basics.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/juce_gui_basics.h"; sourceTree = "SOURCE_ROOT"; }; - 2E91EB1BBD0ED5BC1D0A95A4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TextLayout.h"; path = "../../JuceLibraryCode/modules/juce_graphics/fonts/juce_TextLayout.h"; sourceTree = "SOURCE_ROOT"; }; - 2F8345DA4FF13DA81612EBB3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MidiFile.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_basics/midi/juce_MidiFile.cpp"; sourceTree = "SOURCE_ROOT"; }; - 2F9BA19AD170D9B9F979B025 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_android_CameraDevice.cpp"; path = "../../JuceLibraryCode/modules/juce_video/native/juce_android_CameraDevice.cpp"; sourceTree = "SOURCE_ROOT"; }; - 30236ADC490891CC1557AE3E = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_StandardHeader.h"; path = "../../JuceLibraryCode/modules/juce_core/system/juce_StandardHeader.h"; sourceTree = "SOURCE_ROOT"; }; - 302960973006B86172FD4A6B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_AudioCDReader.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_devices/native/juce_win32_AudioCDReader.cpp"; sourceTree = "SOURCE_ROOT"; }; - 307C5E375D02896F764B50A2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_PopupMenu.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/menus/juce_PopupMenu.h"; sourceTree = "SOURCE_ROOT"; }; + 289C3977B67C1898AC3B974D = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_SharedResourcePointer.h"; path = "../../../../modules/juce_core/memory/juce_SharedResourcePointer.h"; sourceTree = "SOURCE_ROOT"; }; + 28BEE3C7BE3AE2BD888AC55C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OpenGLImage.h"; path = "../../../../modules/juce_opengl/opengl/juce_OpenGLImage.h"; sourceTree = "SOURCE_ROOT"; }; + 29215FCE04DC4D267FF25E6C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_RelativePointPath.h"; path = "../../../../modules/juce_gui_basics/positioning/juce_RelativePointPath.h"; sourceTree = "SOURCE_ROOT"; }; + 29685DC8679DB5024B747D0C = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_ActiveXComponent.cpp"; path = "../../../../modules/juce_gui_extra/native/juce_win32_ActiveXComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; + 29710D5E6C3372E4480BF746 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CaretComponent.h"; path = "../../../../modules/juce_gui_basics/keyboard/juce_CaretComponent.h"; sourceTree = "SOURCE_ROOT"; }; + 29D35A5AB22E9443E0ED8F99 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_RSAKey.cpp"; path = "../../../../modules/juce_cryptography/encryption/juce_RSAKey.cpp"; sourceTree = "SOURCE_ROOT"; }; + 29F5A84EE715DA5BCED467A1 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_AudioCDBurner.cpp"; path = "../../../../modules/juce_audio_devices/native/juce_win32_AudioCDBurner.cpp"; sourceTree = "SOURCE_ROOT"; }; + 2A098563977566E9A9E8CD7E = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_android_OpenSL.cpp"; path = "../../../../modules/juce_audio_devices/native/juce_android_OpenSL.cpp"; sourceTree = "SOURCE_ROOT"; }; + 2A2B7F8BCFC785127CA961A9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MultiTouchMapper.h"; path = "../../../../modules/juce_gui_basics/native/juce_MultiTouchMapper.h"; sourceTree = "SOURCE_ROOT"; }; + 2A59F5E28F97A435592E0B58 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CachedComponentImage.h"; path = "../../../../modules/juce_gui_basics/components/juce_CachedComponentImage.h"; sourceTree = "SOURCE_ROOT"; }; + 2A771B60F7C360A111F75AC6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CustomTypeface.h"; path = "../../../../modules/juce_graphics/fonts/juce_CustomTypeface.h"; sourceTree = "SOURCE_ROOT"; }; + 2AB2B4CC891E77E2DD062BE3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Path.cpp"; path = "../../../../modules/juce_graphics/geometry/juce_Path.cpp"; sourceTree = "SOURCE_ROOT"; }; + 2B02634F8DA8660ED42B0AEF = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_VST3Headers.h"; path = "../../../../modules/juce_audio_processors/format_types/juce_VST3Headers.h"; sourceTree = "SOURCE_ROOT"; }; + 2B1494112273ADF380C99FD3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ValueTree.cpp"; path = "../../../../modules/juce_data_structures/values/juce_ValueTree.cpp"; sourceTree = "SOURCE_ROOT"; }; + 2B4FA0E8FB46CBC71A059FE7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_FileChooser.cpp"; path = "../../../../modules/juce_gui_basics/native/juce_linux_FileChooser.cpp"; sourceTree = "SOURCE_ROOT"; }; + 2B57EB41D3962E3518B79FD8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Socket.h"; path = "../../../../modules/juce_core/network/juce_Socket.h"; sourceTree = "SOURCE_ROOT"; }; + 2B69AEC791776F7CF337E38C = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_SystemTrayIcon.cpp"; path = "../../../../modules/juce_gui_extra/native/juce_linux_SystemTrayIcon.cpp"; sourceTree = "SOURCE_ROOT"; }; + 2B9907A25C1C36C1E46BEA65 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_PathStrokeType.cpp"; path = "../../../../modules/juce_graphics/geometry/juce_PathStrokeType.cpp"; sourceTree = "SOURCE_ROOT"; }; + 2B9BAEF9C46C224088F5BB25 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CallOutBox.h"; path = "../../../../modules/juce_gui_basics/windows/juce_CallOutBox.h"; sourceTree = "SOURCE_ROOT"; }; + 2C1B86FD1CB59198522DEF06 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_WebBrowserComponent.cpp"; path = "../../../../modules/juce_gui_extra/native/juce_win32_WebBrowserComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; + 2C246301EE0EC4A9B4058F01 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Matrix3D.h"; path = "../../../../modules/juce_opengl/geometry/juce_Matrix3D.h"; sourceTree = "SOURCE_ROOT"; }; + 2CFC9FB97ED3587D7E0E4E4B = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MD5.h"; path = "../../../../modules/juce_cryptography/hashing/juce_MD5.h"; sourceTree = "SOURCE_ROOT"; }; + 2CFEB3BEABF88B0C41D94E94 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AffineTransform.h"; path = "../../../../modules/juce_graphics/geometry/juce_AffineTransform.h"; sourceTree = "SOURCE_ROOT"; }; + 2D5F3AD1A03B34AE7349DF5F = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioProcessorListener.h"; path = "../../../../modules/juce_audio_processors/processors/juce_AudioProcessorListener.h"; sourceTree = "SOURCE_ROOT"; }; + 2D8FC1F116F882698F5CFEB9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FileListComponent.h"; path = "../../../../modules/juce_gui_basics/filebrowser/juce_FileListComponent.h"; sourceTree = "SOURCE_ROOT"; }; + 2DB2DBF293A77B80E01EBAED = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ResizableBorderComponent.cpp"; path = "../../../../modules/juce_gui_basics/layout/juce_ResizableBorderComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; + 2DCAC1795F1B47C592E65D4E = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ActionBroadcaster.h"; path = "../../../../modules/juce_events/broadcasters/juce_ActionBroadcaster.h"; sourceTree = "SOURCE_ROOT"; }; + 2E2B14A2334528E4405AEDDC = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ColourGradient.cpp"; path = "../../../../modules/juce_graphics/colour/juce_ColourGradient.cpp"; sourceTree = "SOURCE_ROOT"; }; + 2E650C2E92EA2732B66070D4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_PluginDirectoryScanner.cpp"; path = "../../../../modules/juce_audio_processors/scanning/juce_PluginDirectoryScanner.cpp"; sourceTree = "SOURCE_ROOT"; }; + 2E96848340E1C1B1095AC1F3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Value.cpp"; path = "../../../../modules/juce_data_structures/values/juce_Value.cpp"; sourceTree = "SOURCE_ROOT"; }; + 2FDA8843C89E2D7DFBE3FBFD = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_LowLevelGraphicsSoftwareRenderer.h"; path = "../../../../modules/juce_graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.h"; sourceTree = "SOURCE_ROOT"; }; + 301AF9BA843B1955EE001C98 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ReverbAudioSource.h"; path = "../../../../modules/juce_audio_basics/sources/juce_ReverbAudioSource.h"; sourceTree = "SOURCE_ROOT"; }; + 3095D8D2EF68D6ED502EB00B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_EdgeTable.cpp"; path = "../../../../modules/juce_graphics/geometry/juce_EdgeTable.cpp"; sourceTree = "SOURCE_ROOT"; }; 30B85C7478732E3A6997065D = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; - 30E06EA9F94FA181A6B8F533 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioDataConverters.h"; path = "../../JuceLibraryCode/modules/juce_audio_basics/buffers/juce_AudioDataConverters.h"; sourceTree = "SOURCE_ROOT"; }; - 30EC49300F475411B40273EA = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ImagePreviewComponent.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/filebrowser/juce_ImagePreviewComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; - 313A26829D5268C9E7B28E7E = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_OpenGLPixelFormat.cpp"; path = "../../JuceLibraryCode/modules/juce_opengl/opengl/juce_OpenGLPixelFormat.cpp"; sourceTree = "SOURCE_ROOT"; }; - 31A79A4E5FBBBDAA36B7D273 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_RelativeCoordinate.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/positioning/juce_RelativeCoordinate.cpp"; sourceTree = "SOURCE_ROOT"; }; - 31B95E3446D65E1C0ADC0E4E = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FilenameComponent.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/filebrowser/juce_FilenameComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; - 320CA688772F770F113A99C8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_MessageManager.mm"; path = "../../JuceLibraryCode/modules/juce_events/native/juce_mac_MessageManager.mm"; sourceTree = "SOURCE_ROOT"; }; - 321AC5D0FBCA00E825273253 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OpenGLTexture.h"; path = "../../JuceLibraryCode/modules/juce_opengl/opengl/juce_OpenGLTexture.h"; sourceTree = "SOURCE_ROOT"; }; - 3226060A8CC7B793C5A7A25A = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DocumentWindow.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/windows/juce_DocumentWindow.h"; sourceTree = "SOURCE_ROOT"; }; - 3269E6F38346442BAB611D8C = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ToneGeneratorAudioSource.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_basics/sources/juce_ToneGeneratorAudioSource.cpp"; sourceTree = "SOURCE_ROOT"; }; - 3289B1B53AFC6D7BDBDD850C = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_CodeEditorComponent.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_extra/code_editor/juce_CodeEditorComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; - 3293B0656CFCA5B2303C6E8F = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MidiMessageSequence.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_basics/midi/juce_MidiMessageSequence.cpp"; sourceTree = "SOURCE_ROOT"; }; - 3352C1259B6E110F6B0A835B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ColourGradient.cpp"; path = "../../JuceLibraryCode/modules/juce_graphics/colour/juce_ColourGradient.cpp"; sourceTree = "SOURCE_ROOT"; }; - 3413E3C25DD20925BA622640 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_LAMEEncoderAudioFormat.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_formats/codecs/juce_LAMEEncoderAudioFormat.cpp"; sourceTree = "SOURCE_ROOT"; }; - 34A980957FE5E141693F3334 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioProcessorEditor.h"; path = "../../JuceLibraryCode/modules/juce_audio_processors/processors/juce_AudioProcessorEditor.h"; sourceTree = "SOURCE_ROOT"; }; - 355AFD562757A4867440E64E = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DynamicLibrary.h"; path = "../../JuceLibraryCode/modules/juce_core/threads/juce_DynamicLibrary.h"; sourceTree = "SOURCE_ROOT"; }; - 358A3AED0462892CFDD11749 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CPlusPlusCodeTokeniser.h"; path = "../../JuceLibraryCode/modules/juce_gui_extra/code_editor/juce_CPlusPlusCodeTokeniser.h"; sourceTree = "SOURCE_ROOT"; }; - 358F95020BB4722C04756E09 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_NamedValueSet.cpp"; path = "../../JuceLibraryCode/modules/juce_core/containers/juce_NamedValueSet.cpp"; sourceTree = "SOURCE_ROOT"; }; - 35F51FC31CE36BDF6D41978C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_KnownPluginList.h"; path = "../../JuceLibraryCode/modules/juce_audio_processors/scanning/juce_KnownPluginList.h"; sourceTree = "SOURCE_ROOT"; }; - 3619D8E6B18F0843E8EAA2A5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioTransportSource.h"; path = "../../JuceLibraryCode/modules/juce_audio_devices/sources/juce_AudioTransportSource.h"; sourceTree = "SOURCE_ROOT"; }; - 3669749528AFEB3D613D773E = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_KeyMappingEditorComponent.h"; path = "../../JuceLibraryCode/modules/juce_gui_extra/misc/juce_KeyMappingEditorComponent.h"; sourceTree = "SOURCE_ROOT"; }; - 369EE12DB339DA919C8BF5F6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_events.mm"; path = "../../JuceLibraryCode/modules/juce_events/juce_events.mm"; sourceTree = "SOURCE_ROOT"; }; - 36E382ACBB77916E0A228CC0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioIODeviceType.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_devices/audio_io/juce_AudioIODeviceType.cpp"; sourceTree = "SOURCE_ROOT"; }; - 3748D31911777A17CD3C20A9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_posix_NamedPipe.cpp"; path = "../../JuceLibraryCode/modules/juce_core/native/juce_posix_NamedPipe.cpp"; sourceTree = "SOURCE_ROOT"; }; - 37665101B192EFA4DC5DFE39 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_ALSA.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_devices/native/juce_linux_ALSA.cpp"; sourceTree = "SOURCE_ROOT"; }; - 376708401BCBF6D7EC1F8725 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioTransportSource.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_devices/sources/juce_AudioTransportSource.cpp"; sourceTree = "SOURCE_ROOT"; }; - 37BBA15CAEBD49401D2F82A5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_graphics.h"; path = "../../JuceLibraryCode/modules/juce_graphics/juce_graphics.h"; sourceTree = "SOURCE_ROOT"; }; - 37BEC08C61F8C221C4BED7C3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_SubregionStream.h"; path = "../../JuceLibraryCode/modules/juce_core/streams/juce_SubregionStream.h"; sourceTree = "SOURCE_ROOT"; }; - 37CFAB9F13EC95665CBAB742 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_BufferedInputStream.h"; path = "../../JuceLibraryCode/modules/juce_core/streams/juce_BufferedInputStream.h"; sourceTree = "SOURCE_ROOT"; }; - 384CF76B2FAEB3A5E935AAD8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_DirectSound.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_devices/native/juce_win32_DirectSound.cpp"; sourceTree = "SOURCE_ROOT"; }; - 3898B672BD3A7FDA95255349 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Sampler.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_formats/sampler/juce_Sampler.cpp"; sourceTree = "SOURCE_ROOT"; }; - 38ED648ECAD68AD30C9139AA = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ComponentListener.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/components/juce_ComponentListener.cpp"; sourceTree = "SOURCE_ROOT"; }; - 3944FFE845F494F9A625EC67 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CharPointer_UTF32.h"; path = "../../JuceLibraryCode/modules/juce_core/text/juce_CharPointer_UTF32.h"; sourceTree = "SOURCE_ROOT"; }; - 39562A408421F133E35C495D = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_InterprocessConnection.cpp"; path = "../../JuceLibraryCode/modules/juce_events/interprocess/juce_InterprocessConnection.cpp"; sourceTree = "SOURCE_ROOT"; }; - 398508292A45E227D66AC0E7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Font.cpp"; path = "../../JuceLibraryCode/modules/juce_graphics/fonts/juce_Font.cpp"; sourceTree = "SOURCE_ROOT"; }; - 39EFC895DB6FA253ACD83729 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_PositionableAudioSource.h"; path = "../../JuceLibraryCode/modules/juce_audio_basics/sources/juce_PositionableAudioSource.h"; sourceTree = "SOURCE_ROOT"; }; - 39F3DADB903ABADD1176B79E = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Viewport.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/layout/juce_Viewport.h"; sourceTree = "SOURCE_ROOT"; }; - 3AEDB68E416A876681F89985 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Line.h"; path = "../../JuceLibraryCode/modules/juce_graphics/geometry/juce_Line.h"; sourceTree = "SOURCE_ROOT"; }; - 3AF3E08820EC2CF94B505DCB = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FileChooser.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/filebrowser/juce_FileChooser.cpp"; sourceTree = "SOURCE_ROOT"; }; + 314E9338935BC33A1C468B3E = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MessageListener.cpp"; path = "../../../../modules/juce_events/messages/juce_MessageListener.cpp"; sourceTree = "SOURCE_ROOT"; }; + 31AE430D2372CF6283185033 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_LookAndFeel_V2.h"; path = "../../../../modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V2.h"; sourceTree = "SOURCE_ROOT"; }; + 326E293A87E18FC3FBB26B47 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_GraphicsContext.cpp"; path = "../../../../modules/juce_graphics/contexts/juce_GraphicsContext.cpp"; sourceTree = "SOURCE_ROOT"; }; + 32A667DB98BC4EB30C51F20B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ListBox.cpp"; path = "../../../../modules/juce_gui_basics/widgets/juce_ListBox.cpp"; sourceTree = "SOURCE_ROOT"; }; + 32C683CBA18109949D53149A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_JackAudio.cpp"; path = "../../../../modules/juce_audio_devices/native/juce_linux_JackAudio.cpp"; sourceTree = "SOURCE_ROOT"; }; + 3324210159E5C546DC5C2065 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DeletedAtShutdown.h"; path = "../../../../modules/juce_events/messages/juce_DeletedAtShutdown.h"; sourceTree = "SOURCE_ROOT"; }; + 3391FA30F4D45A4A77DC2CE1 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_mac_CoreGraphicsHelpers.h"; path = "../../../../modules/juce_graphics/native/juce_mac_CoreGraphicsHelpers.h"; sourceTree = "SOURCE_ROOT"; }; + 33E449DEA1FC0CD4CAA3A829 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_cryptography.mm"; path = "../../../../modules/juce_cryptography/juce_cryptography.mm"; sourceTree = "SOURCE_ROOT"; }; + 34A6FFC298D12BF9E4D55AA1 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ComponentAnimator.cpp"; path = "../../../../modules/juce_gui_basics/layout/juce_ComponentAnimator.cpp"; sourceTree = "SOURCE_ROOT"; }; + 35A7FD6EFDE29D2EBD7DFCB8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioCDReader.cpp"; path = "../../../../modules/juce_audio_devices/audio_cd/juce_AudioCDReader.cpp"; sourceTree = "SOURCE_ROOT"; }; + 35AAFB158E16D03C4D977713 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FileSearchPath.h"; path = "../../../../modules/juce_core/files/juce_FileSearchPath.h"; sourceTree = "SOURCE_ROOT"; }; + 35E6F6325AF8463C076BA594 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DrawableButton.cpp"; path = "../../../../modules/juce_gui_basics/buttons/juce_DrawableButton.cpp"; sourceTree = "SOURCE_ROOT"; }; + 369C06F1DC7B3B7EB497D062 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_UndoManager.cpp"; path = "../../../../modules/juce_data_structures/undomanager/juce_UndoManager.cpp"; sourceTree = "SOURCE_ROOT"; }; + 36A0FF58D355147F40981C39 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FileDragAndDropTarget.h"; path = "../../../../modules/juce_gui_basics/mouse/juce_FileDragAndDropTarget.h"; sourceTree = "SOURCE_ROOT"; }; + 36B8F6CFEEA3C1E2A0D09E56 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_VST3Common.h"; path = "../../../../modules/juce_audio_processors/format_types/juce_VST3Common.h"; sourceTree = "SOURCE_ROOT"; }; + 37381332DDDE8F2B3C66CBDE = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_gui_extra.h"; path = "../../../../modules/juce_gui_extra/juce_gui_extra.h"; sourceTree = "SOURCE_ROOT"; }; + 374277A96D9830E45684FDD8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Viewport.h"; path = "../../../../modules/juce_gui_basics/layout/juce_Viewport.h"; sourceTree = "SOURCE_ROOT"; }; + 381AE52C082AE08E724CB954 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ChildProcess.cpp"; path = "../../../../modules/juce_core/threads/juce_ChildProcess.cpp"; sourceTree = "SOURCE_ROOT"; }; + 381B8B8A9D5203E73FED79E9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioPluginFormat.h"; path = "../../../../modules/juce_audio_processors/format/juce_AudioPluginFormat.h"; sourceTree = "SOURCE_ROOT"; }; + 38404F97E5118017DFDCDEC4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_LassoComponent.h"; path = "../../../../modules/juce_gui_basics/mouse/juce_LassoComponent.h"; sourceTree = "SOURCE_ROOT"; }; + 389B4E4055A779D0F6B22C5F = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_StringPool.cpp"; path = "../../../../modules/juce_core/text/juce_StringPool.cpp"; sourceTree = "SOURCE_ROOT"; }; + 38D15A30D4658272F910A7AB = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_KeyboardFocusTraverser.cpp"; path = "../../../../modules/juce_gui_basics/keyboard/juce_KeyboardFocusTraverser.cpp"; sourceTree = "SOURCE_ROOT"; }; + 38EDF1EAB12A05CEE439AF23 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_LADSPAPluginFormat.h"; path = "../../../../modules/juce_audio_processors/format_types/juce_LADSPAPluginFormat.h"; sourceTree = "SOURCE_ROOT"; }; + 3900C9B11914C94DFA1F8C33 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ToneGeneratorAudioSource.h"; path = "../../../../modules/juce_audio_basics/sources/juce_ToneGeneratorAudioSource.h"; sourceTree = "SOURCE_ROOT"; }; + 390351E336C2CF20C38ADB59 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ThreadPool.cpp"; path = "../../../../modules/juce_core/threads/juce_ThreadPool.cpp"; sourceTree = "SOURCE_ROOT"; }; + 393D0CA8D89217F1F2504768 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_TextLayout.cpp"; path = "../../../../modules/juce_graphics/fonts/juce_TextLayout.cpp"; sourceTree = "SOURCE_ROOT"; }; + 394CD5017D81D1CFEBE34894 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_SystemTrayIconComponent.h"; path = "../../../../modules/juce_gui_extra/misc/juce_SystemTrayIconComponent.h"; sourceTree = "SOURCE_ROOT"; }; + 3966D734450E72F5682D2F06 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ImageFileFormat.cpp"; path = "../../../../modules/juce_graphics/images/juce_ImageFileFormat.cpp"; sourceTree = "SOURCE_ROOT"; }; + 3A9FC7EFC378976EE696AE83 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OwnedArray.h"; path = "../../../../modules/juce_core/containers/juce_OwnedArray.h"; sourceTree = "SOURCE_ROOT"; }; + 3AE89D0904EE985359A73B91 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_HighResolutionTimer.cpp"; path = "../../../../modules/juce_core/threads/juce_HighResolutionTimer.cpp"; sourceTree = "SOURCE_ROOT"; }; + 3AF114AC45249CDA77EF940E = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Rectangle.h"; path = "../../../../modules/juce_graphics/geometry/juce_Rectangle.h"; sourceTree = "SOURCE_ROOT"; }; + 3B09334ECC8FB54B4B7D7B59 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ComponentBuilder.h"; path = "../../../../modules/juce_gui_basics/layout/juce_ComponentBuilder.h"; sourceTree = "SOURCE_ROOT"; }; 3B5B55FF08F71060B836F5DB = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; - 3B5DE4A58F1A28D3DC2D5035 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_BubbleMessageComponent.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_extra/misc/juce_BubbleMessageComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; - 3BC29BAC09BDF8518335571D = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Singleton.h"; path = "../../JuceLibraryCode/modules/juce_core/memory/juce_Singleton.h"; sourceTree = "SOURCE_ROOT"; }; - 3C31FCFF8570C5F2281B4774 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_BubbleComponent.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/misc/juce_BubbleComponent.h"; sourceTree = "SOURCE_ROOT"; }; - 3C55CA36E6DF4478E7C2A106 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_UnitTest.cpp"; path = "../../JuceLibraryCode/modules/juce_core/unit_tests/juce_UnitTest.cpp"; sourceTree = "SOURCE_ROOT"; }; - 3CE23C91D3F26953C3BE4A86 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ios_Audio.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_devices/native/juce_ios_Audio.cpp"; sourceTree = "SOURCE_ROOT"; }; - 3D08CF856ED46386AB450F46 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ComponentAnimator.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/layout/juce_ComponentAnimator.h"; sourceTree = "SOURCE_ROOT"; }; - 3D0CCA82BDEA501876257111 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_CameraDevice.mm"; path = "../../JuceLibraryCode/modules/juce_video/native/juce_mac_CameraDevice.mm"; sourceTree = "SOURCE_ROOT"; }; - 3D906BFC50723AC77213FB8E = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_PNGLoader.cpp"; path = "../../JuceLibraryCode/modules/juce_graphics/image_formats/juce_PNGLoader.cpp"; sourceTree = "SOURCE_ROOT"; }; - 3DC4B655D395BCE7D0648755 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_RectangleList.h"; path = "../../JuceLibraryCode/modules/juce_graphics/geometry/juce_RectangleList.h"; sourceTree = "SOURCE_ROOT"; }; - 3DDAC0076D6C914CE76C09D9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_Messaging.cpp"; path = "../../JuceLibraryCode/modules/juce_events/native/juce_win32_Messaging.cpp"; sourceTree = "SOURCE_ROOT"; }; - 3E199BBFEDF370A9853B91E3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_RecentlyOpenedFilesList.h"; path = "../../JuceLibraryCode/modules/juce_gui_extra/misc/juce_RecentlyOpenedFilesList.h"; sourceTree = "SOURCE_ROOT"; }; - 3E25895B1FAD62C2E2DF985E = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_SplashScreen.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_extra/misc/juce_SplashScreen.cpp"; sourceTree = "SOURCE_ROOT"; }; - 3E68E00D0D6613D6A93B3ED1 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_GenericAudioProcessorEditor.h"; path = "../../JuceLibraryCode/modules/juce_audio_processors/processors/juce_GenericAudioProcessorEditor.h"; sourceTree = "SOURCE_ROOT"; }; - 3E9EC18E1C4F444805B36259 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TabbedButtonBar.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/layout/juce_TabbedButtonBar.h"; sourceTree = "SOURCE_ROOT"; }; - 3EFCADD916181E95D684C237 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TextEditor.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/widgets/juce_TextEditor.h"; sourceTree = "SOURCE_ROOT"; }; - 3F1BEF3D596877977723184D = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Array.h"; path = "../../JuceLibraryCode/modules/juce_core/containers/juce_Array.h"; sourceTree = "SOURCE_ROOT"; }; - 3FD4B7D9E2A8CC22D8F0C974 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_android_Misc.cpp"; path = "../../JuceLibraryCode/modules/juce_core/native/juce_android_Misc.cpp"; sourceTree = "SOURCE_ROOT"; }; - 3FEFB6B506459AC93E066C3D = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_android_Audio.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_devices/native/juce_android_Audio.cpp"; sourceTree = "SOURCE_ROOT"; }; - 3FF553F76522FAC43163CE03 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_KeyboardFocusTraverser.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/keyboard/juce_KeyboardFocusTraverser.h"; sourceTree = "SOURCE_ROOT"; }; - 401D5DBEE57DB66AF040885C = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_Direct2DGraphicsContext.cpp"; path = "../../JuceLibraryCode/modules/juce_graphics/native/juce_win32_Direct2DGraphicsContext.cpp"; sourceTree = "SOURCE_ROOT"; }; - 405F7A0C891B13655617BF5F = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_TopLevelWindow.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/windows/juce_TopLevelWindow.cpp"; sourceTree = "SOURCE_ROOT"; }; - 40673853C7079F0A6D8AF2BB = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioSourcePlayer.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_devices/sources/juce_AudioSourcePlayer.cpp"; sourceTree = "SOURCE_ROOT"; }; - 4079EA961E5AFE0A51869E40 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Thread.cpp"; path = "../../JuceLibraryCode/modules/juce_core/threads/juce_Thread.cpp"; sourceTree = "SOURCE_ROOT"; }; - 408F458A6E9A71923FC72D04 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Message.h"; path = "../../JuceLibraryCode/modules/juce_events/messages/juce_Message.h"; sourceTree = "SOURCE_ROOT"; }; - 40B44760A3D17F9F97B857B3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_UndoableAction.h"; path = "../../JuceLibraryCode/modules/juce_data_structures/undomanager/juce_UndoableAction.h"; sourceTree = "SOURCE_ROOT"; }; - 40D6454C05B1D9E3242CDFC8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MP3AudioFormat.h"; path = "../../JuceLibraryCode/modules/juce_audio_formats/codecs/juce_MP3AudioFormat.h"; sourceTree = "SOURCE_ROOT"; }; - 40DDC868EB152DA18FF4832F = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ComponentPeer.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/windows/juce_ComponentPeer.h"; sourceTree = "SOURCE_ROOT"; }; - 4128F91E323A32B6D7189CD5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_NewLine.h"; path = "../../JuceLibraryCode/modules/juce_core/text/juce_NewLine.h"; sourceTree = "SOURCE_ROOT"; }; - 423A70751A8C20A9E1C3E9CB = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AiffAudioFormat.h"; path = "../../JuceLibraryCode/modules/juce_audio_formats/codecs/juce_AiffAudioFormat.h"; sourceTree = "SOURCE_ROOT"; }; - 43234F932D4492E104787435 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ScrollBar.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/layout/juce_ScrollBar.cpp"; sourceTree = "SOURCE_ROOT"; }; - 433E40D469ACDE64A8E40258 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_OpenGLShaderProgram.cpp"; path = "../../JuceLibraryCode/modules/juce_opengl/opengl/juce_OpenGLShaderProgram.cpp"; sourceTree = "SOURCE_ROOT"; }; - 434A87588331CF1CB8118A36 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_RSAKey.cpp"; path = "../../JuceLibraryCode/modules/juce_cryptography/encryption/juce_RSAKey.cpp"; sourceTree = "SOURCE_ROOT"; }; - 438C65CF8B5C0D636F0AC715 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioSourcePlayer.h"; path = "../../JuceLibraryCode/modules/juce_audio_devices/sources/juce_AudioSourcePlayer.h"; sourceTree = "SOURCE_ROOT"; }; - 43BB532CBA295E02FDAC1CFA = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_BigInteger.cpp"; path = "../../JuceLibraryCode/modules/juce_core/maths/juce_BigInteger.cpp"; sourceTree = "SOURCE_ROOT"; }; - 43CC35E1310E10B9422E98C4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ConnectedChildProcess.cpp"; path = "../../JuceLibraryCode/modules/juce_events/interprocess/juce_ConnectedChildProcess.cpp"; sourceTree = "SOURCE_ROOT"; }; - 43F755438129CF5051D3C8D0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_TimeSliceThread.cpp"; path = "../../JuceLibraryCode/modules/juce_core/threads/juce_TimeSliceThread.cpp"; sourceTree = "SOURCE_ROOT"; }; - 442ADB5B235BA350C5FD0BD1 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_VSTPluginFormat.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp"; sourceTree = "SOURCE_ROOT"; }; - 44DE484AE50122D19A902731 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_PluginListComponent.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_processors/scanning/juce_PluginListComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; - 44F0CE6E0BBCE5E596BF70A6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioDataConverters.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_basics/buffers/juce_AudioDataConverters.cpp"; sourceTree = "SOURCE_ROOT"; }; - 45210D0101FB1A0A4AFA4C54 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_PropertyPanel.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/properties/juce_PropertyPanel.cpp"; sourceTree = "SOURCE_ROOT"; }; - 4563BD0A5FB10592A3DC6244 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_InterProcessLock.h"; path = "../../JuceLibraryCode/modules/juce_core/threads/juce_InterProcessLock.h"; sourceTree = "SOURCE_ROOT"; }; - 458072B5FE996673CD03DC28 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_android_OpenSL.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_devices/native/juce_android_OpenSL.cpp"; sourceTree = "SOURCE_ROOT"; }; - 45E9503C1F2B4418E687E9A7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MessageListener.cpp"; path = "../../JuceLibraryCode/modules/juce_events/messages/juce_MessageListener.cpp"; sourceTree = "SOURCE_ROOT"; }; - 45EFD54010FF09B5795B59CD = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_SliderPropertyComponent.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/properties/juce_SliderPropertyComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; - 461440C6B5EE1CF5DB2ECDDA = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TopLevelWindow.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/windows/juce_TopLevelWindow.h"; sourceTree = "SOURCE_ROOT"; }; - 4625F35561AEC875DBEF087B = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ReferenceCountedArray.h"; path = "../../JuceLibraryCode/modules/juce_core/containers/juce_ReferenceCountedArray.h"; sourceTree = "SOURCE_ROOT"; }; - 46A5E45225E1FDA3975F6C83 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_LowLevelGraphicsSoftwareRenderer.cpp"; path = "../../JuceLibraryCode/modules/juce_graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.cpp"; sourceTree = "SOURCE_ROOT"; }; - 46D9408E336E541FAFFB6F1D = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MouseInputSource.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/mouse/juce_MouseInputSource.cpp"; sourceTree = "SOURCE_ROOT"; }; - 476DAA4C7DBFD4BC115090D2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AnimatedPosition.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/layout/juce_AnimatedPosition.h"; sourceTree = "SOURCE_ROOT"; }; - 4784BB8CDAEA553AEA062A56 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MouseCursor.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/mouse/juce_MouseCursor.cpp"; sourceTree = "SOURCE_ROOT"; }; - 478C5F19200D7A3E3D0F3767 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_LuaCodeTokeniser.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_extra/code_editor/juce_LuaCodeTokeniser.cpp"; sourceTree = "SOURCE_ROOT"; }; - 48225D3F1FDE66F5A56A1ABA = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ConcertinaPanel.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/layout/juce_ConcertinaPanel.h"; sourceTree = "SOURCE_ROOT"; }; - 48403410E9FE064527EDCC85 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ReverbAudioSource.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_basics/sources/juce_ReverbAudioSource.cpp"; sourceTree = "SOURCE_ROOT"; }; - 48B1172E10D1795EFD5B4731 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Memory.h"; path = "../../JuceLibraryCode/modules/juce_core/memory/juce_Memory.h"; sourceTree = "SOURCE_ROOT"; }; - 48BDA8E72F3E90C3DF0F9B91 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OwnedArray.h"; path = "../../JuceLibraryCode/modules/juce_core/containers/juce_OwnedArray.h"; sourceTree = "SOURCE_ROOT"; }; - 49C6550365D3B05E7D030E2B = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OpenGL_ios.h"; path = "../../JuceLibraryCode/modules/juce_opengl/native/juce_OpenGL_ios.h"; sourceTree = "SOURCE_ROOT"; }; - 4A0D71E8FA4622C6C7687DD7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_RelativePointPath.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/positioning/juce_RelativePointPath.cpp"; sourceTree = "SOURCE_ROOT"; }; - 4B06A49CE12DBFA2FC861D50 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_SVGParser.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/drawables/juce_SVGParser.cpp"; sourceTree = "SOURCE_ROOT"; }; - 4B09912103F721693FB77FEC = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_SHA256.h"; path = "../../JuceLibraryCode/modules/juce_cryptography/hashing/juce_SHA256.h"; sourceTree = "SOURCE_ROOT"; }; - 4B2CB85C841304CE2E93592F = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_InterprocessConnectionServer.h"; path = "../../JuceLibraryCode/modules/juce_events/interprocess/juce_InterprocessConnectionServer.h"; sourceTree = "SOURCE_ROOT"; }; - 4B4BC465C9478425824F5A82 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ComponentBoundsConstrainer.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/layout/juce_ComponentBoundsConstrainer.cpp"; sourceTree = "SOURCE_ROOT"; }; - 4C41E9A5BA9B4CA47D4A37BB = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DrawablePath.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/drawables/juce_DrawablePath.h"; sourceTree = "SOURCE_ROOT"; }; - 4C512B82D4659142CAAB8390 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_NSViewComponent.mm"; path = "../../JuceLibraryCode/modules/juce_gui_extra/native/juce_mac_NSViewComponent.mm"; sourceTree = "SOURCE_ROOT"; }; - 4C699E969B418C7C5EBE4DB9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MidiMessageCollector.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_devices/midi_io/juce_MidiMessageCollector.cpp"; sourceTree = "SOURCE_ROOT"; }; - 4C93E808908617B457689A69 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ShapeButton.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/buttons/juce_ShapeButton.cpp"; sourceTree = "SOURCE_ROOT"; }; - 4CC30DD2477041D19048C805 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Socket.cpp"; path = "../../JuceLibraryCode/modules/juce_core/network/juce_Socket.cpp"; sourceTree = "SOURCE_ROOT"; }; - 4D67518B8585D2075E450D75 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_PathStrokeType.h"; path = "../../JuceLibraryCode/modules/juce_graphics/geometry/juce_PathStrokeType.h"; sourceTree = "SOURCE_ROOT"; }; - 4D7D8DF32996B70112FFA693 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ThreadWithProgressWindow.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/windows/juce_ThreadWithProgressWindow.cpp"; sourceTree = "SOURCE_ROOT"; }; - 4D97C6AE9A54A7F9663B0022 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_module_info"; path = "../../JuceLibraryCode/modules/juce_gui_extra/juce_module_info"; sourceTree = "SOURCE_ROOT"; }; - 4E02D9A4D6D38BACAB9326AC = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Result.h"; path = "../../JuceLibraryCode/modules/juce_core/misc/juce_Result.h"; sourceTree = "SOURCE_ROOT"; }; - 4E3E146079BC92DDE7B47EF9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_android_Fonts.cpp"; path = "../../JuceLibraryCode/modules/juce_graphics/native/juce_android_Fonts.cpp"; sourceTree = "SOURCE_ROOT"; }; - 4E7B7D1DE6EFB7C38845D97A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FileOutputStream.cpp"; path = "../../JuceLibraryCode/modules/juce_core/files/juce_FileOutputStream.cpp"; sourceTree = "SOURCE_ROOT"; }; - 4EA7EB8C8EDE34046AD54E2F = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_TableHeaderComponent.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/widgets/juce_TableHeaderComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; + 3B9903B0A0252D106C92CAA9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_audio_basics.h"; path = "../../../../modules/juce_audio_basics/juce_audio_basics.h"; sourceTree = "SOURCE_ROOT"; }; + 3BDF8DF3F3C380B1A4CE6C8F = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FileBasedDocument.cpp"; path = "../../../../modules/juce_gui_extra/documents/juce_FileBasedDocument.cpp"; sourceTree = "SOURCE_ROOT"; }; + 3BF23F0B71FB8E526E895905 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FileSearchPathListComponent.cpp"; path = "../../../../modules/juce_gui_basics/filebrowser/juce_FileSearchPathListComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; + 3C825AE2479611DA559164B5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_KeyPressMappingSet.h"; path = "../../../../modules/juce_gui_basics/commands/juce_KeyPressMappingSet.h"; sourceTree = "SOURCE_ROOT"; }; + 3C89D04328C83D2FDD4E5116 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_ios_MessageManager.mm"; path = "../../../../modules/juce_events/native/juce_ios_MessageManager.mm"; sourceTree = "SOURCE_ROOT"; }; + 3CD47BA1CFEFB637DDEAC313 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_SystemStats.cpp"; path = "../../../../modules/juce_core/system/juce_SystemStats.cpp"; sourceTree = "SOURCE_ROOT"; }; + 3D16FF3C64D4248C0C6FF504 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_TableHeaderComponent.cpp"; path = "../../../../modules/juce_gui_basics/widgets/juce_TableHeaderComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; + 3D24784AEA7726A64A340625 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioDeviceManager.h"; path = "../../../../modules/juce_audio_devices/audio_io/juce_AudioDeviceManager.h"; sourceTree = "SOURCE_ROOT"; }; + 3E19A71C4A345EB5C1BA466D = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_WaitableEvent.h"; path = "../../../../modules/juce_core/threads/juce_WaitableEvent.h"; sourceTree = "SOURCE_ROOT"; }; + 3E8E31BB97A86349790D6CC3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_CoreGraphicsContext.mm"; path = "../../../../modules/juce_graphics/native/juce_mac_CoreGraphicsContext.mm"; sourceTree = "SOURCE_ROOT"; }; + 3F0388309395C138AA68FAD7 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_module_info"; path = "../../../../modules/juce_audio_processors/juce_module_info"; sourceTree = "SOURCE_ROOT"; }; + 3FAA5384DA8B28DEB5E57A5D = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ZipFile.cpp"; path = "../../../../modules/juce_core/zip/juce_ZipFile.cpp"; sourceTree = "SOURCE_ROOT"; }; + 3FECAB20E9C0834676E2D9EB = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_File.cpp"; path = "../../../../modules/juce_core/files/juce_File.cpp"; sourceTree = "SOURCE_ROOT"; }; + 403453363C4785FD451A9BA1 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_LagrangeInterpolator.h"; path = "../../../../modules/juce_audio_basics/effects/juce_LagrangeInterpolator.h"; sourceTree = "SOURCE_ROOT"; }; + 40B9C2276B7EF73860E2606B = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioProcessorEditor.h"; path = "../../../../modules/juce_audio_processors/processors/juce_AudioProcessorEditor.h"; sourceTree = "SOURCE_ROOT"; }; + 40F0E944D041D96F2DA4C6A2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_Threads.cpp"; path = "../../../../modules/juce_core/native/juce_win32_Threads.cpp"; sourceTree = "SOURCE_ROOT"; }; + 412D5D6AA4018C8DF59AB741 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_RelativeRectangle.cpp"; path = "../../../../modules/juce_gui_basics/positioning/juce_RelativeRectangle.cpp"; sourceTree = "SOURCE_ROOT"; }; + 414AAB7000E7FDE7683BE72F = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_UIViewComponent.h"; path = "../../../../modules/juce_gui_extra/embedding/juce_UIViewComponent.h"; sourceTree = "SOURCE_ROOT"; }; + 41C74B59D9B392117441DA2D = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioCDBurner.h"; path = "../../../../modules/juce_audio_devices/audio_cd/juce_AudioCDBurner.h"; sourceTree = "SOURCE_ROOT"; }; + 4228B8952E3FBCDA69C1948B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_SHA256.cpp"; path = "../../../../modules/juce_cryptography/hashing/juce_SHA256.cpp"; sourceTree = "SOURCE_ROOT"; }; + 426283CFD858F482E87F530B = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Thread.h"; path = "../../../../modules/juce_core/threads/juce_Thread.h"; sourceTree = "SOURCE_ROOT"; }; + 42BC8303198293E30AC0B21A = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_GlyphArrangement.h"; path = "../../../../modules/juce_graphics/fonts/juce_GlyphArrangement.h"; sourceTree = "SOURCE_ROOT"; }; + 435858CCF38F47E9AAE1B08F = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ChangeListener.h"; path = "../../../../modules/juce_events/broadcasters/juce_ChangeListener.h"; sourceTree = "SOURCE_ROOT"; }; + 439FC260CD869E30210D98BF = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_PopupMenu.h"; path = "../../../../modules/juce_gui_basics/menus/juce_PopupMenu.h"; sourceTree = "SOURCE_ROOT"; }; + 4408766B366713F55707B7A8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ShapeButton.h"; path = "../../../../modules/juce_gui_basics/buttons/juce_ShapeButton.h"; sourceTree = "SOURCE_ROOT"; }; + 440A182A9068A8FBD011BE1A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_InputStream.cpp"; path = "../../../../modules/juce_core/streams/juce_InputStream.cpp"; sourceTree = "SOURCE_ROOT"; }; + 44185DE135E354DD4758B3EA = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Thread.cpp"; path = "../../../../modules/juce_core/threads/juce_Thread.cpp"; sourceTree = "SOURCE_ROOT"; }; + 442199479D1499B6A44BD150 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_module_info"; path = "../../../../modules/juce_audio_devices/juce_module_info"; sourceTree = "SOURCE_ROOT"; }; + 44443DA5B0FDA2480DFBDFC7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AttributedString.h"; path = "../../../../modules/juce_graphics/fonts/juce_AttributedString.h"; sourceTree = "SOURCE_ROOT"; }; + 44ADFB25768FA3BF27762EBF = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_OpenGLAppComponent.cpp"; path = "../../../../modules/juce_opengl/utils/juce_OpenGLAppComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; + 44B3428E8BB4B70104CD76CF = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ResamplingAudioSource.h"; path = "../../../../modules/juce_audio_basics/sources/juce_ResamplingAudioSource.h"; sourceTree = "SOURCE_ROOT"; }; + 44C6568EC00F1682FBCD3B69 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ToolbarItemPalette.cpp"; path = "../../../../modules/juce_gui_basics/widgets/juce_ToolbarItemPalette.cpp"; sourceTree = "SOURCE_ROOT"; }; + 44FC8BD37CFE8C0D851C46F9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_TextEditor.cpp"; path = "../../../../modules/juce_gui_basics/widgets/juce_TextEditor.cpp"; sourceTree = "SOURCE_ROOT"; }; + 4510E3B6AD441EA03B993692 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_OpenGLGraphicsContext.cpp"; path = "../../../../modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.cpp"; sourceTree = "SOURCE_ROOT"; }; + 4570554FB8438C0692EEDC55 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Variant.cpp"; path = "../../../../modules/juce_core/containers/juce_Variant.cpp"; sourceTree = "SOURCE_ROOT"; }; + 464424DDD6A6678B94CE667F = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_CallOutBox.cpp"; path = "../../../../modules/juce_gui_basics/windows/juce_CallOutBox.cpp"; sourceTree = "SOURCE_ROOT"; }; + 4658E12862C546A62E05E4D3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TabbedComponent.h"; path = "../../../../modules/juce_gui_basics/layout/juce_TabbedComponent.h"; sourceTree = "SOURCE_ROOT"; }; + 46885692CC5FDE30FC3649F6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_WavAudioFormat.h"; path = "../../../../modules/juce_audio_formats/codecs/juce_WavAudioFormat.h"; sourceTree = "SOURCE_ROOT"; }; + 46D8BC7303C892ED3F90E4DA = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_CaretComponent.cpp"; path = "../../../../modules/juce_gui_basics/keyboard/juce_CaretComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; + 47E5FB5735D2EC8B039D2691 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Application.h"; path = "../../../../modules/juce_gui_basics/application/juce_Application.h"; sourceTree = "SOURCE_ROOT"; }; + 47E70AF805B1C5C57566C4CB = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MemoryInputStream.cpp"; path = "../../../../modules/juce_core/streams/juce_MemoryInputStream.cpp"; sourceTree = "SOURCE_ROOT"; }; + 495EAFDB9DE4E8E7DBA562D4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OpenGL_win32.h"; path = "../../../../modules/juce_opengl/native/juce_OpenGL_win32.h"; sourceTree = "SOURCE_ROOT"; }; + 49794569C715BA919A01D72E = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ModifierKeys.cpp"; path = "../../../../modules/juce_gui_basics/keyboard/juce_ModifierKeys.cpp"; sourceTree = "SOURCE_ROOT"; }; + 4A1671B78E589A865FEA3CB1 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioIODevice.cpp"; path = "../../../../modules/juce_audio_devices/audio_io/juce_AudioIODevice.cpp"; sourceTree = "SOURCE_ROOT"; }; + 4A31DFDB7AC330488B8BBEA3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Component.cpp"; path = "../../../../modules/juce_gui_basics/components/juce_Component.cpp"; sourceTree = "SOURCE_ROOT"; }; + 4A36826C3F710B92F0347A16 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Singleton.h"; path = "../../../../modules/juce_core/memory/juce_Singleton.h"; sourceTree = "SOURCE_ROOT"; }; + 4A86B4371AE4FC58D879962C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CharPointer_UTF16.h"; path = "../../../../modules/juce_core/text/juce_CharPointer_UTF16.h"; sourceTree = "SOURCE_ROOT"; }; + 4ABF36D87D2BBEDA4DE28A4E = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FileChooserDialogBox.h"; path = "../../../../modules/juce_gui_basics/filebrowser/juce_FileChooserDialogBox.h"; sourceTree = "SOURCE_ROOT"; }; + 4ADE9EFB6C41DE44D40C9837 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_RelativeTime.cpp"; path = "../../../../modules/juce_core/time/juce_RelativeTime.cpp"; sourceTree = "SOURCE_ROOT"; }; + 4B27A11ADAC0D9957BBBCD3E = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_graphics.mm"; path = "../../../../modules/juce_graphics/juce_graphics.mm"; sourceTree = "SOURCE_ROOT"; }; + 4B27C30CF5AC7BFE0AF537AD = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_QuickTimeAudioFormat.cpp"; path = "../../../../modules/juce_audio_formats/codecs/juce_QuickTimeAudioFormat.cpp"; sourceTree = "SOURCE_ROOT"; }; + 4B8102606812A7964CF8D9CE = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_WindowsMediaAudioFormat.h"; path = "../../../../modules/juce_audio_formats/codecs/juce_WindowsMediaAudioFormat.h"; sourceTree = "SOURCE_ROOT"; }; + 4B8342C50F962C3F0AEE9830 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_NormalisableRange.h"; path = "../../../../modules/juce_core/maths/juce_NormalisableRange.h"; sourceTree = "SOURCE_ROOT"; }; + 4BAF7C54867DA3C275C2F59D = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ComponentPeer.cpp"; path = "../../../../modules/juce_gui_basics/windows/juce_ComponentPeer.cpp"; sourceTree = "SOURCE_ROOT"; }; + 4BDEC9A0A09EEDC9D7BDB826 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ByteOrder.h"; path = "../../../../modules/juce_core/memory/juce_ByteOrder.h"; sourceTree = "SOURCE_ROOT"; }; + 4BF9949E0C30EA64B16004BE = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioIODeviceType.h"; path = "../../../../modules/juce_audio_devices/audio_io/juce_AudioIODeviceType.h"; sourceTree = "SOURCE_ROOT"; }; + 4C40BFAE1E25F166EBB5EC48 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_GroupComponent.cpp"; path = "../../../../modules/juce_gui_basics/layout/juce_GroupComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; + 4C87C8EC24CE0EB64640238A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MD5.cpp"; path = "../../../../modules/juce_cryptography/hashing/juce_MD5.cpp"; sourceTree = "SOURCE_ROOT"; }; + 4CF92825BE7B97AC268C2AA5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_LookAndFeel.h"; path = "../../../../modules/juce_gui_basics/lookandfeel/juce_LookAndFeel.h"; sourceTree = "SOURCE_ROOT"; }; + 4D5901626201478A459CE46C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_LiveConstantEditor.h"; path = "../../../../modules/juce_gui_extra/misc/juce_LiveConstantEditor.h"; sourceTree = "SOURCE_ROOT"; }; + 4DB2143B264FC1AE54490BF9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_SortedSet.h"; path = "../../../../modules/juce_core/containers/juce_SortedSet.h"; sourceTree = "SOURCE_ROOT"; }; + 4DB48F6BAEFA120A31259EAE = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_SystemStats.cpp"; path = "../../../../modules/juce_core/native/juce_linux_SystemStats.cpp"; sourceTree = "SOURCE_ROOT"; }; + 4E3C26EE8C6F996F207F0C32 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_RelativePoint.cpp"; path = "../../../../modules/juce_gui_basics/positioning/juce_RelativePoint.cpp"; sourceTree = "SOURCE_ROOT"; }; + 4EAE69CF6B5097A57EBCD27B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ChannelRemappingAudioSource.cpp"; path = "../../../../modules/juce_audio_basics/sources/juce_ChannelRemappingAudioSource.cpp"; sourceTree = "SOURCE_ROOT"; }; + 4EB8D72F57E00C560E370DCB = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_OpenGLShaderProgram.cpp"; path = "../../../../modules/juce_opengl/opengl/juce_OpenGLShaderProgram.cpp"; sourceTree = "SOURCE_ROOT"; }; + 4EBC561A323AEE4D76AD7906 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MixerAudioSource.cpp"; path = "../../../../modules/juce_audio_basics/sources/juce_MixerAudioSource.cpp"; sourceTree = "SOURCE_ROOT"; }; + 4F2D3BD9697AAFA060EAAA59 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ChoicePropertyComponent.h"; path = "../../../../modules/juce_gui_basics/properties/juce_ChoicePropertyComponent.h"; sourceTree = "SOURCE_ROOT"; }; 4F582012EC867318FB3781BB = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = AnimationAppExample/Images.xcassets; sourceTree = "SOURCE_ROOT"; }; - 4F6BC156DF6D42B5A2E6B9D5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ToolbarItemComponent.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/widgets/juce_ToolbarItemComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; - 4F73548B7300043B5CBD8853 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ToneGeneratorAudioSource.h"; path = "../../JuceLibraryCode/modules/juce_audio_basics/sources/juce_ToneGeneratorAudioSource.h"; sourceTree = "SOURCE_ROOT"; }; - 500556EB77FC460F48E018BE = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_XmlDocument.cpp"; path = "../../JuceLibraryCode/modules/juce_core/xml/juce_XmlDocument.cpp"; sourceTree = "SOURCE_ROOT"; }; - 50923F018EFA0EC66289B8DB = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ResizableCornerComponent.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/layout/juce_ResizableCornerComponent.h"; sourceTree = "SOURCE_ROOT"; }; - 50CCC0CC14D17378013CFD72 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_audio_basics.mm"; path = "../../JuceLibraryCode/modules/juce_audio_basics/juce_audio_basics.mm"; sourceTree = "SOURCE_ROOT"; }; - 517756F0CB6482D0AAF4F6E3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FileSearchPath.cpp"; path = "../../JuceLibraryCode/modules/juce_core/files/juce_FileSearchPath.cpp"; sourceTree = "SOURCE_ROOT"; }; - 5178CA597B45B186FEF4D2CD = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Application.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/application/juce_Application.cpp"; sourceTree = "SOURCE_ROOT"; }; - 519B2190343506FF89DD9796 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ImageButton.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/buttons/juce_ImageButton.h"; sourceTree = "SOURCE_ROOT"; }; - 51EF1B32326BCE4445FD8929 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_URL.h"; path = "../../JuceLibraryCode/modules/juce_core/network/juce_URL.h"; sourceTree = "SOURCE_ROOT"; }; - 52438BC8DDE3E8A8A708D307 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FileBrowserComponent.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/filebrowser/juce_FileBrowserComponent.h"; sourceTree = "SOURCE_ROOT"; }; - 525381C319EDB9B47F9DFCFF = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FileChooserDialogBox.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/filebrowser/juce_FileChooserDialogBox.cpp"; sourceTree = "SOURCE_ROOT"; }; - 52B3E9170C4FF9A60E75030D = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Desktop.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/components/juce_Desktop.cpp"; sourceTree = "SOURCE_ROOT"; }; - 52C131B4F65C596E275CC17C = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_CharacterFunctions.cpp"; path = "../../JuceLibraryCode/modules/juce_core/text/juce_CharacterFunctions.cpp"; sourceTree = "SOURCE_ROOT"; }; - 52CC3D36E2A4DD363F99DA9B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_android_WebBrowserComponent.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_extra/native/juce_android_WebBrowserComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; - 52D6B752BBA03EE32E0186EF = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AffineTransform.h"; path = "../../JuceLibraryCode/modules/juce_graphics/geometry/juce_AffineTransform.h"; sourceTree = "SOURCE_ROOT"; }; - 534EB22CE7A71591FCCBA8E4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ComponentDragger.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/mouse/juce_ComponentDragger.cpp"; sourceTree = "SOURCE_ROOT"; }; - 538353D423AC527D313BE99E = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_StretchableLayoutResizerBar.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/layout/juce_StretchableLayoutResizerBar.cpp"; sourceTree = "SOURCE_ROOT"; }; - 538907D94243347E0BD1136A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_JackAudio.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_devices/native/juce_linux_JackAudio.cpp"; sourceTree = "SOURCE_ROOT"; }; - 53972777A5EAB63C5D1DF5E5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_HeapBlock.h"; path = "../../JuceLibraryCode/modules/juce_core/memory/juce_HeapBlock.h"; sourceTree = "SOURCE_ROOT"; }; - 53C236BFA019E49855DD8A22 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Synthesiser.h"; path = "../../JuceLibraryCode/modules/juce_audio_basics/synthesisers/juce_Synthesiser.h"; sourceTree = "SOURCE_ROOT"; }; - 53C4988130522C6DA28A4BE1 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ChildProcess.cpp"; path = "../../JuceLibraryCode/modules/juce_core/threads/juce_ChildProcess.cpp"; sourceTree = "SOURCE_ROOT"; }; - 53CB2A656137C68DC54B43C9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_PerformanceCounter.h"; path = "../../JuceLibraryCode/modules/juce_core/time/juce_PerformanceCounter.h"; sourceTree = "SOURCE_ROOT"; }; - 54063388CD6D9F64180BC16D = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DropShadowEffect.cpp"; path = "../../JuceLibraryCode/modules/juce_graphics/effects/juce_DropShadowEffect.cpp"; sourceTree = "SOURCE_ROOT"; }; - 5424AA8231E11912CD1C516C = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Drawable.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/drawables/juce_Drawable.cpp"; sourceTree = "SOURCE_ROOT"; }; - 5434B55E1B4DCA4392ADF45D = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_module_info"; path = "../../JuceLibraryCode/modules/juce_audio_formats/juce_module_info"; sourceTree = "SOURCE_ROOT"; }; - 54369A3FBDBDCC0FED963610 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Variant.cpp"; path = "../../JuceLibraryCode/modules/juce_core/containers/juce_Variant.cpp"; sourceTree = "SOURCE_ROOT"; }; - 549AA1BB3A58BFDDDDD1FA32 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OpenGL_osx.h"; path = "../../JuceLibraryCode/modules/juce_opengl/native/juce_OpenGL_osx.h"; sourceTree = "SOURCE_ROOT"; }; - 54C1B379B72BAE39C06D9BB0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_InterprocessConnection.h"; path = "../../JuceLibraryCode/modules/juce_events/interprocess/juce_InterprocessConnection.h"; sourceTree = "SOURCE_ROOT"; }; - 5500A9D5683F5124D0BAEA8B = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_RelativeRectangle.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/positioning/juce_RelativeRectangle.h"; sourceTree = "SOURCE_ROOT"; }; - 552E3A59D6200D3CA42CB2E5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_GroupComponent.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/layout/juce_GroupComponent.h"; sourceTree = "SOURCE_ROOT"; }; - 5550F75596B1C84414059D9C = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_android_Network.cpp"; path = "../../JuceLibraryCode/modules/juce_core/native/juce_android_Network.cpp"; sourceTree = "SOURCE_ROOT"; }; - 555BF349B10EE4EF21DCA398 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioSampleBuffer.h"; path = "../../JuceLibraryCode/modules/juce_audio_basics/buffers/juce_AudioSampleBuffer.h"; sourceTree = "SOURCE_ROOT"; }; - 5586252F2B71502A0C1A69B5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ThreadWithProgressWindow.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/windows/juce_ThreadWithProgressWindow.h"; sourceTree = "SOURCE_ROOT"; }; - 560303C3ABFD2D8DA80F5369 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ByteOrder.h"; path = "../../JuceLibraryCode/modules/juce_core/memory/juce_ByteOrder.h"; sourceTree = "SOURCE_ROOT"; }; - 56207999C7136BA24F53DB94 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_RelativePoint.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/positioning/juce_RelativePoint.h"; sourceTree = "SOURCE_ROOT"; }; - 56872D4E18FFA80AEDD4FF35 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_Fonts.cpp"; path = "../../JuceLibraryCode/modules/juce_graphics/native/juce_linux_Fonts.cpp"; sourceTree = "SOURCE_ROOT"; }; - 568C771CA43B20ED9320E9AD = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_InputStream.cpp"; path = "../../JuceLibraryCode/modules/juce_core/streams/juce_InputStream.cpp"; sourceTree = "SOURCE_ROOT"; }; - 56DCDED7C229BEA998AE9610 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_GraphicsContext.cpp"; path = "../../JuceLibraryCode/modules/juce_graphics/contexts/juce_GraphicsContext.cpp"; sourceTree = "SOURCE_ROOT"; }; - 570EA0ADD7290B6AF6C74960 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_OpenGLAppComponent.cpp"; path = "../../JuceLibraryCode/modules/juce_opengl/utils/juce_OpenGLAppComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; - 572F0A8E449EEE319155A448 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_module_info"; path = "../../JuceLibraryCode/modules/juce_graphics/juce_module_info"; sourceTree = "SOURCE_ROOT"; }; - 572F241637045113CA1101E3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ApplicationBase.cpp"; path = "../../JuceLibraryCode/modules/juce_events/messages/juce_ApplicationBase.cpp"; sourceTree = "SOURCE_ROOT"; }; - 57D9F9DA0E4AC9350182E868 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_FileChooser.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/native/juce_win32_FileChooser.cpp"; sourceTree = "SOURCE_ROOT"; }; - 57F9DFFE80638F013ED82F0B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_CodeDocument.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_extra/code_editor/juce_CodeDocument.cpp"; sourceTree = "SOURCE_ROOT"; }; - 584FB01EADCAFB49A98CED27 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_Registry.cpp"; path = "../../JuceLibraryCode/modules/juce_core/native/juce_win32_Registry.cpp"; sourceTree = "SOURCE_ROOT"; }; - 58F79BEACB41061A067708E4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CodeEditorComponent.h"; path = "../../JuceLibraryCode/modules/juce_gui_extra/code_editor/juce_CodeEditorComponent.h"; sourceTree = "SOURCE_ROOT"; }; - 58FB0E03D5E6CC4122CD00B8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FileListComponent.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/filebrowser/juce_FileListComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; - 5982BD1B4149622A6FD884A4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MouseEvent.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/mouse/juce_MouseEvent.cpp"; sourceTree = "SOURCE_ROOT"; }; - 5A8383F3E5B628DE60DB8291 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_gui_extra.mm"; path = "../../JuceLibraryCode/modules/juce_gui_extra/juce_gui_extra.mm"; sourceTree = "SOURCE_ROOT"; }; - 5B679BA94EFF51894AD674EA = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_PropertiesFile.h"; path = "../../JuceLibraryCode/modules/juce_data_structures/app_properties/juce_PropertiesFile.h"; sourceTree = "SOURCE_ROOT"; }; - 5B70ED35F78822734FD91F6F = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ComboBox.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/widgets/juce_ComboBox.h"; sourceTree = "SOURCE_ROOT"; }; - 5B7A3EE41F87CB2931C1E13C = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioSampleBuffer.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_basics/buffers/juce_AudioSampleBuffer.cpp"; sourceTree = "SOURCE_ROOT"; }; - 5B9FDDF7446043886E09E303 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Vector3D.h"; path = "../../JuceLibraryCode/modules/juce_opengl/geometry/juce_Vector3D.h"; sourceTree = "SOURCE_ROOT"; }; - 5C3EF1C1AEC96D6C8687E242 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_android_Threads.cpp"; path = "../../JuceLibraryCode/modules/juce_core/native/juce_android_Threads.cpp"; sourceTree = "SOURCE_ROOT"; }; - 5C74D5593E152C52854A522F = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MixerAudioSource.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_basics/sources/juce_MixerAudioSource.cpp"; sourceTree = "SOURCE_ROOT"; }; - 5CEC5FFCAF1B33BE9B86CDBE = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_PreferencesPanel.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_extra/misc/juce_PreferencesPanel.cpp"; sourceTree = "SOURCE_ROOT"; }; - 5D4B884A37E3A190B16B34CA = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ListBox.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/widgets/juce_ListBox.h"; sourceTree = "SOURCE_ROOT"; }; - 5D903A277EFDDFA522C67E84 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_KnownPluginList.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_processors/scanning/juce_KnownPluginList.cpp"; sourceTree = "SOURCE_ROOT"; }; - 5DF85E59C6FBA88E394C4FD4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_WaitableEvent.h"; path = "../../JuceLibraryCode/modules/juce_core/threads/juce_WaitableEvent.h"; sourceTree = "SOURCE_ROOT"; }; - 5E135BD422EF904C0FCAD1D0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_GlyphArrangement.h"; path = "../../JuceLibraryCode/modules/juce_graphics/fonts/juce_GlyphArrangement.h"; sourceTree = "SOURCE_ROOT"; }; - 5E3AE8001BCEFBED6A1954DA = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioPluginFormatManager.h"; path = "../../JuceLibraryCode/modules/juce_audio_processors/format/juce_AudioPluginFormatManager.h"; sourceTree = "SOURCE_ROOT"; }; - 5E5F9CA2713C02B4DAAEFF9C = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Result.cpp"; path = "../../JuceLibraryCode/modules/juce_core/misc/juce_Result.cpp"; sourceTree = "SOURCE_ROOT"; }; - 5F1334788D34BA2E6EF83086 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_mac_CoreGraphicsHelpers.h"; path = "../../JuceLibraryCode/modules/juce_graphics/native/juce_mac_CoreGraphicsHelpers.h"; sourceTree = "SOURCE_ROOT"; }; - 5F1E31EAC156296643CA5A5F = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_TreeView.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/widgets/juce_TreeView.cpp"; sourceTree = "SOURCE_ROOT"; }; - 5FD5C6D8A917C60FBF029EC0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ButtonPropertyComponent.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/properties/juce_ButtonPropertyComponent.h"; sourceTree = "SOURCE_ROOT"; }; - 60E972163AE7F32E1AC7BF57 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ElementComparator.h"; path = "../../JuceLibraryCode/modules/juce_core/containers/juce_ElementComparator.h"; sourceTree = "SOURCE_ROOT"; }; - 61E5B74F334DF6387DB68E7C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OutputStream.h"; path = "../../JuceLibraryCode/modules/juce_core/streams/juce_OutputStream.h"; sourceTree = "SOURCE_ROOT"; }; - 620921796E4C408487F2D19D = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_HashMap.h"; path = "../../JuceLibraryCode/modules/juce_core/containers/juce_HashMap.h"; sourceTree = "SOURCE_ROOT"; }; - 621EA7E956C5BA64D95DC755 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MemoryMappedFile.h"; path = "../../JuceLibraryCode/modules/juce_core/files/juce_MemoryMappedFile.h"; sourceTree = "SOURCE_ROOT"; }; - 622800F19C8B24050A92D15B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_BufferingAudioSource.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_basics/sources/juce_BufferingAudioSource.cpp"; sourceTree = "SOURCE_ROOT"; }; - 625D1399D1DC0CE04C2BDF7A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_PerformanceCounter.cpp"; path = "../../JuceLibraryCode/modules/juce_core/time/juce_PerformanceCounter.cpp"; sourceTree = "SOURCE_ROOT"; }; - 62AC3BCA9BBA2BDCEE842496 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TextInputTarget.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/keyboard/juce_TextInputTarget.h"; sourceTree = "SOURCE_ROOT"; }; - 62F3157710E0EB1EEDFC71DA = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_CustomTypeface.cpp"; path = "../../JuceLibraryCode/modules/juce_graphics/fonts/juce_CustomTypeface.cpp"; sourceTree = "SOURCE_ROOT"; }; - 62FAD1304BBC71BEDBB033D0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_SystemStats.h"; path = "../../JuceLibraryCode/modules/juce_core/system/juce_SystemStats.h"; sourceTree = "SOURCE_ROOT"; }; - 62FE07463F39D02D8C6F2CA5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CustomTypeface.h"; path = "../../JuceLibraryCode/modules/juce_graphics/fonts/juce_CustomTypeface.h"; sourceTree = "SOURCE_ROOT"; }; - 637A70321AC8948BA9E033FD = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioPluginFormat.h"; path = "../../JuceLibraryCode/modules/juce_audio_processors/format/juce_AudioPluginFormat.h"; sourceTree = "SOURCE_ROOT"; }; - 63E5D7EEC148FF82E7216095 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioFormatManager.h"; path = "../../JuceLibraryCode/modules/juce_audio_formats/format/juce_AudioFormatManager.h"; sourceTree = "SOURCE_ROOT"; }; - 646046D51C5B2655CC633415 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_LocalisedStrings.cpp"; path = "../../JuceLibraryCode/modules/juce_core/text/juce_LocalisedStrings.cpp"; sourceTree = "SOURCE_ROOT"; }; - 6481FF60536C5296C176F94B = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_BubbleMessageComponent.h"; path = "../../JuceLibraryCode/modules/juce_gui_extra/misc/juce_BubbleMessageComponent.h"; sourceTree = "SOURCE_ROOT"; }; - 65411B7DBE47CE3DF4164F05 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FlacAudioFormat.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_formats/codecs/juce_FlacAudioFormat.cpp"; sourceTree = "SOURCE_ROOT"; }; - 6544288E0768C9FCABE3B081 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ChangeListener.h"; path = "../../JuceLibraryCode/modules/juce_events/broadcasters/juce_ChangeListener.h"; sourceTree = "SOURCE_ROOT"; }; - 659511EADFE62ABB7141CA89 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DeletedAtShutdown.h"; path = "../../JuceLibraryCode/modules/juce_events/messages/juce_DeletedAtShutdown.h"; sourceTree = "SOURCE_ROOT"; }; - 662061336599080D7C0ADB56 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_HighResolutionTimer.h"; path = "../../JuceLibraryCode/modules/juce_core/threads/juce_HighResolutionTimer.h"; sourceTree = "SOURCE_ROOT"; }; - 669C2806A49522217459BB3E = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ReadWriteLock.cpp"; path = "../../JuceLibraryCode/modules/juce_core/threads/juce_ReadWriteLock.cpp"; sourceTree = "SOURCE_ROOT"; }; + 4F5C213B72A375A83FE50979 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_Fonts.cpp"; path = "../../../../modules/juce_graphics/native/juce_linux_Fonts.cpp"; sourceTree = "SOURCE_ROOT"; }; + 4F5D668DCEF2B622FD46073D = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ApplicationCommandID.h"; path = "../../../../modules/juce_gui_basics/commands/juce_ApplicationCommandID.h"; sourceTree = "SOURCE_ROOT"; }; + 4F5DED2313FC69EA518E5679 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_InterprocessConnectionServer.cpp"; path = "../../../../modules/juce_events/interprocess/juce_InterprocessConnectionServer.cpp"; sourceTree = "SOURCE_ROOT"; }; + 4F96BFF5D1D40B81C861F92F = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_opengl.h"; path = "../../../../modules/juce_opengl/juce_opengl.h"; sourceTree = "SOURCE_ROOT"; }; + 4FB8B3386156F5702A20F7D8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_PNGLoader.cpp"; path = "../../../../modules/juce_graphics/image_formats/juce_PNGLoader.cpp"; sourceTree = "SOURCE_ROOT"; }; + 500F7CB9F45B62E46F4BBA57 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MenuBarModel.h"; path = "../../../../modules/juce_gui_basics/menus/juce_MenuBarModel.h"; sourceTree = "SOURCE_ROOT"; }; + 51026A3BE98FD70FD916CF45 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_RelativeCoordinatePositioner.cpp"; path = "../../../../modules/juce_gui_basics/positioning/juce_RelativeCoordinatePositioner.cpp"; sourceTree = "SOURCE_ROOT"; }; + 518E9E553CD9F7D215B75B88 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OpenGL_android.h"; path = "../../../../modules/juce_opengl/native/juce_OpenGL_android.h"; sourceTree = "SOURCE_ROOT"; }; + 519CE739793F0797AF1A7957 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ColourSelector.cpp"; path = "../../../../modules/juce_gui_extra/misc/juce_ColourSelector.cpp"; sourceTree = "SOURCE_ROOT"; }; + 52062790A5E737C8846A23A2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MemoryInputStream.h"; path = "../../../../modules/juce_core/streams/juce_MemoryInputStream.h"; sourceTree = "SOURCE_ROOT"; }; + 531BA61B027758A7978052A4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AppleRemote.h"; path = "../../../../modules/juce_gui_extra/misc/juce_AppleRemote.h"; sourceTree = "SOURCE_ROOT"; }; + 5358DE9C9773654731E6F615 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MidiBuffer.h"; path = "../../../../modules/juce_audio_basics/midi/juce_MidiBuffer.h"; sourceTree = "SOURCE_ROOT"; }; + 5383E87DC6DC1D251C271A50 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ComboBox.h"; path = "../../../../modules/juce_gui_basics/widgets/juce_ComboBox.h"; sourceTree = "SOURCE_ROOT"; }; + 5384C065CDEB3032907ECCAF = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Desktop.h"; path = "../../../../modules/juce_gui_basics/components/juce_Desktop.h"; sourceTree = "SOURCE_ROOT"; }; + 553655CA0122E128BC368AD7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ColourSelector.h"; path = "../../../../modules/juce_gui_extra/misc/juce_ColourSelector.h"; sourceTree = "SOURCE_ROOT"; }; + 55417F6D23E7075E5E27BECB = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_AudioCDBurner.mm"; path = "../../../../modules/juce_audio_devices/native/juce_mac_AudioCDBurner.mm"; sourceTree = "SOURCE_ROOT"; }; + 55A4B5CF98FAC1CC23E49C82 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_ios_Windowing.mm"; path = "../../../../modules/juce_gui_basics/native/juce_ios_Windowing.mm"; sourceTree = "SOURCE_ROOT"; }; + 55CEFA60FA0CBA0E6CB71F5D = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_SparseSet.h"; path = "../../../../modules/juce_core/containers/juce_SparseSet.h"; sourceTree = "SOURCE_ROOT"; }; + 55D04DC4EA2F037CCD5DF9A6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_GIFLoader.cpp"; path = "../../../../modules/juce_graphics/image_formats/juce_GIFLoader.cpp"; sourceTree = "SOURCE_ROOT"; }; + 562E99EE1A4B733B7F751955 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_DragAndDrop.cpp"; path = "../../../../modules/juce_gui_basics/native/juce_win32_DragAndDrop.cpp"; sourceTree = "SOURCE_ROOT"; }; + 56545F3F893C3D8CC9215051 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_mac_CoreMidi.cpp"; path = "../../../../modules/juce_audio_devices/native/juce_mac_CoreMidi.cpp"; sourceTree = "SOURCE_ROOT"; }; + 567D63D778B7A22C5D97F1C5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_BlowFish.h"; path = "../../../../modules/juce_cryptography/encryption/juce_BlowFish.h"; sourceTree = "SOURCE_ROOT"; }; + 56985D9599D0D1D00B42F95B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_LookAndFeel_V1.cpp"; path = "../../../../modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V1.cpp"; sourceTree = "SOURCE_ROOT"; }; + 5703889367170F80CAC76898 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_Files.mm"; path = "../../../../modules/juce_core/native/juce_mac_Files.mm"; sourceTree = "SOURCE_ROOT"; }; + 570C35930202882A634FC029 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ResamplingAudioSource.cpp"; path = "../../../../modules/juce_audio_basics/sources/juce_ResamplingAudioSource.cpp"; sourceTree = "SOURCE_ROOT"; }; + 5710CADD28060D8E949D96D5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_LookAndFeel_V2.cpp"; path = "../../../../modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V2.cpp"; sourceTree = "SOURCE_ROOT"; }; + 5719A93B0F6AFE95FC49B673 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_Midi.cpp"; path = "../../../../modules/juce_audio_devices/native/juce_win32_Midi.cpp"; sourceTree = "SOURCE_ROOT"; }; + 57490A9F97D62E7A312EA90C = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FileInputStream.cpp"; path = "../../../../modules/juce_core/files/juce_FileInputStream.cpp"; sourceTree = "SOURCE_ROOT"; }; + 5774E190A351EDF7B7AAB188 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Sampler.cpp"; path = "../../../../modules/juce_audio_formats/sampler/juce_Sampler.cpp"; sourceTree = "SOURCE_ROOT"; }; + 57A0BF533D7A7B57321A8174 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MouseInputSource.h"; path = "../../../../modules/juce_gui_basics/mouse/juce_MouseInputSource.h"; sourceTree = "SOURCE_ROOT"; }; + 5878CA91071620345AB5B3C4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_UnitTest.cpp"; path = "../../../../modules/juce_core/unit_tests/juce_UnitTest.cpp"; sourceTree = "SOURCE_ROOT"; }; + 595A9929C0E873C30AC9AA87 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_PopupMenu.cpp"; path = "../../../../modules/juce_gui_basics/menus/juce_PopupMenu.cpp"; sourceTree = "SOURCE_ROOT"; }; + 59CAB9E5A0CBBC51342FC065 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AsyncUpdater.cpp"; path = "../../../../modules/juce_events/broadcasters/juce_AsyncUpdater.cpp"; sourceTree = "SOURCE_ROOT"; }; + 5A1777E116DA01B554C90CDA = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FillType.cpp"; path = "../../../../modules/juce_graphics/colour/juce_FillType.cpp"; sourceTree = "SOURCE_ROOT"; }; + 5A5749D0A878955C964DD2C5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MouseCursor.cpp"; path = "../../../../modules/juce_gui_basics/mouse/juce_MouseCursor.cpp"; sourceTree = "SOURCE_ROOT"; }; + 5A854859042F6CD761688B25 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_CharacterFunctions.cpp"; path = "../../../../modules/juce_core/text/juce_CharacterFunctions.cpp"; sourceTree = "SOURCE_ROOT"; }; + 5AAE605D230E253D4EAC195E = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ShapeButton.cpp"; path = "../../../../modules/juce_gui_basics/buttons/juce_ShapeButton.cpp"; sourceTree = "SOURCE_ROOT"; }; + 5B5180DAAB935CB6D1DE9AA6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Draggable3DOrientation.h"; path = "../../../../modules/juce_opengl/geometry/juce_Draggable3DOrientation.h"; sourceTree = "SOURCE_ROOT"; }; + 5BBC57B395B553CE08AC4BD7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Drawable.h"; path = "../../../../modules/juce_gui_basics/drawables/juce_Drawable.h"; sourceTree = "SOURCE_ROOT"; }; + 5BBF8CA223EEE4D9C769E453 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ListenerList.h"; path = "../../../../modules/juce_events/broadcasters/juce_ListenerList.h"; sourceTree = "SOURCE_ROOT"; }; + 5C0E42BCF4ED32E1381E7A23 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_OpenGLTexture.cpp"; path = "../../../../modules/juce_opengl/opengl/juce_OpenGLTexture.cpp"; sourceTree = "SOURCE_ROOT"; }; + 5C58E6217AF57BD2A33ED617 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_JSON.h"; path = "../../../../modules/juce_core/javascript/juce_JSON.h"; sourceTree = "SOURCE_ROOT"; }; + 5C62F423D8469A02E55BF59D = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ChangeBroadcaster.h"; path = "../../../../modules/juce_events/broadcasters/juce_ChangeBroadcaster.h"; sourceTree = "SOURCE_ROOT"; }; + 5C8795B0DE5C729CA18FE89B = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Colour.h"; path = "../../../../modules/juce_graphics/colour/juce_Colour.h"; sourceTree = "SOURCE_ROOT"; }; + 5CDC0F220B1EAE847D38D1DE = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Time.h"; path = "../../../../modules/juce_core/time/juce_Time.h"; sourceTree = "SOURCE_ROOT"; }; + 5D1F3BD1476426752ACB1EB2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Path.h"; path = "../../../../modules/juce_graphics/geometry/juce_Path.h"; sourceTree = "SOURCE_ROOT"; }; + 5D43D909CB26D4A07A62A4F7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Logger.cpp"; path = "../../../../modules/juce_core/logging/juce_Logger.cpp"; sourceTree = "SOURCE_ROOT"; }; + 5D4A62D4893C16D7B17C6A43 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Label.cpp"; path = "../../../../modules/juce_gui_basics/widgets/juce_Label.cpp"; sourceTree = "SOURCE_ROOT"; }; + 5EB144BD6AC4D4DE96ABFCA2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_AudioCDReader.mm"; path = "../../../../modules/juce_audio_devices/native/juce_mac_AudioCDReader.mm"; sourceTree = "SOURCE_ROOT"; }; + 6018A3A37F34AE52B39A14D5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_video.mm"; path = "../../../../modules/juce_video/juce_video.mm"; sourceTree = "SOURCE_ROOT"; }; + 605EA4B27D057BCB9263BCFA = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MemoryMappedFile.h"; path = "../../../../modules/juce_core/files/juce_MemoryMappedFile.h"; sourceTree = "SOURCE_ROOT"; }; + 60D8280577C14A7D3F67563D = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ListBox.h"; path = "../../../../modules/juce_gui_basics/widgets/juce_ListBox.h"; sourceTree = "SOURCE_ROOT"; }; + 610F820C21D914E9794A36EE = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Justification.h"; path = "../../../../modules/juce_graphics/placement/juce_Justification.h"; sourceTree = "SOURCE_ROOT"; }; + 611A0824757D50610BB03562 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CameraDevice.h"; path = "../../../../modules/juce_video/capture/juce_CameraDevice.h"; sourceTree = "SOURCE_ROOT"; }; + 61473E0A6AF9B900406695B8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MouseInactivityDetector.cpp"; path = "../../../../modules/juce_gui_basics/mouse/juce_MouseInactivityDetector.cpp"; sourceTree = "SOURCE_ROOT"; }; + 616493921A733162495E7553 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_UndoableAction.h"; path = "../../../../modules/juce_data_structures/undomanager/juce_UndoableAction.h"; sourceTree = "SOURCE_ROOT"; }; + 61797A8C01DC08E83AFA4540 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_NewLine.h"; path = "../../../../modules/juce_core/text/juce_NewLine.h"; sourceTree = "SOURCE_ROOT"; }; + 618839275E13B9DB660001E4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_posix_NamedPipe.cpp"; path = "../../../../modules/juce_core/native/juce_posix_NamedPipe.cpp"; sourceTree = "SOURCE_ROOT"; }; + 61E1C2246CBD45C5A1F40102 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_android_FileChooser.cpp"; path = "../../../../modules/juce_gui_basics/native/juce_android_FileChooser.cpp"; sourceTree = "SOURCE_ROOT"; }; + 61F0D5937E23A6A9EE8D479C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ReferenceCountedObject.h"; path = "../../../../modules/juce_core/memory/juce_ReferenceCountedObject.h"; sourceTree = "SOURCE_ROOT"; }; + 6238740697CA1F0746776243 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_android_Files.cpp"; path = "../../../../modules/juce_core/native/juce_android_Files.cpp"; sourceTree = "SOURCE_ROOT"; }; + 62B6E8B6269ADEF23D85FA3E = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_audio_formats.h"; path = "../../../../modules/juce_audio_formats/juce_audio_formats.h"; sourceTree = "SOURCE_ROOT"; }; + 62E534D1F0B31CD4A1B572E1 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioIODevice.h"; path = "../../../../modules/juce_audio_devices/audio_io/juce_AudioIODevice.h"; sourceTree = "SOURCE_ROOT"; }; + 62EA5E33A940F30BBB56E293 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_RectanglePlacement.h"; path = "../../../../modules/juce_graphics/placement/juce_RectanglePlacement.h"; sourceTree = "SOURCE_ROOT"; }; + 63B031ABCF8DE5C94889823B = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_events.h"; path = "../../../../modules/juce_events/juce_events.h"; sourceTree = "SOURCE_ROOT"; }; + 63E66F6D161941FE12465C29 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_BufferingAudioFormatReader.cpp"; path = "../../../../modules/juce_audio_formats/format/juce_BufferingAudioFormatReader.cpp"; sourceTree = "SOURCE_ROOT"; }; + 63EE49826BF4CFBD9D546DAC = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ImageEffectFilter.h"; path = "../../../../modules/juce_graphics/effects/juce_ImageEffectFilter.h"; sourceTree = "SOURCE_ROOT"; }; + 6421EA349C5D558114D36717 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_InputSource.h"; path = "../../../../modules/juce_core/streams/juce_InputSource.h"; sourceTree = "SOURCE_ROOT"; }; + 64807B3EFFBDC3348512901E = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_LowLevelGraphicsPostScriptRenderer.h"; path = "../../../../modules/juce_graphics/contexts/juce_LowLevelGraphicsPostScriptRenderer.h"; sourceTree = "SOURCE_ROOT"; }; + 65DF385E92A4A65760DC3BD0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Slider.h"; path = "../../../../modules/juce_gui_basics/widgets/juce_Slider.h"; sourceTree = "SOURCE_ROOT"; }; + 66897EA1FD2CDFB4CED47F8B = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_RSAKey.h"; path = "../../../../modules/juce_cryptography/encryption/juce_RSAKey.h"; sourceTree = "SOURCE_ROOT"; }; + 66B37CB373F19F65553466C3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_mac_CarbonViewWrapperComponent.h"; path = "../../../../modules/juce_gui_extra/native/juce_mac_CarbonViewWrapperComponent.h"; sourceTree = "SOURCE_ROOT"; }; + 66CEE40E51335F661B5C5C66 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ToolbarItemComponent.h"; path = "../../../../modules/juce_gui_basics/widgets/juce_ToolbarItemComponent.h"; sourceTree = "SOURCE_ROOT"; }; 66DE43B56D8670C78DD3998D = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; }; - 66EFBCF1D3E6A5FF27129EC3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CharacterFunctions.h"; path = "../../JuceLibraryCode/modules/juce_core/text/juce_CharacterFunctions.h"; sourceTree = "SOURCE_ROOT"; }; - 671FF5E5EBF6920BAAA79B4E = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FloatVectorOperations.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_basics/buffers/juce_FloatVectorOperations.cpp"; sourceTree = "SOURCE_ROOT"; }; - 6726A33668AC0DB1B5E30C65 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_GZIPDecompressorInputStream.cpp"; path = "../../JuceLibraryCode/modules/juce_core/zip/juce_GZIPDecompressorInputStream.cpp"; sourceTree = "SOURCE_ROOT"; }; - 67319D5DD2BD8D31706DB34A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DrawableShape.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/drawables/juce_DrawableShape.cpp"; sourceTree = "SOURCE_ROOT"; }; - 675AA4F17363E5F5F8B5C307 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_Midi.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_devices/native/juce_linux_Midi.cpp"; sourceTree = "SOURCE_ROOT"; }; - 678267D32EB2BF8C0D1217DC = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_events.h"; path = "../../JuceLibraryCode/modules/juce_events/juce_events.h"; sourceTree = "SOURCE_ROOT"; }; - 688E8CBA135D8B2265E0B809 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CodeTokeniser.h"; path = "../../JuceLibraryCode/modules/juce_gui_extra/code_editor/juce_CodeTokeniser.h"; sourceTree = "SOURCE_ROOT"; }; - 692A2B951D818FED7DB03481 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_CoreAudioFormat.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_formats/codecs/juce_CoreAudioFormat.cpp"; sourceTree = "SOURCE_ROOT"; }; - 69572C0082E358837174B04E = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_IIRFilterAudioSource.h"; path = "../../JuceLibraryCode/modules/juce_audio_basics/sources/juce_IIRFilterAudioSource.h"; sourceTree = "SOURCE_ROOT"; }; - 696CCA96408572659C97FBB1 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MouseListener.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/mouse/juce_MouseListener.cpp"; sourceTree = "SOURCE_ROOT"; }; - 69EBBAC63BDB225AD7B9B19C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CameraDevice.h"; path = "../../JuceLibraryCode/modules/juce_video/capture/juce_CameraDevice.h"; sourceTree = "SOURCE_ROOT"; }; - 6A207487147E4661842F2EEA = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Toolbar.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/widgets/juce_Toolbar.h"; sourceTree = "SOURCE_ROOT"; }; - 6AEA07E5992D813558940710 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ImageConvolutionKernel.cpp"; path = "../../JuceLibraryCode/modules/juce_graphics/images/juce_ImageConvolutionKernel.cpp"; sourceTree = "SOURCE_ROOT"; }; - 6B0CD9C29CB8715C6E916244 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Javascript.h"; path = "../../JuceLibraryCode/modules/juce_core/javascript/juce_Javascript.h"; sourceTree = "SOURCE_ROOT"; }; - 6B3ADCFFE9EF5870BD04FA95 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FileSearchPath.h"; path = "../../JuceLibraryCode/modules/juce_core/files/juce_FileSearchPath.h"; sourceTree = "SOURCE_ROOT"; }; - 6B3FA3604D7E751B8F18E841 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_NamedValueSet.h"; path = "../../JuceLibraryCode/modules/juce_core/containers/juce_NamedValueSet.h"; sourceTree = "SOURCE_ROOT"; }; - 6B8FAA45DB6613DA449E26FD = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_LowLevelGraphicsPostScriptRenderer.cpp"; path = "../../JuceLibraryCode/modules/juce_graphics/contexts/juce_LowLevelGraphicsPostScriptRenderer.cpp"; sourceTree = "SOURCE_ROOT"; }; - 6BC5245D8E2ACD816BA03475 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MixerAudioSource.h"; path = "../../JuceLibraryCode/modules/juce_audio_basics/sources/juce_MixerAudioSource.h"; sourceTree = "SOURCE_ROOT"; }; - 6C140CB15288D8837DF454C4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_StretchableLayoutManager.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/layout/juce_StretchableLayoutManager.cpp"; sourceTree = "SOURCE_ROOT"; }; - 6CAD1F4452A73BAB29EF5D4B = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ImagePreviewComponent.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/filebrowser/juce_ImagePreviewComponent.h"; sourceTree = "SOURCE_ROOT"; }; - 6CC23E6F664F9114395C5DFD = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_mac_CarbonViewWrapperComponent.h"; path = "../../JuceLibraryCode/modules/juce_gui_extra/native/juce_mac_CarbonViewWrapperComponent.h"; sourceTree = "SOURCE_ROOT"; }; - 6CD9A954A84F5088471631BB = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_PluginDirectoryScanner.h"; path = "../../JuceLibraryCode/modules/juce_audio_processors/scanning/juce_PluginDirectoryScanner.h"; sourceTree = "SOURCE_ROOT"; }; - 6D111AFF5B12430B6A225802 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Atomic.h"; path = "../../JuceLibraryCode/modules/juce_core/memory/juce_Atomic.h"; sourceTree = "SOURCE_ROOT"; }; - 6D4CC9AA8FAC940AA974DF33 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TimeSliceThread.h"; path = "../../JuceLibraryCode/modules/juce_core/threads/juce_TimeSliceThread.h"; sourceTree = "SOURCE_ROOT"; }; - 6D688EBEDAD32DBB4706CD39 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_SystemTrayIcon.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_extra/native/juce_linux_SystemTrayIcon.cpp"; sourceTree = "SOURCE_ROOT"; }; - 6D9056359A751B000DB1E9B3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_WildcardFileFilter.h"; path = "../../JuceLibraryCode/modules/juce_core/files/juce_WildcardFileFilter.h"; sourceTree = "SOURCE_ROOT"; }; - 6DA5BE65E7A6BAAE4797856D = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MemoryInputStream.cpp"; path = "../../JuceLibraryCode/modules/juce_core/streams/juce_MemoryInputStream.cpp"; sourceTree = "SOURCE_ROOT"; }; - 6E0B73556F626E9DDB2F2F4C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ApplicationCommandManager.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/commands/juce_ApplicationCommandManager.h"; sourceTree = "SOURCE_ROOT"; }; - 6EAAEC3D37B6CC538F2BAC98 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ApplicationCommandManager.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/commands/juce_ApplicationCommandManager.cpp"; sourceTree = "SOURCE_ROOT"; }; - 6EC413415C211744AB3B7E4C = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_Strings.mm"; path = "../../JuceLibraryCode/modules/juce_core/native/juce_mac_Strings.mm"; sourceTree = "SOURCE_ROOT"; }; - 6EDF4554CA5AA64920F95E5E = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Expression.h"; path = "../../JuceLibraryCode/modules/juce_core/maths/juce_Expression.h"; sourceTree = "SOURCE_ROOT"; }; - 6F195B4646BF53D1918F1764 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MACAddress.h"; path = "../../JuceLibraryCode/modules/juce_core/network/juce_MACAddress.h"; sourceTree = "SOURCE_ROOT"; }; - 6F2E3A5DC0BE1D6917784F47 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_StringPool.cpp"; path = "../../JuceLibraryCode/modules/juce_core/text/juce_StringPool.cpp"; sourceTree = "SOURCE_ROOT"; }; - 6F6DDA3B78AF47374B959263 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MidiOutput.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_devices/midi_io/juce_MidiOutput.cpp"; sourceTree = "SOURCE_ROOT"; }; - 6F7FBB230E206816379F5C83 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioIODevice.h"; path = "../../JuceLibraryCode/modules/juce_audio_devices/audio_io/juce_AudioIODevice.h"; sourceTree = "SOURCE_ROOT"; }; - 6F8DE38E80B72E6FF126483A = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ImageEffectFilter.h"; path = "../../JuceLibraryCode/modules/juce_graphics/effects/juce_ImageEffectFilter.h"; sourceTree = "SOURCE_ROOT"; }; - 6F906DF202EB6B421F9C5813 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_LuaCodeTokeniser.h"; path = "../../JuceLibraryCode/modules/juce_gui_extra/code_editor/juce_LuaCodeTokeniser.h"; sourceTree = "SOURCE_ROOT"; }; - 6FC349656B1BC972D349E67B = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ComponentBuilder.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/layout/juce_ComponentBuilder.h"; sourceTree = "SOURCE_ROOT"; }; - 70284B038C6F9030F7CEDEE7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ApplicationBase.h"; path = "../../JuceLibraryCode/modules/juce_events/messages/juce_ApplicationBase.h"; sourceTree = "SOURCE_ROOT"; }; - 702AE0E6FC3184CD8E83643B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MemoryOutputStream.cpp"; path = "../../JuceLibraryCode/modules/juce_core/streams/juce_MemoryOutputStream.cpp"; sourceTree = "SOURCE_ROOT"; }; - 703DEBC270B90BCBA7BCF714 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_mac_SystemTrayIcon.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_extra/native/juce_mac_SystemTrayIcon.cpp"; sourceTree = "SOURCE_ROOT"; }; - 705C1BA65E7FB620E01B44A5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AffineTransform.cpp"; path = "../../JuceLibraryCode/modules/juce_graphics/geometry/juce_AffineTransform.cpp"; sourceTree = "SOURCE_ROOT"; }; - 7063EC546938B514B6EE8982 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MultiTouchMapper.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/native/juce_MultiTouchMapper.h"; sourceTree = "SOURCE_ROOT"; }; - 70835A4653D8754BB6C7CFE2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FillType.cpp"; path = "../../JuceLibraryCode/modules/juce_graphics/colour/juce_FillType.cpp"; sourceTree = "SOURCE_ROOT"; }; - 70EAFCD75DD6A7C1FEBAB94F = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AppleRemote.h"; path = "../../JuceLibraryCode/modules/juce_gui_extra/misc/juce_AppleRemote.h"; sourceTree = "SOURCE_ROOT"; }; - 70F88726C73A6517C14B5E56 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Button.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/buttons/juce_Button.cpp"; sourceTree = "SOURCE_ROOT"; }; - 7161ABCDB705E0F81662DC71 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ApplicationCommandInfo.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/commands/juce_ApplicationCommandInfo.h"; sourceTree = "SOURCE_ROOT"; }; - 716BA2221FA9658AEC00A563 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_SystemAudioVolume.h"; path = "../../JuceLibraryCode/modules/juce_audio_devices/audio_io/juce_SystemAudioVolume.h"; sourceTree = "SOURCE_ROOT"; }; - 72173AE89EE7526AB956CAE8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DrawableImage.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/drawables/juce_DrawableImage.h"; sourceTree = "SOURCE_ROOT"; }; - 72208D4BA50D37B9764FB56A = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_StringRef.h"; path = "../../JuceLibraryCode/modules/juce_core/text/juce_StringRef.h"; sourceTree = "SOURCE_ROOT"; }; - 723111ABC4D02840963C6FC2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ThreadPool.h"; path = "../../JuceLibraryCode/modules/juce_core/threads/juce_ThreadPool.h"; sourceTree = "SOURCE_ROOT"; }; - 729AF566D1EB32D59B8776F7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ScopedReadLock.h"; path = "../../JuceLibraryCode/modules/juce_core/threads/juce_ScopedReadLock.h"; sourceTree = "SOURCE_ROOT"; }; - 72ACB726645A64B055B59277 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Decibels.h"; path = "../../JuceLibraryCode/modules/juce_audio_basics/effects/juce_Decibels.h"; sourceTree = "SOURCE_ROOT"; }; - 72B459EF3E90129FBD1A78EA = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_BufferingAudioFormatReader.h"; path = "../../JuceLibraryCode/modules/juce_audio_formats/format/juce_BufferingAudioFormatReader.h"; sourceTree = "SOURCE_ROOT"; }; - 72CF68A2C3240BFA2EBF22AB = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CharPointer_UTF16.h"; path = "../../JuceLibraryCode/modules/juce_core/text/juce_CharPointer_UTF16.h"; sourceTree = "SOURCE_ROOT"; }; - 730F77EEB7313A110A0B5E5F = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioIODeviceType.h"; path = "../../JuceLibraryCode/modules/juce_audio_devices/audio_io/juce_AudioIODeviceType.h"; sourceTree = "SOURCE_ROOT"; }; - 73237A2CB197259364D09A76 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_PreferencesPanel.h"; path = "../../JuceLibraryCode/modules/juce_gui_extra/misc/juce_PreferencesPanel.h"; sourceTree = "SOURCE_ROOT"; }; + 66E854431C2BBDEE56EA43C8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_VST3PluginFormat.h"; path = "../../../../modules/juce_audio_processors/format_types/juce_VST3PluginFormat.h"; sourceTree = "SOURCE_ROOT"; }; + 673759E656DBA5A9377433E5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_GenericAudioProcessorEditor.cpp"; path = "../../../../modules/juce_audio_processors/processors/juce_GenericAudioProcessorEditor.cpp"; sourceTree = "SOURCE_ROOT"; }; + 674E13DA209E762DF15E9E29 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ResizableCornerComponent.h"; path = "../../../../modules/juce_gui_basics/layout/juce_ResizableCornerComponent.h"; sourceTree = "SOURCE_ROOT"; }; + 67771057800F9416E9777625 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ImagePreviewComponent.h"; path = "../../../../modules/juce_gui_basics/filebrowser/juce_ImagePreviewComponent.h"; sourceTree = "SOURCE_ROOT"; }; + 67895BDE8FA4B2A01E3B8B12 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TargetPlatform.h"; path = "../../../../modules/juce_core/system/juce_TargetPlatform.h"; sourceTree = "SOURCE_ROOT"; }; + 6804336FE1AB499087ACE437 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Initialisation.h"; path = "../../../../modules/juce_events/messages/juce_Initialisation.h"; sourceTree = "SOURCE_ROOT"; }; + 68097881EEDDE0FD03100CC5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_HeapBlock.h"; path = "../../../../modules/juce_core/memory/juce_HeapBlock.h"; sourceTree = "SOURCE_ROOT"; }; + 684E11B1CE018B2C46938D80 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MultiDocumentPanel.cpp"; path = "../../../../modules/juce_gui_basics/layout/juce_MultiDocumentPanel.cpp"; sourceTree = "SOURCE_ROOT"; }; + 68743DE3AA833D6F02F754D7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_TableListBox.cpp"; path = "../../../../modules/juce_gui_basics/widgets/juce_TableListBox.cpp"; sourceTree = "SOURCE_ROOT"; }; + 68FAA921E5D8CFAF9CC07C2F = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_CodeEditorComponent.cpp"; path = "../../../../modules/juce_gui_extra/code_editor/juce_CodeEditorComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; + 6911E01E967839199E4C9822 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Image.h"; path = "../../../../modules/juce_graphics/images/juce_Image.h"; sourceTree = "SOURCE_ROOT"; }; + 693B6DC20214C1ED9C1E89F7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_video.h"; path = "../../../../modules/juce_video/juce_video.h"; sourceTree = "SOURCE_ROOT"; }; + 69449AB58A9C0AB552F754F4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_LookAndFeel_V3.h"; path = "../../../../modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V3.h"; sourceTree = "SOURCE_ROOT"; }; + 69A2DA87D304FD486A872C1B = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ScopedLock.h"; path = "../../../../modules/juce_core/threads/juce_ScopedLock.h"; sourceTree = "SOURCE_ROOT"; }; + 69C36A56AE1A2E8CF64FE388 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CPlusPlusCodeTokeniser.h"; path = "../../../../modules/juce_gui_extra/code_editor/juce_CPlusPlusCodeTokeniser.h"; sourceTree = "SOURCE_ROOT"; }; + 6A1D79062B92685A87BEE5F6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MidiKeyboardState.h"; path = "../../../../modules/juce_audio_basics/midi/juce_MidiKeyboardState.h"; sourceTree = "SOURCE_ROOT"; }; + 6A22C06C6FE2B6B494B4878D = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MACAddress.h"; path = "../../../../modules/juce_core/network/juce_MACAddress.h"; sourceTree = "SOURCE_ROOT"; }; + 6A8AC5E55EE51EE0476D852F = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ComponentPeer.h"; path = "../../../../modules/juce_gui_basics/windows/juce_ComponentPeer.h"; sourceTree = "SOURCE_ROOT"; }; + 6B103C0FB5E6E3618ECD3B48 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_PropertyPanel.cpp"; path = "../../../../modules/juce_gui_basics/properties/juce_PropertyPanel.cpp"; sourceTree = "SOURCE_ROOT"; }; + 6B5C2F14A2268F371F1350B5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OpenGLPixelFormat.h"; path = "../../../../modules/juce_opengl/opengl/juce_OpenGLPixelFormat.h"; sourceTree = "SOURCE_ROOT"; }; + 6BE6A3A14057591A3B4EF2C4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_TextButton.cpp"; path = "../../../../modules/juce_gui_basics/buttons/juce_TextButton.cpp"; sourceTree = "SOURCE_ROOT"; }; + 6C03031AAE5A7C3372D4F1CF = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_GZIPCompressorOutputStream.h"; path = "../../../../modules/juce_core/zip/juce_GZIPCompressorOutputStream.h"; sourceTree = "SOURCE_ROOT"; }; + 6C502DF33FB5C14B8A67B25D = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FileInputSource.cpp"; path = "../../../../modules/juce_core/streams/juce_FileInputSource.cpp"; sourceTree = "SOURCE_ROOT"; }; + 6D0D0EC5B978695152A0B84F = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioSampleBuffer.h"; path = "../../../../modules/juce_audio_basics/buffers/juce_AudioSampleBuffer.h"; sourceTree = "SOURCE_ROOT"; }; + 6D3F3D0139FAC58B2BAA6047 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ConnectedChildProcess.cpp"; path = "../../../../modules/juce_events/interprocess/juce_ConnectedChildProcess.cpp"; sourceTree = "SOURCE_ROOT"; }; + 6D5EE68347208091600E94A2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ResizableEdgeComponent.h"; path = "../../../../modules/juce_gui_basics/layout/juce_ResizableEdgeComponent.h"; sourceTree = "SOURCE_ROOT"; }; + 6DE6751E6A4F0DDE9C7F24B3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TreeView.h"; path = "../../../../modules/juce_gui_basics/widgets/juce_TreeView.h"; sourceTree = "SOURCE_ROOT"; }; + 6E0713769EA84EE0471D9811 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Font.h"; path = "../../../../modules/juce_graphics/fonts/juce_Font.h"; sourceTree = "SOURCE_ROOT"; }; + 6E6672E4055AC4F6D8688310 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioSubsectionReader.h"; path = "../../../../modules/juce_audio_formats/format/juce_AudioSubsectionReader.h"; sourceTree = "SOURCE_ROOT"; }; + 6E841DAA09FE06910D94447D = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_audio_processors.h"; path = "../../../../modules/juce_audio_processors/juce_audio_processors.h"; sourceTree = "SOURCE_ROOT"; }; + 6E9C1F4D69A9C99433DC67C6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DrawableShape.h"; path = "../../../../modules/juce_gui_basics/drawables/juce_DrawableShape.h"; sourceTree = "SOURCE_ROOT"; }; + 6EEECDA2EB328FB597208954 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AbstractFifo.cpp"; path = "../../../../modules/juce_core/containers/juce_AbstractFifo.cpp"; sourceTree = "SOURCE_ROOT"; }; + 6EFC227515CACDE0F8664EC2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_IIRFilterAudioSource.cpp"; path = "../../../../modules/juce_audio_basics/sources/juce_IIRFilterAudioSource.cpp"; sourceTree = "SOURCE_ROOT"; }; + 6F6F888BFFA4BB40DD71285E = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ThreadLocalValue.h"; path = "../../../../modules/juce_core/threads/juce_ThreadLocalValue.h"; sourceTree = "SOURCE_ROOT"; }; + 7022B01ECEE7000DE6008C0A = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_graphics.h"; path = "../../../../modules/juce_graphics/juce_graphics.h"; sourceTree = "SOURCE_ROOT"; }; + 70B18C93C5696330A877B330 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FileSearchPath.cpp"; path = "../../../../modules/juce_core/files/juce_FileSearchPath.cpp"; sourceTree = "SOURCE_ROOT"; }; + 7141B07690C1A022A2BFFBBB = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CompilerSupport.h"; path = "../../../../modules/juce_core/system/juce_CompilerSupport.h"; sourceTree = "SOURCE_ROOT"; }; + 71881F8A6973AACD78ABA719 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_QuickTimeMovieComponent.cpp"; path = "../../../../modules/juce_video/native/juce_win32_QuickTimeMovieComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; + 71B0F66C20CF48F49B3152AF = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_mac_SystemTrayIcon.cpp"; path = "../../../../modules/juce_gui_extra/native/juce_mac_SystemTrayIcon.cpp"; sourceTree = "SOURCE_ROOT"; }; + 71DF518DE7A248B97C8E1C2E = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioSubsectionReader.cpp"; path = "../../../../modules/juce_audio_formats/format/juce_AudioSubsectionReader.cpp"; sourceTree = "SOURCE_ROOT"; }; + 72696E2F6E8EB43A8E604390 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_SelectedItemSet.h"; path = "../../../../modules/juce_gui_basics/mouse/juce_SelectedItemSet.h"; sourceTree = "SOURCE_ROOT"; }; 732EEC584A4CE3ED07C5BEFB = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMIDI.framework; path = System/Library/Frameworks/CoreMIDI.framework; sourceTree = SDKROOT; }; - 7349C82FB18B8E194B854DB8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_Network.cpp"; path = "../../JuceLibraryCode/modules/juce_core/native/juce_linux_Network.cpp"; sourceTree = "SOURCE_ROOT"; }; - 738D2ECFD31190494B40BE78 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Socket.h"; path = "../../JuceLibraryCode/modules/juce_core/network/juce_Socket.h"; sourceTree = "SOURCE_ROOT"; }; - 73CD9E5A889A13890247BA55 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ScopedXLock.h"; path = "../../JuceLibraryCode/modules/juce_events/native/juce_ScopedXLock.h"; sourceTree = "SOURCE_ROOT"; }; - 740CEAD6F3EC74AEE5D29F3A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_ASIO.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_devices/native/juce_win32_ASIO.cpp"; sourceTree = "SOURCE_ROOT"; }; - 747EC1715A027D17F0082830 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_PathStrokeType.cpp"; path = "../../JuceLibraryCode/modules/juce_graphics/geometry/juce_PathStrokeType.cpp"; sourceTree = "SOURCE_ROOT"; }; - 74E4F42C4ECF1C1D2C7873AF = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_module_info"; path = "../../JuceLibraryCode/modules/juce_events/juce_module_info"; sourceTree = "SOURCE_ROOT"; }; - 752E683005CC56CA4A552261 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ScopedWriteLock.h"; path = "../../JuceLibraryCode/modules/juce_core/threads/juce_ScopedWriteLock.h"; sourceTree = "SOURCE_ROOT"; }; - 75CC726CB13BFCCF00F99DF3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FillType.h"; path = "../../JuceLibraryCode/modules/juce_graphics/colour/juce_FillType.h"; sourceTree = "SOURCE_ROOT"; }; - 761FA7CC71FAAE37676425AD = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Label.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/widgets/juce_Label.cpp"; sourceTree = "SOURCE_ROOT"; }; - 7632DB6A2EA67505B1A5B4A8 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_module_info"; path = "../../JuceLibraryCode/modules/juce_opengl/juce_module_info"; sourceTree = "SOURCE_ROOT"; }; - 76CD66265F349446088FD5E3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_SliderPropertyComponent.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/properties/juce_SliderPropertyComponent.h"; sourceTree = "SOURCE_ROOT"; }; - 7760FF1BA004BE4D9CDF1AFA = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ApplicationProperties.cpp"; path = "../../JuceLibraryCode/modules/juce_data_structures/app_properties/juce_ApplicationProperties.cpp"; sourceTree = "SOURCE_ROOT"; }; - 776774969BC27F7269A3B520 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_SHA256.cpp"; path = "../../JuceLibraryCode/modules/juce_cryptography/hashing/juce_SHA256.cpp"; sourceTree = "SOURCE_ROOT"; }; - 778A19A79B821CCE6BD27E12 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DrawableButton.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/buttons/juce_DrawableButton.cpp"; sourceTree = "SOURCE_ROOT"; }; - 77B9644758BED4987CEE2FB9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_HyperlinkButton.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/buttons/juce_HyperlinkButton.h"; sourceTree = "SOURCE_ROOT"; }; - 77EF2BBCC5853A84BB8BB561 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MidiDataConcatenator.h"; path = "../../JuceLibraryCode/modules/juce_audio_devices/native/juce_MidiDataConcatenator.h"; sourceTree = "SOURCE_ROOT"; }; - 77F53EB4FD58030721224396 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_UIViewComponent.h"; path = "../../JuceLibraryCode/modules/juce_gui_extra/embedding/juce_UIViewComponent.h"; sourceTree = "SOURCE_ROOT"; }; - 77FD526A14FAB45DF30CDA71 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_android_Files.cpp"; path = "../../JuceLibraryCode/modules/juce_core/native/juce_android_Files.cpp"; sourceTree = "SOURCE_ROOT"; }; - 78CE05F96C7E21DEE8D6A845 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_AudioUnitPluginFormat.mm"; path = "../../JuceLibraryCode/modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.mm"; sourceTree = "SOURCE_ROOT"; }; - 78D9F913D201ABD1349F023E = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_LiveConstantEditor.h"; path = "../../JuceLibraryCode/modules/juce_gui_extra/misc/juce_LiveConstantEditor.h"; sourceTree = "SOURCE_ROOT"; }; - 78E95B5FD8BFF8B51994F2D8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_WASAPI.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_devices/native/juce_win32_WASAPI.cpp"; sourceTree = "SOURCE_ROOT"; }; - 78FE5E020A7D6EB993701276 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_LADSPAPluginFormat.h"; path = "../../JuceLibraryCode/modules/juce_audio_processors/format_types/juce_LADSPAPluginFormat.h"; sourceTree = "SOURCE_ROOT"; }; - 795EA6840D307165BC0BBCD4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OpenGLPixelFormat.h"; path = "../../JuceLibraryCode/modules/juce_opengl/opengl/juce_OpenGLPixelFormat.h"; sourceTree = "SOURCE_ROOT"; }; - 7A2245EA90D757EED0EBE63A = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MenuBarComponent.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/menus/juce_MenuBarComponent.h"; sourceTree = "SOURCE_ROOT"; }; - 7A6DB25F73AC07158A74D006 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_LowLevelGraphicsContext.h"; path = "../../JuceLibraryCode/modules/juce_graphics/contexts/juce_LowLevelGraphicsContext.h"; sourceTree = "SOURCE_ROOT"; }; - 7AB7CD2C0DB9B58AAA1A4B2F = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ColourSelector.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_extra/misc/juce_ColourSelector.cpp"; sourceTree = "SOURCE_ROOT"; }; - 7B00E4D3D066DFB30406ABCC = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FileListComponent.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/filebrowser/juce_FileListComponent.h"; sourceTree = "SOURCE_ROOT"; }; - 7B849D43BE20E398A8B52F52 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_NSViewComponent.h"; path = "../../JuceLibraryCode/modules/juce_gui_extra/embedding/juce_NSViewComponent.h"; sourceTree = "SOURCE_ROOT"; }; - 7BD61B782DE61C73D8475002 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_LowLevelGraphicsPostScriptRenderer.h"; path = "../../JuceLibraryCode/modules/juce_graphics/contexts/juce_LowLevelGraphicsPostScriptRenderer.h"; sourceTree = "SOURCE_ROOT"; }; - 7C36F478BC80A41544C634C5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ConnectedChildProcess.h"; path = "../../JuceLibraryCode/modules/juce_events/interprocess/juce_ConnectedChildProcess.h"; sourceTree = "SOURCE_ROOT"; }; - 7C4D9BAF8818E5750C110343 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FilePreviewComponent.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/filebrowser/juce_FilePreviewComponent.h"; sourceTree = "SOURCE_ROOT"; }; - 7C91E9B82C9B593E082DD74F = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_BooleanPropertyComponent.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/properties/juce_BooleanPropertyComponent.h"; sourceTree = "SOURCE_ROOT"; }; - 7CE1591D180C957070AE60F6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_SplashScreen.h"; path = "../../JuceLibraryCode/modules/juce_gui_extra/misc/juce_SplashScreen.h"; sourceTree = "SOURCE_ROOT"; }; - 7D81388899A711A7C93107EF = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Desktop.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/components/juce_Desktop.h"; sourceTree = "SOURCE_ROOT"; }; - 7DED484895527D5C0BB6662F = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_CallOutBox.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/windows/juce_CallOutBox.cpp"; sourceTree = "SOURCE_ROOT"; }; - 7E62DD6F1A2FF13D5095D218 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_SystemStats.mm"; path = "../../JuceLibraryCode/modules/juce_core/native/juce_mac_SystemStats.mm"; sourceTree = "SOURCE_ROOT"; }; - 7EA85C6C405022532A6F2F3A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_RecentlyOpenedFilesList.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_extra/misc/juce_RecentlyOpenedFilesList.cpp"; sourceTree = "SOURCE_ROOT"; }; - 7EA9B430B1998ECBEF70D2E2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Identifier.cpp"; path = "../../JuceLibraryCode/modules/juce_core/text/juce_Identifier.cpp"; sourceTree = "SOURCE_ROOT"; }; - 7EDB44744DC44FB9DDECF9FF = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_OpenGLFrameBuffer.cpp"; path = "../../JuceLibraryCode/modules/juce_opengl/opengl/juce_OpenGLFrameBuffer.cpp"; sourceTree = "SOURCE_ROOT"; }; - 7F5AF8186ABA8353EC1D4A24 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ListenerList.h"; path = "../../JuceLibraryCode/modules/juce_events/broadcasters/juce_ListenerList.h"; sourceTree = "SOURCE_ROOT"; }; - 7F6B22405102D9B38BE6E113 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_RelativeRectangle.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/positioning/juce_RelativeRectangle.cpp"; sourceTree = "SOURCE_ROOT"; }; - 7F7C09BE9B70312CE6783717 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_Windowing.mm"; path = "../../JuceLibraryCode/modules/juce_gui_basics/native/juce_mac_Windowing.mm"; sourceTree = "SOURCE_ROOT"; }; - 7FB3628856C8E532EB8421CA = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_core.mm"; path = "../../JuceLibraryCode/modules/juce_core/juce_core.mm"; sourceTree = "SOURCE_ROOT"; }; - 7FCD0EF5D09B904A6D437BC9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_BubbleComponent.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/misc/juce_BubbleComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; - 80C52BD7C8AD60FC1584EDDD = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_BigInteger.h"; path = "../../JuceLibraryCode/modules/juce_core/maths/juce_BigInteger.h"; sourceTree = "SOURCE_ROOT"; }; - 81CF3953D1337AD42C542403 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_module_info"; path = "../../JuceLibraryCode/modules/juce_cryptography/juce_module_info"; sourceTree = "SOURCE_ROOT"; }; - 81EE8DCD7B8BB528C9989B47 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MarkerList.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/positioning/juce_MarkerList.h"; sourceTree = "SOURCE_ROOT"; }; - 82D0CF4B57D906FAEBC60666 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_Fonts.cpp"; path = "../../JuceLibraryCode/modules/juce_graphics/native/juce_win32_Fonts.cpp"; sourceTree = "SOURCE_ROOT"; }; - 82E3A19B4D8BA65CE7310D09 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ApplicationCommandInfo.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/commands/juce_ApplicationCommandInfo.cpp"; sourceTree = "SOURCE_ROOT"; }; - 836E25356E7C3A2534792936 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_SystemTrayIconComponent.h"; path = "../../JuceLibraryCode/modules/juce_gui_extra/misc/juce_SystemTrayIconComponent.h"; sourceTree = "SOURCE_ROOT"; }; - 83A10FEA76D527B4E88AD0EF = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_LagrangeInterpolator.h"; path = "../../JuceLibraryCode/modules/juce_audio_basics/effects/juce_LagrangeInterpolator.h"; sourceTree = "SOURCE_ROOT"; }; - 83AF4F43D85DCDBF318BEC8B = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Colour.h"; path = "../../JuceLibraryCode/modules/juce_graphics/colour/juce_Colour.h"; sourceTree = "SOURCE_ROOT"; }; - 83B04EFF25DA63BE3DA37B11 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ComponentAnimator.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/layout/juce_ComponentAnimator.cpp"; sourceTree = "SOURCE_ROOT"; }; - 8438D37046A9F805AAC7401B = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_android_JNIHelpers.h"; path = "../../JuceLibraryCode/modules/juce_core/native/juce_android_JNIHelpers.h"; sourceTree = "SOURCE_ROOT"; }; - 844583A4973FA34A3FF6DCB5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Initialisation.h"; path = "../../JuceLibraryCode/modules/juce_events/messages/juce_Initialisation.h"; sourceTree = "SOURCE_ROOT"; }; - 849A271BDBC9A7AB9514B8CD = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_VSTMidiEventList.h"; path = "../../JuceLibraryCode/modules/juce_audio_processors/format_types/juce_VSTMidiEventList.h"; sourceTree = "SOURCE_ROOT"; }; + 73CA6BCA313B0239842F298C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ValueTree.h"; path = "../../../../modules/juce_data_structures/values/juce_ValueTree.h"; sourceTree = "SOURCE_ROOT"; }; + 73FF82BCB568578396E88C92 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_WASAPI.cpp"; path = "../../../../modules/juce_audio_devices/native/juce_win32_WASAPI.cpp"; sourceTree = "SOURCE_ROOT"; }; + 74302B51B991EA1775AEFC67 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_core.h"; path = "../../../../modules/juce_core/juce_core.h"; sourceTree = "SOURCE_ROOT"; }; + 749854CD2D13BBBA500F353F = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_PropertySet.cpp"; path = "../../../../modules/juce_core/containers/juce_PropertySet.cpp"; sourceTree = "SOURCE_ROOT"; }; + 74AB51B6E97964B27B1CD019 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Toolbar.cpp"; path = "../../../../modules/juce_gui_basics/widgets/juce_Toolbar.cpp"; sourceTree = "SOURCE_ROOT"; }; + 74B477DE4CFC95E20DBB0D91 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_SystemClipboard.h"; path = "../../../../modules/juce_gui_basics/keyboard/juce_SystemClipboard.h"; sourceTree = "SOURCE_ROOT"; }; + 75D038033B2083D5EFE620A8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Vector3D.h"; path = "../../../../modules/juce_opengl/geometry/juce_Vector3D.h"; sourceTree = "SOURCE_ROOT"; }; + 7627F01C1E5383207D2C0BFB = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_MessageManager.mm"; path = "../../../../modules/juce_events/native/juce_mac_MessageManager.mm"; sourceTree = "SOURCE_ROOT"; }; + 7639526FBF7A4F41961483ED = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_IPAddress.h"; path = "../../../../modules/juce_core/network/juce_IPAddress.h"; sourceTree = "SOURCE_ROOT"; }; + 766EE2CCD4E86729C6CE8112 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DocumentWindow.h"; path = "../../../../modules/juce_gui_basics/windows/juce_DocumentWindow.h"; sourceTree = "SOURCE_ROOT"; }; + 768754211363FED3D2188C9D = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_module_info"; path = "../../../../modules/juce_audio_formats/juce_module_info"; sourceTree = "SOURCE_ROOT"; }; + 76F1A69F15F53D17C632A644 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_RelativeCoordinate.cpp"; path = "../../../../modules/juce_gui_basics/positioning/juce_RelativeCoordinate.cpp"; sourceTree = "SOURCE_ROOT"; }; + 7743414F79908801328D9F03 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_TimeSliceThread.cpp"; path = "../../../../modules/juce_core/threads/juce_TimeSliceThread.cpp"; sourceTree = "SOURCE_ROOT"; }; + 77AE8FD7436387126D3BBBAC = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_KeyMappingEditorComponent.cpp"; path = "../../../../modules/juce_gui_extra/misc/juce_KeyMappingEditorComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; + 782E3434FEA190A986EAC816 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ArrowButton.cpp"; path = "../../../../modules/juce_gui_basics/buttons/juce_ArrowButton.cpp"; sourceTree = "SOURCE_ROOT"; }; + 791ADFB0FFAEE65058B6FC8A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ApplicationCommandInfo.cpp"; path = "../../../../modules/juce_gui_basics/commands/juce_ApplicationCommandInfo.cpp"; sourceTree = "SOURCE_ROOT"; }; + 799472026100D7BAE015F6A6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AnimatedPositionBehaviours.h"; path = "../../../../modules/juce_gui_basics/layout/juce_AnimatedPositionBehaviours.h"; sourceTree = "SOURCE_ROOT"; }; + 7A029D97E723C7F1BDDCAA49 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MultiTimer.cpp"; path = "../../../../modules/juce_events/timers/juce_MultiTimer.cpp"; sourceTree = "SOURCE_ROOT"; }; + 7A46778023CF61B3F417F9AC = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioDataConverters.h"; path = "../../../../modules/juce_audio_basics/buffers/juce_AudioDataConverters.h"; sourceTree = "SOURCE_ROOT"; }; + 7A6E1CBA343C07AC187A3EE8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ComponentAnimator.h"; path = "../../../../modules/juce_gui_basics/layout/juce_ComponentAnimator.h"; sourceTree = "SOURCE_ROOT"; }; + 7AC4D7A22EE9E1F4FBD407C7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MidiDataConcatenator.h"; path = "../../../../modules/juce_audio_devices/native/juce_MidiDataConcatenator.h"; sourceTree = "SOURCE_ROOT"; }; + 7AC8C094442A603DE6257BB1 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CharPointer_UTF8.h"; path = "../../../../modules/juce_core/text/juce_CharPointer_UTF8.h"; sourceTree = "SOURCE_ROOT"; }; + 7BA2EA5655704E5358ABAA9D = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_RectanglePlacement.cpp"; path = "../../../../modules/juce_graphics/placement/juce_RectanglePlacement.cpp"; sourceTree = "SOURCE_ROOT"; }; + 7BC8F7015F35BAFF4AEDA0E6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Toolbar.h"; path = "../../../../modules/juce_gui_basics/widgets/juce_Toolbar.h"; sourceTree = "SOURCE_ROOT"; }; + 7C7B6D8D155687966F681F5B = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_module_info"; path = "../../../../modules/juce_events/juce_module_info"; sourceTree = "SOURCE_ROOT"; }; + 7D8D285B8414388FDB083AFF = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ProgressBar.h"; path = "../../../../modules/juce_gui_basics/widgets/juce_ProgressBar.h"; sourceTree = "SOURCE_ROOT"; }; + 7DCF49E37B27971A7E597555 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_Registry.cpp"; path = "../../../../modules/juce_core/native/juce_win32_Registry.cpp"; sourceTree = "SOURCE_ROOT"; }; + 7E0DD06926DAC8EE93BD4F08 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FileInputSource.h"; path = "../../../../modules/juce_core/streams/juce_FileInputSource.h"; sourceTree = "SOURCE_ROOT"; }; + 7EB8C7E000F0DDAAB4F47802 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_NSViewComponentPeer.mm"; path = "../../../../modules/juce_gui_basics/native/juce_mac_NSViewComponentPeer.mm"; sourceTree = "SOURCE_ROOT"; }; + 7F0614F4F47EB171B8476BDC = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ComponentBoundsConstrainer.cpp"; path = "../../../../modules/juce_gui_basics/layout/juce_ComponentBoundsConstrainer.cpp"; sourceTree = "SOURCE_ROOT"; }; + 7F162E198ECF41AA895DB94B = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AiffAudioFormat.h"; path = "../../../../modules/juce_audio_formats/codecs/juce_AiffAudioFormat.h"; sourceTree = "SOURCE_ROOT"; }; + 7F171BE6BFAA1E3E2A9BED61 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ComponentMovementWatcher.h"; path = "../../../../modules/juce_gui_basics/layout/juce_ComponentMovementWatcher.h"; sourceTree = "SOURCE_ROOT"; }; + 7F2BBAF79EB32BB9904A76FF = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Timer.h"; path = "../../../../modules/juce_events/timers/juce_Timer.h"; sourceTree = "SOURCE_ROOT"; }; + 7FC89C1EEB42DE3C9628591C = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_SliderPropertyComponent.cpp"; path = "../../../../modules/juce_gui_basics/properties/juce_SliderPropertyComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; + 8001506F637B2516AAC5C0D8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ModalComponentManager.cpp"; path = "../../../../modules/juce_gui_basics/components/juce_ModalComponentManager.cpp"; sourceTree = "SOURCE_ROOT"; }; + 803480FD5E7181E0D64FFC53 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OutputStream.h"; path = "../../../../modules/juce_core/streams/juce_OutputStream.h"; sourceTree = "SOURCE_ROOT"; }; + 805EB95DB4B8045064CE9ED3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_android_WebBrowserComponent.cpp"; path = "../../../../modules/juce_gui_extra/native/juce_android_WebBrowserComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; + 805F27CEEC53F4E659884D7A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_ASIO.cpp"; path = "../../../../modules/juce_audio_devices/native/juce_win32_ASIO.cpp"; sourceTree = "SOURCE_ROOT"; }; + 807E7971CB75C806D7DB5DF2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_RelativeRectangle.h"; path = "../../../../modules/juce_gui_basics/positioning/juce_RelativeRectangle.h"; sourceTree = "SOURCE_ROOT"; }; + 8102EBF90140E78193692AEB = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DragAndDropContainer.h"; path = "../../../../modules/juce_gui_basics/mouse/juce_DragAndDropContainer.h"; sourceTree = "SOURCE_ROOT"; }; + 814E0D982BC2A18B9BAF3E38 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioSourcePlayer.cpp"; path = "../../../../modules/juce_audio_devices/sources/juce_AudioSourcePlayer.cpp"; sourceTree = "SOURCE_ROOT"; }; + 823BBAE97A02475F25E54F9D = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_BasicNativeHeaders.h"; path = "../../../../modules/juce_core/native/juce_BasicNativeHeaders.h"; sourceTree = "SOURCE_ROOT"; }; + 82A390DEE5A3B2EFDF7A65E6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ResizableCornerComponent.cpp"; path = "../../../../modules/juce_gui_basics/layout/juce_ResizableCornerComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; + 830ADB6740EF70992E71895F = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FilePreviewComponent.h"; path = "../../../../modules/juce_gui_basics/filebrowser/juce_FilePreviewComponent.h"; sourceTree = "SOURCE_ROOT"; }; + 8314FE695F91DA2FAB51920E = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AlertWindow.cpp"; path = "../../../../modules/juce_gui_basics/windows/juce_AlertWindow.cpp"; sourceTree = "SOURCE_ROOT"; }; + 83325A69170997E33D73770A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioPluginFormatManager.cpp"; path = "../../../../modules/juce_audio_processors/format/juce_AudioPluginFormatManager.cpp"; sourceTree = "SOURCE_ROOT"; }; + 833CD270A139A70FF4E60D35 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MouseEvent.cpp"; path = "../../../../modules/juce_gui_basics/mouse/juce_MouseEvent.cpp"; sourceTree = "SOURCE_ROOT"; }; + 83BA5BED925F6F827DF98CA8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_PositionableAudioSource.h"; path = "../../../../modules/juce_audio_basics/sources/juce_PositionableAudioSource.h"; sourceTree = "SOURCE_ROOT"; }; + 842433A42308565BF3C1542A = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TextEditor.h"; path = "../../../../modules/juce_gui_basics/widgets/juce_TextEditor.h"; sourceTree = "SOURCE_ROOT"; }; + 843BE36A2285F73A3FBB5660 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_SystemStats.cpp"; path = "../../../../modules/juce_core/native/juce_win32_SystemStats.cpp"; sourceTree = "SOURCE_ROOT"; }; + 84494501A6148DAFE162650B = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_posix_SharedCode.h"; path = "../../../../modules/juce_core/native/juce_posix_SharedCode.h"; sourceTree = "SOURCE_ROOT"; }; + 84ABA9491A70313AD6BF6F9A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MACAddress.cpp"; path = "../../../../modules/juce_core/network/juce_MACAddress.cpp"; sourceTree = "SOURCE_ROOT"; }; + 853D2D1ADD05C320052DD5FC = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioFormatReaderSource.cpp"; path = "../../../../modules/juce_audio_formats/format/juce_AudioFormatReaderSource.cpp"; sourceTree = "SOURCE_ROOT"; }; 859E13C66F2193112084D1B9 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Accelerate.framework; path = System/Library/Frameworks/Accelerate.framework; sourceTree = SDKROOT; }; - 85A0EF72EC932C8A327F8139 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Viewport.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/layout/juce_Viewport.cpp"; sourceTree = "SOURCE_ROOT"; }; - 86318DF533A7BB50B88789BC = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_PropertyComponent.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/properties/juce_PropertyComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; - 8669589118EF641C93336C4B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_OpenGLHelpers.cpp"; path = "../../JuceLibraryCode/modules/juce_opengl/opengl/juce_OpenGLHelpers.cpp"; sourceTree = "SOURCE_ROOT"; }; - 8755EB7CFA4EC3C0AEBF8E26 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_WeakReference.h"; path = "../../JuceLibraryCode/modules/juce_core/memory/juce_WeakReference.h"; sourceTree = "SOURCE_ROOT"; }; - 88046B20D38387F2D2650F8D = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ChangeBroadcaster.cpp"; path = "../../JuceLibraryCode/modules/juce_events/broadcasters/juce_ChangeBroadcaster.cpp"; sourceTree = "SOURCE_ROOT"; }; - 8854EAFDD3B68BC78E0A1F89 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_data_structures.h"; path = "../../JuceLibraryCode/modules/juce_data_structures/juce_data_structures.h"; sourceTree = "SOURCE_ROOT"; }; + 8632589E0C21E3B0A5DA0333 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FileBasedDocument.h"; path = "../../../../modules/juce_gui_extra/documents/juce_FileBasedDocument.h"; sourceTree = "SOURCE_ROOT"; }; + 8683CDE5FD2DFCB2CFC8F410 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_TooltipWindow.cpp"; path = "../../../../modules/juce_gui_basics/windows/juce_TooltipWindow.cpp"; sourceTree = "SOURCE_ROOT"; }; + 868955327EBBD0C2C2447DB3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ApplicationBase.h"; path = "../../../../modules/juce_events/messages/juce_ApplicationBase.h"; sourceTree = "SOURCE_ROOT"; }; + 8741126A9694372E46E3FD32 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioPluginFormat.cpp"; path = "../../../../modules/juce_audio_processors/format/juce_AudioPluginFormat.cpp"; sourceTree = "SOURCE_ROOT"; }; + 877ED7656241F46291022910 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OpenGLExtensions.h"; path = "../../../../modules/juce_opengl/native/juce_OpenGLExtensions.h"; sourceTree = "SOURCE_ROOT"; }; + 87E61959D8EA529461A0D257 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_android_CameraDevice.cpp"; path = "../../../../modules/juce_video/native/juce_android_CameraDevice.cpp"; sourceTree = "SOURCE_ROOT"; }; + 87EDBC629357F63AB8E7B507 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FileOutputStream.cpp"; path = "../../../../modules/juce_core/files/juce_FileOutputStream.cpp"; sourceTree = "SOURCE_ROOT"; }; + 884AA1209A726AEAF76E31B0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioDeviceManager.cpp"; path = "../../../../modules/juce_audio_devices/audio_io/juce_AudioDeviceManager.cpp"; sourceTree = "SOURCE_ROOT"; }; + 8866CF798E9F84C49B9D7DCC = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_android_Windowing.cpp"; path = "../../../../modules/juce_gui_basics/native/juce_android_Windowing.cpp"; sourceTree = "SOURCE_ROOT"; }; 888284627B1FEA22193130AB = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreText.framework; path = System/Library/Frameworks/CoreText.framework; sourceTree = SDKROOT; }; - 88A8541D309794713923E3D1 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Typeface.cpp"; path = "../../JuceLibraryCode/modules/juce_graphics/fonts/juce_Typeface.cpp"; sourceTree = "SOURCE_ROOT"; }; - 88D72DB7B94A70CD9EE18440 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Colours.h"; path = "../../JuceLibraryCode/modules/juce_graphics/colour/juce_Colours.h"; sourceTree = "SOURCE_ROOT"; }; - 8910FF4F64E6AFD721B91B0D = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_OpenGLImage.cpp"; path = "../../JuceLibraryCode/modules/juce_opengl/opengl/juce_OpenGLImage.cpp"; sourceTree = "SOURCE_ROOT"; }; - 8AC4AFECD0028680DA96CFEE = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_DirectWriteTypeface.cpp"; path = "../../JuceLibraryCode/modules/juce_graphics/native/juce_win32_DirectWriteTypeface.cpp"; sourceTree = "SOURCE_ROOT"; }; - 8AD5A845BBCF5ED0E6AA5922 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_StringPairArray.cpp"; path = "../../JuceLibraryCode/modules/juce_core/text/juce_StringPairArray.cpp"; sourceTree = "SOURCE_ROOT"; }; - 8B28654FCB4605697C82637F = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ImageComponent.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/widgets/juce_ImageComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; - 8BB79E37A824F6CBBB7A97D9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_TextButton.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/buttons/juce_TextButton.cpp"; sourceTree = "SOURCE_ROOT"; }; - 8CAF2B1BDF49EC845F183218 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_WindowsMediaAudioFormat.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_formats/codecs/juce_WindowsMediaAudioFormat.cpp"; sourceTree = "SOURCE_ROOT"; }; - 8CD45DADF91984C72DAE7E09 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_BufferingAudioSource.h"; path = "../../JuceLibraryCode/modules/juce_audio_basics/sources/juce_BufferingAudioSource.h"; sourceTree = "SOURCE_ROOT"; }; - 8D4E99621AAEBA39CCA68C41 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MessageListener.h"; path = "../../JuceLibraryCode/modules/juce_events/messages/juce_MessageListener.h"; sourceTree = "SOURCE_ROOT"; }; - 8D9A85AC7668D98160EC607E = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_android_FileChooser.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/native/juce_android_FileChooser.cpp"; sourceTree = "SOURCE_ROOT"; }; - 8DC8057B78772BA17A3ADDD1 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioFormatWriter.h"; path = "../../JuceLibraryCode/modules/juce_audio_formats/format/juce_AudioFormatWriter.h"; sourceTree = "SOURCE_ROOT"; }; - 8E6D1C56F3FAC7B249F2582B = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_PropertyComponent.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/properties/juce_PropertyComponent.h"; sourceTree = "SOURCE_ROOT"; }; - 8E6D4E8672ADAA47FF421180 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ReferenceCountedObject.h"; path = "../../JuceLibraryCode/modules/juce_core/memory/juce_ReferenceCountedObject.h"; sourceTree = "SOURCE_ROOT"; }; - 8EA752855DD7BA2C1CEFF9D4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_RelativeCoordinate.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/positioning/juce_RelativeCoordinate.h"; sourceTree = "SOURCE_ROOT"; }; - 8F0BDEECFD7200A7BE6FC598 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Range.h"; path = "../../JuceLibraryCode/modules/juce_core/maths/juce_Range.h"; sourceTree = "SOURCE_ROOT"; }; - 8F3E6744F26B7BAA554F4E41 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_android_SystemStats.cpp"; path = "../../JuceLibraryCode/modules/juce_core/native/juce_android_SystemStats.cpp"; sourceTree = "SOURCE_ROOT"; }; - 8F69B5117A8AB4D95316FBAC = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ArrowButton.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/buttons/juce_ArrowButton.cpp"; sourceTree = "SOURCE_ROOT"; }; - 8F8C1B89ADC4FF3D985E4444 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_android_Messaging.cpp"; path = "../../JuceLibraryCode/modules/juce_events/native/juce_android_Messaging.cpp"; sourceTree = "SOURCE_ROOT"; }; - 8F95ADADC0B19BF9D77D1A01 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CachedComponentImage.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/components/juce_CachedComponentImage.h"; sourceTree = "SOURCE_ROOT"; }; - 8FE90269A3BD4CDE641C5847 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_module_info"; path = "../../JuceLibraryCode/modules/juce_video/juce_module_info"; sourceTree = "SOURCE_ROOT"; }; - 90E607BA3727A053395D2A61 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_IIRFilter.h"; path = "../../JuceLibraryCode/modules/juce_audio_basics/effects/juce_IIRFilter.h"; sourceTree = "SOURCE_ROOT"; }; - 90E99C139FF6443FAABA2729 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_MainMenu.mm"; path = "../../JuceLibraryCode/modules/juce_gui_basics/native/juce_mac_MainMenu.mm"; sourceTree = "SOURCE_ROOT"; }; - 92800D0F94BA509EF80613A0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_WebBrowserComponent.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_extra/native/juce_win32_WebBrowserComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; - 92901C506127F45E3F5B258E = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_PropertySet.h"; path = "../../JuceLibraryCode/modules/juce_core/containers/juce_PropertySet.h"; sourceTree = "SOURCE_ROOT"; }; - 92EE84597D647B6CE0CBD4FE = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_LookAndFeel_V3.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V3.h"; sourceTree = "SOURCE_ROOT"; }; - 933A312B0B63B032495B06C1 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Matrix3D.h"; path = "../../JuceLibraryCode/modules/juce_opengl/geometry/juce_Matrix3D.h"; sourceTree = "SOURCE_ROOT"; }; - 940BD46F150595E60976C487 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ActionBroadcaster.h"; path = "../../JuceLibraryCode/modules/juce_events/broadcasters/juce_ActionBroadcaster.h"; sourceTree = "SOURCE_ROOT"; }; - 9444AB597C118C99704EFDF8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Uuid.cpp"; path = "../../JuceLibraryCode/modules/juce_core/misc/juce_Uuid.cpp"; sourceTree = "SOURCE_ROOT"; }; - 94614BC3AAA7263B1D6BDAE7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_SystemTrayIcon.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_extra/native/juce_win32_SystemTrayIcon.cpp"; sourceTree = "SOURCE_ROOT"; }; - 94B52728DAAC5E3BADD03617 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_InputStream.h"; path = "../../JuceLibraryCode/modules/juce_core/streams/juce_InputStream.h"; sourceTree = "SOURCE_ROOT"; }; - 94B8132DD5915F30ED7DD249 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioPluginInstance.h"; path = "../../JuceLibraryCode/modules/juce_audio_processors/processors/juce_AudioPluginInstance.h"; sourceTree = "SOURCE_ROOT"; }; - 95244870E8E9CC3CC6FF33C7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_IPAddress.cpp"; path = "../../JuceLibraryCode/modules/juce_core/network/juce_IPAddress.cpp"; sourceTree = "SOURCE_ROOT"; }; - 9533D4846543EF2F80E7B561 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Draggable3DOrientation.h"; path = "../../JuceLibraryCode/modules/juce_opengl/geometry/juce_Draggable3DOrientation.h"; sourceTree = "SOURCE_ROOT"; }; - 95446442AB833FA3CAF0D949 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FileSearchPathListComponent.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/filebrowser/juce_FileSearchPathListComponent.h"; sourceTree = "SOURCE_ROOT"; }; - 9563B07A9E53D5FFE868F8BE = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_KeyListener.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/keyboard/juce_KeyListener.cpp"; sourceTree = "SOURCE_ROOT"; }; - 95A59141DCE1349CC649FDB2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ScopedValueSetter.h"; path = "../../JuceLibraryCode/modules/juce_core/containers/juce_ScopedValueSetter.h"; sourceTree = "SOURCE_ROOT"; }; - 9613BC80734D26E200E5CE1F = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_LookAndFeel_V1.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V1.h"; sourceTree = "SOURCE_ROOT"; }; - 968B7B6F9C111B514327A382 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Thread.h"; path = "../../JuceLibraryCode/modules/juce_core/threads/juce_Thread.h"; sourceTree = "SOURCE_ROOT"; }; - 96CE2C991445A3994E1FBCB0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ModifierKeys.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/keyboard/juce_ModifierKeys.cpp"; sourceTree = "SOURCE_ROOT"; }; - 96E6A79B5BBBF580E0E11FF6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ToggleButton.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/buttons/juce_ToggleButton.h"; sourceTree = "SOURCE_ROOT"; }; - 971D7A721F741E81AACBDBDA = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Timer.cpp"; path = "../../JuceLibraryCode/modules/juce_events/timers/juce_Timer.cpp"; sourceTree = "SOURCE_ROOT"; }; - 97984A6B910D0D4B48EFB82B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioFormatWriter.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_formats/format/juce_AudioFormatWriter.cpp"; sourceTree = "SOURCE_ROOT"; }; - 97B99BA54C40DB3348086461 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MemoryInputStream.h"; path = "../../JuceLibraryCode/modules/juce_core/streams/juce_MemoryInputStream.h"; sourceTree = "SOURCE_ROOT"; }; - 97BB0621A58441872B96D1EC = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_LassoComponent.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/mouse/juce_LassoComponent.h"; sourceTree = "SOURCE_ROOT"; }; - 97E51A159B596325E90C5BE9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_PluginDirectoryScanner.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_processors/scanning/juce_PluginDirectoryScanner.cpp"; sourceTree = "SOURCE_ROOT"; }; - 97F9A1E6E51FB3D918EC3174 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DrawableText.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/drawables/juce_DrawableText.cpp"; sourceTree = "SOURCE_ROOT"; }; - 980A1CBA9A6D4B421BEB00F7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MountedVolumeListChangeDetector.h"; path = "../../JuceLibraryCode/modules/juce_events/messages/juce_MountedVolumeListChangeDetector.h"; sourceTree = "SOURCE_ROOT"; }; - 98297330C67DF9D0059606DF = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Point.h"; path = "../../JuceLibraryCode/modules/juce_graphics/geometry/juce_Point.h"; sourceTree = "SOURCE_ROOT"; }; - 983D92711EC4B001DEF300DF = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MemoryBlock.h"; path = "../../JuceLibraryCode/modules/juce_core/memory/juce_MemoryBlock.h"; sourceTree = "SOURCE_ROOT"; }; - 9846C2445B7D6E79A66630F9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_GlowEffect.h"; path = "../../JuceLibraryCode/modules/juce_graphics/effects/juce_GlowEffect.h"; sourceTree = "SOURCE_ROOT"; }; - 98594F6F68633ABB8DB9A488 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_PopupMenu.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/menus/juce_PopupMenu.cpp"; sourceTree = "SOURCE_ROOT"; }; - 98622ABC34EA3DD4334580D5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Sampler.h"; path = "../../JuceLibraryCode/modules/juce_audio_formats/sampler/juce_Sampler.h"; sourceTree = "SOURCE_ROOT"; }; - 9871D03E9A1E28B247352407 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ComboBox.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/widgets/juce_ComboBox.cpp"; sourceTree = "SOURCE_ROOT"; }; - 987E21587B07462F5098831E = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Uuid.h"; path = "../../JuceLibraryCode/modules/juce_core/misc/juce_Uuid.h"; sourceTree = "SOURCE_ROOT"; }; - 9898BBBC81128203FC3934B7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioCDBurner.h"; path = "../../JuceLibraryCode/modules/juce_audio_devices/audio_cd/juce_AudioCDBurner.h"; sourceTree = "SOURCE_ROOT"; }; - 98ED7C529B2A40AA4C0527DD = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DynamicObject.cpp"; path = "../../JuceLibraryCode/modules/juce_core/containers/juce_DynamicObject.cpp"; sourceTree = "SOURCE_ROOT"; }; - 98FBBFD68CCC9D52B62BFFEE = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_video.mm"; path = "../../JuceLibraryCode/modules/juce_video/juce_video.mm"; sourceTree = "SOURCE_ROOT"; }; - 991BB887EC327D340E5AA659 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Primes.h"; path = "../../JuceLibraryCode/modules/juce_cryptography/encryption/juce_Primes.h"; sourceTree = "SOURCE_ROOT"; }; - 995501A12A56DED7CDAAF24B = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioProcessorListener.h"; path = "../../JuceLibraryCode/modules/juce_audio_processors/processors/juce_AudioProcessorListener.h"; sourceTree = "SOURCE_ROOT"; }; - 9980F9FB908ED20591475FA8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CharPointer_ASCII.h"; path = "../../JuceLibraryCode/modules/juce_core/text/juce_CharPointer_ASCII.h"; sourceTree = "SOURCE_ROOT"; }; - 9A160557777085A813B1F0B5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_InputSource.h"; path = "../../JuceLibraryCode/modules/juce_core/streams/juce_InputSource.h"; sourceTree = "SOURCE_ROOT"; }; - 9A704CC5117B59E1F5CEBECD = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DrawablePath.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/drawables/juce_DrawablePath.cpp"; sourceTree = "SOURCE_ROOT"; }; - 9B156F9D8794BF1E15A19C5C = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_TableListBox.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/widgets/juce_TableListBox.cpp"; sourceTree = "SOURCE_ROOT"; }; - 9B1820674E3D99D9D4AB8DD9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_AppleRemote.mm"; path = "../../JuceLibraryCode/modules/juce_gui_extra/native/juce_mac_AppleRemote.mm"; sourceTree = "SOURCE_ROOT"; }; - 9BBE7417871F8708335181B0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_KeyListener.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/keyboard/juce_KeyListener.h"; sourceTree = "SOURCE_ROOT"; }; - 9C6E9983521DF4DFDD0C460B = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_gui_extra.h"; path = "../../JuceLibraryCode/modules/juce_gui_extra/juce_gui_extra.h"; sourceTree = "SOURCE_ROOT"; }; - 9C77E1E9F8BAFCD7610F8F76 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ImageComponent.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/widgets/juce_ImageComponent.h"; sourceTree = "SOURCE_ROOT"; }; - 9CE19F2F963112A2442FF86E = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_RectanglePlacement.h"; path = "../../JuceLibraryCode/modules/juce_graphics/placement/juce_RectanglePlacement.h"; sourceTree = "SOURCE_ROOT"; }; - 9D4642C9C308DD3ABB2DF731 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Time.h"; path = "../../JuceLibraryCode/modules/juce_core/time/juce_Time.h"; sourceTree = "SOURCE_ROOT"; }; - 9D4BEB15620ED88F95BDF105 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FileFilter.h"; path = "../../JuceLibraryCode/modules/juce_core/files/juce_FileFilter.h"; sourceTree = "SOURCE_ROOT"; }; - 9D7A8ED2F93993D6BD4818B9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ImageButton.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/buttons/juce_ImageButton.cpp"; sourceTree = "SOURCE_ROOT"; }; - 9E003766817800EDE5F401DA = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_RenderingHelpers.h"; path = "../../JuceLibraryCode/modules/juce_graphics/native/juce_RenderingHelpers.h"; sourceTree = "SOURCE_ROOT"; }; - 9E22E973F5C7E6AF1004EE8D = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_UndoManager.cpp"; path = "../../JuceLibraryCode/modules/juce_data_structures/undomanager/juce_UndoManager.cpp"; sourceTree = "SOURCE_ROOT"; }; - 9E47EC586E11C6F1AD2782C3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ColourSelector.h"; path = "../../JuceLibraryCode/modules/juce_gui_extra/misc/juce_ColourSelector.h"; sourceTree = "SOURCE_ROOT"; }; - 9E6F450E5BEFD67159EAD012 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_BorderSize.h"; path = "../../JuceLibraryCode/modules/juce_graphics/geometry/juce_BorderSize.h"; sourceTree = "SOURCE_ROOT"; }; - 9F077D151CAAB48E1B7A4A45 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_File.cpp"; path = "../../JuceLibraryCode/modules/juce_core/files/juce_File.cpp"; sourceTree = "SOURCE_ROOT"; }; - 9F32845601855AC6DA5F14B0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_CPlusPlusCodeTokeniser.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_extra/code_editor/juce_CPlusPlusCodeTokeniser.cpp"; sourceTree = "SOURCE_ROOT"; }; - 9F69A9E1418A5E3B33EF5B26 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_JSON.cpp"; path = "../../JuceLibraryCode/modules/juce_core/javascript/juce_JSON.cpp"; sourceTree = "SOURCE_ROOT"; }; - A00497528C590CECD253D1ED = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_WebBrowserComponent.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_extra/native/juce_linux_WebBrowserComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; - A04B28778E7EFA87304B177C = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MouseInactivityDetector.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/mouse/juce_MouseInactivityDetector.cpp"; sourceTree = "SOURCE_ROOT"; }; - A0B1470B03C45DEA4B9EE14B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_GroupComponent.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/layout/juce_GroupComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; - A0CB25C077F41F543BFE0ADE = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MultiDocumentPanel.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/layout/juce_MultiDocumentPanel.h"; sourceTree = "SOURCE_ROOT"; }; - A0D91BF6AFEC74B5349A3087 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CPlusPlusCodeTokeniserFunctions.h"; path = "../../JuceLibraryCode/modules/juce_gui_extra/code_editor/juce_CPlusPlusCodeTokeniserFunctions.h"; sourceTree = "SOURCE_ROOT"; }; - A0EC1B71A589996CE32FDD1B = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_EdgeTable.h"; path = "../../JuceLibraryCode/modules/juce_graphics/geometry/juce_EdgeTable.h"; sourceTree = "SOURCE_ROOT"; }; - A13F9E4C92A3DD4C01330208 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioFormat.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_formats/format/juce_AudioFormat.cpp"; sourceTree = "SOURCE_ROOT"; }; - A1C9C360E9B30D43246B9241 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MemoryMappedAudioFormatReader.h"; path = "../../JuceLibraryCode/modules/juce_audio_formats/format/juce_MemoryMappedAudioFormatReader.h"; sourceTree = "SOURCE_ROOT"; }; - A1EF20A764C5B6EDEFC378E3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_TextPropertyComponent.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/properties/juce_TextPropertyComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; - A232BF668A11B7015B65C33B = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_module_info"; path = "../../JuceLibraryCode/modules/juce_gui_basics/juce_module_info"; sourceTree = "SOURCE_ROOT"; }; - A27997058CED5CD80DE7C4B0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ProgressBar.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/widgets/juce_ProgressBar.cpp"; sourceTree = "SOURCE_ROOT"; }; - A2D0912BF511B8AA5CEE9690 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ResamplingAudioSource.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_basics/sources/juce_ResamplingAudioSource.cpp"; sourceTree = "SOURCE_ROOT"; }; - A2E38A6CEB042C6819BF032C = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_ios_UIViewComponentPeer.mm"; path = "../../JuceLibraryCode/modules/juce_gui_basics/native/juce_ios_UIViewComponentPeer.mm"; sourceTree = "SOURCE_ROOT"; }; - A3405DF38FC19128C399E497 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ThreadPool.cpp"; path = "../../JuceLibraryCode/modules/juce_core/threads/juce_ThreadPool.cpp"; sourceTree = "SOURCE_ROOT"; }; - A38AD54C200158953BA0456D = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_TabbedComponent.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/layout/juce_TabbedComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; - A395CC90104B14CC5D5D8F21 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FileBasedDocument.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_extra/documents/juce_FileBasedDocument.cpp"; sourceTree = "SOURCE_ROOT"; }; - A46624CB68D4D4FC6AFDDDB5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_video.h"; path = "../../JuceLibraryCode/modules/juce_video/juce_video.h"; sourceTree = "SOURCE_ROOT"; }; - A4A99FFB9CECAA4B4ACE8402 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DirectoryIterator.cpp"; path = "../../JuceLibraryCode/modules/juce_core/files/juce_DirectoryIterator.cpp"; sourceTree = "SOURCE_ROOT"; }; - A4CACFA409866E77F609126A = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ZipFile.h"; path = "../../JuceLibraryCode/modules/juce_core/zip/juce_ZipFile.h"; sourceTree = "SOURCE_ROOT"; }; - A4DDA56CCF451DCCA2F47D42 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Justification.h"; path = "../../JuceLibraryCode/modules/juce_graphics/placement/juce_Justification.h"; sourceTree = "SOURCE_ROOT"; }; - A4F8C1DE149AD44A83143598 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_PlatformDefs.h"; path = "../../JuceLibraryCode/modules/juce_core/system/juce_PlatformDefs.h"; sourceTree = "SOURCE_ROOT"; }; - A56E50AC91E42206FAD381F1 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_ActiveXComponent.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_extra/native/juce_win32_ActiveXComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; - A5A2DBDF9350F91E9D6109B7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_AudioCDReader.mm"; path = "../../JuceLibraryCode/modules/juce_audio_devices/native/juce_mac_AudioCDReader.mm"; sourceTree = "SOURCE_ROOT"; }; - A60E87D4E2911C3730CE3DB1 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DrawableRectangle.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/drawables/juce_DrawableRectangle.h"; sourceTree = "SOURCE_ROOT"; }; - A610EB8E83CC94E7DFBBC298 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_SelectedItemSet.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/mouse/juce_SelectedItemSet.h"; sourceTree = "SOURCE_ROOT"; }; - A66CD58D6A8F18628AF2BFF7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_win32_HiddenMessageWindow.h"; path = "../../JuceLibraryCode/modules/juce_events/native/juce_win32_HiddenMessageWindow.h"; sourceTree = "SOURCE_ROOT"; }; + 88CC8BC2EA8CDB378A03FADA = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_android_Messaging.cpp"; path = "../../../../modules/juce_events/native/juce_android_Messaging.cpp"; sourceTree = "SOURCE_ROOT"; }; + 88EF4C8D3A1D2498D8ADB6E0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_PluginListComponent.h"; path = "../../../../modules/juce_audio_processors/scanning/juce_PluginListComponent.h"; sourceTree = "SOURCE_ROOT"; }; + 8945894D17A9407EEEE3B8BD = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MemoryOutputStream.h"; path = "../../../../modules/juce_core/streams/juce_MemoryOutputStream.h"; sourceTree = "SOURCE_ROOT"; }; + 897B10399D1CA882B5B98D0F = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ThreadPool.h"; path = "../../../../modules/juce_core/threads/juce_ThreadPool.h"; sourceTree = "SOURCE_ROOT"; }; + 897C7B6FB012647ED8AB5D05 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_WebBrowserComponent.h"; path = "../../../../modules/juce_gui_extra/misc/juce_WebBrowserComponent.h"; sourceTree = "SOURCE_ROOT"; }; + 89ACAEA951C470AF8683AABD = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CPlusPlusCodeTokeniserFunctions.h"; path = "../../../../modules/juce_gui_extra/code_editor/juce_CPlusPlusCodeTokeniserFunctions.h"; sourceTree = "SOURCE_ROOT"; }; + 89CBCB2D4660B56C1A939011 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_Messaging.cpp"; path = "../../../../modules/juce_events/native/juce_linux_Messaging.cpp"; sourceTree = "SOURCE_ROOT"; }; + 89F5A5C12916F02E579D6394 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ComponentDragger.cpp"; path = "../../../../modules/juce_gui_basics/mouse/juce_ComponentDragger.cpp"; sourceTree = "SOURCE_ROOT"; }; + 8A4A25946040DED54DB8F3B1 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ColourGradient.h"; path = "../../../../modules/juce_graphics/colour/juce_ColourGradient.h"; sourceTree = "SOURCE_ROOT"; }; + 8B155ED74D3D0EB7E890E421 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_IIRFilterAudioSource.h"; path = "../../../../modules/juce_audio_basics/sources/juce_IIRFilterAudioSource.h"; sourceTree = "SOURCE_ROOT"; }; + 8B539DB72CC92EEC7F96C8E6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TooltipClient.h"; path = "../../../../modules/juce_gui_basics/mouse/juce_TooltipClient.h"; sourceTree = "SOURCE_ROOT"; }; + 8B7C0F839098C534A7B4C725 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Random.cpp"; path = "../../../../modules/juce_core/maths/juce_Random.cpp"; sourceTree = "SOURCE_ROOT"; }; + 8BE44C96A60C5D9B9F503409 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DrawableShape.cpp"; path = "../../../../modules/juce_gui_basics/drawables/juce_DrawableShape.cpp"; sourceTree = "SOURCE_ROOT"; }; + 8C105487633A9BD04FDEE50A = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Synthesiser.h"; path = "../../../../modules/juce_audio_basics/synthesisers/juce_Synthesiser.h"; sourceTree = "SOURCE_ROOT"; }; + 8C24F74CB23F1B82C80386FF = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_android_Network.cpp"; path = "../../../../modules/juce_core/native/juce_android_Network.cpp"; sourceTree = "SOURCE_ROOT"; }; + 8C3A6351780E678334FA1406 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_NamedPipe.h"; path = "../../../../modules/juce_core/network/juce_NamedPipe.h"; sourceTree = "SOURCE_ROOT"; }; + 8C547C48DD5B3A854DBFF0F3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MessageManager.cpp"; path = "../../../../modules/juce_events/messages/juce_MessageManager.cpp"; sourceTree = "SOURCE_ROOT"; }; + 8C6A342773288620A8CC2598 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MemoryBlock.cpp"; path = "../../../../modules/juce_core/memory/juce_MemoryBlock.cpp"; sourceTree = "SOURCE_ROOT"; }; + 8C9D252ABA3CDDC81B33884D = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_TabbedButtonBar.cpp"; path = "../../../../modules/juce_gui_basics/layout/juce_TabbedButtonBar.cpp"; sourceTree = "SOURCE_ROOT"; }; + 8C9EC3F9C24081ECEF3FCEFD = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_TabbedComponent.cpp"; path = "../../../../modules/juce_gui_basics/layout/juce_TabbedComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; + 8CA01F9530AC5512C6B74325 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MidiMessage.cpp"; path = "../../../../modules/juce_audio_basics/midi/juce_MidiMessage.cpp"; sourceTree = "SOURCE_ROOT"; }; + 8D3FB0417A39CAEC03D44D73 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_module_info"; path = "../../../../modules/juce_opengl/juce_module_info"; sourceTree = "SOURCE_ROOT"; }; + 8DC827CCF543708CF729FED6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MidiFile.cpp"; path = "../../../../modules/juce_audio_basics/midi/juce_MidiFile.cpp"; sourceTree = "SOURCE_ROOT"; }; + 8DE969191661B557B4222D50 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MouseInactivityDetector.h"; path = "../../../../modules/juce_gui_basics/mouse/juce_MouseInactivityDetector.h"; sourceTree = "SOURCE_ROOT"; }; + 8DEFACA6858D254B4202AF12 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_module_info"; path = "../../../../modules/juce_audio_basics/juce_module_info"; sourceTree = "SOURCE_ROOT"; }; + 8E407C1CF739A93FD2B3B38C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CharPointer_ASCII.h"; path = "../../../../modules/juce_core/text/juce_CharPointer_ASCII.h"; sourceTree = "SOURCE_ROOT"; }; + 8E95A3B7C194244B92D5D65A = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_NativeMessageBox.h"; path = "../../../../modules/juce_gui_basics/windows/juce_NativeMessageBox.h"; sourceTree = "SOURCE_ROOT"; }; + 8EA18CA66CABC9B5087DBDD2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_freetype_Fonts.cpp"; path = "../../../../modules/juce_graphics/native/juce_freetype_Fonts.cpp"; sourceTree = "SOURCE_ROOT"; }; + 8EDD1755AEE1C95660A06BF2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MidiMessageSequence.h"; path = "../../../../modules/juce_audio_basics/midi/juce_MidiMessageSequence.h"; sourceTree = "SOURCE_ROOT"; }; + 8EFB4EBA0836D5401B6D3DFB = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_KeyListener.h"; path = "../../../../modules/juce_gui_basics/keyboard/juce_KeyListener.h"; sourceTree = "SOURCE_ROOT"; }; + 8FA02AA8698232B53D4BFDBB = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MidiMessageSequence.cpp"; path = "../../../../modules/juce_audio_basics/midi/juce_MidiMessageSequence.cpp"; sourceTree = "SOURCE_ROOT"; }; + 90841E3B0B2548A5BD66F15E = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_FileChooser.cpp"; path = "../../../../modules/juce_gui_basics/native/juce_win32_FileChooser.cpp"; sourceTree = "SOURCE_ROOT"; }; + 90B6C81CFB0DE386C673F62E = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_IPAddress.cpp"; path = "../../../../modules/juce_core/network/juce_IPAddress.cpp"; sourceTree = "SOURCE_ROOT"; }; + 90BE189372A13866896CE817 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FileChooserDialogBox.cpp"; path = "../../../../modules/juce_gui_basics/filebrowser/juce_FileChooserDialogBox.cpp"; sourceTree = "SOURCE_ROOT"; }; + 90FEA7DB5EFC4E9B2E933056 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TextInputTarget.h"; path = "../../../../modules/juce_gui_basics/keyboard/juce_TextInputTarget.h"; sourceTree = "SOURCE_ROOT"; }; + 911B308D5222BDFD954DBB32 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioTransportSource.cpp"; path = "../../../../modules/juce_audio_devices/sources/juce_AudioTransportSource.cpp"; sourceTree = "SOURCE_ROOT"; }; + 916001804771DF943551AAEF = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_LocalisedStrings.h"; path = "../../../../modules/juce_core/text/juce_LocalisedStrings.h"; sourceTree = "SOURCE_ROOT"; }; + 91B991143655810C26644D50 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_PixelFormats.h"; path = "../../../../modules/juce_graphics/colour/juce_PixelFormats.h"; sourceTree = "SOURCE_ROOT"; }; + 91CEFA76775CD035E2F9200F = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_LuaCodeTokeniser.h"; path = "../../../../modules/juce_gui_extra/code_editor/juce_LuaCodeTokeniser.h"; sourceTree = "SOURCE_ROOT"; }; + 91D09C7242A24405FB364449 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ScopedWriteLock.h"; path = "../../../../modules/juce_core/threads/juce_ScopedWriteLock.h"; sourceTree = "SOURCE_ROOT"; }; + 9211B175E63E325D4FF6B789 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_KeyPressMappingSet.cpp"; path = "../../../../modules/juce_gui_basics/commands/juce_KeyPressMappingSet.cpp"; sourceTree = "SOURCE_ROOT"; }; + 92172AE93327D4F8008A0AFD = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_BorderSize.h"; path = "../../../../modules/juce_graphics/geometry/juce_BorderSize.h"; sourceTree = "SOURCE_ROOT"; }; + 926063234BAFA6D29366E43E = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_StringPairArray.cpp"; path = "../../../../modules/juce_core/text/juce_StringPairArray.cpp"; sourceTree = "SOURCE_ROOT"; }; + 92BB22C929A3A76CE6F29C7A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DrawableImage.cpp"; path = "../../../../modules/juce_gui_basics/drawables/juce_DrawableImage.cpp"; sourceTree = "SOURCE_ROOT"; }; + 92DF4A828DC5CE370E36044C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DrawableButton.h"; path = "../../../../modules/juce_gui_basics/buttons/juce_DrawableButton.h"; sourceTree = "SOURCE_ROOT"; }; + 932126F914644642A8244676 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_LAMEEncoderAudioFormat.cpp"; path = "../../../../modules/juce_audio_formats/codecs/juce_LAMEEncoderAudioFormat.cpp"; sourceTree = "SOURCE_ROOT"; }; + 935BCEB2593A51E53187ABC2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_String.cpp"; path = "../../../../modules/juce_core/text/juce_String.cpp"; sourceTree = "SOURCE_ROOT"; }; + 93667813A711750790201F8D = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ScopedXLock.h"; path = "../../../../modules/juce_events/native/juce_ScopedXLock.h"; sourceTree = "SOURCE_ROOT"; }; + 93CC262389F622F8AB79CA60 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Button.cpp"; path = "../../../../modules/juce_gui_basics/buttons/juce_Button.cpp"; sourceTree = "SOURCE_ROOT"; }; + 941219816EB5D7A2231019FA = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Result.h"; path = "../../../../modules/juce_core/misc/juce_Result.h"; sourceTree = "SOURCE_ROOT"; }; + 9424FDB8C564B73250B7B20A = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ButtonPropertyComponent.h"; path = "../../../../modules/juce_gui_basics/properties/juce_ButtonPropertyComponent.h"; sourceTree = "SOURCE_ROOT"; }; + 94BFC3162953A5E7E192276A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DrawableComposite.cpp"; path = "../../../../modules/juce_gui_basics/drawables/juce_DrawableComposite.cpp"; sourceTree = "SOURCE_ROOT"; }; + 94FAC7EB87C8EBE67F68AD60 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ImageConvolutionKernel.cpp"; path = "../../../../modules/juce_graphics/images/juce_ImageConvolutionKernel.cpp"; sourceTree = "SOURCE_ROOT"; }; + 95412F7C12937CC7AC22ADCF = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_ALSA.cpp"; path = "../../../../modules/juce_audio_devices/native/juce_linux_ALSA.cpp"; sourceTree = "SOURCE_ROOT"; }; + 95440A40B2FB3CE5E09D57B4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MidiKeyboardState.cpp"; path = "../../../../modules/juce_audio_basics/midi/juce_MidiKeyboardState.cpp"; sourceTree = "SOURCE_ROOT"; }; + 9692128AC24CF671A9C0457B = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_SplashScreen.h"; path = "../../../../modules/juce_gui_extra/misc/juce_SplashScreen.h"; sourceTree = "SOURCE_ROOT"; }; + 96E4B48CF055ED116E5CB3AB = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DropShadower.h"; path = "../../../../modules/juce_gui_basics/misc/juce_DropShadower.h"; sourceTree = "SOURCE_ROOT"; }; + 979A030D4807A573FAA18318 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MixerAudioSource.h"; path = "../../../../modules/juce_audio_basics/sources/juce_MixerAudioSource.h"; sourceTree = "SOURCE_ROOT"; }; + 97EDCA2A04EF5ADAAD9DC594 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_BufferingAudioSource.h"; path = "../../../../modules/juce_audio_basics/sources/juce_BufferingAudioSource.h"; sourceTree = "SOURCE_ROOT"; }; + 987AD2821B6419D5FEDCBD7A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_audio_formats.mm"; path = "../../../../modules/juce_audio_formats/juce_audio_formats.mm"; sourceTree = "SOURCE_ROOT"; }; + 98C77B9D95141EBC60E6AE67 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DirectoryContentsList.cpp"; path = "../../../../modules/juce_gui_basics/filebrowser/juce_DirectoryContentsList.cpp"; sourceTree = "SOURCE_ROOT"; }; + 98D247A4824D969367AFD0FB = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Uuid.h"; path = "../../../../modules/juce_core/misc/juce_Uuid.h"; sourceTree = "SOURCE_ROOT"; }; + 996A274720539E8497291E85 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_QuickTimeAudioFormat.h"; path = "../../../../modules/juce_audio_formats/codecs/juce_QuickTimeAudioFormat.h"; sourceTree = "SOURCE_ROOT"; }; + 99A3B01A6398623F40C528FC = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_FileChooser.mm"; path = "../../../../modules/juce_gui_basics/native/juce_mac_FileChooser.mm"; sourceTree = "SOURCE_ROOT"; }; + 9A4FCF66FF42906A7A2187A5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Value.h"; path = "../../../../modules/juce_data_structures/values/juce_Value.h"; sourceTree = "SOURCE_ROOT"; }; + 9C05D3A33B0D7B6B2EA43C7A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_BlowFish.cpp"; path = "../../../../modules/juce_cryptography/encryption/juce_BlowFish.cpp"; sourceTree = "SOURCE_ROOT"; }; + 9C17E6FC9A4D7C8734800649 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Result.cpp"; path = "../../../../modules/juce_core/misc/juce_Result.cpp"; sourceTree = "SOURCE_ROOT"; }; + 9C3E556586147F27B4EDC982 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_StretchableLayoutManager.cpp"; path = "../../../../modules/juce_gui_basics/layout/juce_StretchableLayoutManager.cpp"; sourceTree = "SOURCE_ROOT"; }; + 9C599E35E8A990404EEF805A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Primes.cpp"; path = "../../../../modules/juce_cryptography/encryption/juce_Primes.cpp"; sourceTree = "SOURCE_ROOT"; }; + 9C8263A9C3210CBC6C909BDF = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_Threads.mm"; path = "../../../../modules/juce_core/native/juce_mac_Threads.mm"; sourceTree = "SOURCE_ROOT"; }; + 9CC0E3267A9D1EF3C8E37601 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OpenGLTexture.h"; path = "../../../../modules/juce_opengl/opengl/juce_OpenGLTexture.h"; sourceTree = "SOURCE_ROOT"; }; + 9CC22BDB1B3FF427D6525D21 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MemoryMappedAudioFormatReader.h"; path = "../../../../modules/juce_audio_formats/format/juce_MemoryMappedAudioFormatReader.h"; sourceTree = "SOURCE_ROOT"; }; + 9D50B3000D941FDCB620068F = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DirectoryIterator.cpp"; path = "../../../../modules/juce_core/files/juce_DirectoryIterator.cpp"; sourceTree = "SOURCE_ROOT"; }; + 9D61877D2691EB78B2ED69EA = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_android_Fonts.cpp"; path = "../../../../modules/juce_graphics/native/juce_android_Fonts.cpp"; sourceTree = "SOURCE_ROOT"; }; + 9D91916A769A7E2967368795 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Synthesiser.cpp"; path = "../../../../modules/juce_audio_basics/synthesisers/juce_Synthesiser.cpp"; sourceTree = "SOURCE_ROOT"; }; + 9DC4092F746AB0F5A73D929D = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ConnectedChildProcess.h"; path = "../../../../modules/juce_events/interprocess/juce_ConnectedChildProcess.h"; sourceTree = "SOURCE_ROOT"; }; + 9DC79DF0A43DA6B06B7B1F44 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OpenGL_linux.h"; path = "../../../../modules/juce_opengl/native/juce_OpenGL_linux.h"; sourceTree = "SOURCE_ROOT"; }; + 9DCDB2CA1444618C4054A114 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Javascript.h"; path = "../../../../modules/juce_core/javascript/juce_Javascript.h"; sourceTree = "SOURCE_ROOT"; }; + 9E44079E499D4F4ECE55354A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Socket.cpp"; path = "../../../../modules/juce_core/network/juce_Socket.cpp"; sourceTree = "SOURCE_ROOT"; }; + 9F522CA5A8E82BF69E7403BF = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Process.h"; path = "../../../../modules/juce_core/threads/juce_Process.h"; sourceTree = "SOURCE_ROOT"; }; + 9F5FD873C8192683DB089745 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MidiBuffer.cpp"; path = "../../../../modules/juce_audio_basics/midi/juce_MidiBuffer.cpp"; sourceTree = "SOURCE_ROOT"; }; + 9F70142818A7806830EEBD7C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TableListBox.h"; path = "../../../../modules/juce_gui_basics/widgets/juce_TableListBox.h"; sourceTree = "SOURCE_ROOT"; }; + 9F7AC745AA0588C821A014D0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_GZIPDecompressorInputStream.h"; path = "../../../../modules/juce_core/zip/juce_GZIPDecompressorInputStream.h"; sourceTree = "SOURCE_ROOT"; }; + 9FBAD3EFE40ACEB06B155A09 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_Files.cpp"; path = "../../../../modules/juce_core/native/juce_linux_Files.cpp"; sourceTree = "SOURCE_ROOT"; }; + 9FC1BB191F1EB657A181866D = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ImageConvolutionKernel.h"; path = "../../../../modules/juce_graphics/images/juce_ImageConvolutionKernel.h"; sourceTree = "SOURCE_ROOT"; }; + A010D6D997B85A393165DAB3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AttributedString.cpp"; path = "../../../../modules/juce_graphics/fonts/juce_AttributedString.cpp"; sourceTree = "SOURCE_ROOT"; }; + A058E50779879A7D9A813A4C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OpenGLAppComponent.h"; path = "../../../../modules/juce_opengl/utils/juce_OpenGLAppComponent.h"; sourceTree = "SOURCE_ROOT"; }; + A0850087D0288361E552BE9A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_SplashScreen.cpp"; path = "../../../../modules/juce_gui_extra/misc/juce_SplashScreen.cpp"; sourceTree = "SOURCE_ROOT"; }; + A09CB6FA9736BD45103AFF46 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_OpenGLContext.cpp"; path = "../../../../modules/juce_opengl/opengl/juce_OpenGLContext.cpp"; sourceTree = "SOURCE_ROOT"; }; + A0F2EAF085969426AC73C85D = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ApplicationCommandManager.h"; path = "../../../../modules/juce_gui_basics/commands/juce_ApplicationCommandManager.h"; sourceTree = "SOURCE_ROOT"; }; + A1A621FDC626245B1B3C1C4D = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ButtonPropertyComponent.cpp"; path = "../../../../modules/juce_gui_basics/properties/juce_ButtonPropertyComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; + A1C77E9A6624B8B1A461C038 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_StretchableLayoutResizerBar.h"; path = "../../../../modules/juce_gui_basics/layout/juce_StretchableLayoutResizerBar.h"; sourceTree = "SOURCE_ROOT"; }; + A2208C87019608EBF813EAA8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_Strings.mm"; path = "../../../../modules/juce_core/native/juce_mac_Strings.mm"; sourceTree = "SOURCE_ROOT"; }; + A23966DF7E681FA878B27B92 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FileOutputStream.h"; path = "../../../../modules/juce_core/files/juce_FileOutputStream.h"; sourceTree = "SOURCE_ROOT"; }; + A281FFA1C7E3AFB8246FD577 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_DirectShowComponent.cpp"; path = "../../../../modules/juce_video/native/juce_win32_DirectShowComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; + A292587AA4633141BA378473 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_HighResolutionTimer.h"; path = "../../../../modules/juce_core/threads/juce_HighResolutionTimer.h"; sourceTree = "SOURCE_ROOT"; }; + A3D0C263C912566AECB57679 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Expression.cpp"; path = "../../../../modules/juce_core/maths/juce_Expression.cpp"; sourceTree = "SOURCE_ROOT"; }; + A3E01235E4AD9DBE2405F792 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_Direct2DGraphicsContext.cpp"; path = "../../../../modules/juce_graphics/native/juce_win32_Direct2DGraphicsContext.cpp"; sourceTree = "SOURCE_ROOT"; }; + A42A97232CE0593D8D989FC1 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CharacterFunctions.h"; path = "../../../../modules/juce_core/text/juce_CharacterFunctions.h"; sourceTree = "SOURCE_ROOT"; }; + A4F394FB62E70E3A3A02E4C7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_NamedPipe.cpp"; path = "../../../../modules/juce_core/network/juce_NamedPipe.cpp"; sourceTree = "SOURCE_ROOT"; }; + A50AF1519D78428A8DCD91BF = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioUnitPluginFormat.h"; path = "../../../../modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.h"; sourceTree = "SOURCE_ROOT"; }; + A53228473B7F7BCF946F15DF = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_PluginListComponent.cpp"; path = "../../../../modules/juce_audio_processors/scanning/juce_PluginListComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; + A54AED02A4929ED6EB693CB9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MessageManager.h"; path = "../../../../modules/juce_events/messages/juce_MessageManager.h"; sourceTree = "SOURCE_ROOT"; }; + A54B5504235B3324635B1DB3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Point.h"; path = "../../../../modules/juce_graphics/geometry/juce_Point.h"; sourceTree = "SOURCE_ROOT"; }; + A587862CF3C96C6C648216A3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_InterprocessConnection.cpp"; path = "../../../../modules/juce_events/interprocess/juce_InterprocessConnection.cpp"; sourceTree = "SOURCE_ROOT"; }; + A5CEADBA23491564FEB6D4EC = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_mac_CoreGraphicsContext.h"; path = "../../../../modules/juce_graphics/native/juce_mac_CoreGraphicsContext.h"; sourceTree = "SOURCE_ROOT"; }; + A5DEEB6DADAA5AB2CF41A880 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DragAndDropContainer.cpp"; path = "../../../../modules/juce_gui_basics/mouse/juce_DragAndDropContainer.cpp"; sourceTree = "SOURCE_ROOT"; }; + A61AD5378601F9DDEB8DED03 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioPlayHead.h"; path = "../../../../modules/juce_audio_processors/processors/juce_AudioPlayHead.h"; sourceTree = "SOURCE_ROOT"; }; A67C5701B28E64F889A92422 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = AppConfig.h; path = ../../JuceLibraryCode/AppConfig.h; sourceTree = "SOURCE_ROOT"; }; - A71DF97DA4CD69A67A1EE763 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TextDragAndDropTarget.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/mouse/juce_TextDragAndDropTarget.h"; sourceTree = "SOURCE_ROOT"; }; - A72F50930E3169EFC9724597 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Javascript.cpp"; path = "../../JuceLibraryCode/modules/juce_core/javascript/juce_Javascript.cpp"; sourceTree = "SOURCE_ROOT"; }; - A751CD8564B7B6B0EBD643E2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ImageFileFormat.h"; path = "../../JuceLibraryCode/modules/juce_graphics/images/juce_ImageFileFormat.h"; sourceTree = "SOURCE_ROOT"; }; - A76327DF3D3A1CB89340C2CB = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_RSAKey.h"; path = "../../JuceLibraryCode/modules/juce_cryptography/encryption/juce_RSAKey.h"; sourceTree = "SOURCE_ROOT"; }; - A77BB927A95DA581268CD729 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioPluginFormat.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_processors/format/juce_AudioPluginFormat.cpp"; sourceTree = "SOURCE_ROOT"; }; - A7D96DBD645622F9EF3B3E88 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_LookAndFeel.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel.h"; sourceTree = "SOURCE_ROOT"; }; - A87251DF370D12DEA68B41A1 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FileTreeComponent.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/filebrowser/juce_FileTreeComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; - A873E57D126C8D931CE6556A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioCDReader.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_devices/audio_cd/juce_AudioCDReader.cpp"; sourceTree = "SOURCE_ROOT"; }; - A8C6E967CBC442F331571870 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Primes.cpp"; path = "../../JuceLibraryCode/modules/juce_cryptography/encryption/juce_Primes.cpp"; sourceTree = "SOURCE_ROOT"; }; - A8DC0ACAAB88D6657355E466 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_LinkedListPointer.h"; path = "../../JuceLibraryCode/modules/juce_core/containers/juce_LinkedListPointer.h"; sourceTree = "SOURCE_ROOT"; }; - A90C3FDE58F6023CE19ECCEF = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_EdgeTable.cpp"; path = "../../JuceLibraryCode/modules/juce_graphics/geometry/juce_EdgeTable.cpp"; sourceTree = "SOURCE_ROOT"; }; - A92EA5F1D1D2ABA2E441DE45 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DrawableComposite.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/drawables/juce_DrawableComposite.cpp"; sourceTree = "SOURCE_ROOT"; }; - A963217BDC628E29845AFA5F = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Path.h"; path = "../../JuceLibraryCode/modules/juce_graphics/geometry/juce_Path.h"; sourceTree = "SOURCE_ROOT"; }; - A97E3E8BDA867CFC443D8D21 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_PropertiesFile.cpp"; path = "../../JuceLibraryCode/modules/juce_data_structures/app_properties/juce_PropertiesFile.cpp"; sourceTree = "SOURCE_ROOT"; }; - AA251B07162ABAA59D3DF432 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_StringPool.h"; path = "../../JuceLibraryCode/modules/juce_core/text/juce_StringPool.h"; sourceTree = "SOURCE_ROOT"; }; - AA67BCD0930A0B3B9D0B12B1 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_AudioCDBurner.mm"; path = "../../JuceLibraryCode/modules/juce_audio_devices/native/juce_mac_AudioCDBurner.mm"; sourceTree = "SOURCE_ROOT"; }; - AB2C5E54CD675401124F26A0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioDeviceManager.h"; path = "../../JuceLibraryCode/modules/juce_audio_devices/audio_io/juce_AudioDeviceManager.h"; sourceTree = "SOURCE_ROOT"; }; - AB7C518F617F260822A67872 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_TextLayout.cpp"; path = "../../JuceLibraryCode/modules/juce_graphics/fonts/juce_TextLayout.cpp"; sourceTree = "SOURCE_ROOT"; }; - ABA9367C4E66F2F18E813816 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ImageCache.cpp"; path = "../../JuceLibraryCode/modules/juce_graphics/images/juce_ImageCache.cpp"; sourceTree = "SOURCE_ROOT"; }; - ABB9E5EBCD9C0F04547E5A90 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MenuBarComponent.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/menus/juce_MenuBarComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; - AC3721AA8206512767A5E5AE = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ResizableCornerComponent.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/layout/juce_ResizableCornerComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; - AC3B9DEF05ED1B18C952FE36 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DirectoryContentsList.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/filebrowser/juce_DirectoryContentsList.h"; sourceTree = "SOURCE_ROOT"; }; - ACA68143C3AEE4F3F3327E66 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MouseInactivityDetector.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/mouse/juce_MouseInactivityDetector.h"; sourceTree = "SOURCE_ROOT"; }; - ACB0BA25EA85951D2A75CC62 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Path.cpp"; path = "../../JuceLibraryCode/modules/juce_graphics/geometry/juce_Path.cpp"; sourceTree = "SOURCE_ROOT"; }; - ACEF6D28EC9FB10B6C0D8EE0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_mac_CoreGraphicsContext.h"; path = "../../JuceLibraryCode/modules/juce_graphics/native/juce_mac_CoreGraphicsContext.h"; sourceTree = "SOURCE_ROOT"; }; - ACF10436974ED4510E3FC4BB = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioProcessorGraph.h"; path = "../../JuceLibraryCode/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h"; sourceTree = "SOURCE_ROOT"; }; - AD6517C175A8D9D5A9D168E6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MidiMessageCollector.h"; path = "../../JuceLibraryCode/modules/juce_audio_devices/midi_io/juce_MidiMessageCollector.h"; sourceTree = "SOURCE_ROOT"; }; + A6AD00FEFB31915AB0F2798F = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ComponentListener.h"; path = "../../../../modules/juce_gui_basics/components/juce_ComponentListener.h"; sourceTree = "SOURCE_ROOT"; }; + A76D6B94991D6E028EE8D1AA = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioFormat.cpp"; path = "../../../../modules/juce_audio_formats/format/juce_AudioFormat.cpp"; sourceTree = "SOURCE_ROOT"; }; + A782FF0CD79464F3E015647E = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_android_JNIHelpers.h"; path = "../../../../modules/juce_core/native/juce_android_JNIHelpers.h"; sourceTree = "SOURCE_ROOT"; }; + A7884EC24DD007D6232DB822 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_Windowing.mm"; path = "../../../../modules/juce_gui_basics/native/juce_mac_Windowing.mm"; sourceTree = "SOURCE_ROOT"; }; + A7B28AD8606992FBE04C527C = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_CodeDocument.cpp"; path = "../../../../modules/juce_gui_extra/code_editor/juce_CodeDocument.cpp"; sourceTree = "SOURCE_ROOT"; }; + A826C1C083678A4E9279C118 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_TreeView.cpp"; path = "../../../../modules/juce_gui_basics/widgets/juce_TreeView.cpp"; sourceTree = "SOURCE_ROOT"; }; + A8A277CAF10A3FEB258174C2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Typeface.h"; path = "../../../../modules/juce_graphics/fonts/juce_Typeface.h"; sourceTree = "SOURCE_ROOT"; }; + A8C570DF829A8B8581B4E8CC = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioProcessorGraph.h"; path = "../../../../modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h"; sourceTree = "SOURCE_ROOT"; }; + A917646C0153D2A57E3C5677 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MidiFile.h"; path = "../../../../modules/juce_audio_basics/midi/juce_MidiFile.h"; sourceTree = "SOURCE_ROOT"; }; + AAA3ED492FF78DBBF86DC612 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_win32_HiddenMessageWindow.h"; path = "../../../../modules/juce_events/native/juce_win32_HiddenMessageWindow.h"; sourceTree = "SOURCE_ROOT"; }; + AF59758C300E586A7A6338D1 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_PropertiesFile.h"; path = "../../../../modules/juce_data_structures/app_properties/juce_PropertiesFile.h"; sourceTree = "SOURCE_ROOT"; }; AF947B0E188B6EA57EB0109B = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; A748C987924800FDBA2E2184 = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = AnimationAppExample.app; sourceTree = "BUILT_PRODUCTS_DIR"; }; - AD6AAB2F586CBD4E35D5167B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MemoryBlock.cpp"; path = "../../JuceLibraryCode/modules/juce_core/memory/juce_MemoryBlock.cpp"; sourceTree = "SOURCE_ROOT"; }; - AD7F976713D7D3B057793A42 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Rectangle.h"; path = "../../JuceLibraryCode/modules/juce_graphics/geometry/juce_Rectangle.h"; sourceTree = "SOURCE_ROOT"; }; - AE7E18FE030834B289424681 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CallOutBox.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/windows/juce_CallOutBox.h"; sourceTree = "SOURCE_ROOT"; }; - AEB7028FB923A6FD7404A84C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MissingGLDefinitions.h"; path = "../../JuceLibraryCode/modules/juce_opengl/native/juce_MissingGLDefinitions.h"; sourceTree = "SOURCE_ROOT"; }; - AEEE72913C595DAE27F43ADC = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ChoicePropertyComponent.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/properties/juce_ChoicePropertyComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; - AFC498B17E8D5B122DB666C1 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ZipFile.cpp"; path = "../../JuceLibraryCode/modules/juce_core/zip/juce_ZipFile.cpp"; sourceTree = "SOURCE_ROOT"; }; - B035D33267C606674E58EE2B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Component.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/components/juce_Component.cpp"; sourceTree = "SOURCE_ROOT"; }; - B063E208C533148EDB5D4B91 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_BooleanPropertyComponent.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/properties/juce_BooleanPropertyComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; - B070645F1A6B85C679B77B21 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_AudioCDReader.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_devices/native/juce_linux_AudioCDReader.cpp"; sourceTree = "SOURCE_ROOT"; }; - B0793B0E00A1410BD054B141 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioIODevice.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_devices/audio_io/juce_AudioIODevice.cpp"; sourceTree = "SOURCE_ROOT"; }; - B08C35519C2E990041F82336 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_CameraDevice.cpp"; path = "../../JuceLibraryCode/modules/juce_video/capture/juce_CameraDevice.cpp"; sourceTree = "SOURCE_ROOT"; }; - B0CD0890EC1297C2C70B741B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MP3AudioFormat.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_formats/codecs/juce_MP3AudioFormat.cpp"; sourceTree = "SOURCE_ROOT"; }; - B14C06A5F45ACD5D93357F96 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MD5.h"; path = "../../JuceLibraryCode/modules/juce_cryptography/hashing/juce_MD5.h"; sourceTree = "SOURCE_ROOT"; }; - B17E7CF3B375FCC6A9178500 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_PluginDescription.h"; path = "../../JuceLibraryCode/modules/juce_audio_processors/processors/juce_PluginDescription.h"; sourceTree = "SOURCE_ROOT"; }; - B1F56F0DD4CC94FF8BB1FBE0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FileSearchPathListComponent.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/filebrowser/juce_FileSearchPathListComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; - B1FDA24AC0EF52652F3DB94E = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ScrollBar.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/layout/juce_ScrollBar.h"; sourceTree = "SOURCE_ROOT"; }; - B2E4733C1FB26F143C0C7344 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_KeyPressMappingSet.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/commands/juce_KeyPressMappingSet.cpp"; sourceTree = "SOURCE_ROOT"; }; - B2F561631B30711F78C118A0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FileChooser.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/filebrowser/juce_FileChooser.h"; sourceTree = "SOURCE_ROOT"; }; - B3669C5F60758B9D20E41583 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ActiveXControlComponent.h"; path = "../../JuceLibraryCode/modules/juce_gui_extra/embedding/juce_ActiveXControlComponent.h"; sourceTree = "SOURCE_ROOT"; }; - B3CFDC682EFECC45C4227288 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_RelativePoint.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/positioning/juce_RelativePoint.cpp"; sourceTree = "SOURCE_ROOT"; }; - B3D51DEA0DE311B017CAB716 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FileOutputStream.h"; path = "../../JuceLibraryCode/modules/juce_core/files/juce_FileOutputStream.h"; sourceTree = "SOURCE_ROOT"; }; - B3E93FD47ACA9498963C8A2C = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ValueTree.cpp"; path = "../../JuceLibraryCode/modules/juce_data_structures/values/juce_ValueTree.cpp"; sourceTree = "SOURCE_ROOT"; }; - B3EB470623EB09A867A9383E = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ScopedLock.h"; path = "../../JuceLibraryCode/modules/juce_core/threads/juce_ScopedLock.h"; sourceTree = "SOURCE_ROOT"; }; - B4554AB60F9524B82FAC071C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OpenGLExtensions.h"; path = "../../JuceLibraryCode/modules/juce_opengl/native/juce_OpenGLExtensions.h"; sourceTree = "SOURCE_ROOT"; }; - B45F7C71FC56F9DCEA7379FF = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AnimatedPositionBehaviours.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/layout/juce_AnimatedPositionBehaviours.h"; sourceTree = "SOURCE_ROOT"; }; - B4AFAA5A74A2E61F0196F4B8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DialogWindow.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/windows/juce_DialogWindow.cpp"; sourceTree = "SOURCE_ROOT"; }; - B4C612999A7FF20800CE507E = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ImageConvolutionKernel.h"; path = "../../JuceLibraryCode/modules/juce_graphics/images/juce_ImageConvolutionKernel.h"; sourceTree = "SOURCE_ROOT"; }; - B4D3C4A6929FB0068E61E5E7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_HyperlinkButton.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/buttons/juce_HyperlinkButton.cpp"; sourceTree = "SOURCE_ROOT"; }; - B4FF9DAF77F9CEFA8FFDA583 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FilenameComponent.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/filebrowser/juce_FilenameComponent.h"; sourceTree = "SOURCE_ROOT"; }; - B53B0352EAA432B0179F0201 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DynamicObject.h"; path = "../../JuceLibraryCode/modules/juce_core/containers/juce_DynamicObject.h"; sourceTree = "SOURCE_ROOT"; }; - B58C5A06F8D666BCB074D981 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OpenGLFrameBuffer.h"; path = "../../JuceLibraryCode/modules/juce_opengl/opengl/juce_OpenGLFrameBuffer.h"; sourceTree = "SOURCE_ROOT"; }; - B65CD1D011475424E927B37E = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Expression.cpp"; path = "../../JuceLibraryCode/modules/juce_core/maths/juce_Expression.cpp"; sourceTree = "SOURCE_ROOT"; }; - B68C18758AC0A7570E067015 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FileBasedDocument.h"; path = "../../JuceLibraryCode/modules/juce_gui_extra/documents/juce_FileBasedDocument.h"; sourceTree = "SOURCE_ROOT"; }; - B6B4BC87EEA6BFF7A739D118 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_data_structures.mm"; path = "../../JuceLibraryCode/modules/juce_data_structures/juce_data_structures.mm"; sourceTree = "SOURCE_ROOT"; }; - B6BB67F1186B3A3DB89DC02B = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_PathIterator.h"; path = "../../JuceLibraryCode/modules/juce_graphics/geometry/juce_PathIterator.h"; sourceTree = "SOURCE_ROOT"; }; - B71187E41B94D7913C1791AE = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Typeface.h"; path = "../../JuceLibraryCode/modules/juce_graphics/fonts/juce_Typeface.h"; sourceTree = "SOURCE_ROOT"; }; + A789D75FEFFFB7E8E835FBAB = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MidiMessageCollector.cpp"; path = "../../../../modules/juce_audio_devices/midi_io/juce_MidiMessageCollector.cpp"; sourceTree = "SOURCE_ROOT"; }; + A8CAB6FAB9BC1CC96FDE7BC2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_RenderingHelpers.h"; path = "../../../../modules/juce_graphics/native/juce_RenderingHelpers.h"; sourceTree = "SOURCE_ROOT"; }; + A95D718F031CB8883DFDE915 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ProgressBar.cpp"; path = "../../../../modules/juce_gui_basics/widgets/juce_ProgressBar.cpp"; sourceTree = "SOURCE_ROOT"; }; + A9608756E1A18BAFCC48A064 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_SpinLock.h"; path = "../../../../modules/juce_core/threads/juce_SpinLock.h"; sourceTree = "SOURCE_ROOT"; }; + A98EED399E310BF85EBBCE12 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OpenGLGraphicsContext.h"; path = "../../../../modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.h"; sourceTree = "SOURCE_ROOT"; }; + AA5CDD430B68BBE10A9026C5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Desktop.cpp"; path = "../../../../modules/juce_gui_basics/components/juce_Desktop.cpp"; sourceTree = "SOURCE_ROOT"; }; + AB3C130E565756182528752D = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AiffAudioFormat.cpp"; path = "../../../../modules/juce_audio_formats/codecs/juce_AiffAudioFormat.cpp"; sourceTree = "SOURCE_ROOT"; }; + AB856191A15A8C9016D974D5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MountedVolumeListChangeDetector.h"; path = "../../../../modules/juce_events/messages/juce_MountedVolumeListChangeDetector.h"; sourceTree = "SOURCE_ROOT"; }; + ABA2E1FE9912D5C28F177E56 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TextDragAndDropTarget.h"; path = "../../../../modules/juce_gui_basics/mouse/juce_TextDragAndDropTarget.h"; sourceTree = "SOURCE_ROOT"; }; + AC018F2C47CF57EB4A87AC36 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_WildcardFileFilter.h"; path = "../../../../modules/juce_core/files/juce_WildcardFileFilter.h"; sourceTree = "SOURCE_ROOT"; }; + AC2AE970951E20A199938AFB = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioDataConverters.cpp"; path = "../../../../modules/juce_audio_basics/buffers/juce_AudioDataConverters.cpp"; sourceTree = "SOURCE_ROOT"; }; + AC3184BE8D8804394FCCDCB6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MidiMessage.h"; path = "../../../../modules/juce_audio_basics/midi/juce_MidiMessage.h"; sourceTree = "SOURCE_ROOT"; }; + AC42B6006776E1CE3A3A94A0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Expression.h"; path = "../../../../modules/juce_core/maths/juce_Expression.h"; sourceTree = "SOURCE_ROOT"; }; + AC56A48CC01AABBE45F51970 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_Fonts.mm"; path = "../../../../modules/juce_graphics/native/juce_mac_Fonts.mm"; sourceTree = "SOURCE_ROOT"; }; + AC725293BD38E8C66E35EED3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_PropertySet.h"; path = "../../../../modules/juce_core/containers/juce_PropertySet.h"; sourceTree = "SOURCE_ROOT"; }; + ACAC59A1C54DC52E8E2438CC = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_CameraDevice.cpp"; path = "../../../../modules/juce_video/native/juce_win32_CameraDevice.cpp"; sourceTree = "SOURCE_ROOT"; }; + AD405DDE86D07F955E27EBF8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_audio_processors.mm"; path = "../../../../modules/juce_audio_processors/juce_audio_processors.mm"; sourceTree = "SOURCE_ROOT"; }; + AD41400898312123119E987A = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_BigInteger.h"; path = "../../../../modules/juce_core/maths/juce_BigInteger.h"; sourceTree = "SOURCE_ROOT"; }; + AD54DAEAB7840FC18DA65503 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_WebBrowserComponent.cpp"; path = "../../../../modules/juce_gui_extra/native/juce_linux_WebBrowserComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; + AD648ADDD885B93B2EB60C88 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioSampleBuffer.cpp"; path = "../../../../modules/juce_audio_basics/buffers/juce_AudioSampleBuffer.cpp"; sourceTree = "SOURCE_ROOT"; }; + AD8417869D43ED72319C283C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_BufferingAudioFormatReader.h"; path = "../../../../modules/juce_audio_formats/format/juce_BufferingAudioFormatReader.h"; sourceTree = "SOURCE_ROOT"; }; + ADCA2F92E2C17964A4AD750E = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ResizableBorderComponent.h"; path = "../../../../modules/juce_gui_basics/layout/juce_ResizableBorderComponent.h"; sourceTree = "SOURCE_ROOT"; }; + AE381B9D6E2A4DA363C7DD3F = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MessageListener.h"; path = "../../../../modules/juce_events/messages/juce_MessageListener.h"; sourceTree = "SOURCE_ROOT"; }; + AF885F6112CEA5C2D7934AA3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DirectoryIterator.h"; path = "../../../../modules/juce_core/files/juce_DirectoryIterator.h"; sourceTree = "SOURCE_ROOT"; }; + B004D25E0DC1AA2C4CD3788A = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MidiMessageCollector.h"; path = "../../../../modules/juce_audio_devices/midi_io/juce_MidiMessageCollector.h"; sourceTree = "SOURCE_ROOT"; }; + B0286AC6D04C5D080A299A1C = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_AudioCDReader.cpp"; path = "../../../../modules/juce_audio_devices/native/juce_linux_AudioCDReader.cpp"; sourceTree = "SOURCE_ROOT"; }; + B0589203065E4CF2C002B0D9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OpenGLHelpers.h"; path = "../../../../modules/juce_opengl/opengl/juce_OpenGLHelpers.h"; sourceTree = "SOURCE_ROOT"; }; + B0626D2C611D9E3DF1408BEA = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TextEditorKeyMapper.h"; path = "../../../../modules/juce_gui_basics/keyboard/juce_TextEditorKeyMapper.h"; sourceTree = "SOURCE_ROOT"; }; + B15DC22CA1E52983F4F57A9D = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_Threads.cpp"; path = "../../../../modules/juce_core/native/juce_linux_Threads.cpp"; sourceTree = "SOURCE_ROOT"; }; + B189762C440B38635351E0A3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Application.cpp"; path = "../../../../modules/juce_gui_basics/application/juce_Application.cpp"; sourceTree = "SOURCE_ROOT"; }; + B1A41C6141726A390E2182A2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_audio_devices.h"; path = "../../../../modules/juce_audio_devices/juce_audio_devices.h"; sourceTree = "SOURCE_ROOT"; }; + B1B7C62CA04ACBAC6CD1C2AD = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_KeyPress.h"; path = "../../../../modules/juce_gui_basics/keyboard/juce_KeyPress.h"; sourceTree = "SOURCE_ROOT"; }; + B1C799A152189A282E6CAC76 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_android_Midi.cpp"; path = "../../../../modules/juce_audio_devices/native/juce_android_Midi.cpp"; sourceTree = "SOURCE_ROOT"; }; + B28F34DD7CABFD48B1EE3CCE = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Random.h"; path = "../../../../modules/juce_core/maths/juce_Random.h"; sourceTree = "SOURCE_ROOT"; }; + B2D42B884600CE62E3253DA3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_DirectSound.cpp"; path = "../../../../modules/juce_audio_devices/native/juce_win32_DirectSound.cpp"; sourceTree = "SOURCE_ROOT"; }; + B305ACE053406FF288E500F8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_SubregionStream.cpp"; path = "../../../../modules/juce_core/streams/juce_SubregionStream.cpp"; sourceTree = "SOURCE_ROOT"; }; + B316291E570F37785C40FE88 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_RelativeParallelogram.cpp"; path = "../../../../modules/juce_gui_basics/positioning/juce_RelativeParallelogram.cpp"; sourceTree = "SOURCE_ROOT"; }; + B3261106892038D4F954E6F9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MouseCursor.h"; path = "../../../../modules/juce_gui_basics/mouse/juce_MouseCursor.h"; sourceTree = "SOURCE_ROOT"; }; + B32716A0B0702E6861726529 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ActionBroadcaster.cpp"; path = "../../../../modules/juce_events/broadcasters/juce_ActionBroadcaster.cpp"; sourceTree = "SOURCE_ROOT"; }; + B3FBDBEBC38720E957C15BE9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_LookAndFeel_V3.cpp"; path = "../../../../modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V3.cpp"; sourceTree = "SOURCE_ROOT"; }; + B401E96340B8AB5DE8CBF5C9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AnimatedAppComponent.cpp"; path = "../../../../modules/juce_gui_extra/misc/juce_AnimatedAppComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; + B409D881BE39C4704C94996C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ReadWriteLock.h"; path = "../../../../modules/juce_core/threads/juce_ReadWriteLock.h"; sourceTree = "SOURCE_ROOT"; }; + B471C2AB67E7C68D1C7D729D = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_PathIterator.cpp"; path = "../../../../modules/juce_graphics/geometry/juce_PathIterator.cpp"; sourceTree = "SOURCE_ROOT"; }; + B4769129853D2822D3DB38D1 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ApplicationProperties.h"; path = "../../../../modules/juce_data_structures/app_properties/juce_ApplicationProperties.h"; sourceTree = "SOURCE_ROOT"; }; + B5142BDA7EBA15F2DB1BB3FA = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ToneGeneratorAudioSource.cpp"; path = "../../../../modules/juce_audio_basics/sources/juce_ToneGeneratorAudioSource.cpp"; sourceTree = "SOURCE_ROOT"; }; + B54A14A497368A580B7D9AEB = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DrawableRectangle.cpp"; path = "../../../../modules/juce_gui_basics/drawables/juce_DrawableRectangle.cpp"; sourceTree = "SOURCE_ROOT"; }; + B57640F7EDADCFE17719EE68 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FileBrowserComponent.h"; path = "../../../../modules/juce_gui_basics/filebrowser/juce_FileBrowserComponent.h"; sourceTree = "SOURCE_ROOT"; }; + B5C3814B2174E5127F42D721 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioFormatWriter.cpp"; path = "../../../../modules/juce_audio_formats/format/juce_AudioFormatWriter.cpp"; sourceTree = "SOURCE_ROOT"; }; + B60524021E6FC59416222870 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OpenGLRenderer.h"; path = "../../../../modules/juce_opengl/opengl/juce_OpenGLRenderer.h"; sourceTree = "SOURCE_ROOT"; }; + B6173E37D15602163B7C0441 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioIODeviceType.cpp"; path = "../../../../modules/juce_audio_devices/audio_io/juce_AudioIODeviceType.cpp"; sourceTree = "SOURCE_ROOT"; }; + B6411B03A6D0185B11DBDA15 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioSourcePlayer.h"; path = "../../../../modules/juce_audio_devices/sources/juce_AudioSourcePlayer.h"; sourceTree = "SOURCE_ROOT"; }; + B6ABBE7782ECD38631EB11BC = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_PluginDescription.h"; path = "../../../../modules/juce_audio_processors/processors/juce_PluginDescription.h"; sourceTree = "SOURCE_ROOT"; }; + B6BE7EF02190070336E63E89 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_RectangleList.h"; path = "../../../../modules/juce_graphics/geometry/juce_RectangleList.h"; sourceTree = "SOURCE_ROOT"; }; + B6C7114A31FD6B1DEB08346F = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ResizableEdgeComponent.cpp"; path = "../../../../modules/juce_gui_basics/layout/juce_ResizableEdgeComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; + B6D9BF4B75784D01B7CDE1AF = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Timer.cpp"; path = "../../../../modules/juce_events/timers/juce_Timer.cpp"; sourceTree = "SOURCE_ROOT"; }; + B70E52FF75D44F0F1F0B31D2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ToolbarButton.h"; path = "../../../../modules/juce_gui_basics/buttons/juce_ToolbarButton.h"; sourceTree = "SOURCE_ROOT"; }; B766DBADE0BD743FAC004870 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = MainComponent.cpp; path = ../../Source/MainComponent.cpp; sourceTree = "SOURCE_ROOT"; }; - B78FA8958102108085ABE489 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_WavAudioFormat.h"; path = "../../JuceLibraryCode/modules/juce_audio_formats/codecs/juce_WavAudioFormat.h"; sourceTree = "SOURCE_ROOT"; }; - B79DB0C1AA34A90D1F3E012B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_StretchableObjectResizer.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/layout/juce_StretchableObjectResizer.cpp"; sourceTree = "SOURCE_ROOT"; }; - B7EA4F63CADAB5B31D3D985F = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Slider.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/widgets/juce_Slider.cpp"; sourceTree = "SOURCE_ROOT"; }; - B7F1AB21699A5EEEA59DA2AD = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_KeyMappingEditorComponent.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_extra/misc/juce_KeyMappingEditorComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; - B852DBE7C0AFD11AB872754A = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioPlayHead.h"; path = "../../JuceLibraryCode/modules/juce_audio_processors/processors/juce_AudioPlayHead.h"; sourceTree = "SOURCE_ROOT"; }; - B87D578105925ED8FFC105AE = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OpenGLContext.h"; path = "../../JuceLibraryCode/modules/juce_opengl/opengl/juce_OpenGLContext.h"; sourceTree = "SOURCE_ROOT"; }; - B8DF17DE3A37A52E3514A492 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Colour.cpp"; path = "../../JuceLibraryCode/modules/juce_graphics/colour/juce_Colour.cpp"; sourceTree = "SOURCE_ROOT"; }; - B973B2A075C1EE23F2AEFF32 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioProcessor.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_processors/processors/juce_AudioProcessor.cpp"; sourceTree = "SOURCE_ROOT"; }; - B989CEE19057D31C6D521BBC = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_ios_MessageManager.mm"; path = "../../JuceLibraryCode/modules/juce_events/native/juce_ios_MessageManager.mm"; sourceTree = "SOURCE_ROOT"; }; - B9D557438E309657EB68CF7D = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_DirectWriteTypeLayout.cpp"; path = "../../JuceLibraryCode/modules/juce_graphics/native/juce_win32_DirectWriteTypeLayout.cpp"; sourceTree = "SOURCE_ROOT"; }; - BA97D0B8F59B68F245351F01 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ActionBroadcaster.cpp"; path = "../../JuceLibraryCode/modules/juce_events/broadcasters/juce_ActionBroadcaster.cpp"; sourceTree = "SOURCE_ROOT"; }; - BB586BA19ADC508119BF86CC = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TextEditorKeyMapper.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/keyboard/juce_TextEditorKeyMapper.h"; sourceTree = "SOURCE_ROOT"; }; - BBF1A328A57B8CA11F40D3B0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_opengl.h"; path = "../../JuceLibraryCode/modules/juce_opengl/juce_opengl.h"; sourceTree = "SOURCE_ROOT"; }; - BBF610446898623948599114 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Random.h"; path = "../../JuceLibraryCode/modules/juce_core/maths/juce_Random.h"; sourceTree = "SOURCE_ROOT"; }; - BC3EB76C434A2FDAC6C46DB2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_audio_formats.mm"; path = "../../JuceLibraryCode/modules/juce_audio_formats/juce_audio_formats.mm"; sourceTree = "SOURCE_ROOT"; }; - BC57385BADED3932DB3714EF = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_RelativeParallelogram.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/positioning/juce_RelativeParallelogram.h"; sourceTree = "SOURCE_ROOT"; }; - BCC1C92B775AEA802A0AC917 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CriticalSection.h"; path = "../../JuceLibraryCode/modules/juce_core/threads/juce_CriticalSection.h"; sourceTree = "SOURCE_ROOT"; }; - BCE1A7250DC27CE2B297B999 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_StretchableLayoutManager.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/layout/juce_StretchableLayoutManager.h"; sourceTree = "SOURCE_ROOT"; }; - BCE458AC1B9E30F85B443851 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_Windowing.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/native/juce_win32_Windowing.cpp"; sourceTree = "SOURCE_ROOT"; }; - BCE6AF6A2A5E7156836E5E7F = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ApplicationCommandTarget.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/commands/juce_ApplicationCommandTarget.h"; sourceTree = "SOURCE_ROOT"; }; - BD2B30F77B968E717E713124 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_TabbedButtonBar.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/layout/juce_TabbedButtonBar.cpp"; sourceTree = "SOURCE_ROOT"; }; - BD455C126781EDA150C9298B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_Threads.mm"; path = "../../JuceLibraryCode/modules/juce_core/native/juce_mac_Threads.mm"; sourceTree = "SOURCE_ROOT"; }; - BE22F0B06CBFF0C62A317CAC = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MenuBarModel.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/menus/juce_MenuBarModel.h"; sourceTree = "SOURCE_ROOT"; }; - BE24FC2B4C9D80DC8DC99BC2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_LookAndFeel_V2.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V2.h"; sourceTree = "SOURCE_ROOT"; }; - BE80DA6D586BB1C790B345E2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_XMLCodeTokeniser.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_extra/code_editor/juce_XMLCodeTokeniser.cpp"; sourceTree = "SOURCE_ROOT"; }; - BE990C63B85752BF968C5EC6 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_module_info"; path = "../../JuceLibraryCode/modules/juce_audio_basics/juce_module_info"; sourceTree = "SOURCE_ROOT"; }; - BEDA74674128EDC35C5CCAC0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_KeyPress.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/keyboard/juce_KeyPress.cpp"; sourceTree = "SOURCE_ROOT"; }; - BF64F4ED5DF12FFF99C826AB = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MessageManager.cpp"; path = "../../JuceLibraryCode/modules/juce_events/messages/juce_MessageManager.cpp"; sourceTree = "SOURCE_ROOT"; }; - BFB2A78106121AE2F199055C = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DeletedAtShutdown.cpp"; path = "../../JuceLibraryCode/modules/juce_events/messages/juce_DeletedAtShutdown.cpp"; sourceTree = "SOURCE_ROOT"; }; - BFC021DD9267F5F0D2D2D58D = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_LookAndFeel_V1.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V1.cpp"; sourceTree = "SOURCE_ROOT"; }; - C00122D03A9B2BE3E4ECBE4E = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_android_GraphicsContext.cpp"; path = "../../JuceLibraryCode/modules/juce_graphics/native/juce_android_GraphicsContext.cpp"; sourceTree = "SOURCE_ROOT"; }; - C12AEDA7D0BE5A220AF9D30A = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_StringPairArray.h"; path = "../../JuceLibraryCode/modules/juce_core/text/juce_StringPairArray.h"; sourceTree = "SOURCE_ROOT"; }; - C1505EA2417265BC59135075 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_RelativePointPath.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/positioning/juce_RelativePointPath.h"; sourceTree = "SOURCE_ROOT"; }; - C18E1D4D4D0E4F6B0525C212 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OptionalScopedPointer.h"; path = "../../JuceLibraryCode/modules/juce_core/memory/juce_OptionalScopedPointer.h"; sourceTree = "SOURCE_ROOT"; }; - C1C5A9F18F63CDB9BDF32177 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MidiBuffer.h"; path = "../../JuceLibraryCode/modules/juce_audio_basics/midi/juce_MidiBuffer.h"; sourceTree = "SOURCE_ROOT"; }; - C2375B75F67BAAA9813EEC2B = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ChoicePropertyComponent.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/properties/juce_ChoicePropertyComponent.h"; sourceTree = "SOURCE_ROOT"; }; - C3B0389DB7042B45EFC751AC = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Slider.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/widgets/juce_Slider.h"; sourceTree = "SOURCE_ROOT"; }; - C42F2CE5B179094CEF9786C1 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TextPropertyComponent.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/properties/juce_TextPropertyComponent.h"; sourceTree = "SOURCE_ROOT"; }; - C44BCD4A16768A91B02EE14C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_WindowsRegistry.h"; path = "../../JuceLibraryCode/modules/juce_core/misc/juce_WindowsRegistry.h"; sourceTree = "SOURCE_ROOT"; }; - C46FC2DAD97DA825D6449A2B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_String.cpp"; path = "../../JuceLibraryCode/modules/juce_core/text/juce_String.cpp"; sourceTree = "SOURCE_ROOT"; }; - C56154402FC7B2983160C3E3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ComponentBuilder.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/layout/juce_ComponentBuilder.cpp"; sourceTree = "SOURCE_ROOT"; }; - C57F2A4DB4E9E55D5017A33F = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_FileChooser.mm"; path = "../../JuceLibraryCode/modules/juce_gui_basics/native/juce_mac_FileChooser.mm"; sourceTree = "SOURCE_ROOT"; }; - C5D7E8FD3897F200069DAF62 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_module_info"; path = "../../JuceLibraryCode/modules/juce_data_structures/juce_module_info"; sourceTree = "SOURCE_ROOT"; }; - C609197710C7E8DF361C4556 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Variant.h"; path = "../../JuceLibraryCode/modules/juce_core/containers/juce_Variant.h"; sourceTree = "SOURCE_ROOT"; }; - C6111F5E51935A78B357FE2E = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_BufferingAudioFormatReader.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_formats/format/juce_BufferingAudioFormatReader.cpp"; sourceTree = "SOURCE_ROOT"; }; - C61D46855CAEF3FB4547909B = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FileChooserDialogBox.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/filebrowser/juce_FileChooserDialogBox.h"; sourceTree = "SOURCE_ROOT"; }; - C67D83EB019C2F931E5FF290 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MidiMessage.h"; path = "../../JuceLibraryCode/modules/juce_audio_basics/midi/juce_MidiMessage.h"; sourceTree = "SOURCE_ROOT"; }; - C70A847D3C9EDEFE5B57C1AC = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_StretchableLayoutResizerBar.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/layout/juce_StretchableLayoutResizerBar.h"; sourceTree = "SOURCE_ROOT"; }; - C7B2F4323D69615085F4A633 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ResizableWindow.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/windows/juce_ResizableWindow.cpp"; sourceTree = "SOURCE_ROOT"; }; - C8541CD950B7AB83AECF39E4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ModifierKeys.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/keyboard/juce_ModifierKeys.h"; sourceTree = "SOURCE_ROOT"; }; - C856D47E76BE017D87E77496 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_WavAudioFormat.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_formats/codecs/juce_WavAudioFormat.cpp"; sourceTree = "SOURCE_ROOT"; }; - C8915F6AB7855AF370A5581B = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OpenGLRenderer.h"; path = "../../JuceLibraryCode/modules/juce_opengl/opengl/juce_OpenGLRenderer.h"; sourceTree = "SOURCE_ROOT"; }; - C8A93F28EB0AE4F99767EE47 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_Threads.cpp"; path = "../../JuceLibraryCode/modules/juce_core/native/juce_win32_Threads.cpp"; sourceTree = "SOURCE_ROOT"; }; - C8AFE60B7174C0006C1C85F3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_Network.mm"; path = "../../JuceLibraryCode/modules/juce_core/native/juce_mac_Network.mm"; sourceTree = "SOURCE_ROOT"; }; - C920268F5AAE587A04131F34 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_RelativeTime.h"; path = "../../JuceLibraryCode/modules/juce_core/time/juce_RelativeTime.h"; sourceTree = "SOURCE_ROOT"; }; - C97E9F209C271E901D31304E = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MessageManager.h"; path = "../../JuceLibraryCode/modules/juce_events/messages/juce_MessageManager.h"; sourceTree = "SOURCE_ROOT"; }; - C98926DCE80A0B3149961D0F = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_Files.mm"; path = "../../JuceLibraryCode/modules/juce_core/native/juce_mac_Files.mm"; sourceTree = "SOURCE_ROOT"; }; - C989EB89ACD3E1E5122BDBAD = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_DirectShowComponent.cpp"; path = "../../JuceLibraryCode/modules/juce_video/native/juce_win32_DirectShowComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; - C98FF9CD6E5BC931F600A73D = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioFormatReader.h"; path = "../../JuceLibraryCode/modules/juce_audio_formats/format/juce_AudioFormatReader.h"; sourceTree = "SOURCE_ROOT"; }; - CAF194AB75BBCF7A63DFDA43 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioProcessorEditor.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_processors/processors/juce_AudioProcessorEditor.cpp"; sourceTree = "SOURCE_ROOT"; }; - CB04786710DE206E794D272F = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_WebBrowserComponent.mm"; path = "../../JuceLibraryCode/modules/juce_gui_extra/native/juce_mac_WebBrowserComponent.mm"; sourceTree = "SOURCE_ROOT"; }; - CB3D07088AB905BD96AD3A90 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_audio_processors.mm"; path = "../../JuceLibraryCode/modules/juce_audio_processors/juce_audio_processors.mm"; sourceTree = "SOURCE_ROOT"; }; - CBE0FA629B5B2B352EFF53D4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_LAMEEncoderAudioFormat.h"; path = "../../JuceLibraryCode/modules/juce_audio_formats/codecs/juce_LAMEEncoderAudioFormat.h"; sourceTree = "SOURCE_ROOT"; }; - CC464EB86E0DE492BEFC7237 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ComponentDragger.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/mouse/juce_ComponentDragger.h"; sourceTree = "SOURCE_ROOT"; }; - CC726694653F832354878239 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FileBrowserListener.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/filebrowser/juce_FileBrowserListener.h"; sourceTree = "SOURCE_ROOT"; }; - CCD5CC6545DB9D9FFBB99D46 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_module_info"; path = "../../JuceLibraryCode/modules/juce_core/juce_module_info"; sourceTree = "SOURCE_ROOT"; }; - CDDD5A437DEFD1CD65160A9C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MidiFile.h"; path = "../../JuceLibraryCode/modules/juce_audio_basics/midi/juce_MidiFile.h"; sourceTree = "SOURCE_ROOT"; }; - CE696F8D455A2C2D1B8051FB = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MarkerList.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/positioning/juce_MarkerList.cpp"; sourceTree = "SOURCE_ROOT"; }; - CEB12E3A853DD633CD5F3AFB = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Component.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/components/juce_Component.h"; sourceTree = "SOURCE_ROOT"; }; - CEE91A9F1C74260FAC3E30A0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ActionListener.h"; path = "../../JuceLibraryCode/modules/juce_events/broadcasters/juce_ActionListener.h"; sourceTree = "SOURCE_ROOT"; }; - CF768CC6E2EA5664519C1C03 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Process.h"; path = "../../JuceLibraryCode/modules/juce_core/threads/juce_Process.h"; sourceTree = "SOURCE_ROOT"; }; - CFB26A1C32F851E8DDC36BB7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MidiKeyboardState.h"; path = "../../JuceLibraryCode/modules/juce_audio_basics/midi/juce_MidiKeyboardState.h"; sourceTree = "SOURCE_ROOT"; }; - D00090B2DE234305128AB650 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_XmlElement.cpp"; path = "../../JuceLibraryCode/modules/juce_core/xml/juce_XmlElement.cpp"; sourceTree = "SOURCE_ROOT"; }; - D0197C6B54D5A5B8AB15A230 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OpenGLHelpers.h"; path = "../../JuceLibraryCode/modules/juce_opengl/opengl/juce_OpenGLHelpers.h"; sourceTree = "SOURCE_ROOT"; }; - D03AA7DD0628031F75231425 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TooltipWindow.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/windows/juce_TooltipWindow.h"; sourceTree = "SOURCE_ROOT"; }; - D06C2B0C19461F7AA18914A8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MouseListener.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/mouse/juce_MouseListener.h"; sourceTree = "SOURCE_ROOT"; }; - D07A1E2DA76EA9CFBC9E3133 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CodeDocument.h"; path = "../../JuceLibraryCode/modules/juce_gui_extra/code_editor/juce_CodeDocument.h"; sourceTree = "SOURCE_ROOT"; }; - D0D385C5D99B9D9A90C00458 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TabbedComponent.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/layout/juce_TabbedComponent.h"; sourceTree = "SOURCE_ROOT"; }; - D0D3C2CBD0363F82E5D9B092 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CompilerSupport.h"; path = "../../JuceLibraryCode/modules/juce_core/system/juce_CompilerSupport.h"; sourceTree = "SOURCE_ROOT"; }; - D18648E47B5447E1F6AEEA52 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_OutputStream.cpp"; path = "../../JuceLibraryCode/modules/juce_core/streams/juce_OutputStream.cpp"; sourceTree = "SOURCE_ROOT"; }; - D18690CB0E643C9A642F73A6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Image.h"; path = "../../JuceLibraryCode/modules/juce_graphics/images/juce_Image.h"; sourceTree = "SOURCE_ROOT"; }; - D214FC393B8C9A379FE3C6CE = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_NamedPipe.h"; path = "../../JuceLibraryCode/modules/juce_core/network/juce_NamedPipe.h"; sourceTree = "SOURCE_ROOT"; }; - D23D5618C7FFFCFD938CD5F1 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_LagrangeInterpolator.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_basics/effects/juce_LagrangeInterpolator.cpp"; sourceTree = "SOURCE_ROOT"; }; - D2BC39EF5E34ACB2BE05539C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CoreAudioFormat.h"; path = "../../JuceLibraryCode/modules/juce_audio_formats/codecs/juce_CoreAudioFormat.h"; sourceTree = "SOURCE_ROOT"; }; - D37E99EBDA572556CA60B942 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ComponentMovementWatcher.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/layout/juce_ComponentMovementWatcher.cpp"; sourceTree = "SOURCE_ROOT"; }; - D3C91BB5D97D3CD7411D718B = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_win32_ComSmartPtr.h"; path = "../../JuceLibraryCode/modules/juce_core/native/juce_win32_ComSmartPtr.h"; sourceTree = "SOURCE_ROOT"; }; - D3DAA92A27A10FBB1AEC0966 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_VST3PluginFormat.h"; path = "../../JuceLibraryCode/modules/juce_audio_processors/format_types/juce_VST3PluginFormat.h"; sourceTree = "SOURCE_ROOT"; }; - D429E0F29213E9058DED8ECC = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ResamplingAudioSource.h"; path = "../../JuceLibraryCode/modules/juce_audio_basics/sources/juce_ResamplingAudioSource.h"; sourceTree = "SOURCE_ROOT"; }; - D4D9555F85A739252C027F45 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Timer.h"; path = "../../JuceLibraryCode/modules/juce_events/timers/juce_Timer.h"; sourceTree = "SOURCE_ROOT"; }; - D4EE8C83FA9A3BB53AA747C0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_KeyPressMappingSet.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/commands/juce_KeyPressMappingSet.h"; sourceTree = "SOURCE_ROOT"; }; - D4FD4193ACDA02D2C3D8B5D6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_QuickTimeMovieComponent.mm"; path = "../../JuceLibraryCode/modules/juce_video/native/juce_mac_QuickTimeMovieComponent.mm"; sourceTree = "SOURCE_ROOT"; }; - D528C603E1870E0BC562CB9D = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_Files.cpp"; path = "../../JuceLibraryCode/modules/juce_core/native/juce_win32_Files.cpp"; sourceTree = "SOURCE_ROOT"; }; - D535D69439B72C799B61DD37 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MathsFunctions.h"; path = "../../JuceLibraryCode/modules/juce_core/maths/juce_MathsFunctions.h"; sourceTree = "SOURCE_ROOT"; }; - D56619E400C7A4619515AFFA = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_SharedResourcePointer.h"; path = "../../JuceLibraryCode/modules/juce_core/memory/juce_SharedResourcePointer.h"; sourceTree = "SOURCE_ROOT"; }; - D568CB3943835ADB2613AEF8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Logger.cpp"; path = "../../JuceLibraryCode/modules/juce_core/logging/juce_Logger.cpp"; sourceTree = "SOURCE_ROOT"; }; - D56DEA7CACE4A86351CDDD5B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_OpenGLTexture.cpp"; path = "../../JuceLibraryCode/modules/juce_opengl/opengl/juce_OpenGLTexture.cpp"; sourceTree = "SOURCE_ROOT"; }; - D61ABCB4D785A183EB967AE7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TargetPlatform.h"; path = "../../JuceLibraryCode/modules/juce_core/system/juce_TargetPlatform.h"; sourceTree = "SOURCE_ROOT"; }; - D6486972C28234B51D512700 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ArrayAllocationBase.h"; path = "../../JuceLibraryCode/modules/juce_core/containers/juce_ArrayAllocationBase.h"; sourceTree = "SOURCE_ROOT"; }; - D65828A1160764381EC4A290 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OpenGLAppComponent.h"; path = "../../JuceLibraryCode/modules/juce_opengl/utils/juce_OpenGLAppComponent.h"; sourceTree = "SOURCE_ROOT"; }; - D69079E0065151480B46F7B7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FileInputStream.h"; path = "../../JuceLibraryCode/modules/juce_core/files/juce_FileInputStream.h"; sourceTree = "SOURCE_ROOT"; }; - D6ECAE5B0CC40752D559ABC4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_DragAndDrop.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/native/juce_win32_DragAndDrop.cpp"; sourceTree = "SOURCE_ROOT"; }; - D720150F1F3647538D037677 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_SystemStats.cpp"; path = "../../JuceLibraryCode/modules/juce_core/native/juce_linux_SystemStats.cpp"; sourceTree = "SOURCE_ROOT"; }; - D728D4777A842A58EC01454A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_cryptography.mm"; path = "../../JuceLibraryCode/modules/juce_cryptography/juce_cryptography.mm"; sourceTree = "SOURCE_ROOT"; }; - D786D6FB9787CEC730CFEDD9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioSource.h"; path = "../../JuceLibraryCode/modules/juce_audio_basics/sources/juce_AudioSource.h"; sourceTree = "SOURCE_ROOT"; }; - D7996C2834C1EE0DAC4BAEDA = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TextButton.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/buttons/juce_TextButton.h"; sourceTree = "SOURCE_ROOT"; }; - D79EAA241B5FA1ECFB84614F = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_LocalisedStrings.h"; path = "../../JuceLibraryCode/modules/juce_core/text/juce_LocalisedStrings.h"; sourceTree = "SOURCE_ROOT"; }; - D7D4E1A29E0B3A33814C7EBF = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_GIFLoader.cpp"; path = "../../JuceLibraryCode/modules/juce_graphics/image_formats/juce_GIFLoader.cpp"; sourceTree = "SOURCE_ROOT"; }; - D8AEA877A6200E6793A56B81 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DirectoryContentsDisplayComponent.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/filebrowser/juce_DirectoryContentsDisplayComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; - D9108E2655D2E4403A4B598A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_RelativeParallelogram.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/positioning/juce_RelativeParallelogram.cpp"; sourceTree = "SOURCE_ROOT"; }; - D97C2B6C906C1C179598C7CC = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_LADSPAPluginFormat.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_processors/format_types/juce_LADSPAPluginFormat.cpp"; sourceTree = "SOURCE_ROOT"; }; - DA088C27651F40F29163E0C2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MouseCursor.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/mouse/juce_MouseCursor.h"; sourceTree = "SOURCE_ROOT"; }; - DA41E1FA66C5B7218625EC70 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_SystemTrayIconComponent.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_extra/misc/juce_SystemTrayIconComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; - DA42AA71E4D47975E018BED0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_CaretComponent.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/keyboard/juce_CaretComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; - DA54722A7C1A958B80B9D10A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_GlyphArrangement.cpp"; path = "../../JuceLibraryCode/modules/juce_graphics/fonts/juce_GlyphArrangement.cpp"; sourceTree = "SOURCE_ROOT"; }; - DA93B8704F3EC4703E2B2DC2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MultiTimer.h"; path = "../../JuceLibraryCode/modules/juce_events/timers/juce_MultiTimer.h"; sourceTree = "SOURCE_ROOT"; }; - DAA6196510C04172905A6BA2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MultiDocumentPanel.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/layout/juce_MultiDocumentPanel.cpp"; sourceTree = "SOURCE_ROOT"; }; - DC078E6D148F784C9843BD8A = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_RelativeCoordinatePositioner.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/positioning/juce_RelativeCoordinatePositioner.h"; sourceTree = "SOURCE_ROOT"; }; - DC4D885D7F7F573E42E13F65 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ToolbarButton.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/buttons/juce_ToolbarButton.h"; sourceTree = "SOURCE_ROOT"; }; - DC4F26260A712654A80A2FF5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_SystemStats.cpp"; path = "../../JuceLibraryCode/modules/juce_core/native/juce_win32_SystemStats.cpp"; sourceTree = "SOURCE_ROOT"; }; - DD4F1D5C6CAD9CEA86F83209 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DrawableRectangle.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/drawables/juce_DrawableRectangle.cpp"; sourceTree = "SOURCE_ROOT"; }; - DDB38AD7F6C5A2E5E3725288 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OpenGLGraphicsContext.h"; path = "../../JuceLibraryCode/modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.h"; sourceTree = "SOURCE_ROOT"; }; - DE3E98A6DCCBE1F461E46E79 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_freetype_Fonts.cpp"; path = "../../JuceLibraryCode/modules/juce_graphics/native/juce_freetype_Fonts.cpp"; sourceTree = "SOURCE_ROOT"; }; - DE41FE4DADD07963905B82D0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CaretComponent.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/keyboard/juce_CaretComponent.h"; sourceTree = "SOURCE_ROOT"; }; - DE48404D34F2CAE314CA4E19 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_XmlDocument.h"; path = "../../JuceLibraryCode/modules/juce_core/xml/juce_XmlDocument.h"; sourceTree = "SOURCE_ROOT"; }; - DE579AF9E1C7F5EA0B7A87A3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_GZIPDecompressorInputStream.h"; path = "../../JuceLibraryCode/modules/juce_core/zip/juce_GZIPDecompressorInputStream.h"; sourceTree = "SOURCE_ROOT"; }; - DE9CB3573085CEA391B49650 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_KeyboardFocusTraverser.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/keyboard/juce_KeyboardFocusTraverser.cpp"; sourceTree = "SOURCE_ROOT"; }; - DECB3C3714353AE5775147AD = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_TemporaryFile.cpp"; path = "../../JuceLibraryCode/modules/juce_core/files/juce_TemporaryFile.cpp"; sourceTree = "SOURCE_ROOT"; }; - DF7A0D14EC237709BAFE9224 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_PixelFormats.h"; path = "../../JuceLibraryCode/modules/juce_graphics/colour/juce_PixelFormats.h"; sourceTree = "SOURCE_ROOT"; }; - DF99FBC1355728976531AD5D = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_WindowsMediaAudioFormat.h"; path = "../../JuceLibraryCode/modules/juce_audio_formats/codecs/juce_WindowsMediaAudioFormat.h"; sourceTree = "SOURCE_ROOT"; }; - DFD3944531485F2F72ECB87A = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioCDReader.h"; path = "../../JuceLibraryCode/modules/juce_audio_devices/audio_cd/juce_AudioCDReader.h"; sourceTree = "SOURCE_ROOT"; }; - E09382FAC0496CC7B1A70087 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DirectoryContentsList.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/filebrowser/juce_DirectoryContentsList.cpp"; sourceTree = "SOURCE_ROOT"; }; - E0D15D4DE8EC3E536812D4FD = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MenuBarModel.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/menus/juce_MenuBarModel.cpp"; sourceTree = "SOURCE_ROOT"; }; - E0DFDD144675EF457B607E50 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AbstractFifo.h"; path = "../../JuceLibraryCode/modules/juce_core/containers/juce_AbstractFifo.h"; sourceTree = "SOURCE_ROOT"; }; - E105D3381CAF5006058DF2FD = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_RelativeCoordinatePositioner.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/positioning/juce_RelativeCoordinatePositioner.cpp"; sourceTree = "SOURCE_ROOT"; }; - E15C23EFF754E1289CE5437C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_GZIPCompressorOutputStream.h"; path = "../../JuceLibraryCode/modules/juce_core/zip/juce_GZIPCompressorOutputStream.h"; sourceTree = "SOURCE_ROOT"; }; - E15E5A1710E50FAB897B4310 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ColourGradient.h"; path = "../../JuceLibraryCode/modules/juce_graphics/colour/juce_ColourGradient.h"; sourceTree = "SOURCE_ROOT"; }; - E16F860A9AA000E590BE321A = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_BasicNativeHeaders.h"; path = "../../JuceLibraryCode/modules/juce_core/native/juce_BasicNativeHeaders.h"; sourceTree = "SOURCE_ROOT"; }; - E19A17B7DFC2E18AFC90946E = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ValueTree.h"; path = "../../JuceLibraryCode/modules/juce_data_structures/values/juce_ValueTree.h"; sourceTree = "SOURCE_ROOT"; }; - E22876603667D88857CA5179 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MidiKeyboardState.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_basics/midi/juce_MidiKeyboardState.cpp"; sourceTree = "SOURCE_ROOT"; }; - E27B4C86E077374F4C5E0F02 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DragAndDropContainer.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/mouse/juce_DragAndDropContainer.h"; sourceTree = "SOURCE_ROOT"; }; - E2940D3353B79053D215093F = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_android_Windowing.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/native/juce_android_Windowing.cpp"; sourceTree = "SOURCE_ROOT"; }; - E34E03B67A82E30F5CD201BF = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ReadWriteLock.h"; path = "../../JuceLibraryCode/modules/juce_core/threads/juce_ReadWriteLock.h"; sourceTree = "SOURCE_ROOT"; }; - E3699DD1D681C7B65A9348C5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MouseInputSource.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/mouse/juce_MouseInputSource.h"; sourceTree = "SOURCE_ROOT"; }; - E39FB683ECD1152137E3853A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioPluginFormatManager.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_processors/format/juce_AudioPluginFormatManager.cpp"; sourceTree = "SOURCE_ROOT"; }; - E3DF0709DECF7FB19A8DBB11 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TreeView.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/widgets/juce_TreeView.h"; sourceTree = "SOURCE_ROOT"; }; - E462CDCA6635D111D6B85C4B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioProcessorGraph.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.cpp"; sourceTree = "SOURCE_ROOT"; }; - E508FDD5269C63F7D0E08E48 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AbstractFifo.cpp"; path = "../../JuceLibraryCode/modules/juce_core/containers/juce_AbstractFifo.cpp"; sourceTree = "SOURCE_ROOT"; }; - E5608726D3CC8DDCA57635BF = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_SparseSet.h"; path = "../../JuceLibraryCode/modules/juce_core/containers/juce_SparseSet.h"; sourceTree = "SOURCE_ROOT"; }; - E63BC85590BE7258F35FA46F = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_LowLevelGraphicsSoftwareRenderer.h"; path = "../../JuceLibraryCode/modules/juce_graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.h"; sourceTree = "SOURCE_ROOT"; }; - E670FE5F095BB2B7F9EB8138 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ChannelRemappingAudioSource.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_basics/sources/juce_ChannelRemappingAudioSource.cpp"; sourceTree = "SOURCE_ROOT"; }; - E7733DCA05641E94C0714362 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ScopedPointer.h"; path = "../../JuceLibraryCode/modules/juce_core/memory/juce_ScopedPointer.h"; sourceTree = "SOURCE_ROOT"; }; - E782C5F53BBED225CABF6587 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioDeviceManager.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_devices/audio_io/juce_AudioDeviceManager.cpp"; sourceTree = "SOURCE_ROOT"; }; - E783E1B6AEFF256939443D39 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_String.h"; path = "../../JuceLibraryCode/modules/juce_core/text/juce_String.h"; sourceTree = "SOURCE_ROOT"; }; - E7B310562519AC9C1FA14CB1 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_GraphicsContext.h"; path = "../../JuceLibraryCode/modules/juce_graphics/contexts/juce_GraphicsContext.h"; sourceTree = "SOURCE_ROOT"; }; - E7C5065D5E153DFF6308D5F3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CharPointer_UTF8.h"; path = "../../JuceLibraryCode/modules/juce_core/text/juce_CharPointer_UTF8.h"; sourceTree = "SOURCE_ROOT"; }; - E7DC2D13A73F3CDA652C9DF5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_BufferedInputStream.cpp"; path = "../../JuceLibraryCode/modules/juce_core/streams/juce_BufferedInputStream.cpp"; sourceTree = "SOURCE_ROOT"; }; - E7E06147F43FCAE8D5B20BAB = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ComponentBoundsConstrainer.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/layout/juce_ComponentBoundsConstrainer.h"; sourceTree = "SOURCE_ROOT"; }; - E8E4F93EF596101FE5333018 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_audio_formats.h"; path = "../../JuceLibraryCode/modules/juce_audio_formats/juce_audio_formats.h"; sourceTree = "SOURCE_ROOT"; }; - E90A5D53778BE390A04B8D30 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ResizableEdgeComponent.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/layout/juce_ResizableEdgeComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; - E965D6B8815E3C5E8A160C48 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FileLogger.h"; path = "../../JuceLibraryCode/modules/juce_core/logging/juce_FileLogger.h"; sourceTree = "SOURCE_ROOT"; }; - E9E6FADE6A6F0B00452C0AD6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_Windowing.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/native/juce_linux_Windowing.cpp"; sourceTree = "SOURCE_ROOT"; }; - E9F7C31F43B7F22018E8170D = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_URL.cpp"; path = "../../JuceLibraryCode/modules/juce_core/network/juce_URL.cpp"; sourceTree = "SOURCE_ROOT"; }; - EA14E79A40FE2177626ADD79 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OpenGLShaderProgram.h"; path = "../../JuceLibraryCode/modules/juce_opengl/opengl/juce_OpenGLShaderProgram.h"; sourceTree = "SOURCE_ROOT"; }; - EA269A07CD83E9F5977889E6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FloatVectorOperations.h"; path = "../../JuceLibraryCode/modules/juce_audio_basics/buffers/juce_FloatVectorOperations.h"; sourceTree = "SOURCE_ROOT"; }; - EB3E426C5FF655F7AD88D843 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioSubsectionReader.h"; path = "../../JuceLibraryCode/modules/juce_audio_formats/format/juce_AudioSubsectionReader.h"; sourceTree = "SOURCE_ROOT"; }; - EB4083E018759B2F9C29C67E = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ThreadLocalValue.h"; path = "../../JuceLibraryCode/modules/juce_core/threads/juce_ThreadLocalValue.h"; sourceTree = "SOURCE_ROOT"; }; - EC60C51FC1AA8BD749F4DEC3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_TooltipWindow.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/windows/juce_TooltipWindow.cpp"; sourceTree = "SOURCE_ROOT"; }; - EC6C43EBC349D5597A1CE53A = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TableListBox.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/widgets/juce_TableListBox.h"; sourceTree = "SOURCE_ROOT"; }; - EC9AF66FDBA32E129D80E59A = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Logger.h"; path = "../../JuceLibraryCode/modules/juce_core/logging/juce_Logger.h"; sourceTree = "SOURCE_ROOT"; }; - ED56CB90240662CE6FBE2A74 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DrawableImage.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/drawables/juce_DrawableImage.cpp"; sourceTree = "SOURCE_ROOT"; }; - EDC826A2266EC4945813EB52 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_android_Midi.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_devices/native/juce_android_Midi.cpp"; sourceTree = "SOURCE_ROOT"; }; - EE7FAE0C413B7370B393CD35 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_LookAndFeel_V3.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V3.cpp"; sourceTree = "SOURCE_ROOT"; }; - F0FA50C01669546088DA6DB3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_JSON.h"; path = "../../JuceLibraryCode/modules/juce_core/javascript/juce_JSON.h"; sourceTree = "SOURCE_ROOT"; }; - F150F0F13B3B18F263086336 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MidiBuffer.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_basics/midi/juce_MidiBuffer.cpp"; sourceTree = "SOURCE_ROOT"; }; - F1E144384FC6A2C42FE4097D = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_KeyPress.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/keyboard/juce_KeyPress.h"; sourceTree = "SOURCE_ROOT"; }; - F2137487557EE18A462259B8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ProgressBar.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/widgets/juce_ProgressBar.h"; sourceTree = "SOURCE_ROOT"; }; - F232D373ED304682C9581DBF = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DrawableButton.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/buttons/juce_DrawableButton.h"; sourceTree = "SOURCE_ROOT"; }; - F27227DC9C5FD1ED9D39644E = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_WebBrowserComponent.h"; path = "../../JuceLibraryCode/modules/juce_gui_extra/misc/juce_WebBrowserComponent.h"; sourceTree = "SOURCE_ROOT"; }; - F27EABE98642759DB9C4DF65 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_JPEGLoader.cpp"; path = "../../JuceLibraryCode/modules/juce_graphics/image_formats/juce_JPEGLoader.cpp"; sourceTree = "SOURCE_ROOT"; }; - F3331BEC83A436D9CB3B9131 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_osx_MessageQueue.h"; path = "../../JuceLibraryCode/modules/juce_events/native/juce_osx_MessageQueue.h"; sourceTree = "SOURCE_ROOT"; }; - F347EE9BC419DB1879790131 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ApplicationProperties.h"; path = "../../JuceLibraryCode/modules/juce_data_structures/app_properties/juce_ApplicationProperties.h"; sourceTree = "SOURCE_ROOT"; }; - F3D6E8D0058A92DE17677894 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_ios_Windowing.mm"; path = "../../JuceLibraryCode/modules/juce_gui_basics/native/juce_ios_Windowing.mm"; sourceTree = "SOURCE_ROOT"; }; - F3DD16E9AF302F242F3D4DBD = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MidiMessage.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_basics/midi/juce_MidiMessage.cpp"; sourceTree = "SOURCE_ROOT"; }; - F42A363007434541AFC1A7A0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DrawableComposite.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/drawables/juce_DrawableComposite.h"; sourceTree = "SOURCE_ROOT"; }; - F44CADD7FDE536377851F6AF = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_TextEditor.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/widgets/juce_TextEditor.cpp"; sourceTree = "SOURCE_ROOT"; }; - F4666836A0E1D98969BF95D0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_ios_UIViewComponent.mm"; path = "../../JuceLibraryCode/modules/juce_gui_extra/native/juce_ios_UIViewComponent.mm"; sourceTree = "SOURCE_ROOT"; }; - F46EB82569549C07A8D04D15 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ToolbarItemPalette.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/widgets/juce_ToolbarItemPalette.h"; sourceTree = "SOURCE_ROOT"; }; - F47A2859B6F0F7800D4FFDAA = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DropShadower.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/misc/juce_DropShadower.h"; sourceTree = "SOURCE_ROOT"; }; - F4DEDFEDF1B16C6C48075EFE = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ChangeBroadcaster.h"; path = "../../JuceLibraryCode/modules/juce_events/broadcasters/juce_ChangeBroadcaster.h"; sourceTree = "SOURCE_ROOT"; }; - F5254F504B56AF6605CBF0EF = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_IIRFilter.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_basics/effects/juce_IIRFilter.cpp"; sourceTree = "SOURCE_ROOT"; }; - F56A1C13CA4FCF50685C2335 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_audio_devices.h"; path = "../../JuceLibraryCode/modules/juce_audio_devices/juce_audio_devices.h"; sourceTree = "SOURCE_ROOT"; }; - F6A17F1B8D8330F6E8DF225B = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ComponentListener.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/components/juce_ComponentListener.h"; sourceTree = "SOURCE_ROOT"; }; - F70EA6F5AF8259555E8A80C2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_PropertySet.cpp"; path = "../../JuceLibraryCode/modules/juce_core/containers/juce_PropertySet.cpp"; sourceTree = "SOURCE_ROOT"; }; - F71DF877F3D13B350F01DFEA = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FileLogger.cpp"; path = "../../JuceLibraryCode/modules/juce_core/logging/juce_FileLogger.cpp"; sourceTree = "SOURCE_ROOT"; }; - F790D306D54E1295F9C7F9E1 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_Clipboard.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/native/juce_linux_Clipboard.cpp"; sourceTree = "SOURCE_ROOT"; }; - F79AAA52220D91666D8B8771 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_Network.cpp"; path = "../../JuceLibraryCode/modules/juce_core/native/juce_win32_Network.cpp"; sourceTree = "SOURCE_ROOT"; }; + B7855FA22C92F7EE272A866E = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_KnownPluginList.h"; path = "../../../../modules/juce_audio_processors/scanning/juce_KnownPluginList.h"; sourceTree = "SOURCE_ROOT"; }; + B7DD84C8B05ABA4A6915E77E = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_core.mm"; path = "../../../../modules/juce_core/juce_core.mm"; sourceTree = "SOURCE_ROOT"; }; + B83DDFEEA66888E9616BCE82 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DirectShowComponent.h"; path = "../../../../modules/juce_video/playback/juce_DirectShowComponent.h"; sourceTree = "SOURCE_ROOT"; }; + B88950266CC4244E1B5394F2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ToggleButton.h"; path = "../../../../modules/juce_gui_basics/buttons/juce_ToggleButton.h"; sourceTree = "SOURCE_ROOT"; }; + BA7FDBE53073F3261D962FF9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_ios_UIViewComponent.mm"; path = "../../../../modules/juce_gui_extra/native/juce_ios_UIViewComponent.mm"; sourceTree = "SOURCE_ROOT"; }; + BACA17304411EED8B219D2AC = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Uuid.cpp"; path = "../../../../modules/juce_core/misc/juce_Uuid.cpp"; sourceTree = "SOURCE_ROOT"; }; + BAD1E66E3AA09ADD70061A50 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_LuaCodeTokeniser.cpp"; path = "../../../../modules/juce_gui_extra/code_editor/juce_LuaCodeTokeniser.cpp"; sourceTree = "SOURCE_ROOT"; }; + BAE06A3352E39521CE5D94EB = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_BigInteger.cpp"; path = "../../../../modules/juce_core/maths/juce_BigInteger.cpp"; sourceTree = "SOURCE_ROOT"; }; + BB144FF841A99B08D5479777 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_VSTPluginFormat.cpp"; path = "../../../../modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp"; sourceTree = "SOURCE_ROOT"; }; + BC02503FFF515269351DF89B = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MidiInput.h"; path = "../../../../modules/juce_audio_devices/midi_io/juce_MidiInput.h"; sourceTree = "SOURCE_ROOT"; }; + BC0ED0B33BB83E19D9609152 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Colours.cpp"; path = "../../../../modules/juce_graphics/colour/juce_Colours.cpp"; sourceTree = "SOURCE_ROOT"; }; + BC1DBF05964D3B9130CD8CB6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FileTreeComponent.h"; path = "../../../../modules/juce_gui_basics/filebrowser/juce_FileTreeComponent.h"; sourceTree = "SOURCE_ROOT"; }; + BCFE159BD9F2DA5515E028A4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ConcertinaPanel.h"; path = "../../../../modules/juce_gui_basics/layout/juce_ConcertinaPanel.h"; sourceTree = "SOURCE_ROOT"; }; + BD588F8D5FD1E6FE88E9D3E4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AnimatedAppComponent.h"; path = "../../../../modules/juce_gui_extra/misc/juce_AnimatedAppComponent.h"; sourceTree = "SOURCE_ROOT"; }; + BD7B0136829554046A511588 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Javascript.cpp"; path = "../../../../modules/juce_core/javascript/juce_Javascript.cpp"; sourceTree = "SOURCE_ROOT"; }; + BDA5B0C014F6DCC188465060 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_BufferedInputStream.h"; path = "../../../../modules/juce_core/streams/juce_BufferedInputStream.h"; sourceTree = "SOURCE_ROOT"; }; + BDE0C2D342D03C389560501F = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioCDReader.h"; path = "../../../../modules/juce_audio_devices/audio_cd/juce_AudioCDReader.h"; sourceTree = "SOURCE_ROOT"; }; + BE61994F6993AE76CBBF1EAB = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Image.cpp"; path = "../../../../modules/juce_graphics/images/juce_Image.cpp"; sourceTree = "SOURCE_ROOT"; }; + BE64EDA4F7260D2D5B7E0410 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_osx_ObjCHelpers.h"; path = "../../../../modules/juce_core/native/juce_osx_ObjCHelpers.h"; sourceTree = "SOURCE_ROOT"; }; + BEC8EC4C23F9AA5C8DFEA15A = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_PathIterator.h"; path = "../../../../modules/juce_graphics/geometry/juce_PathIterator.h"; sourceTree = "SOURCE_ROOT"; }; + BF40FF2E0FA609212C849FBC = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DocumentWindow.cpp"; path = "../../../../modules/juce_gui_basics/windows/juce_DocumentWindow.cpp"; sourceTree = "SOURCE_ROOT"; }; + BFB12FD84F14C9B31249FC04 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ChannelRemappingAudioSource.h"; path = "../../../../modules/juce_audio_basics/sources/juce_ChannelRemappingAudioSource.h"; sourceTree = "SOURCE_ROOT"; }; + BFBF32B0E491C9D4527DF9A6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_EdgeTable.h"; path = "../../../../modules/juce_graphics/geometry/juce_EdgeTable.h"; sourceTree = "SOURCE_ROOT"; }; + C088D98E527C1DA17B55A9D9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ToolbarButton.cpp"; path = "../../../../modules/juce_gui_basics/buttons/juce_ToolbarButton.cpp"; sourceTree = "SOURCE_ROOT"; }; + C0BA74AF0382D87B0E7BCEB3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_LeakedObjectDetector.h"; path = "../../../../modules/juce_core/memory/juce_LeakedObjectDetector.h"; sourceTree = "SOURCE_ROOT"; }; + C0FDDD3106A13770B141E5F2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TextDiff.h"; path = "../../../../modules/juce_core/text/juce_TextDiff.h"; sourceTree = "SOURCE_ROOT"; }; + C1070E62B763F1CCE0BB18F0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_audio_basics.mm"; path = "../../../../modules/juce_audio_basics/juce_audio_basics.mm"; sourceTree = "SOURCE_ROOT"; }; + C186342C3FFB4DE250556D70 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_android_SystemStats.cpp"; path = "../../../../modules/juce_core/native/juce_android_SystemStats.cpp"; sourceTree = "SOURCE_ROOT"; }; + C21701DD3A4A2628C63CB70A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_SVGParser.cpp"; path = "../../../../modules/juce_gui_basics/drawables/juce_SVGParser.cpp"; sourceTree = "SOURCE_ROOT"; }; + C296F214D5B65857DC3DA585 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_GlowEffect.cpp"; path = "../../../../modules/juce_graphics/effects/juce_GlowEffect.cpp"; sourceTree = "SOURCE_ROOT"; }; + C3DEEC17595B1AB020ADA47F = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ImagePreviewComponent.cpp"; path = "../../../../modules/juce_gui_basics/filebrowser/juce_ImagePreviewComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; + C45AB95F4CDF31A41199E6D4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_NSViewComponent.h"; path = "../../../../modules/juce_gui_extra/embedding/juce_NSViewComponent.h"; sourceTree = "SOURCE_ROOT"; }; + C51A754A0E65CA141A2C3310 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FilenameComponent.cpp"; path = "../../../../modules/juce_gui_basics/filebrowser/juce_FilenameComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; + C52E8074125FEED4DB727EDF = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FileChooser.h"; path = "../../../../modules/juce_gui_basics/filebrowser/juce_FileChooser.h"; sourceTree = "SOURCE_ROOT"; }; + C52FB75A0A93BB1397D1F962 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_WindowsMediaAudioFormat.cpp"; path = "../../../../modules/juce_audio_formats/codecs/juce_WindowsMediaAudioFormat.cpp"; sourceTree = "SOURCE_ROOT"; }; + C551CC8801B93AC70F6E4F76 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FilenameComponent.h"; path = "../../../../modules/juce_gui_basics/filebrowser/juce_FilenameComponent.h"; sourceTree = "SOURCE_ROOT"; }; + C5C3838D0FDC65F44C9D1A9A = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CallbackMessage.h"; path = "../../../../modules/juce_events/messages/juce_CallbackMessage.h"; sourceTree = "SOURCE_ROOT"; }; + C6CD42F1DA2F444A59CD4AF0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_CustomTypeface.cpp"; path = "../../../../modules/juce_graphics/fonts/juce_CustomTypeface.cpp"; sourceTree = "SOURCE_ROOT"; }; + C73B4B312C3A4CE4F8E742C2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_GlyphArrangement.cpp"; path = "../../../../modules/juce_graphics/fonts/juce_GlyphArrangement.cpp"; sourceTree = "SOURCE_ROOT"; }; + C7581A35068A3FB43786F4BE = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AbstractFifo.h"; path = "../../../../modules/juce_core/containers/juce_AbstractFifo.h"; sourceTree = "SOURCE_ROOT"; }; + C776DAD938AD7E1207DBCEEB = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Colours.h"; path = "../../../../modules/juce_graphics/colour/juce_Colours.h"; sourceTree = "SOURCE_ROOT"; }; + C7D5A8B28D0B7DE58629AA04 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Colour.cpp"; path = "../../../../modules/juce_graphics/colour/juce_Colour.cpp"; sourceTree = "SOURCE_ROOT"; }; + C884444C380A4B053DB70D12 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_DirectWriteTypeface.cpp"; path = "../../../../modules/juce_graphics/native/juce_win32_DirectWriteTypeface.cpp"; sourceTree = "SOURCE_ROOT"; }; + C8A5AD5503F33596C4147ACB = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MouseListener.h"; path = "../../../../modules/juce_gui_basics/mouse/juce_MouseListener.h"; sourceTree = "SOURCE_ROOT"; }; + C8F82FBA1E0EF7EEA5BD02B9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ConcertinaPanel.cpp"; path = "../../../../modules/juce_gui_basics/layout/juce_ConcertinaPanel.cpp"; sourceTree = "SOURCE_ROOT"; }; + C9A25E2EF32224159B617D5E = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MenuBarComponent.cpp"; path = "../../../../modules/juce_gui_basics/menus/juce_MenuBarComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; + C9BA40AFF2AD427CE4D480D7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_win32_ComSmartPtr.h"; path = "../../../../modules/juce_core/native/juce_win32_ComSmartPtr.h"; sourceTree = "SOURCE_ROOT"; }; + CA025D4369C240E6FA30CE2B = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Range.h"; path = "../../../../modules/juce_core/maths/juce_Range.h"; sourceTree = "SOURCE_ROOT"; }; + CB4D4DA89BA649D3F1B2A645 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TextButton.h"; path = "../../../../modules/juce_gui_basics/buttons/juce_TextButton.h"; sourceTree = "SOURCE_ROOT"; }; + CB5874E2A70E8A6A01FE8C9F = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_Network.cpp"; path = "../../../../modules/juce_core/native/juce_win32_Network.cpp"; sourceTree = "SOURCE_ROOT"; }; + CC0B7738BD544B955D81BF1E = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_events.mm"; path = "../../../../modules/juce_events/juce_events.mm"; sourceTree = "SOURCE_ROOT"; }; + CC3F295E9D9E5863779F9ACD = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ComponentBuilder.cpp"; path = "../../../../modules/juce_gui_basics/layout/juce_ComponentBuilder.cpp"; sourceTree = "SOURCE_ROOT"; }; + CC4B3BCEE612C95F27680EA9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_CPlusPlusCodeTokeniser.cpp"; path = "../../../../modules/juce_gui_extra/code_editor/juce_CPlusPlusCodeTokeniser.cpp"; sourceTree = "SOURCE_ROOT"; }; + CC8F24C4E5FC5C12AA30F6CF = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DragAndDropTarget.h"; path = "../../../../modules/juce_gui_basics/mouse/juce_DragAndDropTarget.h"; sourceTree = "SOURCE_ROOT"; }; + CC96E8E65FDFE4376F71D7B0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_OpenGLPixelFormat.cpp"; path = "../../../../modules/juce_opengl/opengl/juce_OpenGLPixelFormat.cpp"; sourceTree = "SOURCE_ROOT"; }; + CCA3065F893912F3E3625C13 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Reverb.h"; path = "../../../../modules/juce_audio_basics/effects/juce_Reverb.h"; sourceTree = "SOURCE_ROOT"; }; + CCEBEEF441D3FCFE411AAAD6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_android_Threads.cpp"; path = "../../../../modules/juce_core/native/juce_android_Threads.cpp"; sourceTree = "SOURCE_ROOT"; }; + CCF8FB3EA0246D83E3D2E760 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioFormatManager.cpp"; path = "../../../../modules/juce_audio_formats/format/juce_AudioFormatManager.cpp"; sourceTree = "SOURCE_ROOT"; }; + CCF94157A15DD29B6C5DA939 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DynamicObject.h"; path = "../../../../modules/juce_core/containers/juce_DynamicObject.h"; sourceTree = "SOURCE_ROOT"; }; + CD3A68C29B7A733E5954BDA3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MarkerList.h"; path = "../../../../modules/juce_gui_basics/positioning/juce_MarkerList.h"; sourceTree = "SOURCE_ROOT"; }; + CD405182963BEB73FB9E368D = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_SystemStats.mm"; path = "../../../../modules/juce_core/native/juce_mac_SystemStats.mm"; sourceTree = "SOURCE_ROOT"; }; + CD4803D5DD14A33CF5AA9FDE = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OggVorbisAudioFormat.h"; path = "../../../../modules/juce_audio_formats/codecs/juce_OggVorbisAudioFormat.h"; sourceTree = "SOURCE_ROOT"; }; + CD965406DB7511EB187919E7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_NotificationType.h"; path = "../../../../modules/juce_events/messages/juce_NotificationType.h"; sourceTree = "SOURCE_ROOT"; }; + CDFAC8C57A364EEE32CE125E = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OpenGLContext.h"; path = "../../../../modules/juce_opengl/opengl/juce_OpenGLContext.h"; sourceTree = "SOURCE_ROOT"; }; + CE0CE24264C96E86062E0250 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_BubbleMessageComponent.h"; path = "../../../../modules/juce_gui_extra/misc/juce_BubbleMessageComponent.h"; sourceTree = "SOURCE_ROOT"; }; + CE19308F9CD1B8F05E6EF6C5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_RelativeTime.h"; path = "../../../../modules/juce_core/time/juce_RelativeTime.h"; sourceTree = "SOURCE_ROOT"; }; + CE4F0A27AAADFD53316A17BC = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DrawableImage.h"; path = "../../../../modules/juce_gui_basics/drawables/juce_DrawableImage.h"; sourceTree = "SOURCE_ROOT"; }; + CE75A83F0AA70025C36151B1 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MidiOutput.h"; path = "../../../../modules/juce_audio_devices/midi_io/juce_MidiOutput.h"; sourceTree = "SOURCE_ROOT"; }; + CEC05A60A0E19B07F6A3CE6B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Drawable.cpp"; path = "../../../../modules/juce_gui_basics/drawables/juce_Drawable.cpp"; sourceTree = "SOURCE_ROOT"; }; + CF4DDBE1126E8C8C3A37DC78 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AffineTransform.cpp"; path = "../../../../modules/juce_graphics/geometry/juce_AffineTransform.cpp"; sourceTree = "SOURCE_ROOT"; }; + CF4E3CDCC9837C7E52197686 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OpenGL_osx.h"; path = "../../../../modules/juce_opengl/native/juce_OpenGL_osx.h"; sourceTree = "SOURCE_ROOT"; }; + CFF4FDD0FC27C36843B20BFC = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Primes.h"; path = "../../../../modules/juce_cryptography/encryption/juce_Primes.h"; sourceTree = "SOURCE_ROOT"; }; + D00157FA3D14BFECB7FE7232 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DrawablePath.cpp"; path = "../../../../modules/juce_gui_basics/drawables/juce_DrawablePath.cpp"; sourceTree = "SOURCE_ROOT"; }; + D01D74EE9A00B0813B00FDD1 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_StretchableLayoutResizerBar.cpp"; path = "../../../../modules/juce_gui_basics/layout/juce_StretchableLayoutResizerBar.cpp"; sourceTree = "SOURCE_ROOT"; }; + D07A5399F09462A5D7041225 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_KeyboardFocusTraverser.h"; path = "../../../../modules/juce_gui_basics/keyboard/juce_KeyboardFocusTraverser.h"; sourceTree = "SOURCE_ROOT"; }; + D0A5B1AE7B7B56633AF2D5E2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_LowLevelGraphicsPostScriptRenderer.cpp"; path = "../../../../modules/juce_graphics/contexts/juce_LowLevelGraphicsPostScriptRenderer.cpp"; sourceTree = "SOURCE_ROOT"; }; + D0AFF0790D81DB8F66173737 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_SubregionStream.h"; path = "../../../../modules/juce_core/streams/juce_SubregionStream.h"; sourceTree = "SOURCE_ROOT"; }; + D0B5B79546163A6DE73D0E2E = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ImageButton.cpp"; path = "../../../../modules/juce_gui_basics/buttons/juce_ImageButton.cpp"; sourceTree = "SOURCE_ROOT"; }; + D1000A39817E9B771A4FB856 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioFormatWriter.h"; path = "../../../../modules/juce_audio_formats/format/juce_AudioFormatWriter.h"; sourceTree = "SOURCE_ROOT"; }; + D10497F87C560FA833756730 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_TemporaryFile.cpp"; path = "../../../../modules/juce_core/files/juce_TemporaryFile.cpp"; sourceTree = "SOURCE_ROOT"; }; + D104C8636576DFE8A2D11430 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_gui_basics.h"; path = "../../../../modules/juce_gui_basics/juce_gui_basics.h"; sourceTree = "SOURCE_ROOT"; }; + D108D5FFE66F80627621DCA0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_OggVorbisAudioFormat.cpp"; path = "../../../../modules/juce_audio_formats/codecs/juce_OggVorbisAudioFormat.cpp"; sourceTree = "SOURCE_ROOT"; }; + D11D931DAED4F636E8A60264 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ChildProcess.h"; path = "../../../../modules/juce_core/threads/juce_ChildProcess.h"; sourceTree = "SOURCE_ROOT"; }; + D12F8398C3EA9BA0FA88B5CF = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DynamicObject.cpp"; path = "../../../../modules/juce_core/containers/juce_DynamicObject.cpp"; sourceTree = "SOURCE_ROOT"; }; + D19705FE67C941DA74C31A9D = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_XmlDocument.h"; path = "../../../../modules/juce_core/xml/juce_XmlDocument.h"; sourceTree = "SOURCE_ROOT"; }; + D219A10E7C41110A1AA4FBB9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_Messaging.cpp"; path = "../../../../modules/juce_events/native/juce_win32_Messaging.cpp"; sourceTree = "SOURCE_ROOT"; }; + D26821159E190113FEBF99BA = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ApplicationCommandManager.cpp"; path = "../../../../modules/juce_gui_basics/commands/juce_ApplicationCommandManager.cpp"; sourceTree = "SOURCE_ROOT"; }; + D298D1DE4D2FE281CA30910C = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MidiOutput.cpp"; path = "../../../../modules/juce_audio_devices/midi_io/juce_MidiOutput.cpp"; sourceTree = "SOURCE_ROOT"; }; + D2A5F78D0EF37F1E45DF39D4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CodeTokeniser.h"; path = "../../../../modules/juce_gui_extra/code_editor/juce_CodeTokeniser.h"; sourceTree = "SOURCE_ROOT"; }; + D3B4D56DE3F90D9A445A47A6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_data_structures.h"; path = "../../../../modules/juce_data_structures/juce_data_structures.h"; sourceTree = "SOURCE_ROOT"; }; + D3C1097E92146B596194A067 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_RelativeCoordinatePositioner.h"; path = "../../../../modules/juce_gui_basics/positioning/juce_RelativeCoordinatePositioner.h"; sourceTree = "SOURCE_ROOT"; }; + D40C36493501EA97A8D1EB50 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TabbedButtonBar.h"; path = "../../../../modules/juce_gui_basics/layout/juce_TabbedButtonBar.h"; sourceTree = "SOURCE_ROOT"; }; + D4BA573C125944E2773D747F = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ApplicationCommandTarget.cpp"; path = "../../../../modules/juce_gui_basics/commands/juce_ApplicationCommandTarget.cpp"; sourceTree = "SOURCE_ROOT"; }; + D52EB7F089EF359EDCB199AF = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Logger.h"; path = "../../../../modules/juce_core/logging/juce_Logger.h"; sourceTree = "SOURCE_ROOT"; }; + D57735149DD4975283A0C754 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_module_info"; path = "../../../../modules/juce_gui_extra/juce_module_info"; sourceTree = "SOURCE_ROOT"; }; + D5C10F9CC5ADFC1B63AD1DB9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ResizableWindow.cpp"; path = "../../../../modules/juce_gui_basics/windows/juce_ResizableWindow.cpp"; sourceTree = "SOURCE_ROOT"; }; + D5EC3B41088855C3D481A73E = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MarkerList.cpp"; path = "../../../../modules/juce_gui_basics/positioning/juce_MarkerList.cpp"; sourceTree = "SOURCE_ROOT"; }; + D64B71F992FF01CB0EE89641 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Decibels.h"; path = "../../../../modules/juce_audio_basics/effects/juce_Decibels.h"; sourceTree = "SOURCE_ROOT"; }; + D6D37626671B0FB1CE8505C9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_URL.cpp"; path = "../../../../modules/juce_core/network/juce_URL.cpp"; sourceTree = "SOURCE_ROOT"; }; + D6ECAF8B2A4E8B6C97B89FFE = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CharPointer_UTF32.h"; path = "../../../../modules/juce_core/text/juce_CharPointer_UTF32.h"; sourceTree = "SOURCE_ROOT"; }; + D763221FDA235D75039D4C46 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_AudioCDReader.cpp"; path = "../../../../modules/juce_audio_devices/native/juce_win32_AudioCDReader.cpp"; sourceTree = "SOURCE_ROOT"; }; + D7C8F6360C455C0F76E35978 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ActionListener.h"; path = "../../../../modules/juce_events/broadcasters/juce_ActionListener.h"; sourceTree = "SOURCE_ROOT"; }; + D7E612935BA192BF5D24B9A3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DirectoryContentsDisplayComponent.cpp"; path = "../../../../modules/juce_gui_basics/filebrowser/juce_DirectoryContentsDisplayComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; + D80EEBBDEC364958AE05AFFB = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CoreAudioFormat.h"; path = "../../../../modules/juce_audio_formats/codecs/juce_CoreAudioFormat.h"; sourceTree = "SOURCE_ROOT"; }; + D8256B8AA794F43A2259638A = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FileBrowserListener.h"; path = "../../../../modules/juce_gui_basics/filebrowser/juce_FileBrowserListener.h"; sourceTree = "SOURCE_ROOT"; }; + D886106C60A496E47C48AFB4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Viewport.cpp"; path = "../../../../modules/juce_gui_basics/layout/juce_Viewport.cpp"; sourceTree = "SOURCE_ROOT"; }; + D8BAA82AC820CEF315BD9DCB = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_gui_extra.mm"; path = "../../../../modules/juce_gui_extra/juce_gui_extra.mm"; sourceTree = "SOURCE_ROOT"; }; + D949A0753DEE4B4AACDDA3AF = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ReferenceCountedArray.h"; path = "../../../../modules/juce_core/containers/juce_ReferenceCountedArray.h"; sourceTree = "SOURCE_ROOT"; }; + D9FAC914CA572410C055D109 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_String.h"; path = "../../../../modules/juce_core/text/juce_String.h"; sourceTree = "SOURCE_ROOT"; }; + DA353BCF838D64BA343AC0E1 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_module_info"; path = "../../../../modules/juce_core/juce_module_info"; sourceTree = "SOURCE_ROOT"; }; + DA9671908F37549C583C61E5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_BufferingAudioSource.cpp"; path = "../../../../modules/juce_audio_basics/sources/juce_BufferingAudioSource.cpp"; sourceTree = "SOURCE_ROOT"; }; + DA98B32DCA0DEF0113C22F9A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MenuBarModel.cpp"; path = "../../../../modules/juce_gui_basics/menus/juce_MenuBarModel.cpp"; sourceTree = "SOURCE_ROOT"; }; + DAB059DA13868A81301513F7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_PlatformDefs.h"; path = "../../../../modules/juce_core/system/juce_PlatformDefs.h"; sourceTree = "SOURCE_ROOT"; }; + DAC4442F8C2F142270E92349 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TextPropertyComponent.h"; path = "../../../../modules/juce_gui_basics/properties/juce_TextPropertyComponent.h"; sourceTree = "SOURCE_ROOT"; }; + DB1C6393173661404927B4B7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_GZIPCompressorOutputStream.cpp"; path = "../../../../modules/juce_core/zip/juce_GZIPCompressorOutputStream.cpp"; sourceTree = "SOURCE_ROOT"; }; + DB4AC9766332105669D51C1E = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Message.h"; path = "../../../../modules/juce_events/messages/juce_Message.h"; sourceTree = "SOURCE_ROOT"; }; + DBB34599E380FB1F37A28B27 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MultiDocumentPanel.h"; path = "../../../../modules/juce_gui_basics/layout/juce_MultiDocumentPanel.h"; sourceTree = "SOURCE_ROOT"; }; + DBDED1D6237A21D03E68D323 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_SystemTrayIcon.cpp"; path = "../../../../modules/juce_gui_extra/native/juce_win32_SystemTrayIcon.cpp"; sourceTree = "SOURCE_ROOT"; }; + DBFBBC58ED4A18EA9FE04D1D = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_URL.h"; path = "../../../../modules/juce_core/network/juce_URL.h"; sourceTree = "SOURCE_ROOT"; }; + DC3B995E7B51FC0B76826C86 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_android_Misc.cpp"; path = "../../../../modules/juce_core/native/juce_android_Misc.cpp"; sourceTree = "SOURCE_ROOT"; }; + DC6461EF11D5745DF8C00E16 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AlertWindow.h"; path = "../../../../modules/juce_gui_basics/windows/juce_AlertWindow.h"; sourceTree = "SOURCE_ROOT"; }; + DC66DC84909A3802527414C2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ComponentMovementWatcher.cpp"; path = "../../../../modules/juce_gui_basics/layout/juce_ComponentMovementWatcher.cpp"; sourceTree = "SOURCE_ROOT"; }; + DC94270BB4A70056907C3CDD = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Quaternion.h"; path = "../../../../modules/juce_opengl/geometry/juce_Quaternion.h"; sourceTree = "SOURCE_ROOT"; }; + DD03B6CE6F750A9CECA7EDEA = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_CameraDevice.cpp"; path = "../../../../modules/juce_video/capture/juce_CameraDevice.cpp"; sourceTree = "SOURCE_ROOT"; }; + DD19124F0A7FD43F31BDEB87 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_audio_devices.mm"; path = "../../../../modules/juce_audio_devices/juce_audio_devices.mm"; sourceTree = "SOURCE_ROOT"; }; + DD2007C851B70E2C71171145 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_NamedValueSet.cpp"; path = "../../../../modules/juce_core/containers/juce_NamedValueSet.cpp"; sourceTree = "SOURCE_ROOT"; }; + DD73087B002B1DB6B90B666E = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_InterprocessConnection.h"; path = "../../../../modules/juce_events/interprocess/juce_InterprocessConnection.h"; sourceTree = "SOURCE_ROOT"; }; + DE1943CA08D7FAB2E3EC0A14 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Line.h"; path = "../../../../modules/juce_graphics/geometry/juce_Line.h"; sourceTree = "SOURCE_ROOT"; }; + DE4C0926D2EFA7649BD3AAA5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TimeSliceThread.h"; path = "../../../../modules/juce_core/threads/juce_TimeSliceThread.h"; sourceTree = "SOURCE_ROOT"; }; + DE4DC23FAE4C420D489ABD17 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ImageFileFormat.h"; path = "../../../../modules/juce_graphics/images/juce_ImageFileFormat.h"; sourceTree = "SOURCE_ROOT"; }; + DEEA654926310D5B37A191C9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FileLogger.cpp"; path = "../../../../modules/juce_core/logging/juce_FileLogger.cpp"; sourceTree = "SOURCE_ROOT"; }; + DFAD61F886BEAAAE535BBF81 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ZipFile.h"; path = "../../../../modules/juce_core/zip/juce_ZipFile.h"; sourceTree = "SOURCE_ROOT"; }; + DFC58448ADEA2B5D2FF5F8D3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioTransportSource.h"; path = "../../../../modules/juce_audio_devices/sources/juce_AudioTransportSource.h"; sourceTree = "SOURCE_ROOT"; }; + DFD9E836DB24F4DE75A94C29 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FileInputStream.h"; path = "../../../../modules/juce_core/files/juce_FileInputStream.h"; sourceTree = "SOURCE_ROOT"; }; + E0A44ED2A465E22D93420F88 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_Network.mm"; path = "../../../../modules/juce_core/native/juce_mac_Network.mm"; sourceTree = "SOURCE_ROOT"; }; + E0EF847C7052C5FFA2A7CF8B = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_PreferencesPanel.h"; path = "../../../../modules/juce_gui_extra/misc/juce_PreferencesPanel.h"; sourceTree = "SOURCE_ROOT"; }; + E0FCA8F19A081CE941B273FA = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_CameraDevice.mm"; path = "../../../../modules/juce_video/native/juce_mac_CameraDevice.mm"; sourceTree = "SOURCE_ROOT"; }; + E109BFE0F2475C97F17CA5AF = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_cryptography.h"; path = "../../../../modules/juce_cryptography/juce_cryptography.h"; sourceTree = "SOURCE_ROOT"; }; + E13860F17C7FC399EF28EC1A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_KeyPress.cpp"; path = "../../../../modules/juce_gui_basics/keyboard/juce_KeyPress.cpp"; sourceTree = "SOURCE_ROOT"; }; + E1868998BA7B20DF7ED0B5E1 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_ios_UIViewComponentPeer.mm"; path = "../../../../modules/juce_gui_basics/native/juce_ios_UIViewComponentPeer.mm"; sourceTree = "SOURCE_ROOT"; }; + E1A153E1CA08E918F65C2B4D = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioFormatReader.cpp"; path = "../../../../modules/juce_audio_formats/format/juce_AudioFormatReader.cpp"; sourceTree = "SOURCE_ROOT"; }; + E1AC4AB03052A8F3FF90FBA4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Atomic.h"; path = "../../../../modules/juce_core/memory/juce_Atomic.h"; sourceTree = "SOURCE_ROOT"; }; + E21A45155C6954C6E50CCAF6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_PerformanceCounter.h"; path = "../../../../modules/juce_core/time/juce_PerformanceCounter.h"; sourceTree = "SOURCE_ROOT"; }; + E2307A386F9B96576696354B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ComponentListener.cpp"; path = "../../../../modules/juce_gui_basics/components/juce_ComponentListener.cpp"; sourceTree = "SOURCE_ROOT"; }; + E29A372A41F835609F81CC43 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_SystemTrayIconComponent.cpp"; path = "../../../../modules/juce_gui_extra/misc/juce_SystemTrayIconComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; + E2E3FA0BA7B7C8EB3C47B642 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioProcessor.cpp"; path = "../../../../modules/juce_audio_processors/processors/juce_AudioProcessor.cpp"; sourceTree = "SOURCE_ROOT"; }; + E323EAC836E3B5BB29B6AE06 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioPluginInstance.h"; path = "../../../../modules/juce_audio_processors/processors/juce_AudioPluginInstance.h"; sourceTree = "SOURCE_ROOT"; }; + E40FB3B047D27337B9A9CACA = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_XmlElement.h"; path = "../../../../modules/juce_core/xml/juce_XmlElement.h"; sourceTree = "SOURCE_ROOT"; }; + E443717EB8EC16A0B1814BAC = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FileFilter.cpp"; path = "../../../../modules/juce_core/files/juce_FileFilter.cpp"; sourceTree = "SOURCE_ROOT"; }; + E4D5FB6A6F806D9400BBF344 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_NamedValueSet.h"; path = "../../../../modules/juce_core/containers/juce_NamedValueSet.h"; sourceTree = "SOURCE_ROOT"; }; + E57F103FCFDEE26617E3F8F2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FlacAudioFormat.h"; path = "../../../../modules/juce_audio_formats/codecs/juce_FlacAudioFormat.h"; sourceTree = "SOURCE_ROOT"; }; + E587838C598E06E7959F2A31 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_AudioUnitPluginFormat.mm"; path = "../../../../modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.mm"; sourceTree = "SOURCE_ROOT"; }; + E5918150BDBDBCC3060C9FB3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_InputStream.h"; path = "../../../../modules/juce_core/streams/juce_InputStream.h"; sourceTree = "SOURCE_ROOT"; }; + E5AF1F5B3F7F2B30606FBF24 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioFormatReader.h"; path = "../../../../modules/juce_audio_formats/format/juce_AudioFormatReader.h"; sourceTree = "SOURCE_ROOT"; }; + E5B323382721E0B714F5D805 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioProcessorEditor.cpp"; path = "../../../../modules/juce_audio_processors/processors/juce_AudioProcessorEditor.cpp"; sourceTree = "SOURCE_ROOT"; }; + E5B84D5F7CF2B74715EEF3B3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ToolbarItemComponent.cpp"; path = "../../../../modules/juce_gui_basics/widgets/juce_ToolbarItemComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; + E652F16998FA1CBF2068C6FC = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_VSTPluginFormat.h"; path = "../../../../modules/juce_audio_processors/format_types/juce_VSTPluginFormat.h"; sourceTree = "SOURCE_ROOT"; }; + E6BA3A4991987C4AB55F5948 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ArrowButton.h"; path = "../../../../modules/juce_gui_basics/buttons/juce_ArrowButton.h"; sourceTree = "SOURCE_ROOT"; }; + E6D8902FFF0C8CDBB3E4BEA3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_BubbleComponent.cpp"; path = "../../../../modules/juce_gui_basics/misc/juce_BubbleComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; + E6E99E6E9BB715D12B35AB4A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_LADSPAPluginFormat.cpp"; path = "../../../../modules/juce_audio_processors/format_types/juce_LADSPAPluginFormat.cpp"; sourceTree = "SOURCE_ROOT"; }; + E70034BF5EF1721B245C3079 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AsyncUpdater.h"; path = "../../../../modules/juce_events/broadcasters/juce_AsyncUpdater.h"; sourceTree = "SOURCE_ROOT"; }; + E7488E12D0F3300AE33E0B9E = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_GlowEffect.h"; path = "../../../../modules/juce_graphics/effects/juce_GlowEffect.h"; sourceTree = "SOURCE_ROOT"; }; + E7EC04A96E1CBFA9428A4B80 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DynamicLibrary.h"; path = "../../../../modules/juce_core/threads/juce_DynamicLibrary.h"; sourceTree = "SOURCE_ROOT"; }; + E958ECCACCCE70690FAE58B9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ImageComponent.h"; path = "../../../../modules/juce_gui_basics/widgets/juce_ImageComponent.h"; sourceTree = "SOURCE_ROOT"; }; + E973909AF8AFFB788A250CB6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ArrayAllocationBase.h"; path = "../../../../modules/juce_core/containers/juce_ArrayAllocationBase.h"; sourceTree = "SOURCE_ROOT"; }; + E9A4C91E94B6D096BD8217D7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ThreadWithProgressWindow.h"; path = "../../../../modules/juce_gui_basics/windows/juce_ThreadWithProgressWindow.h"; sourceTree = "SOURCE_ROOT"; }; + E9C249D9F38B0DFAF0823653 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_android_GraphicsContext.cpp"; path = "../../../../modules/juce_graphics/native/juce_android_GraphicsContext.cpp"; sourceTree = "SOURCE_ROOT"; }; + EA13B2FC256C7BCF0900369E = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TooltipWindow.h"; path = "../../../../modules/juce_gui_basics/windows/juce_TooltipWindow.h"; sourceTree = "SOURCE_ROOT"; }; + EA5874F225E76DED69BD7132 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CriticalSection.h"; path = "../../../../modules/juce_core/threads/juce_CriticalSection.h"; sourceTree = "SOURCE_ROOT"; }; + EA749A33B0E635F691A42C64 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Sampler.h"; path = "../../../../modules/juce_audio_formats/sampler/juce_Sampler.h"; sourceTree = "SOURCE_ROOT"; }; + EA779F8A580E3D22A7CBD51E = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ImageComponent.cpp"; path = "../../../../modules/juce_gui_basics/widgets/juce_ImageComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; + EAAFB86397B191FF3713155B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_XmlElement.cpp"; path = "../../../../modules/juce_core/xml/juce_XmlElement.cpp"; sourceTree = "SOURCE_ROOT"; }; + EBC4E11E36D206EDF01E6EB0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_LowLevelGraphicsContext.h"; path = "../../../../modules/juce_graphics/contexts/juce_LowLevelGraphicsContext.h"; sourceTree = "SOURCE_ROOT"; }; + EBD6F8CE3122B2AA015A62BB = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_PluginDirectoryScanner.h"; path = "../../../../modules/juce_audio_processors/scanning/juce_PluginDirectoryScanner.h"; sourceTree = "SOURCE_ROOT"; }; + EBDC0E12D4ED20F5DB90BC26 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Typeface.cpp"; path = "../../../../modules/juce_graphics/fonts/juce_Typeface.cpp"; sourceTree = "SOURCE_ROOT"; }; + EC11D53A4118E15738CC70BB = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_PluginDescription.cpp"; path = "../../../../modules/juce_audio_processors/processors/juce_PluginDescription.cpp"; sourceTree = "SOURCE_ROOT"; }; + EC9898734E8AFE5215705476 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OpenGL_ios.h"; path = "../../../../modules/juce_opengl/native/juce_OpenGL_ios.h"; sourceTree = "SOURCE_ROOT"; }; + ECD7A374DADD305C66141AF4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MemoryOutputStream.cpp"; path = "../../../../modules/juce_core/streams/juce_MemoryOutputStream.cpp"; sourceTree = "SOURCE_ROOT"; }; + ED5E6273C8910BF1F8CBDB9B = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MemoryBlock.h"; path = "../../../../modules/juce_core/memory/juce_MemoryBlock.h"; sourceTree = "SOURCE_ROOT"; }; + ED773069A737B4877D02DD90 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioProcessor.h"; path = "../../../../modules/juce_audio_processors/processors/juce_AudioProcessor.h"; sourceTree = "SOURCE_ROOT"; }; + ED7E17722B60B7D89188CE60 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_WeakReference.h"; path = "../../../../modules/juce_core/memory/juce_WeakReference.h"; sourceTree = "SOURCE_ROOT"; }; + ED8032A884A03337DAA1D453 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Time.cpp"; path = "../../../../modules/juce_core/time/juce_Time.cpp"; sourceTree = "SOURCE_ROOT"; }; + EE577E6ABD70D104CD83186C = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DrawableText.cpp"; path = "../../../../modules/juce_gui_basics/drawables/juce_DrawableText.cpp"; sourceTree = "SOURCE_ROOT"; }; + EEBBCD11005AE9AD87B36F32 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ApplicationBase.cpp"; path = "../../../../modules/juce_events/messages/juce_ApplicationBase.cpp"; sourceTree = "SOURCE_ROOT"; }; + EF8B8FB4B02133457562E1F4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_PropertyPanel.h"; path = "../../../../modules/juce_gui_basics/properties/juce_PropertyPanel.h"; sourceTree = "SOURCE_ROOT"; }; + EFA1E7B282EF67800F4766AE = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_Midi.cpp"; path = "../../../../modules/juce_audio_devices/native/juce_linux_Midi.cpp"; sourceTree = "SOURCE_ROOT"; }; + F0B46A9181B1707349A20399 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_BubbleComponent.h"; path = "../../../../modules/juce_gui_basics/misc/juce_BubbleComponent.h"; sourceTree = "SOURCE_ROOT"; }; + F0D54DDE8C2AD1D018A61FDB = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DrawableText.h"; path = "../../../../modules/juce_gui_basics/drawables/juce_DrawableText.h"; sourceTree = "SOURCE_ROOT"; }; + F0E4B5B18AAB82215F5C6AE1 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DropShadowEffect.h"; path = "../../../../modules/juce_graphics/effects/juce_DropShadowEffect.h"; sourceTree = "SOURCE_ROOT"; }; + F113DFEACAF2D8230F0DF5E7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_QuickTimeMovieComponent.h"; path = "../../../../modules/juce_video/playback/juce_QuickTimeMovieComponent.h"; sourceTree = "SOURCE_ROOT"; }; + F16734BCF880A8180C06018D = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_HyperlinkButton.h"; path = "../../../../modules/juce_gui_basics/buttons/juce_HyperlinkButton.h"; sourceTree = "SOURCE_ROOT"; }; + F2040E4B76F8783B471CECED = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_Fonts.cpp"; path = "../../../../modules/juce_graphics/native/juce_win32_Fonts.cpp"; sourceTree = "SOURCE_ROOT"; }; + F20F182CBEF008AA1B1BB52A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_BooleanPropertyComponent.cpp"; path = "../../../../modules/juce_gui_basics/properties/juce_BooleanPropertyComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; + F22781915698D59D4CBE984D = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ScopedPointer.h"; path = "../../../../modules/juce_core/memory/juce_ScopedPointer.h"; sourceTree = "SOURCE_ROOT"; }; + F233E88B6F2BC6906819AE6A = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ScrollBar.h"; path = "../../../../modules/juce_gui_basics/layout/juce_ScrollBar.h"; sourceTree = "SOURCE_ROOT"; }; + F257AD1B82D5595FF9C3F1CA = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_NSViewComponent.mm"; path = "../../../../modules/juce_gui_extra/native/juce_mac_NSViewComponent.mm"; sourceTree = "SOURCE_ROOT"; }; + F26953C1E056357A3DFDF35C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ToolbarItemPalette.h"; path = "../../../../modules/juce_gui_basics/widgets/juce_ToolbarItemPalette.h"; sourceTree = "SOURCE_ROOT"; }; + F2A1FCAC1825462CD568D442 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_StringRef.h"; path = "../../../../modules/juce_core/text/juce_StringRef.h"; sourceTree = "SOURCE_ROOT"; }; + F2DDCDF62D2587FB565A442A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ToggleButton.cpp"; path = "../../../../modules/juce_gui_basics/buttons/juce_ToggleButton.cpp"; sourceTree = "SOURCE_ROOT"; }; + F30876EE30580650FD17B801 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ios_Audio.cpp"; path = "../../../../modules/juce_audio_devices/native/juce_ios_Audio.cpp"; sourceTree = "SOURCE_ROOT"; }; + F3154C77D5DFCE8D71084F23 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DirectoryContentsList.h"; path = "../../../../modules/juce_gui_basics/filebrowser/juce_DirectoryContentsList.h"; sourceTree = "SOURCE_ROOT"; }; + F33B267B702055F8CE27BDB8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_StretchableObjectResizer.h"; path = "../../../../modules/juce_gui_basics/layout/juce_StretchableObjectResizer.h"; sourceTree = "SOURCE_ROOT"; }; + F34126F005008CBB1C42B68F = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FloatVectorOperations.cpp"; path = "../../../../modules/juce_audio_basics/buffers/juce_FloatVectorOperations.cpp"; sourceTree = "SOURCE_ROOT"; }; + F36959B167E88B220CF9D8FE = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_DirectWriteTypeLayout.cpp"; path = "../../../../modules/juce_graphics/native/juce_win32_DirectWriteTypeLayout.cpp"; sourceTree = "SOURCE_ROOT"; }; + F36FACCDB4B94286F6042490 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_LinkedListPointer.h"; path = "../../../../modules/juce_core/containers/juce_LinkedListPointer.h"; sourceTree = "SOURCE_ROOT"; }; + F382E14FAFF5CDEBFEA81B00 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DirectoryContentsDisplayComponent.h"; path = "../../../../modules/juce_gui_basics/filebrowser/juce_DirectoryContentsDisplayComponent.h"; sourceTree = "SOURCE_ROOT"; }; + F38F8132499ADBD3344E8449 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MouseEvent.h"; path = "../../../../modules/juce_gui_basics/mouse/juce_MouseEvent.h"; sourceTree = "SOURCE_ROOT"; }; + F3A0B8ADF39FA8F15A6D8E23 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MultiTimer.h"; path = "../../../../modules/juce_events/timers/juce_MultiTimer.h"; sourceTree = "SOURCE_ROOT"; }; + F3BD246F4283B08B1E21C75B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DeletedAtShutdown.cpp"; path = "../../../../modules/juce_events/messages/juce_DeletedAtShutdown.cpp"; sourceTree = "SOURCE_ROOT"; }; + F3C52FC514B9B3A2DFD7E3F6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioPluginFormatManager.h"; path = "../../../../modules/juce_audio_processors/format/juce_AudioPluginFormatManager.h"; sourceTree = "SOURCE_ROOT"; }; + F4454839EB930FC98D63AED3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_StringPairArray.h"; path = "../../../../modules/juce_core/text/juce_StringPairArray.h"; sourceTree = "SOURCE_ROOT"; }; + F49471EE0681DBD1115D927B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_TextDiff.cpp"; path = "../../../../modules/juce_core/text/juce_TextDiff.cpp"; sourceTree = "SOURCE_ROOT"; }; + F4A977844BD67D5C2BEFCDDC = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ImageButton.h"; path = "../../../../modules/juce_gui_basics/buttons/juce_ImageButton.h"; sourceTree = "SOURCE_ROOT"; }; + F4F618373A81FDC73AB27A91 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AnimatedPosition.h"; path = "../../../../modules/juce_gui_basics/layout/juce_AnimatedPosition.h"; sourceTree = "SOURCE_ROOT"; }; + F5091F49E07C6DF8F644BAF0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ReadWriteLock.cpp"; path = "../../../../modules/juce_core/threads/juce_ReadWriteLock.cpp"; sourceTree = "SOURCE_ROOT"; }; + F64C6AC0DC0376A80A74A82A = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TextLayout.h"; path = "../../../../modules/juce_graphics/fonts/juce_TextLayout.h"; sourceTree = "SOURCE_ROOT"; }; + F65A6A3350F6251E8BBF8CF7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MP3AudioFormat.h"; path = "../../../../modules/juce_audio_formats/codecs/juce_MP3AudioFormat.h"; sourceTree = "SOURCE_ROOT"; }; + F73B6D934AEC9887D9EBB5E2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_WindowsRegistry.h"; path = "../../../../modules/juce_core/misc/juce_WindowsRegistry.h"; sourceTree = "SOURCE_ROOT"; }; + F79ADEBA7B305354085FFB8D = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_VST3PluginFormat.cpp"; path = "../../../../modules/juce_audio_processors/format_types/juce_VST3PluginFormat.cpp"; sourceTree = "SOURCE_ROOT"; }; F7B6DBDC7439C90B4E01752E = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = Main.cpp; path = ../../Source/Main.cpp; sourceTree = "SOURCE_ROOT"; }; - F88891B88E872621E6267BF9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioSubsectionReader.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_formats/format/juce_AudioSubsectionReader.cpp"; sourceTree = "SOURCE_ROOT"; }; - F8CC801FFF5B4B004707190B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_TextDiff.cpp"; path = "../../JuceLibraryCode/modules/juce_core/text/juce_TextDiff.cpp"; sourceTree = "SOURCE_ROOT"; }; - F8E876D642B7406D7D706491 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_BlowFish.h"; path = "../../JuceLibraryCode/modules/juce_cryptography/encryption/juce_BlowFish.h"; sourceTree = "SOURCE_ROOT"; }; - F94ED23A0C2454ED44C7B53B = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FileInputSource.h"; path = "../../JuceLibraryCode/modules/juce_core/streams/juce_FileInputSource.h"; sourceTree = "SOURCE_ROOT"; }; - F9C7BCC7CD4D4FC9CDDF77A9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MultiTimer.cpp"; path = "../../JuceLibraryCode/modules/juce_events/timers/juce_MultiTimer.cpp"; sourceTree = "SOURCE_ROOT"; }; - FA4C2A6A58633E63A09EC3FB = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ToolbarItemComponent.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/widgets/juce_ToolbarItemComponent.h"; sourceTree = "SOURCE_ROOT"; }; - FB5014B315A9FB387052F4DD = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ToggleButton.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/buttons/juce_ToggleButton.cpp"; sourceTree = "SOURCE_ROOT"; }; - FBB2451FAA8812635B019B07 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_LiveConstantEditor.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_extra/misc/juce_LiveConstantEditor.cpp"; sourceTree = "SOURCE_ROOT"; }; - FBB34D0E335152A813554244 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioProcessor.h"; path = "../../JuceLibraryCode/modules/juce_audio_processors/processors/juce_AudioProcessor.h"; sourceTree = "SOURCE_ROOT"; }; - FBC39ED8BF25B886702E335B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_LookAndFeel.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel.cpp"; sourceTree = "SOURCE_ROOT"; }; - FC5A39F51E480EB25A4A2656 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DialogWindow.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/windows/juce_DialogWindow.h"; sourceTree = "SOURCE_ROOT"; }; - FCD0D87F9B7A473885F5A95E = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ComponentPeer.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/windows/juce_ComponentPeer.cpp"; sourceTree = "SOURCE_ROOT"; }; - FCD602F37104023C7B8BE2B6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DirectoryContentsDisplayComponent.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/filebrowser/juce_DirectoryContentsDisplayComponent.h"; sourceTree = "SOURCE_ROOT"; }; - FD096043D0EA583C06AEFDAC = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_IIRFilterAudioSource.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_basics/sources/juce_IIRFilterAudioSource.cpp"; sourceTree = "SOURCE_ROOT"; }; - FD596755997053D5C6F9D460 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Button.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/buttons/juce_Button.h"; sourceTree = "SOURCE_ROOT"; }; - FE00E8025F597B2AD2D00063 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Label.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/widgets/juce_Label.h"; sourceTree = "SOURCE_ROOT"; }; - FE44E4AE499848D27FB7A985 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FileBrowserComponent.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/filebrowser/juce_FileBrowserComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; - FE78C65011B44BD909EC2062 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ModalComponentManager.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/components/juce_ModalComponentManager.h"; sourceTree = "SOURCE_ROOT"; }; - FEF0FE795764A633EA32AD4C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioFormatReaderSource.h"; path = "../../JuceLibraryCode/modules/juce_audio_formats/format/juce_AudioFormatReaderSource.h"; sourceTree = "SOURCE_ROOT"; }; - FEFA7D5743E1801CB7CE041E = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_cryptography.h"; path = "../../JuceLibraryCode/modules/juce_cryptography/juce_cryptography.h"; sourceTree = "SOURCE_ROOT"; }; - FF0D0A3EFBB77DFC905FAFD8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OpenGL_linux.h"; path = "../../JuceLibraryCode/modules/juce_opengl/native/juce_OpenGL_linux.h"; sourceTree = "SOURCE_ROOT"; }; + F7E781AFAA34B511C812896A = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_UndoManager.h"; path = "../../../../modules/juce_data_structures/undomanager/juce_UndoManager.h"; sourceTree = "SOURCE_ROOT"; }; + F831631700830F81994D9980 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_StretchableObjectResizer.cpp"; path = "../../../../modules/juce_gui_basics/layout/juce_StretchableObjectResizer.cpp"; sourceTree = "SOURCE_ROOT"; }; + F83392D9825422AF0DB638D0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_Clipboard.cpp"; path = "../../../../modules/juce_gui_basics/native/juce_linux_Clipboard.cpp"; sourceTree = "SOURCE_ROOT"; }; + F838183EDFF5937C2879EE41 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_RecentlyOpenedFilesList.h"; path = "../../../../modules/juce_gui_extra/misc/juce_RecentlyOpenedFilesList.h"; sourceTree = "SOURCE_ROOT"; }; + F8EB370470B7928A80032F7C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_SHA256.h"; path = "../../../../modules/juce_cryptography/hashing/juce_SHA256.h"; sourceTree = "SOURCE_ROOT"; }; + F95533D725E548643CA584D7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_Windowing.cpp"; path = "../../../../modules/juce_gui_basics/native/juce_win32_Windowing.cpp"; sourceTree = "SOURCE_ROOT"; }; + F9609B0A0387932B86A6FABE = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_InterProcessLock.h"; path = "../../../../modules/juce_core/threads/juce_InterProcessLock.h"; sourceTree = "SOURCE_ROOT"; }; + F994D2E0DF00D0A7765068EF = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ImageCache.cpp"; path = "../../../../modules/juce_graphics/images/juce_ImageCache.cpp"; sourceTree = "SOURCE_ROOT"; }; + F9B00F8F537F74527F6C463C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_KeyMappingEditorComponent.h"; path = "../../../../modules/juce_gui_extra/misc/juce_KeyMappingEditorComponent.h"; sourceTree = "SOURCE_ROOT"; }; + FA2DB83279928FFB76A4BC6E = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_RelativeParallelogram.h"; path = "../../../../modules/juce_gui_basics/positioning/juce_RelativeParallelogram.h"; sourceTree = "SOURCE_ROOT"; }; + FAB998A70437EE4D89CABE2F = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DropShadower.cpp"; path = "../../../../modules/juce_gui_basics/misc/juce_DropShadower.cpp"; sourceTree = "SOURCE_ROOT"; }; + FAC04A1B47255DA7A6397737 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_GenericAudioProcessorEditor.h"; path = "../../../../modules/juce_audio_processors/processors/juce_GenericAudioProcessorEditor.h"; sourceTree = "SOURCE_ROOT"; }; + FAF4C6D8D1D59932F12DF6A7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Memory.h"; path = "../../../../modules/juce_core/memory/juce_Memory.h"; sourceTree = "SOURCE_ROOT"; }; + FB3BE7E3D0A04791487E9E0C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_SliderPropertyComponent.h"; path = "../../../../modules/juce_gui_basics/properties/juce_SliderPropertyComponent.h"; sourceTree = "SOURCE_ROOT"; }; + FB459E95101C8A92E5B39A67 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FileFilter.h"; path = "../../../../modules/juce_core/files/juce_FileFilter.h"; sourceTree = "SOURCE_ROOT"; }; + FB81D25CF4825A9A186B6790 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_module_info"; path = "../../../../modules/juce_data_structures/juce_module_info"; sourceTree = "SOURCE_ROOT"; }; + FBC55E440EF1EA83FC0DAA5A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_PropertiesFile.cpp"; path = "../../../../modules/juce_data_structures/app_properties/juce_PropertiesFile.cpp"; sourceTree = "SOURCE_ROOT"; }; + FBDBD56614E38BB5A5592D32 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_GZIPDecompressorInputStream.cpp"; path = "../../../../modules/juce_core/zip/juce_GZIPDecompressorInputStream.cpp"; sourceTree = "SOURCE_ROOT"; }; + FCA9526394A63B33405F8E58 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_android_Audio.cpp"; path = "../../../../modules/juce_audio_devices/native/juce_android_Audio.cpp"; sourceTree = "SOURCE_ROOT"; }; + FCC9F258531F00BCD91C63DF = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ScrollBar.cpp"; path = "../../../../modules/juce_gui_basics/layout/juce_ScrollBar.cpp"; sourceTree = "SOURCE_ROOT"; }; + FD05E73E3F022E08D70B9569 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FileSearchPathListComponent.h"; path = "../../../../modules/juce_gui_basics/filebrowser/juce_FileSearchPathListComponent.h"; sourceTree = "SOURCE_ROOT"; }; + FD1FFBCE5E94D08B6FB60F70 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ElementComparator.h"; path = "../../../../modules/juce_core/containers/juce_ElementComparator.h"; sourceTree = "SOURCE_ROOT"; }; + FD5262552A90A9DFACB3C07F = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ModifierKeys.h"; path = "../../../../modules/juce_gui_basics/keyboard/juce_ModifierKeys.h"; sourceTree = "SOURCE_ROOT"; }; + FD5E948C1A89B11770A20704 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DrawablePath.h"; path = "../../../../modules/juce_gui_basics/drawables/juce_DrawablePath.h"; sourceTree = "SOURCE_ROOT"; }; + FDA36D1F836D00DE705CD06F = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DialogWindow.cpp"; path = "../../../../modules/juce_gui_basics/windows/juce_DialogWindow.cpp"; sourceTree = "SOURCE_ROOT"; }; + FDE0D8E73B0ED8A938C99AAD = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_IIRFilter.h"; path = "../../../../modules/juce_audio_basics/effects/juce_IIRFilter.h"; sourceTree = "SOURCE_ROOT"; }; + FE1E97C9233F2D472C7C6128 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_XMLCodeTokeniser.h"; path = "../../../../modules/juce_gui_extra/code_editor/juce_XMLCodeTokeniser.h"; sourceTree = "SOURCE_ROOT"; }; + FE41044F09ABE0A6BC0F9293 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ScopedValueSetter.h"; path = "../../../../modules/juce_core/containers/juce_ScopedValueSetter.h"; sourceTree = "SOURCE_ROOT"; }; + FE55A1DFB90A1A5EF37B1741 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioFormatReaderSource.h"; path = "../../../../modules/juce_audio_formats/format/juce_AudioFormatReaderSource.h"; sourceTree = "SOURCE_ROOT"; }; + FEA645D52C593ECCEA779BAF = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Component.h"; path = "../../../../modules/juce_gui_basics/components/juce_Component.h"; sourceTree = "SOURCE_ROOT"; }; + FF1CEE8501CA0F081EE0E3AE = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioFormatManager.h"; path = "../../../../modules/juce_audio_formats/format/juce_AudioFormatManager.h"; sourceTree = "SOURCE_ROOT"; }; + FF1F4F1262BB429E80492B13 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DialogWindow.h"; path = "../../../../modules/juce_gui_basics/windows/juce_DialogWindow.h"; sourceTree = "SOURCE_ROOT"; }; FF3D4768BC96B79F49B10894 = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = Info.plist; path = Info.plist; sourceTree = "SOURCE_ROOT"; }; - FF921DEC61293D650C9BCA7B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ToolbarItemPalette.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/widgets/juce_ToolbarItemPalette.cpp"; sourceTree = "SOURCE_ROOT"; }; - FFA213182EB6CA238D01F488 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ChannelRemappingAudioSource.h"; path = "../../JuceLibraryCode/modules/juce_audio_basics/sources/juce_ChannelRemappingAudioSource.h"; sourceTree = "SOURCE_ROOT"; }; - FFAC8C8B3CC3F05E12744D1F = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FileFilter.cpp"; path = "../../JuceLibraryCode/modules/juce_core/files/juce_FileFilter.cpp"; sourceTree = "SOURCE_ROOT"; }; + FF70C4AB4F37D7C7E1668660 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_HashMap.h"; path = "../../../../modules/juce_core/containers/juce_HashMap.h"; sourceTree = "SOURCE_ROOT"; }; + FF7A26DADF1579C43D80454F = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_LocalisedStrings.cpp"; path = "../../../../modules/juce_core/text/juce_LocalisedStrings.cpp"; sourceTree = "SOURCE_ROOT"; }; 9F41B5C4D3F9CE9C17373AB3 = {isa = PBXGroup; children = ( B766DBADE0BD743FAC004870, F7B6DBDC7439C90B4E01752E, ); name = Source; sourceTree = ""; }; C69760E59D600CF000D468E8 = {isa = PBXGroup; children = ( 9F41B5C4D3F9CE9C17373AB3, ); name = AnimationAppExample; sourceTree = ""; }; 56E5D80A2B5A0AB691ABB90D = {isa = PBXGroup; children = ( - 44F0CE6E0BBCE5E596BF70A6, - 30E06EA9F94FA181A6B8F533, - 5B7A3EE41F87CB2931C1E13C, - 555BF349B10EE4EF21DCA398, - 671FF5E5EBF6920BAAA79B4E, - EA269A07CD83E9F5977889E6, ); name = buffers; sourceTree = ""; }; + AC2AE970951E20A199938AFB, + 7A46778023CF61B3F417F9AC, + AD648ADDD885B93B2EB60C88, + 6D0D0EC5B978695152A0B84F, + F34126F005008CBB1C42B68F, + 03D03AF17C5E899ED9481518, ); name = buffers; sourceTree = ""; }; 976965B1038594B4C210B247 = {isa = PBXGroup; children = ( - F150F0F13B3B18F263086336, - C1C5A9F18F63CDB9BDF32177, - 2F8345DA4FF13DA81612EBB3, - CDDD5A437DEFD1CD65160A9C, - E22876603667D88857CA5179, - CFB26A1C32F851E8DDC36BB7, - F3DD16E9AF302F242F3D4DBD, - C67D83EB019C2F931E5FF290, - 3293B0656CFCA5B2303C6E8F, - 1A491D8A6C3223CF582E050D, ); name = midi; sourceTree = ""; }; + 9F5FD873C8192683DB089745, + 5358DE9C9773654731E6F615, + 8DC827CCF543708CF729FED6, + A917646C0153D2A57E3C5677, + 95440A40B2FB3CE5E09D57B4, + 6A1D79062B92685A87BEE5F6, + 8CA01F9530AC5512C6B74325, + AC3184BE8D8804394FCCDCB6, + 8FA02AA8698232B53D4BFDBB, + 8EDD1755AEE1C95660A06BF2, ); name = midi; sourceTree = ""; }; 26A3DDC7B0D9C11EC02E6407 = {isa = PBXGroup; children = ( - 72ACB726645A64B055B59277, - F5254F504B56AF6605CBF0EF, - 90E607BA3727A053395D2A61, - D23D5618C7FFFCFD938CD5F1, - 83A10FEA76D527B4E88AD0EF, - 27D5D6CE8B6CFF40F8A5B9D0, ); name = effects; sourceTree = ""; }; + D64B71F992FF01CB0EE89641, + 1B3B7CBA0D25C83B8AF72641, + FDE0D8E73B0ED8A938C99AAD, + 0311666DB95BFAE686267D7C, + 403453363C4785FD451A9BA1, + CCA3065F893912F3E3625C13, ); name = effects; sourceTree = ""; }; FE8AB04D3B86B9666AD12C5B = {isa = PBXGroup; children = ( - D786D6FB9787CEC730CFEDD9, - 622800F19C8B24050A92D15B, - 8CD45DADF91984C72DAE7E09, - E670FE5F095BB2B7F9EB8138, - FFA213182EB6CA238D01F488, - FD096043D0EA583C06AEFDAC, - 69572C0082E358837174B04E, - 5C74D5593E152C52854A522F, - 6BC5245D8E2ACD816BA03475, - 39EFC895DB6FA253ACD83729, - A2D0912BF511B8AA5CEE9690, - D429E0F29213E9058DED8ECC, - 48403410E9FE064527EDCC85, - 213971DB941D93E214CF2153, - 3269E6F38346442BAB611D8C, - 4F73548B7300043B5CBD8853, ); name = sources; sourceTree = ""; }; + 086CE5C768CF5889BDEF8955, + DA9671908F37549C583C61E5, + 97EDCA2A04EF5ADAAD9DC594, + 4EAE69CF6B5097A57EBCD27B, + BFB12FD84F14C9B31249FC04, + 6EFC227515CACDE0F8664EC2, + 8B155ED74D3D0EB7E890E421, + 4EBC561A323AEE4D76AD7906, + 979A030D4807A573FAA18318, + 83BA5BED925F6F827DF98CA8, + 570C35930202882A634FC029, + 44B3428E8BB4B70104CD76CF, + 1D5B751294F84B86ABB11D4A, + 301AF9BA843B1955EE001C98, + B5142BDA7EBA15F2DB1BB3FA, + 3900C9B11914C94DFA1F8C33, ); name = sources; sourceTree = ""; }; 11ABF0A415636F8CD40A3097 = {isa = PBXGroup; children = ( - 2A64A444FB90EFA1B0449A67, - 53C236BFA019E49855DD8A22, ); name = synthesisers; sourceTree = ""; }; + 9D91916A769A7E2967368795, + 8C105487633A9BD04FDEE50A, ); name = synthesisers; sourceTree = ""; }; AF12826F0B38E7FC1176C648 = {isa = PBXGroup; children = ( 56E5D80A2B5A0AB691ABB90D, 976965B1038594B4C210B247, 26A3DDC7B0D9C11EC02E6407, FE8AB04D3B86B9666AD12C5B, 11ABF0A415636F8CD40A3097, - BE990C63B85752BF968C5EC6, - 2B780483D0584407FBA38106, ); name = "juce_audio_basics"; sourceTree = ""; }; + 8DEFACA6858D254B4202AF12, + 3B9903B0A0252D106C92CAA9, ); name = "juce_audio_basics"; sourceTree = ""; }; 3B35E0DA3DB0B1509311FBDF = {isa = PBXGroup; children = ( - E782C5F53BBED225CABF6587, - AB2C5E54CD675401124F26A0, - B0793B0E00A1410BD054B141, - 6F7FBB230E206816379F5C83, - 36E382ACBB77916E0A228CC0, - 730F77EEB7313A110A0B5E5F, - 716BA2221FA9658AEC00A563, ); name = "audio_io"; sourceTree = ""; }; + 884AA1209A726AEAF76E31B0, + 3D24784AEA7726A64A340625, + 4A1671B78E589A865FEA3CB1, + 62E534D1F0B31CD4A1B572E1, + B6173E37D15602163B7C0441, + 4BF9949E0C30EA64B16004BE, + 04C105672DA409FE8593DB04, ); name = "audio_io"; sourceTree = ""; }; D487CFDA56FA408A04203A20 = {isa = PBXGroup; children = ( - 112A4FE3483942AF43D513DA, - 4C699E969B418C7C5EBE4DB9, - AD6517C175A8D9D5A9D168E6, - 6F6DDA3B78AF47374B959263, - 13287EAB1073ED487FE17034, ); name = "midi_io"; sourceTree = ""; }; + BC02503FFF515269351DF89B, + A789D75FEFFFB7E8E835FBAB, + B004D25E0DC1AA2C4CD3788A, + D298D1DE4D2FE281CA30910C, + CE75A83F0AA70025C36151B1, ); name = "midi_io"; sourceTree = ""; }; C3D887B6F1284C2394FD72D3 = {isa = PBXGroup; children = ( - 40673853C7079F0A6D8AF2BB, - 438C65CF8B5C0D636F0AC715, - 376708401BCBF6D7EC1F8725, - 3619D8E6B18F0843E8EAA2A5, ); name = sources; sourceTree = ""; }; + 814E0D982BC2A18B9BAF3E38, + B6411B03A6D0185B11DBDA15, + 911B308D5222BDFD954DBB32, + DFC58448ADEA2B5D2FF5F8D3, ); name = sources; sourceTree = ""; }; 09D6686EACFD43021C0E69F3 = {isa = PBXGroup; children = ( - 9898BBBC81128203FC3934B7, - A873E57D126C8D931CE6556A, - DFD3944531485F2F72ECB87A, ); name = "audio_cd"; sourceTree = ""; }; + 41C74B59D9B392117441DA2D, + 35A7FD6EFDE29D2EBD7DFCB8, + BDE0C2D342D03C389560501F, ); name = "audio_cd"; sourceTree = ""; }; A62DE30F63767AFA483DE8C6 = {isa = PBXGroup; children = ( - 3FEFB6B506459AC93E066C3D, - EDC826A2266EC4945813EB52, - 458072B5FE996673CD03DC28, - 3CE23C91D3F26953C3BE4A86, - 37665101B192EFA4DC5DFE39, - B070645F1A6B85C679B77B21, - 538907D94243347E0BD1136A, - 675AA4F17363E5F5F8B5C307, - AA67BCD0930A0B3B9D0B12B1, - A5A2DBDF9350F91E9D6109B7, - 024386A2F47243403C1E2A51, - 117555C684D0E7FB5ADDB891, - 77EF2BBCC5853A84BB8BB561, - 740CEAD6F3EC74AEE5D29F3A, - 0654450BCEE57AB7EC882CBC, - 302960973006B86172FD4A6B, - 384CF76B2FAEB3A5E935AAD8, - 2C2E1D130B90B220D70A4D7A, - 78E95B5FD8BFF8B51994F2D8, ); name = native; sourceTree = ""; }; + FCA9526394A63B33405F8E58, + B1C799A152189A282E6CAC76, + 2A098563977566E9A9E8CD7E, + F30876EE30580650FD17B801, + 95412F7C12937CC7AC22ADCF, + B0286AC6D04C5D080A299A1C, + 32C683CBA18109949D53149A, + EFA1E7B282EF67800F4766AE, + 55417F6D23E7075E5E27BECB, + 5EB144BD6AC4D4DE96ABFCA2, + 25B41C0851C004C9D410B7C8, + 56545F3F893C3D8CC9215051, + 7AC4D7A22EE9E1F4FBD407C7, + 805F27CEEC53F4E659884D7A, + 29F5A84EE715DA5BCED467A1, + D763221FDA235D75039D4C46, + B2D42B884600CE62E3253DA3, + 5719A93B0F6AFE95FC49B673, + 73FF82BCB568578396E88C92, ); name = native; sourceTree = ""; }; 270A86F6A3CE512F0B3EA8DC = {isa = PBXGroup; children = ( 3B35E0DA3DB0B1509311FBDF, D487CFDA56FA408A04203A20, C3D887B6F1284C2394FD72D3, 09D6686EACFD43021C0E69F3, A62DE30F63767AFA483DE8C6, - 2DADD9644CFA5A770AA513A2, - F56A1C13CA4FCF50685C2335, ); name = "juce_audio_devices"; sourceTree = ""; }; + 442199479D1499B6A44BD150, + B1A41C6141726A390E2182A2, ); name = "juce_audio_devices"; sourceTree = ""; }; 72D396CB5861C9C441B3E360 = {isa = PBXGroup; children = ( - A13F9E4C92A3DD4C01330208, - 09043DFD1720837A928ECA06, - 000879A4FF2FFA74721C7CB5, - 63E5D7EEC148FF82E7216095, - 0CB666093FEE15ED3782D60C, - C98FF9CD6E5BC931F600A73D, - 2CBBEE67AE711FFD4D554623, - FEF0FE795764A633EA32AD4C, - 97984A6B910D0D4B48EFB82B, - 8DC8057B78772BA17A3ADDD1, - F88891B88E872621E6267BF9, - EB3E426C5FF655F7AD88D843, - C6111F5E51935A78B357FE2E, - 72B459EF3E90129FBD1A78EA, - A1C9C360E9B30D43246B9241, ); name = format; sourceTree = ""; }; + A76D6B94991D6E028EE8D1AA, + 0E70A4BFB2F7D1AB6188E72C, + CCF8FB3EA0246D83E3D2E760, + FF1CEE8501CA0F081EE0E3AE, + E1A153E1CA08E918F65C2B4D, + E5AF1F5B3F7F2B30606FBF24, + 853D2D1ADD05C320052DD5FC, + FE55A1DFB90A1A5EF37B1741, + B5C3814B2174E5127F42D721, + D1000A39817E9B771A4FB856, + 71DF518DE7A248B97C8E1C2E, + 6E6672E4055AC4F6D8688310, + 63E66F6D161941FE12465C29, + AD8417869D43ED72319C283C, + 9CC22BDB1B3FF427D6525D21, ); name = format; sourceTree = ""; }; 23741F076745FB046C07FB1D = {isa = PBXGroup; children = ( - 0356E85B3D1970B78228D974, - 423A70751A8C20A9E1C3E9CB, - 692A2B951D818FED7DB03481, - D2BC39EF5E34ACB2BE05539C, - 65411B7DBE47CE3DF4164F05, - 227F70FEE9D1F967CFD8DB5A, - 3413E3C25DD20925BA622640, - CBE0FA629B5B2B352EFF53D4, - B0CD0890EC1297C2C70B741B, - 40D6454C05B1D9E3242CDFC8, - 134C3956C7C8E7CF6CEE8868, - 03D53D0D12365594CC24EA4D, - 256A686F1026814DA7434C9A, - 1C96AD5E5DF22AE45779B769, - C856D47E76BE017D87E77496, - B78FA8958102108085ABE489, - 8CAF2B1BDF49EC845F183218, - DF99FBC1355728976531AD5D, ); name = codecs; sourceTree = ""; }; + AB3C130E565756182528752D, + 7F162E198ECF41AA895DB94B, + 0BC32F0BB0B5393D25E09D00, + D80EEBBDEC364958AE05AFFB, + 0AE6516868244378D09124A0, + E57F103FCFDEE26617E3F8F2, + 932126F914644642A8244676, + 1AB580D4342BFFD41F220358, + 264F684A80B93F7A189A5FA5, + F65A6A3350F6251E8BBF8CF7, + D108D5FFE66F80627621DCA0, + CD4803D5DD14A33CF5AA9FDE, + 4B27C30CF5AC7BFE0AF537AD, + 996A274720539E8497291E85, + 0D530396A7BA6BA190100C6E, + 46885692CC5FDE30FC3649F6, + C52FB75A0A93BB1397D1F962, + 4B8102606812A7964CF8D9CE, ); name = codecs; sourceTree = ""; }; EA0CB9DC4E43539FB25FBC68 = {isa = PBXGroup; children = ( - 3898B672BD3A7FDA95255349, - 98622ABC34EA3DD4334580D5, ); name = sampler; sourceTree = ""; }; + 5774E190A351EDF7B7AAB188, + EA749A33B0E635F691A42C64, ); name = sampler; sourceTree = ""; }; D8CF14F51DEE1EA3625BFE6E = {isa = PBXGroup; children = ( 72D396CB5861C9C441B3E360, 23741F076745FB046C07FB1D, EA0CB9DC4E43539FB25FBC68, - 5434B55E1B4DCA4392ADF45D, - E8E4F93EF596101FE5333018, ); name = "juce_audio_formats"; sourceTree = ""; }; + 768754211363FED3D2188C9D, + 62B6E8B6269ADEF23D85FA3E, ); name = "juce_audio_formats"; sourceTree = ""; }; 2127B046D500ADBA07220814 = {isa = PBXGroup; children = ( - B852DBE7C0AFD11AB872754A, - 94B8132DD5915F30ED7DD249, - B973B2A075C1EE23F2AEFF32, - FBB34D0E335152A813554244, - CAF194AB75BBCF7A63DFDA43, - 34A980957FE5E141693F3334, - E462CDCA6635D111D6B85C4B, - ACF10436974ED4510E3FC4BB, - 995501A12A56DED7CDAAF24B, - 23600EA94396F6E810F1C774, - 2D2048FA048F8CEF2459EF31, - 3E68E00D0D6613D6A93B3ED1, - 17CF86369ED4F4A6DFD8E44F, - B17E7CF3B375FCC6A9178500, ); name = processors; sourceTree = ""; }; + A61AD5378601F9DDEB8DED03, + E323EAC836E3B5BB29B6AE06, + E2E3FA0BA7B7C8EB3C47B642, + ED773069A737B4877D02DD90, + E5B323382721E0B714F5D805, + 40B9C2276B7EF73860E2606B, + 15029C3F041B27DD7191482F, + A8C570DF829A8B8581B4E8CC, + 2D5F3AD1A03B34AE7349DF5F, + 102919EC5BCD10DA703688CF, + 673759E656DBA5A9377433E5, + FAC04A1B47255DA7A6397737, + EC11D53A4118E15738CC70BB, + B6ABBE7782ECD38631EB11BC, ); name = processors; sourceTree = ""; }; DB8C9872311AD82A6BE28BCE = {isa = PBXGroup; children = ( - A77BB927A95DA581268CD729, - 637A70321AC8948BA9E033FD, - E39FB683ECD1152137E3853A, - 5E3AE8001BCEFBED6A1954DA, ); name = format; sourceTree = ""; }; + 8741126A9694372E46E3FD32, + 381B8B8A9D5203E73FED79E9, + 83325A69170997E33D73770A, + F3C52FC514B9B3A2DFD7E3F6, ); name = format; sourceTree = ""; }; CD61E634B4D011ABCFA7E39F = {isa = PBXGroup; children = ( - 0A431A685E635E51B2E20FB7, - 78CE05F96C7E21DEE8D6A845, - D97C2B6C906C1C179598C7CC, - 78FE5E020A7D6EB993701276, - 231F8E834F94B7654941EF55, - 0125A6E329679354E74D2FB4, - 069199E3E835739AF23FAC10, - D3DAA92A27A10FBB1AEC0966, - 849A271BDBC9A7AB9514B8CD, - 442ADB5B235BA350C5FD0BD1, - 29D6BB46D3EF49EF86612B12, ); name = "format_types"; sourceTree = ""; }; + A50AF1519D78428A8DCD91BF, + E587838C598E06E7959F2A31, + E6E99E6E9BB715D12B35AB4A, + 38EDF1EAB12A05CEE439AF23, + 36B8F6CFEEA3C1E2A0D09E56, + 2B02634F8DA8660ED42B0AEF, + F79ADEBA7B305354085FFB8D, + 66E854431C2BBDEE56EA43C8, + 0F67C59CB48583941B8656EF, + BB144FF841A99B08D5479777, + E652F16998FA1CBF2068C6FC, ); name = "format_types"; sourceTree = ""; }; 6C9E51DC570947CDBD246B3E = {isa = PBXGroup; children = ( - 5D903A277EFDDFA522C67E84, - 35F51FC31CE36BDF6D41978C, - 97E51A159B596325E90C5BE9, - 6CD9A954A84F5088471631BB, - 44DE484AE50122D19A902731, - 1BEF05EF0D439BB92AE09DE4, ); name = scanning; sourceTree = ""; }; + 0B933FCCF82100D67C0B7D34, + B7855FA22C92F7EE272A866E, + 2E650C2E92EA2732B66070D4, + EBD6F8CE3122B2AA015A62BB, + A53228473B7F7BCF946F15DF, + 88EF4C8D3A1D2498D8ADB6E0, ); name = scanning; sourceTree = ""; }; BA9B6357DA1BF8D6E3120176 = {isa = PBXGroup; children = ( 2127B046D500ADBA07220814, DB8C9872311AD82A6BE28BCE, CD61E634B4D011ABCFA7E39F, 6C9E51DC570947CDBD246B3E, - 23CC00FD68EF7CB9A64D9EED, - 17E9D0C9AC68F13FB1A763CD, ); name = "juce_audio_processors"; sourceTree = ""; }; + 3F0388309395C138AA68FAD7, + 6E841DAA09FE06910D94447D, ); name = "juce_audio_processors"; sourceTree = ""; }; 8C7AB91AFCAF2F99D0E906B0 = {isa = PBXGroup; children = ( - 52C131B4F65C596E275CC17C, - 66EFBCF1D3E6A5FF27129EC3, - 9980F9FB908ED20591475FA8, - E7C5065D5E153DFF6308D5F3, - 72CF68A2C3240BFA2EBF22AB, - 3944FFE845F494F9A625EC67, - 7EA9B430B1998ECBEF70D2E2, - 1557FF99F272F107A90B15DF, - 646046D51C5B2655CC633415, - D79EAA241B5FA1ECFB84614F, - 4128F91E323A32B6D7189CD5, - C46FC2DAD97DA825D6449A2B, - E783E1B6AEFF256939443D39, - 12967F8EBAF9698288C8A5D0, - 0A7FBABADCBBF00C2A842D37, - 8AD5A845BBCF5ED0E6AA5922, - C12AEDA7D0BE5A220AF9D30A, - 6F2E3A5DC0BE1D6917784F47, - AA251B07162ABAA59D3DF432, - 72208D4BA50D37B9764FB56A, - F8CC801FFF5B4B004707190B, - 02BE2D3F87C20BD46CEC2981, ); name = text; sourceTree = ""; }; + 5A854859042F6CD761688B25, + A42A97232CE0593D8D989FC1, + 8E407C1CF739A93FD2B3B38C, + 7AC8C094442A603DE6257BB1, + 4A86B4371AE4FC58D879962C, + D6ECAF8B2A4E8B6C97B89FFE, + 1AB9713046E08B68A6F672CF, + 22C4F82B505995F81CD682B5, + FF7A26DADF1579C43D80454F, + 916001804771DF943551AAEF, + 61797A8C01DC08E83AFA4540, + 935BCEB2593A51E53187ABC2, + D9FAC914CA572410C055D109, + 17B07A06764A6A7759804033, + 14245CED80854EC5291657FA, + 926063234BAFA6D29366E43E, + F4454839EB930FC98D63AED3, + 389B4E4055A779D0F6B22C5F, + 1450CD0879661355CD52DD8D, + F2A1FCAC1825462CD568D442, + F49471EE0681DBD1115D927B, + C0FDDD3106A13770B141E5F2, ); name = text; sourceTree = ""; }; 6898E6C42CC9520DC26F9FBF = {isa = PBXGroup; children = ( - 43BB532CBA295E02FDAC1CFA, - 80C52BD7C8AD60FC1584EDDD, - B65CD1D011475424E927B37E, - 6EDF4554CA5AA64920F95E5E, - D535D69439B72C799B61DD37, - 053C2C09700A8BD5DB4B416B, - 24006F32DA24D5C374C7442A, - BBF610446898623948599114, - 8F0BDEECFD7200A7BE6FC598, ); name = maths; sourceTree = ""; }; + BAE06A3352E39521CE5D94EB, + AD41400898312123119E987A, + A3D0C263C912566AECB57679, + AC42B6006776E1CE3A3A94A0, + 1B3CC8F665F23CB86253EBCE, + 4B8342C50F962C3F0AEE9830, + 8B7C0F839098C534A7B4C725, + B28F34DD7CABFD48B1EE3CCE, + CA025D4369C240E6FA30CE2B, ); name = maths; sourceTree = ""; }; 01A8BF73C8C9D282E9E58D7A = {isa = PBXGroup; children = ( - 6D111AFF5B12430B6A225802, - 560303C3ABFD2D8DA80F5369, - 160E2EF9685EDF05E2A5EF32, - 53972777A5EAB63C5D1DF5E5, - 08CAAD932D355E493366CEF3, - 48B1172E10D1795EFD5B4731, - AD6AAB2F586CBD4E35D5167B, - 983D92711EC4B001DEF300DF, - C18E1D4D4D0E4F6B0525C212, - 8E6D4E8672ADAA47FF421180, - E7733DCA05641E94C0714362, - D56619E400C7A4619515AFFA, - 3BC29BAC09BDF8518335571D, - 8755EB7CFA4EC3C0AEBF8E26, ); name = memory; sourceTree = ""; }; + E1AC4AB03052A8F3FF90FBA4, + 4BDEC9A0A09EEDC9D7BDB826, + 08EC867C77B028C336B79752, + 68097881EEDDE0FD03100CC5, + C0BA74AF0382D87B0E7BCEB3, + FAF4C6D8D1D59932F12DF6A7, + 8C6A342773288620A8CC2598, + ED5E6273C8910BF1F8CBDB9B, + 097237CCE04B9020343CB28D, + 61F0D5937E23A6A9EE8D479C, + F22781915698D59D4CBE984D, + 289C3977B67C1898AC3B974D, + 4A36826C3F710B92F0347A16, + ED7E17722B60B7D89188CE60, ); name = memory; sourceTree = ""; }; DD57AFE6D9A0218912B3DD93 = {isa = PBXGroup; children = ( - E508FDD5269C63F7D0E08E48, - E0DFDD144675EF457B607E50, - 3F1BEF3D596877977723184D, - D6486972C28234B51D512700, - 98ED7C529B2A40AA4C0527DD, - B53B0352EAA432B0179F0201, - 60E972163AE7F32E1AC7BF57, - 620921796E4C408487F2D19D, - A8DC0ACAAB88D6657355E466, - 358F95020BB4722C04756E09, - 6B3FA3604D7E751B8F18E841, - 48BDA8E72F3E90C3DF0F9B91, - F70EA6F5AF8259555E8A80C2, - 92901C506127F45E3F5B258E, - 4625F35561AEC875DBEF087B, - 95A59141DCE1349CC649FDB2, - 064D5359A45F91751130CB6C, - E5608726D3CC8DDCA57635BF, - 54369A3FBDBDCC0FED963610, - C609197710C7E8DF361C4556, ); name = containers; sourceTree = ""; }; + 6EEECDA2EB328FB597208954, + C7581A35068A3FB43786F4BE, + 0C89377A44F26612524DA129, + E973909AF8AFFB788A250CB6, + D12F8398C3EA9BA0FA88B5CF, + CCF94157A15DD29B6C5DA939, + FD1FFBCE5E94D08B6FB60F70, + FF70C4AB4F37D7C7E1668660, + F36FACCDB4B94286F6042490, + DD2007C851B70E2C71171145, + E4D5FB6A6F806D9400BBF344, + 3A9FC7EFC378976EE696AE83, + 749854CD2D13BBBA500F353F, + AC725293BD38E8C66E35EED3, + D949A0753DEE4B4AACDDA3AF, + FE41044F09ABE0A6BC0F9293, + 4DB2143B264FC1AE54490BF9, + 55CEFA60FA0CBA0E6CB71F5D, + 4570554FB8438C0692EEDC55, + 1C71768A34644733E39EEF4F, ); name = containers; sourceTree = ""; }; 7A970EF4CD9FEB460B82CAB2 = {isa = PBXGroup; children = ( - 53C4988130522C6DA28A4BE1, - 0E4F0DA9ECA921AF8E835E19, - BCC1C92B775AEA802A0AC917, - 355AFD562757A4867440E64E, - 1B01AB28846416D9B0050D4A, - 662061336599080D7C0ADB56, - 4563BD0A5FB10592A3DC6244, - CF768CC6E2EA5664519C1C03, - 669C2806A49522217459BB3E, - E34E03B67A82E30F5CD201BF, - B3EB470623EB09A867A9383E, - 729AF566D1EB32D59B8776F7, - 752E683005CC56CA4A552261, - 01E5B72E5D7115CFF884BB86, - 4079EA961E5AFE0A51869E40, - 968B7B6F9C111B514327A382, - EB4083E018759B2F9C29C67E, - A3405DF38FC19128C399E497, - 723111ABC4D02840963C6FC2, - 43F755438129CF5051D3C8D0, - 6D4CC9AA8FAC940AA974DF33, - 5DF85E59C6FBA88E394C4FD4, ); name = threads; sourceTree = ""; }; + 381AE52C082AE08E724CB954, + D11D931DAED4F636E8A60264, + EA5874F225E76DED69BD7132, + E7EC04A96E1CBFA9428A4B80, + 3AE89D0904EE985359A73B91, + A292587AA4633141BA378473, + F9609B0A0387932B86A6FABE, + 9F522CA5A8E82BF69E7403BF, + F5091F49E07C6DF8F644BAF0, + B409D881BE39C4704C94996C, + 69A2DA87D304FD486A872C1B, + 0AD4B355DBB0AED4C90E5657, + 91D09C7242A24405FB364449, + A9608756E1A18BAFCC48A064, + 44185DE135E354DD4758B3EA, + 426283CFD858F482E87F530B, + 6F6F888BFFA4BB40DD71285E, + 390351E336C2CF20C38ADB59, + 897B10399D1CA882B5B98D0F, + 7743414F79908801328D9F03, + DE4C0926D2EFA7649BD3AAA5, + 3E19A71C4A345EB5C1BA466D, ); name = threads; sourceTree = ""; }; A7DDE84C6BDC340DFEAC5C86 = {isa = PBXGroup; children = ( - 625D1399D1DC0CE04C2BDF7A, - 53CB2A656137C68DC54B43C9, - 12503429614C443A89A28FB2, - C920268F5AAE587A04131F34, - 292236D5B7928EF5C6D73341, - 9D4642C9C308DD3ABB2DF731, ); name = time; sourceTree = ""; }; + 24363F41974FD7A3B634B78B, + E21A45155C6954C6E50CCAF6, + 4ADE9EFB6C41DE44D40C9837, + CE19308F9CD1B8F05E6EF6C5, + ED8032A884A03337DAA1D453, + 5CDC0F220B1EAE847D38D1DE, ); name = time; sourceTree = ""; }; 0B90B115C693F54D5DF8E732 = {isa = PBXGroup; children = ( - A4A99FFB9CECAA4B4ACE8402, - 0801100E90790AD44224848A, - 9F077D151CAAB48E1B7A4A45, - 07DB1C038E8EF1D3628F6B7A, - FFAC8C8B3CC3F05E12744D1F, - 9D4BEB15620ED88F95BDF105, - 2BB91B988601A784CA953116, - D69079E0065151480B46F7B7, - 4E7B7D1DE6EFB7C38845D97A, - B3D51DEA0DE311B017CAB716, - 517756F0CB6482D0AAF4F6E3, - 6B3ADCFFE9EF5870BD04FA95, - 621EA7E956C5BA64D95DC755, - DECB3C3714353AE5775147AD, - 077B15886A49C2DF26EB7186, - 16F835A428874C108CE94490, - 6D9056359A751B000DB1E9B3, ); name = files; sourceTree = ""; }; + 9D50B3000D941FDCB620068F, + AF885F6112CEA5C2D7934AA3, + 3FECAB20E9C0834676E2D9EB, + 175654F2545AD9C0603BD0B4, + E443717EB8EC16A0B1814BAC, + FB459E95101C8A92E5B39A67, + 57490A9F97D62E7A312EA90C, + DFD9E836DB24F4DE75A94C29, + 87EDBC629357F63AB8E7B507, + A23966DF7E681FA878B27B92, + 70B18C93C5696330A877B330, + 35AAFB158E16D03C4D977713, + 605EA4B27D057BCB9263BCFA, + D10497F87C560FA833756730, + 176B18B9B61FDA6EC4357EB6, + 07C83735435D264F28158F79, + AC018F2C47CF57EB4A87AC36, ); name = files; sourceTree = ""; }; 9E9C1F84B44CA85F5F472594 = {isa = PBXGroup; children = ( - 95244870E8E9CC3CC6FF33C7, - 150E68F9290BA3701DCABDAE, - 23B94851B96CB057621E0EBA, - 6F195B4646BF53D1918F1764, - 1C9B9B22D2CD87C0D160892C, - D214FC393B8C9A379FE3C6CE, - 4CC30DD2477041D19048C805, - 738D2ECFD31190494B40BE78, - E9F7C31F43B7F22018E8170D, - 51EF1B32326BCE4445FD8929, ); name = network; sourceTree = ""; }; + 90B6C81CFB0DE386C673F62E, + 7639526FBF7A4F41961483ED, + 84ABA9491A70313AD6BF6F9A, + 6A22C06C6FE2B6B494B4878D, + A4F394FB62E70E3A3A02E4C7, + 8C3A6351780E678334FA1406, + 9E44079E499D4F4ECE55354A, + 2B57EB41D3962E3518B79FD8, + D6D37626671B0FB1CE8505C9, + DBFBBC58ED4A18EA9FE04D1D, ); name = network; sourceTree = ""; }; B87CA56B966A881DBF190AE7 = {isa = PBXGroup; children = ( - E7DC2D13A73F3CDA652C9DF5, - 37CFAB9F13EC95665CBAB742, - 1B5BCDA8B68284F2FAF17FE4, - F94ED23A0C2454ED44C7B53B, - 9A160557777085A813B1F0B5, - 568C771CA43B20ED9320E9AD, - 94B52728DAAC5E3BADD03617, - 6DA5BE65E7A6BAAE4797856D, - 97B99BA54C40DB3348086461, - 702AE0E6FC3184CD8E83643B, - 1FDD5774A3619E6116D1A542, - D18648E47B5447E1F6AEEA52, - 61E5B74F334DF6387DB68E7C, - 223EA3BC50EEE65DFD1BF515, - 37BEC08C61F8C221C4BED7C3, ); name = streams; sourceTree = ""; }; + 23936BBF807CCF5B1EEB9F00, + BDA5B0C014F6DCC188465060, + 6C502DF33FB5C14B8A67B25D, + 7E0DD06926DAC8EE93BD4F08, + 6421EA349C5D558114D36717, + 440A182A9068A8FBD011BE1A, + E5918150BDBDBCC3060C9FB3, + 47E70AF805B1C5C57566C4CB, + 52062790A5E737C8846A23A2, + ECD7A374DADD305C66141AF4, + 8945894D17A9407EEEE3B8BD, + 07E19FB806980020A47AA47D, + 803480FD5E7181E0D64FFC53, + B305ACE053406FF288E500F8, + D0AFF0790D81DB8F66173737, ); name = streams; sourceTree = ""; }; C0BC501BDABAB02545D8CED7 = {isa = PBXGroup; children = ( - F71DF877F3D13B350F01DFEA, - E965D6B8815E3C5E8A160C48, - D568CB3943835ADB2613AEF8, - EC9AF66FDBA32E129D80E59A, ); name = logging; sourceTree = ""; }; + DEEA654926310D5B37A191C9, + 234D4927B398ED6E9B7B0E6B, + 5D43D909CB26D4A07A62A4F7, + D52EB7F089EF359EDCB199AF, ); name = logging; sourceTree = ""; }; 314A7534CB4D49F809F0BF86 = {isa = PBXGroup; children = ( - D0D3C2CBD0363F82E5D9B092, - A4F8C1DE149AD44A83143598, - 30236ADC490891CC1557AE3E, - 15F7EA4ECAB7AD7E50A11065, - 62FAD1304BBC71BEDBB033D0, - D61ABCB4D785A183EB967AE7, ); name = system; sourceTree = ""; }; + 7141B07690C1A022A2BFFBBB, + DAB059DA13868A81301513F7, + 07342D914D2A5AF6075CDB2D, + 3CD47BA1CFEFB637DDEAC313, + 03B79DBA48F6C4122DABEE90, + 67895BDE8FA4B2A01E3B8B12, ); name = system; sourceTree = ""; }; 61DC39E8E45840C4E9876585 = {isa = PBXGroup; children = ( - 500556EB77FC460F48E018BE, - DE48404D34F2CAE314CA4E19, - D00090B2DE234305128AB650, - 09BB7D020FA96EB044330205, ); name = xml; sourceTree = ""; }; + 03E91AE23ECCF51E3AF9FC90, + D19705FE67C941DA74C31A9D, + EAAFB86397B191FF3713155B, + E40FB3B047D27337B9A9CACA, ); name = xml; sourceTree = ""; }; 044DA355DFC10789F7E2671A = {isa = PBXGroup; children = ( - A72F50930E3169EFC9724597, - 6B0CD9C29CB8715C6E916244, - 9F69A9E1418A5E3B33EF5B26, - F0FA50C01669546088DA6DB3, ); name = javascript; sourceTree = ""; }; + BD7B0136829554046A511588, + 9DCDB2CA1444618C4054A114, + 1737596EB7F40322C0A5DE20, + 5C58E6217AF57BD2A33ED617, ); name = javascript; sourceTree = ""; }; 9EE7BD032D2E50758043A0FF = {isa = PBXGroup; children = ( - 27ECA38DD6808A358A90E7EF, - E15C23EFF754E1289CE5437C, - 6726A33668AC0DB1B5E30C65, - DE579AF9E1C7F5EA0B7A87A3, - AFC498B17E8D5B122DB666C1, - A4CACFA409866E77F609126A, ); name = zip; sourceTree = ""; }; + DB1C6393173661404927B4B7, + 6C03031AAE5A7C3372D4F1CF, + FBDBD56614E38BB5A5592D32, + 9F7AC745AA0588C821A014D0, + 3FAA5384DA8B28DEB5E57A5D, + DFAD61F886BEAAAE535BBF81, ); name = zip; sourceTree = ""; }; 6BA585E8E2F21352228FF71C = {isa = PBXGroup; children = ( - 3C55CA36E6DF4478E7C2A106, - 11736C186EBE80F228E1D782, ); name = "unit_tests"; sourceTree = ""; }; + 5878CA91071620345AB5B3C4, + 1E6EF8035485237EA92A1310, ); name = "unit_tests"; sourceTree = ""; }; 246C87B7ECF29ACA118F0242 = {isa = PBXGroup; children = ( - 5E5F9CA2713C02B4DAAEFF9C, - 4E02D9A4D6D38BACAB9326AC, - 9444AB597C118C99704EFDF8, - 987E21587B07462F5098831E, - C44BCD4A16768A91B02EE14C, ); name = misc; sourceTree = ""; }; + 9C17E6FC9A4D7C8734800649, + 941219816EB5D7A2231019FA, + BACA17304411EED8B219D2AC, + 98D247A4824D969367AFD0FB, + F73B6D934AEC9887D9EBB5E2, ); name = misc; sourceTree = ""; }; A37D31A95DAA40A87611411B = {isa = PBXGroup; children = ( - 77FD526A14FAB45DF30CDA71, - 8438D37046A9F805AAC7401B, - 3FD4B7D9E2A8CC22D8F0C974, - 5550F75596B1C84414059D9C, - 8F3E6744F26B7BAA554F4E41, - 5C3EF1C1AEC96D6C8687E242, - E16F860A9AA000E590BE321A, - 03F15E955CC6905BAC120050, - 0A79B3C2BCCFF8C8D9837210, - 7349C82FB18B8E194B854DB8, - D720150F1F3647538D037677, - 2B835DD803DC7C2379F3898A, - C98926DCE80A0B3149961D0F, - C8AFE60B7174C0006C1C85F3, - 6EC413415C211744AB3B7E4C, - 7E62DD6F1A2FF13D5095D218, - BD455C126781EDA150C9298B, - 189CFDE7D3BC22BFE5CD87AD, - 3748D31911777A17CD3C20A9, - 269DDBC16D9F714A0B057A94, - D3C91BB5D97D3CD7411D718B, - D528C603E1870E0BC562CB9D, - F79AAA52220D91666D8B8771, - 584FB01EADCAFB49A98CED27, - DC4F26260A712654A80A2FF5, - C8A93F28EB0AE4F99767EE47, ); name = native; sourceTree = ""; }; + 6238740697CA1F0746776243, + A782FF0CD79464F3E015647E, + DC3B995E7B51FC0B76826C86, + 8C24F74CB23F1B82C80386FF, + C186342C3FFB4DE250556D70, + CCEBEEF441D3FCFE411AAAD6, + 823BBAE97A02475F25E54F9D, + 161F35FA23347F495704C26A, + 9FBAD3EFE40ACEB06B155A09, + 13430EC7CBFEF46874F53731, + 4DB48F6BAEFA120A31259EAE, + B15DC22CA1E52983F4F57A9D, + 5703889367170F80CAC76898, + E0A44ED2A465E22D93420F88, + A2208C87019608EBF813EAA8, + CD405182963BEB73FB9E368D, + 9C8263A9C3210CBC6C909BDF, + BE64EDA4F7260D2D5B7E0410, + 618839275E13B9DB660001E4, + 84494501A6148DAFE162650B, + C9BA40AFF2AD427CE4D480D7, + 02AC998E808CAF5C148CFFC5, + CB5874E2A70E8A6A01FE8C9F, + 7DCF49E37B27971A7E597555, + 843BE36A2285F73A3FBB5660, + 40F0E944D041D96F2DA4C6A2, ); name = native; sourceTree = ""; }; 5CF56D8EDFCB4673E75EB0E4 = {isa = PBXGroup; children = ( 8C7AB91AFCAF2F99D0E906B0, 6898E6C42CC9520DC26F9FBF, @@ -1329,182 +1329,182 @@ 6BA585E8E2F21352228FF71C, 246C87B7ECF29ACA118F0242, A37D31A95DAA40A87611411B, - CCD5CC6545DB9D9FFBB99D46, - 0C4D86B553BCA2945973736E, ); name = "juce_core"; sourceTree = ""; }; + DA353BCF838D64BA343AC0E1, + 74302B51B991EA1775AEFC67, ); name = "juce_core"; sourceTree = ""; }; A24377A329F782F1DF1A9E92 = {isa = PBXGroup; children = ( - 2075736FC83122CD98E9448B, - F8E876D642B7406D7D706491, - A8C6E967CBC442F331571870, - 991BB887EC327D340E5AA659, - 434A87588331CF1CB8118A36, - A76327DF3D3A1CB89340C2CB, ); name = encryption; sourceTree = ""; }; + 9C05D3A33B0D7B6B2EA43C7A, + 567D63D778B7A22C5D97F1C5, + 9C599E35E8A990404EEF805A, + CFF4FDD0FC27C36843B20BFC, + 29D35A5AB22E9443E0ED8F99, + 66897EA1FD2CDFB4CED47F8B, ); name = encryption; sourceTree = ""; }; D05EA809F9DB6CFD6B0BFEC0 = {isa = PBXGroup; children = ( - 0906C93F178388D7783BCC92, - B14C06A5F45ACD5D93357F96, - 776774969BC27F7269A3B520, - 4B09912103F721693FB77FEC, ); name = hashing; sourceTree = ""; }; + 4C87C8EC24CE0EB64640238A, + 2CFC9FB97ED3587D7E0E4E4B, + 4228B8952E3FBCDA69C1948B, + F8EB370470B7928A80032F7C, ); name = hashing; sourceTree = ""; }; 752AB8D433735A877FC90255 = {isa = PBXGroup; children = ( A24377A329F782F1DF1A9E92, D05EA809F9DB6CFD6B0BFEC0, - 81CF3953D1337AD42C542403, - FEFA7D5743E1801CB7CE041E, ); name = "juce_cryptography"; sourceTree = ""; }; + 19DC6BDBA978DC67B9783340, + E109BFE0F2475C97F17CA5AF, ); name = "juce_cryptography"; sourceTree = ""; }; 569E6262B6ED4B4C394F150B = {isa = PBXGroup; children = ( - 05D3F009C15785143F3D31E3, - 229DD5C0EF1D6FDA625B85A9, - B3E93FD47ACA9498963C8A2C, - E19A17B7DFC2E18AFC90946E, ); name = values; sourceTree = ""; }; + 2E96848340E1C1B1095AC1F3, + 9A4FCF66FF42906A7A2187A5, + 2B1494112273ADF380C99FD3, + 73CA6BCA313B0239842F298C, ); name = values; sourceTree = ""; }; F3B535506E5F093EB8206BDA = {isa = PBXGroup; children = ( - 40B44760A3D17F9F97B857B3, - 9E22E973F5C7E6AF1004EE8D, - 1B96C0BBFE3E1A61E50E61A4, ); name = undomanager; sourceTree = ""; }; + 616493921A733162495E7553, + 369C06F1DC7B3B7EB497D062, + F7E781AFAA34B511C812896A, ); name = undomanager; sourceTree = ""; }; E4B1CF3D54E0B5547CDF9A87 = {isa = PBXGroup; children = ( - 7760FF1BA004BE4D9CDF1AFA, - F347EE9BC419DB1879790131, - A97E3E8BDA867CFC443D8D21, - 5B679BA94EFF51894AD674EA, ); name = "app_properties"; sourceTree = ""; }; + 09846FF5D2FFB83242A02FF4, + B4769129853D2822D3DB38D1, + FBC55E440EF1EA83FC0DAA5A, + AF59758C300E586A7A6338D1, ); name = "app_properties"; sourceTree = ""; }; 670AA26A4F8D5CF111CE304F = {isa = PBXGroup; children = ( 569E6262B6ED4B4C394F150B, F3B535506E5F093EB8206BDA, E4B1CF3D54E0B5547CDF9A87, - C5D7E8FD3897F200069DAF62, - 8854EAFDD3B68BC78E0A1F89, ); name = "juce_data_structures"; sourceTree = ""; }; + FB81D25CF4825A9A186B6790, + D3B4D56DE3F90D9A445A47A6, ); name = "juce_data_structures"; sourceTree = ""; }; A9C383106F234D341DE730BA = {isa = PBXGroup; children = ( - 572F241637045113CA1101E3, - 70284B038C6F9030F7CEDEE7, - 1B14F64034753EEA8B94AFAA, - BFB2A78106121AE2F199055C, - 659511EADFE62ABB7141CA89, - 844583A4973FA34A3FF6DCB5, - 408F458A6E9A71923FC72D04, - 45E9503C1F2B4418E687E9A7, - 8D4E99621AAEBA39CCA68C41, - BF64F4ED5DF12FFF99C826AB, - C97E9F209C271E901D31304E, - 980A1CBA9A6D4B421BEB00F7, - 057EDA2ADAE5945C87E9E94C, ); name = messages; sourceTree = ""; }; + EEBBCD11005AE9AD87B36F32, + 868955327EBBD0C2C2447DB3, + C5C3838D0FDC65F44C9D1A9A, + F3BD246F4283B08B1E21C75B, + 3324210159E5C546DC5C2065, + 6804336FE1AB499087ACE437, + DB4AC9766332105669D51C1E, + 314E9338935BC33A1C468B3E, + AE381B9D6E2A4DA363C7DD3F, + 8C547C48DD5B3A854DBFF0F3, + A54AED02A4929ED6EB693CB9, + AB856191A15A8C9016D974D5, + CD965406DB7511EB187919E7, ); name = messages; sourceTree = ""; }; F197372050DC8782B9089C8A = {isa = PBXGroup; children = ( - F9C7BCC7CD4D4FC9CDDF77A9, - DA93B8704F3EC4703E2B2DC2, - 971D7A721F741E81AACBDBDA, - D4D9555F85A739252C027F45, ); name = timers; sourceTree = ""; }; + 7A029D97E723C7F1BDDCAA49, + F3A0B8ADF39FA8F15A6D8E23, + B6D9BF4B75784D01B7CDE1AF, + 7F2BBAF79EB32BB9904A76FF, ); name = timers; sourceTree = ""; }; 59EA583396C9C41EDC94D5F6 = {isa = PBXGroup; children = ( - BA97D0B8F59B68F245351F01, - 940BD46F150595E60976C487, - CEE91A9F1C74260FAC3E30A0, - 19F49DDF17B56B3F0EC5D80D, - 08684D02269A6462E874F392, - 88046B20D38387F2D2650F8D, - F4DEDFEDF1B16C6C48075EFE, - 6544288E0768C9FCABE3B081, - 7F5AF8186ABA8353EC1D4A24, ); name = broadcasters; sourceTree = ""; }; + B32716A0B0702E6861726529, + 2DCAC1795F1B47C592E65D4E, + D7C8F6360C455C0F76E35978, + 59CAB9E5A0CBBC51342FC065, + E70034BF5EF1721B245C3079, + 142D03BC875BD387BD10C51F, + 5C62F423D8469A02E55BF59D, + 435858CCF38F47E9AAE1B08F, + 5BBF8CA223EEE4D9C769E453, ); name = broadcasters; sourceTree = ""; }; B90F0A1A63C3408C288F6D8C = {isa = PBXGroup; children = ( - 43CC35E1310E10B9422E98C4, - 7C36F478BC80A41544C634C5, - 39562A408421F133E35C495D, - 54C1B379B72BAE39C06D9BB0, - 094EBE616E535FEACF39583B, - 4B2CB85C841304CE2E93592F, ); name = interprocess; sourceTree = ""; }; + 6D3F3D0139FAC58B2BAA6047, + 9DC4092F746AB0F5A73D929D, + A587862CF3C96C6C648216A3, + DD73087B002B1DB6B90B666E, + 4F5DED2313FC69EA518E5679, + 1E020B9E032C076071700CEC, ); name = interprocess; sourceTree = ""; }; C271DA3D9CE655C433BB4DD3 = {isa = PBXGroup; children = ( - 8F8C1B89ADC4FF3D985E4444, - B989CEE19057D31C6D521BBC, - 27F470103D4B980E2E8E8AEB, - 320CA688772F770F113A99C8, - F3331BEC83A436D9CB3B9131, - 73CD9E5A889A13890247BA55, - A66CD58D6A8F18628AF2BFF7, - 3DDAC0076D6C914CE76C09D9, ); name = native; sourceTree = ""; }; + 88CC8BC2EA8CDB378A03FADA, + 3C89D04328C83D2FDD4E5116, + 89CBCB2D4660B56C1A939011, + 7627F01C1E5383207D2C0BFB, + 17B2789DEC279EE7DB8D9BE4, + 93667813A711750790201F8D, + AAA3ED492FF78DBBF86DC612, + D219A10E7C41110A1AA4FBB9, ); name = native; sourceTree = ""; }; 4F8A65DC4E47B7CB0DB88369 = {isa = PBXGroup; children = ( A9C383106F234D341DE730BA, F197372050DC8782B9089C8A, 59EA583396C9C41EDC94D5F6, B90F0A1A63C3408C288F6D8C, C271DA3D9CE655C433BB4DD3, - 74E4F42C4ECF1C1D2C7873AF, - 678267D32EB2BF8C0D1217DC, ); name = "juce_events"; sourceTree = ""; }; + 7C7B6D8D155687966F681F5B, + 63B031ABCF8DE5C94889823B, ); name = "juce_events"; sourceTree = ""; }; BA53DF8ABDA9DAD0F963BC8B = {isa = PBXGroup; children = ( - B8DF17DE3A37A52E3514A492, - 83AF4F43D85DCDBF318BEC8B, - 3352C1259B6E110F6B0A835B, - E15E5A1710E50FAB897B4310, - 1AA4BEC9E981D64B98626682, - 88D72DB7B94A70CD9EE18440, - 70835A4653D8754BB6C7CFE2, - 75CC726CB13BFCCF00F99DF3, - DF7A0D14EC237709BAFE9224, ); name = colour; sourceTree = ""; }; + C7D5A8B28D0B7DE58629AA04, + 5C8795B0DE5C729CA18FE89B, + 2E2B14A2334528E4405AEDDC, + 8A4A25946040DED54DB8F3B1, + BC0ED0B33BB83E19D9609152, + C776DAD938AD7E1207DBCEEB, + 5A1777E116DA01B554C90CDA, + 236F239E035044438B7CDFCB, + 91B991143655810C26644D50, ); name = colour; sourceTree = ""; }; 88878CC1561F13CF681027E9 = {isa = PBXGroup; children = ( - 56DCDED7C229BEA998AE9610, - E7B310562519AC9C1FA14CB1, - 7A6DB25F73AC07158A74D006, - 6B8FAA45DB6613DA449E26FD, - 7BD61B782DE61C73D8475002, - 46A5E45225E1FDA3975F6C83, - E63BC85590BE7258F35FA46F, ); name = contexts; sourceTree = ""; }; + 326E293A87E18FC3FBB26B47, + 2048DACF787A9BFE011041BC, + EBC4E11E36D206EDF01E6EB0, + D0A5B1AE7B7B56633AF2D5E2, + 64807B3EFFBDC3348512901E, + 123B63088FA1C4D1AD225CDB, + 2FDA8843C89E2D7DFBE3FBFD, ); name = contexts; sourceTree = ""; }; D5CDF20FB8932DEA5810EEE1 = {isa = PBXGroup; children = ( - 1173B2E45074397470CD6EA6, - D18690CB0E643C9A642F73A6, - ABA9367C4E66F2F18E813816, - 1EF1157A189C1B7D4E20B5AE, - 6AEA07E5992D813558940710, - B4C612999A7FF20800CE507E, - 158D17EA6E11AEEEA7D524D3, - A751CD8564B7B6B0EBD643E2, ); name = images; sourceTree = ""; }; + BE61994F6993AE76CBBF1EAB, + 6911E01E967839199E4C9822, + F994D2E0DF00D0A7765068EF, + 2807A00AE6C4539CD935F56D, + 94FAC7EB87C8EBE67F68AD60, + 9FC1BB191F1EB657A181866D, + 3966D734450E72F5682D2F06, + DE4DC23FAE4C420D489ABD17, ); name = images; sourceTree = ""; }; 2C9A23E9808933102222B6EB = {isa = PBXGroup; children = ( - D7D4E1A29E0B3A33814C7EBF, - F27EABE98642759DB9C4DF65, - 3D906BFC50723AC77213FB8E, ); name = "image_formats"; sourceTree = ""; }; + 55D04DC4EA2F037CCD5DF9A6, + 244B9B4B8307A8C51207D457, + 4FB8B3386156F5702A20F7D8, ); name = "image_formats"; sourceTree = ""; }; A0E5437DC111A1AAB63CCD16 = {isa = PBXGroup; children = ( - 705C1BA65E7FB620E01B44A5, - 52D6B752BBA03EE32E0186EF, - 9E6F450E5BEFD67159EAD012, - A90C3FDE58F6023CE19ECCEF, - A0EC1B71A589996CE32FDD1B, - 3AEDB68E416A876681F89985, - ACB0BA25EA85951D2A75CC62, - A963217BDC628E29845AFA5F, - 14875F3B31704358EBBB4F9C, - B6BB67F1186B3A3DB89DC02B, - 747EC1715A027D17F0082830, - 4D67518B8585D2075E450D75, - 98297330C67DF9D0059606DF, - AD7F976713D7D3B057793A42, - 3DC4B655D395BCE7D0648755, ); name = geometry; sourceTree = ""; }; + CF4DDBE1126E8C8C3A37DC78, + 2CFEB3BEABF88B0C41D94E94, + 92172AE93327D4F8008A0AFD, + 3095D8D2EF68D6ED502EB00B, + BFBF32B0E491C9D4527DF9A6, + DE1943CA08D7FAB2E3EC0A14, + 2AB2B4CC891E77E2DD062BE3, + 5D1F3BD1476426752ACB1EB2, + B471C2AB67E7C68D1C7D729D, + BEC8EC4C23F9AA5C8DFEA15A, + 2B9907A25C1C36C1E46BEA65, + 03457E9DD2B35D7C1B0C7393, + A54B5504235B3324635B1DB3, + 3AF114AC45249CDA77EF940E, + B6BE7EF02190070336E63E89, ); name = geometry; sourceTree = ""; }; FD44264B8C9437DCF22CE602 = {isa = PBXGroup; children = ( - A4DDA56CCF451DCCA2F47D42, - 16DA31B062407BE595BD2E6B, - 9CE19F2F963112A2442FF86E, ); name = placement; sourceTree = ""; }; + 610F820C21D914E9794A36EE, + 7BA2EA5655704E5358ABAA9D, + 62EA5E33A940F30BBB56E293, ); name = placement; sourceTree = ""; }; 5BFD15FEDAA57F0C3DA99850 = {isa = PBXGroup; children = ( - 227CEFF1628076DE7A6D5A82, - 08BB70992D33D8DEF932E9BB, - 62F3157710E0EB1EEDFC71DA, - 62FE07463F39D02D8C6F2CA5, - 398508292A45E227D66AC0E7, - 0CF71E055B7DC5BB25E8CC20, - DA54722A7C1A958B80B9D10A, - 5E135BD422EF904C0FCAD1D0, - AB7C518F617F260822A67872, - 2E91EB1BBD0ED5BC1D0A95A4, - 88A8541D309794713923E3D1, - B71187E41B94D7913C1791AE, ); name = fonts; sourceTree = ""; }; + A010D6D997B85A393165DAB3, + 44443DA5B0FDA2480DFBDFC7, + C6CD42F1DA2F444A59CD4AF0, + 2A771B60F7C360A111F75AC6, + 1A667A0FBCC8FC7EBBD15B20, + 6E0713769EA84EE0471D9811, + C73B4B312C3A4CE4F8E742C2, + 42BC8303198293E30AC0B21A, + 393D0CA8D89217F1F2504768, + F64C6AC0DC0376A80A74A82A, + EBDC0E12D4ED20F5DB90BC26, + A8A277CAF10A3FEB258174C2, ); name = fonts; sourceTree = ""; }; 2925596DB97C0571478FCE48 = {isa = PBXGroup; children = ( - 54063388CD6D9F64180BC16D, - 076626EB667106684FC3F5C5, - 0B4FA008BF447F4334E24693, - 9846C2445B7D6E79A66630F9, - 6F8DE38E80B72E6FF126483A, ); name = effects; sourceTree = ""; }; + 1B7AFDD8FCA13757D08B8B3E, + F0E4B5B18AAB82215F5C6AE1, + C296F214D5B65857DC3DA585, + E7488E12D0F3300AE33E0B9E, + 63EE49826BF4CFBD9D546DAC, ); name = effects; sourceTree = ""; }; E62D8A1F0BDD00ABB882F291 = {isa = PBXGroup; children = ( - 4E3E146079BC92DDE7B47EF9, - C00122D03A9B2BE3E4ECBE4E, - DE3E98A6DCCBE1F461E46E79, - 56872D4E18FFA80AEDD4FF35, - ACEF6D28EC9FB10B6C0D8EE0, - 276DFA694283C37D1B65B46A, - 5F1334788D34BA2E6EF83086, - 2837660339370BA9863DC451, - 9E003766817800EDE5F401DA, - 401D5DBEE57DB66AF040885C, - 8AC4AFECD0028680DA96CFEE, - B9D557438E309657EB68CF7D, - 82D0CF4B57D906FAEBC60666, ); name = native; sourceTree = ""; }; + 9D61877D2691EB78B2ED69EA, + E9C249D9F38B0DFAF0823653, + 8EA18CA66CABC9B5087DBDD2, + 4F5C213B72A375A83FE50979, + A5CEADBA23491564FEB6D4EC, + 3E8E31BB97A86349790D6CC3, + 3391FA30F4D45A4A77DC2CE1, + AC56A48CC01AABBE45F51970, + A8CAB6FAB9BC1CC96FDE7BC2, + A3E01235E4AD9DBE2405F792, + C884444C380A4B053DB70D12, + F36959B167E88B220CF9D8FE, + F2040E4B76F8783B471CECED, ); name = native; sourceTree = ""; }; B78A49A94757B1530E3E282B = {isa = PBXGroup; children = ( BA53DF8ABDA9DAD0F963BC8B, 88878CC1561F13CF681027E9, @@ -1515,277 +1515,277 @@ 5BFD15FEDAA57F0C3DA99850, 2925596DB97C0571478FCE48, E62D8A1F0BDD00ABB882F291, - 572F0A8E449EEE319155A448, - 37BBA15CAEBD49401D2F82A5, ); name = "juce_graphics"; sourceTree = ""; }; + 241453DBDECBE0CCD5C096DE, + 7022B01ECEE7000DE6008C0A, ); name = "juce_graphics"; sourceTree = ""; }; 978A5EA7C209E97691DF1580 = {isa = PBXGroup; children = ( - 8F95ADADC0B19BF9D77D1A01, - B035D33267C606674E58EE2B, - CEB12E3A853DD633CD5F3AFB, - 38ED648ECAD68AD30C9139AA, - F6A17F1B8D8330F6E8DF225B, - 52B3E9170C4FF9A60E75030D, - 7D81388899A711A7C93107EF, - 2C4196232A1D92FC98E51684, - FE78C65011B44BD909EC2062, ); name = components; sourceTree = ""; }; + 2A59F5E28F97A435592E0B58, + 4A31DFDB7AC330488B8BBEA3, + FEA645D52C593ECCEA779BAF, + E2307A386F9B96576696354B, + A6AD00FEFB31915AB0F2798F, + AA5CDD430B68BBE10A9026C5, + 5384C065CDEB3032907ECCAF, + 8001506F637B2516AAC5C0D8, + 0B7637C0030C06BE612E41E8, ); name = components; sourceTree = ""; }; 0A15D9E1577644179886B0D6 = {isa = PBXGroup; children = ( - 534EB22CE7A71591FCCBA8E4, - CC464EB86E0DE492BEFC7237, - 24C7C2F049DB74035187FBC7, - E27B4C86E077374F4C5E0F02, - 005BC9B639854EA82BE9D1C4, - 08CE1157B27F232F61111F04, - 97BB0621A58441872B96D1EC, - 4784BB8CDAEA553AEA062A56, - DA088C27651F40F29163E0C2, - 5982BD1B4149622A6FD884A4, - 26FD20E046F037F67A376081, - A04B28778E7EFA87304B177C, - ACA68143C3AEE4F3F3327E66, - 46D9408E336E541FAFFB6F1D, - E3699DD1D681C7B65A9348C5, - 696CCA96408572659C97FBB1, - D06C2B0C19461F7AA18914A8, - A610EB8E83CC94E7DFBBC298, - A71DF97DA4CD69A67A1EE763, - 135F8FB24D69C7E8BE59185F, ); name = mouse; sourceTree = ""; }; + 89F5A5C12916F02E579D6394, + 1D9FABE954892C169D874E35, + A5DEEB6DADAA5AB2CF41A880, + 8102EBF90140E78193692AEB, + CC8F24C4E5FC5C12AA30F6CF, + 36A0FF58D355147F40981C39, + 38404F97E5118017DFDCDEC4, + 5A5749D0A878955C964DD2C5, + B3261106892038D4F954E6F9, + 833CD270A139A70FF4E60D35, + F38F8132499ADBD3344E8449, + 61473E0A6AF9B900406695B8, + 8DE969191661B557B4222D50, + 19E9997C0FE3E36156141D64, + 57A0BF533D7A7B57321A8174, + 2819AE973B501D15AAB8C937, + C8A5AD5503F33596C4147ACB, + 72696E2F6E8EB43A8E604390, + ABA2E1FE9912D5C28F177E56, + 8B539DB72CC92EEC7F96C8E6, ); name = mouse; sourceTree = ""; }; FE8E15A77FCDCB00FBF381DC = {isa = PBXGroup; children = ( - DA42AA71E4D47975E018BED0, - DE41FE4DADD07963905B82D0, - DE9CB3573085CEA391B49650, - 3FF553F76522FAC43163CE03, - 9563B07A9E53D5FFE868F8BE, - 9BBE7417871F8708335181B0, - BEDA74674128EDC35C5CCAC0, - F1E144384FC6A2C42FE4097D, - 96CE2C991445A3994E1FBCB0, - C8541CD950B7AB83AECF39E4, - 19553003D814DD6A3D1CE28D, - BB586BA19ADC508119BF86CC, - 62AC3BCA9BBA2BDCEE842496, ); name = keyboard; sourceTree = ""; }; + 46D8BC7303C892ED3F90E4DA, + 29710D5E6C3372E4480BF746, + 38D15A30D4658272F910A7AB, + D07A5399F09462A5D7041225, + 0060F61BFBCEF4E9EF8B3CC0, + 8EFB4EBA0836D5401B6D3DFB, + E13860F17C7FC399EF28EC1A, + B1B7C62CA04ACBAC6CD1C2AD, + 49794569C715BA919A01D72E, + FD5262552A90A9DFACB3C07F, + 74B477DE4CFC95E20DBB0D91, + B0626D2C611D9E3DF1408BEA, + 90FEA7DB5EFC4E9B2E933056, ); name = keyboard; sourceTree = ""; }; 5D48FC8B43CBDC08DB9531D9 = {isa = PBXGroup; children = ( - 9871D03E9A1E28B247352407, - 5B70ED35F78822734FD91F6F, - 8B28654FCB4605697C82637F, - 9C77E1E9F8BAFCD7610F8F76, - 761FA7CC71FAAE37676425AD, - FE00E8025F597B2AD2D00063, - 20B34958865F62C6D4CC1C2D, - 5D4B884A37E3A190B16B34CA, - A27997058CED5CD80DE7C4B0, - F2137487557EE18A462259B8, - B7EA4F63CADAB5B31D3D985F, - C3B0389DB7042B45EFC751AC, - 4EA7EB8C8EDE34046AD54E2F, - 1CEDC2C77278F47EA71D588C, - 9B156F9D8794BF1E15A19C5C, - EC6C43EBC349D5597A1CE53A, - F44CADD7FDE536377851F6AF, - 3EFCADD916181E95D684C237, - 01E3FAE5B663BB39B4317ADD, - 6A207487147E4661842F2EEA, - 4F6BC156DF6D42B5A2E6B9D5, - FA4C2A6A58633E63A09EC3FB, - 150EE812D88AFDBB98C0A539, - FF921DEC61293D650C9BCA7B, - F46EB82569549C07A8D04D15, - 5F1E31EAC156296643CA5A5F, - E3DF0709DECF7FB19A8DBB11, ); name = widgets; sourceTree = ""; }; + 0C9B04C3B7D8E1CE4FAC6FF6, + 5383E87DC6DC1D251C271A50, + EA779F8A580E3D22A7CBD51E, + E958ECCACCCE70690FAE58B9, + 5D4A62D4893C16D7B17C6A43, + 0F16DEEC2C4B95E3A9F28CE5, + 32A667DB98BC4EB30C51F20B, + 60D8280577C14A7D3F67563D, + A95D718F031CB8883DFDE915, + 7D8D285B8414388FDB083AFF, + 23724FEF549E05851817B4BB, + 65DF385E92A4A65760DC3BD0, + 3D16FF3C64D4248C0C6FF504, + 27676EBA6012198993C2CBA0, + 68743DE3AA833D6F02F754D7, + 9F70142818A7806830EEBD7C, + 44FC8BD37CFE8C0D851C46F9, + 842433A42308565BF3C1542A, + 74AB51B6E97964B27B1CD019, + 7BC8F7015F35BAFF4AEDA0E6, + E5B84D5F7CF2B74715EEF3B3, + 66CEE40E51335F661B5C5C66, + 260A5BDC20C7B4029DB418E4, + 44C6568EC00F1682FBCD3B69, + F26953C1E056357A3DFDF35C, + A826C1C083678A4E9279C118, + 6DE6751E6A4F0DDE9C7F24B3, ); name = widgets; sourceTree = ""; }; F4827EC22DDE876BA01A1012 = {isa = PBXGroup; children = ( - 03D597E4C12113FB74016803, - 1A632A95CA812B23E08E0C7A, - 7DED484895527D5C0BB6662F, - AE7E18FE030834B289424681, - FCD0D87F9B7A473885F5A95E, - 40DDC868EB152DA18FF4832F, - B4AFAA5A74A2E61F0196F4B8, - FC5A39F51E480EB25A4A2656, - 29B12214BCD1551867246556, - 3226060A8CC7B793C5A7A25A, - 13BC4980571374E9F0243F0E, - C7B2F4323D69615085F4A633, - 2765ED5E0A7D8759C81EEA40, - 4D7D8DF32996B70112FFA693, - 5586252F2B71502A0C1A69B5, - EC60C51FC1AA8BD749F4DEC3, - D03AA7DD0628031F75231425, - 405F7A0C891B13655617BF5F, - 461440C6B5EE1CF5DB2ECDDA, ); name = windows; sourceTree = ""; }; + 8314FE695F91DA2FAB51920E, + DC6461EF11D5745DF8C00E16, + 464424DDD6A6678B94CE667F, + 2B9BAEF9C46C224088F5BB25, + 4BAF7C54867DA3C275C2F59D, + 6A8AC5E55EE51EE0476D852F, + FDA36D1F836D00DE705CD06F, + FF1F4F1262BB429E80492B13, + BF40FF2E0FA609212C849FBC, + 766EE2CCD4E86729C6CE8112, + 8E95A3B7C194244B92D5D65A, + D5C10F9CC5ADFC1B63AD1DB9, + 166BDAF3B9896BCB3771A061, + 0346DBE09BEC27EA93676FEB, + E9A4C91E94B6D096BD8217D7, + 8683CDE5FD2DFCB2CFC8F410, + EA13B2FC256C7BCF0900369E, + 27240E9968C04288887BFDC7, + 25869F2A5B90C64E857606D8, ); name = windows; sourceTree = ""; }; EC71C6DC0803DBC6F5B71C8B = {isa = PBXGroup; children = ( - ABB9E5EBCD9C0F04547E5A90, - 7A2245EA90D757EED0EBE63A, - E0D15D4DE8EC3E536812D4FD, - BE22F0B06CBFF0C62A317CAC, - 98594F6F68633ABB8DB9A488, - 307C5E375D02896F764B50A2, ); name = menus; sourceTree = ""; }; + C9A25E2EF32224159B617D5E, + 0054E026B84A3A87020CCE48, + DA98B32DCA0DEF0113C22F9A, + 500F7CB9F45B62E46F4BBA57, + 595A9929C0E873C30AC9AA87, + 439FC260CD869E30210D98BF, ); name = menus; sourceTree = ""; }; E30E1398A3CACDD90FC9C219 = {isa = PBXGroup; children = ( - 476DAA4C7DBFD4BC115090D2, - B45F7C71FC56F9DCEA7379FF, - 83B04EFF25DA63BE3DA37B11, - 3D08CF856ED46386AB450F46, - 4B4BC465C9478425824F5A82, - E7E06147F43FCAE8D5B20BAB, - C56154402FC7B2983160C3E3, - 6FC349656B1BC972D349E67B, - D37E99EBDA572556CA60B942, - 037977A3CA69858654B749F2, - 1A7BABC358CA895F30655093, - 48225D3F1FDE66F5A56A1ABA, - A0B1470B03C45DEA4B9EE14B, - 552E3A59D6200D3CA42CB2E5, - DAA6196510C04172905A6BA2, - A0CB25C077F41F543BFE0ADE, - 22BCEE7C1CFE9805F0C39F3B, - 0C8CE60E5ADA256EC7311C40, - AC3721AA8206512767A5E5AE, - 50923F018EFA0EC66289B8DB, - E90A5D53778BE390A04B8D30, - 071119F515B16F354C9D5D22, - 43234F932D4492E104787435, - B1FDA24AC0EF52652F3DB94E, - 6C140CB15288D8837DF454C4, - BCE1A7250DC27CE2B297B999, - 538353D423AC527D313BE99E, - C70A847D3C9EDEFE5B57C1AC, - B79DB0C1AA34A90D1F3E012B, - 076B1F9E89390D3CFE7B6F8E, - BD2B30F77B968E717E713124, - 3E9EC18E1C4F444805B36259, - A38AD54C200158953BA0456D, - D0D385C5D99B9D9A90C00458, - 85A0EF72EC932C8A327F8139, - 39F3DADB903ABADD1176B79E, ); name = layout; sourceTree = ""; }; + F4F618373A81FDC73AB27A91, + 799472026100D7BAE015F6A6, + 34A6FFC298D12BF9E4D55AA1, + 7A6E1CBA343C07AC187A3EE8, + 7F0614F4F47EB171B8476BDC, + 19045B1A4A9E79DB5A44927C, + CC3F295E9D9E5863779F9ACD, + 3B09334ECC8FB54B4B7D7B59, + DC66DC84909A3802527414C2, + 7F171BE6BFAA1E3E2A9BED61, + C8F82FBA1E0EF7EEA5BD02B9, + BCFE159BD9F2DA5515E028A4, + 4C40BFAE1E25F166EBB5EC48, + 25E6B62A5BF19A0D1E085E10, + 684E11B1CE018B2C46938D80, + DBB34599E380FB1F37A28B27, + 2DB2DBF293A77B80E01EBAED, + ADCA2F92E2C17964A4AD750E, + 82A390DEE5A3B2EFDF7A65E6, + 674E13DA209E762DF15E9E29, + B6C7114A31FD6B1DEB08346F, + 6D5EE68347208091600E94A2, + FCC9F258531F00BCD91C63DF, + F233E88B6F2BC6906819AE6A, + 9C3E556586147F27B4EDC982, + 135DC8543A904B7BBAA0FD7B, + D01D74EE9A00B0813B00FDD1, + A1C77E9A6624B8B1A461C038, + F831631700830F81994D9980, + F33B267B702055F8CE27BDB8, + 8C9D252ABA3CDDC81B33884D, + D40C36493501EA97A8D1EB50, + 8C9EC3F9C24081ECEF3FCEFD, + 4658E12862C546A62E05E4D3, + D886106C60A496E47C48AFB4, + 374277A96D9830E45684FDD8, ); name = layout; sourceTree = ""; }; 3826467DFB859364DD1392F0 = {isa = PBXGroup; children = ( - 8F69B5117A8AB4D95316FBAC, - 0207C77289467D58A696794B, - 70F88726C73A6517C14B5E56, - FD596755997053D5C6F9D460, - 778A19A79B821CCE6BD27E12, - F232D373ED304682C9581DBF, - B4D3C4A6929FB0068E61E5E7, - 77B9644758BED4987CEE2FB9, - 9D7A8ED2F93993D6BD4818B9, - 519B2190343506FF89DD9796, - 4C93E808908617B457689A69, - 03E3F0BF99B3C180F9531411, - 8BB79E37A824F6CBBB7A97D9, - D7996C2834C1EE0DAC4BAEDA, - FB5014B315A9FB387052F4DD, - 96E6A79B5BBBF580E0E11FF6, - 19DA53917D0F1D8438EF83FA, - DC4D885D7F7F573E42E13F65, ); name = buttons; sourceTree = ""; }; + 782E3434FEA190A986EAC816, + E6BA3A4991987C4AB55F5948, + 93CC262389F622F8AB79CA60, + 02C14E49091F42750CD72F00, + 35E6F6325AF8463C076BA594, + 92DF4A828DC5CE370E36044C, + 0B7E069D09A7E46448EAE230, + F16734BCF880A8180C06018D, + D0B5B79546163A6DE73D0E2E, + F4A977844BD67D5C2BEFCDDC, + 5AAE605D230E253D4EAC195E, + 4408766B366713F55707B7A8, + 6BE6A3A14057591A3B4EF2C4, + CB4D4DA89BA649D3F1B2A645, + F2DDCDF62D2587FB565A442A, + B88950266CC4244E1B5394F2, + C088D98E527C1DA17B55A9D9, + B70E52FF75D44F0F1F0B31D2, ); name = buttons; sourceTree = ""; }; B2943EF1FA5DBD81A406374F = {isa = PBXGroup; children = ( - CE696F8D455A2C2D1B8051FB, - 81EE8DCD7B8BB528C9989B47, - 31A79A4E5FBBBDAA36B7D273, - 8EA752855DD7BA2C1CEFF9D4, - E105D3381CAF5006058DF2FD, - DC078E6D148F784C9843BD8A, - D9108E2655D2E4403A4B598A, - BC57385BADED3932DB3714EF, - B3CFDC682EFECC45C4227288, - 56207999C7136BA24F53DB94, - 4A0D71E8FA4622C6C7687DD7, - C1505EA2417265BC59135075, - 7F6B22405102D9B38BE6E113, - 5500A9D5683F5124D0BAEA8B, ); name = positioning; sourceTree = ""; }; + D5EC3B41088855C3D481A73E, + CD3A68C29B7A733E5954BDA3, + 76F1A69F15F53D17C632A644, + 14AB997C7EB22777C1EF533C, + 51026A3BE98FD70FD916CF45, + D3C1097E92146B596194A067, + B316291E570F37785C40FE88, + FA2DB83279928FFB76A4BC6E, + 4E3C26EE8C6F996F207F0C32, + 1DE0CF80B807A4A702DC68BD, + 21D31B64BAD35C6C8E8E8FC0, + 29215FCE04DC4D267FF25E6C, + 412D5D6AA4018C8DF59AB741, + 807E7971CB75C806D7DB5DF2, ); name = positioning; sourceTree = ""; }; B2AAEBDCA5147C75A44D4791 = {isa = PBXGroup; children = ( - 5424AA8231E11912CD1C516C, - 2892D0D481CDCCFCAE374DA8, - A92EA5F1D1D2ABA2E441DE45, - F42A363007434541AFC1A7A0, - ED56CB90240662CE6FBE2A74, - 72173AE89EE7526AB956CAE8, - 9A704CC5117B59E1F5CEBECD, - 4C41E9A5BA9B4CA47D4A37BB, - DD4F1D5C6CAD9CEA86F83209, - A60E87D4E2911C3730CE3DB1, - 67319D5DD2BD8D31706DB34A, - 29054D0D5BB22F6A23808951, - 97F9A1E6E51FB3D918EC3174, - 24E811B6B00094848D08D21F, - 4B06A49CE12DBFA2FC861D50, ); name = drawables; sourceTree = ""; }; + CEC05A60A0E19B07F6A3CE6B, + 5BBC57B395B553CE08AC4BD7, + 94BFC3162953A5E7E192276A, + 2168310E25BD55C9A46499C6, + 92BB22C929A3A76CE6F29C7A, + CE4F0A27AAADFD53316A17BC, + D00157FA3D14BFECB7FE7232, + FD5E948C1A89B11770A20704, + B54A14A497368A580B7D9AEB, + 16ECB71D0D2C5C8BEFF4B4C6, + 8BE44C96A60C5D9B9F503409, + 6E9C1F4D69A9C99433DC67C6, + EE577E6ABD70D104CD83186C, + F0D54DDE8C2AD1D018A61FDB, + C21701DD3A4A2628C63CB70A, ); name = drawables; sourceTree = ""; }; 0EADBF64826A3D243FB6E1DD = {isa = PBXGroup; children = ( - B063E208C533148EDB5D4B91, - 7C91E9B82C9B593E082DD74F, - 1DDEE220B7231E89552E9A07, - 5FD5C6D8A917C60FBF029EC0, - AEEE72913C595DAE27F43ADC, - C2375B75F67BAAA9813EEC2B, - 86318DF533A7BB50B88789BC, - 8E6D1C56F3FAC7B249F2582B, - 45210D0101FB1A0A4AFA4C54, - 0B22BB6E27076BA1B6459249, - 45EFD54010FF09B5795B59CD, - 76CD66265F349446088FD5E3, - A1EF20A764C5B6EDEFC378E3, - C42F2CE5B179094CEF9786C1, ); name = properties; sourceTree = ""; }; + F20F182CBEF008AA1B1BB52A, + 0C61EC70BD4EA59AEEBB6669, + A1A621FDC626245B1B3C1C4D, + 9424FDB8C564B73250B7B20A, + 0ECA7867513EFA30BEA0BE78, + 4F2D3BD9697AAFA060EAAA59, + 20E10FBD8694E185CA551EDE, + 109C128BB4A7A05127A0C485, + 6B103C0FB5E6E3618ECD3B48, + EF8B8FB4B02133457562E1F4, + 7FC89C1EEB42DE3C9628591C, + FB3BE7E3D0A04791487E9E0C, + 1A788BE93E528FDAA62EA02B, + DAC4442F8C2F142270E92349, ); name = properties; sourceTree = ""; }; 1E19112B929FF59057A4B030 = {isa = PBXGroup; children = ( - FBC39ED8BF25B886702E335B, - A7D96DBD645622F9EF3B3E88, - BFC021DD9267F5F0D2D2D58D, - 9613BC80734D26E200E5CE1F, - 1717C592DF6E9FB0825104A3, - BE24FC2B4C9D80DC8DC99BC2, - EE7FAE0C413B7370B393CD35, - 92EE84597D647B6CE0CBD4FE, ); name = lookandfeel; sourceTree = ""; }; + 0700C7069E1CF3FF8966C0E3, + 4CF92825BE7B97AC268C2AA5, + 56985D9599D0D1D00B42F95B, + 0CBC9EB8F2C55E88DB0F49BD, + 5710CADD28060D8E949D96D5, + 31AE430D2372CF6283185033, + B3FBDBEBC38720E957C15BE9, + 69449AB58A9C0AB552F754F4, ); name = lookandfeel; sourceTree = ""; }; 1206D5C335340736A3A574B9 = {isa = PBXGroup; children = ( - D8AEA877A6200E6793A56B81, - FCD602F37104023C7B8BE2B6, - E09382FAC0496CC7B1A70087, - AC3B9DEF05ED1B18C952FE36, - FE44E4AE499848D27FB7A985, - 52438BC8DDE3E8A8A708D307, - CC726694653F832354878239, - 3AF3E08820EC2CF94B505DCB, - B2F561631B30711F78C118A0, - 525381C319EDB9B47F9DFCFF, - C61D46855CAEF3FB4547909B, - 58FB0E03D5E6CC4122CD00B8, - 7B00E4D3D066DFB30406ABCC, - 31B95E3446D65E1C0ADC0E4E, - B4FF9DAF77F9CEFA8FFDA583, - 7C4D9BAF8818E5750C110343, - B1F56F0DD4CC94FF8BB1FBE0, - 95446442AB833FA3CAF0D949, - A87251DF370D12DEA68B41A1, - 1A23B74D25E6B0C55F1A1186, - 30EC49300F475411B40273EA, - 6CAD1F4452A73BAB29EF5D4B, ); name = filebrowser; sourceTree = ""; }; + D7E612935BA192BF5D24B9A3, + F382E14FAFF5CDEBFEA81B00, + 98C77B9D95141EBC60E6AE67, + F3154C77D5DFCE8D71084F23, + 27A9B065352AE36635780373, + B57640F7EDADCFE17719EE68, + D8256B8AA794F43A2259638A, + 0D35F0A502484A40B09F3EBF, + C52E8074125FEED4DB727EDF, + 90BE189372A13866896CE817, + 4ABF36D87D2BBEDA4DE28A4E, + 1FD6FD7218AB240D23DF4BAD, + 2D8FC1F116F882698F5CFEB9, + C51A754A0E65CA141A2C3310, + C551CC8801B93AC70F6E4F76, + 830ADB6740EF70992E71895F, + 3BF23F0B71FB8E526E895905, + FD05E73E3F022E08D70B9569, + 27DC413550834C828252B003, + BC1DBF05964D3B9130CD8CB6, + C3DEEC17595B1AB020ADA47F, + 67771057800F9416E9777625, ); name = filebrowser; sourceTree = ""; }; 53440A90525AC832090A35F2 = {isa = PBXGroup; children = ( - 23FA7918C3938E3FA645F003, - 82E3A19B4D8BA65CE7310D09, - 7161ABCDB705E0F81662DC71, - 6EAAEC3D37B6CC538F2BAC98, - 6E0B73556F626E9DDB2F2F4C, - 0A5ED9AFC5906343E514100D, - BCE6AF6A2A5E7156836E5E7F, - B2E4733C1FB26F143C0C7344, - D4EE8C83FA9A3BB53AA747C0, ); name = commands; sourceTree = ""; }; + 4F5D668DCEF2B622FD46073D, + 791ADFB0FFAEE65058B6FC8A, + 0DB1323191C133E48F07C062, + D26821159E190113FEBF99BA, + A0F2EAF085969426AC73C85D, + D4BA573C125944E2773D747F, + 0D265DF78A9FE5E669F76FC3, + 9211B175E63E325D4FF6B789, + 3C825AE2479611DA559164B5, ); name = commands; sourceTree = ""; }; 815FFA61CB68244C4BFA9A78 = {isa = PBXGroup; children = ( - 7FCD0EF5D09B904A6D437BC9, - 3C31FCFF8570C5F2281B4774, - 1E7287FBD84D26D7C3247D65, - F47A2859B6F0F7800D4FFDAA, ); name = misc; sourceTree = ""; }; + E6D8902FFF0C8CDBB3E4BEA3, + F0B46A9181B1707349A20399, + FAB998A70437EE4D89CABE2F, + 96E4B48CF055ED116E5CB3AB, ); name = misc; sourceTree = ""; }; 8B10235D6698BCD336ECB195 = {isa = PBXGroup; children = ( - 5178CA597B45B186FEF4D2CD, - 015EBD22B273B9E6FA96D62F, ); name = application; sourceTree = ""; }; + B189762C440B38635351E0A3, + 47E5FB5735D2EC8B039D2691, ); name = application; sourceTree = ""; }; 3900F1137E25F9A2DEDF4119 = {isa = PBXGroup; children = ( - 8D9A85AC7668D98160EC607E, - E2940D3353B79053D215093F, - A2E38A6CEB042C6819BF032C, - F3D6E8D0058A92DE17677894, - F790D306D54E1295F9C7F9E1, - 069F8377EE5A3A1B8417E1BB, - E9E6FADE6A6F0B00452C0AD6, - C57F2A4DB4E9E55D5017A33F, - 90E99C139FF6443FAABA2729, - 036DAC2B35EB0E89897CDAF7, - 06D18753FCA84429B281A7CB, - 7F7C09BE9B70312CE6783717, - 7063EC546938B514B6EE8982, - D6ECAE5B0CC40752D559ABC4, - 57D9F9DA0E4AC9350182E868, - BCE458AC1B9E30F85B443851, ); name = native; sourceTree = ""; }; + 61E1C2246CBD45C5A1F40102, + 8866CF798E9F84C49B9D7DCC, + E1868998BA7B20DF7ED0B5E1, + 55A4B5CF98FAC1CC23E49C82, + F83392D9825422AF0DB638D0, + 2B4FA0E8FB46CBC71A059FE7, + 26C95A2DACFF9773038656E0, + 99A3B01A6398623F40C528FC, + 221FD10838A8CE36672FABC0, + 0EF8E3646F6099E89A743D99, + 7EB8C7E000F0DDAAB4F47802, + A7884EC24DD007D6232DB822, + 2A2B7F8BCFC785127CA961A9, + 562E99EE1A4B733B7F751955, + 90841E3B0B2548A5BD66F15E, + F95533D725E548643CA584D7, ); name = native; sourceTree = ""; }; 9A76685D3735D1F1DB8E4DB3 = {isa = PBXGroup; children = ( 978A5EA7C209E97691DF1580, 0A15D9E1577644179886B0D6, @@ -1804,130 +1804,130 @@ 815FFA61CB68244C4BFA9A78, 8B10235D6698BCD336ECB195, 3900F1137E25F9A2DEDF4119, - A232BF668A11B7015B65C33B, - 2DFA08EB2F2965C76C328560, ); name = "juce_gui_basics"; sourceTree = ""; }; + 0E8D536FEBD11AEA3C90B5A8, + D104C8636576DFE8A2D11430, ); name = "juce_gui_basics"; sourceTree = ""; }; 45216CE44016DA606FE98125 = {isa = PBXGroup; children = ( - 57F9DFFE80638F013ED82F0B, - D07A1E2DA76EA9CFBC9E3133, - 3289B1B53AFC6D7BDBDD850C, - 58F79BEACB41061A067708E4, - 688E8CBA135D8B2265E0B809, - 9F32845601855AC6DA5F14B0, - 358A3AED0462892CFDD11749, - A0D91BF6AFEC74B5349A3087, - 478C5F19200D7A3E3D0F3767, - 6F906DF202EB6B421F9C5813, - BE80DA6D586BB1C790B345E2, - 0E261C336A94816F61F6D1F9, ); name = "code_editor"; sourceTree = ""; }; + A7B28AD8606992FBE04C527C, + 13BF0388489EB44A816C9AF6, + 68FAA921E5D8CFAF9CC07C2F, + 191B98765219765CD56CCFED, + D2A5F78D0EF37F1E45DF39D4, + CC4B3BCEE612C95F27680EA9, + 69C36A56AE1A2E8CF64FE388, + 89ACAEA951C470AF8683AABD, + BAD1E66E3AA09ADD70061A50, + 91CEFA76775CD035E2F9200F, + 0852A866937712A0D30684A0, + FE1E97C9233F2D472C7C6128, ); name = "code_editor"; sourceTree = ""; }; 13374F67832C9086375A10EA = {isa = PBXGroup; children = ( - A395CC90104B14CC5D5D8F21, - B68C18758AC0A7570E067015, ); name = documents; sourceTree = ""; }; + 3BDF8DF3F3C380B1A4CE6C8F, + 8632589E0C21E3B0A5DA0333, ); name = documents; sourceTree = ""; }; 5BF35BC9897465D83C81C086 = {isa = PBXGroup; children = ( - B3669C5F60758B9D20E41583, - 7B849D43BE20E398A8B52F52, - 77F53EB4FD58030721224396, ); name = embedding; sourceTree = ""; }; + 0E894AC7229948568720E294, + C45AB95F4CDF31A41199E6D4, + 414AAB7000E7FDE7683BE72F, ); name = embedding; sourceTree = ""; }; 2E8513968E4CDE8852D85EFA = {isa = PBXGroup; children = ( - 2C43979AA3431CC3D61B94A1, - 11930669FC3C726CD1F9712F, - 70EAFCD75DD6A7C1FEBAB94F, - 3B5DE4A58F1A28D3DC2D5035, - 6481FF60536C5296C176F94B, - 7AB7CD2C0DB9B58AAA1A4B2F, - 9E47EC586E11C6F1AD2782C3, - B7F1AB21699A5EEEA59DA2AD, - 3669749528AFEB3D613D773E, - FBB2451FAA8812635B019B07, - 78D9F913D201ABD1349F023E, - 5CEC5FFCAF1B33BE9B86CDBE, - 73237A2CB197259364D09A76, - 7EA85C6C405022532A6F2F3A, - 3E199BBFEDF370A9853B91E3, - 3E25895B1FAD62C2E2DF985E, - 7CE1591D180C957070AE60F6, - DA41E1FA66C5B7218625EC70, - 836E25356E7C3A2534792936, - F27227DC9C5FD1ED9D39644E, ); name = misc; sourceTree = ""; }; + B401E96340B8AB5DE8CBF5C9, + BD588F8D5FD1E6FE88E9D3E4, + 531BA61B027758A7978052A4, + 0D0FAC9754D9469774B8DD2F, + CE0CE24264C96E86062E0250, + 519CE739793F0797AF1A7957, + 553655CA0122E128BC368AD7, + 77AE8FD7436387126D3BBBAC, + F9B00F8F537F74527F6C463C, + 2328C66A446079EDDCC8B14E, + 4D5901626201478A459CE46C, + 0790EC941834B64EA1AC8D5A, + E0EF847C7052C5FFA2A7CF8B, + 2254F8D031DD15BDB278DE3E, + F838183EDFF5937C2879EE41, + A0850087D0288361E552BE9A, + 9692128AC24CF671A9C0457B, + E29A372A41F835609F81CC43, + 394CD5017D81D1CFEBE34894, + 897C7B6FB012647ED8AB5D05, ); name = misc; sourceTree = ""; }; 626453A346165A7A0C138828 = {isa = PBXGroup; children = ( - 52CC3D36E2A4DD363F99DA9B, - F4666836A0E1D98969BF95D0, - 6D688EBEDAD32DBB4706CD39, - A00497528C590CECD253D1ED, - 9B1820674E3D99D9D4AB8DD9, - 6CC23E6F664F9114395C5DFD, - 4C512B82D4659142CAAB8390, - 703DEBC270B90BCBA7BCF714, - CB04786710DE206E794D272F, - A56E50AC91E42206FAD381F1, - 94614BC3AAA7263B1D6BDAE7, - 92800D0F94BA509EF80613A0, ); name = native; sourceTree = ""; }; + 805EB95DB4B8045064CE9ED3, + BA7FDBE53073F3261D962FF9, + 2B69AEC791776F7CF337E38C, + AD54DAEAB7840FC18DA65503, + 1A7002B936C11924FDC07023, + 66B37CB373F19F65553466C3, + F257AD1B82D5595FF9C3F1CA, + 71B0F66C20CF48F49B3152AF, + 21D0A71ADD004B35B90F0D1F, + 29685DC8679DB5024B747D0C, + DBDED1D6237A21D03E68D323, + 2C1B86FD1CB59198522DEF06, ); name = native; sourceTree = ""; }; B8479E2CF92E0AEE774BF1F3 = {isa = PBXGroup; children = ( 45216CE44016DA606FE98125, 13374F67832C9086375A10EA, 5BF35BC9897465D83C81C086, 2E8513968E4CDE8852D85EFA, 626453A346165A7A0C138828, - 4D97C6AE9A54A7F9663B0022, - 9C6E9983521DF4DFDD0C460B, ); name = "juce_gui_extra"; sourceTree = ""; }; + D57735149DD4975283A0C754, + 37381332DDDE8F2B3C66CBDE, ); name = "juce_gui_extra"; sourceTree = ""; }; A33BC9FA8A99B01DC485E60D = {isa = PBXGroup; children = ( - 171DE29200A3E7A8FB2D82F6, - B87D578105925ED8FFC105AE, - 7EDB44744DC44FB9DDECF9FF, - B58C5A06F8D666BCB074D981, - 01FF42E4D2A331779AB0A72C, - DDB38AD7F6C5A2E5E3725288, - 8669589118EF641C93336C4B, - D0197C6B54D5A5B8AB15A230, - 8910FF4F64E6AFD721B91B0D, - 20E9A48DD57A2BD4F3A8EC20, - 313A26829D5268C9E7B28E7E, - 795EA6840D307165BC0BBCD4, - C8915F6AB7855AF370A5581B, - 433E40D469ACDE64A8E40258, - EA14E79A40FE2177626ADD79, - D56DEA7CACE4A86351CDDD5B, - 321AC5D0FBCA00E825273253, ); name = opengl; sourceTree = ""; }; + A09CB6FA9736BD45103AFF46, + CDFAC8C57A364EEE32CE125E, + 166C141D440846E85F91747E, + 0D88ABF90B476D03D3684ABE, + 4510E3B6AD441EA03B993692, + A98EED399E310BF85EBBCE12, + 2188A5670214696EFCF6810F, + B0589203065E4CF2C002B0D9, + 0993051FFD1B0C5E92474DBD, + 28BEE3C7BE3AE2BD888AC55C, + CC96E8E65FDFE4376F71D7B0, + 6B5C2F14A2268F371F1350B5, + B60524021E6FC59416222870, + 4EB8D72F57E00C560E370DCB, + 08C7B33308A32555A7CA21B5, + 5C0E42BCF4ED32E1381E7A23, + 9CC0E3267A9D1EF3C8E37601, ); name = opengl; sourceTree = ""; }; 07ADD7BA5A96F719EDBCA037 = {isa = PBXGroup; children = ( - 9533D4846543EF2F80E7B561, - 933A312B0B63B032495B06C1, - 0180E266C4D70BE9C67AB07A, - 5B9FDDF7446043886E09E303, ); name = geometry; sourceTree = ""; }; + 5B5180DAAB935CB6D1DE9AA6, + 2C246301EE0EC4A9B4058F01, + DC94270BB4A70056907C3CDD, + 75D038033B2083D5EFE620A8, ); name = geometry; sourceTree = ""; }; 03621233E269E436B447C841 = {isa = PBXGroup; children = ( - 570EA0ADD7290B6AF6C74960, - D65828A1160764381EC4A290, ); name = utils; sourceTree = ""; }; + 44ADFB25768FA3BF27762EBF, + A058E50779879A7D9A813A4C, ); name = utils; sourceTree = ""; }; FC95F4C8E60C31B039992722 = {isa = PBXGroup; children = ( - AEB7028FB923A6FD7404A84C, - 24D1B8EBF0B291F684311B9F, - 49C6550365D3B05E7D030E2B, - FF0D0A3EFBB77DFC905FAFD8, - 549AA1BB3A58BFDDDDD1FA32, - 042881A3BC502717D187F4DF, - B4554AB60F9524B82FAC071C, ); name = native; sourceTree = ""; }; + 11D8AE26FA8880E7E8F3B4EB, + 518E9E553CD9F7D215B75B88, + EC9898734E8AFE5215705476, + 9DC79DF0A43DA6B06B7B1F44, + CF4E3CDCC9837C7E52197686, + 495EAFDB9DE4E8E7DBA562D4, + 877ED7656241F46291022910, ); name = native; sourceTree = ""; }; 0707779F272B825E3DF1560B = {isa = PBXGroup; children = ( A33BC9FA8A99B01DC485E60D, 07ADD7BA5A96F719EDBCA037, 03621233E269E436B447C841, FC95F4C8E60C31B039992722, - 7632DB6A2EA67505B1A5B4A8, - BBF1A328A57B8CA11F40D3B0, ); name = "juce_opengl"; sourceTree = ""; }; + 8D3FB0417A39CAEC03D44D73, + 4F96BFF5D1D40B81C861F92F, ); name = "juce_opengl"; sourceTree = ""; }; 62479F93E90EEE65EEC01FDA = {isa = PBXGroup; children = ( - 24A757C009624117895995B4, - 0FF684B2342825C25B6D5DBA, ); name = playback; sourceTree = ""; }; + B83DDFEEA66888E9616BCE82, + F113DFEACAF2D8230F0DF5E7, ); name = playback; sourceTree = ""; }; 616C504727E4806B3BB3980F = {isa = PBXGroup; children = ( - B08C35519C2E990041F82336, - 69EBBAC63BDB225AD7B9B19C, ); name = capture; sourceTree = ""; }; + DD03B6CE6F750A9CECA7EDEA, + 611A0824757D50610BB03562, ); name = capture; sourceTree = ""; }; E545E915D753CB44657CFE99 = {isa = PBXGroup; children = ( - 2F9BA19AD170D9B9F979B025, - 3D0CCA82BDEA501876257111, - D4FD4193ACDA02D2C3D8B5D6, - 21E54D17FED6BEB36D5C712B, - C989EB89ACD3E1E5122BDBAD, - 106CB8DA346ABAC39F9CBF67, ); name = native; sourceTree = ""; }; + 87E61959D8EA529461A0D257, + E0FCA8F19A081CE941B273FA, + 11ACB77A3D91503A3DF673C8, + ACAC59A1C54DC52E8E2438CC, + A281FFA1C7E3AFB8246FD577, + 71881F8A6973AACD78ABA719, ); name = native; sourceTree = ""; }; 397907CF13C78C70801F14D4 = {isa = PBXGroup; children = ( 62479F93E90EEE65EEC01FDA, 616C504727E4806B3BB3980F, E545E915D753CB44657CFE99, - 8FE90269A3BD4CDE641C5847, - A46624CB68D4D4FC6AFDDDB5, ); name = "juce_video"; sourceTree = ""; }; + 254D157C0CCE3C7EA022F4CE, + 693B6DC20214C1ED9C1E89F7, ); name = "juce_video"; sourceTree = ""; }; 7E2ABB7F81888EB9DF84E4C1 = {isa = PBXGroup; children = ( AF12826F0B38E7FC1176C648, 270A86F6A3CE512F0B3EA8DC, @@ -1944,19 +1944,19 @@ 397907CF13C78C70801F14D4, ); name = "Juce Modules"; sourceTree = ""; }; 5B8C542DD6E060115171CF66 = {isa = PBXGroup; children = ( A67C5701B28E64F889A92422, - 50CCC0CC14D17378013CFD72, - 08216A0328094D5809860DEB, - BC3EB76C434A2FDAC6C46DB2, - CB3D07088AB905BD96AD3A90, - 7FB3628856C8E532EB8421CA, - D728D4777A842A58EC01454A, - B6B4BC87EEA6BFF7A739D118, - 369EE12DB339DA919C8BF5F6, - 1291E6270CA79ACEEEFB2636, - 1DAF43BE112A30BC560E95ED, - 5A8383F3E5B628DE60DB8291, - 1A355A0DDA216F713372DF88, - 98FBBFD68CCC9D52B62BFFEE, + C1070E62B763F1CCE0BB18F0, + DD19124F0A7FD43F31BDEB87, + 987AD2821B6419D5FEDCBD7A, + AD405DDE86D07F955E27EBF8, + B7DD84C8B05ABA4A6915E77E, + 33E449DEA1FC0CD4CAA3A829, + 14BB261A450674034E6080F2, + CC0B7738BD544B955D81BF1E, + 4B27A11ADAC0D9957BBBCD3E, + 27B720A5E8CF81ABF9E50848, + D8BAA82AC820CEF315BD9DCB, + 21CF5364CD4910E49D19F8E2, + 6018A3A37F34AE52B39A14D5, 274569E245BFB279247B4ECC, ); name = "Juce Library Code"; sourceTree = ""; }; 9AF618BFAFEABB193C0E7D1A = {isa = PBXGroup; children = ( FF3D4768BC96B79F49B10894, @@ -1997,7 +1997,7 @@ "JUCE_APP_VERSION=1.0.0", "JUCE_APP_VERSION_HEX=0x10000", ); GCC_VERSION = com.apple.compilers.llvm.clang.1_0; - HEADER_SEARCH_PATHS = ("../../JuceLibraryCode", "../../JuceLibraryCode/modules", "$(inherited)"); + HEADER_SEARCH_PATHS = ("../../JuceLibraryCode", "../../../../modules", "$(inherited)"); INFOPLIST_FILE = Info.plist; INSTALL_PATH = "$(HOME)/Applications"; }; name = Debug; }; F361F998F590FCC72F2DE949 = {isa = XCBuildConfiguration; buildSettings = { @@ -2018,7 +2018,7 @@ "JUCE_APP_VERSION_HEX=0x10000", ); GCC_SYMBOLS_PRIVATE_EXTERN = YES; GCC_VERSION = com.apple.compilers.llvm.clang.1_0; - HEADER_SEARCH_PATHS = ("../../JuceLibraryCode", "../../JuceLibraryCode/modules", "$(inherited)"); + HEADER_SEARCH_PATHS = ("../../JuceLibraryCode", "../../../../modules", "$(inherited)"); INFOPLIST_FILE = Info.plist; INSTALL_PATH = "$(HOME)/Applications"; }; name = Release; }; 8FB477F7B77D68FD93DC1D16 = {isa = XCBuildConfiguration; buildSettings = { @@ -2069,19 +2069,19 @@ BD6EB403A891DBC353F7D06C = {isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 328BFAEA24EDCBF7B69F4960, 84E6553798838003062A7791, - EF96289AD85C80471CACC5B6, - 6E1751B19D4AF902E028A7C7, - B1220D75CDAD50F3CA57D1A1, - 1C90AD3A9B9B5E9DE33BD2DE, - 777C7919C5F3C67E528286A1, - E3AF28976801708F8CD9A656, - A8E9942AA157F768897FBBA2, - 937B4A84B983E2AAA040F976, - EBFF0D5A17F1D61FC28BA178, - 129DFE2B7F1FDEE81E188D21, - 79A28D1FFAEAC8D7127BDE2F, - 526057FC6638B0BB7B984637, - 2FCBB2DDE322D55AFEF262AF, ); runOnlyForDeploymentPostprocessing = 0; }; + 9B303E67BC0058053878030C, + ACA92239BEB4C05C418642E2, + 1EFD155B1968AEC88851F831, + 0C7388B5872921063FF273B8, + 9EE1754A8E5230FA1C50713F, + 1852E56533842FDFBE9A6EE3, + CB79C1D77F4FBF0C64B69E1D, + 5E9EFF0130B8CBBEAA0D321B, + EF8AB3F393E946FE4A21AA17, + B70DDF51EDD940F5EF96B96D, + E28816D62DAA38A2794ED6D2, + A911433D03B3314558DB8850, + 590ABC7E64B05F4814FA919E, ); runOnlyForDeploymentPostprocessing = 0; }; F38385A81FAC837FA1743686 = {isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( E3498B080326636A372B74AE, 828D4B32ECB7ECE234A5A1A9, diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/buffers/juce_AudioDataConverters.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/buffers/juce_AudioDataConverters.cpp deleted file mode 100644 index a78b3956b4..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/buffers/juce_AudioDataConverters.cpp +++ /dev/null @@ -1,600 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -void AudioDataConverters::convertFloatToInt16LE (const float* source, void* dest, int numSamples, const int destBytesPerSample) -{ - const double maxVal = (double) 0x7fff; - char* intData = static_cast (dest); - - if (dest != (void*) source || destBytesPerSample <= 4) - { - for (int i = 0; i < numSamples; ++i) - { - *(uint16*) intData = ByteOrder::swapIfBigEndian ((uint16) (short) roundToInt (jlimit (-maxVal, maxVal, maxVal * source[i]))); - intData += destBytesPerSample; - } - } - else - { - intData += destBytesPerSample * numSamples; - - for (int i = numSamples; --i >= 0;) - { - intData -= destBytesPerSample; - *(uint16*) intData = ByteOrder::swapIfBigEndian ((uint16) (short) roundToInt (jlimit (-maxVal, maxVal, maxVal * source[i]))); - } - } -} - -void AudioDataConverters::convertFloatToInt16BE (const float* source, void* dest, int numSamples, const int destBytesPerSample) -{ - const double maxVal = (double) 0x7fff; - char* intData = static_cast (dest); - - if (dest != (void*) source || destBytesPerSample <= 4) - { - for (int i = 0; i < numSamples; ++i) - { - *(uint16*) intData = ByteOrder::swapIfLittleEndian ((uint16) (short) roundToInt (jlimit (-maxVal, maxVal, maxVal * source[i]))); - intData += destBytesPerSample; - } - } - else - { - intData += destBytesPerSample * numSamples; - - for (int i = numSamples; --i >= 0;) - { - intData -= destBytesPerSample; - *(uint16*) intData = ByteOrder::swapIfLittleEndian ((uint16) (short) roundToInt (jlimit (-maxVal, maxVal, maxVal * source[i]))); - } - } -} - -void AudioDataConverters::convertFloatToInt24LE (const float* source, void* dest, int numSamples, const int destBytesPerSample) -{ - const double maxVal = (double) 0x7fffff; - char* intData = static_cast (dest); - - if (dest != (void*) source || destBytesPerSample <= 4) - { - for (int i = 0; i < numSamples; ++i) - { - ByteOrder::littleEndian24BitToChars (roundToInt (jlimit (-maxVal, maxVal, maxVal * source[i])), intData); - intData += destBytesPerSample; - } - } - else - { - intData += destBytesPerSample * numSamples; - - for (int i = numSamples; --i >= 0;) - { - intData -= destBytesPerSample; - ByteOrder::littleEndian24BitToChars (roundToInt (jlimit (-maxVal, maxVal, maxVal * source[i])), intData); - } - } -} - -void AudioDataConverters::convertFloatToInt24BE (const float* source, void* dest, int numSamples, const int destBytesPerSample) -{ - const double maxVal = (double) 0x7fffff; - char* intData = static_cast (dest); - - if (dest != (void*) source || destBytesPerSample <= 4) - { - for (int i = 0; i < numSamples; ++i) - { - ByteOrder::bigEndian24BitToChars (roundToInt (jlimit (-maxVal, maxVal, maxVal * source[i])), intData); - intData += destBytesPerSample; - } - } - else - { - intData += destBytesPerSample * numSamples; - - for (int i = numSamples; --i >= 0;) - { - intData -= destBytesPerSample; - ByteOrder::bigEndian24BitToChars (roundToInt (jlimit (-maxVal, maxVal, maxVal * source[i])), intData); - } - } -} - -void AudioDataConverters::convertFloatToInt32LE (const float* source, void* dest, int numSamples, const int destBytesPerSample) -{ - const double maxVal = (double) 0x7fffffff; - char* intData = static_cast (dest); - - if (dest != (void*) source || destBytesPerSample <= 4) - { - for (int i = 0; i < numSamples; ++i) - { - *(uint32*)intData = ByteOrder::swapIfBigEndian ((uint32) roundToInt (jlimit (-maxVal, maxVal, maxVal * source[i]))); - intData += destBytesPerSample; - } - } - else - { - intData += destBytesPerSample * numSamples; - - for (int i = numSamples; --i >= 0;) - { - intData -= destBytesPerSample; - *(uint32*)intData = ByteOrder::swapIfBigEndian ((uint32) roundToInt (jlimit (-maxVal, maxVal, maxVal * source[i]))); - } - } -} - -void AudioDataConverters::convertFloatToInt32BE (const float* source, void* dest, int numSamples, const int destBytesPerSample) -{ - const double maxVal = (double) 0x7fffffff; - char* intData = static_cast (dest); - - if (dest != (void*) source || destBytesPerSample <= 4) - { - for (int i = 0; i < numSamples; ++i) - { - *(uint32*)intData = ByteOrder::swapIfLittleEndian ((uint32) roundToInt (jlimit (-maxVal, maxVal, maxVal * source[i]))); - intData += destBytesPerSample; - } - } - else - { - intData += destBytesPerSample * numSamples; - - for (int i = numSamples; --i >= 0;) - { - intData -= destBytesPerSample; - *(uint32*)intData = ByteOrder::swapIfLittleEndian ((uint32) roundToInt (jlimit (-maxVal, maxVal, maxVal * source[i]))); - } - } -} - -void AudioDataConverters::convertFloatToFloat32LE (const float* source, void* dest, int numSamples, const int destBytesPerSample) -{ - jassert (dest != (void*) source || destBytesPerSample <= 4); // This op can't be performed on in-place data! - - char* d = static_cast (dest); - - for (int i = 0; i < numSamples; ++i) - { - *(float*) d = source[i]; - - #if JUCE_BIG_ENDIAN - *(uint32*) d = ByteOrder::swap (*(uint32*) d); - #endif - - d += destBytesPerSample; - } -} - -void AudioDataConverters::convertFloatToFloat32BE (const float* source, void* dest, int numSamples, const int destBytesPerSample) -{ - jassert (dest != (void*) source || destBytesPerSample <= 4); // This op can't be performed on in-place data! - - char* d = static_cast (dest); - - for (int i = 0; i < numSamples; ++i) - { - *(float*) d = source[i]; - - #if JUCE_LITTLE_ENDIAN - *(uint32*) d = ByteOrder::swap (*(uint32*) d); - #endif - - d += destBytesPerSample; - } -} - -//============================================================================== -void AudioDataConverters::convertInt16LEToFloat (const void* const source, float* const dest, int numSamples, const int srcBytesPerSample) -{ - const float scale = 1.0f / 0x7fff; - const char* intData = static_cast (source); - - if (source != (void*) dest || srcBytesPerSample >= 4) - { - for (int i = 0; i < numSamples; ++i) - { - dest[i] = scale * (short) ByteOrder::swapIfBigEndian (*(uint16*)intData); - intData += srcBytesPerSample; - } - } - else - { - intData += srcBytesPerSample * numSamples; - - for (int i = numSamples; --i >= 0;) - { - intData -= srcBytesPerSample; - dest[i] = scale * (short) ByteOrder::swapIfBigEndian (*(uint16*)intData); - } - } -} - -void AudioDataConverters::convertInt16BEToFloat (const void* const source, float* const dest, int numSamples, const int srcBytesPerSample) -{ - const float scale = 1.0f / 0x7fff; - const char* intData = static_cast (source); - - if (source != (void*) dest || srcBytesPerSample >= 4) - { - for (int i = 0; i < numSamples; ++i) - { - dest[i] = scale * (short) ByteOrder::swapIfLittleEndian (*(uint16*)intData); - intData += srcBytesPerSample; - } - } - else - { - intData += srcBytesPerSample * numSamples; - - for (int i = numSamples; --i >= 0;) - { - intData -= srcBytesPerSample; - dest[i] = scale * (short) ByteOrder::swapIfLittleEndian (*(uint16*)intData); - } - } -} - -void AudioDataConverters::convertInt24LEToFloat (const void* const source, float* const dest, int numSamples, const int srcBytesPerSample) -{ - const float scale = 1.0f / 0x7fffff; - const char* intData = static_cast (source); - - if (source != (void*) dest || srcBytesPerSample >= 4) - { - for (int i = 0; i < numSamples; ++i) - { - dest[i] = scale * (short) ByteOrder::littleEndian24Bit (intData); - intData += srcBytesPerSample; - } - } - else - { - intData += srcBytesPerSample * numSamples; - - for (int i = numSamples; --i >= 0;) - { - intData -= srcBytesPerSample; - dest[i] = scale * (short) ByteOrder::littleEndian24Bit (intData); - } - } -} - -void AudioDataConverters::convertInt24BEToFloat (const void* const source, float* const dest, int numSamples, const int srcBytesPerSample) -{ - const float scale = 1.0f / 0x7fffff; - const char* intData = static_cast (source); - - if (source != (void*) dest || srcBytesPerSample >= 4) - { - for (int i = 0; i < numSamples; ++i) - { - dest[i] = scale * (short) ByteOrder::bigEndian24Bit (intData); - intData += srcBytesPerSample; - } - } - else - { - intData += srcBytesPerSample * numSamples; - - for (int i = numSamples; --i >= 0;) - { - intData -= srcBytesPerSample; - dest[i] = scale * (short) ByteOrder::bigEndian24Bit (intData); - } - } -} - -void AudioDataConverters::convertInt32LEToFloat (const void* const source, float* const dest, int numSamples, const int srcBytesPerSample) -{ - const float scale = 1.0f / 0x7fffffff; - const char* intData = static_cast (source); - - if (source != (void*) dest || srcBytesPerSample >= 4) - { - for (int i = 0; i < numSamples; ++i) - { - dest[i] = scale * (int) ByteOrder::swapIfBigEndian (*(uint32*) intData); - intData += srcBytesPerSample; - } - } - else - { - intData += srcBytesPerSample * numSamples; - - for (int i = numSamples; --i >= 0;) - { - intData -= srcBytesPerSample; - dest[i] = scale * (int) ByteOrder::swapIfBigEndian (*(uint32*) intData); - } - } -} - -void AudioDataConverters::convertInt32BEToFloat (const void* const source, float* const dest, int numSamples, const int srcBytesPerSample) -{ - const float scale = 1.0f / 0x7fffffff; - const char* intData = static_cast (source); - - if (source != (void*) dest || srcBytesPerSample >= 4) - { - for (int i = 0; i < numSamples; ++i) - { - dest[i] = scale * (int) ByteOrder::swapIfLittleEndian (*(uint32*) intData); - intData += srcBytesPerSample; - } - } - else - { - intData += srcBytesPerSample * numSamples; - - for (int i = numSamples; --i >= 0;) - { - intData -= srcBytesPerSample; - dest[i] = scale * (int) ByteOrder::swapIfLittleEndian (*(uint32*) intData); - } - } -} - -void AudioDataConverters::convertFloat32LEToFloat (const void* const source, float* const dest, int numSamples, const int srcBytesPerSample) -{ - const char* s = static_cast (source); - - for (int i = 0; i < numSamples; ++i) - { - dest[i] = *(float*)s; - - #if JUCE_BIG_ENDIAN - uint32* const d = (uint32*) (dest + i); - *d = ByteOrder::swap (*d); - #endif - - s += srcBytesPerSample; - } -} - -void AudioDataConverters::convertFloat32BEToFloat (const void* const source, float* const dest, int numSamples, const int srcBytesPerSample) -{ - const char* s = static_cast (source); - - for (int i = 0; i < numSamples; ++i) - { - dest[i] = *(float*)s; - - #if JUCE_LITTLE_ENDIAN - uint32* const d = (uint32*) (dest + i); - *d = ByteOrder::swap (*d); - #endif - - s += srcBytesPerSample; - } -} - - -//============================================================================== -void AudioDataConverters::convertFloatToFormat (const DataFormat destFormat, - const float* const source, - void* const dest, - const int numSamples) -{ - switch (destFormat) - { - case int16LE: convertFloatToInt16LE (source, dest, numSamples); break; - case int16BE: convertFloatToInt16BE (source, dest, numSamples); break; - case int24LE: convertFloatToInt24LE (source, dest, numSamples); break; - case int24BE: convertFloatToInt24BE (source, dest, numSamples); break; - case int32LE: convertFloatToInt32LE (source, dest, numSamples); break; - case int32BE: convertFloatToInt32BE (source, dest, numSamples); break; - case float32LE: convertFloatToFloat32LE (source, dest, numSamples); break; - case float32BE: convertFloatToFloat32BE (source, dest, numSamples); break; - default: jassertfalse; break; - } -} - -void AudioDataConverters::convertFormatToFloat (const DataFormat sourceFormat, - const void* const source, - float* const dest, - const int numSamples) -{ - switch (sourceFormat) - { - case int16LE: convertInt16LEToFloat (source, dest, numSamples); break; - case int16BE: convertInt16BEToFloat (source, dest, numSamples); break; - case int24LE: convertInt24LEToFloat (source, dest, numSamples); break; - case int24BE: convertInt24BEToFloat (source, dest, numSamples); break; - case int32LE: convertInt32LEToFloat (source, dest, numSamples); break; - case int32BE: convertInt32BEToFloat (source, dest, numSamples); break; - case float32LE: convertFloat32LEToFloat (source, dest, numSamples); break; - case float32BE: convertFloat32BEToFloat (source, dest, numSamples); break; - default: jassertfalse; break; - } -} - -//============================================================================== -void AudioDataConverters::interleaveSamples (const float** const source, - float* const dest, - const int numSamples, - const int numChannels) -{ - for (int chan = 0; chan < numChannels; ++chan) - { - int i = chan; - const float* src = source [chan]; - - for (int j = 0; j < numSamples; ++j) - { - dest [i] = src [j]; - i += numChannels; - } - } -} - -void AudioDataConverters::deinterleaveSamples (const float* const source, - float** const dest, - const int numSamples, - const int numChannels) -{ - for (int chan = 0; chan < numChannels; ++chan) - { - int i = chan; - float* dst = dest [chan]; - - for (int j = 0; j < numSamples; ++j) - { - dst [j] = source [i]; - i += numChannels; - } - } -} - - -//============================================================================== -#if JUCE_UNIT_TESTS - -class AudioConversionTests : public UnitTest -{ -public: - AudioConversionTests() : UnitTest ("Audio data conversion") {} - - template - struct Test5 - { - static void test (UnitTest& unitTest, Random& r) - { - test (unitTest, false, r); - test (unitTest, true, r); - } - - static void test (UnitTest& unitTest, bool inPlace, Random& r) - { - const int numSamples = 2048; - int32 original [numSamples], converted [numSamples], reversed [numSamples]; - - { - AudioData::Pointer d (original); - bool clippingFailed = false; - - for (int i = 0; i < numSamples / 2; ++i) - { - d.setAsFloat (r.nextFloat() * 2.2f - 1.1f); - - if (! d.isFloatingPoint()) - clippingFailed = d.getAsFloat() > 1.0f || d.getAsFloat() < -1.0f || clippingFailed; - - ++d; - d.setAsInt32 (r.nextInt()); - ++d; - } - - unitTest.expect (! clippingFailed); - } - - // convert data from the source to dest format.. - ScopedPointer conv (new AudioData::ConverterInstance , - AudioData::Pointer >()); - conv->convertSamples (inPlace ? reversed : converted, original, numSamples); - - // ..and back again.. - conv = new AudioData::ConverterInstance , - AudioData::Pointer >(); - if (! inPlace) - zeromem (reversed, sizeof (reversed)); - - conv->convertSamples (reversed, inPlace ? reversed : converted, numSamples); - - { - int biggestDiff = 0; - AudioData::Pointer d1 (original); - AudioData::Pointer d2 (reversed); - - const int errorMargin = 2 * AudioData::Pointer::get32BitResolution() - + AudioData::Pointer::get32BitResolution(); - - for (int i = 0; i < numSamples; ++i) - { - biggestDiff = jmax (biggestDiff, std::abs (d1.getAsInt32() - d2.getAsInt32())); - ++d1; - ++d2; - } - - unitTest.expect (biggestDiff <= errorMargin); - } - } - }; - - template - struct Test3 - { - static void test (UnitTest& unitTest, Random& r) - { - Test5 ::test (unitTest, r); - Test5 ::test (unitTest, r); - } - }; - - template - struct Test2 - { - static void test (UnitTest& unitTest, Random& r) - { - Test3 ::test (unitTest, r); - Test3 ::test (unitTest, r); - Test3 ::test (unitTest, r); - Test3 ::test (unitTest, r); - Test3 ::test (unitTest, r); - Test3 ::test (unitTest, r); - } - }; - - template - struct Test1 - { - static void test (UnitTest& unitTest, Random& r) - { - Test2 ::test (unitTest, r); - Test2 ::test (unitTest, r); - } - }; - - void runTest() - { - Random r = getRandom(); - beginTest ("Round-trip conversion: Int8"); - Test1 ::test (*this, r); - beginTest ("Round-trip conversion: Int16"); - Test1 ::test (*this, r); - beginTest ("Round-trip conversion: Int24"); - Test1 ::test (*this, r); - beginTest ("Round-trip conversion: Int32"); - Test1 ::test (*this, r); - beginTest ("Round-trip conversion: Float32"); - Test1 ::test (*this, r); - } -}; - -static AudioConversionTests audioConversionUnitTests; - -#endif diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/buffers/juce_AudioDataConverters.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/buffers/juce_AudioDataConverters.h deleted file mode 100644 index b3f49a63df..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/buffers/juce_AudioDataConverters.h +++ /dev/null @@ -1,710 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_AUDIODATACONVERTERS_H_INCLUDED -#define JUCE_AUDIODATACONVERTERS_H_INCLUDED - - -//============================================================================== -/** - This class a container which holds all the classes pertaining to the AudioData::Pointer - audio sample format class. - - @see AudioData::Pointer. -*/ -class JUCE_API AudioData -{ -public: - //============================================================================== - // These types can be used as the SampleFormat template parameter for the AudioData::Pointer class. - - class Int8; /**< Used as a template parameter for AudioData::Pointer. Indicates an 8-bit integer packed data format. */ - class UInt8; /**< Used as a template parameter for AudioData::Pointer. Indicates an 8-bit unsigned integer packed data format. */ - class Int16; /**< Used as a template parameter for AudioData::Pointer. Indicates an 16-bit integer packed data format. */ - class Int24; /**< Used as a template parameter for AudioData::Pointer. Indicates an 24-bit integer packed data format. */ - class Int32; /**< Used as a template parameter for AudioData::Pointer. Indicates an 32-bit integer packed data format. */ - class Float32; /**< Used as a template parameter for AudioData::Pointer. Indicates an 32-bit float data format. */ - - //============================================================================== - // These types can be used as the Endianness template parameter for the AudioData::Pointer class. - - class BigEndian; /**< Used as a template parameter for AudioData::Pointer. Indicates that the samples are stored in big-endian order. */ - class LittleEndian; /**< Used as a template parameter for AudioData::Pointer. Indicates that the samples are stored in little-endian order. */ - class NativeEndian; /**< Used as a template parameter for AudioData::Pointer. Indicates that the samples are stored in the CPU's native endianness. */ - - //============================================================================== - // These types can be used as the InterleavingType template parameter for the AudioData::Pointer class. - - class NonInterleaved; /**< Used as a template parameter for AudioData::Pointer. Indicates that the samples are stored contiguously. */ - class Interleaved; /**< Used as a template parameter for AudioData::Pointer. Indicates that the samples are interleaved with a number of other channels. */ - - //============================================================================== - // These types can be used as the Constness template parameter for the AudioData::Pointer class. - - class NonConst; /**< Used as a template parameter for AudioData::Pointer. Indicates that the pointer can be used for non-const data. */ - class Const; /**< Used as a template parameter for AudioData::Pointer. Indicates that the samples can only be used for const data.. */ - - #ifndef DOXYGEN - //============================================================================== - class BigEndian - { - public: - template static inline float getAsFloat (SampleFormatType& s) noexcept { return s.getAsFloatBE(); } - template static inline void setAsFloat (SampleFormatType& s, float newValue) noexcept { s.setAsFloatBE (newValue); } - template static inline int32 getAsInt32 (SampleFormatType& s) noexcept { return s.getAsInt32BE(); } - template static inline void setAsInt32 (SampleFormatType& s, int32 newValue) noexcept { s.setAsInt32BE (newValue); } - template static inline void copyFrom (DestType& dest, SourceType& source) noexcept { dest.copyFromBE (source); } - enum { isBigEndian = 1 }; - }; - - class LittleEndian - { - public: - template static inline float getAsFloat (SampleFormatType& s) noexcept { return s.getAsFloatLE(); } - template static inline void setAsFloat (SampleFormatType& s, float newValue) noexcept { s.setAsFloatLE (newValue); } - template static inline int32 getAsInt32 (SampleFormatType& s) noexcept { return s.getAsInt32LE(); } - template static inline void setAsInt32 (SampleFormatType& s, int32 newValue) noexcept { s.setAsInt32LE (newValue); } - template static inline void copyFrom (DestType& dest, SourceType& source) noexcept { dest.copyFromLE (source); } - enum { isBigEndian = 0 }; - }; - - #if JUCE_BIG_ENDIAN - class NativeEndian : public BigEndian {}; - #else - class NativeEndian : public LittleEndian {}; - #endif - - //============================================================================== - class Int8 - { - public: - inline Int8 (void* d) noexcept : data (static_cast (d)) {} - - inline void advance() noexcept { ++data; } - inline void skip (int numSamples) noexcept { data += numSamples; } - inline float getAsFloatLE() const noexcept { return (float) (*data * (1.0 / (1.0 + maxValue))); } - inline float getAsFloatBE() const noexcept { return getAsFloatLE(); } - inline void setAsFloatLE (float newValue) noexcept { *data = (int8) jlimit ((int) -maxValue, (int) maxValue, roundToInt (newValue * (1.0 + maxValue))); } - inline void setAsFloatBE (float newValue) noexcept { setAsFloatLE (newValue); } - inline int32 getAsInt32LE() const noexcept { return (int) (*data << 24); } - inline int32 getAsInt32BE() const noexcept { return getAsInt32LE(); } - inline void setAsInt32LE (int newValue) noexcept { *data = (int8) (newValue >> 24); } - inline void setAsInt32BE (int newValue) noexcept { setAsInt32LE (newValue); } - inline void clear() noexcept { *data = 0; } - inline void clearMultiple (int num) noexcept { zeromem (data, (size_t) (num * bytesPerSample)) ;} - template inline void copyFromLE (SourceType& source) noexcept { setAsInt32LE (source.getAsInt32()); } - template inline void copyFromBE (SourceType& source) noexcept { setAsInt32BE (source.getAsInt32()); } - inline void copyFromSameType (Int8& source) noexcept { *data = *source.data; } - - int8* data; - enum { bytesPerSample = 1, maxValue = 0x7f, resolution = (1 << 24), isFloat = 0 }; - }; - - class UInt8 - { - public: - inline UInt8 (void* d) noexcept : data (static_cast (d)) {} - - inline void advance() noexcept { ++data; } - inline void skip (int numSamples) noexcept { data += numSamples; } - inline float getAsFloatLE() const noexcept { return (float) ((*data - 128) * (1.0 / (1.0 + maxValue))); } - inline float getAsFloatBE() const noexcept { return getAsFloatLE(); } - inline void setAsFloatLE (float newValue) noexcept { *data = (uint8) jlimit (0, 255, 128 + roundToInt (newValue * (1.0 + maxValue))); } - inline void setAsFloatBE (float newValue) noexcept { setAsFloatLE (newValue); } - inline int32 getAsInt32LE() const noexcept { return (int) ((*data - 128) << 24); } - inline int32 getAsInt32BE() const noexcept { return getAsInt32LE(); } - inline void setAsInt32LE (int newValue) noexcept { *data = (uint8) (128 + (newValue >> 24)); } - inline void setAsInt32BE (int newValue) noexcept { setAsInt32LE (newValue); } - inline void clear() noexcept { *data = 128; } - inline void clearMultiple (int num) noexcept { memset (data, 128, (size_t) num) ;} - template inline void copyFromLE (SourceType& source) noexcept { setAsInt32LE (source.getAsInt32()); } - template inline void copyFromBE (SourceType& source) noexcept { setAsInt32BE (source.getAsInt32()); } - inline void copyFromSameType (UInt8& source) noexcept { *data = *source.data; } - - uint8* data; - enum { bytesPerSample = 1, maxValue = 0x7f, resolution = (1 << 24), isFloat = 0 }; - }; - - class Int16 - { - public: - inline Int16 (void* d) noexcept : data (static_cast (d)) {} - - inline void advance() noexcept { ++data; } - inline void skip (int numSamples) noexcept { data += numSamples; } - inline float getAsFloatLE() const noexcept { return (float) ((1.0 / (1.0 + maxValue)) * (int16) ByteOrder::swapIfBigEndian (*data)); } - inline float getAsFloatBE() const noexcept { return (float) ((1.0 / (1.0 + maxValue)) * (int16) ByteOrder::swapIfLittleEndian (*data)); } - inline void setAsFloatLE (float newValue) noexcept { *data = ByteOrder::swapIfBigEndian ((uint16) jlimit ((int) -maxValue, (int) maxValue, roundToInt (newValue * (1.0 + maxValue)))); } - inline void setAsFloatBE (float newValue) noexcept { *data = ByteOrder::swapIfLittleEndian ((uint16) jlimit ((int) -maxValue, (int) maxValue, roundToInt (newValue * (1.0 + maxValue)))); } - inline int32 getAsInt32LE() const noexcept { return (int32) (ByteOrder::swapIfBigEndian ((uint16) *data) << 16); } - inline int32 getAsInt32BE() const noexcept { return (int32) (ByteOrder::swapIfLittleEndian ((uint16) *data) << 16); } - inline void setAsInt32LE (int32 newValue) noexcept { *data = ByteOrder::swapIfBigEndian ((uint16) (newValue >> 16)); } - inline void setAsInt32BE (int32 newValue) noexcept { *data = ByteOrder::swapIfLittleEndian ((uint16) (newValue >> 16)); } - inline void clear() noexcept { *data = 0; } - inline void clearMultiple (int num) noexcept { zeromem (data, (size_t) (num * bytesPerSample)) ;} - template inline void copyFromLE (SourceType& source) noexcept { setAsInt32LE (source.getAsInt32()); } - template inline void copyFromBE (SourceType& source) noexcept { setAsInt32BE (source.getAsInt32()); } - inline void copyFromSameType (Int16& source) noexcept { *data = *source.data; } - - uint16* data; - enum { bytesPerSample = 2, maxValue = 0x7fff, resolution = (1 << 16), isFloat = 0 }; - }; - - class Int24 - { - public: - inline Int24 (void* d) noexcept : data (static_cast (d)) {} - - inline void advance() noexcept { data += 3; } - inline void skip (int numSamples) noexcept { data += 3 * numSamples; } - inline float getAsFloatLE() const noexcept { return (float) (ByteOrder::littleEndian24Bit (data) * (1.0 / (1.0 + maxValue))); } - inline float getAsFloatBE() const noexcept { return (float) (ByteOrder::bigEndian24Bit (data) * (1.0 / (1.0 + maxValue))); } - inline void setAsFloatLE (float newValue) noexcept { ByteOrder::littleEndian24BitToChars (jlimit ((int) -maxValue, (int) maxValue, roundToInt (newValue * (1.0 + maxValue))), data); } - inline void setAsFloatBE (float newValue) noexcept { ByteOrder::bigEndian24BitToChars (jlimit ((int) -maxValue, (int) maxValue, roundToInt (newValue * (1.0 + maxValue))), data); } - inline int32 getAsInt32LE() const noexcept { return (int32) ByteOrder::littleEndian24Bit (data) << 8; } - inline int32 getAsInt32BE() const noexcept { return (int32) ByteOrder::bigEndian24Bit (data) << 8; } - inline void setAsInt32LE (int32 newValue) noexcept { ByteOrder::littleEndian24BitToChars (newValue >> 8, data); } - inline void setAsInt32BE (int32 newValue) noexcept { ByteOrder::bigEndian24BitToChars (newValue >> 8, data); } - inline void clear() noexcept { data[0] = 0; data[1] = 0; data[2] = 0; } - inline void clearMultiple (int num) noexcept { zeromem (data, (size_t) (num * bytesPerSample)) ;} - template inline void copyFromLE (SourceType& source) noexcept { setAsInt32LE (source.getAsInt32()); } - template inline void copyFromBE (SourceType& source) noexcept { setAsInt32BE (source.getAsInt32()); } - inline void copyFromSameType (Int24& source) noexcept { data[0] = source.data[0]; data[1] = source.data[1]; data[2] = source.data[2]; } - - char* data; - enum { bytesPerSample = 3, maxValue = 0x7fffff, resolution = (1 << 8), isFloat = 0 }; - }; - - class Int32 - { - public: - inline Int32 (void* d) noexcept : data (static_cast (d)) {} - - inline void advance() noexcept { ++data; } - inline void skip (int numSamples) noexcept { data += numSamples; } - inline float getAsFloatLE() const noexcept { return (float) ((1.0 / (1.0 + maxValue)) * (int32) ByteOrder::swapIfBigEndian (*data)); } - inline float getAsFloatBE() const noexcept { return (float) ((1.0 / (1.0 + maxValue)) * (int32) ByteOrder::swapIfLittleEndian (*data)); } - inline void setAsFloatLE (float newValue) noexcept { *data = ByteOrder::swapIfBigEndian ((uint32) (maxValue * jlimit (-1.0, 1.0, (double) newValue))); } - inline void setAsFloatBE (float newValue) noexcept { *data = ByteOrder::swapIfLittleEndian ((uint32) (maxValue * jlimit (-1.0, 1.0, (double) newValue))); } - inline int32 getAsInt32LE() const noexcept { return (int32) ByteOrder::swapIfBigEndian (*data); } - inline int32 getAsInt32BE() const noexcept { return (int32) ByteOrder::swapIfLittleEndian (*data); } - inline void setAsInt32LE (int32 newValue) noexcept { *data = ByteOrder::swapIfBigEndian ((uint32) newValue); } - inline void setAsInt32BE (int32 newValue) noexcept { *data = ByteOrder::swapIfLittleEndian ((uint32) newValue); } - inline void clear() noexcept { *data = 0; } - inline void clearMultiple (int num) noexcept { zeromem (data, (size_t) (num * bytesPerSample)) ;} - template inline void copyFromLE (SourceType& source) noexcept { setAsInt32LE (source.getAsInt32()); } - template inline void copyFromBE (SourceType& source) noexcept { setAsInt32BE (source.getAsInt32()); } - inline void copyFromSameType (Int32& source) noexcept { *data = *source.data; } - - uint32* data; - enum { bytesPerSample = 4, maxValue = 0x7fffffff, resolution = 1, isFloat = 0 }; - }; - - /** A 32-bit integer type, of which only the bottom 24 bits are used. */ - class Int24in32 : public Int32 - { - public: - inline Int24in32 (void* d) noexcept : Int32 (d) {} - - inline float getAsFloatLE() const noexcept { return (float) ((1.0 / (1.0 + maxValue)) * (int32) ByteOrder::swapIfBigEndian (*data)); } - inline float getAsFloatBE() const noexcept { return (float) ((1.0 / (1.0 + maxValue)) * (int32) ByteOrder::swapIfLittleEndian (*data)); } - inline void setAsFloatLE (float newValue) noexcept { *data = ByteOrder::swapIfBigEndian ((uint32) (maxValue * jlimit (-1.0, 1.0, (double) newValue))); } - inline void setAsFloatBE (float newValue) noexcept { *data = ByteOrder::swapIfLittleEndian ((uint32) (maxValue * jlimit (-1.0, 1.0, (double) newValue))); } - inline int32 getAsInt32LE() const noexcept { return (int32) ByteOrder::swapIfBigEndian (*data) << 8; } - inline int32 getAsInt32BE() const noexcept { return (int32) ByteOrder::swapIfLittleEndian (*data) << 8; } - inline void setAsInt32LE (int32 newValue) noexcept { *data = ByteOrder::swapIfBigEndian ((uint32) newValue >> 8); } - inline void setAsInt32BE (int32 newValue) noexcept { *data = ByteOrder::swapIfLittleEndian ((uint32) newValue >> 8); } - template inline void copyFromLE (SourceType& source) noexcept { setAsInt32LE (source.getAsInt32()); } - template inline void copyFromBE (SourceType& source) noexcept { setAsInt32BE (source.getAsInt32()); } - inline void copyFromSameType (Int24in32& source) noexcept { *data = *source.data; } - - enum { bytesPerSample = 4, maxValue = 0x7fffff, resolution = (1 << 8), isFloat = 0 }; - }; - - class Float32 - { - public: - inline Float32 (void* d) noexcept : data (static_cast (d)) {} - - inline void advance() noexcept { ++data; } - inline void skip (int numSamples) noexcept { data += numSamples; } - #if JUCE_BIG_ENDIAN - inline float getAsFloatBE() const noexcept { return *data; } - inline void setAsFloatBE (float newValue) noexcept { *data = newValue; } - inline float getAsFloatLE() const noexcept { union { uint32 asInt; float asFloat; } n; n.asInt = ByteOrder::swap (*(uint32*) data); return n.asFloat; } - inline void setAsFloatLE (float newValue) noexcept { union { uint32 asInt; float asFloat; } n; n.asFloat = newValue; *(uint32*) data = ByteOrder::swap (n.asInt); } - #else - inline float getAsFloatLE() const noexcept { return *data; } - inline void setAsFloatLE (float newValue) noexcept { *data = newValue; } - inline float getAsFloatBE() const noexcept { union { uint32 asInt; float asFloat; } n; n.asInt = ByteOrder::swap (*(uint32*) data); return n.asFloat; } - inline void setAsFloatBE (float newValue) noexcept { union { uint32 asInt; float asFloat; } n; n.asFloat = newValue; *(uint32*) data = ByteOrder::swap (n.asInt); } - #endif - inline int32 getAsInt32LE() const noexcept { return (int32) roundToInt (jlimit (-1.0, 1.0, (double) getAsFloatLE()) * (double) maxValue); } - inline int32 getAsInt32BE() const noexcept { return (int32) roundToInt (jlimit (-1.0, 1.0, (double) getAsFloatBE()) * (double) maxValue); } - inline void setAsInt32LE (int32 newValue) noexcept { setAsFloatLE ((float) (newValue * (1.0 / (1.0 + maxValue)))); } - inline void setAsInt32BE (int32 newValue) noexcept { setAsFloatBE ((float) (newValue * (1.0 / (1.0 + maxValue)))); } - inline void clear() noexcept { *data = 0; } - inline void clearMultiple (int num) noexcept { zeromem (data, (size_t) (num * bytesPerSample)) ;} - template inline void copyFromLE (SourceType& source) noexcept { setAsFloatLE (source.getAsFloat()); } - template inline void copyFromBE (SourceType& source) noexcept { setAsFloatBE (source.getAsFloat()); } - inline void copyFromSameType (Float32& source) noexcept { *data = *source.data; } - - float* data; - enum { bytesPerSample = 4, maxValue = 0x7fffffff, resolution = (1 << 8), isFloat = 1 }; - }; - - //============================================================================== - class NonInterleaved - { - public: - inline NonInterleaved() noexcept {} - inline NonInterleaved (const NonInterleaved&) noexcept {} - inline NonInterleaved (const int) noexcept {} - inline void copyFrom (const NonInterleaved&) noexcept {} - template inline void advanceData (SampleFormatType& s) noexcept { s.advance(); } - template inline void advanceDataBy (SampleFormatType& s, int numSamples) noexcept { s.skip (numSamples); } - template inline void clear (SampleFormatType& s, int numSamples) noexcept { s.clearMultiple (numSamples); } - template inline static int getNumBytesBetweenSamples (const SampleFormatType&) noexcept { return SampleFormatType::bytesPerSample; } - - enum { isInterleavedType = 0, numInterleavedChannels = 1 }; - }; - - class Interleaved - { - public: - inline Interleaved() noexcept : numInterleavedChannels (1) {} - inline Interleaved (const Interleaved& other) noexcept : numInterleavedChannels (other.numInterleavedChannels) {} - inline Interleaved (const int numInterleavedChans) noexcept : numInterleavedChannels (numInterleavedChans) {} - inline void copyFrom (const Interleaved& other) noexcept { numInterleavedChannels = other.numInterleavedChannels; } - template inline void advanceData (SampleFormatType& s) noexcept { s.skip (numInterleavedChannels); } - template inline void advanceDataBy (SampleFormatType& s, int numSamples) noexcept { s.skip (numInterleavedChannels * numSamples); } - template inline void clear (SampleFormatType& s, int numSamples) noexcept { while (--numSamples >= 0) { s.clear(); s.skip (numInterleavedChannels); } } - template inline int getNumBytesBetweenSamples (const SampleFormatType&) const noexcept { return numInterleavedChannels * SampleFormatType::bytesPerSample; } - int numInterleavedChannels; - enum { isInterleavedType = 1 }; - }; - - //============================================================================== - class NonConst - { - public: - typedef void VoidType; - static inline void* toVoidPtr (VoidType* v) noexcept { return v; } - enum { isConst = 0 }; - }; - - class Const - { - public: - typedef const void VoidType; - static inline void* toVoidPtr (VoidType* v) noexcept { return const_cast (v); } - enum { isConst = 1 }; - }; - #endif - - //============================================================================== - /** - A pointer to a block of audio data with a particular encoding. - - This object can be used to read and write from blocks of encoded audio samples. To create one, you specify - the audio format as a series of template parameters, e.g. - @code - // this creates a pointer for reading from a const array of 16-bit little-endian packed samples. - AudioData::Pointer pointer (someRawAudioData); - - // These methods read the sample that is being pointed to - float firstSampleAsFloat = pointer.getAsFloat(); - int32 firstSampleAsInt = pointer.getAsInt32(); - ++pointer; // moves the pointer to the next sample. - pointer += 3; // skips the next 3 samples. - @endcode - - The convertSamples() method lets you copy a range of samples from one format to another, automatically - converting its format. - - @see AudioData::Converter - */ - template - class Pointer : private InterleavingType // (inherited for EBCO) - { - public: - //============================================================================== - /** Creates a non-interleaved pointer from some raw data in the appropriate format. - This constructor is only used if you've specified the AudioData::NonInterleaved option - - for interleaved formats, use the constructor that also takes a number of channels. - */ - Pointer (typename Constness::VoidType* sourceData) noexcept - : data (Constness::toVoidPtr (sourceData)) - { - // If you're using interleaved data, call the other constructor! If you're using non-interleaved data, - // you should pass NonInterleaved as the template parameter for the interleaving type! - static_jassert (InterleavingType::isInterleavedType == 0); - } - - /** Creates a pointer from some raw data in the appropriate format with the specified number of interleaved channels. - For non-interleaved data, use the other constructor. - */ - Pointer (typename Constness::VoidType* sourceData, int numInterleaved) noexcept - : InterleavingType (numInterleaved), data (Constness::toVoidPtr (sourceData)) - { - } - - /** Creates a copy of another pointer. */ - Pointer (const Pointer& other) noexcept - : InterleavingType (other), data (other.data) - { - } - - Pointer& operator= (const Pointer& other) noexcept - { - InterleavingType::operator= (other); - data = other.data; - return *this; - } - - //============================================================================== - /** Returns the value of the first sample as a floating point value. - The value will be in the range -1.0 to 1.0 for integer formats. For floating point - formats, the value could be outside that range, although -1 to 1 is the standard range. - */ - inline float getAsFloat() const noexcept { return Endianness::getAsFloat (data); } - - /** Sets the value of the first sample as a floating point value. - - (This method can only be used if the AudioData::NonConst option was used). - The value should be in the range -1.0 to 1.0 - for integer formats, values outside that - range will be clipped. For floating point formats, any value passed in here will be - written directly, although -1 to 1 is the standard range. - */ - inline void setAsFloat (float newValue) noexcept - { - static_jassert (Constness::isConst == 0); // trying to write to a const pointer! For a writeable one, use AudioData::NonConst instead! - Endianness::setAsFloat (data, newValue); - } - - /** Returns the value of the first sample as a 32-bit integer. - The value returned will be in the range 0x80000000 to 0x7fffffff, and shorter values will be - shifted to fill this range (e.g. if you're reading from 24-bit data, the values will be shifted up - by 8 bits when returned here). If the source data is floating point, values beyond -1.0 to 1.0 will - be clipped so that -1.0 maps onto -0x7fffffff and 1.0 maps to 0x7fffffff. - */ - inline int32 getAsInt32() const noexcept { return Endianness::getAsInt32 (data); } - - /** Sets the value of the first sample as a 32-bit integer. - This will be mapped to the range of the format that is being written - see getAsInt32(). - */ - inline void setAsInt32 (int32 newValue) noexcept - { - static_jassert (Constness::isConst == 0); // trying to write to a const pointer! For a writeable one, use AudioData::NonConst instead! - Endianness::setAsInt32 (data, newValue); - } - - /** Moves the pointer along to the next sample. */ - inline Pointer& operator++() noexcept { advance(); return *this; } - - /** Moves the pointer back to the previous sample. */ - inline Pointer& operator--() noexcept { this->advanceDataBy (data, -1); return *this; } - - /** Adds a number of samples to the pointer's position. */ - Pointer& operator+= (int samplesToJump) noexcept { this->advanceDataBy (data, samplesToJump); return *this; } - - /** Writes a stream of samples into this pointer from another pointer. - This will copy the specified number of samples, converting between formats appropriately. - */ - void convertSamples (Pointer source, int numSamples) const noexcept - { - static_jassert (Constness::isConst == 0); // trying to write to a const pointer! For a writeable one, use AudioData::NonConst instead! - - for (Pointer dest (*this); --numSamples >= 0;) - { - dest.data.copyFromSameType (source.data); - dest.advance(); - source.advance(); - } - } - - /** Writes a stream of samples into this pointer from another pointer. - This will copy the specified number of samples, converting between formats appropriately. - */ - template - void convertSamples (OtherPointerType source, int numSamples) const noexcept - { - static_jassert (Constness::isConst == 0); // trying to write to a const pointer! For a writeable one, use AudioData::NonConst instead! - - Pointer dest (*this); - - if (source.getRawData() != getRawData() || source.getNumBytesBetweenSamples() >= getNumBytesBetweenSamples()) - { - while (--numSamples >= 0) - { - Endianness::copyFrom (dest.data, source); - dest.advance(); - ++source; - } - } - else // copy backwards if we're increasing the sample width.. - { - dest += numSamples; - source += numSamples; - - while (--numSamples >= 0) - Endianness::copyFrom ((--dest).data, --source); - } - } - - /** Sets a number of samples to zero. */ - void clearSamples (int numSamples) const noexcept - { - Pointer dest (*this); - dest.clear (dest.data, numSamples); - } - - /** Scans a block of data, returning the lowest and highest levels as floats */ - void findMinAndMax (size_t numSamples, float& minValue, float& maxValue) const noexcept - { - if (numSamples == 0) - { - minValue = maxValue = 0; - return; - } - - Pointer dest (*this); - - if (isFloatingPoint()) - { - float mn = dest.getAsFloat(); - dest.advance(); - float mx = mn; - - while (--numSamples > 0) - { - const float v = dest.getAsFloat(); - dest.advance(); - - if (mx < v) mx = v; - if (v < mn) mn = v; - } - - minValue = mn; - maxValue = mx; - } - else - { - int32 mn = dest.getAsInt32(); - dest.advance(); - int32 mx = mn; - - while (--numSamples > 0) - { - const int v = dest.getAsInt32(); - dest.advance(); - - if (mx < v) mx = v; - if (v < mn) mn = v; - } - - minValue = mn * (float) (1.0 / (1.0 + Int32::maxValue)); - maxValue = mx * (float) (1.0 / (1.0 + Int32::maxValue)); - } - } - - /** Returns true if the pointer is using a floating-point format. */ - static bool isFloatingPoint() noexcept { return (bool) SampleFormat::isFloat; } - - /** Returns true if the format is big-endian. */ - static bool isBigEndian() noexcept { return (bool) Endianness::isBigEndian; } - - /** Returns the number of bytes in each sample (ignoring the number of interleaved channels). */ - static int getBytesPerSample() noexcept { return (int) SampleFormat::bytesPerSample; } - - /** Returns the number of interleaved channels in the format. */ - int getNumInterleavedChannels() const noexcept { return (int) this->numInterleavedChannels; } - - /** Returns the number of bytes between the start address of each sample. */ - int getNumBytesBetweenSamples() const noexcept { return InterleavingType::getNumBytesBetweenSamples (data); } - - /** Returns the accuracy of this format when represented as a 32-bit integer. - This is the smallest number above 0 that can be represented in the sample format, converted to - a 32-bit range. E,g. if the format is 8-bit, its resolution is 0x01000000; if the format is 24-bit, - its resolution is 0x100. - */ - static int get32BitResolution() noexcept { return (int) SampleFormat::resolution; } - - /** Returns a pointer to the underlying data. */ - const void* getRawData() const noexcept { return data.data; } - - private: - //============================================================================== - SampleFormat data; - - inline void advance() noexcept { this->advanceData (data); } - - Pointer operator++ (int); // private to force you to use the more efficient pre-increment! - Pointer operator-- (int); - }; - - //============================================================================== - /** A base class for objects that are used to convert between two different sample formats. - - The AudioData::ConverterInstance implements this base class and can be templated, so - you can create an instance that converts between two particular formats, and then - store this in the abstract base class. - - @see AudioData::ConverterInstance - */ - class Converter - { - public: - virtual ~Converter() {} - - /** Converts a sequence of samples from the converter's source format into the dest format. */ - virtual void convertSamples (void* destSamples, const void* sourceSamples, int numSamples) const = 0; - - /** Converts a sequence of samples from the converter's source format into the dest format. - This method takes sub-channel indexes, which can be used with interleaved formats in order to choose a - particular sub-channel of the data to be used. - */ - virtual void convertSamples (void* destSamples, int destSubChannel, - const void* sourceSamples, int sourceSubChannel, int numSamples) const = 0; - }; - - //============================================================================== - /** - A class that converts between two templated AudioData::Pointer types, and which - implements the AudioData::Converter interface. - - This can be used as a concrete instance of the AudioData::Converter abstract class. - - @see AudioData::Converter - */ - template - class ConverterInstance : public Converter - { - public: - ConverterInstance (int numSourceChannels = 1, int numDestChannels = 1) - : sourceChannels (numSourceChannels), destChannels (numDestChannels) - {} - - void convertSamples (void* dest, const void* source, int numSamples) const override - { - SourceSampleType s (source, sourceChannels); - DestSampleType d (dest, destChannels); - d.convertSamples (s, numSamples); - } - - void convertSamples (void* dest, int destSubChannel, - const void* source, int sourceSubChannel, int numSamples) const override - { - jassert (destSubChannel < destChannels && sourceSubChannel < sourceChannels); - - SourceSampleType s (addBytesToPointer (source, sourceSubChannel * SourceSampleType::getBytesPerSample()), sourceChannels); - DestSampleType d (addBytesToPointer (dest, destSubChannel * DestSampleType::getBytesPerSample()), destChannels); - d.convertSamples (s, numSamples); - } - - private: - JUCE_DECLARE_NON_COPYABLE (ConverterInstance) - - const int sourceChannels, destChannels; - }; -}; - - - -//============================================================================== -/** - A set of routines to convert buffers of 32-bit floating point data to and from - various integer formats. - - Note that these functions are deprecated - the AudioData class provides a much more - flexible set of conversion classes now. -*/ -class JUCE_API AudioDataConverters -{ -public: - //============================================================================== - static void convertFloatToInt16LE (const float* source, void* dest, int numSamples, int destBytesPerSample = 2); - static void convertFloatToInt16BE (const float* source, void* dest, int numSamples, int destBytesPerSample = 2); - - static void convertFloatToInt24LE (const float* source, void* dest, int numSamples, int destBytesPerSample = 3); - static void convertFloatToInt24BE (const float* source, void* dest, int numSamples, int destBytesPerSample = 3); - - static void convertFloatToInt32LE (const float* source, void* dest, int numSamples, int destBytesPerSample = 4); - static void convertFloatToInt32BE (const float* source, void* dest, int numSamples, int destBytesPerSample = 4); - - static void convertFloatToFloat32LE (const float* source, void* dest, int numSamples, int destBytesPerSample = 4); - static void convertFloatToFloat32BE (const float* source, void* dest, int numSamples, int destBytesPerSample = 4); - - //============================================================================== - static void convertInt16LEToFloat (const void* source, float* dest, int numSamples, int srcBytesPerSample = 2); - static void convertInt16BEToFloat (const void* source, float* dest, int numSamples, int srcBytesPerSample = 2); - - static void convertInt24LEToFloat (const void* source, float* dest, int numSamples, int srcBytesPerSample = 3); - static void convertInt24BEToFloat (const void* source, float* dest, int numSamples, int srcBytesPerSample = 3); - - static void convertInt32LEToFloat (const void* source, float* dest, int numSamples, int srcBytesPerSample = 4); - static void convertInt32BEToFloat (const void* source, float* dest, int numSamples, int srcBytesPerSample = 4); - - static void convertFloat32LEToFloat (const void* source, float* dest, int numSamples, int srcBytesPerSample = 4); - static void convertFloat32BEToFloat (const void* source, float* dest, int numSamples, int srcBytesPerSample = 4); - - //============================================================================== - enum DataFormat - { - int16LE, - int16BE, - int24LE, - int24BE, - int32LE, - int32BE, - float32LE, - float32BE, - }; - - static void convertFloatToFormat (DataFormat destFormat, - const float* source, void* dest, int numSamples); - - static void convertFormatToFloat (DataFormat sourceFormat, - const void* source, float* dest, int numSamples); - - //============================================================================== - static void interleaveSamples (const float** source, float* dest, - int numSamples, int numChannels); - - static void deinterleaveSamples (const float* source, float** dest, - int numSamples, int numChannels); - -private: - AudioDataConverters(); - JUCE_DECLARE_NON_COPYABLE (AudioDataConverters) -}; - - -#endif // JUCE_AUDIODATACONVERTERS_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/buffers/juce_AudioSampleBuffer.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/buffers/juce_AudioSampleBuffer.cpp deleted file mode 100644 index 15b59dafce..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/buffers/juce_AudioSampleBuffer.cpp +++ /dev/null @@ -1,670 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -AudioSampleBuffer::AudioSampleBuffer() noexcept - : numChannels (0), size (0), allocatedBytes (0), - channels (static_cast (preallocatedChannelSpace)), - isClear (false) -{ -} - -AudioSampleBuffer::AudioSampleBuffer (const int numChans, - const int numSamples) noexcept - : numChannels (numChans), - size (numSamples) -{ - jassert (numSamples >= 0); - jassert (numChans >= 0); - - allocateData(); -} - -AudioSampleBuffer::AudioSampleBuffer (const AudioSampleBuffer& other) noexcept - : numChannels (other.numChannels), - size (other.size), - allocatedBytes (other.allocatedBytes) -{ - if (allocatedBytes == 0) - { - allocateChannels (other.channels, 0); - } - else - { - allocateData(); - - if (other.isClear) - { - clear(); - } - else - { - for (int i = 0; i < numChannels; ++i) - FloatVectorOperations::copy (channels[i], other.channels[i], size); - } - } -} - -void AudioSampleBuffer::allocateData() -{ - const size_t channelListSize = sizeof (float*) * (size_t) (numChannels + 1); - allocatedBytes = (size_t) numChannels * (size_t) size * sizeof (float) + channelListSize + 32; - allocatedData.malloc (allocatedBytes); - channels = reinterpret_cast (allocatedData.getData()); - - float* chan = (float*) (allocatedData + channelListSize); - for (int i = 0; i < numChannels; ++i) - { - channels[i] = chan; - chan += size; - } - - channels [numChannels] = nullptr; - isClear = false; -} - -AudioSampleBuffer::AudioSampleBuffer (float* const* dataToReferTo, - const int numChans, - const int numSamples) noexcept - : numChannels (numChans), - size (numSamples), - allocatedBytes (0) -{ - jassert (dataToReferTo != nullptr); - jassert (numChans >= 0 && numSamples >= 0); - allocateChannels (dataToReferTo, 0); -} - -AudioSampleBuffer::AudioSampleBuffer (float* const* dataToReferTo, - const int numChans, - const int startSample, - const int numSamples) noexcept - : numChannels (numChans), - size (numSamples), - allocatedBytes (0), - isClear (false) -{ - jassert (dataToReferTo != nullptr); - jassert (numChans >= 0 && startSample >= 0 && numSamples >= 0); - allocateChannels (dataToReferTo, startSample); -} - -void AudioSampleBuffer::setDataToReferTo (float** dataToReferTo, - const int newNumChannels, - const int newNumSamples) noexcept -{ - jassert (dataToReferTo != nullptr); - jassert (newNumChannels >= 0 && newNumSamples >= 0); - - allocatedBytes = 0; - allocatedData.free(); - - numChannels = newNumChannels; - size = newNumSamples; - - allocateChannels (dataToReferTo, 0); - jassert (! isClear); -} - -void AudioSampleBuffer::allocateChannels (float* const* const dataToReferTo, int offset) -{ - jassert (offset >= 0); - - // (try to avoid doing a malloc here, as that'll blow up things like Pro-Tools) - if (numChannels < (int) numElementsInArray (preallocatedChannelSpace)) - { - channels = static_cast (preallocatedChannelSpace); - } - else - { - allocatedData.malloc ((size_t) numChannels + 1, sizeof (float*)); - channels = reinterpret_cast (allocatedData.getData()); - } - - for (int i = 0; i < numChannels; ++i) - { - // you have to pass in the same number of valid pointers as numChannels - jassert (dataToReferTo[i] != nullptr); - - channels[i] = dataToReferTo[i] + offset; - } - - channels [numChannels] = nullptr; - isClear = false; -} - -AudioSampleBuffer& AudioSampleBuffer::operator= (const AudioSampleBuffer& other) noexcept -{ - if (this != &other) - { - setSize (other.getNumChannels(), other.getNumSamples(), false, false, false); - - if (other.isClear) - { - clear(); - } - else - { - isClear = false; - - for (int i = 0; i < numChannels; ++i) - FloatVectorOperations::copy (channels[i], other.channels[i], size); - } - } - - return *this; -} - -AudioSampleBuffer::~AudioSampleBuffer() noexcept -{ -} - -void AudioSampleBuffer::setSize (const int newNumChannels, - const int newNumSamples, - const bool keepExistingContent, - const bool clearExtraSpace, - const bool avoidReallocating) noexcept -{ - jassert (newNumChannels >= 0); - jassert (newNumSamples >= 0); - - if (newNumSamples != size || newNumChannels != numChannels) - { - const size_t allocatedSamplesPerChannel = ((size_t) newNumSamples + 3) & ~3u; - const size_t channelListSize = ((sizeof (float*) * (size_t) (newNumChannels + 1)) + 15) & ~15u; - const size_t newTotalBytes = ((size_t) newNumChannels * (size_t) allocatedSamplesPerChannel * sizeof (float)) - + channelListSize + 32; - - if (keepExistingContent) - { - HeapBlock newData; - newData.allocate (newTotalBytes, clearExtraSpace || isClear); - - const size_t numSamplesToCopy = (size_t) jmin (newNumSamples, size); - - float** const newChannels = reinterpret_cast (newData.getData()); - float* newChan = reinterpret_cast (newData + channelListSize); - - for (int j = 0; j < newNumChannels; ++j) - { - newChannels[j] = newChan; - newChan += allocatedSamplesPerChannel; - } - - if (! isClear) - { - const int numChansToCopy = jmin (numChannels, newNumChannels); - for (int i = 0; i < numChansToCopy; ++i) - FloatVectorOperations::copy (newChannels[i], channels[i], (int) numSamplesToCopy); - } - - allocatedData.swapWith (newData); - allocatedBytes = newTotalBytes; - channels = newChannels; - } - else - { - if (avoidReallocating && allocatedBytes >= newTotalBytes) - { - if (clearExtraSpace || isClear) - allocatedData.clear (newTotalBytes); - } - else - { - allocatedBytes = newTotalBytes; - allocatedData.allocate (newTotalBytes, clearExtraSpace || isClear); - channels = reinterpret_cast (allocatedData.getData()); - } - - float* chan = reinterpret_cast (allocatedData + channelListSize); - for (int i = 0; i < newNumChannels; ++i) - { - channels[i] = chan; - chan += allocatedSamplesPerChannel; - } - } - - channels [newNumChannels] = 0; - size = newNumSamples; - numChannels = newNumChannels; - } -} - -void AudioSampleBuffer::clear() noexcept -{ - if (! isClear) - { - for (int i = 0; i < numChannels; ++i) - FloatVectorOperations::clear (channels[i], size); - - isClear = true; - } -} - -void AudioSampleBuffer::clear (const int startSample, - const int numSamples) noexcept -{ - jassert (startSample >= 0 && startSample + numSamples <= size); - - if (! isClear) - { - if (startSample == 0 && numSamples == size) - isClear = true; - - for (int i = 0; i < numChannels; ++i) - FloatVectorOperations::clear (channels[i] + startSample, numSamples); - } -} - -void AudioSampleBuffer::clear (const int channel, - const int startSample, - const int numSamples) noexcept -{ - jassert (isPositiveAndBelow (channel, numChannels)); - jassert (startSample >= 0 && startSample + numSamples <= size); - - if (! isClear) - FloatVectorOperations::clear (channels [channel] + startSample, numSamples); -} - -float AudioSampleBuffer::getSample (int channel, int index) const noexcept -{ - jassert (isPositiveAndBelow (channel, numChannels)); - jassert (isPositiveAndBelow (index, size)); - return *(channels [channel] + index); -} - -void AudioSampleBuffer::setSample (int channel, int index, float newValue) noexcept -{ - jassert (isPositiveAndBelow (channel, numChannels)); - jassert (isPositiveAndBelow (index, size)); - *(channels [channel] + index) = newValue; - isClear = false; -} - -void AudioSampleBuffer::addSample (int channel, int index, float valueToAdd) noexcept -{ - jassert (isPositiveAndBelow (channel, numChannels)); - jassert (isPositiveAndBelow (index, size)); - *(channels [channel] + index) += valueToAdd; - isClear = false; -} - -void AudioSampleBuffer::applyGain (const int channel, - const int startSample, - int numSamples, - const float gain) noexcept -{ - jassert (isPositiveAndBelow (channel, numChannels)); - jassert (startSample >= 0 && startSample + numSamples <= size); - - if (gain != 1.0f && ! isClear) - { - float* const d = channels [channel] + startSample; - - if (gain == 0.0f) - FloatVectorOperations::clear (d, numSamples); - else - FloatVectorOperations::multiply (d, gain, numSamples); - } -} - -void AudioSampleBuffer::applyGainRamp (const int channel, - const int startSample, - int numSamples, - float startGain, - float endGain) noexcept -{ - if (! isClear) - { - if (startGain == endGain) - { - applyGain (channel, startSample, numSamples, startGain); - } - else - { - jassert (isPositiveAndBelow (channel, numChannels)); - jassert (startSample >= 0 && startSample + numSamples <= size); - - const float increment = (endGain - startGain) / numSamples; - float* d = channels [channel] + startSample; - - while (--numSamples >= 0) - { - *d++ *= startGain; - startGain += increment; - } - } - } -} - -void AudioSampleBuffer::applyGain (int startSample, int numSamples, float gain) noexcept -{ - for (int i = 0; i < numChannels; ++i) - applyGain (i, startSample, numSamples, gain); -} - -void AudioSampleBuffer::applyGain (const float gain) noexcept -{ - applyGain (0, size, gain); -} - -void AudioSampleBuffer::applyGainRamp (int startSample, int numSamples, - float startGain, float endGain) noexcept -{ - for (int i = 0; i < numChannels; ++i) - applyGainRamp (i, startSample, numSamples, startGain, endGain); -} - -void AudioSampleBuffer::addFrom (const int destChannel, - const int destStartSample, - const AudioSampleBuffer& source, - const int sourceChannel, - const int sourceStartSample, - int numSamples, - const float gain) noexcept -{ - jassert (&source != this || sourceChannel != destChannel); - jassert (isPositiveAndBelow (destChannel, numChannels)); - jassert (destStartSample >= 0 && destStartSample + numSamples <= size); - jassert (isPositiveAndBelow (sourceChannel, source.numChannels)); - jassert (sourceStartSample >= 0 && sourceStartSample + numSamples <= source.size); - - if (gain != 0.0f && numSamples > 0 && ! source.isClear) - { - float* const d = channels [destChannel] + destStartSample; - const float* const s = source.channels [sourceChannel] + sourceStartSample; - - if (isClear) - { - isClear = false; - - if (gain != 1.0f) - FloatVectorOperations::copyWithMultiply (d, s, gain, numSamples); - else - FloatVectorOperations::copy (d, s, numSamples); - } - else - { - if (gain != 1.0f) - FloatVectorOperations::addWithMultiply (d, s, gain, numSamples); - else - FloatVectorOperations::add (d, s, numSamples); - } - } -} - -void AudioSampleBuffer::addFrom (const int destChannel, - const int destStartSample, - const float* source, - int numSamples, - const float gain) noexcept -{ - jassert (isPositiveAndBelow (destChannel, numChannels)); - jassert (destStartSample >= 0 && destStartSample + numSamples <= size); - jassert (source != nullptr); - - if (gain != 0.0f && numSamples > 0) - { - float* const d = channels [destChannel] + destStartSample; - - if (isClear) - { - isClear = false; - - if (gain != 1.0f) - FloatVectorOperations::copyWithMultiply (d, source, gain, numSamples); - else - FloatVectorOperations::copy (d, source, numSamples); - } - else - { - if (gain != 1.0f) - FloatVectorOperations::addWithMultiply (d, source, gain, numSamples); - else - FloatVectorOperations::add (d, source, numSamples); - } - } -} - -void AudioSampleBuffer::addFromWithRamp (const int destChannel, - const int destStartSample, - const float* source, - int numSamples, - float startGain, - const float endGain) noexcept -{ - jassert (isPositiveAndBelow (destChannel, numChannels)); - jassert (destStartSample >= 0 && destStartSample + numSamples <= size); - jassert (source != nullptr); - - if (startGain == endGain) - { - addFrom (destChannel, destStartSample, source, numSamples, startGain); - } - else - { - if (numSamples > 0 && (startGain != 0.0f || endGain != 0.0f)) - { - isClear = false; - const float increment = (endGain - startGain) / numSamples; - float* d = channels [destChannel] + destStartSample; - - while (--numSamples >= 0) - { - *d++ += startGain * *source++; - startGain += increment; - } - } - } -} - -void AudioSampleBuffer::copyFrom (const int destChannel, - const int destStartSample, - const AudioSampleBuffer& source, - const int sourceChannel, - const int sourceStartSample, - int numSamples) noexcept -{ - jassert (&source != this || sourceChannel != destChannel); - jassert (isPositiveAndBelow (destChannel, numChannels)); - jassert (destStartSample >= 0 && destStartSample + numSamples <= size); - jassert (isPositiveAndBelow (sourceChannel, source.numChannels)); - jassert (sourceStartSample >= 0 && sourceStartSample + numSamples <= source.size); - - if (numSamples > 0) - { - if (source.isClear) - { - if (! isClear) - FloatVectorOperations::clear (channels [destChannel] + destStartSample, numSamples); - } - else - { - isClear = false; - FloatVectorOperations::copy (channels [destChannel] + destStartSample, - source.channels [sourceChannel] + sourceStartSample, - numSamples); - } - } -} - -void AudioSampleBuffer::copyFrom (const int destChannel, - const int destStartSample, - const float* source, - int numSamples) noexcept -{ - jassert (isPositiveAndBelow (destChannel, numChannels)); - jassert (destStartSample >= 0 && destStartSample + numSamples <= size); - jassert (source != nullptr); - - if (numSamples > 0) - { - isClear = false; - FloatVectorOperations::copy (channels [destChannel] + destStartSample, source, numSamples); - } -} - -void AudioSampleBuffer::copyFrom (const int destChannel, - const int destStartSample, - const float* source, - int numSamples, - const float gain) noexcept -{ - jassert (isPositiveAndBelow (destChannel, numChannels)); - jassert (destStartSample >= 0 && destStartSample + numSamples <= size); - jassert (source != nullptr); - - if (numSamples > 0) - { - float* const d = channels [destChannel] + destStartSample; - - if (gain != 1.0f) - { - if (gain == 0) - { - if (! isClear) - FloatVectorOperations::clear (d, numSamples); - } - else - { - isClear = false; - FloatVectorOperations::copyWithMultiply (d, source, gain, numSamples); - } - } - else - { - isClear = false; - FloatVectorOperations::copy (d, source, numSamples); - } - } -} - -void AudioSampleBuffer::copyFromWithRamp (const int destChannel, - const int destStartSample, - const float* source, - int numSamples, - float startGain, - float endGain) noexcept -{ - jassert (isPositiveAndBelow (destChannel, numChannels)); - jassert (destStartSample >= 0 && destStartSample + numSamples <= size); - jassert (source != nullptr); - - if (startGain == endGain) - { - copyFrom (destChannel, destStartSample, source, numSamples, startGain); - } - else - { - if (numSamples > 0 && (startGain != 0.0f || endGain != 0.0f)) - { - isClear = false; - const float increment = (endGain - startGain) / numSamples; - float* d = channels [destChannel] + destStartSample; - - while (--numSamples >= 0) - { - *d++ = startGain * *source++; - startGain += increment; - } - } - } -} - -void AudioSampleBuffer::reverse (int channel, int startSample, int numSamples) const noexcept -{ - jassert (isPositiveAndBelow (channel, numChannels)); - jassert (startSample >= 0 && startSample + numSamples <= size); - - if (! isClear) - std::reverse (channels[channel] + startSample, - channels[channel] + startSample + numSamples); -} - -void AudioSampleBuffer::reverse (int startSample, int numSamples) const noexcept -{ - for (int i = 0; i < numChannels; ++i) - reverse (i, startSample, numSamples); -} - -Range AudioSampleBuffer::findMinMax (const int channel, - const int startSample, - int numSamples) const noexcept -{ - jassert (isPositiveAndBelow (channel, numChannels)); - jassert (startSample >= 0 && startSample + numSamples <= size); - - if (isClear) - return Range(); - - return FloatVectorOperations::findMinAndMax (channels [channel] + startSample, numSamples); -} - -float AudioSampleBuffer::getMagnitude (const int channel, - const int startSample, - const int numSamples) const noexcept -{ - jassert (isPositiveAndBelow (channel, numChannels)); - jassert (startSample >= 0 && startSample + numSamples <= size); - - if (isClear) - return 0.0f; - - const Range r (findMinMax (channel, startSample, numSamples)); - - return jmax (r.getStart(), -r.getStart(), r.getEnd(), -r.getEnd()); -} - -float AudioSampleBuffer::getMagnitude (int startSample, int numSamples) const noexcept -{ - float mag = 0.0f; - - if (! isClear) - for (int i = 0; i < numChannels; ++i) - mag = jmax (mag, getMagnitude (i, startSample, numSamples)); - - return mag; -} - -float AudioSampleBuffer::getRMSLevel (const int channel, - const int startSample, - const int numSamples) const noexcept -{ - jassert (isPositiveAndBelow (channel, numChannels)); - jassert (startSample >= 0 && startSample + numSamples <= size); - - if (numSamples <= 0 || channel < 0 || channel >= numChannels || isClear) - return 0.0f; - - const float* const data = channels [channel] + startSample; - double sum = 0.0; - - for (int i = 0; i < numSamples; ++i) - { - const float sample = data [i]; - sum += sample * sample; - } - - return (float) std::sqrt (sum / numSamples); -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/buffers/juce_AudioSampleBuffer.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/buffers/juce_AudioSampleBuffer.h deleted file mode 100644 index 8b9a72c1ff..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/buffers/juce_AudioSampleBuffer.h +++ /dev/null @@ -1,526 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_AUDIOSAMPLEBUFFER_H_INCLUDED -#define JUCE_AUDIOSAMPLEBUFFER_H_INCLUDED - - -//============================================================================== -/** - A multi-channel buffer of 32-bit floating point audio samples. - -*/ -class JUCE_API AudioSampleBuffer -{ -public: - //============================================================================== - /** Creates an empty buffer with 0 channels and 0 length. */ - AudioSampleBuffer() noexcept; - - //============================================================================== - /** Creates a buffer with a specified number of channels and samples. - - The contents of the buffer will initially be undefined, so use clear() to - set all the samples to zero. - - The buffer will allocate its memory internally, and this will be released - when the buffer is deleted. If the memory can't be allocated, this will - throw a std::bad_alloc exception. - */ - AudioSampleBuffer (int numChannels, - int numSamples) noexcept; - - /** Creates a buffer using a pre-allocated block of memory. - - Note that if the buffer is resized or its number of channels is changed, it - will re-allocate memory internally and copy the existing data to this new area, - so it will then stop directly addressing this memory. - - @param dataToReferTo a pre-allocated array containing pointers to the data - for each channel that should be used by this buffer. The - buffer will only refer to this memory, it won't try to delete - it when the buffer is deleted or resized. - @param numChannels the number of channels to use - this must correspond to the - number of elements in the array passed in - @param numSamples the number of samples to use - this must correspond to the - size of the arrays passed in - */ - AudioSampleBuffer (float* const* dataToReferTo, - int numChannels, - int numSamples) noexcept; - - /** Creates a buffer using a pre-allocated block of memory. - - Note that if the buffer is resized or its number of channels is changed, it - will re-allocate memory internally and copy the existing data to this new area, - so it will then stop directly addressing this memory. - - @param dataToReferTo a pre-allocated array containing pointers to the data - for each channel that should be used by this buffer. The - buffer will only refer to this memory, it won't try to delete - it when the buffer is deleted or resized. - @param numChannels the number of channels to use - this must correspond to the - number of elements in the array passed in - @param startSample the offset within the arrays at which the data begins - @param numSamples the number of samples to use - this must correspond to the - size of the arrays passed in - */ - AudioSampleBuffer (float* const* dataToReferTo, - int numChannels, - int startSample, - int numSamples) noexcept; - - /** Copies another buffer. - - This buffer will make its own copy of the other's data, unless the buffer was created - using an external data buffer, in which case boths buffers will just point to the same - shared block of data. - */ - AudioSampleBuffer (const AudioSampleBuffer&) noexcept; - - /** Copies another buffer onto this one. - This buffer's size will be changed to that of the other buffer. - */ - AudioSampleBuffer& operator= (const AudioSampleBuffer&) noexcept; - - /** Destructor. - This will free any memory allocated by the buffer. - */ - ~AudioSampleBuffer() noexcept; - - //============================================================================== - /** Returns the number of channels of audio data that this buffer contains. - @see getSampleData - */ - int getNumChannels() const noexcept { return numChannels; } - - /** Returns the number of samples allocated in each of the buffer's channels. - @see getSampleData - */ - int getNumSamples() const noexcept { return size; } - - /** Returns a pointer to an array of read-only samples in one of the buffer's channels. - For speed, this doesn't check whether the channel number is out of range, - so be careful when using it! - If you need to write to the data, do NOT call this method and const_cast the - result! Instead, you must call getWritePointer so that the buffer knows you're - planning on modifying the data. - */ - const float* getReadPointer (int channelNumber) const noexcept - { - jassert (isPositiveAndBelow (channelNumber, numChannels)); - return channels [channelNumber]; - } - - /** Returns a pointer to an array of read-only samples in one of the buffer's channels. - For speed, this doesn't check whether the channel number or index are out of range, - so be careful when using it! - If you need to write to the data, do NOT call this method and const_cast the - result! Instead, you must call getWritePointer so that the buffer knows you're - planning on modifying the data. - */ - const float* getReadPointer (int channelNumber, int sampleIndex) const noexcept - { - jassert (isPositiveAndBelow (channelNumber, numChannels)); - jassert (isPositiveAndBelow (sampleIndex, size)); - return channels [channelNumber] + sampleIndex; - } - - /** Returns a writeable pointer to one of the buffer's channels. - For speed, this doesn't check whether the channel number is out of range, - so be careful when using it! - Note that if you're not planning on writing to the data, you should always - use getReadPointer instead. - */ - float* getWritePointer (int channelNumber) noexcept - { - jassert (isPositiveAndBelow (channelNumber, numChannels)); - isClear = false; - return channels [channelNumber]; - } - - /** Returns a writeable pointer to one of the buffer's channels. - For speed, this doesn't check whether the channel number or index are out of range, - so be careful when using it! - Note that if you're not planning on writing to the data, you should - use getReadPointer instead. - */ - float* getWritePointer (int channelNumber, int sampleIndex) noexcept - { - jassert (isPositiveAndBelow (channelNumber, numChannels)); - jassert (isPositiveAndBelow (sampleIndex, size)); - isClear = false; - return channels [channelNumber] + sampleIndex; - } - - /** Returns an array of pointers to the channels in the buffer. - - Don't modify any of the pointers that are returned, and bear in mind that - these will become invalid if the buffer is resized. - */ - const float** getArrayOfReadPointers() const noexcept { return const_cast (channels); } - - /** Returns an array of pointers to the channels in the buffer. - - Don't modify any of the pointers that are returned, and bear in mind that - these will become invalid if the buffer is resized. - */ - float** getArrayOfWritePointers() noexcept { isClear = false; return channels; } - - //============================================================================== - /** Changes the buffer's size or number of channels. - - This can expand or contract the buffer's length, and add or remove channels. - - If keepExistingContent is true, it will try to preserve as much of the - old data as it can in the new buffer. - - If clearExtraSpace is true, then any extra channels or space that is - allocated will be also be cleared. If false, then this space is left - uninitialised. - - If avoidReallocating is true, then changing the buffer's size won't reduce the - amount of memory that is currently allocated (but it will still increase it if - the new size is bigger than the amount it currently has). If this is false, then - a new allocation will be done so that the buffer uses takes up the minimum amount - of memory that it needs. - - If the required memory can't be allocated, this will throw a std::bad_alloc exception. - */ - void setSize (int newNumChannels, - int newNumSamples, - bool keepExistingContent = false, - bool clearExtraSpace = false, - bool avoidReallocating = false) noexcept; - - - /** Makes this buffer point to a pre-allocated set of channel data arrays. - - There's also a constructor that lets you specify arrays like this, but this - lets you change the channels dynamically. - - Note that if the buffer is resized or its number of channels is changed, it - will re-allocate memory internally and copy the existing data to this new area, - so it will then stop directly addressing this memory. - - @param dataToReferTo a pre-allocated array containing pointers to the data - for each channel that should be used by this buffer. The - buffer will only refer to this memory, it won't try to delete - it when the buffer is deleted or resized. - @param numChannels the number of channels to use - this must correspond to the - number of elements in the array passed in - @param numSamples the number of samples to use - this must correspond to the - size of the arrays passed in - */ - void setDataToReferTo (float** dataToReferTo, - int numChannels, - int numSamples) noexcept; - - //============================================================================== - /** Clears all the samples in all channels. */ - void clear() noexcept; - - /** Clears a specified region of all the channels. - - For speed, this doesn't check whether the channel and sample number - are in-range, so be careful! - */ - void clear (int startSample, - int numSamples) noexcept; - - /** Clears a specified region of just one channel. - - For speed, this doesn't check whether the channel and sample number - are in-range, so be careful! - */ - void clear (int channel, - int startSample, - int numSamples) noexcept; - - /** Returns true if the buffer has been entirely cleared. - Note that this does not actually measure the contents of the buffer - it simply - returns a flag that is set when the buffer is cleared, and which is reset whenever - functions like getWritePointer() are invoked. That means the method does not take - any time, but it may return false negatives when in fact the buffer is still empty. - */ - bool hasBeenCleared() const noexcept { return isClear; } - - //============================================================================== - /** Returns a sample from the buffer. - The channel and index are not checked - they are expected to be in-range. If not, - an assertion will be thrown, but in a release build, you're into 'undefined behaviour' - territory. - */ - float getSample (int channel, int sampleIndex) const noexcept; - - /** Sets a sample in the buffer. - The channel and index are not checked - they are expected to be in-range. If not, - an assertion will be thrown, but in a release build, you're into 'undefined behaviour' - territory. - */ - void setSample (int destChannel, int destSample, float newValue) noexcept; - - /** Adds a value to a sample in the buffer. - The channel and index are not checked - they are expected to be in-range. If not, - an assertion will be thrown, but in a release build, you're into 'undefined behaviour' - territory. - */ - void addSample (int destChannel, int destSample, float valueToAdd) noexcept; - - /** Applies a gain multiple to a region of one channel. - - For speed, this doesn't check whether the channel and sample number - are in-range, so be careful! - */ - void applyGain (int channel, - int startSample, - int numSamples, - float gain) noexcept; - - /** Applies a gain multiple to a region of all the channels. - - For speed, this doesn't check whether the sample numbers - are in-range, so be careful! - */ - void applyGain (int startSample, - int numSamples, - float gain) noexcept; - - /** Applies a gain multiple to all the audio data. */ - void applyGain (float gain) noexcept; - - /** Applies a range of gains to a region of a channel. - - The gain that is applied to each sample will vary from - startGain on the first sample to endGain on the last Sample, - so it can be used to do basic fades. - - For speed, this doesn't check whether the sample numbers - are in-range, so be careful! - */ - void applyGainRamp (int channel, - int startSample, - int numSamples, - float startGain, - float endGain) noexcept; - - /** Applies a range of gains to a region of all channels. - - The gain that is applied to each sample will vary from - startGain on the first sample to endGain on the last Sample, - so it can be used to do basic fades. - - For speed, this doesn't check whether the sample numbers - are in-range, so be careful! - */ - void applyGainRamp (int startSample, - int numSamples, - float startGain, - float endGain) noexcept; - - /** Adds samples from another buffer to this one. - - @param destChannel the channel within this buffer to add the samples to - @param destStartSample the start sample within this buffer's channel - @param source the source buffer to add from - @param sourceChannel the channel within the source buffer to read from - @param sourceStartSample the offset within the source buffer's channel to start reading samples from - @param numSamples the number of samples to process - @param gainToApplyToSource an optional gain to apply to the source samples before they are - added to this buffer's samples - - @see copyFrom - */ - void addFrom (int destChannel, - int destStartSample, - const AudioSampleBuffer& source, - int sourceChannel, - int sourceStartSample, - int numSamples, - float gainToApplyToSource = 1.0f) noexcept; - - /** Adds samples from an array of floats to one of the channels. - - @param destChannel the channel within this buffer to add the samples to - @param destStartSample the start sample within this buffer's channel - @param source the source data to use - @param numSamples the number of samples to process - @param gainToApplyToSource an optional gain to apply to the source samples before they are - added to this buffer's samples - - @see copyFrom - */ - void addFrom (int destChannel, - int destStartSample, - const float* source, - int numSamples, - float gainToApplyToSource = 1.0f) noexcept; - - /** Adds samples from an array of floats, applying a gain ramp to them. - - @param destChannel the channel within this buffer to add the samples to - @param destStartSample the start sample within this buffer's channel - @param source the source data to use - @param numSamples the number of samples to process - @param startGain the gain to apply to the first sample (this is multiplied with - the source samples before they are added to this buffer) - @param endGain the gain to apply to the final sample. The gain is linearly - interpolated between the first and last samples. - */ - void addFromWithRamp (int destChannel, - int destStartSample, - const float* source, - int numSamples, - float startGain, - float endGain) noexcept; - - /** Copies samples from another buffer to this one. - - @param destChannel the channel within this buffer to copy the samples to - @param destStartSample the start sample within this buffer's channel - @param source the source buffer to read from - @param sourceChannel the channel within the source buffer to read from - @param sourceStartSample the offset within the source buffer's channel to start reading samples from - @param numSamples the number of samples to process - - @see addFrom - */ - void copyFrom (int destChannel, - int destStartSample, - const AudioSampleBuffer& source, - int sourceChannel, - int sourceStartSample, - int numSamples) noexcept; - - /** Copies samples from an array of floats into one of the channels. - - @param destChannel the channel within this buffer to copy the samples to - @param destStartSample the start sample within this buffer's channel - @param source the source buffer to read from - @param numSamples the number of samples to process - - @see addFrom - */ - void copyFrom (int destChannel, - int destStartSample, - const float* source, - int numSamples) noexcept; - - /** Copies samples from an array of floats into one of the channels, applying a gain to it. - - @param destChannel the channel within this buffer to copy the samples to - @param destStartSample the start sample within this buffer's channel - @param source the source buffer to read from - @param numSamples the number of samples to process - @param gain the gain to apply - - @see addFrom - */ - void copyFrom (int destChannel, - int destStartSample, - const float* source, - int numSamples, - float gain) noexcept; - - /** Copies samples from an array of floats into one of the channels, applying a gain ramp. - - @param destChannel the channel within this buffer to copy the samples to - @param destStartSample the start sample within this buffer's channel - @param source the source buffer to read from - @param numSamples the number of samples to process - @param startGain the gain to apply to the first sample (this is multiplied with - the source samples before they are copied to this buffer) - @param endGain the gain to apply to the final sample. The gain is linearly - interpolated between the first and last samples. - - @see addFrom - */ - void copyFromWithRamp (int destChannel, - int destStartSample, - const float* source, - int numSamples, - float startGain, - float endGain) noexcept; - - - /** Returns a Range indicating the lowest and highest sample values in a given section. - - @param channel the channel to read from - @param startSample the start sample within the channel - @param numSamples the number of samples to check - */ - Range findMinMax (int channel, - int startSample, - int numSamples) const noexcept; - - /** Finds the highest absolute sample value within a region of a channel. */ - float getMagnitude (int channel, - int startSample, - int numSamples) const noexcept; - - /** Finds the highest absolute sample value within a region on all channels. */ - float getMagnitude (int startSample, - int numSamples) const noexcept; - - /** Returns the root mean squared level for a region of a channel. */ - float getRMSLevel (int channel, - int startSample, - int numSamples) const noexcept; - - /** Reverses a part of a channel. */ - void reverse (int channel, int startSample, int numSamples) const noexcept; - - /** Reverses a part of the buffer. */ - void reverse (int startSample, int numSamples) const noexcept; - - //============================================================================== - #ifndef DOXYGEN - // Note that these methods have now been replaced by getReadPointer() and getWritePointer() - JUCE_DEPRECATED_WITH_BODY (const float* getSampleData (int channel) const, { return getReadPointer (channel); }) - JUCE_DEPRECATED_WITH_BODY (const float* getSampleData (int channel, int index) const, { return getReadPointer (channel, index); }) - JUCE_DEPRECATED_WITH_BODY (float* getSampleData (int channel), { return getWritePointer (channel); }) - JUCE_DEPRECATED_WITH_BODY (float* getSampleData (int channel, int index), { return getWritePointer (channel, index); }) - - // These have been replaced by getArrayOfReadPointers() and getArrayOfWritePointers() - JUCE_DEPRECATED_WITH_BODY (const float** getArrayOfChannels() const, { return getArrayOfReadPointers(); }) - JUCE_DEPRECATED_WITH_BODY (float** getArrayOfChannels(), { return getArrayOfWritePointers(); }) - #endif - -private: - //============================================================================== - int numChannels, size; - size_t allocatedBytes; - float** channels; - HeapBlock allocatedData; - float* preallocatedChannelSpace [32]; - bool isClear; - - void allocateData(); - void allocateChannels (float* const*, int offset); - - JUCE_LEAK_DETECTOR (AudioSampleBuffer) -}; - - -#endif // JUCE_AUDIOSAMPLEBUFFER_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/buffers/juce_FloatVectorOperations.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/buffers/juce_FloatVectorOperations.cpp deleted file mode 100644 index 2fc6898cba..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/buffers/juce_FloatVectorOperations.cpp +++ /dev/null @@ -1,893 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -namespace FloatVectorHelpers -{ - #define JUCE_INCREMENT_SRC_DEST dest += (16 / sizeof (*dest)); src += (16 / sizeof (*dest)); - #define JUCE_INCREMENT_SRC1_SRC2_DEST dest += (16 / sizeof (*dest)); src1 += (16 / sizeof (*dest)); src2 += (16 / sizeof (*dest)); - #define JUCE_INCREMENT_DEST dest += (16 / sizeof (*dest)); - - #if JUCE_USE_SSE_INTRINSICS - static bool sse2Present = false; - - static bool isSSE2Available() noexcept - { - if (sse2Present) - return true; - - sse2Present = SystemStats::hasSSE2(); - return sse2Present; - } - - inline static bool isAligned (const void* p) noexcept - { - return (((pointer_sized_int) p) & 15) == 0; - } - - struct BasicOps32 - { - typedef float Type; - typedef __m128 ParallelType; - enum { numParallel = 4 }; - - static forcedinline ParallelType load1 (Type v) noexcept { return _mm_load1_ps (&v); } - static forcedinline ParallelType loadA (const Type* v) noexcept { return _mm_load_ps (v); } - static forcedinline ParallelType loadU (const Type* v) noexcept { return _mm_loadu_ps (v); } - static forcedinline void storeA (Type* dest, ParallelType a) noexcept { _mm_store_ps (dest, a); } - static forcedinline void storeU (Type* dest, ParallelType a) noexcept { _mm_storeu_ps (dest, a); } - - static forcedinline ParallelType add (ParallelType a, ParallelType b) noexcept { return _mm_add_ps (a, b); } - static forcedinline ParallelType sub (ParallelType a, ParallelType b) noexcept { return _mm_sub_ps (a, b); } - static forcedinline ParallelType mul (ParallelType a, ParallelType b) noexcept { return _mm_mul_ps (a, b); } - static forcedinline ParallelType max (ParallelType a, ParallelType b) noexcept { return _mm_max_ps (a, b); } - static forcedinline ParallelType min (ParallelType a, ParallelType b) noexcept { return _mm_min_ps (a, b); } - - static forcedinline Type max (ParallelType a) noexcept { Type v[numParallel]; storeU (v, a); return jmax (v[0], v[1], v[2], v[3]); } - static forcedinline Type min (ParallelType a) noexcept { Type v[numParallel]; storeU (v, a); return jmin (v[0], v[1], v[2], v[3]); } - }; - - struct BasicOps64 - { - typedef double Type; - typedef __m128d ParallelType; - enum { numParallel = 2 }; - - static forcedinline ParallelType load1 (Type v) noexcept { return _mm_load1_pd (&v); } - static forcedinline ParallelType loadA (const Type* v) noexcept { return _mm_load_pd (v); } - static forcedinline ParallelType loadU (const Type* v) noexcept { return _mm_loadu_pd (v); } - static forcedinline void storeA (Type* dest, ParallelType a) noexcept { _mm_store_pd (dest, a); } - static forcedinline void storeU (Type* dest, ParallelType a) noexcept { _mm_storeu_pd (dest, a); } - - static forcedinline ParallelType add (ParallelType a, ParallelType b) noexcept { return _mm_add_pd (a, b); } - static forcedinline ParallelType sub (ParallelType a, ParallelType b) noexcept { return _mm_sub_pd (a, b); } - static forcedinline ParallelType mul (ParallelType a, ParallelType b) noexcept { return _mm_mul_pd (a, b); } - static forcedinline ParallelType max (ParallelType a, ParallelType b) noexcept { return _mm_max_pd (a, b); } - static forcedinline ParallelType min (ParallelType a, ParallelType b) noexcept { return _mm_min_pd (a, b); } - - static forcedinline Type max (ParallelType a) noexcept { Type v[numParallel]; storeU (v, a); return jmax (v[0], v[1]); } - static forcedinline Type min (ParallelType a) noexcept { Type v[numParallel]; storeU (v, a); return jmin (v[0], v[1]); } - }; - - #define JUCE_BEGIN_VEC_OP \ - typedef FloatVectorHelpers::ModeType::Mode Mode; \ - if (FloatVectorHelpers::isSSE2Available()) \ - { \ - const int numLongOps = num / Mode::numParallel; - - #define JUCE_FINISH_VEC_OP(normalOp) \ - num &= (Mode::numParallel - 1); \ - if (num == 0) return; \ - } \ - for (int i = 0; i < num; ++i) normalOp; - - #define JUCE_PERFORM_VEC_OP_DEST(normalOp, vecOp, locals, setupOp) \ - JUCE_BEGIN_VEC_OP \ - setupOp \ - if (FloatVectorHelpers::isAligned (dest)) JUCE_VEC_LOOP (vecOp, dummy, Mode::loadA, Mode::storeA, locals, JUCE_INCREMENT_DEST) \ - else JUCE_VEC_LOOP (vecOp, dummy, Mode::loadU, Mode::storeU, locals, JUCE_INCREMENT_DEST) \ - JUCE_FINISH_VEC_OP (normalOp) - - #define JUCE_PERFORM_VEC_OP_SRC_DEST(normalOp, vecOp, locals, increment, setupOp) \ - JUCE_BEGIN_VEC_OP \ - setupOp \ - if (FloatVectorHelpers::isAligned (dest)) \ - { \ - if (FloatVectorHelpers::isAligned (src)) JUCE_VEC_LOOP (vecOp, Mode::loadA, Mode::loadA, Mode::storeA, locals, increment) \ - else JUCE_VEC_LOOP (vecOp, Mode::loadU, Mode::loadA, Mode::storeA, locals, increment) \ - }\ - else \ - { \ - if (FloatVectorHelpers::isAligned (src)) JUCE_VEC_LOOP (vecOp, Mode::loadA, Mode::loadU, Mode::storeU, locals, increment) \ - else JUCE_VEC_LOOP (vecOp, Mode::loadU, Mode::loadU, Mode::storeU, locals, increment) \ - } \ - JUCE_FINISH_VEC_OP (normalOp) - - #define JUCE_PERFORM_VEC_OP_SRC1_SRC2_DEST(normalOp, vecOp, locals, increment, setupOp) \ - JUCE_BEGIN_VEC_OP \ - setupOp \ - { \ - Mode::ParallelType (&loadSrc1) (const Mode::Type* v) = FloatVectorHelpers::isAligned (src1) ? Mode::loadA : Mode::loadU; \ - Mode::ParallelType (&loadSrc2) (const Mode::Type* v) = FloatVectorHelpers::isAligned (src2) ? Mode::loadA : Mode::loadU; \ - void (&storeDst) (Mode::Type* dest, Mode::ParallelType a) = FloatVectorHelpers::isAligned (dest) ? Mode::storeA : Mode::storeU; \ - JUCE_VEC_LOOP_TWO_SOURCES (vecOp, loadSrc1, loadSrc2, storeDst, locals, increment); \ - } \ - JUCE_FINISH_VEC_OP (normalOp) - - //============================================================================== - #elif JUCE_USE_ARM_NEON - - struct BasicOps32 - { - typedef float Type; - typedef float32x4_t ParallelType; - enum { numParallel = 4 }; - - static forcedinline ParallelType load1 (Type v) noexcept { return vld1q_dup_f32 (&v); } - static forcedinline ParallelType loadA (const Type* v) noexcept { return vld1q_f32 (v); } - static forcedinline ParallelType loadU (const Type* v) noexcept { return vld1q_f32 (v); } - static forcedinline void storeA (Type* dest, ParallelType a) noexcept { vst1q_f32 (dest, a); } - static forcedinline void storeU (Type* dest, ParallelType a) noexcept { vst1q_f32 (dest, a); } - - static forcedinline ParallelType add (ParallelType a, ParallelType b) noexcept { return vaddq_f32 (a, b); } - static forcedinline ParallelType sub (ParallelType a, ParallelType b) noexcept { return vsubq_f32 (a, b); } - static forcedinline ParallelType mul (ParallelType a, ParallelType b) noexcept { return vmulq_f32 (a, b); } - static forcedinline ParallelType max (ParallelType a, ParallelType b) noexcept { return vmaxq_f32 (a, b); } - static forcedinline ParallelType min (ParallelType a, ParallelType b) noexcept { return vminq_f32 (a, b); } - - static forcedinline Type max (ParallelType a) noexcept { Type v[numParallel]; storeU (v, a); return jmax (v[0], v[1], v[2], v[3]); } - static forcedinline Type min (ParallelType a) noexcept { Type v[numParallel]; storeU (v, a); return jmin (v[0], v[1], v[2], v[3]); } - }; - - struct BasicOps64 - { - typedef double Type; - typedef double ParallelType; - enum { numParallel = 1 }; - - static forcedinline ParallelType load1 (Type v) noexcept { return v; } - static forcedinline ParallelType loadA (const Type* v) noexcept { return *v; } - static forcedinline ParallelType loadU (const Type* v) noexcept { return *v; } - static forcedinline void storeA (Type* dest, ParallelType a) noexcept { *dest = a; } - static forcedinline void storeU (Type* dest, ParallelType a) noexcept { *dest = a; } - - static forcedinline ParallelType add (ParallelType a, ParallelType b) noexcept { return a + b; } - static forcedinline ParallelType sub (ParallelType a, ParallelType b) noexcept { return a - b; } - static forcedinline ParallelType mul (ParallelType a, ParallelType b) noexcept { return a * b; } - static forcedinline ParallelType max (ParallelType a, ParallelType b) noexcept { return jmax (a, b); } - static forcedinline ParallelType min (ParallelType a, ParallelType b) noexcept { return jmin (a, b); } - - static forcedinline Type max (ParallelType a) noexcept { return a; } - static forcedinline Type min (ParallelType a) noexcept { return a; } - }; - - #define JUCE_BEGIN_VEC_OP \ - typedef FloatVectorHelpers::ModeType::Mode Mode; \ - if (Mode::numParallel > 1) \ - { \ - const int numLongOps = num / Mode::numParallel; - - #define JUCE_FINISH_VEC_OP(normalOp) \ - num &= (Mode::numParallel - 1); \ - if (num == 0) return; \ - } \ - for (int i = 0; i < num; ++i) normalOp; - - #define JUCE_PERFORM_VEC_OP_DEST(normalOp, vecOp, locals, setupOp) \ - JUCE_BEGIN_VEC_OP \ - setupOp \ - JUCE_VEC_LOOP (vecOp, dummy, Mode::loadU, Mode::storeU, locals, JUCE_INCREMENT_DEST) \ - JUCE_FINISH_VEC_OP (normalOp) - - #define JUCE_PERFORM_VEC_OP_SRC_DEST(normalOp, vecOp, locals, increment, setupOp) \ - JUCE_BEGIN_VEC_OP \ - setupOp \ - JUCE_VEC_LOOP (vecOp, Mode::loadU, Mode::loadU, Mode::storeU, locals, increment) \ - JUCE_FINISH_VEC_OP (normalOp) - - #define JUCE_PERFORM_VEC_OP_SRC1_SRC2_DEST(normalOp, vecOp, locals, increment, setupOp) \ - JUCE_BEGIN_VEC_OP \ - setupOp \ - JUCE_VEC_LOOP_TWO_SOURCES (vecOp, Mode::loadU, Mode::loadU, Mode::storeU, locals, increment) \ - JUCE_FINISH_VEC_OP (normalOp) - - //============================================================================== - #else - #define JUCE_PERFORM_VEC_OP_DEST(normalOp, vecOp, locals, setupOp) \ - for (int i = 0; i < num; ++i) normalOp; - - #define JUCE_PERFORM_VEC_OP_SRC_DEST(normalOp, vecOp, locals, increment, setupOp) \ - for (int i = 0; i < num; ++i) normalOp; - - #define JUCE_PERFORM_VEC_OP_SRC1_SRC2_DEST(normalOp, vecOp, locals, increment, setupOp) \ - for (int i = 0; i < num; ++i) normalOp; - #endif - - //============================================================================== - #define JUCE_VEC_LOOP(vecOp, srcLoad, dstLoad, dstStore, locals, increment) \ - for (int i = 0; i < numLongOps; ++i) \ - { \ - locals (srcLoad, dstLoad); \ - dstStore (dest, vecOp); \ - increment; \ - } - - #define JUCE_VEC_LOOP_TWO_SOURCES(vecOp, src1Load, src2Load, dstStore, locals, increment) \ - for (int i = 0; i < numLongOps; ++i) \ - { \ - locals (src1Load, src2Load); \ - dstStore (dest, vecOp); \ - increment; \ - } - - #define JUCE_LOAD_NONE(srcLoad, dstLoad) - #define JUCE_LOAD_DEST(srcLoad, dstLoad) const Mode::ParallelType d = dstLoad (dest); - #define JUCE_LOAD_SRC(srcLoad, dstLoad) const Mode::ParallelType s = srcLoad (src); - #define JUCE_LOAD_SRC1_SRC2(src1Load, src2Load) const Mode::ParallelType s1 = src1Load (src1), s2 = src2Load (src2); - #define JUCE_LOAD_SRC_DEST(srcLoad, dstLoad) const Mode::ParallelType d = dstLoad (dest), s = srcLoad (src); - - #if JUCE_USE_SSE_INTRINSICS || JUCE_USE_ARM_NEON - template struct ModeType { typedef BasicOps32 Mode; }; - template<> struct ModeType<8> { typedef BasicOps64 Mode; }; - - template - struct MinMax - { - typedef typename Mode::Type Type; - typedef typename Mode::ParallelType ParallelType; - - static Type findMinOrMax (const Type* src, int num, const bool isMinimum) noexcept - { - int numLongOps = num / Mode::numParallel; - - #if JUCE_USE_SSE_INTRINSICS - if (numLongOps > 1 && isSSE2Available()) - #else - if (numLongOps > 1) - #endif - { - ParallelType val; - - #if ! JUCE_USE_ARM_NEON - if (isAligned (src)) - { - val = Mode::loadA (src); - - if (isMinimum) - { - while (--numLongOps > 0) - { - src += Mode::numParallel; - val = Mode::min (val, Mode::loadA (src)); - } - } - else - { - while (--numLongOps > 0) - { - src += Mode::numParallel; - val = Mode::max (val, Mode::loadA (src)); - } - } - } - else - #endif - { - val = Mode::loadU (src); - - if (isMinimum) - { - while (--numLongOps > 0) - { - src += Mode::numParallel; - val = Mode::min (val, Mode::loadU (src)); - } - } - else - { - while (--numLongOps > 0) - { - src += Mode::numParallel; - val = Mode::max (val, Mode::loadU (src)); - } - } - } - - Type result = isMinimum ? Mode::min (val) - : Mode::max (val); - - num &= (Mode::numParallel - 1); - src += Mode::numParallel; - - for (int i = 0; i < num; ++i) - result = isMinimum ? jmin (result, src[i]) - : jmax (result, src[i]); - - return result; - } - - return isMinimum ? juce::findMinimum (src, num) - : juce::findMaximum (src, num); - } - - static Range findMinAndMax (const Type* src, int num) noexcept - { - int numLongOps = num / Mode::numParallel; - - #if JUCE_USE_SSE_INTRINSICS - if (numLongOps > 1 && isSSE2Available()) - #else - if (numLongOps > 1) - #endif - { - ParallelType mn, mx; - - #if ! JUCE_USE_ARM_NEON - if (isAligned (src)) - { - mn = Mode::loadA (src); - mx = mn; - - while (--numLongOps > 0) - { - src += Mode::numParallel; - const ParallelType v = Mode::loadA (src); - mn = Mode::min (mn, v); - mx = Mode::max (mx, v); - } - } - else - #endif - { - mn = Mode::loadU (src); - mx = mn; - - while (--numLongOps > 0) - { - src += Mode::numParallel; - const ParallelType v = Mode::loadU (src); - mn = Mode::min (mn, v); - mx = Mode::max (mx, v); - } - } - - Range result (Mode::min (mn), - Mode::max (mx)); - - num &= (Mode::numParallel - 1); - src += Mode::numParallel; - - for (int i = 0; i < num; ++i) - result = result.getUnionWith (src[i]); - - return result; - } - - return Range::findMinAndMax (src, num); - } - }; - #endif -} - -//============================================================================== -void JUCE_CALLTYPE FloatVectorOperations::clear (float* dest, int num) noexcept -{ - #if JUCE_USE_VDSP_FRAMEWORK - vDSP_vclr (dest, 1, (size_t) num); - #else - zeromem (dest, num * sizeof (float)); - #endif -} - -void JUCE_CALLTYPE FloatVectorOperations::clear (double* dest, int num) noexcept -{ - #if JUCE_USE_VDSP_FRAMEWORK - vDSP_vclrD (dest, 1, (size_t) num); - #else - zeromem (dest, num * sizeof (double)); - #endif -} - -void JUCE_CALLTYPE FloatVectorOperations::fill (float* dest, float valueToFill, int num) noexcept -{ - #if JUCE_USE_VDSP_FRAMEWORK - vDSP_vfill (&valueToFill, dest, 1, (size_t) num); - #else - JUCE_PERFORM_VEC_OP_DEST (dest[i] = valueToFill, val, JUCE_LOAD_NONE, - const Mode::ParallelType val = Mode::load1 (valueToFill);) - #endif -} - -void JUCE_CALLTYPE FloatVectorOperations::fill (double* dest, double valueToFill, int num) noexcept -{ - #if JUCE_USE_VDSP_FRAMEWORK - vDSP_vfillD (&valueToFill, dest, 1, (size_t) num); - #else - JUCE_PERFORM_VEC_OP_DEST (dest[i] = valueToFill, val, JUCE_LOAD_NONE, - const Mode::ParallelType val = Mode::load1 (valueToFill);) - #endif -} - -void JUCE_CALLTYPE FloatVectorOperations::copy (float* dest, const float* src, int num) noexcept -{ - memcpy (dest, src, (size_t) num * sizeof (float)); -} - -void JUCE_CALLTYPE FloatVectorOperations::copy (double* dest, const double* src, int num) noexcept -{ - memcpy (dest, src, (size_t) num * sizeof (double)); -} - -void JUCE_CALLTYPE FloatVectorOperations::copyWithMultiply (float* dest, const float* src, float multiplier, int num) noexcept -{ - #if JUCE_USE_VDSP_FRAMEWORK - vDSP_vsmul (src, 1, &multiplier, dest, 1, (vDSP_Length) num); - #else - JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] = src[i] * multiplier, Mode::mul (mult, s), - JUCE_LOAD_SRC, JUCE_INCREMENT_SRC_DEST, - const Mode::ParallelType mult = Mode::load1 (multiplier);) - #endif -} - -void JUCE_CALLTYPE FloatVectorOperations::copyWithMultiply (double* dest, const double* src, double multiplier, int num) noexcept -{ - #if JUCE_USE_VDSP_FRAMEWORK - vDSP_vsmulD (src, 1, &multiplier, dest, 1, (vDSP_Length) num); - #else - JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] = src[i] * multiplier, Mode::mul (mult, s), - JUCE_LOAD_SRC, JUCE_INCREMENT_SRC_DEST, - const Mode::ParallelType mult = Mode::load1 (multiplier);) - #endif -} - -void JUCE_CALLTYPE FloatVectorOperations::add (float* dest, float amount, int num) noexcept -{ - JUCE_PERFORM_VEC_OP_DEST (dest[i] += amount, Mode::add (d, amountToAdd), JUCE_LOAD_DEST, - const Mode::ParallelType amountToAdd = Mode::load1 (amount);) -} - -void JUCE_CALLTYPE FloatVectorOperations::add (double* dest, double amount, int num) noexcept -{ - JUCE_PERFORM_VEC_OP_DEST (dest[i] += amount, Mode::add (d, amountToAdd), JUCE_LOAD_DEST, - const Mode::ParallelType amountToAdd = Mode::load1 (amount);) -} - -void JUCE_CALLTYPE FloatVectorOperations::add (float* dest, float* src, float amount, int num) noexcept -{ - #if JUCE_USE_VDSP_FRAMEWORK - vDSP_vsadd (src, 1, &amount, dest, 1, (vDSP_Length) num); - #else - JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] = src[i] + amount, Mode::add (am, s), - JUCE_LOAD_SRC, JUCE_INCREMENT_SRC_DEST, - const Mode::ParallelType am = Mode::load1 (amount);) - #endif -} - -void JUCE_CALLTYPE FloatVectorOperations::add (double* dest, double* src, double amount, int num) noexcept -{ - #if JUCE_USE_VDSP_FRAMEWORK - vDSP_vsaddD (src, 1, &amount, dest, 1, (vDSP_Length) num); - #else - JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] = src[i] + amount, Mode::add (am, s), - JUCE_LOAD_SRC, JUCE_INCREMENT_SRC_DEST, - const Mode::ParallelType am = Mode::load1 (amount);) - #endif -} - -void JUCE_CALLTYPE FloatVectorOperations::add (float* dest, const float* src, int num) noexcept -{ - #if JUCE_USE_VDSP_FRAMEWORK - vDSP_vadd (src, 1, dest, 1, dest, 1, (vDSP_Length) num); - #else - JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] += src[i], Mode::add (d, s), JUCE_LOAD_SRC_DEST, JUCE_INCREMENT_SRC_DEST, ) - #endif -} - -void JUCE_CALLTYPE FloatVectorOperations::add (double* dest, const double* src, int num) noexcept -{ - #if JUCE_USE_VDSP_FRAMEWORK - vDSP_vaddD (src, 1, dest, 1, dest, 1, (vDSP_Length) num); - #else - JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] += src[i], Mode::add (d, s), JUCE_LOAD_SRC_DEST, JUCE_INCREMENT_SRC_DEST, ) - #endif -} - -void JUCE_CALLTYPE FloatVectorOperations::add (float* dest, const float* src1, const float* src2, int num) noexcept -{ - #if JUCE_USE_VDSP_FRAMEWORK - vDSP_vadd (src1, 1, src2, 1, dest, 1, (vDSP_Length) num); - #else - JUCE_PERFORM_VEC_OP_SRC1_SRC2_DEST (dest[i] = src1[i] + src2[i], Mode::add (s1, s2), JUCE_LOAD_SRC1_SRC2, JUCE_INCREMENT_SRC1_SRC2_DEST, ) - #endif -} - -void JUCE_CALLTYPE FloatVectorOperations::add (double* dest, const double* src1, const double* src2, int num) noexcept -{ - #if JUCE_USE_VDSP_FRAMEWORK - vDSP_vaddD (src1, 1, src2, 1, dest, 1, (vDSP_Length) num); - #else - JUCE_PERFORM_VEC_OP_SRC1_SRC2_DEST (dest[i] = src1[i] + src2[i], Mode::add (s1, s2), JUCE_LOAD_SRC1_SRC2, JUCE_INCREMENT_SRC1_SRC2_DEST, ) - #endif -} - -void JUCE_CALLTYPE FloatVectorOperations::subtract (float* dest, const float* src, int num) noexcept -{ - #if JUCE_USE_VDSP_FRAMEWORK - vDSP_vsub (src, 1, dest, 1, dest, 1, (vDSP_Length) num); - #else - JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] -= src[i], Mode::sub (d, s), JUCE_LOAD_SRC_DEST, JUCE_INCREMENT_SRC_DEST, ) - #endif -} - -void JUCE_CALLTYPE FloatVectorOperations::subtract (double* dest, const double* src, int num) noexcept -{ - #if JUCE_USE_VDSP_FRAMEWORK - vDSP_vsubD (src, 1, dest, 1, dest, 1, (vDSP_Length) num); - #else - JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] -= src[i], Mode::sub (d, s), JUCE_LOAD_SRC_DEST, JUCE_INCREMENT_SRC_DEST, ) - #endif -} - -void JUCE_CALLTYPE FloatVectorOperations::subtract (float* dest, const float* src1, const float* src2, int num) noexcept -{ - #if JUCE_USE_VDSP_FRAMEWORK - vDSP_vsub (src2, 1, src1, 1, dest, 1, (vDSP_Length) num); - #else - JUCE_PERFORM_VEC_OP_SRC1_SRC2_DEST (dest[i] = src1[i] - src2[i], Mode::sub (s1, s2), JUCE_LOAD_SRC1_SRC2, JUCE_INCREMENT_SRC1_SRC2_DEST, ) - #endif -} - -void JUCE_CALLTYPE FloatVectorOperations::subtract (double* dest, const double* src1, const double* src2, int num) noexcept -{ - #if JUCE_USE_VDSP_FRAMEWORK - vDSP_vsubD (src2, 1, src1, 1, dest, 1, (vDSP_Length) num); - #else - JUCE_PERFORM_VEC_OP_SRC1_SRC2_DEST (dest[i] = src1[i] - src2[i], Mode::sub (s1, s2), JUCE_LOAD_SRC1_SRC2, JUCE_INCREMENT_SRC1_SRC2_DEST, ) - #endif -} - -void JUCE_CALLTYPE FloatVectorOperations::addWithMultiply (float* dest, const float* src, float multiplier, int num) noexcept -{ - JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] += src[i] * multiplier, Mode::add (d, Mode::mul (mult, s)), - JUCE_LOAD_SRC_DEST, JUCE_INCREMENT_SRC_DEST, - const Mode::ParallelType mult = Mode::load1 (multiplier);) -} - -void JUCE_CALLTYPE FloatVectorOperations::addWithMultiply (double* dest, const double* src, double multiplier, int num) noexcept -{ - JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] += src[i] * multiplier, Mode::add (d, Mode::mul (mult, s)), - JUCE_LOAD_SRC_DEST, JUCE_INCREMENT_SRC_DEST, - const Mode::ParallelType mult = Mode::load1 (multiplier);) -} - -void JUCE_CALLTYPE FloatVectorOperations::multiply (float* dest, const float* src, int num) noexcept -{ - #if JUCE_USE_VDSP_FRAMEWORK - vDSP_vmul (src, 1, dest, 1, dest, 1, (vDSP_Length) num); - #else - JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] *= src[i], Mode::mul (d, s), JUCE_LOAD_SRC_DEST, JUCE_INCREMENT_SRC_DEST, ) - #endif -} - -void JUCE_CALLTYPE FloatVectorOperations::multiply (double* dest, const double* src, int num) noexcept -{ - #if JUCE_USE_VDSP_FRAMEWORK - vDSP_vmulD (src, 1, dest, 1, dest, 1, (vDSP_Length) num); - #else - JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] *= src[i], Mode::mul (d, s), JUCE_LOAD_SRC_DEST, JUCE_INCREMENT_SRC_DEST, ) - #endif -} - -void JUCE_CALLTYPE FloatVectorOperations::multiply (float* dest, const float* src1, const float* src2, int num) noexcept -{ - #if JUCE_USE_VDSP_FRAMEWORK - vDSP_vmul (src1, 1, src2, 1, dest, 1, (vDSP_Length) num); - #else - JUCE_PERFORM_VEC_OP_SRC1_SRC2_DEST (dest[i] = src1[i] * src2[i], Mode::mul (s1, s2), JUCE_LOAD_SRC1_SRC2, JUCE_INCREMENT_SRC1_SRC2_DEST, ) - #endif -} - -void JUCE_CALLTYPE FloatVectorOperations::multiply (double* dest, const double* src1, const double* src2, int num) noexcept -{ - #if JUCE_USE_VDSP_FRAMEWORK - vDSP_vmulD (src1, 1, src2, 1, dest, 1, (vDSP_Length) num); - #else - JUCE_PERFORM_VEC_OP_SRC1_SRC2_DEST (dest[i] = src1[i] * src2[i], Mode::mul (s1, s2), JUCE_LOAD_SRC1_SRC2, JUCE_INCREMENT_SRC1_SRC2_DEST, ) - #endif -} - -void JUCE_CALLTYPE FloatVectorOperations::multiply (float* dest, float multiplier, int num) noexcept -{ - #if JUCE_USE_VDSP_FRAMEWORK - vDSP_vsmul (dest, 1, &multiplier, dest, 1, (vDSP_Length) num); - #else - JUCE_PERFORM_VEC_OP_DEST (dest[i] *= multiplier, Mode::mul (d, mult), JUCE_LOAD_DEST, - const Mode::ParallelType mult = Mode::load1 (multiplier);) - #endif -} - -void JUCE_CALLTYPE FloatVectorOperations::multiply (double* dest, double multiplier, int num) noexcept -{ - #if JUCE_USE_VDSP_FRAMEWORK - vDSP_vsmulD (dest, 1, &multiplier, dest, 1, (vDSP_Length) num); - #else - JUCE_PERFORM_VEC_OP_DEST (dest[i] *= multiplier, Mode::mul (d, mult), JUCE_LOAD_DEST, - const Mode::ParallelType mult = Mode::load1 (multiplier);) - #endif -} - -void JUCE_CALLTYPE FloatVectorOperations::multiply (float* dest, const float* src, float multiplier, int num) noexcept -{ - JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] = src[i] * multiplier, Mode::mul (mult, s), - JUCE_LOAD_SRC, JUCE_INCREMENT_SRC_DEST, - const Mode::ParallelType mult = Mode::load1 (multiplier);) -} - -void JUCE_CALLTYPE FloatVectorOperations::multiply (double* dest, const double* src, double multiplier, int num) noexcept -{ - JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] = src[i] * multiplier, Mode::mul (mult, s), - JUCE_LOAD_SRC, JUCE_INCREMENT_SRC_DEST, - const Mode::ParallelType mult = Mode::load1 (multiplier);) -} - -void FloatVectorOperations::negate (float* dest, const float* src, int num) noexcept -{ - #if JUCE_USE_VDSP_FRAMEWORK - vDSP_vneg ((float*) src, 1, dest, 1, (vDSP_Length) num); - #else - copyWithMultiply (dest, src, -1.0f, num); - #endif -} - -void FloatVectorOperations::negate (double* dest, const double* src, int num) noexcept -{ - #if JUCE_USE_VDSP_FRAMEWORK - vDSP_vnegD ((double*) src, 1, dest, 1, (vDSP_Length) num); - #else - copyWithMultiply (dest, src, -1.0f, num); - #endif -} - -void JUCE_CALLTYPE FloatVectorOperations::convertFixedToFloat (float* dest, const int* src, float multiplier, int num) noexcept -{ - #if JUCE_USE_ARM_NEON - JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] = src[i] * multiplier, - vmulq_n_f32 (vcvtq_f32_s32 (vld1q_s32 (src)), multiplier), - JUCE_LOAD_NONE, JUCE_INCREMENT_SRC_DEST, ) - #else - JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] = src[i] * multiplier, - Mode::mul (mult, _mm_cvtepi32_ps (_mm_loadu_si128 ((const __m128i*) src))), - JUCE_LOAD_NONE, JUCE_INCREMENT_SRC_DEST, - const Mode::ParallelType mult = Mode::load1 (multiplier);) - #endif -} - -Range JUCE_CALLTYPE FloatVectorOperations::findMinAndMax (const float* src, int num) noexcept -{ - #if JUCE_USE_SSE_INTRINSICS || JUCE_USE_ARM_NEON - return FloatVectorHelpers::MinMax::findMinAndMax (src, num); - #else - return Range::findMinAndMax (src, num); - #endif -} - -Range JUCE_CALLTYPE FloatVectorOperations::findMinAndMax (const double* src, int num) noexcept -{ - #if JUCE_USE_SSE_INTRINSICS || JUCE_USE_ARM_NEON - return FloatVectorHelpers::MinMax::findMinAndMax (src, num); - #else - return Range::findMinAndMax (src, num); - #endif -} - -float JUCE_CALLTYPE FloatVectorOperations::findMinimum (const float* src, int num) noexcept -{ - #if JUCE_USE_SSE_INTRINSICS || JUCE_USE_ARM_NEON - return FloatVectorHelpers::MinMax::findMinOrMax (src, num, true); - #else - return juce::findMinimum (src, num); - #endif -} - -double JUCE_CALLTYPE FloatVectorOperations::findMinimum (const double* src, int num) noexcept -{ - #if JUCE_USE_SSE_INTRINSICS || JUCE_USE_ARM_NEON - return FloatVectorHelpers::MinMax::findMinOrMax (src, num, true); - #else - return juce::findMinimum (src, num); - #endif -} - -float JUCE_CALLTYPE FloatVectorOperations::findMaximum (const float* src, int num) noexcept -{ - #if JUCE_USE_SSE_INTRINSICS || JUCE_USE_ARM_NEON - return FloatVectorHelpers::MinMax::findMinOrMax (src, num, false); - #else - return juce::findMaximum (src, num); - #endif -} - -double JUCE_CALLTYPE FloatVectorOperations::findMaximum (const double* src, int num) noexcept -{ - #if JUCE_USE_SSE_INTRINSICS || JUCE_USE_ARM_NEON - return FloatVectorHelpers::MinMax::findMinOrMax (src, num, false); - #else - return juce::findMaximum (src, num); - #endif -} - -void JUCE_CALLTYPE FloatVectorOperations::enableFlushToZeroMode (bool shouldEnable) noexcept -{ - #if JUCE_USE_SSE_INTRINSICS - if (FloatVectorHelpers::isSSE2Available()) - _MM_SET_FLUSH_ZERO_MODE (shouldEnable ? _MM_FLUSH_ZERO_ON : _MM_FLUSH_ZERO_OFF); - #endif - (void) shouldEnable; -} - -//============================================================================== -//============================================================================== -#if JUCE_UNIT_TESTS - -class FloatVectorOperationsTests : public UnitTest -{ -public: - FloatVectorOperationsTests() : UnitTest ("FloatVectorOperations") {} - - template - struct TestRunner - { - static void runTest (UnitTest& u, Random random) - { - const int range = random.nextBool() ? 500 : 10; - const int num = random.nextInt (range) + 1; - - HeapBlock buffer1 ((size_t) num + 16), buffer2 ((size_t) num + 16); - HeapBlock buffer3 ((size_t) num + 16); - - #if JUCE_ARM - ValueType* const data1 = buffer1; - ValueType* const data2 = buffer2; - int* const int1 = buffer3; - #else - ValueType* const data1 = addBytesToPointer (buffer1.getData(), random.nextInt (16)); - ValueType* const data2 = addBytesToPointer (buffer2.getData(), random.nextInt (16)); - int* const int1 = addBytesToPointer (buffer3.getData(), random.nextInt (16)); - #endif - - fillRandomly (random, data1, num); - fillRandomly (random, data2, num); - - Range minMax1 (FloatVectorOperations::findMinAndMax (data1, num)); - Range minMax2 (Range::findMinAndMax (data1, num)); - u.expect (minMax1 == minMax2); - - u.expect (valuesMatch (FloatVectorOperations::findMinimum (data1, num), juce::findMinimum (data1, num))); - u.expect (valuesMatch (FloatVectorOperations::findMaximum (data1, num), juce::findMaximum (data1, num))); - - u.expect (valuesMatch (FloatVectorOperations::findMinimum (data2, num), juce::findMinimum (data2, num))); - u.expect (valuesMatch (FloatVectorOperations::findMaximum (data2, num), juce::findMaximum (data2, num))); - - FloatVectorOperations::clear (data1, num); - u.expect (areAllValuesEqual (data1, num, 0)); - - FloatVectorOperations::fill (data1, (ValueType) 2, num); - u.expect (areAllValuesEqual (data1, num, (ValueType) 2)); - - FloatVectorOperations::add (data1, (ValueType) 2, num); - u.expect (areAllValuesEqual (data1, num, (ValueType) 4)); - - FloatVectorOperations::copy (data2, data1, num); - u.expect (areAllValuesEqual (data2, num, (ValueType) 4)); - - FloatVectorOperations::add (data2, data1, num); - u.expect (areAllValuesEqual (data2, num, (ValueType) 8)); - - FloatVectorOperations::copyWithMultiply (data2, data1, (ValueType) 4, num); - u.expect (areAllValuesEqual (data2, num, (ValueType) 16)); - - FloatVectorOperations::addWithMultiply (data2, data1, (ValueType) 4, num); - u.expect (areAllValuesEqual (data2, num, (ValueType) 32)); - - FloatVectorOperations::multiply (data1, (ValueType) 2, num); - u.expect (areAllValuesEqual (data1, num, (ValueType) 8)); - - FloatVectorOperations::multiply (data1, data2, num); - u.expect (areAllValuesEqual (data1, num, (ValueType) 256)); - - FloatVectorOperations::negate (data2, data1, num); - u.expect (areAllValuesEqual (data2, num, (ValueType) -256)); - - FloatVectorOperations::subtract (data1, data2, num); - u.expect (areAllValuesEqual (data1, num, (ValueType) 512)); - - fillRandomly (random, int1, num); - doConversionTest (u, data1, data2, int1, num); - } - - static void doConversionTest (UnitTest& u, float* data1, float* data2, int* const int1, int num) - { - FloatVectorOperations::convertFixedToFloat (data1, int1, 2.0f, num); - convertFixed (data2, int1, 2.0f, num); - u.expect (buffersMatch (data1, data2, num)); - } - - static void doConversionTest (UnitTest&, double*, double*, int*, int) {} - - static void fillRandomly (Random& random, ValueType* d, int num) - { - while (--num >= 0) - *d++ = (ValueType) (random.nextDouble() * 1000.0); - } - - static void fillRandomly (Random& random, int* d, int num) - { - while (--num >= 0) - *d++ = random.nextInt(); - } - - static void convertFixed (float* d, const int* s, ValueType multiplier, int num) - { - while (--num >= 0) - *d++ = *s++ * multiplier; - } - - static bool areAllValuesEqual (const ValueType* d, int num, ValueType target) - { - while (--num >= 0) - if (*d++ != target) - return false; - - return true; - } - - static bool buffersMatch (const ValueType* d1, const ValueType* d2, int num) - { - while (--num >= 0) - if (! valuesMatch (*d1++, *d2++)) - return false; - - return true; - } - - static bool valuesMatch (ValueType v1, ValueType v2) - { - return std::abs (v1 - v2) < std::numeric_limits::epsilon(); - } - }; - - void runTest() - { - beginTest ("FloatVectorOperations"); - - for (int i = 1000; --i >= 0;) - { - TestRunner::runTest (*this, getRandom()); - TestRunner::runTest (*this, getRandom()); - } - } -}; - -static FloatVectorOperationsTests vectorOpTests; - -#endif diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/buffers/juce_FloatVectorOperations.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/buffers/juce_FloatVectorOperations.h deleted file mode 100644 index 0b3fcb67c5..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/buffers/juce_FloatVectorOperations.h +++ /dev/null @@ -1,162 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_FLOATVECTOROPERATIONS_H_INCLUDED -#define JUCE_FLOATVECTOROPERATIONS_H_INCLUDED - - -//============================================================================== -/** - A collection of simple vector operations on arrays of floats, accelerated with - SIMD instructions where possible. -*/ -class JUCE_API FloatVectorOperations -{ -public: - //============================================================================== - /** Clears a vector of floats. */ - static void JUCE_CALLTYPE clear (float* dest, int numValues) noexcept; - - /** Clears a vector of doubles. */ - static void JUCE_CALLTYPE clear (double* dest, int numValues) noexcept; - - /** Copies a repeated value into a vector of floats. */ - static void JUCE_CALLTYPE fill (float* dest, float valueToFill, int numValues) noexcept; - - /** Copies a repeated value into a vector of doubles. */ - static void JUCE_CALLTYPE fill (double* dest, double valueToFill, int numValues) noexcept; - - /** Copies a vector of floats. */ - static void JUCE_CALLTYPE copy (float* dest, const float* src, int numValues) noexcept; - - /** Copies a vector of doubles. */ - static void JUCE_CALLTYPE copy (double* dest, const double* src, int numValues) noexcept; - - /** Copies a vector of floats, multiplying each value by a given multiplier */ - static void JUCE_CALLTYPE copyWithMultiply (float* dest, const float* src, float multiplier, int numValues) noexcept; - - /** Copies a vector of doubles, multiplying each value by a given multiplier */ - static void JUCE_CALLTYPE copyWithMultiply (double* dest, const double* src, double multiplier, int numValues) noexcept; - - /** Adds a fixed value to the destination values. */ - static void JUCE_CALLTYPE add (float* dest, float amountToAdd, int numValues) noexcept; - - /** Adds a fixed value to the destination values. */ - static void JUCE_CALLTYPE add (double* dest, double amountToAdd, int numValues) noexcept; - - /** Adds a fixed value to each source value and stores it in the destination array. */ - static void JUCE_CALLTYPE add (float* dest, float* src, float amount, int numValues) noexcept; - - /** Adds a fixed value to each source value and stores it in the destination array. */ - static void JUCE_CALLTYPE add (double* dest, double* src, double amount, int numValues) noexcept; - - /** Adds the source values to the destination values. */ - static void JUCE_CALLTYPE add (float* dest, const float* src, int numValues) noexcept; - - /** Adds the source values to the destination values. */ - static void JUCE_CALLTYPE add (double* dest, const double* src, int numValues) noexcept; - - /** Adds each source1 value to the corresponding source2 value and stores the result in the destination array. */ - static void JUCE_CALLTYPE add (float* dest, const float* src1, const float* src2, int num) noexcept; - - /** Adds each source1 value to the corresponding source2 value and stores the result in the destination array. */ - static void JUCE_CALLTYPE add (double* dest, const double* src1, const double* src2, int num) noexcept; - - /** Subtracts the source values from the destination values. */ - static void JUCE_CALLTYPE subtract (float* dest, const float* src, int numValues) noexcept; - - /** Subtracts the source values from the destination values. */ - static void JUCE_CALLTYPE subtract (double* dest, const double* src, int numValues) noexcept; - - /** Subtracts each source2 value from the corresponding source1 value and stores the result in the destination array. */ - static void JUCE_CALLTYPE subtract (float* dest, const float* src1, const float* src2, int num) noexcept; - - /** Subtracts each source2 value from the corresponding source1 value and stores the result in the destination array. */ - static void JUCE_CALLTYPE subtract (double* dest, const double* src1, const double* src2, int num) noexcept; - - /** Multiplies each source value by the given multiplier, then adds it to the destination value. */ - static void JUCE_CALLTYPE addWithMultiply (float* dest, const float* src, float multiplier, int numValues) noexcept; - - /** Multiplies each source value by the given multiplier, then adds it to the destination value. */ - static void JUCE_CALLTYPE addWithMultiply (double* dest, const double* src, double multiplier, int numValues) noexcept; - - /** Multiplies the destination values by the source values. */ - static void JUCE_CALLTYPE multiply (float* dest, const float* src, int numValues) noexcept; - - /** Multiplies the destination values by the source values. */ - static void JUCE_CALLTYPE multiply (double* dest, const double* src, int numValues) noexcept; - - /** Multiplies each source1 value by the correspinding source2 value, then stores it in the destination array. */ - static void JUCE_CALLTYPE multiply (float* dest, const float* src1, const float* src2, int numValues) noexcept; - - /** Multiplies each source1 value by the correspinding source2 value, then stores it in the destination array. */ - static void JUCE_CALLTYPE multiply (double* dest, const double* src1, const double* src2, int numValues) noexcept; - - /** Multiplies each of the destination values by a fixed multiplier. */ - static void JUCE_CALLTYPE multiply (float* dest, float multiplier, int numValues) noexcept; - - /** Multiplies each of the destination values by a fixed multiplier. */ - static void JUCE_CALLTYPE multiply (double* dest, double multiplier, int numValues) noexcept; - - /** Multiplies each of the source values by a fixed multiplier and stores the result in the destination array. */ - static void JUCE_CALLTYPE multiply (float* dest, const float* src, float multiplier, int num) noexcept; - - /** Multiplies each of the source values by a fixed multiplier and stores the result in the destination array. */ - static void JUCE_CALLTYPE multiply (double* dest, const double* src, double multiplier, int num) noexcept; - - /** Copies a source vector to a destination, negating each value. */ - static void JUCE_CALLTYPE negate (float* dest, const float* src, int numValues) noexcept; - - /** Copies a source vector to a destination, negating each value. */ - static void JUCE_CALLTYPE negate (double* dest, const double* src, int numValues) noexcept; - - /** Converts a stream of integers to floats, multiplying each one by the given multiplier. */ - static void JUCE_CALLTYPE convertFixedToFloat (float* dest, const int* src, float multiplier, int numValues) noexcept; - - /** Finds the miniumum and maximum values in the given array. */ - static Range JUCE_CALLTYPE findMinAndMax (const float* src, int numValues) noexcept; - - /** Finds the miniumum and maximum values in the given array. */ - static Range JUCE_CALLTYPE findMinAndMax (const double* src, int numValues) noexcept; - - /** Finds the miniumum value in the given array. */ - static float JUCE_CALLTYPE findMinimum (const float* src, int numValues) noexcept; - - /** Finds the miniumum value in the given array. */ - static double JUCE_CALLTYPE findMinimum (const double* src, int numValues) noexcept; - - /** Finds the maximum value in the given array. */ - static float JUCE_CALLTYPE findMaximum (const float* src, int numValues) noexcept; - - /** Finds the maximum value in the given array. */ - static double JUCE_CALLTYPE findMaximum (const double* src, int numValues) noexcept; - - /** On Intel CPUs, this method enables or disables the SSE flush-to-zero mode. - Effectively, this is a wrapper around a call to _MM_SET_FLUSH_ZERO_MODE - */ - static void JUCE_CALLTYPE enableFlushToZeroMode (bool shouldEnable) noexcept; -}; - - -#endif // JUCE_FLOATVECTOROPERATIONS_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/effects/juce_Decibels.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/effects/juce_Decibels.h deleted file mode 100644 index c63746ce06..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/effects/juce_Decibels.h +++ /dev/null @@ -1,104 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_DECIBELS_H_INCLUDED -#define JUCE_DECIBELS_H_INCLUDED - - -//============================================================================== -/** - This class contains some helpful static methods for dealing with decibel values. -*/ -class Decibels -{ -public: - //============================================================================== - /** Converts a dBFS value to its equivalent gain level. - - A gain of 1.0 = 0 dB, and lower gains map onto negative decibel values. Any - decibel value lower than minusInfinityDb will return a gain of 0. - */ - template - static Type decibelsToGain (const Type decibels, - const Type minusInfinityDb = (Type) defaultMinusInfinitydB) - { - return decibels > minusInfinityDb ? std::pow ((Type) 10.0, decibels * (Type) 0.05) - : Type(); - } - - /** Converts a gain level into a dBFS value. - - A gain of 1.0 = 0 dB, and lower gains map onto negative decibel values. - If the gain is 0 (or negative), then the method will return the value - provided as minusInfinityDb. - */ - template - static Type gainToDecibels (const Type gain, - const Type minusInfinityDb = (Type) defaultMinusInfinitydB) - { - return gain > Type() ? jmax (minusInfinityDb, (Type) std::log10 (gain) * (Type) 20.0) - : minusInfinityDb; - } - - //============================================================================== - /** Converts a decibel reading to a string, with the 'dB' suffix. - If the decibel value is lower than minusInfinityDb, the return value will - be "-INF dB". - */ - template - static String toString (const Type decibels, - const int decimalPlaces = 2, - const Type minusInfinityDb = (Type) defaultMinusInfinitydB) - { - String s; - - if (decibels <= minusInfinityDb) - { - s = "-INF dB"; - } - else - { - if (decibels >= Type()) - s << '+'; - - s << String (decibels, decimalPlaces) << " dB"; - } - - return s; - } - - -private: - //============================================================================== - enum - { - defaultMinusInfinitydB = -100 - }; - - Decibels(); // This class can't be instantiated, it's just a holder for static methods.. - JUCE_DECLARE_NON_COPYABLE (Decibels) -}; - - -#endif // JUCE_DECIBELS_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/effects/juce_IIRFilter.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/effects/juce_IIRFilter.cpp deleted file mode 100644 index 908a69e0f0..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/effects/juce_IIRFilter.cpp +++ /dev/null @@ -1,244 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#if JUCE_INTEL - #define JUCE_SNAP_TO_ZERO(n) if (! (n < -1.0e-8 || n > 1.0e-8)) n = 0; -#else - #define JUCE_SNAP_TO_ZERO(n) -#endif - -//============================================================================== -IIRCoefficients::IIRCoefficients() noexcept -{ - zeromem (coefficients, sizeof (coefficients)); -} - -IIRCoefficients::~IIRCoefficients() noexcept {} - -IIRCoefficients::IIRCoefficients (const IIRCoefficients& other) noexcept -{ - memcpy (coefficients, other.coefficients, sizeof (coefficients)); -} - -IIRCoefficients& IIRCoefficients::operator= (const IIRCoefficients& other) noexcept -{ - memcpy (coefficients, other.coefficients, sizeof (coefficients)); - return *this; -} - -IIRCoefficients::IIRCoefficients (double c1, double c2, double c3, - double c4, double c5, double c6) noexcept -{ - const double a = 1.0 / c4; - - coefficients[0] = (float) (c1 * a); - coefficients[1] = (float) (c2 * a); - coefficients[2] = (float) (c3 * a); - coefficients[3] = (float) (c5 * a); - coefficients[4] = (float) (c6 * a); -} - -IIRCoefficients IIRCoefficients::makeLowPass (const double sampleRate, - const double frequency) noexcept -{ - jassert (sampleRate > 0); - - const double n = 1.0 / tan (double_Pi * frequency / sampleRate); - const double nSquared = n * n; - const double c1 = 1.0 / (1.0 + std::sqrt (2.0) * n + nSquared); - - return IIRCoefficients (c1, - c1 * 2.0, - c1, - 1.0, - c1 * 2.0 * (1.0 - nSquared), - c1 * (1.0 - std::sqrt (2.0) * n + nSquared)); -} - -IIRCoefficients IIRCoefficients::makeHighPass (const double sampleRate, - const double frequency) noexcept -{ - const double n = tan (double_Pi * frequency / sampleRate); - const double nSquared = n * n; - const double c1 = 1.0 / (1.0 + std::sqrt (2.0) * n + nSquared); - - return IIRCoefficients (c1, - c1 * -2.0, - c1, - 1.0, - c1 * 2.0 * (nSquared - 1.0), - c1 * (1.0 - std::sqrt (2.0) * n + nSquared)); -} - -IIRCoefficients IIRCoefficients::makeLowShelf (const double sampleRate, - const double cutOffFrequency, - const double Q, - const float gainFactor) noexcept -{ - jassert (sampleRate > 0); - jassert (Q > 0); - - const double A = jmax (0.0f, std::sqrt (gainFactor)); - const double aminus1 = A - 1.0; - const double aplus1 = A + 1.0; - const double omega = (double_Pi * 2.0 * jmax (cutOffFrequency, 2.0)) / sampleRate; - const double coso = std::cos (omega); - const double beta = std::sin (omega) * std::sqrt (A) / Q; - const double aminus1TimesCoso = aminus1 * coso; - - return IIRCoefficients (A * (aplus1 - aminus1TimesCoso + beta), - A * 2.0 * (aminus1 - aplus1 * coso), - A * (aplus1 - aminus1TimesCoso - beta), - aplus1 + aminus1TimesCoso + beta, - -2.0 * (aminus1 + aplus1 * coso), - aplus1 + aminus1TimesCoso - beta); -} - -IIRCoefficients IIRCoefficients::makeHighShelf (const double sampleRate, - const double cutOffFrequency, - const double Q, - const float gainFactor) noexcept -{ - jassert (sampleRate > 0); - jassert (Q > 0); - - const double A = jmax (0.0f, std::sqrt (gainFactor)); - const double aminus1 = A - 1.0; - const double aplus1 = A + 1.0; - const double omega = (double_Pi * 2.0 * jmax (cutOffFrequency, 2.0)) / sampleRate; - const double coso = std::cos (omega); - const double beta = std::sin (omega) * std::sqrt (A) / Q; - const double aminus1TimesCoso = aminus1 * coso; - - return IIRCoefficients (A * (aplus1 + aminus1TimesCoso + beta), - A * -2.0 * (aminus1 + aplus1 * coso), - A * (aplus1 + aminus1TimesCoso - beta), - aplus1 - aminus1TimesCoso + beta, - 2.0 * (aminus1 - aplus1 * coso), - aplus1 - aminus1TimesCoso - beta); -} - -IIRCoefficients IIRCoefficients::makePeakFilter (const double sampleRate, - const double centreFrequency, - const double Q, - const float gainFactor) noexcept -{ - jassert (sampleRate > 0); - jassert (Q > 0); - - const double A = jmax (0.0f, std::sqrt (gainFactor)); - const double omega = (double_Pi * 2.0 * jmax (centreFrequency, 2.0)) / sampleRate; - const double alpha = 0.5 * std::sin (omega) / Q; - const double c2 = -2.0 * std::cos (omega); - const double alphaTimesA = alpha * A; - const double alphaOverA = alpha / A; - - return IIRCoefficients (1.0 + alphaTimesA, - c2, - 1.0 - alphaTimesA, - 1.0 + alphaOverA, - c2, - 1.0 - alphaOverA); -} - -//============================================================================== -IIRFilter::IIRFilter() noexcept - : v1 (0), v2 (0), active (false) -{ -} - -IIRFilter::IIRFilter (const IIRFilter& other) noexcept - : v1 (0), v2 (0), active (other.active) -{ - const SpinLock::ScopedLockType sl (other.processLock); - coefficients = other.coefficients; -} - -IIRFilter::~IIRFilter() noexcept -{ -} - -//============================================================================== -void IIRFilter::makeInactive() noexcept -{ - const SpinLock::ScopedLockType sl (processLock); - active = false; -} - -void IIRFilter::setCoefficients (const IIRCoefficients& newCoefficients) noexcept -{ - const SpinLock::ScopedLockType sl (processLock); - - coefficients = newCoefficients; - active = true; -} - -//============================================================================== -void IIRFilter::reset() noexcept -{ - const SpinLock::ScopedLockType sl (processLock); - v1 = v2 = 0; -} - -float IIRFilter::processSingleSampleRaw (const float in) noexcept -{ - float out = coefficients.coefficients[0] * in + v1; - - JUCE_SNAP_TO_ZERO (out); - - v1 = coefficients.coefficients[1] * in - coefficients.coefficients[3] * out + v2; - v2 = coefficients.coefficients[2] * in - coefficients.coefficients[4] * out; - - return out; -} - -void IIRFilter::processSamples (float* const samples, const int numSamples) noexcept -{ - const SpinLock::ScopedLockType sl (processLock); - - if (active) - { - const float c0 = coefficients.coefficients[0]; - const float c1 = coefficients.coefficients[1]; - const float c2 = coefficients.coefficients[2]; - const float c3 = coefficients.coefficients[3]; - const float c4 = coefficients.coefficients[4]; - float lv1 = v1, lv2 = v2; - - for (int i = 0; i < numSamples; ++i) - { - const float in = samples[i]; - const float out = c0 * in + lv1; - samples[i] = out; - - lv1 = c1 * in - c3 * out + lv2; - lv2 = c2 * in - c4 * out; - } - - JUCE_SNAP_TO_ZERO (lv1); v1 = lv1; - JUCE_SNAP_TO_ZERO (lv2); v2 = lv2; - } -} - -#undef JUCE_SNAP_TO_ZERO diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/effects/juce_IIRFilter.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/effects/juce_IIRFilter.h deleted file mode 100644 index 8269cf5825..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/effects/juce_IIRFilter.h +++ /dev/null @@ -1,174 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_IIRFILTER_H_INCLUDED -#define JUCE_IIRFILTER_H_INCLUDED - -class IIRFilter; - -//============================================================================== -/** - A set of coefficients for use in an IIRFilter object. - - @see IIRFilter -*/ -class JUCE_API IIRCoefficients -{ -public: - //============================================================================== - /** Creates a null set of coefficients (which will produce silence). */ - IIRCoefficients() noexcept; - - /** Directly constructs an object from the raw coefficients. - Most people will want to use the static methods instead of this, but - the constructor is public to allow tinkerers to create their own custom - filters! - */ - IIRCoefficients (double c1, double c2, double c3, - double c4, double c5, double c6) noexcept; - - /** Creates a copy of another filter. */ - IIRCoefficients (const IIRCoefficients&) noexcept; - /** Creates a copy of another filter. */ - IIRCoefficients& operator= (const IIRCoefficients&) noexcept; - /** Destructor. */ - ~IIRCoefficients() noexcept; - - /** Returns the coefficients for a low-pass filter. */ - static IIRCoefficients makeLowPass (double sampleRate, - double frequency) noexcept; - - /** Returns the coefficients for a high-pass filter. */ - static IIRCoefficients makeHighPass (double sampleRate, - double frequency) noexcept; - - //============================================================================== - /** Returns the coefficients for a low-pass shelf filter with variable Q and gain. - - The gain is a scale factor that the low frequencies are multiplied by, so values - greater than 1.0 will boost the low frequencies, values less than 1.0 will - attenuate them. - */ - static IIRCoefficients makeLowShelf (double sampleRate, - double cutOffFrequency, - double Q, - float gainFactor) noexcept; - - /** Returns the coefficients for a high-pass shelf filter with variable Q and gain. - - The gain is a scale factor that the high frequencies are multiplied by, so values - greater than 1.0 will boost the high frequencies, values less than 1.0 will - attenuate them. - */ - static IIRCoefficients makeHighShelf (double sampleRate, - double cutOffFrequency, - double Q, - float gainFactor) noexcept; - - /** Returns the coefficients for a peak filter centred around a - given frequency, with a variable Q and gain. - - The gain is a scale factor that the centre frequencies are multiplied by, so - values greater than 1.0 will boost the centre frequencies, values less than - 1.0 will attenuate them. - */ - static IIRCoefficients makePeakFilter (double sampleRate, - double centreFrequency, - double Q, - float gainFactor) noexcept; - - //============================================================================== - /** The raw coefficients. - You should leave these numbers alone unless you really know what you're doing. - */ - float coefficients[5]; -}; - -//============================================================================== -/** - An IIR filter that can perform low, high, or band-pass filtering on an - audio signal. - - @see IIRCoefficient, IIRFilterAudioSource -*/ -class JUCE_API IIRFilter -{ -public: - //============================================================================== - /** Creates a filter. - - Initially the filter is inactive, so will have no effect on samples that - you process with it. Use the setCoefficients() method to turn it into the - type of filter needed. - */ - IIRFilter() noexcept; - - /** Creates a copy of another filter. */ - IIRFilter (const IIRFilter&) noexcept; - - /** Destructor. */ - ~IIRFilter() noexcept; - - //============================================================================== - /** Clears the filter so that any incoming data passes through unchanged. */ - void makeInactive() noexcept; - - /** Applies a set of coefficients to this filter. */ - void setCoefficients (const IIRCoefficients& newCoefficients) noexcept; - - /** Returns the coefficients that this filter is using. */ - IIRCoefficients getCoefficients() const noexcept { return coefficients; } - - //============================================================================== - /** Resets the filter's processing pipeline, ready to start a new stream of data. - - Note that this clears the processing state, but the type of filter and - its coefficients aren't changed. To put a filter into an inactive state, use - the makeInactive() method. - */ - void reset() noexcept; - - /** Performs the filter operation on the given set of samples. */ - void processSamples (float* samples, int numSamples) noexcept; - - /** Processes a single sample, without any locking or checking. - - Use this if you need fast processing of a single value, but be aware that - this isn't thread-safe in the way that processSamples() is. - */ - float processSingleSampleRaw (float sample) noexcept; - -protected: - //============================================================================== - SpinLock processLock; - IIRCoefficients coefficients; - float v1, v2; - bool active; - - IIRFilter& operator= (const IIRFilter&); - JUCE_LEAK_DETECTOR (IIRFilter) -}; - - -#endif // JUCE_IIRFILTER_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/effects/juce_LagrangeInterpolator.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/effects/juce_LagrangeInterpolator.cpp deleted file mode 100644 index 7bab3a576f..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/effects/juce_LagrangeInterpolator.cpp +++ /dev/null @@ -1,200 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -namespace LagrangeHelpers -{ - template - struct ResampleHelper - { - static forcedinline void calc (float& a, float b) { a *= b * (1.0f / k); } - }; - - template<> - struct ResampleHelper <0> - { - static forcedinline void calc (float&, float) {} - }; - - template - static forcedinline float calcCoefficient (float input, const float offset) noexcept - { - ResampleHelper <0 - k>::calc (input, -2.0f - offset); - ResampleHelper <1 - k>::calc (input, -1.0f - offset); - ResampleHelper <2 - k>::calc (input, 0.0f - offset); - ResampleHelper <3 - k>::calc (input, 1.0f - offset); - ResampleHelper <4 - k>::calc (input, 2.0f - offset); - return input; - } - - static forcedinline float valueAtOffset (const float* const inputs, const float offset) noexcept - { - return calcCoefficient<0> (inputs[4], offset) - + calcCoefficient<1> (inputs[3], offset) - + calcCoefficient<2> (inputs[2], offset) - + calcCoefficient<3> (inputs[1], offset) - + calcCoefficient<4> (inputs[0], offset); - } - - static forcedinline void push (float* inputs, const float newValue) noexcept - { - inputs[4] = inputs[3]; - inputs[3] = inputs[2]; - inputs[2] = inputs[1]; - inputs[1] = inputs[0]; - inputs[0] = newValue; - } -} - -//============================================================================== -LagrangeInterpolator::LagrangeInterpolator() { reset(); } -LagrangeInterpolator::~LagrangeInterpolator() {} - -void LagrangeInterpolator::reset() noexcept -{ - subSamplePos = 1.0; - - for (int i = 0; i < numElementsInArray (lastInputSamples); ++i) - lastInputSamples[i] = 0; -} - -int LagrangeInterpolator::process (const double actualRatio, const float* in, - float* out, const int numOut) noexcept -{ - if (actualRatio == 1.0) - { - memcpy (out, in, (size_t) numOut * sizeof (float)); - - if (numOut >= 4) - { - memcpy (lastInputSamples, in + (numOut - 4), 4 * sizeof (float)); - } - else - { - for (int i = 0; i < numOut; ++i) - LagrangeHelpers::push (lastInputSamples, in[i]); - } - - return numOut; - } - - const float* const originalIn = in; - double pos = subSamplePos; - - if (actualRatio < 1.0) - { - for (int i = numOut; --i >= 0;) - { - if (pos >= 1.0) - { - LagrangeHelpers::push (lastInputSamples, *in++); - pos -= 1.0; - } - - *out++ = LagrangeHelpers::valueAtOffset (lastInputSamples, (float) pos); - pos += actualRatio; - } - } - else - { - for (int i = numOut; --i >= 0;) - { - while (pos < actualRatio) - { - LagrangeHelpers::push (lastInputSamples, *in++); - pos += 1.0; - } - - pos -= actualRatio; - *out++ = LagrangeHelpers::valueAtOffset (lastInputSamples, 1.0f - (float) pos); - } - } - - subSamplePos = pos; - return (int) (in - originalIn); -} - -int LagrangeInterpolator::processAdding (const double actualRatio, const float* in, - float* out, const int numOut, const float gain) noexcept -{ - if (actualRatio == 1.0) - { - if (gain != 1.0f) - { - for (int i = 0; i < numOut; ++i) - out[i] += in[i] * gain; - } - else - { - for (int i = 0; i < numOut; ++i) - out[i] += in[i]; - } - - if (numOut >= 4) - { - memcpy (lastInputSamples, in + (numOut - 4), 4 * sizeof (float)); - } - else - { - for (int i = 0; i < numOut; ++i) - LagrangeHelpers::push (lastInputSamples, in[i]); - } - - return numOut; - } - - const float* const originalIn = in; - double pos = subSamplePos; - - if (actualRatio < 1.0) - { - for (int i = numOut; --i >= 0;) - { - if (pos >= 1.0) - { - LagrangeHelpers::push (lastInputSamples, *in++); - pos -= 1.0; - } - - *out++ += gain * LagrangeHelpers::valueAtOffset (lastInputSamples, (float) pos); - pos += actualRatio; - } - } - else - { - for (int i = numOut; --i >= 0;) - { - while (pos < actualRatio) - { - LagrangeHelpers::push (lastInputSamples, *in++); - pos += 1.0; - } - - pos -= actualRatio; - *out++ += gain * LagrangeHelpers::valueAtOffset (lastInputSamples, jmax (0.0f, 1.0f - (float) pos)); - } - } - - subSamplePos = pos; - return (int) (in - originalIn); -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/effects/juce_LagrangeInterpolator.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/effects/juce_LagrangeInterpolator.h deleted file mode 100644 index caa4802ecf..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/effects/juce_LagrangeInterpolator.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_LAGRANGEINTERPOLATOR_H_INCLUDED -#define JUCE_LAGRANGEINTERPOLATOR_H_INCLUDED - - -//============================================================================== -/** - Interpolator for resampling a stream of floats using 4-point lagrange interpolation. - - Note that the resampler is stateful, so when there's a break in the continuity - of the input stream you're feeding it, you should call reset() before feeding - it any new data. And like with any other stateful filter, if you're resampling - multiple channels, make sure each one uses its own LagrangeInterpolator - object. -*/ -class JUCE_API LagrangeInterpolator -{ -public: - LagrangeInterpolator(); - ~LagrangeInterpolator(); - - /** Resets the state of the interpolator. - Call this when there's a break in the continuity of the input data stream. - */ - void reset() noexcept; - - /** Resamples a stream of samples. - - @param speedRatio the number of input samples to use for each output sample - @param inputSamples the source data to read from. This must contain at - least (speedRatio * numOutputSamplesToProduce) samples. - @param outputSamples the buffer to write the results into - @param numOutputSamplesToProduce the number of output samples that should be created - - @returns the actual number of input samples that were used - */ - int process (double speedRatio, - const float* inputSamples, - float* outputSamples, - int numOutputSamplesToProduce) noexcept; - - /** Resamples a stream of samples, adding the results to the output data - with a gain. - - @param speedRatio the number of input samples to use for each output sample - @param inputSamples the source data to read from. This must contain at - least (speedRatio * numOutputSamplesToProduce) samples. - @param outputSamples the buffer to write the results to - the result values will be added - to any pre-existing data in this buffer after being multiplied by - the gain factor - @param numOutputSamplesToProduce the number of output samples that should be created - @param gain a gain factor to multiply the resulting samples by before - adding them to the destination buffer - - @returns the actual number of input samples that were used - */ - int processAdding (double speedRatio, - const float* inputSamples, - float* outputSamples, - int numOutputSamplesToProduce, - float gain) noexcept; - -private: - float lastInputSamples[5]; - double subSamplePos; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (LagrangeInterpolator) -}; - - -#endif // JUCE_LAGRANGEINTERPOLATOR_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/effects/juce_Reverb.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/effects/juce_Reverb.h deleted file mode 100644 index 53457a60b5..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/effects/juce_Reverb.h +++ /dev/null @@ -1,323 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_REVERB_H_INCLUDED -#define JUCE_REVERB_H_INCLUDED - - -//============================================================================== -/** - Performs a simple reverb effect on a stream of audio data. - - This is a simple stereo reverb, based on the technique and tunings used in FreeVerb. - Use setSampleRate() to prepare it, and then call processStereo() or processMono() to - apply the reverb to your audio data. - - @see ReverbAudioSource -*/ -class Reverb -{ -public: - //============================================================================== - Reverb() - { - setParameters (Parameters()); - setSampleRate (44100.0); - } - - //============================================================================== - /** Holds the parameters being used by a Reverb object. */ - struct Parameters - { - Parameters() noexcept - : roomSize (0.5f), - damping (0.5f), - wetLevel (0.33f), - dryLevel (0.4f), - width (1.0f), - freezeMode (0) - {} - - float roomSize; /**< Room size, 0 to 1.0, where 1.0 is big, 0 is small. */ - float damping; /**< Damping, 0 to 1.0, where 0 is not damped, 1.0 is fully damped. */ - float wetLevel; /**< Wet level, 0 to 1.0 */ - float dryLevel; /**< Dry level, 0 to 1.0 */ - float width; /**< Reverb width, 0 to 1.0, where 1.0 is very wide. */ - float freezeMode; /**< Freeze mode - values < 0.5 are "normal" mode, values > 0.5 - put the reverb into a continuous feedback loop. */ - }; - - //============================================================================== - /** Returns the reverb's current parameters. */ - const Parameters& getParameters() const noexcept { return parameters; } - - /** Applies a new set of parameters to the reverb. - Note that this doesn't attempt to lock the reverb, so if you call this in parallel with - the process method, you may get artifacts. - */ - void setParameters (const Parameters& newParams) - { - const float wetScaleFactor = 3.0f; - const float dryScaleFactor = 2.0f; - - const float wet = newParams.wetLevel * wetScaleFactor; - wet1 = wet * (newParams.width * 0.5f + 0.5f); - wet2 = wet * (1.0f - newParams.width) * 0.5f; - dry = newParams.dryLevel * dryScaleFactor; - gain = isFrozen (newParams.freezeMode) ? 0.0f : 0.015f; - parameters = newParams; - shouldUpdateDamping = true; - } - - //============================================================================== - /** Sets the sample rate that will be used for the reverb. - You must call this before the process methods, in order to tell it the correct sample rate. - */ - void setSampleRate (const double sampleRate) - { - jassert (sampleRate > 0); - - static const short combTunings[] = { 1116, 1188, 1277, 1356, 1422, 1491, 1557, 1617 }; // (at 44100Hz) - static const short allPassTunings[] = { 556, 441, 341, 225 }; - const int stereoSpread = 23; - const int intSampleRate = (int) sampleRate; - - for (int i = 0; i < numCombs; ++i) - { - comb[0][i].setSize ((intSampleRate * combTunings[i]) / 44100); - comb[1][i].setSize ((intSampleRate * (combTunings[i] + stereoSpread)) / 44100); - } - - for (int i = 0; i < numAllPasses; ++i) - { - allPass[0][i].setSize ((intSampleRate * allPassTunings[i]) / 44100); - allPass[1][i].setSize ((intSampleRate * (allPassTunings[i] + stereoSpread)) / 44100); - } - - shouldUpdateDamping = true; - } - - /** Clears the reverb's buffers. */ - void reset() - { - for (int j = 0; j < numChannels; ++j) - { - for (int i = 0; i < numCombs; ++i) - comb[j][i].clear(); - - for (int i = 0; i < numAllPasses; ++i) - allPass[j][i].clear(); - } - } - - //============================================================================== - /** Applies the reverb to two stereo channels of audio data. */ - void processStereo (float* const left, float* const right, const int numSamples) noexcept - { - jassert (left != nullptr && right != nullptr); - - if (shouldUpdateDamping) - updateDamping(); - - for (int i = 0; i < numSamples; ++i) - { - const float input = (left[i] + right[i]) * gain; - float outL = 0, outR = 0; - - for (int j = 0; j < numCombs; ++j) // accumulate the comb filters in parallel - { - outL += comb[0][j].process (input); - outR += comb[1][j].process (input); - } - - for (int j = 0; j < numAllPasses; ++j) // run the allpass filters in series - { - outL = allPass[0][j].process (outL); - outR = allPass[1][j].process (outR); - } - - left[i] = outL * wet1 + outR * wet2 + left[i] * dry; - right[i] = outR * wet1 + outL * wet2 + right[i] * dry; - } - } - - /** Applies the reverb to a single mono channel of audio data. */ - void processMono (float* const samples, const int numSamples) noexcept - { - jassert (samples != nullptr); - - if (shouldUpdateDamping) - updateDamping(); - - for (int i = 0; i < numSamples; ++i) - { - const float input = samples[i] * gain; - float output = 0; - - for (int j = 0; j < numCombs; ++j) // accumulate the comb filters in parallel - output += comb[0][j].process (input); - - for (int j = 0; j < numAllPasses; ++j) // run the allpass filters in series - output = allPass[0][j].process (output); - - samples[i] = output * wet1 + samples[i] * dry; - } - } - -private: - //============================================================================== - Parameters parameters; - - volatile bool shouldUpdateDamping; - float gain, wet1, wet2, dry; - - inline static bool isFrozen (const float freezeMode) noexcept { return freezeMode >= 0.5f; } - - void updateDamping() noexcept - { - const float roomScaleFactor = 0.28f; - const float roomOffset = 0.7f; - const float dampScaleFactor = 0.4f; - - shouldUpdateDamping = false; - - if (isFrozen (parameters.freezeMode)) - setDamping (0.0f, 1.0f); - else - setDamping (parameters.damping * dampScaleFactor, - parameters.roomSize * roomScaleFactor + roomOffset); - } - - void setDamping (const float dampingToUse, const float roomSizeToUse) noexcept - { - for (int j = 0; j < numChannels; ++j) - for (int i = numCombs; --i >= 0;) - comb[j][i].setFeedbackAndDamp (roomSizeToUse, dampingToUse); - } - - //============================================================================== - class CombFilter - { - public: - CombFilter() noexcept - : bufferSize (0), bufferIndex (0), - feedback (0), last (0), damp1 (0), damp2 (0) - {} - - void setSize (const int size) - { - if (size != bufferSize) - { - bufferIndex = 0; - buffer.malloc ((size_t) size); - bufferSize = size; - } - - clear(); - } - - void clear() noexcept - { - last = 0; - buffer.clear ((size_t) bufferSize); - } - - void setFeedbackAndDamp (const float f, const float d) noexcept - { - damp1 = d; - damp2 = 1.0f - d; - feedback = f; - } - - inline float process (const float input) noexcept - { - const float output = buffer [bufferIndex]; - last = (output * damp2) + (last * damp1); - JUCE_UNDENORMALISE (last); - - float temp = input + (last * feedback); - JUCE_UNDENORMALISE (temp); - buffer [bufferIndex] = temp; - bufferIndex = (bufferIndex + 1) % bufferSize; - return output; - } - - private: - HeapBlock buffer; - int bufferSize, bufferIndex; - float feedback, last, damp1, damp2; - - JUCE_DECLARE_NON_COPYABLE (CombFilter) - }; - - //============================================================================== - class AllPassFilter - { - public: - AllPassFilter() noexcept : bufferSize (0), bufferIndex (0) {} - - void setSize (const int size) - { - if (size != bufferSize) - { - bufferIndex = 0; - buffer.malloc ((size_t) size); - bufferSize = size; - } - - clear(); - } - - void clear() noexcept - { - buffer.clear ((size_t) bufferSize); - } - - inline float process (const float input) noexcept - { - const float bufferedValue = buffer [bufferIndex]; - float temp = input + (bufferedValue * 0.5f); - JUCE_UNDENORMALISE (temp); - buffer [bufferIndex] = temp; - bufferIndex = (bufferIndex + 1) % bufferSize; - return bufferedValue - input; - } - - private: - HeapBlock buffer; - int bufferSize, bufferIndex; - - JUCE_DECLARE_NON_COPYABLE (AllPassFilter) - }; - - enum { numCombs = 8, numAllPasses = 4, numChannels = 2 }; - - CombFilter comb [numChannels][numCombs]; - AllPassFilter allPass [numChannels][numAllPasses]; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Reverb) -}; - - -#endif // JUCE_REVERB_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/juce_audio_basics.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/juce_audio_basics.cpp deleted file mode 100644 index da9865900e..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/juce_audio_basics.cpp +++ /dev/null @@ -1,94 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#if defined (JUCE_AUDIO_BASICS_H_INCLUDED) && ! JUCE_AMALGAMATED_INCLUDE - /* When you add this cpp file to your project, you mustn't include it in a file where you've - already included any other headers - just put it inside a file on its own, possibly with your config - flags preceding it, but don't include anything else. That also includes avoiding any automatic prefix - header files that the compiler may be using. - */ - #error "Incorrect use of JUCE cpp file" -#endif - -// Your project must contain an AppConfig.h file with your project-specific settings in it, -// and your header search path must make it accessible to the module's files. -#include "AppConfig.h" -#include "juce_audio_basics.h" - -#if JUCE_MINGW && ! defined (__SSE2__) - #define JUCE_USE_SSE_INTRINSICS 0 -#endif - -#ifndef JUCE_USE_SSE_INTRINSICS - #define JUCE_USE_SSE_INTRINSICS 1 -#endif - -#if ! JUCE_INTEL - #undef JUCE_USE_SSE_INTRINSICS -#endif - -#if JUCE_USE_SSE_INTRINSICS - #include -#endif - -#ifndef JUCE_USE_VDSP_FRAMEWORK - #define JUCE_USE_VDSP_FRAMEWORK 1 -#endif - -#if (JUCE_MAC || JUCE_IOS) && JUCE_USE_VDSP_FRAMEWORK - #define Point CarbonDummyPointName // (workaround to avoid definition of "Point" by old Carbon headers) - #include - #undef Point -#else - #undef JUCE_USE_VDSP_FRAMEWORK -#endif - -#if __ARM_NEON__ && ! (JUCE_USE_VDSP_FRAMEWORK || defined (JUCE_USE_ARM_NEON)) - #define JUCE_USE_ARM_NEON 1 - #include -#endif - -namespace juce -{ - -#include "buffers/juce_AudioDataConverters.cpp" -#include "buffers/juce_AudioSampleBuffer.cpp" -#include "buffers/juce_FloatVectorOperations.cpp" -#include "effects/juce_IIRFilter.cpp" -#include "effects/juce_LagrangeInterpolator.cpp" -#include "midi/juce_MidiBuffer.cpp" -#include "midi/juce_MidiFile.cpp" -#include "midi/juce_MidiKeyboardState.cpp" -#include "midi/juce_MidiMessage.cpp" -#include "midi/juce_MidiMessageSequence.cpp" -#include "sources/juce_BufferingAudioSource.cpp" -#include "sources/juce_ChannelRemappingAudioSource.cpp" -#include "sources/juce_IIRFilterAudioSource.cpp" -#include "sources/juce_MixerAudioSource.cpp" -#include "sources/juce_ResamplingAudioSource.cpp" -#include "sources/juce_ReverbAudioSource.cpp" -#include "sources/juce_ToneGeneratorAudioSource.cpp" -#include "synthesisers/juce_Synthesiser.cpp" - -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/juce_audio_basics.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/juce_audio_basics.h index 70c5432a7b..b9a775c861 100644 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/juce_audio_basics.h +++ b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/juce_audio_basics.h @@ -1,59 +1,5 @@ -/* - ============================================================================== +// This is an auto-generated file to redirect any included +// module headers to the correct external folder. - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. +#include "../../../../../modules/juce_audio_basics/juce_audio_basics.h" - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_AUDIO_BASICS_H_INCLUDED -#define JUCE_AUDIO_BASICS_H_INCLUDED - -#include "../juce_core/juce_core.h" - -//============================================================================= -namespace juce -{ - -#include "buffers/juce_AudioDataConverters.h" -#include "buffers/juce_AudioSampleBuffer.h" -#include "buffers/juce_FloatVectorOperations.h" -#include "effects/juce_Decibels.h" -#include "effects/juce_IIRFilter.h" -#include "effects/juce_LagrangeInterpolator.h" -#include "effects/juce_Reverb.h" -#include "midi/juce_MidiMessage.h" -#include "midi/juce_MidiBuffer.h" -#include "midi/juce_MidiMessageSequence.h" -#include "midi/juce_MidiFile.h" -#include "midi/juce_MidiKeyboardState.h" -#include "sources/juce_AudioSource.h" -#include "sources/juce_PositionableAudioSource.h" -#include "sources/juce_BufferingAudioSource.h" -#include "sources/juce_ChannelRemappingAudioSource.h" -#include "sources/juce_IIRFilterAudioSource.h" -#include "sources/juce_MixerAudioSource.h" -#include "sources/juce_ResamplingAudioSource.h" -#include "sources/juce_ReverbAudioSource.h" -#include "sources/juce_ToneGeneratorAudioSource.h" -#include "synthesisers/juce_Synthesiser.h" - -} - -#endif // JUCE_AUDIO_BASICS_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/juce_audio_basics.mm b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/juce_audio_basics.mm deleted file mode 100644 index 54083fdaac..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/juce_audio_basics.mm +++ /dev/null @@ -1,25 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#include "juce_audio_basics.cpp" diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/juce_module_info b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/juce_module_info deleted file mode 100644 index c9cdd3d979..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/juce_module_info +++ /dev/null @@ -1,24 +0,0 @@ -{ - "id": "juce_audio_basics", - "name": "JUCE audio and midi data classes", - "version": "3.0.8", - "description": "Classes for audio buffer manipulation, midi message handling, synthesis, etc", - "website": "http://www.juce.com/juce", - "license": "GPL/Commercial", - - "dependencies": [ { "id": "juce_core", "version": "matching" } ], - - "include": "juce_audio_basics.h", - - "compile": [ { "file": "juce_audio_basics.cpp", "target": "! xcode" }, - { "file": "juce_audio_basics.mm", "target": "xcode" } ], - - "browse": [ "buffers/*", - "midi/*", - "effects/*", - "sources/*", - "synthesisers/*" ], - - "OSXFrameworks": "Accelerate", - "iOSFrameworks": "Accelerate" -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/midi/juce_MidiBuffer.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/midi/juce_MidiBuffer.cpp deleted file mode 100644 index 43ab4c175f..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/midi/juce_MidiBuffer.cpp +++ /dev/null @@ -1,229 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -namespace MidiBufferHelpers -{ - inline int getEventTime (const void* const d) noexcept - { - return *static_cast (d); - } - - inline uint16 getEventDataSize (const void* const d) noexcept - { - return *reinterpret_cast (static_cast (d) + sizeof (int32)); - } - - inline uint16 getEventTotalSize (const void* const d) noexcept - { - return getEventDataSize (d) + sizeof (int32) + sizeof (uint16); - } - - static int findActualEventLength (const uint8* const data, const int maxBytes) noexcept - { - unsigned int byte = (unsigned int) *data; - int size = 0; - - if (byte == 0xf0 || byte == 0xf7) - { - const uint8* d = data + 1; - - while (d < data + maxBytes) - if (*d++ == 0xf7) - break; - - size = (int) (d - data); - } - else if (byte == 0xff) - { - int n; - const int bytesLeft = MidiMessage::readVariableLengthVal (data + 1, n); - size = jmin (maxBytes, n + 2 + bytesLeft); - } - else if (byte >= 0x80) - { - size = jmin (maxBytes, MidiMessage::getMessageLengthFromFirstByte ((uint8) byte)); - } - - return size; - } - - static uint8* findEventAfter (uint8* d, uint8* endData, const int samplePosition) noexcept - { - while (d < endData && getEventTime (d) <= samplePosition) - d += getEventTotalSize (d); - - return d; - } -} - -//============================================================================== -MidiBuffer::MidiBuffer() noexcept {} -MidiBuffer::~MidiBuffer() {} - -MidiBuffer::MidiBuffer (const MidiBuffer& other) noexcept : data (other.data) {} - -MidiBuffer& MidiBuffer::operator= (const MidiBuffer& other) noexcept -{ - data = other.data; - return *this; -} - -MidiBuffer::MidiBuffer (const MidiMessage& message) noexcept -{ - addEvent (message, 0); -} - -void MidiBuffer::swapWith (MidiBuffer& other) noexcept { data.swapWith (other.data); } -void MidiBuffer::clear() noexcept { data.clearQuick(); } -void MidiBuffer::ensureSize (size_t minimumNumBytes) { data.ensureStorageAllocated ((int) minimumNumBytes); } -bool MidiBuffer::isEmpty() const noexcept { return data.size() == 0; } - -void MidiBuffer::clear (const int startSample, const int numSamples) -{ - uint8* const start = MidiBufferHelpers::findEventAfter (data.begin(), data.end(), startSample - 1); - uint8* const end = MidiBufferHelpers::findEventAfter (start, data.end(), startSample + numSamples - 1); - - data.removeRange ((int) (start - data.begin()), (int) (end - data.begin())); -} - -void MidiBuffer::addEvent (const MidiMessage& m, const int sampleNumber) -{ - addEvent (m.getRawData(), m.getRawDataSize(), sampleNumber); -} - -void MidiBuffer::addEvent (const void* const newData, const int maxBytes, const int sampleNumber) -{ - const int numBytes = MidiBufferHelpers::findActualEventLength (static_cast (newData), maxBytes); - - if (numBytes > 0) - { - const size_t newItemSize = (size_t) numBytes + sizeof (int32) + sizeof (uint16); - const int offset = (int) (MidiBufferHelpers::findEventAfter (data.begin(), data.end(), sampleNumber) - data.begin()); - - data.insertMultiple (offset, 0, (int) newItemSize); - - uint8* const d = data.begin() + offset; - *reinterpret_cast (d) = sampleNumber; - *reinterpret_cast (d + 4) = (uint16) numBytes; - memcpy (d + 6, newData, (size_t) numBytes); - } -} - -void MidiBuffer::addEvents (const MidiBuffer& otherBuffer, - const int startSample, - const int numSamples, - const int sampleDeltaToAdd) -{ - Iterator i (otherBuffer); - i.setNextSamplePosition (startSample); - - const uint8* eventData; - int eventSize, position; - - while (i.getNextEvent (eventData, eventSize, position) - && (position < startSample + numSamples || numSamples < 0)) - { - addEvent (eventData, eventSize, position + sampleDeltaToAdd); - } -} - -int MidiBuffer::getNumEvents() const noexcept -{ - int n = 0; - const uint8* const end = data.end(); - - for (const uint8* d = data.begin(); d < end; ++n) - d += MidiBufferHelpers::getEventTotalSize (d); - - return n; -} - -int MidiBuffer::getFirstEventTime() const noexcept -{ - return data.size() > 0 ? MidiBufferHelpers::getEventTime (data.begin()) : 0; -} - -int MidiBuffer::getLastEventTime() const noexcept -{ - if (data.size() == 0) - return 0; - - const uint8* const endData = data.end(); - - for (const uint8* d = data.begin();;) - { - const uint8* const nextOne = d + MidiBufferHelpers::getEventTotalSize (d); - - if (nextOne >= endData) - return MidiBufferHelpers::getEventTime (d); - - d = nextOne; - } -} - -//============================================================================== -MidiBuffer::Iterator::Iterator (const MidiBuffer& b) noexcept - : buffer (b), data (b.data.begin()) -{ -} - -MidiBuffer::Iterator::~Iterator() noexcept -{ -} - -void MidiBuffer::Iterator::setNextSamplePosition (const int samplePosition) noexcept -{ - data = buffer.data.begin(); - const uint8* const dataEnd = buffer.data.end(); - - while (data < dataEnd && MidiBufferHelpers::getEventTime (data) < samplePosition) - data += MidiBufferHelpers::getEventTotalSize (data); -} - -bool MidiBuffer::Iterator::getNextEvent (const uint8* &midiData, int& numBytes, int& samplePosition) noexcept -{ - if (data >= buffer.data.end()) - return false; - - samplePosition = MidiBufferHelpers::getEventTime (data); - const int itemSize = MidiBufferHelpers::getEventDataSize (data); - numBytes = itemSize; - midiData = data + sizeof (int32) + sizeof (uint16); - data += sizeof (int32) + sizeof (uint16) + (size_t) itemSize; - - return true; -} - -bool MidiBuffer::Iterator::getNextEvent (MidiMessage& result, int& samplePosition) noexcept -{ - if (data >= buffer.data.end()) - return false; - - samplePosition = MidiBufferHelpers::getEventTime (data); - const int itemSize = MidiBufferHelpers::getEventDataSize (data); - result = MidiMessage (data + sizeof (int32) + sizeof (uint16), itemSize, samplePosition); - data += sizeof (int32) + sizeof (uint16) + (size_t) itemSize; - - return true; -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/midi/juce_MidiBuffer.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/midi/juce_MidiBuffer.h deleted file mode 100644 index ecbc56a212..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/midi/juce_MidiBuffer.h +++ /dev/null @@ -1,235 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_MIDIBUFFER_H_INCLUDED -#define JUCE_MIDIBUFFER_H_INCLUDED - - -//============================================================================== -/** - Holds a sequence of time-stamped midi events. - - Analogous to the AudioSampleBuffer, this holds a set of midi events with - integer time-stamps. The buffer is kept sorted in order of the time-stamps. - - If you're working with a sequence of midi events that may need to be manipulated - or read/written to a midi file, then MidiMessageSequence is probably a more - appropriate container. MidiBuffer is designed for lower-level streams of raw - midi data. - - @see MidiMessage -*/ -class JUCE_API MidiBuffer -{ -public: - //============================================================================== - /** Creates an empty MidiBuffer. */ - MidiBuffer() noexcept; - - /** Creates a MidiBuffer containing a single midi message. */ - explicit MidiBuffer (const MidiMessage& message) noexcept; - - /** Creates a copy of another MidiBuffer. */ - MidiBuffer (const MidiBuffer&) noexcept; - - /** Makes a copy of another MidiBuffer. */ - MidiBuffer& operator= (const MidiBuffer&) noexcept; - - /** Destructor */ - ~MidiBuffer(); - - //============================================================================== - /** Removes all events from the buffer. */ - void clear() noexcept; - - /** Removes all events between two times from the buffer. - - All events for which (start <= event position < start + numSamples) will - be removed. - */ - void clear (int start, int numSamples); - - /** Returns true if the buffer is empty. - To actually retrieve the events, use a MidiBuffer::Iterator object - */ - bool isEmpty() const noexcept; - - /** Counts the number of events in the buffer. - - This is actually quite a slow operation, as it has to iterate through all - the events, so you might prefer to call isEmpty() if that's all you need - to know. - */ - int getNumEvents() const noexcept; - - /** Adds an event to the buffer. - - The sample number will be used to determine the position of the event in - the buffer, which is always kept sorted. The MidiMessage's timestamp is - ignored. - - If an event is added whose sample position is the same as one or more events - already in the buffer, the new event will be placed after the existing ones. - - To retrieve events, use a MidiBuffer::Iterator object - */ - void addEvent (const MidiMessage& midiMessage, int sampleNumber); - - /** Adds an event to the buffer from raw midi data. - - The sample number will be used to determine the position of the event in - the buffer, which is always kept sorted. - - If an event is added whose sample position is the same as one or more events - already in the buffer, the new event will be placed after the existing ones. - - The event data will be inspected to calculate the number of bytes in length that - the midi event really takes up, so maxBytesOfMidiData may be longer than the data - that actually gets stored. E.g. if you pass in a note-on and a length of 4 bytes, - it'll actually only store 3 bytes. If the midi data is invalid, it might not - add an event at all. - - To retrieve events, use a MidiBuffer::Iterator object - */ - void addEvent (const void* rawMidiData, - int maxBytesOfMidiData, - int sampleNumber); - - /** Adds some events from another buffer to this one. - - @param otherBuffer the buffer containing the events you want to add - @param startSample the lowest sample number in the source buffer for which - events should be added. Any source events whose timestamp is - less than this will be ignored - @param numSamples the valid range of samples from the source buffer for which - events should be added - i.e. events in the source buffer whose - timestamp is greater than or equal to (startSample + numSamples) - will be ignored. If this value is less than 0, all events after - startSample will be taken. - @param sampleDeltaToAdd a value which will be added to the source timestamps of the events - that are added to this buffer - */ - void addEvents (const MidiBuffer& otherBuffer, - int startSample, - int numSamples, - int sampleDeltaToAdd); - - /** Returns the sample number of the first event in the buffer. - If the buffer's empty, this will just return 0. - */ - int getFirstEventTime() const noexcept; - - /** Returns the sample number of the last event in the buffer. - If the buffer's empty, this will just return 0. - */ - int getLastEventTime() const noexcept; - - //============================================================================== - /** Exchanges the contents of this buffer with another one. - - This is a quick operation, because no memory allocating or copying is done, it - just swaps the internal state of the two buffers. - */ - void swapWith (MidiBuffer&) noexcept; - - /** Preallocates some memory for the buffer to use. - This helps to avoid needing to reallocate space when the buffer has messages - added to it. - */ - void ensureSize (size_t minimumNumBytes); - - //============================================================================== - /** - Used to iterate through the events in a MidiBuffer. - - Note that altering the buffer while an iterator is using it isn't a - safe operation. - - @see MidiBuffer - */ - class JUCE_API Iterator - { - public: - //============================================================================== - /** Creates an Iterator for this MidiBuffer. */ - Iterator (const MidiBuffer&) noexcept; - - /** Destructor. */ - ~Iterator() noexcept; - - //============================================================================== - /** Repositions the iterator so that the next event retrieved will be the first - one whose sample position is at greater than or equal to the given position. - */ - void setNextSamplePosition (int samplePosition) noexcept; - - /** Retrieves a copy of the next event from the buffer. - - @param result on return, this will be the message. The MidiMessage's timestamp - is set to the same value as samplePosition. - @param samplePosition on return, this will be the position of the event, as a - sample index in the buffer - @returns true if an event was found, or false if the iterator has reached - the end of the buffer - */ - bool getNextEvent (MidiMessage& result, - int& samplePosition) noexcept; - - /** Retrieves the next event from the buffer. - - @param midiData on return, this pointer will be set to a block of data containing - the midi message. Note that to make it fast, this is a pointer - directly into the MidiBuffer's internal data, so is only valid - temporarily until the MidiBuffer is altered. - @param numBytesOfMidiData on return, this is the number of bytes of data used by the - midi message - @param samplePosition on return, this will be the position of the event, as a - sample index in the buffer - @returns true if an event was found, or false if the iterator has reached - the end of the buffer - */ - bool getNextEvent (const uint8* &midiData, - int& numBytesOfMidiData, - int& samplePosition) noexcept; - - private: - //============================================================================== - const MidiBuffer& buffer; - const uint8* data; - - JUCE_DECLARE_NON_COPYABLE (Iterator) - }; - - /** The raw data holding this buffer. - Obviously access to this data is provided at your own risk. Its internal format could - change in future, so don't write code that relies on it! - */ - Array data; - -private: - JUCE_LEAK_DETECTOR (MidiBuffer) -}; - - -#endif // JUCE_MIDIBUFFER_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/midi/juce_MidiFile.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/midi/juce_MidiFile.cpp deleted file mode 100644 index e798cc0c6c..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/midi/juce_MidiFile.cpp +++ /dev/null @@ -1,428 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -namespace MidiFileHelpers -{ - static void writeVariableLengthInt (OutputStream& out, unsigned int v) - { - unsigned int buffer = v & 0x7f; - - while ((v >>= 7) != 0) - { - buffer <<= 8; - buffer |= ((v & 0x7f) | 0x80); - } - - for (;;) - { - out.writeByte ((char) buffer); - - if (buffer & 0x80) - buffer >>= 8; - else - break; - } - } - - static bool parseMidiHeader (const uint8* &data, short& timeFormat, short& fileType, short& numberOfTracks) noexcept - { - unsigned int ch = ByteOrder::bigEndianInt (data); - data += 4; - - if (ch != ByteOrder::bigEndianInt ("MThd")) - { - bool ok = false; - - if (ch == ByteOrder::bigEndianInt ("RIFF")) - { - for (int i = 0; i < 8; ++i) - { - ch = ByteOrder::bigEndianInt (data); - data += 4; - - if (ch == ByteOrder::bigEndianInt ("MThd")) - { - ok = true; - break; - } - } - } - - if (! ok) - return false; - } - - unsigned int bytesRemaining = ByteOrder::bigEndianInt (data); - data += 4; - fileType = (short) ByteOrder::bigEndianShort (data); - data += 2; - numberOfTracks = (short) ByteOrder::bigEndianShort (data); - data += 2; - timeFormat = (short) ByteOrder::bigEndianShort (data); - data += 2; - bytesRemaining -= 6; - data += bytesRemaining; - - return true; - } - - static double convertTicksToSeconds (const double time, - const MidiMessageSequence& tempoEvents, - const int timeFormat) - { - if (timeFormat < 0) - return time / (-(timeFormat >> 8) * (timeFormat & 0xff)); - - double lastTime = 0.0, correctedTime = 0.0; - const double tickLen = 1.0 / (timeFormat & 0x7fff); - double secsPerTick = 0.5 * tickLen; - const int numEvents = tempoEvents.getNumEvents(); - - for (int i = 0; i < numEvents; ++i) - { - const MidiMessage& m = tempoEvents.getEventPointer(i)->message; - const double eventTime = m.getTimeStamp(); - - if (eventTime >= time) - break; - - correctedTime += (eventTime - lastTime) * secsPerTick; - lastTime = eventTime; - - if (m.isTempoMetaEvent()) - secsPerTick = tickLen * m.getTempoSecondsPerQuarterNote(); - - while (i + 1 < numEvents) - { - const MidiMessage& m2 = tempoEvents.getEventPointer(i + 1)->message; - - if (m2.getTimeStamp() != eventTime) - break; - - if (m2.isTempoMetaEvent()) - secsPerTick = tickLen * m2.getTempoSecondsPerQuarterNote(); - - ++i; - } - } - - return correctedTime + (time - lastTime) * secsPerTick; - } - - // a comparator that puts all the note-offs before note-ons that have the same time - struct Sorter - { - static int compareElements (const MidiMessageSequence::MidiEventHolder* const first, - const MidiMessageSequence::MidiEventHolder* const second) noexcept - { - const double diff = (first->message.getTimeStamp() - second->message.getTimeStamp()); - - if (diff > 0) return 1; - if (diff < 0) return -1; - if (first->message.isNoteOff() && second->message.isNoteOn()) return -1; - if (first->message.isNoteOn() && second->message.isNoteOff()) return 1; - - return 0; - } - }; - - template - static void findAllMatchingEvents (const OwnedArray& tracks, - MidiMessageSequence& results, - MethodType method) - { - for (int i = 0; i < tracks.size(); ++i) - { - const MidiMessageSequence& track = *tracks.getUnchecked(i); - const int numEvents = track.getNumEvents(); - - for (int j = 0; j < numEvents; ++j) - { - const MidiMessage& m = track.getEventPointer(j)->message; - - if ((m.*method)()) - results.addEvent (m); - } - } - } -} - -//============================================================================== -MidiFile::MidiFile() - : timeFormat ((short) (unsigned short) 0xe728) -{ -} - -MidiFile::~MidiFile() -{ -} - -void MidiFile::clear() -{ - tracks.clear(); -} - -//============================================================================== -int MidiFile::getNumTracks() const noexcept -{ - return tracks.size(); -} - -const MidiMessageSequence* MidiFile::getTrack (const int index) const noexcept -{ - return tracks [index]; -} - -void MidiFile::addTrack (const MidiMessageSequence& trackSequence) -{ - tracks.add (new MidiMessageSequence (trackSequence)); -} - -//============================================================================== -short MidiFile::getTimeFormat() const noexcept -{ - return timeFormat; -} - -void MidiFile::setTicksPerQuarterNote (const int ticks) noexcept -{ - timeFormat = (short) ticks; -} - -void MidiFile::setSmpteTimeFormat (const int framesPerSecond, - const int subframeResolution) noexcept -{ - timeFormat = (short) (((-framesPerSecond) << 8) | subframeResolution); -} - -//============================================================================== -void MidiFile::findAllTempoEvents (MidiMessageSequence& results) const -{ - MidiFileHelpers::findAllMatchingEvents (tracks, results, &MidiMessage::isTempoMetaEvent); -} - -void MidiFile::findAllTimeSigEvents (MidiMessageSequence& results) const -{ - MidiFileHelpers::findAllMatchingEvents (tracks, results, &MidiMessage::isTimeSignatureMetaEvent); -} - -void MidiFile::findAllKeySigEvents (MidiMessageSequence& results) const -{ - MidiFileHelpers::findAllMatchingEvents (tracks, results, &MidiMessage::isKeySignatureMetaEvent); -} - -double MidiFile::getLastTimestamp() const -{ - double t = 0.0; - - for (int i = tracks.size(); --i >= 0;) - t = jmax (t, tracks.getUnchecked(i)->getEndTime()); - - return t; -} - -//============================================================================== -bool MidiFile::readFrom (InputStream& sourceStream) -{ - clear(); - MemoryBlock data; - - const int maxSensibleMidiFileSize = 2 * 1024 * 1024; - - // (put a sanity-check on the file size, as midi files are generally small) - if (sourceStream.readIntoMemoryBlock (data, maxSensibleMidiFileSize)) - { - size_t size = data.getSize(); - const uint8* d = static_cast (data.getData()); - short fileType, expectedTracks; - - if (size > 16 && MidiFileHelpers::parseMidiHeader (d, timeFormat, fileType, expectedTracks)) - { - size -= (size_t) (d - static_cast (data.getData())); - - int track = 0; - - while (size > 0 && track < expectedTracks) - { - const int chunkType = (int) ByteOrder::bigEndianInt (d); - d += 4; - const int chunkSize = (int) ByteOrder::bigEndianInt (d); - d += 4; - - if (chunkSize <= 0) - break; - - if (chunkType == (int) ByteOrder::bigEndianInt ("MTrk")) - readNextTrack (d, chunkSize); - - size -= (size_t) chunkSize + 8; - d += chunkSize; - ++track; - } - - return true; - } - } - - return false; -} - -void MidiFile::readNextTrack (const uint8* data, int size) -{ - double time = 0; - uint8 lastStatusByte = 0; - - MidiMessageSequence result; - - while (size > 0) - { - int bytesUsed; - const int delay = MidiMessage::readVariableLengthVal (data, bytesUsed); - data += bytesUsed; - size -= bytesUsed; - time += delay; - - int messSize = 0; - const MidiMessage mm (data, size, messSize, lastStatusByte, time); - - if (messSize <= 0) - break; - - size -= messSize; - data += messSize; - - result.addEvent (mm); - - const uint8 firstByte = *(mm.getRawData()); - if ((firstByte & 0xf0) != 0xf0) - lastStatusByte = firstByte; - } - - // use a sort that puts all the note-offs before note-ons that have the same time - MidiFileHelpers::Sorter sorter; - result.list.sort (sorter, true); - - addTrack (result); - tracks.getLast()->updateMatchedPairs(); -} - -//============================================================================== -void MidiFile::convertTimestampTicksToSeconds() -{ - MidiMessageSequence tempoEvents; - findAllTempoEvents (tempoEvents); - findAllTimeSigEvents (tempoEvents); - - if (timeFormat != 0) - { - for (int i = 0; i < tracks.size(); ++i) - { - const MidiMessageSequence& ms = *tracks.getUnchecked(i); - - for (int j = ms.getNumEvents(); --j >= 0;) - { - MidiMessage& m = ms.getEventPointer(j)->message; - m.setTimeStamp (MidiFileHelpers::convertTicksToSeconds (m.getTimeStamp(), tempoEvents, timeFormat)); - } - } - } -} - -//============================================================================== -bool MidiFile::writeTo (OutputStream& out, int midiFileType) -{ - jassert (midiFileType >= 0 && midiFileType <= 2); - - out.writeIntBigEndian ((int) ByteOrder::bigEndianInt ("MThd")); - out.writeIntBigEndian (6); - out.writeShortBigEndian ((short) midiFileType); - out.writeShortBigEndian ((short) tracks.size()); - out.writeShortBigEndian (timeFormat); - - for (int i = 0; i < tracks.size(); ++i) - writeTrack (out, i); - - out.flush(); - return true; -} - -void MidiFile::writeTrack (OutputStream& mainOut, const int trackNum) -{ - MemoryOutputStream out; - const MidiMessageSequence& ms = *tracks.getUnchecked (trackNum); - - int lastTick = 0; - uint8 lastStatusByte = 0; - bool endOfTrackEventWritten = false; - - for (int i = 0; i < ms.getNumEvents(); ++i) - { - const MidiMessage& mm = ms.getEventPointer(i)->message; - - if (mm.isEndOfTrackMetaEvent()) - endOfTrackEventWritten = true; - - const int tick = roundToInt (mm.getTimeStamp()); - const int delta = jmax (0, tick - lastTick); - MidiFileHelpers::writeVariableLengthInt (out, (uint32) delta); - lastTick = tick; - - const uint8* data = mm.getRawData(); - int dataSize = mm.getRawDataSize(); - - const uint8 statusByte = data[0]; - - if (statusByte == lastStatusByte - && (statusByte & 0xf0) != 0xf0 - && dataSize > 1 - && i > 0) - { - ++data; - --dataSize; - } - else if (statusByte == 0xf0) // Write sysex message with length bytes. - { - out.writeByte ((char) statusByte); - - ++data; - --dataSize; - - MidiFileHelpers::writeVariableLengthInt (out, (uint32) dataSize); - } - - out.write (data, (size_t) dataSize); - lastStatusByte = statusByte; - } - - if (! endOfTrackEventWritten) - { - out.writeByte (0); // (tick delta) - const MidiMessage m (MidiMessage::endOfTrack()); - out.write (m.getRawData(), (size_t) m.getRawDataSize()); - } - - mainOut.writeIntBigEndian ((int) ByteOrder::bigEndianInt ("MTrk")); - mainOut.writeIntBigEndian ((int) out.getDataSize()); - mainOut << out; -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/midi/juce_MidiFile.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/midi/juce_MidiFile.h deleted file mode 100644 index 2a69937143..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/midi/juce_MidiFile.h +++ /dev/null @@ -1,180 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_MIDIFILE_H_INCLUDED -#define JUCE_MIDIFILE_H_INCLUDED - - -//============================================================================== -/** - Reads/writes standard midi format files. - - To read a midi file, create a MidiFile object and call its readFrom() method. You - can then get the individual midi tracks from it using the getTrack() method. - - To write a file, create a MidiFile object, add some MidiMessageSequence objects - to it using the addTrack() method, and then call its writeTo() method to stream - it out. - - @see MidiMessageSequence -*/ -class JUCE_API MidiFile -{ -public: - //============================================================================== - /** Creates an empty MidiFile object. - */ - MidiFile(); - - /** Destructor. */ - ~MidiFile(); - - //============================================================================== - /** Returns the number of tracks in the file. - @see getTrack, addTrack - */ - int getNumTracks() const noexcept; - - /** Returns a pointer to one of the tracks in the file. - @returns a pointer to the track, or nullptr if the index is out-of-range - @see getNumTracks, addTrack - */ - const MidiMessageSequence* getTrack (int index) const noexcept; - - /** Adds a midi track to the file. - This will make its own internal copy of the sequence that is passed-in. - @see getNumTracks, getTrack - */ - void addTrack (const MidiMessageSequence& trackSequence); - - /** Removes all midi tracks from the file. - @see getNumTracks - */ - void clear(); - - /** Returns the raw time format code that will be written to a stream. - - After reading a midi file, this method will return the time-format that - was read from the file's header. It can be changed using the setTicksPerQuarterNote() - or setSmpteTimeFormat() methods. - - If the value returned is positive, it indicates the number of midi ticks - per quarter-note - see setTicksPerQuarterNote(). - - It it's negative, the upper byte indicates the frames-per-second (but negative), and - the lower byte is the number of ticks per frame - see setSmpteTimeFormat(). - */ - short getTimeFormat() const noexcept; - - /** Sets the time format to use when this file is written to a stream. - - If this is called, the file will be written as bars/beats using the - specified resolution, rather than SMPTE absolute times, as would be - used if setSmpteTimeFormat() had been called instead. - - @param ticksPerQuarterNote e.g. 96, 960 - @see setSmpteTimeFormat - */ - void setTicksPerQuarterNote (int ticksPerQuarterNote) noexcept; - - /** Sets the time format to use when this file is written to a stream. - - If this is called, the file will be written using absolute times, rather - than bars/beats as would be the case if setTicksPerBeat() had been called - instead. - - @param framesPerSecond must be 24, 25, 29 or 30 - @param subframeResolution the sub-second resolution, e.g. 4 (midi time code), - 8, 10, 80 (SMPTE bit resolution), or 100. For millisecond - timing, setSmpteTimeFormat (25, 40) - @see setTicksPerBeat - */ - void setSmpteTimeFormat (int framesPerSecond, - int subframeResolution) noexcept; - - //============================================================================== - /** Makes a list of all the tempo-change meta-events from all tracks in the midi file. - Useful for finding the positions of all the tempo changes in a file. - @param tempoChangeEvents a list to which all the events will be added - */ - void findAllTempoEvents (MidiMessageSequence& tempoChangeEvents) const; - - /** Makes a list of all the time-signature meta-events from all tracks in the midi file. - Useful for finding the positions of all the tempo changes in a file. - @param timeSigEvents a list to which all the events will be added - */ - void findAllTimeSigEvents (MidiMessageSequence& timeSigEvents) const; - - /** Makes a list of all the time-signature meta-events from all tracks in the midi file. - @param keySigEvents a list to which all the events will be added - */ - void findAllKeySigEvents (MidiMessageSequence& keySigEvents) const; - - /** Returns the latest timestamp in any of the tracks. - (Useful for finding the length of the file). - */ - double getLastTimestamp() const; - - //============================================================================== - /** Reads a midi file format stream. - - After calling this, you can get the tracks that were read from the file by using the - getNumTracks() and getTrack() methods. - - The timestamps of the midi events in the tracks will represent their positions in - terms of midi ticks. To convert them to seconds, use the convertTimestampTicksToSeconds() - method. - - @returns true if the stream was read successfully - */ - bool readFrom (InputStream& sourceStream); - - /** Writes the midi tracks as a standard midi file. - The midiFileType value is written as the file's format type, which can be 0, 1 - or 2 - see the midi file spec for more info about that. - @returns true if the operation succeeded. - */ - bool writeTo (OutputStream& destStream, int midiFileType = 1); - - /** Converts the timestamp of all the midi events from midi ticks to seconds. - - This will use the midi time format and tempo/time signature info in the - tracks to convert all the timestamps to absolute values in seconds. - */ - void convertTimestampTicksToSeconds(); - - -private: - //============================================================================== - OwnedArray tracks; - short timeFormat; - - void readNextTrack (const uint8*, int size); - void writeTrack (OutputStream&, int trackNum); - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MidiFile) -}; - - -#endif // JUCE_MIDIFILE_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/midi/juce_MidiKeyboardState.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/midi/juce_MidiKeyboardState.cpp deleted file mode 100644 index a40262b37d..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/midi/juce_MidiKeyboardState.cpp +++ /dev/null @@ -1,183 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -MidiKeyboardState::MidiKeyboardState() -{ - zerostruct (noteStates); -} - -MidiKeyboardState::~MidiKeyboardState() -{ -} - -//============================================================================== -void MidiKeyboardState::reset() -{ - const ScopedLock sl (lock); - zerostruct (noteStates); - eventsToAdd.clear(); -} - -bool MidiKeyboardState::isNoteOn (const int midiChannel, const int n) const noexcept -{ - jassert (midiChannel >= 0 && midiChannel <= 16); - - return isPositiveAndBelow (n, (int) 128) - && (noteStates[n] & (1 << (midiChannel - 1))) != 0; -} - -bool MidiKeyboardState::isNoteOnForChannels (const int midiChannelMask, const int n) const noexcept -{ - return isPositiveAndBelow (n, (int) 128) - && (noteStates[n] & midiChannelMask) != 0; -} - -void MidiKeyboardState::noteOn (const int midiChannel, const int midiNoteNumber, const float velocity) -{ - jassert (midiChannel >= 0 && midiChannel <= 16); - jassert (isPositiveAndBelow (midiNoteNumber, (int) 128)); - - const ScopedLock sl (lock); - - if (isPositiveAndBelow (midiNoteNumber, (int) 128)) - { - const int timeNow = (int) Time::getMillisecondCounter(); - eventsToAdd.addEvent (MidiMessage::noteOn (midiChannel, midiNoteNumber, velocity), timeNow); - eventsToAdd.clear (0, timeNow - 500); - - noteOnInternal (midiChannel, midiNoteNumber, velocity); - } -} - -void MidiKeyboardState::noteOnInternal (const int midiChannel, const int midiNoteNumber, const float velocity) -{ - if (isPositiveAndBelow (midiNoteNumber, (int) 128)) - { - noteStates [midiNoteNumber] |= (1 << (midiChannel - 1)); - - for (int i = listeners.size(); --i >= 0;) - listeners.getUnchecked(i)->handleNoteOn (this, midiChannel, midiNoteNumber, velocity); - } -} - -void MidiKeyboardState::noteOff (const int midiChannel, const int midiNoteNumber) -{ - const ScopedLock sl (lock); - - if (isNoteOn (midiChannel, midiNoteNumber)) - { - const int timeNow = (int) Time::getMillisecondCounter(); - eventsToAdd.addEvent (MidiMessage::noteOff (midiChannel, midiNoteNumber), timeNow); - eventsToAdd.clear (0, timeNow - 500); - - noteOffInternal (midiChannel, midiNoteNumber); - } -} - -void MidiKeyboardState::noteOffInternal (const int midiChannel, const int midiNoteNumber) -{ - if (isNoteOn (midiChannel, midiNoteNumber)) - { - noteStates [midiNoteNumber] &= ~(1 << (midiChannel - 1)); - - for (int i = listeners.size(); --i >= 0;) - listeners.getUnchecked(i)->handleNoteOff (this, midiChannel, midiNoteNumber); - } -} - -void MidiKeyboardState::allNotesOff (const int midiChannel) -{ - const ScopedLock sl (lock); - - if (midiChannel <= 0) - { - for (int i = 1; i <= 16; ++i) - allNotesOff (i); - } - else - { - for (int i = 0; i < 128; ++i) - noteOff (midiChannel, i); - } -} - -void MidiKeyboardState::processNextMidiEvent (const MidiMessage& message) -{ - if (message.isNoteOn()) - { - noteOnInternal (message.getChannel(), message.getNoteNumber(), message.getFloatVelocity()); - } - else if (message.isNoteOff()) - { - noteOffInternal (message.getChannel(), message.getNoteNumber()); - } - else if (message.isAllNotesOff()) - { - for (int i = 0; i < 128; ++i) - noteOffInternal (message.getChannel(), i); - } -} - -void MidiKeyboardState::processNextMidiBuffer (MidiBuffer& buffer, - const int startSample, - const int numSamples, - const bool injectIndirectEvents) -{ - MidiBuffer::Iterator i (buffer); - MidiMessage message (0xf4, 0.0); - int time; - - const ScopedLock sl (lock); - - while (i.getNextEvent (message, time)) - processNextMidiEvent (message); - - if (injectIndirectEvents) - { - MidiBuffer::Iterator i2 (eventsToAdd); - const int firstEventToAdd = eventsToAdd.getFirstEventTime(); - const double scaleFactor = numSamples / (double) (eventsToAdd.getLastEventTime() + 1 - firstEventToAdd); - - while (i2.getNextEvent (message, time)) - { - const int pos = jlimit (0, numSamples - 1, roundToInt ((time - firstEventToAdd) * scaleFactor)); - buffer.addEvent (message, startSample + pos); - } - } - - eventsToAdd.clear(); -} - -//============================================================================== -void MidiKeyboardState::addListener (MidiKeyboardStateListener* const listener) -{ - const ScopedLock sl (lock); - listeners.addIfNotAlreadyThere (listener); -} - -void MidiKeyboardState::removeListener (MidiKeyboardStateListener* const listener) -{ - const ScopedLock sl (lock); - listeners.removeFirstMatchingValue (listener); -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/midi/juce_MidiKeyboardState.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/midi/juce_MidiKeyboardState.h deleted file mode 100644 index 885b7d88f9..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/midi/juce_MidiKeyboardState.h +++ /dev/null @@ -1,205 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_MIDIKEYBOARDSTATE_H_INCLUDED -#define JUCE_MIDIKEYBOARDSTATE_H_INCLUDED - -class MidiKeyboardState; - - -//============================================================================== -/** - Receives events from a MidiKeyboardState object. - - @see MidiKeyboardState -*/ -class JUCE_API MidiKeyboardStateListener -{ -public: - //============================================================================== - MidiKeyboardStateListener() noexcept {} - virtual ~MidiKeyboardStateListener() {} - - //============================================================================== - /** Called when one of the MidiKeyboardState's keys is pressed. - - This will be called synchronously when the state is either processing a - buffer in its MidiKeyboardState::processNextMidiBuffer() method, or - when a note is being played with its MidiKeyboardState::noteOn() method. - - Note that this callback could happen from an audio callback thread, so be - careful not to block, and avoid any UI activity in the callback. - */ - virtual void handleNoteOn (MidiKeyboardState* source, - int midiChannel, int midiNoteNumber, float velocity) = 0; - - /** Called when one of the MidiKeyboardState's keys is released. - - This will be called synchronously when the state is either processing a - buffer in its MidiKeyboardState::processNextMidiBuffer() method, or - when a note is being played with its MidiKeyboardState::noteOff() method. - - Note that this callback could happen from an audio callback thread, so be - careful not to block, and avoid any UI activity in the callback. - */ - virtual void handleNoteOff (MidiKeyboardState* source, - int midiChannel, int midiNoteNumber) = 0; -}; - - -//============================================================================== -/** - Represents a piano keyboard, keeping track of which keys are currently pressed. - - This object can parse a stream of midi events, using them to update its idea - of which keys are pressed for each individiual midi channel. - - When keys go up or down, it can broadcast these events to listener objects. - - It also allows key up/down events to be triggered with its noteOn() and noteOff() - methods, and midi messages for these events will be merged into the - midi stream that gets processed by processNextMidiBuffer(). -*/ -class JUCE_API MidiKeyboardState -{ -public: - //============================================================================== - MidiKeyboardState(); - ~MidiKeyboardState(); - - //============================================================================== - /** Resets the state of the object. - - All internal data for all the channels is reset, but no events are sent as a - result. - - If you want to release any keys that are currently down, and to send out note-up - midi messages for this, use the allNotesOff() method instead. - */ - void reset(); - - /** Returns true if the given midi key is currently held down for the given midi channel. - - The channel number must be between 1 and 16. If you want to see if any notes are - on for a range of channels, use the isNoteOnForChannels() method. - */ - bool isNoteOn (int midiChannel, int midiNoteNumber) const noexcept; - - /** Returns true if the given midi key is currently held down on any of a set of midi channels. - - The channel mask has a bit set for each midi channel you want to test for - bit - 0 = midi channel 1, bit 1 = midi channel 2, etc. - - If a note is on for at least one of the specified channels, this returns true. - */ - bool isNoteOnForChannels (int midiChannelMask, int midiNoteNumber) const noexcept; - - /** Turns a specified note on. - - This will cause a suitable midi note-on event to be injected into the midi buffer during the - next call to processNextMidiBuffer(). - - It will also trigger a synchronous callback to the listeners to tell them that the key has - gone down. - */ - void noteOn (int midiChannel, int midiNoteNumber, float velocity); - - /** Turns a specified note off. - - This will cause a suitable midi note-off event to be injected into the midi buffer during the - next call to processNextMidiBuffer(). - - It will also trigger a synchronous callback to the listeners to tell them that the key has - gone up. - - But if the note isn't acutally down for the given channel, this method will in fact do nothing. - */ - void noteOff (int midiChannel, int midiNoteNumber); - - /** This will turn off any currently-down notes for the given midi channel. - - If you pass 0 for the midi channel, it will in fact turn off all notes on all channels. - - Calling this method will make calls to noteOff(), so can trigger synchronous callbacks - and events being added to the midi stream. - */ - void allNotesOff (int midiChannel); - - //============================================================================== - /** Looks at a key-up/down event and uses it to update the state of this object. - - To process a buffer full of midi messages, use the processNextMidiBuffer() method - instead. - */ - void processNextMidiEvent (const MidiMessage& message); - - /** Scans a midi stream for up/down events and adds its own events to it. - - This will look for any up/down events and use them to update the internal state, - synchronously making suitable callbacks to the listeners. - - If injectIndirectEvents is true, then midi events to produce the recent noteOn() - and noteOff() calls will be added into the buffer. - - Only the section of the buffer whose timestamps are between startSample and - (startSample + numSamples) will be affected, and any events added will be placed - between these times. - - If you're going to use this method, you'll need to keep calling it regularly for - it to work satisfactorily. - - To process a single midi event at a time, use the processNextMidiEvent() method - instead. - */ - void processNextMidiBuffer (MidiBuffer& buffer, - int startSample, - int numSamples, - bool injectIndirectEvents); - - //============================================================================== - /** Registers a listener for callbacks when keys go up or down. - @see removeListener - */ - void addListener (MidiKeyboardStateListener* listener); - - /** Deregisters a listener. - @see addListener - */ - void removeListener (MidiKeyboardStateListener* listener); - -private: - //============================================================================== - CriticalSection lock; - uint16 noteStates [128]; - MidiBuffer eventsToAdd; - Array listeners; - - void noteOnInternal (int midiChannel, int midiNoteNumber, float velocity); - void noteOffInternal (int midiChannel, int midiNoteNumber); - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MidiKeyboardState) -}; - - -#endif // JUCE_MIDIKEYBOARDSTATE_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/midi/juce_MidiMessage.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/midi/juce_MidiMessage.cpp deleted file mode 100644 index 07e2ccd271..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/midi/juce_MidiMessage.cpp +++ /dev/null @@ -1,1094 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -namespace MidiHelpers -{ - inline uint8 initialByte (const int type, const int channel) noexcept - { - return (uint8) (type | jlimit (0, 15, channel - 1)); - } - - inline uint8 validVelocity (const int v) noexcept - { - return (uint8) jlimit (0, 127, v); - } -} - -//============================================================================== -int MidiMessage::readVariableLengthVal (const uint8* data, int& numBytesUsed) noexcept -{ - numBytesUsed = 0; - int v = 0, i; - - do - { - i = (int) *data++; - - if (++numBytesUsed > 6) - break; - - v = (v << 7) + (i & 0x7f); - - } while (i & 0x80); - - return v; -} - -int MidiMessage::getMessageLengthFromFirstByte (const uint8 firstByte) noexcept -{ - // this method only works for valid starting bytes of a short midi message - jassert (firstByte >= 0x80 && firstByte != 0xf0 && firstByte != 0xf7); - - static const char messageLengths[] = - { - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 1, 2, 3, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 - }; - - return messageLengths [firstByte & 0x7f]; -} - -//============================================================================== -MidiMessage::MidiMessage() noexcept - : timeStamp (0), size (2) -{ - preallocatedData.asBytes[0] = 0xf0; - preallocatedData.asBytes[1] = 0xf7; -} - -MidiMessage::MidiMessage (const void* const d, const int dataSize, const double t) - : timeStamp (t), - size (dataSize) -{ - jassert (dataSize > 0); - memcpy (allocateSpace (dataSize), d, (size_t) dataSize); - - // check that the length matches the data.. - jassert (size > 3 || *(uint8*)d >= 0xf0 || getMessageLengthFromFirstByte (*(uint8*)d) == size); -} - -MidiMessage::MidiMessage (const int byte1, const double t) noexcept - : timeStamp (t), size (1) -{ - preallocatedData.asBytes[0] = (uint8) byte1; - - // check that the length matches the data.. - jassert (byte1 >= 0xf0 || getMessageLengthFromFirstByte ((uint8) byte1) == 1); -} - -MidiMessage::MidiMessage (const int byte1, const int byte2, const double t) noexcept - : timeStamp (t), size (2) -{ - preallocatedData.asBytes[0] = (uint8) byte1; - preallocatedData.asBytes[1] = (uint8) byte2; - - // check that the length matches the data.. - jassert (byte1 >= 0xf0 || getMessageLengthFromFirstByte ((uint8) byte1) == 2); -} - -MidiMessage::MidiMessage (const int byte1, const int byte2, const int byte3, const double t) noexcept - : timeStamp (t), size (3) -{ - preallocatedData.asBytes[0] = (uint8) byte1; - preallocatedData.asBytes[1] = (uint8) byte2; - preallocatedData.asBytes[2] = (uint8) byte3; - - // check that the length matches the data.. - jassert (byte1 >= 0xf0 || getMessageLengthFromFirstByte ((uint8) byte1) == 3); -} - -MidiMessage::MidiMessage (const MidiMessage& other) - : timeStamp (other.timeStamp), size (other.size) -{ - if (other.allocatedData != nullptr) - { - allocatedData.malloc ((size_t) size); - memcpy (allocatedData, other.allocatedData, (size_t) size); - } - else - { - preallocatedData.asInt32 = other.preallocatedData.asInt32; - } -} - -MidiMessage::MidiMessage (const MidiMessage& other, const double newTimeStamp) - : timeStamp (newTimeStamp), size (other.size) -{ - if (other.allocatedData != nullptr) - { - allocatedData.malloc ((size_t) size); - memcpy (allocatedData, other.allocatedData, (size_t) size); - } - else - { - preallocatedData.asInt32 = other.preallocatedData.asInt32; - } -} - -MidiMessage::MidiMessage (const void* srcData, int sz, int& numBytesUsed, const uint8 lastStatusByte, - double t, bool sysexHasEmbeddedLength) - : timeStamp (t) -{ - const uint8* src = static_cast (srcData); - unsigned int byte = (unsigned int) *src; - - if (byte < 0x80) - { - byte = (unsigned int) (uint8) lastStatusByte; - numBytesUsed = -1; - } - else - { - numBytesUsed = 0; - --sz; - ++src; - } - - if (byte >= 0x80) - { - if (byte == 0xf0) - { - const uint8* d = src; - bool haveReadAllLengthBytes = ! sysexHasEmbeddedLength; - int numVariableLengthSysexBytes = 0; - - while (d < src + sz) - { - if (*d >= 0x80) - { - if (*d == 0xf7) - { - ++d; // include the trailing 0xf7 when we hit it - break; - } - - if (haveReadAllLengthBytes) // if we see a 0x80 bit set after the initial data length - break; // bytes, assume it's the end of the sysex - - ++numVariableLengthSysexBytes; - } - else if (! haveReadAllLengthBytes) - { - haveReadAllLengthBytes = true; - ++numVariableLengthSysexBytes; - } - - ++d; - } - - src += numVariableLengthSysexBytes; - size = 1 + (int) (d - src); - - uint8* dest = allocateSpace (size); - *dest = (uint8) byte; - memcpy (dest + 1, src, (size_t) (size - 1)); - - numBytesUsed += numVariableLengthSysexBytes; // (these aren't counted in the size) - } - else if (byte == 0xff) - { - int n; - const int bytesLeft = readVariableLengthVal (src + 1, n); - size = jmin (sz + 1, n + 2 + bytesLeft); - - uint8* dest = allocateSpace (size); - *dest = (uint8) byte; - memcpy (dest + 1, src, (size_t) size - 1); - } - else - { - preallocatedData.asInt32 = 0; - size = getMessageLengthFromFirstByte ((uint8) byte); - preallocatedData.asBytes[0] = (uint8) byte; - - if (size > 1) - { - preallocatedData.asBytes[1] = src[0]; - - if (size > 2) - preallocatedData.asBytes[2] = src[1]; - } - } - - numBytesUsed += size; - } - else - { - preallocatedData.asInt32 = 0; - size = 0; - } -} - -MidiMessage& MidiMessage::operator= (const MidiMessage& other) -{ - if (this != &other) - { - timeStamp = other.timeStamp; - size = other.size; - - if (other.allocatedData != nullptr) - { - allocatedData.malloc ((size_t) size); - memcpy (allocatedData, other.allocatedData, (size_t) size); - } - else - { - allocatedData.free(); - preallocatedData.asInt32 = other.preallocatedData.asInt32; - } - } - - return *this; -} - -#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS -MidiMessage::MidiMessage (MidiMessage&& other) noexcept - : timeStamp (other.timeStamp), size (other.size) -{ - if (other.allocatedData != nullptr) - allocatedData.swapWith (other.allocatedData); - else - preallocatedData.asInt32 = other.preallocatedData.asInt32; -} - -MidiMessage& MidiMessage::operator= (MidiMessage&& other) noexcept -{ - jassert (this != &other); // shouldn't be possible - - timeStamp = other.timeStamp; - size = other.size; - allocatedData.swapWith (other.allocatedData); - preallocatedData.asInt32 = other.preallocatedData.asInt32; - - return *this; -} -#endif - -MidiMessage::~MidiMessage() {} - -uint8* MidiMessage::allocateSpace (int bytes) -{ - if (bytes > 4) - { - allocatedData.malloc ((size_t) bytes); - return allocatedData; - } - - return preallocatedData.asBytes; -} - -int MidiMessage::getChannel() const noexcept -{ - const uint8* const data = getRawData(); - - if ((data[0] & 0xf0) != 0xf0) - return (data[0] & 0xf) + 1; - - return 0; -} - -bool MidiMessage::isForChannel (const int channel) const noexcept -{ - jassert (channel > 0 && channel <= 16); // valid channels are numbered 1 to 16 - - const uint8* const data = getRawData(); - - return ((data[0] & 0xf) == channel - 1) - && ((data[0] & 0xf0) != 0xf0); -} - -void MidiMessage::setChannel (const int channel) noexcept -{ - jassert (channel > 0 && channel <= 16); // valid channels are numbered 1 to 16 - - uint8* const data = getData(); - - if ((data[0] & 0xf0) != (uint8) 0xf0) - data[0] = (uint8) ((data[0] & (uint8) 0xf0) - | (uint8)(channel - 1)); -} - -bool MidiMessage::isNoteOn (const bool returnTrueForVelocity0) const noexcept -{ - const uint8* const data = getRawData(); - - return ((data[0] & 0xf0) == 0x90) - && (returnTrueForVelocity0 || data[2] != 0); -} - -bool MidiMessage::isNoteOff (const bool returnTrueForNoteOnVelocity0) const noexcept -{ - const uint8* const data = getRawData(); - - return ((data[0] & 0xf0) == 0x80) - || (returnTrueForNoteOnVelocity0 && (data[2] == 0) && ((data[0] & 0xf0) == 0x90)); -} - -bool MidiMessage::isNoteOnOrOff() const noexcept -{ - const uint8* const data = getRawData(); - - const int d = data[0] & 0xf0; - return (d == 0x90) || (d == 0x80); -} - -int MidiMessage::getNoteNumber() const noexcept -{ - return getRawData()[1]; -} - -void MidiMessage::setNoteNumber (const int newNoteNumber) noexcept -{ - if (isNoteOnOrOff()) - getData()[1] = (uint8) (newNoteNumber & 127); -} - -uint8 MidiMessage::getVelocity() const noexcept -{ - if (isNoteOnOrOff()) - return getRawData()[2]; - - return 0; -} - -float MidiMessage::getFloatVelocity() const noexcept -{ - return getVelocity() * (1.0f / 127.0f); -} - -void MidiMessage::setVelocity (const float newVelocity) noexcept -{ - if (isNoteOnOrOff()) - getData()[2] = MidiHelpers::validVelocity (roundToInt (newVelocity * 127.0f)); -} - -void MidiMessage::multiplyVelocity (const float scaleFactor) noexcept -{ - if (isNoteOnOrOff()) - { - uint8* const data = getData(); - data[2] = MidiHelpers::validVelocity (roundToInt (scaleFactor * data[2])); - } -} - -bool MidiMessage::isAftertouch() const noexcept -{ - return (getRawData()[0] & 0xf0) == 0xa0; -} - -int MidiMessage::getAfterTouchValue() const noexcept -{ - jassert (isAftertouch()); - return getRawData()[2]; -} - -MidiMessage MidiMessage::aftertouchChange (const int channel, - const int noteNum, - const int aftertouchValue) noexcept -{ - jassert (channel > 0 && channel <= 16); // valid channels are numbered 1 to 16 - jassert (isPositiveAndBelow (noteNum, (int) 128)); - jassert (isPositiveAndBelow (aftertouchValue, (int) 128)); - - return MidiMessage (MidiHelpers::initialByte (0xa0, channel), - noteNum & 0x7f, - aftertouchValue & 0x7f); -} - -bool MidiMessage::isChannelPressure() const noexcept -{ - return (getRawData()[0] & 0xf0) == 0xd0; -} - -int MidiMessage::getChannelPressureValue() const noexcept -{ - jassert (isChannelPressure()); - return getRawData()[1]; -} - -MidiMessage MidiMessage::channelPressureChange (const int channel, const int pressure) noexcept -{ - jassert (channel > 0 && channel <= 16); // valid channels are numbered 1 to 16 - jassert (isPositiveAndBelow (pressure, (int) 128)); - - return MidiMessage (MidiHelpers::initialByte (0xd0, channel), pressure & 0x7f); -} - -bool MidiMessage::isSustainPedalOn() const noexcept { return isControllerOfType (0x40) && getRawData()[2] >= 64; } -bool MidiMessage::isSustainPedalOff() const noexcept { return isControllerOfType (0x40) && getRawData()[2] < 64; } - -bool MidiMessage::isSostenutoPedalOn() const noexcept { return isControllerOfType (0x42) && getRawData()[2] >= 64; } -bool MidiMessage::isSostenutoPedalOff() const noexcept { return isControllerOfType (0x42) && getRawData()[2] < 64; } - -bool MidiMessage::isSoftPedalOn() const noexcept { return isControllerOfType (0x43) && getRawData()[2] >= 64; } -bool MidiMessage::isSoftPedalOff() const noexcept { return isControllerOfType (0x43) && getRawData()[2] < 64; } - - -bool MidiMessage::isProgramChange() const noexcept -{ - return (getRawData()[0] & 0xf0) == 0xc0; -} - -int MidiMessage::getProgramChangeNumber() const noexcept -{ - jassert (isProgramChange()); - return getRawData()[1]; -} - -MidiMessage MidiMessage::programChange (const int channel, const int programNumber) noexcept -{ - jassert (channel > 0 && channel <= 16); // valid channels are numbered 1 to 16 - - return MidiMessage (MidiHelpers::initialByte (0xc0, channel), programNumber & 0x7f); -} - -bool MidiMessage::isPitchWheel() const noexcept -{ - return (getRawData()[0] & 0xf0) == 0xe0; -} - -int MidiMessage::getPitchWheelValue() const noexcept -{ - jassert (isPitchWheel()); - const uint8* const data = getRawData(); - return data[1] | (data[2] << 7); -} - -MidiMessage MidiMessage::pitchWheel (const int channel, const int position) noexcept -{ - jassert (channel > 0 && channel <= 16); // valid channels are numbered 1 to 16 - jassert (isPositiveAndBelow (position, (int) 0x4000)); - - return MidiMessage (MidiHelpers::initialByte (0xe0, channel), - position & 127, (position >> 7) & 127); -} - -bool MidiMessage::isController() const noexcept -{ - return (getRawData()[0] & 0xf0) == 0xb0; -} - -bool MidiMessage::isControllerOfType (const int controllerType) const noexcept -{ - const uint8* const data = getRawData(); - return (data[0] & 0xf0) == 0xb0 && data[1] == controllerType; -} - -int MidiMessage::getControllerNumber() const noexcept -{ - jassert (isController()); - return getRawData()[1]; -} - -int MidiMessage::getControllerValue() const noexcept -{ - jassert (isController()); - return getRawData()[2]; -} - -MidiMessage MidiMessage::controllerEvent (const int channel, const int controllerType, const int value) noexcept -{ - // the channel must be between 1 and 16 inclusive - jassert (channel > 0 && channel <= 16); - - return MidiMessage (MidiHelpers::initialByte (0xb0, channel), - controllerType & 127, value & 127); -} - -MidiMessage MidiMessage::noteOn (const int channel, const int noteNumber, const float velocity) noexcept -{ - return noteOn (channel, noteNumber, (uint8) (velocity * 127.0f + 0.5f)); -} - -MidiMessage MidiMessage::noteOn (const int channel, const int noteNumber, const uint8 velocity) noexcept -{ - jassert (channel > 0 && channel <= 16); - jassert (isPositiveAndBelow (noteNumber, (int) 128)); - - return MidiMessage (MidiHelpers::initialByte (0x90, channel), - noteNumber & 127, MidiHelpers::validVelocity (velocity)); -} - -MidiMessage MidiMessage::noteOff (const int channel, const int noteNumber, uint8 velocity) noexcept -{ - jassert (channel > 0 && channel <= 16); - jassert (isPositiveAndBelow (noteNumber, (int) 128)); - - return MidiMessage (MidiHelpers::initialByte (0x80, channel), - noteNumber & 127, MidiHelpers::validVelocity (velocity)); -} - -MidiMessage MidiMessage::allNotesOff (const int channel) noexcept -{ - return controllerEvent (channel, 123, 0); -} - -bool MidiMessage::isAllNotesOff() const noexcept -{ - const uint8* const data = getRawData(); - return (data[0] & 0xf0) == 0xb0 && data[1] == 123; -} - -MidiMessage MidiMessage::allSoundOff (const int channel) noexcept -{ - return controllerEvent (channel, 120, 0); -} - -bool MidiMessage::isAllSoundOff() const noexcept -{ - const uint8* const data = getRawData(); - return (data[0] & 0xf0) == 0xb0 && data[1] == 120; -} - -MidiMessage MidiMessage::allControllersOff (const int channel) noexcept -{ - return controllerEvent (channel, 121, 0); -} - -MidiMessage MidiMessage::masterVolume (const float volume) -{ - const int vol = jlimit (0, 0x3fff, roundToInt (volume * 0x4000)); - - const uint8 buf[] = { 0xf0, 0x7f, 0x7f, 0x04, 0x01, - (uint8) (vol & 0x7f), - (uint8) (vol >> 7), - 0xf7 }; - - return MidiMessage (buf, 8); -} - -//============================================================================== -bool MidiMessage::isSysEx() const noexcept -{ - return *getRawData() == 0xf0; -} - -MidiMessage MidiMessage::createSysExMessage (const void* sysexData, const int dataSize) -{ - HeapBlock m ((size_t) dataSize + 2); - - m[0] = 0xf0; - memcpy (m + 1, sysexData, (size_t) dataSize); - m[dataSize + 1] = 0xf7; - - return MidiMessage (m, dataSize + 2); -} - -const uint8* MidiMessage::getSysExData() const noexcept -{ - return isSysEx() ? getRawData() + 1 : nullptr; -} - -int MidiMessage::getSysExDataSize() const noexcept -{ - return isSysEx() ? size - 2 : 0; -} - -//============================================================================== -bool MidiMessage::isMetaEvent() const noexcept { return *getRawData() == 0xff; } -bool MidiMessage::isActiveSense() const noexcept { return *getRawData() == 0xfe; } - -int MidiMessage::getMetaEventType() const noexcept -{ - const uint8* const data = getRawData(); - return *data != 0xff ? -1 : data[1]; -} - -int MidiMessage::getMetaEventLength() const noexcept -{ - const uint8* const data = getRawData(); - if (*data == 0xff) - { - int n; - return jmin (size - 2, readVariableLengthVal (data + 2, n)); - } - - return 0; -} - -const uint8* MidiMessage::getMetaEventData() const noexcept -{ - jassert (isMetaEvent()); - - int n; - const uint8* d = getRawData() + 2; - readVariableLengthVal (d, n); - return d + n; -} - -bool MidiMessage::isTrackMetaEvent() const noexcept { return getMetaEventType() == 0; } -bool MidiMessage::isEndOfTrackMetaEvent() const noexcept { return getMetaEventType() == 47; } - -bool MidiMessage::isTextMetaEvent() const noexcept -{ - const int t = getMetaEventType(); - return t > 0 && t < 16; -} - -String MidiMessage::getTextFromTextMetaEvent() const -{ - const char* const textData = reinterpret_cast (getMetaEventData()); - return String (CharPointer_UTF8 (textData), - CharPointer_UTF8 (textData + getMetaEventLength())); -} - -MidiMessage MidiMessage::textMetaEvent (int type, StringRef text) -{ - jassert (type > 0 && type < 16); - - MidiMessage result; - - const size_t textSize = text.text.sizeInBytes() - 1; - - uint8 header[8]; - size_t n = sizeof (header); - - header[--n] = (uint8) (textSize & 0x7f); - - for (size_t i = textSize; (i >>= 7) != 0;) - header[--n] = (uint8) ((i & 0x7f) | 0x80); - - header[--n] = (uint8) type; - header[--n] = 0xff; - - const size_t headerLen = sizeof (header) - n; - - uint8* const dest = result.allocateSpace ((int) (headerLen + textSize)); - result.size = (int) (headerLen + textSize); - - memcpy (dest, header + n, headerLen); - memcpy (dest + headerLen, text.text.getAddress(), textSize); - - return result; -} - -bool MidiMessage::isTrackNameEvent() const noexcept { const uint8* data = getRawData(); return (data[1] == 3) && (*data == 0xff); } -bool MidiMessage::isTempoMetaEvent() const noexcept { const uint8* data = getRawData(); return (data[1] == 81) && (*data == 0xff); } -bool MidiMessage::isMidiChannelMetaEvent() const noexcept { const uint8* data = getRawData(); return (data[1] == 0x20) && (*data == 0xff) && (data[2] == 1); } - -int MidiMessage::getMidiChannelMetaEventChannel() const noexcept -{ - jassert (isMidiChannelMetaEvent()); - return getRawData()[3] + 1; -} - -double MidiMessage::getTempoSecondsPerQuarterNote() const noexcept -{ - if (! isTempoMetaEvent()) - return 0.0; - - const uint8* const d = getMetaEventData(); - - return (((unsigned int) d[0] << 16) - | ((unsigned int) d[1] << 8) - | d[2]) - / 1000000.0; -} - -double MidiMessage::getTempoMetaEventTickLength (const short timeFormat) const noexcept -{ - if (timeFormat > 0) - { - if (! isTempoMetaEvent()) - return 0.5 / timeFormat; - - return getTempoSecondsPerQuarterNote() / timeFormat; - } - else - { - const int frameCode = (-timeFormat) >> 8; - double framesPerSecond; - - switch (frameCode) - { - case 24: framesPerSecond = 24.0; break; - case 25: framesPerSecond = 25.0; break; - case 29: framesPerSecond = 29.97; break; - case 30: framesPerSecond = 30.0; break; - default: framesPerSecond = 30.0; break; - } - - return (1.0 / framesPerSecond) / (timeFormat & 0xff); - } -} - -MidiMessage MidiMessage::tempoMetaEvent (int microsecondsPerQuarterNote) noexcept -{ - const uint8 d[] = { 0xff, 81, 3, - (uint8) (microsecondsPerQuarterNote >> 16), - (uint8) (microsecondsPerQuarterNote >> 8), - (uint8) microsecondsPerQuarterNote }; - - return MidiMessage (d, 6, 0.0); -} - -bool MidiMessage::isTimeSignatureMetaEvent() const noexcept -{ - const uint8* const data = getRawData(); - return (data[1] == 0x58) && (*data == (uint8) 0xff); -} - -void MidiMessage::getTimeSignatureInfo (int& numerator, int& denominator) const noexcept -{ - if (isTimeSignatureMetaEvent()) - { - const uint8* const d = getMetaEventData(); - numerator = d[0]; - denominator = 1 << d[1]; - } - else - { - numerator = 4; - denominator = 4; - } -} - -MidiMessage MidiMessage::timeSignatureMetaEvent (const int numerator, const int denominator) -{ - int n = 1; - int powerOfTwo = 0; - - while (n < denominator) - { - n <<= 1; - ++powerOfTwo; - } - - const uint8 d[] = { 0xff, 0x58, 0x04, (uint8) numerator, (uint8) powerOfTwo, 1, 96 }; - return MidiMessage (d, 7, 0.0); -} - -MidiMessage MidiMessage::midiChannelMetaEvent (const int channel) noexcept -{ - const uint8 d[] = { 0xff, 0x20, 0x01, (uint8) jlimit (0, 0xff, channel - 1) }; - return MidiMessage (d, 4, 0.0); -} - -bool MidiMessage::isKeySignatureMetaEvent() const noexcept -{ - return getMetaEventType() == 0x59; -} - -int MidiMessage::getKeySignatureNumberOfSharpsOrFlats() const noexcept -{ - return (int) getMetaEventData()[0]; -} - -bool MidiMessage::isKeySignatureMajorKey() const noexcept -{ - return getMetaEventData()[1] == 0; -} - -MidiMessage MidiMessage::keySignatureMetaEvent (int numberOfSharpsOrFlats, bool isMinorKey) -{ - jassert (numberOfSharpsOrFlats >= -7 && numberOfSharpsOrFlats <= 7); - - const uint8 d[] = { 0xff, 0x59, 0x02, (uint8) numberOfSharpsOrFlats, isMinorKey ? (uint8) 1 : (uint8) 0 }; - return MidiMessage (d, 5, 0.0); -} - -MidiMessage MidiMessage::endOfTrack() noexcept -{ - return MidiMessage (0xff, 0x2f, 0, 0.0); -} - -//============================================================================== -bool MidiMessage::isSongPositionPointer() const noexcept { return *getRawData() == 0xf2; } -int MidiMessage::getSongPositionPointerMidiBeat() const noexcept { const uint8* data = getRawData(); return data[1] | (data[2] << 7); } - -MidiMessage MidiMessage::songPositionPointer (const int positionInMidiBeats) noexcept -{ - return MidiMessage (0xf2, - positionInMidiBeats & 127, - (positionInMidiBeats >> 7) & 127); -} - -bool MidiMessage::isMidiStart() const noexcept { return *getRawData() == 0xfa; } -MidiMessage MidiMessage::midiStart() noexcept { return MidiMessage (0xfa); } - -bool MidiMessage::isMidiContinue() const noexcept { return *getRawData() == 0xfb; } -MidiMessage MidiMessage::midiContinue() noexcept { return MidiMessage (0xfb); } - -bool MidiMessage::isMidiStop() const noexcept { return *getRawData() == 0xfc; } -MidiMessage MidiMessage::midiStop() noexcept { return MidiMessage (0xfc); } - -bool MidiMessage::isMidiClock() const noexcept { return *getRawData() == 0xf8; } -MidiMessage MidiMessage::midiClock() noexcept { return MidiMessage (0xf8); } - -bool MidiMessage::isQuarterFrame() const noexcept { return *getRawData() == 0xf1; } -int MidiMessage::getQuarterFrameSequenceNumber() const noexcept { return ((int) getRawData()[1]) >> 4; } -int MidiMessage::getQuarterFrameValue() const noexcept { return ((int) getRawData()[1]) & 0x0f; } - -MidiMessage MidiMessage::quarterFrame (const int sequenceNumber, const int value) noexcept -{ - return MidiMessage (0xf1, (sequenceNumber << 4) | value); -} - -bool MidiMessage::isFullFrame() const noexcept -{ - const uint8* const data = getRawData(); - - return data[0] == 0xf0 - && data[1] == 0x7f - && size >= 10 - && data[3] == 0x01 - && data[4] == 0x01; -} - -void MidiMessage::getFullFrameParameters (int& hours, int& minutes, int& seconds, int& frames, - MidiMessage::SmpteTimecodeType& timecodeType) const noexcept -{ - jassert (isFullFrame()); - - const uint8* const data = getRawData(); - timecodeType = (SmpteTimecodeType) (data[5] >> 5); - hours = data[5] & 0x1f; - minutes = data[6]; - seconds = data[7]; - frames = data[8]; -} - -MidiMessage MidiMessage::fullFrame (const int hours, const int minutes, - const int seconds, const int frames, - MidiMessage::SmpteTimecodeType timecodeType) -{ - const uint8 d[] = { 0xf0, 0x7f, 0x7f, 0x01, 0x01, - (uint8) ((hours & 0x01f) | (timecodeType << 5)), - (uint8) minutes, - (uint8) seconds, - (uint8) frames, - 0xf7 }; - - return MidiMessage (d, 10, 0.0); -} - -bool MidiMessage::isMidiMachineControlMessage() const noexcept -{ - const uint8* const data = getRawData(); - return data[0] == 0xf0 - && data[1] == 0x7f - && data[3] == 0x06 - && size > 5; -} - -MidiMessage::MidiMachineControlCommand MidiMessage::getMidiMachineControlCommand() const noexcept -{ - jassert (isMidiMachineControlMessage()); - - return (MidiMachineControlCommand) getRawData()[4]; -} - -MidiMessage MidiMessage::midiMachineControlCommand (MidiMessage::MidiMachineControlCommand command) -{ - const uint8 d[] = { 0xf0, 0x7f, 0, 6, (uint8) command, 0xf7 }; - - return MidiMessage (d, 6, 0.0); -} - -//============================================================================== -bool MidiMessage::isMidiMachineControlGoto (int& hours, int& minutes, int& seconds, int& frames) const noexcept -{ - const uint8* const data = getRawData(); - if (size >= 12 - && data[0] == 0xf0 - && data[1] == 0x7f - && data[3] == 0x06 - && data[4] == 0x44 - && data[5] == 0x06 - && data[6] == 0x01) - { - hours = data[7] % 24; // (that some machines send out hours > 24) - minutes = data[8]; - seconds = data[9]; - frames = data[10]; - - return true; - } - - return false; -} - -MidiMessage MidiMessage::midiMachineControlGoto (int hours, int minutes, int seconds, int frames) -{ - const uint8 d[] = { 0xf0, 0x7f, 0, 6, 0x44, 6, 1, - (uint8) hours, - (uint8) minutes, - (uint8) seconds, - (uint8) frames, - 0xf7 }; - - return MidiMessage (d, 12, 0.0); -} - -//============================================================================== -String MidiMessage::getMidiNoteName (int note, bool useSharps, bool includeOctaveNumber, int octaveNumForMiddleC) -{ - static const char* const sharpNoteNames[] = { "C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B" }; - static const char* const flatNoteNames[] = { "C", "Db", "D", "Eb", "E", "F", "Gb", "G", "Ab", "A", "Bb", "B" }; - - if (isPositiveAndBelow (note, (int) 128)) - { - String s (useSharps ? sharpNoteNames [note % 12] - : flatNoteNames [note % 12]); - - if (includeOctaveNumber) - s << (note / 12 + (octaveNumForMiddleC - 5)); - - return s; - } - - return String::empty; -} - -double MidiMessage::getMidiNoteInHertz (int noteNumber, const double frequencyOfA) noexcept -{ - return frequencyOfA * pow (2.0, (noteNumber - 69) / 12.0); -} - -bool MidiMessage::isMidiNoteBlack (int noteNumber) noexcept -{ - return ((1 << (noteNumber % 12)) & 0x054a) != 0; -} - -const char* MidiMessage::getGMInstrumentName (const int n) -{ - static const char* names[] = - { - NEEDS_TRANS("Acoustic Grand Piano"), NEEDS_TRANS("Bright Acoustic Piano"), NEEDS_TRANS("Electric Grand Piano"), NEEDS_TRANS("Honky-tonk Piano"), - NEEDS_TRANS("Electric Piano 1"), NEEDS_TRANS("Electric Piano 2"), NEEDS_TRANS("Harpsichord"), NEEDS_TRANS("Clavinet"), - NEEDS_TRANS("Celesta"), NEEDS_TRANS("Glockenspiel"), NEEDS_TRANS("Music Box"), NEEDS_TRANS("Vibraphone"), - NEEDS_TRANS("Marimba"), NEEDS_TRANS("Xylophone"), NEEDS_TRANS("Tubular Bells"), NEEDS_TRANS("Dulcimer"), - NEEDS_TRANS("Drawbar Organ"), NEEDS_TRANS("Percussive Organ"), NEEDS_TRANS("Rock Organ"), NEEDS_TRANS("Church Organ"), - NEEDS_TRANS("Reed Organ"), NEEDS_TRANS("Accordion"), NEEDS_TRANS("Harmonica"), NEEDS_TRANS("Tango Accordion"), - NEEDS_TRANS("Acoustic Guitar (nylon)"), NEEDS_TRANS("Acoustic Guitar (steel)"), NEEDS_TRANS("Electric Guitar (jazz)"), NEEDS_TRANS("Electric Guitar (clean)"), - NEEDS_TRANS("Electric Guitar (mute)"), NEEDS_TRANS("Overdriven Guitar"), NEEDS_TRANS("Distortion Guitar"), NEEDS_TRANS("Guitar Harmonics"), - NEEDS_TRANS("Acoustic Bass"), NEEDS_TRANS("Electric Bass (finger)"), NEEDS_TRANS("Electric Bass (pick)"), NEEDS_TRANS("Fretless Bass"), - NEEDS_TRANS("Slap Bass 1"), NEEDS_TRANS("Slap Bass 2"), NEEDS_TRANS("Synth Bass 1"), NEEDS_TRANS("Synth Bass 2"), - NEEDS_TRANS("Violin"), NEEDS_TRANS("Viola"), NEEDS_TRANS("Cello"), NEEDS_TRANS("Contrabass"), - NEEDS_TRANS("Tremolo Strings"), NEEDS_TRANS("Pizzicato Strings"), NEEDS_TRANS("Orchestral Harp"), NEEDS_TRANS("Timpani"), - NEEDS_TRANS("String Ensemble 1"), NEEDS_TRANS("String Ensemble 2"), NEEDS_TRANS("SynthStrings 1"), NEEDS_TRANS("SynthStrings 2"), - NEEDS_TRANS("Choir Aahs"), NEEDS_TRANS("Voice Oohs"), NEEDS_TRANS("Synth Voice"), NEEDS_TRANS("Orchestra Hit"), - NEEDS_TRANS("Trumpet"), NEEDS_TRANS("Trombone"), NEEDS_TRANS("Tuba"), NEEDS_TRANS("Muted Trumpet"), - NEEDS_TRANS("French Horn"), NEEDS_TRANS("Brass Section"), NEEDS_TRANS("SynthBrass 1"), NEEDS_TRANS("SynthBrass 2"), - NEEDS_TRANS("Soprano Sax"), NEEDS_TRANS("Alto Sax"), NEEDS_TRANS("Tenor Sax"), NEEDS_TRANS("Baritone Sax"), - NEEDS_TRANS("Oboe"), NEEDS_TRANS("English Horn"), NEEDS_TRANS("Bassoon"), NEEDS_TRANS("Clarinet"), - NEEDS_TRANS("Piccolo"), NEEDS_TRANS("Flute"), NEEDS_TRANS("Recorder"), NEEDS_TRANS("Pan Flute"), - NEEDS_TRANS("Blown Bottle"), NEEDS_TRANS("Shakuhachi"), NEEDS_TRANS("Whistle"), NEEDS_TRANS("Ocarina"), - NEEDS_TRANS("Lead 1 (square)"), NEEDS_TRANS("Lead 2 (sawtooth)"), NEEDS_TRANS("Lead 3 (calliope)"), NEEDS_TRANS("Lead 4 (chiff)"), - NEEDS_TRANS("Lead 5 (charang)"), NEEDS_TRANS("Lead 6 (voice)"), NEEDS_TRANS("Lead 7 (fifths)"), NEEDS_TRANS("Lead 8 (bass+lead)"), - NEEDS_TRANS("Pad 1 (new age)"), NEEDS_TRANS("Pad 2 (warm)"), NEEDS_TRANS("Pad 3 (polysynth)"), NEEDS_TRANS("Pad 4 (choir)"), - NEEDS_TRANS("Pad 5 (bowed)"), NEEDS_TRANS("Pad 6 (metallic)"), NEEDS_TRANS("Pad 7 (halo)"), NEEDS_TRANS("Pad 8 (sweep)"), - NEEDS_TRANS("FX 1 (rain)"), NEEDS_TRANS("FX 2 (soundtrack)"), NEEDS_TRANS("FX 3 (crystal)"), NEEDS_TRANS("FX 4 (atmosphere)"), - NEEDS_TRANS("FX 5 (brightness)"), NEEDS_TRANS("FX 6 (goblins)"), NEEDS_TRANS("FX 7 (echoes)"), NEEDS_TRANS("FX 8 (sci-fi)"), - NEEDS_TRANS("Sitar"), NEEDS_TRANS("Banjo"), NEEDS_TRANS("Shamisen"), NEEDS_TRANS("Koto"), - NEEDS_TRANS("Kalimba"), NEEDS_TRANS("Bag pipe"), NEEDS_TRANS("Fiddle"), NEEDS_TRANS("Shanai"), - NEEDS_TRANS("Tinkle Bell"), NEEDS_TRANS("Agogo"), NEEDS_TRANS("Steel Drums"), NEEDS_TRANS("Woodblock"), - NEEDS_TRANS("Taiko Drum"), NEEDS_TRANS("Melodic Tom"), NEEDS_TRANS("Synth Drum"), NEEDS_TRANS("Reverse Cymbal"), - NEEDS_TRANS("Guitar Fret Noise"), NEEDS_TRANS("Breath Noise"), NEEDS_TRANS("Seashore"), NEEDS_TRANS("Bird Tweet"), - NEEDS_TRANS("Telephone Ring"), NEEDS_TRANS("Helicopter"), NEEDS_TRANS("Applause"), NEEDS_TRANS("Gunshot") - }; - - return isPositiveAndBelow (n, numElementsInArray (names)) ? names[n] : nullptr; -} - -const char* MidiMessage::getGMInstrumentBankName (const int n) -{ - static const char* names[] = - { - NEEDS_TRANS("Piano"), NEEDS_TRANS("Chromatic Percussion"), NEEDS_TRANS("Organ"), NEEDS_TRANS("Guitar"), - NEEDS_TRANS("Bass"), NEEDS_TRANS("Strings"), NEEDS_TRANS("Ensemble"), NEEDS_TRANS("Brass"), - NEEDS_TRANS("Reed"), NEEDS_TRANS("Pipe"), NEEDS_TRANS("Synth Lead"), NEEDS_TRANS("Synth Pad"), - NEEDS_TRANS("Synth Effects"), NEEDS_TRANS("Ethnic"), NEEDS_TRANS("Percussive"), NEEDS_TRANS("Sound Effects") - }; - - return isPositiveAndBelow (n, numElementsInArray (names)) ? names[n] : nullptr; -} - -const char* MidiMessage::getRhythmInstrumentName (const int n) -{ - static const char* names[] = - { - NEEDS_TRANS("Acoustic Bass Drum"), NEEDS_TRANS("Bass Drum 1"), NEEDS_TRANS("Side Stick"), NEEDS_TRANS("Acoustic Snare"), - NEEDS_TRANS("Hand Clap"), NEEDS_TRANS("Electric Snare"), NEEDS_TRANS("Low Floor Tom"), NEEDS_TRANS("Closed Hi-Hat"), - NEEDS_TRANS("High Floor Tom"), NEEDS_TRANS("Pedal Hi-Hat"), NEEDS_TRANS("Low Tom"), NEEDS_TRANS("Open Hi-Hat"), - NEEDS_TRANS("Low-Mid Tom"), NEEDS_TRANS("Hi-Mid Tom"), NEEDS_TRANS("Crash Cymbal 1"), NEEDS_TRANS("High Tom"), - NEEDS_TRANS("Ride Cymbal 1"), NEEDS_TRANS("Chinese Cymbal"), NEEDS_TRANS("Ride Bell"), NEEDS_TRANS("Tambourine"), - NEEDS_TRANS("Splash Cymbal"), NEEDS_TRANS("Cowbell"), NEEDS_TRANS("Crash Cymbal 2"), NEEDS_TRANS("Vibraslap"), - NEEDS_TRANS("Ride Cymbal 2"), NEEDS_TRANS("Hi Bongo"), NEEDS_TRANS("Low Bongo"), NEEDS_TRANS("Mute Hi Conga"), - NEEDS_TRANS("Open Hi Conga"), NEEDS_TRANS("Low Conga"), NEEDS_TRANS("High Timbale"), NEEDS_TRANS("Low Timbale"), - NEEDS_TRANS("High Agogo"), NEEDS_TRANS("Low Agogo"), NEEDS_TRANS("Cabasa"), NEEDS_TRANS("Maracas"), - NEEDS_TRANS("Short Whistle"), NEEDS_TRANS("Long Whistle"), NEEDS_TRANS("Short Guiro"), NEEDS_TRANS("Long Guiro"), - NEEDS_TRANS("Claves"), NEEDS_TRANS("Hi Wood Block"), NEEDS_TRANS("Low Wood Block"), NEEDS_TRANS("Mute Cuica"), - NEEDS_TRANS("Open Cuica"), NEEDS_TRANS("Mute Triangle"), NEEDS_TRANS("Open Triangle") - }; - - return (n >= 35 && n <= 81) ? names [n - 35] : nullptr; -} - -const char* MidiMessage::getControllerName (const int n) -{ - static const char* names[] = - { - NEEDS_TRANS("Bank Select"), NEEDS_TRANS("Modulation Wheel (coarse)"), NEEDS_TRANS("Breath controller (coarse)"), - nullptr, - NEEDS_TRANS("Foot Pedal (coarse)"), NEEDS_TRANS("Portamento Time (coarse)"), NEEDS_TRANS("Data Entry (coarse)"), - NEEDS_TRANS("Volume (coarse)"), NEEDS_TRANS("Balance (coarse)"), - nullptr, - NEEDS_TRANS("Pan position (coarse)"), NEEDS_TRANS("Expression (coarse)"), NEEDS_TRANS("Effect Control 1 (coarse)"), - NEEDS_TRANS("Effect Control 2 (coarse)"), - nullptr, nullptr, - NEEDS_TRANS("General Purpose Slider 1"), NEEDS_TRANS("General Purpose Slider 2"), - NEEDS_TRANS("General Purpose Slider 3"), NEEDS_TRANS("General Purpose Slider 4"), - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - NEEDS_TRANS("Bank Select (fine)"), NEEDS_TRANS("Modulation Wheel (fine)"), NEEDS_TRANS("Breath controller (fine)"), - nullptr, - NEEDS_TRANS("Foot Pedal (fine)"), NEEDS_TRANS("Portamento Time (fine)"), NEEDS_TRANS("Data Entry (fine)"), NEEDS_TRANS("Volume (fine)"), - NEEDS_TRANS("Balance (fine)"), nullptr, NEEDS_TRANS("Pan position (fine)"), NEEDS_TRANS("Expression (fine)"), - NEEDS_TRANS("Effect Control 1 (fine)"), NEEDS_TRANS("Effect Control 2 (fine)"), - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - NEEDS_TRANS("Hold Pedal (on/off)"), NEEDS_TRANS("Portamento (on/off)"), NEEDS_TRANS("Sustenuto Pedal (on/off)"), NEEDS_TRANS("Soft Pedal (on/off)"), - NEEDS_TRANS("Legato Pedal (on/off)"), NEEDS_TRANS("Hold 2 Pedal (on/off)"), NEEDS_TRANS("Sound Variation"), NEEDS_TRANS("Sound Timbre"), - NEEDS_TRANS("Sound Release Time"), NEEDS_TRANS("Sound Attack Time"), NEEDS_TRANS("Sound Brightness"), NEEDS_TRANS("Sound Control 6"), - NEEDS_TRANS("Sound Control 7"), NEEDS_TRANS("Sound Control 8"), NEEDS_TRANS("Sound Control 9"), NEEDS_TRANS("Sound Control 10"), - NEEDS_TRANS("General Purpose Button 1 (on/off)"), NEEDS_TRANS("General Purpose Button 2 (on/off)"), - NEEDS_TRANS("General Purpose Button 3 (on/off)"), NEEDS_TRANS("General Purpose Button 4 (on/off)"), - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - NEEDS_TRANS("Reverb Level"), NEEDS_TRANS("Tremolo Level"), NEEDS_TRANS("Chorus Level"), NEEDS_TRANS("Celeste Level"), - NEEDS_TRANS("Phaser Level"), NEEDS_TRANS("Data Button increment"), NEEDS_TRANS("Data Button decrement"), NEEDS_TRANS("Non-registered Parameter (fine)"), - NEEDS_TRANS("Non-registered Parameter (coarse)"), NEEDS_TRANS("Registered Parameter (fine)"), NEEDS_TRANS("Registered Parameter (coarse)"), - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - NEEDS_TRANS("All Sound Off"), NEEDS_TRANS("All Controllers Off"), NEEDS_TRANS("Local Keyboard (on/off)"), NEEDS_TRANS("All Notes Off"), - NEEDS_TRANS("Omni Mode Off"), NEEDS_TRANS("Omni Mode On"), NEEDS_TRANS("Mono Operation"), NEEDS_TRANS("Poly Operation") - }; - - return isPositiveAndBelow (n, numElementsInArray (names)) ? names[n] : nullptr; -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/midi/juce_MidiMessage.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/midi/juce_MidiMessage.h deleted file mode 100644 index 9002aa0336..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/midi/juce_MidiMessage.h +++ /dev/null @@ -1,903 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_MIDIMESSAGE_H_INCLUDED -#define JUCE_MIDIMESSAGE_H_INCLUDED - - -//============================================================================== -/** - Encapsulates a MIDI message. - - @see MidiMessageSequence, MidiOutput, MidiInput -*/ -class JUCE_API MidiMessage -{ -public: - //============================================================================== - /** Creates a 3-byte short midi message. - - @param byte1 message byte 1 - @param byte2 message byte 2 - @param byte3 message byte 3 - @param timeStamp the time to give the midi message - this value doesn't - use any particular units, so will be application-specific - */ - MidiMessage (int byte1, int byte2, int byte3, double timeStamp = 0) noexcept; - - /** Creates a 2-byte short midi message. - - @param byte1 message byte 1 - @param byte2 message byte 2 - @param timeStamp the time to give the midi message - this value doesn't - use any particular units, so will be application-specific - */ - MidiMessage (int byte1, int byte2, double timeStamp = 0) noexcept; - - /** Creates a 1-byte short midi message. - - @param byte1 message byte 1 - @param timeStamp the time to give the midi message - this value doesn't - use any particular units, so will be application-specific - */ - MidiMessage (int byte1, double timeStamp = 0) noexcept; - - /** Creates a midi message from a block of data. */ - MidiMessage (const void* data, int numBytes, double timeStamp = 0); - - /** Reads the next midi message from some data. - - This will read as many bytes from a data stream as it needs to make a - complete message, and will return the number of bytes it used. This lets - you read a sequence of midi messages from a file or stream. - - @param data the data to read from - @param maxBytesToUse the maximum number of bytes it's allowed to read - @param numBytesUsed returns the number of bytes that were actually needed - @param lastStatusByte in a sequence of midi messages, the initial byte - can be dropped from a message if it's the same as the - first byte of the previous message, so this lets you - supply the byte to use if the first byte of the message - has in fact been dropped. - @param timeStamp the time to give the midi message - this value doesn't - use any particular units, so will be application-specific - @param sysexHasEmbeddedLength when reading sysexes, this flag indicates whether - to expect the data to begin with a variable-length field - indicating its size - */ - MidiMessage (const void* data, int maxBytesToUse, - int& numBytesUsed, uint8 lastStatusByte, - double timeStamp = 0, - bool sysexHasEmbeddedLength = true); - - /** Creates an active-sense message. - Since the MidiMessage has to contain a valid message, this default constructor - just initialises it with an empty sysex message. - */ - MidiMessage() noexcept; - - /** Creates a copy of another midi message. */ - MidiMessage (const MidiMessage&); - - /** Creates a copy of another midi message, with a different timestamp. */ - MidiMessage (const MidiMessage&, double newTimeStamp); - - /** Destructor. */ - ~MidiMessage(); - - /** Copies this message from another one. */ - MidiMessage& operator= (const MidiMessage& other); - - #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS - MidiMessage (MidiMessage&&) noexcept; - MidiMessage& operator= (MidiMessage&&) noexcept; - #endif - - //============================================================================== - /** Returns a pointer to the raw midi data. - @see getRawDataSize - */ - const uint8* getRawData() const noexcept { return allocatedData != nullptr ? allocatedData.getData() : preallocatedData.asBytes; } - - /** Returns the number of bytes of data in the message. - @see getRawData - */ - int getRawDataSize() const noexcept { return size; } - - //============================================================================== - /** Returns the timestamp associated with this message. - - The exact meaning of this time and its units will vary, as messages are used in - a variety of different contexts. - - If you're getting the message from a midi file, this could be a time in seconds, or - a number of ticks - see MidiFile::convertTimestampTicksToSeconds(). - - If the message is being used in a MidiBuffer, it might indicate the number of - audio samples from the start of the buffer. - - If the message was created by a MidiInput, see MidiInputCallback::handleIncomingMidiMessage() - for details of the way that it initialises this value. - - @see setTimeStamp, addToTimeStamp - */ - double getTimeStamp() const noexcept { return timeStamp; } - - /** Changes the message's associated timestamp. - The units for the timestamp will be application-specific - see the notes for getTimeStamp(). - @see addToTimeStamp, getTimeStamp - */ - void setTimeStamp (double newTimestamp) noexcept { timeStamp = newTimestamp; } - - /** Adds a value to the message's timestamp. - The units for the timestamp will be application-specific. - */ - void addToTimeStamp (double delta) noexcept { timeStamp += delta; } - - //============================================================================== - /** Returns the midi channel associated with the message. - - @returns a value 1 to 16 if the message has a channel, or 0 if it hasn't (e.g. - if it's a sysex) - @see isForChannel, setChannel - */ - int getChannel() const noexcept; - - /** Returns true if the message applies to the given midi channel. - - @param channelNumber the channel number to look for, in the range 1 to 16 - @see getChannel, setChannel - */ - bool isForChannel (int channelNumber) const noexcept; - - /** Changes the message's midi channel. - This won't do anything for non-channel messages like sysexes. - @param newChannelNumber the channel number to change it to, in the range 1 to 16 - */ - void setChannel (int newChannelNumber) noexcept; - - //============================================================================== - /** Returns true if this is a system-exclusive message. - */ - bool isSysEx() const noexcept; - - /** Returns a pointer to the sysex data inside the message. - If this event isn't a sysex event, it'll return 0. - @see getSysExDataSize - */ - const uint8* getSysExData() const noexcept; - - /** Returns the size of the sysex data. - This value excludes the 0xf0 header byte and the 0xf7 at the end. - @see getSysExData - */ - int getSysExDataSize() const noexcept; - - //============================================================================== - /** Returns true if this message is a 'key-down' event. - - @param returnTrueForVelocity0 if true, then if this event is a note-on with - velocity 0, it will still be considered to be a note-on and the - method will return true. If returnTrueForVelocity0 is false, then - if this is a note-on event with velocity 0, it'll be regarded as - a note-off, and the method will return false - - @see isNoteOff, getNoteNumber, getVelocity, noteOn - */ - bool isNoteOn (bool returnTrueForVelocity0 = false) const noexcept; - - /** Creates a key-down message (using a floating-point velocity). - - @param channel the midi channel, in the range 1 to 16 - @param noteNumber the key number, 0 to 127 - @param velocity in the range 0 to 1.0 - @see isNoteOn - */ - static MidiMessage noteOn (int channel, int noteNumber, float velocity) noexcept; - - /** Creates a key-down message (using an integer velocity). - - @param channel the midi channel, in the range 1 to 16 - @param noteNumber the key number, 0 to 127 - @param velocity in the range 0 to 127 - @see isNoteOn - */ - static MidiMessage noteOn (int channel, int noteNumber, uint8 velocity) noexcept; - - /** Returns true if this message is a 'key-up' event. - - If returnTrueForNoteOnVelocity0 is true, then his will also return true - for a note-on event with a velocity of 0. - - @see isNoteOn, getNoteNumber, getVelocity, noteOff - */ - bool isNoteOff (bool returnTrueForNoteOnVelocity0 = true) const noexcept; - - /** Creates a key-up message. - - @param channel the midi channel, in the range 1 to 16 - @param noteNumber the key number, 0 to 127 - @param velocity in the range 0 to 127 - @see isNoteOff - */ - static MidiMessage noteOff (int channel, int noteNumber, uint8 velocity = 0) noexcept; - - /** Returns true if this message is a 'key-down' or 'key-up' event. - - @see isNoteOn, isNoteOff - */ - bool isNoteOnOrOff() const noexcept; - - /** Returns the midi note number for note-on and note-off messages. - If the message isn't a note-on or off, the value returned is undefined. - @see isNoteOff, getMidiNoteName, getMidiNoteInHertz, setNoteNumber - */ - int getNoteNumber() const noexcept; - - /** Changes the midi note number of a note-on or note-off message. - If the message isn't a note on or off, this will do nothing. - */ - void setNoteNumber (int newNoteNumber) noexcept; - - //============================================================================== - /** Returns the velocity of a note-on or note-off message. - - The value returned will be in the range 0 to 127. - If the message isn't a note-on or off event, it will return 0. - - @see getFloatVelocity - */ - uint8 getVelocity() const noexcept; - - /** Returns the velocity of a note-on or note-off message. - - The value returned will be in the range 0 to 1.0 - If the message isn't a note-on or off event, it will return 0. - - @see getVelocity, setVelocity - */ - float getFloatVelocity() const noexcept; - - /** Changes the velocity of a note-on or note-off message. - - If the message isn't a note on or off, this will do nothing. - - @param newVelocity the new velocity, in the range 0 to 1.0 - @see getFloatVelocity, multiplyVelocity - */ - void setVelocity (float newVelocity) noexcept; - - /** Multiplies the velocity of a note-on or note-off message by a given amount. - - If the message isn't a note on or off, this will do nothing. - - @param scaleFactor the value by which to multiply the velocity - @see setVelocity - */ - void multiplyVelocity (float scaleFactor) noexcept; - - //============================================================================== - /** Returns true if this message is a 'sustain pedal down' controller message. */ - bool isSustainPedalOn() const noexcept; - /** Returns true if this message is a 'sustain pedal up' controller message. */ - bool isSustainPedalOff() const noexcept; - - /** Returns true if this message is a 'sostenuto pedal down' controller message. */ - bool isSostenutoPedalOn() const noexcept; - /** Returns true if this message is a 'sostenuto pedal up' controller message. */ - bool isSostenutoPedalOff() const noexcept; - - /** Returns true if this message is a 'soft pedal down' controller message. */ - bool isSoftPedalOn() const noexcept; - /** Returns true if this message is a 'soft pedal up' controller message. */ - bool isSoftPedalOff() const noexcept; - - //============================================================================== - /** Returns true if the message is a program (patch) change message. - @see getProgramChangeNumber, getGMInstrumentName - */ - bool isProgramChange() const noexcept; - - /** Returns the new program number of a program change message. - If the message isn't a program change, the value returned is undefined. - @see isProgramChange, getGMInstrumentName - */ - int getProgramChangeNumber() const noexcept; - - /** Creates a program-change message. - - @param channel the midi channel, in the range 1 to 16 - @param programNumber the midi program number, 0 to 127 - @see isProgramChange, getGMInstrumentName - */ - static MidiMessage programChange (int channel, int programNumber) noexcept; - - //============================================================================== - /** Returns true if the message is a pitch-wheel move. - @see getPitchWheelValue, pitchWheel - */ - bool isPitchWheel() const noexcept; - - /** Returns the pitch wheel position from a pitch-wheel move message. - - The value returned is a 14-bit number from 0 to 0x3fff, indicating the wheel position. - If called for messages which aren't pitch wheel events, the number returned will be - nonsense. - - @see isPitchWheel - */ - int getPitchWheelValue() const noexcept; - - /** Creates a pitch-wheel move message. - - @param channel the midi channel, in the range 1 to 16 - @param position the wheel position, in the range 0 to 16383 - @see isPitchWheel - */ - static MidiMessage pitchWheel (int channel, int position) noexcept; - - //============================================================================== - /** Returns true if the message is an aftertouch event. - - For aftertouch events, use the getNoteNumber() method to find out the key - that it applies to, and getAftertouchValue() to find out the amount. Use - getChannel() to find out the channel. - - @see getAftertouchValue, getNoteNumber - */ - bool isAftertouch() const noexcept; - - /** Returns the amount of aftertouch from an aftertouch messages. - - The value returned is in the range 0 to 127, and will be nonsense for messages - other than aftertouch messages. - - @see isAftertouch - */ - int getAfterTouchValue() const noexcept; - - /** Creates an aftertouch message. - - @param channel the midi channel, in the range 1 to 16 - @param noteNumber the key number, 0 to 127 - @param aftertouchAmount the amount of aftertouch, 0 to 127 - @see isAftertouch - */ - static MidiMessage aftertouchChange (int channel, - int noteNumber, - int aftertouchAmount) noexcept; - - /** Returns true if the message is a channel-pressure change event. - - This is like aftertouch, but common to the whole channel rather than a specific - note. Use getChannelPressureValue() to find out the pressure, and getChannel() - to find out the channel. - - @see channelPressureChange - */ - bool isChannelPressure() const noexcept; - - /** Returns the pressure from a channel pressure change message. - - @returns the pressure, in the range 0 to 127 - @see isChannelPressure, channelPressureChange - */ - int getChannelPressureValue() const noexcept; - - /** Creates a channel-pressure change event. - - @param channel the midi channel: 1 to 16 - @param pressure the pressure, 0 to 127 - @see isChannelPressure - */ - static MidiMessage channelPressureChange (int channel, int pressure) noexcept; - - //============================================================================== - /** Returns true if this is a midi controller message. - - @see getControllerNumber, getControllerValue, controllerEvent - */ - bool isController() const noexcept; - - /** Returns the controller number of a controller message. - - The name of the controller can be looked up using the getControllerName() method. - Note that the value returned is invalid for messages that aren't controller changes. - - @see isController, getControllerName, getControllerValue - */ - int getControllerNumber() const noexcept; - - /** Returns the controller value from a controller message. - - A value 0 to 127 is returned to indicate the new controller position. - Note that the value returned is invalid for messages that aren't controller changes. - - @see isController, getControllerNumber - */ - int getControllerValue() const noexcept; - - /** Returns true if this message is a controller message and if it has the specified - controller type. - */ - bool isControllerOfType (int controllerType) const noexcept; - - /** Creates a controller message. - - @param channel the midi channel, in the range 1 to 16 - @param controllerType the type of controller - @param value the controller value - @see isController - */ - static MidiMessage controllerEvent (int channel, - int controllerType, - int value) noexcept; - - /** Checks whether this message is an all-notes-off message. - @see allNotesOff - */ - bool isAllNotesOff() const noexcept; - - /** Checks whether this message is an all-sound-off message. - @see allSoundOff - */ - bool isAllSoundOff() const noexcept; - - /** Creates an all-notes-off message. - - @param channel the midi channel, in the range 1 to 16 - @see isAllNotesOff - */ - static MidiMessage allNotesOff (int channel) noexcept; - - /** Creates an all-sound-off message. - - @param channel the midi channel, in the range 1 to 16 - @see isAllSoundOff - */ - static MidiMessage allSoundOff (int channel) noexcept; - - /** Creates an all-controllers-off message. - - @param channel the midi channel, in the range 1 to 16 - */ - static MidiMessage allControllersOff (int channel) noexcept; - - //============================================================================== - /** Returns true if this event is a meta-event. - - Meta-events are things like tempo changes, track names, etc. - - @see getMetaEventType, isTrackMetaEvent, isEndOfTrackMetaEvent, - isTextMetaEvent, isTrackNameEvent, isTempoMetaEvent, isTimeSignatureMetaEvent, - isKeySignatureMetaEvent, isMidiChannelMetaEvent - */ - bool isMetaEvent() const noexcept; - - /** Returns a meta-event's type number. - - If the message isn't a meta-event, this will return -1. - - @see isMetaEvent, isTrackMetaEvent, isEndOfTrackMetaEvent, - isTextMetaEvent, isTrackNameEvent, isTempoMetaEvent, isTimeSignatureMetaEvent, - isKeySignatureMetaEvent, isMidiChannelMetaEvent - */ - int getMetaEventType() const noexcept; - - /** Returns a pointer to the data in a meta-event. - @see isMetaEvent, getMetaEventLength - */ - const uint8* getMetaEventData() const noexcept; - - /** Returns the length of the data for a meta-event. - @see isMetaEvent, getMetaEventData - */ - int getMetaEventLength() const noexcept; - - //============================================================================== - /** Returns true if this is a 'track' meta-event. */ - bool isTrackMetaEvent() const noexcept; - - /** Returns true if this is an 'end-of-track' meta-event. */ - bool isEndOfTrackMetaEvent() const noexcept; - - /** Creates an end-of-track meta-event. - @see isEndOfTrackMetaEvent - */ - static MidiMessage endOfTrack() noexcept; - - /** Returns true if this is an 'track name' meta-event. - You can use the getTextFromTextMetaEvent() method to get the track's name. - */ - bool isTrackNameEvent() const noexcept; - - /** Returns true if this is a 'text' meta-event. - @see getTextFromTextMetaEvent - */ - bool isTextMetaEvent() const noexcept; - - /** Returns the text from a text meta-event. - @see isTextMetaEvent - */ - String getTextFromTextMetaEvent() const; - - /** Creates a text meta-event. */ - static MidiMessage textMetaEvent (int type, StringRef text); - - //============================================================================== - /** Returns true if this is a 'tempo' meta-event. - @see getTempoMetaEventTickLength, getTempoSecondsPerQuarterNote - */ - bool isTempoMetaEvent() const noexcept; - - /** Returns the tick length from a tempo meta-event. - - @param timeFormat the 16-bit time format value from the midi file's header. - @returns the tick length (in seconds). - @see isTempoMetaEvent - */ - double getTempoMetaEventTickLength (short timeFormat) const noexcept; - - /** Calculates the seconds-per-quarter-note from a tempo meta-event. - @see isTempoMetaEvent, getTempoMetaEventTickLength - */ - double getTempoSecondsPerQuarterNote() const noexcept; - - /** Creates a tempo meta-event. - @see isTempoMetaEvent - */ - static MidiMessage tempoMetaEvent (int microsecondsPerQuarterNote) noexcept; - - //============================================================================== - /** Returns true if this is a 'time-signature' meta-event. - @see getTimeSignatureInfo - */ - bool isTimeSignatureMetaEvent() const noexcept; - - /** Returns the time-signature values from a time-signature meta-event. - @see isTimeSignatureMetaEvent - */ - void getTimeSignatureInfo (int& numerator, int& denominator) const noexcept; - - /** Creates a time-signature meta-event. - @see isTimeSignatureMetaEvent - */ - static MidiMessage timeSignatureMetaEvent (int numerator, int denominator); - - //============================================================================== - /** Returns true if this is a 'key-signature' meta-event. - @see getKeySignatureNumberOfSharpsOrFlats, isKeySignatureMajorKey - */ - bool isKeySignatureMetaEvent() const noexcept; - - /** Returns the key from a key-signature meta-event. - This method must only be called if isKeySignatureMetaEvent() is true. - A positive number here indicates the number of sharps in the key signature, - and a negative number indicates a number of flats. So e.g. 3 = F# + C# + G#, - -2 = Bb + Eb - @see isKeySignatureMetaEvent, isKeySignatureMajorKey - */ - int getKeySignatureNumberOfSharpsOrFlats() const noexcept; - - /** Returns true if this key-signature event is major, or false if it's minor. - This method must only be called if isKeySignatureMetaEvent() is true. - */ - bool isKeySignatureMajorKey() const noexcept; - - /** Creates a key-signature meta-event. - @param numberOfSharpsOrFlats if positive, this indicates the number of sharps - in the key; if negative, the number of flats - @param isMinorKey if true, the key is minor; if false, it is major - @see isKeySignatureMetaEvent - */ - static MidiMessage keySignatureMetaEvent (int numberOfSharpsOrFlats, bool isMinorKey); - - //============================================================================== - /** Returns true if this is a 'channel' meta-event. - - A channel meta-event specifies the midi channel that should be used - for subsequent meta-events. - - @see getMidiChannelMetaEventChannel - */ - bool isMidiChannelMetaEvent() const noexcept; - - /** Returns the channel number from a channel meta-event. - - @returns the channel, in the range 1 to 16. - @see isMidiChannelMetaEvent - */ - int getMidiChannelMetaEventChannel() const noexcept; - - /** Creates a midi channel meta-event. - - @param channel the midi channel, in the range 1 to 16 - @see isMidiChannelMetaEvent - */ - static MidiMessage midiChannelMetaEvent (int channel) noexcept; - - //============================================================================== - /** Returns true if this is an active-sense message. */ - bool isActiveSense() const noexcept; - - //============================================================================== - /** Returns true if this is a midi start event. - @see midiStart - */ - bool isMidiStart() const noexcept; - - /** Creates a midi start event. */ - static MidiMessage midiStart() noexcept; - - /** Returns true if this is a midi continue event. - @see midiContinue - */ - bool isMidiContinue() const noexcept; - - /** Creates a midi continue event. */ - static MidiMessage midiContinue() noexcept; - - /** Returns true if this is a midi stop event. - @see midiStop - */ - bool isMidiStop() const noexcept; - - /** Creates a midi stop event. */ - static MidiMessage midiStop() noexcept; - - /** Returns true if this is a midi clock event. - @see midiClock, songPositionPointer - */ - bool isMidiClock() const noexcept; - - /** Creates a midi clock event. */ - static MidiMessage midiClock() noexcept; - - /** Returns true if this is a song-position-pointer message. - @see getSongPositionPointerMidiBeat, songPositionPointer - */ - bool isSongPositionPointer() const noexcept; - - /** Returns the midi beat-number of a song-position-pointer message. - @see isSongPositionPointer, songPositionPointer - */ - int getSongPositionPointerMidiBeat() const noexcept; - - /** Creates a song-position-pointer message. - - The position is a number of midi beats from the start of the song, where 1 midi - beat is 6 midi clocks, and there are 24 midi clocks in a quarter-note. So there - are 4 midi beats in a quarter-note. - - @see isSongPositionPointer, getSongPositionPointerMidiBeat - */ - static MidiMessage songPositionPointer (int positionInMidiBeats) noexcept; - - //============================================================================== - /** Returns true if this is a quarter-frame midi timecode message. - @see quarterFrame, getQuarterFrameSequenceNumber, getQuarterFrameValue - */ - bool isQuarterFrame() const noexcept; - - /** Returns the sequence number of a quarter-frame midi timecode message. - This will be a value between 0 and 7. - @see isQuarterFrame, getQuarterFrameValue, quarterFrame - */ - int getQuarterFrameSequenceNumber() const noexcept; - - /** Returns the value from a quarter-frame message. - This will be the lower nybble of the message's data-byte, a value between 0 and 15 - */ - int getQuarterFrameValue() const noexcept; - - /** Creates a quarter-frame MTC message. - - @param sequenceNumber a value 0 to 7 for the upper nybble of the message's data byte - @param value a value 0 to 15 for the lower nybble of the message's data byte - */ - static MidiMessage quarterFrame (int sequenceNumber, int value) noexcept; - - /** SMPTE timecode types. - Used by the getFullFrameParameters() and fullFrame() methods. - */ - enum SmpteTimecodeType - { - fps24 = 0, - fps25 = 1, - fps30drop = 2, - fps30 = 3 - }; - - /** Returns true if this is a full-frame midi timecode message. */ - bool isFullFrame() const noexcept; - - /** Extracts the timecode information from a full-frame midi timecode message. - - You should only call this on messages where you've used isFullFrame() to - check that they're the right kind. - */ - void getFullFrameParameters (int& hours, - int& minutes, - int& seconds, - int& frames, - SmpteTimecodeType& timecodeType) const noexcept; - - /** Creates a full-frame MTC message. */ - static MidiMessage fullFrame (int hours, - int minutes, - int seconds, - int frames, - SmpteTimecodeType timecodeType); - - //============================================================================== - /** Types of MMC command. - - @see isMidiMachineControlMessage, getMidiMachineControlCommand, midiMachineControlCommand - */ - enum MidiMachineControlCommand - { - mmc_stop = 1, - mmc_play = 2, - mmc_deferredplay = 3, - mmc_fastforward = 4, - mmc_rewind = 5, - mmc_recordStart = 6, - mmc_recordStop = 7, - mmc_pause = 9 - }; - - /** Checks whether this is an MMC message. - If it is, you can use the getMidiMachineControlCommand() to find out its type. - */ - bool isMidiMachineControlMessage() const noexcept; - - /** For an MMC message, this returns its type. - - Make sure it's actually an MMC message with isMidiMachineControlMessage() before - calling this method. - */ - MidiMachineControlCommand getMidiMachineControlCommand() const noexcept; - - /** Creates an MMC message. */ - static MidiMessage midiMachineControlCommand (MidiMachineControlCommand command); - - /** Checks whether this is an MMC "goto" message. - If it is, the parameters passed-in are set to the time that the message contains. - @see midiMachineControlGoto - */ - bool isMidiMachineControlGoto (int& hours, - int& minutes, - int& seconds, - int& frames) const noexcept; - - /** Creates an MMC "goto" message. - This messages tells the device to go to a specific frame. - @see isMidiMachineControlGoto - */ - static MidiMessage midiMachineControlGoto (int hours, - int minutes, - int seconds, - int frames); - - //============================================================================== - /** Creates a master-volume change message. - @param volume the volume, 0 to 1.0 - */ - static MidiMessage masterVolume (float volume); - - //============================================================================== - /** Creates a system-exclusive message. - The data passed in is wrapped with header and tail bytes of 0xf0 and 0xf7. - */ - static MidiMessage createSysExMessage (const void* sysexData, - int dataSize); - - - //============================================================================== - /** Reads a midi variable-length integer. - - @param data the data to read the number from - @param numBytesUsed on return, this will be set to the number of bytes that were read - */ - static int readVariableLengthVal (const uint8* data, - int& numBytesUsed) noexcept; - - /** Based on the first byte of a short midi message, this uses a lookup table - to return the message length (either 1, 2, or 3 bytes). - - The value passed in must be 0x80 or higher. - */ - static int getMessageLengthFromFirstByte (const uint8 firstByte) noexcept; - - //============================================================================== - /** Returns the name of a midi note number. - - E.g "C", "D#", etc. - - @param noteNumber the midi note number, 0 to 127 - @param useSharps if true, sharpened notes are used, e.g. "C#", otherwise - they'll be flattened, e.g. "Db" - @param includeOctaveNumber if true, the octave number will be appended to the string, - e.g. "C#4" - @param octaveNumForMiddleC if an octave number is being appended, this indicates the - number that will be used for middle C's octave - - @see getMidiNoteInHertz - */ - static String getMidiNoteName (int noteNumber, - bool useSharps, - bool includeOctaveNumber, - int octaveNumForMiddleC); - - /** Returns the frequency of a midi note number. - - The frequencyOfA parameter is an optional frequency for 'A', normally 440-444Hz for concert pitch. - @see getMidiNoteName - */ - static double getMidiNoteInHertz (int noteNumber, const double frequencyOfA = 440.0) noexcept; - - /** Returns true if the given midi note number is a black key. */ - static bool isMidiNoteBlack (int noteNumber) noexcept; - - /** Returns the standard name of a GM instrument, or nullptr if unknown for this index. - - @param midiInstrumentNumber the program number 0 to 127 - @see getProgramChangeNumber - */ - static const char* getGMInstrumentName (int midiInstrumentNumber); - - /** Returns the name of a bank of GM instruments, or nullptr if unknown for this bank number. - @param midiBankNumber the bank, 0 to 15 - */ - static const char* getGMInstrumentBankName (int midiBankNumber); - - /** Returns the standard name of a channel 10 percussion sound, or nullptr if unknown for this note number. - @param midiNoteNumber the key number, 35 to 81 - */ - static const char* getRhythmInstrumentName (int midiNoteNumber); - - /** Returns the name of a controller type number, or nullptr if unknown for this controller number. - @see getControllerNumber - */ - static const char* getControllerName (int controllerNumber); - -private: - //============================================================================== - double timeStamp; - HeapBlock allocatedData; - int size; - - #ifndef DOXYGEN - union - { - uint8 asBytes[4]; - uint32 asInt32; - } preallocatedData; - #endif - - inline uint8* getData() noexcept { return allocatedData != nullptr ? allocatedData.getData() : preallocatedData.asBytes; } - uint8* allocateSpace (int); -}; - -#endif // JUCE_MIDIMESSAGE_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/midi/juce_MidiMessageSequence.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/midi/juce_MidiMessageSequence.cpp deleted file mode 100644 index 94a6b9bcfd..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/midi/juce_MidiMessageSequence.cpp +++ /dev/null @@ -1,331 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -MidiMessageSequence::MidiMessageSequence() -{ -} - -MidiMessageSequence::MidiMessageSequence (const MidiMessageSequence& other) -{ - list.addCopiesOf (other.list); - updateMatchedPairs(); -} - -MidiMessageSequence& MidiMessageSequence::operator= (const MidiMessageSequence& other) -{ - MidiMessageSequence otherCopy (other); - swapWith (otherCopy); - return *this; -} - -void MidiMessageSequence::swapWith (MidiMessageSequence& other) noexcept -{ - list.swapWith (other.list); -} - -MidiMessageSequence::~MidiMessageSequence() -{ -} - -void MidiMessageSequence::clear() -{ - list.clear(); -} - -int MidiMessageSequence::getNumEvents() const noexcept -{ - return list.size(); -} - -MidiMessageSequence::MidiEventHolder* MidiMessageSequence::getEventPointer (const int index) const noexcept -{ - return list [index]; -} - -double MidiMessageSequence::getTimeOfMatchingKeyUp (const int index) const noexcept -{ - if (const MidiEventHolder* const meh = list [index]) - if (meh->noteOffObject != nullptr) - return meh->noteOffObject->message.getTimeStamp(); - - return 0.0; -} - -int MidiMessageSequence::getIndexOfMatchingKeyUp (const int index) const noexcept -{ - if (const MidiEventHolder* const meh = list [index]) - return list.indexOf (meh->noteOffObject); - - return -1; -} - -int MidiMessageSequence::getIndexOf (MidiEventHolder* const event) const noexcept -{ - return list.indexOf (event); -} - -int MidiMessageSequence::getNextIndexAtTime (const double timeStamp) const noexcept -{ - const int numEvents = list.size(); - - int i; - for (i = 0; i < numEvents; ++i) - if (list.getUnchecked(i)->message.getTimeStamp() >= timeStamp) - break; - - return i; -} - -//============================================================================== -double MidiMessageSequence::getStartTime() const noexcept -{ - return getEventTime (0); -} - -double MidiMessageSequence::getEndTime() const noexcept -{ - return getEventTime (list.size() - 1); -} - -double MidiMessageSequence::getEventTime (const int index) const noexcept -{ - if (const MidiEventHolder* const meh = list [index]) - return meh->message.getTimeStamp(); - - return 0.0; -} - -//============================================================================== -MidiMessageSequence::MidiEventHolder* MidiMessageSequence::addEvent (const MidiMessage& newMessage, - double timeAdjustment) -{ - MidiEventHolder* const newOne = new MidiEventHolder (newMessage); - - timeAdjustment += newMessage.getTimeStamp(); - newOne->message.setTimeStamp (timeAdjustment); - - int i; - for (i = list.size(); --i >= 0;) - if (list.getUnchecked(i)->message.getTimeStamp() <= timeAdjustment) - break; - - list.insert (i + 1, newOne); - return newOne; -} - -void MidiMessageSequence::deleteEvent (const int index, - const bool deleteMatchingNoteUp) -{ - if (isPositiveAndBelow (index, list.size())) - { - if (deleteMatchingNoteUp) - deleteEvent (getIndexOfMatchingKeyUp (index), false); - - list.remove (index); - } -} - -struct MidiMessageSequenceSorter -{ - static int compareElements (const MidiMessageSequence::MidiEventHolder* const first, - const MidiMessageSequence::MidiEventHolder* const second) noexcept - { - const double diff = first->message.getTimeStamp() - second->message.getTimeStamp(); - return (diff > 0) - (diff < 0); - } -}; - -void MidiMessageSequence::addSequence (const MidiMessageSequence& other, - double timeAdjustment, - double firstAllowableTime, - double endOfAllowableDestTimes) -{ - firstAllowableTime -= timeAdjustment; - endOfAllowableDestTimes -= timeAdjustment; - - for (int i = 0; i < other.list.size(); ++i) - { - const MidiMessage& m = other.list.getUnchecked(i)->message; - const double t = m.getTimeStamp(); - - if (t >= firstAllowableTime && t < endOfAllowableDestTimes) - { - MidiEventHolder* const newOne = new MidiEventHolder (m); - newOne->message.setTimeStamp (timeAdjustment + t); - - list.add (newOne); - } - } - - sort(); -} - -//============================================================================== -void MidiMessageSequence::sort() noexcept -{ - MidiMessageSequenceSorter sorter; - list.sort (sorter, true); -} - -void MidiMessageSequence::updateMatchedPairs() noexcept -{ - for (int i = 0; i < list.size(); ++i) - { - MidiEventHolder* const meh = list.getUnchecked(i); - const MidiMessage& m1 = meh->message; - - if (m1.isNoteOn()) - { - meh->noteOffObject = nullptr; - const int note = m1.getNoteNumber(); - const int chan = m1.getChannel(); - const int len = list.size(); - - for (int j = i + 1; j < len; ++j) - { - const MidiMessage& m = list.getUnchecked(j)->message; - - if (m.getNoteNumber() == note && m.getChannel() == chan) - { - if (m.isNoteOff()) - { - meh->noteOffObject = list[j]; - break; - } - else if (m.isNoteOn()) - { - MidiEventHolder* const newEvent = new MidiEventHolder (MidiMessage::noteOff (chan, note)); - list.insert (j, newEvent); - newEvent->message.setTimeStamp (m.getTimeStamp()); - meh->noteOffObject = newEvent; - break; - } - } - } - } - } -} - -void MidiMessageSequence::addTimeToMessages (const double delta) noexcept -{ - for (int i = list.size(); --i >= 0;) - { - MidiMessage& mm = list.getUnchecked(i)->message; - mm.setTimeStamp (mm.getTimeStamp() + delta); - } -} - -//============================================================================== -void MidiMessageSequence::extractMidiChannelMessages (const int channelNumberToExtract, - MidiMessageSequence& destSequence, - const bool alsoIncludeMetaEvents) const -{ - for (int i = 0; i < list.size(); ++i) - { - const MidiMessage& mm = list.getUnchecked(i)->message; - - if (mm.isForChannel (channelNumberToExtract) || (alsoIncludeMetaEvents && mm.isMetaEvent())) - destSequence.addEvent (mm); - } -} - -void MidiMessageSequence::extractSysExMessages (MidiMessageSequence& destSequence) const -{ - for (int i = 0; i < list.size(); ++i) - { - const MidiMessage& mm = list.getUnchecked(i)->message; - - if (mm.isSysEx()) - destSequence.addEvent (mm); - } -} - -void MidiMessageSequence::deleteMidiChannelMessages (const int channelNumberToRemove) -{ - for (int i = list.size(); --i >= 0;) - if (list.getUnchecked(i)->message.isForChannel (channelNumberToRemove)) - list.remove(i); -} - -void MidiMessageSequence::deleteSysExMessages() -{ - for (int i = list.size(); --i >= 0;) - if (list.getUnchecked(i)->message.isSysEx()) - list.remove(i); -} - -//============================================================================== -void MidiMessageSequence::createControllerUpdatesForTime (const int channelNumber, - const double time, - OwnedArray& dest) -{ - bool doneProg = false; - bool donePitchWheel = false; - Array doneControllers; - doneControllers.ensureStorageAllocated (32); - - for (int i = list.size(); --i >= 0;) - { - const MidiMessage& mm = list.getUnchecked(i)->message; - - if (mm.isForChannel (channelNumber) && mm.getTimeStamp() <= time) - { - if (mm.isProgramChange()) - { - if (! doneProg) - { - dest.add (new MidiMessage (mm, 0.0)); - doneProg = true; - } - } - else if (mm.isController()) - { - if (! doneControllers.contains (mm.getControllerNumber())) - { - dest.add (new MidiMessage (mm, 0.0)); - doneControllers.add (mm.getControllerNumber()); - } - } - else if (mm.isPitchWheel()) - { - if (! donePitchWheel) - { - dest.add (new MidiMessage (mm, 0.0)); - donePitchWheel = true; - } - } - } - } -} - - -//============================================================================== -MidiMessageSequence::MidiEventHolder::MidiEventHolder (const MidiMessage& mm) - : message (mm), noteOffObject (nullptr) -{ -} - -MidiMessageSequence::MidiEventHolder::~MidiEventHolder() -{ -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/midi/juce_MidiMessageSequence.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/midi/juce_MidiMessageSequence.h deleted file mode 100644 index b62940c2d0..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/midi/juce_MidiMessageSequence.h +++ /dev/null @@ -1,265 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_MIDIMESSAGESEQUENCE_H_INCLUDED -#define JUCE_MIDIMESSAGESEQUENCE_H_INCLUDED - - -//============================================================================== -/** - A sequence of timestamped midi messages. - - This allows the sequence to be manipulated, and also to be read from and - written to a standard midi file. - - @see MidiMessage, MidiFile -*/ -class JUCE_API MidiMessageSequence -{ -public: - //============================================================================== - /** Creates an empty midi sequence object. */ - MidiMessageSequence(); - - /** Creates a copy of another sequence. */ - MidiMessageSequence (const MidiMessageSequence&); - - /** Replaces this sequence with another one. */ - MidiMessageSequence& operator= (const MidiMessageSequence&); - - /** Destructor. */ - ~MidiMessageSequence(); - - //============================================================================== - /** Structure used to hold midi events in the sequence. - - These structures act as 'handles' on the events as they are moved about in - the list, and make it quick to find the matching note-offs for note-on events. - - @see MidiMessageSequence::getEventPointer - */ - class MidiEventHolder - { - public: - //============================================================================== - /** Destructor. */ - ~MidiEventHolder(); - - /** The message itself, whose timestamp is used to specify the event's time. */ - MidiMessage message; - - /** The matching note-off event (if this is a note-on event). - - If this isn't a note-on, this pointer will be nullptr. - - Use the MidiMessageSequence::updateMatchedPairs() method to keep these - note-offs up-to-date after events have been moved around in the sequence - or deleted. - */ - MidiEventHolder* noteOffObject; - - private: - //============================================================================== - friend class MidiMessageSequence; - MidiEventHolder (const MidiMessage&); - JUCE_LEAK_DETECTOR (MidiEventHolder) - }; - - //============================================================================== - /** Clears the sequence. */ - void clear(); - - /** Returns the number of events in the sequence. */ - int getNumEvents() const noexcept; - - /** Returns a pointer to one of the events. */ - MidiEventHolder* getEventPointer (int index) const noexcept; - - /** Returns the time of the note-up that matches the note-on at this index. - If the event at this index isn't a note-on, it'll just return 0. - @see MidiMessageSequence::MidiEventHolder::noteOffObject - */ - double getTimeOfMatchingKeyUp (int index) const noexcept; - - /** Returns the index of the note-up that matches the note-on at this index. - If the event at this index isn't a note-on, it'll just return -1. - @see MidiMessageSequence::MidiEventHolder::noteOffObject - */ - int getIndexOfMatchingKeyUp (int index) const noexcept; - - /** Returns the index of an event. */ - int getIndexOf (MidiEventHolder* event) const noexcept; - - /** Returns the index of the first event on or after the given timestamp. - If the time is beyond the end of the sequence, this will return the - number of events. - */ - int getNextIndexAtTime (double timeStamp) const noexcept; - - //============================================================================== - /** Returns the timestamp of the first event in the sequence. - @see getEndTime - */ - double getStartTime() const noexcept; - - /** Returns the timestamp of the last event in the sequence. - @see getStartTime - */ - double getEndTime() const noexcept; - - /** Returns the timestamp of the event at a given index. - If the index is out-of-range, this will return 0.0 - */ - double getEventTime (int index) const noexcept; - - //============================================================================== - /** Inserts a midi message into the sequence. - - The index at which the new message gets inserted will depend on its timestamp, - because the sequence is kept sorted. - - Remember to call updateMatchedPairs() after adding note-on events. - - @param newMessage the new message to add (an internal copy will be made) - @param timeAdjustment an optional value to add to the timestamp of the message - that will be inserted - @see updateMatchedPairs - */ - MidiEventHolder* addEvent (const MidiMessage& newMessage, - double timeAdjustment = 0); - - /** Deletes one of the events in the sequence. - - Remember to call updateMatchedPairs() after removing events. - - @param index the index of the event to delete - @param deleteMatchingNoteUp whether to also remove the matching note-off - if the event you're removing is a note-on - */ - void deleteEvent (int index, bool deleteMatchingNoteUp); - - /** Merges another sequence into this one. - - Remember to call updateMatchedPairs() after using this method. - - @param other the sequence to add from - @param timeAdjustmentDelta an amount to add to the timestamps of the midi events - as they are read from the other sequence - @param firstAllowableDestTime events will not be added if their time is earlier - than this time. (This is after their time has been adjusted - by the timeAdjustmentDelta) - @param endOfAllowableDestTimes events will not be added if their time is equal to - or greater than this time. (This is after their time has - been adjusted by the timeAdjustmentDelta) - */ - void addSequence (const MidiMessageSequence& other, - double timeAdjustmentDelta, - double firstAllowableDestTime, - double endOfAllowableDestTimes); - - //============================================================================== - /** Makes sure all the note-on and note-off pairs are up-to-date. - - Call this after re-ordering messages or deleting/adding messages, and it - will scan the list and make sure all the note-offs in the MidiEventHolder - structures are pointing at the correct ones. - */ - void updateMatchedPairs() noexcept; - - /** Forces a sort of the sequence. - You may need to call this if you've manually modified the timestamps of some - events such that the overall order now needs updating. - */ - void sort() noexcept; - - //============================================================================== - /** Copies all the messages for a particular midi channel to another sequence. - - @param channelNumberToExtract the midi channel to look for, in the range 1 to 16 - @param destSequence the sequence that the chosen events should be copied to - @param alsoIncludeMetaEvents if true, any meta-events (which don't apply to a specific - channel) will also be copied across. - @see extractSysExMessages - */ - void extractMidiChannelMessages (int channelNumberToExtract, - MidiMessageSequence& destSequence, - bool alsoIncludeMetaEvents) const; - - /** Copies all midi sys-ex messages to another sequence. - @param destSequence this is the sequence to which any sys-exes in this sequence - will be added - @see extractMidiChannelMessages - */ - void extractSysExMessages (MidiMessageSequence& destSequence) const; - - /** Removes any messages in this sequence that have a specific midi channel. - @param channelNumberToRemove the midi channel to look for, in the range 1 to 16 - */ - void deleteMidiChannelMessages (int channelNumberToRemove); - - /** Removes any sys-ex messages from this sequence. */ - void deleteSysExMessages(); - - /** Adds an offset to the timestamps of all events in the sequence. - @param deltaTime the amount to add to each timestamp. - */ - void addTimeToMessages (double deltaTime) noexcept; - - //============================================================================== - /** Scans through the sequence to determine the state of any midi controllers at - a given time. - - This will create a sequence of midi controller changes that can be - used to set all midi controllers to the state they would be in at the - specified time within this sequence. - - As well as controllers, it will also recreate the midi program number - and pitch bend position. - - @param channelNumber the midi channel to look for, in the range 1 to 16. Controllers - for other channels will be ignored. - @param time the time at which you want to find out the state - there are - no explicit units for this time measurement, it's the same units - as used for the timestamps of the messages - @param resultMessages an array to which midi controller-change messages will be added. This - will be the minimum number of controller changes to recreate the - state at the required time. - */ - void createControllerUpdatesForTime (int channelNumber, double time, - OwnedArray& resultMessages); - - //============================================================================== - /** Swaps this sequence with another one. */ - void swapWith (MidiMessageSequence&) noexcept; - -private: - //============================================================================== - friend class MidiFile; - OwnedArray list; - - JUCE_LEAK_DETECTOR (MidiMessageSequence) -}; - - -#endif // JUCE_MIDIMESSAGESEQUENCE_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/sources/juce_AudioSource.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/sources/juce_AudioSource.h deleted file mode 100644 index cfbd59fe98..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/sources/juce_AudioSource.h +++ /dev/null @@ -1,181 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_AUDIOSOURCE_H_INCLUDED -#define JUCE_AUDIOSOURCE_H_INCLUDED - - -//============================================================================== -/** - Used by AudioSource::getNextAudioBlock(). -*/ -struct JUCE_API AudioSourceChannelInfo -{ - /** Creates an uninitialised AudioSourceChannelInfo. */ - AudioSourceChannelInfo() noexcept - { - } - - /** Creates an AudioSourceChannelInfo. */ - AudioSourceChannelInfo (AudioSampleBuffer* bufferToUse, - int startSampleOffset, int numSamplesToUse) noexcept - : buffer (bufferToUse), - startSample (startSampleOffset), - numSamples (numSamplesToUse) - { - } - - /** Creates an AudioSourceChannelInfo that uses the whole of a buffer. - Note that the buffer provided must not be deleted while the - AudioSourceChannelInfo is still using it. - */ - explicit AudioSourceChannelInfo (AudioSampleBuffer& bufferToUse) noexcept - : buffer (&bufferToUse), - startSample (0), - numSamples (bufferToUse.getNumSamples()) - { - } - - /** The destination buffer to fill with audio data. - - When the AudioSource::getNextAudioBlock() method is called, the active section - of this buffer should be filled with whatever output the source produces. - - Only the samples specified by the startSample and numSamples members of this structure - should be affected by the call. - - The contents of the buffer when it is passed to the AudioSource::getNextAudioBlock() - method can be treated as the input if the source is performing some kind of filter operation, - but should be cleared if this is not the case - the clearActiveBufferRegion() is - a handy way of doing this. - - The number of channels in the buffer could be anything, so the AudioSource - must cope with this in whatever way is appropriate for its function. - */ - AudioSampleBuffer* buffer; - - /** The first sample in the buffer from which the callback is expected - to write data. */ - int startSample; - - /** The number of samples in the buffer which the callback is expected to - fill with data. */ - int numSamples; - - /** Convenient method to clear the buffer if the source is not producing any data. */ - void clearActiveBufferRegion() const - { - if (buffer != nullptr) - buffer->clear (startSample, numSamples); - } -}; - - -//============================================================================== -/** - Base class for objects that can produce a continuous stream of audio. - - An AudioSource has two states: 'prepared' and 'unprepared'. - - When a source needs to be played, it is first put into a 'prepared' state by a call to - prepareToPlay(), and then repeated calls will be made to its getNextAudioBlock() method to - process the audio data. - - Once playback has finished, the releaseResources() method is called to put the stream - back into an 'unprepared' state. - - @see AudioFormatReaderSource, ResamplingAudioSource -*/ -class JUCE_API AudioSource -{ -protected: - //============================================================================== - /** Creates an AudioSource. */ - AudioSource() noexcept {} - -public: - /** Destructor. */ - virtual ~AudioSource() {} - - //============================================================================== - /** Tells the source to prepare for playing. - - An AudioSource has two states: prepared and unprepared. - - The prepareToPlay() method is guaranteed to be called at least once on an 'unpreprared' - source to put it into a 'prepared' state before any calls will be made to getNextAudioBlock(). - This callback allows the source to initialise any resources it might need when playing. - - Once playback has finished, the releaseResources() method is called to put the stream - back into an 'unprepared' state. - - Note that this method could be called more than once in succession without - a matching call to releaseResources(), so make sure your code is robust and - can handle that kind of situation. - - @param samplesPerBlockExpected the number of samples that the source - will be expected to supply each time its - getNextAudioBlock() method is called. This - number may vary slightly, because it will be dependent - on audio hardware callbacks, and these aren't - guaranteed to always use a constant block size, so - the source should be able to cope with small variations. - @param sampleRate the sample rate that the output will be used at - this - is needed by sources such as tone generators. - @see releaseResources, getNextAudioBlock - */ - virtual void prepareToPlay (int samplesPerBlockExpected, - double sampleRate) = 0; - - /** Allows the source to release anything it no longer needs after playback has stopped. - - This will be called when the source is no longer going to have its getNextAudioBlock() - method called, so it should release any spare memory, etc. that it might have - allocated during the prepareToPlay() call. - - Note that there's no guarantee that prepareToPlay() will actually have been called before - releaseResources(), and it may be called more than once in succession, so make sure your - code is robust and doesn't make any assumptions about when it will be called. - - @see prepareToPlay, getNextAudioBlock - */ - virtual void releaseResources() = 0; - - /** Called repeatedly to fetch subsequent blocks of audio data. - - After calling the prepareToPlay() method, this callback will be made each - time the audio playback hardware (or whatever other destination the audio - data is going to) needs another block of data. - - It will generally be called on a high-priority system thread, or possibly even - an interrupt, so be careful not to do too much work here, as that will cause - audio glitches! - - @see AudioSourceChannelInfo, prepareToPlay, releaseResources - */ - virtual void getNextAudioBlock (const AudioSourceChannelInfo& bufferToFill) = 0; -}; - - -#endif // JUCE_AUDIOSOURCE_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/sources/juce_BufferingAudioSource.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/sources/juce_BufferingAudioSource.cpp deleted file mode 100644 index 21dc173a60..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/sources/juce_BufferingAudioSource.cpp +++ /dev/null @@ -1,259 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -BufferingAudioSource::BufferingAudioSource (PositionableAudioSource* s, - TimeSliceThread& thread, - const bool deleteSourceWhenDeleted, - const int bufferSizeSamples, - const int numChannels) - : source (s, deleteSourceWhenDeleted), - backgroundThread (thread), - numberOfSamplesToBuffer (jmax (1024, bufferSizeSamples)), - numberOfChannels (numChannels), - bufferValidStart (0), - bufferValidEnd (0), - nextPlayPos (0), - sampleRate (0), - wasSourceLooping (false), - isPrepared (false) -{ - jassert (source != nullptr); - - jassert (numberOfSamplesToBuffer > 1024); // not much point using this class if you're - // not using a larger buffer.. -} - -BufferingAudioSource::~BufferingAudioSource() -{ - releaseResources(); -} - -//============================================================================== -void BufferingAudioSource::prepareToPlay (int samplesPerBlockExpected, double newSampleRate) -{ - const int bufferSizeNeeded = jmax (samplesPerBlockExpected * 2, numberOfSamplesToBuffer); - - if (newSampleRate != sampleRate - || bufferSizeNeeded != buffer.getNumSamples() - || ! isPrepared) - { - backgroundThread.removeTimeSliceClient (this); - - isPrepared = true; - sampleRate = newSampleRate; - - source->prepareToPlay (samplesPerBlockExpected, newSampleRate); - - buffer.setSize (numberOfChannels, bufferSizeNeeded); - buffer.clear(); - - bufferValidStart = 0; - bufferValidEnd = 0; - - backgroundThread.addTimeSliceClient (this); - - while (bufferValidEnd - bufferValidStart < jmin (((int) newSampleRate) / 4, - buffer.getNumSamples() / 2)) - { - backgroundThread.moveToFrontOfQueue (this); - Thread::sleep (5); - } - } -} - -void BufferingAudioSource::releaseResources() -{ - isPrepared = false; - backgroundThread.removeTimeSliceClient (this); - - buffer.setSize (numberOfChannels, 0); - source->releaseResources(); -} - -void BufferingAudioSource::getNextAudioBlock (const AudioSourceChannelInfo& info) -{ - const ScopedLock sl (bufferStartPosLock); - - const int validStart = (int) (jlimit (bufferValidStart, bufferValidEnd, nextPlayPos) - nextPlayPos); - const int validEnd = (int) (jlimit (bufferValidStart, bufferValidEnd, nextPlayPos + info.numSamples) - nextPlayPos); - - if (validStart == validEnd) - { - // total cache miss - info.clearActiveBufferRegion(); - } - else - { - if (validStart > 0) - info.buffer->clear (info.startSample, validStart); // partial cache miss at start - - if (validEnd < info.numSamples) - info.buffer->clear (info.startSample + validEnd, - info.numSamples - validEnd); // partial cache miss at end - - if (validStart < validEnd) - { - for (int chan = jmin (numberOfChannels, info.buffer->getNumChannels()); --chan >= 0;) - { - jassert (buffer.getNumSamples() > 0); - const int startBufferIndex = (int) ((validStart + nextPlayPos) % buffer.getNumSamples()); - const int endBufferIndex = (int) ((validEnd + nextPlayPos) % buffer.getNumSamples()); - - if (startBufferIndex < endBufferIndex) - { - info.buffer->copyFrom (chan, info.startSample + validStart, - buffer, - chan, startBufferIndex, - validEnd - validStart); - } - else - { - const int initialSize = buffer.getNumSamples() - startBufferIndex; - - info.buffer->copyFrom (chan, info.startSample + validStart, - buffer, - chan, startBufferIndex, - initialSize); - - info.buffer->copyFrom (chan, info.startSample + validStart + initialSize, - buffer, - chan, 0, - (validEnd - validStart) - initialSize); - } - } - } - - nextPlayPos += info.numSamples; - } -} - -int64 BufferingAudioSource::getNextReadPosition() const -{ - jassert (source->getTotalLength() > 0); - return (source->isLooping() && nextPlayPos > 0) - ? nextPlayPos % source->getTotalLength() - : nextPlayPos; -} - -void BufferingAudioSource::setNextReadPosition (int64 newPosition) -{ - const ScopedLock sl (bufferStartPosLock); - - nextPlayPos = newPosition; - backgroundThread.moveToFrontOfQueue (this); -} - -bool BufferingAudioSource::readNextBufferChunk() -{ - int64 newBVS, newBVE, sectionToReadStart, sectionToReadEnd; - - { - const ScopedLock sl (bufferStartPosLock); - - if (wasSourceLooping != isLooping()) - { - wasSourceLooping = isLooping(); - bufferValidStart = 0; - bufferValidEnd = 0; - } - - newBVS = jmax ((int64) 0, nextPlayPos); - newBVE = newBVS + buffer.getNumSamples() - 4; - sectionToReadStart = 0; - sectionToReadEnd = 0; - - const int maxChunkSize = 2048; - - if (newBVS < bufferValidStart || newBVS >= bufferValidEnd) - { - newBVE = jmin (newBVE, newBVS + maxChunkSize); - - sectionToReadStart = newBVS; - sectionToReadEnd = newBVE; - - bufferValidStart = 0; - bufferValidEnd = 0; - } - else if (std::abs ((int) (newBVS - bufferValidStart)) > 512 - || std::abs ((int) (newBVE - bufferValidEnd)) > 512) - { - newBVE = jmin (newBVE, bufferValidEnd + maxChunkSize); - - sectionToReadStart = bufferValidEnd; - sectionToReadEnd = newBVE; - - bufferValidStart = newBVS; - bufferValidEnd = jmin (bufferValidEnd, newBVE); - } - } - - if (sectionToReadStart == sectionToReadEnd) - return false; - - jassert (buffer.getNumSamples() > 0); - const int bufferIndexStart = (int) (sectionToReadStart % buffer.getNumSamples()); - const int bufferIndexEnd = (int) (sectionToReadEnd % buffer.getNumSamples()); - - if (bufferIndexStart < bufferIndexEnd) - { - readBufferSection (sectionToReadStart, - (int) (sectionToReadEnd - sectionToReadStart), - bufferIndexStart); - } - else - { - const int initialSize = buffer.getNumSamples() - bufferIndexStart; - - readBufferSection (sectionToReadStart, - initialSize, - bufferIndexStart); - - readBufferSection (sectionToReadStart + initialSize, - (int) (sectionToReadEnd - sectionToReadStart) - initialSize, - 0); - } - - { - const ScopedLock sl2 (bufferStartPosLock); - - bufferValidStart = newBVS; - bufferValidEnd = newBVE; - } - - return true; -} - -void BufferingAudioSource::readBufferSection (const int64 start, const int length, const int bufferOffset) -{ - if (source->getNextReadPosition() != start) - source->setNextReadPosition (start); - - AudioSourceChannelInfo info (&buffer, bufferOffset, length); - source->getNextAudioBlock (info); -} - -int BufferingAudioSource::useTimeSlice() -{ - return readNextBufferChunk() ? 1 : 100; -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/sources/juce_BufferingAudioSource.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/sources/juce_BufferingAudioSource.h deleted file mode 100644 index b0ab4d2f75..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/sources/juce_BufferingAudioSource.h +++ /dev/null @@ -1,111 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_BUFFERINGAUDIOSOURCE_H_INCLUDED -#define JUCE_BUFFERINGAUDIOSOURCE_H_INCLUDED - - -//============================================================================== -/** - An AudioSource which takes another source as input, and buffers it using a thread. - - Create this as a wrapper around another thread, and it will read-ahead with - a background thread to smooth out playback. You can either create one of these - directly, or use it indirectly using an AudioTransportSource. - - @see PositionableAudioSource, AudioTransportSource -*/ -class JUCE_API BufferingAudioSource : public PositionableAudioSource, - private TimeSliceClient -{ -public: - //============================================================================== - /** Creates a BufferingAudioSource. - - @param source the input source to read from - @param backgroundThread a background thread that will be used for the - background read-ahead. This object must not be deleted - until after any BufferedAudioSources that are using it - have been deleted! - @param deleteSourceWhenDeleted if true, then the input source object will - be deleted when this object is deleted - @param numberOfSamplesToBuffer the size of buffer to use for reading ahead - @param numberOfChannels the number of channels that will be played - */ - BufferingAudioSource (PositionableAudioSource* source, - TimeSliceThread& backgroundThread, - bool deleteSourceWhenDeleted, - int numberOfSamplesToBuffer, - int numberOfChannels = 2); - - /** Destructor. - - The input source may be deleted depending on whether the deleteSourceWhenDeleted - flag was set in the constructor. - */ - ~BufferingAudioSource(); - - //============================================================================== - /** Implementation of the AudioSource method. */ - void prepareToPlay (int samplesPerBlockExpected, double sampleRate) override; - - /** Implementation of the AudioSource method. */ - void releaseResources() override; - - /** Implementation of the AudioSource method. */ - void getNextAudioBlock (const AudioSourceChannelInfo&) override; - - //============================================================================== - /** Implements the PositionableAudioSource method. */ - void setNextReadPosition (int64 newPosition) override; - - /** Implements the PositionableAudioSource method. */ - int64 getNextReadPosition() const override; - - /** Implements the PositionableAudioSource method. */ - int64 getTotalLength() const override { return source->getTotalLength(); } - - /** Implements the PositionableAudioSource method. */ - bool isLooping() const override { return source->isLooping(); } - -private: - //============================================================================== - OptionalScopedPointer source; - TimeSliceThread& backgroundThread; - int numberOfSamplesToBuffer, numberOfChannels; - AudioSampleBuffer buffer; - CriticalSection bufferStartPosLock; - int64 volatile bufferValidStart, bufferValidEnd, nextPlayPos; - double volatile sampleRate; - bool wasSourceLooping, isPrepared; - - bool readNextBufferChunk(); - void readBufferSection (int64 start, int length, int bufferOffset); - int useTimeSlice() override; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (BufferingAudioSource) -}; - - -#endif // JUCE_BUFFERINGAUDIOSOURCE_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/sources/juce_ChannelRemappingAudioSource.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/sources/juce_ChannelRemappingAudioSource.cpp deleted file mode 100644 index 7e0a58cb46..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/sources/juce_ChannelRemappingAudioSource.cpp +++ /dev/null @@ -1,184 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -ChannelRemappingAudioSource::ChannelRemappingAudioSource (AudioSource* const source_, - const bool deleteSourceWhenDeleted) - : source (source_, deleteSourceWhenDeleted), - requiredNumberOfChannels (2) -{ - remappedInfo.buffer = &buffer; - remappedInfo.startSample = 0; -} - -ChannelRemappingAudioSource::~ChannelRemappingAudioSource() {} - -//============================================================================== -void ChannelRemappingAudioSource::setNumberOfChannelsToProduce (const int requiredNumberOfChannels_) -{ - const ScopedLock sl (lock); - requiredNumberOfChannels = requiredNumberOfChannels_; -} - -void ChannelRemappingAudioSource::clearAllMappings() -{ - const ScopedLock sl (lock); - - remappedInputs.clear(); - remappedOutputs.clear(); -} - -void ChannelRemappingAudioSource::setInputChannelMapping (const int destIndex, const int sourceIndex) -{ - const ScopedLock sl (lock); - - while (remappedInputs.size() < destIndex) - remappedInputs.add (-1); - - remappedInputs.set (destIndex, sourceIndex); -} - -void ChannelRemappingAudioSource::setOutputChannelMapping (const int sourceIndex, const int destIndex) -{ - const ScopedLock sl (lock); - - while (remappedOutputs.size() < sourceIndex) - remappedOutputs.add (-1); - - remappedOutputs.set (sourceIndex, destIndex); -} - -int ChannelRemappingAudioSource::getRemappedInputChannel (const int inputChannelIndex) const -{ - const ScopedLock sl (lock); - - if (inputChannelIndex >= 0 && inputChannelIndex < remappedInputs.size()) - return remappedInputs.getUnchecked (inputChannelIndex); - - return -1; -} - -int ChannelRemappingAudioSource::getRemappedOutputChannel (const int outputChannelIndex) const -{ - const ScopedLock sl (lock); - - if (outputChannelIndex >= 0 && outputChannelIndex < remappedOutputs.size()) - return remappedOutputs .getUnchecked (outputChannelIndex); - - return -1; -} - -//============================================================================== -void ChannelRemappingAudioSource::prepareToPlay (int samplesPerBlockExpected, double sampleRate) -{ - source->prepareToPlay (samplesPerBlockExpected, sampleRate); -} - -void ChannelRemappingAudioSource::releaseResources() -{ - source->releaseResources(); -} - -void ChannelRemappingAudioSource::getNextAudioBlock (const AudioSourceChannelInfo& bufferToFill) -{ - const ScopedLock sl (lock); - - buffer.setSize (requiredNumberOfChannels, bufferToFill.numSamples, false, false, true); - - const int numChans = bufferToFill.buffer->getNumChannels(); - - for (int i = 0; i < buffer.getNumChannels(); ++i) - { - const int remappedChan = getRemappedInputChannel (i); - - if (remappedChan >= 0 && remappedChan < numChans) - { - buffer.copyFrom (i, 0, *bufferToFill.buffer, - remappedChan, - bufferToFill.startSample, - bufferToFill.numSamples); - } - else - { - buffer.clear (i, 0, bufferToFill.numSamples); - } - } - - remappedInfo.numSamples = bufferToFill.numSamples; - - source->getNextAudioBlock (remappedInfo); - - bufferToFill.clearActiveBufferRegion(); - - for (int i = 0; i < requiredNumberOfChannels; ++i) - { - const int remappedChan = getRemappedOutputChannel (i); - - if (remappedChan >= 0 && remappedChan < numChans) - { - bufferToFill.buffer->addFrom (remappedChan, bufferToFill.startSample, - buffer, i, 0, bufferToFill.numSamples); - - } - } -} - -//============================================================================== -XmlElement* ChannelRemappingAudioSource::createXml() const -{ - XmlElement* e = new XmlElement ("MAPPINGS"); - String ins, outs; - - const ScopedLock sl (lock); - - for (int i = 0; i < remappedInputs.size(); ++i) - ins << remappedInputs.getUnchecked(i) << ' '; - - for (int i = 0; i < remappedOutputs.size(); ++i) - outs << remappedOutputs.getUnchecked(i) << ' '; - - e->setAttribute ("inputs", ins.trimEnd()); - e->setAttribute ("outputs", outs.trimEnd()); - - return e; -} - -void ChannelRemappingAudioSource::restoreFromXml (const XmlElement& e) -{ - if (e.hasTagName ("MAPPINGS")) - { - const ScopedLock sl (lock); - - clearAllMappings(); - - StringArray ins, outs; - ins.addTokens (e.getStringAttribute ("inputs"), false); - outs.addTokens (e.getStringAttribute ("outputs"), false); - - for (int i = 0; i < ins.size(); ++i) - remappedInputs.add (ins[i].getIntValue()); - - for (int i = 0; i < outs.size(); ++i) - remappedOutputs.add (outs[i].getIntValue()); - } -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/sources/juce_ChannelRemappingAudioSource.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/sources/juce_ChannelRemappingAudioSource.h deleted file mode 100644 index 483fe99deb..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/sources/juce_ChannelRemappingAudioSource.h +++ /dev/null @@ -1,143 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_CHANNELREMAPPINGAUDIOSOURCE_H_INCLUDED -#define JUCE_CHANNELREMAPPINGAUDIOSOURCE_H_INCLUDED - - -//============================================================================== -/** - An AudioSource that takes the audio from another source, and re-maps its - input and output channels to a different arrangement. - - You can use this to increase or decrease the number of channels that an - audio source uses, or to re-order those channels. - - Call the reset() method before using it to set up a default mapping, and then - the setInputChannelMapping() and setOutputChannelMapping() methods to - create an appropriate mapping, otherwise no channels will be connected and - it'll produce silence. - - @see AudioSource -*/ -class ChannelRemappingAudioSource : public AudioSource -{ -public: - //============================================================================== - /** Creates a remapping source that will pass on audio from the given input. - - @param source the input source to use. Make sure that this doesn't - get deleted before the ChannelRemappingAudioSource object - @param deleteSourceWhenDeleted if true, the input source will be deleted - when this object is deleted, if false, the caller is - responsible for its deletion - */ - ChannelRemappingAudioSource (AudioSource* source, - bool deleteSourceWhenDeleted); - - /** Destructor. */ - ~ChannelRemappingAudioSource(); - - //============================================================================== - /** Specifies a number of channels that this audio source must produce from its - getNextAudioBlock() callback. - */ - void setNumberOfChannelsToProduce (int requiredNumberOfChannels); - - /** Clears any mapped channels. - - After this, no channels are mapped, so this object will produce silence. Create - some mappings with setInputChannelMapping() and setOutputChannelMapping(). - */ - void clearAllMappings(); - - /** Creates an input channel mapping. - - When the getNextAudioBlock() method is called, the data in channel sourceChannelIndex of the incoming - data will be sent to destChannelIndex of our input source. - - @param destChannelIndex the index of an input channel in our input audio source (i.e. the - source specified when this object was created). - @param sourceChannelIndex the index of the input channel in the incoming audio data buffer - during our getNextAudioBlock() callback - */ - void setInputChannelMapping (int destChannelIndex, - int sourceChannelIndex); - - /** Creates an output channel mapping. - - When the getNextAudioBlock() method is called, the data returned in channel sourceChannelIndex by - our input audio source will be copied to channel destChannelIndex of the final buffer. - - @param sourceChannelIndex the index of an output channel coming from our input audio source - (i.e. the source specified when this object was created). - @param destChannelIndex the index of the output channel in the incoming audio data buffer - during our getNextAudioBlock() callback - */ - void setOutputChannelMapping (int sourceChannelIndex, - int destChannelIndex); - - /** Returns the channel from our input that will be sent to channel inputChannelIndex of - our input audio source. - */ - int getRemappedInputChannel (int inputChannelIndex) const; - - /** Returns the output channel to which channel outputChannelIndex of our input audio - source will be sent to. - */ - int getRemappedOutputChannel (int outputChannelIndex) const; - - - //============================================================================== - /** Returns an XML object to encapsulate the state of the mappings. - @see restoreFromXml - */ - XmlElement* createXml() const; - - /** Restores the mappings from an XML object created by createXML(). - @see createXml - */ - void restoreFromXml (const XmlElement&); - - //============================================================================== - void prepareToPlay (int samplesPerBlockExpected, double sampleRate) override; - void releaseResources() override; - void getNextAudioBlock (const AudioSourceChannelInfo&) override; - - -private: - //============================================================================== - OptionalScopedPointer source; - Array remappedInputs, remappedOutputs; - int requiredNumberOfChannels; - - AudioSampleBuffer buffer; - AudioSourceChannelInfo remappedInfo; - CriticalSection lock; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ChannelRemappingAudioSource) -}; - - -#endif // JUCE_CHANNELREMAPPINGAUDIOSOURCE_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/sources/juce_IIRFilterAudioSource.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/sources/juce_IIRFilterAudioSource.cpp deleted file mode 100644 index 08e87f0c1d..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/sources/juce_IIRFilterAudioSource.cpp +++ /dev/null @@ -1,77 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -IIRFilterAudioSource::IIRFilterAudioSource (AudioSource* const inputSource, - const bool deleteInputWhenDeleted) - : input (inputSource, deleteInputWhenDeleted) -{ - jassert (inputSource != nullptr); - - for (int i = 2; --i >= 0;) - iirFilters.add (new IIRFilter()); -} - -IIRFilterAudioSource::~IIRFilterAudioSource() {} - -//============================================================================== -void IIRFilterAudioSource::setCoefficients (const IIRCoefficients& newCoefficients) -{ - for (int i = iirFilters.size(); --i >= 0;) - iirFilters.getUnchecked(i)->setCoefficients (newCoefficients); -} - -void IIRFilterAudioSource::makeInactive() -{ - for (int i = iirFilters.size(); --i >= 0;) - iirFilters.getUnchecked(i)->makeInactive(); -} - -//============================================================================== -void IIRFilterAudioSource::prepareToPlay (int samplesPerBlockExpected, double sampleRate) -{ - input->prepareToPlay (samplesPerBlockExpected, sampleRate); - - for (int i = iirFilters.size(); --i >= 0;) - iirFilters.getUnchecked(i)->reset(); -} - -void IIRFilterAudioSource::releaseResources() -{ - input->releaseResources(); -} - -void IIRFilterAudioSource::getNextAudioBlock (const AudioSourceChannelInfo& bufferToFill) -{ - input->getNextAudioBlock (bufferToFill); - - const int numChannels = bufferToFill.buffer->getNumChannels(); - - while (numChannels > iirFilters.size()) - iirFilters.add (new IIRFilter (*iirFilters.getUnchecked (0))); - - for (int i = 0; i < numChannels; ++i) - iirFilters.getUnchecked(i) - ->processSamples (bufferToFill.buffer->getWritePointer (i, bufferToFill.startSample), - bufferToFill.numSamples); -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/sources/juce_IIRFilterAudioSource.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/sources/juce_IIRFilterAudioSource.h deleted file mode 100644 index 40844c568d..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/sources/juce_IIRFilterAudioSource.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_IIRFILTERAUDIOSOURCE_H_INCLUDED -#define JUCE_IIRFILTERAUDIOSOURCE_H_INCLUDED - - -//============================================================================== -/** - An AudioSource that performs an IIR filter on another source. -*/ -class JUCE_API IIRFilterAudioSource : public AudioSource -{ -public: - //============================================================================== - /** Creates a IIRFilterAudioSource for a given input source. - - @param inputSource the input source to read from - this must not be null - @param deleteInputWhenDeleted if true, the input source will be deleted when - this object is deleted - */ - IIRFilterAudioSource (AudioSource* inputSource, - bool deleteInputWhenDeleted); - - /** Destructor. */ - ~IIRFilterAudioSource(); - - //============================================================================== - /** Changes the filter to use the same parameters as the one being passed in. */ - void setCoefficients (const IIRCoefficients& newCoefficients); - - /** Calls IIRFilter::makeInactive() on all the filters being used internally. */ - void makeInactive(); - - //============================================================================== - void prepareToPlay (int samplesPerBlockExpected, double sampleRate) override; - void releaseResources() override; - void getNextAudioBlock (const AudioSourceChannelInfo&) override; - -private: - //============================================================================== - OptionalScopedPointer input; - OwnedArray iirFilters; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (IIRFilterAudioSource) -}; - - -#endif // JUCE_IIRFILTERAUDIOSOURCE_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/sources/juce_MixerAudioSource.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/sources/juce_MixerAudioSource.cpp deleted file mode 100644 index 60ae1919fe..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/sources/juce_MixerAudioSource.cpp +++ /dev/null @@ -1,155 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -MixerAudioSource::MixerAudioSource() - : currentSampleRate (0.0), bufferSizeExpected (0) -{ -} - -MixerAudioSource::~MixerAudioSource() -{ - removeAllInputs(); -} - -//============================================================================== -void MixerAudioSource::addInputSource (AudioSource* input, const bool deleteWhenRemoved) -{ - if (input != nullptr && ! inputs.contains (input)) - { - double localRate; - int localBufferSize; - - { - const ScopedLock sl (lock); - localRate = currentSampleRate; - localBufferSize = bufferSizeExpected; - } - - if (localRate > 0.0) - input->prepareToPlay (localBufferSize, localRate); - - const ScopedLock sl (lock); - - inputsToDelete.setBit (inputs.size(), deleteWhenRemoved); - inputs.add (input); - } -} - -void MixerAudioSource::removeInputSource (AudioSource* const input) -{ - if (input != nullptr) - { - ScopedPointer toDelete; - - { - const ScopedLock sl (lock); - const int index = inputs.indexOf (input); - - if (index < 0) - return; - - if (inputsToDelete [index]) - toDelete = input; - - inputsToDelete.shiftBits (-1, index); - inputs.remove (index); - } - - input->releaseResources(); - } -} - -void MixerAudioSource::removeAllInputs() -{ - OwnedArray toDelete; - - { - const ScopedLock sl (lock); - - for (int i = inputs.size(); --i >= 0;) - if (inputsToDelete[i]) - toDelete.add (inputs.getUnchecked(i)); - - inputs.clear(); - } - - for (int i = toDelete.size(); --i >= 0;) - toDelete.getUnchecked(i)->releaseResources(); -} - -void MixerAudioSource::prepareToPlay (int samplesPerBlockExpected, double sampleRate) -{ - tempBuffer.setSize (2, samplesPerBlockExpected); - - const ScopedLock sl (lock); - - currentSampleRate = sampleRate; - bufferSizeExpected = samplesPerBlockExpected; - - for (int i = inputs.size(); --i >= 0;) - inputs.getUnchecked(i)->prepareToPlay (samplesPerBlockExpected, sampleRate); -} - -void MixerAudioSource::releaseResources() -{ - const ScopedLock sl (lock); - - for (int i = inputs.size(); --i >= 0;) - inputs.getUnchecked(i)->releaseResources(); - - tempBuffer.setSize (2, 0); - - currentSampleRate = 0; - bufferSizeExpected = 0; -} - -void MixerAudioSource::getNextAudioBlock (const AudioSourceChannelInfo& info) -{ - const ScopedLock sl (lock); - - if (inputs.size() > 0) - { - inputs.getUnchecked(0)->getNextAudioBlock (info); - - if (inputs.size() > 1) - { - tempBuffer.setSize (jmax (1, info.buffer->getNumChannels()), - info.buffer->getNumSamples()); - - AudioSourceChannelInfo info2 (&tempBuffer, 0, info.numSamples); - - for (int i = 1; i < inputs.size(); ++i) - { - inputs.getUnchecked(i)->getNextAudioBlock (info2); - - for (int chan = 0; chan < info.buffer->getNumChannels(); ++chan) - info.buffer->addFrom (chan, info.startSample, tempBuffer, chan, 0, info.numSamples); - } - } - } - else - { - info.clearActiveBufferRegion(); - } -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/sources/juce_MixerAudioSource.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/sources/juce_MixerAudioSource.h deleted file mode 100644 index f581ac31e1..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/sources/juce_MixerAudioSource.h +++ /dev/null @@ -1,101 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_MIXERAUDIOSOURCE_H_INCLUDED -#define JUCE_MIXERAUDIOSOURCE_H_INCLUDED - - -//============================================================================== -/** - An AudioSource that mixes together the output of a set of other AudioSources. - - Input sources can be added and removed while the mixer is running as long as their - prepareToPlay() and releaseResources() methods are called before and after adding - them to the mixer. -*/ -class JUCE_API MixerAudioSource : public AudioSource -{ -public: - //============================================================================== - /** Creates a MixerAudioSource. */ - MixerAudioSource(); - - /** Destructor. */ - ~MixerAudioSource(); - - //============================================================================== - /** Adds an input source to the mixer. - - If the mixer is running you'll need to make sure that the input source - is ready to play by calling its prepareToPlay() method before adding it. - If the mixer is stopped, then its input sources will be automatically - prepared when the mixer's prepareToPlay() method is called. - - @param newInput the source to add to the mixer - @param deleteWhenRemoved if true, then this source will be deleted when - no longer needed by the mixer. - */ - void addInputSource (AudioSource* newInput, bool deleteWhenRemoved); - - /** Removes an input source. - If the source was added by calling addInputSource() with the deleteWhenRemoved - flag set, it will be deleted by this method. - */ - void removeInputSource (AudioSource* input); - - /** Removes all the input sources. - Any sources which were added by calling addInputSource() with the deleteWhenRemoved - flag set will be deleted by this method. - */ - void removeAllInputs(); - - //============================================================================== - /** Implementation of the AudioSource method. - This will call prepareToPlay() on all its input sources. - */ - void prepareToPlay (int samplesPerBlockExpected, double sampleRate) override; - - /** Implementation of the AudioSource method. - This will call releaseResources() on all its input sources. - */ - void releaseResources() override; - - /** Implementation of the AudioSource method. */ - void getNextAudioBlock (const AudioSourceChannelInfo&) override; - - -private: - //============================================================================== - Array inputs; - BigInteger inputsToDelete; - CriticalSection lock; - AudioSampleBuffer tempBuffer; - double currentSampleRate; - int bufferSizeExpected; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MixerAudioSource) -}; - - -#endif // JUCE_MIXERAUDIOSOURCE_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/sources/juce_PositionableAudioSource.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/sources/juce_PositionableAudioSource.h deleted file mode 100644 index 2213722bd7..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/sources/juce_PositionableAudioSource.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_POSITIONABLEAUDIOSOURCE_H_INCLUDED -#define JUCE_POSITIONABLEAUDIOSOURCE_H_INCLUDED - - -//============================================================================== -/** - A type of AudioSource which can be repositioned. - - The basic AudioSource just streams continuously with no idea of a current - time or length, so the PositionableAudioSource is used for a finite stream - that has a current read position. - - @see AudioSource, AudioTransportSource -*/ -class JUCE_API PositionableAudioSource : public AudioSource -{ -protected: - //============================================================================== - /** Creates the PositionableAudioSource. */ - PositionableAudioSource() noexcept {} - -public: - /** Destructor */ - ~PositionableAudioSource() {} - - //============================================================================== - /** Tells the stream to move to a new position. - - Calling this indicates that the next call to AudioSource::getNextAudioBlock() - should return samples from this position. - - Note that this may be called on a different thread to getNextAudioBlock(), - so the subclass should make sure it's synchronised. - */ - virtual void setNextReadPosition (int64 newPosition) = 0; - - /** Returns the position from which the next block will be returned. - - @see setNextReadPosition - */ - virtual int64 getNextReadPosition() const = 0; - - /** Returns the total length of the stream (in samples). */ - virtual int64 getTotalLength() const = 0; - - /** Returns true if this source is actually playing in a loop. */ - virtual bool isLooping() const = 0; - - /** Tells the source whether you'd like it to play in a loop. */ - virtual void setLooping (bool shouldLoop) { (void) shouldLoop; } -}; - - -#endif // JUCE_POSITIONABLEAUDIOSOURCE_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/sources/juce_ResamplingAudioSource.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/sources/juce_ResamplingAudioSource.cpp deleted file mode 100644 index 6a0704e0f1..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/sources/juce_ResamplingAudioSource.cpp +++ /dev/null @@ -1,261 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -ResamplingAudioSource::ResamplingAudioSource (AudioSource* const inputSource, - const bool deleteInputWhenDeleted, - const int numChannels_) - : input (inputSource, deleteInputWhenDeleted), - ratio (1.0), - lastRatio (1.0), - bufferPos (0), - sampsInBuffer (0), - subSampleOffset (0), - numChannels (numChannels_) -{ - jassert (input != nullptr); - zeromem (coefficients, sizeof (coefficients)); -} - -ResamplingAudioSource::~ResamplingAudioSource() {} - -void ResamplingAudioSource::setResamplingRatio (const double samplesInPerOutputSample) -{ - jassert (samplesInPerOutputSample > 0); - - const SpinLock::ScopedLockType sl (ratioLock); - ratio = jmax (0.0, samplesInPerOutputSample); -} - -void ResamplingAudioSource::prepareToPlay (int samplesPerBlockExpected, double sampleRate) -{ - const SpinLock::ScopedLockType sl (ratioLock); - - input->prepareToPlay (samplesPerBlockExpected, sampleRate); - - buffer.setSize (numChannels, roundToInt (samplesPerBlockExpected * ratio) + 32); - - filterStates.calloc ((size_t) numChannels); - srcBuffers.calloc ((size_t) numChannels); - destBuffers.calloc ((size_t) numChannels); - createLowPass (ratio); - - flushBuffers(); -} - -void ResamplingAudioSource::flushBuffers() -{ - buffer.clear(); - bufferPos = 0; - sampsInBuffer = 0; - subSampleOffset = 0.0; - resetFilters(); -} - -void ResamplingAudioSource::releaseResources() -{ - input->releaseResources(); - buffer.setSize (numChannels, 0); -} - -void ResamplingAudioSource::getNextAudioBlock (const AudioSourceChannelInfo& info) -{ - double localRatio; - - { - const SpinLock::ScopedLockType sl (ratioLock); - localRatio = ratio; - } - - if (lastRatio != localRatio) - { - createLowPass (localRatio); - lastRatio = localRatio; - } - - const int sampsNeeded = roundToInt (info.numSamples * localRatio) + 2; - - int bufferSize = buffer.getNumSamples(); - - if (bufferSize < sampsNeeded + 8) - { - bufferPos %= bufferSize; - bufferSize = sampsNeeded + 32; - buffer.setSize (buffer.getNumChannels(), bufferSize, true, true); - } - - bufferPos %= bufferSize; - - int endOfBufferPos = bufferPos + sampsInBuffer; - const int channelsToProcess = jmin (numChannels, info.buffer->getNumChannels()); - - while (sampsNeeded > sampsInBuffer) - { - endOfBufferPos %= bufferSize; - - int numToDo = jmin (sampsNeeded - sampsInBuffer, - bufferSize - endOfBufferPos); - - AudioSourceChannelInfo readInfo (&buffer, endOfBufferPos, numToDo); - input->getNextAudioBlock (readInfo); - - if (localRatio > 1.0001) - { - // for down-sampling, pre-apply the filter.. - - for (int i = channelsToProcess; --i >= 0;) - applyFilter (buffer.getWritePointer (i, endOfBufferPos), numToDo, filterStates[i]); - } - - sampsInBuffer += numToDo; - endOfBufferPos += numToDo; - } - - for (int channel = 0; channel < channelsToProcess; ++channel) - { - destBuffers[channel] = info.buffer->getWritePointer (channel, info.startSample); - srcBuffers[channel] = buffer.getReadPointer (channel); - } - - int nextPos = (bufferPos + 1) % bufferSize; - for (int m = info.numSamples; --m >= 0;) - { - const float alpha = (float) subSampleOffset; - - for (int channel = 0; channel < channelsToProcess; ++channel) - *destBuffers[channel]++ = srcBuffers[channel][bufferPos] - + alpha * (srcBuffers[channel][nextPos] - srcBuffers[channel][bufferPos]); - - subSampleOffset += localRatio; - - jassert (sampsInBuffer > 0); - - while (subSampleOffset >= 1.0) - { - if (++bufferPos >= bufferSize) - bufferPos = 0; - - --sampsInBuffer; - - nextPos = (bufferPos + 1) % bufferSize; - subSampleOffset -= 1.0; - } - } - - if (localRatio < 0.9999) - { - // for up-sampling, apply the filter after transposing.. - for (int i = channelsToProcess; --i >= 0;) - applyFilter (info.buffer->getWritePointer (i, info.startSample), info.numSamples, filterStates[i]); - } - else if (localRatio <= 1.0001 && info.numSamples > 0) - { - // if the filter's not currently being applied, keep it stoked with the last couple of samples to avoid discontinuities - for (int i = channelsToProcess; --i >= 0;) - { - const float* const endOfBuffer = info.buffer->getReadPointer (i, info.startSample + info.numSamples - 1); - FilterState& fs = filterStates[i]; - - if (info.numSamples > 1) - { - fs.y2 = fs.x2 = *(endOfBuffer - 1); - } - else - { - fs.y2 = fs.y1; - fs.x2 = fs.x1; - } - - fs.y1 = fs.x1 = *endOfBuffer; - } - } - - jassert (sampsInBuffer >= 0); -} - -void ResamplingAudioSource::createLowPass (const double frequencyRatio) -{ - const double proportionalRate = (frequencyRatio > 1.0) ? 0.5 / frequencyRatio - : 0.5 * frequencyRatio; - - const double n = 1.0 / std::tan (double_Pi * jmax (0.001, proportionalRate)); - const double nSquared = n * n; - const double c1 = 1.0 / (1.0 + std::sqrt (2.0) * n + nSquared); - - setFilterCoefficients (c1, - c1 * 2.0f, - c1, - 1.0, - c1 * 2.0 * (1.0 - nSquared), - c1 * (1.0 - std::sqrt (2.0) * n + nSquared)); -} - -void ResamplingAudioSource::setFilterCoefficients (double c1, double c2, double c3, double c4, double c5, double c6) -{ - const double a = 1.0 / c4; - - c1 *= a; - c2 *= a; - c3 *= a; - c5 *= a; - c6 *= a; - - coefficients[0] = c1; - coefficients[1] = c2; - coefficients[2] = c3; - coefficients[3] = c4; - coefficients[4] = c5; - coefficients[5] = c6; -} - -void ResamplingAudioSource::resetFilters() -{ - if (filterStates != nullptr) - filterStates.clear ((size_t) numChannels); -} - -void ResamplingAudioSource::applyFilter (float* samples, int num, FilterState& fs) -{ - while (--num >= 0) - { - const double in = *samples; - - double out = coefficients[0] * in - + coefficients[1] * fs.x1 - + coefficients[2] * fs.x2 - - coefficients[4] * fs.y1 - - coefficients[5] * fs.y2; - - #if JUCE_INTEL - if (! (out < -1.0e-8 || out > 1.0e-8)) - out = 0; - #endif - - fs.x2 = fs.x1; - fs.x1 = in; - fs.y2 = fs.y1; - fs.y1 = out; - - *samples++ = (float) out; - } -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/sources/juce_ResamplingAudioSource.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/sources/juce_ResamplingAudioSource.h deleted file mode 100644 index 09d27a8751..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/sources/juce_ResamplingAudioSource.h +++ /dev/null @@ -1,107 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_RESAMPLINGAUDIOSOURCE_H_INCLUDED -#define JUCE_RESAMPLINGAUDIOSOURCE_H_INCLUDED - - -//============================================================================== -/** - A type of AudioSource that takes an input source and changes its sample rate. - - @see AudioSource -*/ -class JUCE_API ResamplingAudioSource : public AudioSource -{ -public: - //============================================================================== - /** Creates a ResamplingAudioSource for a given input source. - - @param inputSource the input source to read from - @param deleteInputWhenDeleted if true, the input source will be deleted when - this object is deleted - @param numChannels the number of channels to process - */ - ResamplingAudioSource (AudioSource* inputSource, - bool deleteInputWhenDeleted, - int numChannels = 2); - - /** Destructor. */ - ~ResamplingAudioSource(); - - /** Changes the resampling ratio. - - (This value can be changed at any time, even while the source is running). - - @param samplesInPerOutputSample if set to 1.0, the input is passed through; higher - values will speed it up; lower values will slow it - down. The ratio must be greater than 0 - */ - void setResamplingRatio (double samplesInPerOutputSample); - - /** Returns the current resampling ratio. - - This is the value that was set by setResamplingRatio(). - */ - double getResamplingRatio() const noexcept { return ratio; } - - /** Clears any buffers and filters that the resampler is using. */ - void flushBuffers(); - - //============================================================================== - void prepareToPlay (int samplesPerBlockExpected, double sampleRate) override; - void releaseResources() override; - void getNextAudioBlock (const AudioSourceChannelInfo&) override; - -private: - //============================================================================== - OptionalScopedPointer input; - double ratio, lastRatio; - AudioSampleBuffer buffer; - int bufferPos, sampsInBuffer; - double subSampleOffset; - double coefficients[6]; - SpinLock ratioLock; - const int numChannels; - HeapBlock destBuffers; - HeapBlock srcBuffers; - - void setFilterCoefficients (double c1, double c2, double c3, double c4, double c5, double c6); - void createLowPass (double proportionalRate); - - struct FilterState - { - double x1, x2, y1, y2; - }; - - HeapBlock filterStates; - void resetFilters(); - - void applyFilter (float* samples, int num, FilterState& fs); - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ResamplingAudioSource) -}; - - -#endif // JUCE_RESAMPLINGAUDIOSOURCE_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/sources/juce_ReverbAudioSource.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/sources/juce_ReverbAudioSource.cpp deleted file mode 100644 index d630075371..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/sources/juce_ReverbAudioSource.cpp +++ /dev/null @@ -1,80 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -ReverbAudioSource::ReverbAudioSource (AudioSource* const inputSource, const bool deleteInputWhenDeleted) - : input (inputSource, deleteInputWhenDeleted), - bypass (false) -{ - jassert (inputSource != nullptr); -} - -ReverbAudioSource::~ReverbAudioSource() {} - -void ReverbAudioSource::prepareToPlay (int samplesPerBlockExpected, double sampleRate) -{ - const ScopedLock sl (lock); - input->prepareToPlay (samplesPerBlockExpected, sampleRate); - reverb.setSampleRate (sampleRate); -} - -void ReverbAudioSource::releaseResources() {} - -void ReverbAudioSource::getNextAudioBlock (const AudioSourceChannelInfo& bufferToFill) -{ - const ScopedLock sl (lock); - - input->getNextAudioBlock (bufferToFill); - - if (! bypass) - { - float* const firstChannel = bufferToFill.buffer->getWritePointer (0, bufferToFill.startSample); - - if (bufferToFill.buffer->getNumChannels() > 1) - { - reverb.processStereo (firstChannel, - bufferToFill.buffer->getWritePointer (1, bufferToFill.startSample), - bufferToFill.numSamples); - } - else - { - reverb.processMono (firstChannel, bufferToFill.numSamples); - } - } -} - -void ReverbAudioSource::setParameters (const Reverb::Parameters& newParams) -{ - const ScopedLock sl (lock); - reverb.setParameters (newParams); -} - -void ReverbAudioSource::setBypassed (bool b) noexcept -{ - if (bypass != b) - { - const ScopedLock sl (lock); - bypass = b; - reverb.reset(); - } -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/sources/juce_ReverbAudioSource.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/sources/juce_ReverbAudioSource.h deleted file mode 100644 index 6b90e184a1..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/sources/juce_ReverbAudioSource.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_REVERBAUDIOSOURCE_H_INCLUDED -#define JUCE_REVERBAUDIOSOURCE_H_INCLUDED - - -//============================================================================== -/** - An AudioSource that uses the Reverb class to apply a reverb to another AudioSource. - - @see Reverb -*/ -class JUCE_API ReverbAudioSource : public AudioSource -{ -public: - /** Creates a ReverbAudioSource to process a given input source. - - @param inputSource the input source to read from - this must not be null - @param deleteInputWhenDeleted if true, the input source will be deleted when - this object is deleted - */ - ReverbAudioSource (AudioSource* inputSource, - bool deleteInputWhenDeleted); - - /** Destructor. */ - ~ReverbAudioSource(); - - //============================================================================== - /** Returns the parameters from the reverb. */ - const Reverb::Parameters& getParameters() const noexcept { return reverb.getParameters(); } - - /** Changes the reverb's parameters. */ - void setParameters (const Reverb::Parameters& newParams); - - void setBypassed (bool isBypassed) noexcept; - bool isBypassed() const noexcept { return bypass; } - - //============================================================================== - void prepareToPlay (int samplesPerBlockExpected, double sampleRate) override; - void releaseResources() override; - void getNextAudioBlock (const AudioSourceChannelInfo&) override; - -private: - //============================================================================== - CriticalSection lock; - OptionalScopedPointer input; - Reverb reverb; - volatile bool bypass; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ReverbAudioSource) -}; - - -#endif // JUCE_REVERBAUDIOSOURCE_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/sources/juce_ToneGeneratorAudioSource.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/sources/juce_ToneGeneratorAudioSource.cpp deleted file mode 100644 index a0e04eff24..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/sources/juce_ToneGeneratorAudioSource.cpp +++ /dev/null @@ -1,75 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -ToneGeneratorAudioSource::ToneGeneratorAudioSource() - : frequency (1000.0), - sampleRate (44100.0), - currentPhase (0.0), - phasePerSample (0.0), - amplitude (0.5f) -{ -} - -ToneGeneratorAudioSource::~ToneGeneratorAudioSource() -{ -} - -//============================================================================== -void ToneGeneratorAudioSource::setAmplitude (const float newAmplitude) -{ - amplitude = newAmplitude; -} - -void ToneGeneratorAudioSource::setFrequency (const double newFrequencyHz) -{ - frequency = newFrequencyHz; - phasePerSample = 0.0; -} - -//============================================================================== -void ToneGeneratorAudioSource::prepareToPlay (int /*samplesPerBlockExpected*/, double rate) -{ - currentPhase = 0.0; - phasePerSample = 0.0; - sampleRate = rate; -} - -void ToneGeneratorAudioSource::releaseResources() -{ -} - -void ToneGeneratorAudioSource::getNextAudioBlock (const AudioSourceChannelInfo& info) -{ - if (phasePerSample == 0.0) - phasePerSample = double_Pi * 2.0 / (sampleRate / frequency); - - for (int i = 0; i < info.numSamples; ++i) - { - const float sample = amplitude * (float) std::sin (currentPhase); - currentPhase += phasePerSample; - - for (int j = info.buffer->getNumChannels(); --j >= 0;) - info.buffer->setSample (j, info.startSample + i, sample); - } -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/sources/juce_ToneGeneratorAudioSource.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/sources/juce_ToneGeneratorAudioSource.h deleted file mode 100644 index 5d09ad8ee9..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/sources/juce_ToneGeneratorAudioSource.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_TONEGENERATORAUDIOSOURCE_H_INCLUDED -#define JUCE_TONEGENERATORAUDIOSOURCE_H_INCLUDED - - -//============================================================================== -/** - A simple AudioSource that generates a sine wave. - -*/ -class JUCE_API ToneGeneratorAudioSource : public AudioSource -{ -public: - //============================================================================== - /** Creates a ToneGeneratorAudioSource. */ - ToneGeneratorAudioSource(); - - /** Destructor. */ - ~ToneGeneratorAudioSource(); - - //============================================================================== - /** Sets the signal's amplitude. */ - void setAmplitude (float newAmplitude); - - /** Sets the signal's frequency. */ - void setFrequency (double newFrequencyHz); - - - //============================================================================== - /** Implementation of the AudioSource method. */ - void prepareToPlay (int samplesPerBlockExpected, double sampleRate) override; - - /** Implementation of the AudioSource method. */ - void releaseResources() override; - - /** Implementation of the AudioSource method. */ - void getNextAudioBlock (const AudioSourceChannelInfo&) override; - - -private: - //============================================================================== - double frequency, sampleRate; - double currentPhase, phasePerSample; - float amplitude; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ToneGeneratorAudioSource) -}; - - -#endif // JUCE_TONEGENERATORAUDIOSOURCE_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/synthesisers/juce_Synthesiser.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/synthesisers/juce_Synthesiser.cpp deleted file mode 100644 index 81110ed9f8..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/synthesisers/juce_Synthesiser.cpp +++ /dev/null @@ -1,503 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -SynthesiserSound::SynthesiserSound() {} -SynthesiserSound::~SynthesiserSound() {} - -//============================================================================== -SynthesiserVoice::SynthesiserVoice() - : currentSampleRate (44100.0), - currentlyPlayingNote (-1), - noteOnTime (0), - keyIsDown (false), - sostenutoPedalDown (false) -{ -} - -SynthesiserVoice::~SynthesiserVoice() -{ -} - -bool SynthesiserVoice::isPlayingChannel (const int midiChannel) const -{ - return currentlyPlayingSound != nullptr - && currentlyPlayingSound->appliesToChannel (midiChannel); -} - -void SynthesiserVoice::setCurrentPlaybackSampleRate (const double newRate) -{ - currentSampleRate = newRate; -} - -bool SynthesiserVoice::isVoiceActive() const -{ - return getCurrentlyPlayingNote() >= 0; -} - -void SynthesiserVoice::clearCurrentNote() -{ - currentlyPlayingNote = -1; - currentlyPlayingSound = nullptr; -} - -void SynthesiserVoice::aftertouchChanged (int) {} - -bool SynthesiserVoice::wasStartedBefore (const SynthesiserVoice& other) const noexcept -{ - return noteOnTime < other.noteOnTime; -} - -//============================================================================== -Synthesiser::Synthesiser() - : sampleRate (0), - lastNoteOnCounter (0), - shouldStealNotes (true) -{ - for (int i = 0; i < numElementsInArray (lastPitchWheelValues); ++i) - lastPitchWheelValues[i] = 0x2000; -} - -Synthesiser::~Synthesiser() -{ -} - -//============================================================================== -SynthesiserVoice* Synthesiser::getVoice (const int index) const -{ - const ScopedLock sl (lock); - return voices [index]; -} - -void Synthesiser::clearVoices() -{ - const ScopedLock sl (lock); - voices.clear(); -} - -SynthesiserVoice* Synthesiser::addVoice (SynthesiserVoice* const newVoice) -{ - const ScopedLock sl (lock); - return voices.add (newVoice); -} - -void Synthesiser::removeVoice (const int index) -{ - const ScopedLock sl (lock); - voices.remove (index); -} - -void Synthesiser::clearSounds() -{ - const ScopedLock sl (lock); - sounds.clear(); -} - -SynthesiserSound* Synthesiser::addSound (const SynthesiserSound::Ptr& newSound) -{ - const ScopedLock sl (lock); - return sounds.add (newSound); -} - -void Synthesiser::removeSound (const int index) -{ - const ScopedLock sl (lock); - sounds.remove (index); -} - -void Synthesiser::setNoteStealingEnabled (const bool shouldSteal) -{ - shouldStealNotes = shouldSteal; -} - -//============================================================================== -void Synthesiser::setCurrentPlaybackSampleRate (const double newRate) -{ - if (sampleRate != newRate) - { - const ScopedLock sl (lock); - - allNotesOff (0, false); - - sampleRate = newRate; - - for (int i = voices.size(); --i >= 0;) - voices.getUnchecked (i)->setCurrentPlaybackSampleRate (newRate); - } -} - -void Synthesiser::renderNextBlock (AudioSampleBuffer& outputBuffer, const MidiBuffer& midiData, - int startSample, int numSamples) -{ - // must set the sample rate before using this! - jassert (sampleRate != 0); - - const ScopedLock sl (lock); - - MidiBuffer::Iterator midiIterator (midiData); - midiIterator.setNextSamplePosition (startSample); - MidiMessage m (0xf4, 0.0); - - while (numSamples > 0) - { - int midiEventPos; - const bool useEvent = midiIterator.getNextEvent (m, midiEventPos) - && midiEventPos < startSample + numSamples; - - const int numThisTime = useEvent ? midiEventPos - startSample - : numSamples; - - if (numThisTime > 0) - renderVoices (outputBuffer, startSample, numThisTime); - - if (useEvent) - handleMidiEvent (m); - - startSample += numThisTime; - numSamples -= numThisTime; - } -} - -void Synthesiser::renderVoices (AudioSampleBuffer& buffer, int startSample, int numSamples) -{ - for (int i = voices.size(); --i >= 0;) - voices.getUnchecked (i)->renderNextBlock (buffer, startSample, numSamples); -} - -void Synthesiser::handleMidiEvent (const MidiMessage& m) -{ - if (m.isNoteOn()) - { - noteOn (m.getChannel(), m.getNoteNumber(), m.getFloatVelocity()); - } - else if (m.isNoteOff()) - { - noteOff (m.getChannel(), m.getNoteNumber(), m.getFloatVelocity(), true); - } - else if (m.isAllNotesOff() || m.isAllSoundOff()) - { - allNotesOff (m.getChannel(), true); - } - else if (m.isPitchWheel()) - { - const int channel = m.getChannel(); - const int wheelPos = m.getPitchWheelValue(); - lastPitchWheelValues [channel - 1] = wheelPos; - - handlePitchWheel (channel, wheelPos); - } - else if (m.isAftertouch()) - { - handleAftertouch (m.getChannel(), m.getNoteNumber(), m.getAfterTouchValue()); - } - else if (m.isController()) - { - handleController (m.getChannel(), m.getControllerNumber(), m.getControllerValue()); - } -} - -//============================================================================== -void Synthesiser::noteOn (const int midiChannel, - const int midiNoteNumber, - const float velocity) -{ - const ScopedLock sl (lock); - - for (int i = sounds.size(); --i >= 0;) - { - SynthesiserSound* const sound = sounds.getUnchecked(i); - - if (sound->appliesToNote (midiNoteNumber) - && sound->appliesToChannel (midiChannel)) - { - // If hitting a note that's still ringing, stop it first (it could be - // still playing because of the sustain or sostenuto pedal). - for (int j = voices.size(); --j >= 0;) - { - SynthesiserVoice* const voice = voices.getUnchecked (j); - - if (voice->getCurrentlyPlayingNote() == midiNoteNumber - && voice->isPlayingChannel (midiChannel)) - stopVoice (voice, 1.0f, true); - } - - startVoice (findFreeVoice (sound, midiChannel, midiNoteNumber, shouldStealNotes), - sound, midiChannel, midiNoteNumber, velocity); - } - } -} - -void Synthesiser::startVoice (SynthesiserVoice* const voice, - SynthesiserSound* const sound, - const int midiChannel, - const int midiNoteNumber, - const float velocity) -{ - if (voice != nullptr && sound != nullptr) - { - if (voice->currentlyPlayingSound != nullptr) - voice->stopNote (0.0f, false); - - voice->startNote (midiNoteNumber, velocity, sound, - lastPitchWheelValues [midiChannel - 1]); - - voice->currentlyPlayingNote = midiNoteNumber; - voice->noteOnTime = ++lastNoteOnCounter; - voice->currentlyPlayingSound = sound; - voice->keyIsDown = true; - voice->sostenutoPedalDown = false; - } -} - -void Synthesiser::stopVoice (SynthesiserVoice* voice, float velocity, const bool allowTailOff) -{ - jassert (voice != nullptr); - - voice->stopNote (velocity, allowTailOff); - - // the subclass MUST call clearCurrentNote() if it's not tailing off! RTFM for stopNote()! - jassert (allowTailOff || (voice->getCurrentlyPlayingNote() < 0 && voice->getCurrentlyPlayingSound() == 0)); -} - -void Synthesiser::noteOff (const int midiChannel, - const int midiNoteNumber, - const float velocity, - const bool allowTailOff) -{ - const ScopedLock sl (lock); - - for (int i = voices.size(); --i >= 0;) - { - SynthesiserVoice* const voice = voices.getUnchecked (i); - - if (voice->getCurrentlyPlayingNote() == midiNoteNumber) - { - if (SynthesiserSound* const sound = voice->getCurrentlyPlayingSound()) - { - if (sound->appliesToNote (midiNoteNumber) - && sound->appliesToChannel (midiChannel)) - { - voice->keyIsDown = false; - - if (! (sustainPedalsDown [midiChannel] || voice->sostenutoPedalDown)) - stopVoice (voice, velocity, allowTailOff); - } - } - } - } -} - -void Synthesiser::allNotesOff (const int midiChannel, const bool allowTailOff) -{ - const ScopedLock sl (lock); - - for (int i = voices.size(); --i >= 0;) - { - SynthesiserVoice* const voice = voices.getUnchecked (i); - - if (midiChannel <= 0 || voice->isPlayingChannel (midiChannel)) - voice->stopNote (1.0f, allowTailOff); - } - - sustainPedalsDown.clear(); -} - -void Synthesiser::handlePitchWheel (const int midiChannel, const int wheelValue) -{ - const ScopedLock sl (lock); - - for (int i = voices.size(); --i >= 0;) - { - SynthesiserVoice* const voice = voices.getUnchecked (i); - - if (midiChannel <= 0 || voice->isPlayingChannel (midiChannel)) - voice->pitchWheelMoved (wheelValue); - } -} - -void Synthesiser::handleController (const int midiChannel, - const int controllerNumber, - const int controllerValue) -{ - switch (controllerNumber) - { - case 0x40: handleSustainPedal (midiChannel, controllerValue >= 64); break; - case 0x42: handleSostenutoPedal (midiChannel, controllerValue >= 64); break; - case 0x43: handleSoftPedal (midiChannel, controllerValue >= 64); break; - default: break; - } - - const ScopedLock sl (lock); - - for (int i = voices.size(); --i >= 0;) - { - SynthesiserVoice* const voice = voices.getUnchecked (i); - - if (midiChannel <= 0 || voice->isPlayingChannel (midiChannel)) - voice->controllerMoved (controllerNumber, controllerValue); - } -} - -void Synthesiser::handleAftertouch (int midiChannel, int midiNoteNumber, int aftertouchValue) -{ - const ScopedLock sl (lock); - - for (int i = voices.size(); --i >= 0;) - { - SynthesiserVoice* const voice = voices.getUnchecked (i); - - if (voice->getCurrentlyPlayingNote() == midiNoteNumber - && (midiChannel <= 0 || voice->isPlayingChannel (midiChannel))) - voice->aftertouchChanged (aftertouchValue); - } -} - -void Synthesiser::handleSustainPedal (int midiChannel, bool isDown) -{ - jassert (midiChannel > 0 && midiChannel <= 16); - const ScopedLock sl (lock); - - if (isDown) - { - sustainPedalsDown.setBit (midiChannel); - } - else - { - for (int i = voices.size(); --i >= 0;) - { - SynthesiserVoice* const voice = voices.getUnchecked (i); - - if (voice->isPlayingChannel (midiChannel) && ! voice->keyIsDown) - stopVoice (voice, 1.0f, true); - } - - sustainPedalsDown.clearBit (midiChannel); - } -} - -void Synthesiser::handleSostenutoPedal (int midiChannel, bool isDown) -{ - jassert (midiChannel > 0 && midiChannel <= 16); - const ScopedLock sl (lock); - - for (int i = voices.size(); --i >= 0;) - { - SynthesiserVoice* const voice = voices.getUnchecked (i); - - if (voice->isPlayingChannel (midiChannel)) - { - if (isDown) - voice->sostenutoPedalDown = true; - else if (voice->sostenutoPedalDown) - stopVoice (voice, 1.0f, true); - } - } -} - -void Synthesiser::handleSoftPedal (int midiChannel, bool /*isDown*/) -{ - (void) midiChannel; - jassert (midiChannel > 0 && midiChannel <= 16); -} - -//============================================================================== -SynthesiserVoice* Synthesiser::findFreeVoice (SynthesiserSound* soundToPlay, - int midiChannel, int midiNoteNumber, - const bool stealIfNoneAvailable) const -{ - const ScopedLock sl (lock); - - for (int i = 0; i < voices.size(); ++i) - { - SynthesiserVoice* const voice = voices.getUnchecked (i); - - if ((! voice->isVoiceActive()) && voice->canPlaySound (soundToPlay)) - return voice; - } - - if (stealIfNoneAvailable) - return findVoiceToSteal (soundToPlay, midiChannel, midiNoteNumber); - - return nullptr; -} - -struct VoiceAgeSorter -{ - static int compareElements (SynthesiserVoice* v1, SynthesiserVoice* v2) noexcept - { - return v1->wasStartedBefore (*v2) ? 1 : (v2->wasStartedBefore (*v1) ? -1 : 0); - } -}; - -SynthesiserVoice* Synthesiser::findVoiceToSteal (SynthesiserSound* soundToPlay, - int /*midiChannel*/, int midiNoteNumber) const -{ - SynthesiserVoice* bottom = nullptr; - SynthesiserVoice* top = nullptr; - - // this is a list of voices we can steal, sorted by how long they've been running - Array usableVoices; - usableVoices.ensureStorageAllocated (voices.size()); - - for (int i = 0; i < voices.size(); ++i) - { - SynthesiserVoice* const voice = voices.getUnchecked (i); - - if (voice->canPlaySound (soundToPlay)) - { - VoiceAgeSorter sorter; - usableVoices.addSorted (sorter, voice); - - const int note = voice->getCurrentlyPlayingNote(); - - if (bottom == nullptr || note < bottom->getCurrentlyPlayingNote()) - bottom = voice; - - if (top == nullptr || note > top->getCurrentlyPlayingNote()) - top = voice; - } - } - - jassert (bottom != nullptr && top != nullptr); - - // The oldest note that's playing with the target pitch playing is ideal.. - for (int i = 0; i < usableVoices.size(); ++i) - { - SynthesiserVoice* const voice = usableVoices.getUnchecked (i); - - if (voice->getCurrentlyPlayingNote() == midiNoteNumber) - return voice; - } - - // ..otherwise, look for the oldest note that isn't the top or bottom note.. - for (int i = 0; i < usableVoices.size(); ++i) - { - SynthesiserVoice* const voice = usableVoices.getUnchecked (i); - - if (voice != bottom && voice != top) - return voice; - } - - // ..otherwise, there's only one or two voices to choose from - we'll return the top one.. - return top; -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/synthesisers/juce_Synthesiser.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/synthesisers/juce_Synthesiser.h deleted file mode 100644 index 3c20a85302..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_basics/synthesisers/juce_Synthesiser.h +++ /dev/null @@ -1,557 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_SYNTHESISER_H_INCLUDED -#define JUCE_SYNTHESISER_H_INCLUDED - - -//============================================================================== -/** - Describes one of the sounds that a Synthesiser can play. - - A synthesiser can contain one or more sounds, and a sound can choose which - midi notes and channels can trigger it. - - The SynthesiserSound is a passive class that just describes what the sound is - - the actual audio rendering for a sound is done by a SynthesiserVoice. This allows - more than one SynthesiserVoice to play the same sound at the same time. - - @see Synthesiser, SynthesiserVoice -*/ -class JUCE_API SynthesiserSound : public ReferenceCountedObject -{ -protected: - //============================================================================== - SynthesiserSound(); - -public: - /** Destructor. */ - virtual ~SynthesiserSound(); - - //============================================================================== - /** Returns true if this sound should be played when a given midi note is pressed. - - The Synthesiser will use this information when deciding which sounds to trigger - for a given note. - */ - virtual bool appliesToNote (int midiNoteNumber) = 0; - - /** Returns true if the sound should be triggered by midi events on a given channel. - - The Synthesiser will use this information when deciding which sounds to trigger - for a given note. - */ - virtual bool appliesToChannel (int midiChannel) = 0; - - /** The class is reference-counted, so this is a handy pointer class for it. */ - typedef ReferenceCountedObjectPtr Ptr; - - -private: - //============================================================================== - JUCE_LEAK_DETECTOR (SynthesiserSound) -}; - - -//============================================================================== -/** - Represents a voice that a Synthesiser can use to play a SynthesiserSound. - - A voice plays a single sound at a time, and a synthesiser holds an array of - voices so that it can play polyphonically. - - @see Synthesiser, SynthesiserSound -*/ -class JUCE_API SynthesiserVoice -{ -public: - //============================================================================== - /** Creates a voice. */ - SynthesiserVoice(); - - /** Destructor. */ - virtual ~SynthesiserVoice(); - - //============================================================================== - /** Returns the midi note that this voice is currently playing. - Returns a value less than 0 if no note is playing. - */ - int getCurrentlyPlayingNote() const noexcept { return currentlyPlayingNote; } - - /** Returns the sound that this voice is currently playing. - Returns nullptr if it's not playing. - */ - SynthesiserSound::Ptr getCurrentlyPlayingSound() const noexcept { return currentlyPlayingSound; } - - /** Must return true if this voice object is capable of playing the given sound. - - If there are different classes of sound, and different classes of voice, a voice can - choose which ones it wants to take on. - - A typical implementation of this method may just return true if there's only one type - of voice and sound, or it might check the type of the sound object passed-in and - see if it's one that it understands. - */ - virtual bool canPlaySound (SynthesiserSound*) = 0; - - /** Called to start a new note. - This will be called during the rendering callback, so must be fast and thread-safe. - */ - virtual void startNote (int midiNoteNumber, - float velocity, - SynthesiserSound* sound, - int currentPitchWheelPosition) = 0; - - /** Called to stop a note. - - This will be called during the rendering callback, so must be fast and thread-safe. - - The velocity indicates how quickly the note was released - 0 is slowly, 1 is quickly. - - If allowTailOff is false or the voice doesn't want to tail-off, then it must stop all - sound immediately, and must call clearCurrentNote() to reset the state of this voice - and allow the synth to reassign it another sound. - - If allowTailOff is true and the voice decides to do a tail-off, then it's allowed to - begin fading out its sound, and it can stop playing until it's finished. As soon as it - finishes playing (during the rendering callback), it must make sure that it calls - clearCurrentNote(). - */ - virtual void stopNote (float velocity, bool allowTailOff) = 0; - - /** Returns true if this voice is currently busy playing a sound. - By default this just checks the getCurrentlyPlayingNote() value, but can - be overridden for more advanced checking. - */ - virtual bool isVoiceActive() const; - - /** Called to let the voice know that the pitch wheel has been moved. - This will be called during the rendering callback, so must be fast and thread-safe. - */ - virtual void pitchWheelMoved (int newPitchWheelValue) = 0; - - /** Called to let the voice know that a midi controller has been moved. - This will be called during the rendering callback, so must be fast and thread-safe. - */ - virtual void controllerMoved (int controllerNumber, int newControllerValue) = 0; - - /** Called to let the voice know that the aftertouch has changed. - This will be called during the rendering callback, so must be fast and thread-safe. - */ - virtual void aftertouchChanged (int newAftertouchValue); - - //============================================================================== - /** Renders the next block of data for this voice. - - The output audio data must be added to the current contents of the buffer provided. - Only the region of the buffer between startSample and (startSample + numSamples) - should be altered by this method. - - If the voice is currently silent, it should just return without doing anything. - - If the sound that the voice is playing finishes during the course of this rendered - block, it must call clearCurrentNote(), to tell the synthesiser that it has finished. - - The size of the blocks that are rendered can change each time it is called, and may - involve rendering as little as 1 sample at a time. In between rendering callbacks, - the voice's methods will be called to tell it about note and controller events. - */ - virtual void renderNextBlock (AudioSampleBuffer& outputBuffer, - int startSample, - int numSamples) = 0; - - /** Changes the voice's reference sample rate. - - The rate is set so that subclasses know the output rate and can set their pitch - accordingly. - - This method is called by the synth, and subclasses can access the current rate with - the currentSampleRate member. - */ - virtual void setCurrentPlaybackSampleRate (double newRate); - - /** Returns the current target sample rate at which rendering is being done. - Subclasses may need to know this so that they can pitch things correctly. - */ - double getSampleRate() const noexcept { return currentSampleRate; } - - /** Returns true if the voice is currently playing a sound which is mapped to the given - midi channel. - - If it's not currently playing, this will return false. - */ - bool isPlayingChannel (int midiChannel) const; - - /** Returns true if the key that triggered this voice is still held down. - Note that the voice may still be playing after the key was released (e.g because the - sostenuto pedal is down). - */ - bool isKeyDown() const noexcept { return keyIsDown; } - - /** Returns true if the sostenuto pedal is currently active for this voice. */ - bool isSostenutoPedalDown() const noexcept { return sostenutoPedalDown; } - - /** Returns true if this voice started playing its current note before the other voice did. */ - bool wasStartedBefore (const SynthesiserVoice& other) const noexcept; - -protected: - /** Resets the state of this voice after a sound has finished playing. - - The subclass must call this when it finishes playing a note and becomes available - to play new ones. - - It must either call it in the stopNote() method, or if the voice is tailing off, - then it should call it later during the renderNextBlock method, as soon as it - finishes its tail-off. - - It can also be called at any time during the render callback if the sound happens - to have finished, e.g. if it's playing a sample and the sample finishes. - */ - void clearCurrentNote(); - - -private: - //============================================================================== - friend class Synthesiser; - - double currentSampleRate; - int currentlyPlayingNote; - uint32 noteOnTime; - SynthesiserSound::Ptr currentlyPlayingSound; - bool keyIsDown, sostenutoPedalDown; - - #if JUCE_CATCH_DEPRECATED_CODE_MISUSE - // Note the new parameters for this method. - virtual int stopNote (bool) { return 0; } - #endif - - JUCE_LEAK_DETECTOR (SynthesiserVoice) -}; - - -//============================================================================== -/** - Base class for a musical device that can play sounds. - - To create a synthesiser, you'll need to create a subclass of SynthesiserSound - to describe each sound available to your synth, and a subclass of SynthesiserVoice - which can play back one of these sounds. - - Then you can use the addVoice() and addSound() methods to give the synthesiser a - set of sounds, and a set of voices it can use to play them. If you only give it - one voice it will be monophonic - the more voices it has, the more polyphony it'll - have available. - - Then repeatedly call the renderNextBlock() method to produce the audio. Any midi - events that go in will be scanned for note on/off messages, and these are used to - start and stop the voices playing the appropriate sounds. - - While it's playing, you can also cause notes to be triggered by calling the noteOn(), - noteOff() and other controller methods. - - Before rendering, be sure to call the setCurrentPlaybackSampleRate() to tell it - what the target playback rate is. This value is passed on to the voices so that - they can pitch their output correctly. -*/ -class JUCE_API Synthesiser -{ -public: - //============================================================================== - /** Creates a new synthesiser. - You'll need to add some sounds and voices before it'll make any sound. - */ - Synthesiser(); - - /** Destructor. */ - virtual ~Synthesiser(); - - //============================================================================== - /** Deletes all voices. */ - void clearVoices(); - - /** Returns the number of voices that have been added. */ - int getNumVoices() const noexcept { return voices.size(); } - - /** Returns one of the voices that have been added. */ - SynthesiserVoice* getVoice (int index) const; - - /** Adds a new voice to the synth. - - All the voices should be the same class of object and are treated equally. - - The object passed in will be managed by the synthesiser, which will delete - it later on when no longer needed. The caller should not retain a pointer to the - voice. - */ - SynthesiserVoice* addVoice (SynthesiserVoice* newVoice); - - /** Deletes one of the voices. */ - void removeVoice (int index); - - //============================================================================== - /** Deletes all sounds. */ - void clearSounds(); - - /** Returns the number of sounds that have been added to the synth. */ - int getNumSounds() const noexcept { return sounds.size(); } - - /** Returns one of the sounds. */ - SynthesiserSound* getSound (int index) const noexcept { return sounds [index]; } - - /** Adds a new sound to the synthesiser. - - The object passed in is reference counted, so will be deleted when the - synthesiser and all voices are no longer using it. - */ - SynthesiserSound* addSound (const SynthesiserSound::Ptr& newSound); - - /** Removes and deletes one of the sounds. */ - void removeSound (int index); - - //============================================================================== - /** If set to true, then the synth will try to take over an existing voice if - it runs out and needs to play another note. - - The value of this boolean is passed into findFreeVoice(), so the result will - depend on the implementation of this method. - */ - void setNoteStealingEnabled (bool shouldStealNotes); - - /** Returns true if note-stealing is enabled. - @see setNoteStealingEnabled - */ - bool isNoteStealingEnabled() const noexcept { return shouldStealNotes; } - - //============================================================================== - /** Triggers a note-on event. - - The default method here will find all the sounds that want to be triggered by - this note/channel. For each sound, it'll try to find a free voice, and use the - voice to start playing the sound. - - Subclasses might want to override this if they need a more complex algorithm. - - This method will be called automatically according to the midi data passed into - renderNextBlock(), but may be called explicitly too. - - The midiChannel parameter is the channel, between 1 and 16 inclusive. - */ - virtual void noteOn (int midiChannel, - int midiNoteNumber, - float velocity); - - /** Triggers a note-off event. - - This will turn off any voices that are playing a sound for the given note/channel. - - If allowTailOff is true, the voices will be allowed to fade out the notes gracefully - (if they can do). If this is false, the notes will all be cut off immediately. - - This method will be called automatically according to the midi data passed into - renderNextBlock(), but may be called explicitly too. - - The midiChannel parameter is the channel, between 1 and 16 inclusive. - */ - virtual void noteOff (int midiChannel, - int midiNoteNumber, - float velocity, - bool allowTailOff); - - /** Turns off all notes. - - This will turn off any voices that are playing a sound on the given midi channel. - - If midiChannel is 0 or less, then all voices will be turned off, regardless of - which channel they're playing. Otherwise it represents a valid midi channel, from - 1 to 16 inclusive. - - If allowTailOff is true, the voices will be allowed to fade out the notes gracefully - (if they can do). If this is false, the notes will all be cut off immediately. - - This method will be called automatically according to the midi data passed into - renderNextBlock(), but may be called explicitly too. - */ - virtual void allNotesOff (int midiChannel, - bool allowTailOff); - - /** Sends a pitch-wheel message to any active voices. - - This will send a pitch-wheel message to any voices that are playing sounds on - the given midi channel. - - This method will be called automatically according to the midi data passed into - renderNextBlock(), but may be called explicitly too. - - @param midiChannel the midi channel, from 1 to 16 inclusive - @param wheelValue the wheel position, from 0 to 0x3fff, as returned by MidiMessage::getPitchWheelValue() - */ - virtual void handlePitchWheel (int midiChannel, - int wheelValue); - - /** Sends a midi controller message to any active voices. - - This will send a midi controller message to any voices that are playing sounds on - the given midi channel. - - This method will be called automatically according to the midi data passed into - renderNextBlock(), but may be called explicitly too. - - @param midiChannel the midi channel, from 1 to 16 inclusive - @param controllerNumber the midi controller type, as returned by MidiMessage::getControllerNumber() - @param controllerValue the midi controller value, between 0 and 127, as returned by MidiMessage::getControllerValue() - */ - virtual void handleController (int midiChannel, - int controllerNumber, - int controllerValue); - - /** Sends an aftertouch message. - - This will send an aftertouch message to any voices that are playing sounds on - the given midi channel and note number. - - This method will be called automatically according to the midi data passed into - renderNextBlock(), but may be called explicitly too. - - @param midiChannel the midi channel, from 1 to 16 inclusive - @param midiNoteNumber the midi note number, 0 to 127 - @param aftertouchValue the aftertouch value, between 0 and 127, - as returned by MidiMessage::getAftertouchValue() - */ - virtual void handleAftertouch (int midiChannel, int midiNoteNumber, int aftertouchValue); - - /** Handles a sustain pedal event. */ - virtual void handleSustainPedal (int midiChannel, bool isDown); - - /** Handles a sostenuto pedal event. */ - virtual void handleSostenutoPedal (int midiChannel, bool isDown); - - /** Can be overridden to handle soft pedal events. */ - virtual void handleSoftPedal (int midiChannel, bool isDown); - - //============================================================================== - /** Tells the synthesiser what the sample rate is for the audio it's being used to render. - - This value is propagated to the voices so that they can use it to render the correct - pitches. - */ - virtual void setCurrentPlaybackSampleRate (double sampleRate); - - /** Creates the next block of audio output. - - This will process the next numSamples of data from all the voices, and add that output - to the audio block supplied, starting from the offset specified. Note that the - data will be added to the current contents of the buffer, so you should clear it - before calling this method if necessary. - - The midi events in the inputMidi buffer are parsed for note and controller events, - and these are used to trigger the voices. Note that the startSample offset applies - both to the audio output buffer and the midi input buffer, so any midi events - with timestamps outside the specified region will be ignored. - */ - void renderNextBlock (AudioSampleBuffer& outputAudio, - const MidiBuffer& inputMidi, - int startSample, - int numSamples); - - /** Returns the current target sample rate at which rendering is being done. - Subclasses may need to know this so that they can pitch things correctly. - */ - double getSampleRate() const noexcept { return sampleRate; } - -protected: - //============================================================================== - /** This is used to control access to the rendering callback and the note trigger methods. */ - CriticalSection lock; - - OwnedArray voices; - ReferenceCountedArray sounds; - - /** The last pitch-wheel values for each midi channel. */ - int lastPitchWheelValues [16]; - - /** Renders the voices for the given range. - By default this just calls renderNextBlock() on each voice, but you may need - to override it to handle custom cases. - */ - virtual void renderVoices (AudioSampleBuffer& outputAudio, - int startSample, int numSamples); - - /** Searches through the voices to find one that's not currently playing, and - which can play the given sound. - - Returns nullptr if all voices are busy and stealing isn't enabled. - - To implement a custom note-stealing algorithm, you can either override this - method, or (preferably) override findVoiceToSteal(). - */ - virtual SynthesiserVoice* findFreeVoice (SynthesiserSound* soundToPlay, - int midiChannel, - int midiNoteNumber, - bool stealIfNoneAvailable) const; - - /** Chooses a voice that is most suitable for being re-used. - The default method will attempt to find the oldest voice that isn't the - bottom or top note being played. If that's not suitable for your synth, - you can override this method and do something more cunning instead. - */ - virtual SynthesiserVoice* findVoiceToSteal (SynthesiserSound* soundToPlay, - int midiChannel, - int midiNoteNumber) const; - - /** Starts a specified voice playing a particular sound. - - You'll probably never need to call this, it's used internally by noteOn(), but - may be needed by subclasses for custom behaviours. - */ - void startVoice (SynthesiserVoice* voice, - SynthesiserSound* sound, - int midiChannel, - int midiNoteNumber, - float velocity); - - /** Can be overridden to do custom handling of incoming midi events. */ - virtual void handleMidiEvent (const MidiMessage&); - -private: - //============================================================================== - double sampleRate; - uint32 lastNoteOnCounter; - bool shouldStealNotes; - BigInteger sustainPedalsDown; - - void stopVoice (SynthesiserVoice*, float velocity, bool allowTailOff); - - #if JUCE_CATCH_DEPRECATED_CODE_MISUSE - // Note the new parameters for these methods. - virtual int findFreeVoice (const bool) const { return 0; } - virtual int noteOff (int, int, int) { return 0; } - virtual int findFreeVoice (SynthesiserSound*, const bool) { return 0; } - virtual int findVoiceToSteal (SynthesiserSound*) const { return 0; } - #endif - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Synthesiser) -}; - - -#endif // JUCE_SYNTHESISER_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/audio_cd/juce_AudioCDBurner.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/audio_cd/juce_AudioCDBurner.h deleted file mode 100644 index 88b1ef2670..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/audio_cd/juce_AudioCDBurner.h +++ /dev/null @@ -1,169 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_AUDIOCDBURNER_H_INCLUDED -#define JUCE_AUDIOCDBURNER_H_INCLUDED - -#if JUCE_USE_CDBURNER || DOXYGEN - - -//============================================================================== -/** -*/ -class AudioCDBurner : public ChangeBroadcaster -{ -public: - //============================================================================== - /** Returns a list of available optical drives. - - Use openDevice() to open one of the items from this list. - */ - static StringArray findAvailableDevices(); - - /** Tries to open one of the optical drives. - - The deviceIndex is an index into the array returned by findAvailableDevices(). - */ - static AudioCDBurner* openDevice (const int deviceIndex); - - /** Destructor. */ - ~AudioCDBurner(); - - //============================================================================== - enum DiskState - { - unknown, /**< An error condition, if the device isn't responding. */ - trayOpen, /**< The drive is currently open. Note that a slot-loading drive - may seem to be permanently open. */ - noDisc, /**< The drive has no disk in it. */ - writableDiskPresent, /**< The drive contains a writeable disk. */ - readOnlyDiskPresent /**< The drive contains a read-only disk. */ - }; - - /** Returns the current status of the device. - - To get informed when the drive's status changes, attach a ChangeListener to - the AudioCDBurner. - */ - DiskState getDiskState() const; - - /** Returns true if there's a writable disk in the drive. */ - bool isDiskPresent() const; - - /** Sends an eject signal to the drive. - The eject will happen asynchronously, so you can use getDiskState() and - waitUntilStateChange() to monitor its progress. - */ - bool openTray(); - - /** Blocks the current thread until the drive's state changes, or until the timeout expires. - @returns the device's new state - */ - DiskState waitUntilStateChange (int timeOutMilliseconds); - - //============================================================================== - /** Returns the set of possible write speeds that the device can handle. - These are as a multiple of 'normal' speed, so e.g. '24x' returns 24, etc. - Note that if there's no media present in the drive, this value may be unavailable! - @see setWriteSpeed, getWriteSpeed - */ - Array getAvailableWriteSpeeds() const; - - //============================================================================== - /** Tries to enable or disable buffer underrun safety on devices that support it. - @returns true if it's now enabled. If the device doesn't support it, this - will always return false. - */ - bool setBufferUnderrunProtection (bool shouldBeEnabled); - - //============================================================================== - /** Returns the number of free blocks on the disk. - - There are 75 blocks per second, at 44100Hz. - */ - int getNumAvailableAudioBlocks() const; - - /** Adds a track to be written. - - The source passed-in here will be kept by this object, and it will - be used and deleted at some point in the future, either during the - burn() method or when this AudioCDBurner object is deleted. Your caller - method shouldn't keep a reference to it or use it again after passing - it in here. - */ - bool addAudioTrack (AudioSource* source, int numSamples); - - //============================================================================== - /** Receives progress callbacks during a cd-burn operation. - @see AudioCDBurner::burn() - */ - class BurnProgressListener - { - public: - BurnProgressListener() noexcept {} - virtual ~BurnProgressListener() {} - - /** Called at intervals to report on the progress of the AudioCDBurner. - - To cancel the burn, return true from this method. - */ - virtual bool audioCDBurnProgress (float proportionComplete) = 0; - }; - - /** Runs the burn process. - This method will block until the operation is complete. - - @param listener the object to receive callbacks about progress - @param ejectDiscAfterwards whether to eject the disk after the burn completes - @param performFakeBurnForTesting if true, no data will actually be written to the disk - @param writeSpeed one of the write speeds from getAvailableWriteSpeeds(), or - 0 or less to mean the fastest speed. - */ - String burn (BurnProgressListener* listener, - bool ejectDiscAfterwards, - bool performFakeBurnForTesting, - int writeSpeed); - - /** If a burn operation is currently in progress, this tells it to stop - as soon as possible. - - It's also possible to stop the burn process by returning true from - BurnProgressListener::audioCDBurnProgress() - */ - void abortBurn(); - -private: - //============================================================================== - AudioCDBurner (const int deviceIndex); - - class Pimpl; - friend struct ContainerDeletePolicy; - ScopedPointer pimpl; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioCDBurner) -}; - - -#endif -#endif // JUCE_AUDIOCDBURNER_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/audio_cd/juce_AudioCDReader.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/audio_cd/juce_AudioCDReader.cpp deleted file mode 100644 index ca9c5b0f26..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/audio_cd/juce_AudioCDReader.cpp +++ /dev/null @@ -1,57 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#if JUCE_USE_CDREADER - -int AudioCDReader::getNumTracks() const -{ - return trackStartSamples.size() - 1; -} - -int AudioCDReader::getPositionOfTrackStart (int trackNum) const -{ - return trackStartSamples [trackNum]; -} - -const Array& AudioCDReader::getTrackOffsets() const -{ - return trackStartSamples; -} - -int AudioCDReader::getCDDBId() -{ - int checksum = 0; - const int numTracks = getNumTracks(); - - for (int i = 0; i < numTracks; ++i) - for (int offset = (trackStartSamples.getUnchecked(i) + 88200) / 44100; offset > 0; offset /= 10) - checksum += offset % 10; - - const int length = (trackStartSamples.getLast() - trackStartSamples.getFirst()) / 44100; - - // CCLLLLTT: checksum, length, tracks - return ((checksum & 0xff) << 24) | (length << 8) | numTracks; -} - -#endif diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/audio_cd/juce_AudioCDReader.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/audio_cd/juce_AudioCDReader.h deleted file mode 100644 index 0e868dba62..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/audio_cd/juce_AudioCDReader.h +++ /dev/null @@ -1,174 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_AUDIOCDREADER_H_INCLUDED -#define JUCE_AUDIOCDREADER_H_INCLUDED - -#if JUCE_USE_CDREADER || DOXYGEN - - -//============================================================================== -/** - A type of AudioFormatReader that reads from an audio CD. - - One of these can be used to read a CD as if it's one big audio stream. Use the - getPositionOfTrackStart() method to find where the individual tracks are - within the stream. - - @see AudioFormatReader -*/ -class JUCE_API AudioCDReader : public AudioFormatReader -{ -public: - //============================================================================== - /** Returns a list of names of Audio CDs currently available for reading. - - If there's a CD drive but no CD in it, this might return an empty list, or - possibly a device that can be opened but which has no tracks, depending - on the platform. - - @see createReaderForCD - */ - static StringArray getAvailableCDNames(); - - /** Tries to create an AudioFormatReader that can read from an Audio CD. - - @param index the index of one of the available CDs - use getAvailableCDNames() - to find out how many there are. - @returns a new AudioCDReader object, or nullptr if it couldn't be created. The - caller will be responsible for deleting the object returned. - */ - static AudioCDReader* createReaderForCD (const int index); - - //============================================================================== - /** Destructor. */ - ~AudioCDReader(); - - /** Implementation of the AudioFormatReader method. */ - bool readSamples (int** destSamples, int numDestChannels, int startOffsetInDestBuffer, - int64 startSampleInFile, int numSamples) override; - - /** Checks whether the CD has been removed from the drive. */ - bool isCDStillPresent() const; - - /** Returns the total number of tracks (audio + data). */ - int getNumTracks() const; - - /** Finds the sample offset of the start of a track. - @param trackNum the track number, where trackNum = 0 is the first track - and trackNum = getNumTracks() means the end of the CD. - */ - int getPositionOfTrackStart (int trackNum) const; - - /** Returns true if a given track is an audio track. - @param trackNum the track number, where 0 is the first track. - */ - bool isTrackAudio (int trackNum) const; - - /** Returns an array of sample offsets for the start of each track, followed by - the sample position of the end of the CD. - */ - const Array& getTrackOffsets() const; - - /** Refreshes the object's table of contents. - - If the disc has been ejected and a different one put in since this - object was created, this will cause it to update its idea of how many tracks - there are, etc. - */ - void refreshTrackLengths(); - - /** Enables scanning for indexes within tracks. - @see getLastIndex - */ - void enableIndexScanning (bool enabled); - - /** Returns the index number found during the last read() call. - - Index scanning is turned off by default - turn it on with enableIndexScanning(). - - Then when the read() method is called, if it comes across an index within that - block, the index number is stored and returned by this method. - - Some devices might not support indexes, of course. - - (If you don't know what CD indexes are, it's unlikely you'll ever need them). - - @see enableIndexScanning - */ - int getLastIndex() const; - - /** Scans a track to find the position of any indexes within it. - @param trackNumber the track to look in, where 0 is the first track on the disc - @returns an array of sample positions of any index points found (not including - the index that marks the start of the track) - */ - Array findIndexesInTrack (const int trackNumber); - - /** Returns the CDDB id number for the CD. - It's not a great way of identifying a disc, but it's traditional. - */ - int getCDDBId(); - - /** Tries to eject the disk. - Ejecting the disk might not actually be possible, e.g. if some other process is using it. - */ - void ejectDisk(); - - //============================================================================== - enum - { - framesPerSecond = 75, - samplesPerFrame = 44100 / framesPerSecond - }; - -private: - //============================================================================== - Array trackStartSamples; - - #if JUCE_MAC - File volumeDir; - Array tracks; - int currentReaderTrack; - ScopedPointer reader; - AudioCDReader (const File& volume); - - #elif JUCE_WINDOWS - bool audioTracks [100]; - void* handle; - MemoryBlock buffer; - bool indexingEnabled; - int lastIndex, firstFrameInBuffer, samplesInBuffer; - AudioCDReader (void* handle); - int getIndexAt (int samplePos); - - #elif JUCE_LINUX - AudioCDReader(); - #endif - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioCDReader) -}; - -#endif -#endif // JUCE_AUDIOCDREADER_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/audio_io/juce_AudioDeviceManager.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/audio_io/juce_AudioDeviceManager.cpp deleted file mode 100644 index fad5eea593..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/audio_io/juce_AudioDeviceManager.cpp +++ /dev/null @@ -1,987 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -AudioDeviceManager::AudioDeviceSetup::AudioDeviceSetup() - : sampleRate (0), - bufferSize (0), - useDefaultInputChannels (true), - useDefaultOutputChannels (true) -{ -} - -bool AudioDeviceManager::AudioDeviceSetup::operator== (const AudioDeviceManager::AudioDeviceSetup& other) const -{ - return outputDeviceName == other.outputDeviceName - && inputDeviceName == other.inputDeviceName - && sampleRate == other.sampleRate - && bufferSize == other.bufferSize - && inputChannels == other.inputChannels - && useDefaultInputChannels == other.useDefaultInputChannels - && outputChannels == other.outputChannels - && useDefaultOutputChannels == other.useDefaultOutputChannels; -} - -//============================================================================== -class AudioDeviceManager::CallbackHandler : public AudioIODeviceCallback, - public MidiInputCallback, - public AudioIODeviceType::Listener -{ -public: - CallbackHandler (AudioDeviceManager& adm) noexcept : owner (adm) {} - -private: - void audioDeviceIOCallback (const float** ins, int numIns, float** outs, int numOuts, int numSamples) override - { - owner.audioDeviceIOCallbackInt (ins, numIns, outs, numOuts, numSamples); - } - - void audioDeviceAboutToStart (AudioIODevice* device) override - { - owner.audioDeviceAboutToStartInt (device); - } - - void audioDeviceStopped() override - { - owner.audioDeviceStoppedInt(); - } - - void audioDeviceError (const String& message) override - { - owner.audioDeviceErrorInt (message); - } - - void handleIncomingMidiMessage (MidiInput* source, const MidiMessage& message) override - { - owner.handleIncomingMidiMessageInt (source, message); - } - - void audioDeviceListChanged() override - { - owner.audioDeviceListChanged(); - } - - AudioDeviceManager& owner; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (CallbackHandler) -}; - - -//============================================================================== -AudioDeviceManager::AudioDeviceManager() - : numInputChansNeeded (0), - numOutputChansNeeded (2), - listNeedsScanning (true), - useInputNames (false), - inputLevel (0), - testSoundPosition (0), - cpuUsageMs (0), - timeToCpuScale (0) -{ - callbackHandler = new CallbackHandler (*this); -} - -AudioDeviceManager::~AudioDeviceManager() -{ - currentAudioDevice = nullptr; - defaultMidiOutput = nullptr; -} - - -//============================================================================== -void AudioDeviceManager::createDeviceTypesIfNeeded() -{ - if (availableDeviceTypes.size() == 0) - { - OwnedArray types; - createAudioDeviceTypes (types); - - for (int i = 0; i < types.size(); ++i) - addAudioDeviceType (types.getUnchecked(i)); - - types.clear (false); - - if (AudioIODeviceType* first = availableDeviceTypes.getFirst()) - currentDeviceType = first->getTypeName(); - } -} - -const OwnedArray& AudioDeviceManager::getAvailableDeviceTypes() -{ - scanDevicesIfNeeded(); - return availableDeviceTypes; -} - -void AudioDeviceManager::audioDeviceListChanged() -{ - if (currentAudioDevice != nullptr) - { - currentSetup.sampleRate = currentAudioDevice->getCurrentSampleRate(); - currentSetup.bufferSize = currentAudioDevice->getCurrentBufferSizeSamples(); - currentSetup.inputChannels = currentAudioDevice->getActiveInputChannels(); - currentSetup.outputChannels = currentAudioDevice->getActiveOutputChannels(); - } - - sendChangeMessage(); -} - -//============================================================================== -static void addIfNotNull (OwnedArray& list, AudioIODeviceType* const device) -{ - if (device != nullptr) - list.add (device); -} - -void AudioDeviceManager::createAudioDeviceTypes (OwnedArray& list) -{ - addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_WASAPI()); - addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_DirectSound()); - addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_ASIO()); - addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_CoreAudio()); - addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_iOSAudio()); - addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_ALSA()); - addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_JACK()); - addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_OpenSLES()); - addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_Android()); -} - -void AudioDeviceManager::addAudioDeviceType (AudioIODeviceType* newDeviceType) -{ - if (newDeviceType != nullptr) - { - jassert (lastDeviceTypeConfigs.size() == availableDeviceTypes.size()); - availableDeviceTypes.add (newDeviceType); - lastDeviceTypeConfigs.add (new AudioDeviceSetup()); - - newDeviceType->addListener (callbackHandler); - } -} - -//============================================================================== -String AudioDeviceManager::initialise (const int numInputChannelsNeeded, - const int numOutputChannelsNeeded, - const XmlElement* const xml, - const bool selectDefaultDeviceOnFailure, - const String& preferredDefaultDeviceName, - const AudioDeviceSetup* preferredSetupOptions) -{ - scanDevicesIfNeeded(); - - numInputChansNeeded = numInputChannelsNeeded; - numOutputChansNeeded = numOutputChannelsNeeded; - - if (xml != nullptr && xml->hasTagName ("DEVICESETUP")) - return initialiseFromXML (*xml, selectDefaultDeviceOnFailure, - preferredDefaultDeviceName, preferredSetupOptions); - - return initialiseDefault (preferredDefaultDeviceName, preferredSetupOptions); -} - -String AudioDeviceManager::initialiseDefault (const String& preferredDefaultDeviceName, - const AudioDeviceSetup* preferredSetupOptions) -{ - AudioDeviceSetup setup; - - if (preferredSetupOptions != nullptr) - { - setup = *preferredSetupOptions; - } - else if (preferredDefaultDeviceName.isNotEmpty()) - { - for (int j = availableDeviceTypes.size(); --j >= 0;) - { - AudioIODeviceType* const type = availableDeviceTypes.getUnchecked(j); - - const StringArray outs (type->getDeviceNames (false)); - - for (int i = 0; i < outs.size(); ++i) - { - if (outs[i].matchesWildcard (preferredDefaultDeviceName, true)) - { - setup.outputDeviceName = outs[i]; - break; - } - } - - const StringArray ins (type->getDeviceNames (true)); - - for (int i = 0; i < ins.size(); ++i) - { - if (ins[i].matchesWildcard (preferredDefaultDeviceName, true)) - { - setup.inputDeviceName = ins[i]; - break; - } - } - } - } - - insertDefaultDeviceNames (setup); - return setAudioDeviceSetup (setup, false); -} - -String AudioDeviceManager::initialiseFromXML (const XmlElement& xml, - const bool selectDefaultDeviceOnFailure, - const String& preferredDefaultDeviceName, - const AudioDeviceSetup* preferredSetupOptions) -{ - lastExplicitSettings = new XmlElement (xml); - - String error; - AudioDeviceSetup setup; - - if (preferredSetupOptions != nullptr) - setup = *preferredSetupOptions; - - if (xml.getStringAttribute ("audioDeviceName").isNotEmpty()) - { - setup.inputDeviceName = setup.outputDeviceName - = xml.getStringAttribute ("audioDeviceName"); - } - else - { - setup.inputDeviceName = xml.getStringAttribute ("audioInputDeviceName"); - setup.outputDeviceName = xml.getStringAttribute ("audioOutputDeviceName"); - } - - currentDeviceType = xml.getStringAttribute ("deviceType"); - - if (findType (currentDeviceType) == nullptr) - { - if (AudioIODeviceType* const type = findType (setup.inputDeviceName, setup.outputDeviceName)) - currentDeviceType = type->getTypeName(); - else if (availableDeviceTypes.size() > 0) - currentDeviceType = availableDeviceTypes.getUnchecked(0)->getTypeName(); - } - - setup.bufferSize = xml.getIntAttribute ("audioDeviceBufferSize"); - setup.sampleRate = xml.getDoubleAttribute ("audioDeviceRate"); - - setup.inputChannels .parseString (xml.getStringAttribute ("audioDeviceInChans", "11"), 2); - setup.outputChannels.parseString (xml.getStringAttribute ("audioDeviceOutChans", "11"), 2); - - setup.useDefaultInputChannels = ! xml.hasAttribute ("audioDeviceInChans"); - setup.useDefaultOutputChannels = ! xml.hasAttribute ("audioDeviceOutChans"); - - error = setAudioDeviceSetup (setup, true); - - midiInsFromXml.clear(); - - forEachXmlChildElementWithTagName (xml, c, "MIDIINPUT") - midiInsFromXml.add (c->getStringAttribute ("name")); - - const StringArray allMidiIns (MidiInput::getDevices()); - - for (int i = allMidiIns.size(); --i >= 0;) - setMidiInputEnabled (allMidiIns[i], midiInsFromXml.contains (allMidiIns[i])); - - if (error.isNotEmpty() && selectDefaultDeviceOnFailure) - error = initialise (numInputChansNeeded, numOutputChansNeeded, - nullptr, false, preferredDefaultDeviceName); - - setDefaultMidiOutput (xml.getStringAttribute ("defaultMidiOutput")); - - return error; -} - -String AudioDeviceManager::initialiseWithDefaultDevices (int numInputChannelsNeeded, - int numOutputChannelsNeeded) -{ - lastExplicitSettings = nullptr; - - return initialise (numInputChannelsNeeded, numOutputChannelsNeeded, - nullptr, false, String(), nullptr); -} - -void AudioDeviceManager::insertDefaultDeviceNames (AudioDeviceSetup& setup) const -{ - if (AudioIODeviceType* type = getCurrentDeviceTypeObject()) - { - if (setup.outputDeviceName.isEmpty()) - setup.outputDeviceName = type->getDeviceNames (false) [type->getDefaultDeviceIndex (false)]; - - if (setup.inputDeviceName.isEmpty()) - setup.inputDeviceName = type->getDeviceNames (true) [type->getDefaultDeviceIndex (true)]; - } -} - -XmlElement* AudioDeviceManager::createStateXml() const -{ - return lastExplicitSettings.createCopy(); -} - -//============================================================================== -void AudioDeviceManager::scanDevicesIfNeeded() -{ - if (listNeedsScanning) - { - listNeedsScanning = false; - - createDeviceTypesIfNeeded(); - - for (int i = availableDeviceTypes.size(); --i >= 0;) - availableDeviceTypes.getUnchecked(i)->scanForDevices(); - } -} - -AudioIODeviceType* AudioDeviceManager::findType (const String& typeName) -{ - scanDevicesIfNeeded(); - - for (int i = availableDeviceTypes.size(); --i >= 0;) - if (availableDeviceTypes.getUnchecked(i)->getTypeName() == typeName) - return availableDeviceTypes.getUnchecked(i); - - return nullptr; -} - -AudioIODeviceType* AudioDeviceManager::findType (const String& inputName, const String& outputName) -{ - scanDevicesIfNeeded(); - - for (int i = availableDeviceTypes.size(); --i >= 0;) - { - AudioIODeviceType* const type = availableDeviceTypes.getUnchecked(i); - - if ((inputName.isNotEmpty() && type->getDeviceNames (true).contains (inputName, true)) - || (outputName.isNotEmpty() && type->getDeviceNames (false).contains (outputName, true))) - { - return type; - } - } - - return nullptr; -} - -void AudioDeviceManager::getAudioDeviceSetup (AudioDeviceSetup& setup) -{ - setup = currentSetup; -} - -void AudioDeviceManager::deleteCurrentDevice() -{ - currentAudioDevice = nullptr; - currentSetup.inputDeviceName.clear(); - currentSetup.outputDeviceName.clear(); -} - -void AudioDeviceManager::setCurrentAudioDeviceType (const String& type, - const bool treatAsChosenDevice) -{ - for (int i = 0; i < availableDeviceTypes.size(); ++i) - { - if (availableDeviceTypes.getUnchecked(i)->getTypeName() == type - && currentDeviceType != type) - { - if (currentAudioDevice != nullptr) - { - closeAudioDevice(); - Thread::sleep (1500); // allow a moment for OS devices to sort themselves out, to help - // avoid things like DirectSound/ASIO clashes - } - - currentDeviceType = type; - - AudioDeviceSetup s (*lastDeviceTypeConfigs.getUnchecked(i)); - insertDefaultDeviceNames (s); - - setAudioDeviceSetup (s, treatAsChosenDevice); - - sendChangeMessage(); - break; - } - } -} - -AudioIODeviceType* AudioDeviceManager::getCurrentDeviceTypeObject() const -{ - for (int i = 0; i < availableDeviceTypes.size(); ++i) - if (availableDeviceTypes.getUnchecked(i)->getTypeName() == currentDeviceType) - return availableDeviceTypes.getUnchecked(i); - - return availableDeviceTypes[0]; -} - -String AudioDeviceManager::setAudioDeviceSetup (const AudioDeviceSetup& newSetup, - const bool treatAsChosenDevice) -{ - jassert (&newSetup != ¤tSetup); // this will have no effect - - if (newSetup == currentSetup && currentAudioDevice != nullptr) - return String(); - - if (! (newSetup == currentSetup)) - sendChangeMessage(); - - stopDevice(); - - const String newInputDeviceName (numInputChansNeeded == 0 ? String() : newSetup.inputDeviceName); - const String newOutputDeviceName (numOutputChansNeeded == 0 ? String() : newSetup.outputDeviceName); - - String error; - AudioIODeviceType* type = getCurrentDeviceTypeObject(); - - if (type == nullptr || (newInputDeviceName.isEmpty() && newOutputDeviceName.isEmpty())) - { - deleteCurrentDevice(); - - if (treatAsChosenDevice) - updateXml(); - - return String(); - } - - if (currentSetup.inputDeviceName != newInputDeviceName - || currentSetup.outputDeviceName != newOutputDeviceName - || currentAudioDevice == nullptr) - { - deleteCurrentDevice(); - scanDevicesIfNeeded(); - - if (newOutputDeviceName.isNotEmpty() - && ! type->getDeviceNames (false).contains (newOutputDeviceName)) - { - return "No such device: " + newOutputDeviceName; - } - - if (newInputDeviceName.isNotEmpty() - && ! type->getDeviceNames (true).contains (newInputDeviceName)) - { - return "No such device: " + newInputDeviceName; - } - - currentAudioDevice = type->createDevice (newOutputDeviceName, newInputDeviceName); - - if (currentAudioDevice == nullptr) - error = "Can't open the audio device!\n\n" - "This may be because another application is currently using the same device - " - "if so, you should close any other applications and try again!"; - else - error = currentAudioDevice->getLastError(); - - if (error.isNotEmpty()) - { - deleteCurrentDevice(); - return error; - } - - if (newSetup.useDefaultInputChannels) - { - inputChannels.clear(); - inputChannels.setRange (0, numInputChansNeeded, true); - } - - if (newSetup.useDefaultOutputChannels) - { - outputChannels.clear(); - outputChannels.setRange (0, numOutputChansNeeded, true); - } - - if (newInputDeviceName.isEmpty()) inputChannels.clear(); - if (newOutputDeviceName.isEmpty()) outputChannels.clear(); - } - - if (! newSetup.useDefaultInputChannels) inputChannels = newSetup.inputChannels; - if (! newSetup.useDefaultOutputChannels) outputChannels = newSetup.outputChannels; - - currentSetup = newSetup; - - currentSetup.sampleRate = chooseBestSampleRate (newSetup.sampleRate); - currentSetup.bufferSize = chooseBestBufferSize (newSetup.bufferSize); - - error = currentAudioDevice->open (inputChannels, - outputChannels, - currentSetup.sampleRate, - currentSetup.bufferSize); - - if (error.isEmpty()) - { - currentDeviceType = currentAudioDevice->getTypeName(); - - currentAudioDevice->start (callbackHandler); - - currentSetup.sampleRate = currentAudioDevice->getCurrentSampleRate(); - currentSetup.bufferSize = currentAudioDevice->getCurrentBufferSizeSamples(); - currentSetup.inputChannels = currentAudioDevice->getActiveInputChannels(); - currentSetup.outputChannels = currentAudioDevice->getActiveOutputChannels(); - - for (int i = 0; i < availableDeviceTypes.size(); ++i) - if (availableDeviceTypes.getUnchecked (i)->getTypeName() == currentDeviceType) - *(lastDeviceTypeConfigs.getUnchecked (i)) = currentSetup; - - if (treatAsChosenDevice) - updateXml(); - } - else - { - deleteCurrentDevice(); - } - - return error; -} - -double AudioDeviceManager::chooseBestSampleRate (double rate) const -{ - jassert (currentAudioDevice != nullptr); - - const Array rates (currentAudioDevice->getAvailableSampleRates()); - - if (rate > 0 && rates.contains (rate)) - return rate; - - double lowestAbove44 = 0.0; - - for (int i = rates.size(); --i >= 0;) - { - const double sr = rates[i]; - - if (sr >= 44100.0 && (lowestAbove44 < 1.0 || sr < lowestAbove44)) - lowestAbove44 = sr; - } - - if (lowestAbove44 > 0.0) - return lowestAbove44; - - return rates[0]; -} - -int AudioDeviceManager::chooseBestBufferSize (int bufferSize) const -{ - jassert (currentAudioDevice != nullptr); - - if (bufferSize > 0 && currentAudioDevice->getAvailableBufferSizes().contains (bufferSize)) - return bufferSize; - - return currentAudioDevice->getDefaultBufferSize(); -} - -void AudioDeviceManager::stopDevice() -{ - if (currentAudioDevice != nullptr) - currentAudioDevice->stop(); - - testSound = nullptr; -} - -void AudioDeviceManager::closeAudioDevice() -{ - stopDevice(); - currentAudioDevice = nullptr; -} - -void AudioDeviceManager::restartLastAudioDevice() -{ - if (currentAudioDevice == nullptr) - { - if (currentSetup.inputDeviceName.isEmpty() - && currentSetup.outputDeviceName.isEmpty()) - { - // This method will only reload the last device that was running - // before closeAudioDevice() was called - you need to actually open - // one first, with setAudioDevice(). - jassertfalse; - return; - } - - AudioDeviceSetup s (currentSetup); - setAudioDeviceSetup (s, false); - } -} - -void AudioDeviceManager::updateXml() -{ - lastExplicitSettings = new XmlElement ("DEVICESETUP"); - - lastExplicitSettings->setAttribute ("deviceType", currentDeviceType); - lastExplicitSettings->setAttribute ("audioOutputDeviceName", currentSetup.outputDeviceName); - lastExplicitSettings->setAttribute ("audioInputDeviceName", currentSetup.inputDeviceName); - - if (currentAudioDevice != nullptr) - { - lastExplicitSettings->setAttribute ("audioDeviceRate", currentAudioDevice->getCurrentSampleRate()); - - if (currentAudioDevice->getDefaultBufferSize() != currentAudioDevice->getCurrentBufferSizeSamples()) - lastExplicitSettings->setAttribute ("audioDeviceBufferSize", currentAudioDevice->getCurrentBufferSizeSamples()); - - if (! currentSetup.useDefaultInputChannels) - lastExplicitSettings->setAttribute ("audioDeviceInChans", currentSetup.inputChannels.toString (2)); - - if (! currentSetup.useDefaultOutputChannels) - lastExplicitSettings->setAttribute ("audioDeviceOutChans", currentSetup.outputChannels.toString (2)); - } - - for (int i = 0; i < enabledMidiInputs.size(); ++i) - lastExplicitSettings->createNewChildElement ("MIDIINPUT") - ->setAttribute ("name", enabledMidiInputs[i]->getName()); - - if (midiInsFromXml.size() > 0) - { - // Add any midi devices that have been enabled before, but which aren't currently - // open because the device has been disconnected. - const StringArray availableMidiDevices (MidiInput::getDevices()); - - for (int i = 0; i < midiInsFromXml.size(); ++i) - if (! availableMidiDevices.contains (midiInsFromXml[i], true)) - lastExplicitSettings->createNewChildElement ("MIDIINPUT") - ->setAttribute ("name", midiInsFromXml[i]); - } - - if (defaultMidiOutputName.isNotEmpty()) - lastExplicitSettings->setAttribute ("defaultMidiOutput", defaultMidiOutputName); -} - -//============================================================================== -void AudioDeviceManager::addAudioCallback (AudioIODeviceCallback* newCallback) -{ - { - const ScopedLock sl (audioCallbackLock); - if (callbacks.contains (newCallback)) - return; - } - - if (currentAudioDevice != nullptr && newCallback != nullptr) - newCallback->audioDeviceAboutToStart (currentAudioDevice); - - const ScopedLock sl (audioCallbackLock); - callbacks.add (newCallback); -} - -void AudioDeviceManager::removeAudioCallback (AudioIODeviceCallback* callbackToRemove) -{ - if (callbackToRemove != nullptr) - { - bool needsDeinitialising = currentAudioDevice != nullptr; - - { - const ScopedLock sl (audioCallbackLock); - - needsDeinitialising = needsDeinitialising && callbacks.contains (callbackToRemove); - callbacks.removeFirstMatchingValue (callbackToRemove); - } - - if (needsDeinitialising) - callbackToRemove->audioDeviceStopped(); - } -} - -void AudioDeviceManager::audioDeviceIOCallbackInt (const float** inputChannelData, - int numInputChannels, - float** outputChannelData, - int numOutputChannels, - int numSamples) -{ - const ScopedLock sl (audioCallbackLock); - - if (inputLevelMeasurementEnabledCount.get() > 0 && numInputChannels > 0) - { - for (int j = 0; j < numSamples; ++j) - { - float s = 0; - - for (int i = 0; i < numInputChannels; ++i) - s += std::abs (inputChannelData[i][j]); - - s /= numInputChannels; - - const double decayFactor = 0.99992; - - if (s > inputLevel) - inputLevel = s; - else if (inputLevel > 0.001f) - inputLevel *= decayFactor; - else - inputLevel = 0; - } - } - else - { - inputLevel = 0; - } - - if (callbacks.size() > 0) - { - const double callbackStartTime = Time::getMillisecondCounterHiRes(); - - tempBuffer.setSize (jmax (1, numOutputChannels), jmax (1, numSamples), false, false, true); - - callbacks.getUnchecked(0)->audioDeviceIOCallback (inputChannelData, numInputChannels, - outputChannelData, numOutputChannels, numSamples); - - float** const tempChans = tempBuffer.getArrayOfWritePointers(); - - for (int i = callbacks.size(); --i > 0;) - { - callbacks.getUnchecked(i)->audioDeviceIOCallback (inputChannelData, numInputChannels, - tempChans, numOutputChannels, numSamples); - - for (int chan = 0; chan < numOutputChannels; ++chan) - { - if (const float* const src = tempChans [chan]) - if (float* const dst = outputChannelData [chan]) - for (int j = 0; j < numSamples; ++j) - dst[j] += src[j]; - } - } - - const double msTaken = Time::getMillisecondCounterHiRes() - callbackStartTime; - const double filterAmount = 0.2; - cpuUsageMs += filterAmount * (msTaken - cpuUsageMs); - } - else - { - for (int i = 0; i < numOutputChannels; ++i) - zeromem (outputChannelData[i], sizeof (float) * (size_t) numSamples); - } - - if (testSound != nullptr) - { - const int numSamps = jmin (numSamples, testSound->getNumSamples() - testSoundPosition); - const float* const src = testSound->getReadPointer (0, testSoundPosition); - - for (int i = 0; i < numOutputChannels; ++i) - for (int j = 0; j < numSamps; ++j) - outputChannelData [i][j] += src[j]; - - testSoundPosition += numSamps; - if (testSoundPosition >= testSound->getNumSamples()) - testSound = nullptr; - } -} - -void AudioDeviceManager::audioDeviceAboutToStartInt (AudioIODevice* const device) -{ - cpuUsageMs = 0; - - const double sampleRate = device->getCurrentSampleRate(); - const int blockSize = device->getCurrentBufferSizeSamples(); - - if (sampleRate > 0.0 && blockSize > 0) - { - const double msPerBlock = 1000.0 * blockSize / sampleRate; - timeToCpuScale = (msPerBlock > 0.0) ? (1.0 / msPerBlock) : 0.0; - } - - { - const ScopedLock sl (audioCallbackLock); - for (int i = callbacks.size(); --i >= 0;) - callbacks.getUnchecked(i)->audioDeviceAboutToStart (device); - } - - sendChangeMessage(); -} - -void AudioDeviceManager::audioDeviceStoppedInt() -{ - cpuUsageMs = 0; - timeToCpuScale = 0; - sendChangeMessage(); - - const ScopedLock sl (audioCallbackLock); - for (int i = callbacks.size(); --i >= 0;) - callbacks.getUnchecked(i)->audioDeviceStopped(); -} - -void AudioDeviceManager::audioDeviceErrorInt (const String& message) -{ - const ScopedLock sl (audioCallbackLock); - for (int i = callbacks.size(); --i >= 0;) - callbacks.getUnchecked(i)->audioDeviceError (message); -} - -double AudioDeviceManager::getCpuUsage() const -{ - return jlimit (0.0, 1.0, timeToCpuScale * cpuUsageMs); -} - -//============================================================================== -void AudioDeviceManager::setMidiInputEnabled (const String& name, const bool enabled) -{ - if (enabled != isMidiInputEnabled (name)) - { - if (enabled) - { - const int index = MidiInput::getDevices().indexOf (name); - - if (index >= 0) - { - if (MidiInput* const midiIn = MidiInput::openDevice (index, callbackHandler)) - { - enabledMidiInputs.add (midiIn); - midiIn->start(); - } - } - } - else - { - for (int i = enabledMidiInputs.size(); --i >= 0;) - if (enabledMidiInputs[i]->getName() == name) - enabledMidiInputs.remove (i); - } - - updateXml(); - sendChangeMessage(); - } -} - -bool AudioDeviceManager::isMidiInputEnabled (const String& name) const -{ - for (int i = enabledMidiInputs.size(); --i >= 0;) - if (enabledMidiInputs[i]->getName() == name) - return true; - - return false; -} - -void AudioDeviceManager::addMidiInputCallback (const String& name, MidiInputCallback* callbackToAdd) -{ - removeMidiInputCallback (name, callbackToAdd); - - if (name.isEmpty() || isMidiInputEnabled (name)) - { - const ScopedLock sl (midiCallbackLock); - - MidiCallbackInfo mc; - mc.deviceName = name; - mc.callback = callbackToAdd; - midiCallbacks.add (mc); - } -} - -void AudioDeviceManager::removeMidiInputCallback (const String& name, MidiInputCallback* callbackToRemove) -{ - for (int i = midiCallbacks.size(); --i >= 0;) - { - const MidiCallbackInfo& mc = midiCallbacks.getReference(i); - - if (mc.callback == callbackToRemove && mc.deviceName == name) - { - const ScopedLock sl (midiCallbackLock); - midiCallbacks.remove (i); - } - } -} - -void AudioDeviceManager::handleIncomingMidiMessageInt (MidiInput* source, const MidiMessage& message) -{ - if (! message.isActiveSense()) - { - const ScopedLock sl (midiCallbackLock); - - for (int i = 0; i < midiCallbacks.size(); ++i) - { - const MidiCallbackInfo& mc = midiCallbacks.getReference(i); - - if (mc.deviceName.isEmpty() || mc.deviceName == source->getName()) - mc.callback->handleIncomingMidiMessage (source, message); - } - } -} - -//============================================================================== -void AudioDeviceManager::setDefaultMidiOutput (const String& deviceName) -{ - if (defaultMidiOutputName != deviceName) - { - Array oldCallbacks; - - { - const ScopedLock sl (audioCallbackLock); - oldCallbacks.swapWith (callbacks); - } - - if (currentAudioDevice != nullptr) - for (int i = oldCallbacks.size(); --i >= 0;) - oldCallbacks.getUnchecked(i)->audioDeviceStopped(); - - defaultMidiOutput = nullptr; - defaultMidiOutputName = deviceName; - - if (deviceName.isNotEmpty()) - defaultMidiOutput = MidiOutput::openDevice (MidiOutput::getDevices().indexOf (deviceName)); - - if (currentAudioDevice != nullptr) - for (int i = oldCallbacks.size(); --i >= 0;) - oldCallbacks.getUnchecked(i)->audioDeviceAboutToStart (currentAudioDevice); - - { - const ScopedLock sl (audioCallbackLock); - oldCallbacks.swapWith (callbacks); - } - - updateXml(); - sendChangeMessage(); - } -} - -//============================================================================== -void AudioDeviceManager::playTestSound() -{ - { // cunningly nested to swap, unlock and delete in that order. - ScopedPointer oldSound; - - { - const ScopedLock sl (audioCallbackLock); - oldSound = testSound; - } - } - - testSoundPosition = 0; - - if (currentAudioDevice != nullptr) - { - const double sampleRate = currentAudioDevice->getCurrentSampleRate(); - const int soundLength = (int) sampleRate; - - const double frequency = 440.0; - const float amplitude = 0.5f; - - const double phasePerSample = double_Pi * 2.0 / (sampleRate / frequency); - - AudioSampleBuffer* const newSound = new AudioSampleBuffer (1, soundLength); - - for (int i = 0; i < soundLength; ++i) - newSound->setSample (0, i, amplitude * (float) std::sin (i * phasePerSample)); - - newSound->applyGainRamp (0, 0, soundLength / 10, 0.0f, 1.0f); - newSound->applyGainRamp (0, soundLength - soundLength / 4, soundLength / 4, 1.0f, 0.0f); - - const ScopedLock sl (audioCallbackLock); - testSound = newSound; - } -} - -void AudioDeviceManager::enableInputLevelMeasurement (const bool enableMeasurement) -{ - if (enableMeasurement) - ++inputLevelMeasurementEnabledCount; - else - --inputLevelMeasurementEnabledCount; - - inputLevel = 0; -} - -double AudioDeviceManager::getCurrentInputLevel() const -{ - jassert (inputLevelMeasurementEnabledCount.get() > 0); // you need to call enableInputLevelMeasurement() before using this! - return inputLevel; -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/audio_io/juce_AudioDeviceManager.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/audio_io/juce_AudioDeviceManager.h deleted file mode 100644 index f1e483f332..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/audio_io/juce_AudioDeviceManager.h +++ /dev/null @@ -1,512 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_AUDIODEVICEMANAGER_H_INCLUDED -#define JUCE_AUDIODEVICEMANAGER_H_INCLUDED - - -//============================================================================== -/** - Manages the state of some audio and midi i/o devices. - - This class keeps tracks of a currently-selected audio device, through - with which it continuously streams data from an audio callback, as well as - one or more midi inputs. - - The idea is that your application will create one global instance of this object, - and let it take care of creating and deleting specific types of audio devices - internally. So when the device is changed, your callbacks will just keep running - without having to worry about this. - - The manager can save and reload all of its device settings as XML, which - makes it very easy for you to save and reload the audio setup of your - application. - - And to make it easy to let the user change its settings, there's a component - to do just that - the AudioDeviceSelectorComponent class, which contains a set of - device selection/sample-rate/latency controls. - - To use an AudioDeviceManager, create one, and use initialise() to set it up. Then - call addAudioCallback() to register your audio callback with it, and use that to process - your audio data. - - The manager also acts as a handy hub for incoming midi messages, allowing a - listener to register for messages from either a specific midi device, or from whatever - the current default midi input device is. The listener then doesn't have to worry about - re-registering with different midi devices if they are changed or deleted. - - And yet another neat trick is that amount of CPU time being used is measured and - available with the getCpuUsage() method. - - The AudioDeviceManager is a ChangeBroadcaster, and will send a change message to - listeners whenever one of its settings is changed. - - @see AudioDeviceSelectorComponent, AudioIODevice, AudioIODeviceType -*/ -class JUCE_API AudioDeviceManager : public ChangeBroadcaster -{ -public: - //============================================================================== - /** Creates a default AudioDeviceManager. - - Initially no audio device will be selected. You should call the initialise() method - and register an audio callback with setAudioCallback() before it'll be able to - actually make any noise. - */ - AudioDeviceManager(); - - /** Destructor. */ - ~AudioDeviceManager(); - - //============================================================================== - /** - This structure holds a set of properties describing the current audio setup. - - An AudioDeviceManager uses this class to save/load its current settings, and to - specify your preferred options when opening a device. - - @see AudioDeviceManager::setAudioDeviceSetup(), AudioDeviceManager::initialise() - */ - struct JUCE_API AudioDeviceSetup - { - /** Creates an AudioDeviceSetup object. - - The default constructor sets all the member variables to indicate default values. - You can then fill-in any values you want to before passing the object to - AudioDeviceManager::initialise(). - */ - AudioDeviceSetup(); - - bool operator== (const AudioDeviceSetup& other) const; - - /** The name of the audio device used for output. - The name has to be one of the ones listed by the AudioDeviceManager's currently - selected device type. - This may be the same as the input device. - An empty string indicates the default device. - */ - String outputDeviceName; - - /** The name of the audio device used for input. - This may be the same as the output device. - An empty string indicates the default device. - */ - String inputDeviceName; - - /** The current sample rate. - This rate is used for both the input and output devices. - A value of 0 indicates that you don't care what rate is used, and the - device will choose a sensible rate for you. - */ - double sampleRate; - - /** The buffer size, in samples. - This buffer size is used for both the input and output devices. - A value of 0 indicates the default buffer size. - */ - int bufferSize; - - /** The set of active input channels. - The bits that are set in this array indicate the channels of the - input device that are active. - If useDefaultInputChannels is true, this value is ignored. - */ - BigInteger inputChannels; - - /** If this is true, it indicates that the inputChannels array - should be ignored, and instead, the device's default channels - should be used. - */ - bool useDefaultInputChannels; - - /** The set of active output channels. - The bits that are set in this array indicate the channels of the - input device that are active. - If useDefaultOutputChannels is true, this value is ignored. - */ - BigInteger outputChannels; - - /** If this is true, it indicates that the outputChannels array - should be ignored, and instead, the device's default channels - should be used. - */ - bool useDefaultOutputChannels; - }; - - - //============================================================================== - /** Opens a set of audio devices ready for use. - - This will attempt to open either a default audio device, or one that was - previously saved as XML. - - @param numInputChannelsNeeded the maximum number of input channels your app would like to - use (the actual number of channels opened may be less than - the number requested) - @param numOutputChannelsNeeded the maximum number of output channels your app would like to - use (the actual number of channels opened may be less than - the number requested) - @param savedState either a previously-saved state that was produced - by createStateXml(), or nullptr if you want the manager - to choose the best device to open. - @param selectDefaultDeviceOnFailure if true, then if the device specified in the XML - fails to open, then a default device will be used - instead. If false, then on failure, no device is - opened. - @param preferredDefaultDeviceName if this is not empty, and there's a device with this - name, then that will be used as the default device - (assuming that there wasn't one specified in the XML). - The string can actually be a simple wildcard, containing "*" - and "?" characters - @param preferredSetupOptions if this is non-null, the structure will be used as the - set of preferred settings when opening the device. If you - use this parameter, the preferredDefaultDeviceName - field will be ignored - - @returns an error message if anything went wrong, or an empty string if it worked ok. - */ - String initialise (int numInputChannelsNeeded, - int numOutputChannelsNeeded, - const XmlElement* savedState, - bool selectDefaultDeviceOnFailure, - const String& preferredDefaultDeviceName = String(), - const AudioDeviceSetup* preferredSetupOptions = nullptr); - - /** Resets everything to a default device setup, clearing any stored settings. */ - String initialiseWithDefaultDevices (int numInputChannelsNeeded, - int numOutputChannelsNeeded); - - /** Returns some XML representing the current state of the manager. - - This stores the current device, its samplerate, block size, etc, and - can be restored later with initialise(). - - Note that this can return a null pointer if no settings have been explicitly changed - (i.e. if the device manager has just been left in its default state). - */ - XmlElement* createStateXml() const; - - //============================================================================== - /** Returns the current device properties that are in use. - @see setAudioDeviceSetup - */ - void getAudioDeviceSetup (AudioDeviceSetup& result); - - /** Changes the current device or its settings. - - If you want to change a device property, like the current sample rate or - block size, you can call getAudioDeviceSetup() to retrieve the current - settings, then tweak the appropriate fields in the AudioDeviceSetup structure, - and pass it back into this method to apply the new settings. - - @param newSetup the settings that you'd like to use - @param treatAsChosenDevice if this is true and if the device opens correctly, these new - settings will be taken as having been explicitly chosen by the - user, and the next time createStateXml() is called, these settings - will be returned. If it's false, then the device is treated as a - temporary or default device, and a call to createStateXml() will - return either the last settings that were made with treatAsChosenDevice - as true, or the last XML settings that were passed into initialise(). - @returns an error message if anything went wrong, or an empty string if it worked ok. - - @see getAudioDeviceSetup - */ - String setAudioDeviceSetup (const AudioDeviceSetup& newSetup, - bool treatAsChosenDevice); - - - /** Returns the currently-active audio device. */ - AudioIODevice* getCurrentAudioDevice() const noexcept { return currentAudioDevice; } - - /** Returns the type of audio device currently in use. - @see setCurrentAudioDeviceType - */ - String getCurrentAudioDeviceType() const { return currentDeviceType; } - - /** Returns the currently active audio device type object. - Don't keep a copy of this pointer - it's owned by the device manager and could - change at any time. - */ - AudioIODeviceType* getCurrentDeviceTypeObject() const; - - /** Changes the class of audio device being used. - - This switches between, e.g. ASIO and DirectSound. On the Mac you probably won't ever call - this because there's only one type: CoreAudio. - - For a list of types, see getAvailableDeviceTypes(). - */ - void setCurrentAudioDeviceType (const String& type, - bool treatAsChosenDevice); - - /** Closes the currently-open device. - You can call restartLastAudioDevice() later to reopen it in the same state - that it was just in. - */ - void closeAudioDevice(); - - /** Tries to reload the last audio device that was running. - - Note that this only reloads the last device that was running before - closeAudioDevice() was called - it doesn't reload any kind of saved-state, - and can only be called after a device has been opened with SetAudioDevice(). - - If a device is already open, this call will do nothing. - */ - void restartLastAudioDevice(); - - //============================================================================== - /** Registers an audio callback to be used. - - The manager will redirect callbacks from whatever audio device is currently - in use to all registered callback objects. If more than one callback is - active, they will all be given the same input data, and their outputs will - be summed. - - If necessary, this method will invoke audioDeviceAboutToStart() on the callback - object before returning. - - To remove a callback, use removeAudioCallback(). - */ - void addAudioCallback (AudioIODeviceCallback* newCallback); - - /** Deregisters a previously added callback. - - If necessary, this method will invoke audioDeviceStopped() on the callback - object before returning. - - @see addAudioCallback - */ - void removeAudioCallback (AudioIODeviceCallback* callback); - - //============================================================================== - /** Returns the average proportion of available CPU being spent inside the audio callbacks. - @returns A value between 0 and 1.0 to indicate the approximate proportion of CPU - time spent in the callbacks. - */ - double getCpuUsage() const; - - //============================================================================== - /** Enables or disables a midi input device. - - The list of devices can be obtained with the MidiInput::getDevices() method. - - Any incoming messages from enabled input devices will be forwarded on to all the - listeners that have been registered with the addMidiInputCallback() method. They - can either register for messages from a particular device, or from just the - "default" midi input. - - Routing the midi input via an AudioDeviceManager means that when a listener - registers for the default midi input, this default device can be changed by the - manager without the listeners having to know about it or re-register. - - It also means that a listener can stay registered for a midi input that is disabled - or not present, so that when the input is re-enabled, the listener will start - receiving messages again. - - @see addMidiInputCallback, isMidiInputEnabled - */ - void setMidiInputEnabled (const String& midiInputDeviceName, bool enabled); - - /** Returns true if a given midi input device is being used. - @see setMidiInputEnabled - */ - bool isMidiInputEnabled (const String& midiInputDeviceName) const; - - /** Registers a listener for callbacks when midi events arrive from a midi input. - - The device name can be empty to indicate that it wants to receive all incoming - events from all the enabled MIDI inputs. Or it can be the name of one of the - MIDI input devices if it just wants the events from that device. (see - MidiInput::getDevices() for the list of device names). - - Only devices which are enabled (see the setMidiInputEnabled() method) will have their - events forwarded on to listeners. - */ - void addMidiInputCallback (const String& midiInputDeviceName, - MidiInputCallback* callback); - - /** Removes a listener that was previously registered with addMidiInputCallback(). */ - void removeMidiInputCallback (const String& midiInputDeviceName, - MidiInputCallback* callback); - - //============================================================================== - /** Sets a midi output device to use as the default. - - The list of devices can be obtained with the MidiOutput::getDevices() method. - - The specified device will be opened automatically and can be retrieved with the - getDefaultMidiOutput() method. - - Pass in an empty string to deselect all devices. For the default device, you - can use MidiOutput::getDevices() [MidiOutput::getDefaultDeviceIndex()]. - - @see getDefaultMidiOutput, getDefaultMidiOutputName - */ - void setDefaultMidiOutput (const String& deviceName); - - /** Returns the name of the default midi output. - @see setDefaultMidiOutput, getDefaultMidiOutput - */ - const String& getDefaultMidiOutputName() const noexcept { return defaultMidiOutputName; } - - /** Returns the current default midi output device. - If no device has been selected, or the device can't be opened, this will return nullptr. - @see getDefaultMidiOutputName - */ - MidiOutput* getDefaultMidiOutput() const noexcept { return defaultMidiOutput; } - - /** Returns a list of the types of device supported. */ - const OwnedArray& getAvailableDeviceTypes(); - - //============================================================================== - /** Creates a list of available types. - - This will add a set of new AudioIODeviceType objects to the specified list, to - represent each available types of device. - - You can override this if your app needs to do something specific, like avoid - using DirectSound devices, etc. - */ - virtual void createAudioDeviceTypes (OwnedArray& types); - - /** Adds a new device type to the list of types. - The manager will take ownership of the object that is passed-in. - */ - void addAudioDeviceType (AudioIODeviceType* newDeviceType); - - //============================================================================== - /** Plays a beep through the current audio device. - - This is here to allow the audio setup UI panels to easily include a "test" - button so that the user can check where the audio is coming from. - */ - void playTestSound(); - - /** Turns on level-measuring. - - When enabled, the device manager will measure the peak input level - across all channels, and you can get this level by calling getCurrentInputLevel(). - - This is mainly intended for audio setup UI panels to use to create a mic - level display, so that the user can check that they've selected the right - device. - - A simple filter is used to make the level decay smoothly, but this is - only intended for giving rough feedback, and not for any kind of accurate - measurement. - */ - void enableInputLevelMeasurement (bool enableMeasurement); - - /** Returns the current input level. - To use this, you must first enable it by calling enableInputLevelMeasurement(). - See enableInputLevelMeasurement() for more info. - */ - double getCurrentInputLevel() const; - - /** Returns the a lock that can be used to synchronise access to the audio callback. - Obviously while this is locked, you're blocking the audio thread from running, so - it must only be used for very brief periods when absolutely necessary. - */ - CriticalSection& getAudioCallbackLock() noexcept { return audioCallbackLock; } - - /** Returns the a lock that can be used to synchronise access to the midi callback. - Obviously while this is locked, you're blocking the midi system from running, so - it must only be used for very brief periods when absolutely necessary. - */ - CriticalSection& getMidiCallbackLock() noexcept { return midiCallbackLock; } - -private: - //============================================================================== - OwnedArray availableDeviceTypes; - OwnedArray lastDeviceTypeConfigs; - - AudioDeviceSetup currentSetup; - ScopedPointer currentAudioDevice; - Array callbacks; - int numInputChansNeeded, numOutputChansNeeded; - String currentDeviceType; - BigInteger inputChannels, outputChannels; - ScopedPointer lastExplicitSettings; - mutable bool listNeedsScanning; - bool useInputNames; - Atomic inputLevelMeasurementEnabledCount; - double inputLevel; - ScopedPointer testSound; - int testSoundPosition; - AudioSampleBuffer tempBuffer; - - struct MidiCallbackInfo - { - String deviceName; - MidiInputCallback* callback; - }; - - StringArray midiInsFromXml; - OwnedArray enabledMidiInputs; - Array midiCallbacks; - - String defaultMidiOutputName; - ScopedPointer defaultMidiOutput; - CriticalSection audioCallbackLock, midiCallbackLock; - - double cpuUsageMs, timeToCpuScale; - - //============================================================================== - class CallbackHandler; - friend class CallbackHandler; - friend struct ContainerDeletePolicy; - ScopedPointer callbackHandler; - - void audioDeviceIOCallbackInt (const float** inputChannelData, int totalNumInputChannels, - float** outputChannelData, int totalNumOutputChannels, int numSamples); - void audioDeviceAboutToStartInt (AudioIODevice*); - void audioDeviceStoppedInt(); - void audioDeviceErrorInt (const String&); - void handleIncomingMidiMessageInt (MidiInput*, const MidiMessage&); - void audioDeviceListChanged(); - - String restartDevice (int blockSizeToUse, double sampleRateToUse, - const BigInteger& ins, const BigInteger& outs); - void stopDevice(); - - void updateXml(); - - void createDeviceTypesIfNeeded(); - void scanDevicesIfNeeded(); - void deleteCurrentDevice(); - double chooseBestSampleRate (double preferred) const; - int chooseBestBufferSize (int preferred) const; - void insertDefaultDeviceNames (AudioDeviceSetup&) const; - String initialiseDefault (const String& preferredDefaultDeviceName, const AudioDeviceSetup*); - String initialiseFromXML (const XmlElement&, bool selectDefaultDeviceOnFailure, - const String& preferredDefaultDeviceName, const AudioDeviceSetup*); - - AudioIODeviceType* findType (const String& inputName, const String& outputName); - AudioIODeviceType* findType (const String& typeName); - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioDeviceManager) -}; - -#endif // JUCE_AUDIODEVICEMANAGER_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/audio_io/juce_AudioIODevice.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/audio_io/juce_AudioIODevice.cpp deleted file mode 100644 index 95221ba037..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/audio_io/juce_AudioIODevice.cpp +++ /dev/null @@ -1,41 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -AudioIODevice::AudioIODevice (const String& deviceName, const String& deviceTypeName) - : name (deviceName), typeName (deviceTypeName) -{ -} - -AudioIODevice::~AudioIODevice() {} - -void AudioIODeviceCallback::audioDeviceError (const String&) {} -bool AudioIODevice::setAudioPreprocessingEnabled (bool) { return false; } -bool AudioIODevice::hasControlPanel() const { return false; } - -bool AudioIODevice::showControlPanel() -{ - jassertfalse; // this should only be called for devices which return true from - // their hasControlPanel() method. - return false; -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/audio_io/juce_AudioIODevice.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/audio_io/juce_AudioIODevice.h deleted file mode 100644 index 8ce41d091e..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/audio_io/juce_AudioIODevice.h +++ /dev/null @@ -1,309 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_AUDIOIODEVICE_H_INCLUDED -#define JUCE_AUDIOIODEVICE_H_INCLUDED - -class AudioIODevice; - - -//============================================================================== -/** - One of these is passed to an AudioIODevice object to stream the audio data - in and out. - - The AudioIODevice will repeatedly call this class's audioDeviceIOCallback() - method on its own high-priority audio thread, when it needs to send or receive - the next block of data. - - @see AudioIODevice, AudioDeviceManager -*/ -class JUCE_API AudioIODeviceCallback -{ -public: - /** Destructor. */ - virtual ~AudioIODeviceCallback() {} - - /** Processes a block of incoming and outgoing audio data. - - The subclass's implementation should use the incoming audio for whatever - purposes it needs to, and must fill all the output channels with the next - block of output data before returning. - - The channel data is arranged with the same array indices as the channel name - array returned by AudioIODevice::getOutputChannelNames(), but those channels - that aren't specified in AudioIODevice::open() will have a null pointer for their - associated channel, so remember to check for this. - - @param inputChannelData a set of arrays containing the audio data for each - incoming channel - this data is valid until the function - returns. There will be one channel of data for each input - channel that was enabled when the audio device was opened - (see AudioIODevice::open()) - @param numInputChannels the number of pointers to channel data in the - inputChannelData array. - @param outputChannelData a set of arrays which need to be filled with the data - that should be sent to each outgoing channel of the device. - There will be one channel of data for each output channel - that was enabled when the audio device was opened (see - AudioIODevice::open()) - The initial contents of the array is undefined, so the - callback function must fill all the channels with zeros if - its output is silence. Failing to do this could cause quite - an unpleasant noise! - @param numOutputChannels the number of pointers to channel data in the - outputChannelData array. - @param numSamples the number of samples in each channel of the input and - output arrays. The number of samples will depend on the - audio device's buffer size and will usually remain constant, - although this isn't guaranteed, so make sure your code can - cope with reasonable changes in the buffer size from one - callback to the next. - */ - virtual void audioDeviceIOCallback (const float** inputChannelData, - int numInputChannels, - float** outputChannelData, - int numOutputChannels, - int numSamples) = 0; - - /** Called to indicate that the device is about to start calling back. - - This will be called just before the audio callbacks begin, either when this - callback has just been added to an audio device, or after the device has been - restarted because of a sample-rate or block-size change. - - You can use this opportunity to find out the sample rate and block size - that the device is going to use by calling the AudioIODevice::getCurrentSampleRate() - and AudioIODevice::getCurrentBufferSizeSamples() on the supplied pointer. - - @param device the audio IO device that will be used to drive the callback. - Note that if you're going to store this this pointer, it is - only valid until the next time that audioDeviceStopped is called. - */ - virtual void audioDeviceAboutToStart (AudioIODevice* device) = 0; - - /** Called to indicate that the device has stopped. */ - virtual void audioDeviceStopped() = 0; - - /** This can be overridden to be told if the device generates an error while operating. - Be aware that this could be called by any thread! And not all devices perform - this callback. - */ - virtual void audioDeviceError (const String& errorMessage); -}; - - -//============================================================================== -/** - Base class for an audio device with synchronised input and output channels. - - Subclasses of this are used to implement different protocols such as DirectSound, - ASIO, CoreAudio, etc. - - To create one of these, you'll need to use the AudioIODeviceType class - see the - documentation for that class for more info. - - For an easier way of managing audio devices and their settings, have a look at the - AudioDeviceManager class. - - @see AudioIODeviceType, AudioDeviceManager -*/ -class JUCE_API AudioIODevice -{ -public: - /** Destructor. */ - virtual ~AudioIODevice(); - - //============================================================================== - /** Returns the device's name, (as set in the constructor). */ - const String& getName() const noexcept { return name; } - - /** Returns the type of the device. - - E.g. "CoreAudio", "ASIO", etc. - this comes from the AudioIODeviceType that created it. - */ - const String& getTypeName() const noexcept { return typeName; } - - //============================================================================== - /** Returns the names of all the available output channels on this device. - To find out which of these are currently in use, call getActiveOutputChannels(). - */ - virtual StringArray getOutputChannelNames() = 0; - - /** Returns the names of all the available input channels on this device. - To find out which of these are currently in use, call getActiveInputChannels(). - */ - virtual StringArray getInputChannelNames() = 0; - - //============================================================================== - /** Returns the set of sample-rates this device supports. - @see getCurrentSampleRate - */ - virtual Array getAvailableSampleRates() = 0; - - /** Returns the set of buffer sizes that are available. - @see getCurrentBufferSizeSamples, getDefaultBufferSize - */ - virtual Array getAvailableBufferSizes() = 0; - - /** Returns the default buffer-size to use. - @returns a number of samples - @see getAvailableBufferSizes - */ - virtual int getDefaultBufferSize() = 0; - - //============================================================================== - /** Tries to open the device ready to play. - - @param inputChannels a BigInteger in which a set bit indicates that the corresponding - input channel should be enabled - @param outputChannels a BigInteger in which a set bit indicates that the corresponding - output channel should be enabled - @param sampleRate the sample rate to try to use - to find out which rates are - available, see getAvailableSampleRates() - @param bufferSizeSamples the size of i/o buffer to use - to find out the available buffer - sizes, see getAvailableBufferSizes() - @returns an error description if there's a problem, or an empty string if it succeeds in - opening the device - @see close - */ - virtual String open (const BigInteger& inputChannels, - const BigInteger& outputChannels, - double sampleRate, - int bufferSizeSamples) = 0; - - /** Closes and releases the device if it's open. */ - virtual void close() = 0; - - /** Returns true if the device is still open. - - A device might spontaneously close itself if something goes wrong, so this checks if - it's still open. - */ - virtual bool isOpen() = 0; - - /** Starts the device actually playing. - - This must be called after the device has been opened. - - @param callback the callback to use for streaming the data. - @see AudioIODeviceCallback, open - */ - virtual void start (AudioIODeviceCallback* callback) = 0; - - /** Stops the device playing. - - Once a device has been started, this will stop it. Any pending calls to the - callback class will be flushed before this method returns. - */ - virtual void stop() = 0; - - /** Returns true if the device is still calling back. - - The device might mysteriously stop, so this checks whether it's - still playing. - */ - virtual bool isPlaying() = 0; - - /** Returns the last error that happened if anything went wrong. */ - virtual String getLastError() = 0; - - //============================================================================== - /** Returns the buffer size that the device is currently using. - - If the device isn't actually open, this value doesn't really mean much. - */ - virtual int getCurrentBufferSizeSamples() = 0; - - /** Returns the sample rate that the device is currently using. - - If the device isn't actually open, this value doesn't really mean much. - */ - virtual double getCurrentSampleRate() = 0; - - /** Returns the device's current physical bit-depth. - - If the device isn't actually open, this value doesn't really mean much. - */ - virtual int getCurrentBitDepth() = 0; - - /** Returns a mask showing which of the available output channels are currently - enabled. - @see getOutputChannelNames - */ - virtual BigInteger getActiveOutputChannels() const = 0; - - /** Returns a mask showing which of the available input channels are currently - enabled. - @see getInputChannelNames - */ - virtual BigInteger getActiveInputChannels() const = 0; - - /** Returns the device's output latency. - - This is the delay in samples between a callback getting a block of data, and - that data actually getting played. - */ - virtual int getOutputLatencyInSamples() = 0; - - /** Returns the device's input latency. - - This is the delay in samples between some audio actually arriving at the soundcard, - and the callback getting passed this block of data. - */ - virtual int getInputLatencyInSamples() = 0; - - - //============================================================================== - /** True if this device can show a pop-up control panel for editing its settings. - - This is generally just true of ASIO devices. If true, you can call showControlPanel() - to display it. - */ - virtual bool hasControlPanel() const; - - /** Shows a device-specific control panel if there is one. - - This should only be called for devices which return true from hasControlPanel(). - */ - virtual bool showControlPanel(); - - /** On devices which support it, this allows automatic gain control or other - mic processing to be disabled. - If the device doesn't support this operation, it'll return false. - */ - virtual bool setAudioPreprocessingEnabled (bool shouldBeEnabled); - - //============================================================================== -protected: - /** Creates a device, setting its name and type member variables. */ - AudioIODevice (const String& deviceName, - const String& typeName); - - /** @internal */ - String name, typeName; -}; - - -#endif // JUCE_AUDIOIODEVICE_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/audio_io/juce_AudioIODeviceType.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/audio_io/juce_AudioIODeviceType.cpp deleted file mode 100644 index 80026e7ae5..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/audio_io/juce_AudioIODeviceType.cpp +++ /dev/null @@ -1,78 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -AudioIODeviceType::AudioIODeviceType (const String& name) - : typeName (name) -{ -} - -AudioIODeviceType::~AudioIODeviceType() -{ -} - -//============================================================================== -void AudioIODeviceType::addListener (Listener* l) { listeners.add (l); } -void AudioIODeviceType::removeListener (Listener* l) { listeners.remove (l); } - -void AudioIODeviceType::callDeviceChangeListeners() -{ - listeners.call (&AudioIODeviceType::Listener::audioDeviceListChanged); -} - -//============================================================================== -#if ! JUCE_MAC -AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_CoreAudio() { return nullptr; } -#endif - -#if ! JUCE_IOS -AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_iOSAudio() { return nullptr; } -#endif - -#if ! (JUCE_WINDOWS && JUCE_WASAPI) -AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_WASAPI() { return nullptr; } -#endif - -#if ! (JUCE_WINDOWS && JUCE_DIRECTSOUND) -AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_DirectSound() { return nullptr; } -#endif - -#if ! (JUCE_WINDOWS && JUCE_ASIO) -AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_ASIO() { return nullptr; } -#endif - -#if ! (JUCE_LINUX && JUCE_ALSA) -AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_ALSA() { return nullptr; } -#endif - -#if ! (JUCE_LINUX && JUCE_JACK) -AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_JACK() { return nullptr; } -#endif - -#if ! JUCE_ANDROID -AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_Android() { return nullptr; } -#endif - -#if ! (JUCE_ANDROID && JUCE_USE_ANDROID_OPENSLES) -AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_OpenSLES() { return nullptr; } -#endif diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/audio_io/juce_AudioIODeviceType.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/audio_io/juce_AudioIODeviceType.h deleted file mode 100644 index d6cd99a5a6..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/audio_io/juce_AudioIODeviceType.h +++ /dev/null @@ -1,182 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_AUDIOIODEVICETYPE_H_INCLUDED -#define JUCE_AUDIOIODEVICETYPE_H_INCLUDED - - -//============================================================================== -/** - Represents a type of audio driver, such as DirectSound, ASIO, CoreAudio, etc. - - To get a list of available audio driver types, use the AudioDeviceManager::createAudioDeviceTypes() - method. Each of the objects returned can then be used to list the available - devices of that type. E.g. - @code - OwnedArray types; - myAudioDeviceManager.createAudioDeviceTypes (types); - - for (int i = 0; i < types.size(); ++i) - { - String typeName (types[i]->getTypeName()); // This will be things like "DirectSound", "CoreAudio", etc. - - types[i]->scanForDevices(); // This must be called before getting the list of devices - - StringArray deviceNames (types[i]->getDeviceNames()); // This will now return a list of available devices of this type - - for (int j = 0; j < deviceNames.size(); ++j) - { - AudioIODevice* device = types[i]->createDevice (deviceNames [j]); - - ... - } - } - @endcode - - For an easier way of managing audio devices and their settings, have a look at the - AudioDeviceManager class. - - @see AudioIODevice, AudioDeviceManager -*/ -class JUCE_API AudioIODeviceType -{ -public: - //============================================================================== - /** Returns the name of this type of driver that this object manages. - - This will be something like "DirectSound", "ASIO", "CoreAudio", "ALSA", etc. - */ - const String& getTypeName() const noexcept { return typeName; } - - //============================================================================== - /** Refreshes the object's cached list of known devices. - - This must be called at least once before calling getDeviceNames() or any of - the other device creation methods. - */ - virtual void scanForDevices() = 0; - - /** Returns the list of available devices of this type. - - The scanForDevices() method must have been called to create this list. - - @param wantInputNames only really used by DirectSound where devices are split up - into inputs and outputs, this indicates whether to use - the input or output name to refer to a pair of devices. - */ - virtual StringArray getDeviceNames (bool wantInputNames = false) const = 0; - - /** Returns the name of the default device. - - This will be one of the names from the getDeviceNames() list. - - @param forInput if true, this means that a default input device should be - returned; if false, it should return the default output - */ - virtual int getDefaultDeviceIndex (bool forInput) const = 0; - - /** Returns the index of a given device in the list of device names. - If asInput is true, it shows the index in the inputs list, otherwise it - looks for it in the outputs list. - */ - virtual int getIndexOfDevice (AudioIODevice* device, bool asInput) const = 0; - - /** Returns true if two different devices can be used for the input and output. - */ - virtual bool hasSeparateInputsAndOutputs() const = 0; - - /** Creates one of the devices of this type. - - The deviceName must be one of the strings returned by getDeviceNames(), and - scanForDevices() must have been called before this method is used. - */ - virtual AudioIODevice* createDevice (const String& outputDeviceName, - const String& inputDeviceName) = 0; - - //============================================================================== - /** - A class for receiving events when audio devices are inserted or removed. - - You can register an AudioIODeviceType::Listener with an~AudioIODeviceType object - using the AudioIODeviceType::addListener() method, and it will be called when - devices of that type are added or removed. - - @see AudioIODeviceType::addListener, AudioIODeviceType::removeListener - */ - class Listener - { - public: - virtual ~Listener() {} - - /** Called when the list of available audio devices changes. */ - virtual void audioDeviceListChanged() = 0; - }; - - /** Adds a listener that will be called when this type of device is added or - removed from the system. - */ - void addListener (Listener* listener); - - /** Removes a listener that was previously added with addListener(). */ - void removeListener (Listener* listener); - - //============================================================================== - /** Destructor. */ - virtual ~AudioIODeviceType(); - - //============================================================================== - /** Creates a CoreAudio device type if it's available on this platform, or returns null. */ - static AudioIODeviceType* createAudioIODeviceType_CoreAudio(); - /** Creates an iOS device type if it's available on this platform, or returns null. */ - static AudioIODeviceType* createAudioIODeviceType_iOSAudio(); - /** Creates a WASAPI device type if it's available on this platform, or returns null. */ - static AudioIODeviceType* createAudioIODeviceType_WASAPI(); - /** Creates a DirectSound device type if it's available on this platform, or returns null. */ - static AudioIODeviceType* createAudioIODeviceType_DirectSound(); - /** Creates an ASIO device type if it's available on this platform, or returns null. */ - static AudioIODeviceType* createAudioIODeviceType_ASIO(); - /** Creates an ALSA device type if it's available on this platform, or returns null. */ - static AudioIODeviceType* createAudioIODeviceType_ALSA(); - /** Creates a JACK device type if it's available on this platform, or returns null. */ - static AudioIODeviceType* createAudioIODeviceType_JACK(); - /** Creates an Android device type if it's available on this platform, or returns null. */ - static AudioIODeviceType* createAudioIODeviceType_Android(); - /** Creates an Android OpenSLES device type if it's available on this platform, or returns null. */ - static AudioIODeviceType* createAudioIODeviceType_OpenSLES(); - -protected: - explicit AudioIODeviceType (const String& typeName); - - /** Synchronously calls all the registered device list change listeners. */ - void callDeviceChangeListeners(); - -private: - String typeName; - ListenerList listeners; - - JUCE_DECLARE_NON_COPYABLE (AudioIODeviceType) -}; - - -#endif // JUCE_AUDIOIODEVICETYPE_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/audio_io/juce_SystemAudioVolume.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/audio_io/juce_SystemAudioVolume.h deleted file mode 100644 index 689e1f2919..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/audio_io/juce_SystemAudioVolume.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_SYSTEMAUDIOVOLUME_H_INCLUDED -#define JUCE_SYSTEMAUDIOVOLUME_H_INCLUDED - - -//============================================================================== -/** - Contains functions to control the system's master volume. -*/ -class JUCE_API SystemAudioVolume -{ -public: - //============================================================================== - /** Returns the operating system's current volume level in the range 0 to 1.0 */ - static float JUCE_CALLTYPE getGain(); - - /** Attempts to set the operating system's current volume level. - @param newGain the level, between 0 and 1.0 - @returns true if the operation succeeds - */ - static bool JUCE_CALLTYPE setGain (float newGain); - - /** Returns true if the system's audio output is currently muted. */ - static bool JUCE_CALLTYPE isMuted(); - - /** Attempts to mute the operating system's audio output. - @param shouldBeMuted true if you want it to be muted - @returns true if the operation succeeds - */ - static bool JUCE_CALLTYPE setMuted (bool shouldBeMuted); - -private: - SystemAudioVolume(); // Don't instantiate this class, just call its static fns. - JUCE_DECLARE_NON_COPYABLE (SystemAudioVolume) -}; - - -#endif // JUCE_SYSTEMAUDIOVOLUME_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/juce_audio_devices.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/juce_audio_devices.cpp deleted file mode 100644 index a9733db06c..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/juce_audio_devices.cpp +++ /dev/null @@ -1,227 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#if defined (JUCE_AUDIO_DEVICES_H_INCLUDED) && ! JUCE_AMALGAMATED_INCLUDE - /* When you add this cpp file to your project, you mustn't include it in a file where you've - already included any other headers - just put it inside a file on its own, possibly with your config - flags preceding it, but don't include anything else. That also includes avoiding any automatic prefix - header files that the compiler may be using. - */ - #error "Incorrect use of JUCE cpp file" -#endif - -// Your project must contain an AppConfig.h file with your project-specific settings in it, -// and your header search path must make it accessible to the module's files. -#include "AppConfig.h" - -#include "../juce_core/native/juce_BasicNativeHeaders.h" -#include "juce_audio_devices.h" - -//============================================================================== -#if JUCE_MAC - #define Point CarbonDummyPointName - #define Component CarbonDummyCompName - #import - #import - #import - #import - #undef Point - #undef Component - -#elif JUCE_IOS - #import - #import - #import - -//============================================================================== -#elif JUCE_WINDOWS - #if JUCE_WASAPI - #include - #endif - - #if JUCE_ASIO - /* This is very frustrating - we only need to use a handful of definitions from - a couple of the header files in Steinberg's ASIO SDK, and it'd be easy to copy - about 30 lines of code into this cpp file to create a fully stand-alone ASIO - implementation... - - ..unfortunately that would break Steinberg's license agreement for use of - their SDK, so I'm not allowed to do this. - - This means that anyone who wants to use JUCE's ASIO abilities will have to: - - 1) Agree to Steinberg's licensing terms and download the ASIO SDK - (see www.steinberg.net/Steinberg/Developers.asp). - - 2) Enable this code with a global definition #define JUCE_ASIO 1. - - 3) Make sure that your header search path contains the iasiodrv.h file that - comes with the SDK. (Only about a handful of the SDK header files are actually - needed - so to simplify things, you could just copy these into your JUCE directory). - */ - #include - #endif - - #if JUCE_USE_CDBURNER - /* You'll need the Platform SDK for these headers - if you don't have it and don't - need to use CD-burning, then you might just want to set the JUCE_USE_CDBURNER flag - to 0, to avoid these includes. - */ - #include - #include - #endif - -//============================================================================== -#elif JUCE_LINUX - #if JUCE_ALSA - /* Got an include error here? If so, you've either not got ALSA installed, or you've - not got your paths set up correctly to find its header files. - - The package you need to install to get ASLA support is "libasound2-dev". - - If you don't have the ALSA library and don't want to build Juce with audio support, - just set the JUCE_ALSA flag to 0. - */ - #include - #endif - - #if JUCE_JACK - /* Got an include error here? If so, you've either not got jack-audio-connection-kit - installed, or you've not got your paths set up correctly to find its header files. - - The package you need to install to get JACK support is "libjack-dev". - - If you don't have the jack-audio-connection-kit library and don't want to build - Juce with low latency audio support, just set the JUCE_JACK flag to 0. - */ - #include - #endif - #undef SIZEOF - -//============================================================================== -#elif JUCE_ANDROID - - #if JUCE_USE_ANDROID_OPENSLES - #include - #include - #include - #endif - -#endif - -namespace juce -{ - -#include "audio_io/juce_AudioDeviceManager.cpp" -#include "audio_io/juce_AudioIODevice.cpp" -#include "audio_io/juce_AudioIODeviceType.cpp" -#include "midi_io/juce_MidiMessageCollector.cpp" -#include "midi_io/juce_MidiOutput.cpp" -#include "audio_cd/juce_AudioCDReader.cpp" -#include "sources/juce_AudioSourcePlayer.cpp" -#include "sources/juce_AudioTransportSource.cpp" -#include "native/juce_MidiDataConcatenator.h" - -//============================================================================== -#if JUCE_MAC - #include "../juce_core/native/juce_osx_ObjCHelpers.h" - #include "native/juce_mac_CoreAudio.cpp" - #include "native/juce_mac_CoreMidi.cpp" - - #if JUCE_USE_CDREADER - #include "native/juce_mac_AudioCDReader.mm" - #endif - - #if JUCE_USE_CDBURNER - #include "native/juce_mac_AudioCDBurner.mm" - #endif - -//============================================================================== -#elif JUCE_IOS - #include "native/juce_ios_Audio.cpp" - #include "native/juce_mac_CoreMidi.cpp" - -//============================================================================== -#elif JUCE_WINDOWS - #include "../juce_core/native/juce_win32_ComSmartPtr.h" - #include "../juce_events/native/juce_win32_HiddenMessageWindow.h" - - #if JUCE_WASAPI - #include "native/juce_win32_WASAPI.cpp" - #endif - - #if JUCE_DIRECTSOUND - #include "native/juce_win32_DirectSound.cpp" - #endif - - #include "native/juce_win32_Midi.cpp" - - #if JUCE_ASIO - #include "native/juce_win32_ASIO.cpp" - #endif - - #if JUCE_USE_CDREADER - #include "native/juce_win32_AudioCDReader.cpp" - #endif - - #if JUCE_USE_CDBURNER - #include "native/juce_win32_AudioCDBurner.cpp" - #endif - -//============================================================================== -#elif JUCE_LINUX - #if JUCE_ALSA - #include "native/juce_linux_ALSA.cpp" - #endif - - #include "native/juce_linux_Midi.cpp" - - #if JUCE_JACK - #include "native/juce_linux_JackAudio.cpp" - #endif - - #if JUCE_USE_CDREADER - #include "native/juce_linux_AudioCDReader.cpp" - #endif - -//============================================================================== -#elif JUCE_ANDROID - #include "../juce_core/native/juce_android_JNIHelpers.h" - #include "native/juce_android_Audio.cpp" - #include "native/juce_android_Midi.cpp" - - #if JUCE_USE_ANDROID_OPENSLES - #include "native/juce_android_OpenSL.cpp" - #endif - -#endif - -#if ! JUCE_SYSTEMAUDIOVOL_IMPLEMENTED - // None of these methods are available. (On Windows you might need to enable WASAPI for this) - float JUCE_CALLTYPE SystemAudioVolume::getGain() { jassertfalse; return 0.0f; } - bool JUCE_CALLTYPE SystemAudioVolume::setGain (float) { jassertfalse; return false; } - bool JUCE_CALLTYPE SystemAudioVolume::isMuted() { jassertfalse; return false; } - bool JUCE_CALLTYPE SystemAudioVolume::setMuted (bool) { jassertfalse; return false; } -#endif -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/juce_audio_devices.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/juce_audio_devices.h index b8528d5bc3..6a672ccda4 100644 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/juce_audio_devices.h +++ b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/juce_audio_devices.h @@ -1,117 +1,5 @@ -/* - ============================================================================== +// This is an auto-generated file to redirect any included +// module headers to the correct external folder. - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. +#include "../../../../../modules/juce_audio_devices/juce_audio_devices.h" - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_AUDIO_DEVICES_H_INCLUDED -#define JUCE_AUDIO_DEVICES_H_INCLUDED - -#include "../juce_events/juce_events.h" -#include "../juce_audio_basics/juce_audio_basics.h" -#include "../juce_audio_formats/juce_audio_formats.h" - -//============================================================================= -/** Config: JUCE_ASIO - Enables ASIO audio devices (MS Windows only). - Turning this on means that you'll need to have the Steinberg ASIO SDK installed - on your Windows build machine. - - See the comments in the ASIOAudioIODevice class's header file for more - info about this. -*/ -#ifndef JUCE_ASIO - #define JUCE_ASIO 0 -#endif - -/** Config: JUCE_WASAPI - Enables WASAPI audio devices (Windows Vista and above). -*/ -#ifndef JUCE_WASAPI - #define JUCE_WASAPI 1 -#endif - -/** Config: JUCE_DIRECTSOUND - Enables DirectSound audio (MS Windows only). -*/ -#ifndef JUCE_DIRECTSOUND - #define JUCE_DIRECTSOUND 1 -#endif - -/** Config: JUCE_ALSA - Enables ALSA audio devices (Linux only). -*/ -#ifndef JUCE_ALSA - #define JUCE_ALSA 1 -#endif - -/** Config: JUCE_JACK - Enables JACK audio devices (Linux only). -*/ -#ifndef JUCE_JACK - #define JUCE_JACK 0 -#endif - -/** Config: JUCE_USE_ANDROID_OPENSLES - Enables OpenSLES devices (Android only). -*/ -#ifndef JUCE_USE_ANDROID_OPENSLES - #if JUCE_ANDROID_API_VERSION > 8 - #define JUCE_USE_ANDROID_OPENSLES 1 - #else - #define JUCE_USE_ANDROID_OPENSLES 0 - #endif -#endif - -//============================================================================= -/** Config: JUCE_USE_CDREADER - Enables the AudioCDReader class (on supported platforms). -*/ -#ifndef JUCE_USE_CDREADER - #define JUCE_USE_CDREADER 0 -#endif - -/** Config: JUCE_USE_CDBURNER - Enables the AudioCDBurner class (on supported platforms). -*/ -#ifndef JUCE_USE_CDBURNER - #define JUCE_USE_CDBURNER 0 -#endif - -//============================================================================= -namespace juce -{ - -#include "audio_io/juce_AudioIODevice.h" -#include "audio_io/juce_AudioIODeviceType.h" -#include "audio_io/juce_SystemAudioVolume.h" -#include "midi_io/juce_MidiInput.h" -#include "midi_io/juce_MidiMessageCollector.h" -#include "midi_io/juce_MidiOutput.h" -#include "sources/juce_AudioSourcePlayer.h" -#include "sources/juce_AudioTransportSource.h" -#include "audio_cd/juce_AudioCDBurner.h" -#include "audio_cd/juce_AudioCDReader.h" -#include "audio_io/juce_AudioDeviceManager.h" - -} - -#endif // JUCE_AUDIO_DEVICES_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/juce_audio_devices.mm b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/juce_audio_devices.mm deleted file mode 100644 index a135119ce2..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/juce_audio_devices.mm +++ /dev/null @@ -1,25 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#include "juce_audio_devices.cpp" diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/juce_module_info b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/juce_module_info deleted file mode 100644 index 6ef2131425..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/juce_module_info +++ /dev/null @@ -1,28 +0,0 @@ -{ - "id": "juce_audio_devices", - "name": "JUCE audio and midi I/O device classes", - "version": "3.0.8", - "description": "Classes to play and record from audio and midi i/o devices.", - "website": "http://www.juce.com/juce", - "license": "GPL/Commercial", - - "dependencies": [ { "id": "juce_audio_basics", "version": "matching" }, - { "id": "juce_audio_formats", "version": "matching" }, - { "id": "juce_events", "version": "matching" } ], - - "include": "juce_audio_devices.h", - - "compile": [ { "file": "juce_audio_devices.cpp", "target": "! xcode" }, - { "file": "juce_audio_devices.mm", "target": "xcode" } ], - - "browse": [ "audio_io/*", - "midi_io/*", - "sources/*", - "audio_cd/*", - "native/*" ], - - "OSXFrameworks": "CoreAudio CoreMIDI DiscRecording", - "iOSFrameworks": "AudioToolbox CoreMIDI", - "LinuxLibs": "asound", - "mingwLibs": "winmm" -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/midi_io/juce_MidiInput.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/midi_io/juce_MidiInput.h deleted file mode 100644 index 630802085b..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/midi_io/juce_MidiInput.h +++ /dev/null @@ -1,182 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_MIDIINPUT_H_INCLUDED -#define JUCE_MIDIINPUT_H_INCLUDED - -class MidiInput; - - -//============================================================================== -/** - Receives incoming messages from a physical MIDI input device. - - This class is overridden to handle incoming midi messages. See the MidiInput - class for more details. - - @see MidiInput -*/ -class JUCE_API MidiInputCallback -{ -public: - /** Destructor. */ - virtual ~MidiInputCallback() {} - - - /** Receives an incoming message. - - A MidiInput object will call this method when a midi event arrives. It'll be - called on a high-priority system thread, so avoid doing anything time-consuming - in here, and avoid making any UI calls. You might find the MidiBuffer class helpful - for queueing incoming messages for use later. - - @param source the MidiInput object that generated the message - @param message the incoming message. The message's timestamp is set to a value - equivalent to (Time::getMillisecondCounter() / 1000.0) to specify the - time when the message arrived. - */ - virtual void handleIncomingMidiMessage (MidiInput* source, - const MidiMessage& message) = 0; - - /** Notification sent each time a packet of a multi-packet sysex message arrives. - - If a long sysex message is broken up into multiple packets, this callback is made - for each packet that arrives until the message is finished, at which point - the normal handleIncomingMidiMessage() callback will be made with the entire - message. - - The message passed in will contain the start of a sysex, but won't be finished - with the terminating 0xf7 byte. - */ - virtual void handlePartialSysexMessage (MidiInput* source, - const uint8* messageData, - int numBytesSoFar, - double timestamp) - { - // (this bit is just to avoid compiler warnings about unused variables) - (void) source; (void) messageData; (void) numBytesSoFar; (void) timestamp; - } -}; - -//============================================================================== -/** - Represents a midi input device. - - To create one of these, use the static getDevices() method to find out what inputs are - available, and then use the openDevice() method to try to open one. - - @see MidiOutput -*/ -class JUCE_API MidiInput -{ -public: - //============================================================================== - /** Returns a list of the available midi input devices. - - You can open one of the devices by passing its index into the - openDevice() method. - - @see getDefaultDeviceIndex, openDevice - */ - static StringArray getDevices(); - - /** Returns the index of the default midi input device to use. - - This refers to the index in the list returned by getDevices(). - */ - static int getDefaultDeviceIndex(); - - /** Tries to open one of the midi input devices. - - This will return a MidiInput object if it manages to open it. You can then - call start() and stop() on this device, and delete it when no longer needed. - - If the device can't be opened, this will return a null pointer. - - @param deviceIndex the index of a device from the list returned by getDevices() - @param callback the object that will receive the midi messages from this device. - - @see MidiInputCallback, getDevices - */ - static MidiInput* openDevice (int deviceIndex, - MidiInputCallback* callback); - - #if JUCE_LINUX || JUCE_MAC || JUCE_IOS || DOXYGEN - /** This will try to create a new midi input device (Not available on Windows). - - This will attempt to create a new midi input device with the specified name, - for other apps to connect to. - - Returns nullptr if a device can't be created. - - @param deviceName the name to use for the new device - @param callback the object that will receive the midi messages from this device. - */ - static MidiInput* createNewDevice (const String& deviceName, - MidiInputCallback* callback); - #endif - - //============================================================================== - /** Destructor. */ - virtual ~MidiInput(); - - /** Returns the name of this device. */ - const String& getName() const noexcept { return name; } - - /** Allows you to set a custom name for the device, in case you don't like the name - it was given when created. - */ - void setName (const String& newName) noexcept { name = newName; } - - //============================================================================== - /** Starts the device running. - - After calling this, the device will start sending midi messages to the - MidiInputCallback object that was specified when the openDevice() method - was called. - - @see stop - */ - virtual void start(); - - /** Stops the device running. - - @see start - */ - virtual void stop(); - -protected: - //============================================================================== - String name; - void* internal; - - explicit MidiInput (const String& name); - -private: - //============================================================================== - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MidiInput) -}; - - -#endif // JUCE_MIDIINPUT_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/midi_io/juce_MidiMessageCollector.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/midi_io/juce_MidiMessageCollector.cpp deleted file mode 100644 index 28e81c0eb9..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/midi_io/juce_MidiMessageCollector.cpp +++ /dev/null @@ -1,153 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -MidiMessageCollector::MidiMessageCollector() - : lastCallbackTime (0), - sampleRate (44100.0001) -{ -} - -MidiMessageCollector::~MidiMessageCollector() -{ -} - -//============================================================================== -void MidiMessageCollector::reset (const double sampleRate_) -{ - jassert (sampleRate_ > 0); - - const ScopedLock sl (midiCallbackLock); - sampleRate = sampleRate_; - incomingMessages.clear(); - lastCallbackTime = Time::getMillisecondCounterHiRes(); -} - -void MidiMessageCollector::addMessageToQueue (const MidiMessage& message) -{ - // you need to call reset() to set the correct sample rate before using this object - jassert (sampleRate != 44100.0001); - - // the messages that come in here need to be time-stamped correctly - see MidiInput - // for details of what the number should be. - jassert (message.getTimeStamp() != 0); - - const ScopedLock sl (midiCallbackLock); - - const int sampleNumber - = (int) ((message.getTimeStamp() - 0.001 * lastCallbackTime) * sampleRate); - - incomingMessages.addEvent (message, sampleNumber); - - // if the messages don't get used for over a second, we'd better - // get rid of any old ones to avoid the queue getting too big - if (sampleNumber > sampleRate) - incomingMessages.clear (0, sampleNumber - (int) sampleRate); -} - -void MidiMessageCollector::removeNextBlockOfMessages (MidiBuffer& destBuffer, - const int numSamples) -{ - // you need to call reset() to set the correct sample rate before using this object - jassert (sampleRate != 44100.0001); - jassert (numSamples > 0); - - const double timeNow = Time::getMillisecondCounterHiRes(); - const double msElapsed = timeNow - lastCallbackTime; - - const ScopedLock sl (midiCallbackLock); - lastCallbackTime = timeNow; - - if (! incomingMessages.isEmpty()) - { - int numSourceSamples = jmax (1, roundToInt (msElapsed * 0.001 * sampleRate)); - - int startSample = 0; - int scale = 1 << 16; - - const uint8* midiData; - int numBytes, samplePosition; - - MidiBuffer::Iterator iter (incomingMessages); - - if (numSourceSamples > numSamples) - { - // if our list of events is longer than the buffer we're being - // asked for, scale them down to squeeze them all in.. - const int maxBlockLengthToUse = numSamples << 5; - - if (numSourceSamples > maxBlockLengthToUse) - { - startSample = numSourceSamples - maxBlockLengthToUse; - numSourceSamples = maxBlockLengthToUse; - iter.setNextSamplePosition (startSample); - } - - scale = (numSamples << 10) / numSourceSamples; - - while (iter.getNextEvent (midiData, numBytes, samplePosition)) - { - samplePosition = ((samplePosition - startSample) * scale) >> 10; - - destBuffer.addEvent (midiData, numBytes, - jlimit (0, numSamples - 1, samplePosition)); - } - } - else - { - // if our event list is shorter than the number we need, put them - // towards the end of the buffer - startSample = numSamples - numSourceSamples; - - while (iter.getNextEvent (midiData, numBytes, samplePosition)) - { - destBuffer.addEvent (midiData, numBytes, - jlimit (0, numSamples - 1, samplePosition + startSample)); - } - } - - incomingMessages.clear(); - } -} - -//============================================================================== -void MidiMessageCollector::handleNoteOn (MidiKeyboardState*, int midiChannel, int midiNoteNumber, float velocity) -{ - MidiMessage m (MidiMessage::noteOn (midiChannel, midiNoteNumber, velocity)); - m.setTimeStamp (Time::getMillisecondCounterHiRes() * 0.001); - - addMessageToQueue (m); -} - -void MidiMessageCollector::handleNoteOff (MidiKeyboardState*, int midiChannel, int midiNoteNumber) -{ - MidiMessage m (MidiMessage::noteOff (midiChannel, midiNoteNumber)); - m.setTimeStamp (Time::getMillisecondCounterHiRes() * 0.001); - - addMessageToQueue (m); -} - -void MidiMessageCollector::handleIncomingMidiMessage (MidiInput*, const MidiMessage& message) -{ - addMessageToQueue (message); -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/midi_io/juce_MidiMessageCollector.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/midi_io/juce_MidiMessageCollector.h deleted file mode 100644 index 5b1673779e..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/midi_io/juce_MidiMessageCollector.h +++ /dev/null @@ -1,104 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_MIDIMESSAGECOLLECTOR_H_INCLUDED -#define JUCE_MIDIMESSAGECOLLECTOR_H_INCLUDED - - -//============================================================================== -/** - Collects incoming realtime MIDI messages and turns them into blocks suitable for - processing by a block-based audio callback. - - The class can also be used as either a MidiKeyboardStateListener or a MidiInputCallback - so it can easily use a midi input or keyboard component as its source. - - @see MidiMessage, MidiInput -*/ -class JUCE_API MidiMessageCollector : public MidiKeyboardStateListener, - public MidiInputCallback -{ -public: - //============================================================================== - /** Creates a MidiMessageCollector. */ - MidiMessageCollector(); - - /** Destructor. */ - ~MidiMessageCollector(); - - //============================================================================== - /** Clears any messages from the queue. - - You need to call this method before starting to use the collector, so that - it knows the correct sample rate to use. - */ - void reset (double sampleRate); - - /** Takes an incoming real-time message and adds it to the queue. - - The message's timestamp is taken, and it will be ready for retrieval as part - of the block returned by the next call to removeNextBlockOfMessages(). - - This method is fully thread-safe when overlapping calls are made with - removeNextBlockOfMessages(). - */ - void addMessageToQueue (const MidiMessage& message); - - /** Removes all the pending messages from the queue as a buffer. - - This will also correct the messages' timestamps to make sure they're in - the range 0 to numSamples - 1. - - This call should be made regularly by something like an audio processing - callback, because the time that it happens is used in calculating the - midi event positions. - - This method is fully thread-safe when overlapping calls are made with - addMessageToQueue(). - - Precondition: numSamples must be greater than 0. - */ - void removeNextBlockOfMessages (MidiBuffer& destBuffer, int numSamples); - - - //============================================================================== - /** @internal */ - void handleNoteOn (MidiKeyboardState*, int midiChannel, int midiNoteNumber, float velocity) override; - /** @internal */ - void handleNoteOff (MidiKeyboardState*, int midiChannel, int midiNoteNumber) override; - /** @internal */ - void handleIncomingMidiMessage (MidiInput*, const MidiMessage&) override; - -private: - //============================================================================== - double lastCallbackTime; - CriticalSection midiCallbackLock; - MidiBuffer incomingMessages; - double sampleRate; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MidiMessageCollector) -}; - - -#endif // JUCE_MIDIMESSAGECOLLECTOR_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/midi_io/juce_MidiOutput.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/midi_io/juce_MidiOutput.cpp deleted file mode 100644 index 0af7d1b7c0..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/midi_io/juce_MidiOutput.cpp +++ /dev/null @@ -1,162 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -struct MidiOutput::PendingMessage -{ - PendingMessage (const void* const data, const int len, const double timeStamp) - : message (data, len, timeStamp) - {} - - MidiMessage message; - PendingMessage* next; -}; - -MidiOutput::MidiOutput() - : Thread ("midi out"), - internal (nullptr), - firstMessage (nullptr) -{ -} - -void MidiOutput::sendBlockOfMessages (const MidiBuffer& buffer, - const double millisecondCounterToStartAt, - double samplesPerSecondForBuffer) -{ - // You've got to call startBackgroundThread() for this to actually work.. - jassert (isThreadRunning()); - - // this needs to be a value in the future - RTFM for this method! - jassert (millisecondCounterToStartAt > 0); - - const double timeScaleFactor = 1000.0 / samplesPerSecondForBuffer; - - MidiBuffer::Iterator i (buffer); - - const uint8* data; - int len, time; - - while (i.getNextEvent (data, len, time)) - { - const double eventTime = millisecondCounterToStartAt + timeScaleFactor * time; - - PendingMessage* const m = new PendingMessage (data, len, eventTime); - - const ScopedLock sl (lock); - - if (firstMessage == nullptr || firstMessage->message.getTimeStamp() > eventTime) - { - m->next = firstMessage; - firstMessage = m; - } - else - { - PendingMessage* mm = firstMessage; - - while (mm->next != nullptr && mm->next->message.getTimeStamp() <= eventTime) - mm = mm->next; - - m->next = mm->next; - mm->next = m; - } - } - - notify(); -} - -void MidiOutput::clearAllPendingMessages() -{ - const ScopedLock sl (lock); - - while (firstMessage != nullptr) - { - PendingMessage* const m = firstMessage; - firstMessage = firstMessage->next; - delete m; - } -} - -void MidiOutput::startBackgroundThread() -{ - startThread (9); -} - -void MidiOutput::stopBackgroundThread() -{ - stopThread (5000); -} - -void MidiOutput::run() -{ - while (! threadShouldExit()) - { - uint32 now = Time::getMillisecondCounter(); - uint32 eventTime = 0; - uint32 timeToWait = 500; - - PendingMessage* message; - - { - const ScopedLock sl (lock); - message = firstMessage; - - if (message != nullptr) - { - eventTime = (uint32) roundToInt (message->message.getTimeStamp()); - - if (eventTime > now + 20) - { - timeToWait = eventTime - (now + 20); - message = nullptr; - } - else - { - firstMessage = message->next; - } - } - } - - if (message != nullptr) - { - const ScopedPointer messageDeleter (message); - - if (eventTime > now) - { - Time::waitForMillisecondCounter (eventTime); - - if (threadShouldExit()) - break; - } - - if (eventTime > now - 200) - sendMessageNow (message->message); - } - else - { - jassert (timeToWait < 1000 * 30); - wait ((int) timeToWait); - } - } - - clearAllPendingMessages(); -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/midi_io/juce_MidiOutput.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/midi_io/juce_MidiOutput.h deleted file mode 100644 index c668f8ab22..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/midi_io/juce_MidiOutput.h +++ /dev/null @@ -1,147 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_MIDIOUTPUT_H_INCLUDED -#define JUCE_MIDIOUTPUT_H_INCLUDED - - -//============================================================================== -/** - Controls a physical MIDI output device. - - To create one of these, use the static getDevices() method to get a list of the - available output devices, then use the openDevice() method to try to open one. - - @see MidiInput -*/ -class JUCE_API MidiOutput : private Thread -{ -public: - //============================================================================== - /** Returns a list of the available midi output devices. - - You can open one of the devices by passing its index into the - openDevice() method. - - @see getDefaultDeviceIndex, openDevice - */ - static StringArray getDevices(); - - /** Returns the index of the default midi output device to use. - - This refers to the index in the list returned by getDevices(). - */ - static int getDefaultDeviceIndex(); - - /** Tries to open one of the midi output devices. - - This will return a MidiOutput object if it manages to open it. You can then - send messages to this device, and delete it when no longer needed. - - If the device can't be opened, this will return a null pointer. - - @param deviceIndex the index of a device from the list returned by getDevices() - @see getDevices - */ - static MidiOutput* openDevice (int deviceIndex); - - - #if JUCE_LINUX || JUCE_MAC || JUCE_IOS || DOXYGEN - /** This will try to create a new midi output device (Not available on Windows). - - This will attempt to create a new midi output device that other apps can connect - to and use as their midi input. - - Returns nullptr if a device can't be created. - - @param deviceName the name to use for the new device - */ - static MidiOutput* createNewDevice (const String& deviceName); - #endif - - //============================================================================== - /** Destructor. */ - virtual ~MidiOutput(); - - /** Makes this device output a midi message. - - @see MidiMessage - */ - virtual void sendMessageNow (const MidiMessage& message); - - //============================================================================== - /** This lets you supply a block of messages that will be sent out at some point - in the future. - - The MidiOutput class has an internal thread that can send out timestamped - messages - this appends a set of messages to its internal buffer, ready for - sending. - - This will only work if you've already started the thread with startBackgroundThread(). - - A time is supplied, at which the block of messages should be sent. This time uses - the same time base as Time::getMillisecondCounter(), and must be in the future. - - The samplesPerSecondForBuffer parameter indicates the number of samples per second - used by the MidiBuffer. Each event in a MidiBuffer has a sample position, and the - samplesPerSecondForBuffer value is needed to convert this sample position to a - real time. - */ - virtual void sendBlockOfMessages (const MidiBuffer& buffer, - double millisecondCounterToStartAt, - double samplesPerSecondForBuffer); - - /** Gets rid of any midi messages that had been added by sendBlockOfMessages(). - */ - virtual void clearAllPendingMessages(); - - /** Starts up a background thread so that the device can send blocks of data. - - Call this to get the device ready, before using sendBlockOfMessages(). - */ - virtual void startBackgroundThread(); - - /** Stops the background thread, and clears any pending midi events. - - @see startBackgroundThread - */ - virtual void stopBackgroundThread(); - - -protected: - //============================================================================== - void* internal; - CriticalSection lock; - struct PendingMessage; - PendingMessage* firstMessage; - - MidiOutput(); - void run() override; - -private: - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MidiOutput) -}; - - -#endif // JUCE_MIDIOUTPUT_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/native/juce_MidiDataConcatenator.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/native/juce_MidiDataConcatenator.h deleted file mode 100644 index 4dc70b9bb7..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/native/juce_MidiDataConcatenator.h +++ /dev/null @@ -1,187 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_MIDIDATACONCATENATOR_H_INCLUDED -#define JUCE_MIDIDATACONCATENATOR_H_INCLUDED - -//============================================================================== -/** - Helper class that takes chunks of incoming midi bytes, packages them into - messages, and dispatches them to a midi callback. -*/ -class MidiDataConcatenator -{ -public: - //============================================================================== - MidiDataConcatenator (const int initialBufferSize) - : pendingData ((size_t) initialBufferSize), - pendingDataTime (0), pendingBytes (0), runningStatus (0) - { - } - - void reset() - { - pendingBytes = 0; - runningStatus = 0; - pendingDataTime = 0; - } - - template - void pushMidiData (const void* inputData, int numBytes, double time, - UserDataType* input, CallbackType& callback) - { - const uint8* d = static_cast (inputData); - - while (numBytes > 0) - { - if (pendingBytes > 0 || d[0] == 0xf0) - { - processSysex (d, numBytes, time, input, callback); - runningStatus = 0; - } - else - { - int len = 0; - uint8 data[3]; - - while (numBytes > 0) - { - // If there's a realtime message embedded in the middle of - // the normal message, handle it now.. - if (*d >= 0xf8 && *d <= 0xfe) - { - const MidiMessage m (*d++, time); - callback.handleIncomingMidiMessage (input, m); - --numBytes; - } - else - { - if (len == 0 && *d < 0x80 && runningStatus >= 0x80) - data[len++] = runningStatus; - - data[len++] = *d++; - --numBytes; - - if (len >= MidiMessage::getMessageLengthFromFirstByte (data[0])) - break; - } - } - - if (len > 0) - { - int used = 0; - const MidiMessage m (data, len, used, 0, time); - - if (used <= 0) - break; // malformed message.. - - jassert (used == len); - callback.handleIncomingMidiMessage (input, m); - runningStatus = data[0]; - } - } - } - } - -private: - template - void processSysex (const uint8*& d, int& numBytes, double time, - UserDataType* input, CallbackType& callback) - { - if (*d == 0xf0) - { - pendingBytes = 0; - pendingDataTime = time; - } - - pendingData.ensureSize ((size_t) (pendingBytes + numBytes), false); - uint8* totalMessage = static_cast (pendingData.getData()); - uint8* dest = totalMessage + pendingBytes; - - do - { - if (pendingBytes > 0 && *d >= 0x80) - { - if (*d == 0xf7) - { - *dest++ = *d++; - ++pendingBytes; - --numBytes; - break; - } - - if (*d >= 0xfa || *d == 0xf8) - { - callback.handleIncomingMidiMessage (input, MidiMessage (*d, time)); - ++d; - --numBytes; - } - else - { - pendingBytes = 0; - int used = 0; - const MidiMessage m (d, numBytes, used, 0, time); - - if (used > 0) - { - callback.handleIncomingMidiMessage (input, m); - numBytes -= used; - d += used; - } - - break; - } - } - else - { - *dest++ = *d++; - ++pendingBytes; - --numBytes; - } - } - while (numBytes > 0); - - if (pendingBytes > 0) - { - if (totalMessage [pendingBytes - 1] == 0xf7) - { - callback.handleIncomingMidiMessage (input, MidiMessage (totalMessage, pendingBytes, pendingDataTime)); - pendingBytes = 0; - } - else - { - callback.handlePartialSysexMessage (input, totalMessage, pendingBytes, pendingDataTime); - } - } - } - - MemoryBlock pendingData; - double pendingDataTime; - int pendingBytes; - uint8 runningStatus; - - JUCE_DECLARE_NON_COPYABLE (MidiDataConcatenator) -}; - -#endif // JUCE_MIDIDATACONCATENATOR_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/native/juce_android_Audio.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/native/juce_android_Audio.cpp deleted file mode 100644 index 80711da9e2..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/native/juce_android_Audio.cpp +++ /dev/null @@ -1,450 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -//============================================================================== -#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD) \ - STATICMETHOD (getMinBufferSize, "getMinBufferSize", "(III)I") \ - STATICMETHOD (getNativeOutputSampleRate, "getNativeOutputSampleRate", "(I)I") \ - METHOD (constructor, "", "(IIIIII)V") \ - METHOD (getState, "getState", "()I") \ - METHOD (play, "play", "()V") \ - METHOD (stop, "stop", "()V") \ - METHOD (release, "release", "()V") \ - METHOD (flush, "flush", "()V") \ - METHOD (write, "write", "([SII)I") \ - -DECLARE_JNI_CLASS (AudioTrack, "android/media/AudioTrack"); -#undef JNI_CLASS_MEMBERS - -//============================================================================== -#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD) \ - STATICMETHOD (getMinBufferSize, "getMinBufferSize", "(III)I") \ - METHOD (constructor, "", "(IIIII)V") \ - METHOD (getState, "getState", "()I") \ - METHOD (startRecording, "startRecording", "()V") \ - METHOD (stop, "stop", "()V") \ - METHOD (read, "read", "([SII)I") \ - METHOD (release, "release", "()V") \ - -DECLARE_JNI_CLASS (AudioRecord, "android/media/AudioRecord"); -#undef JNI_CLASS_MEMBERS - -//============================================================================== -enum -{ - CHANNEL_OUT_STEREO = 12, - CHANNEL_IN_STEREO = 12, - CHANNEL_IN_MONO = 16, - ENCODING_PCM_16BIT = 2, - STREAM_MUSIC = 3, - MODE_STREAM = 1, - STATE_UNINITIALIZED = 0 -}; - -const char* const javaAudioTypeName = "Android Audio"; - -//============================================================================== -class AndroidAudioIODevice : public AudioIODevice, - public Thread -{ -public: - //============================================================================== - AndroidAudioIODevice (const String& deviceName) - : AudioIODevice (deviceName, javaAudioTypeName), - Thread ("audio"), - minBufferSizeOut (0), minBufferSizeIn (0), callback (0), sampleRate (0), - numClientInputChannels (0), numDeviceInputChannels (0), numDeviceInputChannelsAvailable (2), - numClientOutputChannels (0), numDeviceOutputChannels (0), - actualBufferSize (0), isRunning (false), - inputChannelBuffer (1, 1), - outputChannelBuffer (1, 1) - { - JNIEnv* env = getEnv(); - sampleRate = env->CallStaticIntMethod (AudioTrack, AudioTrack.getNativeOutputSampleRate, MODE_STREAM); - - minBufferSizeOut = (int) env->CallStaticIntMethod (AudioTrack, AudioTrack.getMinBufferSize, sampleRate, CHANNEL_OUT_STEREO, ENCODING_PCM_16BIT); - minBufferSizeIn = (int) env->CallStaticIntMethod (AudioRecord, AudioRecord.getMinBufferSize, sampleRate, CHANNEL_IN_STEREO, ENCODING_PCM_16BIT); - - if (minBufferSizeIn <= 0) - { - minBufferSizeIn = env->CallStaticIntMethod (AudioRecord, AudioRecord.getMinBufferSize, sampleRate, CHANNEL_IN_MONO, ENCODING_PCM_16BIT); - - if (minBufferSizeIn > 0) - numDeviceInputChannelsAvailable = 1; - else - numDeviceInputChannelsAvailable = 0; - } - - DBG ("Audio device - min buffers: " << minBufferSizeOut << ", " << minBufferSizeIn << "; " - << sampleRate << " Hz; input chans: " << numDeviceInputChannelsAvailable); - } - - ~AndroidAudioIODevice() - { - close(); - } - - StringArray getOutputChannelNames() override - { - StringArray s; - s.add ("Left"); - s.add ("Right"); - return s; - } - - StringArray getInputChannelNames() override - { - StringArray s; - - if (numDeviceInputChannelsAvailable == 2) - { - s.add ("Left"); - s.add ("Right"); - } - else if (numDeviceInputChannelsAvailable == 1) - { - s.add ("Audio Input"); - } - - return s; - } - - Array getAvailableSampleRates() override - { - Array r; - r.add ((double) sampleRate); - return r; - } - - Array getAvailableBufferSizes() override - { - Array b; - int n = 16; - - for (int i = 0; i < 50; ++i) - { - b.add (n); - n += n < 64 ? 16 - : (n < 512 ? 32 - : (n < 1024 ? 64 - : (n < 2048 ? 128 : 256))); - } - - return b; - } - - int getDefaultBufferSize() override { return 2048; } - - String open (const BigInteger& inputChannels, - const BigInteger& outputChannels, - double requestedSampleRate, - int bufferSize) override - { - close(); - - if (sampleRate != (int) requestedSampleRate) - return "Sample rate not allowed"; - - lastError.clear(); - int preferredBufferSize = (bufferSize <= 0) ? getDefaultBufferSize() : bufferSize; - - numDeviceInputChannels = 0; - numDeviceOutputChannels = 0; - - activeOutputChans = outputChannels; - activeOutputChans.setRange (2, activeOutputChans.getHighestBit(), false); - numClientOutputChannels = activeOutputChans.countNumberOfSetBits(); - - activeInputChans = inputChannels; - activeInputChans.setRange (2, activeInputChans.getHighestBit(), false); - numClientInputChannels = activeInputChans.countNumberOfSetBits(); - - actualBufferSize = preferredBufferSize; - inputChannelBuffer.setSize (2, actualBufferSize); - inputChannelBuffer.clear(); - outputChannelBuffer.setSize (2, actualBufferSize); - outputChannelBuffer.clear(); - - JNIEnv* env = getEnv(); - - if (numClientOutputChannels > 0) - { - numDeviceOutputChannels = 2; - outputDevice = GlobalRef (env->NewObject (AudioTrack, AudioTrack.constructor, - STREAM_MUSIC, sampleRate, CHANNEL_OUT_STEREO, ENCODING_PCM_16BIT, - (jint) (minBufferSizeOut * numDeviceOutputChannels * sizeof (int16)), MODE_STREAM)); - - if (env->CallIntMethod (outputDevice, AudioTrack.getState) != STATE_UNINITIALIZED) - isRunning = true; - else - outputDevice.clear(); // failed to open the device - } - - if (numClientInputChannels > 0 && numDeviceInputChannelsAvailable > 0) - { - numDeviceInputChannels = jmin (numClientInputChannels, numDeviceInputChannelsAvailable); - inputDevice = GlobalRef (env->NewObject (AudioRecord, AudioRecord.constructor, - 0 /* (default audio source) */, sampleRate, - numDeviceInputChannelsAvailable > 1 ? CHANNEL_IN_STEREO : CHANNEL_IN_MONO, - ENCODING_PCM_16BIT, - (jint) (minBufferSizeIn * numDeviceInputChannels * sizeof (int16)))); - - if (env->CallIntMethod (inputDevice, AudioRecord.getState) != STATE_UNINITIALIZED) - isRunning = true; - else - inputDevice.clear(); // failed to open the device - } - - if (isRunning) - { - if (outputDevice != nullptr) - env->CallVoidMethod (outputDevice, AudioTrack.play); - - if (inputDevice != nullptr) - env->CallVoidMethod (inputDevice, AudioRecord.startRecording); - - startThread (8); - } - else - { - closeDevices(); - } - - return lastError; - } - - void close() override - { - if (isRunning) - { - stopThread (2000); - isRunning = false; - closeDevices(); - } - } - - int getOutputLatencyInSamples() override { return (minBufferSizeOut * 3) / 4; } - int getInputLatencyInSamples() override { return (minBufferSizeIn * 3) / 4; } - bool isOpen() override { return isRunning; } - int getCurrentBufferSizeSamples() override { return actualBufferSize; } - int getCurrentBitDepth() override { return 16; } - double getCurrentSampleRate() override { return sampleRate; } - BigInteger getActiveOutputChannels() const override { return activeOutputChans; } - BigInteger getActiveInputChannels() const override { return activeInputChans; } - String getLastError() override { return lastError; } - bool isPlaying() override { return isRunning && callback != 0; } - - void start (AudioIODeviceCallback* newCallback) override - { - if (isRunning && callback != newCallback) - { - if (newCallback != nullptr) - newCallback->audioDeviceAboutToStart (this); - - const ScopedLock sl (callbackLock); - callback = newCallback; - } - } - - void stop() override - { - if (isRunning) - { - AudioIODeviceCallback* lastCallback; - - { - const ScopedLock sl (callbackLock); - lastCallback = callback; - callback = nullptr; - } - - if (lastCallback != nullptr) - lastCallback->audioDeviceStopped(); - } - } - - void run() override - { - JNIEnv* env = getEnv(); - jshortArray audioBuffer = env->NewShortArray (actualBufferSize * jmax (numDeviceOutputChannels, numDeviceInputChannels)); - - while (! threadShouldExit()) - { - if (inputDevice != nullptr) - { - jint numRead = env->CallIntMethod (inputDevice, AudioRecord.read, audioBuffer, 0, actualBufferSize * numDeviceInputChannels); - - if (numRead < actualBufferSize * numDeviceInputChannels) - { - DBG ("Audio read under-run! " << numRead); - } - - jshort* const src = env->GetShortArrayElements (audioBuffer, 0); - - for (int chan = 0; chan < inputChannelBuffer.getNumChannels(); ++chan) - { - AudioData::Pointer d (inputChannelBuffer.getWritePointer (chan)); - - if (chan < numDeviceInputChannels) - { - AudioData::Pointer s (src + chan, numDeviceInputChannels); - d.convertSamples (s, actualBufferSize); - } - else - { - d.clearSamples (actualBufferSize); - } - } - - env->ReleaseShortArrayElements (audioBuffer, src, 0); - } - - if (threadShouldExit()) - break; - - { - const ScopedLock sl (callbackLock); - - if (callback != nullptr) - { - callback->audioDeviceIOCallback (inputChannelBuffer.getArrayOfReadPointers(), numClientInputChannels, - outputChannelBuffer.getArrayOfWritePointers(), numClientOutputChannels, - actualBufferSize); - } - else - { - outputChannelBuffer.clear(); - } - } - - if (outputDevice != nullptr) - { - if (threadShouldExit()) - break; - - jshort* const dest = env->GetShortArrayElements (audioBuffer, 0); - - for (int chan = 0; chan < numDeviceOutputChannels; ++chan) - { - AudioData::Pointer d (dest + chan, numDeviceOutputChannels); - - const float* const sourceChanData = outputChannelBuffer.getReadPointer (jmin (chan, outputChannelBuffer.getNumChannels() - 1)); - AudioData::Pointer s (sourceChanData); - d.convertSamples (s, actualBufferSize); - } - - env->ReleaseShortArrayElements (audioBuffer, dest, 0); - jint numWritten = env->CallIntMethod (outputDevice, AudioTrack.write, audioBuffer, 0, actualBufferSize * numDeviceOutputChannels); - - if (numWritten < actualBufferSize * numDeviceOutputChannels) - { - DBG ("Audio write underrun! " << numWritten); - } - } - } - } - - int minBufferSizeOut, minBufferSizeIn; - -private: - //================================================================================================== - CriticalSection callbackLock; - AudioIODeviceCallback* callback; - jint sampleRate; - int numClientInputChannels, numDeviceInputChannels, numDeviceInputChannelsAvailable; - int numClientOutputChannels, numDeviceOutputChannels; - int actualBufferSize; - bool isRunning; - String lastError; - BigInteger activeOutputChans, activeInputChans; - GlobalRef outputDevice, inputDevice; - AudioSampleBuffer inputChannelBuffer, outputChannelBuffer; - - void closeDevices() - { - if (outputDevice != nullptr) - { - outputDevice.callVoidMethod (AudioTrack.stop); - outputDevice.callVoidMethod (AudioTrack.release); - outputDevice.clear(); - } - - if (inputDevice != nullptr) - { - inputDevice.callVoidMethod (AudioRecord.stop); - inputDevice.callVoidMethod (AudioRecord.release); - inputDevice.clear(); - } - } - - JUCE_DECLARE_NON_COPYABLE (AndroidAudioIODevice) -}; - -//============================================================================== -class AndroidAudioIODeviceType : public AudioIODeviceType -{ -public: - AndroidAudioIODeviceType() : AudioIODeviceType (javaAudioTypeName) {} - - //============================================================================== - void scanForDevices() {} - StringArray getDeviceNames (bool wantInputNames) const { return StringArray (javaAudioTypeName); } - int getDefaultDeviceIndex (bool forInput) const { return 0; } - int getIndexOfDevice (AudioIODevice* device, bool asInput) const { return device != nullptr ? 0 : -1; } - bool hasSeparateInputsAndOutputs() const { return false; } - - AudioIODevice* createDevice (const String& outputDeviceName, - const String& inputDeviceName) - { - ScopedPointer dev; - - if (outputDeviceName.isNotEmpty() || inputDeviceName.isNotEmpty()) - { - dev = new AndroidAudioIODevice (outputDeviceName.isNotEmpty() ? outputDeviceName - : inputDeviceName); - - if (dev->getCurrentSampleRate() <= 0 || dev->getDefaultBufferSize() <= 0) - dev = nullptr; - } - - return dev.release(); - } - -private: - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AndroidAudioIODeviceType) -}; - - -//============================================================================== -extern bool isOpenSLAvailable(); - -AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_Android() -{ - #if JUCE_USE_ANDROID_OPENSLES - if (isOpenSLAvailable()) - return nullptr; - #endif - - return new AndroidAudioIODeviceType(); -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/native/juce_android_Midi.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/native/juce_android_Midi.cpp deleted file mode 100644 index 88eeae6ed7..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/native/juce_android_Midi.cpp +++ /dev/null @@ -1,85 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -StringArray MidiOutput::getDevices() -{ - StringArray devices; - - return devices; -} - -int MidiOutput::getDefaultDeviceIndex() -{ - return 0; -} - -MidiOutput* MidiOutput::openDevice (int index) -{ - return nullptr; -} - -MidiOutput::~MidiOutput() -{ - stopBackgroundThread(); -} - -void MidiOutput::sendMessageNow (const MidiMessage&) -{ -} - -//============================================================================== -MidiInput::MidiInput (const String& name_) - : name (name_), - internal (0) -{ -} - -MidiInput::~MidiInput() -{ -} - -void MidiInput::start() -{ -} - -void MidiInput::stop() -{ -} - -int MidiInput::getDefaultDeviceIndex() -{ - return 0; -} - -StringArray MidiInput::getDevices() -{ - StringArray devs; - - return devs; -} - -MidiInput* MidiInput::openDevice (int index, MidiInputCallback* callback) -{ - return nullptr; -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/native/juce_android_OpenSL.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/native/juce_android_OpenSL.cpp deleted file mode 100644 index 53dc5df6be..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/native/juce_android_OpenSL.cpp +++ /dev/null @@ -1,632 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -const char* const openSLTypeName = "Android OpenSL"; - -bool isOpenSLAvailable() -{ - DynamicLibrary library; - return library.open ("libOpenSLES.so"); -} - -//============================================================================== -class OpenSLAudioIODevice : public AudioIODevice, - public Thread -{ -public: - OpenSLAudioIODevice (const String& deviceName) - : AudioIODevice (deviceName, openSLTypeName), - Thread ("OpenSL"), - callback (nullptr), sampleRate (0), deviceOpen (false), - inputBuffer (2, 2), outputBuffer (2, 2) - { - // OpenSL has piss-poor support for determining latency, so the only way I can find to - // get a number for this is by asking the AudioTrack/AudioRecord classes.. - AndroidAudioIODevice javaDevice (String::empty); - - // this is a total guess about how to calculate the latency, but seems to vaguely agree - // with the devices I've tested.. YMMV - inputLatency = ((javaDevice.minBufferSizeIn * 2) / 3); - outputLatency = ((javaDevice.minBufferSizeOut * 2) / 3); - - const int longestLatency = jmax (inputLatency, outputLatency); - const int totalLatency = inputLatency + outputLatency; - inputLatency = ((longestLatency * inputLatency) / totalLatency) & ~15; - outputLatency = ((longestLatency * outputLatency) / totalLatency) & ~15; - } - - ~OpenSLAudioIODevice() - { - close(); - } - - bool openedOk() const { return engine.outputMixObject != nullptr; } - - StringArray getOutputChannelNames() override - { - StringArray s; - s.add ("Left"); - s.add ("Right"); - return s; - } - - StringArray getInputChannelNames() override - { - StringArray s; - s.add ("Audio Input"); - return s; - } - - Array getAvailableSampleRates() override - { - static const double rates[] = { 8000.0, 16000.0, 32000.0, 44100.0, 48000.0 }; - return Array (rates, numElementsInArray (rates)); - } - - Array getAvailableBufferSizes() override - { - static const int sizes[] = { 256, 512, 768, 1024, 1280, 1600 }; // must all be multiples of the block size - return Array (sizes, numElementsInArray (sizes)); - } - - String open (const BigInteger& inputChannels, - const BigInteger& outputChannels, - double requestedSampleRate, - int bufferSize) override - { - close(); - - lastError.clear(); - sampleRate = (int) requestedSampleRate; - - int preferredBufferSize = (bufferSize <= 0) ? getDefaultBufferSize() : bufferSize; - - activeOutputChans = outputChannels; - activeOutputChans.setRange (2, activeOutputChans.getHighestBit(), false); - numOutputChannels = activeOutputChans.countNumberOfSetBits(); - - activeInputChans = inputChannels; - activeInputChans.setRange (1, activeInputChans.getHighestBit(), false); - numInputChannels = activeInputChans.countNumberOfSetBits(); - - actualBufferSize = preferredBufferSize; - - inputBuffer.setSize (jmax (1, numInputChannels), actualBufferSize); - outputBuffer.setSize (jmax (1, numOutputChannels), actualBufferSize); - outputBuffer.clear(); - - recorder = engine.createRecorder (numInputChannels, sampleRate); - player = engine.createPlayer (numOutputChannels, sampleRate); - - startThread (8); - - deviceOpen = true; - return lastError; - } - - void close() override - { - stop(); - stopThread (6000); - deviceOpen = false; - recorder = nullptr; - player = nullptr; - } - - int getDefaultBufferSize() override { return 1024; } - int getOutputLatencyInSamples() override { return outputLatency; } - int getInputLatencyInSamples() override { return inputLatency; } - bool isOpen() override { return deviceOpen; } - int getCurrentBufferSizeSamples() override { return actualBufferSize; } - int getCurrentBitDepth() override { return 16; } - double getCurrentSampleRate() override { return sampleRate; } - BigInteger getActiveOutputChannels() const override { return activeOutputChans; } - BigInteger getActiveInputChannels() const override { return activeInputChans; } - String getLastError() override { return lastError; } - bool isPlaying() override { return callback != nullptr; } - - void start (AudioIODeviceCallback* newCallback) override - { - stop(); - - if (deviceOpen && callback != newCallback) - { - if (newCallback != nullptr) - newCallback->audioDeviceAboutToStart (this); - - setCallback (newCallback); - } - } - - void stop() override - { - if (AudioIODeviceCallback* const oldCallback = setCallback (nullptr)) - oldCallback->audioDeviceStopped(); - } - - bool setAudioPreprocessingEnabled (bool enable) override - { - return recorder != nullptr && recorder->setAudioPreprocessingEnabled (enable); - } - -private: - //================================================================================================== - CriticalSection callbackLock; - AudioIODeviceCallback* callback; - int actualBufferSize, sampleRate; - int inputLatency, outputLatency; - bool deviceOpen; - String lastError; - BigInteger activeOutputChans, activeInputChans; - int numInputChannels, numOutputChannels; - AudioSampleBuffer inputBuffer, outputBuffer; - struct Player; - struct Recorder; - - AudioIODeviceCallback* setCallback (AudioIODeviceCallback* const newCallback) - { - const ScopedLock sl (callbackLock); - AudioIODeviceCallback* const oldCallback = callback; - callback = newCallback; - return oldCallback; - } - - void run() override - { - if (recorder != nullptr) recorder->start(); - if (player != nullptr) player->start(); - - while (! threadShouldExit()) - { - if (player != nullptr) player->writeBuffer (outputBuffer, *this); - if (recorder != nullptr) recorder->readNextBlock (inputBuffer, *this); - - const ScopedLock sl (callbackLock); - - if (callback != nullptr) - { - callback->audioDeviceIOCallback (numInputChannels > 0 ? inputBuffer.getArrayOfReadPointers() : nullptr, numInputChannels, - numOutputChannels > 0 ? outputBuffer.getArrayOfWritePointers() : nullptr, numOutputChannels, - actualBufferSize); - } - else - { - outputBuffer.clear(); - } - } - } - - //================================================================================================== - struct Engine - { - Engine() - : engineObject (nullptr), engineInterface (nullptr), outputMixObject (nullptr) - { - if (library.open ("libOpenSLES.so")) - { - typedef SLresult (*CreateEngineFunc) (SLObjectItf*, SLuint32, const SLEngineOption*, SLuint32, const SLInterfaceID*, const SLboolean*); - - if (CreateEngineFunc createEngine = (CreateEngineFunc) library.getFunction ("slCreateEngine")) - { - check (createEngine (&engineObject, 0, nullptr, 0, nullptr, nullptr)); - - SLInterfaceID* SL_IID_ENGINE = (SLInterfaceID*) library.getFunction ("SL_IID_ENGINE"); - SL_IID_ANDROIDSIMPLEBUFFERQUEUE = (SLInterfaceID*) library.getFunction ("SL_IID_ANDROIDSIMPLEBUFFERQUEUE"); - SL_IID_PLAY = (SLInterfaceID*) library.getFunction ("SL_IID_PLAY"); - SL_IID_RECORD = (SLInterfaceID*) library.getFunction ("SL_IID_RECORD"); - SL_IID_ANDROIDCONFIGURATION = (SLInterfaceID*) library.getFunction ("SL_IID_ANDROIDCONFIGURATION"); - - check ((*engineObject)->Realize (engineObject, SL_BOOLEAN_FALSE)); - check ((*engineObject)->GetInterface (engineObject, *SL_IID_ENGINE, &engineInterface)); - - check ((*engineInterface)->CreateOutputMix (engineInterface, &outputMixObject, 0, nullptr, nullptr)); - check ((*outputMixObject)->Realize (outputMixObject, SL_BOOLEAN_FALSE)); - } - } - } - - ~Engine() - { - if (outputMixObject != nullptr) (*outputMixObject)->Destroy (outputMixObject); - if (engineObject != nullptr) (*engineObject)->Destroy (engineObject); - } - - Player* createPlayer (const int numChannels, const int sampleRate) - { - if (numChannels <= 0) - return nullptr; - - ScopedPointer player (new Player (numChannels, sampleRate, *this)); - return player->openedOk() ? player.release() : nullptr; - } - - Recorder* createRecorder (const int numChannels, const int sampleRate) - { - if (numChannels <= 0) - return nullptr; - - ScopedPointer recorder (new Recorder (numChannels, sampleRate, *this)); - return recorder->openedOk() ? recorder.release() : nullptr; - } - - SLObjectItf engineObject; - SLEngineItf engineInterface; - SLObjectItf outputMixObject; - - SLInterfaceID* SL_IID_ANDROIDSIMPLEBUFFERQUEUE; - SLInterfaceID* SL_IID_PLAY; - SLInterfaceID* SL_IID_RECORD; - SLInterfaceID* SL_IID_ANDROIDCONFIGURATION; - - private: - DynamicLibrary library; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Engine) - }; - - //================================================================================================== - struct BufferList - { - BufferList (const int numChannels_) - : numChannels (numChannels_), bufferSpace (numChannels_ * numSamples * numBuffers), nextBlock (0) - { - } - - int16* waitForFreeBuffer (Thread& threadToCheck) - { - while (numBlocksOut.get() == numBuffers) - { - dataArrived.wait (1); - - if (threadToCheck.threadShouldExit()) - return nullptr; - } - - return getNextBuffer(); - } - - int16* getNextBuffer() - { - if (++nextBlock == numBuffers) - nextBlock = 0; - - return bufferSpace + nextBlock * numChannels * numSamples; - } - - void bufferReturned() { --numBlocksOut; dataArrived.signal(); } - void bufferSent() { ++numBlocksOut; dataArrived.signal(); } - - int getBufferSizeBytes() const { return numChannels * numSamples * sizeof (int16); } - - const int numChannels; - enum { numSamples = 256, numBuffers = 16 }; - - private: - HeapBlock bufferSpace; - int nextBlock; - Atomic numBlocksOut; - WaitableEvent dataArrived; - }; - - //================================================================================================== - struct Player - { - Player (int numChannels, int sampleRate, Engine& engine) - : playerObject (nullptr), playerPlay (nullptr), playerBufferQueue (nullptr), - bufferList (numChannels) - { - jassert (numChannels == 2); - - SLDataFormat_PCM pcmFormat = - { - SL_DATAFORMAT_PCM, - (SLuint32) numChannels, - (SLuint32) (sampleRate * 1000), // (sample rate units are millihertz) - SL_PCMSAMPLEFORMAT_FIXED_16, - SL_PCMSAMPLEFORMAT_FIXED_16, - SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT, - SL_BYTEORDER_LITTLEENDIAN - }; - - SLDataLocator_AndroidSimpleBufferQueue bufferQueue = { SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, bufferList.numBuffers }; - SLDataSource audioSrc = { &bufferQueue, &pcmFormat }; - - SLDataLocator_OutputMix outputMix = { SL_DATALOCATOR_OUTPUTMIX, engine.outputMixObject }; - SLDataSink audioSink = { &outputMix, nullptr }; - - // (SL_IID_BUFFERQUEUE is not guaranteed to remain future-proof, so use SL_IID_ANDROIDSIMPLEBUFFERQUEUE) - const SLInterfaceID interfaceIDs[] = { *engine.SL_IID_ANDROIDSIMPLEBUFFERQUEUE }; - const SLboolean flags[] = { SL_BOOLEAN_TRUE }; - - check ((*engine.engineInterface)->CreateAudioPlayer (engine.engineInterface, &playerObject, &audioSrc, &audioSink, - 1, interfaceIDs, flags)); - - check ((*playerObject)->Realize (playerObject, SL_BOOLEAN_FALSE)); - check ((*playerObject)->GetInterface (playerObject, *engine.SL_IID_PLAY, &playerPlay)); - check ((*playerObject)->GetInterface (playerObject, *engine.SL_IID_ANDROIDSIMPLEBUFFERQUEUE, &playerBufferQueue)); - check ((*playerBufferQueue)->RegisterCallback (playerBufferQueue, staticCallback, this)); - } - - ~Player() - { - if (playerPlay != nullptr) - check ((*playerPlay)->SetPlayState (playerPlay, SL_PLAYSTATE_STOPPED)); - - if (playerBufferQueue != nullptr) - check ((*playerBufferQueue)->Clear (playerBufferQueue)); - - if (playerObject != nullptr) - (*playerObject)->Destroy (playerObject); - } - - bool openedOk() const noexcept { return playerBufferQueue != nullptr; } - - void start() - { - jassert (openedOk()); - check ((*playerPlay)->SetPlayState (playerPlay, SL_PLAYSTATE_PLAYING)); - } - - void writeBuffer (const AudioSampleBuffer& buffer, Thread& thread) - { - jassert (buffer.getNumChannels() == bufferList.numChannels); - jassert (buffer.getNumSamples() < bufferList.numSamples * bufferList.numBuffers); - - int offset = 0; - int numSamples = buffer.getNumSamples(); - - while (numSamples > 0) - { - int16* const destBuffer = bufferList.waitForFreeBuffer (thread); - - if (destBuffer == nullptr) - break; - - for (int i = 0; i < bufferList.numChannels; ++i) - { - typedef AudioData::Pointer DstSampleType; - typedef AudioData::Pointer SrcSampleType; - - DstSampleType dstData (destBuffer + i, bufferList.numChannels); - SrcSampleType srcData (buffer.getReadPointer (i, offset)); - dstData.convertSamples (srcData, bufferList.numSamples); - } - - check ((*playerBufferQueue)->Enqueue (playerBufferQueue, destBuffer, bufferList.getBufferSizeBytes())); - bufferList.bufferSent(); - - numSamples -= bufferList.numSamples; - offset += bufferList.numSamples; - } - } - - private: - SLObjectItf playerObject; - SLPlayItf playerPlay; - SLAndroidSimpleBufferQueueItf playerBufferQueue; - - BufferList bufferList; - - static void staticCallback (SLAndroidSimpleBufferQueueItf queue, void* context) - { - jassert (queue == static_cast (context)->playerBufferQueue); (void) queue; - static_cast (context)->bufferList.bufferReturned(); - } - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Player) - }; - - //================================================================================================== - struct Recorder - { - Recorder (int numChannels, int sampleRate, Engine& engine) - : recorderObject (nullptr), recorderRecord (nullptr), - recorderBufferQueue (nullptr), configObject (nullptr), - bufferList (numChannels) - { - jassert (numChannels == 1); // STEREO doesn't always work!! - - SLDataFormat_PCM pcmFormat = - { - SL_DATAFORMAT_PCM, - (SLuint32) numChannels, - (SLuint32) (sampleRate * 1000), // (sample rate units are millihertz) - SL_PCMSAMPLEFORMAT_FIXED_16, - SL_PCMSAMPLEFORMAT_FIXED_16, - (numChannels == 1) ? SL_SPEAKER_FRONT_CENTER : (SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT), - SL_BYTEORDER_LITTLEENDIAN - }; - - SLDataLocator_IODevice ioDevice = { SL_DATALOCATOR_IODEVICE, SL_IODEVICE_AUDIOINPUT, SL_DEFAULTDEVICEID_AUDIOINPUT, nullptr }; - SLDataSource audioSrc = { &ioDevice, nullptr }; - - SLDataLocator_AndroidSimpleBufferQueue bufferQueue = { SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, bufferList.numBuffers }; - SLDataSink audioSink = { &bufferQueue, &pcmFormat }; - - const SLInterfaceID interfaceIDs[] = { *engine.SL_IID_ANDROIDSIMPLEBUFFERQUEUE }; - const SLboolean flags[] = { SL_BOOLEAN_TRUE }; - - if (check ((*engine.engineInterface)->CreateAudioRecorder (engine.engineInterface, &recorderObject, &audioSrc, - &audioSink, 1, interfaceIDs, flags))) - { - if (check ((*recorderObject)->Realize (recorderObject, SL_BOOLEAN_FALSE))) - { - check ((*recorderObject)->GetInterface (recorderObject, *engine.SL_IID_RECORD, &recorderRecord)); - check ((*recorderObject)->GetInterface (recorderObject, *engine.SL_IID_ANDROIDSIMPLEBUFFERQUEUE, &recorderBufferQueue)); - check ((*recorderObject)->GetInterface (recorderObject, *engine.SL_IID_ANDROIDCONFIGURATION, &configObject)); - check ((*recorderBufferQueue)->RegisterCallback (recorderBufferQueue, staticCallback, this)); - check ((*recorderRecord)->SetRecordState (recorderRecord, SL_RECORDSTATE_STOPPED)); - - for (int i = bufferList.numBuffers; --i >= 0;) - { - int16* const buffer = bufferList.getNextBuffer(); - jassert (buffer != nullptr); - enqueueBuffer (buffer); - } - } - } - } - - ~Recorder() - { - if (recorderRecord != nullptr) - check ((*recorderRecord)->SetRecordState (recorderRecord, SL_RECORDSTATE_STOPPED)); - - if (recorderBufferQueue != nullptr) - check ((*recorderBufferQueue)->Clear (recorderBufferQueue)); - - if (recorderObject != nullptr) - (*recorderObject)->Destroy (recorderObject); - } - - bool openedOk() const noexcept { return recorderBufferQueue != nullptr; } - - void start() - { - jassert (openedOk()); - check ((*recorderRecord)->SetRecordState (recorderRecord, SL_RECORDSTATE_RECORDING)); - } - - void readNextBlock (AudioSampleBuffer& buffer, Thread& thread) - { - jassert (buffer.getNumChannels() == bufferList.numChannels); - jassert (buffer.getNumSamples() < bufferList.numSamples * bufferList.numBuffers); - jassert ((buffer.getNumSamples() % bufferList.numSamples) == 0); - - int offset = 0; - int numSamples = buffer.getNumSamples(); - - while (numSamples > 0) - { - int16* const srcBuffer = bufferList.waitForFreeBuffer (thread); - - if (srcBuffer == nullptr) - break; - - for (int i = 0; i < bufferList.numChannels; ++i) - { - typedef AudioData::Pointer DstSampleType; - typedef AudioData::Pointer SrcSampleType; - - DstSampleType dstData (buffer.getWritePointer (i, offset)); - SrcSampleType srcData (srcBuffer + i, bufferList.numChannels); - dstData.convertSamples (srcData, bufferList.numSamples); - } - - enqueueBuffer (srcBuffer); - - numSamples -= bufferList.numSamples; - offset += bufferList.numSamples; - } - } - - bool setAudioPreprocessingEnabled (bool enable) - { - SLuint32 mode = enable ? SL_ANDROID_RECORDING_PRESET_GENERIC - : SL_ANDROID_RECORDING_PRESET_VOICE_RECOGNITION; - - return configObject != nullptr - && check ((*configObject)->SetConfiguration (configObject, SL_ANDROID_KEY_RECORDING_PRESET, &mode, sizeof (mode))); - } - - private: - SLObjectItf recorderObject; - SLRecordItf recorderRecord; - SLAndroidSimpleBufferQueueItf recorderBufferQueue; - SLAndroidConfigurationItf configObject; - - BufferList bufferList; - - void enqueueBuffer (int16* buffer) - { - check ((*recorderBufferQueue)->Enqueue (recorderBufferQueue, buffer, bufferList.getBufferSizeBytes())); - bufferList.bufferSent(); - } - - static void staticCallback (SLAndroidSimpleBufferQueueItf queue, void* context) - { - jassert (queue == static_cast (context)->recorderBufferQueue); (void) queue; - static_cast (context)->bufferList.bufferReturned(); - } - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Recorder) - }; - - - //============================================================================== - Engine engine; - - ScopedPointer player; - ScopedPointer recorder; - - //============================================================================== - static bool check (const SLresult result) - { - jassert (result == SL_RESULT_SUCCESS); - return result == SL_RESULT_SUCCESS; - } - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (OpenSLAudioIODevice) -}; - - -//============================================================================== -class OpenSLAudioDeviceType : public AudioIODeviceType -{ -public: - OpenSLAudioDeviceType() : AudioIODeviceType (openSLTypeName) {} - - //============================================================================== - void scanForDevices() {} - StringArray getDeviceNames (bool wantInputNames) const { return StringArray (openSLTypeName); } - int getDefaultDeviceIndex (bool forInput) const { return 0; } - int getIndexOfDevice (AudioIODevice* device, bool asInput) const { return device != nullptr ? 0 : -1; } - bool hasSeparateInputsAndOutputs() const { return false; } - - AudioIODevice* createDevice (const String& outputDeviceName, - const String& inputDeviceName) - { - ScopedPointer dev; - - if (outputDeviceName.isNotEmpty() || inputDeviceName.isNotEmpty()) - { - dev = new OpenSLAudioIODevice (outputDeviceName.isNotEmpty() ? outputDeviceName - : inputDeviceName); - if (! dev->openedOk()) - dev = nullptr; - } - - return dev.release(); - } - -private: - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (OpenSLAudioDeviceType) -}; - - -//============================================================================== -AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_OpenSLES() -{ - return isOpenSLAvailable() ? new OpenSLAudioDeviceType() : nullptr; -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/native/juce_ios_Audio.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/native/juce_ios_Audio.cpp deleted file mode 100644 index 70490aa54e..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/native/juce_ios_Audio.cpp +++ /dev/null @@ -1,576 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -class iOSAudioIODevice : public AudioIODevice -{ -public: - iOSAudioIODevice (const String& deviceName) - : AudioIODevice (deviceName, "Audio"), - actualBufferSize (0), - isRunning (false), - audioUnit (0), - callback (nullptr), - floatData (1, 2) - { - getSessionHolder().activeDevices.add (this); - - numInputChannels = 2; - numOutputChannels = 2; - preferredBufferSize = 0; - - updateDeviceInfo(); - } - - ~iOSAudioIODevice() - { - getSessionHolder().activeDevices.removeFirstMatchingValue (this); - close(); - } - - StringArray getOutputChannelNames() override - { - StringArray s; - s.add ("Left"); - s.add ("Right"); - return s; - } - - StringArray getInputChannelNames() override - { - StringArray s; - if (audioInputIsAvailable) - { - s.add ("Left"); - s.add ("Right"); - } - return s; - } - - Array getAvailableSampleRates() override - { - // can't find a good way to actually ask the device for which of these it supports.. - static const double rates[] = { 8000.0, 16000.0, 22050.0, 32000.0, 44100.0, 48000.0 }; - return Array (rates, numElementsInArray (rates)); - } - - Array getAvailableBufferSizes() override - { - Array r; - - for (int i = 6; i < 12; ++i) - r.add (1 << i); - - return r; - } - - int getDefaultBufferSize() override { return 1024; } - - String open (const BigInteger& inputChannelsWanted, - const BigInteger& outputChannelsWanted, - double targetSampleRate, int bufferSize) override - { - close(); - - lastError.clear(); - preferredBufferSize = (bufferSize <= 0) ? getDefaultBufferSize() : bufferSize; - - // xxx set up channel mapping - - activeOutputChans = outputChannelsWanted; - activeOutputChans.setRange (2, activeOutputChans.getHighestBit(), false); - numOutputChannels = activeOutputChans.countNumberOfSetBits(); - monoOutputChannelNumber = activeOutputChans.findNextSetBit (0); - - activeInputChans = inputChannelsWanted; - activeInputChans.setRange (2, activeInputChans.getHighestBit(), false); - numInputChannels = activeInputChans.countNumberOfSetBits(); - monoInputChannelNumber = activeInputChans.findNextSetBit (0); - - AudioSessionSetActive (true); - - if (numInputChannels > 0 && audioInputIsAvailable) - { - setSessionUInt32Property (kAudioSessionProperty_AudioCategory, kAudioSessionCategory_PlayAndRecord); - setSessionUInt32Property (kAudioSessionProperty_OverrideCategoryEnableBluetoothInput, 1); - } - else - { - setSessionUInt32Property (kAudioSessionProperty_AudioCategory, kAudioSessionCategory_MediaPlayback); - } - - AudioSessionAddPropertyListener (kAudioSessionProperty_AudioRouteChange, routingChangedStatic, this); - - fixAudioRouteIfSetToReceiver(); - - setSessionFloat64Property (kAudioSessionProperty_PreferredHardwareSampleRate, targetSampleRate); - updateDeviceInfo(); - - setSessionFloat32Property (kAudioSessionProperty_PreferredHardwareIOBufferDuration, preferredBufferSize / sampleRate); - updateCurrentBufferSize(); - - prepareFloatBuffers (actualBufferSize); - - isRunning = true; - routingChanged (nullptr); // creates and starts the AU - - lastError = audioUnit != 0 ? "" : "Couldn't open the device"; - return lastError; - } - - void close() override - { - if (isRunning) - { - isRunning = false; - - setSessionUInt32Property (kAudioSessionProperty_AudioCategory, kAudioSessionCategory_MediaPlayback); - - AudioSessionRemovePropertyListenerWithUserData (kAudioSessionProperty_AudioRouteChange, routingChangedStatic, this); - AudioSessionSetActive (false); - - if (audioUnit != 0) - { - AudioComponentInstanceDispose (audioUnit); - audioUnit = 0; - } - } - } - - bool isOpen() override { return isRunning; } - - int getCurrentBufferSizeSamples() override { return actualBufferSize; } - double getCurrentSampleRate() override { return sampleRate; } - int getCurrentBitDepth() override { return 16; } - - BigInteger getActiveOutputChannels() const override { return activeOutputChans; } - BigInteger getActiveInputChannels() const override { return activeInputChans; } - - int getOutputLatencyInSamples() override { return getLatency (kAudioSessionProperty_CurrentHardwareOutputLatency); } - int getInputLatencyInSamples() override { return getLatency (kAudioSessionProperty_CurrentHardwareInputLatency); } - - int getLatency (AudioSessionPropertyID propID) - { - Float32 latency = 0; - getSessionProperty (propID, latency); - return roundToInt (latency * getCurrentSampleRate()); - } - - void start (AudioIODeviceCallback* newCallback) override - { - if (isRunning && callback != newCallback) - { - if (newCallback != nullptr) - newCallback->audioDeviceAboutToStart (this); - - const ScopedLock sl (callbackLock); - callback = newCallback; - } - } - - void stop() override - { - if (isRunning) - { - AudioIODeviceCallback* lastCallback; - - { - const ScopedLock sl (callbackLock); - lastCallback = callback; - callback = nullptr; - } - - if (lastCallback != nullptr) - lastCallback->audioDeviceStopped(); - } - } - - bool isPlaying() override { return isRunning && callback != nullptr; } - String getLastError() override { return lastError; } - - bool setAudioPreprocessingEnabled (bool enable) override - { - return setSessionUInt32Property (kAudioSessionProperty_Mode, enable ? kAudioSessionMode_Default - : kAudioSessionMode_Measurement); - } - -private: - //================================================================================================== - CriticalSection callbackLock; - Float64 sampleRate; - int numInputChannels, numOutputChannels; - int preferredBufferSize, actualBufferSize; - bool isRunning; - String lastError; - - AudioStreamBasicDescription format; - AudioUnit audioUnit; - UInt32 audioInputIsAvailable; - AudioIODeviceCallback* callback; - BigInteger activeOutputChans, activeInputChans; - - AudioSampleBuffer floatData; - float* inputChannels[3]; - float* outputChannels[3]; - bool monoInputChannelNumber, monoOutputChannelNumber; - - void prepareFloatBuffers (int bufferSize) - { - if (numInputChannels + numOutputChannels > 0) - { - floatData.setSize (numInputChannels + numOutputChannels, bufferSize); - zeromem (inputChannels, sizeof (inputChannels)); - zeromem (outputChannels, sizeof (outputChannels)); - - for (int i = 0; i < numInputChannels; ++i) - inputChannels[i] = floatData.getWritePointer (i); - - for (int i = 0; i < numOutputChannels; ++i) - outputChannels[i] = floatData.getWritePointer (i + numInputChannels); - } - } - - //================================================================================================== - OSStatus process (AudioUnitRenderActionFlags* flags, const AudioTimeStamp* time, - const UInt32 numFrames, AudioBufferList* data) - { - OSStatus err = noErr; - - if (audioInputIsAvailable && numInputChannels > 0) - err = AudioUnitRender (audioUnit, flags, time, 1, numFrames, data); - - const ScopedLock sl (callbackLock); - - if (callback != nullptr) - { - if ((int) numFrames > floatData.getNumSamples()) - prepareFloatBuffers ((int) numFrames); - - if (audioInputIsAvailable && numInputChannels > 0) - { - short* shortData = (short*) data->mBuffers[0].mData; - - if (numInputChannels >= 2) - { - for (UInt32 i = 0; i < numFrames; ++i) - { - inputChannels[0][i] = *shortData++ * (1.0f / 32768.0f); - inputChannels[1][i] = *shortData++ * (1.0f / 32768.0f); - } - } - else - { - if (monoInputChannelNumber > 0) - ++shortData; - - for (UInt32 i = 0; i < numFrames; ++i) - { - inputChannels[0][i] = *shortData++ * (1.0f / 32768.0f); - ++shortData; - } - } - } - else - { - for (int i = numInputChannels; --i >= 0;) - zeromem (inputChannels[i], sizeof (float) * numFrames); - } - - callback->audioDeviceIOCallback ((const float**) inputChannels, numInputChannels, - outputChannels, numOutputChannels, (int) numFrames); - - short* shortData = (short*) data->mBuffers[0].mData; - int n = 0; - - if (numOutputChannels >= 2) - { - for (UInt32 i = 0; i < numFrames; ++i) - { - shortData [n++] = (short) (outputChannels[0][i] * 32767.0f); - shortData [n++] = (short) (outputChannels[1][i] * 32767.0f); - } - } - else if (numOutputChannels == 1) - { - for (UInt32 i = 0; i < numFrames; ++i) - { - const short s = (short) (outputChannels[monoOutputChannelNumber][i] * 32767.0f); - shortData [n++] = s; - shortData [n++] = s; - } - } - else - { - zeromem (data->mBuffers[0].mData, 2 * sizeof (short) * numFrames); - } - } - else - { - zeromem (data->mBuffers[0].mData, 2 * sizeof (short) * numFrames); - } - - return err; - } - - void updateDeviceInfo() - { - getSessionProperty (kAudioSessionProperty_CurrentHardwareSampleRate, sampleRate); - getSessionProperty (kAudioSessionProperty_AudioInputAvailable, audioInputIsAvailable); - } - - void updateCurrentBufferSize() - { - Float32 bufferDuration = sampleRate > 0 ? (Float32) (preferredBufferSize / sampleRate) : 0.0f; - getSessionProperty (kAudioSessionProperty_CurrentHardwareIOBufferDuration, bufferDuration); - actualBufferSize = (int) (sampleRate * bufferDuration + 0.5); - } - - void routingChanged (const void* propertyValue) - { - if (! isRunning) - return; - - if (propertyValue != nullptr) - { - CFDictionaryRef routeChangeDictionary = (CFDictionaryRef) propertyValue; - CFNumberRef routeChangeReasonRef = (CFNumberRef) CFDictionaryGetValue (routeChangeDictionary, - CFSTR (kAudioSession_AudioRouteChangeKey_Reason)); - - SInt32 routeChangeReason; - CFNumberGetValue (routeChangeReasonRef, kCFNumberSInt32Type, &routeChangeReason); - - if (routeChangeReason == kAudioSessionRouteChangeReason_OldDeviceUnavailable) - { - const ScopedLock sl (callbackLock); - - if (callback != nullptr) - callback->audioDeviceError ("Old device unavailable"); - } - } - - updateDeviceInfo(); - createAudioUnit(); - - AudioSessionSetActive (true); - - if (audioUnit != 0) - { - UInt32 formatSize = sizeof (format); - AudioUnitGetProperty (audioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 1, &format, &formatSize); - - updateCurrentBufferSize(); - AudioOutputUnitStart (audioUnit); - } - } - - //================================================================================================== - struct AudioSessionHolder - { - AudioSessionHolder() - { - AudioSessionInitialize (0, 0, interruptionListenerCallback, this); - } - - static void interruptionListenerCallback (void* client, UInt32 interruptionType) - { - const Array & activeDevices = static_cast (client)->activeDevices; - - for (int i = activeDevices.size(); --i >= 0;) - activeDevices.getUnchecked(i)->interruptionListener (interruptionType); - } - - Array activeDevices; - }; - - static AudioSessionHolder& getSessionHolder() - { - static AudioSessionHolder audioSessionHolder; - return audioSessionHolder; - } - - void interruptionListener (const UInt32 interruptionType) - { - if (interruptionType == kAudioSessionBeginInterruption) - { - isRunning = false; - AudioOutputUnitStop (audioUnit); - AudioSessionSetActive (false); - - const ScopedLock sl (callbackLock); - - if (callback != nullptr) - callback->audioDeviceError ("iOS audio session interruption"); - } - - if (interruptionType == kAudioSessionEndInterruption) - { - isRunning = true; - AudioSessionSetActive (true); - AudioOutputUnitStart (audioUnit); - - const ScopedLock sl (callbackLock); - - if (callback != nullptr) - callback->audioDeviceError ("iOS audio session resumed"); - } - } - - //================================================================================================== - static OSStatus processStatic (void* client, AudioUnitRenderActionFlags* flags, const AudioTimeStamp* time, - UInt32 /*busNumber*/, UInt32 numFrames, AudioBufferList* data) - { - return static_cast (client)->process (flags, time, numFrames, data); - } - - static void routingChangedStatic (void* client, AudioSessionPropertyID, UInt32 /*inDataSize*/, const void* propertyValue) - { - static_cast (client)->routingChanged (propertyValue); - } - - //================================================================================================== - void resetFormat (const int numChannels) noexcept - { - zerostruct (format); - format.mFormatID = kAudioFormatLinearPCM; - format.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsPacked | kAudioFormatFlagsNativeEndian; - format.mBitsPerChannel = 8 * sizeof (short); - format.mChannelsPerFrame = (UInt32) numChannels; - format.mFramesPerPacket = 1; - format.mBytesPerFrame = format.mBytesPerPacket = (UInt32) numChannels * sizeof (short); - } - - bool createAudioUnit() - { - if (audioUnit != 0) - { - AudioComponentInstanceDispose (audioUnit); - audioUnit = 0; - } - - resetFormat (2); - - AudioComponentDescription desc; - desc.componentType = kAudioUnitType_Output; - desc.componentSubType = kAudioUnitSubType_RemoteIO; - desc.componentManufacturer = kAudioUnitManufacturer_Apple; - desc.componentFlags = 0; - desc.componentFlagsMask = 0; - - AudioComponent comp = AudioComponentFindNext (0, &desc); - AudioComponentInstanceNew (comp, &audioUnit); - - if (audioUnit == 0) - return false; - - if (numInputChannels > 0) - { - const UInt32 one = 1; - AudioUnitSetProperty (audioUnit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input, 1, &one, sizeof (one)); - } - - { - AudioChannelLayout layout; - layout.mChannelBitmap = 0; - layout.mNumberChannelDescriptions = 0; - layout.mChannelLayoutTag = kAudioChannelLayoutTag_Stereo; - AudioUnitSetProperty (audioUnit, kAudioUnitProperty_AudioChannelLayout, kAudioUnitScope_Input, 0, &layout, sizeof (layout)); - AudioUnitSetProperty (audioUnit, kAudioUnitProperty_AudioChannelLayout, kAudioUnitScope_Output, 0, &layout, sizeof (layout)); - } - - { - AURenderCallbackStruct inputProc; - inputProc.inputProc = processStatic; - inputProc.inputProcRefCon = this; - AudioUnitSetProperty (audioUnit, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input, 0, &inputProc, sizeof (inputProc)); - } - - AudioUnitSetProperty (audioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &format, sizeof (format)); - AudioUnitSetProperty (audioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 1, &format, sizeof (format)); - - AudioUnitInitialize (audioUnit); - return true; - } - - // If the routing is set to go through the receiver (i.e. the speaker, but quiet), this re-routes it - // to make it loud. Needed because by default when using an input + output, the output is kept quiet. - static void fixAudioRouteIfSetToReceiver() - { - CFStringRef audioRoute = 0; - if (getSessionProperty (kAudioSessionProperty_AudioRoute, audioRoute) == noErr) - { - NSString* route = (NSString*) audioRoute; - - //DBG ("audio route: " + nsStringToJuce (route)); - - if ([route hasPrefix: @"Receiver"]) - setSessionUInt32Property (kAudioSessionProperty_OverrideAudioRoute, kAudioSessionOverrideAudioRoute_Speaker); - - CFRelease (audioRoute); - } - } - - template - static OSStatus getSessionProperty (AudioSessionPropertyID propID, Type& result) noexcept - { - UInt32 valueSize = sizeof (result); - return AudioSessionGetProperty (propID, &valueSize, &result); - } - - static bool setSessionUInt32Property (AudioSessionPropertyID propID, UInt32 v) noexcept { return AudioSessionSetProperty (propID, sizeof (v), &v) == kAudioSessionNoError; } - static bool setSessionFloat32Property (AudioSessionPropertyID propID, Float32 v) noexcept { return AudioSessionSetProperty (propID, sizeof (v), &v) == kAudioSessionNoError; } - static bool setSessionFloat64Property (AudioSessionPropertyID propID, Float64 v) noexcept { return AudioSessionSetProperty (propID, sizeof (v), &v) == kAudioSessionNoError; } - - JUCE_DECLARE_NON_COPYABLE (iOSAudioIODevice) -}; - - -//============================================================================== -class iOSAudioIODeviceType : public AudioIODeviceType -{ -public: - iOSAudioIODeviceType() : AudioIODeviceType ("iOS Audio") {} - - void scanForDevices() {} - StringArray getDeviceNames (bool /*wantInputNames*/) const { return StringArray ("iOS Audio"); } - int getDefaultDeviceIndex (bool /*forInput*/) const { return 0; } - int getIndexOfDevice (AudioIODevice* d, bool /*asInput*/) const { return d != nullptr ? 0 : -1; } - bool hasSeparateInputsAndOutputs() const { return false; } - - AudioIODevice* createDevice (const String& outputDeviceName, const String& inputDeviceName) - { - if (outputDeviceName.isNotEmpty() || inputDeviceName.isNotEmpty()) - return new iOSAudioIODevice (outputDeviceName.isNotEmpty() ? outputDeviceName - : inputDeviceName); - - return nullptr; - } - -private: - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (iOSAudioIODeviceType) -}; - -//============================================================================== -AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_iOSAudio() -{ - return new iOSAudioIODeviceType(); -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/native/juce_linux_ALSA.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/native/juce_linux_ALSA.cpp deleted file mode 100644 index 091ffbab54..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/native/juce_linux_ALSA.cpp +++ /dev/null @@ -1,1243 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -namespace -{ - -#ifndef JUCE_ALSA_LOGGING - #define JUCE_ALSA_LOGGING 0 -#endif - -#if JUCE_ALSA_LOGGING - #define JUCE_ALSA_LOG(dbgtext) { juce::String tempDbgBuf ("ALSA: "); tempDbgBuf << dbgtext; Logger::writeToLog (tempDbgBuf); DBG (tempDbgBuf) } - #define JUCE_CHECKED_RESULT(x) (logErrorMessage (x, __LINE__)) - - static int logErrorMessage (int err, int lineNum) - { - if (err < 0) - JUCE_ALSA_LOG ("Error: line " << lineNum << ": code " << err << " (" << snd_strerror (err) << ")"); - - return err; - } -#else - #define JUCE_ALSA_LOG(x) {} - #define JUCE_CHECKED_RESULT(x) (x) -#endif - -#define JUCE_ALSA_FAILED(x) failed (x) - -static void getDeviceSampleRates (snd_pcm_t* handle, Array& rates) -{ - const int ratesToTry[] = { 22050, 32000, 44100, 48000, 88200, 96000, 176400, 192000, 0 }; - - snd_pcm_hw_params_t* hwParams; - snd_pcm_hw_params_alloca (&hwParams); - - for (int i = 0; ratesToTry[i] != 0; ++i) - { - if (snd_pcm_hw_params_any (handle, hwParams) >= 0 - && snd_pcm_hw_params_test_rate (handle, hwParams, ratesToTry[i], 0) == 0) - { - rates.addIfNotAlreadyThere ((double) ratesToTry[i]); - } - } -} - -static void getDeviceNumChannels (snd_pcm_t* handle, unsigned int* minChans, unsigned int* maxChans) -{ - snd_pcm_hw_params_t *params; - snd_pcm_hw_params_alloca (¶ms); - - if (snd_pcm_hw_params_any (handle, params) >= 0) - { - snd_pcm_hw_params_get_channels_min (params, minChans); - snd_pcm_hw_params_get_channels_max (params, maxChans); - - JUCE_ALSA_LOG ("getDeviceNumChannels: " << (int) *minChans << " " << (int) *maxChans); - - // some virtual devices (dmix for example) report 10000 channels , we have to clamp these values - *maxChans = jmin (*maxChans, 32u); - *minChans = jmin (*minChans, *maxChans); - } - else - { - JUCE_ALSA_LOG ("getDeviceNumChannels failed"); - } -} - -static void getDeviceProperties (const String& deviceID, - unsigned int& minChansOut, - unsigned int& maxChansOut, - unsigned int& minChansIn, - unsigned int& maxChansIn, - Array& rates, - bool testOutput, - bool testInput) -{ - minChansOut = maxChansOut = minChansIn = maxChansIn = 0; - - if (deviceID.isEmpty()) - return; - - JUCE_ALSA_LOG ("getDeviceProperties(" << deviceID.toUTF8().getAddress() << ")"); - - snd_pcm_info_t* info; - snd_pcm_info_alloca (&info); - - if (testOutput) - { - snd_pcm_t* pcmHandle; - - if (JUCE_CHECKED_RESULT (snd_pcm_open (&pcmHandle, deviceID.toUTF8().getAddress(), SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK)) >= 0) - { - getDeviceNumChannels (pcmHandle, &minChansOut, &maxChansOut); - getDeviceSampleRates (pcmHandle, rates); - - snd_pcm_close (pcmHandle); - } - } - - if (testInput) - { - snd_pcm_t* pcmHandle; - - if (JUCE_CHECKED_RESULT (snd_pcm_open (&pcmHandle, deviceID.toUTF8(), SND_PCM_STREAM_CAPTURE, SND_PCM_NONBLOCK) >= 0)) - { - getDeviceNumChannels (pcmHandle, &minChansIn, &maxChansIn); - - if (rates.size() == 0) - getDeviceSampleRates (pcmHandle, rates); - - snd_pcm_close (pcmHandle); - } - } -} - -static void ensureMinimumNumBitsSet (BigInteger& chans, int minNumChans) -{ - int i = 0; - - while (chans.countNumberOfSetBits() < minNumChans) - chans.setBit (i++); -} - -static void silentErrorHandler (const char*, int, const char*, int, const char*,...) {} - -//============================================================================== -class ALSADevice -{ -public: - ALSADevice (const String& devID, bool forInput) - : handle (0), - bitDepth (16), - numChannelsRunning (0), - latency (0), - deviceID (devID), - isInput (forInput), - isInterleaved (true) - { - JUCE_ALSA_LOG ("snd_pcm_open (" << deviceID.toUTF8().getAddress() << ", forInput=" << forInput << ")"); - - int err = snd_pcm_open (&handle, deviceID.toUTF8(), - forInput ? SND_PCM_STREAM_CAPTURE : SND_PCM_STREAM_PLAYBACK, - SND_PCM_ASYNC); - if (err < 0) - { - if (-err == EBUSY) - error << "The device \"" << deviceID << "\" is busy (another application is using it)."; - else if (-err == ENOENT) - error << "The device \"" << deviceID << "\" is not available."; - else - error << "Could not open " << (forInput ? "input" : "output") << " device \"" << deviceID - << "\": " << snd_strerror(err) << " (" << err << ")"; - - JUCE_ALSA_LOG ("snd_pcm_open failed; " << error); - } - } - - ~ALSADevice() - { - closeNow(); - } - - void closeNow() - { - if (handle != 0) - { - snd_pcm_close (handle); - handle = 0; - } - } - - bool setParameters (unsigned int sampleRate, int numChannels, int bufferSize) - { - if (handle == 0) - return false; - - JUCE_ALSA_LOG ("ALSADevice::setParameters(" << deviceID << ", " - << (int) sampleRate << ", " << numChannels << ", " << bufferSize << ")"); - - snd_pcm_hw_params_t* hwParams; - snd_pcm_hw_params_alloca (&hwParams); - - if (snd_pcm_hw_params_any (handle, hwParams) < 0) - { - // this is the error message that aplay returns when an error happens here, - // it is a bit more explicit that "Invalid parameter" - error = "Broken configuration for this PCM: no configurations available"; - return false; - } - - if (snd_pcm_hw_params_set_access (handle, hwParams, SND_PCM_ACCESS_RW_INTERLEAVED) >= 0) // works better for plughw.. - isInterleaved = true; - else if (snd_pcm_hw_params_set_access (handle, hwParams, SND_PCM_ACCESS_RW_NONINTERLEAVED) >= 0) - isInterleaved = false; - else - { - jassertfalse; - return false; - } - - enum { isFloatBit = 1 << 16, isLittleEndianBit = 1 << 17, onlyUseLower24Bits = 1 << 18 }; - - const int formatsToTry[] = { SND_PCM_FORMAT_FLOAT_LE, 32 | isFloatBit | isLittleEndianBit, - SND_PCM_FORMAT_FLOAT_BE, 32 | isFloatBit, - SND_PCM_FORMAT_S32_LE, 32 | isLittleEndianBit, - SND_PCM_FORMAT_S32_BE, 32, - SND_PCM_FORMAT_S24_3LE, 24 | isLittleEndianBit, - SND_PCM_FORMAT_S24_3BE, 24, - SND_PCM_FORMAT_S24_LE, 32 | isLittleEndianBit | onlyUseLower24Bits, - SND_PCM_FORMAT_S16_LE, 16 | isLittleEndianBit, - SND_PCM_FORMAT_S16_BE, 16 }; - bitDepth = 0; - - for (int i = 0; i < numElementsInArray (formatsToTry); i += 2) - { - if (snd_pcm_hw_params_set_format (handle, hwParams, (_snd_pcm_format) formatsToTry [i]) >= 0) - { - const int type = formatsToTry [i + 1]; - bitDepth = type & 255; - - converter = createConverter (isInput, bitDepth, - (type & isFloatBit) != 0, - (type & isLittleEndianBit) != 0, - (type & onlyUseLower24Bits) != 0, - numChannels); - break; - } - } - - if (bitDepth == 0) - { - error = "device doesn't support a compatible PCM format"; - JUCE_ALSA_LOG ("Error: " + error); - return false; - } - - int dir = 0; - unsigned int periods = 4; - snd_pcm_uframes_t samplesPerPeriod = bufferSize; - - if (JUCE_ALSA_FAILED (snd_pcm_hw_params_set_rate_near (handle, hwParams, &sampleRate, 0)) - || JUCE_ALSA_FAILED (snd_pcm_hw_params_set_channels (handle, hwParams, numChannels)) - || JUCE_ALSA_FAILED (snd_pcm_hw_params_set_periods_near (handle, hwParams, &periods, &dir)) - || JUCE_ALSA_FAILED (snd_pcm_hw_params_set_period_size_near (handle, hwParams, &samplesPerPeriod, &dir)) - || JUCE_ALSA_FAILED (snd_pcm_hw_params (handle, hwParams))) - { - return false; - } - - snd_pcm_uframes_t frames = 0; - - if (JUCE_ALSA_FAILED (snd_pcm_hw_params_get_period_size (hwParams, &frames, &dir)) - || JUCE_ALSA_FAILED (snd_pcm_hw_params_get_periods (hwParams, &periods, &dir))) - latency = 0; - else - latency = frames * (periods - 1); // (this is the method JACK uses to guess the latency..) - - JUCE_ALSA_LOG ("frames: " << (int) frames << ", periods: " << (int) periods - << ", samplesPerPeriod: " << (int) samplesPerPeriod); - - snd_pcm_sw_params_t* swParams; - snd_pcm_sw_params_alloca (&swParams); - snd_pcm_uframes_t boundary; - - if (JUCE_ALSA_FAILED (snd_pcm_sw_params_current (handle, swParams)) - || JUCE_ALSA_FAILED (snd_pcm_sw_params_get_boundary (swParams, &boundary)) - || JUCE_ALSA_FAILED (snd_pcm_sw_params_set_silence_threshold (handle, swParams, 0)) - || JUCE_ALSA_FAILED (snd_pcm_sw_params_set_silence_size (handle, swParams, boundary)) - || JUCE_ALSA_FAILED (snd_pcm_sw_params_set_start_threshold (handle, swParams, samplesPerPeriod)) - || JUCE_ALSA_FAILED (snd_pcm_sw_params_set_stop_threshold (handle, swParams, boundary)) - || JUCE_ALSA_FAILED (snd_pcm_sw_params (handle, swParams))) - { - return false; - } - - #if JUCE_ALSA_LOGGING - // enable this to dump the config of the devices that get opened - snd_output_t* out; - snd_output_stdio_attach (&out, stderr, 0); - snd_pcm_hw_params_dump (hwParams, out); - snd_pcm_sw_params_dump (swParams, out); - #endif - - numChannelsRunning = numChannels; - - return true; - } - - //============================================================================== - bool writeToOutputDevice (AudioSampleBuffer& outputChannelBuffer, const int numSamples) - { - jassert (numChannelsRunning <= outputChannelBuffer.getNumChannels()); - float* const* const data = outputChannelBuffer.getArrayOfWritePointers(); - snd_pcm_sframes_t numDone = 0; - - if (isInterleaved) - { - scratch.ensureSize (sizeof (float) * numSamples * numChannelsRunning, false); - - for (int i = 0; i < numChannelsRunning; ++i) - converter->convertSamples (scratch.getData(), i, data[i], 0, numSamples); - - numDone = snd_pcm_writei (handle, scratch.getData(), numSamples); - } - else - { - for (int i = 0; i < numChannelsRunning; ++i) - converter->convertSamples (data[i], data[i], numSamples); - - numDone = snd_pcm_writen (handle, (void**) data, numSamples); - } - - if (numDone < 0 && JUCE_ALSA_FAILED (snd_pcm_recover (handle, numDone, 1 /* silent */))) - return false; - - if (numDone < numSamples) - JUCE_ALSA_LOG ("Did not write all samples: numDone: " << numDone << ", numSamples: " << numSamples); - - return true; - } - - bool readFromInputDevice (AudioSampleBuffer& inputChannelBuffer, const int numSamples) - { - jassert (numChannelsRunning <= inputChannelBuffer.getNumChannels()); - float* const* const data = inputChannelBuffer.getArrayOfWritePointers(); - - if (isInterleaved) - { - scratch.ensureSize (sizeof (float) * numSamples * numChannelsRunning, false); - scratch.fillWith (0); // (not clearing this data causes warnings in valgrind) - - snd_pcm_sframes_t num = snd_pcm_readi (handle, scratch.getData(), numSamples); - - if (num < 0 && JUCE_ALSA_FAILED (snd_pcm_recover (handle, num, 1 /* silent */))) - return false; - - if (num < numSamples) - JUCE_ALSA_LOG ("Did not read all samples: num: " << num << ", numSamples: " << numSamples); - - for (int i = 0; i < numChannelsRunning; ++i) - converter->convertSamples (data[i], 0, scratch.getData(), i, numSamples); - } - else - { - snd_pcm_sframes_t num = snd_pcm_readn (handle, (void**) data, numSamples); - - if (num < 0 && JUCE_ALSA_FAILED (snd_pcm_recover (handle, num, 1 /* silent */))) - return false; - - if (num < numSamples) - JUCE_ALSA_LOG ("Did not read all samples: num: " << num << ", numSamples: " << numSamples); - - for (int i = 0; i < numChannelsRunning; ++i) - converter->convertSamples (data[i], data[i], numSamples); - } - - return true; - } - - //============================================================================== - snd_pcm_t* handle; - String error; - int bitDepth, numChannelsRunning, latency; - -private: - //============================================================================== - String deviceID; - const bool isInput; - bool isInterleaved; - MemoryBlock scratch; - ScopedPointer converter; - - //============================================================================== - template - struct ConverterHelper - { - static AudioData::Converter* createConverter (const bool forInput, const bool isLittleEndian, const int numInterleavedChannels) - { - if (forInput) - { - typedef AudioData::Pointer DestType; - - if (isLittleEndian) - return new AudioData::ConverterInstance , DestType> (numInterleavedChannels, 1); - - return new AudioData::ConverterInstance , DestType> (numInterleavedChannels, 1); - } - - typedef AudioData::Pointer SourceType; - - if (isLittleEndian) - return new AudioData::ConverterInstance > (1, numInterleavedChannels); - - return new AudioData::ConverterInstance > (1, numInterleavedChannels); - } - }; - - static AudioData::Converter* createConverter (bool forInput, int bitDepth, - bool isFloat, bool isLittleEndian, bool useOnlyLower24Bits, - int numInterleavedChannels) - { - JUCE_ALSA_LOG ("format: bitDepth=" << bitDepth << ", isFloat=" << isFloat - << ", isLittleEndian=" << isLittleEndian << ", numChannels=" << numInterleavedChannels); - - if (isFloat) return ConverterHelper ::createConverter (forInput, isLittleEndian, numInterleavedChannels); - if (bitDepth == 16) return ConverterHelper ::createConverter (forInput, isLittleEndian, numInterleavedChannels); - if (bitDepth == 24) return ConverterHelper ::createConverter (forInput, isLittleEndian, numInterleavedChannels); - - jassert (bitDepth == 32); - - if (useOnlyLower24Bits) - return ConverterHelper ::createConverter (forInput, isLittleEndian, numInterleavedChannels); - - return ConverterHelper ::createConverter (forInput, isLittleEndian, numInterleavedChannels); - } - - //============================================================================== - bool failed (const int errorNum) - { - if (errorNum >= 0) - return false; - - error = snd_strerror (errorNum); - JUCE_ALSA_LOG ("ALSA error: " << error); - return true; - } - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ALSADevice) -}; - -//============================================================================== -class ALSAThread : public Thread -{ -public: - ALSAThread (const String& inputDeviceID, const String& outputDeviceID) - : Thread ("Juce ALSA"), - sampleRate (0), - bufferSize (0), - outputLatency (0), - inputLatency (0), - callback (0), - inputId (inputDeviceID), - outputId (outputDeviceID), - numCallbacks (0), - audioIoInProgress (false), - inputChannelBuffer (1, 1), - outputChannelBuffer (1, 1) - { - initialiseRatesAndChannels(); - } - - ~ALSAThread() - { - close(); - } - - void open (BigInteger inputChannels, - BigInteger outputChannels, - const double newSampleRate, - const int newBufferSize) - { - close(); - - error.clear(); - sampleRate = newSampleRate; - bufferSize = newBufferSize; - - inputChannelBuffer.setSize (jmax ((int) minChansIn, inputChannels.getHighestBit()) + 1, bufferSize); - inputChannelBuffer.clear(); - inputChannelDataForCallback.clear(); - currentInputChans.clear(); - - if (inputChannels.getHighestBit() >= 0) - { - for (int i = 0; i <= jmax (inputChannels.getHighestBit(), (int) minChansIn); ++i) - { - if (inputChannels[i]) - { - inputChannelDataForCallback.add (inputChannelBuffer.getReadPointer (i)); - currentInputChans.setBit (i); - } - } - } - - ensureMinimumNumBitsSet (outputChannels, minChansOut); - - outputChannelBuffer.setSize (jmax ((int) minChansOut, outputChannels.getHighestBit()) + 1, bufferSize); - outputChannelBuffer.clear(); - outputChannelDataForCallback.clear(); - currentOutputChans.clear(); - - if (outputChannels.getHighestBit() >= 0) - { - for (int i = 0; i <= jmax (outputChannels.getHighestBit(), (int) minChansOut); ++i) - { - if (outputChannels[i]) - { - outputChannelDataForCallback.add (outputChannelBuffer.getWritePointer (i)); - currentOutputChans.setBit (i); - } - } - } - - if (outputChannelDataForCallback.size() > 0 && outputId.isNotEmpty()) - { - outputDevice = new ALSADevice (outputId, false); - - if (outputDevice->error.isNotEmpty()) - { - error = outputDevice->error; - outputDevice = nullptr; - return; - } - - if (! outputDevice->setParameters ((unsigned int) sampleRate, - jlimit ((int) minChansOut, (int) maxChansOut, - currentOutputChans.getHighestBit() + 1), - bufferSize)) - { - error = outputDevice->error; - outputDevice = nullptr; - return; - } - - outputLatency = outputDevice->latency; - } - - if (inputChannelDataForCallback.size() > 0 && inputId.isNotEmpty()) - { - inputDevice = new ALSADevice (inputId, true); - - if (inputDevice->error.isNotEmpty()) - { - error = inputDevice->error; - inputDevice = nullptr; - return; - } - - ensureMinimumNumBitsSet (currentInputChans, minChansIn); - - if (! inputDevice->setParameters ((unsigned int) sampleRate, - jlimit ((int) minChansIn, (int) maxChansIn, currentInputChans.getHighestBit() + 1), - bufferSize)) - { - error = inputDevice->error; - inputDevice = nullptr; - return; - } - - inputLatency = inputDevice->latency; - } - - if (outputDevice == nullptr && inputDevice == nullptr) - { - error = "no channels"; - return; - } - - if (outputDevice != nullptr && inputDevice != nullptr) - snd_pcm_link (outputDevice->handle, inputDevice->handle); - - if (inputDevice != nullptr && JUCE_ALSA_FAILED (snd_pcm_prepare (inputDevice->handle))) - return; - - if (outputDevice != nullptr && JUCE_ALSA_FAILED (snd_pcm_prepare (outputDevice->handle))) - return; - - startThread (9); - - int count = 1000; - - while (numCallbacks == 0) - { - sleep (5); - - if (--count < 0 || ! isThreadRunning()) - { - error = "device didn't start"; - break; - } - } - } - - void close() - { - if (isThreadRunning()) - { - // problem: when pulseaudio is suspended (with pasuspend) , the ALSAThread::run is just stuck in - // snd_pcm_writei -- no error, no nothing it just stays stuck. So the only way I found to exit "nicely" - // (that is without the "killing thread by force" of stopThread) , is to just call snd_pcm_close from - // here which will cause the thread to resume, and exit - signalThreadShouldExit(); - - const int callbacksToStop = numCallbacks; - - if ((! waitForThreadToExit (400)) && audioIoInProgress && numCallbacks == callbacksToStop) - { - JUCE_ALSA_LOG ("Thread is stuck in i/o.. Is pulseaudio suspended?"); - - if (outputDevice != nullptr) outputDevice->closeNow(); - if (inputDevice != nullptr) inputDevice->closeNow(); - } - } - - stopThread (6000); - - inputDevice = nullptr; - outputDevice = nullptr; - - inputChannelBuffer.setSize (1, 1); - outputChannelBuffer.setSize (1, 1); - - numCallbacks = 0; - } - - void setCallback (AudioIODeviceCallback* const newCallback) noexcept - { - const ScopedLock sl (callbackLock); - callback = newCallback; - } - - void run() override - { - while (! threadShouldExit()) - { - if (inputDevice != nullptr && inputDevice->handle) - { - audioIoInProgress = true; - - if (! inputDevice->readFromInputDevice (inputChannelBuffer, bufferSize)) - { - JUCE_ALSA_LOG ("Read failure"); - break; - } - - audioIoInProgress = false; - } - - if (threadShouldExit()) - break; - - { - const ScopedLock sl (callbackLock); - ++numCallbacks; - - if (callback != nullptr) - { - callback->audioDeviceIOCallback (inputChannelDataForCallback.getRawDataPointer(), - inputChannelDataForCallback.size(), - outputChannelDataForCallback.getRawDataPointer(), - outputChannelDataForCallback.size(), - bufferSize); - } - else - { - for (int i = 0; i < outputChannelDataForCallback.size(); ++i) - zeromem (outputChannelDataForCallback[i], sizeof (float) * bufferSize); - } - } - - if (outputDevice != nullptr && outputDevice->handle) - { - JUCE_ALSA_FAILED (snd_pcm_wait (outputDevice->handle, 2000)); - - if (threadShouldExit()) - break; - - snd_pcm_sframes_t avail = snd_pcm_avail_update (outputDevice->handle); - - if (avail < 0) - JUCE_ALSA_FAILED (snd_pcm_recover (outputDevice->handle, avail, 0)); - - audioIoInProgress = true; - - if (! outputDevice->writeToOutputDevice (outputChannelBuffer, bufferSize)) - { - JUCE_ALSA_LOG ("write failure"); - break; - } - - audioIoInProgress = false; - } - } - audioIoInProgress = false; - } - - int getBitDepth() const noexcept - { - if (outputDevice != nullptr) - return outputDevice->bitDepth; - - if (inputDevice != nullptr) - return inputDevice->bitDepth; - - return 16; - } - - //============================================================================== - String error; - double sampleRate; - int bufferSize, outputLatency, inputLatency; - BigInteger currentInputChans, currentOutputChans; - - Array sampleRates; - StringArray channelNamesOut, channelNamesIn; - AudioIODeviceCallback* callback; - -private: - //============================================================================== - const String inputId, outputId; - ScopedPointer outputDevice, inputDevice; - int numCallbacks; - bool audioIoInProgress; - - CriticalSection callbackLock; - - AudioSampleBuffer inputChannelBuffer, outputChannelBuffer; - Array inputChannelDataForCallback; - Array outputChannelDataForCallback; - - unsigned int minChansOut, maxChansOut; - unsigned int minChansIn, maxChansIn; - - bool failed (const int errorNum) - { - if (errorNum >= 0) - return false; - - error = snd_strerror (errorNum); - JUCE_ALSA_LOG ("ALSA error: " << error); - return true; - } - - void initialiseRatesAndChannels() - { - sampleRates.clear(); - channelNamesOut.clear(); - channelNamesIn.clear(); - minChansOut = 0; - maxChansOut = 0; - minChansIn = 0; - maxChansIn = 0; - unsigned int dummy = 0; - - getDeviceProperties (inputId, dummy, dummy, minChansIn, maxChansIn, sampleRates, false, true); - getDeviceProperties (outputId, minChansOut, maxChansOut, dummy, dummy, sampleRates, true, false); - - for (unsigned int i = 0; i < maxChansOut; ++i) - channelNamesOut.add ("channel " + String ((int) i + 1)); - - for (unsigned int i = 0; i < maxChansIn; ++i) - channelNamesIn.add ("channel " + String ((int) i + 1)); - } - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ALSAThread) -}; - - -//============================================================================== -class ALSAAudioIODevice : public AudioIODevice -{ -public: - ALSAAudioIODevice (const String& deviceName, - const String& typeName, - const String& inputDeviceID, - const String& outputDeviceID) - : AudioIODevice (deviceName, typeName), - inputId (inputDeviceID), - outputId (outputDeviceID), - isOpen_ (false), - isStarted (false), - internal (inputDeviceID, outputDeviceID) - { - } - - ~ALSAAudioIODevice() - { - close(); - } - - StringArray getOutputChannelNames() override { return internal.channelNamesOut; } - StringArray getInputChannelNames() override { return internal.channelNamesIn; } - - Array getAvailableSampleRates() override { return internal.sampleRates; } - - Array getAvailableBufferSizes() override - { - Array r; - int n = 16; - - for (int i = 0; i < 50; ++i) - { - r.add (n); - n += n < 64 ? 16 - : (n < 512 ? 32 - : (n < 1024 ? 64 - : (n < 2048 ? 128 : 256))); - } - - return r; - } - - int getDefaultBufferSize() override { return 512; } - - String open (const BigInteger& inputChannels, - const BigInteger& outputChannels, - double sampleRate, - int bufferSizeSamples) override - { - close(); - - if (bufferSizeSamples <= 0) - bufferSizeSamples = getDefaultBufferSize(); - - if (sampleRate <= 0) - { - for (int i = 0; i < internal.sampleRates.size(); ++i) - { - double rate = internal.sampleRates[i]; - - if (rate >= 44100) - { - sampleRate = rate; - break; - } - } - } - - internal.open (inputChannels, outputChannels, - sampleRate, bufferSizeSamples); - - isOpen_ = internal.error.isEmpty(); - return internal.error; - } - - void close() override - { - stop(); - internal.close(); - isOpen_ = false; - } - - bool isOpen() override { return isOpen_; } - bool isPlaying() override { return isStarted && internal.error.isEmpty(); } - String getLastError() override { return internal.error; } - - int getCurrentBufferSizeSamples() override { return internal.bufferSize; } - double getCurrentSampleRate() override { return internal.sampleRate; } - int getCurrentBitDepth() override { return internal.getBitDepth(); } - - BigInteger getActiveOutputChannels() const override { return internal.currentOutputChans; } - BigInteger getActiveInputChannels() const override { return internal.currentInputChans; } - - int getOutputLatencyInSamples() override { return internal.outputLatency; } - int getInputLatencyInSamples() override { return internal.inputLatency; } - - void start (AudioIODeviceCallback* callback) override - { - if (! isOpen_) - callback = nullptr; - - if (callback != nullptr) - callback->audioDeviceAboutToStart (this); - - internal.setCallback (callback); - - isStarted = (callback != nullptr); - } - - void stop() override - { - AudioIODeviceCallback* const oldCallback = internal.callback; - - start (nullptr); - - if (oldCallback != nullptr) - oldCallback->audioDeviceStopped(); - } - - String inputId, outputId; - -private: - bool isOpen_, isStarted; - ALSAThread internal; -}; - - -//============================================================================== -class ALSAAudioIODeviceType : public AudioIODeviceType -{ -public: - ALSAAudioIODeviceType (bool onlySoundcards, const String &typeName) - : AudioIODeviceType (typeName), - hasScanned (false), - listOnlySoundcards (onlySoundcards) - { - #if ! JUCE_ALSA_LOGGING - snd_lib_error_set_handler (&silentErrorHandler); - #endif - } - - ~ALSAAudioIODeviceType() - { - #if ! JUCE_ALSA_LOGGING - snd_lib_error_set_handler (nullptr); - #endif - - snd_config_update_free_global(); // prevent valgrind from screaming about alsa leaks - } - - //============================================================================== - void scanForDevices() - { - if (hasScanned) - return; - - hasScanned = true; - inputNames.clear(); - inputIds.clear(); - outputNames.clear(); - outputIds.clear(); - - JUCE_ALSA_LOG ("scanForDevices()"); - - if (listOnlySoundcards) - enumerateAlsaSoundcards(); - else - enumerateAlsaPCMDevices(); - - inputNames.appendNumbersToDuplicates (false, true); - outputNames.appendNumbersToDuplicates (false, true); - } - - StringArray getDeviceNames (bool wantInputNames) const - { - jassert (hasScanned); // need to call scanForDevices() before doing this - - return wantInputNames ? inputNames : outputNames; - } - - int getDefaultDeviceIndex (bool forInput) const - { - jassert (hasScanned); // need to call scanForDevices() before doing this - - const int idx = (forInput ? inputIds : outputIds).indexOf ("default"); - return idx >= 0 ? idx : 0; - } - - bool hasSeparateInputsAndOutputs() const { return true; } - - int getIndexOfDevice (AudioIODevice* device, bool asInput) const - { - jassert (hasScanned); // need to call scanForDevices() before doing this - - if (ALSAAudioIODevice* d = dynamic_cast (device)) - return asInput ? inputIds.indexOf (d->inputId) - : outputIds.indexOf (d->outputId); - - return -1; - } - - AudioIODevice* createDevice (const String& outputDeviceName, - const String& inputDeviceName) - { - jassert (hasScanned); // need to call scanForDevices() before doing this - - const int inputIndex = inputNames.indexOf (inputDeviceName); - const int outputIndex = outputNames.indexOf (outputDeviceName); - - String deviceName (outputIndex >= 0 ? outputDeviceName - : inputDeviceName); - - if (inputIndex >= 0 || outputIndex >= 0) - return new ALSAAudioIODevice (deviceName, getTypeName(), - inputIds [inputIndex], - outputIds [outputIndex]); - - return nullptr; - } - -private: - //============================================================================== - StringArray inputNames, outputNames, inputIds, outputIds; - bool hasScanned, listOnlySoundcards; - - bool testDevice (const String &id, const String &outputName, const String &inputName) - { - unsigned int minChansOut = 0, maxChansOut = 0; - unsigned int minChansIn = 0, maxChansIn = 0; - Array rates; - - bool isInput = inputName.isNotEmpty(), isOutput = outputName.isNotEmpty(); - getDeviceProperties (id, minChansOut, maxChansOut, minChansIn, maxChansIn, rates, isOutput, isInput); - - isInput = maxChansIn > 0; - isOutput = maxChansOut > 0; - - if ((isInput || isOutput) && rates.size() > 0) - { - JUCE_ALSA_LOG ("testDevice: '" << id.toUTF8().getAddress() << "' -> isInput: " - << isInput << ", isOutput: " << isOutput); - - if (isInput) - { - inputNames.add (inputName); - inputIds.add (id); - } - - if (isOutput) - { - outputNames.add (outputName); - outputIds.add (id); - } - - return isInput || isOutput; - } - - return false; - } - - void enumerateAlsaSoundcards() - { - snd_ctl_t* handle = nullptr; - snd_ctl_card_info_t* info = nullptr; - snd_ctl_card_info_alloca (&info); - - int cardNum = -1; - - while (outputIds.size() + inputIds.size() <= 64) - { - snd_card_next (&cardNum); - - if (cardNum < 0) - break; - - if (JUCE_CHECKED_RESULT (snd_ctl_open (&handle, ("hw:" + String (cardNum)).toUTF8(), SND_CTL_NONBLOCK)) >= 0) - { - if (JUCE_CHECKED_RESULT (snd_ctl_card_info (handle, info)) >= 0) - { - String cardId (snd_ctl_card_info_get_id (info)); - - if (cardId.removeCharacters ("0123456789").isEmpty()) - cardId = String (cardNum); - - String cardName = snd_ctl_card_info_get_name (info); - - if (cardName.isEmpty()) - cardName = cardId; - - int device = -1; - - snd_pcm_info_t* pcmInfo; - snd_pcm_info_alloca (&pcmInfo); - - for (;;) - { - if (snd_ctl_pcm_next_device (handle, &device) < 0 || device < 0) - break; - - snd_pcm_info_set_device (pcmInfo, device); - - for (int subDevice = 0, nbSubDevice = 1; subDevice < nbSubDevice; ++subDevice) - { - snd_pcm_info_set_subdevice (pcmInfo, subDevice); - snd_pcm_info_set_stream (pcmInfo, SND_PCM_STREAM_CAPTURE); - const bool isInput = (snd_ctl_pcm_info (handle, pcmInfo) >= 0); - - snd_pcm_info_set_stream (pcmInfo, SND_PCM_STREAM_PLAYBACK); - const bool isOutput = (snd_ctl_pcm_info (handle, pcmInfo) >= 0); - - if (! (isInput || isOutput)) - continue; - - if (nbSubDevice == 1) - nbSubDevice = snd_pcm_info_get_subdevices_count (pcmInfo); - - String id, name; - - if (nbSubDevice == 1) - { - id << "hw:" << cardId << "," << device; - name << cardName << ", " << snd_pcm_info_get_name (pcmInfo); - } - else - { - id << "hw:" << cardId << "," << device << "," << subDevice; - name << cardName << ", " << snd_pcm_info_get_name (pcmInfo) - << " {" << snd_pcm_info_get_subdevice_name (pcmInfo) << "}"; - } - - JUCE_ALSA_LOG ("Soundcard ID: " << id << ", name: '" << name - << ", isInput:" << isInput << ", isOutput:" << isOutput << "\n"); - - if (isInput) - { - inputNames.add (name); - inputIds.add (id); - } - - if (isOutput) - { - outputNames.add (name); - outputIds.add (id); - } - } - } - } - - JUCE_CHECKED_RESULT (snd_ctl_close (handle)); - } - } - } - - /* Enumerates all ALSA output devices (as output by the command aplay -L) - Does not try to open the devices (with "testDevice" for example), - so that it also finds devices that are busy and not yet available. - */ - void enumerateAlsaPCMDevices() - { - void** hints = nullptr; - - if (JUCE_CHECKED_RESULT (snd_device_name_hint (-1, "pcm", &hints)) == 0) - { - for (char** h = (char**) hints; *h; ++h) - { - const String id (hintToString (*h, "NAME")); - const String description (hintToString (*h, "DESC")); - const String ioid (hintToString (*h, "IOID")); - - JUCE_ALSA_LOG ("ID: " << id << "; desc: " << description << "; ioid: " << ioid); - - String ss = id.fromFirstOccurrenceOf ("=", false, false) - .upToFirstOccurrenceOf (",", false, false); - - if (id.isEmpty() - || id.startsWith ("default:") || id.startsWith ("sysdefault:") - || id.startsWith ("plughw:") || id == "null") - continue; - - String name (description.replace ("\n", "; ")); - - if (name.isEmpty()) - name = id; - - bool isOutput = (ioid != "Input"); - bool isInput = (ioid != "Output"); - - // alsa is stupid here, it advertises dmix and dsnoop as input/output devices, but - // opening dmix as input, or dsnoop as output will trigger errors.. - isInput = isInput && ! id.startsWith ("dmix"); - isOutput = isOutput && ! id.startsWith ("dsnoop"); - - if (isInput) - { - inputNames.add (name); - inputIds.add (id); - } - - if (isOutput) - { - outputNames.add (name); - outputIds.add (id); - } - } - - snd_device_name_free_hint (hints); - } - - // sometimes the "default" device is not listed, but it is nice to see it explicitely in the list - if (! outputIds.contains ("default")) - testDevice ("default", "Default ALSA Output", "Default ALSA Input"); - - // same for the pulseaudio plugin - if (! outputIds.contains ("pulse")) - testDevice ("pulse", "Pulseaudio output", "Pulseaudio input"); - - // make sure the default device is listed first, and followed by the pulse device (if present) - int idx = outputIds.indexOf ("pulse"); - outputIds.move (idx, 0); - outputNames.move (idx, 0); - - idx = inputIds.indexOf ("pulse"); - inputIds.move (idx, 0); - inputNames.move (idx, 0); - - idx = outputIds.indexOf ("default"); - outputIds.move (idx, 0); - outputNames.move (idx, 0); - - idx = inputIds.indexOf ("default"); - inputIds.move (idx, 0); - inputNames.move (idx, 0); - } - - static String hintToString (const void* hints, const char* type) - { - char* const hint = snd_device_name_get_hint (hints, type); - const String s (String::fromUTF8 (hint)); - ::free (hint); - return s; - } - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ALSAAudioIODeviceType) -}; - -} - -//============================================================================== -AudioIODeviceType* createAudioIODeviceType_ALSA_Soundcards() -{ - return new ALSAAudioIODeviceType (true, "ALSA HW"); -} - -AudioIODeviceType* createAudioIODeviceType_ALSA_PCMDevices() -{ - return new ALSAAudioIODeviceType (false, "ALSA"); -} - -AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_ALSA() -{ - return createAudioIODeviceType_ALSA_PCMDevices(); -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/native/juce_linux_AudioCDReader.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/native/juce_linux_AudioCDReader.cpp deleted file mode 100644 index a645333010..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/native/juce_linux_AudioCDReader.cpp +++ /dev/null @@ -1,77 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -AudioCDReader::AudioCDReader() - : AudioFormatReader (0, "CD Audio") -{ -} - -StringArray AudioCDReader::getAvailableCDNames() -{ - StringArray names; - return names; -} - -AudioCDReader* AudioCDReader::createReaderForCD (const int index) -{ - return nullptr; -} - -AudioCDReader::~AudioCDReader() -{ -} - -void AudioCDReader::refreshTrackLengths() -{ -} - -bool AudioCDReader::readSamples (int** destSamples, int numDestChannels, int startOffsetInDestBuffer, - int64 startSampleInFile, int numSamples) -{ - return false; -} - -bool AudioCDReader::isCDStillPresent() const -{ - return false; -} - -bool AudioCDReader::isTrackAudio (int trackNum) const -{ - return false; -} - -void AudioCDReader::enableIndexScanning (bool b) -{ -} - -int AudioCDReader::getLastIndex() const -{ - return 0; -} - -Array AudioCDReader::findIndexesInTrack (const int trackNumber) -{ - return Array(); -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/native/juce_linux_JackAudio.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/native/juce_linux_JackAudio.cpp deleted file mode 100644 index 38ad64df93..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/native/juce_linux_JackAudio.cpp +++ /dev/null @@ -1,604 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -//============================================================================== -static void* juce_libjackHandle = nullptr; - -static void* juce_loadJackFunction (const char* const name) -{ - if (juce_libjackHandle == nullptr) - return nullptr; - - return dlsym (juce_libjackHandle, name); -} - -#define JUCE_DECL_JACK_FUNCTION(return_type, fn_name, argument_types, arguments) \ - return_type fn_name argument_types \ - { \ - typedef return_type (*fn_type) argument_types; \ - static fn_type fn = (fn_type) juce_loadJackFunction (#fn_name); \ - return (fn != nullptr) ? ((*fn) arguments) : (return_type) 0; \ - } - -#define JUCE_DECL_VOID_JACK_FUNCTION(fn_name, argument_types, arguments) \ - void fn_name argument_types \ - { \ - typedef void (*fn_type) argument_types; \ - static fn_type fn = (fn_type) juce_loadJackFunction (#fn_name); \ - if (fn != nullptr) (*fn) arguments; \ - } - -//============================================================================== -JUCE_DECL_JACK_FUNCTION (jack_client_t*, jack_client_open, (const char* client_name, jack_options_t options, jack_status_t* status, ...), (client_name, options, status)); -JUCE_DECL_JACK_FUNCTION (int, jack_client_close, (jack_client_t *client), (client)); -JUCE_DECL_JACK_FUNCTION (int, jack_activate, (jack_client_t* client), (client)); -JUCE_DECL_JACK_FUNCTION (int, jack_deactivate, (jack_client_t* client), (client)); -JUCE_DECL_JACK_FUNCTION (jack_nframes_t, jack_get_buffer_size, (jack_client_t* client), (client)); -JUCE_DECL_JACK_FUNCTION (jack_nframes_t, jack_get_sample_rate, (jack_client_t* client), (client)); -JUCE_DECL_VOID_JACK_FUNCTION (jack_on_shutdown, (jack_client_t* client, void (*function)(void* arg), void* arg), (client, function, arg)); -JUCE_DECL_JACK_FUNCTION (void* , jack_port_get_buffer, (jack_port_t* port, jack_nframes_t nframes), (port, nframes)); -JUCE_DECL_JACK_FUNCTION (jack_nframes_t, jack_port_get_total_latency, (jack_client_t* client, jack_port_t* port), (client, port)); -JUCE_DECL_JACK_FUNCTION (jack_port_t* , jack_port_register, (jack_client_t* client, const char* port_name, const char* port_type, unsigned long flags, unsigned long buffer_size), (client, port_name, port_type, flags, buffer_size)); -JUCE_DECL_VOID_JACK_FUNCTION (jack_set_error_function, (void (*func)(const char*)), (func)); -JUCE_DECL_JACK_FUNCTION (int, jack_set_process_callback, (jack_client_t* client, JackProcessCallback process_callback, void* arg), (client, process_callback, arg)); -JUCE_DECL_JACK_FUNCTION (const char**, jack_get_ports, (jack_client_t* client, const char* port_name_pattern, const char* type_name_pattern, unsigned long flags), (client, port_name_pattern, type_name_pattern, flags)); -JUCE_DECL_JACK_FUNCTION (int, jack_connect, (jack_client_t* client, const char* source_port, const char* destination_port), (client, source_port, destination_port)); -JUCE_DECL_JACK_FUNCTION (const char*, jack_port_name, (const jack_port_t* port), (port)); -JUCE_DECL_JACK_FUNCTION (void*, jack_set_port_connect_callback, (jack_client_t* client, JackPortConnectCallback connect_callback, void* arg), (client, connect_callback, arg)); -JUCE_DECL_JACK_FUNCTION (jack_port_t* , jack_port_by_id, (jack_client_t* client, jack_port_id_t port_id), (client, port_id)); -JUCE_DECL_JACK_FUNCTION (int, jack_port_connected, (const jack_port_t* port), (port)); -JUCE_DECL_JACK_FUNCTION (int, jack_port_connected_to, (const jack_port_t* port, const char* port_name), (port, port_name)); - -#if JUCE_DEBUG - #define JACK_LOGGING_ENABLED 1 -#endif - -#if JACK_LOGGING_ENABLED -namespace -{ - void jack_Log (const String& s) - { - std::cerr << s << std::endl; - } - - const char* getJackErrorMessage (const jack_status_t status) - { - if (status & JackServerFailed - || status & JackServerError) return "Unable to connect to JACK server"; - if (status & JackVersionError) return "Client's protocol version does not match"; - if (status & JackInvalidOption) return "The operation contained an invalid or unsupported option"; - if (status & JackNameNotUnique) return "The desired client name was not unique"; - if (status & JackNoSuchClient) return "Requested client does not exist"; - if (status & JackInitFailure) return "Unable to initialize client"; - return nullptr; - } -} - #define JUCE_JACK_LOG_STATUS(x) { if (const char* m = getJackErrorMessage (x)) jack_Log (m); } - #define JUCE_JACK_LOG(x) jack_Log(x) -#else - #define JUCE_JACK_LOG_STATUS(x) {} - #define JUCE_JACK_LOG(x) {} -#endif - - -//============================================================================== -#ifndef JUCE_JACK_CLIENT_NAME - #define JUCE_JACK_CLIENT_NAME "JUCEJack" -#endif - -struct JackPortIterator -{ - JackPortIterator (jack_client_t* const client, const bool forInput) - : ports (nullptr), index (-1) - { - if (client != nullptr) - ports = juce::jack_get_ports (client, nullptr, nullptr, - forInput ? JackPortIsOutput : JackPortIsInput); - // (NB: This looks like it's the wrong way round, but it is correct!) - } - - ~JackPortIterator() - { - ::free (ports); - } - - bool next() - { - if (ports == nullptr || ports [index + 1] == nullptr) - return false; - - name = CharPointer_UTF8 (ports[++index]); - clientName = name.upToFirstOccurrenceOf (":", false, false); - return true; - } - - const char** ports; - int index; - String name; - String clientName; -}; - -class JackAudioIODeviceType; -static Array activeDeviceTypes; - -//============================================================================== -class JackAudioIODevice : public AudioIODevice -{ -public: - JackAudioIODevice (const String& deviceName, - const String& inId, - const String& outId) - : AudioIODevice (deviceName, "JACK"), - inputId (inId), - outputId (outId), - deviceIsOpen (false), - callback (nullptr), - totalNumberOfInputChannels (0), - totalNumberOfOutputChannels (0) - { - jassert (deviceName.isNotEmpty()); - - jack_status_t status; - client = juce::jack_client_open (JUCE_JACK_CLIENT_NAME, JackNoStartServer, &status); - - if (client == nullptr) - { - JUCE_JACK_LOG_STATUS (status); - } - else - { - juce::jack_set_error_function (errorCallback); - - // open input ports - const StringArray inputChannels (getInputChannelNames()); - for (int i = 0; i < inputChannels.size(); ++i) - { - String inputName; - inputName << "in_" << ++totalNumberOfInputChannels; - - inputPorts.add (juce::jack_port_register (client, inputName.toUTF8(), - JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0)); - } - - // open output ports - const StringArray outputChannels (getOutputChannelNames()); - for (int i = 0; i < outputChannels.size (); ++i) - { - String outputName; - outputName << "out_" << ++totalNumberOfOutputChannels; - - outputPorts.add (juce::jack_port_register (client, outputName.toUTF8(), - JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0)); - } - - inChans.calloc (totalNumberOfInputChannels + 2); - outChans.calloc (totalNumberOfOutputChannels + 2); - } - } - - ~JackAudioIODevice() - { - close(); - if (client != nullptr) - { - juce::jack_client_close (client); - client = nullptr; - } - } - - StringArray getChannelNames (bool forInput) const - { - StringArray names; - - for (JackPortIterator i (client, forInput); i.next();) - if (i.clientName == getName()) - names.add (i.name.fromFirstOccurrenceOf (":", false, false)); - - return names; - } - - StringArray getOutputChannelNames() override { return getChannelNames (false); } - StringArray getInputChannelNames() override { return getChannelNames (true); } - - Array getAvailableSampleRates() override - { - Array rates; - - if (client != nullptr) - rates.add (juce::jack_get_sample_rate (client)); - - return rates; - } - - Array getAvailableBufferSizes() override - { - Array sizes; - - if (client != nullptr) - sizes.add (juce::jack_get_buffer_size (client)); - - return sizes; - } - - int getDefaultBufferSize() override { return getCurrentBufferSizeSamples(); } - int getCurrentBufferSizeSamples() override { return client != nullptr ? juce::jack_get_buffer_size (client) : 0; } - double getCurrentSampleRate() override { return client != nullptr ? juce::jack_get_sample_rate (client) : 0; } - - - String open (const BigInteger& inputChannels, const BigInteger& outputChannels, - double /* sampleRate */, int /* bufferSizeSamples */) override - { - if (client == nullptr) - { - lastError = "No JACK client running"; - return lastError; - } - - lastError.clear(); - close(); - - juce::jack_set_process_callback (client, processCallback, this); - juce::jack_set_port_connect_callback (client, portConnectCallback, this); - juce::jack_on_shutdown (client, shutdownCallback, this); - juce::jack_activate (client); - deviceIsOpen = true; - - if (! inputChannels.isZero()) - { - for (JackPortIterator i (client, true); i.next();) - { - if (inputChannels [i.index] && i.clientName == getName()) - { - int error = juce::jack_connect (client, i.ports[i.index], juce::jack_port_name ((jack_port_t*) inputPorts[i.index])); - if (error != 0) - JUCE_JACK_LOG ("Cannot connect input port " + String (i.index) + " (" + i.name + "), error " + String (error)); - } - } - } - - if (! outputChannels.isZero()) - { - for (JackPortIterator i (client, false); i.next();) - { - if (outputChannels [i.index] && i.clientName == getName()) - { - int error = juce::jack_connect (client, juce::jack_port_name ((jack_port_t*) outputPorts[i.index]), i.ports[i.index]); - if (error != 0) - JUCE_JACK_LOG ("Cannot connect output port " + String (i.index) + " (" + i.name + "), error " + String (error)); - } - } - } - - return lastError; - } - - void close() override - { - stop(); - - if (client != nullptr) - { - juce::jack_deactivate (client); - juce::jack_set_process_callback (client, processCallback, nullptr); - juce::jack_set_port_connect_callback (client, portConnectCallback, nullptr); - juce::jack_on_shutdown (client, shutdownCallback, nullptr); - } - - deviceIsOpen = false; - } - - void start (AudioIODeviceCallback* newCallback) override - { - if (deviceIsOpen && newCallback != callback) - { - if (newCallback != nullptr) - newCallback->audioDeviceAboutToStart (this); - - AudioIODeviceCallback* const oldCallback = callback; - - { - const ScopedLock sl (callbackLock); - callback = newCallback; - } - - if (oldCallback != nullptr) - oldCallback->audioDeviceStopped(); - } - } - - void stop() override - { - start (nullptr); - } - - bool isOpen() override { return deviceIsOpen; } - bool isPlaying() override { return callback != nullptr; } - int getCurrentBitDepth() override { return 32; } - String getLastError() override { return lastError; } - - BigInteger getActiveOutputChannels() const override { return activeOutputChannels; } - BigInteger getActiveInputChannels() const override { return activeInputChannels; } - - int getOutputLatencyInSamples() override - { - int latency = 0; - - for (int i = 0; i < outputPorts.size(); i++) - latency = jmax (latency, (int) juce::jack_port_get_total_latency (client, (jack_port_t*) outputPorts [i])); - - return latency; - } - - int getInputLatencyInSamples() override - { - int latency = 0; - - for (int i = 0; i < inputPorts.size(); i++) - latency = jmax (latency, (int) juce::jack_port_get_total_latency (client, (jack_port_t*) inputPorts [i])); - - return latency; - } - - String inputId, outputId; - -private: - void process (const int numSamples) - { - int numActiveInChans = 0, numActiveOutChans = 0; - - for (int i = 0; i < totalNumberOfInputChannels; ++i) - { - if (activeInputChannels[i]) - if (jack_default_audio_sample_t* in - = (jack_default_audio_sample_t*) juce::jack_port_get_buffer ((jack_port_t*) inputPorts.getUnchecked(i), numSamples)) - inChans [numActiveInChans++] = (float*) in; - } - - for (int i = 0; i < totalNumberOfOutputChannels; ++i) - { - if (activeOutputChannels[i]) - if (jack_default_audio_sample_t* out - = (jack_default_audio_sample_t*) juce::jack_port_get_buffer ((jack_port_t*) outputPorts.getUnchecked(i), numSamples)) - outChans [numActiveOutChans++] = (float*) out; - } - - const ScopedLock sl (callbackLock); - - if (callback != nullptr) - { - if ((numActiveInChans + numActiveOutChans) > 0) - callback->audioDeviceIOCallback (const_cast (inChans.getData()), numActiveInChans, - outChans, numActiveOutChans, numSamples); - } - else - { - for (int i = 0; i < numActiveOutChans; ++i) - zeromem (outChans[i], sizeof (float) * numSamples); - } - } - - static int processCallback (jack_nframes_t nframes, void* callbackArgument) - { - if (callbackArgument != nullptr) - ((JackAudioIODevice*) callbackArgument)->process (nframes); - - return 0; - } - - void updateActivePorts() - { - BigInteger newOutputChannels, newInputChannels; - - for (int i = 0; i < outputPorts.size(); ++i) - if (juce::jack_port_connected ((jack_port_t*) outputPorts.getUnchecked(i))) - newOutputChannels.setBit (i); - - for (int i = 0; i < inputPorts.size(); ++i) - if (juce::jack_port_connected ((jack_port_t*) inputPorts.getUnchecked(i))) - newInputChannels.setBit (i); - - if (newOutputChannels != activeOutputChannels - || newInputChannels != activeInputChannels) - { - AudioIODeviceCallback* const oldCallback = callback; - - stop(); - - activeOutputChannels = newOutputChannels; - activeInputChannels = newInputChannels; - - if (oldCallback != nullptr) - start (oldCallback); - - sendDeviceChangedCallback(); - } - } - - static void portConnectCallback (jack_port_id_t, jack_port_id_t, int, void* arg) - { - if (JackAudioIODevice* device = static_cast (arg)) - device->updateActivePorts(); - } - - static void threadInitCallback (void* /* callbackArgument */) - { - JUCE_JACK_LOG ("JackAudioIODevice::initialise"); - } - - static void shutdownCallback (void* callbackArgument) - { - JUCE_JACK_LOG ("JackAudioIODevice::shutdown"); - - if (JackAudioIODevice* device = (JackAudioIODevice*) callbackArgument) - { - device->client = nullptr; - device->close(); - } - } - - static void errorCallback (const char* msg) - { - JUCE_JACK_LOG ("JackAudioIODevice::errorCallback " + String (msg)); - } - - static void sendDeviceChangedCallback(); - - bool deviceIsOpen; - jack_client_t* client; - String lastError; - AudioIODeviceCallback* callback; - CriticalSection callbackLock; - - HeapBlock inChans, outChans; - int totalNumberOfInputChannels; - int totalNumberOfOutputChannels; - Array inputPorts, outputPorts; - BigInteger activeInputChannels, activeOutputChannels; -}; - - -//============================================================================== -class JackAudioIODeviceType : public AudioIODeviceType -{ -public: - JackAudioIODeviceType() - : AudioIODeviceType ("JACK"), - hasScanned (false) - { - activeDeviceTypes.add (this); - } - - ~JackAudioIODeviceType() - { - activeDeviceTypes.removeFirstMatchingValue (this); - } - - void scanForDevices() - { - hasScanned = true; - inputNames.clear(); - inputIds.clear(); - outputNames.clear(); - outputIds.clear(); - - if (juce_libjackHandle == nullptr) juce_libjackHandle = dlopen ("libjack.so.0", RTLD_LAZY); - if (juce_libjackHandle == nullptr) juce_libjackHandle = dlopen ("libjack.so", RTLD_LAZY); - if (juce_libjackHandle == nullptr) return; - - jack_status_t status; - - // open a dummy client - if (jack_client_t* const client = juce::jack_client_open ("JuceJackDummy", JackNoStartServer, &status)) - { - // scan for output devices - for (JackPortIterator i (client, false); i.next();) - { - if (i.clientName != (JUCE_JACK_CLIENT_NAME) && ! inputNames.contains (i.clientName)) - { - inputNames.add (i.clientName); - inputIds.add (i.ports [i.index]); - } - } - - // scan for input devices - for (JackPortIterator i (client, true); i.next();) - { - if (i.clientName != (JUCE_JACK_CLIENT_NAME) && ! outputNames.contains (i.clientName)) - { - outputNames.add (i.clientName); - outputIds.add (i.ports [i.index]); - } - } - - juce::jack_client_close (client); - } - else - { - JUCE_JACK_LOG_STATUS (status); - } - } - - StringArray getDeviceNames (bool wantInputNames) const - { - jassert (hasScanned); // need to call scanForDevices() before doing this - return wantInputNames ? inputNames : outputNames; - } - - int getDefaultDeviceIndex (bool /* forInput */) const - { - jassert (hasScanned); // need to call scanForDevices() before doing this - return 0; - } - - bool hasSeparateInputsAndOutputs() const { return true; } - - int getIndexOfDevice (AudioIODevice* device, bool asInput) const - { - jassert (hasScanned); // need to call scanForDevices() before doing this - - if (JackAudioIODevice* d = dynamic_cast (device)) - return asInput ? inputIds.indexOf (d->inputId) - : outputIds.indexOf (d->outputId); - - return -1; - } - - AudioIODevice* createDevice (const String& outputDeviceName, - const String& inputDeviceName) - { - jassert (hasScanned); // need to call scanForDevices() before doing this - - const int inputIndex = inputNames.indexOf (inputDeviceName); - const int outputIndex = outputNames.indexOf (outputDeviceName); - - if (inputIndex >= 0 || outputIndex >= 0) - return new JackAudioIODevice (outputIndex >= 0 ? outputDeviceName - : inputDeviceName, - inputIds [inputIndex], - outputIds [outputIndex]); - - return nullptr; - } - - void portConnectionChange() { callDeviceChangeListeners(); } - -private: - StringArray inputNames, outputNames, inputIds, outputIds; - bool hasScanned; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (JackAudioIODeviceType) -}; - -void JackAudioIODevice::sendDeviceChangedCallback() -{ - for (int i = activeDeviceTypes.size(); --i >= 0;) - if (JackAudioIODeviceType* d = activeDeviceTypes[i]) - d->portConnectionChange(); -} - -//============================================================================== -AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_JACK() -{ - return new JackAudioIODeviceType(); -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/native/juce_linux_Midi.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/native/juce_linux_Midi.cpp deleted file mode 100644 index a6799f3d58..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/native/juce_linux_Midi.cpp +++ /dev/null @@ -1,612 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#if JUCE_ALSA - -// You can define these strings in your app if you want to override the default names: -#ifndef JUCE_ALSA_MIDI_INPUT_NAME - #define JUCE_ALSA_MIDI_INPUT_NAME "Juce Midi Input" -#endif - -#ifndef JUCE_ALSA_MIDI_OUTPUT_NAME - #define JUCE_ALSA_MIDI_OUTPUT_NAME "Juce Midi Output" -#endif - -//============================================================================== -namespace -{ - -class AlsaPortAndCallback; - -//============================================================================== -class AlsaClient : public ReferenceCountedObject -{ -public: - typedef ReferenceCountedObjectPtr Ptr; - - AlsaClient (bool forInput) - : input (forInput), handle (nullptr) - { - snd_seq_open (&handle, "default", forInput ? SND_SEQ_OPEN_INPUT - : SND_SEQ_OPEN_OUTPUT, 0); - } - - ~AlsaClient() - { - if (handle != nullptr) - { - snd_seq_close (handle); - handle = nullptr; - } - - jassert (activeCallbacks.size() == 0); - - if (inputThread) - { - inputThread->stopThread (3000); - inputThread = nullptr; - } - } - - bool isInput() const noexcept { return input; } - - void setName (const String& name) - { - snd_seq_set_client_name (handle, name.toUTF8()); - } - - void registerCallback (AlsaPortAndCallback* cb) - { - if (cb != nullptr) - { - { - const ScopedLock sl (callbackLock); - activeCallbacks.add (cb); - - if (inputThread == nullptr) - inputThread = new MidiInputThread (*this); - } - - inputThread->startThread(); - } - } - - void unregisterCallback (AlsaPortAndCallback* cb) - { - const ScopedLock sl (callbackLock); - - jassert (activeCallbacks.contains (cb)); - activeCallbacks.removeAllInstancesOf (cb); - - if (activeCallbacks.size() == 0 && inputThread->isThreadRunning()) - inputThread->signalThreadShouldExit(); - } - - void handleIncomingMidiMessage (const MidiMessage& message, int port); - - snd_seq_t* get() const noexcept { return handle; } - -private: - bool input; - snd_seq_t* handle; - - Array activeCallbacks; - CriticalSection callbackLock; - - //============================================================================== - class MidiInputThread : public Thread - { - public: - MidiInputThread (AlsaClient& c) - : Thread ("Juce MIDI Input"), client (c) - { - jassert (client.input && client.get() != nullptr); - } - - void run() override - { - const int maxEventSize = 16 * 1024; - snd_midi_event_t* midiParser; - snd_seq_t* seqHandle = client.get(); - - if (snd_midi_event_new (maxEventSize, &midiParser) >= 0) - { - const int numPfds = snd_seq_poll_descriptors_count (seqHandle, POLLIN); - HeapBlock pfd (numPfds); - snd_seq_poll_descriptors (seqHandle, pfd, numPfds, POLLIN); - - HeapBlock buffer (maxEventSize); - - while (! threadShouldExit()) - { - if (poll (pfd, numPfds, 100) > 0) // there was a "500" here which is a bit long when we exit the program and have to wait for a timeout on this poll call - { - if (threadShouldExit()) - break; - - snd_seq_nonblock (seqHandle, 1); - - do - { - snd_seq_event_t* inputEvent = nullptr; - - if (snd_seq_event_input (seqHandle, &inputEvent) >= 0) - { - // xxx what about SYSEXes that are too big for the buffer? - const int numBytes = snd_midi_event_decode (midiParser, buffer, - maxEventSize, inputEvent); - - snd_midi_event_reset_decode (midiParser); - - if (numBytes > 0) - { - const MidiMessage message ((const uint8*) buffer, numBytes, - Time::getMillisecondCounter() * 0.001); - - client.handleIncomingMidiMessage (message, inputEvent->dest.port); - } - - snd_seq_free_event (inputEvent); - } - } - while (snd_seq_event_input_pending (seqHandle, 0) > 0); - } - } - - snd_midi_event_free (midiParser); - } - }; - - private: - AlsaClient& client; - }; - - ScopedPointer inputThread; -}; - - -static AlsaClient::Ptr globalAlsaSequencerIn() -{ - static AlsaClient::Ptr global (new AlsaClient (true)); - return global; -} - -static AlsaClient::Ptr globalAlsaSequencerOut() -{ - static AlsaClient::Ptr global (new AlsaClient (false)); - return global; -} - -static AlsaClient::Ptr globalAlsaSequencer (bool input) -{ - return input ? globalAlsaSequencerIn() - : globalAlsaSequencerOut(); -} - -//============================================================================== -// represents an input or output port of the supplied AlsaClient -class AlsaPort -{ -public: - AlsaPort() noexcept : portId (-1) {} - AlsaPort (const AlsaClient::Ptr& c, int port) noexcept : client (c), portId (port) {} - - void createPort (const AlsaClient::Ptr& c, const String& name, bool forInput) - { - client = c; - - if (snd_seq_t* handle = client->get()) - portId = snd_seq_create_simple_port (handle, name.toUTF8(), - forInput ? (SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_WRITE) - : (SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_SUBS_READ), - SND_SEQ_PORT_TYPE_MIDI_GENERIC); - } - - void deletePort() - { - if (isValid()) - { - snd_seq_delete_simple_port (client->get(), portId); - portId = -1; - } - } - - void connectWith (int sourceClient, int sourcePort) - { - if (client->isInput()) - snd_seq_connect_from (client->get(), portId, sourceClient, sourcePort); - else - snd_seq_connect_to (client->get(), portId, sourceClient, sourcePort); - } - - bool isValid() const noexcept - { - return client != nullptr && client->get() != nullptr && portId >= 0; - } - - AlsaClient::Ptr client; - int portId; -}; - -//============================================================================== -class AlsaPortAndCallback -{ -public: - AlsaPortAndCallback (AlsaPort p, MidiInput* in, MidiInputCallback* cb) - : port (p), midiInput (in), callback (cb), callbackEnabled (false) - { - } - - ~AlsaPortAndCallback() - { - enableCallback (false); - port.deletePort(); - } - - void enableCallback (bool enable) - { - if (callbackEnabled != enable) - { - callbackEnabled = enable; - - if (enable) - port.client->registerCallback (this); - else - port.client->unregisterCallback (this); - } - } - - void handleIncomingMidiMessage (const MidiMessage& message) const - { - callback->handleIncomingMidiMessage (midiInput, message); - } - -private: - AlsaPort port; - MidiInput* midiInput; - MidiInputCallback* callback; - bool callbackEnabled; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AlsaPortAndCallback) -}; - -void AlsaClient::handleIncomingMidiMessage (const MidiMessage& message, int port) -{ - const ScopedLock sl (callbackLock); - - if (AlsaPortAndCallback* const cb = activeCallbacks[port]) - cb->handleIncomingMidiMessage (message); -} - -//============================================================================== -static AlsaPort iterateMidiClient (const AlsaClient::Ptr& seq, - snd_seq_client_info_t* clientInfo, - const bool forInput, - StringArray& deviceNamesFound, - const int deviceIndexToOpen) -{ - AlsaPort port; - - snd_seq_t* seqHandle = seq->get(); - snd_seq_port_info_t* portInfo = nullptr; - - if (snd_seq_port_info_malloc (&portInfo) == 0) - { - int numPorts = snd_seq_client_info_get_num_ports (clientInfo); - const int client = snd_seq_client_info_get_client (clientInfo); - - snd_seq_port_info_set_client (portInfo, client); - snd_seq_port_info_set_port (portInfo, -1); - - while (--numPorts >= 0) - { - if (snd_seq_query_next_port (seqHandle, portInfo) == 0 - && (snd_seq_port_info_get_capability (portInfo) & (forInput ? SND_SEQ_PORT_CAP_READ - : SND_SEQ_PORT_CAP_WRITE)) != 0) - { - deviceNamesFound.add (snd_seq_client_info_get_name (clientInfo)); - - if (deviceNamesFound.size() == deviceIndexToOpen + 1) - { - const int sourcePort = snd_seq_port_info_get_port (portInfo); - const int sourceClient = snd_seq_client_info_get_client (clientInfo); - - if (sourcePort != -1) - { - const String name (forInput ? JUCE_ALSA_MIDI_INPUT_NAME - : JUCE_ALSA_MIDI_OUTPUT_NAME); - seq->setName (name); - port.createPort (seq, name, forInput); - port.connectWith (sourceClient, sourcePort); - } - } - } - } - - snd_seq_port_info_free (portInfo); - } - - return port; -} - -static AlsaPort iterateMidiDevices (const bool forInput, - StringArray& deviceNamesFound, - const int deviceIndexToOpen) -{ - AlsaPort port; - const AlsaClient::Ptr client (globalAlsaSequencer (forInput)); - - if (snd_seq_t* const seqHandle = client->get()) - { - snd_seq_system_info_t* systemInfo = nullptr; - snd_seq_client_info_t* clientInfo = nullptr; - - if (snd_seq_system_info_malloc (&systemInfo) == 0) - { - if (snd_seq_system_info (seqHandle, systemInfo) == 0 - && snd_seq_client_info_malloc (&clientInfo) == 0) - { - int numClients = snd_seq_system_info_get_cur_clients (systemInfo); - - while (--numClients >= 0 && ! port.isValid()) - if (snd_seq_query_next_client (seqHandle, clientInfo) == 0) - port = iterateMidiClient (client, clientInfo, forInput, - deviceNamesFound, deviceIndexToOpen); - - snd_seq_client_info_free (clientInfo); - } - - snd_seq_system_info_free (systemInfo); - } - - } - - deviceNamesFound.appendNumbersToDuplicates (true, true); - - return port; -} - -AlsaPort createMidiDevice (const bool forInput, const String& deviceNameToOpen) -{ - AlsaPort port; - AlsaClient::Ptr client (new AlsaClient (forInput)); - - if (client->get()) - { - client->setName (deviceNameToOpen + (forInput ? " Input" : " Output")); - port.createPort (client, forInput ? "in" : "out", forInput); - } - - return port; -} - -//============================================================================== -class MidiOutputDevice -{ -public: - MidiOutputDevice (MidiOutput* const output, const AlsaPort& p) - : midiOutput (output), port (p), - maxEventSize (16 * 1024) - { - jassert (port.isValid() && midiOutput != nullptr); - snd_midi_event_new (maxEventSize, &midiParser); - } - - ~MidiOutputDevice() - { - snd_midi_event_free (midiParser); - port.deletePort(); - } - - void sendMessageNow (const MidiMessage& message) - { - if (message.getRawDataSize() > maxEventSize) - { - maxEventSize = message.getRawDataSize(); - snd_midi_event_free (midiParser); - snd_midi_event_new (maxEventSize, &midiParser); - } - - snd_seq_event_t event; - snd_seq_ev_clear (&event); - - long numBytes = (long) message.getRawDataSize(); - const uint8* data = message.getRawData(); - - snd_seq_t* seqHandle = port.client->get(); - - while (numBytes > 0) - { - const long numSent = snd_midi_event_encode (midiParser, data, numBytes, &event); - if (numSent <= 0) - break; - - numBytes -= numSent; - data += numSent; - - snd_seq_ev_set_source (&event, 0); - snd_seq_ev_set_subs (&event); - snd_seq_ev_set_direct (&event); - - snd_seq_event_output (seqHandle, &event); - } - - snd_seq_drain_output (seqHandle); - snd_midi_event_reset_encode (midiParser); - } - -private: - MidiOutput* const midiOutput; - AlsaPort port; - snd_midi_event_t* midiParser; - int maxEventSize; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MidiOutputDevice); -}; - -} // namespace - -StringArray MidiOutput::getDevices() -{ - StringArray devices; - iterateMidiDevices (false, devices, -1); - return devices; -} - -int MidiOutput::getDefaultDeviceIndex() -{ - return 0; -} - -MidiOutput* MidiOutput::openDevice (int deviceIndex) -{ - MidiOutput* newDevice = nullptr; - - StringArray devices; - AlsaPort port (iterateMidiDevices (false, devices, deviceIndex)); - - if (port.isValid()) - { - newDevice = new MidiOutput(); - newDevice->internal = new MidiOutputDevice (newDevice, port); - } - - return newDevice; -} - -MidiOutput* MidiOutput::createNewDevice (const String& deviceName) -{ - MidiOutput* newDevice = nullptr; - - AlsaPort port (createMidiDevice (false, deviceName)); - - if (port.isValid()) - { - newDevice = new MidiOutput(); - newDevice->internal = new MidiOutputDevice (newDevice, port); - } - - return newDevice; -} - -MidiOutput::~MidiOutput() -{ - stopBackgroundThread(); - - delete static_cast (internal); -} - -void MidiOutput::sendMessageNow (const MidiMessage& message) -{ - static_cast (internal)->sendMessageNow (message); -} - -//============================================================================== -MidiInput::MidiInput (const String& nm) - : name (nm), internal (nullptr) -{ -} - -MidiInput::~MidiInput() -{ - stop(); - delete static_cast (internal); -} - -void MidiInput::start() -{ - static_cast (internal)->enableCallback (true); -} - -void MidiInput::stop() -{ - static_cast (internal)->enableCallback (false); -} - -int MidiInput::getDefaultDeviceIndex() -{ - return 0; -} - -StringArray MidiInput::getDevices() -{ - StringArray devices; - iterateMidiDevices (true, devices, -1); - return devices; -} - -MidiInput* MidiInput::openDevice (int deviceIndex, MidiInputCallback* callback) -{ - MidiInput* newDevice = nullptr; - - StringArray devices; - AlsaPort port (iterateMidiDevices (true, devices, deviceIndex)); - - if (port.isValid()) - { - newDevice = new MidiInput (devices [deviceIndex]); - newDevice->internal = new AlsaPortAndCallback (port, newDevice, callback); - } - - return newDevice; -} - -MidiInput* MidiInput::createNewDevice (const String& deviceName, MidiInputCallback* callback) -{ - MidiInput* newDevice = nullptr; - - AlsaPort port (createMidiDevice (true, deviceName)); - - if (port.isValid()) - { - newDevice = new MidiInput (deviceName); - newDevice->internal = new AlsaPortAndCallback (port, newDevice, callback); - } - - return newDevice; -} - - -//============================================================================== -#else - -// (These are just stub functions if ALSA is unavailable...) - -StringArray MidiOutput::getDevices() { return StringArray(); } -int MidiOutput::getDefaultDeviceIndex() { return 0; } -MidiOutput* MidiOutput::openDevice (int) { return nullptr; } -MidiOutput* MidiOutput::createNewDevice (const String&) { return nullptr; } -MidiOutput::~MidiOutput() {} -void MidiOutput::sendMessageNow (const MidiMessage&) {} - -MidiInput::MidiInput (const String& nm) : name (nm), internal (nullptr) {} -MidiInput::~MidiInput() {} -void MidiInput::start() {} -void MidiInput::stop() {} -int MidiInput::getDefaultDeviceIndex() { return 0; } -StringArray MidiInput::getDevices() { return StringArray(); } -MidiInput* MidiInput::openDevice (int, MidiInputCallback*) { return nullptr; } -MidiInput* MidiInput::createNewDevice (const String&, MidiInputCallback*) { return nullptr; } - -#endif diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/native/juce_mac_AudioCDBurner.mm b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/native/juce_mac_AudioCDBurner.mm deleted file mode 100644 index 8dd7bfad16..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/native/juce_mac_AudioCDBurner.mm +++ /dev/null @@ -1,455 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -const int kilobytesPerSecond1x = 176; - -struct AudioTrackProducerClass : public ObjCClass -{ - AudioTrackProducerClass() : ObjCClass ("JUCEAudioTrackProducer_") - { - addIvar ("source"); - - addMethod (@selector (initWithAudioSourceHolder:), initWithAudioSourceHolder, "@@:^v"); - addMethod (@selector (cleanupTrackAfterBurn:), cleanupTrackAfterBurn, "v@:@"); - addMethod (@selector (cleanupTrackAfterVerification:), cleanupTrackAfterVerification, "c@:@"); - addMethod (@selector (estimateLengthOfTrack:), estimateLengthOfTrack, "Q@:@"); - addMethod (@selector (prepareTrack:forBurn:toMedia:), prepareTrack, "c@:@@@"); - addMethod (@selector (prepareTrackForVerification:), prepareTrackForVerification, "c@:@"); - addMethod (@selector (produceDataForTrack:intoBuffer:length:atAddress:blockSize:ioFlags:), - produceDataForTrack, "I@:@^cIQI^I"); - addMethod (@selector (producePreGapForTrack:intoBuffer:length:atAddress:blockSize:ioFlags:), - produceDataForTrack, "I@:@^cIQI^I"); - addMethod (@selector (verifyDataForTrack:intoBuffer:length:atAddress:blockSize:ioFlags:), - produceDataForTrack, "I@:@^cIQI^I"); - - registerClass(); - } - - struct AudioSourceHolder - { - AudioSourceHolder (AudioSource* s, int numFrames) - : source (s), readPosition (0), lengthInFrames (numFrames) - { - } - - ~AudioSourceHolder() - { - if (source != nullptr) - source->releaseResources(); - } - - ScopedPointer source; - int readPosition, lengthInFrames; - }; - -private: - static id initWithAudioSourceHolder (id self, SEL, AudioSourceHolder* source) - { - self = sendSuperclassMessage (self, @selector (init)); - object_setInstanceVariable (self, "source", source); - return self; - } - - static AudioSourceHolder* getSource (id self) - { - return getIvar (self, "source"); - } - - static void dealloc (id self, SEL) - { - delete getSource (self); - sendSuperclassMessage (self, @selector (dealloc)); - } - - static void cleanupTrackAfterBurn (id self, SEL, DRTrack*) {} - static BOOL cleanupTrackAfterVerification (id self, SEL, DRTrack*) { return true; } - - static uint64_t estimateLengthOfTrack (id self, SEL, DRTrack*) - { - return getSource (self)->lengthInFrames; - } - - static BOOL prepareTrack (id self, SEL, DRTrack*, DRBurn*, NSDictionary*) - { - if (AudioSourceHolder* const source = getSource (self)) - { - source->source->prepareToPlay (44100 / 75, 44100); - source->readPosition = 0; - } - - return true; - } - - static BOOL prepareTrackForVerification (id self, SEL, DRTrack*) - { - if (AudioSourceHolder* const source = getSource (self)) - source->source->prepareToPlay (44100 / 75, 44100); - - return true; - } - - static uint32_t produceDataForTrack (id self, SEL, DRTrack*, char* buffer, - uint32_t bufferLength, uint64_t /*address*/, - uint32_t /*blockSize*/, uint32_t* /*flags*/) - { - if (AudioSourceHolder* const source = getSource (self)) - { - const int numSamples = jmin ((int) bufferLength / 4, - (source->lengthInFrames * (44100 / 75)) - source->readPosition); - - if (numSamples > 0) - { - AudioSampleBuffer tempBuffer (2, numSamples); - AudioSourceChannelInfo info (tempBuffer); - - source->source->getNextAudioBlock (info); - - typedef AudioData::Pointer CDSampleFormat; - typedef AudioData::Pointer SourceSampleFormat; - - CDSampleFormat left (buffer, 2); - left.convertSamples (SourceSampleFormat (tempBuffer.getReadPointer (0)), numSamples); - CDSampleFormat right (buffer + 2, 2); - right.convertSamples (SourceSampleFormat (tempBuffer.getReadPointer (1)), numSamples); - - source->readPosition += numSamples; - } - - return numSamples * 4; - } - - return 0; - } - - static uint32_t producePreGapForTrack (id self, SEL, DRTrack*, char* buffer, - uint32_t bufferLength, uint64_t /*address*/, - uint32_t /*blockSize*/, uint32_t* /*flags*/) - { - zeromem (buffer, bufferLength); - return bufferLength; - } - - static BOOL verifyDataForTrack (id self, SEL, DRTrack*, const char*, - uint32_t /*bufferLength*/, uint64_t /*address*/, - uint32_t /*blockSize*/, uint32_t* /*flags*/) - { - return true; - } -}; - -struct OpenDiskDevice -{ - OpenDiskDevice (DRDevice* d) - : device (d), - tracks ([[NSMutableArray alloc] init]), - underrunProtection (true) - { - } - - ~OpenDiskDevice() - { - [tracks release]; - } - - void addSourceTrack (AudioSource* source, int numSamples) - { - if (source != nullptr) - { - const int numFrames = (numSamples + 587) / 588; - - static AudioTrackProducerClass cls; - - NSObject* producer = [cls.createInstance() performSelector: @selector (initWithAudioSourceHolder:) - withObject: (id) new AudioTrackProducerClass::AudioSourceHolder (source, numFrames)]; - DRTrack* track = [[DRTrack alloc] initWithProducer: producer]; - - { - NSMutableDictionary* p = [[track properties] mutableCopy]; - [p setObject: [DRMSF msfWithFrames: numFrames] forKey: DRTrackLengthKey]; - [p setObject: [NSNumber numberWithUnsignedShort: 2352] forKey: DRBlockSizeKey]; - [p setObject: [NSNumber numberWithInt: 0] forKey: DRDataFormKey]; - [p setObject: [NSNumber numberWithInt: 0] forKey: DRBlockTypeKey]; - [p setObject: [NSNumber numberWithInt: 0] forKey: DRTrackModeKey]; - [p setObject: [NSNumber numberWithInt: 0] forKey: DRSessionFormatKey]; - [track setProperties: p]; - [p release]; - } - - [tracks addObject: track]; - - [track release]; - [producer release]; - } - } - - String burn (AudioCDBurner::BurnProgressListener* listener, - bool shouldEject, bool peformFakeBurnForTesting, int burnSpeed) - { - DRBurn* burn = [DRBurn burnForDevice: device]; - - if (! [device acquireExclusiveAccess]) - return "Couldn't open or write to the CD device"; - - [device acquireMediaReservation]; - - NSMutableDictionary* d = [[burn properties] mutableCopy]; - [d autorelease]; - [d setObject: [NSNumber numberWithBool: peformFakeBurnForTesting] forKey: DRBurnTestingKey]; - [d setObject: [NSNumber numberWithBool: false] forKey: DRBurnVerifyDiscKey]; - [d setObject: (shouldEject ? DRBurnCompletionActionEject : DRBurnCompletionActionMount) forKey: DRBurnCompletionActionKey]; - - if (burnSpeed > 0) - [d setObject: [NSNumber numberWithFloat: burnSpeed * kilobytesPerSecond1x] forKey: DRBurnRequestedSpeedKey]; - - if (! underrunProtection) - [d setObject: [NSNumber numberWithBool: false] forKey: DRBurnUnderrunProtectionKey]; - - [burn setProperties: d]; - - [burn writeLayout: tracks]; - - for (;;) - { - Thread::sleep (300); - float progress = [[[burn status] objectForKey: DRStatusPercentCompleteKey] floatValue]; - - if (listener != nullptr && listener->audioCDBurnProgress (progress)) - { - [burn abort]; - return "User cancelled the write operation"; - } - - if ([[[burn status] objectForKey: DRStatusStateKey] isEqualTo: DRStatusStateFailed]) - return "Write operation failed"; - - if ([[[burn status] objectForKey: DRStatusStateKey] isEqualTo: DRStatusStateDone]) - break; - - NSString* err = (NSString*) [[[burn status] objectForKey: DRErrorStatusKey] - objectForKey: DRErrorStatusErrorStringKey]; - if ([err length] > 0) - return nsStringToJuce (err); - } - - [device releaseMediaReservation]; - [device releaseExclusiveAccess]; - return String::empty; - } - - DRDevice* device; - NSMutableArray* tracks; - bool underrunProtection; -}; - -//============================================================================== -class AudioCDBurner::Pimpl : public Timer -{ -public: - Pimpl (AudioCDBurner& b, int deviceIndex) : owner (b) - { - if (DRDevice* dev = [[DRDevice devices] objectAtIndex: deviceIndex]) - { - device = new OpenDiskDevice (dev); - lastState = getDiskState(); - startTimer (1000); - } - } - - ~Pimpl() - { - stopTimer(); - } - - void timerCallback() override - { - const DiskState state = getDiskState(); - - if (state != lastState) - { - lastState = state; - owner.sendChangeMessage(); - } - } - - DiskState getDiskState() const - { - if ([device->device isValid]) - { - NSDictionary* status = [device->device status]; - NSString* state = [status objectForKey: DRDeviceMediaStateKey]; - - if ([state isEqualTo: DRDeviceMediaStateNone]) - { - if ([[status objectForKey: DRDeviceIsTrayOpenKey] boolValue]) - return trayOpen; - - return noDisc; - } - - if ([state isEqualTo: DRDeviceMediaStateMediaPresent]) - { - if ([[[status objectForKey: DRDeviceMediaInfoKey] objectForKey: DRDeviceMediaBlocksFreeKey] intValue] > 0) - return writableDiskPresent; - - return readOnlyDiskPresent; - } - } - - return unknown; - } - - bool openTray() { return [device->device isValid] && [device->device ejectMedia]; } - - Array getAvailableWriteSpeeds() const - { - Array results; - - if ([device->device isValid]) - for (id kbPerSec in [[[device->device status] objectForKey: DRDeviceMediaInfoKey] objectForKey: DRDeviceBurnSpeedsKey]) - results.add ([kbPerSec intValue] / kilobytesPerSecond1x); - - return results; - } - - bool setBufferUnderrunProtection (const bool shouldBeEnabled) - { - if ([device->device isValid]) - { - device->underrunProtection = shouldBeEnabled; - return shouldBeEnabled && [[[device->device status] objectForKey: DRDeviceCanUnderrunProtectCDKey] boolValue]; - } - - return false; - } - - int getNumAvailableAudioBlocks() const - { - return [[[[device->device status] objectForKey: DRDeviceMediaInfoKey] - objectForKey: DRDeviceMediaBlocksFreeKey] intValue]; - } - - ScopedPointer device; - -private: - DiskState lastState; - AudioCDBurner& owner; -}; - -//============================================================================== -AudioCDBurner::AudioCDBurner (const int deviceIndex) -{ - pimpl = new Pimpl (*this, deviceIndex); -} - -AudioCDBurner::~AudioCDBurner() -{ -} - -AudioCDBurner* AudioCDBurner::openDevice (const int deviceIndex) -{ - ScopedPointer b (new AudioCDBurner (deviceIndex)); - - if (b->pimpl->device == nil) - b = nullptr; - - return b.release(); -} - -StringArray AudioCDBurner::findAvailableDevices() -{ - StringArray s; - - for (NSDictionary* dic in [DRDevice devices]) - if (NSString* name = [dic valueForKey: DRDeviceProductNameKey]) - s.add (nsStringToJuce (name)); - - return s; -} - -AudioCDBurner::DiskState AudioCDBurner::getDiskState() const -{ - return pimpl->getDiskState(); -} - -bool AudioCDBurner::isDiskPresent() const -{ - return getDiskState() == writableDiskPresent; -} - -bool AudioCDBurner::openTray() -{ - return pimpl->openTray(); -} - -AudioCDBurner::DiskState AudioCDBurner::waitUntilStateChange (int timeOutMilliseconds) -{ - const int64 timeout = Time::currentTimeMillis() + timeOutMilliseconds; - DiskState oldState = getDiskState(); - DiskState newState = oldState; - - while (newState == oldState && Time::currentTimeMillis() < timeout) - { - newState = getDiskState(); - Thread::sleep (100); - } - - return newState; -} - -Array AudioCDBurner::getAvailableWriteSpeeds() const -{ - return pimpl->getAvailableWriteSpeeds(); -} - -bool AudioCDBurner::setBufferUnderrunProtection (const bool shouldBeEnabled) -{ - return pimpl->setBufferUnderrunProtection (shouldBeEnabled); -} - -int AudioCDBurner::getNumAvailableAudioBlocks() const -{ - return pimpl->getNumAvailableAudioBlocks(); -} - -bool AudioCDBurner::addAudioTrack (AudioSource* source, int numSamps) -{ - if ([pimpl->device->device isValid]) - { - pimpl->device->addSourceTrack (source, numSamps); - return true; - } - - return false; -} - -String AudioCDBurner::burn (AudioCDBurner::BurnProgressListener* listener, - bool ejectDiscAfterwards, - bool performFakeBurnForTesting, - int writeSpeed) -{ - if ([pimpl->device->device isValid]) - return pimpl->device->burn (listener, ejectDiscAfterwards, performFakeBurnForTesting, writeSpeed); - - return "Couldn't open or write to the CD device"; -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/native/juce_mac_AudioCDReader.mm b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/native/juce_mac_AudioCDReader.mm deleted file mode 100644 index 447c98b88e..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/native/juce_mac_AudioCDReader.mm +++ /dev/null @@ -1,261 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -namespace CDReaderHelpers -{ - inline const XmlElement* getElementForKey (const XmlElement& xml, const String& key) - { - forEachXmlChildElementWithTagName (xml, child, "key") - if (child->getAllSubText().trim() == key) - return child->getNextElement(); - - return nullptr; - } - - static int getIntValueForKey (const XmlElement& xml, const String& key, int defaultValue = -1) - { - const XmlElement* const block = getElementForKey (xml, key); - return block != nullptr ? block->getAllSubText().trim().getIntValue() : defaultValue; - } - - // Get the track offsets for a CD given an XmlElement representing its TOC.Plist. - // Returns NULL on success, otherwise a const char* representing an error. - static const char* getTrackOffsets (XmlDocument& xmlDocument, Array& offsets) - { - const ScopedPointer xml (xmlDocument.getDocumentElement()); - if (xml == nullptr) - return "Couldn't parse XML in file"; - - const XmlElement* const dict = xml->getChildByName ("dict"); - if (dict == nullptr) - return "Couldn't get top level dictionary"; - - const XmlElement* const sessions = getElementForKey (*dict, "Sessions"); - if (sessions == nullptr) - return "Couldn't find sessions key"; - - const XmlElement* const session = sessions->getFirstChildElement(); - if (session == nullptr) - return "Couldn't find first session"; - - const int leadOut = getIntValueForKey (*session, "Leadout Block"); - if (leadOut < 0) - return "Couldn't find Leadout Block"; - - const XmlElement* const trackArray = getElementForKey (*session, "Track Array"); - if (trackArray == nullptr) - return "Couldn't find Track Array"; - - forEachXmlChildElement (*trackArray, track) - { - const int trackValue = getIntValueForKey (*track, "Start Block"); - if (trackValue < 0) - return "Couldn't find Start Block in the track"; - - offsets.add (trackValue * AudioCDReader::samplesPerFrame - 88200); - } - - offsets.add (leadOut * AudioCDReader::samplesPerFrame - 88200); - return nullptr; - } - - static void findDevices (Array& cds) - { - File volumes ("/Volumes"); - volumes.findChildFiles (cds, File::findDirectories, false); - - for (int i = cds.size(); --i >= 0;) - if (! cds.getReference(i).getChildFile (".TOC.plist").exists()) - cds.remove (i); - } - - struct TrackSorter - { - static int getCDTrackNumber (const File& file) - { - return file.getFileName().initialSectionContainingOnly ("0123456789").getIntValue(); - } - - static int compareElements (const File& first, const File& second) - { - const int firstTrack = getCDTrackNumber (first); - const int secondTrack = getCDTrackNumber (second); - - jassert (firstTrack > 0 && secondTrack > 0); - - return firstTrack - secondTrack; - } - }; -} - -//============================================================================== -StringArray AudioCDReader::getAvailableCDNames() -{ - Array cds; - CDReaderHelpers::findDevices (cds); - - StringArray names; - - for (int i = 0; i < cds.size(); ++i) - names.add (cds.getReference(i).getFileName()); - - return names; -} - -AudioCDReader* AudioCDReader::createReaderForCD (const int index) -{ - Array cds; - CDReaderHelpers::findDevices (cds); - - if (cds[index].exists()) - return new AudioCDReader (cds[index]); - - return nullptr; -} - -AudioCDReader::AudioCDReader (const File& volume) - : AudioFormatReader (0, "CD Audio"), - volumeDir (volume), - currentReaderTrack (-1), - reader (0) -{ - sampleRate = 44100.0; - bitsPerSample = 16; - numChannels = 2; - usesFloatingPointData = false; - - refreshTrackLengths(); -} - -AudioCDReader::~AudioCDReader() -{ -} - -void AudioCDReader::refreshTrackLengths() -{ - tracks.clear(); - trackStartSamples.clear(); - lengthInSamples = 0; - - volumeDir.findChildFiles (tracks, File::findFiles | File::ignoreHiddenFiles, false, "*.aiff"); - - CDReaderHelpers::TrackSorter sorter; - tracks.sort (sorter); - - const File toc (volumeDir.getChildFile (".TOC.plist")); - - if (toc.exists()) - { - XmlDocument doc (toc); - const char* error = CDReaderHelpers::getTrackOffsets (doc, trackStartSamples); - (void) error; // could be logged.. - - lengthInSamples = trackStartSamples.getLast() - trackStartSamples.getFirst(); - } -} - -bool AudioCDReader::readSamples (int** destSamples, int numDestChannels, int startOffsetInDestBuffer, - int64 startSampleInFile, int numSamples) -{ - while (numSamples > 0) - { - int track = -1; - - for (int i = 0; i < trackStartSamples.size() - 1; ++i) - { - if (startSampleInFile < trackStartSamples.getUnchecked (i + 1)) - { - track = i; - break; - } - } - - if (track < 0) - return false; - - if (track != currentReaderTrack) - { - reader = nullptr; - - if (FileInputStream* const in = tracks [track].createInputStream()) - { - BufferedInputStream* const bin = new BufferedInputStream (in, 65536, true); - - AiffAudioFormat format; - reader = format.createReaderFor (bin, true); - - if (reader == nullptr) - currentReaderTrack = -1; - else - currentReaderTrack = track; - } - } - - if (reader == nullptr) - return false; - - const int startPos = (int) (startSampleInFile - trackStartSamples.getUnchecked (track)); - const int numAvailable = (int) jmin ((int64) numSamples, reader->lengthInSamples - startPos); - - reader->readSamples (destSamples, numDestChannels, startOffsetInDestBuffer, startPos, numAvailable); - - numSamples -= numAvailable; - startSampleInFile += numAvailable; - } - - return true; -} - -bool AudioCDReader::isCDStillPresent() const -{ - return volumeDir.exists(); -} - -void AudioCDReader::ejectDisk() -{ - JUCE_AUTORELEASEPOOL - { - [[NSWorkspace sharedWorkspace] unmountAndEjectDeviceAtPath: juceStringToNS (volumeDir.getFullPathName())]; - } -} - -bool AudioCDReader::isTrackAudio (int trackNum) const -{ - return tracks [trackNum].hasFileExtension (".aiff"); -} - -void AudioCDReader::enableIndexScanning (bool) -{ - // any way to do this on a Mac?? -} - -int AudioCDReader::getLastIndex() const -{ - return 0; -} - -Array AudioCDReader::findIndexesInTrack (const int /*trackNumber*/) -{ - return Array(); -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/native/juce_mac_CoreAudio.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/native/juce_mac_CoreAudio.cpp deleted file mode 100644 index d7044eb138..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/native/juce_mac_CoreAudio.cpp +++ /dev/null @@ -1,1945 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#if JUCE_COREAUDIO_LOGGING_ENABLED - #define JUCE_COREAUDIOLOG(a) { String camsg ("CoreAudio: "); camsg << a; Logger::writeToLog (camsg); } -#else - #define JUCE_COREAUDIOLOG(a) -#endif - -//============================================================================== -struct SystemVol -{ - SystemVol (AudioObjectPropertySelector selector) - : outputDeviceID (kAudioObjectUnknown) - { - addr.mScope = kAudioObjectPropertyScopeGlobal; - addr.mElement = kAudioObjectPropertyElementMaster; - addr.mSelector = kAudioHardwarePropertyDefaultOutputDevice; - - if (AudioHardwareServiceHasProperty (kAudioObjectSystemObject, &addr)) - { - UInt32 deviceIDSize = sizeof (outputDeviceID); - OSStatus status = AudioHardwareServiceGetPropertyData (kAudioObjectSystemObject, &addr, 0, - nullptr, &deviceIDSize, &outputDeviceID); - - if (status == noErr) - { - addr.mElement = kAudioObjectPropertyElementMaster; - addr.mSelector = selector; - addr.mScope = kAudioDevicePropertyScopeOutput; - - if (! AudioHardwareServiceHasProperty (outputDeviceID, &addr)) - outputDeviceID = kAudioObjectUnknown; - } - } - } - - float getGain() - { - Float32 gain = 0; - - if (outputDeviceID != kAudioObjectUnknown) - { - UInt32 size = sizeof (gain); - AudioHardwareServiceGetPropertyData (outputDeviceID, &addr, - 0, nullptr, &size, &gain); - } - - return (float) gain; - } - - bool setGain (float gain) - { - if (outputDeviceID != kAudioObjectUnknown && canSetVolume()) - { - Float32 newVolume = gain; - UInt32 size = sizeof (newVolume); - - return AudioHardwareServiceSetPropertyData (outputDeviceID, &addr, 0, nullptr, - size, &newVolume) == noErr; - } - - return false; - } - - bool isMuted() - { - UInt32 muted = 0; - - if (outputDeviceID != kAudioObjectUnknown) - { - UInt32 size = sizeof (muted); - AudioHardwareServiceGetPropertyData (outputDeviceID, &addr, - 0, nullptr, &size, &muted); - } - - return muted != 0; - } - - bool setMuted (bool mute) - { - if (outputDeviceID != kAudioObjectUnknown && canSetVolume()) - { - UInt32 newMute = mute ? 1 : 0; - UInt32 size = sizeof (newMute); - - return AudioHardwareServiceSetPropertyData (outputDeviceID, &addr, 0, nullptr, - size, &newMute) == noErr; - } - - return false; - } - -private: - AudioDeviceID outputDeviceID; - AudioObjectPropertyAddress addr; - - bool canSetVolume() - { - Boolean isSettable = NO; - return AudioHardwareServiceIsPropertySettable (outputDeviceID, &addr, &isSettable) == noErr - && isSettable; - } -}; - -#define JUCE_SYSTEMAUDIOVOL_IMPLEMENTED 1 -float JUCE_CALLTYPE SystemAudioVolume::getGain() { return SystemVol (kAudioHardwareServiceDeviceProperty_VirtualMasterVolume).getGain(); } -bool JUCE_CALLTYPE SystemAudioVolume::setGain (float gain) { return SystemVol (kAudioHardwareServiceDeviceProperty_VirtualMasterVolume).setGain (gain); } -bool JUCE_CALLTYPE SystemAudioVolume::isMuted() { return SystemVol (kAudioDevicePropertyMute).isMuted(); } -bool JUCE_CALLTYPE SystemAudioVolume::setMuted (bool mute) { return SystemVol (kAudioDevicePropertyMute).setMuted (mute); } - -//============================================================================== -struct CoreAudioClasses -{ - -class CoreAudioIODevice; - -//============================================================================== -class CoreAudioInternal : private Timer -{ -public: - CoreAudioInternal (CoreAudioIODevice& d, AudioDeviceID id) - : owner (d), - inputLatency (0), - outputLatency (0), - bitDepth (32), - callback (nullptr), - #if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 - audioProcID (0), - #endif - deviceID (id), - started (false), - sampleRate (0), - bufferSize (512), - numInputChans (0), - numOutputChans (0), - callbacksAllowed (true) - { - jassert (deviceID != 0); - - updateDetailsFromDevice(); - - AudioObjectPropertyAddress pa; - pa.mSelector = kAudioObjectPropertySelectorWildcard; - pa.mScope = kAudioObjectPropertyScopeWildcard; - pa.mElement = kAudioObjectPropertyElementWildcard; - - AudioObjectAddPropertyListener (deviceID, &pa, deviceListenerProc, this); - } - - ~CoreAudioInternal() - { - AudioObjectPropertyAddress pa; - pa.mSelector = kAudioObjectPropertySelectorWildcard; - pa.mScope = kAudioObjectPropertyScopeWildcard; - pa.mElement = kAudioObjectPropertyElementWildcard; - - AudioObjectRemovePropertyListener (deviceID, &pa, deviceListenerProc, this); - - stop (false); - } - - void allocateTempBuffers() - { - const int tempBufSize = bufferSize + 4; - audioBuffer.calloc ((size_t) ((numInputChans + numOutputChans) * tempBufSize)); - - tempInputBuffers.calloc ((size_t) numInputChans + 2); - tempOutputBuffers.calloc ((size_t) numOutputChans + 2); - - int count = 0; - for (int i = 0; i < numInputChans; ++i) tempInputBuffers[i] = audioBuffer + count++ * tempBufSize; - for (int i = 0; i < numOutputChans; ++i) tempOutputBuffers[i] = audioBuffer + count++ * tempBufSize; - } - - struct CallbackDetailsForChannel - { - int streamNum; - int dataOffsetSamples; - int dataStrideSamples; - }; - - // returns the number of actual available channels - StringArray getChannelInfo (const bool input, Array& newChannelInfo) const - { - StringArray newNames; - int chanNum = 0; - UInt32 size; - - AudioObjectPropertyAddress pa; - pa.mSelector = kAudioDevicePropertyStreamConfiguration; - pa.mScope = input ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput; - pa.mElement = kAudioObjectPropertyElementMaster; - - if (OK (AudioObjectGetPropertyDataSize (deviceID, &pa, 0, nullptr, &size))) - { - HeapBlock bufList; - bufList.calloc (size, 1); - - if (OK (AudioObjectGetPropertyData (deviceID, &pa, 0, nullptr, &size, bufList))) - { - const int numStreams = (int) bufList->mNumberBuffers; - - for (int i = 0; i < numStreams; ++i) - { - const AudioBuffer& b = bufList->mBuffers[i]; - - for (unsigned int j = 0; j < b.mNumberChannels; ++j) - { - String name; - NSString* nameNSString = nil; - size = sizeof (nameNSString); - - pa.mSelector = kAudioObjectPropertyElementName; - pa.mElement = (AudioObjectPropertyElement) chanNum + 1; - - if (AudioObjectGetPropertyData (deviceID, &pa, 0, nullptr, &size, &nameNSString) == noErr) - { - name = nsStringToJuce (nameNSString); - [nameNSString release]; - } - - if ((input ? activeInputChans : activeOutputChans) [chanNum]) - { - CallbackDetailsForChannel info = { i, (int) j, (int) b.mNumberChannels }; - newChannelInfo.add (info); - } - - if (name.isEmpty()) - name << (input ? "Input " : "Output ") << (chanNum + 1); - - newNames.add (name); - ++chanNum; - } - } - } - } - - return newNames; - } - - Array getSampleRatesFromDevice() const - { - Array newSampleRates; - - AudioObjectPropertyAddress pa; - pa.mScope = kAudioObjectPropertyScopeWildcard; - pa.mElement = kAudioObjectPropertyElementMaster; - pa.mSelector = kAudioDevicePropertyAvailableNominalSampleRates; - UInt32 size = 0; - - if (OK (AudioObjectGetPropertyDataSize (deviceID, &pa, 0, nullptr, &size))) - { - HeapBlock ranges; - ranges.calloc (size, 1); - - if (OK (AudioObjectGetPropertyData (deviceID, &pa, 0, nullptr, &size, ranges))) - { - static const double possibleRates[] = { 44100.0, 48000.0, 88200.0, 96000.0, 176400.0, 192000.0 }; - - for (int i = 0; i < numElementsInArray (possibleRates); ++i) - { - for (int j = size / (int) sizeof (AudioValueRange); --j >= 0;) - { - if (possibleRates[i] >= ranges[j].mMinimum - 2 && possibleRates[i] <= ranges[j].mMaximum + 2) - { - newSampleRates.add (possibleRates[i]); - break; - } - } - } - } - } - - if (newSampleRates.size() == 0 && sampleRate > 0) - newSampleRates.add (sampleRate); - - return newSampleRates; - } - - Array getBufferSizesFromDevice() const - { - Array newBufferSizes; - - AudioObjectPropertyAddress pa; - pa.mScope = kAudioObjectPropertyScopeWildcard; - pa.mElement = kAudioObjectPropertyElementMaster; - pa.mSelector = kAudioDevicePropertyBufferFrameSizeRange; - UInt32 size = 0; - - if (OK (AudioObjectGetPropertyDataSize (deviceID, &pa, 0, nullptr, &size))) - { - HeapBlock ranges; - ranges.calloc (size, 1); - - if (OK (AudioObjectGetPropertyData (deviceID, &pa, 0, nullptr, &size, ranges))) - { - newBufferSizes.add ((int) (ranges[0].mMinimum + 15) & ~15); - - for (int i = 32; i < 2048; i += 32) - { - for (int j = size / (int) sizeof (AudioValueRange); --j >= 0;) - { - if (i >= ranges[j].mMinimum && i <= ranges[j].mMaximum) - { - newBufferSizes.addIfNotAlreadyThere (i); - break; - } - } - } - - if (bufferSize > 0) - newBufferSizes.addIfNotAlreadyThere (bufferSize); - } - } - - if (newBufferSizes.size() == 0 && bufferSize > 0) - newBufferSizes.add (bufferSize); - - return newBufferSizes; - } - - int getLatencyFromDevice (AudioObjectPropertyScope scope) const - { - UInt32 lat = 0; - UInt32 size = sizeof (lat); - AudioObjectPropertyAddress pa; - pa.mElement = kAudioObjectPropertyElementMaster; - pa.mSelector = kAudioDevicePropertyLatency; - pa.mScope = scope; - AudioObjectGetPropertyData (deviceID, &pa, 0, nullptr, &size, &lat); - return (int) lat; - } - - int getBitDepthFromDevice (AudioObjectPropertyScope scope) const - { - AudioObjectPropertyAddress pa; - pa.mElement = kAudioObjectPropertyElementMaster; - pa.mSelector = kAudioStreamPropertyPhysicalFormat; - pa.mScope = scope; - - AudioStreamBasicDescription asbd; - UInt32 size = sizeof (asbd); - - if (OK (AudioObjectGetPropertyData (deviceID, &pa, 0, nullptr, &size, &asbd))) - return (int) asbd.mBitsPerChannel; - - return 0; - } - - void updateDetailsFromDevice() - { - stopTimer(); - - if (deviceID == 0) - return; - - // this collects all the new details from the device without any locking, then - // locks + swaps them afterwards. - AudioObjectPropertyAddress pa; - pa.mScope = kAudioObjectPropertyScopeWildcard; - pa.mElement = kAudioObjectPropertyElementMaster; - - UInt32 isAlive; - UInt32 size = sizeof (isAlive); - pa.mSelector = kAudioDevicePropertyDeviceIsAlive; - if (OK (AudioObjectGetPropertyData (deviceID, &pa, 0, nullptr, &size, &isAlive)) && isAlive == 0) - return; - - Float64 sr; - size = sizeof (sr); - pa.mSelector = kAudioDevicePropertyNominalSampleRate; - if (OK (AudioObjectGetPropertyData (deviceID, &pa, 0, nullptr, &size, &sr))) - sampleRate = sr; - - UInt32 framesPerBuf = (UInt32) bufferSize; - size = sizeof (framesPerBuf); - pa.mSelector = kAudioDevicePropertyBufferFrameSize; - AudioObjectGetPropertyData (deviceID, &pa, 0, nullptr, &size, &framesPerBuf); - - Array newBufferSizes (getBufferSizesFromDevice()); - Array newSampleRates (getSampleRatesFromDevice()); - - inputLatency = getLatencyFromDevice (kAudioDevicePropertyScopeInput); - outputLatency = getLatencyFromDevice (kAudioDevicePropertyScopeOutput); - - Array newInChans, newOutChans; - StringArray newInNames (getChannelInfo (true, newInChans)); - StringArray newOutNames (getChannelInfo (false, newOutChans)); - - const int inputBitDepth = getBitDepthFromDevice (kAudioDevicePropertyScopeInput); - const int outputBitDepth = getBitDepthFromDevice (kAudioDevicePropertyScopeOutput); - - bitDepth = jmax (inputBitDepth, outputBitDepth); - if (bitDepth <= 0) - bitDepth = 32; - - // after getting the new values, lock + apply them - const ScopedLock sl (callbackLock); - - bufferSize = (int) framesPerBuf; - allocateTempBuffers(); - - sampleRates.swapWith (newSampleRates); - bufferSizes.swapWith (newBufferSizes); - - inChanNames.swapWith (newInNames); - outChanNames.swapWith (newOutNames); - - inputChannelInfo.swapWith (newInChans); - outputChannelInfo.swapWith (newOutChans); - } - - //============================================================================== - StringArray getSources (bool input) - { - StringArray s; - HeapBlock types; - const int num = getAllDataSourcesForDevice (deviceID, types); - - for (int i = 0; i < num; ++i) - { - AudioValueTranslation avt; - char buffer[256]; - - avt.mInputData = &(types[i]); - avt.mInputDataSize = sizeof (UInt32); - avt.mOutputData = buffer; - avt.mOutputDataSize = 256; - - UInt32 transSize = sizeof (avt); - - AudioObjectPropertyAddress pa; - pa.mSelector = kAudioDevicePropertyDataSourceNameForID; - pa.mScope = input ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput; - pa.mElement = kAudioObjectPropertyElementMaster; - - if (OK (AudioObjectGetPropertyData (deviceID, &pa, 0, nullptr, &transSize, &avt))) - s.add (buffer); - } - - return s; - } - - int getCurrentSourceIndex (bool input) const - { - OSType currentSourceID = 0; - UInt32 size = sizeof (currentSourceID); - int result = -1; - - AudioObjectPropertyAddress pa; - pa.mSelector = kAudioDevicePropertyDataSource; - pa.mScope = input ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput; - pa.mElement = kAudioObjectPropertyElementMaster; - - if (deviceID != 0) - { - if (OK (AudioObjectGetPropertyData (deviceID, &pa, 0, nullptr, &size, ¤tSourceID))) - { - HeapBlock types; - const int num = getAllDataSourcesForDevice (deviceID, types); - - for (int i = 0; i < num; ++i) - { - if (types[num] == currentSourceID) - { - result = i; - break; - } - } - } - } - - return result; - } - - void setCurrentSourceIndex (int index, bool input) - { - if (deviceID != 0) - { - HeapBlock types; - const int num = getAllDataSourcesForDevice (deviceID, types); - - if (isPositiveAndBelow (index, num)) - { - AudioObjectPropertyAddress pa; - pa.mSelector = kAudioDevicePropertyDataSource; - pa.mScope = input ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput; - pa.mElement = kAudioObjectPropertyElementMaster; - - OSType typeId = types[index]; - - OK (AudioObjectSetPropertyData (deviceID, &pa, 0, 0, sizeof (typeId), &typeId)); - } - } - } - - //============================================================================== - String reopen (const BigInteger& inputChannels, - const BigInteger& outputChannels, - double newSampleRate, int bufferSizeSamples) - { - String error; - callbacksAllowed = false; - stopTimer(); - - stop (false); - - activeInputChans = inputChannels; - activeInputChans.setRange (inChanNames.size(), - activeInputChans.getHighestBit() + 1 - inChanNames.size(), - false); - - activeOutputChans = outputChannels; - activeOutputChans.setRange (outChanNames.size(), - activeOutputChans.getHighestBit() + 1 - outChanNames.size(), - false); - - numInputChans = activeInputChans.countNumberOfSetBits(); - numOutputChans = activeOutputChans.countNumberOfSetBits(); - - // set sample rate - AudioObjectPropertyAddress pa; - pa.mSelector = kAudioDevicePropertyNominalSampleRate; - pa.mScope = kAudioObjectPropertyScopeWildcard; - pa.mElement = kAudioObjectPropertyElementMaster; - Float64 sr = newSampleRate; - - if (! OK (AudioObjectSetPropertyData (deviceID, &pa, 0, 0, sizeof (sr), &sr))) - { - error = "Couldn't change sample rate"; - } - else - { - // change buffer size - UInt32 framesPerBuf = (UInt32) bufferSizeSamples; - pa.mSelector = kAudioDevicePropertyBufferFrameSize; - - if (! OK (AudioObjectSetPropertyData (deviceID, &pa, 0, 0, sizeof (framesPerBuf), &framesPerBuf))) - { - error = "Couldn't change buffer size"; - } - else - { - // Annoyingly, after changing the rate and buffer size, some devices fail to - // correctly report their new settings until some random time in the future, so - // after calling updateDetailsFromDevice, we need to manually bodge these values - // to make sure we're using the correct numbers.. - updateDetailsFromDevice(); - sampleRate = newSampleRate; - bufferSize = bufferSizeSamples; - - if (sampleRates.size() == 0) - error = "Device has no available sample-rates"; - else if (bufferSizes.size() == 0) - error = "Device has no available buffer-sizes"; - } - } - - callbacksAllowed = true; - return error; - } - - bool start() - { - if (! started) - { - callback = nullptr; - - if (deviceID != 0) - { - #if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5 - if (OK (AudioDeviceAddIOProc (deviceID, audioIOProc, this))) - #else - if (OK (AudioDeviceCreateIOProcID (deviceID, audioIOProc, this, &audioProcID))) - #endif - { - if (OK (AudioDeviceStart (deviceID, audioIOProc))) - { - started = true; - } - else - { - #if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5 - OK (AudioDeviceRemoveIOProc (deviceID, audioIOProc)); - #else - OK (AudioDeviceDestroyIOProcID (deviceID, audioProcID)); - audioProcID = 0; - #endif - } - } - } - } - - return started; - } - - void setCallback (AudioIODeviceCallback* cb) - { - const ScopedLock sl (callbackLock); - callback = cb; - } - - void stop (bool leaveInterruptRunning) - { - { - const ScopedLock sl (callbackLock); - callback = nullptr; - } - - if (started - && (deviceID != 0) - && ! leaveInterruptRunning) - { - OK (AudioDeviceStop (deviceID, audioIOProc)); - - #if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5 - OK (AudioDeviceRemoveIOProc (deviceID, audioIOProc)); - #else - OK (AudioDeviceDestroyIOProcID (deviceID, audioProcID)); - audioProcID = 0; - #endif - - started = false; - - { const ScopedLock sl (callbackLock); } - - // wait until it's definately stopped calling back.. - for (int i = 40; --i >= 0;) - { - Thread::sleep (50); - - UInt32 running = 0; - UInt32 size = sizeof (running); - - AudioObjectPropertyAddress pa; - pa.mSelector = kAudioDevicePropertyDeviceIsRunning; - pa.mScope = kAudioObjectPropertyScopeWildcard; - pa.mElement = kAudioObjectPropertyElementMaster; - - OK (AudioObjectGetPropertyData (deviceID, &pa, 0, nullptr, &size, &running)); - - if (running == 0) - break; - } - - const ScopedLock sl (callbackLock); - } - } - - double getSampleRate() const { return sampleRate; } - int getBufferSize() const { return bufferSize; } - - void audioCallback (const AudioBufferList* inInputData, - AudioBufferList* outOutputData) - { - const ScopedLock sl (callbackLock); - - if (callback != nullptr) - { - for (int i = numInputChans; --i >= 0;) - { - const CallbackDetailsForChannel& info = inputChannelInfo.getReference(i); - float* dest = tempInputBuffers [i]; - const float* src = ((const float*) inInputData->mBuffers[info.streamNum].mData) - + info.dataOffsetSamples; - const int stride = info.dataStrideSamples; - - if (stride != 0) // if this is zero, info is invalid - { - for (int j = bufferSize; --j >= 0;) - { - *dest++ = *src; - src += stride; - } - } - } - - callback->audioDeviceIOCallback (const_cast (tempInputBuffers.getData()), - numInputChans, - tempOutputBuffers, - numOutputChans, - bufferSize); - - for (int i = numOutputChans; --i >= 0;) - { - const CallbackDetailsForChannel& info = outputChannelInfo.getReference(i); - const float* src = tempOutputBuffers [i]; - float* dest = ((float*) outOutputData->mBuffers[info.streamNum].mData) - + info.dataOffsetSamples; - const int stride = info.dataStrideSamples; - - if (stride != 0) // if this is zero, info is invalid - { - for (int j = bufferSize; --j >= 0;) - { - *dest = *src++; - dest += stride; - } - } - } - } - else - { - for (UInt32 i = 0; i < outOutputData->mNumberBuffers; ++i) - zeromem (outOutputData->mBuffers[i].mData, - outOutputData->mBuffers[i].mDataByteSize); - } - } - - // called by callbacks - void deviceDetailsChanged() - { - if (callbacksAllowed) - startTimer (100); - } - - void timerCallback() override - { - JUCE_COREAUDIOLOG ("Device changed"); - - stopTimer(); - const double oldSampleRate = sampleRate; - const int oldBufferSize = bufferSize; - updateDetailsFromDevice(); - - if (oldBufferSize != bufferSize || oldSampleRate != sampleRate) - owner.restart(); - } - - //============================================================================== - CoreAudioIODevice& owner; - int inputLatency, outputLatency; - int bitDepth; - BigInteger activeInputChans, activeOutputChans; - StringArray inChanNames, outChanNames; - Array sampleRates; - Array bufferSizes; - AudioIODeviceCallback* callback; - #if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 - AudioDeviceIOProcID audioProcID; - #endif - -private: - CriticalSection callbackLock; - AudioDeviceID deviceID; - bool started; - double sampleRate; - int bufferSize; - HeapBlock audioBuffer; - int numInputChans, numOutputChans; - bool callbacksAllowed; - - Array inputChannelInfo, outputChannelInfo; - HeapBlock tempInputBuffers, tempOutputBuffers; - - //============================================================================== - static OSStatus audioIOProc (AudioDeviceID /*inDevice*/, - const AudioTimeStamp* /*inNow*/, - const AudioBufferList* inInputData, - const AudioTimeStamp* /*inInputTime*/, - AudioBufferList* outOutputData, - const AudioTimeStamp* /*inOutputTime*/, - void* device) - { - static_cast (device)->audioCallback (inInputData, outOutputData); - return noErr; - } - - static OSStatus deviceListenerProc (AudioDeviceID /*inDevice*/, UInt32 /*inLine*/, const AudioObjectPropertyAddress* pa, void* inClientData) - { - CoreAudioInternal* const intern = static_cast (inClientData); - - switch (pa->mSelector) - { - case kAudioDevicePropertyBufferSize: - case kAudioDevicePropertyBufferFrameSize: - case kAudioDevicePropertyNominalSampleRate: - case kAudioDevicePropertyStreamFormat: - case kAudioDevicePropertyDeviceIsAlive: - case kAudioStreamPropertyPhysicalFormat: - intern->deviceDetailsChanged(); - break; - - case kAudioDevicePropertyBufferSizeRange: - case kAudioDevicePropertyVolumeScalar: - case kAudioDevicePropertyMute: - case kAudioDevicePropertyPlayThru: - case kAudioDevicePropertyDataSource: - case kAudioDevicePropertyDeviceIsRunning: - break; - } - - return noErr; - } - - //============================================================================== - static int getAllDataSourcesForDevice (AudioDeviceID deviceID, HeapBlock& types) - { - AudioObjectPropertyAddress pa; - pa.mSelector = kAudioDevicePropertyDataSources; - pa.mScope = kAudioObjectPropertyScopeWildcard; - pa.mElement = kAudioObjectPropertyElementMaster; - UInt32 size = 0; - - if (deviceID != 0 - && AudioObjectGetPropertyDataSize (deviceID, &pa, 0, nullptr, &size) == noErr) - { - types.calloc (size, 1); - - if (AudioObjectGetPropertyData (deviceID, &pa, 0, nullptr, &size, types) == noErr) - return size / (int) sizeof (OSType); - } - - return 0; - } - - bool OK (const OSStatus errorCode) const - { - if (errorCode == noErr) - return true; - - const String errorMessage ("CoreAudio error: " + String::toHexString ((int) errorCode)); - JUCE_COREAUDIOLOG (errorMessage); - - if (callback != nullptr) - callback->audioDeviceError (errorMessage); - - return false; - } - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (CoreAudioInternal) -}; - - -//============================================================================== -class CoreAudioIODevice : public AudioIODevice -{ -public: - CoreAudioIODevice (const String& deviceName, - AudioDeviceID inputDeviceId, const int inputIndex_, - AudioDeviceID outputDeviceId, const int outputIndex_) - : AudioIODevice (deviceName, "CoreAudio"), - inputIndex (inputIndex_), - outputIndex (outputIndex_), - isOpen_ (false), - isStarted (false) - { - CoreAudioInternal* device = nullptr; - - if (outputDeviceId == 0 || outputDeviceId == inputDeviceId) - { - jassert (inputDeviceId != 0); - device = new CoreAudioInternal (*this, inputDeviceId); - } - else - { - device = new CoreAudioInternal (*this, outputDeviceId); - } - - internal = device; - jassert (device != nullptr); - - AudioObjectPropertyAddress pa; - pa.mSelector = kAudioObjectPropertySelectorWildcard; - pa.mScope = kAudioObjectPropertyScopeWildcard; - pa.mElement = kAudioObjectPropertyElementWildcard; - - AudioObjectAddPropertyListener (kAudioObjectSystemObject, &pa, hardwareListenerProc, internal); - } - - ~CoreAudioIODevice() - { - close(); - - AudioObjectPropertyAddress pa; - pa.mSelector = kAudioObjectPropertySelectorWildcard; - pa.mScope = kAudioObjectPropertyScopeWildcard; - pa.mElement = kAudioObjectPropertyElementWildcard; - - AudioObjectRemovePropertyListener (kAudioObjectSystemObject, &pa, hardwareListenerProc, internal); - } - - StringArray getOutputChannelNames() override { return internal->outChanNames; } - StringArray getInputChannelNames() override { return internal->inChanNames; } - - bool isOpen() override { return isOpen_; } - - Array getAvailableSampleRates() override { return internal->sampleRates; } - Array getAvailableBufferSizes() override { return internal->bufferSizes; } - - double getCurrentSampleRate() override { return internal->getSampleRate(); } - int getCurrentBitDepth() override { return internal->bitDepth; } - int getCurrentBufferSizeSamples() override { return internal->getBufferSize(); } - - int getDefaultBufferSize() override - { - int best = 0; - - for (int i = 0; best < 512 && i < internal->bufferSizes.size(); ++i) - best = internal->bufferSizes.getUnchecked(i); - - if (best == 0) - best = 512; - - return best; - } - - String open (const BigInteger& inputChannels, - const BigInteger& outputChannels, - double sampleRate, int bufferSizeSamples) override - { - isOpen_ = true; - - if (bufferSizeSamples <= 0) - bufferSizeSamples = getDefaultBufferSize(); - - lastError = internal->reopen (inputChannels, outputChannels, sampleRate, bufferSizeSamples); - - JUCE_COREAUDIOLOG ("Opened: " << getName()); - JUCE_COREAUDIOLOG ("Latencies: " << getInputLatencyInSamples() << ' ' << getOutputLatencyInSamples()); - - isOpen_ = lastError.isEmpty(); - return lastError; - } - - void close() override - { - isOpen_ = false; - internal->stop (false); - } - - void restart() - { - JUCE_COREAUDIOLOG ("Restarting"); - AudioIODeviceCallback* oldCallback = internal->callback; - stop(); - start (oldCallback); - } - - BigInteger getActiveOutputChannels() const override { return internal->activeOutputChans; } - BigInteger getActiveInputChannels() const override { return internal->activeInputChans; } - - int getOutputLatencyInSamples() override - { - // this seems like a good guess at getting the latency right - comparing - // this with a round-trip measurement, it gets it to within a few millisecs - // for the built-in mac soundcard - return internal->outputLatency; - } - - int getInputLatencyInSamples() override - { - return internal->inputLatency; - } - - void start (AudioIODeviceCallback* callback) override - { - if (! isStarted) - { - if (callback != nullptr) - callback->audioDeviceAboutToStart (this); - - isStarted = internal->start(); - - if (isStarted) - internal->setCallback (callback); - } - } - - void stop() override - { - if (isStarted) - { - AudioIODeviceCallback* const lastCallback = internal->callback; - - isStarted = false; - internal->stop (true); - - if (lastCallback != nullptr) - lastCallback->audioDeviceStopped(); - } - } - - bool isPlaying() override - { - if (internal->callback == nullptr) - isStarted = false; - - return isStarted; - } - - String getLastError() override - { - return lastError; - } - - int inputIndex, outputIndex; - -private: - ScopedPointer internal; - bool isOpen_, isStarted; - String lastError; - - static OSStatus hardwareListenerProc (AudioDeviceID /*inDevice*/, UInt32 /*inLine*/, const AudioObjectPropertyAddress* pa, void* inClientData) - { - switch (pa->mSelector) - { - case kAudioHardwarePropertyDevices: - static_cast (inClientData)->deviceDetailsChanged(); - break; - - case kAudioHardwarePropertyDefaultOutputDevice: - case kAudioHardwarePropertyDefaultInputDevice: - case kAudioHardwarePropertyDefaultSystemOutputDevice: - break; - } - - return noErr; - } - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (CoreAudioIODevice) -}; - -//============================================================================== -class AudioIODeviceCombiner : public AudioIODevice, - private Thread -{ -public: - AudioIODeviceCombiner (const String& deviceName) - : AudioIODevice (deviceName, "CoreAudio"), - Thread (deviceName), callback (nullptr), - currentSampleRate (0), currentBufferSize (0), active (false) - { - } - - ~AudioIODeviceCombiner() - { - close(); - devices.clear(); - } - - void addDevice (AudioIODevice* device, bool useInputs, bool useOutputs) - { - jassert (device != nullptr); - jassert (! isOpen()); - jassert (! device->isOpen()); - devices.add (new DeviceWrapper (*this, device, useInputs, useOutputs)); - } - - Array getDevices() const - { - Array devs; - - for (int i = 0; i < devices.size(); ++i) - devs.add (devices.getUnchecked(i)->device); - - return devs; - } - - StringArray getOutputChannelNames() override - { - StringArray names; - - for (int i = 0; i < devices.size(); ++i) - names.addArray (devices.getUnchecked(i)->getOutputChannelNames()); - - names.appendNumbersToDuplicates (false, true); - return names; - } - - StringArray getInputChannelNames() override - { - StringArray names; - - for (int i = 0; i < devices.size(); ++i) - names.addArray (devices.getUnchecked(i)->getInputChannelNames()); - - names.appendNumbersToDuplicates (false, true); - return names; - } - - Array getAvailableSampleRates() override - { - Array commonRates; - - for (int i = 0; i < devices.size(); ++i) - { - Array rates (devices.getUnchecked(i)->device->getAvailableSampleRates()); - - if (i == 0) - commonRates = rates; - else - commonRates.removeValuesNotIn (rates); - } - - return commonRates; - } - - Array getAvailableBufferSizes() override - { - Array commonSizes; - - for (int i = 0; i < devices.size(); ++i) - { - Array sizes (devices.getUnchecked(i)->device->getAvailableBufferSizes()); - - if (i == 0) - commonSizes = sizes; - else - commonSizes.removeValuesNotIn (sizes); - } - - return commonSizes; - } - - bool isOpen() override { return active; } - bool isPlaying() override { return callback != nullptr; } - double getCurrentSampleRate() override { return currentSampleRate; } - int getCurrentBufferSizeSamples() override { return currentBufferSize; } - - int getCurrentBitDepth() override - { - int depth = 32; - - for (int i = 0; i < devices.size(); ++i) - depth = jmin (depth, devices.getUnchecked(i)->device->getCurrentBitDepth()); - - return depth; - } - - int getDefaultBufferSize() override - { - int size = 0; - - for (int i = 0; i < devices.size(); ++i) - size = jmax (size, devices.getUnchecked(i)->device->getDefaultBufferSize()); - - return size; - } - - String open (const BigInteger& inputChannels, - const BigInteger& outputChannels, - double sampleRate, int bufferSize) override - { - close(); - active = true; - - if (bufferSize <= 0) - bufferSize = getDefaultBufferSize(); - - if (sampleRate <= 0) - { - Array rates (getAvailableSampleRates()); - - for (int i = 0; i < rates.size() && sampleRate < 44100.0; ++i) - sampleRate = rates.getUnchecked(i); - } - - currentSampleRate = sampleRate; - currentBufferSize = bufferSize; - - const int fifoSize = bufferSize * 3 + 1; - int totalInputChanIndex = 0, totalOutputChanIndex = 0; - int chanIndex = 0; - - for (int i = 0; i < devices.size(); ++i) - { - DeviceWrapper& d = *devices.getUnchecked(i); - - BigInteger ins (inputChannels >> totalInputChanIndex); - BigInteger outs (outputChannels >> totalOutputChanIndex); - - int numIns = d.getInputChannelNames().size(); - int numOuts = d.getOutputChannelNames().size(); - - totalInputChanIndex += numIns; - totalOutputChanIndex += numOuts; - - String err = d.open (ins, outs, sampleRate, bufferSize, - chanIndex, fifoSize); - - if (err.isNotEmpty()) - { - close(); - lastError = err; - return err; - } - - chanIndex += d.numInputChans + d.numOutputChans; - } - - fifos.setSize (chanIndex, fifoSize); - fifos.clear(); - startThread (9); - - return String(); - } - - void close() override - { - stop(); - stopThread (10000); - fifos.clear(); - active = false; - - for (int i = 0; i < devices.size(); ++i) - devices.getUnchecked(i)->close(); - } - - BigInteger getActiveOutputChannels() const override - { - BigInteger chans; - int start = 0; - - for (int i = 0; i < devices.size(); ++i) - { - const int numChans = devices.getUnchecked(i)->getOutputChannelNames().size(); - - if (numChans > 0) - { - chans |= (devices.getUnchecked(i)->device->getActiveOutputChannels() << start); - start += numChans; - } - } - - return chans; - } - - BigInteger getActiveInputChannels() const override - { - BigInteger chans; - int start = 0; - - for (int i = 0; i < devices.size(); ++i) - { - const int numChans = devices.getUnchecked(i)->getInputChannelNames().size(); - - if (numChans > 0) - { - chans |= (devices.getUnchecked(i)->device->getActiveInputChannels() << start); - start += numChans; - } - } - - return chans; - } - - int getOutputLatencyInSamples() override - { - int lat = 0; - - for (int i = 0; i < devices.size(); ++i) - lat = jmax (lat, devices.getUnchecked(i)->device->getOutputLatencyInSamples()); - - return lat + currentBufferSize * 2; - } - - int getInputLatencyInSamples() override - { - int lat = 0; - - for (int i = 0; i < devices.size(); ++i) - lat = jmax (lat, devices.getUnchecked(i)->device->getInputLatencyInSamples()); - - return lat + currentBufferSize * 2; - } - - void start (AudioIODeviceCallback* newCallback) override - { - if (callback != newCallback) - { - stop(); - fifos.clear(); - - for (int i = 0; i < devices.size(); ++i) - devices.getUnchecked(i)->start(); - - if (newCallback != nullptr) - newCallback->audioDeviceAboutToStart (this); - - const ScopedLock sl (callbackLock); - callback = newCallback; - } - } - - void stop() override - { - AudioIODeviceCallback* lastCallback = nullptr; - - { - const ScopedLock sl (callbackLock); - std::swap (callback, lastCallback); - } - - for (int i = 0; i < devices.size(); ++i) - devices.getUnchecked(i)->device->stop(); - - if (lastCallback != nullptr) - lastCallback->audioDeviceStopped(); - } - - String getLastError() override - { - return lastError; - } - -private: - CriticalSection callbackLock; - AudioIODeviceCallback* callback; - double currentSampleRate; - int currentBufferSize; - bool active; - String lastError; - - AudioSampleBuffer fifos; - - void run() override - { - const int numSamples = currentBufferSize; - - AudioSampleBuffer buffer (fifos.getNumChannels(), numSamples); - buffer.clear(); - - Array inputChans; - Array outputChans; - - for (int i = 0; i < devices.size(); ++i) - { - DeviceWrapper& d = *devices.getUnchecked(i); - - for (int j = 0; j < d.numInputChans; ++j) inputChans.add (buffer.getReadPointer (d.inputIndex + j)); - for (int j = 0; j < d.numOutputChans; ++j) outputChans.add (buffer.getWritePointer (d.outputIndex + j)); - } - - const int numInputChans = inputChans.size(); - const int numOutputChans = outputChans.size(); - - inputChans.add (nullptr); - outputChans.add (nullptr); - - const int blockSizeMs = jmax (1, (int) (1000 * numSamples / currentSampleRate)); - - jassert (numInputChans + numOutputChans == buffer.getNumChannels()); - - while (! threadShouldExit()) - { - readInput (buffer, numSamples, blockSizeMs); - - bool didCallback = true; - - { - const ScopedLock sl (callbackLock); - - if (callback != nullptr) - callback->audioDeviceIOCallback ((const float**) inputChans.getRawDataPointer(), numInputChans, - outputChans.getRawDataPointer(), numOutputChans, numSamples); - else - didCallback = false; - } - - if (didCallback) - { - pushOutputData (buffer, numSamples, blockSizeMs); - } - else - { - for (int i = 0; i < numOutputChans; ++i) - FloatVectorOperations::clear (outputChans[i], numSamples); - - reset(); - } - } - } - - void reset() - { - for (int i = 0; i < devices.size(); ++i) - devices.getUnchecked(i)->reset(); - } - - void underrun() - { - } - - void readInput (AudioSampleBuffer& buffer, const int numSamples, const int blockSizeMs) - { - for (int i = 0; i < devices.size(); ++i) - { - DeviceWrapper& d = *devices.getUnchecked(i); - d.done = (d.numInputChans == 0); - } - - for (int tries = 5;;) - { - bool anyRemaining = false; - - for (int i = 0; i < devices.size(); ++i) - { - DeviceWrapper& d = *devices.getUnchecked(i); - - if (! d.done) - { - if (d.isInputReady (numSamples)) - { - d.readInput (buffer, numSamples); - d.done = true; - } - else - anyRemaining = true; - } - } - - if (! anyRemaining) - return; - - if (--tries == 0) - break; - - wait (blockSizeMs); - } - - for (int j = 0; j < devices.size(); ++j) - { - DeviceWrapper& d = *devices.getUnchecked(j); - - if (! d.done) - for (int i = 0; i < d.numInputChans; ++i) - buffer.clear (d.inputIndex + i, 0, numSamples); - } - } - - void pushOutputData (AudioSampleBuffer& buffer, const int numSamples, const int blockSizeMs) - { - for (int i = 0; i < devices.size(); ++i) - { - DeviceWrapper& d = *devices.getUnchecked(i); - d.done = (d.numOutputChans == 0); - } - - for (int tries = 5;;) - { - bool anyRemaining = false; - - for (int i = 0; i < devices.size(); ++i) - { - DeviceWrapper& d = *devices.getUnchecked(i); - - if (! d.done) - { - if (d.isOutputReady (numSamples)) - { - d.pushOutputData (buffer, numSamples); - d.done = true; - } - else - anyRemaining = true; - } - } - - if ((! anyRemaining) || --tries == 0) - return; - - wait (blockSizeMs); - } - } - - //============================================================================== - struct DeviceWrapper : private AudioIODeviceCallback - { - DeviceWrapper (AudioIODeviceCombiner& cd, AudioIODevice* d, bool useIns, bool useOuts) - : owner (cd), device (d), inputIndex (0), outputIndex (0), - useInputs (useIns), useOutputs (useOuts), - inputFifo (32), outputFifo (32), done (false) - { - } - - ~DeviceWrapper() - { - close(); - } - - String open (const BigInteger& inputChannels, const BigInteger& outputChannels, - double sampleRate, int bufferSize, - int channelIndex, - int fifoSize) - { - inputFifo.setTotalSize (fifoSize); - outputFifo.setTotalSize (fifoSize); - inputFifo.reset(); - outputFifo.reset(); - - String err (device->open (useInputs ? inputChannels : BigInteger(), - useOutputs ? outputChannels : BigInteger(), - sampleRate, bufferSize)); - - numInputChans = useInputs ? device->getActiveInputChannels().countNumberOfSetBits() : 0; - numOutputChans = useOutputs ? device->getActiveOutputChannels().countNumberOfSetBits() : 0; - - inputIndex = channelIndex; - outputIndex = channelIndex + numInputChans; - - return err; - } - - void close() - { - device->close(); - } - - void start() - { - reset(); - device->start (this); - } - - void reset() - { - inputFifo.reset(); - outputFifo.reset(); - } - - StringArray getOutputChannelNames() const { return useOutputs ? device->getOutputChannelNames() : StringArray(); } - StringArray getInputChannelNames() const { return useInputs ? device->getInputChannelNames() : StringArray(); } - - bool isInputReady (int numSamples) const noexcept - { - return numInputChans == 0 || inputFifo.getNumReady() >= numSamples; - } - - void readInput (AudioSampleBuffer& destBuffer, int numSamples) - { - if (numInputChans == 0) - return; - - int start1, size1, start2, size2; - inputFifo.prepareToRead (numSamples, start1, size1, start2, size2); - - for (int i = 0; i < numInputChans; ++i) - { - const int index = inputIndex + i; - float* const dest = destBuffer.getWritePointer (index); - const float* const src = owner.fifos.getReadPointer (index); - - if (size1 > 0) FloatVectorOperations::copy (dest, src + start1, size1); - if (size2 > 0) FloatVectorOperations::copy (dest + size1, src + start2, size2); - } - - inputFifo.finishedRead (size1 + size2); - } - - bool isOutputReady (int numSamples) const noexcept - { - return numOutputChans == 0 || outputFifo.getFreeSpace() >= numSamples; - } - - void pushOutputData (AudioSampleBuffer& srcBuffer, int numSamples) - { - if (numOutputChans == 0) - return; - - int start1, size1, start2, size2; - outputFifo.prepareToWrite (numSamples, start1, size1, start2, size2); - - for (int i = 0; i < numOutputChans; ++i) - { - const int index = outputIndex + i; - float* const dest = owner.fifos.getWritePointer (index); - const float* const src = srcBuffer.getReadPointer (index); - - if (size1 > 0) FloatVectorOperations::copy (dest + start1, src, size1); - if (size2 > 0) FloatVectorOperations::copy (dest + start2, src + size1, size2); - } - - outputFifo.finishedWrite (size1 + size2); - } - - void audioDeviceIOCallback (const float** inputChannelData, int numInputChannels, - float** outputChannelData, int numOutputChannels, - int numSamples) override - { - AudioSampleBuffer& buf = owner.fifos; - - if (numInputChannels > 0) - { - int start1, size1, start2, size2; - inputFifo.prepareToWrite (numSamples, start1, size1, start2, size2); - - if (size1 + size2 < numSamples) - { - inputFifo.reset(); - inputFifo.prepareToWrite (numSamples, start1, size1, start2, size2); - } - - for (int i = 0; i < numInputChannels; ++i) - { - float* const dest = buf.getWritePointer (inputIndex + i); - const float* const src = inputChannelData[i]; - - if (size1 > 0) FloatVectorOperations::copy (dest + start1, src, size1); - if (size2 > 0) FloatVectorOperations::copy (dest + start2, src + size1, size2); - } - - inputFifo.finishedWrite (size1 + size2); - - if (numSamples > size1 + size2) - { - for (int i = 0; i < numInputChans; ++i) - buf.clear (inputIndex + i, size1 + size2, numSamples - (size1 + size2)); - - owner.underrun(); - } - } - - if (numOutputChannels > 0) - { - int start1, size1, start2, size2; - outputFifo.prepareToRead (numSamples, start1, size1, start2, size2); - - if (size1 + size2 < numSamples) - { - Thread::sleep (1); - outputFifo.prepareToRead (numSamples, start1, size1, start2, size2); - } - - for (int i = 0; i < numOutputChannels; ++i) - { - float* const dest = outputChannelData[i]; - const float* const src = buf.getReadPointer (outputIndex + i); - - if (size1 > 0) FloatVectorOperations::copy (dest, src + start1, size1); - if (size2 > 0) FloatVectorOperations::copy (dest + size1, src + start2, size2); - } - - outputFifo.finishedRead (size1 + size2); - - if (numSamples > size1 + size2) - { - for (int i = 0; i < numOutputChannels; ++i) - FloatVectorOperations::clear (outputChannelData[i] + (size1 + size2), numSamples - (size1 + size2)); - - owner.underrun(); - } - } - - owner.notify(); - } - - void audioDeviceAboutToStart (AudioIODevice*) override {} - void audioDeviceStopped() override {} - - void audioDeviceError (const String& errorMessage) override - { - const ScopedLock sl (owner.callbackLock); - - if (owner.callback != nullptr) - owner.callback->audioDeviceError (errorMessage); - } - - AudioIODeviceCombiner& owner; - ScopedPointer device; - int inputIndex, numInputChans, outputIndex, numOutputChans; - bool useInputs, useOutputs; - AbstractFifo inputFifo, outputFifo; - bool done; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (DeviceWrapper) - }; - - OwnedArray devices; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioIODeviceCombiner) -}; - - -//============================================================================== -class CoreAudioIODeviceType : public AudioIODeviceType -{ -public: - CoreAudioIODeviceType() - : AudioIODeviceType ("CoreAudio"), - hasScanned (false) - { - AudioObjectPropertyAddress pa; - pa.mSelector = kAudioHardwarePropertyDevices; - pa.mScope = kAudioObjectPropertyScopeWildcard; - pa.mElement = kAudioObjectPropertyElementWildcard; - - AudioObjectAddPropertyListener (kAudioObjectSystemObject, &pa, hardwareListenerProc, this); - } - - ~CoreAudioIODeviceType() - { - AudioObjectPropertyAddress pa; - pa.mSelector = kAudioHardwarePropertyDevices; - pa.mScope = kAudioObjectPropertyScopeWildcard; - pa.mElement = kAudioObjectPropertyElementWildcard; - - AudioObjectRemovePropertyListener (kAudioObjectSystemObject, &pa, hardwareListenerProc, this); - } - - //============================================================================== - void scanForDevices() - { - hasScanned = true; - - inputDeviceNames.clear(); - outputDeviceNames.clear(); - inputIds.clear(); - outputIds.clear(); - - UInt32 size; - - AudioObjectPropertyAddress pa; - pa.mSelector = kAudioHardwarePropertyDevices; - pa.mScope = kAudioObjectPropertyScopeWildcard; - pa.mElement = kAudioObjectPropertyElementMaster; - - if (AudioObjectGetPropertyDataSize (kAudioObjectSystemObject, &pa, 0, nullptr, &size) == noErr) - { - HeapBlock devs; - devs.calloc (size, 1); - - if (AudioObjectGetPropertyData (kAudioObjectSystemObject, &pa, 0, nullptr, &size, devs) == noErr) - { - const int num = size / (int) sizeof (AudioDeviceID); - for (int i = 0; i < num; ++i) - { - char name [1024]; - size = sizeof (name); - pa.mSelector = kAudioDevicePropertyDeviceName; - - if (AudioObjectGetPropertyData (devs[i], &pa, 0, nullptr, &size, name) == noErr) - { - const String nameString (String::fromUTF8 (name, (int) strlen (name))); - const int numIns = getNumChannels (devs[i], true); - const int numOuts = getNumChannels (devs[i], false); - - if (numIns > 0) - { - inputDeviceNames.add (nameString); - inputIds.add (devs[i]); - } - - if (numOuts > 0) - { - outputDeviceNames.add (nameString); - outputIds.add (devs[i]); - } - } - } - } - } - - inputDeviceNames.appendNumbersToDuplicates (false, true); - outputDeviceNames.appendNumbersToDuplicates (false, true); - } - - StringArray getDeviceNames (bool wantInputNames) const - { - jassert (hasScanned); // need to call scanForDevices() before doing this - - return wantInputNames ? inputDeviceNames - : outputDeviceNames; - } - - int getDefaultDeviceIndex (bool forInput) const - { - jassert (hasScanned); // need to call scanForDevices() before doing this - - AudioDeviceID deviceID; - UInt32 size = sizeof (deviceID); - - // if they're asking for any input channels at all, use the default input, so we - // get the built-in mic rather than the built-in output with no inputs.. - - AudioObjectPropertyAddress pa; - pa.mSelector = forInput ? kAudioHardwarePropertyDefaultInputDevice - : kAudioHardwarePropertyDefaultOutputDevice; - pa.mScope = kAudioObjectPropertyScopeWildcard; - pa.mElement = kAudioObjectPropertyElementMaster; - - if (AudioObjectGetPropertyData (kAudioObjectSystemObject, &pa, 0, nullptr, &size, &deviceID) == noErr) - { - if (forInput) - { - for (int i = inputIds.size(); --i >= 0;) - if (inputIds[i] == deviceID) - return i; - } - else - { - for (int i = outputIds.size(); --i >= 0;) - if (outputIds[i] == deviceID) - return i; - } - } - - return 0; - } - - int getIndexOfDevice (AudioIODevice* device, bool asInput) const - { - jassert (hasScanned); // need to call scanForDevices() before doing this - - if (CoreAudioIODevice* const d = dynamic_cast (device)) - return asInput ? d->inputIndex - : d->outputIndex; - - if (AudioIODeviceCombiner* const d = dynamic_cast (device)) - { - const Array devs (d->getDevices()); - - for (int i = 0; i < devs.size(); ++i) - { - const int index = getIndexOfDevice (devs.getUnchecked(i), asInput); - - if (index >= 0) - return index; - } - } - - return -1; - } - - bool hasSeparateInputsAndOutputs() const { return true; } - - AudioIODevice* createDevice (const String& outputDeviceName, - const String& inputDeviceName) - { - jassert (hasScanned); // need to call scanForDevices() before doing this - - const int inputIndex = inputDeviceNames.indexOf (inputDeviceName); - const int outputIndex = outputDeviceNames.indexOf (outputDeviceName); - - AudioDeviceID inputDeviceID = inputIds [inputIndex]; - AudioDeviceID outputDeviceID = outputIds [outputIndex]; - - if (inputDeviceID == 0 && outputDeviceID == 0) - return nullptr; - - String combinedName (outputDeviceName.isEmpty() ? inputDeviceName : outputDeviceName); - - if (inputDeviceID == outputDeviceID) - return new CoreAudioIODevice (combinedName, inputDeviceID, inputIndex, outputDeviceID, outputIndex); - - ScopedPointer in, out; - - if (inputDeviceID != 0) - in = new CoreAudioIODevice (inputDeviceName, inputDeviceID, inputIndex, 0, -1); - - if (outputDeviceID != 0) - out = new CoreAudioIODevice (outputDeviceName, 0, -1, outputDeviceID, outputIndex); - - if (in == nullptr) return out.release(); - if (out == nullptr) return in.release(); - - ScopedPointer combo (new AudioIODeviceCombiner (combinedName)); - combo->addDevice (in.release(), true, false); - combo->addDevice (out.release(), false, true); - return combo.release(); - } - - //============================================================================== -private: - StringArray inputDeviceNames, outputDeviceNames; - Array inputIds, outputIds; - - bool hasScanned; - - static int getNumChannels (AudioDeviceID deviceID, bool input) - { - int total = 0; - UInt32 size; - - AudioObjectPropertyAddress pa; - pa.mSelector = kAudioDevicePropertyStreamConfiguration; - pa.mScope = input ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput; - pa.mElement = kAudioObjectPropertyElementMaster; - - if (AudioObjectGetPropertyDataSize (deviceID, &pa, 0, nullptr, &size) == noErr) - { - HeapBlock bufList; - bufList.calloc (size, 1); - - if (AudioObjectGetPropertyData (deviceID, &pa, 0, nullptr, &size, bufList) == noErr) - { - const int numStreams = (int) bufList->mNumberBuffers; - - for (int i = 0; i < numStreams; ++i) - { - const AudioBuffer& b = bufList->mBuffers[i]; - total += b.mNumberChannels; - } - } - } - - return total; - } - - void audioDeviceListChanged() - { - scanForDevices(); - callDeviceChangeListeners(); - } - - static OSStatus hardwareListenerProc (AudioDeviceID, UInt32, const AudioObjectPropertyAddress*, void* clientData) - { - static_cast (clientData)->audioDeviceListChanged(); - return noErr; - } - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (CoreAudioIODeviceType) -}; - -}; - -//============================================================================== -AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_CoreAudio() -{ - return new CoreAudioClasses::CoreAudioIODeviceType(); -} - -#undef JUCE_COREAUDIOLOG diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/native/juce_mac_CoreMidi.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/native/juce_mac_CoreMidi.cpp deleted file mode 100644 index 5f8b3d5a67..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/native/juce_mac_CoreMidi.cpp +++ /dev/null @@ -1,530 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_LOG_COREMIDI_ERRORS - #define JUCE_LOG_COREMIDI_ERRORS 1 -#endif - -namespace CoreMidiHelpers -{ - static bool checkError (const OSStatus err, const int lineNum) - { - if (err == noErr) - return true; - - #if JUCE_LOG_COREMIDI_ERRORS - Logger::writeToLog ("CoreMIDI error: " + String (lineNum) + " - " + String::toHexString ((int) err)); - #endif - - (void) lineNum; - return false; - } - - #undef CHECK_ERROR - #define CHECK_ERROR(a) CoreMidiHelpers::checkError (a, __LINE__) - - //============================================================================== - static String getMidiObjectName (MIDIObjectRef entity) - { - String result; - CFStringRef str = nullptr; - MIDIObjectGetStringProperty (entity, kMIDIPropertyName, &str); - - if (str != nullptr) - { - result = String::fromCFString (str); - CFRelease (str); - } - - return result; - } - - static String getEndpointName (MIDIEndpointRef endpoint, bool isExternal) - { - String result (getMidiObjectName (endpoint)); - - MIDIEntityRef entity = 0; // NB: don't attempt to use nullptr for refs - it fails in some types of build. - MIDIEndpointGetEntity (endpoint, &entity); - - if (entity == 0) - return result; // probably virtual - - if (result.isEmpty()) - result = getMidiObjectName (entity); // endpoint name is empty - try the entity - - // now consider the device's name - MIDIDeviceRef device = 0; - MIDIEntityGetDevice (entity, &device); - - if (device != 0) - { - const String deviceName (getMidiObjectName (device)); - - if (deviceName.isNotEmpty()) - { - // if an external device has only one entity, throw away - // the endpoint name and just use the device name - if (isExternal && MIDIDeviceGetNumberOfEntities (device) < 2) - { - result = deviceName; - } - else if (! result.startsWithIgnoreCase (deviceName)) - { - // prepend the device name to the entity name - result = (deviceName + " " + result).trimEnd(); - } - } - } - - return result; - } - - static String getConnectedEndpointName (MIDIEndpointRef endpoint) - { - String result; - - // Does the endpoint have connections? - CFDataRef connections = nullptr; - int numConnections = 0; - - MIDIObjectGetDataProperty (endpoint, kMIDIPropertyConnectionUniqueID, &connections); - - if (connections != nullptr) - { - numConnections = ((int) CFDataGetLength (connections)) / (int) sizeof (MIDIUniqueID); - - if (numConnections > 0) - { - const SInt32* pid = reinterpret_cast (CFDataGetBytePtr (connections)); - - for (int i = 0; i < numConnections; ++i, ++pid) - { - MIDIUniqueID uid = (MIDIUniqueID) ByteOrder::swapIfLittleEndian ((uint32) *pid); - MIDIObjectRef connObject; - MIDIObjectType connObjectType; - OSStatus err = MIDIObjectFindByUniqueID (uid, &connObject, &connObjectType); - - if (err == noErr) - { - String s; - - if (connObjectType == kMIDIObjectType_ExternalSource - || connObjectType == kMIDIObjectType_ExternalDestination) - { - // Connected to an external device's endpoint (10.3 and later). - s = getEndpointName (static_cast (connObject), true); - } - else - { - // Connected to an external device (10.2) (or something else, catch-all) - s = getMidiObjectName (connObject); - } - - if (s.isNotEmpty()) - { - if (result.isNotEmpty()) - result += ", "; - - result += s; - } - } - } - } - - CFRelease (connections); - } - - if (result.isEmpty()) // Here, either the endpoint had no connections, or we failed to obtain names for them. - result = getEndpointName (endpoint, false); - - return result; - } - - static StringArray findDevices (const bool forInput) - { - const ItemCount num = forInput ? MIDIGetNumberOfSources() - : MIDIGetNumberOfDestinations(); - StringArray s; - - for (ItemCount i = 0; i < num; ++i) - { - MIDIEndpointRef dest = forInput ? MIDIGetSource (i) - : MIDIGetDestination (i); - String name; - - if (dest != 0) - name = getConnectedEndpointName (dest); - - if (name.isEmpty()) - name = ""; - - s.add (name); - } - - return s; - } - - static void globalSystemChangeCallback (const MIDINotification*, void*) - { - // TODO.. Should pass-on this notification.. - } - - static String getGlobalMidiClientName() - { - if (JUCEApplicationBase* const app = JUCEApplicationBase::getInstance()) - return app->getApplicationName(); - - return "JUCE"; - } - - static MIDIClientRef getGlobalMidiClient() - { - static MIDIClientRef globalMidiClient = 0; - - if (globalMidiClient == 0) - { - // Since OSX 10.6, the MIDIClientCreate function will only work - // correctly when called from the message thread! - jassert (MessageManager::getInstance()->isThisTheMessageThread()); - - CFStringRef name = getGlobalMidiClientName().toCFString(); - CHECK_ERROR (MIDIClientCreate (name, &globalSystemChangeCallback, nullptr, &globalMidiClient)); - CFRelease (name); - } - - return globalMidiClient; - } - - //============================================================================== - class MidiPortAndEndpoint - { - public: - MidiPortAndEndpoint (MIDIPortRef p, MIDIEndpointRef ep) - : port (p), endPoint (ep) - { - } - - ~MidiPortAndEndpoint() - { - if (port != 0) - MIDIPortDispose (port); - - if (port == 0 && endPoint != 0) // if port == nullptr, it means we created the endpoint, so it's safe to delete it - MIDIEndpointDispose (endPoint); - } - - void send (const MIDIPacketList* const packets) - { - if (port != 0) - MIDISend (port, endPoint, packets); - else - MIDIReceived (endPoint, packets); - } - - MIDIPortRef port; - MIDIEndpointRef endPoint; - }; - - //============================================================================== - class MidiPortAndCallback; - CriticalSection callbackLock; - Array activeCallbacks; - - class MidiPortAndCallback - { - public: - MidiPortAndCallback (MidiInputCallback& cb) - : input (nullptr), active (false), callback (cb), concatenator (2048) - { - } - - ~MidiPortAndCallback() - { - active = false; - - { - const ScopedLock sl (callbackLock); - activeCallbacks.removeFirstMatchingValue (this); - } - - if (portAndEndpoint != 0 && portAndEndpoint->port != 0) - CHECK_ERROR (MIDIPortDisconnectSource (portAndEndpoint->port, portAndEndpoint->endPoint)); - } - - void handlePackets (const MIDIPacketList* const pktlist) - { - const double time = Time::getMillisecondCounterHiRes() * 0.001; - - const ScopedLock sl (callbackLock); - if (activeCallbacks.contains (this) && active) - { - const MIDIPacket* packet = &pktlist->packet[0]; - - for (unsigned int i = 0; i < pktlist->numPackets; ++i) - { - concatenator.pushMidiData (packet->data, (int) packet->length, time, - input, callback); - - packet = MIDIPacketNext (packet); - } - } - } - - MidiInput* input; - ScopedPointer portAndEndpoint; - volatile bool active; - - private: - MidiInputCallback& callback; - MidiDataConcatenator concatenator; - }; - - static void midiInputProc (const MIDIPacketList* pktlist, void* readProcRefCon, void* /*srcConnRefCon*/) - { - static_cast (readProcRefCon)->handlePackets (pktlist); - } -} - -//============================================================================== -StringArray MidiOutput::getDevices() { return CoreMidiHelpers::findDevices (false); } -int MidiOutput::getDefaultDeviceIndex() { return 0; } - -MidiOutput* MidiOutput::openDevice (int index) -{ - MidiOutput* mo = nullptr; - - if (isPositiveAndBelow (index, (int) MIDIGetNumberOfDestinations())) - { - MIDIEndpointRef endPoint = MIDIGetDestination ((ItemCount) index); - - CFStringRef pname; - if (CHECK_ERROR (MIDIObjectGetStringProperty (endPoint, kMIDIPropertyName, &pname))) - { - MIDIClientRef client = CoreMidiHelpers::getGlobalMidiClient(); - MIDIPortRef port; - - if (client != 0 && CHECK_ERROR (MIDIOutputPortCreate (client, pname, &port))) - { - mo = new MidiOutput(); - mo->internal = new CoreMidiHelpers::MidiPortAndEndpoint (port, endPoint); - } - - CFRelease (pname); - } - } - - return mo; -} - -MidiOutput* MidiOutput::createNewDevice (const String& deviceName) -{ - MidiOutput* mo = nullptr; - MIDIClientRef client = CoreMidiHelpers::getGlobalMidiClient(); - - MIDIEndpointRef endPoint; - CFStringRef name = deviceName.toCFString(); - - if (client != 0 && CHECK_ERROR (MIDISourceCreate (client, name, &endPoint))) - { - mo = new MidiOutput(); - mo->internal = new CoreMidiHelpers::MidiPortAndEndpoint (0, endPoint); - } - - CFRelease (name); - return mo; -} - -MidiOutput::~MidiOutput() -{ - stopBackgroundThread(); - - delete static_cast (internal); -} - -void MidiOutput::sendMessageNow (const MidiMessage& message) -{ - #if JUCE_IOS - const MIDITimeStamp timeStamp = mach_absolute_time(); - #else - const MIDITimeStamp timeStamp = AudioGetCurrentHostTime(); - #endif - - HeapBlock allocatedPackets; - MIDIPacketList stackPacket; - MIDIPacketList* packetToSend = &stackPacket; - const size_t dataSize = (size_t) message.getRawDataSize(); - - if (message.isSysEx()) - { - const int maxPacketSize = 256; - int pos = 0, bytesLeft = (int) dataSize; - const int numPackets = (bytesLeft + maxPacketSize - 1) / maxPacketSize; - allocatedPackets.malloc ((size_t) (32 * (size_t) numPackets + dataSize), 1); - packetToSend = allocatedPackets; - packetToSend->numPackets = (UInt32) numPackets; - - MIDIPacket* p = packetToSend->packet; - - for (int i = 0; i < numPackets; ++i) - { - p->timeStamp = timeStamp; - p->length = (UInt16) jmin (maxPacketSize, bytesLeft); - memcpy (p->data, message.getRawData() + pos, p->length); - pos += p->length; - bytesLeft -= p->length; - p = MIDIPacketNext (p); - } - } - else if (dataSize < 65536) // max packet size - { - const size_t stackCapacity = sizeof (stackPacket.packet->data); - - if (dataSize > stackCapacity) - { - allocatedPackets.malloc ((sizeof (MIDIPacketList) - stackCapacity) + dataSize, 1); - packetToSend = allocatedPackets; - } - - packetToSend->numPackets = 1; - MIDIPacket& p = *(packetToSend->packet); - p.timeStamp = timeStamp; - p.length = (UInt16) dataSize; - memcpy (p.data, message.getRawData(), dataSize); - } - else - { - jassertfalse; // packet too large to send! - return; - } - - static_cast (internal)->send (packetToSend); -} - -//============================================================================== -StringArray MidiInput::getDevices() { return CoreMidiHelpers::findDevices (true); } -int MidiInput::getDefaultDeviceIndex() { return 0; } - -MidiInput* MidiInput::openDevice (int index, MidiInputCallback* callback) -{ - jassert (callback != nullptr); - - using namespace CoreMidiHelpers; - MidiInput* newInput = nullptr; - - if (isPositiveAndBelow (index, (int) MIDIGetNumberOfSources())) - { - if (MIDIEndpointRef endPoint = MIDIGetSource ((ItemCount) index)) - { - CFStringRef name; - - if (CHECK_ERROR (MIDIObjectGetStringProperty (endPoint, kMIDIPropertyName, &name))) - { - if (MIDIClientRef client = getGlobalMidiClient()) - { - MIDIPortRef port; - ScopedPointer mpc (new MidiPortAndCallback (*callback)); - - if (CHECK_ERROR (MIDIInputPortCreate (client, name, midiInputProc, mpc, &port))) - { - if (CHECK_ERROR (MIDIPortConnectSource (port, endPoint, nullptr))) - { - mpc->portAndEndpoint = new MidiPortAndEndpoint (port, endPoint); - - newInput = new MidiInput (getDevices() [index]); - mpc->input = newInput; - newInput->internal = mpc; - - const ScopedLock sl (callbackLock); - activeCallbacks.add (mpc.release()); - } - else - { - CHECK_ERROR (MIDIPortDispose (port)); - } - } - } - } - - CFRelease (name); - } - } - - return newInput; -} - -MidiInput* MidiInput::createNewDevice (const String& deviceName, MidiInputCallback* callback) -{ - jassert (callback != nullptr); - - using namespace CoreMidiHelpers; - MidiInput* mi = nullptr; - - if (MIDIClientRef client = getGlobalMidiClient()) - { - ScopedPointer mpc (new MidiPortAndCallback (*callback)); - mpc->active = false; - - MIDIEndpointRef endPoint; - CFStringRef name = deviceName.toCFString(); - - if (CHECK_ERROR (MIDIDestinationCreate (client, name, midiInputProc, mpc, &endPoint))) - { - mpc->portAndEndpoint = new MidiPortAndEndpoint (0, endPoint); - - mi = new MidiInput (deviceName); - mpc->input = mi; - mi->internal = mpc; - - const ScopedLock sl (callbackLock); - activeCallbacks.add (mpc.release()); - } - - CFRelease (name); - } - - return mi; -} - -MidiInput::MidiInput (const String& nm) : name (nm) -{ -} - -MidiInput::~MidiInput() -{ - delete static_cast (internal); -} - -void MidiInput::start() -{ - const ScopedLock sl (CoreMidiHelpers::callbackLock); - static_cast (internal)->active = true; -} - -void MidiInput::stop() -{ - const ScopedLock sl (CoreMidiHelpers::callbackLock); - static_cast (internal)->active = false; -} - -#undef CHECK_ERROR diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/native/juce_win32_ASIO.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/native/juce_win32_ASIO.cpp deleted file mode 100644 index b171bedd65..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/native/juce_win32_ASIO.cpp +++ /dev/null @@ -1,1630 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#undef WINDOWS - -/* The ASIO SDK *should* declare its callback functions as being __cdecl, but different versions seem - to be pretty random about whether or not they do this. If you hit an error using these functions - it'll be because you're trying to build using __stdcall, in which case you'd need to either get hold of - an ASIO SDK which correctly specifies __cdecl, or add the __cdecl keyword to its functions yourself. -*/ -#define JUCE_ASIOCALLBACK __cdecl - -//============================================================================== -namespace ASIODebugging -{ - #if JUCE_ASIO_DEBUGGING - #define JUCE_ASIO_LOG(msg) ASIODebugging::logMessage (msg) - #define JUCE_ASIO_LOG_ERROR(msg, errNum) ASIODebugging::logError ((msg), (errNum)) - - static void logMessage (String message) - { - message = "ASIO: " + message; - DBG (message); - Logger::writeToLog (message); - } - - static void logError (const String& context, long error) - { - const char* err = "Unknown error"; - - switch (error) - { - case ASE_OK: return; - case ASE_NotPresent: err = "Not Present"; break; - case ASE_HWMalfunction: err = "Hardware Malfunction"; break; - case ASE_InvalidParameter: err = "Invalid Parameter"; break; - case ASE_InvalidMode: err = "Invalid Mode"; break; - case ASE_SPNotAdvancing: err = "Sample position not advancing"; break; - case ASE_NoClock: err = "No Clock"; break; - case ASE_NoMemory: err = "Out of memory"; break; - default: break; - } - - logMessage ("error: " + context + " - " + err); - } - #else - static void dummyLog() {} - #define JUCE_ASIO_LOG(msg) ASIODebugging::dummyLog() - #define JUCE_ASIO_LOG_ERROR(msg, errNum) (void) errNum; ASIODebugging::dummyLog() - #endif -} - -//============================================================================== -struct ASIOSampleFormat -{ - ASIOSampleFormat() noexcept {} - - ASIOSampleFormat (const long type) noexcept - : bitDepth (24), - littleEndian (true), - formatIsFloat (false), - byteStride (4) - { - switch (type) - { - case ASIOSTInt16MSB: byteStride = 2; littleEndian = false; bitDepth = 16; break; - case ASIOSTInt24MSB: byteStride = 3; littleEndian = false; break; - case ASIOSTInt32MSB: bitDepth = 32; littleEndian = false; break; - case ASIOSTFloat32MSB: bitDepth = 32; littleEndian = false; formatIsFloat = true; break; - case ASIOSTFloat64MSB: bitDepth = 64; byteStride = 8; littleEndian = false; break; - case ASIOSTInt32MSB16: bitDepth = 16; littleEndian = false; break; - case ASIOSTInt32MSB18: littleEndian = false; break; - case ASIOSTInt32MSB20: littleEndian = false; break; - case ASIOSTInt32MSB24: littleEndian = false; break; - case ASIOSTInt16LSB: byteStride = 2; bitDepth = 16; break; - case ASIOSTInt24LSB: byteStride = 3; break; - case ASIOSTInt32LSB: bitDepth = 32; break; - case ASIOSTFloat32LSB: bitDepth = 32; formatIsFloat = true; break; - case ASIOSTFloat64LSB: bitDepth = 64; byteStride = 8; break; - case ASIOSTInt32LSB16: bitDepth = 16; break; - case ASIOSTInt32LSB18: break; // (unhandled) - case ASIOSTInt32LSB20: break; // (unhandled) - case ASIOSTInt32LSB24: break; - - case ASIOSTDSDInt8LSB1: break; // (unhandled) - case ASIOSTDSDInt8MSB1: break; // (unhandled) - case ASIOSTDSDInt8NER8: break; // (unhandled) - - default: - jassertfalse; // (not a valid format code..) - break; - } - } - - void convertToFloat (const void* const src, float* const dst, const int samps) const noexcept - { - if (formatIsFloat) - { - memcpy (dst, src, samps * sizeof (float)); - } - else - { - switch (bitDepth) - { - case 16: convertInt16ToFloat (static_cast (src), dst, byteStride, samps, littleEndian); break; - case 24: convertInt24ToFloat (static_cast (src), dst, byteStride, samps, littleEndian); break; - case 32: convertInt32ToFloat (static_cast (src), dst, byteStride, samps, littleEndian); break; - default: jassertfalse; break; - } - } - } - - void convertFromFloat (const float* const src, void* const dst, const int samps) const noexcept - { - if (formatIsFloat) - { - memcpy (dst, src, samps * sizeof (float)); - } - else - { - switch (bitDepth) - { - case 16: convertFloatToInt16 (src, static_cast (dst), byteStride, samps, littleEndian); break; - case 24: convertFloatToInt24 (src, static_cast (dst), byteStride, samps, littleEndian); break; - case 32: convertFloatToInt32 (src, static_cast (dst), byteStride, samps, littleEndian); break; - default: jassertfalse; break; - } - } - } - - void clear (void* dst, const int numSamps) noexcept - { - if (dst != nullptr) - zeromem (dst, numSamps * byteStride); - } - - int bitDepth, byteStride; - bool formatIsFloat, littleEndian; - -private: - static void convertInt16ToFloat (const char* src, float* dest, const int srcStrideBytes, - int numSamples, const bool littleEndian) noexcept - { - const double g = 1.0 / 32768.0; - - if (littleEndian) - { - while (--numSamples >= 0) - { - *dest++ = (float) (g * (short) ByteOrder::littleEndianShort (src)); - src += srcStrideBytes; - } - } - else - { - while (--numSamples >= 0) - { - *dest++ = (float) (g * (short) ByteOrder::bigEndianShort (src)); - src += srcStrideBytes; - } - } - } - - static void convertFloatToInt16 (const float* src, char* dest, const int dstStrideBytes, - int numSamples, const bool littleEndian) noexcept - { - const double maxVal = (double) 0x7fff; - - if (littleEndian) - { - while (--numSamples >= 0) - { - *(uint16*) dest = ByteOrder::swapIfBigEndian ((uint16) (short) roundToInt (jlimit (-maxVal, maxVal, maxVal * *src++))); - dest += dstStrideBytes; - } - } - else - { - while (--numSamples >= 0) - { - *(uint16*) dest = ByteOrder::swapIfLittleEndian ((uint16) (short) roundToInt (jlimit (-maxVal, maxVal, maxVal * *src++))); - dest += dstStrideBytes; - } - } - } - - static void convertInt24ToFloat (const char* src, float* dest, const int srcStrideBytes, - int numSamples, const bool littleEndian) noexcept - { - const double g = 1.0 / 0x7fffff; - - if (littleEndian) - { - while (--numSamples >= 0) - { - *dest++ = (float) (g * ByteOrder::littleEndian24Bit (src)); - src += srcStrideBytes; - } - } - else - { - while (--numSamples >= 0) - { - *dest++ = (float) (g * ByteOrder::bigEndian24Bit (src)); - src += srcStrideBytes; - } - } - } - - static void convertFloatToInt24 (const float* src, char* dest, const int dstStrideBytes, - int numSamples, const bool littleEndian) noexcept - { - const double maxVal = (double) 0x7fffff; - - if (littleEndian) - { - while (--numSamples >= 0) - { - ByteOrder::littleEndian24BitToChars ((uint32) roundToInt (jlimit (-maxVal, maxVal, maxVal * *src++)), dest); - dest += dstStrideBytes; - } - } - else - { - while (--numSamples >= 0) - { - ByteOrder::bigEndian24BitToChars ((uint32) roundToInt (jlimit (-maxVal, maxVal, maxVal * *src++)), dest); - dest += dstStrideBytes; - } - } - } - - static void convertInt32ToFloat (const char* src, float* dest, const int srcStrideBytes, - int numSamples, const bool littleEndian) noexcept - { - const double g = 1.0 / 0x7fffffff; - - if (littleEndian) - { - while (--numSamples >= 0) - { - *dest++ = (float) (g * (int) ByteOrder::littleEndianInt (src)); - src += srcStrideBytes; - } - } - else - { - while (--numSamples >= 0) - { - *dest++ = (float) (g * (int) ByteOrder::bigEndianInt (src)); - src += srcStrideBytes; - } - } - } - - static void convertFloatToInt32 (const float* src, char* dest, const int dstStrideBytes, - int numSamples, const bool littleEndian) noexcept - { - const double maxVal = (double) 0x7fffffff; - - if (littleEndian) - { - while (--numSamples >= 0) - { - *(uint32*) dest = ByteOrder::swapIfBigEndian ((uint32) roundToInt (jlimit (-maxVal, maxVal, maxVal * *src++))); - dest += dstStrideBytes; - } - } - else - { - while (--numSamples >= 0) - { - *(uint32*) dest = ByteOrder::swapIfLittleEndian ((uint32) roundToInt (jlimit (-maxVal, maxVal, maxVal * *src++))); - dest += dstStrideBytes; - } - } - } -}; - -//============================================================================== -class ASIOAudioIODevice; -static ASIOAudioIODevice* volatile currentASIODev[3] = { 0 }; - -extern HWND juce_messageWindowHandle; - -class ASIOAudioIODeviceType; -static void sendASIODeviceChangeToListeners (ASIOAudioIODeviceType*); - -//============================================================================== -class ASIOAudioIODevice : public AudioIODevice, - private Timer -{ -public: - ASIOAudioIODevice (ASIOAudioIODeviceType* ownerType, const String& devName, - const CLSID clsID, const int slotNumber) - : AudioIODevice (devName, "ASIO"), - owner (ownerType), - asioObject (nullptr), - classId (clsID), - inputLatency (0), - outputLatency (0), - minSize (0), maxSize (0), - preferredSize (0), - granularity (0), - numClockSources (0), - currentBlockSizeSamples (0), - currentBitDepth (16), - currentSampleRate (0), - currentCallback (nullptr), - bufferIndex (0), - numActiveInputChans (0), - numActiveOutputChans (0), - deviceIsOpen (false), - isStarted (false), - buffersCreated (false), - calledback (false), - littleEndian (false), - postOutput (true), - needToReset (false), - insideControlPanelModalLoop (false), - shouldUsePreferredSize (false) - { - name = devName; - inBuffers.calloc (4); - outBuffers.calloc (4); - - jassert (currentASIODev [slotNumber] == nullptr); - currentASIODev [slotNumber] = this; - - openDevice(); - } - - ~ASIOAudioIODevice() - { - for (int i = 0; i < numElementsInArray (currentASIODev); ++i) - if (currentASIODev[i] == this) - currentASIODev[i] = nullptr; - - close(); - JUCE_ASIO_LOG ("closed"); - removeCurrentDriver(); - } - - void updateSampleRates() - { - // find a list of sample rates.. - const int possibleSampleRates[] = { 44100, 48000, 88200, 96000, 176400, 192000, 352800, 384000 }; - Array newRates; - - if (asioObject != nullptr) - { - for (int index = 0; index < numElementsInArray (possibleSampleRates); ++index) - if (asioObject->canSampleRate ((double) possibleSampleRates[index]) == 0) - newRates.add ((double) possibleSampleRates[index]); - } - - if (newRates.size() == 0) - { - double cr = getSampleRate(); - JUCE_ASIO_LOG ("No sample rates supported - current rate: " + String ((int) cr)); - - if (cr > 0) - newRates.add ((int) cr); - } - - if (sampleRates != newRates) - { - sampleRates.swapWith (newRates); - - #if JUCE_ASIO_DEBUGGING - StringArray s; - for (int i = 0; i < sampleRates.size(); ++i) - s.add (String (sampleRates.getUnchecked(i))); - - JUCE_ASIO_LOG ("Rates: " + s.joinIntoString (" ")); - #endif - } - } - - StringArray getOutputChannelNames() override { return outputChannelNames; } - StringArray getInputChannelNames() override { return inputChannelNames; } - - Array getAvailableSampleRates() override { return sampleRates; } - Array getAvailableBufferSizes() override { return bufferSizes; } - int getDefaultBufferSize() override { return preferredSize; } - - String open (const BigInteger& inputChannels, - const BigInteger& outputChannels, - double sr, int bufferSizeSamples) override - { - if (isOpen()) - close(); - - jassert (currentCallback == nullptr); - - if (bufferSizeSamples < 8 || bufferSizeSamples > 16384) - shouldUsePreferredSize = true; - - if (asioObject == nullptr) - { - const String openingError (openDevice()); - - if (asioObject == nullptr) - return openingError; - } - - isStarted = false; - bufferIndex = -1; - - long err = asioObject->getChannels (&totalNumInputChans, &totalNumOutputChans); - jassert (err == ASE_OK); - - bufferSizeSamples = readBufferSizes (bufferSizeSamples); - - double sampleRate = sr; - currentSampleRate = sampleRate; - currentBlockSizeSamples = bufferSizeSamples; - currentChansOut.clear(); - currentChansIn.clear(); - inBuffers.clear (totalNumInputChans + 1); - outBuffers.clear (totalNumOutputChans + 1); - - updateSampleRates(); - - if (sampleRate == 0 || (sampleRates.size() > 0 && ! sampleRates.contains (sampleRate))) - sampleRate = sampleRates[0]; - - jassert (sampleRate != 0); - if (sampleRate == 0) - sampleRate = 44100.0; - - updateClockSources(); - currentSampleRate = getSampleRate(); - - error.clear(); - buffersCreated = false; - - setSampleRate (sampleRate); - - if (needToReset) - { - JUCE_ASIO_LOG (" Resetting"); - removeCurrentDriver(); - - loadDriver(); - const String error (initDriver()); - - if (error.isNotEmpty()) - JUCE_ASIO_LOG ("ASIOInit: " + error); - - needToReset = false; - } - - const int totalBuffers = resetBuffers (inputChannels, outputChannels); - - setCallbackFunctions(); - - JUCE_ASIO_LOG ("disposing buffers"); - err = asioObject->disposeBuffers(); - - JUCE_ASIO_LOG ("creating buffers: " + String (totalBuffers) + ", " + String (currentBlockSizeSamples)); - err = asioObject->createBuffers (bufferInfos, totalBuffers, currentBlockSizeSamples, &callbacks); - - if (err != ASE_OK) - { - currentBlockSizeSamples = preferredSize; - JUCE_ASIO_LOG_ERROR ("create buffers 2", err); - - asioObject->disposeBuffers(); - err = asioObject->createBuffers (bufferInfos, totalBuffers, currentBlockSizeSamples, &callbacks); - } - - if (err == ASE_OK) - { - buffersCreated = true; - - tempBuffer.calloc (totalBuffers * currentBlockSizeSamples + 32); - - int n = 0; - Array types; - currentBitDepth = 16; - - for (int i = 0; i < (int) totalNumInputChans; ++i) - { - if (inputChannels[i]) - { - inBuffers[n] = tempBuffer + (currentBlockSizeSamples * n); - - ASIOChannelInfo channelInfo = { 0 }; - channelInfo.channel = i; - channelInfo.isInput = 1; - asioObject->getChannelInfo (&channelInfo); - - types.addIfNotAlreadyThere (channelInfo.type); - inputFormat[n] = ASIOSampleFormat (channelInfo.type); - - currentBitDepth = jmax (currentBitDepth, inputFormat[n].bitDepth); - ++n; - } - } - - jassert (numActiveInputChans == n); - n = 0; - - for (int i = 0; i < (int) totalNumOutputChans; ++i) - { - if (outputChannels[i]) - { - outBuffers[n] = tempBuffer + (currentBlockSizeSamples * (numActiveInputChans + n)); - - ASIOChannelInfo channelInfo = { 0 }; - channelInfo.channel = i; - channelInfo.isInput = 0; - asioObject->getChannelInfo (&channelInfo); - - types.addIfNotAlreadyThere (channelInfo.type); - outputFormat[n] = ASIOSampleFormat (channelInfo.type); - - currentBitDepth = jmax (currentBitDepth, outputFormat[n].bitDepth); - ++n; - } - } - - jassert (numActiveOutputChans == n); - - for (int i = types.size(); --i >= 0;) - JUCE_ASIO_LOG ("channel format: " + String (types[i])); - - jassert (n <= totalBuffers); - - for (int i = 0; i < numActiveOutputChans; ++i) - { - outputFormat[i].clear (bufferInfos [numActiveInputChans + i].buffers[0], currentBlockSizeSamples); - outputFormat[i].clear (bufferInfos [numActiveInputChans + i].buffers[1], currentBlockSizeSamples); - } - - readLatencies(); - - asioObject->getBufferSize (&minSize, &maxSize, &preferredSize, &granularity); - deviceIsOpen = true; - - JUCE_ASIO_LOG ("starting"); - calledback = false; - err = asioObject->start(); - - if (err != 0) - { - deviceIsOpen = false; - JUCE_ASIO_LOG ("stop on failure"); - Thread::sleep (10); - asioObject->stop(); - error = "Can't start device"; - Thread::sleep (10); - } - else - { - int count = 300; - while (--count > 0 && ! calledback) - Thread::sleep (10); - - isStarted = true; - - if (! calledback) - { - error = "Device didn't start correctly"; - JUCE_ASIO_LOG ("no callbacks - stopping.."); - asioObject->stop(); - } - } - } - else - { - error = "Can't create i/o buffers"; - } - - if (error.isNotEmpty()) - { - JUCE_ASIO_LOG_ERROR (error, err); - disposeBuffers(); - - Thread::sleep (20); - isStarted = false; - deviceIsOpen = false; - - const String errorCopy (error); - close(); // (this resets the error string) - error = errorCopy; - } - - needToReset = false; - return error; - } - - void close() override - { - error.clear(); - stopTimer(); - stop(); - - if (asioObject != nullptr && deviceIsOpen) - { - const ScopedLock sl (callbackLock); - - deviceIsOpen = false; - isStarted = false; - needToReset = false; - - JUCE_ASIO_LOG ("stopping"); - - if (asioObject != nullptr) - { - Thread::sleep (20); - asioObject->stop(); - Thread::sleep (10); - disposeBuffers(); - } - - Thread::sleep (10); - } - } - - bool isOpen() override { return deviceIsOpen || insideControlPanelModalLoop; } - bool isPlaying() override { return asioObject != nullptr && currentCallback != nullptr; } - - int getCurrentBufferSizeSamples() override { return currentBlockSizeSamples; } - double getCurrentSampleRate() override { return currentSampleRate; } - int getCurrentBitDepth() override { return currentBitDepth; } - - BigInteger getActiveOutputChannels() const override { return currentChansOut; } - BigInteger getActiveInputChannels() const override { return currentChansIn; } - - int getOutputLatencyInSamples() override { return outputLatency + currentBlockSizeSamples / 4; } - int getInputLatencyInSamples() override { return inputLatency + currentBlockSizeSamples / 4; } - - void start (AudioIODeviceCallback* callback) override - { - if (callback != nullptr) - { - callback->audioDeviceAboutToStart (this); - - const ScopedLock sl (callbackLock); - currentCallback = callback; - } - } - - void stop() override - { - AudioIODeviceCallback* const lastCallback = currentCallback; - - { - const ScopedLock sl (callbackLock); - currentCallback = nullptr; - } - - if (lastCallback != nullptr) - lastCallback->audioDeviceStopped(); - } - - String getLastError() { return error; } - bool hasControlPanel() const { return true; } - - bool showControlPanel() - { - JUCE_ASIO_LOG ("showing control panel"); - - bool done = false; - - JUCE_TRY - { - // are there are devices that need to be closed before showing their control panel? - // close(); - insideControlPanelModalLoop = true; - - const uint32 started = Time::getMillisecondCounter(); - - if (asioObject != nullptr) - { - asioObject->controlPanel(); - - const int spent = (int) Time::getMillisecondCounter() - (int) started; - - JUCE_ASIO_LOG ("spent: " + String (spent)); - - if (spent > 300) - { - shouldUsePreferredSize = true; - done = true; - } - } - } - JUCE_CATCH_ALL - - insideControlPanelModalLoop = false; - return done; - } - - void resetRequest() noexcept - { - startTimer (500); - } - - void timerCallback() override - { - if (! insideControlPanelModalLoop) - { - stopTimer(); - - JUCE_ASIO_LOG ("restart request!"); - - AudioIODeviceCallback* const oldCallback = currentCallback; - - close(); - - needToReset = true; - open (BigInteger (currentChansIn), BigInteger (currentChansOut), - currentSampleRate, currentBlockSizeSamples); - - reloadChannelNames(); - - if (oldCallback != nullptr) - start (oldCallback); - - sendASIODeviceChangeToListeners (owner); - } - else - { - startTimer (100); - } - } - -private: - //============================================================================== - WeakReference owner; - IASIO* volatile asioObject; - ASIOCallbacks callbacks; - - CLSID classId; - String error; - - long totalNumInputChans, totalNumOutputChans; - StringArray inputChannelNames, outputChannelNames; - - Array sampleRates; - Array bufferSizes; - long inputLatency, outputLatency; - long minSize, maxSize, preferredSize, granularity; - ASIOClockSource clocks[32]; - int numClockSources; - - int volatile currentBlockSizeSamples; - int volatile currentBitDepth; - double volatile currentSampleRate; - BigInteger currentChansOut, currentChansIn; - AudioIODeviceCallback* volatile currentCallback; - CriticalSection callbackLock; - - HeapBlock bufferInfos; - HeapBlock inBuffers, outBuffers; - HeapBlock inputFormat, outputFormat; - - WaitableEvent event1; - HeapBlock tempBuffer; - int volatile bufferIndex, numActiveInputChans, numActiveOutputChans; - - bool deviceIsOpen, isStarted, buffersCreated; - bool volatile calledback; - bool volatile littleEndian, postOutput, needToReset; - bool volatile insideControlPanelModalLoop; - bool volatile shouldUsePreferredSize; - - //============================================================================== - static String convertASIOString (char* const text, int length) - { - if (CharPointer_UTF8::isValidString (text, length)) - return String::fromUTF8 (text, length); - - WCHAR wideVersion [64] = { 0 }; - MultiByteToWideChar (CP_ACP, 0, text, length, wideVersion, numElementsInArray (wideVersion)); - return wideVersion; - } - - String getChannelName (int index, bool isInput) const - { - ASIOChannelInfo channelInfo = { 0 }; - channelInfo.channel = index; - channelInfo.isInput = isInput ? 1 : 0; - asioObject->getChannelInfo (&channelInfo); - - return convertASIOString (channelInfo.name, sizeof (channelInfo.name)); - } - - void reloadChannelNames() - { - if (asioObject != nullptr - && asioObject->getChannels (&totalNumInputChans, &totalNumOutputChans) == ASE_OK) - { - inputChannelNames.clear(); - outputChannelNames.clear(); - - for (int i = 0; i < totalNumInputChans; ++i) - inputChannelNames.add (getChannelName (i, true)); - - for (int i = 0; i < totalNumOutputChans; ++i) - outputChannelNames.add (getChannelName (i, false)); - - outputChannelNames.trim(); - inputChannelNames.trim(); - outputChannelNames.appendNumbersToDuplicates (false, true); - inputChannelNames.appendNumbersToDuplicates (false, true); - } - } - - int readBufferSizes (int bufferSizeSamples) - { - minSize = 0; - maxSize = 0; - granularity = 0; - - long newPreferredSize = 0; - - if (asioObject->getBufferSize (&minSize, &maxSize, &newPreferredSize, &granularity) == ASE_OK) - { - if (preferredSize != 0 && newPreferredSize != 0 && newPreferredSize != preferredSize) - shouldUsePreferredSize = true; - - if (bufferSizeSamples < minSize || bufferSizeSamples > maxSize) - shouldUsePreferredSize = true; - - preferredSize = newPreferredSize; - } - - // unfortunate workaround for certain drivers which crash if you make - // dynamic changes to the buffer size... - shouldUsePreferredSize = shouldUsePreferredSize || getName().containsIgnoreCase ("Digidesign"); - - if (shouldUsePreferredSize) - { - JUCE_ASIO_LOG ("Using preferred size for buffer.."); - long err = asioObject->getBufferSize (&minSize, &maxSize, &preferredSize, &granularity); - - if (err == ASE_OK) - { - bufferSizeSamples = (int) preferredSize; - } - else - { - bufferSizeSamples = 1024; - JUCE_ASIO_LOG_ERROR ("getBufferSize1", err); - } - - shouldUsePreferredSize = false; - } - - return bufferSizeSamples; - } - - int resetBuffers (const BigInteger& inputChannels, - const BigInteger& outputChannels) - { - numActiveInputChans = 0; - numActiveOutputChans = 0; - - ASIOBufferInfo* info = bufferInfos; - for (int i = 0; i < totalNumInputChans; ++i) - { - if (inputChannels[i]) - { - currentChansIn.setBit (i); - info->isInput = 1; - info->channelNum = i; - info->buffers[0] = info->buffers[1] = nullptr; - ++info; - ++numActiveInputChans; - } - } - - for (int i = 0; i < totalNumOutputChans; ++i) - { - if (outputChannels[i]) - { - currentChansOut.setBit (i); - info->isInput = 0; - info->channelNum = i; - info->buffers[0] = info->buffers[1] = nullptr; - ++info; - ++numActiveOutputChans; - } - } - - return numActiveInputChans + numActiveOutputChans; - } - - void addBufferSizes (long minSize, long maxSize, long preferredSize, long granularity) - { - // find a list of buffer sizes.. - JUCE_ASIO_LOG (String ((int) minSize) + "->" + String ((int) maxSize) + ", " - + String ((int) preferredSize) + ", " + String ((int) granularity)); - - if (granularity >= 0) - { - granularity = jmax (16, (int) granularity); - - for (int i = jmax ((int) (minSize + 15) & ~15, (int) granularity); i < jmin (6400, (int) maxSize); i += granularity) - bufferSizes.addIfNotAlreadyThere (granularity * (i / granularity)); - } - else if (granularity < 0) - { - for (int i = 0; i < 18; ++i) - { - const int s = (1 << i); - - if (s >= minSize && s <= maxSize) - bufferSizes.add (s); - } - } - - bufferSizes.addIfNotAlreadyThere (preferredSize); - - DefaultElementComparator comparator; - bufferSizes.sort (comparator); - } - - double getSampleRate() const - { - double cr = 0; - long err = asioObject->getSampleRate (&cr); - JUCE_ASIO_LOG_ERROR ("getSampleRate", err); - return cr; - } - - void setSampleRate (double newRate) - { - if (currentSampleRate != newRate) - { - JUCE_ASIO_LOG ("rate change: " + String (currentSampleRate) + " to " + String (newRate)); - long err = asioObject->setSampleRate (newRate); - - if (err == ASE_NoClock && numClockSources > 0) - { - JUCE_ASIO_LOG ("trying to set a clock source.."); - Thread::sleep (10); - err = asioObject->setClockSource (clocks[0].index); - JUCE_ASIO_LOG_ERROR ("setClockSource2", err); - - Thread::sleep (10); - err = asioObject->setSampleRate (newRate); - } - - if (err == 0) - currentSampleRate = newRate; - - // on fail, ignore the attempt to change rate, and run with the current one.. - } - } - - void updateClockSources() - { - zeromem (clocks, sizeof (clocks)); - long numSources = numElementsInArray (clocks); - asioObject->getClockSources (clocks, &numSources); - numClockSources = (int) numSources; - - bool isSourceSet = false; - - // careful not to remove this loop because it does more than just logging! - for (int i = 0; i < numClockSources; ++i) - { - String s ("clock: "); - s += clocks[i].name; - - if (clocks[i].isCurrentSource) - { - isSourceSet = true; - s << " (cur)"; - } - - JUCE_ASIO_LOG (s); - } - - if (numClockSources > 1 && ! isSourceSet) - { - JUCE_ASIO_LOG ("setting clock source"); - long err = asioObject->setClockSource (clocks[0].index); - JUCE_ASIO_LOG_ERROR ("setClockSource1", err); - Thread::sleep (20); - } - else - { - if (numClockSources == 0) - JUCE_ASIO_LOG ("no clock sources!"); - } - } - - void readLatencies() - { - inputLatency = outputLatency = 0; - - if (asioObject->getLatencies (&inputLatency, &outputLatency) != 0) - JUCE_ASIO_LOG ("getLatencies() failed"); - else - JUCE_ASIO_LOG ("Latencies: in = " + String ((int) inputLatency) + ", out = " + String ((int) outputLatency)); - } - - void createDummyBuffers (long preferredSize) - { - numActiveInputChans = 0; - numActiveOutputChans = 0; - - ASIOBufferInfo* info = bufferInfos; - int numChans = 0; - - for (int i = 0; i < jmin (2, (int) totalNumInputChans); ++i) - { - info->isInput = 1; - info->channelNum = i; - info->buffers[0] = info->buffers[1] = nullptr; - ++info; - ++numChans; - } - - const int outputBufferIndex = numChans; - - for (int i = 0; i < jmin (2, (int) totalNumOutputChans); ++i) - { - info->isInput = 0; - info->channelNum = i; - info->buffers[0] = info->buffers[1] = nullptr; - ++info; - ++numChans; - } - - setCallbackFunctions(); - - JUCE_ASIO_LOG ("creating buffers (dummy): " + String (numChans) + ", " + String ((int) preferredSize)); - - if (preferredSize > 0) - { - long err = asioObject->createBuffers (bufferInfos, numChans, preferredSize, &callbacks); - JUCE_ASIO_LOG_ERROR ("dummy buffers", err); - } - - long newInps = 0, newOuts = 0; - asioObject->getChannels (&newInps, &newOuts); - - if (totalNumInputChans != newInps || totalNumOutputChans != newOuts) - { - totalNumInputChans = newInps; - totalNumOutputChans = newOuts; - - JUCE_ASIO_LOG (String ((int) totalNumInputChans) + " in; " + String ((int) totalNumOutputChans) + " out"); - } - - updateSampleRates(); - reloadChannelNames(); - - for (int i = 0; i < totalNumOutputChans; ++i) - { - ASIOChannelInfo channelInfo = { 0 }; - channelInfo.channel = i; - channelInfo.isInput = 0; - asioObject->getChannelInfo (&channelInfo); - - outputFormat[i] = ASIOSampleFormat (channelInfo.type); - - if (i < 2) - { - // clear the channels that are used with the dummy stuff - outputFormat[i].clear (bufferInfos [outputBufferIndex + i].buffers[0], preferredSize); - outputFormat[i].clear (bufferInfos [outputBufferIndex + i].buffers[1], preferredSize); - } - } - } - - void removeCurrentDriver() - { - if (asioObject != nullptr) - { - asioObject->Release(); - asioObject = nullptr; - } - } - - bool loadDriver() - { - removeCurrentDriver(); - - bool crashed = false; - bool ok = tryCreatingDriver (crashed); - - if (crashed) - JUCE_ASIO_LOG ("** Driver crashed while being opened"); - - return ok; - } - - bool tryCreatingDriver (bool& crashed) - { - #if ! JUCE_MINGW - __try - #endif - { - return CoCreateInstance (classId, 0, CLSCTX_INPROC_SERVER, - classId, (void**) &asioObject) == S_OK; - } - #if ! JUCE_MINGW - __except (EXCEPTION_EXECUTE_HANDLER) { crashed = true; } - return false; - #endif - } - - String getLastDriverError() const - { - jassert (asioObject != nullptr); - char buffer [512] = { 0 }; - asioObject->getErrorMessage (buffer); - return String (buffer, sizeof (buffer) - 1); - } - - String initDriver() - { - if (asioObject == nullptr) - return "No Driver"; - - const bool initOk = !! asioObject->init (juce_messageWindowHandle); - String driverError; - - // Get error message if init() failed, or if it's a buggy Denon driver, - // which returns true from init() even when it fails. - if ((! initOk) || getName().containsIgnoreCase ("denon dj")) - driverError = getLastDriverError(); - - if ((! initOk) && driverError.isEmpty()) - driverError = "Driver failed to initialise"; - - if (driverError.isEmpty()) - { - char buffer [512]; - asioObject->getDriverName (buffer); // just in case any flimsy drivers expect this to be called.. - } - - return driverError; - } - - String openDevice() - { - // open the device and get its info.. - JUCE_ASIO_LOG ("opening device: " + getName()); - - needToReset = false; - outputChannelNames.clear(); - inputChannelNames.clear(); - bufferSizes.clear(); - sampleRates.clear(); - deviceIsOpen = false; - totalNumInputChans = 0; - totalNumOutputChans = 0; - numActiveInputChans = 0; - numActiveOutputChans = 0; - currentCallback = nullptr; - - error.clear(); - - if (getName().isEmpty()) - return error; - - long err = 0; - - if (loadDriver()) - { - if ((error = initDriver()).isEmpty()) - { - numActiveInputChans = 0; - numActiveOutputChans = 0; - totalNumInputChans = 0; - totalNumOutputChans = 0; - - if (asioObject != nullptr - && (err = asioObject->getChannels (&totalNumInputChans, &totalNumOutputChans)) == 0) - { - JUCE_ASIO_LOG (String ((int) totalNumInputChans) + " in, " + String ((int) totalNumOutputChans) + " out"); - - const int chansToAllocate = totalNumInputChans + totalNumOutputChans + 4; - bufferInfos.calloc (chansToAllocate); - inBuffers.calloc (chansToAllocate); - outBuffers.calloc (chansToAllocate); - inputFormat.calloc (chansToAllocate); - outputFormat.calloc (chansToAllocate); - - if ((err = asioObject->getBufferSize (&minSize, &maxSize, &preferredSize, &granularity)) == 0) - { - addBufferSizes (minSize, maxSize, preferredSize, granularity); - - double currentRate = getSampleRate(); - - if (currentRate < 1.0 || currentRate > 192001.0) - { - JUCE_ASIO_LOG ("setting default sample rate"); - err = asioObject->setSampleRate (44100.0); - JUCE_ASIO_LOG_ERROR ("setting sample rate", err); - - currentRate = getSampleRate(); - } - - currentSampleRate = currentRate; - - postOutput = (asioObject->outputReady() == 0); - if (postOutput) - JUCE_ASIO_LOG ("outputReady true"); - - updateSampleRates(); - - readLatencies(); // ..doing these steps because cubase does so at this stage - createDummyBuffers (preferredSize); // in initialisation, and some devices fail if we don't. - readLatencies(); - - // start and stop because cubase does it.. - err = asioObject->start(); - // ignore an error here, as it might start later after setting other stuff up - JUCE_ASIO_LOG_ERROR ("start", err); - - Thread::sleep (80); - asioObject->stop(); - } - else - { - error = "Can't detect buffer sizes"; - } - } - else - { - error = "Can't detect asio channels"; - } - } - } - else - { - error = "No such device"; - } - - if (error.isNotEmpty()) - { - JUCE_ASIO_LOG_ERROR (error, err); - disposeBuffers(); - removeCurrentDriver(); - } - else - { - JUCE_ASIO_LOG ("device open"); - } - - deviceIsOpen = false; - needToReset = false; - stopTimer(); - return error; - } - - void disposeBuffers() - { - if (asioObject != nullptr && buffersCreated) - { - buffersCreated = false; - asioObject->disposeBuffers(); - } - } - - //============================================================================== - void JUCE_ASIOCALLBACK callback (const long index) - { - if (isStarted) - { - bufferIndex = index; - processBuffer(); - } - else - { - if (postOutput && (asioObject != nullptr)) - asioObject->outputReady(); - } - - calledback = true; - } - - void processBuffer() - { - const ASIOBufferInfo* const infos = bufferInfos; - const int bi = bufferIndex; - - const ScopedLock sl (callbackLock); - - if (bi >= 0) - { - const int samps = currentBlockSizeSamples; - - if (currentCallback != nullptr) - { - for (int i = 0; i < numActiveInputChans; ++i) - { - jassert (inBuffers[i] != nullptr); - inputFormat[i].convertToFloat (infos[i].buffers[bi], inBuffers[i], samps); - } - - currentCallback->audioDeviceIOCallback (const_cast (inBuffers.getData()), numActiveInputChans, - outBuffers, numActiveOutputChans, samps); - - for (int i = 0; i < numActiveOutputChans; ++i) - { - jassert (outBuffers[i] != nullptr); - outputFormat[i].convertFromFloat (outBuffers[i], infos [numActiveInputChans + i].buffers[bi], samps); - } - } - else - { - for (int i = 0; i < numActiveOutputChans; ++i) - outputFormat[i].clear (infos[numActiveInputChans + i].buffers[bi], samps); - } - } - - if (postOutput) - asioObject->outputReady(); - } - - //============================================================================== - template - struct ASIOCallbackFunctions - { - static ASIOTime* JUCE_ASIOCALLBACK bufferSwitchTimeInfoCallback (ASIOTime*, long index, long) - { - if (currentASIODev[deviceIndex] != nullptr) - currentASIODev[deviceIndex]->callback (index); - - return nullptr; - } - - static void JUCE_ASIOCALLBACK bufferSwitchCallback (long index, long) - { - if (currentASIODev[deviceIndex] != nullptr) - currentASIODev[deviceIndex]->callback (index); - } - - static long JUCE_ASIOCALLBACK asioMessagesCallback (long selector, long value, void*, double*) - { - switch (selector) - { - case kAsioSelectorSupported: - if (value == kAsioResetRequest || value == kAsioEngineVersion || value == kAsioResyncRequest - || value == kAsioLatenciesChanged || value == kAsioSupportsInputMonitor) - return 1; - break; - - case kAsioBufferSizeChange: JUCE_ASIO_LOG ("kAsioBufferSizeChange"); return sendResetRequest (deviceIndex); - case kAsioResetRequest: JUCE_ASIO_LOG ("kAsioResetRequest"); return sendResetRequest (deviceIndex); - case kAsioResyncRequest: JUCE_ASIO_LOG ("kAsioResyncRequest"); return sendResetRequest (deviceIndex); - case kAsioLatenciesChanged: JUCE_ASIO_LOG ("kAsioLatenciesChanged"); return 1; - case kAsioEngineVersion: return 2; - - case kAsioSupportsTimeInfo: - case kAsioSupportsTimeCode: - return 0; - } - - return 0; - } - - static void JUCE_ASIOCALLBACK sampleRateChangedCallback (ASIOSampleRate) - { - sendResetRequest (deviceIndex); - } - - static long sendResetRequest (int index) - { - if (currentASIODev[index] != nullptr) - currentASIODev[index]->resetRequest(); - - return 1; - } - - static void setCallbacks (ASIOCallbacks& callbacks) - { - callbacks.bufferSwitch = &bufferSwitchCallback; - callbacks.asioMessage = &asioMessagesCallback; - callbacks.bufferSwitchTimeInfo = &bufferSwitchTimeInfoCallback; - callbacks.sampleRateDidChange = &sampleRateChangedCallback; - } - }; - - void setCallbackFunctions() - { - if (currentASIODev[0] == this) ASIOCallbackFunctions<0>::setCallbacks (callbacks); - else if (currentASIODev[1] == this) ASIOCallbackFunctions<1>::setCallbacks (callbacks); - else if (currentASIODev[2] == this) ASIOCallbackFunctions<2>::setCallbacks (callbacks); - else jassertfalse; - } - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ASIOAudioIODevice) -}; - -//============================================================================== -class ASIOAudioIODeviceType : public AudioIODeviceType -{ -public: - ASIOAudioIODeviceType() - : AudioIODeviceType ("ASIO"), - hasScanned (false) - { - } - - ~ASIOAudioIODeviceType() - { - masterReference.clear(); - } - - //============================================================================== - void scanForDevices() - { - hasScanned = true; - - deviceNames.clear(); - classIds.clear(); - - HKEY hk = 0; - int index = 0; - - if (RegOpenKey (HKEY_LOCAL_MACHINE, _T("software\\asio"), &hk) == ERROR_SUCCESS) - { - TCHAR name [256]; - - while (RegEnumKey (hk, index++, name, numElementsInArray (name)) == ERROR_SUCCESS) - addDriverInfo (name, hk); - - RegCloseKey (hk); - } - } - - StringArray getDeviceNames (bool /*wantInputNames*/) const - { - jassert (hasScanned); // need to call scanForDevices() before doing this - - return deviceNames; - } - - int getDefaultDeviceIndex (bool) const - { - jassert (hasScanned); // need to call scanForDevices() before doing this - - for (int i = deviceNames.size(); --i >= 0;) - if (deviceNames[i].containsIgnoreCase ("asio4all")) - return i; // asio4all is a safe choice for a default.. - - #if JUCE_DEBUG - if (deviceNames.size() > 1 && deviceNames[0].containsIgnoreCase ("digidesign")) - return 1; // (the digi m-box driver crashes the app when you run - // it in the debugger, which can be a bit annoying) - #endif - - return 0; - } - - static int findFreeSlot() - { - for (int i = 0; i < numElementsInArray (currentASIODev); ++i) - if (currentASIODev[i] == 0) - return i; - - jassertfalse; // unfortunately you can only have a finite number - // of ASIO devices open at the same time.. - return -1; - } - - int getIndexOfDevice (AudioIODevice* d, bool /*asInput*/) const - { - jassert (hasScanned); // need to call scanForDevices() before doing this - - return d == nullptr ? -1 : deviceNames.indexOf (d->getName()); - } - - bool hasSeparateInputsAndOutputs() const { return false; } - - AudioIODevice* createDevice (const String& outputDeviceName, - const String& inputDeviceName) - { - // ASIO can't open two different devices for input and output - they must be the same one. - jassert (inputDeviceName == outputDeviceName || outputDeviceName.isEmpty() || inputDeviceName.isEmpty()); - jassert (hasScanned); // need to call scanForDevices() before doing this - - const int index = deviceNames.indexOf (outputDeviceName.isNotEmpty() ? outputDeviceName - : inputDeviceName); - - if (index >= 0) - { - const int freeSlot = findFreeSlot(); - - if (freeSlot >= 0) - return new ASIOAudioIODevice (this, outputDeviceName, - classIds.getReference (index), freeSlot); - } - - return nullptr; - } - - void sendDeviceChangeToListeners() - { - callDeviceChangeListeners(); - } - - WeakReference::Master masterReference; - -private: - StringArray deviceNames; - Array classIds; - - bool hasScanned; - - //============================================================================== - static bool checkClassIsOk (const String& classId) - { - HKEY hk = 0; - bool ok = false; - - if (RegOpenKey (HKEY_CLASSES_ROOT, _T("clsid"), &hk) == ERROR_SUCCESS) - { - int index = 0; - TCHAR name [512]; - - while (RegEnumKey (hk, index++, name, numElementsInArray (name)) == ERROR_SUCCESS) - { - if (classId.equalsIgnoreCase (name)) - { - HKEY subKey, pathKey; - - if (RegOpenKeyEx (hk, name, 0, KEY_READ, &subKey) == ERROR_SUCCESS) - { - if (RegOpenKeyEx (subKey, _T("InprocServer32"), 0, KEY_READ, &pathKey) == ERROR_SUCCESS) - { - TCHAR pathName [1024] = { 0 }; - DWORD dtype = REG_SZ; - DWORD dsize = sizeof (pathName); - - if (RegQueryValueEx (pathKey, 0, 0, &dtype, (LPBYTE) pathName, &dsize) == ERROR_SUCCESS) - // In older code, this used to check for the existance of the file, but there are situations - // where our process doesn't have access to it, but where the driver still loads ok.. - ok = (pathName[0] != 0); - - RegCloseKey (pathKey); - } - - RegCloseKey (subKey); - } - - break; - } - } - - RegCloseKey (hk); - } - - return ok; - } - - //============================================================================== - void addDriverInfo (const String& keyName, HKEY hk) - { - HKEY subKey; - - if (RegOpenKeyEx (hk, keyName.toWideCharPointer(), 0, KEY_READ, &subKey) == ERROR_SUCCESS) - { - TCHAR buf [256] = { 0 }; - DWORD dtype = REG_SZ; - DWORD dsize = sizeof (buf); - - if (RegQueryValueEx (subKey, _T("clsid"), 0, &dtype, (LPBYTE) buf, &dsize) == ERROR_SUCCESS) - { - if (dsize > 0 && checkClassIsOk (buf)) - { - CLSID classId; - if (CLSIDFromString ((LPOLESTR) buf, &classId) == S_OK) - { - dtype = REG_SZ; - dsize = sizeof (buf); - String deviceName; - - if (RegQueryValueEx (subKey, _T("description"), 0, &dtype, (LPBYTE) buf, &dsize) == ERROR_SUCCESS) - deviceName = buf; - else - deviceName = keyName; - - JUCE_ASIO_LOG ("found " + deviceName); - deviceNames.add (deviceName); - classIds.add (classId); - } - } - - RegCloseKey (subKey); - } - } - } - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ASIOAudioIODeviceType) -}; - -void sendASIODeviceChangeToListeners (ASIOAudioIODeviceType* type) -{ - if (type != nullptr) - type->sendDeviceChangeToListeners(); -} - -AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_ASIO() -{ - return new ASIOAudioIODeviceType(); -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/native/juce_win32_AudioCDBurner.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/native/juce_win32_AudioCDBurner.cpp deleted file mode 100644 index 3c3befb80f..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/native/juce_win32_AudioCDBurner.cpp +++ /dev/null @@ -1,411 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -namespace CDBurnerHelpers -{ - IDiscRecorder* enumCDBurners (StringArray* list, int indexToOpen, IDiscMaster** master) - { - CoInitialize (0); - - IDiscMaster* dm; - IDiscRecorder* result = nullptr; - - if (SUCCEEDED (CoCreateInstance (CLSID_MSDiscMasterObj, 0, - CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER, - IID_IDiscMaster, - (void**) &dm))) - { - if (SUCCEEDED (dm->Open())) - { - IEnumDiscRecorders* drEnum = nullptr; - - if (SUCCEEDED (dm->EnumDiscRecorders (&drEnum))) - { - IDiscRecorder* dr = nullptr; - DWORD dummy; - int index = 0; - - while (drEnum->Next (1, &dr, &dummy) == S_OK) - { - if (indexToOpen == index) - { - result = dr; - break; - } - else if (list != nullptr) - { - BSTR path; - - if (SUCCEEDED (dr->GetPath (&path))) - list->add ((const WCHAR*) path); - } - - ++index; - dr->Release(); - } - - drEnum->Release(); - } - - if (master == 0) - dm->Close(); - } - - if (master != nullptr) - *master = dm; - else - dm->Release(); - } - - return result; - } -} - -//============================================================================== -class AudioCDBurner::Pimpl : public ComBaseClassHelper , - public Timer -{ -public: - Pimpl (AudioCDBurner& owner_, IDiscMaster* discMaster_, IDiscRecorder* discRecorder_) - : owner (owner_), discMaster (discMaster_), discRecorder (discRecorder_), redbook (0), - listener (0), progress (0), shouldCancel (false) - { - HRESULT hr = discMaster->SetActiveDiscMasterFormat (IID_IRedbookDiscMaster, (void**) &redbook); - jassert (SUCCEEDED (hr)); - hr = discMaster->SetActiveDiscRecorder (discRecorder); - //jassert (SUCCEEDED (hr)); - - lastState = getDiskState(); - startTimer (2000); - } - - ~Pimpl() {} - - void releaseObjects() - { - discRecorder->Close(); - if (redbook != nullptr) - redbook->Release(); - discRecorder->Release(); - discMaster->Release(); - Release(); - } - - JUCE_COMRESULT QueryCancel (boolean* pbCancel) - { - if (listener != nullptr && ! shouldCancel) - shouldCancel = listener->audioCDBurnProgress (progress); - - *pbCancel = shouldCancel; - - return S_OK; - } - - JUCE_COMRESULT NotifyBlockProgress (long nCompleted, long nTotal) - { - progress = nCompleted / (float) nTotal; - shouldCancel = listener != nullptr && listener->audioCDBurnProgress (progress); - - return E_NOTIMPL; - } - - JUCE_COMRESULT NotifyPnPActivity (void) { return E_NOTIMPL; } - JUCE_COMRESULT NotifyAddProgress (long /*nCompletedSteps*/, long /*nTotalSteps*/) { return E_NOTIMPL; } - JUCE_COMRESULT NotifyTrackProgress (long /*nCurrentTrack*/, long /*nTotalTracks*/) { return E_NOTIMPL; } - JUCE_COMRESULT NotifyPreparingBurn (long /*nEstimatedSeconds*/) { return E_NOTIMPL; } - JUCE_COMRESULT NotifyClosingDisc (long /*nEstimatedSeconds*/) { return E_NOTIMPL; } - JUCE_COMRESULT NotifyBurnComplete (HRESULT /*status*/) { return E_NOTIMPL; } - JUCE_COMRESULT NotifyEraseComplete (HRESULT /*status*/) { return E_NOTIMPL; } - - class ScopedDiscOpener - { - public: - ScopedDiscOpener (Pimpl& p) : pimpl (p) { pimpl.discRecorder->OpenExclusive(); } - ~ScopedDiscOpener() { pimpl.discRecorder->Close(); } - - private: - Pimpl& pimpl; - - JUCE_DECLARE_NON_COPYABLE (ScopedDiscOpener) - }; - - DiskState getDiskState() - { - const ScopedDiscOpener opener (*this); - - long type, flags; - HRESULT hr = discRecorder->QueryMediaType (&type, &flags); - - if (FAILED (hr)) - return unknown; - - if (type != 0 && (flags & MEDIA_WRITABLE) != 0) - return writableDiskPresent; - - if (type == 0) - return noDisc; - - return readOnlyDiskPresent; - } - - int getIntProperty (const LPOLESTR name, const int defaultReturn) const - { - ComSmartPtr prop; - if (FAILED (discRecorder->GetRecorderProperties (prop.resetAndGetPointerAddress()))) - return defaultReturn; - - PROPSPEC iPropSpec; - iPropSpec.ulKind = PRSPEC_LPWSTR; - iPropSpec.lpwstr = name; - - PROPVARIANT iPropVariant; - return FAILED (prop->ReadMultiple (1, &iPropSpec, &iPropVariant)) - ? defaultReturn : (int) iPropVariant.lVal; - } - - bool setIntProperty (const LPOLESTR name, const int value) const - { - ComSmartPtr prop; - if (FAILED (discRecorder->GetRecorderProperties (prop.resetAndGetPointerAddress()))) - return false; - - PROPSPEC iPropSpec; - iPropSpec.ulKind = PRSPEC_LPWSTR; - iPropSpec.lpwstr = name; - - PROPVARIANT iPropVariant; - if (FAILED (prop->ReadMultiple (1, &iPropSpec, &iPropVariant))) - return false; - - iPropVariant.lVal = (long) value; - return SUCCEEDED (prop->WriteMultiple (1, &iPropSpec, &iPropVariant, iPropVariant.vt)) - && SUCCEEDED (discRecorder->SetRecorderProperties (prop)); - } - - void timerCallback() override - { - const DiskState state = getDiskState(); - - if (state != lastState) - { - lastState = state; - owner.sendChangeMessage(); - } - } - - AudioCDBurner& owner; - DiskState lastState; - IDiscMaster* discMaster; - IDiscRecorder* discRecorder; - IRedbookDiscMaster* redbook; - AudioCDBurner::BurnProgressListener* listener; - float progress; - bool shouldCancel; -}; - -//============================================================================== -AudioCDBurner::AudioCDBurner (const int deviceIndex) -{ - IDiscMaster* discMaster = nullptr; - IDiscRecorder* discRecorder = CDBurnerHelpers::enumCDBurners (0, deviceIndex, &discMaster); - - if (discRecorder != nullptr) - pimpl = new Pimpl (*this, discMaster, discRecorder); -} - -AudioCDBurner::~AudioCDBurner() -{ - if (pimpl != nullptr) - pimpl.release()->releaseObjects(); -} - -StringArray AudioCDBurner::findAvailableDevices() -{ - StringArray devs; - CDBurnerHelpers::enumCDBurners (&devs, -1, 0); - return devs; -} - -AudioCDBurner* AudioCDBurner::openDevice (const int deviceIndex) -{ - ScopedPointer b (new AudioCDBurner (deviceIndex)); - - if (b->pimpl == 0) - b = nullptr; - - return b.release(); -} - -AudioCDBurner::DiskState AudioCDBurner::getDiskState() const -{ - return pimpl->getDiskState(); -} - -bool AudioCDBurner::isDiskPresent() const -{ - return getDiskState() == writableDiskPresent; -} - -bool AudioCDBurner::openTray() -{ - const Pimpl::ScopedDiscOpener opener (*pimpl); - return SUCCEEDED (pimpl->discRecorder->Eject()); -} - -AudioCDBurner::DiskState AudioCDBurner::waitUntilStateChange (int timeOutMilliseconds) -{ - const int64 timeout = Time::currentTimeMillis() + timeOutMilliseconds; - DiskState oldState = getDiskState(); - DiskState newState = oldState; - - while (newState == oldState && Time::currentTimeMillis() < timeout) - { - newState = getDiskState(); - Thread::sleep (jmin (250, (int) (timeout - Time::currentTimeMillis()))); - } - - return newState; -} - -Array AudioCDBurner::getAvailableWriteSpeeds() const -{ - Array results; - const int maxSpeed = pimpl->getIntProperty (L"MaxWriteSpeed", 1); - const int speeds[] = { 1, 2, 4, 8, 12, 16, 20, 24, 32, 40, 64, 80 }; - - for (int i = 0; i < numElementsInArray (speeds); ++i) - if (speeds[i] <= maxSpeed) - results.add (speeds[i]); - - results.addIfNotAlreadyThere (maxSpeed); - return results; -} - -bool AudioCDBurner::setBufferUnderrunProtection (const bool shouldBeEnabled) -{ - if (pimpl->getIntProperty (L"BufferUnderrunFreeCapable", 0) == 0) - return false; - - pimpl->setIntProperty (L"EnableBufferUnderrunFree", shouldBeEnabled ? -1 : 0); - return pimpl->getIntProperty (L"EnableBufferUnderrunFree", 0) != 0; -} - -int AudioCDBurner::getNumAvailableAudioBlocks() const -{ - long blocksFree = 0; - pimpl->redbook->GetAvailableAudioTrackBlocks (&blocksFree); - return blocksFree; -} - -String AudioCDBurner::burn (AudioCDBurner::BurnProgressListener* listener, bool ejectDiscAfterwards, - bool performFakeBurnForTesting, int writeSpeed) -{ - pimpl->setIntProperty (L"WriteSpeed", writeSpeed > 0 ? writeSpeed : -1); - - pimpl->listener = listener; - pimpl->progress = 0; - pimpl->shouldCancel = false; - - UINT_PTR cookie; - HRESULT hr = pimpl->discMaster->ProgressAdvise ((AudioCDBurner::Pimpl*) pimpl, &cookie); - - hr = pimpl->discMaster->RecordDisc (performFakeBurnForTesting, - ejectDiscAfterwards); - - String error; - if (hr != S_OK) - { - const char* e = "Couldn't open or write to the CD device"; - - if (hr == IMAPI_E_USERABORT) - e = "User cancelled the write operation"; - else if (hr == IMAPI_E_MEDIUM_NOTPRESENT || hr == IMAPI_E_TRACKOPEN) - e = "No Disk present"; - - error = e; - } - - pimpl->discMaster->ProgressUnadvise (cookie); - pimpl->listener = 0; - - return error; -} - -bool AudioCDBurner::addAudioTrack (AudioSource* audioSource, int numSamples) -{ - if (audioSource == 0) - return false; - - ScopedPointer source (audioSource); - - long bytesPerBlock; - HRESULT hr = pimpl->redbook->GetAudioBlockSize (&bytesPerBlock); - - const int samplesPerBlock = bytesPerBlock / 4; - bool ok = true; - - hr = pimpl->redbook->CreateAudioTrack ((long) numSamples / (bytesPerBlock * 4)); - - HeapBlock buffer (bytesPerBlock); - AudioSampleBuffer sourceBuffer (2, samplesPerBlock); - int samplesDone = 0; - - source->prepareToPlay (samplesPerBlock, 44100.0); - - while (ok) - { - { - AudioSourceChannelInfo info (&sourceBuffer, 0, samplesPerBlock); - sourceBuffer.clear(); - - source->getNextAudioBlock (info); - } - - buffer.clear (bytesPerBlock); - - typedef AudioData::Pointer CDSampleFormat; - - typedef AudioData::Pointer SourceSampleFormat; - - CDSampleFormat left (buffer, 2); - left.convertSamples (SourceSampleFormat (sourceBuffer.getReadPointer (0)), samplesPerBlock); - CDSampleFormat right (buffer + 2, 2); - right.convertSamples (SourceSampleFormat (sourceBuffer.getReadPointer (1)), samplesPerBlock); - - hr = pimpl->redbook->AddAudioTrackBlocks (buffer, bytesPerBlock); - - if (FAILED (hr)) - ok = false; - - samplesDone += samplesPerBlock; - - if (samplesDone >= numSamples) - break; - } - - hr = pimpl->redbook->CloseAudioTrack(); - return ok && hr == S_OK; -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/native/juce_win32_AudioCDReader.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/native/juce_win32_AudioCDReader.cpp deleted file mode 100644 index 064ca9148f..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/native/juce_win32_AudioCDReader.cpp +++ /dev/null @@ -1,1309 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -namespace CDReaderHelpers -{ - -#define FILE_ANY_ACCESS 0 -#ifndef FILE_READ_ACCESS - #define FILE_READ_ACCESS 1 -#endif -#ifndef FILE_WRITE_ACCESS - #define FILE_WRITE_ACCESS 2 -#endif - -#define METHOD_BUFFERED 0 -#define IOCTL_SCSI_BASE 4 -#define SCSI_IOCTL_DATA_OUT 0 -#define SCSI_IOCTL_DATA_IN 1 -#define SCSI_IOCTL_DATA_UNSPECIFIED 2 - -#define CTL_CODE2(DevType, Function, Method, Access) (((DevType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method)) -#define IOCTL_SCSI_PASS_THROUGH_DIRECT CTL_CODE2( IOCTL_SCSI_BASE, 0x0405, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS ) -#define IOCTL_SCSI_GET_ADDRESS CTL_CODE2( IOCTL_SCSI_BASE, 0x0406, METHOD_BUFFERED, FILE_ANY_ACCESS ) - -#define SENSE_LEN 14 -#define SRB_ENABLE_RESIDUAL_COUNT 0x04 -#define SRB_DIR_IN 0x08 -#define SRB_DIR_OUT 0x10 -#define SRB_EVENT_NOTIFY 0x40 -#define SC_HA_INQUIRY 0x00 -#define SC_GET_DEV_TYPE 0x01 -#define SC_EXEC_SCSI_CMD 0x02 -#define SS_PENDING 0x00 -#define SS_COMP 0x01 -#define SS_ERR 0x04 - -enum -{ - READTYPE_ANY = 0, - READTYPE_ATAPI1 = 1, - READTYPE_ATAPI2 = 2, - READTYPE_READ6 = 3, - READTYPE_READ10 = 4, - READTYPE_READ_D8 = 5, - READTYPE_READ_D4 = 6, - READTYPE_READ_D4_1 = 7, - READTYPE_READ10_2 = 8 -}; - -struct SCSI_PASS_THROUGH -{ - USHORT Length; - UCHAR ScsiStatus; - UCHAR PathId; - UCHAR TargetId; - UCHAR Lun; - UCHAR CdbLength; - UCHAR SenseInfoLength; - UCHAR DataIn; - ULONG DataTransferLength; - ULONG TimeOutValue; - ULONG DataBufferOffset; - ULONG SenseInfoOffset; - UCHAR Cdb[16]; -}; - -struct SCSI_PASS_THROUGH_DIRECT -{ - USHORT Length; - UCHAR ScsiStatus; - UCHAR PathId; - UCHAR TargetId; - UCHAR Lun; - UCHAR CdbLength; - UCHAR SenseInfoLength; - UCHAR DataIn; - ULONG DataTransferLength; - ULONG TimeOutValue; - PVOID DataBuffer; - ULONG SenseInfoOffset; - UCHAR Cdb[16]; -}; - -struct SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER -{ - SCSI_PASS_THROUGH_DIRECT spt; - ULONG Filler; - UCHAR ucSenseBuf[32]; -}; - -struct SCSI_ADDRESS -{ - ULONG Length; - UCHAR PortNumber; - UCHAR PathId; - UCHAR TargetId; - UCHAR Lun; -}; - -#pragma pack(1) - -struct SRB_GDEVBlock -{ - BYTE SRB_Cmd; - BYTE SRB_Status; - BYTE SRB_HaID; - BYTE SRB_Flags; - DWORD SRB_Hdr_Rsvd; - BYTE SRB_Target; - BYTE SRB_Lun; - BYTE SRB_DeviceType; - BYTE SRB_Rsvd1; - BYTE pad[68]; -}; - - -struct SRB_ExecSCSICmd -{ - BYTE SRB_Cmd; - BYTE SRB_Status; - BYTE SRB_HaID; - BYTE SRB_Flags; - DWORD SRB_Hdr_Rsvd; - BYTE SRB_Target; - BYTE SRB_Lun; - WORD SRB_Rsvd1; - DWORD SRB_BufLen; - BYTE *SRB_BufPointer; - BYTE SRB_SenseLen; - BYTE SRB_CDBLen; - BYTE SRB_HaStat; - BYTE SRB_TargStat; - VOID *SRB_PostProc; - BYTE SRB_Rsvd2[20]; - BYTE CDBByte[16]; - BYTE SenseArea[SENSE_LEN + 2]; -}; - -struct SRB -{ - BYTE SRB_Cmd; - BYTE SRB_Status; - BYTE SRB_HaId; - BYTE SRB_Flags; - DWORD SRB_Hdr_Rsvd; -}; - -struct TOCTRACK -{ - BYTE rsvd; - BYTE ADR; - BYTE trackNumber; - BYTE rsvd2; - BYTE addr[4]; -}; - -struct TOC -{ - WORD tocLen; - BYTE firstTrack; - BYTE lastTrack; - TOCTRACK tracks[100]; -}; - -#pragma pack() - -//============================================================================== -struct CDDeviceDescription -{ - CDDeviceDescription() : ha (0), tgt (0), lun (0), scsiDriveLetter (0) - { - } - - void createDescription (const char* data) - { - description << String (data + 8, 8).trim() // vendor - << ' ' << String (data + 16, 16).trim() // product id - << ' ' << String (data + 32, 4).trim(); // rev - } - - String description; - BYTE ha, tgt, lun; - char scsiDriveLetter; // will be 0 if not using scsi -}; - -//============================================================================== -class CDReadBuffer -{ -public: - CDReadBuffer (const int numberOfFrames) - : startFrame (0), numFrames (0), dataStartOffset (0), - dataLength (0), bufferSize (2352 * numberOfFrames), index (0), - buffer (bufferSize), wantsIndex (false) - { - } - - bool isZero() const noexcept - { - for (int i = 0; i < dataLength; ++i) - if (buffer [dataStartOffset + i] != 0) - return false; - - return true; - } - - int startFrame, numFrames, dataStartOffset; - int dataLength, bufferSize, index; - HeapBlock buffer; - bool wantsIndex; -}; - -class CDDeviceHandle; - -//============================================================================== -class CDController -{ -public: - CDController() : initialised (false) {} - virtual ~CDController() {} - - virtual bool read (CDReadBuffer&) = 0; - virtual void shutDown() {} - - bool readAudio (CDReadBuffer& rb, CDReadBuffer* overlapBuffer = 0); - int getLastIndex(); - -public: - CDDeviceHandle* deviceInfo; - int framesToCheck, framesOverlap; - bool initialised; - - void prepare (SRB_ExecSCSICmd& s); - void perform (SRB_ExecSCSICmd& s); - void setPaused (bool paused); -}; - - -//============================================================================== -class CDDeviceHandle -{ -public: - CDDeviceHandle (const CDDeviceDescription& device, HANDLE scsiHandle_) - : info (device), scsiHandle (scsiHandle_), readType (READTYPE_ANY) - { - } - - ~CDDeviceHandle() - { - if (controller != nullptr) - { - controller->shutDown(); - controller = 0; - } - - if (scsiHandle != 0) - CloseHandle (scsiHandle); - } - - bool readTOC (TOC* lpToc); - bool readAudio (CDReadBuffer& buffer, CDReadBuffer* overlapBuffer = 0); - void openDrawer (bool shouldBeOpen); - void performScsiCommand (HANDLE event, SRB_ExecSCSICmd& s); - - CDDeviceDescription info; - HANDLE scsiHandle; - BYTE readType; - -private: - ScopedPointer controller; - - bool testController (int readType, CDController* newController, CDReadBuffer& bufferToUse); -}; - -//============================================================================== -HANDLE createSCSIDeviceHandle (const char driveLetter) -{ - TCHAR devicePath[] = { '\\', '\\', '.', '\\', driveLetter, ':', 0, 0 }; - DWORD flags = GENERIC_READ | GENERIC_WRITE; - HANDLE h = CreateFile (devicePath, flags, FILE_SHARE_WRITE | FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); - - if (h == INVALID_HANDLE_VALUE) - { - flags ^= GENERIC_WRITE; - h = CreateFile (devicePath, flags, FILE_SHARE_WRITE | FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); - } - - return h; -} - -void findCDDevices (Array& list) -{ - for (char driveLetter = 'b'; driveLetter <= 'z'; ++driveLetter) - { - TCHAR drivePath[] = { driveLetter, ':', '\\', 0, 0 }; - - if (GetDriveType (drivePath) == DRIVE_CDROM) - { - HANDLE h = createSCSIDeviceHandle (driveLetter); - - if (h != INVALID_HANDLE_VALUE) - { - char buffer[100] = { 0 }; - - SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER p = { 0 }; - p.spt.Length = sizeof (SCSI_PASS_THROUGH); - p.spt.CdbLength = 6; - p.spt.SenseInfoLength = 24; - p.spt.DataIn = SCSI_IOCTL_DATA_IN; - p.spt.DataTransferLength = sizeof (buffer); - p.spt.TimeOutValue = 2; - p.spt.DataBuffer = buffer; - p.spt.SenseInfoOffset = offsetof (SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER, ucSenseBuf); - p.spt.Cdb[0] = 0x12; - p.spt.Cdb[4] = 100; - - DWORD bytesReturned = 0; - - if (DeviceIoControl (h, IOCTL_SCSI_PASS_THROUGH_DIRECT, - &p, sizeof (p), &p, sizeof (p), - &bytesReturned, 0) != 0) - { - CDDeviceDescription dev; - dev.scsiDriveLetter = driveLetter; - dev.createDescription (buffer); - - SCSI_ADDRESS scsiAddr = { 0 }; - scsiAddr.Length = sizeof (scsiAddr); - - if (DeviceIoControl (h, IOCTL_SCSI_GET_ADDRESS, - 0, 0, &scsiAddr, sizeof (scsiAddr), - &bytesReturned, 0) != 0) - { - dev.ha = scsiAddr.PortNumber; - dev.tgt = scsiAddr.TargetId; - dev.lun = scsiAddr.Lun; - list.add (dev); - } - } - - CloseHandle (h); - } - } - } -} - -DWORD performScsiPassThroughCommand (SRB_ExecSCSICmd* const srb, const char driveLetter, - HANDLE& deviceHandle, const bool retryOnFailure) -{ - SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER s = { 0 }; - s.spt.Length = sizeof (SCSI_PASS_THROUGH); - s.spt.CdbLength = srb->SRB_CDBLen; - - s.spt.DataIn = (BYTE) ((srb->SRB_Flags & SRB_DIR_IN) - ? SCSI_IOCTL_DATA_IN - : ((srb->SRB_Flags & SRB_DIR_OUT) - ? SCSI_IOCTL_DATA_OUT - : SCSI_IOCTL_DATA_UNSPECIFIED)); - - s.spt.DataTransferLength = srb->SRB_BufLen; - s.spt.TimeOutValue = 5; - s.spt.DataBuffer = srb->SRB_BufPointer; - s.spt.SenseInfoOffset = offsetof (SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER, ucSenseBuf); - - memcpy (s.spt.Cdb, srb->CDBByte, srb->SRB_CDBLen); - - srb->SRB_Status = SS_ERR; - srb->SRB_TargStat = 0x0004; - - DWORD bytesReturned = 0; - - if (DeviceIoControl (deviceHandle, IOCTL_SCSI_PASS_THROUGH_DIRECT, - &s, sizeof (s), &s, sizeof (s), &bytesReturned, 0) != 0) - { - srb->SRB_Status = SS_COMP; - } - else if (retryOnFailure) - { - const DWORD error = GetLastError(); - - if ((error == ERROR_MEDIA_CHANGED) || (error == ERROR_INVALID_HANDLE)) - { - if (error != ERROR_INVALID_HANDLE) - CloseHandle (deviceHandle); - - deviceHandle = createSCSIDeviceHandle (driveLetter); - - return performScsiPassThroughCommand (srb, driveLetter, deviceHandle, false); - } - } - - return srb->SRB_Status; -} - - -//============================================================================== -// Controller types.. - -class ControllerType1 : public CDController -{ -public: - ControllerType1() {} - - bool read (CDReadBuffer& rb) - { - if (rb.numFrames * 2352 > rb.bufferSize) - return false; - - SRB_ExecSCSICmd s; - prepare (s); - s.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY; - s.SRB_BufLen = rb.bufferSize; - s.SRB_BufPointer = rb.buffer; - s.SRB_CDBLen = 12; - s.CDBByte[0] = 0xBE; - s.CDBByte[3] = (BYTE) ((rb.startFrame >> 16) & 0xFF); - s.CDBByte[4] = (BYTE) ((rb.startFrame >> 8) & 0xFF); - s.CDBByte[5] = (BYTE) (rb.startFrame & 0xFF); - s.CDBByte[8] = (BYTE) (rb.numFrames & 0xFF); - s.CDBByte[9] = (BYTE) (deviceInfo->readType == READTYPE_ATAPI1 ? 0x10 : 0xF0); - perform (s); - - if (s.SRB_Status != SS_COMP) - return false; - - rb.dataLength = rb.numFrames * 2352; - rb.dataStartOffset = 0; - return true; - } -}; - -//============================================================================== -class ControllerType2 : public CDController -{ -public: - ControllerType2() {} - - void shutDown() - { - if (initialised) - { - BYTE bufPointer[] = { 0, 0, 0, 8, 83, 0, 0, 0, 0, 0, 8, 0 }; - - SRB_ExecSCSICmd s; - prepare (s); - s.SRB_Flags = SRB_EVENT_NOTIFY | SRB_ENABLE_RESIDUAL_COUNT; - s.SRB_BufLen = 0x0C; - s.SRB_BufPointer = bufPointer; - s.SRB_CDBLen = 6; - s.CDBByte[0] = 0x15; - s.CDBByte[4] = 0x0C; - perform (s); - } - } - - bool init() - { - SRB_ExecSCSICmd s; - s.SRB_Status = SS_ERR; - - if (deviceInfo->readType == READTYPE_READ10_2) - { - BYTE bufPointer1[] = { 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 9, 48, 35, 6, 0, 0, 0, 0, 0, 128 }; - BYTE bufPointer2[] = { 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 9, 48, 1, 6, 32, 7, 0, 0, 0, 0 }; - - for (int i = 0; i < 2; ++i) - { - prepare (s); - s.SRB_Flags = SRB_EVENT_NOTIFY; - s.SRB_BufLen = 0x14; - s.SRB_BufPointer = (i == 0) ? bufPointer1 : bufPointer2; - s.SRB_CDBLen = 6; - s.CDBByte[0] = 0x15; - s.CDBByte[1] = 0x10; - s.CDBByte[4] = 0x14; - perform (s); - - if (s.SRB_Status != SS_COMP) - return false; - } - } - else - { - BYTE bufPointer[] = { 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 9, 48 }; - - prepare (s); - s.SRB_Flags = SRB_EVENT_NOTIFY; - s.SRB_BufLen = 0x0C; - s.SRB_BufPointer = bufPointer; - s.SRB_CDBLen = 6; - s.CDBByte[0] = 0x15; - s.CDBByte[4] = 0x0C; - perform (s); - } - - return s.SRB_Status == SS_COMP; - } - - bool read (CDReadBuffer& rb) - { - if (rb.numFrames * 2352 > rb.bufferSize) - return false; - - if (! initialised) - { - initialised = init(); - - if (! initialised) - return false; - } - - SRB_ExecSCSICmd s; - prepare (s); - s.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY; - s.SRB_BufLen = rb.bufferSize; - s.SRB_BufPointer = rb.buffer; - s.SRB_CDBLen = 10; - s.CDBByte[0] = 0x28; - s.CDBByte[1] = (BYTE) (deviceInfo->info.lun << 5); - s.CDBByte[3] = (BYTE) ((rb.startFrame >> 16) & 0xFF); - s.CDBByte[4] = (BYTE) ((rb.startFrame >> 8) & 0xFF); - s.CDBByte[5] = (BYTE) (rb.startFrame & 0xFF); - s.CDBByte[8] = (BYTE) (rb.numFrames & 0xFF); - perform (s); - - if (s.SRB_Status != SS_COMP) - return false; - - rb.dataLength = rb.numFrames * 2352; - rb.dataStartOffset = 0; - return true; - } -}; - -//============================================================================== -class ControllerType3 : public CDController -{ -public: - ControllerType3() {} - - bool read (CDReadBuffer& rb) - { - if (rb.numFrames * 2352 > rb.bufferSize) - return false; - - if (! initialised) - { - setPaused (false); - initialised = true; - } - - SRB_ExecSCSICmd s; - prepare (s); - s.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY; - s.SRB_BufLen = rb.numFrames * 2352; - s.SRB_BufPointer = rb.buffer; - s.SRB_CDBLen = 12; - s.CDBByte[0] = 0xD8; - s.CDBByte[3] = (BYTE) ((rb.startFrame >> 16) & 0xFF); - s.CDBByte[4] = (BYTE) ((rb.startFrame >> 8) & 0xFF); - s.CDBByte[5] = (BYTE) (rb.startFrame & 0xFF); - s.CDBByte[9] = (BYTE) (rb.numFrames & 0xFF); - perform (s); - - if (s.SRB_Status != SS_COMP) - return false; - - rb.dataLength = rb.numFrames * 2352; - rb.dataStartOffset = 0; - return true; - } -}; - -//============================================================================== -class ControllerType4 : public CDController -{ -public: - ControllerType4() {} - - bool selectD4Mode() - { - BYTE bufPointer[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 48 }; - - SRB_ExecSCSICmd s; - prepare (s); - s.SRB_Flags = SRB_EVENT_NOTIFY; - s.SRB_CDBLen = 6; - s.SRB_BufLen = 12; - s.SRB_BufPointer = bufPointer; - s.CDBByte[0] = 0x15; - s.CDBByte[1] = 0x10; - s.CDBByte[4] = 0x08; - perform (s); - - return s.SRB_Status == SS_COMP; - } - - bool read (CDReadBuffer& rb) - { - if (rb.numFrames * 2352 > rb.bufferSize) - return false; - - if (! initialised) - { - setPaused (true); - - if (deviceInfo->readType == READTYPE_READ_D4_1) - selectD4Mode(); - - initialised = true; - } - - SRB_ExecSCSICmd s; - prepare (s); - s.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY; - s.SRB_BufLen = rb.bufferSize; - s.SRB_BufPointer = rb.buffer; - s.SRB_CDBLen = 10; - s.CDBByte[0] = 0xD4; - s.CDBByte[3] = (BYTE) ((rb.startFrame >> 16) & 0xFF); - s.CDBByte[4] = (BYTE) ((rb.startFrame >> 8) & 0xFF); - s.CDBByte[5] = (BYTE) (rb.startFrame & 0xFF); - s.CDBByte[8] = (BYTE) (rb.numFrames & 0xFF); - perform (s); - - if (s.SRB_Status != SS_COMP) - return false; - - rb.dataLength = rb.numFrames * 2352; - rb.dataStartOffset = 0; - return true; - } -}; - - -//============================================================================== -void CDController::prepare (SRB_ExecSCSICmd& s) -{ - zerostruct (s); - s.SRB_Cmd = SC_EXEC_SCSI_CMD; - s.SRB_HaID = deviceInfo->info.ha; - s.SRB_Target = deviceInfo->info.tgt; - s.SRB_Lun = deviceInfo->info.lun; - s.SRB_SenseLen = SENSE_LEN; -} - -void CDController::perform (SRB_ExecSCSICmd& s) -{ - s.SRB_PostProc = CreateEvent (0, TRUE, FALSE, 0); - - deviceInfo->performScsiCommand (s.SRB_PostProc, s); -} - -void CDController::setPaused (bool paused) -{ - SRB_ExecSCSICmd s; - prepare (s); - s.SRB_Flags = SRB_EVENT_NOTIFY; - s.SRB_CDBLen = 10; - s.CDBByte[0] = 0x4B; - s.CDBByte[8] = (BYTE) (paused ? 0 : 1); - perform (s); -} - -bool CDController::readAudio (CDReadBuffer& rb, CDReadBuffer* overlapBuffer) -{ - if (overlapBuffer != nullptr) - { - const bool canDoJitter = (overlapBuffer->bufferSize >= 2352 * framesToCheck); - const bool doJitter = canDoJitter && ! overlapBuffer->isZero(); - - if (doJitter - && overlapBuffer->startFrame > 0 - && overlapBuffer->numFrames > 0 - && overlapBuffer->dataLength > 0) - { - const int numFrames = rb.numFrames; - - if (overlapBuffer->startFrame == (rb.startFrame - framesToCheck)) - { - rb.startFrame -= framesOverlap; - - if (framesToCheck < framesOverlap - && numFrames + framesOverlap <= rb.bufferSize / 2352) - rb.numFrames += framesOverlap; - } - else - { - overlapBuffer->dataLength = 0; - overlapBuffer->startFrame = 0; - overlapBuffer->numFrames = 0; - } - } - - if (! read (rb)) - return false; - - if (doJitter) - { - const int checkLen = framesToCheck * 2352; - const int maxToCheck = rb.dataLength - checkLen; - - if (overlapBuffer->dataLength == 0 || overlapBuffer->isZero()) - return true; - - BYTE* const p = overlapBuffer->buffer + overlapBuffer->dataStartOffset; - bool found = false; - - for (int i = 0; i < maxToCheck; ++i) - { - if (memcmp (p, rb.buffer + i, checkLen) == 0) - { - i += checkLen; - rb.dataStartOffset = i; - rb.dataLength -= i; - rb.startFrame = overlapBuffer->startFrame + framesToCheck; - found = true; - break; - } - } - - rb.numFrames = rb.dataLength / 2352; - rb.dataLength = 2352 * rb.numFrames; - - if (! found) - return false; - } - - if (canDoJitter) - { - memcpy (overlapBuffer->buffer, - rb.buffer + rb.dataStartOffset + 2352 * (rb.numFrames - framesToCheck), - 2352 * framesToCheck); - - overlapBuffer->startFrame = rb.startFrame + rb.numFrames - framesToCheck; - overlapBuffer->numFrames = framesToCheck; - overlapBuffer->dataLength = 2352 * framesToCheck; - overlapBuffer->dataStartOffset = 0; - } - else - { - overlapBuffer->startFrame = 0; - overlapBuffer->numFrames = 0; - overlapBuffer->dataLength = 0; - } - - return true; - } - - return read (rb); -} - -int CDController::getLastIndex() -{ - char qdata[100]; - - SRB_ExecSCSICmd s; - prepare (s); - s.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY; - s.SRB_BufLen = sizeof (qdata); - s.SRB_BufPointer = (BYTE*) qdata; - s.SRB_CDBLen = 12; - s.CDBByte[0] = 0x42; - s.CDBByte[1] = (BYTE) (deviceInfo->info.lun << 5); - s.CDBByte[2] = 64; - s.CDBByte[3] = 1; // get current position - s.CDBByte[7] = 0; - s.CDBByte[8] = (BYTE) sizeof (qdata); - perform (s); - - return s.SRB_Status == SS_COMP ? qdata[7] : 0; -} - -//============================================================================== -bool CDDeviceHandle::readTOC (TOC* lpToc) -{ - SRB_ExecSCSICmd s = { 0 }; - s.SRB_Cmd = SC_EXEC_SCSI_CMD; - s.SRB_HaID = info.ha; - s.SRB_Target = info.tgt; - s.SRB_Lun = info.lun; - s.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY; - s.SRB_BufLen = 0x324; - s.SRB_BufPointer = (BYTE*) lpToc; - s.SRB_SenseLen = 0x0E; - s.SRB_CDBLen = 0x0A; - s.SRB_PostProc = CreateEvent (0, TRUE, FALSE, 0); - s.CDBByte[0] = 0x43; - s.CDBByte[1] = 0x00; - s.CDBByte[7] = 0x03; - s.CDBByte[8] = 0x24; - - performScsiCommand (s.SRB_PostProc, s); - return (s.SRB_Status == SS_COMP); -} - -void CDDeviceHandle::performScsiCommand (HANDLE event, SRB_ExecSCSICmd& s) -{ - ResetEvent (event); - DWORD status = performScsiPassThroughCommand ((SRB_ExecSCSICmd*) &s, info.scsiDriveLetter, scsiHandle, true); - - if (status == SS_PENDING) - WaitForSingleObject (event, 4000); - - CloseHandle (event); -} - -bool CDDeviceHandle::readAudio (CDReadBuffer& buffer, CDReadBuffer* overlapBuffer) -{ - if (controller == 0) - { - testController (READTYPE_ATAPI2, new ControllerType1(), buffer) - || testController (READTYPE_ATAPI1, new ControllerType1(), buffer) - || testController (READTYPE_READ10_2, new ControllerType2(), buffer) - || testController (READTYPE_READ10, new ControllerType2(), buffer) - || testController (READTYPE_READ_D8, new ControllerType3(), buffer) - || testController (READTYPE_READ_D4, new ControllerType4(), buffer) - || testController (READTYPE_READ_D4_1, new ControllerType4(), buffer); - } - - buffer.index = 0; - - if (controller != nullptr && controller->readAudio (buffer, overlapBuffer)) - { - if (buffer.wantsIndex) - buffer.index = controller->getLastIndex(); - - return true; - } - - return false; -} - -void CDDeviceHandle::openDrawer (bool shouldBeOpen) -{ - if (shouldBeOpen) - { - if (controller != nullptr) - { - controller->shutDown(); - controller = nullptr; - } - - if (scsiHandle != 0) - { - CloseHandle (scsiHandle); - scsiHandle = 0; - } - } - - SRB_ExecSCSICmd s = { 0 }; - s.SRB_Cmd = SC_EXEC_SCSI_CMD; - s.SRB_HaID = info.ha; - s.SRB_Target = info.tgt; - s.SRB_Lun = info.lun; - s.SRB_SenseLen = SENSE_LEN; - s.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY; - s.SRB_BufLen = 0; - s.SRB_BufPointer = 0; - s.SRB_CDBLen = 12; - s.CDBByte[0] = 0x1b; - s.CDBByte[1] = (BYTE) (info.lun << 5); - s.CDBByte[4] = (BYTE) (shouldBeOpen ? 2 : 3); - s.SRB_PostProc = CreateEvent (0, TRUE, FALSE, 0); - - performScsiCommand (s.SRB_PostProc, s); -} - -bool CDDeviceHandle::testController (const int type, CDController* const newController, CDReadBuffer& rb) -{ - controller = newController; - readType = (BYTE) type; - - controller->deviceInfo = this; - controller->framesToCheck = 1; - controller->framesOverlap = 3; - - bool passed = false; - memset (rb.buffer, 0xcd, rb.bufferSize); - - if (controller->read (rb)) - { - passed = true; - int* p = (int*) (rb.buffer + rb.dataStartOffset); - int wrong = 0; - - for (int i = rb.dataLength / 4; --i >= 0;) - { - if (*p++ == (int) 0xcdcdcdcd) - { - if (++wrong == 4) - { - passed = false; - break; - } - } - else - { - wrong = 0; - } - } - } - - if (! passed) - { - controller->shutDown(); - controller = nullptr; - } - - return passed; -} - - -//============================================================================== -struct CDDeviceWrapper -{ - CDDeviceWrapper (const CDDeviceDescription& device, HANDLE scsiHandle) - : deviceHandle (device, scsiHandle), overlapBuffer (3), jitter (false) - { - // xxx jitter never seemed to actually be enabled (??) - } - - CDDeviceHandle deviceHandle; - CDReadBuffer overlapBuffer; - bool jitter; -}; - -//============================================================================== -int getAddressOfTrack (const TOCTRACK& t) noexcept -{ - return (((DWORD) t.addr[0]) << 24) + (((DWORD) t.addr[1]) << 16) - + (((DWORD) t.addr[2]) << 8) + ((DWORD) t.addr[3]); -} - -const int samplesPerFrame = 44100 / 75; -const int bytesPerFrame = samplesPerFrame * 4; -const int framesPerIndexRead = 4; - -} - -//============================================================================== -StringArray AudioCDReader::getAvailableCDNames() -{ - using namespace CDReaderHelpers; - StringArray results; - - Array list; - findCDDevices (list); - - for (int i = 0; i < list.size(); ++i) - { - String s; - if (list[i].scsiDriveLetter > 0) - s << String::charToString (list[i].scsiDriveLetter).toUpperCase() << ": "; - - s << list[i].description; - results.add (s); - } - - return results; -} - -AudioCDReader* AudioCDReader::createReaderForCD (const int deviceIndex) -{ - using namespace CDReaderHelpers; - - Array list; - findCDDevices (list); - - if (isPositiveAndBelow (deviceIndex, list.size())) - { - HANDLE h = createSCSIDeviceHandle (list [deviceIndex].scsiDriveLetter); - - if (h != INVALID_HANDLE_VALUE) - { - ScopedPointer cd (new AudioCDReader (new CDDeviceWrapper (list [deviceIndex], h))); - - if (cd->lengthInSamples > 0) - return cd.release(); - } - } - - return nullptr; -} - -AudioCDReader::AudioCDReader (void* handle_) - : AudioFormatReader (0, "CD Audio"), - handle (handle_), - indexingEnabled (false), - lastIndex (0), - firstFrameInBuffer (0), - samplesInBuffer (0) -{ - using namespace CDReaderHelpers; - jassert (handle_ != nullptr); - - refreshTrackLengths(); - - sampleRate = 44100.0; - bitsPerSample = 16; - numChannels = 2; - usesFloatingPointData = false; - - buffer.setSize (4 * bytesPerFrame, true); -} - -AudioCDReader::~AudioCDReader() -{ - using namespace CDReaderHelpers; - CDDeviceWrapper* const device = static_cast (handle); - delete device; -} - -bool AudioCDReader::readSamples (int** destSamples, int numDestChannels, int startOffsetInDestBuffer, - int64 startSampleInFile, int numSamples) -{ - using namespace CDReaderHelpers; - CDDeviceWrapper* const device = static_cast (handle); - - bool ok = true; - - while (numSamples > 0) - { - const int bufferStartSample = firstFrameInBuffer * samplesPerFrame; - const int bufferEndSample = bufferStartSample + samplesInBuffer; - - if (startSampleInFile >= bufferStartSample - && startSampleInFile < bufferEndSample) - { - const int toDo = (int) jmin ((int64) numSamples, bufferEndSample - startSampleInFile); - - int* const l = destSamples[0] + startOffsetInDestBuffer; - int* const r = numDestChannels > 1 ? (destSamples[1] + startOffsetInDestBuffer) : nullptr; - const short* src = (const short*) buffer.getData(); - src += 2 * (startSampleInFile - bufferStartSample); - - for (int i = 0; i < toDo; ++i) - { - l[i] = src [i << 1] << 16; - - if (r != nullptr) - r[i] = src [(i << 1) + 1] << 16; - } - - startOffsetInDestBuffer += toDo; - startSampleInFile += toDo; - numSamples -= toDo; - } - else - { - const int framesInBuffer = (int) (buffer.getSize() / bytesPerFrame); - const int frameNeeded = (int) (startSampleInFile / samplesPerFrame); - - if (firstFrameInBuffer + framesInBuffer != frameNeeded) - { - device->overlapBuffer.dataLength = 0; - device->overlapBuffer.startFrame = 0; - device->overlapBuffer.numFrames = 0; - device->jitter = false; - } - - firstFrameInBuffer = frameNeeded; - lastIndex = 0; - - CDReadBuffer readBuffer (framesInBuffer + 4); - readBuffer.wantsIndex = indexingEnabled; - - int i; - for (i = 5; --i >= 0;) - { - readBuffer.startFrame = frameNeeded; - readBuffer.numFrames = framesInBuffer; - - if (device->deviceHandle.readAudio (readBuffer, device->jitter ? &device->overlapBuffer : 0)) - break; - else - device->overlapBuffer.dataLength = 0; - } - - if (i >= 0) - { - buffer.copyFrom (readBuffer.buffer + readBuffer.dataStartOffset, 0, readBuffer.dataLength); - samplesInBuffer = readBuffer.dataLength >> 2; - lastIndex = readBuffer.index; - } - else - { - int* l = destSamples[0] + startOffsetInDestBuffer; - int* r = numDestChannels > 1 ? (destSamples[1] + startOffsetInDestBuffer) : nullptr; - - while (--numSamples >= 0) - { - *l++ = 0; - - if (r != nullptr) - *r++ = 0; - } - - // sometimes the read fails for just the very last couple of blocks, so - // we'll ignore and errors in the last half-second of the disk.. - ok = startSampleInFile > (trackStartSamples [getNumTracks()] - 20000); - break; - } - } - } - - return ok; -} - -bool AudioCDReader::isCDStillPresent() const -{ - using namespace CDReaderHelpers; - TOC toc = { 0 }; - return static_cast (handle)->deviceHandle.readTOC (&toc); -} - -void AudioCDReader::refreshTrackLengths() -{ - using namespace CDReaderHelpers; - trackStartSamples.clear(); - zeromem (audioTracks, sizeof (audioTracks)); - - TOC toc = { 0 }; - - if (static_cast (handle)->deviceHandle.readTOC (&toc)) - { - int numTracks = 1 + toc.lastTrack - toc.firstTrack; - - for (int i = 0; i <= numTracks; ++i) - { - trackStartSamples.add (samplesPerFrame * getAddressOfTrack (toc.tracks [i])); - audioTracks [i] = ((toc.tracks[i].ADR & 4) == 0); - } - } - - lengthInSamples = getPositionOfTrackStart (getNumTracks()); -} - -bool AudioCDReader::isTrackAudio (int trackNum) const -{ - return trackNum >= 0 && trackNum < getNumTracks() && audioTracks [trackNum]; -} - -void AudioCDReader::enableIndexScanning (bool b) -{ - indexingEnabled = b; -} - -int AudioCDReader::getLastIndex() const -{ - return lastIndex; -} - -int AudioCDReader::getIndexAt (int samplePos) -{ - using namespace CDReaderHelpers; - CDDeviceWrapper* const device = static_cast (handle); - - const int frameNeeded = samplePos / samplesPerFrame; - - device->overlapBuffer.dataLength = 0; - device->overlapBuffer.startFrame = 0; - device->overlapBuffer.numFrames = 0; - device->jitter = false; - - firstFrameInBuffer = 0; - lastIndex = 0; - - CDReadBuffer readBuffer (4 + framesPerIndexRead); - readBuffer.wantsIndex = true; - - int i; - for (i = 5; --i >= 0;) - { - readBuffer.startFrame = frameNeeded; - readBuffer.numFrames = framesPerIndexRead; - - if (device->deviceHandle.readAudio (readBuffer)) - break; - } - - if (i >= 0) - return readBuffer.index; - - return -1; -} - -Array AudioCDReader::findIndexesInTrack (const int trackNumber) -{ - using namespace CDReaderHelpers; - Array indexes; - - const int trackStart = getPositionOfTrackStart (trackNumber); - const int trackEnd = getPositionOfTrackStart (trackNumber + 1); - - bool needToScan = true; - - if (trackEnd - trackStart > 20 * 44100) - { - // check the end of the track for indexes before scanning the whole thing - needToScan = false; - int pos = jmax (trackStart, trackEnd - 44100 * 5); - bool seenAnIndex = false; - - while (pos <= trackEnd - samplesPerFrame) - { - const int index = getIndexAt (pos); - - if (index == 0) - { - // lead-out, so skip back a bit if we've not found any indexes yet.. - if (seenAnIndex) - break; - - pos -= 44100 * 5; - - if (pos < trackStart) - break; - } - else - { - if (index > 0) - seenAnIndex = true; - - if (index > 1) - { - needToScan = true; - break; - } - - pos += samplesPerFrame * framesPerIndexRead; - } - } - } - - if (needToScan) - { - CDDeviceWrapper* const device = static_cast (handle); - - int pos = trackStart; - int last = -1; - - while (pos < trackEnd - samplesPerFrame * 10) - { - const int frameNeeded = pos / samplesPerFrame; - - device->overlapBuffer.dataLength = 0; - device->overlapBuffer.startFrame = 0; - device->overlapBuffer.numFrames = 0; - device->jitter = false; - - firstFrameInBuffer = 0; - - CDReadBuffer readBuffer (4); - readBuffer.wantsIndex = true; - - int i; - for (i = 5; --i >= 0;) - { - readBuffer.startFrame = frameNeeded; - readBuffer.numFrames = framesPerIndexRead; - - if (device->deviceHandle.readAudio (readBuffer)) - break; - } - - if (i < 0) - break; - - if (readBuffer.index > last && readBuffer.index > 1) - { - last = readBuffer.index; - indexes.add (pos); - } - - pos += samplesPerFrame * framesPerIndexRead; - } - - indexes.removeFirstMatchingValue (trackStart); - } - - return indexes; -} - -void AudioCDReader::ejectDisk() -{ - using namespace CDReaderHelpers; - static_cast (handle)->deviceHandle.openDrawer (true); -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/native/juce_win32_DirectSound.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/native/juce_win32_DirectSound.cpp deleted file mode 100644 index 88a5960fec..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/native/juce_win32_DirectSound.cpp +++ /dev/null @@ -1,1277 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -} // (juce namespace) - -extern "C" -{ - // Declare just the minimum number of interfaces for the DSound objects that we need.. - typedef struct typeDSBUFFERDESC - { - DWORD dwSize; - DWORD dwFlags; - DWORD dwBufferBytes; - DWORD dwReserved; - LPWAVEFORMATEX lpwfxFormat; - GUID guid3DAlgorithm; - } DSBUFFERDESC; - - struct IDirectSoundBuffer; - - #undef INTERFACE - #define INTERFACE IDirectSound - DECLARE_INTERFACE_(IDirectSound, IUnknown) - { - STDMETHOD(QueryInterface) (THIS_ REFIID, LPVOID*) PURE; - STDMETHOD_(ULONG,AddRef) (THIS) PURE; - STDMETHOD_(ULONG,Release) (THIS) PURE; - STDMETHOD(CreateSoundBuffer) (THIS_ DSBUFFERDESC*, IDirectSoundBuffer**, LPUNKNOWN) PURE; - STDMETHOD(GetCaps) (THIS_ void*) PURE; - STDMETHOD(DuplicateSoundBuffer) (THIS_ IDirectSoundBuffer*, IDirectSoundBuffer**) PURE; - STDMETHOD(SetCooperativeLevel) (THIS_ HWND, DWORD) PURE; - STDMETHOD(Compact) (THIS) PURE; - STDMETHOD(GetSpeakerConfig) (THIS_ LPDWORD) PURE; - STDMETHOD(SetSpeakerConfig) (THIS_ DWORD) PURE; - STDMETHOD(Initialize) (THIS_ const GUID*) PURE; - }; - - #undef INTERFACE - #define INTERFACE IDirectSoundBuffer - DECLARE_INTERFACE_(IDirectSoundBuffer, IUnknown) - { - STDMETHOD(QueryInterface) (THIS_ REFIID, LPVOID*) PURE; - STDMETHOD_(ULONG,AddRef) (THIS) PURE; - STDMETHOD_(ULONG,Release) (THIS) PURE; - STDMETHOD(GetCaps) (THIS_ void*) PURE; - STDMETHOD(GetCurrentPosition) (THIS_ LPDWORD, LPDWORD) PURE; - STDMETHOD(GetFormat) (THIS_ LPWAVEFORMATEX, DWORD, LPDWORD) PURE; - STDMETHOD(GetVolume) (THIS_ LPLONG) PURE; - STDMETHOD(GetPan) (THIS_ LPLONG) PURE; - STDMETHOD(GetFrequency) (THIS_ LPDWORD) PURE; - STDMETHOD(GetStatus) (THIS_ LPDWORD) PURE; - STDMETHOD(Initialize) (THIS_ IDirectSound*, DSBUFFERDESC*) PURE; - STDMETHOD(Lock) (THIS_ DWORD, DWORD, LPVOID*, LPDWORD, LPVOID*, LPDWORD, DWORD) PURE; - STDMETHOD(Play) (THIS_ DWORD, DWORD, DWORD) PURE; - STDMETHOD(SetCurrentPosition) (THIS_ DWORD) PURE; - STDMETHOD(SetFormat) (THIS_ const WAVEFORMATEX*) PURE; - STDMETHOD(SetVolume) (THIS_ LONG) PURE; - STDMETHOD(SetPan) (THIS_ LONG) PURE; - STDMETHOD(SetFrequency) (THIS_ DWORD) PURE; - STDMETHOD(Stop) (THIS) PURE; - STDMETHOD(Unlock) (THIS_ LPVOID, DWORD, LPVOID, DWORD) PURE; - STDMETHOD(Restore) (THIS) PURE; - }; - - //============================================================================== - typedef struct typeDSCBUFFERDESC - { - DWORD dwSize; - DWORD dwFlags; - DWORD dwBufferBytes; - DWORD dwReserved; - LPWAVEFORMATEX lpwfxFormat; - } DSCBUFFERDESC; - - struct IDirectSoundCaptureBuffer; - - #undef INTERFACE - #define INTERFACE IDirectSoundCapture - DECLARE_INTERFACE_(IDirectSoundCapture, IUnknown) - { - STDMETHOD(QueryInterface) (THIS_ REFIID, LPVOID*) PURE; - STDMETHOD_(ULONG,AddRef) (THIS) PURE; - STDMETHOD_(ULONG,Release) (THIS) PURE; - STDMETHOD(CreateCaptureBuffer) (THIS_ DSCBUFFERDESC*, IDirectSoundCaptureBuffer**, LPUNKNOWN) PURE; - STDMETHOD(GetCaps) (THIS_ void*) PURE; - STDMETHOD(Initialize) (THIS_ const GUID*) PURE; - }; - - #undef INTERFACE - #define INTERFACE IDirectSoundCaptureBuffer - DECLARE_INTERFACE_(IDirectSoundCaptureBuffer, IUnknown) - { - STDMETHOD(QueryInterface) (THIS_ REFIID, LPVOID*) PURE; - STDMETHOD_(ULONG,AddRef) (THIS) PURE; - STDMETHOD_(ULONG,Release) (THIS) PURE; - STDMETHOD(GetCaps) (THIS_ void*) PURE; - STDMETHOD(GetCurrentPosition) (THIS_ LPDWORD, LPDWORD) PURE; - STDMETHOD(GetFormat) (THIS_ LPWAVEFORMATEX, DWORD, LPDWORD) PURE; - STDMETHOD(GetStatus) (THIS_ LPDWORD) PURE; - STDMETHOD(Initialize) (THIS_ IDirectSoundCapture*, DSCBUFFERDESC*) PURE; - STDMETHOD(Lock) (THIS_ DWORD, DWORD, LPVOID*, LPDWORD, LPVOID*, LPDWORD, DWORD) PURE; - STDMETHOD(Start) (THIS_ DWORD) PURE; - STDMETHOD(Stop) (THIS) PURE; - STDMETHOD(Unlock) (THIS_ LPVOID, DWORD, LPVOID, DWORD) PURE; - }; - - #undef INTERFACE -} - -namespace juce -{ - -//============================================================================== -namespace DSoundLogging -{ - String getErrorMessage (HRESULT hr) - { - const char* result = nullptr; - - switch (hr) - { - case MAKE_HRESULT(1, 0x878, 10): result = "Device already allocated"; break; - case MAKE_HRESULT(1, 0x878, 30): result = "Control unavailable"; break; - case E_INVALIDARG: result = "Invalid parameter"; break; - case MAKE_HRESULT(1, 0x878, 50): result = "Invalid call"; break; - case E_FAIL: result = "Generic error"; break; - case MAKE_HRESULT(1, 0x878, 70): result = "Priority level error"; break; - case E_OUTOFMEMORY: result = "Out of memory"; break; - case MAKE_HRESULT(1, 0x878, 100): result = "Bad format"; break; - case E_NOTIMPL: result = "Unsupported function"; break; - case MAKE_HRESULT(1, 0x878, 120): result = "No driver"; break; - case MAKE_HRESULT(1, 0x878, 130): result = "Already initialised"; break; - case CLASS_E_NOAGGREGATION: result = "No aggregation"; break; - case MAKE_HRESULT(1, 0x878, 150): result = "Buffer lost"; break; - case MAKE_HRESULT(1, 0x878, 160): result = "Another app has priority"; break; - case MAKE_HRESULT(1, 0x878, 170): result = "Uninitialised"; break; - case E_NOINTERFACE: result = "No interface"; break; - case S_OK: result = "No error"; break; - default: return "Unknown error: " + String ((int) hr); - } - - return result; - } - - //============================================================================== - #if JUCE_DIRECTSOUND_LOGGING - static void logMessage (String message) - { - message = "DSOUND: " + message; - DBG (message); - Logger::writeToLog (message); - } - - static void logError (HRESULT hr, int lineNum) - { - if (FAILED (hr)) - { - String error ("Error at line "); - error << lineNum << ": " << getErrorMessage (hr); - logMessage (error); - } - } - - #define CATCH JUCE_CATCH_EXCEPTION - #define JUCE_DS_LOG(a) DSoundLogging::logMessage(a); - #define JUCE_DS_LOG_ERROR(a) DSoundLogging::logError(a, __LINE__); - #else - #define CATCH JUCE_CATCH_ALL - #define JUCE_DS_LOG(a) - #define JUCE_DS_LOG_ERROR(a) - #endif -} - -//============================================================================== -namespace -{ - #define DSOUND_FUNCTION(functionName, params) \ - typedef HRESULT (WINAPI *type##functionName) params; \ - static type##functionName ds##functionName = nullptr; - - #define DSOUND_FUNCTION_LOAD(functionName) \ - ds##functionName = (type##functionName) GetProcAddress (h, #functionName); \ - jassert (ds##functionName != nullptr); - - typedef BOOL (CALLBACK *LPDSENUMCALLBACKW) (LPGUID, LPCWSTR, LPCWSTR, LPVOID); - typedef BOOL (CALLBACK *LPDSENUMCALLBACKA) (LPGUID, LPCSTR, LPCSTR, LPVOID); - - DSOUND_FUNCTION (DirectSoundCreate, (const GUID*, IDirectSound**, LPUNKNOWN)) - DSOUND_FUNCTION (DirectSoundCaptureCreate, (const GUID*, IDirectSoundCapture**, LPUNKNOWN)) - DSOUND_FUNCTION (DirectSoundEnumerateW, (LPDSENUMCALLBACKW, LPVOID)) - DSOUND_FUNCTION (DirectSoundCaptureEnumerateW, (LPDSENUMCALLBACKW, LPVOID)) - - void initialiseDSoundFunctions() - { - if (dsDirectSoundCreate == nullptr) - { - HMODULE h = LoadLibraryA ("dsound.dll"); - - DSOUND_FUNCTION_LOAD (DirectSoundCreate) - DSOUND_FUNCTION_LOAD (DirectSoundCaptureCreate) - DSOUND_FUNCTION_LOAD (DirectSoundEnumerateW) - DSOUND_FUNCTION_LOAD (DirectSoundCaptureEnumerateW) - } - } - - // the overall size of buffer used is this value x the block size - enum { blocksPerOverallBuffer = 16 }; -} - -//============================================================================== -class DSoundInternalOutChannel -{ -public: - DSoundInternalOutChannel (const String& name_, const GUID& guid_, int rate, - int bufferSize, float* left, float* right) - : bitDepth (16), name (name_), guid (guid_), sampleRate (rate), - bufferSizeSamples (bufferSize), leftBuffer (left), rightBuffer (right), - pDirectSound (nullptr), pOutputBuffer (nullptr) - { - } - - ~DSoundInternalOutChannel() - { - close(); - } - - void close() - { - if (pOutputBuffer != nullptr) - { - JUCE_DS_LOG ("closing output: " + name); - HRESULT hr = pOutputBuffer->Stop(); - JUCE_DS_LOG_ERROR (hr); (void) hr; - - pOutputBuffer->Release(); - pOutputBuffer = nullptr; - } - - if (pDirectSound != nullptr) - { - pDirectSound->Release(); - pDirectSound = nullptr; - } - } - - String open() - { - JUCE_DS_LOG ("opening output: " + name + " rate=" + String (sampleRate) - + " bits=" + String (bitDepth) + " buf=" + String (bufferSizeSamples)); - - pDirectSound = nullptr; - pOutputBuffer = nullptr; - writeOffset = 0; - - String error; - HRESULT hr = E_NOINTERFACE; - - if (dsDirectSoundCreate != nullptr) - hr = dsDirectSoundCreate (&guid, &pDirectSound, nullptr); - - if (SUCCEEDED (hr)) - { - bytesPerBuffer = (bufferSizeSamples * (bitDepth >> 2)) & ~15; - totalBytesPerBuffer = (blocksPerOverallBuffer * bytesPerBuffer) & ~15; - const int numChannels = 2; - - hr = pDirectSound->SetCooperativeLevel (GetDesktopWindow(), 2 /* DSSCL_PRIORITY */); - JUCE_DS_LOG_ERROR (hr); - - if (SUCCEEDED (hr)) - { - IDirectSoundBuffer* pPrimaryBuffer; - - DSBUFFERDESC primaryDesc = { 0 }; - primaryDesc.dwSize = sizeof (DSBUFFERDESC); - primaryDesc.dwFlags = 1 /* DSBCAPS_PRIMARYBUFFER */; - primaryDesc.dwBufferBytes = 0; - primaryDesc.lpwfxFormat = 0; - - JUCE_DS_LOG ("co-op level set"); - hr = pDirectSound->CreateSoundBuffer (&primaryDesc, &pPrimaryBuffer, 0); - JUCE_DS_LOG_ERROR (hr); - - if (SUCCEEDED (hr)) - { - WAVEFORMATEX wfFormat; - wfFormat.wFormatTag = WAVE_FORMAT_PCM; - wfFormat.nChannels = (unsigned short) numChannels; - wfFormat.nSamplesPerSec = (DWORD) sampleRate; - wfFormat.wBitsPerSample = (unsigned short) bitDepth; - wfFormat.nBlockAlign = (unsigned short) (wfFormat.nChannels * wfFormat.wBitsPerSample / 8); - wfFormat.nAvgBytesPerSec = wfFormat.nSamplesPerSec * wfFormat.nBlockAlign; - wfFormat.cbSize = 0; - - hr = pPrimaryBuffer->SetFormat (&wfFormat); - JUCE_DS_LOG_ERROR (hr); - - if (SUCCEEDED (hr)) - { - DSBUFFERDESC secondaryDesc = { 0 }; - secondaryDesc.dwSize = sizeof (DSBUFFERDESC); - secondaryDesc.dwFlags = 0x8000 /* DSBCAPS_GLOBALFOCUS */ - | 0x10000 /* DSBCAPS_GETCURRENTPOSITION2 */; - secondaryDesc.dwBufferBytes = (DWORD) totalBytesPerBuffer; - secondaryDesc.lpwfxFormat = &wfFormat; - - hr = pDirectSound->CreateSoundBuffer (&secondaryDesc, &pOutputBuffer, 0); - JUCE_DS_LOG_ERROR (hr); - - if (SUCCEEDED (hr)) - { - JUCE_DS_LOG ("buffer created"); - - DWORD dwDataLen; - unsigned char* pDSBuffData; - - hr = pOutputBuffer->Lock (0, (DWORD) totalBytesPerBuffer, - (LPVOID*) &pDSBuffData, &dwDataLen, 0, 0, 0); - JUCE_DS_LOG_ERROR (hr); - - if (SUCCEEDED (hr)) - { - zeromem (pDSBuffData, dwDataLen); - - hr = pOutputBuffer->Unlock (pDSBuffData, dwDataLen, 0, 0); - - if (SUCCEEDED (hr)) - { - hr = pOutputBuffer->SetCurrentPosition (0); - - if (SUCCEEDED (hr)) - { - hr = pOutputBuffer->Play (0, 0, 1 /* DSBPLAY_LOOPING */); - - if (SUCCEEDED (hr)) - return String::empty; - } - } - } - } - } - } - } - } - - error = DSoundLogging::getErrorMessage (hr); - close(); - return error; - } - - void synchronisePosition() - { - if (pOutputBuffer != nullptr) - { - DWORD playCursor; - pOutputBuffer->GetCurrentPosition (&playCursor, &writeOffset); - } - } - - bool service() - { - if (pOutputBuffer == 0) - return true; - - DWORD playCursor, writeCursor; - - for (;;) - { - HRESULT hr = pOutputBuffer->GetCurrentPosition (&playCursor, &writeCursor); - - if (hr == MAKE_HRESULT (1, 0x878, 150)) // DSERR_BUFFERLOST - { - pOutputBuffer->Restore(); - continue; - } - - if (SUCCEEDED (hr)) - break; - - JUCE_DS_LOG_ERROR (hr); - jassertfalse; - return true; - } - - int playWriteGap = (int) (writeCursor - playCursor); - if (playWriteGap < 0) - playWriteGap += totalBytesPerBuffer; - - int bytesEmpty = (int) (playCursor - writeOffset); - if (bytesEmpty < 0) - bytesEmpty += totalBytesPerBuffer; - - if (bytesEmpty > (totalBytesPerBuffer - playWriteGap)) - { - writeOffset = writeCursor; - bytesEmpty = totalBytesPerBuffer - playWriteGap; - } - - if (bytesEmpty >= bytesPerBuffer) - { - int* buf1 = nullptr; - int* buf2 = nullptr; - DWORD dwSize1 = 0; - DWORD dwSize2 = 0; - - HRESULT hr = pOutputBuffer->Lock (writeOffset, (DWORD) bytesPerBuffer, - (void**) &buf1, &dwSize1, - (void**) &buf2, &dwSize2, 0); - - if (hr == MAKE_HRESULT (1, 0x878, 150)) // DSERR_BUFFERLOST - { - pOutputBuffer->Restore(); - - hr = pOutputBuffer->Lock (writeOffset, (DWORD) bytesPerBuffer, - (void**) &buf1, &dwSize1, - (void**) &buf2, &dwSize2, 0); - } - - if (SUCCEEDED (hr)) - { - if (bitDepth == 16) - { - const float* left = leftBuffer; - const float* right = rightBuffer; - int samples1 = (int) (dwSize1 >> 2); - int samples2 = (int) (dwSize2 >> 2); - - if (left == nullptr) - { - for (int* dest = buf1; --samples1 >= 0;) *dest++ = convertInputValues (0, *right++); - for (int* dest = buf2; --samples2 >= 0;) *dest++ = convertInputValues (0, *right++); - } - else if (right == nullptr) - { - for (int* dest = buf1; --samples1 >= 0;) *dest++ = convertInputValues (*left++, 0); - for (int* dest = buf2; --samples2 >= 0;) *dest++ = convertInputValues (*left++, 0); - } - else - { - for (int* dest = buf1; --samples1 >= 0;) *dest++ = convertInputValues (*left++, *right++); - for (int* dest = buf2; --samples2 >= 0;) *dest++ = convertInputValues (*left++, *right++); - } - } - else - { - jassertfalse; - } - - writeOffset = (writeOffset + dwSize1 + dwSize2) % totalBytesPerBuffer; - - pOutputBuffer->Unlock (buf1, dwSize1, buf2, dwSize2); - } - else - { - jassertfalse; - JUCE_DS_LOG_ERROR (hr); - } - - bytesEmpty -= bytesPerBuffer; - return true; - } - else - { - return false; - } - } - - int bitDepth; - bool doneFlag; - -private: - String name; - GUID guid; - int sampleRate, bufferSizeSamples; - float* leftBuffer; - float* rightBuffer; - - IDirectSound* pDirectSound; - IDirectSoundBuffer* pOutputBuffer; - DWORD writeOffset; - int totalBytesPerBuffer, bytesPerBuffer; - unsigned int lastPlayCursor; - - static inline int convertInputValues (const float l, const float r) noexcept - { - return jlimit (-32768, 32767, roundToInt (32767.0f * r)) << 16 - | (0xffff & jlimit (-32768, 32767, roundToInt (32767.0f * l))); - } - - JUCE_DECLARE_NON_COPYABLE (DSoundInternalOutChannel) -}; - -//============================================================================== -struct DSoundInternalInChannel -{ -public: - DSoundInternalInChannel (const String& name_, const GUID& guid_, int rate, - int bufferSize, float* left, float* right) - : bitDepth (16), name (name_), guid (guid_), sampleRate (rate), - bufferSizeSamples (bufferSize), leftBuffer (left), rightBuffer (right), - pDirectSound (nullptr), pDirectSoundCapture (nullptr), pInputBuffer (nullptr) - { - } - - ~DSoundInternalInChannel() - { - close(); - } - - void close() - { - if (pInputBuffer != nullptr) - { - JUCE_DS_LOG ("closing input: " + name); - HRESULT hr = pInputBuffer->Stop(); - JUCE_DS_LOG_ERROR (hr); (void) hr; - - pInputBuffer->Release(); - pInputBuffer = nullptr; - } - - if (pDirectSoundCapture != nullptr) - { - pDirectSoundCapture->Release(); - pDirectSoundCapture = nullptr; - } - - if (pDirectSound != nullptr) - { - pDirectSound->Release(); - pDirectSound = nullptr; - } - } - - String open() - { - JUCE_DS_LOG ("opening input: " + name - + " rate=" + String (sampleRate) + " bits=" + String (bitDepth) + " buf=" + String (bufferSizeSamples)); - - pDirectSound = nullptr; - pDirectSoundCapture = nullptr; - pInputBuffer = nullptr; - readOffset = 0; - totalBytesPerBuffer = 0; - - HRESULT hr = dsDirectSoundCaptureCreate != nullptr - ? dsDirectSoundCaptureCreate (&guid, &pDirectSoundCapture, nullptr) - : E_NOINTERFACE; - - if (SUCCEEDED (hr)) - { - const int numChannels = 2; - bytesPerBuffer = (bufferSizeSamples * (bitDepth >> 2)) & ~15; - totalBytesPerBuffer = (blocksPerOverallBuffer * bytesPerBuffer) & ~15; - - WAVEFORMATEX wfFormat; - wfFormat.wFormatTag = WAVE_FORMAT_PCM; - wfFormat.nChannels = (unsigned short)numChannels; - wfFormat.nSamplesPerSec = (DWORD) sampleRate; - wfFormat.wBitsPerSample = (unsigned short) bitDepth; - wfFormat.nBlockAlign = (unsigned short) (wfFormat.nChannels * (wfFormat.wBitsPerSample / 8)); - wfFormat.nAvgBytesPerSec = wfFormat.nSamplesPerSec * wfFormat.nBlockAlign; - wfFormat.cbSize = 0; - - DSCBUFFERDESC captureDesc = { 0 }; - captureDesc.dwSize = sizeof (DSCBUFFERDESC); - captureDesc.dwFlags = 0; - captureDesc.dwBufferBytes = (DWORD) totalBytesPerBuffer; - captureDesc.lpwfxFormat = &wfFormat; - - JUCE_DS_LOG ("object created"); - hr = pDirectSoundCapture->CreateCaptureBuffer (&captureDesc, &pInputBuffer, 0); - - if (SUCCEEDED (hr)) - { - hr = pInputBuffer->Start (1 /* DSCBSTART_LOOPING */); - - if (SUCCEEDED (hr)) - return String::empty; - } - } - - JUCE_DS_LOG_ERROR (hr); - const String error (DSoundLogging::getErrorMessage (hr)); - close(); - - return error; - } - - void synchronisePosition() - { - if (pInputBuffer != nullptr) - { - DWORD capturePos; - pInputBuffer->GetCurrentPosition (&capturePos, (DWORD*) &readOffset); - } - } - - bool service() - { - if (pInputBuffer == 0) - return true; - - DWORD capturePos, readPos; - HRESULT hr = pInputBuffer->GetCurrentPosition (&capturePos, &readPos); - JUCE_DS_LOG_ERROR (hr); - - if (FAILED (hr)) - return true; - - int bytesFilled = (int) (readPos - readOffset); - if (bytesFilled < 0) - bytesFilled += totalBytesPerBuffer; - - if (bytesFilled >= bytesPerBuffer) - { - short* buf1 = nullptr; - short* buf2 = nullptr; - DWORD dwsize1 = 0; - DWORD dwsize2 = 0; - - HRESULT hr = pInputBuffer->Lock ((DWORD) readOffset, (DWORD) bytesPerBuffer, - (void**) &buf1, &dwsize1, - (void**) &buf2, &dwsize2, 0); - - if (SUCCEEDED (hr)) - { - if (bitDepth == 16) - { - const float g = 1.0f / 32768.0f; - - float* destL = leftBuffer; - float* destR = rightBuffer; - int samples1 = (int) (dwsize1 >> 2); - int samples2 = (int) (dwsize2 >> 2); - - if (destL == nullptr) - { - for (const short* src = buf1; --samples1 >= 0;) { ++src; *destR++ = *src++ * g; } - for (const short* src = buf2; --samples2 >= 0;) { ++src; *destR++ = *src++ * g; } - } - else if (destR == nullptr) - { - for (const short* src = buf1; --samples1 >= 0;) { *destL++ = *src++ * g; ++src; } - for (const short* src = buf2; --samples2 >= 0;) { *destL++ = *src++ * g; ++src; } - } - else - { - for (const short* src = buf1; --samples1 >= 0;) { *destL++ = *src++ * g; *destR++ = *src++ * g; } - for (const short* src = buf2; --samples2 >= 0;) { *destL++ = *src++ * g; *destR++ = *src++ * g; } - } - } - else - { - jassertfalse; - } - - readOffset = (readOffset + dwsize1 + dwsize2) % totalBytesPerBuffer; - - pInputBuffer->Unlock (buf1, dwsize1, buf2, dwsize2); - } - else - { - JUCE_DS_LOG_ERROR (hr); - jassertfalse; - } - - bytesFilled -= bytesPerBuffer; - - return true; - } - else - { - return false; - } - } - - unsigned int readOffset; - int bytesPerBuffer, totalBytesPerBuffer; - int bitDepth; - bool doneFlag; - -private: - String name; - GUID guid; - int sampleRate, bufferSizeSamples; - float* leftBuffer; - float* rightBuffer; - - IDirectSound* pDirectSound; - IDirectSoundCapture* pDirectSoundCapture; - IDirectSoundCaptureBuffer* pInputBuffer; - - JUCE_DECLARE_NON_COPYABLE (DSoundInternalInChannel) -}; - -//============================================================================== -class DSoundAudioIODevice : public AudioIODevice, - public Thread -{ -public: - DSoundAudioIODevice (const String& deviceName, - const int outputDeviceIndex_, - const int inputDeviceIndex_) - : AudioIODevice (deviceName, "DirectSound"), - Thread ("Juce DSound"), - outputDeviceIndex (outputDeviceIndex_), - inputDeviceIndex (inputDeviceIndex_), - isOpen_ (false), - isStarted (false), - bufferSizeSamples (0), - sampleRate (0.0), - callback (nullptr) - { - if (outputDeviceIndex_ >= 0) - { - outChannels.add (TRANS("Left")); - outChannels.add (TRANS("Right")); - } - - if (inputDeviceIndex_ >= 0) - { - inChannels.add (TRANS("Left")); - inChannels.add (TRANS("Right")); - } - } - - ~DSoundAudioIODevice() - { - close(); - } - - String open (const BigInteger& inputChannels, - const BigInteger& outputChannels, - double sampleRate, int bufferSizeSamples) override - { - lastError = openDevice (inputChannels, outputChannels, sampleRate, bufferSizeSamples); - isOpen_ = lastError.isEmpty(); - - return lastError; - } - - void close() override - { - stop(); - - if (isOpen_) - { - closeDevice(); - isOpen_ = false; - } - } - - bool isOpen() override { return isOpen_ && isThreadRunning(); } - int getCurrentBufferSizeSamples() override { return bufferSizeSamples; } - double getCurrentSampleRate() override { return sampleRate; } - BigInteger getActiveOutputChannels() const override { return enabledOutputs; } - BigInteger getActiveInputChannels() const override { return enabledInputs; } - int getOutputLatencyInSamples() override { return (int) (getCurrentBufferSizeSamples() * 1.5); } - int getInputLatencyInSamples() override { return getOutputLatencyInSamples(); } - StringArray getOutputChannelNames() override { return outChannels; } - StringArray getInputChannelNames() override { return inChannels; } - - Array getAvailableSampleRates() override - { - static const double rates[] = { 44100.0, 48000.0, 88200.0, 96000.0 }; - return Array (rates, numElementsInArray (rates)); - } - - Array getAvailableBufferSizes() override - { - Array r; - int n = 64; - - for (int i = 0; i < 50; ++i) - { - r.add (n); - n += (n < 512) ? 32 - : ((n < 1024) ? 64 - : ((n < 2048) ? 128 : 256)); - } - - return r; - } - - int getDefaultBufferSize() override { return 2560; } - - int getCurrentBitDepth() override - { - int bits = 256; - - for (int i = inChans.size(); --i >= 0;) - bits = jmin (bits, inChans[i]->bitDepth); - - for (int i = outChans.size(); --i >= 0;) - bits = jmin (bits, outChans[i]->bitDepth); - - if (bits > 32) - bits = 16; - - return bits; - } - - void start (AudioIODeviceCallback* call) override - { - if (isOpen_ && call != nullptr && ! isStarted) - { - if (! isThreadRunning()) - { - // something gone wrong and the thread's stopped.. - isOpen_ = false; - return; - } - - call->audioDeviceAboutToStart (this); - - const ScopedLock sl (startStopLock); - callback = call; - isStarted = true; - } - } - - void stop() override - { - if (isStarted) - { - AudioIODeviceCallback* const callbackLocal = callback; - - { - const ScopedLock sl (startStopLock); - isStarted = false; - } - - if (callbackLocal != nullptr) - callbackLocal->audioDeviceStopped(); - } - } - - bool isPlaying() override { return isStarted && isOpen_ && isThreadRunning(); } - String getLastError() override { return lastError; } - - //============================================================================== - StringArray inChannels, outChannels; - int outputDeviceIndex, inputDeviceIndex; - -private: - bool isOpen_; - bool isStarted; - String lastError; - - OwnedArray inChans; - OwnedArray outChans; - WaitableEvent startEvent; - - int bufferSizeSamples; - double sampleRate; - BigInteger enabledInputs, enabledOutputs; - AudioSampleBuffer inputBuffers, outputBuffers; - - AudioIODeviceCallback* callback; - CriticalSection startStopLock; - - String openDevice (const BigInteger& inputChannels, - const BigInteger& outputChannels, - double sampleRate_, int bufferSizeSamples_); - - void closeDevice() - { - isStarted = false; - stopThread (5000); - - inChans.clear(); - outChans.clear(); - inputBuffers.setSize (1, 1); - outputBuffers.setSize (1, 1); - } - - void resync() - { - if (! threadShouldExit()) - { - sleep (5); - - for (int i = 0; i < outChans.size(); ++i) - outChans.getUnchecked(i)->synchronisePosition(); - - for (int i = 0; i < inChans.size(); ++i) - inChans.getUnchecked(i)->synchronisePosition(); - } - } - -public: - void run() override - { - while (! threadShouldExit()) - { - if (wait (100)) - break; - } - - const int latencyMs = (int) (bufferSizeSamples * 1000.0 / sampleRate); - const int maxTimeMS = jmax (5, 3 * latencyMs); - - while (! threadShouldExit()) - { - int numToDo = 0; - uint32 startTime = Time::getMillisecondCounter(); - - for (int i = inChans.size(); --i >= 0;) - { - inChans.getUnchecked(i)->doneFlag = false; - ++numToDo; - } - - for (int i = outChans.size(); --i >= 0;) - { - outChans.getUnchecked(i)->doneFlag = false; - ++numToDo; - } - - if (numToDo > 0) - { - const int maxCount = 3; - int count = maxCount; - - for (;;) - { - for (int i = inChans.size(); --i >= 0;) - { - DSoundInternalInChannel* const in = inChans.getUnchecked(i); - - if ((! in->doneFlag) && in->service()) - { - in->doneFlag = true; - --numToDo; - } - } - - for (int i = outChans.size(); --i >= 0;) - { - DSoundInternalOutChannel* const out = outChans.getUnchecked(i); - - if ((! out->doneFlag) && out->service()) - { - out->doneFlag = true; - --numToDo; - } - } - - if (numToDo <= 0) - break; - - if (Time::getMillisecondCounter() > startTime + maxTimeMS) - { - resync(); - break; - } - - if (--count <= 0) - { - Sleep (1); - count = maxCount; - } - - if (threadShouldExit()) - return; - } - } - else - { - sleep (1); - } - - const ScopedLock sl (startStopLock); - - if (isStarted) - { - callback->audioDeviceIOCallback (inputBuffers.getArrayOfReadPointers(), inputBuffers.getNumChannels(), - outputBuffers.getArrayOfWritePointers(), outputBuffers.getNumChannels(), - bufferSizeSamples); - } - else - { - outputBuffers.clear(); - sleep (1); - } - } - } - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (DSoundAudioIODevice) -}; - -//============================================================================== -struct DSoundDeviceList -{ - StringArray outputDeviceNames, inputDeviceNames; - Array outputGuids, inputGuids; - - void scan() - { - outputDeviceNames.clear(); - inputDeviceNames.clear(); - outputGuids.clear(); - inputGuids.clear(); - - if (dsDirectSoundEnumerateW != 0) - { - dsDirectSoundEnumerateW (outputEnumProcW, this); - dsDirectSoundCaptureEnumerateW (inputEnumProcW, this); - } - } - - bool operator!= (const DSoundDeviceList& other) const noexcept - { - return outputDeviceNames != other.outputDeviceNames - || inputDeviceNames != other.inputDeviceNames - || outputGuids != other.outputGuids - || inputGuids != other.inputGuids; - } - -private: - static BOOL enumProc (LPGUID lpGUID, String desc, StringArray& names, Array& guids) - { - desc = desc.trim(); - - if (desc.isNotEmpty()) - { - const String origDesc (desc); - - int n = 2; - while (names.contains (desc)) - desc = origDesc + " (" + String (n++) + ")"; - - names.add (desc); - guids.add (lpGUID != nullptr ? *lpGUID : GUID()); - } - - return TRUE; - } - - BOOL outputEnumProc (LPGUID guid, LPCWSTR desc) { return enumProc (guid, desc, outputDeviceNames, outputGuids); } - BOOL inputEnumProc (LPGUID guid, LPCWSTR desc) { return enumProc (guid, desc, inputDeviceNames, inputGuids); } - - static BOOL CALLBACK outputEnumProcW (LPGUID lpGUID, LPCWSTR description, LPCWSTR, LPVOID object) - { - return static_cast (object)->outputEnumProc (lpGUID, description); - } - - static BOOL CALLBACK inputEnumProcW (LPGUID lpGUID, LPCWSTR description, LPCWSTR, LPVOID object) - { - return static_cast (object)->inputEnumProc (lpGUID, description); - } -}; - -//============================================================================== -String DSoundAudioIODevice::openDevice (const BigInteger& inputChannels, - const BigInteger& outputChannels, - double sampleRate_, int bufferSizeSamples_) -{ - closeDevice(); - - sampleRate = sampleRate_; - - if (bufferSizeSamples_ <= 0) - bufferSizeSamples_ = 960; // use as a default size if none is set. - - bufferSizeSamples = bufferSizeSamples_ & ~7; - - DSoundDeviceList dlh; - dlh.scan(); - - enabledInputs = inputChannels; - enabledInputs.setRange (inChannels.size(), - enabledInputs.getHighestBit() + 1 - inChannels.size(), - false); - - inputBuffers.setSize (jmax (1, enabledInputs.countNumberOfSetBits()), bufferSizeSamples); - inputBuffers.clear(); - int numIns = 0; - - for (int i = 0; i <= enabledInputs.getHighestBit(); i += 2) - { - float* left = enabledInputs[i] ? inputBuffers.getWritePointer (numIns++) : nullptr; - float* right = enabledInputs[i + 1] ? inputBuffers.getWritePointer (numIns++) : nullptr; - - if (left != nullptr || right != nullptr) - inChans.add (new DSoundInternalInChannel (dlh.inputDeviceNames [inputDeviceIndex], - dlh.inputGuids [inputDeviceIndex], - (int) sampleRate, bufferSizeSamples, - left, right)); - } - - enabledOutputs = outputChannels; - enabledOutputs.setRange (outChannels.size(), - enabledOutputs.getHighestBit() + 1 - outChannels.size(), - false); - - outputBuffers.setSize (jmax (1, enabledOutputs.countNumberOfSetBits()), bufferSizeSamples); - outputBuffers.clear(); - int numOuts = 0; - - for (int i = 0; i <= enabledOutputs.getHighestBit(); i += 2) - { - float* left = enabledOutputs[i] ? outputBuffers.getWritePointer (numOuts++) : nullptr; - float* right = enabledOutputs[i + 1] ? outputBuffers.getWritePointer (numOuts++) : nullptr; - - if (left != nullptr || right != nullptr) - outChans.add (new DSoundInternalOutChannel (dlh.outputDeviceNames[outputDeviceIndex], - dlh.outputGuids [outputDeviceIndex], - (int) sampleRate, bufferSizeSamples, - left, right)); - } - - String error; - - // boost our priority while opening the devices to try to get better sync between them - const int oldThreadPri = GetThreadPriority (GetCurrentThread()); - const DWORD oldProcPri = GetPriorityClass (GetCurrentProcess()); - SetThreadPriority (GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL); - SetPriorityClass (GetCurrentProcess(), REALTIME_PRIORITY_CLASS); - - for (int i = 0; i < outChans.size(); ++i) - { - error = outChans[i]->open(); - - if (error.isNotEmpty()) - { - error = "Error opening " + dlh.outputDeviceNames[i] + ": \"" + error + "\""; - break; - } - } - - if (error.isEmpty()) - { - for (int i = 0; i < inChans.size(); ++i) - { - error = inChans[i]->open(); - - if (error.isNotEmpty()) - { - error = "Error opening " + dlh.inputDeviceNames[i] + ": \"" + error + "\""; - break; - } - } - } - - if (error.isEmpty()) - { - for (int i = 0; i < outChans.size(); ++i) - outChans.getUnchecked(i)->synchronisePosition(); - - for (int i = 0; i < inChans.size(); ++i) - inChans.getUnchecked(i)->synchronisePosition(); - - startThread (9); - sleep (10); - - notify(); - } - else - { - JUCE_DS_LOG ("Opening failed: " + error); - } - - SetThreadPriority (GetCurrentThread(), oldThreadPri); - SetPriorityClass (GetCurrentProcess(), oldProcPri); - - return error; -} - -//============================================================================== -class DSoundAudioIODeviceType : public AudioIODeviceType, - private DeviceChangeDetector -{ -public: - DSoundAudioIODeviceType() - : AudioIODeviceType ("DirectSound"), - DeviceChangeDetector (L"DirectSound"), - hasScanned (false) - { - initialiseDSoundFunctions(); - } - - void scanForDevices() - { - hasScanned = true; - deviceList.scan(); - } - - StringArray getDeviceNames (bool wantInputNames) const - { - jassert (hasScanned); // need to call scanForDevices() before doing this - - return wantInputNames ? deviceList.inputDeviceNames - : deviceList.outputDeviceNames; - } - - int getDefaultDeviceIndex (bool /*forInput*/) const - { - jassert (hasScanned); // need to call scanForDevices() before doing this - return 0; - } - - int getIndexOfDevice (AudioIODevice* device, bool asInput) const - { - jassert (hasScanned); // need to call scanForDevices() before doing this - - if (DSoundAudioIODevice* const d = dynamic_cast (device)) - return asInput ? d->inputDeviceIndex - : d->outputDeviceIndex; - - return -1; - } - - bool hasSeparateInputsAndOutputs() const { return true; } - - AudioIODevice* createDevice (const String& outputDeviceName, - const String& inputDeviceName) - { - jassert (hasScanned); // need to call scanForDevices() before doing this - - const int outputIndex = deviceList.outputDeviceNames.indexOf (outputDeviceName); - const int inputIndex = deviceList.inputDeviceNames.indexOf (inputDeviceName); - - if (outputIndex >= 0 || inputIndex >= 0) - return new DSoundAudioIODevice (outputDeviceName.isNotEmpty() ? outputDeviceName - : inputDeviceName, - outputIndex, inputIndex); - - return nullptr; - } - -private: - DSoundDeviceList deviceList; - bool hasScanned; - - void systemDeviceChanged() override - { - DSoundDeviceList newList; - newList.scan(); - - if (newList != deviceList) - { - deviceList = newList; - callDeviceChangeListeners(); - } - } - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (DSoundAudioIODeviceType) -}; - -//============================================================================== -AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_DirectSound() -{ - return new DSoundAudioIODeviceType(); -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/native/juce_win32_Midi.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/native/juce_win32_Midi.cpp deleted file mode 100644 index 2737b1e669..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/native/juce_win32_Midi.cpp +++ /dev/null @@ -1,489 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -class MidiInCollector -{ -public: - MidiInCollector (MidiInput* const input_, - MidiInputCallback& callback_) - : deviceHandle (0), - input (input_), - callback (callback_), - concatenator (4096), - isStarted (false), - startTime (0) - { - } - - ~MidiInCollector() - { - stop(); - - if (deviceHandle != 0) - { - for (int count = 5; --count >= 0;) - { - if (midiInClose (deviceHandle) == MMSYSERR_NOERROR) - break; - - Sleep (20); - } - } - } - - //============================================================================== - void handleMessage (const uint8* bytes, const uint32 timeStamp) - { - if (bytes[0] >= 0x80 && isStarted) - { - concatenator.pushMidiData (bytes, MidiMessage::getMessageLengthFromFirstByte (bytes[0]), - convertTimeStamp (timeStamp), input, callback); - writeFinishedBlocks(); - } - } - - void handleSysEx (MIDIHDR* const hdr, const uint32 timeStamp) - { - if (isStarted && hdr->dwBytesRecorded > 0) - { - concatenator.pushMidiData (hdr->lpData, (int) hdr->dwBytesRecorded, - convertTimeStamp (timeStamp), input, callback); - writeFinishedBlocks(); - } - } - - void start() - { - if (deviceHandle != 0 && ! isStarted) - { - activeMidiCollectors.addIfNotAlreadyThere (this); - - for (int i = 0; i < (int) numHeaders; ++i) - { - headers[i].prepare (deviceHandle); - headers[i].write (deviceHandle); - } - - startTime = Time::getMillisecondCounterHiRes(); - MMRESULT res = midiInStart (deviceHandle); - - if (res == MMSYSERR_NOERROR) - { - concatenator.reset(); - isStarted = true; - } - else - { - unprepareAllHeaders(); - } - } - } - - void stop() - { - if (isStarted) - { - isStarted = false; - midiInReset (deviceHandle); - midiInStop (deviceHandle); - activeMidiCollectors.removeFirstMatchingValue (this); - unprepareAllHeaders(); - concatenator.reset(); - } - } - - static void CALLBACK midiInCallback (HMIDIIN, UINT uMsg, DWORD_PTR dwInstance, - DWORD_PTR midiMessage, DWORD_PTR timeStamp) - { - MidiInCollector* const collector = reinterpret_cast (dwInstance); - - if (activeMidiCollectors.contains (collector)) - { - if (uMsg == MIM_DATA) - collector->handleMessage ((const uint8*) &midiMessage, (uint32) timeStamp); - else if (uMsg == MIM_LONGDATA) - collector->handleSysEx ((MIDIHDR*) midiMessage, (uint32) timeStamp); - } - } - - HMIDIIN deviceHandle; - -private: - static Array activeMidiCollectors; - - MidiInput* input; - MidiInputCallback& callback; - MidiDataConcatenator concatenator; - bool volatile isStarted; - double startTime; - - class MidiHeader - { - public: - MidiHeader() {} - - void prepare (HMIDIIN deviceHandle) - { - zerostruct (hdr); - hdr.lpData = data; - hdr.dwBufferLength = (DWORD) numElementsInArray (data); - - midiInPrepareHeader (deviceHandle, &hdr, sizeof (hdr)); - } - - void unprepare (HMIDIIN deviceHandle) - { - if ((hdr.dwFlags & WHDR_DONE) != 0) - { - int c = 10; - while (--c >= 0 && midiInUnprepareHeader (deviceHandle, &hdr, sizeof (hdr)) == MIDIERR_STILLPLAYING) - Thread::sleep (20); - - jassert (c >= 0); - } - } - - void write (HMIDIIN deviceHandle) - { - hdr.dwBytesRecorded = 0; - midiInAddBuffer (deviceHandle, &hdr, sizeof (hdr)); - } - - void writeIfFinished (HMIDIIN deviceHandle) - { - if ((hdr.dwFlags & WHDR_DONE) != 0) - write (deviceHandle); - } - - private: - MIDIHDR hdr; - char data [256]; - - JUCE_DECLARE_NON_COPYABLE (MidiHeader) - }; - - enum { numHeaders = 32 }; - MidiHeader headers [numHeaders]; - - void writeFinishedBlocks() - { - for (int i = 0; i < (int) numHeaders; ++i) - headers[i].writeIfFinished (deviceHandle); - } - - void unprepareAllHeaders() - { - for (int i = 0; i < (int) numHeaders; ++i) - headers[i].unprepare (deviceHandle); - } - - double convertTimeStamp (uint32 timeStamp) - { - double t = startTime + timeStamp; - - const double now = Time::getMillisecondCounterHiRes(); - if (t > now) - { - if (t > now + 2.0) - startTime -= 1.0; - - t = now; - } - - return t * 0.001; - } - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MidiInCollector) -}; - -Array MidiInCollector::activeMidiCollectors; - - -//============================================================================== -StringArray MidiInput::getDevices() -{ - StringArray s; - const UINT num = midiInGetNumDevs(); - - for (UINT i = 0; i < num; ++i) - { - MIDIINCAPS mc = { 0 }; - - if (midiInGetDevCaps (i, &mc, sizeof (mc)) == MMSYSERR_NOERROR) - s.add (String (mc.szPname, sizeof (mc.szPname))); - } - - return s; -} - -int MidiInput::getDefaultDeviceIndex() -{ - return 0; -} - -MidiInput* MidiInput::openDevice (const int index, MidiInputCallback* const callback) -{ - if (callback == nullptr) - return nullptr; - - UINT deviceId = MIDI_MAPPER; - int n = 0; - String name; - - const UINT num = midiInGetNumDevs(); - - for (UINT i = 0; i < num; ++i) - { - MIDIINCAPS mc = { 0 }; - - if (midiInGetDevCaps (i, &mc, sizeof (mc)) == MMSYSERR_NOERROR) - { - if (index == n) - { - deviceId = i; - name = String (mc.szPname, (size_t) numElementsInArray (mc.szPname)); - break; - } - - ++n; - } - } - - ScopedPointer in (new MidiInput (name)); - ScopedPointer collector (new MidiInCollector (in, *callback)); - - HMIDIIN h; - MMRESULT err = midiInOpen (&h, deviceId, - (DWORD_PTR) &MidiInCollector::midiInCallback, - (DWORD_PTR) (MidiInCollector*) collector, - CALLBACK_FUNCTION); - - if (err == MMSYSERR_NOERROR) - { - collector->deviceHandle = h; - in->internal = collector.release(); - return in.release(); - } - - return nullptr; -} - -MidiInput::MidiInput (const String& name_) - : name (name_), - internal (0) -{ -} - -MidiInput::~MidiInput() -{ - delete static_cast (internal); -} - -void MidiInput::start() { static_cast (internal)->start(); } -void MidiInput::stop() { static_cast (internal)->stop(); } - - -//============================================================================== -struct MidiOutHandle -{ - int refCount; - UINT deviceId; - HMIDIOUT handle; - - static Array activeHandles; - -private: - JUCE_LEAK_DETECTOR (MidiOutHandle) -}; - -Array MidiOutHandle::activeHandles; - -//============================================================================== -StringArray MidiOutput::getDevices() -{ - StringArray s; - const UINT num = midiOutGetNumDevs(); - - for (UINT i = 0; i < num; ++i) - { - MIDIOUTCAPS mc = { 0 }; - - if (midiOutGetDevCaps (i, &mc, sizeof (mc)) == MMSYSERR_NOERROR) - s.add (String (mc.szPname, sizeof (mc.szPname))); - } - - return s; -} - -int MidiOutput::getDefaultDeviceIndex() -{ - const UINT num = midiOutGetNumDevs(); - int n = 0; - - for (UINT i = 0; i < num; ++i) - { - MIDIOUTCAPS mc = { 0 }; - - if (midiOutGetDevCaps (i, &mc, sizeof (mc)) == MMSYSERR_NOERROR) - { - if ((mc.wTechnology & MOD_MAPPER) != 0) - return n; - - ++n; - } - } - - return 0; -} - -MidiOutput* MidiOutput::openDevice (int index) -{ - UINT deviceId = MIDI_MAPPER; - const UINT num = midiOutGetNumDevs(); - int n = 0; - - for (UINT i = 0; i < num; ++i) - { - MIDIOUTCAPS mc = { 0 }; - - if (midiOutGetDevCaps (i, &mc, sizeof (mc)) == MMSYSERR_NOERROR) - { - // use the microsoft sw synth as a default - best not to allow deviceId - // to be MIDI_MAPPER, or else device sharing breaks - if (String (mc.szPname, sizeof (mc.szPname)).containsIgnoreCase ("microsoft")) - deviceId = i; - - if (index == n) - { - deviceId = i; - break; - } - - ++n; - } - } - - for (int i = MidiOutHandle::activeHandles.size(); --i >= 0;) - { - MidiOutHandle* const han = MidiOutHandle::activeHandles.getUnchecked(i); - - if (han->deviceId == deviceId) - { - han->refCount++; - - MidiOutput* const out = new MidiOutput(); - out->internal = han; - return out; - } - } - - for (int i = 4; --i >= 0;) - { - HMIDIOUT h = 0; - MMRESULT res = midiOutOpen (&h, deviceId, 0, 0, CALLBACK_NULL); - - if (res == MMSYSERR_NOERROR) - { - MidiOutHandle* const han = new MidiOutHandle(); - han->deviceId = deviceId; - han->refCount = 1; - han->handle = h; - MidiOutHandle::activeHandles.add (han); - - MidiOutput* const out = new MidiOutput(); - out->internal = han; - return out; - } - else if (res == MMSYSERR_ALLOCATED) - { - Sleep (100); - } - else - { - break; - } - } - - return nullptr; -} - -MidiOutput::~MidiOutput() -{ - stopBackgroundThread(); - - MidiOutHandle* const h = static_cast (internal); - - if (MidiOutHandle::activeHandles.contains (h) && --(h->refCount) == 0) - { - midiOutClose (h->handle); - MidiOutHandle::activeHandles.removeFirstMatchingValue (h); - delete h; - } -} - -void MidiOutput::sendMessageNow (const MidiMessage& message) -{ - const MidiOutHandle* const handle = static_cast (internal); - - if (message.getRawDataSize() > 3 || message.isSysEx()) - { - MIDIHDR h = { 0 }; - - h.lpData = (char*) message.getRawData(); - h.dwBytesRecorded = h.dwBufferLength = (DWORD) message.getRawDataSize(); - - if (midiOutPrepareHeader (handle->handle, &h, sizeof (MIDIHDR)) == MMSYSERR_NOERROR) - { - MMRESULT res = midiOutLongMsg (handle->handle, &h, sizeof (MIDIHDR)); - - if (res == MMSYSERR_NOERROR) - { - while ((h.dwFlags & MHDR_DONE) == 0) - Sleep (1); - - int count = 500; // 1 sec timeout - - while (--count >= 0) - { - res = midiOutUnprepareHeader (handle->handle, &h, sizeof (MIDIHDR)); - - if (res == MIDIERR_STILLPLAYING) - Sleep (2); - else - break; - } - } - } - } - else - { - for (int i = 0; i < 50; ++i) - { - if (midiOutShortMsg (handle->handle, *(unsigned int*) message.getRawData()) != MIDIERR_NOTREADY) - break; - - Sleep (1); - } - } -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/native/juce_win32_WASAPI.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/native/juce_win32_WASAPI.cpp deleted file mode 100644 index 0ef7811d45..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/native/juce_win32_WASAPI.cpp +++ /dev/null @@ -1,1509 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_WASAPI_LOGGING - #define JUCE_WASAPI_LOGGING 0 -#endif - -//============================================================================== -namespace WasapiClasses -{ - -void logFailure (HRESULT hr) -{ - (void) hr; - jassert (hr != (HRESULT) 0x800401f0); // If you hit this, it means you're trying to call from - // a thread which hasn't been initialised with CoInitialize(). - - #if JUCE_WASAPI_LOGGING - if (FAILED (hr)) - { - const char* m = nullptr; - - switch (hr) - { - case E_POINTER: m = "E_POINTER"; break; - case E_INVALIDARG: m = "E_INVALIDARG"; break; - - #define JUCE_WASAPI_ERR(desc, n) \ - case MAKE_HRESULT(1, 0x889, n): m = #desc; break; - - JUCE_WASAPI_ERR (AUDCLNT_E_NOT_INITIALIZED, 0x001) - JUCE_WASAPI_ERR (AUDCLNT_E_ALREADY_INITIALIZED, 0x002) - JUCE_WASAPI_ERR (AUDCLNT_E_WRONG_ENDPOINT_TYPE, 0x003) - JUCE_WASAPI_ERR (AUDCLNT_E_DEVICE_INVALIDATED, 0x004) - JUCE_WASAPI_ERR (AUDCLNT_E_NOT_STOPPED, 0x005) - JUCE_WASAPI_ERR (AUDCLNT_E_BUFFER_TOO_LARGE, 0x006) - JUCE_WASAPI_ERR (AUDCLNT_E_OUT_OF_ORDER, 0x007) - JUCE_WASAPI_ERR (AUDCLNT_E_UNSUPPORTED_FORMAT, 0x008) - JUCE_WASAPI_ERR (AUDCLNT_E_INVALID_SIZE, 0x009) - JUCE_WASAPI_ERR (AUDCLNT_E_DEVICE_IN_USE, 0x00a) - JUCE_WASAPI_ERR (AUDCLNT_E_BUFFER_OPERATION_PENDING, 0x00b) - JUCE_WASAPI_ERR (AUDCLNT_E_THREAD_NOT_REGISTERED, 0x00c) - JUCE_WASAPI_ERR (AUDCLNT_E_EXCLUSIVE_MODE_NOT_ALLOWED, 0x00e) - JUCE_WASAPI_ERR (AUDCLNT_E_ENDPOINT_CREATE_FAILED, 0x00f) - JUCE_WASAPI_ERR (AUDCLNT_E_SERVICE_NOT_RUNNING, 0x010) - JUCE_WASAPI_ERR (AUDCLNT_E_EVENTHANDLE_NOT_EXPECTED, 0x011) - JUCE_WASAPI_ERR (AUDCLNT_E_EXCLUSIVE_MODE_ONLY, 0x012) - JUCE_WASAPI_ERR (AUDCLNT_E_BUFDURATION_PERIOD_NOT_EQUAL, 0x013) - JUCE_WASAPI_ERR (AUDCLNT_E_EVENTHANDLE_NOT_SET, 0x014) - JUCE_WASAPI_ERR (AUDCLNT_E_INCORRECT_BUFFER_SIZE, 0x015) - JUCE_WASAPI_ERR (AUDCLNT_E_BUFFER_SIZE_ERROR, 0x016) - JUCE_WASAPI_ERR (AUDCLNT_E_CPUUSAGE_EXCEEDED, 0x017) - JUCE_WASAPI_ERR (AUDCLNT_E_BUFFER_ERROR, 0x018) - JUCE_WASAPI_ERR (AUDCLNT_E_BUFFER_SIZE_NOT_ALIGNED, 0x019) - JUCE_WASAPI_ERR (AUDCLNT_E_INVALID_DEVICE_PERIOD, 0x020) - default: break; - } - - Logger::writeToLog ("WASAPI error: " + (m != nullptr ? String (m) - : String::toHexString ((int) hr))); - } - #endif -} - -#undef check - -bool check (HRESULT hr) -{ - logFailure (hr); - return SUCCEEDED (hr); -} - -//============================================================================== -} - -#if JUCE_MINGW - #define JUCE_COMCLASS(name, guid) \ - struct name; \ - template<> struct UUIDGetter { static CLSID get() { return uuidFromString (guid); } }; \ - struct name - - struct PROPERTYKEY - { - GUID fmtid; - DWORD pid; - }; - - WINOLEAPI PropVariantClear (PROPVARIANT*); -#else - #define JUCE_COMCLASS(name, guid) struct __declspec (uuid (guid)) name -#endif - -#ifndef KSDATAFORMAT_SUBTYPE_PCM - #define KSDATAFORMAT_SUBTYPE_PCM uuidFromString ("00000001-0000-0010-8000-00aa00389b71") - #define KSDATAFORMAT_SUBTYPE_IEEE_FLOAT uuidFromString ("00000003-0000-0010-8000-00aa00389b71") -#endif - -#define JUCE_IUNKNOWNCLASS(name, guid) JUCE_COMCLASS(name, guid) : public IUnknown -#define JUCE_COMCALL virtual HRESULT STDMETHODCALLTYPE - -enum EDataFlow -{ - eRender = 0, - eCapture = (eRender + 1), - eAll = (eCapture + 1) -}; - -enum { DEVICE_STATE_ACTIVE = 1 }; - -JUCE_IUNKNOWNCLASS (IPropertyStore, "886d8eeb-8cf2-4446-8d02-cdba1dbdcf99") -{ - JUCE_COMCALL GetCount (DWORD*) = 0; - JUCE_COMCALL GetAt (DWORD, PROPERTYKEY*) = 0; - JUCE_COMCALL GetValue (const PROPERTYKEY&, PROPVARIANT*) = 0; - JUCE_COMCALL SetValue (const PROPERTYKEY&, const PROPVARIANT&) = 0; - JUCE_COMCALL Commit() = 0; -}; - -JUCE_IUNKNOWNCLASS (IMMDevice, "D666063F-1587-4E43-81F1-B948E807363F") -{ - JUCE_COMCALL Activate (REFIID, DWORD, PROPVARIANT*, void**) = 0; - JUCE_COMCALL OpenPropertyStore (DWORD, IPropertyStore**) = 0; - JUCE_COMCALL GetId (LPWSTR*) = 0; - JUCE_COMCALL GetState (DWORD*) = 0; -}; - -JUCE_IUNKNOWNCLASS (IMMEndpoint, "1BE09788-6894-4089-8586-9A2A6C265AC5") -{ - JUCE_COMCALL GetDataFlow (EDataFlow*) = 0; -}; - -struct IMMDeviceCollection : public IUnknown -{ - JUCE_COMCALL GetCount (UINT*) = 0; - JUCE_COMCALL Item (UINT, IMMDevice**) = 0; -}; - -enum ERole -{ - eConsole = 0, - eMultimedia = (eConsole + 1), - eCommunications = (eMultimedia + 1) -}; - -JUCE_IUNKNOWNCLASS (IMMNotificationClient, "7991EEC9-7E89-4D85-8390-6C703CEC60C0") -{ - JUCE_COMCALL OnDeviceStateChanged (LPCWSTR, DWORD) = 0; - JUCE_COMCALL OnDeviceAdded (LPCWSTR) = 0; - JUCE_COMCALL OnDeviceRemoved (LPCWSTR) = 0; - JUCE_COMCALL OnDefaultDeviceChanged (EDataFlow, ERole, LPCWSTR) = 0; - JUCE_COMCALL OnPropertyValueChanged (LPCWSTR, const PROPERTYKEY) = 0; -}; - -JUCE_IUNKNOWNCLASS (IMMDeviceEnumerator, "A95664D2-9614-4F35-A746-DE8DB63617E6") -{ - JUCE_COMCALL EnumAudioEndpoints (EDataFlow, DWORD, IMMDeviceCollection**) = 0; - JUCE_COMCALL GetDefaultAudioEndpoint (EDataFlow, ERole, IMMDevice**) = 0; - JUCE_COMCALL GetDevice (LPCWSTR, IMMDevice**) = 0; - JUCE_COMCALL RegisterEndpointNotificationCallback (IMMNotificationClient*) = 0; - JUCE_COMCALL UnregisterEndpointNotificationCallback (IMMNotificationClient*) = 0; -}; - -JUCE_COMCLASS (MMDeviceEnumerator, "BCDE0395-E52F-467C-8E3D-C4579291692E"); - -typedef LONGLONG REFERENCE_TIME; - -enum AVRT_PRIORITY -{ - AVRT_PRIORITY_LOW = -1, - AVRT_PRIORITY_NORMAL, - AVRT_PRIORITY_HIGH, - AVRT_PRIORITY_CRITICAL -}; - -enum AUDCLNT_SHAREMODE -{ - AUDCLNT_SHAREMODE_SHARED, - AUDCLNT_SHAREMODE_EXCLUSIVE -}; - -JUCE_IUNKNOWNCLASS (IAudioClient, "1CB9AD4C-DBFA-4c32-B178-C2F568A703B2") -{ - JUCE_COMCALL Initialize (AUDCLNT_SHAREMODE, DWORD, REFERENCE_TIME, REFERENCE_TIME, const WAVEFORMATEX*, LPCGUID) = 0; - JUCE_COMCALL GetBufferSize (UINT32*) = 0; - JUCE_COMCALL GetStreamLatency (REFERENCE_TIME*) = 0; - JUCE_COMCALL GetCurrentPadding (UINT32*) = 0; - JUCE_COMCALL IsFormatSupported (AUDCLNT_SHAREMODE, const WAVEFORMATEX*, WAVEFORMATEX**) = 0; - JUCE_COMCALL GetMixFormat (WAVEFORMATEX**) = 0; - JUCE_COMCALL GetDevicePeriod (REFERENCE_TIME*, REFERENCE_TIME*) = 0; - JUCE_COMCALL Start() = 0; - JUCE_COMCALL Stop() = 0; - JUCE_COMCALL Reset() = 0; - JUCE_COMCALL SetEventHandle (HANDLE) = 0; - JUCE_COMCALL GetService (REFIID, void**) = 0; -}; - -JUCE_IUNKNOWNCLASS (IAudioCaptureClient, "C8ADBD64-E71E-48a0-A4DE-185C395CD317") -{ - JUCE_COMCALL GetBuffer (BYTE**, UINT32*, DWORD*, UINT64*, UINT64*) = 0; - JUCE_COMCALL ReleaseBuffer (UINT32) = 0; - JUCE_COMCALL GetNextPacketSize (UINT32*) = 0; -}; - -JUCE_IUNKNOWNCLASS (IAudioRenderClient, "F294ACFC-3146-4483-A7BF-ADDCA7C260E2") -{ - JUCE_COMCALL GetBuffer (UINT32, BYTE**) = 0; - JUCE_COMCALL ReleaseBuffer (UINT32, DWORD) = 0; -}; - -JUCE_IUNKNOWNCLASS (IAudioEndpointVolume, "5CDF2C82-841E-4546-9722-0CF74078229A") -{ - JUCE_COMCALL RegisterControlChangeNotify (void*) = 0; - JUCE_COMCALL UnregisterControlChangeNotify (void*) = 0; - JUCE_COMCALL GetChannelCount (UINT*) = 0; - JUCE_COMCALL SetMasterVolumeLevel (float, LPCGUID) = 0; - JUCE_COMCALL SetMasterVolumeLevelScalar (float, LPCGUID) = 0; - JUCE_COMCALL GetMasterVolumeLevel (float*) = 0; - JUCE_COMCALL GetMasterVolumeLevelScalar (float*) = 0; - JUCE_COMCALL SetChannelVolumeLevel (UINT, float, LPCGUID) = 0; - JUCE_COMCALL SetChannelVolumeLevelScalar (UINT, float, LPCGUID) = 0; - JUCE_COMCALL GetChannelVolumeLevel (UINT, float*) = 0; - JUCE_COMCALL GetChannelVolumeLevelScalar (UINT, float*) = 0; - JUCE_COMCALL SetMute (BOOL, LPCGUID) = 0; - JUCE_COMCALL GetMute (BOOL*) = 0; - JUCE_COMCALL GetVolumeStepInfo (UINT*, UINT*) = 0; - JUCE_COMCALL VolumeStepUp (LPCGUID) = 0; - JUCE_COMCALL VolumeStepDown (LPCGUID) = 0; - JUCE_COMCALL QueryHardwareSupport (DWORD*) = 0; - JUCE_COMCALL GetVolumeRange (float*, float*, float*) = 0; -}; - -enum AudioSessionDisconnectReason -{ - DisconnectReasonDeviceRemoval = 0, - DisconnectReasonServerShutdown = 1, - DisconnectReasonFormatChanged = 2, - DisconnectReasonSessionLogoff = 3, - DisconnectReasonSessionDisconnected = 4, - DisconnectReasonExclusiveModeOverride = 5 -}; - -enum AudioSessionState -{ - AudioSessionStateInactive = 0, - AudioSessionStateActive = 1, - AudioSessionStateExpired = 2 -}; - -JUCE_IUNKNOWNCLASS (IAudioSessionEvents, "24918ACC-64B3-37C1-8CA9-74A66E9957A8") -{ - JUCE_COMCALL OnDisplayNameChanged (LPCWSTR, LPCGUID) = 0; - JUCE_COMCALL OnIconPathChanged (LPCWSTR, LPCGUID) = 0; - JUCE_COMCALL OnSimpleVolumeChanged (float, BOOL, LPCGUID) = 0; - JUCE_COMCALL OnChannelVolumeChanged (DWORD, float*, DWORD, LPCGUID) = 0; - JUCE_COMCALL OnGroupingParamChanged (LPCGUID, LPCGUID) = 0; - JUCE_COMCALL OnStateChanged (AudioSessionState) = 0; - JUCE_COMCALL OnSessionDisconnected (AudioSessionDisconnectReason) = 0; -}; - -JUCE_IUNKNOWNCLASS (IAudioSessionControl, "F4B1A599-7266-4319-A8CA-E70ACB11E8CD") -{ - JUCE_COMCALL GetState (AudioSessionState*) = 0; - JUCE_COMCALL GetDisplayName (LPWSTR*) = 0; - JUCE_COMCALL SetDisplayName (LPCWSTR, LPCGUID) = 0; - JUCE_COMCALL GetIconPath (LPWSTR*) = 0; - JUCE_COMCALL SetIconPath (LPCWSTR, LPCGUID) = 0; - JUCE_COMCALL GetGroupingParam (GUID*) = 0; - JUCE_COMCALL SetGroupingParam (LPCGUID, LPCGUID) = 0; - JUCE_COMCALL RegisterAudioSessionNotification (IAudioSessionEvents*) = 0; - JUCE_COMCALL UnregisterAudioSessionNotification (IAudioSessionEvents*) = 0; -}; - -#undef JUCE_COMCALL -#undef JUCE_COMCLASS -#undef JUCE_IUNKNOWNCLASS - -//============================================================================== -namespace WasapiClasses -{ - -String getDeviceID (IMMDevice* const device) -{ - String s; - WCHAR* deviceId = nullptr; - - if (check (device->GetId (&deviceId))) - { - s = String (deviceId); - CoTaskMemFree (deviceId); - } - - return s; -} - -EDataFlow getDataFlow (const ComSmartPtr& device) -{ - EDataFlow flow = eRender; - ComSmartPtr endPoint; - if (check (device.QueryInterface (endPoint))) - (void) check (endPoint->GetDataFlow (&flow)); - - return flow; -} - -int refTimeToSamples (const REFERENCE_TIME& t, const double sampleRate) noexcept -{ - return roundToInt (sampleRate * ((double) t) * 0.0000001); -} - -void copyWavFormat (WAVEFORMATEXTENSIBLE& dest, const WAVEFORMATEX* const src) noexcept -{ - memcpy (&dest, src, src->wFormatTag == WAVE_FORMAT_EXTENSIBLE ? sizeof (WAVEFORMATEXTENSIBLE) - : sizeof (WAVEFORMATEX)); -} - -//============================================================================== -class WASAPIDeviceBase -{ -public: - WASAPIDeviceBase (const ComSmartPtr& d, const bool exclusiveMode) - : device (d), - sampleRate (0), - defaultSampleRate (0), - numChannels (0), - actualNumChannels (0), - minBufferSize (0), - defaultBufferSize (0), - latencySamples (0), - useExclusiveMode (exclusiveMode), - sampleRateHasChanged (false) - { - clientEvent = CreateEvent (0, false, false, _T("JuceWASAPI")); - - ComSmartPtr tempClient (createClient()); - if (tempClient == nullptr) - return; - - REFERENCE_TIME defaultPeriod, minPeriod; - if (! check (tempClient->GetDevicePeriod (&defaultPeriod, &minPeriod))) - return; - - WAVEFORMATEX* mixFormat = nullptr; - if (! check (tempClient->GetMixFormat (&mixFormat))) - return; - - WAVEFORMATEXTENSIBLE format; - copyWavFormat (format, mixFormat); - CoTaskMemFree (mixFormat); - - actualNumChannels = numChannels = format.Format.nChannels; - defaultSampleRate = format.Format.nSamplesPerSec; - minBufferSize = refTimeToSamples (minPeriod, defaultSampleRate); - defaultBufferSize = refTimeToSamples (defaultPeriod, defaultSampleRate); - mixFormatChannelMask = format.dwChannelMask; - - rates.addUsingDefaultSort (defaultSampleRate); - - static const int ratesToTest[] = { 44100, 48000, 88200, 96000, 176400, 192000 }; - - for (int i = 0; i < numElementsInArray (ratesToTest); ++i) - { - if (ratesToTest[i] == defaultSampleRate) - continue; - - format.Format.nSamplesPerSec = (DWORD) ratesToTest[i]; - - if (SUCCEEDED (tempClient->IsFormatSupported (useExclusiveMode ? AUDCLNT_SHAREMODE_EXCLUSIVE : AUDCLNT_SHAREMODE_SHARED, - (WAVEFORMATEX*) &format, 0))) - if (! rates.contains (ratesToTest[i])) - rates.addUsingDefaultSort (ratesToTest[i]); - } - } - - virtual ~WASAPIDeviceBase() - { - device = nullptr; - CloseHandle (clientEvent); - } - - bool isOk() const noexcept { return defaultBufferSize > 0 && defaultSampleRate > 0; } - - bool openClient (const double newSampleRate, const BigInteger& newChannels) - { - sampleRate = newSampleRate; - channels = newChannels; - channels.setRange (actualNumChannels, channels.getHighestBit() + 1 - actualNumChannels, false); - numChannels = channels.getHighestBit() + 1; - - if (numChannels == 0) - return true; - - client = createClient(); - - if (client != nullptr - && (tryInitialisingWithFormat (true, 4) || tryInitialisingWithFormat (false, 4) - || tryInitialisingWithFormat (false, 3) || tryInitialisingWithFormat (false, 2))) - { - sampleRateHasChanged = false; - - channelMaps.clear(); - for (int i = 0; i <= channels.getHighestBit(); ++i) - if (channels[i]) - channelMaps.add (i); - - REFERENCE_TIME latency; - if (check (client->GetStreamLatency (&latency))) - latencySamples = refTimeToSamples (latency, sampleRate); - - (void) check (client->GetBufferSize (&actualBufferSize)); - - createSessionEventCallback(); - - return check (client->SetEventHandle (clientEvent)); - } - - return false; - } - - void closeClient() - { - if (client != nullptr) - client->Stop(); - - deleteSessionEventCallback(); - client = nullptr; - ResetEvent (clientEvent); - } - - void deviceSampleRateChanged() - { - sampleRateHasChanged = true; - } - - //============================================================================== - ComSmartPtr device; - ComSmartPtr client; - double sampleRate, defaultSampleRate; - int numChannels, actualNumChannels; - int minBufferSize, defaultBufferSize, latencySamples; - DWORD mixFormatChannelMask; - const bool useExclusiveMode; - Array rates; - HANDLE clientEvent; - BigInteger channels; - Array channelMaps; - UINT32 actualBufferSize; - int bytesPerSample; - bool sampleRateHasChanged; - - virtual void updateFormat (bool isFloat) = 0; - -private: - //============================================================================== - class SessionEventCallback : public ComBaseClassHelper - { - public: - SessionEventCallback (WASAPIDeviceBase& d) : owner (d) {} - - JUCE_COMRESULT OnDisplayNameChanged (LPCWSTR, LPCGUID) { return S_OK; } - JUCE_COMRESULT OnIconPathChanged (LPCWSTR, LPCGUID) { return S_OK; } - JUCE_COMRESULT OnSimpleVolumeChanged (float, BOOL, LPCGUID) { return S_OK; } - JUCE_COMRESULT OnChannelVolumeChanged (DWORD, float*, DWORD, LPCGUID) { return S_OK; } - JUCE_COMRESULT OnGroupingParamChanged (LPCGUID, LPCGUID) { return S_OK; } - JUCE_COMRESULT OnStateChanged (AudioSessionState) { return S_OK; } - - JUCE_COMRESULT OnSessionDisconnected (AudioSessionDisconnectReason reason) - { - if (reason == DisconnectReasonFormatChanged) - owner.deviceSampleRateChanged(); - - return S_OK; - } - - private: - WASAPIDeviceBase& owner; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (SessionEventCallback) - }; - - ComSmartPtr audioSessionControl; - ComSmartPtr sessionEventCallback; - - void createSessionEventCallback() - { - deleteSessionEventCallback(); - client->GetService (__uuidof (IAudioSessionControl), - (void**) audioSessionControl.resetAndGetPointerAddress()); - - if (audioSessionControl != nullptr) - { - sessionEventCallback = new SessionEventCallback (*this); - audioSessionControl->RegisterAudioSessionNotification (sessionEventCallback); - sessionEventCallback->Release(); // (required because ComBaseClassHelper objects are constructed with a ref count of 1) - } - } - - void deleteSessionEventCallback() - { - if (audioSessionControl != nullptr && sessionEventCallback != nullptr) - audioSessionControl->UnregisterAudioSessionNotification (sessionEventCallback); - - audioSessionControl = nullptr; - sessionEventCallback = nullptr; - } - - //============================================================================== - ComSmartPtr createClient() - { - ComSmartPtr client; - - if (device != nullptr) - logFailure (device->Activate (__uuidof (IAudioClient), CLSCTX_INPROC_SERVER, - nullptr, (void**) client.resetAndGetPointerAddress())); - - return client; - } - - bool tryInitialisingWithFormat (const bool useFloat, const int bytesPerSampleToTry) - { - WAVEFORMATEXTENSIBLE format; - zerostruct (format); - - if (numChannels <= 2 && bytesPerSampleToTry <= 2) - { - format.Format.wFormatTag = WAVE_FORMAT_PCM; - } - else - { - format.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE; - format.Format.cbSize = sizeof (WAVEFORMATEXTENSIBLE) - sizeof (WAVEFORMATEX); - } - - format.Format.nSamplesPerSec = (DWORD) sampleRate; - format.Format.nChannels = (WORD) numChannels; - format.Format.wBitsPerSample = (WORD) (8 * bytesPerSampleToTry); - format.Format.nAvgBytesPerSec = (DWORD) (format.Format.nSamplesPerSec * numChannels * bytesPerSampleToTry); - format.Format.nBlockAlign = (WORD) (numChannels * bytesPerSampleToTry); - format.SubFormat = useFloat ? KSDATAFORMAT_SUBTYPE_IEEE_FLOAT : KSDATAFORMAT_SUBTYPE_PCM; - format.Samples.wValidBitsPerSample = format.Format.wBitsPerSample; - format.dwChannelMask = mixFormatChannelMask; - - WAVEFORMATEXTENSIBLE* nearestFormat = nullptr; - - HRESULT hr = client->IsFormatSupported (useExclusiveMode ? AUDCLNT_SHAREMODE_EXCLUSIVE - : AUDCLNT_SHAREMODE_SHARED, - (WAVEFORMATEX*) &format, - useExclusiveMode ? nullptr : (WAVEFORMATEX**) &nearestFormat); - logFailure (hr); - - if (hr == S_FALSE && format.Format.nSamplesPerSec == nearestFormat->Format.nSamplesPerSec) - { - copyWavFormat (format, (WAVEFORMATEX*) nearestFormat); - hr = S_OK; - } - - CoTaskMemFree (nearestFormat); - - REFERENCE_TIME defaultPeriod = 0, minPeriod = 0; - if (useExclusiveMode) - check (client->GetDevicePeriod (&defaultPeriod, &minPeriod)); - - GUID session; - if (hr == S_OK - && check (client->Initialize (useExclusiveMode ? AUDCLNT_SHAREMODE_EXCLUSIVE : AUDCLNT_SHAREMODE_SHARED, - 0x40000 /*AUDCLNT_STREAMFLAGS_EVENTCALLBACK*/, - defaultPeriod, defaultPeriod, (WAVEFORMATEX*) &format, &session))) - { - actualNumChannels = format.Format.nChannels; - const bool isFloat = format.Format.wFormatTag == WAVE_FORMAT_EXTENSIBLE && format.SubFormat == KSDATAFORMAT_SUBTYPE_IEEE_FLOAT; - bytesPerSample = format.Format.wBitsPerSample / 8; - - updateFormat (isFloat); - return true; - } - - return false; - } - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (WASAPIDeviceBase) -}; - -//============================================================================== -class WASAPIInputDevice : public WASAPIDeviceBase -{ -public: - WASAPIInputDevice (const ComSmartPtr& d, const bool exclusiveMode) - : WASAPIDeviceBase (d, exclusiveMode), - reservoir (1, 1) - { - } - - ~WASAPIInputDevice() - { - close(); - } - - bool open (const double newSampleRate, const BigInteger& newChannels) - { - reservoirSize = 0; - reservoirCapacity = 16384; - reservoir.setSize (actualNumChannels * reservoirCapacity * sizeof (float)); - return openClient (newSampleRate, newChannels) - && (numChannels == 0 || check (client->GetService (__uuidof (IAudioCaptureClient), - (void**) captureClient.resetAndGetPointerAddress()))); - } - - void close() - { - closeClient(); - captureClient = nullptr; - reservoir.reset(); - } - - template - void updateFormatWithType (SourceType*) - { - typedef AudioData::Pointer NativeType; - converter = new AudioData::ConverterInstance, NativeType> (actualNumChannels, 1); - } - - void updateFormat (bool isFloat) - { - if (isFloat) updateFormatWithType ((AudioData::Float32*) 0); - else if (bytesPerSample == 4) updateFormatWithType ((AudioData::Int32*) 0); - else if (bytesPerSample == 3) updateFormatWithType ((AudioData::Int24*) 0); - else updateFormatWithType ((AudioData::Int16*) 0); - } - - void copyBuffers (float** destBuffers, int numDestBuffers, int bufferSize, Thread& thread) - { - if (numChannels <= 0) - return; - - int offset = 0; - - while (bufferSize > 0) - { - if (reservoirSize > 0) // There's stuff in the reservoir, so use that... - { - const int samplesToDo = jmin (bufferSize, (int) reservoirSize); - - for (int i = 0; i < numDestBuffers; ++i) - converter->convertSamples (destBuffers[i] + offset, 0, reservoir.getData(), channelMaps.getUnchecked(i), samplesToDo); - - bufferSize -= samplesToDo; - offset += samplesToDo; - reservoirSize = 0; - } - else - { - UINT32 packetLength = 0; - if (! check (captureClient->GetNextPacketSize (&packetLength))) - break; - - if (packetLength == 0) - { - if (thread.threadShouldExit() - || WaitForSingleObject (clientEvent, 1000) == WAIT_TIMEOUT) - break; - - continue; - } - - uint8* inputData; - UINT32 numSamplesAvailable; - DWORD flags; - - if (check (captureClient->GetBuffer (&inputData, &numSamplesAvailable, &flags, 0, 0))) - { - const int samplesToDo = jmin (bufferSize, (int) numSamplesAvailable); - - for (int i = 0; i < numDestBuffers; ++i) - converter->convertSamples (destBuffers[i] + offset, 0, inputData, channelMaps.getUnchecked(i), samplesToDo); - - bufferSize -= samplesToDo; - offset += samplesToDo; - - if (samplesToDo < (int) numSamplesAvailable) - { - reservoirSize = jmin ((int) (numSamplesAvailable - samplesToDo), reservoirCapacity); - memcpy ((uint8*) reservoir.getData(), inputData + bytesPerSample * actualNumChannels * samplesToDo, - (size_t) (bytesPerSample * actualNumChannels * reservoirSize)); - } - - captureClient->ReleaseBuffer (numSamplesAvailable); - } - } - } - } - - ComSmartPtr captureClient; - MemoryBlock reservoir; - int reservoirSize, reservoirCapacity; - ScopedPointer converter; - -private: - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (WASAPIInputDevice) -}; - -//============================================================================== -class WASAPIOutputDevice : public WASAPIDeviceBase -{ -public: - WASAPIOutputDevice (const ComSmartPtr& d, const bool exclusiveMode) - : WASAPIDeviceBase (d, exclusiveMode) - { - } - - ~WASAPIOutputDevice() - { - close(); - } - - bool open (const double newSampleRate, const BigInteger& newChannels) - { - return openClient (newSampleRate, newChannels) - && (numChannels == 0 || check (client->GetService (__uuidof (IAudioRenderClient), (void**) renderClient.resetAndGetPointerAddress()))); - } - - void close() - { - closeClient(); - renderClient = nullptr; - } - - template - void updateFormatWithType (DestType*) - { - typedef AudioData::Pointer NativeType; - converter = new AudioData::ConverterInstance > (1, actualNumChannels); - } - - void updateFormat (bool isFloat) - { - if (isFloat) updateFormatWithType ((AudioData::Float32*) 0); - else if (bytesPerSample == 4) updateFormatWithType ((AudioData::Int32*) 0); - else if (bytesPerSample == 3) updateFormatWithType ((AudioData::Int24*) 0); - else updateFormatWithType ((AudioData::Int16*) 0); - } - - void copyBuffers (const float** const srcBuffers, const int numSrcBuffers, int bufferSize, Thread& thread) - { - if (numChannels <= 0) - return; - - int offset = 0; - - while (bufferSize > 0) - { - UINT32 padding = 0; - if (! check (client->GetCurrentPadding (&padding))) - return; - - int samplesToDo = useExclusiveMode ? bufferSize - : jmin ((int) (actualBufferSize - padding), bufferSize); - - if (samplesToDo <= 0) - { - if (thread.threadShouldExit() - || WaitForSingleObject (clientEvent, 1000) == WAIT_TIMEOUT) - break; - - continue; - } - - uint8* outputData = nullptr; - if (check (renderClient->GetBuffer ((UINT32) samplesToDo, &outputData))) - { - for (int i = 0; i < numSrcBuffers; ++i) - converter->convertSamples (outputData, channelMaps.getUnchecked(i), srcBuffers[i] + offset, 0, samplesToDo); - - renderClient->ReleaseBuffer ((UINT32) samplesToDo, 0); - - offset += samplesToDo; - bufferSize -= samplesToDo; - } - } - } - - ComSmartPtr renderClient; - ScopedPointer converter; - -private: - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (WASAPIOutputDevice) -}; - -//============================================================================== -class WASAPIAudioIODevice : public AudioIODevice, - public Thread, - private AsyncUpdater -{ -public: - WASAPIAudioIODevice (const String& deviceName, - const String& outputDeviceId_, - const String& inputDeviceId_, - const bool exclusiveMode) - : AudioIODevice (deviceName, "Windows Audio"), - Thread ("Juce WASAPI"), - outputDeviceId (outputDeviceId_), - inputDeviceId (inputDeviceId_), - useExclusiveMode (exclusiveMode), - isOpen_ (false), - isStarted (false), - currentBufferSizeSamples (0), - currentSampleRate (0), - callback (nullptr) - { - } - - ~WASAPIAudioIODevice() - { - close(); - } - - bool initialise() - { - latencyIn = latencyOut = 0; - Array ratesIn, ratesOut; - - if (createDevices()) - { - jassert (inputDevice != nullptr || outputDevice != nullptr); - - if (inputDevice != nullptr && outputDevice != nullptr) - { - defaultSampleRate = jmin (inputDevice->defaultSampleRate, outputDevice->defaultSampleRate); - minBufferSize = jmin (inputDevice->minBufferSize, outputDevice->minBufferSize); - defaultBufferSize = jmax (inputDevice->defaultBufferSize, outputDevice->defaultBufferSize); - sampleRates = inputDevice->rates; - sampleRates.removeValuesNotIn (outputDevice->rates); - } - else - { - WASAPIDeviceBase* d = inputDevice != nullptr ? static_cast (inputDevice) - : static_cast (outputDevice); - defaultSampleRate = d->defaultSampleRate; - minBufferSize = d->minBufferSize; - defaultBufferSize = d->defaultBufferSize; - sampleRates = d->rates; - } - - bufferSizes.addUsingDefaultSort (defaultBufferSize); - if (minBufferSize != defaultBufferSize) - bufferSizes.addUsingDefaultSort (minBufferSize); - - int n = 64; - for (int i = 0; i < 40; ++i) - { - if (n >= minBufferSize && n <= 2048 && ! bufferSizes.contains (n)) - bufferSizes.addUsingDefaultSort (n); - - n += (n < 512) ? 32 : (n < 1024 ? 64 : 128); - } - - return true; - } - - return false; - } - - StringArray getOutputChannelNames() override - { - StringArray outChannels; - - if (outputDevice != nullptr) - for (int i = 1; i <= outputDevice->actualNumChannels; ++i) - outChannels.add ("Output channel " + String (i)); - - return outChannels; - } - - StringArray getInputChannelNames() override - { - StringArray inChannels; - - if (inputDevice != nullptr) - for (int i = 1; i <= inputDevice->actualNumChannels; ++i) - inChannels.add ("Input channel " + String (i)); - - return inChannels; - } - - Array getAvailableSampleRates() override { return sampleRates; } - Array getAvailableBufferSizes() override { return bufferSizes; } - int getDefaultBufferSize() override { return defaultBufferSize; } - - int getCurrentBufferSizeSamples() override { return currentBufferSizeSamples; } - double getCurrentSampleRate() override { return currentSampleRate; } - int getCurrentBitDepth() override { return 32; } - int getOutputLatencyInSamples() override { return latencyOut; } - int getInputLatencyInSamples() override { return latencyIn; } - BigInteger getActiveOutputChannels() const override { return outputDevice != nullptr ? outputDevice->channels : BigInteger(); } - BigInteger getActiveInputChannels() const override { return inputDevice != nullptr ? inputDevice->channels : BigInteger(); } - String getLastError() override { return lastError; } - - - String open (const BigInteger& inputChannels, const BigInteger& outputChannels, - double sampleRate, int bufferSizeSamples) override - { - close(); - lastError.clear(); - - if (sampleRates.size() == 0 && inputDevice != nullptr && outputDevice != nullptr) - { - lastError = TRANS("The input and output devices don't share a common sample rate!"); - return lastError; - } - - currentBufferSizeSamples = bufferSizeSamples <= 0 ? defaultBufferSize : jmax (bufferSizeSamples, minBufferSize); - currentSampleRate = sampleRate > 0 ? sampleRate : defaultSampleRate; - lastKnownInputChannels = inputChannels; - lastKnownOutputChannels = outputChannels; - - if (inputDevice != nullptr && ! inputDevice->open (currentSampleRate, inputChannels)) - { - lastError = TRANS("Couldn't open the input device!"); - return lastError; - } - - if (outputDevice != nullptr && ! outputDevice->open (currentSampleRate, outputChannels)) - { - close(); - lastError = TRANS("Couldn't open the output device!"); - return lastError; - } - - if (inputDevice != nullptr) ResetEvent (inputDevice->clientEvent); - if (outputDevice != nullptr) ResetEvent (outputDevice->clientEvent); - - startThread (8); - Thread::sleep (5); - - if (inputDevice != nullptr && inputDevice->client != nullptr) - { - latencyIn = (int) (inputDevice->latencySamples + currentBufferSizeSamples); - - if (! check (inputDevice->client->Start())) - { - close(); - lastError = TRANS("Couldn't start the input device!"); - return lastError; - } - } - - if (outputDevice != nullptr && outputDevice->client != nullptr) - { - latencyOut = (int) (outputDevice->latencySamples + currentBufferSizeSamples); - - if (! check (outputDevice->client->Start())) - { - close(); - lastError = TRANS("Couldn't start the output device!"); - return lastError; - } - } - - isOpen_ = true; - return lastError; - } - - void close() override - { - stop(); - signalThreadShouldExit(); - - if (inputDevice != nullptr) SetEvent (inputDevice->clientEvent); - if (outputDevice != nullptr) SetEvent (outputDevice->clientEvent); - - stopThread (5000); - - if (inputDevice != nullptr) inputDevice->close(); - if (outputDevice != nullptr) outputDevice->close(); - - isOpen_ = false; - } - - bool isOpen() override { return isOpen_ && isThreadRunning(); } - bool isPlaying() override { return isStarted && isOpen_ && isThreadRunning(); } - - void start (AudioIODeviceCallback* call) override - { - if (isOpen_ && call != nullptr && ! isStarted) - { - if (! isThreadRunning()) - { - // something's gone wrong and the thread's stopped.. - isOpen_ = false; - return; - } - - call->audioDeviceAboutToStart (this); - - const ScopedLock sl (startStopLock); - callback = call; - isStarted = true; - } - } - - void stop() override - { - if (isStarted) - { - AudioIODeviceCallback* const callbackLocal = callback; - - { - const ScopedLock sl (startStopLock); - isStarted = false; - } - - if (callbackLocal != nullptr) - callbackLocal->audioDeviceStopped(); - } - } - - void setMMThreadPriority() - { - DynamicLibrary dll ("avrt.dll"); - JUCE_LOAD_WINAPI_FUNCTION (dll, AvSetMmThreadCharacteristicsW, avSetMmThreadCharacteristics, HANDLE, (LPCWSTR, LPDWORD)) - JUCE_LOAD_WINAPI_FUNCTION (dll, AvSetMmThreadPriority, avSetMmThreadPriority, HANDLE, (HANDLE, AVRT_PRIORITY)) - - if (avSetMmThreadCharacteristics != 0 && avSetMmThreadPriority != 0) - { - DWORD dummy = 0; - HANDLE h = avSetMmThreadCharacteristics (L"Pro Audio", &dummy); - - if (h != 0) - avSetMmThreadPriority (h, AVRT_PRIORITY_NORMAL); - } - } - - void run() override - { - setMMThreadPriority(); - - const int bufferSize = currentBufferSizeSamples; - const int numInputBuffers = getActiveInputChannels().countNumberOfSetBits(); - const int numOutputBuffers = getActiveOutputChannels().countNumberOfSetBits(); - bool sampleRateChanged = false; - - AudioSampleBuffer ins (jmax (1, numInputBuffers), bufferSize + 32); - AudioSampleBuffer outs (jmax (1, numOutputBuffers), bufferSize + 32); - float** const inputBuffers = ins.getArrayOfWritePointers(); - float** const outputBuffers = outs.getArrayOfWritePointers(); - ins.clear(); - - while (! threadShouldExit()) - { - if (inputDevice != nullptr) - { - inputDevice->copyBuffers (inputBuffers, numInputBuffers, bufferSize, *this); - - if (threadShouldExit()) - break; - - if (inputDevice->sampleRateHasChanged) - { - sampleRateChanged = true; - sampleRateChangedByOutput = false; - } - } - - { - const ScopedLock sl (startStopLock); - - if (isStarted) - callback->audioDeviceIOCallback (const_cast (inputBuffers), numInputBuffers, - outputBuffers, numOutputBuffers, bufferSize); - else - outs.clear(); - } - - if (outputDevice != nullptr) - { - outputDevice->copyBuffers (const_cast (outputBuffers), numOutputBuffers, bufferSize, *this); - - if (outputDevice->sampleRateHasChanged) - { - sampleRateChanged = true; - sampleRateChangedByOutput = true; - } - } - - if (sampleRateChanged) - { - triggerAsyncUpdate(); - break; // Quit the thread... will restart it later! - } - } - } - - //============================================================================== - String outputDeviceId, inputDeviceId; - String lastError; - -private: - // Device stats... - ScopedPointer inputDevice; - ScopedPointer outputDevice; - const bool useExclusiveMode; - double defaultSampleRate; - int minBufferSize, defaultBufferSize; - int latencyIn, latencyOut; - Array sampleRates; - Array bufferSizes; - - // Active state... - bool isOpen_, isStarted; - int currentBufferSizeSamples; - double currentSampleRate; - bool sampleRateChangedByOutput; - - AudioIODeviceCallback* callback; - CriticalSection startStopLock; - - BigInteger lastKnownInputChannels, lastKnownOutputChannels; - - //============================================================================== - bool createDevices() - { - ComSmartPtr enumerator; - if (! check (enumerator.CoCreateInstance (__uuidof (MMDeviceEnumerator)))) - return false; - - ComSmartPtr deviceCollection; - if (! check (enumerator->EnumAudioEndpoints (eAll, DEVICE_STATE_ACTIVE, deviceCollection.resetAndGetPointerAddress()))) - return false; - - UINT32 numDevices = 0; - if (! check (deviceCollection->GetCount (&numDevices))) - return false; - - for (UINT32 i = 0; i < numDevices; ++i) - { - ComSmartPtr device; - if (! check (deviceCollection->Item (i, device.resetAndGetPointerAddress()))) - continue; - - const String deviceId (getDeviceID (device)); - if (deviceId.isEmpty()) - continue; - - const EDataFlow flow = getDataFlow (device); - - if (deviceId == inputDeviceId && flow == eCapture) - inputDevice = new WASAPIInputDevice (device, useExclusiveMode); - else if (deviceId == outputDeviceId && flow == eRender) - outputDevice = new WASAPIOutputDevice (device, useExclusiveMode); - } - - return (outputDeviceId.isEmpty() || (outputDevice != nullptr && outputDevice->isOk())) - && (inputDeviceId.isEmpty() || (inputDevice != nullptr && inputDevice->isOk())); - } - - //============================================================================== - void handleAsyncUpdate() override - { - stop(); - - outputDevice = nullptr; - inputDevice = nullptr; - initialise(); - - open (lastKnownInputChannels, lastKnownOutputChannels, - getChangedSampleRate(), currentBufferSizeSamples); - - start (callback); - } - - double getChangedSampleRate() const - { - if (outputDevice != nullptr && sampleRateChangedByOutput) - return outputDevice->defaultSampleRate; - - if (inputDevice != nullptr && ! sampleRateChangedByOutput) - return inputDevice->defaultSampleRate; - - return 0.0; - } - - //============================================================================== - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (WASAPIAudioIODevice) -}; - - -//============================================================================== -class WASAPIAudioIODeviceType : public AudioIODeviceType, - private DeviceChangeDetector -{ -public: - WASAPIAudioIODeviceType() - : AudioIODeviceType ("Windows Audio"), - DeviceChangeDetector (L"Windows Audio"), - hasScanned (false) - { - } - - ~WASAPIAudioIODeviceType() - { - if (notifyClient != nullptr) - enumerator->UnregisterEndpointNotificationCallback (notifyClient); - } - - //============================================================================== - void scanForDevices() - { - hasScanned = true; - - outputDeviceNames.clear(); - inputDeviceNames.clear(); - outputDeviceIds.clear(); - inputDeviceIds.clear(); - - scan (outputDeviceNames, inputDeviceNames, - outputDeviceIds, inputDeviceIds); - } - - StringArray getDeviceNames (bool wantInputNames) const - { - jassert (hasScanned); // need to call scanForDevices() before doing this - - return wantInputNames ? inputDeviceNames - : outputDeviceNames; - } - - int getDefaultDeviceIndex (bool /*forInput*/) const - { - jassert (hasScanned); // need to call scanForDevices() before doing this - return 0; - } - - int getIndexOfDevice (AudioIODevice* device, bool asInput) const - { - jassert (hasScanned); // need to call scanForDevices() before doing this - - if (WASAPIAudioIODevice* const d = dynamic_cast (device)) - return asInput ? inputDeviceIds.indexOf (d->inputDeviceId) - : outputDeviceIds.indexOf (d->outputDeviceId); - - return -1; - } - - bool hasSeparateInputsAndOutputs() const { return true; } - - AudioIODevice* createDevice (const String& outputDeviceName, - const String& inputDeviceName) - { - jassert (hasScanned); // need to call scanForDevices() before doing this - - const bool useExclusiveMode = false; - ScopedPointer device; - - const int outputIndex = outputDeviceNames.indexOf (outputDeviceName); - const int inputIndex = inputDeviceNames.indexOf (inputDeviceName); - - if (outputIndex >= 0 || inputIndex >= 0) - { - device = new WASAPIAudioIODevice (outputDeviceName.isNotEmpty() ? outputDeviceName - : inputDeviceName, - outputDeviceIds [outputIndex], - inputDeviceIds [inputIndex], - useExclusiveMode); - - if (! device->initialise()) - device = nullptr; - } - - return device.release(); - } - - //============================================================================== - StringArray outputDeviceNames, outputDeviceIds; - StringArray inputDeviceNames, inputDeviceIds; - -private: - bool hasScanned; - ComSmartPtr enumerator; - - //============================================================================== - class ChangeNotificationClient : public ComBaseClassHelper - { - public: - ChangeNotificationClient (WASAPIAudioIODeviceType& d) - : ComBaseClassHelper (0), device (d) {} - - HRESULT STDMETHODCALLTYPE OnDeviceAdded (LPCWSTR) { return notify(); } - HRESULT STDMETHODCALLTYPE OnDeviceRemoved (LPCWSTR) { return notify(); } - HRESULT STDMETHODCALLTYPE OnDeviceStateChanged (LPCWSTR, DWORD) { return notify(); } - HRESULT STDMETHODCALLTYPE OnDefaultDeviceChanged (EDataFlow, ERole, LPCWSTR) { return notify(); } - HRESULT STDMETHODCALLTYPE OnPropertyValueChanged (LPCWSTR, const PROPERTYKEY) { return notify(); } - - private: - WASAPIAudioIODeviceType& device; - - HRESULT notify() { device.triggerAsyncDeviceChangeCallback(); return S_OK; } - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ChangeNotificationClient) - }; - - ComSmartPtr notifyClient; - - //============================================================================== - static String getDefaultEndpoint (IMMDeviceEnumerator* const enumerator, const bool forCapture) - { - String s; - IMMDevice* dev = nullptr; - - if (check (enumerator->GetDefaultAudioEndpoint (forCapture ? eCapture : eRender, - eMultimedia, &dev))) - { - WCHAR* deviceId = nullptr; - - if (check (dev->GetId (&deviceId))) - { - s = deviceId; - CoTaskMemFree (deviceId); - } - - dev->Release(); - } - - return s; - } - - //============================================================================== - void scan (StringArray& outputDeviceNames, - StringArray& inputDeviceNames, - StringArray& outputDeviceIds, - StringArray& inputDeviceIds) - { - if (enumerator == nullptr) - { - if (! check (enumerator.CoCreateInstance (__uuidof (MMDeviceEnumerator)))) - return; - - notifyClient = new ChangeNotificationClient (*this); - enumerator->RegisterEndpointNotificationCallback (notifyClient); - } - - const String defaultRenderer (getDefaultEndpoint (enumerator, false)); - const String defaultCapture (getDefaultEndpoint (enumerator, true)); - - ComSmartPtr deviceCollection; - UINT32 numDevices = 0; - - if (! (check (enumerator->EnumAudioEndpoints (eAll, DEVICE_STATE_ACTIVE, deviceCollection.resetAndGetPointerAddress())) - && check (deviceCollection->GetCount (&numDevices)))) - return; - - for (UINT32 i = 0; i < numDevices; ++i) - { - ComSmartPtr device; - if (! check (deviceCollection->Item (i, device.resetAndGetPointerAddress()))) - continue; - - DWORD state = 0; - if (! (check (device->GetState (&state)) && state == DEVICE_STATE_ACTIVE)) - continue; - - const String deviceId (getDeviceID (device)); - String name; - - { - ComSmartPtr properties; - if (! check (device->OpenPropertyStore (STGM_READ, properties.resetAndGetPointerAddress()))) - continue; - - PROPVARIANT value; - zerostruct (value); - - const PROPERTYKEY PKEY_Device_FriendlyName - = { { 0xa45c254e, 0xdf1c, 0x4efd, { 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0 } }, 14 }; - - if (check (properties->GetValue (PKEY_Device_FriendlyName, &value))) - name = value.pwszVal; - - PropVariantClear (&value); - } - - const EDataFlow flow = getDataFlow (device); - - if (flow == eRender) - { - const int index = (deviceId == defaultRenderer) ? 0 : -1; - outputDeviceIds.insert (index, deviceId); - outputDeviceNames.insert (index, name); - } - else if (flow == eCapture) - { - const int index = (deviceId == defaultCapture) ? 0 : -1; - inputDeviceIds.insert (index, deviceId); - inputDeviceNames.insert (index, name); - } - } - - inputDeviceNames.appendNumbersToDuplicates (false, false); - outputDeviceNames.appendNumbersToDuplicates (false, false); - } - - //============================================================================== - void systemDeviceChanged() override - { - StringArray newOutNames, newInNames, newOutIds, newInIds; - scan (newOutNames, newInNames, newOutIds, newInIds); - - if (newOutNames != outputDeviceNames - || newInNames != inputDeviceNames - || newOutIds != outputDeviceIds - || newInIds != inputDeviceIds) - { - hasScanned = true; - outputDeviceNames = newOutNames; - inputDeviceNames = newInNames; - outputDeviceIds = newOutIds; - inputDeviceIds = newInIds; - } - - callDeviceChangeListeners(); - } - - //============================================================================== - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (WASAPIAudioIODeviceType) -}; - -//============================================================================== -struct MMDeviceMasterVolume -{ - MMDeviceMasterVolume() - { - ComSmartPtr enumerator; - if (check (enumerator.CoCreateInstance (__uuidof (MMDeviceEnumerator)))) - { - ComSmartPtr device; - if (check (enumerator->GetDefaultAudioEndpoint (eRender, eConsole, device.resetAndGetPointerAddress()))) - check (device->Activate (__uuidof (IAudioEndpointVolume), CLSCTX_INPROC_SERVER, nullptr, - (void**) endpointVolume.resetAndGetPointerAddress())); - } - } - - float getGain() const - { - float vol = 0.0f; - if (endpointVolume != nullptr) - check (endpointVolume->GetMasterVolumeLevelScalar (&vol)); - - return vol; - } - - bool setGain (float newGain) const - { - return endpointVolume != nullptr - && check (endpointVolume->SetMasterVolumeLevelScalar (jlimit (0.0f, 1.0f, newGain), nullptr)); - } - - bool isMuted() const - { - BOOL mute = 0; - return endpointVolume != nullptr - && check (endpointVolume->GetMute (&mute)) && mute != 0; - } - - bool setMuted (bool shouldMute) const - { - return endpointVolume != nullptr - && check (endpointVolume->SetMute (shouldMute, nullptr)); - } - - ComSmartPtr endpointVolume; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MMDeviceMasterVolume) -}; - -} - -//============================================================================== -AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_WASAPI() -{ - if (SystemStats::getOperatingSystemType() >= SystemStats::WinVista) - return new WasapiClasses::WASAPIAudioIODeviceType(); - - return nullptr; -} - -//============================================================================== -#define JUCE_SYSTEMAUDIOVOL_IMPLEMENTED 1 -float JUCE_CALLTYPE SystemAudioVolume::getGain() { return WasapiClasses::MMDeviceMasterVolume().getGain(); } -bool JUCE_CALLTYPE SystemAudioVolume::setGain (float gain) { return WasapiClasses::MMDeviceMasterVolume().setGain (gain); } -bool JUCE_CALLTYPE SystemAudioVolume::isMuted() { return WasapiClasses::MMDeviceMasterVolume().isMuted(); } -bool JUCE_CALLTYPE SystemAudioVolume::setMuted (bool mute) { return WasapiClasses::MMDeviceMasterVolume().setMuted (mute); } diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/sources/juce_AudioSourcePlayer.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/sources/juce_AudioSourcePlayer.cpp deleted file mode 100644 index c351795338..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/sources/juce_AudioSourcePlayer.cpp +++ /dev/null @@ -1,182 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -AudioSourcePlayer::AudioSourcePlayer() - : source (nullptr), - sampleRate (0), - bufferSize (0), - lastGain (1.0f), - gain (1.0f) -{ -} - -AudioSourcePlayer::~AudioSourcePlayer() -{ - setSource (nullptr); -} - -void AudioSourcePlayer::setSource (AudioSource* newSource) -{ - if (source != newSource) - { - AudioSource* const oldSource = source; - - if (newSource != nullptr && bufferSize > 0 && sampleRate > 0) - newSource->prepareToPlay (bufferSize, sampleRate); - - { - const ScopedLock sl (readLock); - source = newSource; - } - - if (oldSource != nullptr) - oldSource->releaseResources(); - } -} - -void AudioSourcePlayer::setGain (const float newGain) noexcept -{ - gain = newGain; -} - -void AudioSourcePlayer::audioDeviceIOCallback (const float** inputChannelData, - int totalNumInputChannels, - float** outputChannelData, - int totalNumOutputChannels, - int numSamples) -{ - // these should have been prepared by audioDeviceAboutToStart()... - jassert (sampleRate > 0 && bufferSize > 0); - - const ScopedLock sl (readLock); - - if (source != nullptr) - { - int numActiveChans = 0, numInputs = 0, numOutputs = 0; - - // messy stuff needed to compact the channels down into an array - // of non-zero pointers.. - for (int i = 0; i < totalNumInputChannels; ++i) - { - if (inputChannelData[i] != nullptr) - { - inputChans [numInputs++] = inputChannelData[i]; - if (numInputs >= numElementsInArray (inputChans)) - break; - } - } - - for (int i = 0; i < totalNumOutputChannels; ++i) - { - if (outputChannelData[i] != nullptr) - { - outputChans [numOutputs++] = outputChannelData[i]; - if (numOutputs >= numElementsInArray (outputChans)) - break; - } - } - - if (numInputs > numOutputs) - { - // if there aren't enough output channels for the number of - // inputs, we need to create some temporary extra ones (can't - // use the input data in case it gets written to) - tempBuffer.setSize (numInputs - numOutputs, numSamples, - false, false, true); - - for (int i = 0; i < numOutputs; ++i) - { - channels[numActiveChans] = outputChans[i]; - memcpy (channels[numActiveChans], inputChans[i], sizeof (float) * (size_t) numSamples); - ++numActiveChans; - } - - for (int i = numOutputs; i < numInputs; ++i) - { - channels[numActiveChans] = tempBuffer.getWritePointer (i - numOutputs); - memcpy (channels[numActiveChans], inputChans[i], sizeof (float) * (size_t) numSamples); - ++numActiveChans; - } - } - else - { - for (int i = 0; i < numInputs; ++i) - { - channels[numActiveChans] = outputChans[i]; - memcpy (channels[numActiveChans], inputChans[i], sizeof (float) * (size_t) numSamples); - ++numActiveChans; - } - - for (int i = numInputs; i < numOutputs; ++i) - { - channels[numActiveChans] = outputChans[i]; - zeromem (channels[numActiveChans], sizeof (float) * (size_t) numSamples); - ++numActiveChans; - } - } - - AudioSampleBuffer buffer (channels, numActiveChans, numSamples); - - AudioSourceChannelInfo info (&buffer, 0, numSamples); - source->getNextAudioBlock (info); - - for (int i = info.buffer->getNumChannels(); --i >= 0;) - buffer.applyGainRamp (i, info.startSample, info.numSamples, lastGain, gain); - - lastGain = gain; - } - else - { - for (int i = 0; i < totalNumOutputChannels; ++i) - if (outputChannelData[i] != nullptr) - zeromem (outputChannelData[i], sizeof (float) * (size_t) numSamples); - } -} - -void AudioSourcePlayer::audioDeviceAboutToStart (AudioIODevice* device) -{ - prepareToPlay (device->getCurrentSampleRate(), - device->getCurrentBufferSizeSamples()); -} - -void AudioSourcePlayer::prepareToPlay (double newSampleRate, int newBufferSize) -{ - sampleRate = newSampleRate; - bufferSize = newBufferSize; - zeromem (channels, sizeof (channels)); - - if (source != nullptr) - source->prepareToPlay (bufferSize, sampleRate); -} - -void AudioSourcePlayer::audioDeviceStopped() -{ - if (source != nullptr) - source->releaseResources(); - - sampleRate = 0.0; - bufferSize = 0; - - tempBuffer.setSize (2, 8); -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/sources/juce_AudioSourcePlayer.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/sources/juce_AudioSourcePlayer.h deleted file mode 100644 index 0a3751c514..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/sources/juce_AudioSourcePlayer.h +++ /dev/null @@ -1,115 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_AUDIOSOURCEPLAYER_H_INCLUDED -#define JUCE_AUDIOSOURCEPLAYER_H_INCLUDED - - -//============================================================================== -/** - Wrapper class to continuously stream audio from an audio source to an - AudioIODevice. - - This object acts as an AudioIODeviceCallback, so can be attached to an - output device, and will stream audio from an AudioSource. -*/ -class JUCE_API AudioSourcePlayer : public AudioIODeviceCallback -{ -public: - //============================================================================== - /** Creates an empty AudioSourcePlayer. */ - AudioSourcePlayer(); - - /** Destructor. - - Make sure this object isn't still being used by an AudioIODevice before - deleting it! - */ - virtual ~AudioSourcePlayer(); - - //============================================================================== - /** Changes the current audio source to play from. - - If the source passed in is already being used, this method will do nothing. - If the source is not null, its prepareToPlay() method will be called - before it starts being used for playback. - - If there's another source currently playing, its releaseResources() method - will be called after it has been swapped for the new one. - - @param newSource the new source to use - this will NOT be deleted - by this object when no longer needed, so it's the - caller's responsibility to manage it. - */ - void setSource (AudioSource* newSource); - - /** Returns the source that's playing. - May return nullptr if there's no source. - */ - AudioSource* getCurrentSource() const noexcept { return source; } - - /** Sets a gain to apply to the audio data. - @see getGain - */ - void setGain (float newGain) noexcept; - - /** Returns the current gain. - @see setGain - */ - float getGain() const noexcept { return gain; } - - //============================================================================== - /** Implementation of the AudioIODeviceCallback method. */ - void audioDeviceIOCallback (const float** inputChannelData, - int totalNumInputChannels, - float** outputChannelData, - int totalNumOutputChannels, - int numSamples) override; - - /** Implementation of the AudioIODeviceCallback method. */ - void audioDeviceAboutToStart (AudioIODevice* device) override; - - /** Implementation of the AudioIODeviceCallback method. */ - void audioDeviceStopped() override; - - /** An alternative method for initialising the source without an AudioIODevice. */ - void prepareToPlay (double sampleRate, int blockSize); - -private: - //============================================================================== - CriticalSection readLock; - AudioSource* source; - double sampleRate; - int bufferSize; - float* channels [128]; - float* outputChans [128]; - const float* inputChans [128]; - AudioSampleBuffer tempBuffer; - float lastGain, gain; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioSourcePlayer) -}; - - -#endif // JUCE_AUDIOSOURCEPLAYER_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/sources/juce_AudioTransportSource.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/sources/juce_AudioTransportSource.cpp deleted file mode 100644 index feb58a983f..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/sources/juce_AudioTransportSource.cpp +++ /dev/null @@ -1,298 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -AudioTransportSource::AudioTransportSource() - : source (nullptr), - resamplerSource (nullptr), - bufferingSource (nullptr), - positionableSource (nullptr), - masterSource (nullptr), - gain (1.0f), - lastGain (1.0f), - playing (false), - stopped (true), - sampleRate (44100.0), - sourceSampleRate (0.0), - blockSize (128), - readAheadBufferSize (0), - isPrepared (false), - inputStreamEOF (false) -{ -} - -AudioTransportSource::~AudioTransportSource() -{ - setSource (nullptr); - releaseMasterResources(); -} - -void AudioTransportSource::setSource (PositionableAudioSource* const newSource, - int readAheadSize, TimeSliceThread* readAheadThread, - double sourceSampleRateToCorrectFor, int maxNumChannels) -{ - if (source == newSource) - { - if (source == nullptr) - return; - - setSource (nullptr, 0, nullptr); // deselect and reselect to avoid releasing resources wrongly - } - - readAheadBufferSize = readAheadSize; - sourceSampleRate = sourceSampleRateToCorrectFor; - - ResamplingAudioSource* newResamplerSource = nullptr; - BufferingAudioSource* newBufferingSource = nullptr; - PositionableAudioSource* newPositionableSource = nullptr; - AudioSource* newMasterSource = nullptr; - - ScopedPointer oldResamplerSource (resamplerSource); - ScopedPointer oldBufferingSource (bufferingSource); - AudioSource* oldMasterSource = masterSource; - - if (newSource != nullptr) - { - newPositionableSource = newSource; - - if (readAheadSize > 0) - { - // If you want to use a read-ahead buffer, you must also provide a TimeSliceThread - // for it to use! - jassert (readAheadThread != nullptr); - - newPositionableSource = newBufferingSource - = new BufferingAudioSource (newPositionableSource, *readAheadThread, - false, readAheadSize, maxNumChannels); - } - - newPositionableSource->setNextReadPosition (0); - - if (sourceSampleRateToCorrectFor > 0) - newMasterSource = newResamplerSource - = new ResamplingAudioSource (newPositionableSource, false, maxNumChannels); - else - newMasterSource = newPositionableSource; - - if (isPrepared) - { - if (newResamplerSource != nullptr && sourceSampleRate > 0 && sampleRate > 0) - newResamplerSource->setResamplingRatio (sourceSampleRate / sampleRate); - - newMasterSource->prepareToPlay (blockSize, sampleRate); - } - } - - { - const ScopedLock sl (callbackLock); - - source = newSource; - resamplerSource = newResamplerSource; - bufferingSource = newBufferingSource; - masterSource = newMasterSource; - positionableSource = newPositionableSource; - - inputStreamEOF = false; - playing = false; - } - - if (oldMasterSource != nullptr) - oldMasterSource->releaseResources(); -} - -void AudioTransportSource::start() -{ - if ((! playing) && masterSource != nullptr) - { - { - const ScopedLock sl (callbackLock); - playing = true; - stopped = false; - inputStreamEOF = false; - } - - sendChangeMessage(); - } -} - -void AudioTransportSource::stop() -{ - if (playing) - { - { - const ScopedLock sl (callbackLock); - playing = false; - } - - int n = 500; - while (--n >= 0 && ! stopped) - Thread::sleep (2); - - sendChangeMessage(); - } -} - -void AudioTransportSource::setPosition (double newPosition) -{ - if (sampleRate > 0.0) - setNextReadPosition ((int64) (newPosition * sampleRate)); -} - -double AudioTransportSource::getCurrentPosition() const -{ - if (sampleRate > 0.0) - return getNextReadPosition() / sampleRate; - - return 0.0; -} - -double AudioTransportSource::getLengthInSeconds() const -{ - if (sampleRate > 0.0) - return getTotalLength() / sampleRate; - - return 0.0; -} - -void AudioTransportSource::setNextReadPosition (int64 newPosition) -{ - if (positionableSource != nullptr) - { - if (sampleRate > 0 && sourceSampleRate > 0) - newPosition = (int64) (newPosition * sourceSampleRate / sampleRate); - - positionableSource->setNextReadPosition (newPosition); - - if (resamplerSource != nullptr) - resamplerSource->flushBuffers(); - - inputStreamEOF = false; - } -} - -int64 AudioTransportSource::getNextReadPosition() const -{ - if (positionableSource != nullptr) - { - const double ratio = (sampleRate > 0 && sourceSampleRate > 0) ? sampleRate / sourceSampleRate : 1.0; - return (int64) (positionableSource->getNextReadPosition() * ratio); - } - - return 0; -} - -int64 AudioTransportSource::getTotalLength() const -{ - const ScopedLock sl (callbackLock); - - if (positionableSource != nullptr) - { - const double ratio = (sampleRate > 0 && sourceSampleRate > 0) ? sampleRate / sourceSampleRate : 1.0; - return (int64) (positionableSource->getTotalLength() * ratio); - } - - return 0; -} - -bool AudioTransportSource::isLooping() const -{ - const ScopedLock sl (callbackLock); - return positionableSource != nullptr && positionableSource->isLooping(); -} - -void AudioTransportSource::setGain (const float newGain) noexcept -{ - gain = newGain; -} - -void AudioTransportSource::prepareToPlay (int samplesPerBlockExpected, double newSampleRate) -{ - const ScopedLock sl (callbackLock); - - sampleRate = newSampleRate; - blockSize = samplesPerBlockExpected; - - if (masterSource != nullptr) - masterSource->prepareToPlay (samplesPerBlockExpected, sampleRate); - - if (resamplerSource != nullptr && sourceSampleRate > 0) - resamplerSource->setResamplingRatio (sourceSampleRate / sampleRate); - - inputStreamEOF = false; - isPrepared = true; -} - -void AudioTransportSource::releaseMasterResources() -{ - const ScopedLock sl (callbackLock); - - if (masterSource != nullptr) - masterSource->releaseResources(); - - isPrepared = false; -} - -void AudioTransportSource::releaseResources() -{ - releaseMasterResources(); -} - -void AudioTransportSource::getNextAudioBlock (const AudioSourceChannelInfo& info) -{ - const ScopedLock sl (callbackLock); - - if (masterSource != nullptr && ! stopped) - { - masterSource->getNextAudioBlock (info); - - if (! playing) - { - // just stopped playing, so fade out the last block.. - for (int i = info.buffer->getNumChannels(); --i >= 0;) - info.buffer->applyGainRamp (i, info.startSample, jmin (256, info.numSamples), 1.0f, 0.0f); - - if (info.numSamples > 256) - info.buffer->clear (info.startSample + 256, info.numSamples - 256); - } - - if (positionableSource->getNextReadPosition() > positionableSource->getTotalLength() + 1 - && ! positionableSource->isLooping()) - { - playing = false; - inputStreamEOF = true; - sendChangeMessage(); - } - - stopped = ! playing; - - for (int i = info.buffer->getNumChannels(); --i >= 0;) - info.buffer->applyGainRamp (i, info.startSample, info.numSamples, lastGain, gain); - } - else - { - info.clearActiveBufferRegion(); - stopped = true; - } - - lastGain = gain; -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/sources/juce_AudioTransportSource.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/sources/juce_AudioTransportSource.h deleted file mode 100644 index e60dee013a..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_devices/sources/juce_AudioTransportSource.h +++ /dev/null @@ -1,180 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_AUDIOTRANSPORTSOURCE_H_INCLUDED -#define JUCE_AUDIOTRANSPORTSOURCE_H_INCLUDED - - -//============================================================================== -/** - An AudioSource that takes a PositionableAudioSource and allows it to be - played, stopped, started, etc. - - This can also be told use a buffer and background thread to read ahead, and - if can correct for different sample-rates. - - You may want to use one of these along with an AudioSourcePlayer and AudioIODevice - to control playback of an audio file. - - @see AudioSource, AudioSourcePlayer -*/ -class JUCE_API AudioTransportSource : public PositionableAudioSource, - public ChangeBroadcaster -{ -public: - //============================================================================== - /** Creates an AudioTransportSource. - After creating one of these, use the setSource() method to select an input source. - */ - AudioTransportSource(); - - /** Destructor. */ - ~AudioTransportSource(); - - //============================================================================== - /** Sets the reader that is being used as the input source. - - This will stop playback, reset the position to 0 and change to the new reader. - - The source passed in will not be deleted by this object, so must be managed by - the caller. - - @param newSource the new input source to use. This may be zero - @param readAheadBufferSize a size of buffer to use for reading ahead. If this - is zero, no reading ahead will be done; if it's - greater than zero, a BufferingAudioSource will be used - to do the reading-ahead. If you set a non-zero value here, - you'll also need to set the readAheadThread parameter. - @param readAheadThread if you set readAheadBufferSize to a non-zero value, then - you'll also need to supply this TimeSliceThread object for - the background reader to use. The thread object must not be - deleted while the AudioTransport source is still using it. - @param sourceSampleRateToCorrectFor if this is non-zero, it specifies the sample - rate of the source, and playback will be sample-rate - adjusted to maintain playback at the correct pitch. If - this is 0, no sample-rate adjustment will be performed - @param maxNumChannels the maximum number of channels that may need to be played - */ - void setSource (PositionableAudioSource* newSource, - int readAheadBufferSize = 0, - TimeSliceThread* readAheadThread = nullptr, - double sourceSampleRateToCorrectFor = 0.0, - int maxNumChannels = 2); - - //============================================================================== - /** Changes the current playback position in the source stream. - - The next time the getNextAudioBlock() method is called, this - is the time from which it'll read data. - - @see getPosition - */ - void setPosition (double newPosition); - - /** Returns the position that the next data block will be read from - This is a time in seconds. - */ - double getCurrentPosition() const; - - /** Returns the stream's length in seconds. */ - double getLengthInSeconds() const; - - /** Returns true if the player has stopped because its input stream ran out of data. */ - bool hasStreamFinished() const noexcept { return inputStreamEOF; } - - //============================================================================== - /** Starts playing (if a source has been selected). - - If it starts playing, this will send a message to any ChangeListeners - that are registered with this object. - */ - void start(); - - /** Stops playing. - - If it's actually playing, this will send a message to any ChangeListeners - that are registered with this object. - */ - void stop(); - - /** Returns true if it's currently playing. */ - bool isPlaying() const noexcept { return playing; } - - //============================================================================== - /** Changes the gain to apply to the output. - @param newGain a factor by which to multiply the outgoing samples, - so 1.0 = 0dB, 0.5 = -6dB, 2.0 = 6dB, etc. - */ - void setGain (float newGain) noexcept; - - /** Returns the current gain setting. - @see setGain - */ - float getGain() const noexcept { return gain; } - - //============================================================================== - /** Implementation of the AudioSource method. */ - void prepareToPlay (int samplesPerBlockExpected, double sampleRate) override; - - /** Implementation of the AudioSource method. */ - void releaseResources() override; - - /** Implementation of the AudioSource method. */ - void getNextAudioBlock (const AudioSourceChannelInfo&) override; - - //============================================================================== - /** Implements the PositionableAudioSource method. */ - void setNextReadPosition (int64 newPosition) override; - - /** Implements the PositionableAudioSource method. */ - int64 getNextReadPosition() const override; - - /** Implements the PositionableAudioSource method. */ - int64 getTotalLength() const override; - - /** Implements the PositionableAudioSource method. */ - bool isLooping() const override; - -private: - //============================================================================== - PositionableAudioSource* source; - ResamplingAudioSource* resamplerSource; - BufferingAudioSource* bufferingSource; - PositionableAudioSource* positionableSource; - AudioSource* masterSource; - - CriticalSection callbackLock; - float volatile gain, lastGain; - bool volatile playing, stopped; - double sampleRate, sourceSampleRate; - int blockSize, readAheadBufferSize; - bool volatile isPrepared, inputStreamEOF; - - void releaseMasterResources(); - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioTransportSource) -}; - - -#endif // JUCE_AUDIOTRANSPORTSOURCE_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/codecs/juce_AiffAudioFormat.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/codecs/juce_AiffAudioFormat.cpp deleted file mode 100644 index 2029bc827c..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/codecs/juce_AiffAudioFormat.cpp +++ /dev/null @@ -1,954 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -static const char* const aiffFormatName = "AIFF file"; - -//============================================================================== -const char* const AiffAudioFormat::appleOneShot = "apple one shot"; -const char* const AiffAudioFormat::appleRootSet = "apple root set"; -const char* const AiffAudioFormat::appleRootNote = "apple root note"; -const char* const AiffAudioFormat::appleBeats = "apple beats"; -const char* const AiffAudioFormat::appleDenominator = "apple denominator"; -const char* const AiffAudioFormat::appleNumerator = "apple numerator"; -const char* const AiffAudioFormat::appleTag = "apple tag"; -const char* const AiffAudioFormat::appleKey = "apple key"; - -//============================================================================== -namespace AiffFileHelpers -{ - inline int chunkName (const char* name) noexcept { return (int) ByteOrder::littleEndianInt (name); } - - #if JUCE_MSVC - #pragma pack (push, 1) - #endif - - //============================================================================== - struct InstChunk - { - struct Loop - { - uint16 type; // these are different in AIFF and WAV - uint16 startIdentifier; - uint16 endIdentifier; - } JUCE_PACKED; - - int8 baseNote; - int8 detune; - int8 lowNote; - int8 highNote; - int8 lowVelocity; - int8 highVelocity; - int16 gain; - Loop sustainLoop; - Loop releaseLoop; - - void copyTo (StringPairArray& values) const - { - values.set ("MidiUnityNote", String (baseNote)); - values.set ("Detune", String (detune)); - - values.set ("LowNote", String (lowNote)); - values.set ("HighNote", String (highNote)); - values.set ("LowVelocity", String (lowVelocity)); - values.set ("HighVelocity", String (highVelocity)); - - values.set ("Gain", String ((int16) ByteOrder::swapIfLittleEndian ((uint16) gain))); - - values.set ("NumSampleLoops", String (2)); // always 2 with AIFF, WAV can have more - values.set ("Loop0Type", String (ByteOrder::swapIfLittleEndian (sustainLoop.type))); - values.set ("Loop0StartIdentifier", String (ByteOrder::swapIfLittleEndian (sustainLoop.startIdentifier))); - values.set ("Loop0EndIdentifier", String (ByteOrder::swapIfLittleEndian (sustainLoop.endIdentifier))); - values.set ("Loop1Type", String (ByteOrder::swapIfLittleEndian (releaseLoop.type))); - values.set ("Loop1StartIdentifier", String (ByteOrder::swapIfLittleEndian (releaseLoop.startIdentifier))); - values.set ("Loop1EndIdentifier", String (ByteOrder::swapIfLittleEndian (releaseLoop.endIdentifier))); - } - - static uint16 getValue16 (const StringPairArray& values, const char* name, const char* def) - { - return ByteOrder::swapIfLittleEndian ((uint16) values.getValue (name, def).getIntValue()); - } - - static int8 getValue8 (const StringPairArray& values, const char* name, const char* def) - { - return (int8) values.getValue (name, def).getIntValue(); - } - - static void create (MemoryBlock& block, const StringPairArray& values) - { - if (values.getAllKeys().contains ("MidiUnityNote", true)) - { - block.setSize ((sizeof (InstChunk) + 3) & ~(size_t) 3, true); - InstChunk& inst = *static_cast (block.getData()); - - inst.baseNote = getValue8 (values, "MidiUnityNote", "60"); - inst.detune = getValue8 (values, "Detune", "0"); - inst.lowNote = getValue8 (values, "LowNote", "0"); - inst.highNote = getValue8 (values, "HighNote", "127"); - inst.lowVelocity = getValue8 (values, "LowVelocity", "1"); - inst.highVelocity = getValue8 (values, "HighVelocity", "127"); - inst.gain = (int16) getValue16 (values, "Gain", "0"); - - inst.sustainLoop.type = getValue16 (values, "Loop0Type", "0"); - inst.sustainLoop.startIdentifier = getValue16 (values, "Loop0StartIdentifier", "0"); - inst.sustainLoop.endIdentifier = getValue16 (values, "Loop0EndIdentifier", "0"); - inst.releaseLoop.type = getValue16 (values, "Loop1Type", "0"); - inst.releaseLoop.startIdentifier = getValue16 (values, "Loop1StartIdentifier", "0"); - inst.releaseLoop.endIdentifier = getValue16 (values, "Loop1EndIdentifier", "0"); - } - } - - } JUCE_PACKED; - - //============================================================================== - struct BASCChunk - { - enum Key - { - minor = 1, - major = 2, - neither = 3, - both = 4 - }; - - BASCChunk (InputStream& input) - { - zerostruct (*this); - - flags = (uint32) input.readIntBigEndian(); - numBeats = (uint32) input.readIntBigEndian(); - rootNote = (uint16) input.readShortBigEndian(); - key = (uint16) input.readShortBigEndian(); - timeSigNum = (uint16) input.readShortBigEndian(); - timeSigDen = (uint16) input.readShortBigEndian(); - oneShot = (uint16) input.readShortBigEndian(); - input.read (unknown, sizeof (unknown)); - } - - void addToMetadata (StringPairArray& metadata) const - { - const bool rootNoteSet = rootNote != 0; - - setBoolFlag (metadata, AiffAudioFormat::appleOneShot, oneShot == 2); - setBoolFlag (metadata, AiffAudioFormat::appleRootSet, rootNoteSet); - - if (rootNoteSet) - metadata.set (AiffAudioFormat::appleRootNote, String (rootNote)); - - metadata.set (AiffAudioFormat::appleBeats, String (numBeats)); - metadata.set (AiffAudioFormat::appleDenominator, String (timeSigDen)); - metadata.set (AiffAudioFormat::appleNumerator, String (timeSigNum)); - - const char* keyString = nullptr; - - switch (key) - { - case minor: keyString = "major"; break; - case major: keyString = "major"; break; - case neither: keyString = "neither"; break; - case both: keyString = "both"; break; - } - - if (keyString != nullptr) - metadata.set (AiffAudioFormat::appleKey, keyString); - } - - void setBoolFlag (StringPairArray& values, const char* name, bool shouldBeSet) const - { - values.set (name, shouldBeSet ? "1" : "0"); - } - - uint32 flags; - uint32 numBeats; - uint16 rootNote; - uint16 key; - uint16 timeSigNum; - uint16 timeSigDen; - uint16 oneShot; - uint8 unknown[66]; - } JUCE_PACKED; - - #if JUCE_MSVC - #pragma pack (pop) - #endif - - //============================================================================== - static String readCATEChunk (InputStream& input, const uint32 length) - { - MemoryBlock mb; - input.skipNextBytes (4); - input.readIntoMemoryBlock (mb, (ssize_t) length - 4); - - static const char* appleGenres[] = - { - "Rock/Blues", - "Electronic/Dance", - "Jazz", - "Urban", - "World/Ethnic", - "Cinematic/New Age", - "Orchestral", - "Country/Folk", - "Experimental", - "Other Genre", - nullptr - }; - - const StringArray genres (appleGenres); - StringArray tagsArray; - - int bytesLeft = (int) mb.getSize(); - const char* data = static_cast (mb.getData()); - - while (bytesLeft > 0) - { - const String tag (CharPointer_UTF8 (data), - CharPointer_UTF8 (data + bytesLeft)); - - if (tag.isNotEmpty()) - tagsArray.add (data); - - const int numBytesInTag = genres.contains (tag) ? 118 : 50; - data += numBytesInTag; - bytesLeft -= numBytesInTag; - } - - return tagsArray.joinIntoString (";"); - } - - //============================================================================== - namespace MarkChunk - { - static bool metaDataContainsZeroIdentifiers (const StringPairArray& values) - { - // (zero cue identifiers are valid for WAV but not for AIFF) - const String cueString ("Cue"); - const String noteString ("CueNote"); - const String identifierString ("Identifier"); - - const StringArray& keys = values.getAllKeys(); - - for (int i = 0; i < keys.size(); ++i) - { - const String key (keys[i]); - - if (key.startsWith (noteString)) - continue; // zero identifier IS valid in a COMT chunk - - if (key.startsWith (cueString) && key.contains (identifierString)) - { - const int value = values.getValue (key, "-1").getIntValue(); - - if (value == 0) - return true; - } - } - - return false; - } - - static void create (MemoryBlock& block, const StringPairArray& values) - { - const int numCues = values.getValue ("NumCuePoints", "0").getIntValue(); - - if (numCues > 0) - { - MemoryOutputStream out (block, false); - - out.writeShortBigEndian ((short) numCues); - - const int numCueLabels = values.getValue ("NumCueLabels", "0").getIntValue(); - const int idOffset = metaDataContainsZeroIdentifiers (values) ? 1 : 0; // can't have zero IDs in AIFF - - #if JUCE_DEBUG - Array identifiers; - #endif - - for (int i = 0; i < numCues; ++i) - { - const String prefixCue ("Cue" + String (i)); - const int identifier = idOffset + values.getValue (prefixCue + "Identifier", "1").getIntValue(); - - #if JUCE_DEBUG - jassert (! identifiers.contains (identifier)); - identifiers.add (identifier); - #endif - - const int offset = values.getValue (prefixCue + "Offset", "0").getIntValue(); - String label ("CueLabel" + String (i)); - - for (int labelIndex = 0; labelIndex < numCueLabels; ++labelIndex) - { - const String prefixLabel ("CueLabel" + String (labelIndex)); - const int labelIdentifier = idOffset + values.getValue (prefixLabel + "Identifier", "1").getIntValue(); - - if (labelIdentifier == identifier) - { - label = values.getValue (prefixLabel + "Text", label); - break; - } - } - - out.writeShortBigEndian ((short) identifier); - out.writeIntBigEndian (offset); - - const size_t labelLength = jmin ((size_t) 254, label.getNumBytesAsUTF8()); // seems to need null terminator even though it's a pstring - out.writeByte ((char) labelLength + 1); - out.write (label.toUTF8(), labelLength); - out.writeByte (0); - } - - if ((out.getDataSize() & 1) != 0) - out.writeByte (0); - } - } - } - - //============================================================================== - namespace COMTChunk - { - static void create (MemoryBlock& block, const StringPairArray& values) - { - const int numNotes = values.getValue ("NumCueNotes", "0").getIntValue(); - - if (numNotes > 0) - { - MemoryOutputStream out (block, false); - out.writeShortBigEndian ((short) numNotes); - - for (int i = 0; i < numNotes; ++i) - { - const String prefix ("CueNote" + String (i)); - - out.writeIntBigEndian (values.getValue (prefix + "TimeStamp", "0").getIntValue()); - out.writeShortBigEndian ((short) values.getValue (prefix + "Identifier", "0").getIntValue()); - - const String comment (values.getValue (prefix + "Text", String())); - - const size_t commentLength = jmin (comment.getNumBytesAsUTF8(), (size_t) 65534); - out.writeShortBigEndian ((short) commentLength + 1); - out.write (comment.toUTF8(), commentLength); - out.writeByte (0); - - if ((out.getDataSize() & 1) != 0) - out.writeByte (0); - } - } - } - } -} - -//============================================================================== -class AiffAudioFormatReader : public AudioFormatReader -{ -public: - AiffAudioFormatReader (InputStream* in) - : AudioFormatReader (in, aiffFormatName) - { - using namespace AiffFileHelpers; - - if (input->readInt() == chunkName ("FORM")) - { - const int len = input->readIntBigEndian(); - const int64 end = input->getPosition() + len; - - const int nextType = input->readInt(); - if (nextType == chunkName ("AIFF") || nextType == chunkName ("AIFC")) - { - bool hasGotVer = false; - bool hasGotData = false; - bool hasGotType = false; - - while (input->getPosition() < end) - { - const int type = input->readInt(); - const uint32 length = (uint32) input->readIntBigEndian(); - const int64 chunkEnd = input->getPosition() + length; - - if (type == chunkName ("FVER")) - { - hasGotVer = true; - - const int ver = input->readIntBigEndian(); - if (ver != 0 && ver != (int) 0xa2805140) - break; - } - else if (type == chunkName ("COMM")) - { - hasGotType = true; - - numChannels = (unsigned int) input->readShortBigEndian(); - lengthInSamples = input->readIntBigEndian(); - bitsPerSample = (unsigned int) input->readShortBigEndian(); - bytesPerFrame = (int) ((numChannels * bitsPerSample) >> 3); - - unsigned char sampleRateBytes[10]; - input->read (sampleRateBytes, 10); - const int byte0 = sampleRateBytes[0]; - - if ((byte0 & 0x80) != 0 - || byte0 <= 0x3F || byte0 > 0x40 - || (byte0 == 0x40 && sampleRateBytes[1] > 0x1C)) - break; - - unsigned int sampRate = ByteOrder::bigEndianInt (sampleRateBytes + 2); - sampRate >>= (16414 - ByteOrder::bigEndianShort (sampleRateBytes)); - sampleRate = (int) sampRate; - - if (length <= 18) - { - // some types don't have a chunk large enough to include a compression - // type, so assume it's just big-endian pcm - littleEndian = false; - } - else - { - const int compType = input->readInt(); - - if (compType == chunkName ("NONE") || compType == chunkName ("twos")) - { - littleEndian = false; - } - else if (compType == chunkName ("sowt")) - { - littleEndian = true; - } - else if (compType == chunkName ("fl32") || compType == chunkName ("FL32")) - { - littleEndian = false; - usesFloatingPointData = true; - } - else - { - sampleRate = 0; - break; - } - } - } - else if (type == chunkName ("SSND")) - { - hasGotData = true; - - const int offset = input->readIntBigEndian(); - dataChunkStart = input->getPosition() + 4 + offset; - lengthInSamples = (bytesPerFrame > 0) ? jmin (lengthInSamples, ((int64) length) / (int64) bytesPerFrame) : 0; - } - else if (type == chunkName ("MARK")) - { - const uint16 numCues = (uint16) input->readShortBigEndian(); - - // these two are always the same for AIFF-read files - metadataValues.set ("NumCuePoints", String (numCues)); - metadataValues.set ("NumCueLabels", String (numCues)); - - for (uint16 i = 0; i < numCues; ++i) - { - uint16 identifier = (uint16) input->readShortBigEndian(); - uint32 offset = (uint32) input->readIntBigEndian(); - uint8 stringLength = (uint8) input->readByte(); - MemoryBlock textBlock; - input->readIntoMemoryBlock (textBlock, stringLength); - - // if the stringLength is even then read one more byte as the - // string needs to be an even number of bytes INCLUDING the - // leading length character in the pascal string - if ((stringLength & 1) == 0) - input->readByte(); - - const String prefixCue ("Cue" + String (i)); - metadataValues.set (prefixCue + "Identifier", String (identifier)); - metadataValues.set (prefixCue + "Offset", String (offset)); - - const String prefixLabel ("CueLabel" + String (i)); - metadataValues.set (prefixLabel + "Identifier", String (identifier)); - metadataValues.set (prefixLabel + "Text", textBlock.toString()); - } - } - else if (type == chunkName ("COMT")) - { - const uint16 numNotes = (uint16) input->readShortBigEndian(); - metadataValues.set ("NumCueNotes", String (numNotes)); - - for (uint16 i = 0; i < numNotes; ++i) - { - uint32 timestamp = (uint32) input->readIntBigEndian(); - uint16 identifier = (uint16) input->readShortBigEndian(); // may be zero in this case - uint16 stringLength = (uint16) input->readShortBigEndian(); - - MemoryBlock textBlock; - input->readIntoMemoryBlock (textBlock, stringLength + (stringLength & 1)); - - const String prefix ("CueNote" + String (i)); - metadataValues.set (prefix + "TimeStamp", String (timestamp)); - metadataValues.set (prefix + "Identifier", String (identifier)); - metadataValues.set (prefix + "Text", textBlock.toString()); - } - } - else if (type == chunkName ("INST")) - { - HeapBlock inst; - inst.calloc (jmax ((size_t) length + 1, sizeof (InstChunk)), 1); - input->read (inst, (int) length); - inst->copyTo (metadataValues); - } - else if (type == chunkName ("basc")) - { - AiffFileHelpers::BASCChunk (*input).addToMetadata (metadataValues); - } - else if (type == chunkName ("cate")) - { - metadataValues.set (AiffAudioFormat::appleTag, - AiffFileHelpers::readCATEChunk (*input, length));; - } - else if ((hasGotVer && hasGotData && hasGotType) - || chunkEnd < input->getPosition() - || input->isExhausted()) - { - break; - } - - input->setPosition (chunkEnd + (chunkEnd & 1)); // (chunks should be aligned to an even byte address) - } - } - } - - if (metadataValues.size() > 0) - metadataValues.set ("MetaDataSource", "AIFF"); - } - - //============================================================================== - bool readSamples (int** destSamples, int numDestChannels, int startOffsetInDestBuffer, - int64 startSampleInFile, int numSamples) override - { - clearSamplesBeyondAvailableLength (destSamples, numDestChannels, startOffsetInDestBuffer, - startSampleInFile, numSamples, lengthInSamples); - - if (numSamples <= 0) - return true; - - input->setPosition (dataChunkStart + startSampleInFile * bytesPerFrame); - - while (numSamples > 0) - { - const int tempBufSize = 480 * 3 * 4; // (keep this a multiple of 3) - char tempBuffer [tempBufSize]; - - const int numThisTime = jmin (tempBufSize / bytesPerFrame, numSamples); - const int bytesRead = input->read (tempBuffer, numThisTime * bytesPerFrame); - - if (bytesRead < numThisTime * bytesPerFrame) - { - jassert (bytesRead >= 0); - zeromem (tempBuffer + bytesRead, (size_t) (numThisTime * bytesPerFrame - bytesRead)); - } - - if (littleEndian) - copySampleData (bitsPerSample, usesFloatingPointData, - destSamples, startOffsetInDestBuffer, numDestChannels, - tempBuffer, (int) numChannels, numThisTime); - else - copySampleData (bitsPerSample, usesFloatingPointData, - destSamples, startOffsetInDestBuffer, numDestChannels, - tempBuffer, (int) numChannels, numThisTime); - - startOffsetInDestBuffer += numThisTime; - numSamples -= numThisTime; - } - - return true; - } - - template - static void copySampleData (unsigned int bitsPerSample, const bool usesFloatingPointData, - int* const* destSamples, int startOffsetInDestBuffer, int numDestChannels, - const void* sourceData, int numChannels, int numSamples) noexcept - { - switch (bitsPerSample) - { - case 8: ReadHelper::read (destSamples, startOffsetInDestBuffer, numDestChannels, sourceData, numChannels, numSamples); break; - case 16: ReadHelper::read (destSamples, startOffsetInDestBuffer, numDestChannels, sourceData, numChannels, numSamples); break; - case 24: ReadHelper::read (destSamples, startOffsetInDestBuffer, numDestChannels, sourceData, numChannels, numSamples); break; - case 32: if (usesFloatingPointData) ReadHelper::read (destSamples, startOffsetInDestBuffer, numDestChannels, sourceData, numChannels, numSamples); - else ReadHelper::read (destSamples, startOffsetInDestBuffer, numDestChannels, sourceData, numChannels, numSamples); break; - default: jassertfalse; break; - } - } - - int bytesPerFrame; - int64 dataChunkStart; - bool littleEndian; - -private: - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AiffAudioFormatReader) -}; - -//============================================================================== -class AiffAudioFormatWriter : public AudioFormatWriter -{ -public: - AiffAudioFormatWriter (OutputStream* out, double rate, - unsigned int numChans, unsigned int bits, - const StringPairArray& metadataValues) - : AudioFormatWriter (out, aiffFormatName, rate, numChans, bits), - lengthInSamples (0), - bytesWritten (0), - writeFailed (false) - { - using namespace AiffFileHelpers; - - if (metadataValues.size() > 0) - { - // The meta data should have been santised for the AIFF format. - // If it was originally sourced from a WAV file the MetaDataSource - // key should be removed (or set to "AIFF") once this has been done - jassert (metadataValues.getValue ("MetaDataSource", "None") != "WAV"); - - MarkChunk::create (markChunk, metadataValues); - COMTChunk::create (comtChunk, metadataValues); - InstChunk::create (instChunk, metadataValues); - } - - headerPosition = out->getPosition(); - writeHeader(); - } - - ~AiffAudioFormatWriter() - { - if ((bytesWritten & 1) != 0) - output->writeByte (0); - - writeHeader(); - } - - //============================================================================== - bool write (const int** data, int numSamples) override - { - jassert (data != nullptr && *data != nullptr); // the input must contain at least one channel! - - if (writeFailed) - return false; - - const size_t bytes = (size_t) numSamples * numChannels * bitsPerSample / 8; - tempBlock.ensureSize ((size_t) bytes, false); - - switch (bitsPerSample) - { - case 8: WriteHelper::write (tempBlock.getData(), (int) numChannels, data, numSamples); break; - case 16: WriteHelper::write (tempBlock.getData(), (int) numChannels, data, numSamples); break; - case 24: WriteHelper::write (tempBlock.getData(), (int) numChannels, data, numSamples); break; - case 32: WriteHelper::write (tempBlock.getData(), (int) numChannels, data, numSamples); break; - default: jassertfalse; break; - } - - if (bytesWritten + bytes >= (size_t) 0xfff00000 - || ! output->write (tempBlock.getData(), bytes)) - { - // failed to write to disk, so let's try writing the header. - // If it's just run out of disk space, then if it does manage - // to write the header, we'll still have a useable file.. - writeHeader(); - writeFailed = true; - return false; - } - else - { - bytesWritten += bytes; - lengthInSamples += (uint64) numSamples; - - return true; - } - } - -private: - MemoryBlock tempBlock, markChunk, comtChunk, instChunk; - uint64 lengthInSamples, bytesWritten; - int64 headerPosition; - bool writeFailed; - - void writeHeader() - { - using namespace AiffFileHelpers; - - const bool couldSeekOk = output->setPosition (headerPosition); - (void) couldSeekOk; - - // if this fails, you've given it an output stream that can't seek! It needs - // to be able to seek back to write the header - jassert (couldSeekOk); - - const int headerLen = (int) (54 + (markChunk.getSize() > 0 ? markChunk.getSize() + 8 : 0) - + (comtChunk.getSize() > 0 ? comtChunk.getSize() + 8 : 0) - + (instChunk.getSize() > 0 ? instChunk.getSize() + 8 : 0)); - int audioBytes = (int) (lengthInSamples * ((bitsPerSample * numChannels) / 8)); - audioBytes += (audioBytes & 1); - - output->writeInt (chunkName ("FORM")); - output->writeIntBigEndian (headerLen + audioBytes - 8); - output->writeInt (chunkName ("AIFF")); - output->writeInt (chunkName ("COMM")); - output->writeIntBigEndian (18); - output->writeShortBigEndian ((short) numChannels); - output->writeIntBigEndian ((int) lengthInSamples); - output->writeShortBigEndian ((short) bitsPerSample); - - uint8 sampleRateBytes[10] = { 0 }; - - if (sampleRate <= 1) - { - sampleRateBytes[0] = 0x3f; - sampleRateBytes[1] = 0xff; - sampleRateBytes[2] = 0x80; - } - else - { - int mask = 0x40000000; - sampleRateBytes[0] = 0x40; - - if (sampleRate >= mask) - { - jassertfalse; - sampleRateBytes[1] = 0x1d; - } - else - { - int n = (int) sampleRate; - - int i; - for (i = 0; i <= 32 ; ++i) - { - if ((n & mask) != 0) - break; - - mask >>= 1; - } - - n = n << (i + 1); - - sampleRateBytes[1] = (uint8) (29 - i); - sampleRateBytes[2] = (uint8) ((n >> 24) & 0xff); - sampleRateBytes[3] = (uint8) ((n >> 16) & 0xff); - sampleRateBytes[4] = (uint8) ((n >> 8) & 0xff); - sampleRateBytes[5] = (uint8) (n & 0xff); - } - } - - output->write (sampleRateBytes, 10); - - if (markChunk.getSize() > 0) - { - output->writeInt (chunkName ("MARK")); - output->writeIntBigEndian ((int) markChunk.getSize()); - *output << markChunk; - } - - if (comtChunk.getSize() > 0) - { - output->writeInt (chunkName ("COMT")); - output->writeIntBigEndian ((int) comtChunk.getSize()); - *output << comtChunk; - } - - if (instChunk.getSize() > 0) - { - output->writeInt (chunkName ("INST")); - output->writeIntBigEndian ((int) instChunk.getSize()); - *output << instChunk; - } - - output->writeInt (chunkName ("SSND")); - output->writeIntBigEndian (audioBytes + 8); - output->writeInt (0); - output->writeInt (0); - - jassert (output->getPosition() == headerLen); - } - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AiffAudioFormatWriter) -}; - -//============================================================================== -class MemoryMappedAiffReader : public MemoryMappedAudioFormatReader -{ -public: - MemoryMappedAiffReader (const File& f, const AiffAudioFormatReader& reader) - : MemoryMappedAudioFormatReader (f, reader, reader.dataChunkStart, - reader.bytesPerFrame * reader.lengthInSamples, reader.bytesPerFrame), - littleEndian (reader.littleEndian) - { - } - - bool readSamples (int** destSamples, int numDestChannels, int startOffsetInDestBuffer, - int64 startSampleInFile, int numSamples) override - { - clearSamplesBeyondAvailableLength (destSamples, numDestChannels, startOffsetInDestBuffer, - startSampleInFile, numSamples, lengthInSamples); - - if (map == nullptr || ! mappedSection.contains (Range (startSampleInFile, startSampleInFile + numSamples))) - { - jassertfalse; // you must make sure that the window contains all the samples you're going to attempt to read. - return false; - } - - if (littleEndian) - AiffAudioFormatReader::copySampleData - (bitsPerSample, usesFloatingPointData, destSamples, startOffsetInDestBuffer, - numDestChannels, sampleToPointer (startSampleInFile), (int) numChannels, numSamples); - else - AiffAudioFormatReader::copySampleData - (bitsPerSample, usesFloatingPointData, destSamples, startOffsetInDestBuffer, - numDestChannels, sampleToPointer (startSampleInFile), (int) numChannels, numSamples); - - return true; - } - - void readMaxLevels (int64 startSampleInFile, int64 numSamples, - float& min0, float& max0, float& min1, float& max1) - { - if (numSamples <= 0) - { - min0 = max0 = min1 = max1 = 0; - return; - } - - if (map == nullptr || ! mappedSection.contains (Range (startSampleInFile, startSampleInFile + numSamples))) - { - jassertfalse; // you must make sure that the window contains all the samples you're going to attempt to read. - - min0 = max0 = min1 = max1 = 0; - return; - } - - switch (bitsPerSample) - { - case 8: scanMinAndMax (startSampleInFile, numSamples, min0, max0, min1, max1); break; - case 16: scanMinAndMax (startSampleInFile, numSamples, min0, max0, min1, max1); break; - case 24: scanMinAndMax (startSampleInFile, numSamples, min0, max0, min1, max1); break; - case 32: if (usesFloatingPointData) scanMinAndMax (startSampleInFile, numSamples, min0, max0, min1, max1); - else scanMinAndMax (startSampleInFile, numSamples, min0, max0, min1, max1); break; - default: jassertfalse; break; - } - } - -private: - const bool littleEndian; - - template - void scanMinAndMax (int64 startSampleInFile, int64 numSamples, - float& min0, float& max0, float& min1, float& max1) const noexcept - { - scanMinAndMax2 (0, startSampleInFile, numSamples, min0, max0); - - if (numChannels > 1) - scanMinAndMax2 (1, startSampleInFile, numSamples, min1, max1); - else - min1 = max1 = 0; - } - - template - void scanMinAndMax2 (int channel, int64 startSampleInFile, int64 numSamples, float& mn, float& mx) const noexcept - { - if (littleEndian) - scanMinAndMaxInterleaved (channel, startSampleInFile, numSamples, mn, mx); - else - scanMinAndMaxInterleaved (channel, startSampleInFile, numSamples, mn, mx); - } - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MemoryMappedAiffReader) -}; - -//============================================================================== -AiffAudioFormat::AiffAudioFormat() : AudioFormat (aiffFormatName, ".aiff .aif") -{ -} - -AiffAudioFormat::~AiffAudioFormat() -{ -} - -Array AiffAudioFormat::getPossibleSampleRates() -{ - const int rates[] = { 22050, 32000, 44100, 48000, 88200, 96000, 176400, 192000, 0 }; - return Array (rates); -} - -Array AiffAudioFormat::getPossibleBitDepths() -{ - const int depths[] = { 8, 16, 24, 0 }; - return Array (depths); -} - -bool AiffAudioFormat::canDoStereo() { return true; } -bool AiffAudioFormat::canDoMono() { return true; } - -#if JUCE_MAC -bool AiffAudioFormat::canHandleFile (const File& f) -{ - if (AudioFormat::canHandleFile (f)) - return true; - - const OSType type = f.getMacOSType(); - - // (NB: written as hex to avoid four-char-constant warnings) - return type == 0x41494646 /* AIFF */ || type == 0x41494643 /* AIFC */ - || type == 0x61696666 /* aiff */ || type == 0x61696663 /* aifc */; -} -#endif - -AudioFormatReader* AiffAudioFormat::createReaderFor (InputStream* sourceStream, const bool deleteStreamIfOpeningFails) -{ - ScopedPointer w (new AiffAudioFormatReader (sourceStream)); - - if (w->sampleRate > 0 && w->numChannels > 0) - return w.release(); - - if (! deleteStreamIfOpeningFails) - w->input = nullptr; - - return nullptr; -} - -MemoryMappedAudioFormatReader* AiffAudioFormat::createMemoryMappedReader (const File& file) -{ - if (FileInputStream* fin = file.createInputStream()) - { - AiffAudioFormatReader reader (fin); - - if (reader.lengthInSamples > 0) - return new MemoryMappedAiffReader (file, reader); - } - - return nullptr; -} - -AudioFormatWriter* AiffAudioFormat::createWriterFor (OutputStream* out, - double sampleRate, - unsigned int numberOfChannels, - int bitsPerSample, - const StringPairArray& metadataValues, - int /*qualityOptionIndex*/) -{ - if (getPossibleBitDepths().contains (bitsPerSample)) - return new AiffAudioFormatWriter (out, sampleRate, numberOfChannels, (unsigned int) bitsPerSample, metadataValues); - - return nullptr; -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/codecs/juce_AiffAudioFormat.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/codecs/juce_AiffAudioFormat.h deleted file mode 100644 index 01d1484b43..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/codecs/juce_AiffAudioFormat.h +++ /dev/null @@ -1,84 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -//============================================================================== -/** - Reads and Writes AIFF format audio files. - - @see AudioFormat -*/ -class JUCE_API AiffAudioFormat : public AudioFormat -{ -public: - //============================================================================== - /** Creates an format object. */ - AiffAudioFormat(); - - /** Destructor. */ - ~AiffAudioFormat(); - - //============================================================================== - /** Metadata property name used when reading a aiff file with a basc chunk. */ - static const char* const appleOneShot; - /** Metadata property name used when reading a aiff file with a basc chunk. */ - static const char* const appleRootSet; - /** Metadata property name used when reading a aiff file with a basc chunk. */ - static const char* const appleRootNote; - /** Metadata property name used when reading a aiff file with a basc chunk. */ - static const char* const appleBeats; - /** Metadata property name used when reading a aiff file with a basc chunk. */ - static const char* const appleDenominator; - /** Metadata property name used when reading a aiff file with a basc chunk. */ - static const char* const appleNumerator; - /** Metadata property name used when reading a aiff file with a basc chunk. */ - static const char* const appleTag; - /** Metadata property name used when reading a aiff file with a basc chunk. */ - static const char* const appleKey; - - //============================================================================== - Array getPossibleSampleRates() override; - Array getPossibleBitDepths() override; - bool canDoStereo() override; - bool canDoMono() override; - - #if JUCE_MAC - bool canHandleFile (const File& fileToTest) override; - #endif - - //============================================================================== - AudioFormatReader* createReaderFor (InputStream* sourceStream, - bool deleteStreamIfOpeningFails) override; - - MemoryMappedAudioFormatReader* createMemoryMappedReader (const File&) override; - - AudioFormatWriter* createWriterFor (OutputStream* streamToWriteTo, - double sampleRateToUse, - unsigned int numberOfChannels, - int bitsPerSample, - const StringPairArray& metadataValues, - int qualityOptionIndex) override; - -private: - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(AiffAudioFormat) -}; diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/codecs/juce_CoreAudioFormat.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/codecs/juce_CoreAudioFormat.cpp deleted file mode 100644 index 6d3aafa1c8..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/codecs/juce_CoreAudioFormat.cpp +++ /dev/null @@ -1,528 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#if JUCE_MAC || JUCE_IOS - -//============================================================================== -namespace -{ - const char* const coreAudioFormatName = "CoreAudio supported file"; - - StringArray findFileExtensionsForCoreAudioCodecs() - { - StringArray extensionsArray; - CFArrayRef extensions = nullptr; - UInt32 sizeOfArray = sizeof (extensions); - - if (AudioFileGetGlobalInfo (kAudioFileGlobalInfo_AllExtensions, 0, 0, &sizeOfArray, &extensions) == noErr) - { - const CFIndex numValues = CFArrayGetCount (extensions); - - for (CFIndex i = 0; i < numValues; ++i) - extensionsArray.add ("." + String::fromCFString ((CFStringRef) CFArrayGetValueAtIndex (extensions, i))); - - CFRelease (extensions); - } - - return extensionsArray; - } -} - -//============================================================================== -const char* const CoreAudioFormat::midiDataBase64 = "midiDataBase64"; -const char* const CoreAudioFormat::tempo = "tempo"; -const char* const CoreAudioFormat::timeSig = "time signature"; -const char* const CoreAudioFormat::keySig = "key signature"; - -//============================================================================== -struct CoreAudioFormatMetatdata -{ - static uint32 chunkName (const char* const name) noexcept { return ByteOrder::bigEndianInt (name); } - - //============================================================================== - struct FileHeader - { - FileHeader (InputStream& input) - { - fileType = (uint32) input.readIntBigEndian(); - fileVersion = (uint16) input.readShortBigEndian(); - fileFlags = (uint16) input.readShortBigEndian(); - } - - uint32 fileType; - uint16 fileVersion; - uint16 fileFlags; - }; - - //============================================================================== - struct ChunkHeader - { - ChunkHeader (InputStream& input) - { - chunkType = (uint32) input.readIntBigEndian(); - chunkSize = (int64) input.readInt64BigEndian(); - } - - uint32 chunkType; - int64 chunkSize; - }; - - //============================================================================== - struct AudioDescriptionChunk - { - AudioDescriptionChunk (InputStream& input) - { - sampleRate = input.readDoubleBigEndian(); - formatID = (uint32) input.readIntBigEndian(); - formatFlags = (uint32) input.readIntBigEndian(); - bytesPerPacket = (uint32) input.readIntBigEndian(); - framesPerPacket = (uint32) input.readIntBigEndian(); - channelsPerFrame = (uint32) input.readIntBigEndian(); - bitsPerChannel = (uint32) input.readIntBigEndian(); - } - - double sampleRate; - uint32 formatID; - uint32 formatFlags; - uint32 bytesPerPacket; - uint32 framesPerPacket; - uint32 channelsPerFrame; - uint32 bitsPerChannel; - }; - - //============================================================================== - struct UserDefinedChunk - { - UserDefinedChunk (InputStream& input, int64 size) - { - // a user defined chunk contains 16 bytes of a UUID first - uuid[1] = input.readInt64BigEndian(); - uuid[0] = input.readInt64BigEndian(); - - input.skipNextBytes (size - 16); - } - - int64 uuid[2]; - }; - - //============================================================================== - static StringPairArray parseMidiChunk (InputStream& input, int64 size) - { - const int64 originalPosition = input.getPosition(); - - MemoryBlock midiBlock; - input.readIntoMemoryBlock (midiBlock, (ssize_t) size); - MemoryInputStream midiInputStream (midiBlock, false); - - StringPairArray midiMetadata; - MidiFile midiFile; - - if (midiFile.readFrom (midiInputStream)) - { - midiMetadata.set (CoreAudioFormat::midiDataBase64, midiBlock.toBase64Encoding()); - - findTempoEvents (midiFile, midiMetadata); - findTimeSigEvents (midiFile, midiMetadata); - findKeySigEvents (midiFile, midiMetadata); - } - - input.setPosition (originalPosition + size); - return midiMetadata; - } - - static void findTempoEvents (MidiFile& midiFile, StringPairArray& midiMetadata) - { - MidiMessageSequence tempoEvents; - midiFile.findAllTempoEvents (tempoEvents); - - const int numTempoEvents = tempoEvents.getNumEvents(); - MemoryOutputStream tempoSequence; - - for (int i = 0; i < numTempoEvents; ++i) - { - const double tempo = getTempoFromTempoMetaEvent (tempoEvents.getEventPointer (i)); - - if (tempo > 0.0) - { - if (i == 0) - midiMetadata.set (CoreAudioFormat::tempo, String (tempo)); - - if (numTempoEvents > 1) - tempoSequence << String (tempo) << ',' << tempoEvents.getEventTime (i) << ';'; - } - } - - if (tempoSequence.getDataSize() > 0) - midiMetadata.set ("tempo sequence", tempoSequence.toUTF8()); - } - - static double getTempoFromTempoMetaEvent (MidiMessageSequence::MidiEventHolder* holder) - { - if (holder != nullptr) - { - const MidiMessage& midiMessage = holder->message; - - if (midiMessage.isTempoMetaEvent()) - { - const double tempoSecondsPerQuarterNote = midiMessage.getTempoSecondsPerQuarterNote(); - - if (tempoSecondsPerQuarterNote > 0.0) - return 60.0 / tempoSecondsPerQuarterNote; - } - } - - return 0.0; - } - - static void findTimeSigEvents (MidiFile& midiFile, StringPairArray& midiMetadata) - { - MidiMessageSequence timeSigEvents; - midiFile.findAllTimeSigEvents (timeSigEvents); - const int numTimeSigEvents = timeSigEvents.getNumEvents(); - - MemoryOutputStream timeSigSequence; - - for (int i = 0; i < numTimeSigEvents; ++i) - { - int numerator, denominator; - timeSigEvents.getEventPointer(i)->message.getTimeSignatureInfo (numerator, denominator); - - String timeSigString; - timeSigString << numerator << '/' << denominator; - - if (i == 0) - midiMetadata.set (CoreAudioFormat::timeSig, timeSigString); - - if (numTimeSigEvents > 1) - timeSigSequence << timeSigString << ',' << timeSigEvents.getEventTime (i) << ';'; - } - - if (timeSigSequence.getDataSize() > 0) - midiMetadata.set ("time signature sequence", timeSigSequence.toUTF8()); - } - - static void findKeySigEvents (MidiFile& midiFile, StringPairArray& midiMetadata) - { - MidiMessageSequence keySigEvents; - midiFile.findAllKeySigEvents (keySigEvents); - const int numKeySigEvents = keySigEvents.getNumEvents(); - - MemoryOutputStream keySigSequence; - - for (int i = 0; i < numKeySigEvents; ++i) - { - const MidiMessage& message (keySigEvents.getEventPointer (i)->message); - const int key = jlimit (0, 14, message.getKeySignatureNumberOfSharpsOrFlats() + 7); - const bool isMajor = message.isKeySignatureMajorKey(); - - static const char* majorKeys[] = { "Cb", "Gb", "Db", "Ab", "Eb", "Bb", "F", "C", "G", "D", "A", "E", "B", "F#", "C#" }; - static const char* minorKeys[] = { "Ab", "Eb", "Bb", "F", "C", "G", "D", "A", "E", "B", "F#", "C#", "G#", "D#", "A#" }; - - String keySigString (isMajor ? majorKeys[key] - : minorKeys[key]); - - if (! isMajor) - keySigString << 'm'; - - if (i == 0) - midiMetadata.set (CoreAudioFormat::keySig, keySigString); - - if (numKeySigEvents > 1) - keySigSequence << keySigString << ',' << keySigEvents.getEventTime (i) << ';'; - } - - if (keySigSequence.getDataSize() > 0) - midiMetadata.set ("key signature sequence", keySigSequence.toUTF8()); - } - - //============================================================================== - static StringPairArray parseInformationChunk (InputStream& input) - { - StringPairArray infoStrings; - const uint32 numEntries = (uint32) input.readIntBigEndian(); - - for (uint32 i = 0; i < numEntries; ++i) - infoStrings.set (input.readString(), input.readString()); - - return infoStrings; - } - - //============================================================================== - static bool read (InputStream& input, StringPairArray& metadataValues) - { - const int64 originalPos = input.getPosition(); - - const FileHeader cafFileHeader (input); - const bool isCafFile = cafFileHeader.fileType == chunkName ("caff"); - - if (isCafFile) - { - while (! input.isExhausted()) - { - const ChunkHeader chunkHeader (input); - - if (chunkHeader.chunkType == chunkName ("desc")) - { - AudioDescriptionChunk audioDescriptionChunk (input); - } - else if (chunkHeader.chunkType == chunkName ("uuid")) - { - UserDefinedChunk userDefinedChunk (input, chunkHeader.chunkSize); - } - else if (chunkHeader.chunkType == chunkName ("data")) - { - // -1 signifies an unknown data size so the data has to be at the - // end of the file so we must have finished the header - - if (chunkHeader.chunkSize == -1) - break; - - input.skipNextBytes (chunkHeader.chunkSize); - } - else if (chunkHeader.chunkType == chunkName ("midi")) - { - metadataValues.addArray (parseMidiChunk (input, chunkHeader.chunkSize)); - } - else if (chunkHeader.chunkType == chunkName ("info")) - { - metadataValues.addArray (parseInformationChunk (input)); - } - else - { - // we aren't decoding this chunk yet so just skip over it - input.skipNextBytes (chunkHeader.chunkSize); - } - } - } - - input.setPosition (originalPos); - - return isCafFile; - } -}; - -//============================================================================== -class CoreAudioReader : public AudioFormatReader -{ -public: - CoreAudioReader (InputStream* const inp) - : AudioFormatReader (inp, coreAudioFormatName), - ok (false), lastReadPosition (0) - { - usesFloatingPointData = true; - bitsPerSample = 32; - - if (input != nullptr) - CoreAudioFormatMetatdata::read (*input, metadataValues); - - OSStatus status = AudioFileOpenWithCallbacks (this, - &readCallback, - nullptr, // write needs to be null to avoid permisisions errors - &getSizeCallback, - nullptr, // setSize needs to be null to avoid permisisions errors - 0, // AudioFileTypeID inFileTypeHint - &audioFileID); - if (status == noErr) - { - status = ExtAudioFileWrapAudioFileID (audioFileID, false, &audioFileRef); - - if (status == noErr) - { - AudioStreamBasicDescription sourceAudioFormat; - UInt32 audioStreamBasicDescriptionSize = sizeof (AudioStreamBasicDescription); - ExtAudioFileGetProperty (audioFileRef, - kExtAudioFileProperty_FileDataFormat, - &audioStreamBasicDescriptionSize, - &sourceAudioFormat); - - numChannels = sourceAudioFormat.mChannelsPerFrame; - sampleRate = sourceAudioFormat.mSampleRate; - - UInt32 sizeOfLengthProperty = sizeof (int64); - ExtAudioFileGetProperty (audioFileRef, - kExtAudioFileProperty_FileLengthFrames, - &sizeOfLengthProperty, - &lengthInSamples); - - destinationAudioFormat.mSampleRate = sampleRate; - destinationAudioFormat.mFormatID = kAudioFormatLinearPCM; - destinationAudioFormat.mFormatFlags = kLinearPCMFormatFlagIsFloat | kLinearPCMFormatFlagIsNonInterleaved | kAudioFormatFlagsNativeEndian; - destinationAudioFormat.mBitsPerChannel = sizeof (float) * 8; - destinationAudioFormat.mChannelsPerFrame = numChannels; - destinationAudioFormat.mBytesPerFrame = sizeof (float); - destinationAudioFormat.mFramesPerPacket = 1; - destinationAudioFormat.mBytesPerPacket = destinationAudioFormat.mFramesPerPacket * destinationAudioFormat.mBytesPerFrame; - - status = ExtAudioFileSetProperty (audioFileRef, - kExtAudioFileProperty_ClientDataFormat, - sizeof (AudioStreamBasicDescription), - &destinationAudioFormat); - if (status == noErr) - { - bufferList.malloc (1, sizeof (AudioBufferList) + numChannels * sizeof (AudioBuffer)); - bufferList->mNumberBuffers = numChannels; - ok = true; - } - } - } - } - - ~CoreAudioReader() - { - ExtAudioFileDispose (audioFileRef); - AudioFileClose (audioFileID); - } - - //============================================================================== - bool readSamples (int** destSamples, int numDestChannels, int startOffsetInDestBuffer, - int64 startSampleInFile, int numSamples) override - { - clearSamplesBeyondAvailableLength (destSamples, numDestChannels, startOffsetInDestBuffer, - startSampleInFile, numSamples, lengthInSamples); - - if (numSamples <= 0) - return true; - - if (lastReadPosition != startSampleInFile) - { - OSStatus status = ExtAudioFileSeek (audioFileRef, startSampleInFile); - if (status != noErr) - return false; - - lastReadPosition = startSampleInFile; - } - - while (numSamples > 0) - { - const int numThisTime = jmin (8192, numSamples); - const size_t numBytes = sizeof (float) * (size_t) numThisTime; - - audioDataBlock.ensureSize (numBytes * numChannels, false); - float* data = static_cast (audioDataBlock.getData()); - - for (int j = (int) numChannels; --j >= 0;) - { - bufferList->mBuffers[j].mNumberChannels = 1; - bufferList->mBuffers[j].mDataByteSize = (UInt32) numBytes; - bufferList->mBuffers[j].mData = data; - data += numThisTime; - } - - UInt32 numFramesToRead = (UInt32) numThisTime; - OSStatus status = ExtAudioFileRead (audioFileRef, &numFramesToRead, bufferList); - if (status != noErr) - return false; - - for (int i = numDestChannels; --i >= 0;) - { - if (destSamples[i] != nullptr) - { - if (i < (int) numChannels) - memcpy (destSamples[i] + startOffsetInDestBuffer, bufferList->mBuffers[i].mData, numBytes); - else - zeromem (destSamples[i] + startOffsetInDestBuffer, numBytes); - } - } - - startOffsetInDestBuffer += numThisTime; - numSamples -= numThisTime; - lastReadPosition += numThisTime; - } - - return true; - } - - bool ok; - -private: - AudioFileID audioFileID; - ExtAudioFileRef audioFileRef; - AudioStreamBasicDescription destinationAudioFormat; - MemoryBlock audioDataBlock; - HeapBlock bufferList; - int64 lastReadPosition; - - static SInt64 getSizeCallback (void* inClientData) - { - return static_cast (inClientData)->input->getTotalLength(); - } - - static OSStatus readCallback (void* inClientData, - SInt64 inPosition, - UInt32 requestCount, - void* buffer, - UInt32* actualCount) - { - CoreAudioReader* const reader = static_cast (inClientData); - - reader->input->setPosition (inPosition); - *actualCount = (UInt32) reader->input->read (buffer, (int) requestCount); - - return noErr; - } - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (CoreAudioReader) -}; - -//============================================================================== -CoreAudioFormat::CoreAudioFormat() - : AudioFormat (coreAudioFormatName, findFileExtensionsForCoreAudioCodecs()) -{ -} - -CoreAudioFormat::~CoreAudioFormat() {} - -Array CoreAudioFormat::getPossibleSampleRates() { return Array(); } -Array CoreAudioFormat::getPossibleBitDepths() { return Array(); } - -bool CoreAudioFormat::canDoStereo() { return true; } -bool CoreAudioFormat::canDoMono() { return true; } - -//============================================================================== -AudioFormatReader* CoreAudioFormat::createReaderFor (InputStream* sourceStream, - bool deleteStreamIfOpeningFails) -{ - ScopedPointer r (new CoreAudioReader (sourceStream)); - - if (r->ok) - return r.release(); - - if (! deleteStreamIfOpeningFails) - r->input = nullptr; - - return nullptr; -} - -AudioFormatWriter* CoreAudioFormat::createWriterFor (OutputStream*, - double /*sampleRateToUse*/, - unsigned int /*numberOfChannels*/, - int /*bitsPerSample*/, - const StringPairArray& /*metadataValues*/, - int /*qualityOptionIndex*/) -{ - jassertfalse; // not yet implemented! - return nullptr; -} - -#endif diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/codecs/juce_CoreAudioFormat.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/codecs/juce_CoreAudioFormat.h deleted file mode 100644 index 60bace485d..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/codecs/juce_CoreAudioFormat.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#if JUCE_MAC || JUCE_IOS || DOXYGEN - -//============================================================================== -/** - OSX and iOS only - This uses the AudioToolbox framework to read any audio - format that the system has a codec for. - - This should be able to understand formats such as mp3, m4a, etc. - - @see AudioFormat - */ -class JUCE_API CoreAudioFormat : public AudioFormat -{ -public: - //============================================================================== - /** Creates a format object. */ - CoreAudioFormat(); - - /** Destructor. */ - ~CoreAudioFormat(); - - //============================================================================== - /** Metadata property name used when reading a caf file with a MIDI chunk. */ - static const char* const midiDataBase64; - /** Metadata property name used when reading a caf file with tempo information. */ - static const char* const tempo; - /** Metadata property name used when reading a caf file time signature information. */ - static const char* const timeSig; - /** Metadata property name used when reading a caf file time signature information. */ - static const char* const keySig; - - //============================================================================== - Array getPossibleSampleRates() override; - Array getPossibleBitDepths() override; - bool canDoStereo() override; - bool canDoMono() override; - - //============================================================================== - AudioFormatReader* createReaderFor (InputStream*, - bool deleteStreamIfOpeningFails) override; - - AudioFormatWriter* createWriterFor (OutputStream*, - double sampleRateToUse, - unsigned int numberOfChannels, - int bitsPerSample, - const StringPairArray& metadataValues, - int qualityOptionIndex) override; - -private: - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (CoreAudioFormat) -}; - -#endif diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/codecs/juce_FlacAudioFormat.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/codecs/juce_FlacAudioFormat.cpp deleted file mode 100644 index 58fdd8fbcf..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/codecs/juce_FlacAudioFormat.cpp +++ /dev/null @@ -1,556 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#if JUCE_USE_FLAC - -namespace FlacNamespace -{ -#if JUCE_INCLUDE_FLAC_CODE || ! defined (JUCE_INCLUDE_FLAC_CODE) - - #undef VERSION - #define VERSION "1.2.1" - - #define FLAC__NO_DLL 1 - - #if JUCE_MSVC - #pragma warning (disable: 4267 4127 4244 4996 4100 4701 4702 4013 4133 4206 4312 4505 4365 4005 4334 181 111) - #endif - - #if JUCE_MAC - #define FLAC__SYS_DARWIN 1 - #endif - - #ifndef SIZE_MAX - #define SIZE_MAX 0xffffffff - #endif - - #if JUCE_CLANG - #pragma clang diagnostic push - #pragma clang diagnostic ignored "-Wconversion" - #pragma clang diagnostic ignored "-Wshadow" - #pragma clang diagnostic ignored "-Wdeprecated-register" - #endif - - #if JUCE_INTEL - #if JUCE_32BIT - #define FLAC__CPU_IA32 1 - #endif - #if JUCE_64BIT - #define FLAC__CPU_X86_64 1 - #endif - #define FLAC__HAS_X86INTRIN 1 - #endif - - #undef __STDC_LIMIT_MACROS - #define __STDC_LIMIT_MACROS 1 - #define flac_max jmax - #define flac_min jmin - #include "flac/all.h" - #include "flac/libFLAC/bitmath.c" - #include "flac/libFLAC/bitreader.c" - #include "flac/libFLAC/bitwriter.c" - #include "flac/libFLAC/cpu.c" - #include "flac/libFLAC/crc.c" - #include "flac/libFLAC/fixed.c" - #include "flac/libFLAC/float.c" - #include "flac/libFLAC/format.c" - #include "flac/libFLAC/lpc_flac.c" - #include "flac/libFLAC/md5.c" - #include "flac/libFLAC/memory.c" - #include "flac/libFLAC/stream_decoder.c" - #include "flac/libFLAC/stream_encoder.c" - #include "flac/libFLAC/stream_encoder_framing.c" - #include "flac/libFLAC/window_flac.c" - #undef VERSION -#else - #include -#endif - - #if JUCE_CLANG - #pragma clang diagnostic pop - #endif -} - -#undef max -#undef min - -//============================================================================== -static const char* const flacFormatName = "FLAC file"; - - -//============================================================================== -class FlacReader : public AudioFormatReader -{ -public: - FlacReader (InputStream* const in) - : AudioFormatReader (in, flacFormatName), - reservoirStart (0), - samplesInReservoir (0), - scanningForLength (false) - { - using namespace FlacNamespace; - lengthInSamples = 0; - - decoder = FLAC__stream_decoder_new(); - - ok = FLAC__stream_decoder_init_stream (decoder, - readCallback_, seekCallback_, tellCallback_, lengthCallback_, - eofCallback_, writeCallback_, metadataCallback_, errorCallback_, - this) == FLAC__STREAM_DECODER_INIT_STATUS_OK; - - if (ok) - { - FLAC__stream_decoder_process_until_end_of_metadata (decoder); - - if (lengthInSamples == 0 && sampleRate > 0) - { - // the length hasn't been stored in the metadata, so we'll need to - // work it out the length the hard way, by scanning the whole file.. - scanningForLength = true; - FLAC__stream_decoder_process_until_end_of_stream (decoder); - scanningForLength = false; - const int64 tempLength = lengthInSamples; - - FLAC__stream_decoder_reset (decoder); - FLAC__stream_decoder_process_until_end_of_metadata (decoder); - lengthInSamples = tempLength; - } - } - } - - ~FlacReader() - { - FlacNamespace::FLAC__stream_decoder_delete (decoder); - } - - void useMetadata (const FlacNamespace::FLAC__StreamMetadata_StreamInfo& info) - { - sampleRate = info.sample_rate; - bitsPerSample = info.bits_per_sample; - lengthInSamples = (unsigned int) info.total_samples; - numChannels = info.channels; - - reservoir.setSize ((int) numChannels, 2 * (int) info.max_blocksize, false, false, true); - } - - // returns the number of samples read - bool readSamples (int** destSamples, int numDestChannels, int startOffsetInDestBuffer, - int64 startSampleInFile, int numSamples) override - { - using namespace FlacNamespace; - - if (! ok) - return false; - - while (numSamples > 0) - { - if (startSampleInFile >= reservoirStart - && startSampleInFile < reservoirStart + samplesInReservoir) - { - const int num = (int) jmin ((int64) numSamples, - reservoirStart + samplesInReservoir - startSampleInFile); - - jassert (num > 0); - - for (int i = jmin (numDestChannels, reservoir.getNumChannels()); --i >= 0;) - if (destSamples[i] != nullptr) - memcpy (destSamples[i] + startOffsetInDestBuffer, - reservoir.getReadPointer (i, (int) (startSampleInFile - reservoirStart)), - sizeof (int) * (size_t) num); - - startOffsetInDestBuffer += num; - startSampleInFile += num; - numSamples -= num; - } - else - { - if (startSampleInFile >= (int) lengthInSamples) - { - samplesInReservoir = 0; - } - else if (startSampleInFile < reservoirStart - || startSampleInFile > reservoirStart + jmax (samplesInReservoir, 511)) - { - // had some problems with flac crashing if the read pos is aligned more - // accurately than this. Probably fixed in newer versions of the library, though. - reservoirStart = (int) (startSampleInFile & ~511); - samplesInReservoir = 0; - FLAC__stream_decoder_seek_absolute (decoder, (FLAC__uint64) reservoirStart); - } - else - { - reservoirStart += samplesInReservoir; - samplesInReservoir = 0; - FLAC__stream_decoder_process_single (decoder); - } - - if (samplesInReservoir == 0) - break; - } - } - - if (numSamples > 0) - { - for (int i = numDestChannels; --i >= 0;) - if (destSamples[i] != nullptr) - zeromem (destSamples[i] + startOffsetInDestBuffer, sizeof (int) * (size_t) numSamples); - } - - return true; - } - - void useSamples (const FlacNamespace::FLAC__int32* const buffer[], int numSamples) - { - if (scanningForLength) - { - lengthInSamples += numSamples; - } - else - { - if (numSamples > reservoir.getNumSamples()) - reservoir.setSize ((int) numChannels, numSamples, false, false, true); - - const unsigned int bitsToShift = 32 - bitsPerSample; - - for (int i = 0; i < (int) numChannels; ++i) - { - const FlacNamespace::FLAC__int32* src = buffer[i]; - - int n = i; - while (src == 0 && n > 0) - src = buffer [--n]; - - if (src != nullptr) - { - int* const dest = reinterpret_cast (reservoir.getWritePointer(i)); - - for (int j = 0; j < numSamples; ++j) - dest[j] = src[j] << bitsToShift; - } - } - - samplesInReservoir = numSamples; - } - } - - //============================================================================== - static FlacNamespace::FLAC__StreamDecoderReadStatus readCallback_ (const FlacNamespace::FLAC__StreamDecoder*, FlacNamespace::FLAC__byte buffer[], size_t* bytes, void* client_data) - { - using namespace FlacNamespace; - *bytes = (size_t) static_cast (client_data)->input->read (buffer, (int) *bytes); - return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE; - } - - static FlacNamespace::FLAC__StreamDecoderSeekStatus seekCallback_ (const FlacNamespace::FLAC__StreamDecoder*, FlacNamespace::FLAC__uint64 absolute_byte_offset, void* client_data) - { - using namespace FlacNamespace; - static_cast (client_data)->input->setPosition ((int) absolute_byte_offset); - return FLAC__STREAM_DECODER_SEEK_STATUS_OK; - } - - static FlacNamespace::FLAC__StreamDecoderTellStatus tellCallback_ (const FlacNamespace::FLAC__StreamDecoder*, FlacNamespace::FLAC__uint64* absolute_byte_offset, void* client_data) - { - using namespace FlacNamespace; - *absolute_byte_offset = (uint64) static_cast (client_data)->input->getPosition(); - return FLAC__STREAM_DECODER_TELL_STATUS_OK; - } - - static FlacNamespace::FLAC__StreamDecoderLengthStatus lengthCallback_ (const FlacNamespace::FLAC__StreamDecoder*, FlacNamespace::FLAC__uint64* stream_length, void* client_data) - { - using namespace FlacNamespace; - *stream_length = (uint64) static_cast (client_data)->input->getTotalLength(); - return FLAC__STREAM_DECODER_LENGTH_STATUS_OK; - } - - static FlacNamespace::FLAC__bool eofCallback_ (const FlacNamespace::FLAC__StreamDecoder*, void* client_data) - { - return static_cast (client_data)->input->isExhausted(); - } - - static FlacNamespace::FLAC__StreamDecoderWriteStatus writeCallback_ (const FlacNamespace::FLAC__StreamDecoder*, - const FlacNamespace::FLAC__Frame* frame, - const FlacNamespace::FLAC__int32* const buffer[], - void* client_data) - { - using namespace FlacNamespace; - static_cast (client_data)->useSamples (buffer, (int) frame->header.blocksize); - return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE; - } - - static void metadataCallback_ (const FlacNamespace::FLAC__StreamDecoder*, - const FlacNamespace::FLAC__StreamMetadata* metadata, - void* client_data) - { - static_cast (client_data)->useMetadata (metadata->data.stream_info); - } - - static void errorCallback_ (const FlacNamespace::FLAC__StreamDecoder*, FlacNamespace::FLAC__StreamDecoderErrorStatus, void*) - { - } - -private: - FlacNamespace::FLAC__StreamDecoder* decoder; - AudioSampleBuffer reservoir; - int reservoirStart, samplesInReservoir; - bool ok, scanningForLength; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (FlacReader) -}; - - -//============================================================================== -class FlacWriter : public AudioFormatWriter -{ -public: - FlacWriter (OutputStream* const out, double rate, uint32 numChans, uint32 bits, int qualityOptionIndex) - : AudioFormatWriter (out, flacFormatName, rate, numChans, bits) - { - using namespace FlacNamespace; - encoder = FLAC__stream_encoder_new(); - - if (qualityOptionIndex > 0) - FLAC__stream_encoder_set_compression_level (encoder, (uint32) jmin (8, qualityOptionIndex)); - - FLAC__stream_encoder_set_do_mid_side_stereo (encoder, numChannels == 2); - FLAC__stream_encoder_set_loose_mid_side_stereo (encoder, numChannels == 2); - FLAC__stream_encoder_set_channels (encoder, numChannels); - FLAC__stream_encoder_set_bits_per_sample (encoder, jmin ((unsigned int) 24, bitsPerSample)); - FLAC__stream_encoder_set_sample_rate (encoder, (unsigned int) sampleRate); - FLAC__stream_encoder_set_blocksize (encoder, 0); - FLAC__stream_encoder_set_do_escape_coding (encoder, true); - - ok = FLAC__stream_encoder_init_stream (encoder, - encodeWriteCallback, encodeSeekCallback, - encodeTellCallback, encodeMetadataCallback, - this) == FLAC__STREAM_ENCODER_INIT_STATUS_OK; - } - - ~FlacWriter() - { - if (ok) - { - FlacNamespace::FLAC__stream_encoder_finish (encoder); - output->flush(); - } - else - { - output = nullptr; // to stop the base class deleting this, as it needs to be returned - // to the caller of createWriter() - } - - FlacNamespace::FLAC__stream_encoder_delete (encoder); - } - - //============================================================================== - bool write (const int** samplesToWrite, int numSamples) override - { - using namespace FlacNamespace; - if (! ok) - return false; - - HeapBlock channels; - HeapBlock temp; - const int bitsToShift = 32 - (int) bitsPerSample; - - if (bitsToShift > 0) - { - temp.malloc (numChannels * (size_t) numSamples); - channels.calloc (numChannels + 1); - - for (unsigned int i = 0; i < numChannels; ++i) - { - if (samplesToWrite[i] == nullptr) - break; - - int* const destData = temp.getData() + i * (size_t) numSamples; - channels[i] = destData; - - for (int j = 0; j < numSamples; ++j) - destData[j] = (samplesToWrite[i][j] >> bitsToShift); - } - - samplesToWrite = const_cast (channels.getData()); - } - - return FLAC__stream_encoder_process (encoder, (const FLAC__int32**) samplesToWrite, (unsigned) numSamples) != 0; - } - - bool writeData (const void* const data, const int size) const - { - return output->write (data, (size_t) size); - } - - static void packUint32 (FlacNamespace::FLAC__uint32 val, FlacNamespace::FLAC__byte* b, const int bytes) - { - b += bytes; - - for (int i = 0; i < bytes; ++i) - { - *(--b) = (FlacNamespace::FLAC__byte) (val & 0xff); - val >>= 8; - } - } - - void writeMetaData (const FlacNamespace::FLAC__StreamMetadata* metadata) - { - using namespace FlacNamespace; - const FLAC__StreamMetadata_StreamInfo& info = metadata->data.stream_info; - - unsigned char buffer [FLAC__STREAM_METADATA_STREAMINFO_LENGTH]; - const unsigned int channelsMinus1 = info.channels - 1; - const unsigned int bitsMinus1 = info.bits_per_sample - 1; - - packUint32 (info.min_blocksize, buffer, 2); - packUint32 (info.max_blocksize, buffer + 2, 2); - packUint32 (info.min_framesize, buffer + 4, 3); - packUint32 (info.max_framesize, buffer + 7, 3); - buffer[10] = (uint8) ((info.sample_rate >> 12) & 0xff); - buffer[11] = (uint8) ((info.sample_rate >> 4) & 0xff); - buffer[12] = (uint8) (((info.sample_rate & 0x0f) << 4) | (channelsMinus1 << 1) | (bitsMinus1 >> 4)); - buffer[13] = (FLAC__byte) (((bitsMinus1 & 0x0f) << 4) | (unsigned int) ((info.total_samples >> 32) & 0x0f)); - packUint32 ((FLAC__uint32) info.total_samples, buffer + 14, 4); - memcpy (buffer + 18, info.md5sum, 16); - - const bool seekOk = output->setPosition (4); - (void) seekOk; - - // if this fails, you've given it an output stream that can't seek! It needs - // to be able to seek back to write the header - jassert (seekOk); - - output->writeIntBigEndian (FLAC__STREAM_METADATA_STREAMINFO_LENGTH); - output->write (buffer, FLAC__STREAM_METADATA_STREAMINFO_LENGTH); - } - - //============================================================================== - static FlacNamespace::FLAC__StreamEncoderWriteStatus encodeWriteCallback (const FlacNamespace::FLAC__StreamEncoder*, - const FlacNamespace::FLAC__byte buffer[], - size_t bytes, - unsigned int /*samples*/, - unsigned int /*current_frame*/, - void* client_data) - { - using namespace FlacNamespace; - return static_cast (client_data)->writeData (buffer, (int) bytes) - ? FLAC__STREAM_ENCODER_WRITE_STATUS_OK - : FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR; - } - - static FlacNamespace::FLAC__StreamEncoderSeekStatus encodeSeekCallback (const FlacNamespace::FLAC__StreamEncoder*, FlacNamespace::FLAC__uint64, void*) - { - using namespace FlacNamespace; - return FLAC__STREAM_ENCODER_SEEK_STATUS_UNSUPPORTED; - } - - static FlacNamespace::FLAC__StreamEncoderTellStatus encodeTellCallback (const FlacNamespace::FLAC__StreamEncoder*, FlacNamespace::FLAC__uint64* absolute_byte_offset, void* client_data) - { - using namespace FlacNamespace; - if (client_data == nullptr) - return FLAC__STREAM_ENCODER_TELL_STATUS_UNSUPPORTED; - - *absolute_byte_offset = (FLAC__uint64) static_cast (client_data)->output->getPosition(); - return FLAC__STREAM_ENCODER_TELL_STATUS_OK; - } - - static void encodeMetadataCallback (const FlacNamespace::FLAC__StreamEncoder*, const FlacNamespace::FLAC__StreamMetadata* metadata, void* client_data) - { - static_cast (client_data)->writeMetaData (metadata); - } - - bool ok; - -private: - FlacNamespace::FLAC__StreamEncoder* encoder; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (FlacWriter) -}; - - -//============================================================================== -FlacAudioFormat::FlacAudioFormat() - : AudioFormat (flacFormatName, ".flac") -{ -} - -FlacAudioFormat::~FlacAudioFormat() -{ -} - -Array FlacAudioFormat::getPossibleSampleRates() -{ - const int rates[] = { 8000, 11025, 12000, 16000, 22050, 32000, 44100, 48000, - 88200, 96000, 176400, 192000, 352800, 384000 }; - - return Array (rates, numElementsInArray (rates)); -} - -Array FlacAudioFormat::getPossibleBitDepths() -{ - const int depths[] = { 16, 24 }; - - return Array (depths, numElementsInArray (depths)); -} - -bool FlacAudioFormat::canDoStereo() { return true; } -bool FlacAudioFormat::canDoMono() { return true; } -bool FlacAudioFormat::isCompressed() { return true; } - -AudioFormatReader* FlacAudioFormat::createReaderFor (InputStream* in, const bool deleteStreamIfOpeningFails) -{ - ScopedPointer r (new FlacReader (in)); - - if (r->sampleRate > 0) - return r.release(); - - if (! deleteStreamIfOpeningFails) - r->input = nullptr; - - return nullptr; -} - -AudioFormatWriter* FlacAudioFormat::createWriterFor (OutputStream* out, - double sampleRate, - unsigned int numberOfChannels, - int bitsPerSample, - const StringPairArray& /*metadataValues*/, - int qualityOptionIndex) -{ - if (getPossibleBitDepths().contains (bitsPerSample)) - { - ScopedPointer w (new FlacWriter (out, sampleRate, numberOfChannels, - (uint32) bitsPerSample, qualityOptionIndex)); - if (w->ok) - return w.release(); - } - - return nullptr; -} - -StringArray FlacAudioFormat::getQualityOptions() -{ - static const char* options[] = { "0 (Fastest)", "1", "2", "3", "4", "5 (Default)","6", "7", "8 (Highest quality)", 0 }; - return StringArray (options); -} - -#endif diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/codecs/juce_FlacAudioFormat.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/codecs/juce_FlacAudioFormat.h deleted file mode 100644 index 20bf094f9e..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/codecs/juce_FlacAudioFormat.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#if JUCE_USE_FLAC || defined (DOXYGEN) - -//============================================================================== -/** - Reads and writes the lossless-compression FLAC audio format. - - To compile this, you'll need to set the JUCE_USE_FLAC flag. - - @see AudioFormat -*/ -class JUCE_API FlacAudioFormat : public AudioFormat -{ -public: - //============================================================================== - FlacAudioFormat(); - ~FlacAudioFormat(); - - //============================================================================== - Array getPossibleSampleRates() override; - Array getPossibleBitDepths() override; - bool canDoStereo() override; - bool canDoMono() override; - bool isCompressed() override; - StringArray getQualityOptions() override; - - //============================================================================== - AudioFormatReader* createReaderFor (InputStream* sourceStream, - bool deleteStreamIfOpeningFails) override; - - AudioFormatWriter* createWriterFor (OutputStream* streamToWriteTo, - double sampleRateToUse, - unsigned int numberOfChannels, - int bitsPerSample, - const StringPairArray& metadataValues, - int qualityOptionIndex) override; -private: - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (FlacAudioFormat) -}; - - -#endif diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/codecs/juce_LAMEEncoderAudioFormat.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/codecs/juce_LAMEEncoderAudioFormat.cpp deleted file mode 100644 index 8a5263cb12..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/codecs/juce_LAMEEncoderAudioFormat.cpp +++ /dev/null @@ -1,222 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#if JUCE_USE_LAME_AUDIO_FORMAT - -class LAMEEncoderAudioFormat::Writer : public AudioFormatWriter -{ -public: - Writer (OutputStream* destStream, const String& formatName, - const File& appFile, int vbr, int cbr, - double sampleRate, unsigned int numberOfChannels, - unsigned int bitsPerSample, const StringPairArray& metadata) - : AudioFormatWriter (destStream, formatName, sampleRate, - numberOfChannels, bitsPerSample), - vbrLevel (vbr), cbrBitrate (cbr), - tempWav (".wav") - { - WavAudioFormat wavFormat; - - if (FileOutputStream* out = tempWav.getFile().createOutputStream()) - { - writer = wavFormat.createWriterFor (out, sampleRate, numChannels, - bitsPerSample, metadata, 0); - - args.add (appFile.getFullPathName()); - - args.add ("--quiet"); - - if (cbrBitrate == 0) - { - args.add ("--vbr-new"); - args.add ("-V"); - args.add (String (vbrLevel)); - } - else - { - args.add ("--cbr"); - args.add ("-b"); - args.add (String (cbrBitrate)); - } - - addMetadataArg (metadata, "id3title", "--tt"); - addMetadataArg (metadata, "id3artist", "--ta"); - addMetadataArg (metadata, "id3album", "--tl"); - addMetadataArg (metadata, "id3comment", "--tc"); - addMetadataArg (metadata, "id3date", "--ty"); - addMetadataArg (metadata, "id3genre", "--tg"); - addMetadataArg (metadata, "id3trackNumber", "--tn"); - } - } - - void addMetadataArg (const StringPairArray& metadata, const char* key, const char* lameFlag) - { - const String value (metadata.getValue (key, String())); - - if (value.isNotEmpty()) - { - args.add (lameFlag); - args.add (value); - } - } - - ~Writer() - { - if (writer != nullptr) - { - writer = nullptr; - - if (! convertToMP3()) - convertToMP3(); // try again - } - } - - bool write (const int** samplesToWrite, int numSamples) - { - return writer != nullptr && writer->write (samplesToWrite, numSamples); - } - -private: - int vbrLevel, cbrBitrate; - TemporaryFile tempWav; - ScopedPointer writer; - StringArray args; - - bool runLameChildProcess (const TemporaryFile& tempMP3, const StringArray& processArgs) const - { - ChildProcess cp; - - if (cp.start (processArgs)) - { - const String childOutput (cp.readAllProcessOutput()); - DBG (childOutput); (void) childOutput; - - cp.waitForProcessToFinish (10000); - return tempMP3.getFile().getSize() > 0; - } - - return false; - } - - bool convertToMP3() const - { - TemporaryFile tempMP3 (".mp3"); - - StringArray args2 (args); - args2.add (tempWav.getFile().getFullPathName()); - args2.add (tempMP3.getFile().getFullPathName()); - - DBG (args2.joinIntoString (" ")); - - if (runLameChildProcess (tempMP3, args2)) - { - FileInputStream fis (tempMP3.getFile()); - - if (fis.openedOk() && output->writeFromInputStream (fis, -1) > 0) - { - output->flush(); - return true; - } - } - - return false; - } - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Writer) -}; - -//============================================================================== -LAMEEncoderAudioFormat::LAMEEncoderAudioFormat (const File& lameApplication) - : AudioFormat ("MP3 file", ".mp3"), - lameApp (lameApplication) -{ -} - -LAMEEncoderAudioFormat::~LAMEEncoderAudioFormat() -{ -} - -bool LAMEEncoderAudioFormat::canHandleFile (const File&) -{ - return false; -} - -Array LAMEEncoderAudioFormat::getPossibleSampleRates() -{ - const int rates[] = { 32000, 44100, 48000, 0 }; - return Array (rates); -} - -Array LAMEEncoderAudioFormat::getPossibleBitDepths() -{ - const int depths[] = { 16, 0 }; - return Array (depths); -} - -bool LAMEEncoderAudioFormat::canDoStereo() { return true; } -bool LAMEEncoderAudioFormat::canDoMono() { return true; } -bool LAMEEncoderAudioFormat::isCompressed() { return true; } - -StringArray LAMEEncoderAudioFormat::getQualityOptions() -{ - static const char* vbrOptions[] = { "VBR quality 0 (best)", "VBR quality 1", "VBR quality 2", "VBR quality 3", - "VBR quality 4 (normal)", "VBR quality 5", "VBR quality 6", "VBR quality 7", - "VBR quality 8", "VBR quality 9 (smallest)", nullptr }; - StringArray opts (vbrOptions); - - const int cbrRates[] = { 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320 }; - - for (int i = 0; i < numElementsInArray (cbrRates); ++i) - opts.add (String (cbrRates[i]) + " Kb/s CBR"); - - return opts; -} - -AudioFormatReader* LAMEEncoderAudioFormat::createReaderFor (InputStream*, const bool) -{ - return nullptr; -} - -AudioFormatWriter* LAMEEncoderAudioFormat::createWriterFor (OutputStream* streamToWriteTo, - double sampleRateToUse, - unsigned int numberOfChannels, - int bitsPerSample, - const StringPairArray& metadataValues, - int qualityOptionIndex) -{ - int vbr = 4; - int cbr = 0; - - const String qual (getQualityOptions() [qualityOptionIndex]); - - if (qual.contains ("VBR")) - vbr = qual.retainCharacters ("0123456789").getIntValue(); - else - cbr = qual.getIntValue(); - - return new Writer (streamToWriteTo, getFormatName(), lameApp, vbr, cbr, - sampleRateToUse, numberOfChannels, bitsPerSample, metadataValues); -} - -#endif diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/codecs/juce_LAMEEncoderAudioFormat.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/codecs/juce_LAMEEncoderAudioFormat.h deleted file mode 100644 index 92e581b083..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/codecs/juce_LAMEEncoderAudioFormat.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#if JUCE_USE_LAME_AUDIO_FORMAT || defined (DOXYGEN) - -//============================================================================== -/** - An AudioFormat class which can use an installed version of the LAME mp3 - encoder to encode a file. - - This format can't read MP3s, it just writes them. Internally, the - AudioFormatWriter object that is returned writes the incoming audio data - to a temporary WAV file, and then when the writer is deleted, it invokes - the LAME executable to convert the data to an MP3, whose data is then - piped into the original OutputStream that was used when first creating - the writer. - - @see AudioFormat -*/ -class JUCE_API LAMEEncoderAudioFormat : public AudioFormat -{ -public: - /** Creates a LAMEEncoderAudioFormat that expects to find a working LAME - executable at the location given. - */ - LAMEEncoderAudioFormat (const File& lameExecutableToUse); - ~LAMEEncoderAudioFormat(); - - bool canHandleFile (const File&); - Array getPossibleSampleRates(); - Array getPossibleBitDepths(); - bool canDoStereo(); - bool canDoMono(); - bool isCompressed(); - StringArray getQualityOptions(); - - AudioFormatReader* createReaderFor (InputStream*, bool deleteStreamIfOpeningFails); - - AudioFormatWriter* createWriterFor (OutputStream*, double sampleRateToUse, - unsigned int numberOfChannels, int bitsPerSample, - const StringPairArray& metadataValues, int qualityOptionIndex); - -private: - File lameApp; - class Writer; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (LAMEEncoderAudioFormat) -}; - -#endif diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/codecs/juce_MP3AudioFormat.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/codecs/juce_MP3AudioFormat.cpp deleted file mode 100644 index 219c93f709..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/codecs/juce_MP3AudioFormat.cpp +++ /dev/null @@ -1,3162 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -/* - IMPORTANT DISCLAIMER: By choosing to enable the JUCE_USE_MP3AUDIOFORMAT flag and - to compile this MP3 code into your software, you do so AT YOUR OWN RISK! By doing so, - you are agreeing that Raw Material Software is in no way responsible for any patent, - copyright, or other legal issues that you may suffer as a result. - - The code in juce_MP3AudioFormat.cpp is NOT guaranteed to be free from infringements of 3rd-party - intellectual property. If you wish to use it, please seek your own independent advice about the - legality of doing so. If you are not willing to accept full responsibility for the consequences - of using this code, then do not enable the JUCE_USE_MP3AUDIOFORMAT setting. -*/ -#if JUCE_USE_MP3AUDIOFORMAT - -namespace MP3Decoder -{ - -struct AllocationTable { int16 bits, d; }; - -const struct AllocationTable allocTable0[] = -{ - {4, 0}, {5, 3}, {3, -3}, {4, -7}, {5, -15}, {6, -31}, {7, -63}, {8, -127}, {9, -255}, {10, -511}, {11, -1023}, {12, -2047}, {13, -4095}, {14, -8191}, {15, -16383}, {16, -32767}, - {4, 0}, {5, 3}, {3, -3}, {4, -7}, {5, -15}, {6, -31}, {7, -63}, {8, -127}, {9, -255}, {10, -511}, {11, -1023}, {12, -2047}, {13, -4095}, {14, -8191}, {15, -16383}, {16, -32767}, - {4, 0}, {5, 3}, {3, -3}, {4, -7}, {5, -15}, {6, -31}, {7, -63}, {8, -127}, {9, -255}, {10, -511}, {11, -1023}, {12, -2047}, {13, -4095}, {14, -8191}, {15, -16383}, {16, -32767}, - {4, 0}, {5, 3}, {7, 5}, {3, -3}, {10, 9}, {4, -7}, {5, -15}, {6, -31}, {7, -63}, {8, -127}, {9, -255}, {10, -511}, {11, -1023}, {12, -2047}, {13, -4095}, {16, -32767}, - {4, 0}, {5, 3}, {7, 5}, {3, -3}, {10, 9}, {4, -7}, {5, -15}, {6, -31}, {7, -63}, {8, -127}, {9, -255}, {10, -511}, {11, -1023}, {12, -2047}, {13, -4095}, {16, -32767}, - {4, 0}, {5, 3}, {7, 5}, {3, -3}, {10, 9}, {4, -7}, {5, -15}, {6, -31}, {7, -63}, {8, -127}, {9, -255}, {10, -511}, {11, -1023}, {12, -2047}, {13, -4095}, {16, -32767}, - {4, 0}, {5, 3}, {7, 5}, {3, -3}, {10, 9}, {4, -7}, {5, -15}, {6, -31}, {7, -63}, {8, -127}, {9, -255}, {10, -511}, {11, -1023}, {12, -2047}, {13, -4095}, {16, -32767}, - {4, 0}, {5, 3}, {7, 5}, {3, -3}, {10, 9}, {4, -7}, {5, -15}, {6, -31}, {7, -63}, {8, -127}, {9, -255}, {10, -511}, {11, -1023}, {12, -2047}, {13, -4095}, {16, -32767}, - {4, 0}, {5, 3}, {7, 5}, {3, -3}, {10, 9}, {4, -7}, {5, -15}, {6, -31}, {7, -63}, {8, -127}, {9, -255}, {10, -511}, {11, -1023}, {12, -2047}, {13, -4095}, {16, -32767}, - {4, 0}, {5, 3}, {7, 5}, {3, -3}, {10, 9}, {4, -7}, {5, -15}, {6, -31}, {7, -63}, {8, -127}, {9, -255}, {10, -511}, {11, -1023}, {12, -2047}, {13, -4095}, {16, -32767}, - {4, 0}, {5, 3}, {7, 5}, {3, -3}, {10, 9}, {4, -7}, {5, -15}, {6, -31}, {7, -63}, {8, -127}, {9, -255}, {10, -511}, {11, -1023}, {12, -2047}, {13, -4095}, {16, -32767}, - {3, 0}, {5, 3}, {7, 5}, {3, -3}, {10, 9}, {4, -7}, {5, -15}, {16, -32767}, {3, 0}, {5, 3}, {7, 5}, {3, -3}, {10, 9}, {4, -7}, {5, -15}, {16, -32767}, - {3, 0}, {5, 3}, {7, 5}, {3, -3}, {10, 9}, {4, -7}, {5, -15}, {16, -32767}, {3, 0}, {5, 3}, {7, 5}, {3, -3}, {10, 9}, {4, -7}, {5, -15}, {16, -32767}, - {3, 0}, {5, 3}, {7, 5}, {3, -3}, {10, 9}, {4, -7}, {5, -15}, {16, -32767}, {3, 0}, {5, 3}, {7, 5}, {3, -3}, {10, 9}, {4, -7}, {5, -15}, {16, -32767}, - {3, 0}, {5, 3}, {7, 5}, {3, -3}, {10, 9}, {4, -7}, {5, -15}, {16, -32767}, {3, 0}, {5, 3}, {7, 5}, {3, -3}, {10, 9}, {4, -7}, {5, -15}, {16, -32767}, - {3, 0}, {5, 3}, {7, 5}, {3, -3}, {10, 9}, {4, -7}, {5, -15}, {16, -32767}, {3, 0}, {5, 3}, {7, 5}, {3, -3}, {10, 9}, {4, -7}, {5, -15}, {16, -32767}, - {3, 0}, {5, 3}, {7, 5}, {3, -3}, {10, 9}, {4, -7}, {5, -15}, {16, -32767}, {3, 0}, {5, 3}, {7, 5}, {3, -3}, {10, 9}, {4, -7}, {5, -15}, {16, -32767}, - {2, 0}, {5, 3}, {7, 5}, {16, -32767}, {2, 0}, {5, 3}, {7, 5}, {16, -32767}, {2, 0}, {5, 3}, {7, 5}, {16, -32767}, {2, 0}, {5, 3}, {7, 5}, {16, -32767} -}; - -const struct AllocationTable allocTable1[] = -{ - {4, 0}, {5, 3}, {3, -3}, {4, -7}, {5, -15}, {6, -31}, {7, -63}, {8, -127}, {9, -255}, {10, -511}, {11, -1023}, {12, -2047}, {13, -4095}, {14, -8191}, {15, -16383}, {16, -32767}, - {4, 0}, {5, 3}, {3, -3}, {4, -7}, {5, -15}, {6, -31}, {7, -63}, {8, -127}, {9, -255}, {10, -511}, {11, -1023}, {12, -2047}, {13, -4095}, {14, -8191}, {15, -16383}, {16, -32767}, - {4, 0}, {5, 3}, {3, -3}, {4, -7}, {5, -15}, {6, -31}, {7, -63}, {8, -127}, {9, -255}, {10, -511}, {11, -1023}, {12, -2047}, {13, -4095}, {14, -8191}, {15, -16383}, {16, -32767}, - {4, 0}, {5, 3}, {7, 5}, {3, -3}, {10, 9}, {4, -7}, {5, -15}, {6, -31}, {7, -63}, {8, -127}, {9, -255}, {10, -511}, {11, -1023}, {12, -2047}, {13, -4095}, {16, -32767}, - {4, 0}, {5, 3}, {7, 5}, {3, -3}, {10, 9}, {4, -7}, {5, -15}, {6, -31}, {7, -63}, {8, -127}, {9, -255}, {10, -511}, {11, -1023}, {12, -2047}, {13, -4095}, {16, -32767}, - {4, 0}, {5, 3}, {7, 5}, {3, -3}, {10, 9}, {4, -7}, {5, -15}, {6, -31}, {7, -63}, {8, -127}, {9, -255}, {10, -511}, {11, -1023}, {12, -2047}, {13, -4095}, {16, -32767}, - {4, 0}, {5, 3}, {7, 5}, {3, -3}, {10, 9}, {4, -7}, {5, -15}, {6, -31}, {7, -63}, {8, -127}, {9, -255}, {10, -511}, {11, -1023}, {12, -2047}, {13, -4095}, {16, -32767}, - {4, 0}, {5, 3}, {7, 5}, {3, -3}, {10, 9}, {4, -7}, {5, -15}, {6, -31}, {7, -63}, {8, -127}, {9, -255}, {10, -511}, {11, -1023}, {12, -2047}, {13, -4095}, {16, -32767}, - {4, 0}, {5, 3}, {7, 5}, {3, -3}, {10, 9}, {4, -7}, {5, -15}, {6, -31}, {7, -63}, {8, -127}, {9, -255}, {10, -511}, {11, -1023}, {12, -2047}, {13, -4095}, {16, -32767}, - {4, 0}, {5, 3}, {7, 5}, {3, -3}, {10, 9}, {4, -7}, {5, -15}, {6, -31}, {7, -63}, {8, -127}, {9, -255}, {10, -511}, {11, -1023}, {12, -2047}, {13, -4095}, {16, -32767}, - {4, 0}, {5, 3}, {7, 5}, {3, -3}, {10, 9}, {4, -7}, {5, -15}, {6, -31}, {7, -63}, {8, -127}, {9, -255}, {10, -511}, {11, -1023}, {12, -2047}, {13, -4095}, {16, -32767}, - {3, 0}, {5, 3}, {7, 5}, {3, -3}, {10, 9}, {4, -7}, {5, -15}, {16, -32767}, {3, 0}, {5, 3}, {7, 5}, {3, -3}, {10, 9}, {4, -7}, {5, -15}, {16, -32767}, - {3, 0}, {5, 3}, {7, 5}, {3, -3}, {10, 9}, {4, -7}, {5, -15}, {16, -32767}, {3, 0}, {5, 3}, {7, 5}, {3, -3}, {10, 9}, {4, -7}, {5, -15}, {16, -32767}, - {3, 0}, {5, 3}, {7, 5}, {3, -3}, {10, 9}, {4, -7}, {5, -15}, {16, -32767}, {3, 0}, {5, 3}, {7, 5}, {3, -3}, {10, 9}, {4, -7}, {5, -15}, {16, -32767}, - {3, 0}, {5, 3}, {7, 5}, {3, -3}, {10, 9}, {4, -7}, {5, -15}, {16, -32767}, {3, 0}, {5, 3}, {7, 5}, {3, -3}, {10, 9}, {4, -7}, {5, -15}, {16, -32767}, - {3, 0}, {5, 3}, {7, 5}, {3, -3}, {10, 9}, {4, -7}, {5, -15}, {16, -32767}, {3, 0}, {5, 3}, {7, 5}, {3, -3}, {10, 9}, {4, -7}, {5, -15}, {16, -32767}, - {3, 0}, {5, 3}, {7, 5}, {3, -3}, {10, 9}, {4, -7}, {5, -15}, {16, -32767}, {3, 0}, {5, 3}, {7, 5}, {3, -3}, {10, 9}, {4, -7}, {5, -15}, {16, -32767}, - {2, 0}, {5, 3}, {7, 5}, {16, -32767}, {2, 0}, {5, 3}, {7, 5}, {16, -32767}, {2, 0}, {5, 3}, {7, 5}, {16, -32767}, {2, 0}, {5, 3}, {7, 5}, {16, -32767}, - {2, 0}, {5, 3}, {7, 5}, {16, -32767}, {2, 0}, {5, 3}, {7, 5}, {16, -32767}, {2, 0}, {5, 3}, {7, 5}, {16, -32767} -}; - -const struct AllocationTable allocTable2[] = -{ - {4, 0}, {5, 3}, {7, 5}, {10, 9}, {4, -7}, {5, -15}, {6, -31}, {7, -63}, {8, -127}, {9, -255}, {10, -511}, {11, -1023}, {12, -2047}, {13, -4095}, {14, -8191}, {15, -16383}, - {4, 0}, {5, 3}, {7, 5}, {10, 9}, {4, -7}, {5, -15}, {6, -31}, {7, -63}, {8, -127}, {9, -255}, {10, -511}, {11, -1023}, {12, -2047}, {13, -4095}, {14, -8191}, {15, -16383}, - {3, 0}, {5, 3}, {7, 5}, {10, 9}, {4, -7}, {5, -15}, {6, -31}, {7, -63}, {3, 0}, {5, 3}, {7, 5}, {10, 9}, {4, -7}, {5, -15}, {6, -31}, {7, -63}, - {3, 0}, {5, 3}, {7, 5}, {10, 9}, {4, -7}, {5, -15}, {6, -31}, {7, -63}, {3, 0}, {5, 3}, {7, 5}, {10, 9}, {4, -7}, {5, -15}, {6, -31}, {7, -63}, - {3, 0}, {5, 3}, {7, 5}, {10, 9}, {4, -7}, {5, -15}, {6, -31}, {7, -63}, {3, 0}, {5, 3}, {7, 5}, {10, 9}, {4, -7}, {5, -15}, {6, -31}, {7, -63} -}; - -const struct AllocationTable allocTable3[] = -{ - {4, 0}, {5, 3}, {7, 5}, {10, 9}, {4, -7}, {5, -15}, {6, -31}, {7, -63}, {8, -127}, {9, -255}, {10, -511}, {11, -1023}, {12, -2047}, {13, -4095}, {14, -8191}, {15, -16383}, - {4, 0}, {5, 3}, {7, 5}, {10, 9}, {4, -7}, {5, -15}, {6, -31}, {7, -63}, {8, -127}, {9, -255}, {10, -511}, {11, -1023}, {12, -2047}, {13, -4095}, {14, -8191}, {15, -16383}, - {3, 0}, {5, 3}, {7, 5}, {10, 9}, {4, -7}, {5, -15}, {6, -31}, {7, -63}, {3, 0}, {5, 3}, {7, 5}, {10, 9}, {4, -7}, {5, -15}, {6, -31}, {7, -63}, - {3, 0}, {5, 3}, {7, 5}, {10, 9}, {4, -7}, {5, -15}, {6, -31}, {7, -63}, {3, 0}, {5, 3}, {7, 5}, {10, 9}, {4, -7}, {5, -15}, {6, -31}, {7, -63}, - {3, 0}, {5, 3}, {7, 5}, {10, 9}, {4, -7}, {5, -15}, {6, -31}, {7, -63}, {3, 0}, {5, 3}, {7, 5}, {10, 9}, {4, -7}, {5, -15}, {6, -31}, {7, -63}, - {3, 0}, {5, 3}, {7, 5}, {10, 9}, {4, -7}, {5, -15}, {6, -31}, {7, -63}, {3, 0}, {5, 3}, {7, 5}, {10, 9}, {4, -7}, {5, -15}, {6, -31}, {7, -63}, - {3, 0}, {5, 3}, {7, 5}, {10, 9}, {4, -7}, {5, -15}, {6, -31}, {7, -63}, {3, 0}, {5, 3}, {7, 5}, {10, 9}, {4, -7}, {5, -15}, {6, -31}, {7, -63} -}; - -const struct AllocationTable allocTable4[] = -{ - {4, 0}, {5, 3}, {7, 5}, {3, -3}, {10, 9}, {4, -7}, {5, -15}, {6, -31}, {7, -63}, {8, -127}, {9, -255}, {10, -511}, {11, -1023}, {12, -2047}, {13, -4095}, {14, -8191}, - {4, 0}, {5, 3}, {7, 5}, {3, -3}, {10, 9}, {4, -7}, {5, -15}, {6, -31}, {7, -63}, {8, -127}, {9, -255}, {10, -511}, {11, -1023}, {12, -2047}, {13, -4095}, {14, -8191}, - {4, 0}, {5, 3}, {7, 5}, {3, -3}, {10, 9}, {4, -7}, {5, -15}, {6, -31}, {7, -63}, {8, -127}, {9, -255}, {10, -511}, {11, -1023}, {12, -2047}, {13, -4095}, {14, -8191}, - {4, 0}, {5, 3}, {7, 5}, {3, -3}, {10, 9}, {4, -7}, {5, -15}, {6, -31}, {7, -63}, {8, -127}, {9, -255}, {10, -511}, {11, -1023}, {12, -2047}, {13, -4095}, {14, -8191}, - {3, 0}, {5, 3}, {7, 5}, {10, 9}, {4, -7}, {5, -15}, {6, -31}, {7, -63}, {3, 0}, {5, 3}, {7, 5}, {10, 9}, {4, -7}, {5, -15}, {6, -31}, {7, -63}, - {3, 0}, {5, 3}, {7, 5}, {10, 9}, {4, -7}, {5, -15}, {6, -31}, {7, -63}, {3, 0}, {5, 3}, {7, 5}, {10, 9}, {4, -7}, {5, -15}, {6, -31}, {7, -63}, - {3, 0}, {5, 3}, {7, 5}, {10, 9}, {4, -7}, {5, -15}, {6, -31}, {7, -63}, {3, 0}, {5, 3}, {7, 5}, {10, 9}, {4, -7}, {5, -15}, {6, -31}, {7, -63}, - {3, 0}, {5, 3}, {7, 5}, {10, 9}, {4, -7}, {5, -15}, {6, -31}, {7, -63}, {2, 0}, {5, 3}, {7, 5}, {10, 9}, {2, 0}, {5, 3}, {7, 5}, {10, 9}, - {2, 0}, {5, 3}, {7, 5}, {10, 9}, {2, 0}, {5, 3}, {7, 5}, {10, 9}, {2, 0}, {5, 3}, {7, 5}, {10, 9}, {2, 0}, {5, 3}, {7, 5}, {10, 9}, - {2, 0}, {5, 3}, {7, 5}, {10, 9}, {2, 0}, {5, 3}, {7, 5}, {10, 9}, {2, 0}, {5, 3}, {7, 5}, {10, 9}, {2, 0}, {5, 3}, {7, 5}, {10, 9}, - {2, 0}, {5, 3}, {7, 5}, {10, 9}, {2, 0}, {5, 3}, {7, 5}, {10, 9}, {2, 0}, {5, 3}, {7, 5}, {10, 9}, {2, 0}, {5, 3}, {7, 5}, {10, 9}, - {2, 0}, {5, 3}, {7, 5}, {10, 9}, {2, 0}, {5, 3}, {7, 5}, {10, 9}, {2, 0}, {5, 3}, {7, 5}, {10, 9}, {2, 0}, {5, 3}, {7, 5}, {10, 9}, - {2, 0}, {5, 3}, {7, 5}, {10, 9} -}; - -struct BandInfoStruct -{ - int16 longIndex[23]; - int16 longDiff[22]; - int16 shortIndex[14]; - int16 shortDiff[13]; -}; - -const BandInfoStruct bandInfo[9] = -{ - { {0, 4, 8, 12, 16, 20, 24, 30, 36, 44, 52, 62, 74, 90, 110, 134, 162, 196, 238, 288, 342, 418, 576}, - {4, 4, 4, 4, 4, 4, 6, 6, 8, 8, 10, 12, 16, 20, 24, 28, 34, 42, 50, 54, 76, 158}, - {0, 4 * 3, 8 * 3, 12 * 3, 16 * 3, 22 * 3, 30 * 3, 40 * 3, 52 * 3, 66 * 3, 84 * 3, 106 * 3, 136 * 3, 192 * 3}, - {4, 4, 4, 4, 6, 8, 10, 12, 14, 18, 22, 30, 56} }, - - { {0, 4, 8, 12, 16, 20, 24, 30, 36, 42, 50, 60, 72, 88, 106, 128, 156, 190, 230, 276, 330, 384, 576}, - {4, 4, 4, 4, 4, 4, 6, 6, 6, 8, 10, 12, 16, 18, 22, 28, 34, 40, 46, 54, 54, 192}, - {0, 4 * 3, 8 * 3, 12 * 3, 16 * 3, 22 * 3, 28 * 3, 38 * 3, 50 * 3, 64 * 3, 80 * 3, 100 * 3, 126 * 3, 192 * 3}, - {4, 4, 4, 4, 6, 6, 10, 12, 14, 16, 20, 26, 66} }, - - { {0, 4, 8, 12, 16, 20, 24, 30, 36, 44, 54, 66, 82, 102, 126, 156, 194, 240, 296, 364, 448, 550, 576}, - {4, 4, 4, 4, 4, 4, 6, 6, 8, 10, 12, 16, 20, 24, 30, 38, 46, 56, 68, 84, 102, 26}, - {0, 4 * 3, 8 * 3, 12 * 3, 16 * 3, 22 * 3, 30 * 3, 42 * 3, 58 * 3, 78 * 3, 104 * 3, 138 * 3, 180 * 3, 192 * 3}, - {4, 4, 4, 4, 6, 8, 12, 16, 20, 26, 34, 42, 12} }, - - { {0, 6, 12, 18, 24, 30, 36, 44, 54, 66, 80, 96, 116, 140, 168, 200, 238, 284, 336, 396, 464, 522, 576}, - {6, 6, 6, 6, 6, 6, 8, 10, 12, 14, 16, 20, 24, 28, 32, 38, 46, 52, 60, 68, 58, 54 }, - {0, 4 * 3, 8 * 3, 12 * 3, 18 * 3, 24 * 3, 32 * 3, 42 * 3, 56 * 3, 74 * 3, 100 * 3, 132 * 3, 174 * 3, 192 * 3}, - {4, 4, 4, 6, 6, 8, 10, 14, 18, 26, 32, 42, 18 } }, - - { {0, 6, 12, 18, 24, 30, 36, 44, 54, 66, 80, 96, 114, 136, 162, 194, 232, 278, 332, 394, 464, 540, 576}, - {6, 6, 6, 6, 6, 6, 8, 10, 12, 14, 16, 18, 22, 26, 32, 38, 46, 54, 62, 70, 76, 36 }, - {0, 4 * 3, 8 * 3, 12 * 3, 18 * 3, 26 * 3, 36 * 3, 48 * 3, 62 * 3, 80 * 3, 104 * 3, 136 * 3, 180 * 3, 192 * 3}, - {4, 4, 4, 6, 8, 10, 12, 14, 18, 24, 32, 44, 12 } }, - - { {0, 6, 12, 18, 24, 30, 36, 44, 54, 66, 80, 96, 116, 140, 168, 200, 238, 284, 336, 396, 464, 522, 576}, - {6, 6, 6, 6, 6, 6, 8, 10, 12, 14, 16, 20, 24, 28, 32, 38, 46, 52, 60, 68, 58, 54 }, - {0, 4 * 3, 8 * 3, 12 * 3, 18 * 3, 26 * 3, 36 * 3, 48 * 3, 62 * 3, 80 * 3, 104 * 3, 134 * 3, 174 * 3, 192 * 3}, - {4, 4, 4, 6, 8, 10, 12, 14, 18, 24, 30, 40, 18 } }, - - { {0, 6, 12, 18, 24, 30, 36, 44, 54, 66, 80, 96, 116, 140, 168, 200, 238, 284, 336, 396, 464, 522, 576}, - {6, 6, 6, 6, 6, 6, 8, 10, 12, 14, 16, 20, 24, 28, 32, 38, 46, 52, 60, 68, 58, 54}, - {0, 12, 24, 36, 54, 78, 108, 144, 186, 240, 312, 402, 522, 576}, - {4, 4, 4, 6, 8, 10, 12, 14, 18, 24, 30, 40, 18} }, - - { {0, 6, 12, 18, 24, 30, 36, 44, 54, 66, 80, 96, 116, 140, 168, 200, 238, 284, 336, 396, 464, 522, 576}, - {6, 6, 6, 6, 6, 6, 8, 10, 12, 14, 16, 20, 24, 28, 32, 38, 46, 52, 60, 68, 58, 54}, - {0, 12, 24, 36, 54, 78, 108, 144, 186, 240, 312, 402, 522, 576}, - {4, 4, 4, 6, 8, 10, 12, 14, 18, 24, 30, 40, 18} }, - - { {0, 12, 24, 36, 48, 60, 72, 88, 108, 132, 160, 192, 232, 280, 336, 400, 476, 566, 568, 570, 572, 574, 576}, - {12, 12, 12, 12, 12, 12, 16, 20, 24, 28, 32, 40, 48, 56, 64, 76, 90, 2, 2, 2, 2, 2}, - {0, 24, 48, 72, 108, 156, 216, 288, 372, 480, 486, 492, 498, 576}, - {8, 8, 8, 12, 16, 20, 24, 28, 36, 2, 2, 2, 26} } -}; - -const double decodeWindow[] = -{ - 0.000000000, -0.000015259, -0.000015259, -0.000015259, -0.000015259, -0.000015259, -0.000015259, -0.000030518, - -0.000030518, -0.000030518, -0.000030518, -0.000045776, -0.000045776, -0.000061035, -0.000061035, -0.000076294, - -0.000076294, -0.000091553, -0.000106812, -0.000106812, -0.000122070, -0.000137329, -0.000152588, -0.000167847, - -0.000198364, -0.000213623, -0.000244141, -0.000259399, -0.000289917, -0.000320435, -0.000366211, -0.000396729, - -0.000442505, -0.000473022, -0.000534058, -0.000579834, -0.000625610, -0.000686646, -0.000747681, -0.000808716, - -0.000885010, -0.000961304, -0.001037598, -0.001113892, -0.001205444, -0.001296997, -0.001388550, -0.001480103, - -0.001586914, -0.001693726, -0.001785278, -0.001907349, -0.002014160, -0.002120972, -0.002243042, -0.002349854, - -0.002456665, -0.002578735, -0.002685547, -0.002792358, -0.002899170, -0.002990723, -0.003082275, -0.003173828, - -0.003250122, -0.003326416, -0.003387451, -0.003433228, -0.003463745, -0.003479004, -0.003479004, -0.003463745, - -0.003417969, -0.003372192, -0.003280640, -0.003173828, -0.003051758, -0.002883911, -0.002700806, -0.002487183, - -0.002227783, -0.001937866, -0.001617432, -0.001266479, -0.000869751, -0.000442505, 0.000030518, 0.000549316, - 0.001098633, 0.001693726, 0.002334595, 0.003005981, 0.003723145, 0.004486084, 0.005294800, 0.006118774, - 0.007003784, 0.007919312, 0.008865356, 0.009841919, 0.010848999, 0.011886597, 0.012939453, 0.014022827, - 0.015121460, 0.016235352, 0.017349243, 0.018463135, 0.019577026, 0.020690918, 0.021789551, 0.022857666, - 0.023910522, 0.024932861, 0.025909424, 0.026840210, 0.027725220, 0.028533936, 0.029281616, 0.029937744, - 0.030532837, 0.031005859, 0.031387329, 0.031661987, 0.031814575, 0.031845093, 0.031738281, 0.031478882, - 0.031082153, 0.030517578, 0.029785156, 0.028884888, 0.027801514, 0.026535034, 0.025085449, 0.023422241, - 0.021575928, 0.019531250, 0.017257690, 0.014801025, 0.012115479, 0.009231567, 0.006134033, 0.002822876, - -0.000686646, -0.004394531, -0.008316040, -0.012420654, -0.016708374, -0.021179199, -0.025817871, -0.030609131, - -0.035552979, -0.040634155, -0.045837402, -0.051132202, -0.056533813, -0.061996460, -0.067520142, -0.073059082, - -0.078628540, -0.084182739, -0.089706421, -0.095169067, -0.100540161, -0.105819702, -0.110946655, -0.115921021, - -0.120697021, -0.125259399, -0.129562378, -0.133590698, -0.137298584, -0.140670776, -0.143676758, -0.146255493, - -0.148422241, -0.150115967, -0.151306152, -0.151962280, -0.152069092, -0.151596069, -0.150497437, -0.148773193, - -0.146362305, -0.143264771, -0.139450073, -0.134887695, -0.129577637, -0.123474121, -0.116577148, -0.108856201, - -0.100311279, -0.090927124, -0.080688477, -0.069595337, -0.057617187, -0.044784546, -0.031082153, -0.016510010, - -0.001068115, 0.015228271, 0.032379150, 0.050354004, 0.069168091, 0.088775635, 0.109161377, 0.130310059, - 0.152206421, 0.174789429, 0.198059082, 0.221984863, 0.246505737, 0.271591187, 0.297210693, 0.323318481, - 0.349868774, 0.376800537, 0.404083252, 0.431655884, 0.459472656, 0.487472534, 0.515609741, 0.543823242, - 0.572036743, 0.600219727, 0.628295898, 0.656219482, 0.683914185, 0.711318970, 0.738372803, 0.765029907, - 0.791213989, 0.816864014, 0.841949463, 0.866363525, 0.890090942, 0.913055420, 0.935195923, 0.956481934, - 0.976852417, 0.996246338, 1.014617920, 1.031936646, 1.048156738, 1.063217163, 1.077117920, 1.089782715, - 1.101211548, 1.111373901, 1.120223999, 1.127746582, 1.133926392, 1.138763428, 1.142211914, 1.144287109, - 1.144989014 -}; - -const int16 huffmanTab0[] = { 0 }; -const int16 huffmanTab1[] = { -5,-3,-1,17,1,16,0 }; -const int16 huffmanTab2[] = { -15,-11,-9,-5,-3,-1,34,2,18,-1,33,32,17,-1,1,16,0 }; -const int16 huffmanTab3[] = { -13,-11,-9,-5,-3,-1,34,2,18,-1,33,32,16,17,-1,1,0 }; -const int16 huffmanTab5[] = { -29,-25,-23,-15,-7,-5,-3,-1,51,35,50,49,-3,-1,19,3,-1,48,34,-3,-1,18,33,-1,2,32,17,-1,1,16,0 }; -const int16 huffmanTab6[] = { -25,-19,-13,-9,-5,-3,-1,51,3,35,-1,50,48,-1,19,49,-3,-1,34,2,18,-3,-1,33,32,1,-1,17,-1,16,0 }; - -const int16 huffmanTab7[] = -{ - -69,-65,-57,-39,-29,-17,-11,-7,-3,-1,85,69,-1,84,83,-1,53,68,-3,-1,37,82,21,-5,-1,81,-1,5,52,-1,80,-1,67,51, - -5,-3,-1,36,66,20,-1,65,64,-11,-7,-3,-1,4,35,-1,50,3,-1,19,49,-3,-1,48,34,18,-5,-1,33,-1,2,32,17,-1,1,16,0 -}; - -const int16 huffmanTab8[] = -{ - -65,-63,-59,-45,-31,-19,-13,-7,-5,-3,-1,85,84,69,83,-3,-1,53,68,37,-3,-1,82,5,21,-5,-1,81,-1,52,67,-3,-1,80, - 51,36,-5,-3,-1,66,20,65,-3,-1,4,64,-1,35,50,-9,-7,-3,-1,19,49,-1,3,48,34,-1,2,32,-1,18,33,17,-3,-1,1,16,0 -}; - -const int16 huffmanTab9[] = -{ - -63,-53,-41,-29,-19,-11,-5,-3,-1,85,69,53,-1,83,-1,84,5,-3,-1,68,37,-1,82,21,-3,-1,81,52,-1,67,-1,80,4,-7,-3, - -1,36,66,-1,51,64,-1,20,65,-5,-3,-1,35,50,19,-1,49,-1,3,48,-5,-3,-1,34,2,18,-1,33,32,-3,-1,17,1,-1,16,0 -}; - -const int16 huffmanTab10[] = -{ - -125,-121,-111,-83,-55,-35,-21,-13,-7,-3,-1,119,103,-1,118,87,-3,-1,117,102,71,-3,-1,116,86,-1,101,55,-9,-3, - -1,115,70,-3,-1,85,84,99,-1,39,114,-11,-5,-3,-1,100,7,112,-1,98,-1,69,53,-5,-1,6,-1,83,68,23,-17,-5,-1,113, - -1,54,38,-5,-3,-1,37,82,21,-1,81,-1,52,67,-3,-1,22,97,-1,96,-1,5,80,-19,-11,-7,-3,-1,36,66,-1,51,4,-1,20, - 65,-3,-1,64,35,-1,50,3,-3,-1,19,49,-1,48,34,-7,-3,-1,18,33,-1,2,32,17,-1,1,16,0 -}; - -const int16 huffmanTab11[] = -{ - -121,-113,-89,-59,-43,-27,-17,-7,-3,-1,119,103,-1,118,117,-3,-1,102,71,-1,116,-1,87,85,-5,-3,-1,86,101,55, - -1,115,70,-9,-7,-3,-1,69,84,-1,53,83,39,-1,114,-1,100,7,-5,-1,113,-1,23,112,-3,-1,54,99,-1,96,-1,68,37,-13, - -7,-5,-3,-1,82,5,21,98,-3,-1,38,6,22,-5,-1,97,-1,81,52,-5,-1,80,-1,67,51,-1,36,66,-15,-11,-7,-3,-1,20,65, - -1,4,64,-1,35,50,-1,19,49,-5,-3,-1,3,48,34,33,-5,-1,18,-1,2,32,17,-3,-1,1,16,0 -}; - -const int16 huffmanTab12[] = -{ - -115,-99,-73,-45,-27,-17,-9,-5,-3,-1,119,103,118,-1,87,117,-3,-1,102,71,-1,116,101,-3,-1,86,55,-3,-1,115, - 85,39,-7,-3,-1,114,70,-1,100,23,-5,-1,113,-1,7,112,-1,54,99,-13,-9,-3,-1,69,84,-1,68,-1,6,5,-1,38,98,-5, - -1,97,-1,22,96,-3,-1,53,83,-1,37,82,-17,-7,-3,-1,21,81,-1,52,67,-5,-3,-1,80,4,36,-1,66,20,-3,-1,51,65,-1, - 35,50,-11,-7,-5,-3,-1,64,3,48,19,-1,49,34,-1,18,33,-7,-5,-3,-1,2,32,0,17,-1,1,16 -}; - -const int16 huffmanTab13[] = -{ - -509,-503,-475,-405,-333,-265,-205,-153,-115,-83,-53,-35,-21,-13,-9,-7,-5,-3,-1,254,252,253,237,255,-1,239,223, - -3,-1,238,207,-1,222,191,-9,-3,-1,251,206,-1,220,-1,175,233,-1,236,221,-9,-5,-3,-1,250,205,190,-1,235,159,-3, - -1,249,234,-1,189,219,-17,-9,-3,-1,143,248,-1,204,-1,174,158,-5,-1,142,-1,127,126,247,-5,-1,218,-1,173,188,-3, - -1,203,246,111,-15,-7,-3,-1,232,95,-1,157,217,-3,-1,245,231,-1,172,187,-9,-3,-1,79,244,-3,-1,202,230,243,-1, - 63,-1,141,216,-21,-9,-3,-1,47,242,-3,-1,110,156,15,-5,-3,-1,201,94,171,-3,-1,125,215,78,-11,-5,-3,-1,200,214, - 62,-1,185,-1,155,170,-1,31,241,-23,-13,-5,-1,240,-1,186,229,-3,-1,228,140,-1,109,227,-5,-1,226,-1,46,14,-1,30, - 225,-15,-7,-3,-1,224,93,-1,213,124,-3,-1,199,77,-1,139,184,-7,-3,-1,212,154,-1,169,108,-1,198,61,-37,-21,-9,-5, - -3,-1,211,123,45,-1,210,29,-5,-1,183,-1,92,197,-3,-1,153,122,195,-7,-5,-3,-1,167,151,75,209,-3,-1,13,208,-1, - 138,168,-11,-7,-3,-1,76,196,-1,107,182,-1,60,44,-3,-1,194,91,-3,-1,181,137,28,-43,-23,-11,-5,-1,193,-1,152,12, - -1,192,-1,180,106,-5,-3,-1,166,121,59,-1,179,-1,136,90,-11,-5,-1,43,-1,165,105,-1,164,-1,120,135,-5,-1,148,-1, - 119,118,178,-11,-3,-1,27,177,-3,-1,11,176,-1,150,74,-7,-3,-1,58,163,-1,89,149,-1,42,162,-47,-23,-9,-3,-1,26, - 161,-3,-1,10,104,160,-5,-3,-1,134,73,147,-3,-1,57,88,-1,133,103,-9,-3,-1,41,146,-3,-1,87,117,56,-5,-1,131,-1, - 102,71,-3,-1,116,86,-1,101,115,-11,-3,-1,25,145,-3,-1,9,144,-1,72,132,-7,-5,-1,114,-1,70,100,40,-1,130,24,-41, - -27,-11,-5,-3,-1,55,39,23,-1,113,-1,85,7,-7,-3,-1,112,54,-1,99,69,-3,-1,84,38,-1,98,53,-5,-1,129,-1,8,128,-3, - -1,22,97,-1,6,96,-13,-9,-5,-3,-1,83,68,37,-1,82,5,-1,21,81,-7,-3,-1,52,67,-1,80,36,-3,-1,66,51,20,-19,-11, - -5,-1,65,-1,4,64,-3,-1,35,50,19,-3,-1,49,3,-1,48,34,-3,-1,18,33,-1,2,32,-3,-1,17,1,16,0 -}; - -const int16 huffmanTab15[] = -{ - -495,-445,-355,-263,-183,-115,-77,-43,-27,-13,-7,-3,-1,255,239,-1,254,223,-1,238,-1,253,207,-7,-3,-1,252,222,-1, - 237,191,-1,251,-1,206,236,-7,-3,-1,221,175,-1,250,190,-3,-1,235,205,-1,220,159,-15,-7,-3,-1,249,234,-1,189,219, - -3,-1,143,248,-1,204,158,-7,-3,-1,233,127,-1,247,173,-3,-1,218,188,-1,111,-1,174,15,-19,-11,-3,-1,203,246, - -3,-1,142,232,-1,95,157,-3,-1,245,126,-1,231,172,-9,-3,-1,202,187,-3,-1,217,141,79,-3,-1,244,63,-1,243,216, - -33,-17,-9,-3,-1,230,47,-1,242,-1,110,240,-3,-1,31,241,-1,156,201,-7,-3,-1,94,171,-1,186,229,-3,-1,125,215, - -1,78,228,-15,-7,-3,-1,140,200,-1,62,109,-3,-1,214,227,-1,155,185,-7,-3,-1,46,170,-1,226,30,-5,-1,225,-1,14, - 224,-1,93,213,-45,-25,-13,-7,-3,-1,124,199,-1,77,139,-1,212,-1,184,154,-7,-3,-1,169,108,-1,198,61,-1,211,210, - -9,-5,-3,-1,45,13,29,-1,123,183,-5,-1,209,-1,92,208,-1,197,138,-17,-7,-3,-1,168,76,-1,196,107,-5,-1,182,-1, - 153,12,-1,60,195,-9,-3,-1,122,167,-1,166,-1,192,11,-1,194,-1,44,91,-55,-29,-15,-7,-3,-1,181,28,-1,137,152,-3, - -1,193,75,-1,180,106,-5,-3,-1,59,121,179,-3,-1,151,136,-1,43,90,-11,-5,-1,178,-1,165,27,-1,177,-1,176,105,-7, - -3,-1,150,74,-1,164,120,-3,-1,135,58,163,-17,-7,-3,-1,89,149,-1,42,162,-3,-1,26,161,-3,-1,10,160,104,-7,-3, - -1,134,73,-1,148,57,-5,-1,147,-1,119,9,-1,88,133,-53,-29,-13,-7,-3,-1,41,103,-1,118,146,-1,145,-1,25,144,-7, - -3,-1,72,132,-1,87,117,-3,-1,56,131,-1,102,71,-7,-3,-1,40,130,-1,24,129,-7,-3,-1,116,8,-1,128,86,-3,-1,101, - 55,-1,115,70,-17,-7,-3,-1,39,114,-1,100,23,-3,-1,85,113,-3,-1,7,112,54,-7,-3,-1,99,69,-1,84,38,-3,-1,98,22, - -3,-1,6,96,53,-33,-19,-9,-5,-1,97,-1,83,68,-1,37,82,-3,-1,21,81,-3,-1,5,80,52,-7,-3,-1,67,36,-1,66,51,-1, - 65,-1,20,4,-9,-3,-1,35,50,-3,-1,64,3,19,-3,-1,49,48,34,-9,-7,-3,-1,18,33,-1,2,32,17,-3,-1,1,16,0 -}; - -const int16 huffmanTab16[] = -{ - -509,-503,-461,-323,-103,-37,-27,-15,-7,-3,-1,239,254,-1,223,253,-3,-1,207,252,-1,191,251,-5,-1,175,-1,250,159, - -3,-1,249,248,143,-7,-3,-1,127,247,-1,111,246,255,-9,-5,-3,-1,95,245,79,-1,244,243,-53,-1,240,-1,63,-29,-19, - -13,-7,-5,-1,206,-1,236,221,222,-1,233,-1,234,217,-1,238,-1,237,235,-3,-1,190,205,-3,-1,220,219,174,-11,-5, - -1,204,-1,173,218,-3,-1,126,172,202,-5,-3,-1,201,125,94,189,242,-93,-5,-3,-1,47,15,31,-1,241,-49,-25,-13, - -5,-1,158,-1,188,203,-3,-1,142,232,-1,157,231,-7,-3,-1,187,141,-1,216,110,-1,230,156,-13,-7,-3,-1,171,186, - -1,229,215,-1,78,-1,228,140,-3,-1,200,62,-1,109,-1,214,155,-19,-11,-5,-3,-1,185,170,225,-1,212,-1,184,169, - -5,-1,123,-1,183,208,227,-7,-3,-1,14,224,-1,93,213,-3,-1,124,199,-1,77,139,-75,-45,-27,-13,-7,-3,-1,154, - 108,-1,198,61,-3,-1,92,197,13,-7,-3,-1,138,168,-1,153,76,-3,-1,182,122,60,-11,-5,-3,-1,91,137,28,-1,192,-1, - 152,121,-1,226,-1,46,30,-15,-7,-3,-1,211,45,-1,210,209,-5,-1,59,-1,151,136,29,-7,-3,-1,196,107,-1,195,167,-1, - 44,-1,194,181,-23,-13,-7,-3,-1,193,12,-1,75,180,-3,-1,106,166,179,-5,-3,-1,90,165,43,-1,178,27,-13,-5,-1,177, - -1,11,176,-3,-1,105,150,-1,74,164,-5,-3,-1,120,135,163,-3,-1,58,89,42,-97,-57,-33,-19,-11,-5,-3,-1,149,104,161, - -3,-1,134,119,148,-5,-3,-1,73,87,103,162,-5,-1,26,-1,10,160,-3,-1,57,147,-1,88,133,-9,-3,-1,41,146,-3,-1,118, - 9,25,-5,-1,145,-1,144,72,-3,-1,132,117,-1,56,131,-21,-11,-5,-3,-1,102,40,130,-3,-1,71,116,24,-3,-1,129,128,-3, - -1,8,86,55,-9,-5,-1,115,-1,101,70,-1,39,114,-5,-3,-1,100,85,7,23,-23,-13,-5,-1,113,-1,112,54,-3,-1,99,69,-1, - 84,38,-3,-1,98,22,-1,97,-1,6,96,-9,-5,-1,83,-1,53,68,-1,37,82,-1,81,-1,21,5,-33,-23,-13,-7,-3,-1,52,67,-1,80, - 36,-3,-1,66,51,20,-5,-1,65,-1,4,64,-1,35,50,-3,-1,19,49,-3,-1,3,48,34,-3,-1,18,33,-1,2,32,-3,-1,17,1,16,0 -}; - -const int16 huffmanTab24[] = -{ - -451,-117,-43,-25,-15,-7,-3,-1,239,254,-1,223,253,-3,-1,207,252,-1,191,251,-5,-1,250,-1,175,159,-1,249,248,-9, - -5,-3,-1,143,127,247,-1,111,246,-3,-1,95,245,-1,79,244,-71,-7,-3,-1,63,243,-1,47,242,-5,-1,241,-1,31,240,-25,-9, - -1,15,-3,-1,238,222,-1,237,206,-7,-3,-1,236,221,-1,190,235,-3,-1,205,220,-1,174,234,-15,-7,-3,-1,189,219,-1,204, - 158,-3,-1,233,173,-1,218,188,-7,-3,-1,203,142,-1,232,157,-3,-1,217,126,-1,231,172,255,-235,-143,-77,-45,-25,-15, - -7,-3,-1,202,187,-1,141,216,-5,-3,-1,14,224,13,230,-5,-3,-1,110,156,201,-1,94,186,-9,-5,-1,229,-1,171,125,-1,215, - 228,-3,-1,140,200,-3,-1,78,46,62,-15,-7,-3,-1,109,214,-1,227,155,-3,-1,185,170,-1,226,30,-7,-3,-1,225,93,-1,213,124, - -3,-1,199,77,-1,139,184,-31,-15,-7,-3,-1,212,154,-1,169,108,-3,-1,198,61,-1,211,45,-7,-3,-1,210,29,-1,123,183,-3,-1, - 209,92,-1,197,138,-17,-7,-3,-1,168,153,-1,76,196,-3,-1,107,182,-3,-1,208,12,60,-7,-3,-1,195,122,-1,167,44,-3,-1,194, - 91,-1,181,28,-57,-35,-19,-7,-3,-1,137,152,-1,193,75,-5,-3,-1,192,11,59,-3,-1,176,10,26,-5,-1,180,-1,106,166,-3,-1,121, - 151,-3,-1,160,9,144,-9,-3,-1,179,136,-3,-1,43,90,178,-7,-3,-1,165,27,-1,177,105,-1,150,164,-17,-9,-5,-3,-1,74,120,135, - -1,58,163,-3,-1,89,149,-1,42,162,-7,-3,-1,161,104,-1,134,119,-3,-1,73,148,-1,57,147,-63,-31,-15,-7,-3,-1,88,133,-1,41, - 103,-3,-1,118,146,-1,25,145,-7,-3,-1,72,132,-1,87,117,-3,-1,56,131,-1,102,40,-17,-7,-3,-1,130,24,-1,71,116,-5,-1,129, - -1,8,128,-1,86,101,-7,-5,-1,23,-1,7,112,115,-3,-1,55,39,114,-15,-7,-3,-1,70,100,-1,85,113,-3,-1,54,99,-1,69,84,-7,-3, - -1,38,98,-1,22,97,-5,-3,-1,6,96,53,-1,83,68,-51,-37,-23,-15,-9,-3,-1,37,82,-1,21,-1,5,80,-1,81,-1,52,67,-3,-1,36,66, - -1,51,20,-9,-5,-1,65,-1,4,64,-1,35,50,-1,19,49,-7,-5,-3,-1,3,48,34,18,-1,33,-1,2,32,-3,-1,17,1,-1,16,0 -}; - -struct BitsToTableMap -{ - uint32 bits; - const int16* table; -}; - -const BitsToTableMap huffmanTables1[] = -{ - { 0, huffmanTab0 }, { 0, huffmanTab1 }, { 0, huffmanTab2 }, { 0, huffmanTab3 }, - { 0, huffmanTab0 }, { 0, huffmanTab5 }, { 0, huffmanTab6 }, { 0, huffmanTab7 }, - { 0, huffmanTab8 }, { 0, huffmanTab9 }, { 0, huffmanTab10 }, { 0, huffmanTab11 }, - { 0, huffmanTab12 }, { 0, huffmanTab13 }, { 0, huffmanTab0 }, { 0, huffmanTab15 }, - { 1, huffmanTab16 }, { 2, huffmanTab16 }, { 3, huffmanTab16 }, { 4, huffmanTab16 }, - { 6, huffmanTab16 }, { 8, huffmanTab16 }, { 10, huffmanTab16 }, { 13, huffmanTab16 }, - { 4, huffmanTab24 }, { 5, huffmanTab24 }, { 6, huffmanTab24 }, { 7, huffmanTab24 }, - { 8, huffmanTab24 }, { 9, huffmanTab24 }, { 11, huffmanTab24 }, { 13, huffmanTab24 } -}; - -const int16 huffmanTabC0[] = { -29,-21,-13,-7,-3,-1,11,15,-1,13,14,-3,-1,7,5,9,-3,-1,6,3,-1,10,12,-3,-1,2,1,-1,4,8,0 }; -const int16 huffmanTabC1[] = { -15,-7,-3,-1,15,14,-1,13,12,-3,-1,11,10,-1,9,8,-7,-3,-1,7,6,-1,5,4,-3,-1,3,2,-1,1,0 }; - -const BitsToTableMap huffmanTables2[] = { { 0, huffmanTabC0 }, { 0, huffmanTabC1 } }; - -//============================================================================== -struct VBRTagData -{ - bool read (const uint8* data) noexcept - { - flags = 0; - - const int layer = (data[1] >> 1) & 3; - if (layer != 1) - return false; - - const int type = (data[1] >> 3) & 1; - const int sampleRateIndex = (data[2] >> 2) & 3; - const int mode = (data[3] >> 6) & 3; - - static const int bitRates[3][16] = - { - { 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, -1 }, // MPEG2 - { 0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, -1 }, // MPEG1 - { 0, 8, 16, 24, 32, 40, 48, 56, 64, -1, -1, -1, -1, -1, -1, -1 }, // MPEG 2.5 - }; - - const int bitrate = bitRates[type][((data[2] >> 4) & 15)]; - - const int sampleRates[3][4] = - { - { 22050, 24000, 16000, -1 }, // MPEG2 - { 44100, 48000, 32000, -1 }, // MPEG1 - { 11025, 12000, 8000, -1 }, // MPEG2.5 - }; - - if ((data[1] >> 4) == 0xe) - sampleRate = sampleRates[2][sampleRateIndex]; - else - sampleRate = sampleRates[type][sampleRateIndex]; - - data += type != 0 ? (mode != 3 ? (32 + 4) : (17 + 4)) - : (mode != 3 ? (17 + 4) : (9 + 4)); - - if (! isVbrTag (data)) - return false; - - data += 4; - flags = ByteOrder::bigEndianInt (data); - data += 4; - - if (flags & 1) - { - frames = ByteOrder::bigEndianInt (data); - data += 4; - } - - if (flags & 2) - { - bytes = ByteOrder::bigEndianInt (data); - data += 4; - } - - if (flags & 4) - { - if (toc != nullptr) - for (int i = 0; i < 100; ++i) - toc[i] = data[i]; - - data += 100; - } - - vbrScale = -1; - - if (flags & 8) - vbrScale = (int) ByteOrder::bigEndianInt (data); - - headersize = ((type + 1) * 72000 * bitrate) / sampleRate; - return true; - } - - uint8 toc[100]; - int sampleRate, vbrScale, headersize; - unsigned int flags, frames, bytes; - -private: - static bool isVbrTag (const uint8* const d) noexcept - { - return (d[0] == 'X' && d[1] == 'i' && d[2] == 'n' && d[3] == 'g') - || (d[0] == 'I' && d[1] == 'n' && d[2] == 'f' && d[3] == 'o'); - } -}; - -//============================================================================== -struct MP3Frame -{ - MP3Frame() - { - zeromem (this, sizeof (MP3Frame)); - single = -1; - } - - void selectLayer2Table() - { - static const int translate[3][2][16] = - { - { { 0, 2, 2, 2, 2, 2, 2, 0, 0, 0, 1, 1, 1, 1, 1, 0 }, { 0, 2, 2, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 } }, - { { 0, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, - { { 0, 3, 3, 3, 3, 3, 3, 0, 0, 0, 1, 1, 1, 1, 1, 0 }, { 0, 3, 3, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 } } - }; - - static const AllocationTable* const tables[] = { allocTable0, allocTable1, allocTable2, allocTable3, allocTable4 }; - static const int limits[] = { 27, 30, 8, 12, 30 }; - - const int index = lsf ? 4 : translate[sampleRateIndex][2 - numChannels][bitrateIndex]; - layer2SubBandLimit = limits [index]; - allocationTable = tables [index]; - } - - int getFrequency() const noexcept - { - const int frequencies[] = { 44100, 48000, 32000, 22050, 24000, 16000, 11025, 12000, 8000 }; - return frequencies [sampleRateIndex]; - } - - void decodeHeader (const uint32 header) - { - jassert (((header >> 10) & 3) != 3); - - mpeg25 = (header & (1 << 20)) == 0; - lsf = mpeg25 ? 1 : ((header & (1 << 19)) ? 0 : 1); - layer = 4 - ((header >> 17) & 3); - sampleRateIndex = mpeg25 ? (6 + ((header >> 10) & 3)) : ((int) ((header >> 10) & 3) + (lsf * 3)); - crc16FollowsHeader = ((header >> 16) & 1) == 0; - bitrateIndex = (header >> 12) & 15; - padding = (header >> 9) & 1; - mode = (header >> 6) & 3; - modeExt = (header >> 4) & 3; - //extension = (header >> 8) & 1; - //copyright = (header >> 3) & 1; - //original = (header >> 2) & 1; - //emphasis = header & 3; - numChannels = (mode == 3) ? 1 : 2; - - static const int frameSizes [2][3][16] = - { - { { 0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448 }, - { 0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384 }, - { 0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320 } }, - - { { 0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256 }, - { 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160 }, - { 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160 } } - }; - - if (bitrateIndex == 0) - { - jassertfalse; // This means the file is using "free format". Apparently very few decoders - // support this mode, and this one certainly doesn't handle it correctly! - frameSize = 0; - } - else - { - switch (layer) - { - case 1: frameSize = (((frameSizes[lsf][0][bitrateIndex] * 12000) / getFrequency() + padding) * 4) - 4; break; - case 2: frameSize = (frameSizes[lsf][1][bitrateIndex] * 144000) / getFrequency() + (padding - 4); break; - case 3: frameSize = (bitrateIndex == 0) ? 0 : ((frameSizes[lsf][2][bitrateIndex] * 144000) / (getFrequency() << lsf) + (padding - 4)); break; - default: break; - } - } - } - - int layer, frameSize, numChannels, single; - int lsf; // 0 = mpeg-1, 1 = mpeg-2/LSF - bool mpeg25; // true = mpeg-2.5, false = mpeg-1/2 - bool crc16FollowsHeader; - int bitrateIndex, sampleRateIndex, padding; - int mode, modeExt, layer2SubBandLimit; - enum { downSampleLimit = 32 }; - const AllocationTable* allocationTable; -}; - -//============================================================================== -struct Constants -{ - Constants() - { - cosTables[0] = cos64; cosTables[1] = cos32; cosTables[2] = cos16; cosTables[3] = cos8; cosTables[4] = cos4; - initDecodeTables(); - initLayer2Tables(); - initLayer3Tables(); - } - - const uint8* getGroupTable (const int16 d1, const uint32 index) const noexcept - { - switch (d1) - { - case 3: return &group3tab [3 * jmin (index, 3u * 3u * 3u)]; - case 5: return &group5tab [3 * jmin (index, 5u * 5u * 5u)]; - case 9: return &group9tab [3 * jmin (index, 9u * 9u * 9u)]; - default: break; - } - - static const uint8 dummy[] = { 0, 0, 0 }; - return dummy; - } - - float muls[27][64]; - float nToThe4Over3[8207]; - float antiAliasingCa[8], antiAliasingCs[8]; - float win[4][36]; - float win1[4][36]; - float powToGains[256 + 118 + 4]; - int longLimit[9][23]; - int shortLimit[9][14]; - float tan1_1[16], tan2_1[16], tan1_2[16], tan2_2[16]; - float pow1_1[2][16], pow2_1[2][16], pow1_2[2][16], pow2_2[2][16]; - int* map[9][3]; - int* mapEnd[9][3]; - uint32 nLength2[512]; - uint32 iLength2[256]; - float decodeWin[512 + 32]; - float* cosTables[5]; - -private: - int mapbuf0[9][152]; - int mapbuf1[9][156]; - int mapbuf2[9][44]; - float cos64[16], cos32[8], cos16[4], cos8[2], cos4[1]; - uint8 group3tab [32 * 3]; - uint8 group5tab [128 * 3]; - uint8 group9tab [1024 * 3]; - - void initDecodeTables() - { - int i, j, scaleval = -1; - float* table = decodeWin; - - for (i = 0; i < 5; ++i) - { - int kr = 0x10 >> i; - int divv = 0x40 >> i; - float* costab = cosTables[i]; - - for (int k = 0; k < kr; ++k) - costab[k] = (float) (1.0 / (2.0 * cos (double_Pi * (k * 2 + 1) / divv))); - } - - for (i = 0, j = 0; i < 256; ++i, ++j, table += 32) - { - if (table < decodeWin + 512 + 16) - table[16] = table[0] = (float) (decodeWindow[j] * scaleval); - if (i % 32 == 31) - table -= 1023; - if (i % 64 == 63) - scaleval = -scaleval; - } - - for (; i < 512; ++i, --j, table += 32) - { - if (table < decodeWin + 512 + 16) - table[16] = table[0] = (float) (decodeWindow[j] * scaleval); - - if (i % 32 == 31) table -= 1023; - if (i % 64 == 63) scaleval = -scaleval; - } - } - - void initLayer2Tables() - { - static const uint8 base[3][9] = - { - { 1, 0, 2 }, - { 17, 18, 0, 19, 20 }, - { 21, 1, 22, 23, 0, 24, 25, 2, 26 } - }; - - static const int tableLengths[] = { 3, 5, 9 }; - static uint8* tables[] = { group3tab, group5tab, group9tab }; - - for (int i = 0; i < 3; ++i) - { - uint8* table = tables[i]; - const int len = tableLengths[i]; - - for (int j = 0; j < len; ++j) - for (int k = 0; k < len; ++k) - for (int l = 0; l < len; ++l) - { - *table++ = base[i][l]; - *table++ = base[i][k]; - *table++ = base[i][j]; - } - } - - for (int k = 0; k < 27; ++k) - { - static const double multipliers[] = - { - 0, -2.0 / 3.0, 2.0 / 3.0, 2.0 / 7.0, 2.0 / 15.0, 2.0 / 31.0, 2.0 / 63.0, 2.0 / 127.0, 2.0 / 255.0, - 2.0 / 511.0, 2.0 / 1023.0, 2.0 / 2047.0, 2.0 / 4095.0, 2.0 / 8191.0, 2.0 / 16383.0, 2.0 / 32767.0, 2.0 / 65535.0, - -4.0 / 5.0, -2.0 / 5.0, 2.0 / 5.0, 4.0 / 5.0, -8.0 / 9.0, -4.0 / 9.0, -2.0 / 9.0, 2.0 / 9.0, 4.0 / 9.0, 8.0 / 9.0 - }; - - float* table = muls[k]; - for (int j = 3, i = 0; i < 63; ++i, --j) - *table++ = (float) (multipliers[k] * pow (2.0, j / 3.0)); - *table++ = 0; - } - } - - void initLayer3Tables() - { - int i, j; - for (i = -256; i < 118 + 4; ++i) - powToGains[i + 256] = (float) pow (2.0, -0.25 * (i + 210)); - - for (i = 0; i < 8207; ++i) - nToThe4Over3[i] = (float) pow ((double) i, 4.0 / 3.0); - - for (i = 0; i < 8; ++i) - { - static double Ci[] = { -0.6, -0.535, -0.33, -0.185, -0.095, -0.041, -0.0142, -0.0037 }; - const double sq = sqrt (1.0 + Ci[i] * Ci[i]); - antiAliasingCs[i] = (float) (1.0 / sq); - antiAliasingCa[i] = (float) (Ci[i] / sq); - } - - for (i = 0; i < 18; ++i) - { - win[0][i] = win[1][i] = (float) (0.5 * sin (double_Pi / 72.0 * (2 * i + 1)) / cos (double_Pi * (2 * i + 19) / 72.0)); - win[0][i + 18] = win[3][i + 18] = (float) (0.5 * sin (double_Pi / 72.0 * (2 * (i + 18) + 1)) / cos (double_Pi * (2 * (i + 18) + 19) / 72.0)); - } - - const double piOver72 = double_Pi; - - for (i = 0; i < 6; ++i) - { - win[1][i + 18] = (float) (0.5 / cos (piOver72 * (2 * (i + 18) + 19))); - win[3][i + 12] = (float) (0.5 / cos (piOver72 * (2 * (i + 12) + 19))); - win[1][i + 24] = (float) (0.5 * sin (double_Pi / 24.0 * (2 * i + 13)) / cos (piOver72 * (2 * (i + 24) + 19))); - win[1][i + 30] = win[3][i] = 0; - win[3][i + 6] = (float) (0.5 * sin (double_Pi / 24.0 * (2 * i + 1)) / cos (piOver72 * (2 * (i + 6) + 19))); - } - - for (i = 0; i < 12; ++i) - win[2][i] = (float) (0.5 * sin (double_Pi / 24.0 * (2 * i + 1)) / cos (double_Pi * (2 * i + 7) / 24.0)); - - for (j = 0; j < 4; ++j) - { - static const int len[4] = { 36, 36, 12, 36 }; - for (i = 0; i < len[j]; i += 2) win1[j][i] = win[j][i]; - for (i = 1; i < len[j]; i += 2) win1[j][i] = -win[j][i]; - } - - const double sqrt2 = 1.41421356237309504880168872420969808; - - for (i = 0; i < 16; ++i) - { - const double t = tan (i * double_Pi / 12.0); - tan1_1[i] = (float) (t / (1.0 + t)); - tan2_1[i] = (float) (1.0 / (1.0 + t)); - tan1_2[i] = (float) (sqrt2 * t / (1.0 + t)); - tan2_2[i] = (float) (sqrt2 / (1.0 + t)); - - for (j = 0; j < 2; ++j) - { - double p1 = 1.0, p2 = 1.0; - - if (i > 0) - { - const double base = pow (2.0, -0.25 * (j + 1)); - - if (i & 1) - p1 = pow (base, (i + 1) * 0.5); - else - p2 = pow (base, i * 0.5); - } - - pow1_1[j][i] = (float) p1; - pow2_1[j][i] = (float) p2; - pow1_2[j][i] = (float) (sqrt2 * p1); - pow2_2[j][i] = (float) (sqrt2 * p2); - } - } - - for (j = 0; j < 9; ++j) - { - const BandInfoStruct& bi = bandInfo[j]; - int cb; - int* mp = map[j][0] = mapbuf0[j]; - const int16* bdf = bi.longDiff; - - for (i = 0, cb = 0; cb < 8; ++cb, i += *bdf++) - { - *mp++ = (*bdf) >> 1; - *mp++ = i; - *mp++ = 3; - *mp++ = cb; - } - bdf = bi.shortDiff + 3; - - for (cb = 3; cb < 13; ++cb) - { - const int l = (*bdf++) >> 1; - - for (int lwin = 0; lwin < 3; ++lwin) - { - *mp++ = l; - *mp++ = i + lwin; - *mp++ = lwin; - *mp++ = cb; - } - i += 6 * l; - } - - mapEnd[j][0] = mp; - mp = map[j][1] = mapbuf1[j]; - bdf = bi.shortDiff; - - for (i = 0, cb = 0; cb < 13; ++cb) - { - const int l = (*bdf++) >> 1; - for (int lwin = 0; lwin < 3; ++lwin) - { - *mp++ = l; - *mp++ = i + lwin; - *mp++ = lwin; - *mp++ = cb; - } - i += 6 * l; - } - mapEnd[j][1] = mp; - - mp = map[j][2] = mapbuf2[j]; - bdf = bi.longDiff; - for (cb = 0; cb < 22; ++cb) - { - *mp++ = (*bdf++) >> 1; - *mp++ = cb; - } - mapEnd[j][2] = mp; - - } - - for (j = 0; j < 9; ++j) - { - for (i = 0; i < 23; ++i) longLimit[j][i] = jmin (32, (bandInfo[j].longIndex[i] - 1 + 8) / 18 + 1); - for (i = 0; i < 14; ++i) shortLimit[j][i] = jmin (32, (bandInfo[j].shortIndex[i] - 1) / 18 + 1); - } - - for (i = 0; i < 5; ++i) - for (j = 0; j < 6; ++j) - for (int k = 0; k < 6; ++k) - { - const int n = k + j * 6 + i * 36; - iLength2[n] = (unsigned int) (i | (j << 3) | (k << 6) | (3 << 12)); - } - - for (i = 0; i < 4; ++i) - for (j = 0; j < 4; ++j) - for (int k = 0; k < 4; ++k) - { - const int n = k + j * 4 + i * 16; - iLength2[n + 180] = (unsigned int) (i | (j << 3) | (k << 6) | (4 << 12)); - } - - for (i = 0; i < 4; ++i) - for (j = 0; j < 3; ++j) - { - const int n = j + i * 3; - iLength2[n + 244] = (unsigned int) (i | (j << 3) | (5 << 12)); - nLength2[n + 500] = (unsigned int) (i | (j << 3) | (2 << 12) | (1 << 15)); - } - - for (i = 0; i < 5; ++i) - for (j = 0; j < 5; ++j) - for (int k = 0; k < 4; ++k) - for (int l = 0; l < 4; ++l) - { - const int n = l + k * 4 + j * 16 + i * 80; - nLength2[n] = (unsigned int) (i | (j << 3) | (k << 6) | (l << 9) | (0 << 12)); - } - - for (i = 0; i < 5; ++i) - for (j = 0; j < 5; ++j) - for (int k = 0; k < 4; ++k) - { - const int n = k + j * 4 + i * 20; - nLength2[n + 400] = (unsigned int) (i | (j << 3) | (k << 6) | (1 << 12)); - } - } -}; - -static const Constants constants; - - -//============================================================================== -struct Layer3SideInfo -{ - struct Info - { - void doAntialias (float xr[32][18]) const noexcept - { - float* xr1 = xr[1]; - int sb; - - if (blockType == 2) - { - if (mixedBlockFlag == 0) - return; - - sb = 1; - } - else - sb = (int) maxb - 1; - - for (; sb != 0; --sb, xr1 += 10) - { - const float* cs = constants.antiAliasingCs; - const float* ca = constants.antiAliasingCa; - float* xr2 = xr1; - - for (int ss = 7; ss >= 0; --ss) - { - const float bu = *--xr2, bd = *xr1; - *xr2 = (bu * *cs) - (bd * *ca); - *xr1++ = (bd * *cs++) + (bu * *ca++); - } - } - } - - void doIStereo (float xrBuffer[2][32][18], const int* const scaleFactors, - const int sampleRate, const bool msStereo, const int lsf) const noexcept - { - float (*xr) [32 * 18] = (float (*) [32 * 18]) xrBuffer; - const BandInfoStruct& bi = bandInfo[sampleRate]; - const float* tabl1, *tabl2; - - if (lsf != 0) - { - const int p = scaleFactorCompression & 1; - if (msStereo) - { - tabl1 = constants.pow1_2[p]; - tabl2 = constants.pow2_2[p]; - } - else - { - tabl1 = constants.pow1_1[p]; - tabl2 = constants.pow2_1[p]; - } - } - else - { - if (msStereo) - { - tabl1 = constants.tan1_2; - tabl2 = constants.tan2_2; - } - else - { - tabl1 = constants.tan1_1; - tabl2 = constants.tan2_1; - } - } - - if (blockType == 2) - { - bool doL = mixedBlockFlag != 0; - - for (uint32 lwin = 0; lwin < 3; ++lwin) - { - uint32 sfb = maxBand[lwin]; - doL = doL && (sfb <= 3); - - for (; sfb < 12; ++sfb) - { - const int p = scaleFactors[sfb * 3 + lwin - mixedBlockFlag]; - if (p != 7) - { - const float t1 = tabl1[p]; - const float t2 = tabl2[p]; - int sb = bi.shortDiff[sfb]; - uint32 index = (uint32) sb + lwin; - - for (; sb > 0; --sb, index += 3) - { - float v = xr[0][index]; - xr[0][index] = v * t1; - xr[1][index] = v * t2; - } - } - } - - const int p = scaleFactors[11 * 3 + lwin - mixedBlockFlag]; - - if (p != 7) - { - const float t1 = tabl1[p]; - const float t2 = tabl2[p]; - int sb = bi.shortDiff[12]; - uint32 index = (uint32) sb + lwin; - - for (; sb > 0; --sb, index += 3) - { - float v = xr[0][index]; - xr[0][index] = v * t1; - xr[1][index] = v * t2; - } - } - } - - if (doL) - { - int index = bi.longIndex[maxBandl]; - - for (uint32 sfb = maxBandl; sfb < 8; ++sfb) - { - int sb = bi.longDiff[sfb]; - const int p = scaleFactors[sfb]; - - if (p != 7) - { - const float t1 = tabl1[p]; - const float t2 = tabl2[p]; - - for (; sb > 0; --sb, ++index) - { - float v = xr[0][index]; - xr[0][index] = v * t1; - xr[1][index] = v * t2; - } - } - else - index += sb; - } - } - } - else - { - int index = bi.longIndex[maxBandl]; - - for (uint32 sfb = maxBandl; sfb < 21; ++sfb) - { - int sb = bi.longDiff[sfb]; - const int p = scaleFactors[sfb]; - - if (p != 7) - { - const float t1 = tabl1[p]; - const float t2 = tabl2[p]; - - for (; sb > 0; --sb, ++index) - { - const float v = xr[0][index]; - xr[0][index] = v * t1; - xr[1][index] = v * t2; - } - } - else - index += sb; - } - - const int p = scaleFactors[20]; - if (p != 7) - { - const float t1 = tabl1[p], t2 = tabl2[p]; - - for (int sb = bi.longDiff[21]; sb > 0; --sb, ++index) - { - const float v = xr[0][index]; - xr[0][index] = v * t1; - xr[1][index] = v * t2; - } - } - } - } - - int scfsi; - uint32 part2_3Length, bigValues; - uint32 scaleFactorCompression, blockType, mixedBlockFlag; - uint32 tableSelect[3]; - uint32 maxBand[3]; - uint32 maxBandl, maxb, region1Start, region2Start; - uint32 preflag, scaleFactorScale, count1TableSelect; - const float* fullGain[3]; - const float* pow2gain; - }; - - struct InfoPair { Info gr[2]; }; - InfoPair ch[2]; - - uint32 mainDataStart, privateBits; -}; - -//============================================================================== -namespace DCT -{ - enum { SBLIMIT = 32 }; - static const float cos6_1 = 0.866025388f; - static const float cos6_2 = 0.5f; - static const float cos9[] = { 1.0f, 0.98480773f, 0.939692616f, 0.866025388f, 0.766044438f, 0.642787635f, 0.5f, 0.342020154f, 0.173648179f }; - static const float cos36[] = { 0.501909912f, 0.517638087f, 0.551688969f, 0.610387266f, 0.707106769f, 0.871723413f, 1.18310082f, 1.93185163f, 5.73685646f }; - static const float cos12[] = { 0.517638087f, 0.707106769f, 1.93185163f }; - - inline void dct36_0 (const int v, float* const ts, float* const out1, float* const out2, - const float* const wintab, float sum0, const float sum1) noexcept - { - const float tmp = sum0 + sum1; - out2[9 + v] = tmp * wintab[27 + v]; - out2[8 - v] = tmp * wintab[26 - v]; - sum0 -= sum1; - ts[SBLIMIT * (8 - v)] = out1[8 - v] + sum0 * wintab[8 - v]; - ts[SBLIMIT * (9 + v)] = out1[9 + v] + sum0 * wintab[9 + v]; - } - - inline void dct36_1 (const int v, float* const ts, float* const out1, float* const out2, const float* const wintab, - const float tmp1a, const float tmp1b, const float tmp2a, const float tmp2b) noexcept - { - dct36_0 (v, ts, out1, out2, wintab, tmp1a + tmp2a, (tmp1b + tmp2b) * cos36[v]); - } - - inline void dct36_2 (const int v, float* const ts, float* const out1, float* const out2, const float* const wintab, - const float tmp1a, const float tmp1b, const float tmp2a, const float tmp2b) noexcept - { - dct36_0 (v, ts, out1, out2, wintab, tmp2a - tmp1a, (tmp2b - tmp1b) * cos36[v]); - } - - static void dct36 (float* const in, float* const out1, float* const out2, const float* const wintab, float* const ts) noexcept - { - in[17] += in[16]; in[16] += in[15]; in[15] += in[14]; in[14] += in[13]; in[13] += in[12]; - in[12] += in[11]; in[11] += in[10]; in[10] += in[9]; in[9] += in[8]; in[8] += in[7]; - in[7] += in[6]; in[6] += in[5]; in[5] += in[4]; in[4] += in[3]; in[3] += in[2]; - in[2] += in[1]; in[1] += in[0]; in[17] += in[15]; in[15] += in[13]; in[13] += in[11]; - in[11] += in[9]; in[9] += in[7]; in[7] += in[5]; in[5] += in[3]; in[3] += in[1]; - - const float ta33 = in[6] * cos9[3]; - const float ta66 = in[12] * cos9[6]; - const float tb33 = in[7] * cos9[3]; - const float tb66 = in[13] * cos9[6]; - - { - const float tmp1a = in[2] * cos9[1] + ta33 + in[10] * cos9[5] + in[14] * cos9[7]; - const float tmp1b = in[3] * cos9[1] + tb33 + in[11] * cos9[5] + in[15] * cos9[7]; - const float tmp2a = in[0] + in[4] * cos9[2] + in[8] * cos9[4] + ta66 + in[16] * cos9[8]; - const float tmp2b = in[1] + in[5] * cos9[2] + in[9] * cos9[4] + tb66 + in[17] * cos9[8]; - dct36_1 (0, ts, out1, out2, wintab, tmp1a, tmp1b, tmp2a, tmp2b); - dct36_2 (8, ts, out1, out2, wintab, tmp1a, tmp1b, tmp2a, tmp2b); - } - - { - const float tmp1a = (in[2] - in[10] - in[14]) * cos9[3]; - const float tmp1b = (in[3] - in[11] - in[15]) * cos9[3]; - const float tmp2a = (in[4] - in[8] - in[16]) * cos9[6] - in[12] + in[0]; - const float tmp2b = (in[5] - in[9] - in[17]) * cos9[6] - in[13] + in[1]; - dct36_1 (1, ts, out1, out2, wintab, tmp1a, tmp1b, tmp2a, tmp2b); - dct36_2 (7, ts, out1, out2, wintab, tmp1a, tmp1b, tmp2a, tmp2b); - } - - { - const float tmp1a = in[2] * cos9[5] - ta33 - in[10] * cos9[7] + in[14] * cos9[1]; - const float tmp1b = in[3] * cos9[5] - tb33 - in[11] * cos9[7] + in[15] * cos9[1]; - const float tmp2a = in[0] - in[4] * cos9[8] - in[8] * cos9[2] + ta66 + in[16] * cos9[4]; - const float tmp2b = in[1] - in[5] * cos9[8] - in[9] * cos9[2] + tb66 + in[17] * cos9[4]; - dct36_1 (2, ts, out1, out2, wintab, tmp1a, tmp1b, tmp2a, tmp2b); - dct36_2 (6, ts, out1, out2, wintab, tmp1a, tmp1b, tmp2a, tmp2b); - } - - { - const float tmp1a = in[2] * cos9[7] - ta33 + in[10] * cos9[1] - in[14] * cos9[5]; - const float tmp1b = in[3] * cos9[7] - tb33 + in[11] * cos9[1] - in[15] * cos9[5]; - const float tmp2a = in[0] - in[4] * cos9[4] + in[8] * cos9[8] + ta66 - in[16] * cos9[2]; - const float tmp2b = in[1] - in[5] * cos9[4] + in[9] * cos9[8] + tb66 - in[17] * cos9[2]; - dct36_1 (3, ts, out1, out2, wintab, tmp1a, tmp1b, tmp2a, tmp2b); - dct36_2 (5, ts, out1, out2, wintab, tmp1a, tmp1b, tmp2a, tmp2b); - } - - const float sum0 = in[0] - in[4] + in[8] - in[12] + in[16]; - const float sum1 = (in[1] - in[5] + in[9] - in[13] + in[17]) * cos36[4]; - dct36_0 (4, ts, out1, out2, wintab, sum0, sum1); - } - - struct DCT12Inputs - { - float in0, in1, in2, in3, in4, in5; - - inline DCT12Inputs (const float* const in) noexcept - { - in5 = in[5*3] + (in4 = in[4*3]); - in4 += (in3 = in[3*3]); - in3 += (in2 = in[2*3]); - in2 += (in1 = in[1*3]); - in1 += (in0 = in[0*3]); - in5 += in3; in3 += in1; - in2 *= cos6_1; - in3 *= cos6_1; - } - - inline void process() noexcept - { - in0 += in4 * cos6_2; - in4 = in0 + in2; in0 -= in2; - in1 += in5 * cos6_2; - in5 = (in1 + in3) * cos12[0]; - in1 = (in1 - in3) * cos12[2]; - in3 = in4 + in5; in4 -= in5; - in2 = in0 + in1; in0 -= in1; - } - }; - - static void dct12 (const float* in, float* const out1, float* const out2, const float* wi, float* ts) noexcept - { - { - ts[0] = out1[0]; - ts[SBLIMIT * 1] = out1[1]; - ts[SBLIMIT * 2] = out1[2]; - ts[SBLIMIT * 3] = out1[3]; - ts[SBLIMIT * 4] = out1[4]; - ts[SBLIMIT * 5] = out1[5]; - - DCT12Inputs inputs (in); - - { - float tmp1 = (inputs.in0 - inputs.in4); - const float tmp2 = (inputs.in1 - inputs.in5) * cos12[1]; - const float tmp0 = tmp1 + tmp2; - tmp1 -= tmp2; - - ts[16 * SBLIMIT] = out1[16] + tmp0 * wi[10]; - ts[13 * SBLIMIT] = out1[13] + tmp0 * wi[7]; - ts[7 * SBLIMIT] = out1[7] + tmp1 * wi[1]; - ts[10 * SBLIMIT] = out1[10] + tmp1 * wi[4]; - } - - inputs.process(); - - ts[17 * SBLIMIT] = out1[17] + inputs.in2 * wi[11]; - ts[12 * SBLIMIT] = out1[12] + inputs.in2 * wi[6]; - ts[14 * SBLIMIT] = out1[14] + inputs.in3 * wi[8]; - ts[15 * SBLIMIT] = out1[15] + inputs.in3 * wi[9]; - - ts[6 * SBLIMIT] = out1[6] + inputs.in0 * wi[0]; - ts[11 * SBLIMIT] = out1[11] + inputs.in0 * wi[5]; - ts[8 * SBLIMIT] = out1[8] + inputs.in4 * wi[2]; - ts[9 * SBLIMIT] = out1[9] + inputs.in4 * wi[3]; - } - - { - DCT12Inputs inputs (++in); - float tmp1 = (inputs.in0 - inputs.in4); - const float tmp2 = (inputs.in1 - inputs.in5) * cos12[1]; - const float tmp0 = tmp1 + tmp2; - tmp1 -= tmp2; - out2[4] = tmp0 * wi[10]; - out2[1] = tmp0 * wi[7]; - ts[13 * SBLIMIT] += tmp1 * wi[1]; - ts[16 * SBLIMIT] += tmp1 * wi[4]; - - inputs.process(); - - out2[5] = inputs.in2 * wi[11]; - out2[0] = inputs.in2 * wi[6]; - out2[2] = inputs.in3 * wi[8]; - out2[3] = inputs.in3 * wi[9]; - ts[12 * SBLIMIT] += inputs.in0 * wi[0]; - ts[17 * SBLIMIT] += inputs.in0 * wi[5]; - ts[14 * SBLIMIT] += inputs.in4 * wi[2]; - ts[15 * SBLIMIT] += inputs.in4 * wi[5 - 2]; - } - - { - DCT12Inputs inputs (++in); - out2[12] = out2[13] = out2[14] = out2[15] = out2[16] = out2[17] = 0; - - float tmp1 = (inputs.in0 - inputs.in4); - const float tmp2 = (inputs.in1 - inputs.in5) * cos12[1]; - const float tmp0 = tmp1 + tmp2; - tmp1 -= tmp2; - - out2[10] = tmp0 * wi[10]; - out2[7] = tmp0 * wi[7]; - out2[1] += tmp1 * wi[1]; - out2[4] += tmp1 * wi[4]; - - inputs.process(); - - out2[11] = inputs.in2 * wi[11]; - out2[6] = inputs.in2 * wi[6]; - out2[8] = inputs.in3 * wi[8]; - out2[9] = inputs.in3 * wi[9]; - out2[0] += inputs.in0 * wi[0]; - out2[5] += inputs.in0 * wi[5]; - out2[2] += inputs.in4 * wi[2]; - out2[3] += inputs.in4 * wi[3]; - } - } - - static void dct64 (float* const out0, float* const out1, float* const b1, float* const b2, const float* const samples) noexcept - { - { - const float* const costab = constants.cosTables[0]; - b1[0x00] = samples[0x00] + samples[0x1F]; b1[0x1F] = (samples[0x00] - samples[0x1F]) * costab[0x0]; - b1[0x01] = samples[0x01] + samples[0x1E]; b1[0x1E] = (samples[0x01] - samples[0x1E]) * costab[0x1]; - b1[0x02] = samples[0x02] + samples[0x1D]; b1[0x1D] = (samples[0x02] - samples[0x1D]) * costab[0x2]; - b1[0x03] = samples[0x03] + samples[0x1C]; b1[0x1C] = (samples[0x03] - samples[0x1C]) * costab[0x3]; - b1[0x04] = samples[0x04] + samples[0x1B]; b1[0x1B] = (samples[0x04] - samples[0x1B]) * costab[0x4]; - b1[0x05] = samples[0x05] + samples[0x1A]; b1[0x1A] = (samples[0x05] - samples[0x1A]) * costab[0x5]; - b1[0x06] = samples[0x06] + samples[0x19]; b1[0x19] = (samples[0x06] - samples[0x19]) * costab[0x6]; - b1[0x07] = samples[0x07] + samples[0x18]; b1[0x18] = (samples[0x07] - samples[0x18]) * costab[0x7]; - b1[0x08] = samples[0x08] + samples[0x17]; b1[0x17] = (samples[0x08] - samples[0x17]) * costab[0x8]; - b1[0x09] = samples[0x09] + samples[0x16]; b1[0x16] = (samples[0x09] - samples[0x16]) * costab[0x9]; - b1[0x0A] = samples[0x0A] + samples[0x15]; b1[0x15] = (samples[0x0A] - samples[0x15]) * costab[0xA]; - b1[0x0B] = samples[0x0B] + samples[0x14]; b1[0x14] = (samples[0x0B] - samples[0x14]) * costab[0xB]; - b1[0x0C] = samples[0x0C] + samples[0x13]; b1[0x13] = (samples[0x0C] - samples[0x13]) * costab[0xC]; - b1[0x0D] = samples[0x0D] + samples[0x12]; b1[0x12] = (samples[0x0D] - samples[0x12]) * costab[0xD]; - b1[0x0E] = samples[0x0E] + samples[0x11]; b1[0x11] = (samples[0x0E] - samples[0x11]) * costab[0xE]; - b1[0x0F] = samples[0x0F] + samples[0x10]; b1[0x10] = (samples[0x0F] - samples[0x10]) * costab[0xF]; - } - - { - const float* const costab = constants.cosTables[1]; - b2[0x00] = b1[0x00] + b1[0x0F]; b2[0x0F] = (b1[0x00] - b1[0x0F]) * costab[0]; - b2[0x01] = b1[0x01] + b1[0x0E]; b2[0x0E] = (b1[0x01] - b1[0x0E]) * costab[1]; - b2[0x02] = b1[0x02] + b1[0x0D]; b2[0x0D] = (b1[0x02] - b1[0x0D]) * costab[2]; - b2[0x03] = b1[0x03] + b1[0x0C]; b2[0x0C] = (b1[0x03] - b1[0x0C]) * costab[3]; - b2[0x04] = b1[0x04] + b1[0x0B]; b2[0x0B] = (b1[0x04] - b1[0x0B]) * costab[4]; - b2[0x05] = b1[0x05] + b1[0x0A]; b2[0x0A] = (b1[0x05] - b1[0x0A]) * costab[5]; - b2[0x06] = b1[0x06] + b1[0x09]; b2[0x09] = (b1[0x06] - b1[0x09]) * costab[6]; - b2[0x07] = b1[0x07] + b1[0x08]; b2[0x08] = (b1[0x07] - b1[0x08]) * costab[7]; - b2[0x10] = b1[0x10] + b1[0x1F]; b2[0x1F] = (b1[0x1F] - b1[0x10]) * costab[0]; - b2[0x11] = b1[0x11] + b1[0x1E]; b2[0x1E] = (b1[0x1E] - b1[0x11]) * costab[1]; - b2[0x12] = b1[0x12] + b1[0x1D]; b2[0x1D] = (b1[0x1D] - b1[0x12]) * costab[2]; - b2[0x13] = b1[0x13] + b1[0x1C]; b2[0x1C] = (b1[0x1C] - b1[0x13]) * costab[3]; - b2[0x14] = b1[0x14] + b1[0x1B]; b2[0x1B] = (b1[0x1B] - b1[0x14]) * costab[4]; - b2[0x15] = b1[0x15] + b1[0x1A]; b2[0x1A] = (b1[0x1A] - b1[0x15]) * costab[5]; - b2[0x16] = b1[0x16] + b1[0x19]; b2[0x19] = (b1[0x19] - b1[0x16]) * costab[6]; - b2[0x17] = b1[0x17] + b1[0x18]; b2[0x18] = (b1[0x18] - b1[0x17]) * costab[7]; - } - - { - const float* const costab = constants.cosTables[2]; - b1[0x00] = b2[0x00] + b2[0x07]; b1[0x07] = (b2[0x00] - b2[0x07]) * costab[0]; - b1[0x01] = b2[0x01] + b2[0x06]; b1[0x06] = (b2[0x01] - b2[0x06]) * costab[1]; - b1[0x02] = b2[0x02] + b2[0x05]; b1[0x05] = (b2[0x02] - b2[0x05]) * costab[2]; - b1[0x03] = b2[0x03] + b2[0x04]; b1[0x04] = (b2[0x03] - b2[0x04]) * costab[3]; - b1[0x08] = b2[0x08] + b2[0x0F]; b1[0x0F] = (b2[0x0F] - b2[0x08]) * costab[0]; - b1[0x09] = b2[0x09] + b2[0x0E]; b1[0x0E] = (b2[0x0E] - b2[0x09]) * costab[1]; - b1[0x0A] = b2[0x0A] + b2[0x0D]; b1[0x0D] = (b2[0x0D] - b2[0x0A]) * costab[2]; - b1[0x0B] = b2[0x0B] + b2[0x0C]; b1[0x0C] = (b2[0x0C] - b2[0x0B]) * costab[3]; - b1[0x10] = b2[0x10] + b2[0x17]; b1[0x17] = (b2[0x10] - b2[0x17]) * costab[0]; - b1[0x11] = b2[0x11] + b2[0x16]; b1[0x16] = (b2[0x11] - b2[0x16]) * costab[1]; - b1[0x12] = b2[0x12] + b2[0x15]; b1[0x15] = (b2[0x12] - b2[0x15]) * costab[2]; - b1[0x13] = b2[0x13] + b2[0x14]; b1[0x14] = (b2[0x13] - b2[0x14]) * costab[3]; - b1[0x18] = b2[0x18] + b2[0x1F]; b1[0x1F] = (b2[0x1F] - b2[0x18]) * costab[0]; - b1[0x19] = b2[0x19] + b2[0x1E]; b1[0x1E] = (b2[0x1E] - b2[0x19]) * costab[1]; - b1[0x1A] = b2[0x1A] + b2[0x1D]; b1[0x1D] = (b2[0x1D] - b2[0x1A]) * costab[2]; - b1[0x1B] = b2[0x1B] + b2[0x1C]; b1[0x1C] = (b2[0x1C] - b2[0x1B]) * costab[3]; - } - - { - const float cos0 = constants.cosTables[3][0]; - const float cos1 = constants.cosTables[3][1]; - b2[0x00] = b1[0x00] + b1[0x03]; b2[0x03] = (b1[0x00] - b1[0x03]) * cos0; - b2[0x01] = b1[0x01] + b1[0x02]; b2[0x02] = (b1[0x01] - b1[0x02]) * cos1; - b2[0x04] = b1[0x04] + b1[0x07]; b2[0x07] = (b1[0x07] - b1[0x04]) * cos0; - b2[0x05] = b1[0x05] + b1[0x06]; b2[0x06] = (b1[0x06] - b1[0x05]) * cos1; - b2[0x08] = b1[0x08] + b1[0x0B]; b2[0x0B] = (b1[0x08] - b1[0x0B]) * cos0; - b2[0x09] = b1[0x09] + b1[0x0A]; b2[0x0A] = (b1[0x09] - b1[0x0A]) * cos1; - b2[0x0C] = b1[0x0C] + b1[0x0F]; b2[0x0F] = (b1[0x0F] - b1[0x0C]) * cos0; - b2[0x0D] = b1[0x0D] + b1[0x0E]; b2[0x0E] = (b1[0x0E] - b1[0x0D]) * cos1; - b2[0x10] = b1[0x10] + b1[0x13]; b2[0x13] = (b1[0x10] - b1[0x13]) * cos0; - b2[0x11] = b1[0x11] + b1[0x12]; b2[0x12] = (b1[0x11] - b1[0x12]) * cos1; - b2[0x14] = b1[0x14] + b1[0x17]; b2[0x17] = (b1[0x17] - b1[0x14]) * cos0; - b2[0x15] = b1[0x15] + b1[0x16]; b2[0x16] = (b1[0x16] - b1[0x15]) * cos1; - b2[0x18] = b1[0x18] + b1[0x1B]; b2[0x1B] = (b1[0x18] - b1[0x1B]) * cos0; - b2[0x19] = b1[0x19] + b1[0x1A]; b2[0x1A] = (b1[0x19] - b1[0x1A]) * cos1; - b2[0x1C] = b1[0x1C] + b1[0x1F]; b2[0x1F] = (b1[0x1F] - b1[0x1C]) * cos0; - b2[0x1D] = b1[0x1D] + b1[0x1E]; b2[0x1E] = (b1[0x1E] - b1[0x1D]) * cos1; - } - - { - const float cos0 = constants.cosTables[4][0]; - b1[0x00] = b2[0x00] + b2[0x01]; b1[0x01] = (b2[0x00] - b2[0x01]) * cos0; - b1[0x02] = b2[0x02] + b2[0x03]; b1[0x03] = (b2[0x03] - b2[0x02]) * cos0; b1[0x02] += b1[0x03]; - b1[0x04] = b2[0x04] + b2[0x05]; b1[0x05] = (b2[0x04] - b2[0x05]) * cos0; - b1[0x06] = b2[0x06] + b2[0x07]; b1[0x07] = (b2[0x07] - b2[0x06]) * cos0; - b1[0x06] += b1[0x07]; b1[0x04] += b1[0x06]; b1[0x06] += b1[0x05]; b1[0x05] += b1[0x07]; - b1[0x08] = b2[0x08] + b2[0x09]; b1[0x09] = (b2[0x08] - b2[0x09]) * cos0; - b1[0x0A] = b2[0x0A] + b2[0x0B]; b1[0x0B] = (b2[0x0B] - b2[0x0A]) * cos0; b1[0x0A] += b1[0x0B]; - b1[0x0C] = b2[0x0C] + b2[0x0D]; b1[0x0D] = (b2[0x0C] - b2[0x0D]) * cos0; - b1[0x0E] = b2[0x0E] + b2[0x0F]; b1[0x0F] = (b2[0x0F] - b2[0x0E]) * cos0; - b1[0x0E] += b1[0x0F]; b1[0x0C] += b1[0x0E]; b1[0x0E] += b1[0x0D]; b1[0x0D] += b1[0x0F]; - b1[0x10] = b2[0x10] + b2[0x11]; b1[0x11] = (b2[0x10] - b2[0x11]) * cos0; - b1[0x12] = b2[0x12] + b2[0x13]; b1[0x13] = (b2[0x13] - b2[0x12]) * cos0; b1[0x12] += b1[0x13]; - b1[0x14] = b2[0x14] + b2[0x15]; b1[0x15] = (b2[0x14] - b2[0x15]) * cos0; - b1[0x16] = b2[0x16] + b2[0x17]; b1[0x17] = (b2[0x17] - b2[0x16]) * cos0; - b1[0x16] += b1[0x17]; b1[0x14] += b1[0x16]; b1[0x16] += b1[0x15]; b1[0x15] += b1[0x17]; - b1[0x18] = b2[0x18] + b2[0x19]; b1[0x19] = (b2[0x18] - b2[0x19]) * cos0; - b1[0x1A] = b2[0x1A] + b2[0x1B]; b1[0x1B] = (b2[0x1B] - b2[0x1A]) * cos0; b1[0x1A] += b1[0x1B]; - b1[0x1C] = b2[0x1C] + b2[0x1D]; b1[0x1D] = (b2[0x1C] - b2[0x1D]) * cos0; - b1[0x1E] = b2[0x1E] + b2[0x1F]; b1[0x1F] = (b2[0x1F] - b2[0x1E]) * cos0; - b1[0x1E] += b1[0x1F]; b1[0x1C] += b1[0x1E]; b1[0x1E] += b1[0x1D]; b1[0x1D] += b1[0x1F]; - } - - out0[0x10 * 16] = b1[0x00]; out0[0x10 * 12] = b1[0x04]; out0[0x10 * 8] = b1[0x02]; out0[0x10 * 4] = b1[0x06]; - out0[0] = b1[0x01]; out1[0] = b1[0x01]; out1[0x10 * 4] = b1[0x05]; out1[0x10 * 8] = b1[0x03]; - out1[0x10 * 12] = b1[0x07]; - - b1[0x08] += b1[0x0C]; out0[0x10 * 14] = b1[0x08]; b1[0x0C] += b1[0x0a]; out0[0x10 * 10] = b1[0x0C]; - b1[0x0A] += b1[0x0E]; out0[0x10 * 6] = b1[0x0A]; b1[0x0E] += b1[0x09]; out0[0x10 * 2] = b1[0x0E]; - b1[0x09] += b1[0x0D]; out1[0x10 * 2] = b1[0x09]; b1[0x0D] += b1[0x0B]; out1[0x10 * 6] = b1[0x0D]; - b1[0x0B] += b1[0x0F]; out1[0x10 * 10] = b1[0x0B]; out1[0x10 * 14] = b1[0x0F]; - - b1[0x18] += b1[0x1C]; out0[0x10 * 15] = b1[0x10] + b1[0x18]; out0[0x10 * 13] = b1[0x18] + b1[0x14]; - b1[0x1C] += b1[0x1a]; out0[0x10 * 11] = b1[0x14] + b1[0x1C]; out0[0x10 * 9] = b1[0x1C] + b1[0x12]; - b1[0x1A] += b1[0x1E]; out0[0x10 * 7] = b1[0x12] + b1[0x1A]; out0[0x10 * 5] = b1[0x1A] + b1[0x16]; - b1[0x1E] += b1[0x19]; out0[0x10 * 3] = b1[0x16] + b1[0x1E]; out0[0x10 * 1] = b1[0x1E] + b1[0x11]; - b1[0x19] += b1[0x1D]; out1[0x10 * 1] = b1[0x11] + b1[0x19]; out1[0x10 * 3] = b1[0x19] + b1[0x15]; - b1[0x1D] += b1[0x1B]; out1[0x10 * 5] = b1[0x15] + b1[0x1D]; out1[0x10 * 7] = b1[0x1D] + b1[0x13]; - b1[0x1B] += b1[0x1F]; out1[0x10 * 9] = b1[0x13] + b1[0x1B]; out1[0x10 * 11] = b1[0x1B] + b1[0x17]; - out1[0x10 * 13] = b1[0x17] + b1[0x1F]; out1[0x10 * 15] = b1[0x1F]; - } - - static void dct64 (float* const a, float* const b, const float* const c) noexcept - { - float temp[64]; - dct64 (a, b, temp, temp + 32, c); - } -} - -//============================================================================== -struct MP3Stream -{ - MP3Stream (InputStream& source) - : stream (source, 8192), - numFrames (0), currentFrameIndex (0), vbrHeaderFound (false) - { - reset(); - } - - int decodeNextBlock (float* const out0, float* const out1, int& done) - { - if (! headerParsed) - { - int nextFrameOffset = scanForNextFrameHeader (false); - - if (lastFrameSize == -1 || needToSyncBitStream) - { - needToSyncBitStream = false; - readVBRHeader(); - - if (vbrHeaderFound) - return 1; - } - - if (nextFrameOffset < 0) - return -1; - - if (nextFrameOffset > 0) - { - int size; - wasFreeFormat = false; - needToSyncBitStream = true; - size = (int) (bufferPointer - (bufferSpace[bufferSpaceIndex] + 512)); - - if (size > 2880) - { - size = 0; - bufferPointer = bufferSpace[bufferSpaceIndex] + 512; - } - - const int toSkip = (size + nextFrameOffset) - 2880; - - if (toSkip > 0) - { - stream.skipNextBytes (toSkip); - nextFrameOffset -= toSkip; - } - - stream.read (bufferPointer, nextFrameOffset); - lastFrameSize += nextFrameOffset; - } - - frame.decodeHeader ((uint32) stream.readIntBigEndian()); - headerParsed = true; - frameSize = frame.frameSize; - isFreeFormat = (frameSize == 0); - sideInfoSize = frame.lsf != 0 ? ((frame.numChannels == 1) ? 9 : 17) - : ((frame.numChannels == 1) ? 17 : 32); - - if (frame.crc16FollowsHeader) - sideInfoSize += 2; - - bufferSpaceIndex = 1 - bufferSpaceIndex; - bufferPointer = bufferSpace[bufferSpaceIndex] + 512; - bitIndex = 0; - - if (lastFrameSize < 0) - return 1; - } - - if (! sideParsed) - { - if (frame.layer == 3) - { - stream.read (bufferPointer, sideInfoSize); - - if (frame.crc16FollowsHeader) - getBits (16); - - const int bits = jmax (0, decodeLayer3SideInfo()); - dataSize = (bits + 7) / 8; - - if (! isFreeFormat) - dataSize = jmin (dataSize, frame.frameSize - sideInfoSize); - } - else - { - dataSize = frame.frameSize; - sideInfoSize = 0; - } - - sideParsed = true; - } - - int result = 1; - - if (! dataParsed) - { - stream.read (bufferPointer, dataSize); - - if (out0 != nullptr) - { - if (frame.layer < 3 && frame.crc16FollowsHeader) - getBits (16); - - switch (frame.layer) - { - case 1: decodeLayer1Frame (out0, out1, done); break; - case 2: decodeLayer2Frame (out0, out1, done); break; - case 3: decodeLayer3Frame (out0, out1, done); break; - default: break; - } - } - - bufferPointer = bufferSpace[bufferSpaceIndex] + 512 + sideInfoSize + dataSize; - dataParsed = true; - result = 0; - } - - if (isFreeFormat) - { - if (wasFreeFormat) - { - frameSize = lastFrameSizeNoPadding + frame.padding; - } - else - { - const int nextFrameOffset = scanForNextFrameHeader (true); - - wasFreeFormat = isFreeFormat; - - if (nextFrameOffset < 0) - { - lastFrameSize = frameSize; - return result; - } - - frameSize = nextFrameOffset + sideInfoSize + dataSize; - lastFrameSizeNoPadding = frameSize - frame.padding; - } - } - - if (result == 0) - return result; - - int bytes = frameSize - (sideInfoSize + dataSize); - - if (bytes > 0) - { - const int toSkip = bytes - 512; - - if (toSkip > 0) - { - stream.skipNextBytes (toSkip); - bytes -= toSkip; - frameSize -= toSkip; - } - - stream.read (bufferPointer, bytes); - bufferPointer += bytes; - } - - lastFrameSize = frameSize; - wasFreeFormat = isFreeFormat; - frameSize = 0; - headerParsed = sideParsed = dataParsed = false; - return result; - } - - bool seek (int frameIndex) - { - frameIndex = jmax (0, frameIndex); - - while (frameIndex >= frameStreamPositions.size() * storedStartPosInterval) - { - int dummy = 0; - const int result = decodeNextBlock (nullptr, nullptr, dummy); - - if (result < 0) - return false; - - if (result > 0) - break; - } - - frameIndex = jmin (frameIndex & ~(storedStartPosInterval - 1), - frameStreamPositions.size() * storedStartPosInterval - 1); - stream.setPosition (frameStreamPositions.getUnchecked (frameIndex / storedStartPosInterval)); - currentFrameIndex = frameIndex; - reset(); - return true; - } - - MP3Frame frame; - VBRTagData vbrTagData; - BufferedInputStream stream; - int numFrames, currentFrameIndex; - bool vbrHeaderFound; - -private: - bool headerParsed, sideParsed, dataParsed, needToSyncBitStream; - bool isFreeFormat, wasFreeFormat; - int sideInfoSize, dataSize; - int frameSize, lastFrameSize, lastFrameSizeNoPadding; - int bufferSpaceIndex; - Layer3SideInfo sideinfo; - uint8 bufferSpace[2][2880 + 1024]; - uint8* bufferPointer; - int bitIndex, synthBo; - float hybridBlock[2][2][32 * 18]; - int hybridBlockIndex[2]; - float synthBuffers[2][2][0x110]; - float hybridIn[2][32][18]; - float hybridOut[2][18][32]; - - void reset() noexcept - { - headerParsed = sideParsed = dataParsed = isFreeFormat = wasFreeFormat = false; - lastFrameSize = -1; - needToSyncBitStream = true; - frameSize = sideInfoSize = dataSize = frameSize = bitIndex = 0; - lastFrameSizeNoPadding = bufferSpaceIndex = 0; - bufferPointer = bufferSpace[bufferSpaceIndex] + 512; - synthBo = 1; - - zerostruct (sideinfo); - zeromem (bufferSpace, sizeof (bufferSpace)); - zeromem (hybridBlock, sizeof (hybridBlock)); - zeromem (hybridBlockIndex, sizeof (hybridBlockIndex)); - zeromem (synthBuffers, sizeof (synthBuffers)); - } - - enum { storedStartPosInterval = 4 }; - Array frameStreamPositions; - - struct SideInfoLayer1 - { - uint8 allocation[32][2]; - uint8 scaleFactor[32][2]; - }; - - struct SideInfoLayer2 - { - uint8 allocation[32][2]; - uint8 scaleFactor[32][2][3]; - }; - - static bool isValidHeader (const uint32 header, const int oldLayer) noexcept - { - const int newLayer = 4 - ((header >> 17) & 3); - - return (header & 0xffe00000) == 0xffe00000 - && newLayer != 4 - && (oldLayer <= 0 || newLayer == oldLayer) - && ((header >> 12) & 15) != 15 - && ((header >> 10) & 3) != 3 - && (header & 3) != 2; - } - - bool rollBackBufferPointer (int backstep) noexcept - { - if (lastFrameSize < 0 && backstep > 0) - return false; - - const uint8* oldBuffer = bufferSpace[1 - bufferSpaceIndex] + 512; - bufferPointer -= backstep; - - if (backstep != 0) - memcpy (bufferPointer, oldBuffer + lastFrameSize - backstep, (size_t) backstep); - - bitIndex = 0; - return true; - } - - uint32 getBits (const int numBits) noexcept - { - if (numBits <= 0 || bufferPointer == nullptr) - return 0; - - const uint32 result = ((((((bufferPointer[0] << 8) | bufferPointer[1]) << 8) - | bufferPointer[2]) << bitIndex) & 0xffffff) >> (24 - numBits); - bitIndex += numBits; - bufferPointer += (bitIndex >> 3); - bitIndex &= 7; - return result; - } - - uint32 getOneBit() noexcept - { - const uint8 result = (uint8) (*bufferPointer << bitIndex); - ++bitIndex; - bufferPointer += (bitIndex >> 3); - bitIndex &= 7; - return result >> 7; - } - - uint32 getBitsUnchecked (const int numBits) noexcept - { - const uint32 result = ((((bufferPointer[0] << 8) | bufferPointer[1]) << bitIndex) & 0xffff) >> (16 - numBits); - bitIndex += numBits; - bufferPointer += (bitIndex >> 3); - bitIndex &= 7; - return result; - } - - inline uint8 getBitsUint8 (const int numBits) noexcept { return (uint8) getBitsUnchecked (numBits); } - inline uint16 getBitsUint16 (const int numBits) noexcept { return (uint16) getBitsUnchecked (numBits); } - - int scanForNextFrameHeader (const bool checkTypeAgainstLastFrame) noexcept - { - const int64 oldPos = stream.getPosition(); - int offset = -3; - uint32 header = 0; - - for (;;) - { - if (stream.isExhausted() || stream.getPosition() > oldPos + 32768) - { - offset = -1; - break; - } - - header = (header << 8) | (uint8) stream.readByte(); - - if (offset >= 0 && isValidHeader (header, frame.layer)) - { - if (! checkTypeAgainstLastFrame) - break; - - const bool mpeg25 = (header & (1 << 20)) == 0; - const uint32 lsf = mpeg25 ? 1 : ((header & (1 << 19)) ? 0 : 1); - const uint32 sampleRateIndex = mpeg25 ? (6 + ((header >> 10) & 3)) : (((header >> 10) & 3) + (lsf * 3)); - const uint32 mode = (header >> 6) & 3; - const uint32 numChannels = (mode == 3) ? 1 : 2; - - if (numChannels == (uint32) frame.numChannels && lsf == (uint32) frame.lsf - && mpeg25 == frame.mpeg25 && sampleRateIndex == (uint32) frame.sampleRateIndex) - break; - } - - ++offset; - } - - if (offset >= 0) - { - if ((currentFrameIndex & (storedStartPosInterval - 1)) == 0) - frameStreamPositions.set (currentFrameIndex / storedStartPosInterval, oldPos + offset); - - ++currentFrameIndex; - } - - stream.setPosition (oldPos); - return offset; - } - - void readVBRHeader() - { - int64 oldPos = stream.getPosition(); - uint8 xing[194]; - stream.read (xing, sizeof (xing)); - - vbrHeaderFound = vbrTagData.read (xing); - - if (vbrHeaderFound) - { - numFrames = (int) vbrTagData.frames; - oldPos += jmax (vbrTagData.headersize, 1); - } - - stream.setPosition (oldPos); - } - - void decodeLayer1Frame (float* const pcm0, float* const pcm1, int& samplesDone) noexcept - { - float fraction[2][32]; - SideInfoLayer1 si; - layer1Step1 (si); - const int single = (frame.numChannels == 1 || frame.single == 3) ? 0 : frame.single; - - if (single >= 0) - { - for (int i = 0; i < 12; ++i) - { - layer1Step2 (si, fraction); - synthesise (fraction[single], 0, pcm0, samplesDone); - } - } - else - { - for (int i = 0; i < 12; ++i) - { - layer1Step2 (si, fraction); - synthesiseStereo (fraction[0], fraction[1], pcm0, pcm1, samplesDone); - } - } - } - - void decodeLayer2Frame (float* const pcm0, float* const pcm1, int& samplesDone) - { - float fraction[2][4][32]; - frame.selectLayer2Table(); - SideInfoLayer2 si; - layer2Step1 (si); - const int single = (frame.numChannels == 1 || frame.single == 3) ? 0 : frame.single; - - if (single >= 0) - { - for (int i = 0; i < 12; ++i) - { - layer2Step2 (si, i >> 2, fraction); - for (int j = 0; j < 3; ++j) - synthesise (fraction[single][j], 0, pcm0, samplesDone); - } - } - else - { - for (int i = 0; i < 12; ++i) - { - layer2Step2 (si, i >> 2, fraction); - for (int j = 0; j < 3; ++j) - synthesiseStereo (fraction[0][j], fraction[1][j], pcm0, pcm1, samplesDone); - } - } - } - - void decodeLayer3Frame (float* const pcm0, float* const pcm1, int& samplesDone) noexcept - { - if (! rollBackBufferPointer ((int) sideinfo.mainDataStart)) - return; - - const int single = frame.numChannels == 1 ? 0 : frame.single; - const int numChans = (frame.numChannels == 1 || single >= 0) ? 1 : 2; - const bool msStereo = (frame.mode == 1) && (frame.modeExt & 2) != 0; - const bool iStereo = (frame.mode == 1) && (frame.modeExt & 1) != 0; - const int granules = frame.lsf ? 1 : 2; - int scaleFactors[2][39]; - - for (int gr = 0; gr < granules; ++gr) - { - { - Layer3SideInfo::Info& granule = sideinfo.ch[0].gr[gr]; - const int part2bits = frame.lsf ? getLayer3ScaleFactors2 (scaleFactors[0], granule, 0) - : getLayer3ScaleFactors1 (scaleFactors[0], granule); - - if (layer3DequantizeSample (hybridIn[0], scaleFactors[0], granule, frame.sampleRateIndex, part2bits)) - return; - } - - if (frame.numChannels == 2) - { - Layer3SideInfo::Info& granule = sideinfo.ch[1].gr[gr]; - const int part2bits = frame.lsf ? getLayer3ScaleFactors2 (scaleFactors[1], granule, iStereo) - : getLayer3ScaleFactors1 (scaleFactors[1], granule); - - if (layer3DequantizeSample (hybridIn[1], scaleFactors[1], granule, frame.sampleRateIndex, part2bits)) - return; - - if (msStereo) - { - for (int i = 0; i < 32 * 18; ++i) - { - const float tmp0 = ((const float*) hybridIn[0]) [i]; - const float tmp1 = ((const float*) hybridIn[1]) [i]; - ((float*) hybridIn[1]) [i] = tmp0 - tmp1; - ((float*) hybridIn[0]) [i] = tmp0 + tmp1; - } - } - - if (iStereo) - granule.doIStereo (hybridIn, scaleFactors[1], frame.sampleRateIndex, msStereo, frame.lsf); - - if (msStereo || iStereo || single == 3) - { - if (granule.maxb > sideinfo.ch[0].gr[gr].maxb) - sideinfo.ch[0].gr[gr].maxb = granule.maxb; - else - granule.maxb = sideinfo.ch[0].gr[gr].maxb; - } - - switch (single) - { - case 3: - { - float* in0 = (float*) hybridIn[0]; - const float* in1 = (const float*) hybridIn[1]; - for (int i = 0; i < (int) (18 * granule.maxb); ++i, ++in0) - *in0 = (*in0 + *in1++); - } - break; - - case 1: - { - float* in0 = (float*) hybridIn[0]; - const float* in1 = (const float*) hybridIn[1]; - for (int i = 0; i < (int) (18 * granule.maxb); ++i) - *in0++ = *in1++; - } - break; - } - } - - for (int ch = 0; ch < numChans; ++ch) - { - const Layer3SideInfo::Info& granule = sideinfo.ch[ch].gr[gr]; - granule.doAntialias (hybridIn[ch]); - layer3Hybrid (hybridIn[ch], hybridOut[ch], ch, granule); - } - - for (int ss = 0; ss < 18; ++ss) - { - if (single >= 0) - synthesise (hybridOut[0][ss], 0, pcm0, samplesDone); - else - synthesiseStereo (hybridOut[0][ss], hybridOut[1][ss], pcm0, pcm1, samplesDone); - } - } - } - - int decodeLayer3SideInfo() noexcept - { - const int numChannels = frame.numChannels; - const int sampleRate = frame.sampleRateIndex; - const int single = (numChannels == 1) ? 0 : frame.single; - const bool msStereo = (frame.mode == 1) && (frame.modeExt & 2) != 0; - const int granules = frame.lsf ? 1 : 2; - - if (frame.lsf == 0) - getLayer3SideInfo1 (numChannels, msStereo, sampleRate, single); - else - getLayer3SideInfo2 (numChannels, msStereo, sampleRate, single); - - int databits = 0; - for (int gr = 0; gr < granules; ++gr) - for (int ch = 0; ch < numChannels; ++ch) - databits += sideinfo.ch[ch].gr[gr].part2_3Length; - - return databits - 8 * (int) sideinfo.mainDataStart; - } - - void layer1Step1 (SideInfoLayer1& si) noexcept - { - zerostruct (si); - int i, jsbound = (frame.mode == 1) ? (frame.modeExt << 2) + 4 : 32; - - if (frame.numChannels == 2) - { - for (i = 0; i < jsbound; ++i) - { - si.allocation[i][0] = getBitsUint8 (4); - si.allocation[i][1] = getBitsUint8 (4); - } - - for (i = jsbound; i < 32; ++i) - si.allocation[i][0] = si.allocation[i][1] = getBitsUint8 (4); - - for (i = 0; i < 32; ++i) - { - si.scaleFactor[i][0] = si.allocation[i][0] ? getBitsUint8 (6) : 0; - si.scaleFactor[i][1] = si.allocation[i][1] ? getBitsUint8 (6) : 0; - } - } - else - { - for (i = 0; i < 32; ++i) - si.allocation[i][0] = getBitsUint8 (4); - - for (i = 0; i < 32; ++i) - si.scaleFactor[i][0] = si.allocation[i][0] ? getBitsUint8 (6) : 0; - } - } - - void layer1Step2 (SideInfoLayer1& si, float fraction[2][32]) noexcept - { - if (frame.numChannels == 2) - { - int i, jsbound = (frame.mode == 1) ? (frame.modeExt << 2) + 4 : 32; - - for (i = 0; i < jsbound; ++i) - { - const uint8 n0 = si.allocation[i][0]; - const uint8 n1 = si.allocation[i][1]; - fraction[0][i] = n0 > 0 ? (float) (((-1 << n0) + getBitsUint16 (n0 + 1) + 1) * constants.muls[n0 + 1][si.scaleFactor[i][0]]) : 0; - fraction[1][i] = n1 > 0 ? (float) (((-1 << n1) + getBitsUint16 (n1 + 1) + 1) * constants.muls[n1 + 1][si.scaleFactor[i][1]]) : 0; - } - - for (i = jsbound; i < 32; ++i) - { - const uint8 n = si.allocation[i][0]; - - if (n > 0) - { - const uint32 w = ((uint32) (-1 << n) + getBitsUint16 (n + 1) + 1); - fraction[0][i] = (float) (w * constants.muls[n + 1][si.scaleFactor[i][0]]); - fraction[1][i] = (float) (w * constants.muls[n + 1][si.scaleFactor[i][1]]); - } - else - fraction[0][i] = fraction[1][i] = 0; - } - } - else - { - for (int i = 0; i < 32; ++i) - { - const uint8 n = si.allocation[i][0]; - const uint8 j = si.scaleFactor[i][0]; - - if (n > 0) - fraction[0][i] = (float) (((-1 << n) + getBitsUint16 (n + 1) + 1) * constants.muls[n + 1][j]); - else - fraction[0][i] = 0; - } - } - } - - void layer2Step1 (SideInfoLayer2& si) noexcept - { - zerostruct (si); - const int sblimit = frame.layer2SubBandLimit; - const int jsbound = (frame.mode == 1) ? (frame.modeExt << 2) + 4 : frame.layer2SubBandLimit; - const AllocationTable* allocTable = frame.allocationTable; - uint8 scfsi[32][2]; - - if (frame.numChannels == 2) - { - for (int i = 0; i < jsbound; ++i) - { - const int16 step = allocTable->bits; - allocTable += (1 << step); - si.allocation[i][0] = getBitsUint8 (step); - si.allocation[i][1] = getBitsUint8 (step); - } - - for (int i = jsbound; i < sblimit; ++i) - { - const int16 step = allocTable->bits; - const uint8 b0 = getBitsUint8 (step); - allocTable += (1 << step); - si.allocation[i][0] = b0; - si.allocation[i][1] = b0; - } - - for (int i = 0; i < sblimit; ++i) - { - scfsi[i][0] = si.allocation[i][0] ? getBitsUint8 (2) : 0; - scfsi[i][1] = si.allocation[i][1] ? getBitsUint8 (2) : 0; - } - } - else - { - for (int i = 0; i < sblimit; ++i) - { - const int16 step = allocTable->bits; - allocTable += (1 << step); - si.allocation[i][0] = getBitsUint8 (step); - } - - for (int i = 0; i < sblimit; ++i) - scfsi[i][0] = si.allocation[i][0] ? getBitsUint8 (2) : 0; - } - - for (int i = 0; i < sblimit; ++i) - { - for (int ch = 0; ch < frame.numChannels; ++ch) - { - uint8 s0 = 0, s1 = 0, s2 = 0; - - if (si.allocation[i][ch]) - { - switch (scfsi[i][ch]) - { - case 0: - s0 = getBitsUint8 (6); - s1 = getBitsUint8 (6); - s2 = getBitsUint8 (6); - break; - case 1: - s1 = s0 = getBitsUint8 (6); - s2 = getBitsUint8 (6); - break; - case 2: - s2 = s1 = s0 = getBitsUint8 (6); - break; - case 3: - s0 = getBitsUint8 (6); - s2 = s1 = getBitsUint8 (6); - break; - default: - break; - } - } - - si.scaleFactor[i][ch][0] = s0; - si.scaleFactor[i][ch][1] = s1; - si.scaleFactor[i][ch][2] = s2; - } - } - } - - void layer2Step2 (SideInfoLayer2& si, const int gr, float fraction[2][4][32]) noexcept - { - const AllocationTable* allocTable = frame.allocationTable; - const int jsbound = (frame.mode == 1) ? (frame.modeExt << 2) + 4 : frame.layer2SubBandLimit; - - for (int i = 0; i < jsbound; ++i) - { - const int16 step = allocTable->bits; - - for (int ch = 0; ch < frame.numChannels; ++ch) - { - const uint8 ba = si.allocation[i][ch]; - if (ba != 0) - { - const uint8 x1 = jmin ((uint8) 63, si.scaleFactor[i][ch][gr]); - const AllocationTable* const alloc2 = allocTable + ba; - const int16 k = jmin ((int16) 16, alloc2->bits); - const int16 d1 = alloc2->d; - - if (d1 < 0) - { - const double cm = constants.muls[k][x1]; - fraction[ch][0][i] = (float) (((int) getBits (k) + d1) * cm); - fraction[ch][1][i] = (float) (((int) getBits (k) + d1) * cm); - fraction[ch][2][i] = (float) (((int) getBits (k) + d1) * cm); - } - else - { - const uint8* const tab = constants.getGroupTable (d1, getBits (k)); - fraction[ch][0][i] = (float) constants.muls[tab[0]][x1]; - fraction[ch][1][i] = (float) constants.muls[tab[1]][x1]; - fraction[ch][2][i] = (float) constants.muls[tab[2]][x1]; - } - } - else - { - fraction[ch][0][i] = fraction[ch][1][i] = fraction[ch][2][i] = 0; - } - } - - allocTable += (1 << step); - } - - for (int i = jsbound; i < frame.layer2SubBandLimit; ++i) - { - const int16 step = allocTable->bits; - const uint8 ba = si.allocation[i][0]; - - if (ba != 0) - { - const AllocationTable* const alloc2 = allocTable + ba; - int16 k = alloc2->bits; - int16 d1 = alloc2->d; - k = (k <= 16) ? k : 16; - - if (d1 < 0) - { - const int v0 = (int) getBits (k); - const int v1 = (int) getBits (k); - const int v2 = (int) getBits (k); - - for (int ch = 0; ch < frame.numChannels; ++ch) - { - const uint8 x1 = jmin ((uint8) 63, si.scaleFactor[i][ch][gr]); - const double cm = constants.muls[k][x1]; - fraction[ch][0][i] = (float) ((v0 + d1) * cm); - fraction[ch][1][i] = (float) ((v1 + d1) * cm); - fraction[ch][2][i] = (float) ((v2 + d1) * cm); - } - } - else - { - const uint8* const tab = constants.getGroupTable (d1, getBits (k)); - const uint8 k0 = tab[0]; - const uint8 k1 = tab[1]; - const uint8 k2 = tab[2]; - - for (int ch = 0; ch < frame.numChannels; ++ch) - { - const uint8 x1 = jmin ((uint8) 63, si.scaleFactor[i][ch][gr]); - fraction[ch][0][i] = (float) constants.muls[k0][x1]; - fraction[ch][1][i] = (float) constants.muls[k1][x1]; - fraction[ch][2][i] = (float) constants.muls[k2][x1]; - } - } - } - else - { - fraction[0][0][i] = fraction[0][1][i] = fraction[0][2][i] = 0; - fraction[1][0][i] = fraction[1][1][i] = fraction[1][2][i] = 0; - } - allocTable += (1 << step); - } - - for (int ch = 0; ch < frame.numChannels; ++ch) - for (int i = frame.layer2SubBandLimit; i < 32; ++i) - fraction[ch][0][i] = fraction[ch][1][i] = fraction[ch][2][i] = 0; - } - - void getLayer3SideInfo1 (const int stereo, const bool msStereo, const int sampleRate, const int single) noexcept - { - const int powdiff = (single == 3) ? 4 : 0; - sideinfo.mainDataStart = getBits (9); - sideinfo.privateBits = getBitsUnchecked (stereo == 1 ? 5 : 3); - - for (int ch = 0; ch < stereo; ++ch) - { - sideinfo.ch[ch].gr[0].scfsi = -1; - sideinfo.ch[ch].gr[1].scfsi = (int) getBitsUnchecked (4); - } - - for (int gr = 0; gr < 2; ++gr) - { - for (int ch = 0; ch < stereo; ++ch) - { - Layer3SideInfo::Info& granule = sideinfo.ch[ch].gr[gr]; - - granule.part2_3Length = getBits (12); - granule.bigValues = jmin (288u, getBitsUnchecked (9)); - - const int qss = (int) getBitsUnchecked (8); - granule.pow2gain = constants.powToGains + 256 - qss + powdiff; - - if (msStereo) - granule.pow2gain += 2; - - granule.scaleFactorCompression = getBitsUnchecked (4); - - if (getOneBit()) - { - granule.blockType = getBitsUnchecked (2); - granule.mixedBlockFlag = getOneBit(); - granule.tableSelect[0] = getBitsUnchecked (5); - granule.tableSelect[1] = getBitsUnchecked (5); - granule.tableSelect[2] = 0; - - for (int i = 0; i < 3; ++i) - { - const uint32 sbg = (getBitsUnchecked (3) << 3); - granule.fullGain[i] = granule.pow2gain + sbg; - } - - granule.region1Start = 36 >> 1; - granule.region2Start = 576 >> 1; - } - else - { - for (int i = 0; i < 3; ++i) - granule.tableSelect[i] = getBitsUnchecked (5); - - const int r0c = (int) getBitsUnchecked (4); - const int r1c = (int) getBitsUnchecked (3); - const int region0index = jmin (22, r0c + 1); - const int region1index = jmin (22, r0c + 1 + r1c + 1); - - granule.region1Start = (uint32) (bandInfo[sampleRate].longIndex[region0index] >> 1); - granule.region2Start = (uint32) (bandInfo[sampleRate].longIndex[region1index] >> 1); - granule.blockType = 0; - granule.mixedBlockFlag = 0; - } - - granule.preflag = getOneBit(); - granule.scaleFactorScale = getOneBit(); - granule.count1TableSelect = getOneBit(); - } - } - } - - void getLayer3SideInfo2 (const int stereo, const bool msStereo, const int sampleRate, const int single) noexcept - { - const int powdiff = (single == 3) ? 4 : 0; - sideinfo.mainDataStart = getBits (8); - sideinfo.privateBits = stereo == 1 ? getOneBit() : getBitsUnchecked (2); - - for (int ch = 0; ch < stereo; ++ch) - { - Layer3SideInfo::Info& granule = sideinfo.ch[ch].gr[0]; - - granule.part2_3Length = getBits (12); - granule.bigValues = jmin (288u, getBitsUnchecked (9)); - - const uint32 qss = getBitsUnchecked (8); - granule.pow2gain = constants.powToGains + 256 - qss + powdiff; - - if (msStereo) - granule.pow2gain += 2; - - granule.scaleFactorCompression = getBits (9); - - if (getOneBit()) - { - granule.blockType = getBitsUnchecked (2); - granule.mixedBlockFlag = getOneBit(); - granule.tableSelect[0] = getBitsUnchecked (5); - granule.tableSelect[1] = getBitsUnchecked (5); - granule.tableSelect[2] = 0; - - for (int i = 0; i < 3; ++i) - { - const uint32 sbg = (getBitsUnchecked (3) << 3); - granule.fullGain[i] = granule.pow2gain + sbg; - } - - if (granule.blockType == 0) - {} - - if (granule.blockType == 2) - granule.region1Start = sampleRate == 8 ? 36 : (36 >> 1); - else - granule.region1Start = sampleRate == 8 ? (108 >> 1) : (54 >> 1); - - granule.region2Start = 576 >> 1; - } - else - { - for (int i = 0; i < 3; ++i) - granule.tableSelect[i] = getBitsUnchecked (5); - - const int r0c = (int) getBitsUnchecked (4); - const int r1c = (int) getBitsUnchecked (3); - const int region0index = jmin (22, r0c + 1); - const int region1index = jmin (22, r0c + 1 + r1c + 1); - - granule.region1Start = (uint32) (bandInfo[sampleRate].longIndex[region0index] >> 1); - granule.region2Start = (uint32) (bandInfo[sampleRate].longIndex[region1index] >> 1); - granule.blockType = 0; - granule.mixedBlockFlag = 0; - } - granule.scaleFactorScale = getOneBit(); - granule.count1TableSelect = getOneBit(); - } - } - - int getLayer3ScaleFactors1 (int* scf, const Layer3SideInfo::Info& granule) noexcept - { - static const uint8 lengths[2][16] = - { - { 0, 0, 0, 0, 3, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4 }, - { 0, 1, 2, 3, 0, 1, 2, 3, 1, 2, 3, 1, 2, 3, 2, 3 } - }; - - int numBits; - const int num0 = lengths[0][granule.scaleFactorCompression]; - const int num1 = lengths[1][granule.scaleFactorCompression]; - - if (granule.blockType == 2) - { - int i = 18; - numBits = (num0 + num1) * 18; - - if (granule.mixedBlockFlag) - { - for (int j = 8; --j >= 0;) *scf++ = (int) getBitsUnchecked (num0); - numBits -= num0; - i = 9; - } - - for (; --i >= 0;) *scf++ = (int) getBitsUnchecked (num0); - for (i = 18; --i >= 0;) *scf++ = (int) getBitsUnchecked (num1); - - *scf++ = 0; - *scf++ = 0; - *scf++ = 0; - } - else - { - const int scfsi = granule.scfsi; - - if (scfsi < 0) - { - for (int i = 11; --i >= 0;) *scf++ = (int) getBitsUnchecked (num0); - for (int j = 10; --j >= 0;) *scf++ = (int) getBitsUnchecked (num1); - numBits = (num0 + num1) * 10 + num0; - } - else - { - numBits = 0; - if ((scfsi & 8) == 0) - { - for (int i = 6; --i >= 0;) *scf++ = (int) getBitsUnchecked (num0); - numBits += num0 * 6; - } - else - scf += 6; - - if ((scfsi & 4) == 0) - { - for (int i = 5; --i >= 0;) *scf++ = (int) getBitsUnchecked (num0); - numBits += num0 * 5; - } - else - scf += 5; - - if ((scfsi & 2) == 0) - { - for (int i = 5; --i >= 0;) *scf++ = (int) getBitsUnchecked (num1); - numBits += num1 * 5; - } - else - scf += 5; - - if ((scfsi & 1) == 0) - { - for (int i = 5; --i >= 0;) *scf++ = (int) getBitsUnchecked (num1); - numBits += num1 * 5; - } - else - scf += 5; - } - - *scf = 0; - } - - return numBits; - } - - int getLayer3ScaleFactors2 (int* scf, Layer3SideInfo::Info& granule, const bool iStereo) noexcept - { - static const uint8 scaleTable[3][6][4] = - { - { { 6, 5, 5, 5 }, { 6, 5, 7, 3 }, { 11, 10, 0, 0 }, { 7, 7, 7, 0 }, { 6, 6, 6, 3 }, { 8, 8, 5, 0 } }, - { { 9, 9, 9, 9 }, { 9, 9, 12, 6 }, { 18, 18, 0, 0 }, { 12, 12, 12, 0 }, { 12, 9, 9, 6 }, { 15, 12, 9, 0 } }, - { { 6, 9, 9, 9 }, { 6, 9, 12, 6 }, { 15, 18, 0, 0 }, { 6, 15, 12, 0 }, { 6, 12, 9, 6 }, { 6, 18, 9, 0 } } - }; - - uint32 len = iStereo ? constants.iLength2 [granule.scaleFactorCompression >> 1] - : constants.nLength2 [granule.scaleFactorCompression]; - - granule.preflag = (len >> 15) & 1; - - int n = 0; - if (granule.blockType == 2) - { - ++n; - if (granule.mixedBlockFlag) - ++n; - } - - const uint8* const data = scaleTable[n][(len >> 12) & 7]; - int i, numBits = 0; - - for (i = 0; i < 4; ++i) - { - int num = len & 7; - len >>= 3; - - if (num) - { - for (int j = 0; j < (int) (data[i]); ++j) - *scf++ = (int) getBitsUnchecked (num); - - numBits += data[i] * num; - } - else - { - for (int j = 0; j < (int) (data[i]); ++j) - *scf++ = 0; - } - } - - n = (n << 1) + 1; - for (i = 0; i < n; ++i) - *scf++ = 0; - - return numBits; - } - - bool layer3DequantizeSample (float xr[32][18], int* scf, Layer3SideInfo::Info& granule, int sampleRate, int part2bits) noexcept - { - const uint32 shift = 1 + granule.scaleFactorScale; - float* xrpnt = (float*) xr; - int part2remain = (int) granule.part2_3Length - part2bits; - - zeromem (xrpnt, sizeof (float) * (size_t) (&xr[32][0] - xrpnt)); - - const int bv = (int) granule.bigValues; - const int region1 = (int) granule.region1Start; - const int region2 = (int) granule.region2Start; - int l3 = ((576 >> 1) - bv) >> 1; - int l[3]; - - if (bv <= region1) - { - l[0] = bv; - l[1] = 0; - l[2] = 0; - } - else - { - l[0] = region1; - if (bv <= region2) - { - l[1] = bv - l[0]; - l[2] = 0; - } - else - { - l[1] = region2 - l[0]; - l[2] = bv - region2; - } - } - - for (int i = 0; i < 3; ++i) - if (l[i] < 0) - l[i] = 0; - - if (granule.blockType == 2) - { - int max[4]; - int step = 0, lwin = 0, cb = 0, mc = 0; - float v = 0; - int* map; - int* mapEnd; - - if (granule.mixedBlockFlag) - { - max[3] = -1; - max[0] = max[1] = max[2] = 2; - map = constants.map [sampleRate][0]; - mapEnd = constants.mapEnd [sampleRate][0]; - } - else - { - max[0] = max[1] = max[2] = max[3] = -1; - map = constants.map [sampleRate][1]; - mapEnd = constants.mapEnd [sampleRate][1]; - } - - for (int i = 0; i < 2; ++i) - { - const BitsToTableMap* h = huffmanTables1 + granule.tableSelect[i]; - - for (int lp = l[i]; lp != 0; --lp, --mc) - { - int x, y; - if (mc == 0) - { - mc = *map++; - xrpnt = ((float*) xr) + (*map++); - lwin = *map++; - cb = *map++; - - if (lwin == 3) - { - v = granule.pow2gain[ (*scf++) << shift]; - step = 1; - } - else - { - v = granule.fullGain[lwin][ (*scf++) << shift]; - step = 3; - } - } - - const int16* val = h->table; - - while ((y = *val++) < 0) - { - if (getOneBit()) - val -= y; - - --part2remain; - } - - x = y >> 4; - y &= 15; - - if (x == 15) - { - max[lwin] = cb; - part2remain -= h->bits + 1; - x += getBits ((int) h->bits); - *xrpnt = constants.nToThe4Over3[x] * (getOneBit() ? -v : v); - } - else if (x) - { - max[lwin] = cb; - *xrpnt = constants.nToThe4Over3[x] * (getOneBit() ? -v : v); - --part2remain; - } - else - *xrpnt = 0; - - xrpnt += step; - - if (y == 15) - { - max[lwin] = cb; - part2remain -= h->bits + 1; - y += getBits ((int) h->bits); - *xrpnt = constants.nToThe4Over3[y] * (getOneBit() ? -v : v); - } - else if (y) - { - max[lwin] = cb; - *xrpnt = constants.nToThe4Over3[y] * (getOneBit() ? -v : v); - --part2remain; - } - else - *xrpnt = 0; - - xrpnt += step; - } - } - - for (; l3 && (part2remain > 0); --l3) - { - const BitsToTableMap* h = huffmanTables2 + granule.count1TableSelect; - const int16* val = h->table; - int16 a; - - while ((a = *val++) < 0) - { - if (part2remain <= 0) - { - a = 0; - break; - } - - --part2remain; - if (getOneBit()) - val -= a; - } - - for (int i = 0; i < 4; ++i) - { - if ((i & 1) == 0) - { - if (mc == 0) - { - mc = *map++; - xrpnt = ((float*) xr) + (*map++); - lwin = *map++; - cb = *map++; - - if (lwin == 3) - { - v = granule.pow2gain[ (*scf++) << shift]; - step = 1; - } - else - { - v = granule.fullGain[lwin][ (*scf++) << shift]; - step = 3; - } - } - - --mc; - } - - if ((a & (8 >> i))) - { - max[lwin] = cb; - if (part2remain == 0) - break; - - --part2remain; - *xrpnt = getOneBit() ? -v : v; - } - else - *xrpnt = 0; - - xrpnt += step; - } - } - - while (map < mapEnd) - { - if (mc == 0) - { - mc = *map++; - xrpnt = ((float*) xr) + *map++; - step = (*map++ == 3) ? 1 : 3; - ++map; - } - - --mc; - *xrpnt = 0; xrpnt += step; - *xrpnt = 0; xrpnt += step; - } - - granule.maxBand[0] = (uint32) (max[0] + 1); - granule.maxBand[1] = (uint32) (max[1] + 1); - granule.maxBand[2] = (uint32) (max[2] + 1); - granule.maxBandl = (uint32) (max[3] + 1); - - const int rmax = jmax (max[0], max[1], max[3]) + 1; - granule.maxb = rmax ? (uint32) constants.shortLimit[sampleRate][rmax] - : (uint32) constants.longLimit[sampleRate][max[3] + 1]; - } - else - { - static const int pretab1[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 3, 3, 3, 2, 0 }; - static const int pretab2[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - - const int* pretab = (const int*) (granule.preflag ? pretab1 : pretab2); - int max = -1, cb = 0, mc = 0; - int* map = constants.map [sampleRate][2]; - float v = 0; - - for (int i = 0; i < 3; ++i) - { - const BitsToTableMap* h = huffmanTables1 + granule.tableSelect[i]; - - for (int lp = l[i]; lp != 0; --lp, --mc) - { - if (mc == 0) - { - mc = *map++; - v = granule.pow2gain [((*scf++) + (*pretab++)) << shift]; - cb = *map++; - } - - const int16* val = h->table; - int y; - - while ((y = *val++) < 0) - { - if (getOneBit()) val -= y; - --part2remain; - } - - int x = y >> 4; - y &= 15; - - if (x == 15) - { - max = cb; - part2remain -= h->bits + 1; - x += getBits ((int) h->bits); - *xrpnt++ = constants.nToThe4Over3[x] * (getOneBit() ? -v : v); - } - else if (x) - { - max = cb; - *xrpnt++ = constants.nToThe4Over3[x] * (getOneBit() ? -v : v); - --part2remain; - } - else - *xrpnt++ = 0; - - if (y == 15) - { - max = cb; - part2remain -= h->bits + 1; - y += getBits ((int) h->bits); - *xrpnt++ = constants.nToThe4Over3[y] * (getOneBit() ? -v : v); - } - else if (y) - { - max = cb; - *xrpnt++ = constants.nToThe4Over3[y] * (getOneBit() ? -v : v); - --part2remain; - } - else - *xrpnt++ = 0; - } - } - - for (; l3 && part2remain > 0; --l3) - { - const BitsToTableMap* h = huffmanTables2 + granule.count1TableSelect; - const int16* values = h->table; - int16 a; - - while ((a = *values++) < 0) - { - if (part2remain <= 0) - { - a = 0; - break; - } - - --part2remain; - if (getOneBit()) - values -= a; - } - - for (int i = 0; i < 4; ++i) - { - if ((i & 1) == 0) - { - if (mc == 0) - { - mc = *map++; - cb = *map++; - v = granule.pow2gain [((*scf++) + (*pretab++)) << shift]; - } - --mc; - } - - if ((a & (0x8 >> i))) - { - max = cb; - - if (part2remain <= 0) - break; - - --part2remain; - *xrpnt++ = getOneBit() ? -v : v; - } - else - *xrpnt++ = 0; - } - } - - zeromem (xrpnt, sizeof (float) * (size_t) (&xr[32][0] - xrpnt)); - - granule.maxBandl = (uint32) (max + 1); - granule.maxb = (uint32) constants.longLimit[sampleRate][granule.maxBandl]; - } - - while (part2remain > 16) - { - getBits (16); - part2remain -= 16; - } - - if (part2remain > 0) - getBits (part2remain); - else if (part2remain < 0) - return true; - - return false; - } - - void layer3Hybrid (float fsIn[32][18], float tsOut[18][32], int ch, const Layer3SideInfo::Info& granule) noexcept - { - float* ts = (float*) tsOut; - float* rawout1, *rawout2; - int sb = 0; - - { - int b = hybridBlockIndex[ch]; - rawout1 = hybridBlock[b][ch]; - b = 1 - b; - rawout2 = hybridBlock[b][ch]; - hybridBlockIndex[ch] = b; - } - - if (granule.mixedBlockFlag) - { - sb = 2; - DCT::dct36 (fsIn[0], rawout1, rawout2, constants.win[0], ts); - DCT::dct36 (fsIn[1], rawout1 + 18, rawout2 + 18, constants.win1[0], ts + 1); - rawout1 += 36; - rawout2 += 36; - ts += 2; - } - - const uint32 bt = granule.blockType; - if (bt == 2) - { - for (; sb < (int) granule.maxb; sb += 2, ts += 2, rawout1 += 36, rawout2 += 36) - { - DCT::dct12 (fsIn[sb], rawout1, rawout2, constants.win[2], ts); - DCT::dct12 (fsIn[sb + 1], rawout1 + 18, rawout2 + 18, constants.win1[2], ts + 1); - } - } - else - { - for (; sb < (int) granule.maxb; sb += 2, ts += 2, rawout1 += 36, rawout2 += 36) - { - DCT::dct36 (fsIn[sb], rawout1, rawout2, constants.win[bt], ts); - DCT::dct36 (fsIn[sb + 1], rawout1 + 18, rawout2 + 18, constants.win1[bt], ts + 1); - } - } - - for (; sb < 32; ++sb, ++ts) - { - for (int i = 0; i < 18; ++i) - { - ts[i * 32] = *rawout1++; - *rawout2++ = 0; - } - } - } - - void synthesiseStereo (const float* bandPtr0, const float* bandPtr1, float* out0, float* out1, int& samplesDone) noexcept - { - int dummy = samplesDone; - synthesise (bandPtr0, 0, out0, dummy); - synthesise (bandPtr1, 1, out1, samplesDone); - } - - void synthesise (const float* bandPtr, const int channel, float* out, int& samplesDone) - { - out += samplesDone; - const int bo = channel == 0 ? ((synthBo - 1) & 15) : synthBo; - float (*buf)[0x110] = synthBuffers[channel]; - float* b0; - int j, bo1 = bo; - - if (bo & 1) - { - b0 = buf[0]; - DCT::dct64 (buf[1] + ((bo + 1) & 15), buf[0] + bo, bandPtr); - } - else - { - ++bo1; - b0 = buf[1]; - DCT::dct64 (buf[0] + bo, buf[1] + bo1, bandPtr); - } - - synthBo = bo; - const float* window = constants.decodeWin + 16 - bo1; - - for (j = 16; j != 0; --j, b0 += 16, window += 32) - { - float sum = window[0] * b0[0]; sum -= window[1] * b0[1]; - sum += window[2] * b0[2]; sum -= window[3] * b0[3]; - sum += window[4] * b0[4]; sum -= window[5] * b0[5]; - sum += window[6] * b0[6]; sum -= window[7] * b0[7]; - sum += window[8] * b0[8]; sum -= window[9] * b0[9]; - sum += window[10] * b0[10]; sum -= window[11] * b0[11]; - sum += window[12] * b0[12]; sum -= window[13] * b0[13]; - sum += window[14] * b0[14]; sum -= window[15] * b0[15]; - *out++ = sum; - } - - { - float sum = window[0] * b0[0]; sum += window[2] * b0[2]; - sum += window[4] * b0[4]; sum += window[6] * b0[6]; - sum += window[8] * b0[8]; sum += window[10] * b0[10]; - sum += window[12] * b0[12]; sum += window[14] * b0[14]; - *out++ = sum; - b0 -= 16; window -= 32; - window += bo1 << 1; - } - - for (j = 15; j != 0; --j, b0 -= 16, window -= 32) - { - float sum = -window[-1] * b0[0]; sum -= window[-2] * b0[1]; - sum -= window[-3] * b0[2]; sum -= window[-4] * b0[3]; - sum -= window[-5] * b0[4]; sum -= window[-6] * b0[5]; - sum -= window[-7] * b0[6]; sum -= window[-8] * b0[7]; - sum -= window[-9] * b0[8]; sum -= window[-10] * b0[9]; - sum -= window[-11] * b0[10]; sum -= window[-12] * b0[11]; - sum -= window[-13] * b0[12]; sum -= window[-14] * b0[13]; - sum -= window[-15] * b0[14]; sum -= window[0] * b0[15]; - *out++ = sum; - } - - samplesDone += 32; - } - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MP3Stream) -}; - -//============================================================================== -static const char* const mp3FormatName = "MP3 file"; - -//============================================================================== -class MP3Reader : public AudioFormatReader -{ -public: - MP3Reader (InputStream* const in) - : AudioFormatReader (in, mp3FormatName), - stream (*in), currentPosition (0), - decodedStart (0), decodedEnd (0) - { - skipID3(); - const int64 streamPos = stream.stream.getPosition(); - - if (readNextBlock()) - { - bitsPerSample = 32; - usesFloatingPointData = true; - sampleRate = stream.frame.getFrequency(); - numChannels = (unsigned int) stream.frame.numChannels; - lengthInSamples = findLength (streamPos); - } - } - - bool readSamples (int** destSamples, int numDestChannels, int startOffsetInDestBuffer, - int64 startSampleInFile, int numSamples) override - { - jassert (destSamples != nullptr); - - if (currentPosition != startSampleInFile) - { - if (! stream.seek ((int) (startSampleInFile / 1152 - 1))) - { - currentPosition = -1; - createEmptyDecodedData(); - } - else - { - decodedStart = decodedEnd = 0; - const int64 streamPos = stream.currentFrameIndex * 1152; - int toSkip = (int) (startSampleInFile - streamPos); - jassert (toSkip >= 0); - - while (toSkip > 0) - { - if (! readNextBlock()) - { - createEmptyDecodedData(); - break; - } - - const int numReady = decodedEnd - decodedStart; - - if (numReady > toSkip) - { - decodedStart += toSkip; - break; - } - - toSkip -= numReady; - } - - currentPosition = startSampleInFile; - } - } - - while (numSamples > 0) - { - if (decodedEnd <= decodedStart && ! readNextBlock()) - { - for (int i = numDestChannels; --i >= 0;) - if (destSamples[i] != nullptr) - zeromem (destSamples[i] + startOffsetInDestBuffer, sizeof (float) * (size_t) numSamples); - - return false; - } - - const int numToCopy = jmin (decodedEnd - decodedStart, numSamples); - float* const* const dst = reinterpret_cast (destSamples); - memcpy (dst[0] + startOffsetInDestBuffer, decoded0 + decodedStart, sizeof (float) * (size_t) numToCopy); - - if (numDestChannels > 1 && dst[1] != nullptr) - memcpy (dst[1] + startOffsetInDestBuffer, (numChannels < 2 ? decoded0 : decoded1) + decodedStart, sizeof (float) * (size_t) numToCopy); - - startOffsetInDestBuffer += numToCopy; - decodedStart += numToCopy; - currentPosition += numToCopy; - numSamples -= numToCopy; - } - - return true; - } - -private: - MP3Stream stream; - int64 currentPosition; - enum { decodedDataSize = 1152 }; - float decoded0 [decodedDataSize], decoded1 [decodedDataSize]; - int decodedStart, decodedEnd; - - void createEmptyDecodedData() noexcept - { - zeromem (decoded0, sizeof (decoded0)); - zeromem (decoded1, sizeof (decoded1)); - decodedStart = 0; - decodedEnd = decodedDataSize; - } - - bool readNextBlock() - { - for (int attempts = 10; --attempts >= 0;) - { - int samplesDone = 0; - const int result = stream.decodeNextBlock (decoded0, decoded1, samplesDone); - - if (result > 0 && stream.stream.isExhausted()) - { - createEmptyDecodedData(); - return true; - } - - if (result <= 0) - { - decodedStart = 0; - decodedEnd = samplesDone; - return result == 0; - } - } - - return false; - } - - void skipID3() - { - const int64 originalPosition = stream.stream.getPosition(); - const uint32 firstWord = (uint32) stream.stream.readInt(); - - if ((firstWord & 0xffffff) == 0x334449) - { - uint8 buffer[6]; - - if (stream.stream.read (buffer, 6) == 6 - && buffer[0] != 0xff - && ((buffer[2] | buffer[3] | buffer[4] | buffer[5]) & 0x80) == 0) - { - const uint32 length = (((uint32) buffer[2]) << 21) - | (((uint32) buffer[3]) << 14) - | (((uint32) buffer[4]) << 7) - | ((uint32) buffer[5]); - - stream.stream.skipNextBytes (length); - return; - } - } - - stream.stream.setPosition (originalPosition); - } - - int64 findLength (int64 streamStartPos) - { - int64 numFrames = stream.numFrames; - - if (numFrames <= 0) - { - const int64 streamSize = stream.stream.getTotalLength(); - - if (streamSize > 0) - { - const int bytesPerFrame = stream.frame.frameSize + 4; - - if (bytesPerFrame == 417 || bytesPerFrame == 418) - numFrames = roundToInt ((streamSize - streamStartPos) / 417.95918); // more accurate for 128k - else - numFrames = (streamSize - streamStartPos) / bytesPerFrame; - } - } - - return numFrames * 1152; - } - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MP3Reader) -}; - -} - -//============================================================================== -MP3AudioFormat::MP3AudioFormat() : AudioFormat (MP3Decoder::mp3FormatName, ".mp3") {} -MP3AudioFormat::~MP3AudioFormat() {} - -Array MP3AudioFormat::getPossibleSampleRates() { return Array(); } -Array MP3AudioFormat::getPossibleBitDepths() { return Array(); } -bool MP3AudioFormat::canDoStereo() { return true; } -bool MP3AudioFormat::canDoMono() { return true; } -bool MP3AudioFormat::isCompressed() { return true; } -StringArray MP3AudioFormat::getQualityOptions() { return StringArray(); } - -AudioFormatReader* MP3AudioFormat::createReaderFor (InputStream* sourceStream, const bool deleteStreamIfOpeningFails) -{ - ScopedPointer r (new MP3Decoder::MP3Reader (sourceStream)); - - if (r->lengthInSamples > 0) - return r.release(); - - if (! deleteStreamIfOpeningFails) - r->input = nullptr; - - return nullptr; -} - -AudioFormatWriter* MP3AudioFormat::createWriterFor (OutputStream*, double /*sampleRateToUse*/, - unsigned int /*numberOfChannels*/, int /*bitsPerSample*/, - const StringPairArray& /*metadataValues*/, int /*qualityOptionIndex*/) -{ - return nullptr; -} - -#endif diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/codecs/juce_MP3AudioFormat.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/codecs/juce_MP3AudioFormat.h deleted file mode 100644 index e89c05db3a..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/codecs/juce_MP3AudioFormat.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#if JUCE_USE_MP3AUDIOFORMAT || DOXYGEN - -//============================================================================== -/** - Software-based MP3 decoding format (doesn't currently provide an encoder). - - IMPORTANT DISCLAIMER: By choosing to enable the JUCE_USE_MP3AUDIOFORMAT flag and - to compile the MP3 code into your software, you do so AT YOUR OWN RISK! By doing so, - you are agreeing that Raw Material Software is in no way responsible for any patent, - copyright, or other legal issues that you may suffer as a result. - - The code in juce_MP3AudioFormat.cpp is NOT guaranteed to be free from infringements of 3rd-party - intellectual property. If you wish to use it, please seek your own independent advice about the - legality of doing so. If you are not willing to accept full responsibility for the consequences - of using this code, then do not enable the JUCE_USE_MP3AUDIOFORMAT setting. -*/ -class MP3AudioFormat : public AudioFormat -{ -public: - //============================================================================== - MP3AudioFormat(); - ~MP3AudioFormat(); - - //============================================================================== - Array getPossibleSampleRates() override; - Array getPossibleBitDepths() override; - bool canDoStereo() override; - bool canDoMono() override; - bool isCompressed() override; - StringArray getQualityOptions() override; - - //============================================================================== - AudioFormatReader* createReaderFor (InputStream*, bool deleteStreamIfOpeningFails) override; - - AudioFormatWriter* createWriterFor (OutputStream*, double sampleRateToUse, - unsigned int numberOfChannels, int bitsPerSample, - const StringPairArray& metadataValues, int qualityOptionIndex) override; -}; - -#endif diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/codecs/juce_OggVorbisAudioFormat.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/codecs/juce_OggVorbisAudioFormat.cpp deleted file mode 100644 index 7cc12a4891..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/codecs/juce_OggVorbisAudioFormat.cpp +++ /dev/null @@ -1,532 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#if JUCE_USE_OGGVORBIS - -#if JUCE_MAC && ! defined (__MACOSX__) - #define __MACOSX__ 1 -#endif - -namespace OggVorbisNamespace -{ -#if JUCE_INCLUDE_OGGVORBIS_CODE || ! defined (JUCE_INCLUDE_OGGVORBIS_CODE) - #if JUCE_MSVC - #pragma warning (push) - #pragma warning (disable: 4267 4127 4244 4996 4100 4701 4702 4013 4133 4206 4305 4189 4706 4995 4365) - #endif - - #if JUCE_CLANG - #pragma clang diagnostic push - #pragma clang diagnostic ignored "-Wconversion" - #pragma clang diagnostic ignored "-Wshadow" - #pragma clang diagnostic ignored "-Wdeprecated-register" - #endif - - #include "oggvorbis/vorbisenc.h" - #include "oggvorbis/codec.h" - #include "oggvorbis/vorbisfile.h" - - #include "oggvorbis/bitwise.c" - #include "oggvorbis/framing.c" - #include "oggvorbis/libvorbis-1.3.2/lib/analysis.c" - #include "oggvorbis/libvorbis-1.3.2/lib/bitrate.c" - #include "oggvorbis/libvorbis-1.3.2/lib/block.c" - #include "oggvorbis/libvorbis-1.3.2/lib/codebook.c" - #include "oggvorbis/libvorbis-1.3.2/lib/envelope.c" - #include "oggvorbis/libvorbis-1.3.2/lib/floor0.c" - #include "oggvorbis/libvorbis-1.3.2/lib/floor1.c" - #include "oggvorbis/libvorbis-1.3.2/lib/info.c" - #include "oggvorbis/libvorbis-1.3.2/lib/lpc.c" - #include "oggvorbis/libvorbis-1.3.2/lib/lsp.c" - #include "oggvorbis/libvorbis-1.3.2/lib/mapping0.c" - #include "oggvorbis/libvorbis-1.3.2/lib/mdct.c" - #include "oggvorbis/libvorbis-1.3.2/lib/psy.c" - #include "oggvorbis/libvorbis-1.3.2/lib/registry.c" - #include "oggvorbis/libvorbis-1.3.2/lib/res0.c" - #include "oggvorbis/libvorbis-1.3.2/lib/sharedbook.c" - #include "oggvorbis/libvorbis-1.3.2/lib/smallft.c" - #include "oggvorbis/libvorbis-1.3.2/lib/synthesis.c" - #include "oggvorbis/libvorbis-1.3.2/lib/vorbisenc.c" - #include "oggvorbis/libvorbis-1.3.2/lib/vorbisfile.c" - #include "oggvorbis/libvorbis-1.3.2/lib/window.c" - - #if JUCE_MSVC - #pragma warning (pop) - #endif - - #if JUCE_CLANG - #pragma clang diagnostic pop - #endif -#else - #include - #include - #include -#endif -} - -#undef max -#undef min - -//============================================================================== -static const char* const oggFormatName = "Ogg-Vorbis file"; - -const char* const OggVorbisAudioFormat::encoderName = "encoder"; -const char* const OggVorbisAudioFormat::id3title = "id3title"; -const char* const OggVorbisAudioFormat::id3artist = "id3artist"; -const char* const OggVorbisAudioFormat::id3album = "id3album"; -const char* const OggVorbisAudioFormat::id3comment = "id3comment"; -const char* const OggVorbisAudioFormat::id3date = "id3date"; -const char* const OggVorbisAudioFormat::id3genre = "id3genre"; -const char* const OggVorbisAudioFormat::id3trackNumber = "id3trackNumber"; - - -//============================================================================== -class OggReader : public AudioFormatReader -{ -public: - OggReader (InputStream* const inp) - : AudioFormatReader (inp, oggFormatName), - reservoirStart (0), - samplesInReservoir (0) - { - using namespace OggVorbisNamespace; - sampleRate = 0; - usesFloatingPointData = true; - - callbacks.read_func = &oggReadCallback; - callbacks.seek_func = &oggSeekCallback; - callbacks.close_func = &oggCloseCallback; - callbacks.tell_func = &oggTellCallback; - - const int err = ov_open_callbacks (input, &ovFile, 0, 0, callbacks); - - if (err == 0) - { - vorbis_info* info = ov_info (&ovFile, -1); - - vorbis_comment* const comment = ov_comment (&ovFile, -1); - addMetadataItem (comment, "ENCODER", OggVorbisAudioFormat::encoderName); - addMetadataItem (comment, "TITLE", OggVorbisAudioFormat::id3title); - addMetadataItem (comment, "ARTIST", OggVorbisAudioFormat::id3artist); - addMetadataItem (comment, "ALBUM", OggVorbisAudioFormat::id3album); - addMetadataItem (comment, "COMMENT", OggVorbisAudioFormat::id3comment); - addMetadataItem (comment, "DATE", OggVorbisAudioFormat::id3date); - addMetadataItem (comment, "GENRE", OggVorbisAudioFormat::id3genre); - addMetadataItem (comment, "TRACKNUMBER", OggVorbisAudioFormat::id3trackNumber); - - lengthInSamples = (uint32) ov_pcm_total (&ovFile, -1); - numChannels = (unsigned int) info->channels; - bitsPerSample = 16; - sampleRate = info->rate; - - reservoir.setSize ((int) numChannels, (int) jmin (lengthInSamples, (int64) 4096)); - } - } - - ~OggReader() - { - OggVorbisNamespace::ov_clear (&ovFile); - } - - void addMetadataItem (OggVorbisNamespace::vorbis_comment* comment, const char* name, const char* metadataName) - { - if (const char* value = vorbis_comment_query (comment, name, 0)) - metadataValues.set (metadataName, value); - } - - //============================================================================== - bool readSamples (int** destSamples, int numDestChannels, int startOffsetInDestBuffer, - int64 startSampleInFile, int numSamples) override - { - while (numSamples > 0) - { - const int numAvailable = (int) (reservoirStart + samplesInReservoir - startSampleInFile); - - if (startSampleInFile >= reservoirStart && numAvailable > 0) - { - // got a few samples overlapping, so use them before seeking.. - - const int numToUse = jmin (numSamples, numAvailable); - - for (int i = jmin (numDestChannels, reservoir.getNumChannels()); --i >= 0;) - if (destSamples[i] != nullptr) - memcpy (destSamples[i] + startOffsetInDestBuffer, - reservoir.getReadPointer (i, (int) (startSampleInFile - reservoirStart)), - sizeof (float) * (size_t) numToUse); - - startSampleInFile += numToUse; - numSamples -= numToUse; - startOffsetInDestBuffer += numToUse; - - if (numSamples == 0) - break; - } - - if (startSampleInFile < reservoirStart - || startSampleInFile + numSamples > reservoirStart + samplesInReservoir) - { - // buffer miss, so refill the reservoir - int bitStream = 0; - - reservoirStart = jmax (0, (int) startSampleInFile); - samplesInReservoir = reservoir.getNumSamples(); - - if (reservoirStart != (int) OggVorbisNamespace::ov_pcm_tell (&ovFile)) - OggVorbisNamespace::ov_pcm_seek (&ovFile, reservoirStart); - - int offset = 0; - int numToRead = samplesInReservoir; - - while (numToRead > 0) - { - float** dataIn = nullptr; - - const long samps = OggVorbisNamespace::ov_read_float (&ovFile, &dataIn, numToRead, &bitStream); - if (samps <= 0) - break; - - jassert (samps <= numToRead); - - for (int i = jmin ((int) numChannels, reservoir.getNumChannels()); --i >= 0;) - memcpy (reservoir.getWritePointer (i, offset), dataIn[i], sizeof (float) * (size_t) samps); - - numToRead -= samps; - offset += samps; - } - - if (numToRead > 0) - reservoir.clear (offset, numToRead); - } - } - - if (numSamples > 0) - { - for (int i = numDestChannels; --i >= 0;) - if (destSamples[i] != nullptr) - zeromem (destSamples[i] + startOffsetInDestBuffer, sizeof (int) * (size_t) numSamples); - } - - return true; - } - - //============================================================================== - static size_t oggReadCallback (void* ptr, size_t size, size_t nmemb, void* datasource) - { - return (size_t) (static_cast (datasource)->read (ptr, (int) (size * nmemb))) / size; - } - - static int oggSeekCallback (void* datasource, OggVorbisNamespace::ogg_int64_t offset, int whence) - { - InputStream* const in = static_cast (datasource); - - if (whence == SEEK_CUR) - offset += in->getPosition(); - else if (whence == SEEK_END) - offset += in->getTotalLength(); - - in->setPosition (offset); - return 0; - } - - static int oggCloseCallback (void*) - { - return 0; - } - - static long oggTellCallback (void* datasource) - { - return (long) static_cast (datasource)->getPosition(); - } - -private: - OggVorbisNamespace::OggVorbis_File ovFile; - OggVorbisNamespace::ov_callbacks callbacks; - AudioSampleBuffer reservoir; - int reservoirStart, samplesInReservoir; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (OggReader) -}; - -//============================================================================== -class OggWriter : public AudioFormatWriter -{ -public: - OggWriter (OutputStream* const out, - const double sampleRate_, - const unsigned int numChannels_, - const unsigned int bitsPerSample_, - const int qualityIndex, - const StringPairArray& metadata) - : AudioFormatWriter (out, oggFormatName, sampleRate_, numChannels_, bitsPerSample_), - ok (false) - { - using namespace OggVorbisNamespace; - - vorbis_info_init (&vi); - - if (vorbis_encode_init_vbr (&vi, (int) numChannels_, (int) sampleRate_, - jlimit (0.0f, 1.0f, qualityIndex * 0.1f)) == 0) - { - vorbis_comment_init (&vc); - - addMetadata (metadata, OggVorbisAudioFormat::encoderName, "ENCODER"); - addMetadata (metadata, OggVorbisAudioFormat::id3title, "TITLE"); - addMetadata (metadata, OggVorbisAudioFormat::id3artist, "ARTIST"); - addMetadata (metadata, OggVorbisAudioFormat::id3album, "ALBUM"); - addMetadata (metadata, OggVorbisAudioFormat::id3comment, "COMMENT"); - addMetadata (metadata, OggVorbisAudioFormat::id3date, "DATE"); - addMetadata (metadata, OggVorbisAudioFormat::id3genre, "GENRE"); - addMetadata (metadata, OggVorbisAudioFormat::id3trackNumber, "TRACKNUMBER"); - - vorbis_analysis_init (&vd, &vi); - vorbis_block_init (&vd, &vb); - - ogg_stream_init (&os, Random::getSystemRandom().nextInt()); - - ogg_packet header; - ogg_packet header_comm; - ogg_packet header_code; - - vorbis_analysis_headerout (&vd, &vc, &header, &header_comm, &header_code); - - ogg_stream_packetin (&os, &header); - ogg_stream_packetin (&os, &header_comm); - ogg_stream_packetin (&os, &header_code); - - for (;;) - { - if (ogg_stream_flush (&os, &og) == 0) - break; - - output->write (og.header, (size_t) og.header_len); - output->write (og.body, (size_t) og.body_len); - } - - ok = true; - } - } - - ~OggWriter() - { - using namespace OggVorbisNamespace; - if (ok) - { - // write a zero-length packet to show ogg that we're finished.. - writeSamples (0); - - ogg_stream_clear (&os); - vorbis_block_clear (&vb); - vorbis_dsp_clear (&vd); - vorbis_comment_clear (&vc); - - vorbis_info_clear (&vi); - output->flush(); - } - else - { - vorbis_info_clear (&vi); - output = nullptr; // to stop the base class deleting this, as it needs to be returned - // to the caller of createWriter() - } - } - - //============================================================================== - bool write (const int** samplesToWrite, int numSamples) override - { - if (ok) - { - using namespace OggVorbisNamespace; - - if (numSamples > 0) - { - const double gain = 1.0 / 0x80000000u; - float** const vorbisBuffer = vorbis_analysis_buffer (&vd, numSamples); - - for (int i = (int) numChannels; --i >= 0;) - { - float* const dst = vorbisBuffer[i]; - const int* const src = samplesToWrite [i]; - - if (src != nullptr && dst != nullptr) - { - for (int j = 0; j < numSamples; ++j) - dst[j] = (float) (src[j] * gain); - } - } - } - - writeSamples (numSamples); - } - - return ok; - } - - void writeSamples (int numSamples) - { - using namespace OggVorbisNamespace; - - vorbis_analysis_wrote (&vd, numSamples); - - while (vorbis_analysis_blockout (&vd, &vb) == 1) - { - vorbis_analysis (&vb, 0); - vorbis_bitrate_addblock (&vb); - - while (vorbis_bitrate_flushpacket (&vd, &op)) - { - ogg_stream_packetin (&os, &op); - - for (;;) - { - if (ogg_stream_pageout (&os, &og) == 0) - break; - - output->write (og.header, (size_t) og.header_len); - output->write (og.body, (size_t) og.body_len); - - if (ogg_page_eos (&og)) - break; - } - } - } - } - - bool ok; - -private: - OggVorbisNamespace::ogg_stream_state os; - OggVorbisNamespace::ogg_page og; - OggVorbisNamespace::ogg_packet op; - OggVorbisNamespace::vorbis_info vi; - OggVorbisNamespace::vorbis_comment vc; - OggVorbisNamespace::vorbis_dsp_state vd; - OggVorbisNamespace::vorbis_block vb; - - void addMetadata (const StringPairArray& metadata, const char* name, const char* vorbisName) - { - const String s (metadata [name]); - - if (s.isNotEmpty()) - vorbis_comment_add_tag (&vc, vorbisName, const_cast (s.toRawUTF8())); - } - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (OggWriter) -}; - - -//============================================================================== -OggVorbisAudioFormat::OggVorbisAudioFormat() : AudioFormat (oggFormatName, ".ogg") -{ -} - -OggVorbisAudioFormat::~OggVorbisAudioFormat() -{ -} - -Array OggVorbisAudioFormat::getPossibleSampleRates() -{ - const int rates[] = { 8000, 11025, 12000, 16000, 22050, 32000, - 44100, 48000, 88200, 96000, 176400, 192000 }; - - return Array (rates, numElementsInArray (rates)); -} - -Array OggVorbisAudioFormat::getPossibleBitDepths() -{ - const int depths[] = { 32 }; - - return Array (depths, numElementsInArray (depths)); -} - -bool OggVorbisAudioFormat::canDoStereo() { return true; } -bool OggVorbisAudioFormat::canDoMono() { return true; } -bool OggVorbisAudioFormat::isCompressed() { return true; } - -AudioFormatReader* OggVorbisAudioFormat::createReaderFor (InputStream* in, const bool deleteStreamIfOpeningFails) -{ - ScopedPointer r (new OggReader (in)); - - if (r->sampleRate > 0) - return r.release(); - - if (! deleteStreamIfOpeningFails) - r->input = nullptr; - - return nullptr; -} - -AudioFormatWriter* OggVorbisAudioFormat::createWriterFor (OutputStream* out, - double sampleRate, - unsigned int numChannels, - int bitsPerSample, - const StringPairArray& metadataValues, - int qualityOptionIndex) -{ - ScopedPointer w (new OggWriter (out, sampleRate, numChannels, - (unsigned int) bitsPerSample, qualityOptionIndex, metadataValues)); - - return w->ok ? w.release() : nullptr; -} - -StringArray OggVorbisAudioFormat::getQualityOptions() -{ - static const char* options[] = { "64 kbps", "80 kbps", "96 kbps", "112 kbps", "128 kbps", "160 kbps", - "192 kbps", "224 kbps", "256 kbps", "320 kbps", "500 kbps", 0 }; - return StringArray (options); -} - -int OggVorbisAudioFormat::estimateOggFileQuality (const File& source) -{ - if (FileInputStream* const in = source.createInputStream()) - { - ScopedPointer r (createReaderFor (in, true)); - - if (r != nullptr) - { - const double lengthSecs = r->lengthInSamples / r->sampleRate; - const int approxBitsPerSecond = (int) (source.getSize() * 8 / lengthSecs); - - const StringArray qualities (getQualityOptions()); - int bestIndex = 0; - int bestDiff = 10000; - - for (int i = qualities.size(); --i >= 0;) - { - const int diff = std::abs (qualities[i].getIntValue() - approxBitsPerSecond); - - if (diff < bestDiff) - { - bestDiff = diff; - bestIndex = i; - } - } - - return bestIndex; - } - } - - return 0; -} - -#endif diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/codecs/juce_OggVorbisAudioFormat.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/codecs/juce_OggVorbisAudioFormat.h deleted file mode 100644 index 03bc3fb6d6..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/codecs/juce_OggVorbisAudioFormat.h +++ /dev/null @@ -1,93 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#if JUCE_USE_OGGVORBIS || defined (DOXYGEN) - -//============================================================================== -/** - Reads and writes the Ogg-Vorbis audio format. - - To compile this, you'll need to set the JUCE_USE_OGGVORBIS flag. - - @see AudioFormat, -*/ -class JUCE_API OggVorbisAudioFormat : public AudioFormat -{ -public: - //============================================================================== - OggVorbisAudioFormat(); - ~OggVorbisAudioFormat(); - - //============================================================================== - Array getPossibleSampleRates() override; - Array getPossibleBitDepths() override; - bool canDoStereo() override; - bool canDoMono() override; - bool isCompressed() override; - StringArray getQualityOptions() override; - - //============================================================================== - /** Tries to estimate the quality level of an ogg file based on its size. - - If it can't read the file for some reason, this will just return 1 (medium quality), - otherwise it will return the approximate quality setting that would have been used - to create the file. - - @see getQualityOptions - */ - int estimateOggFileQuality (const File& source); - - //============================================================================== - /** Metadata property name used by the Ogg writer - if you set a string for this - value, it will be written into the ogg file as the name of the encoder app. - - @see createWriterFor - */ - static const char* const encoderName; - - static const char* const id3title; /**< Metadata key for setting an ID3 title. */ - static const char* const id3artist; /**< Metadata key for setting an ID3 artist name. */ - static const char* const id3album; /**< Metadata key for setting an ID3 album. */ - static const char* const id3comment; /**< Metadata key for setting an ID3 comment. */ - static const char* const id3date; /**< Metadata key for setting an ID3 date. */ - static const char* const id3genre; /**< Metadata key for setting an ID3 genre. */ - static const char* const id3trackNumber; /**< Metadata key for setting an ID3 track number. */ - - //============================================================================== - AudioFormatReader* createReaderFor (InputStream* sourceStream, - bool deleteStreamIfOpeningFails) override; - - AudioFormatWriter* createWriterFor (OutputStream* streamToWriteTo, - double sampleRateToUse, - unsigned int numberOfChannels, - int bitsPerSample, - const StringPairArray& metadataValues, - int qualityOptionIndex) override; - -private: - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (OggVorbisAudioFormat) -}; - - -#endif diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/codecs/juce_QuickTimeAudioFormat.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/codecs/juce_QuickTimeAudioFormat.cpp deleted file mode 100644 index 17a06da616..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/codecs/juce_QuickTimeAudioFormat.cpp +++ /dev/null @@ -1,391 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#if JUCE_QUICKTIME && ! (JUCE_64BIT || JUCE_IOS) - -} // (juce namespace) - -#if ! JUCE_WINDOWS - #define Point CarbonDummyPointName // (workaround to avoid definition of "Point" by old Carbon headers) - #define Component CarbonDummyCompName - #include - #include - #include - #include - #include - #undef Point - #undef Component -#else - #if JUCE_MSVC - #pragma warning (push) - #pragma warning (disable : 4100) - #endif - - /* If you've got an include error here, you probably need to install the QuickTime SDK and - add its header directory to your include path. - - Alternatively, if you don't need any QuickTime services, just set the JUCE_QUICKTIME flag to 0. - */ - #undef SIZE_MAX - #include - #include - #include - #include - #include - #undef SIZE_MAX - - #if JUCE_MSVC - #pragma warning (pop) - #endif -#endif - -namespace juce -{ - -bool juce_OpenQuickTimeMovieFromStream (InputStream* input, Movie& movie, Handle& dataHandle); - -static const char* const quickTimeFormatName = "QuickTime file"; - -//============================================================================== -class QTAudioReader : public AudioFormatReader -{ -public: - QTAudioReader (InputStream* const input_, const int trackNum_) - : AudioFormatReader (input_, quickTimeFormatName), - ok (false), - movie (0), - trackNum (trackNum_), - lastSampleRead (0), - lastThreadId (0), - extractor (0), - dataHandle (0) - { - JUCE_AUTORELEASEPOOL - { - bufferList.calloc (256, 1); - - #if JUCE_WINDOWS - if (InitializeQTML (0) != noErr) - return; - #endif - - if (EnterMovies() != noErr) - return; - - bool opened = juce_OpenQuickTimeMovieFromStream (input_, movie, dataHandle); - - if (! opened) - return; - - { - const int numTracks = GetMovieTrackCount (movie); - int trackCount = 0; - - for (int i = 1; i <= numTracks; ++i) - { - track = GetMovieIndTrack (movie, i); - media = GetTrackMedia (track); - - OSType mediaType; - GetMediaHandlerDescription (media, &mediaType, 0, 0); - - if (mediaType == SoundMediaType - && trackCount++ == trackNum_) - { - ok = true; - break; - } - } - } - - if (! ok) - return; - - ok = false; - - lengthInSamples = GetMediaDecodeDuration (media); - usesFloatingPointData = false; - - samplesPerFrame = (int) (GetMediaDecodeDuration (media) / GetMediaSampleCount (media)); - - trackUnitsPerFrame = GetMovieTimeScale (movie) * samplesPerFrame - / GetMediaTimeScale (media); - - MovieAudioExtractionBegin (movie, 0, &extractor); - - unsigned long output_layout_size; - OSStatus err = MovieAudioExtractionGetPropertyInfo (extractor, - kQTPropertyClass_MovieAudioExtraction_Audio, - kQTMovieAudioExtractionAudioPropertyID_AudioChannelLayout, - 0, &output_layout_size, 0); - if (err != noErr) - return; - - HeapBlock qt_audio_channel_layout; - qt_audio_channel_layout.calloc (output_layout_size, 1); - - MovieAudioExtractionGetProperty (extractor, - kQTPropertyClass_MovieAudioExtraction_Audio, - kQTMovieAudioExtractionAudioPropertyID_AudioChannelLayout, - output_layout_size, qt_audio_channel_layout, 0); - - qt_audio_channel_layout[0].mChannelLayoutTag = kAudioChannelLayoutTag_Stereo; - - MovieAudioExtractionSetProperty (extractor, - kQTPropertyClass_MovieAudioExtraction_Audio, - kQTMovieAudioExtractionAudioPropertyID_AudioChannelLayout, - output_layout_size, - qt_audio_channel_layout); - - err = MovieAudioExtractionGetProperty (extractor, - kQTPropertyClass_MovieAudioExtraction_Audio, - kQTMovieAudioExtractionAudioPropertyID_AudioStreamBasicDescription, - sizeof (inputStreamDesc), - &inputStreamDesc, 0); - if (err != noErr) - return; - - inputStreamDesc.mFormatFlags = kAudioFormatFlagIsSignedInteger - | kAudioFormatFlagIsPacked - | kAudioFormatFlagsNativeEndian; - inputStreamDesc.mBitsPerChannel = sizeof (SInt16) * 8; - inputStreamDesc.mChannelsPerFrame = jmin ((UInt32) 2, inputStreamDesc.mChannelsPerFrame); - inputStreamDesc.mBytesPerFrame = sizeof (SInt16) * inputStreamDesc.mChannelsPerFrame; - inputStreamDesc.mBytesPerPacket = inputStreamDesc.mBytesPerFrame; - - err = MovieAudioExtractionSetProperty (extractor, - kQTPropertyClass_MovieAudioExtraction_Audio, - kQTMovieAudioExtractionAudioPropertyID_AudioStreamBasicDescription, - sizeof (inputStreamDesc), - &inputStreamDesc); - if (err != noErr) - return; - - Boolean allChannelsDiscrete = false; - err = MovieAudioExtractionSetProperty (extractor, - kQTPropertyClass_MovieAudioExtraction_Movie, - kQTMovieAudioExtractionMoviePropertyID_AllChannelsDiscrete, - sizeof (allChannelsDiscrete), - &allChannelsDiscrete); - - if (err != noErr) - return; - - bufferList->mNumberBuffers = 1; - bufferList->mBuffers[0].mNumberChannels = inputStreamDesc.mChannelsPerFrame; - bufferList->mBuffers[0].mDataByteSize = jmax ((UInt32) 4096, (UInt32) (samplesPerFrame * inputStreamDesc.mBytesPerFrame) + 16); - - dataBuffer.malloc (bufferList->mBuffers[0].mDataByteSize); - bufferList->mBuffers[0].mData = dataBuffer; - - sampleRate = inputStreamDesc.mSampleRate; - bitsPerSample = 16; - numChannels = inputStreamDesc.mChannelsPerFrame; - - detachThread(); - ok = true; - } - } - - ~QTAudioReader() - { - JUCE_AUTORELEASEPOOL - { - checkThreadIsAttached(); - - if (dataHandle != nullptr) - DisposeHandle (dataHandle); - - if (extractor != nullptr) - { - MovieAudioExtractionEnd (extractor); - extractor = nullptr; - } - - DisposeMovie (movie); - - #if JUCE_MAC - ExitMoviesOnThread (); - #endif - } - } - - bool readSamples (int** destSamples, int numDestChannels, int startOffsetInDestBuffer, - int64 startSampleInFile, int numSamples) - { - JUCE_AUTORELEASEPOOL - { - checkThreadIsAttached(); - bool readOk = true; - - while (numSamples > 0) - { - if (lastSampleRead != startSampleInFile) - { - TimeRecord time; - time.scale = (TimeScale) inputStreamDesc.mSampleRate; - time.base = 0; - time.value.hi = 0; - time.value.lo = (UInt32) startSampleInFile; - - OSStatus err = MovieAudioExtractionSetProperty (extractor, - kQTPropertyClass_MovieAudioExtraction_Movie, - kQTMovieAudioExtractionMoviePropertyID_CurrentTime, - sizeof (time), &time); - - if (err != noErr) - { - readOk = false; - break; - } - } - - int framesToDo = jmin (numSamples, (int) (bufferList->mBuffers[0].mDataByteSize / inputStreamDesc.mBytesPerFrame)); - bufferList->mBuffers[0].mDataByteSize = inputStreamDesc.mBytesPerFrame * framesToDo; - - UInt32 outFlags = 0; - UInt32 actualNumFrames = framesToDo; - OSStatus err = MovieAudioExtractionFillBuffer (extractor, &actualNumFrames, bufferList, &outFlags); - if (err != noErr) - { - readOk = false; - break; - } - - lastSampleRead = startSampleInFile + actualNumFrames; - const int samplesReceived = actualNumFrames; - - for (int j = numDestChannels; --j >= 0;) - { - if (destSamples[j] != nullptr) - { - const short* src = ((const short*) bufferList->mBuffers[0].mData) + j; - - for (int i = 0; i < samplesReceived; ++i) - { - destSamples[j][startOffsetInDestBuffer + i] = (*src << 16); - src += numChannels; - } - } - } - - startOffsetInDestBuffer += samplesReceived; - startSampleInFile += samplesReceived; - numSamples -= samplesReceived; - - if (((outFlags & kQTMovieAudioExtractionComplete) != 0 || samplesReceived == 0) && numSamples > 0) - { - for (int j = numDestChannels; --j >= 0;) - if (destSamples[j] != nullptr) - zeromem (destSamples[j] + startOffsetInDestBuffer, sizeof (int) * numSamples); - - break; - } - } - - detachThread(); - return readOk; - } - } - - bool ok; - -private: - Movie movie; - Media media; - Track track; - const int trackNum; - double trackUnitsPerFrame; - int samplesPerFrame; - int64 lastSampleRead; - Thread::ThreadID lastThreadId; - MovieAudioExtractionRef extractor; - AudioStreamBasicDescription inputStreamDesc; - HeapBlock bufferList; - HeapBlock dataBuffer; - Handle dataHandle; - - //============================================================================== - void checkThreadIsAttached() - { - #if JUCE_MAC - if (Thread::getCurrentThreadId() != lastThreadId) - EnterMoviesOnThread (0); - AttachMovieToCurrentThread (movie); - #endif - } - - void detachThread() - { - #if JUCE_MAC - DetachMovieFromCurrentThread (movie); - #endif - } - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (QTAudioReader) -}; - - -//============================================================================== -QuickTimeAudioFormat::QuickTimeAudioFormat() : AudioFormat (quickTimeFormatName, ".mov .mp3 .mp4 .m4a") -{ -} - -QuickTimeAudioFormat::~QuickTimeAudioFormat() -{ -} - -Array QuickTimeAudioFormat::getPossibleSampleRates() { return Array(); } -Array QuickTimeAudioFormat::getPossibleBitDepths() { return Array(); } - -bool QuickTimeAudioFormat::canDoStereo() { return true; } -bool QuickTimeAudioFormat::canDoMono() { return true; } - -//============================================================================== -AudioFormatReader* QuickTimeAudioFormat::createReaderFor (InputStream* sourceStream, - const bool deleteStreamIfOpeningFails) -{ - ScopedPointer r (new QTAudioReader (sourceStream, 0)); - - if (r->ok) - return r.release(); - - if (! deleteStreamIfOpeningFails) - r->input = 0; - - return nullptr; -} - -AudioFormatWriter* QuickTimeAudioFormat::createWriterFor (OutputStream* /*streamToWriteTo*/, - double /*sampleRateToUse*/, - unsigned int /*numberOfChannels*/, - int /*bitsPerSample*/, - const StringPairArray& /*metadataValues*/, - int /*qualityOptionIndex*/) -{ - jassertfalse; // not yet implemented! - return nullptr; -} - -#endif diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/codecs/juce_QuickTimeAudioFormat.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/codecs/juce_QuickTimeAudioFormat.h deleted file mode 100644 index 6ef6a4edb6..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/codecs/juce_QuickTimeAudioFormat.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#if JUCE_QUICKTIME - -//============================================================================== -/** - Uses QuickTime to read the audio track a movie or media file. - - As well as QuickTime movies, this should also manage to open other audio - files that quicktime can understand, like mp3, m4a, etc. - - @see AudioFormat -*/ -class JUCE_API QuickTimeAudioFormat : public AudioFormat -{ -public: - //============================================================================== - /** Creates a format object. */ - QuickTimeAudioFormat(); - - /** Destructor. */ - ~QuickTimeAudioFormat(); - - //============================================================================== - Array getPossibleSampleRates(); - Array getPossibleBitDepths(); - bool canDoStereo(); - bool canDoMono(); - - //============================================================================== - AudioFormatReader* createReaderFor (InputStream* sourceStream, - bool deleteStreamIfOpeningFails); - - AudioFormatWriter* createWriterFor (OutputStream* streamToWriteTo, - double sampleRateToUse, - unsigned int numberOfChannels, - int bitsPerSample, - const StringPairArray& metadataValues, - int qualityOptionIndex); - - -private: - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (QuickTimeAudioFormat) -}; - - -#endif diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/codecs/juce_WavAudioFormat.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/codecs/juce_WavAudioFormat.cpp deleted file mode 100644 index 473e7445bc..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/codecs/juce_WavAudioFormat.cpp +++ /dev/null @@ -1,1471 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -static const char* const wavFormatName = "WAV file"; - -//============================================================================== -const char* const WavAudioFormat::bwavDescription = "bwav description"; -const char* const WavAudioFormat::bwavOriginator = "bwav originator"; -const char* const WavAudioFormat::bwavOriginatorRef = "bwav originator ref"; -const char* const WavAudioFormat::bwavOriginationDate = "bwav origination date"; -const char* const WavAudioFormat::bwavOriginationTime = "bwav origination time"; -const char* const WavAudioFormat::bwavTimeReference = "bwav time reference"; -const char* const WavAudioFormat::bwavCodingHistory = "bwav coding history"; - -StringPairArray WavAudioFormat::createBWAVMetadata (const String& description, - const String& originator, - const String& originatorRef, - const Time date, - const int64 timeReferenceSamples, - const String& codingHistory) -{ - StringPairArray m; - - m.set (bwavDescription, description); - m.set (bwavOriginator, originator); - m.set (bwavOriginatorRef, originatorRef); - m.set (bwavOriginationDate, date.formatted ("%Y-%m-%d")); - m.set (bwavOriginationTime, date.formatted ("%H:%M:%S")); - m.set (bwavTimeReference, String (timeReferenceSamples)); - m.set (bwavCodingHistory, codingHistory); - - return m; -} - -const char* const WavAudioFormat::acidOneShot = "acid one shot"; -const char* const WavAudioFormat::acidRootSet = "acid root set"; -const char* const WavAudioFormat::acidStretch = "acid stretch"; -const char* const WavAudioFormat::acidDiskBased = "acid disk based"; -const char* const WavAudioFormat::acidizerFlag = "acidizer flag"; -const char* const WavAudioFormat::acidRootNote = "acid root note"; -const char* const WavAudioFormat::acidBeats = "acid beats"; -const char* const WavAudioFormat::acidDenominator = "acid denominator"; -const char* const WavAudioFormat::acidNumerator = "acid numerator"; -const char* const WavAudioFormat::acidTempo = "acid tempo"; - -const char* const WavAudioFormat::ISRC = "ISRC"; -const char* const WavAudioFormat::tracktionLoopInfo = "tracktion loop info"; - -//============================================================================== -namespace WavFileHelpers -{ - inline int chunkName (const char* const name) noexcept { return (int) ByteOrder::littleEndianInt (name); } - inline size_t roundUpSize (size_t sz) noexcept { return (sz + 3) & ~3u; } - - #if JUCE_MSVC - #pragma pack (push, 1) - #endif - - struct BWAVChunk - { - char description [256]; - char originator [32]; - char originatorRef [32]; - char originationDate [10]; - char originationTime [8]; - uint32 timeRefLow; - uint32 timeRefHigh; - uint16 version; - uint8 umid[64]; - uint8 reserved[190]; - char codingHistory[1]; - - void copyTo (StringPairArray& values, const int totalSize) const - { - values.set (WavAudioFormat::bwavDescription, String::fromUTF8 (description, sizeof (description))); - values.set (WavAudioFormat::bwavOriginator, String::fromUTF8 (originator, sizeof (originator))); - values.set (WavAudioFormat::bwavOriginatorRef, String::fromUTF8 (originatorRef, sizeof (originatorRef))); - values.set (WavAudioFormat::bwavOriginationDate, String::fromUTF8 (originationDate, sizeof (originationDate))); - values.set (WavAudioFormat::bwavOriginationTime, String::fromUTF8 (originationTime, sizeof (originationTime))); - - const uint32 timeLow = ByteOrder::swapIfBigEndian (timeRefLow); - const uint32 timeHigh = ByteOrder::swapIfBigEndian (timeRefHigh); - const int64 time = (((int64)timeHigh) << 32) + timeLow; - - values.set (WavAudioFormat::bwavTimeReference, String (time)); - values.set (WavAudioFormat::bwavCodingHistory, - String::fromUTF8 (codingHistory, totalSize - (int) offsetof (BWAVChunk, codingHistory))); - } - - static MemoryBlock createFrom (const StringPairArray& values) - { - MemoryBlock data (roundUpSize (sizeof (BWAVChunk) + values [WavAudioFormat::bwavCodingHistory].getNumBytesAsUTF8())); - data.fillWith (0); - - BWAVChunk* b = (BWAVChunk*) data.getData(); - - // Allow these calls to overwrite an extra byte at the end, which is fine as long - // as they get called in the right order.. - values [WavAudioFormat::bwavDescription] .copyToUTF8 (b->description, 257); - values [WavAudioFormat::bwavOriginator] .copyToUTF8 (b->originator, 33); - values [WavAudioFormat::bwavOriginatorRef] .copyToUTF8 (b->originatorRef, 33); - values [WavAudioFormat::bwavOriginationDate].copyToUTF8 (b->originationDate, 11); - values [WavAudioFormat::bwavOriginationTime].copyToUTF8 (b->originationTime, 9); - - const int64 time = values [WavAudioFormat::bwavTimeReference].getLargeIntValue(); - b->timeRefLow = ByteOrder::swapIfBigEndian ((uint32) (time & 0xffffffff)); - b->timeRefHigh = ByteOrder::swapIfBigEndian ((uint32) (time >> 32)); - - values [WavAudioFormat::bwavCodingHistory].copyToUTF8 (b->codingHistory, 0x7fffffff); - - if (b->description[0] != 0 - || b->originator[0] != 0 - || b->originationDate[0] != 0 - || b->originationTime[0] != 0 - || b->codingHistory[0] != 0 - || time != 0) - { - return data; - } - - return MemoryBlock(); - } - - } JUCE_PACKED; - - //============================================================================== - struct SMPLChunk - { - struct SampleLoop - { - uint32 identifier; - uint32 type; // these are different in AIFF and WAV - uint32 start; - uint32 end; - uint32 fraction; - uint32 playCount; - } JUCE_PACKED; - - uint32 manufacturer; - uint32 product; - uint32 samplePeriod; - uint32 midiUnityNote; - uint32 midiPitchFraction; - uint32 smpteFormat; - uint32 smpteOffset; - uint32 numSampleLoops; - uint32 samplerData; - SampleLoop loops[1]; - - template - static void setValue (StringPairArray& values, NameType name, uint32 val) - { - values.set (name, String (ByteOrder::swapIfBigEndian (val))); - } - - static void setValue (StringPairArray& values, int prefix, const char* name, uint32 val) - { - setValue (values, "Loop" + String (prefix) + name, val); - } - - void copyTo (StringPairArray& values, const int totalSize) const - { - setValue (values, "Manufacturer", manufacturer); - setValue (values, "Product", product); - setValue (values, "SamplePeriod", samplePeriod); - setValue (values, "MidiUnityNote", midiUnityNote); - setValue (values, "MidiPitchFraction", midiPitchFraction); - setValue (values, "SmpteFormat", smpteFormat); - setValue (values, "SmpteOffset", smpteOffset); - setValue (values, "NumSampleLoops", numSampleLoops); - setValue (values, "SamplerData", samplerData); - - for (int i = 0; i < (int) numSampleLoops; ++i) - { - if ((uint8*) (loops + (i + 1)) > ((uint8*) this) + totalSize) - break; - - setValue (values, i, "Identifier", loops[i].identifier); - setValue (values, i, "Type", loops[i].type); - setValue (values, i, "Start", loops[i].start); - setValue (values, i, "End", loops[i].end); - setValue (values, i, "Fraction", loops[i].fraction); - setValue (values, i, "PlayCount", loops[i].playCount); - } - } - - template - static uint32 getValue (const StringPairArray& values, NameType name, const char* def) - { - return ByteOrder::swapIfBigEndian ((uint32) values.getValue (name, def).getIntValue()); - } - - static uint32 getValue (const StringPairArray& values, int prefix, const char* name, const char* def) - { - return getValue (values, "Loop" + String (prefix) + name, def); - } - - static MemoryBlock createFrom (const StringPairArray& values) - { - MemoryBlock data; - const int numLoops = jmin (64, values.getValue ("NumSampleLoops", "0").getIntValue()); - - if (numLoops > 0) - { - data.setSize (roundUpSize (sizeof (SMPLChunk) + (size_t) (numLoops - 1) * sizeof (SampleLoop)), true); - - SMPLChunk* const s = static_cast (data.getData()); - - s->manufacturer = getValue (values, "Manufacturer", "0"); - s->product = getValue (values, "Product", "0"); - s->samplePeriod = getValue (values, "SamplePeriod", "0"); - s->midiUnityNote = getValue (values, "MidiUnityNote", "60"); - s->midiPitchFraction = getValue (values, "MidiPitchFraction", "0"); - s->smpteFormat = getValue (values, "SmpteFormat", "0"); - s->smpteOffset = getValue (values, "SmpteOffset", "0"); - s->numSampleLoops = ByteOrder::swapIfBigEndian ((uint32) numLoops); - s->samplerData = getValue (values, "SamplerData", "0"); - - for (int i = 0; i < numLoops; ++i) - { - SampleLoop& loop = s->loops[i]; - loop.identifier = getValue (values, i, "Identifier", "0"); - loop.type = getValue (values, i, "Type", "0"); - loop.start = getValue (values, i, "Start", "0"); - loop.end = getValue (values, i, "End", "0"); - loop.fraction = getValue (values, i, "Fraction", "0"); - loop.playCount = getValue (values, i, "PlayCount", "0"); - } - } - - return data; - } - } JUCE_PACKED; - - //============================================================================== - struct InstChunk - { - int8 baseNote; - int8 detune; - int8 gain; - int8 lowNote; - int8 highNote; - int8 lowVelocity; - int8 highVelocity; - - static void setValue (StringPairArray& values, const char* name, int val) - { - values.set (name, String (val)); - } - - void copyTo (StringPairArray& values) const - { - setValue (values, "MidiUnityNote", baseNote); - setValue (values, "Detune", detune); - setValue (values, "Gain", gain); - setValue (values, "LowNote", lowNote); - setValue (values, "HighNote", highNote); - setValue (values, "LowVelocity", lowVelocity); - setValue (values, "HighVelocity", highVelocity); - } - - static int8 getValue (const StringPairArray& values, const char* name, const char* def) - { - return (int8) values.getValue (name, def).getIntValue(); - } - - static MemoryBlock createFrom (const StringPairArray& values) - { - MemoryBlock data; - const StringArray& keys = values.getAllKeys(); - - if (keys.contains ("LowNote", true) && keys.contains ("HighNote", true)) - { - data.setSize (8, true); - InstChunk* const inst = static_cast (data.getData()); - - inst->baseNote = getValue (values, "MidiUnityNote", "60"); - inst->detune = getValue (values, "Detune", "0"); - inst->gain = getValue (values, "Gain", "0"); - inst->lowNote = getValue (values, "LowNote", "0"); - inst->highNote = getValue (values, "HighNote", "127"); - inst->lowVelocity = getValue (values, "LowVelocity", "1"); - inst->highVelocity = getValue (values, "HighVelocity", "127"); - } - - return data; - } - } JUCE_PACKED; - - //============================================================================== - struct CueChunk - { - struct Cue - { - uint32 identifier; - uint32 order; - uint32 chunkID; - uint32 chunkStart; - uint32 blockStart; - uint32 offset; - } JUCE_PACKED; - - uint32 numCues; - Cue cues[1]; - - static void setValue (StringPairArray& values, int prefix, const char* name, uint32 val) - { - values.set ("Cue" + String (prefix) + name, String (ByteOrder::swapIfBigEndian (val))); - } - - void copyTo (StringPairArray& values, const int totalSize) const - { - values.set ("NumCuePoints", String (ByteOrder::swapIfBigEndian (numCues))); - - for (int i = 0; i < (int) numCues; ++i) - { - if ((uint8*) (cues + (i + 1)) > ((uint8*) this) + totalSize) - break; - - setValue (values, i, "Identifier", cues[i].identifier); - setValue (values, i, "Order", cues[i].order); - setValue (values, i, "ChunkID", cues[i].chunkID); - setValue (values, i, "ChunkStart", cues[i].chunkStart); - setValue (values, i, "BlockStart", cues[i].blockStart); - setValue (values, i, "Offset", cues[i].offset); - } - } - - static MemoryBlock createFrom (const StringPairArray& values) - { - MemoryBlock data; - const int numCues = values.getValue ("NumCuePoints", "0").getIntValue(); - - if (numCues > 0) - { - data.setSize (roundUpSize (sizeof (CueChunk) + (size_t) (numCues - 1) * sizeof (Cue)), true); - - CueChunk* const c = static_cast (data.getData()); - - c->numCues = ByteOrder::swapIfBigEndian ((uint32) numCues); - - const String dataChunkID (chunkName ("data")); - int nextOrder = 0; - - #if JUCE_DEBUG - Array identifiers; - #endif - - for (int i = 0; i < numCues; ++i) - { - const String prefix ("Cue" + String (i)); - const uint32 identifier = (uint32) values.getValue (prefix + "Identifier", "0").getIntValue(); - - #if JUCE_DEBUG - jassert (! identifiers.contains (identifier)); - identifiers.add (identifier); - #endif - - const int order = values.getValue (prefix + "Order", String (nextOrder)).getIntValue(); - nextOrder = jmax (nextOrder, order) + 1; - - Cue& cue = c->cues[i]; - cue.identifier = ByteOrder::swapIfBigEndian ((uint32) identifier); - cue.order = ByteOrder::swapIfBigEndian ((uint32) order); - cue.chunkID = ByteOrder::swapIfBigEndian ((uint32) values.getValue (prefix + "ChunkID", dataChunkID).getIntValue()); - cue.chunkStart = ByteOrder::swapIfBigEndian ((uint32) values.getValue (prefix + "ChunkStart", "0").getIntValue()); - cue.blockStart = ByteOrder::swapIfBigEndian ((uint32) values.getValue (prefix + "BlockStart", "0").getIntValue()); - cue.offset = ByteOrder::swapIfBigEndian ((uint32) values.getValue (prefix + "Offset", "0").getIntValue()); - } - } - - return data; - } - - } JUCE_PACKED; - - //============================================================================== - namespace ListChunk - { - static int getValue (const StringPairArray& values, const String& name) - { - return values.getValue (name, "0").getIntValue(); - } - - static int getValue (const StringPairArray& values, const String& prefix, const char* name) - { - return getValue (values, prefix + name); - } - - static void appendLabelOrNoteChunk (const StringPairArray& values, const String& prefix, - const int chunkType, MemoryOutputStream& out) - { - const String label (values.getValue (prefix + "Text", prefix)); - const int labelLength = (int) label.getNumBytesAsUTF8() + 1; - const int chunkLength = 4 + labelLength + (labelLength & 1); - - out.writeInt (chunkType); - out.writeInt (chunkLength); - out.writeInt (getValue (values, prefix, "Identifier")); - out.write (label.toUTF8(), (size_t) labelLength); - - if ((out.getDataSize() & 1) != 0) - out.writeByte (0); - } - - static void appendExtraChunk (const StringPairArray& values, const String& prefix, MemoryOutputStream& out) - { - const String text (values.getValue (prefix + "Text", prefix)); - - const int textLength = (int) text.getNumBytesAsUTF8() + 1; // include null terminator - int chunkLength = textLength + 20 + (textLength & 1); - - out.writeInt (chunkName ("ltxt")); - out.writeInt (chunkLength); - out.writeInt (getValue (values, prefix, "Identifier")); - out.writeInt (getValue (values, prefix, "SampleLength")); - out.writeInt (getValue (values, prefix, "Purpose")); - out.writeShort ((short) getValue (values, prefix, "Country")); - out.writeShort ((short) getValue (values, prefix, "Language")); - out.writeShort ((short) getValue (values, prefix, "Dialect")); - out.writeShort ((short) getValue (values, prefix, "CodePage")); - out.write (text.toUTF8(), (size_t) textLength); - - if ((out.getDataSize() & 1) != 0) - out.writeByte (0); - } - - static MemoryBlock createFrom (const StringPairArray& values) - { - const int numCueLabels = getValue (values, "NumCueLabels"); - const int numCueNotes = getValue (values, "NumCueNotes"); - const int numCueRegions = getValue (values, "NumCueRegions"); - - MemoryOutputStream out; - - if (numCueLabels + numCueNotes + numCueRegions > 0) - { - out.writeInt (chunkName ("adtl")); - - for (int i = 0; i < numCueLabels; ++i) - appendLabelOrNoteChunk (values, "CueLabel" + String (i), chunkName ("labl"), out); - - for (int i = 0; i < numCueNotes; ++i) - appendLabelOrNoteChunk (values, "CueNote" + String (i), chunkName ("note"), out); - - for (int i = 0; i < numCueRegions; ++i) - appendExtraChunk (values, "CueRegion" + String (i), out); - } - - return out.getMemoryBlock(); - } - } - - //============================================================================== - namespace ListInfoChunk - { - static bool writeValue (const StringPairArray& values, MemoryOutputStream& out, const char* paramName) - { - const String value (values.getValue (paramName, String())); - - if (value.isEmpty()) - return false; - - const int valueLength = (int) value.getNumBytesAsUTF8() + 1; - const int chunkLength = valueLength + (valueLength & 1); - - out.writeInt (chunkName (paramName)); - out.writeInt (chunkLength); - out.write (value.toUTF8(), (size_t) valueLength); - - if ((out.getDataSize() & 1) != 0) - out.writeByte (0); - - return true; - } - - static MemoryBlock createFrom (const StringPairArray& values) - { - static const char* params[] = { "INAM", "IART", "IPRD", "IPRT", "ISFT", - "ISRC", "IGNR", "ICMT", "ICOP", "ICRD" }; - - MemoryOutputStream out; - out.writeInt (chunkName ("INFO")); - bool anyParamsDefined = false; - - for (int i = 0; i < numElementsInArray (params); ++i) - if (writeValue (values, out, params[i])) - anyParamsDefined = true; - - return anyParamsDefined ? out.getMemoryBlock() : MemoryBlock(); - } - } - - //============================================================================== - struct AcidChunk - { - /** Reads an acid RIFF chunk from a stream positioned just after the size byte. */ - AcidChunk (InputStream& input, size_t length) - { - zerostruct (*this); - input.read (this, (int) jmin (sizeof (*this), length)); - } - - AcidChunk (const StringPairArray& values) - { - zerostruct (*this); - - flags = getFlagIfPresent (values, WavAudioFormat::acidOneShot, 0x01) - | getFlagIfPresent (values, WavAudioFormat::acidRootSet, 0x02) - | getFlagIfPresent (values, WavAudioFormat::acidStretch, 0x04) - | getFlagIfPresent (values, WavAudioFormat::acidDiskBased, 0x08) - | getFlagIfPresent (values, WavAudioFormat::acidizerFlag, 0x10); - - if (values[WavAudioFormat::acidRootSet].getIntValue() != 0) - rootNote = ByteOrder::swapIfBigEndian ((uint16) values[WavAudioFormat::acidRootNote].getIntValue()); - - numBeats = ByteOrder::swapIfBigEndian ((uint32) values[WavAudioFormat::acidBeats].getIntValue()); - meterDenominator = ByteOrder::swapIfBigEndian ((uint16) values[WavAudioFormat::acidDenominator].getIntValue()); - meterNumerator = ByteOrder::swapIfBigEndian ((uint16) values[WavAudioFormat::acidNumerator].getIntValue()); - - if (values.containsKey (WavAudioFormat::acidTempo)) - tempo = swapFloatByteOrder (values[WavAudioFormat::acidTempo].getFloatValue()); - } - - static MemoryBlock createFrom (const StringPairArray& values) - { - return AcidChunk (values).toMemoryBlock(); - } - - MemoryBlock toMemoryBlock() const - { - return (flags != 0 || rootNote != 0 || numBeats != 0 || meterDenominator != 0 || meterNumerator != 0) - ? MemoryBlock (this, sizeof (*this)) : MemoryBlock(); - } - - void addToMetadata (StringPairArray& values) const - { - setBoolFlag (values, WavAudioFormat::acidOneShot, 0x01); - setBoolFlag (values, WavAudioFormat::acidRootSet, 0x02); - setBoolFlag (values, WavAudioFormat::acidStretch, 0x04); - setBoolFlag (values, WavAudioFormat::acidDiskBased, 0x08); - setBoolFlag (values, WavAudioFormat::acidizerFlag, 0x10); - - if (flags & 0x02) // root note set - values.set (WavAudioFormat::acidRootNote, String (ByteOrder::swapIfBigEndian (rootNote))); - - values.set (WavAudioFormat::acidBeats, String (ByteOrder::swapIfBigEndian (numBeats))); - values.set (WavAudioFormat::acidDenominator, String (ByteOrder::swapIfBigEndian (meterDenominator))); - values.set (WavAudioFormat::acidNumerator, String (ByteOrder::swapIfBigEndian (meterNumerator))); - values.set (WavAudioFormat::acidTempo, String (swapFloatByteOrder (tempo))); - } - - void setBoolFlag (StringPairArray& values, const char* name, uint32 mask) const - { - values.set (name, (flags & ByteOrder::swapIfBigEndian (mask)) ? "1" : "0"); - } - - static uint32 getFlagIfPresent (const StringPairArray& values, const char* name, uint32 flag) - { - return values[name].getIntValue() != 0 ? ByteOrder::swapIfBigEndian (flag) : 0; - } - - static float swapFloatByteOrder (const float x) noexcept - { - #ifdef JUCE_BIG_ENDIAN - union { uint32 asInt; float asFloat; } n; - n.asFloat = x; - n.asInt = ByteOrder::swap (n.asInt); - return n.asFloat; - #else - return x; - #endif - } - - uint32 flags; - uint16 rootNote; - uint16 reserved1; - float reserved2; - uint32 numBeats; - uint16 meterDenominator; - uint16 meterNumerator; - float tempo; - - } JUCE_PACKED; - - //============================================================================== - struct TracktionChunk - { - static MemoryBlock createFrom (const StringPairArray& values) - { - const String s = values[WavAudioFormat::tracktionLoopInfo]; - MemoryBlock data; - - if (s.isNotEmpty()) - { - MemoryOutputStream os (data, false); - os.writeString (s); - } - - return data; - } - }; - - //============================================================================== - namespace AXMLChunk - { - static void addToMetadata (StringPairArray& destValues, const String& source) - { - ScopedPointer xml (XmlDocument::parse (source)); - - if (xml != nullptr && xml->hasTagName ("ebucore:ebuCoreMain")) - { - if (XmlElement* xml2 = xml->getChildByName ("ebucore:coreMetadata")) - { - if (XmlElement* xml3 = xml2->getChildByName ("ebucore:identifier")) - { - if (XmlElement* xml4 = xml3->getChildByName ("dc:identifier")) - { - const String ISRCCode (xml4->getAllSubText().fromFirstOccurrenceOf ("ISRC:", false, true)); - - if (ISRCCode.isNotEmpty()) - destValues.set (WavAudioFormat::ISRC, ISRCCode); - } - } - } - } - } - - static MemoryBlock createFrom (const StringPairArray& values) - { - const String ISRC (values.getValue (WavAudioFormat::ISRC, String::empty)); - MemoryOutputStream xml; - - if (ISRC.isNotEmpty()) - { - xml << "" - "" - "" - "ISRC:" << ISRC << "" - "" - "" - ""; - - xml.writeRepeatedByte (0, xml.getDataSize()); // ensures even size, null termination and room for future growing - } - - return xml.getMemoryBlock(); - } - }; - - //============================================================================== - struct ExtensibleWavSubFormat - { - uint32 data1; - uint16 data2; - uint16 data3; - uint8 data4[8]; - - bool operator== (const ExtensibleWavSubFormat& other) const noexcept { return memcmp (this, &other, sizeof (*this)) == 0; } - bool operator!= (const ExtensibleWavSubFormat& other) const noexcept { return ! operator== (other); } - - } JUCE_PACKED; - - static const ExtensibleWavSubFormat pcmFormat = { 0x00000001, 0x0000, 0x0010, { 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 } }; - static const ExtensibleWavSubFormat IEEEFloatFormat = { 0x00000003, 0x0000, 0x0010, { 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 } }; - static const ExtensibleWavSubFormat ambisonicFormat = { 0x00000001, 0x0721, 0x11d3, { 0x86, 0x44, 0xC8, 0xC1, 0xCA, 0x00, 0x00, 0x00 } }; - - struct DataSize64Chunk // chunk ID = 'ds64' if data size > 0xffffffff, 'JUNK' otherwise - { - uint32 riffSizeLow; // low 4 byte size of RF64 block - uint32 riffSizeHigh; // high 4 byte size of RF64 block - uint32 dataSizeLow; // low 4 byte size of data chunk - uint32 dataSizeHigh; // high 4 byte size of data chunk - uint32 sampleCountLow; // low 4 byte sample count of fact chunk - uint32 sampleCountHigh; // high 4 byte sample count of fact chunk - uint32 tableLength; // number of valid entries in array 'table' - } JUCE_PACKED; - - #if JUCE_MSVC - #pragma pack (pop) - #endif -} - -//============================================================================== -class WavAudioFormatReader : public AudioFormatReader -{ -public: - WavAudioFormatReader (InputStream* const in) - : AudioFormatReader (in, wavFormatName), - bwavChunkStart (0), - bwavSize (0), - dataLength (0), - isRF64 (false) - { - using namespace WavFileHelpers; - uint64 len = 0; - uint64 end = 0; - int cueNoteIndex = 0; - int cueLabelIndex = 0; - int cueRegionIndex = 0; - - const int firstChunkType = input->readInt(); - - if (firstChunkType == chunkName ("RF64")) - { - input->skipNextBytes (4); // size is -1 for RF64 - isRF64 = true; - } - else if (firstChunkType == chunkName ("RIFF")) - { - len = (uint64) (uint32) input->readInt(); - end = len + (uint64) input->getPosition(); - } - else - { - return; - } - - const int64 startOfRIFFChunk = input->getPosition(); - - if (input->readInt() == chunkName ("WAVE")) - { - if (isRF64 && input->readInt() == chunkName ("ds64")) - { - const uint32 length = (uint32) input->readInt(); - - if (length < 28) - return; - - const int64 chunkEnd = input->getPosition() + length + (length & 1); - len = (uint64) input->readInt64(); - end = len + (uint64) startOfRIFFChunk; - dataLength = input->readInt64(); - input->setPosition (chunkEnd); - } - - while ((uint64) input->getPosition() < end && ! input->isExhausted()) - { - const int chunkType = input->readInt(); - uint32 length = (uint32) input->readInt(); - const int64 chunkEnd = input->getPosition() + length + (length & 1); - - if (chunkType == chunkName ("fmt ")) - { - // read the format chunk - const unsigned short format = (unsigned short) input->readShort(); - numChannels = (unsigned int) input->readShort(); - sampleRate = input->readInt(); - const int bytesPerSec = input->readInt(); - input->skipNextBytes (2); - bitsPerSample = (unsigned int) (int) input->readShort(); - - if (bitsPerSample > 64) - { - bytesPerFrame = bytesPerSec / (int) sampleRate; - bitsPerSample = 8 * (unsigned int) bytesPerFrame / numChannels; - } - else - { - bytesPerFrame = numChannels * bitsPerSample / 8; - } - - if (format == 3) - { - usesFloatingPointData = true; - } - else if (format == 0xfffe /*WAVE_FORMAT_EXTENSIBLE*/) - { - if (length < 40) // too short - { - bytesPerFrame = 0; - } - else - { - input->skipNextBytes (4); // skip over size and bitsPerSample - metadataValues.set ("ChannelMask", String (input->readInt())); - - ExtensibleWavSubFormat subFormat; - subFormat.data1 = (uint32) input->readInt(); - subFormat.data2 = (uint16) input->readShort(); - subFormat.data3 = (uint16) input->readShort(); - input->read (subFormat.data4, sizeof (subFormat.data4)); - - if (subFormat == IEEEFloatFormat) - usesFloatingPointData = true; - else if (subFormat != pcmFormat && subFormat != ambisonicFormat) - bytesPerFrame = 0; - } - } - else if (format != 1) - { - bytesPerFrame = 0; - } - } - else if (chunkType == chunkName ("data")) - { - if (! isRF64) // data size is expected to be -1, actual data size is in ds64 chunk - dataLength = length; - - dataChunkStart = input->getPosition(); - lengthInSamples = (bytesPerFrame > 0) ? (dataLength / bytesPerFrame) : 0; - } - else if (chunkType == chunkName ("bext")) - { - bwavChunkStart = input->getPosition(); - bwavSize = length; - - HeapBlock bwav; - bwav.calloc (jmax ((size_t) length + 1, sizeof (BWAVChunk)), 1); - input->read (bwav, (int) length); - bwav->copyTo (metadataValues, (int) length); - } - else if (chunkType == chunkName ("smpl")) - { - HeapBlock smpl; - smpl.calloc (jmax ((size_t) length + 1, sizeof (SMPLChunk)), 1); - input->read (smpl, (int) length); - smpl->copyTo (metadataValues, (int) length); - } - else if (chunkType == chunkName ("inst") || chunkType == chunkName ("INST")) // need to check which... - { - HeapBlock inst; - inst.calloc (jmax ((size_t) length + 1, sizeof (InstChunk)), 1); - input->read (inst, (int) length); - inst->copyTo (metadataValues); - } - else if (chunkType == chunkName ("cue ")) - { - HeapBlock cue; - cue.calloc (jmax ((size_t) length + 1, sizeof (CueChunk)), 1); - input->read (cue, (int) length); - cue->copyTo (metadataValues, (int) length); - } - else if (chunkType == chunkName ("axml")) - { - MemoryBlock axml; - input->readIntoMemoryBlock (axml, (ssize_t) length); - AXMLChunk::addToMetadata (metadataValues, axml.toString()); - } - else if (chunkType == chunkName ("LIST")) - { - if (input->readInt() == chunkName ("adtl")) - { - while (input->getPosition() < chunkEnd) - { - const int adtlChunkType = input->readInt(); - const uint32 adtlLength = (uint32) input->readInt(); - const int64 adtlChunkEnd = input->getPosition() + (adtlLength + (adtlLength & 1)); - - if (adtlChunkType == chunkName ("labl") || adtlChunkType == chunkName ("note")) - { - String prefix; - - if (adtlChunkType == chunkName ("labl")) - prefix << "CueLabel" << cueLabelIndex++; - else if (adtlChunkType == chunkName ("note")) - prefix << "CueNote" << cueNoteIndex++; - - const uint32 identifier = (uint32) input->readInt(); - const int stringLength = (int) adtlLength - 4; - - MemoryBlock textBlock; - input->readIntoMemoryBlock (textBlock, stringLength); - - metadataValues.set (prefix + "Identifier", String (identifier)); - metadataValues.set (prefix + "Text", textBlock.toString()); - } - else if (adtlChunkType == chunkName ("ltxt")) - { - const String prefix ("CueRegion" + String (cueRegionIndex++)); - const uint32 identifier = (uint32) input->readInt(); - const uint32 sampleLength = (uint32) input->readInt(); - const uint32 purpose = (uint32) input->readInt(); - const uint16 country = (uint16) input->readInt(); - const uint16 language = (uint16) input->readInt(); - const uint16 dialect = (uint16) input->readInt(); - const uint16 codePage = (uint16) input->readInt(); - const uint32 stringLength = adtlLength - 20; - - MemoryBlock textBlock; - input->readIntoMemoryBlock (textBlock, (int) stringLength); - - metadataValues.set (prefix + "Identifier", String (identifier)); - metadataValues.set (prefix + "SampleLength", String (sampleLength)); - metadataValues.set (prefix + "Purpose", String (purpose)); - metadataValues.set (prefix + "Country", String (country)); - metadataValues.set (prefix + "Language", String (language)); - metadataValues.set (prefix + "Dialect", String (dialect)); - metadataValues.set (prefix + "CodePage", String (codePage)); - metadataValues.set (prefix + "Text", textBlock.toString()); - } - - input->setPosition (adtlChunkEnd); - } - } - } - else if (chunkType == chunkName ("acid")) - { - AcidChunk (*input, length).addToMetadata (metadataValues); - } - else if (chunkType == chunkName ("Trkn")) - { - MemoryBlock tracktion; - input->readIntoMemoryBlock (tracktion, (ssize_t) length); - metadataValues.set (WavAudioFormat::tracktionLoopInfo, tracktion.toString()); - } - else if (chunkEnd <= input->getPosition()) - { - break; - } - - input->setPosition (chunkEnd); - } - } - - if (cueLabelIndex > 0) metadataValues.set ("NumCueLabels", String (cueLabelIndex)); - if (cueNoteIndex > 0) metadataValues.set ("NumCueNotes", String (cueNoteIndex)); - if (cueRegionIndex > 0) metadataValues.set ("NumCueRegions", String (cueRegionIndex)); - if (metadataValues.size() > 0) metadataValues.set ("MetaDataSource", "WAV"); - } - - //============================================================================== - bool readSamples (int** destSamples, int numDestChannels, int startOffsetInDestBuffer, - int64 startSampleInFile, int numSamples) override - { - clearSamplesBeyondAvailableLength (destSamples, numDestChannels, startOffsetInDestBuffer, - startSampleInFile, numSamples, lengthInSamples); - - if (numSamples <= 0) - return true; - - input->setPosition (dataChunkStart + startSampleInFile * bytesPerFrame); - - while (numSamples > 0) - { - const int tempBufSize = 480 * 3 * 4; // (keep this a multiple of 3) - char tempBuffer [tempBufSize]; - - const int numThisTime = jmin (tempBufSize / bytesPerFrame, numSamples); - const int bytesRead = input->read (tempBuffer, numThisTime * bytesPerFrame); - - if (bytesRead < numThisTime * bytesPerFrame) - { - jassert (bytesRead >= 0); - zeromem (tempBuffer + bytesRead, (size_t) (numThisTime * bytesPerFrame - bytesRead)); - } - - copySampleData (bitsPerSample, usesFloatingPointData, - destSamples, startOffsetInDestBuffer, numDestChannels, - tempBuffer, (int) numChannels, numThisTime); - - startOffsetInDestBuffer += numThisTime; - numSamples -= numThisTime; - } - - return true; - } - - static void copySampleData (unsigned int bitsPerSample, const bool usesFloatingPointData, - int* const* destSamples, int startOffsetInDestBuffer, int numDestChannels, - const void* sourceData, int numChannels, int numSamples) noexcept - { - switch (bitsPerSample) - { - case 8: ReadHelper::read (destSamples, startOffsetInDestBuffer, numDestChannels, sourceData, numChannels, numSamples); break; - case 16: ReadHelper::read (destSamples, startOffsetInDestBuffer, numDestChannels, sourceData, numChannels, numSamples); break; - case 24: ReadHelper::read (destSamples, startOffsetInDestBuffer, numDestChannels, sourceData, numChannels, numSamples); break; - case 32: if (usesFloatingPointData) ReadHelper::read (destSamples, startOffsetInDestBuffer, numDestChannels, sourceData, numChannels, numSamples); - else ReadHelper::read (destSamples, startOffsetInDestBuffer, numDestChannels, sourceData, numChannels, numSamples); break; - default: jassertfalse; break; - } - } - - int64 bwavChunkStart, bwavSize; - int64 dataChunkStart, dataLength; - int bytesPerFrame; - bool isRF64; - -private: - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (WavAudioFormatReader) -}; - -//============================================================================== -class WavAudioFormatWriter : public AudioFormatWriter -{ -public: - WavAudioFormatWriter (OutputStream* const out, const double rate, - const unsigned int numChans, const unsigned int bits, - const StringPairArray& metadataValues) - : AudioFormatWriter (out, wavFormatName, rate, numChans, bits), - lengthInSamples (0), - bytesWritten (0), - writeFailed (false) - { - using namespace WavFileHelpers; - - if (metadataValues.size() > 0) - { - // The meta data should have been santised for the WAV format. - // If it was originally sourced from an AIFF file the MetaDataSource - // key should be removed (or set to "WAV") once this has been done - jassert (metadataValues.getValue ("MetaDataSource", "None") != "AIFF"); - - bwavChunk = BWAVChunk::createFrom (metadataValues); - axmlChunk = AXMLChunk::createFrom (metadataValues); - smplChunk = SMPLChunk::createFrom (metadataValues); - instChunk = InstChunk::createFrom (metadataValues); - cueChunk = CueChunk ::createFrom (metadataValues); - listChunk = ListChunk::createFrom (metadataValues); - listInfoChunk = ListInfoChunk::createFrom (metadataValues); - acidChunk = AcidChunk::createFrom (metadataValues); - trckChunk = TracktionChunk::createFrom (metadataValues); - } - - headerPosition = out->getPosition(); - writeHeader(); - } - - ~WavAudioFormatWriter() - { - writeHeader(); - } - - //============================================================================== - bool write (const int** data, int numSamples) override - { - jassert (numSamples >= 0); - jassert (data != nullptr && *data != nullptr); // the input must contain at least one channel! - - if (writeFailed) - return false; - - const size_t bytes = numChannels * (unsigned int) numSamples * bitsPerSample / 8; - tempBlock.ensureSize (bytes, false); - - switch (bitsPerSample) - { - case 8: WriteHelper::write (tempBlock.getData(), (int) numChannels, data, numSamples); break; - case 16: WriteHelper::write (tempBlock.getData(), (int) numChannels, data, numSamples); break; - case 24: WriteHelper::write (tempBlock.getData(), (int) numChannels, data, numSamples); break; - case 32: WriteHelper::write (tempBlock.getData(), (int) numChannels, data, numSamples); break; - default: jassertfalse; break; - } - - if (! output->write (tempBlock.getData(), bytes)) - { - // failed to write to disk, so let's try writing the header. - // If it's just run out of disk space, then if it does manage - // to write the header, we'll still have a useable file.. - writeHeader(); - writeFailed = true; - return false; - } - - bytesWritten += bytes; - lengthInSamples += (uint64) numSamples; - return true; - } - - bool flush() override - { - const int64 lastWritePos = output->getPosition(); - writeHeader(); - - if (output->setPosition (lastWritePos)) - return true; - - // if this fails, you've given it an output stream that can't seek! It needs - // to be able to seek back to write the header - jassertfalse; - return false; - } - -private: - MemoryBlock tempBlock, bwavChunk, axmlChunk, smplChunk, instChunk, cueChunk, listChunk, listInfoChunk, acidChunk, trckChunk; - uint64 lengthInSamples, bytesWritten; - int64 headerPosition; - bool writeFailed; - - static int getChannelMask (const int numChannels) noexcept - { - switch (numChannels) - { - case 1: return 0; - case 2: return 1 + 2; // SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT - case 3: return 1 + 2 + 4; // SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER - case 4: return 1 + 2 + 16 + 32; // SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT - case 5: return 1 + 2 + 4 + 16 + 32; // SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT - case 6: return 1 + 2 + 4 + 8 + 16 + 32; // SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT - case 7: return 1 + 2 + 4 + 16 + 32 + 512 + 1024; // SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT | SPEAKER_SIDE_LEFT | SPEAKER_SIDE_RIGHT - case 8: return 1 + 2 + 4 + 8 + 16 + 32 + 512 + 1024; // SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT | SPEAKER_SIDE_LEFT | SPEAKER_SIDE_RIGHT - default: break; - } - - return 0; - } - - void writeHeader() - { - if ((bytesWritten & 1) != 0) // pad to an even length - output->writeByte (0); - - using namespace WavFileHelpers; - - if (headerPosition != output->getPosition() && ! output->setPosition (headerPosition)) - { - // if this fails, you've given it an output stream that can't seek! It needs to be - // able to seek back to go back and write the header after the data has been written. - jassertfalse; - return; - } - - const size_t bytesPerFrame = numChannels * bitsPerSample / 8; - uint64 audioDataSize = bytesPerFrame * lengthInSamples; - - const bool isRF64 = (bytesWritten >= 0x100000000LL); - const bool isWaveFmtEx = isRF64 || (numChannels > 2); - - int64 riffChunkSize = (int64) (4 /* 'RIFF' */ + 8 + 40 /* WAVEFORMATEX */ - + 8 + audioDataSize + (audioDataSize & 1) - + chunkSize (bwavChunk) - + chunkSize (axmlChunk) - + chunkSize (smplChunk) - + chunkSize (instChunk) - + chunkSize (cueChunk) - + chunkSize (listChunk) - + chunkSize (listInfoChunk) - + chunkSize (acidChunk) - + chunkSize (trckChunk) - + (8 + 28)); // (ds64 chunk) - - riffChunkSize += (riffChunkSize & 1); - - if (isRF64) - writeChunkHeader (chunkName ("RF64"), -1); - else - writeChunkHeader (chunkName ("RIFF"), (int) riffChunkSize); - - output->writeInt (chunkName ("WAVE")); - - if (! isRF64) - { - #if ! JUCE_WAV_DO_NOT_PAD_HEADER_SIZE - /* NB: This junk chunk is added for padding, so that the header is a fixed size - regardless of whether it's RF64 or not. That way, we can begin recording a file, - and when it's finished, can go back and write either a RIFF or RF64 header, - depending on whether more than 2^32 samples were written. - - The JUCE_WAV_DO_NOT_PAD_HEADER_SIZE macro allows you to disable this feature in case - you need to create files for crappy WAV players with bugs that stop them skipping chunks - which they don't recognise. But DO NOT USE THIS option unless you really have no choice, - because it means that if you write more than 2^32 samples to the file, you'll corrupt it. - */ - writeChunkHeader (chunkName ("JUNK"), 28 + (isWaveFmtEx? 0 : 24)); - output->writeRepeatedByte (0, 28 /* ds64 */ + (isWaveFmtEx? 0 : 24)); - #endif - } - else - { - #if JUCE_WAV_DO_NOT_PAD_HEADER_SIZE - // If you disable padding, then you MUST NOT write more than 2^32 samples to a file. - jassertfalse; - #endif - - writeChunkHeader (chunkName ("ds64"), 28); // chunk size for uncompressed data (no table) - output->writeInt64 (riffChunkSize); - output->writeInt64 ((int64) audioDataSize); - output->writeRepeatedByte (0, 12); - } - - if (isWaveFmtEx) - { - writeChunkHeader (chunkName ("fmt "), 40); - output->writeShort ((short) (uint16) 0xfffe); // WAVE_FORMAT_EXTENSIBLE - } - else - { - writeChunkHeader (chunkName ("fmt "), 16); - output->writeShort (bitsPerSample < 32 ? (short) 1 /*WAVE_FORMAT_PCM*/ - : (short) 3 /*WAVE_FORMAT_IEEE_FLOAT*/); - } - - output->writeShort ((short) numChannels); - output->writeInt ((int) sampleRate); - output->writeInt ((int) (bytesPerFrame * sampleRate)); // nAvgBytesPerSec - output->writeShort ((short) bytesPerFrame); // nBlockAlign - output->writeShort ((short) bitsPerSample); // wBitsPerSample - - if (isWaveFmtEx) - { - output->writeShort (22); // cbSize (size of the extension) - output->writeShort ((short) bitsPerSample); // wValidBitsPerSample - output->writeInt (getChannelMask ((int) numChannels)); - - const ExtensibleWavSubFormat& subFormat = bitsPerSample < 32 ? pcmFormat : IEEEFloatFormat; - - output->writeInt ((int) subFormat.data1); - output->writeShort ((short) subFormat.data2); - output->writeShort ((short) subFormat.data3); - output->write (subFormat.data4, sizeof (subFormat.data4)); - } - - writeChunk (bwavChunk, chunkName ("bext")); - writeChunk (axmlChunk, chunkName ("axml")); - writeChunk (smplChunk, chunkName ("smpl")); - writeChunk (instChunk, chunkName ("inst"), 7); - writeChunk (cueChunk, chunkName ("cue ")); - writeChunk (listChunk, chunkName ("LIST")); - writeChunk (listInfoChunk, chunkName ("LIST")); - writeChunk (acidChunk, chunkName ("acid")); - writeChunk (trckChunk, chunkName ("Trkn")); - - writeChunkHeader (chunkName ("data"), isRF64 ? -1 : (int) (lengthInSamples * bytesPerFrame)); - - usesFloatingPointData = (bitsPerSample == 32); - } - - static size_t chunkSize (const MemoryBlock& data) noexcept { return data.getSize() > 0 ? (8 + data.getSize()) : 0; } - - void writeChunkHeader (int chunkType, int size) const - { - output->writeInt (chunkType); - output->writeInt (size); - } - - void writeChunk (const MemoryBlock& data, int chunkType, int size = 0) const - { - if (data.getSize() > 0) - { - writeChunkHeader (chunkType, size != 0 ? size : (int) data.getSize()); - *output << data; - } - } - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (WavAudioFormatWriter) -}; - -//============================================================================== -class MemoryMappedWavReader : public MemoryMappedAudioFormatReader -{ -public: - MemoryMappedWavReader (const File& file, const WavAudioFormatReader& reader) - : MemoryMappedAudioFormatReader (file, reader, reader.dataChunkStart, - reader.dataLength, reader.bytesPerFrame) - { - } - - bool readSamples (int** destSamples, int numDestChannels, int startOffsetInDestBuffer, - int64 startSampleInFile, int numSamples) override - { - clearSamplesBeyondAvailableLength (destSamples, numDestChannels, startOffsetInDestBuffer, - startSampleInFile, numSamples, lengthInSamples); - - if (map == nullptr || ! mappedSection.contains (Range (startSampleInFile, startSampleInFile + numSamples))) - { - jassertfalse; // you must make sure that the window contains all the samples you're going to attempt to read. - return false; - } - - WavAudioFormatReader::copySampleData (bitsPerSample, usesFloatingPointData, - destSamples, startOffsetInDestBuffer, numDestChannels, - sampleToPointer (startSampleInFile), (int) numChannels, numSamples); - return true; - } - - void readMaxLevels (int64 startSampleInFile, int64 numSamples, - float& min0, float& max0, float& min1, float& max1) override - { - if (numSamples <= 0) - { - min0 = max0 = min1 = max1 = 0; - return; - } - - if (map == nullptr || ! mappedSection.contains (Range (startSampleInFile, startSampleInFile + numSamples))) - { - jassertfalse; // you must make sure that the window contains all the samples you're going to attempt to read. - - min0 = max0 = min1 = max1 = 0; - return; - } - - switch (bitsPerSample) - { - case 8: scanMinAndMax (startSampleInFile, numSamples, min0, max0, min1, max1); break; - case 16: scanMinAndMax (startSampleInFile, numSamples, min0, max0, min1, max1); break; - case 24: scanMinAndMax (startSampleInFile, numSamples, min0, max0, min1, max1); break; - case 32: if (usesFloatingPointData) scanMinAndMax (startSampleInFile, numSamples, min0, max0, min1, max1); - else scanMinAndMax (startSampleInFile, numSamples, min0, max0, min1, max1); break; - default: jassertfalse; break; - } - } - -private: - template - void scanMinAndMax (int64 startSampleInFile, int64 numSamples, - float& min0, float& max0, float& min1, float& max1) const noexcept - { - scanMinAndMaxInterleaved (0, startSampleInFile, numSamples, min0, max0); - - if (numChannels > 1) - scanMinAndMaxInterleaved (1, startSampleInFile, numSamples, min1, max1); - else - min1 = max1 = 0; - } - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MemoryMappedWavReader) -}; - -//============================================================================== -WavAudioFormat::WavAudioFormat() : AudioFormat (wavFormatName, ".wav .bwf") {} -WavAudioFormat::~WavAudioFormat() {} - -Array WavAudioFormat::getPossibleSampleRates() -{ - const int rates[] = { 8000, 11025, 12000, 16000, 22050, 32000, 44100, - 48000, 88200, 96000, 176400, 192000, 352800, 384000 }; - - return Array (rates, numElementsInArray (rates)); -} - -Array WavAudioFormat::getPossibleBitDepths() -{ - const int depths[] = { 8, 16, 24, 32 }; - - return Array (depths, numElementsInArray (depths)); -} - -bool WavAudioFormat::canDoStereo() { return true; } -bool WavAudioFormat::canDoMono() { return true; } - -AudioFormatReader* WavAudioFormat::createReaderFor (InputStream* sourceStream, - const bool deleteStreamIfOpeningFails) -{ - ScopedPointer r (new WavAudioFormatReader (sourceStream)); - - if (r->sampleRate > 0 && r->numChannels > 0 && r->bytesPerFrame > 0) - return r.release(); - - if (! deleteStreamIfOpeningFails) - r->input = nullptr; - - return nullptr; -} - -MemoryMappedAudioFormatReader* WavAudioFormat::createMemoryMappedReader (const File& file) -{ - if (FileInputStream* fin = file.createInputStream()) - { - WavAudioFormatReader reader (fin); - - if (reader.lengthInSamples > 0) - return new MemoryMappedWavReader (file, reader); - } - - return nullptr; -} - -AudioFormatWriter* WavAudioFormat::createWriterFor (OutputStream* out, double sampleRate, - unsigned int numChannels, int bitsPerSample, - const StringPairArray& metadataValues, int /*qualityOptionIndex*/) -{ - if (getPossibleBitDepths().contains (bitsPerSample)) - return new WavAudioFormatWriter (out, sampleRate, (unsigned int) numChannels, - (unsigned int) bitsPerSample, metadataValues); - - return nullptr; -} - -namespace WavFileHelpers -{ - static bool slowCopyWavFileWithNewMetadata (const File& file, const StringPairArray& metadata) - { - TemporaryFile tempFile (file); - - WavAudioFormat wav; - ScopedPointer reader (wav.createReaderFor (file.createInputStream(), true)); - - if (reader != nullptr) - { - ScopedPointer outStream (tempFile.getFile().createOutputStream()); - - if (outStream != nullptr) - { - ScopedPointer writer (wav.createWriterFor (outStream, reader->sampleRate, - reader->numChannels, (int) reader->bitsPerSample, - metadata, 0)); - - if (writer != nullptr) - { - outStream.release(); - - bool ok = writer->writeFromAudioReader (*reader, 0, -1); - writer = nullptr; - reader = nullptr; - - return ok && tempFile.overwriteTargetFileWithTemporary(); - } - } - } - - return false; - } -} - -bool WavAudioFormat::replaceMetadataInFile (const File& wavFile, const StringPairArray& newMetadata) -{ - using namespace WavFileHelpers; - ScopedPointer reader (static_cast (createReaderFor (wavFile.createInputStream(), true))); - - if (reader != nullptr) - { - const int64 bwavPos = reader->bwavChunkStart; - const int64 bwavSize = reader->bwavSize; - reader = nullptr; - - if (bwavSize > 0) - { - MemoryBlock chunk (BWAVChunk::createFrom (newMetadata)); - - if (chunk.getSize() <= (size_t) bwavSize) - { - // the new one will fit in the space available, so write it directly.. - const int64 oldSize = wavFile.getSize(); - - { - FileOutputStream out (wavFile); - - if (! out.failedToOpen()) - { - out.setPosition (bwavPos); - out << chunk; - out.setPosition (oldSize); - } - } - - jassert (wavFile.getSize() == oldSize); - - return true; - } - } - } - - return slowCopyWavFileWithNewMetadata (wavFile, newMetadata); -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/codecs/juce_WavAudioFormat.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/codecs/juce_WavAudioFormat.h deleted file mode 100644 index 62de05a897..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/codecs/juce_WavAudioFormat.h +++ /dev/null @@ -1,171 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -//============================================================================== -/** - Reads and Writes WAV format audio files. - - @see AudioFormat -*/ -class JUCE_API WavAudioFormat : public AudioFormat -{ -public: - //============================================================================== - /** Creates a format object. */ - WavAudioFormat(); - - /** Destructor. */ - ~WavAudioFormat(); - - //============================================================================== - /** Metadata property name used by wav readers and writers for adding - a BWAV chunk to the file. - - @see AudioFormatReader::metadataValues, createWriterFor - */ - static const char* const bwavDescription; - - /** Metadata property name used by wav readers and writers for adding - a BWAV chunk to the file. - - @see AudioFormatReader::metadataValues, createWriterFor - */ - static const char* const bwavOriginator; - - /** Metadata property name used by wav readers and writers for adding - a BWAV chunk to the file. - - @see AudioFormatReader::metadataValues, createWriterFor - */ - static const char* const bwavOriginatorRef; - - /** Metadata property name used by wav readers and writers for adding - a BWAV chunk to the file. - - Date format is: yyyy-mm-dd - - @see AudioFormatReader::metadataValues, createWriterFor - */ - static const char* const bwavOriginationDate; - - /** Metadata property name used by wav readers and writers for adding - a BWAV chunk to the file. - - Time format is: hh-mm-ss - - @see AudioFormatReader::metadataValues, createWriterFor - */ - static const char* const bwavOriginationTime; - - /** Metadata property name used by wav readers and writers for adding - a BWAV chunk to the file. - - This is the number of samples from the start of an edit that the - file is supposed to begin at. Seems like an obvious mistake to - only allow a file to occur in an edit once, but that's the way - it is.. - - @see AudioFormatReader::metadataValues, createWriterFor - */ - static const char* const bwavTimeReference; - - /** Metadata property name used by wav readers and writers for adding - a BWAV chunk to the file. - - @see AudioFormatReader::metadataValues, createWriterFor - */ - static const char* const bwavCodingHistory; - - /** Utility function to fill out the appropriate metadata for a BWAV file. - - This just makes it easier than using the property names directly, and it - fills out the time and date in the right format. - */ - static StringPairArray createBWAVMetadata (const String& description, - const String& originator, - const String& originatorRef, - const Time dateAndTime, - const int64 timeReferenceSamples, - const String& codingHistory); - - //============================================================================== - /** Metadata property name used when reading a WAV file with an acid chunk. */ - static const char* const acidOneShot; - /** Metadata property name used when reading a WAV file with an acid chunk. */ - static const char* const acidRootSet; - /** Metadata property name used when reading a WAV file with an acid chunk. */ - static const char* const acidStretch; - /** Metadata property name used when reading a WAV file with an acid chunk. */ - static const char* const acidDiskBased; - /** Metadata property name used when reading a WAV file with an acid chunk. */ - static const char* const acidizerFlag; - /** Metadata property name used when reading a WAV file with an acid chunk. */ - static const char* const acidRootNote; - /** Metadata property name used when reading a WAV file with an acid chunk. */ - static const char* const acidBeats; - /** Metadata property name used when reading a WAV file with an acid chunk. */ - static const char* const acidDenominator; - /** Metadata property name used when reading a WAV file with an acid chunk. */ - static const char* const acidNumerator; - /** Metadata property name used when reading a WAV file with an acid chunk. */ - static const char* const acidTempo; - - //============================================================================== - /** Metadata property name used when reading an ISRC code from an AXML chunk. */ - static const char* const ISRC; - - /** Metadata property name used when reading a WAV file with a Tracktion chunk. */ - static const char* const tracktionLoopInfo; - - //============================================================================== - Array getPossibleSampleRates() override; - Array getPossibleBitDepths() override; - bool canDoStereo() override; - bool canDoMono() override; - - //============================================================================== - AudioFormatReader* createReaderFor (InputStream* sourceStream, - bool deleteStreamIfOpeningFails) override; - - MemoryMappedAudioFormatReader* createMemoryMappedReader (const File& file) override; - - AudioFormatWriter* createWriterFor (OutputStream* streamToWriteTo, - double sampleRateToUse, - unsigned int numberOfChannels, - int bitsPerSample, - const StringPairArray& metadataValues, - int qualityOptionIndex) override; - - //============================================================================== - /** Utility function to replace the metadata in a wav file with a new set of values. - - If possible, this cheats by overwriting just the metadata region of the file, rather - than by copying the whole file again. - */ - bool replaceMetadataInFile (const File& wavFile, const StringPairArray& newMetadata); - - -private: - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (WavAudioFormat) -}; diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/codecs/juce_WindowsMediaAudioFormat.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/codecs/juce_WindowsMediaAudioFormat.cpp deleted file mode 100644 index f5f5664833..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/codecs/juce_WindowsMediaAudioFormat.cpp +++ /dev/null @@ -1,350 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -namespace WindowsMediaCodec -{ - -class JuceIStream : public ComBaseClassHelper -{ -public: - JuceIStream (InputStream& in) noexcept - : ComBaseClassHelper (0), source (in) - { - } - - JUCE_COMRESULT Commit (DWORD) { return S_OK; } - JUCE_COMRESULT Write (const void*, ULONG, ULONG*) { return E_NOTIMPL; } - JUCE_COMRESULT Clone (IStream**) { return E_NOTIMPL; } - JUCE_COMRESULT SetSize (ULARGE_INTEGER) { return E_NOTIMPL; } - JUCE_COMRESULT Revert() { return E_NOTIMPL; } - JUCE_COMRESULT LockRegion (ULARGE_INTEGER, ULARGE_INTEGER, DWORD) { return E_NOTIMPL; } - JUCE_COMRESULT UnlockRegion (ULARGE_INTEGER, ULARGE_INTEGER, DWORD) { return E_NOTIMPL; } - - JUCE_COMRESULT Read (void* dest, ULONG numBytes, ULONG* bytesRead) - { - const int numRead = source.read (dest, numBytes); - - if (bytesRead != nullptr) - *bytesRead = numRead; - - return (numRead == (int) numBytes) ? S_OK : S_FALSE; - } - - JUCE_COMRESULT Seek (LARGE_INTEGER position, DWORD origin, ULARGE_INTEGER* resultPosition) - { - int64 newPos = (int64) position.QuadPart; - - if (origin == STREAM_SEEK_CUR) - { - newPos += source.getPosition(); - } - else if (origin == STREAM_SEEK_END) - { - const int64 len = source.getTotalLength(); - if (len < 0) - return E_NOTIMPL; - - newPos += len; - } - - if (resultPosition != nullptr) - resultPosition->QuadPart = newPos; - - return source.setPosition (newPos) ? S_OK : E_NOTIMPL; - } - - JUCE_COMRESULT CopyTo (IStream* destStream, ULARGE_INTEGER numBytesToDo, - ULARGE_INTEGER* bytesRead, ULARGE_INTEGER* bytesWritten) - { - uint64 totalCopied = 0; - int64 numBytes = numBytesToDo.QuadPart; - - while (numBytes > 0 && ! source.isExhausted()) - { - char buffer [1024]; - - const int numToCopy = (int) jmin ((int64) sizeof (buffer), (int64) numBytes); - const int numRead = source.read (buffer, numToCopy); - - if (numRead <= 0) - break; - - destStream->Write (buffer, numRead, nullptr); - totalCopied += numRead; - } - - if (bytesRead != nullptr) bytesRead->QuadPart = totalCopied; - if (bytesWritten != nullptr) bytesWritten->QuadPart = totalCopied; - - return S_OK; - } - - JUCE_COMRESULT Stat (STATSTG* stat, DWORD) - { - if (stat == nullptr) - return STG_E_INVALIDPOINTER; - - zerostruct (*stat); - stat->type = STGTY_STREAM; - stat->cbSize.QuadPart = jmax ((int64) 0, source.getTotalLength()); - return S_OK; - } - -private: - InputStream& source; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (JuceIStream) -}; - -//============================================================================== -static const char* wmFormatName = "Windows Media"; -static const char* const extensions[] = { ".mp3", ".wmv", ".asf", ".wm", ".wma", 0 }; - -//============================================================================== -class WMAudioReader : public AudioFormatReader -{ -public: - WMAudioReader (InputStream* const input_) - : AudioFormatReader (input_, TRANS (wmFormatName)), - wmvCoreLib ("Wmvcore.dll") - { - JUCE_LOAD_WINAPI_FUNCTION (wmvCoreLib, WMCreateSyncReader, wmCreateSyncReader, - HRESULT, (IUnknown*, DWORD, IWMSyncReader**)) - - if (wmCreateSyncReader != nullptr) - { - checkCoInitialiseCalled(); - - HRESULT hr = wmCreateSyncReader (nullptr, WMT_RIGHT_PLAYBACK, wmSyncReader.resetAndGetPointerAddress()); - - if (SUCCEEDED (hr)) - hr = wmSyncReader->OpenStream (new JuceIStream (*input)); - - if (SUCCEEDED (hr)) - { - WORD streamNum = 1; - hr = wmSyncReader->GetStreamNumberForOutput (0, &streamNum); - hr = wmSyncReader->SetReadStreamSamples (streamNum, false); - - scanFileForDetails(); - } - } - } - - ~WMAudioReader() - { - if (wmSyncReader != nullptr) - wmSyncReader->Close(); - } - - bool readSamples (int** destSamples, int numDestChannels, int startOffsetInDestBuffer, - int64 startSampleInFile, int numSamples) override - { - if (sampleRate <= 0) - return false; - - checkCoInitialiseCalled(); - - const int stride = numChannels * sizeof (int16); - - while (numSamples > 0) - { - if (! bufferedRange.contains (startSampleInFile)) - { - const bool hasJumped = (startSampleInFile != bufferedRange.getEnd()); - - if (hasJumped) - wmSyncReader->SetRange ((QWORD) (startSampleInFile * 10000000 / (int64) sampleRate), 0); - - ComSmartPtr sampleBuffer; - QWORD sampleTime, duration; - DWORD flags, outputNum; - WORD streamNum; - - HRESULT hr = wmSyncReader->GetNextSample (1, sampleBuffer.resetAndGetPointerAddress(), - &sampleTime, &duration, &flags, &outputNum, &streamNum); - - if (sampleBuffer != nullptr) - { - BYTE* rawData = nullptr; - DWORD dataLength = 0; - hr = sampleBuffer->GetBufferAndLength (&rawData, &dataLength); - - if (dataLength == 0) - return false; - - if (hasJumped) - bufferedRange.setStart ((int64) ((sampleTime * (int64) sampleRate) / 10000000)); - else - bufferedRange.setStart (bufferedRange.getEnd()); // (because the positions returned often aren't continguous) - - bufferedRange.setLength ((int64) (dataLength / stride)); - - buffer.ensureSize ((int) dataLength); - memcpy (buffer.getData(), rawData, (size_t) dataLength); - } - else if (hr == NS_E_NO_MORE_SAMPLES) - { - bufferedRange.setStart (startSampleInFile); - bufferedRange.setLength (256); - buffer.ensureSize (256 * stride); - buffer.fillWith (0); - } - else - { - return false; - } - } - - const int offsetInBuffer = (int) (startSampleInFile - bufferedRange.getStart()); - const int16* const rawData = static_cast (addBytesToPointer (buffer.getData(), offsetInBuffer * stride)); - const int numToDo = jmin (numSamples, (int) (bufferedRange.getLength() - offsetInBuffer)); - - for (int i = 0; i < numDestChannels; ++i) - { - jassert (destSamples[i] != nullptr); - - const int srcChan = jmin (i, (int) numChannels - 1); - const int16* src = rawData + srcChan; - int* const dst = destSamples[i] + startOffsetInDestBuffer; - - for (int j = 0; j < numToDo; ++j) - { - dst[j] = ((uint32) *src) << 16; - src += numChannels; - } - } - - startSampleInFile += numToDo; - startOffsetInDestBuffer += numToDo; - numSamples -= numToDo; - } - - return true; - } - -private: - DynamicLibrary wmvCoreLib; - ComSmartPtr wmSyncReader; - MemoryBlock buffer; - Range bufferedRange; - - void checkCoInitialiseCalled() - { - CoInitialize (0); - } - - void scanFileForDetails() - { - ComSmartPtr wmHeaderInfo; - HRESULT hr = wmSyncReader.QueryInterface (wmHeaderInfo); - - if (SUCCEEDED (hr)) - { - QWORD lengthInNanoseconds = 0; - WORD lengthOfLength = sizeof (lengthInNanoseconds); - WORD streamNum = 0; - WMT_ATTR_DATATYPE wmAttrDataType; - hr = wmHeaderInfo->GetAttributeByName (&streamNum, L"Duration", &wmAttrDataType, - (BYTE*) &lengthInNanoseconds, &lengthOfLength); - - ComSmartPtr wmProfile; - hr = wmSyncReader.QueryInterface (wmProfile); - - if (SUCCEEDED (hr)) - { - ComSmartPtr wmStreamConfig; - hr = wmProfile->GetStream (0, wmStreamConfig.resetAndGetPointerAddress()); - - if (SUCCEEDED (hr)) - { - ComSmartPtr wmMediaProperties; - hr = wmStreamConfig.QueryInterface (wmMediaProperties); - - if (SUCCEEDED (hr)) - { - DWORD sizeMediaType; - hr = wmMediaProperties->GetMediaType (0, &sizeMediaType); - - HeapBlock mediaType; - mediaType.malloc (sizeMediaType, 1); - hr = wmMediaProperties->GetMediaType (mediaType, &sizeMediaType); - - if (mediaType->majortype == WMMEDIATYPE_Audio) - { - const WAVEFORMATEX* const inputFormat = reinterpret_cast (mediaType->pbFormat); - - sampleRate = inputFormat->nSamplesPerSec; - numChannels = inputFormat->nChannels; - bitsPerSample = inputFormat->wBitsPerSample; - lengthInSamples = (lengthInNanoseconds * (int) sampleRate) / 10000000; - } - } - } - } - } - } - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (WMAudioReader) -}; - -} - -//============================================================================== -WindowsMediaAudioFormat::WindowsMediaAudioFormat() - : AudioFormat (TRANS (WindowsMediaCodec::wmFormatName), - StringArray (WindowsMediaCodec::extensions)) -{ -} - -WindowsMediaAudioFormat::~WindowsMediaAudioFormat() {} - -Array WindowsMediaAudioFormat::getPossibleSampleRates() { return Array(); } -Array WindowsMediaAudioFormat::getPossibleBitDepths() { return Array(); } - -bool WindowsMediaAudioFormat::canDoStereo() { return true; } -bool WindowsMediaAudioFormat::canDoMono() { return true; } -bool WindowsMediaAudioFormat::isCompressed() { return true; } - -//============================================================================== -AudioFormatReader* WindowsMediaAudioFormat::createReaderFor (InputStream* sourceStream, bool deleteStreamIfOpeningFails) -{ - ScopedPointer r (new WindowsMediaCodec::WMAudioReader (sourceStream)); - - if (r->sampleRate > 0) - return r.release(); - - if (! deleteStreamIfOpeningFails) - r->input = nullptr; - - return nullptr; -} - -AudioFormatWriter* WindowsMediaAudioFormat::createWriterFor (OutputStream* /*streamToWriteTo*/, double /*sampleRateToUse*/, - unsigned int /*numberOfChannels*/, int /*bitsPerSample*/, - const StringPairArray& /*metadataValues*/, int /*qualityOptionIndex*/) -{ - jassertfalse; // not yet implemented! - return nullptr; -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/codecs/juce_WindowsMediaAudioFormat.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/codecs/juce_WindowsMediaAudioFormat.h deleted file mode 100644 index 8c10ee12da..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/codecs/juce_WindowsMediaAudioFormat.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#if JUCE_WINDOWS || DOXYGEN - -//============================================================================== -/** - Audio format which uses the Windows Media codecs (Windows only). -*/ -class WindowsMediaAudioFormat : public AudioFormat -{ -public: - //============================================================================== - WindowsMediaAudioFormat(); - ~WindowsMediaAudioFormat(); - - //============================================================================== - Array getPossibleSampleRates() override; - Array getPossibleBitDepths() override; - bool canDoStereo() override; - bool canDoMono() override; - bool isCompressed() override; - - //============================================================================== - AudioFormatReader* createReaderFor (InputStream*, bool deleteStreamIfOpeningFails) override; - - AudioFormatWriter* createWriterFor (OutputStream*, double sampleRateToUse, - unsigned int numberOfChannels, int bitsPerSample, - const StringPairArray& metadataValues, int qualityOptionIndex) override; -}; - -#endif diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/format/juce_AudioFormat.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/format/juce_AudioFormat.cpp deleted file mode 100644 index ad871765ad..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/format/juce_AudioFormat.cpp +++ /dev/null @@ -1,56 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -AudioFormat::AudioFormat (String name, StringArray extensions) - : formatName (name), fileExtensions (extensions) -{ -} - -AudioFormat::AudioFormat (StringRef name, StringRef extensions) - : formatName (name.text), fileExtensions (StringArray::fromTokens (extensions, false)) -{ -} - -AudioFormat::~AudioFormat() -{ -} - -bool AudioFormat::canHandleFile (const File& f) -{ - for (int i = 0; i < fileExtensions.size(); ++i) - if (f.hasFileExtension (fileExtensions[i])) - return true; - - return false; -} - -const String& AudioFormat::getFormatName() const { return formatName; } -const StringArray& AudioFormat::getFileExtensions() const { return fileExtensions; } -bool AudioFormat::isCompressed() { return false; } -StringArray AudioFormat::getQualityOptions() { return StringArray(); } - -MemoryMappedAudioFormatReader* AudioFormat::createMemoryMappedReader (const File&) -{ - return nullptr; -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/format/juce_AudioFormat.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/format/juce_AudioFormat.h deleted file mode 100644 index 196d4366c2..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/format/juce_AudioFormat.h +++ /dev/null @@ -1,178 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_AUDIOFORMAT_H_INCLUDED -#define JUCE_AUDIOFORMAT_H_INCLUDED - - -//============================================================================== -/** - Subclasses of AudioFormat are used to read and write different audio - file formats. - - @see AudioFormatReader, AudioFormatWriter, WavAudioFormat, AiffAudioFormat -*/ -class JUCE_API AudioFormat -{ -public: - //============================================================================== - /** Destructor. */ - virtual ~AudioFormat(); - - //============================================================================== - /** Returns the name of this format. - e.g. "WAV file" or "AIFF file" - */ - const String& getFormatName() const; - - /** Returns all the file extensions that might apply to a file of this format. - - The first item will be the one that's preferred when creating a new file. - - So for a wav file this might just return ".wav"; for an AIFF file it might - return two items, ".aif" and ".aiff" - */ - const StringArray& getFileExtensions() const; - - //============================================================================== - /** Returns true if this the given file can be read by this format. - - Subclasses shouldn't do too much work here, just check the extension or - file type. The base class implementation just checks the file's extension - against one of the ones that was registered in the constructor. - */ - virtual bool canHandleFile (const File& fileToTest); - - /** Returns a set of sample rates that the format can read and write. */ - virtual Array getPossibleSampleRates() = 0; - - /** Returns a set of bit depths that the format can read and write. */ - virtual Array getPossibleBitDepths() = 0; - - /** Returns true if the format can do 2-channel audio. */ - virtual bool canDoStereo() = 0; - - /** Returns true if the format can do 1-channel audio. */ - virtual bool canDoMono() = 0; - - /** Returns true if the format uses compressed data. */ - virtual bool isCompressed(); - - /** Returns a list of different qualities that can be used when writing. - - Non-compressed formats will just return an empty array, but for something - like Ogg-Vorbis or MP3, it might return a list of bit-rates, etc. - - When calling createWriterFor(), an index from this array is passed in to - tell the format which option is required. - */ - virtual StringArray getQualityOptions(); - - //============================================================================== - /** Tries to create an object that can read from a stream containing audio - data in this format. - - The reader object that is returned can be used to read from the stream, and - should then be deleted by the caller. - - @param sourceStream the stream to read from - the AudioFormatReader object - that is returned will delete this stream when it no longer - needs it. - @param deleteStreamIfOpeningFails if no reader can be created, this determines whether this method - should delete the stream object that was passed-in. (If a valid - reader is returned, it will always be in charge of deleting the - stream, so this parameter is ignored) - @see AudioFormatReader - */ - virtual AudioFormatReader* createReaderFor (InputStream* sourceStream, - bool deleteStreamIfOpeningFails) = 0; - - /** Attempts to create a MemoryMappedAudioFormatReader, if possible for this format. - If the format does not support this, the method will return nullptr; - */ - virtual MemoryMappedAudioFormatReader* createMemoryMappedReader (const File& file); - - /** Tries to create an object that can write to a stream with this audio format. - - The writer object that is returned can be used to write to the stream, and - should then be deleted by the caller. - - If the stream can't be created for some reason (e.g. the parameters passed in - here aren't suitable), this will return 0. - - @param streamToWriteTo the stream that the data will go to - this will be - deleted by the AudioFormatWriter object when it's no longer - needed. If no AudioFormatWriter can be created by this method, - the stream will NOT be deleted, so that the caller can re-use it - to try to open a different format, etc - @param sampleRateToUse the sample rate for the file, which must be one of the ones - returned by getPossibleSampleRates() - @param numberOfChannels the number of channels - this must be either 1 or 2, and - the choice will depend on the results of canDoMono() and - canDoStereo() - @param bitsPerSample the bits per sample to use - this must be one of the values - returned by getPossibleBitDepths() - @param metadataValues a set of metadata values that the writer should try to write - to the stream. Exactly what these are depends on the format, - and the subclass doesn't actually have to do anything with - them if it doesn't want to. Have a look at the specific format - implementation classes to see possible values that can be - used - @param qualityOptionIndex the index of one of compression qualities returned by the - getQualityOptions() method. If there aren't any quality options - for this format, just pass 0 in this parameter, as it'll be - ignored - @see AudioFormatWriter - */ - virtual AudioFormatWriter* createWriterFor (OutputStream* streamToWriteTo, - double sampleRateToUse, - unsigned int numberOfChannels, - int bitsPerSample, - const StringPairArray& metadataValues, - int qualityOptionIndex) = 0; - -protected: - /** Creates an AudioFormat object. - - @param formatName this sets the value that will be returned by getFormatName() - @param fileExtensions an array of file extensions - these will be returned by getFileExtensions() - */ - AudioFormat (String formatName, StringArray fileExtensions); - - /** Creates an AudioFormat object. - - @param formatName this sets the value that will be returned by getFormatName() - @param fileExtensions a whitespace-separated list of file extensions - these will - be returned by getFileExtensions() - */ - AudioFormat (StringRef formatName, StringRef fileExtensions); - -private: - //============================================================================== - String formatName; - StringArray fileExtensions; -}; - - -#endif // JUCE_AUDIOFORMAT_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/format/juce_AudioFormatManager.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/format/juce_AudioFormatManager.cpp deleted file mode 100644 index f0196c8635..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/format/juce_AudioFormatManager.cpp +++ /dev/null @@ -1,177 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -AudioFormatManager::AudioFormatManager() : defaultFormatIndex (0) {} -AudioFormatManager::~AudioFormatManager() {} - -//============================================================================== -void AudioFormatManager::registerFormat (AudioFormat* newFormat, const bool makeThisTheDefaultFormat) -{ - jassert (newFormat != nullptr); - - if (newFormat != nullptr) - { - #if JUCE_DEBUG - for (int i = getNumKnownFormats(); --i >= 0;) - { - if (getKnownFormat (i)->getFormatName() == newFormat->getFormatName()) - { - jassertfalse; // trying to add the same format twice! - } - } - #endif - - if (makeThisTheDefaultFormat) - defaultFormatIndex = getNumKnownFormats(); - - knownFormats.add (newFormat); - } -} - -void AudioFormatManager::registerBasicFormats() -{ - registerFormat (new WavAudioFormat(), true); - registerFormat (new AiffAudioFormat(), false); - - #if JUCE_USE_FLAC - registerFormat (new FlacAudioFormat(), false); - #endif - - #if JUCE_USE_OGGVORBIS - registerFormat (new OggVorbisAudioFormat(), false); - #endif - - #if JUCE_MAC || JUCE_IOS - registerFormat (new CoreAudioFormat(), false); - #endif - - #if JUCE_USE_MP3AUDIOFORMAT - registerFormat (new MP3AudioFormat(), false); - #endif - - #if JUCE_USE_WINDOWS_MEDIA_FORMAT - registerFormat (new WindowsMediaAudioFormat(), false); - #endif -} - -void AudioFormatManager::clearFormats() -{ - knownFormats.clear(); - defaultFormatIndex = 0; -} - -int AudioFormatManager::getNumKnownFormats() const -{ - return knownFormats.size(); -} - -AudioFormat* AudioFormatManager::getKnownFormat (const int index) const -{ - return knownFormats [index]; -} - -AudioFormat* AudioFormatManager::getDefaultFormat() const -{ - return getKnownFormat (defaultFormatIndex); -} - -AudioFormat* AudioFormatManager::findFormatForFileExtension (const String& fileExtension) const -{ - if (! fileExtension.startsWithChar ('.')) - return findFormatForFileExtension ("." + fileExtension); - - for (int i = 0; i < getNumKnownFormats(); ++i) - if (getKnownFormat(i)->getFileExtensions().contains (fileExtension, true)) - return getKnownFormat(i); - - return nullptr; -} - -String AudioFormatManager::getWildcardForAllFormats() const -{ - StringArray extensions; - - for (int i = 0; i < getNumKnownFormats(); ++i) - extensions.addArray (getKnownFormat(i)->getFileExtensions()); - - extensions.trim(); - extensions.removeEmptyStrings(); - - for (int i = 0; i < extensions.size(); ++i) - extensions.set (i, (extensions[i].startsWithChar ('.') ? "*" : "*.") + extensions[i]); - - extensions.removeDuplicates (true); - return extensions.joinIntoString (";"); -} - -//============================================================================== -AudioFormatReader* AudioFormatManager::createReaderFor (const File& file) -{ - // you need to actually register some formats before the manager can - // use them to open a file! - jassert (getNumKnownFormats() > 0); - - for (int i = 0; i < getNumKnownFormats(); ++i) - { - AudioFormat* const af = getKnownFormat(i); - - if (af->canHandleFile (file)) - if (InputStream* const in = file.createInputStream()) - if (AudioFormatReader* const r = af->createReaderFor (in, true)) - return r; - } - - return nullptr; -} - -AudioFormatReader* AudioFormatManager::createReaderFor (InputStream* audioFileStream) -{ - // you need to actually register some formats before the manager can - // use them to open a file! - jassert (getNumKnownFormats() > 0); - - ScopedPointer in (audioFileStream); - - if (in != nullptr) - { - const int64 originalStreamPos = in->getPosition(); - - for (int i = 0; i < getNumKnownFormats(); ++i) - { - if (AudioFormatReader* const r = getKnownFormat(i)->createReaderFor (in, false)) - { - in.release(); - return r; - } - - in->setPosition (originalStreamPos); - - // the stream that is passed-in must be capable of being repositioned so - // that all the formats can have a go at opening it. - jassert (in->getPosition() == originalStreamPos); - } - } - - return nullptr; -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/format/juce_AudioFormatManager.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/format/juce_AudioFormatManager.h deleted file mode 100644 index f560347d62..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/format/juce_AudioFormatManager.h +++ /dev/null @@ -1,143 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_AUDIOFORMATMANAGER_H_INCLUDED -#define JUCE_AUDIOFORMATMANAGER_H_INCLUDED - - -//============================================================================== -/** - A class for keeping a list of available audio formats, and for deciding which - one to use to open a given file. - - After creating an AudioFormatManager object, you should call registerFormat() - or registerBasicFormats() to give it a list of format types that it can use. - - @see AudioFormat -*/ -class JUCE_API AudioFormatManager -{ -public: - //============================================================================== - /** Creates an empty format manager. - - Before it'll be any use, you'll need to call registerFormat() with all the - formats you want it to be able to recognise. - */ - AudioFormatManager(); - - /** Destructor. */ - ~AudioFormatManager(); - - //============================================================================== - /** Adds a format to the manager's list of available file types. - - The object passed-in will be deleted by this object, so don't keep a pointer - to it! - - If makeThisTheDefaultFormat is true, then the getDefaultFormat() method will - return this one when called. - */ - void registerFormat (AudioFormat* newFormat, - bool makeThisTheDefaultFormat); - - /** Handy method to make it easy to register the formats that come with Juce. - - Currently, this will add WAV and AIFF to the list. - */ - void registerBasicFormats(); - - /** Clears the list of known formats. */ - void clearFormats(); - - /** Returns the number of currently registered file formats. */ - int getNumKnownFormats() const; - - /** Returns one of the registered file formats. */ - AudioFormat* getKnownFormat (int index) const; - - /** Iterator access to the list of known formats. */ - AudioFormat** begin() const noexcept { return knownFormats.begin(); } - - /** Iterator access to the list of known formats. */ - AudioFormat** end() const noexcept { return knownFormats.end(); } - - /** Looks for which of the known formats is listed as being for a given file - extension. - - The extension may have a dot before it, so e.g. ".wav" or "wav" are both ok. - */ - AudioFormat* findFormatForFileExtension (const String& fileExtension) const; - - /** Returns the format which has been set as the default one. - - You can set a format as being the default when it is registered. It's useful - when you want to write to a file, because the best format may change between - platforms, e.g. AIFF is preferred on the Mac, WAV on Windows. - - If none has been set as the default, this method will just return the first - one in the list. - */ - AudioFormat* getDefaultFormat() const; - - /** Returns a set of wildcards for file-matching that contains the extensions for - all known formats. - - E.g. if might return "*.wav;*.aiff" if it just knows about wavs and aiffs. - */ - String getWildcardForAllFormats() const; - - //============================================================================== - /** Searches through the known formats to try to create a suitable reader for - this file. - - If none of the registered formats can open the file, it'll return 0. If it - returns a reader, it's the caller's responsibility to delete the reader. - */ - AudioFormatReader* createReaderFor (const File& audioFile); - - /** Searches through the known formats to try to create a suitable reader for - this stream. - - The stream object that is passed-in will be deleted by this method or by the - reader that is returned, so the caller should not keep any references to it. - - The stream that is passed-in must be capable of being repositioned so - that all the formats can have a go at opening it. - - If none of the registered formats can open the stream, it'll return 0. If it - returns a reader, it's the caller's responsibility to delete the reader. - */ - AudioFormatReader* createReaderFor (InputStream* audioFileStream); - -private: - //============================================================================== - OwnedArray knownFormats; - int defaultFormatIndex; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioFormatManager) -}; - - -#endif // JUCE_AUDIOFORMATMANAGER_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/format/juce_AudioFormatReader.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/format/juce_AudioFormatReader.cpp deleted file mode 100644 index 5db3149eff..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/format/juce_AudioFormatReader.cpp +++ /dev/null @@ -1,412 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -AudioFormatReader::AudioFormatReader (InputStream* const in, const String& name) - : sampleRate (0), - bitsPerSample (0), - lengthInSamples (0), - numChannels (0), - usesFloatingPointData (false), - input (in), - formatName (name) -{ -} - -AudioFormatReader::~AudioFormatReader() -{ - delete input; -} - -bool AudioFormatReader::read (int* const* destSamples, - int numDestChannels, - int64 startSampleInSource, - int numSamplesToRead, - const bool fillLeftoverChannelsWithCopies) -{ - jassert (numDestChannels > 0); // you have to actually give this some channels to work with! - - int startOffsetInDestBuffer = 0; - - if (startSampleInSource < 0) - { - const int silence = (int) jmin (-startSampleInSource, (int64) numSamplesToRead); - - for (int i = numDestChannels; --i >= 0;) - if (destSamples[i] != nullptr) - zeromem (destSamples[i], sizeof (int) * (size_t) silence); - - startOffsetInDestBuffer += silence; - numSamplesToRead -= silence; - startSampleInSource = 0; - } - - if (numSamplesToRead <= 0) - return true; - - if (! readSamples (const_cast (destSamples), - jmin ((int) numChannels, numDestChannels), startOffsetInDestBuffer, - startSampleInSource, numSamplesToRead)) - return false; - - if (numDestChannels > (int) numChannels) - { - if (fillLeftoverChannelsWithCopies) - { - int* lastFullChannel = destSamples[0]; - - for (int i = (int) numChannels; --i > 0;) - { - if (destSamples[i] != nullptr) - { - lastFullChannel = destSamples[i]; - break; - } - } - - if (lastFullChannel != nullptr) - for (int i = (int) numChannels; i < numDestChannels; ++i) - if (destSamples[i] != nullptr) - memcpy (destSamples[i], lastFullChannel, sizeof (int) * (size_t) numSamplesToRead); - } - else - { - for (int i = (int) numChannels; i < numDestChannels; ++i) - if (destSamples[i] != nullptr) - zeromem (destSamples[i], sizeof (int) * (size_t) numSamplesToRead); - } - } - - return true; -} - -static void readChannels (AudioFormatReader& reader, - int** const chans, AudioSampleBuffer* const buffer, - const int startSample, const int numSamples, - const int64 readerStartSample, const int numTargetChannels) -{ - for (int j = 0; j < numTargetChannels; ++j) - chans[j] = reinterpret_cast (buffer->getWritePointer (j, startSample)); - - chans[numTargetChannels] = nullptr; - reader.read (chans, numTargetChannels, readerStartSample, numSamples, true); -} - -void AudioFormatReader::read (AudioSampleBuffer* buffer, - int startSample, - int numSamples, - int64 readerStartSample, - bool useReaderLeftChan, - bool useReaderRightChan) -{ - jassert (buffer != nullptr); - jassert (startSample >= 0 && startSample + numSamples <= buffer->getNumSamples()); - - if (numSamples > 0) - { - const int numTargetChannels = buffer->getNumChannels(); - - if (numTargetChannels <= 2) - { - int* const dest0 = reinterpret_cast (buffer->getWritePointer (0, startSample)); - int* const dest1 = reinterpret_cast (numTargetChannels > 1 ? buffer->getWritePointer (1, startSample) : nullptr); - int* chans[3]; - - if (useReaderLeftChan == useReaderRightChan) - { - chans[0] = dest0; - chans[1] = numChannels > 1 ? dest1 : nullptr; - } - else if (useReaderLeftChan || (numChannels == 1)) - { - chans[0] = dest0; - chans[1] = nullptr; - } - else if (useReaderRightChan) - { - chans[0] = nullptr; - chans[1] = dest0; - } - - chans[2] = nullptr; - read (chans, 2, readerStartSample, numSamples, true); - - // if the target's stereo and the source is mono, dupe the first channel.. - if (numTargetChannels > 1 && (chans[0] == nullptr || chans[1] == nullptr)) - memcpy (dest1, dest0, sizeof (float) * (size_t) numSamples); - } - else if (numTargetChannels <= 64) - { - int* chans[65]; - readChannels (*this, chans, buffer, startSample, numSamples, readerStartSample, numTargetChannels); - } - else - { - HeapBlock chans ((size_t) numTargetChannels); - readChannels (*this, chans, buffer, startSample, numSamples, readerStartSample, numTargetChannels); - } - - if (! usesFloatingPointData) - for (int j = 0; j < numTargetChannels; ++j) - if (float* const d = buffer->getWritePointer (j, startSample)) - FloatVectorOperations::convertFixedToFloat (d, reinterpret_cast (d), 1.0f / 0x7fffffff, numSamples); - } -} - -void AudioFormatReader::readMaxLevels (int64 startSampleInFile, int64 numSamples, - Range* const results, const int channelsToRead) -{ - jassert (channelsToRead > 0 && channelsToRead <= (int) numChannels); - - if (numSamples <= 0) - { - for (int i = 0; i < channelsToRead; ++i) - results[i] = Range(); - - return; - } - - const int bufferSize = (int) jmin (numSamples, (int64) 4096); - AudioSampleBuffer tempSampleBuffer ((int) channelsToRead, bufferSize); - - float* const* const floatBuffer = tempSampleBuffer.getArrayOfWritePointers(); - int* const* intBuffer = reinterpret_cast (floatBuffer); - bool isFirstBlock = true; - - while (numSamples > 0) - { - const int numToDo = (int) jmin (numSamples, (int64) bufferSize); - if (! read (intBuffer, channelsToRead, startSampleInFile, numToDo, false)) - break; - - for (int i = 0; i < channelsToRead; ++i) - { - Range r; - - if (usesFloatingPointData) - { - r = FloatVectorOperations::findMinAndMax (floatBuffer[i], numToDo); - } - else - { - Range intRange (Range::findMinAndMax (intBuffer[i], numToDo)); - - r = Range (intRange.getStart() / (float) std::numeric_limits::max(), - intRange.getEnd() / (float) std::numeric_limits::max()); - } - - results[i] = isFirstBlock ? r : results[i].getUnionWith (r); - } - - isFirstBlock = false; - numSamples -= numToDo; - startSampleInFile += numToDo; - } -} - -void AudioFormatReader::readMaxLevels (int64 startSampleInFile, int64 numSamples, - float& lowestLeft, float& highestLeft, - float& lowestRight, float& highestRight) -{ - Range levels[2]; - readMaxLevels (startSampleInFile, numSamples, levels, jmin (2, (int) numChannels)); - lowestLeft = levels[0].getStart(); - highestLeft = levels[0].getEnd(); - - if (numChannels > 1) - { - lowestRight = levels[1].getStart(); - highestRight = levels[1].getEnd(); - } - else - { - lowestRight = lowestLeft; - highestRight = highestLeft; - } -} - -int64 AudioFormatReader::searchForLevel (int64 startSample, - int64 numSamplesToSearch, - const double magnitudeRangeMinimum, - const double magnitudeRangeMaximum, - const int minimumConsecutiveSamples) -{ - if (numSamplesToSearch == 0) - return -1; - - const int bufferSize = 4096; - HeapBlock tempSpace (bufferSize * 2 + 64); - - int* tempBuffer[3]; - tempBuffer[0] = tempSpace.getData(); - tempBuffer[1] = tempSpace.getData() + bufferSize; - tempBuffer[2] = 0; - - int consecutive = 0; - int64 firstMatchPos = -1; - - jassert (magnitudeRangeMaximum > magnitudeRangeMinimum); - - const double doubleMin = jlimit (0.0, (double) std::numeric_limits::max(), magnitudeRangeMinimum * std::numeric_limits::max()); - const double doubleMax = jlimit (doubleMin, (double) std::numeric_limits::max(), magnitudeRangeMaximum * std::numeric_limits::max()); - const int intMagnitudeRangeMinimum = roundToInt (doubleMin); - const int intMagnitudeRangeMaximum = roundToInt (doubleMax); - - while (numSamplesToSearch != 0) - { - const int numThisTime = (int) jmin (abs64 (numSamplesToSearch), (int64) bufferSize); - int64 bufferStart = startSample; - - if (numSamplesToSearch < 0) - bufferStart -= numThisTime; - - if (bufferStart >= (int) lengthInSamples) - break; - - read (tempBuffer, 2, bufferStart, numThisTime, false); - - int num = numThisTime; - while (--num >= 0) - { - if (numSamplesToSearch < 0) - --startSample; - - bool matches = false; - const int index = (int) (startSample - bufferStart); - - if (usesFloatingPointData) - { - const float sample1 = std::abs (((float*) tempBuffer[0]) [index]); - - if (sample1 >= magnitudeRangeMinimum - && sample1 <= magnitudeRangeMaximum) - { - matches = true; - } - else if (numChannels > 1) - { - const float sample2 = std::abs (((float*) tempBuffer[1]) [index]); - - matches = (sample2 >= magnitudeRangeMinimum - && sample2 <= magnitudeRangeMaximum); - } - } - else - { - const int sample1 = abs (tempBuffer[0] [index]); - - if (sample1 >= intMagnitudeRangeMinimum - && sample1 <= intMagnitudeRangeMaximum) - { - matches = true; - } - else if (numChannels > 1) - { - const int sample2 = abs (tempBuffer[1][index]); - - matches = (sample2 >= intMagnitudeRangeMinimum - && sample2 <= intMagnitudeRangeMaximum); - } - } - - if (matches) - { - if (firstMatchPos < 0) - firstMatchPos = startSample; - - if (++consecutive >= minimumConsecutiveSamples) - { - if (firstMatchPos < 0 || firstMatchPos >= lengthInSamples) - return -1; - - return firstMatchPos; - } - } - else - { - consecutive = 0; - firstMatchPos = -1; - } - - if (numSamplesToSearch > 0) - ++startSample; - } - - if (numSamplesToSearch > 0) - numSamplesToSearch -= numThisTime; - else - numSamplesToSearch += numThisTime; - } - - return -1; -} - -//============================================================================== -MemoryMappedAudioFormatReader::MemoryMappedAudioFormatReader (const File& f, const AudioFormatReader& reader, - int64 start, int64 length, int frameSize) - : AudioFormatReader (nullptr, reader.getFormatName()), file (f), - dataChunkStart (start), dataLength (length), bytesPerFrame (frameSize) -{ - sampleRate = reader.sampleRate; - bitsPerSample = reader.bitsPerSample; - lengthInSamples = reader.lengthInSamples; - numChannels = reader.numChannels; - metadataValues = reader.metadataValues; - usesFloatingPointData = reader.usesFloatingPointData; -} - -bool MemoryMappedAudioFormatReader::mapEntireFile() -{ - return mapSectionOfFile (Range (0, lengthInSamples)); -} - -bool MemoryMappedAudioFormatReader::mapSectionOfFile (Range samplesToMap) -{ - if (map == nullptr || samplesToMap != mappedSection) - { - map = nullptr; - - const Range fileRange (sampleToFilePos (samplesToMap.getStart()), - sampleToFilePos (samplesToMap.getEnd())); - - map = new MemoryMappedFile (file, fileRange, MemoryMappedFile::readOnly); - - if (map->getData() == nullptr) - map = nullptr; - else - mappedSection = Range (jmax ((int64) 0, filePosToSample (map->getRange().getStart() + (bytesPerFrame - 1))), - jmin (lengthInSamples, filePosToSample (map->getRange().getEnd()))); - } - - return map != nullptr; -} - -static int memoryReadDummyVariable; // used to force the compiler not to optimise-away the read operation - -void MemoryMappedAudioFormatReader::touchSample (int64 sample) const noexcept -{ - if (map != nullptr && mappedSection.contains (sample)) - memoryReadDummyVariable += *(char*) sampleToPointer (sample); - else - jassertfalse; // you must make sure that the window contains all the samples you're going to attempt to read. -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/format/juce_AudioFormatReader.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/format/juce_AudioFormatReader.h deleted file mode 100644 index 065388a77b..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/format/juce_AudioFormatReader.h +++ /dev/null @@ -1,300 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_AUDIOFORMATREADER_H_INCLUDED -#define JUCE_AUDIOFORMATREADER_H_INCLUDED - - -//============================================================================== -/** - Reads samples from an audio file stream. - - A subclass that reads a specific type of audio format will be created by - an AudioFormat object. - - @see AudioFormat, AudioFormatWriter -*/ -class JUCE_API AudioFormatReader -{ -protected: - //============================================================================== - /** Creates an AudioFormatReader object. - - @param sourceStream the stream to read from - this will be deleted - by this object when it is no longer needed. (Some - specialised readers might not use this parameter and - can leave it as 0). - @param formatName the description that will be returned by the getFormatName() - method - */ - AudioFormatReader (InputStream* sourceStream, - const String& formatName); - -public: - /** Destructor. */ - virtual ~AudioFormatReader(); - - //============================================================================== - /** Returns a description of what type of format this is. - - E.g. "AIFF" - */ - const String& getFormatName() const noexcept { return formatName; } - - //============================================================================== - /** Reads samples from the stream. - - @param destSamples an array of buffers into which the sample data for each - channel will be written. - If the format is fixed-point, each channel will be written - as an array of 32-bit signed integers using the full - range -0x80000000 to 0x7fffffff, regardless of the source's - bit-depth. If it is a floating-point format, you should cast - the resulting array to a (float**) to get the values (in the - range -1.0 to 1.0 or beyond) - If the format is stereo, then destSamples[0] is the left channel - data, and destSamples[1] is the right channel. - The numDestChannels parameter indicates how many pointers this array - contains, but some of these pointers can be null if you don't want to - read data for some of the channels - @param numDestChannels the number of array elements in the destChannels array - @param startSampleInSource the position in the audio file or stream at which the samples - should be read, as a number of samples from the start of the - stream. It's ok for this to be beyond the start or end of the - available data - any samples that are out-of-range will be returned - as zeros. - @param numSamplesToRead the number of samples to read. If this is greater than the number - of samples that the file or stream contains. the result will be padded - with zeros - @param fillLeftoverChannelsWithCopies if true, this indicates that if there's no source data available - for some of the channels that you pass in, then they should be filled with - copies of valid source channels. - E.g. if you're reading a mono file and you pass 2 channels to this method, then - if fillLeftoverChannelsWithCopies is true, both destination channels will be filled - with the same data from the file's single channel. If fillLeftoverChannelsWithCopies - was false, then only the first channel would be filled with the file's contents, and - the second would be cleared. If there are many channels, e.g. you try to read 4 channels - from a stereo file, then the last 3 would all end up with copies of the same data. - @returns true if the operation succeeded, false if there was an error. Note - that reading sections of data beyond the extent of the stream isn't an - error - the reader should just return zeros for these regions - @see readMaxLevels - */ - bool read (int* const* destSamples, - int numDestChannels, - int64 startSampleInSource, - int numSamplesToRead, - bool fillLeftoverChannelsWithCopies); - - /** Fills a section of an AudioSampleBuffer from this reader. - - This will convert the reader's fixed- or floating-point data to - the buffer's floating-point format, and will try to intelligently - cope with mismatches between the number of channels in the reader - and the buffer. - */ - void read (AudioSampleBuffer* buffer, - int startSampleInDestBuffer, - int numSamples, - int64 readerStartSample, - bool useReaderLeftChan, - bool useReaderRightChan); - - /** Finds the highest and lowest sample levels from a section of the audio stream. - - This will read a block of samples from the stream, and measure the - highest and lowest sample levels from the channels in that section, returning - these as normalised floating-point levels. - - @param startSample the offset into the audio stream to start reading from. It's - ok for this to be beyond the start or end of the stream. - @param numSamples how many samples to read - @param results this array will be filled with Range values for each channel. - The array must contain numChannels elements. - @param numChannelsToRead the number of channels of data to scan. This must be - more than zero, but not more than the total number of channels - that the reader contains - @see read - */ - virtual void readMaxLevels (int64 startSample, int64 numSamples, - Range* results, int numChannelsToRead); - - /** Finds the highest and lowest sample levels from a section of the audio stream. - - This will read a block of samples from the stream, and measure the - highest and lowest sample levels from the channels in that section, returning - these as normalised floating-point levels. - - @param startSample the offset into the audio stream to start reading from. It's - ok for this to be beyond the start or end of the stream. - @param numSamples how many samples to read - @param lowestLeft on return, this is the lowest absolute sample from the left channel - @param highestLeft on return, this is the highest absolute sample from the left channel - @param lowestRight on return, this is the lowest absolute sample from the right - channel (if there is one) - @param highestRight on return, this is the highest absolute sample from the right - channel (if there is one) - @see read - */ - virtual void readMaxLevels (int64 startSample, int64 numSamples, - float& lowestLeft, float& highestLeft, - float& lowestRight, float& highestRight); - - /** Scans the source looking for a sample whose magnitude is in a specified range. - - This will read from the source, either forwards or backwards between two sample - positions, until it finds a sample whose magnitude lies between two specified levels. - - If it finds a suitable sample, it returns its position; if not, it will return -1. - - There's also a minimumConsecutiveSamples setting to help avoid spikes or zero-crossing - points when you're searching for a continuous range of samples - - @param startSample the first sample to look at - @param numSamplesToSearch the number of samples to scan. If this value is negative, - the search will go backwards - @param magnitudeRangeMinimum the lowest magnitude (inclusive) that is considered a hit, from 0 to 1.0 - @param magnitudeRangeMaximum the highest magnitude (inclusive) that is considered a hit, from 0 to 1.0 - @param minimumConsecutiveSamples if this is > 0, the method will only look for a sequence - of this many consecutive samples, all of which lie - within the target range. When it finds such a sequence, - it returns the position of the first in-range sample - it found (i.e. the earliest one if scanning forwards, the - latest one if scanning backwards) - */ - int64 searchForLevel (int64 startSample, - int64 numSamplesToSearch, - double magnitudeRangeMinimum, - double magnitudeRangeMaximum, - int minimumConsecutiveSamples); - - - //============================================================================== - /** The sample-rate of the stream. */ - double sampleRate; - - /** The number of bits per sample, e.g. 16, 24, 32. */ - unsigned int bitsPerSample; - - /** The total number of samples in the audio stream. */ - int64 lengthInSamples; - - /** The total number of channels in the audio stream. */ - unsigned int numChannels; - - /** Indicates whether the data is floating-point or fixed. */ - bool usesFloatingPointData; - - /** A set of metadata values that the reader has pulled out of the stream. - - Exactly what these values are depends on the format, so you can - check out the format implementation code to see what kind of stuff - they understand. - */ - StringPairArray metadataValues; - - /** The input stream, for use by subclasses. */ - InputStream* input; - - - //============================================================================== - /** Subclasses must implement this method to perform the low-level read operation. - - Callers should use read() instead of calling this directly. - - @param destSamples the array of destination buffers to fill. Some of these - pointers may be null - @param numDestChannels the number of items in the destSamples array. This - value is guaranteed not to be greater than the number of - channels that this reader object contains - @param startOffsetInDestBuffer the number of samples from the start of the - dest data at which to begin writing - @param startSampleInFile the number of samples into the source data at which - to begin reading. This value is guaranteed to be >= 0. - @param numSamples the number of samples to read - */ - virtual bool readSamples (int** destSamples, - int numDestChannels, - int startOffsetInDestBuffer, - int64 startSampleInFile, - int numSamples) = 0; - - -protected: - //============================================================================== - /** Used by AudioFormatReader subclasses to copy data to different formats. */ - template - struct ReadHelper - { - typedef AudioData::Pointer DestType; - typedef AudioData::Pointer SourceType; - - template - static void read (TargetType* const* destData, int destOffset, int numDestChannels, - const void* sourceData, int numSourceChannels, int numSamples) noexcept - { - for (int i = 0; i < numDestChannels; ++i) - { - if (void* targetChan = destData[i]) - { - DestType dest (targetChan); - dest += destOffset; - - if (i < numSourceChannels) - dest.convertSamples (SourceType (addBytesToPointer (sourceData, i * SourceType::getBytesPerSample()), numSourceChannels), numSamples); - else - dest.clearSamples (numSamples); - } - } - } - }; - - /** Used by AudioFormatReader subclasses to clear any parts of the data blocks that lie - beyond the end of their available length. - */ - static void clearSamplesBeyondAvailableLength (int** destSamples, int numDestChannels, - int startOffsetInDestBuffer, int64 startSampleInFile, - int& numSamples, int64 fileLengthInSamples) - { - jassert (destSamples != nullptr); - const int64 samplesAvailable = fileLengthInSamples - startSampleInFile; - - if (samplesAvailable < numSamples) - { - for (int i = numDestChannels; --i >= 0;) - if (destSamples[i] != nullptr) - zeromem (destSamples[i] + startOffsetInDestBuffer, sizeof (int) * (size_t) numSamples); - - numSamples = (int) samplesAvailable; - } - } - -private: - String formatName; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioFormatReader) -}; - - -#endif // JUCE_AUDIOFORMATREADER_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/format/juce_AudioFormatReaderSource.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/format/juce_AudioFormatReaderSource.cpp deleted file mode 100644 index fb086ef8ef..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/format/juce_AudioFormatReaderSource.cpp +++ /dev/null @@ -1,85 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -AudioFormatReaderSource::AudioFormatReaderSource (AudioFormatReader* const r, - const bool deleteReaderWhenThisIsDeleted) - : reader (r, deleteReaderWhenThisIsDeleted), - nextPlayPos (0), - looping (false) -{ - jassert (reader != nullptr); -} - -AudioFormatReaderSource::~AudioFormatReaderSource() {} - -int64 AudioFormatReaderSource::getTotalLength() const { return reader->lengthInSamples; } -void AudioFormatReaderSource::setNextReadPosition (int64 newPosition) { nextPlayPos = newPosition; } -void AudioFormatReaderSource::setLooping (bool shouldLoop) { looping = shouldLoop; } - -int64 AudioFormatReaderSource::getNextReadPosition() const -{ - return looping ? nextPlayPos % reader->lengthInSamples - : nextPlayPos; -} - -void AudioFormatReaderSource::prepareToPlay (int /*samplesPerBlockExpected*/, double /*sampleRate*/) {} -void AudioFormatReaderSource::releaseResources() {} - -void AudioFormatReaderSource::getNextAudioBlock (const AudioSourceChannelInfo& info) -{ - if (info.numSamples > 0) - { - const int64 start = nextPlayPos; - - if (looping) - { - const int64 newStart = start % reader->lengthInSamples; - const int64 newEnd = (start + info.numSamples) % reader->lengthInSamples; - - if (newEnd > newStart) - { - reader->read (info.buffer, info.startSample, - (int) (newEnd - newStart), newStart, true, true); - } - else - { - const int endSamps = (int) (reader->lengthInSamples - newStart); - - reader->read (info.buffer, info.startSample, - endSamps, newStart, true, true); - - reader->read (info.buffer, info.startSample + endSamps, - (int) newEnd, 0, true, true); - } - - nextPlayPos = newEnd; - } - else - { - reader->read (info.buffer, info.startSample, - info.numSamples, start, true, true); - nextPlayPos += info.numSamples; - } - } -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/format/juce_AudioFormatReaderSource.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/format/juce_AudioFormatReaderSource.h deleted file mode 100644 index d7ff5f7844..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/format/juce_AudioFormatReaderSource.h +++ /dev/null @@ -1,100 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_AUDIOFORMATREADERSOURCE_H_INCLUDED -#define JUCE_AUDIOFORMATREADERSOURCE_H_INCLUDED - - -//============================================================================== -/** - A type of AudioSource that will read from an AudioFormatReader. - - @see PositionableAudioSource, AudioTransportSource, BufferingAudioSource -*/ -class JUCE_API AudioFormatReaderSource : public PositionableAudioSource -{ -public: - //============================================================================== - /** Creates an AudioFormatReaderSource for a given reader. - - @param sourceReader the reader to use as the data source - this must - not be null - @param deleteReaderWhenThisIsDeleted if true, the reader passed-in will be deleted - when this object is deleted; if false it will be - left up to the caller to manage its lifetime - */ - AudioFormatReaderSource (AudioFormatReader* sourceReader, - bool deleteReaderWhenThisIsDeleted); - - /** Destructor. */ - ~AudioFormatReaderSource(); - - //============================================================================== - /** Toggles loop-mode. - - If set to true, it will continuously loop the input source. If false, - it will just emit silence after the source has finished. - - @see isLooping - */ - void setLooping (bool shouldLoop); - - /** Returns whether loop-mode is turned on or not. */ - bool isLooping() const { return looping; } - - /** Returns the reader that's being used. */ - AudioFormatReader* getAudioFormatReader() const noexcept { return reader; } - - //============================================================================== - /** Implementation of the AudioSource method. */ - void prepareToPlay (int samplesPerBlockExpected, double sampleRate) override; - - /** Implementation of the AudioSource method. */ - void releaseResources() override; - - /** Implementation of the AudioSource method. */ - void getNextAudioBlock (const AudioSourceChannelInfo&) override; - - //============================================================================== - /** Implements the PositionableAudioSource method. */ - void setNextReadPosition (int64 newPosition) override; - - /** Implements the PositionableAudioSource method. */ - int64 getNextReadPosition() const override; - - /** Implements the PositionableAudioSource method. */ - int64 getTotalLength() const override; - -private: - //============================================================================== - OptionalScopedPointer reader; - - int64 volatile nextPlayPos; - bool volatile looping; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioFormatReaderSource) -}; - - -#endif // JUCE_AUDIOFORMATREADERSOURCE_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/format/juce_AudioFormatWriter.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/format/juce_AudioFormatWriter.cpp deleted file mode 100644 index 065f36afa4..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/format/juce_AudioFormatWriter.cpp +++ /dev/null @@ -1,342 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -AudioFormatWriter::AudioFormatWriter (OutputStream* const out, - const String& formatName_, - const double rate, - const unsigned int numChannels_, - const unsigned int bitsPerSample_) - : sampleRate (rate), - numChannels (numChannels_), - bitsPerSample (bitsPerSample_), - usesFloatingPointData (false), - output (out), - formatName (formatName_) -{ -} - -AudioFormatWriter::~AudioFormatWriter() -{ - delete output; -} - -static void convertFloatsToInts (int* dest, const float* src, int numSamples) noexcept -{ - while (--numSamples >= 0) - { - const double samp = *src++; - - if (samp <= -1.0) - *dest = std::numeric_limits::min(); - else if (samp >= 1.0) - *dest = std::numeric_limits::max(); - else - *dest = roundToInt (std::numeric_limits::max() * samp); - - ++dest; - } -} - -bool AudioFormatWriter::writeFromAudioReader (AudioFormatReader& reader, - int64 startSample, - int64 numSamplesToRead) -{ - const int bufferSize = 16384; - AudioSampleBuffer tempBuffer ((int) numChannels, bufferSize); - - int* buffers [128] = { 0 }; - - for (int i = tempBuffer.getNumChannels(); --i >= 0;) - buffers[i] = reinterpret_cast (tempBuffer.getWritePointer (i, 0)); - - if (numSamplesToRead < 0) - numSamplesToRead = reader.lengthInSamples; - - while (numSamplesToRead > 0) - { - const int numToDo = (int) jmin (numSamplesToRead, (int64) bufferSize); - - if (! reader.read (buffers, (int) numChannels, startSample, numToDo, false)) - return false; - - if (reader.usesFloatingPointData != isFloatingPoint()) - { - int** bufferChan = buffers; - - while (*bufferChan != nullptr) - { - void* const b = *bufferChan++; - - if (isFloatingPoint()) - FloatVectorOperations::convertFixedToFloat ((float*) b, (int*) b, 1.0f / 0x7fffffff, numToDo); - else - convertFloatsToInts ((int*) b, (float*) b, numToDo); - } - } - - if (! write (const_cast (buffers), numToDo)) - return false; - - numSamplesToRead -= numToDo; - startSample += numToDo; - } - - return true; -} - -bool AudioFormatWriter::writeFromAudioSource (AudioSource& source, int numSamplesToRead, const int samplesPerBlock) -{ - AudioSampleBuffer tempBuffer (getNumChannels(), samplesPerBlock); - - while (numSamplesToRead > 0) - { - const int numToDo = jmin (numSamplesToRead, samplesPerBlock); - - AudioSourceChannelInfo info (&tempBuffer, 0, numToDo); - info.clearActiveBufferRegion(); - - source.getNextAudioBlock (info); - - if (! writeFromAudioSampleBuffer (tempBuffer, 0, numToDo)) - return false; - - numSamplesToRead -= numToDo; - } - - return true; -} - -bool AudioFormatWriter::writeFromFloatArrays (const float* const* channels, int numSourceChannels, int numSamples) -{ - if (numSamples <= 0) - return true; - - if (isFloatingPoint()) - return write ((const int**) channels, numSamples); - - int* chans [256]; - int scratch [4096]; - - jassert (numSourceChannels < numElementsInArray (chans)); - const int maxSamples = (int) (numElementsInArray (scratch) / numSourceChannels); - - for (int i = 0; i < numSourceChannels; ++i) - chans[i] = scratch + (i * maxSamples); - - chans[numSourceChannels] = nullptr; - int startSample = 0; - - while (numSamples > 0) - { - const int numToDo = jmin (numSamples, maxSamples); - - for (int i = 0; i < numSourceChannels; ++i) - convertFloatsToInts (chans[i], channels[i] + startSample, numToDo); - - if (! write ((const int**) chans, numToDo)) - return false; - - startSample += numToDo; - numSamples -= numToDo; - } - - return true; -} - -bool AudioFormatWriter::writeFromAudioSampleBuffer (const AudioSampleBuffer& source, int startSample, int numSamples) -{ - const int numSourceChannels = source.getNumChannels(); - jassert (startSample >= 0 && startSample + numSamples <= source.getNumSamples() && numSourceChannels > 0); - - if (startSample == 0) - return writeFromFloatArrays (source.getArrayOfReadPointers(), numSourceChannels, numSamples); - - const float* chans [256]; - jassert ((int) numChannels < numElementsInArray (chans)); - - for (int i = 0; i < numSourceChannels; ++i) - chans[i] = source.getReadPointer (i, startSample); - - chans[numSourceChannels] = nullptr; - - return writeFromFloatArrays (chans, numSourceChannels, numSamples); -} - -bool AudioFormatWriter::flush() -{ - return false; -} - -//============================================================================== -class AudioFormatWriter::ThreadedWriter::Buffer : private TimeSliceClient -{ -public: - Buffer (TimeSliceThread& tst, AudioFormatWriter* w, int channels, int numSamples) - : fifo (numSamples), - buffer (channels, numSamples), - timeSliceThread (tst), - writer (w), - receiver (nullptr), - samplesWritten (0), - samplesPerFlush (0), - flushSampleCounter (0), - isRunning (true) - { - timeSliceThread.addTimeSliceClient (this); - } - - ~Buffer() - { - isRunning = false; - timeSliceThread.removeTimeSliceClient (this); - - while (writePendingData() == 0) - {} - } - - bool write (const float* const* data, int numSamples) - { - if (numSamples <= 0 || ! isRunning) - return true; - - jassert (timeSliceThread.isThreadRunning()); // you need to get your thread running before pumping data into this! - - int start1, size1, start2, size2; - fifo.prepareToWrite (numSamples, start1, size1, start2, size2); - - if (size1 + size2 < numSamples) - return false; - - for (int i = buffer.getNumChannels(); --i >= 0;) - { - buffer.copyFrom (i, start1, data[i], size1); - buffer.copyFrom (i, start2, data[i] + size1, size2); - } - - fifo.finishedWrite (size1 + size2); - timeSliceThread.notify(); - return true; - } - - int useTimeSlice() override - { - return writePendingData(); - } - - int writePendingData() - { - const int numToDo = fifo.getTotalSize() / 4; - - int start1, size1, start2, size2; - fifo.prepareToRead (numToDo, start1, size1, start2, size2); - - if (size1 <= 0) - return 10; - - writer->writeFromAudioSampleBuffer (buffer, start1, size1); - - const ScopedLock sl (thumbnailLock); - if (receiver != nullptr) - receiver->addBlock (samplesWritten, buffer, start1, size1); - - samplesWritten += size1; - - if (size2 > 0) - { - writer->writeFromAudioSampleBuffer (buffer, start2, size2); - - if (receiver != nullptr) - receiver->addBlock (samplesWritten, buffer, start2, size2); - - samplesWritten += size2; - } - - fifo.finishedRead (size1 + size2); - - if (samplesPerFlush > 0) - { - flushSampleCounter -= size1 + size2; - - if (flushSampleCounter <= 0) - { - flushSampleCounter = samplesPerFlush; - writer->flush(); - } - } - - return 0; - } - - void setDataReceiver (IncomingDataReceiver* newReceiver) - { - if (newReceiver != nullptr) - newReceiver->reset (buffer.getNumChannels(), writer->getSampleRate(), 0); - - const ScopedLock sl (thumbnailLock); - receiver = newReceiver; - samplesWritten = 0; - } - - void setFlushInterval (int numSamples) noexcept - { - samplesPerFlush = numSamples; - } - -private: - AbstractFifo fifo; - AudioSampleBuffer buffer; - TimeSliceThread& timeSliceThread; - ScopedPointer writer; - CriticalSection thumbnailLock; - IncomingDataReceiver* receiver; - int64 samplesWritten; - int samplesPerFlush, flushSampleCounter; - volatile bool isRunning; - - JUCE_DECLARE_NON_COPYABLE (Buffer) -}; - -AudioFormatWriter::ThreadedWriter::ThreadedWriter (AudioFormatWriter* writer, TimeSliceThread& backgroundThread, int numSamplesToBuffer) - : buffer (new AudioFormatWriter::ThreadedWriter::Buffer (backgroundThread, writer, (int) writer->numChannels, numSamplesToBuffer)) -{ -} - -AudioFormatWriter::ThreadedWriter::~ThreadedWriter() -{ -} - -bool AudioFormatWriter::ThreadedWriter::write (const float* const* data, int numSamples) -{ - return buffer->write (data, numSamples); -} - -void AudioFormatWriter::ThreadedWriter::setDataReceiver (AudioFormatWriter::ThreadedWriter::IncomingDataReceiver* receiver) -{ - buffer->setDataReceiver (receiver); -} - -void AudioFormatWriter::ThreadedWriter::setFlushInterval (int numSamplesPerFlush) noexcept -{ - buffer->setFlushInterval (numSamplesPerFlush); -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/format/juce_AudioFormatWriter.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/format/juce_AudioFormatWriter.h deleted file mode 100644 index 9098c75fb6..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/format/juce_AudioFormatWriter.h +++ /dev/null @@ -1,274 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_AUDIOFORMATWRITER_H_INCLUDED -#define JUCE_AUDIOFORMATWRITER_H_INCLUDED - - -//============================================================================== -/** - Writes samples to an audio file stream. - - A subclass that writes a specific type of audio format will be created by - an AudioFormat object. - - After creating one of these with the AudioFormat::createWriterFor() method - you can call its write() method to store the samples, and then delete it. - - @see AudioFormat, AudioFormatReader -*/ -class JUCE_API AudioFormatWriter -{ -protected: - //============================================================================== - /** Creates an AudioFormatWriter object. - - @param destStream the stream to write to - this will be deleted - by this object when it is no longer needed - @param formatName the description that will be returned by the getFormatName() - method - @param sampleRate the sample rate to use - the base class just stores - this value, it doesn't do anything with it - @param numberOfChannels the number of channels to write - the base class just stores - this value, it doesn't do anything with it - @param bitsPerSample the bit depth of the stream - the base class just stores - this value, it doesn't do anything with it - */ - AudioFormatWriter (OutputStream* destStream, - const String& formatName, - double sampleRate, - unsigned int numberOfChannels, - unsigned int bitsPerSample); - -public: - /** Destructor. */ - virtual ~AudioFormatWriter(); - - //============================================================================== - /** Returns a description of what type of format this is. - - E.g. "AIFF file" - */ - const String& getFormatName() const noexcept { return formatName; } - - //============================================================================== - /** Writes a set of samples to the audio stream. - - Note that if you're trying to write the contents of an AudioSampleBuffer, you - can use AudioSampleBuffer::writeToAudioWriter(). - - @param samplesToWrite an array of arrays containing the sample data for - each channel to write. This is a zero-terminated - array of arrays, and can contain a different number - of channels than the actual stream uses, and the - writer should do its best to cope with this. - If the format is fixed-point, each channel will be formatted - as an array of signed integers using the full 32-bit - range -0x80000000 to 0x7fffffff, regardless of the source's - bit-depth. If it is a floating-point format, you should treat - the arrays as arrays of floats, and just cast it to an (int**) - to pass it into the method. - @param numSamples the number of samples to write - */ - virtual bool write (const int** samplesToWrite, int numSamples) = 0; - - /** Some formats may support a flush operation that makes sure the file is in a - valid state before carrying on. - If supported, this means that by calling flush periodically when writing data - to a large file, then it should still be left in a readable state if your program - crashes. - It goes without saying that this method must be called from the same thread that's - calling write()! - If the format supports flushing and the operation succeeds, this returns true. - */ - virtual bool flush(); - - //============================================================================== - /** Reads a section of samples from an AudioFormatReader, and writes these to - the output. - - This will take care of any floating-point conversion that's required to convert - between the two formats. It won't deal with sample-rate conversion, though. - - If numSamplesToRead < 0, it will write the entire length of the reader. - - @returns false if it can't read or write properly during the operation - */ - bool writeFromAudioReader (AudioFormatReader& reader, - int64 startSample, - int64 numSamplesToRead); - - /** Reads some samples from an AudioSource, and writes these to the output. - - The source must already have been initialised with the AudioSource::prepareToPlay() method - - @param source the source to read from - @param numSamplesToRead total number of samples to read and write - @param samplesPerBlock the maximum number of samples to fetch from the source - @returns false if it can't read or write properly during the operation - */ - bool writeFromAudioSource (AudioSource& source, - int numSamplesToRead, - int samplesPerBlock = 2048); - - - /** Writes some samples from an AudioSampleBuffer. */ - bool writeFromAudioSampleBuffer (const AudioSampleBuffer& source, - int startSample, int numSamples); - - /** Writes some samples from a set of float data channels. */ - bool writeFromFloatArrays (const float* const* channels, int numChannels, int numSamples); - - //============================================================================== - /** Returns the sample rate being used. */ - double getSampleRate() const noexcept { return sampleRate; } - - /** Returns the number of channels being written. */ - int getNumChannels() const noexcept { return (int) numChannels; } - - /** Returns the bit-depth of the data being written. */ - int getBitsPerSample() const noexcept { return (int) bitsPerSample; } - - /** Returns true if it's a floating-point format, false if it's fixed-point. */ - bool isFloatingPoint() const noexcept { return usesFloatingPointData; } - - //============================================================================== - /** - Provides a FIFO for an AudioFormatWriter, allowing you to push incoming - data into a buffer which will be flushed to disk by a background thread. - */ - class ThreadedWriter - { - public: - /** Creates a ThreadedWriter for a given writer and a thread. - - The writer object which is passed in here will be owned and deleted by - the ThreadedWriter when it is no longer needed. - - To stop the writer and flush the buffer to disk, simply delete this object. - */ - ThreadedWriter (AudioFormatWriter* writer, - TimeSliceThread& backgroundThread, - int numSamplesToBuffer); - - /** Destructor. */ - ~ThreadedWriter(); - - /** Pushes some incoming audio data into the FIFO. - - If there's enough free space in the buffer, this will add the data to it, - - If the FIFO is too full to accept this many samples, the method will return - false - then you could either wait until the background thread has had time to - consume some of the buffered data and try again, or you can give up - and lost this block. - - The data must be an array containing the same number of channels as the - AudioFormatWriter object is using. None of these channels can be null. - */ - bool write (const float* const* data, int numSamples); - - class JUCE_API IncomingDataReceiver - { - public: - IncomingDataReceiver() {} - virtual ~IncomingDataReceiver() {} - - virtual void reset (int numChannels, double sampleRate, int64 totalSamplesInSource) = 0; - virtual void addBlock (int64 sampleNumberInSource, const AudioSampleBuffer& newData, - int startOffsetInBuffer, int numSamples) = 0; - }; - - /** Allows you to specify a callback that this writer should update with the - incoming data. - The receiver will be cleared and will the writer will begin adding data to - it as the data arrives. Pass a null pointer to remove the current receiver. - - The object passed-in must not be deleted while this writer is still using it. - */ - void setDataReceiver (IncomingDataReceiver*); - - /** Sets how many samples should be written before calling the AudioFormatWriter::flush method. - Set this to 0 to disable flushing (this is the default). - */ - void setFlushInterval (int numSamplesPerFlush) noexcept; - - private: - class Buffer; - friend struct ContainerDeletePolicy; - ScopedPointer buffer; - }; - -protected: - //============================================================================== - /** The sample rate of the stream. */ - double sampleRate; - - /** The number of channels being written to the stream. */ - unsigned int numChannels; - - /** The bit depth of the file. */ - unsigned int bitsPerSample; - - /** True if it's a floating-point format, false if it's fixed-point. */ - bool usesFloatingPointData; - - /** The output stream for use by subclasses. */ - OutputStream* output; - - /** Used by AudioFormatWriter subclasses to copy data to different formats. */ - template - struct WriteHelper - { - typedef AudioData::Pointer DestType; - typedef AudioData::Pointer SourceType; - - static void write (void* destData, int numDestChannels, const int* const* source, - int numSamples, const int sourceOffset = 0) noexcept - { - for (int i = 0; i < numDestChannels; ++i) - { - const DestType dest (addBytesToPointer (destData, i * DestType::getBytesPerSample()), numDestChannels); - - if (*source != nullptr) - { - dest.convertSamples (SourceType (*source + sourceOffset), numSamples); - ++source; - } - else - { - dest.clearSamples (numSamples); - } - } - } - }; - -private: - String formatName; - friend class ThreadedWriter; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioFormatWriter) -}; - -#endif // JUCE_AUDIOFORMATWRITER_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/format/juce_AudioSubsectionReader.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/format/juce_AudioSubsectionReader.cpp deleted file mode 100644 index bbe1ebd79b..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/format/juce_AudioSubsectionReader.cpp +++ /dev/null @@ -1,73 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -AudioSubsectionReader::AudioSubsectionReader (AudioFormatReader* const source_, - const int64 startSample_, - const int64 length_, - const bool deleteSourceWhenDeleted_) - : AudioFormatReader (0, source_->getFormatName()), - source (source_), - startSample (startSample_), - deleteSourceWhenDeleted (deleteSourceWhenDeleted_) -{ - length = jmin (jmax ((int64) 0, source->lengthInSamples - startSample), length_); - - sampleRate = source->sampleRate; - bitsPerSample = source->bitsPerSample; - lengthInSamples = length; - numChannels = source->numChannels; - usesFloatingPointData = source->usesFloatingPointData; -} - -AudioSubsectionReader::~AudioSubsectionReader() -{ - if (deleteSourceWhenDeleted) - delete source; -} - -//============================================================================== -bool AudioSubsectionReader::readSamples (int** destSamples, int numDestChannels, int startOffsetInDestBuffer, - int64 startSampleInFile, int numSamples) -{ - clearSamplesBeyondAvailableLength (destSamples, numDestChannels, startOffsetInDestBuffer, - startSampleInFile, numSamples, length); - - return source->readSamples (destSamples, numDestChannels, startOffsetInDestBuffer, - startSampleInFile + startSample, numSamples); -} - -void AudioSubsectionReader::readMaxLevels (int64 startSampleInFile, - int64 numSamples, - float& lowestLeft, - float& highestLeft, - float& lowestRight, - float& highestRight) -{ - startSampleInFile = jmax ((int64) 0, startSampleInFile); - numSamples = jmax ((int64) 0, jmin (numSamples, length - startSampleInFile)); - - source->readMaxLevels (startSampleInFile + startSample, numSamples, - lowestLeft, highestLeft, - lowestRight, highestRight); -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/format/juce_AudioSubsectionReader.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/format/juce_AudioSubsectionReader.h deleted file mode 100644 index fb9e6a031a..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/format/juce_AudioSubsectionReader.h +++ /dev/null @@ -1,84 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_AUDIOSUBSECTIONREADER_H_INCLUDED -#define JUCE_AUDIOSUBSECTIONREADER_H_INCLUDED - - -//============================================================================== -/** - This class is used to wrap an AudioFormatReader and only read from a - subsection of the file. - - So if you have a reader which can read a 1000 sample file, you could wrap it - in one of these to only access, e.g. samples 100 to 200, and any samples - outside that will come back as 0. Accessing sample 0 from this reader will - actually read the first sample from the other's subsection, which might - be at a non-zero position. - - @see AudioFormatReader -*/ -class JUCE_API AudioSubsectionReader : public AudioFormatReader -{ -public: - //============================================================================== - /** Creates an AudioSubsectionReader for a given data source. - - @param sourceReader the source reader from which we'll be taking data - @param subsectionStartSample the sample within the source reader which will be - mapped onto sample 0 for this reader. - @param subsectionLength the number of samples from the source that will - make up the subsection. If this reader is asked for - any samples beyond this region, it will return zero. - @param deleteSourceWhenDeleted if true, the sourceReader object will be deleted when - this object is deleted. - */ - AudioSubsectionReader (AudioFormatReader* sourceReader, - int64 subsectionStartSample, - int64 subsectionLength, - bool deleteSourceWhenDeleted); - - /** Destructor. */ - ~AudioSubsectionReader(); - - - //============================================================================== - bool readSamples (int** destSamples, int numDestChannels, int startOffsetInDestBuffer, - int64 startSampleInFile, int numSamples) override; - - void readMaxLevels (int64 startSample, int64 numSamples, - float& lowestLeft, float& highestLeft, - float& lowestRight, float& highestRight) override; - - -private: - //============================================================================== - AudioFormatReader* const source; - int64 startSample, length; - const bool deleteSourceWhenDeleted; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioSubsectionReader) -}; - -#endif // JUCE_AUDIOSUBSECTIONREADER_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/format/juce_BufferingAudioFormatReader.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/format/juce_BufferingAudioFormatReader.cpp deleted file mode 100644 index ecfe1d457a..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/format/juce_BufferingAudioFormatReader.cpp +++ /dev/null @@ -1,172 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -BufferingAudioReader::BufferingAudioReader (AudioFormatReader* sourceReader, - TimeSliceThread& timeSliceThread, - int samplesToBuffer) - : AudioFormatReader (nullptr, sourceReader->getFormatName()), - source (sourceReader), thread (timeSliceThread), - nextReadPosition (0), - numBlocks (1 + (samplesToBuffer / samplesPerBlock)) -{ - sampleRate = source->sampleRate; - lengthInSamples = source->lengthInSamples; - numChannels = source->numChannels; - metadataValues = source->metadataValues; - bitsPerSample = 32; - usesFloatingPointData = true; - - for (int i = 3; --i >= 0;) - readNextBufferChunk(); - - timeSliceThread.addTimeSliceClient (this); -} - -BufferingAudioReader::~BufferingAudioReader() -{ - thread.removeTimeSliceClient (this); -} - -void BufferingAudioReader::setReadTimeout (int timeoutMilliseconds) noexcept -{ - timeoutMs = timeoutMilliseconds; -} - -bool BufferingAudioReader::readSamples (int** destSamples, int numDestChannels, int startOffsetInDestBuffer, - int64 startSampleInFile, int numSamples) -{ - const uint32 startTime = Time::getMillisecondCounter(); - clearSamplesBeyondAvailableLength (destSamples, numDestChannels, startOffsetInDestBuffer, - startSampleInFile, numSamples, lengthInSamples); - - const ScopedLock sl (lock); - nextReadPosition = startSampleInFile; - - while (numSamples > 0) - { - if (const BufferedBlock* const block = getBlockContaining (startSampleInFile)) - { - const int offset = (int) (startSampleInFile - block->range.getStart()); - const int numToDo = jmin (numSamples, (int) (block->range.getEnd() - startSampleInFile)); - - for (int j = 0; j < numDestChannels; ++j) - { - if (float* dest = (float*) destSamples[j]) - { - dest += startOffsetInDestBuffer; - - if (j < (int) numChannels) - FloatVectorOperations::copy (dest, block->buffer.getReadPointer (j, offset), numToDo); - else - FloatVectorOperations::clear (dest, numToDo); - } - } - - startOffsetInDestBuffer += numToDo; - startSampleInFile += numToDo; - numSamples -= numToDo; - } - else - { - if (timeoutMs >= 0 && Time::getMillisecondCounter() >= startTime + (uint32) timeoutMs) - { - for (int j = 0; j < numDestChannels; ++j) - if (float* dest = (float*) destSamples[j]) - FloatVectorOperations::clear (dest + startOffsetInDestBuffer, numSamples); - - break; - } - else - { - ScopedUnlock ul (lock); - Thread::yield(); - } - } - } - - return true; -} - -BufferingAudioReader::BufferedBlock::BufferedBlock (AudioFormatReader& reader, int64 pos, int numSamples) - : range (pos, pos + numSamples), - buffer ((int) reader.numChannels, numSamples) -{ - reader.read (&buffer, 0, numSamples, pos, true, true); -} - -BufferingAudioReader::BufferedBlock* BufferingAudioReader::getBlockContaining (int64 pos) const noexcept -{ - for (int i = blocks.size(); --i >= 0;) - { - BufferedBlock* const b = blocks.getUnchecked(i); - - if (b->range.contains (pos)) - return b; - } - - return nullptr; -} - -int BufferingAudioReader::useTimeSlice() -{ - return readNextBufferChunk() ? 1 : 100; -} - -bool BufferingAudioReader::readNextBufferChunk() -{ - const int64 pos = nextReadPosition; - const int64 startPos = ((pos - 1024) / samplesPerBlock) * samplesPerBlock; - const int64 endPos = startPos + numBlocks * samplesPerBlock; - - OwnedArray newBlocks; - - for (int i = blocks.size(); --i >= 0;) - if (blocks.getUnchecked(i)->range.intersects (Range (startPos, endPos))) - newBlocks.add (blocks.getUnchecked(i)); - - if (newBlocks.size() == numBlocks) - { - newBlocks.clear (false); - return false; - } - - for (int64 p = startPos; p < endPos; p += samplesPerBlock) - { - if (getBlockContaining (p) == nullptr) - { - newBlocks.add (new BufferedBlock (*source, p, samplesPerBlock)); - break; // just do one block - } - } - - { - const ScopedLock sl (lock); - newBlocks.swapWith (blocks); - } - - for (int i = blocks.size(); --i >= 0;) - newBlocks.removeObject (blocks.getUnchecked(i), false); - - return true; -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/format/juce_BufferingAudioFormatReader.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/format/juce_BufferingAudioFormatReader.h deleted file mode 100644 index 8f950be63f..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/format/juce_BufferingAudioFormatReader.h +++ /dev/null @@ -1,93 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_BUFFERINGAUDIOFORMATREADER_H_INCLUDED -#define JUCE_BUFFERINGAUDIOFORMATREADER_H_INCLUDED - -//============================================================================== -/** - An AudioFormatReader that uses a background thread to pre-read data from - another reader. - - @see AudioFormatReader -*/ -class JUCE_API BufferingAudioReader : public AudioFormatReader, - private TimeSliceClient -{ -public: - /** Creates a reader. - - @param sourceReader the source reader to wrap. This BufferingAudioReader - takes ownership of this object and will delete it later - when no longer needed - @param timeSliceThread the thread that should be used to do the background reading. - Make sure that the thread you supply is running, and won't - be deleted while the reader object still exists. - @param samplesToBuffer the total number of samples to buffer ahead. - */ - BufferingAudioReader (AudioFormatReader* sourceReader, - TimeSliceThread& timeSliceThread, - int samplesToBuffer); - - ~BufferingAudioReader(); - - /** Sets a number of milliseconds that the reader can block for in its readSamples() - method before giving up and returning silence. - A value of less that 0 means "wait forever". - The default timeout is 0. - */ - void setReadTimeout (int timeoutMilliseconds) noexcept; - - bool readSamples (int** destSamples, int numDestChannels, int startOffsetInDestBuffer, - int64 startSampleInFile, int numSamples) override; - -private: - ScopedPointer source; - TimeSliceThread& thread; - int64 nextReadPosition; - const int numBlocks; - int timeoutMs; - - enum { samplesPerBlock = 32768 }; - - struct BufferedBlock - { - BufferedBlock (AudioFormatReader& reader, int64 pos, int numSamples); - - Range range; - AudioSampleBuffer buffer; - }; - - CriticalSection lock; - OwnedArray blocks; - - BufferedBlock* getBlockContaining (int64 pos) const noexcept; - int useTimeSlice() override; - bool readNextBufferChunk(); - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (BufferingAudioReader) -}; - - -#endif // JUCE_BUFFERINGAUDIOFORMATREADER_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/format/juce_MemoryMappedAudioFormatReader.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/format/juce_MemoryMappedAudioFormatReader.h deleted file mode 100644 index 2ec6388be2..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/format/juce_MemoryMappedAudioFormatReader.h +++ /dev/null @@ -1,106 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_MEMORYMAPPEDAUDIOFORMATREADER_H_INCLUDED -#define JUCE_MEMORYMAPPEDAUDIOFORMATREADER_H_INCLUDED - - -//============================================================================== -/** - A specialised type of AudioFormatReader that uses a MemoryMappedFile to read - directly from an audio file. - - This allows for incredibly fast random-access to sample data in the mapped - region of the file, but not all audio formats support it - see - AudioFormat::createMemoryMappedReader(). - - Note that before reading samples from a MemoryMappedAudioFormatReader, you must first - call mapEntireFile() or mapSectionOfFile() to ensure that the region you want to - read has been mapped. - - @see AudioFormat::createMemoryMappedReader, AudioFormatReader -*/ -class JUCE_API MemoryMappedAudioFormatReader : public AudioFormatReader -{ -protected: - //============================================================================== - /** Creates an MemoryMappedAudioFormatReader object. - - Note that before attempting to read any data, you must call mapEntireFile() - or mapSectionOfFile() to ensure that the region you want to read has - been mapped. - */ - MemoryMappedAudioFormatReader (const File& file, const AudioFormatReader& details, - int64 dataChunkStart, int64 dataChunkLength, int bytesPerFrame); - -public: - /** Returns the file that is being mapped */ - const File& getFile() const noexcept { return file; } - - /** Attempts to map the entire file into memory. */ - bool mapEntireFile(); - - /** Attempts to map a section of the file into memory. */ - bool mapSectionOfFile (Range samplesToMap); - - /** Returns the sample range that's currently memory-mapped and available for reading. */ - Range getMappedSection() const noexcept { return mappedSection; } - - /** Touches the memory for the given sample, to force it to be loaded into active memory. */ - void touchSample (int64 sample) const noexcept; - - /** Returns the number of bytes currently being mapped */ - size_t getNumBytesUsed() const { return map != nullptr ? map->getSize() : 0; } - -protected: - File file; - Range mappedSection; - ScopedPointer map; - int64 dataChunkStart, dataLength; - int bytesPerFrame; - - /** Converts a sample index to a byte position in the file. */ - inline int64 sampleToFilePos (int64 sample) const noexcept { return dataChunkStart + sample * bytesPerFrame; } - - /** Converts a byte position in the file to a sample index. */ - inline int64 filePosToSample (int64 filePos) const noexcept { return (filePos - dataChunkStart) / bytesPerFrame; } - - /** Converts a sample index to a pointer to the mapped file memory. */ - inline const void* sampleToPointer (int64 sample) const noexcept { return addBytesToPointer (map->getData(), sampleToFilePos (sample) - map->getRange().getStart()); } - - /** Used by AudioFormatReader subclasses to scan for min/max ranges in interleaved data. */ - template - void scanMinAndMaxInterleaved (int channel, int64 startSampleInFile, int64 numSamples, float& mn, float& mx) const noexcept - { - typedef AudioData::Pointer SourceType; - - SourceType (addBytesToPointer (sampleToPointer (startSampleInFile), ((int) bitsPerSample / 8) * channel), (int) numChannels) - .findMinAndMax ((size_t) numSamples, mn, mx); - } - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MemoryMappedAudioFormatReader) -}; - - -#endif // JUCE_MEMORYMAPPEDAUDIOFORMATREADER_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/juce_audio_formats.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/juce_audio_formats.cpp deleted file mode 100644 index b68042ff6e..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/juce_audio_formats.cpp +++ /dev/null @@ -1,121 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#if defined (JUCE_AUDIO_FORMATS_H_INCLUDED) && ! JUCE_AMALGAMATED_INCLUDE - /* When you add this cpp file to your project, you mustn't include it in a file where you've - already included any other headers - just put it inside a file on its own, possibly with your config - flags preceding it, but don't include anything else. That also includes avoiding any automatic prefix - header files that the compiler may be using. - */ - #error "Incorrect use of JUCE cpp file" -#endif - -// Your project must contain an AppConfig.h file with your project-specific settings in it, -// and your header search path must make it accessible to the module's files. -#include "AppConfig.h" - -#include "../juce_core/native/juce_BasicNativeHeaders.h" -#include "juce_audio_formats.h" - -//============================================================================== -#if JUCE_MAC - #define Point CarbonDummyPointName - #define Component CarbonDummyCompName - #if JUCE_QUICKTIME - #import - #endif - #include - #undef Component - #undef Point - -#elif JUCE_IOS - #import - #import - -//============================================================================== -#elif JUCE_WINDOWS - #if JUCE_QUICKTIME - /* If you've got an include error here, you probably need to install the QuickTime SDK and - add its header directory to your include path. - - Alternatively, if you don't need any QuickTime services, just set the JUCE_QUICKTIME flag to 0. - */ - #include - #include - #include - #include - #include - - /* If you've got QuickTime 7 installed, then these COM objects should be found in - the "\Program Files\Quicktime" directory. You'll need to add this directory to - your include search path to make these import statements work. - */ - #import - #import - - #if JUCE_MSVC && ! JUCE_DONT_AUTOLINK_TO_WIN32_LIBRARIES - #pragma comment (lib, "QTMLClient.lib") - #endif - #endif - - #if JUCE_USE_WINDOWS_MEDIA_FORMAT - #include - #endif -#endif - -//============================================================================== -namespace juce -{ - -#if JUCE_ANDROID - #include "../juce_core/native/juce_android_JNIHelpers.h" - #undef JUCE_QUICKTIME -#endif - -#if JUCE_WINDOWS - #include "../juce_core/native/juce_win32_ComSmartPtr.h" -#endif - -#include "format/juce_AudioFormat.cpp" -#include "format/juce_AudioFormatManager.cpp" -#include "format/juce_AudioFormatReader.cpp" -#include "format/juce_AudioFormatReaderSource.cpp" -#include "format/juce_AudioFormatWriter.cpp" -#include "format/juce_AudioSubsectionReader.cpp" -#include "format/juce_BufferingAudioFormatReader.cpp" -#include "sampler/juce_Sampler.cpp" -#include "codecs/juce_AiffAudioFormat.cpp" -#include "codecs/juce_CoreAudioFormat.cpp" -#include "codecs/juce_FlacAudioFormat.cpp" -#include "codecs/juce_MP3AudioFormat.cpp" -#include "codecs/juce_OggVorbisAudioFormat.cpp" -#include "codecs/juce_QuickTimeAudioFormat.cpp" -#include "codecs/juce_WavAudioFormat.cpp" -#include "codecs/juce_LAMEEncoderAudioFormat.cpp" - -#if JUCE_WINDOWS && JUCE_USE_WINDOWS_MEDIA_FORMAT - #include "codecs/juce_WindowsMediaAudioFormat.cpp" -#endif - -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/juce_audio_formats.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/juce_audio_formats.h index c15194e464..4307ccc794 100644 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/juce_audio_formats.h +++ b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/juce_audio_formats.h @@ -1,110 +1,5 @@ -/* - ============================================================================== +// This is an auto-generated file to redirect any included +// module headers to the correct external folder. - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. +#include "../../../../../modules/juce_audio_formats/juce_audio_formats.h" - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_AUDIO_FORMATS_H_INCLUDED -#define JUCE_AUDIO_FORMATS_H_INCLUDED - -#include "../juce_audio_basics/juce_audio_basics.h" - -//============================================================================= -/** Config: JUCE_USE_FLAC - Enables the FLAC audio codec classes (available on all platforms). - If your app doesn't need to read FLAC files, you might want to disable this to - reduce the size of your codebase and build time. -*/ -#ifndef JUCE_USE_FLAC - #define JUCE_USE_FLAC 1 -#endif - -/** Config: JUCE_USE_OGGVORBIS - Enables the Ogg-Vorbis audio codec classes (available on all platforms). - If your app doesn't need to read Ogg-Vorbis files, you might want to disable this to - reduce the size of your codebase and build time. -*/ -#ifndef JUCE_USE_OGGVORBIS - #define JUCE_USE_OGGVORBIS 1 -#endif - -/** Config: JUCE_USE_MP3AUDIOFORMAT - Enables the software-based MP3AudioFormat class. - IMPORTANT DISCLAIMER: By choosing to enable the JUCE_USE_MP3AUDIOFORMAT flag and to compile - this MP3 code into your software, you do so AT YOUR OWN RISK! By doing so, you are agreeing - that Raw Material Software is in no way responsible for any patent, copyright, or other - legal issues that you may suffer as a result. - - The code in juce_MP3AudioFormat.cpp is NOT guaranteed to be free from infringements of 3rd-party - intellectual property. If you wish to use it, please seek your own independent advice about the - legality of doing so. If you are not willing to accept full responsibility for the consequences - of using this code, then do not enable this setting. -*/ -#ifndef JUCE_USE_MP3AUDIOFORMAT - #define JUCE_USE_MP3AUDIOFORMAT 0 -#endif - -/** Config: JUCE_USE_LAME_AUDIO_FORMAT - Enables the LameEncoderAudioFormat class. -*/ -#ifndef JUCE_USE_LAME_AUDIO_FORMAT - #define JUCE_USE_LAME_AUDIO_FORMAT 0 -#endif - -/** Config: JUCE_USE_WINDOWS_MEDIA_FORMAT - Enables the Windows Media SDK codecs. -*/ -#ifndef JUCE_USE_WINDOWS_MEDIA_FORMAT - #define JUCE_USE_WINDOWS_MEDIA_FORMAT 1 -#endif - -#if ! JUCE_MSVC - #undef JUCE_USE_WINDOWS_MEDIA_FORMAT - #define JUCE_USE_WINDOWS_MEDIA_FORMAT 0 -#endif - -//============================================================================= -namespace juce -{ - -class AudioFormat; -#include "format/juce_AudioFormatReader.h" -#include "format/juce_AudioFormatWriter.h" -#include "format/juce_MemoryMappedAudioFormatReader.h" -#include "format/juce_AudioFormat.h" -#include "format/juce_AudioFormatManager.h" -#include "format/juce_AudioFormatReaderSource.h" -#include "format/juce_AudioSubsectionReader.h" -#include "format/juce_BufferingAudioFormatReader.h" -#include "codecs/juce_AiffAudioFormat.h" -#include "codecs/juce_CoreAudioFormat.h" -#include "codecs/juce_FlacAudioFormat.h" -#include "codecs/juce_LAMEEncoderAudioFormat.h" -#include "codecs/juce_MP3AudioFormat.h" -#include "codecs/juce_OggVorbisAudioFormat.h" -#include "codecs/juce_QuickTimeAudioFormat.h" -#include "codecs/juce_WavAudioFormat.h" -#include "codecs/juce_WindowsMediaAudioFormat.h" -#include "sampler/juce_Sampler.h" - -} - -#endif // JUCE_AUDIO_FORMATS_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/juce_audio_formats.mm b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/juce_audio_formats.mm deleted file mode 100644 index 9b32ae5af7..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/juce_audio_formats.mm +++ /dev/null @@ -1,25 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#include "juce_audio_formats.cpp" diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/juce_module_info b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/juce_module_info deleted file mode 100644 index e355719763..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/juce_module_info +++ /dev/null @@ -1,22 +0,0 @@ -{ - "id": "juce_audio_formats", - "name": "JUCE audio file format codecs", - "version": "3.0.8", - "description": "Classes for reading and writing various audio file formats.", - "website": "http://www.juce.com/juce", - "license": "GPL/Commercial", - - "dependencies": [ { "id": "juce_audio_basics", "version": "matching" } ], - - "include": "juce_audio_formats.h", - - "compile": [ { "file": "juce_audio_formats.cpp", "target": "! xcode" }, - { "file": "juce_audio_formats.mm", "target": "xcode" } ], - - "browse": [ "format/*", - "codecs/*", - "sampler/*" ], - - "OSXFrameworks": "CoreAudio CoreMIDI QuartzCore AudioToolbox", - "iOSFrameworks": "AudioToolbox QuartzCore" -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/sampler/juce_Sampler.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/sampler/juce_Sampler.cpp deleted file mode 100644 index 4e7583e0a6..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/sampler/juce_Sampler.cpp +++ /dev/null @@ -1,224 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -SamplerSound::SamplerSound (const String& soundName, - AudioFormatReader& source, - const BigInteger& notes, - const int midiNoteForNormalPitch, - const double attackTimeSecs, - const double releaseTimeSecs, - const double maxSampleLengthSeconds) - : name (soundName), - midiNotes (notes), - midiRootNote (midiNoteForNormalPitch) -{ - sourceSampleRate = source.sampleRate; - - if (sourceSampleRate <= 0 || source.lengthInSamples <= 0) - { - length = 0; - attackSamples = 0; - releaseSamples = 0; - } - else - { - length = jmin ((int) source.lengthInSamples, - (int) (maxSampleLengthSeconds * sourceSampleRate)); - - data = new AudioSampleBuffer (jmin (2, (int) source.numChannels), length + 4); - - source.read (data, 0, length + 4, 0, true, true); - - attackSamples = roundToInt (attackTimeSecs * sourceSampleRate); - releaseSamples = roundToInt (releaseTimeSecs * sourceSampleRate); - } -} - -SamplerSound::~SamplerSound() -{ -} - -bool SamplerSound::appliesToNote (int midiNoteNumber) -{ - return midiNotes [midiNoteNumber]; -} - -bool SamplerSound::appliesToChannel (int /*midiChannel*/) -{ - return true; -} - -//============================================================================== -SamplerVoice::SamplerVoice() - : pitchRatio (0.0), - sourceSamplePosition (0.0), - lgain (0.0f), rgain (0.0f), - attackReleaseLevel (0), attackDelta (0), releaseDelta (0), - isInAttack (false), isInRelease (false) -{ -} - -SamplerVoice::~SamplerVoice() -{ -} - -bool SamplerVoice::canPlaySound (SynthesiserSound* sound) -{ - return dynamic_cast (sound) != nullptr; -} - -void SamplerVoice::startNote (const int midiNoteNumber, - const float velocity, - SynthesiserSound* s, - const int /*currentPitchWheelPosition*/) -{ - if (const SamplerSound* const sound = dynamic_cast (s)) - { - pitchRatio = pow (2.0, (midiNoteNumber - sound->midiRootNote) / 12.0) - * sound->sourceSampleRate / getSampleRate(); - - sourceSamplePosition = 0.0; - lgain = velocity; - rgain = velocity; - - isInAttack = (sound->attackSamples > 0); - isInRelease = false; - - if (isInAttack) - { - attackReleaseLevel = 0.0f; - attackDelta = (float) (pitchRatio / sound->attackSamples); - } - else - { - attackReleaseLevel = 1.0f; - attackDelta = 0.0f; - } - - if (sound->releaseSamples > 0) - releaseDelta = (float) (-pitchRatio / sound->releaseSamples); - else - releaseDelta = 0.0f; - } - else - { - jassertfalse; // this object can only play SamplerSounds! - } -} - -void SamplerVoice::stopNote (float /*velocity*/, bool allowTailOff) -{ - if (allowTailOff) - { - isInAttack = false; - isInRelease = true; - } - else - { - clearCurrentNote(); - } -} - -void SamplerVoice::pitchWheelMoved (const int /*newValue*/) -{ -} - -void SamplerVoice::controllerMoved (const int /*controllerNumber*/, - const int /*newValue*/) -{ -} - -//============================================================================== -void SamplerVoice::renderNextBlock (AudioSampleBuffer& outputBuffer, int startSample, int numSamples) -{ - if (const SamplerSound* const playingSound = static_cast (getCurrentlyPlayingSound().get())) - { - const float* const inL = playingSound->data->getReadPointer (0); - const float* const inR = playingSound->data->getNumChannels() > 1 - ? playingSound->data->getReadPointer (1) : nullptr; - - float* outL = outputBuffer.getWritePointer (0, startSample); - float* outR = outputBuffer.getNumChannels() > 1 ? outputBuffer.getWritePointer (1, startSample) : nullptr; - - while (--numSamples >= 0) - { - const int pos = (int) sourceSamplePosition; - const float alpha = (float) (sourceSamplePosition - pos); - const float invAlpha = 1.0f - alpha; - - // just using a very simple linear interpolation here.. - float l = (inL [pos] * invAlpha + inL [pos + 1] * alpha); - float r = (inR != nullptr) ? (inR [pos] * invAlpha + inR [pos + 1] * alpha) - : l; - - l *= lgain; - r *= rgain; - - if (isInAttack) - { - l *= attackReleaseLevel; - r *= attackReleaseLevel; - - attackReleaseLevel += attackDelta; - - if (attackReleaseLevel >= 1.0f) - { - attackReleaseLevel = 1.0f; - isInAttack = false; - } - } - else if (isInRelease) - { - l *= attackReleaseLevel; - r *= attackReleaseLevel; - - attackReleaseLevel += releaseDelta; - - if (attackReleaseLevel <= 0.0f) - { - stopNote (0.0f, false); - break; - } - } - - if (outR != nullptr) - { - *outL++ += l; - *outR++ += r; - } - else - { - *outL++ += (l + r) * 0.5f; - } - - sourceSamplePosition += pitchRatio; - - if (sourceSamplePosition > playingSound->length) - { - stopNote (0.0f, false); - break; - } - } - } -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/sampler/juce_Sampler.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/sampler/juce_Sampler.h deleted file mode 100644 index f801bf2329..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_formats/sampler/juce_Sampler.h +++ /dev/null @@ -1,146 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_SAMPLER_H_INCLUDED -#define JUCE_SAMPLER_H_INCLUDED - - -//============================================================================== -/** - A subclass of SynthesiserSound that represents a sampled audio clip. - - This is a pretty basic sampler, and just attempts to load the whole audio stream - into memory. - - To use it, create a Synthesiser, add some SamplerVoice objects to it, then - give it some SampledSound objects to play. - - @see SamplerVoice, Synthesiser, SynthesiserSound -*/ -class JUCE_API SamplerSound : public SynthesiserSound -{ -public: - //============================================================================== - /** Creates a sampled sound from an audio reader. - - This will attempt to load the audio from the source into memory and store - it in this object. - - @param name a name for the sample - @param source the audio to load. This object can be safely deleted by the - caller after this constructor returns - @param midiNotes the set of midi keys that this sound should be played on. This - is used by the SynthesiserSound::appliesToNote() method - @param midiNoteForNormalPitch the midi note at which the sample should be played - with its natural rate. All other notes will be pitched - up or down relative to this one - @param attackTimeSecs the attack (fade-in) time, in seconds - @param releaseTimeSecs the decay (fade-out) time, in seconds - @param maxSampleLengthSeconds a maximum length of audio to read from the audio - source, in seconds - */ - SamplerSound (const String& name, - AudioFormatReader& source, - const BigInteger& midiNotes, - int midiNoteForNormalPitch, - double attackTimeSecs, - double releaseTimeSecs, - double maxSampleLengthSeconds); - - /** Destructor. */ - ~SamplerSound(); - - //============================================================================== - /** Returns the sample's name */ - const String& getName() const noexcept { return name; } - - /** Returns the audio sample data. - This could return nullptr if there was a problem loading the data. - */ - AudioSampleBuffer* getAudioData() const noexcept { return data; } - - - //============================================================================== - bool appliesToNote (int midiNoteNumber) override; - bool appliesToChannel (int midiChannel) override; - - -private: - //============================================================================== - friend class SamplerVoice; - - String name; - ScopedPointer data; - double sourceSampleRate; - BigInteger midiNotes; - int length, attackSamples, releaseSamples; - int midiRootNote; - - JUCE_LEAK_DETECTOR (SamplerSound) -}; - - -//============================================================================== -/** - A subclass of SynthesiserVoice that can play a SamplerSound. - - To use it, create a Synthesiser, add some SamplerVoice objects to it, then - give it some SampledSound objects to play. - - @see SamplerSound, Synthesiser, SynthesiserVoice -*/ -class JUCE_API SamplerVoice : public SynthesiserVoice -{ -public: - //============================================================================== - /** Creates a SamplerVoice. */ - SamplerVoice(); - - /** Destructor. */ - ~SamplerVoice(); - - //============================================================================== - bool canPlaySound (SynthesiserSound*) override; - - void startNote (int midiNoteNumber, float velocity, SynthesiserSound*, int pitchWheel) override; - void stopNote (float velocity, bool allowTailOff) override; - - void pitchWheelMoved (int newValue); - void controllerMoved (int controllerNumber, int newValue) override; - - void renderNextBlock (AudioSampleBuffer&, int startSample, int numSamples) override; - - -private: - //============================================================================== - double pitchRatio; - double sourceSamplePosition; - float lgain, rgain, attackReleaseLevel, attackDelta, releaseDelta; - bool isInAttack, isInRelease; - - JUCE_LEAK_DETECTOR (SamplerVoice) -}; - - -#endif // JUCE_SAMPLER_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/format/juce_AudioPluginFormat.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/format/juce_AudioPluginFormat.cpp deleted file mode 100644 index cbd25424a4..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/format/juce_AudioPluginFormat.cpp +++ /dev/null @@ -1,26 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -AudioPluginFormat::AudioPluginFormat() noexcept {} -AudioPluginFormat::~AudioPluginFormat() {} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/format/juce_AudioPluginFormat.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/format/juce_AudioPluginFormat.h deleted file mode 100644 index d0af2013ce..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/format/juce_AudioPluginFormat.h +++ /dev/null @@ -1,112 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_AUDIOPLUGINFORMAT_H_INCLUDED -#define JUCE_AUDIOPLUGINFORMAT_H_INCLUDED - - -//============================================================================== -/** - The base class for a type of plugin format, such as VST, AudioUnit, LADSPA, etc. - - @see AudioFormatManager -*/ -class JUCE_API AudioPluginFormat -{ -public: - //============================================================================== - /** Destructor. */ - virtual ~AudioPluginFormat(); - - //============================================================================== - /** Returns the format name. - E.g. "VST", "AudioUnit", etc. - */ - virtual String getName() const = 0; - - /** This tries to create descriptions for all the plugin types available in - a binary module file. - - The file will be some kind of DLL or bundle. - - Normally there will only be one type returned, but some plugins - (e.g. VST shells) can use a single DLL to create a set of different plugin - subtypes, so in that case, each subtype is returned as a separate object. - */ - virtual void findAllTypesForFile (OwnedArray& results, - const String& fileOrIdentifier) = 0; - - /** Tries to recreate a type from a previously generated PluginDescription. - @see PluginDescription::createInstance - */ - virtual AudioPluginInstance* createInstanceFromDescription (const PluginDescription& desc, - double initialSampleRate, - int initialBufferSize) = 0; - - /** Should do a quick check to see if this file or directory might be a plugin of - this format. - - This is for searching for potential files, so it shouldn't actually try to - load the plugin or do anything time-consuming. - */ - virtual bool fileMightContainThisPluginType (const String& fileOrIdentifier) = 0; - - /** Returns a readable version of the name of the plugin that this identifier refers to. */ - virtual String getNameOfPluginFromIdentifier (const String& fileOrIdentifier) = 0; - - /** Returns true if this plugin's version or date has changed and it should be re-checked. */ - virtual bool pluginNeedsRescanning (const PluginDescription&) = 0; - - /** Checks whether this plugin could possibly be loaded. - It doesn't actually need to load it, just to check whether the file or component - still exists. - */ - virtual bool doesPluginStillExist (const PluginDescription& desc) = 0; - - /** Returns true if this format needs to run a scan to find its list of plugins. */ - virtual bool canScanForPlugins() const = 0; - - /** Searches a suggested set of directories for any plugins in this format. - The path might be ignored, e.g. by AUs, which are found by the OS rather - than manually. - */ - virtual StringArray searchPathsForPlugins (const FileSearchPath& directoriesToSearch, - bool recursive) = 0; - - /** Returns the typical places to look for this kind of plugin. - - Note that if this returns no paths, it means that the format doesn't search in - files or folders, e.g. AudioUnits. - */ - virtual FileSearchPath getDefaultLocationsToSearch() = 0; - -protected: - //============================================================================== - AudioPluginFormat() noexcept; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioPluginFormat) -}; - - -#endif // JUCE_AUDIOPLUGINFORMAT_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/format/juce_AudioPluginFormatManager.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/format/juce_AudioPluginFormatManager.cpp deleted file mode 100644 index 0afa7c7931..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/format/juce_AudioPluginFormatManager.cpp +++ /dev/null @@ -1,104 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -AudioPluginFormatManager::AudioPluginFormatManager() {} -AudioPluginFormatManager::~AudioPluginFormatManager() {} - -//============================================================================== -void AudioPluginFormatManager::addDefaultFormats() -{ - #if JUCE_DEBUG - // you should only call this method once! - for (int i = formats.size(); --i >= 0;) - { - #if JUCE_PLUGINHOST_VST - jassert (dynamic_cast (formats[i]) == nullptr); - #endif - - #if JUCE_PLUGINHOST_VST3 - jassert (dynamic_cast (formats[i]) == nullptr); - #endif - - #if JUCE_PLUGINHOST_AU && JUCE_MAC - jassert (dynamic_cast (formats[i]) == nullptr); - #endif - - #if JUCE_PLUGINHOST_LADSPA && JUCE_LINUX - jassert (dynamic_cast (formats[i]) == nullptr); - #endif - } - #endif - - #if JUCE_PLUGINHOST_AU && JUCE_MAC - formats.add (new AudioUnitPluginFormat()); - #endif - - #if JUCE_PLUGINHOST_VST - formats.add (new VSTPluginFormat()); - #endif - - #if JUCE_PLUGINHOST_VST3 - formats.add (new VST3PluginFormat()); - #endif - - #if JUCE_PLUGINHOST_LADSPA && JUCE_LINUX - formats.add (new LADSPAPluginFormat()); - #endif -} - -int AudioPluginFormatManager::getNumFormats() -{ - return formats.size(); -} - -AudioPluginFormat* AudioPluginFormatManager::getFormat (const int index) -{ - return formats [index]; -} - -void AudioPluginFormatManager::addFormat (AudioPluginFormat* const format) -{ - formats.add (format); -} - -AudioPluginInstance* AudioPluginFormatManager::createPluginInstance (const PluginDescription& description, double rate, - int blockSize, String& errorMessage) const -{ - for (int i = 0; i < formats.size(); ++i) - if (AudioPluginInstance* result = formats.getUnchecked(i)->createInstanceFromDescription (description, rate, blockSize)) - return result; - - errorMessage = doesPluginStillExist (description) ? TRANS ("This plug-in failed to load correctly") - : TRANS ("This plug-in file no longer exists"); - return nullptr; -} - -bool AudioPluginFormatManager::doesPluginStillExist (const PluginDescription& description) const -{ - for (int i = 0; i < formats.size(); ++i) - if (formats.getUnchecked(i)->getName() == description.pluginFormatName) - return formats.getUnchecked(i)->doesPluginStillExist (description); - - return false; -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/format/juce_AudioPluginFormatManager.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/format/juce_AudioPluginFormatManager.h deleted file mode 100644 index a6f1607d16..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/format/juce_AudioPluginFormatManager.h +++ /dev/null @@ -1,99 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_AUDIOPLUGINFORMATMANAGER_H_INCLUDED -#define JUCE_AUDIOPLUGINFORMATMANAGER_H_INCLUDED - - -//============================================================================== -/** - This maintains a list of known AudioPluginFormats. - - @see AudioPluginFormat -*/ -class JUCE_API AudioPluginFormatManager -{ -public: - //============================================================================== - AudioPluginFormatManager(); - - /** Destructor. */ - ~AudioPluginFormatManager(); - - //============================================================================== - /** Adds any formats that it knows about, e.g. VST. - */ - void addDefaultFormats(); - - //============================================================================== - /** Returns the number of types of format that are available. - - Use getFormat() to get one of them. - */ - int getNumFormats(); - - /** Returns one of the available formats. - - @see getNumFormats - */ - AudioPluginFormat* getFormat (int index); - - //============================================================================== - /** Adds a format to the list. - - The object passed in will be owned and deleted by the manager. - */ - void addFormat (AudioPluginFormat* format); - - - //============================================================================== - /** Tries to load the type for this description, by trying all the formats - that this manager knows about. - - The caller is responsible for deleting the object that is returned. - - If it can't load the plugin, it returns nullptr and leaves a message in the - errorMessage string. - */ - AudioPluginInstance* createPluginInstance (const PluginDescription& description, - double initialSampleRate, - int initialBufferSize, - String& errorMessage) const; - - /** Checks that the file or component for this plugin actually still exists. - - (This won't try to load the plugin) - */ - bool doesPluginStillExist (const PluginDescription& description) const; - -private: - //============================================================================== - OwnedArray formats; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioPluginFormatManager) -}; - - - -#endif // JUCE_AUDIOPLUGINFORMATMANAGER_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.h deleted file mode 100644 index 46c2b10eeb..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#if (JUCE_PLUGINHOST_AU && JUCE_MAC) || DOXYGEN - -//============================================================================== -/** - Implements a plugin format manager for AudioUnits. -*/ -class JUCE_API AudioUnitPluginFormat : public AudioPluginFormat -{ -public: - //============================================================================== - AudioUnitPluginFormat(); - ~AudioUnitPluginFormat(); - - //============================================================================== - String getName() const override { return "AudioUnit"; } - void findAllTypesForFile (OwnedArray&, const String& fileOrIdentifier) override; - AudioPluginInstance* createInstanceFromDescription (const PluginDescription& desc, double, int) override; - bool fileMightContainThisPluginType (const String& fileOrIdentifier) override; - String getNameOfPluginFromIdentifier (const String& fileOrIdentifier) override; - bool pluginNeedsRescanning (const PluginDescription&) override; - StringArray searchPathsForPlugins (const FileSearchPath&, bool recursive); - bool doesPluginStillExist (const PluginDescription&) override; - FileSearchPath getDefaultLocationsToSearch() override; - bool canScanForPlugins() const override { return true; } - -private: - //============================================================================== - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioUnitPluginFormat) -}; - -#endif diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.mm b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.mm deleted file mode 100644 index 2877509e8c..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.mm +++ /dev/null @@ -1,1738 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#if JUCE_PLUGINHOST_AU && JUCE_MAC - -} // (juce namespace) - -#include -#include -#include -#include -#include - -#if JUCE_SUPPORT_CARBON - #include -#endif - -namespace juce -{ - -#include "../../juce_audio_devices/native/juce_MidiDataConcatenator.h" - -#if JUCE_SUPPORT_CARBON - #include "../../juce_gui_extra/native/juce_mac_CarbonViewWrapperComponent.h" -#endif - -// Change this to disable logging of various activities -#ifndef AU_LOGGING - #define AU_LOGGING 1 -#endif - -#if AU_LOGGING - #define JUCE_AU_LOG(a) Logger::writeToLog(a); -#else - #define JUCE_AU_LOG(a) -#endif - -namespace AudioUnitFormatHelpers -{ - #if JUCE_DEBUG - static ThreadLocalValue insideCallback; - #endif - - String osTypeToString (OSType type) noexcept - { - const juce_wchar s[4] = { (juce_wchar) ((type >> 24) & 0xff), - (juce_wchar) ((type >> 16) & 0xff), - (juce_wchar) ((type >> 8) & 0xff), - (juce_wchar) (type & 0xff) }; - return String (s, 4); - } - - OSType stringToOSType (String s) - { - if (s.trim().length() >= 4) // (to avoid trimming leading spaces) - s = s.trim(); - - s += " "; - - return (((OSType) (unsigned char) s[0]) << 24) - | (((OSType) (unsigned char) s[1]) << 16) - | (((OSType) (unsigned char) s[2]) << 8) - | ((OSType) (unsigned char) s[3]); - } - - static const char* auIdentifierPrefix = "AudioUnit:"; - - String createPluginIdentifier (const AudioComponentDescription& desc) - { - String s (auIdentifierPrefix); - - if (desc.componentType == kAudioUnitType_MusicDevice) - s << "Synths/"; - else if (desc.componentType == kAudioUnitType_MusicEffect - || desc.componentType == kAudioUnitType_Effect) - s << "Effects/"; - else if (desc.componentType == kAudioUnitType_Generator) - s << "Generators/"; - else if (desc.componentType == kAudioUnitType_Panner) - s << "Panners/"; - - s << osTypeToString (desc.componentType) << "," - << osTypeToString (desc.componentSubType) << "," - << osTypeToString (desc.componentManufacturer); - - return s; - } - - void getNameAndManufacturer (AudioComponent comp, String& name, String& manufacturer) - { - CFStringRef cfName; - if (AudioComponentCopyName (comp, &cfName) == noErr) - { - name = String::fromCFString (cfName); - CFRelease (cfName); - } - - if (name.containsChar (':')) - { - manufacturer = name.upToFirstOccurrenceOf (":", false, false).trim(); - name = name.fromFirstOccurrenceOf (":", false, false).trim(); - } - - if (name.isEmpty()) - name = ""; - } - - bool getComponentDescFromIdentifier (const String& fileOrIdentifier, AudioComponentDescription& desc, - String& name, String& version, String& manufacturer) - { - if (fileOrIdentifier.startsWithIgnoreCase (auIdentifierPrefix)) - { - String s (fileOrIdentifier.substring (jmax (fileOrIdentifier.lastIndexOfChar (':'), - fileOrIdentifier.lastIndexOfChar ('/')) + 1)); - - StringArray tokens; - tokens.addTokens (s, ",", StringRef()); - tokens.removeEmptyStrings(); - - if (tokens.size() == 3) - { - zerostruct (desc); - desc.componentType = stringToOSType (tokens[0]); - desc.componentSubType = stringToOSType (tokens[1]); - desc.componentManufacturer = stringToOSType (tokens[2]); - - if (AudioComponent comp = AudioComponentFindNext (0, &desc)) - { - getNameAndManufacturer (comp, name, manufacturer); - - if (manufacturer.isEmpty()) - manufacturer = tokens[2]; - - if (version.isEmpty()) - { - UInt32 versionNum; - - if (AudioComponentGetVersion (comp, &versionNum) == noErr) - { - version << (int) (versionNum >> 16) << "." - << (int) ((versionNum >> 8) & 0xff) << "." - << (int) (versionNum & 0xff); - } - } - - return true; - } - } - } - - return false; - } - - bool getComponentDescFromFile (const String& fileOrIdentifier, AudioComponentDescription& desc, - String& name, String& version, String& manufacturer) - { - zerostruct (desc); - - const File file (fileOrIdentifier); - if (! file.hasFileExtension (".component")) - return false; - - const char* const utf8 = fileOrIdentifier.toUTF8(); - - if (CFURLRef url = CFURLCreateFromFileSystemRepresentation (0, (const UInt8*) utf8, - strlen (utf8), file.isDirectory())) - { - CFBundleRef bundleRef = CFBundleCreate (kCFAllocatorDefault, url); - CFRelease (url); - - if (bundleRef != 0) - { - CFTypeRef bundleName = CFBundleGetValueForInfoDictionaryKey (bundleRef, CFSTR("CFBundleName")); - - if (bundleName != 0 && CFGetTypeID (bundleName) == CFStringGetTypeID()) - name = String::fromCFString ((CFStringRef) bundleName); - - if (name.isEmpty()) - name = file.getFileNameWithoutExtension(); - - CFTypeRef versionString = CFBundleGetValueForInfoDictionaryKey (bundleRef, CFSTR("CFBundleVersion")); - - if (versionString != 0 && CFGetTypeID (versionString) == CFStringGetTypeID()) - version = String::fromCFString ((CFStringRef) versionString); - - CFTypeRef manuString = CFBundleGetValueForInfoDictionaryKey (bundleRef, CFSTR("CFBundleGetInfoString")); - - if (manuString != 0 && CFGetTypeID (manuString) == CFStringGetTypeID()) - manufacturer = String::fromCFString ((CFStringRef) manuString); - - const short resFileId = CFBundleOpenBundleResourceMap (bundleRef); - UseResFile (resFileId); - - const OSType thngType = stringToOSType ("thng"); - - for (ResourceIndex i = 1; i <= Count1Resources (thngType); ++i) - { - if (Handle h = Get1IndResource (thngType, i)) - { - HLock (h); - const uint32* const types = (const uint32*) *h; - - if (types[0] == kAudioUnitType_MusicDevice - || types[0] == kAudioUnitType_MusicEffect - || types[0] == kAudioUnitType_Effect - || types[0] == kAudioUnitType_Generator - || types[0] == kAudioUnitType_Panner) - { - desc.componentType = types[0]; - desc.componentSubType = types[1]; - desc.componentManufacturer = types[2]; - - if (AudioComponent comp = AudioComponentFindNext (0, &desc)) - getNameAndManufacturer (comp, name, manufacturer); - - break; - } - - HUnlock (h); - ReleaseResource (h); - } - } - - CFBundleCloseBundleResourceMap (bundleRef, resFileId); - CFRelease (bundleRef); - } - } - - return desc.componentType != 0 && desc.componentSubType != 0; - } - - const char* getCategory (OSType type) noexcept - { - switch (type) - { - case kAudioUnitType_Effect: - case kAudioUnitType_MusicEffect: return "Effect"; - case kAudioUnitType_MusicDevice: return "Synth"; - case kAudioUnitType_Generator: return "Generator"; - case kAudioUnitType_Panner: return "Panner"; - default: break; - } - - return nullptr; - } -} - -//============================================================================== -class AudioUnitPluginWindowCarbon; -class AudioUnitPluginWindowCocoa; - -//============================================================================== -class AudioUnitPluginInstance : public AudioPluginInstance -{ -public: - AudioUnitPluginInstance (const String& fileOrId) - : fileOrIdentifier (fileOrId), - wantsMidiMessages (false), - producesMidiMessages (false), - wasPlaying (false), - prepared (false), - currentBuffer (nullptr), - numInputBusChannels (0), - numOutputBusChannels (0), - numInputBusses (0), - numOutputBusses (0), - audioUnit (nullptr), - eventListenerRef (0), - midiConcatenator (2048) - { - using namespace AudioUnitFormatHelpers; - - #if JUCE_DEBUG - ++*insideCallback; - #endif - - JUCE_AU_LOG ("Opening AU: " + fileOrIdentifier); - - if (getComponentDescFromIdentifier (fileOrIdentifier, componentDesc, pluginName, version, manufacturer) - || getComponentDescFromFile (fileOrIdentifier, componentDesc, pluginName, version, manufacturer)) - { - if (AudioComponent comp = AudioComponentFindNext (0, &componentDesc)) - { - AudioComponentInstanceNew (comp, &audioUnit); - - wantsMidiMessages = componentDesc.componentType == kAudioUnitType_MusicDevice - || componentDesc.componentType == kAudioUnitType_MusicEffect; - } - } - - #if JUCE_DEBUG - --*insideCallback; - #endif - } - - ~AudioUnitPluginInstance() - { - const ScopedLock sl (lock); - - #if JUCE_DEBUG - // this indicates that some kind of recursive call is getting triggered that's - // deleting this plugin while it's still under construction. - jassert (AudioUnitFormatHelpers::insideCallback.get() == 0); - #endif - - if (eventListenerRef != 0) - { - AUListenerDispose (eventListenerRef); - eventListenerRef = 0; - } - - if (audioUnit != nullptr) - { - if (prepared) - releaseResources(); - - AudioComponentInstanceDispose (audioUnit); - audioUnit = nullptr; - } - } - - void initialise (double rate, int blockSize) - { - refreshParameterList(); - updateNumChannels(); - producesMidiMessages = canProduceMidiOutput(); - setPlayConfigDetails (numInputBusChannels * numInputBusses, - numOutputBusChannels * numOutputBusses, - rate, blockSize); - setLatencySamples (0); - - if (parameters.size() == 0) - { - // some plugins crash if initialiseAudioUnit() is called too soon (sigh..), so we'll - // only call it here if it seems like they it's one of the awkward plugins that can - // only create their parameters after it has been initialised. - initialiseAudioUnit(); - refreshParameterList(); - } - - setPluginCallbacks(); - } - - //============================================================================== - // AudioPluginInstance methods: - - void fillInPluginDescription (PluginDescription& desc) const override - { - desc.name = pluginName; - desc.descriptiveName = pluginName; - desc.fileOrIdentifier = AudioUnitFormatHelpers::createPluginIdentifier (componentDesc); - desc.uid = ((int) componentDesc.componentType) - ^ ((int) componentDesc.componentSubType) - ^ ((int) componentDesc.componentManufacturer); - desc.lastFileModTime = Time(); - desc.pluginFormatName = "AudioUnit"; - desc.category = AudioUnitFormatHelpers::getCategory (componentDesc.componentType); - desc.manufacturerName = manufacturer; - desc.version = version; - desc.numInputChannels = getNumInputChannels(); - desc.numOutputChannels = getNumOutputChannels(); - desc.isInstrument = (componentDesc.componentType == kAudioUnitType_MusicDevice); - } - - void* getPlatformSpecificData() override { return audioUnit; } - const String getName() const override { return pluginName; } - - bool silenceInProducesSilenceOut() const override - { - return getTailLengthSeconds() <= 0; - } - - double getTailLengthSeconds() const override - { - Float64 tail = 0; - UInt32 tailSize = sizeof (tail); - - if (audioUnit != nullptr) - AudioUnitGetProperty (audioUnit, kAudioUnitProperty_TailTime, kAudioUnitScope_Global, - 0, &tail, &tailSize); - - return tail; - } - - bool acceptsMidi() const override { return wantsMidiMessages; } - bool producesMidi() const override { return producesMidiMessages; } - - //============================================================================== - // AudioProcessor methods: - - void prepareToPlay (double newSampleRate, int estimatedSamplesPerBlock) override - { - if (audioUnit != nullptr) - { - releaseResources(); - updateNumChannels(); - - Float64 sampleRateIn = 0, sampleRateOut = 0; - UInt32 sampleRateSize = sizeof (sampleRateIn); - const Float64 sr = newSampleRate; - - for (int i = 0; i < numInputBusses; ++i) - { - AudioUnitGetProperty (audioUnit, kAudioUnitProperty_SampleRate, kAudioUnitScope_Input, i, &sampleRateIn, &sampleRateSize); - - if (sampleRateIn != sr) - AudioUnitSetProperty (audioUnit, kAudioUnitProperty_SampleRate, kAudioUnitScope_Input, i, &sr, sizeof (sr)); - } - - for (int i = 0; i < numOutputBusses; ++i) - { - AudioUnitGetProperty (audioUnit, kAudioUnitProperty_SampleRate, kAudioUnitScope_Output, i, &sampleRateOut, &sampleRateSize); - - if (sampleRateOut != sr) - AudioUnitSetProperty (audioUnit, kAudioUnitProperty_SampleRate, kAudioUnitScope_Output, i, &sr, sizeof (sr)); - } - - UInt32 frameSize = (UInt32) estimatedSamplesPerBlock; - AudioUnitSetProperty (audioUnit, kAudioUnitProperty_MaximumFramesPerSlice, kAudioUnitScope_Global, 0, - &frameSize, sizeof (frameSize)); - - setPlayConfigDetails (numInputBusChannels * numInputBusses, - numOutputBusChannels * numOutputBusses, - newSampleRate, estimatedSamplesPerBlock); - - Float64 latencySecs = 0.0; - UInt32 latencySize = sizeof (latencySecs); - AudioUnitGetProperty (audioUnit, kAudioUnitProperty_Latency, kAudioUnitScope_Global, - 0, &latencySecs, &latencySize); - - setLatencySamples (roundToInt (latencySecs * newSampleRate)); - - { - AudioStreamBasicDescription stream; - zerostruct (stream); // (can't use "= { 0 }" on this object because it's typedef'ed as a C struct) - stream.mSampleRate = sr; - stream.mFormatID = kAudioFormatLinearPCM; - stream.mFormatFlags = kAudioFormatFlagsNativeFloatPacked | kAudioFormatFlagIsNonInterleaved | kAudioFormatFlagsNativeEndian; - stream.mFramesPerPacket = 1; - stream.mBytesPerPacket = 4; - stream.mBytesPerFrame = 4; - stream.mBitsPerChannel = 32; - stream.mChannelsPerFrame = numInputBusChannels; - - for (int i = 0; i < numInputBusses; ++i) - AudioUnitSetProperty (audioUnit, kAudioUnitProperty_StreamFormat, - kAudioUnitScope_Input, i, &stream, sizeof (stream)); - - stream.mChannelsPerFrame = numOutputBusChannels; - - for (int i = 0; i < numOutputBusses; ++i) - AudioUnitSetProperty (audioUnit, kAudioUnitProperty_StreamFormat, - kAudioUnitScope_Output, i, &stream, sizeof (stream)); - } - - if (numOutputBusses != 0 && numOutputBusChannels != 0) - outputBufferList.calloc (numOutputBusses, getAudioBufferSizeInBytes()); - - zerostruct (timeStamp); - timeStamp.mSampleTime = 0; - timeStamp.mHostTime = AudioGetCurrentHostTime(); - timeStamp.mFlags = kAudioTimeStampSampleTimeValid | kAudioTimeStampHostTimeValid; - - currentBuffer = nullptr; - wasPlaying = false; - - resetBusses(); - - jassert (! prepared); - initialiseAudioUnit(); - } - } - - void releaseResources() override - { - if (prepared) - { - AudioUnitUninitialize (audioUnit); - resetBusses(); - AudioUnitReset (audioUnit, kAudioUnitScope_Global, 0); - - outputBufferList.free(); - currentBuffer = nullptr; - prepared = false; - } - - incomingMidi.clear(); - } - - bool initialiseAudioUnit() - { - if (! prepared) - prepared = (AudioUnitInitialize (audioUnit) == noErr); - - return prepared; - } - - void resetBusses() - { - for (int i = 0; i < numInputBusses; ++i) AudioUnitReset (audioUnit, kAudioUnitScope_Input, i); - for (int i = 0; i < numOutputBusses; ++i) AudioUnitReset (audioUnit, kAudioUnitScope_Output, i); - } - - void processBlock (AudioSampleBuffer& buffer, MidiBuffer& midiMessages) override - { - const int numSamples = buffer.getNumSamples(); - - if (prepared) - { - timeStamp.mHostTime = AudioGetCurrentHostTime(); - - for (int i = 0; i < numOutputBusses; ++i) - { - if (AudioBufferList* const abl = getAudioBufferListForBus(i)) - { - abl->mNumberBuffers = numOutputBusChannels; - - for (int j = 0; j < numOutputBusChannels; ++j) - { - abl->mBuffers[j].mNumberChannels = 1; - abl->mBuffers[j].mDataByteSize = sizeof (float) * numSamples; - abl->mBuffers[j].mData = buffer.getWritePointer (i * numOutputBusChannels + j); - } - } - } - - currentBuffer = &buffer; - - if (wantsMidiMessages) - { - const uint8* midiEventData; - int midiEventSize, midiEventPosition; - - for (MidiBuffer::Iterator i (midiMessages); i.getNextEvent (midiEventData, midiEventSize, midiEventPosition);) - { - if (midiEventSize <= 3) - MusicDeviceMIDIEvent (audioUnit, - midiEventData[0], midiEventData[1], midiEventData[2], - midiEventPosition); - else - MusicDeviceSysEx (audioUnit, midiEventData, midiEventSize); - } - - midiMessages.clear(); - } - - - for (int i = 0; i < numOutputBusses; ++i) - { - AudioUnitRenderActionFlags flags = 0; - AudioUnitRender (audioUnit, &flags, &timeStamp, i, numSamples, getAudioBufferListForBus (i)); - } - - timeStamp.mSampleTime += numSamples; - } - else - { - // Plugin not working correctly, so just bypass.. - for (int i = 0; i < getNumOutputChannels(); ++i) - buffer.clear (i, 0, buffer.getNumSamples()); - } - - if (producesMidiMessages) - { - const ScopedLock sl (midiInLock); - midiMessages.swapWith (incomingMidi); - incomingMidi.clear(); - } - } - - //============================================================================== - bool hasEditor() const override { return true; } - AudioProcessorEditor* createEditor() override; - - //============================================================================== - const String getInputChannelName (int index) const override - { - if (isPositiveAndBelow (index, getNumInputChannels())) - return "Input " + String (index + 1); - - return String(); - } - - const String getOutputChannelName (int index) const override - { - if (isPositiveAndBelow (index, getNumOutputChannels())) - return "Output " + String (index + 1); - - return String(); - } - - bool isInputChannelStereoPair (int index) const override { return isPositiveAndBelow (index, getNumInputChannels()); } - bool isOutputChannelStereoPair (int index) const override { return isPositiveAndBelow (index, getNumOutputChannels()); } - - //============================================================================== - int getNumParameters() override { return parameters.size(); } - - float getParameter (int index) override - { - const ScopedLock sl (lock); - - AudioUnitParameterValue value = 0; - - if (audioUnit != nullptr) - { - if (const ParamInfo* p = parameters[index]) - { - AudioUnitGetParameter (audioUnit, - p->paramID, - kAudioUnitScope_Global, 0, - &value); - - value = (value - p->minValue) / (p->maxValue - p->minValue); - } - } - - return value; - } - - void setParameter (int index, float newValue) override - { - const ScopedLock sl (lock); - - if (audioUnit != nullptr) - { - if (const ParamInfo* p = parameters[index]) - { - AudioUnitSetParameter (audioUnit, p->paramID, kAudioUnitScope_Global, 0, - p->minValue + (p->maxValue - p->minValue) * newValue, 0); - - sendParameterChangeEvent (index); - } - } - } - - void sendParameterChangeEvent (int index) - { - jassert (audioUnit != nullptr); - - const ParamInfo& p = *parameters.getUnchecked (index); - - AudioUnitEvent ev; - ev.mEventType = kAudioUnitEvent_ParameterValueChange; - ev.mArgument.mParameter.mAudioUnit = audioUnit; - ev.mArgument.mParameter.mParameterID = p.paramID; - ev.mArgument.mParameter.mScope = kAudioUnitScope_Global; - ev.mArgument.mParameter.mElement = 0; - - AUEventListenerNotify (nullptr, nullptr, &ev); - } - - void sendAllParametersChangedEvents() - { - jassert (audioUnit != nullptr); - - AudioUnitParameter param; - param.mAudioUnit = audioUnit; - param.mParameterID = kAUParameterListener_AnyParameter; - - AUParameterListenerNotify (nullptr, nullptr, ¶m); - } - - const String getParameterName (int index) override - { - if (const ParamInfo* p = parameters[index]) - return p->name; - - return String(); - } - - const String getParameterText (int index) override { return String (getParameter (index)); } - - bool isParameterAutomatable (int index) const override - { - if (const ParamInfo* p = parameters[index]) - return p->automatable; - - return false; - } - - //============================================================================== - int getNumPrograms() override - { - CFArrayRef presets; - UInt32 sz = sizeof (CFArrayRef); - int num = 0; - - if (AudioUnitGetProperty (audioUnit, kAudioUnitProperty_FactoryPresets, - kAudioUnitScope_Global, 0, &presets, &sz) == noErr) - { - num = (int) CFArrayGetCount (presets); - CFRelease (presets); - } - - return num; - } - - int getCurrentProgram() override - { - AUPreset current; - current.presetNumber = 0; - UInt32 sz = sizeof (AUPreset); - - AudioUnitGetProperty (audioUnit, kAudioUnitProperty_PresentPreset, - kAudioUnitScope_Global, 0, ¤t, &sz); - - return current.presetNumber; - } - - void setCurrentProgram (int newIndex) override - { - AUPreset current; - current.presetNumber = newIndex; - current.presetName = CFSTR(""); - - AudioUnitSetProperty (audioUnit, kAudioUnitProperty_PresentPreset, - kAudioUnitScope_Global, 0, ¤t, sizeof (AUPreset)); - - sendAllParametersChangedEvents(); - } - - const String getProgramName (int index) override - { - String s; - CFArrayRef presets; - UInt32 sz = sizeof (CFArrayRef); - - if (AudioUnitGetProperty (audioUnit, kAudioUnitProperty_FactoryPresets, - kAudioUnitScope_Global, 0, &presets, &sz) == noErr) - { - for (CFIndex i = 0; i < CFArrayGetCount (presets); ++i) - { - if (const AUPreset* p = (const AUPreset*) CFArrayGetValueAtIndex (presets, i)) - { - if (p->presetNumber == index) - { - s = String::fromCFString (p->presetName); - break; - } - } - } - - CFRelease (presets); - } - - return s; - } - - void changeProgramName (int /*index*/, const String& /*newName*/) override - { - jassertfalse; // xxx not implemented! - } - - //============================================================================== - void getStateInformation (MemoryBlock& destData) override - { - getCurrentProgramStateInformation (destData); - } - - void getCurrentProgramStateInformation (MemoryBlock& destData) override - { - CFPropertyListRef propertyList = 0; - UInt32 sz = sizeof (CFPropertyListRef); - - if (AudioUnitGetProperty (audioUnit, - kAudioUnitProperty_ClassInfo, - kAudioUnitScope_Global, - 0, &propertyList, &sz) == noErr) - { - CFWriteStreamRef stream = CFWriteStreamCreateWithAllocatedBuffers (kCFAllocatorDefault, kCFAllocatorDefault); - CFWriteStreamOpen (stream); - - CFIndex bytesWritten = CFPropertyListWriteToStream (propertyList, stream, kCFPropertyListBinaryFormat_v1_0, 0); - CFWriteStreamClose (stream); - - CFDataRef data = (CFDataRef) CFWriteStreamCopyProperty (stream, kCFStreamPropertyDataWritten); - - destData.setSize (bytesWritten); - destData.copyFrom (CFDataGetBytePtr (data), 0, destData.getSize()); - CFRelease (data); - - CFRelease (stream); - CFRelease (propertyList); - } - } - - void setStateInformation (const void* data, int sizeInBytes) override - { - setCurrentProgramStateInformation (data, sizeInBytes); - } - - void setCurrentProgramStateInformation (const void* data, int sizeInBytes) override - { - CFReadStreamRef stream = CFReadStreamCreateWithBytesNoCopy (kCFAllocatorDefault, (const UInt8*) data, - sizeInBytes, kCFAllocatorNull); - CFReadStreamOpen (stream); - - CFPropertyListFormat format = kCFPropertyListBinaryFormat_v1_0; - CFPropertyListRef propertyList = CFPropertyListCreateFromStream (kCFAllocatorDefault, stream, 0, - kCFPropertyListImmutable, &format, 0); - CFRelease (stream); - - if (propertyList != 0) - { - initialiseAudioUnit(); - - AudioUnitSetProperty (audioUnit, kAudioUnitProperty_ClassInfo, kAudioUnitScope_Global, - 0, &propertyList, sizeof (propertyList)); - - sendAllParametersChangedEvents(); - - CFRelease (propertyList); - } - } - - void refreshParameterList() override - { - parameters.clear(); - - if (audioUnit != nullptr) - { - UInt32 paramListSize = 0; - AudioUnitGetProperty (audioUnit, kAudioUnitProperty_ParameterList, kAudioUnitScope_Global, - 0, 0, ¶mListSize); - - if (paramListSize > 0) - { - const size_t numParams = paramListSize / sizeof (int); - - HeapBlock ids; - ids.calloc (numParams); - - AudioUnitGetProperty (audioUnit, kAudioUnitProperty_ParameterList, kAudioUnitScope_Global, - 0, ids, ¶mListSize); - - for (int i = 0; i < numParams; ++i) - { - AudioUnitParameterInfo info; - UInt32 sz = sizeof (info); - - if (AudioUnitGetProperty (audioUnit, - kAudioUnitProperty_ParameterInfo, - kAudioUnitScope_Global, - ids[i], &info, &sz) == noErr) - { - ParamInfo* const param = new ParamInfo(); - parameters.add (param); - param->paramID = ids[i]; - param->minValue = info.minValue; - param->maxValue = info.maxValue; - param->automatable = (info.flags & kAudioUnitParameterFlag_NonRealTime) == 0; - - if ((info.flags & kAudioUnitParameterFlag_HasCFNameString) != 0) - { - param->name = String::fromCFString (info.cfNameString); - - if ((info.flags & kAudioUnitParameterFlag_CFNameRelease) != 0) - CFRelease (info.cfNameString); - } - else - { - param->name = String (info.name, sizeof (info.name)); - } - } - } - } - } - } - - void handleIncomingMidiMessage (void*, const MidiMessage& message) - { - const ScopedLock sl (midiInLock); - incomingMidi.addEvent (message, 0); - } - - void handlePartialSysexMessage (void*, const uint8*, int, double) {} - -private: - //============================================================================== - friend class AudioUnitPluginWindowCarbon; - friend class AudioUnitPluginWindowCocoa; - friend class AudioUnitPluginFormat; - - AudioComponentDescription componentDesc; - String pluginName, manufacturer, version; - String fileOrIdentifier; - CriticalSection lock; - bool wantsMidiMessages, producesMidiMessages, wasPlaying, prepared; - - HeapBlock outputBufferList; - AudioTimeStamp timeStamp; - AudioSampleBuffer* currentBuffer; - int numInputBusChannels, numOutputBusChannels, numInputBusses, numOutputBusses; - - AudioUnit audioUnit; - AUEventListenerRef eventListenerRef; - - struct ParamInfo - { - UInt32 paramID; - String name; - AudioUnitParameterValue minValue, maxValue; - bool automatable; - }; - - OwnedArray parameters; - - MidiDataConcatenator midiConcatenator; - CriticalSection midiInLock; - MidiBuffer incomingMidi; - - void setPluginCallbacks() - { - if (audioUnit != nullptr) - { - { - AURenderCallbackStruct info; - zerostruct (info); // (can't use "= { 0 }" on this object because it's typedef'ed as a C struct) - - info.inputProcRefCon = this; - info.inputProc = renderGetInputCallback; - - for (int i = 0; i < numInputBusses; ++i) - AudioUnitSetProperty (audioUnit, kAudioUnitProperty_SetRenderCallback, - kAudioUnitScope_Input, i, &info, sizeof (info)); - } - - if (producesMidiMessages) - { - AUMIDIOutputCallbackStruct info; - zerostruct (info); - - info.userData = this; - info.midiOutputCallback = renderMidiOutputCallback; - - producesMidiMessages = (AudioUnitSetProperty (audioUnit, kAudioUnitProperty_MIDIOutputCallback, - kAudioUnitScope_Global, 0, &info, sizeof (info)) == noErr); - } - - { - HostCallbackInfo info; - zerostruct (info); - - info.hostUserData = this; - info.beatAndTempoProc = getBeatAndTempoCallback; - info.musicalTimeLocationProc = getMusicalTimeLocationCallback; - info.transportStateProc = getTransportStateCallback; - - AudioUnitSetProperty (audioUnit, kAudioUnitProperty_HostCallbacks, - kAudioUnitScope_Global, 0, &info, sizeof (info)); - } - - AUEventListenerCreate (eventListenerCallback, this, - #if MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_4 - CFRunLoopGetMain(), - #else - nullptr, - #endif - kCFRunLoopDefaultMode, 0, 0, &eventListenerRef); - - for (int i = 0; i < parameters.size(); ++i) - { - AudioUnitEvent event; - event.mArgument.mParameter.mAudioUnit = audioUnit; - event.mArgument.mParameter.mParameterID = parameters.getUnchecked(i)->paramID; - event.mArgument.mParameter.mScope = kAudioUnitScope_Global; - event.mArgument.mParameter.mElement = 0; - - event.mEventType = kAudioUnitEvent_ParameterValueChange; - AUEventListenerAddEventType (eventListenerRef, nullptr, &event); - - event.mEventType = kAudioUnitEvent_BeginParameterChangeGesture; - AUEventListenerAddEventType (eventListenerRef, nullptr, &event); - - event.mEventType = kAudioUnitEvent_EndParameterChangeGesture; - AUEventListenerAddEventType (eventListenerRef, nullptr, &event); - } - - // Add a listener for program changes - AudioUnitEvent event; - event.mArgument.mProperty.mAudioUnit = audioUnit; - event.mArgument.mProperty.mPropertyID = kAudioUnitProperty_PresentPreset; - event.mArgument.mProperty.mScope = kAudioUnitScope_Global; - event.mArgument.mProperty.mElement = 0; - - event.mEventType = kAudioUnitEvent_PropertyChange; - AUEventListenerAddEventType (eventListenerRef, nullptr, &event); - } - } - - void eventCallback (const AudioUnitEvent& event, AudioUnitParameterValue newValue) - { - switch (event.mEventType) - { - case kAudioUnitEvent_ParameterValueChange: - for (int i = 0; i < parameters.size(); ++i) - { - const ParamInfo& p = *parameters.getUnchecked(i); - - if (p.paramID == event.mArgument.mParameter.mParameterID) - { - sendParamChangeMessageToListeners (i, (newValue - p.minValue) / (p.maxValue - p.minValue)); - break; - } - } - - break; - - case kAudioUnitEvent_BeginParameterChangeGesture: - beginParameterChangeGesture (event.mArgument.mParameter.mParameterID); - break; - - case kAudioUnitEvent_EndParameterChangeGesture: - endParameterChangeGesture (event.mArgument.mParameter.mParameterID); - break; - - default: - sendAllParametersChangedEvents(); - break; - } - } - - static void eventListenerCallback (void* userRef, void*, const AudioUnitEvent* event, - UInt64, AudioUnitParameterValue value) - { - jassert (event != nullptr); - static_cast (userRef)->eventCallback (*event, value); - } - - //============================================================================== - OSStatus renderGetInput (AudioUnitRenderActionFlags*, - const AudioTimeStamp*, - UInt32 inBusNumber, - UInt32 inNumberFrames, - AudioBufferList* ioData) const - { - if (currentBuffer != nullptr) - { - // if this ever happens, might need to add extra handling - jassert (inNumberFrames == (UInt32) currentBuffer->getNumSamples()); - - for (UInt32 i = 0; i < ioData->mNumberBuffers; ++i) - { - const int bufferChannel = inBusNumber * numInputBusChannels + i; - - if (bufferChannel < currentBuffer->getNumChannels()) - { - memcpy (ioData->mBuffers[i].mData, - currentBuffer->getReadPointer (bufferChannel), - sizeof (float) * inNumberFrames); - } - else - { - zeromem (ioData->mBuffers[i].mData, - sizeof (float) * inNumberFrames); - } - } - } - - return noErr; - } - - OSStatus renderMidiOutput (const MIDIPacketList* pktlist) - { - if (pktlist != nullptr && pktlist->numPackets) - { - const double time = Time::getMillisecondCounterHiRes() * 0.001; - const MIDIPacket* packet = &pktlist->packet[0]; - - for (UInt32 i = 0; i < pktlist->numPackets; ++i) - { - midiConcatenator.pushMidiData (packet->data, (int) packet->length, time, (void*) nullptr, *this); - packet = MIDIPacketNext (packet); - } - } - - return noErr; - } - - template - static void setIfNotNull (Type1* p, Type2 value) noexcept - { - if (p != nullptr) *p = value; - } - - OSStatus getBeatAndTempo (Float64* outCurrentBeat, Float64* outCurrentTempo) const - { - AudioPlayHead* const ph = getPlayHead(); - AudioPlayHead::CurrentPositionInfo result; - - if (ph != nullptr && ph->getCurrentPosition (result)) - { - setIfNotNull (outCurrentBeat, result.ppqPosition); - setIfNotNull (outCurrentTempo, result.bpm); - } - else - { - setIfNotNull (outCurrentBeat, 0); - setIfNotNull (outCurrentTempo, 120.0); - } - - return noErr; - } - - OSStatus getMusicalTimeLocation (UInt32* outDeltaSampleOffsetToNextBeat, Float32* outTimeSig_Numerator, - UInt32* outTimeSig_Denominator, Float64* outCurrentMeasureDownBeat) const - { - AudioPlayHead* const ph = getPlayHead(); - AudioPlayHead::CurrentPositionInfo result; - - if (ph != nullptr && ph->getCurrentPosition (result)) - { - setIfNotNull (outTimeSig_Numerator, result.timeSigNumerator); - setIfNotNull (outTimeSig_Denominator, result.timeSigDenominator); - setIfNotNull (outDeltaSampleOffsetToNextBeat, 0); //xxx - setIfNotNull (outCurrentMeasureDownBeat, result.ppqPositionOfLastBarStart); //xxx wrong - } - else - { - setIfNotNull (outDeltaSampleOffsetToNextBeat, 0); - setIfNotNull (outTimeSig_Numerator, 4); - setIfNotNull (outTimeSig_Denominator, 4); - setIfNotNull (outCurrentMeasureDownBeat, 0); - } - - return noErr; - } - - OSStatus getTransportState (Boolean* outIsPlaying, Boolean* outTransportStateChanged, - Float64* outCurrentSampleInTimeLine, Boolean* outIsCycling, - Float64* outCycleStartBeat, Float64* outCycleEndBeat) - { - AudioPlayHead* const ph = getPlayHead(); - AudioPlayHead::CurrentPositionInfo result; - - if (ph != nullptr && ph->getCurrentPosition (result)) - { - setIfNotNull (outIsPlaying, result.isPlaying); - - if (outTransportStateChanged != nullptr) - { - *outTransportStateChanged = result.isPlaying != wasPlaying; - wasPlaying = result.isPlaying; - } - - setIfNotNull (outCurrentSampleInTimeLine, result.timeInSamples); - setIfNotNull (outIsCycling, false); - setIfNotNull (outCycleStartBeat, 0); - setIfNotNull (outCycleEndBeat, 0); - } - else - { - setIfNotNull (outIsPlaying, false); - setIfNotNull (outTransportStateChanged, false); - setIfNotNull (outCurrentSampleInTimeLine, 0); - setIfNotNull (outIsCycling, false); - setIfNotNull (outCycleStartBeat, 0); - setIfNotNull (outCycleEndBeat, 0); - } - - return noErr; - } - - //============================================================================== - static OSStatus renderGetInputCallback (void* hostRef, AudioUnitRenderActionFlags* ioActionFlags, - const AudioTimeStamp* inTimeStamp, UInt32 inBusNumber, - UInt32 inNumberFrames, AudioBufferList* ioData) - { - return static_cast (hostRef) - ->renderGetInput (ioActionFlags, inTimeStamp, inBusNumber, inNumberFrames, ioData); - } - - static OSStatus renderMidiOutputCallback (void* hostRef, const AudioTimeStamp*, UInt32 /*midiOutNum*/, - const struct MIDIPacketList* pktlist) - { - return static_cast (hostRef)->renderMidiOutput (pktlist); - } - - static OSStatus getBeatAndTempoCallback (void* hostRef, Float64* outCurrentBeat, Float64* outCurrentTempo) - { - return static_cast (hostRef)->getBeatAndTempo (outCurrentBeat, outCurrentTempo); - } - - static OSStatus getMusicalTimeLocationCallback (void* hostRef, UInt32* outDeltaSampleOffsetToNextBeat, - Float32* outTimeSig_Numerator, UInt32* outTimeSig_Denominator, - Float64* outCurrentMeasureDownBeat) - { - return static_cast (hostRef) - ->getMusicalTimeLocation (outDeltaSampleOffsetToNextBeat, outTimeSig_Numerator, - outTimeSig_Denominator, outCurrentMeasureDownBeat); - } - - static OSStatus getTransportStateCallback (void* hostRef, Boolean* outIsPlaying, Boolean* outTransportStateChanged, - Float64* outCurrentSampleInTimeLine, Boolean* outIsCycling, - Float64* outCycleStartBeat, Float64* outCycleEndBeat) - { - return static_cast (hostRef) - ->getTransportState (outIsPlaying, outTransportStateChanged, outCurrentSampleInTimeLine, - outIsCycling, outCycleStartBeat, outCycleEndBeat); - } - - //============================================================================== - size_t getAudioBufferSizeInBytes() const noexcept - { - return offsetof (AudioBufferList, mBuffers) + (sizeof (AudioBuffer) * numOutputBusChannels); - } - - AudioBufferList* getAudioBufferListForBus (int busIndex) const noexcept - { - return addBytesToPointer (outputBufferList.getData(), getAudioBufferSizeInBytes() * busIndex); - } - - int getElementCount (AudioUnitScope scope) const noexcept - { - UInt32 count; - UInt32 countSize = sizeof (count); - - if (AudioUnitGetProperty (audioUnit, kAudioUnitProperty_ElementCount, scope, 0, &count, &countSize) != noErr - || countSize == 0) - count = 1; - - return (int) count; - } - - void updateNumChannels() - { - numInputBusses = getElementCount (kAudioUnitScope_Input); - numOutputBusses = getElementCount (kAudioUnitScope_Output); - - AUChannelInfo supportedChannels [128]; - UInt32 supportedChannelsSize = sizeof (supportedChannels); - - if (AudioUnitGetProperty (audioUnit, kAudioUnitProperty_SupportedNumChannels, kAudioUnitScope_Global, - 0, supportedChannels, &supportedChannelsSize) == noErr - && supportedChannelsSize > 0) - { - int explicitNumIns = 0; - int explicitNumOuts = 0; - int maximumNumIns = 0; - int maximumNumOuts = 0; - - for (int i = 0; i < (int) (supportedChannelsSize / sizeof (AUChannelInfo)); ++i) - { - const int inChannels = (int) supportedChannels[i].inChannels; - const int outChannels = (int) supportedChannels[i].outChannels; - - if (inChannels < 0) - maximumNumIns = jmin (maximumNumIns, inChannels); - else - explicitNumIns = jmax (explicitNumIns, inChannels); - - if (outChannels < 0) - maximumNumOuts = jmin (maximumNumOuts, outChannels); - else - explicitNumOuts = jmax (explicitNumOuts, outChannels); - } - - if ((maximumNumIns == -1 && maximumNumOuts == -1) // (special meaning: any number of ins/outs, as long as they match) - || (maximumNumIns == -2 && maximumNumOuts == -1) // (special meaning: any number of ins/outs, even if they don't match) - || (maximumNumIns == -1 && maximumNumOuts == -2)) - { - numInputBusChannels = numOutputBusChannels = 2; - } - else - { - numInputBusChannels = explicitNumIns; - numOutputBusChannels = explicitNumOuts; - - if (maximumNumIns == -1 || (maximumNumIns < 0 && explicitNumIns <= -maximumNumIns)) - numInputBusChannels = 2; - - if (maximumNumOuts == -1 || (maximumNumOuts < 0 && explicitNumOuts <= -maximumNumOuts)) - numOutputBusChannels = 2; - } - } - else - { - // (this really means the plugin will take any number of ins/outs as long - // as they are the same) - numInputBusChannels = numOutputBusChannels = 2; - } - } - - bool canProduceMidiOutput() - { - UInt32 dataSize = 0; - Boolean isWritable = false; - - if (AudioUnitGetPropertyInfo (audioUnit, kAudioUnitProperty_MIDIOutputCallbackInfo, - kAudioUnitScope_Global, 0, &dataSize, &isWritable) == noErr - && dataSize != 0) - { - CFArrayRef midiArray; - - if (AudioUnitGetProperty (audioUnit, kAudioUnitProperty_MIDIOutputCallbackInfo, - kAudioUnitScope_Global, 0, &midiArray, &dataSize) == noErr) - { - bool result = (CFArrayGetCount (midiArray) > 0); - CFRelease (midiArray); - return result; - } - } - - return false; - } - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioUnitPluginInstance) -}; - -//============================================================================== -class AudioUnitPluginWindowCocoa : public AudioProcessorEditor -{ -public: - AudioUnitPluginWindowCocoa (AudioUnitPluginInstance& p, bool createGenericViewIfNeeded) - : AudioProcessorEditor (&p), - plugin (p) - { - addAndMakeVisible (wrapper); - - setOpaque (true); - setVisible (true); - setSize (100, 100); - - createView (createGenericViewIfNeeded); - } - - ~AudioUnitPluginWindowCocoa() - { - if (isValid()) - { - wrapper.setVisible (false); - removeChildComponent (&wrapper); - wrapper.setView (nil); - plugin.editorBeingDeleted (this); - } - } - - bool isValid() const { return wrapper.getView() != nil; } - - void paint (Graphics& g) override - { - g.fillAll (Colours::white); - } - - void resized() override - { - wrapper.setSize (getWidth(), getHeight()); - } - - void childBoundsChanged (Component*) override - { - setSize (wrapper.getWidth(), wrapper.getHeight()); - } - -private: - AudioUnitPluginInstance& plugin; - - AutoResizingNSViewComponent wrapper; - - bool createView (const bool createGenericViewIfNeeded) - { - if (! plugin.initialiseAudioUnit()) - return false; - - NSView* pluginView = nil; - UInt32 dataSize = 0; - Boolean isWritable = false; - - if (AudioUnitGetPropertyInfo (plugin.audioUnit, kAudioUnitProperty_CocoaUI, kAudioUnitScope_Global, - 0, &dataSize, &isWritable) == noErr - && dataSize != 0 - && AudioUnitGetPropertyInfo (plugin.audioUnit, kAudioUnitProperty_CocoaUI, kAudioUnitScope_Global, - 0, &dataSize, &isWritable) == noErr) - { - HeapBlock info; - info.calloc (dataSize, 1); - - if (AudioUnitGetProperty (plugin.audioUnit, kAudioUnitProperty_CocoaUI, kAudioUnitScope_Global, - 0, info, &dataSize) == noErr) - { - NSString* viewClassName = (NSString*) (info->mCocoaAUViewClass[0]); - CFStringRef path = CFURLCopyPath (info->mCocoaAUViewBundleLocation); - NSString* unescapedPath = (NSString*) CFURLCreateStringByReplacingPercentEscapes (0, path, CFSTR ("")); - CFRelease (path); - NSBundle* viewBundle = [NSBundle bundleWithPath: [unescapedPath autorelease]]; - Class viewClass = [viewBundle classNamed: viewClassName]; - - if ([viewClass conformsToProtocol: @protocol (AUCocoaUIBase)] - && [viewClass instancesRespondToSelector: @selector (interfaceVersion)] - && [viewClass instancesRespondToSelector: @selector (uiViewForAudioUnit: withSize:)]) - { - id factory = [[[viewClass alloc] init] autorelease]; - pluginView = [factory uiViewForAudioUnit: plugin.audioUnit - withSize: NSMakeSize (getWidth(), getHeight())]; - } - - for (int i = (dataSize - sizeof (CFURLRef)) / sizeof (CFStringRef); --i >= 0;) - CFRelease (info->mCocoaAUViewClass[i]); - - CFRelease (info->mCocoaAUViewBundleLocation); - } - } - - if (createGenericViewIfNeeded && (pluginView == nil)) - { - { - // This forces CoreAudio.component to be loaded, otherwise the AUGenericView will assert - AudioComponentDescription desc; - String name, version, manufacturer; - AudioUnitFormatHelpers::getComponentDescFromIdentifier ("AudioUnit:Output/auou,genr,appl", - desc, name, version, manufacturer); - } - - pluginView = [[AUGenericView alloc] initWithAudioUnit: plugin.audioUnit]; - } - - wrapper.setView (pluginView); - - if (pluginView != nil) - wrapper.resizeToFitView(); - - return pluginView != nil; - } -}; - -#if JUCE_SUPPORT_CARBON - -//============================================================================== -class AudioUnitPluginWindowCarbon : public AudioProcessorEditor -{ -public: - AudioUnitPluginWindowCarbon (AudioUnitPluginInstance& p) - : AudioProcessorEditor (&p), - plugin (p), - audioComponent (nullptr), - viewComponent (nullptr) - { - addAndMakeVisible (innerWrapper = new InnerWrapperComponent (*this)); - - setOpaque (true); - setVisible (true); - setSize (400, 300); - - UInt32 propertySize; - if (AudioUnitGetPropertyInfo (plugin.audioUnit, kAudioUnitProperty_GetUIComponentList, - kAudioUnitScope_Global, 0, &propertySize, NULL) == noErr - && propertySize > 0) - { - HeapBlock views (propertySize / sizeof (AudioComponentDescription)); - - if (AudioUnitGetProperty (plugin.audioUnit, kAudioUnitProperty_GetUIComponentList, - kAudioUnitScope_Global, 0, &views[0], &propertySize) == noErr) - { - audioComponent = AudioComponentFindNext (nullptr, &views[0]); - } - } - } - - ~AudioUnitPluginWindowCarbon() - { - innerWrapper = nullptr; - - if (isValid()) - plugin.editorBeingDeleted (this); - } - - bool isValid() const noexcept { return audioComponent != nullptr; } - - //============================================================================== - void paint (Graphics& g) override - { - g.fillAll (Colours::black); - } - - void resized() override - { - if (innerWrapper != nullptr) - innerWrapper->setSize (getWidth(), getHeight()); - } - - //============================================================================== - bool keyStateChanged (bool) override { return false; } - bool keyPressed (const KeyPress&) override { return false; } - - //============================================================================== - AudioUnit getAudioUnit() const { return plugin.audioUnit; } - - AudioUnitCarbonView getViewComponent() - { - if (viewComponent == nullptr && audioComponent != nullptr) - AudioComponentInstanceNew (audioComponent, &viewComponent); - - return viewComponent; - } - - void closeViewComponent() - { - if (viewComponent != nullptr) - { - JUCE_AU_LOG ("Closing AU GUI: " + plugin.getName()); - - AudioComponentInstanceDispose (viewComponent); - viewComponent = nullptr; - } - } - -private: - //============================================================================== - AudioUnitPluginInstance& plugin; - AudioComponent audioComponent; - AudioUnitCarbonView viewComponent; - - //============================================================================== - class InnerWrapperComponent : public CarbonViewWrapperComponent - { - public: - InnerWrapperComponent (AudioUnitPluginWindowCarbon& w) : owner (w) {} - - ~InnerWrapperComponent() - { - deleteWindow(); - } - - HIViewRef attachView (WindowRef windowRef, HIViewRef rootView) override - { - JUCE_AU_LOG ("Opening AU GUI: " + owner.plugin.getName()); - - AudioUnitCarbonView carbonView = owner.getViewComponent(); - - if (carbonView == 0) - return 0; - - Float32Point pos = { 0, 0 }; - Float32Point size = { 250, 200 }; - HIViewRef pluginView = 0; - - AudioUnitCarbonViewCreate (carbonView, owner.getAudioUnit(), windowRef, rootView, - &pos, &size, (ControlRef*) &pluginView); - - return pluginView; - } - - void removeView (HIViewRef) override - { - owner.closeViewComponent(); - } - - private: - AudioUnitPluginWindowCarbon& owner; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (InnerWrapperComponent) - }; - - friend class InnerWrapperComponent; - ScopedPointer innerWrapper; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioUnitPluginWindowCarbon) -}; - -#endif - -//============================================================================== -AudioProcessorEditor* AudioUnitPluginInstance::createEditor() -{ - ScopedPointer w (new AudioUnitPluginWindowCocoa (*this, false)); - - if (! static_cast (w.get())->isValid()) - w = nullptr; - - #if JUCE_SUPPORT_CARBON - if (w == nullptr) - { - w = new AudioUnitPluginWindowCarbon (*this); - - if (! static_cast (w.get())->isValid()) - w = nullptr; - } - #endif - - if (w == nullptr) - w = new AudioUnitPluginWindowCocoa (*this, true); // use AUGenericView as a fallback - - return w.release(); -} - - -//============================================================================== -//============================================================================== -AudioUnitPluginFormat::AudioUnitPluginFormat() -{ -} - -AudioUnitPluginFormat::~AudioUnitPluginFormat() -{ -} - -void AudioUnitPluginFormat::findAllTypesForFile (OwnedArray& results, - const String& fileOrIdentifier) -{ - if (! fileMightContainThisPluginType (fileOrIdentifier)) - return; - - PluginDescription desc; - desc.fileOrIdentifier = fileOrIdentifier; - desc.uid = 0; - - try - { - ScopedPointer createdInstance (createInstanceFromDescription (desc, 44100.0, 512)); - - if (AudioUnitPluginInstance* auInstance = dynamic_cast (createdInstance.get())) - results.add (new PluginDescription (auInstance->getPluginDescription())); - } - catch (...) - { - // crashed while loading... - } -} - -AudioPluginInstance* AudioUnitPluginFormat::createInstanceFromDescription (const PluginDescription& desc, double rate, int blockSize) -{ - if (fileMightContainThisPluginType (desc.fileOrIdentifier)) - { - ScopedPointer result (new AudioUnitPluginInstance (desc.fileOrIdentifier)); - - if (result->audioUnit != nullptr) - { - result->initialise (rate, blockSize); - return result.release(); - } - } - - return nullptr; -} - -StringArray AudioUnitPluginFormat::searchPathsForPlugins (const FileSearchPath&, bool /*recursive*/) -{ - StringArray result; - AudioComponent comp = nullptr; - - for (;;) - { - AudioComponentDescription desc; - zerostruct (desc); - - comp = AudioComponentFindNext (comp, &desc); - - if (comp == nullptr) - break; - - AudioComponentGetDescription (comp, &desc); - - if (desc.componentType == kAudioUnitType_MusicDevice - || desc.componentType == kAudioUnitType_MusicEffect - || desc.componentType == kAudioUnitType_Effect - || desc.componentType == kAudioUnitType_Generator - || desc.componentType == kAudioUnitType_Panner) - { - result.add (AudioUnitFormatHelpers::createPluginIdentifier (desc)); - } - } - - return result; -} - -bool AudioUnitPluginFormat::fileMightContainThisPluginType (const String& fileOrIdentifier) -{ - AudioComponentDescription desc; - - String name, version, manufacturer; - if (AudioUnitFormatHelpers::getComponentDescFromIdentifier (fileOrIdentifier, desc, name, version, manufacturer)) - return AudioComponentFindNext (nullptr, &desc) != nullptr; - - const File f (File::createFileWithoutCheckingPath (fileOrIdentifier)); - - return f.hasFileExtension (".component") - && f.isDirectory(); -} - -String AudioUnitPluginFormat::getNameOfPluginFromIdentifier (const String& fileOrIdentifier) -{ - AudioComponentDescription desc; - String name, version, manufacturer; - AudioUnitFormatHelpers::getComponentDescFromIdentifier (fileOrIdentifier, desc, name, version, manufacturer); - - if (name.isEmpty()) - name = fileOrIdentifier; - - return name; -} - -bool AudioUnitPluginFormat::pluginNeedsRescanning (const PluginDescription& desc) -{ - AudioComponentDescription newDesc; - String name, version, manufacturer; - - return ! (AudioUnitFormatHelpers::getComponentDescFromIdentifier (desc.fileOrIdentifier, newDesc, - name, version, manufacturer) - && version == desc.version); -} - -bool AudioUnitPluginFormat::doesPluginStillExist (const PluginDescription& desc) -{ - if (desc.fileOrIdentifier.startsWithIgnoreCase (AudioUnitFormatHelpers::auIdentifierPrefix)) - return fileMightContainThisPluginType (desc.fileOrIdentifier); - - return File (desc.fileOrIdentifier).exists(); -} - -FileSearchPath AudioUnitPluginFormat::getDefaultLocationsToSearch() -{ - return FileSearchPath(); -} - -#undef JUCE_AU_LOG - -#endif diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/format_types/juce_LADSPAPluginFormat.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/format_types/juce_LADSPAPluginFormat.cpp deleted file mode 100644 index 1bb2413ec5..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/format_types/juce_LADSPAPluginFormat.cpp +++ /dev/null @@ -1,703 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#if JUCE_PLUGINHOST_LADSPA && JUCE_LINUX - -} // (juce namespace) - -#include - -namespace juce -{ - -static int shellLADSPAUIDToCreate = 0; -static int insideLADSPACallback = 0; - -#define JUCE_LADSPA_LOGGING 1 - -#if JUCE_LADSPA_LOGGING - #define JUCE_LADSPA_LOG(x) Logger::writeToLog (x); -#else - #define JUCE_LADSPA_LOG(x) -#endif - -//============================================================================== -class LADSPAModuleHandle : public ReferenceCountedObject -{ -public: - LADSPAModuleHandle (const File& f) - : file (f), moduleMain (nullptr) - { - getActiveModules().add (this); - } - - ~LADSPAModuleHandle() - { - getActiveModules().removeFirstMatchingValue (this); - close(); - } - - typedef ReferenceCountedObjectPtr Ptr; - - static Array & getActiveModules() - { - static Array activeModules; - return activeModules; - } - - static LADSPAModuleHandle* findOrCreateModule (const File& file) - { - for (int i = getActiveModules().size(); --i >= 0;) - { - LADSPAModuleHandle* const module = getActiveModules().getUnchecked(i); - - if (module->file == file) - return module; - } - - ++insideLADSPACallback; - shellLADSPAUIDToCreate = 0; - - JUCE_LADSPA_LOG ("Loading LADSPA module: " + file.getFullPathName()); - - ScopedPointer m (new LADSPAModuleHandle (file)); - - if (! m->open()) - m = nullptr; - - --insideLADSPACallback; - - return m.release(); - } - - File file; - LADSPA_Descriptor_Function moduleMain; - -private: - DynamicLibrary module; - - bool open() - { - module.open (file.getFullPathName()); - moduleMain = (LADSPA_Descriptor_Function) module.getFunction ("ladspa_descriptor"); - return moduleMain != nullptr; - } - - void close() - { - module.close(); - } - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (LADSPAModuleHandle) -}; - - -//============================================================================== -class LADSPAPluginInstance : public AudioPluginInstance -{ -public: - LADSPAPluginInstance (const LADSPAModuleHandle::Ptr& m) - : module (m), plugin (nullptr), handle (nullptr), - initialised (false), tempBuffer (1, 1) - { - ++insideLADSPACallback; - - name = module->file.getFileNameWithoutExtension(); - - JUCE_LADSPA_LOG ("Creating LADSPA instance: " + name); - - if (module->moduleMain != nullptr) - { - plugin = module->moduleMain (shellLADSPAUIDToCreate); - - if (plugin == nullptr) - { - JUCE_LADSPA_LOG ("Cannot find any valid descriptor in shared library"); - --insideLADSPACallback; - return; - } - } - else - { - JUCE_LADSPA_LOG ("Cannot find any valid plugin in shared library"); - --insideLADSPACallback; - return; - } - - const double sampleRate = getSampleRate() > 0 ? getSampleRate() : 44100.0; - - handle = plugin->instantiate (plugin, (uint32) sampleRate); - - --insideLADSPACallback; - } - - ~LADSPAPluginInstance() - { - const ScopedLock sl (lock); - - jassert (insideLADSPACallback == 0); - - if (handle != nullptr && plugin != nullptr && plugin->cleanup != nullptr) - plugin->cleanup (handle); - - initialised = false; - module = nullptr; - plugin = nullptr; - handle = nullptr; - } - - void initialise (double initialSampleRate, int initialBlockSize) - { - setPlayConfigDetails (inputs.size(), outputs.size(), initialSampleRate, initialBlockSize); - - if (initialised || plugin == nullptr || handle == nullptr) - return; - - JUCE_LADSPA_LOG ("Initialising LADSPA: " + name); - - initialised = true; - - inputs.clear(); - outputs.clear(); - parameters.clear(); - - for (unsigned int i = 0; i < plugin->PortCount; ++i) - { - const LADSPA_PortDescriptor portDesc = plugin->PortDescriptors[i]; - - if ((portDesc & LADSPA_PORT_CONTROL) != 0) - parameters.add (i); - - if ((portDesc & LADSPA_PORT_AUDIO) != 0) - { - if ((portDesc & LADSPA_PORT_INPUT) != 0) inputs.add (i); - if ((portDesc & LADSPA_PORT_OUTPUT) != 0) outputs.add (i); - } - } - - parameterValues.calloc (parameters.size()); - - for (int i = 0; i < parameters.size(); ++i) - plugin->connect_port (handle, parameters[i], &(parameterValues[i].scaled)); - - setPlayConfigDetails (inputs.size(), outputs.size(), initialSampleRate, initialBlockSize); - - setCurrentProgram (0); - setLatencySamples (0); - - // Some plugins crash if this doesn't happen: - if (plugin->activate != nullptr) plugin->activate (handle); - if (plugin->deactivate != nullptr) plugin->deactivate (handle); - } - - //============================================================================== - // AudioPluginInstance methods: - - void fillInPluginDescription (PluginDescription& desc) const - { - desc.name = getName(); - desc.fileOrIdentifier = module->file.getFullPathName(); - desc.uid = getUID(); - desc.lastFileModTime = module->file.getLastModificationTime(); - desc.pluginFormatName = "LADSPA"; - desc.category = getCategory(); - desc.manufacturerName = plugin != nullptr ? String (plugin->Maker) : String(); - desc.version = getVersion(); - desc.numInputChannels = getNumInputChannels(); - desc.numOutputChannels = getNumOutputChannels(); - desc.isInstrument = false; - } - - const String getName() const - { - if (plugin != nullptr && plugin->Label != nullptr) - return plugin->Label; - - return name; - } - - int getUID() const - { - if (plugin != nullptr && plugin->UniqueID != 0) - return (int) plugin->UniqueID; - - return module->file.hashCode(); - } - - String getVersion() const { return LADSPA_VERSION; } - String getCategory() const { return "Effect"; } - - bool acceptsMidi() const { return false; } - bool producesMidi() const { return false; } - - bool silenceInProducesSilenceOut() const { return plugin == nullptr; } // ..any way to get a proper answer for these? - double getTailLengthSeconds() const { return 0.0; } - - //============================================================================== - void prepareToPlay (double newSampleRate, int samplesPerBlockExpected) - { - setLatencySamples (0); - - initialise (newSampleRate, samplesPerBlockExpected); - - if (initialised) - { - tempBuffer.setSize (jmax (1, outputs.size()), samplesPerBlockExpected); - - // dodgy hack to force some plugins to initialise the sample rate.. - if (getNumParameters() > 0) - { - const float old = getParameter (0); - setParameter (0, (old < 0.5f) ? 1.0f : 0.0f); - setParameter (0, old); - } - - if (plugin->activate != nullptr) - plugin->activate (handle); - } - } - - void releaseResources() - { - if (handle != nullptr && plugin->deactivate != nullptr) - plugin->deactivate (handle); - - tempBuffer.setSize (1, 1); - } - - void processBlock (AudioSampleBuffer& buffer, MidiBuffer& midiMessages) - { - const int numSamples = buffer.getNumSamples(); - - if (initialised && plugin != nullptr && handle != nullptr) - { - for (int i = 0; i < inputs.size(); ++i) - plugin->connect_port (handle, inputs[i], - i < buffer.getNumChannels() ? buffer.getWritePointer (i) : nullptr); - - if (plugin->run != nullptr) - { - for (int i = 0; i < outputs.size(); ++i) - plugin->connect_port (handle, outputs.getUnchecked(i), - i < buffer.getNumChannels() ? buffer.getWritePointer (i) : nullptr); - - plugin->run (handle, numSamples); - return; - } - - if (plugin->run_adding != nullptr) - { - tempBuffer.setSize (outputs.size(), numSamples); - tempBuffer.clear(); - - for (int i = 0; i < outputs.size(); ++i) - plugin->connect_port (handle, outputs.getUnchecked(i), tempBuffer.getWritePointer (i)); - - plugin->run_adding (handle, numSamples); - - for (int i = 0; i < outputs.size(); ++i) - if (i < buffer.getNumChannels()) - buffer.copyFrom (i, 0, tempBuffer, i, 0, numSamples); - - return; - } - - jassertfalse; // no callback to use? - } - - for (int i = getNumInputChannels(); i < getNumOutputChannels(); ++i) - buffer.clear (i, 0, numSamples); - } - - bool isInputChannelStereoPair (int index) const { return isPositiveAndBelow (index, getNumInputChannels()); } - bool isOutputChannelStereoPair (int index) const { return isPositiveAndBelow (index, getNumInputChannels()); } - - const String getInputChannelName (const int index) const - { - if (isPositiveAndBelow (index, getNumInputChannels())) - return String (plugin->PortNames [inputs [index]]).trim(); - - return String(); - } - - const String getOutputChannelName (const int index) const - { - if (isPositiveAndBelow (index, getNumInputChannels())) - return String (plugin->PortNames [outputs [index]]).trim(); - - return String(); - } - - //============================================================================== - int getNumParameters() { return handle != nullptr ? parameters.size() : 0; } - - bool isParameterAutomatable (int index) const - { - return plugin != nullptr - && (plugin->PortDescriptors [parameters[index]] & LADSPA_PORT_INPUT) != 0; - } - - float getParameter (int index) - { - if (plugin != nullptr && isPositiveAndBelow (index, parameters.size())) - { - const ScopedLock sl (lock); - return parameterValues[index].unscaled; - } - - return 0.0f; - } - - void setParameter (int index, float newValue) - { - if (plugin != nullptr && isPositiveAndBelow (index, parameters.size())) - { - const ScopedLock sl (lock); - - ParameterValue& p = parameterValues[index]; - - if (p.unscaled != newValue) - p = ParameterValue (getNewParamScaled (plugin->PortRangeHints [parameters[index]], newValue), newValue); - } - } - - const String getParameterName (int index) - { - if (plugin != nullptr) - { - jassert (isPositiveAndBelow (index, parameters.size())); - return String (plugin->PortNames [parameters [index]]).trim(); - } - - return String(); - } - - const String getParameterText (int index) - { - if (plugin != nullptr) - { - jassert (index >= 0 && index < parameters.size()); - - const LADSPA_PortRangeHint& hint = plugin->PortRangeHints [parameters [index]]; - - if (LADSPA_IS_HINT_INTEGER (hint.HintDescriptor)) - return String ((int) parameterValues[index].scaled); - - return String (parameterValues[index].scaled, 4); - } - - return String(); - } - - //============================================================================== - int getNumPrograms() { return 0; } - int getCurrentProgram() { return 0; } - - void setCurrentProgram (int newIndex) - { - if (plugin != nullptr) - for (int i = 0; i < parameters.size(); ++i) - parameterValues[i] = getParamValue (plugin->PortRangeHints [parameters[i]]); - } - - const String getProgramName (int index) - { - // XXX - return String(); - } - - void changeProgramName (int index, const String& newName) - { - // XXX - } - - //============================================================================== - void getStateInformation (MemoryBlock& destData) - { - destData.setSize (sizeof (float) * getNumParameters()); - destData.fillWith (0); - - float* const p = (float*) ((char*) destData.getData()); - for (int i = 0; i < getNumParameters(); ++i) - p[i] = getParameter(i); - } - - void getCurrentProgramStateInformation (MemoryBlock& destData) - { - getStateInformation (destData); - } - - void setStateInformation (const void* data, int sizeInBytes) - { - const float* p = static_cast (data); - - for (int i = 0; i < getNumParameters(); ++i) - setParameter (i, p[i]); - } - - void setCurrentProgramStateInformation (const void* data, int sizeInBytes) - { - setStateInformation (data, sizeInBytes); - } - - bool hasEditor() const - { - return false; - } - - AudioProcessorEditor* createEditor() - { - return nullptr; - } - - bool isValid() const - { - return handle != nullptr; - } - - LADSPAModuleHandle::Ptr module; - const LADSPA_Descriptor* plugin; - -private: - LADSPA_Handle handle; - String name; - CriticalSection lock; - bool initialised; - AudioSampleBuffer tempBuffer; - Array inputs, outputs, parameters; - - struct ParameterValue - { - inline ParameterValue() noexcept : scaled (0), unscaled (0) {} - inline ParameterValue (float s, float u) noexcept : scaled (s), unscaled (u) {} - - float scaled, unscaled; - }; - - HeapBlock parameterValues; - - //============================================================================== - static float scaledValue (float low, float high, float alpha, bool useLog) noexcept - { - if (useLog && low > 0 && high > 0) - return expf (logf (low) * (1.0f - alpha) + logf (high) * alpha); - - return low + (high - low) * alpha; - } - - static float toIntIfNecessary (const LADSPA_PortRangeHintDescriptor& desc, float value) - { - return LADSPA_IS_HINT_INTEGER (desc) ? ((float) (int) value) : value; - } - - float getNewParamScaled (const LADSPA_PortRangeHint& hint, float newValue) const - { - const LADSPA_PortRangeHintDescriptor& desc = hint.HintDescriptor; - - if (LADSPA_IS_HINT_TOGGLED (desc)) - return (newValue < 0.5f) ? 0.0f : 1.0f; - - const float scale = LADSPA_IS_HINT_SAMPLE_RATE (desc) ? (float) getSampleRate() : 1.0f; - const float lower = hint.LowerBound * scale; - const float upper = hint.UpperBound * scale; - - if (LADSPA_IS_HINT_BOUNDED_BELOW (desc) && LADSPA_IS_HINT_BOUNDED_ABOVE (desc)) - return toIntIfNecessary (desc, scaledValue (lower, upper, newValue, LADSPA_IS_HINT_LOGARITHMIC (desc))); - - if (LADSPA_IS_HINT_BOUNDED_BELOW (desc)) return toIntIfNecessary (desc, newValue); - if (LADSPA_IS_HINT_BOUNDED_ABOVE (desc)) return toIntIfNecessary (desc, newValue * upper); - - return 0.0f; - } - - ParameterValue getParamValue (const LADSPA_PortRangeHint& hint) const - { - const LADSPA_PortRangeHintDescriptor& desc = hint.HintDescriptor; - - if (LADSPA_IS_HINT_HAS_DEFAULT (desc)) - { - if (LADSPA_IS_HINT_DEFAULT_0 (desc)) return ParameterValue(); - if (LADSPA_IS_HINT_DEFAULT_1 (desc)) return ParameterValue (1.0f, 1.0f); - if (LADSPA_IS_HINT_DEFAULT_100 (desc)) return ParameterValue (100.0f, 0.5f); - if (LADSPA_IS_HINT_DEFAULT_440 (desc)) return ParameterValue (440.0f, 0.5f); - - const float scale = LADSPA_IS_HINT_SAMPLE_RATE (desc) ? (float) getSampleRate() : 1.0f; - const float lower = hint.LowerBound * scale; - const float upper = hint.UpperBound * scale; - - if (LADSPA_IS_HINT_BOUNDED_BELOW (desc) && LADSPA_IS_HINT_DEFAULT_MINIMUM (desc)) return ParameterValue (lower, 0.0f); - if (LADSPA_IS_HINT_BOUNDED_ABOVE (desc) && LADSPA_IS_HINT_DEFAULT_MAXIMUM (desc)) return ParameterValue (upper, 1.0f); - - if (LADSPA_IS_HINT_BOUNDED_BELOW (desc)) - { - const bool useLog = LADSPA_IS_HINT_LOGARITHMIC (desc); - - if (LADSPA_IS_HINT_DEFAULT_LOW (desc)) return ParameterValue (scaledValue (lower, upper, 0.25f, useLog), 0.25f); - if (LADSPA_IS_HINT_DEFAULT_MIDDLE (desc)) return ParameterValue (scaledValue (lower, upper, 0.50f, useLog), 0.50f); - if (LADSPA_IS_HINT_DEFAULT_HIGH (desc)) return ParameterValue (scaledValue (lower, upper, 0.75f, useLog), 0.75f); - } - } - - return ParameterValue(); - } - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (LADSPAPluginInstance) -}; - - -//============================================================================== -//============================================================================== -LADSPAPluginFormat::LADSPAPluginFormat() {} -LADSPAPluginFormat::~LADSPAPluginFormat() {} - -void LADSPAPluginFormat::findAllTypesForFile (OwnedArray & results, - const String& fileOrIdentifier) -{ - if (! fileMightContainThisPluginType (fileOrIdentifier)) - return; - - PluginDescription desc; - desc.fileOrIdentifier = fileOrIdentifier; - desc.uid = 0; - - ScopedPointer instance (dynamic_cast (createInstanceFromDescription (desc, 44100.0, 512))); - - if (instance == nullptr || ! instance->isValid()) - return; - - instance->initialise (44100.0, 512); - - instance->fillInPluginDescription (desc); - - if (instance->module->moduleMain != nullptr) - { - for (int uid = 0;; ++uid) - { - if (const LADSPA_Descriptor* plugin = instance->module->moduleMain (uid)) - { - desc.uid = uid; - desc.name = plugin->Name != nullptr ? plugin->Name : "Unknown"; - - if (! arrayContainsPlugin (results, desc)) - results.add (new PluginDescription (desc)); - } - else - { - break; - } - } - } -} - -AudioPluginInstance* LADSPAPluginFormat::createInstanceFromDescription (const PluginDescription& desc, - double sampleRate, int blockSize) -{ - ScopedPointer result; - - if (fileMightContainThisPluginType (desc.fileOrIdentifier)) - { - File file (desc.fileOrIdentifier); - - const File previousWorkingDirectory (File::getCurrentWorkingDirectory()); - file.getParentDirectory().setAsCurrentWorkingDirectory(); - - const LADSPAModuleHandle::Ptr module (LADSPAModuleHandle::findOrCreateModule (file)); - - if (module != nullptr) - { - shellLADSPAUIDToCreate = desc.uid; - - result = new LADSPAPluginInstance (module); - - if (result->plugin != nullptr && result->isValid()) - result->initialise (sampleRate, blockSize); - else - result = nullptr; - } - - previousWorkingDirectory.setAsCurrentWorkingDirectory(); - } - - return result.release(); -} - -bool LADSPAPluginFormat::fileMightContainThisPluginType (const String& fileOrIdentifier) -{ - const File f (File::createFileWithoutCheckingPath (fileOrIdentifier)); - return f.existsAsFile() && f.hasFileExtension (".so"); -} - -String LADSPAPluginFormat::getNameOfPluginFromIdentifier (const String& fileOrIdentifier) -{ - return fileOrIdentifier; -} - -bool LADSPAPluginFormat::pluginNeedsRescanning (const PluginDescription& desc) -{ - return File (desc.fileOrIdentifier).getLastModificationTime() != desc.lastFileModTime; -} - -bool LADSPAPluginFormat::doesPluginStillExist (const PluginDescription& desc) -{ - return File::createFileWithoutCheckingPath (desc.fileOrIdentifier).exists(); -} - -StringArray LADSPAPluginFormat::searchPathsForPlugins (const FileSearchPath& directoriesToSearch, const bool recursive) -{ - StringArray results; - - for (int j = 0; j < directoriesToSearch.getNumPaths(); ++j) - recursiveFileSearch (results, directoriesToSearch[j], recursive); - - return results; -} - -void LADSPAPluginFormat::recursiveFileSearch (StringArray& results, const File& dir, const bool recursive) -{ - DirectoryIterator iter (dir, false, "*", File::findFilesAndDirectories); - - while (iter.next()) - { - const File f (iter.getFile()); - bool isPlugin = false; - - if (fileMightContainThisPluginType (f.getFullPathName())) - { - isPlugin = true; - results.add (f.getFullPathName()); - } - - if (recursive && (! isPlugin) && f.isDirectory()) - recursiveFileSearch (results, f, true); - } -} - -FileSearchPath LADSPAPluginFormat::getDefaultLocationsToSearch() -{ - return FileSearchPath (SystemStats::getEnvironmentVariable ("LADSPA_PATH", - "/usr/lib/ladspa;/usr/local/lib/ladspa;~/.ladspa") - .replace (":", ";")); -} - -#endif diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/format_types/juce_LADSPAPluginFormat.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/format_types/juce_LADSPAPluginFormat.h deleted file mode 100644 index 21d3167723..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/format_types/juce_LADSPAPluginFormat.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#if (JUCE_PLUGINHOST_LADSPA && JUCE_LINUX) || DOXYGEN - -//============================================================================== -/** - Implements a plugin format manager for LADSPA plugins. -*/ -class JUCE_API LADSPAPluginFormat : public AudioPluginFormat -{ -public: - //============================================================================== - LADSPAPluginFormat(); - ~LADSPAPluginFormat(); - - //============================================================================== - String getName() const override { return "LADSPA"; } - void findAllTypesForFile (OwnedArray&, const String& fileOrIdentifier) override; - AudioPluginInstance* createInstanceFromDescription (const PluginDescription&, double, int) override; - bool fileMightContainThisPluginType (const String& fileOrIdentifier) override; - String getNameOfPluginFromIdentifier (const String& fileOrIdentifier) override; - bool pluginNeedsRescanning (const PluginDescription&) override; - StringArray searchPathsForPlugins (const FileSearchPath&, bool recursive) override; - bool doesPluginStillExist (const PluginDescription&) override; - FileSearchPath getDefaultLocationsToSearch() override; - bool canScanForPlugins() const override { return true; } - -private: - void recursiveFileSearch (StringArray&, const File&, bool recursive); - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (LADSPAPluginFormat) -}; - - -#endif diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/format_types/juce_VST3Common.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/format_types/juce_VST3Common.h deleted file mode 100644 index d7e66cdc89..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/format_types/juce_VST3Common.h +++ /dev/null @@ -1,420 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_VST3COMMON_H_INCLUDED -#define JUCE_VST3COMMON_H_INCLUDED - -//============================================================================== -#define JUCE_DECLARE_VST3_COM_REF_METHODS \ - Steinberg::uint32 PLUGIN_API addRef() override { return (Steinberg::uint32) ++refCount; } \ - Steinberg::uint32 PLUGIN_API release() override { const int r = --refCount; if (r == 0) delete this; return (Steinberg::uint32) r; } - -#define JUCE_DECLARE_VST3_COM_QUERY_METHODS \ - Steinberg::tresult PLUGIN_API queryInterface (const Steinberg::TUID, void** obj) override \ - { \ - jassertfalse; \ - *obj = nullptr; \ - return Steinberg::kNotImplemented; \ - } - -static bool doUIDsMatch (const Steinberg::TUID a, const Steinberg::TUID b) noexcept -{ - return std::memcmp (a, b, sizeof (Steinberg::TUID)) == 0; -} - -#define TEST_FOR_AND_RETURN_IF_VALID(iidToTest, ClassType) \ - if (doUIDsMatch (iidToTest, ClassType::iid)) \ - { \ - addRef(); \ - *obj = dynamic_cast (this); \ - return Steinberg::kResultOk; \ - } - -#define TEST_FOR_COMMON_BASE_AND_RETURN_IF_VALID(iidToTest, CommonClassType, SourceClassType) \ - if (doUIDsMatch (iidToTest, CommonClassType::iid)) \ - { \ - addRef(); \ - *obj = (CommonClassType*) static_cast (this); \ - return Steinberg::kResultOk; \ - } - -//============================================================================== -static juce::String toString (const Steinberg::char8* string) noexcept { return juce::String (string); } -static juce::String toString (const Steinberg::char16* string) noexcept { return juce::String (juce::CharPointer_UTF16 ((juce::CharPointer_UTF16::CharType*) string)); } - -// NB: The casts are handled by a Steinberg::UString operator -static juce::String toString (const Steinberg::UString128& string) noexcept { return toString (static_cast (string)); } -static juce::String toString (const Steinberg::UString256& string) noexcept { return toString (static_cast (string)); } - -static void toString128 (Steinberg::Vst::String128 result, const juce::String& source) -{ - Steinberg::UString (result, 128).fromAscii (source.toUTF8()); -} - -static Steinberg::Vst::TChar* toString (const juce::String& source) noexcept -{ - return reinterpret_cast (source.toUTF16().getAddress()); -} - -#if JUCE_WINDOWS - static const Steinberg::FIDString defaultVST3WindowType = Steinberg::kPlatformTypeHWND; -#else - static const Steinberg::FIDString defaultVST3WindowType = Steinberg::kPlatformTypeNSView; -#endif - - -//============================================================================== -static Steinberg::Vst::SpeakerArrangement getArrangementForBus (Steinberg::Vst::IAudioProcessor* processor, - bool isInput, int busIndex) -{ - Steinberg::Vst::SpeakerArrangement arrangement = Steinberg::Vst::SpeakerArr::kEmpty; - - if (processor != nullptr) - processor->getBusArrangement (isInput ? Steinberg::Vst::kInput : Steinberg::Vst::kOutput, - (Steinberg::int32) busIndex, arrangement); - - return arrangement; -} - -/** For the sake of simplicity, there can only be 1 arrangement type per channel count. - i.e.: 4 channels == k31Cine OR k40Cine -*/ -static Steinberg::Vst::SpeakerArrangement getArrangementForNumChannels (int numChannels) noexcept -{ - using namespace Steinberg::Vst::SpeakerArr; - - switch (numChannels) - { - case 0: return kEmpty; - case 1: return kMono; - case 2: return kStereo; - case 3: return k30Cine; - case 4: return k31Cine; - case 5: return k50; - case 6: return k51; - case 7: return k61Cine; - case 8: return k71CineFullFront; - case 9: return k90; - case 10: return k91; - case 11: return k101; - case 12: return k111; - case 13: return k130; - case 14: return k131; - case 24: return (Steinberg::Vst::SpeakerArrangement) 1929904127; // k222 - default: break; - } - - jassert (numChannels >= 0); - - juce::BigInteger bi; - bi.setRange (0, jmin (numChannels, (int) (sizeof (Steinberg::Vst::SpeakerArrangement) * 8)), true); - return (Steinberg::Vst::SpeakerArrangement) bi.toInt64(); -} - -//============================================================================== -template -class ComSmartPtr -{ -public: - ComSmartPtr() noexcept : source (nullptr) {} - ComSmartPtr (ObjectType* object, bool autoAddRef = true) noexcept : source (object) { if (source != nullptr && autoAddRef) source->addRef(); } - ComSmartPtr (const ComSmartPtr& other) noexcept : source (other.source) { if (source != nullptr) source->addRef(); } - ~ComSmartPtr() { if (source != nullptr) source->release(); } - - operator ObjectType*() const noexcept { return source; } - ObjectType* get() const noexcept { return source; } - ObjectType& operator*() const noexcept { return *source; } - ObjectType* operator->() const noexcept { return source; } - - ComSmartPtr& operator= (const ComSmartPtr& other) { return operator= (other.source); } - - ComSmartPtr& operator= (ObjectType* const newObjectToTakePossessionOf) - { - ComSmartPtr p (newObjectToTakePossessionOf); - std::swap (p.source, source); - return *this; - } - - bool operator== (ObjectType* const other) noexcept { return source == other; } - bool operator!= (ObjectType* const other) noexcept { return source != other; } - - bool loadFrom (Steinberg::FUnknown* o) - { - *this = nullptr; - return o != nullptr && o->queryInterface (ObjectType::iid, (void**) &source) == Steinberg::kResultOk; - } - - bool loadFrom (Steinberg::IPluginFactory* factory, const Steinberg::TUID& uuid) - { - jassert (factory != nullptr); - *this = nullptr; - return factory->createInstance (uuid, ObjectType::iid, (void**) &source) == Steinberg::kResultOk; - } - -private: - ObjectType* source; -}; - -//============================================================================== -class MidiEventList : public Steinberg::Vst::IEventList -{ -public: - MidiEventList() {} - virtual ~MidiEventList() {} - - JUCE_DECLARE_VST3_COM_REF_METHODS - JUCE_DECLARE_VST3_COM_QUERY_METHODS - - //============================================================================== - void clear() - { - events.clearQuick(); - } - - Steinberg::int32 PLUGIN_API getEventCount() override - { - return (Steinberg::int32) events.size(); - } - - // NB: This has to cope with out-of-range indexes from some plugins. - Steinberg::tresult PLUGIN_API getEvent (Steinberg::int32 index, Steinberg::Vst::Event& e) override - { - if (isPositiveAndBelow ((int) index, events.size())) - { - e = events.getReference ((int) index); - return Steinberg::kResultTrue; - } - - return Steinberg::kResultFalse; - } - - Steinberg::tresult PLUGIN_API addEvent (Steinberg::Vst::Event& e) override - { - events.add (e); - return Steinberg::kResultTrue; - } - - //============================================================================== - static void toMidiBuffer (MidiBuffer& result, Steinberg::Vst::IEventList& eventList) - { - const int32 numEvents = eventList.getEventCount(); - - for (Steinberg::int32 i = 0; i < numEvents; ++i) - { - Steinberg::Vst::Event e; - - if (eventList.getEvent (i, e) == Steinberg::kResultOk) - { - switch (e.type) - { - case Steinberg::Vst::Event::kNoteOnEvent: - result.addEvent (MidiMessage::noteOn (createSafeChannel (e.noteOn.channel), - createSafeNote (e.noteOn.pitch), - (Steinberg::uint8) denormaliseToMidiValue (e.noteOn.velocity)), - e.sampleOffset); - break; - - case Steinberg::Vst::Event::kNoteOffEvent: - result.addEvent (MidiMessage::noteOff (createSafeChannel (e.noteOff.channel), - createSafeNote (e.noteOff.pitch), - (Steinberg::uint8) denormaliseToMidiValue (e.noteOff.velocity)), - e.sampleOffset); - break; - - case Steinberg::Vst::Event::kPolyPressureEvent: - result.addEvent (MidiMessage::aftertouchChange (createSafeChannel (e.polyPressure.channel), - createSafeNote (e.polyPressure.pitch), - denormaliseToMidiValue (e.polyPressure.pressure)), - e.sampleOffset); - break; - - case Steinberg::Vst::Event::kDataEvent: - result.addEvent (MidiMessage::createSysExMessage (e.data.bytes, e.data.size), - e.sampleOffset); - break; - - default: - break; - } - } - } - } - - static void toEventList (Steinberg::Vst::IEventList& result, MidiBuffer& midiBuffer) - { - MidiBuffer::Iterator iterator (midiBuffer); - MidiMessage msg; - int midiEventPosition = 0; - - enum { maxNumEvents = 2048 }; // Steinberg's Host Checker states that no more than 2048 events are allowed at once - int numEvents = 0; - - while (iterator.getNextEvent (msg, midiEventPosition)) - { - if (++numEvents > maxNumEvents) - break; - - Steinberg::Vst::Event e = { 0 }; - - if (msg.isNoteOn()) - { - e.type = Steinberg::Vst::Event::kNoteOnEvent; - e.noteOn.channel = createSafeChannel (msg.getChannel()); - e.noteOn.pitch = createSafeNote (msg.getNoteNumber()); - e.noteOn.velocity = normaliseMidiValue (msg.getVelocity()); - e.noteOn.length = 0; - e.noteOn.tuning = 0.0f; - e.noteOn.noteId = -1; - } - else if (msg.isNoteOff()) - { - e.type = Steinberg::Vst::Event::kNoteOffEvent; - e.noteOff.channel = createSafeChannel (msg.getChannel()); - e.noteOff.pitch = createSafeNote (msg.getNoteNumber()); - e.noteOff.velocity = normaliseMidiValue (msg.getVelocity()); - e.noteOff.tuning = 0.0f; - e.noteOff.noteId = -1; - } - else if (msg.isSysEx()) - { - e.type = Steinberg::Vst::Event::kDataEvent; - e.data.bytes = msg.getSysExData(); - e.data.size = msg.getSysExDataSize(); - e.data.type = Steinberg::Vst::DataEvent::kMidiSysEx; - } - else if (msg.isAftertouch()) - { - e.type = Steinberg::Vst::Event::kPolyPressureEvent; - e.polyPressure.channel = createSafeChannel (msg.getChannel()); - e.polyPressure.pitch = createSafeNote (msg.getNoteNumber()); - e.polyPressure.pressure = normaliseMidiValue (msg.getAfterTouchValue()); - } - else - { - continue; - } - - e.busIndex = 0; - e.sampleOffset = midiEventPosition; - - result.addEvent (e); - } - } - -private: - Array events; - Atomic refCount; - - static Steinberg::int16 createSafeChannel (int channel) noexcept { return (Steinberg::int16) jlimit (0, 15, channel - 1); } - static int createSafeChannel (Steinberg::int16 channel) noexcept { return (int) jlimit (1, 16, channel + 1); } - - static Steinberg::int16 createSafeNote (int note) noexcept { return (Steinberg::int16) jlimit (0, 127, note); } - static int createSafeNote (Steinberg::int16 note) noexcept { return jlimit (0, 127, (int) note); } - - static float normaliseMidiValue (int value) noexcept { return jlimit (0.0f, 1.0f, (float) value / 127.0f); } - static int denormaliseToMidiValue (float value) noexcept { return roundToInt (jlimit (0.0f, 127.0f, value * 127.0f)); } - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MidiEventList) -}; - -//============================================================================== -namespace VST3BufferExchange -{ - typedef Array Bus; - typedef Array BusMap; - - /** Assigns a series of AudioSampleBuffer's channels to an AudioBusBuffers' - - @warning For speed, does not check the channel count and offsets - according to the AudioSampleBuffer - */ - void associateBufferTo (Steinberg::Vst::AudioBusBuffers& vstBuffers, - Bus& bus, - AudioSampleBuffer& buffer, - int numChannels, int channelStartOffset, - int sampleOffset = 0) - { - const int channelEnd = numChannels + channelStartOffset; - jassert (channelEnd >= 0 && channelEnd <= buffer.getNumChannels()); - - bus.clearQuick(); - - for (int i = channelStartOffset; i < channelEnd; ++i) - bus.add (buffer.getWritePointer (i, sampleOffset)); - - vstBuffers.channelBuffers32 = bus.getRawDataPointer(); - vstBuffers.numChannels = numChannels; - vstBuffers.silenceFlags = 0; - } - - static void mapArrangementToBusses (int& channelIndexOffset, int index, - Array& result, - BusMap& busMapToUse, Steinberg::Vst::SpeakerArrangement arrangement, - AudioSampleBuffer& source) - { - const int numChansForBus = BigInteger ((juce::int64) arrangement).countNumberOfSetBits(); - - if (index >= result.size()) - result.add (Steinberg::Vst::AudioBusBuffers()); - - if (index >= busMapToUse.size()) - busMapToUse.add (Bus()); - - if (numChansForBus > 0) - { - associateBufferTo (result.getReference (index), - busMapToUse.getReference (index), - source, numChansForBus, channelIndexOffset); - } - - channelIndexOffset += numChansForBus; - } - - static void mapBufferToBusses (Array& result, BusMap& busMapToUse, - const Array& arrangements, - AudioSampleBuffer& source) - { - int channelIndexOffset = 0; - - for (int i = 0; i < arrangements.size(); ++i) - mapArrangementToBusses (channelIndexOffset, i, result, busMapToUse, - arrangements.getUnchecked (i), source); - } - - static void mapBufferToBusses (Array& result, - Steinberg::Vst::IAudioProcessor& processor, - BusMap& busMapToUse, bool isInput, int numBusses, - AudioSampleBuffer& source) - { - int channelIndexOffset = 0; - - for (int i = 0; i < numBusses; ++i) - mapArrangementToBusses (channelIndexOffset, i, - result, busMapToUse, - getArrangementForBus (&processor, isInput, i), - source); - } -} - -#endif // JUCE_VST3COMMON_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/format_types/juce_VST3Headers.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/format_types/juce_VST3Headers.h deleted file mode 100644 index ffb90e8664..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/format_types/juce_VST3Headers.h +++ /dev/null @@ -1,172 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_VST3HEADERS_H_INCLUDED -#define JUCE_VST3HEADERS_H_INCLUDED - -#undef Point -#undef Component - -// Wow, those Steinberg guys really don't worry too much about compiler warnings. -#if _MSC_VER - #pragma warning (disable: 4505) - #pragma warning (push, 0) - #pragma warning (disable: 4702) -#elif __clang__ - #pragma clang diagnostic push - #pragma clang diagnostic ignored "-Wnon-virtual-dtor" - #pragma clang diagnostic ignored "-Wreorder" - #pragma clang diagnostic ignored "-Wunsequenced" - #pragma clang diagnostic ignored "-Wint-to-pointer-cast" - #pragma clang diagnostic ignored "-Wunused-parameter" - #pragma clang diagnostic ignored "-Wconversion" - #pragma clang diagnostic ignored "-Woverloaded-virtual" - #pragma clang diagnostic ignored "-Wshadow" - #pragma clang diagnostic ignored "-Wdeprecated-register" -#endif - -/* These files come with the Steinberg VST3 SDK - to get them, you'll need to - visit the Steinberg website and agree to whatever is currently required to - get them. - - Then, you'll need to make sure your include path contains your "VST3 SDK" - directory (or whatever you've named it on your machine). The Introjucer has - a special box for setting this path. -*/ -#if JUCE_VST3HEADERS_INCLUDE_HEADERS_ONLY - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include -#else - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - -//============================================================================== -namespace Steinberg -{ - /** Missing IIDs */ - DEF_CLASS_IID (IPluginBase) - DEF_CLASS_IID (IPlugView) - DEF_CLASS_IID (IPlugFrame) - DEF_CLASS_IID (IBStream) - DEF_CLASS_IID (ISizeableStream) - DEF_CLASS_IID (IPluginFactory) - DEF_CLASS_IID (IPluginFactory2) - DEF_CLASS_IID (IPluginFactory3) -} -#endif //JUCE_VST3HEADERS_INCLUDE_HEADERS_ONLY - -#if _MSC_VER - #pragma warning (pop) -#elif __clang__ - #pragma clang diagnostic pop -#endif - -//============================================================================== -#undef ASSERT -#undef WARNING -#undef PRINTSYSERROR -#undef DEBUGSTR -#undef DBPRT0 -#undef DBPRT1 -#undef DBPRT2 -#undef DBPRT3 -#undef DBPRT4 -#undef DBPRT5 -#undef min -#undef max -#undef MIN -#undef MAX -#undef calloc -#undef free -#undef malloc -#undef realloc -#undef NEW -#undef NEWVEC -#undef VERIFY -#undef VERIFY_IS -#undef VERIFY_NOT -#undef META_CREATE_FUNC -#undef CLASS_CREATE_FUNC -#undef SINGLE_CREATE_FUNC -#undef _META_CLASS -#undef _META_CLASS_IFACE -#undef _META_CLASS_SINGLE -#undef META_CLASS -#undef META_CLASS_IFACE -#undef META_CLASS_SINGLE -#undef SINGLETON -#undef OBJ_METHODS -#undef QUERY_INTERFACE -#undef LICENCE_UID -#undef BEGIN_FACTORY -#undef DEF_CLASS -#undef DEF_CLASS1 -#undef DEF_CLASS2 -#undef DEF_CLASS_W -#undef END_FACTORY -#undef Point -#undef Component - -#endif // JUCE_VST3HEADERS_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/format_types/juce_VST3PluginFormat.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/format_types/juce_VST3PluginFormat.cpp deleted file mode 100644 index a7416264c8..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/format_types/juce_VST3PluginFormat.cpp +++ /dev/null @@ -1,2517 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#if JUCE_PLUGINHOST_VST3 - -} // namespace juce - -#if JucePlugin_Build_VST3 - #undef JUCE_VST3HEADERS_INCLUDE_HEADERS_ONLY - #define JUCE_VST3HEADERS_INCLUDE_HEADERS_ONLY 1 -#endif - -#include -#include "juce_VST3Headers.h" - -#undef JUCE_VST3HEADERS_INCLUDE_HEADERS_ONLY - -namespace juce -{ - -#include "juce_VST3Common.h" - -using namespace Steinberg; - -//============================================================================== -struct VST3Classes -{ - -#ifndef JUCE_VST3_DEBUGGING - #define JUCE_VST3_DEBUGGING 0 -#endif - -#if JUCE_VST3_DEBUGGING - #define VST3_DBG(a) Logger::writeToLog (a); -#else - #define VST3_DBG(a) -#endif - -#if JUCE_DEBUG -static int warnOnFailure (int result) -{ - const char* message = "Unknown result!"; - - switch (result) - { - case kResultOk: return result; - case kNotImplemented: message = "kNotImplemented"; break; - case kNoInterface: message = "kNoInterface"; break; - case kResultFalse: message = "kResultFalse"; break; - case kInvalidArgument: message = "kInvalidArgument"; break; - case kInternalError: message = "kInternalError"; break; - case kNotInitialized: message = "kNotInitialized"; break; - case kOutOfMemory: message = "kOutOfMemory"; break; - default: break; - } - - DBG (message); - return result; -} -#else - #define warnOnFailure(x) x -#endif - -//============================================================================== -static int getHashForTUID (const TUID& tuid) noexcept -{ - int value = 0; - - for (int i = 0; i < numElementsInArray (tuid); ++i) - value = (value * 31) + tuid[i]; - - return value; -} - -template -static void fillDescriptionWith (PluginDescription& description, ObjectType& object) -{ - description.version = toString (object.version).trim(); - description.category = toString (object.subCategories).trim(); - - if (description.manufacturerName.trim().isEmpty()) - description.manufacturerName = toString (object.vendor).trim(); -} - -static void createPluginDescription (PluginDescription& description, - const File& pluginFile, const String& company, const String& name, - const PClassInfo& info, PClassInfo2* info2, PClassInfoW* infoW, - int numInputs, int numOutputs) -{ - description.fileOrIdentifier = pluginFile.getFullPathName(); - description.lastFileModTime = pluginFile.getLastModificationTime(); - description.manufacturerName = company; - description.name = name; - description.descriptiveName = name; - description.pluginFormatName = "VST3"; - description.numInputChannels = numInputs; - description.numOutputChannels = numOutputs; - description.uid = getHashForTUID (info.cid); - - if (infoW != nullptr) fillDescriptionWith (description, *infoW); - else if (info2 != nullptr) fillDescriptionWith (description, *info2); - - if (description.category.isEmpty()) - description.category = toString (info.category).trim(); - - description.isInstrument = description.category.containsIgnoreCase ("Instrument"); // This seems to be the only way to find that out! ARGH! -} - -static int getNumSingleDirectionBussesFor (Vst::IComponent* component, - bool checkInputs, - bool checkAudioChannels) -{ - jassert (component != nullptr); - - return (int) component->getBusCount (checkAudioChannels ? Vst::kAudio : Vst::kEvent, - checkInputs ? Vst::kInput : Vst::kOutput); -} - -/** Gives the total number of channels for a particular type of bus direction and media type */ -static int getNumSingleDirectionChannelsFor (Vst::IComponent* component, - bool checkInputs, - bool checkAudioChannels) -{ - jassert (component != nullptr); - - const Vst::BusDirections direction = checkInputs ? Vst::kInput : Vst::kOutput; - const Vst::MediaTypes mediaType = checkAudioChannels ? Vst::kAudio : Vst::kEvent; - const Steinberg::int32 numBuses = component->getBusCount (mediaType, direction); - - int numChannels = 0; - - for (Steinberg::int32 i = numBuses; --i >= 0;) - { - Vst::BusInfo busInfo; - warnOnFailure (component->getBusInfo (mediaType, direction, i, busInfo)); - numChannels += (int) busInfo.channelCount; - } - - return numChannels; -} - -static void setStateForAllBussesOfType (Vst::IComponent* component, - bool state, - bool activateInputs, - bool activateAudioChannels) -{ - jassert (component != nullptr); - - const Vst::BusDirections direction = activateInputs ? Vst::kInput : Vst::kOutput; - const Vst::MediaTypes mediaType = activateAudioChannels ? Vst::kAudio : Vst::kEvent; - const Steinberg::int32 numBuses = component->getBusCount (mediaType, direction); - - for (Steinberg::int32 i = numBuses; --i >= 0;) - warnOnFailure (component->activateBus (mediaType, direction, i, state)); -} - -//============================================================================== -/** Assigns a complete AudioSampleBuffer's channels to an AudioBusBuffers' */ -static void associateWholeBufferTo (Vst::AudioBusBuffers& vstBuffers, AudioSampleBuffer& buffer) noexcept -{ - vstBuffers.channelBuffers32 = buffer.getArrayOfWritePointers(); - vstBuffers.numChannels = buffer.getNumChannels(); - vstBuffers.silenceFlags = 0; -} - -//============================================================================== -static void toProcessContext (Vst::ProcessContext& context, AudioPlayHead* playHead, double sampleRate) -{ - jassert (sampleRate > 0.0); //Must always be valid, as stated by the VST3 SDK - - using namespace Vst; - - zerostruct (context); - context.sampleRate = sampleRate; - - if (playHead != nullptr) - { - AudioPlayHead::CurrentPositionInfo position; - playHead->getCurrentPosition (position); - - context.projectTimeSamples = position.timeInSamples; //Must always be valid, as stated by the VST3 SDK - context.projectTimeMusic = position.timeInSeconds; //Does not always need to be valid... - context.tempo = position.bpm; - context.timeSigNumerator = position.timeSigNumerator; - context.timeSigDenominator = position.timeSigDenominator; - context.barPositionMusic = position.ppqPositionOfLastBarStart; - context.cycleStartMusic = position.ppqLoopStart; - context.cycleEndMusic = position.ppqLoopEnd; - - switch (position.frameRate) - { - case AudioPlayHead::fps24: context.frameRate.framesPerSecond = 24; break; - case AudioPlayHead::fps25: context.frameRate.framesPerSecond = 25; break; - case AudioPlayHead::fps30: context.frameRate.framesPerSecond = 30; break; - - case AudioPlayHead::fps2997: - case AudioPlayHead::fps2997drop: - case AudioPlayHead::fps30drop: - { - context.frameRate.framesPerSecond = 30; - context.frameRate.flags = FrameRate::kDropRate; - - if (position.frameRate == AudioPlayHead::fps2997drop) - context.frameRate.flags |= FrameRate::kPullDownRate; - } - break; - - case AudioPlayHead::fpsUnknown: break; - - default: jassertfalse; break; // New frame rate? - } - - if (position.isPlaying) context.state |= ProcessContext::kPlaying; - if (position.isRecording) context.state |= ProcessContext::kRecording; - if (position.isLooping) context.state |= ProcessContext::kCycleActive; - } - else - { - context.tempo = 120.0; - context.frameRate.framesPerSecond = 30; - context.timeSigNumerator = 4; - context.timeSigDenominator = 4; - } - - if (context.projectTimeMusic >= 0.0) context.state |= ProcessContext::kProjectTimeMusicValid; - if (context.barPositionMusic >= 0.0) context.state |= ProcessContext::kBarPositionValid; - if (context.tempo > 0.0) context.state |= ProcessContext::kTempoValid; - if (context.frameRate.framesPerSecond > 0) context.state |= ProcessContext::kSmpteValid; - - if (context.cycleStartMusic >= 0.0 - && context.cycleEndMusic > 0.0 - && context.cycleEndMusic > context.cycleStartMusic) - { - context.state |= ProcessContext::kCycleValid; - } - - if (context.timeSigNumerator > 0 && context.timeSigDenominator > 0) - context.state |= ProcessContext::kTimeSigValid; -} - -//============================================================================== -/** Get a list of speaker arrangements as per their speaker names - - (e.g.: 2 regular channels, aliased as 'kStringStereoS', is "L R") -*/ -static StringArray getSpeakerArrangements() -{ - using namespace Vst::SpeakerArr; - - const Vst::CString arrangements[] = - { - kStringMonoS, kStringStereoS, kStringStereoRS, kStringStereoCS, - kStringStereoSS, kStringStereoCLfeS, kString30CineS, kString30MusicS, - kString31CineS, kString31MusicS, kString40CineS, kString40MusicS, - kString41CineS, kString41MusicS, kString50S, kString51S, - kString60CineS, kString60MusicS, kString61CineS, kString61MusicS, - kString70CineS, kString70MusicS, kString71CineS, kString71MusicS, - kString80CineS, kString80MusicS, kString81CineS, kString81MusicS, - kString80CubeS, kStringBFormat1stOrderS, kString71CineTopCenterS, - kString71CineCenterHighS, kString71CineFrontHighS, kString71CineSideHighS, - kString71CineFullRearS, kString90S, kString91S, - kString100S, kString101S, kString110S, kString111S, - kString130S, kString131S, kString102S, kString122S, - nullptr - }; - - return StringArray (arrangements); -} - -/** Get a list of speaker arrangements as per their named configurations - - (e.g.: 2 regular channels, aliased as 'kStringStereoS', is "L R") -*/ -static StringArray getNamedSpeakerArrangements() -{ - using namespace Vst::SpeakerArr; - - const Vst::CString arrangements[] = - { - kStringEmpty, kStringMono, kStringStereo, kStringStereoR, - kStringStereoC, kStringStereoSide, kStringStereoCLfe, kString30Cine, - kString30Music, kString31Cine, kString31Music, kString40Cine, - kString40Music, kString41Cine, kString41Music, kString50, - kString51, kString60Cine, kString60Music, kString61Cine, - kString61Music, kString70Cine, kString70Music, kString71Cine, - kString71Music, kString71CineTopCenter, kString71CineCenterHigh, - kString71CineFrontHigh, kString71CineSideHigh, kString71CineFullRear, - kString80Cine, kString80Music, kString80Cube, kString81Cine, - kString81Music, kString102, kString122, kString90, - kString91, kString100, kString101, kString110, - kString111, kString130, kString131, - nullptr - }; - - return StringArray (arrangements); -} - -static Vst::SpeakerArrangement getSpeakerArrangementFrom (const String& string) -{ - return Vst::SpeakerArr::getSpeakerArrangementFromString (string.toUTF8()); -} - -//============================================================================== -static StringArray getPluginEffectCategories() -{ - using namespace Vst::PlugType; - - const Vst::CString categories[] = - { - kFxAnalyzer, kFxDelay, kFxDistortion, kFxDynamics, - kFxEQ, kFxFilter, kFx, kFxInstrument, - kFxInstrumentExternal, kFxSpatial, kFxGenerator, kFxMastering, - kFxModulation, kFxPitchShift, kFxRestoration, kFxReverb, - kFxSurround, kFxTools, kSpatial, kSpatialFx, - nullptr - }; - - return StringArray (categories); -} - -static StringArray getPluginInstrumentCategories() -{ - using namespace Vst::PlugType; - - const Vst::CString categories[] = - { - kInstrumentSynthSampler, kInstrumentDrum, - kInstrumentSampler, kInstrumentSynth, - kInstrumentExternal, kFxInstrument, - kFxInstrumentExternal, kFxSpatial, - kFxGenerator, - nullptr - }; - - return StringArray (categories); -} - -//============================================================================== -class VST3PluginInstance; - -class VST3HostContext : public Vst::IComponentHandler, // From VST V3.0.0 - public Vst::IComponentHandler2, // From VST V3.1.0 (a very well named class, of course!) - public Vst::IComponentHandler3, // From VST V3.5.0 (also very well named!) - public Vst::IContextMenuTarget, - public Vst::IHostApplication, - public Vst::IParamValueQueue, - public Vst::IUnitHandler -{ -public: - VST3HostContext (VST3PluginInstance* pluginInstance) : owner (pluginInstance) - { - appName = File::getSpecialLocation (File::currentApplicationFile).getFileNameWithoutExtension(); - attributeList = new AttributeList (this); - } - - virtual ~VST3HostContext() {} - - JUCE_DECLARE_VST3_COM_REF_METHODS - - FUnknown* getFUnknown() { return static_cast (this); } - - static bool hasFlag (Steinberg::int32 source, Steinberg::int32 flag) noexcept - { - return (source & flag) == flag; - } - - //============================================================================== - tresult PLUGIN_API beginEdit (Vst::ParamID paramID) override - { - const int index = getIndexOfParamID (paramID); - - if (index < 0) - return kResultFalse; - - owner->beginParameterChangeGesture (index); - return kResultTrue; - } - - tresult PLUGIN_API performEdit (Vst::ParamID paramID, Vst::ParamValue valueNormalized) override - { - const int index = getIndexOfParamID (paramID); - - if (index < 0) - return kResultFalse; - - owner->sendParamChangeMessageToListeners (index, (float) valueNormalized); - return owner->editController->setParamNormalized (paramID, valueNormalized); - } - - tresult PLUGIN_API endEdit (Vst::ParamID paramID) override - { - const int index = getIndexOfParamID (paramID); - - if (index < 0) - return kResultFalse; - - owner->endParameterChangeGesture (index); - return kResultTrue; - } - - tresult PLUGIN_API restartComponent (Steinberg::int32 flags) override - { - if (owner != nullptr) - { - if (hasFlag (flags, Vst::kReloadComponent)) - owner->reset(); - - if (hasFlag (flags, Vst::kIoChanged)) - { - const double sampleRate = owner->getSampleRate(); - const int blockSize = owner->getBlockSize(); - - owner->prepareToPlay (sampleRate >= 8000 ? sampleRate : 44100.0, - blockSize > 0 ? blockSize : 1024); - } - - if (hasFlag (flags, Vst::kLatencyChanged)) - if (owner->processor != nullptr) - owner->setLatencySamples (jmax (0, (int) owner->processor->getLatencySamples())); - - owner->updateHostDisplay(); - return kResultTrue; - } - - jassertfalse; - return kResultFalse; - } - - //============================================================================== - tresult PLUGIN_API setDirty (TBool) override - { - return kResultFalse; - } - - tresult PLUGIN_API requestOpenEditor (FIDString name) override - { - (void) name; - jassertfalse; - return kResultFalse; - } - - tresult PLUGIN_API startGroupEdit() override - { - jassertfalse; - return kResultFalse; - } - - tresult PLUGIN_API finishGroupEdit() override - { - jassertfalse; - return kResultFalse; - } - - //============================================================================== - class ContextMenu : public Vst::IContextMenu - { - public: - ContextMenu (VST3PluginInstance& pluginInstance) : owner (pluginInstance) {} - virtual ~ContextMenu() {} - - JUCE_DECLARE_VST3_COM_REF_METHODS - JUCE_DECLARE_VST3_COM_QUERY_METHODS - - Steinberg::int32 PLUGIN_API getItemCount() override { return (Steinberg::int32) items.size(); } - - tresult PLUGIN_API addItem (const Item& item, IContextMenuTarget* target) override - { - jassert (target != nullptr); - - ItemAndTarget newItem; - newItem.item = item; - newItem.target = target; - - items.add (newItem); - return kResultOk; - } - - tresult PLUGIN_API removeItem (const Item& toRemove, IContextMenuTarget* target) override - { - for (int i = items.size(); --i >= 0;) - { - ItemAndTarget& item = items.getReference(i); - - if (item.item.tag == toRemove.tag && item.target == target) - items.remove (i); - } - - return kResultOk; - } - - tresult PLUGIN_API getItem (Steinberg::int32 tag, Item& result, IContextMenuTarget** target) override - { - for (int i = 0; i < items.size(); ++i) - { - const ItemAndTarget& item = items.getReference(i); - - if (item.item.tag == tag) - { - result = item.item; - - if (target != nullptr) - *target = item.target; - - return kResultTrue; - } - } - - zerostruct (result); - return kResultFalse; - } - - tresult PLUGIN_API popup (Steinberg::UCoord x, Steinberg::UCoord y) override - { - Array subItemStack; - OwnedArray menuStack; - PopupMenu* topLevelMenu = menuStack.add (new PopupMenu()); - - for (int i = 0; i < items.size(); ++i) - { - const Item& item = items.getReference (i).item; - - PopupMenu* menuToUse = menuStack.getLast(); - - if (hasFlag (item.flags, Item::kIsGroupStart & ~Item::kIsDisabled)) - { - subItemStack.add (&item); - menuStack.add (new PopupMenu()); - } - else if (hasFlag (item.flags, Item::kIsGroupEnd)) - { - if (const Item* subItem = subItemStack.getLast()) - { - if (PopupMenu* m = menuStack [menuStack.size() - 2]) - m->addSubMenu (toString (subItem->name), *menuToUse, - ! hasFlag (subItem->flags, Item::kIsDisabled), - nullptr, - hasFlag (subItem->flags, Item::kIsChecked)); - - menuStack.removeLast (1); - subItemStack.removeLast (1); - } - } - else if (hasFlag (item.flags, Item::kIsSeparator)) - { - menuToUse->addSeparator(); - } - else - { - menuToUse->addItem (item.tag != 0 ? (int) item.tag : (int) zeroTagReplacement, - toString (item.name), - ! hasFlag (item.flags, Item::kIsDisabled), - hasFlag (item.flags, Item::kIsChecked)); - } - } - - PopupMenu::Options options; - - if (AudioProcessorEditor* ed = owner.getActiveEditor()) - options = options.withTargetScreenArea (ed->getScreenBounds().translated ((int) x, (int) y).withSize (1, 1)); - - #if JUCE_MODAL_LOOPS_PERMITTED - // Unfortunately, Steinberg's docs explicitly say this should be modal.. - handleResult (topLevelMenu->showMenu (options)); - #else - topLevelMenu->showMenuAsync (options, ModalCallbackFunction::create (menuFinished, ComSmartPtr (this))); - #endif - - return kResultOk; - } - - #if ! JUCE_MODAL_LOOPS_PERMITTED - static void menuFinished (int modalResult, ComSmartPtr menu) { menu->handleResult (modalResult); } - #endif - - private: - enum { zeroTagReplacement = 0x7fffffff }; - - Atomic refCount; - VST3PluginInstance& owner; - - struct ItemAndTarget - { - Item item; - ComSmartPtr target; - }; - - Array items; - - void handleResult (int result) - { - if (result == 0) - return; - - if (result == zeroTagReplacement) - result = 0; - - for (int i = 0; i < items.size(); ++i) - { - const ItemAndTarget& item = items.getReference(i); - - if ((int) item.item.tag == result) - { - if (item.target != nullptr) - item.target->executeMenuItem ((Steinberg::int32) result); - - break; - } - } - } - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ContextMenu) - }; - - Vst::IContextMenu* PLUGIN_API createContextMenu (IPlugView*, const Vst::ParamID*) override - { - if (owner != nullptr) - return new ContextMenu (*owner); - - return nullptr; - } - - tresult PLUGIN_API executeMenuItem (Steinberg::int32) override - { - jassertfalse; - return kResultFalse; - } - - //============================================================================== - tresult PLUGIN_API getName (Vst::String128 name) override - { - Steinberg::String str (appName.toUTF8()); - str.copyTo (name, 0, 127); - return kResultOk; - } - - tresult PLUGIN_API createInstance (TUID cid, TUID iid, void** obj) override - { - *obj = nullptr; - - if (! doUIDsMatch (cid, iid)) - { - jassertfalse; - return kInvalidArgument; - } - - if (doUIDsMatch (cid, Vst::IMessage::iid) && doUIDsMatch (iid, Vst::IMessage::iid)) - { - ComSmartPtr m (new Message (*this, attributeList)); - messageQueue.add (m); - m->addRef(); - *obj = m; - return kResultOk; - } - else if (doUIDsMatch (cid, Vst::IAttributeList::iid) && doUIDsMatch (iid, Vst::IAttributeList::iid)) - { - ComSmartPtr l (new AttributeList (this)); - l->addRef(); - *obj = l; - return kResultOk; - } - - jassertfalse; - return kNotImplemented; - } - - //============================================================================== - Vst::ParamID PLUGIN_API getParameterId() override - { - jassertfalse; - return 0; - } - - Steinberg::int32 PLUGIN_API getPointCount() override - { - jassertfalse; - return 0; - } - - tresult PLUGIN_API getPoint (Steinberg::int32, Steinberg::int32&, Vst::ParamValue&) override - { - jassertfalse; - return kResultFalse; - } - - tresult PLUGIN_API addPoint (Steinberg::int32, Vst::ParamValue, Steinberg::int32&) override - { - jassertfalse; - return kResultFalse; - } - - //============================================================================== - tresult PLUGIN_API notifyUnitSelection (Vst::UnitID) override - { - jassertfalse; - return kResultFalse; - } - - tresult PLUGIN_API notifyProgramListChange (Vst::ProgramListID, Steinberg::int32) override - { - jassertfalse; - return kResultFalse; - } - - //============================================================================== - tresult PLUGIN_API queryInterface (const TUID iid, void** obj) override - { - if (doUIDsMatch (iid, Vst::IAttributeList::iid)) - { - *obj = attributeList.get(); - return kResultOk; - } - - TEST_FOR_AND_RETURN_IF_VALID (iid, Vst::IComponentHandler) - TEST_FOR_AND_RETURN_IF_VALID (iid, Vst::IComponentHandler2) - TEST_FOR_AND_RETURN_IF_VALID (iid, Vst::IComponentHandler3) - TEST_FOR_AND_RETURN_IF_VALID (iid, Vst::IContextMenuTarget) - TEST_FOR_AND_RETURN_IF_VALID (iid, Vst::IHostApplication) - TEST_FOR_AND_RETURN_IF_VALID (iid, Vst::IParamValueQueue) - TEST_FOR_AND_RETURN_IF_VALID (iid, Vst::IUnitHandler) - TEST_FOR_COMMON_BASE_AND_RETURN_IF_VALID (iid, FUnknown, Vst::IComponentHandler) - - *obj = nullptr; - return kNotImplemented; - } - -private: - //============================================================================== - VST3PluginInstance* const owner; - Atomic refCount; - String appName; - - typedef std::map ParamMapType; - ParamMapType paramToIndexMap; - - int getIndexOfParamID (Vst::ParamID paramID) - { - if (owner == nullptr || owner->editController == nullptr) - return -1; - - int result = getMappedParamID (paramID); - - if (result < 0) - { - const int numParams = owner->editController->getParameterCount(); - - for (int i = 0; i < numParams; ++i) - { - Vst::ParameterInfo paramInfo; - owner->editController->getParameterInfo (i, paramInfo); - paramToIndexMap[paramInfo.id] = i; - } - - result = getMappedParamID (paramID); - } - - return result; - } - - int getMappedParamID (Vst::ParamID paramID) - { - const ParamMapType::iterator it (paramToIndexMap.find (paramID)); - return it != paramToIndexMap.end() ? it->second : -1; - } - - //============================================================================== - class Message : public Vst::IMessage - { - public: - Message (VST3HostContext& o, Vst::IAttributeList* list) - : owner (o), attributeList (list) - { - } - - Message (VST3HostContext& o, Vst::IAttributeList* list, FIDString id) - : owner (o), attributeList (list), messageId (toString (id)) - { - } - - Message (VST3HostContext& o, Vst::IAttributeList* list, FIDString id, const var& v) - : value (v), owner (o), attributeList (list), messageId (toString (id)) - { - } - - virtual ~Message() {} - - JUCE_DECLARE_VST3_COM_REF_METHODS - JUCE_DECLARE_VST3_COM_QUERY_METHODS - - FIDString PLUGIN_API getMessageID() override { return messageId.toRawUTF8(); } - void PLUGIN_API setMessageID (FIDString id) override { messageId = toString (id); } - Vst::IAttributeList* PLUGIN_API getAttributes() override { return attributeList; } - - var value; - - private: - VST3HostContext& owner; - ComSmartPtr attributeList; - String messageId; - Atomic refCount; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Message) - }; - - Array, CriticalSection> messageQueue; - - //============================================================================== - class AttributeList : public Vst::IAttributeList - { - public: - AttributeList (VST3HostContext* o) : owner (o) {} - virtual ~AttributeList() {} - - JUCE_DECLARE_VST3_COM_REF_METHODS - JUCE_DECLARE_VST3_COM_QUERY_METHODS - - //============================================================================== - tresult PLUGIN_API setInt (AttrID id, Steinberg::int64 value) override - { - jassert (id != nullptr); - - if (! setValueForId (id, value)) - owner->messageQueue.add (ComSmartPtr (new Message (*owner, this, id, value))); - - return kResultTrue; - } - - tresult PLUGIN_API setFloat (AttrID id, double value) override - { - jassert (id != nullptr); - - if (! setValueForId (id, value)) - owner->messageQueue.add (ComSmartPtr (new Message (*owner, this, id, value))); - - return kResultTrue; - } - - tresult PLUGIN_API setString (AttrID id, const Vst::TChar* string) override - { - jassert (id != nullptr); - jassert (string != nullptr); - - const String text (toString (string)); - - if (! setValueForId (id, text)) - owner->messageQueue.add (ComSmartPtr (new Message (*owner, this, id, text))); - - return kResultTrue; - } - - tresult PLUGIN_API setBinary (AttrID id, const void* data, Steinberg::uint32 size) override - { - jassert (id != nullptr); - jassert (data != nullptr && size > 0); - - MemoryBlock block (data, (size_t) size); - - if (! setValueForId (id, block)) - owner->messageQueue.add (ComSmartPtr (new Message (*owner, this, id, block))); - - return kResultTrue; - } - - //============================================================================== - tresult PLUGIN_API getInt (AttrID id, Steinberg::int64& result) override - { - jassert (id != nullptr); - - if (fetchValueForId (id, result)) - return kResultTrue; - - jassertfalse; - return kResultFalse; - } - - tresult PLUGIN_API getFloat (AttrID id, double& result) override - { - jassert (id != nullptr); - - if (fetchValueForId (id, result)) - return kResultTrue; - - jassertfalse; - return kResultFalse; - } - - tresult PLUGIN_API getString (AttrID id, Vst::TChar* result, Steinberg::uint32 length) override - { - jassert (id != nullptr); - - String stringToFetch; - if (fetchValueForId (id, stringToFetch)) - { - Steinberg::String str (stringToFetch.toRawUTF8()); - str.copyTo (result, 0, (Steinberg::int32) jmin (length, (Steinberg::uint32) std::numeric_limits::max())); - - return kResultTrue; - } - - jassertfalse; - return kResultFalse; - } - - tresult PLUGIN_API getBinary (AttrID id, const void*& data, Steinberg::uint32& size) override - { - jassert (id != nullptr); - - for (int i = owner->messageQueue.size(); --i >= 0;) - { - Message* const message = owner->messageQueue.getReference (i); - - if (std::strcmp (message->getMessageID(), id) == 0) - { - if (MemoryBlock* binaryData = message->value.getBinaryData()) - { - data = binaryData->getData(); - size = (Steinberg::uint32) binaryData->getSize(); - return kResultTrue; - } - } - } - - return kResultFalse; - } - - private: - VST3HostContext* owner; - Atomic refCount; - - //============================================================================== - template - bool setValueForId (AttrID id, const Type& value) - { - jassert (id != nullptr); - - for (int i = owner->messageQueue.size(); --i >= 0;) - { - VST3HostContext::Message* const message = owner->messageQueue.getReference (i); - - if (std::strcmp (message->getMessageID(), id) == 0) - { - message->value = value; - return true; - } - } - - return false; // No message found with that Id - } - - template - bool fetchValueForId (AttrID id, Type& value) - { - jassert (id != nullptr); - - for (int i = owner->messageQueue.size(); --i >= 0;) - { - VST3HostContext::Message* const message = owner->messageQueue.getReference (i); - - if (std::strcmp (message->getMessageID(), id) == 0) - { - value = message->value; - return true; - } - } - - return false; - } - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AttributeList) - }; - - ComSmartPtr attributeList; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (VST3HostContext) -}; - -//============================================================================== -class DescriptionFactory -{ -public: - DescriptionFactory (VST3HostContext* host, IPluginFactory* pluginFactory) - : vst3HostContext (host), factory (pluginFactory) - { - jassert (pluginFactory != nullptr); - } - - virtual ~DescriptionFactory() {} - - Result findDescriptionsAndPerform (const File& file) - { - StringArray foundNames; - PFactoryInfo factoryInfo; - factory->getFactoryInfo (&factoryInfo); - const String companyName (toString (factoryInfo.vendor).trim()); - - Result result (Result::ok()); - - const Steinberg::int32 numClasses = factory->countClasses(); - - for (Steinberg::int32 i = 0; i < numClasses; ++i) - { - PClassInfo info; - factory->getClassInfo (i, &info); - - if (std::strcmp (info.category, kVstAudioEffectClass) != 0) - continue; - - const String name (toString (info.name).trim()); - - if (foundNames.contains (name, true)) - continue; - - ScopedPointer info2; - ScopedPointer infoW; - - { - ComSmartPtr pf2; - ComSmartPtr pf3; - - if (pf2.loadFrom (factory)) - { - info2 = new PClassInfo2(); - pf2->getClassInfo2 (i, info2); - } - - if (pf3.loadFrom (factory)) - { - infoW = new PClassInfoW(); - pf3->getClassInfoUnicode (i, infoW); - } - } - - foundNames.add (name); - - PluginDescription desc; - - { - ComSmartPtr component; - - if (component.loadFrom (factory, info.cid)) - { - if (component->initialize (vst3HostContext->getFUnknown()) == kResultOk) - { - const int numInputs = getNumSingleDirectionChannelsFor (component, true, true); - const int numOutputs = getNumSingleDirectionChannelsFor (component, false, true); - - createPluginDescription (desc, file, companyName, name, - info, info2, infoW, numInputs, numOutputs); - - component->terminate(); - } - else - { - jassertfalse; - } - } - else - { - jassertfalse; - } - } - - result = performOnDescription (desc); - - if (result.failed()) - break; - } - - return result; - } - -protected: - virtual Result performOnDescription (PluginDescription& description) = 0; - -private: - ComSmartPtr vst3HostContext; - ComSmartPtr factory; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (DescriptionFactory) -}; - -struct MatchingDescriptionFinder : public DescriptionFactory -{ - MatchingDescriptionFinder (VST3HostContext* host, IPluginFactory* pluginFactory, const PluginDescription& desc) - : DescriptionFactory (host, pluginFactory), description (desc) - { - } - - static const char* getSuccessString() noexcept { return "Found Description"; } - - Result performOnDescription (PluginDescription& desc) - { - if (description.isDuplicateOf (desc)) - return Result::fail (getSuccessString()); - - return Result::ok(); - } - -private: - const PluginDescription& description; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MatchingDescriptionFinder) -}; - -struct DescriptionLister : public DescriptionFactory -{ - DescriptionLister (VST3HostContext* host, IPluginFactory* pluginFactory) - : DescriptionFactory (host, pluginFactory) - { - } - - Result performOnDescription (PluginDescription& desc) - { - list.add (new PluginDescription (desc)); - return Result::ok(); - } - - OwnedArray list; - -private: - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (DescriptionLister) -}; - -//============================================================================== -struct DLLHandle -{ - DLLHandle (const String& modulePath) - : factory (nullptr) - { - if (modulePath.trim().isNotEmpty()) - open (modulePath); - } - - ~DLLHandle() - { - typedef bool (PLUGIN_API *ExitModuleFn) (); - - #if JUCE_WINDOWS - if (ExitModuleFn exitFn = (ExitModuleFn) getFunction ("ExitDll")) - exitFn(); - - releaseFactory(); - library.close(); - - #else - if (bundleRef != nullptr) - { - if (ExitModuleFn exitFn = (ExitModuleFn) getFunction ("bundleExit")) - exitFn(); - - releaseFactory(); - - CFRelease (bundleRef); - bundleRef = nullptr; - } - #endif - } - - void open (const PluginDescription& description) - { - #if JUCE_WINDOWS - jassert (description.fileOrIdentifier.isNotEmpty()); - jassert (File (description.fileOrIdentifier).existsAsFile()); - library.open (description.fileOrIdentifier); - #else - open (description.fileOrIdentifier); - #endif - } - - /** @note The factory should begin with a refCount of 1, - so don't increment the reference count - (ie: don't use a ComSmartPtr in here)! - Its lifetime will be handled by this DllHandle, - when such will be destroyed. - - @see releaseFactory - */ - IPluginFactory* JUCE_CALLTYPE getPluginFactory() - { - if (factory == nullptr) - if (GetFactoryProc proc = (GetFactoryProc) getFunction ("GetPluginFactory")) - factory = proc(); - - jassert (factory != nullptr); // The plugin NEEDS to provide a factory to be able to be called a VST3! - return factory; - } - - void* getFunction (const char* functionName) - { - #if JUCE_WINDOWS - return library.getFunction (functionName); - #else - if (bundleRef == nullptr) - return nullptr; - - CFStringRef name = String (functionName).toCFString(); - void* fn = CFBundleGetFunctionPointerForName (bundleRef, name); - CFRelease (name); - return fn; - #endif - } - -private: - IPluginFactory* factory; - - void releaseFactory() - { - if (factory != nullptr) - factory->release(); - } - - #if JUCE_WINDOWS - DynamicLibrary library; - - bool open (const String& filePath) - { - if (library.open (filePath)) - { - typedef bool (PLUGIN_API *InitModuleProc) (); - if (InitModuleProc proc = (InitModuleProc) getFunction ("InitDll")) - { - if (proc()) - return true; - } - else - { - return true; - } - - library.close(); - } - - return false; - } - - #else - CFBundleRef bundleRef; - - bool open (const String& filePath) - { - const File file (filePath); - const char* const utf8 = file.getFullPathName().toRawUTF8(); - - if (CFURLRef url = CFURLCreateFromFileSystemRepresentation (0, (const UInt8*) utf8, (CFIndex) std::strlen (utf8), file.isDirectory())) - { - bundleRef = CFBundleCreate (kCFAllocatorDefault, url); - CFRelease (url); - - if (bundleRef != nullptr) - { - CFErrorRef error = nullptr; - - if (CFBundleLoadExecutableAndReturnError (bundleRef, &error)) - { - typedef bool (*BundleEntryProc)(CFBundleRef); - - if (BundleEntryProc proc = (BundleEntryProc) getFunction ("bundleEntry")) - { - if (proc (bundleRef)) - return true; - } - else - { - return true; - } - } - - if (error != nullptr) - { - if (CFStringRef failureMessage = CFErrorCopyFailureReason (error)) - { - DBG (String::fromCFString (failureMessage)); - CFRelease (failureMessage); - } - - CFRelease (error); - } - - CFRelease (bundleRef); - bundleRef = nullptr; - } - } - - return false; - } - #endif - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (DLLHandle) -}; - -//============================================================================== -class VST3ModuleHandle : public ReferenceCountedObject -{ -public: - explicit VST3ModuleHandle (const File& pluginFile) : file (pluginFile) - { - getActiveModules().add (this); - } - - ~VST3ModuleHandle() - { - getActiveModules().removeFirstMatchingValue (this); - } - - /** - Since there is no apparent indication if a VST3 plugin is a shell or not, - we're stuck iterating through a VST3's factory, creating a description - for every housed plugin. - */ - static bool getAllDescriptionsForFile (OwnedArray& results, - const String& fileOrIdentifier) - { - DLLHandle tempModule (fileOrIdentifier); - - ComSmartPtr pluginFactory (tempModule.getPluginFactory()); - - if (pluginFactory != nullptr) - { - ComSmartPtr host (new VST3HostContext (nullptr)); - DescriptionLister lister (host, pluginFactory); - const Result result (lister.findDescriptionsAndPerform (File (fileOrIdentifier))); - - results.addCopiesOf (lister.list); - - return result.wasOk(); - } - - jassertfalse; - return false; - } - - //============================================================================== - typedef ReferenceCountedObjectPtr Ptr; - - static VST3ModuleHandle::Ptr findOrCreateModule (const File& file, const PluginDescription& description) - { - Array& activeModules = getActiveModules(); - - for (int i = activeModules.size(); --i >= 0;) - { - VST3ModuleHandle* const module = activeModules.getUnchecked (i); - - // VST3s are basically shells, you must therefore check their name along with their file: - if (module->file == file && module->name == description.name) - return module; - } - - VST3ModuleHandle::Ptr m (new VST3ModuleHandle (file)); - - if (! m->open (file, description)) - m = nullptr; - - return m; - } - - //============================================================================== - IPluginFactory* getPluginFactory() { return dllHandle->getPluginFactory(); } - - File file; - String name; - -private: - ScopedPointer dllHandle; - - //============================================================================== - static Array& getActiveModules() - { - static Array activeModules; - return activeModules; - } - - //============================================================================== - bool open (const File& f, const PluginDescription& description) - { - dllHandle = new DLLHandle (f.getFullPathName()); - - ComSmartPtr pluginFactory (dllHandle->getPluginFactory()); - - if (pluginFactory != nullptr) - { - ComSmartPtr host (new VST3HostContext (nullptr)); - MatchingDescriptionFinder finder (host, pluginFactory, description); - - const Result result (finder.findDescriptionsAndPerform (f)); - - if (result.getErrorMessage() == MatchingDescriptionFinder::getSuccessString()) - { - name = description.name; - return true; - } - } - - return false; - } - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (VST3ModuleHandle) -}; - -//============================================================================== -class VST3PluginWindow : public AudioProcessorEditor, - public ComponentMovementWatcher, - public IPlugFrame -{ -public: - VST3PluginWindow (AudioProcessor* owner, IPlugView* pluginView) - : AudioProcessorEditor (owner), - ComponentMovementWatcher (this), - refCount (1), - view (pluginView, false), - pluginHandle (nullptr), - recursiveResize (false) - { - setSize (10, 10); - setOpaque (true); - setVisible (true); - - warnOnFailure (view->setFrame (this)); - - ViewRect rect; - warnOnFailure (view->getSize (&rect)); - resizeWithRect (*this, rect); - } - - ~VST3PluginWindow() - { - warnOnFailure (view->removed()); - warnOnFailure (view->setFrame (nullptr)); - - processor.editorBeingDeleted (this); - - #if JUCE_MAC - dummyComponent.setView (nullptr); - #endif - - view = nullptr; - } - - JUCE_DECLARE_VST3_COM_REF_METHODS - JUCE_DECLARE_VST3_COM_QUERY_METHODS - - void paint (Graphics& g) override - { - g.fillAll (Colours::black); - } - - void mouseWheelMove (const MouseEvent&, const MouseWheelDetails& wheel) override - { - view->onWheel (wheel.deltaY); - } - - void focusGained (FocusChangeType) override { view->onFocus (true); } - void focusLost (FocusChangeType) override { view->onFocus (false); } - - /** It seems that most, if not all, plugins do their own keyboard hooks, - but IPlugView does have a set of keyboard related methods... - */ - bool keyStateChanged (bool /*isKeyDown*/) override { return true; } - bool keyPressed (const KeyPress& /*key*/) override { return true; } - - //============================================================================== - void componentMovedOrResized (bool, bool wasResized) override - { - if (recursiveResize) - return; - - Component* const topComp = getTopLevelComponent(); - - if (topComp->getPeer() != nullptr) - { - #if JUCE_WINDOWS - const Point pos (topComp->getLocalPoint (this, Point())); - #endif - - recursiveResize = true; - - ViewRect rect; - - if (wasResized && view->canResize() == kResultTrue) - { - rect.right = (Steinberg::int32) getWidth(); - rect.bottom = (Steinberg::int32) getHeight(); - view->checkSizeConstraint (&rect); - - setSize ((int) rect.getWidth(), (int) rect.getHeight()); - - #if JUCE_WINDOWS - SetWindowPos (pluginHandle, 0, - pos.x, pos.y, rect.getWidth(), rect.getHeight(), - isVisible() ? SWP_SHOWWINDOW : SWP_HIDEWINDOW); - #elif JUCE_MAC - dummyComponent.setBounds (getLocalBounds()); - #endif - - view->onSize (&rect); - } - else - { - warnOnFailure (view->getSize (&rect)); - - #if JUCE_WINDOWS - SetWindowPos (pluginHandle, 0, - pos.x, pos.y, rect.getWidth(), rect.getHeight(), - isVisible() ? SWP_SHOWWINDOW : SWP_HIDEWINDOW); - #elif JUCE_MAC - dummyComponent.setBounds (0, 0, (int) rect.getWidth(), (int) rect.getHeight()); - #endif - } - - // Some plugins don't update their cursor correctly when mousing out the window - Desktop::getInstance().getMainMouseSource().forceMouseCursorUpdate(); - - recursiveResize = false; - } - } - - void componentPeerChanged() override { } - - void componentVisibilityChanged() override - { - attachPluginWindow(); - componentMovedOrResized (true, true); - } - - tresult PLUGIN_API resizeView (IPlugView* incomingView, ViewRect* newSize) override - { - if (incomingView != nullptr - && newSize != nullptr - && incomingView == view) - { - resizeWithRect (dummyComponent, *newSize); - setSize (dummyComponent.getWidth(), dummyComponent.getHeight()); - return kResultTrue; - } - - jassertfalse; - return kInvalidArgument; - } - -private: - //============================================================================== - Atomic refCount; - ComSmartPtr view; - - #if JUCE_WINDOWS - class ChildComponent : public Component - { - public: - ChildComponent() {} - void paint (Graphics& g) override { g.fillAll (Colours::cornflowerblue); } - - using Component::createNewPeer; - - private: - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ChildComponent) - }; - - ChildComponent dummyComponent; - ScopedPointer peer; - typedef HWND HandleFormat; - #elif JUCE_MAC - AutoResizingNSViewComponentWithParent dummyComponent; - typedef NSView* HandleFormat; - #else - Component dummyComponent; - typedef void* HandleFormat; - #endif - - HandleFormat pluginHandle; - bool recursiveResize; - - //============================================================================== - static void resizeWithRect (Component& comp, const ViewRect& rect) - { - comp.setBounds ((int) rect.left, (int) rect.top, - jmax (10, std::abs ((int) rect.getWidth())), - jmax (10, std::abs ((int) rect.getHeight()))); - } - - void attachPluginWindow() - { - if (pluginHandle == nullptr) - { - #if JUCE_WINDOWS - if (Component* topComp = getTopLevelComponent()) - peer = dummyComponent.createNewPeer (0, topComp->getWindowHandle()); - else - peer = nullptr; - - if (peer != nullptr) - pluginHandle = (HandleFormat) peer->getNativeHandle(); - #elif JUCE_MAC - dummyComponent.setBounds (getLocalBounds()); - addAndMakeVisible (dummyComponent); - pluginHandle = (NSView*) dummyComponent.getView(); - jassert (pluginHandle != nil); - #endif - - if (pluginHandle != nullptr) - warnOnFailure (view->attached (pluginHandle, defaultVST3WindowType)); - } - } - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (VST3PluginWindow) -}; - -//============================================================================== -class VST3PluginInstance : public AudioPluginInstance -{ -public: - VST3PluginInstance (const VST3ModuleHandle::Ptr& handle) - : module (handle), - numInputAudioBusses (0), - numOutputAudioBusses (0), - inputParameterChanges (new ParameterChangeList()), - outputParameterChanges (new ParameterChangeList()), - midiInputs (new MidiEventList()), - midiOutputs (new MidiEventList()), - isComponentInitialised (false), - isControllerInitialised (false), - isActive (false) - { - host = new VST3HostContext (this); - } - - ~VST3PluginInstance() - { - jassert (getActiveEditor() == nullptr); // You must delete any editors before deleting the plugin instance! - - releaseResources(); - - if (editControllerConnection != nullptr && componentConnection != nullptr) - { - editControllerConnection->disconnect (componentConnection); - componentConnection->disconnect (editControllerConnection); - } - - editController->setComponentHandler (nullptr); - - if (isControllerInitialised) editController->terminate(); - if (isComponentInitialised) component->terminate(); - - componentConnection = nullptr; - editControllerConnection = nullptr; - unitData = nullptr; - unitInfo = nullptr; - programListData = nullptr; - componentHandler2 = nullptr; - componentHandler = nullptr; - processor = nullptr; - editController2 = nullptr; - editController = nullptr; - component = nullptr; - host = nullptr; - module = nullptr; - } - - bool initialise() - { - #if JUCE_WINDOWS - // On Windows it's highly advisable to create your plugins using the message thread, - // because many plugins need a chance to create HWNDs that will get their messages - // delivered by the main message thread, and that's not possible from a background thread. - jassert (MessageManager::getInstance()->isThisTheMessageThread()); - #endif - - ComSmartPtr factory (module->getPluginFactory()); - - PFactoryInfo factoryInfo; - factory->getFactoryInfo (&factoryInfo); - company = toString (factoryInfo.vendor).trim(); - - if (! fetchComponentAndController (factory, factory->countClasses())) - return false; - - // (May return an error if the plugin combines the IComponent and IEditController implementations) - editController->initialize (host->getFUnknown()); - - isControllerInitialised = true; - editController->setComponentHandler (host); - grabInformationObjects(); - synchroniseStates(); - interconnectComponentAndController(); - setupIO(); - return true; - } - - //============================================================================== - void fillInPluginDescription (PluginDescription& description) const override - { - jassert (module != nullptr); - - createPluginDescription (description, module->file, - company, module->name, - *info, info2, infoW, - getNumInputChannels(), - getNumOutputChannels()); - } - - void* getPlatformSpecificData() override { return component; } - void refreshParameterList() override {} - - //============================================================================== - const String getName() const override - { - return module != nullptr ? module->name : String::empty; - } - - void repopulateArrangements() - { - inputArrangements.clearQuick(); - outputArrangements.clearQuick(); - - // NB: Some plugins need a valid arrangement despite specifying 0 for their I/O busses - for (int i = 0; i < jmax (1, numInputAudioBusses); ++i) - inputArrangements.add (getArrangementForBus (processor, true, i)); - - for (int i = 0; i < jmax (1, numOutputAudioBusses); ++i) - outputArrangements.add (getArrangementForBus (processor, false, i)); - } - - void prepareToPlay (double sampleRate, int estimatedSamplesPerBlock) override - { - // Avoid redundantly calling things like setActive, which can be a heavy-duty call for some plugins: - if (isActive - && getSampleRate() == sampleRate - && getBlockSize() == estimatedSamplesPerBlock) - return; - - using namespace Vst; - - ProcessSetup setup; - setup.symbolicSampleSize = kSample32; - setup.maxSamplesPerBlock = estimatedSamplesPerBlock; - setup.sampleRate = sampleRate; - setup.processMode = isNonRealtime() ? kOffline : kRealtime; - - warnOnFailure (processor->setupProcessing (setup)); - - if (! isComponentInitialised) - isComponentInitialised = component->initialize (host->getFUnknown()) == kResultTrue; - - editController->setComponentHandler (host); - - if (inputArrangements.size() <= 0 || outputArrangements.size() <= 0) - repopulateArrangements(); - - warnOnFailure (processor->setBusArrangements (inputArrangements.getRawDataPointer(), numInputAudioBusses, - outputArrangements.getRawDataPointer(), numOutputAudioBusses)); - - // Update the num. busses in case the configuration has been modified by the plugin. (May affect number of channels!): - const int newNumInputAudioBusses = getNumSingleDirectionBussesFor (component, true, true); - const int newNumOutputAudioBusses = getNumSingleDirectionBussesFor (component, false, true); - - // Repopulate arrangements if the number of busses have changed: - if (numInputAudioBusses != newNumInputAudioBusses - || numOutputAudioBusses != newNumOutputAudioBusses) - { - numInputAudioBusses = newNumInputAudioBusses; - numOutputAudioBusses = newNumOutputAudioBusses; - - repopulateArrangements(); - } - - // Needed for having the same sample rate in processBlock(); some plugins need this! - setPlayConfigDetails (getNumSingleDirectionChannelsFor (component, true, true), - getNumSingleDirectionChannelsFor (component, false, true), - sampleRate, estimatedSamplesPerBlock); - - setStateForAllBusses (true); - - setLatencySamples (jmax (0, (int) processor->getLatencySamples())); - - warnOnFailure (component->setActive (true)); - warnOnFailure (processor->setProcessing (true)); - - isActive = true; - } - - void releaseResources() override - { - if (! isActive) - return; // Avoids redundantly calling things like setActive - - JUCE_TRY - { - isActive = false; - - setStateForAllBusses (false); - - if (processor != nullptr) - warnOnFailure (processor->setProcessing (false)); - - if (component != nullptr) - warnOnFailure (component->setActive (false)); - } - JUCE_CATCH_ALL_ASSERT - } - - void processBlock (AudioSampleBuffer& buffer, MidiBuffer& midiMessages) override - { - using namespace Vst; - - if (isActive - && processor != nullptr - && processor->canProcessSampleSize (kSample32) == kResultTrue) - { - const int numSamples = buffer.getNumSamples(); - - ProcessData data; - data.processMode = isNonRealtime() ? kOffline : kRealtime; - data.symbolicSampleSize = kSample32; - data.numInputs = numInputAudioBusses; - data.numOutputs = numOutputAudioBusses; - data.inputParameterChanges = inputParameterChanges; - data.outputParameterChanges = outputParameterChanges; - data.numSamples = (Steinberg::int32) numSamples; - - updateTimingInformation (data, getSampleRate()); - - for (int i = getNumInputChannels(); i < buffer.getNumChannels(); ++i) - buffer.clear (i, 0, numSamples); - - associateTo (data, buffer); - associateTo (data, midiMessages); - - processor->process (data); - - MidiEventList::toMidiBuffer (midiMessages, *midiOutputs); - } - } - - //============================================================================== - String getChannelName (int channelIndex, bool forInput, bool forAudioChannel) const - { - const int numBusses = getNumSingleDirectionBussesFor (component, forInput, forAudioChannel); - int numCountedChannels = 0; - - for (int i = 0; i < numBusses; ++i) - { - Vst::BusInfo busInfo (getBusInfo (forInput, forAudioChannel, i)); - - numCountedChannels += busInfo.channelCount; - - if (channelIndex < numCountedChannels) - return toString (busInfo.name); - } - - return String::empty; - } - - const String getInputChannelName (int channelIndex) const override { return getChannelName (channelIndex, true, true); } - const String getOutputChannelName (int channelIndex) const override { return getChannelName (channelIndex, false, true); } - - bool isInputChannelStereoPair (int channelIndex) const override - { - if (channelIndex < 0 || channelIndex >= getNumInputChannels()) - return false; - - return getBusInfo (true, true).channelCount == 2; - } - - bool isOutputChannelStereoPair (int channelIndex) const override - { - if (channelIndex < 0 || channelIndex >= getNumOutputChannels()) - return false; - - return getBusInfo (false, true).channelCount == 2; - } - - bool acceptsMidi() const override { return getBusInfo (true, false).channelCount > 0; } - bool producesMidi() const override { return getBusInfo (false, false).channelCount > 0; } - - //============================================================================== - bool silenceInProducesSilenceOut() const override - { - if (processor != nullptr) - return processor->getTailSamples() == Vst::kNoTail; - - return true; - } - - /** May return a negative value as a means of informing us that the plugin has "infinite tail," or 0 for "no tail." */ - double getTailLengthSeconds() const override - { - if (processor != nullptr) - { - const double sampleRate = getSampleRate(); - - if (sampleRate > 0.0) - return jlimit (0, 0x7fffffff, (int) processor->getTailSamples()) / sampleRate; - } - - return 0.0; - } - - //============================================================================== - AudioProcessorEditor* createEditor() override - { - if (IPlugView* view = tryCreatingView()) - return new VST3PluginWindow (this, view); - - return nullptr; - } - - bool hasEditor() const override - { - // (if possible, avoid creating a second instance of the editor, because that crashes some plugins) - if (getActiveEditor() != nullptr) - return true; - - ComSmartPtr view (tryCreatingView(), false); - return view != nullptr; - } - - //============================================================================== - int getNumParameters() override - { - if (editController != nullptr) - return (int) editController->getParameterCount(); - - return 0; - } - - const String getParameterName (int parameterIndex) override - { - return toString (getParameterInfoForIndex (parameterIndex).title); - } - - float getParameter (int parameterIndex) override - { - if (editController != nullptr) - { - const uint32 id = getParameterInfoForIndex (parameterIndex).id; - return (float) editController->getParamNormalized (id); - } - - return 0.0f; - } - - const String getParameterText (int parameterIndex) override - { - if (editController != nullptr) - { - const uint32 id = getParameterInfoForIndex (parameterIndex).id; - - Vst::String128 result; - warnOnFailure (editController->getParamStringByValue (id, editController->getParamNormalized (id), result)); - - return toString (result); - } - - return String::empty; - } - - void setParameter (int parameterIndex, float newValue) override - { - if (editController != nullptr) - { - const uint32 id = getParameterInfoForIndex (parameterIndex).id; - editController->setParamNormalized (id, (double) newValue); - } - } - - //============================================================================== - int getNumPrograms() override { return getProgramListInfo (0).programCount; } - int getCurrentProgram() override { return 0; } - void setCurrentProgram (int) override {} - void changeProgramName (int, const String&) override {} - - const String getProgramName (int index) override - { - Vst::String128 result; - unitInfo->getProgramName (getProgramListInfo (0).id, index, result); - return toString (result); - } - - //============================================================================== - void reset() override - { - if (component != nullptr) - { - component->setActive (false); - component->setActive (true); - } - } - - //============================================================================== - void getStateInformation (MemoryBlock& destData) override - { - XmlElement state ("VST3PluginState"); - - appendStateFrom (state, component, "IComponent"); - appendStateFrom (state, editController, "IEditController"); - - AudioProcessor::copyXmlToBinary (state, destData); - } - - void setStateInformation (const void* data, int sizeInBytes) override - { - ScopedPointer head (AudioProcessor::getXmlFromBinary (data, sizeInBytes)); - - if (head != nullptr) - { - ComSmartPtr s (createMemoryStreamForState (*head, "IComponent")); - - if (s != nullptr && component != nullptr) - component->setState (s); - - if (editController != nullptr) - { - if (s != nullptr) - editController->setComponentState (s); - - s = createMemoryStreamForState (*head, "IEditController"); - - if (s != nullptr) - editController->setState (s); - } - } - } - - /** @note Not applicable to VST3 */ - void getCurrentProgramStateInformation (MemoryBlock& destData) override - { - destData.setSize (0, true); - } - - /** @note Not applicable to VST3 */ - void setCurrentProgramStateInformation (const void* data, int sizeInBytes) override - { - (void) data; - (void) sizeInBytes; - } - -private: - //============================================================================== - VST3ModuleHandle::Ptr module; - - friend VST3HostContext; - ComSmartPtr host; - - // Information objects: - String company; - ScopedPointer info; - ScopedPointer info2; - ScopedPointer infoW; - - // Rudimentary interfaces: - ComSmartPtr component; - ComSmartPtr editController; - ComSmartPtr editController2; - ComSmartPtr processor; - ComSmartPtr componentHandler; - ComSmartPtr componentHandler2; - ComSmartPtr unitInfo; - ComSmartPtr unitData; - ComSmartPtr programListData; - ComSmartPtr componentConnection; - ComSmartPtr editControllerConnection; - - /** The number of IO busses MUST match that of the plugin, - even if there aren't enough channels to process, - as very poorly specified by the Steinberg SDK - */ - int numInputAudioBusses, numOutputAudioBusses; - Array inputArrangements, outputArrangements; // Caching to improve performance and to avoid possible non-thread-safe calls to getBusArrangements(). - VST3BufferExchange::BusMap inputBusMap, outputBusMap; - Array inputBusses, outputBusses; - - //============================================================================== - template - static void appendStateFrom (XmlElement& head, ComSmartPtr& object, const String& identifier) - { - if (object != nullptr) - { - Steinberg::MemoryStream stream; - - if (object->getState (&stream) == kResultTrue) - { - MemoryBlock info (stream.getData(), (std::size_t) stream.getSize()); - head.createNewChildElement (identifier)->addTextElement (info.toBase64Encoding()); - } - } - } - - static Steinberg::MemoryStream* createMemoryStreamForState (XmlElement& head, StringRef identifier) - { - Steinberg::MemoryStream* stream = nullptr; - - if (XmlElement* const state = head.getChildByName (identifier)) - { - MemoryBlock mem; - - if (mem.fromBase64Encoding (state->getAllSubText())) - { - stream = new Steinberg::MemoryStream(); - stream->setSize ((TSize) mem.getSize()); - mem.copyTo (stream->getData(), 0, mem.getSize()); - } - } - - return stream; - } - - //============================================================================== - class ParameterChangeList : public Vst::IParameterChanges - { - public: - ParameterChangeList() {} - virtual ~ParameterChangeList() {} - - JUCE_DECLARE_VST3_COM_REF_METHODS - JUCE_DECLARE_VST3_COM_QUERY_METHODS - - Steinberg::int32 PLUGIN_API getParameterCount() override { return 0; } - - Vst::IParamValueQueue* PLUGIN_API getParameterData (Steinberg::int32) override - { - return nullptr; - } - - Vst::IParamValueQueue* PLUGIN_API addParameterData (const Vst::ParamID&, Steinberg::int32& index) override - { - index = 0; - return nullptr; - } - - private: - Atomic refCount; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ParameterChangeList) - }; - - ComSmartPtr inputParameterChanges, outputParameterChanges; - ComSmartPtr midiInputs, midiOutputs; - Vst::ProcessContext timingInfo; //< Only use this in processBlock()! - bool isComponentInitialised, isControllerInitialised, isActive; - - //============================================================================== - bool fetchComponentAndController (IPluginFactory* factory, const Steinberg::int32 numClasses) - { - jassert (numClasses >= 0); // The plugin must provide at least an IComponent and IEditController! - - for (Steinberg::int32 j = 0; j < numClasses; ++j) - { - info = new PClassInfo(); - factory->getClassInfo (j, info); - - if (std::strcmp (info->category, kVstAudioEffectClass) != 0) - continue; - - const String name (toString (info->name).trim()); - - if (module->name != name) - continue; - - { - ComSmartPtr pf2; - ComSmartPtr pf3; - - if (pf2.loadFrom (factory)) - { - info2 = new PClassInfo2(); - pf2->getClassInfo2 (j, info2); - } - else - { - info2 = nullptr; - } - - if (pf3.loadFrom (factory)) - { - pf3->setHostContext (host->getFUnknown()); - infoW = new PClassInfoW(); - pf3->getClassInfoUnicode (j, infoW); - } - else - { - infoW = nullptr; - } - } - - bool failed = true; - - if (component.loadFrom (factory, info->cid) && component != nullptr) - { - warnOnFailure (component->setIoMode (isNonRealtime() ? Vst::kOffline : Vst::kRealtime)); - - if (warnOnFailure (component->initialize (host->getFUnknown())) != kResultOk) - return false; - - isComponentInitialised = true; - - // Get the IEditController: - TUID controllerCID = { 0 }; - - if (component->getControllerClassId (controllerCID) == kResultTrue && FUID (controllerCID).isValid()) - editController.loadFrom (factory, controllerCID); - - if (editController == nullptr) - { - // Try finding the IEditController the long way around: - for (Steinberg::int32 i = 0; i < numClasses; ++i) - { - PClassInfo classInfo; - factory->getClassInfo (i, &classInfo); - - if (std::strcmp (classInfo.category, kVstComponentControllerClass) == 0) - editController.loadFrom (factory, classInfo.cid); - } - } - - if (editController == nullptr) - editController.loadFrom (component); - - failed = editController == nullptr; - } - - if (failed) - { - jassertfalse; // The plugin won't function without a valid IComponent and IEditController implementation! - - if (component != nullptr) - { - component->terminate(); - component = nullptr; - } - - if (editController != nullptr) - { - editController->terminate(); - editController = nullptr; - } - - break; - } - - return true; - } - - return false; - } - - /** Some plugins need to be "connected" to intercommunicate between their implemented classes */ - void interconnectComponentAndController() - { - componentConnection.loadFrom (component); - editControllerConnection.loadFrom (editController); - - if (componentConnection != nullptr && editControllerConnection != nullptr) - { - warnOnFailure (editControllerConnection->connect (componentConnection)); - warnOnFailure (componentConnection->connect (editControllerConnection)); - } - } - - void synchroniseStates() - { - Steinberg::MemoryStream stream; - - if (component->getState (&stream) == kResultTrue) - if (stream.seek (0, Steinberg::IBStream::kIBSeekSet, nullptr) == kResultTrue) - warnOnFailure (editController->setComponentState (&stream)); - } - - void grabInformationObjects() - { - processor.loadFrom (component); - unitInfo.loadFrom (component); - programListData.loadFrom (component); - unitData.loadFrom (component); - editController2.loadFrom (component); - componentHandler.loadFrom (component); - componentHandler2.loadFrom (component); - - if (processor == nullptr) processor.loadFrom (editController); - if (unitInfo == nullptr) unitInfo.loadFrom (editController); - if (programListData == nullptr) programListData.loadFrom (editController); - if (unitData == nullptr) unitData.loadFrom (editController); - if (editController2 == nullptr) editController2.loadFrom (editController); - if (componentHandler == nullptr) componentHandler.loadFrom (editController); - if (componentHandler2 == nullptr) componentHandler2.loadFrom (editController); - } - - void setStateForAllBusses (bool newState) - { - setStateForAllBussesOfType (component, newState, true, true); // Activate/deactivate audio inputs - setStateForAllBussesOfType (component, newState, false, true); // Activate/deactivate audio outputs - setStateForAllBussesOfType (component, newState, true, false); // Activate/deactivate MIDI inputs - setStateForAllBussesOfType (component, newState, false, false); // Activate/deactivate MIDI outputs - } - - void setupIO() - { - setStateForAllBusses (true); - - Vst::ProcessSetup setup; - setup.symbolicSampleSize = Vst::kSample32; - setup.maxSamplesPerBlock = 1024; - setup.sampleRate = 44100.0; - setup.processMode = Vst::kRealtime; - - warnOnFailure (processor->setupProcessing (setup)); - - numInputAudioBusses = getNumSingleDirectionBussesFor (component, true, true); - numOutputAudioBusses = getNumSingleDirectionBussesFor (component, false, true); - - setPlayConfigDetails (getNumSingleDirectionChannelsFor (component, true, true), - getNumSingleDirectionChannelsFor (component, false, true), - setup.sampleRate, (int) setup.maxSamplesPerBlock); - } - - //============================================================================== - Vst::BusInfo getBusInfo (bool forInput, bool forAudio, int index = 0) const - { - Vst::BusInfo busInfo; - busInfo.mediaType = forAudio ? Vst::kAudio : Vst::kEvent; - busInfo.direction = forInput ? Vst::kInput : Vst::kOutput; - - component->getBusInfo (busInfo.mediaType, busInfo.direction, - (Steinberg::int32) index, busInfo); - return busInfo; - } - - //============================================================================== - /** @note An IPlugView, when first created, should start with a ref-count of 1! */ - IPlugView* tryCreatingView() const - { - IPlugView* v = editController->createView (Vst::ViewType::kEditor); - - if (v == nullptr) v = editController->createView (nullptr); - if (v == nullptr) editController->queryInterface (IPlugView::iid, (void**) &v); - - return v; - } - - //============================================================================== - void associateTo (Vst::ProcessData& destination, AudioSampleBuffer& buffer) - { - using namespace VST3BufferExchange; - - mapBufferToBusses (inputBusses, inputBusMap, inputArrangements, buffer); - mapBufferToBusses (outputBusses, outputBusMap, outputArrangements, buffer); - - destination.inputs = inputBusses.getRawDataPointer(); - destination.outputs = outputBusses.getRawDataPointer(); - } - - void associateTo (Vst::ProcessData& destination, MidiBuffer& midiBuffer) - { - midiInputs->clear(); - midiOutputs->clear(); - - MidiEventList::toEventList (*midiInputs, midiBuffer); - - destination.inputEvents = midiInputs; - destination.outputEvents = midiOutputs; - } - - void updateTimingInformation (Vst::ProcessData& destination, double processSampleRate) - { - toProcessContext (timingInfo, getPlayHead(), processSampleRate); - destination.processContext = &timingInfo; - } - - Vst::ParameterInfo getParameterInfoForIndex (int index) const - { - Vst::ParameterInfo paramInfo = { 0 }; - - if (processor != nullptr) - editController->getParameterInfo (index, paramInfo); - - return paramInfo; - } - - Vst::ProgramListInfo getProgramListInfo (int index) const - { - Vst::ProgramListInfo paramInfo = { 0 }; - - if (unitInfo != nullptr) - unitInfo->getProgramListInfo (index, paramInfo); - - return paramInfo; - } - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (VST3PluginInstance) -}; - -}; - -//============================================================================== -VST3PluginFormat::VST3PluginFormat() {} -VST3PluginFormat::~VST3PluginFormat() {} - -void VST3PluginFormat::findAllTypesForFile (OwnedArray& results, const String& fileOrIdentifier) -{ - if (! fileMightContainThisPluginType (fileOrIdentifier)) - return; - - VST3Classes::VST3ModuleHandle::getAllDescriptionsForFile (results, fileOrIdentifier); -} - -AudioPluginInstance* VST3PluginFormat::createInstanceFromDescription (const PluginDescription& description, double, int) -{ - ScopedPointer result; - - if (fileMightContainThisPluginType (description.fileOrIdentifier)) - { - File file (description.fileOrIdentifier); - - const File previousWorkingDirectory (File::getCurrentWorkingDirectory()); - file.getParentDirectory().setAsCurrentWorkingDirectory(); - - if (const VST3Classes::VST3ModuleHandle::Ptr module = VST3Classes::VST3ModuleHandle::findOrCreateModule (file, description)) - { - result = new VST3Classes::VST3PluginInstance (module); - - if (! result->initialise()) - result = nullptr; - } - - previousWorkingDirectory.setAsCurrentWorkingDirectory(); - } - - return result.release(); -} - -bool VST3PluginFormat::fileMightContainThisPluginType (const String& fileOrIdentifier) -{ - const File f (File::createFileWithoutCheckingPath (fileOrIdentifier)); - - return f.hasFileExtension (".vst3") - #if JUCE_MAC - && f.exists(); - #else - && f.existsAsFile(); - #endif -} - -String VST3PluginFormat::getNameOfPluginFromIdentifier (const String& fileOrIdentifier) -{ - return fileOrIdentifier; //Impossible to tell because every VST3 is a type of shell... -} - -bool VST3PluginFormat::pluginNeedsRescanning (const PluginDescription& description) -{ - return File (description.fileOrIdentifier).getLastModificationTime() != description.lastFileModTime; -} - -bool VST3PluginFormat::doesPluginStillExist (const PluginDescription& description) -{ - return File (description.fileOrIdentifier).exists(); -} - -StringArray VST3PluginFormat::searchPathsForPlugins (const FileSearchPath& directoriesToSearch, const bool recursive) -{ - StringArray results; - - for (int i = 0; i < directoriesToSearch.getNumPaths(); ++i) - recursiveFileSearch (results, directoriesToSearch[i], recursive); - - return results; -} - -void VST3PluginFormat::recursiveFileSearch (StringArray& results, const File& directory, const bool recursive) -{ - DirectoryIterator iter (directory, false, "*", File::findFilesAndDirectories); - - while (iter.next()) - { - const File f (iter.getFile()); - bool isPlugin = false; - - if (fileMightContainThisPluginType (f.getFullPathName())) - { - isPlugin = true; - results.add (f.getFullPathName()); - } - - if (recursive && (! isPlugin) && f.isDirectory()) - recursiveFileSearch (results, f, true); - } -} - -FileSearchPath VST3PluginFormat::getDefaultLocationsToSearch() -{ - #if JUCE_WINDOWS - const String programFiles (File::getSpecialLocation (File::globalApplicationsDirectory).getFullPathName()); - return FileSearchPath (programFiles + "\\Common Files\\VST3"); - #elif JUCE_MAC - return FileSearchPath ("/Library/Audio/Plug-Ins/VST3;~/Library/Audio/Plug-Ins/VST3"); - #else - return FileSearchPath(); - #endif -} - -#endif //JUCE_PLUGINHOST_VST3 diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/format_types/juce_VST3PluginFormat.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/format_types/juce_VST3PluginFormat.h deleted file mode 100644 index 308ff5ab13..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/format_types/juce_VST3PluginFormat.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_VST3PLUGINFORMAT_H_INCLUDED -#define JUCE_VST3PLUGINFORMAT_H_INCLUDED - -#if JUCE_PLUGINHOST_VST3 -/** - Implements a plugin format for VST3s. -*/ -class JUCE_API VST3PluginFormat : public AudioPluginFormat -{ -public: - /** Constructor */ - VST3PluginFormat(); - - /** Destructor */ - ~VST3PluginFormat(); - - //============================================================================== - /** @internal */ - String getName() const override { return "VST3"; } - /** @internal */ - void findAllTypesForFile (OwnedArray& results, const String& fileOrIdentifier) override; - /** @internal */ - AudioPluginInstance* createInstanceFromDescription (const PluginDescription& description, double, int) override; - /** @internal */ - bool fileMightContainThisPluginType (const String& fileOrIdentifier) override; - /** @internal */ - String getNameOfPluginFromIdentifier (const String& fileOrIdentifier) override; - /** @internal */ - bool pluginNeedsRescanning (const PluginDescription& description) override; - /** @internal */ - StringArray searchPathsForPlugins (const FileSearchPath& searchPath, bool recursive) override; - /** @internal */ - bool doesPluginStillExist (const PluginDescription& description) override; - /** @internal */ - FileSearchPath getDefaultLocationsToSearch() override; - /** @internal */ - bool canScanForPlugins() const override { return true; } - -private: - //============================================================================== - void recursiveFileSearch (StringArray&, const File&, bool recursive); - - //============================================================================== - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (VST3PluginFormat) -}; - -#endif // JUCE_PLUGINHOST_VST3 -#endif // JUCE_VST3PLUGINFORMAT_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/format_types/juce_VSTMidiEventList.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/format_types/juce_VSTMidiEventList.h deleted file mode 100644 index f442eab855..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/format_types/juce_VSTMidiEventList.h +++ /dev/null @@ -1,187 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifdef __aeffect__ // NB: this must come first, *before* the header-guard. - -#ifndef JUCE_VSTMIDIEVENTLIST_H_INCLUDED -#define JUCE_VSTMIDIEVENTLIST_H_INCLUDED - -//============================================================================== -/** Holds a set of VSTMidiEvent objects and makes it easy to add - events to the list. - - This is used by both the VST hosting code and the plugin wrapper. -*/ -class VSTMidiEventList -{ -public: - //============================================================================== - VSTMidiEventList() - : numEventsUsed (0), numEventsAllocated (0) - { - } - - ~VSTMidiEventList() - { - freeEvents(); - } - - //============================================================================== - void clear() - { - numEventsUsed = 0; - - if (events != nullptr) - events->numEvents = 0; - } - - void addEvent (const void* const midiData, const int numBytes, const int frameOffset) - { - ensureSize (numEventsUsed + 1); - - VstMidiEvent* const e = (VstMidiEvent*) (events->events [numEventsUsed]); - events->numEvents = ++numEventsUsed; - - if (numBytes <= 4) - { - if (e->type == kVstSysExType) - { - delete[] (((VstMidiSysexEvent*) e)->sysexDump); - e->type = kVstMidiType; - e->byteSize = sizeof (VstMidiEvent); - e->noteLength = 0; - e->noteOffset = 0; - e->detune = 0; - e->noteOffVelocity = 0; - } - - e->deltaFrames = frameOffset; - memcpy (e->midiData, midiData, (size_t) numBytes); - } - else - { - VstMidiSysexEvent* const se = (VstMidiSysexEvent*) e; - - if (se->type == kVstSysExType) - delete[] se->sysexDump; - - se->sysexDump = new char [numBytes]; - memcpy (se->sysexDump, midiData, (size_t) numBytes); - - se->type = kVstSysExType; - se->byteSize = sizeof (VstMidiSysexEvent); - se->deltaFrames = frameOffset; - se->flags = 0; - se->dumpBytes = numBytes; - se->resvd1 = 0; - se->resvd2 = 0; - } - } - - //============================================================================== - // Handy method to pull the events out of an event buffer supplied by the host - // or plugin. - static void addEventsToMidiBuffer (const VstEvents* events, MidiBuffer& dest) - { - for (int i = 0; i < events->numEvents; ++i) - { - const VstEvent* const e = events->events[i]; - - if (e != nullptr) - { - if (e->type == kVstMidiType) - { - dest.addEvent ((const juce::uint8*) ((const VstMidiEvent*) e)->midiData, - 4, e->deltaFrames); - } - else if (e->type == kVstSysExType) - { - dest.addEvent ((const juce::uint8*) ((const VstMidiSysexEvent*) e)->sysexDump, - (int) ((const VstMidiSysexEvent*) e)->dumpBytes, - e->deltaFrames); - } - } - } - } - - //============================================================================== - void ensureSize (int numEventsNeeded) - { - if (numEventsNeeded > numEventsAllocated) - { - numEventsNeeded = (numEventsNeeded + 32) & ~31; - - const size_t size = 20 + sizeof (VstEvent*) * (size_t) numEventsNeeded; - - if (events == nullptr) - events.calloc (size, 1); - else - events.realloc (size, 1); - - for (int i = numEventsAllocated; i < numEventsNeeded; ++i) - events->events[i] = allocateVSTEvent(); - - numEventsAllocated = numEventsNeeded; - } - } - - void freeEvents() - { - if (events != nullptr) - { - for (int i = numEventsAllocated; --i >= 0;) - freeVSTEvent (events->events[i]); - - events.free(); - numEventsUsed = 0; - numEventsAllocated = 0; - } - } - - //============================================================================== - HeapBlock events; - -private: - int numEventsUsed, numEventsAllocated; - - static VstEvent* allocateVSTEvent() - { - VstEvent* const e = (VstEvent*) std::calloc (1, sizeof (VstMidiEvent) > sizeof (VstMidiSysexEvent) ? sizeof (VstMidiEvent) - : sizeof (VstMidiSysexEvent)); - e->type = kVstMidiType; - e->byteSize = sizeof (VstMidiEvent); - return e; - } - - static void freeVSTEvent (VstEvent* e) - { - if (e->type == kVstSysExType) - delete[] (((VstMidiSysexEvent*) e)->sysexDump); - - std::free (e); - } -}; - -#endif // JUCE_VSTMIDIEVENTLIST_H_INCLUDED -#endif diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp deleted file mode 100644 index 5509e2c384..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp +++ /dev/null @@ -1,2889 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#if JUCE_PLUGINHOST_VST - -//============================================================================== -#if JUCE_MAC && JUCE_SUPPORT_CARBON - #include "../../juce_gui_extra/native/juce_mac_CarbonViewWrapperComponent.h" -#endif - -//============================================================================== -#undef PRAGMA_ALIGN_SUPPORTED -#define VST_FORCE_DEPRECATED 0 - -#if JUCE_MSVC - #pragma warning (push) - #pragma warning (disable: 4996) -#elif ! JUCE_MINGW - #define __cdecl -#endif - -/* Obviously you're going to need the Steinberg vstsdk2.4 folder in - your include path if you want to add VST support. - - If you're not interested in VSTs, you can disable them by setting the - JUCE_PLUGINHOST_VST flag to 0. -*/ -#include "pluginterfaces/vst2.x/aeffectx.h" - -#if JUCE_MSVC - #pragma warning (pop) - #pragma warning (disable: 4355) // ("this" used in initialiser list warning) -#endif - -//============================================================================== -#include "juce_VSTMidiEventList.h" - -#if JUCE_MINGW - #ifndef WM_APPCOMMAND - #define WM_APPCOMMAND 0x0319 - #endif - - extern "C" void _fpreset(); - extern "C" void _clearfp(); -#elif ! JUCE_WINDOWS - static void _fpreset() {} - static void _clearfp() {} -#endif - -#ifndef JUCE_VST_WRAPPER_LOAD_CUSTOM_MAIN - #define JUCE_VST_WRAPPER_LOAD_CUSTOM_MAIN -#endif - -#ifndef JUCE_VST_WRAPPER_INVOKE_MAIN - #define JUCE_VST_WRAPPER_INVOKE_MAIN effect = module->moduleMain (&audioMaster); -#endif - -//============================================================================== -namespace -{ - const int fxbVersionNum = 1; - - struct fxProgram - { - VstInt32 chunkMagic; // 'CcnK' - VstInt32 byteSize; // of this chunk, excl. magic + byteSize - VstInt32 fxMagic; // 'FxCk' - VstInt32 version; - VstInt32 fxID; // fx unique id - VstInt32 fxVersion; - VstInt32 numParams; - char prgName[28]; - float params[1]; // variable no. of parameters - }; - - struct fxSet - { - VstInt32 chunkMagic; // 'CcnK' - VstInt32 byteSize; // of this chunk, excl. magic + byteSize - VstInt32 fxMagic; // 'FxBk' - VstInt32 version; - VstInt32 fxID; // fx unique id - VstInt32 fxVersion; - VstInt32 numPrograms; - char future[128]; - fxProgram programs[1]; // variable no. of programs - }; - - struct fxChunkSet - { - VstInt32 chunkMagic; // 'CcnK' - VstInt32 byteSize; // of this chunk, excl. magic + byteSize - VstInt32 fxMagic; // 'FxCh', 'FPCh', or 'FBCh' - VstInt32 version; - VstInt32 fxID; // fx unique id - VstInt32 fxVersion; - VstInt32 numPrograms; - char future[128]; - VstInt32 chunkSize; - char chunk[8]; // variable - }; - - struct fxProgramSet - { - VstInt32 chunkMagic; // 'CcnK' - VstInt32 byteSize; // of this chunk, excl. magic + byteSize - VstInt32 fxMagic; // 'FxCh', 'FPCh', or 'FBCh' - VstInt32 version; - VstInt32 fxID; // fx unique id - VstInt32 fxVersion; - VstInt32 numPrograms; - char name[28]; - VstInt32 chunkSize; - char chunk[8]; // variable - }; - - static VstInt32 fxbName (const char* name) noexcept { return (VstInt32) ByteOrder::bigEndianInt (name); } - static VstInt32 fxbSwap (const VstInt32 x) noexcept { return (VstInt32) ByteOrder::swapIfLittleEndian ((uint32) x); } - - static float fxbSwapFloat (const float x) noexcept - { - #ifdef JUCE_LITTLE_ENDIAN - union { uint32 asInt; float asFloat; } n; - n.asFloat = x; - n.asInt = ByteOrder::swap (n.asInt); - return n.asFloat; - #else - return x; - #endif - } -} - -//============================================================================== -namespace -{ - static double getVSTHostTimeNanoseconds() noexcept - { - #if JUCE_WINDOWS - return timeGetTime() * 1000000.0; - #elif JUCE_LINUX - timeval micro; - gettimeofday (µ, 0); - return micro.tv_usec * 1000.0; - #elif JUCE_MAC - UnsignedWide micro; - Microseconds (µ); - return micro.lo * 1000.0; - #endif - } - - static int shellUIDToCreate = 0; - static int insideVSTCallback = 0; - - struct IdleCallRecursionPreventer - { - IdleCallRecursionPreventer() : isMessageThread (MessageManager::getInstance()->isThisTheMessageThread()) - { - if (isMessageThread) - ++insideVSTCallback; - } - - ~IdleCallRecursionPreventer() - { - if (isMessageThread) - --insideVSTCallback; - } - - const bool isMessageThread; - JUCE_DECLARE_NON_COPYABLE (IdleCallRecursionPreventer) - }; - - #if JUCE_MAC - static bool makeFSRefFromPath (FSRef* destFSRef, const String& path) - { - return FSPathMakeRef (reinterpret_cast (path.toRawUTF8()), destFSRef, 0) == noErr; - } - #endif - - #if JUCE_MAC && JUCE_PPC - static void* newCFMFromMachO (void* const machofp) noexcept - { - void* result = (void*) new char[8]; - - ((void**) result)[0] = machofp; - ((void**) result)[1] = result; - - return result; - } - #endif -} - -//============================================================================== -typedef AEffect* (VSTCALLBACK *MainCall) (audioMasterCallback); -static VstIntPtr VSTCALLBACK audioMaster (AEffect* effect, VstInt32 opcode, VstInt32 index, VstIntPtr value, void* ptr, float opt); - -//============================================================================== -// Change this to disable logging of various VST activities -#ifndef VST_LOGGING - #define VST_LOGGING 1 -#endif - -#if VST_LOGGING - #define JUCE_VST_LOG(a) Logger::writeToLog(a); -#else - #define JUCE_VST_LOG(a) -#endif - -//============================================================================== -#if JUCE_LINUX - -extern Display* display; -extern XContext windowHandleXContext; - -namespace -{ - static bool xErrorTriggered = false; - - static int temporaryErrorHandler (Display*, XErrorEvent*) - { - xErrorTriggered = true; - return 0; - } - - typedef void (*EventProcPtr) (XEvent* ev); - - static EventProcPtr getPropertyFromXWindow (Window handle, Atom atom) - { - XErrorHandler oldErrorHandler = XSetErrorHandler (temporaryErrorHandler); - xErrorTriggered = false; - - int userSize; - unsigned long bytes, userCount; - unsigned char* data; - Atom userType; - - XGetWindowProperty (display, handle, atom, 0, 1, false, AnyPropertyType, - &userType, &userSize, &userCount, &bytes, &data); - - XSetErrorHandler (oldErrorHandler); - - return (userCount == 1 && ! xErrorTriggered) ? *reinterpret_cast (data) : nullptr; - } - - Window getChildWindow (Window windowToCheck) - { - Window rootWindow, parentWindow; - Window* childWindows; - unsigned int numChildren = 0; - - XQueryTree (display, windowToCheck, &rootWindow, &parentWindow, &childWindows, &numChildren); - - if (numChildren > 0) - return childWindows [0]; - - return 0; - } - - static void translateJuceToXButtonModifiers (const MouseEvent& e, XEvent& ev) noexcept - { - if (e.mods.isLeftButtonDown()) - { - ev.xbutton.button = Button1; - ev.xbutton.state |= Button1Mask; - } - else if (e.mods.isRightButtonDown()) - { - ev.xbutton.button = Button3; - ev.xbutton.state |= Button3Mask; - } - else if (e.mods.isMiddleButtonDown()) - { - ev.xbutton.button = Button2; - ev.xbutton.state |= Button2Mask; - } - } - - static void translateJuceToXMotionModifiers (const MouseEvent& e, XEvent& ev) noexcept - { - if (e.mods.isLeftButtonDown()) ev.xmotion.state |= Button1Mask; - else if (e.mods.isRightButtonDown()) ev.xmotion.state |= Button3Mask; - else if (e.mods.isMiddleButtonDown()) ev.xmotion.state |= Button2Mask; - } - - static void translateJuceToXCrossingModifiers (const MouseEvent& e, XEvent& ev) noexcept - { - if (e.mods.isLeftButtonDown()) ev.xcrossing.state |= Button1Mask; - else if (e.mods.isRightButtonDown()) ev.xcrossing.state |= Button3Mask; - else if (e.mods.isMiddleButtonDown()) ev.xcrossing.state |= Button2Mask; - } - - static void translateJuceToXMouseWheelModifiers (const MouseEvent& e, const float increment, XEvent& ev) noexcept - { - if (increment < 0) - { - ev.xbutton.button = Button5; - ev.xbutton.state |= Button5Mask; - } - else if (increment > 0) - { - ev.xbutton.button = Button4; - ev.xbutton.state |= Button4Mask; - } - } -} - -#endif - -//============================================================================== -class ModuleHandle : public ReferenceCountedObject -{ -public: - //============================================================================== - File file; - MainCall moduleMain, customMain; - String pluginName; - ScopedPointer vstXml; - - typedef ReferenceCountedObjectPtr Ptr; - - static Array& getActiveModules() - { - static Array activeModules; - return activeModules; - } - - //============================================================================== - static ModuleHandle* findOrCreateModule (const File& file) - { - for (int i = getActiveModules().size(); --i >= 0;) - { - ModuleHandle* const module = getActiveModules().getUnchecked(i); - - if (module->file == file) - return module; - } - - _fpreset(); // (doesn't do any harm) - - const IdleCallRecursionPreventer icrp; - shellUIDToCreate = 0; - - JUCE_VST_LOG ("Attempting to load VST: " + file.getFullPathName()); - - ScopedPointer m (new ModuleHandle (file)); - - if (! m->open()) - m = nullptr; - - _fpreset(); // (doesn't do any harm) - - return m.release(); - } - - //============================================================================== - ModuleHandle (const File& f) - : file (f), moduleMain (nullptr), customMain (nullptr) - #if JUCE_MAC - #if JUCE_PPC - , fragId (0) - #endif - , resHandle (0), bundleRef (0), resFileId (0) - #endif - { - getActiveModules().add (this); - - #if JUCE_WINDOWS || JUCE_LINUX - fullParentDirectoryPathName = f.getParentDirectory().getFullPathName(); - #elif JUCE_MAC - FSRef ref; - makeFSRefFromPath (&ref, f.getParentDirectory().getFullPathName()); - FSGetCatalogInfo (&ref, kFSCatInfoNone, 0, 0, &parentDirFSSpec, 0); - #endif - } - - ~ModuleHandle() - { - getActiveModules().removeFirstMatchingValue (this); - close(); - } - - //============================================================================== -#if JUCE_WINDOWS || JUCE_LINUX - DynamicLibrary module; - String fullParentDirectoryPathName; - - bool open() - { - pluginName = file.getFileNameWithoutExtension(); - - module.open (file.getFullPathName()); - - moduleMain = (MainCall) module.getFunction ("VSTPluginMain"); - - if (moduleMain == nullptr) - moduleMain = (MainCall) module.getFunction ("main"); - - JUCE_VST_WRAPPER_LOAD_CUSTOM_MAIN - - if (moduleMain != nullptr) - { - vstXml = XmlDocument::parse (file.withFileExtension ("vstxml")); - - #if JUCE_WINDOWS - if (vstXml == nullptr) - vstXml = XmlDocument::parse (getDLLResource (file, "VSTXML", 1)); - #endif - } - - return moduleMain != nullptr; - } - - void close() - { - _fpreset(); // (doesn't do any harm) - - module.close(); - } - - void closeEffect (AEffect* eff) - { - eff->dispatcher (eff, effClose, 0, 0, 0, 0); - } - - #if JUCE_WINDOWS - static String getDLLResource (const File& dllFile, const String& type, int resID) - { - DynamicLibrary dll (dllFile.getFullPathName()); - HMODULE dllModule = (HMODULE) dll.getNativeHandle(); - - if (dllModule != INVALID_HANDLE_VALUE) - { - if (HRSRC res = FindResource (dllModule, MAKEINTRESOURCE (resID), type.toWideCharPointer())) - { - if (HGLOBAL hGlob = LoadResource (dllModule, res)) - { - const char* data = static_cast (LockResource (hGlob)); - return String::fromUTF8 (data, SizeofResource (dllModule, res)); - } - } - } - - return String::empty; - } - #endif -#else - #if JUCE_PPC - CFragConnectionID fragId; - #endif - Handle resHandle; - CFBundleRef bundleRef; - FSSpec parentDirFSSpec; - short resFileId; - - bool open() - { - bool ok = false; - - if (file.hasFileExtension (".vst")) - { - const char* const utf8 = file.getFullPathName().toRawUTF8(); - - if (CFURLRef url = CFURLCreateFromFileSystemRepresentation (0, (const UInt8*) utf8, - strlen (utf8), file.isDirectory())) - { - bundleRef = CFBundleCreate (kCFAllocatorDefault, url); - CFRelease (url); - - if (bundleRef != 0) - { - if (CFBundleLoadExecutable (bundleRef)) - { - moduleMain = (MainCall) CFBundleGetFunctionPointerForName (bundleRef, CFSTR("main_macho")); - - if (moduleMain == nullptr) - moduleMain = (MainCall) CFBundleGetFunctionPointerForName (bundleRef, CFSTR("VSTPluginMain")); - - JUCE_VST_WRAPPER_LOAD_CUSTOM_MAIN - - if (moduleMain != nullptr) - { - if (CFTypeRef name = CFBundleGetValueForInfoDictionaryKey (bundleRef, CFSTR("CFBundleName"))) - { - if (CFGetTypeID (name) == CFStringGetTypeID()) - { - char buffer[1024]; - - if (CFStringGetCString ((CFStringRef) name, buffer, sizeof (buffer), CFStringGetSystemEncoding())) - pluginName = buffer; - } - } - - if (pluginName.isEmpty()) - pluginName = file.getFileNameWithoutExtension(); - - resFileId = CFBundleOpenBundleResourceMap (bundleRef); - - ok = true; - - Array vstXmlFiles; - file.getChildFile ("Contents") - .getChildFile ("Resources") - .findChildFiles (vstXmlFiles, File::findFiles, false, "*.vstxml"); - - if (vstXmlFiles.size() > 0) - vstXml = XmlDocument::parse (vstXmlFiles.getReference(0)); - } - } - - if (! ok) - { - CFBundleUnloadExecutable (bundleRef); - CFRelease (bundleRef); - bundleRef = 0; - } - } - } - } - #if JUCE_PPC - else - { - FSRef fn; - - if (FSPathMakeRef ((UInt8*) file.getFullPathName().toRawUTF8(), &fn, 0) == noErr) - { - resFileId = FSOpenResFile (&fn, fsRdPerm); - - if (resFileId != -1) - { - const int numEffs = Count1Resources ('aEff'); - - for (int i = 0; i < numEffs; ++i) - { - resHandle = Get1IndResource ('aEff', i + 1); - - if (resHandle != 0) - { - OSType type; - Str255 name; - SInt16 id; - GetResInfo (resHandle, &id, &type, name); - pluginName = String ((const char*) name + 1, name[0]); - DetachResource (resHandle); - HLock (resHandle); - - ::Ptr ptr; - Str255 errorText; - - OSErr err = GetMemFragment (*resHandle, GetHandleSize (resHandle), - name, kPrivateCFragCopy, - &fragId, &ptr, errorText); - - if (err == noErr) - { - moduleMain = (MainCall) newMachOFromCFM (ptr); - ok = true; - } - else - { - HUnlock (resHandle); - } - - break; - } - } - - if (! ok) - CloseResFile (resFileId); - } - } - } - #endif - - return ok; - } - - void close() - { - #if JUCE_PPC - if (fragId != 0) - { - if (moduleMain != nullptr) - disposeMachOFromCFM ((void*) moduleMain); - - CloseConnection (&fragId); - HUnlock (resHandle); - - if (resFileId != 0) - CloseResFile (resFileId); - } - else - #endif - if (bundleRef != 0) - { - CFBundleCloseBundleResourceMap (bundleRef, resFileId); - - if (CFGetRetainCount (bundleRef) == 1) - CFBundleUnloadExecutable (bundleRef); - - if (CFGetRetainCount (bundleRef) > 0) - CFRelease (bundleRef); - } - } - - void closeEffect (AEffect* eff) - { - #if JUCE_PPC - if (fragId != 0) - { - Array thingsToDelete; - thingsToDelete.add ((void*) eff->dispatcher); - thingsToDelete.add ((void*) eff->process); - thingsToDelete.add ((void*) eff->setParameter); - thingsToDelete.add ((void*) eff->getParameter); - thingsToDelete.add ((void*) eff->processReplacing); - - eff->dispatcher (eff, effClose, 0, 0, 0, 0); - - for (int i = thingsToDelete.size(); --i >= 0;) - disposeMachOFromCFM (thingsToDelete[i]); - } - else - #endif - { - eff->dispatcher (eff, effClose, 0, 0, 0, 0); - } - } - - #if JUCE_PPC - static void* newMachOFromCFM (void* cfmfp) - { - if (cfmfp == 0) - return nullptr; - - UInt32* const mfp = new UInt32[6]; - - mfp[0] = 0x3d800000 | ((UInt32) cfmfp >> 16); - mfp[1] = 0x618c0000 | ((UInt32) cfmfp & 0xffff); - mfp[2] = 0x800c0000; - mfp[3] = 0x804c0004; - mfp[4] = 0x7c0903a6; - mfp[5] = 0x4e800420; - - MakeDataExecutable (mfp, sizeof (UInt32) * 6); - return mfp; - } - - static void disposeMachOFromCFM (void* ptr) - { - delete[] static_cast (ptr); - } - - void coerceAEffectFunctionCalls (AEffect* eff) - { - if (fragId != 0) - { - eff->dispatcher = (AEffectDispatcherProc) newMachOFromCFM ((void*) eff->dispatcher); - eff->process = (AEffectProcessProc) newMachOFromCFM ((void*) eff->process); - eff->setParameter = (AEffectSetParameterProc) newMachOFromCFM ((void*) eff->setParameter); - eff->getParameter = (AEffectGetParameterProc) newMachOFromCFM ((void*) eff->getParameter); - eff->processReplacing = (AEffectProcessProc) newMachOFromCFM ((void*) eff->processReplacing); - } - } - #endif - -#endif - -private: - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ModuleHandle) -}; - -static const int defaultVSTSampleRateValue = 44100; -static const int defaultVSTBlockSizeValue = 512; - -//============================================================================== -//============================================================================== -class VSTPluginInstance : public AudioPluginInstance, - private Timer, - private AsyncUpdater -{ -public: - VSTPluginInstance (const ModuleHandle::Ptr& mh) - : effect (nullptr), - module (mh), - usesCocoaNSView (false), - name (mh->pluginName), - wantsMidiMessages (false), - initialised (false), - isPowerOn (false), - tempBuffer (1, 1) - { - try - { - const IdleCallRecursionPreventer icrp; - _fpreset(); - - JUCE_VST_LOG ("Creating VST instance: " + name); - - #if JUCE_MAC - if (module->resFileId != 0) - UseResFile (module->resFileId); - - #if JUCE_PPC - if (module->fragId != 0) - { - static void* audioMasterCoerced = nullptr; - if (audioMasterCoerced == nullptr) - audioMasterCoerced = newCFMFromMachO ((void*) &audioMaster); - - effect = module->moduleMain ((audioMasterCallback) audioMasterCoerced); - } - else - #endif - #endif - { - JUCE_VST_WRAPPER_INVOKE_MAIN - } - - if (effect != nullptr && effect->magic == kEffectMagic) - { - #if JUCE_PPC - module->coerceAEffectFunctionCalls (effect); - #endif - - jassert (effect->resvd2 == 0); - jassert (effect->object != 0); - - _fpreset(); // some dodgy plugs fuck around with this - } - else - { - effect = nullptr; - } - } - catch (...) - {} - } - - ~VSTPluginInstance() - { - const ScopedLock sl (lock); - - if (effect != nullptr && effect->magic == kEffectMagic) - { - #if JUCE_MAC - if (module->resFileId != 0) - UseResFile (module->resFileId); - #endif - - // Must delete any editors before deleting the plugin instance! - jassert (getActiveEditor() == 0); - - _fpreset(); // some dodgy plugs fuck around with this - - module->closeEffect (effect); - } - - module = nullptr; - effect = nullptr; - } - - void fillInPluginDescription (PluginDescription& desc) const override - { - desc.name = name; - - { - char buffer [512] = { 0 }; - dispatch (effGetEffectName, 0, 0, buffer, 0); - - desc.descriptiveName = String::fromUTF8 (buffer).trim(); - - if (desc.descriptiveName.isEmpty()) - desc.descriptiveName = name; - } - - desc.fileOrIdentifier = module->file.getFullPathName(); - desc.uid = getUID(); - desc.lastFileModTime = module->file.getLastModificationTime(); - desc.pluginFormatName = "VST"; - desc.category = getCategory(); - - { - char buffer [kVstMaxVendorStrLen + 8] = { 0 }; - dispatch (effGetVendorString, 0, 0, buffer, 0); - desc.manufacturerName = String::fromUTF8 (buffer); - } - - desc.version = getVersion(); - desc.numInputChannels = getNumInputChannels(); - desc.numOutputChannels = getNumOutputChannels(); - desc.isInstrument = (effect != nullptr && (effect->flags & effFlagsIsSynth) != 0); - } - - void initialise (double initialSampleRate, int initialBlockSize) - { - if (initialised || effect == nullptr) - return; - - #if JUCE_WINDOWS - // On Windows it's highly advisable to create your plugins using the message thread, - // because many plugins need a chance to create HWNDs that will get their - // messages delivered by the main message thread, and that's not possible from - // a background thread. - jassert (MessageManager::getInstance()->isThisTheMessageThread()); - #endif - - JUCE_VST_LOG ("Initialising VST: " + module->pluginName + " (" + getVersion() + ")"); - initialised = true; - - setPlayConfigDetails (effect->numInputs, effect->numOutputs, - initialSampleRate, initialBlockSize); - - dispatch (effIdentify, 0, 0, 0, 0); - - if (getSampleRate() > 0) - dispatch (effSetSampleRate, 0, 0, 0, (float) getSampleRate()); - - if (getBlockSize() > 0) - dispatch (effSetBlockSize, 0, jmax (32, getBlockSize()), 0, 0); - - dispatch (effOpen, 0, 0, 0, 0); - - setPlayConfigDetails (effect->numInputs, effect->numOutputs, - getSampleRate(), getBlockSize()); - - if (getNumPrograms() > 1) - setCurrentProgram (0); - else - dispatch (effSetProgram, 0, 0, 0, 0); - - for (int i = effect->numInputs; --i >= 0;) dispatch (effConnectInput, i, 1, 0, 0); - for (int i = effect->numOutputs; --i >= 0;) dispatch (effConnectOutput, i, 1, 0, 0); - - if (getVstCategory() != kPlugCategShell) // (workaround for Waves 5 plugins which crash during this call) - updateStoredProgramNames(); - - wantsMidiMessages = dispatch (effCanDo, 0, 0, (void*) "receiveVstMidiEvent", 0) > 0; - - #if JUCE_MAC && JUCE_SUPPORT_CARBON - usesCocoaNSView = (dispatch (effCanDo, 0, 0, (void*) "hasCockosViewAsConfig", 0) & 0xffff0000) == 0xbeef0000; - #endif - - setLatencySamples (effect->initialDelay); - } - - void* getPlatformSpecificData() override { return effect; } - const String getName() const override { return name; } - - int getUID() const - { - int uid = effect != nullptr ? effect->uniqueID : 0; - - if (uid == 0) - uid = module->file.hashCode(); - - return uid; - } - - bool silenceInProducesSilenceOut() const override - { - return effect == nullptr || (effect->flags & effFlagsNoSoundInStop) != 0; - } - - double getTailLengthSeconds() const override - { - if (effect == nullptr) - return 0.0; - - const double sampleRate = getSampleRate(); - - if (sampleRate <= 0) - return 0.0; - - VstIntPtr samples = dispatch (effGetTailSize, 0, 0, 0, 0); - return samples / sampleRate; - } - - bool acceptsMidi() const override { return wantsMidiMessages; } - bool producesMidi() const override { return dispatch (effCanDo, 0, 0, (void*) "sendVstMidiEvent", 0) > 0; } - - VstPlugCategory getVstCategory() const noexcept { return (VstPlugCategory) dispatch (effGetPlugCategory, 0, 0, 0, 0); } - - //============================================================================== - void prepareToPlay (double rate, int samplesPerBlockExpected) override - { - setPlayConfigDetails (effect->numInputs, effect->numOutputs, rate, samplesPerBlockExpected); - - vstHostTime.tempo = 120.0; - vstHostTime.timeSigNumerator = 4; - vstHostTime.timeSigDenominator = 4; - vstHostTime.sampleRate = rate; - vstHostTime.samplePos = 0; - vstHostTime.flags = kVstNanosValid | kVstAutomationWriting | kVstAutomationReading; - - initialise (rate, samplesPerBlockExpected); - - if (initialised) - { - wantsMidiMessages = wantsMidiMessages - || (dispatch (effCanDo, 0, 0, (void*) "receiveVstMidiEvent", 0) > 0); - - if (wantsMidiMessages) - midiEventsToSend.ensureSize (256); - else - midiEventsToSend.freeEvents(); - - incomingMidi.clear(); - - dispatch (effSetSampleRate, 0, 0, 0, (float) rate); - dispatch (effSetBlockSize, 0, jmax (16, samplesPerBlockExpected), 0, 0); - - tempBuffer.setSize (jmax (1, effect->numOutputs), samplesPerBlockExpected); - - if (! isPowerOn) - setPower (true); - - // dodgy hack to force some plugins to initialise the sample rate.. - if ((! hasEditor()) && getNumParameters() > 0) - { - const float old = getParameter (0); - setParameter (0, (old < 0.5f) ? 1.0f : 0.0f); - setParameter (0, old); - } - - dispatch (effStartProcess, 0, 0, 0, 0); - - setLatencySamples (effect->initialDelay); - } - } - - void releaseResources() override - { - if (initialised) - { - dispatch (effStopProcess, 0, 0, 0, 0); - setPower (false); - } - - tempBuffer.setSize (1, 1); - incomingMidi.clear(); - - midiEventsToSend.freeEvents(); - } - - void reset() override - { - if (isPowerOn) - { - setPower (false); - setPower (true); - } - } - - void processBlock (AudioSampleBuffer& buffer, MidiBuffer& midiMessages) override - { - const int numSamples = buffer.getNumSamples(); - - if (initialised) - { - if (AudioPlayHead* const playHead = getPlayHead()) - { - AudioPlayHead::CurrentPositionInfo position; - playHead->getCurrentPosition (position); - - vstHostTime.samplePos = (double) position.timeInSamples; - vstHostTime.tempo = position.bpm; - vstHostTime.timeSigNumerator = position.timeSigNumerator; - vstHostTime.timeSigDenominator = position.timeSigDenominator; - vstHostTime.ppqPos = position.ppqPosition; - vstHostTime.barStartPos = position.ppqPositionOfLastBarStart; - vstHostTime.flags |= kVstTempoValid | kVstTimeSigValid | kVstPpqPosValid | kVstBarsValid; - - VstInt32 newTransportFlags = 0; - if (position.isPlaying) newTransportFlags |= kVstTransportPlaying; - if (position.isRecording) newTransportFlags |= kVstTransportRecording; - - if (newTransportFlags != (vstHostTime.flags & (kVstTransportPlaying | kVstTransportRecording))) - vstHostTime.flags = (vstHostTime.flags & ~(kVstTransportPlaying | kVstTransportRecording)) | newTransportFlags | kVstTransportChanged; - else - vstHostTime.flags &= ~kVstTransportChanged; - - switch (position.frameRate) - { - case AudioPlayHead::fps24: setHostTimeFrameRate (0, 24.0, position.timeInSeconds); break; - case AudioPlayHead::fps25: setHostTimeFrameRate (1, 25.0, position.timeInSeconds); break; - case AudioPlayHead::fps2997: setHostTimeFrameRate (2, 29.97, position.timeInSeconds); break; - case AudioPlayHead::fps30: setHostTimeFrameRate (3, 30.0, position.timeInSeconds); break; - case AudioPlayHead::fps2997drop: setHostTimeFrameRate (4, 29.97, position.timeInSeconds); break; - case AudioPlayHead::fps30drop: setHostTimeFrameRate (5, 29.97, position.timeInSeconds); break; - default: break; - } - - if (position.isLooping) - { - vstHostTime.cycleStartPos = position.ppqLoopStart; - vstHostTime.cycleEndPos = position.ppqLoopEnd; - vstHostTime.flags |= kVstCyclePosValid; - } - else - { - vstHostTime.flags &= ~kVstCyclePosValid; - } - } - - vstHostTime.nanoSeconds = getVSTHostTimeNanoseconds(); - - if (wantsMidiMessages) - { - midiEventsToSend.clear(); - midiEventsToSend.ensureSize (1); - - MidiBuffer::Iterator iter (midiMessages); - const uint8* midiData; - int numBytesOfMidiData, samplePosition; - - while (iter.getNextEvent (midiData, numBytesOfMidiData, samplePosition)) - { - midiEventsToSend.addEvent (midiData, numBytesOfMidiData, - jlimit (0, numSamples - 1, samplePosition)); - } - - effect->dispatcher (effect, effProcessEvents, 0, 0, midiEventsToSend.events, 0); - } - - _clearfp(); - - if ((effect->flags & effFlagsCanReplacing) != 0) - { - effect->processReplacing (effect, buffer.getArrayOfWritePointers(), buffer.getArrayOfWritePointers(), numSamples); - } - else - { - tempBuffer.setSize (effect->numOutputs, numSamples); - tempBuffer.clear(); - - effect->process (effect, buffer.getArrayOfWritePointers(), tempBuffer.getArrayOfWritePointers(), numSamples); - - for (int i = effect->numOutputs; --i >= 0;) - buffer.copyFrom (i, 0, tempBuffer.getReadPointer (i), numSamples); - } - } - else - { - // Not initialised, so just bypass.. - for (int i = 0; i < getNumOutputChannels(); ++i) - buffer.clear (i, 0, buffer.getNumSamples()); - } - - { - // copy any incoming midi.. - const ScopedLock sl (midiInLock); - - midiMessages.swapWith (incomingMidi); - incomingMidi.clear(); - } - } - - //============================================================================== - bool hasEditor() const override { return effect != nullptr && (effect->flags & effFlagsHasEditor) != 0; } - AudioProcessorEditor* createEditor() override; - - //============================================================================== - const String getInputChannelName (int index) const override - { - if (index >= 0 && index < getNumInputChannels()) - { - VstPinProperties pinProps; - if (dispatch (effGetInputProperties, index, 0, &pinProps, 0.0f) != 0) - return String (pinProps.label, sizeof (pinProps.label)); - } - - return String::empty; - } - - bool isInputChannelStereoPair (int index) const override - { - if (index < 0 || index >= getNumInputChannels()) - return false; - - VstPinProperties pinProps; - if (dispatch (effGetInputProperties, index, 0, &pinProps, 0.0f) != 0) - return (pinProps.flags & kVstPinIsStereo) != 0; - - return true; - } - - const String getOutputChannelName (int index) const override - { - if (index >= 0 && index < getNumOutputChannels()) - { - VstPinProperties pinProps; - if (dispatch (effGetOutputProperties, index, 0, &pinProps, 0.0f) != 0) - return String (pinProps.label, sizeof (pinProps.label)); - } - - return String::empty; - } - - bool isOutputChannelStereoPair (int index) const override - { - if (index < 0 || index >= getNumOutputChannels()) - return false; - - VstPinProperties pinProps; - if (dispatch (effGetOutputProperties, index, 0, &pinProps, 0.0f) != 0) - return (pinProps.flags & kVstPinIsStereo) != 0; - - return true; - } - - bool isValidChannel (int index, bool isInput) const - { - return isPositiveAndBelow (index, isInput ? getNumInputChannels() : getNumOutputChannels()); - } - - //============================================================================== - int getNumParameters() { return effect != nullptr ? effect->numParams : 0; } - - float getParameter (int index) override - { - if (effect != nullptr && isPositiveAndBelow (index, (int) effect->numParams)) - { - const ScopedLock sl (lock); - return effect->getParameter (effect, index); - } - - return 0.0f; - } - - void setParameter (int index, float newValue) override - { - if (effect != nullptr && isPositiveAndBelow (index, (int) effect->numParams)) - { - const ScopedLock sl (lock); - - if (effect->getParameter (effect, index) != newValue) - effect->setParameter (effect, index, newValue); - } - } - - const String getParameterName (int index) override { return getTextForOpcode (index, effGetParamName); } - const String getParameterText (int index) override { return getTextForOpcode (index, effGetParamDisplay); } - String getParameterLabel (int index) const override { return getTextForOpcode (index, effGetParamLabel); } - - bool isParameterAutomatable (int index) const override - { - if (effect != nullptr) - { - jassert (index >= 0 && index < effect->numParams); - return dispatch (effCanBeAutomated, index, 0, 0, 0) != 0; - } - - return false; - } - - //============================================================================== - int getNumPrograms() override { return effect != nullptr ? jmax (0, effect->numPrograms) : 0; } - - // NB: some plugs return negative numbers from this function. - int getCurrentProgram() override { return (int) dispatch (effGetProgram, 0, 0, 0, 0); } - - void setCurrentProgram (int newIndex) override - { - if (getNumPrograms() > 0 && newIndex != getCurrentProgram()) - dispatch (effSetProgram, 0, jlimit (0, getNumPrograms() - 1, newIndex), 0, 0); - } - - const String getProgramName (int index) override - { - if (index >= 0) - { - if (index == getCurrentProgram()) - return getCurrentProgramName(); - - if (effect != nullptr) - { - char nm[264] = { 0 }; - - if (dispatch (effGetProgramNameIndexed, jlimit (0, getNumPrograms(), index), -1, nm, 0) != 0) - return String::fromUTF8 (nm).trim(); - } - } - - return programNames [index]; - } - - void changeProgramName (int index, const String& newName) override - { - if (index >= 0 && index == getCurrentProgram()) - { - if (getNumPrograms() > 0 && newName != getCurrentProgramName()) - dispatch (effSetProgramName, 0, 0, (void*) newName.substring (0, 24).toRawUTF8(), 0.0f); - } - else - { - jassertfalse; // xxx not implemented! - } - } - - //============================================================================== - void getStateInformation (MemoryBlock& mb) override { saveToFXBFile (mb, true); } - void getCurrentProgramStateInformation (MemoryBlock& mb) override { saveToFXBFile (mb, false); } - - void setStateInformation (const void* data, int size) override { loadFromFXBFile (data, size); } - void setCurrentProgramStateInformation (const void* data, int size) override { loadFromFXBFile (data, size); } - - //============================================================================== - void timerCallback() override - { - if (dispatch (effIdle, 0, 0, 0, 0) == 0) - stopTimer(); - } - - void handleAsyncUpdate() override - { - // indicates that something about the plugin has changed.. - updateHostDisplay(); - } - - VstIntPtr handleCallback (VstInt32 opcode, VstInt32 index, VstIntPtr value, void* ptr, float opt) - { - switch (opcode) - { - case audioMasterAutomate: sendParamChangeMessageToListeners (index, opt); break; - case audioMasterProcessEvents: handleMidiFromPlugin ((const VstEvents*) ptr); break; - - #if JUCE_MSVC - #pragma warning (push) - #pragma warning (disable: 4311) - #endif - case audioMasterGetTime: return (VstIntPtr) &vstHostTime; - #if JUCE_MSVC - #pragma warning (pop) - #endif - - case audioMasterIdle: - if (insideVSTCallback == 0 && MessageManager::getInstance()->isThisTheMessageThread()) - { - const IdleCallRecursionPreventer icrp; - - #if JUCE_MAC - if (getActiveEditor() != nullptr) - dispatch (effEditIdle, 0, 0, 0, 0); - #endif - - Timer::callPendingTimersSynchronously(); - - handleUpdateNowIfNeeded(); - - for (int i = ComponentPeer::getNumPeers(); --i >= 0;) - if (ComponentPeer* p = ComponentPeer::getPeer(i)) - p->performAnyPendingRepaintsNow(); - } - break; - - case audioMasterSizeWindow: - if (AudioProcessorEditor* ed = getActiveEditor()) - ed->setSize (index, (int) value); - - return 1; - - case audioMasterUpdateDisplay: triggerAsyncUpdate(); break; - case audioMasterIOChanged: setLatencySamples (effect->initialDelay); break; - case audioMasterNeedIdle: startTimer (50); break; - - case audioMasterGetSampleRate: return (VstIntPtr) (getSampleRate() > 0 ? getSampleRate() : defaultVSTSampleRateValue); - case audioMasterGetBlockSize: return (VstIntPtr) (getBlockSize() > 0 ? getBlockSize() : defaultVSTBlockSizeValue); - case audioMasterWantMidi: wantsMidiMessages = true; break; - case audioMasterGetDirectory: return getVstDirectory(); - - case audioMasterTempoAt: - if (extraFunctions != nullptr) - return (VstIntPtr) extraFunctions->getTempoAt ((int64) value); - - break; - - case audioMasterGetAutomationState: - if (extraFunctions != nullptr) - return (VstIntPtr) extraFunctions->getAutomationState(); - - break; - - case audioMasterPinConnected: - return isValidChannel (index, value == 0) ? 0 : 1; // (yes, 0 = true) - - case audioMasterGetCurrentProcessLevel: - return isNonRealtime() ? 4 : 0; - - // none of these are handled (yet).. - case audioMasterBeginEdit: - case audioMasterEndEdit: - case audioMasterSetTime: - case audioMasterGetParameterQuantization: - case audioMasterGetInputLatency: - case audioMasterGetOutputLatency: - case audioMasterGetPreviousPlug: - case audioMasterGetNextPlug: - case audioMasterWillReplaceOrAccumulate: - case audioMasterOfflineStart: - case audioMasterOfflineRead: - case audioMasterOfflineWrite: - case audioMasterOfflineGetCurrentPass: - case audioMasterOfflineGetCurrentMetaPass: - case audioMasterVendorSpecific: - case audioMasterSetIcon: - case audioMasterGetLanguage: - case audioMasterOpenWindow: - case audioMasterCloseWindow: - break; - - default: - return handleGeneralCallback (opcode, index, value, ptr, opt); - } - - return 0; - } - - // handles non plugin-specific callbacks.. - static VstIntPtr handleGeneralCallback (VstInt32 opcode, VstInt32 /*index*/, VstIntPtr /*value*/, void *ptr, float /*opt*/) - { - switch (opcode) - { - case audioMasterCanDo: - { - static const char* canDos[] = { "supplyIdle", - "sendVstEvents", - "sendVstMidiEvent", - "sendVstTimeInfo", - "receiveVstEvents", - "receiveVstMidiEvent", - "supportShell", - "shellCategory" }; - - for (int i = 0; i < numElementsInArray (canDos); ++i) - if (strcmp (canDos[i], (const char*) ptr) == 0) - return 1; - - return 0; - } - - case audioMasterVersion: return 2400; - case audioMasterCurrentId: return shellUIDToCreate; - case audioMasterGetNumAutomatableParameters: return 0; - case audioMasterGetAutomationState: return 1; - case audioMasterGetVendorVersion: return 0x0101; - - case audioMasterGetVendorString: - case audioMasterGetProductString: - { - String hostName ("Juce VST Host"); - - if (JUCEApplicationBase* app = JUCEApplicationBase::getInstance()) - hostName = app->getApplicationName(); - - hostName.copyToUTF8 ((char*) ptr, (size_t) jmin (kVstMaxVendorStrLen, kVstMaxProductStrLen) - 1); - break; - } - - case audioMasterGetSampleRate: return (VstIntPtr) defaultVSTSampleRateValue; - case audioMasterGetBlockSize: return (VstIntPtr) defaultVSTBlockSizeValue; - case audioMasterSetOutputSampleRate: return 0; - - default: - DBG ("*** Unhandled VST Callback: " + String ((int) opcode)); - break; - } - - return 0; - } - - //============================================================================== - VstIntPtr dispatch (const int opcode, const int index, const VstIntPtr value, void* const ptr, float opt) const - { - VstIntPtr result = 0; - - if (effect != nullptr) - { - const ScopedLock sl (lock); - const IdleCallRecursionPreventer icrp; - - try - { - #if JUCE_MAC - const ResFileRefNum oldResFile = CurResFile(); - - if (module->resFileId != 0) - UseResFile (module->resFileId); - #endif - - result = effect->dispatcher (effect, opcode, index, value, ptr, opt); - - #if JUCE_MAC - const ResFileRefNum newResFile = CurResFile(); - if (newResFile != oldResFile) // avoid confusing the parent app's resource file with the plug-in's - { - module->resFileId = newResFile; - UseResFile (oldResFile); - } - #endif - } - catch (...) - {} - } - - return result; - } - - bool loadFromFXBFile (const void* const data, const size_t dataSize) - { - if (dataSize < 28) - return false; - - const fxSet* const set = (const fxSet*) data; - - if ((set->chunkMagic != fxbName ("CcnK") && set->chunkMagic != fxbName ("KncC")) - || fxbSwap (set->version) > fxbVersionNum) - return false; - - if (set->fxMagic == fxbName ("FxBk")) - { - // bank of programs - if (fxbSwap (set->numPrograms) >= 0) - { - const int oldProg = getCurrentProgram(); - const int numParams = fxbSwap (((const fxProgram*) (set->programs))->numParams); - const int progLen = sizeof (fxProgram) + (numParams - 1) * sizeof (float); - - for (int i = 0; i < fxbSwap (set->numPrograms); ++i) - { - if (i != oldProg) - { - const fxProgram* const prog = (const fxProgram*) (((const char*) (set->programs)) + i * progLen); - if (((const char*) prog) - ((const char*) set) >= (ssize_t) dataSize) - return false; - - if (fxbSwap (set->numPrograms) > 0) - setCurrentProgram (i); - - if (! restoreProgramSettings (prog)) - return false; - } - } - - if (fxbSwap (set->numPrograms) > 0) - setCurrentProgram (oldProg); - - const fxProgram* const prog = (const fxProgram*) (((const char*) (set->programs)) + oldProg * progLen); - if (((const char*) prog) - ((const char*) set) >= (ssize_t) dataSize) - return false; - - if (! restoreProgramSettings (prog)) - return false; - } - } - else if (set->fxMagic == fxbName ("FxCk")) - { - // single program - const fxProgram* const prog = (const fxProgram*) data; - - if (prog->chunkMagic != fxbName ("CcnK")) - return false; - - changeProgramName (getCurrentProgram(), prog->prgName); - - for (int i = 0; i < fxbSwap (prog->numParams); ++i) - setParameter (i, fxbSwapFloat (prog->params[i])); - } - else if (set->fxMagic == fxbName ("FBCh") || set->fxMagic == fxbName ("hCBF")) - { - // non-preset chunk - const fxChunkSet* const cset = (const fxChunkSet*) data; - - if (fxbSwap (cset->chunkSize) + sizeof (fxChunkSet) - 8 > (unsigned int) dataSize) - return false; - - setChunkData (cset->chunk, fxbSwap (cset->chunkSize), false); - } - else if (set->fxMagic == fxbName ("FPCh") || set->fxMagic == fxbName ("hCPF")) - { - // preset chunk - const fxProgramSet* const cset = (const fxProgramSet*) data; - - if (fxbSwap (cset->chunkSize) + sizeof (fxProgramSet) - 8 > (unsigned int) dataSize) - return false; - - setChunkData (cset->chunk, fxbSwap (cset->chunkSize), true); - - changeProgramName (getCurrentProgram(), cset->name); - } - else - { - return false; - } - - return true; - } - - bool saveToFXBFile (MemoryBlock& dest, bool isFXB, int maxSizeMB = 128) - { - const int numPrograms = getNumPrograms(); - const int numParams = getNumParameters(); - - if (usesChunks()) - { - MemoryBlock chunk; - getChunkData (chunk, ! isFXB, maxSizeMB); - - if (isFXB) - { - const size_t totalLen = sizeof (fxChunkSet) + chunk.getSize() - 8; - dest.setSize (totalLen, true); - - fxChunkSet* const set = (fxChunkSet*) dest.getData(); - set->chunkMagic = fxbName ("CcnK"); - set->byteSize = 0; - set->fxMagic = fxbName ("FBCh"); - set->version = fxbSwap (fxbVersionNum); - set->fxID = fxbSwap (getUID()); - set->fxVersion = fxbSwap (getVersionNumber()); - set->numPrograms = fxbSwap (numPrograms); - set->chunkSize = fxbSwap ((VstInt32) chunk.getSize()); - - chunk.copyTo (set->chunk, 0, chunk.getSize()); - } - else - { - const size_t totalLen = sizeof (fxProgramSet) + chunk.getSize() - 8; - dest.setSize (totalLen, true); - - fxProgramSet* const set = (fxProgramSet*) dest.getData(); - set->chunkMagic = fxbName ("CcnK"); - set->byteSize = 0; - set->fxMagic = fxbName ("FPCh"); - set->version = fxbSwap (fxbVersionNum); - set->fxID = fxbSwap (getUID()); - set->fxVersion = fxbSwap (getVersionNumber()); - set->numPrograms = fxbSwap (numPrograms); - set->chunkSize = fxbSwap ((VstInt32) chunk.getSize()); - - getCurrentProgramName().copyToUTF8 (set->name, sizeof (set->name) - 1); - chunk.copyTo (set->chunk, 0, chunk.getSize()); - } - } - else - { - if (isFXB) - { - const int progLen = sizeof (fxProgram) + (numParams - 1) * sizeof (float); - const int len = (sizeof (fxSet) - sizeof (fxProgram)) + progLen * jmax (1, numPrograms); - dest.setSize (len, true); - - fxSet* const set = (fxSet*) dest.getData(); - set->chunkMagic = fxbName ("CcnK"); - set->byteSize = 0; - set->fxMagic = fxbName ("FxBk"); - set->version = fxbSwap (fxbVersionNum); - set->fxID = fxbSwap (getUID()); - set->fxVersion = fxbSwap (getVersionNumber()); - set->numPrograms = fxbSwap (numPrograms); - - const int oldProgram = getCurrentProgram(); - MemoryBlock oldSettings; - createTempParameterStore (oldSettings); - - setParamsInProgramBlock ((fxProgram*) (((char*) (set->programs)) + oldProgram * progLen)); - - for (int i = 0; i < numPrograms; ++i) - { - if (i != oldProgram) - { - setCurrentProgram (i); - setParamsInProgramBlock ((fxProgram*) (((char*) (set->programs)) + i * progLen)); - } - } - - setCurrentProgram (oldProgram); - restoreFromTempParameterStore (oldSettings); - } - else - { - const int totalLen = sizeof (fxProgram) + (numParams - 1) * sizeof (float); - dest.setSize (totalLen, true); - - setParamsInProgramBlock ((fxProgram*) dest.getData()); - } - } - - return true; - } - - bool usesChunks() const noexcept { return effect != nullptr && (effect->flags & effFlagsProgramChunks) != 0; } - - bool getChunkData (MemoryBlock& mb, bool isPreset, int maxSizeMB) const - { - if (usesChunks()) - { - void* data = nullptr; - const VstIntPtr bytes = dispatch (effGetChunk, isPreset ? 1 : 0, 0, &data, 0.0f); - - if (data != nullptr && bytes <= maxSizeMB * 1024 * 1024) - { - mb.setSize (bytes); - mb.copyFrom (data, 0, bytes); - - return true; - } - } - - return false; - } - - bool setChunkData (const void* data, const int size, bool isPreset) - { - if (size > 0 && usesChunks()) - { - dispatch (effSetChunk, isPreset ? 1 : 0, size, (void*) data, 0.0f); - - if (! isPreset) - updateStoredProgramNames(); - - return true; - } - - return false; - } - - AEffect* effect; - ModuleHandle::Ptr module; - - ScopedPointer extraFunctions; - bool usesCocoaNSView; - -private: - String name; - CriticalSection lock; - bool wantsMidiMessages, initialised, isPowerOn; - mutable StringArray programNames; - AudioSampleBuffer tempBuffer; - CriticalSection midiInLock; - MidiBuffer incomingMidi; - VSTMidiEventList midiEventsToSend; - VstTimeInfo vstHostTime; - - //============================================================================== - void setHostTimeFrameRate (long frameRateIndex, double frameRate, double currentTime) noexcept - { - vstHostTime.flags |= kVstSmpteValid; - vstHostTime.smpteFrameRate = (VstInt32) frameRateIndex; - vstHostTime.smpteOffset = (VstInt32) (currentTime * 80.0 * frameRate + 0.5); - } - - bool restoreProgramSettings (const fxProgram* const prog) - { - if (prog->chunkMagic == fxbName ("CcnK") && prog->fxMagic == fxbName ("FxCk")) - { - changeProgramName (getCurrentProgram(), prog->prgName); - - for (int i = 0; i < fxbSwap (prog->numParams); ++i) - setParameter (i, fxbSwapFloat (prog->params[i])); - - return true; - } - - return false; - } - - String getTextForOpcode (const int index, const AEffectOpcodes opcode) const - { - if (effect == nullptr) - return String::empty; - - jassert (index >= 0 && index < effect->numParams); - char nm [256] = { 0 }; - dispatch (opcode, index, 0, nm, 0); - return String (CharPointer_UTF8 (nm)).trim(); - } - - String getCurrentProgramName() - { - String progName; - - if (effect != nullptr) - { - { - char nm[256] = { 0 }; - dispatch (effGetProgramName, 0, 0, nm, 0); - progName = String (CharPointer_UTF8 (nm)).trim(); - } - - const int index = getCurrentProgram(); - - if (index >= 0 && programNames[index].isEmpty()) - { - while (programNames.size() < index) - programNames.add (String::empty); - - programNames.set (index, progName); - } - } - - return progName; - } - - void setParamsInProgramBlock (fxProgram* const prog) - { - const int numParams = getNumParameters(); - - prog->chunkMagic = fxbName ("CcnK"); - prog->byteSize = 0; - prog->fxMagic = fxbName ("FxCk"); - prog->version = fxbSwap (fxbVersionNum); - prog->fxID = fxbSwap (getUID()); - prog->fxVersion = fxbSwap (getVersionNumber()); - prog->numParams = fxbSwap (numParams); - - getCurrentProgramName().copyToUTF8 (prog->prgName, sizeof (prog->prgName) - 1); - - for (int i = 0; i < numParams; ++i) - prog->params[i] = fxbSwapFloat (getParameter (i)); - } - - void updateStoredProgramNames() - { - if (effect != nullptr && getNumPrograms() > 0) - { - char nm[256] = { 0 }; - - // only do this if the plugin can't use indexed names.. - if (dispatch (effGetProgramNameIndexed, 0, -1, nm, 0) == 0) - { - const int oldProgram = getCurrentProgram(); - MemoryBlock oldSettings; - createTempParameterStore (oldSettings); - - for (int i = 0; i < getNumPrograms(); ++i) - { - setCurrentProgram (i); - getCurrentProgramName(); // (this updates the list) - } - - setCurrentProgram (oldProgram); - restoreFromTempParameterStore (oldSettings); - } - } - } - - void handleMidiFromPlugin (const VstEvents* const events) - { - if (events != nullptr) - { - const ScopedLock sl (midiInLock); - VSTMidiEventList::addEventsToMidiBuffer (events, incomingMidi); - } - } - - //============================================================================== - void createTempParameterStore (MemoryBlock& dest) - { - dest.setSize (64 + 4 * getNumParameters()); - dest.fillWith (0); - - getCurrentProgramName().copyToUTF8 ((char*) dest.getData(), 63); - - float* const p = (float*) (((char*) dest.getData()) + 64); - for (int i = 0; i < getNumParameters(); ++i) - p[i] = getParameter(i); - } - - void restoreFromTempParameterStore (const MemoryBlock& m) - { - changeProgramName (getCurrentProgram(), (const char*) m.getData()); - - float* p = (float*) (((char*) m.getData()) + 64); - for (int i = 0; i < getNumParameters(); ++i) - setParameter (i, p[i]); - } - - VstIntPtr getVstDirectory() const - { - #if JUCE_MAC - return (VstIntPtr) (void*) &module->parentDirFSSpec; - #else - return (VstIntPtr) (pointer_sized_uint) module->fullParentDirectoryPathName.toRawUTF8(); - #endif - } - - //============================================================================== - int getVersionNumber() const noexcept { return effect != nullptr ? effect->version : 0; } - - String getVersion() const - { - unsigned int v = (unsigned int) dispatch (effGetVendorVersion, 0, 0, 0, 0); - - String s; - - if (v == 0 || (int) v == -1) - v = getVersionNumber(); - - if (v != 0) - { - int versionBits[32]; - int n = 0; - - for (int vv = v; vv != 0; vv /= 10) - versionBits [n++] = vv % 10; - - if (n > 4) // if the number ends up silly, it's probably encoded as hex instead of decimal.. - { - n = 0; - - for (int vv = v; vv != 0; vv >>= 8) - versionBits [n++] = vv & 255; - } - - while (n > 1 && versionBits [n - 1] == 0) - --n; - - s << 'V'; - - while (n > 0) - { - s << versionBits [--n]; - - if (n > 0) - s << '.'; - } - } - - return s; - } - - const char* getCategory() const - { - switch (getVstCategory()) - { - case kPlugCategEffect: return "Effect"; - case kPlugCategSynth: return "Synth"; - case kPlugCategAnalysis: return "Analysis"; - case kPlugCategMastering: return "Mastering"; - case kPlugCategSpacializer: return "Spacial"; - case kPlugCategRoomFx: return "Reverb"; - case kPlugSurroundFx: return "Surround"; - case kPlugCategRestoration: return "Restoration"; - case kPlugCategGenerator: return "Tone generation"; - default: break; - } - - return nullptr; - } - - void setPower (const bool on) - { - dispatch (effMainsChanged, 0, on ? 1 : 0, 0, 0); - isPowerOn = on; - } - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (VSTPluginInstance) -}; - -//============================================================================== -class VSTPluginWindow; -static Array activeVSTWindows; - -//============================================================================== -class VSTPluginWindow : public AudioProcessorEditor, - #if ! JUCE_MAC - public ComponentMovementWatcher, - #endif - public Timer -{ -public: - VSTPluginWindow (VSTPluginInstance& plug) - : AudioProcessorEditor (&plug), - #if ! JUCE_MAC - ComponentMovementWatcher (this), - #endif - plugin (plug), - isOpen (false), - recursiveResize (false), - pluginWantsKeys (false), - pluginRefusesToResize (false), - alreadyInside (false) - { - #if JUCE_WINDOWS - pluginHWND = 0; - sizeCheckCount = 0; - - #elif JUCE_LINUX - pluginWindow = None; - pluginProc = None; - - #elif JUCE_MAC - #if JUCE_SUPPORT_CARBON - if (! plug.usesCocoaNSView) - addAndMakeVisible (carbonWrapper = new CarbonWrapperComponent (*this)); - else - #endif - addAndMakeVisible (cocoaWrapper = new AutoResizingNSViewComponentWithParent()); - #endif - - activeVSTWindows.add (this); - - setSize (1, 1); - setOpaque (true); - setVisible (true); - } - - ~VSTPluginWindow() - { - closePluginWindow(); - - #if JUCE_MAC - #if JUCE_SUPPORT_CARBON - carbonWrapper = nullptr; - #endif - cocoaWrapper = nullptr; - #endif - - activeVSTWindows.removeFirstMatchingValue (this); - plugin.editorBeingDeleted (this); - } - - //============================================================================== - #if ! JUCE_MAC - void componentMovedOrResized (bool /*wasMoved*/, bool /*wasResized*/) override - { - if (recursiveResize) - return; - - Component* const topComp = getTopLevelComponent(); - - if (topComp->getPeer() != nullptr) - { - const Point pos (topComp->getLocalPoint (this, Point())); - - recursiveResize = true; - - #if JUCE_WINDOWS - if (pluginHWND != 0) - MoveWindow (pluginHWND, pos.getX(), pos.getY(), getWidth(), getHeight(), TRUE); - #elif JUCE_LINUX - if (pluginWindow != 0) - { - XResizeWindow (display, pluginWindow, getWidth(), getHeight()); - XMoveWindow (display, pluginWindow, pos.getX(), pos.getY()); - XMapRaised (display, pluginWindow); - } - #endif - - recursiveResize = false; - } - } - - void componentVisibilityChanged() override - { - if (isShowing()) - openPluginWindow(); - else if (! shouldAvoidDeletingWindow()) - closePluginWindow(); - - componentMovedOrResized (true, true); - } - - void componentPeerChanged() override - { - closePluginWindow(); - openPluginWindow(); - } - #endif - - #if JUCE_MAC - void visibilityChanged() override - { - if (cocoaWrapper != nullptr) - { - if (isVisible()) - openPluginWindow ((NSView*) cocoaWrapper->getView()); - else - closePluginWindow(); - } - } - - void childBoundsChanged (Component*) override - { - if (cocoaWrapper != nullptr) - { - int w = cocoaWrapper->getWidth(); - int h = cocoaWrapper->getHeight(); - - if (w != getWidth() || h != getHeight()) - setSize (w, h); - } - } - #endif - - //============================================================================== - bool keyStateChanged (bool) override { return pluginWantsKeys; } - bool keyPressed (const juce::KeyPress&) override { return pluginWantsKeys; } - - //============================================================================== - #if JUCE_MAC - void paint (Graphics& g) override - { - g.fillAll (Colours::black); - } - #else - void paint (Graphics& g) override - { - if (isOpen) - { - #if JUCE_LINUX - if (pluginWindow != 0) - { - const Rectangle clip (g.getClipBounds()); - - XEvent ev = { 0 }; - ev.xexpose.type = Expose; - ev.xexpose.display = display; - ev.xexpose.window = pluginWindow; - ev.xexpose.x = clip.getX(); - ev.xexpose.y = clip.getY(); - ev.xexpose.width = clip.getWidth(); - ev.xexpose.height = clip.getHeight(); - - sendEventToChild (ev); - } - #endif - } - else - { - g.fillAll (Colours::black); - } - } - #endif - - //============================================================================== - void timerCallback() override - { - if (isShowing()) - { - #if JUCE_WINDOWS - if (--sizeCheckCount <= 0) - { - sizeCheckCount = 10; - checkPluginWindowSize(); - } - #endif - - static bool reentrant = false; - - if (! reentrant) - { - reentrant = true; - plugin.dispatch (effEditIdle, 0, 0, 0, 0); - reentrant = false; - } - } - } - - //============================================================================== - void mouseDown (const MouseEvent& e) override - { - (void) e; - - #if JUCE_LINUX - if (pluginWindow == 0) - return; - - toFront (true); - - XEvent ev; - prepareXEvent (ev, e); - ev.xbutton.type = ButtonPress; - translateJuceToXButtonModifiers (e, ev); - sendEventToChild (ev); - - #elif JUCE_WINDOWS - toFront (true); - #endif - } - - void broughtToFront() override - { - activeVSTWindows.removeFirstMatchingValue (this); - activeVSTWindows.add (this); - - #if JUCE_MAC - dispatch (effEditTop, 0, 0, 0, 0); - #endif - } - - //============================================================================== -private: - VSTPluginInstance& plugin; - bool isOpen, recursiveResize; - bool pluginWantsKeys, pluginRefusesToResize, alreadyInside; - - #if JUCE_WINDOWS - HWND pluginHWND; - void* originalWndProc; - int sizeCheckCount; - #elif JUCE_LINUX - Window pluginWindow; - EventProcPtr pluginProc; - #endif - - // This is a workaround for old Mackie plugins that crash if their - // window is deleted more than once. - bool shouldAvoidDeletingWindow() const - { - return plugin.getPluginDescription() - .manufacturerName.containsIgnoreCase ("Loud Technologies"); - } - - // This is an old workaround for some plugins that need a repaint when their - // windows are first created, but it breaks some Izotope plugins.. - bool shouldRepaintCarbonWindowWhenCreated() - { - return ! plugin.getName().containsIgnoreCase ("izotope"); - } - - //============================================================================== -#if JUCE_MAC - void openPluginWindow (void* parentWindow) - { - if (isOpen || parentWindow == 0) - return; - - isOpen = true; - - ERect* rect = nullptr; - dispatch (effEditGetRect, 0, 0, &rect, 0); - dispatch (effEditOpen, 0, 0, parentWindow, 0); - - // do this before and after like in the steinberg example - dispatch (effEditGetRect, 0, 0, &rect, 0); - dispatch (effGetProgram, 0, 0, 0, 0); // also in steinberg code - - // Install keyboard hooks - pluginWantsKeys = (dispatch (effKeysRequired, 0, 0, 0, 0) == 0); - - // double-check it's not too tiny - int w = 250, h = 150; - - if (rect != nullptr) - { - w = rect->right - rect->left; - h = rect->bottom - rect->top; - - if (w == 0 || h == 0) - { - w = 250; - h = 150; - } - } - - w = jmax (w, 32); - h = jmax (h, 32); - - setSize (w, h); - - startTimer (18 + juce::Random::getSystemRandom().nextInt (5)); - repaint(); - } - -#else - void openPluginWindow() - { - if (isOpen || getWindowHandle() == 0) - return; - - JUCE_VST_LOG ("Opening VST UI: " + plugin.getName()); - isOpen = true; - - ERect* rect = nullptr; - dispatch (effEditGetRect, 0, 0, &rect, 0); - dispatch (effEditOpen, 0, 0, getWindowHandle(), 0); - - // do this before and after like in the steinberg example - dispatch (effEditGetRect, 0, 0, &rect, 0); - dispatch (effGetProgram, 0, 0, 0, 0); // also in steinberg code - - // Install keyboard hooks - pluginWantsKeys = (dispatch (effKeysRequired, 0, 0, 0, 0) == 0); - - #if JUCE_WINDOWS - originalWndProc = 0; - pluginHWND = GetWindow ((HWND) getWindowHandle(), GW_CHILD); - - if (pluginHWND == 0) - { - isOpen = false; - setSize (300, 150); - return; - } - - #pragma warning (push) - #pragma warning (disable: 4244) - - if (! pluginWantsKeys) - { - originalWndProc = (void*) GetWindowLongPtr (pluginHWND, GWLP_WNDPROC); - SetWindowLongPtr (pluginHWND, GWLP_WNDPROC, (LONG_PTR) vstHookWndProc); - } - - #pragma warning (pop) - - RECT r; - GetWindowRect (pluginHWND, &r); - int w = r.right - r.left; - int h = r.bottom - r.top; - - if (rect != nullptr) - { - const int rw = rect->right - rect->left; - const int rh = rect->bottom - rect->top; - - if ((rw > 50 && rh > 50 && rw < 2000 && rh < 2000 && rw != w && rh != h) - || ((w == 0 && rw > 0) || (h == 0 && rh > 0))) - { - // very dodgy logic to decide which size is right. - if (abs (rw - w) > 350 || abs (rh - h) > 350) - { - SetWindowPos (pluginHWND, 0, - 0, 0, rw, rh, - SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOZORDER); - - GetWindowRect (pluginHWND, &r); - - w = r.right - r.left; - h = r.bottom - r.top; - - pluginRefusesToResize = (w != rw) || (h != rh); - - w = rw; - h = rh; - } - } - } - - #elif JUCE_LINUX - pluginWindow = getChildWindow ((Window) getWindowHandle()); - - if (pluginWindow != 0) - pluginProc = (EventProcPtr) getPropertyFromXWindow (pluginWindow, - XInternAtom (display, "_XEventProc", False)); - - int w = 250, h = 150; - - if (rect != nullptr) - { - w = rect->right - rect->left; - h = rect->bottom - rect->top; - - if (w == 0 || h == 0) - { - w = 250; - h = 150; - } - } - - if (pluginWindow != 0) - XMapRaised (display, pluginWindow); - #endif - - // double-check it's not too tiny - w = jmax (w, 32); - h = jmax (h, 32); - - setSize (w, h); - - #if JUCE_WINDOWS - checkPluginWindowSize(); - #endif - - startTimer (18 + juce::Random::getSystemRandom().nextInt (5)); - repaint(); - } -#endif - - //============================================================================== - void closePluginWindow() - { - if (isOpen) - { - JUCE_VST_LOG ("Closing VST UI: " + plugin.getName()); - isOpen = false; - dispatch (effEditClose, 0, 0, 0, 0); - stopTimer(); - - #if JUCE_WINDOWS - #pragma warning (push) - #pragma warning (disable: 4244) - if (originalWndProc != 0 && pluginHWND != 0 && IsWindow (pluginHWND)) - SetWindowLongPtr (pluginHWND, GWLP_WNDPROC, (LONG_PTR) originalWndProc); - #pragma warning (pop) - - originalWndProc = 0; - pluginHWND = 0; - #elif JUCE_LINUX - pluginWindow = 0; - pluginProc = 0; - #endif - } - } - - //============================================================================== - VstIntPtr dispatch (const int opcode, const int index, const int value, void* const ptr, float opt) - { - return plugin.dispatch (opcode, index, value, ptr, opt); - } - - //============================================================================== -#if JUCE_WINDOWS - void checkPluginWindowSize() - { - RECT r; - GetWindowRect (pluginHWND, &r); - const int w = r.right - r.left; - const int h = r.bottom - r.top; - - if (isShowing() && w > 0 && h > 0 - && (w != getWidth() || h != getHeight()) - && ! pluginRefusesToResize) - { - setSize (w, h); - sizeCheckCount = 0; - } - } - - // hooks to get keyboard events from VST windows.. - static LRESULT CALLBACK vstHookWndProc (HWND hW, UINT message, WPARAM wParam, LPARAM lParam) - { - for (int i = activeVSTWindows.size(); --i >= 0;) - { - Component::SafePointer w (activeVSTWindows[i]); - - if (w != nullptr && w->pluginHWND == hW) - { - if (message == WM_CHAR - || message == WM_KEYDOWN - || message == WM_SYSKEYDOWN - || message == WM_KEYUP - || message == WM_SYSKEYUP - || message == WM_APPCOMMAND) - { - SendMessage ((HWND) w->getTopLevelComponent()->getWindowHandle(), - message, wParam, lParam); - } - - if (w != nullptr) // (may have been deleted in SendMessage callback) - return CallWindowProc ((WNDPROC) w->originalWndProc, - (HWND) w->pluginHWND, - message, wParam, lParam); - } - } - - return DefWindowProc (hW, message, wParam, lParam); - } -#endif - -#if JUCE_LINUX - //============================================================================== - // overload mouse/keyboard events to forward them to the plugin's inner window.. - void sendEventToChild (XEvent& event) - { - if (pluginProc != 0) - { - // if the plugin publishes an event procedure, pass the event directly.. - pluginProc (&event); - } - else if (pluginWindow != 0) - { - // if the plugin has a window, then send the event to the window so that - // its message thread will pick it up.. - XSendEvent (display, pluginWindow, False, NoEventMask, &event); - XFlush (display); - } - } - - void prepareXEvent (XEvent& ev, const MouseEvent& e) const noexcept - { - zerostruct (ev); - ev.xcrossing.display = display; - ev.xcrossing.window = pluginWindow; - ev.xcrossing.root = RootWindow (display, DefaultScreen (display)); - ev.xcrossing.time = CurrentTime; - ev.xcrossing.x = e.x; - ev.xcrossing.y = e.y; - ev.xcrossing.x_root = e.getScreenX(); - ev.xcrossing.y_root = e.getScreenY(); - } - - void mouseEnter (const MouseEvent& e) override - { - if (pluginWindow != 0) - { - XEvent ev; - prepareXEvent (ev, e); - ev.xcrossing.type = EnterNotify; - ev.xcrossing.mode = NotifyNormal; - ev.xcrossing.detail = NotifyAncestor; - translateJuceToXCrossingModifiers (e, ev); - sendEventToChild (ev); - } - } - - void mouseExit (const MouseEvent& e) override - { - if (pluginWindow != 0) - { - XEvent ev; - prepareXEvent (ev, e); - ev.xcrossing.type = LeaveNotify; - ev.xcrossing.mode = NotifyNormal; - ev.xcrossing.detail = NotifyAncestor; - ev.xcrossing.focus = hasKeyboardFocus (true); - translateJuceToXCrossingModifiers (e, ev); - sendEventToChild (ev); - } - } - - void mouseMove (const MouseEvent& e) override - { - if (pluginWindow != 0) - { - XEvent ev; - prepareXEvent (ev, e); - ev.xmotion.type = MotionNotify; - ev.xmotion.is_hint = NotifyNormal; - sendEventToChild (ev); - } - } - - void mouseDrag (const MouseEvent& e) override - { - if (pluginWindow != 0) - { - XEvent ev; - prepareXEvent (ev, e); - ev.xmotion.type = MotionNotify; - ev.xmotion.is_hint = NotifyNormal; - translateJuceToXMotionModifiers (e, ev); - sendEventToChild (ev); - } - } - - void mouseUp (const MouseEvent& e) override - { - if (pluginWindow != 0) - { - XEvent ev; - prepareXEvent (ev, e); - ev.xbutton.type = ButtonRelease; - translateJuceToXButtonModifiers (e, ev); - sendEventToChild (ev); - } - } - - void mouseWheelMove (const MouseEvent& e, const MouseWheelDetails& wheel) override - { - if (pluginWindow != 0) - { - XEvent ev; - prepareXEvent (ev, e); - ev.xbutton.type = ButtonPress; - translateJuceToXMouseWheelModifiers (e, wheel.deltaY, ev); - sendEventToChild (ev); - - ev.xbutton.type = ButtonRelease; - sendEventToChild (ev); - } - } -#endif - - //============================================================================== -#if JUCE_MAC - #if JUCE_SUPPORT_CARBON - class CarbonWrapperComponent : public CarbonViewWrapperComponent - { - public: - CarbonWrapperComponent (VSTPluginWindow& w) - : owner (w), alreadyInside (false) - { - keepPluginWindowWhenHidden = w.shouldAvoidDeletingWindow(); - setRepaintsChildHIViewWhenCreated (w.shouldRepaintCarbonWindowWhenCreated()); - } - - ~CarbonWrapperComponent() - { - deleteWindow(); - } - - HIViewRef attachView (WindowRef windowRef, HIViewRef /*rootView*/) override - { - owner.openPluginWindow (windowRef); - return 0; - } - - void removeView (HIViewRef) override - { - if (owner.isOpen) - { - owner.isOpen = false; - owner.dispatch (effEditClose, 0, 0, 0, 0); - owner.dispatch (effEditSleep, 0, 0, 0, 0); - } - } - - bool getEmbeddedViewSize (int& w, int& h) override - { - ERect* rect = nullptr; - owner.dispatch (effEditGetRect, 0, 0, &rect, 0); - w = rect->right - rect->left; - h = rect->bottom - rect->top; - return true; - } - - void handleMouseDown (int x, int y) override - { - if (! alreadyInside) - { - alreadyInside = true; - getTopLevelComponent()->toFront (true); - owner.dispatch (effEditMouse, x, y, 0, 0); - alreadyInside = false; - } - else - { - PostEvent (::mouseDown, 0); - } - } - - void handlePaint() override - { - if (ComponentPeer* const peer = getPeer()) - { - const Point pos (peer->globalToLocal (getScreenPosition())); - ERect r; - r.left = (VstInt16) pos.getX(); - r.top = (VstInt16) pos.getY(); - r.right = (VstInt16) (r.left + getWidth()); - r.bottom = (VstInt16) (r.top + getHeight()); - - owner.dispatch (effEditDraw, 0, 0, &r, 0); - } - } - - private: - VSTPluginWindow& owner; - bool alreadyInside; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (CarbonWrapperComponent) - }; - - friend class CarbonWrapperComponent; - ScopedPointer carbonWrapper; - #endif - - ScopedPointer cocoaWrapper; - - void resized() override - { - #if JUCE_SUPPORT_CARBON - if (carbonWrapper != nullptr) - carbonWrapper->setSize (getWidth(), getHeight()); - #endif - - if (cocoaWrapper != nullptr) - cocoaWrapper->setSize (getWidth(), getHeight()); - } -#endif - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (VSTPluginWindow) -}; - -//============================================================================== -AudioProcessorEditor* VSTPluginInstance::createEditor() -{ - return hasEditor() ? new VSTPluginWindow (*this) - : nullptr; -} - -//============================================================================== -// entry point for all callbacks from the plugin -static VstIntPtr VSTCALLBACK audioMaster (AEffect* effect, VstInt32 opcode, VstInt32 index, VstIntPtr value, void* ptr, float opt) -{ - if (effect != nullptr) - if (VSTPluginInstance* instance = (VSTPluginInstance*) (effect->resvd2)) - return instance->handleCallback (opcode, index, value, ptr, opt); - - return VSTPluginInstance::handleGeneralCallback (opcode, index, value, ptr, opt); -} - -//============================================================================== -VSTPluginFormat::VSTPluginFormat() {} -VSTPluginFormat::~VSTPluginFormat() {} - -static VSTPluginInstance* createAndUpdateDesc (VSTPluginFormat& format, PluginDescription& desc) -{ - if (AudioPluginInstance* p = format.createInstanceFromDescription (desc, 44100.0, 512)) - { - if (VSTPluginInstance* instance = dynamic_cast (p)) - { - #if JUCE_MAC - if (instance->module->resFileId != 0) - UseResFile (instance->module->resFileId); - #endif - - instance->fillInPluginDescription (desc); - return instance; - } - - jassertfalse; - } - - return nullptr; -} - -void VSTPluginFormat::findAllTypesForFile (OwnedArray& results, - const String& fileOrIdentifier) -{ - if (! fileMightContainThisPluginType (fileOrIdentifier)) - return; - - PluginDescription desc; - desc.fileOrIdentifier = fileOrIdentifier; - desc.uid = 0; - - ScopedPointer instance (createAndUpdateDesc (*this, desc)); - - if (instance == nullptr) - return; - - if (instance->getVstCategory() != kPlugCategShell) - { - // Normal plugin... - results.add (new PluginDescription (desc)); - - instance->dispatch (effOpen, 0, 0, 0, 0); - } - else - { - // It's a shell plugin, so iterate all the subtypes... - for (;;) - { - char shellEffectName [256] = { 0 }; - const int uid = (int) instance->dispatch (effShellGetNextPlugin, 0, 0, shellEffectName, 0); - - if (uid == 0) - break; - - desc.uid = uid; - desc.name = shellEffectName; - - aboutToScanVSTShellPlugin (desc); - - ScopedPointer shellInstance (createAndUpdateDesc (*this, desc)); - - if (shellInstance != nullptr) - { - jassert (desc.uid == uid); - desc.hasSharedContainer = true; - desc.name = shellEffectName; - - if (! arrayContainsPlugin (results, desc)) - results.add (new PluginDescription (desc)); - } - } - } -} - -AudioPluginInstance* VSTPluginFormat::createInstanceFromDescription (const PluginDescription& desc, - double sampleRate, int blockSize) -{ - ScopedPointer result; - - if (fileMightContainThisPluginType (desc.fileOrIdentifier)) - { - File file (desc.fileOrIdentifier); - - const File previousWorkingDirectory (File::getCurrentWorkingDirectory()); - file.getParentDirectory().setAsCurrentWorkingDirectory(); - - if (ModuleHandle::Ptr module = ModuleHandle::findOrCreateModule (file)) - { - shellUIDToCreate = desc.uid; - - result = new VSTPluginInstance (module); - - if (result->effect != nullptr) - { - result->effect->resvd2 = (VstIntPtr) (pointer_sized_int) (VSTPluginInstance*) result; - result->initialise (sampleRate, blockSize); - } - else - { - result = nullptr; - } - } - - previousWorkingDirectory.setAsCurrentWorkingDirectory(); - } - - return result.release(); -} - -bool VSTPluginFormat::fileMightContainThisPluginType (const String& fileOrIdentifier) -{ - const File f (File::createFileWithoutCheckingPath (fileOrIdentifier)); - - #if JUCE_MAC - if (f.isDirectory() && f.hasFileExtension (".vst")) - return true; - - #if JUCE_PPC - FSRef fileRef; - if (makeFSRefFromPath (&fileRef, f.getFullPathName())) - { - const short resFileId = FSOpenResFile (&fileRef, fsRdPerm); - - if (resFileId != -1) - { - const int numEffects = Count1Resources ('aEff'); - CloseResFile (resFileId); - - if (numEffects > 0) - return true; - } - } - #endif - - return false; - #elif JUCE_WINDOWS - return f.existsAsFile() && f.hasFileExtension (".dll"); - #elif JUCE_LINUX - return f.existsAsFile() && f.hasFileExtension (".so"); - #endif -} - -String VSTPluginFormat::getNameOfPluginFromIdentifier (const String& fileOrIdentifier) -{ - return fileOrIdentifier; -} - -bool VSTPluginFormat::pluginNeedsRescanning (const PluginDescription& desc) -{ - return File (desc.fileOrIdentifier).getLastModificationTime() != desc.lastFileModTime; -} - -bool VSTPluginFormat::doesPluginStillExist (const PluginDescription& desc) -{ - return File (desc.fileOrIdentifier).exists(); -} - -StringArray VSTPluginFormat::searchPathsForPlugins (const FileSearchPath& directoriesToSearch, const bool recursive) -{ - StringArray results; - - for (int j = 0; j < directoriesToSearch.getNumPaths(); ++j) - recursiveFileSearch (results, directoriesToSearch [j], recursive); - - return results; -} - -void VSTPluginFormat::recursiveFileSearch (StringArray& results, const File& dir, const bool recursive) -{ - // avoid allowing the dir iterator to be recursive, because we want to avoid letting it delve inside - // .component or .vst directories. - DirectoryIterator iter (dir, false, "*", File::findFilesAndDirectories); - - while (iter.next()) - { - const File f (iter.getFile()); - bool isPlugin = false; - - if (fileMightContainThisPluginType (f.getFullPathName())) - { - isPlugin = true; - results.add (f.getFullPathName()); - } - - if (recursive && (! isPlugin) && f.isDirectory()) - recursiveFileSearch (results, f, true); - } -} - -FileSearchPath VSTPluginFormat::getDefaultLocationsToSearch() -{ - #if JUCE_MAC - return FileSearchPath ("~/Library/Audio/Plug-Ins/VST;/Library/Audio/Plug-Ins/VST"); - #elif JUCE_LINUX - return FileSearchPath (SystemStats::getEnvironmentVariable ("VST_PATH", - "/usr/lib/vst;/usr/local/lib/vst;~/.vst") - .replace (":", ";")); - #elif JUCE_WINDOWS - const String programFiles (File::getSpecialLocation (File::globalApplicationsDirectory).getFullPathName()); - - FileSearchPath paths; - paths.add (WindowsRegistry::getValue ("HKLM\\Software\\VST\\VSTPluginsPath", - programFiles + "\\Steinberg\\VstPlugins")); - paths.removeNonExistentPaths(); - - paths.add (WindowsRegistry::getValue ("HKLM\\Software\\VST\\VSTPluginsPath", - programFiles + "\\VstPlugins")); - return paths; - #endif -} - -const XmlElement* VSTPluginFormat::getVSTXML (AudioPluginInstance* plugin) -{ - if (VSTPluginInstance* const vst = dynamic_cast (plugin)) - if (vst->module != nullptr) - return vst->module->vstXml.get(); - - return nullptr; -} - -bool VSTPluginFormat::loadFromFXBFile (AudioPluginInstance* plugin, const void* data, size_t dataSize) -{ - if (VSTPluginInstance* vst = dynamic_cast (plugin)) - return vst->loadFromFXBFile (data, dataSize); - - return false; -} - -bool VSTPluginFormat::saveToFXBFile (AudioPluginInstance* plugin, MemoryBlock& dest, bool asFXB) -{ - if (VSTPluginInstance* vst = dynamic_cast (plugin)) - return vst->saveToFXBFile (dest, asFXB); - - return false; -} - -bool VSTPluginFormat::getChunkData (AudioPluginInstance* plugin, MemoryBlock& result, bool isPreset) -{ - if (VSTPluginInstance* vst = dynamic_cast (plugin)) - return vst->getChunkData (result, isPreset, 128); - - return false; -} - -bool VSTPluginFormat::setChunkData (AudioPluginInstance* plugin, const void* data, int size, bool isPreset) -{ - if (VSTPluginInstance* vst = dynamic_cast (plugin)) - return vst->setChunkData (data, size, isPreset); - - return false; -} - -void VSTPluginFormat::setExtraFunctions (AudioPluginInstance* plugin, ExtraFunctions* functions) -{ - ScopedPointer f (functions); - - if (VSTPluginInstance* vst = dynamic_cast (plugin)) - vst->extraFunctions = f; -} - -VSTPluginFormat::VstIntPtr JUCE_CALLTYPE VSTPluginFormat::dispatcher (AudioPluginInstance* plugin, int32 opcode, int32 index, VstIntPtr value, void* ptr, float opt) -{ - if (VSTPluginInstance* vst = dynamic_cast (plugin)) - return vst->dispatch (opcode, index, value, ptr, opt); - - return 0; -} - -void VSTPluginFormat::aboutToScanVSTShellPlugin (const PluginDescription&) {} - -#endif diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.h deleted file mode 100644 index 4e4b744176..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.h +++ /dev/null @@ -1,113 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#if JUCE_PLUGINHOST_VST || DOXYGEN - -//============================================================================== -/** - Implements a plugin format manager for VSTs. -*/ -class JUCE_API VSTPluginFormat : public AudioPluginFormat -{ -public: - //============================================================================== - VSTPluginFormat(); - ~VSTPluginFormat(); - - //============================================================================== - /** Attempts to retreive the VSTXML data from a plugin. - Will return nullptr if the plugin isn't a VST, or if it doesn't have any VSTXML. - */ - static const XmlElement* getVSTXML (AudioPluginInstance* plugin); - - /** Attempts to reload a VST plugin's state from some FXB or FXP data. */ - static bool loadFromFXBFile (AudioPluginInstance* plugin, const void* data, size_t dataSize); - - /** Attempts to save a VST's state to some FXP or FXB data. */ - static bool saveToFXBFile (AudioPluginInstance* plugin, MemoryBlock& result, bool asFXB); - - /** Attempts to get a VST's state as a chunk of memory. */ - static bool getChunkData (AudioPluginInstance* plugin, MemoryBlock& result, bool isPreset); - - /** Attempts to set a VST's state from a chunk of memory. */ - static bool setChunkData (AudioPluginInstance* plugin, const void* data, int size, bool isPreset); - - //============================================================================== - /** Base class for some extra functions that can be attached to a VST plugin instance. */ - class ExtraFunctions - { - public: - virtual ~ExtraFunctions() {} - - /** This should return 10000 * the BPM at this position in the current edit. */ - virtual int64 getTempoAt (int64 samplePos) = 0; - - /** This should return the host's automation state. - @returns 0 = not supported, 1 = off, 2 = read, 3 = write, 4 = read/write - */ - virtual int getAutomationState() = 0; - }; - - /** Provides an ExtraFunctions callback object for a plugin to use. - The plugin will take ownership of the object and will delete it automatically. - */ - static void setExtraFunctions (AudioPluginInstance* plugin, ExtraFunctions* functions); - - //============================================================================== - #if JUCE_64BIT - typedef int64 VstIntPtr; - #else - typedef int32 VstIntPtr; - #endif - - /** This simply calls directly to the VST's AEffect::dispatcher() function. */ - static VstIntPtr JUCE_CALLTYPE dispatcher (AudioPluginInstance*, int32, int32, VstIntPtr, void*, float); - - //============================================================================== - String getName() const override { return "VST"; } - void findAllTypesForFile (OwnedArray&, const String& fileOrIdentifier) override; - AudioPluginInstance* createInstanceFromDescription (const PluginDescription&, double, int) override; - bool fileMightContainThisPluginType (const String& fileOrIdentifier) override; - String getNameOfPluginFromIdentifier (const String& fileOrIdentifier) override; - bool pluginNeedsRescanning (const PluginDescription&) override; - StringArray searchPathsForPlugins (const FileSearchPath&, bool recursive) override; - bool doesPluginStillExist (const PluginDescription&) override; - FileSearchPath getDefaultLocationsToSearch() override; - bool canScanForPlugins() const override { return true; } - - /** Can be overridden to receive a callback when each member of a shell plugin is about to be - tested during a call to findAllTypesForFile(). - Only the name and uid members of the PluginDescription are guaranteed to be valid when - this is called. - */ - virtual void aboutToScanVSTShellPlugin (const PluginDescription&); - -private: - void recursiveFileSearch (StringArray&, const File&, bool recursive); - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (VSTPluginFormat) -}; - - -#endif diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/juce_audio_processors.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/juce_audio_processors.cpp deleted file mode 100644 index d1f1679fba..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/juce_audio_processors.cpp +++ /dev/null @@ -1,158 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#if defined (JUCE_AUDIO_PROCESSORS_H_INCLUDED) && ! JUCE_AMALGAMATED_INCLUDE - /* When you add this cpp file to your project, you mustn't include it in a file where you've - already included any other headers - just put it inside a file on its own, possibly with your config - flags preceding it, but don't include anything else. That also includes avoiding any automatic prefix - header files that the compiler may be using. - */ - #error "Incorrect use of JUCE cpp file" -#endif - -// Your project must contain an AppConfig.h file with your project-specific settings in it, -// and your header search path must make it accessible to the module's files. -#include "AppConfig.h" - -#include "../juce_core/native/juce_BasicNativeHeaders.h" -#include "juce_audio_processors.h" -#include "../juce_gui_extra/juce_gui_extra.h" - -//============================================================================== -#if JUCE_MAC - #if JUCE_SUPPORT_CARBON \ - && ((JUCE_PLUGINHOST_VST || JUCE_PLUGINHOST_AU) \ - || ! (defined (MAC_OS_X_VERSION_10_6) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_6)) - #define Point CarbonDummyPointName // (workaround to avoid definition of "Point" by old Carbon headers) - #define Component CarbonDummyCompName - #include - #undef Point - #undef Component - #endif -#endif - -#if JUCE_PLUGINHOST_VST && JUCE_LINUX - #include - #include - #undef KeyPress -#endif - -#if ! JUCE_WINDOWS && ! JUCE_MAC - #undef JUCE_PLUGINHOST_VST3 - #define JUCE_PLUGINHOST_VST3 0 -#endif - -//============================================================================== -namespace juce -{ - -static inline bool arrayContainsPlugin (const OwnedArray& list, - const PluginDescription& desc) -{ - for (int i = list.size(); --i >= 0;) - if (list.getUnchecked(i)->isDuplicateOf (desc)) - return true; - - return false; -} - -#if JUCE_MAC -//============================================================================== -struct AutoResizingNSViewComponent : public NSViewComponent, - private AsyncUpdater -{ - AutoResizingNSViewComponent() : recursive (false) {} - - void childBoundsChanged (Component*) override - { - if (recursive) - { - triggerAsyncUpdate(); - } - else - { - recursive = true; - resizeToFitView(); - recursive = true; - } - } - - void handleAsyncUpdate() override { resizeToFitView(); } - - bool recursive; -}; - -//============================================================================== -struct AutoResizingNSViewComponentWithParent : public AutoResizingNSViewComponent, - private Timer -{ - AutoResizingNSViewComponentWithParent() - { - NSView* v = [[NSView alloc] init]; - setView (v); - [v release]; - - startTimer (30); - } - - NSView* getChildView() const - { - if (NSView* parent = (NSView*) getView()) - if ([[parent subviews] count] > 0) - return [[parent subviews] objectAtIndex: 0]; - - return nil; - } - - void timerCallback() override - { - if (NSView* child = getChildView()) - { - stopTimer(); - setView (child); - } - } -}; -#endif - -#if JUCE_CLANG - #pragma clang diagnostic ignored "-Wdeprecated-declarations" -#endif - -#include "format/juce_AudioPluginFormat.cpp" -#include "format/juce_AudioPluginFormatManager.cpp" -#include "processors/juce_AudioProcessor.cpp" -#include "processors/juce_AudioProcessorEditor.cpp" -#include "processors/juce_AudioProcessorGraph.cpp" -#include "processors/juce_GenericAudioProcessorEditor.cpp" -#include "processors/juce_PluginDescription.cpp" -#include "format_types/juce_LADSPAPluginFormat.cpp" -#include "format_types/juce_VSTPluginFormat.cpp" -#include "format_types/juce_VST3PluginFormat.cpp" -#include "format_types/juce_AudioUnitPluginFormat.mm" -#include "scanning/juce_KnownPluginList.cpp" -#include "scanning/juce_PluginDirectoryScanner.cpp" -#include "scanning/juce_PluginListComponent.cpp" - -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/juce_audio_processors.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/juce_audio_processors.h index 2811656805..bd61929b93 100644 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/juce_audio_processors.h +++ b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/juce_audio_processors.h @@ -1,98 +1,5 @@ -/* - ============================================================================== +// This is an auto-generated file to redirect any included +// module headers to the correct external folder. - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. +#include "../../../../../modules/juce_audio_processors/juce_audio_processors.h" - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_AUDIO_PROCESSORS_H_INCLUDED -#define JUCE_AUDIO_PROCESSORS_H_INCLUDED - -#include "../juce_gui_basics/juce_gui_basics.h" -#include "../juce_audio_basics/juce_audio_basics.h" - - -//============================================================================= -/** Config: JUCE_PLUGINHOST_VST - Enables the VST audio plugin hosting classes. This requires the Steinberg VST SDK to be - installed on your machine. - - @see VSTPluginFormat, VST3PluginFormat, AudioPluginFormat, AudioPluginFormatManager, JUCE_PLUGINHOST_AU, JUCE_PLUGINHOST_VST3 -*/ -#ifndef JUCE_PLUGINHOST_VST - #define JUCE_PLUGINHOST_VST 0 -#endif - -/** Config: JUCE_PLUGINHOST_VST3 - Enables the VST3 audio plugin hosting classes. This requires the Steinberg VST3 SDK to be - installed on your machine. - - @see VSTPluginFormat, VST3PluginFormat, AudioPluginFormat, AudioPluginFormatManager, JUCE_PLUGINHOST_VST, JUCE_PLUGINHOST_AU -*/ -#ifndef JUCE_PLUGINHOST_VST3 - #define JUCE_PLUGINHOST_VST3 0 -#endif - -/** Config: JUCE_PLUGINHOST_AU - Enables the AudioUnit plugin hosting classes. This is Mac-only, of course. - - @see AudioUnitPluginFormat, AudioPluginFormat, AudioPluginFormatManager, JUCE_PLUGINHOST_VST, JUCE_PLUGINHOST_VST3 -*/ -#ifndef JUCE_PLUGINHOST_AU - #define JUCE_PLUGINHOST_AU 0 -#endif - -#if ! (JUCE_PLUGINHOST_AU || JUCE_PLUGINHOST_VST || JUCE_PLUGINHOST_VST3) -// #error "You need to set either the JUCE_PLUGINHOST_AU and/or JUCE_PLUGINHOST_VST and/or JUCE_PLUGINHOST_VST3 flags if you're using this module!" -#endif - -#if ! (defined (JUCE_SUPPORT_CARBON) || JUCE_64BIT) - #define JUCE_SUPPORT_CARBON 1 -#endif - -//============================================================================= -//============================================================================= -namespace juce -{ - -class AudioProcessor; -#include "processors/juce_AudioPlayHead.h" -#include "processors/juce_AudioProcessorEditor.h" -#include "processors/juce_AudioProcessorListener.h" -#include "processors/juce_AudioProcessorParameter.h" -#include "processors/juce_AudioProcessor.h" -#include "processors/juce_PluginDescription.h" -#include "processors/juce_AudioPluginInstance.h" -#include "processors/juce_AudioProcessorGraph.h" -#include "processors/juce_GenericAudioProcessorEditor.h" -#include "format/juce_AudioPluginFormat.h" -#include "format/juce_AudioPluginFormatManager.h" -#include "scanning/juce_KnownPluginList.h" -#include "format_types/juce_AudioUnitPluginFormat.h" -#include "format_types/juce_LADSPAPluginFormat.h" -#include "format_types/juce_VSTMidiEventList.h" -#include "format_types/juce_VSTPluginFormat.h" -#include "format_types/juce_VST3PluginFormat.h" -#include "scanning/juce_PluginDirectoryScanner.h" -#include "scanning/juce_PluginListComponent.h" - -} - -#endif // JUCE_AUDIO_PROCESSORS_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/juce_audio_processors.mm b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/juce_audio_processors.mm deleted file mode 100644 index 918e84810a..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/juce_audio_processors.mm +++ /dev/null @@ -1,25 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#include "juce_audio_processors.cpp" diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/juce_module_info b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/juce_module_info deleted file mode 100644 index 40a0d87714..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/juce_module_info +++ /dev/null @@ -1,25 +0,0 @@ -{ - "id": "juce_audio_processors", - "name": "JUCE audio plugin hosting classes", - "version": "3.0.8", - "description": "Classes for loading and playing VST, AU, or internally-generated audio processors.", - "website": "http://www.juce.com/juce", - "license": "GPL/Commercial", - - "dependencies": [ { "id": "juce_gui_extra", "version": "matching" }, - { "id": "juce_audio_basics", "version": "matching" } ], - - "include": "juce_audio_processors.h", - - "compile": [ { "file": "juce_audio_processors.cpp", "target": "! xcode" }, - { "file": "juce_audio_processors.mm", "target": "xcode" } ], - - "browse": [ "processors/*", - "format/*", - "format_types/*", - "scanning/*" - ], - - "OSXFrameworks": "CoreAudio CoreMIDI AudioToolbox", - "iOSFrameworks": "AudioToolbox" -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/processors/juce_AudioPlayHead.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/processors/juce_AudioPlayHead.h deleted file mode 100644 index b92b802f92..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/processors/juce_AudioPlayHead.h +++ /dev/null @@ -1,140 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_AUDIOPLAYHEAD_H_INCLUDED -#define JUCE_AUDIOPLAYHEAD_H_INCLUDED - - -//============================================================================== -/** - A subclass of AudioPlayHead can supply information about the position and - status of a moving play head during audio playback. - - One of these can be supplied to an AudioProcessor object so that it can find - out about the position of the audio that it is rendering. - - @see AudioProcessor::setPlayHead, AudioProcessor::getPlayHead -*/ -class JUCE_API AudioPlayHead -{ -protected: - //============================================================================== - AudioPlayHead() {} - -public: - virtual ~AudioPlayHead() {} - - //============================================================================== - /** Frame rate types. */ - enum FrameRateType - { - fps24 = 0, - fps25 = 1, - fps2997 = 2, - fps30 = 3, - fps2997drop = 4, - fps30drop = 5, - fpsUnknown = 99 - }; - - //============================================================================== - /** This structure is filled-in by the AudioPlayHead::getCurrentPosition() method. - */ - struct JUCE_API CurrentPositionInfo - { - /** The tempo in BPM */ - double bpm; - - /** Time signature numerator, e.g. the 3 of a 3/4 time sig */ - int timeSigNumerator; - /** Time signature denominator, e.g. the 4 of a 3/4 time sig */ - int timeSigDenominator; - - /** The current play position, in samples from the start of the edit. */ - int64 timeInSamples; - /** The current play position, in seconds from the start of the edit. */ - double timeInSeconds; - - /** For timecode, the position of the start of the edit, in seconds from 00:00:00:00. */ - double editOriginTime; - - /** The current play position, in pulses-per-quarter-note. */ - double ppqPosition; - - /** The position of the start of the last bar, in pulses-per-quarter-note. - - This is the time from the start of the edit to the start of the current - bar, in ppq units. - - Note - this value may be unavailable on some hosts, e.g. Pro-Tools. If - it's not available, the value will be 0. - */ - double ppqPositionOfLastBarStart; - - /** The video frame rate, if applicable. */ - FrameRateType frameRate; - - /** True if the transport is currently playing. */ - bool isPlaying; - - /** True if the transport is currently recording. - - (When isRecording is true, then isPlaying will also be true). - */ - bool isRecording; - - /** The current cycle start position in pulses-per-quarter-note. - Note that not all hosts or plugin formats may provide this value. - @see isLooping - */ - double ppqLoopStart; - - /** The current cycle end position in pulses-per-quarter-note. - Note that not all hosts or plugin formats may provide this value. - @see isLooping - */ - double ppqLoopEnd; - - /** True if the transport is currently looping. */ - bool isLooping; - - //============================================================================== - bool operator== (const CurrentPositionInfo& other) const noexcept; - bool operator!= (const CurrentPositionInfo& other) const noexcept; - - void resetToDefault(); - }; - - //============================================================================== - /** Fills-in the given structure with details about the transport's - position at the start of the current processing block. - - This method must ONLY be called from within your AudioProcessor::processBlock() - method. Calling it at any other time will probably cause a nasty crash. - */ - virtual bool getCurrentPosition (CurrentPositionInfo& result) = 0; -}; - - -#endif // JUCE_AUDIOPLAYHEAD_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/processors/juce_AudioPluginInstance.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/processors/juce_AudioPluginInstance.h deleted file mode 100644 index b7c7b7dc37..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/processors/juce_AudioPluginInstance.h +++ /dev/null @@ -1,86 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_AUDIOPLUGININSTANCE_H_INCLUDED -#define JUCE_AUDIOPLUGININSTANCE_H_INCLUDED - - -//============================================================================== -/** - Base class for an active instance of a plugin. - - This derives from the AudioProcessor class, and adds some extra functionality - that helps when wrapping dynamically loaded plugins. - - This class is not needed when writing plugins, and you should never need to derive - your own sub-classes from it. The plugin hosting classes use it internally and will - return AudioPluginInstance objects which wrap external plugins. - - @see AudioProcessor, AudioPluginFormat -*/ -class JUCE_API AudioPluginInstance : public AudioProcessor -{ -public: - //============================================================================== - /** Destructor. - - Make sure that you delete any UI components that belong to this plugin before - deleting the plugin. - */ - virtual ~AudioPluginInstance() {} - - //============================================================================== - /** Fills-in the appropriate parts of this plugin description object. */ - virtual void fillInPluginDescription (PluginDescription& description) const = 0; - - /** Returns a PluginDescription for this plugin. - This is just a convenience method to avoid calling fillInPluginDescription. - */ - PluginDescription getPluginDescription() const - { - PluginDescription desc; - fillInPluginDescription (desc); - return desc; - } - - /** Returns a pointer to some kind of platform-specific data about the plugin. - E.g. For a VST, this value can be cast to an AEffect*. For an AudioUnit, it can be - cast to an AudioUnit handle. - */ - virtual void* getPlatformSpecificData() { return nullptr; } - - /** For some formats (currently AudioUnit), this forces a reload of the list of - available parameters. - */ - virtual void refreshParameterList() {} - -protected: - //============================================================================== - AudioPluginInstance() {} - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioPluginInstance) -}; - - -#endif // JUCE_AUDIOPLUGININSTANCE_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/processors/juce_AudioProcessor.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/processors/juce_AudioProcessor.cpp deleted file mode 100644 index e46dba37e8..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/processors/juce_AudioProcessor.cpp +++ /dev/null @@ -1,474 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -static ThreadLocalValue wrapperTypeBeingCreated; - -void JUCE_CALLTYPE AudioProcessor::setTypeOfNextNewPlugin (AudioProcessor::WrapperType type) -{ - wrapperTypeBeingCreated = type; -} - -AudioProcessor::AudioProcessor() - : wrapperType (wrapperTypeBeingCreated.get()), - playHead (nullptr), - sampleRate (0), - blockSize (0), - numInputChannels (0), - numOutputChannels (0), - latencySamples (0), - suspended (false), - nonRealtime (false) -{ -} - -AudioProcessor::~AudioProcessor() -{ - // ooh, nasty - the editor should have been deleted before the filter - // that it refers to is deleted.. - jassert (activeEditor == nullptr); - - #if JUCE_DEBUG - // This will fail if you've called beginParameterChangeGesture() for one - // or more parameters without having made a corresponding call to endParameterChangeGesture... - jassert (changingParams.countNumberOfSetBits() == 0); - #endif -} - -void AudioProcessor::setPlayHead (AudioPlayHead* const newPlayHead) -{ - playHead = newPlayHead; -} - -void AudioProcessor::addListener (AudioProcessorListener* const newListener) -{ - const ScopedLock sl (listenerLock); - listeners.addIfNotAlreadyThere (newListener); -} - -void AudioProcessor::removeListener (AudioProcessorListener* const listenerToRemove) -{ - const ScopedLock sl (listenerLock); - listeners.removeFirstMatchingValue (listenerToRemove); -} - -void AudioProcessor::setPlayConfigDetails (const int newNumIns, - const int newNumOuts, - const double newSampleRate, - const int newBlockSize) noexcept -{ - sampleRate = newSampleRate; - blockSize = newBlockSize; - - if (numInputChannels != newNumIns || numOutputChannels != newNumOuts) - { - numInputChannels = newNumIns; - numOutputChannels = newNumOuts; - - numChannelsChanged(); - } -} - -void AudioProcessor::numChannelsChanged() {} - -void AudioProcessor::setSpeakerArrangement (const String& inputs, const String& outputs) -{ - inputSpeakerArrangement = inputs; - outputSpeakerArrangement = outputs; -} - -void AudioProcessor::setNonRealtime (const bool newNonRealtime) noexcept -{ - nonRealtime = newNonRealtime; -} - -void AudioProcessor::setLatencySamples (const int newLatency) -{ - if (latencySamples != newLatency) - { - latencySamples = newLatency; - updateHostDisplay(); - } -} - -void AudioProcessor::setParameterNotifyingHost (const int parameterIndex, - const float newValue) -{ - setParameter (parameterIndex, newValue); - sendParamChangeMessageToListeners (parameterIndex, newValue); -} - -AudioProcessorListener* AudioProcessor::getListenerLocked (const int index) const noexcept -{ - const ScopedLock sl (listenerLock); - return listeners [index]; -} - -void AudioProcessor::sendParamChangeMessageToListeners (const int parameterIndex, const float newValue) -{ - if (isPositiveAndBelow (parameterIndex, getNumParameters())) - { - for (int i = listeners.size(); --i >= 0;) - if (AudioProcessorListener* l = getListenerLocked (i)) - l->audioProcessorParameterChanged (this, parameterIndex, newValue); - } - else - { - jassertfalse; // called with an out-of-range parameter index! - } -} - -void AudioProcessor::beginParameterChangeGesture (int parameterIndex) -{ - if (isPositiveAndBelow (parameterIndex, getNumParameters())) - { - #if JUCE_DEBUG - // This means you've called beginParameterChangeGesture twice in succession without a matching - // call to endParameterChangeGesture. That might be fine in most hosts, but better to avoid doing it. - jassert (! changingParams [parameterIndex]); - changingParams.setBit (parameterIndex); - #endif - - for (int i = listeners.size(); --i >= 0;) - if (AudioProcessorListener* l = getListenerLocked (i)) - l->audioProcessorParameterChangeGestureBegin (this, parameterIndex); - } - else - { - jassertfalse; // called with an out-of-range parameter index! - } -} - -void AudioProcessor::endParameterChangeGesture (int parameterIndex) -{ - if (isPositiveAndBelow (parameterIndex, getNumParameters())) - { - #if JUCE_DEBUG - // This means you've called endParameterChangeGesture without having previously called - // endParameterChangeGesture. That might be fine in most hosts, but better to keep the - // calls matched correctly. - jassert (changingParams [parameterIndex]); - changingParams.clearBit (parameterIndex); - #endif - - for (int i = listeners.size(); --i >= 0;) - if (AudioProcessorListener* l = getListenerLocked (i)) - l->audioProcessorParameterChangeGestureEnd (this, parameterIndex); - } - else - { - jassertfalse; // called with an out-of-range parameter index! - } -} - -void AudioProcessor::updateHostDisplay() -{ - for (int i = listeners.size(); --i >= 0;) - if (AudioProcessorListener* l = getListenerLocked (i)) - l->audioProcessorChanged (this); -} - -const OwnedArray& AudioProcessor::getParameters() const noexcept -{ - return managedParameters; -} - -int AudioProcessor::getNumParameters() -{ - return managedParameters.size(); -} - -float AudioProcessor::getParameter (int index) -{ - if (AudioProcessorParameter* p = getParamChecked (index)) - return p->getValue(); - - return 0; -} - -void AudioProcessor::setParameter (int index, float newValue) -{ - if (AudioProcessorParameter* p = getParamChecked (index)) - p->setValue (newValue); -} - -float AudioProcessor::getParameterDefaultValue (int index) -{ - if (AudioProcessorParameter* p = managedParameters[index]) - return p->getDefaultValue(); - - return 0; -} - -const String AudioProcessor::getParameterName (int index) -{ - if (AudioProcessorParameter* p = getParamChecked (index)) - return p->getName (512); - - return String(); -} - -String AudioProcessor::getParameterName (int index, int maximumStringLength) -{ - if (AudioProcessorParameter* p = managedParameters[index]) - return p->getName (maximumStringLength); - - return getParameterName (index).substring (0, maximumStringLength); -} - -const String AudioProcessor::getParameterText (int index) -{ - return getParameterText (index, 1024); -} - -String AudioProcessor::getParameterText (int index, int maximumStringLength) -{ - if (AudioProcessorParameter* p = managedParameters[index]) - return p->getText (p->getValue(), maximumStringLength); - - return getParameterText (index).substring (0, maximumStringLength); -} - -int AudioProcessor::getParameterNumSteps (int index) -{ - if (AudioProcessorParameter* p = managedParameters[index]) - return p->getNumSteps(); - - return AudioProcessor::getDefaultNumParameterSteps(); -} - -int AudioProcessor::getDefaultNumParameterSteps() noexcept -{ - return 0x7fffffff; -} - -String AudioProcessor::getParameterLabel (int index) const -{ - if (AudioProcessorParameter* p = managedParameters[index]) - return p->getLabel(); - - return String(); -} - -bool AudioProcessor::isParameterAutomatable (int index) const -{ - if (AudioProcessorParameter* p = managedParameters[index]) - return p->isAutomatable(); - - return true; -} - -bool AudioProcessor::isParameterOrientationInverted (int index) const -{ - if (AudioProcessorParameter* p = managedParameters[index]) - return p->isOrientationInverted(); - - return false; -} - -bool AudioProcessor::isMetaParameter (int index) const -{ - if (AudioProcessorParameter* p = managedParameters[index]) - return p->isMetaParameter(); - - return false; -} - -AudioProcessorParameter* AudioProcessor::getParamChecked (int index) const noexcept -{ - AudioProcessorParameter* p = managedParameters[index]; - - // If you hit this, then you're either trying to access parameters that are out-of-range, - // or you're not using addParameter and the managed parameter list, but have failed - // to override some essential virtual methods and implement them appropriately. - jassert (p != nullptr); - return p; -} - -void AudioProcessor::addParameter (AudioProcessorParameter* p) -{ - p->processor = this; - p->parameterIndex = managedParameters.size(); - managedParameters.add (p); -} - -void AudioProcessor::suspendProcessing (const bool shouldBeSuspended) -{ - const ScopedLock sl (callbackLock); - suspended = shouldBeSuspended; -} - -void AudioProcessor::reset() {} -void AudioProcessor::processBlockBypassed (AudioSampleBuffer&, MidiBuffer&) {} - -//============================================================================== -void AudioProcessor::editorBeingDeleted (AudioProcessorEditor* const editor) noexcept -{ - const ScopedLock sl (callbackLock); - - if (activeEditor == editor) - activeEditor = nullptr; -} - -AudioProcessorEditor* AudioProcessor::createEditorIfNeeded() -{ - if (activeEditor != nullptr) - return activeEditor; - - AudioProcessorEditor* const ed = createEditor(); - - if (ed != nullptr) - { - // you must give your editor comp a size before returning it.. - jassert (ed->getWidth() > 0 && ed->getHeight() > 0); - - const ScopedLock sl (callbackLock); - activeEditor = ed; - } - - // You must make your hasEditor() method return a consistent result! - jassert (hasEditor() == (ed != nullptr)); - - return ed; -} - -//============================================================================== -void AudioProcessor::getCurrentProgramStateInformation (juce::MemoryBlock& destData) -{ - getStateInformation (destData); -} - -void AudioProcessor::setCurrentProgramStateInformation (const void* data, int sizeInBytes) -{ - setStateInformation (data, sizeInBytes); -} - -//============================================================================== -// magic number to identify memory blocks that we've stored as XML -const uint32 magicXmlNumber = 0x21324356; - -void AudioProcessor::copyXmlToBinary (const XmlElement& xml, juce::MemoryBlock& destData) -{ - { - MemoryOutputStream out (destData, false); - out.writeInt (magicXmlNumber); - out.writeInt (0); - xml.writeToStream (out, String(), true, false); - out.writeByte (0); - } - - // go back and write the string length.. - static_cast (destData.getData())[1] - = ByteOrder::swapIfBigEndian ((uint32) destData.getSize() - 9); -} - -XmlElement* AudioProcessor::getXmlFromBinary (const void* data, const int sizeInBytes) -{ - if (sizeInBytes > 8 - && ByteOrder::littleEndianInt (data) == magicXmlNumber) - { - const int stringLength = (int) ByteOrder::littleEndianInt (addBytesToPointer (data, 4)); - - if (stringLength > 0) - return XmlDocument::parse (String::fromUTF8 (static_cast (data) + 8, - jmin ((sizeInBytes - 8), stringLength))); - } - - return nullptr; -} - -//============================================================================== -void AudioProcessorListener::audioProcessorParameterChangeGestureBegin (AudioProcessor*, int) {} -void AudioProcessorListener::audioProcessorParameterChangeGestureEnd (AudioProcessor*, int) {} - -//============================================================================== -AudioProcessorParameter::AudioProcessorParameter() noexcept - : processor (nullptr), parameterIndex (-1) -{} - -AudioProcessorParameter::~AudioProcessorParameter() {} - -void AudioProcessorParameter::setValueNotifyingHost (float newValue) -{ - // This method can't be used until the parameter has been attached to a processor! - jassert (processor != nullptr && parameterIndex >= 0); - - return processor->setParameterNotifyingHost (parameterIndex, newValue); -} - -void AudioProcessorParameter::beginChangeGesture() -{ - // This method can't be used until the parameter has been attached to a processor! - jassert (processor != nullptr && parameterIndex >= 0); - - processor->beginParameterChangeGesture (parameterIndex); -} - -void AudioProcessorParameter::endChangeGesture() -{ - // This method can't be used until the parameter has been attached to a processor! - jassert (processor != nullptr && parameterIndex >= 0); - - processor->endParameterChangeGesture (parameterIndex); -} - -bool AudioProcessorParameter::isOrientationInverted() const { return false; } -bool AudioProcessorParameter::isAutomatable() const { return true; } -bool AudioProcessorParameter::isMetaParameter() const { return false; } -int AudioProcessorParameter::getNumSteps() const { return AudioProcessor::getDefaultNumParameterSteps(); } - -String AudioProcessorParameter::getText (float value, int /*maximumStringLength*/) const -{ - return String (value, 2); -} - -//============================================================================== -bool AudioPlayHead::CurrentPositionInfo::operator== (const CurrentPositionInfo& other) const noexcept -{ - return timeInSamples == other.timeInSamples - && ppqPosition == other.ppqPosition - && editOriginTime == other.editOriginTime - && ppqPositionOfLastBarStart == other.ppqPositionOfLastBarStart - && frameRate == other.frameRate - && isPlaying == other.isPlaying - && isRecording == other.isRecording - && bpm == other.bpm - && timeSigNumerator == other.timeSigNumerator - && timeSigDenominator == other.timeSigDenominator - && ppqLoopStart == other.ppqLoopStart - && ppqLoopEnd == other.ppqLoopEnd - && isLooping == other.isLooping; -} - -bool AudioPlayHead::CurrentPositionInfo::operator!= (const CurrentPositionInfo& other) const noexcept -{ - return ! operator== (other); -} - -void AudioPlayHead::CurrentPositionInfo::resetToDefault() -{ - zerostruct (*this); - timeSigNumerator = 4; - timeSigDenominator = 4; - bpm = 120; -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/processors/juce_AudioProcessor.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/processors/juce_AudioProcessor.h deleted file mode 100644 index aaae9ef172..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/processors/juce_AudioProcessor.h +++ /dev/null @@ -1,689 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_AUDIOPROCESSOR_H_INCLUDED -#define JUCE_AUDIOPROCESSOR_H_INCLUDED - - -//============================================================================== -/** - Base class for audio processing filters or plugins. - - This is intended to act as a base class of audio filter that is general enough to - be wrapped as a VST, AU, RTAS, etc, or used internally. - - It is also used by the plugin hosting code as the wrapper around an instance - of a loaded plugin. - - Derive your filter class from this base class, and if you're building a plugin, - you should implement a global function called createPluginFilter() which creates - and returns a new instance of your subclass. -*/ -class JUCE_API AudioProcessor -{ -protected: - //============================================================================== - /** Constructor. */ - AudioProcessor(); - -public: - /** Destructor. */ - virtual ~AudioProcessor(); - - //============================================================================== - /** Returns the name of this processor. */ - virtual const String getName() const = 0; - - //============================================================================== - /** Called before playback starts, to let the filter prepare itself. - - The sample rate is the target sample rate, and will remain constant until - playback stops. - - The estimatedSamplesPerBlock value is a HINT about the typical number of - samples that will be processed for each callback, but isn't any kind - of guarantee. The actual block sizes that the host uses may be different - each time the callback happens, and may be more or less than this value. - */ - virtual void prepareToPlay (double sampleRate, - int estimatedSamplesPerBlock) = 0; - - /** Called after playback has stopped, to let the filter free up any resources it - no longer needs. - */ - virtual void releaseResources() = 0; - - /** Renders the next block. - - When this method is called, the buffer contains a number of channels which is - at least as great as the maximum number of input and output channels that - this filter is using. It will be filled with the filter's input data and - should be replaced with the filter's output. - - So for example if your filter has 2 input channels and 4 output channels, then - the buffer will contain 4 channels, the first two being filled with the - input data. Your filter should read these, do its processing, and replace - the contents of all 4 channels with its output. - - Or if your filter has 5 inputs and 2 outputs, the buffer will have 5 channels, - all filled with data, and your filter should overwrite the first 2 of these - with its output. But be VERY careful not to write anything to the last 3 - channels, as these might be mapped to memory that the host assumes is read-only! - - Note that if you have more outputs than inputs, then only those channels that - correspond to an input channel are guaranteed to contain sensible data - e.g. - in the case of 2 inputs and 4 outputs, the first two channels contain the input, - but the last two channels may contain garbage, so you should be careful not to - let this pass through without being overwritten or cleared. - - Also note that the buffer may have more channels than are strictly necessary, - but you should only read/write from the ones that your filter is supposed to - be using. - - The number of samples in these buffers is NOT guaranteed to be the same for every - callback, and may be more or less than the estimated value given to prepareToPlay(). - Your code must be able to cope with variable-sized blocks, or you're going to get - clicks and crashes! - - If the filter is receiving a midi input, then the midiMessages array will be filled - with the midi messages for this block. Each message's timestamp will indicate the - message's time, as a number of samples from the start of the block. - - Any messages left in the midi buffer when this method has finished are assumed to - be the filter's midi output. This means that your filter should be careful to - clear any incoming messages from the array if it doesn't want them to be passed-on. - - Be very careful about what you do in this callback - it's going to be called by - the audio thread, so any kind of interaction with the UI is absolutely - out of the question. If you change a parameter in here and need to tell your UI to - update itself, the best way is probably to inherit from a ChangeBroadcaster, let - the UI components register as listeners, and then call sendChangeMessage() inside the - processBlock() method to send out an asynchronous message. You could also use - the AsyncUpdater class in a similar way. - */ - virtual void processBlock (AudioSampleBuffer& buffer, - MidiBuffer& midiMessages) = 0; - - /** Renders the next block when the processor is being bypassed. - The default implementation of this method will pass-through any incoming audio, but - you may override this method e.g. to add latency compensation to the data to match - the processor's latency characteristics. This will avoid situations where bypassing - will shift the signal forward in time, possibly creating pre-echo effects and odd timings. - Another use for this method would be to cross-fade or morph between the wet (not bypassed) - and dry (bypassed) signals. - */ - virtual void processBlockBypassed (AudioSampleBuffer& buffer, - MidiBuffer& midiMessages); - - //============================================================================== - /** Returns the current AudioPlayHead object that should be used to find - out the state and position of the playhead. - - You can call this from your processBlock() method, and use the AudioPlayHead - object to get the details about the time of the start of the block currently - being processed. - - If the host hasn't supplied a playhead object, this will return nullptr. - */ - AudioPlayHead* getPlayHead() const noexcept { return playHead; } - - - //============================================================================== - /** Returns the current sample rate. - - This can be called from your processBlock() method - it's not guaranteed - to be valid at any other time, and may return 0 if it's unknown. - */ - double getSampleRate() const noexcept { return sampleRate; } - - /** Returns the current typical block size that is being used. - - This can be called from your processBlock() method - it's not guaranteed - to be valid at any other time. - - Remember it's not the ONLY block size that may be used when calling - processBlock, it's just the normal one. The actual block sizes used may be - larger or smaller than this, and will vary between successive calls. - */ - int getBlockSize() const noexcept { return blockSize; } - - //============================================================================== - /** Returns the number of input channels that the host will be sending the filter. - - If writing a plugin, your configuration macros should specify the number of - channels that your filter would prefer to have, and this method lets - you know how many the host is actually using. - - Note that this method is only valid during or after the prepareToPlay() - method call. Until that point, the number of channels will be unknown. - */ - int getNumInputChannels() const noexcept { return numInputChannels; } - - /** Returns the number of output channels that the host will be sending the filter. - - If writing a plugin, your configuration macros should specify the number of - channels that your filter would prefer to have, and this method lets - you know how many the host is actually using. - - Note that this method is only valid during or after the prepareToPlay() - method call. Until that point, the number of channels will be unknown. - */ - int getNumOutputChannels() const noexcept { return numOutputChannels; } - - /** Returns a string containing a whitespace-separated list of speaker types - corresponding to each input channel. - For example in a 5.1 arrangement, the string may be "L R C Lfe Ls Rs" - If the speaker arrangement is unknown, the returned string will be empty. - */ - const String& getInputSpeakerArrangement() const noexcept { return inputSpeakerArrangement; } - - /** Returns a string containing a whitespace-separated list of speaker types - corresponding to each output channel. - For example in a 5.1 arrangement, the string may be "L R C Lfe Ls Rs" - If the speaker arrangement is unknown, the returned string will be empty. - */ - const String& getOutputSpeakerArrangement() const noexcept { return outputSpeakerArrangement; } - - //============================================================================== - /** Returns the name of one of the processor's input channels. - - The processor might not supply very useful names for channels, and this might be - something like "1", "2", "left", "right", etc. - */ - virtual const String getInputChannelName (int channelIndex) const = 0; - - /** Returns the name of one of the processor's output channels. - - The processor might not supply very useful names for channels, and this might be - something like "1", "2", "left", "right", etc. - */ - virtual const String getOutputChannelName (int channelIndex) const = 0; - - /** Returns true if the specified channel is part of a stereo pair with its neighbour. */ - virtual bool isInputChannelStereoPair (int index) const = 0; - - /** Returns true if the specified channel is part of a stereo pair with its neighbour. */ - virtual bool isOutputChannelStereoPair (int index) const = 0; - - /** This returns the number of samples delay that the filter imposes on the audio - passing through it. - - The host will call this to find the latency - the filter itself should set this value - by calling setLatencySamples() as soon as it can during its initialisation. - */ - int getLatencySamples() const noexcept { return latencySamples; } - - /** The filter should call this to set the number of samples delay that it introduces. - - The filter should call this as soon as it can during initialisation, and can call it - later if the value changes. - */ - void setLatencySamples (int newLatency); - - /** Returns true if a silent input always produces a silent output. */ - virtual bool silenceInProducesSilenceOut() const = 0; - - /** Returns the length of the filter's tail, in seconds. */ - virtual double getTailLengthSeconds() const = 0; - - /** Returns true if the processor wants midi messages. */ - virtual bool acceptsMidi() const = 0; - - /** Returns true if the processor produces midi messages. */ - virtual bool producesMidi() const = 0; - - //============================================================================== - /** This returns a critical section that will automatically be locked while the host - is calling the processBlock() method. - - Use it from your UI or other threads to lock access to variables that are used - by the process callback, but obviously be careful not to keep it locked for - too long, because that could cause stuttering playback. If you need to do something - that'll take a long time and need the processing to stop while it happens, use the - suspendProcessing() method instead. - - @see suspendProcessing - */ - const CriticalSection& getCallbackLock() const noexcept { return callbackLock; } - - /** Enables and disables the processing callback. - - If you need to do something time-consuming on a thread and would like to make sure - the audio processing callback doesn't happen until you've finished, use this - to disable the callback and re-enable it again afterwards. - - E.g. - @code - void loadNewPatch() - { - suspendProcessing (true); - - ..do something that takes ages.. - - suspendProcessing (false); - } - @endcode - - If the host tries to make an audio callback while processing is suspended, the - filter will return an empty buffer, but won't block the audio thread like it would - do if you use the getCallbackLock() critical section to synchronise access. - - Any code that calls processBlock() should call isSuspended() before doing so, and - if the processor is suspended, it should avoid the call and emit silence or - whatever is appropriate. - - @see getCallbackLock - */ - void suspendProcessing (bool shouldBeSuspended); - - /** Returns true if processing is currently suspended. - @see suspendProcessing - */ - bool isSuspended() const noexcept { return suspended; } - - /** A plugin can override this to be told when it should reset any playing voices. - - The default implementation does nothing, but a host may call this to tell the - plugin that it should stop any tails or sounds that have been left running. - */ - virtual void reset(); - - //============================================================================== - /** Returns true if the processor is being run in an offline mode for rendering. - - If the processor is being run live on realtime signals, this returns false. - If the mode is unknown, this will assume it's realtime and return false. - - This value may be unreliable until the prepareToPlay() method has been called, - and could change each time prepareToPlay() is called. - - @see setNonRealtime() - */ - bool isNonRealtime() const noexcept { return nonRealtime; } - - /** Called by the host to tell this processor whether it's being used in a non-realtime - capacity for offline rendering or bouncing. - */ - virtual void setNonRealtime (bool isNonRealtime) noexcept; - - //============================================================================== - /** Creates the filter's UI. - - This can return nullptr if you want a UI-less filter, in which case the host may create - a generic UI that lets the user twiddle the parameters directly. - - If you do want to pass back a component, the component should be created and set to - the correct size before returning it. If you implement this method, you must - also implement the hasEditor() method and make it return true. - - Remember not to do anything silly like allowing your filter to keep a pointer to - the component that gets created - it could be deleted later without any warning, which - would make your pointer into a dangler. Use the getActiveEditor() method instead. - - The correct way to handle the connection between an editor component and its - filter is to use something like a ChangeBroadcaster so that the editor can - register itself as a listener, and be told when a change occurs. This lets them - safely unregister themselves when they are deleted. - - Here are a few things to bear in mind when writing an editor: - - - Initially there won't be an editor, until the user opens one, or they might - not open one at all. Your filter mustn't rely on it being there. - - An editor object may be deleted and a replacement one created again at any time. - - It's safe to assume that an editor will be deleted before its filter. - - @see hasEditor - */ - virtual AudioProcessorEditor* createEditor() = 0; - - /** Your filter must override this and return true if it can create an editor component. - @see createEditor - */ - virtual bool hasEditor() const = 0; - - //============================================================================== - /** Returns the active editor, if there is one. - Bear in mind this can return nullptr, even if an editor has previously been opened. - */ - AudioProcessorEditor* getActiveEditor() const noexcept { return activeEditor; } - - /** Returns the active editor, or if there isn't one, it will create one. - This may call createEditor() internally to create the component. - */ - AudioProcessorEditor* createEditorIfNeeded(); - - //============================================================================== - /** This must return the correct value immediately after the object has been - created, and mustn't change the number of parameters later. - */ - virtual int getNumParameters(); - - /** Returns the name of a particular parameter. */ - virtual const String getParameterName (int parameterIndex); - - /** Called by the host to find out the value of one of the filter's parameters. - - The host will expect the value returned to be between 0 and 1.0. - - This could be called quite frequently, so try to make your code efficient. - It's also likely to be called by non-UI threads, so the code in here should - be thread-aware. - */ - virtual float getParameter (int parameterIndex); - - /** Returns the value of a parameter as a text string. */ - virtual const String getParameterText (int parameterIndex); - - /** Returns the name of a parameter as a text string with a preferred maximum length. - If you want to provide customised short versions of your parameter names that - will look better in constrained spaces (e.g. the displays on hardware controller - devices or mixing desks) then you should implement this method. - If you don't override it, the default implementation will call getParameterText(int), - and truncate the result. - */ - virtual String getParameterName (int parameterIndex, int maximumStringLength); - - /** Returns the value of a parameter as a text string with a preferred maximum length. - If you want to provide customised short versions of your parameter values that - will look better in constrained spaces (e.g. the displays on hardware controller - devices or mixing desks) then you should implement this method. - If you don't override it, the default implementation will call getParameterText(int), - and truncate the result. - */ - virtual String getParameterText (int parameterIndex, int maximumStringLength); - - /** Returns the number of discrete steps that this parameter can represent. - The default return value if you don't implement this method is - AudioProcessor::getDefaultNumParameterSteps(). - If your parameter is boolean, then you may want to make this return 2. - The value that is returned may or may not be used, depending on the host. - */ - virtual int getParameterNumSteps (int parameterIndex); - - /** Returns the default number of steps for a parameter. - @see getParameterNumSteps - */ - static int getDefaultNumParameterSteps() noexcept; - - /** Returns the default value for the parameter. - By default, this just returns 0. - The value that is returned may or may not be used, depending on the host. - */ - virtual float getParameterDefaultValue (int parameterIndex); - - /** Some plugin types may be able to return a label string for a - parameter's units. - */ - virtual String getParameterLabel (int index) const; - - /** This can be overridden to tell the host that particular parameters operate in the - reverse direction. (Not all plugin formats or hosts will actually use this information). - */ - virtual bool isParameterOrientationInverted (int index) const; - - /** The host will call this method to change the value of one of the filter's parameters. - - The host may call this at any time, including during the audio processing - callback, so the filter has to process this very fast and avoid blocking. - - If you want to set the value of a parameter internally, e.g. from your - editor component, then don't call this directly - instead, use the - setParameterNotifyingHost() method, which will also send a message to - the host telling it about the change. If the message isn't sent, the host - won't be able to automate your parameters properly. - - The value passed will be between 0 and 1.0. - */ - virtual void setParameter (int parameterIndex, float newValue); - - /** Your filter can call this when it needs to change one of its parameters. - - This could happen when the editor or some other internal operation changes - a parameter. This method will call the setParameter() method to change the - value, and will then send a message to the host telling it about the change. - - Note that to make sure the host correctly handles automation, you should call - the beginParameterChangeGesture() and endParameterChangeGesture() methods to - tell the host when the user has started and stopped changing the parameter. - */ - void setParameterNotifyingHost (int parameterIndex, float newValue); - - /** Returns true if the host can automate this parameter. - By default, this returns true for all parameters. - */ - virtual bool isParameterAutomatable (int parameterIndex) const; - - /** Should return true if this parameter is a "meta" parameter. - A meta-parameter is a parameter that changes other params. It is used - by some hosts (e.g. AudioUnit hosts). - By default this returns false. - */ - virtual bool isMetaParameter (int parameterIndex) const; - - /** Sends a signal to the host to tell it that the user is about to start changing this - parameter. - - This allows the host to know when a parameter is actively being held by the user, and - it may use this information to help it record automation. - - If you call this, it must be matched by a later call to endParameterChangeGesture(). - */ - void beginParameterChangeGesture (int parameterIndex); - - /** Tells the host that the user has finished changing this parameter. - - This allows the host to know when a parameter is actively being held by the user, and - it may use this information to help it record automation. - - A call to this method must follow a call to beginParameterChangeGesture(). - */ - void endParameterChangeGesture (int parameterIndex); - - /** The filter can call this when something (apart from a parameter value) has changed. - - It sends a hint to the host that something like the program, number of parameters, - etc, has changed, and that it should update itself. - */ - void updateHostDisplay(); - - //============================================================================== - /** Adds a parameter to the list. - The parameter object will be managed and deleted automatically by the list - when no longer needed. - */ - void addParameter (AudioProcessorParameter*); - - /** Returns the current list of parameters. */ - const OwnedArray& getParameters() const noexcept; - - //============================================================================== - /** Returns the number of preset programs the filter supports. - - The value returned must be valid as soon as this object is created, and - must not change over its lifetime. - - This value shouldn't be less than 1. - */ - virtual int getNumPrograms() = 0; - - /** Returns the number of the currently active program. */ - virtual int getCurrentProgram() = 0; - - /** Called by the host to change the current program. */ - virtual void setCurrentProgram (int index) = 0; - - /** Must return the name of a given program. */ - virtual const String getProgramName (int index) = 0; - - /** Called by the host to rename a program. */ - virtual void changeProgramName (int index, const String& newName) = 0; - - //============================================================================== - /** The host will call this method when it wants to save the filter's internal state. - - This must copy any info about the filter's state into the block of memory provided, - so that the host can store this and later restore it using setStateInformation(). - - Note that there's also a getCurrentProgramStateInformation() method, which only - stores the current program, not the state of the entire filter. - - See also the helper function copyXmlToBinary() for storing settings as XML. - - @see getCurrentProgramStateInformation - */ - virtual void getStateInformation (juce::MemoryBlock& destData) = 0; - - /** The host will call this method if it wants to save the state of just the filter's - current program. - - Unlike getStateInformation, this should only return the current program's state. - - Not all hosts support this, and if you don't implement it, the base class - method just calls getStateInformation() instead. If you do implement it, be - sure to also implement getCurrentProgramStateInformation. - - @see getStateInformation, setCurrentProgramStateInformation - */ - virtual void getCurrentProgramStateInformation (juce::MemoryBlock& destData); - - /** This must restore the filter's state from a block of data previously created - using getStateInformation(). - - Note that there's also a setCurrentProgramStateInformation() method, which tries - to restore just the current program, not the state of the entire filter. - - See also the helper function getXmlFromBinary() for loading settings as XML. - - @see setCurrentProgramStateInformation - */ - virtual void setStateInformation (const void* data, int sizeInBytes) = 0; - - /** The host will call this method if it wants to restore the state of just the filter's - current program. - - Not all hosts support this, and if you don't implement it, the base class - method just calls setStateInformation() instead. If you do implement it, be - sure to also implement getCurrentProgramStateInformation. - - @see setStateInformation, getCurrentProgramStateInformation - */ - virtual void setCurrentProgramStateInformation (const void* data, int sizeInBytes); - - /** This method is called when the number of input or output channels is changed. */ - virtual void numChannelsChanged(); - - //============================================================================== - /** Adds a listener that will be called when an aspect of this processor changes. */ - virtual void addListener (AudioProcessorListener* newListener); - - /** Removes a previously added listener. */ - virtual void removeListener (AudioProcessorListener* listenerToRemove); - - //============================================================================== - /** Tells the processor to use this playhead object. - The processor will not take ownership of the object, so the caller must delete it when - it is no longer being used. - */ - virtual void setPlayHead (AudioPlayHead* newPlayHead); - - //============================================================================== - /** This is called by the processor to specify its details before being played. */ - void setPlayConfigDetails (int numIns, int numOuts, double sampleRate, int blockSize) noexcept; - - //============================================================================== - /** Not for public use - this is called before deleting an editor component. */ - void editorBeingDeleted (AudioProcessorEditor*) noexcept; - - /** Not for public use - this is called to initialise the processor before playing. */ - void setSpeakerArrangement (const String& inputs, const String& outputs); - - /** Flags to indicate the type of plugin context in which a processor is being used. */ - enum WrapperType - { - wrapperType_Undefined = 0, - wrapperType_VST, - wrapperType_VST3, - wrapperType_AudioUnit, - wrapperType_RTAS, - wrapperType_AAX, - wrapperType_Standalone - }; - - /** When loaded by a plugin wrapper, this flag will be set to indicate the type - of plugin within which the processor is running. - */ - WrapperType wrapperType; - - //============================================================================== - /** Helper function that just converts an xml element into a binary blob. - - Use this in your filter's getStateInformation() method if you want to - store its state as xml. - - Then use getXmlFromBinary() to reverse this operation and retrieve the XML - from a binary blob. - */ - static void copyXmlToBinary (const XmlElement& xml, - juce::MemoryBlock& destData); - - /** Retrieves an XML element that was stored as binary with the copyXmlToBinary() method. - - This might return nullptr if the data's unsuitable or corrupted. Otherwise it will return - an XmlElement object that the caller must delete when no longer needed. - */ - static XmlElement* getXmlFromBinary (const void* data, int sizeInBytes); - - /** @internal */ - static void JUCE_CALLTYPE setTypeOfNextNewPlugin (WrapperType); - -protected: - /** @internal */ - AudioPlayHead* playHead; - - /** @internal */ - void sendParamChangeMessageToListeners (int parameterIndex, float newValue); - -private: - Array listeners; - Component::SafePointer activeEditor; - double sampleRate; - int blockSize, numInputChannels, numOutputChannels, latencySamples; - bool suspended, nonRealtime; - CriticalSection callbackLock, listenerLock; - String inputSpeakerArrangement, outputSpeakerArrangement; - - OwnedArray managedParameters; - AudioProcessorParameter* getParamChecked (int) const noexcept; - - #if JUCE_DEBUG - BigInteger changingParams; - #endif - - AudioProcessorListener* getListenerLocked (int) const noexcept; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioProcessor) -}; - - -#endif // JUCE_AUDIOPROCESSOR_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/processors/juce_AudioProcessorEditor.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/processors/juce_AudioProcessorEditor.cpp deleted file mode 100644 index a625411117..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/processors/juce_AudioProcessorEditor.cpp +++ /dev/null @@ -1,43 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -AudioProcessorEditor::AudioProcessorEditor (AudioProcessor& p) noexcept : processor (p) -{ -} - -AudioProcessorEditor::AudioProcessorEditor (AudioProcessor* p) noexcept : processor (*p) -{ - // the filter must be valid.. - jassert (p != nullptr); -} - -AudioProcessorEditor::~AudioProcessorEditor() -{ - // if this fails, then the wrapper hasn't called editorBeingDeleted() on the - // filter for some reason.. - jassert (processor.getActiveEditor() != this); -} - -void AudioProcessorEditor::setControlHighlight (ParameterControlHighlightInfo) {} -int AudioProcessorEditor::getControlParameterIndex (Component&) { return -1; } diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/processors/juce_AudioProcessorEditor.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/processors/juce_AudioProcessorEditor.h deleted file mode 100644 index 1755497c33..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/processors/juce_AudioProcessorEditor.h +++ /dev/null @@ -1,92 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_AUDIOPROCESSOREDITOR_H_INCLUDED -#define JUCE_AUDIOPROCESSOREDITOR_H_INCLUDED - - -//============================================================================== -/** - Base class for the component that acts as the GUI for an AudioProcessor. - - Derive your editor component from this class, and create an instance of it - by overriding the AudioProcessor::createEditor() method. - - @see AudioProcessor, GenericAudioProcessorEditor -*/ -class JUCE_API AudioProcessorEditor : public Component -{ -protected: - //============================================================================== - /** Creates an editor for the specified processor. */ - AudioProcessorEditor (AudioProcessor&) noexcept; - - /** Creates an editor for the specified processor. */ - AudioProcessorEditor (AudioProcessor*) noexcept; - -public: - /** Destructor. */ - ~AudioProcessorEditor(); - - - //============================================================================== - /** The AudioProcessor that this editor represents. */ - AudioProcessor& processor; - - /** Returns a pointer to the processor that this editor represents. - This method is here to support legacy code, but it's easier to just use the - AudioProcessorEditor::processor member variable directly to get this object. - */ - AudioProcessor* getAudioProcessor() const noexcept { return &processor; } - - //============================================================================== - /** Used by the setParameterHighlighting() method. */ - struct ParameterControlHighlightInfo - { - int parameterIndex; - bool isHighlighted; - Colour suggestedColour; - }; - - /** Some types of plugin can call this to suggest that the control for a particular - parameter should be highlighted. - Currently only AAX plugins will call this, and implementing it is optional. - */ - virtual void setControlHighlight (ParameterControlHighlightInfo); - - /** Called by certain plug-in wrappers to find out whether a component is used - to control a parameter. - - If the given component represents a particular plugin parameter, then this - method should return the index of that parameter. If not, it should return -1. - Currently only AAX plugins will call this, and implementing it is optional. - */ - virtual int getControlParameterIndex (Component&); - -private: - JUCE_DECLARE_NON_COPYABLE (AudioProcessorEditor) -}; - - -#endif // JUCE_AUDIOPROCESSOREDITOR_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.cpp deleted file mode 100644 index 9ca46d2f7f..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.cpp +++ /dev/null @@ -1,1531 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -const int AudioProcessorGraph::midiChannelIndex = 0x1000; - -//============================================================================== -namespace GraphRenderingOps -{ - -//============================================================================== -class AudioGraphRenderingOp -{ -public: - AudioGraphRenderingOp() {} - virtual ~AudioGraphRenderingOp() {} - - virtual void perform (AudioSampleBuffer& sharedBufferChans, - const OwnedArray & sharedMidiBuffers, - const int numSamples) = 0; - - JUCE_LEAK_DETECTOR (AudioGraphRenderingOp) -}; - -//============================================================================== -class ClearChannelOp : public AudioGraphRenderingOp -{ -public: - ClearChannelOp (const int channelNum_) - : channelNum (channelNum_) - {} - - void perform (AudioSampleBuffer& sharedBufferChans, const OwnedArray &, const int numSamples) - { - sharedBufferChans.clear (channelNum, 0, numSamples); - } - -private: - const int channelNum; - - JUCE_DECLARE_NON_COPYABLE (ClearChannelOp) -}; - -//============================================================================== -class CopyChannelOp : public AudioGraphRenderingOp -{ -public: - CopyChannelOp (const int srcChannelNum_, const int dstChannelNum_) - : srcChannelNum (srcChannelNum_), - dstChannelNum (dstChannelNum_) - {} - - void perform (AudioSampleBuffer& sharedBufferChans, const OwnedArray &, const int numSamples) - { - sharedBufferChans.copyFrom (dstChannelNum, 0, sharedBufferChans, srcChannelNum, 0, numSamples); - } - -private: - const int srcChannelNum, dstChannelNum; - - JUCE_DECLARE_NON_COPYABLE (CopyChannelOp) -}; - -//============================================================================== -class AddChannelOp : public AudioGraphRenderingOp -{ -public: - AddChannelOp (const int srcChannelNum_, const int dstChannelNum_) - : srcChannelNum (srcChannelNum_), - dstChannelNum (dstChannelNum_) - {} - - void perform (AudioSampleBuffer& sharedBufferChans, const OwnedArray &, const int numSamples) - { - sharedBufferChans.addFrom (dstChannelNum, 0, sharedBufferChans, srcChannelNum, 0, numSamples); - } - -private: - const int srcChannelNum, dstChannelNum; - - JUCE_DECLARE_NON_COPYABLE (AddChannelOp) -}; - -//============================================================================== -class ClearMidiBufferOp : public AudioGraphRenderingOp -{ -public: - ClearMidiBufferOp (const int bufferNum_) - : bufferNum (bufferNum_) - {} - - void perform (AudioSampleBuffer&, const OwnedArray & sharedMidiBuffers, const int) - { - sharedMidiBuffers.getUnchecked (bufferNum)->clear(); - } - -private: - const int bufferNum; - - JUCE_DECLARE_NON_COPYABLE (ClearMidiBufferOp) -}; - -//============================================================================== -class CopyMidiBufferOp : public AudioGraphRenderingOp -{ -public: - CopyMidiBufferOp (const int srcBufferNum_, const int dstBufferNum_) - : srcBufferNum (srcBufferNum_), - dstBufferNum (dstBufferNum_) - {} - - void perform (AudioSampleBuffer&, const OwnedArray & sharedMidiBuffers, const int) - { - *sharedMidiBuffers.getUnchecked (dstBufferNum) = *sharedMidiBuffers.getUnchecked (srcBufferNum); - } - -private: - const int srcBufferNum, dstBufferNum; - - JUCE_DECLARE_NON_COPYABLE (CopyMidiBufferOp) -}; - -//============================================================================== -class AddMidiBufferOp : public AudioGraphRenderingOp -{ -public: - AddMidiBufferOp (const int srcBufferNum_, const int dstBufferNum_) - : srcBufferNum (srcBufferNum_), - dstBufferNum (dstBufferNum_) - {} - - void perform (AudioSampleBuffer&, const OwnedArray & sharedMidiBuffers, const int numSamples) - { - sharedMidiBuffers.getUnchecked (dstBufferNum) - ->addEvents (*sharedMidiBuffers.getUnchecked (srcBufferNum), 0, numSamples, 0); - } - -private: - const int srcBufferNum, dstBufferNum; - - JUCE_DECLARE_NON_COPYABLE (AddMidiBufferOp) -}; - -//============================================================================== -class DelayChannelOp : public AudioGraphRenderingOp -{ -public: - DelayChannelOp (const int channel_, const int numSamplesDelay_) - : channel (channel_), - bufferSize (numSamplesDelay_ + 1), - readIndex (0), writeIndex (numSamplesDelay_) - { - buffer.calloc ((size_t) bufferSize); - } - - void perform (AudioSampleBuffer& sharedBufferChans, const OwnedArray &, const int numSamples) - { - float* data = sharedBufferChans.getWritePointer (channel, 0); - - for (int i = numSamples; --i >= 0;) - { - buffer [writeIndex] = *data; - *data++ = buffer [readIndex]; - - if (++readIndex >= bufferSize) readIndex = 0; - if (++writeIndex >= bufferSize) writeIndex = 0; - } - } - -private: - HeapBlock buffer; - const int channel, bufferSize; - int readIndex, writeIndex; - - JUCE_DECLARE_NON_COPYABLE (DelayChannelOp) -}; - - -//============================================================================== -class ProcessBufferOp : public AudioGraphRenderingOp -{ -public: - ProcessBufferOp (const AudioProcessorGraph::Node::Ptr& node_, - const Array & audioChannelsToUse_, - const int totalChans_, - const int midiBufferToUse_) - : node (node_), - processor (node_->getProcessor()), - audioChannelsToUse (audioChannelsToUse_), - totalChans (jmax (1, totalChans_)), - midiBufferToUse (midiBufferToUse_) - { - channels.calloc ((size_t) totalChans); - - while (audioChannelsToUse.size() < totalChans) - audioChannelsToUse.add (0); - } - - void perform (AudioSampleBuffer& sharedBufferChans, const OwnedArray & sharedMidiBuffers, const int numSamples) - { - for (int i = totalChans; --i >= 0;) - channels[i] = sharedBufferChans.getWritePointer (audioChannelsToUse.getUnchecked (i), 0); - - AudioSampleBuffer buffer (channels, totalChans, numSamples); - - processor->processBlock (buffer, *sharedMidiBuffers.getUnchecked (midiBufferToUse)); - } - - const AudioProcessorGraph::Node::Ptr node; - AudioProcessor* const processor; - -private: - Array audioChannelsToUse; - HeapBlock channels; - int totalChans; - int midiBufferToUse; - - JUCE_DECLARE_NON_COPYABLE (ProcessBufferOp) -}; - -//============================================================================== -/** Used to calculate the correct sequence of rendering ops needed, based on - the best re-use of shared buffers at each stage. -*/ -class RenderingOpSequenceCalculator -{ -public: - //============================================================================== - RenderingOpSequenceCalculator (AudioProcessorGraph& graph_, - const Array& orderedNodes_, - Array& renderingOps) - : graph (graph_), - orderedNodes (orderedNodes_), - totalLatency (0) - { - nodeIds.add ((uint32) zeroNodeID); // first buffer is read-only zeros - channels.add (0); - - midiNodeIds.add ((uint32) zeroNodeID); - - for (int i = 0; i < orderedNodes.size(); ++i) - { - createRenderingOpsForNode ((AudioProcessorGraph::Node*) orderedNodes.getUnchecked(i), - renderingOps, i); - - markAnyUnusedBuffersAsFree (i); - } - - graph.setLatencySamples (totalLatency); - } - - int getNumBuffersNeeded() const { return nodeIds.size(); } - int getNumMidiBuffersNeeded() const { return midiNodeIds.size(); } - -private: - //============================================================================== - AudioProcessorGraph& graph; - const Array& orderedNodes; - Array channels; - Array nodeIds, midiNodeIds; - - enum { freeNodeID = 0xffffffff, zeroNodeID = 0xfffffffe }; - - static bool isNodeBusy (uint32 nodeID) noexcept { return nodeID != freeNodeID && nodeID != zeroNodeID; } - - Array nodeDelayIDs; - Array nodeDelays; - int totalLatency; - - int getNodeDelay (const uint32 nodeID) const { return nodeDelays [nodeDelayIDs.indexOf (nodeID)]; } - - void setNodeDelay (const uint32 nodeID, const int latency) - { - const int index = nodeDelayIDs.indexOf (nodeID); - - if (index >= 0) - { - nodeDelays.set (index, latency); - } - else - { - nodeDelayIDs.add (nodeID); - nodeDelays.add (latency); - } - } - - int getInputLatencyForNode (const uint32 nodeID) const - { - int maxLatency = 0; - - for (int i = graph.getNumConnections(); --i >= 0;) - { - const AudioProcessorGraph::Connection* const c = graph.getConnection (i); - - if (c->destNodeId == nodeID) - maxLatency = jmax (maxLatency, getNodeDelay (c->sourceNodeId)); - } - - return maxLatency; - } - - //============================================================================== - void createRenderingOpsForNode (AudioProcessorGraph::Node* const node, - Array& renderingOps, - const int ourRenderingIndex) - { - const int numIns = node->getProcessor()->getNumInputChannels(); - const int numOuts = node->getProcessor()->getNumOutputChannels(); - const int totalChans = jmax (numIns, numOuts); - - Array audioChannelsToUse; - int midiBufferToUse = -1; - - int maxLatency = getInputLatencyForNode (node->nodeId); - - for (int inputChan = 0; inputChan < numIns; ++inputChan) - { - // get a list of all the inputs to this node - Array sourceNodes; - Array sourceOutputChans; - - for (int i = graph.getNumConnections(); --i >= 0;) - { - const AudioProcessorGraph::Connection* const c = graph.getConnection (i); - - if (c->destNodeId == node->nodeId && c->destChannelIndex == inputChan) - { - sourceNodes.add (c->sourceNodeId); - sourceOutputChans.add (c->sourceChannelIndex); - } - } - - int bufIndex = -1; - - if (sourceNodes.size() == 0) - { - // unconnected input channel - - if (inputChan >= numOuts) - { - bufIndex = getReadOnlyEmptyBuffer(); - jassert (bufIndex >= 0); - } - else - { - bufIndex = getFreeBuffer (false); - renderingOps.add (new ClearChannelOp (bufIndex)); - } - } - else if (sourceNodes.size() == 1) - { - // channel with a straightforward single input.. - const uint32 srcNode = sourceNodes.getUnchecked(0); - const int srcChan = sourceOutputChans.getUnchecked(0); - - bufIndex = getBufferContaining (srcNode, srcChan); - - if (bufIndex < 0) - { - // if not found, this is probably a feedback loop - bufIndex = getReadOnlyEmptyBuffer(); - jassert (bufIndex >= 0); - } - - if (inputChan < numOuts - && isBufferNeededLater (ourRenderingIndex, - inputChan, - srcNode, srcChan)) - { - // can't mess up this channel because it's needed later by another node, so we - // need to use a copy of it.. - const int newFreeBuffer = getFreeBuffer (false); - - renderingOps.add (new CopyChannelOp (bufIndex, newFreeBuffer)); - - bufIndex = newFreeBuffer; - } - - const int nodeDelay = getNodeDelay (srcNode); - - if (nodeDelay < maxLatency) - renderingOps.add (new DelayChannelOp (bufIndex, maxLatency - nodeDelay)); - } - else - { - // channel with a mix of several inputs.. - - // try to find a re-usable channel from our inputs.. - int reusableInputIndex = -1; - - for (int i = 0; i < sourceNodes.size(); ++i) - { - const int sourceBufIndex = getBufferContaining (sourceNodes.getUnchecked(i), - sourceOutputChans.getUnchecked(i)); - - if (sourceBufIndex >= 0 - && ! isBufferNeededLater (ourRenderingIndex, - inputChan, - sourceNodes.getUnchecked(i), - sourceOutputChans.getUnchecked(i))) - { - // we've found one of our input chans that can be re-used.. - reusableInputIndex = i; - bufIndex = sourceBufIndex; - - const int nodeDelay = getNodeDelay (sourceNodes.getUnchecked (i)); - if (nodeDelay < maxLatency) - renderingOps.add (new DelayChannelOp (sourceBufIndex, maxLatency - nodeDelay)); - - break; - } - } - - if (reusableInputIndex < 0) - { - // can't re-use any of our input chans, so get a new one and copy everything into it.. - bufIndex = getFreeBuffer (false); - jassert (bufIndex != 0); - - const int srcIndex = getBufferContaining (sourceNodes.getUnchecked (0), - sourceOutputChans.getUnchecked (0)); - if (srcIndex < 0) - { - // if not found, this is probably a feedback loop - renderingOps.add (new ClearChannelOp (bufIndex)); - } - else - { - renderingOps.add (new CopyChannelOp (srcIndex, bufIndex)); - } - - reusableInputIndex = 0; - const int nodeDelay = getNodeDelay (sourceNodes.getFirst()); - - if (nodeDelay < maxLatency) - renderingOps.add (new DelayChannelOp (bufIndex, maxLatency - nodeDelay)); - } - - for (int j = 0; j < sourceNodes.size(); ++j) - { - if (j != reusableInputIndex) - { - int srcIndex = getBufferContaining (sourceNodes.getUnchecked(j), - sourceOutputChans.getUnchecked(j)); - if (srcIndex >= 0) - { - const int nodeDelay = getNodeDelay (sourceNodes.getUnchecked (j)); - - if (nodeDelay < maxLatency) - { - if (! isBufferNeededLater (ourRenderingIndex, inputChan, - sourceNodes.getUnchecked(j), - sourceOutputChans.getUnchecked(j))) - { - renderingOps.add (new DelayChannelOp (srcIndex, maxLatency - nodeDelay)); - } - else // buffer is reused elsewhere, can't be delayed - { - const int bufferToDelay = getFreeBuffer (false); - renderingOps.add (new CopyChannelOp (srcIndex, bufferToDelay)); - renderingOps.add (new DelayChannelOp (bufferToDelay, maxLatency - nodeDelay)); - srcIndex = bufferToDelay; - } - } - - renderingOps.add (new AddChannelOp (srcIndex, bufIndex)); - } - } - } - } - - jassert (bufIndex >= 0); - audioChannelsToUse.add (bufIndex); - - if (inputChan < numOuts) - markBufferAsContaining (bufIndex, node->nodeId, inputChan); - } - - for (int outputChan = numIns; outputChan < numOuts; ++outputChan) - { - const int bufIndex = getFreeBuffer (false); - jassert (bufIndex != 0); - audioChannelsToUse.add (bufIndex); - - markBufferAsContaining (bufIndex, node->nodeId, outputChan); - } - - // Now the same thing for midi.. - Array midiSourceNodes; - - for (int i = graph.getNumConnections(); --i >= 0;) - { - const AudioProcessorGraph::Connection* const c = graph.getConnection (i); - - if (c->destNodeId == node->nodeId && c->destChannelIndex == AudioProcessorGraph::midiChannelIndex) - midiSourceNodes.add (c->sourceNodeId); - } - - if (midiSourceNodes.size() == 0) - { - // No midi inputs.. - midiBufferToUse = getFreeBuffer (true); // need to pick a buffer even if the processor doesn't use midi - - if (node->getProcessor()->acceptsMidi() || node->getProcessor()->producesMidi()) - renderingOps.add (new ClearMidiBufferOp (midiBufferToUse)); - } - else if (midiSourceNodes.size() == 1) - { - // One midi input.. - midiBufferToUse = getBufferContaining (midiSourceNodes.getUnchecked(0), - AudioProcessorGraph::midiChannelIndex); - - if (midiBufferToUse >= 0) - { - if (isBufferNeededLater (ourRenderingIndex, - AudioProcessorGraph::midiChannelIndex, - midiSourceNodes.getUnchecked(0), - AudioProcessorGraph::midiChannelIndex)) - { - // can't mess up this channel because it's needed later by another node, so we - // need to use a copy of it.. - const int newFreeBuffer = getFreeBuffer (true); - renderingOps.add (new CopyMidiBufferOp (midiBufferToUse, newFreeBuffer)); - midiBufferToUse = newFreeBuffer; - } - } - else - { - // probably a feedback loop, so just use an empty one.. - midiBufferToUse = getFreeBuffer (true); // need to pick a buffer even if the processor doesn't use midi - } - } - else - { - // More than one midi input being mixed.. - int reusableInputIndex = -1; - - for (int i = 0; i < midiSourceNodes.size(); ++i) - { - const int sourceBufIndex = getBufferContaining (midiSourceNodes.getUnchecked(i), - AudioProcessorGraph::midiChannelIndex); - - if (sourceBufIndex >= 0 - && ! isBufferNeededLater (ourRenderingIndex, - AudioProcessorGraph::midiChannelIndex, - midiSourceNodes.getUnchecked(i), - AudioProcessorGraph::midiChannelIndex)) - { - // we've found one of our input buffers that can be re-used.. - reusableInputIndex = i; - midiBufferToUse = sourceBufIndex; - break; - } - } - - if (reusableInputIndex < 0) - { - // can't re-use any of our input buffers, so get a new one and copy everything into it.. - midiBufferToUse = getFreeBuffer (true); - jassert (midiBufferToUse >= 0); - - const int srcIndex = getBufferContaining (midiSourceNodes.getUnchecked(0), - AudioProcessorGraph::midiChannelIndex); - if (srcIndex >= 0) - renderingOps.add (new CopyMidiBufferOp (srcIndex, midiBufferToUse)); - else - renderingOps.add (new ClearMidiBufferOp (midiBufferToUse)); - - reusableInputIndex = 0; - } - - for (int j = 0; j < midiSourceNodes.size(); ++j) - { - if (j != reusableInputIndex) - { - const int srcIndex = getBufferContaining (midiSourceNodes.getUnchecked(j), - AudioProcessorGraph::midiChannelIndex); - if (srcIndex >= 0) - renderingOps.add (new AddMidiBufferOp (srcIndex, midiBufferToUse)); - } - } - } - - if (node->getProcessor()->producesMidi()) - markBufferAsContaining (midiBufferToUse, node->nodeId, - AudioProcessorGraph::midiChannelIndex); - - setNodeDelay (node->nodeId, maxLatency + node->getProcessor()->getLatencySamples()); - - if (numOuts == 0) - totalLatency = maxLatency; - - renderingOps.add (new ProcessBufferOp (node, audioChannelsToUse, - totalChans, midiBufferToUse)); - } - - //============================================================================== - int getFreeBuffer (const bool forMidi) - { - if (forMidi) - { - for (int i = 1; i < midiNodeIds.size(); ++i) - if (midiNodeIds.getUnchecked(i) == freeNodeID) - return i; - - midiNodeIds.add ((uint32) freeNodeID); - return midiNodeIds.size() - 1; - } - else - { - for (int i = 1; i < nodeIds.size(); ++i) - if (nodeIds.getUnchecked(i) == freeNodeID) - return i; - - nodeIds.add ((uint32) freeNodeID); - channels.add (0); - return nodeIds.size() - 1; - } - } - - int getReadOnlyEmptyBuffer() const noexcept - { - return 0; - } - - int getBufferContaining (const uint32 nodeId, const int outputChannel) const noexcept - { - if (outputChannel == AudioProcessorGraph::midiChannelIndex) - { - for (int i = midiNodeIds.size(); --i >= 0;) - if (midiNodeIds.getUnchecked(i) == nodeId) - return i; - } - else - { - for (int i = nodeIds.size(); --i >= 0;) - if (nodeIds.getUnchecked(i) == nodeId - && channels.getUnchecked(i) == outputChannel) - return i; - } - - return -1; - } - - void markAnyUnusedBuffersAsFree (const int stepIndex) - { - for (int i = 0; i < nodeIds.size(); ++i) - { - if (isNodeBusy (nodeIds.getUnchecked(i)) - && ! isBufferNeededLater (stepIndex, -1, - nodeIds.getUnchecked(i), - channels.getUnchecked(i))) - { - nodeIds.set (i, (uint32) freeNodeID); - } - } - - for (int i = 0; i < midiNodeIds.size(); ++i) - { - if (isNodeBusy (midiNodeIds.getUnchecked(i)) - && ! isBufferNeededLater (stepIndex, -1, - midiNodeIds.getUnchecked(i), - AudioProcessorGraph::midiChannelIndex)) - { - midiNodeIds.set (i, (uint32) freeNodeID); - } - } - } - - bool isBufferNeededLater (int stepIndexToSearchFrom, - int inputChannelOfIndexToIgnore, - const uint32 nodeId, - const int outputChanIndex) const - { - while (stepIndexToSearchFrom < orderedNodes.size()) - { - const AudioProcessorGraph::Node* const node = (const AudioProcessorGraph::Node*) orderedNodes.getUnchecked (stepIndexToSearchFrom); - - if (outputChanIndex == AudioProcessorGraph::midiChannelIndex) - { - if (inputChannelOfIndexToIgnore != AudioProcessorGraph::midiChannelIndex - && graph.getConnectionBetween (nodeId, AudioProcessorGraph::midiChannelIndex, - node->nodeId, AudioProcessorGraph::midiChannelIndex) != nullptr) - return true; - } - else - { - for (int i = 0; i < node->getProcessor()->getNumInputChannels(); ++i) - if (i != inputChannelOfIndexToIgnore - && graph.getConnectionBetween (nodeId, outputChanIndex, - node->nodeId, i) != nullptr) - return true; - } - - inputChannelOfIndexToIgnore = -1; - ++stepIndexToSearchFrom; - } - - return false; - } - - void markBufferAsContaining (int bufferNum, uint32 nodeId, int outputIndex) - { - if (outputIndex == AudioProcessorGraph::midiChannelIndex) - { - jassert (bufferNum > 0 && bufferNum < midiNodeIds.size()); - - midiNodeIds.set (bufferNum, nodeId); - } - else - { - jassert (bufferNum >= 0 && bufferNum < nodeIds.size()); - - nodeIds.set (bufferNum, nodeId); - channels.set (bufferNum, outputIndex); - } - } - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (RenderingOpSequenceCalculator) -}; - -//============================================================================== -// Holds a fast lookup table for checking which nodes are inputs to others. -class ConnectionLookupTable -{ -public: - explicit ConnectionLookupTable (const OwnedArray& connections) - { - for (int i = 0; i < connections.size(); ++i) - { - const AudioProcessorGraph::Connection* const c = connections.getUnchecked(i); - - int index; - Entry* entry = findEntry (c->destNodeId, index); - - if (entry == nullptr) - { - entry = new Entry (c->destNodeId); - entries.insert (index, entry); - } - - entry->srcNodes.add (c->sourceNodeId); - } - } - - bool isAnInputTo (const uint32 possibleInputId, - const uint32 possibleDestinationId) const noexcept - { - return isAnInputToRecursive (possibleInputId, possibleDestinationId, entries.size()); - } - -private: - //============================================================================== - struct Entry - { - explicit Entry (const uint32 destNodeId_) noexcept : destNodeId (destNodeId_) {} - - const uint32 destNodeId; - SortedSet srcNodes; - - JUCE_DECLARE_NON_COPYABLE (Entry) - }; - - OwnedArray entries; - - bool isAnInputToRecursive (const uint32 possibleInputId, - const uint32 possibleDestinationId, - int recursionCheck) const noexcept - { - int index; - - if (const Entry* const entry = findEntry (possibleDestinationId, index)) - { - const SortedSet& srcNodes = entry->srcNodes; - - if (srcNodes.contains (possibleInputId)) - return true; - - if (--recursionCheck >= 0) - { - for (int i = 0; i < srcNodes.size(); ++i) - if (isAnInputToRecursive (possibleInputId, srcNodes.getUnchecked(i), recursionCheck)) - return true; - } - } - - return false; - } - - Entry* findEntry (const uint32 destNodeId, int& insertIndex) const noexcept - { - Entry* result = nullptr; - - int start = 0; - int end = entries.size(); - - for (;;) - { - if (start >= end) - { - break; - } - else if (destNodeId == entries.getUnchecked (start)->destNodeId) - { - result = entries.getUnchecked (start); - break; - } - else - { - const int halfway = (start + end) / 2; - - if (halfway == start) - { - if (destNodeId >= entries.getUnchecked (halfway)->destNodeId) - ++start; - - break; - } - else if (destNodeId >= entries.getUnchecked (halfway)->destNodeId) - start = halfway; - else - end = halfway; - } - } - - insertIndex = start; - return result; - } - - JUCE_DECLARE_NON_COPYABLE (ConnectionLookupTable) -}; - -//============================================================================== -struct ConnectionSorter -{ - static int compareElements (const AudioProcessorGraph::Connection* const first, - const AudioProcessorGraph::Connection* const second) noexcept - { - if (first->sourceNodeId < second->sourceNodeId) return -1; - if (first->sourceNodeId > second->sourceNodeId) return 1; - if (first->destNodeId < second->destNodeId) return -1; - if (first->destNodeId > second->destNodeId) return 1; - if (first->sourceChannelIndex < second->sourceChannelIndex) return -1; - if (first->sourceChannelIndex > second->sourceChannelIndex) return 1; - if (first->destChannelIndex < second->destChannelIndex) return -1; - if (first->destChannelIndex > second->destChannelIndex) return 1; - - return 0; - } -}; - -} - -//============================================================================== -AudioProcessorGraph::Connection::Connection (const uint32 sourceNodeId_, const int sourceChannelIndex_, - const uint32 destNodeId_, const int destChannelIndex_) noexcept - : sourceNodeId (sourceNodeId_), sourceChannelIndex (sourceChannelIndex_), - destNodeId (destNodeId_), destChannelIndex (destChannelIndex_) -{ -} - -//============================================================================== -AudioProcessorGraph::Node::Node (const uint32 nodeId_, AudioProcessor* const processor_) noexcept - : nodeId (nodeId_), - processor (processor_), - isPrepared (false) -{ - jassert (processor != nullptr); -} - -void AudioProcessorGraph::Node::prepare (const double sampleRate, const int blockSize, - AudioProcessorGraph* const graph) -{ - if (! isPrepared) - { - isPrepared = true; - setParentGraph (graph); - - processor->setPlayConfigDetails (processor->getNumInputChannels(), - processor->getNumOutputChannels(), - sampleRate, blockSize); - - processor->prepareToPlay (sampleRate, blockSize); - } -} - -void AudioProcessorGraph::Node::unprepare() -{ - if (isPrepared) - { - isPrepared = false; - processor->releaseResources(); - } -} - -void AudioProcessorGraph::Node::setParentGraph (AudioProcessorGraph* const graph) const -{ - if (AudioProcessorGraph::AudioGraphIOProcessor* const ioProc - = dynamic_cast (processor.get())) - ioProc->setParentGraph (graph); -} - -//============================================================================== -AudioProcessorGraph::AudioProcessorGraph() - : lastNodeId (0), - currentAudioInputBuffer (nullptr), - currentMidiInputBuffer (nullptr) -{ -} - -AudioProcessorGraph::~AudioProcessorGraph() -{ - clearRenderingSequence(); - clear(); -} - -const String AudioProcessorGraph::getName() const -{ - return "Audio Graph"; -} - -//============================================================================== -void AudioProcessorGraph::clear() -{ - nodes.clear(); - connections.clear(); - triggerAsyncUpdate(); -} - -AudioProcessorGraph::Node* AudioProcessorGraph::getNodeForId (const uint32 nodeId) const -{ - for (int i = nodes.size(); --i >= 0;) - if (nodes.getUnchecked(i)->nodeId == nodeId) - return nodes.getUnchecked(i); - - return nullptr; -} - -AudioProcessorGraph::Node* AudioProcessorGraph::addNode (AudioProcessor* const newProcessor, uint32 nodeId) -{ - if (newProcessor == nullptr || newProcessor == this) - { - jassertfalse; - return nullptr; - } - - for (int i = nodes.size(); --i >= 0;) - { - if (nodes.getUnchecked(i)->getProcessor() == newProcessor) - { - jassertfalse; // Cannot add the same object to the graph twice! - return nullptr; - } - } - - if (nodeId == 0) - { - nodeId = ++lastNodeId; - } - else - { - // you can't add a node with an id that already exists in the graph.. - jassert (getNodeForId (nodeId) == nullptr); - removeNode (nodeId); - - if (nodeId > lastNodeId) - lastNodeId = nodeId; - } - - newProcessor->setPlayHead (getPlayHead()); - - Node* const n = new Node (nodeId, newProcessor); - nodes.add (n); - triggerAsyncUpdate(); - - n->setParentGraph (this); - return n; -} - -bool AudioProcessorGraph::removeNode (const uint32 nodeId) -{ - disconnectNode (nodeId); - - for (int i = nodes.size(); --i >= 0;) - { - if (nodes.getUnchecked(i)->nodeId == nodeId) - { - nodes.getUnchecked(i)->setParentGraph (nullptr); - nodes.remove (i); - triggerAsyncUpdate(); - - return true; - } - } - - return false; -} - -//============================================================================== -const AudioProcessorGraph::Connection* AudioProcessorGraph::getConnectionBetween (const uint32 sourceNodeId, - const int sourceChannelIndex, - const uint32 destNodeId, - const int destChannelIndex) const -{ - const Connection c (sourceNodeId, sourceChannelIndex, destNodeId, destChannelIndex); - GraphRenderingOps::ConnectionSorter sorter; - return connections [connections.indexOfSorted (sorter, &c)]; -} - -bool AudioProcessorGraph::isConnected (const uint32 possibleSourceNodeId, - const uint32 possibleDestNodeId) const -{ - for (int i = connections.size(); --i >= 0;) - { - const Connection* const c = connections.getUnchecked(i); - - if (c->sourceNodeId == possibleSourceNodeId - && c->destNodeId == possibleDestNodeId) - { - return true; - } - } - - return false; -} - -bool AudioProcessorGraph::canConnect (const uint32 sourceNodeId, - const int sourceChannelIndex, - const uint32 destNodeId, - const int destChannelIndex) const -{ - if (sourceChannelIndex < 0 - || destChannelIndex < 0 - || sourceNodeId == destNodeId - || (destChannelIndex == midiChannelIndex) != (sourceChannelIndex == midiChannelIndex)) - return false; - - const Node* const source = getNodeForId (sourceNodeId); - - if (source == nullptr - || (sourceChannelIndex != midiChannelIndex && sourceChannelIndex >= source->processor->getNumOutputChannels()) - || (sourceChannelIndex == midiChannelIndex && ! source->processor->producesMidi())) - return false; - - const Node* const dest = getNodeForId (destNodeId); - - if (dest == nullptr - || (destChannelIndex != midiChannelIndex && destChannelIndex >= dest->processor->getNumInputChannels()) - || (destChannelIndex == midiChannelIndex && ! dest->processor->acceptsMidi())) - return false; - - return getConnectionBetween (sourceNodeId, sourceChannelIndex, - destNodeId, destChannelIndex) == nullptr; -} - -bool AudioProcessorGraph::addConnection (const uint32 sourceNodeId, - const int sourceChannelIndex, - const uint32 destNodeId, - const int destChannelIndex) -{ - if (! canConnect (sourceNodeId, sourceChannelIndex, destNodeId, destChannelIndex)) - return false; - - GraphRenderingOps::ConnectionSorter sorter; - connections.addSorted (sorter, new Connection (sourceNodeId, sourceChannelIndex, - destNodeId, destChannelIndex)); - triggerAsyncUpdate(); - return true; -} - -void AudioProcessorGraph::removeConnection (const int index) -{ - connections.remove (index); - triggerAsyncUpdate(); -} - -bool AudioProcessorGraph::removeConnection (const uint32 sourceNodeId, const int sourceChannelIndex, - const uint32 destNodeId, const int destChannelIndex) -{ - bool doneAnything = false; - - for (int i = connections.size(); --i >= 0;) - { - const Connection* const c = connections.getUnchecked(i); - - if (c->sourceNodeId == sourceNodeId - && c->destNodeId == destNodeId - && c->sourceChannelIndex == sourceChannelIndex - && c->destChannelIndex == destChannelIndex) - { - removeConnection (i); - doneAnything = true; - } - } - - return doneAnything; -} - -bool AudioProcessorGraph::disconnectNode (const uint32 nodeId) -{ - bool doneAnything = false; - - for (int i = connections.size(); --i >= 0;) - { - const Connection* const c = connections.getUnchecked(i); - - if (c->sourceNodeId == nodeId || c->destNodeId == nodeId) - { - removeConnection (i); - doneAnything = true; - } - } - - return doneAnything; -} - -bool AudioProcessorGraph::isConnectionLegal (const Connection* const c) const -{ - jassert (c != nullptr); - - const Node* const source = getNodeForId (c->sourceNodeId); - const Node* const dest = getNodeForId (c->destNodeId); - - return source != nullptr - && dest != nullptr - && (c->sourceChannelIndex != midiChannelIndex ? isPositiveAndBelow (c->sourceChannelIndex, source->processor->getNumOutputChannels()) - : source->processor->producesMidi()) - && (c->destChannelIndex != midiChannelIndex ? isPositiveAndBelow (c->destChannelIndex, dest->processor->getNumInputChannels()) - : dest->processor->acceptsMidi()); -} - -bool AudioProcessorGraph::removeIllegalConnections() -{ - bool doneAnything = false; - - for (int i = connections.size(); --i >= 0;) - { - if (! isConnectionLegal (connections.getUnchecked(i))) - { - removeConnection (i); - doneAnything = true; - } - } - - return doneAnything; -} - -//============================================================================== -static void deleteRenderOpArray (Array& ops) -{ - for (int i = ops.size(); --i >= 0;) - delete static_cast (ops.getUnchecked(i)); -} - -void AudioProcessorGraph::clearRenderingSequence() -{ - Array oldOps; - - { - const ScopedLock sl (getCallbackLock()); - renderingOps.swapWith (oldOps); - } - - deleteRenderOpArray (oldOps); -} - -bool AudioProcessorGraph::isAnInputTo (const uint32 possibleInputId, - const uint32 possibleDestinationId, - const int recursionCheck) const -{ - if (recursionCheck > 0) - { - for (int i = connections.size(); --i >= 0;) - { - const AudioProcessorGraph::Connection* const c = connections.getUnchecked (i); - - if (c->destNodeId == possibleDestinationId - && (c->sourceNodeId == possibleInputId - || isAnInputTo (possibleInputId, c->sourceNodeId, recursionCheck - 1))) - return true; - } - } - - return false; -} - -void AudioProcessorGraph::buildRenderingSequence() -{ - Array newRenderingOps; - int numRenderingBuffersNeeded = 2; - int numMidiBuffersNeeded = 1; - - { - MessageManagerLock mml; - - Array orderedNodes; - - { - const GraphRenderingOps::ConnectionLookupTable table (connections); - - for (int i = 0; i < nodes.size(); ++i) - { - Node* const node = nodes.getUnchecked(i); - - node->prepare (getSampleRate(), getBlockSize(), this); - - int j = 0; - for (; j < orderedNodes.size(); ++j) - if (table.isAnInputTo (node->nodeId, ((Node*) orderedNodes.getUnchecked(j))->nodeId)) - break; - - orderedNodes.insert (j, node); - } - } - - GraphRenderingOps::RenderingOpSequenceCalculator calculator (*this, orderedNodes, newRenderingOps); - - numRenderingBuffersNeeded = calculator.getNumBuffersNeeded(); - numMidiBuffersNeeded = calculator.getNumMidiBuffersNeeded(); - } - - { - // swap over to the new rendering sequence.. - const ScopedLock sl (getCallbackLock()); - - renderingBuffers.setSize (numRenderingBuffersNeeded, getBlockSize()); - renderingBuffers.clear(); - - for (int i = midiBuffers.size(); --i >= 0;) - midiBuffers.getUnchecked(i)->clear(); - - while (midiBuffers.size() < numMidiBuffersNeeded) - midiBuffers.add (new MidiBuffer()); - - renderingOps.swapWith (newRenderingOps); - } - - // delete the old ones.. - deleteRenderOpArray (newRenderingOps); -} - -void AudioProcessorGraph::handleAsyncUpdate() -{ - buildRenderingSequence(); -} - -//============================================================================== -void AudioProcessorGraph::prepareToPlay (double /*sampleRate*/, int estimatedSamplesPerBlock) -{ - currentAudioInputBuffer = nullptr; - currentAudioOutputBuffer.setSize (jmax (1, getNumOutputChannels()), estimatedSamplesPerBlock); - currentMidiInputBuffer = nullptr; - currentMidiOutputBuffer.clear(); - - clearRenderingSequence(); - buildRenderingSequence(); -} - -void AudioProcessorGraph::releaseResources() -{ - for (int i = 0; i < nodes.size(); ++i) - nodes.getUnchecked(i)->unprepare(); - - renderingBuffers.setSize (1, 1); - midiBuffers.clear(); - - currentAudioInputBuffer = nullptr; - currentAudioOutputBuffer.setSize (1, 1); - currentMidiInputBuffer = nullptr; - currentMidiOutputBuffer.clear(); -} - -void AudioProcessorGraph::reset() -{ - const ScopedLock sl (getCallbackLock()); - - for (int i = 0; i < nodes.size(); ++i) - nodes.getUnchecked(i)->getProcessor()->reset(); -} - -void AudioProcessorGraph::processBlock (AudioSampleBuffer& buffer, MidiBuffer& midiMessages) -{ - const int numSamples = buffer.getNumSamples(); - - currentAudioInputBuffer = &buffer; - currentAudioOutputBuffer.setSize (jmax (1, buffer.getNumChannels()), numSamples); - currentAudioOutputBuffer.clear(); - currentMidiInputBuffer = &midiMessages; - currentMidiOutputBuffer.clear(); - - for (int i = 0; i < renderingOps.size(); ++i) - { - GraphRenderingOps::AudioGraphRenderingOp* const op - = (GraphRenderingOps::AudioGraphRenderingOp*) renderingOps.getUnchecked(i); - - op->perform (renderingBuffers, midiBuffers, numSamples); - } - - for (int i = 0; i < buffer.getNumChannels(); ++i) - buffer.copyFrom (i, 0, currentAudioOutputBuffer, i, 0, numSamples); - - midiMessages.clear(); - midiMessages.addEvents (currentMidiOutputBuffer, 0, buffer.getNumSamples(), 0); -} - -const String AudioProcessorGraph::getInputChannelName (int channelIndex) const -{ - return "Input " + String (channelIndex + 1); -} - -const String AudioProcessorGraph::getOutputChannelName (int channelIndex) const -{ - return "Output " + String (channelIndex + 1); -} - -bool AudioProcessorGraph::isInputChannelStereoPair (int /*index*/) const { return true; } -bool AudioProcessorGraph::isOutputChannelStereoPair (int /*index*/) const { return true; } -bool AudioProcessorGraph::silenceInProducesSilenceOut() const { return false; } -double AudioProcessorGraph::getTailLengthSeconds() const { return 0; } -bool AudioProcessorGraph::acceptsMidi() const { return true; } -bool AudioProcessorGraph::producesMidi() const { return true; } -void AudioProcessorGraph::getStateInformation (juce::MemoryBlock& /*destData*/) {} -void AudioProcessorGraph::setStateInformation (const void* /*data*/, int /*sizeInBytes*/) {} - - -//============================================================================== -AudioProcessorGraph::AudioGraphIOProcessor::AudioGraphIOProcessor (const IODeviceType type_) - : type (type_), - graph (nullptr) -{ -} - -AudioProcessorGraph::AudioGraphIOProcessor::~AudioGraphIOProcessor() -{ -} - -const String AudioProcessorGraph::AudioGraphIOProcessor::getName() const -{ - switch (type) - { - case audioOutputNode: return "Audio Output"; - case audioInputNode: return "Audio Input"; - case midiOutputNode: return "Midi Output"; - case midiInputNode: return "Midi Input"; - default: break; - } - - return String(); -} - -void AudioProcessorGraph::AudioGraphIOProcessor::fillInPluginDescription (PluginDescription& d) const -{ - d.name = getName(); - d.uid = d.name.hashCode(); - d.category = "I/O devices"; - d.pluginFormatName = "Internal"; - d.manufacturerName = "Raw Material Software"; - d.version = "1.0"; - d.isInstrument = false; - - d.numInputChannels = getNumInputChannels(); - if (type == audioOutputNode && graph != nullptr) - d.numInputChannels = graph->getNumInputChannels(); - - d.numOutputChannels = getNumOutputChannels(); - if (type == audioInputNode && graph != nullptr) - d.numOutputChannels = graph->getNumOutputChannels(); -} - -void AudioProcessorGraph::AudioGraphIOProcessor::prepareToPlay (double, int) -{ - jassert (graph != nullptr); -} - -void AudioProcessorGraph::AudioGraphIOProcessor::releaseResources() -{ -} - -void AudioProcessorGraph::AudioGraphIOProcessor::processBlock (AudioSampleBuffer& buffer, - MidiBuffer& midiMessages) -{ - jassert (graph != nullptr); - - switch (type) - { - case audioOutputNode: - { - for (int i = jmin (graph->currentAudioOutputBuffer.getNumChannels(), - buffer.getNumChannels()); --i >= 0;) - { - graph->currentAudioOutputBuffer.addFrom (i, 0, buffer, i, 0, buffer.getNumSamples()); - } - - break; - } - - case audioInputNode: - { - for (int i = jmin (graph->currentAudioInputBuffer->getNumChannels(), - buffer.getNumChannels()); --i >= 0;) - { - buffer.copyFrom (i, 0, *graph->currentAudioInputBuffer, i, 0, buffer.getNumSamples()); - } - - break; - } - - case midiOutputNode: - graph->currentMidiOutputBuffer.addEvents (midiMessages, 0, buffer.getNumSamples(), 0); - break; - - case midiInputNode: - midiMessages.addEvents (*graph->currentMidiInputBuffer, 0, buffer.getNumSamples(), 0); - break; - - default: - break; - } -} - -bool AudioProcessorGraph::AudioGraphIOProcessor::silenceInProducesSilenceOut() const -{ - return isOutput(); -} - -double AudioProcessorGraph::AudioGraphIOProcessor::getTailLengthSeconds() const -{ - return 0; -} - -bool AudioProcessorGraph::AudioGraphIOProcessor::acceptsMidi() const -{ - return type == midiOutputNode; -} - -bool AudioProcessorGraph::AudioGraphIOProcessor::producesMidi() const -{ - return type == midiInputNode; -} - -const String AudioProcessorGraph::AudioGraphIOProcessor::getInputChannelName (int channelIndex) const -{ - switch (type) - { - case audioOutputNode: return "Output " + String (channelIndex + 1); - case midiOutputNode: return "Midi Output"; - default: break; - } - - return String(); -} - -const String AudioProcessorGraph::AudioGraphIOProcessor::getOutputChannelName (int channelIndex) const -{ - switch (type) - { - case audioInputNode: return "Input " + String (channelIndex + 1); - case midiInputNode: return "Midi Input"; - default: break; - } - - return String(); -} - -bool AudioProcessorGraph::AudioGraphIOProcessor::isInputChannelStereoPair (int /*index*/) const -{ - return type == audioInputNode || type == audioOutputNode; -} - -bool AudioProcessorGraph::AudioGraphIOProcessor::isOutputChannelStereoPair (int index) const -{ - return isInputChannelStereoPair (index); -} - -bool AudioProcessorGraph::AudioGraphIOProcessor::isInput() const { return type == audioInputNode || type == midiInputNode; } -bool AudioProcessorGraph::AudioGraphIOProcessor::isOutput() const { return type == audioOutputNode || type == midiOutputNode; } - -bool AudioProcessorGraph::AudioGraphIOProcessor::hasEditor() const { return false; } -AudioProcessorEditor* AudioProcessorGraph::AudioGraphIOProcessor::createEditor() { return nullptr; } - -int AudioProcessorGraph::AudioGraphIOProcessor::getNumParameters() { return 0; } -const String AudioProcessorGraph::AudioGraphIOProcessor::getParameterName (int) { return String(); } - -float AudioProcessorGraph::AudioGraphIOProcessor::getParameter (int) { return 0.0f; } -const String AudioProcessorGraph::AudioGraphIOProcessor::getParameterText (int) { return String(); } -void AudioProcessorGraph::AudioGraphIOProcessor::setParameter (int, float) { } - -int AudioProcessorGraph::AudioGraphIOProcessor::getNumPrograms() { return 0; } -int AudioProcessorGraph::AudioGraphIOProcessor::getCurrentProgram() { return 0; } -void AudioProcessorGraph::AudioGraphIOProcessor::setCurrentProgram (int) { } - -const String AudioProcessorGraph::AudioGraphIOProcessor::getProgramName (int) { return String(); } -void AudioProcessorGraph::AudioGraphIOProcessor::changeProgramName (int, const String&) {} - -void AudioProcessorGraph::AudioGraphIOProcessor::getStateInformation (juce::MemoryBlock&) {} -void AudioProcessorGraph::AudioGraphIOProcessor::setStateInformation (const void*, int) {} - -void AudioProcessorGraph::AudioGraphIOProcessor::setParentGraph (AudioProcessorGraph* const newGraph) -{ - graph = newGraph; - - if (graph != nullptr) - { - setPlayConfigDetails (type == audioOutputNode ? graph->getNumOutputChannels() : 0, - type == audioInputNode ? graph->getNumInputChannels() : 0, - getSampleRate(), - getBlockSize()); - - updateHostDisplay(); - } -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h deleted file mode 100644 index d94468235a..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h +++ /dev/null @@ -1,413 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_AUDIOPROCESSORGRAPH_H_INCLUDED -#define JUCE_AUDIOPROCESSORGRAPH_H_INCLUDED - - -//============================================================================== -/** - A type of AudioProcessor which plays back a graph of other AudioProcessors. - - Use one of these objects if you want to wire-up a set of AudioProcessors - and play back the result. - - Processors can be added to the graph as "nodes" using addNode(), and once - added, you can connect any of their input or output channels to other - nodes using addConnection(). - - To play back a graph through an audio device, you might want to use an - AudioProcessorPlayer object. -*/ -class JUCE_API AudioProcessorGraph : public AudioProcessor, - private AsyncUpdater -{ -public: - //============================================================================== - /** Creates an empty graph. */ - AudioProcessorGraph(); - - /** Destructor. - Any processor objects that have been added to the graph will also be deleted. - */ - ~AudioProcessorGraph(); - - //============================================================================== - /** Represents one of the nodes, or processors, in an AudioProcessorGraph. - - To create a node, call AudioProcessorGraph::addNode(). - */ - class JUCE_API Node : public ReferenceCountedObject - { - public: - //============================================================================== - /** The ID number assigned to this node. - This is assigned by the graph that owns it, and can't be changed. - */ - const uint32 nodeId; - - /** The actual processor object that this node represents. */ - AudioProcessor* getProcessor() const noexcept { return processor; } - - /** A set of user-definable properties that are associated with this node. - - This can be used to attach values to the node for whatever purpose seems - useful. For example, you might store an x and y position if your application - is displaying the nodes on-screen. - */ - NamedValueSet properties; - - //============================================================================== - /** A convenient typedef for referring to a pointer to a node object. */ - typedef ReferenceCountedObjectPtr Ptr; - - private: - //============================================================================== - friend class AudioProcessorGraph; - - const ScopedPointer processor; - bool isPrepared; - - Node (uint32 nodeId, AudioProcessor*) noexcept; - - void setParentGraph (AudioProcessorGraph*) const; - void prepare (double sampleRate, int blockSize, AudioProcessorGraph*); - void unprepare(); - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Node) - }; - - //============================================================================== - /** Represents a connection between two channels of two nodes in an AudioProcessorGraph. - - To create a connection, use AudioProcessorGraph::addConnection(). - */ - struct JUCE_API Connection - { - public: - //============================================================================== - Connection (uint32 sourceNodeId, int sourceChannelIndex, - uint32 destNodeId, int destChannelIndex) noexcept; - - //============================================================================== - /** The ID number of the node which is the input source for this connection. - @see AudioProcessorGraph::getNodeForId - */ - uint32 sourceNodeId; - - /** The index of the output channel of the source node from which this - connection takes its data. - - If this value is the special number AudioProcessorGraph::midiChannelIndex, then - it is referring to the source node's midi output. Otherwise, it is the zero-based - index of an audio output channel in the source node. - */ - int sourceChannelIndex; - - /** The ID number of the node which is the destination for this connection. - @see AudioProcessorGraph::getNodeForId - */ - uint32 destNodeId; - - /** The index of the input channel of the destination node to which this - connection delivers its data. - - If this value is the special number AudioProcessorGraph::midiChannelIndex, then - it is referring to the destination node's midi input. Otherwise, it is the zero-based - index of an audio input channel in the destination node. - */ - int destChannelIndex; - - private: - //============================================================================== - JUCE_LEAK_DETECTOR (Connection) - }; - - //============================================================================== - /** Deletes all nodes and connections from this graph. - Any processor objects in the graph will be deleted. - */ - void clear(); - - /** Returns the number of nodes in the graph. */ - int getNumNodes() const { return nodes.size(); } - - /** Returns a pointer to one of the nodes in the graph. - This will return nullptr if the index is out of range. - @see getNodeForId - */ - Node* getNode (const int index) const { return nodes [index]; } - - /** Searches the graph for a node with the given ID number and returns it. - If no such node was found, this returns nullptr. - @see getNode - */ - Node* getNodeForId (const uint32 nodeId) const; - - /** Adds a node to the graph. - - This creates a new node in the graph, for the specified processor. Once you have - added a processor to the graph, the graph owns it and will delete it later when - it is no longer needed. - - The optional nodeId parameter lets you specify an ID to use for the node, but - if the value is already in use, this new node will overwrite the old one. - - If this succeeds, it returns a pointer to the newly-created node. - */ - Node* addNode (AudioProcessor* newProcessor, uint32 nodeId = 0); - - /** Deletes a node within the graph which has the specified ID. - - This will also delete any connections that are attached to this node. - */ - bool removeNode (uint32 nodeId); - - //============================================================================== - /** Returns the number of connections in the graph. */ - int getNumConnections() const { return connections.size(); } - - /** Returns a pointer to one of the connections in the graph. */ - const Connection* getConnection (int index) const { return connections [index]; } - - /** Searches for a connection between some specified channels. - If no such connection is found, this returns nullptr. - */ - const Connection* getConnectionBetween (uint32 sourceNodeId, - int sourceChannelIndex, - uint32 destNodeId, - int destChannelIndex) const; - - /** Returns true if there is a connection between any of the channels of - two specified nodes. - */ - bool isConnected (uint32 possibleSourceNodeId, - uint32 possibleDestNodeId) const; - - /** Returns true if it would be legal to connect the specified points. */ - bool canConnect (uint32 sourceNodeId, int sourceChannelIndex, - uint32 destNodeId, int destChannelIndex) const; - - /** Attempts to connect two specified channels of two nodes. - - If this isn't allowed (e.g. because you're trying to connect a midi channel - to an audio one or other such nonsense), then it'll return false. - */ - bool addConnection (uint32 sourceNodeId, int sourceChannelIndex, - uint32 destNodeId, int destChannelIndex); - - /** Deletes the connection with the specified index. */ - void removeConnection (int index); - - /** Deletes any connection between two specified points. - Returns true if a connection was actually deleted. - */ - bool removeConnection (uint32 sourceNodeId, int sourceChannelIndex, - uint32 destNodeId, int destChannelIndex); - - /** Removes all connections from the specified node. */ - bool disconnectNode (uint32 nodeId); - - /** Returns true if the given connection's channel numbers map on to valid - channels at each end. - Even if a connection is valid when created, its status could change if - a node changes its channel config. - */ - bool isConnectionLegal (const Connection* connection) const; - - /** Performs a sanity checks of all the connections. - - This might be useful if some of the processors are doing things like changing - their channel counts, which could render some connections obsolete. - */ - bool removeIllegalConnections(); - - //============================================================================== - /** A special number that represents the midi channel of a node. - - This is used as a channel index value if you want to refer to the midi input - or output instead of an audio channel. - */ - static const int midiChannelIndex; - - - //============================================================================== - /** A special type of AudioProcessor that can live inside an AudioProcessorGraph - in order to use the audio that comes into and out of the graph itself. - - If you create an AudioGraphIOProcessor in "input" mode, it will act as a - node in the graph which delivers the audio that is coming into the parent - graph. This allows you to stream the data to other nodes and process the - incoming audio. - - Likewise, one of these in "output" mode can be sent data which it will add to - the sum of data being sent to the graph's output. - - @see AudioProcessorGraph - */ - class JUCE_API AudioGraphIOProcessor : public AudioPluginInstance - { - public: - /** Specifies the mode in which this processor will operate. - */ - enum IODeviceType - { - audioInputNode, /**< In this mode, the processor has output channels - representing all the audio input channels that are - coming into its parent audio graph. */ - audioOutputNode, /**< In this mode, the processor has input channels - representing all the audio output channels that are - going out of its parent audio graph. */ - midiInputNode, /**< In this mode, the processor has a midi output which - delivers the same midi data that is arriving at its - parent graph. */ - midiOutputNode /**< In this mode, the processor has a midi input and - any data sent to it will be passed out of the parent - graph. */ - }; - - //============================================================================== - /** Returns the mode of this processor. */ - IODeviceType getType() const { return type; } - - /** Returns the parent graph to which this processor belongs, or nullptr if it - hasn't yet been added to one. */ - AudioProcessorGraph* getParentGraph() const { return graph; } - - /** True if this is an audio or midi input. */ - bool isInput() const; - /** True if this is an audio or midi output. */ - bool isOutput() const; - - //============================================================================== - AudioGraphIOProcessor (const IODeviceType type); - ~AudioGraphIOProcessor(); - - const String getName() const; - void fillInPluginDescription (PluginDescription&) const; - - void prepareToPlay (double sampleRate, int estimatedSamplesPerBlock); - void releaseResources(); - void processBlock (AudioSampleBuffer&, MidiBuffer&); - - const String getInputChannelName (int channelIndex) const; - const String getOutputChannelName (int channelIndex) const; - bool isInputChannelStereoPair (int index) const; - bool isOutputChannelStereoPair (int index) const; - bool silenceInProducesSilenceOut() const; - double getTailLengthSeconds() const; - bool acceptsMidi() const; - bool producesMidi() const; - - bool hasEditor() const; - AudioProcessorEditor* createEditor(); - - int getNumParameters(); - const String getParameterName (int); - float getParameter (int); - const String getParameterText (int); - void setParameter (int, float); - - int getNumPrograms(); - int getCurrentProgram(); - void setCurrentProgram (int); - const String getProgramName (int); - void changeProgramName (int, const String&); - - void getStateInformation (juce::MemoryBlock& destData); - void setStateInformation (const void* data, int sizeInBytes); - - /** @internal */ - void setParentGraph (AudioProcessorGraph*); - - private: - const IODeviceType type; - AudioProcessorGraph* graph; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioGraphIOProcessor) - }; - - //============================================================================== - // AudioProcessor methods: - - const String getName() const; - - void prepareToPlay (double sampleRate, int estimatedSamplesPerBlock); - void releaseResources(); - void processBlock (AudioSampleBuffer&, MidiBuffer&); - void reset(); - - const String getInputChannelName (int channelIndex) const; - const String getOutputChannelName (int channelIndex) const; - bool isInputChannelStereoPair (int index) const; - bool isOutputChannelStereoPair (int index) const; - bool silenceInProducesSilenceOut() const; - double getTailLengthSeconds() const; - - bool acceptsMidi() const; - bool producesMidi() const; - - bool hasEditor() const { return false; } - AudioProcessorEditor* createEditor() { return nullptr; } - - int getNumParameters() { return 0; } - const String getParameterName (int) { return String(); } - float getParameter (int) { return 0; } - const String getParameterText (int) { return String(); } - void setParameter (int, float) { } - - int getNumPrograms() { return 0; } - int getCurrentProgram() { return 0; } - void setCurrentProgram (int) { } - const String getProgramName (int) { return String(); } - void changeProgramName (int, const String&) { } - - void getStateInformation (juce::MemoryBlock&); - void setStateInformation (const void* data, int sizeInBytes); - -private: - //============================================================================== - ReferenceCountedArray nodes; - OwnedArray connections; - uint32 lastNodeId; - AudioSampleBuffer renderingBuffers; - OwnedArray midiBuffers; - Array renderingOps; - - friend class AudioGraphIOProcessor; - AudioSampleBuffer* currentAudioInputBuffer; - AudioSampleBuffer currentAudioOutputBuffer; - MidiBuffer* currentMidiInputBuffer; - MidiBuffer currentMidiOutputBuffer; - - void handleAsyncUpdate() override; - void clearRenderingSequence(); - void buildRenderingSequence(); - bool isAnInputTo (uint32 possibleInputId, uint32 possibleDestinationId, int recursionCheck) const; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioProcessorGraph) -}; - - -#endif // JUCE_AUDIOPROCESSORGRAPH_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/processors/juce_AudioProcessorListener.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/processors/juce_AudioProcessorListener.h deleted file mode 100644 index d8ea93c994..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/processors/juce_AudioProcessorListener.h +++ /dev/null @@ -1,106 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_AUDIOPROCESSORLISTENER_H_INCLUDED -#define JUCE_AUDIOPROCESSORLISTENER_H_INCLUDED - - -//============================================================================== -/** - Base class for listeners that want to know about changes to an AudioProcessor. - - Use AudioProcessor::addListener() to register your listener with an AudioProcessor. - - @see AudioProcessor -*/ -class JUCE_API AudioProcessorListener -{ -public: - //============================================================================== - /** Destructor. */ - virtual ~AudioProcessorListener() {} - - //============================================================================== - /** Receives a callback when a parameter is changed. - - IMPORTANT NOTE: this will be called synchronously when a parameter changes, and - many audio processors will change their parameter during their audio callback. - This means that not only has your handler code got to be completely thread-safe, - but it's also got to be VERY fast, and avoid blocking. If you need to handle - this event on your message thread, use this callback to trigger an AsyncUpdater - or ChangeBroadcaster which you can respond to on the message thread. - */ - virtual void audioProcessorParameterChanged (AudioProcessor* processor, - int parameterIndex, - float newValue) = 0; - - /** Called to indicate that something else in the plugin has changed, like its - program, number of parameters, etc. - - IMPORTANT NOTE: this will be called synchronously, and many audio processors will - call it during their audio callback. This means that not only has your handler code - got to be completely thread-safe, but it's also got to be VERY fast, and avoid - blocking. If you need to handle this event on your message thread, use this callback - to trigger an AsyncUpdater or ChangeBroadcaster which you can respond to later on the - message thread. - */ - virtual void audioProcessorChanged (AudioProcessor* processor) = 0; - - /** Indicates that a parameter change gesture has started. - - E.g. if the user is dragging a slider, this would be called when they first - press the mouse button, and audioProcessorParameterChangeGestureEnd would be - called when they release it. - - IMPORTANT NOTE: this will be called synchronously, and many audio processors will - call it during their audio callback. This means that not only has your handler code - got to be completely thread-safe, but it's also got to be VERY fast, and avoid - blocking. If you need to handle this event on your message thread, use this callback - to trigger an AsyncUpdater or ChangeBroadcaster which you can respond to later on the - message thread. - - @see audioProcessorParameterChangeGestureEnd - */ - virtual void audioProcessorParameterChangeGestureBegin (AudioProcessor* processor, - int parameterIndex); - - /** Indicates that a parameter change gesture has finished. - - E.g. if the user is dragging a slider, this would be called when they release - the mouse button. - - IMPORTANT NOTE: this will be called synchronously, and many audio processors will - call it during their audio callback. This means that not only has your handler code - got to be completely thread-safe, but it's also got to be VERY fast, and avoid - blocking. If you need to handle this event on your message thread, use this callback - to trigger an AsyncUpdater or ChangeBroadcaster which you can respond to later on the - message thread. - - @see audioProcessorParameterChangeGestureBegin - */ - virtual void audioProcessorParameterChangeGestureEnd (AudioProcessor* processor, - int parameterIndex); -}; - -#endif // JUCE_AUDIOPROCESSORLISTENER_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/processors/juce_AudioProcessorParameter.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/processors/juce_AudioProcessorParameter.h deleted file mode 100644 index 8b4d2cf32c..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/processors/juce_AudioProcessorParameter.h +++ /dev/null @@ -1,158 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_AUDIOPROCESSORPARAMETER_H_INCLUDED -#define JUCE_AUDIOPROCESSORPARAMETER_H_INCLUDED - - -//============================================================================== -/** An abstract base class for parameter objects that can be added to an - AudioProcessor. - - @see AudioProcessor::addParameter -*/ -class JUCE_API AudioProcessorParameter -{ -public: - AudioProcessorParameter() noexcept; - - /** Destructor. */ - virtual ~AudioProcessorParameter(); - - /** Called by the host to find out the value of this parameter. - - Hosts will expect the value returned to be between 0 and 1.0. - - This could be called quite frequently, so try to make your code efficient. - It's also likely to be called by non-UI threads, so the code in here should - be thread-aware. - */ - virtual float getValue() const = 0; - - /** The host will call this method to change the value of one of the filter's parameters. - - The host may call this at any time, including during the audio processing - callback, so the filter has to process this very fast and avoid blocking. - - If you want to set the value of a parameter internally, e.g. from your - editor component, then don't call this directly - instead, use the - setValueNotifyingHost() method, which will also send a message to - the host telling it about the change. If the message isn't sent, the host - won't be able to automate your parameters properly. - - The value passed will be between 0 and 1.0. - */ - virtual void setValue (float newValue) = 0; - - /** Your filter can call this when it needs to change one of its parameters. - - This could happen when the editor or some other internal operation changes - a parameter. This method will call the setParameter() method to change the - value, and will then send a message to the host telling it about the change. - - Note that to make sure the host correctly handles automation, you should call - the beginChangeGesture() and endChangeGesture() methods to tell the host when - the user has started and stopped changing the parameter. - */ - void setValueNotifyingHost (float newValue); - - /** Sends a signal to the host to tell it that the user is about to start changing this - parameter. - This allows the host to know when a parameter is actively being held by the user, and - it may use this information to help it record automation. - If you call this, it must be matched by a later call to endChangeGesture(). - */ - void beginChangeGesture(); - - /** Tells the host that the user has finished changing this parameter. - This allows the host to know when a parameter is actively being held by the user, - and it may use this information to help it record automation. - A call to this method must follow a call to beginChangeGesture(). - */ - void endChangeGesture(); - - /** This should return the default value for this parameter. */ - virtual float getDefaultValue() const = 0; - - /** Returns the name to display for this parameter, which should be made - to fit within the given string length. - */ - virtual String getName (int maximumStringLength) const = 0; - - /** Some parameters may be able to return a label string for - their units. For example "Hz" or "%". - */ - virtual String getLabel() const = 0; - - /** Returns the number of discrete interval steps that this parameter's range - should be quantised into. - - If you want a continuous range of values, don't override this method, and allow - the default implementation to return AudioProcessor::getDefaultNumParameterSteps(). - If your parameter is boolean, then you may want to make this return 2. - The value that is returned may or may not be used, depending on the host. - */ - virtual int getNumSteps() const; - - /** Returns a textual version of the supplied parameter value. - The default implementation just returns the floating point value - as a string, but this could do anything you need for a custom type - of value. - */ - virtual String getText (float value, int /*maximumStringLength*/) const; - - /** Should parse a string and return the appropriate value for it. */ - virtual float getValueForText (const String& text) const = 0; - - /** This can be overridden to tell the host that this parameter operates in the - reverse direction. - (Not all plugin formats or hosts will actually use this information). - */ - virtual bool isOrientationInverted() const; - - /** Returns true if the host can automate this parameter. - By default, this returns true. - */ - virtual bool isAutomatable() const; - - /** Should return true if this parameter is a "meta" parameter. - A meta-parameter is a parameter that changes other params. It is used - by some hosts (e.g. AudioUnit hosts). - By default this returns false. - */ - virtual bool isMetaParameter() const; - - /** Returns the index of this parameter in its parent processor's parameter list. */ - int getParameterIndex() const noexcept { return parameterIndex; } - -private: - friend class AudioProcessor; - AudioProcessor* processor; - int parameterIndex; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioProcessorParameter) -}; - - -#endif // JUCE_AUDIOPROCESSORPARAMETER_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/processors/juce_GenericAudioProcessorEditor.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/processors/juce_GenericAudioProcessorEditor.cpp deleted file mode 100644 index c94411d7b1..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/processors/juce_GenericAudioProcessorEditor.cpp +++ /dev/null @@ -1,172 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -class ProcessorParameterPropertyComp : public PropertyComponent, - private AudioProcessorListener, - private Timer -{ -public: - ProcessorParameterPropertyComp (const String& name, AudioProcessor& p, int paramIndex) - : PropertyComponent (name), - owner (p), - index (paramIndex), - paramHasChanged (false), - slider (p, paramIndex) - { - startTimer (100); - addAndMakeVisible (slider); - owner.addListener (this); - } - - ~ProcessorParameterPropertyComp() - { - owner.removeListener (this); - } - - void refresh() override - { - paramHasChanged = false; - - if (slider.getThumbBeingDragged() < 0) - slider.setValue (owner.getParameter (index), dontSendNotification); - - slider.updateText(); - } - - void audioProcessorChanged (AudioProcessor*) override {} - - void audioProcessorParameterChanged (AudioProcessor*, int parameterIndex, float) override - { - if (parameterIndex == index) - paramHasChanged = true; - } - - void timerCallback() override - { - if (paramHasChanged) - { - refresh(); - startTimer (1000 / 50); - } - else - { - startTimer (jmin (1000 / 4, getTimerInterval() + 10)); - } - } - -private: - //============================================================================== - class ParamSlider : public Slider - { - public: - ParamSlider (AudioProcessor& p, int paramIndex) : owner (p), index (paramIndex) - { - const int steps = owner.getParameterNumSteps (index); - - if (steps > 1 && steps < 0x7fffffff) - setRange (0.0, 1.0, 1.0 / (steps - 1.0)); - else - setRange (0.0, 1.0); - - setSliderStyle (Slider::LinearBar); - setTextBoxIsEditable (false); - setScrollWheelEnabled (true); - } - - void valueChanged() override - { - const float newVal = (float) getValue(); - - if (owner.getParameter (index) != newVal) - { - owner.setParameterNotifyingHost (index, newVal); - updateText(); - } - } - - String getTextFromValue (double /*value*/) override - { - return owner.getParameterText (index) + " " + owner.getParameterLabel (index).trimEnd(); - } - - private: - //============================================================================== - AudioProcessor& owner; - const int index; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ParamSlider) - }; - - AudioProcessor& owner; - const int index; - bool volatile paramHasChanged; - ParamSlider slider; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ProcessorParameterPropertyComp) -}; - - -//============================================================================== -GenericAudioProcessorEditor::GenericAudioProcessorEditor (AudioProcessor* const p) - : AudioProcessorEditor (p) -{ - jassert (p != nullptr); - setOpaque (true); - - addAndMakeVisible (panel); - - Array params; - - const int numParams = p->getNumParameters(); - int totalHeight = 0; - - for (int i = 0; i < numParams; ++i) - { - String name (p->getParameterName (i)); - if (name.trim().isEmpty()) - name = "Unnamed"; - - ProcessorParameterPropertyComp* const pc = new ProcessorParameterPropertyComp (name, *p, i); - params.add (pc); - totalHeight += pc->getPreferredHeight(); - } - - panel.addProperties (params); - - setSize (400, jlimit (25, 400, totalHeight)); -} - -GenericAudioProcessorEditor::~GenericAudioProcessorEditor() -{ -} - -void GenericAudioProcessorEditor::paint (Graphics& g) -{ - g.fillAll (Colours::white); -} - -void GenericAudioProcessorEditor::resized() -{ - panel.setBounds (getLocalBounds()); -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/processors/juce_GenericAudioProcessorEditor.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/processors/juce_GenericAudioProcessorEditor.h deleted file mode 100644 index 1189f8802c..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/processors/juce_GenericAudioProcessorEditor.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_GENERICAUDIOPROCESSOREDITOR_H_INCLUDED -#define JUCE_GENERICAUDIOPROCESSOREDITOR_H_INCLUDED - - -//============================================================================== -/** - A type of UI component that displays the parameters of an AudioProcessor as - a simple list of sliders. - - This can be used for showing an editor for a processor that doesn't supply - its own custom editor. - - @see AudioProcessor -*/ -class JUCE_API GenericAudioProcessorEditor : public AudioProcessorEditor -{ -public: - //============================================================================== - GenericAudioProcessorEditor (AudioProcessor* owner); - ~GenericAudioProcessorEditor(); - - //============================================================================== - void paint (Graphics&) override; - void resized() override; - -private: - //============================================================================== - PropertyPanel panel; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (GenericAudioProcessorEditor) -}; - - -#endif // JUCE_GENERICAUDIOPROCESSOREDITOR_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/processors/juce_PluginDescription.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/processors/juce_PluginDescription.cpp deleted file mode 100644 index 5eafc07ced..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/processors/juce_PluginDescription.cpp +++ /dev/null @@ -1,140 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -PluginDescription::PluginDescription() - : uid (0), - isInstrument (false), - numInputChannels (0), - numOutputChannels (0), - hasSharedContainer (false) -{ -} - -PluginDescription::~PluginDescription() -{ -} - -PluginDescription::PluginDescription (const PluginDescription& other) - : name (other.name), - descriptiveName (other.descriptiveName), - pluginFormatName (other.pluginFormatName), - category (other.category), - manufacturerName (other.manufacturerName), - version (other.version), - fileOrIdentifier (other.fileOrIdentifier), - lastFileModTime (other.lastFileModTime), - uid (other.uid), - isInstrument (other.isInstrument), - numInputChannels (other.numInputChannels), - numOutputChannels (other.numOutputChannels), - hasSharedContainer (other.hasSharedContainer) -{ -} - -PluginDescription& PluginDescription::operator= (const PluginDescription& other) -{ - name = other.name; - descriptiveName = other.descriptiveName; - pluginFormatName = other.pluginFormatName; - category = other.category; - manufacturerName = other.manufacturerName; - version = other.version; - fileOrIdentifier = other.fileOrIdentifier; - uid = other.uid; - isInstrument = other.isInstrument; - lastFileModTime = other.lastFileModTime; - numInputChannels = other.numInputChannels; - numOutputChannels = other.numOutputChannels; - hasSharedContainer = other.hasSharedContainer; - - return *this; -} - -bool PluginDescription::isDuplicateOf (const PluginDescription& other) const noexcept -{ - return fileOrIdentifier == other.fileOrIdentifier - && uid == other.uid; -} - -static String getPluginDescSuffix (const PluginDescription& d) -{ - return "-" + String::toHexString (d.fileOrIdentifier.hashCode()) - + "-" + String::toHexString (d.uid); -} - -bool PluginDescription::matchesIdentifierString (const String& identifierString) const -{ - return identifierString.endsWithIgnoreCase (getPluginDescSuffix (*this)); -} - -String PluginDescription::createIdentifierString() const -{ - return pluginFormatName + "-" + name + getPluginDescSuffix (*this); -} - -XmlElement* PluginDescription::createXml() const -{ - XmlElement* const e = new XmlElement ("PLUGIN"); - e->setAttribute ("name", name); - if (descriptiveName != name) - e->setAttribute ("descriptiveName", descriptiveName); - - e->setAttribute ("format", pluginFormatName); - e->setAttribute ("category", category); - e->setAttribute ("manufacturer", manufacturerName); - e->setAttribute ("version", version); - e->setAttribute ("file", fileOrIdentifier); - e->setAttribute ("uid", String::toHexString (uid)); - e->setAttribute ("isInstrument", isInstrument); - e->setAttribute ("fileTime", String::toHexString (lastFileModTime.toMilliseconds())); - e->setAttribute ("numInputs", numInputChannels); - e->setAttribute ("numOutputs", numOutputChannels); - e->setAttribute ("isShell", hasSharedContainer); - - return e; -} - -bool PluginDescription::loadFromXml (const XmlElement& xml) -{ - if (xml.hasTagName ("PLUGIN")) - { - name = xml.getStringAttribute ("name"); - descriptiveName = xml.getStringAttribute ("descriptiveName", name); - pluginFormatName = xml.getStringAttribute ("format"); - category = xml.getStringAttribute ("category"); - manufacturerName = xml.getStringAttribute ("manufacturer"); - version = xml.getStringAttribute ("version"); - fileOrIdentifier = xml.getStringAttribute ("file"); - uid = xml.getStringAttribute ("uid").getHexValue32(); - isInstrument = xml.getBoolAttribute ("isInstrument", false); - lastFileModTime = Time (xml.getStringAttribute ("fileTime").getHexValue64()); - numInputChannels = xml.getIntAttribute ("numInputs"); - numOutputChannels = xml.getIntAttribute ("numOutputs"); - hasSharedContainer = xml.getBoolAttribute ("isShell", false); - - return true; - } - - return false; -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/processors/juce_PluginDescription.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/processors/juce_PluginDescription.h deleted file mode 100644 index 24b17e5bff..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/processors/juce_PluginDescription.h +++ /dev/null @@ -1,151 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_PLUGINDESCRIPTION_H_INCLUDED -#define JUCE_PLUGINDESCRIPTION_H_INCLUDED - - -//============================================================================== -/** - A small class to represent some facts about a particular type of plug-in. - - This class is for storing and managing the details about a plug-in without - actually having to load an instance of it. - - A KnownPluginList contains a list of PluginDescription objects. - - @see KnownPluginList -*/ -class JUCE_API PluginDescription -{ -public: - //============================================================================== - PluginDescription(); - PluginDescription (const PluginDescription& other); - PluginDescription& operator= (const PluginDescription& other); - ~PluginDescription(); - - //============================================================================== - /** The name of the plug-in. */ - String name; - - /** A more descriptive name for the plug-in. - This may be the same as the 'name' field, but some plug-ins may provide an - alternative name. - */ - String descriptiveName; - - /** The plug-in format, e.g. "VST", "AudioUnit", etc. */ - String pluginFormatName; - - /** A category, such as "Dynamics", "Reverbs", etc. */ - String category; - - /** The manufacturer. */ - String manufacturerName; - - /** The version. This string doesn't have any particular format. */ - String version; - - /** Either the file containing the plug-in module, or some other unique way - of identifying it. - - E.g. for an AU, this would be an ID string that the component manager - could use to retrieve the plug-in. For a VST, it's the file path. - */ - String fileOrIdentifier; - - /** The last time the plug-in file was changed. - This is handy when scanning for new or changed plug-ins. - */ - Time lastFileModTime; - - /** A unique ID for the plug-in. - - Note that this might not be unique between formats, e.g. a VST and some - other format might actually have the same id. - - @see createIdentifierString - */ - int uid; - - /** True if the plug-in identifies itself as a synthesiser. */ - bool isInstrument; - - /** The number of inputs. */ - int numInputChannels; - - /** The number of outputs. */ - int numOutputChannels; - - /** True if the plug-in is part of a multi-type container, e.g. a VST Shell. */ - bool hasSharedContainer; - - /** Returns true if the two descriptions refer to the same plug-in. - - This isn't quite as simple as them just having the same file (because of - shell plug-ins). - */ - bool isDuplicateOf (const PluginDescription& other) const noexcept; - - /** Return true if this description is equivalent to another one which created the - given identifier string. - - Note that this isn't quite as simple as them just calling createIdentifierString() - and comparing the strings, because the identifers can differ (thanks to shell plug-ins). - */ - bool matchesIdentifierString (const String& identifierString) const; - - //============================================================================== - /** Returns a string that can be saved and used to uniquely identify the - plugin again. - - This contains less info than the XML encoding, and is independent of the - plug-in's file location, so can be used to store a plug-in ID for use - across different machines. - */ - String createIdentifierString() const; - - //============================================================================== - /** Creates an XML object containing these details. - - @see loadFromXml - */ - XmlElement* createXml() const; - - /** Reloads the info in this structure from an XML record that was previously - saved with createXML(). - - Returns true if the XML was a valid plug-in description. - */ - bool loadFromXml (const XmlElement& xml); - - -private: - //============================================================================== - JUCE_LEAK_DETECTOR (PluginDescription) -}; - - -#endif // JUCE_PLUGINDESCRIPTION_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/scanning/juce_KnownPluginList.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/scanning/juce_KnownPluginList.cpp deleted file mode 100644 index 081ba11a8b..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/scanning/juce_KnownPluginList.cpp +++ /dev/null @@ -1,549 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -KnownPluginList::KnownPluginList() {} -KnownPluginList::~KnownPluginList() {} - -void KnownPluginList::clear() -{ - if (types.size() > 0) - { - types.clear(); - sendChangeMessage(); - } -} - -PluginDescription* KnownPluginList::getTypeForFile (const String& fileOrIdentifier) const -{ - for (int i = 0; i < types.size(); ++i) - if (types.getUnchecked(i)->fileOrIdentifier == fileOrIdentifier) - return types.getUnchecked(i); - - return nullptr; -} - -PluginDescription* KnownPluginList::getTypeForIdentifierString (const String& identifierString) const -{ - for (int i = 0; i < types.size(); ++i) - if (types.getUnchecked(i)->matchesIdentifierString (identifierString)) - return types.getUnchecked(i); - - return nullptr; -} - -bool KnownPluginList::addType (const PluginDescription& type) -{ - for (int i = types.size(); --i >= 0;) - { - if (types.getUnchecked(i)->isDuplicateOf (type)) - { - // strange - found a duplicate plugin with different info.. - jassert (types.getUnchecked(i)->name == type.name); - jassert (types.getUnchecked(i)->isInstrument == type.isInstrument); - - *types.getUnchecked(i) = type; - return false; - } - } - - types.insert (0, new PluginDescription (type)); - sendChangeMessage(); - return true; -} - -void KnownPluginList::removeType (const int index) -{ - types.remove (index); - sendChangeMessage(); -} - -bool KnownPluginList::isListingUpToDate (const String& fileOrIdentifier, - AudioPluginFormat& formatToUse) const -{ - if (getTypeForFile (fileOrIdentifier) == nullptr) - return false; - - for (int i = types.size(); --i >= 0;) - { - const PluginDescription* const d = types.getUnchecked(i); - - if (d->fileOrIdentifier == fileOrIdentifier - && formatToUse.pluginNeedsRescanning (*d)) - return false; - } - - return true; -} - -void KnownPluginList::setCustomScanner (CustomScanner* newScanner) -{ - scanner = newScanner; -} - -bool KnownPluginList::scanAndAddFile (const String& fileOrIdentifier, - const bool dontRescanIfAlreadyInList, - OwnedArray & typesFound, - AudioPluginFormat& format) -{ - const ScopedLock sl (scanLock); - - if (dontRescanIfAlreadyInList - && getTypeForFile (fileOrIdentifier) != nullptr) - { - bool needsRescanning = false; - - for (int i = types.size(); --i >= 0;) - { - const PluginDescription* const d = types.getUnchecked(i); - - if (d->fileOrIdentifier == fileOrIdentifier && d->pluginFormatName == format.getName()) - { - if (format.pluginNeedsRescanning (*d)) - needsRescanning = true; - else - typesFound.add (new PluginDescription (*d)); - } - } - - if (! needsRescanning) - return false; - } - - if (blacklist.contains (fileOrIdentifier)) - return false; - - OwnedArray found; - - { - const ScopedUnlock sl2 (scanLock); - - if (scanner != nullptr) - { - if (! scanner->findPluginTypesFor (format, found, fileOrIdentifier)) - addToBlacklist (fileOrIdentifier); - } - else - { - format.findAllTypesForFile (found, fileOrIdentifier); - } - } - - for (int i = 0; i < found.size(); ++i) - { - PluginDescription* const desc = found.getUnchecked(i); - jassert (desc != nullptr); - - addType (*desc); - typesFound.add (new PluginDescription (*desc)); - } - - return found.size() > 0; -} - -void KnownPluginList::scanAndAddDragAndDroppedFiles (AudioPluginFormatManager& formatManager, - const StringArray& files, - OwnedArray & typesFound) -{ - for (int i = 0; i < files.size(); ++i) - { - const String filenameOrID (files[i]); - bool found = false; - - for (int j = 0; j < formatManager.getNumFormats(); ++j) - { - AudioPluginFormat* const format = formatManager.getFormat (j); - - if (format->fileMightContainThisPluginType (filenameOrID) - && scanAndAddFile (filenameOrID, true, typesFound, *format)) - { - found = true; - break; - } - } - - if (! found) - { - const File f (filenameOrID); - - if (f.isDirectory()) - { - StringArray s; - - { - Array subFiles; - f.findChildFiles (subFiles, File::findFilesAndDirectories, false); - - for (int j = 0; j < subFiles.size(); ++j) - s.add (subFiles.getReference(j).getFullPathName()); - } - - scanAndAddDragAndDroppedFiles (formatManager, s, typesFound); - } - } - } - - scanFinished(); -} - -void KnownPluginList::scanFinished() -{ - if (scanner != nullptr) - scanner->scanFinished(); -} - -const StringArray& KnownPluginList::getBlacklistedFiles() const -{ - return blacklist; -} - -void KnownPluginList::addToBlacklist (const String& pluginID) -{ - if (! blacklist.contains (pluginID)) - { - blacklist.add (pluginID); - sendChangeMessage(); - } -} - -void KnownPluginList::removeFromBlacklist (const String& pluginID) -{ - const int index = blacklist.indexOf (pluginID); - - if (index >= 0) - { - blacklist.remove (index); - sendChangeMessage(); - } -} - -void KnownPluginList::clearBlacklistedFiles() -{ - if (blacklist.size() > 0) - { - blacklist.clear(); - sendChangeMessage(); - } -} - -//============================================================================== -struct PluginSorter -{ - PluginSorter (KnownPluginList::SortMethod sortMethod, bool forwards) noexcept - : method (sortMethod), direction (forwards ? 1 : -1) {} - - int compareElements (const PluginDescription* const first, - const PluginDescription* const second) const - { - int diff = 0; - - switch (method) - { - case KnownPluginList::sortByCategory: diff = first->category.compareNatural (second->category); break; - case KnownPluginList::sortByManufacturer: diff = first->manufacturerName.compareNatural (second->manufacturerName); break; - case KnownPluginList::sortByFormat: diff = first->pluginFormatName.compare (second->pluginFormatName); break; - case KnownPluginList::sortByFileSystemLocation: diff = lastPathPart (first->fileOrIdentifier).compare (lastPathPart (second->fileOrIdentifier)); break; - default: break; - } - - if (diff == 0) - diff = first->name.compareNatural (second->name); - - return diff * direction; - } - -private: - static String lastPathPart (const String& path) - { - return path.replaceCharacter ('\\', '/').upToLastOccurrenceOf ("/", false, false); - } - - const KnownPluginList::SortMethod method; - const int direction; - - JUCE_DECLARE_NON_COPYABLE (PluginSorter) -}; - -void KnownPluginList::sort (const SortMethod method, bool forwards) -{ - if (method != defaultOrder) - { - Array oldOrder, newOrder; - oldOrder.addArray (types); - - PluginSorter sorter (method, forwards); - types.sort (sorter, true); - - newOrder.addArray (types); - - if (oldOrder != newOrder) - sendChangeMessage(); - } -} - -//============================================================================== -XmlElement* KnownPluginList::createXml() const -{ - XmlElement* const e = new XmlElement ("KNOWNPLUGINS"); - - for (int i = types.size(); --i >= 0;) - e->prependChildElement (types.getUnchecked(i)->createXml()); - - for (int i = 0; i < blacklist.size(); ++i) - e->createNewChildElement ("BLACKLISTED")->setAttribute ("id", blacklist[i]); - - return e; -} - -void KnownPluginList::recreateFromXml (const XmlElement& xml) -{ - clear(); - clearBlacklistedFiles(); - - if (xml.hasTagName ("KNOWNPLUGINS")) - { - forEachXmlChildElement (xml, e) - { - PluginDescription info; - - if (e->hasTagName ("BLACKLISTED")) - blacklist.add (e->getStringAttribute ("id")); - else if (info.loadFromXml (*e)) - addType (info); - } - } -} - -//============================================================================== -struct PluginTreeUtils -{ - enum { menuIdBase = 0x324503f4 }; - - static void buildTreeByFolder (KnownPluginList::PluginTree& tree, const Array & allPlugins) - { - for (int i = 0; i < allPlugins.size(); ++i) - { - PluginDescription* const pd = allPlugins.getUnchecked (i); - - String path (pd->fileOrIdentifier.replaceCharacter ('\\', '/') - .upToLastOccurrenceOf ("/", false, false)); - - if (path.substring (1, 2) == ":") - path = path.substring (2); - - addPlugin (tree, pd, path); - } - - optimiseFolders (tree, false); - } - - static void optimiseFolders (KnownPluginList::PluginTree& tree, bool concatenateName) - { - for (int i = tree.subFolders.size(); --i >= 0;) - { - KnownPluginList::PluginTree& sub = *tree.subFolders.getUnchecked(i); - optimiseFolders (sub, concatenateName || (tree.subFolders.size() > 1)); - - if (sub.plugins.size() == 0) - { - for (int j = 0; j < sub.subFolders.size(); ++j) - { - KnownPluginList::PluginTree* const s = sub.subFolders.getUnchecked(j); - - if (concatenateName) - s->folder = sub.folder + "/" + s->folder; - - tree.subFolders.add (s); - } - - sub.subFolders.clear (false); - tree.subFolders.remove (i); - } - } - } - - static void buildTreeByCategory (KnownPluginList::PluginTree& tree, - const Array & sorted, - const KnownPluginList::SortMethod sortMethod) - { - String lastType; - ScopedPointer current (new KnownPluginList::PluginTree()); - - for (int i = 0; i < sorted.size(); ++i) - { - const PluginDescription* const pd = sorted.getUnchecked(i); - String thisType (sortMethod == KnownPluginList::sortByCategory ? pd->category - : pd->manufacturerName); - - if (! thisType.containsNonWhitespaceChars()) - thisType = "Other"; - - if (thisType != lastType) - { - if (current->plugins.size() + current->subFolders.size() > 0) - { - current->folder = lastType; - tree.subFolders.add (current.release()); - current = new KnownPluginList::PluginTree(); - } - - lastType = thisType; - } - - current->plugins.add (pd); - } - - if (current->plugins.size() + current->subFolders.size() > 0) - { - current->folder = lastType; - tree.subFolders.add (current.release()); - } - } - - static void addPlugin (KnownPluginList::PluginTree& tree, PluginDescription* const pd, String path) - { - if (path.isEmpty()) - { - tree.plugins.add (pd); - } - else - { - #if JUCE_MAC - if (path.containsChar (':')) - path = path.fromFirstOccurrenceOf (":", false, false); // avoid the special AU formatting nonsense on Mac.. - #endif - - const String firstSubFolder (path.upToFirstOccurrenceOf ("/", false, false)); - const String remainingPath (path.fromFirstOccurrenceOf ("/", false, false)); - - for (int i = tree.subFolders.size(); --i >= 0;) - { - KnownPluginList::PluginTree& subFolder = *tree.subFolders.getUnchecked(i); - - if (subFolder.folder.equalsIgnoreCase (firstSubFolder)) - { - addPlugin (subFolder, pd, remainingPath); - return; - } - } - - KnownPluginList::PluginTree* const newFolder = new KnownPluginList::PluginTree(); - newFolder->folder = firstSubFolder; - tree.subFolders.add (newFolder); - addPlugin (*newFolder, pd, remainingPath); - } - } - - static bool containsDuplicateNames (const Array& plugins, const String& name) - { - int matches = 0; - - for (int i = 0; i < plugins.size(); ++i) - if (plugins.getUnchecked(i)->name == name) - if (++matches > 1) - return true; - - return false; - } - - static void addToMenu (const KnownPluginList::PluginTree& tree, PopupMenu& m, const OwnedArray & allPlugins) - { - for (int i = 0; i < tree.subFolders.size(); ++i) - { - const KnownPluginList::PluginTree& sub = *tree.subFolders.getUnchecked(i); - - PopupMenu subMenu; - addToMenu (sub, subMenu, allPlugins); - m.addSubMenu (sub.folder, subMenu); - } - - for (int i = 0; i < tree.plugins.size(); ++i) - { - const PluginDescription* const plugin = tree.plugins.getUnchecked(i); - - String name (plugin->name); - - if (containsDuplicateNames (tree.plugins, name)) - name << " (" << plugin->pluginFormatName << ')'; - - m.addItem (allPlugins.indexOf (plugin) + menuIdBase, name, true, false); - } - } -}; - -KnownPluginList::PluginTree* KnownPluginList::createTree (const SortMethod sortMethod) const -{ - Array sorted; - - { - PluginSorter sorter (sortMethod, true); - - for (int i = 0; i < types.size(); ++i) - sorted.addSorted (sorter, types.getUnchecked(i)); - } - - PluginTree* tree = new PluginTree(); - - if (sortMethod == sortByCategory || sortMethod == sortByManufacturer || sortMethod == sortByFormat) - { - PluginTreeUtils::buildTreeByCategory (*tree, sorted, sortMethod); - } - else if (sortMethod == sortByFileSystemLocation) - { - PluginTreeUtils::buildTreeByFolder (*tree, sorted); - } - else - { - for (int i = 0; i < sorted.size(); ++i) - tree->plugins.add (sorted.getUnchecked(i)); - } - - return tree; -} - -//============================================================================== -void KnownPluginList::addToMenu (PopupMenu& menu, const SortMethod sortMethod) const -{ - ScopedPointer tree (createTree (sortMethod)); - PluginTreeUtils::addToMenu (*tree, menu, types); -} - -int KnownPluginList::getIndexChosenByMenu (const int menuResultCode) const -{ - const int i = menuResultCode - PluginTreeUtils::menuIdBase; - return isPositiveAndBelow (i, types.size()) ? i : -1; -} - -//============================================================================== -KnownPluginList::CustomScanner::CustomScanner() {} -KnownPluginList::CustomScanner::~CustomScanner() {} - -void KnownPluginList::CustomScanner::scanFinished() {} - -bool KnownPluginList::CustomScanner::shouldExit() const noexcept -{ - if (ThreadPoolJob* job = ThreadPoolJob::getCurrentThreadPoolJob()) - return job->shouldExit(); - - return false; -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/scanning/juce_KnownPluginList.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/scanning/juce_KnownPluginList.h deleted file mode 100644 index 3c8df25fdd..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/scanning/juce_KnownPluginList.h +++ /dev/null @@ -1,223 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_KNOWNPLUGINLIST_H_INCLUDED -#define JUCE_KNOWNPLUGINLIST_H_INCLUDED - - -//============================================================================== -/** - Manages a list of plugin types. - - This can be easily edited, saved and loaded, and used to create instances of - the plugin types in it. - - @see PluginListComponent -*/ -class JUCE_API KnownPluginList : public ChangeBroadcaster -{ -public: - //============================================================================== - /** Creates an empty list. */ - KnownPluginList(); - - /** Destructor. */ - ~KnownPluginList(); - - //============================================================================== - /** Clears the list. */ - void clear(); - - /** Returns the number of types currently in the list. - @see getType - */ - int getNumTypes() const noexcept { return types.size(); } - - /** Returns one of the types. - @see getNumTypes - */ - PluginDescription* getType (int index) const noexcept { return types [index]; } - - /** Type iteration. */ - PluginDescription** begin() const noexcept { return types.begin(); } - /** Type iteration. */ - PluginDescription** end() const noexcept { return types.end(); } - - /** Looks for a type in the list which comes from this file. */ - PluginDescription* getTypeForFile (const String& fileOrIdentifier) const; - - /** Looks for a type in the list which matches a plugin type ID. - - The identifierString parameter must have been created by - PluginDescription::createIdentifierString(). - */ - PluginDescription* getTypeForIdentifierString (const String& identifierString) const; - - /** Adds a type manually from its description. */ - bool addType (const PluginDescription& type); - - /** Removes a type. */ - void removeType (int index); - - /** Looks for all types that can be loaded from a given file, and adds them - to the list. - - If dontRescanIfAlreadyInList is true, then the file will only be loaded and - re-tested if it's not already in the list, or if the file's modification - time has changed since the list was created. If dontRescanIfAlreadyInList is - false, the file will always be reloaded and tested. - - Returns true if any new types were added, and all the types found in this - file (even if it was already known and hasn't been re-scanned) get returned - in the array. - */ - bool scanAndAddFile (const String& possiblePluginFileOrIdentifier, - bool dontRescanIfAlreadyInList, - OwnedArray & typesFound, - AudioPluginFormat& formatToUse); - - /** Tells a custom scanner that a scan has finished, and it can release any resources. */ - void scanFinished(); - - /** Returns true if the specified file is already known about and if it - hasn't been modified since our entry was created. - */ - bool isListingUpToDate (const String& possiblePluginFileOrIdentifier, - AudioPluginFormat& formatToUse) const; - - /** Scans and adds a bunch of files that might have been dragged-and-dropped. - If any types are found in the files, their descriptions are returned in the array. - */ - void scanAndAddDragAndDroppedFiles (AudioPluginFormatManager& formatManager, - const StringArray& filenames, - OwnedArray & typesFound); - - //============================================================================== - /** Returns the list of blacklisted files. */ - const StringArray& getBlacklistedFiles() const; - - /** Adds a plugin ID to the black-list. */ - void addToBlacklist (const String& pluginID); - - /** Removes a plugin ID from the black-list. */ - void removeFromBlacklist (const String& pluginID); - - /** Clears all the blacklisted files. */ - void clearBlacklistedFiles(); - - //============================================================================== - /** Sort methods used to change the order of the plugins in the list. - */ - enum SortMethod - { - defaultOrder = 0, - sortAlphabetically, - sortByCategory, - sortByManufacturer, - sortByFormat, - sortByFileSystemLocation - }; - - //============================================================================== - /** Adds all the plugin types to a popup menu so that the user can select one. - - Depending on the sort method, it may add sub-menus for categories, - manufacturers, etc. - - Use getIndexChosenByMenu() to find out the type that was chosen. - */ - void addToMenu (PopupMenu& menu, SortMethod sortMethod) const; - - /** Converts a menu item index that has been chosen into its index in this list. - Returns -1 if it's not an ID that was used. - @see addToMenu - */ - int getIndexChosenByMenu (int menuResultCode) const; - - //============================================================================== - /** Sorts the list. */ - void sort (SortMethod method, bool forwards); - - //============================================================================== - /** Creates some XML that can be used to store the state of this list. */ - XmlElement* createXml() const; - - /** Recreates the state of this list from its stored XML format. */ - void recreateFromXml (const XmlElement& xml); - - //============================================================================== - /** A structure that recursively holds a tree of plugins. - @see KnownPluginList::createTree() - */ - struct PluginTree - { - String folder; /**< The name of this folder in the tree */ - OwnedArray subFolders; - Array plugins; - }; - - /** Creates a PluginTree object containing all the known plugins. */ - PluginTree* createTree (const SortMethod sortMethod) const; - - //============================================================================== - class CustomScanner - { - public: - CustomScanner(); - virtual ~CustomScanner(); - - /** Attempts to load the given file and find a list of plugins in it. - @returns true if the plugin loaded, false if it crashed - */ - virtual bool findPluginTypesFor (AudioPluginFormat& format, - OwnedArray & result, - const String& fileOrIdentifier) = 0; - - /** Called when a scan has finished, to allow clean-up of resources. */ - virtual void scanFinished(); - - /** Returns true if the current scan should be abandoned. - Any blocking methods should check this value repeatedly and return if - if becomes true. - */ - bool shouldExit() const noexcept; - }; - - /** Supplies a custom scanner to be used in future scans. - The KnownPluginList will take ownership of the object passed in. - */ - void setCustomScanner (CustomScanner*); - -private: - //============================================================================== - OwnedArray types; - StringArray blacklist; - ScopedPointer scanner; - CriticalSection scanLock; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (KnownPluginList) -}; - - -#endif // JUCE_KNOWNPLUGINLIST_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/scanning/juce_PluginDirectoryScanner.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/scanning/juce_PluginDirectoryScanner.cpp deleted file mode 100644 index a7beea7339..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/scanning/juce_PluginDirectoryScanner.cpp +++ /dev/null @@ -1,136 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -static StringArray readDeadMansPedalFile (const File& file) -{ - StringArray lines; - file.readLines (lines); - lines.removeEmptyStrings(); - return lines; -} - -PluginDirectoryScanner::PluginDirectoryScanner (KnownPluginList& listToAddTo, - AudioPluginFormat& formatToLookFor, - FileSearchPath directoriesToSearch, - const bool recursive, - const File& deadMansPedal) - : list (listToAddTo), - format (formatToLookFor), - deadMansPedalFile (deadMansPedal), - progress (0) -{ - directoriesToSearch.removeRedundantPaths(); - - filesOrIdentifiersToScan = format.searchPathsForPlugins (directoriesToSearch, recursive); - - // If any plugins have crashed recently when being loaded, move them to the - // end of the list to give the others a chance to load correctly.. - const StringArray crashedPlugins (readDeadMansPedalFile (deadMansPedalFile)); - - for (int i = 0; i < crashedPlugins.size(); ++i) - { - const String f = crashedPlugins[i]; - - for (int j = filesOrIdentifiersToScan.size(); --j >= 0;) - if (f == filesOrIdentifiersToScan[j]) - filesOrIdentifiersToScan.move (j, -1); - } - - applyBlacklistingsFromDeadMansPedal (listToAddTo, deadMansPedalFile); - nextIndex.set (filesOrIdentifiersToScan.size()); -} - -PluginDirectoryScanner::~PluginDirectoryScanner() -{ - list.scanFinished(); -} - -//============================================================================== -String PluginDirectoryScanner::getNextPluginFileThatWillBeScanned() const -{ - return format.getNameOfPluginFromIdentifier (filesOrIdentifiersToScan [nextIndex.get() - 1]); -} - -void PluginDirectoryScanner::updateProgress() -{ - progress = (1.0f - nextIndex.get() / (float) filesOrIdentifiersToScan.size()); -} - -bool PluginDirectoryScanner::scanNextFile (const bool dontRescanIfAlreadyInList, - String& nameOfPluginBeingScanned) -{ - const int index = --nextIndex; - - if (index >= 0) - { - const String file (filesOrIdentifiersToScan [index]); - - if (file.isNotEmpty() && ! list.isListingUpToDate (file, format)) - { - nameOfPluginBeingScanned = format.getNameOfPluginFromIdentifier (file); - - OwnedArray typesFound; - - // Add this plugin to the end of the dead-man's pedal list in case it crashes... - StringArray crashedPlugins (readDeadMansPedalFile (deadMansPedalFile)); - crashedPlugins.removeString (file); - crashedPlugins.add (file); - setDeadMansPedalFile (crashedPlugins); - - list.scanAndAddFile (file, dontRescanIfAlreadyInList, typesFound, format); - - // Managed to load without crashing, so remove it from the dead-man's-pedal.. - crashedPlugins.removeString (file); - setDeadMansPedalFile (crashedPlugins); - - if (typesFound.size() == 0 && ! list.getBlacklistedFiles().contains (file)) - failedFiles.add (file); - } - } - - updateProgress(); - return index > 0; -} - -bool PluginDirectoryScanner::skipNextFile() -{ - updateProgress(); - return --nextIndex > 0; -} - -void PluginDirectoryScanner::setDeadMansPedalFile (const StringArray& newContents) -{ - if (deadMansPedalFile.getFullPathName().isNotEmpty()) - deadMansPedalFile.replaceWithText (newContents.joinIntoString ("\n"), true, true); -} - -void PluginDirectoryScanner::applyBlacklistingsFromDeadMansPedal (KnownPluginList& list, const File& file) -{ - // If any plugins have crashed recently when being loaded, move them to the - // end of the list to give the others a chance to load correctly.. - const StringArray crashedPlugins (readDeadMansPedalFile (file)); - - for (int i = 0; i < crashedPlugins.size(); ++i) - list.addToBlacklist (crashedPlugins[i]); -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/scanning/juce_PluginDirectoryScanner.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/scanning/juce_PluginDirectoryScanner.h deleted file mode 100644 index 762e742593..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/scanning/juce_PluginDirectoryScanner.h +++ /dev/null @@ -1,127 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_PLUGINDIRECTORYSCANNER_H_INCLUDED -#define JUCE_PLUGINDIRECTORYSCANNER_H_INCLUDED - - -//============================================================================== -/** - Scans a directory for plugins, and adds them to a KnownPluginList. - - To use one of these, create it and call scanNextFile() repeatedly, until - it returns false. -*/ -class JUCE_API PluginDirectoryScanner -{ -public: - //============================================================================== - /** - Creates a scanner. - - @param listToAddResultsTo this will get the new types added to it. - @param formatToLookFor this is the type of format that you want to look for - @param directoriesToSearch the path to search - @param searchRecursively true to search recursively - @param deadMansPedalFile if this isn't File::nonexistent, then it will - be used as a file to store the names of any plugins - that crash during initialisation. If there are - any plugins listed in it, then these will always - be scanned after all other possible files have - been tried - in this way, even if there's a few - dodgy plugins in your path, then a couple of rescans - will still manage to find all the proper plugins. - It's probably best to choose a file in the user's - application data directory (alongside your app's - settings file) for this. The file format it uses - is just a list of filenames of the modules that - failed. - */ - PluginDirectoryScanner (KnownPluginList& listToAddResultsTo, - AudioPluginFormat& formatToLookFor, - FileSearchPath directoriesToSearch, - bool searchRecursively, - const File& deadMansPedalFile); - - /** Destructor. */ - ~PluginDirectoryScanner(); - - //============================================================================== - /** Tries the next likely-looking file. - - If dontRescanIfAlreadyInList is true, then the file will only be loaded and - re-tested if it's not already in the list, or if the file's modification - time has changed since the list was created. If dontRescanIfAlreadyInList is - false, the file will always be reloaded and tested. - The nameOfPluginBeingScanned will be updated to the name of the plugin being - scanned before the scan starts. - - Returns false when there are no more files to try. - */ - bool scanNextFile (bool dontRescanIfAlreadyInList, - String& nameOfPluginBeingScanned); - - /** Skips over the next file without scanning it. - Returns false when there are no more files to try. - */ - bool skipNextFile(); - - /** Returns the description of the plugin that will be scanned during the next - call to scanNextFile(). - - This is handy if you want to show the user which file is currently getting - scanned. - */ - String getNextPluginFileThatWillBeScanned() const; - - /** Returns the estimated progress, between 0 and 1. */ - float getProgress() const { return progress; } - - /** This returns a list of all the filenames of things that looked like being - a plugin file, but which failed to open for some reason. - */ - const StringArray& getFailedFiles() const noexcept { return failedFiles; } - - /** Reads the given dead-mans-pedal file and applies its contents to the list. */ - static void applyBlacklistingsFromDeadMansPedal (KnownPluginList& listToApplyTo, - const File& deadMansPedalFile); - -private: - //============================================================================== - KnownPluginList& list; - AudioPluginFormat& format; - StringArray filesOrIdentifiersToScan; - File deadMansPedalFile; - StringArray failedFiles; - Atomic nextIndex; - float progress; - - void updateProgress(); - void setDeadMansPedalFile (const StringArray& newContents); - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (PluginDirectoryScanner) -}; - - -#endif // JUCE_PLUGINDIRECTORYSCANNER_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/scanning/juce_PluginListComponent.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/scanning/juce_PluginListComponent.cpp deleted file mode 100644 index a0c2388cfa..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/scanning/juce_PluginListComponent.cpp +++ /dev/null @@ -1,554 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -class PluginListComponent::TableModel : public TableListBoxModel -{ -public: - TableModel (PluginListComponent& c, KnownPluginList& l) : owner (c), list (l) {} - - int getNumRows() override - { - return list.getNumTypes() + list.getBlacklistedFiles().size(); - } - - void paintRowBackground (Graphics& g, int /*rowNumber*/, int /*width*/, int /*height*/, bool rowIsSelected) override - { - if (rowIsSelected) - g.fillAll (owner.findColour (TextEditor::highlightColourId)); - } - - enum - { - nameCol = 1, - typeCol = 2, - categoryCol = 3, - manufacturerCol = 4, - descCol = 5 - }; - - void paintCell (Graphics& g, int row, int columnId, int width, int height, bool /*rowIsSelected*/) override - { - String text; - bool isBlacklisted = row >= list.getNumTypes(); - - if (isBlacklisted) - { - if (columnId == nameCol) - text = list.getBlacklistedFiles() [row - list.getNumTypes()]; - else if (columnId == descCol) - text = TRANS("Deactivated after failing to initialise correctly"); - } - else if (const PluginDescription* const desc = list.getType (row)) - { - switch (columnId) - { - case nameCol: text = desc->name; break; - case typeCol: text = desc->pluginFormatName; break; - case categoryCol: text = desc->category.isNotEmpty() ? desc->category : "-"; break; - case manufacturerCol: text = desc->manufacturerName; break; - case descCol: text = getPluginDescription (*desc); break; - - default: jassertfalse; break; - } - } - - if (text.isNotEmpty()) - { - g.setColour (isBlacklisted ? Colours::red - : columnId == nameCol ? Colours::black - : Colours::grey); - g.setFont (Font (height * 0.7f, Font::bold)); - g.drawFittedText (text, 4, 0, width - 6, height, Justification::centredLeft, 1, 0.9f); - } - } - - void deleteKeyPressed (int) override - { - owner.removeSelected(); - } - - void sortOrderChanged (int newSortColumnId, bool isForwards) override - { - switch (newSortColumnId) - { - case nameCol: list.sort (KnownPluginList::sortAlphabetically, isForwards); break; - case typeCol: list.sort (KnownPluginList::sortByFormat, isForwards); break; - case categoryCol: list.sort (KnownPluginList::sortByCategory, isForwards); break; - case manufacturerCol: list.sort (KnownPluginList::sortByManufacturer, isForwards); break; - case descCol: break; - - default: jassertfalse; break; - } - } - - static void removePluginItem (KnownPluginList& list, int index) - { - if (index < list.getNumTypes()) - list.removeType (index); - else - list.removeFromBlacklist (list.getBlacklistedFiles() [index - list.getNumTypes()]); - } - - static String getPluginDescription (const PluginDescription& desc) - { - StringArray items; - - if (desc.descriptiveName != desc.name) - items.add (desc.descriptiveName); - - items.add (desc.version); - - items.removeEmptyStrings(); - return items.joinIntoString (" - "); - } - - PluginListComponent& owner; - KnownPluginList& list; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (TableModel) -}; - -//============================================================================== -PluginListComponent::PluginListComponent (AudioPluginFormatManager& manager, KnownPluginList& listToEdit, - const File& deadMansPedal, PropertiesFile* const props) - : formatManager (manager), - list (listToEdit), - deadMansPedalFile (deadMansPedal), - optionsButton ("Options..."), - propertiesToUse (props), - numThreads (0) -{ - tableModel = new TableModel (*this, listToEdit); - - TableHeaderComponent& header = table.getHeader(); - - header.addColumn (TRANS("Name"), TableModel::nameCol, 200, 100, 700, TableHeaderComponent::defaultFlags | TableHeaderComponent::sortedForwards); - header.addColumn (TRANS("Format"), TableModel::typeCol, 80, 80, 80, TableHeaderComponent::notResizable); - header.addColumn (TRANS("Category"), TableModel::categoryCol, 100, 100, 200); - header.addColumn (TRANS("Manufacturer"), TableModel::manufacturerCol, 200, 100, 300); - header.addColumn (TRANS("Description"), TableModel::descCol, 300, 100, 500, TableHeaderComponent::notSortable); - - table.setHeaderHeight (22); - table.setRowHeight (20); - table.setModel (tableModel); - table.setMultipleSelectionEnabled (true); - addAndMakeVisible (table); - - addAndMakeVisible (optionsButton); - optionsButton.addListener (this); - optionsButton.setTriggeredOnMouseDown (true); - - setSize (400, 600); - list.addChangeListener (this); - updateList(); - table.getHeader().reSortTable(); - - PluginDirectoryScanner::applyBlacklistingsFromDeadMansPedal (list, deadMansPedalFile); - deadMansPedalFile.deleteFile(); -} - -PluginListComponent::~PluginListComponent() -{ - list.removeChangeListener (this); -} - -void PluginListComponent::setOptionsButtonText (const String& newText) -{ - optionsButton.setButtonText (newText); - resized(); -} - -void PluginListComponent::setNumberOfThreadsForScanning (int num) -{ - numThreads = num; -} - -void PluginListComponent::resized() -{ - Rectangle r (getLocalBounds().reduced (2)); - - optionsButton.setBounds (r.removeFromBottom (24)); - optionsButton.changeWidthToFitText (24); - - r.removeFromBottom (3); - table.setBounds (r); -} - -void PluginListComponent::changeListenerCallback (ChangeBroadcaster*) -{ - table.getHeader().reSortTable(); - updateList(); -} - -void PluginListComponent::updateList() -{ - table.updateContent(); - table.repaint(); -} - -void PluginListComponent::removeSelected() -{ - const SparseSet selected (table.getSelectedRows()); - - for (int i = table.getNumRows(); --i >= 0;) - if (selected.contains (i)) - TableModel::removePluginItem (list, i); -} - -bool PluginListComponent::canShowSelectedFolder() const -{ - if (const PluginDescription* const desc = list.getType (table.getSelectedRow())) - return File::createFileWithoutCheckingPath (desc->fileOrIdentifier).exists(); - - return false; -} - -void PluginListComponent::showSelectedFolder() -{ - if (canShowSelectedFolder()) - if (const PluginDescription* const desc = list.getType (table.getSelectedRow())) - File (desc->fileOrIdentifier).getParentDirectory().startAsProcess(); -} - -void PluginListComponent::removeMissingPlugins() -{ - for (int i = list.getNumTypes(); --i >= 0;) - if (! formatManager.doesPluginStillExist (*list.getType (i))) - list.removeType (i); -} - -void PluginListComponent::optionsMenuStaticCallback (int result, PluginListComponent* pluginList) -{ - if (pluginList != nullptr) - pluginList->optionsMenuCallback (result); -} - -void PluginListComponent::optionsMenuCallback (int result) -{ - switch (result) - { - case 0: break; - case 1: list.clear(); break; - case 2: removeSelected(); break; - case 3: showSelectedFolder(); break; - case 4: removeMissingPlugins(); break; - - default: - if (AudioPluginFormat* format = formatManager.getFormat (result - 10)) - scanFor (*format); - - break; - } -} - -void PluginListComponent::buttonClicked (Button* button) -{ - if (button == &optionsButton) - { - PopupMenu menu; - menu.addItem (1, TRANS("Clear list")); - menu.addItem (2, TRANS("Remove selected plug-in from list"), table.getNumSelectedRows() > 0); - menu.addItem (3, TRANS("Show folder containing selected plug-in"), canShowSelectedFolder()); - menu.addItem (4, TRANS("Remove any plug-ins whose files no longer exist")); - menu.addSeparator(); - - for (int i = 0; i < formatManager.getNumFormats(); ++i) - { - AudioPluginFormat* const format = formatManager.getFormat (i); - - if (format->canScanForPlugins()) - menu.addItem (10 + i, "Scan for new or updated " + format->getName() + " plug-ins"); - } - - menu.showMenuAsync (PopupMenu::Options().withTargetComponent (&optionsButton), - ModalCallbackFunction::forComponent (optionsMenuStaticCallback, this)); - } -} - -bool PluginListComponent::isInterestedInFileDrag (const StringArray& /*files*/) -{ - return true; -} - -void PluginListComponent::filesDropped (const StringArray& files, int, int) -{ - OwnedArray typesFound; - list.scanAndAddDragAndDroppedFiles (formatManager, files, typesFound); -} - -FileSearchPath PluginListComponent::getLastSearchPath (PropertiesFile& properties, AudioPluginFormat& format) -{ - return FileSearchPath (properties.getValue ("lastPluginScanPath_" + format.getName(), - format.getDefaultLocationsToSearch().toString())); -} - -void PluginListComponent::setLastSearchPath (PropertiesFile& properties, AudioPluginFormat& format, - const FileSearchPath& newPath) -{ - properties.setValue ("lastPluginScanPath_" + format.getName(), newPath.toString()); -} - -//============================================================================== -class PluginListComponent::Scanner : private Timer -{ -public: - Scanner (PluginListComponent& plc, AudioPluginFormat& format, PropertiesFile* properties, int threads) - : owner (plc), formatToScan (format), propertiesToUse (properties), - pathChooserWindow (TRANS("Select folders to scan..."), String::empty, AlertWindow::NoIcon), - progressWindow (TRANS("Scanning for plug-ins..."), - TRANS("Searching for all possible plug-in files..."), AlertWindow::NoIcon), - progress (0.0), numThreads (threads), finished (false) - { - FileSearchPath path (formatToScan.getDefaultLocationsToSearch()); - - if (path.getNumPaths() > 0) // if the path is empty, then paths aren't used for this format. - { - if (propertiesToUse != nullptr) - path = getLastSearchPath (*propertiesToUse, formatToScan); - - pathList.setSize (500, 300); - pathList.setPath (path); - - pathChooserWindow.addCustomComponent (&pathList); - pathChooserWindow.addButton (TRANS("Scan"), 1, KeyPress (KeyPress::returnKey)); - pathChooserWindow.addButton (TRANS("Cancel"), 0, KeyPress (KeyPress::escapeKey)); - - pathChooserWindow.enterModalState (true, - ModalCallbackFunction::forComponent (startScanCallback, - &pathChooserWindow, this), - false); - } - else - { - startScan(); - } - } - - ~Scanner() - { - if (pool != nullptr) - { - pool->removeAllJobs (true, 60000); - pool = nullptr; - } - } - -private: - PluginListComponent& owner; - AudioPluginFormat& formatToScan; - PropertiesFile* propertiesToUse; - ScopedPointer scanner; - AlertWindow pathChooserWindow, progressWindow; - FileSearchPathListComponent pathList; - String pluginBeingScanned; - double progress; - int numThreads; - bool finished; - ScopedPointer pool; - - static void startScanCallback (int result, AlertWindow* alert, Scanner* scanner) - { - if (alert != nullptr && scanner != nullptr) - { - if (result != 0) - scanner->warnUserAboutStupidPaths(); - else - scanner->finishedScan(); - } - } - - // Try to dissuade people from to scanning their entire C: drive, or other system folders. - void warnUserAboutStupidPaths() - { - for (int i = 0; i < pathList.getPath().getNumPaths(); ++i) - { - const File f (pathList.getPath()[i]); - - if (isStupidPath (f)) - { - AlertWindow::showOkCancelBox (AlertWindow::WarningIcon, - TRANS("Plugin Scanning"), - TRANS("If you choose to scan folders that contain non-plugin files, " - "then scanning may take a long time, and can cause crashes when " - "attempting to load unsuitable files.") - + newLine - + TRANS ("Are you sure you want to scan the folder \"XYZ\"?") - .replace ("XYZ", f.getFullPathName()), - TRANS ("Scan"), - String::empty, - nullptr, - ModalCallbackFunction::create (warnAboutStupidPathsCallback, this)); - return; - } - } - - startScan(); - } - - static bool isStupidPath (const File& f) - { - Array roots; - File::findFileSystemRoots (roots); - - if (roots.contains (f)) - return true; - - File::SpecialLocationType pathsThatWouldBeStupidToScan[] - = { File::globalApplicationsDirectory, - File::userHomeDirectory, - File::userDocumentsDirectory, - File::userDesktopDirectory, - File::tempDirectory, - File::userMusicDirectory, - File::userMoviesDirectory, - File::userPicturesDirectory }; - - for (int i = 0; i < numElementsInArray (pathsThatWouldBeStupidToScan); ++i) - { - const File sillyFolder (File::getSpecialLocation (pathsThatWouldBeStupidToScan[i])); - - if (f == sillyFolder || sillyFolder.isAChildOf (f)) - return true; - } - - return false; - } - - static void warnAboutStupidPathsCallback (int result, Scanner* scanner) - { - if (result != 0) - scanner->startScan(); - else - scanner->finishedScan(); - } - - void startScan() - { - pathChooserWindow.setVisible (false); - - scanner = new PluginDirectoryScanner (owner.list, formatToScan, pathList.getPath(), - true, owner.deadMansPedalFile); - - if (propertiesToUse != nullptr) - { - setLastSearchPath (*propertiesToUse, formatToScan, pathList.getPath()); - propertiesToUse->saveIfNeeded(); - } - - progressWindow.addButton (TRANS("Cancel"), 0, KeyPress (KeyPress::escapeKey)); - progressWindow.addProgressBarComponent (progress); - progressWindow.enterModalState(); - - if (numThreads > 0) - { - pool = new ThreadPool (numThreads); - - for (int i = numThreads; --i >= 0;) - pool->addJob (new ScanJob (*this), true); - } - - startTimer (20); - } - - void finishedScan() - { - owner.scanFinished (scanner != nullptr ? scanner->getFailedFiles() - : StringArray()); - } - - void timerCallback() override - { - if (pool == nullptr) - { - if (doNextScan()) - startTimer (20); - } - - if (! progressWindow.isCurrentlyModal()) - finished = true; - - if (finished) - finishedScan(); - else - progressWindow.setMessage (TRANS("Testing") + ":\n\n" + pluginBeingScanned); - } - - bool doNextScan() - { - if (scanner->scanNextFile (true, pluginBeingScanned)) - { - progress = scanner->getProgress(); - return true; - } - - finished = true; - return false; - } - - struct ScanJob : public ThreadPoolJob - { - ScanJob (Scanner& s) : ThreadPoolJob ("pluginscan"), scanner (s) {} - - JobStatus runJob() - { - while (scanner.doNextScan() && ! shouldExit()) - {} - - return jobHasFinished; - } - - Scanner& scanner; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ScanJob) - }; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Scanner) -}; - -void PluginListComponent::scanFor (AudioPluginFormat& format) -{ - currentScanner = new Scanner (*this, format, propertiesToUse, numThreads); -} - -bool PluginListComponent::isScanning() const noexcept -{ - return currentScanner != nullptr; -} - -void PluginListComponent::scanFinished (const StringArray& failedFiles) -{ - StringArray shortNames; - - for (int i = 0; i < failedFiles.size(); ++i) - shortNames.add (File::createFileWithoutCheckingPath (failedFiles[i]).getFileName()); - - currentScanner = nullptr; // mustn't delete this before using the failed files array - - if (shortNames.size() > 0) - AlertWindow::showMessageBoxAsync (AlertWindow::InfoIcon, - TRANS("Scan complete"), - TRANS("Note that the following files appeared to be plugin files, but failed to load correctly") - + ":\n\n" - + shortNames.joinIntoString (", ")); -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/scanning/juce_PluginListComponent.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/scanning/juce_PluginListComponent.h deleted file mode 100644 index 97751a8022..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_audio_processors/scanning/juce_PluginListComponent.h +++ /dev/null @@ -1,114 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_PLUGINLISTCOMPONENT_H_INCLUDED -#define JUCE_PLUGINLISTCOMPONENT_H_INCLUDED - - -//============================================================================== -/** - A component displaying a list of plugins, with options to scan for them, - add, remove and sort them. -*/ -class JUCE_API PluginListComponent : public Component, - public FileDragAndDropTarget, - private ChangeListener, - private ButtonListener // (can't use Button::Listener due to idiotic VC2005 bug) -{ -public: - //============================================================================== - /** - Creates the list component. - - For info about the deadMansPedalFile, see the PluginDirectoryScanner constructor. - The properties file, if supplied, is used to store the user's last search paths. - */ - PluginListComponent (AudioPluginFormatManager& formatManager, - KnownPluginList& listToRepresent, - const File& deadMansPedalFile, - PropertiesFile* propertiesToUse); - - /** Destructor. */ - ~PluginListComponent(); - - /** Changes the text in the panel's options button. */ - void setOptionsButtonText (const String& newText); - - /** Sets how many threads to simultaneously scan for plugins. - If this is 0, then all scanning happens on the message thread (this is the default) - */ - void setNumberOfThreadsForScanning (int numThreads); - - /** Returns the last search path stored in a given properties file for the specified format. */ - static FileSearchPath getLastSearchPath (PropertiesFile&, AudioPluginFormat&); - - /** Stores a search path in a properties file for the given format. */ - static void setLastSearchPath (PropertiesFile&, AudioPluginFormat&, const FileSearchPath&); - - /** Triggers an asynchronous scan for the given format. */ - void scanFor (AudioPluginFormat&); - - /** Returns true if there's currently a scan in progress. */ - bool isScanning() const noexcept; - -private: - //============================================================================== - AudioPluginFormatManager& formatManager; - KnownPluginList& list; - File deadMansPedalFile; - TableListBox table; - TextButton optionsButton; - PropertiesFile* propertiesToUse; - int numThreads; - - class TableModel; - friend class TableModel; - friend struct ContainerDeletePolicy; - ScopedPointer tableModel; - - class Scanner; - friend class Scanner; - friend struct ContainerDeletePolicy; - ScopedPointer currentScanner; - - void scanFinished (const StringArray&); - static void optionsMenuStaticCallback (int, PluginListComponent*); - void optionsMenuCallback (int); - void updateList(); - void showSelectedFolder(); - bool canShowSelectedFolder() const; - void removeSelected(); - void removeMissingPlugins(); - - void resized() override; - bool isInterestedInFileDrag (const StringArray&) override; - void filesDropped (const StringArray&, int, int) override; - void buttonClicked (Button*) override; - void changeListenerCallback (ChangeBroadcaster*) override; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (PluginListComponent) -}; - - -#endif // JUCE_PLUGINLISTCOMPONENT_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/containers/juce_AbstractFifo.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/containers/juce_AbstractFifo.cpp deleted file mode 100644 index 65b1615c56..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/containers/juce_AbstractFifo.cpp +++ /dev/null @@ -1,235 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -AbstractFifo::AbstractFifo (const int capacity) noexcept - : bufferSize (capacity) -{ - jassert (bufferSize > 0); -} - -AbstractFifo::~AbstractFifo() {} - -int AbstractFifo::getTotalSize() const noexcept { return bufferSize; } -int AbstractFifo::getFreeSpace() const noexcept { return bufferSize - getNumReady() - 1; } - -int AbstractFifo::getNumReady() const noexcept -{ - const int vs = validStart.get(); - const int ve = validEnd.get(); - return ve >= vs ? (ve - vs) : (bufferSize - (vs - ve)); -} - -void AbstractFifo::reset() noexcept -{ - validEnd = 0; - validStart = 0; -} - -void AbstractFifo::setTotalSize (int newSize) noexcept -{ - jassert (newSize > 0); - reset(); - bufferSize = newSize; -} - -//============================================================================== -void AbstractFifo::prepareToWrite (int numToWrite, int& startIndex1, int& blockSize1, int& startIndex2, int& blockSize2) const noexcept -{ - const int vs = validStart.get(); - const int ve = validEnd.value; - - const int freeSpace = ve >= vs ? (bufferSize - (ve - vs)) : (vs - ve); - numToWrite = jmin (numToWrite, freeSpace - 1); - - if (numToWrite <= 0) - { - startIndex1 = 0; - startIndex2 = 0; - blockSize1 = 0; - blockSize2 = 0; - } - else - { - startIndex1 = ve; - startIndex2 = 0; - blockSize1 = jmin (bufferSize - ve, numToWrite); - numToWrite -= blockSize1; - blockSize2 = numToWrite <= 0 ? 0 : jmin (numToWrite, vs); - } -} - -void AbstractFifo::finishedWrite (int numWritten) noexcept -{ - jassert (numWritten >= 0 && numWritten < bufferSize); - int newEnd = validEnd.value + numWritten; - if (newEnd >= bufferSize) - newEnd -= bufferSize; - - validEnd = newEnd; -} - -void AbstractFifo::prepareToRead (int numWanted, int& startIndex1, int& blockSize1, int& startIndex2, int& blockSize2) const noexcept -{ - const int vs = validStart.value; - const int ve = validEnd.get(); - - const int numReady = ve >= vs ? (ve - vs) : (bufferSize - (vs - ve)); - numWanted = jmin (numWanted, numReady); - - if (numWanted <= 0) - { - startIndex1 = 0; - startIndex2 = 0; - blockSize1 = 0; - blockSize2 = 0; - } - else - { - startIndex1 = vs; - startIndex2 = 0; - blockSize1 = jmin (bufferSize - vs, numWanted); - numWanted -= blockSize1; - blockSize2 = numWanted <= 0 ? 0 : jmin (numWanted, ve); - } -} - -void AbstractFifo::finishedRead (int numRead) noexcept -{ - jassert (numRead >= 0 && numRead <= bufferSize); - - int newStart = validStart.value + numRead; - if (newStart >= bufferSize) - newStart -= bufferSize; - - validStart = newStart; -} - -//============================================================================== -//============================================================================== -#if JUCE_UNIT_TESTS - -class AbstractFifoTests : public UnitTest -{ -public: - AbstractFifoTests() : UnitTest ("Abstract Fifo") {} - - class WriteThread : public Thread - { - public: - WriteThread (AbstractFifo& f, int* b, Random rng) - : Thread ("fifo writer"), fifo (f), buffer (b), random (rng) - { - startThread(); - } - - ~WriteThread() - { - stopThread (5000); - } - - void run() - { - int n = 0; - - while (! threadShouldExit()) - { - int num = random.nextInt (2000) + 1; - - int start1, size1, start2, size2; - fifo.prepareToWrite (num, start1, size1, start2, size2); - - jassert (size1 >= 0 && size2 >= 0); - jassert (size1 == 0 || (start1 >= 0 && start1 < fifo.getTotalSize())); - jassert (size2 == 0 || (start2 >= 0 && start2 < fifo.getTotalSize())); - - for (int i = 0; i < size1; ++i) - buffer [start1 + i] = n++; - - for (int i = 0; i < size2; ++i) - buffer [start2 + i] = n++; - - fifo.finishedWrite (size1 + size2); - } - } - - private: - AbstractFifo& fifo; - int* buffer; - Random random; - }; - - void runTest() - { - beginTest ("AbstractFifo"); - - int buffer [5000]; - AbstractFifo fifo (numElementsInArray (buffer)); - - WriteThread writer (fifo, buffer, getRandom()); - - int n = 0; - Random r = getRandom(); - r.combineSeed (12345); - - for (int count = 100000; --count >= 0;) - { - int num = r.nextInt (6000) + 1; - - int start1, size1, start2, size2; - fifo.prepareToRead (num, start1, size1, start2, size2); - - if (! (size1 >= 0 && size2 >= 0) - && (size1 == 0 || (start1 >= 0 && start1 < fifo.getTotalSize())) - && (size2 == 0 || (start2 >= 0 && start2 < fifo.getTotalSize()))) - { - expect (false, "prepareToRead returned -ve values"); - break; - } - - bool failed = false; - - for (int i = 0; i < size1; ++i) - failed = (buffer [start1 + i] != n++) || failed; - - for (int i = 0; i < size2; ++i) - failed = (buffer [start2 + i] != n++) || failed; - - if (failed) - { - expect (false, "read values were incorrect"); - break; - } - - fifo.finishedRead (size1 + size2); - } - } -}; - -static AbstractFifoTests fifoUnitTests; - -#endif diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/containers/juce_AbstractFifo.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/containers/juce_AbstractFifo.h deleted file mode 100644 index 02feac74e8..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/containers/juce_AbstractFifo.h +++ /dev/null @@ -1,220 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_ABSTRACTFIFO_H_INCLUDED -#define JUCE_ABSTRACTFIFO_H_INCLUDED - - -//============================================================================== -/** - Encapsulates the logic required to implement a lock-free FIFO. - - This class handles the logic needed when building a single-reader, single-writer FIFO. - - It doesn't actually hold any data itself, but your FIFO class can use one of these to manage - its position and status when reading or writing to it. - - To use it, you can call prepareToWrite() to determine the position within your own buffer that - an incoming block of data should be stored, and prepareToRead() to find out when the next - outgoing block should be read from. - - e.g. - @code - class MyFifo - { - public: - MyFifo() : abstractFifo (1024) - { - } - - void addToFifo (const int* someData, int numItems) - { - int start1, size1, start2, size2; - abstractFifo.prepareToWrite (numItems, start1, size1, start2, size2); - - if (size1 > 0) - copySomeData (myBuffer + start1, someData, size1); - - if (size2 > 0) - copySomeData (myBuffer + start2, someData + size1, size2); - - abstractFifo.finishedWrite (size1 + size2); - } - - void readFromFifo (int* someData, int numItems) - { - int start1, size1, start2, size2; - abstractFifo.prepareToRead (numSamples, start1, size1, start2, size2); - - if (size1 > 0) - copySomeData (someData, myBuffer + start1, size1); - - if (size2 > 0) - copySomeData (someData + size1, myBuffer + start2, size2); - - abstractFifo.finishedRead (size1 + size2); - } - - private: - AbstractFifo abstractFifo; - int myBuffer [1024]; - }; - @endcode -*/ -class JUCE_API AbstractFifo -{ -public: - //============================================================================== - /** Creates a FIFO to manage a buffer with the specified capacity. */ - AbstractFifo (int capacity) noexcept; - - /** Destructor */ - ~AbstractFifo(); - - //============================================================================== - /** Returns the total size of the buffer being managed. */ - int getTotalSize() const noexcept; - - /** Returns the number of items that can currently be added to the buffer without it overflowing. */ - int getFreeSpace() const noexcept; - - /** Returns the number of items that can currently be read from the buffer. */ - int getNumReady() const noexcept; - - /** Clears the buffer positions, so that it appears empty. */ - void reset() noexcept; - - /** Changes the buffer's total size. - Note that this isn't thread-safe, so don't call it if there's any danger that it - might overlap with a call to any other method in this class! - */ - void setTotalSize (int newSize) noexcept; - - //============================================================================== - /** Returns the location within the buffer at which an incoming block of data should be written. - - Because the section of data that you want to add to the buffer may overlap the end - and wrap around to the start, two blocks within your buffer are returned, and you - should copy your data into the first one, with any remaining data spilling over into - the second. - - If the number of items you ask for is too large to fit within the buffer's free space, then - blockSize1 + blockSize2 may add up to a lower value than numToWrite. If this happens, you - may decide to keep waiting and re-trying the method until there's enough space available. - - After calling this method, if you choose to write your data into the blocks returned, you - must call finishedWrite() to tell the FIFO how much data you actually added. - - e.g. - @code - void addToFifo (const int* someData, int numItems) - { - int start1, size1, start2, size2; - prepareToWrite (numItems, start1, size1, start2, size2); - - if (size1 > 0) - copySomeData (myBuffer + start1, someData, size1); - - if (size2 > 0) - copySomeData (myBuffer + start2, someData + size1, size2); - - finishedWrite (size1 + size2); - } - @endcode - - @param numToWrite indicates how many items you'd like to add to the buffer - @param startIndex1 on exit, this will contain the start index in your buffer at which your data should be written - @param blockSize1 on exit, this indicates how many items can be written to the block starting at startIndex1 - @param startIndex2 on exit, this will contain the start index in your buffer at which any data that didn't fit into - the first block should be written - @param blockSize2 on exit, this indicates how many items can be written to the block starting at startIndex2 - @see finishedWrite - */ - void prepareToWrite (int numToWrite, int& startIndex1, int& blockSize1, int& startIndex2, int& blockSize2) const noexcept; - - /** Called after writing from the FIFO, to indicate that this many items have been added. - @see prepareToWrite - */ - void finishedWrite (int numWritten) noexcept; - - /** Returns the location within the buffer from which the next block of data should be read. - - Because the section of data that you want to read from the buffer may overlap the end - and wrap around to the start, two blocks within your buffer are returned, and you - should read from both of them. - - If the number of items you ask for is greater than the amount of data available, then - blockSize1 + blockSize2 may add up to a lower value than numWanted. If this happens, you - may decide to keep waiting and re-trying the method until there's enough data available. - - After calling this method, if you choose to read the data, you must call finishedRead() to - tell the FIFO how much data you have consumed. - - e.g. - @code - void readFromFifo (int* someData, int numItems) - { - int start1, size1, start2, size2; - prepareToRead (numSamples, start1, size1, start2, size2); - - if (size1 > 0) - copySomeData (someData, myBuffer + start1, size1); - - if (size2 > 0) - copySomeData (someData + size1, myBuffer + start2, size2); - - finishedRead (size1 + size2); - } - @endcode - - @param numWanted indicates how many items you'd like to add to the buffer - @param startIndex1 on exit, this will contain the start index in your buffer at which your data should be written - @param blockSize1 on exit, this indicates how many items can be written to the block starting at startIndex1 - @param startIndex2 on exit, this will contain the start index in your buffer at which any data that didn't fit into - the first block should be written - @param blockSize2 on exit, this indicates how many items can be written to the block starting at startIndex2 - @see finishedRead - */ - void prepareToRead (int numWanted, int& startIndex1, int& blockSize1, int& startIndex2, int& blockSize2) const noexcept; - - /** Called after reading from the FIFO, to indicate that this many items have now been consumed. - @see prepareToRead - */ - void finishedRead (int numRead) noexcept; - - -private: - //============================================================================== - int bufferSize; - Atomic validStart, validEnd; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AbstractFifo) -}; - - -#endif // JUCE_ABSTRACTFIFO_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/containers/juce_Array.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/containers/juce_Array.h deleted file mode 100644 index 8e9cf3f9b0..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/containers/juce_Array.h +++ /dev/null @@ -1,1112 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_ARRAY_H_INCLUDED -#define JUCE_ARRAY_H_INCLUDED - - -//============================================================================== -/** - Holds a resizable array of primitive or copy-by-value objects. - - Examples of arrays are: Array, Array or Array - - The Array class can be used to hold simple, non-polymorphic objects as well as primitive types - to - do so, the class must fulfil these requirements: - - it must have a copy constructor and assignment operator - - it must be able to be relocated in memory by a memcpy without this causing any problems - so - objects whose functionality relies on external pointers or references to themselves can not be used. - - You can of course have an array of pointers to any kind of object, e.g. Array, but if - you do this, the array doesn't take any ownership of the objects - see the OwnedArray class or the - ReferenceCountedArray class for more powerful ways of holding lists of objects. - - For holding lists of strings, you can use Array\, but it's usually better to use the - specialised class StringArray, which provides more useful functions. - - To make all the array's methods thread-safe, pass in "CriticalSection" as the templated - TypeOfCriticalSectionToUse parameter, instead of the default DummyCriticalSection. - - @see OwnedArray, ReferenceCountedArray, StringArray, CriticalSection -*/ -template -class Array -{ -private: - typedef PARAMETER_TYPE (ElementType) ParameterType; - -public: - //============================================================================== - /** Creates an empty array. */ - Array() noexcept : numUsed (0) - { - } - - /** Creates a copy of another array. - @param other the array to copy - */ - Array (const Array& other) - { - const ScopedLockType lock (other.getLock()); - numUsed = other.numUsed; - data.setAllocatedSize (other.numUsed); - - for (int i = 0; i < numUsed; ++i) - new (data.elements + i) ElementType (other.data.elements[i]); - } - - #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS - Array (Array&& other) noexcept - : data (static_cast&&> (other.data)), - numUsed (other.numUsed) - { - other.numUsed = 0; - } - #endif - - /** Initalises from a null-terminated C array of values. - - @param values the array to copy from - */ - template - explicit Array (const TypeToCreateFrom* values) - : numUsed (0) - { - while (*values != TypeToCreateFrom()) - add (*values++); - } - - /** Initalises from a C array of values. - - @param values the array to copy from - @param numValues the number of values in the array - */ - template - Array (const TypeToCreateFrom* values, int numValues) - : numUsed (numValues) - { - data.setAllocatedSize (numValues); - - for (int i = 0; i < numValues; ++i) - new (data.elements + i) ElementType (values[i]); - } - - /** Destructor. */ - ~Array() - { - deleteAllElements(); - } - - /** Copies another array. - @param other the array to copy - */ - Array& operator= (const Array& other) - { - if (this != &other) - { - Array otherCopy (other); - swapWith (otherCopy); - } - - return *this; - } - - #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS - Array& operator= (Array&& other) noexcept - { - const ScopedLockType lock (getLock()); - deleteAllElements(); - data = static_cast&&> (other.data); - numUsed = other.numUsed; - other.numUsed = 0; - return *this; - } - #endif - - //============================================================================== - /** Compares this array to another one. - Two arrays are considered equal if they both contain the same set of - elements, in the same order. - @param other the other array to compare with - */ - template - bool operator== (const OtherArrayType& other) const - { - const ScopedLockType lock (getLock()); - const typename OtherArrayType::ScopedLockType lock2 (other.getLock()); - - if (numUsed != other.numUsed) - return false; - - for (int i = numUsed; --i >= 0;) - if (! (data.elements [i] == other.data.elements [i])) - return false; - - return true; - } - - /** Compares this array to another one. - Two arrays are considered equal if they both contain the same set of - elements, in the same order. - @param other the other array to compare with - */ - template - bool operator!= (const OtherArrayType& other) const - { - return ! operator== (other); - } - - //============================================================================== - /** Removes all elements from the array. - This will remove all the elements, and free any storage that the array is - using. To clear the array without freeing the storage, use the clearQuick() - method instead. - - @see clearQuick - */ - void clear() - { - const ScopedLockType lock (getLock()); - deleteAllElements(); - data.setAllocatedSize (0); - numUsed = 0; - } - - /** Removes all elements from the array without freeing the array's allocated storage. - @see clear - */ - void clearQuick() - { - const ScopedLockType lock (getLock()); - deleteAllElements(); - numUsed = 0; - } - - //============================================================================== - /** Returns the current number of elements in the array. - */ - inline int size() const noexcept - { - return numUsed; - } - - /** Returns one of the elements in the array. - If the index passed in is beyond the range of valid elements, this - will return a default value. - - If you're certain that the index will always be a valid element, you - can call getUnchecked() instead, which is faster. - - @param index the index of the element being requested (0 is the first element in the array) - @see getUnchecked, getFirst, getLast - */ - ElementType operator[] (const int index) const - { - const ScopedLockType lock (getLock()); - - if (isPositiveAndBelow (index, numUsed)) - { - jassert (data.elements != nullptr); - return data.elements [index]; - } - - return ElementType(); - } - - /** Returns one of the elements in the array, without checking the index passed in. - - Unlike the operator[] method, this will try to return an element without - checking that the index is within the bounds of the array, so should only - be used when you're confident that it will always be a valid index. - - @param index the index of the element being requested (0 is the first element in the array) - @see operator[], getFirst, getLast - */ - inline ElementType getUnchecked (const int index) const - { - const ScopedLockType lock (getLock()); - jassert (isPositiveAndBelow (index, numUsed) && data.elements != nullptr); - return data.elements [index]; - } - - /** Returns a direct reference to one of the elements in the array, without checking the index passed in. - - This is like getUnchecked, but returns a direct reference to the element, so that - you can alter it directly. Obviously this can be dangerous, so only use it when - absolutely necessary. - - @param index the index of the element being requested (0 is the first element in the array) - @see operator[], getFirst, getLast - */ - inline ElementType& getReference (const int index) const noexcept - { - const ScopedLockType lock (getLock()); - jassert (isPositiveAndBelow (index, numUsed) && data.elements != nullptr); - return data.elements [index]; - } - - /** Returns the first element in the array, or a default value if the array is empty. - - @see operator[], getUnchecked, getLast - */ - inline ElementType getFirst() const - { - const ScopedLockType lock (getLock()); - - if (numUsed > 0) - { - jassert (data.elements != nullptr); - return data.elements[0]; - } - - return ElementType(); - } - - /** Returns the last element in the array, or a default value if the array is empty. - - @see operator[], getUnchecked, getFirst - */ - inline ElementType getLast() const - { - const ScopedLockType lock (getLock()); - - if (numUsed > 0) - { - jassert (data.elements != nullptr); - return data.elements[numUsed - 1]; - } - - return ElementType(); - } - - /** Returns a pointer to the actual array data. - This pointer will only be valid until the next time a non-const method - is called on the array. - */ - inline ElementType* getRawDataPointer() noexcept - { - return data.elements; - } - - //============================================================================== - /** Returns a pointer to the first element in the array. - This method is provided for compatibility with standard C++ iteration mechanisms. - */ - inline ElementType* begin() const noexcept - { - return data.elements; - } - - /** Returns a pointer to the element which follows the last element in the array. - This method is provided for compatibility with standard C++ iteration mechanisms. - */ - inline ElementType* end() const noexcept - { - #if JUCE_DEBUG - if (data.elements == nullptr || numUsed <= 0) // (to keep static analysers happy) - return data.elements; - #endif - - return data.elements + numUsed; - } - - //============================================================================== - /** Finds the index of the first element which matches the value passed in. - - This will search the array for the given object, and return the index - of its first occurrence. If the object isn't found, the method will return -1. - - @param elementToLookFor the value or object to look for - @returns the index of the object, or -1 if it's not found - */ - int indexOf (ParameterType elementToLookFor) const - { - const ScopedLockType lock (getLock()); - const ElementType* e = data.elements.getData(); - const ElementType* const end_ = e + numUsed; - - for (; e != end_; ++e) - if (elementToLookFor == *e) - return static_cast (e - data.elements.getData()); - - return -1; - } - - /** Returns true if the array contains at least one occurrence of an object. - - @param elementToLookFor the value or object to look for - @returns true if the item is found - */ - bool contains (ParameterType elementToLookFor) const - { - const ScopedLockType lock (getLock()); - const ElementType* e = data.elements.getData(); - const ElementType* const end_ = e + numUsed; - - for (; e != end_; ++e) - if (elementToLookFor == *e) - return true; - - return false; - } - - //============================================================================== - /** Appends a new element at the end of the array. - - @param newElement the new object to add to the array - @see set, insert, addIfNotAlreadyThere, addSorted, addUsingDefaultSort, addArray - */ - void add (const ElementType& newElement) - { - const ScopedLockType lock (getLock()); - data.ensureAllocatedSize (numUsed + 1); - new (data.elements + numUsed++) ElementType (newElement); - } - - #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS - /** Appends a new element at the end of the array. - - @param newElement the new object to add to the array - @see set, insert, addIfNotAlreadyThere, addSorted, addUsingDefaultSort, addArray - */ - void add (ElementType&& newElement) - { - const ScopedLockType lock (getLock()); - data.ensureAllocatedSize (numUsed + 1); - new (data.elements + numUsed++) ElementType (static_cast (newElement)); - } - #endif - - /** Inserts a new element into the array at a given position. - - If the index is less than 0 or greater than the size of the array, the - element will be added to the end of the array. - Otherwise, it will be inserted into the array, moving all the later elements - along to make room. - - @param indexToInsertAt the index at which the new element should be - inserted (pass in -1 to add it to the end) - @param newElement the new object to add to the array - @see add, addSorted, addUsingDefaultSort, set - */ - void insert (int indexToInsertAt, ParameterType newElement) - { - const ScopedLockType lock (getLock()); - data.ensureAllocatedSize (numUsed + 1); - jassert (data.elements != nullptr); - - if (isPositiveAndBelow (indexToInsertAt, numUsed)) - { - ElementType* const insertPos = data.elements + indexToInsertAt; - const int numberToMove = numUsed - indexToInsertAt; - - if (numberToMove > 0) - memmove (insertPos + 1, insertPos, ((size_t) numberToMove) * sizeof (ElementType)); - - new (insertPos) ElementType (newElement); - ++numUsed; - } - else - { - new (data.elements + numUsed++) ElementType (newElement); - } - } - - /** Inserts multiple copies of an element into the array at a given position. - - If the index is less than 0 or greater than the size of the array, the - element will be added to the end of the array. - Otherwise, it will be inserted into the array, moving all the later elements - along to make room. - - @param indexToInsertAt the index at which the new element should be inserted - @param newElement the new object to add to the array - @param numberOfTimesToInsertIt how many copies of the value to insert - @see insert, add, addSorted, set - */ - void insertMultiple (int indexToInsertAt, ParameterType newElement, - int numberOfTimesToInsertIt) - { - if (numberOfTimesToInsertIt > 0) - { - const ScopedLockType lock (getLock()); - data.ensureAllocatedSize (numUsed + numberOfTimesToInsertIt); - ElementType* insertPos; - - if (isPositiveAndBelow (indexToInsertAt, numUsed)) - { - insertPos = data.elements + indexToInsertAt; - const int numberToMove = numUsed - indexToInsertAt; - memmove (insertPos + numberOfTimesToInsertIt, insertPos, ((size_t) numberToMove) * sizeof (ElementType)); - } - else - { - insertPos = data.elements + numUsed; - } - - numUsed += numberOfTimesToInsertIt; - - while (--numberOfTimesToInsertIt >= 0) - new (insertPos++) ElementType (newElement); - } - } - - /** Inserts an array of values into this array at a given position. - - If the index is less than 0 or greater than the size of the array, the - new elements will be added to the end of the array. - Otherwise, they will be inserted into the array, moving all the later elements - along to make room. - - @param indexToInsertAt the index at which the first new element should be inserted - @param newElements the new values to add to the array - @param numberOfElements how many items are in the array - @see insert, add, addSorted, set - */ - void insertArray (int indexToInsertAt, - const ElementType* newElements, - int numberOfElements) - { - if (numberOfElements > 0) - { - const ScopedLockType lock (getLock()); - data.ensureAllocatedSize (numUsed + numberOfElements); - ElementType* insertPos = data.elements; - - if (isPositiveAndBelow (indexToInsertAt, numUsed)) - { - insertPos += indexToInsertAt; - const int numberToMove = numUsed - indexToInsertAt; - memmove (insertPos + numberOfElements, insertPos, numberToMove * sizeof (ElementType)); - } - else - { - insertPos += numUsed; - } - - numUsed += numberOfElements; - - while (--numberOfElements >= 0) - new (insertPos++) ElementType (*newElements++); - } - } - - /** Appends a new element at the end of the array as long as the array doesn't - already contain it. - - If the array already contains an element that matches the one passed in, nothing - will be done. - - @param newElement the new object to add to the array - */ - void addIfNotAlreadyThere (ParameterType newElement) - { - const ScopedLockType lock (getLock()); - - if (! contains (newElement)) - add (newElement); - } - - /** Replaces an element with a new value. - - If the index is less than zero, this method does nothing. - If the index is beyond the end of the array, the item is added to the end of the array. - - @param indexToChange the index whose value you want to change - @param newValue the new value to set for this index. - @see add, insert - */ - void set (const int indexToChange, ParameterType newValue) - { - jassert (indexToChange >= 0); - const ScopedLockType lock (getLock()); - - if (isPositiveAndBelow (indexToChange, numUsed)) - { - jassert (data.elements != nullptr); - data.elements [indexToChange] = newValue; - } - else if (indexToChange >= 0) - { - data.ensureAllocatedSize (numUsed + 1); - new (data.elements + numUsed++) ElementType (newValue); - } - } - - /** Replaces an element with a new value without doing any bounds-checking. - - This just sets a value directly in the array's internal storage, so you'd - better make sure it's in range! - - @param indexToChange the index whose value you want to change - @param newValue the new value to set for this index. - @see set, getUnchecked - */ - void setUnchecked (const int indexToChange, ParameterType newValue) - { - const ScopedLockType lock (getLock()); - jassert (isPositiveAndBelow (indexToChange, numUsed)); - data.elements [indexToChange] = newValue; - } - - /** Adds elements from an array to the end of this array. - - @param elementsToAdd an array of some kind of object from which elements - can be constructed. - @param numElementsToAdd how many elements are in this other array - @see add - */ - template - void addArray (const Type* elementsToAdd, int numElementsToAdd) - { - const ScopedLockType lock (getLock()); - - if (numElementsToAdd > 0) - { - data.ensureAllocatedSize (numUsed + numElementsToAdd); - - while (--numElementsToAdd >= 0) - { - new (data.elements + numUsed) ElementType (*elementsToAdd++); - ++numUsed; - } - } - } - - /** Adds elements from a null-terminated array of pointers to the end of this array. - - @param elementsToAdd an array of pointers to some kind of object from which elements - can be constructed. This array must be terminated by a nullptr - @see addArray - */ - template - void addNullTerminatedArray (const Type* const* elementsToAdd) - { - int num = 0; - for (const Type* const* e = elementsToAdd; *e != nullptr; ++e) - ++num; - - addArray (elementsToAdd, num); - } - - /** This swaps the contents of this array with those of another array. - - If you need to exchange two arrays, this is vastly quicker than using copy-by-value - because it just swaps their internal pointers. - */ - template - void swapWith (OtherArrayType& otherArray) noexcept - { - const ScopedLockType lock1 (getLock()); - const typename OtherArrayType::ScopedLockType lock2 (otherArray.getLock()); - data.swapWith (otherArray.data); - std::swap (numUsed, otherArray.numUsed); - } - - /** Adds elements from another array to the end of this array. - - @param arrayToAddFrom the array from which to copy the elements - @param startIndex the first element of the other array to start copying from - @param numElementsToAdd how many elements to add from the other array. If this - value is negative or greater than the number of available elements, - all available elements will be copied. - @see add - */ - template - void addArray (const OtherArrayType& arrayToAddFrom, - int startIndex = 0, - int numElementsToAdd = -1) - { - const typename OtherArrayType::ScopedLockType lock1 (arrayToAddFrom.getLock()); - - { - const ScopedLockType lock2 (getLock()); - - if (startIndex < 0) - { - jassertfalse; - startIndex = 0; - } - - if (numElementsToAdd < 0 || startIndex + numElementsToAdd > arrayToAddFrom.size()) - numElementsToAdd = arrayToAddFrom.size() - startIndex; - - while (--numElementsToAdd >= 0) - add (arrayToAddFrom.getUnchecked (startIndex++)); - } - } - - /** This will enlarge or shrink the array to the given number of elements, by adding - or removing items from its end. - - If the array is smaller than the given target size, empty elements will be appended - until its size is as specified. If its size is larger than the target, items will be - removed from its end to shorten it. - */ - void resize (const int targetNumItems) - { - jassert (targetNumItems >= 0); - - const int numToAdd = targetNumItems - numUsed; - if (numToAdd > 0) - insertMultiple (numUsed, ElementType(), numToAdd); - else if (numToAdd < 0) - removeRange (targetNumItems, -numToAdd); - } - - /** Inserts a new element into the array, assuming that the array is sorted. - - This will use a comparator to find the position at which the new element - should go. If the array isn't sorted, the behaviour of this - method will be unpredictable. - - @param comparator the comparator to use to compare the elements - see the sort() - method for details about the form this object should take - @param newElement the new element to insert to the array - @returns the index at which the new item was added - @see addUsingDefaultSort, add, sort - */ - template - int addSorted (ElementComparator& comparator, ParameterType newElement) - { - const ScopedLockType lock (getLock()); - const int index = findInsertIndexInSortedArray (comparator, data.elements.getData(), newElement, 0, numUsed); - insert (index, newElement); - return index; - } - - /** Inserts a new element into the array, assuming that the array is sorted. - - This will use the DefaultElementComparator class for sorting, so your ElementType - must be suitable for use with that class. If the array isn't sorted, the behaviour of this - method will be unpredictable. - - @param newElement the new element to insert to the array - @see addSorted, sort - */ - void addUsingDefaultSort (ParameterType newElement) - { - DefaultElementComparator comparator; - addSorted (comparator, newElement); - } - - /** Finds the index of an element in the array, assuming that the array is sorted. - - This will use a comparator to do a binary-chop to find the index of the given - element, if it exists. If the array isn't sorted, the behaviour of this - method will be unpredictable. - - @param comparator the comparator to use to compare the elements - see the sort() - method for details about the form this object should take - @param elementToLookFor the element to search for - @returns the index of the element, or -1 if it's not found - @see addSorted, sort - */ - template - int indexOfSorted (ElementComparator& comparator, TargetValueType elementToLookFor) const - { - (void) comparator; // if you pass in an object with a static compareElements() method, this - // avoids getting warning messages about the parameter being unused - - const ScopedLockType lock (getLock()); - - for (int s = 0, e = numUsed;;) - { - if (s >= e) - return -1; - - if (comparator.compareElements (elementToLookFor, data.elements [s]) == 0) - return s; - - const int halfway = (s + e) / 2; - if (halfway == s) - return -1; - - if (comparator.compareElements (elementToLookFor, data.elements [halfway]) >= 0) - s = halfway; - else - e = halfway; - } - } - - //============================================================================== - /** Removes an element from the array. - - This will remove the element at a given index, and move back - all the subsequent elements to close the gap. - If the index passed in is out-of-range, nothing will happen. - - @param indexToRemove the index of the element to remove - @returns the element that has been removed - @see removeFirstMatchingValue, removeAllInstancesOf, removeRange - */ - ElementType remove (const int indexToRemove) - { - const ScopedLockType lock (getLock()); - - if (isPositiveAndBelow (indexToRemove, numUsed)) - { - jassert (data.elements != nullptr); - ElementType removed (data.elements[indexToRemove]); - removeInternal (indexToRemove); - return removed; - } - - return ElementType(); - } - - /** Removes an item from the array. - - This will remove the first occurrence of the given element from the array. - If the item isn't found, no action is taken. - - @param valueToRemove the object to try to remove - @see remove, removeRange - */ - void removeFirstMatchingValue (ParameterType valueToRemove) - { - const ScopedLockType lock (getLock()); - ElementType* const e = data.elements; - - for (int i = 0; i < numUsed; ++i) - { - if (valueToRemove == e[i]) - { - removeInternal (i); - break; - } - } - } - - /** Removes an item from the array. - - This will remove the first occurrence of the given element from the array. - If the item isn't found, no action is taken. - - @param valueToRemove the object to try to remove - @see remove, removeRange - */ - void removeAllInstancesOf (ParameterType valueToRemove) - { - const ScopedLockType lock (getLock()); - - for (int i = numUsed; --i >= 0;) - if (valueToRemove == data.elements[i]) - removeInternal (i); - } - - /** Removes a range of elements from the array. - - This will remove a set of elements, starting from the given index, - and move subsequent elements down to close the gap. - - If the range extends beyond the bounds of the array, it will - be safely clipped to the size of the array. - - @param startIndex the index of the first element to remove - @param numberToRemove how many elements should be removed - @see remove, removeFirstMatchingValue, removeAllInstancesOf - */ - void removeRange (int startIndex, int numberToRemove) - { - const ScopedLockType lock (getLock()); - const int endIndex = jlimit (0, numUsed, startIndex + numberToRemove); - startIndex = jlimit (0, numUsed, startIndex); - - if (endIndex > startIndex) - { - ElementType* const e = data.elements + startIndex; - - numberToRemove = endIndex - startIndex; - for (int i = 0; i < numberToRemove; ++i) - e[i].~ElementType(); - - const int numToShift = numUsed - endIndex; - if (numToShift > 0) - memmove (e, e + numberToRemove, ((size_t) numToShift) * sizeof (ElementType)); - - numUsed -= numberToRemove; - minimiseStorageAfterRemoval(); - } - } - - /** Removes the last n elements from the array. - - @param howManyToRemove how many elements to remove from the end of the array - @see remove, removeFirstMatchingValue, removeAllInstancesOf, removeRange - */ - void removeLast (int howManyToRemove = 1) - { - const ScopedLockType lock (getLock()); - - if (howManyToRemove > numUsed) - howManyToRemove = numUsed; - - for (int i = 1; i <= howManyToRemove; ++i) - data.elements [numUsed - i].~ElementType(); - - numUsed -= howManyToRemove; - minimiseStorageAfterRemoval(); - } - - /** Removes any elements which are also in another array. - - @param otherArray the other array in which to look for elements to remove - @see removeValuesNotIn, remove, removeFirstMatchingValue, removeAllInstancesOf, removeRange - */ - template - void removeValuesIn (const OtherArrayType& otherArray) - { - const typename OtherArrayType::ScopedLockType lock1 (otherArray.getLock()); - const ScopedLockType lock2 (getLock()); - - if (this == &otherArray) - { - clear(); - } - else - { - if (otherArray.size() > 0) - { - for (int i = numUsed; --i >= 0;) - if (otherArray.contains (data.elements [i])) - removeInternal (i); - } - } - } - - /** Removes any elements which are not found in another array. - - Only elements which occur in this other array will be retained. - - @param otherArray the array in which to look for elements NOT to remove - @see removeValuesIn, remove, removeFirstMatchingValue, removeAllInstancesOf, removeRange - */ - template - void removeValuesNotIn (const OtherArrayType& otherArray) - { - const typename OtherArrayType::ScopedLockType lock1 (otherArray.getLock()); - const ScopedLockType lock2 (getLock()); - - if (this != &otherArray) - { - if (otherArray.size() <= 0) - { - clear(); - } - else - { - for (int i = numUsed; --i >= 0;) - if (! otherArray.contains (data.elements [i])) - removeInternal (i); - } - } - } - - /** Swaps over two elements in the array. - - This swaps over the elements found at the two indexes passed in. - If either index is out-of-range, this method will do nothing. - - @param index1 index of one of the elements to swap - @param index2 index of the other element to swap - */ - void swap (const int index1, - const int index2) - { - const ScopedLockType lock (getLock()); - - if (isPositiveAndBelow (index1, numUsed) - && isPositiveAndBelow (index2, numUsed)) - { - std::swap (data.elements [index1], - data.elements [index2]); - } - } - - /** Moves one of the values to a different position. - - This will move the value to a specified index, shuffling along - any intervening elements as required. - - So for example, if you have the array { 0, 1, 2, 3, 4, 5 } then calling - move (2, 4) would result in { 0, 1, 3, 4, 2, 5 }. - - @param currentIndex the index of the value to be moved. If this isn't a - valid index, then nothing will be done - @param newIndex the index at which you'd like this value to end up. If this - is less than zero, the value will be moved to the end - of the array - */ - void move (const int currentIndex, int newIndex) noexcept - { - if (currentIndex != newIndex) - { - const ScopedLockType lock (getLock()); - - if (isPositiveAndBelow (currentIndex, numUsed)) - { - if (! isPositiveAndBelow (newIndex, numUsed)) - newIndex = numUsed - 1; - - char tempCopy [sizeof (ElementType)]; - memcpy (tempCopy, data.elements + currentIndex, sizeof (ElementType)); - - if (newIndex > currentIndex) - { - memmove (data.elements + currentIndex, - data.elements + currentIndex + 1, - sizeof (ElementType) * (size_t) (newIndex - currentIndex)); - } - else - { - memmove (data.elements + newIndex + 1, - data.elements + newIndex, - sizeof (ElementType) * (size_t) (currentIndex - newIndex)); - } - - memcpy (data.elements + newIndex, tempCopy, sizeof (ElementType)); - } - } - } - - //============================================================================== - /** Reduces the amount of storage being used by the array. - - Arrays typically allocate slightly more storage than they need, and after - removing elements, they may have quite a lot of unused space allocated. - This method will reduce the amount of allocated storage to a minimum. - */ - void minimiseStorageOverheads() - { - const ScopedLockType lock (getLock()); - data.shrinkToNoMoreThan (numUsed); - } - - /** Increases the array's internal storage to hold a minimum number of elements. - - Calling this before adding a large known number of elements means that - the array won't have to keep dynamically resizing itself as the elements - are added, and it'll therefore be more efficient. - */ - void ensureStorageAllocated (const int minNumElements) - { - const ScopedLockType lock (getLock()); - data.ensureAllocatedSize (minNumElements); - } - - //============================================================================== - /** Sorts the elements in the array. - - This will use a comparator object to sort the elements into order. The object - passed must have a method of the form: - @code - int compareElements (ElementType first, ElementType second); - @endcode - - ..and this method must return: - - a value of < 0 if the first comes before the second - - a value of 0 if the two objects are equivalent - - a value of > 0 if the second comes before the first - - To improve performance, the compareElements() method can be declared as static or const. - - @param comparator the comparator to use for comparing elements. - @param retainOrderOfEquivalentItems if this is true, then items - which the comparator says are equivalent will be - kept in the order in which they currently appear - in the array. This is slower to perform, but may - be important in some cases. If it's false, a faster - algorithm is used, but equivalent elements may be - rearranged. - - @see addSorted, indexOfSorted, sortArray - */ - template - void sort (ElementComparator& comparator, - const bool retainOrderOfEquivalentItems = false) const - { - const ScopedLockType lock (getLock()); - (void) comparator; // if you pass in an object with a static compareElements() method, this - // avoids getting warning messages about the parameter being unused - sortArray (comparator, data.elements.getData(), 0, size() - 1, retainOrderOfEquivalentItems); - } - - //============================================================================== - /** Returns the CriticalSection that locks this array. - To lock, you can call getLock().enter() and getLock().exit(), or preferably use - an object of ScopedLockType as an RAII lock for it. - */ - inline const TypeOfCriticalSectionToUse& getLock() const noexcept { return data; } - - /** Returns the type of scoped lock to use for locking this array */ - typedef typename TypeOfCriticalSectionToUse::ScopedLockType ScopedLockType; - - - //============================================================================== - #ifndef DOXYGEN - // Note that the swapWithArray method has been replaced by a more flexible templated version, - // and renamed "swapWith" to be more consistent with the names used in other classes. - JUCE_DEPRECATED_WITH_BODY (void swapWithArray (Array& other) noexcept, { swapWith (other); }) - #endif - -private: - //============================================================================== - ArrayAllocationBase data; - int numUsed; - - void removeInternal (const int indexToRemove) - { - --numUsed; - ElementType* const e = data.elements + indexToRemove; - e->~ElementType(); - const int numberToShift = numUsed - indexToRemove; - - if (numberToShift > 0) - memmove (e, e + 1, ((size_t) numberToShift) * sizeof (ElementType)); - - minimiseStorageAfterRemoval(); - } - - inline void deleteAllElements() noexcept - { - for (int i = 0; i < numUsed; ++i) - data.elements[i].~ElementType(); - } - - void minimiseStorageAfterRemoval() - { - if (data.numAllocated > jmax (minimumAllocatedSize, numUsed * 2)) - data.shrinkToNoMoreThan (jmax (numUsed, jmax (minimumAllocatedSize, 64 / (int) sizeof (ElementType)))); - } -}; - - -#endif // JUCE_ARRAY_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/containers/juce_ArrayAllocationBase.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/containers/juce_ArrayAllocationBase.h deleted file mode 100644 index cfbe464671..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/containers/juce_ArrayAllocationBase.h +++ /dev/null @@ -1,138 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_ARRAYALLOCATIONBASE_H_INCLUDED -#define JUCE_ARRAYALLOCATIONBASE_H_INCLUDED - - -//============================================================================== -/** - Implements some basic array storage allocation functions. - - This class isn't really for public use - it's used by the other - array classes, but might come in handy for some purposes. - - It inherits from a critical section class to allow the arrays to use - the "empty base class optimisation" pattern to reduce their footprint. - - @see Array, OwnedArray, ReferenceCountedArray -*/ -template -class ArrayAllocationBase : public TypeOfCriticalSectionToUse -{ -public: - //============================================================================== - /** Creates an empty array. */ - ArrayAllocationBase() noexcept - : numAllocated (0) - { - } - - /** Destructor. */ - ~ArrayAllocationBase() noexcept - { - } - - #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS - ArrayAllocationBase (ArrayAllocationBase&& other) noexcept - : elements (static_cast &&> (other.elements)), - numAllocated (other.numAllocated) - { - } - - ArrayAllocationBase& operator= (ArrayAllocationBase&& other) noexcept - { - elements = static_cast &&> (other.elements); - numAllocated = other.numAllocated; - return *this; - } - #endif - - //============================================================================== - /** Changes the amount of storage allocated. - - This will retain any data currently held in the array, and either add or - remove extra space at the end. - - @param numElements the number of elements that are needed - */ - void setAllocatedSize (const int numElements) - { - if (numAllocated != numElements) - { - if (numElements > 0) - elements.realloc ((size_t) numElements); - else - elements.free(); - - numAllocated = numElements; - } - } - - /** Increases the amount of storage allocated if it is less than a given amount. - - This will retain any data currently held in the array, but will add - extra space at the end to make sure there it's at least as big as the size - passed in. If it's already bigger, no action is taken. - - @param minNumElements the minimum number of elements that are needed - */ - void ensureAllocatedSize (const int minNumElements) - { - if (minNumElements > numAllocated) - setAllocatedSize ((minNumElements + minNumElements / 2 + 8) & ~7); - - jassert (numAllocated <= 0 || elements != nullptr); - } - - /** Minimises the amount of storage allocated so that it's no more than - the given number of elements. - */ - void shrinkToNoMoreThan (const int maxNumElements) - { - if (maxNumElements < numAllocated) - setAllocatedSize (maxNumElements); - } - - /** Swap the contents of two objects. */ - void swapWith (ArrayAllocationBase & other) noexcept - { - elements.swapWith (other.elements); - std::swap (numAllocated, other.numAllocated); - } - - //============================================================================== - HeapBlock elements; - int numAllocated; - -private: - JUCE_DECLARE_NON_COPYABLE (ArrayAllocationBase) -}; - - -#endif // JUCE_ARRAYALLOCATIONBASE_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/containers/juce_DynamicObject.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/containers/juce_DynamicObject.cpp deleted file mode 100644 index 38f5c5f081..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/containers/juce_DynamicObject.cpp +++ /dev/null @@ -1,133 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -DynamicObject::DynamicObject() -{ -} - -DynamicObject::DynamicObject (const DynamicObject& other) - : ReferenceCountedObject(), properties (other.properties) -{ -} - -DynamicObject::~DynamicObject() -{ -} - -bool DynamicObject::hasProperty (const Identifier& propertyName) const -{ - const var* const v = properties.getVarPointer (propertyName); - return v != nullptr && ! v->isMethod(); -} - -var DynamicObject::getProperty (const Identifier& propertyName) const -{ - return properties [propertyName]; -} - -void DynamicObject::setProperty (const Identifier& propertyName, const var& newValue) -{ - properties.set (propertyName, newValue); -} - -void DynamicObject::removeProperty (const Identifier& propertyName) -{ - properties.remove (propertyName); -} - -bool DynamicObject::hasMethod (const Identifier& methodName) const -{ - return getProperty (methodName).isMethod(); -} - -var DynamicObject::invokeMethod (Identifier method, const var::NativeFunctionArgs& args) -{ - if (var::NativeFunction function = properties [method].getNativeFunction()) - return function (args); - - return var(); -} - -void DynamicObject::setMethod (Identifier name, var::NativeFunction function) -{ - properties.set (name, var (function)); -} - -void DynamicObject::clear() -{ - properties.clear(); -} - -void DynamicObject::cloneAllProperties() -{ - for (int i = properties.size(); --i >= 0;) - if (var* v = properties.getVarPointerAt (i)) - *v = v->clone(); -} - -DynamicObject::Ptr DynamicObject::clone() -{ - Ptr d (new DynamicObject (*this)); - d->cloneAllProperties(); - return d; -} - -void DynamicObject::writeAsJSON (OutputStream& out, const int indentLevel, const bool allOnOneLine) -{ - out << '{'; - if (! allOnOneLine) - out << newLine; - - const int numValues = properties.size(); - - for (int i = 0; i < numValues; ++i) - { - if (! allOnOneLine) - JSONFormatter::writeSpaces (out, indentLevel + JSONFormatter::indentSize); - - out << '"'; - JSONFormatter::writeString (out, properties.getName (i)); - out << "\": "; - JSONFormatter::write (out, properties.getValueAt (i), indentLevel + JSONFormatter::indentSize, allOnOneLine); - - if (i < numValues - 1) - { - if (allOnOneLine) - out << ", "; - else - out << ',' << newLine; - } - else if (! allOnOneLine) - out << newLine; - } - - if (! allOnOneLine) - JSONFormatter::writeSpaces (out, indentLevel); - - out << '}'; -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/containers/juce_DynamicObject.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/containers/juce_DynamicObject.h deleted file mode 100644 index 5c624a4d9b..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/containers/juce_DynamicObject.h +++ /dev/null @@ -1,139 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_DYNAMICOBJECT_H_INCLUDED -#define JUCE_DYNAMICOBJECT_H_INCLUDED - - -//============================================================================== -/** - Represents a dynamically implemented object. - - This class is primarily intended for wrapping scripting language objects, - but could be used for other purposes. - - An instance of a DynamicObject can be used to store named properties, and - by subclassing hasMethod() and invokeMethod(), you can give your object - methods. -*/ -class JUCE_API DynamicObject : public ReferenceCountedObject -{ -public: - //============================================================================== - DynamicObject(); - DynamicObject (const DynamicObject&); - ~DynamicObject(); - - typedef ReferenceCountedObjectPtr Ptr; - - //============================================================================== - /** Returns true if the object has a property with this name. - Note that if the property is actually a method, this will return false. - */ - virtual bool hasProperty (const Identifier& propertyName) const; - - /** Returns a named property. - This returns var::null if no such property exists. - */ - virtual var getProperty (const Identifier& propertyName) const; - - /** Sets a named property. */ - virtual void setProperty (const Identifier& propertyName, const var& newValue); - - /** Removes a named property. */ - virtual void removeProperty (const Identifier& propertyName); - - //============================================================================== - /** Checks whether this object has the specified method. - - The default implementation of this just checks whether there's a property - with this name that's actually a method, but this can be overridden for - building objects with dynamic invocation. - */ - virtual bool hasMethod (const Identifier& methodName) const; - - /** Invokes a named method on this object. - - The default implementation looks up the named property, and if it's a method - call, then it invokes it. - - This method is virtual to allow more dynamic invocation to used for objects - where the methods may not already be set as properies. - */ - virtual var invokeMethod (Identifier methodName, - const var::NativeFunctionArgs& args); - - /** Adds a method to the class. - - This is basically the same as calling setProperty (methodName, (var::NativeFunction) myFunction), but - helps to avoid accidentally invoking the wrong type of var constructor. It also makes - the code easier to read, - */ - void setMethod (Identifier methodName, var::NativeFunction function); - - //============================================================================== - /** Removes all properties and methods from the object. */ - void clear(); - - /** Returns the NamedValueSet that holds the object's properties. */ - NamedValueSet& getProperties() noexcept { return properties; } - - /** Calls var::clone() on all the properties that this object contains. */ - void cloneAllProperties(); - - //============================================================================== - /** Returns a clone of this object. - The default implementation of this method just returns a new DynamicObject - with a (deep) copy of all of its properties. Subclasses can override this to - implement their own custom copy routines. - */ - virtual Ptr clone(); - - //============================================================================== - /** Writes this object to a text stream in JSON format. - This method is used by JSON::toString and JSON::writeToStream, and you should - never need to call it directly, but it's virtual so that custom object types - can stringify themselves appropriately. - */ - virtual void writeAsJSON (OutputStream&, int indentLevel, bool allOnOneLine); - -private: - //============================================================================== - NamedValueSet properties; - - #if JUCE_CATCH_DEPRECATED_CODE_MISUSE - // These methods have been deprecated - use var::invoke instead - virtual void invokeMethod (const Identifier&, const var*, int) {} - #endif - - JUCE_LEAK_DETECTOR (DynamicObject) -}; - - - -#endif // JUCE_DYNAMICOBJECT_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/containers/juce_ElementComparator.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/containers/juce_ElementComparator.h deleted file mode 100644 index 01dc5b7030..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/containers/juce_ElementComparator.h +++ /dev/null @@ -1,195 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_ELEMENTCOMPARATOR_H_INCLUDED -#define JUCE_ELEMENTCOMPARATOR_H_INCLUDED - -#ifndef DOXYGEN - -/** This is an internal helper class which converts a juce ElementComparator style - class (using a "compareElements" method) into a class that's compatible with - std::sort (i.e. using an operator() to compare the elements) -*/ -template -struct SortFunctionConverter -{ - SortFunctionConverter (ElementComparator& e) : comparator (e) {} - - template - bool operator() (Type a, Type b) { return comparator.compareElements (a, b) < 0; } - -private: - ElementComparator& comparator; - SortFunctionConverter& operator= (const SortFunctionConverter&) JUCE_DELETED_FUNCTION; -}; - -#endif - - -//============================================================================== -/** - Sorts a range of elements in an array. - - The comparator object that is passed-in must define a public method with the following - signature: - @code - int compareElements (ElementType first, ElementType second); - @endcode - - ..and this method must return: - - a value of < 0 if the first comes before the second - - a value of 0 if the two objects are equivalent - - a value of > 0 if the second comes before the first - - To improve performance, the compareElements() method can be declared as static or const. - - @param comparator an object which defines a compareElements() method - @param array the array to sort - @param firstElement the index of the first element of the range to be sorted - @param lastElement the index of the last element in the range that needs - sorting (this is inclusive) - @param retainOrderOfEquivalentItems if true, the order of items that the - comparator deems the same will be maintained - this will be - a slower algorithm than if they are allowed to be moved around. - - @see sortArrayRetainingOrder -*/ -template -static void sortArray (ElementComparator& comparator, - ElementType* const array, - int firstElement, - int lastElement, - const bool retainOrderOfEquivalentItems) -{ - SortFunctionConverter converter (comparator); - - if (retainOrderOfEquivalentItems) - std::stable_sort (array + firstElement, array + lastElement + 1, converter); - else - std::sort (array + firstElement, array + lastElement + 1, converter); -} - - -//============================================================================== -/** - Searches a sorted array of elements, looking for the index at which a specified value - should be inserted for it to be in the correct order. - - The comparator object that is passed-in must define a public method with the following - signature: - @code - int compareElements (ElementType first, ElementType second); - @endcode - - ..and this method must return: - - a value of < 0 if the first comes before the second - - a value of 0 if the two objects are equivalent - - a value of > 0 if the second comes before the first - - To improve performance, the compareElements() method can be declared as static or const. - - @param comparator an object which defines a compareElements() method - @param array the array to search - @param newElement the value that is going to be inserted - @param firstElement the index of the first element to search - @param lastElement the index of the last element in the range (this is non-inclusive) -*/ -template -static int findInsertIndexInSortedArray (ElementComparator& comparator, - ElementType* const array, - const ElementType newElement, - int firstElement, - int lastElement) -{ - jassert (firstElement <= lastElement); - - (void) comparator; // if you pass in an object with a static compareElements() method, this - // avoids getting warning messages about the parameter being unused - - while (firstElement < lastElement) - { - if (comparator.compareElements (newElement, array [firstElement]) == 0) - { - ++firstElement; - break; - } - else - { - const int halfway = (firstElement + lastElement) >> 1; - - if (halfway == firstElement) - { - if (comparator.compareElements (newElement, array [halfway]) >= 0) - ++firstElement; - - break; - } - else if (comparator.compareElements (newElement, array [halfway]) >= 0) - { - firstElement = halfway; - } - else - { - lastElement = halfway; - } - } - } - - return firstElement; -} - -//============================================================================== -/** - A simple ElementComparator class that can be used to sort an array of - objects that support the '<' operator. - - This will work for primitive types and objects that implement operator<(). - - Example: @code - Array myArray; - DefaultElementComparator sorter; - myArray.sort (sorter); - @endcode - - @see ElementComparator -*/ -template -class DefaultElementComparator -{ -private: - typedef PARAMETER_TYPE (ElementType) ParameterType; - -public: - static int compareElements (ParameterType first, ParameterType second) - { - return (first < second) ? -1 : ((second < first) ? 1 : 0); - } -}; - - -#endif // JUCE_ELEMENTCOMPARATOR_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/containers/juce_HashMap.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/containers/juce_HashMap.h deleted file mode 100644 index 07d02b401f..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/containers/juce_HashMap.h +++ /dev/null @@ -1,455 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_HASHMAP_H_INCLUDED -#define JUCE_HASHMAP_H_INCLUDED - - -//============================================================================== -/** - A simple class to generate hash functions for some primitive types, intended for - use with the HashMap class. - @see HashMap -*/ -struct DefaultHashFunctions -{ - /** Generates a simple hash from an integer. */ - int generateHash (const int key, const int upperLimit) const noexcept { return std::abs (key) % upperLimit; } - /** Generates a simple hash from an int64. */ - int generateHash (const int64 key, const int upperLimit) const noexcept { return std::abs ((int) key) % upperLimit; } - /** Generates a simple hash from a string. */ - int generateHash (const String& key, const int upperLimit) const noexcept { return (int) (((uint32) key.hashCode()) % (uint32) upperLimit); } - /** Generates a simple hash from a variant. */ - int generateHash (const var& key, const int upperLimit) const noexcept { return generateHash (key.toString(), upperLimit); } -}; - - -//============================================================================== -/** - Holds a set of mappings between some key/value pairs. - - The types of the key and value objects are set as template parameters. - You can also specify a class to supply a hash function that converts a key value - into an hashed integer. This class must have the form: - - @code - struct MyHashGenerator - { - int generateHash (MyKeyType key, int upperLimit) const - { - // The function must return a value 0 <= x < upperLimit - return someFunctionOfMyKeyType (key) % upperLimit; - } - }; - @endcode - - Like the Array class, the key and value types are expected to be copy-by-value - types, so if you define them to be pointer types, this class won't delete the - objects that they point to. - - If you don't supply a class for the HashFunctionType template parameter, the - default one provides some simple mappings for strings and ints. - - @code - HashMap hash; - hash.set (1, "item1"); - hash.set (2, "item2"); - - DBG (hash [1]); // prints "item1" - DBG (hash [2]); // prints "item2" - - // This iterates the map, printing all of its key -> value pairs.. - for (HashMap::Iterator i (hash); i.next();) - DBG (i.getKey() << " -> " << i.getValue()); - @endcode - - @tparam HashFunctionType The class of hash function, which must be copy-constructible. - @see CriticalSection, DefaultHashFunctions, NamedValueSet, SortedSet -*/ -template -class HashMap -{ -private: - typedef PARAMETER_TYPE (KeyType) KeyTypeParameter; - typedef PARAMETER_TYPE (ValueType) ValueTypeParameter; - -public: - //============================================================================== - /** Creates an empty hash-map. - - @param numberOfSlots Specifies the number of hash entries the map will use. This will be - the "upperLimit" parameter that is passed to your generateHash() - function. The number of hash slots will grow automatically if necessary, - or it can be remapped manually using remapTable(). - @param hashFunction An instance of HashFunctionType, which will be copied and - stored to use with the HashMap. This parameter can be omitted - if HashFunctionType has a default constructor. - */ - explicit HashMap (int numberOfSlots = defaultHashTableSize, - HashFunctionType hashFunction = HashFunctionType()) - : hashFunctionToUse (hashFunction), totalNumItems (0) - { - hashSlots.insertMultiple (0, nullptr, numberOfSlots); - } - - /** Destructor. */ - ~HashMap() - { - clear(); - } - - //============================================================================== - /** Removes all values from the map. - Note that this will clear the content, but won't affect the number of slots (see - remapTable and getNumSlots). - */ - void clear() - { - const ScopedLockType sl (getLock()); - - for (int i = hashSlots.size(); --i >= 0;) - { - HashEntry* h = hashSlots.getUnchecked(i); - - while (h != nullptr) - { - const ScopedPointer deleter (h); - h = h->nextEntry; - } - - hashSlots.set (i, nullptr); - } - - totalNumItems = 0; - } - - //============================================================================== - /** Returns the current number of items in the map. */ - inline int size() const noexcept - { - return totalNumItems; - } - - /** Returns the value corresponding to a given key. - If the map doesn't contain the key, a default instance of the value type is returned. - @param keyToLookFor the key of the item being requested - */ - inline ValueType operator[] (KeyTypeParameter keyToLookFor) const - { - const ScopedLockType sl (getLock()); - - for (const HashEntry* entry = hashSlots.getUnchecked (generateHashFor (keyToLookFor)); entry != nullptr; entry = entry->nextEntry) - if (entry->key == keyToLookFor) - return entry->value; - - return ValueType(); - } - - //============================================================================== - /** Returns true if the map contains an item with the specied key. */ - bool contains (KeyTypeParameter keyToLookFor) const - { - const ScopedLockType sl (getLock()); - - for (const HashEntry* entry = hashSlots.getUnchecked (generateHashFor (keyToLookFor)); entry != nullptr; entry = entry->nextEntry) - if (entry->key == keyToLookFor) - return true; - - return false; - } - - /** Returns true if the hash contains at least one occurrence of a given value. */ - bool containsValue (ValueTypeParameter valueToLookFor) const - { - const ScopedLockType sl (getLock()); - - for (int i = getNumSlots(); --i >= 0;) - for (const HashEntry* entry = hashSlots.getUnchecked(i); entry != nullptr; entry = entry->nextEntry) - if (entry->value == valueToLookFor) - return true; - - return false; - } - - //============================================================================== - /** Adds or replaces an element in the hash-map. - If there's already an item with the given key, this will replace its value. Otherwise, a new item - will be added to the map. - */ - void set (KeyTypeParameter newKey, ValueTypeParameter newValue) - { - const ScopedLockType sl (getLock()); - const int hashIndex = generateHashFor (newKey); - - HashEntry* const firstEntry = hashSlots.getUnchecked (hashIndex); - - for (HashEntry* entry = firstEntry; entry != nullptr; entry = entry->nextEntry) - { - if (entry->key == newKey) - { - entry->value = newValue; - return; - } - } - - hashSlots.set (hashIndex, new HashEntry (newKey, newValue, firstEntry)); - ++totalNumItems; - - if (totalNumItems > (getNumSlots() * 3) / 2) - remapTable (getNumSlots() * 2); - } - - /** Removes an item with the given key. */ - void remove (KeyTypeParameter keyToRemove) - { - const ScopedLockType sl (getLock()); - const int hashIndex = generateHashFor (keyToRemove); - HashEntry* entry = hashSlots.getUnchecked (hashIndex); - HashEntry* previous = nullptr; - - while (entry != nullptr) - { - if (entry->key == keyToRemove) - { - const ScopedPointer deleter (entry); - - entry = entry->nextEntry; - - if (previous != nullptr) - previous->nextEntry = entry; - else - hashSlots.set (hashIndex, entry); - - --totalNumItems; - } - else - { - previous = entry; - entry = entry->nextEntry; - } - } - } - - /** Removes all items with the given value. */ - void removeValue (ValueTypeParameter valueToRemove) - { - const ScopedLockType sl (getLock()); - - for (int i = getNumSlots(); --i >= 0;) - { - HashEntry* entry = hashSlots.getUnchecked(i); - HashEntry* previous = nullptr; - - while (entry != nullptr) - { - if (entry->value == valueToRemove) - { - const ScopedPointer deleter (entry); - - entry = entry->nextEntry; - - if (previous != nullptr) - previous->nextEntry = entry; - else - hashSlots.set (i, entry); - - --totalNumItems; - } - else - { - previous = entry; - entry = entry->nextEntry; - } - } - } - } - - /** Remaps the hash-map to use a different number of slots for its hash function. - Each slot corresponds to a single hash-code, and each one can contain multiple items. - @see getNumSlots() - */ - void remapTable (int newNumberOfSlots) - { - HashMap newTable (newNumberOfSlots); - - for (int i = getNumSlots(); --i >= 0;) - for (const HashEntry* entry = hashSlots.getUnchecked(i); entry != nullptr; entry = entry->nextEntry) - newTable.set (entry->key, entry->value); - - swapWith (newTable); - } - - /** Returns the number of slots which are available for hashing. - Each slot corresponds to a single hash-code, and each one can contain multiple items. - @see getNumSlots() - */ - inline int getNumSlots() const noexcept - { - return hashSlots.size(); - } - - //============================================================================== - /** Efficiently swaps the contents of two hash-maps. */ - template - void swapWith (OtherHashMapType& otherHashMap) noexcept - { - const ScopedLockType lock1 (getLock()); - const typename OtherHashMapType::ScopedLockType lock2 (otherHashMap.getLock()); - - hashSlots.swapWith (otherHashMap.hashSlots); - std::swap (totalNumItems, otherHashMap.totalNumItems); - } - - //============================================================================== - /** Returns the CriticalSection that locks this structure. - To lock, you can call getLock().enter() and getLock().exit(), or preferably use - an object of ScopedLockType as an RAII lock for it. - */ - inline const TypeOfCriticalSectionToUse& getLock() const noexcept { return lock; } - - /** Returns the type of scoped lock to use for locking this array */ - typedef typename TypeOfCriticalSectionToUse::ScopedLockType ScopedLockType; - -private: - //============================================================================== - class HashEntry - { - public: - HashEntry (KeyTypeParameter k, ValueTypeParameter val, HashEntry* const next) - : key (k), value (val), nextEntry (next) - {} - - const KeyType key; - ValueType value; - HashEntry* nextEntry; - - JUCE_DECLARE_NON_COPYABLE (HashEntry) - }; - -public: - //============================================================================== - /** Iterates over the items in a HashMap. - - To use it, repeatedly call next() until it returns false, e.g. - @code - HashMap myMap; - - HashMap::Iterator i (myMap); - - while (i.next()) - { - DBG (i.getKey() << " -> " << i.getValue()); - } - @endcode - - The order in which items are iterated bears no resemblence to the order in which - they were originally added! - - Obviously as soon as you call any non-const methods on the original hash-map, any - iterators that were created beforehand will cease to be valid, and should not be used. - - @see HashMap - */ - class Iterator - { - public: - //============================================================================== - Iterator (const HashMap& hashMapToIterate) - : hashMap (hashMapToIterate), entry (nullptr), index (0) - {} - - /** Moves to the next item, if one is available. - When this returns true, you can get the item's key and value using getKey() and - getValue(). If it returns false, the iteration has finished and you should stop. - */ - bool next() - { - if (entry != nullptr) - entry = entry->nextEntry; - - while (entry == nullptr) - { - if (index >= hashMap.getNumSlots()) - return false; - - entry = hashMap.hashSlots.getUnchecked (index++); - } - - return true; - } - - /** Returns the current item's key. - This should only be called when a call to next() has just returned true. - */ - KeyType getKey() const - { - return entry != nullptr ? entry->key : KeyType(); - } - - /** Returns the current item's value. - This should only be called when a call to next() has just returned true. - */ - ValueType getValue() const - { - return entry != nullptr ? entry->value : ValueType(); - } - - private: - //============================================================================== - const HashMap& hashMap; - HashEntry* entry; - int index; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Iterator) - }; - -private: - //============================================================================== - enum { defaultHashTableSize = 101 }; - friend class Iterator; - - HashFunctionType hashFunctionToUse; - Array hashSlots; - int totalNumItems; - TypeOfCriticalSectionToUse lock; - - int generateHashFor (KeyTypeParameter key) const - { - const int hash = hashFunctionToUse.generateHash (key, getNumSlots()); - jassert (isPositiveAndBelow (hash, getNumSlots())); // your hash function is generating out-of-range numbers! - return hash; - } - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (HashMap) -}; - - -#endif // JUCE_HASHMAP_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/containers/juce_LinkedListPointer.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/containers/juce_LinkedListPointer.h deleted file mode 100644 index a27e521834..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/containers/juce_LinkedListPointer.h +++ /dev/null @@ -1,371 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_LINKEDLISTPOINTER_H_INCLUDED -#define JUCE_LINKEDLISTPOINTER_H_INCLUDED - - -//============================================================================== -/** - Helps to manipulate singly-linked lists of objects. - - For objects that are designed to contain a pointer to the subsequent item in the - list, this class contains methods to deal with the list. To use it, the ObjectType - class that it points to must contain a LinkedListPointer called nextListItem, e.g. - - @code - struct MyObject - { - int x, y, z; - - // A linkable object must contain a member with this name and type, which must be - // accessible by the LinkedListPointer class. (This doesn't mean it has to be public - - // you could make your class a friend of a LinkedListPointer instead). - LinkedListPointer nextListItem; - }; - - LinkedListPointer myList; - myList.append (new MyObject()); - myList.append (new MyObject()); - - int numItems = myList.size(); // returns 2 - MyObject* lastInList = myList.getLast(); - @endcode -*/ -template -class LinkedListPointer -{ -public: - //============================================================================== - /** Creates a null pointer to an empty list. */ - LinkedListPointer() noexcept - : item (nullptr) - { - } - - /** Creates a pointer to a list whose head is the item provided. */ - explicit LinkedListPointer (ObjectType* const headItem) noexcept - : item (headItem) - { - } - - /** Sets this pointer to point to a new list. */ - LinkedListPointer& operator= (ObjectType* const newItem) noexcept - { - item = newItem; - return *this; - } - - #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS - LinkedListPointer (LinkedListPointer&& other) noexcept - : item (other.item) - { - other.item = nullptr; - } - - LinkedListPointer& operator= (LinkedListPointer&& other) noexcept - { - jassert (this != &other); // hopefully the compiler should make this situation impossible! - - item = other.item; - other.item = nullptr; - return *this; - } - #endif - - //============================================================================== - /** Returns the item which this pointer points to. */ - inline operator ObjectType*() const noexcept - { - return item; - } - - /** Returns the item which this pointer points to. */ - inline ObjectType* get() const noexcept - { - return item; - } - - /** Returns the last item in the list which this pointer points to. - This will iterate the list and return the last item found. Obviously the speed - of this operation will be proportional to the size of the list. If the list is - empty the return value will be this object. - If you're planning on appending a number of items to your list, it's much more - efficient to use the Appender class than to repeatedly call getLast() to find the end. - */ - LinkedListPointer& getLast() noexcept - { - LinkedListPointer* l = this; - - while (l->item != nullptr) - l = &(l->item->nextListItem); - - return *l; - } - - /** Returns the number of items in the list. - Obviously with a simple linked list, getting the size involves iterating the list, so - this can be a lengthy operation - be careful when using this method in your code. - */ - int size() const noexcept - { - int total = 0; - - for (ObjectType* i = item; i != nullptr; i = i->nextListItem) - ++total; - - return total; - } - - /** Returns the item at a given index in the list. - Since the only way to find an item is to iterate the list, this operation can obviously - be slow, depending on its size, so you should be careful when using this in algorithms. - */ - LinkedListPointer& operator[] (int index) noexcept - { - LinkedListPointer* l = this; - - while (--index >= 0 && l->item != nullptr) - l = &(l->item->nextListItem); - - return *l; - } - - /** Returns the item at a given index in the list. - Since the only way to find an item is to iterate the list, this operation can obviously - be slow, depending on its size, so you should be careful when using this in algorithms. - */ - const LinkedListPointer& operator[] (int index) const noexcept - { - const LinkedListPointer* l = this; - - while (--index >= 0 && l->item != nullptr) - l = &(l->item->nextListItem); - - return *l; - } - - /** Returns true if the list contains the given item. */ - bool contains (const ObjectType* const itemToLookFor) const noexcept - { - for (ObjectType* i = item; i != nullptr; i = i->nextListItem) - if (itemToLookFor == i) - return true; - - return false; - } - - //============================================================================== - /** Inserts an item into the list, placing it before the item that this pointer - currently points to. - */ - void insertNext (ObjectType* const newItem) - { - jassert (newItem != nullptr); - jassert (newItem->nextListItem == nullptr); - newItem->nextListItem = item; - item = newItem; - } - - /** Inserts an item at a numeric index in the list. - Obviously this will involve iterating the list to find the item at the given index, - so be careful about the impact this may have on execution time. - */ - void insertAtIndex (int index, ObjectType* newItem) - { - jassert (newItem != nullptr); - LinkedListPointer* l = this; - - while (index != 0 && l->item != nullptr) - { - l = &(l->item->nextListItem); - --index; - } - - l->insertNext (newItem); - } - - /** Replaces the object that this pointer points to, appending the rest of the list to - the new object, and returning the old one. - */ - ObjectType* replaceNext (ObjectType* const newItem) noexcept - { - jassert (newItem != nullptr); - jassert (newItem->nextListItem == nullptr); - - ObjectType* const oldItem = item; - item = newItem; - item->nextListItem = oldItem->nextListItem.item; - oldItem->nextListItem.item = nullptr; - return oldItem; - } - - /** Adds an item to the end of the list. - - This operation involves iterating the whole list, so can be slow - if you need to - append a number of items to your list, it's much more efficient to use the Appender - class than to repeatedly call append(). - */ - void append (ObjectType* const newItem) - { - getLast().item = newItem; - } - - /** Creates copies of all the items in another list and adds them to this one. - This will use the ObjectType's copy constructor to try to create copies of each - item in the other list, and appends them to this list. - */ - void addCopyOfList (const LinkedListPointer& other) - { - LinkedListPointer* insertPoint = this; - - for (ObjectType* i = other.item; i != nullptr; i = i->nextListItem) - { - insertPoint->insertNext (new ObjectType (*i)); - insertPoint = &(insertPoint->item->nextListItem); - } - } - - /** Removes the head item from the list. - This won't delete the object that is removed, but returns it, so the caller can - delete it if necessary. - */ - ObjectType* removeNext() noexcept - { - ObjectType* const oldItem = item; - - if (oldItem != nullptr) - { - item = oldItem->nextListItem; - oldItem->nextListItem.item = nullptr; - } - - return oldItem; - } - - /** Removes a specific item from the list. - Note that this will not delete the item, it simply unlinks it from the list. - */ - void remove (ObjectType* const itemToRemove) - { - if (LinkedListPointer* const l = findPointerTo (itemToRemove)) - l->removeNext(); - } - - /** Iterates the list, calling the delete operator on all of its elements and - leaving this pointer empty. - */ - void deleteAll() - { - while (item != nullptr) - { - ObjectType* const oldItem = item; - item = oldItem->nextListItem; - delete oldItem; - } - } - - /** Finds a pointer to a given item. - If the item is found in the list, this returns the pointer that points to it. If - the item isn't found, this returns null. - */ - LinkedListPointer* findPointerTo (ObjectType* const itemToLookFor) noexcept - { - LinkedListPointer* l = this; - - while (l->item != nullptr) - { - if (l->item == itemToLookFor) - return l; - - l = &(l->item->nextListItem); - } - - return nullptr; - } - - /** Copies the items in the list to an array. - The destArray must contain enough elements to hold the entire list - no checks are - made for this! - */ - void copyToArray (ObjectType** destArray) const noexcept - { - jassert (destArray != nullptr); - - for (ObjectType* i = item; i != nullptr; i = i->nextListItem) - *destArray++ = i; - } - - /** Swaps this pointer with another one */ - void swapWith (LinkedListPointer& other) noexcept - { - std::swap (item, other.item); - } - - //============================================================================== - /** - Allows efficient repeated insertions into a list. - - You can create an Appender object which points to the last element in your - list, and then repeatedly call Appender::append() to add items to the end - of the list in O(1) time. - */ - class Appender - { - public: - /** Creates an appender which will add items to the given list. - */ - Appender (LinkedListPointer& endOfListPointer) noexcept - : endOfList (&endOfListPointer) - { - // This can only be used to add to the end of a list. - jassert (endOfListPointer.item == nullptr); - } - - /** Appends an item to the list. */ - void append (ObjectType* const newItem) noexcept - { - *endOfList = newItem; - endOfList = &(newItem->nextListItem); - } - - private: - LinkedListPointer* endOfList; - - JUCE_DECLARE_NON_COPYABLE (Appender) - }; - -private: - //============================================================================== - ObjectType* item; - - JUCE_DECLARE_NON_COPYABLE (LinkedListPointer) -}; - - -#endif // JUCE_LINKEDLISTPOINTER_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/containers/juce_NamedValueSet.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/containers/juce_NamedValueSet.cpp deleted file mode 100644 index 504ab784f4..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/containers/juce_NamedValueSet.cpp +++ /dev/null @@ -1,270 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -struct NamedValueSet::NamedValue -{ - NamedValue() noexcept {} - NamedValue (Identifier n, const var& v) : name (n), value (v) {} - NamedValue (const NamedValue& other) : name (other.name), value (other.value) {} - - #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS - NamedValue (NamedValue&& other) noexcept - : name (static_cast (other.name)), - value (static_cast (other.value)) - { - } - - NamedValue (Identifier n, var&& v) : name (n), value (static_cast (v)) - { - } - - NamedValue& operator= (NamedValue&& other) noexcept - { - name = static_cast (other.name); - value = static_cast (other.value); - return *this; - } - #endif - - bool operator== (const NamedValue& other) const noexcept { return name == other.name && value == other.value; } - bool operator!= (const NamedValue& other) const noexcept { return ! operator== (other); } - - Identifier name; - var value; -}; - -//============================================================================== -NamedValueSet::NamedValueSet() noexcept -{ -} - -NamedValueSet::NamedValueSet (const NamedValueSet& other) - : values (other.values) -{ -} - -NamedValueSet& NamedValueSet::operator= (const NamedValueSet& other) -{ - clear(); - values = other.values; - return *this; -} - -#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS -NamedValueSet::NamedValueSet (NamedValueSet&& other) noexcept - : values (static_cast &&> (other.values)) -{ -} - -NamedValueSet& NamedValueSet::operator= (NamedValueSet&& other) noexcept -{ - other.values.swapWith (values); - return *this; -} -#endif - -NamedValueSet::~NamedValueSet() noexcept -{ -} - -void NamedValueSet::clear() -{ - values.clear(); -} - -bool NamedValueSet::operator== (const NamedValueSet& other) const -{ - return values == other.values; -} - -bool NamedValueSet::operator!= (const NamedValueSet& other) const -{ - return ! operator== (other); -} - -int NamedValueSet::size() const noexcept -{ - return values.size(); -} - -const var& NamedValueSet::operator[] (const Identifier& name) const noexcept -{ - if (const var* v = getVarPointer (name)) - return *v; - - return var::null; -} - -var NamedValueSet::getWithDefault (const Identifier& name, const var& defaultReturnValue) const -{ - if (const var* const v = getVarPointer (name)) - return *v; - - return defaultReturnValue; -} - -var* NamedValueSet::getVarPointer (const Identifier& name) const noexcept -{ - for (NamedValue* e = values.end(), *i = values.begin(); i != e; ++i) - if (i->name == name) - return &(i->value); - - return nullptr; -} - -#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS -bool NamedValueSet::set (Identifier name, var&& newValue) -{ - if (var* const v = getVarPointer (name)) - { - if (v->equalsWithSameType (newValue)) - return false; - - *v = static_cast (newValue); - return true; - } - - values.add (NamedValue (name, static_cast (newValue))); - return true; -} -#endif - -bool NamedValueSet::set (Identifier name, const var& newValue) -{ - if (var* const v = getVarPointer (name)) - { - if (v->equalsWithSameType (newValue)) - return false; - - *v = newValue; - return true; - } - - values.add (NamedValue (name, newValue)); - return true; -} - -bool NamedValueSet::contains (const Identifier& name) const noexcept -{ - return getVarPointer (name) != nullptr; -} - -int NamedValueSet::indexOf (const Identifier& name) const noexcept -{ - const int numValues = values.size(); - - for (int i = 0; i < numValues; ++i) - if (values.getReference(i).name == name) - return i; - - return -1; -} - -bool NamedValueSet::remove (const Identifier& name) -{ - const int numValues = values.size(); - - for (int i = 0; i < numValues; ++i) - { - if (values.getReference(i).name == name) - { - values.remove (i); - return true; - } - } - - return false; -} - -Identifier NamedValueSet::getName (const int index) const noexcept -{ - if (isPositiveAndBelow (index, values.size())) - return values.getReference (index).name; - - jassertfalse; - return Identifier(); -} - -const var& NamedValueSet::getValueAt (const int index) const noexcept -{ - if (isPositiveAndBelow (index, values.size())) - return values.getReference (index).value; - - jassertfalse; - return var::null; -} - -var* NamedValueSet::getVarPointerAt (int index) const noexcept -{ - if (isPositiveAndBelow (index, values.size())) - return &(values.getReference (index).value); - - return nullptr; -} - -void NamedValueSet::setFromXmlAttributes (const XmlElement& xml) -{ - values.clearQuick(); - - for (const XmlElement::XmlAttributeNode* att = xml.attributes; att != nullptr; att = att->nextListItem) - { - if (att->name.toString().startsWith ("base64:")) - { - MemoryBlock mb; - - if (mb.fromBase64Encoding (att->value)) - { - values.add (NamedValue (att->name.toString().substring (7), var (mb))); - continue; - } - } - - values.add (NamedValue (att->name, var (att->value))); - } -} - -void NamedValueSet::copyToXmlAttributes (XmlElement& xml) const -{ - for (NamedValue* e = values.end(), *i = values.begin(); i != e; ++i) - { - if (const MemoryBlock* mb = i->value.getBinaryData()) - { - xml.setAttribute ("base64:" + i->name.toString(), mb->toBase64Encoding()); - } - else - { - // These types can't be stored as XML! - jassert (! i->value.isObject()); - jassert (! i->value.isMethod()); - jassert (! i->value.isArray()); - - xml.setAttribute (i->name.toString(), - i->value.toString()); - } - } -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/containers/juce_NamedValueSet.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/containers/juce_NamedValueSet.h deleted file mode 100644 index e4a98edc67..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/containers/juce_NamedValueSet.h +++ /dev/null @@ -1,145 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_NAMEDVALUESET_H_INCLUDED -#define JUCE_NAMEDVALUESET_H_INCLUDED - - -//============================================================================== -/** Holds a set of named var objects. - - This can be used as a basic structure to hold a set of var object, which can - be retrieved by using their identifier. -*/ -class JUCE_API NamedValueSet -{ -public: - /** Creates an empty set. */ - NamedValueSet() noexcept; - - /** Creates a copy of another set. */ - NamedValueSet (const NamedValueSet&); - - /** Replaces this set with a copy of another set. */ - NamedValueSet& operator= (const NamedValueSet&); - - #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS - NamedValueSet (NamedValueSet&&) noexcept; - NamedValueSet& operator= (NamedValueSet&&) noexcept; - #endif - - /** Destructor. */ - ~NamedValueSet() noexcept; - - bool operator== (const NamedValueSet&) const; - bool operator!= (const NamedValueSet&) const; - - //============================================================================== - /** Returns the total number of values that the set contains. */ - int size() const noexcept; - - /** Returns the value of a named item. - If the name isn't found, this will return a void variant. - @see getProperty - */ - const var& operator[] (const Identifier& name) const noexcept; - - /** Tries to return the named value, but if no such value is found, this will - instead return the supplied default value. - */ - var getWithDefault (const Identifier& name, const var& defaultReturnValue) const; - - /** Changes or adds a named value. - @returns true if a value was changed or added; false if the - value was already set the value passed-in. - */ - bool set (Identifier name, const var& newValue); - - #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS - /** Changes or adds a named value. - @returns true if a value was changed or added; false if the - value was already set the value passed-in. - */ - bool set (Identifier name, var&& newValue); - #endif - - /** Returns true if the set contains an item with the specified name. */ - bool contains (const Identifier& name) const noexcept; - - /** Removes a value from the set. - @returns true if a value was removed; false if there was no value - with the name that was given. - */ - bool remove (const Identifier& name); - - /** Returns the name of the value at a given index. - The index must be between 0 and size() - 1. - */ - Identifier getName (int index) const noexcept; - - /** Returns a pointer to the var that holds a named value, or null if there is - no value with this name. - - Do not use this method unless you really need access to the internal var object - for some reason - for normal reading and writing always prefer operator[]() and set(). - */ - var* getVarPointer (const Identifier& name) const noexcept; - - /** Returns the value of the item at a given index. - The index must be between 0 and size() - 1. - */ - const var& getValueAt (int index) const noexcept; - - /** Returns the value of the item at a given index. - The index must be between 0 and size() - 1, or this will return a nullptr - */ - var* getVarPointerAt (int index) const noexcept; - - /** Returns the index of the given name, or -1 if it's not found. */ - int indexOf (const Identifier& name) const noexcept; - - /** Removes all values. */ - void clear(); - - //============================================================================== - /** Sets properties to the values of all of an XML element's attributes. */ - void setFromXmlAttributes (const XmlElement& xml); - - /** Sets attributes in an XML element corresponding to each of this object's - properties. - */ - void copyToXmlAttributes (XmlElement& xml) const; - -private: - //============================================================================== - struct NamedValue; - Array values; -}; - - -#endif // JUCE_NAMEDVALUESET_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/containers/juce_OwnedArray.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/containers/juce_OwnedArray.h deleted file mode 100644 index be7448c8dd..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/containers/juce_OwnedArray.h +++ /dev/null @@ -1,897 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_OWNEDARRAY_H_INCLUDED -#define JUCE_OWNEDARRAY_H_INCLUDED - - -//============================================================================== -/** An array designed for holding objects. - - This holds a list of pointers to objects, and will automatically - delete the objects when they are removed from the array, or when the - array is itself deleted. - - Declare it in the form: OwnedArray - - ..and then add new objects, e.g. myOwnedArray.add (new MyObjectClass()); - - After adding objects, they are 'owned' by the array and will be deleted when - removed or replaced. - - To make all the array's methods thread-safe, pass in "CriticalSection" as the templated - TypeOfCriticalSectionToUse parameter, instead of the default DummyCriticalSection. - - @see Array, ReferenceCountedArray, StringArray, CriticalSection -*/ -template - -class OwnedArray -{ -public: - //============================================================================== - /** Creates an empty array. */ - OwnedArray() noexcept - : numUsed (0) - { - } - - /** Deletes the array and also deletes any objects inside it. - - To get rid of the array without deleting its objects, use its - clear (false) method before deleting it. - */ - ~OwnedArray() - { - deleteAllObjects(); - } - - #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS - OwnedArray (OwnedArray&& other) noexcept - : data (static_cast &&> (other.data)), - numUsed (other.numUsed) - { - other.numUsed = 0; - } - - OwnedArray& operator= (OwnedArray&& other) noexcept - { - const ScopedLockType lock (getLock()); - deleteAllObjects(); - - data = static_cast &&> (other.data); - numUsed = other.numUsed; - other.numUsed = 0; - return *this; - } - #endif - - //============================================================================== - /** Clears the array, optionally deleting the objects inside it first. */ - void clear (bool deleteObjects = true) - { - const ScopedLockType lock (getLock()); - - if (deleteObjects) - deleteAllObjects(); - - data.setAllocatedSize (0); - numUsed = 0; - } - - //============================================================================== - /** Clears the array, optionally deleting the objects inside it first. */ - void clearQuick (bool deleteObjects) - { - const ScopedLockType lock (getLock()); - - if (deleteObjects) - deleteAllObjects(); - - numUsed = 0; - } - - //============================================================================== - /** Returns the number of items currently in the array. - @see operator[] - */ - inline int size() const noexcept - { - return numUsed; - } - - /** Returns a pointer to the object at this index in the array. - - If the index is out-of-range, this will return a null pointer, (and - it could be null anyway, because it's ok for the array to hold null - pointers as well as objects). - - @see getUnchecked - */ - inline ObjectClass* operator[] (const int index) const noexcept - { - const ScopedLockType lock (getLock()); - if (isPositiveAndBelow (index, numUsed)) - { - jassert (data.elements != nullptr); - return data.elements [index]; - } - - return nullptr; - } - - /** Returns a pointer to the object at this index in the array, without checking whether the index is in-range. - - This is a faster and less safe version of operator[] which doesn't check the index passed in, so - it can be used when you're sure the index is always going to be legal. - */ - inline ObjectClass* getUnchecked (const int index) const noexcept - { - const ScopedLockType lock (getLock()); - jassert (isPositiveAndBelow (index, numUsed) && data.elements != nullptr); - return data.elements [index]; - } - - /** Returns a pointer to the first object in the array. - - This will return a null pointer if the array's empty. - @see getLast - */ - inline ObjectClass* getFirst() const noexcept - { - const ScopedLockType lock (getLock()); - - if (numUsed > 0) - { - jassert (data.elements != nullptr); - return data.elements [0]; - } - - return nullptr; - } - - /** Returns a pointer to the last object in the array. - - This will return a null pointer if the array's empty. - @see getFirst - */ - inline ObjectClass* getLast() const noexcept - { - const ScopedLockType lock (getLock()); - - if (numUsed > 0) - { - jassert (data.elements != nullptr); - return data.elements [numUsed - 1]; - } - - return nullptr; - } - - /** Returns a pointer to the actual array data. - This pointer will only be valid until the next time a non-const method - is called on the array. - */ - inline ObjectClass** getRawDataPointer() noexcept - { - return data.elements; - } - - //============================================================================== - /** Returns a pointer to the first element in the array. - This method is provided for compatibility with standard C++ iteration mechanisms. - */ - inline ObjectClass** begin() const noexcept - { - return data.elements; - } - - /** Returns a pointer to the element which follows the last element in the array. - This method is provided for compatibility with standard C++ iteration mechanisms. - */ - inline ObjectClass** end() const noexcept - { - #if JUCE_DEBUG - if (data.elements == nullptr || numUsed <= 0) // (to keep static analysers happy) - return data.elements; - #endif - - return data.elements + numUsed; - } - - //============================================================================== - /** Finds the index of an object which might be in the array. - - @param objectToLookFor the object to look for - @returns the index at which the object was found, or -1 if it's not found - */ - int indexOf (const ObjectClass* objectToLookFor) const noexcept - { - const ScopedLockType lock (getLock()); - ObjectClass* const* e = data.elements.getData(); - ObjectClass* const* const end_ = e + numUsed; - - for (; e != end_; ++e) - if (objectToLookFor == *e) - return static_cast (e - data.elements.getData()); - - return -1; - } - - /** Returns true if the array contains a specified object. - - @param objectToLookFor the object to look for - @returns true if the object is in the array - */ - bool contains (const ObjectClass* objectToLookFor) const noexcept - { - const ScopedLockType lock (getLock()); - ObjectClass* const* e = data.elements.getData(); - ObjectClass* const* const end_ = e + numUsed; - - for (; e != end_; ++e) - if (objectToLookFor == *e) - return true; - - return false; - } - - //============================================================================== - /** Appends a new object to the end of the array. - - Note that the this object will be deleted by the OwnedArray when it - is removed, so be careful not to delete it somewhere else. - - Also be careful not to add the same object to the array more than once, - as this will obviously cause deletion of dangling pointers. - - @param newObject the new object to add to the array - @returns the new object that was added - @see set, insert, addIfNotAlreadyThere, addSorted - */ - ObjectClass* add (ObjectClass* newObject) noexcept - { - const ScopedLockType lock (getLock()); - data.ensureAllocatedSize (numUsed + 1); - jassert (data.elements != nullptr); - data.elements [numUsed++] = newObject; - return newObject; - } - - /** Inserts a new object into the array at the given index. - - Note that the this object will be deleted by the OwnedArray when it - is removed, so be careful not to delete it somewhere else. - - If the index is less than 0 or greater than the size of the array, the - element will be added to the end of the array. - Otherwise, it will be inserted into the array, moving all the later elements - along to make room. - - Be careful not to add the same object to the array more than once, - as this will obviously cause deletion of dangling pointers. - - @param indexToInsertAt the index at which the new element should be inserted - @param newObject the new object to add to the array - @returns the new object that was added - @see add, addSorted, addIfNotAlreadyThere, set - */ - ObjectClass* insert (int indexToInsertAt, ObjectClass* newObject) noexcept - { - if (indexToInsertAt < 0) - return add (newObject); - - const ScopedLockType lock (getLock()); - - if (indexToInsertAt > numUsed) - indexToInsertAt = numUsed; - - data.ensureAllocatedSize (numUsed + 1); - jassert (data.elements != nullptr); - - ObjectClass** const e = data.elements + indexToInsertAt; - const int numToMove = numUsed - indexToInsertAt; - - if (numToMove > 0) - memmove (e + 1, e, sizeof (ObjectClass*) * (size_t) numToMove); - - *e = newObject; - ++numUsed; - return newObject; - } - - /** Inserts an array of values into this array at a given position. - - If the index is less than 0 or greater than the size of the array, the - new elements will be added to the end of the array. - Otherwise, they will be inserted into the array, moving all the later elements - along to make room. - - @param indexToInsertAt the index at which the first new element should be inserted - @param newObjects the new values to add to the array - @param numberOfElements how many items are in the array - @see insert, add, addSorted, set - */ - void insertArray (int indexToInsertAt, - ObjectClass* const* newObjects, - int numberOfElements) - { - if (numberOfElements > 0) - { - const ScopedLockType lock (getLock()); - data.ensureAllocatedSize (numUsed + numberOfElements); - ObjectClass** insertPos = data.elements; - - if (isPositiveAndBelow (indexToInsertAt, numUsed)) - { - insertPos += indexToInsertAt; - const size_t numberToMove = (size_t) (numUsed - indexToInsertAt); - memmove (insertPos + numberOfElements, insertPos, numberToMove * sizeof (ObjectClass*)); - } - else - { - insertPos += numUsed; - } - - numUsed += numberOfElements; - - while (--numberOfElements >= 0) - *insertPos++ = *newObjects++; - } - } - - /** Appends a new object at the end of the array as long as the array doesn't - already contain it. - - If the array already contains a matching object, nothing will be done. - - @param newObject the new object to add to the array - @returns the new object that was added - */ - ObjectClass* addIfNotAlreadyThere (ObjectClass* newObject) noexcept - { - const ScopedLockType lock (getLock()); - - if (! contains (newObject)) - add (newObject); - - return newObject; - } - - /** Replaces an object in the array with a different one. - - If the index is less than zero, this method does nothing. - If the index is beyond the end of the array, the new object is added to the end of the array. - - Be careful not to add the same object to the array more than once, - as this will obviously cause deletion of dangling pointers. - - @param indexToChange the index whose value you want to change - @param newObject the new value to set for this index. - @param deleteOldElement whether to delete the object that's being replaced with the new one - @see add, insert, remove - */ - ObjectClass* set (int indexToChange, ObjectClass* newObject, bool deleteOldElement = true) - { - if (indexToChange >= 0) - { - ScopedPointer toDelete; - - { - const ScopedLockType lock (getLock()); - - if (indexToChange < numUsed) - { - if (deleteOldElement) - { - toDelete = data.elements [indexToChange]; - - if (toDelete == newObject) - toDelete.release(); - } - - data.elements [indexToChange] = newObject; - } - else - { - data.ensureAllocatedSize (numUsed + 1); - data.elements [numUsed++] = newObject; - } - } - } - else - { - jassertfalse; // you're trying to set an object at a negative index, which doesn't have - // any effect - but since the object is not being added, it may be leaking.. - } - - return newObject; - } - - /** Adds elements from another array to the end of this array. - - @param arrayToAddFrom the array from which to copy the elements - @param startIndex the first element of the other array to start copying from - @param numElementsToAdd how many elements to add from the other array. If this - value is negative or greater than the number of available elements, - all available elements will be copied. - @see add - */ - template - void addArray (const OtherArrayType& arrayToAddFrom, - int startIndex = 0, - int numElementsToAdd = -1) - { - const typename OtherArrayType::ScopedLockType lock1 (arrayToAddFrom.getLock()); - const ScopedLockType lock2 (getLock()); - - if (startIndex < 0) - { - jassertfalse; - startIndex = 0; - } - - if (numElementsToAdd < 0 || startIndex + numElementsToAdd > arrayToAddFrom.size()) - numElementsToAdd = arrayToAddFrom.size() - startIndex; - - data.ensureAllocatedSize (numUsed + numElementsToAdd); - jassert (numElementsToAdd <= 0 || data.elements != nullptr); - - while (--numElementsToAdd >= 0) - { - data.elements [numUsed] = arrayToAddFrom.getUnchecked (startIndex++); - ++numUsed; - } - } - - /** Adds copies of the elements in another array to the end of this array. - - The other array must be either an OwnedArray of a compatible type of object, or an Array - containing pointers to the same kind of object. The objects involved must provide - a copy constructor, and this will be used to create new copies of each element, and - add them to this array. - - @param arrayToAddFrom the array from which to copy the elements - @param startIndex the first element of the other array to start copying from - @param numElementsToAdd how many elements to add from the other array. If this - value is negative or greater than the number of available elements, - all available elements will be copied. - @see add - */ - template - void addCopiesOf (const OtherArrayType& arrayToAddFrom, - int startIndex = 0, - int numElementsToAdd = -1) - { - const typename OtherArrayType::ScopedLockType lock1 (arrayToAddFrom.getLock()); - const ScopedLockType lock2 (getLock()); - - if (startIndex < 0) - { - jassertfalse; - startIndex = 0; - } - - if (numElementsToAdd < 0 || startIndex + numElementsToAdd > arrayToAddFrom.size()) - numElementsToAdd = arrayToAddFrom.size() - startIndex; - - data.ensureAllocatedSize (numUsed + numElementsToAdd); - jassert (numElementsToAdd <= 0 || data.elements != nullptr); - - while (--numElementsToAdd >= 0) - data.elements [numUsed++] = createCopyIfNotNull (arrayToAddFrom.getUnchecked (startIndex++)); - } - - /** Inserts a new object into the array assuming that the array is sorted. - - This will use a comparator to find the position at which the new object - should go. If the array isn't sorted, the behaviour of this - method will be unpredictable. - - @param comparator the comparator to use to compare the elements - see the sort method - for details about this object's structure - @param newObject the new object to insert to the array - @returns the index at which the new object was added - @see add, sort, indexOfSorted - */ - template - int addSorted (ElementComparator& comparator, ObjectClass* const newObject) noexcept - { - (void) comparator; // if you pass in an object with a static compareElements() method, this - // avoids getting warning messages about the parameter being unused - const ScopedLockType lock (getLock()); - const int index = findInsertIndexInSortedArray (comparator, data.elements.getData(), newObject, 0, numUsed); - insert (index, newObject); - return index; - } - - /** Finds the index of an object in the array, assuming that the array is sorted. - - This will use a comparator to do a binary-chop to find the index of the given - element, if it exists. If the array isn't sorted, the behaviour of this - method will be unpredictable. - - @param comparator the comparator to use to compare the elements - see the sort() - method for details about the form this object should take - @param objectToLookFor the object to search for - @returns the index of the element, or -1 if it's not found - @see addSorted, sort - */ - template - int indexOfSorted (ElementComparator& comparator, const ObjectClass* const objectToLookFor) const noexcept - { - (void) comparator; - const ScopedLockType lock (getLock()); - int s = 0, e = numUsed; - - while (s < e) - { - if (comparator.compareElements (objectToLookFor, data.elements [s]) == 0) - return s; - - const int halfway = (s + e) / 2; - if (halfway == s) - break; - - if (comparator.compareElements (objectToLookFor, data.elements [halfway]) >= 0) - s = halfway; - else - e = halfway; - } - - return -1; - } - - //============================================================================== - /** Removes an object from the array. - - This will remove the object at a given index (optionally also - deleting it) and move back all the subsequent objects to close the gap. - If the index passed in is out-of-range, nothing will happen. - - @param indexToRemove the index of the element to remove - @param deleteObject whether to delete the object that is removed - @see removeObject, removeRange - */ - void remove (int indexToRemove, bool deleteObject = true) - { - ScopedPointer toDelete; - - { - const ScopedLockType lock (getLock()); - - if (isPositiveAndBelow (indexToRemove, numUsed)) - { - ObjectClass** const e = data.elements + indexToRemove; - - if (deleteObject) - toDelete = *e; - - --numUsed; - const int numToShift = numUsed - indexToRemove; - - if (numToShift > 0) - memmove (e, e + 1, sizeof (ObjectClass*) * (size_t) numToShift); - } - } - - if ((numUsed << 1) < data.numAllocated) - minimiseStorageOverheads(); - } - - /** Removes and returns an object from the array without deleting it. - - This will remove the object at a given index and return it, moving back all - the subsequent objects to close the gap. If the index passed in is out-of-range, - nothing will happen. - - @param indexToRemove the index of the element to remove - @see remove, removeObject, removeRange - */ - ObjectClass* removeAndReturn (int indexToRemove) - { - ObjectClass* removedItem = nullptr; - const ScopedLockType lock (getLock()); - - if (isPositiveAndBelow (indexToRemove, numUsed)) - { - ObjectClass** const e = data.elements + indexToRemove; - removedItem = *e; - - --numUsed; - const int numToShift = numUsed - indexToRemove; - - if (numToShift > 0) - memmove (e, e + 1, sizeof (ObjectClass*) * (size_t) numToShift); - - if ((numUsed << 1) < data.numAllocated) - minimiseStorageOverheads(); - } - - return removedItem; - } - - /** Removes a specified object from the array. - - If the item isn't found, no action is taken. - - @param objectToRemove the object to try to remove - @param deleteObject whether to delete the object (if it's found) - @see remove, removeRange - */ - void removeObject (const ObjectClass* objectToRemove, bool deleteObject = true) - { - const ScopedLockType lock (getLock()); - ObjectClass** const e = data.elements.getData(); - - for (int i = 0; i < numUsed; ++i) - { - if (objectToRemove == e[i]) - { - remove (i, deleteObject); - break; - } - } - } - - /** Removes a range of objects from the array. - - This will remove a set of objects, starting from the given index, - and move any subsequent elements down to close the gap. - - If the range extends beyond the bounds of the array, it will - be safely clipped to the size of the array. - - @param startIndex the index of the first object to remove - @param numberToRemove how many objects should be removed - @param deleteObjects whether to delete the objects that get removed - @see remove, removeObject - */ - void removeRange (int startIndex, int numberToRemove, bool deleteObjects = true) - { - const ScopedLockType lock (getLock()); - const int endIndex = jlimit (0, numUsed, startIndex + numberToRemove); - startIndex = jlimit (0, numUsed, startIndex); - - if (endIndex > startIndex) - { - if (deleteObjects) - { - for (int i = startIndex; i < endIndex; ++i) - { - ContainerDeletePolicy::destroy (data.elements [i]); - data.elements [i] = nullptr; // (in case one of the destructors accesses this array and hits a dangling pointer) - } - } - - const int rangeSize = endIndex - startIndex; - ObjectClass** e = data.elements + startIndex; - int numToShift = numUsed - endIndex; - numUsed -= rangeSize; - - while (--numToShift >= 0) - { - *e = e [rangeSize]; - ++e; - } - - if ((numUsed << 1) < data.numAllocated) - minimiseStorageOverheads(); - } - } - - /** Removes the last n objects from the array. - - @param howManyToRemove how many objects to remove from the end of the array - @param deleteObjects whether to also delete the objects that are removed - @see remove, removeObject, removeRange - */ - void removeLast (int howManyToRemove = 1, - bool deleteObjects = true) - { - const ScopedLockType lock (getLock()); - - if (howManyToRemove >= numUsed) - clear (deleteObjects); - else - removeRange (numUsed - howManyToRemove, howManyToRemove, deleteObjects); - } - - /** Swaps a pair of objects in the array. - - If either of the indexes passed in is out-of-range, nothing will happen, - otherwise the two objects at these positions will be exchanged. - */ - void swap (int index1, - int index2) noexcept - { - const ScopedLockType lock (getLock()); - - if (isPositiveAndBelow (index1, numUsed) - && isPositiveAndBelow (index2, numUsed)) - { - std::swap (data.elements [index1], - data.elements [index2]); - } - } - - /** Moves one of the objects to a different position. - - This will move the object to a specified index, shuffling along - any intervening elements as required. - - So for example, if you have the array { 0, 1, 2, 3, 4, 5 } then calling - move (2, 4) would result in { 0, 1, 3, 4, 2, 5 }. - - @param currentIndex the index of the object to be moved. If this isn't a - valid index, then nothing will be done - @param newIndex the index at which you'd like this object to end up. If this - is less than zero, it will be moved to the end of the array - */ - void move (int currentIndex, int newIndex) noexcept - { - if (currentIndex != newIndex) - { - const ScopedLockType lock (getLock()); - - if (isPositiveAndBelow (currentIndex, numUsed)) - { - if (! isPositiveAndBelow (newIndex, numUsed)) - newIndex = numUsed - 1; - - ObjectClass* const value = data.elements [currentIndex]; - - if (newIndex > currentIndex) - { - memmove (data.elements + currentIndex, - data.elements + currentIndex + 1, - sizeof (ObjectClass*) * (size_t) (newIndex - currentIndex)); - } - else - { - memmove (data.elements + newIndex + 1, - data.elements + newIndex, - sizeof (ObjectClass*) * (size_t) (currentIndex - newIndex)); - } - - data.elements [newIndex] = value; - } - } - } - - /** This swaps the contents of this array with those of another array. - - If you need to exchange two arrays, this is vastly quicker than using copy-by-value - because it just swaps their internal pointers. - */ - template - void swapWith (OtherArrayType& otherArray) noexcept - { - const ScopedLockType lock1 (getLock()); - const typename OtherArrayType::ScopedLockType lock2 (otherArray.getLock()); - data.swapWith (otherArray.data); - std::swap (numUsed, otherArray.numUsed); - } - - //============================================================================== - /** Reduces the amount of storage being used by the array. - - Arrays typically allocate slightly more storage than they need, and after - removing elements, they may have quite a lot of unused space allocated. - This method will reduce the amount of allocated storage to a minimum. - */ - void minimiseStorageOverheads() noexcept - { - const ScopedLockType lock (getLock()); - data.shrinkToNoMoreThan (numUsed); - } - - /** Increases the array's internal storage to hold a minimum number of elements. - - Calling this before adding a large known number of elements means that - the array won't have to keep dynamically resizing itself as the elements - are added, and it'll therefore be more efficient. - */ - void ensureStorageAllocated (const int minNumElements) noexcept - { - const ScopedLockType lock (getLock()); - data.ensureAllocatedSize (minNumElements); - } - - //============================================================================== - /** Sorts the elements in the array. - - This will use a comparator object to sort the elements into order. The object - passed must have a method of the form: - @code - int compareElements (ElementType* first, ElementType* second); - @endcode - - ..and this method must return: - - a value of < 0 if the first comes before the second - - a value of 0 if the two objects are equivalent - - a value of > 0 if the second comes before the first - - To improve performance, the compareElements() method can be declared as static or const. - - @param comparator the comparator to use for comparing elements. - @param retainOrderOfEquivalentItems if this is true, then items - which the comparator says are equivalent will be - kept in the order in which they currently appear - in the array. This is slower to perform, but may - be important in some cases. If it's false, a faster - algorithm is used, but equivalent elements may be - rearranged. - @see sortArray, indexOfSorted - */ - template - void sort (ElementComparator& comparator, - bool retainOrderOfEquivalentItems = false) const noexcept - { - (void) comparator; // if you pass in an object with a static compareElements() method, this - // avoids getting warning messages about the parameter being unused - - const ScopedLockType lock (getLock()); - sortArray (comparator, data.elements.getData(), 0, size() - 1, retainOrderOfEquivalentItems); - } - - //============================================================================== - /** Returns the CriticalSection that locks this array. - To lock, you can call getLock().enter() and getLock().exit(), or preferably use - an object of ScopedLockType as an RAII lock for it. - */ - inline const TypeOfCriticalSectionToUse& getLock() const noexcept { return data; } - - /** Returns the type of scoped lock to use for locking this array */ - typedef typename TypeOfCriticalSectionToUse::ScopedLockType ScopedLockType; - - - //============================================================================== - #ifndef DOXYGEN - // Note that the swapWithArray method has been replaced by a more flexible templated version, - // and renamed "swapWith" to be more consistent with the names used in other classes. - JUCE_DEPRECATED_WITH_BODY (void swapWithArray (OwnedArray& other) noexcept, { swapWith (other); }) - #endif - -private: - //============================================================================== - ArrayAllocationBase data; - int numUsed; - - void deleteAllObjects() - { - while (numUsed > 0) - ContainerDeletePolicy::destroy (data.elements [--numUsed]); - } - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (OwnedArray) -}; - - -#endif // JUCE_OWNEDARRAY_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/containers/juce_PropertySet.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/containers/juce_PropertySet.cpp deleted file mode 100644 index 6b02bafb4e..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/containers/juce_PropertySet.cpp +++ /dev/null @@ -1,219 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -PropertySet::PropertySet (const bool ignoreCaseOfKeyNames) - : properties (ignoreCaseOfKeyNames), - fallbackProperties (nullptr), - ignoreCaseOfKeys (ignoreCaseOfKeyNames) -{ -} - -PropertySet::PropertySet (const PropertySet& other) - : properties (other.properties), - fallbackProperties (other.fallbackProperties), - ignoreCaseOfKeys (other.ignoreCaseOfKeys) -{ -} - -PropertySet& PropertySet::operator= (const PropertySet& other) -{ - properties = other.properties; - fallbackProperties = other.fallbackProperties; - ignoreCaseOfKeys = other.ignoreCaseOfKeys; - - propertyChanged(); - return *this; -} - -PropertySet::~PropertySet() -{ -} - -void PropertySet::clear() -{ - const ScopedLock sl (lock); - - if (properties.size() > 0) - { - properties.clear(); - propertyChanged(); - } -} - -String PropertySet::getValue (StringRef keyName, const String& defaultValue) const noexcept -{ - const ScopedLock sl (lock); - - const int index = properties.getAllKeys().indexOf (keyName, ignoreCaseOfKeys); - - if (index >= 0) - return properties.getAllValues() [index]; - - return fallbackProperties != nullptr ? fallbackProperties->getValue (keyName, defaultValue) - : defaultValue; -} - -int PropertySet::getIntValue (StringRef keyName, const int defaultValue) const noexcept -{ - const ScopedLock sl (lock); - const int index = properties.getAllKeys().indexOf (keyName, ignoreCaseOfKeys); - - if (index >= 0) - return properties.getAllValues() [index].getIntValue(); - - return fallbackProperties != nullptr ? fallbackProperties->getIntValue (keyName, defaultValue) - : defaultValue; -} - -double PropertySet::getDoubleValue (StringRef keyName, const double defaultValue) const noexcept -{ - const ScopedLock sl (lock); - const int index = properties.getAllKeys().indexOf (keyName, ignoreCaseOfKeys); - - if (index >= 0) - return properties.getAllValues()[index].getDoubleValue(); - - return fallbackProperties != nullptr ? fallbackProperties->getDoubleValue (keyName, defaultValue) - : defaultValue; -} - -bool PropertySet::getBoolValue (StringRef keyName, const bool defaultValue) const noexcept -{ - const ScopedLock sl (lock); - const int index = properties.getAllKeys().indexOf (keyName, ignoreCaseOfKeys); - - if (index >= 0) - return properties.getAllValues() [index].getIntValue() != 0; - - return fallbackProperties != nullptr ? fallbackProperties->getBoolValue (keyName, defaultValue) - : defaultValue; -} - -XmlElement* PropertySet::getXmlValue (StringRef keyName) const -{ - return XmlDocument::parse (getValue (keyName)); -} - -void PropertySet::setValue (const String& keyName, const var& v) -{ - jassert (keyName.isNotEmpty()); // shouldn't use an empty key name! - - if (keyName.isNotEmpty()) - { - const String value (v.toString()); - const ScopedLock sl (lock); - - const int index = properties.getAllKeys().indexOf (keyName, ignoreCaseOfKeys); - - if (index < 0 || properties.getAllValues() [index] != value) - { - properties.set (keyName, value); - propertyChanged(); - } - } -} - -void PropertySet::removeValue (StringRef keyName) -{ - if (keyName.isNotEmpty()) - { - const ScopedLock sl (lock); - const int index = properties.getAllKeys().indexOf (keyName, ignoreCaseOfKeys); - - if (index >= 0) - { - properties.remove (keyName); - propertyChanged(); - } - } -} - -void PropertySet::setValue (const String& keyName, const XmlElement* const xml) -{ - setValue (keyName, xml == nullptr ? var() - : var (xml->createDocument ("", true))); -} - -bool PropertySet::containsKey (StringRef keyName) const noexcept -{ - const ScopedLock sl (lock); - return properties.getAllKeys().contains (keyName, ignoreCaseOfKeys); -} - -void PropertySet::addAllPropertiesFrom (const PropertySet& source) -{ - const ScopedLock sl (source.getLock()); - - for (int i = 0; i < source.properties.size(); ++i) - setValue (source.properties.getAllKeys() [i], - source.properties.getAllValues() [i]); -} - -void PropertySet::setFallbackPropertySet (PropertySet* fallbackProperties_) noexcept -{ - const ScopedLock sl (lock); - fallbackProperties = fallbackProperties_; -} - -XmlElement* PropertySet::createXml (const String& nodeName) const -{ - const ScopedLock sl (lock); - XmlElement* const xml = new XmlElement (nodeName); - - for (int i = 0; i < properties.getAllKeys().size(); ++i) - { - XmlElement* const e = xml->createNewChildElement ("VALUE"); - e->setAttribute ("name", properties.getAllKeys()[i]); - e->setAttribute ("val", properties.getAllValues()[i]); - } - - return xml; -} - -void PropertySet::restoreFromXml (const XmlElement& xml) -{ - const ScopedLock sl (lock); - clear(); - - forEachXmlChildElementWithTagName (xml, e, "VALUE") - { - if (e->hasAttribute ("name") - && e->hasAttribute ("val")) - { - properties.set (e->getStringAttribute ("name"), - e->getStringAttribute ("val")); - } - } - - if (properties.size() > 0) - propertyChanged(); -} - -void PropertySet::propertyChanged() -{ -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/containers/juce_PropertySet.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/containers/juce_PropertySet.h deleted file mode 100644 index 2a4ecb1216..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/containers/juce_PropertySet.h +++ /dev/null @@ -1,211 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_PROPERTYSET_H_INCLUDED -#define JUCE_PROPERTYSET_H_INCLUDED - - -//============================================================================== -/** - A set of named property values, which can be strings, integers, floating point, etc. - - Effectively, this just wraps a StringPairArray in an interface that makes it easier - to load and save types other than strings. - - See the PropertiesFile class for a subclass of this, which automatically broadcasts change - messages and saves/loads the list from a file. -*/ -class JUCE_API PropertySet -{ -public: - //============================================================================== - /** Creates an empty PropertySet. - @param ignoreCaseOfKeyNames if true, the names of properties are compared in a - case-insensitive way - */ - PropertySet (bool ignoreCaseOfKeyNames = false); - - /** Creates a copy of another PropertySet. */ - PropertySet (const PropertySet& other); - - /** Copies another PropertySet over this one. */ - PropertySet& operator= (const PropertySet& other); - - /** Destructor. */ - virtual ~PropertySet(); - - //============================================================================== - /** Returns one of the properties as a string. - - If the value isn't found in this set, then this will look for it in a fallback - property set (if you've specified one with the setFallbackPropertySet() method), - and if it can't find one there, it'll return the default value passed-in. - - @param keyName the name of the property to retrieve - @param defaultReturnValue a value to return if the named property doesn't actually exist - */ - String getValue (StringRef keyName, const String& defaultReturnValue = String()) const noexcept; - - /** Returns one of the properties as an integer. - - If the value isn't found in this set, then this will look for it in a fallback - property set (if you've specified one with the setFallbackPropertySet() method), - and if it can't find one there, it'll return the default value passed-in. - - @param keyName the name of the property to retrieve - @param defaultReturnValue a value to return if the named property doesn't actually exist - */ - int getIntValue (StringRef keyName, int defaultReturnValue = 0) const noexcept; - - /** Returns one of the properties as an double. - - If the value isn't found in this set, then this will look for it in a fallback - property set (if you've specified one with the setFallbackPropertySet() method), - and if it can't find one there, it'll return the default value passed-in. - - @param keyName the name of the property to retrieve - @param defaultReturnValue a value to return if the named property doesn't actually exist - */ - double getDoubleValue (StringRef keyName, double defaultReturnValue = 0.0) const noexcept; - - /** Returns one of the properties as an boolean. - - The result will be true if the string found for this key name can be parsed as a non-zero - integer. - - If the value isn't found in this set, then this will look for it in a fallback - property set (if you've specified one with the setFallbackPropertySet() method), - and if it can't find one there, it'll return the default value passed-in. - - @param keyName the name of the property to retrieve - @param defaultReturnValue a value to return if the named property doesn't actually exist - */ - bool getBoolValue (StringRef keyName, bool defaultReturnValue = false) const noexcept; - - /** Returns one of the properties as an XML element. - - The result will a new XMLElement object that the caller must delete. If may return nullptr - if the key isn't found, or if the entry contains an string that isn't valid XML. - - If the value isn't found in this set, then this will look for it in a fallback - property set (if you've specified one with the setFallbackPropertySet() method), - and if it can't find one there, it'll return the default value passed-in. - - @param keyName the name of the property to retrieve - */ - XmlElement* getXmlValue (StringRef keyName) const; - - //============================================================================== - /** Sets a named property. - - @param keyName the name of the property to set. (This mustn't be an empty string) - @param value the new value to set it to - */ - void setValue (const String& keyName, const var& value); - - /** Sets a named property to an XML element. - - @param keyName the name of the property to set. (This mustn't be an empty string) - @param xml the new element to set it to. If this is zero, the value will be set to - an empty string - @see getXmlValue - */ - void setValue (const String& keyName, const XmlElement* xml); - - /** This copies all the values from a source PropertySet to this one. - This won't remove any existing settings, it just adds any that it finds in the source set. - */ - void addAllPropertiesFrom (const PropertySet& source); - - //============================================================================== - /** Deletes a property. - @param keyName the name of the property to delete. (This mustn't be an empty string) - */ - void removeValue (StringRef keyName); - - /** Returns true if the properies include the given key. */ - bool containsKey (StringRef keyName) const noexcept; - - /** Removes all values. */ - void clear(); - - //============================================================================== - /** Returns the keys/value pair array containing all the properties. */ - StringPairArray& getAllProperties() noexcept { return properties; } - - /** Returns the lock used when reading or writing to this set */ - const CriticalSection& getLock() const noexcept { return lock; } - - //============================================================================== - /** Returns an XML element which encapsulates all the items in this property set. - The string parameter is the tag name that should be used for the node. - @see restoreFromXml - */ - XmlElement* createXml (const String& nodeName) const; - - /** Reloads a set of properties that were previously stored as XML. - The node passed in must have been created by the createXml() method. - @see createXml - */ - void restoreFromXml (const XmlElement& xml); - - //============================================================================== - /** Sets up a second PopertySet that will be used to look up any values that aren't - set in this one. - - If you set this up to be a pointer to a second property set, then whenever one - of the getValue() methods fails to find an entry in this set, it will look up that - value in the fallback set, and if it finds it, it will return that. - - Make sure that you don't delete the fallback set while it's still being used by - another set! To remove the fallback set, just call this method with a null pointer. - - @see getFallbackPropertySet - */ - void setFallbackPropertySet (PropertySet* fallbackProperties) noexcept; - - /** Returns the fallback property set. - @see setFallbackPropertySet - */ - PropertySet* getFallbackPropertySet() const noexcept { return fallbackProperties; } - -protected: - /** Subclasses can override this to be told when one of the properies has been changed. */ - virtual void propertyChanged(); - -private: - StringPairArray properties; - PropertySet* fallbackProperties; - CriticalSection lock; - bool ignoreCaseOfKeys; - - JUCE_LEAK_DETECTOR (PropertySet) -}; - - -#endif // JUCE_PROPERTYSET_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/containers/juce_ReferenceCountedArray.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/containers/juce_ReferenceCountedArray.h deleted file mode 100644 index 6b02c3e3e2..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/containers/juce_ReferenceCountedArray.h +++ /dev/null @@ -1,897 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_REFERENCECOUNTEDARRAY_H_INCLUDED -#define JUCE_REFERENCECOUNTEDARRAY_H_INCLUDED - - -//============================================================================== -/** - Holds a list of objects derived from ReferenceCountedObject, or which implement basic - reference-count handling methods. - - The template parameter specifies the class of the object you want to point to - the easiest - way to make a class reference-countable is to simply make it inherit from ReferenceCountedObject - or SingleThreadedReferenceCountedObject, but if you need to, you can roll your own reference-countable - class by implementing a set of methods called incReferenceCount(), decReferenceCount(), and - decReferenceCountWithoutDeleting(). See ReferenceCountedObject for examples of how these methods - should behave. - - A ReferenceCountedArray holds objects derived from ReferenceCountedObject, - and takes care of incrementing and decrementing their ref counts when they - are added and removed from the array. - - To make all the array's methods thread-safe, pass in "CriticalSection" as the templated - TypeOfCriticalSectionToUse parameter, instead of the default DummyCriticalSection. - - @see Array, OwnedArray, StringArray -*/ -template -class ReferenceCountedArray -{ -public: - typedef ReferenceCountedObjectPtr ObjectClassPtr; - - //============================================================================== - /** Creates an empty array. - @see ReferenceCountedObject, Array, OwnedArray - */ - ReferenceCountedArray() noexcept - : numUsed (0) - { - } - - /** Creates a copy of another array */ - ReferenceCountedArray (const ReferenceCountedArray& other) noexcept - { - const ScopedLockType lock (other.getLock()); - numUsed = other.size(); - data.setAllocatedSize (numUsed); - memcpy (data.elements, other.getRawDataPointer(), (size_t) numUsed * sizeof (ObjectClass*)); - - for (int i = numUsed; --i >= 0;) - if (ObjectClass* o = data.elements[i]) - o->incReferenceCount(); - } - - /** Creates a copy of another array */ - template - ReferenceCountedArray (const ReferenceCountedArray& other) noexcept - { - const typename ReferenceCountedArray::ScopedLockType lock (other.getLock()); - numUsed = other.size(); - data.setAllocatedSize (numUsed); - memcpy (data.elements, other.getRawDataPointer(), numUsed * sizeof (ObjectClass*)); - - for (int i = numUsed; --i >= 0;) - if (ObjectClass* o = data.elements[i]) - o->incReferenceCount(); - } - - /** Copies another array into this one. - Any existing objects in this array will first be released. - */ - ReferenceCountedArray& operator= (const ReferenceCountedArray& other) noexcept - { - ReferenceCountedArray otherCopy (other); - swapWith (otherCopy); - return *this; - } - - /** Copies another array into this one. - Any existing objects in this array will first be released. - */ - template - ReferenceCountedArray& operator= (const ReferenceCountedArray& other) noexcept - { - ReferenceCountedArray otherCopy (other); - swapWith (otherCopy); - return *this; - } - - /** Destructor. - Any objects in the array will be released, and may be deleted if not referenced from elsewhere. - */ - ~ReferenceCountedArray() - { - clear(); - } - - //============================================================================== - /** Removes all objects from the array. - - Any objects in the array that are not referenced from elsewhere will be deleted. - */ - void clear() - { - const ScopedLockType lock (getLock()); - - while (numUsed > 0) - if (ObjectClass* o = data.elements [--numUsed]) - releaseObject (o); - - jassert (numUsed == 0); - data.setAllocatedSize (0); - } - - /** Returns the current number of objects in the array. */ - inline int size() const noexcept - { - return numUsed; - } - - /** Returns a pointer to the object at this index in the array. - - If the index is out-of-range, this will return a null pointer, (and - it could be null anyway, because it's ok for the array to hold null - pointers as well as objects). - - @see getUnchecked - */ - inline ObjectClassPtr operator[] (const int index) const noexcept - { - return getObjectPointer (index); - } - - /** Returns a pointer to the object at this index in the array, without checking - whether the index is in-range. - - This is a faster and less safe version of operator[] which doesn't check the index passed in, so - it can be used when you're sure the index is always going to be legal. - */ - inline ObjectClassPtr getUnchecked (const int index) const noexcept - { - return getObjectPointerUnchecked (index); - } - - /** Returns a raw pointer to the object at this index in the array. - - If the index is out-of-range, this will return a null pointer, (and - it could be null anyway, because it's ok for the array to hold null - pointers as well as objects). - - @see getUnchecked - */ - inline ObjectClass* getObjectPointer (const int index) const noexcept - { - const ScopedLockType lock (getLock()); - - if (isPositiveAndBelow (index, numUsed)) - { - jassert (data.elements != nullptr); - return data.elements [index]; - } - - return ObjectClassPtr(); - } - - /** Returns a raw pointer to the object at this index in the array, without checking - whether the index is in-range. - */ - inline ObjectClass* getObjectPointerUnchecked (const int index) const noexcept - { - const ScopedLockType lock (getLock()); - jassert (isPositiveAndBelow (index, numUsed) && data.elements != nullptr); - return data.elements [index]; - } - - /** Returns a pointer to the first object in the array. - - This will return a null pointer if the array's empty. - @see getLast - */ - inline ObjectClassPtr getFirst() const noexcept - { - const ScopedLockType lock (getLock()); - - if (numUsed > 0) - { - jassert (data.elements != nullptr); - return data.elements [0]; - } - - return ObjectClassPtr(); - } - - /** Returns a pointer to the last object in the array. - - This will return a null pointer if the array's empty. - @see getFirst - */ - inline ObjectClassPtr getLast() const noexcept - { - const ScopedLockType lock (getLock()); - - if (numUsed > 0) - { - jassert (data.elements != nullptr); - return data.elements [numUsed - 1]; - } - - return ObjectClassPtr(); - } - - /** Returns a pointer to the actual array data. - This pointer will only be valid until the next time a non-const method - is called on the array. - */ - inline ObjectClass** getRawDataPointer() const noexcept - { - return data.elements; - } - - //============================================================================== - /** Returns a pointer to the first element in the array. - This method is provided for compatibility with standard C++ iteration mechanisms. - */ - inline ObjectClass** begin() const noexcept - { - return data.elements; - } - - /** Returns a pointer to the element which follows the last element in the array. - This method is provided for compatibility with standard C++ iteration mechanisms. - */ - inline ObjectClass** end() const noexcept - { - return data.elements + numUsed; - } - - //============================================================================== - /** Finds the index of the first occurrence of an object in the array. - - @param objectToLookFor the object to look for - @returns the index at which the object was found, or -1 if it's not found - */ - int indexOf (const ObjectClass* const objectToLookFor) const noexcept - { - const ScopedLockType lock (getLock()); - ObjectClass** e = data.elements.getData(); - ObjectClass** const endPointer = e + numUsed; - - while (e != endPointer) - { - if (objectToLookFor == *e) - return static_cast (e - data.elements.getData()); - - ++e; - } - - return -1; - } - - /** Returns true if the array contains a specified object. - - @param objectToLookFor the object to look for - @returns true if the object is in the array - */ - bool contains (const ObjectClass* const objectToLookFor) const noexcept - { - const ScopedLockType lock (getLock()); - ObjectClass** e = data.elements.getData(); - ObjectClass** const endPointer = e + numUsed; - - while (e != endPointer) - { - if (objectToLookFor == *e) - return true; - - ++e; - } - - return false; - } - - /** Appends a new object to the end of the array. - - This will increase the new object's reference count. - - @param newObject the new object to add to the array - @see set, insert, addIfNotAlreadyThere, addSorted, addArray - */ - ObjectClass* add (ObjectClass* const newObject) noexcept - { - const ScopedLockType lock (getLock()); - data.ensureAllocatedSize (numUsed + 1); - jassert (data.elements != nullptr); - data.elements [numUsed++] = newObject; - - if (newObject != nullptr) - newObject->incReferenceCount(); - - return newObject; - } - - /** Inserts a new object into the array at the given index. - - If the index is less than 0 or greater than the size of the array, the - element will be added to the end of the array. - Otherwise, it will be inserted into the array, moving all the later elements - along to make room. - - This will increase the new object's reference count. - - @param indexToInsertAt the index at which the new element should be inserted - @param newObject the new object to add to the array - @see add, addSorted, addIfNotAlreadyThere, set - */ - ObjectClass* insert (int indexToInsertAt, - ObjectClass* const newObject) noexcept - { - if (indexToInsertAt < 0) - return add (newObject); - - const ScopedLockType lock (getLock()); - - if (indexToInsertAt > numUsed) - indexToInsertAt = numUsed; - - data.ensureAllocatedSize (numUsed + 1); - jassert (data.elements != nullptr); - - ObjectClass** const e = data.elements + indexToInsertAt; - const int numToMove = numUsed - indexToInsertAt; - - if (numToMove > 0) - memmove (e + 1, e, sizeof (ObjectClass*) * (size_t) numToMove); - - *e = newObject; - - if (newObject != nullptr) - newObject->incReferenceCount(); - - ++numUsed; - - return newObject; - } - - /** Appends a new object at the end of the array as long as the array doesn't - already contain it. - - If the array already contains a matching object, nothing will be done. - - @param newObject the new object to add to the array - */ - void addIfNotAlreadyThere (ObjectClass* const newObject) noexcept - { - const ScopedLockType lock (getLock()); - if (! contains (newObject)) - add (newObject); - } - - /** Replaces an object in the array with a different one. - - If the index is less than zero, this method does nothing. - If the index is beyond the end of the array, the new object is added to the end of the array. - - The object being added has its reference count increased, and if it's replacing - another object, then that one has its reference count decreased, and may be deleted. - - @param indexToChange the index whose value you want to change - @param newObject the new value to set for this index. - @see add, insert, remove - */ - void set (const int indexToChange, - ObjectClass* const newObject) - { - if (indexToChange >= 0) - { - const ScopedLockType lock (getLock()); - - if (newObject != nullptr) - newObject->incReferenceCount(); - - if (indexToChange < numUsed) - { - if (ObjectClass* o = data.elements [indexToChange]) - releaseObject (o); - - data.elements [indexToChange] = newObject; - } - else - { - data.ensureAllocatedSize (numUsed + 1); - jassert (data.elements != nullptr); - data.elements [numUsed++] = newObject; - } - } - } - - /** Adds elements from another array to the end of this array. - - @param arrayToAddFrom the array from which to copy the elements - @param startIndex the first element of the other array to start copying from - @param numElementsToAdd how many elements to add from the other array. If this - value is negative or greater than the number of available elements, - all available elements will be copied. - @see add - */ - void addArray (const ReferenceCountedArray& arrayToAddFrom, - int startIndex = 0, - int numElementsToAdd = -1) noexcept - { - const ScopedLockType lock1 (arrayToAddFrom.getLock()); - - { - const ScopedLockType lock2 (getLock()); - - if (startIndex < 0) - { - jassertfalse; - startIndex = 0; - } - - if (numElementsToAdd < 0 || startIndex + numElementsToAdd > arrayToAddFrom.size()) - numElementsToAdd = arrayToAddFrom.size() - startIndex; - - if (numElementsToAdd > 0) - { - data.ensureAllocatedSize (numUsed + numElementsToAdd); - - while (--numElementsToAdd >= 0) - add (arrayToAddFrom.getUnchecked (startIndex++)); - } - } - } - - /** Inserts a new object into the array assuming that the array is sorted. - - This will use a comparator to find the position at which the new object - should go. If the array isn't sorted, the behaviour of this - method will be unpredictable. - - @param comparator the comparator object to use to compare the elements - see the - sort() method for details about this object's form - @param newObject the new object to insert to the array - @returns the index at which the new object was added - @see add, sort - */ - template - int addSorted (ElementComparator& comparator, ObjectClass* newObject) noexcept - { - const ScopedLockType lock (getLock()); - const int index = findInsertIndexInSortedArray (comparator, data.elements.getData(), newObject, 0, numUsed); - insert (index, newObject); - return index; - } - - /** Inserts or replaces an object in the array, assuming it is sorted. - - This is similar to addSorted, but if a matching element already exists, then it will be - replaced by the new one, rather than the new one being added as well. - */ - template - void addOrReplaceSorted (ElementComparator& comparator, - ObjectClass* newObject) noexcept - { - const ScopedLockType lock (getLock()); - const int index = findInsertIndexInSortedArray (comparator, data.elements.getData(), newObject, 0, numUsed); - - if (index > 0 && comparator.compareElements (newObject, data.elements [index - 1]) == 0) - set (index - 1, newObject); // replace an existing object that matches - else - insert (index, newObject); // no match, so insert the new one - } - - /** Finds the index of an object in the array, assuming that the array is sorted. - - This will use a comparator to do a binary-chop to find the index of the given - element, if it exists. If the array isn't sorted, the behaviour of this - method will be unpredictable. - - @param comparator the comparator to use to compare the elements - see the sort() - method for details about the form this object should take - @param objectToLookFor the object to search for - @returns the index of the element, or -1 if it's not found - @see addSorted, sort - */ - template - int indexOfSorted (ElementComparator& comparator, - const ObjectClass* const objectToLookFor) const noexcept - { - (void) comparator; - const ScopedLockType lock (getLock()); - int s = 0, e = numUsed; - - while (s < e) - { - if (comparator.compareElements (objectToLookFor, data.elements [s]) == 0) - return s; - - const int halfway = (s + e) / 2; - if (halfway == s) - break; - - if (comparator.compareElements (objectToLookFor, data.elements [halfway]) >= 0) - s = halfway; - else - e = halfway; - } - - return -1; - } - - //============================================================================== - /** Removes an object from the array. - - This will remove the object at a given index and move back all the - subsequent objects to close the gap. - - If the index passed in is out-of-range, nothing will happen. - - The object that is removed will have its reference count decreased, - and may be deleted if not referenced from elsewhere. - - @param indexToRemove the index of the element to remove - @see removeObject, removeRange - */ - void remove (const int indexToRemove) - { - const ScopedLockType lock (getLock()); - - if (isPositiveAndBelow (indexToRemove, numUsed)) - { - ObjectClass** const e = data.elements + indexToRemove; - - if (ObjectClass* o = *e) - releaseObject (o); - - --numUsed; - const int numberToShift = numUsed - indexToRemove; - - if (numberToShift > 0) - memmove (e, e + 1, sizeof (ObjectClass*) * (size_t) numberToShift); - - if ((numUsed << 1) < data.numAllocated) - minimiseStorageOverheads(); - } - } - - /** Removes and returns an object from the array. - - This will remove the object at a given index and return it, moving back all - the subsequent objects to close the gap. If the index passed in is out-of-range, - nothing will happen and a null pointer will be returned. - - @param indexToRemove the index of the element to remove - @see remove, removeObject, removeRange - */ - ObjectClassPtr removeAndReturn (const int indexToRemove) - { - ObjectClassPtr removedItem; - const ScopedLockType lock (getLock()); - - if (isPositiveAndBelow (indexToRemove, numUsed)) - { - ObjectClass** const e = data.elements + indexToRemove; - - if (ObjectClass* o = *e) - { - removedItem = o; - releaseObject (o); - } - - --numUsed; - const int numberToShift = numUsed - indexToRemove; - - if (numberToShift > 0) - memmove (e, e + 1, sizeof (ObjectClass*) * (size_t) numberToShift); - - if ((numUsed << 1) < data.numAllocated) - minimiseStorageOverheads(); - } - - return removedItem; - } - - /** Removes the first occurrence of a specified object from the array. - - If the item isn't found, no action is taken. If it is found, it is - removed and has its reference count decreased. - - @param objectToRemove the object to try to remove - @see remove, removeRange - */ - void removeObject (ObjectClass* const objectToRemove) - { - const ScopedLockType lock (getLock()); - remove (indexOf (objectToRemove)); - } - - /** Removes a range of objects from the array. - - This will remove a set of objects, starting from the given index, - and move any subsequent elements down to close the gap. - - If the range extends beyond the bounds of the array, it will - be safely clipped to the size of the array. - - The objects that are removed will have their reference counts decreased, - and may be deleted if not referenced from elsewhere. - - @param startIndex the index of the first object to remove - @param numberToRemove how many objects should be removed - @see remove, removeObject - */ - void removeRange (const int startIndex, - const int numberToRemove) - { - const ScopedLockType lock (getLock()); - - const int start = jlimit (0, numUsed, startIndex); - const int endIndex = jlimit (0, numUsed, startIndex + numberToRemove); - - if (endIndex > start) - { - int i; - for (i = start; i < endIndex; ++i) - { - if (ObjectClass* o = data.elements[i]) - { - releaseObject (o); - data.elements[i] = nullptr; // (in case one of the destructors accesses this array and hits a dangling pointer) - } - } - - const int rangeSize = endIndex - start; - ObjectClass** e = data.elements + start; - i = numUsed - endIndex; - numUsed -= rangeSize; - - while (--i >= 0) - { - *e = e [rangeSize]; - ++e; - } - - if ((numUsed << 1) < data.numAllocated) - minimiseStorageOverheads(); - } - } - - /** Removes the last n objects from the array. - - The objects that are removed will have their reference counts decreased, - and may be deleted if not referenced from elsewhere. - - @param howManyToRemove how many objects to remove from the end of the array - @see remove, removeObject, removeRange - */ - void removeLast (int howManyToRemove = 1) - { - const ScopedLockType lock (getLock()); - - if (howManyToRemove > numUsed) - howManyToRemove = numUsed; - - while (--howManyToRemove >= 0) - remove (numUsed - 1); - } - - /** Swaps a pair of objects in the array. - - If either of the indexes passed in is out-of-range, nothing will happen, - otherwise the two objects at these positions will be exchanged. - */ - void swap (const int index1, - const int index2) noexcept - { - const ScopedLockType lock (getLock()); - - if (isPositiveAndBelow (index1, numUsed) - && isPositiveAndBelow (index2, numUsed)) - { - std::swap (data.elements [index1], - data.elements [index2]); - } - } - - /** Moves one of the objects to a different position. - - This will move the object to a specified index, shuffling along - any intervening elements as required. - - So for example, if you have the array { 0, 1, 2, 3, 4, 5 } then calling - move (2, 4) would result in { 0, 1, 3, 4, 2, 5 }. - - @param currentIndex the index of the object to be moved. If this isn't a - valid index, then nothing will be done - @param newIndex the index at which you'd like this object to end up. If this - is less than zero, it will be moved to the end of the array - */ - void move (const int currentIndex, - int newIndex) noexcept - { - if (currentIndex != newIndex) - { - const ScopedLockType lock (getLock()); - - if (isPositiveAndBelow (currentIndex, numUsed)) - { - if (! isPositiveAndBelow (newIndex, numUsed)) - newIndex = numUsed - 1; - - ObjectClass* const value = data.elements [currentIndex]; - - if (newIndex > currentIndex) - { - memmove (data.elements + currentIndex, - data.elements + currentIndex + 1, - sizeof (ObjectClass*) * (size_t) (newIndex - currentIndex)); - } - else - { - memmove (data.elements + newIndex + 1, - data.elements + newIndex, - sizeof (ObjectClass*) * (size_t) (currentIndex - newIndex)); - } - - data.elements [newIndex] = value; - } - } - } - - //============================================================================== - /** This swaps the contents of this array with those of another array. - - If you need to exchange two arrays, this is vastly quicker than using copy-by-value - because it just swaps their internal pointers. - */ - template - void swapWith (OtherArrayType& otherArray) noexcept - { - const ScopedLockType lock1 (getLock()); - const typename OtherArrayType::ScopedLockType lock2 (otherArray.getLock()); - data.swapWith (otherArray.data); - std::swap (numUsed, otherArray.numUsed); - } - - //============================================================================== - /** Compares this array to another one. - - @returns true only if the other array contains the same objects in the same order - */ - bool operator== (const ReferenceCountedArray& other) const noexcept - { - const ScopedLockType lock2 (other.getLock()); - const ScopedLockType lock1 (getLock()); - - if (numUsed != other.numUsed) - return false; - - for (int i = numUsed; --i >= 0;) - if (data.elements [i] != other.data.elements [i]) - return false; - - return true; - } - - /** Compares this array to another one. - - @see operator== - */ - bool operator!= (const ReferenceCountedArray& other) const noexcept - { - return ! operator== (other); - } - - //============================================================================== - /** Sorts the elements in the array. - - This will use a comparator object to sort the elements into order. The object - passed must have a method of the form: - @code - int compareElements (ElementType first, ElementType second); - @endcode - - ..and this method must return: - - a value of < 0 if the first comes before the second - - a value of 0 if the two objects are equivalent - - a value of > 0 if the second comes before the first - - To improve performance, the compareElements() method can be declared as static or const. - - @param comparator the comparator to use for comparing elements. - @param retainOrderOfEquivalentItems if this is true, then items - which the comparator says are equivalent will be - kept in the order in which they currently appear - in the array. This is slower to perform, but may - be important in some cases. If it's false, a faster - algorithm is used, but equivalent elements may be - rearranged. - - @see sortArray - */ - template - void sort (ElementComparator& comparator, - const bool retainOrderOfEquivalentItems = false) const noexcept - { - (void) comparator; // if you pass in an object with a static compareElements() method, this - // avoids getting warning messages about the parameter being unused - - const ScopedLockType lock (getLock()); - sortArray (comparator, data.elements.getData(), 0, size() - 1, retainOrderOfEquivalentItems); - } - - //============================================================================== - /** Reduces the amount of storage being used by the array. - - Arrays typically allocate slightly more storage than they need, and after - removing elements, they may have quite a lot of unused space allocated. - This method will reduce the amount of allocated storage to a minimum. - */ - void minimiseStorageOverheads() noexcept - { - const ScopedLockType lock (getLock()); - data.shrinkToNoMoreThan (numUsed); - } - - /** Increases the array's internal storage to hold a minimum number of elements. - - Calling this before adding a large known number of elements means that - the array won't have to keep dynamically resizing itself as the elements - are added, and it'll therefore be more efficient. - */ - void ensureStorageAllocated (const int minNumElements) - { - const ScopedLockType lock (getLock()); - data.ensureAllocatedSize (minNumElements); - } - - //============================================================================== - /** Returns the CriticalSection that locks this array. - To lock, you can call getLock().enter() and getLock().exit(), or preferably use - an object of ScopedLockType as an RAII lock for it. - */ - inline const TypeOfCriticalSectionToUse& getLock() const noexcept { return data; } - - /** Returns the type of scoped lock to use for locking this array */ - typedef typename TypeOfCriticalSectionToUse::ScopedLockType ScopedLockType; - - - //============================================================================== - #ifndef DOXYGEN - // Note that the swapWithArray method has been replaced by a more flexible templated version, - // and renamed "swapWith" to be more consistent with the names used in other classes. - JUCE_DEPRECATED_WITH_BODY (void swapWithArray (ReferenceCountedArray& other) noexcept, { swapWith (other); }) - #endif - -private: - //============================================================================== - ArrayAllocationBase data; - int numUsed; - - static void releaseObject (ObjectClass* o) - { - if (o->decReferenceCountWithoutDeleting()) - ContainerDeletePolicy::destroy (o); - } -}; - - -#endif // JUCE_REFERENCECOUNTEDARRAY_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/containers/juce_ScopedValueSetter.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/containers/juce_ScopedValueSetter.h deleted file mode 100644 index 13b871ef24..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/containers/juce_ScopedValueSetter.h +++ /dev/null @@ -1,100 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_SCOPEDVALUESETTER_H_INCLUDED -#define JUCE_SCOPEDVALUESETTER_H_INCLUDED - - -//============================================================================== -/** - Helper class providing an RAII-based mechanism for temporarily setting and - then re-setting a value. - - E.g. @code - int x = 1; - - { - ScopedValueSetter setter (x, 2); - - // x is now 2 - } - - // x is now 1 again - - { - ScopedValueSetter setter (x, 3, 4); - - // x is now 3 - } - - // x is now 4 - @endcode - -*/ -template -class ScopedValueSetter -{ -public: - /** Creates a ScopedValueSetter that will immediately change the specified value to the - given new value, and will then reset it to its original value when this object is deleted. - */ - ScopedValueSetter (ValueType& valueToSet, - ValueType newValue) - : value (valueToSet), - originalValue (valueToSet) - { - valueToSet = newValue; - } - - /** Creates a ScopedValueSetter that will immediately change the specified value to the - given new value, and will then reset it to be valueWhenDeleted when this object is deleted. - */ - ScopedValueSetter (ValueType& valueToSet, - ValueType newValue, - ValueType valueWhenDeleted) - : value (valueToSet), - originalValue (valueWhenDeleted) - { - valueToSet = newValue; - } - - ~ScopedValueSetter() - { - value = originalValue; - } - -private: - //============================================================================== - ValueType& value; - const ValueType originalValue; - - JUCE_DECLARE_NON_COPYABLE (ScopedValueSetter) -}; - - -#endif // JUCE_SCOPEDVALUESETTER_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/containers/juce_SortedSet.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/containers/juce_SortedSet.h deleted file mode 100644 index 62fd9233dc..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/containers/juce_SortedSet.h +++ /dev/null @@ -1,494 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_SORTEDSET_H_INCLUDED -#define JUCE_SORTEDSET_H_INCLUDED - -#if JUCE_MSVC - #pragma warning (push) - #pragma warning (disable: 4512) -#endif - -//============================================================================== -/** - Holds a set of unique primitive objects, such as ints or doubles. - - A set can only hold one item with a given value, so if for example it's a - set of integers, attempting to add the same integer twice will do nothing - the second time. - - Internally, the list of items is kept sorted (which means that whatever - kind of primitive type is used must support the ==, <, >, <= and >= operators - to determine the order), and searching the set for known values is very fast - because it uses a binary-chop method. - - Note that if you're using a class or struct as the element type, it must be - capable of being copied or moved with a straightforward memcpy, rather than - needing construction and destruction code. - - To make all the set's methods thread-safe, pass in "CriticalSection" as the templated - TypeOfCriticalSectionToUse parameter, instead of the default DummyCriticalSection. - - @see Array, OwnedArray, ReferenceCountedArray, StringArray, CriticalSection -*/ -template -class SortedSet -{ -public: - //============================================================================== - /** Creates an empty set. */ - SortedSet() noexcept - { - } - - /** Creates a copy of another set. - @param other the set to copy - */ - SortedSet (const SortedSet& other) - : data (other.data) - { - } - - /** Destructor. */ - ~SortedSet() noexcept - { - } - - /** Copies another set over this one. - @param other the set to copy - */ - SortedSet& operator= (const SortedSet& other) noexcept - { - data = other.data; - return *this; - } - - //============================================================================== - /** Compares this set to another one. - Two sets are considered equal if they both contain the same set of elements. - @param other the other set to compare with - */ - bool operator== (const SortedSet& other) const noexcept - { - return data == other.data; - } - - /** Compares this set to another one. - Two sets are considered equal if they both contain the same set of elements. - @param other the other set to compare with - */ - bool operator!= (const SortedSet& other) const noexcept - { - return ! operator== (other); - } - - //============================================================================== - /** Removes all elements from the set. - - This will remove all the elements, and free any storage that the set is - using. To clear it without freeing the storage, use the clearQuick() - method instead. - - @see clearQuick - */ - void clear() noexcept - { - data.clear(); - } - - /** Removes all elements from the set without freeing the array's allocated storage. - @see clear - */ - void clearQuick() noexcept - { - data.clearQuick(); - } - - //============================================================================== - /** Returns the current number of elements in the set. */ - inline int size() const noexcept - { - return data.size(); - } - - /** Returns one of the elements in the set. - - If the index passed in is beyond the range of valid elements, this - will return zero. - - If you're certain that the index will always be a valid element, you - can call getUnchecked() instead, which is faster. - - @param index the index of the element being requested (0 is the first element in the set) - @see getUnchecked, getFirst, getLast - */ - inline ElementType operator[] (const int index) const noexcept - { - return data [index]; - } - - /** Returns one of the elements in the set, without checking the index passed in. - Unlike the operator[] method, this will try to return an element without - checking that the index is within the bounds of the set, so should only - be used when you're confident that it will always be a valid index. - - @param index the index of the element being requested (0 is the first element in the set) - @see operator[], getFirst, getLast - */ - inline ElementType getUnchecked (const int index) const noexcept - { - return data.getUnchecked (index); - } - - /** Returns a direct reference to one of the elements in the set, without checking the index passed in. - - This is like getUnchecked, but returns a direct reference to the element, so that - you can alter it directly. Obviously this can be dangerous, so only use it when - absolutely necessary. - - @param index the index of the element being requested (0 is the first element in the array) - */ - inline ElementType& getReference (const int index) const noexcept - { - return data.getReference (index); - } - - /** Returns the first element in the set, or 0 if the set is empty. - @see operator[], getUnchecked, getLast - */ - inline ElementType getFirst() const noexcept - { - return data.getFirst(); - } - - /** Returns the last element in the set, or 0 if the set is empty. - @see operator[], getUnchecked, getFirst - */ - inline ElementType getLast() const noexcept - { - return data.getLast(); - } - - //============================================================================== - /** Returns a pointer to the first element in the set. - This method is provided for compatibility with standard C++ iteration mechanisms. - */ - inline ElementType* begin() const noexcept - { - return data.begin(); - } - - /** Returns a pointer to the element which follows the last element in the set. - This method is provided for compatibility with standard C++ iteration mechanisms. - */ - inline ElementType* end() const noexcept - { - return data.end(); - } - - //============================================================================== - /** Finds the index of the first element which matches the value passed in. - - This will search the set for the given object, and return the index - of its first occurrence. If the object isn't found, the method will return -1. - - @param elementToLookFor the value or object to look for - @returns the index of the object, or -1 if it's not found - */ - int indexOf (const ElementType& elementToLookFor) const noexcept - { - const ScopedLockType lock (data.getLock()); - - int s = 0; - int e = data.size(); - - for (;;) - { - if (s >= e) - return -1; - - if (elementToLookFor == data.getReference (s)) - return s; - - const int halfway = (s + e) / 2; - - if (halfway == s) - return -1; - - if (elementToLookFor < data.getReference (halfway)) - e = halfway; - else - s = halfway; - } - } - - /** Returns true if the set contains at least one occurrence of an object. - - @param elementToLookFor the value or object to look for - @returns true if the item is found - */ - bool contains (const ElementType& elementToLookFor) const noexcept - { - return indexOf (elementToLookFor) >= 0; - } - - //============================================================================== - /** Adds a new element to the set, (as long as it's not already in there). - - Note that if a matching element already exists, the new value will be assigned - to the existing one using operator=, so that if there are any differences between - the objects which were not recognised by the object's operator==, then the - set will always contain a copy of the most recently added one. - - @param newElement the new object to add to the set - @returns true if the value was added, or false if it already existed - @see set, insert, addIfNotAlreadyThere, addSorted, addSet, addArray - */ - bool add (const ElementType& newElement) noexcept - { - const ScopedLockType lock (getLock()); - - int s = 0; - int e = data.size(); - - while (s < e) - { - ElementType& elem = data.getReference (s); - if (newElement == elem) - { - elem = newElement; // force an update in case operator== permits differences. - return false; - } - - const int halfway = (s + e) / 2; - const bool isBeforeHalfway = (newElement < data.getReference (halfway)); - - if (halfway == s) - { - if (! isBeforeHalfway) - ++s; - - break; - } - - if (isBeforeHalfway) - e = halfway; - else - s = halfway; - } - - data.insert (s, newElement); - return true; - } - - /** Adds elements from an array to this set. - - @param elementsToAdd the array of elements to add - @param numElementsToAdd how many elements are in this other array - @see add - */ - void addArray (const ElementType* elementsToAdd, - int numElementsToAdd) noexcept - { - const ScopedLockType lock (getLock()); - - while (--numElementsToAdd >= 0) - add (*elementsToAdd++); - } - - /** Adds elements from another set to this one. - - @param setToAddFrom the set from which to copy the elements - @param startIndex the first element of the other set to start copying from - @param numElementsToAdd how many elements to add from the other set. If this - value is negative or greater than the number of available elements, - all available elements will be copied. - @see add - */ - template - void addSet (const OtherSetType& setToAddFrom, - int startIndex = 0, - int numElementsToAdd = -1) noexcept - { - const typename OtherSetType::ScopedLockType lock1 (setToAddFrom.getLock()); - - { - const ScopedLockType lock2 (getLock()); - jassert (this != &setToAddFrom); - - if (this != &setToAddFrom) - { - if (startIndex < 0) - { - jassertfalse; - startIndex = 0; - } - - if (numElementsToAdd < 0 || startIndex + numElementsToAdd > setToAddFrom.size()) - numElementsToAdd = setToAddFrom.size() - startIndex; - - if (numElementsToAdd > 0) - addArray (&setToAddFrom.data.getReference (startIndex), numElementsToAdd); - } - } - } - - //============================================================================== - /** Removes an element from the set. - - This will remove the element at a given index. - If the index passed in is out-of-range, nothing will happen. - - @param indexToRemove the index of the element to remove - @returns the element that has been removed - @see removeValue, removeRange - */ - ElementType remove (const int indexToRemove) noexcept - { - return data.remove (indexToRemove); - } - - /** Removes an item from the set. - - This will remove the given element from the set, if it's there. - - @param valueToRemove the object to try to remove - @see remove, removeRange - */ - void removeValue (const ElementType valueToRemove) noexcept - { - const ScopedLockType lock (getLock()); - data.remove (indexOf (valueToRemove)); - } - - /** Removes any elements which are also in another set. - - @param otherSet the other set in which to look for elements to remove - @see removeValuesNotIn, remove, removeValue, removeRange - */ - template - void removeValuesIn (const OtherSetType& otherSet) noexcept - { - const typename OtherSetType::ScopedLockType lock1 (otherSet.getLock()); - const ScopedLockType lock2 (getLock()); - - if (this == &otherSet) - { - clear(); - } - else if (otherSet.size() > 0) - { - for (int i = data.size(); --i >= 0;) - if (otherSet.contains (data.getReference (i))) - remove (i); - } - } - - /** Removes any elements which are not found in another set. - - Only elements which occur in this other set will be retained. - - @param otherSet the set in which to look for elements NOT to remove - @see removeValuesIn, remove, removeValue, removeRange - */ - template - void removeValuesNotIn (const OtherSetType& otherSet) noexcept - { - const typename OtherSetType::ScopedLockType lock1 (otherSet.getLock()); - const ScopedLockType lock2 (getLock()); - - if (this != &otherSet) - { - if (otherSet.size() <= 0) - { - clear(); - } - else - { - for (int i = data.size(); --i >= 0;) - if (! otherSet.contains (data.getReference (i))) - remove (i); - } - } - } - - /** This swaps the contents of this array with those of another array. - - If you need to exchange two arrays, this is vastly quicker than using copy-by-value - because it just swaps their internal pointers. - */ - template - void swapWith (OtherSetType& otherSet) noexcept - { - data.swapWith (otherSet.data); - } - - //============================================================================== - /** Reduces the amount of storage being used by the set. - - Sets typically allocate slightly more storage than they need, and after - removing elements, they may have quite a lot of unused space allocated. - This method will reduce the amount of allocated storage to a minimum. - */ - void minimiseStorageOverheads() noexcept - { - data.minimiseStorageOverheads(); - } - - /** Increases the set's internal storage to hold a minimum number of elements. - - Calling this before adding a large known number of elements means that - the set won't have to keep dynamically resizing itself as the elements - are added, and it'll therefore be more efficient. - */ - void ensureStorageAllocated (const int minNumElements) - { - data.ensureStorageAllocated (minNumElements); - } - - //============================================================================== - /** Returns the CriticalSection that locks this array. - To lock, you can call getLock().enter() and getLock().exit(), or preferably use - an object of ScopedLockType as an RAII lock for it. - */ - inline const TypeOfCriticalSectionToUse& getLock() const noexcept { return data.getLock(); } - - /** Returns the type of scoped lock to use for locking this array */ - typedef typename TypeOfCriticalSectionToUse::ScopedLockType ScopedLockType; - - -private: - //============================================================================== - Array data; -}; - -#if JUCE_MSVC - #pragma warning (pop) -#endif - -#endif // JUCE_SORTEDSET_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/containers/juce_SparseSet.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/containers/juce_SparseSet.h deleted file mode 100644 index 86366fce5b..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/containers/juce_SparseSet.h +++ /dev/null @@ -1,298 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_SPARSESET_H_INCLUDED -#define JUCE_SPARSESET_H_INCLUDED - - -//============================================================================== -/** - Holds a set of primitive values, storing them as a set of ranges. - - This container acts like an array, but can efficiently hold large contiguous - ranges of values. It's quite a specialised class, mostly useful for things - like keeping the set of selected rows in a listbox. - - The type used as a template parameter must be an integer type, such as int, short, - int64, etc. -*/ -template -class SparseSet -{ -public: - //============================================================================== - /** Creates a new empty set. */ - SparseSet() - { - } - - /** Creates a copy of another SparseSet. */ - SparseSet (const SparseSet& other) - : values (other.values) - { - } - - //============================================================================== - /** Clears the set. */ - void clear() - { - values.clear(); - } - - /** Checks whether the set is empty. - - This is much quicker than using (size() == 0). - */ - bool isEmpty() const noexcept - { - return values.size() == 0; - } - - /** Returns the number of values in the set. - - Because of the way the data is stored, this method can take longer if there - are a lot of items in the set. Use isEmpty() for a quick test of whether there - are any items. - */ - Type size() const - { - Type total (0); - - for (int i = 0; i < values.size(); i += 2) - total += values.getUnchecked (i + 1) - values.getUnchecked (i); - - return total; - } - - /** Returns one of the values in the set. - - @param index the index of the value to retrieve, in the range 0 to (size() - 1). - @returns the value at this index, or 0 if it's out-of-range - */ - Type operator[] (Type index) const - { - for (int i = 0; i < values.size(); i += 2) - { - const Type start (values.getUnchecked (i)); - const Type len (values.getUnchecked (i + 1) - start); - - if (index < len) - return start + index; - - index -= len; - } - - return Type(); - } - - /** Checks whether a particular value is in the set. */ - bool contains (const Type valueToLookFor) const - { - for (int i = 0; i < values.size(); ++i) - if (valueToLookFor < values.getUnchecked(i)) - return (i & 1) != 0; - - return false; - } - - //============================================================================== - /** Returns the number of contiguous blocks of values. - @see getRange - */ - int getNumRanges() const noexcept - { - return values.size() >> 1; - } - - /** Returns one of the contiguous ranges of values stored. - @param rangeIndex the index of the range to look up, between 0 - and (getNumRanges() - 1) - @see getTotalRange - */ - const Range getRange (const int rangeIndex) const - { - if (isPositiveAndBelow (rangeIndex, getNumRanges())) - return Range (values.getUnchecked (rangeIndex << 1), - values.getUnchecked ((rangeIndex << 1) + 1)); - - return Range(); - } - - /** Returns the range between the lowest and highest values in the set. - @see getRange - */ - Range getTotalRange() const - { - if (values.size() > 0) - { - jassert ((values.size() & 1) == 0); - return Range (values.getUnchecked (0), - values.getUnchecked (values.size() - 1)); - } - - return Range(); - } - - //============================================================================== - /** Adds a range of contiguous values to the set. - e.g. addRange (Range \ (10, 14)) will add (10, 11, 12, 13) to the set. - */ - void addRange (const Range range) - { - jassert (range.getLength() >= 0); - if (range.getLength() > 0) - { - removeRange (range); - - values.addUsingDefaultSort (range.getStart()); - values.addUsingDefaultSort (range.getEnd()); - - simplify(); - } - } - - /** Removes a range of values from the set. - e.g. removeRange (Range\ (10, 14)) will remove (10, 11, 12, 13) from the set. - */ - void removeRange (const Range rangeToRemove) - { - jassert (rangeToRemove.getLength() >= 0); - - if (rangeToRemove.getLength() > 0 - && values.size() > 0 - && rangeToRemove.getStart() < values.getUnchecked (values.size() - 1) - && values.getUnchecked(0) < rangeToRemove.getEnd()) - { - const bool onAtStart = contains (rangeToRemove.getStart() - 1); - const Type lastValue (jmin (rangeToRemove.getEnd(), values.getLast())); - const bool onAtEnd = contains (lastValue); - - for (int i = values.size(); --i >= 0;) - { - if (values.getUnchecked(i) <= lastValue) - { - while (values.getUnchecked(i) >= rangeToRemove.getStart()) - { - values.remove (i); - - if (--i < 0) - break; - } - - break; - } - } - - if (onAtStart) values.addUsingDefaultSort (rangeToRemove.getStart()); - if (onAtEnd) values.addUsingDefaultSort (lastValue); - - simplify(); - } - } - - /** Does an XOR of the values in a given range. */ - void invertRange (const Range range) - { - SparseSet newItems; - newItems.addRange (range); - - for (int i = getNumRanges(); --i >= 0;) - newItems.removeRange (getRange (i)); - - removeRange (range); - - for (int i = newItems.getNumRanges(); --i >= 0;) - addRange (newItems.getRange(i)); - } - - /** Checks whether any part of a given range overlaps any part of this set. */ - bool overlapsRange (const Range range) - { - if (range.getLength() > 0) - { - for (int i = getNumRanges(); --i >= 0;) - { - if (values.getUnchecked ((i << 1) + 1) <= range.getStart()) - return false; - - if (values.getUnchecked (i << 1) < range.getEnd()) - return true; - } - } - - return false; - } - - /** Checks whether the whole of a given range is contained within this one. */ - bool containsRange (const Range range) - { - if (range.getLength() > 0) - { - for (int i = getNumRanges(); --i >= 0;) - { - if (values.getUnchecked ((i << 1) + 1) <= range.getStart()) - return false; - - if (values.getUnchecked (i << 1) <= range.getStart() - && range.getEnd() <= values.getUnchecked ((i << 1) + 1)) - return true; - } - } - - return false; - } - - //============================================================================== - bool operator== (const SparseSet& other) noexcept - { - return values == other.values; - } - - bool operator!= (const SparseSet& other) noexcept - { - return values != other.values; - } - -private: - //============================================================================== - // alternating start/end values of ranges of values that are present. - Array values; - - void simplify() - { - jassert ((values.size() & 1) == 0); - - for (int i = values.size(); --i > 0;) - if (values.getUnchecked(i) == values.getUnchecked (i - 1)) - values.removeRange (--i, 2); - } -}; - - - -#endif // JUCE_SPARSESET_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/containers/juce_Variant.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/containers/juce_Variant.cpp deleted file mode 100644 index db3f2f5666..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/containers/juce_Variant.cpp +++ /dev/null @@ -1,780 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -enum VariantStreamMarkers -{ - varMarker_Int = 1, - varMarker_BoolTrue = 2, - varMarker_BoolFalse = 3, - varMarker_Double = 4, - varMarker_String = 5, - varMarker_Int64 = 6, - varMarker_Array = 7, - varMarker_Binary = 8, - varMarker_Undefined = 9 -}; - -//============================================================================== -class var::VariantType -{ -public: - VariantType() noexcept {} - virtual ~VariantType() noexcept {} - - virtual int toInt (const ValueUnion&) const noexcept { return 0; } - virtual int64 toInt64 (const ValueUnion&) const noexcept { return 0; } - virtual double toDouble (const ValueUnion&) const noexcept { return 0; } - virtual String toString (const ValueUnion&) const { return String::empty; } - virtual bool toBool (const ValueUnion&) const noexcept { return false; } - virtual ReferenceCountedObject* toObject (const ValueUnion&) const noexcept { return nullptr; } - virtual Array* toArray (const ValueUnion&) const noexcept { return nullptr; } - virtual MemoryBlock* toBinary (const ValueUnion&) const noexcept { return nullptr; } - virtual var clone (const var& original) const { return original; } - - virtual bool isVoid() const noexcept { return false; } - virtual bool isUndefined() const noexcept { return false; } - virtual bool isInt() const noexcept { return false; } - virtual bool isInt64() const noexcept { return false; } - virtual bool isBool() const noexcept { return false; } - virtual bool isDouble() const noexcept { return false; } - virtual bool isString() const noexcept { return false; } - virtual bool isObject() const noexcept { return false; } - virtual bool isArray() const noexcept { return false; } - virtual bool isBinary() const noexcept { return false; } - virtual bool isMethod() const noexcept { return false; } - - virtual void cleanUp (ValueUnion&) const noexcept {} - virtual void createCopy (ValueUnion& dest, const ValueUnion& source) const { dest = source; } - virtual bool equals (const ValueUnion& data, const ValueUnion& otherData, const VariantType& otherType) const noexcept = 0; - virtual void writeToStream (const ValueUnion& data, OutputStream& output) const = 0; -}; - -//============================================================================== -class var::VariantType_Void : public var::VariantType -{ -public: - VariantType_Void() noexcept {} - static const VariantType_Void instance; - - bool isVoid() const noexcept override { return true; } - bool equals (const ValueUnion&, const ValueUnion&, const VariantType& otherType) const noexcept override { return otherType.isVoid() || otherType.isUndefined(); } - void writeToStream (const ValueUnion&, OutputStream& output) const override { output.writeCompressedInt (0); } -}; - -//============================================================================== -class var::VariantType_Undefined : public var::VariantType -{ -public: - VariantType_Undefined() noexcept {} - static const VariantType_Undefined instance; - - bool isUndefined() const noexcept override { return true; } - String toString (const ValueUnion&) const override { return "undefined"; } - bool equals (const ValueUnion&, const ValueUnion&, const VariantType& otherType) const noexcept override { return otherType.isVoid() || otherType.isUndefined(); } - - void writeToStream (const ValueUnion&, OutputStream& output) const override - { - output.writeCompressedInt (1); - output.writeByte (varMarker_Undefined); - } -}; - -//============================================================================== -class var::VariantType_Int : public var::VariantType -{ -public: - VariantType_Int() noexcept {} - static const VariantType_Int instance; - - int toInt (const ValueUnion& data) const noexcept override { return data.intValue; }; - int64 toInt64 (const ValueUnion& data) const noexcept override { return (int64) data.intValue; }; - double toDouble (const ValueUnion& data) const noexcept override { return (double) data.intValue; } - String toString (const ValueUnion& data) const override { return String (data.intValue); } - bool toBool (const ValueUnion& data) const noexcept override { return data.intValue != 0; } - bool isInt() const noexcept override { return true; } - - bool equals (const ValueUnion& data, const ValueUnion& otherData, const VariantType& otherType) const noexcept override - { - if (otherType.isDouble() || otherType.isInt64() || otherType.isString()) - return otherType.equals (otherData, data, *this); - - return otherType.toInt (otherData) == data.intValue; - } - - void writeToStream (const ValueUnion& data, OutputStream& output) const override - { - output.writeCompressedInt (5); - output.writeByte (varMarker_Int); - output.writeInt (data.intValue); - } -}; - -//============================================================================== -class var::VariantType_Int64 : public var::VariantType -{ -public: - VariantType_Int64() noexcept {} - static const VariantType_Int64 instance; - - int toInt (const ValueUnion& data) const noexcept override { return (int) data.int64Value; }; - int64 toInt64 (const ValueUnion& data) const noexcept override { return data.int64Value; }; - double toDouble (const ValueUnion& data) const noexcept override { return (double) data.int64Value; } - String toString (const ValueUnion& data) const override { return String (data.int64Value); } - bool toBool (const ValueUnion& data) const noexcept override { return data.int64Value != 0; } - bool isInt64() const noexcept override { return true; } - - bool equals (const ValueUnion& data, const ValueUnion& otherData, const VariantType& otherType) const noexcept override - { - if (otherType.isDouble() || otherType.isString()) - return otherType.equals (otherData, data, *this); - - return otherType.toInt64 (otherData) == data.int64Value; - } - - void writeToStream (const ValueUnion& data, OutputStream& output) const override - { - output.writeCompressedInt (9); - output.writeByte (varMarker_Int64); - output.writeInt64 (data.int64Value); - } -}; - -//============================================================================== -class var::VariantType_Double : public var::VariantType -{ -public: - VariantType_Double() noexcept {} - static const VariantType_Double instance; - - int toInt (const ValueUnion& data) const noexcept override { return (int) data.doubleValue; }; - int64 toInt64 (const ValueUnion& data) const noexcept override { return (int64) data.doubleValue; }; - double toDouble (const ValueUnion& data) const noexcept override { return data.doubleValue; } - String toString (const ValueUnion& data) const override { return String (data.doubleValue); } - bool toBool (const ValueUnion& data) const noexcept override { return data.doubleValue != 0; } - bool isDouble() const noexcept override { return true; } - - bool equals (const ValueUnion& data, const ValueUnion& otherData, const VariantType& otherType) const noexcept override - { - return std::abs (otherType.toDouble (otherData) - data.doubleValue) < std::numeric_limits::epsilon(); - } - - void writeToStream (const ValueUnion& data, OutputStream& output) const override - { - output.writeCompressedInt (9); - output.writeByte (varMarker_Double); - output.writeDouble (data.doubleValue); - } -}; - -//============================================================================== -class var::VariantType_Bool : public var::VariantType -{ -public: - VariantType_Bool() noexcept {} - static const VariantType_Bool instance; - - int toInt (const ValueUnion& data) const noexcept override { return data.boolValue ? 1 : 0; }; - int64 toInt64 (const ValueUnion& data) const noexcept override { return data.boolValue ? 1 : 0; }; - double toDouble (const ValueUnion& data) const noexcept override { return data.boolValue ? 1.0 : 0.0; } - String toString (const ValueUnion& data) const override { return String::charToString (data.boolValue ? (juce_wchar) '1' : (juce_wchar) '0'); } - bool toBool (const ValueUnion& data) const noexcept override { return data.boolValue; } - bool isBool() const noexcept override { return true; } - - bool equals (const ValueUnion& data, const ValueUnion& otherData, const VariantType& otherType) const noexcept override - { - return otherType.toBool (otherData) == data.boolValue; - } - - void writeToStream (const ValueUnion& data, OutputStream& output) const override - { - output.writeCompressedInt (1); - output.writeByte (data.boolValue ? (char) varMarker_BoolTrue : (char) varMarker_BoolFalse); - } -}; - -//============================================================================== -class var::VariantType_String : public var::VariantType -{ -public: - VariantType_String() noexcept {} - static const VariantType_String instance; - - void cleanUp (ValueUnion& data) const noexcept override { getString (data)-> ~String(); } - void createCopy (ValueUnion& dest, const ValueUnion& source) const override { new (dest.stringValue) String (*getString (source)); } - - bool isString() const noexcept override { return true; } - int toInt (const ValueUnion& data) const noexcept override { return getString (data)->getIntValue(); }; - int64 toInt64 (const ValueUnion& data) const noexcept override { return getString (data)->getLargeIntValue(); }; - double toDouble (const ValueUnion& data) const noexcept override { return getString (data)->getDoubleValue(); } - String toString (const ValueUnion& data) const override { return *getString (data); } - bool toBool (const ValueUnion& data) const noexcept override { return getString (data)->getIntValue() != 0 - || getString (data)->trim().equalsIgnoreCase ("true") - || getString (data)->trim().equalsIgnoreCase ("yes"); } - - bool equals (const ValueUnion& data, const ValueUnion& otherData, const VariantType& otherType) const noexcept override - { - return otherType.toString (otherData) == *getString (data); - } - - void writeToStream (const ValueUnion& data, OutputStream& output) const override - { - const String* const s = getString (data); - const size_t len = s->getNumBytesAsUTF8() + 1; - HeapBlock temp (len); - s->copyToUTF8 (temp, len); - output.writeCompressedInt ((int) (len + 1)); - output.writeByte (varMarker_String); - output.write (temp, len); - } - -private: - static inline const String* getString (const ValueUnion& data) noexcept { return reinterpret_cast (data.stringValue); } - static inline String* getString (ValueUnion& data) noexcept { return reinterpret_cast (data.stringValue); } -}; - -//============================================================================== -class var::VariantType_Object : public var::VariantType -{ -public: - VariantType_Object() noexcept {} - static const VariantType_Object instance; - - void cleanUp (ValueUnion& data) const noexcept override { if (data.objectValue != nullptr) data.objectValue->decReferenceCount(); } - - void createCopy (ValueUnion& dest, const ValueUnion& source) const override - { - dest.objectValue = source.objectValue; - if (dest.objectValue != nullptr) - dest.objectValue->incReferenceCount(); - } - - String toString (const ValueUnion& data) const override { return "Object 0x" + String::toHexString ((int) (pointer_sized_int) data.objectValue); } - bool toBool (const ValueUnion& data) const noexcept override { return data.objectValue != 0; } - ReferenceCountedObject* toObject (const ValueUnion& data) const noexcept override { return data.objectValue; } - bool isObject() const noexcept override { return true; } - - bool equals (const ValueUnion& data, const ValueUnion& otherData, const VariantType& otherType) const noexcept override - { - return otherType.toObject (otherData) == data.objectValue; - } - - var clone (const var& original) const override - { - if (DynamicObject* d = original.getDynamicObject()) - return d->clone().get(); - - jassertfalse; // can only clone DynamicObjects! - return var(); - } - - void writeToStream (const ValueUnion&, OutputStream& output) const override - { - jassertfalse; // Can't write an object to a stream! - output.writeCompressedInt (0); - } -}; - -//============================================================================== -class var::VariantType_Array : public var::VariantType_Object -{ -public: - VariantType_Array() noexcept {} - static const VariantType_Array instance; - - String toString (const ValueUnion&) const override { return "[Array]"; } - ReferenceCountedObject* toObject (const ValueUnion&) const noexcept override { return nullptr; } - bool isArray() const noexcept override { return true; } - - Array* toArray (const ValueUnion& data) const noexcept override - { - if (RefCountedArray* a = dynamic_cast (data.objectValue)) - return &(a->array); - - return nullptr; - } - - bool equals (const ValueUnion& data, const ValueUnion& otherData, const VariantType& otherType) const noexcept override - { - const Array* const thisArray = toArray (data); - const Array* const otherArray = otherType.toArray (otherData); - return thisArray == otherArray || (thisArray != nullptr && otherArray != nullptr && *otherArray == *thisArray); - } - - var clone (const var& original) const override - { - Array arrayCopy; - - if (const Array* array = toArray (original.value)) - for (int i = 0; i < array->size(); ++i) - arrayCopy.add (array->getReference(i).clone()); - - return var (arrayCopy); - } - - void writeToStream (const ValueUnion& data, OutputStream& output) const override - { - if (const Array* array = toArray (data)) - { - MemoryOutputStream buffer (512); - const int numItems = array->size(); - buffer.writeCompressedInt (numItems); - - for (int i = 0; i < numItems; ++i) - array->getReference(i).writeToStream (buffer); - - output.writeCompressedInt (1 + (int) buffer.getDataSize()); - output.writeByte (varMarker_Array); - output << buffer; - } - } - - struct RefCountedArray : public ReferenceCountedObject - { - RefCountedArray (const Array& a) : array (a) { incReferenceCount(); } - #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS - RefCountedArray (Array&& a) : array (static_cast&&> (a)) { incReferenceCount(); } - #endif - Array array; - }; -}; - -//============================================================================== -class var::VariantType_Binary : public var::VariantType -{ -public: - VariantType_Binary() noexcept {} - - static const VariantType_Binary instance; - - void cleanUp (ValueUnion& data) const noexcept override { delete data.binaryValue; } - void createCopy (ValueUnion& dest, const ValueUnion& source) const override { dest.binaryValue = new MemoryBlock (*source.binaryValue); } - - String toString (const ValueUnion& data) const override { return data.binaryValue->toBase64Encoding(); } - bool isBinary() const noexcept override { return true; } - MemoryBlock* toBinary (const ValueUnion& data) const noexcept override { return data.binaryValue; } - - bool equals (const ValueUnion& data, const ValueUnion& otherData, const VariantType& otherType) const noexcept override - { - const MemoryBlock* const otherBlock = otherType.toBinary (otherData); - return otherBlock != nullptr && *otherBlock == *data.binaryValue; - } - - void writeToStream (const ValueUnion& data, OutputStream& output) const override - { - output.writeCompressedInt (1 + (int) data.binaryValue->getSize()); - output.writeByte (varMarker_Binary); - output << *data.binaryValue; - } -}; - -//============================================================================== -class var::VariantType_Method : public var::VariantType -{ -public: - VariantType_Method() noexcept {} - static const VariantType_Method instance; - - String toString (const ValueUnion&) const override { return "Method"; } - bool toBool (const ValueUnion& data) const noexcept override { return data.methodValue != nullptr; } - bool isMethod() const noexcept override { return true; } - - bool equals (const ValueUnion& data, const ValueUnion& otherData, const VariantType& otherType) const noexcept override - { - return otherType.isMethod() && otherData.methodValue == data.methodValue; - } - - void writeToStream (const ValueUnion&, OutputStream& output) const override - { - jassertfalse; // Can't write a method to a stream! - output.writeCompressedInt (0); - } -}; - -//============================================================================== -const var::VariantType_Void var::VariantType_Void::instance; -const var::VariantType_Undefined var::VariantType_Undefined::instance; -const var::VariantType_Int var::VariantType_Int::instance; -const var::VariantType_Int64 var::VariantType_Int64::instance; -const var::VariantType_Bool var::VariantType_Bool::instance; -const var::VariantType_Double var::VariantType_Double::instance; -const var::VariantType_String var::VariantType_String::instance; -const var::VariantType_Object var::VariantType_Object::instance; -const var::VariantType_Array var::VariantType_Array::instance; -const var::VariantType_Binary var::VariantType_Binary::instance; -const var::VariantType_Method var::VariantType_Method::instance; - - -//============================================================================== -var::var() noexcept : type (&VariantType_Void::instance) {} -var::var (const VariantType& t) noexcept : type (&t) {} -var::~var() noexcept { type->cleanUp (value); } - -const var var::null; - -//============================================================================== -var::var (const var& valueToCopy) : type (valueToCopy.type) -{ - type->createCopy (value, valueToCopy.value); -} - -var::var (const int v) noexcept : type (&VariantType_Int::instance) { value.intValue = v; } -var::var (const int64 v) noexcept : type (&VariantType_Int64::instance) { value.int64Value = v; } -var::var (const bool v) noexcept : type (&VariantType_Bool::instance) { value.boolValue = v; } -var::var (const double v) noexcept : type (&VariantType_Double::instance) { value.doubleValue = v; } -var::var (NativeFunction m) noexcept : type (&VariantType_Method::instance) { value.methodValue = m; } -var::var (const Array& v) : type (&VariantType_Array::instance) { value.objectValue = new VariantType_Array::RefCountedArray(v); } -var::var (const String& v) : type (&VariantType_String::instance) { new (value.stringValue) String (v); } -var::var (const char* const v) : type (&VariantType_String::instance) { new (value.stringValue) String (v); } -var::var (const wchar_t* const v) : type (&VariantType_String::instance) { new (value.stringValue) String (v); } -var::var (const void* v, size_t sz) : type (&VariantType_Binary::instance) { value.binaryValue = new MemoryBlock (v, sz); } -var::var (const MemoryBlock& v) : type (&VariantType_Binary::instance) { value.binaryValue = new MemoryBlock (v); } - -var::var (ReferenceCountedObject* const object) : type (&VariantType_Object::instance) -{ - value.objectValue = object; - - if (object != nullptr) - object->incReferenceCount(); -} - -var var::undefined() noexcept { return var (VariantType_Undefined::instance); } - -//============================================================================== -bool var::isVoid() const noexcept { return type->isVoid(); } -bool var::isUndefined() const noexcept { return type->isUndefined(); } -bool var::isInt() const noexcept { return type->isInt(); } -bool var::isInt64() const noexcept { return type->isInt64(); } -bool var::isBool() const noexcept { return type->isBool(); } -bool var::isDouble() const noexcept { return type->isDouble(); } -bool var::isString() const noexcept { return type->isString(); } -bool var::isObject() const noexcept { return type->isObject(); } -bool var::isArray() const noexcept { return type->isArray(); } -bool var::isBinaryData() const noexcept { return type->isBinary(); } -bool var::isMethod() const noexcept { return type->isMethod(); } - -var::operator int() const noexcept { return type->toInt (value); } -var::operator int64() const noexcept { return type->toInt64 (value); } -var::operator bool() const noexcept { return type->toBool (value); } -var::operator float() const noexcept { return (float) type->toDouble (value); } -var::operator double() const noexcept { return type->toDouble (value); } -String var::toString() const { return type->toString (value); } -var::operator String() const { return type->toString (value); } -ReferenceCountedObject* var::getObject() const noexcept { return type->toObject (value); } -Array* var::getArray() const noexcept { return type->toArray (value); } -MemoryBlock* var::getBinaryData() const noexcept { return type->toBinary (value); } -DynamicObject* var::getDynamicObject() const noexcept { return dynamic_cast (getObject()); } - -//============================================================================== -void var::swapWith (var& other) noexcept -{ - std::swap (type, other.type); - std::swap (value, other.value); -} - -var& var::operator= (const var& v) { type->cleanUp (value); type = v.type; type->createCopy (value, v.value); return *this; } -var& var::operator= (const int v) { type->cleanUp (value); type = &VariantType_Int::instance; value.intValue = v; return *this; } -var& var::operator= (const int64 v) { type->cleanUp (value); type = &VariantType_Int64::instance; value.int64Value = v; return *this; } -var& var::operator= (const bool v) { type->cleanUp (value); type = &VariantType_Bool::instance; value.boolValue = v; return *this; } -var& var::operator= (const double v) { type->cleanUp (value); type = &VariantType_Double::instance; value.doubleValue = v; return *this; } -var& var::operator= (const char* const v) { type->cleanUp (value); type = &VariantType_String::instance; new (value.stringValue) String (v); return *this; } -var& var::operator= (const wchar_t* const v) { type->cleanUp (value); type = &VariantType_String::instance; new (value.stringValue) String (v); return *this; } -var& var::operator= (const String& v) { type->cleanUp (value); type = &VariantType_String::instance; new (value.stringValue) String (v); return *this; } -var& var::operator= (const Array& v) { var v2 (v); swapWith (v2); return *this; } -var& var::operator= (ReferenceCountedObject* v) { var v2 (v); swapWith (v2); return *this; } -var& var::operator= (NativeFunction v) { var v2 (v); swapWith (v2); return *this; } - -#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS -var::var (var&& other) noexcept - : type (other.type), - value (other.value) -{ - other.type = &VariantType_Void::instance; -} - -var& var::operator= (var&& other) noexcept -{ - swapWith (other); - return *this; -} - -var::var (String&& v) : type (&VariantType_String::instance) -{ - new (value.stringValue) String (static_cast (v)); -} - -var::var (MemoryBlock&& v) : type (&VariantType_Binary::instance) -{ - value.binaryValue = new MemoryBlock (static_cast (v)); -} - -var::var (Array&& v) : type (&VariantType_Array::instance) -{ - value.objectValue = new VariantType_Array::RefCountedArray (static_cast&&> (v)); -} - -var& var::operator= (String&& v) -{ - type->cleanUp (value); - type = &VariantType_String::instance; - new (value.stringValue) String (static_cast (v)); - return *this; -} -#endif - -//============================================================================== -bool var::equals (const var& other) const noexcept -{ - return type->equals (value, other.value, *other.type); -} - -bool var::equalsWithSameType (const var& other) const noexcept -{ - return type == other.type && equals (other); -} - -bool var::hasSameTypeAs (const var& other) const noexcept -{ - return type == other.type; -} - -bool operator== (const var& v1, const var& v2) noexcept { return v1.equals (v2); } -bool operator!= (const var& v1, const var& v2) noexcept { return ! v1.equals (v2); } -bool operator== (const var& v1, const String& v2) { return v1.toString() == v2; } -bool operator!= (const var& v1, const String& v2) { return v1.toString() != v2; } -bool operator== (const var& v1, const char* const v2) { return v1.toString() == v2; } -bool operator!= (const var& v1, const char* const v2) { return v1.toString() != v2; } - -//============================================================================== -var var::clone() const noexcept -{ - return type->clone (*this); -} - -//============================================================================== -var var::operator[] (const Identifier propertyName) const -{ - if (DynamicObject* const o = getDynamicObject()) - return o->getProperty (propertyName); - - return var(); -} - -var var::operator[] (const char* const propertyName) const -{ - return operator[] (Identifier (propertyName)); -} - -var var::getProperty (const Identifier propertyName, const var& defaultReturnValue) const -{ - if (DynamicObject* const o = getDynamicObject()) - return o->getProperties().getWithDefault (propertyName, defaultReturnValue); - - return defaultReturnValue; -} - -var::NativeFunction var::getNativeFunction() const -{ - return isMethod() ? value.methodValue : nullptr; -} - -var var::invoke (Identifier method, const var* arguments, int numArguments) const -{ - if (DynamicObject* const o = getDynamicObject()) - return o->invokeMethod (method, var::NativeFunctionArgs (*this, arguments, numArguments)); - - return var(); -} - -var var::call (const Identifier method) const -{ - return invoke (method, nullptr, 0); -} - -var var::call (const Identifier method, const var& arg1) const -{ - return invoke (method, &arg1, 1); -} - -var var::call (const Identifier method, const var& arg1, const var& arg2) const -{ - var args[] = { arg1, arg2 }; - return invoke (method, args, 2); -} - -var var::call (const Identifier method, const var& arg1, const var& arg2, const var& arg3) -{ - var args[] = { arg1, arg2, arg3 }; - return invoke (method, args, 3); -} - -var var::call (const Identifier method, const var& arg1, const var& arg2, const var& arg3, const var& arg4) const -{ - var args[] = { arg1, arg2, arg3, arg4 }; - return invoke (method, args, 4); -} - -var var::call (const Identifier method, const var& arg1, const var& arg2, const var& arg3, const var& arg4, const var& arg5) const -{ - var args[] = { arg1, arg2, arg3, arg4, arg5 }; - return invoke (method, args, 5); -} - -//============================================================================== -int var::size() const -{ - if (const Array* const array = getArray()) - return array->size(); - - return 0; -} - -const var& var::operator[] (int arrayIndex) const -{ - const Array* const array = getArray(); - - // When using this method, the var must actually be an array, and the index - // must be in-range! - jassert (array != nullptr && isPositiveAndBelow (arrayIndex, array->size())); - - return array->getReference (arrayIndex); -} - -var& var::operator[] (int arrayIndex) -{ - const Array* const array = getArray(); - - // When using this method, the var must actually be an array, and the index - // must be in-range! - jassert (array != nullptr && isPositiveAndBelow (arrayIndex, array->size())); - - return array->getReference (arrayIndex); -} - -Array* var::convertToArray() -{ - if (Array* array = getArray()) - return array; - - Array tempVar; - if (! isVoid()) - tempVar.add (*this); - - *this = tempVar; - return getArray(); -} - -void var::append (const var& n) -{ - convertToArray()->add (n); -} - -void var::remove (const int index) -{ - if (Array* const array = getArray()) - array->remove (index); -} - -void var::insert (const int index, const var& n) -{ - convertToArray()->insert (index, n); -} - -void var::resize (const int numArrayElementsWanted) -{ - convertToArray()->resize (numArrayElementsWanted); -} - -int var::indexOf (const var& n) const -{ - if (const Array* const array = getArray()) - return array->indexOf (n); - - return -1; -} - -//============================================================================== -void var::writeToStream (OutputStream& output) const -{ - type->writeToStream (value, output); -} - -var var::readFromStream (InputStream& input) -{ - const int numBytes = input.readCompressedInt(); - - if (numBytes > 0) - { - switch (input.readByte()) - { - case varMarker_Int: return var (input.readInt()); - case varMarker_Int64: return var (input.readInt64()); - case varMarker_BoolTrue: return var (true); - case varMarker_BoolFalse: return var (false); - case varMarker_Double: return var (input.readDouble()); - case varMarker_String: - { - MemoryOutputStream mo; - mo.writeFromInputStream (input, numBytes - 1); - return var (mo.toUTF8()); - } - - case varMarker_Binary: - { - MemoryBlock mb ((size_t) numBytes - 1); - - if (numBytes > 1) - { - const int numRead = input.read (mb.getData(), numBytes - 1); - mb.setSize ((size_t) numRead); - } - - return var (mb); - } - - case varMarker_Array: - { - var v; - Array* const destArray = v.convertToArray(); - - for (int i = input.readCompressedInt(); --i >= 0;) - destArray->add (readFromStream (input)); - - return v; - } - - default: - input.skipNextBytes (numBytes - 1); break; - } - } - - return var(); -} - -var::NativeFunctionArgs::NativeFunctionArgs (const var& t, const var* args, int numArgs) noexcept - : thisObject (t), arguments (args), numArguments (numArgs) -{} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/containers/juce_Variant.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/containers/juce_Variant.h deleted file mode 100644 index 41a4884c1c..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/containers/juce_Variant.h +++ /dev/null @@ -1,327 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_VARIANT_H_INCLUDED -#define JUCE_VARIANT_H_INCLUDED - - -//============================================================================== -/** - A variant class, that can be used to hold a range of primitive values. - - A var object can hold a range of simple primitive values, strings, or - any kind of ReferenceCountedObject. The var class is intended to act like - the kind of values used in dynamic scripting languages. - - You can save/load var objects either in a small, proprietary binary format - using writeToStream()/readFromStream(), or as JSON by using the JSON class. - - @see JSON, DynamicObject -*/ -class JUCE_API var -{ -public: - //============================================================================== - /** This structure is passed to a NativeFunction callback, and contains invocation - details about the function's arguments and context. - */ - struct NativeFunctionArgs - { - NativeFunctionArgs (const var& thisObject, const var* args, int numArgs) noexcept; - - const var& thisObject; - const var* arguments; - int numArguments; - - JUCE_DECLARE_NON_COPYABLE (NativeFunctionArgs) - }; - - typedef var (*NativeFunction) (const NativeFunctionArgs&); - typedef Identifier identifier; - - //============================================================================== - /** Creates a void variant. */ - var() noexcept; - - /** Destructor. */ - ~var() noexcept; - - /** A static var object that can be used where you need an empty variant object. */ - static const var null; - - var (const var& valueToCopy); - var (int value) noexcept; - var (int64 value) noexcept; - var (bool value) noexcept; - var (double value) noexcept; - var (const char* value); - var (const wchar_t* value); - var (const String& value); - var (const Array& value); - var (ReferenceCountedObject* object); - var (NativeFunction method) noexcept; - var (const void* binaryData, size_t dataSize); - var (const MemoryBlock& binaryData); - - var& operator= (const var& valueToCopy); - var& operator= (int value); - var& operator= (int64 value); - var& operator= (bool value); - var& operator= (double value); - var& operator= (const char* value); - var& operator= (const wchar_t* value); - var& operator= (const String& value); - var& operator= (const Array& value); - var& operator= (ReferenceCountedObject* object); - var& operator= (NativeFunction method); - - #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS - var (var&& other) noexcept; - var (String&& value); - var (MemoryBlock&& binaryData); - var (Array&& value); - var& operator= (var&& other) noexcept; - var& operator= (String&& value); - #endif - - void swapWith (var& other) noexcept; - - /** Returns a var object that can be used where you need the javascript "undefined" value. */ - static var undefined() noexcept; - - //============================================================================== - operator int() const noexcept; - operator int64() const noexcept; - operator bool() const noexcept; - operator float() const noexcept; - operator double() const noexcept; - operator String() const; - String toString() const; - - /** If this variant holds an array, this provides access to it. - NOTE: Beware when you use this - the array pointer is only valid for the lifetime - of the variant that returned it, so be very careful not to call this method on temporary - var objects that are the return-value of a function, and which may go out of scope before - you use the array! - */ - Array* getArray() const noexcept; - - /** If this variant holds a memory block, this provides access to it. - NOTE: Beware when you use this - the MemoryBlock pointer is only valid for the lifetime - of the variant that returned it, so be very careful not to call this method on temporary - var objects that are the return-value of a function, and which may go out of scope before - you use the MemoryBlock! - */ - MemoryBlock* getBinaryData() const noexcept; - - ReferenceCountedObject* getObject() const noexcept; - DynamicObject* getDynamicObject() const noexcept; - - //============================================================================== - bool isVoid() const noexcept; - bool isUndefined() const noexcept; - bool isInt() const noexcept; - bool isInt64() const noexcept; - bool isBool() const noexcept; - bool isDouble() const noexcept; - bool isString() const noexcept; - bool isObject() const noexcept; - bool isArray() const noexcept; - bool isBinaryData() const noexcept; - bool isMethod() const noexcept; - - /** Returns true if this var has the same value as the one supplied. - Note that this ignores the type, so a string var "123" and an integer var with the - value 123 are considered to be equal. - @see equalsWithSameType - */ - bool equals (const var& other) const noexcept; - - /** Returns true if this var has the same value and type as the one supplied. - This differs from equals() because e.g. "123" and 123 will be considered different. - @see equals - */ - bool equalsWithSameType (const var& other) const noexcept; - - /** Returns true if this var has the same type as the one supplied. */ - bool hasSameTypeAs (const var& other) const noexcept; - - /** Returns a deep copy of this object. - For simple types this just returns a copy, but if the object contains any arrays - or DynamicObjects, they will be cloned (recursively). - */ - var clone() const noexcept; - - //============================================================================== - /** If the var is an array, this returns the number of elements. - If the var isn't actually an array, this will return 0. - */ - int size() const; - - /** If the var is an array, this can be used to return one of its elements. - To call this method, you must make sure that the var is actually an array, and - that the index is a valid number. If these conditions aren't met, behaviour is - undefined. - For more control over the array's contents, you can call getArray() and manipulate - it directly as an Array\. - */ - const var& operator[] (int arrayIndex) const; - - /** If the var is an array, this can be used to return one of its elements. - To call this method, you must make sure that the var is actually an array, and - that the index is a valid number. If these conditions aren't met, behaviour is - undefined. - For more control over the array's contents, you can call getArray() and manipulate - it directly as an Array\. - */ - var& operator[] (int arrayIndex); - - /** Appends an element to the var, converting it to an array if it isn't already one. - If the var isn't an array, it will be converted to one, and if its value was non-void, - this value will be kept as the first element of the new array. The parameter value - will then be appended to it. - For more control over the array's contents, you can call getArray() and manipulate - it directly as an Array\. - */ - void append (const var& valueToAppend); - - /** Inserts an element to the var, converting it to an array if it isn't already one. - If the var isn't an array, it will be converted to one, and if its value was non-void, - this value will be kept as the first element of the new array. The parameter value - will then be inserted into it. - For more control over the array's contents, you can call getArray() and manipulate - it directly as an Array\. - */ - void insert (int index, const var& value); - - /** If the var is an array, this removes one of its elements. - If the index is out-of-range or the var isn't an array, nothing will be done. - For more control over the array's contents, you can call getArray() and manipulate - it directly as an Array\. - */ - void remove (int index); - - /** Treating the var as an array, this resizes it to contain the specified number of elements. - If the var isn't an array, it will be converted to one, and if its value was non-void, - this value will be kept as the first element of the new array before resizing. - For more control over the array's contents, you can call getArray() and manipulate - it directly as an Array\. - */ - void resize (int numArrayElementsWanted); - - /** If the var is an array, this searches it for the first occurrence of the specified value, - and returns its index. - If the var isn't an array, or if the value isn't found, this returns -1. - */ - int indexOf (const var& value) const; - - //============================================================================== - /** If this variant is an object, this returns one of its properties. */ - var operator[] (Identifier propertyName) const; - /** If this variant is an object, this returns one of its properties. */ - var operator[] (const char* propertyName) const; - /** If this variant is an object, this returns one of its properties, or a default - fallback value if the property is not set. */ - var getProperty (Identifier propertyName, const var& defaultReturnValue) const; - - /** Invokes a named method call with no arguments. */ - var call (Identifier method) const; - /** Invokes a named method call with one argument. */ - var call (Identifier method, const var& arg1) const; - /** Invokes a named method call with 2 arguments. */ - var call (Identifier method, const var& arg1, const var& arg2) const; - /** Invokes a named method call with 3 arguments. */ - var call (Identifier method, const var& arg1, const var& arg2, const var& arg3); - /** Invokes a named method call with 4 arguments. */ - var call (Identifier method, const var& arg1, const var& arg2, const var& arg3, const var& arg4) const; - /** Invokes a named method call with 5 arguments. */ - var call (Identifier method, const var& arg1, const var& arg2, const var& arg3, const var& arg4, const var& arg5) const; - /** Invokes a named method call with a list of arguments. */ - var invoke (Identifier method, const var* arguments, int numArguments) const; - /** If this object is a method, this returns the function pointer. */ - NativeFunction getNativeFunction() const; - - //============================================================================== - /** Writes a binary representation of this value to a stream. - The data can be read back later using readFromStream(). - @see JSON - */ - void writeToStream (OutputStream& output) const; - - /** Reads back a stored binary representation of a value. - The data in the stream must have been written using writeToStream(), or this - will have unpredictable results. - @see JSON - */ - static var readFromStream (InputStream& input); - -private: - //============================================================================== - class VariantType; friend class VariantType; - class VariantType_Void; friend class VariantType_Void; - class VariantType_Undefined; friend class VariantType_Undefined; - class VariantType_Int; friend class VariantType_Int; - class VariantType_Int64; friend class VariantType_Int64; - class VariantType_Double; friend class VariantType_Double; - class VariantType_Bool; friend class VariantType_Bool; - class VariantType_String; friend class VariantType_String; - class VariantType_Object; friend class VariantType_Object; - class VariantType_Array; friend class VariantType_Array; - class VariantType_Binary; friend class VariantType_Binary; - class VariantType_Method; friend class VariantType_Method; - - union ValueUnion - { - int intValue; - int64 int64Value; - bool boolValue; - double doubleValue; - char stringValue [sizeof (String)]; - ReferenceCountedObject* objectValue; - MemoryBlock* binaryValue; - NativeFunction methodValue; - }; - - const VariantType* type; - ValueUnion value; - - Array* convertToArray(); - var (const VariantType&) noexcept; -}; - -/** Compares the values of two var objects, using the var::equals() comparison. */ -bool operator== (const var& v1, const var& v2) noexcept; -/** Compares the values of two var objects, using the var::equals() comparison. */ -bool operator!= (const var& v1, const var& v2) noexcept; -bool operator== (const var& v1, const String& v2); -bool operator!= (const var& v1, const String& v2); -bool operator== (const var& v1, const char* v2); -bool operator!= (const var& v1, const char* v2); - - -#endif // JUCE_VARIANT_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/files/juce_DirectoryIterator.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/files/juce_DirectoryIterator.cpp deleted file mode 100644 index 7d6dd4b13f..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/files/juce_DirectoryIterator.cpp +++ /dev/null @@ -1,159 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -DirectoryIterator::DirectoryIterator (const File& directory, bool recursive, - const String& pattern, const int type) - : wildCards (parseWildcards (pattern)), - fileFinder (directory, (recursive || wildCards.size() > 1) ? "*" : pattern), - wildCard (pattern), - path (File::addTrailingSeparator (directory.getFullPathName())), - index (-1), - totalNumFiles (-1), - whatToLookFor (type), - isRecursive (recursive), - hasBeenAdvanced (false) -{ - // you have to specify the type of files you're looking for! - jassert ((type & (File::findFiles | File::findDirectories)) != 0); - jassert (type > 0 && type <= 7); -} - -DirectoryIterator::~DirectoryIterator() -{ -} - -StringArray DirectoryIterator::parseWildcards (const String& pattern) -{ - StringArray s; - s.addTokens (pattern, ";,", "\"'"); - s.trim(); - s.removeEmptyStrings(); - return s; -} - -bool DirectoryIterator::fileMatches (const StringArray& wildCards, const String& filename) -{ - for (int i = 0; i < wildCards.size(); ++i) - if (filename.matchesWildcard (wildCards[i], ! File::areFileNamesCaseSensitive())) - return true; - - return false; -} - -bool DirectoryIterator::next() -{ - return next (nullptr, nullptr, nullptr, nullptr, nullptr, nullptr); -} - -bool DirectoryIterator::next (bool* const isDirResult, bool* const isHiddenResult, int64* const fileSize, - Time* const modTime, Time* const creationTime, bool* const isReadOnly) -{ - hasBeenAdvanced = true; - - if (subIterator != nullptr) - { - if (subIterator->next (isDirResult, isHiddenResult, fileSize, modTime, creationTime, isReadOnly)) - return true; - - subIterator = nullptr; - } - - String filename; - bool isDirectory, isHidden = false; - - while (fileFinder.next (filename, &isDirectory, - (isHiddenResult != nullptr || (whatToLookFor & File::ignoreHiddenFiles) != 0) ? &isHidden : nullptr, - fileSize, modTime, creationTime, isReadOnly)) - { - ++index; - - if (! filename.containsOnly (".")) - { - bool matches = false; - - if (isDirectory) - { - if (isRecursive && ((whatToLookFor & File::ignoreHiddenFiles) == 0 || ! isHidden)) - subIterator = new DirectoryIterator (File::createFileWithoutCheckingPath (path + filename), - true, wildCard, whatToLookFor); - - matches = (whatToLookFor & File::findDirectories) != 0; - } - else - { - matches = (whatToLookFor & File::findFiles) != 0; - } - - // if we're not relying on the OS iterator to do the wildcard match, do it now.. - if (matches && (isRecursive || wildCards.size() > 1)) - matches = fileMatches (wildCards, filename); - - if (matches && (whatToLookFor & File::ignoreHiddenFiles) != 0) - matches = ! isHidden; - - if (matches) - { - currentFile = File::createFileWithoutCheckingPath (path + filename); - if (isHiddenResult != nullptr) *isHiddenResult = isHidden; - if (isDirResult != nullptr) *isDirResult = isDirectory; - - return true; - } - - if (subIterator != nullptr) - return next (isDirResult, isHiddenResult, fileSize, modTime, creationTime, isReadOnly); - } - } - - return false; -} - -const File& DirectoryIterator::getFile() const -{ - if (subIterator != nullptr && subIterator->hasBeenAdvanced) - return subIterator->getFile(); - - // You need to call DirectoryIterator::next() before asking it for the file that it found! - jassert (hasBeenAdvanced); - - return currentFile; -} - -float DirectoryIterator::getEstimatedProgress() const -{ - if (totalNumFiles < 0) - totalNumFiles = File (path).getNumberOfChildFiles (File::findFilesAndDirectories); - - if (totalNumFiles <= 0) - return 0.0f; - - const float detailedIndex = (subIterator != nullptr) ? index + subIterator->getEstimatedProgress() - : (float) index; - - return detailedIndex / totalNumFiles; -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/files/juce_DirectoryIterator.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/files/juce_DirectoryIterator.h deleted file mode 100644 index 3ca2265f1a..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/files/juce_DirectoryIterator.h +++ /dev/null @@ -1,159 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_DIRECTORYITERATOR_H_INCLUDED -#define JUCE_DIRECTORYITERATOR_H_INCLUDED - - -//============================================================================== -/** - Searches through the files in a directory, returning each file that is found. - - A DirectoryIterator will search through a directory and its subdirectories using - a wildcard filepattern match. - - If you may be scanning a large number of files, it's usually smarter to use this - class than File::findChildFiles() because it allows you to stop at any time, rather - than having to wait for the entire scan to finish before getting the results. - - It also provides an estimate of its progress, using a (highly inaccurate!) algorithm. -*/ -class JUCE_API DirectoryIterator -{ -public: - //============================================================================== - /** Creates a DirectoryIterator for a given directory. - - After creating one of these, call its next() method to get the - first file - e.g. @code - - DirectoryIterator iter (File ("/animals/mooses"), true, "*.moose"); - - while (iter.next()) - { - File theFileItFound (iter.getFile()); - - ... etc - } - @endcode - - @param directory the directory to search in - @param isRecursive whether all the subdirectories should also be searched - @param wildCard the file pattern to match. This may contain multiple patterns - separated by a semi-colon or comma, e.g. "*.jpg;*.png" - @param whatToLookFor a value from the File::TypesOfFileToFind enum, specifying - whether to look for files, directories, or both. - */ - DirectoryIterator (const File& directory, - bool isRecursive, - const String& wildCard = "*", - int whatToLookFor = File::findFiles); - - /** Destructor. */ - ~DirectoryIterator(); - - /** Moves the iterator along to the next file. - - @returns true if a file was found (you can then use getFile() to see what it was) - or - false if there are no more matching files. - */ - bool next(); - - /** Moves the iterator along to the next file, and returns various properties of that file. - - If you need to find out details about the file, it's more efficient to call this method than - to call the normal next() method and then find out the details afterwards. - - All the parameters are optional, so pass null pointers for any items that you're not - interested in. - - @returns true if a file was found (you can then use getFile() to see what it was) - or - false if there are no more matching files. If it returns false, then none of the - parameters will be filled-in. - */ - bool next (bool* isDirectory, - bool* isHidden, - int64* fileSize, - Time* modTime, - Time* creationTime, - bool* isReadOnly); - - /** Returns the file that the iterator is currently pointing at. - - The result of this call is only valid after a call to next() has returned true. - */ - const File& getFile() const; - - /** Returns a guess of how far through the search the iterator has got. - - @returns a value 0.0 to 1.0 to show the progress, although this won't be - very accurate. - */ - float getEstimatedProgress() const; - -private: - //============================================================================== - class NativeIterator - { - public: - NativeIterator (const File& directory, const String& wildCard); - ~NativeIterator(); - - bool next (String& filenameFound, - bool* isDirectory, bool* isHidden, int64* fileSize, - Time* modTime, Time* creationTime, bool* isReadOnly); - - class Pimpl; - - private: - friend class DirectoryIterator; - friend struct ContainerDeletePolicy; - ScopedPointer pimpl; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (NativeIterator) - }; - - friend struct ContainerDeletePolicy; - StringArray wildCards; - NativeIterator fileFinder; - String wildCard, path; - int index; - mutable int totalNumFiles; - const int whatToLookFor; - const bool isRecursive; - bool hasBeenAdvanced; - ScopedPointer subIterator; - File currentFile; - - static StringArray parseWildcards (const String& pattern); - static bool fileMatches (const StringArray& wildCards, const String& filename); - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (DirectoryIterator) -}; - -#endif // JUCE_DIRECTORYITERATOR_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/files/juce_File.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/files/juce_File.cpp deleted file mode 100644 index d5c520a098..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/files/juce_File.cpp +++ /dev/null @@ -1,1086 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -File::File (const String& fullPathName) - : fullPath (parseAbsolutePath (fullPathName)) -{ -} - -File File::createFileWithoutCheckingPath (const String& path) noexcept -{ - File f; - f.fullPath = path; - return f; -} - -File::File (const File& other) - : fullPath (other.fullPath) -{ -} - -File& File::operator= (const String& newPath) -{ - fullPath = parseAbsolutePath (newPath); - return *this; -} - -File& File::operator= (const File& other) -{ - fullPath = other.fullPath; - return *this; -} - -#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS -File::File (File&& other) noexcept - : fullPath (static_cast (other.fullPath)) -{ -} - -File& File::operator= (File&& other) noexcept -{ - fullPath = static_cast (other.fullPath); - return *this; -} -#endif - -const File File::nonexistent; - - -//============================================================================== -String File::parseAbsolutePath (const String& p) -{ - if (p.isEmpty()) - return String(); - -#if JUCE_WINDOWS - // Windows.. - String path (p.replaceCharacter ('/', '\\')); - - if (path.startsWithChar (separator)) - { - if (path[1] != separator) - { - /* When you supply a raw string to the File object constructor, it must be an absolute path. - If you're trying to parse a string that may be either a relative path or an absolute path, - you MUST provide a context against which the partial path can be evaluated - you can do - this by simply using File::getChildFile() instead of the File constructor. E.g. saying - "File::getCurrentWorkingDirectory().getChildFile (myUnknownPath)" would return an absolute - path if that's what was supplied, or would evaluate a partial path relative to the CWD. - */ - jassertfalse; - - path = File::getCurrentWorkingDirectory().getFullPathName().substring (0, 2) + path; - } - } - else if (! path.containsChar (':')) - { - /* When you supply a raw string to the File object constructor, it must be an absolute path. - If you're trying to parse a string that may be either a relative path or an absolute path, - you MUST provide a context against which the partial path can be evaluated - you can do - this by simply using File::getChildFile() instead of the File constructor. E.g. saying - "File::getCurrentWorkingDirectory().getChildFile (myUnknownPath)" would return an absolute - path if that's what was supplied, or would evaluate a partial path relative to the CWD. - */ - jassertfalse; - - return File::getCurrentWorkingDirectory().getChildFile (path).getFullPathName(); - } -#else - // Mac or Linux.. - - // Yes, I know it's legal for a unix pathname to contain a backslash, but this assertion is here - // to catch anyone who's trying to run code that was written on Windows with hard-coded path names. - // If that's why you've ended up here, use File::getChildFile() to build your paths instead. - jassert ((! p.containsChar ('\\')) || (p.indexOfChar ('/') >= 0 && p.indexOfChar ('/') < p.indexOfChar ('\\'))); - - String path (p); - - if (path.startsWithChar ('~')) - { - if (path[1] == separator || path[1] == 0) - { - // expand a name of the form "~/abc" - path = File::getSpecialLocation (File::userHomeDirectory).getFullPathName() - + path.substring (1); - } - else - { - // expand a name of type "~dave/abc" - const String userName (path.substring (1).upToFirstOccurrenceOf ("/", false, false)); - - if (struct passwd* const pw = getpwnam (userName.toUTF8())) - path = addTrailingSeparator (pw->pw_dir) + path.fromFirstOccurrenceOf ("/", false, false); - } - } - else if (! path.startsWithChar (separator)) - { - #if JUCE_DEBUG || JUCE_LOG_ASSERTIONS - if (! (path.startsWith ("./") || path.startsWith ("../"))) - { - /* When you supply a raw string to the File object constructor, it must be an absolute path. - If you're trying to parse a string that may be either a relative path or an absolute path, - you MUST provide a context against which the partial path can be evaluated - you can do - this by simply using File::getChildFile() instead of the File constructor. E.g. saying - "File::getCurrentWorkingDirectory().getChildFile (myUnknownPath)" would return an absolute - path if that's what was supplied, or would evaluate a partial path relative to the CWD. - */ - jassertfalse; - - #if JUCE_LOG_ASSERTIONS - Logger::writeToLog ("Illegal absolute path: " + path); - #endif - } - #endif - - return File::getCurrentWorkingDirectory().getChildFile (path).getFullPathName(); - } -#endif - - while (path.endsWithChar (separator) && path != separatorString) // careful not to turn a single "/" into an empty string. - path = path.dropLastCharacters (1); - - return path; -} - -String File::addTrailingSeparator (const String& path) -{ - return path.endsWithChar (separator) ? path - : path + separator; -} - -//============================================================================== -#if JUCE_LINUX - #define NAMES_ARE_CASE_SENSITIVE 1 -#endif - -bool File::areFileNamesCaseSensitive() -{ - #if NAMES_ARE_CASE_SENSITIVE - return true; - #else - return false; - #endif -} - -static int compareFilenames (const String& name1, const String& name2) noexcept -{ - #if NAMES_ARE_CASE_SENSITIVE - return name1.compare (name2); - #else - return name1.compareIgnoreCase (name2); - #endif -} - -bool File::operator== (const File& other) const { return compareFilenames (fullPath, other.fullPath) == 0; } -bool File::operator!= (const File& other) const { return compareFilenames (fullPath, other.fullPath) != 0; } -bool File::operator< (const File& other) const { return compareFilenames (fullPath, other.fullPath) < 0; } -bool File::operator> (const File& other) const { return compareFilenames (fullPath, other.fullPath) > 0; } - -//============================================================================== -bool File::setReadOnly (const bool shouldBeReadOnly, - const bool applyRecursively) const -{ - bool worked = true; - - if (applyRecursively && isDirectory()) - { - Array subFiles; - findChildFiles (subFiles, File::findFilesAndDirectories, false); - - for (int i = subFiles.size(); --i >= 0;) - worked = subFiles.getReference(i).setReadOnly (shouldBeReadOnly, true) && worked; - } - - return setFileReadOnlyInternal (shouldBeReadOnly) && worked; -} - -bool File::deleteRecursively() const -{ - bool worked = true; - - if (isDirectory()) - { - Array subFiles; - findChildFiles (subFiles, File::findFilesAndDirectories, false); - - for (int i = subFiles.size(); --i >= 0;) - worked = subFiles.getReference(i).deleteRecursively() && worked; - } - - return deleteFile() && worked; -} - -bool File::moveFileTo (const File& newFile) const -{ - if (newFile.fullPath == fullPath) - return true; - - if (! exists()) - return false; - - #if ! NAMES_ARE_CASE_SENSITIVE - if (*this != newFile) - #endif - if (! newFile.deleteFile()) - return false; - - return moveInternal (newFile); -} - -bool File::copyFileTo (const File& newFile) const -{ - return (*this == newFile) - || (exists() && newFile.deleteFile() && copyInternal (newFile)); -} - -bool File::copyDirectoryTo (const File& newDirectory) const -{ - if (isDirectory() && newDirectory.createDirectory()) - { - Array subFiles; - findChildFiles (subFiles, File::findFiles, false); - - for (int i = 0; i < subFiles.size(); ++i) - if (! subFiles.getReference(i).copyFileTo (newDirectory.getChildFile (subFiles.getReference(i).getFileName()))) - return false; - - subFiles.clear(); - findChildFiles (subFiles, File::findDirectories, false); - - for (int i = 0; i < subFiles.size(); ++i) - if (! subFiles.getReference(i).copyDirectoryTo (newDirectory.getChildFile (subFiles.getReference(i).getFileName()))) - return false; - - return true; - } - - return false; -} - -//============================================================================== -String File::getPathUpToLastSlash() const -{ - const int lastSlash = fullPath.lastIndexOfChar (separator); - - if (lastSlash > 0) - return fullPath.substring (0, lastSlash); - - if (lastSlash == 0) - return separatorString; - - return fullPath; -} - -File File::getParentDirectory() const -{ - File f; - f.fullPath = getPathUpToLastSlash(); - return f; -} - -//============================================================================== -String File::getFileName() const -{ - return fullPath.substring (fullPath.lastIndexOfChar (separator) + 1); -} - -String File::getFileNameWithoutExtension() const -{ - const int lastSlash = fullPath.lastIndexOfChar (separator) + 1; - const int lastDot = fullPath.lastIndexOfChar ('.'); - - if (lastDot > lastSlash) - return fullPath.substring (lastSlash, lastDot); - - return fullPath.substring (lastSlash); -} - -bool File::isAChildOf (const File& potentialParent) const -{ - if (potentialParent.fullPath.isEmpty()) - return false; - - const String ourPath (getPathUpToLastSlash()); - - if (compareFilenames (potentialParent.fullPath, ourPath) == 0) - return true; - - if (potentialParent.fullPath.length() >= ourPath.length()) - return false; - - return getParentDirectory().isAChildOf (potentialParent); -} - -int File::hashCode() const { return fullPath.hashCode(); } -int64 File::hashCode64() const { return fullPath.hashCode64(); } - -//============================================================================== -bool File::isAbsolutePath (StringRef path) -{ - return path.text[0] == separator - #if JUCE_WINDOWS - || (path.isNotEmpty() && path.text[1] == ':'); - #else - || path.text[0] == '~'; - #endif -} - -File File::getChildFile (StringRef relativePath) const -{ - if (isAbsolutePath (relativePath)) - return File (String (relativePath.text)); - - if (relativePath[0] != '.') - return File (addTrailingSeparator (fullPath) + relativePath); - - String path (fullPath); - - // It's relative, so remove any ../ or ./ bits at the start.. - #if JUCE_WINDOWS - if (relativePath.text.indexOf ((juce_wchar) '/') >= 0) - return getChildFile (String (relativePath.text).replaceCharacter ('/', '\\')); - #endif - - while (relativePath[0] == '.') - { - const juce_wchar secondChar = relativePath[1]; - - if (secondChar == '.') - { - const juce_wchar thirdChar = relativePath[2]; - - if (thirdChar == 0 || thirdChar == separator) - { - const int lastSlash = path.lastIndexOfChar (separator); - if (lastSlash >= 0) - path = path.substring (0, lastSlash); - - relativePath = relativePath.text + (thirdChar == 0 ? 2 : 3); - } - else - { - break; - } - } - else if (secondChar == separator) - { - relativePath = relativePath.text + 2; - } - else - { - break; - } - } - - return File (addTrailingSeparator (path) + relativePath); -} - -File File::getSiblingFile (StringRef fileName) const -{ - return getParentDirectory().getChildFile (fileName); -} - -//============================================================================== -String File::descriptionOfSizeInBytes (const int64 bytes) -{ - const char* suffix; - double divisor = 0; - - if (bytes == 1) { suffix = " byte"; } - else if (bytes < 1024) { suffix = " bytes"; } - else if (bytes < 1024 * 1024) { suffix = " KB"; divisor = 1024.0; } - else if (bytes < 1024 * 1024 * 1024) { suffix = " MB"; divisor = 1024.0 * 1024.0; } - else { suffix = " GB"; divisor = 1024.0 * 1024.0 * 1024.0; } - - return (divisor > 0 ? String (bytes / divisor, 1) : String (bytes)) + suffix; -} - -//============================================================================== -Result File::create() const -{ - if (exists()) - return Result::ok(); - - const File parentDir (getParentDirectory()); - - if (parentDir == *this) - return Result::fail ("Cannot create parent directory"); - - Result r (parentDir.createDirectory()); - - if (r.wasOk()) - { - FileOutputStream fo (*this, 8); - r = fo.getStatus(); - } - - return r; -} - -Result File::createDirectory() const -{ - if (isDirectory()) - return Result::ok(); - - const File parentDir (getParentDirectory()); - - if (parentDir == *this) - return Result::fail ("Cannot create parent directory"); - - Result r (parentDir.createDirectory()); - - if (r.wasOk()) - r = createDirectoryInternal (fullPath.trimCharactersAtEnd (separatorString)); - - return r; -} - -//============================================================================== -Time File::getLastModificationTime() const { int64 m, a, c; getFileTimesInternal (m, a, c); return Time (m); } -Time File::getLastAccessTime() const { int64 m, a, c; getFileTimesInternal (m, a, c); return Time (a); } -Time File::getCreationTime() const { int64 m, a, c; getFileTimesInternal (m, a, c); return Time (c); } - -bool File::setLastModificationTime (Time t) const { return setFileTimesInternal (t.toMilliseconds(), 0, 0); } -bool File::setLastAccessTime (Time t) const { return setFileTimesInternal (0, t.toMilliseconds(), 0); } -bool File::setCreationTime (Time t) const { return setFileTimesInternal (0, 0, t.toMilliseconds()); } - -//============================================================================== -bool File::loadFileAsData (MemoryBlock& destBlock) const -{ - if (! existsAsFile()) - return false; - - FileInputStream in (*this); - return in.openedOk() && getSize() == (int64) in.readIntoMemoryBlock (destBlock); -} - -String File::loadFileAsString() const -{ - if (! existsAsFile()) - return String(); - - FileInputStream in (*this); - return in.openedOk() ? in.readEntireStreamAsString() - : String(); -} - -void File::readLines (StringArray& destLines) const -{ - destLines.addLines (loadFileAsString()); -} - -//============================================================================== -int File::findChildFiles (Array& results, - const int whatToLookFor, - const bool searchRecursively, - const String& wildCardPattern) const -{ - int total = 0; - - for (DirectoryIterator di (*this, searchRecursively, wildCardPattern, whatToLookFor); di.next();) - { - results.add (di.getFile()); - ++total; - } - - return total; -} - -int File::getNumberOfChildFiles (const int whatToLookFor, const String& wildCardPattern) const -{ - int total = 0; - - for (DirectoryIterator di (*this, false, wildCardPattern, whatToLookFor); di.next();) - ++total; - - return total; -} - -bool File::containsSubDirectories() const -{ - if (! isDirectory()) - return false; - - DirectoryIterator di (*this, false, "*", findDirectories); - return di.next(); -} - -//============================================================================== -File File::getNonexistentChildFile (const String& suggestedPrefix, - const String& suffix, - bool putNumbersInBrackets) const -{ - File f (getChildFile (suggestedPrefix + suffix)); - - if (f.exists()) - { - int number = 1; - String prefix (suggestedPrefix); - - // remove any bracketed numbers that may already be on the end.. - if (prefix.trim().endsWithChar (')')) - { - putNumbersInBrackets = true; - - const int openBracks = prefix.lastIndexOfChar ('('); - const int closeBracks = prefix.lastIndexOfChar (')'); - - if (openBracks > 0 - && closeBracks > openBracks - && prefix.substring (openBracks + 1, closeBracks).containsOnly ("0123456789")) - { - number = prefix.substring (openBracks + 1, closeBracks).getIntValue(); - prefix = prefix.substring (0, openBracks); - } - } - - // also use brackets if it ends in a digit. - putNumbersInBrackets = putNumbersInBrackets - || CharacterFunctions::isDigit (prefix.getLastCharacter()); - - do - { - String newName (prefix); - - if (putNumbersInBrackets) - newName << '(' << ++number << ')'; - else - newName << ++number; - - f = getChildFile (newName + suffix); - - } while (f.exists()); - } - - return f; -} - -File File::getNonexistentSibling (const bool putNumbersInBrackets) const -{ - if (! exists()) - return *this; - - return getParentDirectory().getNonexistentChildFile (getFileNameWithoutExtension(), - getFileExtension(), - putNumbersInBrackets); -} - -//============================================================================== -String File::getFileExtension() const -{ - const int indexOfDot = fullPath.lastIndexOfChar ('.'); - - if (indexOfDot > fullPath.lastIndexOfChar (separator)) - return fullPath.substring (indexOfDot); - - return String(); -} - -bool File::hasFileExtension (StringRef possibleSuffix) const -{ - if (possibleSuffix.isEmpty()) - return fullPath.lastIndexOfChar ('.') <= fullPath.lastIndexOfChar (separator); - - const int semicolon = possibleSuffix.text.indexOf ((juce_wchar) ';'); - - if (semicolon >= 0) - return hasFileExtension (String (possibleSuffix.text).substring (0, semicolon).trimEnd()) - || hasFileExtension ((possibleSuffix.text + (semicolon + 1)).findEndOfWhitespace()); - - if (fullPath.endsWithIgnoreCase (possibleSuffix)) - { - if (possibleSuffix.text[0] == '.') - return true; - - const int dotPos = fullPath.length() - possibleSuffix.length() - 1; - - if (dotPos >= 0) - return fullPath [dotPos] == '.'; - } - - return false; -} - -File File::withFileExtension (StringRef newExtension) const -{ - if (fullPath.isEmpty()) - return File(); - - String filePart (getFileName()); - - const int i = filePart.lastIndexOfChar ('.'); - if (i >= 0) - filePart = filePart.substring (0, i); - - if (newExtension.isNotEmpty() && newExtension.text[0] != '.') - filePart << '.'; - - return getSiblingFile (filePart + newExtension); -} - -//============================================================================== -bool File::startAsProcess (const String& parameters) const -{ - return exists() && Process::openDocument (fullPath, parameters); -} - -//============================================================================== -FileInputStream* File::createInputStream() const -{ - ScopedPointer fin (new FileInputStream (*this)); - - if (fin->openedOk()) - return fin.release(); - - return nullptr; -} - -FileOutputStream* File::createOutputStream (const size_t bufferSize) const -{ - ScopedPointer out (new FileOutputStream (*this, bufferSize)); - - return out->failedToOpen() ? nullptr - : out.release(); -} - -//============================================================================== -bool File::appendData (const void* const dataToAppend, - const size_t numberOfBytes) const -{ - jassert (((ssize_t) numberOfBytes) >= 0); - - if (numberOfBytes == 0) - return true; - - FileOutputStream out (*this, 8192); - return out.openedOk() && out.write (dataToAppend, numberOfBytes); -} - -bool File::replaceWithData (const void* const dataToWrite, - const size_t numberOfBytes) const -{ - if (numberOfBytes == 0) - return deleteFile(); - - TemporaryFile tempFile (*this, TemporaryFile::useHiddenFile); - tempFile.getFile().appendData (dataToWrite, numberOfBytes); - return tempFile.overwriteTargetFileWithTemporary(); -} - -bool File::appendText (const String& text, - const bool asUnicode, - const bool writeUnicodeHeaderBytes) const -{ - FileOutputStream out (*this); - - if (out.failedToOpen()) - return false; - - out.writeText (text, asUnicode, writeUnicodeHeaderBytes); - return true; -} - -bool File::replaceWithText (const String& textToWrite, - const bool asUnicode, - const bool writeUnicodeHeaderBytes) const -{ - TemporaryFile tempFile (*this, TemporaryFile::useHiddenFile); - tempFile.getFile().appendText (textToWrite, asUnicode, writeUnicodeHeaderBytes); - return tempFile.overwriteTargetFileWithTemporary(); -} - -bool File::hasIdenticalContentTo (const File& other) const -{ - if (other == *this) - return true; - - if (getSize() == other.getSize() && existsAsFile() && other.existsAsFile()) - { - FileInputStream in1 (*this), in2 (other); - - if (in1.openedOk() && in2.openedOk()) - { - const int bufferSize = 4096; - HeapBlock buffer1 (bufferSize), buffer2 (bufferSize); - - for (;;) - { - const int num1 = in1.read (buffer1, bufferSize); - const int num2 = in2.read (buffer2, bufferSize); - - if (num1 != num2) - break; - - if (num1 <= 0) - return true; - - if (memcmp (buffer1, buffer2, (size_t) num1) != 0) - break; - } - } - } - - return false; -} - -//============================================================================== -String File::createLegalPathName (const String& original) -{ - String s (original); - String start; - - if (s.isNotEmpty() && s[1] == ':') - { - start = s.substring (0, 2); - s = s.substring (2); - } - - return start + s.removeCharacters ("\"#@,;:<>*^|?") - .substring (0, 1024); -} - -String File::createLegalFileName (const String& original) -{ - String s (original.removeCharacters ("\"#@,;:<>*^|?\\/")); - - const int maxLength = 128; // only the length of the filename, not the whole path - const int len = s.length(); - - if (len > maxLength) - { - const int lastDot = s.lastIndexOfChar ('.'); - - if (lastDot > jmax (0, len - 12)) - { - s = s.substring (0, maxLength - (len - lastDot)) - + s.substring (lastDot); - } - else - { - s = s.substring (0, maxLength); - } - } - - return s; -} - -//============================================================================== -static int countNumberOfSeparators (String::CharPointerType s) -{ - int num = 0; - - for (;;) - { - const juce_wchar c = s.getAndAdvance(); - - if (c == 0) - break; - - if (c == File::separator) - ++num; - } - - return num; -} - -String File::getRelativePathFrom (const File& dir) const -{ - String thisPath (fullPath); - - while (thisPath.endsWithChar (separator)) - thisPath = thisPath.dropLastCharacters (1); - - String dirPath (addTrailingSeparator (dir.existsAsFile() ? dir.getParentDirectory().getFullPathName() - : dir.fullPath)); - - int commonBitLength = 0; - String::CharPointerType thisPathAfterCommon (thisPath.getCharPointer()); - String::CharPointerType dirPathAfterCommon (dirPath.getCharPointer()); - - { - String::CharPointerType thisPathIter (thisPath.getCharPointer()); - String::CharPointerType dirPathIter (dirPath.getCharPointer()); - - for (int i = 0;;) - { - const juce_wchar c1 = thisPathIter.getAndAdvance(); - const juce_wchar c2 = dirPathIter.getAndAdvance(); - - #if NAMES_ARE_CASE_SENSITIVE - if (c1 != c2 - #else - if ((c1 != c2 && CharacterFunctions::toLowerCase (c1) != CharacterFunctions::toLowerCase (c2)) - #endif - || c1 == 0) - break; - - ++i; - - if (c1 == separator) - { - thisPathAfterCommon = thisPathIter; - dirPathAfterCommon = dirPathIter; - commonBitLength = i; - } - } - } - - // if the only common bit is the root, then just return the full path.. - if (commonBitLength == 0 || (commonBitLength == 1 && thisPath[1] == separator)) - return fullPath; - - const int numUpDirectoriesNeeded = countNumberOfSeparators (dirPathAfterCommon); - - if (numUpDirectoriesNeeded == 0) - return thisPathAfterCommon; - - #if JUCE_WINDOWS - String s (String::repeatedString ("..\\", numUpDirectoriesNeeded)); - #else - String s (String::repeatedString ("../", numUpDirectoriesNeeded)); - #endif - s.appendCharPointer (thisPathAfterCommon); - return s; -} - -//============================================================================== -File File::createTempFile (StringRef fileNameEnding) -{ - const File tempFile (getSpecialLocation (tempDirectory) - .getChildFile ("temp_" + String::toHexString (Random::getSystemRandom().nextInt())) - .withFileExtension (fileNameEnding)); - - if (tempFile.exists()) - return createTempFile (fileNameEnding); - - return tempFile; -} - -//============================================================================== -MemoryMappedFile::MemoryMappedFile (const File& file, MemoryMappedFile::AccessMode mode) - : address (nullptr), range (0, file.getSize()), fileHandle (0) -{ - openInternal (file, mode); -} - -MemoryMappedFile::MemoryMappedFile (const File& file, const Range& fileRange, AccessMode mode) - : address (nullptr), range (fileRange.getIntersectionWith (Range (0, file.getSize()))), fileHandle (0) -{ - openInternal (file, mode); -} - - -//============================================================================== -#if JUCE_UNIT_TESTS - -class FileTests : public UnitTest -{ -public: - FileTests() : UnitTest ("Files") {} - - void runTest() - { - beginTest ("Reading"); - - const File home (File::getSpecialLocation (File::userHomeDirectory)); - const File temp (File::getSpecialLocation (File::tempDirectory)); - - expect (! File::nonexistent.exists()); - expect (home.isDirectory()); - expect (home.exists()); - expect (! home.existsAsFile()); - expect (File::getSpecialLocation (File::userDocumentsDirectory).isDirectory()); - expect (File::getSpecialLocation (File::userApplicationDataDirectory).isDirectory()); - expect (File::getSpecialLocation (File::currentExecutableFile).exists()); - expect (File::getSpecialLocation (File::currentApplicationFile).exists()); - expect (File::getSpecialLocation (File::invokedExecutableFile).exists()); - expect (home.getVolumeTotalSize() > 1024 * 1024); - expect (home.getBytesFreeOnVolume() > 0); - expect (! home.isHidden()); - expect (home.isOnHardDisk()); - expect (! home.isOnCDRomDrive()); - expect (File::getCurrentWorkingDirectory().exists()); - expect (home.setAsCurrentWorkingDirectory()); - expect (File::getCurrentWorkingDirectory() == home); - - { - Array roots; - File::findFileSystemRoots (roots); - expect (roots.size() > 0); - - int numRootsExisting = 0; - for (int i = 0; i < roots.size(); ++i) - if (roots[i].exists()) - ++numRootsExisting; - - // (on windows, some of the drives may not contain media, so as long as at least one is ok..) - expect (numRootsExisting > 0); - } - - beginTest ("Writing"); - - File demoFolder (temp.getChildFile ("Juce UnitTests Temp Folder.folder")); - expect (demoFolder.deleteRecursively()); - expect (demoFolder.createDirectory()); - expect (demoFolder.isDirectory()); - expect (demoFolder.getParentDirectory() == temp); - expect (temp.isDirectory()); - - { - Array files; - temp.findChildFiles (files, File::findFilesAndDirectories, false, "*"); - expect (files.contains (demoFolder)); - } - - { - Array files; - temp.findChildFiles (files, File::findDirectories, true, "*.folder"); - expect (files.contains (demoFolder)); - } - - File tempFile (demoFolder.getNonexistentChildFile ("test", ".txt", false)); - - expect (tempFile.getFileExtension() == ".txt"); - expect (tempFile.hasFileExtension (".txt")); - expect (tempFile.hasFileExtension ("txt")); - expect (tempFile.withFileExtension ("xyz").hasFileExtension (".xyz")); - expect (tempFile.withFileExtension ("xyz").hasFileExtension ("abc;xyz;foo")); - expect (tempFile.withFileExtension ("xyz").hasFileExtension ("xyz;foo")); - expect (! tempFile.withFileExtension ("h").hasFileExtension ("bar;foo;xx")); - expect (tempFile.getSiblingFile ("foo").isAChildOf (temp)); - expect (tempFile.hasWriteAccess()); - - { - FileOutputStream fo (tempFile); - fo.write ("0123456789", 10); - } - - expect (tempFile.exists()); - expect (tempFile.getSize() == 10); - expect (std::abs ((int) (tempFile.getLastModificationTime().toMilliseconds() - Time::getCurrentTime().toMilliseconds())) < 3000); - expectEquals (tempFile.loadFileAsString(), String ("0123456789")); - expect (! demoFolder.containsSubDirectories()); - - expectEquals (tempFile.getRelativePathFrom (demoFolder.getParentDirectory()), demoFolder.getFileName() + File::separatorString + tempFile.getFileName()); - expectEquals (demoFolder.getParentDirectory().getRelativePathFrom (tempFile), ".." + File::separatorString + ".." + File::separatorString + demoFolder.getParentDirectory().getFileName()); - - expect (demoFolder.getNumberOfChildFiles (File::findFiles) == 1); - expect (demoFolder.getNumberOfChildFiles (File::findFilesAndDirectories) == 1); - expect (demoFolder.getNumberOfChildFiles (File::findDirectories) == 0); - demoFolder.getNonexistentChildFile ("tempFolder", "", false).createDirectory(); - expect (demoFolder.getNumberOfChildFiles (File::findDirectories) == 1); - expect (demoFolder.getNumberOfChildFiles (File::findFilesAndDirectories) == 2); - expect (demoFolder.containsSubDirectories()); - - expect (tempFile.hasWriteAccess()); - tempFile.setReadOnly (true); - expect (! tempFile.hasWriteAccess()); - tempFile.setReadOnly (false); - expect (tempFile.hasWriteAccess()); - - Time t (Time::getCurrentTime()); - tempFile.setLastModificationTime (t); - Time t2 = tempFile.getLastModificationTime(); - expect (std::abs ((int) (t2.toMilliseconds() - t.toMilliseconds())) <= 1000); - - { - MemoryBlock mb; - tempFile.loadFileAsData (mb); - expect (mb.getSize() == 10); - expect (mb[0] == '0'); - } - - { - expect (tempFile.getSize() == 10); - FileOutputStream fo (tempFile); - expect (fo.openedOk()); - - expect (fo.setPosition (7)); - expect (fo.truncate().wasOk()); - expect (tempFile.getSize() == 7); - fo.write ("789", 3); - fo.flush(); - expect (tempFile.getSize() == 10); - } - - beginTest ("Memory-mapped files"); - - { - MemoryMappedFile mmf (tempFile, MemoryMappedFile::readOnly); - expect (mmf.getSize() == 10); - expect (mmf.getData() != nullptr); - expect (memcmp (mmf.getData(), "0123456789", 10) == 0); - } - - { - const File tempFile2 (tempFile.getNonexistentSibling (false)); - expect (tempFile2.create()); - expect (tempFile2.appendData ("xxxxxxxxxx", 10)); - - { - MemoryMappedFile mmf (tempFile2, MemoryMappedFile::readWrite); - expect (mmf.getSize() == 10); - expect (mmf.getData() != nullptr); - memcpy (mmf.getData(), "abcdefghij", 10); - } - - { - MemoryMappedFile mmf (tempFile2, MemoryMappedFile::readWrite); - expect (mmf.getSize() == 10); - expect (mmf.getData() != nullptr); - expect (memcmp (mmf.getData(), "abcdefghij", 10) == 0); - } - - expect (tempFile2.deleteFile()); - } - - beginTest ("More writing"); - - expect (tempFile.appendData ("abcdefghij", 10)); - expect (tempFile.getSize() == 20); - expect (tempFile.replaceWithData ("abcdefghij", 10)); - expect (tempFile.getSize() == 10); - - File tempFile2 (tempFile.getNonexistentSibling (false)); - expect (tempFile.copyFileTo (tempFile2)); - expect (tempFile2.exists()); - expect (tempFile2.hasIdenticalContentTo (tempFile)); - expect (tempFile.deleteFile()); - expect (! tempFile.exists()); - expect (tempFile2.moveFileTo (tempFile)); - expect (tempFile.exists()); - expect (! tempFile2.exists()); - - expect (demoFolder.deleteRecursively()); - expect (! demoFolder.exists()); - } -}; - -static FileTests fileUnitTests; - -#endif diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/files/juce_File.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/files/juce_File.h deleted file mode 100644 index 57d970fff0..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/files/juce_File.h +++ /dev/null @@ -1,973 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_FILE_H_INCLUDED -#define JUCE_FILE_H_INCLUDED - - -//============================================================================== -/** - Represents a local file or directory. - - This class encapsulates the absolute pathname of a file or directory, and - has methods for finding out about the file and changing its properties. - - To read or write to the file, there are methods for returning an input or - output stream. - - @see FileInputStream, FileOutputStream -*/ -class JUCE_API File -{ -public: - //============================================================================== - /** Creates an (invalid) file object. - - The file is initially set to an empty path, so getFullPath() will return - an empty string, and comparing the file to File::nonexistent will return - true. - - You can use its operator= method to point it at a proper file. - */ - File() noexcept {} - - /** Creates a file from an absolute path. - - If the path supplied is a relative path, it is taken to be relative - to the current working directory (see File::getCurrentWorkingDirectory()), - but this isn't a recommended way of creating a file, because you - never know what the CWD is going to be. - - On the Mac/Linux, the path can include "~" notation for referring to - user home directories. - */ - File (const String& absolutePath); - - /** Creates a copy of another file object. */ - File (const File&); - - /** Destructor. */ - ~File() noexcept {} - - /** Sets the file based on an absolute pathname. - - If the path supplied is a relative path, it is taken to be relative - to the current working directory (see File::getCurrentWorkingDirectory()), - but this isn't a recommended way of creating a file, because you - never know what the CWD is going to be. - - On the Mac/Linux, the path can include "~" notation for referring to - user home directories. - */ - File& operator= (const String& newAbsolutePath); - - /** Copies from another file object. */ - File& operator= (const File& otherFile); - - #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS - File (File&&) noexcept; - File& operator= (File&&) noexcept; - #endif - - //============================================================================== - /** This static constant is used for referring to an 'invalid' file. */ - static const File nonexistent; - - //============================================================================== - /** Checks whether the file actually exists. - - @returns true if the file exists, either as a file or a directory. - @see existsAsFile, isDirectory - */ - bool exists() const; - - /** Checks whether the file exists and is a file rather than a directory. - - @returns true only if this is a real file, false if it's a directory - or doesn't exist - @see exists, isDirectory - */ - bool existsAsFile() const; - - /** Checks whether the file is a directory that exists. - - @returns true only if the file is a directory which actually exists, so - false if it's a file or doesn't exist at all - @see exists, existsAsFile - */ - bool isDirectory() const; - - /** Returns the size of the file in bytes. - - @returns the number of bytes in the file, or 0 if it doesn't exist. - */ - int64 getSize() const; - - /** Utility function to convert a file size in bytes to a neat string description. - - So for example 100 would return "100 bytes", 2000 would return "2 KB", - 2000000 would produce "2 MB", etc. - */ - static String descriptionOfSizeInBytes (int64 bytes); - - //============================================================================== - /** Returns the complete, absolute path of this file. - - This includes the filename and all its parent folders. On Windows it'll - also include the drive letter prefix; on Mac or Linux it'll be a complete - path starting from the root folder. - - If you just want the file's name, you should use getFileName() or - getFileNameWithoutExtension(). - - @see getFileName, getRelativePathFrom - */ - const String& getFullPathName() const noexcept { return fullPath; } - - /** Returns the last section of the pathname. - - Returns just the final part of the path - e.g. if the whole path - is "/moose/fish/foo.txt" this will return "foo.txt". - - For a directory, it returns the final part of the path - e.g. for the - directory "/moose/fish" it'll return "fish". - - If the filename begins with a dot, it'll return the whole filename, e.g. for - "/moose/.fish", it'll return ".fish" - - @see getFullPathName, getFileNameWithoutExtension - */ - String getFileName() const; - - /** Creates a relative path that refers to a file relatively to a given directory. - - e.g. File ("/moose/foo.txt").getRelativePathFrom (File ("/moose/fish/haddock")) - would return "../../foo.txt". - - If it's not possible to navigate from one file to the other, an absolute - path is returned. If the paths are invalid, an empty string may also be - returned. - - @param directoryToBeRelativeTo the directory which the resultant string will - be relative to. If this is actually a file rather than - a directory, its parent directory will be used instead. - If it doesn't exist, it's assumed to be a directory. - @see getChildFile, isAbsolutePath - */ - String getRelativePathFrom (const File& directoryToBeRelativeTo) const; - - //============================================================================== - /** Returns the file's extension. - - Returns the file extension of this file, also including the dot. - - e.g. "/moose/fish/foo.txt" would return ".txt" - - @see hasFileExtension, withFileExtension, getFileNameWithoutExtension - */ - String getFileExtension() const; - - /** Checks whether the file has a given extension. - - @param extensionToTest the extension to look for - it doesn't matter whether or - not this string has a dot at the start, so ".wav" and "wav" - will have the same effect. To compare with multiple extensions, this - parameter can contain multiple strings, separated by semi-colons - - so, for example: hasFileExtension (".jpeg;png;gif") would return - true if the file has any of those three extensions. - - @see getFileExtension, withFileExtension, getFileNameWithoutExtension - */ - bool hasFileExtension (StringRef extensionToTest) const; - - /** Returns a version of this file with a different file extension. - - e.g. File ("/moose/fish/foo.txt").withFileExtension ("html") returns "/moose/fish/foo.html" - - @param newExtension the new extension, either with or without a dot at the start (this - doesn't make any difference). To get remove a file's extension altogether, - pass an empty string into this function. - - @see getFileName, getFileExtension, hasFileExtension, getFileNameWithoutExtension - */ - File withFileExtension (StringRef newExtension) const; - - /** Returns the last part of the filename, without its file extension. - - e.g. for "/moose/fish/foo.txt" this will return "foo". - - @see getFileName, getFileExtension, hasFileExtension, withFileExtension - */ - String getFileNameWithoutExtension() const; - - //============================================================================== - /** Returns a 32-bit hash-code that identifies this file. - - This is based on the filename. Obviously it's possible, although unlikely, that - two files will have the same hash-code. - */ - int hashCode() const; - - /** Returns a 64-bit hash-code that identifies this file. - - This is based on the filename. Obviously it's possible, although unlikely, that - two files will have the same hash-code. - */ - int64 hashCode64() const; - - //============================================================================== - /** Returns a file that represents a relative (or absolute) sub-path of the current one. - - This will find a child file or directory of the current object. - - e.g. - File ("/moose/fish").getChildFile ("foo.txt") will produce "/moose/fish/foo.txt". - File ("/moose/fish").getChildFile ("haddock/foo.txt") will produce "/moose/fish/haddock/foo.txt". - File ("/moose/fish").getChildFile ("../foo.txt") will produce "/moose/foo.txt". - - If the string is actually an absolute path, it will be treated as such, e.g. - File ("/moose/fish").getChildFile ("/foo.txt") will produce "/foo.txt" - - @see getSiblingFile, getParentDirectory, getRelativePathFrom, isAChildOf - */ - File getChildFile (StringRef relativeOrAbsolutePath) const; - - /** Returns a file which is in the same directory as this one. - - This is equivalent to getParentDirectory().getChildFile (name). - - @see getChildFile, getParentDirectory - */ - File getSiblingFile (StringRef siblingFileName) const; - - //============================================================================== - /** Returns the directory that contains this file or directory. - - e.g. for "/moose/fish/foo.txt" this will return "/moose/fish". - */ - File getParentDirectory() const; - - /** Checks whether a file is somewhere inside a directory. - - Returns true if this file is somewhere inside a subdirectory of the directory - that is passed in. Neither file actually has to exist, because the function - just checks the paths for similarities. - - e.g. File ("/moose/fish/foo.txt").isAChildOf ("/moose") is true. - File ("/moose/fish/foo.txt").isAChildOf ("/moose/fish") is also true. - */ - bool isAChildOf (const File& potentialParentDirectory) const; - - //============================================================================== - /** Chooses a filename relative to this one that doesn't already exist. - - If this file is a directory, this will return a child file of this - directory that doesn't exist, by adding numbers to a prefix and suffix until - it finds one that isn't already there. - - If the prefix + the suffix doesn't exist, it won't bother adding a number. - - e.g. File ("/moose/fish").getNonexistentChildFile ("foo", ".txt", true) might - return "/moose/fish/foo(2).txt" if there's already a file called "foo.txt". - - @param prefix the string to use for the filename before the number - @param suffix the string to add to the filename after the number - @param putNumbersInBrackets if true, this will create filenames in the - format "prefix(number)suffix", if false, it will leave the - brackets out. - */ - File getNonexistentChildFile (const String& prefix, - const String& suffix, - bool putNumbersInBrackets = true) const; - - /** Chooses a filename for a sibling file to this one that doesn't already exist. - - If this file doesn't exist, this will just return itself, otherwise it - will return an appropriate sibling that doesn't exist, e.g. if a file - "/moose/fish/foo.txt" exists, this might return "/moose/fish/foo(2).txt". - - @param putNumbersInBrackets whether to add brackets around the numbers that - get appended to the new filename. - */ - File getNonexistentSibling (bool putNumbersInBrackets = true) const; - - //============================================================================== - /** Compares the pathnames for two files. */ - bool operator== (const File&) const; - /** Compares the pathnames for two files. */ - bool operator!= (const File&) const; - /** Compares the pathnames for two files. */ - bool operator< (const File&) const; - /** Compares the pathnames for two files. */ - bool operator> (const File&) const; - - //============================================================================== - /** Checks whether a file can be created or written to. - - @returns true if it's possible to create and write to this file. If the file - doesn't already exist, this will check its parent directory to - see if writing is allowed. - @see setReadOnly - */ - bool hasWriteAccess() const; - - /** Changes the write-permission of a file or directory. - - @param shouldBeReadOnly whether to add or remove write-permission - @param applyRecursively if the file is a directory and this is true, it will - recurse through all the subfolders changing the permissions - of all files - @returns true if it manages to change the file's permissions. - @see hasWriteAccess - */ - bool setReadOnly (bool shouldBeReadOnly, - bool applyRecursively = false) const; - - /** Returns true if this file is a hidden or system file. - The criteria for deciding whether a file is hidden are platform-dependent. - */ - bool isHidden() const; - - /** Returns true if this file is a link or alias that can be followed using getLinkedTarget(). */ - bool isLink() const; - - /** If this file is a link or alias, this returns the file that it points to. - If the file isn't actually link, it'll just return itself. - */ - File getLinkedTarget() const; - - /** Returns a unique identifier for the file, if one is available. - - Depending on the OS and file-system, this may be a unix inode number or - a win32 file identifier, or 0 if it fails to find one. The number will - be unique on the filesystem, but not globally. - */ - uint64 getFileIdentifier() const; - - //============================================================================== - /** Returns the last modification time of this file. - - @returns the time, or an invalid time if the file doesn't exist. - @see setLastModificationTime, getLastAccessTime, getCreationTime - */ - Time getLastModificationTime() const; - - /** Returns the last time this file was accessed. - - @returns the time, or an invalid time if the file doesn't exist. - @see setLastAccessTime, getLastModificationTime, getCreationTime - */ - Time getLastAccessTime() const; - - /** Returns the time that this file was created. - - @returns the time, or an invalid time if the file doesn't exist. - @see getLastModificationTime, getLastAccessTime - */ - Time getCreationTime() const; - - /** Changes the modification time for this file. - - @param newTime the time to apply to the file - @returns true if it manages to change the file's time. - @see getLastModificationTime, setLastAccessTime, setCreationTime - */ - bool setLastModificationTime (Time newTime) const; - - /** Changes the last-access time for this file. - - @param newTime the time to apply to the file - @returns true if it manages to change the file's time. - @see getLastAccessTime, setLastModificationTime, setCreationTime - */ - bool setLastAccessTime (Time newTime) const; - - /** Changes the creation date for this file. - - @param newTime the time to apply to the file - @returns true if it manages to change the file's time. - @see getCreationTime, setLastModificationTime, setLastAccessTime - */ - bool setCreationTime (Time newTime) const; - - /** If possible, this will try to create a version string for the given file. - - The OS may be able to look at the file and give a version for it - e.g. with - executables, bundles, dlls, etc. If no version is available, this will - return an empty string. - */ - String getVersion() const; - - //============================================================================== - /** Creates an empty file if it doesn't already exist. - - If the file that this object refers to doesn't exist, this will create a file - of zero size. - - If it already exists or is a directory, this method will do nothing. - - @returns true if the file has been created (or if it already existed). - @see createDirectory - */ - Result create() const; - - /** Creates a new directory for this filename. - - This will try to create the file as a directory, and fill also create - any parent directories it needs in order to complete the operation. - - @returns a result to indicate whether the directory was created successfully, or - an error message if it failed. - @see create - */ - Result createDirectory() const; - - /** Deletes a file. - - If this file is actually a directory, it may not be deleted correctly if it - contains files. See deleteRecursively() as a better way of deleting directories. - - @returns true if the file has been successfully deleted (or if it didn't exist to - begin with). - @see deleteRecursively - */ - bool deleteFile() const; - - /** Deletes a file or directory and all its subdirectories. - - If this file is a directory, this will try to delete it and all its subfolders. If - it's just a file, it will just try to delete the file. - - @returns true if the file and all its subfolders have been successfully deleted - (or if it didn't exist to begin with). - @see deleteFile - */ - bool deleteRecursively() const; - - /** Moves this file or folder to the trash. - - @returns true if the operation succeeded. It could fail if the trash is full, or - if the file is write-protected, so you should check the return value - and act appropriately. - */ - bool moveToTrash() const; - - /** Moves or renames a file. - - Tries to move a file to a different location. - If the target file already exists, this will attempt to delete it first, and - will fail if this can't be done. - - Note that the destination file isn't the directory to put it in, it's the actual - filename that you want the new file to have. - - @returns true if the operation succeeds - */ - bool moveFileTo (const File& targetLocation) const; - - /** Copies a file. - - Tries to copy a file to a different location. - If the target file already exists, this will attempt to delete it first, and - will fail if this can't be done. - - @returns true if the operation succeeds - */ - bool copyFileTo (const File& targetLocation) const; - - /** Copies a directory. - - Tries to copy an entire directory, recursively. - - If this file isn't a directory or if any target files can't be created, this - will return false. - - @param newDirectory the directory that this one should be copied to. Note that this - is the name of the actual directory to create, not the directory - into which the new one should be placed, so there must be enough - write privileges to create it if it doesn't exist. Any files inside - it will be overwritten by similarly named ones that are copied. - */ - bool copyDirectoryTo (const File& newDirectory) const; - - //============================================================================== - /** Used in file searching, to specify whether to return files, directories, or both. - */ - enum TypesOfFileToFind - { - findDirectories = 1, /**< Use this flag to indicate that you want to find directories. */ - findFiles = 2, /**< Use this flag to indicate that you want to find files. */ - findFilesAndDirectories = 3, /**< Use this flag to indicate that you want to find both files and directories. */ - ignoreHiddenFiles = 4 /**< Add this flag to avoid returning any hidden files in the results. */ - }; - - /** Searches inside a directory for files matching a wildcard pattern. - - Assuming that this file is a directory, this method will search it - for either files or subdirectories whose names match a filename pattern. - - @param results an array to which File objects will be added for the - files that the search comes up with - @param whatToLookFor a value from the TypesOfFileToFind enum, specifying whether to - return files, directories, or both. If the ignoreHiddenFiles flag - is also added to this value, hidden files won't be returned - @param searchRecursively if true, all subdirectories will be recursed into to do - an exhaustive search - @param wildCardPattern the filename pattern to search for, e.g. "*.txt" - @returns the number of results that have been found - - @see getNumberOfChildFiles, DirectoryIterator - */ - int findChildFiles (Array& results, - int whatToLookFor, - bool searchRecursively, - const String& wildCardPattern = "*") const; - - /** Searches inside a directory and counts how many files match a wildcard pattern. - - Assuming that this file is a directory, this method will search it - for either files or subdirectories whose names match a filename pattern, - and will return the number of matches found. - - This isn't a recursive call, and will only search this directory, not - its children. - - @param whatToLookFor a value from the TypesOfFileToFind enum, specifying whether to - count files, directories, or both. If the ignoreHiddenFiles flag - is also added to this value, hidden files won't be counted - @param wildCardPattern the filename pattern to search for, e.g. "*.txt" - @returns the number of matches found - @see findChildFiles, DirectoryIterator - */ - int getNumberOfChildFiles (int whatToLookFor, - const String& wildCardPattern = "*") const; - - /** Returns true if this file is a directory that contains one or more subdirectories. - @see isDirectory, findChildFiles - */ - bool containsSubDirectories() const; - - //============================================================================== - /** Creates a stream to read from this file. - - @returns a stream that will read from this file (initially positioned at the - start of the file), or nullptr if the file can't be opened for some reason - @see createOutputStream, loadFileAsData - */ - FileInputStream* createInputStream() const; - - /** Creates a stream to write to this file. - - If the file exists, the stream that is returned will be positioned ready for - writing at the end of the file, so you might want to use deleteFile() first - to write to an empty file. - - @returns a stream that will write to this file (initially positioned at the - end of the file), or nullptr if the file can't be opened for some reason - @see createInputStream, appendData, appendText - */ - FileOutputStream* createOutputStream (size_t bufferSize = 0x8000) const; - - //============================================================================== - /** Loads a file's contents into memory as a block of binary data. - - Of course, trying to load a very large file into memory will blow up, so - it's better to check first. - - @param result the data block to which the file's contents should be appended - note - that if the memory block might already contain some data, you - might want to clear it first - @returns true if the file could all be read into memory - */ - bool loadFileAsData (MemoryBlock& result) const; - - /** Reads a file into memory as a string. - - Attempts to load the entire file as a zero-terminated string. - - This makes use of InputStream::readEntireStreamAsString, which can - read either UTF-16 or UTF-8 file formats. - */ - String loadFileAsString() const; - - /** Reads the contents of this file as text and splits it into lines, which are - appended to the given StringArray. - */ - void readLines (StringArray& destLines) const; - - //============================================================================== - /** Appends a block of binary data to the end of the file. - - This will try to write the given buffer to the end of the file. - - @returns false if it can't write to the file for some reason - */ - bool appendData (const void* dataToAppend, - size_t numberOfBytes) const; - - /** Replaces this file's contents with a given block of data. - - This will delete the file and replace it with the given data. - - A nice feature of this method is that it's safe - instead of deleting - the file first and then re-writing it, it creates a new temporary file, - writes the data to that, and then moves the new file to replace the existing - file. This means that if the power gets pulled out or something crashes, - you're a lot less likely to end up with a corrupted or unfinished file.. - - Returns true if the operation succeeds, or false if it fails. - - @see appendText - */ - bool replaceWithData (const void* dataToWrite, - size_t numberOfBytes) const; - - /** Appends a string to the end of the file. - - This will try to append a text string to the file, as either 16-bit unicode - or 8-bit characters in the default system encoding. - - It can also write the 'ff fe' unicode header bytes before the text to indicate - the endianness of the file. - - Any single \\n characters in the string are replaced with \\r\\n before it is written. - - @see replaceWithText - */ - bool appendText (const String& textToAppend, - bool asUnicode = false, - bool writeUnicodeHeaderBytes = false) const; - - /** Replaces this file's contents with a given text string. - - This will delete the file and replace it with the given text. - - A nice feature of this method is that it's safe - instead of deleting - the file first and then re-writing it, it creates a new temporary file, - writes the text to that, and then moves the new file to replace the existing - file. This means that if the power gets pulled out or something crashes, - you're a lot less likely to end up with an empty file.. - - For an explanation of the parameters here, see the appendText() method. - - Returns true if the operation succeeds, or false if it fails. - - @see appendText - */ - bool replaceWithText (const String& textToWrite, - bool asUnicode = false, - bool writeUnicodeHeaderBytes = false) const; - - /** Attempts to scan the contents of this file and compare it to another file, returning - true if this is possible and they match byte-for-byte. - */ - bool hasIdenticalContentTo (const File& other) const; - - //============================================================================== - /** Creates a set of files to represent each file root. - - e.g. on Windows this will create files for "c:\", "d:\" etc according - to which ones are available. On the Mac/Linux, this will probably - just add a single entry for "/". - */ - static void findFileSystemRoots (Array& results); - - /** Finds the name of the drive on which this file lives. - @returns the volume label of the drive, or an empty string if this isn't possible - */ - String getVolumeLabel() const; - - /** Returns the serial number of the volume on which this file lives. - @returns the serial number, or zero if there's a problem doing this - */ - int getVolumeSerialNumber() const; - - /** Returns the number of bytes free on the drive that this file lives on. - - @returns the number of bytes free, or 0 if there's a problem finding this out - @see getVolumeTotalSize - */ - int64 getBytesFreeOnVolume() const; - - /** Returns the total size of the drive that contains this file. - - @returns the total number of bytes that the volume can hold - @see getBytesFreeOnVolume - */ - int64 getVolumeTotalSize() const; - - /** Returns true if this file is on a CD or DVD drive. */ - bool isOnCDRomDrive() const; - - /** Returns true if this file is on a hard disk. - - This will fail if it's a network drive, but will still be true for - removable hard-disks. - */ - bool isOnHardDisk() const; - - /** Returns true if this file is on a removable disk drive. - - This might be a usb-drive, a CD-rom, or maybe a network drive. - */ - bool isOnRemovableDrive() const; - - //============================================================================== - /** Launches the file as a process. - - - if the file is executable, this will run it. - - - if it's a document of some kind, it will launch the document with its - default viewer application. - - - if it's a folder, it will be opened in Explorer, Finder, or equivalent. - - @see revealToUser - */ - bool startAsProcess (const String& parameters = String()) const; - - /** Opens Finder, Explorer, or whatever the OS uses, to show the user this file's location. - @see startAsProcess - */ - void revealToUser() const; - - //============================================================================== - /** A set of types of location that can be passed to the getSpecialLocation() method. - */ - enum SpecialLocationType - { - /** The user's home folder. This is the same as using File ("~"). */ - userHomeDirectory, - - /** The user's default documents folder. On Windows, this might be the user's - "My Documents" folder. On the Mac it'll be their "Documents" folder. Linux - doesn't tend to have one of these, so it might just return their home folder. - */ - userDocumentsDirectory, - - /** The folder that contains the user's desktop objects. */ - userDesktopDirectory, - - /** The most likely place where a user might store their music files. */ - userMusicDirectory, - - /** The most likely place where a user might store their movie files. */ - userMoviesDirectory, - - /** The most likely place where a user might store their picture files. */ - userPicturesDirectory, - - /** The folder in which applications store their persistent user-specific settings. - On Windows, this might be "\Documents and Settings\username\Application Data". - On the Mac, it might be "~/Library". If you're going to store your settings in here, - always create your own sub-folder to put them in, to avoid making a mess. - */ - userApplicationDataDirectory, - - /** An equivalent of the userApplicationDataDirectory folder that is shared by all users - of the computer, rather than just the current user. - - On the Mac it'll be "/Library", on Windows, it could be something like - "\Documents and Settings\All Users\Application Data". - - Depending on the setup, this folder may be read-only. - */ - commonApplicationDataDirectory, - - /** A place to put documents which are shared by all users of the machine. - On Windows this may be somewhere like "C:\Users\Public\Documents", on OSX it - will be something like "/Users/Shared". Other OSes may have no such concept - though, so be careful. - */ - commonDocumentsDirectory, - - /** The folder that should be used for temporary files. - Always delete them when you're finished, to keep the user's computer tidy! - */ - tempDirectory, - - /** Returns this application's executable file. - - If running as a plug-in or DLL, this will (where possible) be the DLL rather than the - host app. - - On the mac this will return the unix binary, not the package folder - see - currentApplicationFile for that. - - See also invokedExecutableFile, which is similar, but if the exe was launched from a - file link, invokedExecutableFile will return the name of the link. - */ - currentExecutableFile, - - /** Returns this application's location. - - If running as a plug-in or DLL, this will (where possible) be the DLL rather than the - host app. - - On the mac this will return the package folder (if it's in one), not the unix binary - that's inside it - compare with currentExecutableFile. - */ - currentApplicationFile, - - /** Returns the file that was invoked to launch this executable. - This may differ from currentExecutableFile if the app was started from e.g. a link - this - will return the name of the link that was used, whereas currentExecutableFile will return - the actual location of the target executable. - */ - invokedExecutableFile, - - /** In a plugin, this will return the path of the host executable. */ - hostApplicationPath, - - #if JUCE_WINDOWS - /** On a Windows machine, returns the location of the Windows/System32 folder. */ - windowsSystemDirectory, - #endif - - /** The directory in which applications normally get installed. - So on windows, this would be something like "c:\program files", on the - Mac "/Applications", or "/usr" on linux. - */ - globalApplicationsDirectory - }; - - /** Finds the location of a special type of file or directory, such as a home folder or - documents folder. - - @see SpecialLocationType - */ - static File JUCE_CALLTYPE getSpecialLocation (const SpecialLocationType type); - - //============================================================================== - /** Returns a temporary file in the system's temp directory. - This will try to return the name of a non-existent temp file. - To get the temp folder, you can use getSpecialLocation (File::tempDirectory). - */ - static File createTempFile (StringRef fileNameEnding); - - - //============================================================================== - /** Returns the current working directory. - @see setAsCurrentWorkingDirectory - */ - static File getCurrentWorkingDirectory(); - - /** Sets the current working directory to be this file. - - For this to work the file must point to a valid directory. - - @returns true if the current directory has been changed. - @see getCurrentWorkingDirectory - */ - bool setAsCurrentWorkingDirectory() const; - - //============================================================================== - /** The system-specific file separator character. - On Windows, this will be '\', on Mac/Linux, it'll be '/' - */ - static const juce_wchar separator; - - /** The system-specific file separator character, as a string. - On Windows, this will be '\', on Mac/Linux, it'll be '/' - */ - static const String separatorString; - - //============================================================================== - /** Returns a version of a filename with any illegal characters removed. - - This will return a copy of the given string after removing characters - that are not allowed in a legal filename, and possibly shortening the - string if it's too long. - - Because this will remove slashes, don't use it on an absolute pathname - use - createLegalPathName() for that. - - @see createLegalPathName - */ - static String createLegalFileName (const String& fileNameToFix); - - /** Returns a version of a path with any illegal characters removed. - - Similar to createLegalFileName(), but this won't remove slashes, so can - be used on a complete pathname. - - @see createLegalFileName - */ - static String createLegalPathName (const String& pathNameToFix); - - /** Indicates whether filenames are case-sensitive on the current operating system. */ - static bool areFileNamesCaseSensitive(); - - /** Returns true if the string seems to be a fully-specified absolute path. */ - static bool isAbsolutePath (StringRef path); - - /** Creates a file that simply contains this string, without doing the sanity-checking - that the normal constructors do. - - Best to avoid this unless you really know what you're doing. - */ - static File createFileWithoutCheckingPath (const String& absolutePath) noexcept; - - /** Adds a separator character to the end of a path if it doesn't already have one. */ - static String addTrailingSeparator (const String& path); - - #if JUCE_MAC || JUCE_IOS || DOXYGEN - //============================================================================== - /** OSX ONLY - Finds the OSType of a file from the its resources. */ - OSType getMacOSType() const; - - /** OSX ONLY - Returns true if this file is actually a bundle. */ - bool isBundle() const; - #endif - - #if JUCE_MAC || DOXYGEN - /** OSX ONLY - Adds this file to the OSX dock */ - void addToDock() const; - #endif - - #if JUCE_WINDOWS - /** Windows ONLY - Creates a win32 .LNK shortcut file that links to this file. */ - bool createLink (const String& description, const File& linkFileToCreate) const; - #endif - -private: - //============================================================================== - String fullPath; - - static String parseAbsolutePath (const String&); - String getPathUpToLastSlash() const; - - Result createDirectoryInternal (const String&) const; - bool copyInternal (const File&) const; - bool moveInternal (const File&) const; - bool setFileTimesInternal (int64 m, int64 a, int64 c) const; - void getFileTimesInternal (int64& m, int64& a, int64& c) const; - bool setFileReadOnlyInternal (bool) const; -}; - -#endif // JUCE_FILE_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/files/juce_FileFilter.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/files/juce_FileFilter.cpp deleted file mode 100644 index bd0bdf861b..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/files/juce_FileFilter.cpp +++ /dev/null @@ -1,41 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -FileFilter::FileFilter (const String& filterDescription) - : description (filterDescription) -{ -} - -FileFilter::~FileFilter() -{ -} - -const String& FileFilter::getDescription() const noexcept -{ - return description; -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/files/juce_FileFilter.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/files/juce_FileFilter.h deleted file mode 100644 index 4c02415c4b..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/files/juce_FileFilter.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_FILEFILTER_H_INCLUDED -#define JUCE_FILEFILTER_H_INCLUDED - - -//============================================================================== -/** - Interface for deciding which files are suitable for something. - - For example, this is used by DirectoryContentsList to select which files - go into the list. - - @see WildcardFileFilter, DirectoryContentsList, FileListComponent, FileBrowserComponent -*/ -class JUCE_API FileFilter -{ -public: - //============================================================================== - /** Creates a filter with the given description. - - The description can be returned later with the getDescription() method. - */ - FileFilter (const String& filterDescription); - - /** Destructor. */ - virtual ~FileFilter(); - - //============================================================================== - /** Returns the description that the filter was created with. */ - const String& getDescription() const noexcept; - - //============================================================================== - /** Should return true if this file is suitable for inclusion in whatever context - the object is being used. - */ - virtual bool isFileSuitable (const File& file) const = 0; - - /** Should return true if this directory is suitable for inclusion in whatever context - the object is being used. - */ - virtual bool isDirectorySuitable (const File& file) const = 0; - - -protected: - //============================================================================== - String description; -}; - - -#endif // JUCE_FILEFILTER_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/files/juce_FileInputStream.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/files/juce_FileInputStream.cpp deleted file mode 100644 index 801ccfaaf2..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/files/juce_FileInputStream.cpp +++ /dev/null @@ -1,84 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -int64 juce_fileSetPosition (void* handle, int64 pos); - - -//============================================================================== -FileInputStream::FileInputStream (const File& f) - : file (f), - fileHandle (nullptr), - currentPosition (0), - status (Result::ok()) -{ - openHandle(); -} - -int64 FileInputStream::getTotalLength() -{ - // You should always check that a stream opened successfully before using it! - jassert (openedOk()); - - return file.getSize(); -} - -int FileInputStream::read (void* buffer, int bytesToRead) -{ - // You should always check that a stream opened successfully before using it! - jassert (openedOk()); - - // The buffer should never be null, and a negative size is probably a - // sign that something is broken! - jassert (buffer != nullptr && bytesToRead >= 0); - - const size_t num = readInternal (buffer, (size_t) bytesToRead); - currentPosition += num; - - return (int) num; -} - -bool FileInputStream::isExhausted() -{ - return currentPosition >= getTotalLength(); -} - -int64 FileInputStream::getPosition() -{ - return currentPosition; -} - -bool FileInputStream::setPosition (int64 pos) -{ - // You should always check that a stream opened successfully before using it! - jassert (openedOk()); - - if (pos != currentPosition) - currentPosition = juce_fileSetPosition (fileHandle, pos); - - return currentPosition == pos; -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/files/juce_FileInputStream.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/files/juce_FileInputStream.h deleted file mode 100644 index 35963baaee..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/files/juce_FileInputStream.h +++ /dev/null @@ -1,96 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_FILEINPUTSTREAM_H_INCLUDED -#define JUCE_FILEINPUTSTREAM_H_INCLUDED - - -//============================================================================== -/** - An input stream that reads from a local file. - - @see InputStream, FileOutputStream, File::createInputStream -*/ -class JUCE_API FileInputStream : public InputStream -{ -public: - //============================================================================== - /** Creates a FileInputStream to read from the given file. - - After creating a FileInputStream, you should use openedOk() or failedToOpen() - to make sure that it's OK before trying to read from it! If it failed, you - can call getStatus() to get more error information. - */ - explicit FileInputStream (const File& fileToRead); - - /** Destructor. */ - ~FileInputStream(); - - //============================================================================== - /** Returns the file that this stream is reading from. */ - const File& getFile() const noexcept { return file; } - - /** Returns the status of the file stream. - The result will be ok if the file opened successfully. If an error occurs while - opening or reading from the file, this will contain an error message. - */ - const Result& getStatus() const noexcept { return status; } - - /** Returns true if the stream couldn't be opened for some reason. - @see getResult() - */ - bool failedToOpen() const noexcept { return status.failed(); } - - /** Returns true if the stream opened without problems. - @see getResult() - */ - bool openedOk() const noexcept { return status.wasOk(); } - - - //============================================================================== - int64 getTotalLength() override; - int read (void*, int) override; - bool isExhausted() override; - int64 getPosition() override; - bool setPosition (int64) override; - -private: - //============================================================================== - const File file; - void* fileHandle; - int64 currentPosition; - Result status; - - void openHandle(); - size_t readInternal (void*, size_t); - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (FileInputStream) -}; - - -#endif // JUCE_FILEINPUTSTREAM_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/files/juce_FileOutputStream.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/files/juce_FileOutputStream.cpp deleted file mode 100644 index 961a8d19e8..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/files/juce_FileOutputStream.cpp +++ /dev/null @@ -1,134 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -int64 juce_fileSetPosition (void* handle, int64 pos); - -//============================================================================== -FileOutputStream::FileOutputStream (const File& f, const size_t bufferSizeToUse) - : file (f), - fileHandle (nullptr), - status (Result::ok()), - currentPosition (0), - bufferSize (bufferSizeToUse), - bytesInBuffer (0), - buffer (jmax (bufferSizeToUse, (size_t) 16)) -{ - openHandle(); -} - -FileOutputStream::~FileOutputStream() -{ - flushBuffer(); - closeHandle(); -} - -int64 FileOutputStream::getPosition() -{ - return currentPosition; -} - -bool FileOutputStream::setPosition (int64 newPosition) -{ - if (newPosition != currentPosition) - { - flushBuffer(); - currentPosition = juce_fileSetPosition (fileHandle, newPosition); - } - - return newPosition == currentPosition; -} - -bool FileOutputStream::flushBuffer() -{ - bool ok = true; - - if (bytesInBuffer > 0) - { - ok = (writeInternal (buffer, bytesInBuffer) == (ssize_t) bytesInBuffer); - bytesInBuffer = 0; - } - - return ok; -} - -void FileOutputStream::flush() -{ - flushBuffer(); - flushInternal(); -} - -bool FileOutputStream::write (const void* const src, const size_t numBytes) -{ - jassert (src != nullptr && ((ssize_t) numBytes) >= 0); - - if (bytesInBuffer + numBytes < bufferSize) - { - memcpy (buffer + bytesInBuffer, src, numBytes); - bytesInBuffer += numBytes; - currentPosition += numBytes; - } - else - { - if (! flushBuffer()) - return false; - - if (numBytes < bufferSize) - { - memcpy (buffer + bytesInBuffer, src, numBytes); - bytesInBuffer += numBytes; - currentPosition += numBytes; - } - else - { - const ssize_t bytesWritten = writeInternal (src, numBytes); - - if (bytesWritten < 0) - return false; - - currentPosition += bytesWritten; - return bytesWritten == (ssize_t) numBytes; - } - } - - return true; -} - -bool FileOutputStream::writeRepeatedByte (uint8 byte, size_t numBytes) -{ - jassert (((ssize_t) numBytes) >= 0); - - if (bytesInBuffer + numBytes < bufferSize) - { - memset (buffer + bytesInBuffer, byte, numBytes); - bytesInBuffer += numBytes; - currentPosition += numBytes; - return true; - } - - return OutputStream::writeRepeatedByte (byte, numBytes); -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/files/juce_FileOutputStream.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/files/juce_FileOutputStream.h deleted file mode 100644 index f80705f23b..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/files/juce_FileOutputStream.h +++ /dev/null @@ -1,116 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_FILEOUTPUTSTREAM_H_INCLUDED -#define JUCE_FILEOUTPUTSTREAM_H_INCLUDED - - -//============================================================================== -/** - An output stream that writes into a local file. - - @see OutputStream, FileInputStream, File::createOutputStream -*/ -class JUCE_API FileOutputStream : public OutputStream -{ -public: - //============================================================================== - /** Creates a FileOutputStream. - - If the file doesn't exist, it will first be created. If the file can't be - created or opened, the failedToOpen() method will return - true. - - If the file already exists when opened, the stream's write-postion will - be set to the end of the file. To overwrite an existing file, - use File::deleteFile() before opening the stream, or use setPosition(0) - after it's opened (although this won't truncate the file). - - @see TemporaryFile - */ - FileOutputStream (const File& fileToWriteTo, - size_t bufferSizeToUse = 16384); - - /** Destructor. */ - ~FileOutputStream(); - - //============================================================================== - /** Returns the file that this stream is writing to. - */ - const File& getFile() const { return file; } - - /** Returns the status of the file stream. - The result will be ok if the file opened successfully. If an error occurs while - opening or writing to the file, this will contain an error message. - */ - const Result& getStatus() const noexcept { return status; } - - /** Returns true if the stream couldn't be opened for some reason. - @see getResult() - */ - bool failedToOpen() const noexcept { return status.failed(); } - - /** Returns true if the stream opened without problems. - @see getResult() - */ - bool openedOk() const noexcept { return status.wasOk(); } - - /** Attempts to truncate the file to the current write position. - To truncate a file to a specific size, first use setPosition() to seek to the - appropriate location, and then call this method. - */ - Result truncate(); - - //============================================================================== - void flush() override; - int64 getPosition() override; - bool setPosition (int64) override; - bool write (const void*, size_t) override; - bool writeRepeatedByte (uint8 byte, size_t numTimesToRepeat) override; - - -private: - //============================================================================== - File file; - void* fileHandle; - Result status; - int64 currentPosition; - size_t bufferSize, bytesInBuffer; - HeapBlock buffer; - - void openHandle(); - void closeHandle(); - void flushInternal(); - bool flushBuffer(); - int64 setPositionInternal (int64); - ssize_t writeInternal (const void*, size_t); - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (FileOutputStream) -}; - -#endif // JUCE_FILEOUTPUTSTREAM_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/files/juce_FileSearchPath.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/files/juce_FileSearchPath.cpp deleted file mode 100644 index ce0af7edaa..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/files/juce_FileSearchPath.cpp +++ /dev/null @@ -1,172 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -FileSearchPath::FileSearchPath() {} -FileSearchPath::~FileSearchPath() {} - -FileSearchPath::FileSearchPath (const String& path) -{ - init (path); -} - -FileSearchPath::FileSearchPath (const FileSearchPath& other) - : directories (other.directories) -{ -} - -FileSearchPath& FileSearchPath::operator= (const FileSearchPath& other) -{ - directories = other.directories; - return *this; -} - -FileSearchPath& FileSearchPath::operator= (const String& path) -{ - init (path); - return *this; -} - -void FileSearchPath::init (const String& path) -{ - directories.clear(); - directories.addTokens (path, ";", "\""); - directories.trim(); - directories.removeEmptyStrings(); - - for (int i = directories.size(); --i >= 0;) - directories.set (i, directories[i].unquoted()); -} - -int FileSearchPath::getNumPaths() const -{ - return directories.size(); -} - -File FileSearchPath::operator[] (const int index) const -{ - return File (directories [index]); -} - -String FileSearchPath::toString() const -{ - StringArray directories2 (directories); - for (int i = directories2.size(); --i >= 0;) - if (directories2[i].containsChar (';')) - directories2.set (i, directories2[i].quoted()); - - return directories2.joinIntoString (";"); -} - -void FileSearchPath::add (const File& dir, const int insertIndex) -{ - directories.insert (insertIndex, dir.getFullPathName()); -} - -void FileSearchPath::addIfNotAlreadyThere (const File& dir) -{ - for (int i = 0; i < directories.size(); ++i) - if (File (directories[i]) == dir) - return; - - add (dir); -} - -void FileSearchPath::remove (const int index) -{ - directories.remove (index); -} - -void FileSearchPath::addPath (const FileSearchPath& other) -{ - for (int i = 0; i < other.getNumPaths(); ++i) - addIfNotAlreadyThere (other[i]); -} - -void FileSearchPath::removeRedundantPaths() -{ - for (int i = directories.size(); --i >= 0;) - { - const File d1 (directories[i]); - - for (int j = directories.size(); --j >= 0;) - { - const File d2 (directories[j]); - - if ((i != j) && (d1.isAChildOf (d2) || d1 == d2)) - { - directories.remove (i); - break; - } - } - } -} - -void FileSearchPath::removeNonExistentPaths() -{ - for (int i = directories.size(); --i >= 0;) - if (! File (directories[i]).isDirectory()) - directories.remove (i); -} - -int FileSearchPath::findChildFiles (Array& results, - const int whatToLookFor, - const bool searchRecursively, - const String& wildCardPattern) const -{ - int total = 0; - - for (int i = 0; i < directories.size(); ++i) - total += operator[] (i).findChildFiles (results, - whatToLookFor, - searchRecursively, - wildCardPattern); - - return total; -} - -bool FileSearchPath::isFileInPath (const File& fileToCheck, - const bool checkRecursively) const -{ - for (int i = directories.size(); --i >= 0;) - { - const File d (directories[i]); - - if (checkRecursively) - { - if (fileToCheck.isAChildOf (d)) - return true; - } - else - { - if (fileToCheck.getParentDirectory() == d) - return true; - } - } - - return false; -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/files/juce_FileSearchPath.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/files/juce_FileSearchPath.h deleted file mode 100644 index 51baf2e77c..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/files/juce_FileSearchPath.h +++ /dev/null @@ -1,165 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_FILESEARCHPATH_H_INCLUDED -#define JUCE_FILESEARCHPATH_H_INCLUDED - - -//============================================================================== -/** - Represents a set of folders that make up a search path. - - @see File -*/ -class JUCE_API FileSearchPath -{ -public: - //============================================================================== - /** Creates an empty search path. */ - FileSearchPath(); - - /** Creates a search path from a string of pathnames. - - The path can be semicolon- or comma-separated, e.g. - "/foo/bar;/foo/moose;/fish/moose" - - The separate folders are tokenised and added to the search path. - */ - FileSearchPath (const String& path); - - /** Creates a copy of another search path. */ - FileSearchPath (const FileSearchPath&); - - /** Copies another search path. */ - FileSearchPath& operator= (const FileSearchPath&); - - /** Destructor. */ - ~FileSearchPath(); - - /** Uses a string containing a list of pathnames to re-initialise this list. - - This search path is cleared and the semicolon- or comma-separated folders - in this string are added instead. e.g. "/foo/bar;/foo/moose;/fish/moose" - */ - FileSearchPath& operator= (const String& path); - - //============================================================================== - /** Returns the number of folders in this search path. - @see operator[] - */ - int getNumPaths() const; - - /** Returns one of the folders in this search path. - The file returned isn't guaranteed to actually be a valid directory. - @see getNumPaths - */ - File operator[] (int index) const; - - /** Returns the search path as a semicolon-separated list of directories. */ - String toString() const; - - //============================================================================== - /** Adds a new directory to the search path. - - The new directory is added to the end of the list if the insertIndex parameter is - less than zero, otherwise it is inserted at the given index. - */ - void add (const File& directoryToAdd, - int insertIndex = -1); - - /** Adds a new directory to the search path if it's not already in there. */ - void addIfNotAlreadyThere (const File& directoryToAdd); - - /** Removes a directory from the search path. */ - void remove (int indexToRemove); - - /** Merges another search path into this one. - This will remove any duplicate directories. - */ - void addPath (const FileSearchPath&); - - /** Removes any directories that are actually subdirectories of one of the other directories in the search path. - - If the search is intended to be recursive, there's no point having nested folders in the search - path, because they'll just get searched twice and you'll get duplicate results. - - e.g. if the path is "c:\abc\de;c:\abc", this method will simplify it to "c:\abc" - */ - void removeRedundantPaths(); - - /** Removes any directories that don't actually exist. */ - void removeNonExistentPaths(); - - //============================================================================== - /** Searches the path for a wildcard. - - This will search all the directories in the search path in order, adding any - matching files to the results array. - - @param results an array to append the results to - @param whatToLookFor a value from the File::TypesOfFileToFind enum, specifying whether to - return files, directories, or both. - @param searchRecursively whether to recursively search the subdirectories too - @param wildCardPattern a pattern to match against the filenames - @returns the number of files added to the array - @see File::findChildFiles - */ - int findChildFiles (Array& results, - int whatToLookFor, - bool searchRecursively, - const String& wildCardPattern = "*") const; - - //============================================================================== - /** Finds out whether a file is inside one of the path's directories. - - This will return true if the specified file is a child of one of the - directories specified by this path. Note that this doesn't actually do any - searching or check that the files exist - it just looks at the pathnames - to work out whether the file would be inside a directory. - - @param fileToCheck the file to look for - @param checkRecursively if true, then this will return true if the file is inside a - subfolder of one of the path's directories (at any depth). If false - it will only return true if the file is actually a direct child - of one of the directories. - @see File::isAChildOf - - */ - bool isFileInPath (const File& fileToCheck, - bool checkRecursively) const; - -private: - //============================================================================== - StringArray directories; - - void init (const String&); - - JUCE_LEAK_DETECTOR (FileSearchPath) -}; - -#endif // JUCE_FILESEARCHPATH_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/files/juce_MemoryMappedFile.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/files/juce_MemoryMappedFile.h deleted file mode 100644 index 8a79185f49..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/files/juce_MemoryMappedFile.h +++ /dev/null @@ -1,115 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_MEMORYMAPPEDFILE_H_INCLUDED -#define JUCE_MEMORYMAPPEDFILE_H_INCLUDED - - -//============================================================================== -/** - Maps a file into virtual memory for easy reading and/or writing. -*/ -class JUCE_API MemoryMappedFile -{ -public: - /** The read/write flags used when opening a memory mapped file. */ - enum AccessMode - { - readOnly, /**< Indicates that the memory can only be read. */ - readWrite /**< Indicates that the memory can be read and written to - changes that are - made will be flushed back to disk at the whim of the OS. */ - }; - - /** Opens a file and maps it to an area of virtual memory. - - The file should already exist, and should already be the size that you want to work with - when you call this. If the file is resized after being opened, the behaviour is undefined. - - If the file exists and the operation succeeds, the getData() and getSize() methods will - return the location and size of the data that can be read or written. Note that the entire - file is not read into memory immediately - the OS simply creates a virtual mapping, which - will lazily pull the data into memory when blocks are accessed. - - If the file can't be opened for some reason, the getData() method will return a null pointer. - */ - MemoryMappedFile (const File& file, AccessMode mode); - - /** Opens a section of a file and maps it to an area of virtual memory. - - The file should already exist, and should already be the size that you want to work with - when you call this. If the file is resized after being opened, the behaviour is undefined. - - If the file exists and the operation succeeds, the getData() and getSize() methods will - return the location and size of the data that can be read or written. Note that the entire - file is not read into memory immediately - the OS simply creates a virtual mapping, which - will lazily pull the data into memory when blocks are accessed. - - If the file can't be opened for some reason, the getData() method will return a null pointer. - - NOTE: the start of the actual range used may be rounded-down to a multiple of the OS's page-size, - so do not assume that the mapped memory will begin at exactly the position you requested - always - use getRange() to check the actual range that is being used. - */ - MemoryMappedFile (const File& file, - const Range& fileRange, - AccessMode mode); - - /** Destructor. */ - ~MemoryMappedFile(); - - /** Returns the address at which this file has been mapped, or a null pointer if - the file couldn't be successfully mapped. - */ - void* getData() const noexcept { return address; } - - /** Returns the number of bytes of data that are available for reading or writing. - This will normally be the size of the file. - */ - size_t getSize() const noexcept { return (size_t) range.getLength(); } - - /** Returns the section of the file at which the mapped memory represents. */ - Range getRange() const noexcept { return range; } - -private: - //============================================================================== - void* address; - Range range; - - #if JUCE_WINDOWS - void* fileHandle; - #else - int fileHandle; - #endif - - void openInternal (const File&, AccessMode); - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MemoryMappedFile) -}; - - -#endif // JUCE_MEMORYMAPPEDFILE_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/files/juce_TemporaryFile.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/files/juce_TemporaryFile.cpp deleted file mode 100644 index 50475d58f0..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/files/juce_TemporaryFile.cpp +++ /dev/null @@ -1,117 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -static File createTempFile (const File& parentDirectory, String name, - const String& suffix, const int optionFlags) -{ - if ((optionFlags & TemporaryFile::useHiddenFile) != 0) - name = "." + name; - - return parentDirectory.getNonexistentChildFile (name, suffix, (optionFlags & TemporaryFile::putNumbersInBrackets) != 0); -} - -TemporaryFile::TemporaryFile (const String& suffix, const int optionFlags) - : temporaryFile (createTempFile (File::getSpecialLocation (File::tempDirectory), - "temp_" + String::toHexString (Random::getSystemRandom().nextInt()), - suffix, optionFlags)) -{ -} - -TemporaryFile::TemporaryFile (const File& target, const int optionFlags) - : temporaryFile (createTempFile (target.getParentDirectory(), - target.getFileNameWithoutExtension() - + "_temp" + String::toHexString (Random::getSystemRandom().nextInt()), - target.getFileExtension(), optionFlags)), - targetFile (target) -{ - // If you use this constructor, you need to give it a valid target file! - jassert (targetFile != File()); -} - -TemporaryFile::TemporaryFile (const File& target, const File& temporary) - : temporaryFile (temporary), targetFile (target) -{ -} - -TemporaryFile::~TemporaryFile() -{ - if (! deleteTemporaryFile()) - { - /* Failed to delete our temporary file! The most likely reason for this would be - that you've not closed an output stream that was being used to write to file. - - If you find that something beyond your control is changing permissions on - your temporary files and preventing them from being deleted, you may want to - call TemporaryFile::deleteTemporaryFile() to detect those error cases and - handle them appropriately. - */ - jassertfalse; - } -} - -//============================================================================== -bool TemporaryFile::overwriteTargetFileWithTemporary() const -{ - // This method only works if you created this object with the constructor - // that takes a target file! - jassert (targetFile != File()); - - if (temporaryFile.exists()) - { - // Have a few attempts at overwriting the file before giving up.. - for (int i = 5; --i >= 0;) - { - if (temporaryFile.moveFileTo (targetFile)) - return true; - - Thread::sleep (100); - } - } - else - { - // There's no temporary file to use. If your write failed, you should - // probably check, and not bother calling this method. - jassertfalse; - } - - return false; -} - -bool TemporaryFile::deleteTemporaryFile() const -{ - // Have a few attempts at deleting the file before giving up.. - for (int i = 5; --i >= 0;) - { - if (temporaryFile.deleteFile()) - return true; - - Thread::sleep (50); - } - - return false; -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/files/juce_TemporaryFile.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/files/juce_TemporaryFile.h deleted file mode 100644 index 04561a74b1..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/files/juce_TemporaryFile.h +++ /dev/null @@ -1,169 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_TEMPORARYFILE_H_INCLUDED -#define JUCE_TEMPORARYFILE_H_INCLUDED - - -//============================================================================== -/** - Manages a temporary file, which will be deleted when this object is deleted. - - This object is intended to be used as a stack based object, using its scope - to make sure the temporary file isn't left lying around. - - For example: - - @code - { - File myTargetFile ("~/myfile.txt"); - - // this will choose a file called something like "~/myfile_temp239348.txt" - // which definitely doesn't exist at the time the constructor is called. - TemporaryFile temp (myTargetFile); - - // create a stream to the temporary file, and write some data to it... - ScopedPointer out (temp.getFile().createOutputStream()); - - if (out != nullptr) - { - out->write ( ...etc ) - out = nullptr; // (deletes the stream) - - // ..now we've finished writing, this will rename the temp file to - // make it replace the target file we specified above. - bool succeeded = temp.overwriteTargetFileWithTemporary(); - } - - // ..and even if something went wrong and our overwrite failed, - // as the TemporaryFile object goes out of scope here, it'll make sure - // that the temp file gets deleted. - } - @endcode - - @see File, FileOutputStream -*/ -class JUCE_API TemporaryFile -{ -public: - //============================================================================== - enum OptionFlags - { - useHiddenFile = 1, /**< Indicates that the temporary file should be hidden - - i.e. its name should start with a dot. */ - putNumbersInBrackets = 2 /**< Indicates that when numbers are appended to make sure - the file is unique, they should go in brackets rather - than just being appended (see File::getNonexistentSibling() )*/ - }; - - //============================================================================== - /** Creates a randomly-named temporary file in the default temp directory. - - @param suffix a file suffix to use for the file - @param optionFlags a combination of the values listed in the OptionFlags enum - The file will not be created until you write to it. And remember that when - this object is deleted, the file will also be deleted! - */ - TemporaryFile (const String& suffix = String(), - int optionFlags = 0); - - /** Creates a temporary file in the same directory as a specified file. - - This is useful if you have a file that you want to overwrite, but don't - want to harm the original file if the write operation fails. You can - use this to create a temporary file next to the target file, then - write to the temporary file, and finally use overwriteTargetFileWithTemporary() - to replace the target file with the one you've just written. - - This class won't create any files until you actually write to them. And remember - that when this object is deleted, the temporary file will also be deleted! - - @param targetFile the file that you intend to overwrite - the temporary - file will be created in the same directory as this - @param optionFlags a combination of the values listed in the OptionFlags enum - */ - TemporaryFile (const File& targetFile, - int optionFlags = 0); - - /** Creates a temporary file using an explicit filename. - The other constructors are a better choice than this one, unless for some reason - you need to explicitly specify the temporary file you want to use. - - @param targetFile the file that you intend to overwrite - @param temporaryFile the temporary file to be used - */ - TemporaryFile (const File& targetFile, - const File& temporaryFile); - - /** Destructor. - - When this object is deleted it will make sure that its temporary file is - also deleted! If the operation fails, it'll throw an assertion in debug - mode. - */ - ~TemporaryFile(); - - //============================================================================== - /** Returns the temporary file. */ - const File& getFile() const noexcept { return temporaryFile; } - - /** Returns the target file that was specified in the constructor. */ - const File& getTargetFile() const noexcept { return targetFile; } - - /** Tries to move the temporary file to overwrite the target file that was - specified in the constructor. - - If you used the constructor that specified a target file, this will attempt - to replace that file with the temporary one. - - Before calling this, make sure: - - that you've actually written to the temporary file - - that you've closed any open streams that you were using to write to it - - and that you don't have any streams open to the target file, which would - prevent it being overwritten - - If the file move succeeds, this returns false, and the temporary file will - have disappeared. If it fails, the temporary file will probably still exist, - but will be deleted when this object is destroyed. - */ - bool overwriteTargetFileWithTemporary() const; - - /** Attempts to delete the temporary file, if it exists. - @returns true if the file is successfully deleted (or if it didn't exist). - */ - bool deleteTemporaryFile() const; - - -private: - //============================================================================== - const File temporaryFile, targetFile; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (TemporaryFile) -}; - -#endif // JUCE_TEMPORARYFILE_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/files/juce_WildcardFileFilter.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/files/juce_WildcardFileFilter.cpp deleted file mode 100644 index f18a2eb9ac..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/files/juce_WildcardFileFilter.cpp +++ /dev/null @@ -1,76 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -static void parseWildcard (const String& pattern, StringArray& result) -{ - result.addTokens (pattern.toLowerCase(), ";,", "\"'"); - - result.trim(); - result.removeEmptyStrings(); - - // special case for *.*, because people use it to mean "any file", but it - // would actually ignore files with no extension. - for (int i = result.size(); --i >= 0;) - if (result[i] == "*.*") - result.set (i, "*"); -} - -static bool matchWildcard (const File& file, const StringArray& wildcards) -{ - const String filename (file.getFileName()); - - for (int i = wildcards.size(); --i >= 0;) - if (filename.matchesWildcard (wildcards[i], true)) - return true; - - return false; -} - -WildcardFileFilter::WildcardFileFilter (const String& fileWildcardPatterns, - const String& directoryWildcardPatterns, - const String& desc) - : FileFilter (desc.isEmpty() ? fileWildcardPatterns - : (desc + " (" + fileWildcardPatterns + ")")) -{ - parseWildcard (fileWildcardPatterns, fileWildcards); - parseWildcard (directoryWildcardPatterns, directoryWildcards); -} - -WildcardFileFilter::~WildcardFileFilter() -{ -} - -bool WildcardFileFilter::isFileSuitable (const File& file) const -{ - return matchWildcard (file, fileWildcards); -} - -bool WildcardFileFilter::isDirectorySuitable (const File& file) const -{ - return matchWildcard (file, directoryWildcards); -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/files/juce_WildcardFileFilter.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/files/juce_WildcardFileFilter.h deleted file mode 100644 index fb398ce63b..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/files/juce_WildcardFileFilter.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_WILDCARDFILEFILTER_H_INCLUDED -#define JUCE_WILDCARDFILEFILTER_H_INCLUDED - - -//============================================================================== -/** - A type of FileFilter that works by wildcard pattern matching. - - This filter only allows files that match one of the specified patterns, but - allows all directories through. - - @see FileFilter, DirectoryContentsList, FileListComponent, FileBrowserComponent -*/ -class JUCE_API WildcardFileFilter : public FileFilter -{ -public: - //============================================================================== - /** - Creates a wildcard filter for one or more patterns. - - The wildcardPatterns parameter is a comma or semicolon-delimited set of - patterns, e.g. "*.wav;*.aiff" would look for files ending in either .wav - or .aiff. - - Passing an empty string as a pattern will fail to match anything, so by leaving - either the file or directory pattern parameter empty means you can control - whether files or directories are found. - - The description is a name to show the user in a list of possible patterns, so - for the wav/aiff example, your description might be "audio files". - */ - WildcardFileFilter (const String& fileWildcardPatterns, - const String& directoryWildcardPatterns, - const String& description); - - /** Destructor. */ - ~WildcardFileFilter(); - - //============================================================================== - /** Returns true if the filename matches one of the patterns specified. */ - bool isFileSuitable (const File& file) const; - - /** This always returns true. */ - bool isDirectorySuitable (const File& file) const; - -private: - //============================================================================== - StringArray fileWildcards, directoryWildcards; - - JUCE_LEAK_DETECTOR (WildcardFileFilter) -}; - - -#endif // JUCE_WILDCARDFILEFILTER_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/javascript/juce_JSON.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/javascript/juce_JSON.cpp deleted file mode 100644 index 5a0f7f7c0c..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/javascript/juce_JSON.cpp +++ /dev/null @@ -1,643 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -class JSONParser -{ -public: - static Result parseObjectOrArray (String::CharPointerType t, var& result) - { - t = t.findEndOfWhitespace(); - - switch (t.getAndAdvance()) - { - case 0: result = var(); return Result::ok(); - case '{': return parseObject (t, result); - case '[': return parseArray (t, result); - } - - return createFail ("Expected '{' or '['", &t); - } - - static Result parseString (const juce_wchar quoteChar, String::CharPointerType& t, var& result) - { - MemoryOutputStream buffer (256); - - for (;;) - { - juce_wchar c = t.getAndAdvance(); - - if (c == quoteChar) - break; - - if (c == '\\') - { - c = t.getAndAdvance(); - - switch (c) - { - case '"': - case '\'': - case '\\': - case '/': break; - - case 'a': c = '\a'; break; - case 'b': c = '\b'; break; - case 'f': c = '\f'; break; - case 'n': c = '\n'; break; - case 'r': c = '\r'; break; - case 't': c = '\t'; break; - - case 'u': - { - c = 0; - - for (int i = 4; --i >= 0;) - { - const int digitValue = CharacterFunctions::getHexDigitValue (t.getAndAdvance()); - if (digitValue < 0) - return createFail ("Syntax error in unicode escape sequence"); - - c = (juce_wchar) ((c << 4) + digitValue); - } - - break; - } - } - } - - if (c == 0) - return createFail ("Unexpected end-of-input in string constant"); - - buffer.appendUTF8Char (c); - } - - result = buffer.toUTF8(); - return Result::ok(); - } - - static Result parseAny (String::CharPointerType& t, var& result) - { - t = t.findEndOfWhitespace(); - String::CharPointerType t2 (t); - - switch (t2.getAndAdvance()) - { - case '{': t = t2; return parseObject (t, result); - case '[': t = t2; return parseArray (t, result); - case '"': t = t2; return parseString ('"', t, result); - case '\'': t = t2; return parseString ('\'', t, result); - - case '-': - t2 = t2.findEndOfWhitespace(); - if (! CharacterFunctions::isDigit (*t2)) - break; - - t = t2; - return parseNumber (t, result, true); - - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - return parseNumber (t, result, false); - - case 't': // "true" - if (t2.getAndAdvance() == 'r' && t2.getAndAdvance() == 'u' && t2.getAndAdvance() == 'e') - { - t = t2; - result = var (true); - return Result::ok(); - } - break; - - case 'f': // "false" - if (t2.getAndAdvance() == 'a' && t2.getAndAdvance() == 'l' - && t2.getAndAdvance() == 's' && t2.getAndAdvance() == 'e') - { - t = t2; - result = var (false); - return Result::ok(); - } - break; - - case 'n': // "null" - if (t2.getAndAdvance() == 'u' && t2.getAndAdvance() == 'l' && t2.getAndAdvance() == 'l') - { - t = t2; - result = var(); - return Result::ok(); - } - break; - - default: - break; - } - - return createFail ("Syntax error", &t); - } - -private: - static Result createFail (const char* const message, const String::CharPointerType* location = nullptr) - { - String m (message); - if (location != nullptr) - m << ": \"" << String (*location, 20) << '"'; - - return Result::fail (m); - } - - static Result parseNumber (String::CharPointerType& t, var& result, const bool isNegative) - { - String::CharPointerType oldT (t); - - int64 intValue = t.getAndAdvance() - '0'; - jassert (intValue >= 0 && intValue < 10); - - for (;;) - { - String::CharPointerType previousChar (t); - const juce_wchar c = t.getAndAdvance(); - const int digit = ((int) c) - '0'; - - if (isPositiveAndBelow (digit, 10)) - { - intValue = intValue * 10 + digit; - continue; - } - - if (c == 'e' || c == 'E' || c == '.') - { - t = oldT; - const double asDouble = CharacterFunctions::readDoubleValue (t); - result = isNegative ? -asDouble : asDouble; - return Result::ok(); - } - - if (CharacterFunctions::isWhitespace (c) - || c == ',' || c == '}' || c == ']' || c == 0) - { - t = previousChar; - break; - } - - return createFail ("Syntax error in number", &oldT); - } - - const int64 correctedValue = isNegative ? -intValue : intValue; - - if ((intValue >> 31) != 0) - result = correctedValue; - else - result = (int) correctedValue; - - return Result::ok(); - } - - static Result parseObject (String::CharPointerType& t, var& result) - { - DynamicObject* const resultObject = new DynamicObject(); - result = resultObject; - NamedValueSet& resultProperties = resultObject->getProperties(); - - for (;;) - { - t = t.findEndOfWhitespace(); - - String::CharPointerType oldT (t); - const juce_wchar c = t.getAndAdvance(); - - if (c == '}') - break; - - if (c == 0) - return createFail ("Unexpected end-of-input in object declaration"); - - if (c == '"') - { - var propertyNameVar; - Result r (parseString ('"', t, propertyNameVar)); - - if (r.failed()) - return r; - - const Identifier propertyName (propertyNameVar.toString()); - - if (propertyName.isValid()) - { - t = t.findEndOfWhitespace(); - oldT = t; - - const juce_wchar c2 = t.getAndAdvance(); - if (c2 != ':') - return createFail ("Expected ':', but found", &oldT); - - resultProperties.set (propertyName, var()); - var* propertyValue = resultProperties.getVarPointer (propertyName); - - Result r2 (parseAny (t, *propertyValue)); - - if (r2.failed()) - return r2; - - t = t.findEndOfWhitespace(); - oldT = t; - - const juce_wchar nextChar = t.getAndAdvance(); - - if (nextChar == ',') - continue; - - if (nextChar == '}') - break; - } - } - - return createFail ("Expected object member declaration, but found", &oldT); - } - - return Result::ok(); - } - - static Result parseArray (String::CharPointerType& t, var& result) - { - result = var (Array()); - Array* const destArray = result.getArray(); - - for (;;) - { - t = t.findEndOfWhitespace(); - - String::CharPointerType oldT (t); - const juce_wchar c = t.getAndAdvance(); - - if (c == ']') - break; - - if (c == 0) - return createFail ("Unexpected end-of-input in array declaration"); - - t = oldT; - destArray->add (var()); - Result r (parseAny (t, destArray->getReference (destArray->size() - 1))); - - if (r.failed()) - return r; - - t = t.findEndOfWhitespace(); - oldT = t; - - const juce_wchar nextChar = t.getAndAdvance(); - - if (nextChar == ',') - continue; - - if (nextChar == ']') - break; - - return createFail ("Expected object array item, but found", &oldT); - } - - return Result::ok(); - } -}; - -//============================================================================== -class JSONFormatter -{ -public: - static void write (OutputStream& out, const var& v, - const int indentLevel, const bool allOnOneLine) - { - if (v.isString()) - { - out << '"'; - writeString (out, v.toString().getCharPointer()); - out << '"'; - } - else if (v.isVoid()) - { - out << "null"; - } - else if (v.isUndefined()) - { - out << "undefined"; - } - else if (v.isBool()) - { - out << (static_cast (v) ? "true" : "false"); - } - else if (v.isArray()) - { - writeArray (out, *v.getArray(), indentLevel, allOnOneLine); - } - else if (v.isObject()) - { - if (DynamicObject* object = v.getDynamicObject()) - object->writeAsJSON (out, indentLevel, allOnOneLine); - else - jassertfalse; // Only DynamicObjects can be converted to JSON! - } - else - { - // Can't convert these other types of object to JSON! - jassert (! (v.isMethod() || v.isBinaryData())); - - out << v.toString(); - } - } - - static void writeEscapedChar (OutputStream& out, const unsigned short value) - { - out << "\\u" << String::toHexString ((int) value).paddedLeft ('0', 4); - } - - static void writeString (OutputStream& out, String::CharPointerType t) - { - for (;;) - { - const juce_wchar c (t.getAndAdvance()); - - switch (c) - { - case 0: return; - - case '\"': out << "\\\""; break; - case '\\': out << "\\\\"; break; - case '\a': out << "\\a"; break; - case '\b': out << "\\b"; break; - case '\f': out << "\\f"; break; - case '\t': out << "\\t"; break; - case '\r': out << "\\r"; break; - case '\n': out << "\\n"; break; - - default: - if (c >= 32 && c < 127) - { - out << (char) c; - } - else - { - if (CharPointer_UTF16::getBytesRequiredFor (c) > 2) - { - CharPointer_UTF16::CharType chars[2]; - CharPointer_UTF16 utf16 (chars); - utf16.write (c); - - for (int i = 0; i < 2; ++i) - writeEscapedChar (out, (unsigned short) chars[i]); - } - else - { - writeEscapedChar (out, (unsigned short) c); - } - } - - break; - } - } - } - - static void writeSpaces (OutputStream& out, int numSpaces) - { - out.writeRepeatedByte (' ', (size_t) numSpaces); - } - - static void writeArray (OutputStream& out, const Array& array, - const int indentLevel, const bool allOnOneLine) - { - out << '['; - - if (array.size() > 0) - { - if (! allOnOneLine) - out << newLine; - - for (int i = 0; i < array.size(); ++i) - { - if (! allOnOneLine) - writeSpaces (out, indentLevel + indentSize); - - write (out, array.getReference(i), indentLevel + indentSize, allOnOneLine); - - if (i < array.size() - 1) - { - if (allOnOneLine) - out << ", "; - else - out << ',' << newLine; - } - else if (! allOnOneLine) - out << newLine; - } - - if (! allOnOneLine) - writeSpaces (out, indentLevel); - } - - out << ']'; - } - - enum { indentSize = 2 }; -}; - -//============================================================================== -var JSON::parse (const String& text) -{ - var result; - - if (! parse (text, result)) - result = var(); - - return result; -} - -var JSON::fromString (StringRef text) -{ - var result; - - if (! JSONParser::parseAny (text.text, result)) - result = var(); - - return result; -} - -var JSON::parse (InputStream& input) -{ - return parse (input.readEntireStreamAsString()); -} - -var JSON::parse (const File& file) -{ - return parse (file.loadFileAsString()); -} - -Result JSON::parse (const String& text, var& result) -{ - return JSONParser::parseObjectOrArray (text.getCharPointer(), result); -} - -String JSON::toString (const var& data, const bool allOnOneLine) -{ - MemoryOutputStream mo (1024); - JSONFormatter::write (mo, data, 0, allOnOneLine); - return mo.toUTF8(); -} - -void JSON::writeToStream (OutputStream& output, const var& data, const bool allOnOneLine) -{ - JSONFormatter::write (output, data, 0, allOnOneLine); -} - -String JSON::escapeString (StringRef s) -{ - MemoryOutputStream mo; - JSONFormatter::writeString (mo, s.text); - return mo.toString(); -} - -Result JSON::parseQuotedString (String::CharPointerType& t, var& result) -{ - const juce_wchar quote = t.getAndAdvance(); - - if (quote == '"' || quote == '\'') - return JSONParser::parseString (quote, t, result); - - return Result::fail ("Not a quoted string!"); -} - -//============================================================================== -//============================================================================== -#if JUCE_UNIT_TESTS - -class JSONTests : public UnitTest -{ -public: - JSONTests() : UnitTest ("JSON") {} - - static String createRandomWideCharString (Random& r) - { - juce_wchar buffer[40] = { 0 }; - - for (int i = 0; i < numElementsInArray (buffer) - 1; ++i) - { - if (r.nextBool()) - { - do - { - buffer[i] = (juce_wchar) (1 + r.nextInt (0x10ffff - 1)); - } - while (! CharPointer_UTF16::canRepresent (buffer[i])); - } - else - buffer[i] = (juce_wchar) (1 + r.nextInt (0xff)); - } - - return CharPointer_UTF32 (buffer); - } - - static String createRandomIdentifier (Random& r) - { - char buffer[30] = { 0 }; - - for (int i = 0; i < numElementsInArray (buffer) - 1; ++i) - { - static const char chars[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-:"; - buffer[i] = chars [r.nextInt (sizeof (chars) - 1)]; - } - - return CharPointer_ASCII (buffer); - } - - static var createRandomVar (Random& r, int depth) - { - switch (r.nextInt (depth > 3 ? 6 : 8)) - { - case 0: return var(); - case 1: return r.nextInt(); - case 2: return r.nextInt64(); - case 3: return r.nextBool(); - case 4: return r.nextDouble(); - case 5: return createRandomWideCharString (r); - - case 6: - { - var v (createRandomVar (r, depth + 1)); - - for (int i = 1 + r.nextInt (30); --i >= 0;) - v.append (createRandomVar (r, depth + 1)); - - return v; - } - - case 7: - { - DynamicObject* o = new DynamicObject(); - - for (int i = r.nextInt (30); --i >= 0;) - o->setProperty (createRandomIdentifier (r), createRandomVar (r, depth + 1)); - - return o; - } - - default: - return var(); - } - } - - void runTest() - { - beginTest ("JSON"); - Random r = getRandom(); - - expect (JSON::parse (String::empty) == var::null); - expect (JSON::parse ("{}").isObject()); - expect (JSON::parse ("[]").isArray()); - expect (JSON::parse ("[ 1234 ]")[0].isInt()); - expect (JSON::parse ("[ 12345678901234 ]")[0].isInt64()); - expect (JSON::parse ("[ 1.123e3 ]")[0].isDouble()); - expect (JSON::parse ("[ -1234]")[0].isInt()); - expect (JSON::parse ("[-12345678901234]")[0].isInt64()); - expect (JSON::parse ("[-1.123e3]")[0].isDouble()); - - for (int i = 100; --i >= 0;) - { - var v; - - if (i > 0) - v = createRandomVar (r, 0); - - const bool oneLine = r.nextBool(); - String asString (JSON::toString (v, oneLine)); - var parsed = JSON::parse ("[" + asString + "]")[0]; - String parsedString (JSON::toString (parsed, oneLine)); - expect (asString.isNotEmpty() && parsedString == asString); - } - } -}; - -static JSONTests JSONUnitTests; - -#endif diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/javascript/juce_JSON.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/javascript/juce_JSON.h deleted file mode 100644 index 7fb17ee209..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/javascript/juce_JSON.h +++ /dev/null @@ -1,136 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_JSON_H_INCLUDED -#define JUCE_JSON_H_INCLUDED - - -//============================================================================== -/** - Contains static methods for converting JSON-formatted text to and from var objects. - - The var class is structurally compatible with JSON-formatted data, so these - functions allow you to parse JSON into a var object, and to convert a var - object to JSON-formatted text. - - @see var -*/ -class JUCE_API JSON -{ -public: - //============================================================================== - /** Parses a string of JSON-formatted text, and returns a result code containing - any parse errors. - - This will return the parsed structure in the parsedResult parameter, and will - return a Result object to indicate whether parsing was successful, and if not, - it will contain an error message. - - If you're not interested in the error message, you can use one of the other - shortcut parse methods, which simply return a var::null if the parsing fails. - - Note that this will only parse valid JSON, which means that the item given must - be either an object or an array definition. If you want to also be able to parse - any kind of primitive JSON object, use the fromString() method. - */ - static Result parse (const String& text, var& parsedResult); - - /** Attempts to parse some JSON-formatted text, and returns the result as a var object. - - If the parsing fails, this simply returns var::null - if you need to find out more - detail about the parse error, use the alternative parse() method which returns a Result. - - Note that this will only parse valid JSON, which means that the item given must - be either an object or an array definition. If you want to also be able to parse - any kind of primitive JSON object, use the fromString() method. - */ - static var parse (const String& text); - - /** Attempts to parse some JSON-formatted text from a file, and returns the result - as a var object. - - Note that this is just a short-cut for reading the entire file into a string and - parsing the result. - - If the parsing fails, this simply returns var::null - if you need to find out more - detail about the parse error, use the alternative parse() method which returns a Result. - */ - static var parse (const File& file); - - /** Attempts to parse some JSON-formatted text from a stream, and returns the result - as a var object. - - Note that this is just a short-cut for reading the entire stream into a string and - parsing the result. - - If the parsing fails, this simply returns var::null - if you need to find out more - detail about the parse error, use the alternative parse() method which returns a Result. - */ - static var parse (InputStream& input); - - //============================================================================== - /** Returns a string which contains a JSON-formatted representation of the var object. - If allOnOneLine is true, the result will be compacted into a single line of text - with no carriage-returns. If false, it will be laid-out in a more human-readable format. - @see writeToStream - */ - static String toString (const var& objectToFormat, - bool allOnOneLine = false); - - /** Parses a string that was created with the toString() method. - This is slightly different to the parse() methods because they will reject primitive - values and only accept array or object definitions, whereas this method will handle - either. - */ - static var fromString (StringRef); - - /** Writes a JSON-formatted representation of the var object to the given stream. - If allOnOneLine is true, the result will be compacted into a single line of text - with no carriage-returns. If false, it will be laid-out in a more human-readable format. - @see toString - */ - static void writeToStream (OutputStream& output, - const var& objectToFormat, - bool allOnOneLine = false); - - /** Returns a version of a string with any extended characters escaped. */ - static String escapeString (StringRef); - - /** Parses a quoted string-literal in JSON format, returning the un-escaped result in the - result parameter, and an error message in case the content was illegal. - This advances the text parameter, leaving it positioned after the closing quote. - */ - static Result parseQuotedString (String::CharPointerType& text, var& result); - -private: - //============================================================================== - JSON() JUCE_DELETED_FUNCTION; // This class can't be instantiated - just use its static methods. -}; - - -#endif // JUCE_JSON_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/javascript/juce_Javascript.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/javascript/juce_Javascript.cpp deleted file mode 100644 index e78bb37113..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/javascript/juce_Javascript.cpp +++ /dev/null @@ -1,1725 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#define JUCE_JS_OPERATORS(X) \ - X(semicolon, ";") X(dot, ".") X(comma, ",") \ - X(openParen, "(") X(closeParen, ")") X(openBrace, "{") X(closeBrace, "}") \ - X(openBracket, "[") X(closeBracket, "]") X(colon, ":") X(question, "?") \ - X(typeEquals, "===") X(equals, "==") X(assign, "=") \ - X(typeNotEquals, "!==") X(notEquals, "!=") X(logicalNot, "!") \ - X(plusEquals, "+=") X(plusplus, "++") X(plus, "+") \ - X(minusEquals, "-=") X(minusminus, "--") X(minus, "-") \ - X(timesEquals, "*=") X(times, "*") X(divideEquals, "/=") X(divide, "/") \ - X(moduloEquals, "%=") X(modulo, "%") X(xorEquals, "^=") X(bitwiseXor, "^") \ - X(andEquals, "&=") X(logicalAnd, "&&") X(bitwiseAnd, "&") \ - X(orEquals, "|=") X(logicalOr, "||") X(bitwiseOr, "|") \ - X(leftShiftEquals, "<<=") X(lessThanOrEqual, "<=") X(leftShift, "<<") X(lessThan, "<") \ - X(rightShiftUnsigned, ">>>") X(rightShiftEquals, ">>=") X(rightShift, ">>") X(greaterThanOrEqual, ">=") X(greaterThan, ">") - -#define JUCE_JS_KEYWORDS(X) \ - X(var, "var") X(if_, "if") X(else_, "else") X(do_, "do") X(null_, "null") \ - X(while_, "while") X(for_, "for") X(break_, "break") X(continue_, "continue") X(undefined, "undefined") \ - X(function, "function") X(return_, "return") X(true_, "true") X(false_, "false") X(new_, "new") - -namespace TokenTypes -{ - #define JUCE_DECLARE_JS_TOKEN(name, str) static const char* const name = str; - JUCE_JS_KEYWORDS (JUCE_DECLARE_JS_TOKEN) - JUCE_JS_OPERATORS (JUCE_DECLARE_JS_TOKEN) - JUCE_DECLARE_JS_TOKEN (eof, "$eof") - JUCE_DECLARE_JS_TOKEN (literal, "$literal") - JUCE_DECLARE_JS_TOKEN (identifier, "$identifier") -} - -#if JUCE_MSVC - #pragma warning (push) - #pragma warning (disable: 4702) -#endif - -//============================================================================== -struct JavascriptEngine::RootObject : public DynamicObject -{ - RootObject() - { - setMethod ("exec", exec); - setMethod ("eval", eval); - setMethod ("trace", trace); - setMethod ("charToInt", charToInt); - setMethod ("parseInt", IntegerClass::parseInt); - } - - Time timeout; - - typedef const var::NativeFunctionArgs& Args; - typedef const char* TokenType; - - void execute (const String& code) - { - ExpressionTreeBuilder tb (code); - ScopedPointer (tb.parseStatementList())->perform (Scope (nullptr, this, this), nullptr); - } - - var evaluate (const String& code) - { - ExpressionTreeBuilder tb (code); - return ExpPtr (tb.parseExpression())->getResult (Scope (nullptr, this, this)); - } - - //============================================================================== - static bool areTypeEqual (const var& a, const var& b) - { - return a.hasSameTypeAs (b) && isFunction (a) == isFunction (b) - && (((a.isUndefined() || a.isVoid()) && (b.isUndefined() || b.isVoid())) || a == b); - } - - static String getTokenName (TokenType t) { return t[0] == '$' ? String (t + 1) : ("'" + String (t) + "'"); } - static bool isFunction (const var& v) { return dynamic_cast (v.getObject()) != nullptr; } - static bool isNumericOrUndefined (const var& v) { return v.isInt() || v.isDouble() || v.isInt64() || v.isBool() || v.isUndefined(); } - static int64 getOctalValue (const String& s) { BigInteger b; b.parseString (s, 8); return b.toInt64(); } - static Identifier getPrototypeIdentifier() { static const Identifier i ("prototype"); return i; } - static var* getPropertyPointer (DynamicObject* o, Identifier i) { return o->getProperties().getVarPointer (i); } - - //============================================================================== - struct CodeLocation - { - CodeLocation (const String& code) noexcept : program (code), location (program.getCharPointer()) {} - CodeLocation (const CodeLocation& other) noexcept : program (other.program), location (other.location) {} - - void throwError (const String& message) const - { - int col = 1, line = 1; - - for (String::CharPointerType i (program.getCharPointer()); i < location && ! i.isEmpty(); ++i) - { - ++col; - if (*i == '\n') { col = 1; ++line; } - } - - throw "Line " + String (line) + ", column " + String (col) + " : " + message; - } - - String program; - String::CharPointerType location; - }; - - //============================================================================== - struct Scope - { - Scope (const Scope* p, RootObject* r, DynamicObject* s) noexcept : parent (p), root (r), scope (s) {} - - const Scope* parent; - ReferenceCountedObjectPtr root; - DynamicObject::Ptr scope; - - var findFunctionCall (const CodeLocation& location, const var& targetObject, Identifier functionName) const - { - if (DynamicObject* o = targetObject.getDynamicObject()) - { - if (const var* prop = getPropertyPointer (o, functionName)) - return *prop; - - for (DynamicObject* p = o->getProperty (getPrototypeIdentifier()).getDynamicObject(); p != nullptr; - p = p->getProperty (getPrototypeIdentifier()).getDynamicObject()) - { - if (const var* prop = getPropertyPointer (p, functionName)) - return *prop; - } - } - - if (targetObject.isString()) - if (var* m = findRootClassProperty (StringClass::getClassName(), functionName)) - return *m; - - if (targetObject.isArray()) - if (var* m = findRootClassProperty (ArrayClass::getClassName(), functionName)) - return *m; - - if (var* m = findRootClassProperty (ObjectClass::getClassName(), functionName)) - return *m; - - location.throwError ("Unknown function '" + functionName.toString() + "'"); - return var(); - } - - var* findRootClassProperty (Identifier className, Identifier propName) const - { - if (DynamicObject* cls = root->getProperty (className).getDynamicObject()) - return getPropertyPointer (cls, propName); - - return nullptr; - } - - var findSymbolInParentScopes (Identifier name) const - { - if (const var* v = getPropertyPointer (scope, name)) - return *v; - - return parent != nullptr ? parent->findSymbolInParentScopes (name) - : var::undefined(); - } - - bool findAndInvokeMethod (Identifier function, const var::NativeFunctionArgs& args, var& result) const - { - DynamicObject* target = args.thisObject.getDynamicObject(); - - if (target == nullptr || target == scope) - { - if (const var* m = getPropertyPointer (scope, function)) - { - if (FunctionObject* fo = dynamic_cast (m->getObject())) - { - result = fo->invoke (*this, args); - return true; - } - } - } - - const NamedValueSet& props = scope->getProperties(); - - for (int i = 0; i < props.size(); ++i) - if (DynamicObject* o = props.getValueAt (i).getDynamicObject()) - if (Scope (this, root, o).findAndInvokeMethod (function, args, result)) - return true; - - return false; - } - - void checkTimeOut (const CodeLocation& location) const - { - if (Time::getCurrentTime() > root->timeout) - location.throwError ("Execution timed-out"); - } - }; - - //============================================================================== - struct Statement - { - Statement (const CodeLocation& l) noexcept : location (l) {} - virtual ~Statement() {} - - enum ResultCode { ok = 0, returnWasHit, breakWasHit, continueWasHit }; - virtual ResultCode perform (const Scope&, var*) const { return ok; } - - CodeLocation location; - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Statement) - }; - - struct Expression : public Statement - { - Expression (const CodeLocation& l) noexcept : Statement (l) {} - - virtual var getResult (const Scope&) const { return var::undefined(); } - virtual void assign (const Scope&, const var&) const { location.throwError ("Cannot assign to this expression!"); } - - ResultCode perform (const Scope& s, var*) const override { getResult (s); return ok; } - }; - - typedef ScopedPointer ExpPtr; - - struct BlockStatement : public Statement - { - BlockStatement (const CodeLocation& l) noexcept : Statement (l) {} - - ResultCode perform (const Scope& s, var* returnedValue) const override - { - for (int i = 0; i < statements.size(); ++i) - if (ResultCode r = statements.getUnchecked(i)->perform (s, returnedValue)) - return r; - - return ok; - } - - OwnedArray statements; - }; - - struct IfStatement : public Statement - { - IfStatement (const CodeLocation& l) noexcept : Statement (l) {} - - ResultCode perform (const Scope& s, var* returnedValue) const override - { - return (condition->getResult(s) ? trueBranch : falseBranch)->perform (s, returnedValue); - } - - ExpPtr condition; - ScopedPointer trueBranch, falseBranch; - }; - - struct VarStatement : public Statement - { - VarStatement (const CodeLocation& l) noexcept : Statement (l) {} - - ResultCode perform (const Scope& s, var*) const override - { - s.scope->setProperty (name, initialiser->getResult (s)); - return ok; - } - - Identifier name; - ExpPtr initialiser; - }; - - struct LoopStatement : public Statement - { - LoopStatement (const CodeLocation& l, bool isDo) noexcept : Statement (l), isDoLoop (isDo) {} - - ResultCode perform (const Scope& s, var* returnedValue) const override - { - initialiser->perform (s, nullptr); - - while (isDoLoop || condition->getResult (s)) - { - s.checkTimeOut (location); - ResultCode r = body->perform (s, returnedValue); - - if (r == returnWasHit) return r; - if (r == breakWasHit) break; - - iterator->perform (s, nullptr); - - if (isDoLoop && r != continueWasHit && ! condition->getResult (s)) - break; - } - - return ok; - } - - ScopedPointer initialiser, iterator, body; - ExpPtr condition; - bool isDoLoop; - }; - - struct ReturnStatement : public Statement - { - ReturnStatement (const CodeLocation& l, Expression* v) noexcept : Statement (l), returnValue (v) {} - - ResultCode perform (const Scope& s, var* ret) const override - { - if (ret != nullptr) *ret = returnValue->getResult (s); - return returnWasHit; - } - - ExpPtr returnValue; - }; - - struct BreakStatement : public Statement - { - BreakStatement (const CodeLocation& l) noexcept : Statement (l) {} - ResultCode perform (const Scope&, var*) const override { return breakWasHit; } - }; - - struct ContinueStatement : public Statement - { - ContinueStatement (const CodeLocation& l) noexcept : Statement (l) {} - ResultCode perform (const Scope&, var*) const override { return continueWasHit; } - }; - - struct LiteralValue : public Expression - { - LiteralValue (const CodeLocation& l, const var& v) noexcept : Expression (l), value (v) {} - var getResult (const Scope&) const override { return value; } - var value; - }; - - struct UnqualifiedName : public Expression - { - UnqualifiedName (const CodeLocation& l, Identifier n) noexcept : Expression (l), name (n) {} - - var getResult (const Scope& s) const override { return s.findSymbolInParentScopes (name); } - - void assign (const Scope& s, const var& newValue) const override - { - if (var* v = getPropertyPointer (s.scope, name)) - *v = newValue; - else - s.root->setProperty (name, newValue); - } - - Identifier name; - }; - - struct DotOperator : public Expression - { - DotOperator (const CodeLocation& l, ExpPtr& p, Identifier c) noexcept : Expression (l), parent (p), child (c) {} - - var getResult (const Scope& s) const override - { - var p (parent->getResult (s)); - static const Identifier lengthID ("length"); - - if (child == lengthID) - { - if (Array* array = p.getArray()) return array->size(); - if (p.isString()) return p.toString().length(); - } - - if (DynamicObject* o = p.getDynamicObject()) - if (const var* v = getPropertyPointer (o, child)) - return *v; - - return var::undefined(); - } - - void assign (const Scope& s, const var& newValue) const override - { - if (DynamicObject* o = parent->getResult (s).getDynamicObject()) - o->setProperty (child, newValue); - else - Expression::assign (s, newValue); - } - - ExpPtr parent; - Identifier child; - }; - - struct ArraySubscript : public Expression - { - ArraySubscript (const CodeLocation& l) noexcept : Expression (l) {} - - var getResult (const Scope& s) const override - { - if (const Array* array = object->getResult (s).getArray()) - return (*array) [static_cast (index->getResult (s))]; - - return var::undefined(); - } - - void assign (const Scope& s, const var& newValue) const override - { - if (Array* array = object->getResult (s).getArray()) - { - const int i = index->getResult (s); - while (array->size() < i) - array->add (var::undefined()); - - array->set (i, newValue); - return; - } - - Expression::assign (s, newValue); - } - - ExpPtr object, index; - }; - - struct BinaryOperatorBase : public Expression - { - BinaryOperatorBase (const CodeLocation& l, ExpPtr& a, ExpPtr& b, TokenType op) noexcept - : Expression (l), lhs (a), rhs (b), operation (op) {} - - ExpPtr lhs, rhs; - TokenType operation; - }; - - struct BinaryOperator : public BinaryOperatorBase - { - BinaryOperator (const CodeLocation& l, ExpPtr& a, ExpPtr& b, TokenType op) noexcept - : BinaryOperatorBase (l, a, b, op) {} - - virtual var getWithUndefinedArg() const { return var::undefined(); } - virtual var getWithDoubles (double, double) const { return throwError ("Double"); } - virtual var getWithInts (int64, int64) const { return throwError ("Integer"); } - virtual var getWithArrayOrObject (const var& a, const var&) const { return throwError (a.isArray() ? "Array" : "Object"); } - virtual var getWithStrings (const String&, const String&) const { return throwError ("String"); } - - var getResult (const Scope& s) const override - { - var a (lhs->getResult (s)), b (rhs->getResult (s)); - - if ((a.isUndefined() || a.isVoid()) && (b.isUndefined() || b.isVoid())) - return getWithUndefinedArg(); - - if (isNumericOrUndefined (a) && isNumericOrUndefined (b)) - return (a.isDouble() || b.isDouble()) ? getWithDoubles (a, b) : getWithInts (a, b); - - if (a.isArray() || a.isObject()) - return getWithArrayOrObject (a, b); - - return getWithStrings (a.toString(), b.toString()); - } - - var throwError (const char* typeName) const - { location.throwError (getTokenName (operation) + " is not allowed on the " + typeName + " type"); return var(); } - }; - - struct EqualsOp : public BinaryOperator - { - EqualsOp (const CodeLocation& l, ExpPtr& a, ExpPtr& b) noexcept : BinaryOperator (l, a, b, TokenTypes::equals) {} - var getWithUndefinedArg() const override { return true; } - var getWithDoubles (double a, double b) const override { return a == b; } - var getWithInts (int64 a, int64 b) const override { return a == b; } - var getWithStrings (const String& a, const String& b) const override { return a == b; } - var getWithArrayOrObject (const var& a, const var& b) const override { return a == b; } - }; - - struct NotEqualsOp : public BinaryOperator - { - NotEqualsOp (const CodeLocation& l, ExpPtr& a, ExpPtr& b) noexcept : BinaryOperator (l, a, b, TokenTypes::notEquals) {} - var getWithUndefinedArg() const override { return false; } - var getWithDoubles (double a, double b) const override { return a != b; } - var getWithInts (int64 a, int64 b) const override { return a != b; } - var getWithStrings (const String& a, const String& b) const override { return a != b; } - var getWithArrayOrObject (const var& a, const var& b) const override { return a != b; } - }; - - struct LessThanOp : public BinaryOperator - { - LessThanOp (const CodeLocation& l, ExpPtr& a, ExpPtr& b) noexcept : BinaryOperator (l, a, b, TokenTypes::lessThan) {} - var getWithDoubles (double a, double b) const override { return a < b; } - var getWithInts (int64 a, int64 b) const override { return a < b; } - var getWithStrings (const String& a, const String& b) const override { return a < b; } - }; - - struct LessThanOrEqualOp : public BinaryOperator - { - LessThanOrEqualOp (const CodeLocation& l, ExpPtr& a, ExpPtr& b) noexcept : BinaryOperator (l, a, b, TokenTypes::lessThanOrEqual) {} - var getWithDoubles (double a, double b) const override { return a <= b; } - var getWithInts (int64 a, int64 b) const override { return a <= b; } - var getWithStrings (const String& a, const String& b) const override { return a <= b; } - }; - - struct GreaterThanOp : public BinaryOperator - { - GreaterThanOp (const CodeLocation& l, ExpPtr& a, ExpPtr& b) noexcept : BinaryOperator (l, a, b, TokenTypes::greaterThan) {} - var getWithDoubles (double a, double b) const override { return a > b; } - var getWithInts (int64 a, int64 b) const override { return a > b; } - var getWithStrings (const String& a, const String& b) const override { return a > b; } - }; - - struct GreaterThanOrEqualOp : public BinaryOperator - { - GreaterThanOrEqualOp (const CodeLocation& l, ExpPtr& a, ExpPtr& b) noexcept : BinaryOperator (l, a, b, TokenTypes::greaterThanOrEqual) {} - var getWithDoubles (double a, double b) const override { return a >= b; } - var getWithInts (int64 a, int64 b) const override { return a >= b; } - var getWithStrings (const String& a, const String& b) const override { return a >= b; } - }; - - struct AdditionOp : public BinaryOperator - { - AdditionOp (const CodeLocation& l, ExpPtr& a, ExpPtr& b) noexcept : BinaryOperator (l, a, b, TokenTypes::plus) {} - var getWithDoubles (double a, double b) const override { return a + b; } - var getWithInts (int64 a, int64 b) const override { return a + b; } - var getWithStrings (const String& a, const String& b) const override { return a + b; } - }; - - struct SubtractionOp : public BinaryOperator - { - SubtractionOp (const CodeLocation& l, ExpPtr& a, ExpPtr& b) noexcept : BinaryOperator (l, a, b, TokenTypes::minus) {} - var getWithDoubles (double a, double b) const override { return a - b; } - var getWithInts (int64 a, int64 b) const override { return a - b; } - }; - - struct MultiplyOp : public BinaryOperator - { - MultiplyOp (const CodeLocation& l, ExpPtr& a, ExpPtr& b) noexcept : BinaryOperator (l, a, b, TokenTypes::times) {} - var getWithDoubles (double a, double b) const override { return a * b; } - var getWithInts (int64 a, int64 b) const override { return a * b; } - }; - - struct DivideOp : public BinaryOperator - { - DivideOp (const CodeLocation& l, ExpPtr& a, ExpPtr& b) noexcept : BinaryOperator (l, a, b, TokenTypes::divide) {} - var getWithDoubles (double a, double b) const override { return b != 0 ? a / b : std::numeric_limits::infinity(); } - var getWithInts (int64 a, int64 b) const override { return b != 0 ? var (a / (double) b) : var (std::numeric_limits::infinity()); } - }; - - struct ModuloOp : public BinaryOperator - { - ModuloOp (const CodeLocation& l, ExpPtr& a, ExpPtr& b) noexcept : BinaryOperator (l, a, b, TokenTypes::modulo) {} - var getWithInts (int64 a, int64 b) const override { return b != 0 ? var (a % b) : var (std::numeric_limits::infinity()); } - }; - - struct BitwiseOrOp : public BinaryOperator - { - BitwiseOrOp (const CodeLocation& l, ExpPtr& a, ExpPtr& b) noexcept : BinaryOperator (l, a, b, TokenTypes::bitwiseOr) {} - var getWithInts (int64 a, int64 b) const override { return a | b; } - }; - - struct BitwiseAndOp : public BinaryOperator - { - BitwiseAndOp (const CodeLocation& l, ExpPtr& a, ExpPtr& b) noexcept : BinaryOperator (l, a, b, TokenTypes::bitwiseAnd) {} - var getWithInts (int64 a, int64 b) const override { return a & b; } - }; - - struct BitwiseXorOp : public BinaryOperator - { - BitwiseXorOp (const CodeLocation& l, ExpPtr& a, ExpPtr& b) noexcept : BinaryOperator (l, a, b, TokenTypes::bitwiseXor) {} - var getWithInts (int64 a, int64 b) const override { return a ^ b; } - }; - - struct LeftShiftOp : public BinaryOperator - { - LeftShiftOp (const CodeLocation& l, ExpPtr& a, ExpPtr& b) noexcept : BinaryOperator (l, a, b, TokenTypes::leftShift) {} - var getWithInts (int64 a, int64 b) const override { return ((int) a) << (int) b; } - }; - - struct RightShiftOp : public BinaryOperator - { - RightShiftOp (const CodeLocation& l, ExpPtr& a, ExpPtr& b) noexcept : BinaryOperator (l, a, b, TokenTypes::rightShift) {} - var getWithInts (int64 a, int64 b) const override { return ((int) a) >> (int) b; } - }; - - struct RightShiftUnsignedOp : public BinaryOperator - { - RightShiftUnsignedOp (const CodeLocation& l, ExpPtr& a, ExpPtr& b) noexcept : BinaryOperator (l, a, b, TokenTypes::rightShiftUnsigned) {} - var getWithInts (int64 a, int64 b) const override { return (int) (((uint32) a) >> (int) b); } - }; - - struct LogicalAndOp : public BinaryOperatorBase - { - LogicalAndOp (const CodeLocation& l, ExpPtr& a, ExpPtr& b) noexcept : BinaryOperatorBase (l, a, b, TokenTypes::logicalAnd) {} - var getResult (const Scope& s) const override { return lhs->getResult (s) && rhs->getResult (s); } - }; - - struct LogicalOrOp : public BinaryOperatorBase - { - LogicalOrOp (const CodeLocation& l, ExpPtr& a, ExpPtr& b) noexcept : BinaryOperatorBase (l, a, b, TokenTypes::logicalOr) {} - var getResult (const Scope& s) const override { return lhs->getResult (s) || rhs->getResult (s); } - }; - - struct TypeEqualsOp : public BinaryOperatorBase - { - TypeEqualsOp (const CodeLocation& l, ExpPtr& a, ExpPtr& b) noexcept : BinaryOperatorBase (l, a, b, TokenTypes::typeEquals) {} - var getResult (const Scope& s) const override { return areTypeEqual (lhs->getResult (s), rhs->getResult (s)); } - }; - - struct TypeNotEqualsOp : public BinaryOperatorBase - { - TypeNotEqualsOp (const CodeLocation& l, ExpPtr& a, ExpPtr& b) noexcept : BinaryOperatorBase (l, a, b, TokenTypes::typeNotEquals) {} - var getResult (const Scope& s) const override { return ! areTypeEqual (lhs->getResult (s), rhs->getResult (s)); } - }; - - struct ConditionalOp : public Expression - { - ConditionalOp (const CodeLocation& l) noexcept : Expression (l) {} - - var getResult (const Scope& s) const override { return (condition->getResult (s) ? trueBranch : falseBranch)->getResult (s); } - void assign (const Scope& s, const var& v) const override { (condition->getResult (s) ? trueBranch : falseBranch)->assign (s, v); } - - ExpPtr condition, trueBranch, falseBranch; - }; - - struct Assignment : public Expression - { - Assignment (const CodeLocation& l, ExpPtr& dest, ExpPtr& source) noexcept : Expression (l), target (dest), newValue (source) {} - - var getResult (const Scope& s) const override - { - var value (newValue->getResult (s)); - target->assign (s, value); - return value; - } - - ExpPtr target, newValue; - }; - - struct SelfAssignment : public Expression - { - SelfAssignment (const CodeLocation& l, Expression* dest, Expression* source) noexcept - : Expression (l), target (dest), newValue (source) {} - - var getResult (const Scope& s) const override - { - var value (newValue->getResult (s)); - target->assign (s, value); - return value; - } - - Expression* target; // Careful! this pointer aliases a sub-term of newValue! - ExpPtr newValue; - TokenType op; - }; - - struct PostAssignment : public SelfAssignment - { - PostAssignment (const CodeLocation& l, Expression* dest, Expression* source) noexcept : SelfAssignment (l, dest, source) {} - - var getResult (const Scope& s) const override - { - var oldValue (target->getResult (s)); - target->assign (s, newValue->getResult (s)); - return oldValue; - } - }; - - struct FunctionCall : public Expression - { - FunctionCall (const CodeLocation& l) noexcept : Expression (l) {} - - var getResult (const Scope& s) const override - { - if (DotOperator* dot = dynamic_cast (object.get())) - { - var thisObject (dot->parent->getResult (s)); - return invokeFunction (s, s.findFunctionCall (location, thisObject, dot->child), thisObject); - } - - var function (object->getResult (s)); - return invokeFunction (s, function, var (s.scope)); - } - - var invokeFunction (const Scope& s, const var& function, const var& thisObject) const - { - s.checkTimeOut (location); - - Array argVars; - for (int i = 0; i < arguments.size(); ++i) - argVars.add (arguments.getUnchecked(i)->getResult (s)); - - const var::NativeFunctionArgs args (thisObject, argVars.begin(), argVars.size()); - - if (var::NativeFunction nativeFunction = function.getNativeFunction()) - return nativeFunction (args); - - if (FunctionObject* fo = dynamic_cast (function.getObject())) - return fo->invoke (s, args); - - location.throwError ("This expression is not a function!"); return var(); - } - - ExpPtr object; - OwnedArray arguments; - }; - - struct NewOperator : public FunctionCall - { - NewOperator (const CodeLocation& l) noexcept : FunctionCall (l) {} - - var getResult (const Scope& s) const override - { - var classOrFunc = object->getResult (s); - - const bool isFunc = isFunction (classOrFunc); - if (! (isFunc || classOrFunc.getDynamicObject() != nullptr)) - return var::undefined(); - - DynamicObject::Ptr newObject (new DynamicObject()); - - if (isFunc) - invokeFunction (s, classOrFunc, newObject.get()); - else - newObject->setProperty (getPrototypeIdentifier(), classOrFunc); - - return newObject.get(); - } - }; - - struct ObjectDeclaration : public Expression - { - ObjectDeclaration (const CodeLocation& l) noexcept : Expression (l) {} - - var getResult (const Scope& s) const override - { - DynamicObject::Ptr newObject (new DynamicObject()); - - for (int i = 0; i < names.size(); ++i) - newObject->setProperty (names.getUnchecked(i), initialisers.getUnchecked(i)->getResult (s)); - - return newObject.get(); - } - - Array names; - OwnedArray initialisers; - }; - - struct ArrayDeclaration : public Expression - { - ArrayDeclaration (const CodeLocation& l) noexcept : Expression (l) {} - - var getResult (const Scope& s) const override - { - Array a; - - for (int i = 0; i < values.size(); ++i) - a.add (values.getUnchecked(i)->getResult (s)); - - return a; - } - - OwnedArray values; - }; - - //============================================================================== - struct FunctionObject : public DynamicObject - { - FunctionObject() noexcept {} - - FunctionObject (const FunctionObject& other) : DynamicObject(), functionCode (other.functionCode) - { - ExpressionTreeBuilder tb (functionCode); - tb.parseFunctionParamsAndBody (*this); - } - - DynamicObject::Ptr clone() override { return new FunctionObject (*this); } - - void writeAsJSON (OutputStream& out, int /*indentLevel*/, bool /*allOnOneLine*/) override - { - out << "function " << functionCode; - } - - var invoke (const Scope& s, const var::NativeFunctionArgs& args) const - { - DynamicObject::Ptr functionRoot (new DynamicObject()); - - static const Identifier thisIdent ("this"); - functionRoot->setProperty (thisIdent, args.thisObject); - - for (int i = 0; i < parameters.size(); ++i) - functionRoot->setProperty (parameters.getReference(i), - i < args.numArguments ? args.arguments[i] : var::undefined()); - - var result; - body->perform (Scope (&s, s.root, functionRoot), &result); - return result; - } - - String functionCode; - Array parameters; - ScopedPointer body; - }; - - //============================================================================== - struct TokenIterator - { - TokenIterator (const String& code) : location (code), p (code.getCharPointer()) { skip(); } - - void skip() - { - skipWhitespaceAndComments(); - location.location = p; - currentType = matchNextToken(); - } - - void match (TokenType expected) - { - if (currentType != expected) - location.throwError ("Found " + getTokenName (currentType) + " when expecting " + getTokenName (expected)); - - skip(); - } - - bool matchIf (TokenType expected) { if (currentType == expected) { skip(); return true; } return false; } - bool matchesAny (TokenType t1, TokenType t2) const { return currentType == t1 || currentType == t2; } - bool matchesAny (TokenType t1, TokenType t2, TokenType t3) const { return matchesAny (t1, t2) || currentType == t3; } - - CodeLocation location; - TokenType currentType; - var currentValue; - - private: - String::CharPointerType p; - - static bool isIdentifierStart (const juce_wchar c) noexcept { return CharacterFunctions::isLetter (c) || c == '_'; } - static bool isIdentifierBody (const juce_wchar c) noexcept { return CharacterFunctions::isLetterOrDigit (c) || c == '_'; } - - TokenType matchNextToken() - { - if (isIdentifierStart (*p)) - { - String::CharPointerType end (p); - while (isIdentifierBody (*++end)) {} - - const size_t len = (size_t) (end - p); - #define JUCE_JS_COMPARE_KEYWORD(name, str) if (len == sizeof (str) - 1 && matchToken (TokenTypes::name, len)) return TokenTypes::name; - JUCE_JS_KEYWORDS (JUCE_JS_COMPARE_KEYWORD) - - currentValue = String (p, end); p = end; - return TokenTypes::identifier; - } - - if (p.isDigit()) - { - if (parseHexLiteral() || parseFloatLiteral() || parseOctalLiteral() || parseDecimalLiteral()) - return TokenTypes::literal; - - location.throwError ("Syntax error in numeric constant"); - } - - if (parseStringLiteral (*p) || (*p == '.' && parseFloatLiteral())) - return TokenTypes::literal; - - #define JUCE_JS_COMPARE_OPERATOR(name, str) if (matchToken (TokenTypes::name, sizeof (str) - 1)) return TokenTypes::name; - JUCE_JS_OPERATORS (JUCE_JS_COMPARE_OPERATOR) - - if (! p.isEmpty()) - location.throwError ("Unexpected character '" + String::charToString (*p) + "' in source"); - - return TokenTypes::eof; - } - - bool matchToken (TokenType name, const size_t len) noexcept - { - if (p.compareUpTo (CharPointer_ASCII (name), (int) len) != 0) return false; - p += (int) len; return true; - } - - void skipWhitespaceAndComments() - { - for (;;) - { - p = p.findEndOfWhitespace(); - - if (*p == '/') - { - const juce_wchar c2 = p[1]; - - if (c2 == '/') { p = CharacterFunctions::find (p, (juce_wchar) '\n'); continue; } - - if (c2 == '*') - { - location.location = p; - p = CharacterFunctions::find (p + 2, CharPointer_ASCII ("*/")); - if (p.isEmpty()) location.throwError ("Unterminated '/*' comment"); - p += 2; continue; - } - } - - break; - } - } - - bool parseStringLiteral (juce_wchar quoteType) - { - if (quoteType != '"' && quoteType != '\'') - return false; - - Result r (JSON::parseQuotedString (p, currentValue)); - if (r.failed()) location.throwError (r.getErrorMessage()); - return true; - } - - bool parseHexLiteral() - { - if (*p != '0' || (p[1] != 'x' && p[1] != 'X')) return false; - - String::CharPointerType t (++p); - int64 v = CharacterFunctions::getHexDigitValue (*++t); - if (v < 0) return false; - - for (;;) - { - const int digit = CharacterFunctions::getHexDigitValue (*++t); - if (digit < 0) break; - v = v * 16 + digit; - } - - currentValue = v; p = t; - return true; - } - - bool parseFloatLiteral() - { - int numDigits = 0; - String::CharPointerType t (p); - while (t.isDigit()) { ++t; ++numDigits; } - - const bool hasPoint = (*t == '.'); - - if (hasPoint) - while ((++t).isDigit()) ++numDigits; - - if (numDigits == 0) - return false; - - juce_wchar c = *t; - const bool hasExponent = (c == 'e' || c == 'E'); - - if (hasExponent) - { - c = *++t; - if (c == '+' || c == '-') ++t; - if (! t.isDigit()) return false; - while ((++t).isDigit()) {} - } - - if (! (hasExponent || hasPoint)) return false; - - currentValue = CharacterFunctions::getDoubleValue (p); p = t; - return true; - } - - bool parseOctalLiteral() - { - String::CharPointerType t (p); - int64 v = *t - '0'; - if (v != 0) return false; // first digit of octal must be 0 - - for (;;) - { - const int digit = (int) (*++t - '0'); - if (isPositiveAndBelow (digit, 8)) v = v * 8 + digit; - else if (isPositiveAndBelow (digit, 10)) location.throwError ("Decimal digit in octal constant"); - else break; - } - - currentValue = v; p = t; - return true; - } - - bool parseDecimalLiteral() - { - int64 v = 0; - - for (;; ++p) - { - const int digit = (int) (*p - '0'); - if (isPositiveAndBelow (digit, 10)) v = v * 10 + digit; - else break; - } - - currentValue = v; - return true; - } - }; - - //============================================================================== - struct ExpressionTreeBuilder : private TokenIterator - { - ExpressionTreeBuilder (const String code) : TokenIterator (code) {} - - BlockStatement* parseStatementList() - { - ScopedPointer b (new BlockStatement (location)); - - while (currentType != TokenTypes::closeBrace && currentType != TokenTypes::eof) - b->statements.add (parseStatement()); - - return b.release(); - } - - void parseFunctionParamsAndBody (FunctionObject& fo) - { - match (TokenTypes::openParen); - - while (currentType != TokenTypes::closeParen) - { - fo.parameters.add (currentValue.toString()); - match (TokenTypes::identifier); - - if (currentType != TokenTypes::closeParen) - match (TokenTypes::comma); - } - - match (TokenTypes::closeParen); - fo.body = parseBlock(); - } - - Expression* parseExpression() - { - ExpPtr lhs (parseLogicOperator()); - - if (matchIf (TokenTypes::question)) return parseTerneryOperator (lhs); - if (matchIf (TokenTypes::assign)) { ExpPtr rhs (parseExpression()); return new Assignment (location, lhs, rhs); } - if (matchIf (TokenTypes::plusEquals)) return parseInPlaceOpExpression (lhs); - if (matchIf (TokenTypes::minusEquals)) return parseInPlaceOpExpression (lhs); - if (matchIf (TokenTypes::leftShiftEquals)) return parseInPlaceOpExpression (lhs); - if (matchIf (TokenTypes::rightShiftEquals)) return parseInPlaceOpExpression (lhs); - - return lhs.release(); - } - - private: - void throwError (const String& err) const { location.throwError (err); } - - template - Expression* parseInPlaceOpExpression (ExpPtr& lhs) - { - ExpPtr rhs (parseExpression()); - Expression* bareLHS = lhs; // careful - bare pointer is deliberately alised - return new SelfAssignment (location, bareLHS, new OpType (location, lhs, rhs)); - } - - BlockStatement* parseBlock() - { - match (TokenTypes::openBrace); - ScopedPointer b (parseStatementList()); - match (TokenTypes::closeBrace); - return b.release(); - } - - Statement* parseStatement() - { - if (currentType == TokenTypes::openBrace) return parseBlock(); - if (matchIf (TokenTypes::var)) return parseVar(); - if (matchIf (TokenTypes::if_)) return parseIf(); - if (matchIf (TokenTypes::while_)) return parseDoOrWhileLoop (false); - if (matchIf (TokenTypes::do_)) return parseDoOrWhileLoop (true); - if (matchIf (TokenTypes::for_)) return parseForLoop(); - if (matchIf (TokenTypes::return_)) return new ReturnStatement (location, matchIf (TokenTypes::semicolon) ? new Expression (location) : parseExpression()); - if (matchIf (TokenTypes::break_)) return new BreakStatement (location); - if (matchIf (TokenTypes::continue_)) return new ContinueStatement (location); - if (matchIf (TokenTypes::function)) return parseFunction(); - if (matchIf (TokenTypes::semicolon)) return new Statement (location); - if (matchIf (TokenTypes::plusplus)) return parsePreIncDec(); - if (matchIf (TokenTypes::minusminus)) return parsePreIncDec(); - - if (matchesAny (TokenTypes::openParen, TokenTypes::openBracket)) - return matchEndOfStatement (parseFactor()); - - if (matchesAny (TokenTypes::identifier, TokenTypes::literal, TokenTypes::minus)) - return matchEndOfStatement (parseExpression()); - - throwError ("Found " + getTokenName (currentType) + " when expecting a statement"); - return nullptr; - } - - Expression* matchEndOfStatement (Expression* ex) { ExpPtr e (ex); if (currentType != TokenTypes::eof) match (TokenTypes::semicolon); return e.release(); } - Expression* matchCloseParen (Expression* ex) { ExpPtr e (ex); match (TokenTypes::closeParen); return e.release(); } - - Statement* parseIf() - { - ScopedPointer s (new IfStatement (location)); - match (TokenTypes::openParen); - s->condition = parseExpression(); - match (TokenTypes::closeParen); - s->trueBranch = parseStatement(); - s->falseBranch = matchIf (TokenTypes::else_) ? parseStatement() : new Statement (location); - return s.release(); - } - - Statement* parseVar() - { - ScopedPointer s (new VarStatement (location)); - s->name = parseIdentifier(); - s->initialiser = matchIf (TokenTypes::assign) ? parseExpression() : new Expression (location); - - if (matchIf (TokenTypes::comma)) - { - ScopedPointer block (new BlockStatement (location)); - block->statements.add (s.release()); - block->statements.add (parseVar()); - return block.release(); - } - - match (TokenTypes::semicolon); - return s.release(); - } - - Statement* parseFunction() - { - Identifier name; - var fn = parseFunctionDefinition (name); - - if (name.isNull()) - throwError ("Functions defined at statement-level must have a name"); - - ExpPtr nm (new UnqualifiedName (location, name)), value (new LiteralValue (location, fn)); - return new Assignment (location, nm, value); - } - - Statement* parseForLoop() - { - ScopedPointer s (new LoopStatement (location, false)); - match (TokenTypes::openParen); - s->initialiser = parseStatement(); - - if (matchIf (TokenTypes::semicolon)) - s->condition = new LiteralValue (location, true); - else - { - s->condition = parseExpression(); - match (TokenTypes::semicolon); - } - - if (matchIf (TokenTypes::closeParen)) - s->iterator = new Statement (location); - else - { - s->iterator = parseExpression(); - match (TokenTypes::closeParen); - } - - s->body = parseStatement(); - return s.release(); - } - - Statement* parseDoOrWhileLoop (bool isDoLoop) - { - ScopedPointer s (new LoopStatement (location, isDoLoop)); - s->initialiser = new Statement (location); - s->iterator = new Statement (location); - - if (isDoLoop) - { - s->body = parseBlock(); - match (TokenTypes::while_); - } - - match (TokenTypes::openParen); - s->condition = parseExpression(); - match (TokenTypes::closeParen); - - if (! isDoLoop) - s->body = parseStatement(); - - return s.release(); - } - - Identifier parseIdentifier() - { - Identifier i; - if (currentType == TokenTypes::identifier) - i = currentValue.toString(); - - match (TokenTypes::identifier); - return i; - } - - var parseFunctionDefinition (Identifier& functionName) - { - const String::CharPointerType functionStart (location.location); - - if (currentType == TokenTypes::identifier) - functionName = parseIdentifier(); - - ScopedPointer fo (new FunctionObject()); - parseFunctionParamsAndBody (*fo); - fo->functionCode = String (functionStart, location.location); - return var (fo.release()); - } - - Expression* parseFunctionCall (FunctionCall* call, ExpPtr& function) - { - ScopedPointer s (call); - s->object = function; - match (TokenTypes::openParen); - - while (currentType != TokenTypes::closeParen) - { - s->arguments.add (parseExpression()); - if (currentType != TokenTypes::closeParen) - match (TokenTypes::comma); - } - - return matchCloseParen (s.release()); - } - - Expression* parseSuffixes (Expression* e) - { - ExpPtr input (e); - - if (matchIf (TokenTypes::dot)) - return parseSuffixes (new DotOperator (location, input, parseIdentifier())); - - if (currentType == TokenTypes::openParen) - return parseSuffixes (parseFunctionCall (new FunctionCall (location), input)); - - if (matchIf (TokenTypes::openBracket)) - { - ScopedPointer s (new ArraySubscript (location)); - s->object = input; - s->index = parseExpression(); - match (TokenTypes::closeBracket); - return parseSuffixes (s.release()); - } - - if (matchIf (TokenTypes::plusplus)) return parsePostIncDec (input); - if (matchIf (TokenTypes::minusminus)) return parsePostIncDec (input); - - return input.release(); - } - - Expression* parseFactor() - { - if (currentType == TokenTypes::identifier) return parseSuffixes (new UnqualifiedName (location, parseIdentifier())); - if (matchIf (TokenTypes::openParen)) return parseSuffixes (matchCloseParen (parseExpression())); - if (matchIf (TokenTypes::true_)) return parseSuffixes (new LiteralValue (location, (int) 1)); - if (matchIf (TokenTypes::false_)) return parseSuffixes (new LiteralValue (location, (int) 0)); - if (matchIf (TokenTypes::null_)) return parseSuffixes (new LiteralValue (location, var())); - if (matchIf (TokenTypes::undefined)) return parseSuffixes (new Expression (location)); - - if (currentType == TokenTypes::literal) - { - var v (currentValue); skip(); - return parseSuffixes (new LiteralValue (location, v)); - } - - if (matchIf (TokenTypes::openBrace)) - { - ScopedPointer e (new ObjectDeclaration (location)); - - while (currentType != TokenTypes::closeBrace) - { - e->names.add (currentValue.toString()); - match ((currentType == TokenTypes::literal && currentValue.isString()) - ? TokenTypes::literal : TokenTypes::identifier); - match (TokenTypes::colon); - e->initialisers.add (parseExpression()); - - if (currentType != TokenTypes::closeBrace) - match (TokenTypes::comma); - } - - match (TokenTypes::closeBrace); - return parseSuffixes (e.release()); - } - - if (matchIf (TokenTypes::openBracket)) - { - ScopedPointer e (new ArrayDeclaration (location)); - - while (currentType != TokenTypes::closeBracket) - { - e->values.add (parseExpression()); - - if (currentType != TokenTypes::closeBracket) - match (TokenTypes::comma); - } - - match (TokenTypes::closeBracket); - return parseSuffixes (e.release()); - } - - if (matchIf (TokenTypes::function)) - { - Identifier name; - var fn = parseFunctionDefinition (name); - - if (name.isValid()) - throwError ("Inline functions definitions cannot have a name"); - - return new LiteralValue (location, fn); - } - - if (matchIf (TokenTypes::new_)) - { - ExpPtr name (new UnqualifiedName (location, parseIdentifier())); - - while (matchIf (TokenTypes::dot)) - name = new DotOperator (location, name, parseIdentifier()); - - return parseFunctionCall (new NewOperator (location), name); - } - - throwError ("Found " + getTokenName (currentType) + " when expecting an expression"); - return nullptr; - } - - template - Expression* parsePreIncDec() - { - Expression* e = parseFactor(); // careful - bare pointer is deliberately alised - ExpPtr lhs (e), one (new LiteralValue (location, (int) 1)); - return new SelfAssignment (location, e, new OpType (location, lhs, one)); - } - - template - Expression* parsePostIncDec (ExpPtr& lhs) - { - Expression* e = lhs.release(); // careful - bare pointer is deliberately alised - ExpPtr lhs2 (e), one (new LiteralValue (location, (int) 1)); - return new PostAssignment (location, e, new OpType (location, lhs2, one)); - } - - Expression* parseUnary() - { - if (matchIf (TokenTypes::minus)) { ExpPtr a (new LiteralValue (location, (int) 0)), b (parseUnary()); return new SubtractionOp (location, a, b); } - if (matchIf (TokenTypes::logicalNot)) { ExpPtr a (new LiteralValue (location, (int) 0)), b (parseUnary()); return new EqualsOp (location, a, b); } - if (matchIf (TokenTypes::plusplus)) return parsePreIncDec(); - if (matchIf (TokenTypes::minusminus)) return parsePreIncDec(); - - return parseFactor(); - } - - Expression* parseMultiplyDivide() - { - ExpPtr a (parseUnary()); - - for (;;) - { - if (matchIf (TokenTypes::times)) { ExpPtr b (parseUnary()); a = new MultiplyOp (location, a, b); } - else if (matchIf (TokenTypes::divide)) { ExpPtr b (parseUnary()); a = new DivideOp (location, a, b); } - else if (matchIf (TokenTypes::modulo)) { ExpPtr b (parseUnary()); a = new ModuloOp (location, a, b); } - else break; - } - - return a.release(); - } - - Expression* parseAdditionSubtraction() - { - ExpPtr a (parseMultiplyDivide()); - - for (;;) - { - if (matchIf (TokenTypes::plus)) { ExpPtr b (parseMultiplyDivide()); a = new AdditionOp (location, a, b); } - else if (matchIf (TokenTypes::minus)) { ExpPtr b (parseMultiplyDivide()); a = new SubtractionOp (location, a, b); } - else break; - } - - return a.release(); - } - - Expression* parseShiftOperator() - { - ExpPtr a (parseAdditionSubtraction()); - - for (;;) - { - if (matchIf (TokenTypes::leftShift)) { ExpPtr b (parseExpression()); a = new LeftShiftOp (location, a, b); } - else if (matchIf (TokenTypes::rightShift)) { ExpPtr b (parseExpression()); a = new RightShiftOp (location, a, b); } - else if (matchIf (TokenTypes::rightShiftUnsigned)) { ExpPtr b (parseExpression()); a = new RightShiftUnsignedOp (location, a, b); } - else break; - } - - return a.release(); - } - - Expression* parseComparator() - { - ExpPtr a (parseShiftOperator()); - - for (;;) - { - if (matchIf (TokenTypes::equals)) { ExpPtr b (parseShiftOperator()); a = new EqualsOp (location, a, b); } - else if (matchIf (TokenTypes::notEquals)) { ExpPtr b (parseShiftOperator()); a = new NotEqualsOp (location, a, b); } - else if (matchIf (TokenTypes::typeEquals)) { ExpPtr b (parseShiftOperator()); a = new TypeEqualsOp (location, a, b); } - else if (matchIf (TokenTypes::typeNotEquals)) { ExpPtr b (parseShiftOperator()); a = new TypeNotEqualsOp (location, a, b); } - else if (matchIf (TokenTypes::lessThan)) { ExpPtr b (parseShiftOperator()); a = new LessThanOp (location, a, b); } - else if (matchIf (TokenTypes::lessThanOrEqual)) { ExpPtr b (parseShiftOperator()); a = new LessThanOrEqualOp (location, a, b); } - else if (matchIf (TokenTypes::greaterThan)) { ExpPtr b (parseShiftOperator()); a = new GreaterThanOp (location, a, b); } - else if (matchIf (TokenTypes::greaterThanOrEqual)) { ExpPtr b (parseShiftOperator()); a = new GreaterThanOrEqualOp (location, a, b); } - else break; - } - - return a.release(); - } - - Expression* parseLogicOperator() - { - ExpPtr a (parseComparator()); - - for (;;) - { - if (matchIf (TokenTypes::logicalAnd)) { ExpPtr b (parseComparator()); a = new LogicalAndOp (location, a, b); } - else if (matchIf (TokenTypes::logicalOr)) { ExpPtr b (parseComparator()); a = new LogicalOrOp (location, a, b); } - else if (matchIf (TokenTypes::bitwiseAnd)) { ExpPtr b (parseComparator()); a = new BitwiseAndOp (location, a, b); } - else if (matchIf (TokenTypes::bitwiseOr)) { ExpPtr b (parseComparator()); a = new BitwiseOrOp (location, a, b); } - else if (matchIf (TokenTypes::bitwiseXor)) { ExpPtr b (parseComparator()); a = new BitwiseXorOp (location, a, b); } - else break; - } - - return a.release(); - } - - Expression* parseTerneryOperator (ExpPtr& condition) - { - ScopedPointer e (new ConditionalOp (location)); - e->condition = condition; - e->trueBranch = parseExpression(); - match (TokenTypes::colon); - e->falseBranch = parseExpression(); - return e.release(); - } - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ExpressionTreeBuilder) - }; - - //============================================================================== - static var get (Args a, int index) noexcept { return index < a.numArguments ? a.arguments[index] : var(); } - static bool isInt (Args a, int index) noexcept { return get (a, index).isInt() || get (a, index).isInt64(); } - static int getInt (Args a, int index) noexcept { return get (a, index); } - static double getDouble (Args a, int index) noexcept { return get (a, index); } - static String getString (Args a, int index) noexcept { return get (a, index).toString(); } - - //============================================================================== - struct ObjectClass : public DynamicObject - { - ObjectClass() - { - setMethod ("dump", dump); - setMethod ("clone", clone); - } - - static Identifier getClassName() { static const Identifier i ("Object"); return i; } - static var dump (Args a) { DBG (JSON::toString (a.thisObject)); (void) a; return var::undefined(); } - static var clone (Args a) { return a.thisObject.clone(); } - }; - - //============================================================================== - struct ArrayClass : public DynamicObject - { - ArrayClass() - { - setMethod ("contains", contains); - setMethod ("remove", remove); - setMethod ("join", join); - } - - static Identifier getClassName() { static const Identifier i ("Array"); return i; } - - static var contains (Args a) - { - if (const Array* array = a.thisObject.getArray()) - return array->contains (get (a, 0)); - - return false; - } - - static var remove (Args a) - { - if (Array* array = a.thisObject.getArray()) - array->removeAllInstancesOf (get (a, 0)); - - return var::undefined(); - } - - static var join (Args a) - { - StringArray strings; - - if (const Array* array = a.thisObject.getArray()) - for (int i = 0; i < array->size(); ++i) - strings.add (array->getReference(i).toString()); - - return strings.joinIntoString (getString (a, 0)); - } - }; - - //============================================================================== - struct StringClass : public DynamicObject - { - StringClass() - { - setMethod ("substring", substring); - setMethod ("indexOf", indexOf); - setMethod ("charAt", charAt); - setMethod ("charCodeAt", charCodeAt); - setMethod ("fromCharCode", fromCharCode); - setMethod ("split", split); - } - - static Identifier getClassName() { static const Identifier i ("String"); return i; } - - static var fromCharCode (Args a) { return String::charToString (getInt (a, 0)); } - static var substring (Args a) { return a.thisObject.toString().substring (getInt (a, 0), getInt (a, 1)); } - static var indexOf (Args a) { return a.thisObject.toString().indexOf (getString (a, 0)); } - static var charCodeAt (Args a) { return (int) a.thisObject.toString() [getInt (a, 0)]; } - static var charAt (Args a) { int p = getInt (a, 0); return a.thisObject.toString().substring (p, p + 1); } - - static var split (Args a) - { - const String str (a.thisObject.toString()); - const String sep (getString (a, 0)); - StringArray strings; - - if (sep.isNotEmpty()) - strings.addTokens (str, sep.substring (0, 1), ""); - else // special-case for empty separator: split all chars separately - for (String::CharPointerType pos = str.getCharPointer(); ! pos.isEmpty(); ++pos) - strings.add (String::charToString (*pos)); - - var array; - for (int i = 0; i < strings.size(); ++i) - array.append (strings[i]); - - return array; - } - }; - - //============================================================================== - struct MathClass : public DynamicObject - { - MathClass() - { - setMethod ("abs", Math_abs); setMethod ("round", Math_round); - setMethod ("random", Math_random); setMethod ("randInt", Math_randInt); - setMethod ("min", Math_min); setMethod ("max", Math_max); - setMethod ("range", Math_range); setMethod ("sign", Math_sign); - setMethod ("PI", Math_pi); setMethod ("E", Math_e); - setMethod ("toDegrees", Math_toDegrees); setMethod ("toRadians", Math_toRadians); - setMethod ("sin", Math_sin); setMethod ("asin", Math_asin); - setMethod ("sinh", Math_sinh); setMethod ("asinh", Math_asinh); - setMethod ("cos", Math_cos); setMethod ("acos", Math_acos); - setMethod ("cosh", Math_cosh); setMethod ("acosh", Math_acosh); - setMethod ("tan", Math_tan); setMethod ("atan", Math_atan); - setMethod ("tanh", Math_tanh); setMethod ("atanh", Math_atanh); - setMethod ("log", Math_log); setMethod ("log10", Math_log10); - setMethod ("exp", Math_exp); setMethod ("pow", Math_pow); - setMethod ("sqr", Math_sqr); setMethod ("sqrt", Math_sqrt); - setMethod ("ceil", Math_ceil); setMethod ("floor", Math_floor); - } - - static var Math_pi (Args) { return double_Pi; } - static var Math_e (Args) { return exp (1.0); } - static var Math_random (Args) { return Random::getSystemRandom().nextDouble(); } - static var Math_randInt (Args a) { return Random::getSystemRandom().nextInt (Range (getInt (a, 0), getInt (a, 1))); } - static var Math_abs (Args a) { return isInt (a, 0) ? var (std::abs (getInt (a, 0))) : var (std::abs (getDouble (a, 0))); } - static var Math_round (Args a) { return isInt (a, 0) ? var (roundToInt (getInt (a, 0))) : var (roundToInt (getDouble (a, 0))); } - static var Math_sign (Args a) { return isInt (a, 0) ? var (sign (getInt (a, 0))) : var (sign (getDouble (a, 0))); } - static var Math_range (Args a) { return isInt (a, 0) ? var (jlimit (getInt (a, 1), getInt (a, 2), getInt (a, 0))) : var (jlimit (getDouble (a, 1), getDouble (a, 2), getDouble (a, 0))); } - static var Math_min (Args a) { return (isInt (a, 0) && isInt (a, 1)) ? var (jmin (getInt (a, 0), getInt (a, 1))) : var (jmin (getDouble (a, 0), getDouble (a, 1))); } - static var Math_max (Args a) { return (isInt (a, 0) && isInt (a, 1)) ? var (jmax (getInt (a, 0), getInt (a, 1))) : var (jmax (getDouble (a, 0), getDouble (a, 1))); } - static var Math_toDegrees (Args a) { return (180.0 / double_Pi) * getDouble (a, 0); } - static var Math_toRadians (Args a) { return (double_Pi / 180.0) * getDouble (a, 0); } - static var Math_sin (Args a) { return sin (getDouble (a, 0)); } - static var Math_asin (Args a) { return asin (getDouble (a, 0)); } - static var Math_cos (Args a) { return cos (getDouble (a, 0)); } - static var Math_acos (Args a) { return acos (getDouble (a, 0)); } - static var Math_sinh (Args a) { return sinh (getDouble (a, 0)); } - static var Math_asinh (Args a) { return asinh (getDouble (a, 0)); } - static var Math_cosh (Args a) { return cosh (getDouble (a, 0)); } - static var Math_acosh (Args a) { return acosh (getDouble (a, 0)); } - static var Math_tan (Args a) { return tan (getDouble (a, 0)); } - static var Math_tanh (Args a) { return tanh (getDouble (a, 0)); } - static var Math_atan (Args a) { return atan (getDouble (a, 0)); } - static var Math_atanh (Args a) { return atanh (getDouble (a, 0)); } - static var Math_log (Args a) { return log (getDouble (a, 0)); } - static var Math_log10 (Args a) { return log10 (getDouble (a, 0)); } - static var Math_exp (Args a) { return exp (getDouble (a, 0)); } - static var Math_pow (Args a) { return pow (getDouble (a, 0), getDouble (a, 1)); } - static var Math_sqr (Args a) { double x = getDouble (a, 0); return x * x; } - static var Math_sqrt (Args a) { return std::sqrt (getDouble (a, 0)); } - static var Math_ceil (Args a) { return std::ceil (getDouble (a, 0)); } - static var Math_floor (Args a) { return std::floor (getDouble (a, 0)); } - - static Identifier getClassName() { static const Identifier i ("Math"); return i; } - template static Type sign (Type n) noexcept { return n > 0 ? (Type) 1 : (n < 0 ? (Type) -1 : 0); } - }; - - //============================================================================== - struct JSONClass : public DynamicObject - { - JSONClass() { setMethod ("stringify", stringify); } - static Identifier getClassName() { static const Identifier i ("JSON"); return i; } - static var stringify (Args a) { return JSON::toString (get (a, 0)); } - }; - - //============================================================================== - struct IntegerClass : public DynamicObject - { - IntegerClass() { setMethod ("parseInt", parseInt); } - static Identifier getClassName() { static const Identifier i ("Integer"); return i; } - - static var parseInt (Args a) - { - const String s (getString (a, 0).trim()); - - return s[0] == '0' ? (s[1] == 'x' ? s.substring(2).getHexValue64() : getOctalValue (s)) - : s.getLargeIntValue(); - } - }; - - //============================================================================== - static var trace (Args a) { Logger::outputDebugString (JSON::toString (a.thisObject)); return var::undefined(); } - static var charToInt (Args a) { return (int) (getString (a, 0)[0]); } - - static var exec (Args a) - { - if (RootObject* root = dynamic_cast (a.thisObject.getObject())) - root->execute (getString (a, 0)); - - return var::undefined(); - } - - static var eval (Args a) - { - if (RootObject* root = dynamic_cast (a.thisObject.getObject())) - return root->evaluate (getString (a, 0)); - - return var::undefined(); - } -}; - -//============================================================================== -JavascriptEngine::JavascriptEngine() : maximumExecutionTime (15.0), root (new RootObject()) -{ - registerNativeObject (RootObject::ObjectClass ::getClassName(), new RootObject::ObjectClass()); - registerNativeObject (RootObject::ArrayClass ::getClassName(), new RootObject::ArrayClass()); - registerNativeObject (RootObject::StringClass ::getClassName(), new RootObject::StringClass()); - registerNativeObject (RootObject::MathClass ::getClassName(), new RootObject::MathClass()); - registerNativeObject (RootObject::JSONClass ::getClassName(), new RootObject::JSONClass()); - registerNativeObject (RootObject::IntegerClass ::getClassName(), new RootObject::IntegerClass()); -} - -JavascriptEngine::~JavascriptEngine() {} - -void JavascriptEngine::prepareTimeout() const noexcept { root->timeout = Time::getCurrentTime() + maximumExecutionTime; } - -void JavascriptEngine::registerNativeObject (Identifier name, DynamicObject* object) -{ - root->setProperty (name, object); -} - -Result JavascriptEngine::execute (const String& code) -{ - try - { - prepareTimeout(); - root->execute (code); - } - catch (String& error) - { - return Result::fail (error); - } - - return Result::ok(); -} - -var JavascriptEngine::evaluate (const String& code, Result* result) -{ - try - { - prepareTimeout(); - if (result != nullptr) *result = Result::ok(); - return root->evaluate (code); - } - catch (String& error) - { - if (result != nullptr) *result = Result::fail (error); - } - - return var::undefined(); -} - -var JavascriptEngine::callFunction (Identifier function, const var::NativeFunctionArgs& args, Result* result) -{ - var returnVal (var::undefined()); - - try - { - prepareTimeout(); - if (result != nullptr) *result = Result::ok(); - RootObject::Scope (nullptr, root, root).findAndInvokeMethod (function, args, returnVal); - } - catch (String& error) - { - if (result != nullptr) *result = Result::fail (error); - } - - return returnVal; -} - -const NamedValueSet& JavascriptEngine::getRootObjectProperties() const noexcept -{ - return root->getProperties(); -} - -#if JUCE_MSVC - #pragma warning (pop) -#endif diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/javascript/juce_Javascript.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/javascript/juce_Javascript.h deleted file mode 100644 index eafc3cdb60..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/javascript/juce_Javascript.h +++ /dev/null @@ -1,108 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -/** - A simple javascript interpreter! - - It's not fully standards-compliant, and won't be as fast as the fancy JIT-compiled - engines that you get in browsers, but this is an extremely compact, low-overhead javascript - interpreter, which is integrated with the juce var and DynamicObject classes. If you need - a few simple bits of scripting in your app, and want to be able to easily let the JS - work with native objects defined as DynamicObject subclasses, then this might do the job. - - To use, simply create an instance of this class and call execute() to run your code. - Variables that the script sets can be retrieved with evaluate(), and if you need to provide - native objects for the script to use, you can add them with registerNativeObject(). - - One caveat: Because the values and objects that the engine works with are DynamicObject - and var objects, they use reference-counting rather than garbage-collection, so if your - script creates complex connections between objects, you run the risk of creating cyclic - dependencies and hence leaking. -*/ -class JavascriptEngine -{ -public: - /** Creates an instance of the engine. - This creates a root namespace and defines some basic Object, String, Array - and Math library methods. - */ - JavascriptEngine(); - - /** Destructor. */ - ~JavascriptEngine(); - - /** Attempts to parse and run a block of javascript code. - If there's a parse or execution error, the error description is returned in - the result. - You can specify a maximum time for which the program is allowed to run, and - it'll return with an error message if this time is exceeded. - */ - Result execute (const String& javascriptCode); - - /** Attempts to parse and run a javascript expression, and returns the result. - If there's a syntax error, or the expression can't be evaluated, the return value - will be var::undefined(). The errorMessage parameter gives you a way to find out - any parsing errors. - You can specify a maximum time for which the program is allowed to run, and - it'll return with an error message if this time is exceeded. - */ - var evaluate (const String& javascriptCode, - Result* errorMessage = nullptr); - - /** Calls a function in the root namespace, and returns the result. - The function arguments are passed in the same format as used by native - methods in the var class. - */ - var callFunction (Identifier function, - const var::NativeFunctionArgs& args, - Result* errorMessage = nullptr); - - /** Adds a native object to the root namespace. - The object passed-in is reference-counted, and will be retained by the - engine until the engine is deleted. The name must be a simple JS identifier, - without any dots. - */ - void registerNativeObject (Identifier objectName, DynamicObject* object); - - /** This value indicates how long a call to one of the evaluate methods is permitted - to run before timing-out and failing. - The default value is a number of seconds, but you can change this to whatever value - suits your application. - */ - RelativeTime maximumExecutionTime; - - /** Provides access to the set of properties of the root namespace object. */ - const NamedValueSet& getRootObjectProperties() const noexcept; - -private: - JUCE_PUBLIC_IN_DLL_BUILD (struct RootObject) - const ReferenceCountedObjectPtr root; - void prepareTimeout() const noexcept; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (JavascriptEngine) -}; diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/juce_core.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/juce_core.cpp deleted file mode 100644 index 7cfc664537..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/juce_core.cpp +++ /dev/null @@ -1,226 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#if defined (JUCE_CORE_H_INCLUDED) && ! JUCE_AMALGAMATED_INCLUDE - /* When you add this cpp file to your project, you mustn't include it in a file where you've - already included any other headers - just put it inside a file on its own, possibly with your config - flags preceding it, but don't include anything else. That also includes avoiding any automatic prefix - header files that the compiler may be using. - */ - #error "Incorrect use of JUCE cpp file" -#endif - -// Your project must contain an AppConfig.h file with your project-specific settings in it, -// and your header search path must make it accessible to the module's files. -#include "AppConfig.h" - -//============================================================================== -#include "native/juce_BasicNativeHeaders.h" -#include "juce_core.h" - -#include -#include -#include - -#if ! JUCE_ANDROID - #include -#endif - -#if JUCE_WINDOWS - #include - - #define _WINSOCK_DEPRECATED_NO_WARNINGS 1 - #include - #include - - #if ! JUCE_MINGW - #include - - #if ! JUCE_DONT_AUTOLINK_TO_WIN32_LIBRARIES - #pragma comment (lib, "DbgHelp.lib") - #endif - #endif - - #if JUCE_MINGW - #include - #endif - -#else - #if JUCE_LINUX || JUCE_ANDROID - #include - #include - #include - #include - #include - #endif - - #if JUCE_LINUX - #include - #include - #endif - - #include - #include - #include - #include - #include - #include - #include - #include - - #if ! JUCE_ANDROID - #include - #endif -#endif - -#if JUCE_MAC || JUCE_IOS - #include - #include -#endif - -#if JUCE_ANDROID - #include -#endif - - -//============================================================================== -namespace juce -{ - -#include "containers/juce_AbstractFifo.cpp" -#include "containers/juce_NamedValueSet.cpp" -#include "containers/juce_PropertySet.cpp" -#include "containers/juce_Variant.cpp" -#include "files/juce_DirectoryIterator.cpp" -#include "files/juce_File.cpp" -#include "files/juce_FileInputStream.cpp" -#include "files/juce_FileOutputStream.cpp" -#include "files/juce_FileSearchPath.cpp" -#include "files/juce_TemporaryFile.cpp" -#include "javascript/juce_JSON.cpp" -#include "javascript/juce_Javascript.cpp" -#include "containers/juce_DynamicObject.cpp" -#include "logging/juce_FileLogger.cpp" -#include "logging/juce_Logger.cpp" -#include "maths/juce_BigInteger.cpp" -#include "maths/juce_Expression.cpp" -#include "maths/juce_Random.cpp" -#include "memory/juce_MemoryBlock.cpp" -#include "misc/juce_Result.cpp" -#include "misc/juce_Uuid.cpp" -#include "network/juce_MACAddress.cpp" -#include "network/juce_NamedPipe.cpp" -#include "network/juce_Socket.cpp" -#include "network/juce_IPAddress.cpp" -#include "streams/juce_BufferedInputStream.cpp" -#include "streams/juce_FileInputSource.cpp" -#include "streams/juce_InputStream.cpp" -#include "streams/juce_MemoryInputStream.cpp" -#include "streams/juce_MemoryOutputStream.cpp" -#include "streams/juce_SubregionStream.cpp" -#include "system/juce_SystemStats.cpp" -#include "text/juce_CharacterFunctions.cpp" -#include "text/juce_Identifier.cpp" -#include "text/juce_LocalisedStrings.cpp" -#include "text/juce_String.cpp" -#include "streams/juce_OutputStream.cpp" -#include "text/juce_StringArray.cpp" -#include "text/juce_StringPairArray.cpp" -#include "text/juce_StringPool.cpp" -#include "text/juce_TextDiff.cpp" -#include "threads/juce_ReadWriteLock.cpp" -#include "threads/juce_Thread.cpp" -#include "threads/juce_ThreadPool.cpp" -#include "threads/juce_TimeSliceThread.cpp" -#include "time/juce_PerformanceCounter.cpp" -#include "time/juce_RelativeTime.cpp" -#include "time/juce_Time.cpp" -#include "unit_tests/juce_UnitTest.cpp" -#include "xml/juce_XmlDocument.cpp" -#include "xml/juce_XmlElement.cpp" -#include "zip/juce_GZIPDecompressorInputStream.cpp" -#include "zip/juce_GZIPCompressorOutputStream.cpp" -#include "zip/juce_ZipFile.cpp" -#include "files/juce_FileFilter.cpp" -#include "files/juce_WildcardFileFilter.cpp" - -//============================================================================== -#if JUCE_MAC || JUCE_IOS -#include "native/juce_osx_ObjCHelpers.h" -#endif - -#if JUCE_ANDROID -#include "native/juce_android_JNIHelpers.h" -#endif - -#if ! JUCE_WINDOWS -#include "native/juce_posix_SharedCode.h" -#include "native/juce_posix_NamedPipe.cpp" -#endif - -//============================================================================== -#if JUCE_MAC || JUCE_IOS -#include "native/juce_mac_Files.mm" -#include "native/juce_mac_Network.mm" -#include "native/juce_mac_Strings.mm" -#include "native/juce_mac_SystemStats.mm" -#include "native/juce_mac_Threads.mm" - -//============================================================================== -#elif JUCE_WINDOWS -#include "native/juce_win32_ComSmartPtr.h" -#include "native/juce_win32_Files.cpp" -#include "native/juce_win32_Network.cpp" -#include "native/juce_win32_Registry.cpp" -#include "native/juce_win32_SystemStats.cpp" -#include "native/juce_win32_Threads.cpp" - -//============================================================================== -#elif JUCE_LINUX -#include "native/juce_linux_CommonFile.cpp" -#include "native/juce_linux_Files.cpp" -#include "native/juce_linux_Network.cpp" -#include "native/juce_linux_SystemStats.cpp" -#include "native/juce_linux_Threads.cpp" - -//============================================================================== -#elif JUCE_ANDROID -#include "native/juce_linux_CommonFile.cpp" -#include "native/juce_android_Files.cpp" -#include "native/juce_android_Misc.cpp" -#include "native/juce_android_Network.cpp" -#include "native/juce_android_SystemStats.cpp" -#include "native/juce_android_Threads.cpp" - -#endif - -#include "threads/juce_ChildProcess.cpp" -#include "threads/juce_HighResolutionTimer.cpp" -#include "network/juce_URL.cpp" - -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/juce_core.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/juce_core.h index ce5219ee83..ee07e01a50 100644 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/juce_core.h +++ b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/juce_core.h @@ -1,285 +1,5 @@ -/* - ============================================================================== +// This is an auto-generated file to redirect any included +// module headers to the correct external folder. - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. +#include "../../../../../modules/juce_core/juce_core.h" - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_CORE_H_INCLUDED -#define JUCE_CORE_H_INCLUDED - -#ifndef JUCE_MODULE_AVAILABLE_juce_core - /* If you fail to make sure that all your compile units are building JUCE with the same set of - option flags, then there's a risk that different compile units will treat the classes as having - different memory layouts, leading to very nasty memory corruption errors when they all get - linked together. That's why it's best to always include the Introjucer-generated AppConfig.h - file before any juce headers. - - Note that if you do have an AppConfig.h file and hit this warning, it means that it doesn't - contain the JUCE_MODULE_AVAILABLE_xxx flags, which are necessary for some inter-module - functionality to work correctly. In that case, you should either rebuild your AppConfig.h with - the latest introjucer, or fix it manually to contain these flags. - */ - #ifdef _MSC_VER - #pragma message ("Have you included your AppConfig.h file before including the JUCE headers?") - #else - #warning "Have you included your AppConfig.h file before including the JUCE headers?" - #endif -#endif - -//============================================================================== -#include "system/juce_TargetPlatform.h" - -//============================================================================= -/** Config: JUCE_FORCE_DEBUG - - Normally, JUCE_DEBUG is set to 1 or 0 based on compiler and project settings, - but if you define this value, you can override this to force it to be true or false. -*/ -#ifndef JUCE_FORCE_DEBUG - //#define JUCE_FORCE_DEBUG 0 -#endif - -//============================================================================= -/** Config: JUCE_LOG_ASSERTIONS - - If this flag is enabled, the jassert and jassertfalse macros will always use Logger::writeToLog() - to write a message when an assertion happens. - - Enabling it will also leave this turned on in release builds. When it's disabled, - however, the jassert and jassertfalse macros will not be compiled in a - release build. - - @see jassert, jassertfalse, Logger -*/ -#ifndef JUCE_LOG_ASSERTIONS - #if JUCE_ANDROID - #define JUCE_LOG_ASSERTIONS 1 - #else - #define JUCE_LOG_ASSERTIONS 0 - #endif -#endif - -//============================================================================= -/** Config: JUCE_CHECK_MEMORY_LEAKS - - Enables a memory-leak check for certain objects when the app terminates. See the LeakedObjectDetector - class and the JUCE_LEAK_DETECTOR macro for more details about enabling leak checking for specific classes. -*/ -#if JUCE_DEBUG && ! defined (JUCE_CHECK_MEMORY_LEAKS) - #define JUCE_CHECK_MEMORY_LEAKS 1 -#endif - -//============================================================================= -/** Config: JUCE_DONT_AUTOLINK_TO_WIN32_LIBRARIES - - In a Visual C++ build, this can be used to stop the required system libs being - automatically added to the link stage. -*/ -#ifndef JUCE_DONT_AUTOLINK_TO_WIN32_LIBRARIES - #define JUCE_DONT_AUTOLINK_TO_WIN32_LIBRARIES 0 -#endif - -/** Config: JUCE_INCLUDE_ZLIB_CODE - This can be used to disable Juce's embedded 3rd-party zlib code. - You might need to tweak this if you're linking to an external zlib library in your app, - but for normal apps, this option should be left alone. - - If you disable this, you might also want to set a value for JUCE_ZLIB_INCLUDE_PATH, to - specify the path where your zlib headers live. -*/ -#ifndef JUCE_INCLUDE_ZLIB_CODE - #define JUCE_INCLUDE_ZLIB_CODE 1 -#endif - -#ifndef JUCE_ZLIB_INCLUDE_PATH - #define JUCE_ZLIB_INCLUDE_PATH -#endif - -/* Config: JUCE_CATCH_UNHANDLED_EXCEPTIONS - If enabled, this will add some exception-catching code to forward unhandled exceptions - to your JUCEApplicationBase::unhandledException() callback. -*/ -#ifndef JUCE_CATCH_UNHANDLED_EXCEPTIONS - //#define JUCE_CATCH_UNHANDLED_EXCEPTIONS 1 -#endif - -#ifndef JUCE_STRING_UTF_TYPE - #define JUCE_STRING_UTF_TYPE 8 -#endif - -//============================================================================= -//============================================================================= -#if JUCE_MSVC - #pragma warning (disable: 4251) // (DLL build warning, must be disabled before pushing the warning state) - #pragma warning (push) - #pragma warning (disable: 4786) // (long class name warning) - #ifdef __INTEL_COMPILER - #pragma warning (disable: 1125) - #endif -#endif - -#include "system/juce_StandardHeader.h" - -namespace juce -{ - -class StringRef; -class MemoryBlock; -class File; -class InputStream; -class OutputStream; -class DynamicObject; -class FileInputStream; -class FileOutputStream; -class XmlElement; -class JSONFormatter; - -extern JUCE_API bool JUCE_CALLTYPE juce_isRunningUnderDebugger(); -extern JUCE_API void JUCE_CALLTYPE logAssertion (const char* file, int line) noexcept; - -#include "memory/juce_Memory.h" -#include "maths/juce_MathsFunctions.h" -#include "memory/juce_ByteOrder.h" -#include "memory/juce_Atomic.h" -#include "text/juce_CharacterFunctions.h" - -#if JUCE_MSVC - #pragma warning (push) - #pragma warning (disable: 4514 4996) -#endif - -#include "text/juce_CharPointer_UTF8.h" -#include "text/juce_CharPointer_UTF16.h" -#include "text/juce_CharPointer_UTF32.h" -#include "text/juce_CharPointer_ASCII.h" - -#if JUCE_MSVC - #pragma warning (pop) -#endif - -#include "text/juce_String.h" -#include "text/juce_StringRef.h" -#include "logging/juce_Logger.h" -#include "memory/juce_LeakedObjectDetector.h" -#include "memory/juce_ContainerDeletePolicy.h" -#include "memory/juce_HeapBlock.h" -#include "memory/juce_MemoryBlock.h" -#include "memory/juce_ReferenceCountedObject.h" -#include "memory/juce_ScopedPointer.h" -#include "memory/juce_OptionalScopedPointer.h" -#include "memory/juce_Singleton.h" -#include "memory/juce_WeakReference.h" -#include "threads/juce_ScopedLock.h" -#include "threads/juce_CriticalSection.h" -#include "maths/juce_Range.h" -#include "maths/juce_NormalisableRange.h" -#include "containers/juce_ElementComparator.h" -#include "containers/juce_ArrayAllocationBase.h" -#include "containers/juce_Array.h" -#include "containers/juce_LinkedListPointer.h" -#include "containers/juce_OwnedArray.h" -#include "containers/juce_ReferenceCountedArray.h" -#include "containers/juce_ScopedValueSetter.h" -#include "containers/juce_SortedSet.h" -#include "containers/juce_SparseSet.h" -#include "containers/juce_AbstractFifo.h" -#include "text/juce_NewLine.h" -#include "text/juce_StringPool.h" -#include "text/juce_Identifier.h" -#include "text/juce_StringArray.h" -#include "text/juce_StringPairArray.h" -#include "text/juce_TextDiff.h" -#include "text/juce_LocalisedStrings.h" -#include "misc/juce_Result.h" -#include "containers/juce_Variant.h" -#include "containers/juce_NamedValueSet.h" -#include "containers/juce_DynamicObject.h" -#include "containers/juce_HashMap.h" -#include "time/juce_RelativeTime.h" -#include "time/juce_Time.h" -#include "streams/juce_InputStream.h" -#include "streams/juce_OutputStream.h" -#include "streams/juce_BufferedInputStream.h" -#include "streams/juce_MemoryInputStream.h" -#include "streams/juce_MemoryOutputStream.h" -#include "streams/juce_SubregionStream.h" -#include "streams/juce_InputSource.h" -#include "files/juce_File.h" -#include "files/juce_DirectoryIterator.h" -#include "files/juce_FileInputStream.h" -#include "files/juce_FileOutputStream.h" -#include "files/juce_FileSearchPath.h" -#include "files/juce_MemoryMappedFile.h" -#include "files/juce_TemporaryFile.h" -#include "files/juce_FileFilter.h" -#include "files/juce_WildcardFileFilter.h" -#include "streams/juce_FileInputSource.h" -#include "logging/juce_FileLogger.h" -#include "javascript/juce_JSON.h" -#include "javascript/juce_Javascript.h" -#include "maths/juce_BigInteger.h" -#include "maths/juce_Expression.h" -#include "maths/juce_Random.h" -#include "misc/juce_Uuid.h" -#include "misc/juce_WindowsRegistry.h" -#include "system/juce_PlatformDefs.h" -#include "system/juce_CompilerSupport.h" -#include "system/juce_SystemStats.h" -#include "threads/juce_ChildProcess.h" -#include "threads/juce_DynamicLibrary.h" -#include "threads/juce_HighResolutionTimer.h" -#include "threads/juce_InterProcessLock.h" -#include "threads/juce_Process.h" -#include "threads/juce_SpinLock.h" -#include "threads/juce_WaitableEvent.h" -#include "threads/juce_Thread.h" -#include "threads/juce_ThreadLocalValue.h" -#include "threads/juce_ThreadPool.h" -#include "threads/juce_TimeSliceThread.h" -#include "threads/juce_ReadWriteLock.h" -#include "threads/juce_ScopedReadLock.h" -#include "threads/juce_ScopedWriteLock.h" -#include "network/juce_IPAddress.h" -#include "network/juce_MACAddress.h" -#include "network/juce_NamedPipe.h" -#include "network/juce_Socket.h" -#include "network/juce_URL.h" -#include "time/juce_PerformanceCounter.h" -#include "unit_tests/juce_UnitTest.h" -#include "xml/juce_XmlDocument.h" -#include "xml/juce_XmlElement.h" -#include "zip/juce_GZIPCompressorOutputStream.h" -#include "zip/juce_GZIPDecompressorInputStream.h" -#include "zip/juce_ZipFile.h" -#include "containers/juce_PropertySet.h" -#include "memory/juce_SharedResourcePointer.h" - -} - -#if JUCE_MSVC - #pragma warning (pop) -#endif - -#endif // JUCE_CORE_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/juce_core.mm b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/juce_core.mm deleted file mode 100644 index 90a2f7cdbc..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/juce_core.mm +++ /dev/null @@ -1,29 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#include "juce_core.cpp" diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/juce_module_info b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/juce_module_info deleted file mode 100644 index 7fb2073385..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/juce_module_info +++ /dev/null @@ -1,38 +0,0 @@ -{ - "id": "juce_core", - "name": "JUCE core classes", - "version": "3.0.8", - "description": "The essential set of basic JUCE classes, as required by all the other JUCE modules. Includes text, container, memory, threading and i/o functionality.", - "website": "http://www.juce.com/juce", - "license": "ISC Permissive", - - "dependencies": [], - - "include": "juce_core.h", - - "compile": [ { "file": "juce_core.cpp", "target": "! xcode" }, - { "file": "juce_core.mm", "target": "xcode" } ], - - "browse": [ "text/*", - "maths/*", - "memory/*", - "containers/*", - "threads/*", - "time/*", - "files/*", - "network/*", - "streams/*", - "logging/*", - "system/*", - "xml/*", - "javascript/*", - "zip/*", - "unit_tests/*", - "misc/*", - "native/*" ], - - "OSXFrameworks": "Cocoa IOKit", - "iOSFrameworks": "Foundation", - "LinuxLibs": "rt dl pthread", - "mingwLibs": "uuid wsock32 wininet version ole32 ws2_32 oleaut32 imm32 comdlg32 shlwapi rpcrt4 winmm" -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/logging/juce_FileLogger.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/logging/juce_FileLogger.cpp deleted file mode 100644 index 8cadfda8b4..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/logging/juce_FileLogger.cpp +++ /dev/null @@ -1,134 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -FileLogger::FileLogger (const File& file, - const String& welcomeMessage, - const int64 maxInitialFileSizeBytes) - : logFile (file) -{ - if (maxInitialFileSizeBytes >= 0) - trimFileSize (maxInitialFileSizeBytes); - - if (! file.exists()) - file.create(); // (to create the parent directories) - - String welcome; - welcome << newLine - << "**********************************************************" << newLine - << welcomeMessage << newLine - << "Log started: " << Time::getCurrentTime().toString (true, true) << newLine; - - FileLogger::logMessage (welcome); -} - -FileLogger::~FileLogger() {} - -//============================================================================== -void FileLogger::logMessage (const String& message) -{ - const ScopedLock sl (logLock); - DBG (message); - FileOutputStream out (logFile, 256); - out << message << newLine; -} - -void FileLogger::trimFileSize (int64 maxFileSizeBytes) const -{ - if (maxFileSizeBytes <= 0) - { - logFile.deleteFile(); - } - else - { - const int64 fileSize = logFile.getSize(); - - if (fileSize > maxFileSizeBytes) - { - TemporaryFile tempFile (logFile); - - { - FileOutputStream out (tempFile.getFile()); - FileInputStream in (logFile); - - if (! (out.openedOk() && in.openedOk())) - return; - - in.setPosition (fileSize - maxFileSizeBytes); - - for (;;) - { - const char c = in.readByte(); - if (c == 0) - return; - - if (c == '\n' || c == '\r') - { - out << c; - break; - } - } - - out.writeFromInputStream (in, -1); - } - - tempFile.overwriteTargetFileWithTemporary(); - } - } -} - -//============================================================================== -File FileLogger::getSystemLogFileFolder() -{ - #if JUCE_MAC - return File ("~/Library/Logs"); - #else - return File::getSpecialLocation (File::userApplicationDataDirectory); - #endif -} - -FileLogger* FileLogger::createDefaultAppLogger (const String& logFileSubDirectoryName, - const String& logFileName, - const String& welcomeMessage, - const int64 maxInitialFileSizeBytes) -{ - return new FileLogger (getSystemLogFileFolder().getChildFile (logFileSubDirectoryName) - .getChildFile (logFileName), - welcomeMessage, maxInitialFileSizeBytes); -} - -FileLogger* FileLogger::createDateStampedLogger (const String& logFileSubDirectoryName, - const String& logFileNameRoot, - const String& logFileNameSuffix, - const String& welcomeMessage) -{ - return new FileLogger (getSystemLogFileFolder().getChildFile (logFileSubDirectoryName) - .getChildFile (logFileNameRoot + Time::getCurrentTime().formatted ("%Y-%m-%d_%H-%M-%S")) - .withFileExtension (logFileNameSuffix) - .getNonexistentSibling(), - welcomeMessage, 0); -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/logging/juce_FileLogger.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/logging/juce_FileLogger.h deleted file mode 100644 index 6be1668cb7..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/logging/juce_FileLogger.h +++ /dev/null @@ -1,135 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_FILELOGGER_H_INCLUDED -#define JUCE_FILELOGGER_H_INCLUDED - - -//============================================================================== -/** - A simple implementation of a Logger that writes to a file. - - @see Logger -*/ -class JUCE_API FileLogger : public Logger -{ -public: - //============================================================================== - /** Creates a FileLogger for a given file. - - @param fileToWriteTo the file that to use - new messages will be appended - to the file. If the file doesn't exist, it will be created, - along with any parent directories that are needed. - @param welcomeMessage when opened, the logger will write a header to the log, along - with the current date and time, and this welcome message - @param maxInitialFileSizeBytes if this is zero or greater, then if the file already exists - but is larger than this number of bytes, then the start of the - file will be truncated to keep the size down. This prevents a log - file getting ridiculously large over time. The file will be truncated - at a new-line boundary. If this value is less than zero, no size limit - will be imposed; if it's zero, the file will always be deleted. Note that - the size is only checked once when this object is created - any logging - that is done later will be appended without any checking - */ - FileLogger (const File& fileToWriteTo, - const String& welcomeMessage, - const int64 maxInitialFileSizeBytes = 128 * 1024); - - /** Destructor. */ - ~FileLogger(); - - //============================================================================== - /** Returns the file that this logger is writing to. */ - const File& getLogFile() const noexcept { return logFile; } - - //============================================================================== - /** Helper function to create a log file in the correct place for this platform. - - The method might return nullptr if the file can't be created for some reason. - - @param logFileSubDirectoryName the name of the subdirectory to create inside the logs folder (as - returned by getSystemLogFileFolder). It's best to use something - like the name of your application here. - @param logFileName the name of the file to create, e.g. "MyAppLog.txt". - @param welcomeMessage a message that will be written to the log when it's opened. - @param maxInitialFileSizeBytes (see the FileLogger constructor for more info on this) - */ - static FileLogger* createDefaultAppLogger (const String& logFileSubDirectoryName, - const String& logFileName, - const String& welcomeMessage, - const int64 maxInitialFileSizeBytes = 128 * 1024); - - /** Helper function to create a log file in the correct place for this platform. - - The filename used is based on the root and suffix strings provided, along with a - time and date string, meaning that a new, empty log file will be always be created - rather than appending to an exising one. - - The method might return nullptr if the file can't be created for some reason. - - @param logFileSubDirectoryName the name of the subdirectory to create inside the logs folder (as - returned by getSystemLogFileFolder). It's best to use something - like the name of your application here. - @param logFileNameRoot the start of the filename to use, e.g. "MyAppLog_". This will have - a timestamp and the logFileNameSuffix appended to it - @param logFileNameSuffix the file suffix to use, e.g. ".txt" - @param welcomeMessage a message that will be written to the log when it's opened. - */ - static FileLogger* createDateStampedLogger (const String& logFileSubDirectoryName, - const String& logFileNameRoot, - const String& logFileNameSuffix, - const String& welcomeMessage); - - //============================================================================== - /** Returns an OS-specific folder where log-files should be stored. - - On Windows this will return a logger with a path such as: - c:\\Documents and Settings\\username\\Application Data\\[logFileSubDirectoryName]\\[logFileName] - - On the Mac it'll create something like: - ~/Library/Logs/[logFileSubDirectoryName]/[logFileName] - - @see createDefaultAppLogger - */ - static File getSystemLogFileFolder(); - - // (implementation of the Logger virtual method) - void logMessage (const String&); - -private: - //============================================================================== - File logFile; - CriticalSection logLock; - - void trimFileSize (int64 maxFileSizeBytes) const; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (FileLogger) -}; - - -#endif // JUCE_FILELOGGER_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/logging/juce_Logger.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/logging/juce_Logger.cpp deleted file mode 100644 index 0b1c8d6beb..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/logging/juce_Logger.cpp +++ /dev/null @@ -1,63 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -Logger::Logger() {} - -Logger::~Logger() -{ - // You're deleting this logger while it's still being used! - // Always call Logger::setCurrentLogger (nullptr) before deleting the active logger. - jassert (currentLogger != this); -} - -Logger* Logger::currentLogger = nullptr; - -void Logger::setCurrentLogger (Logger* const newLogger) noexcept { currentLogger = newLogger; } -Logger* Logger::getCurrentLogger() noexcept { return currentLogger; } - -void Logger::writeToLog (const String& message) -{ - if (currentLogger != nullptr) - currentLogger->logMessage (message); - else - outputDebugString (message); -} - -#if JUCE_LOG_ASSERTIONS || JUCE_DEBUG -void JUCE_API JUCE_CALLTYPE logAssertion (const char* const filename, const int lineNum) noexcept -{ - String m ("JUCE Assertion failure in "); - m << File::createFileWithoutCheckingPath (filename).getFileName() << ':' << lineNum; - - #if JUCE_LOG_ASSERTIONS - Logger::writeToLog (m); - #else - DBG (m); - #endif -} -#endif diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/logging/juce_Logger.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/logging/juce_Logger.h deleted file mode 100644 index d0d3af57ff..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/logging/juce_Logger.h +++ /dev/null @@ -1,97 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_LOGGER_H_INCLUDED -#define JUCE_LOGGER_H_INCLUDED - - -//============================================================================== -/** - Acts as an application-wide logging class. - - A subclass of Logger can be created and passed into the Logger::setCurrentLogger - method and this will then be used by all calls to writeToLog. - - The logger class also contains methods for writing messages to the debugger's - output stream. - - @see FileLogger -*/ -class JUCE_API Logger -{ -public: - //============================================================================== - /** Destructor. */ - virtual ~Logger(); - - //============================================================================== - /** Sets the current logging class to use. - - Note that the object passed in will not be owned or deleted by the logger, so - the caller must make sure that it is not deleted while still being used. - A null pointer can be passed-in to disable any logging. - */ - static void JUCE_CALLTYPE setCurrentLogger (Logger* newLogger) noexcept; - - /** Returns the current logger, or nullptr if none has been set. */ - static Logger* getCurrentLogger() noexcept; - - /** Writes a string to the current logger. - - This will pass the string to the logger's logMessage() method if a logger - has been set. - - @see logMessage - */ - static void JUCE_CALLTYPE writeToLog (const String& message); - - - //============================================================================== - /** Writes a message to the standard error stream. - - This can be called directly, or by using the DBG() macro in - juce_PlatformDefs.h (which will avoid calling the method in non-debug builds). - */ - static void JUCE_CALLTYPE outputDebugString (const String& text); - - -protected: - //============================================================================== - Logger(); - - /** This is overloaded by subclasses to implement custom logging behaviour. - @see setCurrentLogger - */ - virtual void logMessage (const String& message) = 0; - -private: - static Logger* currentLogger; -}; - - -#endif // JUCE_LOGGER_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/maths/juce_BigInteger.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/maths/juce_BigInteger.cpp deleted file mode 100644 index dd09616353..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/maths/juce_BigInteger.cpp +++ /dev/null @@ -1,1014 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -namespace -{ - inline size_t bitToIndex (const int bit) noexcept { return (size_t) (bit >> 5); } - inline uint32 bitToMask (const int bit) noexcept { return (uint32) 1 << (bit & 31); } -} - -//============================================================================== -BigInteger::BigInteger() - : numValues (4), - highestBit (-1), - negative (false) -{ - values.calloc (numValues + 1); -} - -BigInteger::BigInteger (const int32 value) - : numValues (4), - highestBit (31), - negative (value < 0) -{ - values.calloc (numValues + 1); - values[0] = (uint32) abs (value); - highestBit = getHighestBit(); -} - -BigInteger::BigInteger (const uint32 value) - : numValues (4), - highestBit (31), - negative (false) -{ - values.calloc (numValues + 1); - values[0] = value; - highestBit = getHighestBit(); -} - -BigInteger::BigInteger (int64 value) - : numValues (4), - highestBit (63), - negative (value < 0) -{ - values.calloc (numValues + 1); - - if (value < 0) - value = -value; - - values[0] = (uint32) value; - values[1] = (uint32) (value >> 32); - highestBit = getHighestBit(); -} - -BigInteger::BigInteger (const BigInteger& other) - : numValues ((size_t) jmax ((size_t) 4, bitToIndex (other.highestBit) + 1)), - highestBit (other.getHighestBit()), - negative (other.negative) -{ - values.malloc (numValues + 1); - memcpy (values, other.values, sizeof (uint32) * (numValues + 1)); -} - -#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS -BigInteger::BigInteger (BigInteger&& other) noexcept - : values (static_cast &&> (other.values)), - numValues (other.numValues), - highestBit (other.highestBit), - negative (other.negative) -{ -} - -BigInteger& BigInteger::operator= (BigInteger&& other) noexcept -{ - values = static_cast &&> (other.values); - numValues = other.numValues; - highestBit = other.highestBit; - negative = other.negative; - return *this; -} -#endif - -BigInteger::~BigInteger() -{ -} - -void BigInteger::swapWith (BigInteger& other) noexcept -{ - values.swapWith (other.values); - std::swap (numValues, other.numValues); - std::swap (highestBit, other.highestBit); - std::swap (negative, other.negative); -} - -BigInteger& BigInteger::operator= (const BigInteger& other) -{ - if (this != &other) - { - highestBit = other.getHighestBit(); - jassert (other.numValues >= 4); - numValues = (size_t) jmax ((size_t) 4, bitToIndex (highestBit) + 1); - negative = other.negative; - values.malloc (numValues + 1); - memcpy (values, other.values, sizeof (uint32) * (numValues + 1)); - } - - return *this; -} - -void BigInteger::ensureSize (const size_t numVals) -{ - if (numVals + 2 >= numValues) - { - size_t oldSize = numValues; - numValues = ((numVals + 2) * 3) / 2; - values.realloc (numValues + 1); - - while (oldSize < numValues) - values [oldSize++] = 0; - } -} - -//============================================================================== -bool BigInteger::operator[] (const int bit) const noexcept -{ - return bit <= highestBit && bit >= 0 - && ((values [bitToIndex (bit)] & bitToMask (bit)) != 0); -} - -int BigInteger::toInteger() const noexcept -{ - const int n = (int) (values[0] & 0x7fffffff); - return negative ? -n : n; -} - -int64 BigInteger::toInt64() const noexcept -{ - const int64 n = (((int64) (values[1] & 0x7fffffff)) << 32) | values[0]; - return negative ? -n : n; -} - -BigInteger BigInteger::getBitRange (int startBit, int numBits) const -{ - BigInteger r; - numBits = jmin (numBits, getHighestBit() + 1 - startBit); - r.ensureSize ((size_t) bitToIndex (numBits)); - r.highestBit = numBits; - - int i = 0; - while (numBits > 0) - { - r.values[i++] = getBitRangeAsInt (startBit, (int) jmin (32, numBits)); - numBits -= 32; - startBit += 32; - } - - r.highestBit = r.getHighestBit(); - return r; -} - -uint32 BigInteger::getBitRangeAsInt (const int startBit, int numBits) const noexcept -{ - if (numBits > 32) - { - jassertfalse; // use getBitRange() if you need more than 32 bits.. - numBits = 32; - } - - numBits = jmin (numBits, highestBit + 1 - startBit); - - if (numBits <= 0) - return 0; - - const size_t pos = bitToIndex (startBit); - const int offset = startBit & 31; - const int endSpace = 32 - numBits; - - uint32 n = ((uint32) values [pos]) >> offset; - - if (offset > endSpace) - n |= ((uint32) values [pos + 1]) << (32 - offset); - - return n & (((uint32) 0xffffffff) >> endSpace); -} - -void BigInteger::setBitRangeAsInt (const int startBit, int numBits, uint32 valueToSet) -{ - if (numBits > 32) - { - jassertfalse; - numBits = 32; - } - - for (int i = 0; i < numBits; ++i) - { - setBit (startBit + i, (valueToSet & 1) != 0); - valueToSet >>= 1; - } -} - -//============================================================================== -void BigInteger::clear() -{ - if (numValues > 16) - { - numValues = 4; - values.calloc (numValues + 1); - } - else - { - values.clear (numValues + 1); - } - - highestBit = -1; - negative = false; -} - -void BigInteger::setBit (const int bit) -{ - if (bit >= 0) - { - if (bit > highestBit) - { - ensureSize (bitToIndex (bit)); - highestBit = bit; - } - - values [bitToIndex (bit)] |= bitToMask (bit); - } -} - -void BigInteger::setBit (const int bit, const bool shouldBeSet) -{ - if (shouldBeSet) - setBit (bit); - else - clearBit (bit); -} - -void BigInteger::clearBit (const int bit) noexcept -{ - if (bit >= 0 && bit <= highestBit) - values [bitToIndex (bit)] &= ~bitToMask (bit); -} - -void BigInteger::setRange (int startBit, int numBits, const bool shouldBeSet) -{ - while (--numBits >= 0) - setBit (startBit++, shouldBeSet); -} - -void BigInteger::insertBit (const int bit, const bool shouldBeSet) -{ - if (bit >= 0) - shiftBits (1, bit); - - setBit (bit, shouldBeSet); -} - -//============================================================================== -bool BigInteger::isZero() const noexcept -{ - return getHighestBit() < 0; -} - -bool BigInteger::isOne() const noexcept -{ - return getHighestBit() == 0 && ! negative; -} - -bool BigInteger::isNegative() const noexcept -{ - return negative && ! isZero(); -} - -void BigInteger::setNegative (const bool neg) noexcept -{ - negative = neg; -} - -void BigInteger::negate() noexcept -{ - negative = (! negative) && ! isZero(); -} - -#if JUCE_USE_MSVC_INTRINSICS && ! defined (__INTEL_COMPILER) - #pragma intrinsic (_BitScanReverse) -#endif - -inline static int highestBitInInt (uint32 n) noexcept -{ - jassert (n != 0); // (the built-in functions may not work for n = 0) - - #if JUCE_GCC - return 31 - __builtin_clz (n); - #elif JUCE_USE_MSVC_INTRINSICS - unsigned long highest; - _BitScanReverse (&highest, n); - return (int) highest; - #else - n |= (n >> 1); - n |= (n >> 2); - n |= (n >> 4); - n |= (n >> 8); - n |= (n >> 16); - return countBitsInInt32 (n >> 1); - #endif -} - -int BigInteger::countNumberOfSetBits() const noexcept -{ - int total = 0; - - for (int i = (int) bitToIndex (highestBit) + 1; --i >= 0;) - total += countNumberOfBits (values[i]); - - return total; -} - -int BigInteger::getHighestBit() const noexcept -{ - for (int i = (int) bitToIndex (highestBit + 1); i >= 0; --i) - { - const uint32 n = values[i]; - - if (n != 0) - return highestBitInInt (n) + (i << 5); - } - - return -1; -} - -int BigInteger::findNextSetBit (int i) const noexcept -{ - for (; i <= highestBit; ++i) - if ((values [bitToIndex (i)] & bitToMask (i)) != 0) - return i; - - return -1; -} - -int BigInteger::findNextClearBit (int i) const noexcept -{ - for (; i <= highestBit; ++i) - if ((values [bitToIndex (i)] & bitToMask (i)) == 0) - break; - - return i; -} - -//============================================================================== -BigInteger& BigInteger::operator+= (const BigInteger& other) -{ - if (other.isNegative()) - return operator-= (-other); - - if (isNegative()) - { - if (compareAbsolute (other) < 0) - { - BigInteger temp (*this); - temp.negate(); - *this = other; - operator-= (temp); - } - else - { - negate(); - operator-= (other); - negate(); - } - } - else - { - if (other.highestBit > highestBit) - highestBit = other.highestBit; - - ++highestBit; - - const size_t numInts = bitToIndex (highestBit) + 1; - ensureSize (numInts); - - int64 remainder = 0; - - for (size_t i = 0; i <= numInts; ++i) - { - if (i < numValues) - remainder += values[i]; - - if (i < other.numValues) - remainder += other.values[i]; - - values[i] = (uint32) remainder; - remainder >>= 32; - } - - jassert (remainder == 0); - highestBit = getHighestBit(); - } - - return *this; -} - -BigInteger& BigInteger::operator-= (const BigInteger& other) -{ - if (other.isNegative()) - return operator+= (-other); - - if (! isNegative()) - { - if (compareAbsolute (other) < 0) - { - BigInteger temp (other); - swapWith (temp); - operator-= (temp); - negate(); - return *this; - } - } - else - { - negate(); - operator+= (other); - negate(); - return *this; - } - - const size_t numInts = bitToIndex (highestBit) + 1; - const size_t maxOtherInts = bitToIndex (other.highestBit) + 1; - int64 amountToSubtract = 0; - - for (size_t i = 0; i <= numInts; ++i) - { - if (i <= maxOtherInts) - amountToSubtract += (int64) other.values[i]; - - if (values[i] >= amountToSubtract) - { - values[i] = (uint32) (values[i] - amountToSubtract); - amountToSubtract = 0; - } - else - { - const int64 n = ((int64) values[i] + (((int64) 1) << 32)) - amountToSubtract; - values[i] = (uint32) n; - amountToSubtract = 1; - } - } - - return *this; -} - -BigInteger& BigInteger::operator*= (const BigInteger& other) -{ - BigInteger total; - highestBit = getHighestBit(); - const bool wasNegative = isNegative(); - setNegative (false); - - for (int i = 0; i <= highestBit; ++i) - { - if (operator[](i)) - { - BigInteger n (other); - n.setNegative (false); - n <<= i; - total += n; - } - } - - total.setNegative (wasNegative ^ other.isNegative()); - swapWith (total); - return *this; -} - -void BigInteger::divideBy (const BigInteger& divisor, BigInteger& remainder) -{ - jassert (this != &remainder); // (can't handle passing itself in to get the remainder) - - const int divHB = divisor.getHighestBit(); - const int ourHB = getHighestBit(); - - if (divHB < 0 || ourHB < 0) - { - // division by zero - remainder.clear(); - clear(); - } - else - { - const bool wasNegative = isNegative(); - - swapWith (remainder); - remainder.setNegative (false); - clear(); - - BigInteger temp (divisor); - temp.setNegative (false); - - int leftShift = ourHB - divHB; - temp <<= leftShift; - - while (leftShift >= 0) - { - if (remainder.compareAbsolute (temp) >= 0) - { - remainder -= temp; - setBit (leftShift); - } - - if (--leftShift >= 0) - temp >>= 1; - } - - negative = wasNegative ^ divisor.isNegative(); - remainder.setNegative (wasNegative); - } -} - -BigInteger& BigInteger::operator/= (const BigInteger& other) -{ - BigInteger remainder; - divideBy (other, remainder); - return *this; -} - -BigInteger& BigInteger::operator|= (const BigInteger& other) -{ - // this operation doesn't take into account negative values.. - jassert (isNegative() == other.isNegative()); - - if (other.highestBit >= 0) - { - ensureSize (bitToIndex (other.highestBit)); - - int n = (int) bitToIndex (other.highestBit) + 1; - - while (--n >= 0) - values[n] |= other.values[n]; - - if (other.highestBit > highestBit) - highestBit = other.highestBit; - - highestBit = getHighestBit(); - } - - return *this; -} - -BigInteger& BigInteger::operator&= (const BigInteger& other) -{ - // this operation doesn't take into account negative values.. - jassert (isNegative() == other.isNegative()); - - int n = (int) numValues; - - while (n > (int) other.numValues) - values[--n] = 0; - - while (--n >= 0) - values[n] &= other.values[n]; - - if (other.highestBit < highestBit) - highestBit = other.highestBit; - - highestBit = getHighestBit(); - return *this; -} - -BigInteger& BigInteger::operator^= (const BigInteger& other) -{ - // this operation will only work with the absolute values - jassert (isNegative() == other.isNegative()); - - if (other.highestBit >= 0) - { - ensureSize (bitToIndex (other.highestBit)); - - int n = (int) bitToIndex (other.highestBit) + 1; - - while (--n >= 0) - values[n] ^= other.values[n]; - - if (other.highestBit > highestBit) - highestBit = other.highestBit; - - highestBit = getHighestBit(); - } - - return *this; -} - -BigInteger& BigInteger::operator%= (const BigInteger& divisor) -{ - BigInteger remainder; - divideBy (divisor, remainder); - swapWith (remainder); - return *this; -} - -BigInteger& BigInteger::operator++() { return operator+= (1); } -BigInteger& BigInteger::operator--() { return operator-= (1); } -BigInteger BigInteger::operator++ (int) { const BigInteger old (*this); operator+= (1); return old; } -BigInteger BigInteger::operator-- (int) { const BigInteger old (*this); operator-= (1); return old; } - -BigInteger BigInteger::operator-() const { BigInteger b (*this); b.negate(); return b; } -BigInteger BigInteger::operator+ (const BigInteger& other) const { BigInteger b (*this); return b += other; } -BigInteger BigInteger::operator- (const BigInteger& other) const { BigInteger b (*this); return b -= other; } -BigInteger BigInteger::operator* (const BigInteger& other) const { BigInteger b (*this); return b *= other; } -BigInteger BigInteger::operator/ (const BigInteger& other) const { BigInteger b (*this); return b /= other; } -BigInteger BigInteger::operator| (const BigInteger& other) const { BigInteger b (*this); return b |= other; } -BigInteger BigInteger::operator& (const BigInteger& other) const { BigInteger b (*this); return b &= other; } -BigInteger BigInteger::operator^ (const BigInteger& other) const { BigInteger b (*this); return b ^= other; } -BigInteger BigInteger::operator% (const BigInteger& other) const { BigInteger b (*this); return b %= other; } -BigInteger BigInteger::operator<< (const int numBits) const { BigInteger b (*this); return b <<= numBits; } -BigInteger BigInteger::operator>> (const int numBits) const { BigInteger b (*this); return b >>= numBits; } -BigInteger& BigInteger::operator<<= (const int numBits) { shiftBits (numBits, 0); return *this; } -BigInteger& BigInteger::operator>>= (const int numBits) { shiftBits (-numBits, 0); return *this; } - -//============================================================================== -int BigInteger::compare (const BigInteger& other) const noexcept -{ - if (isNegative() == other.isNegative()) - { - const int absComp = compareAbsolute (other); - return isNegative() ? -absComp : absComp; - } - else - { - return isNegative() ? -1 : 1; - } -} - -int BigInteger::compareAbsolute (const BigInteger& other) const noexcept -{ - const int h1 = getHighestBit(); - const int h2 = other.getHighestBit(); - - if (h1 > h2) - return 1; - else if (h1 < h2) - return -1; - - for (int i = (int) bitToIndex (h1) + 1; --i >= 0;) - if (values[i] != other.values[i]) - return (values[i] > other.values[i]) ? 1 : -1; - - return 0; -} - -bool BigInteger::operator== (const BigInteger& other) const noexcept { return compare (other) == 0; } -bool BigInteger::operator!= (const BigInteger& other) const noexcept { return compare (other) != 0; } -bool BigInteger::operator< (const BigInteger& other) const noexcept { return compare (other) < 0; } -bool BigInteger::operator<= (const BigInteger& other) const noexcept { return compare (other) <= 0; } -bool BigInteger::operator> (const BigInteger& other) const noexcept { return compare (other) > 0; } -bool BigInteger::operator>= (const BigInteger& other) const noexcept { return compare (other) >= 0; } - -//============================================================================== -void BigInteger::shiftLeft (int bits, const int startBit) -{ - if (startBit > 0) - { - for (int i = highestBit + 1; --i >= startBit;) - setBit (i + bits, operator[] (i)); - - while (--bits >= 0) - clearBit (bits + startBit); - } - else - { - ensureSize (bitToIndex (highestBit + bits) + 1); - - const size_t wordsToMove = bitToIndex (bits); - size_t top = 1 + bitToIndex (highestBit); - highestBit += bits; - - if (wordsToMove > 0) - { - for (int i = (int) top; --i >= 0;) - values [(size_t) i + wordsToMove] = values [i]; - - for (size_t j = 0; j < wordsToMove; ++j) - values [j] = 0; - - bits &= 31; - } - - if (bits != 0) - { - const int invBits = 32 - bits; - - for (size_t i = top + 1 + wordsToMove; --i > wordsToMove;) - values[i] = (values[i] << bits) | (values [i - 1] >> invBits); - - values [wordsToMove] = values [wordsToMove] << bits; - } - - highestBit = getHighestBit(); - } -} - -void BigInteger::shiftRight (int bits, const int startBit) -{ - if (startBit > 0) - { - for (int i = startBit; i <= highestBit; ++i) - setBit (i, operator[] (i + bits)); - - highestBit = getHighestBit(); - } - else - { - if (bits > highestBit) - { - clear(); - } - else - { - const size_t wordsToMove = bitToIndex (bits); - size_t top = 1 + bitToIndex (highestBit) - wordsToMove; - highestBit -= bits; - - if (wordsToMove > 0) - { - size_t i; - for (i = 0; i < top; ++i) - values [i] = values [i + wordsToMove]; - - for (i = 0; i < wordsToMove; ++i) - values [top + i] = 0; - - bits &= 31; - } - - if (bits != 0) - { - const int invBits = 32 - bits; - - --top; - for (size_t i = 0; i < top; ++i) - values[i] = (values[i] >> bits) | (values [i + 1] << invBits); - - values[top] = (values[top] >> bits); - } - - highestBit = getHighestBit(); - } - } -} - -void BigInteger::shiftBits (int bits, const int startBit) -{ - if (highestBit >= 0) - { - if (bits < 0) - shiftRight (-bits, startBit); - else if (bits > 0) - shiftLeft (bits, startBit); - } -} - -//============================================================================== -static BigInteger simpleGCD (BigInteger* m, BigInteger* n) -{ - while (! m->isZero()) - { - if (n->compareAbsolute (*m) > 0) - std::swap (m, n); - - *m -= *n; - } - - return *n; -} - -BigInteger BigInteger::findGreatestCommonDivisor (BigInteger n) const -{ - BigInteger m (*this); - - while (! n.isZero()) - { - if (abs (m.getHighestBit() - n.getHighestBit()) <= 16) - return simpleGCD (&m, &n); - - BigInteger temp2; - m.divideBy (n, temp2); - - m.swapWith (n); - n.swapWith (temp2); - } - - return m; -} - -void BigInteger::exponentModulo (const BigInteger& exponent, const BigInteger& modulus) -{ - BigInteger exp (exponent); - exp %= modulus; - - BigInteger value (1); - swapWith (value); - value %= modulus; - - while (! exp.isZero()) - { - if (exp [0]) - { - operator*= (value); - operator%= (modulus); - } - - value *= value; - value %= modulus; - exp >>= 1; - } -} - -void BigInteger::inverseModulo (const BigInteger& modulus) -{ - if (modulus.isOne() || modulus.isNegative()) - { - clear(); - return; - } - - if (isNegative() || compareAbsolute (modulus) >= 0) - operator%= (modulus); - - if (isOne()) - return; - - if (! (*this)[0]) - { - // not invertible - clear(); - return; - } - - BigInteger a1 (modulus); - BigInteger a2 (*this); - BigInteger b1 (modulus); - BigInteger b2 (1); - - while (! a2.isOne()) - { - BigInteger temp1, multiplier (a1); - multiplier.divideBy (a2, temp1); - - temp1 = a2; - temp1 *= multiplier; - BigInteger temp2 (a1); - temp2 -= temp1; - a1 = a2; - a2 = temp2; - - temp1 = b2; - temp1 *= multiplier; - temp2 = b1; - temp2 -= temp1; - b1 = b2; - b2 = temp2; - } - - while (b2.isNegative()) - b2 += modulus; - - b2 %= modulus; - swapWith (b2); -} - -//============================================================================== -OutputStream& JUCE_CALLTYPE operator<< (OutputStream& stream, const BigInteger& value) -{ - return stream << value.toString (10); -} - -String BigInteger::toString (const int base, const int minimumNumCharacters) const -{ - String s; - BigInteger v (*this); - - if (base == 2 || base == 8 || base == 16) - { - const int bits = (base == 2) ? 1 : (base == 8 ? 3 : 4); - static const char hexDigits[] = "0123456789abcdef"; - - for (;;) - { - const uint32 remainder = v.getBitRangeAsInt (0, bits); - - v >>= bits; - - if (remainder == 0 && v.isZero()) - break; - - s = String::charToString ((juce_wchar) (uint8) hexDigits [remainder]) + s; - } - } - else if (base == 10) - { - const BigInteger ten (10); - BigInteger remainder; - - for (;;) - { - v.divideBy (ten, remainder); - - if (remainder.isZero() && v.isZero()) - break; - - s = String (remainder.getBitRangeAsInt (0, 8)) + s; - } - } - else - { - jassertfalse; // can't do the specified base! - return String(); - } - - s = s.paddedLeft ('0', minimumNumCharacters); - - return isNegative() ? "-" + s : s; -} - -void BigInteger::parseString (StringRef text, const int base) -{ - clear(); - String::CharPointerType t (text.text.findEndOfWhitespace()); - - setNegative (*t == (juce_wchar) '-'); - - if (base == 2 || base == 8 || base == 16) - { - const int bits = (base == 2) ? 1 : (base == 8 ? 3 : 4); - - for (;;) - { - const juce_wchar c = t.getAndAdvance(); - const int digit = CharacterFunctions::getHexDigitValue (c); - - if (((uint32) digit) < (uint32) base) - { - operator<<= (bits); - operator+= (digit); - } - else if (c == 0) - { - break; - } - } - } - else if (base == 10) - { - const BigInteger ten ((uint32) 10); - - for (;;) - { - const juce_wchar c = t.getAndAdvance(); - - if (c >= '0' && c <= '9') - { - operator*= (ten); - operator+= ((int) (c - '0')); - } - else if (c == 0) - { - break; - } - } - } -} - -MemoryBlock BigInteger::toMemoryBlock() const -{ - const int numBytes = (getHighestBit() + 8) >> 3; - MemoryBlock mb ((size_t) numBytes); - - for (int i = 0; i < numBytes; ++i) - mb[i] = (char) getBitRangeAsInt (i << 3, 8); - - return mb; -} - -void BigInteger::loadFromMemoryBlock (const MemoryBlock& data) -{ - clear(); - - for (int i = (int) data.getSize(); --i >= 0;) - this->setBitRangeAsInt (i << 3, 8, (uint32) data [i]); -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/maths/juce_BigInteger.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/maths/juce_BigInteger.h deleted file mode 100644 index 4c6c25c565..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/maths/juce_BigInteger.h +++ /dev/null @@ -1,334 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_BIGINTEGER_H_INCLUDED -#define JUCE_BIGINTEGER_H_INCLUDED - - -//============================================================================== -/** - An arbitrarily large integer class. - - A BigInteger can be used in a similar way to a normal integer, but has no size - limit (except for memory and performance constraints). - - Negative values are possible, but the value isn't stored as 2s-complement, so - be careful if you use negative values and look at the values of individual bits. -*/ -class JUCE_API BigInteger -{ -public: - //============================================================================== - /** Creates an empty BigInteger */ - BigInteger(); - - /** Creates a BigInteger containing an integer value in its low bits. - The low 32 bits of the number are initialised with this value. - */ - BigInteger (uint32 value); - - /** Creates a BigInteger containing an integer value in its low bits. - The low 32 bits of the number are initialised with the absolute value - passed in, and its sign is set to reflect the sign of the number. - */ - BigInteger (int32 value); - - /** Creates a BigInteger containing an integer value in its low bits. - The low 64 bits of the number are initialised with the absolute value - passed in, and its sign is set to reflect the sign of the number. - */ - BigInteger (int64 value); - - /** Creates a copy of another BigInteger. */ - BigInteger (const BigInteger&); - - #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS - BigInteger (BigInteger&&) noexcept; - BigInteger& operator= (BigInteger&&) noexcept; - #endif - - /** Destructor. */ - ~BigInteger(); - - //============================================================================== - /** Copies another BigInteger onto this one. */ - BigInteger& operator= (const BigInteger&); - - /** Swaps the internal contents of this with another object. */ - void swapWith (BigInteger&) noexcept; - - //============================================================================== - /** Returns the value of a specified bit in the number. - If the index is out-of-range, the result will be false. - */ - bool operator[] (int bit) const noexcept; - - /** Returns true if no bits are set. */ - bool isZero() const noexcept; - - /** Returns true if the value is 1. */ - bool isOne() const noexcept; - - /** Attempts to get the lowest 32 bits of the value as an integer. - If the value is bigger than the integer limits, this will return only the lower bits. - */ - int toInteger() const noexcept; - - /** Attempts to get the lowest 64 bits of the value as an integer. - If the value is bigger than the integer limits, this will return only the lower bits. - */ - int64 toInt64() const noexcept; - - //============================================================================== - /** Resets the value to 0. */ - void clear(); - - /** Clears a particular bit in the number. */ - void clearBit (int bitNumber) noexcept; - - /** Sets a specified bit to 1. */ - void setBit (int bitNumber); - - /** Sets or clears a specified bit. */ - void setBit (int bitNumber, bool shouldBeSet); - - /** Sets a range of bits to be either on or off. - - @param startBit the first bit to change - @param numBits the number of bits to change - @param shouldBeSet whether to turn these bits on or off - */ - void setRange (int startBit, int numBits, bool shouldBeSet); - - /** Inserts a bit an a given position, shifting up any bits above it. */ - void insertBit (int bitNumber, bool shouldBeSet); - - /** Returns a range of bits as a new BigInteger. - - e.g. getBitRangeAsInt (0, 64) would return the lowest 64 bits. - @see getBitRangeAsInt - */ - BigInteger getBitRange (int startBit, int numBits) const; - - /** Returns a range of bits as an integer value. - - e.g. getBitRangeAsInt (0, 32) would return the lowest 32 bits. - - Asking for more than 32 bits isn't allowed (obviously) - for that, use - getBitRange(). - */ - uint32 getBitRangeAsInt (int startBit, int numBits) const noexcept; - - /** Sets a range of bits to an integer value. - - Copies the given integer onto a range of bits, starting at startBit, - and using up to numBits of the available bits. - */ - void setBitRangeAsInt (int startBit, int numBits, uint32 valueToSet); - - /** Shifts a section of bits left or right. - - @param howManyBitsLeft how far to move the bits (+ve numbers shift it left, -ve numbers shift it right). - @param startBit the first bit to affect - if this is > 0, only bits above that index will be affected. - */ - void shiftBits (int howManyBitsLeft, int startBit); - - /** Returns the total number of set bits in the value. */ - int countNumberOfSetBits() const noexcept; - - /** Looks for the index of the next set bit after a given starting point. - - This searches from startIndex (inclusive) upwards for the first set bit, - and returns its index. If no set bits are found, it returns -1. - */ - int findNextSetBit (int startIndex) const noexcept; - - /** Looks for the index of the next clear bit after a given starting point. - - This searches from startIndex (inclusive) upwards for the first clear bit, - and returns its index. - */ - int findNextClearBit (int startIndex) const noexcept; - - /** Returns the index of the highest set bit in the number. - If the value is zero, this will return -1. - */ - int getHighestBit() const noexcept; - - //============================================================================== - // All the standard arithmetic ops... - - BigInteger& operator+= (const BigInteger&); - BigInteger& operator-= (const BigInteger&); - BigInteger& operator*= (const BigInteger&); - BigInteger& operator/= (const BigInteger&); - BigInteger& operator|= (const BigInteger&); - BigInteger& operator&= (const BigInteger&); - BigInteger& operator^= (const BigInteger&); - BigInteger& operator%= (const BigInteger&); - BigInteger& operator<<= (int numBitsToShift); - BigInteger& operator>>= (int numBitsToShift); - BigInteger& operator++(); - BigInteger& operator--(); - BigInteger operator++ (int); - BigInteger operator-- (int); - - BigInteger operator-() const; - BigInteger operator+ (const BigInteger&) const; - BigInteger operator- (const BigInteger&) const; - BigInteger operator* (const BigInteger&) const; - BigInteger operator/ (const BigInteger&) const; - BigInteger operator| (const BigInteger&) const; - BigInteger operator& (const BigInteger&) const; - BigInteger operator^ (const BigInteger&) const; - BigInteger operator% (const BigInteger&) const; - BigInteger operator<< (int numBitsToShift) const; - BigInteger operator>> (int numBitsToShift) const; - - bool operator== (const BigInteger&) const noexcept; - bool operator!= (const BigInteger&) const noexcept; - bool operator< (const BigInteger&) const noexcept; - bool operator<= (const BigInteger&) const noexcept; - bool operator> (const BigInteger&) const noexcept; - bool operator>= (const BigInteger&) const noexcept; - - //============================================================================== - /** Does a signed comparison of two BigIntegers. - - Return values are: - - 0 if the numbers are the same - - < 0 if this number is smaller than the other - - > 0 if this number is bigger than the other - */ - int compare (const BigInteger& other) const noexcept; - - /** Compares the magnitudes of two BigIntegers, ignoring their signs. - - Return values are: - - 0 if the numbers are the same - - < 0 if this number is smaller than the other - - > 0 if this number is bigger than the other - */ - int compareAbsolute (const BigInteger& other) const noexcept; - - /** Divides this value by another one and returns the remainder. - - This number is divided by other, leaving the quotient in this number, - with the remainder being copied to the other BigInteger passed in. - */ - void divideBy (const BigInteger& divisor, BigInteger& remainder); - - /** Returns the largest value that will divide both this value and the one passed-in. */ - BigInteger findGreatestCommonDivisor (BigInteger other) const; - - /** Performs a combined exponent and modulo operation. - This BigInteger's value becomes (this ^ exponent) % modulus. - */ - void exponentModulo (const BigInteger& exponent, const BigInteger& modulus); - - /** Performs an inverse modulo on the value. - i.e. the result is (this ^ -1) mod (modulus). - */ - void inverseModulo (const BigInteger& modulus); - - //============================================================================== - /** Returns true if the value is less than zero. - @see setNegative, negate - */ - bool isNegative() const noexcept; - - /** Changes the sign of the number to be positive or negative. - @see isNegative, negate - */ - void setNegative (bool shouldBeNegative) noexcept; - - /** Inverts the sign of the number. - @see isNegative, setNegative - */ - void negate() noexcept; - - //============================================================================== - /** Converts the number to a string. - - Specify a base such as 2 (binary), 8 (octal), 10 (decimal), 16 (hex). - If minimumNumCharacters is greater than 0, the returned string will be - padded with leading zeros to reach at least that length. - */ - String toString (int base, int minimumNumCharacters = 1) const; - - /** Reads the numeric value from a string. - - Specify a base such as 2 (binary), 8 (octal), 10 (decimal), 16 (hex). - Any invalid characters will be ignored. - */ - void parseString (StringRef text, int base); - - //============================================================================== - /** Turns the number into a block of binary data. - - The data is arranged as little-endian, so the first byte of data is the low 8 bits - of the number, and so on. - - @see loadFromMemoryBlock - */ - MemoryBlock toMemoryBlock() const; - - /** Converts a block of raw data into a number. - - The data is arranged as little-endian, so the first byte of data is the low 8 bits - of the number, and so on. - - @see toMemoryBlock - */ - void loadFromMemoryBlock (const MemoryBlock& data); - -private: - //============================================================================== - HeapBlock values; - size_t numValues; - int highestBit; - bool negative; - - void ensureSize (size_t); - void shiftLeft (int bits, int startBit); - void shiftRight (int bits, int startBit); - - JUCE_LEAK_DETECTOR (BigInteger) -}; - -/** Writes a BigInteger to an OutputStream as a UTF8 decimal string. */ -OutputStream& JUCE_CALLTYPE operator<< (OutputStream& stream, const BigInteger& value); - -//============================================================================== -#ifndef DOXYGEN - // For backwards compatibility, BitArray is defined as an alias for BigInteger. - typedef BigInteger BitArray; -#endif - - -#endif // JUCE_BIGINTEGER_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/maths/juce_Expression.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/maths/juce_Expression.cpp deleted file mode 100644 index a18effa041..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/maths/juce_Expression.cpp +++ /dev/null @@ -1,1183 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -class Expression::Term : public SingleThreadedReferenceCountedObject -{ -public: - Term() {} - virtual ~Term() {} - - virtual Type getType() const noexcept = 0; - virtual Term* clone() const = 0; - virtual ReferenceCountedObjectPtr resolve (const Scope&, int recursionDepth) = 0; - virtual String toString() const = 0; - virtual double toDouble() const { return 0; } - virtual int getInputIndexFor (const Term*) const { return -1; } - virtual int getOperatorPrecedence() const { return 0; } - virtual int getNumInputs() const { return 0; } - virtual Term* getInput (int) const { return nullptr; } - virtual ReferenceCountedObjectPtr negated(); - - virtual ReferenceCountedObjectPtr createTermToEvaluateInput (const Scope&, const Term* /*inputTerm*/, - double /*overallTarget*/, Term* /*topLevelTerm*/) const - { - jassertfalse; - return ReferenceCountedObjectPtr(); - } - - virtual String getName() const - { - jassertfalse; // You shouldn't call this for an expression that's not actually a function! - return String(); - } - - virtual void renameSymbol (const Symbol& oldSymbol, const String& newName, const Scope& scope, int recursionDepth) - { - for (int i = getNumInputs(); --i >= 0;) - getInput (i)->renameSymbol (oldSymbol, newName, scope, recursionDepth); - } - - class SymbolVisitor - { - public: - virtual ~SymbolVisitor() {} - virtual void useSymbol (const Symbol&) = 0; - }; - - virtual void visitAllSymbols (SymbolVisitor& visitor, const Scope& scope, int recursionDepth) - { - for (int i = getNumInputs(); --i >= 0;) - getInput(i)->visitAllSymbols (visitor, scope, recursionDepth); - } - -private: - JUCE_DECLARE_NON_COPYABLE (Term) -}; - - -//============================================================================== -struct Expression::Helpers -{ - typedef ReferenceCountedObjectPtr TermPtr; - - static void checkRecursionDepth (const int depth) - { - if (depth > 256) - throw EvaluationError ("Recursive symbol references"); - } - - friend class Expression::Term; - - //============================================================================== - /** An exception that can be thrown by Expression::evaluate(). */ - class EvaluationError : public std::exception - { - public: - EvaluationError (const String& desc) : description (desc) - { - DBG ("Expression::EvaluationError: " + description); - } - - String description; - }; - - //============================================================================== - class Constant : public Term - { - public: - Constant (const double val, const bool resolutionTarget) - : value (val), isResolutionTarget (resolutionTarget) {} - - Type getType() const noexcept { return constantType; } - Term* clone() const { return new Constant (value, isResolutionTarget); } - TermPtr resolve (const Scope&, int) { return this; } - double toDouble() const { return value; } - TermPtr negated() { return new Constant (-value, isResolutionTarget); } - - String toString() const - { - String s (value); - if (isResolutionTarget) - s = "@" + s; - - return s; - } - - double value; - bool isResolutionTarget; - }; - - //============================================================================== - class BinaryTerm : public Term - { - public: - BinaryTerm (Term* const l, Term* const r) : left (l), right (r) - { - jassert (l != nullptr && r != nullptr); - } - - int getInputIndexFor (const Term* possibleInput) const - { - return possibleInput == left ? 0 : (possibleInput == right ? 1 : -1); - } - - Type getType() const noexcept { return operatorType; } - int getNumInputs() const { return 2; } - Term* getInput (int index) const { return index == 0 ? left.get() : (index == 1 ? right.get() : 0); } - - virtual double performFunction (double left, double right) const = 0; - virtual void writeOperator (String& dest) const = 0; - - TermPtr resolve (const Scope& scope, int recursionDepth) - { - return new Constant (performFunction (left ->resolve (scope, recursionDepth)->toDouble(), - right->resolve (scope, recursionDepth)->toDouble()), false); - } - - String toString() const - { - String s; - - const int ourPrecendence = getOperatorPrecedence(); - if (left->getOperatorPrecedence() > ourPrecendence) - s << '(' << left->toString() << ')'; - else - s = left->toString(); - - writeOperator (s); - - if (right->getOperatorPrecedence() >= ourPrecendence) - s << '(' << right->toString() << ')'; - else - s << right->toString(); - - return s; - } - - protected: - const TermPtr left, right; - - TermPtr createDestinationTerm (const Scope& scope, const Term* input, double overallTarget, Term* topLevelTerm) const - { - jassert (input == left || input == right); - if (input != left && input != right) - return TermPtr(); - - if (const Term* const dest = findDestinationFor (topLevelTerm, this)) - return dest->createTermToEvaluateInput (scope, this, overallTarget, topLevelTerm); - - return new Constant (overallTarget, false); - } - }; - - //============================================================================== - class SymbolTerm : public Term - { - public: - explicit SymbolTerm (const String& sym) : symbol (sym) {} - - TermPtr resolve (const Scope& scope, int recursionDepth) - { - checkRecursionDepth (recursionDepth); - return scope.getSymbolValue (symbol).term->resolve (scope, recursionDepth + 1); - } - - Type getType() const noexcept { return symbolType; } - Term* clone() const { return new SymbolTerm (symbol); } - String toString() const { return symbol; } - String getName() const { return symbol; } - - void visitAllSymbols (SymbolVisitor& visitor, const Scope& scope, int recursionDepth) - { - checkRecursionDepth (recursionDepth); - visitor.useSymbol (Symbol (scope.getScopeUID(), symbol)); - scope.getSymbolValue (symbol).term->visitAllSymbols (visitor, scope, recursionDepth + 1); - } - - void renameSymbol (const Symbol& oldSymbol, const String& newName, const Scope& scope, int /*recursionDepth*/) - { - if (oldSymbol.symbolName == symbol && scope.getScopeUID() == oldSymbol.scopeUID) - symbol = newName; - } - - String symbol; - }; - - //============================================================================== - class Function : public Term - { - public: - explicit Function (const String& name) : functionName (name) {} - - Function (const String& name, const Array& params) - : functionName (name), parameters (params) - {} - - Type getType() const noexcept { return functionType; } - Term* clone() const { return new Function (functionName, parameters); } - int getNumInputs() const { return parameters.size(); } - Term* getInput (int i) const { return parameters.getReference(i).term; } - String getName() const { return functionName; } - - TermPtr resolve (const Scope& scope, int recursionDepth) - { - checkRecursionDepth (recursionDepth); - double result = 0; - const int numParams = parameters.size(); - if (numParams > 0) - { - HeapBlock params ((size_t) numParams); - for (int i = 0; i < numParams; ++i) - params[i] = parameters.getReference(i).term->resolve (scope, recursionDepth + 1)->toDouble(); - - result = scope.evaluateFunction (functionName, params, numParams); - } - else - { - result = scope.evaluateFunction (functionName, nullptr, 0); - } - - return new Constant (result, false); - } - - int getInputIndexFor (const Term* possibleInput) const - { - for (int i = 0; i < parameters.size(); ++i) - if (parameters.getReference(i).term == possibleInput) - return i; - - return -1; - } - - String toString() const - { - if (parameters.size() == 0) - return functionName + "()"; - - String s (functionName + " ("); - - for (int i = 0; i < parameters.size(); ++i) - { - s << parameters.getReference(i).term->toString(); - - if (i < parameters.size() - 1) - s << ", "; - } - - s << ')'; - return s; - } - - const String functionName; - Array parameters; - }; - - //============================================================================== - class DotOperator : public BinaryTerm - { - public: - DotOperator (SymbolTerm* const l, Term* const r) : BinaryTerm (l, r) {} - - TermPtr resolve (const Scope& scope, int recursionDepth) - { - checkRecursionDepth (recursionDepth); - - EvaluationVisitor visitor (right, recursionDepth + 1); - scope.visitRelativeScope (getSymbol()->symbol, visitor); - return visitor.output; - } - - Term* clone() const { return new DotOperator (getSymbol(), right); } - String getName() const { return "."; } - int getOperatorPrecedence() const { return 1; } - void writeOperator (String& dest) const { dest << '.'; } - double performFunction (double, double) const { return 0.0; } - - void visitAllSymbols (SymbolVisitor& visitor, const Scope& scope, int recursionDepth) - { - checkRecursionDepth (recursionDepth); - visitor.useSymbol (Symbol (scope.getScopeUID(), getSymbol()->symbol)); - - SymbolVisitingVisitor v (right, visitor, recursionDepth + 1); - - try - { - scope.visitRelativeScope (getSymbol()->symbol, v); - } - catch (...) {} - } - - void renameSymbol (const Symbol& oldSymbol, const String& newName, const Scope& scope, int recursionDepth) - { - checkRecursionDepth (recursionDepth); - getSymbol()->renameSymbol (oldSymbol, newName, scope, recursionDepth); - - SymbolRenamingVisitor visitor (right, oldSymbol, newName, recursionDepth + 1); - - try - { - scope.visitRelativeScope (getSymbol()->symbol, visitor); - } - catch (...) {} - } - - private: - //============================================================================== - class EvaluationVisitor : public Scope::Visitor - { - public: - EvaluationVisitor (const TermPtr& t, const int recursion) - : input (t), output (t), recursionCount (recursion) {} - - void visit (const Scope& scope) { output = input->resolve (scope, recursionCount); } - - const TermPtr input; - TermPtr output; - const int recursionCount; - - private: - JUCE_DECLARE_NON_COPYABLE (EvaluationVisitor) - }; - - class SymbolVisitingVisitor : public Scope::Visitor - { - public: - SymbolVisitingVisitor (const TermPtr& t, SymbolVisitor& v, const int recursion) - : input (t), visitor (v), recursionCount (recursion) {} - - void visit (const Scope& scope) { input->visitAllSymbols (visitor, scope, recursionCount); } - - private: - const TermPtr input; - SymbolVisitor& visitor; - const int recursionCount; - - JUCE_DECLARE_NON_COPYABLE (SymbolVisitingVisitor) - }; - - class SymbolRenamingVisitor : public Scope::Visitor - { - public: - SymbolRenamingVisitor (const TermPtr& t, const Expression::Symbol& symbol_, const String& newName_, const int recursionCount_) - : input (t), symbol (symbol_), newName (newName_), recursionCount (recursionCount_) {} - - void visit (const Scope& scope) { input->renameSymbol (symbol, newName, scope, recursionCount); } - - private: - const TermPtr input; - const Symbol& symbol; - const String newName; - const int recursionCount; - - JUCE_DECLARE_NON_COPYABLE (SymbolRenamingVisitor) - }; - - SymbolTerm* getSymbol() const { return static_cast (left.get()); } - - JUCE_DECLARE_NON_COPYABLE (DotOperator) - }; - - //============================================================================== - class Negate : public Term - { - public: - explicit Negate (const TermPtr& t) : input (t) - { - jassert (t != nullptr); - } - - Type getType() const noexcept { return operatorType; } - int getInputIndexFor (const Term* possibleInput) const { return possibleInput == input ? 0 : -1; } - int getNumInputs() const { return 1; } - Term* getInput (int index) const { return index == 0 ? input.get() : nullptr; } - Term* clone() const { return new Negate (input->clone()); } - - TermPtr resolve (const Scope& scope, int recursionDepth) - { - return new Constant (-input->resolve (scope, recursionDepth)->toDouble(), false); - } - - String getName() const { return "-"; } - TermPtr negated() { return input; } - - TermPtr createTermToEvaluateInput (const Scope& scope, const Term* t, double overallTarget, Term* topLevelTerm) const - { - (void) t; - jassert (t == input); - - const Term* const dest = findDestinationFor (topLevelTerm, this); - - return new Negate (dest == nullptr ? new Constant (overallTarget, false) - : dest->createTermToEvaluateInput (scope, this, overallTarget, topLevelTerm)); - } - - String toString() const - { - if (input->getOperatorPrecedence() > 0) - return "-(" + input->toString() + ")"; - - return "-" + input->toString(); - } - - private: - const TermPtr input; - }; - - //============================================================================== - class Add : public BinaryTerm - { - public: - Add (Term* const l, Term* const r) : BinaryTerm (l, r) {} - - Term* clone() const { return new Add (left->clone(), right->clone()); } - double performFunction (double lhs, double rhs) const { return lhs + rhs; } - int getOperatorPrecedence() const { return 3; } - String getName() const { return "+"; } - void writeOperator (String& dest) const { dest << " + "; } - - TermPtr createTermToEvaluateInput (const Scope& scope, const Term* input, double overallTarget, Term* topLevelTerm) const - { - const TermPtr newDest (createDestinationTerm (scope, input, overallTarget, topLevelTerm)); - if (newDest == nullptr) - return TermPtr(); - - return new Subtract (newDest, (input == left ? right : left)->clone()); - } - - private: - JUCE_DECLARE_NON_COPYABLE (Add) - }; - - //============================================================================== - class Subtract : public BinaryTerm - { - public: - Subtract (Term* const l, Term* const r) : BinaryTerm (l, r) {} - - Term* clone() const { return new Subtract (left->clone(), right->clone()); } - double performFunction (double lhs, double rhs) const { return lhs - rhs; } - int getOperatorPrecedence() const { return 3; } - String getName() const { return "-"; } - void writeOperator (String& dest) const { dest << " - "; } - - TermPtr createTermToEvaluateInput (const Scope& scope, const Term* input, double overallTarget, Term* topLevelTerm) const - { - const TermPtr newDest (createDestinationTerm (scope, input, overallTarget, topLevelTerm)); - if (newDest == nullptr) - return TermPtr(); - - if (input == left) - return new Add (newDest, right->clone()); - - return new Subtract (left->clone(), newDest); - } - - private: - JUCE_DECLARE_NON_COPYABLE (Subtract) - }; - - //============================================================================== - class Multiply : public BinaryTerm - { - public: - Multiply (Term* const l, Term* const r) : BinaryTerm (l, r) {} - - Term* clone() const { return new Multiply (left->clone(), right->clone()); } - double performFunction (double lhs, double rhs) const { return lhs * rhs; } - String getName() const { return "*"; } - void writeOperator (String& dest) const { dest << " * "; } - int getOperatorPrecedence() const { return 2; } - - TermPtr createTermToEvaluateInput (const Scope& scope, const Term* input, double overallTarget, Term* topLevelTerm) const - { - const TermPtr newDest (createDestinationTerm (scope, input, overallTarget, topLevelTerm)); - if (newDest == nullptr) - return TermPtr(); - - return new Divide (newDest, (input == left ? right : left)->clone()); - } - - private: - JUCE_DECLARE_NON_COPYABLE (Multiply) - }; - - //============================================================================== - class Divide : public BinaryTerm - { - public: - Divide (Term* const l, Term* const r) : BinaryTerm (l, r) {} - - Term* clone() const { return new Divide (left->clone(), right->clone()); } - double performFunction (double lhs, double rhs) const { return lhs / rhs; } - String getName() const { return "/"; } - void writeOperator (String& dest) const { dest << " / "; } - int getOperatorPrecedence() const { return 2; } - - TermPtr createTermToEvaluateInput (const Scope& scope, const Term* input, double overallTarget, Term* topLevelTerm) const - { - const TermPtr newDest (createDestinationTerm (scope, input, overallTarget, topLevelTerm)); - if (newDest == nullptr) - return TermPtr(); - - if (input == left) - return new Multiply (newDest, right->clone()); - - return new Divide (left->clone(), newDest); - } - - private: - JUCE_DECLARE_NON_COPYABLE (Divide) - }; - - //============================================================================== - static Term* findDestinationFor (Term* const topLevel, const Term* const inputTerm) - { - const int inputIndex = topLevel->getInputIndexFor (inputTerm); - if (inputIndex >= 0) - return topLevel; - - for (int i = topLevel->getNumInputs(); --i >= 0;) - { - Term* const t = findDestinationFor (topLevel->getInput (i), inputTerm); - - if (t != nullptr) - return t; - } - - return nullptr; - } - - static Constant* findTermToAdjust (Term* const term, const bool mustBeFlagged) - { - jassert (term != nullptr); - - if (term->getType() == constantType) - { - Constant* const c = static_cast (term); - if (c->isResolutionTarget || ! mustBeFlagged) - return c; - } - - if (term->getType() == functionType) - return nullptr; - - const int numIns = term->getNumInputs(); - - for (int i = 0; i < numIns; ++i) - { - Term* const input = term->getInput (i); - - if (input->getType() == constantType) - { - Constant* const c = static_cast (input); - - if (c->isResolutionTarget || ! mustBeFlagged) - return c; - } - } - - for (int i = 0; i < numIns; ++i) - { - Constant* const c = findTermToAdjust (term->getInput (i), mustBeFlagged); - if (c != nullptr) - return c; - } - - return nullptr; - } - - static bool containsAnySymbols (const Term* const t) - { - if (t->getType() == Expression::symbolType) - return true; - - for (int i = t->getNumInputs(); --i >= 0;) - if (containsAnySymbols (t->getInput (i))) - return true; - - return false; - } - - //============================================================================== - class SymbolCheckVisitor : public Term::SymbolVisitor - { - public: - SymbolCheckVisitor (const Symbol& symbol_) : wasFound (false), symbol (symbol_) {} - void useSymbol (const Symbol& s) { wasFound = wasFound || s == symbol; } - - bool wasFound; - - private: - const Symbol& symbol; - - JUCE_DECLARE_NON_COPYABLE (SymbolCheckVisitor) - }; - - //============================================================================== - class SymbolListVisitor : public Term::SymbolVisitor - { - public: - SymbolListVisitor (Array& list_) : list (list_) {} - void useSymbol (const Symbol& s) { list.addIfNotAlreadyThere (s); } - - private: - Array& list; - - JUCE_DECLARE_NON_COPYABLE (SymbolListVisitor) - }; - - //============================================================================== - class Parser - { - public: - //============================================================================== - Parser (String::CharPointerType& stringToParse) - : text (stringToParse) - { - } - - TermPtr readUpToComma() - { - if (text.isEmpty()) - return new Constant (0.0, false); - - const TermPtr e (readExpression()); - - if (e == nullptr || ((! readOperator (",")) && ! text.isEmpty())) - throw ParseError ("Syntax error: \"" + String (text) + "\""); - - return e; - } - - private: - String::CharPointerType& text; - - //============================================================================== - static inline bool isDecimalDigit (const juce_wchar c) noexcept - { - return c >= '0' && c <= '9'; - } - - bool readChar (const juce_wchar required) noexcept - { - if (*text == required) - { - ++text; - return true; - } - - return false; - } - - bool readOperator (const char* ops, char* const opType = nullptr) noexcept - { - text = text.findEndOfWhitespace(); - - while (*ops != 0) - { - if (readChar ((juce_wchar) (uint8) *ops)) - { - if (opType != nullptr) - *opType = *ops; - - return true; - } - - ++ops; - } - - return false; - } - - bool readIdentifier (String& identifier) noexcept - { - text = text.findEndOfWhitespace(); - String::CharPointerType t (text); - int numChars = 0; - - if (t.isLetter() || *t == '_') - { - ++t; - ++numChars; - - while (t.isLetterOrDigit() || *t == '_') - { - ++t; - ++numChars; - } - } - - if (numChars > 0) - { - identifier = String (text, (size_t) numChars); - text = t; - return true; - } - - return false; - } - - Term* readNumber() noexcept - { - text = text.findEndOfWhitespace(); - String::CharPointerType t (text); - - const bool isResolutionTarget = (*t == '@'); - if (isResolutionTarget) - { - ++t; - t = t.findEndOfWhitespace(); - text = t; - } - - if (*t == '-') - { - ++t; - t = t.findEndOfWhitespace(); - } - - if (isDecimalDigit (*t) || (*t == '.' && isDecimalDigit (t[1]))) - return new Constant (CharacterFunctions::readDoubleValue (text), isResolutionTarget); - - return nullptr; - } - - TermPtr readExpression() - { - TermPtr lhs (readMultiplyOrDivideExpression()); - - char opType; - while (lhs != nullptr && readOperator ("+-", &opType)) - { - TermPtr rhs (readMultiplyOrDivideExpression()); - - if (rhs == nullptr) - throw ParseError ("Expected expression after \"" + String::charToString ((juce_wchar) (uint8) opType) + "\""); - - if (opType == '+') - lhs = new Add (lhs, rhs); - else - lhs = new Subtract (lhs, rhs); - } - - return lhs; - } - - TermPtr readMultiplyOrDivideExpression() - { - TermPtr lhs (readUnaryExpression()); - - char opType; - while (lhs != nullptr && readOperator ("*/", &opType)) - { - TermPtr rhs (readUnaryExpression()); - - if (rhs == nullptr) - throw ParseError ("Expected expression after \"" + String::charToString ((juce_wchar) (uint8) opType) + "\""); - - if (opType == '*') - lhs = new Multiply (lhs, rhs); - else - lhs = new Divide (lhs, rhs); - } - - return lhs; - } - - TermPtr readUnaryExpression() - { - char opType; - if (readOperator ("+-", &opType)) - { - TermPtr e (readUnaryExpression()); - - if (e == nullptr) - throw ParseError ("Expected expression after \"" + String::charToString ((juce_wchar) (uint8) opType) + "\""); - - if (opType == '-') - e = e->negated(); - - return e; - } - - return readPrimaryExpression(); - } - - TermPtr readPrimaryExpression() - { - TermPtr e (readParenthesisedExpression()); - if (e != nullptr) - return e; - - e = readNumber(); - if (e != nullptr) - return e; - - return readSymbolOrFunction(); - } - - TermPtr readSymbolOrFunction() - { - String identifier; - if (readIdentifier (identifier)) - { - if (readOperator ("(")) // method call... - { - Function* const f = new Function (identifier); - ScopedPointer func (f); // (can't use ScopedPointer in MSVC) - - TermPtr param (readExpression()); - - if (param == nullptr) - { - if (readOperator (")")) - return func.release(); - - throw ParseError ("Expected parameters after \"" + identifier + " (\""); - } - - f->parameters.add (Expression (param)); - - while (readOperator (",")) - { - param = readExpression(); - - if (param == nullptr) - throw ParseError ("Expected expression after \",\""); - - f->parameters.add (Expression (param)); - } - - if (readOperator (")")) - return func.release(); - - throw ParseError ("Expected \")\""); - } - - if (readOperator (".")) - { - TermPtr rhs (readSymbolOrFunction()); - - if (rhs == nullptr) - throw ParseError ("Expected symbol or function after \".\""); - - if (identifier == "this") - return rhs; - - return new DotOperator (new SymbolTerm (identifier), rhs); - } - - // just a symbol.. - jassert (identifier.trim() == identifier); - return new SymbolTerm (identifier); - } - - return TermPtr(); - } - - TermPtr readParenthesisedExpression() - { - if (! readOperator ("(")) - return TermPtr(); - - const TermPtr e (readExpression()); - if (e == nullptr || ! readOperator (")")) - return TermPtr(); - - return e; - } - - JUCE_DECLARE_NON_COPYABLE (Parser) - }; -}; - -//============================================================================== -Expression::Expression() - : term (new Expression::Helpers::Constant (0, false)) -{ -} - -Expression::~Expression() -{ -} - -Expression::Expression (Term* const term_) - : term (term_) -{ - jassert (term != nullptr); -} - -Expression::Expression (const double constant) - : term (new Expression::Helpers::Constant (constant, false)) -{ -} - -Expression::Expression (const Expression& other) - : term (other.term) -{ -} - -Expression& Expression::operator= (const Expression& other) -{ - term = other.term; - return *this; -} - -#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS -Expression::Expression (Expression&& other) noexcept - : term (static_cast &&> (other.term)) -{ -} - -Expression& Expression::operator= (Expression&& other) noexcept -{ - term = static_cast &&> (other.term); - return *this; -} -#endif - -Expression::Expression (const String& stringToParse) -{ - String::CharPointerType text (stringToParse.getCharPointer()); - Helpers::Parser parser (text); - term = parser.readUpToComma(); -} - -Expression Expression::parse (String::CharPointerType& stringToParse) -{ - Helpers::Parser parser (stringToParse); - return Expression (parser.readUpToComma()); -} - -double Expression::evaluate() const -{ - return evaluate (Expression::Scope()); -} - -double Expression::evaluate (const Expression::Scope& scope) const -{ - try - { - return term->resolve (scope, 0)->toDouble(); - } - catch (Helpers::EvaluationError&) - {} - - return 0; -} - -double Expression::evaluate (const Scope& scope, String& evaluationError) const -{ - try - { - return term->resolve (scope, 0)->toDouble(); - } - catch (Helpers::EvaluationError& e) - { - evaluationError = e.description; - } - - return 0; -} - -Expression Expression::operator+ (const Expression& other) const { return Expression (new Helpers::Add (term, other.term)); } -Expression Expression::operator- (const Expression& other) const { return Expression (new Helpers::Subtract (term, other.term)); } -Expression Expression::operator* (const Expression& other) const { return Expression (new Helpers::Multiply (term, other.term)); } -Expression Expression::operator/ (const Expression& other) const { return Expression (new Helpers::Divide (term, other.term)); } -Expression Expression::operator-() const { return Expression (term->negated()); } -Expression Expression::symbol (const String& symbol) { return Expression (new Helpers::SymbolTerm (symbol)); } - -Expression Expression::function (const String& functionName, const Array& parameters) -{ - return Expression (new Helpers::Function (functionName, parameters)); -} - -Expression Expression::adjustedToGiveNewResult (const double targetValue, const Expression::Scope& scope) const -{ - ScopedPointer newTerm (term->clone()); - - Helpers::Constant* termToAdjust = Helpers::findTermToAdjust (newTerm, true); - - if (termToAdjust == nullptr) - termToAdjust = Helpers::findTermToAdjust (newTerm, false); - - if (termToAdjust == nullptr) - { - newTerm = new Helpers::Add (newTerm.release(), new Helpers::Constant (0, false)); - termToAdjust = Helpers::findTermToAdjust (newTerm, false); - } - - jassert (termToAdjust != nullptr); - - const Term* const parent = Helpers::findDestinationFor (newTerm, termToAdjust); - - if (parent == nullptr) - { - termToAdjust->value = targetValue; - } - else - { - const Helpers::TermPtr reverseTerm (parent->createTermToEvaluateInput (scope, termToAdjust, targetValue, newTerm)); - - if (reverseTerm == nullptr) - return Expression (targetValue); - - termToAdjust->value = reverseTerm->resolve (scope, 0)->toDouble(); - } - - return Expression (newTerm.release()); -} - -Expression Expression::withRenamedSymbol (const Expression::Symbol& oldSymbol, const String& newName, const Scope& scope) const -{ - jassert (newName.toLowerCase().containsOnly ("abcdefghijklmnopqrstuvwxyz0123456789_")); - - if (oldSymbol.symbolName == newName) - return *this; - - Expression e (term->clone()); - e.term->renameSymbol (oldSymbol, newName, scope, 0); - return e; -} - -bool Expression::referencesSymbol (const Expression::Symbol& symbolToCheck, const Scope& scope) const -{ - Helpers::SymbolCheckVisitor visitor (symbolToCheck); - - try - { - term->visitAllSymbols (visitor, scope, 0); - } - catch (Helpers::EvaluationError&) - {} - - return visitor.wasFound; -} - -void Expression::findReferencedSymbols (Array& results, const Scope& scope) const -{ - try - { - Helpers::SymbolListVisitor visitor (results); - term->visitAllSymbols (visitor, scope, 0); - } - catch (Helpers::EvaluationError&) - {} -} - -String Expression::toString() const { return term->toString(); } -bool Expression::usesAnySymbols() const { return Helpers::containsAnySymbols (term); } -Expression::Type Expression::getType() const noexcept { return term->getType(); } -String Expression::getSymbolOrFunction() const { return term->getName(); } -int Expression::getNumInputs() const { return term->getNumInputs(); } -Expression Expression::getInput (int index) const { return Expression (term->getInput (index)); } - -//============================================================================== -ReferenceCountedObjectPtr Expression::Term::negated() -{ - return new Helpers::Negate (this); -} - -//============================================================================== -Expression::ParseError::ParseError (const String& message) - : description (message) -{ - DBG ("Expression::ParseError: " + message); -} - -//============================================================================== -Expression::Symbol::Symbol (const String& scopeUID_, const String& symbolName_) - : scopeUID (scopeUID_), symbolName (symbolName_) -{ -} - -bool Expression::Symbol::operator== (const Symbol& other) const noexcept -{ - return symbolName == other.symbolName && scopeUID == other.scopeUID; -} - -bool Expression::Symbol::operator!= (const Symbol& other) const noexcept -{ - return ! operator== (other); -} - -//============================================================================== -Expression::Scope::Scope() {} -Expression::Scope::~Scope() {} - -Expression Expression::Scope::getSymbolValue (const String& symbol) const -{ - if (symbol.isNotEmpty()) - throw Helpers::EvaluationError ("Unknown symbol: " + symbol); - - return Expression(); -} - -double Expression::Scope::evaluateFunction (const String& functionName, const double* parameters, int numParams) const -{ - if (numParams > 0) - { - if (functionName == "min") - { - double v = parameters[0]; - for (int i = 1; i < numParams; ++i) - v = jmin (v, parameters[i]); - - return v; - } - - if (functionName == "max") - { - double v = parameters[0]; - for (int i = 1; i < numParams; ++i) - v = jmax (v, parameters[i]); - - return v; - } - - if (numParams == 1) - { - if (functionName == "sin") return sin (parameters[0]); - if (functionName == "cos") return cos (parameters[0]); - if (functionName == "tan") return tan (parameters[0]); - if (functionName == "abs") return std::abs (parameters[0]); - } - } - - throw Helpers::EvaluationError ("Unknown function: \"" + functionName + "\""); -} - -void Expression::Scope::visitRelativeScope (const String& scopeName, Visitor&) const -{ - throw Helpers::EvaluationError ("Unknown symbol: " + scopeName); -} - -String Expression::Scope::getScopeUID() const -{ - return String(); -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/maths/juce_Expression.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/maths/juce_Expression.h deleted file mode 100644 index 8939129093..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/maths/juce_Expression.h +++ /dev/null @@ -1,270 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_EXPRESSION_H_INCLUDED -#define JUCE_EXPRESSION_H_INCLUDED - - -//============================================================================== -/** - A class for dynamically evaluating simple numeric expressions. - - This class can parse a simple C-style string expression involving floating point - numbers, named symbols and functions. The basic arithmetic operations of +, -, *, / - are supported, as well as parentheses, and any alphanumeric identifiers are - assumed to be named symbols which will be resolved when the expression is - evaluated. - - Expressions which use identifiers and functions require a subclass of - Expression::Scope to be supplied when evaluating them, and this object - is expected to be able to resolve the symbol names and perform the functions that - are used. -*/ -class JUCE_API Expression -{ -public: - //============================================================================== - /** Creates a simple expression with a value of 0. */ - Expression(); - - /** Destructor. */ - ~Expression(); - - /** Creates a simple expression with a specified constant value. */ - explicit Expression (double constant); - - /** Creates a copy of an expression. */ - Expression (const Expression&); - - /** Copies another expression. */ - Expression& operator= (const Expression&); - - #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS - Expression (Expression&&) noexcept; - Expression& operator= (Expression&&) noexcept; - #endif - - /** Creates an expression by parsing a string. - If there's a syntax error in the string, this will throw a ParseError exception. - @throws ParseError - */ - explicit Expression (const String& stringToParse); - - /** Returns a string version of the expression. */ - String toString() const; - - /** Returns an expression which is an addition operation of two existing expressions. */ - Expression operator+ (const Expression&) const; - /** Returns an expression which is a subtraction operation of two existing expressions. */ - Expression operator- (const Expression&) const; - /** Returns an expression which is a multiplication operation of two existing expressions. */ - Expression operator* (const Expression&) const; - /** Returns an expression which is a division operation of two existing expressions. */ - Expression operator/ (const Expression&) const; - /** Returns an expression which performs a negation operation on an existing expression. */ - Expression operator-() const; - - /** Returns an Expression which is an identifier reference. */ - static Expression symbol (const String& symbol); - - /** Returns an Expression which is a function call. */ - static Expression function (const String& functionName, const Array& parameters); - - /** Returns an Expression which parses a string from a character pointer, and updates the pointer - to indicate where it finished. - - The pointer is incremented so that on return, it indicates the character that follows - the end of the expression that was parsed. - - If there's a syntax error in the string, this will throw a ParseError exception. - @throws ParseError - */ - static Expression parse (String::CharPointerType& stringToParse); - - //============================================================================== - /** When evaluating an Expression object, this class is used to resolve symbols and - perform functions that the expression uses. - */ - class JUCE_API Scope - { - public: - Scope(); - virtual ~Scope(); - - /** Returns some kind of globally unique ID that identifies this scope. */ - virtual String getScopeUID() const; - - /** Returns the value of a symbol. - If the symbol is unknown, this can throw an Expression::EvaluationError exception. - The member value is set to the part of the symbol that followed the dot, if there is - one, e.g. for "foo.bar", symbol = "foo" and member = "bar". - @throws Expression::EvaluationError - */ - virtual Expression getSymbolValue (const String& symbol) const; - - /** Executes a named function. - If the function name is unknown, this can throw an Expression::EvaluationError exception. - @throws Expression::EvaluationError - */ - virtual double evaluateFunction (const String& functionName, - const double* parameters, int numParameters) const; - - /** Used as a callback by the Scope::visitRelativeScope() method. - You should never create an instance of this class yourself, it's used by the - expression evaluation code. - */ - class Visitor - { - public: - virtual ~Visitor() {} - virtual void visit (const Scope&) = 0; - }; - - /** Creates a Scope object for a named scope, and then calls a visitor - to do some kind of processing with this new scope. - - If the name is valid, this method must create a suitable (temporary) Scope - object to represent it, and must call the Visitor::visit() method with this - new scope. - */ - virtual void visitRelativeScope (const String& scopeName, Visitor& visitor) const; - }; - - /** Evaluates this expression, without using a Scope. - Without a Scope, no symbols can be used, and only basic functions such as sin, cos, tan, - min, max are available. - To find out about any errors during evaluation, use the other version of this method which - takes a String parameter. - */ - double evaluate() const; - - /** Evaluates this expression, providing a scope that should be able to evaluate any symbols - or functions that it uses. - To find out about any errors during evaluation, use the other version of this method which - takes a String parameter. - */ - double evaluate (const Scope& scope) const; - - /** Evaluates this expression, providing a scope that should be able to evaluate any symbols - or functions that it uses. - */ - double evaluate (const Scope& scope, String& evaluationError) const; - - /** Attempts to return an expression which is a copy of this one, but with a constant adjusted - to make the expression resolve to a target value. - - E.g. if the expression is "x + 10" and x is 5, then asking for a target value of 8 will return - the expression "x + 3". Obviously some expressions can't be reversed in this way, in which - case they might just be adjusted by adding a constant to the original expression. - - @throws Expression::EvaluationError - */ - Expression adjustedToGiveNewResult (double targetValue, const Scope& scope) const; - - /** Represents a symbol that is used in an Expression. */ - struct Symbol - { - Symbol (const String& scopeUID, const String& symbolName); - bool operator== (const Symbol&) const noexcept; - bool operator!= (const Symbol&) const noexcept; - - String scopeUID; /**< The unique ID of the Scope that contains this symbol. */ - String symbolName; /**< The name of the symbol. */ - }; - - /** Returns a copy of this expression in which all instances of a given symbol have been renamed. */ - Expression withRenamedSymbol (const Symbol& oldSymbol, const String& newName, const Scope& scope) const; - - /** Returns true if this expression makes use of the specified symbol. - If a suitable scope is supplied, the search will dereference and recursively check - all symbols, so that it can be determined whether this expression relies on the given - symbol at any level in its evaluation. If the scope parameter is null, this just checks - whether the expression contains any direct references to the symbol. - - @throws Expression::EvaluationError - */ - bool referencesSymbol (const Symbol& symbol, const Scope& scope) const; - - /** Returns true if this expression contains any symbols. */ - bool usesAnySymbols() const; - - /** Returns a list of all symbols that may be needed to resolve this expression in the given scope. */ - void findReferencedSymbols (Array& results, const Scope& scope) const; - - //============================================================================== - /** An exception that can be thrown by Expression::parse(). */ - class ParseError : public std::exception - { - public: - ParseError (const String& message); - - String description; - }; - - //============================================================================== - /** Expression type. - @see Expression::getType() - */ - enum Type - { - constantType, - functionType, - operatorType, - symbolType - }; - - /** Returns the type of this expression. */ - Type getType() const noexcept; - - /** If this expression is a symbol, function or operator, this returns its identifier. */ - String getSymbolOrFunction() const; - - /** Returns the number of inputs to this expression. - @see getInput - */ - int getNumInputs() const; - - /** Retrieves one of the inputs to this expression. - @see getNumInputs - */ - Expression getInput (int index) const; - -private: - //============================================================================== - class Term; - struct Helpers; - friend class Term; - friend struct Helpers; - friend struct ContainerDeletePolicy; - friend class ReferenceCountedObjectPtr; - ReferenceCountedObjectPtr term; - - explicit Expression (Term*); -}; - -#endif // JUCE_EXPRESSION_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/maths/juce_MathsFunctions.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/maths/juce_MathsFunctions.h deleted file mode 100644 index d2d02b900f..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/maths/juce_MathsFunctions.h +++ /dev/null @@ -1,549 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_MATHSFUNCTIONS_H_INCLUDED -#define JUCE_MATHSFUNCTIONS_H_INCLUDED - -//============================================================================== -/* - This file sets up some handy mathematical typdefs and functions. -*/ - -//============================================================================== -// Definitions for the int8, int16, int32, int64 and pointer_sized_int types. - -/** A platform-independent 8-bit signed integer type. */ -typedef signed char int8; -/** A platform-independent 8-bit unsigned integer type. */ -typedef unsigned char uint8; -/** A platform-independent 16-bit signed integer type. */ -typedef signed short int16; -/** A platform-independent 16-bit unsigned integer type. */ -typedef unsigned short uint16; -/** A platform-independent 32-bit signed integer type. */ -typedef signed int int32; -/** A platform-independent 32-bit unsigned integer type. */ -typedef unsigned int uint32; - -#if JUCE_MSVC - /** A platform-independent 64-bit integer type. */ - typedef __int64 int64; - /** A platform-independent 64-bit unsigned integer type. */ - typedef unsigned __int64 uint64; -#else - /** A platform-independent 64-bit integer type. */ - typedef long long int64; - /** A platform-independent 64-bit unsigned integer type. */ - typedef unsigned long long uint64; -#endif - -#ifndef DOXYGEN - /** A macro for creating 64-bit literals. - Historically, this was needed to support portability with MSVC6, and is kept here - so that old code will still compile, but nowadays every compiler will support the - LL and ULL suffixes, so you should use those in preference to this macro. - */ - #define literal64bit(longLiteral) (longLiteral##LL) -#endif - -#if JUCE_64BIT - /** A signed integer type that's guaranteed to be large enough to hold a pointer without truncating it. */ - typedef int64 pointer_sized_int; - /** An unsigned integer type that's guaranteed to be large enough to hold a pointer without truncating it. */ - typedef uint64 pointer_sized_uint; -#elif JUCE_MSVC - /** A signed integer type that's guaranteed to be large enough to hold a pointer without truncating it. */ - typedef _W64 int pointer_sized_int; - /** An unsigned integer type that's guaranteed to be large enough to hold a pointer without truncating it. */ - typedef _W64 unsigned int pointer_sized_uint; -#else - /** A signed integer type that's guaranteed to be large enough to hold a pointer without truncating it. */ - typedef int pointer_sized_int; - /** An unsigned integer type that's guaranteed to be large enough to hold a pointer without truncating it. */ - typedef unsigned int pointer_sized_uint; -#endif - -#if JUCE_MSVC - typedef pointer_sized_int ssize_t; -#endif - -//============================================================================== -// Some indispensible min/max functions - -/** Returns the larger of two values. */ -template -inline Type jmax (const Type a, const Type b) { return (a < b) ? b : a; } - -/** Returns the larger of three values. */ -template -inline Type jmax (const Type a, const Type b, const Type c) { return (a < b) ? ((b < c) ? c : b) : ((a < c) ? c : a); } - -/** Returns the larger of four values. */ -template -inline Type jmax (const Type a, const Type b, const Type c, const Type d) { return jmax (a, jmax (b, c, d)); } - -/** Returns the smaller of two values. */ -template -inline Type jmin (const Type a, const Type b) { return (b < a) ? b : a; } - -/** Returns the smaller of three values. */ -template -inline Type jmin (const Type a, const Type b, const Type c) { return (b < a) ? ((c < b) ? c : b) : ((c < a) ? c : a); } - -/** Returns the smaller of four values. */ -template -inline Type jmin (const Type a, const Type b, const Type c, const Type d) { return jmin (a, jmin (b, c, d)); } - -/** Scans an array of values, returning the minimum value that it contains. */ -template -const Type findMinimum (const Type* data, int numValues) -{ - if (numValues <= 0) - return Type(); - - Type result (*data++); - - while (--numValues > 0) // (> 0 rather than >= 0 because we've already taken the first sample) - { - const Type& v = *data++; - if (v < result) result = v; - } - - return result; -} - -/** Scans an array of values, returning the maximum value that it contains. */ -template -const Type findMaximum (const Type* values, int numValues) -{ - if (numValues <= 0) - return Type(); - - Type result (*values++); - - while (--numValues > 0) // (> 0 rather than >= 0 because we've already taken the first sample) - { - const Type& v = *values++; - if (result < v) result = v; - } - - return result; -} - -/** Scans an array of values, returning the minimum and maximum values that it contains. */ -template -void findMinAndMax (const Type* values, int numValues, Type& lowest, Type& highest) -{ - if (numValues <= 0) - { - lowest = Type(); - highest = Type(); - } - else - { - Type mn (*values++); - Type mx (mn); - - while (--numValues > 0) // (> 0 rather than >= 0 because we've already taken the first sample) - { - const Type& v = *values++; - - if (mx < v) mx = v; - if (v < mn) mn = v; - } - - lowest = mn; - highest = mx; - } -} - - -//============================================================================== -/** Constrains a value to keep it within a given range. - - This will check that the specified value lies between the lower and upper bounds - specified, and if not, will return the nearest value that would be in-range. Effectively, - it's like calling jmax (lowerLimit, jmin (upperLimit, value)). - - Note that it expects that lowerLimit <= upperLimit. If this isn't true, - the results will be unpredictable. - - @param lowerLimit the minimum value to return - @param upperLimit the maximum value to return - @param valueToConstrain the value to try to return - @returns the closest value to valueToConstrain which lies between lowerLimit - and upperLimit (inclusive) - @see jlimit0To, jmin, jmax -*/ -template -inline Type jlimit (const Type lowerLimit, - const Type upperLimit, - const Type valueToConstrain) noexcept -{ - jassert (lowerLimit <= upperLimit); // if these are in the wrong order, results are unpredictable.. - - return (valueToConstrain < lowerLimit) ? lowerLimit - : ((upperLimit < valueToConstrain) ? upperLimit - : valueToConstrain); -} - -/** Returns true if a value is at least zero, and also below a specified upper limit. - This is basically a quicker way to write: - @code valueToTest >= 0 && valueToTest < upperLimit - @endcode -*/ -template -inline bool isPositiveAndBelow (Type valueToTest, Type upperLimit) noexcept -{ - jassert (Type() <= upperLimit); // makes no sense to call this if the upper limit is itself below zero.. - return Type() <= valueToTest && valueToTest < upperLimit; -} - -template <> -inline bool isPositiveAndBelow (const int valueToTest, const int upperLimit) noexcept -{ - jassert (upperLimit >= 0); // makes no sense to call this if the upper limit is itself below zero.. - return static_cast (valueToTest) < static_cast (upperLimit); -} - -/** Returns true if a value is at least zero, and also less than or equal to a specified upper limit. - This is basically a quicker way to write: - @code valueToTest >= 0 && valueToTest <= upperLimit - @endcode -*/ -template -inline bool isPositiveAndNotGreaterThan (Type valueToTest, Type upperLimit) noexcept -{ - jassert (Type() <= upperLimit); // makes no sense to call this if the upper limit is itself below zero.. - return Type() <= valueToTest && valueToTest <= upperLimit; -} - -template <> -inline bool isPositiveAndNotGreaterThan (const int valueToTest, const int upperLimit) noexcept -{ - jassert (upperLimit >= 0); // makes no sense to call this if the upper limit is itself below zero.. - return static_cast (valueToTest) <= static_cast (upperLimit); -} - -//============================================================================== -/** Handy function to swap two values. */ -template -inline void swapVariables (Type& variable1, Type& variable2) -{ - std::swap (variable1, variable2); -} - -/** Handy function for getting the number of elements in a simple const C array. - E.g. - @code - static int myArray[] = { 1, 2, 3 }; - - int numElements = numElementsInArray (myArray) // returns 3 - @endcode -*/ -template -inline int numElementsInArray (Type (&array)[N]) -{ - (void) array; // (required to avoid a spurious warning in MS compilers) - (void) sizeof (0[array]); // This line should cause an error if you pass an object with a user-defined subscript operator - return N; -} - -//============================================================================== -// Some useful maths functions that aren't always present with all compilers and build settings. - -/** Using juce_hypot is easier than dealing with the different types of hypot function - that are provided by the various platforms and compilers. */ -template -inline Type juce_hypot (Type a, Type b) noexcept -{ - #if JUCE_MSVC - return static_cast (_hypot (a, b)); - #else - return static_cast (hypot (a, b)); - #endif -} - -/** 64-bit abs function. */ -inline int64 abs64 (const int64 n) noexcept -{ - return (n >= 0) ? n : -n; -} - -#if JUCE_MSVC && ! defined (DOXYGEN) // The MSVC libraries omit these functions for some reason... - template Type asinh (Type x) noexcept { return std::log (x + std::sqrt (x * x + (Type) 1)); } - template Type acosh (Type x) noexcept { return std::log (x + std::sqrt (x * x - (Type) 1)); } - template Type atanh (Type x) noexcept { return (std::log (x + (Type) 1) - std::log (((Type) 1) - x)) / (Type) 2; } -#endif - -//============================================================================== -/** A predefined value for Pi, at double-precision. - @see float_Pi -*/ -const double double_Pi = 3.1415926535897932384626433832795; - -/** A predefined value for Pi, at single-precision. - @see double_Pi -*/ -const float float_Pi = 3.14159265358979323846f; - - -//============================================================================== -/** The isfinite() method seems to vary between platforms, so this is a - platform-independent function for it. -*/ -template -inline bool juce_isfinite (FloatingPointType value) -{ - #if JUCE_WINDOWS - return _finite (value); - #elif JUCE_ANDROID - return isfinite (value); - #else - return std::isfinite (value); - #endif -} - -//============================================================================== -#if JUCE_MSVC - #pragma optimize ("t", off) - #ifndef __INTEL_COMPILER - #pragma float_control (precise, on, push) - #endif -#endif - -/** Fast floating-point-to-integer conversion. - - This is faster than using the normal c++ cast to convert a float to an int, and - it will round the value to the nearest integer, rather than rounding it down - like the normal cast does. - - Note that this routine gets its speed at the expense of some accuracy, and when - rounding values whose floating point component is exactly 0.5, odd numbers and - even numbers will be rounded up or down differently. -*/ -template -inline int roundToInt (const FloatType value) noexcept -{ - #ifdef __INTEL_COMPILER - #pragma float_control (precise, on, push) - #endif - - union { int asInt[2]; double asDouble; } n; - n.asDouble = ((double) value) + 6755399441055744.0; - - #if JUCE_BIG_ENDIAN - return n.asInt [1]; - #else - return n.asInt [0]; - #endif -} - -inline int roundToInt (int value) noexcept -{ - return value; -} - -#if JUCE_MSVC - #ifndef __INTEL_COMPILER - #pragma float_control (pop) - #endif - #pragma optimize ("", on) // resets optimisations to the project defaults -#endif - -/** Fast floating-point-to-integer conversion. - - This is a slightly slower and slightly more accurate version of roundDoubleToInt(). It works - fine for values above zero, but negative numbers are rounded the wrong way. -*/ -inline int roundToIntAccurate (const double value) noexcept -{ - #ifdef __INTEL_COMPILER - #pragma float_control (pop) - #endif - - return roundToInt (value + 1.5e-8); -} - -/** Fast floating-point-to-integer conversion. - - This is faster than using the normal c++ cast to convert a double to an int, and - it will round the value to the nearest integer, rather than rounding it down - like the normal cast does. - - Note that this routine gets its speed at the expense of some accuracy, and when - rounding values whose floating point component is exactly 0.5, odd numbers and - even numbers will be rounded up or down differently. For a more accurate conversion, - see roundDoubleToIntAccurate(). -*/ -inline int roundDoubleToInt (const double value) noexcept -{ - return roundToInt (value); -} - -/** Fast floating-point-to-integer conversion. - - This is faster than using the normal c++ cast to convert a float to an int, and - it will round the value to the nearest integer, rather than rounding it down - like the normal cast does. - - Note that this routine gets its speed at the expense of some accuracy, and when - rounding values whose floating point component is exactly 0.5, odd numbers and - even numbers will be rounded up or down differently. -*/ -inline int roundFloatToInt (const float value) noexcept -{ - return roundToInt (value); -} - -//============================================================================== -/** Returns true if the specified integer is a power-of-two. -*/ -template -bool isPowerOfTwo (IntegerType value) -{ - return (value & (value - 1)) == 0; -} - -/** Returns the smallest power-of-two which is equal to or greater than the given integer. -*/ -inline int nextPowerOfTwo (int n) noexcept -{ - --n; - n |= (n >> 1); - n |= (n >> 2); - n |= (n >> 4); - n |= (n >> 8); - n |= (n >> 16); - return n + 1; -} - -/** Returns the number of bits in a 32-bit integer. */ -inline int countNumberOfBits (uint32 n) noexcept -{ - n -= ((n >> 1) & 0x55555555); - n = (((n >> 2) & 0x33333333) + (n & 0x33333333)); - n = (((n >> 4) + n) & 0x0f0f0f0f); - n += (n >> 8); - n += (n >> 16); - return (int) (n & 0x3f); -} - -/** Returns the number of bits in a 64-bit integer. */ -inline int countNumberOfBits (uint64 n) noexcept -{ - return countNumberOfBits ((uint32) n) + countNumberOfBits ((uint32) (n >> 32)); -} - -/** Performs a modulo operation, but can cope with the dividend being negative. - The divisor must be greater than zero. -*/ -template -IntegerType negativeAwareModulo (IntegerType dividend, const IntegerType divisor) noexcept -{ - jassert (divisor > 0); - dividend %= divisor; - return (dividend < 0) ? (dividend + divisor) : dividend; -} - -/** Returns the square of its argument. */ -template -NumericType square (NumericType n) noexcept -{ - return n * n; -} - -//============================================================================== -#if (JUCE_INTEL && JUCE_32BIT) || defined (DOXYGEN) - /** This macro can be applied to a float variable to check whether it contains a denormalised - value, and to normalise it if necessary. - On CPUs that aren't vulnerable to denormalisation problems, this will have no effect. - */ - #define JUCE_UNDENORMALISE(x) x += 1.0f; x -= 1.0f; -#else - #define JUCE_UNDENORMALISE(x) -#endif - -//============================================================================== -/** This namespace contains a few template classes for helping work out class type variations. -*/ -namespace TypeHelpers -{ - #if JUCE_VC8_OR_EARLIER - #define PARAMETER_TYPE(type) const type& - #else - /** The ParameterType struct is used to find the best type to use when passing some kind - of object as a parameter. - - Of course, this is only likely to be useful in certain esoteric template situations. - - Because "typename TypeHelpers::ParameterType::type" is a bit of a mouthful, there's - a PARAMETER_TYPE(SomeClass) macro that you can use to get the same effect. - - E.g. "myFunction (PARAMETER_TYPE (int), PARAMETER_TYPE (MyObject))" - would evaluate to "myfunction (int, const MyObject&)", keeping any primitive types as - pass-by-value, but passing objects as a const reference, to avoid copying. - */ - template struct ParameterType { typedef const Type& type; }; - - #if ! DOXYGEN - template struct ParameterType { typedef Type& type; }; - template struct ParameterType { typedef Type* type; }; - template <> struct ParameterType { typedef char type; }; - template <> struct ParameterType { typedef unsigned char type; }; - template <> struct ParameterType { typedef short type; }; - template <> struct ParameterType { typedef unsigned short type; }; - template <> struct ParameterType { typedef int type; }; - template <> struct ParameterType { typedef unsigned int type; }; - template <> struct ParameterType { typedef long type; }; - template <> struct ParameterType { typedef unsigned long type; }; - template <> struct ParameterType { typedef int64 type; }; - template <> struct ParameterType { typedef uint64 type; }; - template <> struct ParameterType { typedef bool type; }; - template <> struct ParameterType { typedef float type; }; - template <> struct ParameterType { typedef double type; }; - #endif - - /** A helpful macro to simplify the use of the ParameterType template. - @see ParameterType - */ - #define PARAMETER_TYPE(a) typename TypeHelpers::ParameterType::type - #endif - - - /** These templates are designed to take a type, and if it's a double, they return a double - type; for anything else, they return a float type. - */ - template struct SmallestFloatType { typedef float type; }; - template <> struct SmallestFloatType { typedef double type; }; -} - - -//============================================================================== - -#endif // JUCE_MATHSFUNCTIONS_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/maths/juce_NormalisableRange.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/maths/juce_NormalisableRange.h deleted file mode 100644 index 800c616303..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/maths/juce_NormalisableRange.h +++ /dev/null @@ -1,169 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_NORMALISABLERANGE_H_INCLUDED -#define JUCE_NORMALISABLERANGE_H_INCLUDED - - -//============================================================================== -/** - Represents a mapping between an arbitrary range of values and a - normalised 0->1 range. - - The properties of the mapping also include an optional snapping interval - and skew-factor. - - @see Range -*/ -template -class NormalisableRange -{ -public: - /** Creates a continuous range that performs a dummy mapping. */ - NormalisableRange() noexcept : start(), end (1), interval(), skew (static_cast (1)) {} - - /** Creates a copy of another range. */ - NormalisableRange (const NormalisableRange& other) noexcept - : start (other.start), end (other.end), - interval (other.interval), skew (other.skew) - { - checkInvariants(); - } - - /** Creates a copy of another range. */ - NormalisableRange& operator= (const NormalisableRange& other) noexcept - { - start = other.start; - end = other.end; - interval = other.interval; - skew = other.skew; - checkInvariants(); - return *this; - } - - /** Creates a NormalisableRange with a given range, interval and skew factor. */ - NormalisableRange (ValueType rangeStart, - ValueType rangeEnd, - ValueType intervalValue, - ValueType skewFactor) noexcept - : start (rangeStart), end (rangeEnd), - interval (intervalValue), skew (skewFactor) - { - checkInvariants(); - } - - /** Creates a NormalisableRange with a given range and interval, but a dummy skew-factor. */ - NormalisableRange (ValueType rangeStart, - ValueType rangeEnd, - ValueType intervalValue) noexcept - : start (rangeStart), end (rangeEnd), - interval (intervalValue), skew (static_cast (1)) - { - checkInvariants(); - } - - /** Creates a NormalisableRange with a given range, continuous interval, but a dummy skew-factor. */ - NormalisableRange (ValueType rangeStart, - ValueType rangeEnd) noexcept - : start (rangeStart), end (rangeEnd), - interval(), skew (static_cast (1)) - { - checkInvariants(); - } - - /** Uses the properties of this mapping to convert a non-normalised value to - its 0->1 representation. - */ - ValueType convertTo0to1 (ValueType v) const noexcept - { - ValueType proportion = (v - start) / (end - start); - - if (skew != static_cast (1)) - proportion = pow (proportion, skew); - - return proportion; - } - - /** Uses the properties of this mapping to convert a normalised 0->1 value to - its full-range representation. - */ - ValueType convertFrom0to1 (ValueType proportion) const noexcept - { - if (skew != static_cast (1) && proportion > ValueType()) - proportion = exp (log (proportion) / skew); - - return start + (end - start) * proportion; - } - - /** Takes a non-normalised value and snaps it based on the interval property of - this NormalisedRange. */ - ValueType snapToLegalValue (ValueType v) const noexcept - { - if (interval > ValueType()) - v = start + interval * std::floor ((v - start) / interval + static_cast (0.5)); - - if (v <= start || end <= start) - return start; - - if (v >= end) - return end; - - return v; - } - - /** The start of the non-normalised range. */ - ValueType start; - - /** The end of the non-normalised range. */ - ValueType end; - - /** The snapping interval that should be used (in non-normalised value). Use 0 for a continuous range. */ - ValueType interval; - - /** An optional skew factor that alters the way values are distribute across the range. - - The skew factor lets you skew the mapping logarithmically so that larger or smaller - values are given a larger proportion of the avilable space. - - A factor of 1.0 has no skewing effect at all. If the factor is < 1.0, the lower end - of the range will fill more of the slider's length; if the factor is > 1.0, the upper - end of the range will be expanded. - */ - ValueType skew; - -private: - void checkInvariants() const - { - jassert (end > start); - jassert (interval >= ValueType()); - jassert (skew > ValueType()); - } -}; - - -#endif // JUCE_NORMALISABLERANGE_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/maths/juce_Random.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/maths/juce_Random.cpp deleted file mode 100644 index a196256834..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/maths/juce_Random.cpp +++ /dev/null @@ -1,189 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -Random::Random (const int64 seedValue) noexcept : seed (seedValue) -{ -} - -Random::Random() : seed (1) -{ - setSeedRandomly(); -} - -Random::~Random() noexcept -{ -} - -void Random::setSeed (const int64 newSeed) noexcept -{ - seed = newSeed; -} - -void Random::combineSeed (const int64 seedValue) noexcept -{ - seed ^= nextInt64() ^ seedValue; -} - -void Random::setSeedRandomly() -{ - static int64 globalSeed = 0; - - combineSeed (globalSeed ^ (int64) (pointer_sized_int) this); - combineSeed (Time::getMillisecondCounter()); - combineSeed (Time::getHighResolutionTicks()); - combineSeed (Time::getHighResolutionTicksPerSecond()); - combineSeed (Time::currentTimeMillis()); - globalSeed ^= seed; -} - -Random& Random::getSystemRandom() noexcept -{ - static Random sysRand; - return sysRand; -} - -//============================================================================== -int Random::nextInt() noexcept -{ - seed = (seed * 0x5deece66dLL + 11) & 0xffffffffffffLL; - - return (int) (seed >> 16); -} - -int Random::nextInt (const int maxValue) noexcept -{ - jassert (maxValue > 0); - return (int) ((((unsigned int) nextInt()) * (uint64) maxValue) >> 32); -} - -int Random::nextInt (Range range) noexcept -{ - return range.getStart() + nextInt (range.getLength()); -} - -int64 Random::nextInt64() noexcept -{ - return (((int64) nextInt()) << 32) | (int64) (uint64) (uint32) nextInt(); -} - -bool Random::nextBool() noexcept -{ - return (nextInt() & 0x40000000) != 0; -} - -float Random::nextFloat() noexcept -{ - return static_cast (nextInt()) / (std::numeric_limits::max() + 1.0f); -} - -double Random::nextDouble() noexcept -{ - return static_cast (nextInt()) / (std::numeric_limits::max() + 1.0); -} - -BigInteger Random::nextLargeNumber (const BigInteger& maximumValue) -{ - BigInteger n; - - do - { - fillBitsRandomly (n, 0, maximumValue.getHighestBit() + 1); - } - while (n >= maximumValue); - - return n; -} - -void Random::fillBitsRandomly (void* const buffer, size_t bytes) -{ - int* d = static_cast (buffer); - - for (; bytes >= sizeof (int); bytes -= sizeof (int)) - *d++ = nextInt(); - - if (bytes > 0) - { - const int lastBytes = nextInt(); - memcpy (d, &lastBytes, bytes); - } -} - -void Random::fillBitsRandomly (BigInteger& arrayToChange, int startBit, int numBits) -{ - arrayToChange.setBit (startBit + numBits - 1, true); // to force the array to pre-allocate space - - while ((startBit & 31) != 0 && numBits > 0) - { - arrayToChange.setBit (startBit++, nextBool()); - --numBits; - } - - while (numBits >= 32) - { - arrayToChange.setBitRangeAsInt (startBit, 32, (unsigned int) nextInt()); - startBit += 32; - numBits -= 32; - } - - while (--numBits >= 0) - arrayToChange.setBit (startBit + numBits, nextBool()); -} - -//============================================================================== -#if JUCE_UNIT_TESTS - -class RandomTests : public UnitTest -{ -public: - RandomTests() : UnitTest ("Random") {} - - void runTest() - { - beginTest ("Random"); - - Random r = getRandom(); - - for (int i = 2000; --i >= 0;) - { - expect (r.nextDouble() >= 0.0 && r.nextDouble() < 1.0); - expect (r.nextFloat() >= 0.0f && r.nextFloat() < 1.0f); - expect (r.nextInt (5) >= 0 && r.nextInt (5) < 5); - expect (r.nextInt (1) == 0); - - int n = r.nextInt (50) + 1; - expect (r.nextInt (n) >= 0 && r.nextInt (n) < n); - - n = r.nextInt (0x7ffffffe) + 1; - expect (r.nextInt (n) >= 0 && r.nextInt (n) < n); - } - } -}; - -static RandomTests randomTests; - -#endif diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/maths/juce_Random.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/maths/juce_Random.h deleted file mode 100644 index 19e6d6ef8b..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/maths/juce_Random.h +++ /dev/null @@ -1,143 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_RANDOM_H_INCLUDED -#define JUCE_RANDOM_H_INCLUDED - - -//============================================================================== -/** - A random number generator. - - You can create a Random object and use it to generate a sequence of random numbers. -*/ -class JUCE_API Random -{ -public: - //============================================================================== - /** Creates a Random object based on a seed value. - - For a given seed value, the subsequent numbers generated by this object - will be predictable, so a good idea is to set this value based - on the time, e.g. - - new Random (Time::currentTimeMillis()) - */ - explicit Random (int64 seedValue) noexcept; - - /** Creates a Random object using a random seed value. - Internally, this calls setSeedRandomly() to randomise the seed. - */ - Random(); - - /** Destructor. */ - ~Random() noexcept; - - /** Returns the next random 32 bit integer. - @returns a random integer from the full range 0x80000000 to 0x7fffffff - */ - int nextInt() noexcept; - - /** Returns the next random number, limited to a given range. - The maxValue parameter may not be negative, or zero. - @returns a random integer between 0 (inclusive) and maxValue (exclusive). - */ - int nextInt (int maxValue) noexcept; - - /** Returns the next random number, limited to a given range. - @returns a random integer between the range start (inclusive) and its end (exclusive). - */ - int nextInt (Range range) noexcept; - - /** Returns the next 64-bit random number. - @returns a random integer from the full range 0x8000000000000000 to 0x7fffffffffffffff - */ - int64 nextInt64() noexcept; - - /** Returns the next random floating-point number. - @returns a random value in the range 0 to 1.0 - */ - float nextFloat() noexcept; - - /** Returns the next random floating-point number. - @returns a random value in the range 0 to 1.0 - */ - double nextDouble() noexcept; - - /** Returns the next random boolean value. */ - bool nextBool() noexcept; - - /** Returns a BigInteger containing a random number. - @returns a random value in the range 0 to (maximumValue - 1). - */ - BigInteger nextLargeNumber (const BigInteger& maximumValue); - - /** Fills a block of memory with random values. */ - void fillBitsRandomly (void* bufferToFill, size_t sizeInBytes); - - /** Sets a range of bits in a BigInteger to random values. */ - void fillBitsRandomly (BigInteger& arrayToChange, int startBit, int numBits); - - //============================================================================== - /** Resets this Random object to a given seed value. */ - void setSeed (int64 newSeed) noexcept; - - /** Returns the RNG's current seed. */ - int64 getSeed() const noexcept { return seed; } - - /** Merges this object's seed with another value. - This sets the seed to be a value created by combining the current seed and this - new value. - */ - void combineSeed (int64 seedValue) noexcept; - - /** Reseeds this generator using a value generated from various semi-random system - properties like the current time, etc. - - Because this function convolves the time with the last seed value, calling - it repeatedly will increase the randomness of the final result. - */ - void setSeedRandomly(); - - /** The overhead of creating a new Random object is fairly small, but if you want to avoid - it, you can call this method to get a global shared Random object. - - It's not thread-safe though, so threads should use their own Random object, otherwise - you run the risk of your random numbers becoming.. erm.. randomly corrupted.. - */ - static Random& getSystemRandom() noexcept; - -private: - //============================================================================== - int64 seed; - - JUCE_LEAK_DETECTOR (Random) -}; - - -#endif // JUCE_RANDOM_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/maths/juce_Range.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/maths/juce_Range.h deleted file mode 100644 index 6add152347..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/maths/juce_Range.h +++ /dev/null @@ -1,304 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_RANGE_H_INCLUDED -#define JUCE_RANGE_H_INCLUDED - - -//============================================================================== -/** A general-purpose range object, that simply represents any linear range with - a start and end point. - - Note that when checking whether values fall within the range, the start value is - considered to be inclusive, and the end of the range exclusive. - - The templated parameter is expected to be a primitive integer or floating point - type, though class types could also be used if they behave in a number-like way. -*/ -template -class Range -{ -public: - //============================================================================== - /** Constructs an empty range. */ - Range() noexcept : start(), end() - { - } - - /** Constructs a range with given start and end values. */ - Range (const ValueType startValue, const ValueType endValue) noexcept - : start (startValue), end (jmax (startValue, endValue)) - { - } - - /** Constructs a copy of another range. */ - Range (const Range& other) noexcept - : start (other.start), end (other.end) - { - } - - /** Copies another range object. */ - Range& operator= (Range other) noexcept - { - start = other.start; - end = other.end; - return *this; - } - - /** Returns the range that lies between two positions (in either order). */ - static Range between (const ValueType position1, const ValueType position2) noexcept - { - return position1 < position2 ? Range (position1, position2) - : Range (position2, position1); - } - - /** Returns a range with a given start and length. */ - static Range withStartAndLength (const ValueType startValue, const ValueType length) noexcept - { - jassert (length >= ValueType()); - return Range (startValue, startValue + length); - } - - /** Returns a range with the specified start position and a length of zero. */ - static Range emptyRange (const ValueType start) noexcept - { - return Range (start, start); - } - - //============================================================================== - /** Returns the start of the range. */ - inline ValueType getStart() const noexcept { return start; } - - /** Returns the length of the range. */ - inline ValueType getLength() const noexcept { return end - start; } - - /** Returns the end of the range. */ - inline ValueType getEnd() const noexcept { return end; } - - /** Returns true if the range has a length of zero. */ - inline bool isEmpty() const noexcept { return start == end; } - - //============================================================================== - /** Changes the start position of the range, leaving the end position unchanged. - If the new start position is higher than the current end of the range, the end point - will be pushed along to equal it, leaving an empty range at the new position. - */ - void setStart (const ValueType newStart) noexcept - { - start = newStart; - if (end < newStart) - end = newStart; - } - - /** Returns a range with the same end as this one, but a different start. - If the new start position is higher than the current end of the range, the end point - will be pushed along to equal it, returning an empty range at the new position. - */ - Range withStart (const ValueType newStart) const noexcept - { - return Range (newStart, jmax (newStart, end)); - } - - /** Returns a range with the same length as this one, but moved to have the given start position. */ - Range movedToStartAt (const ValueType newStart) const noexcept - { - return Range (newStart, end + (newStart - start)); - } - - /** Changes the end position of the range, leaving the start unchanged. - If the new end position is below the current start of the range, the start point - will be pushed back to equal the new end point. - */ - void setEnd (const ValueType newEnd) noexcept - { - end = newEnd; - if (newEnd < start) - start = newEnd; - } - - /** Returns a range with the same start position as this one, but a different end. - If the new end position is below the current start of the range, the start point - will be pushed back to equal the new end point. - */ - Range withEnd (const ValueType newEnd) const noexcept - { - return Range (jmin (start, newEnd), newEnd); - } - - /** Returns a range with the same length as this one, but moved to have the given end position. */ - Range movedToEndAt (const ValueType newEnd) const noexcept - { - return Range (start + (newEnd - end), newEnd); - } - - /** Changes the length of the range. - Lengths less than zero are treated as zero. - */ - void setLength (const ValueType newLength) noexcept - { - end = start + jmax (ValueType(), newLength); - } - - /** Returns a range with the same start as this one, but a different length. - Lengths less than zero are treated as zero. - */ - Range withLength (const ValueType newLength) const noexcept - { - return Range (start, start + newLength); - } - - //============================================================================== - /** Adds an amount to the start and end of the range. */ - inline Range operator+= (const ValueType amountToAdd) noexcept - { - start += amountToAdd; - end += amountToAdd; - return *this; - } - - /** Subtracts an amount from the start and end of the range. */ - inline Range operator-= (const ValueType amountToSubtract) noexcept - { - start -= amountToSubtract; - end -= amountToSubtract; - return *this; - } - - /** Returns a range that is equal to this one with an amount added to its - start and end. - */ - Range operator+ (const ValueType amountToAdd) const noexcept - { - return Range (start + amountToAdd, end + amountToAdd); - } - - /** Returns a range that is equal to this one with the specified amount - subtracted from its start and end. */ - Range operator- (const ValueType amountToSubtract) const noexcept - { - return Range (start - amountToSubtract, end - amountToSubtract); - } - - bool operator== (Range other) const noexcept { return start == other.start && end == other.end; } - bool operator!= (Range other) const noexcept { return start != other.start || end != other.end; } - - //============================================================================== - /** Returns true if the given position lies inside this range. */ - bool contains (const ValueType position) const noexcept - { - return start <= position && position < end; - } - - /** Returns the nearest value to the one supplied, which lies within the range. */ - ValueType clipValue (const ValueType value) const noexcept - { - return jlimit (start, end, value); - } - - /** Returns true if the given range lies entirely inside this range. - When making this comparison, the start value is considered to be inclusive, - and the end of the range exclusive. - */ - bool contains (Range other) const noexcept - { - return start <= other.start && end >= other.end; - } - - /** Returns true if the given range intersects this one. */ - bool intersects (Range other) const noexcept - { - return other.start < end && start < other.end; - } - - /** Returns the range that is the intersection of the two ranges, or an empty range - with an undefined start position if they don't overlap. */ - Range getIntersectionWith (Range other) const noexcept - { - return Range (jmax (start, other.start), - jmin (end, other.end)); - } - - /** Returns the smallest range that contains both this one and the other one. */ - Range getUnionWith (Range other) const noexcept - { - return Range (jmin (start, other.start), - jmax (end, other.end)); - } - - /** Returns the smallest range that contains both this one and the given value. */ - Range getUnionWith (const ValueType valueToInclude) const noexcept - { - return Range (jmin (valueToInclude, start), - jmax (valueToInclude, end)); - } - - /** Returns a given range, after moving it forwards or backwards to fit it - within this range. - - If the supplied range has a greater length than this one, the return value - will be this range. - - Otherwise, if the supplied range is smaller than this one, the return value - will be the new range, shifted forwards or backwards so that it doesn't extend - beyond this one, but keeping its original length. - */ - Range constrainRange (Range rangeToConstrain) const noexcept - { - const ValueType otherLen = rangeToConstrain.getLength(); - return getLength() <= otherLen - ? *this - : rangeToConstrain.movedToStartAt (jlimit (start, end - otherLen, rangeToConstrain.getStart())); - } - - /** Scans an array of values for its min and max, and returns these as a Range. */ - static Range findMinAndMax (const ValueType* values, int numValues) noexcept - { - if (numValues <= 0) - return Range(); - - const ValueType first (*values++); - Range r (first, first); - - while (--numValues > 0) // (> 0 rather than >= 0 because we've already taken the first sample) - { - const ValueType v (*values++); - - if (r.end < v) r.end = v; - if (v < r.start) r.start = v; - } - - return r; - } - -private: - //============================================================================== - ValueType start, end; -}; - - -#endif // JUCE_RANGE_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/memory/juce_Atomic.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/memory/juce_Atomic.h deleted file mode 100644 index 5e9d30c13d..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/memory/juce_Atomic.h +++ /dev/null @@ -1,399 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_ATOMIC_H_INCLUDED -#define JUCE_ATOMIC_H_INCLUDED - - -//============================================================================== -/** - Simple class to hold a primitive value and perform atomic operations on it. - - The type used must be a 32 or 64 bit primitive, like an int, pointer, etc. - There are methods to perform most of the basic atomic operations. -*/ -template -class Atomic -{ -public: - /** Creates a new value, initialised to zero. */ - inline Atomic() noexcept - : value (0) - { - } - - /** Creates a new value, with a given initial value. */ - inline explicit Atomic (const Type initialValue) noexcept - : value (initialValue) - { - } - - /** Copies another value (atomically). */ - inline Atomic (const Atomic& other) noexcept - : value (other.get()) - { - } - - /** Destructor. */ - inline ~Atomic() noexcept - { - // This class can only be used for types which are 32 or 64 bits in size. - static_jassert (sizeof (Type) == 4 || sizeof (Type) == 8); - } - - /** Atomically reads and returns the current value. */ - Type get() const noexcept; - - /** Copies another value onto this one (atomically). */ - inline Atomic& operator= (const Atomic& other) noexcept { exchange (other.get()); return *this; } - - /** Copies another value onto this one (atomically). */ - inline Atomic& operator= (const Type newValue) noexcept { exchange (newValue); return *this; } - - /** Atomically sets the current value. */ - void set (Type newValue) noexcept { exchange (newValue); } - - /** Atomically sets the current value, returning the value that was replaced. */ - Type exchange (Type value) noexcept; - - /** Atomically adds a number to this value, returning the new value. */ - Type operator+= (Type amountToAdd) noexcept; - - /** Atomically subtracts a number from this value, returning the new value. */ - Type operator-= (Type amountToSubtract) noexcept; - - /** Atomically increments this value, returning the new value. */ - Type operator++() noexcept; - - /** Atomically decrements this value, returning the new value. */ - Type operator--() noexcept; - - /** Atomically compares this value with a target value, and if it is equal, sets - this to be equal to a new value. - - This operation is the atomic equivalent of doing this: - @code - bool compareAndSetBool (Type newValue, Type valueToCompare) - { - if (get() == valueToCompare) - { - set (newValue); - return true; - } - - return false; - } - @endcode - - @returns true if the comparison was true and the value was replaced; false if - the comparison failed and the value was left unchanged. - @see compareAndSetValue - */ - bool compareAndSetBool (Type newValue, Type valueToCompare) noexcept; - - /** Atomically compares this value with a target value, and if it is equal, sets - this to be equal to a new value. - - This operation is the atomic equivalent of doing this: - @code - Type compareAndSetValue (Type newValue, Type valueToCompare) - { - Type oldValue = get(); - if (oldValue == valueToCompare) - set (newValue); - - return oldValue; - } - @endcode - - @returns the old value before it was changed. - @see compareAndSetBool - */ - Type compareAndSetValue (Type newValue, Type valueToCompare) noexcept; - - /** Implements a memory read/write barrier. */ - static void memoryBarrier() noexcept; - - //============================================================================== - #if JUCE_64BIT - JUCE_ALIGN (8) - #else - JUCE_ALIGN (4) - #endif - - /** The raw value that this class operates on. - This is exposed publically in case you need to manipulate it directly - for performance reasons. - */ - volatile Type value; - -private: - template - static inline Dest castTo (Source value) noexcept { union { Dest d; Source s; } u; u.s = value; return u.d; } - - static inline Type castFrom32Bit (int32 value) noexcept { return castTo (value); } - static inline Type castFrom64Bit (int64 value) noexcept { return castTo (value); } - static inline int32 castTo32Bit (Type value) noexcept { return castTo (value); } - static inline int64 castTo64Bit (Type value) noexcept { return castTo (value); } - - Type operator++ (int); // better to just use pre-increment with atomics.. - Type operator-- (int); - - /** This templated negate function will negate pointers as well as integers */ - template - inline ValueType negateValue (ValueType n) noexcept - { - return sizeof (ValueType) == 1 ? (ValueType) -(signed char) n - : (sizeof (ValueType) == 2 ? (ValueType) -(short) n - : (sizeof (ValueType) == 4 ? (ValueType) -(int) n - : ((ValueType) -(int64) n))); - } - - /** This templated negate function will negate pointers as well as integers */ - template - inline PointerType* negateValue (PointerType* n) noexcept - { - return reinterpret_cast (-reinterpret_cast (n)); - } -}; - - -//============================================================================== -/* - The following code is in the header so that the atomics can be inlined where possible... -*/ -#if JUCE_MAC && (JUCE_PPC || __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 2)) - #define JUCE_ATOMICS_MAC_LEGACY 1 // Older OSX builds using gcc4.1 or earlier - - #if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5 - #define JUCE_MAC_ATOMICS_VOLATILE - #else - #define JUCE_MAC_ATOMICS_VOLATILE volatile - #endif - - #if JUCE_PPC - // None of these atomics are available for PPC or for iOS 3.1 or earlier!! - template static Type OSAtomicAdd64Barrier (Type b, JUCE_MAC_ATOMICS_VOLATILE Type* a) noexcept { jassertfalse; return *a += b; } - template static Type OSAtomicIncrement64Barrier (JUCE_MAC_ATOMICS_VOLATILE Type* a) noexcept { jassertfalse; return ++*a; } - template static Type OSAtomicDecrement64Barrier (JUCE_MAC_ATOMICS_VOLATILE Type* a) noexcept { jassertfalse; return --*a; } - template static bool OSAtomicCompareAndSwap64Barrier (Type old, Type newValue, JUCE_MAC_ATOMICS_VOLATILE Type* value) noexcept - { jassertfalse; if (old == *value) { *value = newValue; return true; } return false; } - #define JUCE_64BIT_ATOMICS_UNAVAILABLE 1 - #endif - -//============================================================================== -#elif JUCE_GCC || JUCE_CLANG - #define JUCE_ATOMICS_GCC 1 // GCC with intrinsics - - #if JUCE_IOS || JUCE_ANDROID // (64-bit ops will compile but not link on these mobile OSes) - #define JUCE_64BIT_ATOMICS_UNAVAILABLE 1 - #endif - -//============================================================================== -#else - #define JUCE_ATOMICS_WINDOWS 1 // Windows with intrinsics - - #if JUCE_USE_MSVC_INTRINSICS - #ifndef __INTEL_COMPILER - #pragma intrinsic (_InterlockedExchange, _InterlockedIncrement, _InterlockedDecrement, _InterlockedCompareExchange, \ - _InterlockedCompareExchange64, _InterlockedExchangeAdd, _ReadWriteBarrier) - #endif - #define juce_InterlockedExchange(a, b) _InterlockedExchange(a, b) - #define juce_InterlockedIncrement(a) _InterlockedIncrement(a) - #define juce_InterlockedDecrement(a) _InterlockedDecrement(a) - #define juce_InterlockedExchangeAdd(a, b) _InterlockedExchangeAdd(a, b) - #define juce_InterlockedCompareExchange(a, b, c) _InterlockedCompareExchange(a, b, c) - #define juce_InterlockedCompareExchange64(a, b, c) _InterlockedCompareExchange64(a, b, c) - #define juce_MemoryBarrier _ReadWriteBarrier - #else - long juce_InterlockedExchange (volatile long* a, long b) noexcept; - long juce_InterlockedIncrement (volatile long* a) noexcept; - long juce_InterlockedDecrement (volatile long* a) noexcept; - long juce_InterlockedExchangeAdd (volatile long* a, long b) noexcept; - long juce_InterlockedCompareExchange (volatile long* a, long b, long c) noexcept; - __int64 juce_InterlockedCompareExchange64 (volatile __int64* a, __int64 b, __int64 c) noexcept; - inline void juce_MemoryBarrier() noexcept { long x = 0; juce_InterlockedIncrement (&x); } - #endif - - #if JUCE_64BIT - #ifndef __INTEL_COMPILER - #pragma intrinsic (_InterlockedExchangeAdd64, _InterlockedExchange64, _InterlockedIncrement64, _InterlockedDecrement64) - #endif - #define juce_InterlockedExchangeAdd64(a, b) _InterlockedExchangeAdd64(a, b) - #define juce_InterlockedExchange64(a, b) _InterlockedExchange64(a, b) - #define juce_InterlockedIncrement64(a) _InterlockedIncrement64(a) - #define juce_InterlockedDecrement64(a) _InterlockedDecrement64(a) - #else - // None of these atomics are available in a 32-bit Windows build!! - template static Type juce_InterlockedExchangeAdd64 (volatile Type* a, Type b) noexcept { jassertfalse; Type old = *a; *a += b; return old; } - template static Type juce_InterlockedExchange64 (volatile Type* a, Type b) noexcept { jassertfalse; Type old = *a; *a = b; return old; } - template static Type juce_InterlockedIncrement64 (volatile Type* a) noexcept { jassertfalse; return ++*a; } - template static Type juce_InterlockedDecrement64 (volatile Type* a) noexcept { jassertfalse; return --*a; } - #define JUCE_64BIT_ATOMICS_UNAVAILABLE 1 - #endif -#endif - - -#if JUCE_MSVC - #pragma warning (push) - #pragma warning (disable: 4311) // (truncation warning) -#endif - -//============================================================================== -template -inline Type Atomic::get() const noexcept -{ - #if JUCE_ATOMICS_MAC_LEGACY - return sizeof (Type) == 4 ? castFrom32Bit ((int32) OSAtomicAdd32Barrier ((int32_t) 0, (JUCE_MAC_ATOMICS_VOLATILE int32_t*) &value)) - : castFrom64Bit ((int64) OSAtomicAdd64Barrier ((int64_t) 0, (JUCE_MAC_ATOMICS_VOLATILE int64_t*) &value)); - #elif JUCE_ATOMICS_WINDOWS - return sizeof (Type) == 4 ? castFrom32Bit ((int32) juce_InterlockedExchangeAdd ((volatile long*) &value, (long) 0)) - : castFrom64Bit ((int64) juce_InterlockedExchangeAdd64 ((volatile __int64*) &value, (__int64) 0)); - #elif JUCE_ATOMICS_GCC - return sizeof (Type) == 4 ? castFrom32Bit ((int32) __sync_add_and_fetch ((volatile int32*) &value, 0)) - : castFrom64Bit ((int64) __sync_add_and_fetch ((volatile int64*) &value, 0)); - #endif -} - -template -inline Type Atomic::exchange (const Type newValue) noexcept -{ - #if JUCE_ATOMICS_MAC_LEGACY || JUCE_ATOMICS_GCC - Type currentVal = value; - while (! compareAndSetBool (newValue, currentVal)) { currentVal = value; } - return currentVal; - #elif JUCE_ATOMICS_WINDOWS - return sizeof (Type) == 4 ? castFrom32Bit ((int32) juce_InterlockedExchange ((volatile long*) &value, (long) castTo32Bit (newValue))) - : castFrom64Bit ((int64) juce_InterlockedExchange64 ((volatile __int64*) &value, (__int64) castTo64Bit (newValue))); - #endif -} - -template -inline Type Atomic::operator+= (const Type amountToAdd) noexcept -{ - #if JUCE_ATOMICS_MAC_LEGACY - return sizeof (Type) == 4 ? (Type) OSAtomicAdd32Barrier ((int32_t) castTo32Bit (amountToAdd), (JUCE_MAC_ATOMICS_VOLATILE int32_t*) &value) - : (Type) OSAtomicAdd64Barrier ((int64_t) amountToAdd, (JUCE_MAC_ATOMICS_VOLATILE int64_t*) &value); - #elif JUCE_ATOMICS_WINDOWS - return sizeof (Type) == 4 ? (Type) (juce_InterlockedExchangeAdd ((volatile long*) &value, (long) amountToAdd) + (long) amountToAdd) - : (Type) (juce_InterlockedExchangeAdd64 ((volatile __int64*) &value, (__int64) amountToAdd) + (__int64) amountToAdd); - #elif JUCE_ATOMICS_GCC - return (Type) __sync_add_and_fetch (&value, amountToAdd); - #endif -} - -template -inline Type Atomic::operator-= (const Type amountToSubtract) noexcept -{ - return operator+= (negateValue (amountToSubtract)); -} - -template -inline Type Atomic::operator++() noexcept -{ - #if JUCE_ATOMICS_MAC_LEGACY - return sizeof (Type) == 4 ? (Type) OSAtomicIncrement32Barrier ((JUCE_MAC_ATOMICS_VOLATILE int32_t*) &value) - : (Type) OSAtomicIncrement64Barrier ((JUCE_MAC_ATOMICS_VOLATILE int64_t*) &value); - #elif JUCE_ATOMICS_WINDOWS - return sizeof (Type) == 4 ? (Type) juce_InterlockedIncrement ((volatile long*) &value) - : (Type) juce_InterlockedIncrement64 ((volatile __int64*) &value); - #elif JUCE_ATOMICS_GCC - return sizeof (Type) == 4 ? (Type) __sync_add_and_fetch (&value, (Type) 1) - : (Type) __sync_add_and_fetch ((int64_t*) &value, 1); - #endif -} - -template -inline Type Atomic::operator--() noexcept -{ - #if JUCE_ATOMICS_MAC_LEGACY - return sizeof (Type) == 4 ? (Type) OSAtomicDecrement32Barrier ((JUCE_MAC_ATOMICS_VOLATILE int32_t*) &value) - : (Type) OSAtomicDecrement64Barrier ((JUCE_MAC_ATOMICS_VOLATILE int64_t*) &value); - #elif JUCE_ATOMICS_WINDOWS - return sizeof (Type) == 4 ? (Type) juce_InterlockedDecrement ((volatile long*) &value) - : (Type) juce_InterlockedDecrement64 ((volatile __int64*) &value); - #elif JUCE_ATOMICS_GCC - return sizeof (Type) == 4 ? (Type) __sync_add_and_fetch (&value, (Type) -1) - : (Type) __sync_add_and_fetch ((int64_t*) &value, -1); - #endif -} - -template -inline bool Atomic::compareAndSetBool (const Type newValue, const Type valueToCompare) noexcept -{ - #if JUCE_ATOMICS_MAC_LEGACY - return sizeof (Type) == 4 ? OSAtomicCompareAndSwap32Barrier ((int32_t) castTo32Bit (valueToCompare), (int32_t) castTo32Bit (newValue), (JUCE_MAC_ATOMICS_VOLATILE int32_t*) &value) - : OSAtomicCompareAndSwap64Barrier ((int64_t) castTo64Bit (valueToCompare), (int64_t) castTo64Bit (newValue), (JUCE_MAC_ATOMICS_VOLATILE int64_t*) &value); - #elif JUCE_ATOMICS_WINDOWS - return compareAndSetValue (newValue, valueToCompare) == valueToCompare; - #elif JUCE_ATOMICS_GCC - return sizeof (Type) == 4 ? __sync_bool_compare_and_swap ((volatile int32*) &value, castTo32Bit (valueToCompare), castTo32Bit (newValue)) - : __sync_bool_compare_and_swap ((volatile int64*) &value, castTo64Bit (valueToCompare), castTo64Bit (newValue)); - #endif -} - -template -inline Type Atomic::compareAndSetValue (const Type newValue, const Type valueToCompare) noexcept -{ - #if JUCE_ATOMICS_MAC_LEGACY - for (;;) // Annoying workaround for only having a bool CAS operation.. - { - if (compareAndSetBool (newValue, valueToCompare)) - return valueToCompare; - - const Type result = value; - if (result != valueToCompare) - return result; - } - - #elif JUCE_ATOMICS_WINDOWS - return sizeof (Type) == 4 ? castFrom32Bit ((int32) juce_InterlockedCompareExchange ((volatile long*) &value, (long) castTo32Bit (newValue), (long) castTo32Bit (valueToCompare))) - : castFrom64Bit ((int64) juce_InterlockedCompareExchange64 ((volatile __int64*) &value, (__int64) castTo64Bit (newValue), (__int64) castTo64Bit (valueToCompare))); - #elif JUCE_ATOMICS_GCC - return sizeof (Type) == 4 ? castFrom32Bit ((int32) __sync_val_compare_and_swap ((volatile int32*) &value, castTo32Bit (valueToCompare), castTo32Bit (newValue))) - : castFrom64Bit ((int64) __sync_val_compare_and_swap ((volatile int64*) &value, castTo64Bit (valueToCompare), castTo64Bit (newValue))); - #endif -} - -template -inline void Atomic::memoryBarrier() noexcept -{ - #if JUCE_ATOMICS_MAC_LEGACY - OSMemoryBarrier(); - #elif JUCE_ATOMICS_GCC - __sync_synchronize(); - #elif JUCE_ATOMICS_WINDOWS - juce_MemoryBarrier(); - #endif -} - -#if JUCE_MSVC - #pragma warning (pop) -#endif - -#endif // JUCE_ATOMIC_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/memory/juce_ByteOrder.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/memory/juce_ByteOrder.h deleted file mode 100644 index fcd56bce25..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/memory/juce_ByteOrder.h +++ /dev/null @@ -1,196 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_BYTEORDER_H_INCLUDED -#define JUCE_BYTEORDER_H_INCLUDED - - -//============================================================================== -/** Contains static methods for converting the byte order between different - endiannesses. -*/ -class JUCE_API ByteOrder -{ -public: - //============================================================================== - /** Swaps the upper and lower bytes of a 16-bit integer. */ - static uint16 swap (uint16 value) noexcept; - - /** Reverses the order of the 4 bytes in a 32-bit integer. */ - static uint32 swap (uint32 value) noexcept; - - /** Reverses the order of the 8 bytes in a 64-bit integer. */ - static uint64 swap (uint64 value) noexcept; - - //============================================================================== - /** Swaps the byte order of a 16-bit int if the CPU is big-endian */ - static uint16 swapIfBigEndian (uint16 value) noexcept; - - /** Swaps the byte order of a 32-bit int if the CPU is big-endian */ - static uint32 swapIfBigEndian (uint32 value) noexcept; - - /** Swaps the byte order of a 64-bit int if the CPU is big-endian */ - static uint64 swapIfBigEndian (uint64 value) noexcept; - - /** Swaps the byte order of a 16-bit int if the CPU is little-endian */ - static uint16 swapIfLittleEndian (uint16 value) noexcept; - - /** Swaps the byte order of a 32-bit int if the CPU is little-endian */ - static uint32 swapIfLittleEndian (uint32 value) noexcept; - - /** Swaps the byte order of a 64-bit int if the CPU is little-endian */ - static uint64 swapIfLittleEndian (uint64 value) noexcept; - - //============================================================================== - /** Turns 4 bytes into a little-endian integer. */ - static uint32 littleEndianInt (const void* bytes) noexcept; - - /** Turns 8 bytes into a little-endian integer. */ - static uint64 littleEndianInt64 (const void* bytes) noexcept; - - /** Turns 2 bytes into a little-endian integer. */ - static uint16 littleEndianShort (const void* bytes) noexcept; - - /** Turns 4 bytes into a big-endian integer. */ - static uint32 bigEndianInt (const void* bytes) noexcept; - - /** Turns 8 bytes into a big-endian integer. */ - static uint64 bigEndianInt64 (const void* bytes) noexcept; - - /** Turns 2 bytes into a big-endian integer. */ - static uint16 bigEndianShort (const void* bytes) noexcept; - - //============================================================================== - /** Converts 3 little-endian bytes into a signed 24-bit value (which is sign-extended to 32 bits). */ - static int littleEndian24Bit (const void* bytes) noexcept; - - /** Converts 3 big-endian bytes into a signed 24-bit value (which is sign-extended to 32 bits). */ - static int bigEndian24Bit (const void* bytes) noexcept; - - /** Copies a 24-bit number to 3 little-endian bytes. */ - static void littleEndian24BitToChars (int value, void* destBytes) noexcept; - - /** Copies a 24-bit number to 3 big-endian bytes. */ - static void bigEndian24BitToChars (int value, void* destBytes) noexcept; - - //============================================================================== - /** Returns true if the current CPU is big-endian. */ - static bool isBigEndian() noexcept; - -private: - ByteOrder() JUCE_DELETED_FUNCTION; - - JUCE_DECLARE_NON_COPYABLE (ByteOrder) -}; - - -//============================================================================== -#if JUCE_USE_MSVC_INTRINSICS && ! defined (__INTEL_COMPILER) - #pragma intrinsic (_byteswap_ulong) -#endif - -inline uint16 ByteOrder::swap (uint16 n) noexcept -{ - #if JUCE_USE_MSVC_INTRINSICSxxx // agh - the MS compiler has an internal error when you try to use this intrinsic! - return static_cast (_byteswap_ushort (n)); - #else - return static_cast ((n << 8) | (n >> 8)); - #endif -} - -inline uint32 ByteOrder::swap (uint32 n) noexcept -{ - #if JUCE_MAC || JUCE_IOS - return OSSwapInt32 (n); - #elif JUCE_GCC && JUCE_INTEL && ! JUCE_NO_INLINE_ASM - asm("bswap %%eax" : "=a"(n) : "a"(n)); - return n; - #elif JUCE_USE_MSVC_INTRINSICS - return _byteswap_ulong (n); - #elif JUCE_MSVC && ! JUCE_NO_INLINE_ASM - __asm { - mov eax, n - bswap eax - mov n, eax - } - return n; - #elif JUCE_ANDROID - return bswap_32 (n); - #else - return (n << 24) | (n >> 24) | ((n & 0xff00) << 8) | ((n & 0xff0000) >> 8); - #endif -} - -inline uint64 ByteOrder::swap (uint64 value) noexcept -{ - #if JUCE_MAC || JUCE_IOS - return OSSwapInt64 (value); - #elif JUCE_USE_MSVC_INTRINSICS - return _byteswap_uint64 (value); - #else - return (((int64) swap ((uint32) value)) << 32) | swap ((uint32) (value >> 32)); - #endif -} - -#if JUCE_LITTLE_ENDIAN - inline uint16 ByteOrder::swapIfBigEndian (const uint16 v) noexcept { return v; } - inline uint32 ByteOrder::swapIfBigEndian (const uint32 v) noexcept { return v; } - inline uint64 ByteOrder::swapIfBigEndian (const uint64 v) noexcept { return v; } - inline uint16 ByteOrder::swapIfLittleEndian (const uint16 v) noexcept { return swap (v); } - inline uint32 ByteOrder::swapIfLittleEndian (const uint32 v) noexcept { return swap (v); } - inline uint64 ByteOrder::swapIfLittleEndian (const uint64 v) noexcept { return swap (v); } - inline uint32 ByteOrder::littleEndianInt (const void* const bytes) noexcept { return *static_cast (bytes); } - inline uint64 ByteOrder::littleEndianInt64 (const void* const bytes) noexcept { return *static_cast (bytes); } - inline uint16 ByteOrder::littleEndianShort (const void* const bytes) noexcept { return *static_cast (bytes); } - inline uint32 ByteOrder::bigEndianInt (const void* const bytes) noexcept { return swap (*static_cast (bytes)); } - inline uint64 ByteOrder::bigEndianInt64 (const void* const bytes) noexcept { return swap (*static_cast (bytes)); } - inline uint16 ByteOrder::bigEndianShort (const void* const bytes) noexcept { return swap (*static_cast (bytes)); } - inline bool ByteOrder::isBigEndian() noexcept { return false; } -#else - inline uint16 ByteOrder::swapIfBigEndian (const uint16 v) noexcept { return swap (v); } - inline uint32 ByteOrder::swapIfBigEndian (const uint32 v) noexcept { return swap (v); } - inline uint64 ByteOrder::swapIfBigEndian (const uint64 v) noexcept { return swap (v); } - inline uint16 ByteOrder::swapIfLittleEndian (const uint16 v) noexcept { return v; } - inline uint32 ByteOrder::swapIfLittleEndian (const uint32 v) noexcept { return v; } - inline uint64 ByteOrder::swapIfLittleEndian (const uint64 v) noexcept { return v; } - inline uint32 ByteOrder::littleEndianInt (const void* const bytes) noexcept { return swap (*static_cast (bytes)); } - inline uint64 ByteOrder::littleEndianInt64 (const void* const bytes) noexcept { return swap (*static_cast (bytes)); } - inline uint16 ByteOrder::littleEndianShort (const void* const bytes) noexcept { return swap (*static_cast (bytes)); } - inline uint32 ByteOrder::bigEndianInt (const void* const bytes) noexcept { return *static_cast (bytes); } - inline uint64 ByteOrder::bigEndianInt64 (const void* const bytes) noexcept { return *static_cast (bytes); } - inline uint16 ByteOrder::bigEndianShort (const void* const bytes) noexcept { return *static_cast (bytes); } - inline bool ByteOrder::isBigEndian() noexcept { return true; } -#endif - -inline int ByteOrder::littleEndian24Bit (const void* const bytes) noexcept { return (((int) static_cast (bytes)[2]) << 16) | (((int) static_cast (bytes)[1]) << 8) | ((int) static_cast (bytes)[0]); } -inline int ByteOrder::bigEndian24Bit (const void* const bytes) noexcept { return (((int) static_cast (bytes)[0]) << 16) | (((int) static_cast (bytes)[1]) << 8) | ((int) static_cast (bytes)[2]); } -inline void ByteOrder::littleEndian24BitToChars (const int value, void* const destBytes) noexcept { static_cast (destBytes)[0] = (uint8) value; static_cast (destBytes)[1] = (uint8) (value >> 8); static_cast (destBytes)[2] = (uint8) (value >> 16); } -inline void ByteOrder::bigEndian24BitToChars (const int value, void* const destBytes) noexcept { static_cast (destBytes)[0] = (uint8) (value >> 16); static_cast (destBytes)[1] = (uint8) (value >> 8); static_cast (destBytes)[2] = (uint8) value; } - - -#endif // JUCE_BYTEORDER_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/memory/juce_ContainerDeletePolicy.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/memory/juce_ContainerDeletePolicy.h deleted file mode 100644 index 60cddaa75c..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/memory/juce_ContainerDeletePolicy.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_CONTAINERDELETEPOLICY_H_INCLUDED -#define JUCE_CONTAINERDELETEPOLICY_H_INCLUDED - -//============================================================================== -/** - Used by container classes as an indirect way to delete an object of a - particular type. - - The generic implementation of this class simply calls 'delete', but you can - create a specialised version of it for a particular class if you need to - delete that type of object in a more appropriate way. - - @see ScopedPointer, OwnedArray -*/ -template -struct ContainerDeletePolicy -{ - static void destroy (ObjectType* object) - { - delete object; - } -}; - - -#endif // JUCE_CONTAINERDELETEPOLICY_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/memory/juce_HeapBlock.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/memory/juce_HeapBlock.h deleted file mode 100644 index 3731f0b302..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/memory/juce_HeapBlock.h +++ /dev/null @@ -1,308 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_HEAPBLOCK_H_INCLUDED -#define JUCE_HEAPBLOCK_H_INCLUDED - -#ifndef DOXYGEN -namespace HeapBlockHelper -{ - template - struct ThrowOnFail { static void check (void*) {} }; - - template<> - struct ThrowOnFail { static void check (void* data) { if (data == nullptr) throw std::bad_alloc(); } }; -} -#endif - -//============================================================================== -/** - Very simple container class to hold a pointer to some data on the heap. - - When you need to allocate some heap storage for something, always try to use - this class instead of allocating the memory directly using malloc/free. - - A HeapBlock object can be treated in pretty much exactly the same way - as an char*, but as long as you allocate it on the stack or as a class member, - it's almost impossible for it to leak memory. - - It also makes your code much more concise and readable than doing the same thing - using direct allocations, - - E.g. instead of this: - @code - int* temp = (int*) malloc (1024 * sizeof (int)); - memcpy (temp, xyz, 1024 * sizeof (int)); - free (temp); - temp = (int*) calloc (2048 * sizeof (int)); - temp[0] = 1234; - memcpy (foobar, temp, 2048 * sizeof (int)); - free (temp); - @endcode - - ..you could just write this: - @code - HeapBlock temp (1024); - memcpy (temp, xyz, 1024 * sizeof (int)); - temp.calloc (2048); - temp[0] = 1234; - memcpy (foobar, temp, 2048 * sizeof (int)); - @endcode - - The class is extremely lightweight, containing only a pointer to the - data, and exposes malloc/realloc/calloc/free methods that do the same jobs - as their less object-oriented counterparts. Despite adding safety, you probably - won't sacrifice any performance by using this in place of normal pointers. - - The throwOnFailure template parameter can be set to true if you'd like the class - to throw a std::bad_alloc exception when an allocation fails. If this is false, - then a failed allocation will just leave the heapblock with a null pointer (assuming - that the system's malloc() function doesn't throw). - - @see Array, OwnedArray, MemoryBlock -*/ -template -class HeapBlock -{ -public: - //============================================================================== - /** Creates a HeapBlock which is initially just a null pointer. - - After creation, you can resize the array using the malloc(), calloc(), - or realloc() methods. - */ - HeapBlock() noexcept : data (nullptr) - { - } - - /** Creates a HeapBlock containing a number of elements. - - The contents of the block are undefined, as it will have been created by a - malloc call. - - If you want an array of zero values, you can use the calloc() method or the - other constructor that takes an InitialisationState parameter. - */ - explicit HeapBlock (const size_t numElements) - : data (static_cast (std::malloc (numElements * sizeof (ElementType)))) - { - throwOnAllocationFailure(); - } - - /** Creates a HeapBlock containing a number of elements. - - The initialiseToZero parameter determines whether the new memory should be cleared, - or left uninitialised. - */ - HeapBlock (const size_t numElements, const bool initialiseToZero) - : data (static_cast (initialiseToZero - ? std::calloc (numElements, sizeof (ElementType)) - : std::malloc (numElements * sizeof (ElementType)))) - { - throwOnAllocationFailure(); - } - - /** Destructor. - This will free the data, if any has been allocated. - */ - ~HeapBlock() - { - std::free (data); - } - - #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS - HeapBlock (HeapBlock&& other) noexcept - : data (other.data) - { - other.data = nullptr; - } - - HeapBlock& operator= (HeapBlock&& other) noexcept - { - std::swap (data, other.data); - return *this; - } - #endif - - //============================================================================== - /** Returns a raw pointer to the allocated data. - This may be a null pointer if the data hasn't yet been allocated, or if it has been - freed by calling the free() method. - */ - inline operator ElementType*() const noexcept { return data; } - - /** Returns a raw pointer to the allocated data. - This may be a null pointer if the data hasn't yet been allocated, or if it has been - freed by calling the free() method. - */ - inline ElementType* getData() const noexcept { return data; } - - /** Returns a void pointer to the allocated data. - This may be a null pointer if the data hasn't yet been allocated, or if it has been - freed by calling the free() method. - */ - inline operator void*() const noexcept { return static_cast (data); } - - /** Returns a void pointer to the allocated data. - This may be a null pointer if the data hasn't yet been allocated, or if it has been - freed by calling the free() method. - */ - inline operator const void*() const noexcept { return static_cast (data); } - - /** Lets you use indirect calls to the first element in the array. - Obviously this will cause problems if the array hasn't been initialised, because it'll - be referencing a null pointer. - */ - inline ElementType* operator->() const noexcept { return data; } - - /** Returns a reference to one of the data elements. - Obviously there's no bounds-checking here, as this object is just a dumb pointer and - has no idea of the size it currently has allocated. - */ - template - inline ElementType& operator[] (IndexType index) const noexcept { return data [index]; } - - /** Returns a pointer to a data element at an offset from the start of the array. - This is the same as doing pointer arithmetic on the raw pointer itself. - */ - template - inline ElementType* operator+ (IndexType index) const noexcept { return data + index; } - - //============================================================================== - /** Compares the pointer with another pointer. - This can be handy for checking whether this is a null pointer. - */ - inline bool operator== (const ElementType* const otherPointer) const noexcept { return otherPointer == data; } - - /** Compares the pointer with another pointer. - This can be handy for checking whether this is a null pointer. - */ - inline bool operator!= (const ElementType* const otherPointer) const noexcept { return otherPointer != data; } - - //============================================================================== - /** Allocates a specified amount of memory. - - This uses the normal malloc to allocate an amount of memory for this object. - Any previously allocated memory will be freed by this method. - - The number of bytes allocated will be (newNumElements * elementSize). Normally - you wouldn't need to specify the second parameter, but it can be handy if you need - to allocate a size in bytes rather than in terms of the number of elements. - - The data that is allocated will be freed when this object is deleted, or when you - call free() or any of the allocation methods. - */ - void malloc (const size_t newNumElements, const size_t elementSize = sizeof (ElementType)) - { - std::free (data); - data = static_cast (std::malloc (newNumElements * elementSize)); - throwOnAllocationFailure(); - } - - /** Allocates a specified amount of memory and clears it. - This does the same job as the malloc() method, but clears the memory that it allocates. - */ - void calloc (const size_t newNumElements, const size_t elementSize = sizeof (ElementType)) - { - std::free (data); - data = static_cast (std::calloc (newNumElements, elementSize)); - throwOnAllocationFailure(); - } - - /** Allocates a specified amount of memory and optionally clears it. - This does the same job as either malloc() or calloc(), depending on the - initialiseToZero parameter. - */ - void allocate (const size_t newNumElements, bool initialiseToZero) - { - std::free (data); - data = static_cast (initialiseToZero - ? std::calloc (newNumElements, sizeof (ElementType)) - : std::malloc (newNumElements * sizeof (ElementType))); - throwOnAllocationFailure(); - } - - /** Re-allocates a specified amount of memory. - - The semantics of this method are the same as malloc() and calloc(), but it - uses realloc() to keep as much of the existing data as possible. - */ - void realloc (const size_t newNumElements, const size_t elementSize = sizeof (ElementType)) - { - data = static_cast (data == nullptr ? std::malloc (newNumElements * elementSize) - : std::realloc (data, newNumElements * elementSize)); - throwOnAllocationFailure(); - } - - /** Frees any currently-allocated data. - This will free the data and reset this object to be a null pointer. - */ - void free() - { - std::free (data); - data = nullptr; - } - - /** Swaps this object's data with the data of another HeapBlock. - The two objects simply exchange their data pointers. - */ - template - void swapWith (HeapBlock & other) noexcept - { - std::swap (data, other.data); - } - - /** This fills the block with zeros, up to the number of elements specified. - Since the block has no way of knowing its own size, you must make sure that the number of - elements you specify doesn't exceed the allocated size. - */ - void clear (size_t numElements) noexcept - { - zeromem (data, sizeof (ElementType) * numElements); - } - - /** This typedef can be used to get the type of the heapblock's elements. */ - typedef ElementType Type; - -private: - //============================================================================== - ElementType* data; - - void throwOnAllocationFailure() const - { - HeapBlockHelper::ThrowOnFail::check (data); - } - - #if ! (defined (JUCE_DLL) || defined (JUCE_DLL_BUILD)) - JUCE_DECLARE_NON_COPYABLE (HeapBlock) - JUCE_PREVENT_HEAP_ALLOCATION // Creating a 'new HeapBlock' would be missing the point! - #endif -}; - - -#endif // JUCE_HEAPBLOCK_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/memory/juce_LeakedObjectDetector.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/memory/juce_LeakedObjectDetector.h deleted file mode 100644 index 248e7bcfbd..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/memory/juce_LeakedObjectDetector.h +++ /dev/null @@ -1,146 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_LEAKEDOBJECTDETECTOR_H_INCLUDED -#define JUCE_LEAKEDOBJECTDETECTOR_H_INCLUDED - - -//============================================================================== -/** - Embedding an instance of this class inside another class can be used as a low-overhead - way of detecting leaked instances. - - This class keeps an internal static count of the number of instances that are - active, so that when the app is shutdown and the static destructors are called, - it can check whether there are any left-over instances that may have been leaked. - - To use it, use the JUCE_LEAK_DETECTOR macro as a simple way to put one in your - class declaration. Have a look through the juce codebase for examples, it's used - in most of the classes. -*/ -template -class LeakedObjectDetector -{ -public: - //============================================================================== - LeakedObjectDetector() noexcept { ++(getCounter().numObjects); } - LeakedObjectDetector (const LeakedObjectDetector&) noexcept { ++(getCounter().numObjects); } - - ~LeakedObjectDetector() - { - if (--(getCounter().numObjects) < 0) - { - DBG ("*** Dangling pointer deletion! Class: " << getLeakedObjectClassName()); - - /** If you hit this, then you've managed to delete more instances of this class than you've - created.. That indicates that you're deleting some dangling pointers. - - Note that although this assertion will have been triggered during a destructor, it might - not be this particular deletion that's at fault - the incorrect one may have happened - at an earlier point in the program, and simply not been detected until now. - - Most errors like this are caused by using old-fashioned, non-RAII techniques for - your object management. Tut, tut. Always, always use ScopedPointers, OwnedArrays, - ReferenceCountedObjects, etc, and avoid the 'delete' operator at all costs! - */ - jassertfalse; - } - } - -private: - //============================================================================== - class LeakCounter - { - public: - LeakCounter() noexcept {} - - ~LeakCounter() - { - if (numObjects.value > 0) - { - DBG ("*** Leaked objects detected: " << numObjects.value << " instance(s) of class " << getLeakedObjectClassName()); - - /** If you hit this, then you've leaked one or more objects of the type specified by - the 'OwnerClass' template parameter - the name should have been printed by the line above. - - If you're leaking, it's probably because you're using old-fashioned, non-RAII techniques for - your object management. Tut, tut. Always, always use ScopedPointers, OwnedArrays, - ReferenceCountedObjects, etc, and avoid the 'delete' operator at all costs! - */ - jassertfalse; - } - } - - Atomic numObjects; - }; - - static const char* getLeakedObjectClassName() - { - return OwnerClass::getLeakedObjectClassName(); - } - - static LeakCounter& getCounter() noexcept - { - static LeakCounter counter; - return counter; - } -}; - -//============================================================================== -#if DOXYGEN || ! defined (JUCE_LEAK_DETECTOR) - #if (DOXYGEN || JUCE_CHECK_MEMORY_LEAKS) - /** This macro lets you embed a leak-detecting object inside a class. - - To use it, simply declare a JUCE_LEAK_DETECTOR(YourClassName) inside a private section - of the class declaration. E.g. - - @code - class MyClass - { - public: - MyClass(); - void blahBlah(); - - private: - JUCE_LEAK_DETECTOR (MyClass) - }; - @endcode - - @see JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR, LeakedObjectDetector - */ - #define JUCE_LEAK_DETECTOR(OwnerClass) \ - friend class juce::LeakedObjectDetector; \ - static const char* getLeakedObjectClassName() noexcept { return #OwnerClass; } \ - juce::LeakedObjectDetector JUCE_JOIN_MACRO (leakDetector, __LINE__); - #else - #define JUCE_LEAK_DETECTOR(OwnerClass) - #endif -#endif - - -#endif // JUCE_LEAKEDOBJECTDETECTOR_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/memory/juce_Memory.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/memory/juce_Memory.h deleted file mode 100644 index 57d1644dc0..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/memory/juce_Memory.h +++ /dev/null @@ -1,126 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_MEMORY_H_INCLUDED -#define JUCE_MEMORY_H_INCLUDED - -//============================================================================== -/** Fills a block of memory with zeros. */ -inline void zeromem (void* memory, size_t numBytes) noexcept { memset (memory, 0, numBytes); } - -/** Overwrites a structure or object with zeros. */ -template -inline void zerostruct (Type& structure) noexcept { memset (&structure, 0, sizeof (structure)); } - -/** Delete an object pointer, and sets the pointer to null. - - Remember that it's not good c++ practice to use delete directly - always try to use a ScopedPointer - or other automatic lifetime-management system rather than resorting to deleting raw pointers! -*/ -template -inline void deleteAndZero (Type& pointer) { delete pointer; pointer = nullptr; } - -/** A handy function which adds a number of bytes to any type of pointer and returns the result. - This can be useful to avoid casting pointers to a char* and back when you want to move them by - a specific number of bytes, -*/ -template -inline Type* addBytesToPointer (Type* pointer, IntegerType bytes) noexcept { return (Type*) (((char*) pointer) + bytes); } - -/** A handy function which returns the difference between any two pointers, in bytes. - The address of the second pointer is subtracted from the first, and the difference in bytes is returned. -*/ -template -inline int getAddressDifference (Type1* pointer1, Type2* pointer2) noexcept { return (int) (((const char*) pointer1) - (const char*) pointer2); } - -/** If a pointer is non-null, this returns a new copy of the object that it points to, or safely returns - nullptr if the pointer is null. -*/ -template -inline Type* createCopyIfNotNull (const Type* pointer) { return pointer != nullptr ? new Type (*pointer) : nullptr; } - -//============================================================================== -#if JUCE_MAC || JUCE_IOS || DOXYGEN - - /** A handy C++ wrapper that creates and deletes an NSAutoreleasePool object using RAII. - You should use the JUCE_AUTORELEASEPOOL macro to create a local auto-release pool on the stack. - */ - class JUCE_API ScopedAutoReleasePool - { - public: - ScopedAutoReleasePool(); - ~ScopedAutoReleasePool(); - - private: - void* pool; - - JUCE_DECLARE_NON_COPYABLE (ScopedAutoReleasePool) - }; - - /** A macro that can be used to easily declare a local ScopedAutoReleasePool - object for RAII-based obj-C autoreleasing. - Because this may use the \@autoreleasepool syntax, you must follow the macro with - a set of braces to mark the scope of the pool. - */ -#if (JUCE_COMPILER_SUPPORTS_ARC && defined (__OBJC__)) || DOXYGEN - #define JUCE_AUTORELEASEPOOL @autoreleasepool -#else - #define JUCE_AUTORELEASEPOOL const juce::ScopedAutoReleasePool JUCE_JOIN_MACRO (autoReleasePool_, __LINE__); -#endif - -#else - #define JUCE_AUTORELEASEPOOL -#endif - -//============================================================================== -/* In a Windows DLL build, we'll expose some malloc/free functions that live inside the DLL, and use these for - allocating all the objects - that way all juce objects in the DLL and in the host will live in the same heap, - avoiding problems when an object is created in one module and passed across to another where it is deleted. - By piggy-backing on the JUCE_LEAK_DETECTOR macro, these allocators can be injected into most juce classes. -*/ -#if JUCE_MSVC && (defined (JUCE_DLL) || defined (JUCE_DLL_BUILD)) && ! (JUCE_DISABLE_DLL_ALLOCATORS || DOXYGEN) - extern JUCE_API void* juceDLL_malloc (size_t); - extern JUCE_API void juceDLL_free (void*); - - #define JUCE_LEAK_DETECTOR(OwnerClass) public:\ - static void* operator new (size_t sz) { return juce::juceDLL_malloc (sz); } \ - static void* operator new (size_t, void* p) { return p; } \ - static void operator delete (void* p) { juce::juceDLL_free (p); } \ - static void operator delete (void*, void*) {} -#endif - -//============================================================================== -/** (Deprecated) This was a Windows-specific way of checking for object leaks - now please - use the JUCE_LEAK_DETECTOR instead. -*/ -#ifndef juce_UseDebuggingNewOperator - #define juce_UseDebuggingNewOperator -#endif - - -#endif // JUCE_MEMORY_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/memory/juce_MemoryBlock.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/memory/juce_MemoryBlock.cpp deleted file mode 100644 index 6097c7e7e5..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/memory/juce_MemoryBlock.cpp +++ /dev/null @@ -1,416 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -MemoryBlock::MemoryBlock() noexcept - : size (0) -{ -} - -MemoryBlock::MemoryBlock (const size_t initialSize, const bool initialiseToZero) -{ - if (initialSize > 0) - { - size = initialSize; - data.allocate (initialSize, initialiseToZero); - } - else - { - size = 0; - } -} - -MemoryBlock::MemoryBlock (const MemoryBlock& other) - : size (other.size) -{ - if (size > 0) - { - jassert (other.data != nullptr); - data.malloc (size); - memcpy (data, other.data, size); - } -} - -MemoryBlock::MemoryBlock (const void* const dataToInitialiseFrom, const size_t sizeInBytes) - : size (sizeInBytes) -{ - jassert (((ssize_t) sizeInBytes) >= 0); - - if (size > 0) - { - jassert (dataToInitialiseFrom != nullptr); // non-zero size, but a zero pointer passed-in? - - data.malloc (size); - - if (dataToInitialiseFrom != nullptr) - memcpy (data, dataToInitialiseFrom, size); - } -} - -MemoryBlock::~MemoryBlock() noexcept -{ -} - -MemoryBlock& MemoryBlock::operator= (const MemoryBlock& other) -{ - if (this != &other) - { - setSize (other.size, false); - memcpy (data, other.data, size); - } - - return *this; -} - -#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS -MemoryBlock::MemoryBlock (MemoryBlock&& other) noexcept - : data (static_cast&&> (other.data)), - size (other.size) -{ -} - -MemoryBlock& MemoryBlock::operator= (MemoryBlock&& other) noexcept -{ - data = static_cast&&> (other.data); - size = other.size; - return *this; -} -#endif - - -//============================================================================== -bool MemoryBlock::operator== (const MemoryBlock& other) const noexcept -{ - return matches (other.data, other.size); -} - -bool MemoryBlock::operator!= (const MemoryBlock& other) const noexcept -{ - return ! operator== (other); -} - -bool MemoryBlock::matches (const void* dataToCompare, size_t dataSize) const noexcept -{ - return size == dataSize - && memcmp (data, dataToCompare, size) == 0; -} - -//============================================================================== -// this will resize the block to this size -void MemoryBlock::setSize (const size_t newSize, const bool initialiseToZero) -{ - if (size != newSize) - { - if (newSize <= 0) - { - reset(); - } - else - { - if (data != nullptr) - { - data.realloc (newSize); - - if (initialiseToZero && (newSize > size)) - zeromem (data + size, newSize - size); - } - else - { - data.allocate (newSize, initialiseToZero); - } - - size = newSize; - } - } -} - -void MemoryBlock::reset() -{ - data.free(); - size = 0; -} - -void MemoryBlock::ensureSize (const size_t minimumSize, const bool initialiseToZero) -{ - if (size < minimumSize) - setSize (minimumSize, initialiseToZero); -} - -void MemoryBlock::swapWith (MemoryBlock& other) noexcept -{ - std::swap (size, other.size); - data.swapWith (other.data); -} - -//============================================================================== -void MemoryBlock::fillWith (const uint8 value) noexcept -{ - memset (data, (int) value, size); -} - -void MemoryBlock::append (const void* const srcData, const size_t numBytes) -{ - if (numBytes > 0) - { - jassert (srcData != nullptr); // this must not be null! - const size_t oldSize = size; - setSize (size + numBytes); - memcpy (data + oldSize, srcData, numBytes); - } -} - -void MemoryBlock::replaceWith (const void* const srcData, const size_t numBytes) -{ - if (numBytes > 0) - { - jassert (srcData != nullptr); // this must not be null! - setSize (numBytes); - memcpy (data, srcData, numBytes); - } -} - -void MemoryBlock::insert (const void* const srcData, const size_t numBytes, size_t insertPosition) -{ - if (numBytes > 0) - { - jassert (srcData != nullptr); // this must not be null! - insertPosition = jmin (size, insertPosition); - const size_t trailingDataSize = size - insertPosition; - setSize (size + numBytes, false); - - if (trailingDataSize > 0) - memmove (data + insertPosition + numBytes, - data + insertPosition, - trailingDataSize); - - memcpy (data + insertPosition, srcData, numBytes); - } -} - -void MemoryBlock::removeSection (const size_t startByte, const size_t numBytesToRemove) -{ - if (startByte + numBytesToRemove >= size) - { - setSize (startByte); - } - else if (numBytesToRemove > 0) - { - memmove (data + startByte, - data + startByte + numBytesToRemove, - size - (startByte + numBytesToRemove)); - - setSize (size - numBytesToRemove); - } -} - -void MemoryBlock::copyFrom (const void* const src, int offset, size_t num) noexcept -{ - const char* d = static_cast (src); - - if (offset < 0) - { - d -= offset; - num += (size_t) -offset; - offset = 0; - } - - if ((size_t) offset + num > size) - num = size - (size_t) offset; - - if (num > 0) - memcpy (data + offset, d, num); -} - -void MemoryBlock::copyTo (void* const dst, int offset, size_t num) const noexcept -{ - char* d = static_cast (dst); - - if (offset < 0) - { - zeromem (d, (size_t) -offset); - d -= offset; - num -= (size_t) -offset; - offset = 0; - } - - if ((size_t) offset + num > size) - { - const size_t newNum = size - (size_t) offset; - zeromem (d + newNum, num - newNum); - num = newNum; - } - - if (num > 0) - memcpy (d, data + offset, num); -} - -String MemoryBlock::toString() const -{ - return String::fromUTF8 (data, (int) size); -} - -//============================================================================== -int MemoryBlock::getBitRange (const size_t bitRangeStart, size_t numBits) const noexcept -{ - int res = 0; - - size_t byte = bitRangeStart >> 3; - size_t offsetInByte = bitRangeStart & 7; - size_t bitsSoFar = 0; - - while (numBits > 0 && (size_t) byte < size) - { - const size_t bitsThisTime = jmin (numBits, 8 - offsetInByte); - const int mask = (0xff >> (8 - bitsThisTime)) << offsetInByte; - - res |= (((data[byte] & mask) >> offsetInByte) << bitsSoFar); - - bitsSoFar += bitsThisTime; - numBits -= bitsThisTime; - ++byte; - offsetInByte = 0; - } - - return res; -} - -void MemoryBlock::setBitRange (const size_t bitRangeStart, size_t numBits, int bitsToSet) noexcept -{ - size_t byte = bitRangeStart >> 3; - size_t offsetInByte = bitRangeStart & 7; - uint32 mask = ~((((uint32) 0xffffffff) << (32 - numBits)) >> (32 - numBits)); - - while (numBits > 0 && (size_t) byte < size) - { - const size_t bitsThisTime = jmin (numBits, 8 - offsetInByte); - - const uint32 tempMask = (mask << offsetInByte) | ~((((uint32) 0xffffffff) >> offsetInByte) << offsetInByte); - const uint32 tempBits = (uint32) bitsToSet << offsetInByte; - - data[byte] = (char) (((uint32) data[byte] & tempMask) | tempBits); - - ++byte; - numBits -= bitsThisTime; - bitsToSet >>= bitsThisTime; - mask >>= bitsThisTime; - offsetInByte = 0; - } -} - -//============================================================================== -void MemoryBlock::loadFromHexString (StringRef hex) -{ - ensureSize ((size_t) hex.length() >> 1); - char* dest = data; - String::CharPointerType t (hex.text); - - for (;;) - { - int byte = 0; - - for (int loop = 2; --loop >= 0;) - { - byte <<= 4; - - for (;;) - { - const juce_wchar c = t.getAndAdvance(); - - if (c >= '0' && c <= '9') { byte |= c - '0'; break; } - if (c >= 'a' && c <= 'z') { byte |= c - ('a' - 10); break; } - if (c >= 'A' && c <= 'Z') { byte |= c - ('A' - 10); break; } - - if (c == 0) - { - setSize (static_cast (dest - data)); - return; - } - } - } - - *dest++ = (char) byte; - } -} - -//============================================================================== -static const char base64EncodingTable[] = ".ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+"; - -String MemoryBlock::toBase64Encoding() const -{ - const size_t numChars = ((size << 3) + 5) / 6; - - String destString ((unsigned int) size); // store the length, followed by a '.', and then the data. - const int initialLen = destString.length(); - destString.preallocateBytes (sizeof (String::CharPointerType::CharType) * (size_t) initialLen + 2 + numChars); - - String::CharPointerType d (destString.getCharPointer()); - d += initialLen; - d.write ('.'); - - for (size_t i = 0; i < numChars; ++i) - d.write ((juce_wchar) (uint8) base64EncodingTable [getBitRange (i * 6, 6)]); - - d.writeNull(); - return destString; -} - -static const char base64DecodingTable[] = -{ - 63, 0, 0, 0, 0, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 0, 0, 0, 0, 0, 0, 0, - 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, - 0, 0, 0, 0, 0, 0, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52 -}; - -bool MemoryBlock::fromBase64Encoding (StringRef s) -{ - String::CharPointerType dot (CharacterFunctions::find (s.text, (juce_wchar) '.')); - - if (dot.isEmpty()) - return false; - - const int numBytesNeeded = String (s.text, dot).getIntValue(); - - setSize ((size_t) numBytesNeeded, true); - - String::CharPointerType srcChars (dot + 1); - int pos = 0; - - for (;;) - { - int c = (int) srcChars.getAndAdvance(); - - if (c == 0) - return true; - - c -= 43; - if (isPositiveAndBelow (c, numElementsInArray (base64DecodingTable))) - { - setBitRange ((size_t) pos, 6, base64DecodingTable [c]); - pos += 6; - } - } -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/memory/juce_MemoryBlock.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/memory/juce_MemoryBlock.h deleted file mode 100644 index 30bb3cab24..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/memory/juce_MemoryBlock.h +++ /dev/null @@ -1,253 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_MEMORYBLOCK_H_INCLUDED -#define JUCE_MEMORYBLOCK_H_INCLUDED - - -//============================================================================== -/** - A class to hold a resizable block of raw data. - -*/ -class JUCE_API MemoryBlock -{ -public: - //============================================================================== - /** Create an uninitialised block with 0 size. */ - MemoryBlock() noexcept; - - /** Creates a memory block with a given initial size. - - @param initialSize the size of block to create - @param initialiseToZero whether to clear the memory or just leave it uninitialised - */ - MemoryBlock (const size_t initialSize, - bool initialiseToZero = false); - - /** Creates a copy of another memory block. */ - MemoryBlock (const MemoryBlock&); - - /** Creates a memory block using a copy of a block of data. - - @param dataToInitialiseFrom some data to copy into this block - @param sizeInBytes how much space to use - */ - MemoryBlock (const void* dataToInitialiseFrom, size_t sizeInBytes); - - /** Destructor. */ - ~MemoryBlock() noexcept; - - /** Copies another memory block onto this one. - This block will be resized and copied to exactly match the other one. - */ - MemoryBlock& operator= (const MemoryBlock&); - - #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS - MemoryBlock (MemoryBlock&&) noexcept; - MemoryBlock& operator= (MemoryBlock&&) noexcept; - #endif - - //============================================================================== - /** Compares two memory blocks. - @returns true only if the two blocks are the same size and have identical contents. - */ - bool operator== (const MemoryBlock& other) const noexcept; - - /** Compares two memory blocks. - @returns true if the two blocks are different sizes or have different contents. - */ - bool operator!= (const MemoryBlock& other) const noexcept; - - /** Returns true if the data in this MemoryBlock matches the raw bytes passed-in. */ - bool matches (const void* data, size_t dataSize) const noexcept; - - //============================================================================== - /** Returns a void pointer to the data. - - Note that the pointer returned will probably become invalid when the - block is resized. - */ - void* getData() const noexcept { return data; } - - /** Returns a byte from the memory block. - This returns a reference, so you can also use it to set a byte. - */ - template - char& operator[] (const Type offset) const noexcept { return data [offset]; } - - - //============================================================================== - /** Returns the block's current allocated size, in bytes. */ - size_t getSize() const noexcept { return size; } - - /** Resizes the memory block. - - Any data that is present in both the old and new sizes will be retained. - When enlarging the block, the new space that is allocated at the end can either be - cleared, or left uninitialised. - - @param newSize the new desired size for the block - @param initialiseNewSpaceToZero if the block gets enlarged, this determines - whether to clear the new section or just leave it - uninitialised - @see ensureSize - */ - void setSize (const size_t newSize, - bool initialiseNewSpaceToZero = false); - - /** Increases the block's size only if it's smaller than a given size. - - @param minimumSize if the block is already bigger than this size, no action - will be taken; otherwise it will be increased to this size - @param initialiseNewSpaceToZero if the block gets enlarged, this determines - whether to clear the new section or just leave it - uninitialised - @see setSize - */ - void ensureSize (const size_t minimumSize, - bool initialiseNewSpaceToZero = false); - - /** Frees all the blocks data, setting its size to 0. */ - void reset(); - - //============================================================================== - /** Fills the entire memory block with a repeated byte value. - This is handy for clearing a block of memory to zero. - */ - void fillWith (uint8 valueToUse) noexcept; - - /** Adds another block of data to the end of this one. - The data pointer must not be null. This block's size will be increased accordingly. - */ - void append (const void* data, size_t numBytes); - - /** Resizes this block to the given size and fills its contents from the supplied buffer. - The data pointer must not be null. - */ - void replaceWith (const void* data, size_t numBytes); - - /** Inserts some data into the block. - The dataToInsert pointer must not be null. This block's size will be increased accordingly. - If the insert position lies outside the valid range of the block, it will be clipped to - within the range before being used. - */ - void insert (const void* dataToInsert, size_t numBytesToInsert, size_t insertPosition); - - /** Chops out a section of the block. - - This will remove a section of the memory block and close the gap around it, - shifting any subsequent data downwards and reducing the size of the block. - - If the range specified goes beyond the size of the block, it will be clipped. - */ - void removeSection (size_t startByte, size_t numBytesToRemove); - - //============================================================================== - /** Copies data into this MemoryBlock from a memory address. - - @param srcData the memory location of the data to copy into this block - @param destinationOffset the offset in this block at which the data being copied should begin - @param numBytes how much to copy in (if this goes beyond the size of the memory block, - it will be clipped so not to do anything nasty) - */ - void copyFrom (const void* srcData, - int destinationOffset, - size_t numBytes) noexcept; - - /** Copies data from this MemoryBlock to a memory address. - - @param destData the memory location to write to - @param sourceOffset the offset within this block from which the copied data will be read - @param numBytes how much to copy (if this extends beyond the limits of the memory block, - zeros will be used for that portion of the data) - */ - void copyTo (void* destData, - int sourceOffset, - size_t numBytes) const noexcept; - - //============================================================================== - /** Exchanges the contents of this and another memory block. - No actual copying is required for this, so it's very fast. - */ - void swapWith (MemoryBlock& other) noexcept; - - //============================================================================== - /** Attempts to parse the contents of the block as a zero-terminated UTF8 string. */ - String toString() const; - - //============================================================================== - /** Parses a string of hexadecimal numbers and writes this data into the memory block. - - The block will be resized to the number of valid bytes read from the string. - Non-hex characters in the string will be ignored. - - @see String::toHexString() - */ - void loadFromHexString (StringRef sourceHexString); - - //============================================================================== - /** Sets a number of bits in the memory block, treating it as a long binary sequence. */ - void setBitRange (size_t bitRangeStart, - size_t numBits, - int binaryNumberToApply) noexcept; - - /** Reads a number of bits from the memory block, treating it as one long binary sequence */ - int getBitRange (size_t bitRangeStart, - size_t numBitsToRead) const noexcept; - - //============================================================================== - /** Returns a string of characters that represent the binary contents of this block. - - Uses a 64-bit encoding system to allow binary data to be turned into a string - of simple non-extended characters, e.g. for storage in XML. - - @see fromBase64Encoding - */ - String toBase64Encoding() const; - - /** Takes a string of encoded characters and turns it into binary data. - - The string passed in must have been created by to64BitEncoding(), and this - block will be resized to recreate the original data block. - - @see toBase64Encoding - */ - bool fromBase64Encoding (StringRef encodedString); - - -private: - //============================================================================== - HeapBlock data; - size_t size; - - JUCE_LEAK_DETECTOR (MemoryBlock) -}; - - -#endif // JUCE_MEMORYBLOCK_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/memory/juce_OptionalScopedPointer.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/memory/juce_OptionalScopedPointer.h deleted file mode 100644 index a633dca1b8..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/memory/juce_OptionalScopedPointer.h +++ /dev/null @@ -1,186 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_OPTIONALSCOPEDPOINTER_H_INCLUDED -#define JUCE_OPTIONALSCOPEDPOINTER_H_INCLUDED - - -//============================================================================== -/** - Holds a pointer to an object which can optionally be deleted when this pointer - goes out of scope. - - This acts in many ways like a ScopedPointer, but allows you to specify whether or - not the object is deleted. - - @see ScopedPointer -*/ -template -class OptionalScopedPointer -{ -public: - //============================================================================== - /** Creates an empty OptionalScopedPointer. */ - OptionalScopedPointer() : shouldDelete (false) {} - - /** Creates an OptionalScopedPointer to point to a given object, and specifying whether - the OptionalScopedPointer will delete it. - - If takeOwnership is true, then the OptionalScopedPointer will act like a ScopedPointer, - deleting the object when it is itself deleted. If this parameter is false, then the - OptionalScopedPointer just holds a normal pointer to the object, and won't delete it. - */ - OptionalScopedPointer (ObjectType* objectToHold, bool takeOwnership) - : object (objectToHold), shouldDelete (takeOwnership) - { - } - - /** Takes ownership of the object that another OptionalScopedPointer holds. - - Like a normal ScopedPointer, the objectToTransferFrom object will become null, - as ownership of the managed object is transferred to this object. - - The flag to indicate whether or not to delete the managed object is also - copied from the source object. - */ - OptionalScopedPointer (OptionalScopedPointer& objectToTransferFrom) - : object (objectToTransferFrom.release()), - shouldDelete (objectToTransferFrom.shouldDelete) - { - } - - /** Takes ownership of the object that another OptionalScopedPointer holds. - - Like a normal ScopedPointer, the objectToTransferFrom object will become null, - as ownership of the managed object is transferred to this object. - - The ownership flag that says whether or not to delete the managed object is also - copied from the source object. - */ - OptionalScopedPointer& operator= (OptionalScopedPointer& objectToTransferFrom) - { - if (object != objectToTransferFrom.object) - { - clear(); - object = objectToTransferFrom.object; - } - - shouldDelete = objectToTransferFrom.shouldDelete; - return *this; - } - - /** The destructor may or may not delete the object that is being held, depending on the - takeOwnership flag that was specified when the object was first passed into an - OptionalScopedPointer constructor. - */ - ~OptionalScopedPointer() - { - clear(); - } - - //============================================================================== - /** Returns the object that this pointer is managing. */ - inline operator ObjectType*() const noexcept { return object; } - - /** Returns the object that this pointer is managing. */ - inline ObjectType* get() const noexcept { return object; } - - /** Returns the object that this pointer is managing. */ - inline ObjectType& operator*() const noexcept { return *object; } - - /** Lets you access methods and properties of the object that this pointer is holding. */ - inline ObjectType* operator->() const noexcept { return object; } - - //============================================================================== - /** Removes the current object from this OptionalScopedPointer without deleting it. - This will return the current object, and set this OptionalScopedPointer to a null pointer. - */ - ObjectType* release() noexcept { return object.release(); } - - /** Resets this pointer to null, possibly deleting the object that it holds, if it has - ownership of it. - */ - void clear() - { - if (! shouldDelete) - object.release(); - } - - /** Makes this OptionalScopedPointer point at a new object, specifying whether the - OptionalScopedPointer will take ownership of the object. - - If takeOwnership is true, then the OptionalScopedPointer will act like a ScopedPointer, - deleting the object when it is itself deleted. If this parameter is false, then the - OptionalScopedPointer just holds a normal pointer to the object, and won't delete it. - */ - void set (ObjectType* newObject, bool takeOwnership) - { - if (object != newObject) - { - clear(); - object = newObject; - } - - shouldDelete = takeOwnership; - } - - /** Makes this OptionalScopedPointer point at a new object, and take ownership of that object. */ - void setOwned (ObjectType* newObject) - { - set (newObject, true); - } - - /** Makes this OptionalScopedPointer point at a new object, but will not take ownership of that object. */ - void setNonOwned (ObjectType* newObject) - { - set (newObject, false); - } - - /** Returns true if the target object will be deleted when this pointer - object is deleted. - */ - bool willDeleteObject() const noexcept { return shouldDelete; } - - //============================================================================== - /** Swaps this object with another OptionalScopedPointer. - The two objects simply exchange their states. - */ - void swapWith (OptionalScopedPointer& other) noexcept - { - object.swapWith (other.object); - std::swap (shouldDelete, other.shouldDelete); - } - -private: - //============================================================================== - ScopedPointer object; - bool shouldDelete; -}; - - -#endif // JUCE_OPTIONALSCOPEDPOINTER_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/memory/juce_ReferenceCountedObject.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/memory/juce_ReferenceCountedObject.h deleted file mode 100644 index 36ac5c3a7c..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/memory/juce_ReferenceCountedObject.h +++ /dev/null @@ -1,415 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_REFERENCECOUNTEDOBJECT_H_INCLUDED -#define JUCE_REFERENCECOUNTEDOBJECT_H_INCLUDED - - -//============================================================================== -/** - A base class which provides methods for reference-counting. - - To add reference-counting to a class, derive it from this class, and - use the ReferenceCountedObjectPtr class to point to it. - - e.g. @code - class MyClass : public ReferenceCountedObject - { - void foo(); - - // This is a neat way of declaring a typedef for a pointer class, - // rather than typing out the full templated name each time.. - typedef ReferenceCountedObjectPtr Ptr; - }; - - MyClass::Ptr p = new MyClass(); - MyClass::Ptr p2 = p; - p = nullptr; - p2->foo(); - @endcode - - Once a new ReferenceCountedObject has been assigned to a pointer, be - careful not to delete the object manually. - - This class uses an Atomic value to hold the reference count, so that it - the pointers can be passed between threads safely. For a faster but non-thread-safe - version, use SingleThreadedReferenceCountedObject instead. - - @see ReferenceCountedObjectPtr, ReferenceCountedArray, SingleThreadedReferenceCountedObject -*/ -class JUCE_API ReferenceCountedObject -{ -public: - //============================================================================== - /** Increments the object's reference count. - - This is done automatically by the smart pointer, but is public just - in case it's needed for nefarious purposes. - */ - void incReferenceCount() noexcept - { - ++refCount; - } - - /** Decreases the object's reference count. - If the count gets to zero, the object will be deleted. - */ - void decReferenceCount() noexcept - { - jassert (getReferenceCount() > 0); - - if (--refCount == 0) - delete this; - } - - /** Decreases the object's reference count. - If the count gets to zero, the object will not be deleted, but this method - will return true, allowing the caller to take care of deletion. - */ - bool decReferenceCountWithoutDeleting() noexcept - { - jassert (getReferenceCount() > 0); - return --refCount == 0; - } - - /** Returns the object's current reference count. */ - int getReferenceCount() const noexcept { return refCount.get(); } - - -protected: - //============================================================================== - /** Creates the reference-counted object (with an initial ref count of zero). */ - ReferenceCountedObject() {} - - /** Destructor. */ - virtual ~ReferenceCountedObject() - { - // it's dangerous to delete an object that's still referenced by something else! - jassert (getReferenceCount() == 0); - } - - /** Resets the reference count to zero without deleting the object. - You should probably never need to use this! - */ - void resetReferenceCount() noexcept - { - refCount = 0; - } - -private: - //============================================================================== - Atomic refCount; - - friend struct ContainerDeletePolicy; - JUCE_DECLARE_NON_COPYABLE (ReferenceCountedObject) -}; - - -//============================================================================== -/** - Adds reference-counting to an object. - - This is effectively a version of the ReferenceCountedObject class, but which - uses a non-atomic counter, and so is not thread-safe (but which will be more - efficient). - For more details on how to use it, see the ReferenceCountedObject class notes. - - @see ReferenceCountedObject, ReferenceCountedObjectPtr, ReferenceCountedArray -*/ -class JUCE_API SingleThreadedReferenceCountedObject -{ -public: - //============================================================================== - /** Increments the object's reference count. - - This is done automatically by the smart pointer, but is public just - in case it's needed for nefarious purposes. - */ - void incReferenceCount() noexcept - { - ++refCount; - } - - /** Decreases the object's reference count. - If the count gets to zero, the object will be deleted. - */ - void decReferenceCount() noexcept - { - jassert (getReferenceCount() > 0); - - if (--refCount == 0) - delete this; - } - - /** Decreases the object's reference count. - If the count gets to zero, the object will not be deleted, but this method - will return true, allowing the caller to take care of deletion. - */ - bool decReferenceCountWithoutDeleting() noexcept - { - jassert (getReferenceCount() > 0); - return --refCount == 0; - } - - /** Returns the object's current reference count. */ - int getReferenceCount() const noexcept { return refCount; } - - -protected: - //============================================================================== - /** Creates the reference-counted object (with an initial ref count of zero). */ - SingleThreadedReferenceCountedObject() : refCount (0) {} - - /** Destructor. */ - virtual ~SingleThreadedReferenceCountedObject() - { - // it's dangerous to delete an object that's still referenced by something else! - jassert (getReferenceCount() == 0); - } - -private: - //============================================================================== - int refCount; - - friend struct ContainerDeletePolicy; - JUCE_DECLARE_NON_COPYABLE (SingleThreadedReferenceCountedObject) -}; - - -//============================================================================== -/** - A smart-pointer class which points to a reference-counted object. - - The template parameter specifies the class of the object you want to point to - the easiest - way to make a class reference-countable is to simply make it inherit from ReferenceCountedObject - or SingleThreadedReferenceCountedObject, but if you need to, you can roll your own reference-countable - class by implementing a set of methods called incReferenceCount(), decReferenceCount(), and - decReferenceCountWithoutDeleting(). See ReferenceCountedObject for examples of how these methods - should behave. - - When using this class, you'll probably want to create a typedef to abbreviate the full - templated name - e.g. - @code - struct MyClass : public ReferenceCountedObject - { - typedef ReferenceCountedObjectPtr Ptr; - ... - @endcode - - @see ReferenceCountedObject, ReferenceCountedObjectArray -*/ -template -class ReferenceCountedObjectPtr -{ -public: - /** The class being referenced by this pointer. */ - typedef ReferenceCountedObjectClass ReferencedType; - - //============================================================================== - /** Creates a pointer to a null object. */ - ReferenceCountedObjectPtr() noexcept - : referencedObject (nullptr) - { - } - - /** Creates a pointer to an object. - This will increment the object's reference-count. - */ - ReferenceCountedObjectPtr (ReferencedType* refCountedObject) noexcept - : referencedObject (refCountedObject) - { - incIfNotNull (refCountedObject); - } - - /** Copies another pointer. - This will increment the object's reference-count. - */ - ReferenceCountedObjectPtr (const ReferenceCountedObjectPtr& other) noexcept - : referencedObject (other.referencedObject) - { - incIfNotNull (referencedObject); - } - - /** Copies another pointer. - This will increment the object's reference-count (if it is non-null). - */ - template - ReferenceCountedObjectPtr (const ReferenceCountedObjectPtr& other) noexcept - : referencedObject (static_cast (other.get())) - { - incIfNotNull (referencedObject); - } - - /** Changes this pointer to point at a different object. - The reference count of the old object is decremented, and it might be - deleted if it hits zero. The new object's count is incremented. - */ - ReferenceCountedObjectPtr& operator= (const ReferenceCountedObjectPtr& other) - { - return operator= (other.referencedObject); - } - - /** Changes this pointer to point at a different object. - The reference count of the old object is decremented, and it might be - deleted if it hits zero. The new object's count is incremented. - */ - template - ReferenceCountedObjectPtr& operator= (const ReferenceCountedObjectPtr& other) - { - return operator= (static_cast (other.get())); - } - - /** Changes this pointer to point at a different object. - - The reference count of the old object is decremented, and it might be - deleted if it hits zero. The new object's count is incremented. - */ - ReferenceCountedObjectPtr& operator= (ReferencedType* const newObject) - { - if (referencedObject != newObject) - { - incIfNotNull (newObject); - ReferencedType* const oldObject = referencedObject; - referencedObject = newObject; - decIfNotNull (oldObject); - } - - return *this; - } - - #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS - /** Takes-over the object from another pointer. */ - ReferenceCountedObjectPtr (ReferenceCountedObjectPtr&& other) noexcept - : referencedObject (other.referencedObject) - { - other.referencedObject = nullptr; - } - - /** Takes-over the object from another pointer. */ - ReferenceCountedObjectPtr& operator= (ReferenceCountedObjectPtr&& other) - { - std::swap (referencedObject, other.referencedObject); - return *this; - } - #endif - - /** Destructor. - This will decrement the object's reference-count, which will cause the - object to be deleted when the ref-count hits zero. - */ - ~ReferenceCountedObjectPtr() - { - decIfNotNull (referencedObject); - } - - //============================================================================== - /** Returns the object that this pointer references. - The pointer returned may be null, of course. - */ - operator ReferencedType*() const noexcept { return referencedObject; } - - /** Returns the object that this pointer references. - The pointer returned may be null, of course. - */ - ReferencedType* get() const noexcept { return referencedObject; } - - /** Returns the object that this pointer references. - The pointer returned may be null, of course. - */ - ReferencedType* getObject() const noexcept { return referencedObject; } - - // the -> operator is called on the referenced object - ReferencedType* operator->() const noexcept - { - jassert (referencedObject != nullptr); // null pointer method call! - return referencedObject; - } - -private: - //============================================================================== - ReferencedType* referencedObject; - - static void incIfNotNull (ReferencedType* o) noexcept - { - if (o != nullptr) - o->incReferenceCount(); - } - - static void decIfNotNull (ReferencedType* o) noexcept - { - if (o != nullptr && o->decReferenceCountWithoutDeleting()) - ContainerDeletePolicy::destroy (o); - } -}; - - -//============================================================================== -/** Compares two ReferenceCountedObjectPointers. */ -template -bool operator== (const ReferenceCountedObjectPtr& object1, ReferenceCountedObjectClass* const object2) noexcept -{ - return object1.get() == object2; -} - -/** Compares two ReferenceCountedObjectPointers. */ -template -bool operator== (const ReferenceCountedObjectPtr& object1, const ReferenceCountedObjectPtr& object2) noexcept -{ - return object1.get() == object2.get(); -} - -/** Compares two ReferenceCountedObjectPointers. */ -template -bool operator== (ReferenceCountedObjectClass* object1, const ReferenceCountedObjectPtr& object2) noexcept -{ - return object1 == object2.get(); -} - -/** Compares two ReferenceCountedObjectPointers. */ -template -bool operator!= (const ReferenceCountedObjectPtr& object1, const ReferenceCountedObjectClass* object2) noexcept -{ - return object1.get() != object2; -} - -/** Compares two ReferenceCountedObjectPointers. */ -template -bool operator!= (const ReferenceCountedObjectPtr& object1, const ReferenceCountedObjectPtr& object2) noexcept -{ - return object1.get() != object2.get(); -} - -/** Compares two ReferenceCountedObjectPointers. */ -template -bool operator!= (ReferenceCountedObjectClass* object1, const ReferenceCountedObjectPtr& object2) noexcept -{ - return object1 != object2.get(); -} - - -#endif // JUCE_REFERENCECOUNTEDOBJECT_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/memory/juce_ScopedPointer.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/memory/juce_ScopedPointer.h deleted file mode 100644 index 1aa8031e1d..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/memory/juce_ScopedPointer.h +++ /dev/null @@ -1,253 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_SCOPEDPOINTER_H_INCLUDED -#define JUCE_SCOPEDPOINTER_H_INCLUDED - -//============================================================================== -/** - This class holds a pointer which is automatically deleted when this object goes - out of scope. - - Once a pointer has been passed to a ScopedPointer, it will make sure that the pointer - gets deleted when the ScopedPointer is deleted. Using the ScopedPointer on the stack or - as member variables is a good way to use RAII to avoid accidentally leaking dynamically - created objects. - - A ScopedPointer can be used in pretty much the same way that you'd use a normal pointer - to an object. If you use the assignment operator to assign a different object to a - ScopedPointer, the old one will be automatically deleted. - - Important note: The class is designed to hold a pointer to an object, NOT to an array! - It calls delete on its payload, not delete[], so do not give it an array to hold! For - that kind of purpose, you should be using HeapBlock or Array instead. - - A const ScopedPointer is guaranteed not to lose ownership of its object or change the - object to which it points during its lifetime. This means that making a copy of a const - ScopedPointer is impossible, as that would involve the new copy taking ownership from the - old one. - - If you need to get a pointer out of a ScopedPointer without it being deleted, you - can use the release() method. - - Something to note is the main difference between this class and the std::auto_ptr class, - which is that ScopedPointer provides a cast-to-object operator, wheras std::auto_ptr - requires that you always call get() to retrieve the pointer. The advantages of providing - the cast is that you don't need to call get(), so can use the ScopedPointer in pretty much - exactly the same way as a raw pointer. The disadvantage is that the compiler is free to - use the cast in unexpected and sometimes dangerous ways - in particular, it becomes difficult - to return a ScopedPointer as the result of a function. To avoid this causing errors, - ScopedPointer contains an overloaded constructor that should cause a syntax error in these - circumstances, but it does mean that instead of returning a ScopedPointer from a function, - you'd need to return a raw pointer (or use a std::auto_ptr instead). -*/ -template -class ScopedPointer -{ -public: - //============================================================================== - /** Creates a ScopedPointer containing a null pointer. */ - inline ScopedPointer() noexcept : object (nullptr) - { - } - - /** Creates a ScopedPointer that owns the specified object. */ - inline ScopedPointer (ObjectType* const objectToTakePossessionOf) noexcept - : object (objectToTakePossessionOf) - { - } - - /** Creates a ScopedPointer that takes its pointer from another ScopedPointer. - - Because a pointer can only belong to one ScopedPointer, this transfers - the pointer from the other object to this one, and the other object is reset to - be a null pointer. - */ - ScopedPointer (ScopedPointer& objectToTransferFrom) noexcept - : object (objectToTransferFrom.object) - { - objectToTransferFrom.object = nullptr; - } - - /** Destructor. - This will delete the object that this ScopedPointer currently refers to. - */ - inline ~ScopedPointer() { ContainerDeletePolicy::destroy (object); } - - /** Changes this ScopedPointer to point to a new object. - - Because a pointer can only belong to one ScopedPointer, this transfers - the pointer from the other object to this one, and the other object is reset to - be a null pointer. - - If this ScopedPointer already points to an object, that object - will first be deleted. - */ - ScopedPointer& operator= (ScopedPointer& objectToTransferFrom) - { - if (this != objectToTransferFrom.getAddress()) - { - // Two ScopedPointers should never be able to refer to the same object - if - // this happens, you must have done something dodgy! - jassert (object == nullptr || object != objectToTransferFrom.object); - - ObjectType* const oldObject = object; - object = objectToTransferFrom.object; - objectToTransferFrom.object = nullptr; - ContainerDeletePolicy::destroy (oldObject); - } - - return *this; - } - - /** Changes this ScopedPointer to point to a new object. - - If this ScopedPointer already points to an object, that object - will first be deleted. - - The pointer that you pass in may be a nullptr. - */ - ScopedPointer& operator= (ObjectType* const newObjectToTakePossessionOf) - { - if (object != newObjectToTakePossessionOf) - { - ObjectType* const oldObject = object; - object = newObjectToTakePossessionOf; - ContainerDeletePolicy::destroy (oldObject); - } - - return *this; - } - - #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS - ScopedPointer (ScopedPointer&& other) noexcept - : object (other.object) - { - other.object = nullptr; - } - - ScopedPointer& operator= (ScopedPointer&& other) noexcept - { - object = other.object; - other.object = nullptr; - return *this; - } - #endif - - //============================================================================== - /** Returns the object that this ScopedPointer refers to. */ - inline operator ObjectType*() const noexcept { return object; } - - /** Returns the object that this ScopedPointer refers to. */ - inline ObjectType* get() const noexcept { return object; } - - /** Returns the object that this ScopedPointer refers to. */ - inline ObjectType& operator*() const noexcept { return *object; } - - /** Lets you access methods and properties of the object that this ScopedPointer refers to. */ - inline ObjectType* operator->() const noexcept { return object; } - - //============================================================================== - /** Removes the current object from this ScopedPointer without deleting it. - This will return the current object, and set the ScopedPointer to a null pointer. - */ - ObjectType* release() noexcept { ObjectType* const o = object; object = nullptr; return o; } - - //============================================================================== - /** Swaps this object with that of another ScopedPointer. - The two objects simply exchange their pointers. - */ - void swapWith (ScopedPointer& other) noexcept - { - // Two ScopedPointers should never be able to refer to the same object - if - // this happens, you must have done something dodgy! - jassert (object != other.object || this == other.getAddress() || object == nullptr); - - std::swap (object, other.object); - } - - /** If the pointer is non-null, this will attempt to return a new copy of the object that is pointed to. - If the pointer is null, this will safely return a nullptr. - */ - inline ObjectType* createCopy() const { return createCopyIfNotNull (object); } - -private: - //============================================================================== - ObjectType* object; - - // (Required as an alternative to the overloaded & operator). - const ScopedPointer* getAddress() const noexcept { return this; } - - #if ! JUCE_MSVC // (MSVC can't deal with multiple copy constructors) - /* The copy constructors are private to stop people accidentally copying a const ScopedPointer - (the compiler would let you do so by implicitly casting the source to its raw object pointer). - - A side effect of this is that in a compiler that doesn't support C++11, you may hit an - error when you write something like this: - - ScopedPointer m = new MyClass(); // Compile error: copy constructor is private. - - Even though the compiler would normally ignore the assignment here, it can't do so when the - copy constructor is private. It's very easy to fix though - just write it like this: - - ScopedPointer m (new MyClass()); // Compiles OK - - It's probably best to use the latter form when writing your object declarations anyway, as - this is a better representation of the code that you actually want the compiler to produce. - */ - JUCE_DECLARE_NON_COPYABLE (ScopedPointer) - #endif -}; - -//============================================================================== -/** Compares a ScopedPointer with another pointer. - This can be handy for checking whether this is a null pointer. -*/ -template -bool operator== (const ScopedPointer& pointer1, ObjectType* const pointer2) noexcept -{ - return static_cast (pointer1) == pointer2; -} - -/** Compares a ScopedPointer with another pointer. - This can be handy for checking whether this is a null pointer. -*/ -template -bool operator!= (const ScopedPointer& pointer1, ObjectType* const pointer2) noexcept -{ - return static_cast (pointer1) != pointer2; -} - -//============================================================================== -#ifndef DOXYGEN -// NB: This is just here to prevent any silly attempts to call deleteAndZero() on a ScopedPointer. -template -void deleteAndZero (ScopedPointer&) { static_jassert (sizeof (Type) == 12345); } -#endif - -#endif // JUCE_SCOPEDPOINTER_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/memory/juce_SharedResourcePointer.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/memory/juce_SharedResourcePointer.h deleted file mode 100644 index 53d314b4e1..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/memory/juce_SharedResourcePointer.h +++ /dev/null @@ -1,152 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_SHAREDRESOURCEPOINTER_H_INCLUDED -#define JUCE_SHAREDRESOURCEPOINTER_H_INCLUDED - - -//============================================================================== -/** - A smart-pointer that automatically creates and manages the lifetime of a - shared static instance of a class. - - The SharedObjectType template type indicates the class to use for the shared - object - the only requirements on this class are that it must have a public - default constructor and destructor. - - The SharedResourcePointer offers a pattern that differs from using a singleton or - static instance of an object, because it uses reference-counting to make sure that - the underlying shared object is automatically created/destroyed according to the - number of SharedResourcePointer objects that exist. When the last one is deleted, - the underlying object is also immediately destroyed. This allows you to use scoping - to manage the lifetime of a shared resource. - - Note: the construction/deletion of the shared object must not involve any - code that makes recursive calls to a SharedResourcePointer, or you'll cause - a deadlock. - - Example: - @code - // An example of a class that contains the shared data you want to use. - struct MySharedData - { - // There's no need to ever create an instance of this class directly yourself, - // but it does need a public constructor that does the initialisation. - MySharedData() - { - sharedStuff = generateHeavyweightStuff(); - } - - Array sharedStuff; - }; - - struct DataUserClass - { - DataUserClass() - { - // Multiple instances of the DataUserClass will all have the same - // shared common instance of MySharedData referenced by their sharedData - // member variables. - useSharedStuff (sharedData->sharedStuff); - } - - // By keeping this pointer as a member variable, the shared resource - // is guaranteed to be available for as long as the DataUserClass object. - SharedResourcePointer sharedData; - }; - - @endcode - */ -template -class SharedResourcePointer -{ -public: - /** Creates an instance of the shared object. - If other SharedResourcePointer objects for this type already exist, then - this one will simply point to the same shared object that they are already - using. Otherwise, if this is the first SharedResourcePointer to be created, - then a shared object will be created automatically. - */ - SharedResourcePointer() - { - SharedObjectHolder& holder = getSharedObjectHolder(); - const SpinLock::ScopedLockType sl (holder.lock); - - if (++(holder.refCount) == 1) - holder.sharedInstance = new SharedObjectType(); - - sharedObject = holder.sharedInstance; - } - - /** Destructor. - If no other SharedResourcePointer objects exist, this will also delete - the shared object to which it refers. - */ - ~SharedResourcePointer() - { - SharedObjectHolder& holder = getSharedObjectHolder(); - const SpinLock::ScopedLockType sl (holder.lock); - - if (--(holder.refCount) == 0) - holder.sharedInstance = nullptr; - } - - /** Returns the shared object. */ - operator SharedObjectType*() const noexcept { return sharedObject; } - - /** Returns the shared object. */ - SharedObjectType& get() const noexcept { return *sharedObject; } - - /** Returns the object that this pointer references. - The pointer returned may be zero, of course. - */ - SharedObjectType& getObject() const noexcept { return *sharedObject; } - - SharedObjectType* operator->() const noexcept { return sharedObject; } - -private: - struct SharedObjectHolder : public ReferenceCountedObject - { - SpinLock lock; - ScopedPointer sharedInstance; - int refCount; - }; - - static SharedObjectHolder& getSharedObjectHolder() noexcept - { - static void* holder [(sizeof (SharedObjectHolder) + sizeof(void*) - 1) / sizeof(void*)] = { 0 }; - return *reinterpret_cast (holder); - } - - SharedObjectType* sharedObject; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (SharedResourcePointer) -}; - - -#endif // JUCE_SHAREDRESOURCEPOINTER_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/memory/juce_Singleton.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/memory/juce_Singleton.h deleted file mode 100644 index 00ea0afe09..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/memory/juce_Singleton.h +++ /dev/null @@ -1,292 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_SINGLETON_H_INCLUDED -#define JUCE_SINGLETON_H_INCLUDED - - -//============================================================================== -/** - Macro to declare member variables and methods for a singleton class. - - To use this, add the line juce_DeclareSingleton (MyClass, doNotRecreateAfterDeletion) - to the class's definition. - - Then put a macro juce_ImplementSingleton (MyClass) along with the class's - implementation code. - - It's also a very good idea to also add the call clearSingletonInstance() in your class's - destructor, in case it is deleted by other means than deleteInstance() - - Clients can then call the static method MyClass::getInstance() to get a pointer - to the singleton, or MyClass::getInstanceWithoutCreating() which will return 0 if - no instance currently exists. - - e.g. @code - - class MySingleton - { - public: - MySingleton() - { - } - - ~MySingleton() - { - // this ensures that no dangling pointers are left when the - // singleton is deleted. - clearSingletonInstance(); - } - - juce_DeclareSingleton (MySingleton, false) - }; - - juce_ImplementSingleton (MySingleton) - - - // example of usage: - MySingleton* m = MySingleton::getInstance(); // creates the singleton if there isn't already one. - - ... - - MySingleton::deleteInstance(); // safely deletes the singleton (if it's been created). - - @endcode - - If doNotRecreateAfterDeletion = true, it won't allow the object to be created more - than once during the process's lifetime - i.e. after you've created and deleted the - object, getInstance() will refuse to create another one. This can be useful to stop - objects being accidentally re-created during your app's shutdown code. - - If you know that your object will only be created and deleted by a single thread, you - can use the slightly more efficient juce_DeclareSingleton_SingleThreaded() macro instead - of this one. - - @see juce_ImplementSingleton, juce_DeclareSingleton_SingleThreaded -*/ -#define juce_DeclareSingleton(classname, doNotRecreateAfterDeletion) \ -\ - static classname* _singletonInstance; \ - static juce::CriticalSection _singletonLock; \ -\ - static classname* JUCE_CALLTYPE getInstance() \ - { \ - if (_singletonInstance == nullptr) \ - {\ - const juce::ScopedLock sl (_singletonLock); \ -\ - if (_singletonInstance == nullptr) \ - { \ - static bool alreadyInside = false; \ - static bool createdOnceAlready = false; \ -\ - const bool problem = alreadyInside || ((doNotRecreateAfterDeletion) && createdOnceAlready); \ - jassert (! problem); \ - if (! problem) \ - { \ - createdOnceAlready = true; \ - alreadyInside = true; \ - classname* newObject = new classname(); /* (use a stack variable to avoid setting the newObject value before the class has finished its constructor) */ \ - alreadyInside = false; \ -\ - _singletonInstance = newObject; \ - } \ - } \ - } \ -\ - return _singletonInstance; \ - } \ -\ - static inline classname* JUCE_CALLTYPE getInstanceWithoutCreating() noexcept\ - { \ - return _singletonInstance; \ - } \ -\ - static void JUCE_CALLTYPE deleteInstance() \ - { \ - const juce::ScopedLock sl (_singletonLock); \ - if (_singletonInstance != nullptr) \ - { \ - classname* const old = _singletonInstance; \ - _singletonInstance = nullptr; \ - delete old; \ - } \ - } \ -\ - void clearSingletonInstance() noexcept\ - { \ - if (_singletonInstance == this) \ - _singletonInstance = nullptr; \ - } - - -//============================================================================== -/** This is a counterpart to the juce_DeclareSingleton macro. - - After adding the juce_DeclareSingleton to the class definition, this macro has - to be used in the cpp file. -*/ -#define juce_ImplementSingleton(classname) \ -\ - classname* classname::_singletonInstance = nullptr; \ - juce::CriticalSection classname::_singletonLock; - - -//============================================================================== -/** - Macro to declare member variables and methods for a singleton class. - - This is exactly the same as juce_DeclareSingleton, but doesn't use a critical - section to make access to it thread-safe. If you know that your object will - only ever be created or deleted by a single thread, then this is a - more efficient version to use. - - If doNotRecreateAfterDeletion = true, it won't allow the object to be created more - than once during the process's lifetime - i.e. after you've created and deleted the - object, getInstance() will refuse to create another one. This can be useful to stop - objects being accidentally re-created during your app's shutdown code. - - See the documentation for juce_DeclareSingleton for more information about - how to use it, the only difference being that you have to use - juce_ImplementSingleton_SingleThreaded instead of juce_ImplementSingleton. - - @see juce_ImplementSingleton_SingleThreaded, juce_DeclareSingleton, juce_DeclareSingleton_SingleThreaded_Minimal -*/ -#define juce_DeclareSingleton_SingleThreaded(classname, doNotRecreateAfterDeletion) \ -\ - static classname* _singletonInstance; \ -\ - static classname* getInstance() \ - { \ - if (_singletonInstance == nullptr) \ - { \ - static bool alreadyInside = false; \ - static bool createdOnceAlready = false; \ -\ - const bool problem = alreadyInside || ((doNotRecreateAfterDeletion) && createdOnceAlready); \ - jassert (! problem); \ - if (! problem) \ - { \ - createdOnceAlready = true; \ - alreadyInside = true; \ - classname* newObject = new classname(); /* (use a stack variable to avoid setting the newObject value before the class has finished its constructor) */ \ - alreadyInside = false; \ -\ - _singletonInstance = newObject; \ - } \ - } \ -\ - return _singletonInstance; \ - } \ -\ - static inline classname* getInstanceWithoutCreating() noexcept\ - { \ - return _singletonInstance; \ - } \ -\ - static void deleteInstance() \ - { \ - if (_singletonInstance != nullptr) \ - { \ - classname* const old = _singletonInstance; \ - _singletonInstance = nullptr; \ - delete old; \ - } \ - } \ -\ - void clearSingletonInstance() noexcept\ - { \ - if (_singletonInstance == this) \ - _singletonInstance = nullptr; \ - } - -//============================================================================== -/** - Macro to declare member variables and methods for a singleton class. - - This is like juce_DeclareSingleton_SingleThreaded, but doesn't do any checking - for recursion or repeated instantiation. It's intended for use as a lightweight - version of a singleton, where you're using it in very straightforward - circumstances and don't need the extra checking. - - Juce use the normal juce_ImplementSingleton_SingleThreaded as the counterpart - to this declaration, as you would with juce_DeclareSingleton_SingleThreaded. - - See the documentation for juce_DeclareSingleton for more information about - how to use it, the only difference being that you have to use - juce_ImplementSingleton_SingleThreaded instead of juce_ImplementSingleton. - - @see juce_ImplementSingleton_SingleThreaded, juce_DeclareSingleton -*/ -#define juce_DeclareSingleton_SingleThreaded_Minimal(classname) \ -\ - static classname* _singletonInstance; \ -\ - static classname* getInstance() \ - { \ - if (_singletonInstance == nullptr) \ - _singletonInstance = new classname(); \ -\ - return _singletonInstance; \ - } \ -\ - static inline classname* getInstanceWithoutCreating() noexcept\ - { \ - return _singletonInstance; \ - } \ -\ - static void deleteInstance() \ - { \ - if (_singletonInstance != nullptr) \ - { \ - classname* const old = _singletonInstance; \ - _singletonInstance = nullptr; \ - delete old; \ - } \ - } \ -\ - void clearSingletonInstance() noexcept\ - { \ - if (_singletonInstance == this) \ - _singletonInstance = nullptr; \ - } - - -//============================================================================== -/** This is a counterpart to the juce_DeclareSingleton_SingleThreaded macro. - - After adding juce_DeclareSingleton_SingleThreaded or juce_DeclareSingleton_SingleThreaded_Minimal - to the class definition, this macro has to be used somewhere in the cpp file. -*/ -#define juce_ImplementSingleton_SingleThreaded(classname) \ -\ - classname* classname::_singletonInstance = nullptr; - - - -#endif // JUCE_SINGLETON_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/memory/juce_WeakReference.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/memory/juce_WeakReference.h deleted file mode 100644 index c11b19f85c..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/memory/juce_WeakReference.h +++ /dev/null @@ -1,212 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_WEAKREFERENCE_H_INCLUDED -#define JUCE_WEAKREFERENCE_H_INCLUDED - - -//============================================================================== -/** - This class acts as a pointer which will automatically become null if the object - to which it points is deleted. - - To accomplish this, the source object needs to cooperate by performing a couple of simple tasks. - It must embed a WeakReference::Master object, which stores a shared pointer object, and must clear - this master pointer in its destructor. - - E.g. - @code - class MyObject - { - public: - MyObject() - { - // If you're planning on using your WeakReferences in a multi-threaded situation, you may choose - // to create a WeakReference to the object here in the constructor, which will pre-initialise the - // embedded object, avoiding an (extremely unlikely) race condition that could occur if multiple - // threads overlap while creating the first WeakReference to it. - } - - ~MyObject() - { - // This will zero all the references - you need to call this in your destructor. - masterReference.clear(); - } - - private: - // You need to embed a variable of this type, with the name "masterReference" inside your object. If the - // variable is not public, you should make your class a friend of WeakReference so that the - // WeakReference class can access it. - WeakReference::Master masterReference; - friend class WeakReference; - }; - - // Here's an example of using a pointer.. - - MyObject* n = new MyObject(); - WeakReference myObjectRef = n; - - MyObject* pointer1 = myObjectRef; // returns a valid pointer to 'n' - delete n; - MyObject* pointer2 = myObjectRef; // returns a null pointer - @endcode - - @see WeakReference::Master -*/ -template -class WeakReference -{ -public: - /** Creates a null SafePointer. */ - inline WeakReference() noexcept {} - - /** Creates a WeakReference that points at the given object. */ - WeakReference (ObjectType* const object) : holder (getRef (object)) {} - - /** Creates a copy of another WeakReference. */ - WeakReference (const WeakReference& other) noexcept : holder (other.holder) {} - - /** Copies another pointer to this one. */ - WeakReference& operator= (const WeakReference& other) { holder = other.holder; return *this; } - - /** Copies another pointer to this one. */ - WeakReference& operator= (ObjectType* const newObject) { holder = getRef (newObject); return *this; } - - #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS - WeakReference (WeakReference&& other) noexcept : holder (static_cast (other.holder)) {} - WeakReference& operator= (WeakReference&& other) noexcept { holder = static_cast (other.holder); return *this; } - #endif - - /** Returns the object that this pointer refers to, or null if the object no longer exists. */ - ObjectType* get() const noexcept { return holder != nullptr ? holder->get() : nullptr; } - - /** Returns the object that this pointer refers to, or null if the object no longer exists. */ - operator ObjectType*() const noexcept { return get(); } - - /** Returns the object that this pointer refers to, or null if the object no longer exists. */ - ObjectType* operator->() noexcept { return get(); } - - /** Returns the object that this pointer refers to, or null if the object no longer exists. */ - const ObjectType* operator->() const noexcept { return get(); } - - /** This returns true if this reference has been pointing at an object, but that object has - since been deleted. - - If this reference was only ever pointing at a null pointer, this will return false. Using - operator=() to make this refer to a different object will reset this flag to match the status - of the reference from which you're copying. - */ - bool wasObjectDeleted() const noexcept { return holder != nullptr && holder->get() == nullptr; } - - bool operator== (ObjectType* const object) const noexcept { return get() == object; } - bool operator!= (ObjectType* const object) const noexcept { return get() != object; } - - //============================================================================== - /** This class is used internally by the WeakReference class - don't use it directly - in your code! - @see WeakReference - */ - class SharedPointer : public ReferenceCountingType - { - public: - explicit SharedPointer (ObjectType* const obj) noexcept : owner (obj) {} - - inline ObjectType* get() const noexcept { return owner; } - void clearPointer() noexcept { owner = nullptr; } - - private: - ObjectType* volatile owner; - - JUCE_DECLARE_NON_COPYABLE (SharedPointer) - }; - - typedef ReferenceCountedObjectPtr SharedRef; - - //============================================================================== - /** - This class is embedded inside an object to which you want to attach WeakReference pointers. - See the WeakReference class notes for an example of how to use this class. - @see WeakReference - */ - class Master - { - public: - Master() noexcept {} - - ~Master() noexcept - { - // You must remember to call clear() in your source object's destructor! See the notes - // for the WeakReference class for an example of how to do this. - jassert (sharedPointer == nullptr || sharedPointer->get() == nullptr); - } - - /** The first call to this method will create an internal object that is shared by all weak - references to the object. - */ - SharedPointer* getSharedPointer (ObjectType* const object) - { - if (sharedPointer == nullptr) - { - sharedPointer = new SharedPointer (object); - } - else - { - // You're trying to create a weak reference to an object that has already been deleted!! - jassert (sharedPointer->get() != nullptr); - } - - return sharedPointer; - } - - /** The object that owns this master pointer should call this before it gets destroyed, - to zero all the references to this object that may be out there. See the WeakReference - class notes for an example of how to do this. - */ - void clear() noexcept - { - if (sharedPointer != nullptr) - sharedPointer->clearPointer(); - } - - private: - SharedRef sharedPointer; - - JUCE_DECLARE_NON_COPYABLE (Master) - }; - -private: - SharedRef holder; - - static inline SharedPointer* getRef (ObjectType* const o) - { - return (o != nullptr) ? o->masterReference.getSharedPointer (o) : nullptr; - } -}; - - -#endif // JUCE_WEAKREFERENCE_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/misc/juce_Result.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/misc/juce_Result.cpp deleted file mode 100644 index 1734907f5e..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/misc/juce_Result.cpp +++ /dev/null @@ -1,83 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -Result::Result() noexcept {} - -Result::Result (const String& message) noexcept - : errorMessage (message) -{ -} - -Result::Result (const Result& other) - : errorMessage (other.errorMessage) -{ -} - -Result& Result::operator= (const Result& other) -{ - errorMessage = other.errorMessage; - return *this; -} - -#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS -Result::Result (Result&& other) noexcept - : errorMessage (static_cast (other.errorMessage)) -{ -} - -Result& Result::operator= (Result&& other) noexcept -{ - errorMessage = static_cast (other.errorMessage); - return *this; -} -#endif - -bool Result::operator== (const Result& other) const noexcept -{ - return errorMessage == other.errorMessage; -} - -bool Result::operator!= (const Result& other) const noexcept -{ - return errorMessage != other.errorMessage; -} - -Result Result::fail (const String& errorMessage) noexcept -{ - return Result (errorMessage.isEmpty() ? "Unknown Error" : errorMessage); -} - -const String& Result::getErrorMessage() const noexcept -{ - return errorMessage; -} - -bool Result::wasOk() const noexcept { return errorMessage.isEmpty(); } -Result::operator bool() const noexcept { return errorMessage.isEmpty(); } -bool Result::failed() const noexcept { return errorMessage.isNotEmpty(); } -bool Result::operator!() const noexcept { return errorMessage.isNotEmpty(); } diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/misc/juce_Result.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/misc/juce_Result.h deleted file mode 100644 index 7c320ac336..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/misc/juce_Result.h +++ /dev/null @@ -1,125 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_RESULT_H_INCLUDED -#define JUCE_RESULT_H_INCLUDED - - -//============================================================================== -/** - Represents the 'success' or 'failure' of an operation, and holds an associated - error message to describe the error when there's a failure. - - E.g. - @code - Result myOperation() - { - if (doSomeKindOfFoobar()) - return Result::ok(); - else - return Result::fail ("foobar didn't work!"); - } - - const Result result (myOperation()); - - if (result.wasOk()) - { - ...it's all good... - } - else - { - warnUserAboutFailure ("The foobar operation failed! Error message was: " - + result.getErrorMessage()); - } - @endcode -*/ -class JUCE_API Result -{ -public: - //============================================================================== - /** Creates and returns a 'successful' result. */ - static Result ok() noexcept { return Result(); } - - /** Creates a 'failure' result. - If you pass a blank error message in here, a default "Unknown Error" message - will be used instead. - */ - static Result fail (const String& errorMessage) noexcept; - - //============================================================================== - /** Returns true if this result indicates a success. */ - bool wasOk() const noexcept; - - /** Returns true if this result indicates a failure. - You can use getErrorMessage() to retrieve the error message associated - with the failure. - */ - bool failed() const noexcept; - - /** Returns true if this result indicates a success. - This is equivalent to calling wasOk(). - */ - operator bool() const noexcept; - - /** Returns true if this result indicates a failure. - This is equivalent to calling failed(). - */ - bool operator!() const noexcept; - - /** Returns the error message that was set when this result was created. - For a successful result, this will be an empty string; - */ - const String& getErrorMessage() const noexcept; - - //============================================================================== - Result (const Result&); - Result& operator= (const Result&); - - #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS - Result (Result&&) noexcept; - Result& operator= (Result&&) noexcept; - #endif - - bool operator== (const Result& other) const noexcept; - bool operator!= (const Result& other) const noexcept; - -private: - String errorMessage; - - // The default constructor is not for public use! - // Instead, use Result::ok() or Result::fail() - Result() noexcept; - explicit Result (const String&) noexcept; - - // These casts are private to prevent people trying to use the Result object in numeric contexts - operator int() const; - operator void*() const; -}; - - -#endif // JUCE_RESULT_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/misc/juce_Uuid.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/misc/juce_Uuid.cpp deleted file mode 100644 index eb749643f6..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/misc/juce_Uuid.cpp +++ /dev/null @@ -1,117 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -Uuid::Uuid() -{ - Random r; - - for (size_t i = 0; i < sizeof (uuid); ++i) - uuid[i] = (uint8) (r.nextInt (256)); - - // To make it RFC 4122 compliant, need to force a few bits... - uuid[6] = (uuid[6] & 0x0f) | 0x40; - uuid[8] = (uuid[8] & 0x3f) | 0x80; -} - -Uuid::~Uuid() noexcept {} - -Uuid::Uuid (const Uuid& other) noexcept -{ - memcpy (uuid, other.uuid, sizeof (uuid)); -} - -Uuid& Uuid::operator= (const Uuid& other) noexcept -{ - memcpy (uuid, other.uuid, sizeof (uuid)); - return *this; -} - -bool Uuid::operator== (const Uuid& other) const noexcept { return memcmp (uuid, other.uuid, sizeof (uuid)) == 0; } -bool Uuid::operator!= (const Uuid& other) const noexcept { return ! operator== (other); } - -Uuid Uuid::null() noexcept -{ - return Uuid ((const uint8*) nullptr); -} - -bool Uuid::isNull() const noexcept -{ - for (size_t i = 0; i < sizeof (uuid); ++i) - if (uuid[i] != 0) - return false; - - return true; -} - -String Uuid::getHexRegion (int start, int length) const -{ - return String::toHexString (uuid + start, length, 0); -} - -String Uuid::toString() const -{ - return getHexRegion (0, 16); -} - -String Uuid::toDashedString() const -{ - return getHexRegion (0, 4) - + "-" + getHexRegion (4, 2) - + "-" + getHexRegion (6, 2) - + "-" + getHexRegion (8, 2) - + "-" + getHexRegion (10, 6); -} - -Uuid::Uuid (const String& uuidString) -{ - operator= (uuidString); -} - -Uuid& Uuid::operator= (const String& uuidString) -{ - MemoryBlock mb; - mb.loadFromHexString (uuidString); - mb.ensureSize (sizeof (uuid), true); - mb.copyTo (uuid, 0, sizeof (uuid)); - return *this; -} - -Uuid::Uuid (const uint8* const rawData) noexcept -{ - operator= (rawData); -} - -Uuid& Uuid::operator= (const uint8* const rawData) noexcept -{ - if (rawData != nullptr) - memcpy (uuid, rawData, sizeof (uuid)); - else - zeromem (uuid, sizeof (uuid)); - - return *this; -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/misc/juce_Uuid.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/misc/juce_Uuid.h deleted file mode 100644 index cd7af0dbc5..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/misc/juce_Uuid.h +++ /dev/null @@ -1,121 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_UUID_H_INCLUDED -#define JUCE_UUID_H_INCLUDED - - -//============================================================================== -/** - A universally unique 128-bit identifier. - - This class generates very random unique numbers. It's vanishingly unlikely - that two identical UUIDs would ever be created by chance. The values are - formatted to meet the RFC 4122 version 4 standard. - - The class includes methods for saving the ID as a string or as raw binary data. -*/ -class JUCE_API Uuid -{ -public: - //============================================================================== - /** Creates a new unique ID, compliant with RFC 4122 version 4. */ - Uuid(); - - /** Destructor. */ - ~Uuid() noexcept; - - /** Creates a copy of another UUID. */ - Uuid (const Uuid&) noexcept; - - /** Copies another UUID. */ - Uuid& operator= (const Uuid&) noexcept; - - //============================================================================== - /** Returns true if the ID is zero. */ - bool isNull() const noexcept; - - /** Returns a null Uuid object. */ - static Uuid null() noexcept; - - bool operator== (const Uuid&) const noexcept; - bool operator!= (const Uuid&) const noexcept; - - //============================================================================== - /** Returns a stringified version of this UUID. - - A Uuid object can later be reconstructed from this string using operator= or - the constructor that takes a string parameter. - - @returns a 32 character hex string. - */ - String toString() const; - - /** Returns a stringified version of this UUID, separating it into sections with dashes. - @returns a string in the format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx - */ - String toDashedString() const; - - /** Creates an ID from an encoded string version. - @see toString - */ - Uuid (const String& uuidString); - - /** Copies from a stringified UUID. - The string passed in should be one that was created with the toString() method. - */ - Uuid& operator= (const String& uuidString); - - - //============================================================================== - /** Returns a pointer to the internal binary representation of the ID. - - This is an array of 16 bytes. To reconstruct a Uuid from its data, use - the constructor or operator= method that takes an array of uint8s. - */ - const uint8* getRawData() const noexcept { return uuid; } - - /** Creates a UUID from a 16-byte array. - @see getRawData - */ - Uuid (const uint8* rawData) noexcept; - - /** Sets this UUID from 16-bytes of raw data. */ - Uuid& operator= (const uint8* rawData) noexcept; - - -private: - //============================================================================== - uint8 uuid[16]; - String getHexRegion (int, int) const; - - JUCE_LEAK_DETECTOR (Uuid) -}; - - -#endif // JUCE_UUID_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/misc/juce_WindowsRegistry.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/misc/juce_WindowsRegistry.h deleted file mode 100644 index a1fb2a25c5..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/misc/juce_WindowsRegistry.h +++ /dev/null @@ -1,141 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_WINDOWSREGISTRY_H_INCLUDED -#define JUCE_WINDOWSREGISTRY_H_INCLUDED - -#if JUCE_WINDOWS || DOXYGEN - -/** - Contains some static helper functions for manipulating the MS Windows registry - (Only available on Windows, of course!) -*/ -class JUCE_API WindowsRegistry -{ -public: - /** These values can be used to specify whether the 32- or 64-bit registry should be used. - When running on a 32-bit OS, there is no 64-bit registry, so the mode will be ignored. - */ - enum WoW64Mode - { - /** Default handling: 32-bit apps will use the 32-bit registry, and 64-bit apps - will use the 64-bit registry. */ - WoW64_Default = 0, - - /** Always use the 64-bit registry store. (KEY_WOW64_64KEY). */ - WoW64_64bit = 0x100, - - /** Always use the 32-bit registry store. (KEY_WOW64_32KEY). */ - WoW64_32bit = 0x200 - }; - - //============================================================================== - /** Returns a string from the registry. - The path is a string for the entire path of a value in the registry, - e.g. "HKEY_CURRENT_USER\Software\foo\bar" - */ - static String JUCE_CALLTYPE getValue (const String& regValuePath, - const String& defaultValue = String::empty, - WoW64Mode mode = WoW64_Default); - - /** Reads a binary block from the registry. - The path is a string for the entire path of a value in the registry, - e.g. "HKEY_CURRENT_USER\Software\foo\bar" - @returns a DWORD indicating the type of the key. - */ - static uint32 JUCE_CALLTYPE getBinaryValue (const String& regValuePath, MemoryBlock& resultData, WoW64Mode mode = WoW64_Default); - - /** Sets a registry value as a string. - This will take care of creating any groups needed to get to the given registry value. - */ - static bool JUCE_CALLTYPE setValue (const String& regValuePath, const String& value, WoW64Mode mode = WoW64_Default); - - /** Sets a registry value as a DWORD. - This will take care of creating any groups needed to get to the given registry value. - */ - static bool JUCE_CALLTYPE setValue (const String& regValuePath, uint32 value, WoW64Mode mode = WoW64_Default); - - /** Sets a registry value as a QWORD. - This will take care of creating any groups needed to get to the given registry value. - */ - static bool JUCE_CALLTYPE setValue (const String& regValuePath, uint64 value, WoW64Mode mode = WoW64_Default); - - /** Sets a registry value as a binary block. - This will take care of creating any groups needed to get to the given registry value. - */ - static bool JUCE_CALLTYPE setValue (const String& regValuePath, const MemoryBlock& value, WoW64Mode mode = WoW64_Default); - - /** Returns true if the given value exists in the registry. */ - static bool JUCE_CALLTYPE valueExists (const String& regValuePath, WoW64Mode mode = WoW64_Default); - - /** Returns true if the given key exists in the registry. */ - static bool JUCE_CALLTYPE keyExists (const String& regValuePath, WoW64Mode mode = WoW64_Default); - - /** Deletes a registry value. */ - static void JUCE_CALLTYPE deleteValue (const String& regValuePath, WoW64Mode mode = WoW64_Default); - - /** Deletes a registry key (which is registry-talk for 'folder'). */ - static void JUCE_CALLTYPE deleteKey (const String& regKeyPath, WoW64Mode mode = WoW64_Default); - - /** Creates a file association in the registry. - - This lets you set the executable that should be launched by a given file extension. - @param fileExtension the file extension to associate, including the - initial dot, e.g. ".txt" - @param symbolicDescription a space-free short token to identify the file type - @param fullDescription a human-readable description of the file type - @param targetExecutable the executable that should be launched - @param iconResourceNumber the icon that gets displayed for the file type will be - found by looking up this resource number in the - executable. Pass 0 here to not use an icon - @param registerForCurrentUserOnly if false, this will try to register the association - for all users (you might not have permission to do this - unless running in an installer). If true, it will register the - association in HKEY_CURRENT_USER. - @param mode the WoW64 mode to use for choosing the database - */ - static bool JUCE_CALLTYPE registerFileAssociation (const String& fileExtension, - const String& symbolicDescription, - const String& fullDescription, - const File& targetExecutable, - int iconResourceNumber, - bool registerForCurrentUserOnly, - WoW64Mode mode = WoW64_Default); - - // DEPRECATED: use the other methods with a WoW64Mode parameter of WoW64_64bit instead. - JUCE_DEPRECATED (static String getValueWow64 (const String&, const String& defaultValue = String::empty)); - JUCE_DEPRECATED (static bool valueExistsWow64 (const String&)); - JUCE_DEPRECATED (static bool keyExistsWow64 (const String&)); - -private: - WindowsRegistry() JUCE_DELETED_FUNCTION; - JUCE_DECLARE_NON_COPYABLE (WindowsRegistry) -}; - -#endif -#endif // JUCE_WINDOWSREGISTRY_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/native/juce_BasicNativeHeaders.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/native/juce_BasicNativeHeaders.h deleted file mode 100644 index cdaa0eff3b..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/native/juce_BasicNativeHeaders.h +++ /dev/null @@ -1,223 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_BASICNATIVEHEADERS_H_INCLUDED -#define JUCE_BASICNATIVEHEADERS_H_INCLUDED - -#include "../system/juce_TargetPlatform.h" -#undef T - -//============================================================================== -#if JUCE_MAC || JUCE_IOS - - #if JUCE_IOS - #import - #import - #import - #import - #include - #else - #define Point CarbonDummyPointName - #define Component CarbonDummyCompName - #import - #import - #undef Point - #undef Component - #include - #endif - - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - -//============================================================================== -#elif JUCE_WINDOWS - #if JUCE_MSVC - #ifndef _CPPRTTI - #error "You're compiling without RTTI enabled! This is needed for a lot of JUCE classes, please update your compiler settings!" - #endif - - #ifndef _CPPUNWIND - #error "You're compiling without exceptions enabled! This is needed for a lot of JUCE classes, please update your compiler settings!" - #endif - - #pragma warning (push) - #pragma warning (disable : 4100 4201 4514 4312 4995) - #endif - - #define STRICT 1 - #define WIN32_LEAN_AND_MEAN 1 - #if JUCE_MINGW - #define _WIN32_WINNT 0x0501 - #else - #define _WIN32_WINNT 0x0600 - #endif - #define _UNICODE 1 - #define UNICODE 1 - #ifndef _WIN32_IE - #define _WIN32_IE 0x0500 - #endif - - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - - #if JUCE_MINGW - #include - #else - #include - #include - #endif - - #undef PACKED - - #if JUCE_MSVC - #pragma warning (pop) - #pragma warning (4: 4511 4512 4100 /*4365*/) // (enable some warnings that are turned off in VC8) - #endif - - #if JUCE_MSVC && ! JUCE_DONT_AUTOLINK_TO_WIN32_LIBRARIES - #pragma comment (lib, "kernel32.lib") - #pragma comment (lib, "user32.lib") - #pragma comment (lib, "wininet.lib") - #pragma comment (lib, "advapi32.lib") - #pragma comment (lib, "ws2_32.lib") - #pragma comment (lib, "version.lib") - #pragma comment (lib, "shlwapi.lib") - #pragma comment (lib, "winmm.lib") - - #ifdef _NATIVE_WCHAR_T_DEFINED - #ifdef _DEBUG - #pragma comment (lib, "comsuppwd.lib") - #else - #pragma comment (lib, "comsuppw.lib") - #endif - #else - #ifdef _DEBUG - #pragma comment (lib, "comsuppd.lib") - #else - #pragma comment (lib, "comsupp.lib") - #endif - #endif - #endif - - /* Used with DynamicLibrary to simplify importing functions from a win32 DLL. - - dll: the DynamicLibrary object - functionName: function to import - localFunctionName: name you want to use to actually call it (must be different) - returnType: the return type - params: list of params (bracketed) - */ - #define JUCE_LOAD_WINAPI_FUNCTION(dll, functionName, localFunctionName, returnType, params) \ - typedef returnType (WINAPI *type##localFunctionName) params; \ - type##localFunctionName localFunctionName = (type##localFunctionName) dll.getFunction (#functionName); - -//============================================================================== -#elif JUCE_LINUX - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - -//============================================================================== -#elif JUCE_ANDROID - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include -#endif - -// Need to clear various moronic redefinitions made by system headers.. -#undef max -#undef min -#undef direct -#undef check - -#endif // JUCE_BASICNATIVEHEADERS_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/native/juce_android_Files.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/native/juce_android_Files.cpp deleted file mode 100644 index 45903b15c9..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/native/juce_android_Files.cpp +++ /dev/null @@ -1,104 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -bool File::isOnCDRomDrive() const -{ - return false; -} - -bool File::isOnHardDisk() const -{ - return true; -} - -bool File::isOnRemovableDrive() const -{ - return false; -} - -String File::getVersion() const -{ - return String::empty; -} - -File File::getSpecialLocation (const SpecialLocationType type) -{ - switch (type) - { - case userHomeDirectory: - case userDocumentsDirectory: - case userMusicDirectory: - case userMoviesDirectory: - case userPicturesDirectory: - case userApplicationDataDirectory: - case userDesktopDirectory: - return File (android.appDataDir); - - case commonApplicationDataDirectory: - case commonDocumentsDirectory: - return File (android.appDataDir); - - case globalApplicationsDirectory: - return File ("/system/app"); - - case tempDirectory: - return File (android.appDataDir).getChildFile (".temp"); - - case invokedExecutableFile: - case currentExecutableFile: - case currentApplicationFile: - case hostApplicationPath: - return juce_getExecutableFile(); - - default: - jassertfalse; // unknown type? - break; - } - - return File(); -} - -bool File::moveToTrash() const -{ - if (! exists()) - return true; - - // TODO - return false; -} - -JUCE_API bool JUCE_CALLTYPE Process::openDocument (const String& fileName, const String& parameters) -{ - const LocalRef t (javaString (fileName)); - android.activity.callVoidMethod (JuceAppActivity.launchURL, t.get()); - return true; -} - -void File::revealToUser() const -{ -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/native/juce_android_JNIHelpers.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/native/juce_android_JNIHelpers.h deleted file mode 100644 index 8e8b07d3ad..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/native/juce_android_JNIHelpers.h +++ /dev/null @@ -1,428 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_ANDROID_JNIHELPERS_H_INCLUDED -#define JUCE_ANDROID_JNIHELPERS_H_INCLUDED - -#if ! (defined (JUCE_ANDROID_ACTIVITY_CLASSNAME) && defined (JUCE_ANDROID_ACTIVITY_CLASSPATH)) - #error "The JUCE_ANDROID_ACTIVITY_CLASSNAME and JUCE_ANDROID_ACTIVITY_CLASSPATH macros must be set!" -#endif - -//============================================================================== -extern JNIEnv* getEnv() noexcept; - -//============================================================================== -class GlobalRef -{ -public: - inline GlobalRef() noexcept : obj (0) {} - inline explicit GlobalRef (jobject o) : obj (retain (o)) {} - inline GlobalRef (const GlobalRef& other) : obj (retain (other.obj)) {} - ~GlobalRef() { clear(); } - - inline void clear() - { - if (obj != 0) - { - getEnv()->DeleteGlobalRef (obj); - obj = 0; - } - } - - inline GlobalRef& operator= (const GlobalRef& other) - { - jobject newObj = retain (other.obj); - clear(); - obj = newObj; - return *this; - } - - //============================================================================== - inline operator jobject() const noexcept { return obj; } - inline jobject get() const noexcept { return obj; } - - //============================================================================== - #define DECLARE_CALL_TYPE_METHOD(returnType, typeName) \ - returnType call##typeName##Method (jmethodID methodID, ... ) const \ - { \ - va_list args; \ - va_start (args, methodID); \ - returnType result = getEnv()->Call##typeName##MethodV (obj, methodID, args); \ - va_end (args); \ - return result; \ - } - - DECLARE_CALL_TYPE_METHOD (jobject, Object) - DECLARE_CALL_TYPE_METHOD (jboolean, Boolean) - DECLARE_CALL_TYPE_METHOD (jbyte, Byte) - DECLARE_CALL_TYPE_METHOD (jchar, Char) - DECLARE_CALL_TYPE_METHOD (jshort, Short) - DECLARE_CALL_TYPE_METHOD (jint, Int) - DECLARE_CALL_TYPE_METHOD (jlong, Long) - DECLARE_CALL_TYPE_METHOD (jfloat, Float) - DECLARE_CALL_TYPE_METHOD (jdouble, Double) - #undef DECLARE_CALL_TYPE_METHOD - - void callVoidMethod (jmethodID methodID, ... ) const - { - va_list args; - va_start (args, methodID); - getEnv()->CallVoidMethodV (obj, methodID, args); - va_end (args); - } - -private: - //============================================================================== - jobject obj; - - static inline jobject retain (jobject obj) - { - return obj == 0 ? 0 : getEnv()->NewGlobalRef (obj); - } -}; - -//============================================================================== -template -class LocalRef -{ -public: - explicit inline LocalRef (JavaType o) noexcept : obj (o) {} - inline LocalRef (const LocalRef& other) noexcept : obj (retain (other.obj)) {} - ~LocalRef() { clear(); } - - void clear() - { - if (obj != 0) - getEnv()->DeleteLocalRef (obj); - } - - LocalRef& operator= (const LocalRef& other) - { - jobject newObj = retain (other.obj); - clear(); - obj = newObj; - return *this; - } - - inline operator JavaType() const noexcept { return obj; } - inline JavaType get() const noexcept { return obj; } - -private: - JavaType obj; - - static JavaType retain (JavaType obj) - { - return obj == 0 ? 0 : (JavaType) getEnv()->NewLocalRef (obj); - } -}; - -//============================================================================== -namespace -{ - String juceString (JNIEnv* env, jstring s) - { - const char* const utf8 = env->GetStringUTFChars (s, nullptr); - CharPointer_UTF8 utf8CP (utf8); - const String result (utf8CP); - env->ReleaseStringUTFChars (s, utf8); - return result; - } - - String juceString (jstring s) - { - return juceString (getEnv(), s); - } - - LocalRef javaString (const String& s) - { - return LocalRef (getEnv()->NewStringUTF (s.toUTF8())); - } - - LocalRef javaStringFromChar (const juce_wchar c) - { - char utf8[8] = { 0 }; - CharPointer_UTF8 (utf8).write (c); - return LocalRef (getEnv()->NewStringUTF (utf8)); - } -} - -//============================================================================== -class JNIClassBase -{ -public: - explicit JNIClassBase (const char* classPath); - virtual ~JNIClassBase(); - - inline operator jclass() const noexcept { return classRef; } - - static void initialiseAllClasses (JNIEnv*); - static void releaseAllClasses (JNIEnv*); - -protected: - virtual void initialiseFields (JNIEnv*) = 0; - - jmethodID resolveMethod (JNIEnv*, const char* methodName, const char* params); - jmethodID resolveStaticMethod (JNIEnv*, const char* methodName, const char* params); - jfieldID resolveField (JNIEnv*, const char* fieldName, const char* signature); - jfieldID resolveStaticField (JNIEnv*, const char* fieldName, const char* signature); - -private: - const char* const classPath; - jclass classRef; - - static Array& getClasses(); - void initialise (JNIEnv*); - void release (JNIEnv*); - - JUCE_DECLARE_NON_COPYABLE (JNIClassBase) -}; - -//============================================================================== -#define CREATE_JNI_METHOD(methodID, stringName, params) methodID = resolveMethod (env, stringName, params); -#define CREATE_JNI_STATICMETHOD(methodID, stringName, params) methodID = resolveStaticMethod (env, stringName, params); -#define CREATE_JNI_FIELD(fieldID, stringName, signature) fieldID = resolveField (env, stringName, signature); -#define CREATE_JNI_STATICFIELD(fieldID, stringName, signature) fieldID = resolveStaticField (env, stringName, signature); -#define DECLARE_JNI_METHOD(methodID, stringName, params) jmethodID methodID; -#define DECLARE_JNI_FIELD(fieldID, stringName, signature) jfieldID fieldID; - -#define DECLARE_JNI_CLASS(CppClassName, javaPath) \ - class CppClassName ## _Class : public JNIClassBase \ - { \ - public: \ - CppClassName ## _Class() : JNIClassBase (javaPath) {} \ - \ - void initialiseFields (JNIEnv* env) \ - { \ - JNI_CLASS_MEMBERS (CREATE_JNI_METHOD, CREATE_JNI_STATICMETHOD, CREATE_JNI_FIELD, CREATE_JNI_STATICFIELD); \ - } \ - \ - JNI_CLASS_MEMBERS (DECLARE_JNI_METHOD, DECLARE_JNI_METHOD, DECLARE_JNI_FIELD, DECLARE_JNI_FIELD); \ - }; \ - static CppClassName ## _Class CppClassName; - - -//============================================================================== -#define JUCE_JNI_CALLBACK(className, methodName, returnType, params) \ - extern "C" __attribute__ ((visibility("default"))) returnType JUCE_JOIN_MACRO (JUCE_JOIN_MACRO (Java_, className), _ ## methodName) params - -//============================================================================== -class AndroidSystem -{ -public: - AndroidSystem(); - - void initialise (JNIEnv*, jobject activity, jstring appFile, jstring appDataDir); - void shutdown (JNIEnv*); - - //============================================================================== - GlobalRef activity; - String appFile, appDataDir; - int screenWidth, screenHeight, dpi; -}; - -extern AndroidSystem android; - -//============================================================================== -class ThreadLocalJNIEnvHolder -{ -public: - ThreadLocalJNIEnvHolder() noexcept - : jvm (nullptr) - { - zeromem (threads, sizeof (threads)); - zeromem (envs, sizeof (envs)); - } - - void initialise (JNIEnv* env) - { - // NB: the DLL can be left loaded by the JVM, so the same static - // objects can end up being reused by subsequent runs of the app - zeromem (threads, sizeof (threads)); - zeromem (envs, sizeof (envs)); - - env->GetJavaVM (&jvm); - addEnv (env); - } - - JNIEnv* attach() noexcept - { - if (android.activity != nullptr) - { - if (JNIEnv* env = attachToCurrentThread()) - { - SpinLock::ScopedLockType sl (addRemoveLock); - return addEnv (env); - } - - jassertfalse; - } - - return nullptr; - } - - void detach() noexcept - { - if (android.activity != nullptr) - { - jvm->DetachCurrentThread(); - - const pthread_t thisThread = pthread_self(); - - SpinLock::ScopedLockType sl (addRemoveLock); - for (int i = 0; i < maxThreads; ++i) - if (threads[i] == thisThread) - threads[i] = 0; - } - } - - JNIEnv* getOrAttach() noexcept - { - if (JNIEnv* env = get()) - return env; - - SpinLock::ScopedLockType sl (addRemoveLock); - - if (JNIEnv* env = get()) - return env; - - if (JNIEnv* env = attachToCurrentThread()) - return addEnv (env); - - return nullptr; - } - -private: - JavaVM* jvm; - enum { maxThreads = 32 }; - pthread_t threads [maxThreads]; - JNIEnv* envs [maxThreads]; - SpinLock addRemoveLock; - - JNIEnv* addEnv (JNIEnv* env) noexcept - { - const pthread_t thisThread = pthread_self(); - - for (int i = 0; i < maxThreads; ++i) - { - if (threads[i] == 0) - { - envs[i] = env; - threads[i] = thisThread; - return env; - } - } - - jassertfalse; // too many threads! - return nullptr; - } - - JNIEnv* get() const noexcept - { - const pthread_t thisThread = pthread_self(); - - for (int i = 0; i < maxThreads; ++i) - if (threads[i] == thisThread) - return envs[i]; - - return nullptr; - } - - JNIEnv* attachToCurrentThread() - { - JNIEnv* env = nullptr; - jvm->AttachCurrentThread (&env, nullptr); - return env; - } -}; - -extern ThreadLocalJNIEnvHolder threadLocalJNIEnvHolder; - -struct AndroidThreadScope -{ - AndroidThreadScope() { threadLocalJNIEnvHolder.attach(); } - ~AndroidThreadScope() { threadLocalJNIEnvHolder.detach(); } -}; - -//============================================================================== -#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD) \ - METHOD (createNewView, "createNewView", "(ZJ)L" JUCE_ANDROID_ACTIVITY_CLASSPATH "$ComponentPeerView;") \ - METHOD (deleteView, "deleteView", "(L" JUCE_ANDROID_ACTIVITY_CLASSPATH "$ComponentPeerView;)V") \ - METHOD (postMessage, "postMessage", "(J)V") \ - METHOD (finish, "finish", "()V") \ - METHOD (getClipboardContent, "getClipboardContent", "()Ljava/lang/String;") \ - METHOD (setClipboardContent, "setClipboardContent", "(Ljava/lang/String;)V") \ - METHOD (excludeClipRegion, "excludeClipRegion", "(Landroid/graphics/Canvas;FFFF)V") \ - METHOD (renderGlyph, "renderGlyph", "(CLandroid/graphics/Paint;Landroid/graphics/Matrix;Landroid/graphics/Rect;)[I") \ - STATICMETHOD (createHTTPStream, "createHTTPStream", "(Ljava/lang/String;Z[BLjava/lang/String;I[ILjava/lang/StringBuffer;)L" JUCE_ANDROID_ACTIVITY_CLASSPATH "$HTTPStream;") \ - METHOD (launchURL, "launchURL", "(Ljava/lang/String;)V") \ - METHOD (showMessageBox, "showMessageBox", "(Ljava/lang/String;Ljava/lang/String;J)V") \ - METHOD (showOkCancelBox, "showOkCancelBox", "(Ljava/lang/String;Ljava/lang/String;J)V") \ - METHOD (showYesNoCancelBox, "showYesNoCancelBox", "(Ljava/lang/String;Ljava/lang/String;J)V") \ - STATICMETHOD (getLocaleValue, "getLocaleValue", "(Z)Ljava/lang/String;") \ - METHOD (scanFile, "scanFile", "(Ljava/lang/String;)V") - -DECLARE_JNI_CLASS (JuceAppActivity, JUCE_ANDROID_ACTIVITY_CLASSPATH); -#undef JNI_CLASS_MEMBERS - -//============================================================================== -#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD) \ - METHOD (constructor, "", "(I)V") \ - METHOD (setColor, "setColor", "(I)V") \ - METHOD (setAlpha, "setAlpha", "(I)V") \ - METHOD (setTypeface, "setTypeface", "(Landroid/graphics/Typeface;)Landroid/graphics/Typeface;") \ - METHOD (ascent, "ascent", "()F") \ - METHOD (descent, "descent", "()F") \ - METHOD (setTextSize, "setTextSize", "(F)V") \ - METHOD (getTextWidths, "getTextWidths", "(Ljava/lang/String;[F)I") \ - METHOD (setTextScaleX, "setTextScaleX", "(F)V") \ - METHOD (getTextPath, "getTextPath", "(Ljava/lang/String;IIFFLandroid/graphics/Path;)V") \ - METHOD (setShader, "setShader", "(Landroid/graphics/Shader;)Landroid/graphics/Shader;") \ - -DECLARE_JNI_CLASS (Paint, "android/graphics/Paint"); -#undef JNI_CLASS_MEMBERS - -//============================================================================== -#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD) \ - METHOD (constructor, "", "()V") \ - METHOD (setValues, "setValues", "([F)V") \ - -DECLARE_JNI_CLASS (Matrix, "android/graphics/Matrix"); -#undef JNI_CLASS_MEMBERS - -//============================================================================== -#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD) \ - METHOD (constructor, "", "(IIII)V") \ - FIELD (left, "left", "I") \ - FIELD (right, "right", "I") \ - FIELD (top, "top", "I") \ - FIELD (bottom, "bottom", "I") \ - -DECLARE_JNI_CLASS (RectClass, "android/graphics/Rect"); -#undef JNI_CLASS_MEMBERS - -#endif // JUCE_ANDROID_JNIHELPERS_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/native/juce_android_Misc.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/native/juce_android_Misc.cpp deleted file mode 100644 index d26adc185e..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/native/juce_android_Misc.cpp +++ /dev/null @@ -1,32 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -void Logger::outputDebugString (const String& text) -{ - __android_log_print (ANDROID_LOG_INFO, "JUCE", "%s", text.toUTF8().getAddress()); -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/native/juce_android_Network.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/native/juce_android_Network.cpp deleted file mode 100644 index 29a8cb5919..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/native/juce_android_Network.cpp +++ /dev/null @@ -1,181 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -//============================================================================== -#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD) \ - METHOD (constructor, "", "()V") \ - METHOD (toString, "toString", "()Ljava/lang/String;") \ - -DECLARE_JNI_CLASS (StringBuffer, "java/lang/StringBuffer"); -#undef JNI_CLASS_MEMBERS - -//============================================================================== -#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD) \ - METHOD (release, "release", "()V") \ - METHOD (read, "read", "([BI)I") \ - METHOD (getPosition, "getPosition", "()J") \ - METHOD (getTotalLength, "getTotalLength", "()J") \ - METHOD (isExhausted, "isExhausted", "()Z") \ - METHOD (setPosition, "setPosition", "(J)Z") \ - -DECLARE_JNI_CLASS (HTTPStream, JUCE_ANDROID_ACTIVITY_CLASSPATH "$HTTPStream"); -#undef JNI_CLASS_MEMBERS - - -//============================================================================== -void MACAddress::findAllAddresses (Array& result) -{ - // TODO -} - - -JUCE_API bool JUCE_CALLTYPE Process::openEmailWithAttachments (const String& targetEmailAddress, - const String& emailSubject, - const String& bodyText, - const StringArray& filesToAttach) -{ - // TODO - return false; -} - - -//============================================================================== -class WebInputStream : public InputStream -{ -public: - WebInputStream (String address, bool isPost, const MemoryBlock& postData, - URL::OpenStreamProgressCallback* progressCallback, void* progressCallbackContext, - const String& headers, int timeOutMs, StringPairArray* responseHeaders) - : statusCode (0) - { - if (! address.contains ("://")) - address = "http://" + address; - - JNIEnv* env = getEnv(); - - jbyteArray postDataArray = 0; - - if (postData.getSize() > 0) - { - postDataArray = env->NewByteArray (postData.getSize()); - env->SetByteArrayRegion (postDataArray, 0, postData.getSize(), (const jbyte*) postData.getData()); - } - - LocalRef responseHeaderBuffer (env->NewObject (StringBuffer, StringBuffer.constructor)); - - // Annoyingly, the android HTTP functions will choke on this call if you try to do it on the message - // thread. You'll need to move your networking code to a background thread to keep it happy.. - jassert (Thread::getCurrentThread() != nullptr); - - jintArray statusCodeArray = env->NewIntArray (1); - jassert (statusCodeArray != 0); - - stream = GlobalRef (env->CallStaticObjectMethod (JuceAppActivity, - JuceAppActivity.createHTTPStream, - javaString (address).get(), - (jboolean) isPost, - postDataArray, - javaString (headers).get(), - (jint) timeOutMs, - statusCodeArray, - responseHeaderBuffer.get())); - - jint* const statusCodeElements = env->GetIntArrayElements (statusCodeArray, 0); - statusCode = statusCodeElements[0]; - env->ReleaseIntArrayElements (statusCodeArray, statusCodeElements, 0); - env->DeleteLocalRef (statusCodeArray); - - if (postDataArray != 0) - env->DeleteLocalRef (postDataArray); - - if (stream != 0) - { - StringArray headerLines; - - { - LocalRef headersString ((jstring) env->CallObjectMethod (responseHeaderBuffer.get(), - StringBuffer.toString)); - headerLines.addLines (juceString (env, headersString)); - } - - if (responseHeaders != 0) - { - for (int i = 0; i < headerLines.size(); ++i) - { - const String& header = headerLines[i]; - const String key (header.upToFirstOccurrenceOf (": ", false, false)); - const String value (header.fromFirstOccurrenceOf (": ", false, false)); - const String previousValue ((*responseHeaders) [key]); - - responseHeaders->set (key, previousValue.isEmpty() ? value : (previousValue + "," + value)); - } - } - } - } - - ~WebInputStream() - { - if (stream != 0) - stream.callVoidMethod (HTTPStream.release); - } - - //============================================================================== - bool isError() const { return stream == nullptr; } - - bool isExhausted() override { return stream != nullptr && stream.callBooleanMethod (HTTPStream.isExhausted); } - int64 getTotalLength() override { return stream != nullptr ? stream.callLongMethod (HTTPStream.getTotalLength) : 0; } - int64 getPosition() override { return stream != nullptr ? stream.callLongMethod (HTTPStream.getPosition) : 0; } - bool setPosition (int64 wantedPos) override { return stream != nullptr && stream.callBooleanMethod (HTTPStream.setPosition, (jlong) wantedPos); } - - int read (void* buffer, int bytesToRead) override - { - jassert (buffer != nullptr && bytesToRead >= 0); - - if (stream == nullptr) - return 0; - - JNIEnv* env = getEnv(); - - jbyteArray javaArray = env->NewByteArray (bytesToRead); - - int numBytes = stream.callIntMethod (HTTPStream.read, javaArray, (jint) bytesToRead); - - if (numBytes > 0) - env->GetByteArrayRegion (javaArray, 0, numBytes, static_cast (buffer)); - - env->DeleteLocalRef (javaArray); - return numBytes; - } - - //============================================================================== - GlobalRef stream; - int statusCode; - -private: - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (WebInputStream) -}; diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/native/juce_android_SystemStats.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/native/juce_android_SystemStats.cpp deleted file mode 100644 index 8223b892c5..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/native/juce_android_SystemStats.cpp +++ /dev/null @@ -1,315 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -JNIClassBase::JNIClassBase (const char* cp) : classPath (cp), classRef (0) -{ - getClasses().add (this); -} - -JNIClassBase::~JNIClassBase() -{ - getClasses().removeFirstMatchingValue (this); -} - -Array& JNIClassBase::getClasses() -{ - static Array classes; - return classes; -} - -void JNIClassBase::initialise (JNIEnv* env) -{ - classRef = (jclass) env->NewGlobalRef (env->FindClass (classPath)); - jassert (classRef != 0); - - initialiseFields (env); -} - -void JNIClassBase::release (JNIEnv* env) -{ - env->DeleteGlobalRef (classRef); -} - -void JNIClassBase::initialiseAllClasses (JNIEnv* env) -{ - const Array& classes = getClasses(); - for (int i = classes.size(); --i >= 0;) - classes.getUnchecked(i)->initialise (env); -} - -void JNIClassBase::releaseAllClasses (JNIEnv* env) -{ - const Array& classes = getClasses(); - for (int i = classes.size(); --i >= 0;) - classes.getUnchecked(i)->release (env); -} - -jmethodID JNIClassBase::resolveMethod (JNIEnv* env, const char* methodName, const char* params) -{ - jmethodID m = env->GetMethodID (classRef, methodName, params); - jassert (m != 0); - return m; -} - -jmethodID JNIClassBase::resolveStaticMethod (JNIEnv* env, const char* methodName, const char* params) -{ - jmethodID m = env->GetStaticMethodID (classRef, methodName, params); - jassert (m != 0); - return m; -} - -jfieldID JNIClassBase::resolveField (JNIEnv* env, const char* fieldName, const char* signature) -{ - jfieldID f = env->GetFieldID (classRef, fieldName, signature); - jassert (f != 0); - return f; -} - -jfieldID JNIClassBase::resolveStaticField (JNIEnv* env, const char* fieldName, const char* signature) -{ - jfieldID f = env->GetStaticFieldID (classRef, fieldName, signature); - jassert (f != 0); - return f; -} - -//============================================================================== -ThreadLocalJNIEnvHolder threadLocalJNIEnvHolder; - -#if JUCE_DEBUG -static bool systemInitialised = false; -#endif - -JNIEnv* getEnv() noexcept -{ - #if JUCE_DEBUG - if (! systemInitialised) - { - DBG ("*** Call to getEnv() when system not initialised"); - jassertfalse; - std::exit (EXIT_FAILURE); - } - #endif - - return threadLocalJNIEnvHolder.getOrAttach(); -} - -extern "C" jint JNI_OnLoad (JavaVM*, void*) -{ - return JNI_VERSION_1_2; -} - -//============================================================================== -AndroidSystem::AndroidSystem() : screenWidth (0), screenHeight (0), dpi (160) -{ -} - -void AndroidSystem::initialise (JNIEnv* env, jobject act, jstring file, jstring dataDir) -{ - screenWidth = screenHeight = 0; - dpi = 160; - JNIClassBase::initialiseAllClasses (env); - - threadLocalJNIEnvHolder.initialise (env); - #if JUCE_DEBUG - systemInitialised = true; - #endif - - activity = GlobalRef (act); - appFile = juceString (env, file); - appDataDir = juceString (env, dataDir); -} - -void AndroidSystem::shutdown (JNIEnv* env) -{ - activity.clear(); - - #if JUCE_DEBUG - systemInitialised = false; - #endif - - JNIClassBase::releaseAllClasses (env); -} - -AndroidSystem android; - -//============================================================================== -namespace AndroidStatsHelpers -{ - #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD) \ - STATICMETHOD (getProperty, "getProperty", "(Ljava/lang/String;)Ljava/lang/String;") - - DECLARE_JNI_CLASS (SystemClass, "java/lang/System"); - #undef JNI_CLASS_MEMBERS - - String getSystemProperty (const String& name) - { - return juceString (LocalRef ((jstring) getEnv()->CallStaticObjectMethod (SystemClass, - SystemClass.getProperty, - javaString (name).get()))); - } - - String getLocaleValue (bool isRegion) - { - return juceString (LocalRef ((jstring) getEnv()->CallStaticObjectMethod (JuceAppActivity, - JuceAppActivity.getLocaleValue, - isRegion))); - } - - #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD) - DECLARE_JNI_CLASS (BuildClass, "android/os/Build"); - #undef JNI_CLASS_MEMBERS - - String getAndroidOsBuildValue (const char* fieldName) - { - return juceString (LocalRef ((jstring) getEnv()->GetStaticObjectField ( - BuildClass, getEnv()->GetStaticFieldID (BuildClass, fieldName, "Ljava/lang/String;")))); - } -} - -//============================================================================== -SystemStats::OperatingSystemType SystemStats::getOperatingSystemType() -{ - return Android; -} - -String SystemStats::getOperatingSystemName() -{ - return "Android " + AndroidStatsHelpers::getSystemProperty ("os.version"); -} - -String SystemStats::getDeviceDescription() -{ - return AndroidStatsHelpers::getAndroidOsBuildValue ("MODEL") - + "-" + AndroidStatsHelpers::getAndroidOsBuildValue ("SERIAL"); -} - -bool SystemStats::isOperatingSystem64Bit() -{ - #if JUCE_64BIT - return true; - #else - return false; - #endif -} - -String SystemStats::getCpuVendor() -{ - return AndroidStatsHelpers::getSystemProperty ("os.arch"); -} - -int SystemStats::getCpuSpeedInMegaherz() -{ - return 0; // TODO -} - -int SystemStats::getMemorySizeInMegabytes() -{ - #if __ANDROID_API__ >= 9 - struct sysinfo sysi; - - if (sysinfo (&sysi) == 0) - return (sysi.totalram * sysi.mem_unit / (1024 * 1024)); - #endif - - return 0; -} - -int SystemStats::getPageSize() -{ - return sysconf (_SC_PAGESIZE); -} - -//============================================================================== -String SystemStats::getLogonName() -{ - if (const char* user = getenv ("USER")) - return CharPointer_UTF8 (user); - - if (struct passwd* const pw = getpwuid (getuid())) - return CharPointer_UTF8 (pw->pw_name); - - return String::empty; -} - -String SystemStats::getFullUserName() -{ - return getLogonName(); -} - -String SystemStats::getComputerName() -{ - char name [256] = { 0 }; - if (gethostname (name, sizeof (name) - 1) == 0) - return name; - - return String::empty; -} - - -String SystemStats::getUserLanguage() { return AndroidStatsHelpers::getLocaleValue (false); } -String SystemStats::getUserRegion() { return AndroidStatsHelpers::getLocaleValue (true); } -String SystemStats::getDisplayLanguage() { return getUserLanguage() + "-" + getUserRegion(); } - -//============================================================================== -void CPUInformation::initialise() noexcept -{ - numCpus = jmax (1, sysconf (_SC_NPROCESSORS_ONLN)); -} - -//============================================================================== -uint32 juce_millisecondsSinceStartup() noexcept -{ - timespec t; - clock_gettime (CLOCK_MONOTONIC, &t); - - return t.tv_sec * 1000 + t.tv_nsec / 1000000; -} - -int64 Time::getHighResolutionTicks() noexcept -{ - timespec t; - clock_gettime (CLOCK_MONOTONIC, &t); - - return (t.tv_sec * (int64) 1000000) + (t.tv_nsec / 1000); -} - -int64 Time::getHighResolutionTicksPerSecond() noexcept -{ - return 1000000; // (microseconds) -} - -double Time::getMillisecondCounterHiRes() noexcept -{ - return getHighResolutionTicks() * 0.001; -} - -bool Time::setSystemTimeToThisTime() const -{ - jassertfalse; - return false; -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/native/juce_android_Threads.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/native/juce_android_Threads.cpp deleted file mode 100644 index 981be9ae49..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/native/juce_android_Threads.cpp +++ /dev/null @@ -1,76 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -/* - Note that a lot of methods that you'd expect to find in this file actually - live in juce_posix_SharedCode.h! -*/ - -//============================================================================== -// sets the process to 0=low priority, 1=normal, 2=high, 3=realtime -JUCE_API void JUCE_CALLTYPE Process::setPriority (ProcessPriority prior) -{ - // TODO - - struct sched_param param; - int policy, maxp, minp; - - const int p = (int) prior; - - if (p <= 1) - policy = SCHED_OTHER; - else - policy = SCHED_RR; - - minp = sched_get_priority_min (policy); - maxp = sched_get_priority_max (policy); - - if (p < 2) - param.sched_priority = 0; - else if (p == 2 ) - // Set to middle of lower realtime priority range - param.sched_priority = minp + (maxp - minp) / 4; - else - // Set to middle of higher realtime priority range - param.sched_priority = minp + (3 * (maxp - minp) / 4); - - pthread_setschedparam (pthread_self(), policy, ¶m); -} - -JUCE_API bool JUCE_CALLTYPE juce_isRunningUnderDebugger() -{ - return false; -} - -JUCE_API bool JUCE_CALLTYPE Process::isRunningUnderDebugger() -{ - return juce_isRunningUnderDebugger(); -} - -JUCE_API void JUCE_CALLTYPE Process::raisePrivilege() {} -JUCE_API void JUCE_CALLTYPE Process::lowerPrivilege() {} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/native/juce_linux_CommonFile.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/native/juce_linux_CommonFile.cpp deleted file mode 100644 index 2ce98b3bda..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/native/juce_linux_CommonFile.cpp +++ /dev/null @@ -1,153 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -bool File::copyInternal (const File& dest) const -{ - FileInputStream in (*this); - - if (dest.deleteFile()) - { - { - FileOutputStream out (dest); - - if (out.failedToOpen()) - return false; - - if (out.writeFromInputStream (in, -1) == getSize()) - return true; - } - - dest.deleteFile(); - } - - return false; -} - -void File::findFileSystemRoots (Array& destArray) -{ - destArray.add (File ("/")); -} - -bool File::isHidden() const -{ - return getFileName().startsWithChar ('.'); -} - -static String getLinkedFile (StringRef file) -{ - HeapBlock buffer (8194); - const int numBytes = (int) readlink (file.text, buffer, 8192); - return String::fromUTF8 (buffer, jmax (0, numBytes)); -}; - -bool File::isLink() const -{ - return getLinkedFile (getFullPathName()).isNotEmpty(); -} - -File File::getLinkedTarget() const -{ - String f (getLinkedFile (getFullPathName())); - - if (f.isNotEmpty()) - return getSiblingFile (f); - - return *this; -} - -//============================================================================== -class DirectoryIterator::NativeIterator::Pimpl -{ -public: - Pimpl (const File& directory, const String& wc) - : parentDir (File::addTrailingSeparator (directory.getFullPathName())), - wildCard (wc), dir (opendir (directory.getFullPathName().toUTF8())) - { - } - - ~Pimpl() - { - if (dir != nullptr) - closedir (dir); - } - - bool next (String& filenameFound, - bool* const isDir, bool* const isHidden, int64* const fileSize, - Time* const modTime, Time* const creationTime, bool* const isReadOnly) - { - if (dir != nullptr) - { - const char* wildcardUTF8 = nullptr; - - for (;;) - { - struct dirent* const de = readdir (dir); - - if (de == nullptr) - break; - - if (wildcardUTF8 == nullptr) - wildcardUTF8 = wildCard.toUTF8(); - - if (fnmatch (wildcardUTF8, de->d_name, FNM_CASEFOLD) == 0) - { - filenameFound = CharPointer_UTF8 (de->d_name); - - updateStatInfoForFile (parentDir + filenameFound, isDir, fileSize, modTime, creationTime, isReadOnly); - - if (isHidden != nullptr) - *isHidden = filenameFound.startsWithChar ('.'); - - return true; - } - } - } - - return false; - } - -private: - String parentDir, wildCard; - DIR* dir; - - JUCE_DECLARE_NON_COPYABLE (Pimpl) -}; - -DirectoryIterator::NativeIterator::NativeIterator (const File& directory, const String& wildCard) - : pimpl (new DirectoryIterator::NativeIterator::Pimpl (directory, wildCard)) -{ -} - -DirectoryIterator::NativeIterator::~NativeIterator() {} - -bool DirectoryIterator::NativeIterator::next (String& filenameFound, - bool* isDir, bool* isHidden, int64* fileSize, - Time* modTime, Time* creationTime, bool* isReadOnly) -{ - return pimpl->next (filenameFound, isDir, isHidden, fileSize, modTime, creationTime, isReadOnly); -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/native/juce_linux_Files.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/native/juce_linux_Files.cpp deleted file mode 100644 index d0dd54df4a..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/native/juce_linux_Files.cpp +++ /dev/null @@ -1,241 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -enum -{ - U_ISOFS_SUPER_MAGIC = 0x9660, // linux/iso_fs.h - U_MSDOS_SUPER_MAGIC = 0x4d44, // linux/msdos_fs.h - U_NFS_SUPER_MAGIC = 0x6969, // linux/nfs_fs.h - U_SMB_SUPER_MAGIC = 0x517B // linux/smb_fs.h -}; - -bool File::isOnCDRomDrive() const -{ - struct statfs buf; - - return statfs (getFullPathName().toUTF8(), &buf) == 0 - && buf.f_type == (short) U_ISOFS_SUPER_MAGIC; -} - -bool File::isOnHardDisk() const -{ - struct statfs buf; - - if (statfs (getFullPathName().toUTF8(), &buf) == 0) - { - switch (buf.f_type) - { - case U_ISOFS_SUPER_MAGIC: // CD-ROM - case U_MSDOS_SUPER_MAGIC: // Probably floppy (but could be mounted FAT filesystem) - case U_NFS_SUPER_MAGIC: // Network NFS - case U_SMB_SUPER_MAGIC: // Network Samba - return false; - - default: break; - } - } - - // Assume so if this fails for some reason - return true; -} - -bool File::isOnRemovableDrive() const -{ - jassertfalse; // xxx not implemented for linux! - return false; -} - -String File::getVersion() const -{ - return String(); // xxx not yet implemented -} - -//============================================================================== -static File resolveXDGFolder (const char* const type, const char* const fallbackFolder) -{ - StringArray confLines; - File ("~/.config/user-dirs.dirs").readLines (confLines); - - for (int i = 0; i < confLines.size(); ++i) - { - const String line (confLines[i].trimStart()); - - if (line.startsWith (type)) - { - // eg. resolve XDG_MUSIC_DIR="$HOME/Music" to /home/user/Music - const File f (line.replace ("$HOME", File ("~").getFullPathName()) - .fromFirstOccurrenceOf ("=", false, false) - .trim().unquoted()); - - if (f.isDirectory()) - return f; - } - } - - return File (fallbackFolder); -} - -const char* const* juce_argv = nullptr; -int juce_argc = 0; - -File File::getSpecialLocation (const SpecialLocationType type) -{ - switch (type) - { - case userHomeDirectory: - { - if (const char* homeDir = getenv ("HOME")) - return File (CharPointer_UTF8 (homeDir)); - - if (struct passwd* const pw = getpwuid (getuid())) - return File (CharPointer_UTF8 (pw->pw_dir)); - - return File(); - } - - case userDocumentsDirectory: return resolveXDGFolder ("XDG_DOCUMENTS_DIR", "~"); - case userMusicDirectory: return resolveXDGFolder ("XDG_MUSIC_DIR", "~"); - case userMoviesDirectory: return resolveXDGFolder ("XDG_VIDEOS_DIR", "~"); - case userPicturesDirectory: return resolveXDGFolder ("XDG_PICTURES_DIR", "~"); - case userDesktopDirectory: return resolveXDGFolder ("XDG_DESKTOP_DIR", "~/Desktop"); - case userApplicationDataDirectory: return resolveXDGFolder ("XDG_CONFIG_HOME", "~"); - case commonDocumentsDirectory: - case commonApplicationDataDirectory: return File ("/var"); - case globalApplicationsDirectory: return File ("/usr"); - - case tempDirectory: - { - File tmp ("/var/tmp"); - - if (! tmp.isDirectory()) - { - tmp = "/tmp"; - - if (! tmp.isDirectory()) - tmp = File::getCurrentWorkingDirectory(); - } - - return tmp; - } - - case invokedExecutableFile: - if (juce_argv != nullptr && juce_argc > 0) - return File (CharPointer_UTF8 (juce_argv[0])); - // deliberate fall-through... - - case currentExecutableFile: - case currentApplicationFile: - return juce_getExecutableFile(); - - case hostApplicationPath: - { - const File f ("/proc/self/exe"); - return f.isLink() ? f.getLinkedTarget() : juce_getExecutableFile(); - } - - default: - jassertfalse; // unknown type? - break; - } - - return File(); -} - -//============================================================================== -bool File::moveToTrash() const -{ - if (! exists()) - return true; - - File trashCan ("~/.Trash"); - - if (! trashCan.isDirectory()) - trashCan = "~/.local/share/Trash/files"; - - if (! trashCan.isDirectory()) - return false; - - return moveFileTo (trashCan.getNonexistentChildFile (getFileNameWithoutExtension(), - getFileExtension())); -} - -//============================================================================== -static bool isFileExecutable (const String& filename) -{ - juce_statStruct info; - - return juce_stat (filename, info) - && S_ISREG (info.st_mode) - && access (filename.toUTF8(), X_OK) == 0; -} - -bool Process::openDocument (const String& fileName, const String& parameters) -{ - String cmdString (fileName.replace (" ", "\\ ",false)); - cmdString << " " << parameters; - - if (URL::isProbablyAWebsiteURL (fileName) - || cmdString.startsWithIgnoreCase ("file:") - || URL::isProbablyAnEmailAddress (fileName) - || File::createFileWithoutCheckingPath (fileName).isDirectory() - || ! isFileExecutable (fileName)) - { - // create a command that tries to launch a bunch of likely browsers - static const char* const browserNames[] = { "xdg-open", "/etc/alternatives/x-www-browser", "firefox", "mozilla", - "google-chrome", "chromium-browser", "opera", "konqueror" }; - StringArray cmdLines; - - for (int i = 0; i < numElementsInArray (browserNames); ++i) - cmdLines.add (String (browserNames[i]) + " " + cmdString.trim().quoted()); - - cmdString = cmdLines.joinIntoString (" || "); - } - - const char* const argv[4] = { "/bin/sh", "-c", cmdString.toUTF8(), 0 }; - - const int cpid = fork(); - - if (cpid == 0) - { - setsid(); - - // Child process - execve (argv[0], (char**) argv, environ); - exit (0); - } - - return cpid >= 0; -} - -void File::revealToUser() const -{ - if (isDirectory()) - startAsProcess(); - else if (getParentDirectory().exists()) - getParentDirectory().startAsProcess(); -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/native/juce_linux_Network.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/native/juce_linux_Network.cpp deleted file mode 100644 index 6871aa5469..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/native/juce_linux_Network.cpp +++ /dev/null @@ -1,445 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -void MACAddress::findAllAddresses (Array& result) -{ - const int s = socket (AF_INET, SOCK_DGRAM, 0); - if (s != -1) - { - struct ifaddrs* addrs = nullptr; - - if (getifaddrs (&addrs) != -1) - { - for (struct ifaddrs* i = addrs; i != nullptr; i = i->ifa_next) - { - struct ifreq ifr; - strcpy (ifr.ifr_name, i->ifa_name); - ifr.ifr_addr.sa_family = AF_INET; - - if (ioctl (s, SIOCGIFHWADDR, &ifr) == 0) - { - MACAddress ma ((const uint8*) ifr.ifr_hwaddr.sa_data); - - if (! ma.isNull()) - result.addIfNotAlreadyThere (ma); - } - } - - freeifaddrs (addrs); - } - - close (s); - } -} - - -bool JUCE_CALLTYPE Process::openEmailWithAttachments (const String& /* targetEmailAddress */, - const String& /* emailSubject */, - const String& /* bodyText */, - const StringArray& /* filesToAttach */) -{ - jassertfalse; // xxx todo - return false; -} - - -//============================================================================== -class WebInputStream : public InputStream -{ -public: - WebInputStream (const String& address_, bool isPost_, const MemoryBlock& postData_, - URL::OpenStreamProgressCallback* progressCallback, void* progressCallbackContext, - const String& headers_, int timeOutMs_, StringPairArray* responseHeaders) - : statusCode (0), socketHandle (-1), levelsOfRedirection (0), - address (address_), headers (headers_), postData (postData_), position (0), - finished (false), isPost (isPost_), timeOutMs (timeOutMs_) - { - statusCode = createConnection (progressCallback, progressCallbackContext); - - if (responseHeaders != nullptr && ! isError()) - { - for (int i = 0; i < headerLines.size(); ++i) - { - const String& headersEntry = headerLines[i]; - const String key (headersEntry.upToFirstOccurrenceOf (": ", false, false)); - const String value (headersEntry.fromFirstOccurrenceOf (": ", false, false)); - const String previousValue ((*responseHeaders) [key]); - responseHeaders->set (key, previousValue.isEmpty() ? value : (previousValue + "," + value)); - } - } - } - - ~WebInputStream() - { - closeSocket(); - } - - //============================================================================== - bool isError() const { return socketHandle < 0; } - bool isExhausted() override { return finished; } - int64 getPosition() override { return position; } - - int64 getTotalLength() override - { - //xxx to do - return -1; - } - - int read (void* buffer, int bytesToRead) override - { - if (finished || isError()) - return 0; - - fd_set readbits; - FD_ZERO (&readbits); - FD_SET (socketHandle, &readbits); - - struct timeval tv; - tv.tv_sec = jmax (1, timeOutMs / 1000); - tv.tv_usec = 0; - - if (select (socketHandle + 1, &readbits, 0, 0, &tv) <= 0) - return 0; // (timeout) - - const int bytesRead = jmax (0, (int) recv (socketHandle, buffer, bytesToRead, MSG_WAITALL)); - if (bytesRead == 0) - finished = true; - - position += bytesRead; - return bytesRead; - } - - bool setPosition (int64 wantedPos) override - { - if (isError()) - return false; - - if (wantedPos != position) - { - finished = false; - - if (wantedPos < position) - { - closeSocket(); - position = 0; - statusCode = createConnection (0, 0); - } - - skipNextBytes (wantedPos - position); - } - - return true; - } - - //============================================================================== - int statusCode; - -private: - int socketHandle, levelsOfRedirection; - StringArray headerLines; - String address, headers; - MemoryBlock postData; - int64 position; - bool finished; - const bool isPost; - const int timeOutMs; - - void closeSocket() - { - if (socketHandle >= 0) - close (socketHandle); - - socketHandle = -1; - levelsOfRedirection = 0; - } - - int createConnection (URL::OpenStreamProgressCallback* progressCallback, void* progressCallbackContext) - { - closeSocket(); - - uint32 timeOutTime = Time::getMillisecondCounter(); - - if (timeOutMs == 0) - timeOutTime += 60000; - else if (timeOutMs < 0) - timeOutTime = 0xffffffff; - else - timeOutTime += timeOutMs; - - String hostName, hostPath; - int hostPort; - if (! decomposeURL (address, hostName, hostPath, hostPort)) - return 0; - - String serverName, proxyName, proxyPath; - int proxyPort = 0; - int port = 0; - - const String proxyURL (getenv ("http_proxy")); - if (proxyURL.startsWithIgnoreCase ("http://")) - { - if (! decomposeURL (proxyURL, proxyName, proxyPath, proxyPort)) - return 0; - - serverName = proxyName; - port = proxyPort; - } - else - { - serverName = hostName; - port = hostPort; - } - - struct addrinfo hints; - zerostruct (hints); - - hints.ai_family = AF_UNSPEC; - hints.ai_socktype = SOCK_STREAM; - hints.ai_flags = AI_NUMERICSERV; - - struct addrinfo* result = nullptr; - if (getaddrinfo (serverName.toUTF8(), String (port).toUTF8(), &hints, &result) != 0 || result == 0) - return 0; - - socketHandle = socket (result->ai_family, result->ai_socktype, 0); - - if (socketHandle == -1) - { - freeaddrinfo (result); - return 0; - } - - int receiveBufferSize = 16384; - setsockopt (socketHandle, SOL_SOCKET, SO_RCVBUF, (char*) &receiveBufferSize, sizeof (receiveBufferSize)); - setsockopt (socketHandle, SOL_SOCKET, SO_KEEPALIVE, 0, 0); - - #if JUCE_MAC - setsockopt (socketHandle, SOL_SOCKET, SO_NOSIGPIPE, 0, 0); - #endif - - if (connect (socketHandle, result->ai_addr, result->ai_addrlen) == -1) - { - closeSocket(); - freeaddrinfo (result); - return 0; - } - - freeaddrinfo (result); - - { - const MemoryBlock requestHeader (createRequestHeader (hostName, hostPort, proxyName, proxyPort, - hostPath, address, headers, postData, isPost)); - - if (! sendHeader (socketHandle, requestHeader, timeOutTime, - progressCallback, progressCallbackContext)) - { - closeSocket(); - return 0; - } - } - - String responseHeader (readResponse (timeOutTime)); - position = 0; - - if (responseHeader.isNotEmpty()) - { - headerLines = StringArray::fromLines (responseHeader); - - const int status = responseHeader.fromFirstOccurrenceOf (" ", false, false) - .substring (0, 3).getIntValue(); - - //int contentLength = findHeaderItem (lines, "Content-Length:").getIntValue(); - //bool isChunked = findHeaderItem (lines, "Transfer-Encoding:").equalsIgnoreCase ("chunked"); - - String location (findHeaderItem (headerLines, "Location:")); - - if (status >= 300 && status < 400 - && location.isNotEmpty() && location != address) - { - if (! location.startsWithIgnoreCase ("http://")) - location = "http://" + location; - - if (++levelsOfRedirection <= 3) - { - address = location; - return createConnection (progressCallback, progressCallbackContext); - } - } - else - { - levelsOfRedirection = 0; - return status; - } - } - - closeSocket(); - return 0; - } - - //============================================================================== - String readResponse (const uint32 timeOutTime) - { - int numConsecutiveLFs = 0; - MemoryOutputStream buffer; - - while (numConsecutiveLFs < 2 - && buffer.getDataSize() < 32768 - && Time::getMillisecondCounter() <= timeOutTime - && ! (finished || isError())) - { - char c = 0; - if (read (&c, 1) != 1) - return String(); - - buffer.writeByte (c); - - if (c == '\n') - ++numConsecutiveLFs; - else if (c != '\r') - numConsecutiveLFs = 0; - } - - const String header (buffer.toString().trimEnd()); - - if (header.startsWithIgnoreCase ("HTTP/")) - return header; - - return String(); - } - - static void writeValueIfNotPresent (MemoryOutputStream& dest, const String& headers, const String& key, const String& value) - { - if (! headers.containsIgnoreCase (key)) - dest << "\r\n" << key << ' ' << value; - } - - static void writeHost (MemoryOutputStream& dest, const bool isPost, - const String& path, const String& host, int /*port*/) - { - dest << (isPost ? "POST " : "GET ") << path << " HTTP/1.0\r\nHost: " << host; - } - - static MemoryBlock createRequestHeader (const String& hostName, const int hostPort, - const String& proxyName, const int proxyPort, - const String& hostPath, const String& originalURL, - const String& userHeaders, const MemoryBlock& postData, - const bool isPost) - { - MemoryOutputStream header; - - if (proxyName.isEmpty()) - writeHost (header, isPost, hostPath, hostName, hostPort); - else - writeHost (header, isPost, originalURL, proxyName, proxyPort); - - writeValueIfNotPresent (header, userHeaders, "User-Agent:", "JUCE/" JUCE_STRINGIFY(JUCE_MAJOR_VERSION) - "." JUCE_STRINGIFY(JUCE_MINOR_VERSION) - "." JUCE_STRINGIFY(JUCE_BUILDNUMBER)); - writeValueIfNotPresent (header, userHeaders, "Connection:", "close"); - - if (isPost) - writeValueIfNotPresent (header, userHeaders, "Content-Length:", String ((int) postData.getSize())); - - header << "\r\n" << userHeaders - << "\r\n" << postData; - - return header.getMemoryBlock(); - } - - static bool sendHeader (int socketHandle, const MemoryBlock& requestHeader, const uint32 timeOutTime, - URL::OpenStreamProgressCallback* progressCallback, void* progressCallbackContext) - { - size_t totalHeaderSent = 0; - - while (totalHeaderSent < requestHeader.getSize()) - { - if (Time::getMillisecondCounter() > timeOutTime) - return false; - - const int numToSend = jmin (1024, (int) (requestHeader.getSize() - totalHeaderSent)); - - if (send (socketHandle, static_cast (requestHeader.getData()) + totalHeaderSent, numToSend, 0) != numToSend) - return false; - - totalHeaderSent += numToSend; - - if (progressCallback != nullptr && ! progressCallback (progressCallbackContext, totalHeaderSent, requestHeader.getSize())) - return false; - } - - return true; - } - - static bool decomposeURL (const String& url, String& host, String& path, int& port) - { - if (! url.startsWithIgnoreCase ("http://")) - return false; - - const int nextSlash = url.indexOfChar (7, '/'); - int nextColon = url.indexOfChar (7, ':'); - if (nextColon > nextSlash && nextSlash > 0) - nextColon = -1; - - if (nextColon >= 0) - { - host = url.substring (7, nextColon); - - if (nextSlash >= 0) - port = url.substring (nextColon + 1, nextSlash).getIntValue(); - else - port = url.substring (nextColon + 1).getIntValue(); - } - else - { - port = 80; - - if (nextSlash >= 0) - host = url.substring (7, nextSlash); - else - host = url.substring (7); - } - - if (nextSlash >= 0) - path = url.substring (nextSlash); - else - path = "/"; - - return true; - } - - static String findHeaderItem (const StringArray& lines, const String& itemName) - { - for (int i = 0; i < lines.size(); ++i) - if (lines[i].startsWithIgnoreCase (itemName)) - return lines[i].substring (itemName.length()).trim(); - - return String(); - } - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (WebInputStream) -}; diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/native/juce_linux_SystemStats.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/native/juce_linux_SystemStats.cpp deleted file mode 100644 index 939edb47bc..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/native/juce_linux_SystemStats.cpp +++ /dev/null @@ -1,191 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -void Logger::outputDebugString (const String& text) -{ - std::cerr << text << std::endl; -} - -//============================================================================== -SystemStats::OperatingSystemType SystemStats::getOperatingSystemType() -{ - return Linux; -} - -String SystemStats::getOperatingSystemName() -{ - return "Linux"; -} - -bool SystemStats::isOperatingSystem64Bit() -{ - #if JUCE_64BIT - return true; - #else - //xxx not sure how to find this out?.. - return false; - #endif -} - -//============================================================================== -namespace LinuxStatsHelpers -{ - String getCpuInfo (const char* const key) - { - StringArray lines; - File ("/proc/cpuinfo").readLines (lines); - - for (int i = lines.size(); --i >= 0;) // (NB - it's important that this runs in reverse order) - if (lines[i].upToFirstOccurrenceOf (":", false, false).trim().equalsIgnoreCase (key)) - return lines[i].fromFirstOccurrenceOf (":", false, false).trim(); - - return String(); - } -} - -String SystemStats::getDeviceDescription() -{ - return LinuxStatsHelpers::getCpuInfo ("Hardware"); -} - -String SystemStats::getCpuVendor() -{ - String v (LinuxStatsHelpers::getCpuInfo ("vendor_id")); - - if (v.isEmpty()) - v = LinuxStatsHelpers::getCpuInfo ("model name"); - - return v; -} - -int SystemStats::getCpuSpeedInMegaherz() -{ - return roundToInt (LinuxStatsHelpers::getCpuInfo ("cpu MHz").getFloatValue()); -} - -int SystemStats::getMemorySizeInMegabytes() -{ - struct sysinfo sysi; - - if (sysinfo (&sysi) == 0) - return sysi.totalram * sysi.mem_unit / (1024 * 1024); - - return 0; -} - -int SystemStats::getPageSize() -{ - return sysconf (_SC_PAGESIZE); -} - -//============================================================================== -String SystemStats::getLogonName() -{ - if (const char* user = getenv ("USER")) - return CharPointer_UTF8 (user); - - if (struct passwd* const pw = getpwuid (getuid())) - return CharPointer_UTF8 (pw->pw_name); - - return String(); -} - -String SystemStats::getFullUserName() -{ - return getLogonName(); -} - -String SystemStats::getComputerName() -{ - char name [256] = { 0 }; - if (gethostname (name, sizeof (name) - 1) == 0) - return name; - - return String(); -} - -static String getLocaleValue (nl_item key) -{ - const char* oldLocale = ::setlocale (LC_ALL, ""); - String result (String::fromUTF8 (nl_langinfo (key))); - ::setlocale (LC_ALL, oldLocale); - return result; -} - -String SystemStats::getUserLanguage() { return getLocaleValue (_NL_IDENTIFICATION_LANGUAGE); } -String SystemStats::getUserRegion() { return getLocaleValue (_NL_IDENTIFICATION_TERRITORY); } -String SystemStats::getDisplayLanguage() { return getUserLanguage() + "-" + getUserRegion(); } - -//============================================================================== -void CPUInformation::initialise() noexcept -{ - const String flags (LinuxStatsHelpers::getCpuInfo ("flags")); - hasMMX = flags.contains ("mmx"); - hasSSE = flags.contains ("sse"); - hasSSE2 = flags.contains ("sse2"); - hasSSE3 = flags.contains ("sse3"); - has3DNow = flags.contains ("3dnow"); - - numCpus = LinuxStatsHelpers::getCpuInfo ("processor").getIntValue() + 1; -} - -//============================================================================== -uint32 juce_millisecondsSinceStartup() noexcept -{ - timespec t; - clock_gettime (CLOCK_MONOTONIC, &t); - - return t.tv_sec * 1000 + t.tv_nsec / 1000000; -} - -int64 Time::getHighResolutionTicks() noexcept -{ - timespec t; - clock_gettime (CLOCK_MONOTONIC, &t); - - return (t.tv_sec * (int64) 1000000) + (t.tv_nsec / 1000); -} - -int64 Time::getHighResolutionTicksPerSecond() noexcept -{ - return 1000000; // (microseconds) -} - -double Time::getMillisecondCounterHiRes() noexcept -{ - return getHighResolutionTicks() * 0.001; -} - -bool Time::setSystemTimeToThisTime() const -{ - timeval t; - t.tv_sec = millisSinceEpoch / 1000; - t.tv_usec = (millisSinceEpoch - t.tv_sec * 1000) * 1000; - - return settimeofday (&t, 0) == 0; -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/native/juce_linux_Threads.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/native/juce_linux_Threads.cpp deleted file mode 100644 index 659fbd997c..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/native/juce_linux_Threads.cpp +++ /dev/null @@ -1,90 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -/* - Note that a lot of methods that you'd expect to find in this file actually - live in juce_posix_SharedCode.h! -*/ - -//============================================================================== -JUCE_API void JUCE_CALLTYPE Process::setPriority (const ProcessPriority prior) -{ - const int policy = (prior <= NormalPriority) ? SCHED_OTHER : SCHED_RR; - const int minp = sched_get_priority_min (policy); - const int maxp = sched_get_priority_max (policy); - - struct sched_param param; - - switch (prior) - { - case LowPriority: - case NormalPriority: param.sched_priority = 0; break; - case HighPriority: param.sched_priority = minp + (maxp - minp) / 4; break; - case RealtimePriority: param.sched_priority = minp + (3 * (maxp - minp) / 4); break; - default: jassertfalse; break; - } - - pthread_setschedparam (pthread_self(), policy, ¶m); -} - -JUCE_API bool JUCE_CALLTYPE juce_isRunningUnderDebugger() -{ - #if JUCE_BSD - return false; - #else - static char testResult = 0; - - if (testResult == 0) - { - testResult = (char) ptrace (PT_TRACE_ME, 0, 0, 0); - - if (testResult >= 0) - { - ptrace (PT_DETACH, 0, (caddr_t) 1, 0); - testResult = 1; - } - } - - return testResult < 0; - #endif -} - -JUCE_API bool JUCE_CALLTYPE Process::isRunningUnderDebugger() -{ - return juce_isRunningUnderDebugger(); -} - -static bool swapUserAndEffectiveUser() -{ - int result1 = setreuid (geteuid(), getuid()); - int result2 = setregid (getegid(), getgid()); - return result1 == 0 && result2 == 0; -} - -JUCE_API void JUCE_CALLTYPE Process::raisePrivilege() { if (geteuid() != 0 && getuid() == 0) swapUserAndEffectiveUser(); } -JUCE_API void JUCE_CALLTYPE Process::lowerPrivilege() { if (geteuid() == 0 && getuid() != 0) swapUserAndEffectiveUser(); } diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/native/juce_mac_Files.mm b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/native/juce_mac_Files.mm deleted file mode 100644 index 0a00e92124..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/native/juce_mac_Files.mm +++ /dev/null @@ -1,498 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -/* - Note that a lot of methods that you'd expect to find in this file actually - live in juce_posix_SharedCode.h! -*/ - -//============================================================================== -bool File::copyInternal (const File& dest) const -{ - JUCE_AUTORELEASEPOOL - { - NSFileManager* fm = [NSFileManager defaultManager]; - - return [fm fileExistsAtPath: juceStringToNS (fullPath)] - #if defined (MAC_OS_X_VERSION_10_6) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 - && [fm copyItemAtPath: juceStringToNS (fullPath) - toPath: juceStringToNS (dest.getFullPathName()) - error: nil]; - #else - && [fm copyPath: juceStringToNS (fullPath) - toPath: juceStringToNS (dest.getFullPathName()) - handler: nil]; - #endif - } -} - -void File::findFileSystemRoots (Array& destArray) -{ - destArray.add (File ("/")); -} - - -//============================================================================== -namespace FileHelpers -{ - static bool isFileOnDriveType (const File& f, const char* const* types) - { - struct statfs buf; - - if (juce_doStatFS (f, buf)) - { - const String type (buf.f_fstypename); - - while (*types != 0) - if (type.equalsIgnoreCase (*types++)) - return true; - } - - return false; - } - - static bool isHiddenFile (const String& path) - { - #if defined (MAC_OS_X_VERSION_10_6) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_6 - JUCE_AUTORELEASEPOOL - { - NSNumber* hidden = nil; - NSError* err = nil; - - return [[NSURL fileURLWithPath: juceStringToNS (path)] - getResourceValue: &hidden forKey: NSURLIsHiddenKey error: &err] - && [hidden boolValue]; - } - #elif JUCE_IOS - return File (path).getFileName().startsWithChar ('.'); - #else - FSRef ref; - LSItemInfoRecord info; - - return FSPathMakeRefWithOptions ((const UInt8*) path.toRawUTF8(), kFSPathMakeRefDoNotFollowLeafSymlink, &ref, 0) == noErr - && LSCopyItemInfoForRef (&ref, kLSRequestBasicFlagsOnly, &info) == noErr - && (info.flags & kLSItemInfoIsInvisible) != 0; - #endif - } - - #if JUCE_IOS - static String getIOSSystemLocation (NSSearchPathDirectory type) - { - return nsStringToJuce ([NSSearchPathForDirectoriesInDomains (type, NSUserDomainMask, YES) - objectAtIndex: 0]); - } - #endif - - static bool launchExecutable (const String& pathAndArguments) - { - const char* const argv[4] = { "/bin/sh", "-c", pathAndArguments.toUTF8(), 0 }; - - const int cpid = fork(); - - if (cpid == 0) - { - // Child process - if (execve (argv[0], (char**) argv, 0) < 0) - exit (0); - } - else - { - if (cpid < 0) - return false; - } - - return true; - } -} - -bool File::isOnCDRomDrive() const -{ - static const char* const cdTypes[] = { "cd9660", "cdfs", "cddafs", "udf", nullptr }; - - return FileHelpers::isFileOnDriveType (*this, cdTypes); -} - -bool File::isOnHardDisk() const -{ - static const char* const nonHDTypes[] = { "nfs", "smbfs", "ramfs", nullptr }; - - return ! (isOnCDRomDrive() || FileHelpers::isFileOnDriveType (*this, nonHDTypes)); -} - -bool File::isOnRemovableDrive() const -{ - #if JUCE_IOS - return false; // xxx is this possible? - #else - JUCE_AUTORELEASEPOOL - { - BOOL removable = false; - - [[NSWorkspace sharedWorkspace] - getFileSystemInfoForPath: juceStringToNS (getFullPathName()) - isRemovable: &removable - isWritable: nil - isUnmountable: nil - description: nil - type: nil]; - - return removable; - } - #endif -} - -bool File::isHidden() const -{ - return FileHelpers::isHiddenFile (getFullPathName()); -} - -//============================================================================== -const char* const* juce_argv = nullptr; -int juce_argc = 0; - -File File::getSpecialLocation (const SpecialLocationType type) -{ - JUCE_AUTORELEASEPOOL - { - String resultPath; - - switch (type) - { - case userHomeDirectory: resultPath = nsStringToJuce (NSHomeDirectory()); break; - - #if JUCE_IOS - case userDocumentsDirectory: resultPath = FileHelpers::getIOSSystemLocation (NSDocumentDirectory); break; - case userDesktopDirectory: resultPath = FileHelpers::getIOSSystemLocation (NSDesktopDirectory); break; - - case tempDirectory: - { - File tmp (FileHelpers::getIOSSystemLocation (NSCachesDirectory)); - tmp = tmp.getChildFile (juce_getExecutableFile().getFileNameWithoutExtension()); - tmp.createDirectory(); - return tmp.getFullPathName(); - } - - #else - case userDocumentsDirectory: resultPath = "~/Documents"; break; - case userDesktopDirectory: resultPath = "~/Desktop"; break; - - case tempDirectory: - { - File tmp ("~/Library/Caches/" + juce_getExecutableFile().getFileNameWithoutExtension()); - tmp.createDirectory(); - return File (tmp.getFullPathName()); - } - #endif - case userMusicDirectory: resultPath = "~/Music"; break; - case userMoviesDirectory: resultPath = "~/Movies"; break; - case userPicturesDirectory: resultPath = "~/Pictures"; break; - case userApplicationDataDirectory: resultPath = "~/Library"; break; - case commonApplicationDataDirectory: resultPath = "/Library"; break; - case commonDocumentsDirectory: resultPath = "/Users/Shared"; break; - case globalApplicationsDirectory: resultPath = "/Applications"; break; - - case invokedExecutableFile: - if (juce_argv != nullptr && juce_argc > 0) - return File (CharPointer_UTF8 (juce_argv[0])); - // deliberate fall-through... - - case currentExecutableFile: - return juce_getExecutableFile(); - - case currentApplicationFile: - { - const File exe (juce_getExecutableFile()); - const File parent (exe.getParentDirectory()); - - #if JUCE_IOS - return parent; - #else - return parent.getFullPathName().endsWithIgnoreCase ("Contents/MacOS") - ? parent.getParentDirectory().getParentDirectory() - : exe; - #endif - } - - case hostApplicationPath: - { - unsigned int size = 8192; - HeapBlock buffer; - buffer.calloc (size + 8); - - _NSGetExecutablePath (buffer.getData(), &size); - return File (String::fromUTF8 (buffer, (int) size)); - } - - default: - jassertfalse; // unknown type? - break; - } - - if (resultPath.isNotEmpty()) - return File (resultPath.convertToPrecomposedUnicode()); - } - - return File(); -} - -//============================================================================== -String File::getVersion() const -{ - JUCE_AUTORELEASEPOOL - { - if (NSBundle* bundle = [NSBundle bundleWithPath: juceStringToNS (getFullPathName())]) - if (NSDictionary* info = [bundle infoDictionary]) - if (NSString* name = [info valueForKey: nsStringLiteral ("CFBundleShortVersionString")]) - return nsStringToJuce (name); - } - - return String(); -} - -//============================================================================== -static NSString* getFileLink (const String& path) -{ - #if JUCE_IOS || (defined (MAC_OS_X_VERSION_10_5) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5) - return [[NSFileManager defaultManager] destinationOfSymbolicLinkAtPath: juceStringToNS (path) error: nil]; - #else - // (the cast here avoids a deprecation warning) - return [((id) [NSFileManager defaultManager]) pathContentOfSymbolicLinkAtPath: juceStringToNS (path)]; - #endif -} - -bool File::isLink() const -{ - return getFileLink (fullPath) != nil; -} - -File File::getLinkedTarget() const -{ - if (NSString* dest = getFileLink (fullPath)) - return getSiblingFile (nsStringToJuce (dest)); - - return *this; -} - -//============================================================================== -bool File::moveToTrash() const -{ - if (! exists()) - return true; - - #if JUCE_IOS - return deleteFile(); //xxx is there a trashcan on the iOS? - #else - JUCE_AUTORELEASEPOOL - { - NSString* p = juceStringToNS (getFullPathName()); - - return [[NSWorkspace sharedWorkspace] - performFileOperation: NSWorkspaceRecycleOperation - source: [p stringByDeletingLastPathComponent] - destination: nsEmptyString() - files: [NSArray arrayWithObject: [p lastPathComponent]] - tag: nil ]; - } - #endif -} - -//============================================================================== -class DirectoryIterator::NativeIterator::Pimpl -{ -public: - Pimpl (const File& directory, const String& wildCard_) - : parentDir (File::addTrailingSeparator (directory.getFullPathName())), - wildCard (wildCard_), - enumerator (nil) - { - JUCE_AUTORELEASEPOOL - { - enumerator = [[[NSFileManager defaultManager] enumeratorAtPath: juceStringToNS (directory.getFullPathName())] retain]; - } - } - - ~Pimpl() - { - [enumerator release]; - } - - bool next (String& filenameFound, - bool* const isDir, bool* const isHidden, int64* const fileSize, - Time* const modTime, Time* const creationTime, bool* const isReadOnly) - { - JUCE_AUTORELEASEPOOL - { - const char* wildcardUTF8 = nullptr; - - for (;;) - { - NSString* file; - if (enumerator == nil || (file = [enumerator nextObject]) == nil) - return false; - - [enumerator skipDescendents]; - filenameFound = nsStringToJuce (file).convertToPrecomposedUnicode(); - - if (wildcardUTF8 == nullptr) - wildcardUTF8 = wildCard.toUTF8(); - - if (fnmatch (wildcardUTF8, filenameFound.toUTF8(), FNM_CASEFOLD) != 0) - continue; - - const String fullPath (parentDir + filenameFound); - updateStatInfoForFile (fullPath, isDir, fileSize, modTime, creationTime, isReadOnly); - - if (isHidden != nullptr) - *isHidden = FileHelpers::isHiddenFile (fullPath); - - return true; - } - } - } - -private: - String parentDir, wildCard; - NSDirectoryEnumerator* enumerator; - - JUCE_DECLARE_NON_COPYABLE (Pimpl) -}; - -DirectoryIterator::NativeIterator::NativeIterator (const File& directory, const String& wildcard) - : pimpl (new DirectoryIterator::NativeIterator::Pimpl (directory, wildcard)) -{ -} - -DirectoryIterator::NativeIterator::~NativeIterator() -{ -} - -bool DirectoryIterator::NativeIterator::next (String& filenameFound, - bool* const isDir, bool* const isHidden, int64* const fileSize, - Time* const modTime, Time* const creationTime, bool* const isReadOnly) -{ - return pimpl->next (filenameFound, isDir, isHidden, fileSize, modTime, creationTime, isReadOnly); -} - - -//============================================================================== -bool JUCE_CALLTYPE Process::openDocument (const String& fileName, const String& parameters) -{ - JUCE_AUTORELEASEPOOL - { - NSURL* filenameAsURL = [NSURL URLWithString: juceStringToNS (fileName)]; - - #if JUCE_IOS - (void) parameters; - return [[UIApplication sharedApplication] openURL: filenameAsURL]; - #else - NSWorkspace* workspace = [NSWorkspace sharedWorkspace]; - - if (parameters.isEmpty()) - return [workspace openFile: juceStringToNS (fileName)] - || [workspace openURL: filenameAsURL]; - - const File file (fileName); - - if (file.isBundle()) - { - StringArray params; - params.addTokens (parameters, true); - - NSMutableArray* paramArray = [[[NSMutableArray alloc] init] autorelease]; - for (int i = 0; i < params.size(); ++i) - [paramArray addObject: juceStringToNS (params[i])]; - - NSMutableDictionary* dict = [[[NSMutableDictionary alloc] init] autorelease]; - [dict setObject: paramArray - forKey: nsStringLiteral ("NSWorkspaceLaunchConfigurationArguments")]; - - return [workspace launchApplicationAtURL: filenameAsURL - options: NSWorkspaceLaunchDefault | NSWorkspaceLaunchNewInstance - configuration: dict - error: nil]; - } - - if (file.exists()) - return FileHelpers::launchExecutable ("\"" + fileName + "\" " + parameters); - - return false; - #endif - } -} - -void File::revealToUser() const -{ - #if ! JUCE_IOS - if (exists()) - [[NSWorkspace sharedWorkspace] selectFile: juceStringToNS (getFullPathName()) inFileViewerRootedAtPath: nsEmptyString()]; - else if (getParentDirectory().exists()) - getParentDirectory().revealToUser(); - #endif -} - -//============================================================================== -OSType File::getMacOSType() const -{ - JUCE_AUTORELEASEPOOL - { - #if JUCE_IOS || (defined (MAC_OS_X_VERSION_10_5) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5) - NSDictionary* fileDict = [[NSFileManager defaultManager] attributesOfItemAtPath: juceStringToNS (getFullPathName()) error: nil]; - #else - // (the cast here avoids a deprecation warning) - NSDictionary* fileDict = [((id) [NSFileManager defaultManager]) fileAttributesAtPath: juceStringToNS (getFullPathName()) traverseLink: NO]; - #endif - - return [fileDict fileHFSTypeCode]; - } -} - -bool File::isBundle() const -{ - #if JUCE_IOS - return false; // xxx can't find a sensible way to do this without trying to open the bundle.. - #else - JUCE_AUTORELEASEPOOL - { - return [[NSWorkspace sharedWorkspace] isFilePackageAtPath: juceStringToNS (getFullPathName())]; - } - #endif -} - -#if JUCE_MAC -void File::addToDock() const -{ - // check that it's not already there... - if (! juce_getOutputFromCommand ("defaults read com.apple.dock persistent-apps").containsIgnoreCase (getFullPathName())) - { - juce_runSystemCommand ("defaults write com.apple.dock persistent-apps -array-add \"tile-datafile-data_CFURLString" - + getFullPathName() + "_CFURLStringType0\""); - - juce_runSystemCommand ("osascript -e \"tell application \\\"Dock\\\" to quit\""); - } -} -#endif diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/native/juce_mac_Network.mm b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/native/juce_mac_Network.mm deleted file mode 100644 index 130759e6d6..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/native/juce_mac_Network.mm +++ /dev/null @@ -1,445 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -void MACAddress::findAllAddresses (Array& result) -{ - ifaddrs* addrs = nullptr; - - if (getifaddrs (&addrs) == 0) - { - for (const ifaddrs* cursor = addrs; cursor != nullptr; cursor = cursor->ifa_next) - { - sockaddr_storage* sto = (sockaddr_storage*) cursor->ifa_addr; - if (sto->ss_family == AF_LINK) - { - const sockaddr_dl* const sadd = (const sockaddr_dl*) cursor->ifa_addr; - - #ifndef IFT_ETHER - enum { IFT_ETHER = 6 }; - #endif - - if (sadd->sdl_type == IFT_ETHER) - { - MACAddress ma (MACAddress (((const uint8*) sadd->sdl_data) + sadd->sdl_nlen)); - - if (! ma.isNull()) - result.addIfNotAlreadyThere (ma); - } - } - } - - freeifaddrs (addrs); - } -} - -//============================================================================== -bool JUCE_CALLTYPE Process::openEmailWithAttachments (const String& targetEmailAddress, - const String& emailSubject, - const String& bodyText, - const StringArray& filesToAttach) -{ - #if JUCE_IOS - (void) targetEmailAddress; - (void) emailSubject; - (void) bodyText; - (void) filesToAttach; - - //xxx probably need to use MFMailComposeViewController - jassertfalse; - return false; - #else - JUCE_AUTORELEASEPOOL - { - String script; - script << "tell application \"Mail\"\r\n" - "set newMessage to make new outgoing message with properties {subject:\"" - << emailSubject.replace ("\"", "\\\"") - << "\", content:\"" - << bodyText.replace ("\"", "\\\"") - << "\" & return & return}\r\n" - "tell newMessage\r\n" - "set visible to true\r\n" - "set sender to \"sdfsdfsdfewf\"\r\n" - "make new to recipient at end of to recipients with properties {address:\"" - << targetEmailAddress - << "\"}\r\n"; - - for (int i = 0; i < filesToAttach.size(); ++i) - { - script << "tell content\r\n" - "make new attachment with properties {file name:\"" - << filesToAttach[i].replace ("\"", "\\\"") - << "\"} at after the last paragraph\r\n" - "end tell\r\n"; - } - - script << "end tell\r\n" - "end tell\r\n"; - - NSAppleScript* s = [[NSAppleScript alloc] initWithSource: juceStringToNS (script)]; - NSDictionary* error = nil; - const bool ok = [s executeAndReturnError: &error] != nil; - [s release]; - - return ok; - } - #endif -} - -//============================================================================== -class URLConnectionState : public Thread -{ -public: - URLConnectionState (NSURLRequest* req) - : Thread ("http connection"), - contentLength (-1), - delegate (nil), - request ([req retain]), - connection (nil), - data ([[NSMutableData data] retain]), - headers (nil), - statusCode (0), - initialised (false), - hasFailed (false), - hasFinished (false) - { - static DelegateClass cls; - delegate = [cls.createInstance() init]; - DelegateClass::setState (delegate, this); - } - - ~URLConnectionState() - { - stop(); - [connection release]; - [data release]; - [request release]; - [headers release]; - [delegate release]; - } - - bool start (URL::OpenStreamProgressCallback* callback, void* context) - { - startThread(); - - while (isThreadRunning() && ! initialised) - { - if (callback != nullptr) - callback (context, -1, (int) [[request HTTPBody] length]); - - Thread::sleep (1); - } - - return connection != nil && ! hasFailed; - } - - void stop() - { - [connection cancel]; - stopThread (10000); - } - - int read (char* dest, int numBytes) - { - int numDone = 0; - - while (numBytes > 0) - { - const int available = jmin (numBytes, (int) [data length]); - - if (available > 0) - { - const ScopedLock sl (dataLock); - [data getBytes: dest length: (NSUInteger) available]; - [data replaceBytesInRange: NSMakeRange (0, (NSUInteger) available) withBytes: nil length: 0]; - - numDone += available; - numBytes -= available; - dest += available; - } - else - { - if (hasFailed || hasFinished) - break; - - Thread::sleep (1); - } - } - - return numDone; - } - - void didReceiveResponse (NSURLResponse* response) - { - { - const ScopedLock sl (dataLock); - [data setLength: 0]; - } - - initialised = true; - contentLength = [response expectedContentLength]; - - [headers release]; - headers = nil; - - if ([response isKindOfClass: [NSHTTPURLResponse class]]) - { - NSHTTPURLResponse* httpResponse = (NSHTTPURLResponse*) response; - headers = [[httpResponse allHeaderFields] retain]; - statusCode = (int) [httpResponse statusCode]; - } - } - - void didFailWithError (NSError* error) - { - DBG (nsStringToJuce ([error description])); (void) error; - hasFailed = true; - initialised = true; - signalThreadShouldExit(); - } - - void didReceiveData (NSData* newData) - { - const ScopedLock sl (dataLock); - [data appendData: newData]; - initialised = true; - } - - void didSendBodyData (NSInteger /*totalBytesWritten*/, NSInteger /*totalBytesExpected*/) - { - } - - void finishedLoading() - { - hasFinished = true; - initialised = true; - signalThreadShouldExit(); - } - - void run() override - { - connection = [[NSURLConnection alloc] initWithRequest: request - delegate: delegate]; - while (! threadShouldExit()) - { - JUCE_AUTORELEASEPOOL - { - [[NSRunLoop currentRunLoop] runUntilDate: [NSDate dateWithTimeIntervalSinceNow: 0.01]]; - } - } - } - - int64 contentLength; - CriticalSection dataLock; - NSObject* delegate; - NSURLRequest* request; - NSURLConnection* connection; - NSMutableData* data; - NSDictionary* headers; - int statusCode; - bool initialised, hasFailed, hasFinished; - -private: - //============================================================================== - struct DelegateClass : public ObjCClass - { - DelegateClass() : ObjCClass ("JUCEAppDelegate_") - { - addIvar ("state"); - - addMethod (@selector (connection:didReceiveResponse:), didReceiveResponse, "v@:@@"); - addMethod (@selector (connection:didFailWithError:), didFailWithError, "v@:@@"); - addMethod (@selector (connection:didReceiveData:), didReceiveData, "v@:@@"); - addMethod (@selector (connection:didSendBodyData:totalBytesWritten:totalBytesExpectedToWrite:), - connectionDidSendBodyData, "v@:@iii"); - addMethod (@selector (connectionDidFinishLoading:), connectionDidFinishLoading, "v@:@"); - addMethod (@selector (connection:willSendRequest:redirectResponse:), willSendRequest, "@@:@@"); - - registerClass(); - } - - static void setState (id self, URLConnectionState* state) { object_setInstanceVariable (self, "state", state); } - static URLConnectionState* getState (id self) { return getIvar (self, "state"); } - - private: - static void didReceiveResponse (id self, SEL, NSURLConnection*, NSURLResponse* response) - { - getState (self)->didReceiveResponse (response); - } - - static void didFailWithError (id self, SEL, NSURLConnection*, NSError* error) - { - getState (self)->didFailWithError (error); - } - - static void didReceiveData (id self, SEL, NSURLConnection*, NSData* newData) - { - getState (self)->didReceiveData (newData); - } - - static NSURLRequest* willSendRequest (id, SEL, NSURLConnection*, NSURLRequest* request, NSURLResponse*) - { - return request; - } - - static void connectionDidSendBodyData (id self, SEL, NSURLConnection*, NSInteger, NSInteger totalBytesWritten, NSInteger totalBytesExpected) - { - getState (self)->didSendBodyData (totalBytesWritten, totalBytesExpected); - } - - static void connectionDidFinishLoading (id self, SEL, NSURLConnection*) - { - getState (self)->finishedLoading(); - } - }; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (URLConnectionState) -}; - - -//============================================================================== -class WebInputStream : public InputStream -{ -public: - WebInputStream (const String& address_, bool isPost_, const MemoryBlock& postData_, - URL::OpenStreamProgressCallback* progressCallback, void* progressCallbackContext, - const String& headers_, int timeOutMs_, StringPairArray* responseHeaders) - : statusCode (0), address (address_), headers (headers_), postData (postData_), position (0), - finished (false), isPost (isPost_), timeOutMs (timeOutMs_) - { - JUCE_AUTORELEASEPOOL - { - createConnection (progressCallback, progressCallbackContext); - - if (responseHeaders != nullptr && connection != nullptr && connection->headers != nil) - { - statusCode = connection->statusCode; - - NSEnumerator* enumerator = [connection->headers keyEnumerator]; - - while (NSString* key = [enumerator nextObject]) - responseHeaders->set (nsStringToJuce (key), - nsStringToJuce ((NSString*) [connection->headers objectForKey: key])); - } - } - } - - //============================================================================== - bool isError() const { return connection == nullptr; } - int64 getTotalLength() override { return connection == nullptr ? -1 : connection->contentLength; } - bool isExhausted() override { return finished; } - int64 getPosition() override { return position; } - - int read (void* buffer, int bytesToRead) override - { - jassert (buffer != nullptr && bytesToRead >= 0); - - if (finished || isError()) - return 0; - - JUCE_AUTORELEASEPOOL - { - const int bytesRead = connection->read (static_cast (buffer), bytesToRead); - position += bytesRead; - - if (bytesRead == 0) - finished = true; - - return bytesRead; - } - } - - bool setPosition (int64 wantedPos) override - { - if (wantedPos != position) - { - finished = false; - - if (wantedPos < position) - { - connection = nullptr; - position = 0; - createConnection (0, 0); - } - - skipNextBytes (wantedPos - position); - } - - return true; - } - - int statusCode; - -private: - ScopedPointer connection; - String address, headers; - MemoryBlock postData; - int64 position; - bool finished; - const bool isPost; - const int timeOutMs; - - void createConnection (URL::OpenStreamProgressCallback* progressCallback, void* progressCallbackContext) - { - jassert (connection == nullptr); - - NSMutableURLRequest* req = [NSMutableURLRequest requestWithURL: [NSURL URLWithString: juceStringToNS (address)] - cachePolicy: NSURLRequestReloadIgnoringLocalCacheData - timeoutInterval: timeOutMs <= 0 ? 60.0 : (timeOutMs / 1000.0)]; - - if (req != nil) - { - [req setHTTPMethod: nsStringLiteral (isPost ? "POST" : "GET")]; - //[req setCachePolicy: NSURLRequestReloadIgnoringLocalAndRemoteCacheData]; - - StringArray headerLines; - headerLines.addLines (headers); - headerLines.removeEmptyStrings (true); - - for (int i = 0; i < headerLines.size(); ++i) - { - const String key (headerLines[i].upToFirstOccurrenceOf (":", false, false).trim()); - const String value (headerLines[i].fromFirstOccurrenceOf (":", false, false).trim()); - - if (key.isNotEmpty() && value.isNotEmpty()) - [req addValue: juceStringToNS (value) forHTTPHeaderField: juceStringToNS (key)]; - } - - if (isPost && postData.getSize() > 0) - [req setHTTPBody: [NSData dataWithBytes: postData.getData() - length: postData.getSize()]]; - - connection = new URLConnectionState (req); - - if (! connection->start (progressCallback, progressCallbackContext)) - connection = nullptr; - } - } - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (WebInputStream) -}; diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/native/juce_mac_Strings.mm b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/native/juce_mac_Strings.mm deleted file mode 100644 index 862eb539e8..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/native/juce_mac_Strings.mm +++ /dev/null @@ -1,96 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -String String::fromCFString (CFStringRef cfString) -{ - if (cfString == 0) - return String(); - - CFRange range = { 0, CFStringGetLength (cfString) }; - HeapBlock u ((size_t) range.length + 1); - CFStringGetCharacters (cfString, range, u); - u[range.length] = 0; - - return String (CharPointer_UTF16 ((const CharPointer_UTF16::CharType*) u.getData())); -} - -CFStringRef String::toCFString() const -{ - CharPointer_UTF16 utf16 (toUTF16()); - return CFStringCreateWithCharacters (kCFAllocatorDefault, (const UniChar*) utf16.getAddress(), (CFIndex) utf16.length()); -} - -String String::convertToPrecomposedUnicode() const -{ - #if JUCE_IOS - JUCE_AUTORELEASEPOOL - { - return nsStringToJuce ([juceStringToNS (*this) precomposedStringWithCanonicalMapping]); - } - #else - UnicodeMapping map; - - map.unicodeEncoding = CreateTextEncoding (kTextEncodingUnicodeDefault, - kUnicodeNoSubset, - kTextEncodingDefaultFormat); - - map.otherEncoding = CreateTextEncoding (kTextEncodingUnicodeDefault, - kUnicodeCanonicalCompVariant, - kTextEncodingDefaultFormat); - - map.mappingVersion = kUnicodeUseLatestMapping; - - UnicodeToTextInfo conversionInfo = 0; - String result; - - if (CreateUnicodeToTextInfo (&map, &conversionInfo) == noErr) - { - const size_t bytesNeeded = CharPointer_UTF16::getBytesRequiredFor (getCharPointer()); - - HeapBlock tempOut; - tempOut.calloc (bytesNeeded + 4); - - ByteCount bytesRead = 0; - ByteCount outputBufferSize = 0; - - if (ConvertFromUnicodeToText (conversionInfo, - bytesNeeded, (ConstUniCharArrayPtr) toUTF16().getAddress(), - kUnicodeDefaultDirectionMask, - 0, 0, 0, 0, - bytesNeeded, &bytesRead, - &outputBufferSize, tempOut) == noErr) - { - result = String (CharPointer_UTF16 ((CharPointer_UTF16::CharType*) tempOut.getData())); - } - - DisposeUnicodeToTextInfo (&conversionInfo); - } - - return result; - #endif -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/native/juce_mac_SystemStats.mm b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/native/juce_mac_SystemStats.mm deleted file mode 100644 index 2d49ae6982..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/native/juce_mac_SystemStats.mm +++ /dev/null @@ -1,306 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -ScopedAutoReleasePool::ScopedAutoReleasePool() -{ - pool = [[NSAutoreleasePool alloc] init]; -} - -ScopedAutoReleasePool::~ScopedAutoReleasePool() -{ - [((NSAutoreleasePool*) pool) release]; -} - -//============================================================================== -void Logger::outputDebugString (const String& text) -{ - // Would prefer to use std::cerr here, but avoiding it for - // the moment, due to clang JIT linkage problems. - fputs (text.toRawUTF8(), stderr); - fputs ("\n", stderr); - fflush (stderr); -} - -//============================================================================== -namespace SystemStatsHelpers -{ - #if JUCE_INTEL && ! JUCE_NO_INLINE_ASM - static void doCPUID (uint32& a, uint32& b, uint32& c, uint32& d, uint32 type) - { - uint32 la = a, lb = b, lc = c, ld = d; - - asm ("mov %%ebx, %%esi \n\t" - "cpuid \n\t" - "xchg %%esi, %%ebx" - : "=a" (la), "=S" (lb), "=c" (lc), "=d" (ld) : "a" (type) - #if JUCE_64BIT - , "b" (lb), "c" (lc), "d" (ld) - #endif - ); - - a = la; b = lb; c = lc; d = ld; - } - #endif -} - -//============================================================================== -void CPUInformation::initialise() noexcept -{ - #if JUCE_INTEL && ! JUCE_NO_INLINE_ASM - uint32 a = 0, b = 0, d = 0, c = 0; - SystemStatsHelpers::doCPUID (a, b, c, d, 1); - - hasMMX = (d & (1u << 23)) != 0; - hasSSE = (d & (1u << 25)) != 0; - hasSSE2 = (d & (1u << 26)) != 0; - has3DNow = (b & (1u << 31)) != 0; - hasSSE3 = (c & (1u << 0)) != 0; - #endif - - #if JUCE_IOS || (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5) - numCpus = (int) [[NSProcessInfo processInfo] activeProcessorCount]; - #else - numCpus = (int) MPProcessors(); - #endif -} - -#if JUCE_MAC -struct RLimitInitialiser -{ - RLimitInitialiser() - { - rlimit lim; - getrlimit (RLIMIT_NOFILE, &lim); - lim.rlim_cur = lim.rlim_max = RLIM_INFINITY; - setrlimit (RLIMIT_NOFILE, &lim); - } -}; - -static RLimitInitialiser rLimitInitialiser; -#endif - -//============================================================================== -#if ! JUCE_IOS -static String getOSXVersion() -{ - JUCE_AUTORELEASEPOOL - { - NSDictionary* dict = [NSDictionary dictionaryWithContentsOfFile: - nsStringLiteral ("/System/Library/CoreServices/SystemVersion.plist")]; - - return nsStringToJuce ([dict objectForKey: nsStringLiteral ("ProductVersion")]); - } -} -#endif - -SystemStats::OperatingSystemType SystemStats::getOperatingSystemType() -{ - #if JUCE_IOS - return iOS; - #else - StringArray parts; - parts.addTokens (getOSXVersion(), ".", StringRef()); - - jassert (parts[0].getIntValue() == 10); - const int major = parts[1].getIntValue(); - jassert (major > 2); - - return (OperatingSystemType) (major + MacOSX_10_4 - 4); - #endif -} - -String SystemStats::getOperatingSystemName() -{ - #if JUCE_IOS - return "iOS " + nsStringToJuce ([[UIDevice currentDevice] systemVersion]); - #else - return "Mac OSX " + getOSXVersion(); - #endif -} - -String SystemStats::getDeviceDescription() -{ - #if JUCE_IOS - return nsStringToJuce ([[UIDevice currentDevice] model]); - #else - return String(); - #endif -} - -bool SystemStats::isOperatingSystem64Bit() -{ - #if JUCE_IOS - return false; - #elif JUCE_64BIT - return true; - #else - return getOperatingSystemType() >= MacOSX_10_6; - #endif -} - -int SystemStats::getMemorySizeInMegabytes() -{ - uint64 mem = 0; - size_t memSize = sizeof (mem); - int mib[] = { CTL_HW, HW_MEMSIZE }; - sysctl (mib, 2, &mem, &memSize, 0, 0); - return (int) (mem / (1024 * 1024)); -} - -String SystemStats::getCpuVendor() -{ - #if JUCE_INTEL && ! JUCE_NO_INLINE_ASM - uint32 dummy = 0; - uint32 vendor[4] = { 0 }; - - SystemStatsHelpers::doCPUID (dummy, vendor[0], vendor[2], vendor[1], 0); - - return String (reinterpret_cast (vendor), 12); - #else - return String(); - #endif -} - -int SystemStats::getCpuSpeedInMegaherz() -{ - uint64 speedHz = 0; - size_t speedSize = sizeof (speedHz); - int mib[] = { CTL_HW, HW_CPU_FREQ }; - sysctl (mib, 2, &speedHz, &speedSize, 0, 0); - - #if JUCE_BIG_ENDIAN - if (speedSize == 4) - speedHz >>= 32; - #endif - - return (int) (speedHz / 1000000); -} - -//============================================================================== -String SystemStats::getLogonName() -{ - return nsStringToJuce (NSUserName()); -} - -String SystemStats::getFullUserName() -{ - return nsStringToJuce (NSFullUserName()); -} - -String SystemStats::getComputerName() -{ - char name [256] = { 0 }; - if (gethostname (name, sizeof (name) - 1) == 0) - return String (name).upToLastOccurrenceOf (".local", false, true); - - return String(); -} - -static String getLocaleValue (CFStringRef key) -{ - CFLocaleRef cfLocale = CFLocaleCopyCurrent(); - const String result (String::fromCFString ((CFStringRef) CFLocaleGetValue (cfLocale, key))); - CFRelease (cfLocale); - return result; -} - -String SystemStats::getUserLanguage() { return getLocaleValue (kCFLocaleLanguageCode); } -String SystemStats::getUserRegion() { return getLocaleValue (kCFLocaleCountryCode); } - -String SystemStats::getDisplayLanguage() -{ - CFArrayRef cfPrefLangs = CFLocaleCopyPreferredLanguages(); - const String result (String::fromCFString ((CFStringRef) CFArrayGetValueAtIndex (cfPrefLangs, 0))); - CFRelease (cfPrefLangs); - return result; -} - -//============================================================================== -/* NB: these are kept outside the HiResCounterInfo struct and initialised to 1 to avoid - division-by-zero errors if some other static constructor calls us before this file's - static constructors have had a chance to fill them in correctly.. -*/ -static uint64 hiResCounterNumerator = 0, hiResCounterDenominator = 1; - -class HiResCounterInfo -{ -public: - HiResCounterInfo() - { - mach_timebase_info_data_t timebase; - (void) mach_timebase_info (&timebase); - - if (timebase.numer % 1000000 == 0) - { - hiResCounterNumerator = timebase.numer / 1000000; - hiResCounterDenominator = timebase.denom; - } - else - { - hiResCounterNumerator = timebase.numer; - hiResCounterDenominator = timebase.denom * (uint64) 1000000; - } - - highResTimerFrequency = (timebase.denom * (uint64) 1000000000) / timebase.numer; - highResTimerToMillisecRatio = hiResCounterNumerator / (double) hiResCounterDenominator; - } - - uint32 millisecondsSinceStartup() const noexcept - { - return (uint32) ((mach_absolute_time() * hiResCounterNumerator) / hiResCounterDenominator); - } - - double getMillisecondCounterHiRes() const noexcept - { - return mach_absolute_time() * highResTimerToMillisecRatio; - } - - int64 highResTimerFrequency; - -private: - double highResTimerToMillisecRatio; -}; - -static HiResCounterInfo hiResCounterInfo; - -uint32 juce_millisecondsSinceStartup() noexcept { return hiResCounterInfo.millisecondsSinceStartup(); } -double Time::getMillisecondCounterHiRes() noexcept { return hiResCounterInfo.getMillisecondCounterHiRes(); } -int64 Time::getHighResolutionTicksPerSecond() noexcept { return hiResCounterInfo.highResTimerFrequency; } -int64 Time::getHighResolutionTicks() noexcept { return (int64) mach_absolute_time(); } - -bool Time::setSystemTimeToThisTime() const -{ - jassertfalse; - return false; -} - -//============================================================================== -int SystemStats::getPageSize() -{ - return (int) NSPageSize(); -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/native/juce_mac_Threads.mm b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/native/juce_mac_Threads.mm deleted file mode 100644 index 004baeb2a1..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/native/juce_mac_Threads.mm +++ /dev/null @@ -1,97 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -/* - Note that a lot of methods that you'd expect to find in this file actually - live in juce_posix_SharedCode.h! -*/ - -#if JUCE_IOS -bool isIOSAppActive = true; -#endif - -//============================================================================== -JUCE_API bool JUCE_CALLTYPE Process::isForegroundProcess() -{ - #if JUCE_MAC - return [NSApp isActive]; - #else - return isIOSAppActive; - #endif -} - -JUCE_API void JUCE_CALLTYPE Process::makeForegroundProcess() -{ - #if JUCE_MAC - [NSApp activateIgnoringOtherApps: YES]; - #endif -} - -JUCE_API void JUCE_CALLTYPE Process::hide() -{ - #if JUCE_MAC - [NSApp hide: nil]; - #endif -} - -JUCE_API void JUCE_CALLTYPE Process::raisePrivilege() -{ - jassertfalse; -} - -JUCE_API void JUCE_CALLTYPE Process::lowerPrivilege() -{ - jassertfalse; -} - -JUCE_API void JUCE_CALLTYPE Process::setPriority (ProcessPriority) -{ - // xxx -} - -//============================================================================== -JUCE_API bool JUCE_CALLTYPE juce_isRunningUnderDebugger() -{ - static char testResult = 0; - - if (testResult == 0) - { - struct kinfo_proc info; - int m[] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, getpid() }; - size_t sz = sizeof (info); - sysctl (m, 4, &info, &sz, 0, 0); - testResult = ((info.kp_proc.p_flag & P_TRACED) != 0) ? 1 : -1; - } - - return testResult > 0; -} - -JUCE_API bool JUCE_CALLTYPE Process::isRunningUnderDebugger() -{ - return juce_isRunningUnderDebugger(); -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/native/juce_osx_ObjCHelpers.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/native/juce_osx_ObjCHelpers.h deleted file mode 100644 index 10878d0427..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/native/juce_osx_ObjCHelpers.h +++ /dev/null @@ -1,169 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_OSX_OBJCHELPERS_H_INCLUDED -#define JUCE_OSX_OBJCHELPERS_H_INCLUDED - - -/* This file contains a few helper functions that are used internally but which - need to be kept away from the public headers because they use obj-C symbols. -*/ -namespace -{ - //============================================================================== - static inline String nsStringToJuce (NSString* s) - { - return CharPointer_UTF8 ([s UTF8String]); - } - - static inline NSString* juceStringToNS (const String& s) - { - return [NSString stringWithUTF8String: s.toUTF8()]; - } - - static inline NSString* nsStringLiteral (const char* const s) noexcept - { - return [NSString stringWithUTF8String: s]; - } - - static inline NSString* nsEmptyString() noexcept - { - return [NSString string]; - } - - #if JUCE_MAC - template - static NSRect makeNSRect (const RectangleType& r) noexcept - { - return NSMakeRect (static_cast (r.getX()), - static_cast (r.getY()), - static_cast (r.getWidth()), - static_cast (r.getHeight())); - } - #endif -} - -//============================================================================== -template -struct NSObjectRetainer -{ - inline NSObjectRetainer (ObjectType* o) : object (o) { [object retain]; } - inline ~NSObjectRetainer() { [object release]; } - - ObjectType* object; -}; - -//============================================================================== -template -struct ObjCClass -{ - ObjCClass (const char* nameRoot) - : cls (objc_allocateClassPair ([SuperclassType class], getRandomisedName (nameRoot).toUTF8(), 0)) - { - } - - ~ObjCClass() - { - objc_disposeClassPair (cls); - } - - void registerClass() - { - objc_registerClassPair (cls); - } - - SuperclassType* createInstance() const - { - return class_createInstance (cls, 0); - } - - template - void addIvar (const char* name) - { - BOOL b = class_addIvar (cls, name, sizeof (Type), (uint8_t) rint (log2 (sizeof (Type))), @encode (Type)); - jassert (b); (void) b; - } - - template - void addMethod (SEL selector, FunctionType callbackFn, const char* signature) - { - BOOL b = class_addMethod (cls, selector, (IMP) callbackFn, signature); - jassert (b); (void) b; - } - - template - void addMethod (SEL selector, FunctionType callbackFn, const char* sig1, const char* sig2) - { - addMethod (selector, callbackFn, (String (sig1) + sig2).toUTF8()); - } - - template - void addMethod (SEL selector, FunctionType callbackFn, const char* sig1, const char* sig2, const char* sig3) - { - addMethod (selector, callbackFn, (String (sig1) + sig2 + sig3).toUTF8()); - } - - template - void addMethod (SEL selector, FunctionType callbackFn, const char* sig1, const char* sig2, const char* sig3, const char* sig4) - { - addMethod (selector, callbackFn, (String (sig1) + sig2 + sig3 + sig4).toUTF8()); - } - - void addProtocol (Protocol* protocol) - { - BOOL b = class_addProtocol (cls, protocol); - jassert (b); (void) b; - } - - static id sendSuperclassMessage (id self, SEL selector) - { - objc_super s = { self, [SuperclassType class] }; - return objc_msgSendSuper (&s, selector); - } - - template - static Type getIvar (id self, const char* name) - { - void* v = nullptr; - object_getInstanceVariable (self, name, &v); - return static_cast (v); - } - - Class cls; - -private: - static String getRandomisedName (const char* root) - { - return root + String::toHexString (juce::Random::getSystemRandom().nextInt64()); - } - - JUCE_DECLARE_NON_COPYABLE (ObjCClass) -}; - - -#endif // JUCE_OSX_OBJCHELPERS_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/native/juce_posix_NamedPipe.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/native/juce_posix_NamedPipe.cpp deleted file mode 100644 index d0c0b09af7..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/native/juce_posix_NamedPipe.cpp +++ /dev/null @@ -1,224 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -class NamedPipe::Pimpl -{ -public: - Pimpl (const String& pipePath, bool createPipe) - : pipeInName (pipePath + "_in"), - pipeOutName (pipePath + "_out"), - pipeIn (-1), pipeOut (-1), - createdPipe (createPipe), - stopReadOperation (false) - { - signal (SIGPIPE, signalHandler); - juce_siginterrupt (SIGPIPE, 1); - } - - ~Pimpl() - { - if (pipeIn != -1) ::close (pipeIn); - if (pipeOut != -1) ::close (pipeOut); - - if (createdPipe) - { - unlink (pipeInName.toUTF8()); - unlink (pipeOutName.toUTF8()); - } - } - - int read (char* destBuffer, int maxBytesToRead, int timeOutMilliseconds) - { - const uint32 timeoutEnd = getTimeoutEnd (timeOutMilliseconds); - - if (pipeIn == -1) - { - pipeIn = openPipe (createdPipe ? pipeInName : pipeOutName, O_RDWR | O_NONBLOCK, timeoutEnd); - - if (pipeIn == -1) - return -1; - } - - int bytesRead = 0; - - while (bytesRead < maxBytesToRead) - { - const int bytesThisTime = maxBytesToRead - bytesRead; - const int numRead = (int) ::read (pipeIn, destBuffer, (size_t) bytesThisTime); - - if (numRead <= 0) - { - if (errno != EWOULDBLOCK || stopReadOperation || hasExpired (timeoutEnd)) - return -1; - - const int maxWaitingTime = 30; - waitForInput (pipeIn, timeoutEnd == 0 ? maxWaitingTime - : jmin (maxWaitingTime, - (int) (timeoutEnd - Time::getMillisecondCounter()))); - continue; - } - - bytesRead += numRead; - destBuffer += numRead; - } - - return bytesRead; - } - - int write (const char* sourceBuffer, int numBytesToWrite, int timeOutMilliseconds) - { - const uint32 timeoutEnd = getTimeoutEnd (timeOutMilliseconds); - - if (pipeOut == -1) - { - pipeOut = openPipe (createdPipe ? pipeOutName : pipeInName, O_WRONLY, timeoutEnd); - - if (pipeOut == -1) - return -1; - } - - int bytesWritten = 0; - - while (bytesWritten < numBytesToWrite && ! hasExpired (timeoutEnd)) - { - const int bytesThisTime = numBytesToWrite - bytesWritten; - const int numWritten = (int) ::write (pipeOut, sourceBuffer, (size_t) bytesThisTime); - - if (numWritten <= 0) - return -1; - - bytesWritten += numWritten; - sourceBuffer += numWritten; - } - - return bytesWritten; - } - - bool createFifos() const - { - return (mkfifo (pipeInName .toUTF8(), 0666) == 0 || errno == EEXIST) - && (mkfifo (pipeOutName.toUTF8(), 0666) == 0 || errno == EEXIST); - } - - const String pipeInName, pipeOutName; - int pipeIn, pipeOut; - - const bool createdPipe; - bool stopReadOperation; - -private: - static void signalHandler (int) {} - - static uint32 getTimeoutEnd (const int timeOutMilliseconds) - { - return timeOutMilliseconds >= 0 ? Time::getMillisecondCounter() + (uint32) timeOutMilliseconds : 0; - } - - static bool hasExpired (const uint32 timeoutEnd) - { - return timeoutEnd != 0 && Time::getMillisecondCounter() >= timeoutEnd; - } - - int openPipe (const String& name, int flags, const uint32 timeoutEnd) - { - for (;;) - { - const int p = ::open (name.toUTF8(), flags); - - if (p != -1 || hasExpired (timeoutEnd) || stopReadOperation) - return p; - - Thread::sleep (2); - } - } - - static void waitForInput (const int handle, const int timeoutMsecs) noexcept - { - struct timeval timeout; - timeout.tv_sec = timeoutMsecs / 1000; - timeout.tv_usec = (timeoutMsecs % 1000) * 1000; - - fd_set rset; - FD_ZERO (&rset); - FD_SET (handle, &rset); - - select (handle + 1, &rset, nullptr, 0, &timeout); - } - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Pimpl) -}; - -void NamedPipe::close() -{ - if (pimpl != nullptr) - { - pimpl->stopReadOperation = true; - - char buffer[1] = { 0 }; - ssize_t done = ::write (pimpl->pipeIn, buffer, 1); - (void) done; - - ScopedWriteLock sl (lock); - pimpl = nullptr; - } -} - -bool NamedPipe::openInternal (const String& pipeName, const bool createPipe) -{ - #if JUCE_IOS - pimpl = new Pimpl (File::getSpecialLocation (File::tempDirectory) - .getChildFile (File::createLegalFileName (pipeName)).getFullPathName(), createPipe); - #else - String file (pipeName); - - if (! File::isAbsolutePath (file)) - file = "/tmp/" + File::createLegalFileName (file); - - pimpl = new Pimpl (file, createPipe); - #endif - - if (createPipe && ! pimpl->createFifos()) - { - pimpl = nullptr; - return false; - } - - return true; -} - -int NamedPipe::read (void* destBuffer, int maxBytesToRead, int timeOutMilliseconds) -{ - ScopedReadLock sl (lock); - return pimpl != nullptr ? pimpl->read (static_cast (destBuffer), maxBytesToRead, timeOutMilliseconds) : -1; -} - -int NamedPipe::write (const void* sourceBuffer, int numBytesToWrite, int timeOutMilliseconds) -{ - ScopedReadLock sl (lock); - return pimpl != nullptr ? pimpl->write (static_cast (sourceBuffer), numBytesToWrite, timeOutMilliseconds) : -1; -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/native/juce_posix_SharedCode.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/native/juce_posix_SharedCode.h deleted file mode 100644 index 91785d6ad7..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/native/juce_posix_SharedCode.h +++ /dev/null @@ -1,1308 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -CriticalSection::CriticalSection() noexcept -{ - pthread_mutexattr_t atts; - pthread_mutexattr_init (&atts); - pthread_mutexattr_settype (&atts, PTHREAD_MUTEX_RECURSIVE); - #if ! JUCE_ANDROID - pthread_mutexattr_setprotocol (&atts, PTHREAD_PRIO_INHERIT); - #endif - pthread_mutex_init (&lock, &atts); - pthread_mutexattr_destroy (&atts); -} - -CriticalSection::~CriticalSection() noexcept { pthread_mutex_destroy (&lock); } -void CriticalSection::enter() const noexcept { pthread_mutex_lock (&lock); } -bool CriticalSection::tryEnter() const noexcept { return pthread_mutex_trylock (&lock) == 0; } -void CriticalSection::exit() const noexcept { pthread_mutex_unlock (&lock); } - -//============================================================================== -WaitableEvent::WaitableEvent (const bool useManualReset) noexcept - : triggered (false), manualReset (useManualReset) -{ - pthread_cond_init (&condition, 0); - - pthread_mutexattr_t atts; - pthread_mutexattr_init (&atts); - #if ! JUCE_ANDROID - pthread_mutexattr_setprotocol (&atts, PTHREAD_PRIO_INHERIT); - #endif - pthread_mutex_init (&mutex, &atts); -} - -WaitableEvent::~WaitableEvent() noexcept -{ - pthread_cond_destroy (&condition); - pthread_mutex_destroy (&mutex); -} - -bool WaitableEvent::wait (const int timeOutMillisecs) const noexcept -{ - pthread_mutex_lock (&mutex); - - if (! triggered) - { - if (timeOutMillisecs < 0) - { - do - { - pthread_cond_wait (&condition, &mutex); - } - while (! triggered); - } - else - { - struct timeval now; - gettimeofday (&now, 0); - - struct timespec time; - time.tv_sec = now.tv_sec + (timeOutMillisecs / 1000); - time.tv_nsec = (now.tv_usec + ((timeOutMillisecs % 1000) * 1000)) * 1000; - - if (time.tv_nsec >= 1000000000) - { - time.tv_nsec -= 1000000000; - time.tv_sec++; - } - - do - { - if (pthread_cond_timedwait (&condition, &mutex, &time) == ETIMEDOUT) - { - pthread_mutex_unlock (&mutex); - return false; - } - } - while (! triggered); - } - } - - if (! manualReset) - triggered = false; - - pthread_mutex_unlock (&mutex); - return true; -} - -void WaitableEvent::signal() const noexcept -{ - pthread_mutex_lock (&mutex); - - if (! triggered) - { - triggered = true; - pthread_cond_broadcast (&condition); - } - - pthread_mutex_unlock (&mutex); -} - -void WaitableEvent::reset() const noexcept -{ - pthread_mutex_lock (&mutex); - triggered = false; - pthread_mutex_unlock (&mutex); -} - -//============================================================================== -void JUCE_CALLTYPE Thread::sleep (int millisecs) -{ - struct timespec time; - time.tv_sec = millisecs / 1000; - time.tv_nsec = (millisecs % 1000) * 1000000; - nanosleep (&time, nullptr); -} - -void JUCE_CALLTYPE Process::terminate() -{ - #if JUCE_ANDROID - _exit (EXIT_FAILURE); - #else - std::_Exit (EXIT_FAILURE); - #endif -} - -//============================================================================== -const juce_wchar File::separator = '/'; -const String File::separatorString ("/"); - -//============================================================================== -File File::getCurrentWorkingDirectory() -{ - HeapBlock heapBuffer; - - char localBuffer [1024]; - char* cwd = getcwd (localBuffer, sizeof (localBuffer) - 1); - size_t bufferSize = 4096; - - while (cwd == nullptr && errno == ERANGE) - { - heapBuffer.malloc (bufferSize); - cwd = getcwd (heapBuffer, bufferSize - 1); - bufferSize += 1024; - } - - return File (CharPointer_UTF8 (cwd)); -} - -bool File::setAsCurrentWorkingDirectory() const -{ - return chdir (getFullPathName().toUTF8()) == 0; -} - -//============================================================================== -// The unix siginterrupt function is deprecated - this does the same job. -int juce_siginterrupt (int sig, int flag) -{ - struct ::sigaction act; - (void) ::sigaction (sig, nullptr, &act); - - if (flag != 0) - act.sa_flags &= ~SA_RESTART; - else - act.sa_flags |= SA_RESTART; - - return ::sigaction (sig, &act, nullptr); -} - -//============================================================================== -namespace -{ - #if JUCE_LINUX || (JUCE_IOS && ! __DARWIN_ONLY_64_BIT_INO_T) // (this iOS stuff is to avoid a simulator bug) - typedef struct stat64 juce_statStruct; - #define JUCE_STAT stat64 - #else - typedef struct stat juce_statStruct; - #define JUCE_STAT stat - #endif - - bool juce_stat (const String& fileName, juce_statStruct& info) - { - return fileName.isNotEmpty() - && JUCE_STAT (fileName.toUTF8(), &info) == 0; - } - - // if this file doesn't exist, find a parent of it that does.. - bool juce_doStatFS (File f, struct statfs& result) - { - for (int i = 5; --i >= 0;) - { - if (f.exists()) - break; - - f = f.getParentDirectory(); - } - - return statfs (f.getFullPathName().toUTF8(), &result) == 0; - } - - #if (JUCE_MAC && MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_5) || JUCE_IOS - static int64 getCreationTime (const juce_statStruct& s) noexcept { return (int64) s.st_birthtime; } - #else - static int64 getCreationTime (const juce_statStruct& s) noexcept { return (int64) s.st_ctime; } - #endif - - void updateStatInfoForFile (const String& path, bool* const isDir, int64* const fileSize, - Time* const modTime, Time* const creationTime, bool* const isReadOnly) - { - if (isDir != nullptr || fileSize != nullptr || modTime != nullptr || creationTime != nullptr) - { - juce_statStruct info; - const bool statOk = juce_stat (path, info); - - if (isDir != nullptr) *isDir = statOk && ((info.st_mode & S_IFDIR) != 0); - if (fileSize != nullptr) *fileSize = statOk ? (int64) info.st_size : 0; - if (modTime != nullptr) *modTime = Time (statOk ? (int64) info.st_mtime * 1000 : 0); - if (creationTime != nullptr) *creationTime = Time (statOk ? getCreationTime (info) * 1000 : 0); - } - - if (isReadOnly != nullptr) - *isReadOnly = access (path.toUTF8(), W_OK) != 0; - } - - Result getResultForErrno() - { - return Result::fail (String (strerror (errno))); - } - - Result getResultForReturnValue (int value) - { - return value == -1 ? getResultForErrno() : Result::ok(); - } - - int getFD (void* handle) noexcept { return (int) (pointer_sized_int) handle; } - void* fdToVoidPointer (int fd) noexcept { return (void*) (pointer_sized_int) fd; } -} - -bool File::isDirectory() const -{ - juce_statStruct info; - - return fullPath.isEmpty() - || (juce_stat (fullPath, info) && ((info.st_mode & S_IFDIR) != 0)); -} - -bool File::exists() const -{ - return fullPath.isNotEmpty() - && access (fullPath.toUTF8(), F_OK) == 0; -} - -bool File::existsAsFile() const -{ - return exists() && ! isDirectory(); -} - -int64 File::getSize() const -{ - juce_statStruct info; - return juce_stat (fullPath, info) ? info.st_size : 0; -} - -uint64 File::getFileIdentifier() const -{ - juce_statStruct info; - return juce_stat (fullPath, info) ? (uint64) info.st_ino : 0; -} - -//============================================================================== -bool File::hasWriteAccess() const -{ - if (exists()) - return access (fullPath.toUTF8(), W_OK) == 0; - - if ((! isDirectory()) && fullPath.containsChar (separator)) - return getParentDirectory().hasWriteAccess(); - - return false; -} - -bool File::setFileReadOnlyInternal (const bool shouldBeReadOnly) const -{ - juce_statStruct info; - if (! juce_stat (fullPath, info)) - return false; - - info.st_mode &= 0777; // Just permissions - - if (shouldBeReadOnly) - info.st_mode &= ~(S_IWUSR | S_IWGRP | S_IWOTH); - else - // Give everybody write permission? - info.st_mode |= S_IWUSR | S_IWGRP | S_IWOTH; - - return chmod (fullPath.toUTF8(), info.st_mode) == 0; -} - -void File::getFileTimesInternal (int64& modificationTime, int64& accessTime, int64& creationTime) const -{ - modificationTime = 0; - accessTime = 0; - creationTime = 0; - - juce_statStruct info; - if (juce_stat (fullPath, info)) - { - modificationTime = (int64) info.st_mtime * 1000; - accessTime = (int64) info.st_atime * 1000; - creationTime = (int64) info.st_ctime * 1000; - } -} - -bool File::setFileTimesInternal (int64 modificationTime, int64 accessTime, int64 /*creationTime*/) const -{ - juce_statStruct info; - - if ((modificationTime != 0 || accessTime != 0) && juce_stat (fullPath, info)) - { - struct utimbuf times; - times.actime = accessTime != 0 ? (time_t) (accessTime / 1000) : info.st_atime; - times.modtime = modificationTime != 0 ? (time_t) (modificationTime / 1000) : info.st_mtime; - - return utime (fullPath.toUTF8(), ×) == 0; - } - - return false; -} - -bool File::deleteFile() const -{ - if (! exists()) - return true; - - if (isDirectory()) - return rmdir (fullPath.toUTF8()) == 0; - - return remove (fullPath.toUTF8()) == 0; -} - -bool File::moveInternal (const File& dest) const -{ - if (rename (fullPath.toUTF8(), dest.getFullPathName().toUTF8()) == 0) - return true; - - if (hasWriteAccess() && copyInternal (dest)) - { - if (deleteFile()) - return true; - - dest.deleteFile(); - } - - return false; -} - -Result File::createDirectoryInternal (const String& fileName) const -{ - return getResultForReturnValue (mkdir (fileName.toUTF8(), 0777)); -} - -//===================================================================== -int64 juce_fileSetPosition (void* handle, int64 pos) -{ - if (handle != 0 && lseek (getFD (handle), pos, SEEK_SET) == pos) - return pos; - - return -1; -} - -void FileInputStream::openHandle() -{ - const int f = open (file.getFullPathName().toUTF8(), O_RDONLY, 00644); - - if (f != -1) - fileHandle = fdToVoidPointer (f); - else - status = getResultForErrno(); -} - -FileInputStream::~FileInputStream() -{ - if (fileHandle != 0) - close (getFD (fileHandle)); -} - -size_t FileInputStream::readInternal (void* const buffer, const size_t numBytes) -{ - ssize_t result = 0; - - if (fileHandle != 0) - { - result = ::read (getFD (fileHandle), buffer, numBytes); - - if (result < 0) - { - status = getResultForErrno(); - result = 0; - } - } - - return (size_t) result; -} - -//============================================================================== -void FileOutputStream::openHandle() -{ - if (file.exists()) - { - const int f = open (file.getFullPathName().toUTF8(), O_RDWR, 00644); - - if (f != -1) - { - currentPosition = lseek (f, 0, SEEK_END); - - if (currentPosition >= 0) - { - fileHandle = fdToVoidPointer (f); - } - else - { - status = getResultForErrno(); - close (f); - } - } - else - { - status = getResultForErrno(); - } - } - else - { - const int f = open (file.getFullPathName().toUTF8(), O_RDWR + O_CREAT, 00644); - - if (f != -1) - fileHandle = fdToVoidPointer (f); - else - status = getResultForErrno(); - } -} - -void FileOutputStream::closeHandle() -{ - if (fileHandle != 0) - { - close (getFD (fileHandle)); - fileHandle = 0; - } -} - -ssize_t FileOutputStream::writeInternal (const void* const data, const size_t numBytes) -{ - ssize_t result = 0; - - if (fileHandle != 0) - { - result = ::write (getFD (fileHandle), data, numBytes); - - if (result == -1) - status = getResultForErrno(); - } - - return result; -} - -void FileOutputStream::flushInternal() -{ - if (fileHandle != 0) - { - if (fsync (getFD (fileHandle)) == -1) - status = getResultForErrno(); - - #if JUCE_ANDROID - // This stuff tells the OS to asynchronously update the metadata - // that the OS has cached aboud the file - this metadata is used - // when the device is acting as a USB drive, and unless it's explicitly - // refreshed, it'll get out of step with the real file. - const LocalRef t (javaString (file.getFullPathName())); - android.activity.callVoidMethod (JuceAppActivity.scanFile, t.get()); - #endif - } -} - -Result FileOutputStream::truncate() -{ - if (fileHandle == 0) - return status; - - flush(); - return getResultForReturnValue (ftruncate (getFD (fileHandle), (off_t) currentPosition)); -} - -//============================================================================== -String SystemStats::getEnvironmentVariable (const String& name, const String& defaultValue) -{ - if (const char* s = ::getenv (name.toUTF8())) - return String::fromUTF8 (s); - - return defaultValue; -} - -//============================================================================== -void MemoryMappedFile::openInternal (const File& file, AccessMode mode) -{ - jassert (mode == readOnly || mode == readWrite); - - if (range.getStart() > 0) - { - const long pageSize = sysconf (_SC_PAGE_SIZE); - range.setStart (range.getStart() - (range.getStart() % pageSize)); - } - - fileHandle = open (file.getFullPathName().toUTF8(), - mode == readWrite ? (O_CREAT + O_RDWR) : O_RDONLY, 00644); - - if (fileHandle != -1) - { - void* m = mmap (0, (size_t) range.getLength(), - mode == readWrite ? (PROT_READ | PROT_WRITE) : PROT_READ, - MAP_SHARED, fileHandle, - (off_t) range.getStart()); - - if (m != MAP_FAILED) - { - address = m; - madvise (m, (size_t) range.getLength(), MADV_SEQUENTIAL); - } - else - { - range = Range(); - } - } -} - -MemoryMappedFile::~MemoryMappedFile() -{ - if (address != nullptr) - munmap (address, (size_t) range.getLength()); - - if (fileHandle != 0) - close (fileHandle); -} - -//============================================================================== -#if JUCE_PROJUCER_LIVE_BUILD -extern "C" const char* juce_getCurrentExecutablePath(); -#endif - -File juce_getExecutableFile(); -File juce_getExecutableFile() -{ - #if JUCE_PROJUCER_LIVE_BUILD - return File (juce_getCurrentExecutablePath()); - #elif JUCE_ANDROID - return File (android.appFile); - #else - struct DLAddrReader - { - static String getFilename() - { - Dl_info exeInfo; - dladdr ((void*) juce_getExecutableFile, &exeInfo); - return CharPointer_UTF8 (exeInfo.dli_fname); - } - }; - - static String filename (DLAddrReader::getFilename()); - return File::getCurrentWorkingDirectory().getChildFile (filename); - #endif -} - -//============================================================================== -int64 File::getBytesFreeOnVolume() const -{ - struct statfs buf; - if (juce_doStatFS (*this, buf)) - return (int64) buf.f_bsize * (int64) buf.f_bavail; // Note: this returns space available to non-super user - - return 0; -} - -int64 File::getVolumeTotalSize() const -{ - struct statfs buf; - if (juce_doStatFS (*this, buf)) - return (int64) buf.f_bsize * (int64) buf.f_blocks; - - return 0; -} - -String File::getVolumeLabel() const -{ - #if JUCE_MAC - struct VolAttrBuf - { - u_int32_t length; - attrreference_t mountPointRef; - char mountPointSpace [MAXPATHLEN]; - } attrBuf; - - struct attrlist attrList; - zerostruct (attrList); // (can't use "= { 0 }" on this object because it's typedef'ed as a C struct) - attrList.bitmapcount = ATTR_BIT_MAP_COUNT; - attrList.volattr = ATTR_VOL_INFO | ATTR_VOL_NAME; - - File f (*this); - - for (;;) - { - if (getattrlist (f.getFullPathName().toUTF8(), &attrList, &attrBuf, sizeof (attrBuf), 0) == 0) - return String::fromUTF8 (((const char*) &attrBuf.mountPointRef) + attrBuf.mountPointRef.attr_dataoffset, - (int) attrBuf.mountPointRef.attr_length); - - const File parent (f.getParentDirectory()); - - if (f == parent) - break; - - f = parent; - } - #endif - - return String(); -} - -int File::getVolumeSerialNumber() const -{ - int result = 0; -/* int fd = open (getFullPathName().toUTF8(), O_RDONLY | O_NONBLOCK); - - char info [512]; - - #ifndef HDIO_GET_IDENTITY - #define HDIO_GET_IDENTITY 0x030d - #endif - - if (ioctl (fd, HDIO_GET_IDENTITY, info) == 0) - { - DBG (String (info + 20, 20)); - result = String (info + 20, 20).trim().getIntValue(); - } - - close (fd);*/ - return result; -} - -//============================================================================== -#if ! JUCE_IOS -void juce_runSystemCommand (const String&); -void juce_runSystemCommand (const String& command) -{ - int result = system (command.toUTF8()); - (void) result; -} - -String juce_getOutputFromCommand (const String&); -String juce_getOutputFromCommand (const String& command) -{ - // slight bodge here, as we just pipe the output into a temp file and read it... - const File tempFile (File::getSpecialLocation (File::tempDirectory) - .getNonexistentChildFile (String::toHexString (Random::getSystemRandom().nextInt()), ".tmp", false)); - - juce_runSystemCommand (command + " > " + tempFile.getFullPathName()); - - String result (tempFile.loadFileAsString()); - tempFile.deleteFile(); - return result; -} -#endif - -//============================================================================== -#if JUCE_IOS -class InterProcessLock::Pimpl -{ -public: - Pimpl (const String&, int) - : handle (1), refCount (1) // On iOS just fake success.. - { - } - - int handle, refCount; -}; - -#else - -class InterProcessLock::Pimpl -{ -public: - Pimpl (const String& lockName, const int timeOutMillisecs) - : handle (0), refCount (1) - { - #if JUCE_MAC - if (! createLockFile (File ("~/Library/Caches/com.juce.locks").getChildFile (lockName), timeOutMillisecs)) - // Fallback if the user's home folder is on a network drive with no ability to lock.. - createLockFile (File ("/tmp/com.juce.locks").getChildFile (lockName), timeOutMillisecs); - - #else - File tempFolder ("/var/tmp"); - if (! tempFolder.isDirectory()) - tempFolder = "/tmp"; - - createLockFile (tempFolder.getChildFile (lockName), timeOutMillisecs); - #endif - } - - ~Pimpl() - { - closeFile(); - } - - bool createLockFile (const File& file, const int timeOutMillisecs) - { - file.create(); - handle = open (file.getFullPathName().toUTF8(), O_RDWR); - - if (handle != 0) - { - struct flock fl; - zerostruct (fl); - - fl.l_whence = SEEK_SET; - fl.l_type = F_WRLCK; - - const int64 endTime = Time::currentTimeMillis() + timeOutMillisecs; - - for (;;) - { - const int result = fcntl (handle, F_SETLK, &fl); - - if (result >= 0) - return true; - - const int error = errno; - - if (error != EINTR) - { - if (error == EBADF || error == ENOTSUP) - return false; - - if (timeOutMillisecs == 0 - || (timeOutMillisecs > 0 && Time::currentTimeMillis() >= endTime)) - break; - - Thread::sleep (10); - } - } - } - - closeFile(); - return true; // only false if there's a file system error. Failure to lock still returns true. - } - - void closeFile() - { - if (handle != 0) - { - struct flock fl; - zerostruct (fl); - - fl.l_whence = SEEK_SET; - fl.l_type = F_UNLCK; - - while (! (fcntl (handle, F_SETLKW, &fl) >= 0 || errno != EINTR)) - {} - - close (handle); - handle = 0; - } - } - - int handle, refCount; -}; -#endif - -InterProcessLock::InterProcessLock (const String& nm) : name (nm) -{ -} - -InterProcessLock::~InterProcessLock() -{ -} - -bool InterProcessLock::enter (const int timeOutMillisecs) -{ - const ScopedLock sl (lock); - - if (pimpl == nullptr) - { - pimpl = new Pimpl (name, timeOutMillisecs); - - if (pimpl->handle == 0) - pimpl = nullptr; - } - else - { - pimpl->refCount++; - } - - return pimpl != nullptr; -} - -void InterProcessLock::exit() -{ - const ScopedLock sl (lock); - - // Trying to release the lock too many times! - jassert (pimpl != nullptr); - - if (pimpl != nullptr && --(pimpl->refCount) == 0) - pimpl = nullptr; -} - -//============================================================================== -void JUCE_API juce_threadEntryPoint (void*); - -extern "C" void* threadEntryProc (void*); -extern "C" void* threadEntryProc (void* userData) -{ - JUCE_AUTORELEASEPOOL - { - #if JUCE_ANDROID - const AndroidThreadScope androidEnv; - #endif - - juce_threadEntryPoint (userData); - } - - return nullptr; -} - -void Thread::launchThread() -{ - threadHandle = 0; - pthread_t handle = 0; - - if (pthread_create (&handle, 0, threadEntryProc, this) == 0) - { - pthread_detach (handle); - threadHandle = (void*) handle; - threadId = (ThreadID) threadHandle; - } -} - -void Thread::closeThreadHandle() -{ - threadId = 0; - threadHandle = 0; -} - -void Thread::killThread() -{ - if (threadHandle != 0) - { - #if JUCE_ANDROID - jassertfalse; // pthread_cancel not available! - #else - pthread_cancel ((pthread_t) threadHandle); - #endif - } -} - -void JUCE_CALLTYPE Thread::setCurrentThreadName (const String& name) -{ - #if JUCE_IOS || (JUCE_MAC && defined (MAC_OS_X_VERSION_10_5) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5) - JUCE_AUTORELEASEPOOL - { - [[NSThread currentThread] setName: juceStringToNS (name)]; - } - #elif JUCE_LINUX - #if (__GLIBC__ * 1000 + __GLIBC_MINOR__) >= 2012 - pthread_setname_np (pthread_self(), name.toRawUTF8()); - #else - prctl (PR_SET_NAME, name.toRawUTF8(), 0, 0, 0); - #endif - #endif -} - -bool Thread::setThreadPriority (void* handle, int priority) -{ - struct sched_param param; - int policy; - priority = jlimit (0, 10, priority); - - if (handle == nullptr) - handle = (void*) pthread_self(); - - if (pthread_getschedparam ((pthread_t) handle, &policy, ¶m) != 0) - return false; - - policy = priority == 0 ? SCHED_OTHER : SCHED_RR; - - const int minPriority = sched_get_priority_min (policy); - const int maxPriority = sched_get_priority_max (policy); - - param.sched_priority = ((maxPriority - minPriority) * priority) / 10 + minPriority; - return pthread_setschedparam ((pthread_t) handle, policy, ¶m) == 0; -} - -Thread::ThreadID JUCE_CALLTYPE Thread::getCurrentThreadId() -{ - return (ThreadID) pthread_self(); -} - -void JUCE_CALLTYPE Thread::yield() -{ - sched_yield(); -} - -//============================================================================== -/* Remove this macro if you're having problems compiling the cpu affinity - calls (the API for these has changed about quite a bit in various Linux - versions, and a lot of distros seem to ship with obsolete versions) -*/ -#if defined (CPU_ISSET) && ! defined (SUPPORT_AFFINITIES) - #define SUPPORT_AFFINITIES 1 -#endif - -void JUCE_CALLTYPE Thread::setCurrentThreadAffinityMask (const uint32 affinityMask) -{ - #if SUPPORT_AFFINITIES - cpu_set_t affinity; - CPU_ZERO (&affinity); - - for (int i = 0; i < 32; ++i) - if ((affinityMask & (1 << i)) != 0) - CPU_SET (i, &affinity); - - /* - N.B. If this line causes a compile error, then you've probably not got the latest - version of glibc installed. - - If you don't want to update your copy of glibc and don't care about cpu affinities, - then you can just disable all this stuff by setting the SUPPORT_AFFINITIES macro to 0. - */ - sched_setaffinity (getpid(), sizeof (cpu_set_t), &affinity); - sched_yield(); - - #else - /* affinities aren't supported because either the appropriate header files weren't found, - or the SUPPORT_AFFINITIES macro was turned off - */ - jassertfalse; - (void) affinityMask; - #endif -} - -//============================================================================== -bool DynamicLibrary::open (const String& name) -{ - close(); - handle = dlopen (name.isEmpty() ? nullptr : name.toUTF8().getAddress(), RTLD_LOCAL | RTLD_NOW); - return handle != nullptr; -} - -void DynamicLibrary::close() -{ - if (handle != nullptr) - { - dlclose (handle); - handle = nullptr; - } -} - -void* DynamicLibrary::getFunction (const String& functionName) noexcept -{ - return handle != nullptr ? dlsym (handle, functionName.toUTF8()) : nullptr; -} - - - -//============================================================================== -class ChildProcess::ActiveProcess -{ -public: - ActiveProcess (const StringArray& arguments, int streamFlags) - : childPID (0), pipeHandle (0), readHandle (0) - { - // Looks like you're trying to launch a non-existent exe or a folder (perhaps on OSX - // you're trying to launch the .app folder rather than the actual binary inside it?) - jassert ((! arguments[0].containsChar ('/')) - || File::getCurrentWorkingDirectory().getChildFile (arguments[0]).existsAsFile()); - - int pipeHandles[2] = { 0 }; - - if (pipe (pipeHandles) == 0) - { - const pid_t result = fork(); - - if (result < 0) - { - close (pipeHandles[0]); - close (pipeHandles[1]); - } - else if (result == 0) - { - // we're the child process.. - close (pipeHandles[0]); // close the read handle - - if ((streamFlags & wantStdOut) != 0) - dup2 (pipeHandles[1], 1); // turns the pipe into stdout - else - close (STDOUT_FILENO); - - if ((streamFlags & wantStdErr) != 0) - dup2 (pipeHandles[1], 2); - else - close (STDERR_FILENO); - - close (pipeHandles[1]); - - Array argv; - for (int i = 0; i < arguments.size(); ++i) - if (arguments[i].isNotEmpty()) - argv.add (const_cast (arguments[i].toUTF8().getAddress())); - - argv.add (nullptr); - - execvp (argv[0], argv.getRawDataPointer()); - exit (-1); - } - else - { - // we're the parent process.. - childPID = result; - pipeHandle = pipeHandles[0]; - close (pipeHandles[1]); // close the write handle - } - } - } - - ~ActiveProcess() - { - if (readHandle != 0) - fclose (readHandle); - - if (pipeHandle != 0) - close (pipeHandle); - } - - bool isRunning() const noexcept - { - if (childPID != 0) - { - int childState; - const int pid = waitpid (childPID, &childState, WNOHANG); - return pid == 0 || ! (WIFEXITED (childState) || WIFSIGNALED (childState)); - } - - return false; - } - - int read (void* const dest, const int numBytes) noexcept - { - jassert (dest != nullptr); - - #ifdef fdopen - #error // the zlib headers define this function as NULL! - #endif - - if (readHandle == 0 && childPID != 0) - readHandle = fdopen (pipeHandle, "r"); - - if (readHandle != 0) - return (int) fread (dest, 1, (size_t) numBytes, readHandle); - - return 0; - } - - bool killProcess() const noexcept - { - return ::kill (childPID, SIGKILL) == 0; - } - - uint32 getExitCode() const noexcept - { - if (childPID != 0) - { - int childState = 0; - const int pid = waitpid (childPID, &childState, WNOHANG); - - if (pid >= 0 && WIFEXITED (childState)) - return WEXITSTATUS (childState); - } - - return 0; - } - - int childPID; - -private: - int pipeHandle; - FILE* readHandle; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ActiveProcess) -}; - -bool ChildProcess::start (const String& command, int streamFlags) -{ - return start (StringArray::fromTokens (command, true), streamFlags); -} - -bool ChildProcess::start (const StringArray& args, int streamFlags) -{ - if (args.size() == 0) - return false; - - activeProcess = new ActiveProcess (args, streamFlags); - - if (activeProcess->childPID == 0) - activeProcess = nullptr; - - return activeProcess != nullptr; -} - -//============================================================================== -struct HighResolutionTimer::Pimpl -{ - Pimpl (HighResolutionTimer& t) : owner (t), thread (0), shouldStop (false) - { - } - - ~Pimpl() - { - jassert (thread == 0); - } - - void start (int newPeriod) - { - if (periodMs != newPeriod) - { - if (thread != pthread_self()) - { - stop(); - - periodMs = newPeriod; - shouldStop = false; - - if (pthread_create (&thread, nullptr, timerThread, this) == 0) - setThreadToRealtime (thread, (uint64) newPeriod); - else - jassertfalse; - } - else - { - periodMs = newPeriod; - shouldStop = false; - } - } - } - - void stop() - { - if (thread != 0) - { - shouldStop = true; - - while (thread != 0 && thread != pthread_self()) - Thread::yield(); - } - } - - HighResolutionTimer& owner; - int volatile periodMs; - -private: - pthread_t thread; - bool volatile shouldStop; - - static void* timerThread (void* param) - { - #if JUCE_ANDROID - const AndroidThreadScope androidEnv; - #else - int dummy; - pthread_setcancelstate (PTHREAD_CANCEL_ENABLE, &dummy); - #endif - - reinterpret_cast (param)->timerThread(); - return nullptr; - } - - void timerThread() - { - int lastPeriod = periodMs; - Clock clock (lastPeriod); - - while (! shouldStop) - { - clock.wait(); - owner.hiResTimerCallback(); - - if (lastPeriod != periodMs) - { - lastPeriod = periodMs; - clock = Clock (lastPeriod); - } - } - - periodMs = 0; - thread = 0; - } - - struct Clock - { - #if JUCE_MAC || JUCE_IOS - Clock (double millis) noexcept - { - mach_timebase_info_data_t timebase; - (void) mach_timebase_info (&timebase); - delta = (((uint64_t) (millis * 1000000.0)) * timebase.denom) / timebase.numer; - time = mach_absolute_time(); - } - - void wait() noexcept - { - time += delta; - mach_wait_until (time); - } - - uint64_t time, delta; - - #elif JUCE_ANDROID - Clock (double millis) noexcept : delta ((uint64) (millis * 1000000)) - { - } - - void wait() noexcept - { - struct timespec t; - t.tv_sec = (time_t) (delta / 1000000000); - t.tv_nsec = (long) (delta % 1000000000); - nanosleep (&t, nullptr); - } - - uint64 delta; - #else - Clock (double millis) noexcept : delta ((uint64) (millis * 1000000)) - { - struct timespec t; - clock_gettime (CLOCK_MONOTONIC, &t); - time = 1000000000 * (int64) t.tv_sec + t.tv_nsec; - } - - void wait() noexcept - { - time += delta; - - struct timespec t; - t.tv_sec = (time_t) (time / 1000000000); - t.tv_nsec = (long) (time % 1000000000); - - clock_nanosleep (CLOCK_MONOTONIC, TIMER_ABSTIME, &t, nullptr); - } - - uint64 time, delta; - #endif - }; - - static bool setThreadToRealtime (pthread_t thread, uint64 periodMs) - { - #if JUCE_MAC || JUCE_IOS - thread_time_constraint_policy_data_t policy; - policy.period = (uint32_t) (periodMs * 1000000); - policy.computation = 50000; - policy.constraint = policy.period; - policy.preemptible = true; - - return thread_policy_set (pthread_mach_thread_np (thread), - THREAD_TIME_CONSTRAINT_POLICY, - (thread_policy_t) &policy, - THREAD_TIME_CONSTRAINT_POLICY_COUNT) == KERN_SUCCESS; - - #else - (void) periodMs; - struct sched_param param; - param.sched_priority = sched_get_priority_max (SCHED_RR); - return pthread_setschedparam (thread, SCHED_RR, ¶m) == 0; - - #endif - } - - JUCE_DECLARE_NON_COPYABLE (Pimpl) -}; diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/native/juce_win32_ComSmartPtr.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/native/juce_win32_ComSmartPtr.h deleted file mode 100644 index 0dc0efc20a..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/native/juce_win32_ComSmartPtr.h +++ /dev/null @@ -1,170 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_WIN32_COMSMARTPTR_H_INCLUDED -#define JUCE_WIN32_COMSMARTPTR_H_INCLUDED - -#if ! (defined (_MSC_VER) || defined (__uuidof)) -template struct UUIDGetter { static CLSID get() { jassertfalse; return CLSID(); } }; -#define __uuidof(x) UUIDGetter::get() -#endif - -inline GUID uuidFromString (const char* const s) noexcept -{ - unsigned long p0; - unsigned int p1, p2, p3, p4, p5, p6, p7, p8, p9, p10; - - #ifndef _MSC_VER - sscanf - #else - sscanf_s - #endif - (s, "%08lX-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X", - &p0, &p1, &p2, &p3, &p4, &p5, &p6, &p7, &p8, &p9, &p10); - - GUID g = { p0, (uint16) p1, (uint16) p2, { (uint8) p3, (uint8) p4, (uint8) p5, (uint8) p6, - (uint8) p7, (uint8) p8, (uint8) p9, (uint8) p10 }}; - return g; -} - -//============================================================================== -/** A simple COM smart pointer. -*/ -template -class ComSmartPtr -{ -public: - ComSmartPtr() throw() : p (0) {} - ComSmartPtr (ComClass* const obj) : p (obj) { if (p) p->AddRef(); } - ComSmartPtr (const ComSmartPtr& other) : p (other.p) { if (p) p->AddRef(); } - ~ComSmartPtr() { release(); } - - operator ComClass*() const throw() { return p; } - ComClass& operator*() const throw() { return *p; } - ComClass* operator->() const throw() { return p; } - - ComSmartPtr& operator= (ComClass* const newP) - { - if (newP != 0) newP->AddRef(); - release(); - p = newP; - return *this; - } - - ComSmartPtr& operator= (const ComSmartPtr& newP) { return operator= (newP.p); } - - // Releases and nullifies this pointer and returns its address - ComClass** resetAndGetPointerAddress() - { - release(); - p = 0; - return &p; - } - - HRESULT CoCreateInstance (REFCLSID classUUID, DWORD dwClsContext = CLSCTX_INPROC_SERVER) - { - HRESULT hr = ::CoCreateInstance (classUUID, 0, dwClsContext, __uuidof (ComClass), (void**) resetAndGetPointerAddress()); - jassert (hr != CO_E_NOTINITIALIZED); // You haven't called CoInitialize for the current thread! - return hr; - } - - template - HRESULT QueryInterface (REFCLSID classUUID, ComSmartPtr& destObject) const - { - if (p == 0) - return E_POINTER; - - return p->QueryInterface (classUUID, (void**) destObject.resetAndGetPointerAddress()); - } - - template - HRESULT QueryInterface (ComSmartPtr& destObject) const - { - return this->QueryInterface (__uuidof (OtherComClass), destObject); - } - -private: - ComClass* p; - - void release() { if (p != 0) p->Release(); } - - ComClass** operator&() throw(); // private to avoid it being used accidentally -}; - -//============================================================================== -#define JUCE_COMRESULT HRESULT __stdcall - -//============================================================================== -template -class ComBaseClassHelperBase : public ComClass -{ -public: - ComBaseClassHelperBase (unsigned int initialRefCount) : refCount (initialRefCount) {} - virtual ~ComBaseClassHelperBase() {} - - ULONG __stdcall AddRef() { return ++refCount; } - ULONG __stdcall Release() { const ULONG r = --refCount; if (r == 0) delete this; return r; } - -protected: - ULONG refCount; - - JUCE_COMRESULT QueryInterface (REFIID refId, void** result) - { - if (refId == IID_IUnknown) - return castToType (result); - - *result = 0; - return E_NOINTERFACE; - } - - template - JUCE_COMRESULT castToType (void** result) - { - this->AddRef(); *result = dynamic_cast (this); return S_OK; - } -}; - -/** Handy base class for writing COM objects, providing ref-counting and a basic QueryInterface method. -*/ -template -class ComBaseClassHelper : public ComBaseClassHelperBase -{ -public: - ComBaseClassHelper (unsigned int initialRefCount = 1) : ComBaseClassHelperBase (initialRefCount) {} - ~ComBaseClassHelper() {} - - JUCE_COMRESULT QueryInterface (REFIID refId, void** result) - { - if (refId == __uuidof (ComClass)) - return this->template castToType (result); - - return ComBaseClassHelperBase ::QueryInterface (refId, result); - } -}; - -#endif // JUCE_WIN32_COMSMARTPTR_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/native/juce_win32_Files.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/native/juce_win32_Files.cpp deleted file mode 100644 index a77aa5aaca..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/native/juce_win32_Files.cpp +++ /dev/null @@ -1,999 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef INVALID_FILE_ATTRIBUTES - #define INVALID_FILE_ATTRIBUTES ((DWORD) -1) -#endif - -//============================================================================== -namespace WindowsFileHelpers -{ - DWORD getAtts (const String& path) - { - return GetFileAttributes (path.toWideCharPointer()); - } - - int64 fileTimeToTime (const FILETIME* const ft) - { - static_jassert (sizeof (ULARGE_INTEGER) == sizeof (FILETIME)); // tell me if this fails! - - return (int64) ((reinterpret_cast (ft)->QuadPart - 116444736000000000LL) / 10000); - } - - FILETIME* timeToFileTime (const int64 time, FILETIME* const ft) noexcept - { - if (time <= 0) - return nullptr; - - reinterpret_cast (ft)->QuadPart = (ULONGLONG) (time * 10000 + 116444736000000000LL); - return ft; - } - - String getDriveFromPath (String path) - { - if (path.isNotEmpty() && path[1] == ':' && path[2] == 0) - path << '\\'; - - const size_t numBytes = CharPointer_UTF16::getBytesRequiredFor (path.getCharPointer()) + 4; - HeapBlock pathCopy; - pathCopy.calloc (numBytes, 1); - path.copyToUTF16 (pathCopy, numBytes); - - if (PathStripToRoot (pathCopy)) - path = static_cast (pathCopy); - - return path; - } - - int64 getDiskSpaceInfo (const String& path, const bool total) - { - ULARGE_INTEGER spc, tot, totFree; - - if (GetDiskFreeSpaceEx (getDriveFromPath (path).toWideCharPointer(), &spc, &tot, &totFree)) - return total ? (int64) tot.QuadPart - : (int64) spc.QuadPart; - - return 0; - } - - unsigned int getWindowsDriveType (const String& path) - { - return GetDriveType (getDriveFromPath (path).toWideCharPointer()); - } - - File getSpecialFolderPath (int type) - { - WCHAR path [MAX_PATH + 256]; - - if (SHGetSpecialFolderPath (0, path, type, FALSE)) - return File (String (path)); - - return File(); - } - - File getModuleFileName (HINSTANCE moduleHandle) - { - WCHAR dest [MAX_PATH + 256]; - dest[0] = 0; - GetModuleFileName (moduleHandle, dest, (DWORD) numElementsInArray (dest)); - return File (String (dest)); - } - - Result getResultForLastError() - { - TCHAR messageBuffer [256] = { 0 }; - - FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, - nullptr, GetLastError(), MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), - messageBuffer, (DWORD) numElementsInArray (messageBuffer) - 1, nullptr); - - return Result::fail (String (messageBuffer)); - } -} - -//============================================================================== -const juce_wchar File::separator = '\\'; -const String File::separatorString ("\\"); - - -//============================================================================== -bool File::exists() const -{ - return fullPath.isNotEmpty() - && WindowsFileHelpers::getAtts (fullPath) != INVALID_FILE_ATTRIBUTES; -} - -bool File::existsAsFile() const -{ - return fullPath.isNotEmpty() - && (WindowsFileHelpers::getAtts (fullPath) & FILE_ATTRIBUTE_DIRECTORY) == 0; -} - -bool File::isDirectory() const -{ - const DWORD attr = WindowsFileHelpers::getAtts (fullPath); - return ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0) && (attr != INVALID_FILE_ATTRIBUTES); -} - -bool File::hasWriteAccess() const -{ - if (exists()) - return (WindowsFileHelpers::getAtts (fullPath) & FILE_ATTRIBUTE_READONLY) == 0; - - // on windows, it seems that even read-only directories can still be written into, - // so checking the parent directory's permissions would return the wrong result.. - return true; -} - -bool File::setFileReadOnlyInternal (const bool shouldBeReadOnly) const -{ - const DWORD oldAtts = WindowsFileHelpers::getAtts (fullPath); - - if (oldAtts == INVALID_FILE_ATTRIBUTES) - return false; - - const DWORD newAtts = shouldBeReadOnly ? (oldAtts | FILE_ATTRIBUTE_READONLY) - : (oldAtts & ~FILE_ATTRIBUTE_READONLY); - return newAtts == oldAtts - || SetFileAttributes (fullPath.toWideCharPointer(), newAtts) != FALSE; -} - -bool File::isHidden() const -{ - return (WindowsFileHelpers::getAtts (fullPath) & FILE_ATTRIBUTE_HIDDEN) != 0; -} - -//============================================================================== -bool File::deleteFile() const -{ - if (! exists()) - return true; - - return isDirectory() ? RemoveDirectory (fullPath.toWideCharPointer()) != 0 - : DeleteFile (fullPath.toWideCharPointer()) != 0; -} - -bool File::moveToTrash() const -{ - if (! exists()) - return true; - - // The string we pass in must be double null terminated.. - const size_t numBytes = CharPointer_UTF16::getBytesRequiredFor (fullPath.getCharPointer()) + 8; - HeapBlock doubleNullTermPath; - doubleNullTermPath.calloc (numBytes, 1); - fullPath.copyToUTF16 (doubleNullTermPath, numBytes); - - SHFILEOPSTRUCT fos = { 0 }; - fos.wFunc = FO_DELETE; - fos.pFrom = doubleNullTermPath; - fos.fFlags = FOF_ALLOWUNDO | FOF_NOERRORUI | FOF_SILENT | FOF_NOCONFIRMATION - | FOF_NOCONFIRMMKDIR | FOF_RENAMEONCOLLISION; - - return SHFileOperation (&fos) == 0; -} - -bool File::copyInternal (const File& dest) const -{ - return CopyFile (fullPath.toWideCharPointer(), dest.getFullPathName().toWideCharPointer(), false) != 0; -} - -bool File::moveInternal (const File& dest) const -{ - return MoveFile (fullPath.toWideCharPointer(), dest.getFullPathName().toWideCharPointer()) != 0; -} - -Result File::createDirectoryInternal (const String& fileName) const -{ - return CreateDirectory (fileName.toWideCharPointer(), 0) ? Result::ok() - : WindowsFileHelpers::getResultForLastError(); -} - -//============================================================================== -int64 juce_fileSetPosition (void* handle, int64 pos) -{ - LARGE_INTEGER li; - li.QuadPart = pos; - li.LowPart = SetFilePointer ((HANDLE) handle, (LONG) li.LowPart, &li.HighPart, FILE_BEGIN); // (returns -1 if it fails) - return li.QuadPart; -} - -void FileInputStream::openHandle() -{ - HANDLE h = CreateFile (file.getFullPathName().toWideCharPointer(), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, - OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, 0); - - if (h != INVALID_HANDLE_VALUE) - fileHandle = (void*) h; - else - status = WindowsFileHelpers::getResultForLastError(); -} - -FileInputStream::~FileInputStream() -{ - CloseHandle ((HANDLE) fileHandle); -} - -size_t FileInputStream::readInternal (void* buffer, size_t numBytes) -{ - if (fileHandle != 0) - { - DWORD actualNum = 0; - if (! ReadFile ((HANDLE) fileHandle, buffer, (DWORD) numBytes, &actualNum, 0)) - status = WindowsFileHelpers::getResultForLastError(); - - return (size_t) actualNum; - } - - return 0; -} - -//============================================================================== -void FileOutputStream::openHandle() -{ - HANDLE h = CreateFile (file.getFullPathName().toWideCharPointer(), GENERIC_WRITE, FILE_SHARE_READ, 0, - OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); - - if (h != INVALID_HANDLE_VALUE) - { - LARGE_INTEGER li; - li.QuadPart = 0; - li.LowPart = SetFilePointer (h, 0, &li.HighPart, FILE_END); - - if (li.LowPart != INVALID_SET_FILE_POINTER) - { - fileHandle = (void*) h; - currentPosition = li.QuadPart; - return; - } - } - - status = WindowsFileHelpers::getResultForLastError(); -} - -void FileOutputStream::closeHandle() -{ - CloseHandle ((HANDLE) fileHandle); -} - -ssize_t FileOutputStream::writeInternal (const void* buffer, size_t numBytes) -{ - if (fileHandle != nullptr) - { - DWORD actualNum = 0; - if (! WriteFile ((HANDLE) fileHandle, buffer, (DWORD) numBytes, &actualNum, 0)) - status = WindowsFileHelpers::getResultForLastError(); - - return (ssize_t) actualNum; - } - - return 0; -} - -void FileOutputStream::flushInternal() -{ - if (fileHandle != nullptr) - if (! FlushFileBuffers ((HANDLE) fileHandle)) - status = WindowsFileHelpers::getResultForLastError(); -} - -Result FileOutputStream::truncate() -{ - if (fileHandle == nullptr) - return status; - - flush(); - return SetEndOfFile ((HANDLE) fileHandle) ? Result::ok() - : WindowsFileHelpers::getResultForLastError(); -} - -//============================================================================== -void MemoryMappedFile::openInternal (const File& file, AccessMode mode) -{ - jassert (mode == readOnly || mode == readWrite); - - if (range.getStart() > 0) - { - SYSTEM_INFO systemInfo; - GetNativeSystemInfo (&systemInfo); - - range.setStart (range.getStart() - (range.getStart() % systemInfo.dwAllocationGranularity)); - } - - DWORD accessMode = GENERIC_READ, createType = OPEN_EXISTING; - DWORD protect = PAGE_READONLY, access = FILE_MAP_READ; - - if (mode == readWrite) - { - accessMode = GENERIC_READ | GENERIC_WRITE; - createType = OPEN_ALWAYS; - protect = PAGE_READWRITE; - access = FILE_MAP_ALL_ACCESS; - } - - HANDLE h = CreateFile (file.getFullPathName().toWideCharPointer(), accessMode, FILE_SHARE_READ, 0, - createType, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, 0); - - if (h != INVALID_HANDLE_VALUE) - { - fileHandle = (void*) h; - - HANDLE mappingHandle = CreateFileMapping (h, 0, protect, (DWORD) (range.getEnd() >> 32), (DWORD) range.getEnd(), 0); - - if (mappingHandle != 0) - { - address = MapViewOfFile (mappingHandle, access, (DWORD) (range.getStart() >> 32), - (DWORD) range.getStart(), (SIZE_T) range.getLength()); - - if (address == nullptr) - range = Range(); - - CloseHandle (mappingHandle); - } - } -} - -MemoryMappedFile::~MemoryMappedFile() -{ - if (address != nullptr) - UnmapViewOfFile (address); - - if (fileHandle != nullptr) - CloseHandle ((HANDLE) fileHandle); -} - -//============================================================================== -int64 File::getSize() const -{ - WIN32_FILE_ATTRIBUTE_DATA attributes; - - if (GetFileAttributesEx (fullPath.toWideCharPointer(), GetFileExInfoStandard, &attributes)) - return (((int64) attributes.nFileSizeHigh) << 32) | attributes.nFileSizeLow; - - return 0; -} - -void File::getFileTimesInternal (int64& modificationTime, int64& accessTime, int64& creationTime) const -{ - using namespace WindowsFileHelpers; - WIN32_FILE_ATTRIBUTE_DATA attributes; - - if (GetFileAttributesEx (fullPath.toWideCharPointer(), GetFileExInfoStandard, &attributes)) - { - modificationTime = fileTimeToTime (&attributes.ftLastWriteTime); - creationTime = fileTimeToTime (&attributes.ftCreationTime); - accessTime = fileTimeToTime (&attributes.ftLastAccessTime); - } - else - { - creationTime = accessTime = modificationTime = 0; - } -} - -bool File::setFileTimesInternal (int64 modificationTime, int64 accessTime, int64 creationTime) const -{ - using namespace WindowsFileHelpers; - - bool ok = false; - HANDLE h = CreateFile (fullPath.toWideCharPointer(), GENERIC_WRITE, FILE_SHARE_READ, 0, - OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); - - if (h != INVALID_HANDLE_VALUE) - { - FILETIME m, a, c; - - ok = SetFileTime (h, - timeToFileTime (creationTime, &c), - timeToFileTime (accessTime, &a), - timeToFileTime (modificationTime, &m)) != 0; - - CloseHandle (h); - } - - return ok; -} - -//============================================================================== -void File::findFileSystemRoots (Array& destArray) -{ - TCHAR buffer [2048] = { 0 }; - GetLogicalDriveStrings (2048, buffer); - - const TCHAR* n = buffer; - StringArray roots; - - while (*n != 0) - { - roots.add (String (n)); - - while (*n++ != 0) - {} - } - - roots.sort (true); - - for (int i = 0; i < roots.size(); ++i) - destArray.add (roots [i]); -} - -//============================================================================== -String File::getVolumeLabel() const -{ - TCHAR dest[64]; - if (! GetVolumeInformation (WindowsFileHelpers::getDriveFromPath (getFullPathName()).toWideCharPointer(), dest, - (DWORD) numElementsInArray (dest), 0, 0, 0, 0, 0)) - dest[0] = 0; - - return dest; -} - -int File::getVolumeSerialNumber() const -{ - TCHAR dest[64]; - DWORD serialNum; - - if (! GetVolumeInformation (WindowsFileHelpers::getDriveFromPath (getFullPathName()).toWideCharPointer(), dest, - (DWORD) numElementsInArray (dest), &serialNum, 0, 0, 0, 0)) - return 0; - - return (int) serialNum; -} - -int64 File::getBytesFreeOnVolume() const -{ - return WindowsFileHelpers::getDiskSpaceInfo (getFullPathName(), false); -} - -int64 File::getVolumeTotalSize() const -{ - return WindowsFileHelpers::getDiskSpaceInfo (getFullPathName(), true); -} - -uint64 File::getFileIdentifier() const -{ - uint64 result = 0; - - HANDLE h = CreateFile (getFullPathName().toWideCharPointer(), - GENERIC_READ, FILE_SHARE_READ, nullptr, - OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0); - - if (h != INVALID_HANDLE_VALUE) - { - BY_HANDLE_FILE_INFORMATION info; - zerostruct (info); - - if (GetFileInformationByHandle (h, &info)) - result = (((uint64) info.nFileIndexHigh) << 32) | info.nFileIndexLow; - - CloseHandle (h); - } - - return result; -} - -//============================================================================== -bool File::isOnCDRomDrive() const -{ - return WindowsFileHelpers::getWindowsDriveType (getFullPathName()) == DRIVE_CDROM; -} - -bool File::isOnHardDisk() const -{ - if (fullPath.isEmpty()) - return false; - - const unsigned int n = WindowsFileHelpers::getWindowsDriveType (getFullPathName()); - - if (fullPath.toLowerCase()[0] <= 'b' && fullPath[1] == ':') - return n != DRIVE_REMOVABLE; - - return n != DRIVE_CDROM && n != DRIVE_REMOTE; -} - -bool File::isOnRemovableDrive() const -{ - if (fullPath.isEmpty()) - return false; - - const unsigned int n = WindowsFileHelpers::getWindowsDriveType (getFullPathName()); - - return n == DRIVE_CDROM - || n == DRIVE_REMOTE - || n == DRIVE_REMOVABLE - || n == DRIVE_RAMDISK; -} - -//============================================================================== -File JUCE_CALLTYPE File::getSpecialLocation (const SpecialLocationType type) -{ - int csidlType = 0; - - switch (type) - { - case userHomeDirectory: csidlType = CSIDL_PROFILE; break; - case userDocumentsDirectory: csidlType = CSIDL_PERSONAL; break; - case userDesktopDirectory: csidlType = CSIDL_DESKTOP; break; - case userApplicationDataDirectory: csidlType = CSIDL_APPDATA; break; - case commonApplicationDataDirectory: csidlType = CSIDL_COMMON_APPDATA; break; - case commonDocumentsDirectory: csidlType = CSIDL_COMMON_DOCUMENTS; break; - case globalApplicationsDirectory: csidlType = CSIDL_PROGRAM_FILES; break; - case userMusicDirectory: csidlType = 0x0d; /*CSIDL_MYMUSIC*/ break; - case userMoviesDirectory: csidlType = 0x0e; /*CSIDL_MYVIDEO*/ break; - case userPicturesDirectory: csidlType = 0x27; /*CSIDL_MYPICTURES*/ break; - - case tempDirectory: - { - WCHAR dest [2048]; - dest[0] = 0; - GetTempPath ((DWORD) numElementsInArray (dest), dest); - return File (String (dest)); - } - - case windowsSystemDirectory: - { - WCHAR dest [2048]; - dest[0] = 0; - GetSystemDirectoryW (dest, (UINT) numElementsInArray (dest)); - return File (String (dest)); - } - - case invokedExecutableFile: - case currentExecutableFile: - case currentApplicationFile: - return WindowsFileHelpers::getModuleFileName ((HINSTANCE) Process::getCurrentModuleInstanceHandle()); - - case hostApplicationPath: - return WindowsFileHelpers::getModuleFileName (0); - - default: - jassertfalse; // unknown type? - return File(); - } - - return WindowsFileHelpers::getSpecialFolderPath (csidlType); -} - -//============================================================================== -File File::getCurrentWorkingDirectory() -{ - WCHAR dest [MAX_PATH + 256]; - dest[0] = 0; - GetCurrentDirectory ((DWORD) numElementsInArray (dest), dest); - return File (String (dest)); -} - -bool File::setAsCurrentWorkingDirectory() const -{ - return SetCurrentDirectory (getFullPathName().toWideCharPointer()) != FALSE; -} - -//============================================================================== -String File::getVersion() const -{ - String result; - - DWORD handle = 0; - DWORD bufferSize = GetFileVersionInfoSize (getFullPathName().toWideCharPointer(), &handle); - HeapBlock buffer; - buffer.calloc (bufferSize); - - if (GetFileVersionInfo (getFullPathName().toWideCharPointer(), 0, bufferSize, buffer)) - { - VS_FIXEDFILEINFO* vffi; - UINT len = 0; - - if (VerQueryValue (buffer, (LPTSTR) _T("\\"), (LPVOID*) &vffi, &len)) - { - result << (int) HIWORD (vffi->dwFileVersionMS) << '.' - << (int) LOWORD (vffi->dwFileVersionMS) << '.' - << (int) HIWORD (vffi->dwFileVersionLS) << '.' - << (int) LOWORD (vffi->dwFileVersionLS); - } - } - - return result; -} - -//============================================================================== -bool File::isLink() const -{ - return hasFileExtension (".lnk"); -} - -File File::getLinkedTarget() const -{ - File result (*this); - String p (getFullPathName()); - - if (! exists()) - p += ".lnk"; - else if (! hasFileExtension (".lnk")) - return result; - - ComSmartPtr shellLink; - ComSmartPtr persistFile; - - if (SUCCEEDED (shellLink.CoCreateInstance (CLSID_ShellLink)) - && SUCCEEDED (shellLink.QueryInterface (persistFile)) - && SUCCEEDED (persistFile->Load (p.toWideCharPointer(), STGM_READ)) - && SUCCEEDED (shellLink->Resolve (0, SLR_ANY_MATCH | SLR_NO_UI))) - { - WIN32_FIND_DATA winFindData; - WCHAR resolvedPath [MAX_PATH]; - - if (SUCCEEDED (shellLink->GetPath (resolvedPath, MAX_PATH, &winFindData, SLGP_UNCPRIORITY))) - result = File (resolvedPath); - } - - return result; -} - -bool File::createLink (const String& description, const File& linkFileToCreate) const -{ - linkFileToCreate.deleteFile(); - - ComSmartPtr shellLink; - ComSmartPtr persistFile; - - CoInitialize (0); - - return SUCCEEDED (shellLink.CoCreateInstance (CLSID_ShellLink)) - && SUCCEEDED (shellLink->SetPath (getFullPathName().toWideCharPointer())) - && SUCCEEDED (shellLink->SetDescription (description.toWideCharPointer())) - && SUCCEEDED (shellLink.QueryInterface (persistFile)) - && SUCCEEDED (persistFile->Save (linkFileToCreate.getFullPathName().toWideCharPointer(), TRUE)); -} - -//============================================================================== -class DirectoryIterator::NativeIterator::Pimpl -{ -public: - Pimpl (const File& directory, const String& wildCard) - : directoryWithWildCard (File::addTrailingSeparator (directory.getFullPathName()) + wildCard), - handle (INVALID_HANDLE_VALUE) - { - } - - ~Pimpl() - { - if (handle != INVALID_HANDLE_VALUE) - FindClose (handle); - } - - bool next (String& filenameFound, - bool* const isDir, bool* const isHidden, int64* const fileSize, - Time* const modTime, Time* const creationTime, bool* const isReadOnly) - { - using namespace WindowsFileHelpers; - WIN32_FIND_DATA findData; - - if (handle == INVALID_HANDLE_VALUE) - { - handle = FindFirstFile (directoryWithWildCard.toWideCharPointer(), &findData); - - if (handle == INVALID_HANDLE_VALUE) - return false; - } - else - { - if (FindNextFile (handle, &findData) == 0) - return false; - } - - filenameFound = findData.cFileName; - - if (isDir != nullptr) *isDir = ((findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0); - if (isHidden != nullptr) *isHidden = ((findData.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) != 0); - if (isReadOnly != nullptr) *isReadOnly = ((findData.dwFileAttributes & FILE_ATTRIBUTE_READONLY) != 0); - if (fileSize != nullptr) *fileSize = findData.nFileSizeLow + (((int64) findData.nFileSizeHigh) << 32); - if (modTime != nullptr) *modTime = Time (fileTimeToTime (&findData.ftLastWriteTime)); - if (creationTime != nullptr) *creationTime = Time (fileTimeToTime (&findData.ftCreationTime)); - - return true; - } - -private: - const String directoryWithWildCard; - HANDLE handle; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Pimpl) -}; - -DirectoryIterator::NativeIterator::NativeIterator (const File& directory, const String& wildCard) - : pimpl (new DirectoryIterator::NativeIterator::Pimpl (directory, wildCard)) -{ -} - -DirectoryIterator::NativeIterator::~NativeIterator() -{ -} - -bool DirectoryIterator::NativeIterator::next (String& filenameFound, - bool* const isDir, bool* const isHidden, int64* const fileSize, - Time* const modTime, Time* const creationTime, bool* const isReadOnly) -{ - return pimpl->next (filenameFound, isDir, isHidden, fileSize, modTime, creationTime, isReadOnly); -} - - -//============================================================================== -bool JUCE_CALLTYPE Process::openDocument (const String& fileName, const String& parameters) -{ - HINSTANCE hInstance = 0; - - JUCE_TRY - { - hInstance = ShellExecute (0, 0, fileName.toWideCharPointer(), - parameters.toWideCharPointer(), 0, SW_SHOWDEFAULT); - } - JUCE_CATCH_ALL - - return hInstance > (HINSTANCE) 32; -} - -void File::revealToUser() const -{ - DynamicLibrary dll ("Shell32.dll"); - JUCE_LOAD_WINAPI_FUNCTION (dll, ILCreateFromPathW, ilCreateFromPathW, ITEMIDLIST*, (LPCWSTR)) - JUCE_LOAD_WINAPI_FUNCTION (dll, ILFree, ilFree, void, (ITEMIDLIST*)) - JUCE_LOAD_WINAPI_FUNCTION (dll, SHOpenFolderAndSelectItems, shOpenFolderAndSelectItems, HRESULT, (ITEMIDLIST*, UINT, void*, DWORD)) - - if (ilCreateFromPathW != nullptr && shOpenFolderAndSelectItems != nullptr && ilFree != nullptr) - { - if (ITEMIDLIST* const itemIDList = ilCreateFromPathW (fullPath.toWideCharPointer())) - { - shOpenFolderAndSelectItems (itemIDList, 0, nullptr, 0); - ilFree (itemIDList); - } - } -} - -//============================================================================== -class NamedPipe::Pimpl -{ -public: - Pimpl (const String& pipeName, const bool createPipe) - : filename ("\\\\.\\pipe\\" + File::createLegalFileName (pipeName)), - pipeH (INVALID_HANDLE_VALUE), - cancelEvent (CreateEvent (0, FALSE, FALSE, 0)), - connected (false), ownsPipe (createPipe), shouldStop (false) - { - if (createPipe) - pipeH = CreateNamedPipe (filename.toWideCharPointer(), - PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, 0, - PIPE_UNLIMITED_INSTANCES, 4096, 4096, 0, 0); - } - - ~Pimpl() - { - disconnectPipe(); - - if (pipeH != INVALID_HANDLE_VALUE) - CloseHandle (pipeH); - - CloseHandle (cancelEvent); - } - - bool connect (const int timeOutMs) - { - if (! ownsPipe) - { - if (pipeH != INVALID_HANDLE_VALUE) - return true; - - const Time timeOutEnd (Time::getCurrentTime() + RelativeTime::milliseconds (timeOutMs)); - - for (;;) - { - { - const ScopedLock sl (createFileLock); - - if (pipeH == INVALID_HANDLE_VALUE) - pipeH = CreateFile (filename.toWideCharPointer(), - GENERIC_READ | GENERIC_WRITE, 0, 0, - OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0); - } - - if (pipeH != INVALID_HANDLE_VALUE) - return true; - - if (shouldStop || (timeOutMs >= 0 && Time::getCurrentTime() > timeOutEnd)) - return false; - - Thread::sleep (1); - } - } - - if (! connected) - { - OverlappedEvent over; - - if (ConnectNamedPipe (pipeH, &over.over) == 0) - { - switch (GetLastError()) - { - case ERROR_PIPE_CONNECTED: connected = true; break; - case ERROR_IO_PENDING: - case ERROR_PIPE_LISTENING: connected = waitForIO (over, timeOutMs); break; - default: break; - } - } - } - - return connected; - } - - void disconnectPipe() - { - if (ownsPipe && connected) - { - DisconnectNamedPipe (pipeH); - connected = false; - } - } - - int read (void* destBuffer, const int maxBytesToRead, const int timeOutMilliseconds) - { - while (connect (timeOutMilliseconds)) - { - if (maxBytesToRead <= 0) - return 0; - - OverlappedEvent over; - unsigned long numRead; - - if (ReadFile (pipeH, destBuffer, (DWORD) maxBytesToRead, &numRead, &over.over)) - return (int) numRead; - - const DWORD lastError = GetLastError(); - - if (lastError == ERROR_IO_PENDING) - { - if (! waitForIO (over, timeOutMilliseconds)) - return -1; - - if (GetOverlappedResult (pipeH, &over.over, &numRead, FALSE)) - return (int) numRead; - } - - if (ownsPipe && (GetLastError() == ERROR_BROKEN_PIPE || GetLastError() == ERROR_PIPE_NOT_CONNECTED)) - disconnectPipe(); - else - break; - } - - return -1; - } - - int write (const void* sourceBuffer, int numBytesToWrite, int timeOutMilliseconds) - { - if (connect (timeOutMilliseconds)) - { - if (numBytesToWrite <= 0) - return 0; - - OverlappedEvent over; - unsigned long numWritten; - - if (WriteFile (pipeH, sourceBuffer, (DWORD) numBytesToWrite, &numWritten, &over.over)) - return (int) numWritten; - - if (GetLastError() == ERROR_IO_PENDING) - { - if (! waitForIO (over, timeOutMilliseconds)) - return -1; - - if (GetOverlappedResult (pipeH, &over.over, &numWritten, FALSE)) - return (int) numWritten; - - if (GetLastError() == ERROR_BROKEN_PIPE && ownsPipe) - disconnectPipe(); - } - } - - return -1; - } - - const String filename; - HANDLE pipeH, cancelEvent; - bool connected, ownsPipe, shouldStop; - CriticalSection createFileLock; - -private: - struct OverlappedEvent - { - OverlappedEvent() - { - zerostruct (over); - over.hEvent = CreateEvent (0, TRUE, FALSE, 0); - } - - ~OverlappedEvent() - { - CloseHandle (over.hEvent); - } - - OVERLAPPED over; - }; - - bool waitForIO (OverlappedEvent& over, int timeOutMilliseconds) - { - if (shouldStop) - return false; - - HANDLE handles[] = { over.over.hEvent, cancelEvent }; - DWORD waitResult = WaitForMultipleObjects (2, handles, FALSE, - timeOutMilliseconds >= 0 ? timeOutMilliseconds - : INFINITE); - - if (waitResult == WAIT_OBJECT_0) - return true; - - CancelIo (pipeH); - return false; - } - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Pimpl) -}; - -void NamedPipe::close() -{ - if (pimpl != nullptr) - { - pimpl->shouldStop = true; - SetEvent (pimpl->cancelEvent); - - ScopedWriteLock sl (lock); - pimpl = nullptr; - } -} - -bool NamedPipe::openInternal (const String& pipeName, const bool createPipe) -{ - pimpl = new Pimpl (pipeName, createPipe); - - if (createPipe && pimpl->pipeH == INVALID_HANDLE_VALUE) - { - pimpl = nullptr; - return false; - } - - return true; -} - -int NamedPipe::read (void* destBuffer, int maxBytesToRead, int timeOutMilliseconds) -{ - ScopedReadLock sl (lock); - return pimpl != nullptr ? pimpl->read (destBuffer, maxBytesToRead, timeOutMilliseconds) : -1; -} - -int NamedPipe::write (const void* sourceBuffer, int numBytesToWrite, int timeOutMilliseconds) -{ - ScopedReadLock sl (lock); - return pimpl != nullptr ? pimpl->write (sourceBuffer, numBytesToWrite, timeOutMilliseconds) : -1; -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/native/juce_win32_Network.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/native/juce_win32_Network.cpp deleted file mode 100644 index f0b6061b41..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/native/juce_win32_Network.cpp +++ /dev/null @@ -1,506 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef INTERNET_FLAG_NEED_FILE - #define INTERNET_FLAG_NEED_FILE 0x00000010 -#endif - -#ifndef INTERNET_OPTION_DISABLE_AUTODIAL - #define INTERNET_OPTION_DISABLE_AUTODIAL 70 -#endif - -//============================================================================== -class WebInputStream : public InputStream -{ -public: - WebInputStream (const String& address_, bool isPost_, const MemoryBlock& postData_, - URL::OpenStreamProgressCallback* progressCallback, void* progressCallbackContext, - const String& headers_, int timeOutMs_, StringPairArray* responseHeaders) - : statusCode (0), connection (0), request (0), - address (address_), headers (headers_), postData (postData_), position (0), - finished (false), isPost (isPost_), timeOutMs (timeOutMs_) - { - for (int maxRedirects = 10; --maxRedirects >= 0;) - { - createConnection (progressCallback, progressCallbackContext); - - if (! isError()) - { - DWORD bufferSizeBytes = 4096; - StringPairArray headers (false); - - for (;;) - { - HeapBlock buffer ((size_t) bufferSizeBytes); - - if (HttpQueryInfo (request, HTTP_QUERY_RAW_HEADERS_CRLF, buffer.getData(), &bufferSizeBytes, 0)) - { - StringArray headersArray; - headersArray.addLines (String (reinterpret_cast (buffer.getData()))); - - for (int i = 0; i < headersArray.size(); ++i) - { - const String& header = headersArray[i]; - const String key (header.upToFirstOccurrenceOf (": ", false, false)); - const String value (header.fromFirstOccurrenceOf (": ", false, false)); - const String previousValue (headers[key]); - headers.set (key, previousValue.isEmpty() ? value : (previousValue + "," + value)); - } - - break; - } - - if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) - break; - - bufferSizeBytes += 4096; - } - - DWORD status = 0; - DWORD statusSize = sizeof (status); - - if (HttpQueryInfo (request, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER, &status, &statusSize, 0)) - { - statusCode = (int) status; - - if (status == 301 || status == 302 || status == 303 || status == 307) - { - const String newLocation (headers["Location"]); - - if (newLocation.isNotEmpty() && newLocation != address) - { - address = newLocation; - continue; - } - } - } - - if (responseHeaders != nullptr) - responseHeaders->addArray (headers); - } - - break; - } - } - - ~WebInputStream() - { - close(); - } - - //============================================================================== - bool isError() const { return request == 0; } - bool isExhausted() { return finished; } - int64 getPosition() { return position; } - - int64 getTotalLength() - { - if (! isError()) - { - DWORD index = 0, result = 0, size = sizeof (result); - - if (HttpQueryInfo (request, HTTP_QUERY_CONTENT_LENGTH | HTTP_QUERY_FLAG_NUMBER, &result, &size, &index)) - return (int64) result; - } - - return -1; - } - - int read (void* buffer, int bytesToRead) - { - jassert (buffer != nullptr && bytesToRead >= 0); - DWORD bytesRead = 0; - - if (! (finished || isError())) - { - InternetReadFile (request, buffer, (DWORD) bytesToRead, &bytesRead); - position += bytesRead; - - if (bytesRead == 0) - finished = true; - } - - return (int) bytesRead; - } - - bool setPosition (int64 wantedPos) - { - if (isError()) - return false; - - if (wantedPos != position) - { - finished = false; - position = (int64) InternetSetFilePointer (request, (LONG) wantedPos, 0, FILE_BEGIN, 0); - - if (position == wantedPos) - return true; - - if (wantedPos < position) - { - close(); - position = 0; - createConnection (0, 0); - } - - skipNextBytes (wantedPos - position); - } - - return true; - } - - int statusCode; - -private: - //============================================================================== - HINTERNET connection, request; - String address, headers; - MemoryBlock postData; - int64 position; - bool finished; - const bool isPost; - int timeOutMs; - - void close() - { - if (request != 0) - { - InternetCloseHandle (request); - request = 0; - } - - if (connection != 0) - { - InternetCloseHandle (connection); - connection = 0; - } - } - - void createConnection (URL::OpenStreamProgressCallback* progressCallback, - void* progressCallbackContext) - { - static HINTERNET sessionHandle = InternetOpen (_T("juce"), INTERNET_OPEN_TYPE_PRECONFIG, 0, 0, 0); - - close(); - - if (sessionHandle != 0) - { - // break up the url.. - const int fileNumChars = 65536; - const int serverNumChars = 2048; - const int usernameNumChars = 1024; - const int passwordNumChars = 1024; - HeapBlock file (fileNumChars), server (serverNumChars), - username (usernameNumChars), password (passwordNumChars); - - URL_COMPONENTS uc = { 0 }; - uc.dwStructSize = sizeof (uc); - uc.lpszUrlPath = file; - uc.dwUrlPathLength = fileNumChars; - uc.lpszHostName = server; - uc.dwHostNameLength = serverNumChars; - uc.lpszUserName = username; - uc.dwUserNameLength = usernameNumChars; - uc.lpszPassword = password; - uc.dwPasswordLength = passwordNumChars; - - if (InternetCrackUrl (address.toWideCharPointer(), 0, 0, &uc)) - openConnection (uc, sessionHandle, progressCallback, progressCallbackContext); - } - } - - void openConnection (URL_COMPONENTS& uc, HINTERNET sessionHandle, - URL::OpenStreamProgressCallback* progressCallback, - void* progressCallbackContext) - { - int disable = 1; - InternetSetOption (sessionHandle, INTERNET_OPTION_DISABLE_AUTODIAL, &disable, sizeof (disable)); - - if (timeOutMs == 0) - timeOutMs = 30000; - else if (timeOutMs < 0) - timeOutMs = -1; - - applyTimeout (sessionHandle, INTERNET_OPTION_CONNECT_TIMEOUT); - applyTimeout (sessionHandle, INTERNET_OPTION_RECEIVE_TIMEOUT); - applyTimeout (sessionHandle, INTERNET_OPTION_SEND_TIMEOUT); - applyTimeout (sessionHandle, INTERNET_OPTION_DATA_RECEIVE_TIMEOUT); - applyTimeout (sessionHandle, INTERNET_OPTION_DATA_SEND_TIMEOUT); - - const bool isFtp = address.startsWithIgnoreCase ("ftp:"); - - connection = InternetConnect (sessionHandle, uc.lpszHostName, uc.nPort, - uc.lpszUserName, uc.lpszPassword, - isFtp ? (DWORD) INTERNET_SERVICE_FTP - : (DWORD) INTERNET_SERVICE_HTTP, - 0, 0); - if (connection != 0) - { - if (isFtp) - request = FtpOpenFile (connection, uc.lpszUrlPath, GENERIC_READ, - FTP_TRANSFER_TYPE_BINARY | INTERNET_FLAG_NEED_FILE, 0); - else - openHTTPConnection (uc, progressCallback, progressCallbackContext); - } - } - - void applyTimeout (HINTERNET sessionHandle, const DWORD option) - { - InternetSetOption (sessionHandle, option, &timeOutMs, sizeof (timeOutMs)); - } - - void openHTTPConnection (URL_COMPONENTS& uc, URL::OpenStreamProgressCallback* progressCallback, - void* progressCallbackContext) - { - const TCHAR* mimeTypes[] = { _T("*/*"), nullptr }; - - DWORD flags = INTERNET_FLAG_RELOAD | INTERNET_FLAG_NO_CACHE_WRITE | INTERNET_FLAG_NO_COOKIES - | INTERNET_FLAG_NO_AUTO_REDIRECT | SECURITY_SET_MASK; - - if (address.startsWithIgnoreCase ("https:")) - flags |= INTERNET_FLAG_SECURE; // (this flag only seems necessary if the OS is running IE6 - - // IE7 seems to automatically work out when it's https) - - request = HttpOpenRequest (connection, isPost ? _T("POST") : _T("GET"), - uc.lpszUrlPath, 0, 0, mimeTypes, flags, 0); - - if (request != 0) - { - setSecurityFlags(); - - INTERNET_BUFFERS buffers = { 0 }; - buffers.dwStructSize = sizeof (INTERNET_BUFFERS); - buffers.lpcszHeader = headers.toWideCharPointer(); - buffers.dwHeadersLength = (DWORD) headers.length(); - buffers.dwBufferTotal = (DWORD) postData.getSize(); - - if (HttpSendRequestEx (request, &buffers, 0, HSR_INITIATE, 0)) - { - int bytesSent = 0; - - for (;;) - { - const int bytesToDo = jmin (1024, (int) postData.getSize() - bytesSent); - DWORD bytesDone = 0; - - if (bytesToDo > 0 - && ! InternetWriteFile (request, - static_cast (postData.getData()) + bytesSent, - (DWORD) bytesToDo, &bytesDone)) - { - break; - } - - if (bytesToDo == 0 || (int) bytesDone < bytesToDo) - { - if (HttpEndRequest (request, 0, 0, 0)) - return; - - break; - } - - bytesSent += bytesDone; - - if (progressCallback != nullptr - && ! progressCallback (progressCallbackContext, bytesSent, (int) postData.getSize())) - break; - } - } - } - - close(); - } - - void setSecurityFlags() - { - DWORD dwFlags = 0, dwBuffLen = sizeof (DWORD); - InternetQueryOption (request, INTERNET_OPTION_SECURITY_FLAGS, &dwFlags, &dwBuffLen); - dwFlags |= SECURITY_FLAG_IGNORE_UNKNOWN_CA | SECURITY_SET_MASK; - InternetSetOption (request, INTERNET_OPTION_SECURITY_FLAGS, &dwFlags, sizeof (dwFlags)); - } - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (WebInputStream) -}; - - -//============================================================================== -struct GetAdaptersInfoHelper -{ - bool callGetAdaptersInfo() - { - DynamicLibrary dll ("iphlpapi.dll"); - JUCE_LOAD_WINAPI_FUNCTION (dll, GetAdaptersInfo, getAdaptersInfo, DWORD, (PIP_ADAPTER_INFO, PULONG)) - - if (getAdaptersInfo == nullptr) - return false; - - adapterInfo.malloc (1); - ULONG len = sizeof (IP_ADAPTER_INFO); - - if (getAdaptersInfo (adapterInfo, &len) == ERROR_BUFFER_OVERFLOW) - adapterInfo.malloc (len, 1); - - return getAdaptersInfo (adapterInfo, &len) == NO_ERROR; - } - - HeapBlock adapterInfo; -}; - -namespace MACAddressHelpers -{ - static void addAddress (Array& result, const MACAddress& ma) - { - if (! ma.isNull()) - result.addIfNotAlreadyThere (ma); - } - - static void getViaGetAdaptersInfo (Array& result) - { - GetAdaptersInfoHelper gah; - - if (gah.callGetAdaptersInfo()) - { - for (PIP_ADAPTER_INFO adapter = gah.adapterInfo; adapter != nullptr; adapter = adapter->Next) - if (adapter->AddressLength >= 6) - addAddress (result, MACAddress (adapter->Address)); - } - } - - static void getViaNetBios (Array& result) - { - DynamicLibrary dll ("netapi32.dll"); - JUCE_LOAD_WINAPI_FUNCTION (dll, Netbios, NetbiosCall, UCHAR, (PNCB)) - - if (NetbiosCall != 0) - { - LANA_ENUM enums = { 0 }; - - { - NCB ncb = { 0 }; - ncb.ncb_command = NCBENUM; - ncb.ncb_buffer = (unsigned char*) &enums; - ncb.ncb_length = sizeof (LANA_ENUM); - NetbiosCall (&ncb); - } - - for (int i = 0; i < enums.length; ++i) - { - NCB ncb2 = { 0 }; - ncb2.ncb_command = NCBRESET; - ncb2.ncb_lana_num = enums.lana[i]; - - if (NetbiosCall (&ncb2) == 0) - { - NCB ncb = { 0 }; - memcpy (ncb.ncb_callname, "* ", NCBNAMSZ); - ncb.ncb_command = NCBASTAT; - ncb.ncb_lana_num = enums.lana[i]; - - struct ASTAT - { - ADAPTER_STATUS adapt; - NAME_BUFFER NameBuff [30]; - }; - - ASTAT astat; - zerostruct (astat); - ncb.ncb_buffer = (unsigned char*) &astat; - ncb.ncb_length = sizeof (ASTAT); - - if (NetbiosCall (&ncb) == 0 && astat.adapt.adapter_type == 0xfe) - addAddress (result, MACAddress (astat.adapt.adapter_address)); - } - } - } - } -} - -void MACAddress::findAllAddresses (Array& result) -{ - MACAddressHelpers::getViaGetAdaptersInfo (result); - MACAddressHelpers::getViaNetBios (result); -} - -void IPAddress::findAllAddresses (Array& result) -{ - result.addIfNotAlreadyThere (IPAddress::local()); - - GetAdaptersInfoHelper gah; - - if (gah.callGetAdaptersInfo()) - { - for (PIP_ADAPTER_INFO adapter = gah.adapterInfo; adapter != nullptr; adapter = adapter->Next) - { - IPAddress ip (adapter->IpAddressList.IpAddress.String); - - if (ip != IPAddress::any()) - result.addIfNotAlreadyThere (ip); - } - } -} - -//============================================================================== -bool JUCE_CALLTYPE Process::openEmailWithAttachments (const String& targetEmailAddress, - const String& emailSubject, - const String& bodyText, - const StringArray& filesToAttach) -{ - DynamicLibrary dll ("MAPI32.dll"); - JUCE_LOAD_WINAPI_FUNCTION (dll, MAPISendMail, mapiSendMail, - ULONG, (LHANDLE, ULONG, lpMapiMessage, ::FLAGS, ULONG)) - - if (mapiSendMail == nullptr) - return false; - - MapiMessage message = { 0 }; - message.lpszSubject = (LPSTR) emailSubject.toRawUTF8(); - message.lpszNoteText = (LPSTR) bodyText.toRawUTF8(); - - MapiRecipDesc recip = { 0 }; - recip.ulRecipClass = MAPI_TO; - String targetEmailAddress_ (targetEmailAddress); - if (targetEmailAddress_.isEmpty()) - targetEmailAddress_ = " "; // (Windows Mail can't deal with a blank address) - recip.lpszName = (LPSTR) targetEmailAddress_.toRawUTF8(); - message.nRecipCount = 1; - message.lpRecips = &recip; - - HeapBlock files; - files.calloc ((size_t) filesToAttach.size()); - - message.nFileCount = (ULONG) filesToAttach.size(); - message.lpFiles = files; - - for (int i = 0; i < filesToAttach.size(); ++i) - { - files[i].nPosition = (ULONG) -1; - files[i].lpszPathName = (LPSTR) filesToAttach[i].toRawUTF8(); - } - - return mapiSendMail (0, 0, &message, MAPI_DIALOG | MAPI_LOGON_UI, 0) == SUCCESS_SUCCESS; -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/native/juce_win32_Registry.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/native/juce_win32_Registry.cpp deleted file mode 100644 index 811947439a..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/native/juce_win32_Registry.cpp +++ /dev/null @@ -1,227 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -struct RegistryKeyWrapper -{ - RegistryKeyWrapper (String name, const bool createForWriting, const DWORD wow64Flags) - : key (0), wideCharValueName (nullptr) - { - HKEY rootKey = 0; - - if (name.startsWithIgnoreCase ("HKEY_CURRENT_USER\\")) rootKey = HKEY_CURRENT_USER; - else if (name.startsWithIgnoreCase ("HKEY_LOCAL_MACHINE\\")) rootKey = HKEY_LOCAL_MACHINE; - else if (name.startsWithIgnoreCase ("HKEY_CLASSES_ROOT\\")) rootKey = HKEY_CLASSES_ROOT; - - if (rootKey != 0) - { - name = name.substring (name.indexOfChar ('\\') + 1); - - const int lastSlash = name.lastIndexOfChar ('\\'); - valueName = name.substring (lastSlash + 1); - wideCharValueName = valueName.toWideCharPointer(); - - name = name.substring (0, lastSlash); - const wchar_t* const wideCharName = name.toWideCharPointer(); - DWORD result; - - if (createForWriting) - RegCreateKeyEx (rootKey, wideCharName, 0, 0, REG_OPTION_NON_VOLATILE, - KEY_WRITE | KEY_QUERY_VALUE | wow64Flags, 0, &key, &result); - else - RegOpenKeyEx (rootKey, wideCharName, 0, KEY_READ | wow64Flags, &key); - } - } - - ~RegistryKeyWrapper() - { - if (key != 0) - RegCloseKey (key); - } - - static bool setValue (const String& regValuePath, const DWORD type, - const void* data, size_t dataSize, const DWORD wow64Flags) - { - const RegistryKeyWrapper key (regValuePath, true, wow64Flags); - - return key.key != 0 - && RegSetValueEx (key.key, key.wideCharValueName, 0, type, - reinterpret_cast (data), - (DWORD) dataSize) == ERROR_SUCCESS; - } - - static uint32 getBinaryValue (const String& regValuePath, MemoryBlock& result, DWORD wow64Flags) - { - const RegistryKeyWrapper key (regValuePath, false, wow64Flags); - - if (key.key != 0) - { - for (unsigned long bufferSize = 1024; ; bufferSize *= 2) - { - result.setSize (bufferSize, false); - DWORD type = REG_NONE; - - const LONG err = RegQueryValueEx (key.key, key.wideCharValueName, 0, &type, - (LPBYTE) result.getData(), &bufferSize); - - if (err == ERROR_SUCCESS) - { - result.setSize (bufferSize, false); - return type; - } - - if (err != ERROR_MORE_DATA) - break; - } - } - - return REG_NONE; - } - - static String getValue (const String& regValuePath, const String& defaultValue, DWORD wow64Flags) - { - MemoryBlock buffer; - switch (getBinaryValue (regValuePath, buffer, wow64Flags)) - { - case REG_SZ: return static_cast (buffer.getData()); - case REG_DWORD: return String ((int) *reinterpret_cast (buffer.getData())); - default: break; - } - - return defaultValue; - } - - static bool keyExists (const String& regValuePath, const DWORD wow64Flags) - { - return RegistryKeyWrapper (regValuePath, false, wow64Flags).key != 0; - } - - static bool valueExists (const String& regValuePath, const DWORD wow64Flags) - { - const RegistryKeyWrapper key (regValuePath, false, wow64Flags); - - if (key.key == 0) - return false; - - unsigned char buffer [512]; - unsigned long bufferSize = sizeof (buffer); - DWORD type = 0; - - const LONG result = RegQueryValueEx (key.key, key.wideCharValueName, - 0, &type, buffer, &bufferSize); - - return result == ERROR_SUCCESS || result == ERROR_MORE_DATA; - } - - HKEY key; - const wchar_t* wideCharValueName; - String valueName; - - JUCE_DECLARE_NON_COPYABLE (RegistryKeyWrapper) -}; - -uint32 JUCE_CALLTYPE WindowsRegistry::getBinaryValue (const String& regValuePath, MemoryBlock& result, WoW64Mode mode) -{ - return RegistryKeyWrapper::getBinaryValue (regValuePath, result, (DWORD) mode); -} - -String JUCE_CALLTYPE WindowsRegistry::getValue (const String& regValuePath, const String& defaultValue, WoW64Mode mode) -{ - return RegistryKeyWrapper::getValue (regValuePath, defaultValue, (DWORD) mode); -} - -bool JUCE_CALLTYPE WindowsRegistry::setValue (const String& regValuePath, const String& value, WoW64Mode mode) -{ - return RegistryKeyWrapper::setValue (regValuePath, REG_SZ, value.toWideCharPointer(), - CharPointer_UTF16::getBytesRequiredFor (value.getCharPointer()), mode); -} - -bool JUCE_CALLTYPE WindowsRegistry::setValue (const String& regValuePath, const uint32 value, WoW64Mode mode) -{ - return RegistryKeyWrapper::setValue (regValuePath, REG_DWORD, &value, sizeof (value), (DWORD) mode); -} - -bool JUCE_CALLTYPE WindowsRegistry::setValue (const String& regValuePath, const uint64 value, WoW64Mode mode) -{ - return RegistryKeyWrapper::setValue (regValuePath, REG_QWORD, &value, sizeof (value), (DWORD) mode); -} - -bool JUCE_CALLTYPE WindowsRegistry::setValue (const String& regValuePath, const MemoryBlock& value, WoW64Mode mode) -{ - return RegistryKeyWrapper::setValue (regValuePath, REG_BINARY, value.getData(), value.getSize(), (DWORD) mode); -} - -bool JUCE_CALLTYPE WindowsRegistry::valueExists (const String& regValuePath, WoW64Mode mode) -{ - return RegistryKeyWrapper::valueExists (regValuePath, (DWORD) mode); -} - -bool JUCE_CALLTYPE WindowsRegistry::keyExists (const String& regValuePath, WoW64Mode mode) -{ - return RegistryKeyWrapper::keyExists (regValuePath, (DWORD) mode); -} - -void JUCE_CALLTYPE WindowsRegistry::deleteValue (const String& regValuePath, WoW64Mode mode) -{ - const RegistryKeyWrapper key (regValuePath, true, (DWORD) mode); - - if (key.key != 0) - RegDeleteValue (key.key, key.wideCharValueName); -} - -void JUCE_CALLTYPE WindowsRegistry::deleteKey (const String& regKeyPath, WoW64Mode mode) -{ - const RegistryKeyWrapper key (regKeyPath, true, (DWORD) mode); - - if (key.key != 0) - RegDeleteKey (key.key, key.wideCharValueName); -} - -bool JUCE_CALLTYPE WindowsRegistry::registerFileAssociation (const String& fileExtension, - const String& symbolicDescription, - const String& fullDescription, - const File& targetExecutable, - const int iconResourceNumber, - const bool registerForCurrentUserOnly, - WoW64Mode mode) -{ - const char* const root = registerForCurrentUserOnly ? "HKEY_CURRENT_USER\\Software\\Classes\\" - : "HKEY_CLASSES_ROOT\\"; - const String key (root + symbolicDescription); - - return setValue (root + fileExtension + "\\", symbolicDescription, mode) - && setValue (key + "\\", fullDescription, mode) - && setValue (key + "\\shell\\open\\command\\", targetExecutable.getFullPathName() + " \"%1\"", mode) - && (iconResourceNumber == 0 - || setValue (key + "\\DefaultIcon\\", - targetExecutable.getFullPathName() + "," + String (iconResourceNumber))); -} - -// These methods are deprecated: -String WindowsRegistry::getValueWow64 (const String& p, const String& defVal) { return getValue (p, defVal, WoW64_64bit); } -bool WindowsRegistry::valueExistsWow64 (const String& p) { return valueExists (p, WoW64_64bit); } -bool WindowsRegistry::keyExistsWow64 (const String& p) { return keyExists (p, WoW64_64bit); } diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/native/juce_win32_SystemStats.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/native/juce_win32_SystemStats.cpp deleted file mode 100644 index d98e3237bc..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/native/juce_win32_SystemStats.cpp +++ /dev/null @@ -1,459 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -void Logger::outputDebugString (const String& text) -{ - OutputDebugString ((text + "\n").toWideCharPointer()); -} - -//============================================================================== -#ifdef JUCE_DLL_BUILD - JUCE_API void* juceDLL_malloc (size_t sz) { return std::malloc (sz); } - JUCE_API void juceDLL_free (void* block) { std::free (block); } -#endif - -//============================================================================== -#if JUCE_USE_MSVC_INTRINSICS - -// CPU info functions using intrinsics... - -#pragma intrinsic (__cpuid) -#pragma intrinsic (__rdtsc) - -static void callCPUID (int result[4], int infoType) -{ - __cpuid (result, infoType); -} - -#else - -static void callCPUID (int result[4], int infoType) -{ - #if ! JUCE_MINGW - __try - #endif - { - #if JUCE_GCC - __asm__ __volatile__ ("cpuid" : "=a" (result[0]), "=b" (result[1]), "=c" (result[2]),"=d" (result[3]) : "a" (infoType)); - #else - __asm - { - mov esi, result - mov eax, infoType - xor ecx, ecx - cpuid - mov dword ptr [esi + 0], eax - mov dword ptr [esi + 4], ebx - mov dword ptr [esi + 8], ecx - mov dword ptr [esi + 12], edx - } - #endif - } - #if ! JUCE_MINGW - __except (EXCEPTION_EXECUTE_HANDLER) {} - #endif -} - -#endif - -String SystemStats::getCpuVendor() -{ - int info[4] = { 0 }; - callCPUID (info, 0); - - char v [12]; - memcpy (v, info + 1, 4); - memcpy (v + 4, info + 3, 4); - memcpy (v + 8, info + 2, 4); - - return String (v, 12); -} - -//============================================================================== -void CPUInformation::initialise() noexcept -{ - int info[4] = { 0 }; - callCPUID (info, 1); - - // NB: IsProcessorFeaturePresent doesn't work on XP - hasMMX = (info[3] & (1 << 23)) != 0; - hasSSE = (info[3] & (1 << 25)) != 0; - hasSSE2 = (info[3] & (1 << 26)) != 0; - hasSSE3 = (info[2] & (1 << 0)) != 0; - has3DNow = (info[1] & (1 << 31)) != 0; - - SYSTEM_INFO systemInfo; - GetNativeSystemInfo (&systemInfo); - numCpus = (int) systemInfo.dwNumberOfProcessors; -} - -#if JUCE_MSVC && JUCE_CHECK_MEMORY_LEAKS -struct DebugFlagsInitialiser -{ - DebugFlagsInitialiser() - { - _CrtSetDbgFlag (_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); - } -}; - -static DebugFlagsInitialiser debugFlagsInitialiser; -#endif - -//============================================================================== -static bool isWindowsVersionOrLater (SystemStats::OperatingSystemType target) -{ - OSVERSIONINFOEX info; - zerostruct (info); - info.dwOSVersionInfoSize = sizeof (OSVERSIONINFOEX); - - if (target >= SystemStats::WinVista) - { - info.dwMajorVersion = 6; - - switch (target) - { - case SystemStats::WinVista: break; - case SystemStats::Windows7: info.dwMinorVersion = 1; break; - case SystemStats::Windows8_0: info.dwMinorVersion = 2; break; - case SystemStats::Windows8_1: info.dwMinorVersion = 3; break; - default: jassertfalse; break; - } - } - else - { - info.dwMajorVersion = 5; - info.dwMinorVersion = target >= SystemStats::WinXP ? 1 : 0; - } - - DWORDLONG mask = 0; - - VER_SET_CONDITION (mask, VER_MAJORVERSION, VER_GREATER_EQUAL); - VER_SET_CONDITION (mask, VER_MINORVERSION, VER_GREATER_EQUAL); - VER_SET_CONDITION (mask, VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL); - VER_SET_CONDITION (mask, VER_SERVICEPACKMINOR, VER_GREATER_EQUAL); - - return VerifyVersionInfo (&info, - VER_MAJORVERSION | VER_MINORVERSION - | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, - mask) != FALSE; -} - -SystemStats::OperatingSystemType SystemStats::getOperatingSystemType() -{ - const SystemStats::OperatingSystemType types[] - = { Windows8_1, Windows8_0, Windows7, WinVista, WinXP, Win2000 }; - - for (int i = 0; i < numElementsInArray (types); ++i) - if (isWindowsVersionOrLater (types[i])) - return types[i]; - - jassertfalse; // need to support whatever new version is running! - return UnknownOS; -} - -String SystemStats::getOperatingSystemName() -{ - const char* name = "Unknown OS"; - - switch (getOperatingSystemType()) - { - case Windows8_1: name = "Windows 8.1"; break; - case Windows8_0: name = "Windows 8.0"; break; - case Windows7: name = "Windows 7"; break; - case WinVista: name = "Windows Vista"; break; - case WinXP: name = "Windows XP"; break; - case Win2000: name = "Windows 2000"; break; - default: jassertfalse; break; // !! new type of OS? - } - - return name; -} - -String SystemStats::getDeviceDescription() -{ - return String(); -} - -bool SystemStats::isOperatingSystem64Bit() -{ - #if JUCE_64BIT - return true; - #else - typedef BOOL (WINAPI* LPFN_ISWOW64PROCESS) (HANDLE, PBOOL); - - LPFN_ISWOW64PROCESS fnIsWow64Process - = (LPFN_ISWOW64PROCESS) GetProcAddress (GetModuleHandleA ("kernel32"), "IsWow64Process"); - - BOOL isWow64 = FALSE; - - return fnIsWow64Process != nullptr - && fnIsWow64Process (GetCurrentProcess(), &isWow64) - && isWow64 != FALSE; - #endif -} - -//============================================================================== -int SystemStats::getMemorySizeInMegabytes() -{ - MEMORYSTATUSEX mem; - mem.dwLength = sizeof (mem); - GlobalMemoryStatusEx (&mem); - return (int) (mem.ullTotalPhys / (1024 * 1024)) + 1; -} - -//============================================================================== -String SystemStats::getEnvironmentVariable (const String& name, const String& defaultValue) -{ - DWORD len = GetEnvironmentVariableW (name.toWideCharPointer(), nullptr, 0); - if (GetLastError() == ERROR_ENVVAR_NOT_FOUND) - return String (defaultValue); - - HeapBlock buffer (len); - len = GetEnvironmentVariableW (name.toWideCharPointer(), buffer, len); - - return String (CharPointer_wchar_t (buffer), - CharPointer_wchar_t (buffer + len)); -} - -//============================================================================== -uint32 juce_millisecondsSinceStartup() noexcept -{ - return (uint32) timeGetTime(); -} - -//============================================================================== -class HiResCounterHandler -{ -public: - HiResCounterHandler() - : hiResTicksOffset (0) - { - // This macro allows you to override the default timer-period - // used on Windows. By default this is set to 1, because that has - // always been the value used in JUCE apps, and changing it could - // affect the behaviour of existing code, but you may wish to make - // it larger (or set it to 0 to use the system default) to make your - // app less demanding on the CPU. - // For more info, see win32 documentation about the timeBeginPeriod - // function. - #ifndef JUCE_WIN32_TIMER_PERIOD - #define JUCE_WIN32_TIMER_PERIOD 1 - #endif - - #if JUCE_WIN32_TIMER_PERIOD > 0 - const MMRESULT res = timeBeginPeriod (JUCE_WIN32_TIMER_PERIOD); - (void) res; - jassert (res == TIMERR_NOERROR); - #endif - - LARGE_INTEGER f; - QueryPerformanceFrequency (&f); - hiResTicksPerSecond = f.QuadPart; - hiResTicksScaleFactor = 1000.0 / hiResTicksPerSecond; - } - - inline int64 getHighResolutionTicks() noexcept - { - LARGE_INTEGER ticks; - QueryPerformanceCounter (&ticks); - - const int64 mainCounterAsHiResTicks = (juce_millisecondsSinceStartup() * hiResTicksPerSecond) / 1000; - const int64 newOffset = mainCounterAsHiResTicks - ticks.QuadPart; - - // fix for a very obscure PCI hardware bug that can make the counter - // sometimes jump forwards by a few seconds.. - const int64 offsetDrift = abs64 (newOffset - hiResTicksOffset); - - if (offsetDrift > (hiResTicksPerSecond >> 1)) - hiResTicksOffset = newOffset; - - return ticks.QuadPart + hiResTicksOffset; - } - - inline double getMillisecondCounterHiRes() noexcept - { - return getHighResolutionTicks() * hiResTicksScaleFactor; - } - - int64 hiResTicksPerSecond, hiResTicksOffset; - double hiResTicksScaleFactor; -}; - -static HiResCounterHandler hiResCounterHandler; - -int64 Time::getHighResolutionTicksPerSecond() noexcept { return hiResCounterHandler.hiResTicksPerSecond; } -int64 Time::getHighResolutionTicks() noexcept { return hiResCounterHandler.getHighResolutionTicks(); } -double Time::getMillisecondCounterHiRes() noexcept { return hiResCounterHandler.getMillisecondCounterHiRes(); } - -//============================================================================== -static int64 juce_getClockCycleCounter() noexcept -{ - #if JUCE_USE_MSVC_INTRINSICS - // MS intrinsics version... - return (int64) __rdtsc(); - - #elif JUCE_GCC - // GNU inline asm version... - unsigned int hi = 0, lo = 0; - - __asm__ __volatile__ ( - "xor %%eax, %%eax \n\ - xor %%edx, %%edx \n\ - rdtsc \n\ - movl %%eax, %[lo] \n\ - movl %%edx, %[hi]" - : - : [hi] "m" (hi), - [lo] "m" (lo) - : "cc", "eax", "ebx", "ecx", "edx", "memory"); - - return (int64) ((((uint64) hi) << 32) | lo); - #else - // MSVC inline asm version... - unsigned int hi = 0, lo = 0; - - __asm - { - xor eax, eax - xor edx, edx - rdtsc - mov lo, eax - mov hi, edx - } - - return (int64) ((((uint64) hi) << 32) | lo); - #endif -} - -int SystemStats::getCpuSpeedInMegaherz() -{ - const int64 cycles = juce_getClockCycleCounter(); - const uint32 millis = Time::getMillisecondCounter(); - int lastResult = 0; - - for (;;) - { - int n = 1000000; - while (--n > 0) {} - - const uint32 millisElapsed = Time::getMillisecondCounter() - millis; - const int64 cyclesNow = juce_getClockCycleCounter(); - - if (millisElapsed > 80) - { - const int newResult = (int) (((cyclesNow - cycles) / millisElapsed) / 1000); - - if (millisElapsed > 500 || (lastResult == newResult && newResult > 100)) - return newResult; - - lastResult = newResult; - } - } -} - - -//============================================================================== -bool Time::setSystemTimeToThisTime() const -{ - SYSTEMTIME st; - - st.wDayOfWeek = 0; - st.wYear = (WORD) getYear(); - st.wMonth = (WORD) (getMonth() + 1); - st.wDay = (WORD) getDayOfMonth(); - st.wHour = (WORD) getHours(); - st.wMinute = (WORD) getMinutes(); - st.wSecond = (WORD) getSeconds(); - st.wMilliseconds = (WORD) (millisSinceEpoch % 1000); - - // do this twice because of daylight saving conversion problems - the - // first one sets it up, the second one kicks it in. - return SetLocalTime (&st) != 0 - && SetLocalTime (&st) != 0; -} - -int SystemStats::getPageSize() -{ - SYSTEM_INFO systemInfo; - GetNativeSystemInfo (&systemInfo); - - return (int) systemInfo.dwPageSize; -} - -//============================================================================== -String SystemStats::getLogonName() -{ - TCHAR text [256] = { 0 }; - DWORD len = (DWORD) numElementsInArray (text) - 1; - GetUserName (text, &len); - return String (text, len); -} - -String SystemStats::getFullUserName() -{ - return getLogonName(); -} - -String SystemStats::getComputerName() -{ - TCHAR text [MAX_COMPUTERNAME_LENGTH + 1] = { 0 }; - DWORD len = (DWORD) numElementsInArray (text) - 1; - GetComputerName (text, &len); - return String (text, len); -} - -static String getLocaleValue (LCID locale, LCTYPE key, const char* defaultValue) -{ - TCHAR buffer [256] = { 0 }; - if (GetLocaleInfo (locale, key, buffer, 255) > 0) - return buffer; - - return defaultValue; -} - -String SystemStats::getUserLanguage() { return getLocaleValue (LOCALE_USER_DEFAULT, LOCALE_SISO639LANGNAME, "en"); } -String SystemStats::getUserRegion() { return getLocaleValue (LOCALE_USER_DEFAULT, LOCALE_SISO3166CTRYNAME, "US"); } - -String SystemStats::getDisplayLanguage() -{ - DynamicLibrary dll ("kernel32.dll"); - JUCE_LOAD_WINAPI_FUNCTION (dll, GetUserDefaultUILanguage, getUserDefaultUILanguage, LANGID, (void)) - - if (getUserDefaultUILanguage == nullptr) - return "en"; - - const DWORD langID = MAKELCID (getUserDefaultUILanguage(), SORT_DEFAULT); - - String mainLang (getLocaleValue (langID, LOCALE_SISO639LANGNAME, "en")); - String region (getLocaleValue (langID, LOCALE_SISO3166CTRYNAME, nullptr)); - - if (region.isNotEmpty()) - mainLang << '-' << region; - - return mainLang; -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/native/juce_win32_Threads.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/native/juce_win32_Threads.cpp deleted file mode 100644 index 1421c109f8..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/native/juce_win32_Threads.cpp +++ /dev/null @@ -1,625 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -HWND juce_messageWindowHandle = 0; // (this is used by other parts of the codebase) - -void* getUser32Function (const char* functionName) -{ - HMODULE module = GetModuleHandleA ("user32.dll"); - jassert (module != 0); - return (void*) GetProcAddress (module, functionName); -} - -//============================================================================== -#if ! JUCE_USE_MSVC_INTRINSICS -// In newer compilers, the inline versions of these are used (in juce_Atomic.h), but in -// older ones we have to actually call the ops as win32 functions.. -long juce_InterlockedExchange (volatile long* a, long b) noexcept { return InterlockedExchange (a, b); } -long juce_InterlockedIncrement (volatile long* a) noexcept { return InterlockedIncrement (a); } -long juce_InterlockedDecrement (volatile long* a) noexcept { return InterlockedDecrement (a); } -long juce_InterlockedExchangeAdd (volatile long* a, long b) noexcept { return InterlockedExchangeAdd (a, b); } -long juce_InterlockedCompareExchange (volatile long* a, long b, long c) noexcept { return InterlockedCompareExchange (a, b, c); } - -__int64 juce_InterlockedCompareExchange64 (volatile __int64* value, __int64 newValue, __int64 valueToCompare) noexcept -{ - jassertfalse; // This operation isn't available in old MS compiler versions! - - __int64 oldValue = *value; - if (oldValue == valueToCompare) - *value = newValue; - - return oldValue; -} - -#endif - -//============================================================================== -CriticalSection::CriticalSection() noexcept -{ - // (just to check the MS haven't changed this structure and broken things...) - #if JUCE_VC7_OR_EARLIER - static_jassert (sizeof (CRITICAL_SECTION) <= 24); - #else - static_jassert (sizeof (CRITICAL_SECTION) <= sizeof (lock)); - #endif - - InitializeCriticalSection ((CRITICAL_SECTION*) lock); -} - -CriticalSection::~CriticalSection() noexcept { DeleteCriticalSection ((CRITICAL_SECTION*) lock); } -void CriticalSection::enter() const noexcept { EnterCriticalSection ((CRITICAL_SECTION*) lock); } -bool CriticalSection::tryEnter() const noexcept { return TryEnterCriticalSection ((CRITICAL_SECTION*) lock) != FALSE; } -void CriticalSection::exit() const noexcept { LeaveCriticalSection ((CRITICAL_SECTION*) lock); } - - -//============================================================================== -WaitableEvent::WaitableEvent (const bool manualReset) noexcept - : handle (CreateEvent (0, manualReset ? TRUE : FALSE, FALSE, 0)) {} - -WaitableEvent::~WaitableEvent() noexcept { CloseHandle (handle); } - -void WaitableEvent::signal() const noexcept { SetEvent (handle); } -void WaitableEvent::reset() const noexcept { ResetEvent (handle); } - -bool WaitableEvent::wait (const int timeOutMs) const noexcept -{ - return WaitForSingleObject (handle, (DWORD) timeOutMs) == WAIT_OBJECT_0; -} - -//============================================================================== -void JUCE_API juce_threadEntryPoint (void*); - -static unsigned int __stdcall threadEntryProc (void* userData) -{ - if (juce_messageWindowHandle != 0) - AttachThreadInput (GetWindowThreadProcessId (juce_messageWindowHandle, 0), - GetCurrentThreadId(), TRUE); - - juce_threadEntryPoint (userData); - - _endthreadex (0); - return 0; -} - -void Thread::launchThread() -{ - unsigned int newThreadId; - threadHandle = (void*) _beginthreadex (0, 0, &threadEntryProc, this, 0, &newThreadId); - threadId = (ThreadID) newThreadId; -} - -void Thread::closeThreadHandle() -{ - CloseHandle ((HANDLE) threadHandle); - threadId = 0; - threadHandle = 0; -} - -void Thread::killThread() -{ - if (threadHandle != 0) - { - #if JUCE_DEBUG - OutputDebugStringA ("** Warning - Forced thread termination **\n"); - #endif - TerminateThread (threadHandle, 0); - } -} - -void JUCE_CALLTYPE Thread::setCurrentThreadName (const String& name) -{ - #if JUCE_DEBUG && JUCE_MSVC - struct - { - DWORD dwType; - LPCSTR szName; - DWORD dwThreadID; - DWORD dwFlags; - } info; - - info.dwType = 0x1000; - info.szName = name.toUTF8(); - info.dwThreadID = GetCurrentThreadId(); - info.dwFlags = 0; - - __try - { - RaiseException (0x406d1388 /*MS_VC_EXCEPTION*/, 0, sizeof (info) / sizeof (ULONG_PTR), (ULONG_PTR*) &info); - } - __except (EXCEPTION_CONTINUE_EXECUTION) - {} - #else - (void) name; - #endif -} - -Thread::ThreadID JUCE_CALLTYPE Thread::getCurrentThreadId() -{ - return (ThreadID) (pointer_sized_int) GetCurrentThreadId(); -} - -bool Thread::setThreadPriority (void* handle, int priority) -{ - int pri = THREAD_PRIORITY_TIME_CRITICAL; - - if (priority < 1) pri = THREAD_PRIORITY_IDLE; - else if (priority < 2) pri = THREAD_PRIORITY_LOWEST; - else if (priority < 5) pri = THREAD_PRIORITY_BELOW_NORMAL; - else if (priority < 7) pri = THREAD_PRIORITY_NORMAL; - else if (priority < 9) pri = THREAD_PRIORITY_ABOVE_NORMAL; - else if (priority < 10) pri = THREAD_PRIORITY_HIGHEST; - - if (handle == 0) - handle = GetCurrentThread(); - - return SetThreadPriority (handle, pri) != FALSE; -} - -void JUCE_CALLTYPE Thread::setCurrentThreadAffinityMask (const uint32 affinityMask) -{ - SetThreadAffinityMask (GetCurrentThread(), affinityMask); -} - -//============================================================================== -struct SleepEvent -{ - SleepEvent() noexcept - : handle (CreateEvent (nullptr, FALSE, FALSE, - #if JUCE_DEBUG - _T("JUCE Sleep Event"))) - #else - nullptr)) - #endif - {} - - ~SleepEvent() noexcept - { - CloseHandle (handle); - handle = 0; - } - - HANDLE handle; -}; - -static SleepEvent sleepEvent; - -void JUCE_CALLTYPE Thread::sleep (const int millisecs) -{ - jassert (millisecs >= 0); - - if (millisecs >= 10 || sleepEvent.handle == 0) - Sleep ((DWORD) millisecs); - else - // unlike Sleep() this is guaranteed to return to the current thread after - // the time expires, so we'll use this for short waits, which are more likely - // to need to be accurate - WaitForSingleObject (sleepEvent.handle, (DWORD) millisecs); -} - -void Thread::yield() -{ - Sleep (0); -} - -//============================================================================== -static int lastProcessPriority = -1; - -// called when the app gains focus because Windows does weird things to process priority -// when you swap apps, and this forces an update when the app is brought to the front. -void juce_repeatLastProcessPriority() -{ - if (lastProcessPriority >= 0) // (avoid changing this if it's not been explicitly set by the app..) - { - DWORD p; - - switch (lastProcessPriority) - { - case Process::LowPriority: p = IDLE_PRIORITY_CLASS; break; - case Process::NormalPriority: p = NORMAL_PRIORITY_CLASS; break; - case Process::HighPriority: p = HIGH_PRIORITY_CLASS; break; - case Process::RealtimePriority: p = REALTIME_PRIORITY_CLASS; break; - default: jassertfalse; return; // bad priority value - } - - SetPriorityClass (GetCurrentProcess(), p); - } -} - -void JUCE_CALLTYPE Process::setPriority (ProcessPriority prior) -{ - if (lastProcessPriority != (int) prior) - { - lastProcessPriority = (int) prior; - juce_repeatLastProcessPriority(); - } -} - -JUCE_API bool JUCE_CALLTYPE juce_isRunningUnderDebugger() -{ - return IsDebuggerPresent() != FALSE; -} - -bool JUCE_CALLTYPE Process::isRunningUnderDebugger() -{ - return juce_isRunningUnderDebugger(); -} - -static void* currentModuleHandle = nullptr; - -void* JUCE_CALLTYPE Process::getCurrentModuleInstanceHandle() noexcept -{ - if (currentModuleHandle == nullptr) - currentModuleHandle = GetModuleHandleA (nullptr); - - return currentModuleHandle; -} - -void JUCE_CALLTYPE Process::setCurrentModuleInstanceHandle (void* const newHandle) noexcept -{ - currentModuleHandle = newHandle; -} - -void JUCE_CALLTYPE Process::raisePrivilege() -{ - jassertfalse; // xxx not implemented -} - -void JUCE_CALLTYPE Process::lowerPrivilege() -{ - jassertfalse; // xxx not implemented -} - -void JUCE_CALLTYPE Process::terminate() -{ - #if JUCE_MSVC && JUCE_CHECK_MEMORY_LEAKS - _CrtDumpMemoryLeaks(); - #endif - - // bullet in the head in case there's a problem shutting down.. - ExitProcess (1); -} - -bool juce_isRunningInWine() -{ - HMODULE ntdll = GetModuleHandleA ("ntdll"); - return ntdll != 0 && GetProcAddress (ntdll, "wine_get_version") != nullptr; -} - -//============================================================================== -bool DynamicLibrary::open (const String& name) -{ - close(); - - JUCE_TRY - { - handle = LoadLibrary (name.toWideCharPointer()); - } - JUCE_CATCH_ALL - - return handle != nullptr; -} - -void DynamicLibrary::close() -{ - JUCE_TRY - { - if (handle != nullptr) - { - FreeLibrary ((HMODULE) handle); - handle = nullptr; - } - } - JUCE_CATCH_ALL -} - -void* DynamicLibrary::getFunction (const String& functionName) noexcept -{ - return handle != nullptr ? (void*) GetProcAddress ((HMODULE) handle, functionName.toUTF8()) // (void* cast is required for mingw) - : nullptr; -} - - -//============================================================================== -class InterProcessLock::Pimpl -{ -public: - Pimpl (String name, const int timeOutMillisecs) - : handle (0), refCount (1) - { - name = name.replaceCharacter ('\\', '/'); - handle = CreateMutexW (0, TRUE, ("Global\\" + name).toWideCharPointer()); - - // Not 100% sure why a global mutex sometimes can't be allocated, but if it fails, fall back to - // a local one. (A local one also sometimes fails on other machines so neither type appears to be - // universally reliable) - if (handle == 0) - handle = CreateMutexW (0, TRUE, ("Local\\" + name).toWideCharPointer()); - - if (handle != 0 && GetLastError() == ERROR_ALREADY_EXISTS) - { - if (timeOutMillisecs == 0) - { - close(); - return; - } - - switch (WaitForSingleObject (handle, timeOutMillisecs < 0 ? INFINITE : timeOutMillisecs)) - { - case WAIT_OBJECT_0: - case WAIT_ABANDONED: - break; - - case WAIT_TIMEOUT: - default: - close(); - break; - } - } - } - - ~Pimpl() - { - close(); - } - - void close() - { - if (handle != 0) - { - ReleaseMutex (handle); - CloseHandle (handle); - handle = 0; - } - } - - HANDLE handle; - int refCount; -}; - -InterProcessLock::InterProcessLock (const String& name_) - : name (name_) -{ -} - -InterProcessLock::~InterProcessLock() -{ -} - -bool InterProcessLock::enter (const int timeOutMillisecs) -{ - const ScopedLock sl (lock); - - if (pimpl == nullptr) - { - pimpl = new Pimpl (name, timeOutMillisecs); - - if (pimpl->handle == 0) - pimpl = nullptr; - } - else - { - pimpl->refCount++; - } - - return pimpl != nullptr; -} - -void InterProcessLock::exit() -{ - const ScopedLock sl (lock); - - // Trying to release the lock too many times! - jassert (pimpl != nullptr); - - if (pimpl != nullptr && --(pimpl->refCount) == 0) - pimpl = nullptr; -} - -//============================================================================== -class ChildProcess::ActiveProcess -{ -public: - ActiveProcess (const String& command, int streamFlags) - : ok (false), readPipe (0), writePipe (0) - { - SECURITY_ATTRIBUTES securityAtts = { 0 }; - securityAtts.nLength = sizeof (securityAtts); - securityAtts.bInheritHandle = TRUE; - - if (CreatePipe (&readPipe, &writePipe, &securityAtts, 0) - && SetHandleInformation (readPipe, HANDLE_FLAG_INHERIT, 0)) - { - STARTUPINFOW startupInfo = { 0 }; - startupInfo.cb = sizeof (startupInfo); - - startupInfo.hStdOutput = (streamFlags | wantStdOut) != 0 ? writePipe : 0; - startupInfo.hStdError = (streamFlags | wantStdErr) != 0 ? writePipe : 0; - startupInfo.dwFlags = STARTF_USESTDHANDLES; - - ok = CreateProcess (nullptr, const_cast (command.toWideCharPointer()), - nullptr, nullptr, TRUE, CREATE_NO_WINDOW | CREATE_UNICODE_ENVIRONMENT, - nullptr, nullptr, &startupInfo, &processInfo) != FALSE; - } - } - - ~ActiveProcess() - { - if (ok) - { - CloseHandle (processInfo.hThread); - CloseHandle (processInfo.hProcess); - } - - if (readPipe != 0) - CloseHandle (readPipe); - - if (writePipe != 0) - CloseHandle (writePipe); - } - - bool isRunning() const noexcept - { - return WaitForSingleObject (processInfo.hProcess, 0) != WAIT_OBJECT_0; - } - - int read (void* dest, int numNeeded) const noexcept - { - int total = 0; - - while (ok && numNeeded > 0) - { - DWORD available = 0; - - if (! PeekNamedPipe ((HANDLE) readPipe, nullptr, 0, nullptr, &available, nullptr)) - break; - - const int numToDo = jmin ((int) available, numNeeded); - - if (available == 0) - { - if (! isRunning()) - break; - - Thread::yield(); - } - else - { - DWORD numRead = 0; - if (! ReadFile ((HANDLE) readPipe, dest, numToDo, &numRead, nullptr)) - break; - - total += numRead; - dest = addBytesToPointer (dest, numRead); - numNeeded -= numRead; - } - } - - return total; - } - - bool killProcess() const noexcept - { - return TerminateProcess (processInfo.hProcess, 0) != FALSE; - } - - uint32 getExitCode() const noexcept - { - DWORD exitCode = 0; - GetExitCodeProcess (processInfo.hProcess, &exitCode); - return (uint32) exitCode; - } - - bool ok; - -private: - HANDLE readPipe, writePipe; - PROCESS_INFORMATION processInfo; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ActiveProcess) -}; - -bool ChildProcess::start (const String& command, int streamFlags) -{ - activeProcess = new ActiveProcess (command, streamFlags); - - if (! activeProcess->ok) - activeProcess = nullptr; - - return activeProcess != nullptr; -} - -bool ChildProcess::start (const StringArray& args, int streamFlags) -{ - String escaped; - - for (int i = 0; i < args.size(); ++i) - { - String arg (args[i]); - - // If there are spaces, surround it with quotes. If there are quotes, - // replace them with \" so that CommandLineToArgv will correctly parse them. - if (arg.containsAnyOf ("\" ")) - arg = arg.replace ("\"", "\\\"").quoted(); - - escaped << arg << ' '; - } - - return start (escaped.trim(), streamFlags); -} - -//============================================================================== -struct HighResolutionTimer::Pimpl -{ - Pimpl (HighResolutionTimer& t) noexcept : owner (t), periodMs (0) - { - } - - ~Pimpl() - { - jassert (periodMs == 0); - } - - void start (int newPeriod) - { - if (newPeriod != periodMs) - { - stop(); - periodMs = newPeriod; - - TIMECAPS tc; - if (timeGetDevCaps (&tc, sizeof (tc)) == TIMERR_NOERROR) - { - const int actualPeriod = jlimit ((int) tc.wPeriodMin, (int) tc.wPeriodMax, newPeriod); - - timerID = timeSetEvent (actualPeriod, tc.wPeriodMin, callbackFunction, (DWORD_PTR) this, - TIME_PERIODIC | TIME_CALLBACK_FUNCTION | 0x100 /*TIME_KILL_SYNCHRONOUS*/); - } - } - } - - void stop() - { - periodMs = 0; - timeKillEvent (timerID); - } - - HighResolutionTimer& owner; - int periodMs; - -private: - unsigned int timerID; - - static void __stdcall callbackFunction (UINT, UINT, DWORD_PTR userInfo, DWORD_PTR, DWORD_PTR) - { - if (Pimpl* const timer = reinterpret_cast (userInfo)) - if (timer->periodMs != 0) - timer->owner.hiResTimerCallback(); - } - - JUCE_DECLARE_NON_COPYABLE (Pimpl) -}; diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/network/juce_IPAddress.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/network/juce_IPAddress.cpp deleted file mode 100644 index 6c4d087712..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/network/juce_IPAddress.cpp +++ /dev/null @@ -1,149 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -IPAddress::IPAddress() noexcept -{ - address[0] = 0; address[1] = 0; - address[2] = 0; address[3] = 0; -} - -IPAddress::IPAddress (const uint8 bytes[4]) noexcept -{ - address[0] = bytes[0]; address[1] = bytes[1]; - address[2] = bytes[2]; address[3] = bytes[3]; -} - -IPAddress::IPAddress (uint8 a0, uint8 a1, uint8 a2, uint8 a3) noexcept -{ - address[0] = a0; address[1] = a1; - address[2] = a2; address[3] = a3; -} - -IPAddress::IPAddress (uint32 n) noexcept -{ - address[0] = (n >> 24); - address[1] = (n >> 16) & 255; - address[2] = (n >> 8) & 255; - address[3] = (n & 255); -} - -IPAddress::IPAddress (const String& adr) -{ - StringArray tokens; - tokens.addTokens (adr, ".", String()); - - for (int i = 0; i < 4; ++i) - address[i] = (uint8) tokens[i].getIntValue(); -} - -String IPAddress::toString() const -{ - String s ((int) address[0]); - - for (int i = 1; i < 4; ++i) - s << '.' << (int) address[i]; - - return s; -} - -IPAddress IPAddress::any() noexcept { return IPAddress(); } -IPAddress IPAddress::broadcast() noexcept { return IPAddress (255, 255, 255, 255); } -IPAddress IPAddress::local() noexcept { return IPAddress (127, 0, 0, 1); } - -bool IPAddress::operator== (const IPAddress& other) const noexcept -{ - return address[0] == other.address[0] - && address[1] == other.address[1] - && address[2] == other.address[2] - && address[3] == other.address[3]; -} - -bool IPAddress::operator!= (const IPAddress& other) const noexcept -{ - return ! operator== (other); -} - -#if ! JUCE_WINDOWS -static void addAddress (const sockaddr_in* addr_in, Array& result) -{ - in_addr_t addr = addr_in->sin_addr.s_addr; - - if (addr != INADDR_NONE) - result.addIfNotAlreadyThere (IPAddress (ntohl (addr))); -} - -static void findIPAddresses (int sock, Array& result) -{ - ifconf cfg; - HeapBlock buffer; - int bufferSize = 1024; - - do - { - bufferSize *= 2; - buffer.calloc ((size_t) bufferSize); - - cfg.ifc_len = bufferSize; - cfg.ifc_buf = buffer; - - if (ioctl (sock, SIOCGIFCONF, &cfg) < 0 && errno != EINVAL) - return; - - } while (bufferSize < cfg.ifc_len + 2 * (int) (IFNAMSIZ + sizeof (struct sockaddr_in6))); - - #if JUCE_MAC || JUCE_IOS - while (cfg.ifc_len >= (int) (IFNAMSIZ + sizeof (struct sockaddr_in))) - { - if (cfg.ifc_req->ifr_addr.sa_family == AF_INET) // Skip non-internet addresses - addAddress ((const sockaddr_in*) &cfg.ifc_req->ifr_addr, result); - - cfg.ifc_len -= IFNAMSIZ + cfg.ifc_req->ifr_addr.sa_len; - cfg.ifc_buf += IFNAMSIZ + cfg.ifc_req->ifr_addr.sa_len; - } - #else - for (size_t i = 0; i < cfg.ifc_len / sizeof (struct ifreq); ++i) - { - const ifreq& item = cfg.ifc_req[i]; - - if (item.ifr_addr.sa_family == AF_INET) - addAddress ((const sockaddr_in*) &item.ifr_addr, result); - } - #endif -} - -void IPAddress::findAllAddresses (Array& result) -{ - const int sock = socket (AF_INET, SOCK_DGRAM, 0); // a dummy socket to execute the IO control - - if (sock >= 0) - { - findIPAddresses (sock, result); - ::close (sock); - } -} -#endif diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/network/juce_IPAddress.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/network/juce_IPAddress.h deleted file mode 100644 index 1f2f0e8101..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/network/juce_IPAddress.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_IPADDRESS_H_INCLUDED -#define JUCE_IPADDRESS_H_INCLUDED - - -//============================================================================== -/** - An IPV4 address. -*/ -class JUCE_API IPAddress -{ -public: - //============================================================================== - /** Populates a list of all the IP addresses that this machine is using. */ - static void findAllAddresses (Array& results); - - //============================================================================== - /** Creates a null address (0.0.0.0). */ - IPAddress() noexcept; - - /** Creates an address from 4 bytes. */ - explicit IPAddress (const uint8 bytes[4]) noexcept; - - /** Creates an address from 4 bytes. */ - IPAddress (uint8 address1, uint8 address2, uint8 address3, uint8 address4) noexcept; - - /** Creates an address from a packed 32-bit integer, where the MSB is - the first number in the address, and the LSB is the last. - */ - explicit IPAddress (uint32 asNativeEndian32Bit) noexcept; - - /** Parses a string IP address of the form "a.b.c.d". */ - explicit IPAddress (const String& address); - - /** Returns a dot-separated string in the form "1.2.3.4" */ - String toString() const; - - /** Returns an address meaning "any" (0.0.0.0) */ - static IPAddress any() noexcept; - - /** Returns an address meaning "broadcast" (255.255.255.255) */ - static IPAddress broadcast() noexcept; - - /** Returns an address meaning "localhost" (127.0.0.1) */ - static IPAddress local() noexcept; - - bool operator== (const IPAddress& other) const noexcept; - bool operator!= (const IPAddress& other) const noexcept; - - /** The elements of the IP address. */ - uint8 address[4]; -}; - - -#endif // JUCE_IPADDRESS_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/network/juce_MACAddress.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/network/juce_MACAddress.cpp deleted file mode 100644 index b7cb3c115c..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/network/juce_MACAddress.cpp +++ /dev/null @@ -1,78 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -MACAddress::MACAddress() -{ - zeromem (address, sizeof (address)); -} - -MACAddress::MACAddress (const MACAddress& other) -{ - memcpy (address, other.address, sizeof (address)); -} - -MACAddress& MACAddress::operator= (const MACAddress& other) -{ - memcpy (address, other.address, sizeof (address)); - return *this; -} - -MACAddress::MACAddress (const uint8 bytes[6]) -{ - memcpy (address, bytes, sizeof (address)); -} - -String MACAddress::toString() const -{ - String s; - - for (size_t i = 0; i < sizeof (address); ++i) - { - s << String::toHexString ((int) address[i]).paddedLeft ('0', 2); - - if (i < sizeof (address) - 1) - s << '-'; - } - - return s; -} - -int64 MACAddress::toInt64() const noexcept -{ - int64 n = 0; - - for (int i = (int) sizeof (address); --i >= 0;) - n = (n << 8) | address[i]; - - return n; -} - -bool MACAddress::isNull() const noexcept { return toInt64() == 0; } - -bool MACAddress::operator== (const MACAddress& other) const noexcept { return memcmp (address, other.address, sizeof (address)) == 0; } -bool MACAddress::operator!= (const MACAddress& other) const noexcept { return ! operator== (other); } diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/network/juce_MACAddress.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/network/juce_MACAddress.h deleted file mode 100644 index 67e119ec7f..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/network/juce_MACAddress.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_MACADDRESS_H_INCLUDED -#define JUCE_MACADDRESS_H_INCLUDED - - -//============================================================================== -/** - Represents a MAC network card adapter address ID. -*/ -class JUCE_API MACAddress -{ -public: - //============================================================================== - /** Populates a list of the MAC addresses of all the available network cards. */ - static void findAllAddresses (Array& results); - - //============================================================================== - /** Creates a null address (00-00-00-00-00-00). */ - MACAddress(); - - /** Creates a copy of another address. */ - MACAddress (const MACAddress&); - - /** Creates a copy of another address. */ - MACAddress& operator= (const MACAddress&); - - /** Creates an address from 6 bytes. */ - explicit MACAddress (const uint8 bytes[6]); - - /** Returns a pointer to the 6 bytes that make up this address. */ - const uint8* getBytes() const noexcept { return address; } - - /** Returns a dash-separated string in the form "11-22-33-44-55-66" */ - String toString() const; - - /** Returns the address in the lower 6 bytes of an int64. - - This uses a little-endian arrangement, with the first byte of the address being - stored in the least-significant byte of the result value. - */ - int64 toInt64() const noexcept; - - /** Returns true if this address is null (00-00-00-00-00-00). */ - bool isNull() const noexcept; - - bool operator== (const MACAddress&) const noexcept; - bool operator!= (const MACAddress&) const noexcept; - - //============================================================================== -private: - uint8 address[6]; -}; - - -#endif // JUCE_MACADDRESS_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/network/juce_NamedPipe.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/network/juce_NamedPipe.cpp deleted file mode 100644 index 488e63f41e..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/network/juce_NamedPipe.cpp +++ /dev/null @@ -1,66 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -NamedPipe::NamedPipe() -{ -} - -NamedPipe::~NamedPipe() -{ - close(); -} - -bool NamedPipe::openExisting (const String& pipeName) -{ - close(); - - ScopedWriteLock sl (lock); - currentPipeName = pipeName; - return openInternal (pipeName, false); -} - -bool NamedPipe::isOpen() const -{ - return pimpl != nullptr; -} - -bool NamedPipe::createNewPipe (const String& pipeName) -{ - close(); - - ScopedWriteLock sl (lock); - currentPipeName = pipeName; - return openInternal (pipeName, true); -} - -String NamedPipe::getName() const -{ - return currentPipeName; -} - -// other methods for this class are implemented in the platform-specific files diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/network/juce_NamedPipe.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/network/juce_NamedPipe.h deleted file mode 100644 index d2029bd027..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/network/juce_NamedPipe.h +++ /dev/null @@ -1,104 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_NAMEDPIPE_H_INCLUDED -#define JUCE_NAMEDPIPE_H_INCLUDED - - -//============================================================================== -/** - A cross-process pipe that can have data written to and read from it. - - Two processes can use NamedPipe objects to exchange blocks of data. - - @see InterprocessConnection -*/ -class JUCE_API NamedPipe -{ -public: - //============================================================================== - /** Creates a NamedPipe. */ - NamedPipe(); - - /** Destructor. */ - ~NamedPipe(); - - //============================================================================== - /** Tries to open a pipe that already exists. - Returns true if it succeeds. - */ - bool openExisting (const String& pipeName); - - /** Tries to create a new pipe. - Returns true if it succeeds. - */ - bool createNewPipe (const String& pipeName); - - /** Closes the pipe, if it's open. */ - void close(); - - /** True if the pipe is currently open. */ - bool isOpen() const; - - /** Returns the last name that was used to try to open this pipe. */ - String getName() const; - - //============================================================================== - /** Reads data from the pipe. - - This will block until another thread has written enough data into the pipe to fill - the number of bytes specified, or until another thread calls the cancelPendingReads() - method. - - If the operation fails, it returns -1, otherwise, it will return the number of - bytes read. - - If timeOutMilliseconds is less than zero, it will wait indefinitely, otherwise - this is a maximum timeout for reading from the pipe. - */ - int read (void* destBuffer, int maxBytesToRead, int timeOutMilliseconds); - - /** Writes some data to the pipe. - @returns the number of bytes written, or -1 on failure. - */ - int write (const void* sourceBuffer, int numBytesToWrite, int timeOutMilliseconds); - -private: - //============================================================================== - JUCE_PUBLIC_IN_DLL_BUILD (class Pimpl) - ScopedPointer pimpl; - String currentPipeName; - ReadWriteLock lock; - - bool openInternal (const String& pipeName, const bool createPipe); - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (NamedPipe) -}; - - -#endif // JUCE_NAMEDPIPE_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/network/juce_Socket.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/network/juce_Socket.cpp deleted file mode 100644 index 50da39cbc2..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/network/juce_Socket.cpp +++ /dev/null @@ -1,601 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#if JUCE_MSVC - #pragma warning (push) - #pragma warning (disable : 4127 4389 4018) -#endif - -#ifndef AI_NUMERICSERV // (missing in older Mac SDKs) - #define AI_NUMERICSERV 0x1000 -#endif - -#if JUCE_WINDOWS - typedef int juce_socklen_t; - typedef SOCKET SocketHandle; -#else - typedef socklen_t juce_socklen_t; - typedef int SocketHandle; -#endif - -//============================================================================== -namespace SocketHelpers -{ - static void initSockets() - { - #if JUCE_WINDOWS - static bool socketsStarted = false; - - if (! socketsStarted) - { - socketsStarted = true; - - WSADATA wsaData; - const WORD wVersionRequested = MAKEWORD (1, 1); - WSAStartup (wVersionRequested, &wsaData); - } - #endif - } - - static bool resetSocketOptions (const SocketHandle handle, const bool isDatagram, const bool allowBroadcast) noexcept - { - const int sndBufSize = 65536; - const int rcvBufSize = 65536; - const int one = 1; - - return handle > 0 - && setsockopt (handle, SOL_SOCKET, SO_RCVBUF, (const char*) &rcvBufSize, sizeof (rcvBufSize)) == 0 - && setsockopt (handle, SOL_SOCKET, SO_SNDBUF, (const char*) &sndBufSize, sizeof (sndBufSize)) == 0 - && (isDatagram ? ((! allowBroadcast) || setsockopt (handle, SOL_SOCKET, SO_BROADCAST, (const char*) &one, sizeof (one)) == 0) - : (setsockopt (handle, IPPROTO_TCP, TCP_NODELAY, (const char*) &one, sizeof (one)) == 0)); - } - - static bool bindSocketToPort (const SocketHandle handle, const int port) noexcept - { - if (handle <= 0 || port <= 0) - return false; - - struct sockaddr_in servTmpAddr; - zerostruct (servTmpAddr); // (can't use "= { 0 }" on this object because it's typedef'ed as a C struct) - servTmpAddr.sin_family = PF_INET; - servTmpAddr.sin_addr.s_addr = htonl (INADDR_ANY); - servTmpAddr.sin_port = htons ((uint16) port); - - return bind (handle, (struct sockaddr*) &servTmpAddr, sizeof (struct sockaddr_in)) >= 0; - } - - static int readSocket (const SocketHandle handle, - void* const destBuffer, const int maxBytesToRead, - bool volatile& connected, - const bool blockUntilSpecifiedAmountHasArrived) noexcept - { - int bytesRead = 0; - - while (bytesRead < maxBytesToRead) - { - int bytesThisTime; - - #if JUCE_WINDOWS - bytesThisTime = recv (handle, static_cast (destBuffer) + bytesRead, maxBytesToRead - bytesRead, 0); - #else - while ((bytesThisTime = (int) ::read (handle, addBytesToPointer (destBuffer, bytesRead), - (size_t) (maxBytesToRead - bytesRead))) < 0 - && errno == EINTR - && connected) - { - } - #endif - - if (bytesThisTime <= 0 || ! connected) - { - if (bytesRead == 0) - bytesRead = -1; - - break; - } - - bytesRead += bytesThisTime; - - if (! blockUntilSpecifiedAmountHasArrived) - break; - } - - return bytesRead; - } - - static int waitForReadiness (const SocketHandle handle, const bool forReading, const int timeoutMsecs) noexcept - { - struct timeval timeout; - struct timeval* timeoutp; - - if (timeoutMsecs >= 0) - { - timeout.tv_sec = timeoutMsecs / 1000; - timeout.tv_usec = (timeoutMsecs % 1000) * 1000; - timeoutp = &timeout; - } - else - { - timeoutp = 0; - } - - fd_set rset, wset; - FD_ZERO (&rset); - FD_SET (handle, &rset); - FD_ZERO (&wset); - FD_SET (handle, &wset); - - fd_set* const prset = forReading ? &rset : nullptr; - fd_set* const pwset = forReading ? nullptr : &wset; - - #if JUCE_WINDOWS - if (select ((int) handle + 1, prset, pwset, 0, timeoutp) < 0) - return -1; - #else - { - int result; - while ((result = select (handle + 1, prset, pwset, 0, timeoutp)) < 0 - && errno == EINTR) - { - } - - if (result < 0) - return -1; - } - #endif - - { - int opt; - juce_socklen_t len = sizeof (opt); - - if (getsockopt (handle, SOL_SOCKET, SO_ERROR, (char*) &opt, &len) < 0 - || opt != 0) - return -1; - } - - return FD_ISSET (handle, forReading ? &rset : &wset) ? 1 : 0; - } - - static bool setSocketBlockingState (const SocketHandle handle, const bool shouldBlock) noexcept - { - #if JUCE_WINDOWS - u_long nonBlocking = shouldBlock ? 0 : (u_long) 1; - return ioctlsocket (handle, FIONBIO, &nonBlocking) == 0; - #else - int socketFlags = fcntl (handle, F_GETFL, 0); - - if (socketFlags == -1) - return false; - - if (shouldBlock) - socketFlags &= ~O_NONBLOCK; - else - socketFlags |= O_NONBLOCK; - - return fcntl (handle, F_SETFL, socketFlags) == 0; - #endif - } - - static bool connectSocket (int volatile& handle, - const bool isDatagram, - struct addrinfo** const serverAddress, - const String& hostName, - const int portNumber, - const int timeOutMillisecs) noexcept - { - struct addrinfo hints; - zerostruct (hints); - - hints.ai_family = AF_UNSPEC; - hints.ai_socktype = isDatagram ? SOCK_DGRAM : SOCK_STREAM; - hints.ai_flags = AI_NUMERICSERV; - - struct addrinfo* info = nullptr; - if (getaddrinfo (hostName.toUTF8(), String (portNumber).toUTF8(), &hints, &info) != 0 - || info == nullptr) - return false; - - if (handle < 0) - handle = (int) socket (info->ai_family, info->ai_socktype, 0); - - if (handle < 0) - { - freeaddrinfo (info); - return false; - } - - if (isDatagram) - { - if (*serverAddress != nullptr) - freeaddrinfo (*serverAddress); - - *serverAddress = info; - return true; - } - - setSocketBlockingState (handle, false); - const int result = ::connect (handle, info->ai_addr, (socklen_t) info->ai_addrlen); - freeaddrinfo (info); - - if (result < 0) - { - #if JUCE_WINDOWS - if (result == SOCKET_ERROR && WSAGetLastError() == WSAEWOULDBLOCK) - #else - if (errno == EINPROGRESS) - #endif - { - if (waitForReadiness (handle, false, timeOutMillisecs) != 1) - { - setSocketBlockingState (handle, true); - return false; - } - } - } - - setSocketBlockingState (handle, true); - resetSocketOptions (handle, false, false); - - return true; - } - - static void makeReusable (int handle) noexcept - { - const int reuse = 1; - setsockopt (handle, SOL_SOCKET, SO_REUSEADDR, (const char*) &reuse, sizeof (reuse)); - } -} - -//============================================================================== -StreamingSocket::StreamingSocket() - : portNumber (0), - handle (-1), - connected (false), - isListener (false) -{ - SocketHelpers::initSockets(); -} - -StreamingSocket::StreamingSocket (const String& host, int portNum, int h) - : hostName (host), - portNumber (portNum), - handle (h), - connected (true), - isListener (false) -{ - SocketHelpers::initSockets(); - SocketHelpers::resetSocketOptions (h, false, false); -} - -StreamingSocket::~StreamingSocket() -{ - close(); -} - -//============================================================================== -int StreamingSocket::read (void* destBuffer, const int maxBytesToRead, - const bool blockUntilSpecifiedAmountHasArrived) -{ - return (connected && ! isListener) ? SocketHelpers::readSocket (handle, destBuffer, maxBytesToRead, - connected, blockUntilSpecifiedAmountHasArrived) - : -1; -} - -int StreamingSocket::write (const void* sourceBuffer, const int numBytesToWrite) -{ - if (isListener || ! connected) - return -1; - - #if JUCE_WINDOWS - return send (handle, (const char*) sourceBuffer, numBytesToWrite, 0); - #else - int result; - - while ((result = (int) ::write (handle, sourceBuffer, (size_t) numBytesToWrite)) < 0 - && errno == EINTR) - { - } - - return result; - #endif -} - -//============================================================================== -int StreamingSocket::waitUntilReady (const bool readyForReading, - const int timeoutMsecs) const -{ - return connected ? SocketHelpers::waitForReadiness (handle, readyForReading, timeoutMsecs) - : -1; -} - -//============================================================================== -bool StreamingSocket::bindToPort (const int port) -{ - return SocketHelpers::bindSocketToPort (handle, port); -} - -bool StreamingSocket::connect (const String& remoteHostName, - const int remotePortNumber, - const int timeOutMillisecs) -{ - if (isListener) - { - jassertfalse; // a listener socket can't connect to another one! - return false; - } - - if (connected) - close(); - - hostName = remoteHostName; - portNumber = remotePortNumber; - isListener = false; - - connected = SocketHelpers::connectSocket (handle, false, nullptr, remoteHostName, - remotePortNumber, timeOutMillisecs); - - if (! (connected && SocketHelpers::resetSocketOptions (handle, false, false))) - { - close(); - return false; - } - - return true; -} - -void StreamingSocket::close() -{ - #if JUCE_WINDOWS - if (handle != SOCKET_ERROR || connected) - closesocket (handle); - - connected = false; - #else - if (connected) - { - connected = false; - - if (isListener) - { - // need to do this to interrupt the accept() function.. - StreamingSocket temp; - temp.connect (IPAddress::local().toString(), portNumber, 1000); - } - } - - if (handle != -1) - ::close (handle); - #endif - - hostName.clear(); - portNumber = 0; - handle = -1; - isListener = false; -} - -//============================================================================== -bool StreamingSocket::createListener (const int newPortNumber, const String& localHostName) -{ - if (connected) - close(); - - hostName = "listener"; - portNumber = newPortNumber; - isListener = true; - - struct sockaddr_in servTmpAddr; - zerostruct (servTmpAddr); - - servTmpAddr.sin_family = PF_INET; - servTmpAddr.sin_addr.s_addr = htonl (INADDR_ANY); - - if (localHostName.isNotEmpty()) - servTmpAddr.sin_addr.s_addr = ::inet_addr (localHostName.toUTF8()); - - servTmpAddr.sin_port = htons ((uint16) portNumber); - - handle = (int) socket (AF_INET, SOCK_STREAM, 0); - - if (handle < 0) - return false; - - #if ! JUCE_WINDOWS // on windows, adding this option produces behaviour different to posix - SocketHelpers::makeReusable (handle); - #endif - - if (bind (handle, (struct sockaddr*) &servTmpAddr, sizeof (struct sockaddr_in)) < 0 - || listen (handle, SOMAXCONN) < 0) - { - close(); - return false; - } - - connected = true; - return true; -} - -StreamingSocket* StreamingSocket::waitForNextConnection() const -{ - // To call this method, you first have to use createListener() to - // prepare this socket as a listener. - jassert (isListener || ! connected); - - if (connected && isListener) - { - struct sockaddr_storage address; - juce_socklen_t len = sizeof (address); - const int newSocket = (int) accept (handle, (struct sockaddr*) &address, &len); - - if (newSocket >= 0 && connected) - return new StreamingSocket (inet_ntoa (((struct sockaddr_in*) &address)->sin_addr), - portNumber, newSocket); - } - - return nullptr; -} - -bool StreamingSocket::isLocal() const noexcept -{ - return hostName == "127.0.0.1"; -} - - -//============================================================================== -//============================================================================== -DatagramSocket::DatagramSocket (const int localPortNumber, const bool canBroadcast) - : portNumber (0), - handle (-1), - connected (true), - allowBroadcast (canBroadcast), - serverAddress (nullptr) -{ - SocketHelpers::initSockets(); - - handle = (int) socket (AF_INET, SOCK_DGRAM, 0); - SocketHelpers::makeReusable (handle); - bindToPort (localPortNumber); -} - -DatagramSocket::DatagramSocket (const String& host, const int portNum, - const int h, const int localPortNumber) - : hostName (host), - portNumber (portNum), - handle (h), - connected (true), - allowBroadcast (false), - serverAddress (nullptr) -{ - SocketHelpers::initSockets(); - - SocketHelpers::resetSocketOptions (h, true, allowBroadcast); - bindToPort (localPortNumber); -} - -DatagramSocket::~DatagramSocket() -{ - close(); - - if (serverAddress != nullptr) - freeaddrinfo (static_cast (serverAddress)); -} - -void DatagramSocket::close() -{ - #if JUCE_WINDOWS - closesocket (handle); - connected = false; - #else - connected = false; - ::close (handle); - #endif - - hostName.clear(); - portNumber = 0; - handle = -1; -} - -bool DatagramSocket::bindToPort (const int port) -{ - return SocketHelpers::bindSocketToPort (handle, port); -} - -bool DatagramSocket::connect (const String& remoteHostName, - const int remotePortNumber, - const int timeOutMillisecs) -{ - if (connected) - close(); - - hostName = remoteHostName; - portNumber = remotePortNumber; - - connected = SocketHelpers::connectSocket (handle, true, (struct addrinfo**) &serverAddress, - remoteHostName, remotePortNumber, - timeOutMillisecs); - - if (! (connected && SocketHelpers::resetSocketOptions (handle, true, allowBroadcast))) - { - close(); - return false; - } - - return true; -} - -DatagramSocket* DatagramSocket::waitForNextConnection() const -{ - while (waitUntilReady (true, -1) == 1) - { - struct sockaddr_storage address; - juce_socklen_t len = sizeof (address); - char buf[1]; - - if (recvfrom (handle, buf, 0, 0, (struct sockaddr*) &address, &len) > 0) - return new DatagramSocket (inet_ntoa (((struct sockaddr_in*) &address)->sin_addr), - ntohs (((struct sockaddr_in*) &address)->sin_port), - -1, -1); - } - - return nullptr; -} - -//============================================================================== -int DatagramSocket::waitUntilReady (const bool readyForReading, - const int timeoutMsecs) const -{ - return connected ? SocketHelpers::waitForReadiness (handle, readyForReading, timeoutMsecs) - : -1; -} - -int DatagramSocket::read (void* destBuffer, const int maxBytesToRead, const bool blockUntilSpecifiedAmountHasArrived) -{ - return connected ? SocketHelpers::readSocket (handle, destBuffer, maxBytesToRead, - connected, blockUntilSpecifiedAmountHasArrived) - : -1; -} - -int DatagramSocket::write (const void* sourceBuffer, const int numBytesToWrite) -{ - // You need to call connect() first to set the server address.. - jassert (serverAddress != nullptr && connected); - - return connected ? (int) sendto (handle, (const char*) sourceBuffer, - (size_t) numBytesToWrite, 0, - static_cast (serverAddress)->ai_addr, - (juce_socklen_t) static_cast (serverAddress)->ai_addrlen) - : -1; -} - -bool DatagramSocket::isLocal() const noexcept -{ - return hostName == "127.0.0.1"; -} - -#if JUCE_MSVC - #pragma warning (pop) -#endif diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/network/juce_Socket.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/network/juce_Socket.h deleted file mode 100644 index 73795c9563..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/network/juce_Socket.h +++ /dev/null @@ -1,305 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_SOCKET_H_INCLUDED -#define JUCE_SOCKET_H_INCLUDED - - -//============================================================================== -/** - A wrapper for a streaming (TCP) socket. - - This allows low-level use of sockets; for an easier-to-use messaging layer on top of - sockets, you could also try the InterprocessConnection class. - - @see DatagramSocket, InterprocessConnection, InterprocessConnectionServer -*/ -class JUCE_API StreamingSocket -{ -public: - //============================================================================== - /** Creates an uninitialised socket. - - To connect it, use the connect() method, after which you can read() or write() - to it. - - To wait for other sockets to connect to this one, the createListener() method - enters "listener" mode, and can be used to spawn new sockets for each connection - that comes along. - */ - StreamingSocket(); - - /** Destructor. */ - ~StreamingSocket(); - - //============================================================================== - /** Binds the socket to the specified local port. - - @returns true on success; false may indicate that another socket is already bound - on the same port - */ - bool bindToPort (int localPortNumber); - - /** Tries to connect the socket to hostname:port. - - If timeOutMillisecs is 0, then this method will block until the operating system - rejects the connection (which could take a long time). - - @returns true if it succeeds. - @see isConnected - */ - bool connect (const String& remoteHostname, - int remotePortNumber, - int timeOutMillisecs = 3000); - - /** True if the socket is currently connected. */ - bool isConnected() const noexcept { return connected; } - - /** Closes the connection. */ - void close(); - - /** Returns the name of the currently connected host. */ - const String& getHostName() const noexcept { return hostName; } - - /** Returns the port number that's currently open. */ - int getPort() const noexcept { return portNumber; } - - /** True if the socket is connected to this machine rather than over the network. */ - bool isLocal() const noexcept; - - /** Returns the OS's socket handle that's currently open. */ - int getRawSocketHandle() const noexcept { return handle; } - - //============================================================================== - /** Waits until the socket is ready for reading or writing. - - If readyForReading is true, it will wait until the socket is ready for - reading; if false, it will wait until it's ready for writing. - - If the timeout is < 0, it will wait forever, or else will give up after - the specified time. - - If the socket is ready on return, this returns 1. If it times-out before - the socket becomes ready, it returns 0. If an error occurs, it returns -1. - */ - int waitUntilReady (bool readyForReading, - int timeoutMsecs) const; - - /** Reads bytes from the socket. - - If blockUntilSpecifiedAmountHasArrived is true, the method will block until - maxBytesToRead bytes have been read, (or until an error occurs). If this - flag is false, the method will return as much data as is currently available - without blocking. - - @returns the number of bytes read, or -1 if there was an error. - @see waitUntilReady - */ - int read (void* destBuffer, int maxBytesToRead, - bool blockUntilSpecifiedAmountHasArrived); - - /** Writes bytes to the socket from a buffer. - - Note that this method will block unless you have checked the socket is ready - for writing before calling it (see the waitUntilReady() method). - - @returns the number of bytes written, or -1 if there was an error. - */ - int write (const void* sourceBuffer, int numBytesToWrite); - - //============================================================================== - /** Puts this socket into "listener" mode. - - When in this mode, your thread can call waitForNextConnection() repeatedly, - which will spawn new sockets for each new connection, so that these can - be handled in parallel by other threads. - - @param portNumber the port number to listen on - @param localHostName the interface address to listen on - pass an empty - string to listen on all addresses - @returns true if it manages to open the socket successfully. - - @see waitForNextConnection - */ - bool createListener (int portNumber, const String& localHostName = String()); - - /** When in "listener" mode, this waits for a connection and spawns it as a new - socket. - - The object that gets returned will be owned by the caller. - - This method can only be called after using createListener(). - - @see createListener - */ - StreamingSocket* waitForNextConnection() const; - -private: - //============================================================================== - String hostName; - int volatile portNumber, handle; - bool connected, isListener; - - StreamingSocket (const String& hostname, int portNumber, int handle); - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (StreamingSocket) -}; - - -//============================================================================== -/** - A wrapper for a datagram (UDP) socket. - - This allows low-level use of sockets; for an easier-to-use messaging layer on top of - sockets, you could also try the InterprocessConnection class. - - @see StreamingSocket, InterprocessConnection, InterprocessConnectionServer -*/ -class JUCE_API DatagramSocket -{ -public: - //============================================================================== - /** - Creates an (uninitialised) datagram socket. - - The localPortNumber is the port on which to bind this socket. If this value is 0, - the port number is assigned by the operating system. - - To use the socket for sending, call the connect() method. This will not immediately - make a connection, but will save the destination you've provided. After this, you can - call read() or write(). - - If enableBroadcasting is true, the socket will be allowed to send broadcast messages - (may require extra privileges on linux) - - To wait for other sockets to connect to this one, call waitForNextConnection(). - */ - DatagramSocket (int localPortNumber, - bool enableBroadcasting = false); - - /** Destructor. */ - ~DatagramSocket(); - - //============================================================================== - /** Binds the socket to the specified local port. - - @returns true on success; false may indicate that another socket is already bound - on the same port - */ - bool bindToPort (int localPortNumber); - - /** Tries to connect the socket to hostname:port. - - If timeOutMillisecs is 0, then this method will block until the operating system - rejects the connection (which could take a long time). - - @returns true if it succeeds. - @see isConnected - */ - bool connect (const String& remoteHostname, - int remotePortNumber, - int timeOutMillisecs = 3000); - - /** True if the socket is currently connected. */ - bool isConnected() const noexcept { return connected; } - - /** Closes the connection. */ - void close(); - - /** Returns the name of the currently connected host. */ - const String& getHostName() const noexcept { return hostName; } - - /** Returns the port number that's currently open. */ - int getPort() const noexcept { return portNumber; } - - /** True if the socket is connected to this machine rather than over the network. */ - bool isLocal() const noexcept; - - /** Returns the OS's socket handle that's currently open. */ - int getRawSocketHandle() const noexcept { return handle; } - - //============================================================================== - /** Waits until the socket is ready for reading or writing. - - If readyForReading is true, it will wait until the socket is ready for - reading; if false, it will wait until it's ready for writing. - - If the timeout is < 0, it will wait forever, or else will give up after - the specified time. - - If the socket is ready on return, this returns 1. If it times-out before - the socket becomes ready, it returns 0. If an error occurs, it returns -1. - */ - int waitUntilReady (bool readyForReading, - int timeoutMsecs) const; - - /** Reads bytes from the socket. - - If blockUntilSpecifiedAmountHasArrived is true, the method will block until - maxBytesToRead bytes have been read, (or until an error occurs). If this - flag is false, the method will return as much data as is currently available - without blocking. - - @returns the number of bytes read, or -1 if there was an error. - @see waitUntilReady - */ - int read (void* destBuffer, int maxBytesToRead, - bool blockUntilSpecifiedAmountHasArrived); - - /** Writes bytes to the socket from a buffer. - - Note that this method will block unless you have checked the socket is ready - for writing before calling it (see the waitUntilReady() method). - - @returns the number of bytes written, or -1 if there was an error. - */ - int write (const void* sourceBuffer, int numBytesToWrite); - - //============================================================================== - /** This waits for incoming data to be sent, and returns a socket that can be used - to read it. - - The object that gets returned is owned by the caller, and can't be used for - sending, but can be used to read the data. - */ - DatagramSocket* waitForNextConnection() const; - -private: - //============================================================================== - String hostName; - int volatile portNumber, handle; - bool connected, allowBroadcast; - void* serverAddress; - - DatagramSocket (const String& hostname, int portNumber, int handle, int localPortNumber); - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (DatagramSocket) -}; - - -#endif // JUCE_SOCKET_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/network/juce_URL.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/network/juce_URL.cpp deleted file mode 100644 index 76d2b1e79f..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/network/juce_URL.cpp +++ /dev/null @@ -1,502 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -URL::URL() -{ -} - -URL::URL (const String& u) : url (u) -{ - int i = url.indexOfChar ('?'); - - if (i >= 0) - { - do - { - const int nextAmp = url.indexOfChar (i + 1, '&'); - const int equalsPos = url.indexOfChar (i + 1, '='); - - if (equalsPos > i + 1) - { - if (nextAmp < 0) - { - addParameter (removeEscapeChars (url.substring (i + 1, equalsPos)), - removeEscapeChars (url.substring (equalsPos + 1))); - } - else if (nextAmp > 0 && equalsPos < nextAmp) - { - addParameter (removeEscapeChars (url.substring (i + 1, equalsPos)), - removeEscapeChars (url.substring (equalsPos + 1, nextAmp))); - } - } - - i = nextAmp; - } - while (i >= 0); - - url = url.upToFirstOccurrenceOf ("?", false, false); - } -} - -URL::URL (const String& u, int) : url (u) {} - -URL URL::createWithoutParsing (const String& u) -{ - return URL (u, 0); -} - -URL::URL (const URL& other) - : url (other.url), - postData (other.postData), - parameterNames (other.parameterNames), - parameterValues (other.parameterValues), - filesToUpload (other.filesToUpload) -{ -} - -URL& URL::operator= (const URL& other) -{ - url = other.url; - postData = other.postData; - parameterNames = other.parameterNames; - parameterValues = other.parameterValues; - filesToUpload = other.filesToUpload; - - return *this; -} - -bool URL::operator== (const URL& other) const -{ - return url == other.url - && postData == other.postData - && parameterNames == other.parameterNames - && parameterValues == other.parameterValues - && filesToUpload == other.filesToUpload; -} - -bool URL::operator!= (const URL& other) const -{ - return ! operator== (other); -} - -URL::~URL() -{ -} - -namespace URLHelpers -{ - static String getMangledParameters (const URL& url) - { - jassert (url.getParameterNames().size() == url.getParameterValues().size()); - String p; - - for (int i = 0; i < url.getParameterNames().size(); ++i) - { - if (i > 0) - p << '&'; - - p << URL::addEscapeChars (url.getParameterNames()[i], true) - << '=' - << URL::addEscapeChars (url.getParameterValues()[i], true); - } - - return p; - } - - static int findEndOfScheme (const String& url) - { - int i = 0; - - while (CharacterFunctions::isLetterOrDigit (url[i]) - || url[i] == '+' || url[i] == '-' || url[i] == '.') - ++i; - - return url[i] == ':' ? i + 1 : 0; - } - - static int findStartOfNetLocation (const String& url) - { - int start = findEndOfScheme (url); - while (url[start] == '/') - ++start; - - return start; - } - - static int findStartOfPath (const String& url) - { - return url.indexOfChar (findStartOfNetLocation (url), '/') + 1; - } - - static void concatenatePaths (String& path, const String& suffix) - { - if (! path.endsWithChar ('/')) - path << '/'; - - if (suffix.startsWithChar ('/')) - path += suffix.substring (1); - else - path += suffix; - } -} - -void URL::addParameter (const String& name, const String& value) -{ - parameterNames.add (name); - parameterValues.add (value); -} - -String URL::toString (const bool includeGetParameters) const -{ - if (includeGetParameters && parameterNames.size() > 0) - return url + "?" + URLHelpers::getMangledParameters (*this); - - return url; -} - -bool URL::isEmpty() const noexcept -{ - return url.isEmpty(); -} - -bool URL::isWellFormed() const -{ - //xxx TODO - return url.isNotEmpty(); -} - -String URL::getDomain() const -{ - const int start = URLHelpers::findStartOfNetLocation (url); - const int end1 = url.indexOfChar (start, '/'); - const int end2 = url.indexOfChar (start, ':'); - - const int end = (end1 < 0 && end2 < 0) ? std::numeric_limits::max() - : ((end1 < 0 || end2 < 0) ? jmax (end1, end2) - : jmin (end1, end2)); - return url.substring (start, end); -} - -String URL::getSubPath() const -{ - const int startOfPath = URLHelpers::findStartOfPath (url); - - return startOfPath <= 0 ? String() - : url.substring (startOfPath); -} - -String URL::getScheme() const -{ - return url.substring (0, URLHelpers::findEndOfScheme (url) - 1); -} - -int URL::getPort() const -{ - const int colonPos = url.indexOfChar (URLHelpers::findStartOfNetLocation (url), ':'); - - return colonPos > 0 ? url.substring (colonPos + 1).getIntValue() : 0; -} - -URL URL::withNewSubPath (const String& newPath) const -{ - const int startOfPath = URLHelpers::findStartOfPath (url); - - URL u (*this); - - if (startOfPath > 0) - u.url = url.substring (0, startOfPath); - - URLHelpers::concatenatePaths (u.url, newPath); - return u; -} - -URL URL::getChildURL (const String& subPath) const -{ - URL u (*this); - URLHelpers::concatenatePaths (u.url, subPath); - return u; -} - -void URL::createHeadersAndPostData (String& headers, MemoryBlock& headersAndPostData) const -{ - MemoryOutputStream data (headersAndPostData, false); - - if (filesToUpload.size() > 0) - { - // (this doesn't currently support mixing custom post-data with uploads..) - jassert (postData.isEmpty()); - - const String boundary (String::toHexString (Random::getSystemRandom().nextInt64())); - - headers << "Content-Type: multipart/form-data; boundary=" << boundary << "\r\n"; - - data << "--" << boundary; - - for (int i = 0; i < parameterNames.size(); ++i) - { - data << "\r\nContent-Disposition: form-data; name=\"" << parameterNames[i] - << "\"\r\n\r\n" << parameterValues[i] - << "\r\n--" << boundary; - } - - for (int i = 0; i < filesToUpload.size(); ++i) - { - const Upload& f = *filesToUpload.getObjectPointerUnchecked(i); - - data << "\r\nContent-Disposition: form-data; name=\"" << f.parameterName - << "\"; filename=\"" << f.filename << "\"\r\n"; - - if (f.mimeType.isNotEmpty()) - data << "Content-Type: " << f.mimeType << "\r\n"; - - data << "Content-Transfer-Encoding: binary\r\n\r\n"; - - if (f.data != nullptr) - data << *f.data; - else - data << f.file; - - data << "\r\n--" << boundary; - } - - data << "--\r\n"; - } - else - { - data << URLHelpers::getMangledParameters (*this) - << postData; - - // if the user-supplied headers didn't contain a content-type, add one now.. - if (! headers.containsIgnoreCase ("Content-Type")) - headers << "Content-Type: application/x-www-form-urlencoded\r\n"; - - headers << "Content-length: " << (int) data.getDataSize() << "\r\n"; - } -} - -//============================================================================== -bool URL::isProbablyAWebsiteURL (const String& possibleURL) -{ - static const char* validProtocols[] = { "http:", "ftp:", "https:" }; - - for (int i = 0; i < numElementsInArray (validProtocols); ++i) - if (possibleURL.startsWithIgnoreCase (validProtocols[i])) - return true; - - if (possibleURL.containsChar ('@') - || possibleURL.containsChar (' ')) - return false; - - const String topLevelDomain (possibleURL.upToFirstOccurrenceOf ("/", false, false) - .fromLastOccurrenceOf (".", false, false)); - - return topLevelDomain.isNotEmpty() && topLevelDomain.length() <= 3; -} - -bool URL::isProbablyAnEmailAddress (const String& possibleEmailAddress) -{ - const int atSign = possibleEmailAddress.indexOfChar ('@'); - - return atSign > 0 - && possibleEmailAddress.lastIndexOfChar ('.') > (atSign + 1) - && ! possibleEmailAddress.endsWithChar ('.'); -} - -//============================================================================== -InputStream* URL::createInputStream (const bool usePostCommand, - OpenStreamProgressCallback* const progressCallback, - void* const progressCallbackContext, - String headers, - const int timeOutMs, - StringPairArray* const responseHeaders, - int* statusCode) const -{ - MemoryBlock headersAndPostData; - - if (! headers.endsWithChar ('\n')) - headers << "\r\n"; - - if (usePostCommand) - createHeadersAndPostData (headers, headersAndPostData); - - if (! headers.endsWithChar ('\n')) - headers << "\r\n"; - - ScopedPointer wi (new WebInputStream (toString (! usePostCommand), - usePostCommand, headersAndPostData, - progressCallback, progressCallbackContext, - headers, timeOutMs, responseHeaders)); - - if (statusCode != nullptr) - *statusCode = wi->statusCode; - - return wi->isError() ? nullptr : wi.release(); -} - -//============================================================================== -bool URL::readEntireBinaryStream (MemoryBlock& destData, - const bool usePostCommand) const -{ - const ScopedPointer in (createInputStream (usePostCommand)); - - if (in != nullptr) - { - in->readIntoMemoryBlock (destData); - return true; - } - - return false; -} - -String URL::readEntireTextStream (const bool usePostCommand) const -{ - const ScopedPointer in (createInputStream (usePostCommand)); - - if (in != nullptr) - return in->readEntireStreamAsString(); - - return String(); -} - -XmlElement* URL::readEntireXmlStream (const bool usePostCommand) const -{ - return XmlDocument::parse (readEntireTextStream (usePostCommand)); -} - -//============================================================================== -URL URL::withParameter (const String& parameterName, - const String& parameterValue) const -{ - URL u (*this); - u.addParameter (parameterName, parameterValue); - return u; -} - -URL URL::withPOSTData (const String& newPostData) const -{ - URL u (*this); - u.postData = newPostData; - return u; -} - -URL::Upload::Upload (const String& param, const String& name, - const String& mime, const File& f, MemoryBlock* mb) - : parameterName (param), filename (name), mimeType (mime), file (f), data (mb) -{ - jassert (mimeType.isNotEmpty()); // You need to supply a mime type! -} - -URL URL::withUpload (Upload* const f) const -{ - URL u (*this); - - for (int i = u.filesToUpload.size(); --i >= 0;) - if (u.filesToUpload.getObjectPointerUnchecked(i)->parameterName == f->parameterName) - u.filesToUpload.remove (i); - - u.filesToUpload.add (f); - return u; -} - -URL URL::withFileToUpload (const String& parameterName, const File& fileToUpload, - const String& mimeType) const -{ - return withUpload (new Upload (parameterName, fileToUpload.getFileName(), - mimeType, fileToUpload, nullptr)); -} - -URL URL::withDataToUpload (const String& parameterName, const String& filename, - const MemoryBlock& fileContentToUpload, const String& mimeType) const -{ - return withUpload (new Upload (parameterName, filename, mimeType, File(), - new MemoryBlock (fileContentToUpload))); -} - -//============================================================================== -String URL::removeEscapeChars (const String& s) -{ - String result (s.replaceCharacter ('+', ' ')); - - if (! result.containsChar ('%')) - return result; - - // We need to operate on the string as raw UTF8 chars, and then recombine them into unicode - // after all the replacements have been made, so that multi-byte chars are handled. - Array utf8 (result.toRawUTF8(), (int) result.getNumBytesAsUTF8()); - - for (int i = 0; i < utf8.size(); ++i) - { - if (utf8.getUnchecked(i) == '%') - { - const int hexDigit1 = CharacterFunctions::getHexDigitValue ((juce_wchar) (uint8) utf8 [i + 1]); - const int hexDigit2 = CharacterFunctions::getHexDigitValue ((juce_wchar) (uint8) utf8 [i + 2]); - - if (hexDigit1 >= 0 && hexDigit2 >= 0) - { - utf8.set (i, (char) ((hexDigit1 << 4) + hexDigit2)); - utf8.removeRange (i + 1, 2); - } - } - } - - return String::fromUTF8 (utf8.getRawDataPointer(), utf8.size()); -} - -String URL::addEscapeChars (const String& s, const bool isParameter) -{ - const CharPointer_UTF8 legalChars (isParameter ? "_-.*!'()" - : ",$_-.*!'()"); - - Array utf8 (s.toRawUTF8(), (int) s.getNumBytesAsUTF8()); - - for (int i = 0; i < utf8.size(); ++i) - { - const char c = utf8.getUnchecked(i); - - if (! (CharacterFunctions::isLetterOrDigit (c) - || legalChars.indexOf ((juce_wchar) c) >= 0)) - { - utf8.set (i, '%'); - utf8.insert (++i, "0123456789abcdef" [((uint8) c) >> 4]); - utf8.insert (++i, "0123456789abcdef" [c & 15]); - } - } - - return String::fromUTF8 (utf8.getRawDataPointer(), utf8.size()); -} - -//============================================================================== -bool URL::launchInDefaultBrowser() const -{ - String u (toString (true)); - - if (u.containsChar ('@') && ! u.containsChar (':')) - u = "mailto:" + u; - - return Process::openDocument (u, String()); -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/network/juce_URL.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/network/juce_URL.h deleted file mode 100644 index 06d8fb732d..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/network/juce_URL.h +++ /dev/null @@ -1,378 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_URL_H_INCLUDED -#define JUCE_URL_H_INCLUDED - - -//============================================================================== -/** - Represents a URL and has a bunch of useful functions to manipulate it. - - This class can be used to launch URLs in browsers, and also to create - InputStreams that can read from remote http or ftp sources. -*/ -class JUCE_API URL -{ -public: - //============================================================================== - /** Creates an empty URL. */ - URL(); - - /** Creates a URL from a string. - This will parse any embedded parameters after a '?' character and store them - in the list (see getParameterNames etc). If you don't want this to happen, you - can use createWithoutParsing(). - */ - URL (const String& url); - - /** Creates a copy of another URL. */ - URL (const URL& other); - - /** Destructor. */ - ~URL(); - - /** Copies this URL from another one. */ - URL& operator= (const URL& other); - - /** Compares two URLs. - All aspects of the URLs must be identical for them to match, including any parameters, - upload files, etc. - */ - bool operator== (const URL&) const; - bool operator!= (const URL&) const; - - //============================================================================== - /** Returns a string version of the URL. - - If includeGetParameters is true and any parameters have been set with the - withParameter() method, then the string will have these appended on the - end and url-encoded. - */ - String toString (bool includeGetParameters) const; - - /** Returns true if the URL is an empty string. */ - bool isEmpty() const noexcept; - - /** True if it seems to be valid. */ - bool isWellFormed() const; - - /** Returns just the domain part of the URL. - - E.g. for "http://www.xyz.com/foobar", this will return "www.xyz.com". - */ - String getDomain() const; - - /** Returns the path part of the URL. - - E.g. for "http://www.xyz.com/foo/bar?x=1", this will return "foo/bar". - */ - String getSubPath() const; - - /** Returns the scheme of the URL. - - E.g. for "http://www.xyz.com/foobar", this will return "http". (It won't - include the colon). - */ - String getScheme() const; - - /** Attempts to read a port number from the URL. - @returns the port number, or 0 if none is explicitly specified. - */ - int getPort() const; - - /** Returns a new version of this URL that uses a different sub-path. - - E.g. if the URL is "http://www.xyz.com/foo?x=1" and you call this with - "bar", it'll return "http://www.xyz.com/bar?x=1". - */ - URL withNewSubPath (const String& newPath) const; - - /** Returns a new URL that refers to a sub-path relative to this one. - - E.g. if the URL is "http://www.xyz.com/foo" and you call this with - "bar", it'll return "http://www.xyz.com/foo/bar". Note that there's no way for - this method to know whether the original URL is a file or directory, so it's - up to you to make sure it's a directory. It also won't attempt to be smart about - the content of the childPath string, so if this string is an absolute URL, it'll - still just get bolted onto the end of the path. - - @see File::getChildFile - */ - URL getChildURL (const String& subPath) const; - - //============================================================================== - /** Returns a copy of this URL, with a GET or POST parameter added to the end. - - Any control characters in the value will be encoded. - - e.g. calling "withParameter ("amount", "some fish") for the url "www.fish.com" - would produce a new url whose toString(true) method would return - "www.fish.com?amount=some+fish". - - @see getParameterNames, getParameterValues - */ - URL withParameter (const String& parameterName, - const String& parameterValue) const; - - /** Returns a copy of this URL, with a file-upload type parameter added to it. - - When performing a POST where one of your parameters is a binary file, this - lets you specify the file. - - Note that the filename is stored, but the file itself won't actually be read - until this URL is later used to create a network input stream. If you want to - upload data from memory, use withDataToUpload(). - - @see withDataToUpload - */ - URL withFileToUpload (const String& parameterName, - const File& fileToUpload, - const String& mimeType) const; - - /** Returns a copy of this URL, with a file-upload type parameter added to it. - - When performing a POST where one of your parameters is a binary file, this - lets you specify the file content. - Note that the filename parameter should not be a full path, it's just the - last part of the filename. - - @see withFileToUpload - */ - URL withDataToUpload (const String& parameterName, - const String& filename, - const MemoryBlock& fileContentToUpload, - const String& mimeType) const; - - /** Returns an array of the names of all the URL's parameters. - - E.g. for the url "www.fish.com?type=haddock&amount=some+fish", this array would - contain two items: "type" and "amount". - - You can call getParameterValues() to get the corresponding value of each - parameter. Note that the list can contain multiple parameters with the same name. - - @see getParameterValues, withParameter - */ - const StringArray& getParameterNames() const noexcept { return parameterNames; } - - /** Returns an array of the values of all the URL's parameters. - - E.g. for the url "www.fish.com?type=haddock&amount=some+fish", this array would - contain two items: "haddock" and "some fish". - - The values returned will have been cleaned up to remove any escape characters. - - You can call getParameterNames() to get the corresponding name of each - parameter. Note that the list can contain multiple parameters with the same name. - - @see getParameterNames, withParameter - */ - const StringArray& getParameterValues() const noexcept { return parameterValues; } - - /** Returns a copy of this URL, with a block of data to send as the POST data. - - If you're setting the POST data, be careful not to have any parameters set - as well, otherwise it'll all get thrown in together, and might not have the - desired effect. - - If the URL already contains some POST data, this will replace it, rather - than being appended to it. - - This data will only be used if you specify a post operation when you call - createInputStream(). - */ - URL withPOSTData (const String& postData) const; - - /** Returns the data that was set using withPOSTData(). */ - const String& getPostData() const noexcept { return postData; } - - //============================================================================== - /** Tries to launch the system's default browser to open the URL. - - Returns true if this seems to have worked. - */ - bool launchInDefaultBrowser() const; - - //============================================================================== - /** Takes a guess as to whether a string might be a valid website address. - - This isn't foolproof! - */ - static bool isProbablyAWebsiteURL (const String& possibleURL); - - /** Takes a guess as to whether a string might be a valid email address. - - This isn't foolproof! - */ - static bool isProbablyAnEmailAddress (const String& possibleEmailAddress); - - //============================================================================== - /** This callback function can be used by the createInputStream() method. - - It allows your app to receive progress updates during a lengthy POST operation. If you - want to continue the operation, this should return true, or false to abort. - */ - typedef bool (OpenStreamProgressCallback) (void* context, int bytesSent, int totalBytes); - - /** Attempts to open a stream that can read from this URL. - - @param usePostCommand if true, it will try to do use a http 'POST' to pass - the parameters, otherwise it'll encode them into the - URL and do a 'GET'. - @param progressCallback if this is non-zero, it lets you supply a callback function - to keep track of the operation's progress. This can be useful - for lengthy POST operations, so that you can provide user feedback. - @param progressCallbackContext if a callback is specified, this value will be passed to - the function - @param extraHeaders 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. - @param connectionTimeOutMs if 0, this will use whatever default setting the OS chooses. If - a negative number, it will be infinite. Otherwise it specifies a - time in milliseconds. - @param responseHeaders if this is non-null, all the (key, value) pairs received as headers - in the response will be stored in this array - @param statusCode if this is non-null, it will get set to the http status code, if one - is known, or 0 if a code isn't available - @returns an input stream that the caller must delete, or a null pointer if there was an - error trying to open it. - */ - InputStream* createInputStream (bool usePostCommand, - OpenStreamProgressCallback* progressCallback = nullptr, - void* progressCallbackContext = nullptr, - String extraHeaders = String(), - int connectionTimeOutMs = 0, - StringPairArray* responseHeaders = nullptr, - int* statusCode = nullptr) const; - - - //============================================================================== - /** Tries to download the entire contents of this URL into a binary data block. - - If it succeeds, this will return true and append the data it read onto the end - of the memory block. - - @param destData the memory block to append the new data to - @param usePostCommand whether to use a POST command to get the data (uses - a GET command if this is false) - @see readEntireTextStream, readEntireXmlStream - */ - bool readEntireBinaryStream (MemoryBlock& destData, - bool usePostCommand = false) const; - - /** Tries to download the entire contents of this URL as a string. - - If it fails, this will return an empty string, otherwise it will return the - contents of the downloaded file. If you need to distinguish between a read - operation that fails and one that returns an empty string, you'll need to use - a different method, such as readEntireBinaryStream(). - - @param usePostCommand whether to use a POST command to get the data (uses - a GET command if this is false) - @see readEntireBinaryStream, readEntireXmlStream - */ - String readEntireTextStream (bool usePostCommand = false) const; - - /** Tries to download the entire contents of this URL and parse it as XML. - - If it fails, or if the text that it reads can't be parsed as XML, this will - return 0. - - When it returns a valid XmlElement object, the caller is responsibile for deleting - this object when no longer needed. - - @param usePostCommand whether to use a POST command to get the data (uses - a GET command if this is false) - - @see readEntireBinaryStream, readEntireTextStream - */ - XmlElement* readEntireXmlStream (bool usePostCommand = false) const; - - //============================================================================== - /** Adds escape sequences to a string to encode any characters that aren't - legal in a URL. - - E.g. any spaces will be replaced with "%20". - - This is the opposite of removeEscapeChars(). - - If isParameter is true, it means that the string is going to be used - as a parameter, so it also encodes '$' and ',' (which would otherwise - be legal in a URL. - - @see removeEscapeChars - */ - static String addEscapeChars (const String& stringToAddEscapeCharsTo, - bool isParameter); - - /** Replaces any escape character sequences in a string with their original - character codes. - - E.g. any instances of "%20" will be replaced by a space. - - This is the opposite of addEscapeChars(). - - @see addEscapeChars - */ - static String removeEscapeChars (const String& stringToRemoveEscapeCharsFrom); - - /** Returns a URL without attempting to remove any embedded parameters from the string. - This may be necessary if you need to create a request that involves both POST - parameters and parameters which are embedded in the URL address itself. - */ - static URL createWithoutParsing (const String& url); - -private: - //============================================================================== - String url, postData; - StringArray parameterNames, parameterValues; - - struct Upload : public ReferenceCountedObject - { - Upload (const String&, const String&, const String&, const File&, MemoryBlock*); - String parameterName, filename, mimeType; - File file; - ScopedPointer data; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Upload) - }; - - friend struct ContainerDeletePolicy; - ReferenceCountedArray filesToUpload; - - URL (const String&, int); - void addParameter (const String&, const String&); - void createHeadersAndPostData (String&, MemoryBlock&) const; - URL withUpload (Upload*) const; - - JUCE_LEAK_DETECTOR (URL) -}; - - -#endif // JUCE_URL_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/streams/juce_BufferedInputStream.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/streams/juce_BufferedInputStream.cpp deleted file mode 100644 index ec01f8e1bc..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/streams/juce_BufferedInputStream.cpp +++ /dev/null @@ -1,198 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -namespace -{ - int calcBufferStreamBufferSize (int requestedSize, InputStream* const source) noexcept - { - // You need to supply a real stream when creating a BufferedInputStream - jassert (source != nullptr); - - requestedSize = jmax (256, requestedSize); - - const int64 sourceSize = source->getTotalLength(); - if (sourceSize >= 0 && sourceSize < requestedSize) - requestedSize = jmax (32, (int) sourceSize); - - return requestedSize; - } -} - -//============================================================================== -BufferedInputStream::BufferedInputStream (InputStream* const sourceStream, const int bufferSize_, - const bool deleteSourceWhenDestroyed) - : source (sourceStream, deleteSourceWhenDestroyed), - bufferSize (calcBufferStreamBufferSize (bufferSize_, sourceStream)), - position (sourceStream->getPosition()), - lastReadPos (0), - bufferStart (position), - bufferOverlap (128) -{ - buffer.malloc ((size_t) bufferSize); -} - -BufferedInputStream::BufferedInputStream (InputStream& sourceStream, const int bufferSize_) - : source (&sourceStream, false), - bufferSize (calcBufferStreamBufferSize (bufferSize_, &sourceStream)), - position (sourceStream.getPosition()), - lastReadPos (0), - bufferStart (position), - bufferOverlap (128) -{ - buffer.malloc ((size_t) bufferSize); -} - -BufferedInputStream::~BufferedInputStream() -{ -} - -//============================================================================== -int64 BufferedInputStream::getTotalLength() -{ - return source->getTotalLength(); -} - -int64 BufferedInputStream::getPosition() -{ - return position; -} - -bool BufferedInputStream::setPosition (int64 newPosition) -{ - position = jmax ((int64) 0, newPosition); - return true; -} - -bool BufferedInputStream::isExhausted() -{ - return position >= lastReadPos && source->isExhausted(); -} - -void BufferedInputStream::ensureBuffered() -{ - const int64 bufferEndOverlap = lastReadPos - bufferOverlap; - - if (position < bufferStart || position >= bufferEndOverlap) - { - int bytesRead; - - if (position < lastReadPos - && position >= bufferEndOverlap - && position >= bufferStart) - { - const int bytesToKeep = (int) (lastReadPos - position); - memmove (buffer, buffer + (int) (position - bufferStart), (size_t) bytesToKeep); - - bufferStart = position; - - bytesRead = source->read (buffer + bytesToKeep, - (int) (bufferSize - bytesToKeep)); - - lastReadPos += bytesRead; - bytesRead += bytesToKeep; - } - else - { - bufferStart = position; - source->setPosition (bufferStart); - bytesRead = source->read (buffer, bufferSize); - lastReadPos = bufferStart + bytesRead; - } - - while (bytesRead < bufferSize) - buffer [bytesRead++] = 0; - } -} - -int BufferedInputStream::read (void* destBuffer, int maxBytesToRead) -{ - jassert (destBuffer != nullptr && maxBytesToRead >= 0); - - if (position >= bufferStart - && position + maxBytesToRead <= lastReadPos) - { - memcpy (destBuffer, buffer + (int) (position - bufferStart), (size_t) maxBytesToRead); - position += maxBytesToRead; - - return maxBytesToRead; - } - else - { - if (position < bufferStart || position >= lastReadPos) - ensureBuffered(); - - int bytesRead = 0; - - while (maxBytesToRead > 0) - { - const int bytesAvailable = jmin (maxBytesToRead, (int) (lastReadPos - position)); - - if (bytesAvailable > 0) - { - memcpy (destBuffer, buffer + (int) (position - bufferStart), (size_t) bytesAvailable); - maxBytesToRead -= bytesAvailable; - bytesRead += bytesAvailable; - position += bytesAvailable; - destBuffer = static_cast (destBuffer) + bytesAvailable; - } - - const int64 oldLastReadPos = lastReadPos; - ensureBuffered(); - - if (oldLastReadPos == lastReadPos) - break; // if ensureBuffered() failed to read any more data, bail out - - if (isExhausted()) - break; - } - - return bytesRead; - } -} - -String BufferedInputStream::readString() -{ - if (position >= bufferStart - && position < lastReadPos) - { - const int maxChars = (int) (lastReadPos - position); - - const char* const src = buffer + (int) (position - bufferStart); - - for (int i = 0; i < maxChars; ++i) - { - if (src[i] == 0) - { - position += i + 1; - return String::fromUTF8 (src, i); - } - } - } - - return InputStream::readString(); -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/streams/juce_BufferedInputStream.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/streams/juce_BufferedInputStream.h deleted file mode 100644 index 8f1e633bed..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/streams/juce_BufferedInputStream.h +++ /dev/null @@ -1,92 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_BUFFEREDINPUTSTREAM_H_INCLUDED -#define JUCE_BUFFEREDINPUTSTREAM_H_INCLUDED - - -//============================================================================== -/** Wraps another input stream, and reads from it using an intermediate buffer - - If you're using an input stream such as a file input stream, and making lots of - small read accesses to it, it's probably sensible to wrap it in one of these, - so that the source stream gets accessed in larger chunk sizes, meaning less - work for the underlying stream. -*/ -class JUCE_API BufferedInputStream : public InputStream -{ -public: - //============================================================================== - /** Creates a BufferedInputStream from an input source. - - @param sourceStream the source stream to read from - @param bufferSize the size of reservoir to use to buffer the source - @param deleteSourceWhenDestroyed whether the sourceStream that is passed in should be - deleted by this object when it is itself deleted. - */ - BufferedInputStream (InputStream* sourceStream, - int bufferSize, - bool deleteSourceWhenDestroyed); - - /** Creates a BufferedInputStream from an input source. - - @param sourceStream the source stream to read from - the source stream must not - be deleted until this object has been destroyed. - @param bufferSize the size of reservoir to use to buffer the source - */ - BufferedInputStream (InputStream& sourceStream, int bufferSize); - - /** Destructor. - - This may also delete the source stream, if that option was chosen when the - buffered stream was created. - */ - ~BufferedInputStream(); - - - //============================================================================== - int64 getTotalLength() override; - int64 getPosition() override; - bool setPosition (int64 newPosition) override; - int read (void* destBuffer, int maxBytesToRead) override; - String readString() override; - bool isExhausted() override; - - -private: - //============================================================================== - OptionalScopedPointer source; - int bufferSize; - int64 position, lastReadPos, bufferStart, bufferOverlap; - HeapBlock buffer; - void ensureBuffered(); - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (BufferedInputStream) -}; - -#endif // JUCE_BUFFEREDINPUTSTREAM_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/streams/juce_FileInputSource.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/streams/juce_FileInputSource.cpp deleted file mode 100644 index 51b9db9066..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/streams/juce_FileInputSource.cpp +++ /dev/null @@ -1,56 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -FileInputSource::FileInputSource (const File& f, bool useFileTimeInHash) - : file (f), useFileTimeInHashGeneration (useFileTimeInHash) -{ -} - -FileInputSource::~FileInputSource() -{ -} - -InputStream* FileInputSource::createInputStream() -{ - return file.createInputStream(); -} - -InputStream* FileInputSource::createInputStreamFor (const String& relatedItemPath) -{ - return file.getSiblingFile (relatedItemPath).createInputStream(); -} - -int64 FileInputSource::hashCode() const -{ - int64 h = file.hashCode(); - - if (useFileTimeInHashGeneration) - h ^= file.getLastModificationTime().toMilliseconds(); - - return h; -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/streams/juce_FileInputSource.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/streams/juce_FileInputSource.h deleted file mode 100644 index d2e6d862fe..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/streams/juce_FileInputSource.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_FILEINPUTSOURCE_H_INCLUDED -#define JUCE_FILEINPUTSOURCE_H_INCLUDED - - -//============================================================================== -/** - A type of InputSource that represents a normal file. - - @see InputSource -*/ -class JUCE_API FileInputSource : public InputSource -{ -public: - //============================================================================== - /** Creates a FileInputSource for a file. - If the useFileTimeInHashGeneration parameter is true, then this object's - hashCode() method will incorporate the file time into its hash code; if - false, only the file name will be used for the hash. - */ - FileInputSource (const File& file, bool useFileTimeInHashGeneration = false); - - /** Destructor. */ - ~FileInputSource(); - - InputStream* createInputStream(); - InputStream* createInputStreamFor (const String& relatedItemPath); - int64 hashCode() const; - -private: - //============================================================================== - const File file; - bool useFileTimeInHashGeneration; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (FileInputSource) -}; - - -#endif // JUCE_FILEINPUTSOURCE_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/streams/juce_InputSource.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/streams/juce_InputSource.h deleted file mode 100644 index 0e13ac520e..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/streams/juce_InputSource.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_INPUTSOURCE_H_INCLUDED -#define JUCE_INPUTSOURCE_H_INCLUDED - - -//============================================================================== -/** - A lightweight object that can create a stream to read some kind of resource. - - This may be used to refer to a file, or some other kind of source, allowing a - caller to create an input stream that can read from it when required. - - @see FileInputSource -*/ -class JUCE_API InputSource -{ -public: - //============================================================================== - InputSource() noexcept {} - - /** Destructor. */ - virtual ~InputSource() {} - - //============================================================================== - /** Returns a new InputStream to read this item. - - @returns an inputstream that the caller will delete, or nullptr if - the filename isn't found. - */ - virtual InputStream* createInputStream() = 0; - - /** Returns a new InputStream to read an item, relative. - - @param relatedItemPath the relative pathname of the resource that is required - @returns an inputstream that the caller will delete, or nullptr if - the item isn't found. - */ - virtual InputStream* createInputStreamFor (const String& relatedItemPath) = 0; - - /** Returns a hash code that uniquely represents this item. - */ - virtual int64 hashCode() const = 0; - - -private: - //============================================================================== - JUCE_LEAK_DETECTOR (InputSource) -}; - - -#endif // JUCE_INPUTSOURCE_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/streams/juce_InputStream.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/streams/juce_InputStream.cpp deleted file mode 100644 index 07b9976da3..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/streams/juce_InputStream.cpp +++ /dev/null @@ -1,236 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -int64 InputStream::getNumBytesRemaining() -{ - int64 len = getTotalLength(); - - if (len >= 0) - len -= getPosition(); - - return len; -} - -char InputStream::readByte() -{ - char temp = 0; - read (&temp, 1); - return temp; -} - -bool InputStream::readBool() -{ - return readByte() != 0; -} - -short InputStream::readShort() -{ - char temp[2]; - - if (read (temp, 2) == 2) - return (short) ByteOrder::littleEndianShort (temp); - - return 0; -} - -short InputStream::readShortBigEndian() -{ - char temp[2]; - - if (read (temp, 2) == 2) - return (short) ByteOrder::bigEndianShort (temp); - - return 0; -} - -int InputStream::readInt() -{ - char temp[4]; - - if (read (temp, 4) == 4) - return (int) ByteOrder::littleEndianInt (temp); - - return 0; -} - -int InputStream::readIntBigEndian() -{ - char temp[4]; - - if (read (temp, 4) == 4) - return (int) ByteOrder::bigEndianInt (temp); - - return 0; -} - -int InputStream::readCompressedInt() -{ - const uint8 sizeByte = (uint8) readByte(); - if (sizeByte == 0) - return 0; - - const int numBytes = (sizeByte & 0x7f); - if (numBytes > 4) - { - jassertfalse; // trying to read corrupt data - this method must only be used - // to read data that was written by OutputStream::writeCompressedInt() - return 0; - } - - char bytes[4] = { 0, 0, 0, 0 }; - if (read (bytes, numBytes) != numBytes) - return 0; - - const int num = (int) ByteOrder::littleEndianInt (bytes); - return (sizeByte >> 7) ? -num : num; -} - -int64 InputStream::readInt64() -{ - union { uint8 asBytes[8]; uint64 asInt64; } n; - - if (read (n.asBytes, 8) == 8) - return (int64) ByteOrder::swapIfBigEndian (n.asInt64); - - return 0; -} - -int64 InputStream::readInt64BigEndian() -{ - union { uint8 asBytes[8]; uint64 asInt64; } n; - - if (read (n.asBytes, 8) == 8) - return (int64) ByteOrder::swapIfLittleEndian (n.asInt64); - - return 0; -} - -float InputStream::readFloat() -{ - // the union below relies on these types being the same size... - static_jassert (sizeof (int32) == sizeof (float)); - union { int32 asInt; float asFloat; } n; - n.asInt = (int32) readInt(); - return n.asFloat; -} - -float InputStream::readFloatBigEndian() -{ - union { int32 asInt; float asFloat; } n; - n.asInt = (int32) readIntBigEndian(); - return n.asFloat; -} - -double InputStream::readDouble() -{ - union { int64 asInt; double asDouble; } n; - n.asInt = readInt64(); - return n.asDouble; -} - -double InputStream::readDoubleBigEndian() -{ - union { int64 asInt; double asDouble; } n; - n.asInt = readInt64BigEndian(); - return n.asDouble; -} - -String InputStream::readString() -{ - MemoryBlock buffer (256); - char* data = static_cast (buffer.getData()); - size_t i = 0; - - while ((data[i] = readByte()) != 0) - { - if (++i >= buffer.getSize()) - { - buffer.setSize (buffer.getSize() + 512); - data = static_cast (buffer.getData()); - } - } - - return String::fromUTF8 (data, (int) i); -} - -String InputStream::readNextLine() -{ - MemoryBlock buffer (256); - char* data = static_cast (buffer.getData()); - size_t i = 0; - - while ((data[i] = readByte()) != 0) - { - if (data[i] == '\n') - break; - - if (data[i] == '\r') - { - const int64 lastPos = getPosition(); - - if (readByte() != '\n') - setPosition (lastPos); - - break; - } - - if (++i >= buffer.getSize()) - { - buffer.setSize (buffer.getSize() + 512); - data = static_cast (buffer.getData()); - } - } - - return String::fromUTF8 (data, (int) i); -} - -size_t InputStream::readIntoMemoryBlock (MemoryBlock& block, ssize_t numBytes) -{ - MemoryOutputStream mo (block, true); - return (size_t) mo.writeFromInputStream (*this, numBytes); -} - -String InputStream::readEntireStreamAsString() -{ - MemoryOutputStream mo; - mo << *this; - return mo.toString(); -} - -//============================================================================== -void InputStream::skipNextBytes (int64 numBytesToSkip) -{ - if (numBytesToSkip > 0) - { - const int skipBufferSize = (int) jmin (numBytesToSkip, (int64) 16384); - HeapBlock temp ((size_t) skipBufferSize); - - while (numBytesToSkip > 0 && ! isExhausted()) - numBytesToSkip -= read (temp, (int) jmin (numBytesToSkip, (int64) skipBufferSize)); - } -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/streams/juce_InputStream.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/streams/juce_InputStream.h deleted file mode 100644 index ebdc795fab..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/streams/juce_InputStream.h +++ /dev/null @@ -1,266 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_INPUTSTREAM_H_INCLUDED -#define JUCE_INPUTSTREAM_H_INCLUDED - - -//============================================================================== -/** The base class for streams that read data. - - Input and output streams are used throughout the library - subclasses can override - some or all of the virtual functions to implement their behaviour. - - @see OutputStream, MemoryInputStream, BufferedInputStream, FileInputStream -*/ -class JUCE_API InputStream -{ -public: - /** Destructor. */ - virtual ~InputStream() {} - - //============================================================================== - /** Returns the total number of bytes available for reading in this stream. - - Note that this is the number of bytes available from the start of the - stream, not from the current position. - - If the size of the stream isn't actually known, this will return -1. - - @see getNumBytesRemaining - */ - virtual int64 getTotalLength() = 0; - - /** Returns the number of bytes available for reading, or a negative value if - the remaining length is not known. - @see getTotalLength - */ - int64 getNumBytesRemaining(); - - /** Returns true if the stream has no more data to read. */ - virtual bool isExhausted() = 0; - - //============================================================================== - /** Reads some data from the stream into a memory buffer. - - This is the only read method that subclasses actually need to implement, as the - InputStream base class implements the other read methods in terms of this one (although - it's often more efficient for subclasses to implement them directly). - - @param destBuffer the destination buffer for the data. This must not be null. - @param maxBytesToRead the maximum number of bytes to read - make sure the - memory block passed in is big enough to contain this - many bytes. This value must not be negative. - - @returns the actual number of bytes that were read, which may be less than - maxBytesToRead if the stream is exhausted before it gets that far - */ - virtual int read (void* destBuffer, int maxBytesToRead) = 0; - - /** Reads a byte from the stream. - If the stream is exhausted, this will return zero. - @see OutputStream::writeByte - */ - virtual char readByte(); - - /** Reads a boolean from the stream. - The bool is encoded as a single byte - non-zero for true, 0 for false. - If the stream is exhausted, this will return false. - @see OutputStream::writeBool - */ - virtual bool readBool(); - - /** Reads two bytes from the stream as a little-endian 16-bit value. - If the next two bytes read are byte1 and byte2, this returns (byte1 | (byte2 << 8)). - If the stream is exhausted partway through reading the bytes, this will return zero. - @see OutputStream::writeShort, readShortBigEndian - */ - virtual short readShort(); - - /** Reads two bytes from the stream as a little-endian 16-bit value. - If the next two bytes read are byte1 and byte2, this returns (byte2 | (byte1 << 8)). - If the stream is exhausted partway through reading the bytes, this will return zero. - @see OutputStream::writeShortBigEndian, readShort - */ - virtual short readShortBigEndian(); - - /** Reads four bytes from the stream as a little-endian 32-bit value. - - If the next four bytes are byte1 to byte4, this returns - (byte1 | (byte2 << 8) | (byte3 << 16) | (byte4 << 24)). - - If the stream is exhausted partway through reading the bytes, this will return zero. - - @see OutputStream::writeInt, readIntBigEndian - */ - virtual int readInt(); - - /** Reads four bytes from the stream as a big-endian 32-bit value. - - If the next four bytes are byte1 to byte4, this returns - (byte4 | (byte3 << 8) | (byte2 << 16) | (byte1 << 24)). - - If the stream is exhausted partway through reading the bytes, this will return zero. - - @see OutputStream::writeIntBigEndian, readInt - */ - virtual int readIntBigEndian(); - - /** Reads eight bytes from the stream as a little-endian 64-bit value. - - If the next eight bytes are byte1 to byte8, this returns - (byte1 | (byte2 << 8) | (byte3 << 16) | (byte4 << 24) | (byte5 << 32) | (byte6 << 40) | (byte7 << 48) | (byte8 << 56)). - - If the stream is exhausted partway through reading the bytes, this will return zero. - - @see OutputStream::writeInt64, readInt64BigEndian - */ - virtual int64 readInt64(); - - /** Reads eight bytes from the stream as a big-endian 64-bit value. - - If the next eight bytes are byte1 to byte8, this returns - (byte8 | (byte7 << 8) | (byte6 << 16) | (byte5 << 24) | (byte4 << 32) | (byte3 << 40) | (byte2 << 48) | (byte1 << 56)). - - If the stream is exhausted partway through reading the bytes, this will return zero. - - @see OutputStream::writeInt64BigEndian, readInt64 - */ - virtual int64 readInt64BigEndian(); - - /** Reads four bytes as a 32-bit floating point value. - The raw 32-bit encoding of the float is read from the stream as a little-endian int. - If the stream is exhausted partway through reading the bytes, this will return zero. - @see OutputStream::writeFloat, readDouble - */ - virtual float readFloat(); - - /** Reads four bytes as a 32-bit floating point value. - The raw 32-bit encoding of the float is read from the stream as a big-endian int. - If the stream is exhausted partway through reading the bytes, this will return zero. - @see OutputStream::writeFloatBigEndian, readDoubleBigEndian - */ - virtual float readFloatBigEndian(); - - /** Reads eight bytes as a 64-bit floating point value. - The raw 64-bit encoding of the double is read from the stream as a little-endian int64. - If the stream is exhausted partway through reading the bytes, this will return zero. - @see OutputStream::writeDouble, readFloat - */ - virtual double readDouble(); - - /** Reads eight bytes as a 64-bit floating point value. - The raw 64-bit encoding of the double is read from the stream as a big-endian int64. - If the stream is exhausted partway through reading the bytes, this will return zero. - @see OutputStream::writeDoubleBigEndian, readFloatBigEndian - */ - virtual double readDoubleBigEndian(); - - /** Reads an encoded 32-bit number from the stream using a space-saving compressed format. - For small values, this is more space-efficient than using readInt() and OutputStream::writeInt() - The format used is: number of significant bytes + up to 4 bytes in little-endian order. - @see OutputStream::writeCompressedInt() - */ - virtual int readCompressedInt(); - - //============================================================================== - /** Reads a UTF-8 string from the stream, up to the next linefeed or carriage return. - - This will read up to the next "\n" or "\r\n" or end-of-stream. - - After this call, the stream's position will be left pointing to the next character - following the line-feed, but the linefeeds aren't included in the string that - is returned. - */ - virtual String readNextLine(); - - /** Reads a zero-terminated UTF-8 string from the stream. - - This will read characters from the stream until it hits a null character - or end-of-stream. - - @see OutputStream::writeString, readEntireStreamAsString - */ - virtual String readString(); - - /** Tries to read the whole stream and turn it into a string. - - This will read from the stream's current position until the end-of-stream. - It can read from UTF-8 data, or UTF-16 if it detects suitable header-bytes. - */ - virtual String readEntireStreamAsString(); - - /** Reads from the stream and appends the data to a MemoryBlock. - - @param destBlock the block to append the data onto - @param maxNumBytesToRead if this is a positive value, it sets a limit to the number - of bytes that will be read - if it's negative, data - will be read until the stream is exhausted. - @returns the number of bytes that were added to the memory block - */ - virtual size_t readIntoMemoryBlock (MemoryBlock& destBlock, - ssize_t maxNumBytesToRead = -1); - - //============================================================================== - /** Returns the offset of the next byte that will be read from the stream. - @see setPosition - */ - virtual int64 getPosition() = 0; - - /** Tries to move the current read position of the stream. - - The position is an absolute number of bytes from the stream's start. - - Some streams might not be able to do this, in which case they should do - nothing and return false. Others might be able to manage it by resetting - themselves and skipping to the correct position, although this is - obviously a bit slow. - - @returns true if the stream manages to reposition itself correctly - @see getPosition - */ - virtual bool setPosition (int64 newPosition) = 0; - - /** Reads and discards a number of bytes from the stream. - - Some input streams might implement this efficiently, but the base - class will just keep reading data until the requisite number of bytes - have been done. - */ - virtual void skipNextBytes (int64 numBytesToSkip); - - -protected: - //============================================================================== - InputStream() noexcept {} - -private: - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (InputStream) -}; - -#endif // JUCE_INPUTSTREAM_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/streams/juce_MemoryInputStream.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/streams/juce_MemoryInputStream.cpp deleted file mode 100644 index 82b2d141e7..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/streams/juce_MemoryInputStream.cpp +++ /dev/null @@ -1,159 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -MemoryInputStream::MemoryInputStream (const void* const sourceData, - const size_t sourceDataSize, - const bool keepInternalCopy) - : data (sourceData), - dataSize (sourceDataSize), - position (0) -{ - if (keepInternalCopy) - createInternalCopy(); -} - -MemoryInputStream::MemoryInputStream (const MemoryBlock& sourceData, - const bool keepInternalCopy) - : data (sourceData.getData()), - dataSize (sourceData.getSize()), - position (0) -{ - if (keepInternalCopy) - createInternalCopy(); -} - -void MemoryInputStream::createInternalCopy() -{ - internalCopy.malloc (dataSize); - memcpy (internalCopy, data, dataSize); - data = internalCopy; -} - -MemoryInputStream::~MemoryInputStream() -{ -} - -int64 MemoryInputStream::getTotalLength() -{ - return (int64) dataSize; -} - -int MemoryInputStream::read (void* const buffer, const int howMany) -{ - jassert (buffer != nullptr && howMany >= 0); - - const int num = jmin (howMany, (int) (dataSize - position)); - if (num <= 0) - return 0; - - memcpy (buffer, addBytesToPointer (data, position), (size_t) num); - position += (unsigned int) num; - return num; -} - -bool MemoryInputStream::isExhausted() -{ - return position >= dataSize; -} - -bool MemoryInputStream::setPosition (const int64 pos) -{ - position = (size_t) jlimit ((int64) 0, (int64) dataSize, pos); - return true; -} - -int64 MemoryInputStream::getPosition() -{ - return (int64) position; -} - - -//============================================================================== -#if JUCE_UNIT_TESTS - -class MemoryStreamTests : public UnitTest -{ -public: - MemoryStreamTests() : UnitTest ("MemoryInputStream & MemoryOutputStream") {} - - void runTest() - { - beginTest ("Basics"); - Random r = getRandom(); - - int randomInt = r.nextInt(); - int64 randomInt64 = r.nextInt64(); - double randomDouble = r.nextDouble(); - String randomString (createRandomWideCharString (r)); - - MemoryOutputStream mo; - mo.writeInt (randomInt); - mo.writeIntBigEndian (randomInt); - mo.writeCompressedInt (randomInt); - mo.writeString (randomString); - mo.writeInt64 (randomInt64); - mo.writeInt64BigEndian (randomInt64); - mo.writeDouble (randomDouble); - mo.writeDoubleBigEndian (randomDouble); - - MemoryInputStream mi (mo.getData(), mo.getDataSize(), false); - expect (mi.readInt() == randomInt); - expect (mi.readIntBigEndian() == randomInt); - expect (mi.readCompressedInt() == randomInt); - expectEquals (mi.readString(), randomString); - expect (mi.readInt64() == randomInt64); - expect (mi.readInt64BigEndian() == randomInt64); - expect (mi.readDouble() == randomDouble); - expect (mi.readDoubleBigEndian() == randomDouble); - } - - static String createRandomWideCharString (Random& r) - { - juce_wchar buffer [50] = { 0 }; - - for (int i = 0; i < numElementsInArray (buffer) - 1; ++i) - { - if (r.nextBool()) - { - do - { - buffer[i] = (juce_wchar) (1 + r.nextInt (0x10ffff - 1)); - } - while (! CharPointer_UTF16::canRepresent (buffer[i])); - } - else - buffer[i] = (juce_wchar) (1 + r.nextInt (0xff)); - } - - return CharPointer_UTF32 (buffer); - } -}; - -static MemoryStreamTests memoryInputStreamUnitTests; - -#endif diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/streams/juce_MemoryInputStream.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/streams/juce_MemoryInputStream.h deleted file mode 100644 index 013bc39f66..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/streams/juce_MemoryInputStream.h +++ /dev/null @@ -1,97 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_MEMORYINPUTSTREAM_H_INCLUDED -#define JUCE_MEMORYINPUTSTREAM_H_INCLUDED - - -//============================================================================== -/** - Allows a block of data to be accessed as a stream. - - This can either be used to refer to a shared block of memory, or can make its - own internal copy of the data when the MemoryInputStream is created. -*/ -class JUCE_API MemoryInputStream : public InputStream -{ -public: - //============================================================================== - /** Creates a MemoryInputStream. - - @param sourceData the block of data to use as the stream's source - @param sourceDataSize the number of bytes in the source data block - @param keepInternalCopyOfData if false, the stream will just keep a pointer to - the source data, so this data shouldn't be changed - for the lifetime of the stream; if this parameter is - true, the stream will make its own copy of the - data and use that. - */ - MemoryInputStream (const void* sourceData, - size_t sourceDataSize, - bool keepInternalCopyOfData); - - /** Creates a MemoryInputStream. - - @param data a block of data to use as the stream's source - @param keepInternalCopyOfData if false, the stream will just keep a reference to - the source data, so this data shouldn't be changed - for the lifetime of the stream; if this parameter is - true, the stream will make its own copy of the - data and use that. - */ - MemoryInputStream (const MemoryBlock& data, - bool keepInternalCopyOfData); - - /** Destructor. */ - ~MemoryInputStream(); - - /** Returns a pointer to the source data block from which this stream is reading. */ - const void* getData() const noexcept { return data; } - - /** Returns the number of bytes of source data in the block from which this stream is reading. */ - size_t getDataSize() const noexcept { return dataSize; } - - //============================================================================== - int64 getPosition() override; - bool setPosition (int64 pos) override; - int64 getTotalLength() override; - bool isExhausted() override; - int read (void* destBuffer, int maxBytesToRead) override; - -private: - //============================================================================== - const void* data; - size_t dataSize, position; - HeapBlock internalCopy; - - void createInternalCopy(); - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MemoryInputStream) -}; - -#endif // JUCE_MEMORYINPUTSTREAM_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/streams/juce_MemoryOutputStream.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/streams/juce_MemoryOutputStream.cpp deleted file mode 100644 index adbaed2f2b..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/streams/juce_MemoryOutputStream.cpp +++ /dev/null @@ -1,214 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -MemoryOutputStream::MemoryOutputStream (const size_t initialSize) - : blockToUse (&internalBlock), externalData (nullptr), - position (0), size (0), availableSize (0) -{ - internalBlock.setSize (initialSize, false); -} - -MemoryOutputStream::MemoryOutputStream (MemoryBlock& memoryBlockToWriteTo, - const bool appendToExistingBlockContent) - : blockToUse (&memoryBlockToWriteTo), externalData (nullptr), - position (0), size (0), availableSize (0) -{ - if (appendToExistingBlockContent) - position = size = memoryBlockToWriteTo.getSize(); -} - -MemoryOutputStream::MemoryOutputStream (void* destBuffer, size_t destBufferSize) - : blockToUse (nullptr), externalData (destBuffer), - position (0), size (0), availableSize (destBufferSize) -{ - jassert (externalData != nullptr); // This must be a valid pointer. -} - -MemoryOutputStream::~MemoryOutputStream() -{ - trimExternalBlockSize(); -} - -void MemoryOutputStream::flush() -{ - trimExternalBlockSize(); -} - -void MemoryOutputStream::trimExternalBlockSize() -{ - if (blockToUse != &internalBlock && blockToUse != nullptr) - blockToUse->setSize (size, false); -} - -void MemoryOutputStream::preallocate (const size_t bytesToPreallocate) -{ - if (blockToUse != nullptr) - blockToUse->ensureSize (bytesToPreallocate + 1); -} - -void MemoryOutputStream::reset() noexcept -{ - position = 0; - size = 0; -} - -char* MemoryOutputStream::prepareToWrite (size_t numBytes) -{ - jassert ((ssize_t) numBytes >= 0); - size_t storageNeeded = position + numBytes; - - char* data; - - if (blockToUse != nullptr) - { - if (storageNeeded >= blockToUse->getSize()) - blockToUse->ensureSize ((storageNeeded + jmin (storageNeeded / 2, (size_t) (1024 * 1024)) + 32) & ~31u); - - data = static_cast (blockToUse->getData()); - } - else - { - if (storageNeeded > availableSize) - return nullptr; - - data = static_cast (externalData); - } - - char* const writePointer = data + position; - position += numBytes; - size = jmax (size, position); - return writePointer; -} - -bool MemoryOutputStream::write (const void* const buffer, size_t howMany) -{ - jassert (buffer != nullptr); - - if (howMany == 0) - return true; - - if (char* dest = prepareToWrite (howMany)) - { - memcpy (dest, buffer, howMany); - return true; - } - - return false; -} - -bool MemoryOutputStream::writeRepeatedByte (uint8 byte, size_t howMany) -{ - if (howMany == 0) - return true; - - if (char* dest = prepareToWrite (howMany)) - { - memset (dest, byte, howMany); - return true; - } - - return false; -} - -bool MemoryOutputStream::appendUTF8Char (juce_wchar c) -{ - if (char* dest = prepareToWrite (CharPointer_UTF8::getBytesRequiredFor (c))) - { - CharPointer_UTF8 (dest).write (c); - return true; - } - - return false; -} - -MemoryBlock MemoryOutputStream::getMemoryBlock() const -{ - return MemoryBlock (getData(), getDataSize()); -} - -const void* MemoryOutputStream::getData() const noexcept -{ - if (blockToUse == nullptr) - return externalData; - - if (blockToUse->getSize() > size) - static_cast (blockToUse->getData()) [size] = 0; - - return blockToUse->getData(); -} - -bool MemoryOutputStream::setPosition (int64 newPosition) -{ - if (newPosition <= (int64) size) - { - // ok to seek backwards - position = jlimit ((size_t) 0, size, (size_t) newPosition); - return true; - } - - // can't move beyond the end of the stream.. - return false; -} - -int64 MemoryOutputStream::writeFromInputStream (InputStream& source, int64 maxNumBytesToWrite) -{ - // before writing from an input, see if we can preallocate to make it more efficient.. - int64 availableData = source.getTotalLength() - source.getPosition(); - - if (availableData > 0) - { - if (maxNumBytesToWrite > availableData || maxNumBytesToWrite < 0) - maxNumBytesToWrite = availableData; - - if (blockToUse != nullptr) - preallocate (blockToUse->getSize() + (size_t) maxNumBytesToWrite); - } - - return OutputStream::writeFromInputStream (source, maxNumBytesToWrite); -} - -String MemoryOutputStream::toUTF8() const -{ - const char* const d = static_cast (getData()); - return String (CharPointer_UTF8 (d), CharPointer_UTF8 (d + getDataSize())); -} - -String MemoryOutputStream::toString() const -{ - return String::createStringFromData (getData(), (int) getDataSize()); -} - -OutputStream& JUCE_CALLTYPE operator<< (OutputStream& stream, const MemoryOutputStream& streamToRead) -{ - const size_t dataSize = streamToRead.getDataSize(); - - if (dataSize > 0) - stream.write (streamToRead.getData(), dataSize); - - return stream; -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/streams/juce_MemoryOutputStream.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/streams/juce_MemoryOutputStream.h deleted file mode 100644 index 2e764effe5..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/streams/juce_MemoryOutputStream.h +++ /dev/null @@ -1,139 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_MEMORYOUTPUTSTREAM_H_INCLUDED -#define JUCE_MEMORYOUTPUTSTREAM_H_INCLUDED - - -//============================================================================== -/** - Writes data to an internal memory buffer, which grows as required. - - The data that was written into the stream can then be accessed later as - a contiguous block of memory. -*/ -class JUCE_API MemoryOutputStream : public OutputStream -{ -public: - //============================================================================== - /** Creates an empty memory stream, ready to be written into. - @param initialSize the intial amount of capacity to allocate for writing into - */ - MemoryOutputStream (size_t initialSize = 256); - - /** Creates a memory stream for writing into into a pre-existing MemoryBlock object. - - Note that the destination block will always be larger than the amount of data - that has been written to the stream, because the MemoryOutputStream keeps some - spare capactity at its end. To trim the block's size down to fit the actual - data, call flush(), or delete the MemoryOutputStream. - - @param memoryBlockToWriteTo the block into which new data will be written. - @param appendToExistingBlockContent if this is true, the contents of the block will be - kept, and new data will be appended to it. If false, - the block will be cleared before use - */ - MemoryOutputStream (MemoryBlock& memoryBlockToWriteTo, - bool appendToExistingBlockContent); - - /** Creates a MemoryOutputStream that will write into a user-supplied, fixed-size - block of memory. - When using this mode, the stream will write directly into this memory area until - it's full, at which point write operations will fail. - */ - MemoryOutputStream (void* destBuffer, size_t destBufferSize); - - /** Destructor. - This will free any data that was written to it. - */ - ~MemoryOutputStream(); - - //============================================================================== - /** Returns a pointer to the data that has been written to the stream. - @see getDataSize - */ - const void* getData() const noexcept; - - /** Returns the number of bytes of data that have been written to the stream. - @see getData - */ - size_t getDataSize() const noexcept { return size; } - - /** Resets the stream, clearing any data that has been written to it so far. */ - void reset() noexcept; - - /** Increases the internal storage capacity to be able to contain at least the specified - amount of data without needing to be resized. - */ - void preallocate (size_t bytesToPreallocate); - - /** Appends the utf-8 bytes for a unicode character */ - bool appendUTF8Char (juce_wchar character); - - /** Returns a String created from the (UTF8) data that has been written to the stream. */ - String toUTF8() const; - - /** Attempts to detect the encoding of the data and convert it to a string. - @see String::createStringFromData - */ - String toString() const; - - /** Returns a copy of the stream's data as a memory block. */ - MemoryBlock getMemoryBlock() const; - - //============================================================================== - /** If the stream is writing to a user-supplied MemoryBlock, this will trim any excess - capacity off the block, so that its length matches the amount of actual data that - has been written so far. - */ - void flush(); - - bool write (const void*, size_t) override; - int64 getPosition() override { return (int64) position; } - bool setPosition (int64) override; - int64 writeFromInputStream (InputStream&, int64 maxNumBytesToWrite) override; - bool writeRepeatedByte (uint8 byte, size_t numTimesToRepeat) override; - -private: - //============================================================================== - MemoryBlock* const blockToUse; - MemoryBlock internalBlock; - void* externalData; - size_t position, size, availableSize; - - void trimExternalBlockSize(); - char* prepareToWrite (size_t); - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MemoryOutputStream) -}; - -/** Copies all the data that has been written to a MemoryOutputStream into another stream. */ -OutputStream& JUCE_CALLTYPE operator<< (OutputStream& stream, const MemoryOutputStream& streamToRead); - - -#endif // JUCE_MEMORYOUTPUTSTREAM_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/streams/juce_OutputStream.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/streams/juce_OutputStream.cpp deleted file mode 100644 index c67e3fb8c2..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/streams/juce_OutputStream.cpp +++ /dev/null @@ -1,351 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#if JUCE_DEBUG - -struct DanglingStreamChecker -{ - DanglingStreamChecker() {} - - ~DanglingStreamChecker() - { - /* - It's always a bad idea to leak any object, but if you're leaking output - streams, then there's a good chance that you're failing to flush a file - to disk properly, which could result in corrupted data and other similar - nastiness.. - */ - jassert (activeStreams.size() == 0); - } - - Array activeStreams; -}; - -static DanglingStreamChecker danglingStreamChecker; -#endif - -//============================================================================== -OutputStream::OutputStream() - : newLineString (NewLine::getDefault()) -{ - #if JUCE_DEBUG - danglingStreamChecker.activeStreams.add (this); - #endif -} - -OutputStream::~OutputStream() -{ - #if JUCE_DEBUG - danglingStreamChecker.activeStreams.removeFirstMatchingValue (this); - #endif -} - -//============================================================================== -bool OutputStream::writeBool (const bool b) -{ - return writeByte (b ? (char) 1 - : (char) 0); -} - -bool OutputStream::writeByte (char byte) -{ - return write (&byte, 1); -} - -bool OutputStream::writeRepeatedByte (uint8 byte, size_t numTimesToRepeat) -{ - for (size_t i = 0; i < numTimesToRepeat; ++i) - if (! writeByte ((char) byte)) - return false; - - return true; -} - -bool OutputStream::writeShort (short value) -{ - const unsigned short v = ByteOrder::swapIfBigEndian ((unsigned short) value); - return write (&v, 2); -} - -bool OutputStream::writeShortBigEndian (short value) -{ - const unsigned short v = ByteOrder::swapIfLittleEndian ((unsigned short) value); - return write (&v, 2); -} - -bool OutputStream::writeInt (int value) -{ - const unsigned int v = ByteOrder::swapIfBigEndian ((unsigned int) value); - return write (&v, 4); -} - -bool OutputStream::writeIntBigEndian (int value) -{ - const unsigned int v = ByteOrder::swapIfLittleEndian ((unsigned int) value); - return write (&v, 4); -} - -bool OutputStream::writeCompressedInt (int value) -{ - unsigned int un = (value < 0) ? (unsigned int) -value - : (unsigned int) value; - - uint8 data[5]; - int num = 0; - - while (un > 0) - { - data[++num] = (uint8) un; - un >>= 8; - } - - data[0] = (uint8) num; - - if (value < 0) - data[0] |= 0x80; - - return write (data, (size_t) num + 1); -} - -bool OutputStream::writeInt64 (int64 value) -{ - const uint64 v = ByteOrder::swapIfBigEndian ((uint64) value); - return write (&v, 8); -} - -bool OutputStream::writeInt64BigEndian (int64 value) -{ - const uint64 v = ByteOrder::swapIfLittleEndian ((uint64) value); - return write (&v, 8); -} - -bool OutputStream::writeFloat (float value) -{ - union { int asInt; float asFloat; } n; - n.asFloat = value; - return writeInt (n.asInt); -} - -bool OutputStream::writeFloatBigEndian (float value) -{ - union { int asInt; float asFloat; } n; - n.asFloat = value; - return writeIntBigEndian (n.asInt); -} - -bool OutputStream::writeDouble (double value) -{ - union { int64 asInt; double asDouble; } n; - n.asDouble = value; - return writeInt64 (n.asInt); -} - -bool OutputStream::writeDoubleBigEndian (double value) -{ - union { int64 asInt; double asDouble; } n; - n.asDouble = value; - return writeInt64BigEndian (n.asInt); -} - -bool OutputStream::writeString (const String& text) -{ - #if (JUCE_STRING_UTF_TYPE == 8) - return write (text.toRawUTF8(), text.getNumBytesAsUTF8() + 1); - #else - // (This avoids using toUTF8() to prevent the memory bloat that it would leave behind - // if lots of large, persistent strings were to be written to streams). - const size_t numBytes = text.getNumBytesAsUTF8() + 1; - HeapBlock temp (numBytes); - text.copyToUTF8 (temp, numBytes); - return write (temp, numBytes); - #endif -} - -bool OutputStream::writeText (const String& text, const bool asUTF16, - const bool writeUTF16ByteOrderMark) -{ - if (asUTF16) - { - if (writeUTF16ByteOrderMark) - write ("\x0ff\x0fe", 2); - - String::CharPointerType src (text.getCharPointer()); - bool lastCharWasReturn = false; - - for (;;) - { - const juce_wchar c = src.getAndAdvance(); - - if (c == 0) - break; - - if (c == '\n' && ! lastCharWasReturn) - writeShort ((short) '\r'); - - lastCharWasReturn = (c == L'\r'); - - if (! writeShort ((short) c)) - return false; - } - } - else - { - const char* src = text.toUTF8(); - const char* t = src; - - for (;;) - { - if (*t == '\n') - { - if (t > src) - if (! write (src, (size_t) (t - src))) - return false; - - if (! write ("\r\n", 2)) - return false; - - src = t + 1; - } - else if (*t == '\r') - { - if (t[1] == '\n') - ++t; - } - else if (*t == 0) - { - if (t > src) - if (! write (src, (size_t) (t - src))) - return false; - - break; - } - - ++t; - } - } - - return true; -} - -int64 OutputStream::writeFromInputStream (InputStream& source, int64 numBytesToWrite) -{ - if (numBytesToWrite < 0) - numBytesToWrite = std::numeric_limits::max(); - - int64 numWritten = 0; - - while (numBytesToWrite > 0) - { - char buffer [8192]; - const int num = source.read (buffer, (int) jmin (numBytesToWrite, (int64) sizeof (buffer))); - - if (num <= 0) - break; - - write (buffer, (size_t) num); - - numBytesToWrite -= num; - numWritten += num; - } - - return numWritten; -} - -//============================================================================== -void OutputStream::setNewLineString (const String& newLineString_) -{ - newLineString = newLineString_; -} - -//============================================================================== -template -static void writeIntToStream (OutputStream& stream, IntegerType number) -{ - char buffer [NumberToStringConverters::charsNeededForInt]; - char* end = buffer + numElementsInArray (buffer); - const char* start = NumberToStringConverters::numberToString (end, number); - stream.write (start, (size_t) (end - start - 1)); -} - -JUCE_API OutputStream& JUCE_CALLTYPE operator<< (OutputStream& stream, const int number) -{ - writeIntToStream (stream, number); - return stream; -} - -JUCE_API OutputStream& JUCE_CALLTYPE operator<< (OutputStream& stream, const int64 number) -{ - writeIntToStream (stream, number); - return stream; -} - -JUCE_API OutputStream& JUCE_CALLTYPE operator<< (OutputStream& stream, const double number) -{ - return stream << String (number); -} - -JUCE_API OutputStream& JUCE_CALLTYPE operator<< (OutputStream& stream, const char character) -{ - stream.writeByte (character); - return stream; -} - -JUCE_API OutputStream& JUCE_CALLTYPE operator<< (OutputStream& stream, const char* const text) -{ - stream.write (text, strlen (text)); - return stream; -} - -JUCE_API OutputStream& JUCE_CALLTYPE operator<< (OutputStream& stream, const MemoryBlock& data) -{ - if (data.getSize() > 0) - stream.write (data.getData(), data.getSize()); - - return stream; -} - -JUCE_API OutputStream& JUCE_CALLTYPE operator<< (OutputStream& stream, const File& fileToRead) -{ - FileInputStream in (fileToRead); - - if (in.openedOk()) - return stream << in; - - return stream; -} - -JUCE_API OutputStream& JUCE_CALLTYPE operator<< (OutputStream& stream, InputStream& streamToRead) -{ - stream.writeFromInputStream (streamToRead, -1); - return stream; -} - -JUCE_API OutputStream& JUCE_CALLTYPE operator<< (OutputStream& stream, const NewLine&) -{ - return stream << stream.getNewLineString(); -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/streams/juce_OutputStream.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/streams/juce_OutputStream.h deleted file mode 100644 index 102ab5a01e..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/streams/juce_OutputStream.h +++ /dev/null @@ -1,278 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_OUTPUTSTREAM_H_INCLUDED -#define JUCE_OUTPUTSTREAM_H_INCLUDED - - -//============================================================================== -/** - The base class for streams that write data to some kind of destination. - - Input and output streams are used throughout the library - subclasses can override - some or all of the virtual functions to implement their behaviour. - - @see InputStream, MemoryOutputStream, FileOutputStream -*/ -class JUCE_API OutputStream -{ -protected: - //============================================================================== - OutputStream(); - -public: - /** Destructor. - - Some subclasses might want to do things like call flush() during their - destructors. - */ - virtual ~OutputStream(); - - //============================================================================== - /** If the stream is using a buffer, this will ensure it gets written - out to the destination. */ - virtual void flush() = 0; - - /** Tries to move the stream's output position. - - Not all streams will be able to seek to a new position - this will return - false if it fails to work. - - @see getPosition - */ - virtual bool setPosition (int64 newPosition) = 0; - - /** Returns the stream's current position. - - @see setPosition - */ - virtual int64 getPosition() = 0; - - //============================================================================== - /** Writes a block of data to the stream. - - When creating a subclass of OutputStream, this is the only write method - that needs to be overloaded - the base class has methods for writing other - types of data which use this to do the work. - - @param dataToWrite the target buffer to receive the data. This must not be null. - @param numberOfBytes the number of bytes to write. - @returns false if the write operation fails for some reason - */ - virtual bool write (const void* dataToWrite, - size_t numberOfBytes) = 0; - - //============================================================================== - /** Writes a single byte to the stream. - @returns false if the write operation fails for some reason - @see InputStream::readByte - */ - virtual bool writeByte (char byte); - - /** Writes a boolean to the stream as a single byte. - This is encoded as a binary byte (not as text) with a value of 1 or 0. - @returns false if the write operation fails for some reason - @see InputStream::readBool - */ - virtual bool writeBool (bool boolValue); - - /** Writes a 16-bit integer to the stream in a little-endian byte order. - This will write two bytes to the stream: (value & 0xff), then (value >> 8). - @returns false if the write operation fails for some reason - @see InputStream::readShort - */ - virtual bool writeShort (short value); - - /** Writes a 16-bit integer to the stream in a big-endian byte order. - This will write two bytes to the stream: (value >> 8), then (value & 0xff). - @returns false if the write operation fails for some reason - @see InputStream::readShortBigEndian - */ - virtual bool writeShortBigEndian (short value); - - /** Writes a 32-bit integer to the stream in a little-endian byte order. - @returns false if the write operation fails for some reason - @see InputStream::readInt - */ - virtual bool writeInt (int value); - - /** Writes a 32-bit integer to the stream in a big-endian byte order. - @returns false if the write operation fails for some reason - @see InputStream::readIntBigEndian - */ - virtual bool writeIntBigEndian (int value); - - /** Writes a 64-bit integer to the stream in a little-endian byte order. - @returns false if the write operation fails for some reason - @see InputStream::readInt64 - */ - virtual bool writeInt64 (int64 value); - - /** Writes a 64-bit integer to the stream in a big-endian byte order. - @returns false if the write operation fails for some reason - @see InputStream::readInt64BigEndian - */ - virtual bool writeInt64BigEndian (int64 value); - - /** Writes a 32-bit floating point value to the stream in a binary format. - The binary 32-bit encoding of the float is written as a little-endian int. - @returns false if the write operation fails for some reason - @see InputStream::readFloat - */ - virtual bool writeFloat (float value); - - /** Writes a 32-bit floating point value to the stream in a binary format. - The binary 32-bit encoding of the float is written as a big-endian int. - @returns false if the write operation fails for some reason - @see InputStream::readFloatBigEndian - */ - virtual bool writeFloatBigEndian (float value); - - /** Writes a 64-bit floating point value to the stream in a binary format. - The eight raw bytes of the double value are written out as a little-endian 64-bit int. - @returns false if the write operation fails for some reason - @see InputStream::readDouble - */ - virtual bool writeDouble (double value); - - /** Writes a 64-bit floating point value to the stream in a binary format. - The eight raw bytes of the double value are written out as a big-endian 64-bit int. - @see InputStream::readDoubleBigEndian - @returns false if the write operation fails for some reason - */ - virtual bool writeDoubleBigEndian (double value); - - /** Writes a byte to the output stream a given number of times. - @returns false if the write operation fails for some reason - */ - virtual bool writeRepeatedByte (uint8 byte, size_t numTimesToRepeat); - - /** Writes a condensed binary encoding of a 32-bit integer. - - If you're storing a lot of integers which are unlikely to have very large values, - this can save a lot of space, because values under 0xff will only take up 2 bytes, - under 0xffff only 3 bytes, etc. - - The format used is: number of significant bytes + up to 4 bytes in little-endian order. - - @returns false if the write operation fails for some reason - @see InputStream::readCompressedInt - */ - virtual bool writeCompressedInt (int value); - - /** Stores a string in the stream in a binary format. - - This isn't the method to use if you're trying to append text to the end of a - text-file! It's intended for storing a string so that it can be retrieved later - by InputStream::readString(). - - It writes the string to the stream as UTF8, including the null termination character. - - For appending text to a file, instead use writeText, or operator<< - - @returns false if the write operation fails for some reason - @see InputStream::readString, writeText, operator<< - */ - virtual bool writeString (const String& text); - - /** Writes a string of text to the stream. - - It can either write the text as UTF-8 or UTF-16, and can also add the UTF-16 byte-order-mark - bytes (0xff, 0xfe) to indicate the endianness (these should only be used at the start - of a file). - - The method also replaces '\\n' characters in the text with '\\r\\n'. - @returns false if the write operation fails for some reason - */ - virtual bool writeText (const String& text, - bool asUTF16, - bool writeUTF16ByteOrderMark); - - /** Reads data from an input stream and writes it to this stream. - - @param source the stream to read from - @param maxNumBytesToWrite the number of bytes to read from the stream (if this is - less than zero, it will keep reading until the input - is exhausted) - @returns the number of bytes written - */ - virtual int64 writeFromInputStream (InputStream& source, int64 maxNumBytesToWrite); - - //============================================================================== - /** Sets the string that will be written to the stream when the writeNewLine() - method is called. - By default this will be set the value of NewLine::getDefault(). - */ - void setNewLineString (const String& newLineString); - - /** Returns the current new-line string that was set by setNewLineString(). */ - const String& getNewLineString() const noexcept { return newLineString; } - -private: - //============================================================================== - String newLineString; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (OutputStream) -}; - -//============================================================================== -/** Writes a number to a stream as 8-bit characters in the default system encoding. */ -JUCE_API OutputStream& JUCE_CALLTYPE operator<< (OutputStream& stream, int number); - -/** Writes a number to a stream as 8-bit characters in the default system encoding. */ -JUCE_API OutputStream& JUCE_CALLTYPE operator<< (OutputStream& stream, int64 number); - -/** Writes a number to a stream as 8-bit characters in the default system encoding. */ -JUCE_API OutputStream& JUCE_CALLTYPE operator<< (OutputStream& stream, double number); - -/** Writes a character to a stream. */ -JUCE_API OutputStream& JUCE_CALLTYPE operator<< (OutputStream& stream, char character); - -/** Writes a null-terminated text string to a stream. */ -JUCE_API OutputStream& JUCE_CALLTYPE operator<< (OutputStream& stream, const char* text); - -/** Writes a block of data from a MemoryBlock to a stream. */ -JUCE_API OutputStream& JUCE_CALLTYPE operator<< (OutputStream& stream, const MemoryBlock& data); - -/** Writes the contents of a file to a stream. */ -JUCE_API OutputStream& JUCE_CALLTYPE operator<< (OutputStream& stream, const File& fileToRead); - -/** Writes the complete contents of an input stream to an output stream. */ -JUCE_API OutputStream& JUCE_CALLTYPE operator<< (OutputStream& stream, InputStream& streamToRead); - -/** Writes a new-line to a stream. - You can use the predefined symbol 'newLine' to invoke this, e.g. - @code - myOutputStream << "Hello World" << newLine << newLine; - @endcode - @see OutputStream::setNewLineString -*/ -JUCE_API OutputStream& JUCE_CALLTYPE operator<< (OutputStream& stream, const NewLine&); - - -#endif // JUCE_OUTPUTSTREAM_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/streams/juce_SubregionStream.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/streams/juce_SubregionStream.cpp deleted file mode 100644 index c998c7984c..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/streams/juce_SubregionStream.cpp +++ /dev/null @@ -1,82 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -SubregionStream::SubregionStream (InputStream* const sourceStream, - const int64 start, const int64 length, - const bool deleteSourceWhenDestroyed) - : source (sourceStream, deleteSourceWhenDestroyed), - startPositionInSourceStream (start), - lengthOfSourceStream (length) -{ - SubregionStream::setPosition (0); -} - -SubregionStream::~SubregionStream() -{ -} - -int64 SubregionStream::getTotalLength() -{ - const int64 srcLen = source->getTotalLength() - startPositionInSourceStream; - - return lengthOfSourceStream >= 0 ? jmin (lengthOfSourceStream, srcLen) - : srcLen; -} - -int64 SubregionStream::getPosition() -{ - return source->getPosition() - startPositionInSourceStream; -} - -bool SubregionStream::setPosition (int64 newPosition) -{ - return source->setPosition (jmax ((int64) 0, newPosition + startPositionInSourceStream)); -} - -int SubregionStream::read (void* destBuffer, int maxBytesToRead) -{ - jassert (destBuffer != nullptr && maxBytesToRead >= 0); - - if (lengthOfSourceStream < 0) - return source->read (destBuffer, maxBytesToRead); - - maxBytesToRead = (int) jmin ((int64) maxBytesToRead, lengthOfSourceStream - getPosition()); - - if (maxBytesToRead <= 0) - return 0; - - return source->read (destBuffer, maxBytesToRead); -} - -bool SubregionStream::isExhausted() -{ - if (lengthOfSourceStream >= 0 && getPosition() >= lengthOfSourceStream) - return true; - - return source->isExhausted(); -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/streams/juce_SubregionStream.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/streams/juce_SubregionStream.h deleted file mode 100644 index d291a03c34..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/streams/juce_SubregionStream.h +++ /dev/null @@ -1,88 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_SUBREGIONSTREAM_H_INCLUDED -#define JUCE_SUBREGIONSTREAM_H_INCLUDED - - -//============================================================================== -/** Wraps another input stream, and reads from a specific part of it. - - This lets you take a subsection of a stream and present it as an entire - stream in its own right. -*/ -class JUCE_API SubregionStream : public InputStream -{ -public: - //============================================================================== - /** Creates a SubregionStream from an input source. - - @param sourceStream the source stream to read from - @param startPositionInSourceStream this is the position in the source stream that - corresponds to position 0 in this stream - @param lengthOfSourceStream this specifies the maximum number of bytes - from the source stream that will be passed through - by this stream. When the position of this stream - exceeds lengthOfSourceStream, it will cause an end-of-stream. - If the length passed in here is greater than the length - of the source stream (as returned by getTotalLength()), - then the smaller value will be used. - Passing a negative value for this parameter means it - will keep reading until the source's end-of-stream. - @param deleteSourceWhenDestroyed whether the sourceStream that is passed in should be - deleted by this object when it is itself deleted. - */ - SubregionStream (InputStream* sourceStream, - int64 startPositionInSourceStream, - int64 lengthOfSourceStream, - bool deleteSourceWhenDestroyed); - - /** Destructor. - - This may also delete the source stream, if that option was chosen when the - buffered stream was created. - */ - ~SubregionStream(); - - - //============================================================================== - int64 getTotalLength() override; - int64 getPosition() override; - bool setPosition (int64 newPosition) override; - int read (void* destBuffer, int maxBytesToRead) override; - bool isExhausted() override; - -private: - //============================================================================== - OptionalScopedPointer source; - const int64 startPositionInSourceStream, lengthOfSourceStream; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (SubregionStream) -}; - -#endif // JUCE_SUBREGIONSTREAM_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/system/juce_CompilerSupport.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/system/juce_CompilerSupport.h deleted file mode 100644 index d09095645e..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/system/juce_CompilerSupport.h +++ /dev/null @@ -1,147 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_COMPILERSUPPORT_H_INCLUDED -#define JUCE_COMPILERSUPPORT_H_INCLUDED - -/* This file has some checks to see whether the compiler supports various C++11/14 features, - When these aren't available, the code defines a few workarounds, so that we can still use - some of the newer language features like nullptr and noexcept, even on old compilers. -*/ - -//============================================================================== -// GCC -#if (__cplusplus >= 201103L || defined (__GXX_EXPERIMENTAL_CXX0X__)) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 405 - #define JUCE_COMPILER_SUPPORTS_NOEXCEPT 1 - #define JUCE_COMPILER_SUPPORTS_NULLPTR 1 - #define JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS 1 - - #if (__GNUC__ * 100 + __GNUC_MINOR__) >= 407 && ! defined (JUCE_COMPILER_SUPPORTS_OVERRIDE_AND_FINAL) - #define JUCE_COMPILER_SUPPORTS_OVERRIDE_AND_FINAL 1 - #endif - - #if (__GNUC__ * 100 + __GNUC_MINOR__) >= 407 && ! defined (JUCE_DELETED_FUNCTION) - #define JUCE_DELETED_FUNCTION = delete - #endif - - #if (__GNUC__ * 100 + __GNUC_MINOR__) >= 406 && ! defined (JUCE_COMPILER_SUPPORTS_LAMBDAS) - #define JUCE_COMPILER_SUPPORTS_LAMBDAS 1 - #endif -#endif - -//============================================================================== -// Clang -#if JUCE_CLANG && defined (__has_feature) - #if __has_feature (cxx_nullptr) - #define JUCE_COMPILER_SUPPORTS_NULLPTR 1 - #endif - - #if __has_feature (cxx_noexcept) - #define JUCE_COMPILER_SUPPORTS_NOEXCEPT 1 - #endif - - #if __has_feature (cxx_rvalue_references) - #define JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS 1 - #endif - - #if __has_feature (cxx_deleted_functions) - #define JUCE_DELETED_FUNCTION = delete - #endif - - #if __has_feature (cxx_lambdas) \ - && ((JUCE_MAC && defined (MAC_OS_X_VERSION_10_8) && MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_8) \ - || (JUCE_IOS && defined (__IPHONE_7_0) && __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_7_0) \ - || ! (JUCE_MAC || JUCE_IOS)) - #define JUCE_COMPILER_SUPPORTS_LAMBDAS 1 - #endif - - #ifndef JUCE_COMPILER_SUPPORTS_OVERRIDE_AND_FINAL - #define JUCE_COMPILER_SUPPORTS_OVERRIDE_AND_FINAL 1 - #endif - - #ifndef JUCE_COMPILER_SUPPORTS_ARC - #define JUCE_COMPILER_SUPPORTS_ARC 1 - #endif -#endif - -//============================================================================== -// MSVC -#ifdef _MSC_VER - #if _MSC_VER >= 1600 - #define JUCE_COMPILER_SUPPORTS_NULLPTR 1 - #define JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS 1 - #endif - - #if _MSC_VER >= 1700 - #define JUCE_COMPILER_SUPPORTS_OVERRIDE_AND_FINAL 1 - #define JUCE_COMPILER_SUPPORTS_LAMBDAS 1 - #endif - - #if _MSC_VER >= 1900 - #define JUCE_COMPILER_SUPPORTS_NOEXCEPT 1 - #define JUCE_DELETED_FUNCTION = delete - #endif -#endif - -//============================================================================== -// Declare some fake versions of nullptr and noexcept, for older compilers: - -#ifndef JUCE_DELETED_FUNCTION - /** This macro can be placed after a method declaration to allow the use of - the C++11 feature "= delete" on all compilers. - On newer compilers that support it, it does the C++11 "= delete", but on - older ones it's just an empty definition. - */ - #define JUCE_DELETED_FUNCTION -#endif - -#if ! DOXYGEN - #if ! JUCE_COMPILER_SUPPORTS_NOEXCEPT - #ifdef noexcept - #undef noexcept - #endif - #define noexcept throw() - #if defined (_MSC_VER) && _MSC_VER > 1600 - #define _ALLOW_KEYWORD_MACROS 1 // (to stop VC2012 complaining) - #endif - #endif - - #if ! JUCE_COMPILER_SUPPORTS_NULLPTR - #ifdef nullptr - #undef nullptr - #endif - #define nullptr (0) - #endif - - #if ! JUCE_COMPILER_SUPPORTS_OVERRIDE_AND_FINAL - #undef override - #define override - #endif -#endif - -#endif // JUCE_COMPILERSUPPORT_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/system/juce_PlatformDefs.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/system/juce_PlatformDefs.h deleted file mode 100644 index 3252fdbba6..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/system/juce_PlatformDefs.h +++ /dev/null @@ -1,339 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_PLATFORMDEFS_H_INCLUDED -#define JUCE_PLATFORMDEFS_H_INCLUDED - -//============================================================================== -/* This file defines miscellaneous macros for debugging, assertions, etc. -*/ - -//============================================================================== -#ifdef JUCE_FORCE_DEBUG - #undef JUCE_DEBUG - - #if JUCE_FORCE_DEBUG - #define JUCE_DEBUG 1 - #endif -#endif - -/** This macro defines the C calling convention used as the standard for Juce calls. */ -#if JUCE_MSVC - #define JUCE_CALLTYPE __stdcall - #define JUCE_CDECL __cdecl -#else - #define JUCE_CALLTYPE - #define JUCE_CDECL -#endif - -//============================================================================== -// Debugging and assertion macros - -#if JUCE_LOG_ASSERTIONS || JUCE_DEBUG - #define juce_LogCurrentAssertion juce::logAssertion (__FILE__, __LINE__); -#else - #define juce_LogCurrentAssertion -#endif - -//============================================================================== -#if JUCE_IOS || JUCE_LINUX || JUCE_ANDROID || JUCE_PPC - /** This will try to break into the debugger if the app is currently being debugged. - If called by an app that's not being debugged, the behaiour isn't defined - it may crash or not, depending - on the platform. - @see jassert() - */ - #define juce_breakDebugger { ::kill (0, SIGTRAP); } -#elif JUCE_USE_MSVC_INTRINSICS - #ifndef __INTEL_COMPILER - #pragma intrinsic (__debugbreak) - #endif - #define juce_breakDebugger { __debugbreak(); } -#elif JUCE_GCC || JUCE_MAC - #if JUCE_NO_INLINE_ASM - #define juce_breakDebugger { } - #else - #define juce_breakDebugger { asm ("int $3"); } - #endif -#else - #define juce_breakDebugger { __asm int 3 } -#endif - -#if JUCE_CLANG && defined (__has_feature) && ! defined (JUCE_ANALYZER_NORETURN) - #if __has_feature (attribute_analyzer_noreturn) - inline void __attribute__((analyzer_noreturn)) juce_assert_noreturn() {} - #define JUCE_ANALYZER_NORETURN juce_assert_noreturn(); - #endif -#endif - -#ifndef JUCE_ANALYZER_NORETURN - #define JUCE_ANALYZER_NORETURN -#endif - -//============================================================================== -#if JUCE_MSVC && ! DOXYGEN - #define MACRO_WITH_FORCED_SEMICOLON(x) \ - __pragma(warning(push)) \ - __pragma(warning(disable:4127)) \ - do { x } while (false) \ - __pragma(warning(pop)) -#else - /** This is the good old C++ trick for creating a macro that forces the user to put - a semicolon after it when they use it. - */ - #define MACRO_WITH_FORCED_SEMICOLON(x) do { x } while (false) -#endif - -//============================================================================== -#if JUCE_DEBUG || DOXYGEN - /** Writes a string to the standard error stream. - This is only compiled in a debug build. - @see Logger::outputDebugString - */ - #define DBG(dbgtext) MACRO_WITH_FORCED_SEMICOLON (juce::String tempDbgBuf; tempDbgBuf << dbgtext; juce::Logger::outputDebugString (tempDbgBuf);) - - //============================================================================== - /** This will always cause an assertion failure. - It is only compiled in a debug build, (unless JUCE_LOG_ASSERTIONS is enabled for your build). - @see jassert - */ - #define jassertfalse MACRO_WITH_FORCED_SEMICOLON (juce_LogCurrentAssertion; if (juce::juce_isRunningUnderDebugger()) juce_breakDebugger; JUCE_ANALYZER_NORETURN) - - //============================================================================== - /** Platform-independent assertion macro. - - This macro gets turned into a no-op when you're building with debugging turned off, so be - careful that the expression you pass to it doesn't perform any actions that are vital for the - correct behaviour of your program! - @see jassertfalse - */ - #define jassert(expression) MACRO_WITH_FORCED_SEMICOLON (if (! (expression)) jassertfalse;) - -#else - //============================================================================== - // If debugging is disabled, these dummy debug and assertion macros are used.. - - #define DBG(dbgtext) - #define jassertfalse MACRO_WITH_FORCED_SEMICOLON (juce_LogCurrentAssertion) - - #if JUCE_LOG_ASSERTIONS - #define jassert(expression) MACRO_WITH_FORCED_SEMICOLON (if (! (expression)) jassertfalse;) - #else - #define jassert(a) MACRO_WITH_FORCED_SEMICOLON ( ; ) - #endif - -#endif - -//============================================================================== -#ifndef DOXYGEN -namespace juce -{ - template struct JuceStaticAssert; - template <> struct JuceStaticAssert { static void dummy() {} }; -} -#endif - -/** A compile-time assertion macro. - If the expression parameter is false, the macro will cause a compile error. (The actual error - message that the compiler generates may be completely bizarre and seem to have no relation to - the place where you put the static_assert though!) -*/ -#define static_jassert(expression) juce::JuceStaticAssert::dummy(); - -/** This is a shorthand macro for declaring stubs for a class's copy constructor and operator=. - - For example, instead of - @code - class MyClass - { - etc.. - - private: - MyClass (const MyClass&); - MyClass& operator= (const MyClass&); - };@endcode - - ..you can just write: - - @code - class MyClass - { - etc.. - - private: - JUCE_DECLARE_NON_COPYABLE (MyClass) - };@endcode -*/ -#define JUCE_DECLARE_NON_COPYABLE(className) \ - className (const className&) JUCE_DELETED_FUNCTION;\ - className& operator= (const className&) JUCE_DELETED_FUNCTION; - -/** This is a shorthand way of writing both a JUCE_DECLARE_NON_COPYABLE and - JUCE_LEAK_DETECTOR macro for a class. -*/ -#define JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(className) \ - JUCE_DECLARE_NON_COPYABLE(className) \ - JUCE_LEAK_DETECTOR(className) - -/** This macro can be added to class definitions to disable the use of new/delete to - allocate the object on the heap, forcing it to only be used as a stack or member variable. -*/ -#define JUCE_PREVENT_HEAP_ALLOCATION \ - private: \ - static void* operator new (size_t) JUCE_DELETED_FUNCTION; \ - static void operator delete (void*) JUCE_DELETED_FUNCTION; - - -//============================================================================== -#if ! DOXYGEN - #define JUCE_JOIN_MACRO_HELPER(a, b) a ## b - #define JUCE_STRINGIFY_MACRO_HELPER(a) #a -#endif - -/** A good old-fashioned C macro concatenation helper. - This combines two items (which may themselves be macros) into a single string, - avoiding the pitfalls of the ## macro operator. -*/ -#define JUCE_JOIN_MACRO(item1, item2) JUCE_JOIN_MACRO_HELPER (item1, item2) - -/** A handy C macro for stringifying any symbol, rather than just a macro parameter. -*/ -#define JUCE_STRINGIFY(item) JUCE_STRINGIFY_MACRO_HELPER (item) - - -//============================================================================== -#if JUCE_MSVC && ! defined (DOXYGEN) - #define JUCE_WARNING_HELPER(file, line, mess) message(file "(" JUCE_STRINGIFY (line) ") : Warning: " #mess) - #define JUCE_COMPILER_WARNING(message) __pragma(JUCE_WARNING_HELPER (__FILE__, __LINE__, message)); -#else - #ifndef DOXYGEN - #define JUCE_WARNING_HELPER(mess) message(#mess) - #endif - - /** This macro allows you to emit a custom compiler warning message. - Very handy for marking bits of code as "to-do" items, or for shaming - code written by your co-workers in a way that's hard to ignore. - - GCC and Clang provide the \#warning directive, but MSVC doesn't, so this macro - is a cross-compiler way to get the same functionality as \#warning. - */ - #define JUCE_COMPILER_WARNING(message) _Pragma(JUCE_STRINGIFY (JUCE_WARNING_HELPER (message))); -#endif - - -//============================================================================== -#if JUCE_CATCH_UNHANDLED_EXCEPTIONS - - #define JUCE_TRY try - - #define JUCE_CATCH_ALL catch (...) {} - #define JUCE_CATCH_ALL_ASSERT catch (...) { jassertfalse; } - - #if ! JUCE_MODULE_AVAILABLE_juce_gui_basics - #define JUCE_CATCH_EXCEPTION JUCE_CATCH_ALL - #else - /** Used in try-catch blocks, this macro will send exceptions to the JUCEApplicationBase - object so they can be logged by the application if it wants to. - */ - #define JUCE_CATCH_EXCEPTION \ - catch (const std::exception& e) \ - { \ - juce::JUCEApplicationBase::sendUnhandledException (&e, __FILE__, __LINE__); \ - } \ - catch (...) \ - { \ - juce::JUCEApplicationBase::sendUnhandledException (nullptr, __FILE__, __LINE__); \ - } - #endif - -#else - - #define JUCE_TRY - #define JUCE_CATCH_EXCEPTION - #define JUCE_CATCH_ALL - #define JUCE_CATCH_ALL_ASSERT - -#endif - -//============================================================================== -#if JUCE_DEBUG || DOXYGEN - /** A platform-independent way of forcing an inline function. - Use the syntax: @code - forcedinline void myfunction (int x) - @endcode - */ - #define forcedinline inline -#else - #if JUCE_MSVC - #define forcedinline __forceinline - #else - #define forcedinline inline __attribute__((always_inline)) - #endif -#endif - -#if JUCE_MSVC || DOXYGEN - /** This can be placed before a stack or member variable declaration to tell the compiler - to align it to the specified number of bytes. */ - #define JUCE_ALIGN(bytes) __declspec (align (bytes)) -#else - #define JUCE_ALIGN(bytes) __attribute__ ((aligned (bytes))) -#endif - -//============================================================================== -// Cross-compiler deprecation macros.. -#ifdef DOXYGEN - /** This macro can be used to wrap a function which has been deprecated. */ - #define JUCE_DEPRECATED(functionDef) - #define JUCE_DEPRECATED_WITH_BODY(functionDef, body) -#elif JUCE_MSVC && ! JUCE_NO_DEPRECATION_WARNINGS - #define JUCE_DEPRECATED(functionDef) __declspec(deprecated) functionDef - #define JUCE_DEPRECATED_WITH_BODY(functionDef, body) __declspec(deprecated) functionDef body -#elif JUCE_GCC && ! JUCE_NO_DEPRECATION_WARNINGS - #define JUCE_DEPRECATED(functionDef) functionDef __attribute__ ((deprecated)) - #define JUCE_DEPRECATED_WITH_BODY(functionDef, body) functionDef __attribute__ ((deprecated)) body -#else - #define JUCE_DEPRECATED(functionDef) functionDef - #define JUCE_DEPRECATED_WITH_BODY(functionDef, body) functionDef body -#endif - -//============================================================================== -#if JUCE_ANDROID && ! DOXYGEN - #define JUCE_MODAL_LOOPS_PERMITTED 0 -#elif ! defined (JUCE_MODAL_LOOPS_PERMITTED) - /** Some operating environments don't provide a modal loop mechanism, so this flag can be - used to disable any functions that try to run a modal loop. */ - #define JUCE_MODAL_LOOPS_PERMITTED 1 -#endif - -//============================================================================== -#if JUCE_GCC - #define JUCE_PACKED __attribute__((packed)) -#elif ! DOXYGEN - #define JUCE_PACKED -#endif - -#endif // JUCE_PLATFORMDEFS_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/system/juce_StandardHeader.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/system/juce_StandardHeader.h deleted file mode 100644 index 35d9b87fb5..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/system/juce_StandardHeader.h +++ /dev/null @@ -1,159 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_STANDARDHEADER_H_INCLUDED -#define JUCE_STANDARDHEADER_H_INCLUDED - -//============================================================================== -/** Current JUCE version number. - - See also SystemStats::getJUCEVersion() for a string version. -*/ -#define JUCE_MAJOR_VERSION 3 -#define JUCE_MINOR_VERSION 0 -#define JUCE_BUILDNUMBER 8 - -/** Current Juce version number. - - Bits 16 to 32 = major version. - Bits 8 to 16 = minor version. - Bits 0 to 8 = point release. - - See also SystemStats::getJUCEVersion() for a string version. -*/ -#define JUCE_VERSION ((JUCE_MAJOR_VERSION << 16) + (JUCE_MINOR_VERSION << 8) + JUCE_BUILDNUMBER) - - -//============================================================================== -#include "juce_PlatformDefs.h" -#include "juce_CompilerSupport.h" - -//============================================================================== -// Now we'll include some common OS headers.. -#if JUCE_MSVC - #pragma warning (push) - #pragma warning (disable: 4514 4245 4100) -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if JUCE_USE_MSVC_INTRINSICS - #include -#endif - -#if JUCE_MAC || JUCE_IOS - #include -#endif - -#if JUCE_LINUX - #include - - #if __INTEL_COMPILER - #if __ia64__ - #include - #else - #include - #endif - #endif -#endif - -#if JUCE_MSVC && JUCE_DEBUG - #include -#endif - -#if JUCE_MSVC - #pragma warning (pop) -#endif - -#if JUCE_ANDROID - #include - #include -#endif - -// undef symbols that are sometimes set by misguided 3rd-party headers.. -#undef check -#undef TYPE_BOOL -#undef max -#undef min - -//============================================================================== -// DLL building settings on Windows -#if JUCE_MSVC - #ifdef JUCE_DLL_BUILD - #define JUCE_API __declspec (dllexport) - #pragma warning (disable: 4251) - #elif defined (JUCE_DLL) - #define JUCE_API __declspec (dllimport) - #pragma warning (disable: 4251) - #endif - #ifdef __INTEL_COMPILER - #pragma warning (disable: 1125) // (virtual override warning) - #endif -#elif defined (JUCE_DLL) || defined (JUCE_DLL_BUILD) - #define JUCE_API __attribute__ ((visibility("default"))) -#endif - -//============================================================================== -#ifndef JUCE_API - #define JUCE_API /**< This macro is added to all juce public class declarations. */ -#endif - -#if JUCE_MSVC && JUCE_DLL_BUILD - #define JUCE_PUBLIC_IN_DLL_BUILD(declaration) public: declaration; private: -#else - #define JUCE_PUBLIC_IN_DLL_BUILD(declaration) declaration; -#endif - -/** This macro is added to all juce public function declarations. */ -#define JUCE_PUBLIC_FUNCTION JUCE_API JUCE_CALLTYPE - -#if (! defined (JUCE_CATCH_DEPRECATED_CODE_MISUSE)) && JUCE_DEBUG && ! DOXYGEN - /** This turns on some non-essential bits of code that should prevent old code from compiling - in cases where method signatures have changed, etc. - */ - #define JUCE_CATCH_DEPRECATED_CODE_MISUSE 1 -#endif - -#ifndef DOXYGEN - #define JUCE_NAMESPACE juce // This old macro is deprecated: you should just use the juce namespace directly. -#endif - -#endif // JUCE_STANDARDHEADER_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/system/juce_SystemStats.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/system/juce_SystemStats.cpp deleted file mode 100644 index 365e94d9fe..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/system/juce_SystemStats.cpp +++ /dev/null @@ -1,183 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -String SystemStats::getJUCEVersion() -{ - // Some basic tests, to keep an eye on things and make sure these types work ok - // on all platforms. Let me know if any of these assertions fail on your system! - static_jassert (sizeof (pointer_sized_int) == sizeof (void*)); - static_jassert (sizeof (int8) == 1); - static_jassert (sizeof (uint8) == 1); - static_jassert (sizeof (int16) == 2); - static_jassert (sizeof (uint16) == 2); - static_jassert (sizeof (int32) == 4); - static_jassert (sizeof (uint32) == 4); - static_jassert (sizeof (int64) == 8); - static_jassert (sizeof (uint64) == 8); - - return "JUCE v" JUCE_STRINGIFY(JUCE_MAJOR_VERSION) - "." JUCE_STRINGIFY(JUCE_MINOR_VERSION) - "." JUCE_STRINGIFY(JUCE_BUILDNUMBER); -} - -#if JUCE_ANDROID && ! defined (JUCE_DISABLE_JUCE_VERSION_PRINTING) - #define JUCE_DISABLE_JUCE_VERSION_PRINTING 1 -#endif - -#if JUCE_DEBUG && ! JUCE_DISABLE_JUCE_VERSION_PRINTING - struct JuceVersionPrinter - { - JuceVersionPrinter() - { - DBG (SystemStats::getJUCEVersion()); - } - }; - - static JuceVersionPrinter juceVersionPrinter; -#endif - - -//============================================================================== -struct CPUInformation -{ - CPUInformation() noexcept - : numCpus (0), hasMMX (false), hasSSE (false), - hasSSE2 (false), hasSSE3 (false), has3DNow (false) - { - initialise(); - } - - void initialise() noexcept; - - int numCpus; - bool hasMMX, hasSSE, hasSSE2, hasSSE3, has3DNow; -}; - -static const CPUInformation& getCPUInformation() noexcept -{ - static CPUInformation info; - return info; -} - -int SystemStats::getNumCpus() noexcept { return getCPUInformation().numCpus; } -bool SystemStats::hasMMX() noexcept { return getCPUInformation().hasMMX; } -bool SystemStats::hasSSE() noexcept { return getCPUInformation().hasSSE; } -bool SystemStats::hasSSE2() noexcept { return getCPUInformation().hasSSE2; } -bool SystemStats::hasSSE3() noexcept { return getCPUInformation().hasSSE3; } -bool SystemStats::has3DNow() noexcept { return getCPUInformation().has3DNow; } - - -//============================================================================== -String SystemStats::getStackBacktrace() -{ - String result; - - #if JUCE_ANDROID || JUCE_MINGW - jassertfalse; // sorry, not implemented yet! - - #elif JUCE_WINDOWS - HANDLE process = GetCurrentProcess(); - SymInitialize (process, nullptr, TRUE); - - void* stack[128]; - int frames = (int) CaptureStackBackTrace (0, numElementsInArray (stack), stack, nullptr); - - HeapBlock symbol; - symbol.calloc (sizeof (SYMBOL_INFO) + 256, 1); - symbol->MaxNameLen = 255; - symbol->SizeOfStruct = sizeof (SYMBOL_INFO); - - for (int i = 0; i < frames; ++i) - { - DWORD64 displacement = 0; - - if (SymFromAddr (process, (DWORD64) stack[i], &displacement, symbol)) - { - result << i << ": "; - - IMAGEHLP_MODULE64 moduleInfo; - zerostruct (moduleInfo); - moduleInfo.SizeOfStruct = sizeof (moduleInfo); - - if (::SymGetModuleInfo64 (process, symbol->ModBase, &moduleInfo)) - result << moduleInfo.ModuleName << ": "; - - result << symbol->Name << " + 0x" << String::toHexString ((int64) displacement) << newLine; - } - } - - #else - void* stack[128]; - int frames = backtrace (stack, numElementsInArray (stack)); - char** frameStrings = backtrace_symbols (stack, frames); - - for (int i = 0; i < frames; ++i) - result << frameStrings[i] << newLine; - - ::free (frameStrings); - #endif - - return result; -} - -//============================================================================== -static SystemStats::CrashHandlerFunction globalCrashHandler = nullptr; - -#if JUCE_WINDOWS -static LONG WINAPI handleCrash (LPEXCEPTION_POINTERS) -{ - globalCrashHandler(); - return EXCEPTION_EXECUTE_HANDLER; -} -#else -static void handleCrash (int) -{ - globalCrashHandler(); - kill (getpid(), SIGKILL); -} - -int juce_siginterrupt (int sig, int flag); -#endif - -void SystemStats::setApplicationCrashHandler (CrashHandlerFunction handler) -{ - jassert (handler != nullptr); // This must be a valid function. - globalCrashHandler = handler; - - #if JUCE_WINDOWS - SetUnhandledExceptionFilter (handleCrash); - #else - const int signals[] = { SIGFPE, SIGILL, SIGSEGV, SIGBUS, SIGABRT, SIGSYS }; - - for (int i = 0; i < numElementsInArray (signals); ++i) - { - ::signal (signals[i], handleCrash); - juce_siginterrupt (signals[i], 1); - } - #endif -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/system/juce_SystemStats.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/system/juce_SystemStats.h deleted file mode 100644 index 023dcc0a42..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/system/juce_SystemStats.h +++ /dev/null @@ -1,196 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_SYSTEMSTATS_H_INCLUDED -#define JUCE_SYSTEMSTATS_H_INCLUDED - - -//============================================================================== -/** - Contains methods for finding out about the current hardware and OS configuration. -*/ -class JUCE_API SystemStats -{ -public: - //============================================================================== - /** Returns the current version of JUCE, - See also the JUCE_VERSION, JUCE_MAJOR_VERSION and JUCE_MINOR_VERSION macros. - */ - static String getJUCEVersion(); - - //============================================================================== - /** The set of possible results of the getOperatingSystemType() method. */ - enum OperatingSystemType - { - UnknownOS = 0, - - Linux = 0x2000, - Android = 0x3000, - iOS = 0x8000, - - MacOSX_10_4 = 0x1004, - MacOSX_10_5 = 0x1005, - MacOSX_10_6 = 0x1006, - MacOSX_10_7 = 0x1007, - MacOSX_10_8 = 0x1008, - MacOSX_10_9 = 0x1009, - MacOSX_10_10 = 0x100a, - - Win2000 = 0x4105, - WinXP = 0x4106, - WinVista = 0x4107, - Windows7 = 0x4108, - Windows8_0 = 0x4109, - Windows8_1 = 0x410a, - - Windows = 0x4000, /**< To test whether any version of Windows is running, - you can use the expression ((getOperatingSystemType() & Windows) != 0). */ - }; - - /** Returns the type of operating system we're running on. - - @returns one of the values from the OperatingSystemType enum. - @see getOperatingSystemName - */ - static OperatingSystemType getOperatingSystemType(); - - /** Returns the name of the type of operating system we're running on. - - @returns a string describing the OS type. - @see getOperatingSystemType - */ - static String getOperatingSystemName(); - - /** Returns true if the OS is 64-bit, or false for a 32-bit OS. */ - static bool isOperatingSystem64Bit(); - - /** Returns an environment variable. - If the named value isn't set, this will return the defaultValue string instead. - */ - static String getEnvironmentVariable (const String& name, const String& defaultValue); - - //============================================================================== - /** Returns the current user's name, if available. - @see getFullUserName() - */ - static String getLogonName(); - - /** Returns the current user's full name, if available. - On some OSes, this may just return the same value as getLogonName(). - @see getLogonName() - */ - static String getFullUserName(); - - /** Returns the host-name of the computer. */ - static String getComputerName(); - - /** Returns the language of the user's locale. - The return value is a 2 or 3 letter language code (ISO 639-1 or ISO 639-2) - */ - static String getUserLanguage(); - - /** Returns the region of the user's locale. - The return value is a 2 letter country code (ISO 3166-1 alpha-2). - */ - static String getUserRegion(); - - /** Returns the user's display language. - The return value is a 2 or 3 letter language code (ISO 639-1 or ISO 639-2). - Note that depending on the OS and region, this may also be followed by a dash - and a sub-region code, e.g "en-GB" - */ - static String getDisplayLanguage(); - - /** This will attempt to return some kind of string describing the device. - If no description is available, it'll just return an empty string. You may - want to use this for things like determining the type of phone/iPad, etc. - */ - static String getDeviceDescription(); - - //============================================================================== - // CPU and memory information.. - - /** Returns the number of CPU cores. */ - static int getNumCpus() noexcept; - - /** Returns the approximate CPU speed. - @returns the speed in megahertz, e.g. 1500, 2500, 32000 (depending on - what year you're reading this...) - */ - static int getCpuSpeedInMegaherz(); - - /** Returns a string to indicate the CPU vendor. - Might not be known on some systems. - */ - static String getCpuVendor(); - - static bool hasMMX() noexcept; /**< Returns true if Intel MMX instructions are available. */ - static bool hasSSE() noexcept; /**< Returns true if Intel SSE instructions are available. */ - static bool hasSSE2() noexcept; /**< Returns true if Intel SSE2 instructions are available. */ - static bool hasSSE3() noexcept; /**< Returns true if Intel SSE2 instructions are available. */ - static bool has3DNow() noexcept; /**< Returns true if AMD 3DNOW instructions are available. */ - - //============================================================================== - /** Finds out how much RAM is in the machine. - @returns the approximate number of megabytes of memory, or zero if - something goes wrong when finding out. - */ - static int getMemorySizeInMegabytes(); - - /** Returns the system page-size. - This is only used by programmers with beards. - */ - static int getPageSize(); - - //============================================================================== - /** Returns a backtrace of the current call-stack. - The usefulness of the result will depend on the level of debug symbols - that are available in the executable. - */ - static String getStackBacktrace(); - - /** A void() function type, used by setApplicationCrashHandler(). */ - typedef void (*CrashHandlerFunction)(); - - /** Sets up a global callback function that will be called if the application - executes some kind of illegal instruction. - - You may want to call getStackBacktrace() in your handler function, to find out - where the problem happened and log it, etc. - */ - static void setApplicationCrashHandler (CrashHandlerFunction); - -private: - //============================================================================== - SystemStats(); - - JUCE_DECLARE_NON_COPYABLE (SystemStats) -}; - - -#endif // JUCE_SYSTEMSTATS_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/system/juce_TargetPlatform.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/system/juce_TargetPlatform.h deleted file mode 100644 index 63470b668d..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/system/juce_TargetPlatform.h +++ /dev/null @@ -1,201 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_TARGETPLATFORM_H_INCLUDED -#define JUCE_TARGETPLATFORM_H_INCLUDED - -//============================================================================== -/* This file figures out which platform is being built, and defines some macros - that the rest of the code can use for OS-specific compilation. - - Macros that will be set here are: - - - One of JUCE_WINDOWS, JUCE_MAC JUCE_LINUX, JUCE_IOS, JUCE_ANDROID, etc. - - Either JUCE_32BIT or JUCE_64BIT, depending on the architecture. - - Either JUCE_LITTLE_ENDIAN or JUCE_BIG_ENDIAN. - - Either JUCE_INTEL or JUCE_PPC - - Either JUCE_GCC or JUCE_MSVC -*/ - -//============================================================================== -#if (defined (_WIN32) || defined (_WIN64)) - #define JUCE_WIN32 1 - #define JUCE_WINDOWS 1 -#elif defined (JUCE_ANDROID) - #undef JUCE_ANDROID - #define JUCE_ANDROID 1 -#elif defined (LINUX) || defined (__linux__) - #define JUCE_LINUX 1 -#elif defined (__APPLE_CPP__) || defined(__APPLE_CC__) - #define Point CarbonDummyPointName // (workaround to avoid definition of "Point" by old Carbon headers) - #define Component CarbonDummyCompName - #include // (needed to find out what platform we're using) - #undef Point - #undef Component - - #if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR - #define JUCE_IPHONE 1 - #define JUCE_IOS 1 - #else - #define JUCE_MAC 1 - #endif -#elif defined (__FreeBSD__) - #define JUCE_BSD 1 -#else - #error "Unknown platform!" -#endif - -//============================================================================== -#if JUCE_WINDOWS - #ifdef _MSC_VER - #ifdef _WIN64 - #define JUCE_64BIT 1 - #else - #define JUCE_32BIT 1 - #endif - #endif - - #ifdef _DEBUG - #define JUCE_DEBUG 1 - #endif - - #ifdef __MINGW32__ - #define JUCE_MINGW 1 - #ifdef __MINGW64__ - #define JUCE_64BIT 1 - #else - #define JUCE_32BIT 1 - #endif - #endif - - /** If defined, this indicates that the processor is little-endian. */ - #define JUCE_LITTLE_ENDIAN 1 - - #define JUCE_INTEL 1 -#endif - -//============================================================================== -#if JUCE_MAC || JUCE_IOS - - #if defined (DEBUG) || defined (_DEBUG) || ! (defined (NDEBUG) || defined (_NDEBUG)) - #define JUCE_DEBUG 1 - #endif - - #if ! (defined (DEBUG) || defined (_DEBUG) || defined (NDEBUG) || defined (_NDEBUG)) - #warning "Neither NDEBUG or DEBUG has been defined - you should set one of these to make it clear whether this is a release build," - #endif - - #ifdef __LITTLE_ENDIAN__ - #define JUCE_LITTLE_ENDIAN 1 - #else - #define JUCE_BIG_ENDIAN 1 - #endif - - #ifdef __LP64__ - #define JUCE_64BIT 1 - #else - #define JUCE_32BIT 1 - #endif - - #if defined (__ppc__) || defined (__ppc64__) - #define JUCE_PPC 1 - #elif defined (__arm__) || defined (__arm64__) - #define JUCE_ARM 1 - #else - #define JUCE_INTEL 1 - #endif - - #if JUCE_MAC && MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_4 - #error "Building for OSX 10.3 is no longer supported!" - #endif - - #if JUCE_MAC && ! defined (MAC_OS_X_VERSION_10_5) - #error "To build with 10.4 compatibility, use a 10.5 or 10.6 SDK and set the deployment target to 10.4" - #endif -#endif - -//============================================================================== -#if JUCE_LINUX || JUCE_ANDROID - - #ifdef _DEBUG - #define JUCE_DEBUG 1 - #endif - - // Allow override for big-endian Linux platforms - #if defined (__LITTLE_ENDIAN__) || ! defined (JUCE_BIG_ENDIAN) - #define JUCE_LITTLE_ENDIAN 1 - #undef JUCE_BIG_ENDIAN - #else - #undef JUCE_LITTLE_ENDIAN - #define JUCE_BIG_ENDIAN 1 - #endif - - #if defined (__LP64__) || defined (_LP64) || defined (__arm64__) - #define JUCE_64BIT 1 - #else - #define JUCE_32BIT 1 - #endif - - #if defined (__arm__) || defined (__arm64__) - #define JUCE_ARM 1 - #elif __MMX__ || __SSE__ || __amd64__ - #define JUCE_INTEL 1 - #endif -#endif - -//============================================================================== -// Compiler type macros. - -#ifdef __clang__ - #define JUCE_CLANG 1 - #define JUCE_GCC 1 -#elif defined (__GNUC__) - #define JUCE_GCC 1 -#elif defined (_MSC_VER) - #define JUCE_MSVC 1 - - #if _MSC_VER < 1500 - #define JUCE_VC8_OR_EARLIER 1 - - #if _MSC_VER < 1400 - #define JUCE_VC7_OR_EARLIER 1 - - #if _MSC_VER < 1300 - #warning "MSVC 6.0 is no longer supported!" - #endif - #endif - #endif - - #if JUCE_64BIT || ! JUCE_VC7_OR_EARLIER - #define JUCE_USE_MSVC_INTRINSICS 1 - #endif -#else - #error unknown compiler -#endif - -#endif // JUCE_TARGETPLATFORM_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/text/juce_CharPointer_ASCII.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/text/juce_CharPointer_ASCII.h deleted file mode 100644 index a966543b56..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/text/juce_CharPointer_ASCII.h +++ /dev/null @@ -1,387 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_CHARPOINTER_ASCII_H_INCLUDED -#define JUCE_CHARPOINTER_ASCII_H_INCLUDED - - -//============================================================================== -/** - Wraps a pointer to a null-terminated ASCII character string, and provides - various methods to operate on the data. - - A valid ASCII string is assumed to not contain any characters above 127. - - @see CharPointer_UTF8, CharPointer_UTF16, CharPointer_UTF32 -*/ -class CharPointer_ASCII -{ -public: - typedef char CharType; - - inline explicit CharPointer_ASCII (const CharType* const rawPointer) noexcept - : data (const_cast (rawPointer)) - { - } - - inline CharPointer_ASCII (const CharPointer_ASCII& other) noexcept - : data (other.data) - { - } - - inline CharPointer_ASCII operator= (const CharPointer_ASCII other) noexcept - { - data = other.data; - return *this; - } - - inline CharPointer_ASCII operator= (const CharType* text) noexcept - { - data = const_cast (text); - return *this; - } - - /** This is a pointer comparison, it doesn't compare the actual text. */ - inline bool operator== (CharPointer_ASCII other) const noexcept { return data == other.data; } - inline bool operator!= (CharPointer_ASCII other) const noexcept { return data != other.data; } - inline bool operator<= (CharPointer_ASCII other) const noexcept { return data <= other.data; } - inline bool operator< (CharPointer_ASCII other) const noexcept { return data < other.data; } - inline bool operator>= (CharPointer_ASCII other) const noexcept { return data >= other.data; } - inline bool operator> (CharPointer_ASCII other) const noexcept { return data > other.data; } - - /** Returns the address that this pointer is pointing to. */ - inline CharType* getAddress() const noexcept { return data; } - - /** Returns the address that this pointer is pointing to. */ - inline operator const CharType*() const noexcept { return data; } - - /** Returns true if this pointer is pointing to a null character. */ - inline bool isEmpty() const noexcept { return *data == 0; } - - /** Returns the unicode character that this pointer is pointing to. */ - inline juce_wchar operator*() const noexcept { return (juce_wchar) (uint8) *data; } - - /** Moves this pointer along to the next character in the string. */ - inline CharPointer_ASCII operator++() noexcept - { - ++data; - return *this; - } - - /** Moves this pointer to the previous character in the string. */ - inline CharPointer_ASCII operator--() noexcept - { - --data; - return *this; - } - - /** Returns the character that this pointer is currently pointing to, and then - advances the pointer to point to the next character. */ - inline juce_wchar getAndAdvance() noexcept { return (juce_wchar) (uint8) *data++; } - - /** Moves this pointer along to the next character in the string. */ - CharPointer_ASCII operator++ (int) noexcept - { - CharPointer_ASCII temp (*this); - ++data; - return temp; - } - - /** Moves this pointer forwards by the specified number of characters. */ - inline void operator+= (const int numToSkip) noexcept - { - data += numToSkip; - } - - inline void operator-= (const int numToSkip) noexcept - { - data -= numToSkip; - } - - /** Returns the character at a given character index from the start of the string. */ - inline juce_wchar operator[] (const int characterIndex) const noexcept - { - return (juce_wchar) (unsigned char) data [characterIndex]; - } - - /** Returns a pointer which is moved forwards from this one by the specified number of characters. */ - CharPointer_ASCII operator+ (const int numToSkip) const noexcept - { - return CharPointer_ASCII (data + numToSkip); - } - - /** Returns a pointer which is moved backwards from this one by the specified number of characters. */ - CharPointer_ASCII operator- (const int numToSkip) const noexcept - { - return CharPointer_ASCII (data - numToSkip); - } - - /** Writes a unicode character to this string, and advances this pointer to point to the next position. */ - inline void write (const juce_wchar charToWrite) noexcept - { - *data++ = (char) charToWrite; - } - - inline void replaceChar (const juce_wchar newChar) noexcept - { - *data = (char) newChar; - } - - /** Writes a null character to this string (leaving the pointer's position unchanged). */ - inline void writeNull() const noexcept - { - *data = 0; - } - - /** Returns the number of characters in this string. */ - size_t length() const noexcept - { - return (size_t) strlen (data); - } - - /** Returns the number of characters in this string, or the given value, whichever is lower. */ - size_t lengthUpTo (const size_t maxCharsToCount) const noexcept - { - return CharacterFunctions::lengthUpTo (*this, maxCharsToCount); - } - - /** Returns the number of characters in this string, or up to the given end pointer, whichever is lower. */ - size_t lengthUpTo (const CharPointer_ASCII end) const noexcept - { - return CharacterFunctions::lengthUpTo (*this, end); - } - - /** Returns the number of bytes that are used to represent this string. - This includes the terminating null character. - */ - size_t sizeInBytes() const noexcept - { - return length() + 1; - } - - /** Returns the number of bytes that would be needed to represent the given - unicode character in this encoding format. - */ - static inline size_t getBytesRequiredFor (const juce_wchar) noexcept - { - return 1; - } - - /** Returns the number of bytes that would be needed to represent the given - string in this encoding format. - The value returned does NOT include the terminating null character. - */ - template - static size_t getBytesRequiredFor (const CharPointer text) noexcept - { - return text.length(); - } - - /** Returns a pointer to the null character that terminates this string. */ - CharPointer_ASCII findTerminatingNull() const noexcept - { - return CharPointer_ASCII (data + length()); - } - - /** Copies a source string to this pointer, advancing this pointer as it goes. */ - template - void writeAll (const CharPointer src) noexcept - { - CharacterFunctions::copyAll (*this, src); - } - - /** Copies a source string to this pointer, advancing this pointer as it goes. */ - void writeAll (const CharPointer_ASCII src) noexcept - { - strcpy (data, src.data); - } - - /** Copies a source string to this pointer, advancing this pointer as it goes. - The maxDestBytes parameter specifies the maximum number of bytes that can be written - to the destination buffer before stopping. - */ - template - size_t writeWithDestByteLimit (const CharPointer src, const size_t maxDestBytes) noexcept - { - return CharacterFunctions::copyWithDestByteLimit (*this, src, maxDestBytes); - } - - /** Copies a source string to this pointer, advancing this pointer as it goes. - The maxChars parameter specifies the maximum number of characters that can be - written to the destination buffer before stopping (including the terminating null). - */ - template - void writeWithCharLimit (const CharPointer src, const int maxChars) noexcept - { - CharacterFunctions::copyWithCharLimit (*this, src, maxChars); - } - - /** Compares this string with another one. */ - template - int compare (const CharPointer other) const noexcept - { - return CharacterFunctions::compare (*this, other); - } - - /** Compares this string with another one. */ - int compare (const CharPointer_ASCII other) const noexcept - { - return strcmp (data, other.data); - } - - /** Compares this string with another one, up to a specified number of characters. */ - template - int compareUpTo (const CharPointer other, const int maxChars) const noexcept - { - return CharacterFunctions::compareUpTo (*this, other, maxChars); - } - - /** Compares this string with another one, up to a specified number of characters. */ - int compareUpTo (const CharPointer_ASCII other, const int maxChars) const noexcept - { - return strncmp (data, other.data, (size_t) maxChars); - } - - /** Compares this string with another one. */ - template - int compareIgnoreCase (const CharPointer other) const - { - return CharacterFunctions::compareIgnoreCase (*this, other); - } - - int compareIgnoreCase (const CharPointer_ASCII other) const - { - #if JUCE_WINDOWS - return stricmp (data, other.data); - #else - return strcasecmp (data, other.data); - #endif - } - - /** Compares this string with another one, up to a specified number of characters. */ - template - int compareIgnoreCaseUpTo (const CharPointer other, const int maxChars) const noexcept - { - return CharacterFunctions::compareIgnoreCaseUpTo (*this, other, maxChars); - } - - /** Returns the character index of a substring, or -1 if it isn't found. */ - template - int indexOf (const CharPointer stringToFind) const noexcept - { - return CharacterFunctions::indexOf (*this, stringToFind); - } - - /** Returns the character index of a unicode character, or -1 if it isn't found. */ - int indexOf (const juce_wchar charToFind) const noexcept - { - int i = 0; - - while (data[i] != 0) - { - if (data[i] == (char) charToFind) - return i; - - ++i; - } - - return -1; - } - - /** Returns the character index of a unicode character, or -1 if it isn't found. */ - int indexOf (const juce_wchar charToFind, const bool ignoreCase) const noexcept - { - return ignoreCase ? CharacterFunctions::indexOfCharIgnoreCase (*this, charToFind) - : CharacterFunctions::indexOfChar (*this, charToFind); - } - - /** Returns true if the first character of this string is whitespace. */ - bool isWhitespace() const { return CharacterFunctions::isWhitespace (*data) != 0; } - /** Returns true if the first character of this string is a digit. */ - bool isDigit() const { return CharacterFunctions::isDigit (*data) != 0; } - /** Returns true if the first character of this string is a letter. */ - bool isLetter() const { return CharacterFunctions::isLetter (*data) != 0; } - /** Returns true if the first character of this string is a letter or digit. */ - bool isLetterOrDigit() const { return CharacterFunctions::isLetterOrDigit (*data) != 0; } - /** Returns true if the first character of this string is upper-case. */ - bool isUpperCase() const { return CharacterFunctions::isUpperCase ((juce_wchar) (uint8) *data) != 0; } - /** Returns true if the first character of this string is lower-case. */ - bool isLowerCase() const { return CharacterFunctions::isLowerCase ((juce_wchar) (uint8) *data) != 0; } - - /** Returns an upper-case version of the first character of this string. */ - juce_wchar toUpperCase() const noexcept { return CharacterFunctions::toUpperCase ((juce_wchar) (uint8) *data); } - /** Returns a lower-case version of the first character of this string. */ - juce_wchar toLowerCase() const noexcept { return CharacterFunctions::toLowerCase ((juce_wchar) (uint8) *data); } - - /** Parses this string as a 32-bit integer. */ - int getIntValue32() const noexcept { return atoi (data); } - - /** Parses this string as a 64-bit integer. */ - int64 getIntValue64() const noexcept - { - #if JUCE_LINUX || JUCE_ANDROID - return atoll (data); - #elif JUCE_WINDOWS - return _atoi64 (data); - #else - return CharacterFunctions::getIntValue (*this); - #endif - } - - /** Parses this string as a floating point double. */ - double getDoubleValue() const noexcept { return CharacterFunctions::getDoubleValue (*this); } - - /** Returns the first non-whitespace character in the string. */ - CharPointer_ASCII findEndOfWhitespace() const noexcept { return CharacterFunctions::findEndOfWhitespace (*this); } - - /** Returns true if the given unicode character can be represented in this encoding. */ - static bool canRepresent (juce_wchar character) noexcept - { - return ((unsigned int) character) < (unsigned int) 128; - } - - /** Returns true if this data contains a valid string in this encoding. */ - static bool isValidString (const CharType* dataToTest, int maxBytesToRead) - { - while (--maxBytesToRead >= 0) - { - if (((signed char) *dataToTest) <= 0) - return *dataToTest == 0; - - ++dataToTest; - } - - return true; - } - -private: - CharType* data; -}; - - -#endif // JUCE_CHARPOINTER_ASCII_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/text/juce_CharPointer_UTF16.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/text/juce_CharPointer_UTF16.h deleted file mode 100644 index d0eba5ceaa..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/text/juce_CharPointer_UTF16.h +++ /dev/null @@ -1,525 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_CHARPOINTER_UTF16_H_INCLUDED -#define JUCE_CHARPOINTER_UTF16_H_INCLUDED - - -//============================================================================== -/** - Wraps a pointer to a null-terminated UTF-16 character string, and provides - various methods to operate on the data. - @see CharPointer_UTF8, CharPointer_UTF32 -*/ -class CharPointer_UTF16 -{ -public: - #if JUCE_NATIVE_WCHAR_IS_UTF16 - typedef wchar_t CharType; - #else - typedef int16 CharType; - #endif - - inline explicit CharPointer_UTF16 (const CharType* const rawPointer) noexcept - : data (const_cast (rawPointer)) - { - } - - inline CharPointer_UTF16 (const CharPointer_UTF16& other) noexcept - : data (other.data) - { - } - - inline CharPointer_UTF16 operator= (CharPointer_UTF16 other) noexcept - { - data = other.data; - return *this; - } - - inline CharPointer_UTF16 operator= (const CharType* text) noexcept - { - data = const_cast (text); - return *this; - } - - /** This is a pointer comparison, it doesn't compare the actual text. */ - inline bool operator== (CharPointer_UTF16 other) const noexcept { return data == other.data; } - inline bool operator!= (CharPointer_UTF16 other) const noexcept { return data != other.data; } - inline bool operator<= (CharPointer_UTF16 other) const noexcept { return data <= other.data; } - inline bool operator< (CharPointer_UTF16 other) const noexcept { return data < other.data; } - inline bool operator>= (CharPointer_UTF16 other) const noexcept { return data >= other.data; } - inline bool operator> (CharPointer_UTF16 other) const noexcept { return data > other.data; } - - /** Returns the address that this pointer is pointing to. */ - inline CharType* getAddress() const noexcept { return data; } - - /** Returns the address that this pointer is pointing to. */ - inline operator const CharType*() const noexcept { return data; } - - /** Returns true if this pointer is pointing to a null character. */ - inline bool isEmpty() const noexcept { return *data == 0; } - - /** Returns the unicode character that this pointer is pointing to. */ - juce_wchar operator*() const noexcept - { - uint32 n = (uint32) (uint16) *data; - - if (n >= 0xd800 && n <= 0xdfff && ((uint32) (uint16) data[1]) >= 0xdc00) - n = 0x10000 + (((n - 0xd800) << 10) | (((uint32) (uint16) data[1]) - 0xdc00)); - - return (juce_wchar) n; - } - - /** Moves this pointer along to the next character in the string. */ - CharPointer_UTF16 operator++() noexcept - { - const juce_wchar n = *data++; - - if (n >= 0xd800 && n <= 0xdfff && ((uint32) (uint16) *data) >= 0xdc00) - ++data; - - return *this; - } - - /** Moves this pointer back to the previous character in the string. */ - CharPointer_UTF16 operator--() noexcept - { - const juce_wchar n = *--data; - - if (n >= 0xdc00 && n <= 0xdfff) - --data; - - return *this; - } - - /** Returns the character that this pointer is currently pointing to, and then - advances the pointer to point to the next character. */ - juce_wchar getAndAdvance() noexcept - { - uint32 n = (uint32) (uint16) *data++; - - if (n >= 0xd800 && n <= 0xdfff && ((uint32) (uint16) *data) >= 0xdc00) - n = 0x10000 + ((((n - 0xd800) << 10) | (((uint32) (uint16) *data++) - 0xdc00))); - - return (juce_wchar) n; - } - - /** Moves this pointer along to the next character in the string. */ - CharPointer_UTF16 operator++ (int) noexcept - { - CharPointer_UTF16 temp (*this); - ++*this; - return temp; - } - - /** Moves this pointer forwards by the specified number of characters. */ - void operator+= (int numToSkip) noexcept - { - if (numToSkip < 0) - { - while (++numToSkip <= 0) - --*this; - } - else - { - while (--numToSkip >= 0) - ++*this; - } - } - - /** Moves this pointer backwards by the specified number of characters. */ - void operator-= (int numToSkip) noexcept - { - operator+= (-numToSkip); - } - - /** Returns the character at a given character index from the start of the string. */ - juce_wchar operator[] (const int characterIndex) const noexcept - { - CharPointer_UTF16 p (*this); - p += characterIndex; - return *p; - } - - /** Returns a pointer which is moved forwards from this one by the specified number of characters. */ - CharPointer_UTF16 operator+ (const int numToSkip) const noexcept - { - CharPointer_UTF16 p (*this); - p += numToSkip; - return p; - } - - /** Returns a pointer which is moved backwards from this one by the specified number of characters. */ - CharPointer_UTF16 operator- (const int numToSkip) const noexcept - { - CharPointer_UTF16 p (*this); - p += -numToSkip; - return p; - } - - /** Writes a unicode character to this string, and advances this pointer to point to the next position. */ - void write (juce_wchar charToWrite) noexcept - { - if (charToWrite >= 0x10000) - { - charToWrite -= 0x10000; - *data++ = (CharType) (0xd800 + (charToWrite >> 10)); - *data++ = (CharType) (0xdc00 + (charToWrite & 0x3ff)); - } - else - { - *data++ = (CharType) charToWrite; - } - } - - /** Writes a null character to this string (leaving the pointer's position unchanged). */ - inline void writeNull() const noexcept - { - *data = 0; - } - - /** Returns the number of characters in this string. */ - size_t length() const noexcept - { - const CharType* d = data; - size_t count = 0; - - for (;;) - { - const int n = *d++; - - if (n >= 0xd800 && n <= 0xdfff) - { - if (*d++ == 0) - break; - } - else if (n == 0) - break; - - ++count; - } - - return count; - } - - /** Returns the number of characters in this string, or the given value, whichever is lower. */ - size_t lengthUpTo (const size_t maxCharsToCount) const noexcept - { - return CharacterFunctions::lengthUpTo (*this, maxCharsToCount); - } - - /** Returns the number of characters in this string, or up to the given end pointer, whichever is lower. */ - size_t lengthUpTo (const CharPointer_UTF16 end) const noexcept - { - return CharacterFunctions::lengthUpTo (*this, end); - } - - /** Returns the number of bytes that are used to represent this string. - This includes the terminating null character. - */ - size_t sizeInBytes() const noexcept - { - return sizeof (CharType) * (findNullIndex (data) + 1); - } - - /** Returns the number of bytes that would be needed to represent the given - unicode character in this encoding format. - */ - static size_t getBytesRequiredFor (const juce_wchar charToWrite) noexcept - { - return (charToWrite >= 0x10000) ? (sizeof (CharType) * 2) : sizeof (CharType); - } - - /** Returns the number of bytes that would be needed to represent the given - string in this encoding format. - The value returned does NOT include the terminating null character. - */ - template - static size_t getBytesRequiredFor (CharPointer text) noexcept - { - size_t count = 0; - juce_wchar n; - - while ((n = text.getAndAdvance()) != 0) - count += getBytesRequiredFor (n); - - return count; - } - - /** Returns a pointer to the null character that terminates this string. */ - CharPointer_UTF16 findTerminatingNull() const noexcept - { - const CharType* t = data; - - while (*t != 0) - ++t; - - return CharPointer_UTF16 (t); - } - - /** Copies a source string to this pointer, advancing this pointer as it goes. */ - template - void writeAll (const CharPointer src) noexcept - { - CharacterFunctions::copyAll (*this, src); - } - - /** Copies a source string to this pointer, advancing this pointer as it goes. */ - void writeAll (const CharPointer_UTF16 src) noexcept - { - const CharType* s = src.data; - - while ((*data = *s) != 0) - { - ++data; - ++s; - } - } - - /** Copies a source string to this pointer, advancing this pointer as it goes. - The maxDestBytes parameter specifies the maximum number of bytes that can be written - to the destination buffer before stopping. - */ - template - size_t writeWithDestByteLimit (const CharPointer src, const size_t maxDestBytes) noexcept - { - return CharacterFunctions::copyWithDestByteLimit (*this, src, maxDestBytes); - } - - /** Copies a source string to this pointer, advancing this pointer as it goes. - The maxChars parameter specifies the maximum number of characters that can be - written to the destination buffer before stopping (including the terminating null). - */ - template - void writeWithCharLimit (const CharPointer src, const int maxChars) noexcept - { - CharacterFunctions::copyWithCharLimit (*this, src, maxChars); - } - - /** Compares this string with another one. */ - template - int compare (const CharPointer other) const noexcept - { - return CharacterFunctions::compare (*this, other); - } - - /** Compares this string with another one, up to a specified number of characters. */ - template - int compareUpTo (const CharPointer other, const int maxChars) const noexcept - { - return CharacterFunctions::compareUpTo (*this, other, maxChars); - } - - /** Compares this string with another one. */ - template - int compareIgnoreCase (const CharPointer other) const noexcept - { - return CharacterFunctions::compareIgnoreCase (*this, other); - } - - /** Compares this string with another one, up to a specified number of characters. */ - template - int compareIgnoreCaseUpTo (const CharPointer other, const int maxChars) const noexcept - { - return CharacterFunctions::compareIgnoreCaseUpTo (*this, other, maxChars); - } - - #if JUCE_WINDOWS && ! DOXYGEN - int compareIgnoreCase (const CharPointer_UTF16 other) const noexcept - { - return _wcsicmp (data, other.data); - } - - int compareIgnoreCaseUpTo (const CharPointer_UTF16 other, int maxChars) const noexcept - { - return _wcsnicmp (data, other.data, (size_t) maxChars); - } - - int indexOf (const CharPointer_UTF16 stringToFind) const noexcept - { - const CharType* const t = wcsstr (data, stringToFind.getAddress()); - return t == nullptr ? -1 : (int) (t - data); - } - #endif - - /** Returns the character index of a substring, or -1 if it isn't found. */ - template - int indexOf (const CharPointer stringToFind) const noexcept - { - return CharacterFunctions::indexOf (*this, stringToFind); - } - - /** Returns the character index of a unicode character, or -1 if it isn't found. */ - int indexOf (const juce_wchar charToFind) const noexcept - { - return CharacterFunctions::indexOfChar (*this, charToFind); - } - - /** Returns the character index of a unicode character, or -1 if it isn't found. */ - int indexOf (const juce_wchar charToFind, const bool ignoreCase) const noexcept - { - return ignoreCase ? CharacterFunctions::indexOfCharIgnoreCase (*this, charToFind) - : CharacterFunctions::indexOfChar (*this, charToFind); - } - - /** Returns true if the first character of this string is whitespace. */ - bool isWhitespace() const noexcept { return CharacterFunctions::isWhitespace (operator*()) != 0; } - /** Returns true if the first character of this string is a digit. */ - bool isDigit() const noexcept { return CharacterFunctions::isDigit (operator*()) != 0; } - /** Returns true if the first character of this string is a letter. */ - bool isLetter() const noexcept { return CharacterFunctions::isLetter (operator*()) != 0; } - /** Returns true if the first character of this string is a letter or digit. */ - bool isLetterOrDigit() const noexcept { return CharacterFunctions::isLetterOrDigit (operator*()) != 0; } - /** Returns true if the first character of this string is upper-case. */ - bool isUpperCase() const noexcept { return CharacterFunctions::isUpperCase (operator*()) != 0; } - /** Returns true if the first character of this string is lower-case. */ - bool isLowerCase() const noexcept { return CharacterFunctions::isLowerCase (operator*()) != 0; } - - /** Returns an upper-case version of the first character of this string. */ - juce_wchar toUpperCase() const noexcept { return CharacterFunctions::toUpperCase (operator*()); } - /** Returns a lower-case version of the first character of this string. */ - juce_wchar toLowerCase() const noexcept { return CharacterFunctions::toLowerCase (operator*()); } - - /** Parses this string as a 32-bit integer. */ - int getIntValue32() const noexcept - { - #if JUCE_WINDOWS - return _wtoi (data); - #else - return CharacterFunctions::getIntValue (*this); - #endif - } - - /** Parses this string as a 64-bit integer. */ - int64 getIntValue64() const noexcept - { - #if JUCE_WINDOWS - return _wtoi64 (data); - #else - return CharacterFunctions::getIntValue (*this); - #endif - } - - /** Parses this string as a floating point double. */ - double getDoubleValue() const noexcept { return CharacterFunctions::getDoubleValue (*this); } - - /** Returns the first non-whitespace character in the string. */ - CharPointer_UTF16 findEndOfWhitespace() const noexcept { return CharacterFunctions::findEndOfWhitespace (*this); } - - /** Returns true if the given unicode character can be represented in this encoding. */ - static bool canRepresent (juce_wchar character) noexcept - { - return ((unsigned int) character) < (unsigned int) 0x10ffff - && (((unsigned int) character) < 0xd800 || ((unsigned int) character) > 0xdfff); - } - - /** Returns true if this data contains a valid string in this encoding. */ - static bool isValidString (const CharType* dataToTest, int maxBytesToRead) - { - maxBytesToRead /= (int) sizeof (CharType); - - while (--maxBytesToRead >= 0 && *dataToTest != 0) - { - const uint32 n = (uint32) (uint16) *dataToTest++; - - if (n >= 0xd800) - { - if (n > 0x10ffff) - return false; - - if (n <= 0xdfff) - { - if (n > 0xdc00) - return false; - - const uint32 nextChar = (uint32) (uint16) *dataToTest++; - - if (nextChar < 0xdc00 || nextChar > 0xdfff) - return false; - } - } - } - - return true; - } - - /** Atomically swaps this pointer for a new value, returning the previous value. */ - CharPointer_UTF16 atomicSwap (const CharPointer_UTF16 newValue) - { - return CharPointer_UTF16 (reinterpret_cast &> (data).exchange (newValue.data)); - } - - /** These values are the byte-order-mark (BOM) values for a UTF-16 stream. */ - enum - { - byteOrderMarkBE1 = 0xfe, - byteOrderMarkBE2 = 0xff, - byteOrderMarkLE1 = 0xff, - byteOrderMarkLE2 = 0xfe - }; - - /** Returns true if the first pair of bytes in this pointer are the UTF16 byte-order mark (big endian). - The pointer must not be null, and must contain at least two valid bytes. - */ - static bool isByteOrderMarkBigEndian (const void* possibleByteOrder) noexcept - { - jassert (possibleByteOrder != nullptr); - const uint8* const c = static_cast (possibleByteOrder); - - return c[0] == (uint8) byteOrderMarkBE1 - && c[1] == (uint8) byteOrderMarkBE2; - } - - /** Returns true if the first pair of bytes in this pointer are the UTF16 byte-order mark (little endian). - The pointer must not be null, and must contain at least two valid bytes. - */ - static bool isByteOrderMarkLittleEndian (const void* possibleByteOrder) noexcept - { - jassert (possibleByteOrder != nullptr); - const uint8* const c = static_cast (possibleByteOrder); - - return c[0] == (uint8) byteOrderMarkLE1 - && c[1] == (uint8) byteOrderMarkLE2; - } - -private: - CharType* data; - - static unsigned int findNullIndex (const CharType* const t) noexcept - { - unsigned int n = 0; - - while (t[n] != 0) - ++n; - - return n; - } -}; - - -#endif // JUCE_CHARPOINTER_UTF16_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/text/juce_CharPointer_UTF32.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/text/juce_CharPointer_UTF32.h deleted file mode 100644 index 42cfe48714..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/text/juce_CharPointer_UTF32.h +++ /dev/null @@ -1,378 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_CHARPOINTER_UTF32_H_INCLUDED -#define JUCE_CHARPOINTER_UTF32_H_INCLUDED - - -//============================================================================== -/** - Wraps a pointer to a null-terminated UTF-32 character string, and provides - various methods to operate on the data. - @see CharPointer_UTF8, CharPointer_UTF16 -*/ -class CharPointer_UTF32 -{ -public: - typedef juce_wchar CharType; - - inline explicit CharPointer_UTF32 (const CharType* const rawPointer) noexcept - : data (const_cast (rawPointer)) - { - } - - inline CharPointer_UTF32 (const CharPointer_UTF32& other) noexcept - : data (other.data) - { - } - - inline CharPointer_UTF32 operator= (CharPointer_UTF32 other) noexcept - { - data = other.data; - return *this; - } - - inline CharPointer_UTF32 operator= (const CharType* text) noexcept - { - data = const_cast (text); - return *this; - } - - /** This is a pointer comparison, it doesn't compare the actual text. */ - inline bool operator== (CharPointer_UTF32 other) const noexcept { return data == other.data; } - inline bool operator!= (CharPointer_UTF32 other) const noexcept { return data != other.data; } - inline bool operator<= (CharPointer_UTF32 other) const noexcept { return data <= other.data; } - inline bool operator< (CharPointer_UTF32 other) const noexcept { return data < other.data; } - inline bool operator>= (CharPointer_UTF32 other) const noexcept { return data >= other.data; } - inline bool operator> (CharPointer_UTF32 other) const noexcept { return data > other.data; } - - /** Returns the address that this pointer is pointing to. */ - inline CharType* getAddress() const noexcept { return data; } - - /** Returns the address that this pointer is pointing to. */ - inline operator const CharType*() const noexcept { return data; } - - /** Returns true if this pointer is pointing to a null character. */ - inline bool isEmpty() const noexcept { return *data == 0; } - - /** Returns the unicode character that this pointer is pointing to. */ - inline juce_wchar operator*() const noexcept { return *data; } - - /** Moves this pointer along to the next character in the string. */ - inline CharPointer_UTF32 operator++() noexcept - { - ++data; - return *this; - } - - /** Moves this pointer to the previous character in the string. */ - inline CharPointer_UTF32 operator--() noexcept - { - --data; - return *this; - } - - /** Returns the character that this pointer is currently pointing to, and then - advances the pointer to point to the next character. */ - inline juce_wchar getAndAdvance() noexcept { return *data++; } - - /** Moves this pointer along to the next character in the string. */ - CharPointer_UTF32 operator++ (int) noexcept - { - CharPointer_UTF32 temp (*this); - ++data; - return temp; - } - - /** Moves this pointer forwards by the specified number of characters. */ - inline void operator+= (const int numToSkip) noexcept - { - data += numToSkip; - } - - inline void operator-= (const int numToSkip) noexcept - { - data -= numToSkip; - } - - /** Returns the character at a given character index from the start of the string. */ - inline juce_wchar& operator[] (const int characterIndex) const noexcept - { - return data [characterIndex]; - } - - /** Returns a pointer which is moved forwards from this one by the specified number of characters. */ - CharPointer_UTF32 operator+ (const int numToSkip) const noexcept - { - return CharPointer_UTF32 (data + numToSkip); - } - - /** Returns a pointer which is moved backwards from this one by the specified number of characters. */ - CharPointer_UTF32 operator- (const int numToSkip) const noexcept - { - return CharPointer_UTF32 (data - numToSkip); - } - - /** Writes a unicode character to this string, and advances this pointer to point to the next position. */ - inline void write (const juce_wchar charToWrite) noexcept - { - *data++ = charToWrite; - } - - inline void replaceChar (const juce_wchar newChar) noexcept - { - *data = newChar; - } - - /** Writes a null character to this string (leaving the pointer's position unchanged). */ - inline void writeNull() const noexcept - { - *data = 0; - } - - /** Returns the number of characters in this string. */ - size_t length() const noexcept - { - #if JUCE_NATIVE_WCHAR_IS_UTF32 && ! JUCE_ANDROID - return wcslen (data); - #else - size_t n = 0; - while (data[n] != 0) - ++n; - return n; - #endif - } - - /** Returns the number of characters in this string, or the given value, whichever is lower. */ - size_t lengthUpTo (const size_t maxCharsToCount) const noexcept - { - return CharacterFunctions::lengthUpTo (*this, maxCharsToCount); - } - - /** Returns the number of characters in this string, or up to the given end pointer, whichever is lower. */ - size_t lengthUpTo (const CharPointer_UTF32 end) const noexcept - { - return CharacterFunctions::lengthUpTo (*this, end); - } - - /** Returns the number of bytes that are used to represent this string. - This includes the terminating null character. - */ - size_t sizeInBytes() const noexcept - { - return sizeof (CharType) * (length() + 1); - } - - /** Returns the number of bytes that would be needed to represent the given - unicode character in this encoding format. - */ - static inline size_t getBytesRequiredFor (const juce_wchar) noexcept - { - return sizeof (CharType); - } - - /** Returns the number of bytes that would be needed to represent the given - string in this encoding format. - The value returned does NOT include the terminating null character. - */ - template - static size_t getBytesRequiredFor (const CharPointer text) noexcept - { - return sizeof (CharType) * text.length(); - } - - /** Returns a pointer to the null character that terminates this string. */ - CharPointer_UTF32 findTerminatingNull() const noexcept - { - return CharPointer_UTF32 (data + length()); - } - - /** Copies a source string to this pointer, advancing this pointer as it goes. */ - template - void writeAll (const CharPointer src) noexcept - { - CharacterFunctions::copyAll (*this, src); - } - - /** Copies a source string to this pointer, advancing this pointer as it goes. */ - void writeAll (const CharPointer_UTF32 src) noexcept - { - const CharType* s = src.data; - - while ((*data = *s) != 0) - { - ++data; - ++s; - } - } - - /** Copies a source string to this pointer, advancing this pointer as it goes. - The maxDestBytes parameter specifies the maximum number of bytes that can be written - to the destination buffer before stopping. - */ - template - size_t writeWithDestByteLimit (const CharPointer src, const size_t maxDestBytes) noexcept - { - return CharacterFunctions::copyWithDestByteLimit (*this, src, maxDestBytes); - } - - /** Copies a source string to this pointer, advancing this pointer as it goes. - The maxChars parameter specifies the maximum number of characters that can be - written to the destination buffer before stopping (including the terminating null). - */ - template - void writeWithCharLimit (const CharPointer src, const int maxChars) noexcept - { - CharacterFunctions::copyWithCharLimit (*this, src, maxChars); - } - - /** Compares this string with another one. */ - template - int compare (const CharPointer other) const noexcept - { - return CharacterFunctions::compare (*this, other); - } - - #if JUCE_NATIVE_WCHAR_IS_UTF32 && ! JUCE_ANDROID - /** Compares this string with another one. */ - int compare (const CharPointer_UTF32 other) const noexcept - { - return wcscmp (data, other.data); - } - #endif - - /** Compares this string with another one, up to a specified number of characters. */ - template - int compareUpTo (const CharPointer other, const int maxChars) const noexcept - { - return CharacterFunctions::compareUpTo (*this, other, maxChars); - } - - /** Compares this string with another one. */ - template - int compareIgnoreCase (const CharPointer other) const - { - return CharacterFunctions::compareIgnoreCase (*this, other); - } - - /** Compares this string with another one, up to a specified number of characters. */ - template - int compareIgnoreCaseUpTo (const CharPointer other, const int maxChars) const noexcept - { - return CharacterFunctions::compareIgnoreCaseUpTo (*this, other, maxChars); - } - - /** Returns the character index of a substring, or -1 if it isn't found. */ - template - int indexOf (const CharPointer stringToFind) const noexcept - { - return CharacterFunctions::indexOf (*this, stringToFind); - } - - /** Returns the character index of a unicode character, or -1 if it isn't found. */ - int indexOf (const juce_wchar charToFind) const noexcept - { - int i = 0; - - while (data[i] != 0) - { - if (data[i] == charToFind) - return i; - - ++i; - } - - return -1; - } - - /** Returns the character index of a unicode character, or -1 if it isn't found. */ - int indexOf (const juce_wchar charToFind, const bool ignoreCase) const noexcept - { - return ignoreCase ? CharacterFunctions::indexOfCharIgnoreCase (*this, charToFind) - : CharacterFunctions::indexOfChar (*this, charToFind); - } - - /** Returns true if the first character of this string is whitespace. */ - bool isWhitespace() const { return CharacterFunctions::isWhitespace (*data) != 0; } - /** Returns true if the first character of this string is a digit. */ - bool isDigit() const { return CharacterFunctions::isDigit (*data) != 0; } - /** Returns true if the first character of this string is a letter. */ - bool isLetter() const { return CharacterFunctions::isLetter (*data) != 0; } - /** Returns true if the first character of this string is a letter or digit. */ - bool isLetterOrDigit() const { return CharacterFunctions::isLetterOrDigit (*data) != 0; } - /** Returns true if the first character of this string is upper-case. */ - bool isUpperCase() const { return CharacterFunctions::isUpperCase (*data) != 0; } - /** Returns true if the first character of this string is lower-case. */ - bool isLowerCase() const { return CharacterFunctions::isLowerCase (*data) != 0; } - - /** Returns an upper-case version of the first character of this string. */ - juce_wchar toUpperCase() const noexcept { return CharacterFunctions::toUpperCase (*data); } - /** Returns a lower-case version of the first character of this string. */ - juce_wchar toLowerCase() const noexcept { return CharacterFunctions::toLowerCase (*data); } - - /** Parses this string as a 32-bit integer. */ - int getIntValue32() const noexcept { return CharacterFunctions::getIntValue (*this); } - /** Parses this string as a 64-bit integer. */ - int64 getIntValue64() const noexcept { return CharacterFunctions::getIntValue (*this); } - - /** Parses this string as a floating point double. */ - double getDoubleValue() const noexcept { return CharacterFunctions::getDoubleValue (*this); } - - /** Returns the first non-whitespace character in the string. */ - CharPointer_UTF32 findEndOfWhitespace() const noexcept { return CharacterFunctions::findEndOfWhitespace (*this); } - - /** Returns true if the given unicode character can be represented in this encoding. */ - static bool canRepresent (juce_wchar character) noexcept - { - return ((unsigned int) character) < (unsigned int) 0x10ffff; - } - - /** Returns true if this data contains a valid string in this encoding. */ - static bool isValidString (const CharType* dataToTest, int maxBytesToRead) - { - maxBytesToRead /= (int) sizeof (CharType); - - while (--maxBytesToRead >= 0 && *dataToTest != 0) - if (! canRepresent (*dataToTest++)) - return false; - - return true; - } - - /** Atomically swaps this pointer for a new value, returning the previous value. */ - CharPointer_UTF32 atomicSwap (const CharPointer_UTF32 newValue) - { - return CharPointer_UTF32 (reinterpret_cast &> (data).exchange (newValue.data)); - } - -private: - CharType* data; -}; - - -#endif // JUCE_CHARPOINTER_UTF32_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/text/juce_CharPointer_UTF8.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/text/juce_CharPointer_UTF8.h deleted file mode 100644 index 78d9a975ee..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/text/juce_CharPointer_UTF8.h +++ /dev/null @@ -1,572 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_CHARPOINTER_UTF8_H_INCLUDED -#define JUCE_CHARPOINTER_UTF8_H_INCLUDED - -//============================================================================== -/** - Wraps a pointer to a null-terminated UTF-8 character string, and provides - various methods to operate on the data. - @see CharPointer_UTF16, CharPointer_UTF32 -*/ -class CharPointer_UTF8 -{ -public: - typedef char CharType; - - inline explicit CharPointer_UTF8 (const CharType* const rawPointer) noexcept - : data (const_cast (rawPointer)) - { - } - - inline CharPointer_UTF8 (const CharPointer_UTF8& other) noexcept - : data (other.data) - { - } - - inline CharPointer_UTF8 operator= (CharPointer_UTF8 other) noexcept - { - data = other.data; - return *this; - } - - inline CharPointer_UTF8 operator= (const CharType* text) noexcept - { - data = const_cast (text); - return *this; - } - - /** This is a pointer comparison, it doesn't compare the actual text. */ - inline bool operator== (CharPointer_UTF8 other) const noexcept { return data == other.data; } - inline bool operator!= (CharPointer_UTF8 other) const noexcept { return data != other.data; } - inline bool operator<= (CharPointer_UTF8 other) const noexcept { return data <= other.data; } - inline bool operator< (CharPointer_UTF8 other) const noexcept { return data < other.data; } - inline bool operator>= (CharPointer_UTF8 other) const noexcept { return data >= other.data; } - inline bool operator> (CharPointer_UTF8 other) const noexcept { return data > other.data; } - - /** Returns the address that this pointer is pointing to. */ - inline CharType* getAddress() const noexcept { return data; } - - /** Returns the address that this pointer is pointing to. */ - inline operator const CharType*() const noexcept { return data; } - - /** Returns true if this pointer is pointing to a null character. */ - inline bool isEmpty() const noexcept { return *data == 0; } - - /** Returns the unicode character that this pointer is pointing to. */ - juce_wchar operator*() const noexcept - { - const signed char byte = (signed char) *data; - - if (byte >= 0) - return (juce_wchar) (uint8) byte; - - uint32 n = (uint32) (uint8) byte; - uint32 mask = 0x7f; - uint32 bit = 0x40; - size_t numExtraValues = 0; - - while ((n & bit) != 0 && bit > 0x10) - { - mask >>= 1; - ++numExtraValues; - bit >>= 1; - } - - n &= mask; - - for (size_t i = 1; i <= numExtraValues; ++i) - { - const uint8 nextByte = (uint8) data [i]; - - if ((nextByte & 0xc0) != 0x80) - break; - - n <<= 6; - n |= (nextByte & 0x3f); - } - - return (juce_wchar) n; - } - - /** Moves this pointer along to the next character in the string. */ - CharPointer_UTF8& operator++() noexcept - { - jassert (*data != 0); // trying to advance past the end of the string? - const signed char n = (signed char) *data++; - - if (n < 0) - { - juce_wchar bit = 0x40; - - while ((n & bit) != 0 && bit > 0x8) - { - ++data; - bit >>= 1; - } - } - - return *this; - } - - /** Moves this pointer back to the previous character in the string. */ - CharPointer_UTF8 operator--() noexcept - { - int count = 0; - - while ((*--data & 0xc0) == 0x80 && ++count < 4) - {} - - return *this; - } - - /** Returns the character that this pointer is currently pointing to, and then - advances the pointer to point to the next character. */ - juce_wchar getAndAdvance() noexcept - { - const signed char byte = (signed char) *data++; - - if (byte >= 0) - return (juce_wchar) (uint8) byte; - - uint32 n = (uint32) (uint8) byte; - uint32 mask = 0x7f; - uint32 bit = 0x40; - int numExtraValues = 0; - - while ((n & bit) != 0 && bit > 0x8) - { - mask >>= 1; - ++numExtraValues; - bit >>= 1; - } - - n &= mask; - - while (--numExtraValues >= 0) - { - const uint32 nextByte = (uint32) (uint8) *data; - - if ((nextByte & 0xc0) != 0x80) - break; - - ++data; - n <<= 6; - n |= (nextByte & 0x3f); - } - - return (juce_wchar) n; - } - - /** Moves this pointer along to the next character in the string. */ - CharPointer_UTF8 operator++ (int) noexcept - { - CharPointer_UTF8 temp (*this); - ++*this; - return temp; - } - - /** Moves this pointer forwards by the specified number of characters. */ - void operator+= (int numToSkip) noexcept - { - if (numToSkip < 0) - { - while (++numToSkip <= 0) - --*this; - } - else - { - while (--numToSkip >= 0) - ++*this; - } - } - - /** Moves this pointer backwards by the specified number of characters. */ - void operator-= (int numToSkip) noexcept - { - operator+= (-numToSkip); - } - - /** Returns the character at a given character index from the start of the string. */ - juce_wchar operator[] (int characterIndex) const noexcept - { - CharPointer_UTF8 p (*this); - p += characterIndex; - return *p; - } - - /** Returns a pointer which is moved forwards from this one by the specified number of characters. */ - CharPointer_UTF8 operator+ (int numToSkip) const noexcept - { - CharPointer_UTF8 p (*this); - p += numToSkip; - return p; - } - - /** Returns a pointer which is moved backwards from this one by the specified number of characters. */ - CharPointer_UTF8 operator- (int numToSkip) const noexcept - { - CharPointer_UTF8 p (*this); - p += -numToSkip; - return p; - } - - /** Returns the number of characters in this string. */ - size_t length() const noexcept - { - const CharType* d = data; - size_t count = 0; - - for (;;) - { - const uint32 n = (uint32) (uint8) *d++; - - if ((n & 0x80) != 0) - { - while ((*d & 0xc0) == 0x80) - ++d; - } - else if (n == 0) - break; - - ++count; - } - - return count; - } - - /** Returns the number of characters in this string, or the given value, whichever is lower. */ - size_t lengthUpTo (const size_t maxCharsToCount) const noexcept - { - return CharacterFunctions::lengthUpTo (*this, maxCharsToCount); - } - - /** Returns the number of characters in this string, or up to the given end pointer, whichever is lower. */ - size_t lengthUpTo (const CharPointer_UTF8 end) const noexcept - { - return CharacterFunctions::lengthUpTo (*this, end); - } - - /** Returns the number of bytes that are used to represent this string. - This includes the terminating null character. - */ - size_t sizeInBytes() const noexcept - { - jassert (data != nullptr); - return strlen (data) + 1; - } - - /** Returns the number of bytes that would be needed to represent the given - unicode character in this encoding format. - */ - static size_t getBytesRequiredFor (const juce_wchar charToWrite) noexcept - { - size_t num = 1; - const uint32 c = (uint32) charToWrite; - - if (c >= 0x80) - { - ++num; - if (c >= 0x800) - { - ++num; - if (c >= 0x10000) - ++num; - } - } - - return num; - } - - /** Returns the number of bytes that would be needed to represent the given - string in this encoding format. - The value returned does NOT include the terminating null character. - */ - template - static size_t getBytesRequiredFor (CharPointer text) noexcept - { - size_t count = 0; - juce_wchar n; - - while ((n = text.getAndAdvance()) != 0) - count += getBytesRequiredFor (n); - - return count; - } - - /** Returns a pointer to the null character that terminates this string. */ - CharPointer_UTF8 findTerminatingNull() const noexcept - { - return CharPointer_UTF8 (data + strlen (data)); - } - - /** Writes a unicode character to this string, and advances this pointer to point to the next position. */ - void write (const juce_wchar charToWrite) noexcept - { - const uint32 c = (uint32) charToWrite; - - if (c >= 0x80) - { - int numExtraBytes = 1; - if (c >= 0x800) - { - ++numExtraBytes; - if (c >= 0x10000) - ++numExtraBytes; - } - - *data++ = (CharType) ((uint32) (0xff << (7 - numExtraBytes)) | (c >> (numExtraBytes * 6))); - - while (--numExtraBytes >= 0) - *data++ = (CharType) (0x80 | (0x3f & (c >> (numExtraBytes * 6)))); - } - else - { - *data++ = (CharType) c; - } - } - - /** Writes a null character to this string (leaving the pointer's position unchanged). */ - inline void writeNull() const noexcept - { - *data = 0; - } - - /** Copies a source string to this pointer, advancing this pointer as it goes. */ - template - void writeAll (const CharPointer src) noexcept - { - CharacterFunctions::copyAll (*this, src); - } - - /** Copies a source string to this pointer, advancing this pointer as it goes. */ - void writeAll (const CharPointer_UTF8 src) noexcept - { - const CharType* s = src.data; - - while ((*data = *s) != 0) - { - ++data; - ++s; - } - } - - /** Copies a source string to this pointer, advancing this pointer as it goes. - The maxDestBytes parameter specifies the maximum number of bytes that can be written - to the destination buffer before stopping. - */ - template - size_t writeWithDestByteLimit (const CharPointer src, const size_t maxDestBytes) noexcept - { - return CharacterFunctions::copyWithDestByteLimit (*this, src, maxDestBytes); - } - - /** Copies a source string to this pointer, advancing this pointer as it goes. - The maxChars parameter specifies the maximum number of characters that can be - written to the destination buffer before stopping (including the terminating null). - */ - template - void writeWithCharLimit (const CharPointer src, const int maxChars) noexcept - { - CharacterFunctions::copyWithCharLimit (*this, src, maxChars); - } - - /** Compares this string with another one. */ - template - int compare (const CharPointer other) const noexcept - { - return CharacterFunctions::compare (*this, other); - } - - /** Compares this string with another one, up to a specified number of characters. */ - template - int compareUpTo (const CharPointer other, const int maxChars) const noexcept - { - return CharacterFunctions::compareUpTo (*this, other, maxChars); - } - - /** Compares this string with another one. */ - template - int compareIgnoreCase (const CharPointer other) const noexcept - { - return CharacterFunctions::compareIgnoreCase (*this, other); - } - - /** Compares this string with another one. */ - int compareIgnoreCase (const CharPointer_UTF8 other) const noexcept - { - #if JUCE_WINDOWS - return stricmp (data, other.data); - #else - return strcasecmp (data, other.data); - #endif - } - - /** Compares this string with another one, up to a specified number of characters. */ - template - int compareIgnoreCaseUpTo (const CharPointer other, const int maxChars) const noexcept - { - return CharacterFunctions::compareIgnoreCaseUpTo (*this, other, maxChars); - } - - /** Returns the character index of a substring, or -1 if it isn't found. */ - template - int indexOf (const CharPointer stringToFind) const noexcept - { - return CharacterFunctions::indexOf (*this, stringToFind); - } - - /** Returns the character index of a unicode character, or -1 if it isn't found. */ - int indexOf (const juce_wchar charToFind) const noexcept - { - return CharacterFunctions::indexOfChar (*this, charToFind); - } - - /** Returns the character index of a unicode character, or -1 if it isn't found. */ - int indexOf (const juce_wchar charToFind, const bool ignoreCase) const noexcept - { - return ignoreCase ? CharacterFunctions::indexOfCharIgnoreCase (*this, charToFind) - : CharacterFunctions::indexOfChar (*this, charToFind); - } - - /** Returns true if the first character of this string is whitespace. */ - bool isWhitespace() const noexcept { return *data == ' ' || (*data <= 13 && *data >= 9); } - /** Returns true if the first character of this string is a digit. */ - bool isDigit() const noexcept { return *data >= '0' && *data <= '9'; } - /** Returns true if the first character of this string is a letter. */ - bool isLetter() const noexcept { return CharacterFunctions::isLetter (operator*()) != 0; } - /** Returns true if the first character of this string is a letter or digit. */ - bool isLetterOrDigit() const noexcept { return CharacterFunctions::isLetterOrDigit (operator*()) != 0; } - /** Returns true if the first character of this string is upper-case. */ - bool isUpperCase() const noexcept { return CharacterFunctions::isUpperCase (operator*()) != 0; } - /** Returns true if the first character of this string is lower-case. */ - bool isLowerCase() const noexcept { return CharacterFunctions::isLowerCase (operator*()) != 0; } - - /** Returns an upper-case version of the first character of this string. */ - juce_wchar toUpperCase() const noexcept { return CharacterFunctions::toUpperCase (operator*()); } - /** Returns a lower-case version of the first character of this string. */ - juce_wchar toLowerCase() const noexcept { return CharacterFunctions::toLowerCase (operator*()); } - - /** Parses this string as a 32-bit integer. */ - int getIntValue32() const noexcept { return atoi (data); } - - /** Parses this string as a 64-bit integer. */ - int64 getIntValue64() const noexcept - { - #if JUCE_LINUX || JUCE_ANDROID - return atoll (data); - #elif JUCE_WINDOWS - return _atoi64 (data); - #else - return CharacterFunctions::getIntValue (*this); - #endif - } - - /** Parses this string as a floating point double. */ - double getDoubleValue() const noexcept { return CharacterFunctions::getDoubleValue (*this); } - - /** Returns the first non-whitespace character in the string. */ - CharPointer_UTF8 findEndOfWhitespace() const noexcept { return CharacterFunctions::findEndOfWhitespace (*this); } - - /** Returns true if the given unicode character can be represented in this encoding. */ - static bool canRepresent (juce_wchar character) noexcept - { - return ((unsigned int) character) < (unsigned int) 0x10ffff; - } - - /** Returns true if this data contains a valid string in this encoding. */ - static bool isValidString (const CharType* dataToTest, int maxBytesToRead) - { - while (--maxBytesToRead >= 0 && *dataToTest != 0) - { - const signed char byte = (signed char) *dataToTest++; - - if (byte < 0) - { - uint8 bit = 0x40; - int numExtraValues = 0; - - while ((byte & bit) != 0) - { - if (bit < 8) - return false; - - ++numExtraValues; - bit >>= 1; - - if (bit == 8 && (numExtraValues > maxBytesToRead - || *CharPointer_UTF8 (dataToTest - 1) > 0x10ffff)) - return false; - } - - maxBytesToRead -= numExtraValues; - if (maxBytesToRead < 0) - return false; - - while (--numExtraValues >= 0) - if ((*dataToTest++ & 0xc0) != 0x80) - return false; - } - } - - return true; - } - - /** Atomically swaps this pointer for a new value, returning the previous value. */ - CharPointer_UTF8 atomicSwap (const CharPointer_UTF8 newValue) - { - return CharPointer_UTF8 (reinterpret_cast &> (data).exchange (newValue.data)); - } - - /** These values are the byte-order mark (BOM) values for a UTF-8 stream. */ - enum - { - byteOrderMark1 = 0xef, - byteOrderMark2 = 0xbb, - byteOrderMark3 = 0xbf - }; - - /** Returns true if the first three bytes in this pointer are the UTF8 byte-order mark (BOM). - The pointer must not be null, and must point to at least 3 valid bytes. - */ - static bool isByteOrderMark (const void* possibleByteOrder) noexcept - { - jassert (possibleByteOrder != nullptr); - const uint8* const c = static_cast (possibleByteOrder); - - return c[0] == (uint8) byteOrderMark1 - && c[1] == (uint8) byteOrderMark2 - && c[2] == (uint8) byteOrderMark3; - } - -private: - CharType* data; -}; - -#endif // JUCE_CHARPOINTER_UTF8_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/text/juce_CharacterFunctions.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/text/juce_CharacterFunctions.cpp deleted file mode 100644 index 11eaa188b6..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/text/juce_CharacterFunctions.cpp +++ /dev/null @@ -1,154 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -//============================================================================== -#if JUCE_MSVC - #pragma warning (push) - #pragma warning (disable: 4514 4996) -#endif - -juce_wchar CharacterFunctions::toUpperCase (const juce_wchar character) noexcept -{ - return towupper ((wchar_t) character); -} - -juce_wchar CharacterFunctions::toLowerCase (const juce_wchar character) noexcept -{ - return towlower ((wchar_t) character); -} - -bool CharacterFunctions::isUpperCase (const juce_wchar character) noexcept -{ - #if JUCE_WINDOWS - return iswupper ((wchar_t) character) != 0; - #else - return toLowerCase (character) != character; - #endif -} - -bool CharacterFunctions::isLowerCase (const juce_wchar character) noexcept -{ - #if JUCE_WINDOWS - return iswlower ((wchar_t) character) != 0; - #else - return toUpperCase (character) != character; - #endif -} - -#if JUCE_MSVC - #pragma warning (pop) -#endif - -//============================================================================== -bool CharacterFunctions::isWhitespace (const char character) noexcept -{ - return character == ' ' || (character <= 13 && character >= 9); -} - -bool CharacterFunctions::isWhitespace (const juce_wchar character) noexcept -{ - return iswspace ((wchar_t) character) != 0; -} - -bool CharacterFunctions::isDigit (const char character) noexcept -{ - return (character >= '0' && character <= '9'); -} - -bool CharacterFunctions::isDigit (const juce_wchar character) noexcept -{ - return iswdigit ((wchar_t) character) != 0; -} - -bool CharacterFunctions::isLetter (const char character) noexcept -{ - return (character >= 'a' && character <= 'z') - || (character >= 'A' && character <= 'Z'); -} - -bool CharacterFunctions::isLetter (const juce_wchar character) noexcept -{ - return iswalpha ((wchar_t) character) != 0; -} - -bool CharacterFunctions::isLetterOrDigit (const char character) noexcept -{ - return (character >= 'a' && character <= 'z') - || (character >= 'A' && character <= 'Z') - || (character >= '0' && character <= '9'); -} - -bool CharacterFunctions::isLetterOrDigit (const juce_wchar character) noexcept -{ - return iswalnum ((wchar_t) character) != 0; -} - -int CharacterFunctions::getHexDigitValue (const juce_wchar digit) noexcept -{ - unsigned int d = (unsigned int) digit - '0'; - if (d < (unsigned int) 10) - return (int) d; - - d += (unsigned int) ('0' - 'a'); - if (d < (unsigned int) 6) - return (int) d + 10; - - d += (unsigned int) ('a' - 'A'); - if (d < (unsigned int) 6) - return (int) d + 10; - - return -1; -} - -double CharacterFunctions::mulexp10 (const double value, int exponent) noexcept -{ - if (exponent == 0) - return value; - - if (value == 0) - return 0; - - const bool negative = (exponent < 0); - if (negative) - exponent = -exponent; - - double result = 1.0, power = 10.0; - for (int bit = 1; exponent != 0; bit <<= 1) - { - if ((exponent & bit) != 0) - { - exponent ^= bit; - result *= power; - if (exponent == 0) - break; - } - power *= power; - } - - return negative ? (value / result) : (value * result); -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/text/juce_CharacterFunctions.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/text/juce_CharacterFunctions.h deleted file mode 100644 index bade0dd703..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/text/juce_CharacterFunctions.h +++ /dev/null @@ -1,629 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_CHARACTERFUNCTIONS_H_INCLUDED -#define JUCE_CHARACTERFUNCTIONS_H_INCLUDED - - -//============================================================================== -#if JUCE_WINDOWS && ! DOXYGEN - #define JUCE_NATIVE_WCHAR_IS_UTF8 0 - #define JUCE_NATIVE_WCHAR_IS_UTF16 1 - #define JUCE_NATIVE_WCHAR_IS_UTF32 0 -#else - /** This macro will be set to 1 if the compiler's native wchar_t is an 8-bit type. */ - #define JUCE_NATIVE_WCHAR_IS_UTF8 0 - /** This macro will be set to 1 if the compiler's native wchar_t is a 16-bit type. */ - #define JUCE_NATIVE_WCHAR_IS_UTF16 0 - /** This macro will be set to 1 if the compiler's native wchar_t is a 32-bit type. */ - #define JUCE_NATIVE_WCHAR_IS_UTF32 1 -#endif - -#if JUCE_NATIVE_WCHAR_IS_UTF32 || DOXYGEN - /** A platform-independent 32-bit unicode character type. */ - typedef wchar_t juce_wchar; -#else - typedef uint32 juce_wchar; -#endif - -#ifndef DOXYGEN - /** This macro is deprecated, but preserved for compatibility with old code. */ - #define JUCE_T(stringLiteral) (L##stringLiteral) -#endif - -#if JUCE_DEFINE_T_MACRO - /** The 'T' macro is an alternative for using the "L" prefix in front of a string literal. - - This macro is deprecated, but available for compatibility with old code if you set - JUCE_DEFINE_T_MACRO = 1. The fastest, most portable and best way to write your string - literals is as standard char strings, using escaped utf-8 character sequences for extended - characters, rather than trying to store them as wide-char strings. - */ - #define T(stringLiteral) JUCE_T(stringLiteral) -#endif - -//============================================================================== -/** - A collection of functions for manipulating characters and character strings. - - Most of these methods are designed for internal use by the String and CharPointer - classes, but some of them may be useful to call directly. - - @see String, CharPointer_UTF8, CharPointer_UTF16, CharPointer_UTF32 -*/ -class JUCE_API CharacterFunctions -{ -public: - //============================================================================== - /** Converts a character to upper-case. */ - static juce_wchar toUpperCase (juce_wchar character) noexcept; - /** Converts a character to lower-case. */ - static juce_wchar toLowerCase (juce_wchar character) noexcept; - - /** Checks whether a unicode character is upper-case. */ - static bool isUpperCase (juce_wchar character) noexcept; - /** Checks whether a unicode character is lower-case. */ - static bool isLowerCase (juce_wchar character) noexcept; - - /** Checks whether a character is whitespace. */ - static bool isWhitespace (char character) noexcept; - /** Checks whether a character is whitespace. */ - static bool isWhitespace (juce_wchar character) noexcept; - - /** Checks whether a character is a digit. */ - static bool isDigit (char character) noexcept; - /** Checks whether a character is a digit. */ - static bool isDigit (juce_wchar character) noexcept; - - /** Checks whether a character is alphabetic. */ - static bool isLetter (char character) noexcept; - /** Checks whether a character is alphabetic. */ - static bool isLetter (juce_wchar character) noexcept; - - /** Checks whether a character is alphabetic or numeric. */ - static bool isLetterOrDigit (char character) noexcept; - /** Checks whether a character is alphabetic or numeric. */ - static bool isLetterOrDigit (juce_wchar character) noexcept; - - /** Returns 0 to 16 for '0' to 'F", or -1 for characters that aren't a legal hex digit. */ - static int getHexDigitValue (juce_wchar digit) noexcept; - - //============================================================================== - /** Parses a character string to read a floating-point number. - Note that this will advance the pointer that is passed in, leaving it at - the end of the number. - */ - template - static double readDoubleValue (CharPointerType& text) noexcept - { - double result[3] = { 0 }, accumulator[2] = { 0 }; - int exponentAdjustment[2] = { 0 }, exponentAccumulator[2] = { -1, -1 }; - int exponent = 0, decPointIndex = 0, digit = 0; - int lastDigit = 0, numSignificantDigits = 0; - bool isNegative = false, digitsFound = false; - const int maxSignificantDigits = 15 + 2; - - text = text.findEndOfWhitespace(); - juce_wchar c = *text; - - switch (c) - { - case '-': isNegative = true; // fall-through.. - case '+': c = *++text; - } - - switch (c) - { - case 'n': - case 'N': - if ((text[1] == 'a' || text[1] == 'A') && (text[2] == 'n' || text[2] == 'N')) - return std::numeric_limits::quiet_NaN(); - break; - - case 'i': - case 'I': - if ((text[1] == 'n' || text[1] == 'N') && (text[2] == 'f' || text[2] == 'F')) - return std::numeric_limits::infinity(); - break; - } - - for (;;) - { - if (text.isDigit()) - { - lastDigit = digit; - digit = (int) text.getAndAdvance() - '0'; - digitsFound = true; - - if (decPointIndex != 0) - exponentAdjustment[1]++; - - if (numSignificantDigits == 0 && digit == 0) - continue; - - if (++numSignificantDigits > maxSignificantDigits) - { - if (digit > 5) - ++accumulator [decPointIndex]; - else if (digit == 5 && (lastDigit & 1) != 0) - ++accumulator [decPointIndex]; - - if (decPointIndex > 0) - exponentAdjustment[1]--; - else - exponentAdjustment[0]++; - - while (text.isDigit()) - { - ++text; - if (decPointIndex == 0) - exponentAdjustment[0]++; - } - } - else - { - const double maxAccumulatorValue = (double) ((std::numeric_limits::max() - 9) / 10); - if (accumulator [decPointIndex] > maxAccumulatorValue) - { - result [decPointIndex] = mulexp10 (result [decPointIndex], exponentAccumulator [decPointIndex]) - + accumulator [decPointIndex]; - accumulator [decPointIndex] = 0; - exponentAccumulator [decPointIndex] = 0; - } - - accumulator [decPointIndex] = accumulator[decPointIndex] * 10 + digit; - exponentAccumulator [decPointIndex]++; - } - } - else if (decPointIndex == 0 && *text == '.') - { - ++text; - decPointIndex = 1; - - if (numSignificantDigits > maxSignificantDigits) - { - while (text.isDigit()) - ++text; - break; - } - } - else - { - break; - } - } - - result[0] = mulexp10 (result[0], exponentAccumulator[0]) + accumulator[0]; - - if (decPointIndex != 0) - result[1] = mulexp10 (result[1], exponentAccumulator[1]) + accumulator[1]; - - c = *text; - if ((c == 'e' || c == 'E') && digitsFound) - { - bool negativeExponent = false; - - switch (*++text) - { - case '-': negativeExponent = true; // fall-through.. - case '+': ++text; - } - - while (text.isDigit()) - exponent = (exponent * 10) + ((int) text.getAndAdvance() - '0'); - - if (negativeExponent) - exponent = -exponent; - } - - double r = mulexp10 (result[0], exponent + exponentAdjustment[0]); - if (decPointIndex != 0) - r += mulexp10 (result[1], exponent - exponentAdjustment[1]); - - return isNegative ? -r : r; - } - - /** Parses a character string, to read a floating-point value. */ - template - static double getDoubleValue (CharPointerType text) noexcept - { - return readDoubleValue (text); - } - - //============================================================================== - /** Parses a character string, to read an integer value. */ - template - static IntType getIntValue (const CharPointerType text) noexcept - { - IntType v = 0; - CharPointerType s (text.findEndOfWhitespace()); - - const bool isNeg = *s == '-'; - if (isNeg) - ++s; - - for (;;) - { - const juce_wchar c = s.getAndAdvance(); - - if (c >= '0' && c <= '9') - v = v * 10 + (IntType) (c - '0'); - else - break; - } - - return isNeg ? -v : v; - } - - template - struct HexParser - { - template - static ResultType parse (CharPointerType t) noexcept - { - ResultType result = 0; - - while (! t.isEmpty()) - { - const int hexValue = CharacterFunctions::getHexDigitValue (t.getAndAdvance()); - - if (hexValue >= 0) - result = (result << 4) | hexValue; - } - - return result; - } - }; - - //============================================================================== - /** Counts the number of characters in a given string, stopping if the count exceeds - a specified limit. */ - template - static size_t lengthUpTo (CharPointerType text, const size_t maxCharsToCount) noexcept - { - size_t len = 0; - - while (len < maxCharsToCount && text.getAndAdvance() != 0) - ++len; - - return len; - } - - /** Counts the number of characters in a given string, stopping if the count exceeds - a specified end-pointer. */ - template - static size_t lengthUpTo (CharPointerType start, const CharPointerType end) noexcept - { - size_t len = 0; - - while (start < end && start.getAndAdvance() != 0) - ++len; - - return len; - } - - /** Copies null-terminated characters from one string to another. */ - template - static void copyAll (DestCharPointerType& dest, SrcCharPointerType src) noexcept - { - for (;;) - { - const juce_wchar c = src.getAndAdvance(); - - if (c == 0) - break; - - dest.write (c); - } - - dest.writeNull(); - } - - /** Copies characters from one string to another, up to a null terminator - or a given byte size limit. */ - template - static size_t copyWithDestByteLimit (DestCharPointerType& dest, SrcCharPointerType src, size_t maxBytesToWrite) noexcept - { - typename DestCharPointerType::CharType const* const startAddress = dest.getAddress(); - ssize_t maxBytes = (ssize_t) maxBytesToWrite; - maxBytes -= sizeof (typename DestCharPointerType::CharType); // (allow for a terminating null) - - for (;;) - { - const juce_wchar c = src.getAndAdvance(); - const size_t bytesNeeded = DestCharPointerType::getBytesRequiredFor (c); - - maxBytes -= bytesNeeded; - if (c == 0 || maxBytes < 0) - break; - - dest.write (c); - } - - dest.writeNull(); - - return (size_t) getAddressDifference (dest.getAddress(), startAddress) - + sizeof (typename DestCharPointerType::CharType); - } - - /** Copies characters from one string to another, up to a null terminator - or a given maximum number of characters. */ - template - static void copyWithCharLimit (DestCharPointerType& dest, SrcCharPointerType src, int maxChars) noexcept - { - while (--maxChars > 0) - { - const juce_wchar c = src.getAndAdvance(); - if (c == 0) - break; - - dest.write (c); - } - - dest.writeNull(); - } - - /** Compares two null-terminated character strings. */ - template - static int compare (CharPointerType1 s1, CharPointerType2 s2) noexcept - { - for (;;) - { - const int c1 = (int) s1.getAndAdvance(); - const int c2 = (int) s2.getAndAdvance(); - const int diff = c1 - c2; - - if (diff != 0) return diff < 0 ? -1 : 1; - if (c1 == 0) break; - } - - return 0; - } - - /** Compares two null-terminated character strings, up to a given number of characters. */ - template - static int compareUpTo (CharPointerType1 s1, CharPointerType2 s2, int maxChars) noexcept - { - while (--maxChars >= 0) - { - const int c1 = (int) s1.getAndAdvance(); - const int c2 = (int) s2.getAndAdvance(); - const int diff = c1 - c2; - - if (diff != 0) return diff < 0 ? -1 : 1; - if (c1 == 0) break; - } - - return 0; - } - - /** Compares two null-terminated character strings, using a case-independant match. */ - template - static int compareIgnoreCase (CharPointerType1 s1, CharPointerType2 s2) noexcept - { - for (;;) - { - const int c1 = (int) s1.toUpperCase(); - const int c2 = (int) s2.toUpperCase(); - const int diff = c1 - c2; - - if (diff != 0) return diff < 0 ? -1 : 1; - if (c1 == 0) break; - - ++s1; ++s2; - } - - return 0; - } - - /** Compares two null-terminated character strings, using a case-independent match. */ - template - static int compareIgnoreCaseUpTo (CharPointerType1 s1, CharPointerType2 s2, int maxChars) noexcept - { - while (--maxChars >= 0) - { - const int c1 = (int) s1.toUpperCase(); - const int c2 = (int) s2.toUpperCase(); - const int diff = c1 - c2; - - if (diff != 0) return diff < 0 ? -1 : 1; - if (c1 == 0) break; - - ++s1; ++s2; - } - - return 0; - } - - /** Finds the character index of a given substring in another string. - Returns -1 if the substring is not found. - */ - template - static int indexOf (CharPointerType1 textToSearch, const CharPointerType2 substringToLookFor) noexcept - { - int index = 0; - const int substringLength = (int) substringToLookFor.length(); - - for (;;) - { - if (textToSearch.compareUpTo (substringToLookFor, substringLength) == 0) - return index; - - if (textToSearch.getAndAdvance() == 0) - return -1; - - ++index; - } - } - - /** Returns a pointer to the first occurrence of a substring in a string. - If the substring is not found, this will return a pointer to the string's - null terminator. - */ - template - static CharPointerType1 find (CharPointerType1 textToSearch, const CharPointerType2 substringToLookFor) noexcept - { - const int substringLength = (int) substringToLookFor.length(); - - while (textToSearch.compareUpTo (substringToLookFor, substringLength) != 0 - && ! textToSearch.isEmpty()) - ++textToSearch; - - return textToSearch; - } - - /** Returns a pointer to the first occurrence of a substring in a string. - If the substring is not found, this will return a pointer to the string's - null terminator. - */ - template - static CharPointerType find (CharPointerType textToSearch, const juce_wchar charToLookFor) noexcept - { - for (;; ++textToSearch) - { - const juce_wchar c = *textToSearch; - - if (c == charToLookFor || c == 0) - break; - } - - return textToSearch; - } - - /** Finds the character index of a given substring in another string, using - a case-independent match. - Returns -1 if the substring is not found. - */ - template - static int indexOfIgnoreCase (CharPointerType1 haystack, const CharPointerType2 needle) noexcept - { - int index = 0; - const int needleLength = (int) needle.length(); - - for (;;) - { - if (haystack.compareIgnoreCaseUpTo (needle, needleLength) == 0) - return index; - - if (haystack.getAndAdvance() == 0) - return -1; - - ++index; - } - } - - /** Finds the character index of a given character in another string. - Returns -1 if the character is not found. - */ - template - static int indexOfChar (Type text, const juce_wchar charToFind) noexcept - { - int i = 0; - - while (! text.isEmpty()) - { - if (text.getAndAdvance() == charToFind) - return i; - - ++i; - } - - return -1; - } - - /** Finds the character index of a given character in another string, using - a case-independent match. - Returns -1 if the character is not found. - */ - template - static int indexOfCharIgnoreCase (Type text, juce_wchar charToFind) noexcept - { - charToFind = CharacterFunctions::toLowerCase (charToFind); - int i = 0; - - while (! text.isEmpty()) - { - if (text.toLowerCase() == charToFind) - return i; - - ++text; - ++i; - } - - return -1; - } - - /** Returns a pointer to the first non-whitespace character in a string. - If the string contains only whitespace, this will return a pointer - to its null terminator. - */ - template - static Type findEndOfWhitespace (Type text) noexcept - { - while (text.isWhitespace()) - ++text; - - return text; - } - - /** Returns a pointer to the first character in the string which is found in - the breakCharacters string. - */ - template - static Type findEndOfToken (Type text, const BreakType breakCharacters, const Type quoteCharacters) - { - juce_wchar currentQuoteChar = 0; - - while (! text.isEmpty()) - { - const juce_wchar c = text.getAndAdvance(); - - if (currentQuoteChar == 0 && breakCharacters.indexOf (c) >= 0) - { - --text; - break; - } - - if (quoteCharacters.indexOf (c) >= 0) - { - if (currentQuoteChar == 0) - currentQuoteChar = c; - else if (currentQuoteChar == c) - currentQuoteChar = 0; - } - } - - return text; - } - -private: - static double mulexp10 (const double value, int exponent) noexcept; -}; - - -#endif // JUCE_CHARACTERFUNCTIONS_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/text/juce_Identifier.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/text/juce_Identifier.cpp deleted file mode 100644 index bac4dd58a9..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/text/juce_Identifier.cpp +++ /dev/null @@ -1,70 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -Identifier::Identifier() noexcept {} -Identifier::~Identifier() noexcept {} - -Identifier::Identifier (const Identifier& other) noexcept : name (other.name) {} - -Identifier& Identifier::operator= (const Identifier other) noexcept -{ - name = other.name; - return *this; -} - -Identifier::Identifier (const String& nm) - : name (StringPool::getGlobalPool().getPooledString (nm)) -{ - /* An Identifier string must be suitable for use as a script variable or XML - attribute, so it can only contain this limited set of characters.. */ - jassert (isValidIdentifier (toString())); -} - -Identifier::Identifier (const char* nm) - : name (StringPool::getGlobalPool().getPooledString (nm)) -{ - /* An Identifier string must be suitable for use as a script variable or XML - attribute, so it can only contain this limited set of characters.. */ - jassert (isValidIdentifier (toString())); -} - -Identifier::Identifier (String::CharPointerType start, String::CharPointerType end) - : name (StringPool::getGlobalPool().getPooledString (start, end)) -{ - /* An Identifier string must be suitable for use as a script variable or XML - attribute, so it can only contain this limited set of characters.. */ - jassert (isValidIdentifier (toString())); -} - -Identifier Identifier::null; - -bool Identifier::isValidIdentifier (const String& possibleIdentifier) noexcept -{ - return possibleIdentifier.isNotEmpty() - && possibleIdentifier.containsOnly ("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-:#@$%"); -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/text/juce_Identifier.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/text/juce_Identifier.h deleted file mode 100644 index f60eec8d45..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/text/juce_Identifier.h +++ /dev/null @@ -1,120 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_IDENTIFIER_H_INCLUDED -#define JUCE_IDENTIFIER_H_INCLUDED - - -//============================================================================== -/** - Represents a string identifier, designed for accessing properties by name. - - Comparing two Identifier objects is very fast (an O(1) operation), but creating - them can be slower than just using a String directly, so the optimal way to use them - is to keep some static Identifier objects for the things you use often. - - @see NamedValueSet, ValueTree -*/ -class JUCE_API Identifier -{ -public: - /** Creates a null identifier. */ - Identifier() noexcept; - - /** Creates an identifier with a specified name. - Because this name may need to be used in contexts such as script variables or XML - tags, it must only contain ascii letters and digits, or the underscore character. - */ - Identifier (const char* name); - - /** Creates an identifier with a specified name. - Because this name may need to be used in contexts such as script variables or XML - tags, it must only contain ascii letters and digits, or the underscore character. - */ - Identifier (const String& name); - - /** Creates an identifier with a specified name. - Because this name may need to be used in contexts such as script variables or XML - tags, it must only contain ascii letters and digits, or the underscore character. - */ - Identifier (String::CharPointerType nameStart, String::CharPointerType nameEnd); - - /** Creates a copy of another identifier. */ - Identifier (const Identifier& other) noexcept; - - /** Creates a copy of another identifier. */ - Identifier& operator= (const Identifier other) noexcept; - - /** Destructor */ - ~Identifier() noexcept; - - /** Compares two identifiers. This is a very fast operation. */ - inline bool operator== (Identifier other) const noexcept { return name.getCharPointer() == other.name.getCharPointer(); } - - /** Compares two identifiers. This is a very fast operation. */ - inline bool operator!= (Identifier other) const noexcept { return name.getCharPointer() != other.name.getCharPointer(); } - - /** Compares the identifier with a string. */ - inline bool operator== (StringRef other) const noexcept { return name == other; } - - /** Compares the identifier with a string. */ - inline bool operator!= (StringRef other) const noexcept { return name != other; } - - /** Returns this identifier as a string. */ - const String& toString() const noexcept { return name; } - - /** Returns this identifier's raw string pointer. */ - operator String::CharPointerType() const noexcept { return name.getCharPointer(); } - - /** Returns this identifier's raw string pointer. */ - String::CharPointerType getCharPointer() const noexcept { return name.getCharPointer(); } - - /** Returns this identifier as a StringRef. */ - operator StringRef() const noexcept { return name; } - - /** Returns true if this Identifier is not null */ - bool isValid() const noexcept { return name.isNotEmpty(); } - - /** Returns true if this Identifier is null */ - bool isNull() const noexcept { return name.isEmpty(); } - - /** A null identifier. */ - static Identifier null; - - /** Checks a given string for characters that might not be valid in an Identifier. - Since Identifiers are used as a script variables and XML attributes, they should only contain - alphanumeric characters, underscores, or the '-' and ':' characters. - */ - static bool isValidIdentifier (const String& possibleIdentifier) noexcept; - -private: - String name; -}; - - -#endif // JUCE_IDENTIFIER_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/text/juce_LocalisedStrings.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/text/juce_LocalisedStrings.cpp deleted file mode 100644 index e6118d31aa..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/text/juce_LocalisedStrings.cpp +++ /dev/null @@ -1,209 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -LocalisedStrings::LocalisedStrings (const String& fileContents, bool ignoreCase) -{ - loadFromText (fileContents, ignoreCase); -} - -LocalisedStrings::LocalisedStrings (const File& fileToLoad, bool ignoreCase) -{ - loadFromText (fileToLoad.loadFileAsString(), ignoreCase); -} - -LocalisedStrings::LocalisedStrings (const LocalisedStrings& other) - : languageName (other.languageName), countryCodes (other.countryCodes), - translations (other.translations), fallback (createCopyIfNotNull (other.fallback.get())) -{ -} - -LocalisedStrings& LocalisedStrings::operator= (const LocalisedStrings& other) -{ - languageName = other.languageName; - countryCodes = other.countryCodes; - translations = other.translations; - fallback = createCopyIfNotNull (other.fallback.get()); - return *this; -} - -LocalisedStrings::~LocalisedStrings() -{ -} - -//============================================================================== -String LocalisedStrings::translate (const String& text) const -{ - if (fallback != nullptr && ! translations.containsKey (text)) - return fallback->translate (text); - - return translations.getValue (text, text); -} - -String LocalisedStrings::translate (const String& text, const String& resultIfNotFound) const -{ - if (fallback != nullptr && ! translations.containsKey (text)) - return fallback->translate (text, resultIfNotFound); - - return translations.getValue (text, resultIfNotFound); -} - -namespace -{ - #if JUCE_CHECK_MEMORY_LEAKS - // By using this object to force a LocalisedStrings object to be created - // before the currentMappings object, we can force the static order-of-destruction to - // delete the currentMappings object first, which avoids a bogus leak warning. - // (Oddly, just creating a LocalisedStrings on the stack doesn't work in gcc, it - // has to be created with 'new' for this to work..) - struct LeakAvoidanceTrick - { - LeakAvoidanceTrick() - { - const ScopedPointer dummy (new LocalisedStrings (String(), false)); - } - }; - - LeakAvoidanceTrick leakAvoidanceTrick; - #endif - - SpinLock currentMappingsLock; - ScopedPointer currentMappings; - - static int findCloseQuote (const String& text, int startPos) - { - juce_wchar lastChar = 0; - String::CharPointerType t (text.getCharPointer() + startPos); - - for (;;) - { - const juce_wchar c = t.getAndAdvance(); - - if (c == 0 || (c == '"' && lastChar != '\\')) - break; - - lastChar = c; - ++startPos; - } - - return startPos; - } - - static String unescapeString (const String& s) - { - return s.replace ("\\\"", "\"") - .replace ("\\\'", "\'") - .replace ("\\t", "\t") - .replace ("\\r", "\r") - .replace ("\\n", "\n"); - } -} - -void LocalisedStrings::loadFromText (const String& fileContents, bool ignoreCase) -{ - translations.setIgnoresCase (ignoreCase); - - StringArray lines; - lines.addLines (fileContents); - - for (int i = 0; i < lines.size(); ++i) - { - String line (lines[i].trim()); - - if (line.startsWithChar ('"')) - { - int closeQuote = findCloseQuote (line, 1); - - const String originalText (unescapeString (line.substring (1, closeQuote))); - - if (originalText.isNotEmpty()) - { - const int openingQuote = findCloseQuote (line, closeQuote + 1); - closeQuote = findCloseQuote (line, openingQuote + 1); - - const String newText (unescapeString (line.substring (openingQuote + 1, closeQuote))); - - if (newText.isNotEmpty()) - translations.set (originalText, newText); - } - } - else if (line.startsWithIgnoreCase ("language:")) - { - languageName = line.substring (9).trim(); - } - else if (line.startsWithIgnoreCase ("countries:")) - { - countryCodes.addTokens (line.substring (10).trim(), true); - countryCodes.trim(); - countryCodes.removeEmptyStrings(); - } - } - - translations.minimiseStorageOverheads(); -} - -void LocalisedStrings::addStrings (const LocalisedStrings& other) -{ - jassert (languageName == other.languageName); - jassert (countryCodes == other.countryCodes); - - translations.addArray (other.translations); -} - -void LocalisedStrings::setFallback (LocalisedStrings* f) -{ - fallback = f; -} - -//============================================================================== -void LocalisedStrings::setCurrentMappings (LocalisedStrings* newTranslations) -{ - const SpinLock::ScopedLockType sl (currentMappingsLock); - currentMappings = newTranslations; -} - -LocalisedStrings* LocalisedStrings::getCurrentMappings() -{ - return currentMappings; -} - -String LocalisedStrings::translateWithCurrentMappings (const String& text) { return juce::translate (text); } -String LocalisedStrings::translateWithCurrentMappings (const char* text) { return juce::translate (text); } - -JUCE_API String translate (const String& text) { return juce::translate (text, text); } -JUCE_API String translate (const char* text) { return juce::translate (String (text)); } -JUCE_API String translate (CharPointer_UTF8 text) { return juce::translate (String (text)); } - -JUCE_API String translate (const String& text, const String& resultIfNotFound) -{ - const SpinLock::ScopedLockType sl (currentMappingsLock); - - if (const LocalisedStrings* const mappings = LocalisedStrings::getCurrentMappings()) - return mappings->translate (text, resultIfNotFound); - - return resultIfNotFound; -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/text/juce_LocalisedStrings.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/text/juce_LocalisedStrings.h deleted file mode 100644 index a594919b84..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/text/juce_LocalisedStrings.h +++ /dev/null @@ -1,247 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_LOCALISEDSTRINGS_H_INCLUDED -#define JUCE_LOCALISEDSTRINGS_H_INCLUDED - - -//============================================================================== -/** - Used to convert strings to localised foreign-language versions. - - This is basically a look-up table of strings and their translated equivalents. - It can be loaded from a text file, so that you can supply a set of localised - versions of strings that you use in your app. - - To use it in your code, simply call the translate() method on each string that - might have foreign versions, and if none is found, the method will just return - the original string. - - The translation file should start with some lines specifying a description of - the language it contains, and also a list of ISO country codes where it might - be appropriate to use the file. After that, each line of the file should contain - a pair of quoted strings with an '=' sign. - - E.g. for a french translation, the file might be: - - @code - language: French - countries: fr be mc ch lu - - "hello" = "bonjour" - "goodbye" = "au revoir" - @endcode - - If the strings need to contain a quote character, they can use '\"' instead, and - if the first non-whitespace character on a line isn't a quote, then it's ignored, - (you can use this to add comments). - - Note that this is a singleton class, so don't create or destroy the object directly. - There's also a TRANS(text) macro defined to make it easy to use the this. - - E.g. @code - printSomething (TRANS("hello")); - @endcode - - This macro is used in the Juce classes themselves, so your application has a chance to - intercept and translate any internal Juce text strings that might be shown. (You can easily - get a list of all the messages by searching for the TRANS() macro in the Juce source - code). -*/ -class JUCE_API LocalisedStrings -{ -public: - //============================================================================== - /** Creates a set of translations from the text of a translation file. - - When you create one of these, you can call setCurrentMappings() to make it - the set of mappings that the system's using. - */ - LocalisedStrings (const String& fileContents, bool ignoreCaseOfKeys); - - /** Creates a set of translations from a file. - - When you create one of these, you can call setCurrentMappings() to make it - the set of mappings that the system's using. - */ - LocalisedStrings (const File& fileToLoad, bool ignoreCaseOfKeys); - - LocalisedStrings (const LocalisedStrings&); - LocalisedStrings& operator= (const LocalisedStrings&); - - /** Destructor. */ - ~LocalisedStrings(); - - //============================================================================== - /** Selects the current set of mappings to be used by the system. - - The object you pass in will be automatically deleted when no longer needed, so - don't keep a pointer to it. You can also pass in nullptr to remove the current - mappings. - - See also the TRANS() macro, which uses the current set to do its translation. - - @see translateWithCurrentMappings - */ - static void setCurrentMappings (LocalisedStrings* newTranslations); - - /** Returns the currently selected set of mappings. - - This is the object that was last passed to setCurrentMappings(). It may - be nullptr if none has been created. - */ - static LocalisedStrings* getCurrentMappings(); - - /** Tries to translate a string using the currently selected set of mappings. - - If no mapping has been set, or if the mapping doesn't contain a translation - for the string, this will just return the original string. - - See also the TRANS() macro, which uses this method to do its translation. - - @see setCurrentMappings, getCurrentMappings - */ - static String translateWithCurrentMappings (const String& text); - - /** Tries to translate a string using the currently selected set of mappings. - - If no mapping has been set, or if the mapping doesn't contain a translation - for the string, this will just return the original string. - - See also the TRANS() macro, which uses this method to do its translation. - - @see setCurrentMappings, getCurrentMappings - */ - static String translateWithCurrentMappings (const char* text); - - //============================================================================== - /** Attempts to look up a string and return its localised version. - If the string isn't found in the list, the original string will be returned. - */ - String translate (const String& text) const; - - /** Attempts to look up a string and return its localised version. - If the string isn't found in the list, the resultIfNotFound string will be returned. - */ - String translate (const String& text, const String& resultIfNotFound) const; - - /** Returns the name of the language specified in the translation file. - - This is specified in the file using a line starting with "language:", e.g. - @code - language: german - @endcode - */ - String getLanguageName() const { return languageName; } - - /** Returns the list of suitable country codes listed in the translation file. - - These is specified in the file using a line starting with "countries:", e.g. - @code - countries: fr be mc ch lu - @endcode - - The country codes are supposed to be 2-character ISO complient codes. - */ - const StringArray& getCountryCodes() const { return countryCodes; } - - /** Provides access to the actual list of mappings. */ - const StringPairArray& getMappings() const { return translations; } - - //============================================================================== - /** Adds and merges another set of translations into this set. - - Note that the language name and country codes of the new LocalisedStrings - object must match that of this object - an assertion will be thrown if they - don't match. - - Any existing values will have their mappings overwritten by the new ones. - */ - void addStrings (const LocalisedStrings&); - - /** Gives this object a set of strings to use as a fallback if a string isn't found. - The object that is passed-in will be owned and deleted by this object - when no longer needed. It can be nullptr to clear the existing fallback object. - */ - void setFallback (LocalisedStrings* fallbackStrings); - -private: - //============================================================================== - String languageName; - StringArray countryCodes; - StringPairArray translations; - ScopedPointer fallback; - friend struct ContainerDeletePolicy; - - void loadFromText (const String&, bool ignoreCase); - - JUCE_LEAK_DETECTOR (LocalisedStrings) -}; - -//============================================================================== -#ifndef TRANS - /** Uses the LocalisedStrings class to translate the given string literal. - This macro is provided for backwards-compatibility, and just calls the translate() - function. In new code, it's recommended that you just call translate() directly - instead, and avoid using macros. - @see translate(), LocalisedStrings - */ - #define TRANS(stringLiteral) juce::translate (stringLiteral) -#endif - -/** A dummy version of the TRANS macro, used to indicate a string literal that should be - added to the translation file by source-code scanner tools. - - Wrapping a string literal in this macro has no effect, but by using it around strings - that your app needs to translate at a later stage, it lets automatic code-scanning tools - find this string and add it to the list of strings that need translation. -*/ -#define NEEDS_TRANS(stringLiteral) (stringLiteral) - -/** Uses the LocalisedStrings class to translate the given string literal. - @see LocalisedStrings -*/ -JUCE_API String translate (const String& stringLiteral); - -/** Uses the LocalisedStrings class to translate the given string literal. - @see LocalisedStrings -*/ -JUCE_API String translate (const char* stringLiteral); - -/** Uses the LocalisedStrings class to translate the given string literal. - @see LocalisedStrings -*/ -JUCE_API String translate (CharPointer_UTF8 stringLiteral); - -/** Uses the LocalisedStrings class to translate the given string literal. - @see LocalisedStrings -*/ -JUCE_API String translate (const String& stringLiteral, const String& resultIfNotFound); - - -#endif // JUCE_LOCALISEDSTRINGS_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/text/juce_NewLine.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/text/juce_NewLine.h deleted file mode 100644 index 980ac23cff..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/text/juce_NewLine.h +++ /dev/null @@ -1,86 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_NEWLINE_H_INCLUDED -#define JUCE_NEWLINE_H_INCLUDED - - -//============================================================================== -/** This class is used for represent a new-line character sequence. - - To write a new-line to a stream, you can use the predefined 'newLine' variable, e.g. - @code - myOutputStream << "Hello World" << newLine << newLine; - @endcode - - The exact character sequence that will be used for the new-line can be set and - retrieved with OutputStream::setNewLineString() and OutputStream::getNewLineString(). -*/ -class JUCE_API NewLine -{ -public: - /** Returns the default new-line sequence that the library uses. - @see OutputStream::setNewLineString() - */ - static const char* getDefault() noexcept { return "\r\n"; } - - /** Returns the default new-line sequence that the library uses. - @see getDefault() - */ - operator String() const { return getDefault(); } - - /** Returns the default new-line sequence that the library uses. - @see OutputStream::setNewLineString() - */ - operator StringRef() const noexcept { return getDefault(); } -}; - -//============================================================================== -/** A predefined object representing a new-line, which can be written to a string or stream. - - To write a new-line to a stream, you can use the predefined 'newLine' variable like this: - @code - myOutputStream << "Hello World" << newLine << newLine; - @endcode -*/ -extern NewLine newLine; - -//============================================================================== -/** Writes a new-line sequence to a string. - You can use the predefined object 'newLine' to invoke this, e.g. - @code - myString << "Hello World" << newLine << newLine; - @endcode -*/ -JUCE_API String& JUCE_CALLTYPE operator<< (String& string1, const NewLine&); - -#if JUCE_STRING_UTF_TYPE != 8 && ! defined (DOXYGEN) - inline String operator+ (String s1, const NewLine&) { return s1 += NewLine::getDefault(); } -#endif - -#endif // JUCE_NEWLINE_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/text/juce_String.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/text/juce_String.cpp deleted file mode 100644 index 1dce723099..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/text/juce_String.cpp +++ /dev/null @@ -1,2543 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#if JUCE_MSVC - #pragma warning (push) - #pragma warning (disable: 4514 4996) -#endif - -NewLine newLine; - -#if defined (JUCE_STRINGS_ARE_UNICODE) && ! JUCE_STRINGS_ARE_UNICODE - #error "JUCE_STRINGS_ARE_UNICODE is deprecated! All strings are now unicode by default." -#endif - -#if JUCE_NATIVE_WCHAR_IS_UTF8 - typedef CharPointer_UTF8 CharPointer_wchar_t; -#elif JUCE_NATIVE_WCHAR_IS_UTF16 - typedef CharPointer_UTF16 CharPointer_wchar_t; -#else - typedef CharPointer_UTF32 CharPointer_wchar_t; -#endif - -static inline CharPointer_wchar_t castToCharPointer_wchar_t (const void* t) noexcept -{ - return CharPointer_wchar_t (static_cast (t)); -} - -//============================================================================== -// (Mirrors the structure of StringHolder, but without the atomic member, so can be statically constructed) -struct EmptyString -{ - int refCount; - size_t allocatedBytes; - String::CharPointerType::CharType text; -}; - -static const EmptyString emptyString = { 0x3fffffff, sizeof (String::CharPointerType::CharType), 0 }; - -//============================================================================== -class StringHolder -{ -public: - StringHolder() JUCE_DELETED_FUNCTION; - - typedef String::CharPointerType CharPointerType; - typedef String::CharPointerType::CharType CharType; - - //============================================================================== - static CharPointerType createUninitialisedBytes (size_t numBytes) - { - numBytes = (numBytes + 3) & ~(size_t) 3; - StringHolder* const s = reinterpret_cast (new char [sizeof (StringHolder) - sizeof (CharType) + numBytes]); - s->refCount.value = 0; - s->allocatedNumBytes = numBytes; - return CharPointerType (s->text); - } - - template - static CharPointerType createFromCharPointer (const CharPointer text) - { - if (text.getAddress() == nullptr || text.isEmpty()) - return CharPointerType (&(emptyString.text)); - - CharPointer t (text); - size_t bytesNeeded = sizeof (CharType); - - while (! t.isEmpty()) - bytesNeeded += CharPointerType::getBytesRequiredFor (t.getAndAdvance()); - - const CharPointerType dest (createUninitialisedBytes (bytesNeeded)); - CharPointerType (dest).writeAll (text); - return dest; - } - - template - static CharPointerType createFromCharPointer (const CharPointer text, size_t maxChars) - { - if (text.getAddress() == nullptr || text.isEmpty() || maxChars == 0) - return CharPointerType (&(emptyString.text)); - - CharPointer end (text); - size_t numChars = 0; - size_t bytesNeeded = sizeof (CharType); - - while (numChars < maxChars && ! end.isEmpty()) - { - bytesNeeded += CharPointerType::getBytesRequiredFor (end.getAndAdvance()); - ++numChars; - } - - const CharPointerType dest (createUninitialisedBytes (bytesNeeded)); - CharPointerType (dest).writeWithCharLimit (text, (int) numChars + 1); - return dest; - } - - template - static CharPointerType createFromCharPointer (const CharPointer start, const CharPointer end) - { - if (start.getAddress() == nullptr || start.isEmpty()) - return CharPointerType (&(emptyString.text)); - - CharPointer e (start); - int numChars = 0; - size_t bytesNeeded = sizeof (CharType); - - while (e < end && ! e.isEmpty()) - { - bytesNeeded += CharPointerType::getBytesRequiredFor (e.getAndAdvance()); - ++numChars; - } - - const CharPointerType dest (createUninitialisedBytes (bytesNeeded)); - CharPointerType (dest).writeWithCharLimit (start, numChars + 1); - return dest; - } - - static CharPointerType createFromCharPointer (const CharPointerType start, const CharPointerType end) - { - if (start.getAddress() == nullptr || start.isEmpty()) - return CharPointerType (&(emptyString.text)); - - const size_t numBytes = (size_t) (reinterpret_cast (end.getAddress()) - - reinterpret_cast (start.getAddress())); - const CharPointerType dest (createUninitialisedBytes (numBytes + sizeof (CharType))); - memcpy (dest.getAddress(), start, numBytes); - dest.getAddress()[numBytes / sizeof (CharType)] = 0; - return dest; - } - - static CharPointerType createFromFixedLength (const char* const src, const size_t numChars) - { - const CharPointerType dest (createUninitialisedBytes (numChars * sizeof (CharType) + sizeof (CharType))); - CharPointerType (dest).writeWithCharLimit (CharPointer_UTF8 (src), (int) (numChars + 1)); - return dest; - } - - //============================================================================== - static void retain (const CharPointerType text) noexcept - { - StringHolder* const b = bufferFromText (text); - - if (b != (StringHolder*) &emptyString) - ++(b->refCount); - } - - static inline void release (StringHolder* const b) noexcept - { - if (b != (StringHolder*) &emptyString) - if (--(b->refCount) == -1) - delete[] reinterpret_cast (b); - } - - static void release (const CharPointerType text) noexcept - { - release (bufferFromText (text)); - } - - static inline int getReferenceCount (const CharPointerType text) noexcept - { - return bufferFromText (text)->refCount.get() + 1; - } - - //============================================================================== - static CharPointerType makeUniqueWithByteSize (const CharPointerType text, size_t numBytes) - { - StringHolder* const b = bufferFromText (text); - - if (b == (StringHolder*) &emptyString) - { - CharPointerType newText (createUninitialisedBytes (numBytes)); - newText.writeNull(); - return newText; - } - - if (b->allocatedNumBytes >= numBytes && b->refCount.get() <= 0) - return text; - - CharPointerType newText (createUninitialisedBytes (jmax (b->allocatedNumBytes, numBytes))); - memcpy (newText.getAddress(), text.getAddress(), b->allocatedNumBytes); - release (b); - - return newText; - } - - static size_t getAllocatedNumBytes (const CharPointerType text) noexcept - { - return bufferFromText (text)->allocatedNumBytes; - } - - //============================================================================== - Atomic refCount; - size_t allocatedNumBytes; - CharType text[1]; - -private: - static inline StringHolder* bufferFromText (const CharPointerType text) noexcept - { - // (Can't use offsetof() here because of warnings about this not being a POD) - return reinterpret_cast (reinterpret_cast (text.getAddress()) - - (reinterpret_cast (reinterpret_cast (1)->text) - 1)); - } - - void compileTimeChecks() - { - // Let me know if any of these assertions fail on your system! - #if JUCE_NATIVE_WCHAR_IS_UTF8 - static_jassert (sizeof (wchar_t) == 1); - #elif JUCE_NATIVE_WCHAR_IS_UTF16 - static_jassert (sizeof (wchar_t) == 2); - #elif JUCE_NATIVE_WCHAR_IS_UTF32 - static_jassert (sizeof (wchar_t) == 4); - #else - #error "native wchar_t size is unknown" - #endif - - static_jassert (sizeof (EmptyString) == sizeof (StringHolder)); - } -}; - -const String String::empty; - -//============================================================================== -String::String() noexcept : text (&(emptyString.text)) -{ -} - -String::~String() noexcept -{ - StringHolder::release (text); -} - -String::String (const String& other) noexcept : text (other.text) -{ - StringHolder::retain (text); -} - -void String::swapWith (String& other) noexcept -{ - std::swap (text, other.text); -} - -void String::clear() noexcept -{ - StringHolder::release (text); - text = &(emptyString.text); -} - -String& String::operator= (const String& other) noexcept -{ - StringHolder::retain (other.text); - StringHolder::release (text.atomicSwap (other.text)); - return *this; -} - -#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS -String::String (String&& other) noexcept : text (other.text) -{ - other.text = &(emptyString.text); -} - -String& String::operator= (String&& other) noexcept -{ - std::swap (text, other.text); - return *this; -} -#endif - -inline String::PreallocationBytes::PreallocationBytes (const size_t num) noexcept : numBytes (num) {} - -String::String (const PreallocationBytes& preallocationSize) - : text (StringHolder::createUninitialisedBytes (preallocationSize.numBytes + sizeof (CharPointerType::CharType))) -{ -} - -void String::preallocateBytes (const size_t numBytesNeeded) -{ - text = StringHolder::makeUniqueWithByteSize (text, numBytesNeeded + sizeof (CharPointerType::CharType)); -} - -int String::getReferenceCount() const noexcept -{ - return StringHolder::getReferenceCount (text); -} - -//============================================================================== -String::String (const char* const t) - : text (StringHolder::createFromCharPointer (CharPointer_ASCII (t))) -{ - /* If you get an assertion here, then you're trying to create a string from 8-bit data - that contains values greater than 127. These can NOT be correctly converted to unicode - because there's no way for the String class to know what encoding was used to - create them. The source data could be UTF-8, ASCII or one of many local code-pages. - - To get around this problem, you must be more explicit when you pass an ambiguous 8-bit - string to the String class - so for example if your source data is actually UTF-8, - you'd call String (CharPointer_UTF8 ("my utf8 string..")), and it would be able to - correctly convert the multi-byte characters to unicode. It's *highly* recommended that - you use UTF-8 with escape characters in your source code to represent extended characters, - because there's no other way to represent these strings in a way that isn't dependent on - the compiler, source code editor and platform. - - Note that the Introjucer has a handy string literal generator utility that will convert - any unicode string to a valid C++ string literal, creating ascii escape sequences that will - work in any compiler. - */ - jassert (t == nullptr || CharPointer_ASCII::isValidString (t, std::numeric_limits::max())); -} - -String::String (const char* const t, const size_t maxChars) - : text (StringHolder::createFromCharPointer (CharPointer_ASCII (t), maxChars)) -{ - /* If you get an assertion here, then you're trying to create a string from 8-bit data - that contains values greater than 127. These can NOT be correctly converted to unicode - because there's no way for the String class to know what encoding was used to - create them. The source data could be UTF-8, ASCII or one of many local code-pages. - - To get around this problem, you must be more explicit when you pass an ambiguous 8-bit - string to the String class - so for example if your source data is actually UTF-8, - you'd call String (CharPointer_UTF8 ("my utf8 string..")), and it would be able to - correctly convert the multi-byte characters to unicode. It's *highly* recommended that - you use UTF-8 with escape characters in your source code to represent extended characters, - because there's no other way to represent these strings in a way that isn't dependent on - the compiler, source code editor and platform. - - Note that the Introjucer has a handy string literal generator utility that will convert - any unicode string to a valid C++ string literal, creating ascii escape sequences that will - work in any compiler. - */ - jassert (t == nullptr || CharPointer_ASCII::isValidString (t, (int) maxChars)); -} - -String::String (const wchar_t* const t) : text (StringHolder::createFromCharPointer (castToCharPointer_wchar_t (t))) {} -String::String (const CharPointer_UTF8 t) : text (StringHolder::createFromCharPointer (t)) {} -String::String (const CharPointer_UTF16 t) : text (StringHolder::createFromCharPointer (t)) {} -String::String (const CharPointer_UTF32 t) : text (StringHolder::createFromCharPointer (t)) {} -String::String (const CharPointer_ASCII t) : text (StringHolder::createFromCharPointer (t)) {} - -String::String (const CharPointer_UTF8 t, const size_t maxChars) : text (StringHolder::createFromCharPointer (t, maxChars)) {} -String::String (const CharPointer_UTF16 t, const size_t maxChars) : text (StringHolder::createFromCharPointer (t, maxChars)) {} -String::String (const CharPointer_UTF32 t, const size_t maxChars) : text (StringHolder::createFromCharPointer (t, maxChars)) {} -String::String (const wchar_t* const t, size_t maxChars) : text (StringHolder::createFromCharPointer (castToCharPointer_wchar_t (t), maxChars)) {} - -String::String (const CharPointer_UTF8 start, const CharPointer_UTF8 end) : text (StringHolder::createFromCharPointer (start, end)) {} -String::String (const CharPointer_UTF16 start, const CharPointer_UTF16 end) : text (StringHolder::createFromCharPointer (start, end)) {} -String::String (const CharPointer_UTF32 start, const CharPointer_UTF32 end) : text (StringHolder::createFromCharPointer (start, end)) {} - -String::String (const std::string& s) : text (StringHolder::createFromFixedLength (s.data(), s.size())) {} - -String String::charToString (const juce_wchar character) -{ - String result (PreallocationBytes (CharPointerType::getBytesRequiredFor (character))); - CharPointerType t (result.text); - t.write (character); - t.writeNull(); - return result; -} - -//============================================================================== -namespace NumberToStringConverters -{ - enum - { - charsNeededForInt = 32, - charsNeededForDouble = 48 - }; - - template - static char* printDigits (char* t, Type v) noexcept - { - *--t = 0; - - do - { - *--t = '0' + (char) (v % 10); - v /= 10; - - } while (v > 0); - - return t; - } - - // pass in a pointer to the END of a buffer.. - static char* numberToString (char* t, const int64 n) noexcept - { - if (n >= 0) - return printDigits (t, static_cast (n)); - - // NB: this needs to be careful not to call -std::numeric_limits::min(), - // which has undefined behaviour - t = printDigits (t, static_cast (-(n + 1)) + 1); - *--t = '-'; - return t; - } - - static char* numberToString (char* t, uint64 v) noexcept - { - return printDigits (t, v); - } - - static char* numberToString (char* t, const int n) noexcept - { - if (n >= 0) - return printDigits (t, static_cast (n)); - - // NB: this needs to be careful not to call -std::numeric_limits::min(), - // which has undefined behaviour - t = printDigits (t, static_cast (-(n + 1)) + 1); - *--t = '-'; - return t; - } - - static char* numberToString (char* t, unsigned int v) noexcept - { - return printDigits (t, v); - } - - struct StackArrayStream : public std::basic_streambuf > - { - explicit StackArrayStream (char* d) - { - static const std::locale classicLocale (std::locale::classic()); - imbue (classicLocale); - setp (d, d + charsNeededForDouble); - } - - size_t writeDouble (double n, int numDecPlaces) - { - { - std::ostream o (this); - - if (numDecPlaces > 0) - o.precision ((std::streamsize) numDecPlaces); - - o << n; - } - - return (size_t) (pptr() - pbase()); - } - }; - - static char* doubleToString (char* buffer, const int numChars, double n, int numDecPlaces, size_t& len) noexcept - { - if (numDecPlaces > 0 && numDecPlaces < 7 && n > -1.0e20 && n < 1.0e20) - { - char* const end = buffer + numChars; - char* t = end; - int64 v = (int64) (pow (10.0, numDecPlaces) * std::abs (n) + 0.5); - *--t = (char) 0; - - while (numDecPlaces >= 0 || v > 0) - { - if (numDecPlaces == 0) - *--t = '.'; - - *--t = (char) ('0' + (v % 10)); - - v /= 10; - --numDecPlaces; - } - - if (n < 0) - *--t = '-'; - - len = (size_t) (end - t - 1); - return t; - } - - StackArrayStream strm (buffer); - len = strm.writeDouble (n, numDecPlaces); - jassert (len <= charsNeededForDouble); - return buffer; - } - - template - static String::CharPointerType createFromInteger (const IntegerType number) - { - char buffer [charsNeededForInt]; - char* const end = buffer + numElementsInArray (buffer); - char* const start = numberToString (end, number); - return StringHolder::createFromFixedLength (start, (size_t) (end - start - 1)); - } - - static String::CharPointerType createFromDouble (const double number, const int numberOfDecimalPlaces) - { - char buffer [charsNeededForDouble]; - size_t len; - char* const start = doubleToString (buffer, numElementsInArray (buffer), (double) number, numberOfDecimalPlaces, len); - return StringHolder::createFromFixedLength (start, len); - } -} - -//============================================================================== -String::String (const int number) : text (NumberToStringConverters::createFromInteger (number)) {} -String::String (const unsigned int number) : text (NumberToStringConverters::createFromInteger (number)) {} -String::String (const short number) : text (NumberToStringConverters::createFromInteger ((int) number)) {} -String::String (const unsigned short number) : text (NumberToStringConverters::createFromInteger ((unsigned int) number)) {} -String::String (const int64 number) : text (NumberToStringConverters::createFromInteger (number)) {} -String::String (const uint64 number) : text (NumberToStringConverters::createFromInteger (number)) {} - -String::String (const float number) : text (NumberToStringConverters::createFromDouble ((double) number, 0)) {} -String::String (const double number) : text (NumberToStringConverters::createFromDouble (number, 0)) {} -String::String (const float number, const int numberOfDecimalPlaces) : text (NumberToStringConverters::createFromDouble ((double) number, numberOfDecimalPlaces)) {} -String::String (const double number, const int numberOfDecimalPlaces) : text (NumberToStringConverters::createFromDouble (number, numberOfDecimalPlaces)) {} - -//============================================================================== -int String::length() const noexcept -{ - return (int) text.length(); -} - -static size_t findByteOffsetOfEnd (String::CharPointerType text) noexcept -{ - return (size_t) (((char*) text.findTerminatingNull().getAddress()) - (char*) text.getAddress()); -} - -size_t String::getByteOffsetOfEnd() const noexcept -{ - return findByteOffsetOfEnd (text); -} - -juce_wchar String::operator[] (int index) const noexcept -{ - jassert (index == 0 || (index > 0 && index <= (int) text.lengthUpTo ((size_t) index + 1))); - return text [index]; -} - -template -struct HashGenerator -{ - template - static Type calculate (CharPointer t) noexcept - { - Type result = Type(); - - while (! t.isEmpty()) - result = ((Type) multiplier) * result + (Type) t.getAndAdvance(); - - return result; - } - - enum { multiplier = sizeof (Type) > 4 ? 101 : 31 }; -}; - -int String::hashCode() const noexcept { return HashGenerator ::calculate (text); } -int64 String::hashCode64() const noexcept { return HashGenerator ::calculate (text); } -std::size_t String::hash() const noexcept { return HashGenerator::calculate (text); } - -//============================================================================== -JUCE_API bool JUCE_CALLTYPE operator== (const String& s1, const String& s2) noexcept { return s1.compare (s2) == 0; } -JUCE_API bool JUCE_CALLTYPE operator!= (const String& s1, const String& s2) noexcept { return s1.compare (s2) != 0; } -JUCE_API bool JUCE_CALLTYPE operator== (const String& s1, const char* s2) noexcept { return s1.compare (s2) == 0; } -JUCE_API bool JUCE_CALLTYPE operator!= (const String& s1, const char* s2) noexcept { return s1.compare (s2) != 0; } -JUCE_API bool JUCE_CALLTYPE operator== (const String& s1, const wchar_t* s2) noexcept { return s1.compare (s2) == 0; } -JUCE_API bool JUCE_CALLTYPE operator!= (const String& s1, const wchar_t* s2) noexcept { return s1.compare (s2) != 0; } -JUCE_API bool JUCE_CALLTYPE operator== (const String& s1, StringRef s2) noexcept { return s1.getCharPointer().compare (s2.text) == 0; } -JUCE_API bool JUCE_CALLTYPE operator!= (const String& s1, StringRef s2) noexcept { return s1.getCharPointer().compare (s2.text) != 0; } -JUCE_API bool JUCE_CALLTYPE operator== (const String& s1, const CharPointer_UTF8 s2) noexcept { return s1.getCharPointer().compare (s2) == 0; } -JUCE_API bool JUCE_CALLTYPE operator!= (const String& s1, const CharPointer_UTF8 s2) noexcept { return s1.getCharPointer().compare (s2) != 0; } -JUCE_API bool JUCE_CALLTYPE operator== (const String& s1, const CharPointer_UTF16 s2) noexcept { return s1.getCharPointer().compare (s2) == 0; } -JUCE_API bool JUCE_CALLTYPE operator!= (const String& s1, const CharPointer_UTF16 s2) noexcept { return s1.getCharPointer().compare (s2) != 0; } -JUCE_API bool JUCE_CALLTYPE operator== (const String& s1, const CharPointer_UTF32 s2) noexcept { return s1.getCharPointer().compare (s2) == 0; } -JUCE_API bool JUCE_CALLTYPE operator!= (const String& s1, const CharPointer_UTF32 s2) noexcept { return s1.getCharPointer().compare (s2) != 0; } -JUCE_API bool JUCE_CALLTYPE operator> (const String& s1, const String& s2) noexcept { return s1.compare (s2) > 0; } -JUCE_API bool JUCE_CALLTYPE operator< (const String& s1, const String& s2) noexcept { return s1.compare (s2) < 0; } -JUCE_API bool JUCE_CALLTYPE operator>= (const String& s1, const String& s2) noexcept { return s1.compare (s2) >= 0; } -JUCE_API bool JUCE_CALLTYPE operator<= (const String& s1, const String& s2) noexcept { return s1.compare (s2) <= 0; } - -bool String::equalsIgnoreCase (const wchar_t* const t) const noexcept -{ - return t != nullptr ? text.compareIgnoreCase (castToCharPointer_wchar_t (t)) == 0 - : isEmpty(); -} - -bool String::equalsIgnoreCase (const char* const t) const noexcept -{ - return t != nullptr ? text.compareIgnoreCase (CharPointer_UTF8 (t)) == 0 - : isEmpty(); -} - -bool String::equalsIgnoreCase (StringRef t) const noexcept -{ - return text.compareIgnoreCase (t.text) == 0; -} - -bool String::equalsIgnoreCase (const String& other) const noexcept -{ - return text == other.text - || text.compareIgnoreCase (other.text) == 0; -} - -int String::compare (const String& other) const noexcept { return (text == other.text) ? 0 : text.compare (other.text); } -int String::compare (const char* const other) const noexcept { return text.compare (CharPointer_UTF8 (other)); } -int String::compare (const wchar_t* const other) const noexcept { return text.compare (castToCharPointer_wchar_t (other)); } -int String::compareIgnoreCase (const String& other) const noexcept { return (text == other.text) ? 0 : text.compareIgnoreCase (other.text); } - -static int stringCompareRight (String::CharPointerType s1, String::CharPointerType s2) noexcept -{ - for (int bias = 0;;) - { - const juce_wchar c1 = s1.getAndAdvance(); - const bool isDigit1 = CharacterFunctions::isDigit (c1); - - const juce_wchar c2 = s2.getAndAdvance(); - const bool isDigit2 = CharacterFunctions::isDigit (c2); - - if (! (isDigit1 || isDigit2)) return bias; - if (! isDigit1) return -1; - if (! isDigit2) return 1; - - if (c1 != c2 && bias == 0) - bias = c1 < c2 ? -1 : 1; - - jassert (c1 != 0 && c2 != 0); - } -} - -static int stringCompareLeft (String::CharPointerType s1, String::CharPointerType s2) noexcept -{ - for (;;) - { - const juce_wchar c1 = s1.getAndAdvance(); - const bool isDigit1 = CharacterFunctions::isDigit (c1); - - const juce_wchar c2 = s2.getAndAdvance(); - const bool isDigit2 = CharacterFunctions::isDigit (c2); - - if (! (isDigit1 || isDigit2)) return 0; - if (! isDigit1) return -1; - if (! isDigit2) return 1; - if (c1 < c2) return -1; - if (c1 > c2) return 1; - } -} - -static int naturalStringCompare (String::CharPointerType s1, String::CharPointerType s2) noexcept -{ - bool firstLoop = true; - - for (;;) - { - const bool hasSpace1 = s1.isWhitespace(); - const bool hasSpace2 = s2.isWhitespace(); - - if ((! firstLoop) && (hasSpace1 ^ hasSpace2)) - return hasSpace2 ? 1 : -1; - - firstLoop = false; - - if (hasSpace1) s1 = s1.findEndOfWhitespace(); - if (hasSpace2) s2 = s2.findEndOfWhitespace(); - - if (s1.isDigit() && s2.isDigit()) - { - const int result = (*s1 == '0' || *s2 == '0') ? stringCompareLeft (s1, s2) - : stringCompareRight (s1, s2); - - if (result != 0) - return result; - } - - juce_wchar c1 = s1.getAndAdvance(); - juce_wchar c2 = s2.getAndAdvance(); - - if (c1 != c2) - { - c1 = CharacterFunctions::toUpperCase (c1); - c2 = CharacterFunctions::toUpperCase (c2); - } - - if (c1 == c2) - { - if (c1 == 0) - return 0; - } - else - { - const bool isAlphaNum1 = CharacterFunctions::isLetterOrDigit (c1); - const bool isAlphaNum2 = CharacterFunctions::isLetterOrDigit (c2); - - if (isAlphaNum2 && ! isAlphaNum1) return -1; - if (isAlphaNum1 && ! isAlphaNum2) return 1; - - return c1 < c2 ? -1 : 1; - } - - jassert (c1 != 0 && c2 != 0); - } -} - -int String::compareNatural (StringRef other) const noexcept -{ - return naturalStringCompare (getCharPointer(), other.text); -} - -//============================================================================== -void String::append (const String& textToAppend, size_t maxCharsToTake) -{ - appendCharPointer (textToAppend.text, maxCharsToTake); -} - -void String::appendCharPointer (const CharPointerType textToAppend) -{ - appendCharPointer (textToAppend, textToAppend.findTerminatingNull()); -} - -void String::appendCharPointer (const CharPointerType startOfTextToAppend, - const CharPointerType endOfTextToAppend) -{ - jassert (startOfTextToAppend.getAddress() != nullptr && endOfTextToAppend.getAddress() != nullptr); - - const int extraBytesNeeded = getAddressDifference (endOfTextToAppend.getAddress(), - startOfTextToAppend.getAddress()); - jassert (extraBytesNeeded >= 0); - - if (extraBytesNeeded > 0) - { - const size_t byteOffsetOfNull = getByteOffsetOfEnd(); - preallocateBytes (byteOffsetOfNull + (size_t) extraBytesNeeded); - - CharPointerType::CharType* const newStringStart = addBytesToPointer (text.getAddress(), (int) byteOffsetOfNull); - memcpy (newStringStart, startOfTextToAppend.getAddress(), (size_t) extraBytesNeeded); - CharPointerType (addBytesToPointer (newStringStart, extraBytesNeeded)).writeNull(); - } -} - -String& String::operator+= (const wchar_t* const t) -{ - appendCharPointer (castToCharPointer_wchar_t (t)); - return *this; -} - -String& String::operator+= (const char* const t) -{ - appendCharPointer (CharPointer_UTF8 (t)); // (using UTF8 here triggers a faster code-path than ascii) - return *this; -} - -String& String::operator+= (const String& other) -{ - if (isEmpty()) - return operator= (other); - - appendCharPointer (other.text); - return *this; -} - -String& String::operator+= (const char ch) -{ - const char asString[] = { ch, 0 }; - return operator+= (asString); -} - -String& String::operator+= (const wchar_t ch) -{ - const wchar_t asString[] = { ch, 0 }; - return operator+= (asString); -} - -#if ! JUCE_NATIVE_WCHAR_IS_UTF32 -String& String::operator+= (const juce_wchar ch) -{ - const juce_wchar asString[] = { ch, 0 }; - appendCharPointer (CharPointer_UTF32 (asString)); - return *this; -} -#endif - -String& String::operator+= (const int number) -{ - char buffer [16]; - char* end = buffer + numElementsInArray (buffer); - char* start = NumberToStringConverters::numberToString (end, number); - - #if (JUCE_STRING_UTF_TYPE == 8) - appendCharPointer (CharPointerType (start), CharPointerType (end)); - #else - appendCharPointer (CharPointer_ASCII (start), CharPointer_ASCII (end)); - #endif - return *this; -} - -String& String::operator+= (int64 number) -{ - char buffer [32]; - char* end = buffer + numElementsInArray (buffer); - char* start = NumberToStringConverters::numberToString (end, number); - - #if (JUCE_STRING_UTF_TYPE == 8) - appendCharPointer (CharPointerType (start), CharPointerType (end)); - #else - appendCharPointer (CharPointer_ASCII (start), CharPointer_ASCII (end)); - #endif - return *this; -} - -//============================================================================== -JUCE_API String JUCE_CALLTYPE operator+ (const char* const s1, const String& s2) { String s (s1); return s += s2; } -JUCE_API String JUCE_CALLTYPE operator+ (const wchar_t* const s1, const String& s2) { String s (s1); return s += s2; } - -JUCE_API String JUCE_CALLTYPE operator+ (const char s1, const String& s2) { return String::charToString ((juce_wchar) (uint8) s1) + s2; } -JUCE_API String JUCE_CALLTYPE operator+ (const wchar_t s1, const String& s2) { return String::charToString (s1) + s2; } - -JUCE_API String JUCE_CALLTYPE operator+ (String s1, const String& s2) { return s1 += s2; } -JUCE_API String JUCE_CALLTYPE operator+ (String s1, const char* const s2) { return s1 += s2; } -JUCE_API String JUCE_CALLTYPE operator+ (String s1, const wchar_t* s2) { return s1 += s2; } - -JUCE_API String JUCE_CALLTYPE operator+ (String s1, const char s2) { return s1 += s2; } -JUCE_API String JUCE_CALLTYPE operator+ (String s1, const wchar_t s2) { return s1 += s2; } - -#if ! JUCE_NATIVE_WCHAR_IS_UTF32 -JUCE_API String JUCE_CALLTYPE operator+ (const juce_wchar s1, const String& s2) { return String::charToString (s1) + s2; } -JUCE_API String JUCE_CALLTYPE operator+ (String s1, const juce_wchar s2) { return s1 += s2; } -JUCE_API String& JUCE_CALLTYPE operator<< (String& s1, const juce_wchar s2) { return s1 += s2; } -#endif - -JUCE_API String& JUCE_CALLTYPE operator<< (String& s1, const char s2) { return s1 += s2; } -JUCE_API String& JUCE_CALLTYPE operator<< (String& s1, const wchar_t s2) { return s1 += s2; } - -JUCE_API String& JUCE_CALLTYPE operator<< (String& s1, const char* const s2) { return s1 += s2; } -JUCE_API String& JUCE_CALLTYPE operator<< (String& s1, const wchar_t* const s2) { return s1 += s2; } -JUCE_API String& JUCE_CALLTYPE operator<< (String& s1, const String& s2) { return s1 += s2; } - -JUCE_API String& JUCE_CALLTYPE operator<< (String& s1, const int number) { return s1 += number; } -JUCE_API String& JUCE_CALLTYPE operator<< (String& s1, const short number) { return s1 += (int) number; } -JUCE_API String& JUCE_CALLTYPE operator<< (String& s1, const long number) { return s1 += (int) number; } -JUCE_API String& JUCE_CALLTYPE operator<< (String& s1, const int64 number) { return s1 += String (number); } -JUCE_API String& JUCE_CALLTYPE operator<< (String& s1, const float number) { return s1 += String (number); } -JUCE_API String& JUCE_CALLTYPE operator<< (String& s1, const double number) { return s1 += String (number); } -JUCE_API String& JUCE_CALLTYPE operator<< (String& s1, const uint64 number) { return s1 += String (number); } - -JUCE_API OutputStream& JUCE_CALLTYPE operator<< (OutputStream& stream, const String& text) -{ - return operator<< (stream, StringRef (text)); -} - -JUCE_API OutputStream& JUCE_CALLTYPE operator<< (OutputStream& stream, StringRef text) -{ - const size_t numBytes = CharPointer_UTF8::getBytesRequiredFor (text.text); - - #if (JUCE_STRING_UTF_TYPE == 8) - stream.write (text.text.getAddress(), numBytes); - #else - // (This avoids using toUTF8() to prevent the memory bloat that it would leave behind - // if lots of large, persistent strings were to be written to streams). - HeapBlock temp (numBytes + 1); - CharPointer_UTF8 (temp).writeAll (text.text); - stream.write (temp, numBytes); - #endif - - return stream; -} - -JUCE_API String& JUCE_CALLTYPE operator<< (String& string1, const NewLine&) -{ - return string1 += NewLine::getDefault(); -} - -//============================================================================== -int String::indexOfChar (const juce_wchar character) const noexcept -{ - return text.indexOf (character); -} - -int String::indexOfChar (const int startIndex, const juce_wchar character) const noexcept -{ - CharPointerType t (text); - - for (int i = 0; ! t.isEmpty(); ++i) - { - if (i >= startIndex) - { - if (t.getAndAdvance() == character) - return i; - } - else - { - ++t; - } - } - - return -1; -} - -int String::lastIndexOfChar (const juce_wchar character) const noexcept -{ - CharPointerType t (text); - int last = -1; - - for (int i = 0; ! t.isEmpty(); ++i) - if (t.getAndAdvance() == character) - last = i; - - return last; -} - -int String::indexOfAnyOf (StringRef charactersToLookFor, const int startIndex, const bool ignoreCase) const noexcept -{ - CharPointerType t (text); - - for (int i = 0; ! t.isEmpty(); ++i) - { - if (i >= startIndex) - { - if (charactersToLookFor.text.indexOf (t.getAndAdvance(), ignoreCase) >= 0) - return i; - } - else - { - ++t; - } - } - - return -1; -} - -int String::indexOf (StringRef other) const noexcept -{ - return other.isEmpty() ? 0 : text.indexOf (other.text); -} - -int String::indexOfIgnoreCase (StringRef other) const noexcept -{ - return other.isEmpty() ? 0 : CharacterFunctions::indexOfIgnoreCase (text, other.text); -} - -int String::indexOf (const int startIndex, StringRef other) const noexcept -{ - if (other.isEmpty()) - return -1; - - CharPointerType t (text); - - for (int i = startIndex; --i >= 0;) - { - if (t.isEmpty()) - return -1; - - ++t; - } - - int found = t.indexOf (other.text); - if (found >= 0) - found += startIndex; - return found; -} - -int String::indexOfIgnoreCase (const int startIndex, StringRef other) const noexcept -{ - if (other.isEmpty()) - return -1; - - CharPointerType t (text); - - for (int i = startIndex; --i >= 0;) - { - if (t.isEmpty()) - return -1; - - ++t; - } - - int found = CharacterFunctions::indexOfIgnoreCase (t, other.text); - if (found >= 0) - found += startIndex; - return found; -} - -int String::lastIndexOf (StringRef other) const noexcept -{ - if (other.isNotEmpty()) - { - const int len = other.length(); - int i = length() - len; - - if (i >= 0) - { - for (CharPointerType n (text + i); i >= 0; --i) - { - if (n.compareUpTo (other.text, len) == 0) - return i; - - --n; - } - } - } - - return -1; -} - -int String::lastIndexOfIgnoreCase (StringRef other) const noexcept -{ - if (other.isNotEmpty()) - { - const int len = other.length(); - int i = length() - len; - - if (i >= 0) - { - for (CharPointerType n (text + i); i >= 0; --i) - { - if (n.compareIgnoreCaseUpTo (other.text, len) == 0) - return i; - - --n; - } - } - } - - return -1; -} - -int String::lastIndexOfAnyOf (StringRef charactersToLookFor, const bool ignoreCase) const noexcept -{ - CharPointerType t (text); - int last = -1; - - for (int i = 0; ! t.isEmpty(); ++i) - if (charactersToLookFor.text.indexOf (t.getAndAdvance(), ignoreCase) >= 0) - last = i; - - return last; -} - -bool String::contains (StringRef other) const noexcept -{ - return indexOf (other) >= 0; -} - -bool String::containsChar (const juce_wchar character) const noexcept -{ - return text.indexOf (character) >= 0; -} - -bool String::containsIgnoreCase (StringRef t) const noexcept -{ - return indexOfIgnoreCase (t) >= 0; -} - -int String::indexOfWholeWord (StringRef word) const noexcept -{ - if (word.isNotEmpty()) - { - CharPointerType t (text); - const int wordLen = word.length(); - const int end = (int) t.length() - wordLen; - - for (int i = 0; i <= end; ++i) - { - if (t.compareUpTo (word.text, wordLen) == 0 - && (i == 0 || ! (t - 1).isLetterOrDigit()) - && ! (t + wordLen).isLetterOrDigit()) - return i; - - ++t; - } - } - - return -1; -} - -int String::indexOfWholeWordIgnoreCase (StringRef word) const noexcept -{ - if (word.isNotEmpty()) - { - CharPointerType t (text); - const int wordLen = word.length(); - const int end = (int) t.length() - wordLen; - - for (int i = 0; i <= end; ++i) - { - if (t.compareIgnoreCaseUpTo (word.text, wordLen) == 0 - && (i == 0 || ! (t - 1).isLetterOrDigit()) - && ! (t + wordLen).isLetterOrDigit()) - return i; - - ++t; - } - } - - return -1; -} - -bool String::containsWholeWord (StringRef wordToLookFor) const noexcept -{ - return indexOfWholeWord (wordToLookFor) >= 0; -} - -bool String::containsWholeWordIgnoreCase (StringRef wordToLookFor) const noexcept -{ - return indexOfWholeWordIgnoreCase (wordToLookFor) >= 0; -} - -//============================================================================== -template -struct WildCardMatcher -{ - static bool matches (CharPointer wildcard, CharPointer test, const bool ignoreCase) noexcept - { - for (;;) - { - const juce_wchar wc = wildcard.getAndAdvance(); - - if (wc == '*') - return wildcard.isEmpty() || matchesAnywhere (wildcard, test, ignoreCase); - - if (! characterMatches (wc, test.getAndAdvance(), ignoreCase)) - return false; - - if (wc == 0) - return true; - } - } - - static bool characterMatches (const juce_wchar wc, const juce_wchar tc, const bool ignoreCase) noexcept - { - return (wc == tc) || (wc == '?' && tc != 0) - || (ignoreCase && CharacterFunctions::toLowerCase (wc) == CharacterFunctions::toLowerCase (tc)); - } - - static bool matchesAnywhere (const CharPointer wildcard, CharPointer test, const bool ignoreCase) noexcept - { - for (; ! test.isEmpty(); ++test) - if (matches (wildcard, test, ignoreCase)) - return true; - - return false; - } -}; - -bool String::matchesWildcard (StringRef wildcard, const bool ignoreCase) const noexcept -{ - return WildCardMatcher::matches (wildcard.text, text, ignoreCase); -} - -//============================================================================== -String String::repeatedString (StringRef stringToRepeat, int numberOfTimesToRepeat) -{ - if (numberOfTimesToRepeat <= 0) - return String(); - - String result (PreallocationBytes (findByteOffsetOfEnd (stringToRepeat) * (size_t) numberOfTimesToRepeat)); - CharPointerType n (result.text); - - while (--numberOfTimesToRepeat >= 0) - n.writeAll (stringToRepeat.text); - - return result; -} - -String String::paddedLeft (const juce_wchar padCharacter, int minimumLength) const -{ - jassert (padCharacter != 0); - - int extraChars = minimumLength; - CharPointerType end (text); - - while (! end.isEmpty()) - { - --extraChars; - ++end; - } - - if (extraChars <= 0 || padCharacter == 0) - return *this; - - const size_t currentByteSize = (size_t) (((char*) end.getAddress()) - (char*) text.getAddress()); - String result (PreallocationBytes (currentByteSize + (size_t) extraChars * CharPointerType::getBytesRequiredFor (padCharacter))); - CharPointerType n (result.text); - - while (--extraChars >= 0) - n.write (padCharacter); - - n.writeAll (text); - return result; -} - -String String::paddedRight (const juce_wchar padCharacter, int minimumLength) const -{ - jassert (padCharacter != 0); - - int extraChars = minimumLength; - CharPointerType end (text); - - while (! end.isEmpty()) - { - --extraChars; - ++end; - } - - if (extraChars <= 0 || padCharacter == 0) - return *this; - - const size_t currentByteSize = (size_t) (((char*) end.getAddress()) - (char*) text.getAddress()); - String result (PreallocationBytes (currentByteSize + (size_t) extraChars * CharPointerType::getBytesRequiredFor (padCharacter))); - CharPointerType n (result.text); - - n.writeAll (text); - - while (--extraChars >= 0) - n.write (padCharacter); - - n.writeNull(); - return result; -} - -//============================================================================== -String String::replaceSection (int index, int numCharsToReplace, StringRef stringToInsert) const -{ - if (index < 0) - { - // a negative index to replace from? - jassertfalse; - index = 0; - } - - if (numCharsToReplace < 0) - { - // replacing a negative number of characters? - numCharsToReplace = 0; - jassertfalse; - } - - CharPointerType insertPoint (text); - - for (int i = 0; i < index; ++i) - { - if (insertPoint.isEmpty()) - { - // replacing beyond the end of the string? - jassertfalse; - return *this + stringToInsert; - } - - ++insertPoint; - } - - CharPointerType startOfRemainder (insertPoint); - - for (int i = 0; i < numCharsToReplace && ! startOfRemainder.isEmpty(); ++i) - ++startOfRemainder; - - if (insertPoint == text && startOfRemainder.isEmpty()) - return stringToInsert.text; - - const size_t initialBytes = (size_t) (((char*) insertPoint.getAddress()) - (char*) text.getAddress()); - const size_t newStringBytes = findByteOffsetOfEnd (stringToInsert); - const size_t remainderBytes = (size_t) (((char*) startOfRemainder.findTerminatingNull().getAddress()) - (char*) startOfRemainder.getAddress()); - - const size_t newTotalBytes = initialBytes + newStringBytes + remainderBytes; - if (newTotalBytes <= 0) - return String(); - - String result (PreallocationBytes ((size_t) newTotalBytes)); - - char* dest = (char*) result.text.getAddress(); - memcpy (dest, text.getAddress(), initialBytes); - dest += initialBytes; - memcpy (dest, stringToInsert.text.getAddress(), newStringBytes); - dest += newStringBytes; - memcpy (dest, startOfRemainder.getAddress(), remainderBytes); - dest += remainderBytes; - CharPointerType ((CharPointerType::CharType*) dest).writeNull(); - - return result; -} - -String String::replace (StringRef stringToReplace, StringRef stringToInsert, const bool ignoreCase) const -{ - const int stringToReplaceLen = stringToReplace.length(); - const int stringToInsertLen = stringToInsert.length(); - - int i = 0; - String result (*this); - - while ((i = (ignoreCase ? result.indexOfIgnoreCase (i, stringToReplace) - : result.indexOf (i, stringToReplace))) >= 0) - { - result = result.replaceSection (i, stringToReplaceLen, stringToInsert); - i += stringToInsertLen; - } - - return result; -} - -class StringCreationHelper -{ -public: - StringCreationHelper (const size_t initialBytes) - : source (nullptr), dest (nullptr), allocatedBytes (initialBytes), bytesWritten (0) - { - result.preallocateBytes (allocatedBytes); - dest = result.getCharPointer(); - } - - StringCreationHelper (const String::CharPointerType s) - : source (s), dest (nullptr), allocatedBytes (StringHolder::getAllocatedNumBytes (s)), bytesWritten (0) - { - result.preallocateBytes (allocatedBytes); - dest = result.getCharPointer(); - } - - void write (juce_wchar c) - { - bytesWritten += String::CharPointerType::getBytesRequiredFor (c); - - if (bytesWritten > allocatedBytes) - { - allocatedBytes += jmax ((size_t) 8, allocatedBytes / 16); - const size_t destOffset = (size_t) (((char*) dest.getAddress()) - (char*) result.getCharPointer().getAddress()); - result.preallocateBytes (allocatedBytes); - dest = addBytesToPointer (result.getCharPointer().getAddress(), (int) destOffset); - } - - dest.write (c); - } - - String result; - String::CharPointerType source; - -private: - String::CharPointerType dest; - size_t allocatedBytes, bytesWritten; -}; - -String String::replaceCharacter (const juce_wchar charToReplace, const juce_wchar charToInsert) const -{ - if (! containsChar (charToReplace)) - return *this; - - StringCreationHelper builder (text); - - for (;;) - { - juce_wchar c = builder.source.getAndAdvance(); - - if (c == charToReplace) - c = charToInsert; - - builder.write (c); - - if (c == 0) - break; - } - - return builder.result; -} - -String String::replaceCharacters (StringRef charactersToReplace, StringRef charactersToInsertInstead) const -{ - StringCreationHelper builder (text); - - for (;;) - { - juce_wchar c = builder.source.getAndAdvance(); - - const int index = charactersToReplace.text.indexOf (c); - if (index >= 0) - c = charactersToInsertInstead [index]; - - builder.write (c); - - if (c == 0) - break; - } - - return builder.result; -} - -//============================================================================== -bool String::startsWith (StringRef other) const noexcept -{ - return text.compareUpTo (other.text, other.length()) == 0; -} - -bool String::startsWithIgnoreCase (StringRef other) const noexcept -{ - return text.compareIgnoreCaseUpTo (other.text, other.length()) == 0; -} - -bool String::startsWithChar (const juce_wchar character) const noexcept -{ - jassert (character != 0); // strings can't contain a null character! - - return *text == character; -} - -bool String::endsWithChar (const juce_wchar character) const noexcept -{ - jassert (character != 0); // strings can't contain a null character! - - if (text.isEmpty()) - return false; - - CharPointerType t (text.findTerminatingNull()); - return *--t == character; -} - -bool String::endsWith (StringRef other) const noexcept -{ - CharPointerType end (text.findTerminatingNull()); - CharPointerType otherEnd (other.text.findTerminatingNull()); - - while (end > text && otherEnd > other.text) - { - --end; - --otherEnd; - - if (*end != *otherEnd) - return false; - } - - return otherEnd == other.text; -} - -bool String::endsWithIgnoreCase (StringRef other) const noexcept -{ - CharPointerType end (text.findTerminatingNull()); - CharPointerType otherEnd (other.text.findTerminatingNull()); - - while (end > text && otherEnd > other.text) - { - --end; - --otherEnd; - - if (end.toLowerCase() != otherEnd.toLowerCase()) - return false; - } - - return otherEnd == other.text; -} - -//============================================================================== -String String::toUpperCase() const -{ - StringCreationHelper builder (text); - - for (;;) - { - const juce_wchar c = builder.source.toUpperCase(); - builder.write (c); - - if (c == 0) - break; - - ++(builder.source); - } - - return builder.result; -} - -String String::toLowerCase() const -{ - StringCreationHelper builder (text); - - for (;;) - { - const juce_wchar c = builder.source.toLowerCase(); - builder.write (c); - - if (c == 0) - break; - - ++(builder.source); - } - - return builder.result; -} - -//============================================================================== -juce_wchar String::getLastCharacter() const noexcept -{ - return isEmpty() ? juce_wchar() : text [length() - 1]; -} - -String String::substring (int start, const int end) const -{ - if (start < 0) - start = 0; - - if (end <= start) - return String(); - - int i = 0; - CharPointerType t1 (text); - - while (i < start) - { - if (t1.isEmpty()) - return String(); - - ++i; - ++t1; - } - - CharPointerType t2 (t1); - while (i < end) - { - if (t2.isEmpty()) - { - if (start == 0) - return *this; - - break; - } - - ++i; - ++t2; - } - - return String (t1, t2); -} - -String String::substring (int start) const -{ - if (start <= 0) - return *this; - - CharPointerType t (text); - - while (--start >= 0) - { - if (t.isEmpty()) - return String(); - - ++t; - } - - return String (t); -} - -String String::dropLastCharacters (const int numberToDrop) const -{ - return String (text, (size_t) jmax (0, length() - numberToDrop)); -} - -String String::getLastCharacters (const int numCharacters) const -{ - return String (text + jmax (0, length() - jmax (0, numCharacters))); -} - -String String::fromFirstOccurrenceOf (StringRef sub, - const bool includeSubString, - const bool ignoreCase) const -{ - const int i = ignoreCase ? indexOfIgnoreCase (sub) - : indexOf (sub); - if (i < 0) - return String(); - - return substring (includeSubString ? i : i + sub.length()); -} - -String String::fromLastOccurrenceOf (StringRef sub, - const bool includeSubString, - const bool ignoreCase) const -{ - const int i = ignoreCase ? lastIndexOfIgnoreCase (sub) - : lastIndexOf (sub); - if (i < 0) - return *this; - - return substring (includeSubString ? i : i + sub.length()); -} - -String String::upToFirstOccurrenceOf (StringRef sub, - const bool includeSubString, - const bool ignoreCase) const -{ - const int i = ignoreCase ? indexOfIgnoreCase (sub) - : indexOf (sub); - if (i < 0) - return *this; - - return substring (0, includeSubString ? i + sub.length() : i); -} - -String String::upToLastOccurrenceOf (StringRef sub, - const bool includeSubString, - const bool ignoreCase) const -{ - const int i = ignoreCase ? lastIndexOfIgnoreCase (sub) - : lastIndexOf (sub); - if (i < 0) - return *this; - - return substring (0, includeSubString ? i + sub.length() : i); -} - -bool String::isQuotedString() const -{ - const String trimmed (trimStart()); - - return trimmed[0] == '"' - || trimmed[0] == '\''; -} - -String String::unquoted() const -{ - const int len = length(); - - if (len == 0) - return String(); - - const juce_wchar lastChar = text [len - 1]; - const int dropAtStart = (*text == '"' || *text == '\'') ? 1 : 0; - const int dropAtEnd = (lastChar == '"' || lastChar == '\'') ? 1 : 0; - - return substring (dropAtStart, len - dropAtEnd); -} - -String String::quoted (const juce_wchar quoteCharacter) const -{ - if (isEmpty()) - return charToString (quoteCharacter) + quoteCharacter; - - String t (*this); - - if (! t.startsWithChar (quoteCharacter)) - t = charToString (quoteCharacter) + t; - - if (! t.endsWithChar (quoteCharacter)) - t += quoteCharacter; - - return t; -} - -//============================================================================== -static String::CharPointerType findTrimmedEnd (const String::CharPointerType start, - String::CharPointerType end) -{ - while (end > start) - { - if (! (--end).isWhitespace()) - { - ++end; - break; - } - } - - return end; -} - -String String::trim() const -{ - if (isNotEmpty()) - { - CharPointerType start (text.findEndOfWhitespace()); - - const CharPointerType end (start.findTerminatingNull()); - CharPointerType trimmedEnd (findTrimmedEnd (start, end)); - - if (trimmedEnd <= start) - return String(); - - if (text < start || trimmedEnd < end) - return String (start, trimmedEnd); - } - - return *this; -} - -String String::trimStart() const -{ - if (isNotEmpty()) - { - const CharPointerType t (text.findEndOfWhitespace()); - - if (t != text) - return String (t); - } - - return *this; -} - -String String::trimEnd() const -{ - if (isNotEmpty()) - { - const CharPointerType end (text.findTerminatingNull()); - CharPointerType trimmedEnd (findTrimmedEnd (text, end)); - - if (trimmedEnd < end) - return String (text, trimmedEnd); - } - - return *this; -} - -String String::trimCharactersAtStart (StringRef charactersToTrim) const -{ - CharPointerType t (text); - - while (charactersToTrim.text.indexOf (*t) >= 0) - ++t; - - return t == text ? *this : String (t); -} - -String String::trimCharactersAtEnd (StringRef charactersToTrim) const -{ - if (isNotEmpty()) - { - const CharPointerType end (text.findTerminatingNull()); - CharPointerType trimmedEnd (end); - - while (trimmedEnd > text) - { - if (charactersToTrim.text.indexOf (*--trimmedEnd) < 0) - { - ++trimmedEnd; - break; - } - } - - if (trimmedEnd < end) - return String (text, trimmedEnd); - } - - return *this; -} - -//============================================================================== -String String::retainCharacters (StringRef charactersToRetain) const -{ - if (isEmpty()) - return String(); - - StringCreationHelper builder (text); - - for (;;) - { - juce_wchar c = builder.source.getAndAdvance(); - - if (charactersToRetain.text.indexOf (c) >= 0) - builder.write (c); - - if (c == 0) - break; - } - - builder.write (0); - return builder.result; -} - -String String::removeCharacters (StringRef charactersToRemove) const -{ - if (isEmpty()) - return String(); - - StringCreationHelper builder (text); - - for (;;) - { - juce_wchar c = builder.source.getAndAdvance(); - - if (charactersToRemove.text.indexOf (c) < 0) - builder.write (c); - - if (c == 0) - break; - } - - return builder.result; -} - -String String::initialSectionContainingOnly (StringRef permittedCharacters) const -{ - for (CharPointerType t (text); ! t.isEmpty(); ++t) - if (permittedCharacters.text.indexOf (*t) < 0) - return String (text, t); - - return *this; -} - -String String::initialSectionNotContaining (StringRef charactersToStopAt) const -{ - for (CharPointerType t (text); ! t.isEmpty(); ++t) - if (charactersToStopAt.text.indexOf (*t) >= 0) - return String (text, t); - - return *this; -} - -bool String::containsOnly (StringRef chars) const noexcept -{ - for (CharPointerType t (text); ! t.isEmpty();) - if (chars.text.indexOf (t.getAndAdvance()) < 0) - return false; - - return true; -} - -bool String::containsAnyOf (StringRef chars) const noexcept -{ - for (CharPointerType t (text); ! t.isEmpty();) - if (chars.text.indexOf (t.getAndAdvance()) >= 0) - return true; - - return false; -} - -bool String::containsNonWhitespaceChars() const noexcept -{ - for (CharPointerType t (text); ! t.isEmpty(); ++t) - if (! t.isWhitespace()) - return true; - - return false; -} - -// Note! The format parameter here MUST NOT be a reference, otherwise MS's va_start macro fails to work (but still compiles). -String String::formatted (const String pf, ... ) -{ - size_t bufferSize = 256; - - for (;;) - { - va_list args; - va_start (args, pf); - - #if JUCE_WINDOWS - HeapBlock temp (bufferSize); - const int num = (int) _vsnwprintf (temp.getData(), bufferSize - 1, pf.toWideCharPointer(), args); - #elif JUCE_ANDROID - HeapBlock temp (bufferSize); - const int num = (int) vsnprintf (temp.getData(), bufferSize - 1, pf.toUTF8(), args); - #else - HeapBlock temp (bufferSize); - const int num = (int) vswprintf (temp.getData(), bufferSize - 1, pf.toWideCharPointer(), args); - #endif - - va_end (args); - - if (num > 0) - return String (temp); - - bufferSize += 256; - - if (num == 0 || bufferSize > 65536) // the upper limit is a sanity check to avoid situations where vprintf repeatedly - break; // returns -1 because of an error rather than because it needs more space. - } - - return String(); -} - -//============================================================================== -int String::getIntValue() const noexcept { return text.getIntValue32(); } -int64 String::getLargeIntValue() const noexcept { return text.getIntValue64(); } -float String::getFloatValue() const noexcept { return (float) getDoubleValue(); } -double String::getDoubleValue() const noexcept { return text.getDoubleValue(); } - -int String::getTrailingIntValue() const noexcept -{ - int n = 0; - int mult = 1; - CharPointerType t (text.findTerminatingNull()); - - while (--t >= text) - { - if (! t.isDigit()) - { - if (*t == '-') - n = -n; - - break; - } - - n += mult * (*t - '0'); - mult *= 10; - } - - return n; -} - -static const char hexDigits[] = "0123456789abcdef"; - -template -static String hexToString (Type v) -{ - String::CharPointerType::CharType buffer[32]; - String::CharPointerType::CharType* const end = buffer + numElementsInArray (buffer) - 1; - String::CharPointerType::CharType* t = end; - *t = 0; - - do - { - *--t = hexDigits [(int) (v & 15)]; - v >>= 4; - - } while (v != 0); - - return String (String::CharPointerType (t), - String::CharPointerType (end)); -} - -String String::toHexString (int number) { return hexToString ((unsigned int) number); } -String String::toHexString (int64 number) { return hexToString ((uint64) number); } -String String::toHexString (short number) { return toHexString ((int) (unsigned short) number); } - -String String::toHexString (const void* const d, const int size, const int groupSize) -{ - if (size <= 0) - return String(); - - int numChars = (size * 2) + 2; - if (groupSize > 0) - numChars += size / groupSize; - - String s (PreallocationBytes (sizeof (CharPointerType::CharType) * (size_t) numChars)); - - const unsigned char* data = static_cast (d); - CharPointerType dest (s.text); - - for (int i = 0; i < size; ++i) - { - const unsigned char nextByte = *data++; - dest.write ((juce_wchar) hexDigits [nextByte >> 4]); - dest.write ((juce_wchar) hexDigits [nextByte & 0xf]); - - if (groupSize > 0 && (i % groupSize) == (groupSize - 1) && i < (size - 1)) - dest.write ((juce_wchar) ' '); - } - - dest.writeNull(); - return s; -} - -int String::getHexValue32() const noexcept { return CharacterFunctions::HexParser ::parse (text); } -int64 String::getHexValue64() const noexcept { return CharacterFunctions::HexParser::parse (text); } - -//============================================================================== -String String::createStringFromData (const void* const unknownData, const int size) -{ - const uint8* const data = static_cast (unknownData); - - if (size <= 0 || data == nullptr) - return String(); - - if (size == 1) - return charToString ((juce_wchar) data[0]); - - if (CharPointer_UTF16::isByteOrderMarkBigEndian (data) - || CharPointer_UTF16::isByteOrderMarkLittleEndian (data)) - { - const int numChars = size / 2 - 1; - - StringCreationHelper builder ((size_t) numChars); - - const uint16* const src = (const uint16*) (data + 2); - - if (CharPointer_UTF16::isByteOrderMarkBigEndian (data)) - { - for (int i = 0; i < numChars; ++i) - builder.write ((juce_wchar) ByteOrder::swapIfLittleEndian (src[i])); - } - else - { - for (int i = 0; i < numChars; ++i) - builder.write ((juce_wchar) ByteOrder::swapIfBigEndian (src[i])); - } - - builder.write (0); - return builder.result; - } - - const uint8* start = data; - - if (size >= 3 && CharPointer_UTF8::isByteOrderMark (data)) - start += 3; - - return String (CharPointer_UTF8 ((const char*) start), - CharPointer_UTF8 ((const char*) (data + size))); -} - -//============================================================================== -static const juce_wchar emptyChar = 0; - -template -struct StringEncodingConverter -{ - static CharPointerType_Dest convert (const String& s) - { - String& source = const_cast (s); - - typedef typename CharPointerType_Dest::CharType DestChar; - - if (source.isEmpty()) - return CharPointerType_Dest (reinterpret_cast (&emptyChar)); - - CharPointerType_Src text (source.getCharPointer()); - const size_t extraBytesNeeded = CharPointerType_Dest::getBytesRequiredFor (text) + sizeof (typename CharPointerType_Dest::CharType); - const size_t endOffset = (text.sizeInBytes() + 3) & ~3u; // the new string must be word-aligned or many Windows - // functions will fail to read it correctly! - source.preallocateBytes (endOffset + extraBytesNeeded); - text = source.getCharPointer(); - - void* const newSpace = addBytesToPointer (text.getAddress(), (int) endOffset); - const CharPointerType_Dest extraSpace (static_cast (newSpace)); - - #if JUCE_DEBUG // (This just avoids spurious warnings from valgrind about the uninitialised bytes at the end of the buffer..) - const size_t bytesToClear = (size_t) jmin ((int) extraBytesNeeded, 4); - zeromem (addBytesToPointer (newSpace, extraBytesNeeded - bytesToClear), bytesToClear); - #endif - - CharPointerType_Dest (extraSpace).writeAll (text); - return extraSpace; - } -}; - -template <> -struct StringEncodingConverter -{ - static CharPointer_UTF8 convert (const String& source) noexcept { return CharPointer_UTF8 ((CharPointer_UTF8::CharType*) source.getCharPointer().getAddress()); } -}; - -template <> -struct StringEncodingConverter -{ - static CharPointer_UTF16 convert (const String& source) noexcept { return CharPointer_UTF16 ((CharPointer_UTF16::CharType*) source.getCharPointer().getAddress()); } -}; - -template <> -struct StringEncodingConverter -{ - static CharPointer_UTF32 convert (const String& source) noexcept { return CharPointer_UTF32 ((CharPointer_UTF32::CharType*) source.getCharPointer().getAddress()); } -}; - -CharPointer_UTF8 String::toUTF8() const { return StringEncodingConverter::convert (*this); } -CharPointer_UTF16 String::toUTF16() const { return StringEncodingConverter::convert (*this); } -CharPointer_UTF32 String::toUTF32() const { return StringEncodingConverter::convert (*this); } - -const char* String::toRawUTF8() const -{ - return toUTF8().getAddress(); -} - -const wchar_t* String::toWideCharPointer() const -{ - return StringEncodingConverter::convert (*this).getAddress(); -} - -std::string String::toStdString() const -{ - return std::string (toRawUTF8()); -} - -//============================================================================== -template -struct StringCopier -{ - static size_t copyToBuffer (const CharPointerType_Src source, typename CharPointerType_Dest::CharType* const buffer, const size_t maxBufferSizeBytes) - { - jassert (((ssize_t) maxBufferSizeBytes) >= 0); // keep this value positive! - - if (buffer == nullptr) - return CharPointerType_Dest::getBytesRequiredFor (source) + sizeof (typename CharPointerType_Dest::CharType); - - return CharPointerType_Dest (buffer).writeWithDestByteLimit (source, maxBufferSizeBytes); - } -}; - -size_t String::copyToUTF8 (CharPointer_UTF8::CharType* const buffer, size_t maxBufferSizeBytes) const noexcept -{ - return StringCopier::copyToBuffer (text, buffer, maxBufferSizeBytes); -} - -size_t String::copyToUTF16 (CharPointer_UTF16::CharType* const buffer, size_t maxBufferSizeBytes) const noexcept -{ - return StringCopier::copyToBuffer (text, buffer, maxBufferSizeBytes); -} - -size_t String::copyToUTF32 (CharPointer_UTF32::CharType* const buffer, size_t maxBufferSizeBytes) const noexcept -{ - return StringCopier::copyToBuffer (text, buffer, maxBufferSizeBytes); -} - -//============================================================================== -size_t String::getNumBytesAsUTF8() const noexcept -{ - return CharPointer_UTF8::getBytesRequiredFor (text); -} - -String String::fromUTF8 (const char* const buffer, int bufferSizeBytes) -{ - if (buffer != nullptr) - { - if (bufferSizeBytes < 0) - return String (CharPointer_UTF8 (buffer)); - - if (bufferSizeBytes > 0) - { - jassert (CharPointer_UTF8::isValidString (buffer, bufferSizeBytes)); - return String (CharPointer_UTF8 (buffer), CharPointer_UTF8 (buffer + bufferSizeBytes)); - } - } - - return String(); -} - -#if JUCE_MSVC - #pragma warning (pop) -#endif - -//============================================================================== -StringRef::StringRef() noexcept : text ((const String::CharPointerType::CharType*) "\0\0\0") -{ -} - -StringRef::StringRef (const char* stringLiteral) noexcept - #if JUCE_STRING_UTF_TYPE != 8 - : text (nullptr), stringCopy (stringLiteral) - #else - : text (stringLiteral) - #endif -{ - #if JUCE_STRING_UTF_TYPE != 8 - text = stringCopy.getCharPointer(); - #endif - - jassert (stringLiteral != nullptr); // This must be a valid string literal, not a null pointer!! - - #if JUCE_NATIVE_WCHAR_IS_UTF8 - /* If you get an assertion here, then you're trying to create a string from 8-bit data - that contains values greater than 127. These can NOT be correctly converted to unicode - because there's no way for the String class to know what encoding was used to - create them. The source data could be UTF-8, ASCII or one of many local code-pages. - - To get around this problem, you must be more explicit when you pass an ambiguous 8-bit - string to the StringRef class - so for example if your source data is actually UTF-8, - you'd call StringRef (CharPointer_UTF8 ("my utf8 string..")), and it would be able to - correctly convert the multi-byte characters to unicode. It's *highly* recommended that - you use UTF-8 with escape characters in your source code to represent extended characters, - because there's no other way to represent these strings in a way that isn't dependent on - the compiler, source code editor and platform. - */ - jassert (CharPointer_ASCII::isValidString (stringLiteral, std::numeric_limits::max())); - #endif -} - -StringRef::StringRef (String::CharPointerType stringLiteral) noexcept : text (stringLiteral) -{ - jassert (stringLiteral.getAddress() != nullptr); // This must be a valid string literal, not a null pointer!! -} - -StringRef::StringRef (const String& string) noexcept : text (string.getCharPointer()) {} - - -//============================================================================== -//============================================================================== -#if JUCE_UNIT_TESTS - -class StringTests : public UnitTest -{ -public: - StringTests() : UnitTest ("String class") {} - - template - struct TestUTFConversion - { - static void test (UnitTest& test, Random& r) - { - String s (createRandomWideCharString (r)); - - typename CharPointerType::CharType buffer [300]; - - memset (buffer, 0xff, sizeof (buffer)); - CharPointerType (buffer).writeAll (s.toUTF32()); - test.expectEquals (String (CharPointerType (buffer)), s); - - memset (buffer, 0xff, sizeof (buffer)); - CharPointerType (buffer).writeAll (s.toUTF16()); - test.expectEquals (String (CharPointerType (buffer)), s); - - memset (buffer, 0xff, sizeof (buffer)); - CharPointerType (buffer).writeAll (s.toUTF8()); - test.expectEquals (String (CharPointerType (buffer)), s); - - test.expect (CharPointerType::isValidString (buffer, (int) strlen ((const char*) buffer))); - } - }; - - static String createRandomWideCharString (Random& r) - { - juce_wchar buffer[50] = { 0 }; - - for (int i = 0; i < numElementsInArray (buffer) - 1; ++i) - { - if (r.nextBool()) - { - do - { - buffer[i] = (juce_wchar) (1 + r.nextInt (0x10ffff - 1)); - } - while (! CharPointer_UTF16::canRepresent (buffer[i])); - } - else - buffer[i] = (juce_wchar) (1 + r.nextInt (0xff)); - } - - return CharPointer_UTF32 (buffer); - } - - void runTest() - { - Random r = getRandom(); - - { - beginTest ("Basics"); - - expect (String().length() == 0); - expect (String() == String::empty); - String s1, s2 ("abcd"); - expect (s1.isEmpty() && ! s1.isNotEmpty()); - expect (s2.isNotEmpty() && ! s2.isEmpty()); - expect (s2.length() == 4); - s1 = "abcd"; - expect (s2 == s1 && s1 == s2); - expect (s1 == "abcd" && s1 == L"abcd"); - expect (String ("abcd") == String (L"abcd")); - expect (String ("abcdefg", 4) == L"abcd"); - expect (String ("abcdefg", 4) == String (L"abcdefg", 4)); - expect (String::charToString ('x') == "x"); - expect (String::charToString (0) == String::empty); - expect (s2 + "e" == "abcde" && s2 + 'e' == "abcde"); - expect (s2 + L'e' == "abcde" && s2 + L"e" == "abcde"); - expect (s1.equalsIgnoreCase ("abcD") && s1 < "abce" && s1 > "abbb"); - expect (s1.startsWith ("ab") && s1.startsWith ("abcd") && ! s1.startsWith ("abcde")); - expect (s1.startsWithIgnoreCase ("aB") && s1.endsWithIgnoreCase ("CD")); - expect (s1.endsWith ("bcd") && ! s1.endsWith ("aabcd")); - expectEquals (s1.indexOf (String::empty), 0); - expectEquals (s1.indexOfIgnoreCase (String::empty), 0); - expect (s1.startsWith (String::empty) && s1.endsWith (String::empty) && s1.contains (String::empty)); - expect (s1.contains ("cd") && s1.contains ("ab") && s1.contains ("abcd")); - expect (s1.containsChar ('a')); - expect (! s1.containsChar ('x')); - expect (! s1.containsChar (0)); - expect (String ("abc foo bar").containsWholeWord ("abc") && String ("abc foo bar").containsWholeWord ("abc")); - } - - { - beginTest ("Operations"); - - String s ("012345678"); - expect (s.hashCode() != 0); - expect (s.hashCode64() != 0); - expect (s.hashCode() != (s + s).hashCode()); - expect (s.hashCode64() != (s + s).hashCode64()); - expect (s.compare (String ("012345678")) == 0); - expect (s.compare (String ("012345679")) < 0); - expect (s.compare (String ("012345676")) > 0); - expect (String("a").compareNatural ("A") == 0); - expect (String("A").compareNatural ("B") < 0); - expect (String("a").compareNatural ("B") < 0); - expect (String("10").compareNatural ("2") > 0); - expect (String("Abc 10").compareNatural ("aBC 2") > 0); - expect (String("Abc 1").compareNatural ("aBC 2") < 0); - expect (s.substring (2, 3) == String::charToString (s[2])); - expect (s.substring (0, 1) == String::charToString (s[0])); - expect (s.getLastCharacter() == s [s.length() - 1]); - expect (String::charToString (s.getLastCharacter()) == s.getLastCharacters (1)); - expect (s.substring (0, 3) == L"012"); - expect (s.substring (0, 100) == s); - expect (s.substring (-1, 100) == s); - expect (s.substring (3) == "345678"); - expect (s.indexOf (String (L"45")) == 4); - expect (String ("444445").indexOf ("45") == 4); - expect (String ("444445").lastIndexOfChar ('4') == 4); - expect (String ("45454545x").lastIndexOf (String (L"45")) == 6); - expect (String ("45454545x").lastIndexOfAnyOf ("456") == 7); - expect (String ("45454545x").lastIndexOfAnyOf (String (L"456x")) == 8); - expect (String ("abABaBaBa").lastIndexOfIgnoreCase ("aB") == 6); - expect (s.indexOfChar (L'4') == 4); - expect (s + s == "012345678012345678"); - expect (s.startsWith (s)); - expect (s.startsWith (s.substring (0, 4))); - expect (s.startsWith (s.dropLastCharacters (4))); - expect (s.endsWith (s.substring (5))); - expect (s.endsWith (s)); - expect (s.contains (s.substring (3, 6))); - expect (s.contains (s.substring (3))); - expect (s.startsWithChar (s[0])); - expect (s.endsWithChar (s.getLastCharacter())); - expect (s [s.length()] == 0); - expect (String ("abcdEFGH").toLowerCase() == String ("abcdefgh")); - expect (String ("abcdEFGH").toUpperCase() == String ("ABCDEFGH")); - - String s2 ("123"); - s2 << ((int) 4) << ((short) 5) << "678" << L"9" << '0'; - s2 += "xyz"; - expect (s2 == "1234567890xyz"); - s2 += (int) 123; - expect (s2 == "1234567890xyz123"); - s2 += (int64) 123; - expect (s2 == "1234567890xyz123123"); - - beginTest ("Numeric conversions"); - expect (String::empty.getIntValue() == 0); - expect (String::empty.getDoubleValue() == 0.0); - expect (String::empty.getFloatValue() == 0.0f); - expect (s.getIntValue() == 12345678); - expect (s.getLargeIntValue() == (int64) 12345678); - expect (s.getDoubleValue() == 12345678.0); - expect (s.getFloatValue() == 12345678.0f); - expect (String (-1234).getIntValue() == -1234); - expect (String ((int64) -1234).getLargeIntValue() == -1234); - expect (String (-1234.56).getDoubleValue() == -1234.56); - expect (String (-1234.56f).getFloatValue() == -1234.56f); - expect (String (std::numeric_limits::max()).getIntValue() == std::numeric_limits::max()); - expect (String (std::numeric_limits::min()).getIntValue() == std::numeric_limits::min()); - expect (String (std::numeric_limits::max()).getLargeIntValue() == std::numeric_limits::max()); - expect (String (std::numeric_limits::min()).getLargeIntValue() == std::numeric_limits::min()); - expect (("xyz" + s).getTrailingIntValue() == s.getIntValue()); - expect (s.getHexValue32() == 0x12345678); - expect (s.getHexValue64() == (int64) 0x12345678); - expect (String::toHexString (0x1234abcd).equalsIgnoreCase ("1234abcd")); - expect (String::toHexString ((int64) 0x1234abcd).equalsIgnoreCase ("1234abcd")); - expect (String::toHexString ((short) 0x12ab).equalsIgnoreCase ("12ab")); - - unsigned char data[] = { 1, 2, 3, 4, 0xa, 0xb, 0xc, 0xd }; - expect (String::toHexString (data, 8, 0).equalsIgnoreCase ("010203040a0b0c0d")); - expect (String::toHexString (data, 8, 1).equalsIgnoreCase ("01 02 03 04 0a 0b 0c 0d")); - expect (String::toHexString (data, 8, 2).equalsIgnoreCase ("0102 0304 0a0b 0c0d")); - - beginTest ("Subsections"); - String s3; - s3 = "abcdeFGHIJ"; - expect (s3.equalsIgnoreCase ("ABCdeFGhiJ")); - expect (s3.compareIgnoreCase (L"ABCdeFGhiJ") == 0); - expect (s3.containsIgnoreCase (s3.substring (3))); - expect (s3.indexOfAnyOf ("xyzf", 2, true) == 5); - expect (s3.indexOfAnyOf (String (L"xyzf"), 2, false) == -1); - expect (s3.indexOfAnyOf ("xyzF", 2, false) == 5); - expect (s3.containsAnyOf (String (L"zzzFs"))); - expect (s3.startsWith ("abcd")); - expect (s3.startsWithIgnoreCase (String (L"abCD"))); - expect (s3.startsWith (String::empty)); - expect (s3.startsWithChar ('a')); - expect (s3.endsWith (String ("HIJ"))); - expect (s3.endsWithIgnoreCase (String (L"Hij"))); - expect (s3.endsWith (String::empty)); - expect (s3.endsWithChar (L'J')); - expect (s3.indexOf ("HIJ") == 7); - expect (s3.indexOf (String (L"HIJK")) == -1); - expect (s3.indexOfIgnoreCase ("hij") == 7); - expect (s3.indexOfIgnoreCase (String (L"hijk")) == -1); - expect (s3.toStdString() == s3.toRawUTF8()); - - String s4 (s3); - s4.append (String ("xyz123"), 3); - expect (s4 == s3 + "xyz"); - - expect (String (1234) < String (1235)); - expect (String (1235) > String (1234)); - expect (String (1234) >= String (1234)); - expect (String (1234) <= String (1234)); - expect (String (1235) >= String (1234)); - expect (String (1234) <= String (1235)); - - String s5 ("word word2 word3"); - expect (s5.containsWholeWord (String ("word2"))); - expect (s5.indexOfWholeWord ("word2") == 5); - expect (s5.containsWholeWord (String (L"word"))); - expect (s5.containsWholeWord ("word3")); - expect (s5.containsWholeWord (s5)); - expect (s5.containsWholeWordIgnoreCase (String (L"Word2"))); - expect (s5.indexOfWholeWordIgnoreCase ("Word2") == 5); - expect (s5.containsWholeWordIgnoreCase (String (L"Word"))); - expect (s5.containsWholeWordIgnoreCase ("Word3")); - expect (! s5.containsWholeWordIgnoreCase (String (L"Wordx"))); - expect (! s5.containsWholeWordIgnoreCase ("xWord2")); - expect (s5.containsNonWhitespaceChars()); - expect (s5.containsOnly ("ordw23 ")); - expect (! String (" \n\r\t").containsNonWhitespaceChars()); - - expect (s5.matchesWildcard (String (L"wor*"), false)); - expect (s5.matchesWildcard ("wOr*", true)); - expect (s5.matchesWildcard (String (L"*word3"), true)); - expect (s5.matchesWildcard ("*word?", true)); - expect (s5.matchesWildcard (String (L"Word*3"), true)); - expect (! s5.matchesWildcard (String (L"*34"), true)); - expect (String ("xx**y").matchesWildcard ("*y", true)); - expect (String ("xx**y").matchesWildcard ("x*y", true)); - expect (String ("xx**y").matchesWildcard ("xx*y", true)); - expect (String ("xx**y").matchesWildcard ("xx*", true)); - expect (String ("xx?y").matchesWildcard ("x??y", true)); - expect (String ("xx?y").matchesWildcard ("xx?y", true)); - expect (! String ("xx?y").matchesWildcard ("xx?y?", true)); - expect (String ("xx?y").matchesWildcard ("xx??", true)); - - expectEquals (s5.fromFirstOccurrenceOf (String::empty, true, false), s5); - expectEquals (s5.fromFirstOccurrenceOf ("xword2", true, false), s5.substring (100)); - expectEquals (s5.fromFirstOccurrenceOf (String (L"word2"), true, false), s5.substring (5)); - expectEquals (s5.fromFirstOccurrenceOf ("Word2", true, true), s5.substring (5)); - expectEquals (s5.fromFirstOccurrenceOf ("word2", false, false), s5.getLastCharacters (6)); - expectEquals (s5.fromFirstOccurrenceOf ("Word2", false, true), s5.getLastCharacters (6)); - - expectEquals (s5.fromLastOccurrenceOf (String::empty, true, false), s5); - expectEquals (s5.fromLastOccurrenceOf ("wordx", true, false), s5); - expectEquals (s5.fromLastOccurrenceOf ("word", true, false), s5.getLastCharacters (5)); - expectEquals (s5.fromLastOccurrenceOf ("worD", true, true), s5.getLastCharacters (5)); - expectEquals (s5.fromLastOccurrenceOf ("word", false, false), s5.getLastCharacters (1)); - expectEquals (s5.fromLastOccurrenceOf ("worD", false, true), s5.getLastCharacters (1)); - - expect (s5.upToFirstOccurrenceOf (String::empty, true, false).isEmpty()); - expectEquals (s5.upToFirstOccurrenceOf ("word4", true, false), s5); - expectEquals (s5.upToFirstOccurrenceOf ("word2", true, false), s5.substring (0, 10)); - expectEquals (s5.upToFirstOccurrenceOf ("Word2", true, true), s5.substring (0, 10)); - expectEquals (s5.upToFirstOccurrenceOf ("word2", false, false), s5.substring (0, 5)); - expectEquals (s5.upToFirstOccurrenceOf ("Word2", false, true), s5.substring (0, 5)); - - expectEquals (s5.upToLastOccurrenceOf (String::empty, true, false), s5); - expectEquals (s5.upToLastOccurrenceOf ("zword", true, false), s5); - expectEquals (s5.upToLastOccurrenceOf ("word", true, false), s5.dropLastCharacters (1)); - expectEquals (s5.dropLastCharacters(1).upToLastOccurrenceOf ("word", true, false), s5.dropLastCharacters (1)); - expectEquals (s5.upToLastOccurrenceOf ("Word", true, true), s5.dropLastCharacters (1)); - expectEquals (s5.upToLastOccurrenceOf ("word", false, false), s5.dropLastCharacters (5)); - expectEquals (s5.upToLastOccurrenceOf ("Word", false, true), s5.dropLastCharacters (5)); - - expectEquals (s5.replace ("word", "xyz", false), String ("xyz xyz2 xyz3")); - expect (s5.replace ("Word", "xyz", true) == "xyz xyz2 xyz3"); - expect (s5.dropLastCharacters (1).replace ("Word", String ("xyz"), true) == L"xyz xyz2 xyz"); - expect (s5.replace ("Word", "", true) == " 2 3"); - expectEquals (s5.replace ("Word2", "xyz", true), String ("word xyz word3")); - expect (s5.replaceCharacter (L'w', 'x') != s5); - expectEquals (s5.replaceCharacter ('w', L'x').replaceCharacter ('x', 'w'), s5); - expect (s5.replaceCharacters ("wo", "xy") != s5); - expectEquals (s5.replaceCharacters ("wo", "xy").replaceCharacters ("xy", "wo"), s5); - expectEquals (s5.retainCharacters ("1wordxya"), String ("wordwordword")); - expect (s5.retainCharacters (String::empty).isEmpty()); - expect (s5.removeCharacters ("1wordxya") == " 2 3"); - expectEquals (s5.removeCharacters (String::empty), s5); - expect (s5.initialSectionContainingOnly ("word") == L"word"); - expect (String ("word").initialSectionContainingOnly ("word") == L"word"); - expectEquals (s5.initialSectionNotContaining (String ("xyz ")), String ("word")); - expectEquals (s5.initialSectionNotContaining (String (";[:'/")), s5); - expect (! s5.isQuotedString()); - expect (s5.quoted().isQuotedString()); - expect (! s5.quoted().unquoted().isQuotedString()); - expect (! String ("x'").isQuotedString()); - expect (String ("'x").isQuotedString()); - - String s6 (" \t xyz \t\r\n"); - expectEquals (s6.trim(), String ("xyz")); - expect (s6.trim().trim() == "xyz"); - expectEquals (s5.trim(), s5); - expectEquals (s6.trimStart().trimEnd(), s6.trim()); - expectEquals (s6.trimStart().trimEnd(), s6.trimEnd().trimStart()); - expectEquals (s6.trimStart().trimStart().trimEnd().trimEnd(), s6.trimEnd().trimStart()); - expect (s6.trimStart() != s6.trimEnd()); - expectEquals (("\t\r\n " + s6 + "\t\n \r").trim(), s6.trim()); - expect (String::repeatedString ("xyz", 3) == L"xyzxyzxyz"); - } - - { - beginTest ("UTF conversions"); - - TestUTFConversion ::test (*this, r); - TestUTFConversion ::test (*this, r); - TestUTFConversion ::test (*this, r); - } - - { - beginTest ("StringArray"); - - StringArray s; - s.addTokens ("4,3,2,1,0", ";,", "x"); - expectEquals (s.size(), 5); - - expectEquals (s.joinIntoString ("-"), String ("4-3-2-1-0")); - s.remove (2); - expectEquals (s.joinIntoString ("--"), String ("4--3--1--0")); - expectEquals (s.joinIntoString (String::empty), String ("4310")); - s.clear(); - expectEquals (s.joinIntoString ("x"), String::empty); - - StringArray toks; - toks.addTokens ("x,,", ";,", ""); - expectEquals (toks.size(), 3); - expectEquals (toks.joinIntoString ("-"), String ("x--")); - toks.clear(); - - toks.addTokens (",x,", ";,", ""); - expectEquals (toks.size(), 3); - expectEquals (toks.joinIntoString ("-"), String ("-x-")); - toks.clear(); - - toks.addTokens ("x,'y,z',", ";,", "'"); - expectEquals (toks.size(), 3); - expectEquals (toks.joinIntoString ("-"), String ("x-'y,z'-")); - } - - { - beginTest ("var"); - - var v1 = 0; - var v2 = 0.1; - var v3 = "0.1"; - var v4 = (int64) 0; - var v5 = 0.0; - expect (! v2.equals (v1)); - expect (! v1.equals (v2)); - expect (v2.equals (v3)); - expect (v3.equals (v2)); - expect (! v3.equals (v1)); - expect (! v1.equals (v3)); - expect (v1.equals (v4)); - expect (v4.equals (v1)); - expect (v5.equals (v4)); - expect (v4.equals (v5)); - expect (! v2.equals (v4)); - expect (! v4.equals (v2)); - } - } -}; - -static StringTests stringUnitTests; - -#endif diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/text/juce_String.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/text/juce_String.h deleted file mode 100644 index 6a511070bb..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/text/juce_String.h +++ /dev/null @@ -1,1370 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_STRING_H_INCLUDED -#define JUCE_STRING_H_INCLUDED - - -//============================================================================== -/** - The JUCE String class! - - Using a reference-counted internal representation, these strings are fast - and efficient, and there are methods to do just about any operation you'll ever - dream of. - - @see StringArray, StringPairArray -*/ -class JUCE_API String -{ -public: - //============================================================================== - /** Creates an empty string. - @see empty - */ - String() noexcept; - - /** Creates a copy of another string. */ - String (const String& other) noexcept; - - #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS - String (String&& other) noexcept; - #endif - - /** Creates a string from a zero-terminated ascii text string. - - The string passed-in must not contain any characters with a value above 127, because - these can't be converted to unicode without knowing the original encoding that was - used to create the string. If you attempt to pass-in values above 127, you'll get an - assertion. - - To create strings with extended characters from UTF-8, you should explicitly call - String (CharPointer_UTF8 ("my utf8 string..")). It's *highly* recommended that you - use UTF-8 with escape characters in your source code to represent extended characters, - because there's no other way to represent unicode strings in a way that isn't dependent - on the compiler, source code editor and platform. - */ - String (const char* text); - - /** Creates a string from a string of 8-bit ascii characters. - - The string passed-in must not contain any characters with a value above 127, because - these can't be converted to unicode without knowing the original encoding that was - used to create the string. If you attempt to pass-in values above 127, you'll get an - assertion. - - To create strings with extended characters from UTF-8, you should explicitly call - String (CharPointer_UTF8 ("my utf8 string..")). It's *highly* recommended that you - use UTF-8 with escape characters in your source code to represent extended characters, - because there's no other way to represent unicode strings in a way that isn't dependent - on the compiler, source code editor and platform. - - This will use up to the first maxChars characters of the string (or less if the string - is actually shorter). - */ - String (const char* text, size_t maxChars); - - /** Creates a string from a whcar_t character string. - Depending on the platform, this may be treated as either UTF-32 or UTF-16. - */ - String (const wchar_t* text); - - /** Creates a string from a whcar_t character string. - Depending on the platform, this may be treated as either UTF-32 or UTF-16. - */ - String (const wchar_t* text, size_t maxChars); - - //============================================================================== - /** Creates a string from a UTF-8 character string */ - String (const CharPointer_UTF8 text); - - /** Creates a string from a UTF-8 character string */ - String (const CharPointer_UTF8 text, size_t maxChars); - - /** Creates a string from a UTF-8 character string */ - String (const CharPointer_UTF8 start, const CharPointer_UTF8 end); - - //============================================================================== - /** Creates a string from a UTF-16 character string */ - String (const CharPointer_UTF16 text); - - /** Creates a string from a UTF-16 character string */ - String (const CharPointer_UTF16 text, size_t maxChars); - - /** Creates a string from a UTF-16 character string */ - String (const CharPointer_UTF16 start, const CharPointer_UTF16 end); - - //============================================================================== - /** Creates a string from a UTF-32 character string */ - String (const CharPointer_UTF32 text); - - /** Creates a string from a UTF-32 character string */ - String (const CharPointer_UTF32 text, size_t maxChars); - - /** Creates a string from a UTF-32 character string */ - String (const CharPointer_UTF32 start, const CharPointer_UTF32 end); - - //============================================================================== - /** Creates a string from an ASCII character string */ - String (const CharPointer_ASCII text); - - /** Creates a string from a UTF-8 encoded std::string. */ - String (const std::string&); - - //============================================================================== - /** Creates a string from a single character. */ - static String charToString (juce_wchar character); - - /** Destructor. */ - ~String() noexcept; - - //============================================================================== - /** This is an empty string that can be used whenever one is needed. - - It's better to use this than String() because it explains what's going on - and is more efficient. - */ - static const String empty; - - /** This is the character encoding type used internally to store the string. - - By setting the value of JUCE_STRING_UTF_TYPE to 8, 16, or 32, you can change the - internal storage format of the String class. UTF-8 uses the least space (if your strings - contain few extended characters), but call operator[] involves iterating the string to find - the required index. UTF-32 provides instant random access to its characters, but uses 4 bytes - per character to store them. UTF-16 uses more space than UTF-8 and is also slow to index, - but is the native wchar_t format used in Windows. - - It doesn't matter too much which format you pick, because the toUTF8(), toUTF16() and - toUTF32() methods let you access the string's content in any of the other formats. - */ - #if (JUCE_STRING_UTF_TYPE == 32) - typedef CharPointer_UTF32 CharPointerType; - #elif (JUCE_STRING_UTF_TYPE == 16) - typedef CharPointer_UTF16 CharPointerType; - #elif (DOXYGEN || JUCE_STRING_UTF_TYPE == 8) - typedef CharPointer_UTF8 CharPointerType; - #else - #error "You must set the value of JUCE_STRING_UTF_TYPE to be either 8, 16, or 32!" - #endif - - //============================================================================== - /** Generates a probably-unique 32-bit hashcode from this string. */ - int hashCode() const noexcept; - - /** Generates a probably-unique 64-bit hashcode from this string. */ - int64 hashCode64() const noexcept; - - /** Generates a probably-unique hashcode from this string. */ - std::size_t hash() const noexcept; - - /** Returns the number of characters in the string. */ - int length() const noexcept; - - //============================================================================== - // Assignment and concatenation operators.. - - /** Replaces this string's contents with another string. */ - String& operator= (const String& other) noexcept; - - #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS - String& operator= (String&& other) noexcept; - #endif - - /** Appends another string at the end of this one. */ - String& operator+= (const String& stringToAppend); - /** Appends another string at the end of this one. */ - String& operator+= (const char* textToAppend); - /** Appends another string at the end of this one. */ - String& operator+= (const wchar_t* textToAppend); - /** Appends a decimal number at the end of this string. */ - String& operator+= (int numberToAppend); - /** Appends a decimal number at the end of this string. */ - String& operator+= (int64 numberToAppend); - /** Appends a character at the end of this string. */ - String& operator+= (char characterToAppend); - /** Appends a character at the end of this string. */ - String& operator+= (wchar_t characterToAppend); - #if ! JUCE_NATIVE_WCHAR_IS_UTF32 - /** Appends a character at the end of this string. */ - String& operator+= (juce_wchar characterToAppend); - #endif - - /** Appends a string to the end of this one. - - @param textToAppend the string to add - @param maxCharsToTake the maximum number of characters to take from the string passed in - */ - void append (const String& textToAppend, size_t maxCharsToTake); - - /** Appends a string to the end of this one. - - @param startOfTextToAppend the start of the string to add. This must not be a nullptr - @param endOfTextToAppend the end of the string to add. This must not be a nullptr - */ - void appendCharPointer (const CharPointerType startOfTextToAppend, - const CharPointerType endOfTextToAppend); - - /** Appends a string to the end of this one. - - @param startOfTextToAppend the start of the string to add. This must not be a nullptr - @param endOfTextToAppend the end of the string to add. This must not be a nullptr - */ - template - void appendCharPointer (const CharPointer startOfTextToAppend, - const CharPointer endOfTextToAppend) - { - jassert (startOfTextToAppend.getAddress() != nullptr && endOfTextToAppend.getAddress() != nullptr); - - size_t extraBytesNeeded = 0, numChars = 1; - - for (CharPointer t (startOfTextToAppend); t != endOfTextToAppend && ! t.isEmpty(); ++numChars) - extraBytesNeeded += CharPointerType::getBytesRequiredFor (t.getAndAdvance()); - - if (extraBytesNeeded > 0) - { - const size_t byteOffsetOfNull = getByteOffsetOfEnd(); - - preallocateBytes (byteOffsetOfNull + extraBytesNeeded); - CharPointerType (addBytesToPointer (text.getAddress(), (int) byteOffsetOfNull)) - .writeWithCharLimit (startOfTextToAppend, (int) numChars); - } - } - - /** Appends a string to the end of this one. */ - void appendCharPointer (const CharPointerType textToAppend); - - /** Appends a string to the end of this one. - - @param textToAppend the string to add - @param maxCharsToTake the maximum number of characters to take from the string passed in - */ - template - void appendCharPointer (const CharPointer textToAppend, size_t maxCharsToTake) - { - if (textToAppend.getAddress() != nullptr) - { - size_t extraBytesNeeded = 0, numChars = 1; - - for (CharPointer t (textToAppend); numChars <= maxCharsToTake && ! t.isEmpty(); ++numChars) - extraBytesNeeded += CharPointerType::getBytesRequiredFor (t.getAndAdvance()); - - if (extraBytesNeeded > 0) - { - const size_t byteOffsetOfNull = getByteOffsetOfEnd(); - - preallocateBytes (byteOffsetOfNull + extraBytesNeeded); - CharPointerType (addBytesToPointer (text.getAddress(), (int) byteOffsetOfNull)) - .writeWithCharLimit (textToAppend, (int) numChars); - } - } - } - - /** Appends a string to the end of this one. */ - template - void appendCharPointer (const CharPointer textToAppend) - { - appendCharPointer (textToAppend, std::numeric_limits::max()); - } - - //============================================================================== - // Comparison methods.. - - /** Returns true if the string contains no characters. - Note that there's also an isNotEmpty() method to help write readable code. - @see containsNonWhitespaceChars() - */ - inline bool isEmpty() const noexcept { return text[0] == 0; } - - /** Returns true if the string contains at least one character. - Note that there's also an isEmpty() method to help write readable code. - @see containsNonWhitespaceChars() - */ - inline bool isNotEmpty() const noexcept { return text[0] != 0; } - - /** Resets this string to be empty. */ - void clear() noexcept; - - /** Case-insensitive comparison with another string. */ - bool equalsIgnoreCase (const String& other) const noexcept; - - /** Case-insensitive comparison with another string. */ - bool equalsIgnoreCase (StringRef other) const noexcept; - - /** Case-insensitive comparison with another string. */ - bool equalsIgnoreCase (const wchar_t* other) const noexcept; - - /** Case-insensitive comparison with another string. */ - bool equalsIgnoreCase (const char* other) const noexcept; - - /** Case-sensitive comparison with another string. - @returns 0 if the two strings are identical; negative if this string comes before - the other one alphabetically, or positive if it comes after it. - */ - int compare (const String& other) const noexcept; - - /** Case-sensitive comparison with another string. - @returns 0 if the two strings are identical; negative if this string comes before - the other one alphabetically, or positive if it comes after it. - */ - int compare (const char* other) const noexcept; - - /** Case-sensitive comparison with another string. - @returns 0 if the two strings are identical; negative if this string comes before - the other one alphabetically, or positive if it comes after it. - */ - int compare (const wchar_t* other) const noexcept; - - /** Case-insensitive comparison with another string. - @returns 0 if the two strings are identical; negative if this string comes before - the other one alphabetically, or positive if it comes after it. - */ - int compareIgnoreCase (const String& other) const noexcept; - - /** Compares two strings, taking into account textual characteristics like numbers and spaces. - - This comparison is case-insensitive and can detect words and embedded numbers in the - strings, making it good for sorting human-readable lists of things like filenames. - - @returns 0 if the two strings are identical; negative if this string comes before - the other one alphabetically, or positive if it comes after it. - */ - int compareNatural (StringRef other) const noexcept; - - /** Tests whether the string begins with another string. - If the parameter is an empty string, this will always return true. - Uses a case-sensitive comparison. - */ - bool startsWith (StringRef text) const noexcept; - - /** Tests whether the string begins with a particular character. - If the character is 0, this will always return false. - Uses a case-sensitive comparison. - */ - bool startsWithChar (juce_wchar character) const noexcept; - - /** Tests whether the string begins with another string. - If the parameter is an empty string, this will always return true. - Uses a case-insensitive comparison. - */ - bool startsWithIgnoreCase (StringRef text) const noexcept; - - /** Tests whether the string ends with another string. - If the parameter is an empty string, this will always return true. - Uses a case-sensitive comparison. - */ - bool endsWith (StringRef text) const noexcept; - - /** Tests whether the string ends with a particular character. - If the character is 0, this will always return false. - Uses a case-sensitive comparison. - */ - bool endsWithChar (juce_wchar character) const noexcept; - - /** Tests whether the string ends with another string. - If the parameter is an empty string, this will always return true. - Uses a case-insensitive comparison. - */ - bool endsWithIgnoreCase (StringRef text) const noexcept; - - /** Tests whether the string contains another substring. - If the parameter is an empty string, this will always return true. - Uses a case-sensitive comparison. - */ - bool contains (StringRef text) const noexcept; - - /** Tests whether the string contains a particular character. - Uses a case-sensitive comparison. - */ - bool containsChar (juce_wchar character) const noexcept; - - /** Tests whether the string contains another substring. - Uses a case-insensitive comparison. - */ - bool containsIgnoreCase (StringRef text) const noexcept; - - /** Tests whether the string contains another substring as a distinct word. - - @returns true if the string contains this word, surrounded by - non-alphanumeric characters - @see indexOfWholeWord, containsWholeWordIgnoreCase - */ - bool containsWholeWord (StringRef wordToLookFor) const noexcept; - - /** Tests whether the string contains another substring as a distinct word. - - @returns true if the string contains this word, surrounded by - non-alphanumeric characters - @see indexOfWholeWordIgnoreCase, containsWholeWord - */ - bool containsWholeWordIgnoreCase (StringRef wordToLookFor) const noexcept; - - /** Finds an instance of another substring if it exists as a distinct word. - - @returns if the string contains this word, surrounded by non-alphanumeric characters, - then this will return the index of the start of the substring. If it isn't - found, then it will return -1 - @see indexOfWholeWordIgnoreCase, containsWholeWord - */ - int indexOfWholeWord (StringRef wordToLookFor) const noexcept; - - /** Finds an instance of another substring if it exists as a distinct word. - - @returns if the string contains this word, surrounded by non-alphanumeric characters, - then this will return the index of the start of the substring. If it isn't - found, then it will return -1 - @see indexOfWholeWord, containsWholeWordIgnoreCase - */ - int indexOfWholeWordIgnoreCase (StringRef wordToLookFor) const noexcept; - - /** Looks for any of a set of characters in the string. - Uses a case-sensitive comparison. - - @returns true if the string contains any of the characters from - the string that is passed in. - */ - bool containsAnyOf (StringRef charactersItMightContain) const noexcept; - - /** Looks for a set of characters in the string. - Uses a case-sensitive comparison. - - @returns Returns false if any of the characters in this string do not occur in - the parameter string. If this string is empty, the return value will - always be true. - */ - bool containsOnly (StringRef charactersItMightContain) const noexcept; - - /** Returns true if this string contains any non-whitespace characters. - - This will return false if the string contains only whitespace characters, or - if it's empty. - - It is equivalent to calling "myString.trim().isNotEmpty()". - */ - bool containsNonWhitespaceChars() const noexcept; - - /** Returns true if the string matches this simple wildcard expression. - - So for example String ("abcdef").matchesWildcard ("*DEF", true) would return true. - - This isn't a full-blown regex though! The only wildcard characters supported - are "*" and "?". It's mainly intended for filename pattern matching. - */ - bool matchesWildcard (StringRef wildcard, bool ignoreCase) const noexcept; - - //============================================================================== - // Substring location methods.. - - /** Searches for a character inside this string. - Uses a case-sensitive comparison. - @returns the index of the first occurrence of the character in this - string, or -1 if it's not found. - */ - int indexOfChar (juce_wchar characterToLookFor) const noexcept; - - /** Searches for a character inside this string. - Uses a case-sensitive comparison. - @param startIndex the index from which the search should proceed - @param characterToLookFor the character to look for - @returns the index of the first occurrence of the character in this - string, or -1 if it's not found. - */ - int indexOfChar (int startIndex, juce_wchar characterToLookFor) const noexcept; - - /** Returns the index of the first character that matches one of the characters - passed-in to this method. - - This scans the string, beginning from the startIndex supplied, and if it finds - a character that appears in the string charactersToLookFor, it returns its index. - - If none of these characters are found, it returns -1. - - If ignoreCase is true, the comparison will be case-insensitive. - - @see indexOfChar, lastIndexOfAnyOf - */ - int indexOfAnyOf (StringRef charactersToLookFor, - int startIndex = 0, - bool ignoreCase = false) const noexcept; - - /** Searches for a substring within this string. - Uses a case-sensitive comparison. - @returns the index of the first occurrence of this substring, or -1 if it's not found. - If textToLookFor is an empty string, this will always return 0. - */ - int indexOf (StringRef textToLookFor) const noexcept; - - /** Searches for a substring within this string. - Uses a case-sensitive comparison. - @param startIndex the index from which the search should proceed - @param textToLookFor the string to search for - @returns the index of the first occurrence of this substring, or -1 if it's not found. - If textToLookFor is an empty string, this will always return -1. - */ - int indexOf (int startIndex, StringRef textToLookFor) const noexcept; - - /** Searches for a substring within this string. - Uses a case-insensitive comparison. - @returns the index of the first occurrence of this substring, or -1 if it's not found. - If textToLookFor is an empty string, this will always return 0. - */ - int indexOfIgnoreCase (StringRef textToLookFor) const noexcept; - - /** Searches for a substring within this string. - Uses a case-insensitive comparison. - @param startIndex the index from which the search should proceed - @param textToLookFor the string to search for - @returns the index of the first occurrence of this substring, or -1 if it's not found. - If textToLookFor is an empty string, this will always return -1. - */ - int indexOfIgnoreCase (int startIndex, StringRef textToLookFor) const noexcept; - - /** Searches for a character inside this string (working backwards from the end of the string). - Uses a case-sensitive comparison. - @returns the index of the last occurrence of the character in this string, or -1 if it's not found. - */ - int lastIndexOfChar (juce_wchar character) const noexcept; - - /** Searches for a substring inside this string (working backwards from the end of the string). - Uses a case-sensitive comparison. - @returns the index of the start of the last occurrence of the substring within this string, - or -1 if it's not found. If textToLookFor is an empty string, this will always return -1. - */ - int lastIndexOf (StringRef textToLookFor) const noexcept; - - /** Searches for a substring inside this string (working backwards from the end of the string). - Uses a case-insensitive comparison. - @returns the index of the start of the last occurrence of the substring within this string, or -1 - if it's not found. If textToLookFor is an empty string, this will always return -1. - */ - int lastIndexOfIgnoreCase (StringRef textToLookFor) const noexcept; - - /** Returns the index of the last character in this string that matches one of the - characters passed-in to this method. - - This scans the string backwards, starting from its end, and if it finds - a character that appears in the string charactersToLookFor, it returns its index. - - If none of these characters are found, it returns -1. - - If ignoreCase is true, the comparison will be case-insensitive. - - @see lastIndexOf, indexOfAnyOf - */ - int lastIndexOfAnyOf (StringRef charactersToLookFor, - bool ignoreCase = false) const noexcept; - - - //============================================================================== - // Substring extraction and manipulation methods.. - - /** Returns the character at this index in the string. - In a release build, no checks are made to see if the index is within a valid range, so be - careful! In a debug build, the index is checked and an assertion fires if it's out-of-range. - - Also beware that depending on the encoding format that the string is using internally, this - method may execute in either O(1) or O(n) time, so be careful when using it in your algorithms. - If you're scanning through a string to inspect its characters, you should never use this operator - for random access, it's far more efficient to call getCharPointer() to return a pointer, and - then to use that to iterate the string. - @see getCharPointer - */ - juce_wchar operator[] (int index) const noexcept; - - /** Returns the final character of the string. - If the string is empty this will return 0. - */ - juce_wchar getLastCharacter() const noexcept; - - //============================================================================== - /** Returns a subsection of the string. - - If the range specified is beyond the limits of the string, as much as - possible is returned. - - @param startIndex the index of the start of the substring needed - @param endIndex all characters from startIndex up to (but not including) - this index are returned - @see fromFirstOccurrenceOf, dropLastCharacters, getLastCharacters, upToFirstOccurrenceOf - */ - String substring (int startIndex, int endIndex) const; - - /** Returns a section of the string, starting from a given position. - - @param startIndex the first character to include. If this is beyond the end - of the string, an empty string is returned. If it is zero or - less, the whole string is returned. - @returns the substring from startIndex up to the end of the string - @see dropLastCharacters, getLastCharacters, fromFirstOccurrenceOf, upToFirstOccurrenceOf, fromLastOccurrenceOf - */ - String substring (int startIndex) const; - - /** Returns a version of this string with a number of characters removed - from the end. - - @param numberToDrop the number of characters to drop from the end of the - string. If this is greater than the length of the string, - an empty string will be returned. If zero or less, the - original string will be returned. - @see substring, fromFirstOccurrenceOf, upToFirstOccurrenceOf, fromLastOccurrenceOf, getLastCharacter - */ - String dropLastCharacters (int numberToDrop) const; - - /** Returns a number of characters from the end of the string. - - This returns the last numCharacters characters from the end of the string. If the - string is shorter than numCharacters, the whole string is returned. - - @see substring, dropLastCharacters, getLastCharacter - */ - String getLastCharacters (int numCharacters) const; - - //============================================================================== - /** Returns a section of the string starting from a given substring. - - This will search for the first occurrence of the given substring, and - return the section of the string starting from the point where this is - found (optionally not including the substring itself). - - e.g. for the string "123456", fromFirstOccurrenceOf ("34", true) would return "3456", and - fromFirstOccurrenceOf ("34", false) would return "56". - - If the substring isn't found, the method will return an empty string. - - If ignoreCase is true, the comparison will be case-insensitive. - - @see upToFirstOccurrenceOf, fromLastOccurrenceOf - */ - String fromFirstOccurrenceOf (StringRef substringToStartFrom, - bool includeSubStringInResult, - bool ignoreCase) const; - - /** Returns a section of the string starting from the last occurrence of a given substring. - - Similar to fromFirstOccurrenceOf(), but using the last occurrence of the substring, and - unlike fromFirstOccurrenceOf(), if the substring isn't found, this method will - return the whole of the original string. - - @see fromFirstOccurrenceOf, upToLastOccurrenceOf - */ - String fromLastOccurrenceOf (StringRef substringToFind, - bool includeSubStringInResult, - bool ignoreCase) const; - - /** Returns the start of this string, up to the first occurrence of a substring. - - This will search for the first occurrence of a given substring, and then - return a copy of the string, up to the position of this substring, - optionally including or excluding the substring itself in the result. - - e.g. for the string "123456", upTo ("34", false) would return "12", and - upTo ("34", true) would return "1234". - - If the substring isn't found, this will return the whole of the original string. - - @see upToLastOccurrenceOf, fromFirstOccurrenceOf - */ - String upToFirstOccurrenceOf (StringRef substringToEndWith, - bool includeSubStringInResult, - bool ignoreCase) const; - - /** Returns the start of this string, up to the last occurrence of a substring. - - Similar to upToFirstOccurrenceOf(), but this finds the last occurrence rather than the first. - If the substring isn't found, this will return the whole of the original string. - - @see upToFirstOccurrenceOf, fromFirstOccurrenceOf - */ - String upToLastOccurrenceOf (StringRef substringToFind, - bool includeSubStringInResult, - bool ignoreCase) const; - - //============================================================================== - /** Returns a copy of this string with any whitespace characters removed from the start and end. */ - String trim() const; - - /** Returns a copy of this string with any whitespace characters removed from the start. */ - String trimStart() const; - - /** Returns a copy of this string with any whitespace characters removed from the end. */ - String trimEnd() const; - - /** Returns a copy of this string, having removed a specified set of characters from its start. - Characters are removed from the start of the string until it finds one that is not in the - specified set, and then it stops. - @param charactersToTrim the set of characters to remove. - @see trim, trimStart, trimCharactersAtEnd - */ - String trimCharactersAtStart (StringRef charactersToTrim) const; - - /** Returns a copy of this string, having removed a specified set of characters from its end. - Characters are removed from the end of the string until it finds one that is not in the - specified set, and then it stops. - @param charactersToTrim the set of characters to remove. - @see trim, trimEnd, trimCharactersAtStart - */ - String trimCharactersAtEnd (StringRef charactersToTrim) const; - - //============================================================================== - /** Returns an upper-case version of this string. */ - String toUpperCase() const; - - /** Returns an lower-case version of this string. */ - String toLowerCase() const; - - //============================================================================== - /** Replaces a sub-section of the string with another string. - - This will return a copy of this string, with a set of characters - from startIndex to startIndex + numCharsToReplace removed, and with - a new string inserted in their place. - - Note that this is a const method, and won't alter the string itself. - - @param startIndex the first character to remove. If this is beyond the bounds of the string, - it will be constrained to a valid range. - @param numCharactersToReplace the number of characters to remove. If zero or less, no - characters will be taken out. - @param stringToInsert the new string to insert at startIndex after the characters have been - removed. - */ - String replaceSection (int startIndex, - int numCharactersToReplace, - StringRef stringToInsert) const; - - /** Replaces all occurrences of a substring with another string. - - Returns a copy of this string, with any occurrences of stringToReplace - swapped for stringToInsertInstead. - - Note that this is a const method, and won't alter the string itself. - */ - String replace (StringRef stringToReplace, - StringRef stringToInsertInstead, - bool ignoreCase = false) const; - - /** Returns a string with all occurrences of a character replaced with a different one. */ - String replaceCharacter (juce_wchar characterToReplace, - juce_wchar characterToInsertInstead) const; - - /** Replaces a set of characters with another set. - - Returns a string in which each character from charactersToReplace has been replaced - by the character at the equivalent position in newCharacters (so the two strings - passed in must be the same length). - - e.g. replaceCharacters ("abc", "def") replaces 'a' with 'd', 'b' with 'e', etc. - - Note that this is a const method, and won't affect the string itself. - */ - String replaceCharacters (StringRef charactersToReplace, - StringRef charactersToInsertInstead) const; - - /** Returns a version of this string that only retains a fixed set of characters. - - This will return a copy of this string, omitting any characters which are not - found in the string passed-in. - - e.g. for "1122334455", retainCharacters ("432") would return "223344" - - Note that this is a const method, and won't alter the string itself. - */ - String retainCharacters (StringRef charactersToRetain) const; - - /** Returns a version of this string with a set of characters removed. - - This will return a copy of this string, omitting any characters which are - found in the string passed-in. - - e.g. for "1122334455", removeCharacters ("432") would return "1155" - - Note that this is a const method, and won't alter the string itself. - */ - String removeCharacters (StringRef charactersToRemove) const; - - /** Returns a section from the start of the string that only contains a certain set of characters. - - This returns the leftmost section of the string, up to (and not including) the - first character that doesn't appear in the string passed in. - */ - String initialSectionContainingOnly (StringRef permittedCharacters) const; - - /** Returns a section from the start of the string that only contains a certain set of characters. - - This returns the leftmost section of the string, up to (and not including) the - first character that occurs in the string passed in. (If none of the specified - characters are found in the string, the return value will just be the original string). - */ - String initialSectionNotContaining (StringRef charactersToStopAt) const; - - //============================================================================== - /** Checks whether the string might be in quotation marks. - - @returns true if the string begins with a quote character (either a double or single quote). - It is also true if there is whitespace before the quote, but it doesn't check the end of the string. - @see unquoted, quoted - */ - bool isQuotedString() const; - - /** Removes quotation marks from around the string, (if there are any). - - Returns a copy of this string with any quotes removed from its ends. Quotes that aren't - at the ends of the string are not affected. If there aren't any quotes, the original string - is returned. - - Note that this is a const method, and won't alter the string itself. - - @see isQuotedString, quoted - */ - String unquoted() const; - - /** Adds quotation marks around a string. - - This will return a copy of the string with a quote at the start and end, (but won't - add the quote if there's already one there, so it's safe to call this on strings that - may already have quotes around them). - - Note that this is a const method, and won't alter the string itself. - - @param quoteCharacter the character to add at the start and end - @see isQuotedString, unquoted - */ - String quoted (juce_wchar quoteCharacter = '"') const; - - - //============================================================================== - /** Creates a string which is a version of a string repeated and joined together. - - @param stringToRepeat the string to repeat - @param numberOfTimesToRepeat how many times to repeat it - */ - static String repeatedString (StringRef stringToRepeat, - int numberOfTimesToRepeat); - - /** Returns a copy of this string with the specified character repeatedly added to its - beginning until the total length is at least the minimum length specified. - */ - String paddedLeft (juce_wchar padCharacter, int minimumLength) const; - - /** Returns a copy of this string with the specified character repeatedly added to its - end until the total length is at least the minimum length specified. - */ - String paddedRight (juce_wchar padCharacter, int minimumLength) const; - - /** Creates a string from data in an unknown format. - - This looks at some binary data and tries to guess whether it's Unicode - or 8-bit characters, then returns a string that represents it correctly. - - Should be able to handle Unicode endianness correctly, by looking at - the first two bytes. - */ - static String createStringFromData (const void* data, int size); - - /** Creates a String from a printf-style parameter list. - - I don't like this method. I don't use it myself, and I recommend avoiding it and - using the operator<< methods or pretty much anything else instead. It's only provided - here because of the popular unrest that was stirred-up when I tried to remove it... - - If you're really determined to use it, at least make sure that you never, ever, - pass any String objects to it as parameters. And bear in mind that internally, depending - on the platform, it may be using wchar_t or char character types, so that even string - literals can't be safely used as parameters if you're writing portable code. - */ - static String formatted (const String formatString, ... ); - - //============================================================================== - // Numeric conversions.. - - /** Creates a string containing this signed 32-bit integer as a decimal number. - @see getIntValue, getFloatValue, getDoubleValue, toHexString - */ - explicit String (int decimalInteger); - - /** Creates a string containing this unsigned 32-bit integer as a decimal number. - @see getIntValue, getFloatValue, getDoubleValue, toHexString - */ - explicit String (unsigned int decimalInteger); - - /** Creates a string containing this signed 16-bit integer as a decimal number. - @see getIntValue, getFloatValue, getDoubleValue, toHexString - */ - explicit String (short decimalInteger); - - /** Creates a string containing this unsigned 16-bit integer as a decimal number. - @see getIntValue, getFloatValue, getDoubleValue, toHexString - */ - explicit String (unsigned short decimalInteger); - - /** Creates a string containing this signed 64-bit integer as a decimal number. - @see getLargeIntValue, getFloatValue, getDoubleValue, toHexString - */ - explicit String (int64 largeIntegerValue); - - /** Creates a string containing this unsigned 64-bit integer as a decimal number. - @see getLargeIntValue, getFloatValue, getDoubleValue, toHexString - */ - explicit String (uint64 largeIntegerValue); - - /** Creates a string representing this floating-point number. - @param floatValue the value to convert to a string - @see getDoubleValue, getIntValue - */ - explicit String (float floatValue); - - /** Creates a string representing this floating-point number. - @param doubleValue the value to convert to a string - @see getFloatValue, getIntValue - */ - explicit String (double doubleValue); - - /** Creates a string representing this floating-point number. - @param floatValue the value to convert to a string - @param numberOfDecimalPlaces if this is > 0, it will format the number using that many - decimal places, and will not use exponent notation. If 0 or - less, it will use exponent notation if necessary. - @see getDoubleValue, getIntValue - */ - String (float floatValue, int numberOfDecimalPlaces); - - /** Creates a string representing this floating-point number. - @param doubleValue the value to convert to a string - @param numberOfDecimalPlaces if this is > 0, it will format the number using that many - decimal places, and will not use exponent notation. If 0 or - less, it will use exponent notation if necessary. - @see getFloatValue, getIntValue - */ - String (double doubleValue, int numberOfDecimalPlaces); - - /** Reads the value of the string as a decimal number (up to 32 bits in size). - - @returns the value of the string as a 32 bit signed base-10 integer. - @see getTrailingIntValue, getHexValue32, getHexValue64 - */ - int getIntValue() const noexcept; - - /** Reads the value of the string as a decimal number (up to 64 bits in size). - @returns the value of the string as a 64 bit signed base-10 integer. - */ - int64 getLargeIntValue() const noexcept; - - /** Parses a decimal number from the end of the string. - - This will look for a value at the end of the string. - e.g. for "321 xyz654" it will return 654; for "2 3 4" it'll return 4. - - Negative numbers are not handled, so "xyz-5" returns 5. - - @see getIntValue - */ - int getTrailingIntValue() const noexcept; - - /** Parses this string as a floating point number. - - @returns the value of the string as a 32-bit floating point value. - @see getDoubleValue - */ - float getFloatValue() const noexcept; - - /** Parses this string as a floating point number. - - @returns the value of the string as a 64-bit floating point value. - @see getFloatValue - */ - double getDoubleValue() const noexcept; - - /** Parses the string as a hexadecimal number. - - Non-hexadecimal characters in the string are ignored. - - If the string contains too many characters, then the lowest significant - digits are returned, e.g. "ffff12345678" would produce 0x12345678. - - @returns a 32-bit number which is the value of the string in hex. - */ - int getHexValue32() const noexcept; - - /** Parses the string as a hexadecimal number. - - Non-hexadecimal characters in the string are ignored. - - If the string contains too many characters, then the lowest significant - digits are returned, e.g. "ffff1234567812345678" would produce 0x1234567812345678. - - @returns a 64-bit number which is the value of the string in hex. - */ - int64 getHexValue64() const noexcept; - - /** Creates a string representing this 32-bit value in hexadecimal. */ - static String toHexString (int number); - - /** Creates a string representing this 64-bit value in hexadecimal. */ - static String toHexString (int64 number); - - /** Creates a string representing this 16-bit value in hexadecimal. */ - static String toHexString (short number); - - /** Creates a string containing a hex dump of a block of binary data. - - @param data the binary data to use as input - @param size how many bytes of data to use - @param groupSize how many bytes are grouped together before inserting a - space into the output. e.g. group size 0 has no spaces, - group size 1 looks like: "be a1 c2 ff", group size 2 looks - like "bea1 c2ff". - */ - static String toHexString (const void* data, int size, int groupSize = 1); - - //============================================================================== - /** Returns the character pointer currently being used to store this string. - - Because it returns a reference to the string's internal data, the pointer - that is returned must not be stored anywhere, as it can be deleted whenever the - string changes. - */ - inline CharPointerType getCharPointer() const noexcept { return text; } - - /** Returns a pointer to a UTF-8 version of this string. - - Because it returns a reference to the string's internal data, the pointer - that is returned must not be stored anywhere, as it can be deleted whenever the - string changes. - - To find out how many bytes you need to store this string as UTF-8, you can call - CharPointer_UTF8::getBytesRequiredFor (myString.getCharPointer()) - - @see toRawUTF8, getCharPointer, toUTF16, toUTF32 - */ - CharPointer_UTF8 toUTF8() const; - - /** Returns a pointer to a UTF-8 version of this string. - - Because it returns a reference to the string's internal data, the pointer - that is returned must not be stored anywhere, as it can be deleted whenever the - string changes. - - To find out how many bytes you need to store this string as UTF-8, you can call - CharPointer_UTF8::getBytesRequiredFor (myString.getCharPointer()) - - @see getCharPointer, toUTF8, toUTF16, toUTF32 - */ - const char* toRawUTF8() const; - - /** Returns a pointer to a UTF-16 version of this string. - - Because it returns a reference to the string's internal data, the pointer - that is returned must not be stored anywhere, as it can be deleted whenever the - string changes. - - To find out how many bytes you need to store this string as UTF-16, you can call - CharPointer_UTF16::getBytesRequiredFor (myString.getCharPointer()) - - @see getCharPointer, toUTF8, toUTF32 - */ - CharPointer_UTF16 toUTF16() const; - - /** Returns a pointer to a UTF-32 version of this string. - - Because it returns a reference to the string's internal data, the pointer - that is returned must not be stored anywhere, as it can be deleted whenever the - string changes. - - @see getCharPointer, toUTF8, toUTF16 - */ - CharPointer_UTF32 toUTF32() const; - - /** Returns a pointer to a wchar_t version of this string. - - Because it returns a reference to the string's internal data, the pointer - that is returned must not be stored anywhere, as it can be deleted whenever the - string changes. - - Bear in mind that the wchar_t type is different on different platforms, so on - Windows, this will be equivalent to calling toUTF16(), on unix it'll be the same - as calling toUTF32(), etc. - - @see getCharPointer, toUTF8, toUTF16, toUTF32 - */ - const wchar_t* toWideCharPointer() const; - - /** */ - std::string toStdString() const; - - //============================================================================== - /** Creates a String from a UTF-8 encoded buffer. - If the size is < 0, it'll keep reading until it hits a zero. - */ - static String fromUTF8 (const char* utf8buffer, int bufferSizeBytes = -1); - - /** Returns the number of bytes required to represent this string as UTF8. - The number returned does NOT include the trailing zero. - @see toUTF8, copyToUTF8 - */ - size_t getNumBytesAsUTF8() const noexcept; - - //============================================================================== - /** Copies the string to a buffer as UTF-8 characters. - - Returns the number of bytes copied to the buffer, including the terminating null - character. - - To find out how many bytes you need to store this string as UTF-8, you can call - CharPointer_UTF8::getBytesRequiredFor (myString.getCharPointer()) - - @param destBuffer the place to copy it to; if this is a null pointer, the method just - returns the number of bytes required (including the terminating null character). - @param maxBufferSizeBytes the size of the destination buffer, in bytes. If the string won't fit, it'll - put in as many as it can while still allowing for a terminating null char at the - end, and will return the number of bytes that were actually used. - @see CharPointer_UTF8::writeWithDestByteLimit - */ - size_t copyToUTF8 (CharPointer_UTF8::CharType* destBuffer, size_t maxBufferSizeBytes) const noexcept; - - /** Copies the string to a buffer as UTF-16 characters. - - Returns the number of bytes copied to the buffer, including the terminating null - character. - - To find out how many bytes you need to store this string as UTF-16, you can call - CharPointer_UTF16::getBytesRequiredFor (myString.getCharPointer()) - - @param destBuffer the place to copy it to; if this is a null pointer, the method just - returns the number of bytes required (including the terminating null character). - @param maxBufferSizeBytes the size of the destination buffer, in bytes. If the string won't fit, it'll - put in as many as it can while still allowing for a terminating null char at the - end, and will return the number of bytes that were actually used. - @see CharPointer_UTF16::writeWithDestByteLimit - */ - size_t copyToUTF16 (CharPointer_UTF16::CharType* destBuffer, size_t maxBufferSizeBytes) const noexcept; - - /** Copies the string to a buffer as UTF-32 characters. - - Returns the number of bytes copied to the buffer, including the terminating null - character. - - To find out how many bytes you need to store this string as UTF-32, you can call - CharPointer_UTF32::getBytesRequiredFor (myString.getCharPointer()) - - @param destBuffer the place to copy it to; if this is a null pointer, the method just - returns the number of bytes required (including the terminating null character). - @param maxBufferSizeBytes the size of the destination buffer, in bytes. If the string won't fit, it'll - put in as many as it can while still allowing for a terminating null char at the - end, and will return the number of bytes that were actually used. - @see CharPointer_UTF32::writeWithDestByteLimit - */ - size_t copyToUTF32 (CharPointer_UTF32::CharType* destBuffer, size_t maxBufferSizeBytes) const noexcept; - - //============================================================================== - /** Increases the string's internally allocated storage. - - Although the string's contents won't be affected by this call, it will - increase the amount of memory allocated internally for the string to grow into. - - If you're about to make a large number of calls to methods such - as += or <<, it's more efficient to preallocate enough extra space - beforehand, so that these methods won't have to keep resizing the string - to append the extra characters. - - @param numBytesNeeded the number of bytes to allocate storage for. If this - value is less than the currently allocated size, it will - have no effect. - */ - void preallocateBytes (size_t numBytesNeeded); - - /** Swaps the contents of this string with another one. - This is a very fast operation, as no allocation or copying needs to be done. - */ - void swapWith (String& other) noexcept; - - //============================================================================== - #if JUCE_MAC || JUCE_IOS || DOXYGEN - /** OSX ONLY - Creates a String from an OSX CFString. */ - static String fromCFString (CFStringRef cfString); - - /** OSX ONLY - Converts this string to a CFString. - Remember that you must use CFRelease() to free the returned string when you're - finished with it. - */ - CFStringRef toCFString() const; - - /** OSX ONLY - Returns a copy of this string in which any decomposed unicode characters have - been converted to their precomposed equivalents. */ - String convertToPrecomposedUnicode() const; - #endif - - /** Returns the number of String objects which are currently sharing the same internal - data as this one. - */ - int getReferenceCount() const noexcept; - -private: - //============================================================================== - CharPointerType text; - - //============================================================================== - struct PreallocationBytes - { - explicit PreallocationBytes (size_t) noexcept; - size_t numBytes; - }; - - explicit String (const PreallocationBytes&); // This constructor preallocates a certain amount of memory - size_t getByteOffsetOfEnd() const noexcept; - JUCE_DEPRECATED (String (const String&, size_t)); - - // This private cast operator should prevent strings being accidentally cast - // to bools (this is possible because the compiler can add an implicit cast - // via a const char*) - operator bool() const noexcept { return false; } -}; - -//============================================================================== -/** Concatenates two strings. */ -JUCE_API String JUCE_CALLTYPE operator+ (const char* string1, const String& string2); -/** Concatenates two strings. */ -JUCE_API String JUCE_CALLTYPE operator+ (const wchar_t* string1, const String& string2); -/** Concatenates two strings. */ -JUCE_API String JUCE_CALLTYPE operator+ (char string1, const String& string2); -/** Concatenates two strings. */ -JUCE_API String JUCE_CALLTYPE operator+ (wchar_t string1, const String& string2); -#if ! JUCE_NATIVE_WCHAR_IS_UTF32 -/** Concatenates two strings. */ -JUCE_API String JUCE_CALLTYPE operator+ (juce_wchar string1, const String& string2); -#endif - -/** Concatenates two strings. */ -JUCE_API String JUCE_CALLTYPE operator+ (String string1, const String& string2); -/** Concatenates two strings. */ -JUCE_API String JUCE_CALLTYPE operator+ (String string1, const char* string2); -/** Concatenates two strings. */ -JUCE_API String JUCE_CALLTYPE operator+ (String string1, const wchar_t* string2); -/** Concatenates two strings. */ -JUCE_API String JUCE_CALLTYPE operator+ (String string1, char characterToAppend); -/** Concatenates two strings. */ -JUCE_API String JUCE_CALLTYPE operator+ (String string1, wchar_t characterToAppend); -#if ! JUCE_NATIVE_WCHAR_IS_UTF32 -/** Concatenates two strings. */ -JUCE_API String JUCE_CALLTYPE operator+ (String string1, juce_wchar characterToAppend); -#endif - -//============================================================================== -/** Appends a character at the end of a string. */ -JUCE_API String& JUCE_CALLTYPE operator<< (String& string1, char characterToAppend); -/** Appends a character at the end of a string. */ -JUCE_API String& JUCE_CALLTYPE operator<< (String& string1, wchar_t characterToAppend); -#if ! JUCE_NATIVE_WCHAR_IS_UTF32 -/** Appends a character at the end of a string. */ -JUCE_API String& JUCE_CALLTYPE operator<< (String& string1, juce_wchar characterToAppend); -#endif - -/** Appends a string to the end of the first one. */ -JUCE_API String& JUCE_CALLTYPE operator<< (String& string1, const char* string2); -/** Appends a string to the end of the first one. */ -JUCE_API String& JUCE_CALLTYPE operator<< (String& string1, const wchar_t* string2); -/** Appends a string to the end of the first one. */ -JUCE_API String& JUCE_CALLTYPE operator<< (String& string1, const String& string2); - -/** Appends a decimal number at the end of a string. */ -JUCE_API String& JUCE_CALLTYPE operator<< (String& string1, short number); -/** Appends a decimal number at the end of a string. */ -JUCE_API String& JUCE_CALLTYPE operator<< (String& string1, int number); -/** Appends a decimal number at the end of a string. */ -JUCE_API String& JUCE_CALLTYPE operator<< (String& string1, long number); -/** Appends a decimal number at the end of a string. */ -JUCE_API String& JUCE_CALLTYPE operator<< (String& string1, int64 number); -/** Appends a decimal number at the end of a string. */ -JUCE_API String& JUCE_CALLTYPE operator<< (String& string1, uint64 number); -/** Appends a decimal number at the end of a string. */ -JUCE_API String& JUCE_CALLTYPE operator<< (String& string1, float number); -/** Appends a decimal number at the end of a string. */ -JUCE_API String& JUCE_CALLTYPE operator<< (String& string1, double number); - -//============================================================================== -/** Case-sensitive comparison of two strings. */ -JUCE_API bool JUCE_CALLTYPE operator== (const String& string1, const String& string2) noexcept; -/** Case-sensitive comparison of two strings. */ -JUCE_API bool JUCE_CALLTYPE operator== (const String& string1, const char* string2) noexcept; -/** Case-sensitive comparison of two strings. */ -JUCE_API bool JUCE_CALLTYPE operator== (const String& string1, const wchar_t* string2) noexcept; -/** Case-sensitive comparison of two strings. */ -JUCE_API bool JUCE_CALLTYPE operator== (const String& string1, const CharPointer_UTF8 string2) noexcept; -/** Case-sensitive comparison of two strings. */ -JUCE_API bool JUCE_CALLTYPE operator== (const String& string1, const CharPointer_UTF16 string2) noexcept; -/** Case-sensitive comparison of two strings. */ -JUCE_API bool JUCE_CALLTYPE operator== (const String& string1, const CharPointer_UTF32 string2) noexcept; - -/** Case-sensitive comparison of two strings. */ -JUCE_API bool JUCE_CALLTYPE operator!= (const String& string1, const String& string2) noexcept; -/** Case-sensitive comparison of two strings. */ -JUCE_API bool JUCE_CALLTYPE operator!= (const String& string1, const char* string2) noexcept; -/** Case-sensitive comparison of two strings. */ -JUCE_API bool JUCE_CALLTYPE operator!= (const String& string1, const wchar_t* string2) noexcept; -/** Case-sensitive comparison of two strings. */ -JUCE_API bool JUCE_CALLTYPE operator!= (const String& string1, const CharPointer_UTF8 string2) noexcept; -/** Case-sensitive comparison of two strings. */ -JUCE_API bool JUCE_CALLTYPE operator!= (const String& string1, const CharPointer_UTF16 string2) noexcept; -/** Case-sensitive comparison of two strings. */ -JUCE_API bool JUCE_CALLTYPE operator!= (const String& string1, const CharPointer_UTF32 string2) noexcept; - -/** Case-sensitive comparison of two strings. */ -JUCE_API bool JUCE_CALLTYPE operator> (const String& string1, const String& string2) noexcept; -/** Case-sensitive comparison of two strings. */ -JUCE_API bool JUCE_CALLTYPE operator< (const String& string1, const String& string2) noexcept; -/** Case-sensitive comparison of two strings. */ -JUCE_API bool JUCE_CALLTYPE operator>= (const String& string1, const String& string2) noexcept; -/** Case-sensitive comparison of two strings. */ -JUCE_API bool JUCE_CALLTYPE operator<= (const String& string1, const String& string2) noexcept; - -//============================================================================== -/** This operator allows you to write a juce String directly to std output streams. - This is handy for writing strings to std::cout, std::cerr, etc. -*/ -template -std::basic_ostream & JUCE_CALLTYPE operator<< (std::basic_ostream & stream, const String& stringToWrite) -{ - return stream << stringToWrite.toRawUTF8(); -} - -/** This operator allows you to write a juce String directly to std output streams. - This is handy for writing strings to std::wcout, std::wcerr, etc. -*/ -template -std::basic_ostream & JUCE_CALLTYPE operator<< (std::basic_ostream & stream, const String& stringToWrite) -{ - return stream << stringToWrite.toWideCharPointer(); -} - -/** Writes a string to an OutputStream as UTF8. */ -JUCE_API OutputStream& JUCE_CALLTYPE operator<< (OutputStream& stream, const String& stringToWrite); - -/** Writes a string to an OutputStream as UTF8. */ -JUCE_API OutputStream& JUCE_CALLTYPE operator<< (OutputStream& stream, StringRef stringToWrite); - - -#endif // JUCE_STRING_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/text/juce_StringArray.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/text/juce_StringArray.cpp deleted file mode 100644 index 6c49138623..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/text/juce_StringArray.cpp +++ /dev/null @@ -1,485 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -StringArray::StringArray() noexcept -{ -} - -StringArray::StringArray (const StringArray& other) - : strings (other.strings) -{ -} - -#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS -StringArray::StringArray (StringArray&& other) noexcept - : strings (static_cast &&> (other.strings)) -{ -} -#endif - -StringArray::StringArray (const String& firstValue) -{ - strings.add (firstValue); -} - -StringArray::StringArray (const String* initialStrings, int numberOfStrings) -{ - strings.addArray (initialStrings, numberOfStrings); -} - -StringArray::StringArray (const char* const* initialStrings) -{ - strings.addNullTerminatedArray (initialStrings); -} - -StringArray::StringArray (const char* const* initialStrings, int numberOfStrings) -{ - strings.addArray (initialStrings, numberOfStrings); -} - -StringArray::StringArray (const wchar_t* const* initialStrings) -{ - strings.addNullTerminatedArray (initialStrings); -} - -StringArray::StringArray (const wchar_t* const* initialStrings, int numberOfStrings) -{ - strings.addArray (initialStrings, numberOfStrings); -} - -StringArray& StringArray::operator= (const StringArray& other) -{ - strings = other.strings; - return *this; -} - -#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS -StringArray& StringArray::operator= (StringArray&& other) noexcept -{ - strings = static_cast &&> (other.strings); - return *this; -} -#endif - -StringArray::~StringArray() -{ -} - -bool StringArray::operator== (const StringArray& other) const noexcept -{ - return strings == other.strings; -} - -bool StringArray::operator!= (const StringArray& other) const noexcept -{ - return ! operator== (other); -} - -void StringArray::swapWith (StringArray& other) noexcept -{ - strings.swapWith (other.strings); -} - -void StringArray::clear() -{ - strings.clear(); -} - -void StringArray::clearQuick() -{ - strings.clearQuick(); -} - -const String& StringArray::operator[] (const int index) const noexcept -{ - if (isPositiveAndBelow (index, strings.size())) - return strings.getReference (index); - - return String::empty; -} - -String& StringArray::getReference (const int index) noexcept -{ - return strings.getReference (index); -} - -void StringArray::add (const String& newString) -{ - strings.add (newString); -} - -#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS -void StringArray::add (String&& stringToAdd) -{ - strings.add (static_cast (stringToAdd)); -} -#endif - -void StringArray::insert (const int index, const String& newString) -{ - strings.insert (index, newString); -} - -void StringArray::addIfNotAlreadyThere (const String& newString, const bool ignoreCase) -{ - if (! contains (newString, ignoreCase)) - add (newString); -} - -void StringArray::addArray (const StringArray& otherArray, int startIndex, int numElementsToAdd) -{ - if (startIndex < 0) - { - jassertfalse; - startIndex = 0; - } - - if (numElementsToAdd < 0 || startIndex + numElementsToAdd > otherArray.size()) - numElementsToAdd = otherArray.size() - startIndex; - - while (--numElementsToAdd >= 0) - strings.add (otherArray.strings.getReference (startIndex++)); -} - -void StringArray::set (const int index, const String& newString) -{ - strings.set (index, newString); -} - -bool StringArray::contains (StringRef stringToLookFor, const bool ignoreCase) const -{ - return indexOf (stringToLookFor, ignoreCase) >= 0; -} - -int StringArray::indexOf (StringRef stringToLookFor, const bool ignoreCase, int i) const -{ - if (i < 0) - i = 0; - - const int numElements = size(); - - if (ignoreCase) - { - for (; i < numElements; ++i) - if (strings.getReference(i).equalsIgnoreCase (stringToLookFor)) - return i; - } - else - { - for (; i < numElements; ++i) - if (stringToLookFor == strings.getReference (i)) - return i; - } - - return -1; -} - -void StringArray::move (const int currentIndex, const int newIndex) noexcept -{ - strings.move (currentIndex, newIndex); -} - -//============================================================================== -void StringArray::remove (const int index) -{ - strings.remove (index); -} - -void StringArray::removeString (StringRef stringToRemove, const bool ignoreCase) -{ - if (ignoreCase) - { - for (int i = size(); --i >= 0;) - if (strings.getReference(i).equalsIgnoreCase (stringToRemove)) - strings.remove (i); - } - else - { - for (int i = size(); --i >= 0;) - if (stringToRemove == strings.getReference (i)) - strings.remove (i); - } -} - -void StringArray::removeRange (int startIndex, int numberToRemove) -{ - strings.removeRange (startIndex, numberToRemove); -} - -//============================================================================== -void StringArray::removeEmptyStrings (const bool removeWhitespaceStrings) -{ - if (removeWhitespaceStrings) - { - for (int i = size(); --i >= 0;) - if (! strings.getReference(i).containsNonWhitespaceChars()) - strings.remove (i); - } - else - { - for (int i = size(); --i >= 0;) - if (strings.getReference(i).isEmpty()) - strings.remove (i); - } -} - -void StringArray::trim() -{ - for (int i = size(); --i >= 0;) - { - String& s = strings.getReference(i); - s = s.trim(); - } -} - -//============================================================================== -struct InternalStringArrayComparator_CaseSensitive -{ - static int compareElements (String& s1, String& s2) noexcept { return s1.compare (s2); } -}; - -struct InternalStringArrayComparator_CaseInsensitive -{ - static int compareElements (String& s1, String& s2) noexcept { return s1.compareIgnoreCase (s2); } -}; - -struct InternalStringArrayComparator_Natural -{ - static int compareElements (String& s1, String& s2) noexcept { return s1.compareNatural (s2); } -}; - -void StringArray::sort (const bool ignoreCase) -{ - if (ignoreCase) - { - InternalStringArrayComparator_CaseInsensitive comp; - strings.sort (comp); - } - else - { - InternalStringArrayComparator_CaseSensitive comp; - strings.sort (comp); - } -} - -void StringArray::sortNatural() -{ - InternalStringArrayComparator_Natural comp; - strings.sort (comp); -} - -//============================================================================== -String StringArray::joinIntoString (StringRef separator, int start, int numberToJoin) const -{ - const int last = (numberToJoin < 0) ? size() - : jmin (size(), start + numberToJoin); - - if (start < 0) - start = 0; - - if (start >= last) - return String(); - - if (start == last - 1) - return strings.getReference (start); - - const size_t separatorBytes = separator.text.sizeInBytes() - sizeof (String::CharPointerType::CharType); - size_t bytesNeeded = separatorBytes * (size_t) (last - start - 1); - - for (int i = start; i < last; ++i) - bytesNeeded += strings.getReference(i).getCharPointer().sizeInBytes() - sizeof (String::CharPointerType::CharType); - - String result; - result.preallocateBytes (bytesNeeded); - - String::CharPointerType dest (result.getCharPointer()); - - while (start < last) - { - const String& s = strings.getReference (start); - - if (! s.isEmpty()) - dest.writeAll (s.getCharPointer()); - - if (++start < last && separatorBytes > 0) - dest.writeAll (separator.text); - } - - dest.writeNull(); - - return result; -} - -int StringArray::addTokens (StringRef text, const bool preserveQuotedStrings) -{ - return addTokens (text, " \n\r\t", preserveQuotedStrings ? "\"" : ""); -} - -int StringArray::addTokens (StringRef text, StringRef breakCharacters, StringRef quoteCharacters) -{ - int num = 0; - - if (text.isNotEmpty()) - { - for (String::CharPointerType t (text.text);;) - { - String::CharPointerType tokenEnd (CharacterFunctions::findEndOfToken (t, - breakCharacters.text, - quoteCharacters.text)); - strings.add (String (t, tokenEnd)); - ++num; - - if (tokenEnd.isEmpty()) - break; - - t = ++tokenEnd; - } - } - - return num; -} - -int StringArray::addLines (StringRef sourceText) -{ - int numLines = 0; - String::CharPointerType text (sourceText.text); - bool finished = text.isEmpty(); - - while (! finished) - { - for (String::CharPointerType startOfLine (text);;) - { - const String::CharPointerType endOfLine (text); - - switch (text.getAndAdvance()) - { - case 0: finished = true; break; - case '\n': break; - case '\r': if (*text == '\n') ++text; break; - default: continue; - } - - strings.add (String (startOfLine, endOfLine)); - ++numLines; - break; - } - } - - return numLines; -} - -StringArray StringArray::fromTokens (StringRef stringToTokenise, bool preserveQuotedStrings) -{ - StringArray s; - s.addTokens (stringToTokenise, preserveQuotedStrings); - return s; -} - -StringArray StringArray::fromTokens (StringRef stringToTokenise, - StringRef breakCharacters, - StringRef quoteCharacters) -{ - StringArray s; - s.addTokens (stringToTokenise, breakCharacters, quoteCharacters); - return s; -} - -StringArray StringArray::fromLines (StringRef stringToBreakUp) -{ - StringArray s; - s.addLines (stringToBreakUp); - return s; -} - -//============================================================================== -void StringArray::removeDuplicates (const bool ignoreCase) -{ - for (int i = 0; i < size() - 1; ++i) - { - const String s (strings.getReference(i)); - - for (int nextIndex = i + 1;;) - { - nextIndex = indexOf (s, ignoreCase, nextIndex); - - if (nextIndex < 0) - break; - - strings.remove (nextIndex); - } - } -} - -void StringArray::appendNumbersToDuplicates (const bool ignoreCase, - const bool appendNumberToFirstInstance, - CharPointer_UTF8 preNumberString, - CharPointer_UTF8 postNumberString) -{ - CharPointer_UTF8 defaultPre (" ("), defaultPost (")"); - - if (preNumberString.getAddress() == nullptr) - preNumberString = defaultPre; - - if (postNumberString.getAddress() == nullptr) - postNumberString = defaultPost; - - for (int i = 0; i < size() - 1; ++i) - { - String& s = strings.getReference(i); - - int nextIndex = indexOf (s, ignoreCase, i + 1); - - if (nextIndex >= 0) - { - const String original (s); - - int number = 0; - - if (appendNumberToFirstInstance) - s = original + String (preNumberString) + String (++number) + String (postNumberString); - else - ++number; - - while (nextIndex >= 0) - { - set (nextIndex, (*this)[nextIndex] + String (preNumberString) + String (++number) + String (postNumberString)); - nextIndex = indexOf (original, ignoreCase, nextIndex + 1); - } - } - } -} - -void StringArray::ensureStorageAllocated (int minNumElements) -{ - strings.ensureStorageAllocated (minNumElements); -} - -void StringArray::minimiseStorageOverheads() -{ - strings.minimiseStorageOverheads(); -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/text/juce_StringArray.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/text/juce_StringArray.h deleted file mode 100644 index 52335e1b45..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/text/juce_StringArray.h +++ /dev/null @@ -1,421 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_STRINGARRAY_H_INCLUDED -#define JUCE_STRINGARRAY_H_INCLUDED - - -//============================================================================== -/** - A special array for holding a list of strings. - - @see String, StringPairArray -*/ -class JUCE_API StringArray -{ -public: - //============================================================================== - /** Creates an empty string array */ - StringArray() noexcept; - - /** Creates a copy of another string array */ - StringArray (const StringArray&); - - #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS - StringArray (StringArray&&) noexcept; - #endif - - /** Creates an array containing a single string. */ - explicit StringArray (const String& firstValue); - - /** Creates an array from a raw array of strings. - @param strings an array of strings to add - @param numberOfStrings how many items there are in the array - */ - StringArray (const String* strings, int numberOfStrings); - - /** Creates a copy of an array of string literals. - @param strings an array of strings to add. Null pointers in the array will be - treated as empty strings - @param numberOfStrings how many items there are in the array - */ - StringArray (const char* const* strings, int numberOfStrings); - - /** Creates a copy of a null-terminated array of string literals. - - Each item from the array passed-in is added, until it encounters a null pointer, - at which point it stops. - */ - explicit StringArray (const char* const* strings); - - /** Creates a copy of a null-terminated array of string literals. - Each item from the array passed-in is added, until it encounters a null pointer, - at which point it stops. - */ - explicit StringArray (const wchar_t* const* strings); - - /** Creates a copy of an array of string literals. - @param strings an array of strings to add. Null pointers in the array will be - treated as empty strings - @param numberOfStrings how many items there are in the array - */ - StringArray (const wchar_t* const* strings, int numberOfStrings); - - /** Destructor. */ - ~StringArray(); - - /** Copies the contents of another string array into this one */ - StringArray& operator= (const StringArray&); - - #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS - StringArray& operator= (StringArray&&) noexcept; - #endif - - /** Swaps the contents of this and another StringArray. */ - void swapWith (StringArray&) noexcept; - - //============================================================================== - /** Compares two arrays. - Comparisons are case-sensitive. - @returns true only if the other array contains exactly the same strings in the same order - */ - bool operator== (const StringArray&) const noexcept; - - /** Compares two arrays. - Comparisons are case-sensitive. - @returns false if the other array contains exactly the same strings in the same order - */ - bool operator!= (const StringArray&) const noexcept; - - //============================================================================== - /** Returns the number of strings in the array */ - inline int size() const noexcept { return strings.size(); }; - - /** Returns one of the strings from the array. - - If the index is out-of-range, an empty string is returned. - - Obviously the reference returned shouldn't be stored for later use, as the - string it refers to may disappear when the array changes. - */ - const String& operator[] (int index) const noexcept; - - /** Returns a reference to one of the strings in the array. - This lets you modify a string in-place in the array, but you must be sure that - the index is in-range. - */ - String& getReference (int index) noexcept; - - /** Returns a pointer to the first String in the array. - This method is provided for compatibility with standard C++ iteration mechanisms. - */ - inline String* begin() const noexcept { return strings.begin(); } - - /** Returns a pointer to the String which follows the last element in the array. - This method is provided for compatibility with standard C++ iteration mechanisms. - */ - inline String* end() const noexcept { return strings.end(); } - - /** Searches for a string in the array. - - The comparison will be case-insensitive if the ignoreCase parameter is true. - - @returns true if the string is found inside the array - */ - bool contains (StringRef stringToLookFor, - bool ignoreCase = false) const; - - /** Searches for a string in the array. - - The comparison will be case-insensitive if the ignoreCase parameter is true. - - @param stringToLookFor the string to try to find - @param ignoreCase whether the comparison should be case-insensitive - @param startIndex the first index to start searching from - @returns the index of the first occurrence of the string in this array, - or -1 if it isn't found. - */ - int indexOf (StringRef stringToLookFor, - bool ignoreCase = false, - int startIndex = 0) const; - - //============================================================================== - /** Appends a string at the end of the array. */ - void add (const String& stringToAdd); - - #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS - /** Appends a string at the end of the array. */ - void add (String&& stringToAdd); - #endif - - /** Inserts a string into the array. - - This will insert a string into the array at the given index, moving - up the other elements to make room for it. - If the index is less than zero or greater than the size of the array, - the new string will be added to the end of the array. - */ - void insert (int index, const String& stringToAdd); - - /** Adds a string to the array as long as it's not already in there. - The search can optionally be case-insensitive. - */ - void addIfNotAlreadyThere (const String& stringToAdd, bool ignoreCase = false); - - /** Replaces one of the strings in the array with another one. - - If the index is higher than the array's size, the new string will be - added to the end of the array; if it's less than zero nothing happens. - */ - void set (int index, const String& newString); - - /** Appends some strings from another array to the end of this one. - - @param other the array to add - @param startIndex the first element of the other array to add - @param numElementsToAdd the maximum number of elements to add (if this is - less than zero, they are all added) - */ - void addArray (const StringArray& other, - int startIndex = 0, - int numElementsToAdd = -1); - - /** Breaks up a string into tokens and adds them to this array. - - This will tokenise the given string using whitespace characters as the - token delimiters, and will add these tokens to the end of the array. - @returns the number of tokens added - @see fromTokens - */ - int addTokens (StringRef stringToTokenise, bool preserveQuotedStrings); - - /** Breaks up a string into tokens and adds them to this array. - - This will tokenise the given string (using the string passed in to define the - token delimiters), and will add these tokens to the end of the array. - - @param stringToTokenise the string to tokenise - @param breakCharacters a string of characters, any of which will be considered - to be a token delimiter. - @param quoteCharacters if this string isn't empty, it defines a set of characters - which are treated as quotes. Any text occurring - between quotes is not broken up into tokens. - @returns the number of tokens added - @see fromTokens - */ - int addTokens (StringRef stringToTokenise, - StringRef breakCharacters, - StringRef quoteCharacters); - - /** Breaks up a string into lines and adds them to this array. - - This breaks a string down into lines separated by \\n or \\r\\n, and adds each line - to the array. Line-break characters are omitted from the strings that are added to - the array. - */ - int addLines (StringRef stringToBreakUp); - - /** Returns an array containing the tokens in a given string. - - This will tokenise the given string using whitespace characters as the - token delimiters, and return these tokens as an array. - @see addTokens - */ - static StringArray fromTokens (StringRef stringToTokenise, - bool preserveQuotedStrings); - - /** Returns an array containing the tokens in a given string. - - This will tokenise the given string using whitespace characters as the - token delimiters, and return these tokens as an array. - - @param stringToTokenise the string to tokenise - @param breakCharacters a string of characters, any of which will be considered - to be a token delimiter. - @param quoteCharacters if this string isn't empty, it defines a set of characters - which are treated as quotes. Any text occurring - between quotes is not broken up into tokens. - @see addTokens - */ - static StringArray fromTokens (StringRef stringToTokenise, - StringRef breakCharacters, - StringRef quoteCharacters); - - /** Returns an array containing the lines in a given string. - - This breaks a string down into lines separated by \\n or \\r\\n, and returns an - array containing these lines. Line-break characters are omitted from the strings that - are added to the array. - */ - static StringArray fromLines (StringRef stringToBreakUp); - - //============================================================================== - /** Removes all elements from the array. */ - void clear(); - - /** Removes all elements from the array without freeing the array's allocated storage. - @see clear - */ - void clearQuick(); - - /** Removes a string from the array. - If the index is out-of-range, no action will be taken. - */ - void remove (int index); - - /** Finds a string in the array and removes it. - This will remove the first occurrence of the given string from the array. The - comparison may be case-insensitive depending on the ignoreCase parameter. - */ - void removeString (StringRef stringToRemove, - bool ignoreCase = false); - - /** Removes a range of elements from the array. - - This will remove a set of elements, starting from the given index, - and move subsequent elements down to close the gap. - - If the range extends beyond the bounds of the array, it will - be safely clipped to the size of the array. - - @param startIndex the index of the first element to remove - @param numberToRemove how many elements should be removed - */ - void removeRange (int startIndex, int numberToRemove); - - /** Removes any duplicated elements from the array. - - If any string appears in the array more than once, only the first occurrence of - it will be retained. - - @param ignoreCase whether to use a case-insensitive comparison - */ - void removeDuplicates (bool ignoreCase); - - /** Removes empty strings from the array. - @param removeWhitespaceStrings if true, strings that only contain whitespace - characters will also be removed - */ - void removeEmptyStrings (bool removeWhitespaceStrings = true); - - /** Moves one of the strings to a different position. - - This will move the string to a specified index, shuffling along - any intervening elements as required. - - So for example, if you have the array { 0, 1, 2, 3, 4, 5 } then calling - move (2, 4) would result in { 0, 1, 3, 4, 2, 5 }. - - @param currentIndex the index of the value to be moved. If this isn't a - valid index, then nothing will be done - @param newIndex the index at which you'd like this value to end up. If this - is less than zero, the value will be moved to the end - of the array - */ - void move (int currentIndex, int newIndex) noexcept; - - /** Deletes any whitespace characters from the starts and ends of all the strings. */ - void trim(); - - /** Adds numbers to the strings in the array, to make each string unique. - - This will add numbers to the ends of groups of similar strings. - e.g. if there are two "moose" strings, they will become "moose (1)" and "moose (2)" - - @param ignoreCaseWhenComparing whether the comparison used is case-insensitive - @param appendNumberToFirstInstance whether the first of a group of similar strings - also has a number appended to it. - @param preNumberString when adding a number, this string is added before the number. - If you pass 0, a default string will be used, which adds - brackets around the number. - @param postNumberString this string is appended after any numbers that are added. - If you pass 0, a default string will be used, which adds - brackets around the number. - */ - void appendNumbersToDuplicates (bool ignoreCaseWhenComparing, - bool appendNumberToFirstInstance, - CharPointer_UTF8 preNumberString = CharPointer_UTF8 (nullptr), - CharPointer_UTF8 postNumberString = CharPointer_UTF8 (nullptr)); - - //============================================================================== - /** Joins the strings in the array together into one string. - - This will join a range of elements from the array into a string, separating - them with a given string. - - e.g. joinIntoString (",") will turn an array of "a" "b" and "c" into "a,b,c". - - @param separatorString the string to insert between all the strings - @param startIndex the first element to join - @param numberOfElements how many elements to join together. If this is less - than zero, all available elements will be used. - */ - String joinIntoString (StringRef separatorString, - int startIndex = 0, - int numberOfElements = -1) const; - - //============================================================================== - /** Sorts the array into alphabetical order. - @param ignoreCase if true, the comparisons used will be case-sensitive. - */ - void sort (bool ignoreCase); - - /** Sorts the array using extra language-aware rules to do a better job of comparing - words containing spaces and numbers. - @see String::compareNatural() - */ - void sortNatural(); - - //============================================================================== - /** Increases the array's internal storage to hold a minimum number of elements. - - Calling this before adding a large known number of elements means that - the array won't have to keep dynamically resizing itself as the elements - are added, and it'll therefore be more efficient. - */ - void ensureStorageAllocated (int minNumElements); - - /** Reduces the amount of storage being used by the array. - - Arrays typically allocate slightly more storage than they need, and after - removing elements, they may have quite a lot of unused space allocated. - This method will reduce the amount of allocated storage to a minimum. - */ - void minimiseStorageOverheads(); - - /** This is the array holding the actual strings. This is public to allow direct access - to array methods that may not already be provided by the StringArray class. - */ - Array strings; - -private: - JUCE_LEAK_DETECTOR (StringArray) -}; - - -#endif // JUCE_STRINGARRAY_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/text/juce_StringPairArray.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/text/juce_StringPairArray.cpp deleted file mode 100644 index 3275d2d4aa..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/text/juce_StringPairArray.cpp +++ /dev/null @@ -1,147 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -StringPairArray::StringPairArray (const bool ignoreCase_) - : ignoreCase (ignoreCase_) -{ -} - -StringPairArray::StringPairArray (const StringPairArray& other) - : keys (other.keys), - values (other.values), - ignoreCase (other.ignoreCase) -{ -} - -StringPairArray::~StringPairArray() -{ -} - -StringPairArray& StringPairArray::operator= (const StringPairArray& other) -{ - keys = other.keys; - values = other.values; - return *this; -} - -bool StringPairArray::operator== (const StringPairArray& other) const -{ - for (int i = keys.size(); --i >= 0;) - if (other [keys[i]] != values[i]) - return false; - - return true; -} - -bool StringPairArray::operator!= (const StringPairArray& other) const -{ - return ! operator== (other); -} - -const String& StringPairArray::operator[] (StringRef key) const -{ - return values [keys.indexOf (key, ignoreCase)]; -} - -String StringPairArray::getValue (StringRef key, const String& defaultReturnValue) const -{ - const int i = keys.indexOf (key, ignoreCase); - - if (i >= 0) - return values[i]; - - return defaultReturnValue; -} - -bool StringPairArray::containsKey (StringRef key) const noexcept -{ - return keys.contains (key); -} - -void StringPairArray::set (const String& key, const String& value) -{ - const int i = keys.indexOf (key, ignoreCase); - - if (i >= 0) - { - values.set (i, value); - } - else - { - keys.add (key); - values.add (value); - } -} - -void StringPairArray::addArray (const StringPairArray& other) -{ - for (int i = 0; i < other.size(); ++i) - set (other.keys[i], other.values[i]); -} - -void StringPairArray::clear() -{ - keys.clear(); - values.clear(); -} - -void StringPairArray::remove (StringRef key) -{ - remove (keys.indexOf (key, ignoreCase)); -} - -void StringPairArray::remove (const int index) -{ - keys.remove (index); - values.remove (index); -} - -void StringPairArray::setIgnoresCase (const bool shouldIgnoreCase) -{ - ignoreCase = shouldIgnoreCase; -} - -String StringPairArray::getDescription() const -{ - String s; - - for (int i = 0; i < keys.size(); ++i) - { - s << keys[i] << " = " << values[i]; - if (i < keys.size()) - s << ", "; - } - - return s; -} - -void StringPairArray::minimiseStorageOverheads() -{ - keys.minimiseStorageOverheads(); - values.minimiseStorageOverheads(); -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/text/juce_StringPairArray.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/text/juce_StringPairArray.h deleted file mode 100644 index e1c774d124..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/text/juce_StringPairArray.h +++ /dev/null @@ -1,157 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_STRINGPAIRARRAY_H_INCLUDED -#define JUCE_STRINGPAIRARRAY_H_INCLUDED - - -//============================================================================== -/** - A container for holding a set of strings which are keyed by another string. - - @see StringArray -*/ -class JUCE_API StringPairArray -{ -public: - //============================================================================== - /** Creates an empty array */ - StringPairArray (bool ignoreCaseWhenComparingKeys = true); - - /** Creates a copy of another array */ - StringPairArray (const StringPairArray& other); - - /** Destructor. */ - ~StringPairArray(); - - /** Copies the contents of another string array into this one */ - StringPairArray& operator= (const StringPairArray& other); - - //============================================================================== - /** Compares two arrays. - Comparisons are case-sensitive. - @returns true only if the other array contains exactly the same strings with the same keys - */ - bool operator== (const StringPairArray& other) const; - - /** Compares two arrays. - Comparisons are case-sensitive. - @returns false if the other array contains exactly the same strings with the same keys - */ - bool operator!= (const StringPairArray& other) const; - - //============================================================================== - /** Finds the value corresponding to a key string. - - If no such key is found, this will just return an empty string. To check whether - a given key actually exists (because it might actually be paired with an empty string), use - the getAllKeys() method to obtain a list. - - Obviously the reference returned shouldn't be stored for later use, as the - string it refers to may disappear when the array changes. - - @see getValue - */ - const String& operator[] (StringRef key) const; - - /** Finds the value corresponding to a key string. - If no such key is found, this will just return the value provided as a default. - @see operator[] - */ - String getValue (StringRef, const String& defaultReturnValue) const; - - /** Returns true if the given key exists. */ - bool containsKey (StringRef key) const noexcept; - - /** Returns a list of all keys in the array. */ - const StringArray& getAllKeys() const noexcept { return keys; } - - /** Returns a list of all values in the array. */ - const StringArray& getAllValues() const noexcept { return values; } - - /** Returns the number of strings in the array */ - inline int size() const noexcept { return keys.size(); }; - - - //============================================================================== - /** Adds or amends a key/value pair. - If a value already exists with this key, its value will be overwritten, - otherwise the key/value pair will be added to the array. - */ - void set (const String& key, const String& value); - - /** Adds the items from another array to this one. - This is equivalent to using set() to add each of the pairs from the other array. - */ - void addArray (const StringPairArray& other); - - //============================================================================== - /** Removes all elements from the array. */ - void clear(); - - /** Removes a string from the array based on its key. - If the key isn't found, nothing will happen. - */ - void remove (StringRef key); - - /** Removes a string from the array based on its index. - If the index is out-of-range, no action will be taken. - */ - void remove (int index); - - //============================================================================== - /** Indicates whether to use a case-insensitive search when looking up a key string. - */ - void setIgnoresCase (bool shouldIgnoreCase); - - //============================================================================== - /** Returns a descriptive string containing the items. - This is handy for dumping the contents of an array. - */ - String getDescription() const; - - //============================================================================== - /** Reduces the amount of storage being used by the array. - - Arrays typically allocate slightly more storage than they need, and after - removing elements, they may have quite a lot of unused space allocated. - This method will reduce the amount of allocated storage to a minimum. - */ - void minimiseStorageOverheads(); - - -private: - //============================================================================== - StringArray keys, values; - bool ignoreCase; - - JUCE_LEAK_DETECTOR (StringPairArray) -}; - - -#endif // JUCE_STRINGPAIRARRAY_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/text/juce_StringPool.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/text/juce_StringPool.cpp deleted file mode 100644 index 039a30bf91..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/text/juce_StringPool.cpp +++ /dev/null @@ -1,166 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -static const int minNumberOfStringsForGarbageCollection = 300; -static const uint32 garbageCollectionInterval = 30000; - - -StringPool::StringPool() noexcept : lastGarbageCollectionTime (0) {} -StringPool::~StringPool() {} - -struct StartEndString -{ - StartEndString (String::CharPointerType s, String::CharPointerType e) noexcept : start (s), end (e) {} - operator String() const { return String (start, end); } - - String::CharPointerType start, end; -}; - -static int compareStrings (const String& s1, const String& s2) noexcept { return s1.compare (s2); } -static int compareStrings (CharPointer_UTF8 s1, const String& s2) noexcept { return s1.compare (s2.getCharPointer()); } - -static int compareStrings (const StartEndString& string1, const String& string2) noexcept -{ - String::CharPointerType s1 (string1.start), s2 (string2.getCharPointer()); - - for (;;) - { - const int c1 = s1 < string1.end ? (int) s1.getAndAdvance() : 0; - const int c2 = (int) s2.getAndAdvance(); - const int diff = c1 - c2; - - if (diff != 0) return diff < 0 ? -1 : 1; - if (c1 == 0) break; - } - - return 0; -} - -template -static String addPooledString (Array& strings, const NewStringType& newString) -{ - int start = 0; - int end = strings.size(); - - while (start < end) - { - const String& startString = strings.getReference (start); - const int startComp = compareStrings (newString, startString); - - if (startComp == 0) - return startString; - - const int halfway = (start + end) / 2; - - if (halfway == start) - { - if (startComp > 0) - ++start; - - break; - } - - const String& halfwayString = strings.getReference (halfway); - const int halfwayComp = compareStrings (newString, halfwayString); - - if (halfwayComp == 0) - return halfwayString; - - if (halfwayComp > 0) - start = halfway; - else - end = halfway; - } - - strings.insert (start, newString); - return strings.getReference (start); -} - -String StringPool::getPooledString (const char* const newString) -{ - if (newString == nullptr || *newString == 0) - return String(); - - const ScopedLock sl (lock); - garbageCollectIfNeeded(); - return addPooledString (strings, CharPointer_UTF8 (newString)); -} - -String StringPool::getPooledString (String::CharPointerType start, String::CharPointerType end) -{ - if (start.isEmpty() || start == end) - return String(); - - const ScopedLock sl (lock); - garbageCollectIfNeeded(); - return addPooledString (strings, StartEndString (start, end)); -} - -String StringPool::getPooledString (StringRef newString) -{ - if (newString.isEmpty()) - return String(); - - const ScopedLock sl (lock); - garbageCollectIfNeeded(); - return addPooledString (strings, newString.text); -} - -String StringPool::getPooledString (const String& newString) -{ - if (newString.isEmpty()) - return String(); - - const ScopedLock sl (lock); - garbageCollectIfNeeded(); - return addPooledString (strings, newString); -} - -void StringPool::garbageCollectIfNeeded() -{ - if (strings.size() > minNumberOfStringsForGarbageCollection - && Time::getApproximateMillisecondCounter() > lastGarbageCollectionTime + garbageCollectionInterval) - garbageCollect(); -} - -void StringPool::garbageCollect() -{ - const ScopedLock sl (lock); - - for (int i = strings.size(); --i >= 0;) - if (strings.getReference(i).getReferenceCount() == 1) - strings.remove (i); - - lastGarbageCollectionTime = Time::getApproximateMillisecondCounter(); -} - -StringPool& StringPool::getGlobalPool() noexcept -{ - static StringPool pool; - return pool; -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/text/juce_StringPool.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/text/juce_StringPool.h deleted file mode 100644 index 4de2186554..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/text/juce_StringPool.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_STRINGPOOL_H_INCLUDED -#define JUCE_STRINGPOOL_H_INCLUDED - - -//============================================================================== -/** - A StringPool holds a set of shared strings, which reduces storage overheads and improves - comparison speed when dealing with many duplicate strings. - - When you add a string to a pool using getPooledString, it'll return a character - array containing the same string. This array is owned by the pool, and the same array - is returned every time a matching string is asked for. This means that it's trivial to - compare two pooled strings for equality, as you can simply compare their pointers. It - also cuts down on storage if you're using many copies of the same string. -*/ -class JUCE_API StringPool -{ -public: - //============================================================================== - /** Creates an empty pool. */ - StringPool() noexcept; - - /** Destructor */ - ~StringPool(); - - //============================================================================== - /** Returns a pointer to a shared copy of the string that is passed in. - The pool will always return the same String object when asked for a string that matches it. - */ - String getPooledString (const String& original); - - /** Returns a pointer to a copy of the string that is passed in. - The pool will always return the same String object when asked for a string that matches it. - */ - String getPooledString (const char* original); - - /** Returns a pointer to a shared copy of the string that is passed in. - The pool will always return the same String object when asked for a string that matches it. - */ - String getPooledString (StringRef original); - - /** Returns a pointer to a copy of the string that is passed in. - The pool will always return the same String object when asked for a string that matches it. - */ - String getPooledString (String::CharPointerType start, String::CharPointerType end); - - //============================================================================== - /** Scans the pool, and removes any strings that are unreferenced. - You don't generally need to call this - it'll be called automatically when the pool grows - large enough to warrant it. - */ - void garbageCollect(); - - /** Returns a shared global pool which is used for things like Identifiers, XML parsing. */ - static StringPool& getGlobalPool() noexcept; - -private: - Array strings; - CriticalSection lock; - uint32 lastGarbageCollectionTime; - - void garbageCollectIfNeeded(); -}; - - -#endif // JUCE_STRINGPOOL_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/text/juce_StringRef.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/text/juce_StringRef.h deleted file mode 100644 index 434bf4ae73..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/text/juce_StringRef.h +++ /dev/null @@ -1,138 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_STRINGREF_H_INCLUDED -#define JUCE_STRINGREF_H_INCLUDED - -//============================================================================== -/** - A simple class for holding temporary references to a string literal or String. - - Unlike a real String object, the StringRef does not allocate any memory or - take ownership of the strings you give to it - it simply holds a reference to - a string that has been allocated elsewhere. - The main purpose of the class is to be used instead of a const String& as the type - of function arguments where the caller may pass either a string literal or a String - object. This means that when the called uses a string literal, there's no need - for an temporary String object to be allocated, and this cuts down overheads - substantially. - - Because the class is simply a wrapper around a pointer, you should always pass - it by value, not by reference. - - @code - void myStringFunction1 (const String&); - void myStringFunction2 (StringRef); - - myStringFunction1 ("abc"); // Implicitly allocates a temporary String object. - myStringFunction2 ("abc"); // Much faster, as no local allocations are needed. - @endcode - - For examples of it in use, see the XmlElement or StringArray classes. - - Bear in mind that there are still many cases where it's better to use an argument - which is a const String&. For example if the function stores the string or needs - to internally create a String from the argument, then it's better for the original - argument to already be a String. - - @see String -*/ -class JUCE_API StringRef -{ -public: - /** Creates a StringRef from a raw string literal. - The StringRef object does NOT take ownership or copy this data, so you must - ensure that the data does not change during the lifetime of the StringRef. - Note that this pointer not be null! - */ - StringRef (const char* stringLiteral) noexcept; - - /** Creates a StringRef from a raw char pointer. - The StringRef object does NOT take ownership or copy this data, so you must - ensure that the data does not change during the lifetime of the StringRef. - */ - StringRef (String::CharPointerType stringLiteral) noexcept; - - /** Creates a StringRef from a String. - The StringRef object does NOT take ownership or copy the data from the String, - so you must ensure that the String is not modified or deleted during the lifetime - of the StringRef. - */ - StringRef (const String& string) noexcept; - - /** Creates a StringRef pointer to an empty string. */ - StringRef() noexcept; - - //============================================================================== - /** Returns a raw pointer to the underlying string data. */ - operator const String::CharPointerType::CharType*() const noexcept { return text.getAddress(); } - /** Returns a pointer to the underlying string data as a char pointer object. */ - operator String::CharPointerType() const noexcept { return text; } - - /** Returns true if the string is empty. */ - bool isEmpty() const noexcept { return text.isEmpty(); } - /** Returns true if the string is not empty. */ - bool isNotEmpty() const noexcept { return ! text.isEmpty(); } - /** Returns the number of characters in the string. */ - int length() const noexcept { return (int) text.length(); } - - /** Retrieves a character by index. */ - juce_wchar operator[] (int index) const noexcept { return text[index]; } - - /** Compares this StringRef with a String. */ - bool operator== (const String& s) const noexcept { return text.compare (s.getCharPointer()) == 0; } - /** Compares this StringRef with a String. */ - bool operator!= (const String& s) const noexcept { return text.compare (s.getCharPointer()) != 0; } - - /** Case-sensitive comparison of two StringRefs. */ - bool operator== (StringRef s) const noexcept { return text.compare (s.text) == 0; } - /** Case-sensitive comparison of two StringRefs. */ - bool operator!= (StringRef s) const noexcept { return text.compare (s.text) != 0; } - - //============================================================================== - /** The text that is referenced. */ - String::CharPointerType text; - - #if JUCE_STRING_UTF_TYPE != 8 && ! defined (DOXYGEN) - // Sorry, non-UTF8 people, you're unable to take advantage of StringRef, because - // you've chosen a character encoding that doesn't match C++ string literals. - String stringCopy; - #endif -}; - -//============================================================================== -/** Case-sensitive comparison of two strings. */ -JUCE_API bool JUCE_CALLTYPE operator== (const String& string1, StringRef string2) noexcept; -/** Case-sensitive comparison of two strings. */ -JUCE_API bool JUCE_CALLTYPE operator!= (const String& string1, StringRef string2) noexcept; - -#if JUCE_STRING_UTF_TYPE != 8 && ! defined (DOXYGEN) - inline String operator+ (String s1, StringRef s2) { return s1 += String (s2.text); } -#endif - -#endif // JUCE_STRINGREF_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/text/juce_TextDiff.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/text/juce_TextDiff.cpp deleted file mode 100644 index 6b4c80794e..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/text/juce_TextDiff.cpp +++ /dev/null @@ -1,247 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -struct TextDiffHelpers -{ - enum { minLengthToMatch = 3 }; - - struct StringRegion - { - StringRegion (const String& s) noexcept - : text (s.getCharPointer()), start (0), length (s.length()) {} - - StringRegion (const String::CharPointerType t, int s, int len) noexcept - : text (t), start (s), length (len) {} - - String::CharPointerType text; - int start, length; - }; - - static void addInsertion (TextDiff& td, const String::CharPointerType text, int index, int length) - { - TextDiff::Change c; - c.insertedText = String (text, (size_t) length); - c.start = index; - c.length = length; - td.changes.add (c); - } - - static void addDeletion (TextDiff& td, int index, int length) - { - TextDiff::Change c; - c.start = index; - c.length = length; - td.changes.add (c); - } - - static void diffSkippingCommonStart (TextDiff& td, const StringRegion& a, const StringRegion& b) - { - String::CharPointerType sa (a.text); - String::CharPointerType sb (b.text); - const int maxLen = jmax (a.length, b.length); - - for (int i = 0; i < maxLen; ++i, ++sa, ++sb) - { - if (*sa != *sb) - { - diffRecursively (td, StringRegion (sa, a.start + i, a.length - i), - StringRegion (sb, b.start + i, b.length - i)); - break; - } - } - } - - static void diffRecursively (TextDiff& td, const StringRegion& a, const StringRegion& b) - { - int indexA, indexB; - const int len = findLongestCommonSubstring (a.text, a.length, - b.text, b.length, - indexA, indexB); - - if (len >= minLengthToMatch) - { - if (indexA > 0 && indexB > 0) - diffSkippingCommonStart (td, StringRegion (a.text, a.start, indexA), - StringRegion (b.text, b.start, indexB)); - else if (indexA > 0) - addDeletion (td, b.start, indexA); - else if (indexB > 0) - addInsertion (td, b.text, b.start, indexB); - - diffRecursively (td, StringRegion (a.text + indexA + len, a.start + indexA + len, a.length - indexA - len), - StringRegion (b.text + indexB + len, b.start + indexB + len, b.length - indexB - len)); - } - else - { - if (a.length > 0) addDeletion (td, b.start, a.length); - if (b.length > 0) addInsertion (td, b.text, b.start, b.length); - } - } - - static int findLongestCommonSubstring (String::CharPointerType a, const int lenA, - const String::CharPointerType b, const int lenB, - int& indexInA, int& indexInB) - { - if (lenA == 0 || lenB == 0) - return 0; - - HeapBlock lines; - lines.calloc (2 + 2 * (size_t) lenB); - - int* l0 = lines; - int* l1 = l0 + lenB + 1; - - int loopsWithoutImprovement = 0; - int bestLength = 0; - indexInA = indexInB = 0; - - for (int i = 0; i < lenA; ++i) - { - const juce_wchar ca = a.getAndAdvance(); - String::CharPointerType b2 (b); - - for (int j = 0; j < lenB; ++j) - { - if (ca != b2.getAndAdvance()) - { - l1[j + 1] = 0; - } - else - { - const int len = l0[j] + 1; - l1[j + 1] = len; - - if (len > bestLength) - { - loopsWithoutImprovement = 0; - bestLength = len; - indexInA = i; - indexInB = j; - } - } - } - - if (++loopsWithoutImprovement > 100) - break; - - std::swap (l0, l1); - } - - indexInA -= bestLength - 1; - indexInB -= bestLength - 1; - return bestLength; - } -}; - -TextDiff::TextDiff (const String& original, const String& target) -{ - TextDiffHelpers::diffSkippingCommonStart (*this, original, target); -} - -String TextDiff::appliedTo (String text) const -{ - for (int i = 0; i < changes.size(); ++i) - text = changes.getReference(i).appliedTo (text); - - return text; -} - -bool TextDiff::Change::isDeletion() const noexcept -{ - return insertedText.isEmpty(); -} - -String TextDiff::Change::appliedTo (const String& text) const noexcept -{ - return text.substring (0, start) + (isDeletion() ? text.substring (start + length) - : (insertedText + text.substring (start))); -} - -//============================================================================== -//============================================================================== -#if JUCE_UNIT_TESTS - -class DiffTests : public UnitTest -{ -public: - DiffTests() : UnitTest ("TextDiff class") {} - - static String createString (Random& r) - { - juce_wchar buffer[50] = { 0 }; - - for (int i = r.nextInt (49); --i >= 0;) - { - if (r.nextInt (10) == 0) - { - do - { - buffer[i] = (juce_wchar) (1 + r.nextInt (0x10ffff - 1)); - } - while (! CharPointer_UTF16::canRepresent (buffer[i])); - } - else - buffer[i] = (juce_wchar) ('a' + r.nextInt (3)); - } - - return CharPointer_UTF32 (buffer); - } - - void testDiff (const String& a, const String& b) - { - TextDiff diff (a, b); - const String result (diff.appliedTo (a)); - expectEquals (result, b); - } - - void runTest() - { - beginTest ("TextDiff"); - - Random r = getRandom(); - - testDiff (String::empty, String::empty); - testDiff ("x", String::empty); - testDiff (String::empty, "x"); - testDiff ("x", "x"); - testDiff ("x", "y"); - testDiff ("xxx", "x"); - testDiff ("x", "xxx"); - - for (int i = 5000; --i >= 0;) - { - String s (createString (r)); - testDiff (s, createString (r)); - testDiff (s + createString (r), s + createString (r)); - } - } -}; - -static DiffTests diffTests; - -#endif diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/text/juce_TextDiff.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/text/juce_TextDiff.h deleted file mode 100644 index d420c3d859..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/text/juce_TextDiff.h +++ /dev/null @@ -1,80 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_TEXTDIFF_H_INCLUDED -#define JUCE_TEXTDIFF_H_INCLUDED - - -/** - Calculates and applies a sequence of changes to convert one text string into - another. - - Once created, the TextDiff object contains an array of change objects, where - each change can be either an insertion or a deletion. When applied in order - to the original string, these changes will convert it to the target string. -*/ -class JUCE_API TextDiff -{ -public: - /** Creates a set of diffs for converting the original string into the target. */ - TextDiff (const String& original, - const String& target); - - /** Applies this sequence of changes to the original string, producing the - target string that was specified when generating them. - - Obviously it only makes sense to call this function with the string that - was originally passed to the constructor. Any other input will produce an - undefined result. - */ - String appliedTo (String text) const; - - /** Describes a change, which can be either an insertion or deletion. */ - struct Change - { - String insertedText; /**< If this change is a deletion, this string will be empty; otherwise, - it'll be the text that should be inserted at the index specified by start. */ - int start; /**< Specifies the character index in a string at which text should be inserted or deleted. */ - int length; /**< If this change is a deletion, this specifies the number of characters to delete. For an - insertion, this is the length of the new text being inserted. */ - - /** Returns true if this change is a deletion, or false for an insertion. */ - bool isDeletion() const noexcept; - - /** Returns the result of applying this change to a string. */ - String appliedTo (const String& original) const noexcept; - }; - - /** The list of changes required to perform the transformation. - Applying each of these, in order, to the original string will produce the target. - */ - Array changes; -}; - - -#endif // JUCE_TEXTDIFF_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/threads/juce_ChildProcess.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/threads/juce_ChildProcess.cpp deleted file mode 100644 index 4566b13f1d..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/threads/juce_ChildProcess.cpp +++ /dev/null @@ -1,113 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -ChildProcess::ChildProcess() {} -ChildProcess::~ChildProcess() {} - -bool ChildProcess::isRunning() const -{ - return activeProcess != nullptr && activeProcess->isRunning(); -} - -int ChildProcess::readProcessOutput (void* dest, int numBytes) -{ - return activeProcess != nullptr ? activeProcess->read (dest, numBytes) : 0; -} - -bool ChildProcess::kill() -{ - return activeProcess == nullptr || activeProcess->killProcess(); -} - -uint32 ChildProcess::getExitCode() const -{ - return activeProcess != nullptr ? activeProcess->getExitCode() : 0; -} - -bool ChildProcess::waitForProcessToFinish (const int timeoutMs) const -{ - const uint32 timeoutTime = Time::getMillisecondCounter() + (uint32) timeoutMs; - - do - { - if (! isRunning()) - return true; - } - while (timeoutMs < 0 || Time::getMillisecondCounter() < timeoutTime); - - return false; -} - -String ChildProcess::readAllProcessOutput() -{ - MemoryOutputStream result; - - for (;;) - { - char buffer [512]; - const int num = readProcessOutput (buffer, sizeof (buffer)); - - if (num <= 0) - break; - - result.write (buffer, (size_t) num); - } - - return result.toString(); -} - -//============================================================================== -#if JUCE_UNIT_TESTS - -class ChildProcessTests : public UnitTest -{ -public: - ChildProcessTests() : UnitTest ("ChildProcess") {} - - void runTest() - { - beginTest ("Child Processes"); - - #if JUCE_WINDOWS || JUCE_MAC || JUCE_LINUX - ChildProcess p; - - #if JUCE_WINDOWS - expect (p.start ("tasklist")); - #else - expect (p.start ("ls /")); - #endif - - //String output (p.readAllProcessOutput()); - //expect (output.isNotEmpty()); - #endif - } -}; - -static ChildProcessTests childProcessUnitTests; - -#endif diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/threads/juce_ChildProcess.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/threads/juce_ChildProcess.h deleted file mode 100644 index 0adcb57b70..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/threads/juce_ChildProcess.h +++ /dev/null @@ -1,119 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_CHILDPROCESS_H_INCLUDED -#define JUCE_CHILDPROCESS_H_INCLUDED - - -//============================================================================== -/** - Launches and monitors a child process. - - This class lets you launch an executable, and read its output. You can also - use it to check whether the child process has finished. -*/ -class JUCE_API ChildProcess -{ -public: - //============================================================================== - /** Creates a process object. - To actually launch the process, use start(). - */ - ChildProcess(); - - /** Destructor. - Note that deleting this object won't terminate the child process. - */ - ~ChildProcess(); - - /** These flags are used by the start() methods. */ - enum StreamFlags - { - wantStdOut = 1, - wantStdErr = 2 - }; - - /** Attempts to launch a child process command. - - The command should be the name of the executable file, followed by any arguments - that are required. - If the process has already been launched, this will launch it again. If a problem - occurs, the method will return false. - The streamFlags is a combinations of values to indicate which of the child's output - streams should be read and returned by readProcessOutput(). - */ - bool start (const String& command, int streamFlags = wantStdOut | wantStdErr); - - /** Attempts to launch a child process command. - - The first argument should be the name of the executable file, followed by any other - arguments that are needed. - If the process has already been launched, this will launch it again. If a problem - occurs, the method will return false. - The streamFlags is a combinations of values to indicate which of the child's output - streams should be read and returned by readProcessOutput(). - */ - bool start (const StringArray& arguments, int streamFlags = wantStdOut | wantStdErr); - - /** Returns true if the child process is alive. */ - bool isRunning() const; - - /** Attempts to read some output from the child process. - This will attempt to read up to the given number of bytes of data from the - process. It returns the number of bytes that were actually read. - */ - int readProcessOutput (void* destBuffer, int numBytesToRead); - - /** Blocks until the process has finished, and then returns its complete output - as a string. - */ - String readAllProcessOutput(); - - /** Blocks until the process is no longer running. */ - bool waitForProcessToFinish (int timeoutMs) const; - - /** If the process has finished, this returns its exit code. */ - uint32 getExitCode() const; - - /** Attempts to kill the child process. - Returns true if it succeeded. Trying to read from the process after calling this may - result in undefined behaviour. - */ - bool kill(); - -private: - //============================================================================== - class ActiveProcess; - friend struct ContainerDeletePolicy; - ScopedPointer activeProcess; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ChildProcess) -}; - - -#endif // JUCE_CHILDPROCESS_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/threads/juce_CriticalSection.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/threads/juce_CriticalSection.h deleted file mode 100644 index 60e61dda5e..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/threads/juce_CriticalSection.h +++ /dev/null @@ -1,266 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_CRITICALSECTION_H_INCLUDED -#define JUCE_CRITICALSECTION_H_INCLUDED - - -//============================================================================== -/** - A re-entrant mutex. - - A CriticalSection acts as a re-entrant mutex object. The best way to lock and unlock - one of these is by using RAII in the form of a local ScopedLock object - have a look - through the codebase for many examples of how to do this. - - In almost all cases you'll want to declare your CriticalSection as a member variable. - Occasionally you may want to declare one as a static variable, but in that case the usual - C++ static object order-of-construction warnings should be heeded. - - @see ScopedLock, ScopedTryLock, ScopedUnlock, SpinLock, ReadWriteLock, Thread, InterProcessLock -*/ -class JUCE_API CriticalSection -{ -public: - //============================================================================== - /** Creates a CriticalSection object. */ - CriticalSection() noexcept; - - /** Destructor. - If the critical section is deleted whilst locked, any subsequent behaviour - is unpredictable. - */ - ~CriticalSection() noexcept; - - //============================================================================== - /** Acquires the lock. - - If the lock is already held by the caller thread, the method returns immediately. - If the lock is currently held by another thread, this will wait until it becomes free. - - It's strongly recommended that you never call this method directly - instead use the - ScopedLock class to manage the locking using an RAII pattern instead. - - @see exit, tryEnter, ScopedLock - */ - void enter() const noexcept; - - /** Attempts to lock this critical section without blocking. - - This method behaves identically to CriticalSection::enter, except that the caller thread - does not wait if the lock is currently held by another thread but returns false immediately. - - @returns false if the lock is currently held by another thread, true otherwise. - @see enter - */ - bool tryEnter() const noexcept; - - /** Releases the lock. - - If the caller thread hasn't got the lock, this can have unpredictable results. - - If the enter() method has been called multiple times by the thread, each - call must be matched by a call to exit() before other threads will be allowed - to take over the lock. - - @see enter, ScopedLock - */ - void exit() const noexcept; - - - //============================================================================== - /** Provides the type of scoped lock to use with a CriticalSection. */ - typedef GenericScopedLock ScopedLockType; - - /** Provides the type of scoped unlocker to use with a CriticalSection. */ - typedef GenericScopedUnlock ScopedUnlockType; - - /** Provides the type of scoped try-locker to use with a CriticalSection. */ - typedef GenericScopedTryLock ScopedTryLockType; - - -private: - //============================================================================== - #if JUCE_WINDOWS - // To avoid including windows.h in the public JUCE headers, we'll just allocate - // a block of memory here that's big enough to be used internally as a windows - // CRITICAL_SECTION structure. - #if JUCE_64BIT - uint8 lock[44]; - #else - uint8 lock[24]; - #endif - #else - mutable pthread_mutex_t lock; - #endif - - JUCE_DECLARE_NON_COPYABLE (CriticalSection) -}; - - -//============================================================================== -/** - A class that can be used in place of a real CriticalSection object, but which - doesn't perform any locking. - - This is currently used by some templated classes, and most compilers should - manage to optimise it out of existence. - - @see CriticalSection, Array, OwnedArray, ReferenceCountedArray -*/ -class JUCE_API DummyCriticalSection -{ -public: - inline DummyCriticalSection() noexcept {} - inline ~DummyCriticalSection() noexcept {} - - inline void enter() const noexcept {} - inline bool tryEnter() const noexcept { return true; } - inline void exit() const noexcept {} - - //============================================================================== - /** A dummy scoped-lock type to use with a dummy critical section. */ - struct ScopedLockType - { - ScopedLockType (const DummyCriticalSection&) noexcept {} - }; - - /** A dummy scoped-unlocker type to use with a dummy critical section. */ - typedef ScopedLockType ScopedUnlockType; - -private: - JUCE_DECLARE_NON_COPYABLE (DummyCriticalSection) -}; - -//============================================================================== -/** - Automatically locks and unlocks a CriticalSection object. - - You can use a ScopedLock as a local variable to provide RAII-based locking of a CriticalSection. - - e.g. @code - - struct MyObject - { - CriticalSection objectLock; - - // assuming that this example function will be called by multiple threads - void foo() - { - const ScopedLock myScopedLock (objectLock); - - // objectLock is now locked.. - - ...do some thread-safe work here... - - // ..and objectLock gets unlocked here, as myScopedLock goes out of - // scope at the end of the block - } - }; - @endcode - - @see CriticalSection, ScopedUnlock -*/ -typedef CriticalSection::ScopedLockType ScopedLock; - -//============================================================================== -/** - Automatically unlocks and re-locks a CriticalSection object. - - This is the reverse of a ScopedLock object - instead of locking the critical - section for the lifetime of this object, it unlocks it. - - Make sure you don't try to unlock critical sections that aren't actually locked! - - e.g. @code - - struct MyObject - { - CriticalSection objectLock; - - void foo() - { - { - const ScopedLock myScopedLock (objectLock); - - // objectLock is now locked.. - - { - ScopedUnlock myUnlocker (objectLock); - - // ..and now unlocked.. - } - - // ..and now locked again.. - } - - // ..and finally unlocked. - } - }; - @endcode - - @see CriticalSection, ScopedLock -*/ -typedef CriticalSection::ScopedUnlockType ScopedUnlock; - -//============================================================================== -/** - Automatically tries to lock and unlock a CriticalSection object. - - Use one of these as a local variable to control access to a CriticalSection. - - e.g. @code - - struct MyObject - { - CriticalSection objectLock; - - void foo() - { - const ScopedTryLock myScopedTryLock (objectLock); - - // Unlike using a ScopedLock, this may fail to actually get the lock, so you - // must call the isLocked() method before making any assumptions.. - if (myScopedTryLock.isLocked()) - { - ...safely do some work... - } - else - { - // If we get here, then our attempt at locking failed because another thread had already locked it.. - } - } - }; - @endcode - - @see CriticalSection::tryEnter, ScopedLock, ScopedUnlock, ScopedReadLock -*/ -typedef CriticalSection::ScopedTryLockType ScopedTryLock; - - -#endif // JUCE_CRITICALSECTION_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/threads/juce_DynamicLibrary.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/threads/juce_DynamicLibrary.h deleted file mode 100644 index df6625b540..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/threads/juce_DynamicLibrary.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_DYNAMICLIBRARY_H_INCLUDED -#define JUCE_DYNAMICLIBRARY_H_INCLUDED - -/** - Handles the opening and closing of DLLs. - - This class can be used to open a DLL and get some function pointers from it. - Since the DLL is freed when this object is deleted, it's handy for managing - library lifetimes using RAII. -*/ -class JUCE_API DynamicLibrary -{ -public: - /** Creates an unopened DynamicLibrary object. - Call open() to actually open one. - */ - DynamicLibrary() noexcept : handle (nullptr) {} - - /** - */ - DynamicLibrary (const String& name) : handle (nullptr) { open (name); } - - /** Destructor. - If a library is currently open, it will be closed when this object is destroyed. - */ - ~DynamicLibrary() { close(); } - - /** Opens a DLL. - The name and the method by which it gets found is of course platform-specific, and - may or may not include a path, depending on the OS. - If a library is already open when this method is called, it will first close the library - before attempting to load the new one. - @returns true if the library was successfully found and opened. - */ - bool open (const String& name); - - /** Releases the currently-open DLL, or has no effect if none was open. */ - void close(); - - /** Tries to find a named function in the currently-open DLL, and returns a pointer to it. - If no library is open, or if the function isn't found, this will return a null pointer. - */ - void* getFunction (const String& functionName) noexcept; - - /** Returns the platform-specific native library handle. - You'll need to cast this to whatever is appropriate for the OS that's in use. - */ - void* getNativeHandle() const noexcept { return handle; } - -private: - void* handle; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (DynamicLibrary) -}; - - -#endif // JUCE_DYNAMICLIBRARY_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/threads/juce_HighResolutionTimer.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/threads/juce_HighResolutionTimer.cpp deleted file mode 100644 index 3475b74d1c..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/threads/juce_HighResolutionTimer.cpp +++ /dev/null @@ -1,36 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -HighResolutionTimer::HighResolutionTimer() { pimpl = new Pimpl (*this); } -HighResolutionTimer::~HighResolutionTimer() { stopTimer(); } - -void HighResolutionTimer::startTimer (int periodMs) { pimpl->start (jmax (1, periodMs)); } -void HighResolutionTimer::stopTimer() { pimpl->stop(); } - -bool HighResolutionTimer::isTimerRunning() const noexcept { return pimpl->periodMs != 0; } -int HighResolutionTimer::getTimerInterval() const noexcept { return pimpl->periodMs; } diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/threads/juce_HighResolutionTimer.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/threads/juce_HighResolutionTimer.h deleted file mode 100644 index 21022adc69..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/threads/juce_HighResolutionTimer.h +++ /dev/null @@ -1,109 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_HIGHRESOLUTIONTIMER_H_INCLUDED -#define JUCE_HIGHRESOLUTIONTIMER_H_INCLUDED - -/** - A high-resolution periodic timer. - - This provides accurately-timed regular callbacks. Unlike the normal Timer - class, this one uses a dedicated thread, not the message thread, so is - far more stable and precise. - - You should only use this class in situations where you really need accuracy, - because unlike the normal Timer class, which is very lightweight and cheap - to start/stop, the HighResolutionTimer will use far more resources, and - starting/stopping it may involve launching and killing threads. - - @see Timer -*/ -class JUCE_API HighResolutionTimer -{ -protected: - /** Creates a HighResolutionTimer. - When created, the timer is stopped, so use startTimer() to get it going. - */ - HighResolutionTimer(); - -public: - /** Destructor. */ - virtual ~HighResolutionTimer(); - - //============================================================================== - /** The user-defined callback routine that actually gets called periodically. - - This will be called on a dedicated timer thread, so make sure your - implementation is thread-safe! - - It's perfectly ok to call startTimer() or stopTimer() from within this - callback to change the subsequent intervals. - */ - virtual void hiResTimerCallback() = 0; - - //============================================================================== - /** Starts the timer and sets the length of interval required. - - If the timer is already started, this will reset its counter, so the - time between calling this method and the next timer callback will not be - less than the interval length passed in. - - @param intervalInMilliseconds the interval to use (any values less than 1 will be - rounded up to 1) - */ - void startTimer (int intervalInMilliseconds); - - /** Stops the timer. - - This method may block while it waits for pending callbacks to complete. Once it - returns, no more callbacks will be made. If it is called from the timer's own thread, - it will cancel the timer after the current callback returns. - */ - void stopTimer(); - - /** Checks if the timer has been started. - @returns true if the timer is running. - */ - bool isTimerRunning() const noexcept; - - /** Returns the timer's interval. - @returns the timer's interval in milliseconds if it's running, or 0 if it's not. - */ - int getTimerInterval() const noexcept; - -private: - struct Pimpl; - friend struct Pimpl; - friend struct ContainerDeletePolicy; - ScopedPointer pimpl; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (HighResolutionTimer) -}; - - -#endif // JUCE_HIGHRESOLUTIONTIMER_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/threads/juce_InterProcessLock.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/threads/juce_InterProcessLock.h deleted file mode 100644 index dc903b02b9..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/threads/juce_InterProcessLock.h +++ /dev/null @@ -1,128 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_INTERPROCESSLOCK_H_INCLUDED -#define JUCE_INTERPROCESSLOCK_H_INCLUDED - - -//============================================================================== -/** - Acts as a critical section which processes can use to block each other. - - @see CriticalSection -*/ -class JUCE_API InterProcessLock -{ -public: - //============================================================================== - /** Creates a lock object. - @param name a name that processes will use to identify this lock object - */ - explicit InterProcessLock (const String& name); - - /** Destructor. - This will also release the lock if it's currently held by this process. - */ - ~InterProcessLock(); - - //============================================================================== - /** Attempts to lock the critical section. - - @param timeOutMillisecs how many milliseconds to wait if the lock is already - held by another process - a value of 0 will return - immediately, negative values will wait forever - @returns true if the lock could be gained within the timeout period, or - false if the timeout expired. - */ - bool enter (int timeOutMillisecs = -1); - - /** Releases the lock if it's currently held by this process. */ - void exit(); - - //============================================================================== - /** - Automatically locks and unlocks an InterProcessLock object. - - This works like a ScopedLock, but using an InterprocessLock rather than - a CriticalSection. - - @see ScopedLock - */ - class ScopedLockType - { - public: - //============================================================================== - /** Creates a scoped lock. - - As soon as it is created, this will lock the InterProcessLock, and - when the ScopedLockType object is deleted, the InterProcessLock will - be unlocked. - - Note that since an InterprocessLock can fail due to errors, you should check - isLocked() to make sure that the lock was successful before using it. - - Make sure this object is created and deleted by the same thread, - otherwise there are no guarantees what will happen! Best just to use it - as a local stack object, rather than creating one with the new() operator. - */ - explicit ScopedLockType (InterProcessLock& l) : ipLock (l) { lockWasSuccessful = l.enter(); } - - /** Destructor. - - The InterProcessLock will be unlocked when the destructor is called. - - Make sure this object is created and deleted by the same thread, - otherwise there are no guarantees what will happen! - */ - inline ~ScopedLockType() { ipLock.exit(); } - - /** Returns true if the InterProcessLock was successfully locked. */ - bool isLocked() const noexcept { return lockWasSuccessful; } - - private: - //============================================================================== - InterProcessLock& ipLock; - bool lockWasSuccessful; - - JUCE_DECLARE_NON_COPYABLE (ScopedLockType) - }; - -private: - //============================================================================== - class Pimpl; - friend struct ContainerDeletePolicy; - ScopedPointer pimpl; - - CriticalSection lock; - String name; - - JUCE_DECLARE_NON_COPYABLE (InterProcessLock) -}; - - -#endif // JUCE_INTERPROCESSLOCK_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/threads/juce_Process.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/threads/juce_Process.h deleted file mode 100644 index f3efd66285..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/threads/juce_Process.h +++ /dev/null @@ -1,153 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_PROCESS_H_INCLUDED -#define JUCE_PROCESS_H_INCLUDED - - -//============================================================================== -/** Represents the current executable's process. - - This contains methods for controlling the current application at the - process-level. - - @see Thread, JUCEApplicationBase -*/ -class JUCE_API Process -{ -public: - //============================================================================== - enum ProcessPriority - { - LowPriority = 0, - NormalPriority = 1, - HighPriority = 2, - RealtimePriority = 3 - }; - - /** Changes the current process's priority. - - @param priority the process priority, where - 0=low, 1=normal, 2=high, 3=realtime - */ - static void JUCE_CALLTYPE setPriority (const ProcessPriority priority); - - /** Kills the current process immediately. - - This is an emergency process terminator that kills the application - immediately - it's intended only for use only when something goes - horribly wrong. - - @see JUCEApplicationBase::quit - */ - static void JUCE_CALLTYPE terminate(); - - //============================================================================== - /** Returns true if this application process is the one that the user is - currently using. - */ - static bool JUCE_CALLTYPE isForegroundProcess(); - - /** Attempts to make the current process the active one. - (This is not possible on some platforms). - */ - static void JUCE_CALLTYPE makeForegroundProcess(); - - /** Hides the application (on an OS that supports this, e.g. OSX) */ - static void JUCE_CALLTYPE hide(); - - //============================================================================== - /** Raises the current process's privilege level. - - Does nothing if this isn't supported by the current OS, or if process - privilege level is fixed. - */ - static void JUCE_CALLTYPE raisePrivilege(); - - /** Lowers the current process's privilege level. - - Does nothing if this isn't supported by the current OS, or if process - privilege level is fixed. - */ - static void JUCE_CALLTYPE lowerPrivilege(); - - //============================================================================== - /** Returns true if this process is being hosted by a debugger. */ - static bool JUCE_CALLTYPE isRunningUnderDebugger(); - - - //============================================================================== - /** Tries to launch the OS's default reader application for a given file or URL. */ - static bool JUCE_CALLTYPE openDocument (const String& documentURL, const String& parameters); - - /** Tries to launch the OS's default email application to let the user create a message. */ - static bool JUCE_CALLTYPE openEmailWithAttachments (const String& targetEmailAddress, - const String& emailSubject, - const String& bodyText, - const StringArray& filesToAttach); - - #if JUCE_WINDOWS || DOXYGEN - //============================================================================== - /** WINDOWS ONLY - This returns the HINSTANCE of the current module. - - The return type is a void* to avoid being dependent on windows.h - just cast - it to a HINSTANCE to use it. - - In a normal JUCE application, this will be automatically set to the module - handle of the executable. - - If you've built a DLL and plan to use any JUCE messaging or windowing classes, - you'll need to make sure you call the setCurrentModuleInstanceHandle() - to provide the correct module handle in your DllMain() function, because - the system relies on the correct instance handle when opening windows. - */ - static void* JUCE_CALLTYPE getCurrentModuleInstanceHandle() noexcept; - - /** WINDOWS ONLY - Sets a new module handle to be used by the library. - - The parameter type is a void* to avoid being dependent on windows.h, but it actually - expects a HINSTANCE value. - - @see getCurrentModuleInstanceHandle() - */ - static void JUCE_CALLTYPE setCurrentModuleInstanceHandle (void* newHandle) noexcept; - #endif - - #if JUCE_MAC || DOXYGEN - //============================================================================== - /** OSX ONLY - Shows or hides the OSX dock icon for this app. */ - static void setDockIconVisible (bool isVisible); - #endif - -private: - Process(); - JUCE_DECLARE_NON_COPYABLE (Process) -}; - - -#endif // JUCE_PROCESS_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/threads/juce_ReadWriteLock.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/threads/juce_ReadWriteLock.cpp deleted file mode 100644 index a0821b4400..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/threads/juce_ReadWriteLock.cpp +++ /dev/null @@ -1,150 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -ReadWriteLock::ReadWriteLock() noexcept - : numWaitingWriters (0), - numWriters (0), - writerThreadId (0) -{ - readerThreads.ensureStorageAllocated (16); -} - -ReadWriteLock::~ReadWriteLock() noexcept -{ - jassert (readerThreads.size() == 0); - jassert (numWriters == 0); -} - -//============================================================================== -void ReadWriteLock::enterRead() const noexcept -{ - while (! tryEnterRead()) - waitEvent.wait (100); -} - -bool ReadWriteLock::tryEnterRead() const noexcept -{ - const Thread::ThreadID threadId = Thread::getCurrentThreadId(); - - const SpinLock::ScopedLockType sl (accessLock); - - for (int i = 0; i < readerThreads.size(); ++i) - { - ThreadRecursionCount& trc = readerThreads.getReference(i); - - if (trc.threadID == threadId) - { - trc.count++; - return true; - } - } - - if (numWriters + numWaitingWriters == 0 - || (threadId == writerThreadId && numWriters > 0)) - { - ThreadRecursionCount trc = { threadId, 1 }; - readerThreads.add (trc); - return true; - } - - return false; -} - -void ReadWriteLock::exitRead() const noexcept -{ - const Thread::ThreadID threadId = Thread::getCurrentThreadId(); - const SpinLock::ScopedLockType sl (accessLock); - - for (int i = 0; i < readerThreads.size(); ++i) - { - ThreadRecursionCount& trc = readerThreads.getReference(i); - - if (trc.threadID == threadId) - { - if (--(trc.count) == 0) - { - readerThreads.remove (i); - waitEvent.signal(); - } - - return; - } - } - - jassertfalse; // unlocking a lock that wasn't locked.. -} - -//============================================================================== -void ReadWriteLock::enterWrite() const noexcept -{ - const Thread::ThreadID threadId = Thread::getCurrentThreadId(); - const SpinLock::ScopedLockType sl (accessLock); - - while (! tryEnterWriteInternal (threadId)) - { - ++numWaitingWriters; - accessLock.exit(); - waitEvent.wait (100); - accessLock.enter(); - --numWaitingWriters; - } -} - -bool ReadWriteLock::tryEnterWrite() const noexcept -{ - const SpinLock::ScopedLockType sl (accessLock); - return tryEnterWriteInternal (Thread::getCurrentThreadId()); -} - -bool ReadWriteLock::tryEnterWriteInternal (Thread::ThreadID threadId) const noexcept -{ - if (readerThreads.size() + numWriters == 0 - || threadId == writerThreadId - || (readerThreads.size() == 1 && readerThreads.getReference(0).threadID == threadId)) - { - writerThreadId = threadId; - ++numWriters; - return true; - } - - return false; -} - -void ReadWriteLock::exitWrite() const noexcept -{ - const SpinLock::ScopedLockType sl (accessLock); - - // check this thread actually had the lock.. - jassert (numWriters > 0 && writerThreadId == Thread::getCurrentThreadId()); - - if (--numWriters == 0) - { - writerThreadId = 0; - waitEvent.signal(); - } -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/threads/juce_ReadWriteLock.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/threads/juce_ReadWriteLock.h deleted file mode 100644 index c41d2580ab..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/threads/juce_ReadWriteLock.h +++ /dev/null @@ -1,152 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_READWRITELOCK_H_INCLUDED -#define JUCE_READWRITELOCK_H_INCLUDED - - -//============================================================================== -/** - A critical section that allows multiple simultaneous readers. - - Features of this type of lock are: - - - Multiple readers can hold the lock at the same time, but only one writer - can hold it at once. - - Writers trying to gain the lock will be blocked until all readers and writers - have released it - - Readers trying to gain the lock while a writer is waiting to acquire it will be - blocked until the writer has obtained and released it - - If a thread already has a read lock and tries to obtain a write lock, it will succeed if - there are no other readers - - If a thread already has the write lock and tries to obtain a read lock, this will succeed. - - Recursive locking is supported. - - @see ScopedReadLock, ScopedWriteLock, CriticalSection -*/ -class JUCE_API ReadWriteLock -{ -public: - //============================================================================== - /** - Creates a ReadWriteLock object. - */ - ReadWriteLock() noexcept; - - /** Destructor. - If the object is deleted whilst locked, any subsequent behaviour is undefined. - */ - ~ReadWriteLock() noexcept; - - //============================================================================== - /** Locks this object for reading. - - Multiple threads can simultaneously lock the object for reading, but if another - thread has it locked for writing, then this will block until it releases the lock. - - @see exitRead, ScopedReadLock - */ - void enterRead() const noexcept; - - /** Tries to lock this object for reading. - - Multiple threads can simultaneously lock the object for reading, but if another - thread has it locked for writing, then this will fail and return false. - - @returns true if the lock is successfully gained. - @see exitRead, ScopedReadLock - */ - bool tryEnterRead() const noexcept; - - /** Releases the read-lock. - - If the caller thread hasn't got the lock, this can have unpredictable results. - - If the enterRead() method has been called multiple times by the thread, each - call must be matched by a call to exitRead() before other threads will be allowed - to take over the lock. - - @see enterRead, ScopedReadLock - */ - void exitRead() const noexcept; - - //============================================================================== - /** Locks this object for writing. - - This will block until any other threads that have it locked for reading or - writing have released their lock. - - @see exitWrite, ScopedWriteLock - */ - void enterWrite() const noexcept; - - /** Tries to lock this object for writing. - - This is like enterWrite(), but doesn't block - it returns true if it manages - to obtain the lock. - - @returns true if the lock is successfully gained. - @see enterWrite - */ - bool tryEnterWrite() const noexcept; - - /** Releases the write-lock. - - If the caller thread hasn't got the lock, this can have unpredictable results. - - If the enterWrite() method has been called multiple times by the thread, each - call must be matched by a call to exit() before other threads will be allowed - to take over the lock. - - @see enterWrite, ScopedWriteLock - */ - void exitWrite() const noexcept; - - -private: - //============================================================================== - SpinLock accessLock; - WaitableEvent waitEvent; - mutable int numWaitingWriters, numWriters; - mutable Thread::ThreadID writerThreadId; - - struct ThreadRecursionCount - { - Thread::ThreadID threadID; - int count; - }; - - mutable Array readerThreads; - - bool tryEnterWriteInternal (Thread::ThreadID) const noexcept; - - JUCE_DECLARE_NON_COPYABLE (ReadWriteLock) -}; - - -#endif // JUCE_READWRITELOCK_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/threads/juce_ScopedLock.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/threads/juce_ScopedLock.h deleted file mode 100644 index 442551add9..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/threads/juce_ScopedLock.h +++ /dev/null @@ -1,237 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_SCOPEDLOCK_H_INCLUDED -#define JUCE_SCOPEDLOCK_H_INCLUDED - - -//============================================================================== -/** - Automatically locks and unlocks a mutex object. - - Use one of these as a local variable to provide RAII-based locking of a mutex. - - The templated class could be a CriticalSection, SpinLock, or anything else that - provides enter() and exit() methods. - - e.g. @code - CriticalSection myCriticalSection; - - for (;;) - { - const GenericScopedLock myScopedLock (myCriticalSection); - // myCriticalSection is now locked - - ...do some stuff... - - // myCriticalSection gets unlocked here. - } - @endcode - - @see GenericScopedUnlock, CriticalSection, SpinLock, ScopedLock, ScopedUnlock -*/ -template -class GenericScopedLock -{ -public: - //============================================================================== - /** Creates a GenericScopedLock. - - As soon as it is created, this will acquire the lock, and when the GenericScopedLock - object is deleted, the lock will be released. - - Make sure this object is created and deleted by the same thread, - otherwise there are no guarantees what will happen! Best just to use it - as a local stack object, rather than creating one with the new() operator. - */ - inline explicit GenericScopedLock (const LockType& lock) noexcept : lock_ (lock) { lock.enter(); } - - /** Destructor. - The lock will be released when the destructor is called. - Make sure this object is created and deleted by the same thread, otherwise there are - no guarantees what will happen! - */ - inline ~GenericScopedLock() noexcept { lock_.exit(); } - -private: - //============================================================================== - const LockType& lock_; - - JUCE_DECLARE_NON_COPYABLE (GenericScopedLock) -}; - - -//============================================================================== -/** - Automatically unlocks and re-locks a mutex object. - - This is the reverse of a GenericScopedLock object - instead of locking the mutex - for the lifetime of this object, it unlocks it. - - Make sure you don't try to unlock mutexes that aren't actually locked! - - e.g. @code - - CriticalSection myCriticalSection; - - for (;;) - { - const GenericScopedLock myScopedLock (myCriticalSection); - // myCriticalSection is now locked - - ... do some stuff with it locked .. - - while (xyz) - { - ... do some stuff with it locked .. - - const GenericScopedUnlock unlocker (myCriticalSection); - - // myCriticalSection is now unlocked for the remainder of this block, - // and re-locked at the end. - - ...do some stuff with it unlocked ... - } - - // myCriticalSection gets unlocked here. - } - @endcode - - @see GenericScopedLock, CriticalSection, ScopedLock, ScopedUnlock -*/ -template -class GenericScopedUnlock -{ -public: - //============================================================================== - /** Creates a GenericScopedUnlock. - - As soon as it is created, this will unlock the CriticalSection, and - when the ScopedLock object is deleted, the CriticalSection will - be re-locked. - - Make sure this object is created and deleted by the same thread, - otherwise there are no guarantees what will happen! Best just to use it - as a local stack object, rather than creating one with the new() operator. - */ - inline explicit GenericScopedUnlock (const LockType& lock) noexcept : lock_ (lock) { lock.exit(); } - - /** Destructor. - - The CriticalSection will be unlocked when the destructor is called. - - Make sure this object is created and deleted by the same thread, - otherwise there are no guarantees what will happen! - */ - inline ~GenericScopedUnlock() noexcept { lock_.enter(); } - - -private: - //============================================================================== - const LockType& lock_; - - JUCE_DECLARE_NON_COPYABLE (GenericScopedUnlock) -}; - - -//============================================================================== -/** - Automatically locks and unlocks a mutex object. - - Use one of these as a local variable to provide RAII-based locking of a mutex. - - The templated class could be a CriticalSection, SpinLock, or anything else that - provides enter() and exit() methods. - - e.g. @code - - CriticalSection myCriticalSection; - - for (;;) - { - const GenericScopedTryLock myScopedTryLock (myCriticalSection); - - // Unlike using a ScopedLock, this may fail to actually get the lock, so you - // should test this with the isLocked() method before doing your thread-unsafe - // action.. - if (myScopedTryLock.isLocked()) - { - ...do some stuff... - } - else - { - ..our attempt at locking failed because another thread had already locked it.. - } - - // myCriticalSection gets unlocked here (if it was locked) - } - @endcode - - @see CriticalSection::tryEnter, GenericScopedLock, GenericScopedUnlock -*/ -template -class GenericScopedTryLock -{ -public: - //============================================================================== - /** Creates a GenericScopedTryLock. - - As soon as it is created, this will attempt to acquire the lock, and when the - GenericScopedTryLock is deleted, the lock will be released (if the lock was - successfully acquired). - - Make sure this object is created and deleted by the same thread, - otherwise there are no guarantees what will happen! Best just to use it - as a local stack object, rather than creating one with the new() operator. - */ - inline explicit GenericScopedTryLock (const LockType& lock) noexcept - : lock_ (lock), lockWasSuccessful (lock.tryEnter()) {} - - /** Destructor. - - The mutex will be unlocked (if it had been successfully locked) when the - destructor is called. - - Make sure this object is created and deleted by the same thread, - otherwise there are no guarantees what will happen! - */ - inline ~GenericScopedTryLock() noexcept { if (lockWasSuccessful) lock_.exit(); } - - /** Returns true if the mutex was successfully locked. */ - bool isLocked() const noexcept { return lockWasSuccessful; } - -private: - //============================================================================== - const LockType& lock_; - const bool lockWasSuccessful; - - JUCE_DECLARE_NON_COPYABLE (GenericScopedTryLock) -}; - - -#endif // JUCE_SCOPEDLOCK_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/threads/juce_ScopedReadLock.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/threads/juce_ScopedReadLock.h deleted file mode 100644 index 107e838a50..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/threads/juce_ScopedReadLock.h +++ /dev/null @@ -1,90 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_SCOPEDREADLOCK_H_INCLUDED -#define JUCE_SCOPEDREADLOCK_H_INCLUDED - - -//============================================================================== -/** - Automatically locks and unlocks a ReadWriteLock object. - - Use one of these as a local variable to control access to a ReadWriteLock. - - e.g. @code - - ReadWriteLock myLock; - - for (;;) - { - const ScopedReadLock myScopedLock (myLock); - // myLock is now locked - - ...do some stuff... - - // myLock gets unlocked here. - } - @endcode - - @see ReadWriteLock, ScopedWriteLock -*/ -class JUCE_API ScopedReadLock -{ -public: - //============================================================================== - /** Creates a ScopedReadLock. - - As soon as it is created, this will call ReadWriteLock::enterRead(), and - when the ScopedReadLock object is deleted, the ReadWriteLock will - be unlocked. - - Make sure this object is created and deleted by the same thread, - otherwise there are no guarantees what will happen! Best just to use it - as a local stack object, rather than creating one with the new() operator. - */ - inline explicit ScopedReadLock (const ReadWriteLock& lock) noexcept : lock_ (lock) { lock.enterRead(); } - - /** Destructor. - - The ReadWriteLock's exitRead() method will be called when the destructor is called. - - Make sure this object is created and deleted by the same thread, - otherwise there are no guarantees what will happen! - */ - inline ~ScopedReadLock() noexcept { lock_.exitRead(); } - - -private: - //============================================================================== - const ReadWriteLock& lock_; - - JUCE_DECLARE_NON_COPYABLE (ScopedReadLock) -}; - - -#endif // JUCE_SCOPEDREADLOCK_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/threads/juce_ScopedWriteLock.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/threads/juce_ScopedWriteLock.h deleted file mode 100644 index 44e3198a58..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/threads/juce_ScopedWriteLock.h +++ /dev/null @@ -1,90 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_SCOPEDWRITELOCK_H_INCLUDED -#define JUCE_SCOPEDWRITELOCK_H_INCLUDED - - -//============================================================================== -/** - Automatically locks and unlocks a ReadWriteLock object. - - Use one of these as a local variable to control access to a ReadWriteLock. - - e.g. @code - - ReadWriteLock myLock; - - for (;;) - { - const ScopedWriteLock myScopedLock (myLock); - // myLock is now locked - - ...do some stuff... - - // myLock gets unlocked here. - } - @endcode - - @see ReadWriteLock, ScopedReadLock -*/ -class JUCE_API ScopedWriteLock -{ -public: - //============================================================================== - /** Creates a ScopedWriteLock. - - As soon as it is created, this will call ReadWriteLock::enterWrite(), and - when the ScopedWriteLock object is deleted, the ReadWriteLock will - be unlocked. - - Make sure this object is created and deleted by the same thread, - otherwise there are no guarantees what will happen! Best just to use it - as a local stack object, rather than creating one with the new() operator. - */ - inline explicit ScopedWriteLock (const ReadWriteLock& lock) noexcept : lock_ (lock) { lock.enterWrite(); } - - /** Destructor. - - The ReadWriteLock's exitWrite() method will be called when the destructor is called. - - Make sure this object is created and deleted by the same thread, - otherwise there are no guarantees what will happen! - */ - inline ~ScopedWriteLock() noexcept { lock_.exitWrite(); } - - -private: - //============================================================================== - const ReadWriteLock& lock_; - - JUCE_DECLARE_NON_COPYABLE (ScopedWriteLock) -}; - - -#endif // JUCE_SCOPEDWRITELOCK_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/threads/juce_SpinLock.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/threads/juce_SpinLock.h deleted file mode 100644 index 664cc3c0a0..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/threads/juce_SpinLock.h +++ /dev/null @@ -1,91 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_SPINLOCK_H_INCLUDED -#define JUCE_SPINLOCK_H_INCLUDED - - -//============================================================================== -/** - A simple spin-lock class that can be used as a simple, low-overhead mutex for - uncontended situations. - - Note that unlike a CriticalSection, this type of lock is not re-entrant, and may - be less efficient when used it a highly contended situation, but it's very small and - requires almost no initialisation. - It's most appropriate for simple situations where you're only going to hold the - lock for a very brief time. - - @see CriticalSection -*/ -class JUCE_API SpinLock -{ -public: - inline SpinLock() noexcept {} - inline ~SpinLock() noexcept {} - - /** Acquires the lock. - This will block until the lock has been successfully acquired by this thread. - Note that a SpinLock is NOT re-entrant, and is not smart enough to know whether the - caller thread already has the lock - so if a thread tries to acquire a lock that it - already holds, this method will never return! - - It's strongly recommended that you never call this method directly - instead use the - ScopedLockType class to manage the locking using an RAII pattern instead. - */ - void enter() const noexcept; - - /** Attempts to acquire the lock, returning true if this was successful. */ - inline bool tryEnter() const noexcept - { - return lock.compareAndSetBool (1, 0); - } - - /** Releases the lock. */ - inline void exit() const noexcept - { - jassert (lock.value == 1); // Agh! Releasing a lock that isn't currently held! - lock = 0; - } - - //============================================================================== - /** Provides the type of scoped lock to use for locking a SpinLock. */ - typedef GenericScopedLock ScopedLockType; - - /** Provides the type of scoped unlocker to use with a SpinLock. */ - typedef GenericScopedUnlock ScopedUnlockType; - -private: - //============================================================================== - mutable Atomic lock; - - JUCE_DECLARE_NON_COPYABLE (SpinLock) -}; - - -#endif // JUCE_SPINLOCK_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/threads/juce_Thread.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/threads/juce_Thread.cpp deleted file mode 100644 index 3d1ff0ab1a..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/threads/juce_Thread.cpp +++ /dev/null @@ -1,371 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -Thread::Thread (const String& threadName_) - : threadName (threadName_), - threadHandle (nullptr), - threadId (0), - threadPriority (5), - affinityMask (0), - shouldExit (false) -{ -} - -Thread::~Thread() -{ - /* If your thread class's destructor has been called without first stopping the thread, that - means that this partially destructed object is still performing some work - and that's - probably a Bad Thing! - - To avoid this type of nastiness, always make sure you call stopThread() before or during - your subclass's destructor. - */ - jassert (! isThreadRunning()); - - stopThread (-1); -} - -//============================================================================== -// Use a ref-counted object to hold this shared data, so that it can outlive its static -// shared pointer when threads are still running during static shutdown. -struct CurrentThreadHolder : public ReferenceCountedObject -{ - CurrentThreadHolder() noexcept {} - - typedef ReferenceCountedObjectPtr Ptr; - ThreadLocalValue value; - - JUCE_DECLARE_NON_COPYABLE (CurrentThreadHolder) -}; - -static char currentThreadHolderLock [sizeof (SpinLock)]; // (statically initialised to zeros). - -static SpinLock* castToSpinLockWithoutAliasingWarning (void* s) -{ - return static_cast (s); -} - -static CurrentThreadHolder::Ptr getCurrentThreadHolder() -{ - static CurrentThreadHolder::Ptr currentThreadHolder; - SpinLock::ScopedLockType lock (*castToSpinLockWithoutAliasingWarning (currentThreadHolderLock)); - - if (currentThreadHolder == nullptr) - currentThreadHolder = new CurrentThreadHolder(); - - return currentThreadHolder; -} - -void Thread::threadEntryPoint() -{ - const CurrentThreadHolder::Ptr currentThreadHolder (getCurrentThreadHolder()); - currentThreadHolder->value = this; - - JUCE_TRY - { - if (threadName.isNotEmpty()) - setCurrentThreadName (threadName); - - if (startSuspensionEvent.wait (10000)) - { - jassert (getCurrentThreadId() == threadId); - - if (affinityMask != 0) - setCurrentThreadAffinityMask (affinityMask); - - run(); - } - } - JUCE_CATCH_ALL_ASSERT - - currentThreadHolder->value.releaseCurrentThreadStorage(); - closeThreadHandle(); -} - -// used to wrap the incoming call from the platform-specific code -void JUCE_API juce_threadEntryPoint (void* userData) -{ - static_cast (userData)->threadEntryPoint(); -} - -//============================================================================== -void Thread::startThread() -{ - const ScopedLock sl (startStopLock); - - shouldExit = false; - - if (threadHandle == nullptr) - { - launchThread(); - setThreadPriority (threadHandle, threadPriority); - startSuspensionEvent.signal(); - } -} - -void Thread::startThread (const int priority) -{ - const ScopedLock sl (startStopLock); - - if (threadHandle == nullptr) - { - threadPriority = priority; - startThread(); - } - else - { - setPriority (priority); - } -} - -bool Thread::isThreadRunning() const -{ - return threadHandle != nullptr; -} - -Thread* JUCE_CALLTYPE Thread::getCurrentThread() -{ - return getCurrentThreadHolder()->value.get(); -} - -//============================================================================== -void Thread::signalThreadShouldExit() -{ - shouldExit = true; -} - -bool Thread::waitForThreadToExit (const int timeOutMilliseconds) const -{ - // Doh! So how exactly do you expect this thread to wait for itself to stop?? - jassert (getThreadId() != getCurrentThreadId() || getCurrentThreadId() == 0); - - const uint32 timeoutEnd = Time::getMillisecondCounter() + (uint32) timeOutMilliseconds; - - while (isThreadRunning()) - { - if (timeOutMilliseconds >= 0 && Time::getMillisecondCounter() > timeoutEnd) - return false; - - sleep (2); - } - - return true; -} - -bool Thread::stopThread (const int timeOutMilliseconds) -{ - // agh! You can't stop the thread that's calling this method! How on earth - // would that work?? - jassert (getCurrentThreadId() != getThreadId()); - - const ScopedLock sl (startStopLock); - - if (isThreadRunning()) - { - signalThreadShouldExit(); - notify(); - - if (timeOutMilliseconds != 0) - waitForThreadToExit (timeOutMilliseconds); - - if (isThreadRunning()) - { - // very bad karma if this point is reached, as there are bound to be - // locks and events left in silly states when a thread is killed by force.. - jassertfalse; - Logger::writeToLog ("!! killing thread by force !!"); - - killThread(); - - threadHandle = nullptr; - threadId = 0; - return false; - } - } - - return true; -} - -//============================================================================== -bool Thread::setPriority (const int newPriority) -{ - // NB: deadlock possible if you try to set the thread prio from the thread itself, - // so using setCurrentThreadPriority instead in that case. - if (getCurrentThreadId() == getThreadId()) - return setCurrentThreadPriority (newPriority); - - const ScopedLock sl (startStopLock); - - if ((! isThreadRunning()) || setThreadPriority (threadHandle, newPriority)) - { - threadPriority = newPriority; - return true; - } - - return false; -} - -bool Thread::setCurrentThreadPriority (const int newPriority) -{ - return setThreadPriority (0, newPriority); -} - -void Thread::setAffinityMask (const uint32 newAffinityMask) -{ - affinityMask = newAffinityMask; -} - -//============================================================================== -bool Thread::wait (const int timeOutMilliseconds) const -{ - return defaultEvent.wait (timeOutMilliseconds); -} - -void Thread::notify() const -{ - defaultEvent.signal(); -} - -//============================================================================== -void SpinLock::enter() const noexcept -{ - if (! tryEnter()) - { - for (int i = 20; --i >= 0;) - if (tryEnter()) - return; - - while (! tryEnter()) - Thread::yield(); - } -} - -//============================================================================== -#if JUCE_UNIT_TESTS - -class AtomicTests : public UnitTest -{ -public: - AtomicTests() : UnitTest ("Atomics") {} - - void runTest() - { - beginTest ("Misc"); - - char a1[7]; - expect (numElementsInArray(a1) == 7); - int a2[3]; - expect (numElementsInArray(a2) == 3); - - expect (ByteOrder::swap ((uint16) 0x1122) == 0x2211); - expect (ByteOrder::swap ((uint32) 0x11223344) == 0x44332211); - expect (ByteOrder::swap ((uint64) 0x1122334455667788ULL) == 0x8877665544332211LL); - - beginTest ("Atomic int"); - AtomicTester ::testInteger (*this); - beginTest ("Atomic unsigned int"); - AtomicTester ::testInteger (*this); - beginTest ("Atomic int32"); - AtomicTester ::testInteger (*this); - beginTest ("Atomic uint32"); - AtomicTester ::testInteger (*this); - beginTest ("Atomic long"); - AtomicTester ::testInteger (*this); - beginTest ("Atomic void*"); - AtomicTester ::testInteger (*this); - beginTest ("Atomic int*"); - AtomicTester ::testInteger (*this); - beginTest ("Atomic float"); - AtomicTester ::testFloat (*this); - #if ! JUCE_64BIT_ATOMICS_UNAVAILABLE // 64-bit intrinsics aren't available on some old platforms - beginTest ("Atomic int64"); - AtomicTester ::testInteger (*this); - beginTest ("Atomic uint64"); - AtomicTester ::testInteger (*this); - beginTest ("Atomic double"); - AtomicTester ::testFloat (*this); - #endif - } - - template - class AtomicTester - { - public: - AtomicTester() {} - - static void testInteger (UnitTest& test) - { - Atomic a, b; - a.set ((Type) 10); - test.expect (a.value == (Type) 10); - test.expect (a.get() == (Type) 10); - a += (Type) 15; - test.expect (a.get() == (Type) 25); - a.memoryBarrier(); - a -= (Type) 5; - test.expect (a.get() == (Type) 20); - test.expect (++a == (Type) 21); - ++a; - test.expect (--a == (Type) 21); - test.expect (a.get() == (Type) 21); - a.memoryBarrier(); - - testFloat (test); - } - - static void testFloat (UnitTest& test) - { - Atomic a, b; - a = (Type) 21; - a.memoryBarrier(); - - /* These are some simple test cases to check the atomics - let me know - if any of these assertions fail on your system! - */ - test.expect (a.get() == (Type) 21); - test.expect (a.compareAndSetValue ((Type) 100, (Type) 50) == (Type) 21); - test.expect (a.get() == (Type) 21); - test.expect (a.compareAndSetValue ((Type) 101, a.get()) == (Type) 21); - test.expect (a.get() == (Type) 101); - test.expect (! a.compareAndSetBool ((Type) 300, (Type) 200)); - test.expect (a.get() == (Type) 101); - test.expect (a.compareAndSetBool ((Type) 200, a.get())); - test.expect (a.get() == (Type) 200); - - test.expect (a.exchange ((Type) 300) == (Type) 200); - test.expect (a.get() == (Type) 300); - - b = a; - test.expect (b.get() == a.get()); - } - }; -}; - -static AtomicTests atomicUnitTests; - -#endif diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/threads/juce_Thread.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/threads/juce_Thread.h deleted file mode 100644 index aef96b7dc0..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/threads/juce_Thread.h +++ /dev/null @@ -1,289 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_THREAD_H_INCLUDED -#define JUCE_THREAD_H_INCLUDED - - -//============================================================================== -/** - Encapsulates a thread. - - Subclasses derive from Thread and implement the run() method, in which they - do their business. The thread can then be started with the startThread() method - and controlled with various other methods. - - This class also contains some thread-related static methods, such - as sleep(), yield(), getCurrentThreadId() etc. - - @see CriticalSection, WaitableEvent, Process, ThreadWithProgressWindow, - MessageManagerLock -*/ -class JUCE_API Thread -{ -public: - //============================================================================== - /** - Creates a thread. - - When first created, the thread is not running. Use the startThread() - method to start it. - */ - explicit Thread (const String& threadName); - - /** Destructor. - - You must never attempt to delete a Thread object while it's still running - - always call stopThread() and make sure your thread has stopped before deleting - the object. Failing to do so will throw an assertion, and put you firmly into - undefined behaviour territory. - */ - virtual ~Thread(); - - //============================================================================== - /** Must be implemented to perform the thread's actual code. - - Remember that the thread must regularly check the threadShouldExit() - method whilst running, and if this returns true it should return from - the run() method as soon as possible to avoid being forcibly killed. - - @see threadShouldExit, startThread - */ - virtual void run() = 0; - - //============================================================================== - // Thread control functions.. - - /** Starts the thread running. - - This will cause the thread's run() method to be called by a new thread. - If this thread is already running, startThread() won't do anything. - - @see stopThread - */ - void startThread(); - - /** Starts the thread with a given priority. - - Launches the thread with a given priority, where 0 = lowest, 10 = highest. - If the thread is already running, its priority will be changed. - - @see startThread, setPriority - */ - void startThread (int priority); - - /** Attempts to stop the thread running. - - This method will cause the threadShouldExit() method to return true - and call notify() in case the thread is currently waiting. - - Hopefully the thread will then respond to this by exiting cleanly, and - the stopThread method will wait for a given time-period for this to - happen. - - If the thread is stuck and fails to respond after the time-out, it gets - forcibly killed, which is a very bad thing to happen, as it could still - be holding locks, etc. which are needed by other parts of your program. - - @param timeOutMilliseconds The number of milliseconds to wait for the - thread to finish before killing it by force. A negative - value in here will wait forever. - @returns true if the thread was cleanly stopped before the timeout, or false - if it had to be killed by force. - @see signalThreadShouldExit, threadShouldExit, waitForThreadToExit, isThreadRunning - */ - bool stopThread (int timeOutMilliseconds); - - //============================================================================== - /** Returns true if the thread is currently active */ - bool isThreadRunning() const; - - /** Sets a flag to tell the thread it should stop. - - Calling this means that the threadShouldExit() method will then return true. - The thread should be regularly checking this to see whether it should exit. - - If your thread makes use of wait(), you might want to call notify() after calling - this method, to interrupt any waits that might be in progress, and allow it - to reach a point where it can exit. - - @see threadShouldExit - @see waitForThreadToExit - */ - void signalThreadShouldExit(); - - /** Checks whether the thread has been told to stop running. - - Threads need to check this regularly, and if it returns true, they should - return from their run() method at the first possible opportunity. - - @see signalThreadShouldExit - */ - inline bool threadShouldExit() const { return shouldExit; } - - /** Waits for the thread to stop. - - This will waits until isThreadRunning() is false or until a timeout expires. - - @param timeOutMilliseconds the time to wait, in milliseconds. If this value - is less than zero, it will wait forever. - @returns true if the thread exits, or false if the timeout expires first. - */ - bool waitForThreadToExit (int timeOutMilliseconds) const; - - //============================================================================== - /** Changes the thread's priority. - May return false if for some reason the priority can't be changed. - - @param priority the new priority, in the range 0 (lowest) to 10 (highest). A priority - of 5 is normal. - */ - bool setPriority (int priority); - - /** Changes the priority of the caller thread. - - Similar to setPriority(), but this static method acts on the caller thread. - May return false if for some reason the priority can't be changed. - - @see setPriority - */ - static bool setCurrentThreadPriority (int priority); - - //============================================================================== - /** Sets the affinity mask for the thread. - - This will only have an effect next time the thread is started - i.e. if the - thread is already running when called, it'll have no effect. - - @see setCurrentThreadAffinityMask - */ - void setAffinityMask (uint32 affinityMask); - - /** Changes the affinity mask for the caller thread. - This will change the affinity mask for the thread that calls this static method. - @see setAffinityMask - */ - static void JUCE_CALLTYPE setCurrentThreadAffinityMask (uint32 affinityMask); - - //============================================================================== - // this can be called from any thread that needs to pause.. - static void JUCE_CALLTYPE sleep (int milliseconds); - - /** Yields the calling thread's current time-slot. */ - static void JUCE_CALLTYPE yield(); - - //============================================================================== - /** Makes the thread wait for a notification. - - This puts the thread to sleep until either the timeout period expires, or - another thread calls the notify() method to wake it up. - - A negative time-out value means that the method will wait indefinitely. - - @returns true if the event has been signalled, false if the timeout expires. - */ - bool wait (int timeOutMilliseconds) const; - - /** Wakes up the thread. - - If the thread has called the wait() method, this will wake it up. - - @see wait - */ - void notify() const; - - //============================================================================== - /** A value type used for thread IDs. - @see getCurrentThreadId(), getThreadId() - */ - typedef void* ThreadID; - - /** Returns an id that identifies the caller thread. - - To find the ID of a particular thread object, use getThreadId(). - - @returns a unique identifier that identifies the calling thread. - @see getThreadId - */ - static ThreadID JUCE_CALLTYPE getCurrentThreadId(); - - /** Finds the thread object that is currently running. - - Note that the main UI thread (or other non-Juce threads) don't have a Thread - object associated with them, so this will return 0. - */ - static Thread* JUCE_CALLTYPE getCurrentThread(); - - /** Returns the ID of this thread. - - That means the ID of this thread object - not of the thread that's calling the method. - - This can change when the thread is started and stopped, and will be invalid if the - thread's not actually running. - - @see getCurrentThreadId - */ - ThreadID getThreadId() const noexcept { return threadId; } - - /** Returns the name of the thread. - - This is the name that gets set in the constructor. - */ - const String& getThreadName() const { return threadName; } - - /** Changes the name of the caller thread. - Different OSes may place different length or content limits on this name. - */ - static void JUCE_CALLTYPE setCurrentThreadName (const String& newThreadName); - - -private: - //============================================================================== - const String threadName; - void* volatile threadHandle; - ThreadID threadId; - CriticalSection startStopLock; - WaitableEvent startSuspensionEvent, defaultEvent; - int threadPriority; - uint32 affinityMask; - bool volatile shouldExit; - - #ifndef DOXYGEN - friend void JUCE_API juce_threadEntryPoint (void*); - #endif - - void launchThread(); - void closeThreadHandle(); - void killThread(); - void threadEntryPoint(); - static bool setThreadPriority (void*, int); - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Thread) -}; - -#endif // JUCE_THREAD_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/threads/juce_ThreadLocalValue.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/threads/juce_ThreadLocalValue.h deleted file mode 100644 index bd5c808f82..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/threads/juce_ThreadLocalValue.h +++ /dev/null @@ -1,198 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_THREADLOCALVALUE_H_INCLUDED -#define JUCE_THREADLOCALVALUE_H_INCLUDED - -// (NB: on win32, native thread-locals aren't possible in a dynamically loaded DLL in XP). -#if ! ((JUCE_MSVC && (JUCE_64BIT || ! defined (JucePlugin_PluginCode))) \ - || (JUCE_MAC && JUCE_CLANG && defined (MAC_OS_X_VERSION_10_7) \ - && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_7)) - #define JUCE_NO_COMPILER_THREAD_LOCAL 1 -#endif - -//============================================================================== -/** - Provides cross-platform support for thread-local objects. - - This class holds an internal list of objects of the templated type, keeping - an instance for each thread that requests one. The first time a thread attempts - to access its value, an object is created and added to the list for that thread. - - Typically, you'll probably want to create a static instance of a ThreadLocalValue - object, or hold one within a singleton. - - The templated class for your value must be a primitive type, or a simple POD struct. - - When a thread no longer needs to use its value, it can call releaseCurrentThreadStorage() - to allow the storage to be re-used by another thread. If a thread exits without calling - this method, the object storage will be left allocated until the ThreadLocalValue object - is deleted. -*/ -template -class ThreadLocalValue -{ -public: - /** */ - ThreadLocalValue() noexcept - { - } - - /** Destructor. - When this object is deleted, all the value objects for all threads will be deleted. - */ - ~ThreadLocalValue() - { - #if JUCE_NO_COMPILER_THREAD_LOCAL - for (ObjectHolder* o = first.value; o != nullptr;) - { - ObjectHolder* const next = o->next; - delete o; - o = next; - } - #endif - } - - /** Returns a reference to this thread's instance of the value. - Note that the first time a thread tries to access the value, an instance of the - value object will be created - so if your value's class has a non-trivial - constructor, be aware that this method could invoke it. - */ - Type& operator*() const noexcept { return get(); } - - /** Returns a pointer to this thread's instance of the value. - Note that the first time a thread tries to access the value, an instance of the - value object will be created - so if your value's class has a non-trivial - constructor, be aware that this method could invoke it. - */ - operator Type*() const noexcept { return &get(); } - - /** Accesses a method or field of the value object. - Note that the first time a thread tries to access the value, an instance of the - value object will be created - so if your value's class has a non-trivial - constructor, be aware that this method could invoke it. - */ - Type* operator->() const noexcept { return &get(); } - - /** Assigns a new value to the thread-local object. */ - ThreadLocalValue& operator= (const Type& newValue) { get() = newValue; return *this; } - - /** Returns a reference to this thread's instance of the value. - Note that the first time a thread tries to access the value, an instance of the - value object will be created - so if your value's class has a non-trivial - constructor, be aware that this method could invoke it. - */ - Type& get() const noexcept - { - #if JUCE_NO_COMPILER_THREAD_LOCAL - const Thread::ThreadID threadId = Thread::getCurrentThreadId(); - - for (ObjectHolder* o = first.get(); o != nullptr; o = o->next) - if (o->threadId == threadId) - return o->object; - - for (ObjectHolder* o = first.get(); o != nullptr; o = o->next) - { - if (o->threadId == nullptr) - { - { - SpinLock::ScopedLockType sl (lock); - - if (o->threadId != nullptr) - continue; - - o->threadId = threadId; - } - - o->object = Type(); - return o->object; - } - } - - ObjectHolder* const newObject = new ObjectHolder (threadId); - - do - { - newObject->next = first.get(); - } - while (! first.compareAndSetBool (newObject, newObject->next)); - - return newObject->object; - #elif JUCE_MAC - static __thread Type object; - return object; - #elif JUCE_MSVC - static __declspec(thread) Type object; - return object; - #endif - } - - /** Called by a thread before it terminates, to allow this class to release - any storage associated with the thread. - */ - void releaseCurrentThreadStorage() - { - #if JUCE_NO_COMPILER_THREAD_LOCAL - const Thread::ThreadID threadId = Thread::getCurrentThreadId(); - - for (ObjectHolder* o = first.get(); o != nullptr; o = o->next) - { - if (o->threadId == threadId) - { - SpinLock::ScopedLockType sl (lock); - o->threadId = nullptr; - } - } - #endif - } - -private: - //============================================================================== - #if JUCE_NO_COMPILER_THREAD_LOCAL - struct ObjectHolder - { - ObjectHolder (const Thread::ThreadID& tid) - : threadId (tid), next (nullptr), object() - {} - - Thread::ThreadID threadId; - ObjectHolder* next; - Type object; - - JUCE_DECLARE_NON_COPYABLE (ObjectHolder) - }; - - mutable Atomic first; - SpinLock lock; - #endif - - JUCE_DECLARE_NON_COPYABLE (ThreadLocalValue) -}; - - -#endif // JUCE_THREADLOCALVALUE_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/threads/juce_ThreadPool.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/threads/juce_ThreadPool.cpp deleted file mode 100644 index e6b0b9f9ad..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/threads/juce_ThreadPool.cpp +++ /dev/null @@ -1,384 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -class ThreadPool::ThreadPoolThread : public Thread -{ -public: - ThreadPoolThread (ThreadPool& p) - : Thread ("Pool"), currentJob (nullptr), pool (p) - { - } - - void run() override - { - while (! threadShouldExit()) - if (! pool.runNextJob (*this)) - wait (500); - } - - ThreadPoolJob* volatile currentJob; - ThreadPool& pool; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ThreadPoolThread) -}; - -//============================================================================== -ThreadPoolJob::ThreadPoolJob (const String& name) - : jobName (name), pool (nullptr), - shouldStop (false), isActive (false), shouldBeDeleted (false) -{ -} - -ThreadPoolJob::~ThreadPoolJob() -{ - // you mustn't delete a job while it's still in a pool! Use ThreadPool::removeJob() - // to remove it first! - jassert (pool == nullptr || ! pool->contains (this)); -} - -String ThreadPoolJob::getJobName() const -{ - return jobName; -} - -void ThreadPoolJob::setJobName (const String& newName) -{ - jobName = newName; -} - -void ThreadPoolJob::signalJobShouldExit() -{ - shouldStop = true; -} - -ThreadPoolJob* ThreadPoolJob::getCurrentThreadPoolJob() -{ - if (ThreadPool::ThreadPoolThread* t = dynamic_cast (Thread::getCurrentThread())) - return t->currentJob; - - return nullptr; -} - -//============================================================================== -ThreadPool::ThreadPool (const int numThreads) -{ - jassert (numThreads > 0); // not much point having a pool without any threads! - - createThreads (numThreads); -} - -ThreadPool::ThreadPool() -{ - createThreads (SystemStats::getNumCpus()); -} - -ThreadPool::~ThreadPool() -{ - removeAllJobs (true, 5000); - stopThreads(); -} - -void ThreadPool::createThreads (int numThreads) -{ - for (int i = jmax (1, numThreads); --i >= 0;) - threads.add (new ThreadPoolThread (*this)); - - for (int i = threads.size(); --i >= 0;) - threads.getUnchecked(i)->startThread(); -} - -void ThreadPool::stopThreads() -{ - for (int i = threads.size(); --i >= 0;) - threads.getUnchecked(i)->signalThreadShouldExit(); - - for (int i = threads.size(); --i >= 0;) - threads.getUnchecked(i)->stopThread (500); -} - -void ThreadPool::addJob (ThreadPoolJob* const job, const bool deleteJobWhenFinished) -{ - jassert (job != nullptr); - jassert (job->pool == nullptr); - - if (job->pool == nullptr) - { - job->pool = this; - job->shouldStop = false; - job->isActive = false; - job->shouldBeDeleted = deleteJobWhenFinished; - - { - const ScopedLock sl (lock); - jobs.add (job); - } - - for (int i = threads.size(); --i >= 0;) - threads.getUnchecked(i)->notify(); - } -} - -int ThreadPool::getNumJobs() const -{ - return jobs.size(); -} - -ThreadPoolJob* ThreadPool::getJob (const int index) const -{ - const ScopedLock sl (lock); - return jobs [index]; -} - -bool ThreadPool::contains (const ThreadPoolJob* const job) const -{ - const ScopedLock sl (lock); - return jobs.contains (const_cast (job)); -} - -bool ThreadPool::isJobRunning (const ThreadPoolJob* const job) const -{ - const ScopedLock sl (lock); - return jobs.contains (const_cast (job)) && job->isActive; -} - -bool ThreadPool::waitForJobToFinish (const ThreadPoolJob* const job, const int timeOutMs) const -{ - if (job != nullptr) - { - const uint32 start = Time::getMillisecondCounter(); - - while (contains (job)) - { - if (timeOutMs >= 0 && Time::getMillisecondCounter() >= start + (uint32) timeOutMs) - return false; - - jobFinishedSignal.wait (2); - } - } - - return true; -} - -bool ThreadPool::removeJob (ThreadPoolJob* const job, - const bool interruptIfRunning, - const int timeOutMs) -{ - bool dontWait = true; - OwnedArray deletionList; - - if (job != nullptr) - { - const ScopedLock sl (lock); - - if (jobs.contains (job)) - { - if (job->isActive) - { - if (interruptIfRunning) - job->signalJobShouldExit(); - - dontWait = false; - } - else - { - jobs.removeFirstMatchingValue (job); - addToDeleteList (deletionList, job); - } - } - } - - return dontWait || waitForJobToFinish (job, timeOutMs); -} - -bool ThreadPool::removeAllJobs (const bool interruptRunningJobs, const int timeOutMs, - ThreadPool::JobSelector* const selectedJobsToRemove) -{ - Array jobsToWaitFor; - - { - OwnedArray deletionList; - - { - const ScopedLock sl (lock); - - for (int i = jobs.size(); --i >= 0;) - { - ThreadPoolJob* const job = jobs.getUnchecked(i); - - if (selectedJobsToRemove == nullptr || selectedJobsToRemove->isJobSuitable (job)) - { - if (job->isActive) - { - jobsToWaitFor.add (job); - - if (interruptRunningJobs) - job->signalJobShouldExit(); - } - else - { - jobs.remove (i); - addToDeleteList (deletionList, job); - } - } - } - } - } - - const uint32 start = Time::getMillisecondCounter(); - - for (;;) - { - for (int i = jobsToWaitFor.size(); --i >= 0;) - { - ThreadPoolJob* const job = jobsToWaitFor.getUnchecked (i); - - if (! isJobRunning (job)) - jobsToWaitFor.remove (i); - } - - if (jobsToWaitFor.size() == 0) - break; - - if (timeOutMs >= 0 && Time::getMillisecondCounter() >= start + (uint32) timeOutMs) - return false; - - jobFinishedSignal.wait (20); - } - - return true; -} - -StringArray ThreadPool::getNamesOfAllJobs (const bool onlyReturnActiveJobs) const -{ - StringArray s; - const ScopedLock sl (lock); - - for (int i = 0; i < jobs.size(); ++i) - { - const ThreadPoolJob* const job = jobs.getUnchecked(i); - if (job->isActive || ! onlyReturnActiveJobs) - s.add (job->getJobName()); - } - - return s; -} - -bool ThreadPool::setThreadPriorities (const int newPriority) -{ - bool ok = true; - - for (int i = threads.size(); --i >= 0;) - if (! threads.getUnchecked(i)->setPriority (newPriority)) - ok = false; - - return ok; -} - -ThreadPoolJob* ThreadPool::pickNextJobToRun() -{ - OwnedArray deletionList; - - { - const ScopedLock sl (lock); - - for (int i = 0; i < jobs.size(); ++i) - { - ThreadPoolJob* job = jobs[i]; - - if (job != nullptr && ! job->isActive) - { - if (job->shouldStop) - { - jobs.remove (i); - addToDeleteList (deletionList, job); - --i; - continue; - } - - job->isActive = true; - return job; - } - } - } - - return nullptr; -} - -bool ThreadPool::runNextJob (ThreadPoolThread& thread) -{ - if (ThreadPoolJob* const job = pickNextJobToRun()) - { - ThreadPoolJob::JobStatus result = ThreadPoolJob::jobHasFinished; - thread.currentJob = job; - - JUCE_TRY - { - result = job->runJob(); - } - JUCE_CATCH_ALL_ASSERT - - thread.currentJob = nullptr; - - OwnedArray deletionList; - - { - const ScopedLock sl (lock); - - if (jobs.contains (job)) - { - job->isActive = false; - - if (result != ThreadPoolJob::jobNeedsRunningAgain || job->shouldStop) - { - jobs.removeFirstMatchingValue (job); - addToDeleteList (deletionList, job); - - jobFinishedSignal.signal(); - } - else - { - // move the job to the end of the queue if it wants another go - jobs.move (jobs.indexOf (job), -1); - } - } - } - - return true; - } - - return false; -} - -void ThreadPool::addToDeleteList (OwnedArray& deletionList, ThreadPoolJob* const job) const -{ - job->shouldStop = true; - job->pool = nullptr; - - if (job->shouldBeDeleted) - deletionList.add (job); -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/threads/juce_ThreadPool.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/threads/juce_ThreadPool.h deleted file mode 100644 index 3d5f7622bb..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/threads/juce_ThreadPool.h +++ /dev/null @@ -1,321 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_THREADPOOL_H_INCLUDED -#define JUCE_THREADPOOL_H_INCLUDED - -class ThreadPool; -class ThreadPoolThread; - - -//============================================================================== -/** - A task that is executed by a ThreadPool object. - - A ThreadPool keeps a list of ThreadPoolJob objects which are executed by - its threads. - - The runJob() method needs to be implemented to do the task, and if the code that - does the work takes a significant time to run, it must keep checking the shouldExit() - method to see if something is trying to interrupt the job. If shouldExit() returns - true, the runJob() method must return immediately. - - @see ThreadPool, Thread -*/ -class JUCE_API ThreadPoolJob -{ -public: - //============================================================================== - /** Creates a thread pool job object. - After creating your job, add it to a thread pool with ThreadPool::addJob(). - */ - explicit ThreadPoolJob (const String& name); - - /** Destructor. */ - virtual ~ThreadPoolJob(); - - //============================================================================== - /** Returns the name of this job. - @see setJobName - */ - String getJobName() const; - - /** Changes the job's name. - @see getJobName - */ - void setJobName (const String& newName); - - //============================================================================== - /** These are the values that can be returned by the runJob() method. - */ - enum JobStatus - { - jobHasFinished = 0, /**< indicates that the job has finished and can be - removed from the pool. */ - - jobNeedsRunningAgain /**< indicates that the job would like to be called - again when a thread is free. */ - }; - - /** Peforms the actual work that this job needs to do. - - Your subclass must implement this method, in which is does its work. - - If the code in this method takes a significant time to run, it must repeatedly check - the shouldExit() method to see if something is trying to interrupt the job. - If shouldExit() ever returns true, the runJob() method must return immediately. - - If this method returns jobHasFinished, then the job will be removed from the pool - immediately. If it returns jobNeedsRunningAgain, then the job will be left in the - pool and will get a chance to run again as soon as a thread is free. - - @see shouldExit() - */ - virtual JobStatus runJob() = 0; - - - //============================================================================== - /** Returns true if this job is currently running its runJob() method. */ - bool isRunning() const noexcept { return isActive; } - - /** Returns true if something is trying to interrupt this job and make it stop. - - Your runJob() method must call this whenever it gets a chance, and if it ever - returns true, the runJob() method must return immediately. - - @see signalJobShouldExit() - */ - bool shouldExit() const noexcept { return shouldStop; } - - /** Calling this will cause the shouldExit() method to return true, and the job - should (if it's been implemented correctly) stop as soon as possible. - - @see shouldExit() - */ - void signalJobShouldExit(); - - //============================================================================== - /** If the calling thread is being invoked inside a runJob() method, this will - return the ThreadPoolJob that it belongs to. - */ - static ThreadPoolJob* getCurrentThreadPoolJob(); - - //============================================================================== -private: - friend class ThreadPool; - friend class ThreadPoolThread; - String jobName; - ThreadPool* pool; - bool shouldStop, isActive, shouldBeDeleted; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ThreadPoolJob) -}; - - -//============================================================================== -/** - A set of threads that will run a list of jobs. - - When a ThreadPoolJob object is added to the ThreadPool's list, its runJob() method - will be called by the next pooled thread that becomes free. - - @see ThreadPoolJob, Thread -*/ -class JUCE_API ThreadPool -{ -public: - //============================================================================== - /** Creates a thread pool. - Once you've created a pool, you can give it some jobs by calling addJob(). - @param numberOfThreads the number of threads to run. These will be started - immediately, and will run until the pool is deleted. - */ - ThreadPool (int numberOfThreads); - - /** Creates a thread pool with one thread per CPU core. - Once you've created a pool, you can give it some jobs by calling addJob(). - If you want to specify the number of threads, use the other constructor; this - one creates a pool which has one thread for each CPU core. - @see SystemStats::getNumCpus() - */ - ThreadPool(); - - /** Destructor. - - This will attempt to remove all the jobs before deleting, but if you want to - specify a timeout, you should call removeAllJobs() explicitly before deleting - the pool. - */ - ~ThreadPool(); - - //============================================================================== - /** A callback class used when you need to select which ThreadPoolJob objects are suitable - for some kind of operation. - @see ThreadPool::removeAllJobs - */ - class JUCE_API JobSelector - { - public: - virtual ~JobSelector() {} - - /** Should return true if the specified thread matches your criteria for whatever - operation that this object is being used for. - - Any implementation of this method must be extremely fast and thread-safe! - */ - virtual bool isJobSuitable (ThreadPoolJob* job) = 0; - }; - - //============================================================================== - /** Adds a job to the queue. - - Once a job has been added, then the next time a thread is free, it will run - the job's ThreadPoolJob::runJob() method. Depending on the return value of the - runJob() method, the pool will either remove the job from the pool or add it to - the back of the queue to be run again. - - If deleteJobWhenFinished is true, then the job object will be owned and deleted by - the pool when not needed - if you do this, make sure that your object's destructor - is thread-safe. - - If deleteJobWhenFinished is false, the pointer will be used but not deleted, and - the caller is responsible for making sure the object is not deleted before it has - been removed from the pool. - */ - void addJob (ThreadPoolJob* job, - bool deleteJobWhenFinished); - - /** Tries to remove a job from the pool. - - If the job isn't yet running, this will simply remove it. If it is running, it - will wait for it to finish. - - If the timeout period expires before the job finishes running, then the job will be - left in the pool and this will return false. It returns true if the job is successfully - stopped and removed. - - @param job the job to remove - @param interruptIfRunning if true, then if the job is currently busy, its - ThreadPoolJob::signalJobShouldExit() method will be called to try - to interrupt it. If false, then if the job will be allowed to run - until it stops normally (or the timeout expires) - @param timeOutMilliseconds the length of time this method should wait for the job to finish - before giving up and returning false - */ - bool removeJob (ThreadPoolJob* job, - bool interruptIfRunning, - int timeOutMilliseconds); - - /** Tries to remove all jobs from the pool. - - @param interruptRunningJobs if true, then all running jobs will have their ThreadPoolJob::signalJobShouldExit() - methods called to try to interrupt them - @param timeOutMilliseconds the length of time this method should wait for all the jobs to finish - before giving up and returning false - @param selectedJobsToRemove if this is non-zero, the JobSelector object is asked to decide which - jobs should be removed. If it is zero, all jobs are removed - @returns true if all jobs are successfully stopped and removed; false if the timeout period - expires while waiting for one or more jobs to stop - */ - bool removeAllJobs (bool interruptRunningJobs, - int timeOutMilliseconds, - JobSelector* selectedJobsToRemove = nullptr); - - /** Returns the number of jobs currently running or queued. - */ - int getNumJobs() const; - - /** Returns one of the jobs in the queue. - - Note that this can be a very volatile list as jobs might be continuously getting shifted - around in the list, and this method may return nullptr if the index is currently out-of-range. - */ - ThreadPoolJob* getJob (int index) const; - - /** Returns true if the given job is currently queued or running. - - @see isJobRunning() - */ - bool contains (const ThreadPoolJob* job) const; - - /** Returns true if the given job is currently being run by a thread. - */ - bool isJobRunning (const ThreadPoolJob* job) const; - - /** Waits until a job has finished running and has been removed from the pool. - - This will wait until the job is no longer in the pool - i.e. until its - runJob() method returns ThreadPoolJob::jobHasFinished. - - If the timeout period expires before the job finishes, this will return false; - it returns true if the job has finished successfully. - */ - bool waitForJobToFinish (const ThreadPoolJob* job, - int timeOutMilliseconds) const; - - /** Returns a list of the names of all the jobs currently running or queued. - If onlyReturnActiveJobs is true, only the ones currently running are returned. - */ - StringArray getNamesOfAllJobs (bool onlyReturnActiveJobs) const; - - /** Changes the priority of all the threads. - - This will call Thread::setPriority() for each thread in the pool. - May return false if for some reason the priority can't be changed. - */ - bool setThreadPriorities (int newPriority); - - -private: - //============================================================================== - Array jobs; - - class ThreadPoolThread; - friend class ThreadPoolJob; - friend class ThreadPoolThread; - friend struct ContainerDeletePolicy; - OwnedArray threads; - - CriticalSection lock; - WaitableEvent jobFinishedSignal; - - bool runNextJob (ThreadPoolThread&); - ThreadPoolJob* pickNextJobToRun(); - void addToDeleteList (OwnedArray&, ThreadPoolJob*) const; - void createThreads (int numThreads); - void stopThreads(); - - // Note that this method has changed, and no longer has a parameter to indicate - // whether the jobs should be deleted - see the new method for details. - void removeAllJobs (bool, int, bool); - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ThreadPool) -}; - - -#endif // JUCE_THREADPOOL_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/threads/juce_TimeSliceThread.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/threads/juce_TimeSliceThread.cpp deleted file mode 100644 index f055a15e20..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/threads/juce_TimeSliceThread.cpp +++ /dev/null @@ -1,171 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -TimeSliceThread::TimeSliceThread (const String& name) - : Thread (name), - clientBeingCalled (nullptr) -{ -} - -TimeSliceThread::~TimeSliceThread() -{ - stopThread (2000); -} - -//============================================================================== -void TimeSliceThread::addTimeSliceClient (TimeSliceClient* const client, int millisecondsBeforeStarting) -{ - if (client != nullptr) - { - const ScopedLock sl (listLock); - client->nextCallTime = Time::getCurrentTime() + RelativeTime::milliseconds (millisecondsBeforeStarting); - clients.addIfNotAlreadyThere (client); - notify(); - } -} - -void TimeSliceThread::removeTimeSliceClient (TimeSliceClient* const client) -{ - const ScopedLock sl1 (listLock); - - // if there's a chance we're in the middle of calling this client, we need to - // also lock the outer lock.. - if (clientBeingCalled == client) - { - const ScopedUnlock ul (listLock); // unlock first to get the order right.. - - const ScopedLock sl2 (callbackLock); - const ScopedLock sl3 (listLock); - - clients.removeFirstMatchingValue (client); - } - else - { - clients.removeFirstMatchingValue (client); - } -} - -void TimeSliceThread::moveToFrontOfQueue (TimeSliceClient* client) -{ - const ScopedLock sl (listLock); - - if (clients.contains (client)) - { - client->nextCallTime = Time::getCurrentTime(); - notify(); - } -} - -int TimeSliceThread::getNumClients() const -{ - return clients.size(); -} - -TimeSliceClient* TimeSliceThread::getClient (const int i) const -{ - const ScopedLock sl (listLock); - return clients [i]; -} - -//============================================================================== -TimeSliceClient* TimeSliceThread::getNextClient (int index) const -{ - Time soonest; - TimeSliceClient* client = nullptr; - - for (int i = clients.size(); --i >= 0;) - { - TimeSliceClient* const c = clients.getUnchecked ((i + index) % clients.size()); - - if (client == nullptr || c->nextCallTime < soonest) - { - client = c; - soonest = c->nextCallTime; - } - } - - return client; -} - -void TimeSliceThread::run() -{ - int index = 0; - - while (! threadShouldExit()) - { - int timeToWait = 500; - - { - Time nextClientTime; - - { - const ScopedLock sl2 (listLock); - - index = clients.size() > 0 ? ((index + 1) % clients.size()) : 0; - - if (TimeSliceClient* const firstClient = getNextClient (index)) - nextClientTime = firstClient->nextCallTime; - } - - const Time now (Time::getCurrentTime()); - - if (nextClientTime > now) - { - timeToWait = (int) jmin ((int64) 500, (nextClientTime - now).inMilliseconds()); - } - else - { - timeToWait = index == 0 ? 1 : 0; - - const ScopedLock sl (callbackLock); - - { - const ScopedLock sl2 (listLock); - clientBeingCalled = getNextClient (index); - } - - if (clientBeingCalled != nullptr) - { - const int msUntilNextCall = clientBeingCalled->useTimeSlice(); - - const ScopedLock sl2 (listLock); - - if (msUntilNextCall >= 0) - clientBeingCalled->nextCallTime = now + RelativeTime::milliseconds (msUntilNextCall); - else - clients.removeFirstMatchingValue (clientBeingCalled); - - clientBeingCalled = nullptr; - } - } - } - - if (timeToWait > 0) - wait (timeToWait); - } -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/threads/juce_TimeSliceThread.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/threads/juce_TimeSliceThread.h deleted file mode 100644 index 8c30567507..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/threads/juce_TimeSliceThread.h +++ /dev/null @@ -1,149 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_TIMESLICETHREAD_H_INCLUDED -#define JUCE_TIMESLICETHREAD_H_INCLUDED - -class TimeSliceThread; - - -//============================================================================== -/** - Used by the TimeSliceThread class. - - To register your class with a TimeSliceThread, derive from this class and - use the TimeSliceThread::addTimeSliceClient() method to add it to the list. - - Make sure you always call TimeSliceThread::removeTimeSliceClient() before - deleting your client! - - @see TimeSliceThread -*/ -class JUCE_API TimeSliceClient -{ -public: - /** Destructor. */ - virtual ~TimeSliceClient() {} - - /** Called back by a TimeSliceThread. - - When you register this class with it, a TimeSliceThread will repeatedly call - this method. - - The implementation of this method should use its time-slice to do something that's - quick - never block for longer than absolutely necessary. - - @returns Your method should return the number of milliseconds which it would like to wait before being called - again. Returning 0 will make the thread call again as soon as possible (after possibly servicing - other busy clients). If you return a value below zero, your client will be removed from the list of clients, - and won't be called again. The value you specify isn't a guaranteee, and is only used as a hint by the - thread - the actual time before the next callback may be more or less than specified. - You can force the TimeSliceThread to wake up and poll again immediately by calling its notify() method. - */ - virtual int useTimeSlice() = 0; - - -private: - friend class TimeSliceThread; - Time nextCallTime; -}; - - -//============================================================================== -/** - A thread that keeps a list of clients, and calls each one in turn, giving them - all a chance to run some sort of short task. - - @see TimeSliceClient, Thread -*/ -class JUCE_API TimeSliceThread : public Thread -{ -public: - //============================================================================== - /** - Creates a TimeSliceThread. - - When first created, the thread is not running. Use the startThread() - method to start it. - */ - explicit TimeSliceThread (const String& threadName); - - /** Destructor. - - Deleting a Thread object that is running will only give the thread a - brief opportunity to stop itself cleanly, so it's recommended that you - should always call stopThread() with a decent timeout before deleting, - to avoid the thread being forcibly killed (which is a Bad Thing). - */ - ~TimeSliceThread(); - - //============================================================================== - /** Adds a client to the list. - - The client's callbacks will start after the number of milliseconds specified - by millisecondsBeforeStarting (and this may happen before this method has returned). - */ - void addTimeSliceClient (TimeSliceClient* client, int millisecondsBeforeStarting = 0); - - /** Removes a client from the list. - - This method will make sure that all callbacks to the client have completely - finished before the method returns. - */ - void removeTimeSliceClient (TimeSliceClient* client); - - /** If the given client is waiting in the queue, it will be moved to the front - and given a time-slice as soon as possible. - If the specified client has not been added, nothing will happen. - */ - void moveToFrontOfQueue (TimeSliceClient* client); - - /** Returns the number of registered clients. */ - int getNumClients() const; - - /** Returns one of the registered clients. */ - TimeSliceClient* getClient (int index) const; - - //============================================================================== - #ifndef DOXYGEN - void run() override; - #endif - - //============================================================================== -private: - CriticalSection callbackLock, listLock; - Array clients; - TimeSliceClient* clientBeingCalled; - - TimeSliceClient* getNextClient (int index) const; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (TimeSliceThread) -}; - - -#endif // JUCE_TIMESLICETHREAD_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/threads/juce_WaitableEvent.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/threads/juce_WaitableEvent.h deleted file mode 100644 index 83f6f06450..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/threads/juce_WaitableEvent.h +++ /dev/null @@ -1,118 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_WAITABLEEVENT_H_INCLUDED -#define JUCE_WAITABLEEVENT_H_INCLUDED - - -//============================================================================== -/** - Allows threads to wait for events triggered by other threads. - - A thread can call wait() on a WaitableObject, and this will suspend the - calling thread until another thread wakes it up by calling the signal() - method. -*/ -class JUCE_API WaitableEvent -{ -public: - //============================================================================== - /** Creates a WaitableEvent object. - - The object is initially in an unsignalled state. - - @param manualReset If this is false, the event will be reset automatically when the wait() - method is called. If manualReset is true, then once the event is signalled, - the only way to reset it will be by calling the reset() method. - */ - explicit WaitableEvent (bool manualReset = false) noexcept; - - /** Destructor. - - If other threads are waiting on this object when it gets deleted, this - can cause nasty errors, so be careful! - */ - ~WaitableEvent() noexcept; - - //============================================================================== - /** Suspends the calling thread until the event has been signalled. - - This will wait until the object's signal() method is called by another thread, - or until the timeout expires. - - After the event has been signalled, this method will return true and if manualReset - was set to false in the WaitableEvent's constructor, then the event will be reset. - - @param timeOutMilliseconds the maximum time to wait, in milliseconds. A negative - value will cause it to wait forever. - - @returns true if the object has been signalled, false if the timeout expires first. - @see signal, reset - */ - bool wait (int timeOutMilliseconds = -1) const noexcept; - - //============================================================================== - /** Wakes up any threads that are currently waiting on this object. - - If signal() is called when nothing is waiting, the next thread to call wait() - will return immediately and reset the signal. - - If the WaitableEvent is manual reset, all current and future threads that wait upon this - object will be woken, until reset() is explicitly called. - - If the WaitableEvent is automatic reset, and one or more threads is waiting upon the object, - then one of them will be woken up. If no threads are currently waiting, then the next thread - to call wait() will be woken up. As soon as a thread is woken, the signal is automatically - reset. - - @see wait, reset - */ - void signal() const noexcept; - - //============================================================================== - /** Resets the event to an unsignalled state. - If it's not already signalled, this does nothing. - */ - void reset() const noexcept; - - -private: - //============================================================================== - #if JUCE_WINDOWS - void* handle; - #else - mutable pthread_cond_t condition; - mutable pthread_mutex_t mutex; - mutable bool triggered, manualReset; - #endif - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (WaitableEvent) -}; - - -#endif // JUCE_WAITABLEEVENT_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/time/juce_PerformanceCounter.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/time/juce_PerformanceCounter.cpp deleted file mode 100644 index b22d5e4848..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/time/juce_PerformanceCounter.cpp +++ /dev/null @@ -1,132 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -static void appendToFile (const File& f, const String& s) -{ - if (f.getFullPathName().isNotEmpty()) - { - FileOutputStream out (f); - - if (! out.failedToOpen()) - out << s << newLine; - } -} - -PerformanceCounter::PerformanceCounter (const String& name, int runsPerPrintout, const File& loggingFile) - : runsPerPrint (runsPerPrintout), startTime (0), outputFile (loggingFile) -{ - stats.name = name; - appendToFile (outputFile, "**** Counter for \"" + name + "\" started at: " + Time::getCurrentTime().toString (true, true)); -} - -PerformanceCounter::~PerformanceCounter() -{ - printStatistics(); -} - -PerformanceCounter::Statistics::Statistics() noexcept - : averageSeconds(), maximumSeconds(), minimumSeconds(), totalSeconds(), numRuns() -{ -} - -void PerformanceCounter::Statistics::clear() noexcept -{ - averageSeconds = maximumSeconds = minimumSeconds = totalSeconds = 0; - numRuns = 0; -} - -void PerformanceCounter::Statistics::addResult (double elapsed) noexcept -{ - if (numRuns == 0) - { - maximumSeconds = elapsed; - minimumSeconds = elapsed; - } - else - { - maximumSeconds = jmax (maximumSeconds, elapsed); - minimumSeconds = jmin (minimumSeconds, elapsed); - } - - ++numRuns; - totalSeconds += elapsed; -} - -static String timeToString (double secs) -{ - return String ((int64) (secs * (secs < 0.01 ? 1000000.0 : 1000.0) + 0.5)) - + (secs < 0.01 ? " microsecs" : " millisecs"); -} - -String PerformanceCounter::Statistics::toString() const -{ - MemoryOutputStream s; - - s << "Performance count for \"" << name << "\" over " << numRuns << " run(s)" << newLine - << "Average = " << timeToString (averageSeconds) - << ", minimum = " << timeToString (minimumSeconds) - << ", maximum = " << timeToString (maximumSeconds) - << ", total = " << timeToString (totalSeconds); - - return s.toString(); -} - -void PerformanceCounter::start() noexcept -{ - startTime = Time::getHighResolutionTicks(); -} - -bool PerformanceCounter::stop() -{ - stats.addResult (Time::highResolutionTicksToSeconds (Time::getHighResolutionTicks() - startTime)); - - if (stats.numRuns < runsPerPrint) - return false; - - printStatistics(); - return true; -} - -void PerformanceCounter::printStatistics() -{ - const String desc (getStatisticsAndReset().toString()); - - Logger::outputDebugString (desc); - appendToFile (outputFile, desc); -} - -PerformanceCounter::Statistics PerformanceCounter::getStatisticsAndReset() -{ - Statistics s (stats); - stats.clear(); - - if (s.numRuns > 0) - s.averageSeconds = s.totalSeconds / s.numRuns; - - return s; -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/time/juce_PerformanceCounter.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/time/juce_PerformanceCounter.h deleted file mode 100644 index aac50d21c7..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/time/juce_PerformanceCounter.h +++ /dev/null @@ -1,127 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_PERFORMANCECOUNTER_H_INCLUDED -#define JUCE_PERFORMANCECOUNTER_H_INCLUDED - - -//============================================================================== -/** A timer for measuring performance of code and dumping the results to a file. - - e.g. @code - - PerformanceCounter pc ("fish", 50, "/temp/myfishlog.txt"); - - for (;;) - { - pc.start(); - - doSomethingFishy(); - - pc.stop(); - } - @endcode - - In this example, the time of each period between calling start/stop will be - measured and averaged over 50 runs, and the results printed to a file - every 50 times round the loop. -*/ -class JUCE_API PerformanceCounter -{ -public: - //============================================================================== - /** Creates a PerformanceCounter object. - - @param counterName the name used when printing out the statistics - @param runsPerPrintout the number of start/stop iterations before calling - printStatistics() - @param loggingFile a file to dump the results to - if this is File::nonexistent, - the results are just written to the debugger output - */ - PerformanceCounter (const String& counterName, - int runsPerPrintout = 100, - const File& loggingFile = File()); - - /** Destructor. */ - ~PerformanceCounter(); - - //============================================================================== - /** Starts timing. - @see stop - */ - void start() noexcept; - - /** Stops timing and prints out the results. - - The number of iterations before doing a printout of the - results is set in the constructor. - - @see start - */ - bool stop(); - - /** Dumps the current metrics to the debugger output and to a file. - - As well as using Logger::outputDebugString to print the results, - this will write then to the file specified in the constructor (if - this was valid). - */ - void printStatistics(); - - /** Holds the current statistics. */ - struct Statistics - { - Statistics() noexcept; - - void clear() noexcept; - String toString() const; - - void addResult (double elapsed) noexcept; - - String name; - double averageSeconds; - double maximumSeconds; - double minimumSeconds; - double totalSeconds; - int64 numRuns; - }; - - /** Returns a copy of the current stats, and resets the internal counter. */ - Statistics getStatisticsAndReset(); - -private: - //============================================================================== - Statistics stats; - int64 runsPerPrint, startTime; - File outputFile; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (PerformanceCounter) -}; - - -#endif // JUCE_PERFORMANCECOUNTER_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/time/juce_RelativeTime.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/time/juce_RelativeTime.cpp deleted file mode 100644 index 6fca4fedea..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/time/juce_RelativeTime.cpp +++ /dev/null @@ -1,139 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -RelativeTime::RelativeTime (const double secs) noexcept : numSeconds (secs) {} -RelativeTime::RelativeTime (const RelativeTime& other) noexcept : numSeconds (other.numSeconds) {} -RelativeTime::~RelativeTime() noexcept {} - -//============================================================================== -RelativeTime RelativeTime::milliseconds (const int milliseconds) noexcept { return RelativeTime (milliseconds * 0.001); } -RelativeTime RelativeTime::milliseconds (const int64 milliseconds) noexcept { return RelativeTime (milliseconds * 0.001); } -RelativeTime RelativeTime::seconds (double s) noexcept { return RelativeTime (s); } -RelativeTime RelativeTime::minutes (const double numberOfMinutes) noexcept { return RelativeTime (numberOfMinutes * 60.0); } -RelativeTime RelativeTime::hours (const double numberOfHours) noexcept { return RelativeTime (numberOfHours * (60.0 * 60.0)); } -RelativeTime RelativeTime::days (const double numberOfDays) noexcept { return RelativeTime (numberOfDays * (60.0 * 60.0 * 24.0)); } -RelativeTime RelativeTime::weeks (const double numberOfWeeks) noexcept { return RelativeTime (numberOfWeeks * (60.0 * 60.0 * 24.0 * 7.0)); } - -//============================================================================== -int64 RelativeTime::inMilliseconds() const noexcept { return (int64) (numSeconds * 1000.0); } -double RelativeTime::inMinutes() const noexcept { return numSeconds / 60.0; } -double RelativeTime::inHours() const noexcept { return numSeconds / (60.0 * 60.0); } -double RelativeTime::inDays() const noexcept { return numSeconds / (60.0 * 60.0 * 24.0); } -double RelativeTime::inWeeks() const noexcept { return numSeconds / (60.0 * 60.0 * 24.0 * 7.0); } - -//============================================================================== -RelativeTime& RelativeTime::operator= (const RelativeTime& other) noexcept { numSeconds = other.numSeconds; return *this; } - -RelativeTime RelativeTime::operator+= (RelativeTime t) noexcept { numSeconds += t.numSeconds; return *this; } -RelativeTime RelativeTime::operator-= (RelativeTime t) noexcept { numSeconds -= t.numSeconds; return *this; } -RelativeTime RelativeTime::operator+= (const double secs) noexcept { numSeconds += secs; return *this; } -RelativeTime RelativeTime::operator-= (const double secs) noexcept { numSeconds -= secs; return *this; } - -RelativeTime operator+ (RelativeTime t1, RelativeTime t2) noexcept { return t1 += t2; } -RelativeTime operator- (RelativeTime t1, RelativeTime t2) noexcept { return t1 -= t2; } - -bool operator== (RelativeTime t1, RelativeTime t2) noexcept { return t1.inSeconds() == t2.inSeconds(); } -bool operator!= (RelativeTime t1, RelativeTime t2) noexcept { return t1.inSeconds() != t2.inSeconds(); } -bool operator> (RelativeTime t1, RelativeTime t2) noexcept { return t1.inSeconds() > t2.inSeconds(); } -bool operator< (RelativeTime t1, RelativeTime t2) noexcept { return t1.inSeconds() < t2.inSeconds(); } -bool operator>= (RelativeTime t1, RelativeTime t2) noexcept { return t1.inSeconds() >= t2.inSeconds(); } -bool operator<= (RelativeTime t1, RelativeTime t2) noexcept { return t1.inSeconds() <= t2.inSeconds(); } - -//============================================================================== -static void translateTimeField (String& result, int n, const char* singular, const char* plural) -{ - result << TRANS (n == 1 ? singular : plural) - .replace (n == 1 ? "1" : "2", String (n)) - << ' '; -} - -String RelativeTime::getDescription (const String& returnValueForZeroTime) const -{ - if (numSeconds < 0.001 && numSeconds > -0.001) - return returnValueForZeroTime; - - String result; - result.preallocateBytes (32); - - if (numSeconds < 0) - result << '-'; - - int fieldsShown = 0; - int n = std::abs ((int) inWeeks()); - if (n > 0) - { - translateTimeField (result, n, NEEDS_TRANS("1 week"), NEEDS_TRANS("2 weeks")); - ++fieldsShown; - } - - n = std::abs ((int) inDays()) % 7; - if (n > 0) - { - translateTimeField (result, n, NEEDS_TRANS("1 day"), NEEDS_TRANS("2 days")); - ++fieldsShown; - } - - if (fieldsShown < 2) - { - n = std::abs ((int) inHours()) % 24; - if (n > 0) - { - translateTimeField (result, n, NEEDS_TRANS("1 hr"), NEEDS_TRANS("2 hrs")); - ++fieldsShown; - } - - if (fieldsShown < 2) - { - n = std::abs ((int) inMinutes()) % 60; - if (n > 0) - { - translateTimeField (result, n, NEEDS_TRANS("1 min"), NEEDS_TRANS("2 mins")); - ++fieldsShown; - } - - if (fieldsShown < 2) - { - n = std::abs ((int) inSeconds()) % 60; - if (n > 0) - { - translateTimeField (result, n, NEEDS_TRANS("1 sec"), NEEDS_TRANS("2 secs")); - ++fieldsShown; - } - - if (fieldsShown == 0) - { - n = std::abs ((int) inMilliseconds()) % 1000; - if (n > 0) - result << n << ' ' << TRANS ("ms"); - } - } - } - } - - return result.trimEnd(); -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/time/juce_RelativeTime.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/time/juce_RelativeTime.h deleted file mode 100644 index 7e39d21177..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/time/juce_RelativeTime.h +++ /dev/null @@ -1,184 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_RELATIVETIME_H_INCLUDED -#define JUCE_RELATIVETIME_H_INCLUDED - - -//============================================================================== -/** A relative measure of time. - - The time is stored as a number of seconds, at double-precision floating - point accuracy, and may be positive or negative. - - If you need an absolute time, (i.e. a date + time), see the Time class. -*/ -class JUCE_API RelativeTime -{ -public: - //============================================================================== - /** Creates a RelativeTime. - - @param seconds the number of seconds, which may be +ve or -ve. - @see milliseconds, minutes, hours, days, weeks - */ - explicit RelativeTime (double seconds = 0.0) noexcept; - - /** Copies another relative time. */ - RelativeTime (const RelativeTime& other) noexcept; - - /** Copies another relative time. */ - RelativeTime& operator= (const RelativeTime& other) noexcept; - - /** Destructor. */ - ~RelativeTime() noexcept; - - //============================================================================== - /** Creates a new RelativeTime object representing a number of milliseconds. - @see seconds, minutes, hours, days, weeks - */ - static RelativeTime milliseconds (int milliseconds) noexcept; - - /** Creates a new RelativeTime object representing a number of milliseconds. - @see seconds, minutes, hours, days, weeks - */ - static RelativeTime milliseconds (int64 milliseconds) noexcept; - - /** Creates a new RelativeTime object representing a number of seconds. - @see milliseconds, minutes, hours, days, weeks - */ - static RelativeTime seconds (double seconds) noexcept; - - /** Creates a new RelativeTime object representing a number of minutes. - @see milliseconds, hours, days, weeks - */ - static RelativeTime minutes (double numberOfMinutes) noexcept; - - /** Creates a new RelativeTime object representing a number of hours. - @see milliseconds, minutes, days, weeks - */ - static RelativeTime hours (double numberOfHours) noexcept; - - /** Creates a new RelativeTime object representing a number of days. - @see milliseconds, minutes, hours, weeks - */ - static RelativeTime days (double numberOfDays) noexcept; - - /** Creates a new RelativeTime object representing a number of weeks. - @see milliseconds, minutes, hours, days - */ - static RelativeTime weeks (double numberOfWeeks) noexcept; - - //============================================================================== - /** Returns the number of milliseconds this time represents. - @see milliseconds, inSeconds, inMinutes, inHours, inDays, inWeeks - */ - int64 inMilliseconds() const noexcept; - - /** Returns the number of seconds this time represents. - @see inMilliseconds, inMinutes, inHours, inDays, inWeeks - */ - double inSeconds() const noexcept { return numSeconds; } - - /** Returns the number of minutes this time represents. - @see inMilliseconds, inSeconds, inHours, inDays, inWeeks - */ - double inMinutes() const noexcept; - - /** Returns the number of hours this time represents. - @see inMilliseconds, inSeconds, inMinutes, inDays, inWeeks - */ - double inHours() const noexcept; - - /** Returns the number of days this time represents. - @see inMilliseconds, inSeconds, inMinutes, inHours, inWeeks - */ - double inDays() const noexcept; - - /** Returns the number of weeks this time represents. - @see inMilliseconds, inSeconds, inMinutes, inHours, inDays - */ - double inWeeks() const noexcept; - - /** Returns a readable textual description of the time. - - The exact format of the string returned will depend on - the magnitude of the time - e.g. - - "1 min 4 secs", "1 hr 45 mins", "2 weeks 5 days", "140 ms" - - so that only the two most significant units are printed. - - The returnValueForZeroTime value is the result that is returned if the - length is zero. Depending on your application you might want to use this - to return something more relevant like "empty" or "0 secs", etc. - - @see inMilliseconds, inSeconds, inMinutes, inHours, inDays, inWeeks - */ - String getDescription (const String& returnValueForZeroTime = "0") const; - - - //============================================================================== - /** Adds another RelativeTime to this one. */ - RelativeTime operator+= (RelativeTime timeToAdd) noexcept; - /** Subtracts another RelativeTime from this one. */ - RelativeTime operator-= (RelativeTime timeToSubtract) noexcept; - - /** Adds a number of seconds to this time. */ - RelativeTime operator+= (double secondsToAdd) noexcept; - /** Subtracts a number of seconds from this time. */ - RelativeTime operator-= (double secondsToSubtract) noexcept; - -private: - //============================================================================== - double numSeconds; -}; - -//============================================================================== -/** Compares two RelativeTimes. */ -bool operator== (RelativeTime t1, RelativeTime t2) noexcept; -/** Compares two RelativeTimes. */ -bool operator!= (RelativeTime t1, RelativeTime t2) noexcept; -/** Compares two RelativeTimes. */ -bool operator> (RelativeTime t1, RelativeTime t2) noexcept; -/** Compares two RelativeTimes. */ -bool operator< (RelativeTime t1, RelativeTime t2) noexcept; -/** Compares two RelativeTimes. */ -bool operator>= (RelativeTime t1, RelativeTime t2) noexcept; -/** Compares two RelativeTimes. */ -bool operator<= (RelativeTime t1, RelativeTime t2) noexcept; - -//============================================================================== -/** Adds two RelativeTimes together. */ -RelativeTime operator+ (RelativeTime t1, RelativeTime t2) noexcept; -/** Subtracts two RelativeTimes. */ -RelativeTime operator- (RelativeTime t1, RelativeTime t2) noexcept; - - - -#endif // JUCE_RELATIVETIME_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/time/juce_Time.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/time/juce_Time.cpp deleted file mode 100644 index fabcfde2ef..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/time/juce_Time.cpp +++ /dev/null @@ -1,469 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -namespace TimeHelpers -{ - static struct tm millisToLocal (const int64 millis) noexcept - { - struct tm result; - const int64 seconds = millis / 1000; - - if (seconds < 86400LL || seconds >= 2145916800LL) - { - // use extended maths for dates beyond 1970 to 2037.. - const int timeZoneAdjustment = 31536000 - (int) (Time (1971, 0, 1, 0, 0).toMilliseconds() / 1000); - const int64 jdm = seconds + timeZoneAdjustment + 210866803200LL; - - const int days = (int) (jdm / 86400LL); - const int a = 32044 + days; - const int b = (4 * a + 3) / 146097; - const int c = a - (b * 146097) / 4; - const int d = (4 * c + 3) / 1461; - const int e = c - (d * 1461) / 4; - const int m = (5 * e + 2) / 153; - - result.tm_mday = e - (153 * m + 2) / 5 + 1; - result.tm_mon = m + 2 - 12 * (m / 10); - result.tm_year = b * 100 + d - 6700 + (m / 10); - result.tm_wday = (days + 1) % 7; - result.tm_yday = -1; - - int t = (int) (jdm % 86400LL); - result.tm_hour = t / 3600; - t %= 3600; - result.tm_min = t / 60; - result.tm_sec = t % 60; - result.tm_isdst = -1; - } - else - { - time_t now = static_cast (seconds); - - #if JUCE_WINDOWS - #ifdef _INC_TIME_INL - if (now >= 0 && now <= 0x793406fff) - localtime_s (&result, &now); - else - zerostruct (result); - #else - result = *localtime (&now); - #endif - #else - - localtime_r (&now, &result); // more thread-safe - #endif - } - - return result; - } - - static int extendedModulo (const int64 value, const int modulo) noexcept - { - return (int) (value >= 0 ? (value % modulo) - : (value - ((value / modulo) + 1) * modulo)); - } - - static inline String formatString (const String& format, const struct tm* const tm) - { - #if JUCE_ANDROID - typedef CharPointer_UTF8 StringType; - #elif JUCE_WINDOWS - typedef CharPointer_UTF16 StringType; - #else - typedef CharPointer_UTF32 StringType; - #endif - - for (size_t bufferSize = 256; ; bufferSize += 256) - { - HeapBlock buffer (bufferSize); - - #if JUCE_ANDROID - const size_t numChars = strftime (buffer, bufferSize - 1, format.toUTF8(), tm); - #elif JUCE_WINDOWS - const size_t numChars = wcsftime (buffer, bufferSize - 1, format.toWideCharPointer(), tm); - #else - const size_t numChars = wcsftime (buffer, bufferSize - 1, format.toUTF32(), tm); - #endif - - if (numChars > 0 || format.isEmpty()) - return String (StringType (buffer), - StringType (buffer) + (int) numChars); - } - } - - static uint32 lastMSCounterValue = 0; -} - -//============================================================================== -Time::Time() noexcept - : millisSinceEpoch (0) -{ -} - -Time::Time (const Time& other) noexcept - : millisSinceEpoch (other.millisSinceEpoch) -{ -} - -Time::Time (const int64 ms) noexcept - : millisSinceEpoch (ms) -{ -} - -Time::Time (const int year, - const int month, - const int day, - const int hours, - const int minutes, - const int seconds, - const int milliseconds, - const bool useLocalTime) noexcept -{ - jassert (year > 100); // year must be a 4-digit version - - if (year < 1971 || year >= 2038 || ! useLocalTime) - { - // use extended maths for dates beyond 1970 to 2037.. - const int timeZoneAdjustment = useLocalTime ? (31536000 - (int) (Time (1971, 0, 1, 0, 0).toMilliseconds() / 1000)) - : 0; - const int a = (13 - month) / 12; - const int y = year + 4800 - a; - const int jd = day + (153 * (month + 12 * a - 2) + 2) / 5 - + (y * 365) + (y / 4) - (y / 100) + (y / 400) - - 32045; - - const int64 s = ((int64) jd) * 86400LL - 210866803200LL; - - millisSinceEpoch = 1000 * (s + (hours * 3600 + minutes * 60 + seconds - timeZoneAdjustment)) - + milliseconds; - } - else - { - struct tm t; - t.tm_year = year - 1900; - t.tm_mon = month; - t.tm_mday = day; - t.tm_hour = hours; - t.tm_min = minutes; - t.tm_sec = seconds; - t.tm_isdst = -1; - - millisSinceEpoch = 1000 * (int64) mktime (&t); - - if (millisSinceEpoch < 0) - millisSinceEpoch = 0; - else - millisSinceEpoch += milliseconds; - } -} - -Time::~Time() noexcept -{ -} - -Time& Time::operator= (const Time& other) noexcept -{ - millisSinceEpoch = other.millisSinceEpoch; - return *this; -} - -//============================================================================== -int64 Time::currentTimeMillis() noexcept -{ - #if JUCE_WINDOWS - struct _timeb t; - #ifdef _INC_TIME_INL - _ftime_s (&t); - #else - _ftime (&t); - #endif - return ((int64) t.time) * 1000 + t.millitm; - #else - struct timeval tv; - gettimeofday (&tv, nullptr); - return ((int64) tv.tv_sec) * 1000 + tv.tv_usec / 1000; - #endif -} - -Time JUCE_CALLTYPE Time::getCurrentTime() noexcept -{ - return Time (currentTimeMillis()); -} - -//============================================================================== -uint32 juce_millisecondsSinceStartup() noexcept; - -uint32 Time::getMillisecondCounter() noexcept -{ - const uint32 now = juce_millisecondsSinceStartup(); - - if (now < TimeHelpers::lastMSCounterValue) - { - // in multi-threaded apps this might be called concurrently, so - // make sure that our last counter value only increases and doesn't - // go backwards.. - if (now < TimeHelpers::lastMSCounterValue - 1000) - TimeHelpers::lastMSCounterValue = now; - } - else - { - TimeHelpers::lastMSCounterValue = now; - } - - return now; -} - -uint32 Time::getApproximateMillisecondCounter() noexcept -{ - if (TimeHelpers::lastMSCounterValue == 0) - getMillisecondCounter(); - - return TimeHelpers::lastMSCounterValue; -} - -void Time::waitForMillisecondCounter (const uint32 targetTime) noexcept -{ - for (;;) - { - const uint32 now = getMillisecondCounter(); - - if (now >= targetTime) - break; - - const int toWait = (int) (targetTime - now); - - if (toWait > 2) - { - Thread::sleep (jmin (20, toWait >> 1)); - } - else - { - // xxx should consider using mutex_pause on the mac as it apparently - // makes it seem less like a spinlock and avoids lowering the thread pri. - for (int i = 10; --i >= 0;) - Thread::yield(); - } - } -} - -//============================================================================== -double Time::highResolutionTicksToSeconds (const int64 ticks) noexcept -{ - return ticks / (double) getHighResolutionTicksPerSecond(); -} - -int64 Time::secondsToHighResolutionTicks (const double seconds) noexcept -{ - return (int64) (seconds * (double) getHighResolutionTicksPerSecond()); -} - -//============================================================================== -String Time::toString (const bool includeDate, - const bool includeTime, - const bool includeSeconds, - const bool use24HourClock) const noexcept -{ - String result; - - if (includeDate) - { - result << getDayOfMonth() << ' ' - << getMonthName (true) << ' ' - << getYear(); - - if (includeTime) - result << ' '; - } - - if (includeTime) - { - const int mins = getMinutes(); - - result << (use24HourClock ? getHours() : getHoursInAmPmFormat()) - << (mins < 10 ? ":0" : ":") << mins; - - if (includeSeconds) - { - const int secs = getSeconds(); - result << (secs < 10 ? ":0" : ":") << secs; - } - - if (! use24HourClock) - result << (isAfternoon() ? "pm" : "am"); - } - - return result.trimEnd(); -} - -String Time::formatted (const String& format) const -{ - struct tm t (TimeHelpers::millisToLocal (millisSinceEpoch)); - return TimeHelpers::formatString (format, &t); -} - -//============================================================================== -int Time::getYear() const noexcept { return TimeHelpers::millisToLocal (millisSinceEpoch).tm_year + 1900; } -int Time::getMonth() const noexcept { return TimeHelpers::millisToLocal (millisSinceEpoch).tm_mon; } -int Time::getDayOfYear() const noexcept { return TimeHelpers::millisToLocal (millisSinceEpoch).tm_yday; } -int Time::getDayOfMonth() const noexcept { return TimeHelpers::millisToLocal (millisSinceEpoch).tm_mday; } -int Time::getDayOfWeek() const noexcept { return TimeHelpers::millisToLocal (millisSinceEpoch).tm_wday; } -int Time::getHours() const noexcept { return TimeHelpers::millisToLocal (millisSinceEpoch).tm_hour; } -int Time::getMinutes() const noexcept { return TimeHelpers::millisToLocal (millisSinceEpoch).tm_min; } -int Time::getSeconds() const noexcept { return TimeHelpers::extendedModulo (millisSinceEpoch / 1000, 60); } -int Time::getMilliseconds() const noexcept { return TimeHelpers::extendedModulo (millisSinceEpoch, 1000); } - -int Time::getHoursInAmPmFormat() const noexcept -{ - const int hours = getHours(); - - if (hours == 0) return 12; - if (hours <= 12) return hours; - - return hours - 12; -} - -bool Time::isAfternoon() const noexcept -{ - return getHours() >= 12; -} - -bool Time::isDaylightSavingTime() const noexcept -{ - return TimeHelpers::millisToLocal (millisSinceEpoch).tm_isdst != 0; -} - -String Time::getTimeZone() const noexcept -{ - String zone[2]; - - #if JUCE_WINDOWS - _tzset(); - - #ifdef _INC_TIME_INL - for (int i = 0; i < 2; ++i) - { - char name[128] = { 0 }; - size_t length; - _get_tzname (&length, name, 127, i); - zone[i] = name; - } - #else - const char** const zonePtr = (const char**) _tzname; - zone[0] = zonePtr[0]; - zone[1] = zonePtr[1]; - #endif - #else - tzset(); - const char** const zonePtr = (const char**) tzname; - zone[0] = zonePtr[0]; - zone[1] = zonePtr[1]; - #endif - - if (isDaylightSavingTime()) - { - zone[0] = zone[1]; - - if (zone[0].length() > 3 - && zone[0].containsIgnoreCase ("daylight") - && zone[0].contains ("GMT")) - zone[0] = "BST"; - } - - return zone[0].substring (0, 3); -} - -String Time::getMonthName (const bool threeLetterVersion) const -{ - return getMonthName (getMonth(), threeLetterVersion); -} - -String Time::getWeekdayName (const bool threeLetterVersion) const -{ - return getWeekdayName (getDayOfWeek(), threeLetterVersion); -} - -static const char* const shortMonthNames[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; -static const char* const longMonthNames[] = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }; - -String Time::getMonthName (int monthNumber, const bool threeLetterVersion) -{ - monthNumber %= 12; - - return TRANS (threeLetterVersion ? shortMonthNames [monthNumber] - : longMonthNames [monthNumber]); -} - -String Time::getWeekdayName (int day, const bool threeLetterVersion) -{ - static const char* const shortDayNames[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }; - static const char* const longDayNames[] = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" }; - - day %= 7; - - return TRANS (threeLetterVersion ? shortDayNames [day] - : longDayNames [day]); -} - -//============================================================================== -Time& Time::operator+= (RelativeTime delta) noexcept { millisSinceEpoch += delta.inMilliseconds(); return *this; } -Time& Time::operator-= (RelativeTime delta) noexcept { millisSinceEpoch -= delta.inMilliseconds(); return *this; } - -Time operator+ (Time time, RelativeTime delta) noexcept { Time t (time); return t += delta; } -Time operator- (Time time, RelativeTime delta) noexcept { Time t (time); return t -= delta; } -Time operator+ (RelativeTime delta, Time time) noexcept { Time t (time); return t += delta; } -const RelativeTime operator- (Time time1, Time time2) noexcept { return RelativeTime::milliseconds (time1.toMilliseconds() - time2.toMilliseconds()); } - -bool operator== (Time time1, Time time2) noexcept { return time1.toMilliseconds() == time2.toMilliseconds(); } -bool operator!= (Time time1, Time time2) noexcept { return time1.toMilliseconds() != time2.toMilliseconds(); } -bool operator< (Time time1, Time time2) noexcept { return time1.toMilliseconds() < time2.toMilliseconds(); } -bool operator> (Time time1, Time time2) noexcept { return time1.toMilliseconds() > time2.toMilliseconds(); } -bool operator<= (Time time1, Time time2) noexcept { return time1.toMilliseconds() <= time2.toMilliseconds(); } -bool operator>= (Time time1, Time time2) noexcept { return time1.toMilliseconds() >= time2.toMilliseconds(); } - -static int getMonthNumberForCompileDate (const String& m) noexcept -{ - for (int i = 0; i < 12; ++i) - if (m.equalsIgnoreCase (shortMonthNames[i])) - return i; - - // If you hit this because your compiler has a non-standard __DATE__ format, - // let me know so we can add support for it! - jassertfalse; - return 0; -} - -Time Time::getCompilationDate() -{ - StringArray dateTokens; - dateTokens.addTokens (__DATE__, true); - dateTokens.removeEmptyStrings (true); - - return Time (dateTokens[2].getIntValue(), - getMonthNumberForCompileDate (dateTokens[0]), - dateTokens[1].getIntValue(), 12, 0); -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/time/juce_Time.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/time/juce_Time.h deleted file mode 100644 index 4a35e0878e..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/time/juce_Time.h +++ /dev/null @@ -1,404 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_TIME_H_INCLUDED -#define JUCE_TIME_H_INCLUDED - - -//============================================================================== -/** - Holds an absolute date and time. - - Internally, the time is stored at millisecond precision. - - @see RelativeTime -*/ -class JUCE_API Time -{ -public: - //============================================================================== - /** Creates a Time object. - - This default constructor creates a time of 1st January 1970, (which is - represented internally as 0ms). - - To create a time object representing the current time, use getCurrentTime(). - - @see getCurrentTime - */ - Time() noexcept; - - /** Creates a time based on a number of milliseconds. - - The internal millisecond count is set to 0 (1st January 1970). To create a - time object set to the current time, use getCurrentTime(). - - @param millisecondsSinceEpoch the number of milliseconds since the unix - 'epoch' (midnight Jan 1st 1970). - @see getCurrentTime, currentTimeMillis - */ - explicit Time (int64 millisecondsSinceEpoch) noexcept; - - /** Creates a time from a set of date components. - - The timezone is assumed to be whatever the system is using as its locale. - - @param year the year, in 4-digit format, e.g. 2004 - @param month the month, in the range 0 to 11 - @param day the day of the month, in the range 1 to 31 - @param hours hours in 24-hour clock format, 0 to 23 - @param minutes minutes 0 to 59 - @param seconds seconds 0 to 59 - @param milliseconds milliseconds 0 to 999 - @param useLocalTime if true, encode using the current machine's local time; if - false, it will always work in GMT. - */ - Time (int year, - int month, - int day, - int hours, - int minutes, - int seconds = 0, - int milliseconds = 0, - bool useLocalTime = true) noexcept; - - /** Creates a copy of another Time object. */ - Time (const Time& other) noexcept; - - /** Destructor. */ - ~Time() noexcept; - - /** Copies this time from another one. */ - Time& operator= (const Time& other) noexcept; - - //============================================================================== - /** Returns a Time object that is set to the current system time. - - @see currentTimeMillis - */ - static Time JUCE_CALLTYPE getCurrentTime() noexcept; - - /** Returns the time as a number of milliseconds. - - @returns the number of milliseconds this Time object represents, since - midnight jan 1st 1970. - @see getMilliseconds - */ - int64 toMilliseconds() const noexcept { return millisSinceEpoch; } - - /** Returns the year. - - A 4-digit format is used, e.g. 2004. - */ - int getYear() const noexcept; - - /** Returns the number of the month. - - The value returned is in the range 0 to 11. - @see getMonthName - */ - int getMonth() const noexcept; - - /** Returns the name of the month. - - @param threeLetterVersion if true, it'll be a 3-letter abbreviation, e.g. "Jan"; if false - it'll return the long form, e.g. "January" - @see getMonth - */ - String getMonthName (bool threeLetterVersion) const; - - /** Returns the day of the month. - The value returned is in the range 1 to 31. - */ - int getDayOfMonth() const noexcept; - - /** Returns the number of the day of the week. - The value returned is in the range 0 to 6 (0 = sunday, 1 = monday, etc). - */ - int getDayOfWeek() const noexcept; - - /** Returns the number of the day of the year. - The value returned is in the range 0 to 365. - */ - int getDayOfYear() const noexcept; - - /** Returns the name of the weekday. - - @param threeLetterVersion if true, it'll return a 3-letter abbreviation, e.g. "Tue"; if - false, it'll return the full version, e.g. "Tuesday". - */ - String getWeekdayName (bool threeLetterVersion) const; - - /** Returns the number of hours since midnight. - - This is in 24-hour clock format, in the range 0 to 23. - - @see getHoursInAmPmFormat, isAfternoon - */ - int getHours() const noexcept; - - /** Returns true if the time is in the afternoon. - - So it returns true for "PM", false for "AM". - - @see getHoursInAmPmFormat, getHours - */ - bool isAfternoon() const noexcept; - - /** Returns the hours in 12-hour clock format. - - This will return a value 1 to 12 - use isAfternoon() to find out - whether this is in the afternoon or morning. - - @see getHours, isAfternoon - */ - int getHoursInAmPmFormat() const noexcept; - - /** Returns the number of minutes, 0 to 59. */ - int getMinutes() const noexcept; - - /** Returns the number of seconds, 0 to 59. */ - int getSeconds() const noexcept; - - /** Returns the number of milliseconds, 0 to 999. - - Unlike toMilliseconds(), this just returns the position within the - current second rather than the total number since the epoch. - - @see toMilliseconds - */ - int getMilliseconds() const noexcept; - - /** Returns true if the local timezone uses a daylight saving correction. */ - bool isDaylightSavingTime() const noexcept; - - /** Returns a 3-character string to indicate the local timezone. */ - String getTimeZone() const noexcept; - - //============================================================================== - /** Quick way of getting a string version of a date and time. - - For a more powerful way of formatting the date and time, see the formatted() method. - - @param includeDate whether to include the date in the string - @param includeTime whether to include the time in the string - @param includeSeconds if the time is being included, this provides an option not to include - the seconds in it - @param use24HourClock if the time is being included, sets whether to use am/pm or 24 - hour notation. - @see formatted - */ - String toString (bool includeDate, - bool includeTime, - bool includeSeconds = true, - bool use24HourClock = false) const noexcept; - - /** Converts this date/time to a string with a user-defined format. - - This uses the C strftime() function to format this time as a string. To save you - looking it up, these are the escape codes that strftime uses (other codes might - work on some platforms and not others, but these are the common ones): - - %a is replaced by the locale's abbreviated weekday name. - %A is replaced by the locale's full weekday name. - %b is replaced by the locale's abbreviated month name. - %B is replaced by the locale's full month name. - %c is replaced by the locale's appropriate date and time representation. - %d is replaced by the day of the month as a decimal number [01,31]. - %H is replaced by the hour (24-hour clock) as a decimal number [00,23]. - %I is replaced by the hour (12-hour clock) as a decimal number [01,12]. - %j is replaced by the day of the year as a decimal number [001,366]. - %m is replaced by the month as a decimal number [01,12]. - %M is replaced by the minute as a decimal number [00,59]. - %p is replaced by the locale's equivalent of either a.m. or p.m. - %S is replaced by the second as a decimal number [00,61]. - %U is replaced by the week number of the year (Sunday as the first day of the week) as a decimal number [00,53]. - %w is replaced by the weekday as a decimal number [0,6], with 0 representing Sunday. - %W is replaced by the week number of the year (Monday as the first day of the week) as a decimal number [00,53]. All days in a new year preceding the first Monday are considered to be in week 0. - %x is replaced by the locale's appropriate date representation. - %X is replaced by the locale's appropriate time representation. - %y is replaced by the year without century as a decimal number [00,99]. - %Y is replaced by the year with century as a decimal number. - %Z is replaced by the timezone name or abbreviation, or by no bytes if no timezone information exists. - %% is replaced by %. - - @see toString - */ - String formatted (const String& format) const; - - //============================================================================== - /** Adds a RelativeTime to this time. */ - Time& operator+= (RelativeTime delta) noexcept; - /** Subtracts a RelativeTime from this time. */ - Time& operator-= (RelativeTime delta) noexcept; - - //============================================================================== - /** Tries to set the computer's clock. - - @returns true if this succeeds, although depending on the system, the - application might not have sufficient privileges to do this. - */ - bool setSystemTimeToThisTime() const; - - //============================================================================== - /** Returns the name of a day of the week. - - @param dayNumber the day, 0 to 6 (0 = sunday, 1 = monday, etc) - @param threeLetterVersion if true, it'll return a 3-letter abbreviation, e.g. "Tue"; if - false, it'll return the full version, e.g. "Tuesday". - */ - static String getWeekdayName (int dayNumber, bool threeLetterVersion); - - /** Returns the name of one of the months. - - @param monthNumber the month, 0 to 11 - @param threeLetterVersion if true, it'll be a 3-letter abbreviation, e.g. "Jan"; if false - it'll return the long form, e.g. "January" - */ - static String getMonthName (int monthNumber, bool threeLetterVersion); - - //============================================================================== - // Static methods for getting system timers directly.. - - /** Returns the current system time. - - Returns the number of milliseconds since midnight jan 1st 1970. - - Should be accurate to within a few millisecs, depending on platform, - hardware, etc. - */ - static int64 currentTimeMillis() noexcept; - - /** Returns the number of millisecs since a fixed event (usually system startup). - - This returns a monotonically increasing value which it unaffected by changes to the - system clock. It should be accurate to within a few millisecs, depending on platform, - hardware, etc. - - Being a 32-bit return value, it will of course wrap back to 0 after 2^32 seconds of - uptime, so be careful to take that into account. If you need a 64-bit time, you can - use currentTimeMillis() instead. - - @see getApproximateMillisecondCounter - */ - static uint32 getMillisecondCounter() noexcept; - - /** Returns the number of millisecs since a fixed event (usually system startup). - - This has the same function as getMillisecondCounter(), but returns a more accurate - value, using a higher-resolution timer if one is available. - - @see getMillisecondCounter - */ - static double getMillisecondCounterHiRes() noexcept; - - /** Waits until the getMillisecondCounter() reaches a given value. - - This will make the thread sleep as efficiently as it can while it's waiting. - */ - static void waitForMillisecondCounter (uint32 targetTime) noexcept; - - /** Less-accurate but faster version of getMillisecondCounter(). - - This will return the last value that getMillisecondCounter() returned, so doesn't - need to make a system call, but is less accurate - it shouldn't be more than - 100ms away from the correct time, though, so is still accurate enough for a - lot of purposes. - - @see getMillisecondCounter - */ - static uint32 getApproximateMillisecondCounter() noexcept; - - //============================================================================== - // High-resolution timers.. - - /** Returns the current high-resolution counter's tick-count. - - This is a similar idea to getMillisecondCounter(), but with a higher - resolution. - - @see getHighResolutionTicksPerSecond, highResolutionTicksToSeconds, - secondsToHighResolutionTicks - */ - static int64 getHighResolutionTicks() noexcept; - - /** Returns the resolution of the high-resolution counter in ticks per second. - - @see getHighResolutionTicks, highResolutionTicksToSeconds, - secondsToHighResolutionTicks - */ - static int64 getHighResolutionTicksPerSecond() noexcept; - - /** Converts a number of high-resolution ticks into seconds. - - @see getHighResolutionTicks, getHighResolutionTicksPerSecond, - secondsToHighResolutionTicks - */ - static double highResolutionTicksToSeconds (int64 ticks) noexcept; - - /** Converts a number seconds into high-resolution ticks. - - @see getHighResolutionTicks, getHighResolutionTicksPerSecond, - highResolutionTicksToSeconds - */ - static int64 secondsToHighResolutionTicks (double seconds) noexcept; - - /** Returns a Time based on the value of the __DATE__ macro when this module was compiled */ - static Time getCompilationDate(); - -private: - //============================================================================== - int64 millisSinceEpoch; -}; - -//============================================================================== -/** Adds a RelativeTime to a Time. */ -JUCE_API Time operator+ (Time time, RelativeTime delta) noexcept; -/** Adds a RelativeTime to a Time. */ -JUCE_API Time operator+ (RelativeTime delta, Time time) noexcept; - -/** Subtracts a RelativeTime from a Time. */ -JUCE_API Time operator- (Time time, RelativeTime delta) noexcept; -/** Returns the relative time difference between two times. */ -JUCE_API const RelativeTime operator- (Time time1, Time time2) noexcept; - -/** Compares two Time objects. */ -JUCE_API bool operator== (Time time1, Time time2) noexcept; -/** Compares two Time objects. */ -JUCE_API bool operator!= (Time time1, Time time2) noexcept; -/** Compares two Time objects. */ -JUCE_API bool operator< (Time time1, Time time2) noexcept; -/** Compares two Time objects. */ -JUCE_API bool operator<= (Time time1, Time time2) noexcept; -/** Compares two Time objects. */ -JUCE_API bool operator> (Time time1, Time time2) noexcept; -/** Compares two Time objects. */ -JUCE_API bool operator>= (Time time1, Time time2) noexcept; - - -#endif // JUCE_TIME_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/unit_tests/juce_UnitTest.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/unit_tests/juce_UnitTest.cpp deleted file mode 100644 index f5a60c1a54..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/unit_tests/juce_UnitTest.cpp +++ /dev/null @@ -1,260 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -UnitTest::UnitTest (const String& nm) - : name (nm), runner (nullptr) -{ - getAllTests().add (this); -} - -UnitTest::~UnitTest() -{ - getAllTests().removeFirstMatchingValue (this); -} - -Array& UnitTest::getAllTests() -{ - static Array tests; - return tests; -} - -void UnitTest::initialise() {} -void UnitTest::shutdown() {} - -void UnitTest::performTest (UnitTestRunner* const newRunner) -{ - jassert (newRunner != nullptr); - runner = newRunner; - - initialise(); - runTest(); - shutdown(); -} - -void UnitTest::logMessage (const String& message) -{ - // This method's only valid while the test is being run! - jassert (runner != nullptr); - - runner->logMessage (message); -} - -void UnitTest::beginTest (const String& testName) -{ - // This method's only valid while the test is being run! - jassert (runner != nullptr); - - runner->beginNewTest (this, testName); -} - -void UnitTest::expect (const bool result, const String& failureMessage) -{ - // This method's only valid while the test is being run! - jassert (runner != nullptr); - - if (result) - runner->addPass(); - else - runner->addFail (failureMessage); -} - -Random UnitTest::getRandom() const -{ - // This method's only valid while the test is being run! - jassert (runner != nullptr); - - return runner->randomForTest; -} - -//============================================================================== -UnitTestRunner::UnitTestRunner() - : currentTest (nullptr), - assertOnFailure (true), - logPasses (false) -{ -} - -UnitTestRunner::~UnitTestRunner() -{ -} - -void UnitTestRunner::setAssertOnFailure (bool shouldAssert) noexcept -{ - assertOnFailure = shouldAssert; -} - -void UnitTestRunner::setPassesAreLogged (bool shouldDisplayPasses) noexcept -{ - logPasses = shouldDisplayPasses; -} - -int UnitTestRunner::getNumResults() const noexcept -{ - return results.size(); -} - -const UnitTestRunner::TestResult* UnitTestRunner::getResult (int index) const noexcept -{ - return results [index]; -} - -void UnitTestRunner::resultsUpdated() -{ -} - -void UnitTestRunner::runTests (const Array& tests, int64 randomSeed) -{ - results.clear(); - resultsUpdated(); - - if (randomSeed == 0) - randomSeed = Random().nextInt (0x7ffffff); - - randomForTest = Random (randomSeed); - logMessage ("Random seed: 0x" + String::toHexString (randomSeed)); - - for (int i = 0; i < tests.size(); ++i) - { - if (shouldAbortTests()) - break; - - try - { - tests.getUnchecked(i)->performTest (this); - } - catch (...) - { - addFail ("An unhandled exception was thrown!"); - } - } - - endTest(); -} - -void UnitTestRunner::runAllTests (int64 randomSeed) -{ - runTests (UnitTest::getAllTests(), randomSeed); -} - -void UnitTestRunner::logMessage (const String& message) -{ - Logger::writeToLog (message); -} - -bool UnitTestRunner::shouldAbortTests() -{ - return false; -} - -void UnitTestRunner::beginNewTest (UnitTest* const test, const String& subCategory) -{ - endTest(); - currentTest = test; - - TestResult* const r = new TestResult(); - results.add (r); - r->unitTestName = test->getName(); - r->subcategoryName = subCategory; - r->passes = 0; - r->failures = 0; - - logMessage ("-----------------------------------------------------------------"); - logMessage ("Starting test: " + r->unitTestName + " / " + subCategory + "..."); - - resultsUpdated(); -} - -void UnitTestRunner::endTest() -{ - if (results.size() > 0) - { - TestResult* const r = results.getLast(); - - if (r->failures > 0) - { - String m ("FAILED!! "); - m << r->failures << (r->failures == 1 ? " test" : " tests") - << " failed, out of a total of " << (r->passes + r->failures); - - logMessage (String::empty); - logMessage (m); - logMessage (String::empty); - } - else - { - logMessage ("All tests completed successfully"); - } - } -} - -void UnitTestRunner::addPass() -{ - { - const ScopedLock sl (results.getLock()); - - TestResult* const r = results.getLast(); - jassert (r != nullptr); // You need to call UnitTest::beginTest() before performing any tests! - - r->passes++; - - if (logPasses) - { - String message ("Test "); - message << (r->failures + r->passes) << " passed"; - logMessage (message); - } - } - - resultsUpdated(); -} - -void UnitTestRunner::addFail (const String& failureMessage) -{ - { - const ScopedLock sl (results.getLock()); - - TestResult* const r = results.getLast(); - jassert (r != nullptr); // You need to call UnitTest::beginTest() before performing any tests! - - r->failures++; - - String message ("!!! Test "); - message << (r->failures + r->passes) << " failed"; - - if (failureMessage.isNotEmpty()) - message << ": " << failureMessage; - - r->messages.add (message); - - logMessage (message); - } - - resultsUpdated(); - - if (assertOnFailure) { jassertfalse; } -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/unit_tests/juce_UnitTest.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/unit_tests/juce_UnitTest.h deleted file mode 100644 index f5908c17cb..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/unit_tests/juce_UnitTest.h +++ /dev/null @@ -1,311 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_UNITTEST_H_INCLUDED -#define JUCE_UNITTEST_H_INCLUDED - -class UnitTestRunner; - - -//============================================================================== -/** - This is a base class for classes that perform a unit test. - - To write a test using this class, your code should look something like this: - - @code - class MyTest : public UnitTest - { - public: - MyTest() : UnitTest ("Foobar testing") {} - - void runTest() - { - beginTest ("Part 1"); - - expect (myFoobar.doesSomething()); - expect (myFoobar.doesSomethingElse()); - - beginTest ("Part 2"); - - expect (myOtherFoobar.doesSomething()); - expect (myOtherFoobar.doesSomethingElse()); - - ...etc.. - } - }; - - // Creating a static instance will automatically add the instance to the array - // returned by UnitTest::getAllTests(), so the test will be included when you call - // UnitTestRunner::runAllTests() - static MyTest test; - @endcode - - To run a test, use the UnitTestRunner class. - - @see UnitTestRunner -*/ -class JUCE_API UnitTest -{ -public: - //============================================================================== - /** Creates a test with the given name. */ - explicit UnitTest (const String& name); - - /** Destructor. */ - virtual ~UnitTest(); - - /** Returns the name of the test. */ - const String& getName() const noexcept { return name; } - - /** Runs the test, using the specified UnitTestRunner. - You shouldn't need to call this method directly - use - UnitTestRunner::runTests() instead. - */ - void performTest (UnitTestRunner* runner); - - /** Returns the set of all UnitTest objects that currently exist. */ - static Array& getAllTests(); - - //============================================================================== - /** You can optionally implement this method to set up your test. - This method will be called before runTest(). - */ - virtual void initialise(); - - /** You can optionally implement this method to clear up after your test has been run. - This method will be called after runTest() has returned. - */ - virtual void shutdown(); - - /** Implement this method in your subclass to actually run your tests. - - The content of your implementation should call beginTest() and expect() - to perform the tests. - */ - virtual void runTest() = 0; - - //============================================================================== - /** Tells the system that a new subsection of tests is beginning. - This should be called from your runTest() method, and may be called - as many times as you like, to demarcate different sets of tests. - */ - void beginTest (const String& testName); - - //============================================================================== - /** Checks that the result of a test is true, and logs this result. - - In your runTest() method, you should call this method for each condition that - you want to check, e.g. - - @code - void runTest() - { - beginTest ("basic tests"); - expect (x + y == 2); - expect (getThing() == someThing); - ...etc... - } - @endcode - - If testResult is true, a pass is logged; if it's false, a failure is logged. - If the failure message is specified, it will be written to the log if the test fails. - */ - void expect (bool testResult, const String& failureMessage = String::empty); - - /** Compares two values, and if they don't match, prints out a message containing the - expected and actual result values. - */ - template - void expectEquals (ValueType actual, ValueType expected, String failureMessage = String::empty) - { - const bool result = (actual == expected); - - if (! result) - { - if (failureMessage.isNotEmpty()) - failureMessage << " -- "; - - failureMessage << "Expected value: " << expected << ", Actual value: " << actual; - } - - expect (result, failureMessage); - } - - //============================================================================== - /** Writes a message to the test log. - This can only be called from within your runTest() method. - */ - void logMessage (const String& message); - - /** Returns a shared RNG that all unit tests should use. - If a test needs random numbers, it's important that when an error is found, the - exact circumstances can be re-created in order to re-test the problem, by - repeating the test with the same random seed value. - To make this possible, the UnitTestRunner class creates a master seed value - for the run, writes this number to the log, and then this method returns a - Random object based on that seed. All tests should only use this method to - create any Random objects that they need. - - Note that this method will return an identical object each time it's called - for a given run, so if you need several different Random objects, the best - way to do that is to call Random::combineSeed() on the result to permute it - with a constant value. - */ - Random getRandom() const; - -private: - //============================================================================== - const String name; - UnitTestRunner* runner; - - JUCE_DECLARE_NON_COPYABLE (UnitTest) -}; - - -//============================================================================== -/** - Runs a set of unit tests. - - You can instantiate one of these objects and use it to invoke tests on a set of - UnitTest objects. - - By using a subclass of UnitTestRunner, you can intercept logging messages and - perform custom behaviour when each test completes. - - @see UnitTest -*/ -class JUCE_API UnitTestRunner -{ -public: - //============================================================================== - /** */ - UnitTestRunner(); - - /** Destructor. */ - virtual ~UnitTestRunner(); - - /** Runs a set of tests. - - The tests are performed in order, and the results are logged. To run all the - registered UnitTest objects that exist, use runAllTests(). - - If you want to run the tests with a predetermined seed, you can pass that into - the randomSeed argument, or pass 0 to have a randomly-generated seed chosen. - */ - void runTests (const Array& tests, int64 randomSeed = 0); - - /** Runs all the UnitTest objects that currently exist. - This calls runTests() for all the objects listed in UnitTest::getAllTests(). - - If you want to run the tests with a predetermined seed, you can pass that into - the randomSeed argument, or pass 0 to have a randomly-generated seed chosen. - */ - void runAllTests (int64 randomSeed = 0); - - /** Sets a flag to indicate whether an assertion should be triggered if a test fails. - This is true by default. - */ - void setAssertOnFailure (bool shouldAssert) noexcept; - - /** Sets a flag to indicate whether successful tests should be logged. - By default, this is set to false, so that only failures will be displayed in the log. - */ - void setPassesAreLogged (bool shouldDisplayPasses) noexcept; - - //============================================================================== - /** Contains the results of a test. - - One of these objects is instantiated each time UnitTest::beginTest() is called, and - it contains details of the number of subsequent UnitTest::expect() calls that are - made. - */ - struct TestResult - { - /** The main name of this test (i.e. the name of the UnitTest object being run). */ - String unitTestName; - /** The name of the current subcategory (i.e. the name that was set when UnitTest::beginTest() was called). */ - String subcategoryName; - - /** The number of UnitTest::expect() calls that succeeded. */ - int passes; - /** The number of UnitTest::expect() calls that failed. */ - int failures; - - /** A list of messages describing the failed tests. */ - StringArray messages; - }; - - /** Returns the number of TestResult objects that have been performed. - @see getResult - */ - int getNumResults() const noexcept; - - /** Returns one of the TestResult objects that describes a test that has been run. - @see getNumResults - */ - const TestResult* getResult (int index) const noexcept; - -protected: - /** Called when the list of results changes. - You can override this to perform some sort of behaviour when results are added. - */ - virtual void resultsUpdated(); - - /** Logs a message about the current test progress. - By default this just writes the message to the Logger class, but you could override - this to do something else with the data. - */ - virtual void logMessage (const String& message); - - /** This can be overridden to let the runner know that it should abort the tests - as soon as possible, e.g. because the thread needs to stop. - */ - virtual bool shouldAbortTests(); - -private: - //============================================================================== - friend class UnitTest; - - UnitTest* currentTest; - String currentSubCategory; - OwnedArray results; - bool assertOnFailure, logPasses; - Random randomForTest; - - void beginNewTest (UnitTest* test, const String& subCategory); - void endTest(); - - void addPass(); - void addFail (const String& failureMessage); - - JUCE_DECLARE_NON_COPYABLE (UnitTestRunner) -}; - - -#endif // JUCE_UNITTEST_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/xml/juce_XmlDocument.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/xml/juce_XmlDocument.cpp deleted file mode 100644 index 2eab527a25..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/xml/juce_XmlDocument.cpp +++ /dev/null @@ -1,891 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -XmlDocument::XmlDocument (const String& documentText) - : originalText (documentText), - input (nullptr), - outOfData (false), - errorOccurred (false), - needToLoadDTD (false), - ignoreEmptyTextElements (true) -{ -} - -XmlDocument::XmlDocument (const File& file) - : input (nullptr), - outOfData (false), - errorOccurred (false), - needToLoadDTD (false), - ignoreEmptyTextElements (true), - inputSource (new FileInputSource (file)) -{ -} - -XmlDocument::~XmlDocument() -{ -} - -XmlElement* XmlDocument::parse (const File& file) -{ - XmlDocument doc (file); - return doc.getDocumentElement(); -} - -XmlElement* XmlDocument::parse (const String& xmlData) -{ - XmlDocument doc (xmlData); - return doc.getDocumentElement(); -} - -void XmlDocument::setInputSource (InputSource* const newSource) noexcept -{ - inputSource = newSource; -} - -void XmlDocument::setEmptyTextElementsIgnored (const bool shouldBeIgnored) noexcept -{ - ignoreEmptyTextElements = shouldBeIgnored; -} - -namespace XmlIdentifierChars -{ - static bool isIdentifierCharSlow (const juce_wchar c) noexcept - { - return CharacterFunctions::isLetterOrDigit (c) - || c == '_' || c == '-' || c == ':' || c == '.'; - } - - static bool isIdentifierChar (const juce_wchar c) noexcept - { - static const uint32 legalChars[] = { 0, 0x7ff6000, 0x87fffffe, 0x7fffffe, 0 }; - - return ((int) c < (int) numElementsInArray (legalChars) * 32) ? ((legalChars [c >> 5] & (1 << (c & 31))) != 0) - : isIdentifierCharSlow (c); - } - - /*static void generateIdentifierCharConstants() - { - uint32 n[8] = { 0 }; - for (int i = 0; i < 256; ++i) - if (isIdentifierCharSlow (i)) - n[i >> 5] |= (1 << (i & 31)); - - String s; - for (int i = 0; i < 8; ++i) - s << "0x" << String::toHexString ((int) n[i]) << ", "; - - DBG (s); - }*/ - - static String::CharPointerType findEndOfToken (String::CharPointerType p) - { - while (isIdentifierChar (*p)) - ++p; - - return p; - } -} - -XmlElement* XmlDocument::getDocumentElement (const bool onlyReadOuterDocumentElement) -{ - if (originalText.isEmpty() && inputSource != nullptr) - { - ScopedPointer in (inputSource->createInputStream()); - - if (in != nullptr) - { - MemoryOutputStream data; - data.writeFromInputStream (*in, onlyReadOuterDocumentElement ? 8192 : -1); - - #if JUCE_STRING_UTF_TYPE == 8 - if (data.getDataSize() > 2) - { - data.writeByte (0); - const char* text = static_cast (data.getData()); - - if (CharPointer_UTF16::isByteOrderMarkBigEndian (text) - || CharPointer_UTF16::isByteOrderMarkLittleEndian (text)) - { - originalText = data.toString(); - } - else - { - if (CharPointer_UTF8::isByteOrderMark (text)) - text += 3; - - // parse the input buffer directly to avoid copying it all to a string.. - return parseDocumentElement (String::CharPointerType (text), onlyReadOuterDocumentElement); - } - } - #else - originalText = data.toString(); - #endif - } - } - - return parseDocumentElement (originalText.getCharPointer(), onlyReadOuterDocumentElement); -} - -const String& XmlDocument::getLastParseError() const noexcept -{ - return lastError; -} - -void XmlDocument::setLastError (const String& desc, const bool carryOn) -{ - lastError = desc; - errorOccurred = ! carryOn; -} - -String XmlDocument::getFileContents (const String& filename) const -{ - if (inputSource != nullptr) - { - const ScopedPointer in (inputSource->createInputStreamFor (filename.trim().unquoted())); - - if (in != nullptr) - return in->readEntireStreamAsString(); - } - - return String::empty; -} - -juce_wchar XmlDocument::readNextChar() noexcept -{ - const juce_wchar c = input.getAndAdvance(); - - if (c == 0) - { - outOfData = true; - --input; - } - - return c; -} - -XmlElement* XmlDocument::parseDocumentElement (String::CharPointerType textToParse, - const bool onlyReadOuterDocumentElement) -{ - input = textToParse; - errorOccurred = false; - outOfData = false; - needToLoadDTD = true; - - if (textToParse.isEmpty()) - { - lastError = "not enough input"; - } - else if (! parseHeader()) - { - lastError = "malformed header"; - } - else if (! parseDTD()) - { - lastError = "malformed DTD"; - } - else - { - lastError.clear(); - - ScopedPointer result (readNextElement (! onlyReadOuterDocumentElement)); - - if (! errorOccurred) - return result.release(); - } - - return nullptr; -} - -bool XmlDocument::parseHeader() -{ - skipNextWhiteSpace(); - - if (CharacterFunctions::compareUpTo (input, CharPointer_ASCII (""))); - - if (headerEnd.isEmpty()) - return false; - - #if JUCE_DEBUG - const String encoding (String (input, headerEnd) - .fromFirstOccurrenceOf ("encoding", false, true) - .fromFirstOccurrenceOf ("=", false, false) - .fromFirstOccurrenceOf ("\"", false, false) - .upToFirstOccurrenceOf ("\"", false, false).trim()); - - /* If you load an XML document with a non-UTF encoding type, it may have been - loaded wrongly.. Since all the files are read via the normal juce file streams, - they're treated as UTF-8, so by the time it gets to the parser, the encoding will - have been lost. Best plan is to stick to utf-8 or if you have specific files to - read, use your own code to convert them to a unicode String, and pass that to the - XML parser. - */ - jassert (encoding.isEmpty() || encoding.startsWithIgnoreCase ("utf-")); - #endif - - input = headerEnd + 2; - skipNextWhiteSpace(); - } - - return true; -} - -bool XmlDocument::parseDTD() -{ - if (CharacterFunctions::compareUpTo (input, CharPointer_ASCII (" 0;) - { - const juce_wchar c = readNextChar(); - - if (outOfData) - return false; - - if (c == '<') - ++n; - else if (c == '>') - --n; - } - - dtdText = String (dtdStart, input - 1).trim(); - } - - return true; -} - -void XmlDocument::skipNextWhiteSpace() -{ - for (;;) - { - input = input.findEndOfWhitespace(); - - if (input.isEmpty()) - { - outOfData = true; - break; - } - - if (*input == '<') - { - if (input[1] == '!' - && input[2] == '-' - && input[3] == '-') - { - input += 4; - const int closeComment = input.indexOf (CharPointer_ASCII ("-->")); - - if (closeComment < 0) - { - outOfData = true; - break; - } - - input += closeComment + 3; - continue; - } - - if (input[1] == '?') - { - input += 2; - const int closeBracket = input.indexOf (CharPointer_ASCII ("?>")); - - if (closeBracket < 0) - { - outOfData = true; - break; - } - - input += closeBracket + 2; - continue; - } - } - - break; - } -} - -void XmlDocument::readQuotedString (String& result) -{ - const juce_wchar quote = readNextChar(); - - while (! outOfData) - { - const juce_wchar c = readNextChar(); - - if (c == quote) - break; - - --input; - - if (c == '&') - { - readEntity (result); - } - else - { - const String::CharPointerType start (input); - - for (;;) - { - const juce_wchar character = *input; - - if (character == quote) - { - result.appendCharPointer (start, input); - ++input; - return; - } - else if (character == '&') - { - result.appendCharPointer (start, input); - break; - } - else if (character == 0) - { - setLastError ("unmatched quotes", false); - outOfData = true; - break; - } - - ++input; - } - } - } -} - -XmlElement* XmlDocument::readNextElement (const bool alsoParseSubElements) -{ - XmlElement* node = nullptr; - - skipNextWhiteSpace(); - if (outOfData) - return nullptr; - - if (*input == '<') - { - ++input; - String::CharPointerType endOfToken (XmlIdentifierChars::findEndOfToken (input)); - - if (endOfToken == input) - { - // no tag name - but allow for a gap after the '<' before giving an error - skipNextWhiteSpace(); - endOfToken = XmlIdentifierChars::findEndOfToken (input); - - if (endOfToken == input) - { - setLastError ("tag name missing", false); - return node; - } - } - - node = new XmlElement (input, endOfToken); - input = endOfToken; - LinkedListPointer::Appender attributeAppender (node->attributes); - - // look for attributes - for (;;) - { - skipNextWhiteSpace(); - - const juce_wchar c = *input; - - // empty tag.. - if (c == '/' && input[1] == '>') - { - input += 2; - break; - } - - // parse the guts of the element.. - if (c == '>') - { - ++input; - - if (alsoParseSubElements) - readChildElements (*node); - - break; - } - - // get an attribute.. - if (XmlIdentifierChars::isIdentifierChar (c)) - { - String::CharPointerType attNameEnd (XmlIdentifierChars::findEndOfToken (input)); - - if (attNameEnd != input) - { - const String::CharPointerType attNameStart (input); - input = attNameEnd; - - skipNextWhiteSpace(); - - if (readNextChar() == '=') - { - skipNextWhiteSpace(); - - const juce_wchar nextChar = *input; - - if (nextChar == '"' || nextChar == '\'') - { - XmlElement::XmlAttributeNode* const newAtt - = new XmlElement::XmlAttributeNode (attNameStart, attNameEnd); - - readQuotedString (newAtt->value); - attributeAppender.append (newAtt); - continue; - } - } - else - { - setLastError ("expected '=' after attribute '" - + String (attNameStart, attNameEnd) + "'", false); - return node; - } - } - } - else - { - if (! outOfData) - setLastError ("illegal character found in " + node->getTagName() + ": '" + c + "'", false); - } - - break; - } - } - - return node; -} - -void XmlDocument::readChildElements (XmlElement& parent) -{ - LinkedListPointer::Appender childAppender (parent.firstChildElement); - - for (;;) - { - const String::CharPointerType preWhitespaceInput (input); - skipNextWhiteSpace(); - - if (outOfData) - { - setLastError ("unmatched tags", false); - break; - } - - if (*input == '<') - { - const juce_wchar c1 = input[1]; - - if (c1 == '/') - { - // our close tag.. - const int closeTag = input.indexOf ((juce_wchar) '>'); - - if (closeTag >= 0) - input += closeTag + 1; - - break; - } - - if (c1 == '!' && CharacterFunctions::compareUpTo (input + 2, CharPointer_ASCII ("[CDATA["), 7) == 0) - { - input += 9; - const String::CharPointerType inputStart (input); - - for (;;) - { - const juce_wchar c0 = *input; - - if (c0 == 0) - { - setLastError ("unterminated CDATA section", false); - outOfData = true; - break; - } - else if (c0 == ']' - && input[1] == ']' - && input[2] == '>') - { - childAppender.append (XmlElement::createTextElement (String (inputStart, input))); - input += 3; - break; - } - - ++input; - } - } - else - { - // this is some other element, so parse and add it.. - if (XmlElement* const n = readNextElement (true)) - childAppender.append (n); - else - break; - } - } - else // must be a character block - { - input = preWhitespaceInput; // roll back to include the leading whitespace - String textElementContent; - - for (;;) - { - const juce_wchar c = *input; - - if (c == '<') - { - if (input[1] == '!' && input[2] == '-' && input[3] == '-') - { - input += 4; - const int closeComment = input.indexOf (CharPointer_ASCII ("-->")); - - if (closeComment < 0) - { - setLastError ("unterminated comment", false); - outOfData = true; - return; - } - - input += closeComment + 3; - continue; - } - - break; - } - - if (c == 0) - { - setLastError ("unmatched tags", false); - outOfData = true; - return; - } - - if (c == '&') - { - String entity; - readEntity (entity); - - if (entity.startsWithChar ('<') && entity [1] != 0) - { - const String::CharPointerType oldInput (input); - const bool oldOutOfData = outOfData; - - input = entity.getCharPointer(); - outOfData = false; - - for (;;) - { - XmlElement* const n = readNextElement (true); - - if (n == nullptr) - break; - - childAppender.append (n); - } - - input = oldInput; - outOfData = oldOutOfData; - } - else - { - textElementContent += entity; - } - } - else - { - const String::CharPointerType start (input); - - for (;;) - { - const juce_wchar nextChar = *input; - - if (nextChar == '<' || nextChar == '&') - break; - - if (nextChar == 0) - { - setLastError ("unmatched tags", false); - outOfData = true; - return; - } - - ++input; - } - - textElementContent.appendCharPointer (start, input); - } - } - - if ((! ignoreEmptyTextElements) || textElementContent.containsNonWhitespaceChars()) - childAppender.append (XmlElement::createTextElement (textElementContent)); - } - } -} - -void XmlDocument::readEntity (String& result) -{ - // skip over the ampersand - ++input; - - if (input.compareIgnoreCaseUpTo (CharPointer_ASCII ("amp;"), 4) == 0) - { - input += 4; - result += '&'; - } - else if (input.compareIgnoreCaseUpTo (CharPointer_ASCII ("quot;"), 5) == 0) - { - input += 5; - result += '"'; - } - else if (input.compareIgnoreCaseUpTo (CharPointer_ASCII ("apos;"), 5) == 0) - { - input += 5; - result += '\''; - } - else if (input.compareIgnoreCaseUpTo (CharPointer_ASCII ("lt;"), 3) == 0) - { - input += 3; - result += '<'; - } - else if (input.compareIgnoreCaseUpTo (CharPointer_ASCII ("gt;"), 3) == 0) - { - input += 3; - result += '>'; - } - else if (*input == '#') - { - int charCode = 0; - ++input; - - if (*input == 'x' || *input == 'X') - { - ++input; - int numChars = 0; - - while (input[0] != ';') - { - const int hexValue = CharacterFunctions::getHexDigitValue (input[0]); - - if (hexValue < 0 || ++numChars > 8) - { - setLastError ("illegal escape sequence", true); - break; - } - - charCode = (charCode << 4) | hexValue; - ++input; - } - - ++input; - } - else if (input[0] >= '0' && input[0] <= '9') - { - int numChars = 0; - - while (input[0] != ';') - { - if (++numChars > 12) - { - setLastError ("illegal escape sequence", true); - break; - } - - charCode = charCode * 10 + ((int) input[0] - '0'); - ++input; - } - - ++input; - } - else - { - setLastError ("illegal escape sequence", true); - result += '&'; - return; - } - - result << (juce_wchar) charCode; - } - else - { - const String::CharPointerType entityNameStart (input); - const int closingSemiColon = input.indexOf ((juce_wchar) ';'); - - if (closingSemiColon < 0) - { - outOfData = true; - result += '&'; - } - else - { - input += closingSemiColon + 1; - - result += expandExternalEntity (String (entityNameStart, (size_t) closingSemiColon)); - } - } -} - -String XmlDocument::expandEntity (const String& ent) -{ - if (ent.equalsIgnoreCase ("amp")) return String::charToString ('&'); - if (ent.equalsIgnoreCase ("quot")) return String::charToString ('"'); - if (ent.equalsIgnoreCase ("apos")) return String::charToString ('\''); - if (ent.equalsIgnoreCase ("lt")) return String::charToString ('<'); - if (ent.equalsIgnoreCase ("gt")) return String::charToString ('>'); - - if (ent[0] == '#') - { - const juce_wchar char1 = ent[1]; - - if (char1 == 'x' || char1 == 'X') - return String::charToString (static_cast (ent.substring (2).getHexValue32())); - - if (char1 >= '0' && char1 <= '9') - return String::charToString (static_cast (ent.substring (1).getIntValue())); - - setLastError ("illegal escape sequence", false); - return String::charToString ('&'); - } - - return expandExternalEntity (ent); -} - -String XmlDocument::expandExternalEntity (const String& entity) -{ - if (needToLoadDTD) - { - if (dtdText.isNotEmpty()) - { - dtdText = dtdText.trimCharactersAtEnd (">"); - tokenisedDTD.addTokens (dtdText, true); - - if (tokenisedDTD [tokenisedDTD.size() - 2].equalsIgnoreCase ("system") - && tokenisedDTD [tokenisedDTD.size() - 1].isQuotedString()) - { - const String fn (tokenisedDTD [tokenisedDTD.size() - 1]); - - tokenisedDTD.clear(); - tokenisedDTD.addTokens (getFileContents (fn), true); - } - else - { - tokenisedDTD.clear(); - const int openBracket = dtdText.indexOfChar ('['); - - if (openBracket > 0) - { - const int closeBracket = dtdText.lastIndexOfChar (']'); - - if (closeBracket > openBracket) - tokenisedDTD.addTokens (dtdText.substring (openBracket + 1, - closeBracket), true); - } - } - - for (int i = tokenisedDTD.size(); --i >= 0;) - { - if (tokenisedDTD[i].startsWithChar ('%') - && tokenisedDTD[i].endsWithChar (';')) - { - const String parsed (getParameterEntity (tokenisedDTD[i].substring (1, tokenisedDTD[i].length() - 1))); - StringArray newToks; - newToks.addTokens (parsed, true); - - tokenisedDTD.remove (i); - - for (int j = newToks.size(); --j >= 0;) - tokenisedDTD.insert (i, newToks[j]); - } - } - } - - needToLoadDTD = false; - } - - for (int i = 0; i < tokenisedDTD.size(); ++i) - { - if (tokenisedDTD[i] == entity) - { - if (tokenisedDTD[i - 1].equalsIgnoreCase ("").trim().unquoted()); - - // check for sub-entities.. - int ampersand = ent.indexOfChar ('&'); - - while (ampersand >= 0) - { - const int semiColon = ent.indexOf (i + 1, ";"); - - if (semiColon < 0) - { - setLastError ("entity without terminating semi-colon", false); - break; - } - - const String resolved (expandEntity (ent.substring (i + 1, semiColon))); - - ent = ent.substring (0, ampersand) - + resolved - + ent.substring (semiColon + 1); - - ampersand = ent.indexOfChar (semiColon + 1, '&'); - } - - return ent; - } - } - } - - setLastError ("unknown entity", true); - - return entity; -} - -String XmlDocument::getParameterEntity (const String& entity) -{ - for (int i = 0; i < tokenisedDTD.size(); ++i) - { - if (tokenisedDTD[i] == entity - && tokenisedDTD [i - 1] == "%" - && tokenisedDTD [i - 2].equalsIgnoreCase ("")); - - if (ent.equalsIgnoreCase ("system")) - return getFileContents (tokenisedDTD [i + 2].trimCharactersAtEnd (">")); - - return ent.trim().unquoted(); - } - } - - return entity; -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/xml/juce_XmlDocument.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/xml/juce_XmlDocument.h deleted file mode 100644 index d2a5b49e03..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/xml/juce_XmlDocument.h +++ /dev/null @@ -1,181 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_XMLDOCUMENT_H_INCLUDED -#define JUCE_XMLDOCUMENT_H_INCLUDED - - -//============================================================================== -/** - Parses a text-based XML document and creates an XmlElement object from it. - - The parser will parse DTDs to load external entities but won't - check the document for validity against the DTD. - - e.g. - @code - - XmlDocument myDocument (File ("myfile.xml")); - XmlElement* mainElement = myDocument.getDocumentElement(); - - if (mainElement == nullptr) - { - String error = myDocument.getLastParseError(); - } - else - { - ..use the element - } - - @endcode - - Or you can use the static helper methods for quick parsing.. - - @code - XmlElement* xml = XmlDocument::parse (myXmlFile); - - if (xml != nullptr && xml->hasTagName ("foobar")) - { - ...etc - @endcode - - @see XmlElement -*/ -class JUCE_API XmlDocument -{ -public: - //============================================================================== - /** Creates an XmlDocument from the xml text. - The text doesn't actually get parsed until the getDocumentElement() method is called. - */ - XmlDocument (const String& documentText); - - /** Creates an XmlDocument from a file. - The text doesn't actually get parsed until the getDocumentElement() method is called. - */ - XmlDocument (const File& file); - - /** Destructor. */ - ~XmlDocument(); - - //============================================================================== - /** Creates an XmlElement object to represent the main document node. - - This method will do the actual parsing of the text, and if there's a - parse error, it may returns nullptr (and you can find out the error using - the getLastParseError() method). - - See also the parse() methods, which provide a shorthand way to quickly - parse a file or string. - - @param onlyReadOuterDocumentElement if true, the parser will only read the - first section of the file, and will only - return the outer document element - this - allows quick checking of large files to - see if they contain the correct type of - tag, without having to parse the entire file - @returns a new XmlElement which the caller will need to delete, or null if - there was an error. - @see getLastParseError - */ - XmlElement* getDocumentElement (bool onlyReadOuterDocumentElement = false); - - /** Returns the parsing error that occurred the last time getDocumentElement was called. - - @returns the error, or an empty string if there was no error. - */ - const String& getLastParseError() const noexcept; - - /** Sets an input source object to use for parsing documents that reference external entities. - - If the document has been created from a file, this probably won't be needed, but - if you're parsing some text and there might be a DTD that references external - files, you may need to create a custom input source that can retrieve the - other files it needs. - - The object that is passed-in will be deleted automatically when no longer needed. - - @see InputSource - */ - void setInputSource (InputSource* newSource) noexcept; - - /** Sets a flag to change the treatment of empty text elements. - - If this is true (the default state), then any text elements that contain only - whitespace characters will be ingored during parsing. If you need to catch - whitespace-only text, then you should set this to false before calling the - getDocumentElement() method. - */ - void setEmptyTextElementsIgnored (bool shouldBeIgnored) noexcept; - - //============================================================================== - /** A handy static method that parses a file. - This is a shortcut for creating an XmlDocument object and calling getDocumentElement() on it. - @returns a new XmlElement which the caller will need to delete, or null if there was an error. - */ - static XmlElement* parse (const File& file); - - /** A handy static method that parses some XML data. - This is a shortcut for creating an XmlDocument object and calling getDocumentElement() on it. - @returns a new XmlElement which the caller will need to delete, or null if there was an error. - */ - static XmlElement* parse (const String& xmlData); - - - //============================================================================== -private: - String originalText; - String::CharPointerType input; - bool outOfData, errorOccurred; - - String lastError, dtdText; - StringArray tokenisedDTD; - bool needToLoadDTD, ignoreEmptyTextElements; - ScopedPointer inputSource; - - XmlElement* parseDocumentElement (String::CharPointerType, bool outer); - void setLastError (const String&, bool carryOn); - bool parseHeader(); - bool parseDTD(); - void skipNextWhiteSpace(); - juce_wchar readNextChar() noexcept; - XmlElement* readNextElement (bool alsoParseSubElements); - void readChildElements (XmlElement&); - void readQuotedString (String&); - void readEntity (String&); - - String getFileContents (const String&) const; - String expandEntity (const String&); - String expandExternalEntity (const String&); - String getParameterEntity (const String&); - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (XmlDocument) -}; - - -#endif // JUCE_XMLDOCUMENT_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/xml/juce_XmlElement.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/xml/juce_XmlElement.cpp deleted file mode 100644 index 866d10ab3b..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/xml/juce_XmlElement.cpp +++ /dev/null @@ -1,888 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -XmlElement::XmlAttributeNode::XmlAttributeNode (const XmlAttributeNode& other) noexcept - : name (other.name), - value (other.value) -{ -} - -XmlElement::XmlAttributeNode::XmlAttributeNode (const Identifier& n, const String& v) noexcept - : name (n), value (v) -{ - #if JUCE_DEBUG - // this checks whether the attribute name string contains any illegal characters.. - for (String::CharPointerType t (name.getCharPointer()); ! t.isEmpty(); ++t) - jassert (t.isLetterOrDigit() || *t == '_' || *t == '-' || *t == ':'); - #endif -} - -XmlElement::XmlAttributeNode::XmlAttributeNode (String::CharPointerType nameStart, String::CharPointerType nameEnd) - : name (nameStart, nameEnd) -{ -} - -//============================================================================== -static void sanityCheckTagName (const String& tag) -{ - (void) tag; - - // the tag name mustn't be empty, or it'll look like a text element! - jassert (tag.containsNonWhitespaceChars()); - - // The tag can't contain spaces or other characters that would create invalid XML! - jassert (! tag.containsAnyOf (" <>/&(){}")); -} - -XmlElement::XmlElement (const String& tag) - : tagName (StringPool::getGlobalPool().getPooledString (tag)) -{ - sanityCheckTagName (tagName); -} - -XmlElement::XmlElement (const char* tag) - : tagName (StringPool::getGlobalPool().getPooledString (tag)) -{ - sanityCheckTagName (tagName); -} - -XmlElement::XmlElement (StringRef tag) - : tagName (StringPool::getGlobalPool().getPooledString (tag)) -{ - sanityCheckTagName (tagName); -} - -XmlElement::XmlElement (const Identifier& tag) - : tagName (tag.toString()) -{ - sanityCheckTagName (tagName); -} - -XmlElement::XmlElement (String::CharPointerType tagNameStart, String::CharPointerType tagNameEnd) - : tagName (StringPool::getGlobalPool().getPooledString (tagNameStart, tagNameEnd)) -{ - sanityCheckTagName (tagName); -} - -XmlElement::XmlElement (int /*dummy*/) noexcept -{ -} - -XmlElement::XmlElement (const XmlElement& other) - : tagName (other.tagName) -{ - copyChildrenAndAttributesFrom (other); -} - -XmlElement& XmlElement::operator= (const XmlElement& other) -{ - if (this != &other) - { - removeAllAttributes(); - deleteAllChildElements(); - tagName = other.tagName; - copyChildrenAndAttributesFrom (other); - } - - return *this; -} - -#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS -XmlElement::XmlElement (XmlElement&& other) noexcept - : nextListItem (static_cast&&> (other.nextListItem)), - firstChildElement (static_cast&&> (other.firstChildElement)), - attributes (static_cast&&> (other.attributes)), - tagName (static_cast (other.tagName)) -{ -} - -XmlElement& XmlElement::operator= (XmlElement&& other) noexcept -{ - jassert (this != &other); // hopefully the compiler should make this situation impossible! - - removeAllAttributes(); - deleteAllChildElements(); - - nextListItem = static_cast&&> (other.nextListItem); - firstChildElement = static_cast&&> (other.firstChildElement); - attributes = static_cast&&> (other.attributes); - tagName = static_cast (other.tagName); - - return *this; -} -#endif - -void XmlElement::copyChildrenAndAttributesFrom (const XmlElement& other) -{ - jassert (firstChildElement.get() == nullptr); - firstChildElement.addCopyOfList (other.firstChildElement); - - jassert (attributes.get() == nullptr); - attributes.addCopyOfList (other.attributes); -} - -XmlElement::~XmlElement() noexcept -{ - firstChildElement.deleteAll(); - attributes.deleteAll(); -} - -//============================================================================== -namespace XmlOutputFunctions -{ - #if 0 // (These functions are just used to generate the lookup table used below) - bool isLegalXmlCharSlow (const juce_wchar character) noexcept - { - if ((character >= 'a' && character <= 'z') - || (character >= 'A' && character <= 'Z') - || (character >= '0' && character <= '9')) - return true; - - const char* t = " .,;:-()_+=?!'#@[]/\\*%~{}$|"; - - do - { - if (((juce_wchar) (uint8) *t) == character) - return true; - } - while (*++t != 0); - - return false; - } - - void generateLegalCharLookupTable() - { - uint8 n[32] = { 0 }; - for (int i = 0; i < 256; ++i) - if (isLegalXmlCharSlow (i)) - n[i >> 3] |= (1 << (i & 7)); - - String s; - for (int i = 0; i < 32; ++i) - s << (int) n[i] << ", "; - - DBG (s); - } - #endif - - static bool isLegalXmlChar (const uint32 c) noexcept - { - static const unsigned char legalChars[] = { 0, 0, 0, 0, 187, 255, 255, 175, 255, - 255, 255, 191, 254, 255, 255, 127 }; - return c < sizeof (legalChars) * 8 - && (legalChars [c >> 3] & (1 << (c & 7))) != 0; - } - - static void escapeIllegalXmlChars (OutputStream& outputStream, const String& text, const bool changeNewLines) - { - String::CharPointerType t (text.getCharPointer()); - - for (;;) - { - const uint32 character = (uint32) t.getAndAdvance(); - - if (character == 0) - break; - - if (isLegalXmlChar (character)) - { - outputStream << (char) character; - } - else - { - switch (character) - { - case '&': outputStream << "&"; break; - case '"': outputStream << """; break; - case '>': outputStream << ">"; break; - case '<': outputStream << "<"; break; - - case '\n': - case '\r': - if (! changeNewLines) - { - outputStream << (char) character; - break; - } - // Note: deliberate fall-through here! - default: - outputStream << "&#" << ((int) character) << ';'; - break; - } - } - } - } - - static void writeSpaces (OutputStream& out, const size_t numSpaces) - { - out.writeRepeatedByte (' ', numSpaces); - } -} - -void XmlElement::writeElementAsText (OutputStream& outputStream, - const int indentationLevel, - const int lineWrapLength) const -{ - using namespace XmlOutputFunctions; - - if (indentationLevel >= 0) - writeSpaces (outputStream, (size_t) indentationLevel); - - if (! isTextElement()) - { - outputStream.writeByte ('<'); - outputStream << tagName; - - { - const size_t attIndent = (size_t) (indentationLevel + tagName.length() + 1); - int lineLen = 0; - - for (const XmlAttributeNode* att = attributes; att != nullptr; att = att->nextListItem) - { - if (lineLen > lineWrapLength && indentationLevel >= 0) - { - outputStream << newLine; - writeSpaces (outputStream, attIndent); - lineLen = 0; - } - - const int64 startPos = outputStream.getPosition(); - outputStream.writeByte (' '); - outputStream << att->name; - outputStream.write ("=\"", 2); - escapeIllegalXmlChars (outputStream, att->value, true); - outputStream.writeByte ('"'); - lineLen += (int) (outputStream.getPosition() - startPos); - } - } - - if (firstChildElement != nullptr) - { - outputStream.writeByte ('>'); - - bool lastWasTextNode = false; - - for (XmlElement* child = firstChildElement; child != nullptr; child = child->nextListItem) - { - if (child->isTextElement()) - { - escapeIllegalXmlChars (outputStream, child->getText(), false); - lastWasTextNode = true; - } - else - { - if (indentationLevel >= 0 && ! lastWasTextNode) - outputStream << newLine; - - child->writeElementAsText (outputStream, - lastWasTextNode ? 0 : (indentationLevel + (indentationLevel >= 0 ? 2 : 0)), lineWrapLength); - lastWasTextNode = false; - } - } - - if (indentationLevel >= 0 && ! lastWasTextNode) - { - outputStream << newLine; - writeSpaces (outputStream, (size_t) indentationLevel); - } - - outputStream.write ("'); - } - else - { - outputStream.write ("/>", 2); - } - } - else - { - escapeIllegalXmlChars (outputStream, getText(), false); - } -} - -String XmlElement::createDocument (StringRef dtdToUse, - const bool allOnOneLine, - const bool includeXmlHeader, - StringRef encodingType, - const int lineWrapLength) const -{ - MemoryOutputStream mem (2048); - writeToStream (mem, dtdToUse, allOnOneLine, includeXmlHeader, encodingType, lineWrapLength); - - return mem.toUTF8(); -} - -void XmlElement::writeToStream (OutputStream& output, - StringRef dtdToUse, - const bool allOnOneLine, - const bool includeXmlHeader, - StringRef encodingType, - const int lineWrapLength) const -{ - using namespace XmlOutputFunctions; - - if (includeXmlHeader) - { - output << ""; - - if (allOnOneLine) - output.writeByte (' '); - else - output << newLine << newLine; - } - - if (dtdToUse.isNotEmpty()) - { - output << dtdToUse; - - if (allOnOneLine) - output.writeByte (' '); - else - output << newLine; - } - - writeElementAsText (output, allOnOneLine ? -1 : 0, lineWrapLength); - - if (! allOnOneLine) - output << newLine; -} - -bool XmlElement::writeToFile (const File& file, - StringRef dtdToUse, - StringRef encodingType, - const int lineWrapLength) const -{ - TemporaryFile tempFile (file); - - { - FileOutputStream out (tempFile.getFile()); - - if (! out.openedOk()) - return false; - - writeToStream (out, dtdToUse, false, true, encodingType, lineWrapLength); - } - - return tempFile.overwriteTargetFileWithTemporary(); -} - -//============================================================================== -bool XmlElement::hasTagName (StringRef possibleTagName) const noexcept -{ - const bool matches = tagName.equalsIgnoreCase (possibleTagName); - - // XML tags should be case-sensitive, so although this method allows a - // case-insensitive match to pass, you should try to avoid this. - jassert ((! matches) || tagName == possibleTagName); - - return matches; -} - -String XmlElement::getNamespace() const -{ - return tagName.upToFirstOccurrenceOf (":", false, false); -} - -String XmlElement::getTagNameWithoutNamespace() const -{ - return tagName.fromLastOccurrenceOf (":", false, false); -} - -bool XmlElement::hasTagNameIgnoringNamespace (StringRef possibleTagName) const -{ - return hasTagName (possibleTagName) || getTagNameWithoutNamespace() == possibleTagName; -} - -XmlElement* XmlElement::getNextElementWithTagName (StringRef requiredTagName) const -{ - XmlElement* e = nextListItem; - - while (e != nullptr && ! e->hasTagName (requiredTagName)) - e = e->nextListItem; - - return e; -} - -//============================================================================== -int XmlElement::getNumAttributes() const noexcept -{ - return attributes.size(); -} - -const String& XmlElement::getAttributeName (const int index) const noexcept -{ - if (const XmlAttributeNode* const att = attributes [index]) - return att->name.toString(); - - return String::empty; -} - -const String& XmlElement::getAttributeValue (const int index) const noexcept -{ - if (const XmlAttributeNode* const att = attributes [index]) - return att->value; - - return String::empty; -} - -XmlElement::XmlAttributeNode* XmlElement::getAttribute (StringRef attributeName) const noexcept -{ - for (XmlAttributeNode* att = attributes; att != nullptr; att = att->nextListItem) - if (att->name == attributeName) - return att; - - return nullptr; -} - -bool XmlElement::hasAttribute (StringRef attributeName) const noexcept -{ - return getAttribute (attributeName) != nullptr; -} - -//============================================================================== -const String& XmlElement::getStringAttribute (StringRef attributeName) const noexcept -{ - if (const XmlAttributeNode* att = getAttribute (attributeName)) - return att->value; - - return String::empty; -} - -String XmlElement::getStringAttribute (StringRef attributeName, const String& defaultReturnValue) const -{ - if (const XmlAttributeNode* att = getAttribute (attributeName)) - return att->value; - - return defaultReturnValue; -} - -int XmlElement::getIntAttribute (StringRef attributeName, const int defaultReturnValue) const -{ - if (const XmlAttributeNode* att = getAttribute (attributeName)) - return att->value.getIntValue(); - - return defaultReturnValue; -} - -double XmlElement::getDoubleAttribute (StringRef attributeName, const double defaultReturnValue) const -{ - if (const XmlAttributeNode* att = getAttribute (attributeName)) - return att->value.getDoubleValue(); - - return defaultReturnValue; -} - -bool XmlElement::getBoolAttribute (StringRef attributeName, const bool defaultReturnValue) const -{ - if (const XmlAttributeNode* att = getAttribute (attributeName)) - { - const juce_wchar firstChar = *(att->value.getCharPointer().findEndOfWhitespace()); - - return firstChar == '1' - || firstChar == 't' - || firstChar == 'y' - || firstChar == 'T' - || firstChar == 'Y'; - } - - return defaultReturnValue; -} - -bool XmlElement::compareAttribute (StringRef attributeName, - StringRef stringToCompareAgainst, - const bool ignoreCase) const noexcept -{ - if (const XmlAttributeNode* att = getAttribute (attributeName)) - return ignoreCase ? att->value.equalsIgnoreCase (stringToCompareAgainst) - : att->value == stringToCompareAgainst; - - return false; -} - -//============================================================================== -void XmlElement::setAttribute (const Identifier& attributeName, const String& value) -{ - if (attributes == nullptr) - { - attributes = new XmlAttributeNode (attributeName, value); - } - else - { - for (XmlAttributeNode* att = attributes; ; att = att->nextListItem) - { - if (att->name == attributeName) - { - att->value = value; - break; - } - - if (att->nextListItem == nullptr) - { - att->nextListItem = new XmlAttributeNode (attributeName, value); - break; - } - } - } -} - -void XmlElement::setAttribute (const Identifier& attributeName, const int number) -{ - setAttribute (attributeName, String (number)); -} - -void XmlElement::setAttribute (const Identifier& attributeName, const double number) -{ - setAttribute (attributeName, String (number, 20)); -} - -void XmlElement::removeAttribute (const Identifier& attributeName) noexcept -{ - for (LinkedListPointer* att = &attributes; - att->get() != nullptr; - att = &(att->get()->nextListItem)) - { - if (att->get()->name == attributeName) - { - delete att->removeNext(); - break; - } - } -} - -void XmlElement::removeAllAttributes() noexcept -{ - attributes.deleteAll(); -} - -//============================================================================== -int XmlElement::getNumChildElements() const noexcept -{ - return firstChildElement.size(); -} - -XmlElement* XmlElement::getChildElement (const int index) const noexcept -{ - return firstChildElement [index].get(); -} - -XmlElement* XmlElement::getChildByName (StringRef childName) const noexcept -{ - jassert (! childName.isEmpty()); - - for (XmlElement* child = firstChildElement; child != nullptr; child = child->nextListItem) - if (child->hasTagName (childName)) - return child; - - return nullptr; -} - -XmlElement* XmlElement::getChildByAttribute (StringRef attributeName, StringRef attributeValue) const noexcept -{ - jassert (! attributeName.isEmpty()); - - for (XmlElement* child = firstChildElement; child != nullptr; child = child->nextListItem) - if (child->compareAttribute (attributeName, attributeValue)) - return child; - - return nullptr; -} - -void XmlElement::addChildElement (XmlElement* const newNode) noexcept -{ - if (newNode != nullptr) - { - // The element being added must not be a child of another node! - jassert (newNode->nextListItem == nullptr); - - firstChildElement.append (newNode); - } -} - -void XmlElement::insertChildElement (XmlElement* const newNode, int indexToInsertAt) noexcept -{ - if (newNode != nullptr) - { - // The element being added must not be a child of another node! - jassert (newNode->nextListItem == nullptr); - - firstChildElement.insertAtIndex (indexToInsertAt, newNode); - } -} - -void XmlElement::prependChildElement (XmlElement* newNode) noexcept -{ - if (newNode != nullptr) - { - // The element being added must not be a child of another node! - jassert (newNode->nextListItem == nullptr); - - firstChildElement.insertNext (newNode); - } -} - -XmlElement* XmlElement::createNewChildElement (StringRef childTagName) -{ - XmlElement* const newElement = new XmlElement (childTagName); - addChildElement (newElement); - return newElement; -} - -bool XmlElement::replaceChildElement (XmlElement* const currentChildElement, - XmlElement* const newNode) noexcept -{ - if (newNode != nullptr) - { - if (LinkedListPointer* const p = firstChildElement.findPointerTo (currentChildElement)) - { - if (currentChildElement != newNode) - delete p->replaceNext (newNode); - - return true; - } - } - - return false; -} - -void XmlElement::removeChildElement (XmlElement* const childToRemove, - const bool shouldDeleteTheChild) noexcept -{ - if (childToRemove != nullptr) - { - firstChildElement.remove (childToRemove); - - if (shouldDeleteTheChild) - delete childToRemove; - } -} - -bool XmlElement::isEquivalentTo (const XmlElement* const other, - const bool ignoreOrderOfAttributes) const noexcept -{ - if (this != other) - { - if (other == nullptr || tagName != other->tagName) - return false; - - if (ignoreOrderOfAttributes) - { - int totalAtts = 0; - - for (const XmlAttributeNode* att = attributes; att != nullptr; att = att->nextListItem) - { - if (! other->compareAttribute (att->name, att->value)) - return false; - - ++totalAtts; - } - - if (totalAtts != other->getNumAttributes()) - return false; - } - else - { - const XmlAttributeNode* thisAtt = attributes; - const XmlAttributeNode* otherAtt = other->attributes; - - for (;;) - { - if (thisAtt == nullptr || otherAtt == nullptr) - { - if (thisAtt == otherAtt) // both nullptr, so it's a match - break; - - return false; - } - - if (thisAtt->name != otherAtt->name - || thisAtt->value != otherAtt->value) - { - return false; - } - - thisAtt = thisAtt->nextListItem; - otherAtt = otherAtt->nextListItem; - } - } - - const XmlElement* thisChild = firstChildElement; - const XmlElement* otherChild = other->firstChildElement; - - for (;;) - { - if (thisChild == nullptr || otherChild == nullptr) - { - if (thisChild == otherChild) // both 0, so it's a match - break; - - return false; - } - - if (! thisChild->isEquivalentTo (otherChild, ignoreOrderOfAttributes)) - return false; - - thisChild = thisChild->nextListItem; - otherChild = otherChild->nextListItem; - } - } - - return true; -} - -void XmlElement::deleteAllChildElements() noexcept -{ - firstChildElement.deleteAll(); -} - -void XmlElement::deleteAllChildElementsWithTagName (StringRef name) noexcept -{ - for (XmlElement* child = firstChildElement; child != nullptr;) - { - XmlElement* const nextChild = child->nextListItem; - - if (child->hasTagName (name)) - removeChildElement (child, true); - - child = nextChild; - } -} - -bool XmlElement::containsChildElement (const XmlElement* const possibleChild) const noexcept -{ - return firstChildElement.contains (possibleChild); -} - -XmlElement* XmlElement::findParentElementOf (const XmlElement* const elementToLookFor) noexcept -{ - if (this == elementToLookFor || elementToLookFor == nullptr) - return nullptr; - - for (XmlElement* child = firstChildElement; child != nullptr; child = child->nextListItem) - { - if (elementToLookFor == child) - return this; - - if (XmlElement* const found = child->findParentElementOf (elementToLookFor)) - return found; - } - - return nullptr; -} - -void XmlElement::getChildElementsAsArray (XmlElement** elems) const noexcept -{ - firstChildElement.copyToArray (elems); -} - -void XmlElement::reorderChildElements (XmlElement** const elems, const int num) noexcept -{ - XmlElement* e = firstChildElement = elems[0]; - - for (int i = 1; i < num; ++i) - { - e->nextListItem = elems[i]; - e = e->nextListItem; - } - - e->nextListItem = nullptr; -} - -//============================================================================== -bool XmlElement::isTextElement() const noexcept -{ - return tagName.isEmpty(); -} - -static const String juce_xmltextContentAttributeName ("text"); - -const String& XmlElement::getText() const noexcept -{ - jassert (isTextElement()); // you're trying to get the text from an element that - // isn't actually a text element.. If this contains text sub-nodes, you - // probably want to use getAllSubText instead. - - return getStringAttribute (juce_xmltextContentAttributeName); -} - -void XmlElement::setText (const String& newText) -{ - if (isTextElement()) - setAttribute (juce_xmltextContentAttributeName, newText); - else - jassertfalse; // you can only change the text in a text element, not a normal one. -} - -String XmlElement::getAllSubText() const -{ - if (isTextElement()) - return getText(); - - if (getNumChildElements() == 1) - return firstChildElement.get()->getAllSubText(); - - MemoryOutputStream mem (1024); - - for (const XmlElement* child = firstChildElement; child != nullptr; child = child->nextListItem) - mem << child->getAllSubText(); - - return mem.toUTF8(); -} - -String XmlElement::getChildElementAllSubText (StringRef childTagName, const String& defaultReturnValue) const -{ - if (const XmlElement* const child = getChildByName (childTagName)) - return child->getAllSubText(); - - return defaultReturnValue; -} - -XmlElement* XmlElement::createTextElement (const String& text) -{ - XmlElement* const e = new XmlElement ((int) 0); - e->setAttribute (juce_xmltextContentAttributeName, text); - return e; -} - -void XmlElement::addTextElement (const String& text) -{ - addChildElement (createTextElement (text)); -} - -void XmlElement::deleteAllTextElements() noexcept -{ - for (XmlElement* child = firstChildElement; child != nullptr;) - { - XmlElement* const next = child->nextListItem; - - if (child->isTextElement()) - removeChildElement (child, true); - - child = next; - } -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/xml/juce_XmlElement.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/xml/juce_XmlElement.h deleted file mode 100644 index 2f03e93aa6..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/xml/juce_XmlElement.h +++ /dev/null @@ -1,770 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_XMLELEMENT_H_INCLUDED -#define JUCE_XMLELEMENT_H_INCLUDED - - -//============================================================================== -/** A handy macro to make it easy to iterate all the child elements in an XmlElement. - - The parentXmlElement should be a reference to the parent XML, and the childElementVariableName - will be the name of a pointer to each child element. - - E.g. @code - XmlElement* myParentXml = createSomeKindOfXmlDocument(); - - forEachXmlChildElement (*myParentXml, child) - { - if (child->hasTagName ("FOO")) - doSomethingWithXmlElement (child); - } - - @endcode - - @see forEachXmlChildElementWithTagName -*/ -#define forEachXmlChildElement(parentXmlElement, childElementVariableName) \ -\ - for (juce::XmlElement* childElementVariableName = (parentXmlElement).getFirstChildElement(); \ - childElementVariableName != nullptr; \ - childElementVariableName = childElementVariableName->getNextElement()) - -/** A macro that makes it easy to iterate all the child elements of an XmlElement - which have a specified tag. - - This does the same job as the forEachXmlChildElement macro, but only for those - elements that have a particular tag name. - - The parentXmlElement should be a reference to the parent XML, and the childElementVariableName - will be the name of a pointer to each child element. The requiredTagName is the - tag name to match. - - E.g. @code - XmlElement* myParentXml = createSomeKindOfXmlDocument(); - - forEachXmlChildElementWithTagName (*myParentXml, child, "MYTAG") - { - // the child object is now guaranteed to be a element.. - doSomethingWithMYTAGElement (child); - } - - @endcode - - @see forEachXmlChildElement -*/ -#define forEachXmlChildElementWithTagName(parentXmlElement, childElementVariableName, requiredTagName) \ -\ - for (juce::XmlElement* childElementVariableName = (parentXmlElement).getChildByName (requiredTagName); \ - childElementVariableName != nullptr; \ - childElementVariableName = childElementVariableName->getNextElementWithTagName (requiredTagName)) - - -//============================================================================== -/** Used to build a tree of elements representing an XML document. - - An XML document can be parsed into a tree of XmlElements, each of which - represents an XML tag structure, and which may itself contain other - nested elements. - - An XmlElement can also be converted back into a text document, and has - lots of useful methods for manipulating its attributes and sub-elements, - so XmlElements can actually be used as a handy general-purpose data - structure. - - Here's an example of parsing some elements: @code - // check we're looking at the right kind of document.. - if (myElement->hasTagName ("ANIMALS")) - { - // now we'll iterate its sub-elements looking for 'giraffe' elements.. - forEachXmlChildElement (*myElement, e) - { - if (e->hasTagName ("GIRAFFE")) - { - // found a giraffe, so use some of its attributes.. - - String giraffeName = e->getStringAttribute ("name"); - int giraffeAge = e->getIntAttribute ("age"); - bool isFriendly = e->getBoolAttribute ("friendly"); - } - } - } - @endcode - - And here's an example of how to create an XML document from scratch: @code - // create an outer node called "ANIMALS" - XmlElement animalsList ("ANIMALS"); - - for (int i = 0; i < numAnimals; ++i) - { - // create an inner element.. - XmlElement* giraffe = new XmlElement ("GIRAFFE"); - - giraffe->setAttribute ("name", "nigel"); - giraffe->setAttribute ("age", 10); - giraffe->setAttribute ("friendly", true); - - // ..and add our new element to the parent node - animalsList.addChildElement (giraffe); - } - - // now we can turn the whole thing into a text document.. - String myXmlDoc = animalsList.createDocument (String::empty); - @endcode - - @see XmlDocument -*/ -class JUCE_API XmlElement -{ -public: - //============================================================================== - /** Creates an XmlElement with this tag name. */ - explicit XmlElement (const String& tagName); - - /** Creates an XmlElement with this tag name. */ - explicit XmlElement (const char* tagName); - - /** Creates an XmlElement with this tag name. */ - explicit XmlElement (const Identifier& tagName); - - /** Creates an XmlElement with this tag name. */ - explicit XmlElement (StringRef tagName); - - /** Creates an XmlElement with this tag name. */ - XmlElement (String::CharPointerType tagNameBegin, String::CharPointerType tagNameEnd); - - /** Creates a (deep) copy of another element. */ - XmlElement (const XmlElement&); - - /** Creates a (deep) copy of another element. */ - XmlElement& operator= (const XmlElement&); - - #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS - XmlElement (XmlElement&&) noexcept; - XmlElement& operator= (XmlElement&&) noexcept; - #endif - - /** Deleting an XmlElement will also delete all of its child elements. */ - ~XmlElement() noexcept; - - //============================================================================== - /** Compares two XmlElements to see if they contain the same text and attiributes. - - The elements are only considered equivalent if they contain the same attiributes - with the same values, and have the same sub-nodes. - - @param other the other element to compare to - @param ignoreOrderOfAttributes if true, this means that two elements with the - same attributes in a different order will be - considered the same; if false, the attributes must - be in the same order as well - */ - bool isEquivalentTo (const XmlElement* other, - bool ignoreOrderOfAttributes) const noexcept; - - //============================================================================== - /** Returns an XML text document that represents this element. - - The string returned can be parsed to recreate the same XmlElement that - was used to create it. - - @param dtdToUse the DTD to add to the document - @param allOnOneLine if true, this means that the document will not contain any - linefeeds, so it'll be smaller but not very easy to read. - @param includeXmlHeader whether to add the ", this would return "MOOSE". - @see hasTagName - */ - const String& getTagName() const noexcept { return tagName; } - - /** Returns the namespace portion of the tag-name, or an empty string if none is specified. */ - String getNamespace() const; - - /** Returns the part of the tag-name that follows any namespace declaration. */ - String getTagNameWithoutNamespace() const; - - /** Tests whether this element has a particular tag name. - @param possibleTagName the tag name you're comparing it with - @see getTagName - */ - bool hasTagName (StringRef possibleTagName) const noexcept; - - /** Tests whether this element has a particular tag name, ignoring any XML namespace prefix. - So a test for e.g. "xyz" will return true for "xyz" and also "foo:xyz", "bar::xyz", etc. - @see getTagName - */ - bool hasTagNameIgnoringNamespace (StringRef possibleTagName) const; - - //============================================================================== - /** Returns the number of XML attributes this element contains. - - E.g. for an element such as \, this would - return 2. - */ - int getNumAttributes() const noexcept; - - /** Returns the name of one of the elements attributes. - - E.g. for an element such as \, then - getAttributeName(1) would return "antlers". - - @see getAttributeValue, getStringAttribute - */ - const String& getAttributeName (int attributeIndex) const noexcept; - - /** Returns the value of one of the elements attributes. - - E.g. for an element such as \, then - getAttributeName(1) would return "2". - - @see getAttributeName, getStringAttribute - */ - const String& getAttributeValue (int attributeIndex) const noexcept; - - //============================================================================== - // Attribute-handling methods.. - - /** Checks whether the element contains an attribute with a certain name. */ - bool hasAttribute (StringRef attributeName) const noexcept; - - /** Returns the value of a named attribute. - @param attributeName the name of the attribute to look up - */ - const String& getStringAttribute (StringRef attributeName) const noexcept; - - /** Returns the value of a named attribute. - @param attributeName the name of the attribute to look up - @param defaultReturnValue a value to return if the element doesn't have an attribute - with this name - */ - String getStringAttribute (StringRef attributeName, const String& defaultReturnValue) const; - - /** Compares the value of a named attribute with a value passed-in. - - @param attributeName the name of the attribute to look up - @param stringToCompareAgainst the value to compare it with - @param ignoreCase whether the comparison should be case-insensitive - @returns true if the value of the attribute is the same as the string passed-in; - false if it's different (or if no such attribute exists) - */ - bool compareAttribute (StringRef attributeName, - StringRef stringToCompareAgainst, - bool ignoreCase = false) const noexcept; - - /** Returns the value of a named attribute as an integer. - - This will try to find the attribute and convert it to an integer (using - the String::getIntValue() method). - - @param attributeName the name of the attribute to look up - @param defaultReturnValue a value to return if the element doesn't have an attribute - with this name - @see setAttribute - */ - int getIntAttribute (StringRef attributeName, int defaultReturnValue = 0) const; - - /** Returns the value of a named attribute as floating-point. - - This will try to find the attribute and convert it to an integer (using - the String::getDoubleValue() method). - - @param attributeName the name of the attribute to look up - @param defaultReturnValue a value to return if the element doesn't have an attribute - with this name - @see setAttribute - */ - double getDoubleAttribute (StringRef attributeName, double defaultReturnValue = 0.0) const; - - /** Returns the value of a named attribute as a boolean. - - This will try to find the attribute and interpret it as a boolean. To do this, - it'll return true if the value is "1", "true", "y", etc, or false for other - values. - - @param attributeName the name of the attribute to look up - @param defaultReturnValue a value to return if the element doesn't have an attribute - with this name - */ - bool getBoolAttribute (StringRef attributeName, bool defaultReturnValue = false) const; - - /** Adds a named attribute to the element. - - If the element already contains an attribute with this name, it's value will - be updated to the new value. If there's no such attribute yet, a new one will - be added. - - Note that there are other setAttribute() methods that take integers, - doubles, etc. to make it easy to store numbers. - - @param attributeName the name of the attribute to set - @param newValue the value to set it to - @see removeAttribute - */ - void setAttribute (const Identifier& attributeName, const String& newValue); - - /** Adds a named attribute to the element, setting it to an integer value. - - If the element already contains an attribute with this name, it's value will - be updated to the new value. If there's no such attribute yet, a new one will - be added. - - Note that there are other setAttribute() methods that take integers, - doubles, etc. to make it easy to store numbers. - - @param attributeName the name of the attribute to set - @param newValue the value to set it to - */ - void setAttribute (const Identifier& attributeName, int newValue); - - /** Adds a named attribute to the element, setting it to a floating-point value. - - If the element already contains an attribute with this name, it's value will - be updated to the new value. If there's no such attribute yet, a new one will - be added. - - Note that there are other setAttribute() methods that take integers, - doubles, etc. to make it easy to store numbers. - - @param attributeName the name of the attribute to set - @param newValue the value to set it to - */ - void setAttribute (const Identifier& attributeName, double newValue); - - /** Removes a named attribute from the element. - - @param attributeName the name of the attribute to remove - @see removeAllAttributes - */ - void removeAttribute (const Identifier& attributeName) noexcept; - - /** Removes all attributes from this element. */ - void removeAllAttributes() noexcept; - - //============================================================================== - // Child element methods.. - - /** Returns the first of this element's sub-elements. - see getNextElement() for an example of how to iterate the sub-elements. - @see forEachXmlChildElement - */ - XmlElement* getFirstChildElement() const noexcept { return firstChildElement; } - - /** Returns the next of this element's siblings. - - This can be used for iterating an element's sub-elements, e.g. - @code - XmlElement* child = myXmlDocument->getFirstChildElement(); - - while (child != nullptr) - { - ...do stuff with this child.. - - child = child->getNextElement(); - } - @endcode - - Note that when iterating the child elements, some of them might be - text elements as well as XML tags - use isTextElement() to work this - out. - - Also, it's much easier and neater to use this method indirectly via the - forEachXmlChildElement macro. - - @returns the sibling element that follows this one, or zero if this is the last - element in its parent - - @see getNextElement, isTextElement, forEachXmlChildElement - */ - inline XmlElement* getNextElement() const noexcept { return nextListItem; } - - /** Returns the next of this element's siblings which has the specified tag - name. - - This is like getNextElement(), but will scan through the list until it - finds an element with the given tag name. - - @see getNextElement, forEachXmlChildElementWithTagName - */ - XmlElement* getNextElementWithTagName (StringRef requiredTagName) const; - - /** Returns the number of sub-elements in this element. - @see getChildElement - */ - int getNumChildElements() const noexcept; - - /** Returns the sub-element at a certain index. - - It's not very efficient to iterate the sub-elements by index - see - getNextElement() for an example of how best to iterate. - - @returns the n'th child of this element, or nullptr if the index is out-of-range - @see getNextElement, isTextElement, getChildByName - */ - XmlElement* getChildElement (int index) const noexcept; - - /** Returns the first sub-element with a given tag-name. - - @param tagNameToLookFor the tag name of the element you want to find - @returns the first element with this tag name, or nullptr if none is found - @see getNextElement, isTextElement, getChildElement, getChildByAttribute - */ - XmlElement* getChildByName (StringRef tagNameToLookFor) const noexcept; - - /** Returns the first sub-element which has an attribute that matches the given value. - - @param attributeName the name of the attribute to check - @param attributeValue the target value of the attribute - @returns the first element with this attribute value, or nullptr if none is found - @see getChildByName - */ - XmlElement* getChildByAttribute (StringRef attributeName, - StringRef attributeValue) const noexcept; - - //============================================================================== - /** Appends an element to this element's list of children. - - Child elements are deleted automatically when their parent is deleted, so - make sure the object that you pass in will not be deleted by anything else, - and make sure it's not already the child of another element. - - Note that due to the XmlElement using a singly-linked-list, prependChildElement() - is an O(1) operation, but addChildElement() is an O(N) operation - so if - you're adding large number of elements, you may prefer to do so in reverse order! - - @see getFirstChildElement, getNextElement, getNumChildElements, - getChildElement, removeChildElement - */ - void addChildElement (XmlElement* newChildElement) noexcept; - - /** Inserts an element into this element's list of children. - - Child elements are deleted automatically when their parent is deleted, so - make sure the object that you pass in will not be deleted by anything else, - and make sure it's not already the child of another element. - - @param newChildElement the element to add - @param indexToInsertAt the index at which to insert the new element - if this is - below zero, it will be added to the end of the list - @see addChildElement, insertChildElement - */ - void insertChildElement (XmlElement* newChildElement, - int indexToInsertAt) noexcept; - - /** Inserts an element at the beginning of this element's list of children. - - Child elements are deleted automatically when their parent is deleted, so - make sure the object that you pass in will not be deleted by anything else, - and make sure it's not already the child of another element. - - Note that due to the XmlElement using a singly-linked-list, prependChildElement() - is an O(1) operation, but addChildElement() is an O(N) operation - so if - you're adding large number of elements, you may prefer to do so in reverse order! - - @see addChildElement, insertChildElement - */ - void prependChildElement (XmlElement* newChildElement) noexcept; - - /** Creates a new element with the given name and returns it, after adding it - as a child element. - - This is a handy method that means that instead of writing this: - @code - XmlElement* newElement = new XmlElement ("foobar"); - myParentElement->addChildElement (newElement); - @endcode - - ..you could just write this: - @code - XmlElement* newElement = myParentElement->createNewChildElement ("foobar"); - @endcode - */ - XmlElement* createNewChildElement (StringRef tagName); - - /** Replaces one of this element's children with another node. - - If the current element passed-in isn't actually a child of this element, - this will return false and the new one won't be added. Otherwise, the - existing element will be deleted, replaced with the new one, and it - will return true. - */ - bool replaceChildElement (XmlElement* currentChildElement, - XmlElement* newChildNode) noexcept; - - /** Removes a child element. - - @param childToRemove the child to look for and remove - @param shouldDeleteTheChild if true, the child will be deleted, if false it'll - just remove it - */ - void removeChildElement (XmlElement* childToRemove, - bool shouldDeleteTheChild) noexcept; - - /** Deletes all the child elements in the element. - @see removeChildElement, deleteAllChildElementsWithTagName - */ - void deleteAllChildElements() noexcept; - - /** Deletes all the child elements with a given tag name. - @see removeChildElement - */ - void deleteAllChildElementsWithTagName (StringRef tagName) noexcept; - - /** Returns true if the given element is a child of this one. */ - bool containsChildElement (const XmlElement* possibleChild) const noexcept; - - /** Recursively searches all sub-elements of this one, looking for an element - which is the direct parent of the specified element. - - Because elements don't store a pointer to their parent, if you have one - and need to find its parent, the only way to do so is to exhaustively - search the whole tree for it. - - If the given child is found somewhere in this element's hierarchy, then - this method will return its parent. If not, it will return nullptr. - */ - XmlElement* findParentElementOf (const XmlElement* childToSearchFor) noexcept; - - //============================================================================== - /** Sorts the child elements using a comparator. - - This will use a comparator object to sort the elements into order. The object - passed must have a method of the form: - @code - int compareElements (const XmlElement* first, const XmlElement* second); - @endcode - - ..and this method must return: - - a value of < 0 if the first comes before the second - - a value of 0 if the two objects are equivalent - - a value of > 0 if the second comes before the first - - To improve performance, the compareElements() method can be declared as static or const. - - @param comparator the comparator to use for comparing elements. - @param retainOrderOfEquivalentItems if this is true, then items which the comparator - says are equivalent will be kept in the order in which they - currently appear in the array. This is slower to perform, but - may be important in some cases. If it's false, a faster algorithm - is used, but equivalent elements may be rearranged. - */ - template - void sortChildElements (ElementComparator& comparator, - bool retainOrderOfEquivalentItems = false) - { - const int num = getNumChildElements(); - - if (num > 1) - { - HeapBlock elems ((size_t) num); - getChildElementsAsArray (elems); - sortArray (comparator, (XmlElement**) elems, 0, num - 1, retainOrderOfEquivalentItems); - reorderChildElements (elems, num); - } - } - - //============================================================================== - /** Returns true if this element is a section of text. - - Elements can either be an XML tag element or a secton of text, so this - is used to find out what kind of element this one is. - - @see getAllText, addTextElement, deleteAllTextElements - */ - bool isTextElement() const noexcept; - - /** Returns the text for a text element. - - Note that if you have an element like this: - - @codehello@endcode - - then calling getText on the "xyz" element won't return "hello", because that is - actually stored in a special text sub-element inside the xyz element. To get the - "hello" string, you could either call getText on the (unnamed) sub-element, or - use getAllSubText() to do this automatically. - - Note that leading and trailing whitespace will be included in the string - to remove - if, just call String::trim() on the result. - - @see isTextElement, getAllSubText, getChildElementAllSubText - */ - const String& getText() const noexcept; - - /** Sets the text in a text element. - - Note that this is only a valid call if this element is a text element. If it's - not, then no action will be performed. If you're trying to add text inside a normal - element, you probably want to use addTextElement() instead. - */ - void setText (const String& newText); - - /** Returns all the text from this element's child nodes. - - This iterates all the child elements and when it finds text elements, - it concatenates their text into a big string which it returns. - - E.g. @codehello there world@endcode - if you called getAllSubText on the "xyz" element, it'd return "hello there world". - - Note that leading and trailing whitespace will be included in the string - to remove - if, just call String::trim() on the result. - - @see isTextElement, getChildElementAllSubText, getText, addTextElement - */ - String getAllSubText() const; - - /** Returns all the sub-text of a named child element. - - If there is a child element with the given tag name, this will return - all of its sub-text (by calling getAllSubText() on it). If there is - no such child element, this will return the default string passed-in. - - @see getAllSubText - */ - String getChildElementAllSubText (StringRef childTagName, - const String& defaultReturnValue) const; - - /** Appends a section of text to this element. - @see isTextElement, getText, getAllSubText - */ - void addTextElement (const String& text); - - /** Removes all the text elements from this element. - @see isTextElement, getText, getAllSubText, addTextElement - */ - void deleteAllTextElements() noexcept; - - /** Creates a text element that can be added to a parent element. */ - static XmlElement* createTextElement (const String& text); - - //============================================================================== -private: - struct XmlAttributeNode - { - XmlAttributeNode (const XmlAttributeNode&) noexcept; - XmlAttributeNode (const Identifier&, const String&) noexcept; - XmlAttributeNode (String::CharPointerType, String::CharPointerType); - - LinkedListPointer nextListItem; - Identifier name; - String value; - - private: - XmlAttributeNode& operator= (const XmlAttributeNode&) JUCE_DELETED_FUNCTION; - }; - - friend class XmlDocument; - friend class LinkedListPointer; - friend class LinkedListPointer; - friend class LinkedListPointer::Appender; - friend class NamedValueSet; - - LinkedListPointer nextListItem; - LinkedListPointer firstChildElement; - LinkedListPointer attributes; - String tagName; - - XmlElement (int) noexcept; - void copyChildrenAndAttributesFrom (const XmlElement&); - void writeElementAsText (OutputStream&, int indentationLevel, int lineWrapLength) const; - void getChildElementsAsArray (XmlElement**) const noexcept; - void reorderChildElements (XmlElement**, int) noexcept; - XmlAttributeNode* getAttribute (StringRef) const noexcept; - - // Sigh.. L"" or _T("") string literals are problematic in general, and really inappropriate - // for XML tags. Use a UTF-8 encoded literal instead, or if you're really determined to use - // UTF-16, cast it to a String and use the other constructor. - XmlElement (const wchar_t*) JUCE_DELETED_FUNCTION; - - JUCE_LEAK_DETECTOR (XmlElement) -}; - - -#endif // JUCE_XMLELEMENT_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/zip/juce_GZIPCompressorOutputStream.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/zip/juce_GZIPCompressorOutputStream.cpp deleted file mode 100644 index cb9a577eb5..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/zip/juce_GZIPCompressorOutputStream.cpp +++ /dev/null @@ -1,213 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -class GZIPCompressorOutputStream::GZIPCompressorHelper -{ -public: - GZIPCompressorHelper (const int compressionLevel, const int windowBits) - : compLevel ((compressionLevel < 1 || compressionLevel > 9) ? -1 : compressionLevel), - isFirstDeflate (true), - streamIsValid (false), - finished (false) - { - using namespace zlibNamespace; - zerostruct (stream); - - streamIsValid = (deflateInit2 (&stream, compLevel, Z_DEFLATED, - windowBits != 0 ? windowBits : MAX_WBITS, - 8, strategy) == Z_OK); - } - - ~GZIPCompressorHelper() - { - if (streamIsValid) - zlibNamespace::deflateEnd (&stream); - } - - bool write (const uint8* data, size_t dataSize, OutputStream& out) - { - // When you call flush() on a gzip stream, the stream is closed, and you can - // no longer continue to write data to it! - jassert (! finished); - - while (dataSize > 0) - if (! doNextBlock (data, dataSize, out, Z_NO_FLUSH)) - return false; - - return true; - } - - void finish (OutputStream& out) - { - const uint8* data = nullptr; - size_t dataSize = 0; - - while (! finished) - doNextBlock (data, dataSize, out, Z_FINISH); - } - -private: - enum { strategy = 0 }; - - zlibNamespace::z_stream stream; - const int compLevel; - bool isFirstDeflate, streamIsValid, finished; - zlibNamespace::Bytef buffer[32768]; - - bool doNextBlock (const uint8*& data, size_t& dataSize, OutputStream& out, const int flushMode) - { - using namespace zlibNamespace; - - if (streamIsValid) - { - stream.next_in = const_cast (data); - stream.next_out = buffer; - stream.avail_in = (z_uInt) dataSize; - stream.avail_out = (z_uInt) sizeof (buffer); - - const int result = isFirstDeflate ? deflateParams (&stream, compLevel, strategy) - : deflate (&stream, flushMode); - isFirstDeflate = false; - - switch (result) - { - case Z_STREAM_END: - finished = true; - // Deliberate fall-through.. - case Z_OK: - { - data += dataSize - stream.avail_in; - dataSize = stream.avail_in; - const ssize_t bytesDone = (ssize_t) sizeof (buffer) - (ssize_t) stream.avail_out; - return bytesDone <= 0 || out.write (buffer, (size_t) bytesDone); - } - - default: - break; - } - } - - return false; - } - - JUCE_DECLARE_NON_COPYABLE (GZIPCompressorHelper) -}; - -//============================================================================== -GZIPCompressorOutputStream::GZIPCompressorOutputStream (OutputStream* const out, - const int compressionLevel, - const bool deleteDestStream, - const int windowBits) - : destStream (out, deleteDestStream), - helper (new GZIPCompressorHelper (compressionLevel, windowBits)) -{ - jassert (out != nullptr); -} - -GZIPCompressorOutputStream::~GZIPCompressorOutputStream() -{ - flush(); -} - -void GZIPCompressorOutputStream::flush() -{ - helper->finish (*destStream); - destStream->flush(); -} - -bool GZIPCompressorOutputStream::write (const void* destBuffer, size_t howMany) -{ - jassert (destBuffer != nullptr && (ssize_t) howMany >= 0); - - return helper->write (static_cast (destBuffer), howMany, *destStream); -} - -int64 GZIPCompressorOutputStream::getPosition() -{ - return destStream->getPosition(); -} - -bool GZIPCompressorOutputStream::setPosition (int64 /*newPosition*/) -{ - jassertfalse; // can't do it! - return false; -} - -//============================================================================== -#if JUCE_UNIT_TESTS - -class GZIPTests : public UnitTest -{ -public: - GZIPTests() : UnitTest ("GZIP") {} - - void runTest() - { - beginTest ("GZIP"); - Random rng = getRandom(); - - for (int i = 100; --i >= 0;) - { - MemoryOutputStream original, compressed, uncompressed; - - { - GZIPCompressorOutputStream zipper (&compressed, rng.nextInt (10), false); - - for (int j = rng.nextInt (100); --j >= 0;) - { - MemoryBlock data ((unsigned int) (rng.nextInt (2000) + 1)); - - for (int k = (int) data.getSize(); --k >= 0;) - data[k] = (char) rng.nextInt (255); - - original << data; - zipper << data; - } - } - - { - MemoryInputStream compressedInput (compressed.getData(), compressed.getDataSize(), false); - GZIPDecompressorInputStream unzipper (compressedInput); - - uncompressed << unzipper; - } - - expectEquals ((int) uncompressed.getDataSize(), - (int) original.getDataSize()); - - if (original.getDataSize() == uncompressed.getDataSize()) - expect (memcmp (uncompressed.getData(), - original.getData(), - original.getDataSize()) == 0); - } - } -}; - -static GZIPTests gzipTests; - -#endif diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/zip/juce_GZIPCompressorOutputStream.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/zip/juce_GZIPCompressorOutputStream.h deleted file mode 100644 index 3309486a05..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/zip/juce_GZIPCompressorOutputStream.h +++ /dev/null @@ -1,101 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_GZIPCOMPRESSOROUTPUTSTREAM_H_INCLUDED -#define JUCE_GZIPCOMPRESSOROUTPUTSTREAM_H_INCLUDED - - -//============================================================================== -/** - A stream which uses zlib to compress the data written into it. - - Important note: When you call flush() on a GZIPCompressorOutputStream, - the gzip data is closed - this means that no more data can be written to - it, and any subsequent attempts to call write() will cause an assertion. - - @see GZIPDecompressorInputStream -*/ -class JUCE_API GZIPCompressorOutputStream : public OutputStream -{ -public: - //============================================================================== - /** Creates a compression stream. - - @param destStream the stream into which the compressed data should - be written - @param compressionLevel how much to compress the data, between 1 and 9, where - 1 is the fastest/lowest compression, and 9 is the - slowest/highest compression. Any value outside this range - indicates that a default compression level should be used. - @param deleteDestStreamWhenDestroyed whether or not to delete the destStream object when - this stream is destroyed - @param windowBits this is used internally to change the window size used - by zlib - leave it as 0 unless you specifically need to set - its value for some reason - */ - GZIPCompressorOutputStream (OutputStream* destStream, - int compressionLevel = 0, - bool deleteDestStreamWhenDestroyed = false, - int windowBits = 0); - - /** Destructor. */ - ~GZIPCompressorOutputStream(); - - //============================================================================== - /** Flushes and closes the stream. - Note that unlike most streams, when you call flush() on a GZIPCompressorOutputStream, - the stream is closed - this means that no more data can be written to it, and any - subsequent attempts to call write() will cause an assertion. - */ - void flush(); - - int64 getPosition() override; - bool setPosition (int64) override; - bool write (const void*, size_t) override; - - /** These are preset values that can be used for the constructor's windowBits parameter. - For more info about this, see the zlib documentation for its windowBits parameter. - */ - enum WindowBitsValues - { - windowBitsRaw = -15, - windowBitsGZIP = 15 + 16 - }; - -private: - //============================================================================== - OptionalScopedPointer destStream; - - class GZIPCompressorHelper; - friend struct ContainerDeletePolicy; - ScopedPointer helper; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (GZIPCompressorOutputStream) -}; - -#endif // JUCE_GZIPCOMPRESSOROUTPUTSTREAM_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/zip/juce_GZIPDecompressorInputStream.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/zip/juce_GZIPDecompressorInputStream.cpp deleted file mode 100644 index 71e0850727..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/zip/juce_GZIPDecompressorInputStream.cpp +++ /dev/null @@ -1,288 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#if JUCE_MSVC - #pragma warning (push) - #pragma warning (disable: 4309 4305 4365) -#endif - -namespace zlibNamespace -{ - #if JUCE_INCLUDE_ZLIB_CODE - #if JUCE_CLANG - #pragma clang diagnostic push - #pragma clang diagnostic ignored "-Wconversion" - #pragma clang diagnostic ignored "-Wshadow" - #pragma clang diagnostic ignored "-Wdeprecated-register" - #endif - - #undef OS_CODE - #undef fdopen - #define ZLIB_INTERNAL - #define NO_DUMMY_DECL - #include "zlib/zlib.h" - #include "zlib/adler32.c" - #include "zlib/compress.c" - #undef DO1 - #undef DO8 - #include "zlib/crc32.c" - #include "zlib/deflate.c" - #include "zlib/inffast.c" - #undef PULLBYTE - #undef LOAD - #undef RESTORE - #undef INITBITS - #undef NEEDBITS - #undef DROPBITS - #undef BYTEBITS - #include "zlib/inflate.c" - #include "zlib/inftrees.c" - #include "zlib/trees.c" - #include "zlib/zutil.c" - #undef Byte - #undef fdopen - #undef local - #undef Freq - #undef Code - #undef Dad - #undef Len - - #if JUCE_CLANG - #pragma clang diagnostic pop - #endif - #else - #include JUCE_ZLIB_INCLUDE_PATH - #endif -} - -#if JUCE_MSVC - #pragma warning (pop) -#endif - -//============================================================================== -// internal helper object that holds the zlib structures so they don't have to be -// included publicly. -class GZIPDecompressorInputStream::GZIPDecompressHelper -{ -public: - GZIPDecompressHelper (const bool dontWrap) - : finished (true), - needsDictionary (false), - error (true), - streamIsValid (false), - data (nullptr), - dataSize (0) - { - using namespace zlibNamespace; - zerostruct (stream); - streamIsValid = (inflateInit2 (&stream, dontWrap ? -MAX_WBITS : MAX_WBITS) == Z_OK); - finished = error = ! streamIsValid; - } - - ~GZIPDecompressHelper() - { - using namespace zlibNamespace; - if (streamIsValid) - inflateEnd (&stream); - } - - bool needsInput() const noexcept { return dataSize <= 0; } - - void setInput (uint8* const data_, const size_t size) noexcept - { - data = data_; - dataSize = size; - } - - int doNextBlock (uint8* const dest, const unsigned int destSize) - { - using namespace zlibNamespace; - if (streamIsValid && data != nullptr && ! finished) - { - stream.next_in = data; - stream.next_out = dest; - stream.avail_in = (z_uInt) dataSize; - stream.avail_out = (z_uInt) destSize; - - switch (inflate (&stream, Z_PARTIAL_FLUSH)) - { - case Z_STREAM_END: - finished = true; - // deliberate fall-through - case Z_OK: - data += dataSize - stream.avail_in; - dataSize = (z_uInt) stream.avail_in; - return (int) (destSize - stream.avail_out); - - case Z_NEED_DICT: - needsDictionary = true; - data += dataSize - stream.avail_in; - dataSize = (size_t) stream.avail_in; - break; - - case Z_DATA_ERROR: - case Z_MEM_ERROR: - error = true; - - default: - break; - } - } - - return 0; - } - - bool finished, needsDictionary, error, streamIsValid; - - enum { gzipDecompBufferSize = 32768 }; - -private: - zlibNamespace::z_stream stream; - uint8* data; - size_t dataSize; - - JUCE_DECLARE_NON_COPYABLE (GZIPDecompressHelper) -}; - -//============================================================================== -GZIPDecompressorInputStream::GZIPDecompressorInputStream (InputStream* const source, - const bool deleteSourceWhenDestroyed, - const bool noWrap_, - const int64 uncompressedStreamLength_) - : sourceStream (source, deleteSourceWhenDestroyed), - uncompressedStreamLength (uncompressedStreamLength_), - noWrap (noWrap_), - isEof (false), - activeBufferSize (0), - originalSourcePos (source->getPosition()), - currentPos (0), - buffer ((size_t) GZIPDecompressHelper::gzipDecompBufferSize), - helper (new GZIPDecompressHelper (noWrap_)) -{ -} - -GZIPDecompressorInputStream::GZIPDecompressorInputStream (InputStream& source) - : sourceStream (&source, false), - uncompressedStreamLength (-1), - noWrap (false), - isEof (false), - activeBufferSize (0), - originalSourcePos (source.getPosition()), - currentPos (0), - buffer ((size_t) GZIPDecompressHelper::gzipDecompBufferSize), - helper (new GZIPDecompressHelper (false)) -{ -} - -GZIPDecompressorInputStream::~GZIPDecompressorInputStream() -{ -} - -int64 GZIPDecompressorInputStream::getTotalLength() -{ - return uncompressedStreamLength; -} - -int GZIPDecompressorInputStream::read (void* destBuffer, int howMany) -{ - jassert (destBuffer != nullptr && howMany >= 0); - - if (howMany > 0 && ! isEof) - { - int numRead = 0; - uint8* d = static_cast (destBuffer); - - while (! helper->error) - { - const int n = helper->doNextBlock (d, (unsigned int) howMany); - currentPos += n; - - if (n == 0) - { - if (helper->finished || helper->needsDictionary) - { - isEof = true; - return numRead; - } - - if (helper->needsInput()) - { - activeBufferSize = sourceStream->read (buffer, (int) GZIPDecompressHelper::gzipDecompBufferSize); - - if (activeBufferSize > 0) - { - helper->setInput (buffer, (size_t) activeBufferSize); - } - else - { - isEof = true; - return numRead; - } - } - } - else - { - numRead += n; - howMany -= n; - d += n; - - if (howMany <= 0) - return numRead; - } - } - } - - return 0; -} - -bool GZIPDecompressorInputStream::isExhausted() -{ - return helper->error || isEof; -} - -int64 GZIPDecompressorInputStream::getPosition() -{ - return currentPos; -} - -bool GZIPDecompressorInputStream::setPosition (int64 newPos) -{ - if (newPos < currentPos) - { - // to go backwards, reset the stream and start again.. - isEof = false; - activeBufferSize = 0; - currentPos = 0; - helper = new GZIPDecompressHelper (noWrap); - - sourceStream->setPosition (originalSourcePos); - } - - skipNextBytes (newPos - currentPos); - return true; -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/zip/juce_GZIPDecompressorInputStream.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/zip/juce_GZIPDecompressorInputStream.h deleted file mode 100644 index 78a0b77b7f..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/zip/juce_GZIPDecompressorInputStream.h +++ /dev/null @@ -1,97 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_GZIPDECOMPRESSORINPUTSTREAM_H_INCLUDED -#define JUCE_GZIPDECOMPRESSORINPUTSTREAM_H_INCLUDED - - -//============================================================================== -/** - This stream will decompress a source-stream using zlib. - - Tip: if you're reading lots of small items from one of these streams, you - can increase the performance enormously by passing it through a - BufferedInputStream, so that it has to read larger blocks less often. - - @see GZIPCompressorOutputStream -*/ -class JUCE_API GZIPDecompressorInputStream : public InputStream -{ -public: - //============================================================================== - /** Creates a decompressor stream. - - @param sourceStream the stream to read from - @param deleteSourceWhenDestroyed whether or not to delete the source stream - when this object is destroyed - @param noWrap this is used internally by the ZipFile class - and should be ignored by user applications - @param uncompressedStreamLength if the creator knows the length that the - uncompressed stream will be, then it can supply this - value, which will be returned by getTotalLength() - */ - GZIPDecompressorInputStream (InputStream* sourceStream, - bool deleteSourceWhenDestroyed, - bool noWrap = false, - int64 uncompressedStreamLength = -1); - - /** Creates a decompressor stream. - - @param sourceStream the stream to read from - the source stream must not be - deleted until this object has been destroyed - */ - GZIPDecompressorInputStream (InputStream& sourceStream); - - /** Destructor. */ - ~GZIPDecompressorInputStream(); - - //============================================================================== - int64 getPosition() override; - bool setPosition (int64 pos) override; - int64 getTotalLength() override; - bool isExhausted() override; - int read (void* destBuffer, int maxBytesToRead) override; - -private: - //============================================================================== - OptionalScopedPointer sourceStream; - const int64 uncompressedStreamLength; - const bool noWrap; - bool isEof; - int activeBufferSize; - int64 originalSourcePos, currentPos; - HeapBlock buffer; - - class GZIPDecompressHelper; - friend struct ContainerDeletePolicy; - ScopedPointer helper; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (GZIPDecompressorInputStream) -}; - -#endif // JUCE_GZIPDECOMPRESSORINPUTSTREAM_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/zip/juce_ZipFile.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/zip/juce_ZipFile.cpp deleted file mode 100644 index a76d8b8900..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/zip/juce_ZipFile.cpp +++ /dev/null @@ -1,608 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -class ZipFile::ZipEntryHolder -{ -public: - ZipEntryHolder (const char* const buffer, const int fileNameLen) - { - entry.filename = String::fromUTF8 (buffer + 46, fileNameLen); - - const int time = ByteOrder::littleEndianShort (buffer + 12); - const int date = ByteOrder::littleEndianShort (buffer + 14); - entry.fileTime = getFileTimeFromRawEncodings (time, date); - - compressed = ByteOrder::littleEndianShort (buffer + 10) != 0; - compressedSize = (size_t) ByteOrder::littleEndianInt (buffer + 20); - entry.uncompressedSize = ByteOrder::littleEndianInt (buffer + 24); - - streamOffset = ByteOrder::littleEndianInt (buffer + 42); - } - - struct FileNameComparator - { - static int compareElements (const ZipEntryHolder* first, const ZipEntryHolder* second) - { - return first->entry.filename.compare (second->entry.filename); - } - }; - - ZipEntry entry; - size_t streamOffset; - size_t compressedSize; - bool compressed; - -private: - static Time getFileTimeFromRawEncodings (int time, int date) - { - const int year = 1980 + (date >> 9); - const int month = ((date >> 5) & 15) - 1; - const int day = date & 31; - const int hours = time >> 11; - const int minutes = (time >> 5) & 63; - const int seconds = (time & 31) << 1; - - return Time (year, month, day, hours, minutes, seconds); - } -}; - -//============================================================================== -namespace -{ - int findEndOfZipEntryTable (InputStream& input, int& numEntries) - { - BufferedInputStream in (input, 8192); - - in.setPosition (in.getTotalLength()); - int64 pos = in.getPosition(); - const int64 lowestPos = jmax ((int64) 0, pos - 1024); - - char buffer [32] = { 0 }; - - while (pos > lowestPos) - { - in.setPosition (pos - 22); - pos = in.getPosition(); - memcpy (buffer + 22, buffer, 4); - - if (in.read (buffer, 22) != 22) - return 0; - - for (int i = 0; i < 22; ++i) - { - if (ByteOrder::littleEndianInt (buffer + i) == 0x06054b50) - { - in.setPosition (pos + i); - in.read (buffer, 22); - numEntries = ByteOrder::littleEndianShort (buffer + 10); - - return (int) ByteOrder::littleEndianInt (buffer + 16); - } - } - } - - return 0; - } -} - -//============================================================================== -class ZipFile::ZipInputStream : public InputStream -{ -public: - ZipInputStream (ZipFile& zf, ZipFile::ZipEntryHolder& zei) - : file (zf), - zipEntryHolder (zei), - pos (0), - headerSize (0), - inputStream (zf.inputStream) - { - if (zf.inputSource != nullptr) - { - inputStream = streamToDelete = file.inputSource->createInputStream(); - } - else - { - #if JUCE_DEBUG - zf.streamCounter.numOpenStreams++; - #endif - } - - char buffer [30]; - - if (inputStream != nullptr - && inputStream->setPosition ((int64) zei.streamOffset) - && inputStream->read (buffer, 30) == 30 - && ByteOrder::littleEndianInt (buffer) == 0x04034b50) - { - headerSize = 30 + ByteOrder::littleEndianShort (buffer + 26) - + ByteOrder::littleEndianShort (buffer + 28); - } - } - - ~ZipInputStream() - { - #if JUCE_DEBUG - if (inputStream != nullptr && inputStream == file.inputStream) - file.streamCounter.numOpenStreams--; - #endif - } - - int64 getTotalLength() - { - return (int64) zipEntryHolder.compressedSize; - } - - int read (void* buffer, int howMany) - { - if (headerSize <= 0) - return 0; - - howMany = (int) jmin ((int64) howMany, ((int64) zipEntryHolder.compressedSize) - pos); - - if (inputStream == nullptr) - return 0; - - int num; - - if (inputStream == file.inputStream) - { - const ScopedLock sl (file.lock); - inputStream->setPosition (pos + (int64) zipEntryHolder.streamOffset + headerSize); - num = inputStream->read (buffer, howMany); - } - else - { - inputStream->setPosition (pos + (int64) zipEntryHolder.streamOffset + headerSize); - num = inputStream->read (buffer, howMany); - } - - pos += num; - return num; - } - - bool isExhausted() - { - return headerSize <= 0 || pos >= (int64) zipEntryHolder.compressedSize; - } - - int64 getPosition() - { - return pos; - } - - bool setPosition (int64 newPos) - { - pos = jlimit ((int64) 0, (int64) zipEntryHolder.compressedSize, newPos); - return true; - } - -private: - ZipFile& file; - ZipEntryHolder zipEntryHolder; - int64 pos; - int headerSize; - InputStream* inputStream; - ScopedPointer streamToDelete; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ZipInputStream) -}; - - -//============================================================================== -ZipFile::ZipFile (InputStream* const stream, const bool deleteStreamWhenDestroyed) - : inputStream (stream) -{ - if (deleteStreamWhenDestroyed) - streamToDelete = inputStream; - - init(); -} - -ZipFile::ZipFile (InputStream& stream) - : inputStream (&stream) -{ - init(); -} - -ZipFile::ZipFile (const File& file) - : inputStream (nullptr), - inputSource (new FileInputSource (file)) -{ - init(); -} - -ZipFile::ZipFile (InputSource* const source) - : inputStream (nullptr), - inputSource (source) -{ - init(); -} - -ZipFile::~ZipFile() -{ - entries.clear(); -} - -#if JUCE_DEBUG -ZipFile::OpenStreamCounter::~OpenStreamCounter() -{ - /* If you hit this assertion, it means you've created a stream to read one of the items in the - zipfile, but you've forgotten to delete that stream object before deleting the file.. - Streams can't be kept open after the file is deleted because they need to share the input - stream that is managed by the ZipFile object. - */ - jassert (numOpenStreams == 0); -} -#endif - -//============================================================================== -int ZipFile::getNumEntries() const noexcept -{ - return entries.size(); -} - -const ZipFile::ZipEntry* ZipFile::getEntry (const int index) const noexcept -{ - if (ZipEntryHolder* const zei = entries [index]) - return &(zei->entry); - - return nullptr; -} - -int ZipFile::getIndexOfFileName (const String& fileName) const noexcept -{ - for (int i = 0; i < entries.size(); ++i) - if (entries.getUnchecked (i)->entry.filename == fileName) - return i; - - return -1; -} - -const ZipFile::ZipEntry* ZipFile::getEntry (const String& fileName) const noexcept -{ - return getEntry (getIndexOfFileName (fileName)); -} - -InputStream* ZipFile::createStreamForEntry (const int index) -{ - InputStream* stream = nullptr; - - if (ZipEntryHolder* const zei = entries[index]) - { - stream = new ZipInputStream (*this, *zei); - - if (zei->compressed) - { - stream = new GZIPDecompressorInputStream (stream, true, true, (int64) zei->entry.uncompressedSize); - - // (much faster to unzip in big blocks using a buffer..) - stream = new BufferedInputStream (stream, 32768, true); - } - } - - return stream; -} - -InputStream* ZipFile::createStreamForEntry (const ZipEntry& entry) -{ - for (int i = 0; i < entries.size(); ++i) - if (&entries.getUnchecked (i)->entry == &entry) - return createStreamForEntry (i); - - return nullptr; -} - -void ZipFile::sortEntriesByFilename() -{ - ZipEntryHolder::FileNameComparator sorter; - entries.sort (sorter); -} - -//============================================================================== -void ZipFile::init() -{ - ScopedPointer toDelete; - InputStream* in = inputStream; - - if (inputSource != nullptr) - { - in = inputSource->createInputStream(); - toDelete = in; - } - - if (in != nullptr) - { - int numEntries = 0; - int pos = findEndOfZipEntryTable (*in, numEntries); - - if (pos >= 0 && pos < in->getTotalLength()) - { - const int size = (int) (in->getTotalLength() - pos); - - in->setPosition (pos); - MemoryBlock headerData; - - if (in->readIntoMemoryBlock (headerData, size) == (size_t) size) - { - pos = 0; - - for (int i = 0; i < numEntries; ++i) - { - if (pos + 46 > size) - break; - - const char* const buffer = static_cast (headerData.getData()) + pos; - - const int fileNameLen = ByteOrder::littleEndianShort (buffer + 28); - - if (pos + 46 + fileNameLen > size) - break; - - entries.add (new ZipEntryHolder (buffer, fileNameLen)); - - pos += 46 + fileNameLen - + ByteOrder::littleEndianShort (buffer + 30) - + ByteOrder::littleEndianShort (buffer + 32); - } - } - } - } -} - -Result ZipFile::uncompressTo (const File& targetDirectory, - const bool shouldOverwriteFiles) -{ - for (int i = 0; i < entries.size(); ++i) - { - Result result (uncompressEntry (i, targetDirectory, shouldOverwriteFiles)); - if (result.failed()) - return result; - } - - return Result::ok(); -} - -Result ZipFile::uncompressEntry (const int index, - const File& targetDirectory, - bool shouldOverwriteFiles) -{ - const ZipEntryHolder* zei = entries.getUnchecked (index); - - #if JUCE_WINDOWS - const String entryPath (zei->entry.filename); - #else - const String entryPath (zei->entry.filename.replaceCharacter ('\\', '/')); - #endif - - const File targetFile (targetDirectory.getChildFile (entryPath)); - - if (entryPath.endsWithChar ('/') || entryPath.endsWithChar ('\\')) - return targetFile.createDirectory(); // (entry is a directory, not a file) - - ScopedPointer in (createStreamForEntry (index)); - - if (in == nullptr) - return Result::fail ("Failed to open the zip file for reading"); - - if (targetFile.exists()) - { - if (! shouldOverwriteFiles) - return Result::ok(); - - if (! targetFile.deleteFile()) - return Result::fail ("Failed to write to target file: " + targetFile.getFullPathName()); - } - - if (! targetFile.getParentDirectory().createDirectory()) - return Result::fail ("Failed to create target folder: " + targetFile.getParentDirectory().getFullPathName()); - - { - FileOutputStream out (targetFile); - - if (out.failedToOpen()) - return Result::fail ("Failed to write to target file: " + targetFile.getFullPathName()); - - out << *in; - } - - targetFile.setCreationTime (zei->entry.fileTime); - targetFile.setLastModificationTime (zei->entry.fileTime); - targetFile.setLastAccessTime (zei->entry.fileTime); - - return Result::ok(); -} - - -//============================================================================= -class ZipFile::Builder::Item -{ -public: - Item (const File& f, InputStream* s, const int compression, const String& storedPath, Time time) - : file (f), stream (s), storedPathname (storedPath), - fileTime (time), compressionLevel (compression), - compressedSize (0), uncompressedSize (0), headerStart (0), checksum (0) - { - } - - bool writeData (OutputStream& target, const int64 overallStartPosition) - { - MemoryOutputStream compressedData ((size_t) file.getSize()); - - if (compressionLevel > 0) - { - GZIPCompressorOutputStream compressor (&compressedData, compressionLevel, false, - GZIPCompressorOutputStream::windowBitsRaw); - if (! writeSource (compressor)) - return false; - } - else - { - if (! writeSource (compressedData)) - return false; - } - - compressedSize = (int) compressedData.getDataSize(); - headerStart = (int) (target.getPosition() - overallStartPosition); - - target.writeInt (0x04034b50); - writeFlagsAndSizes (target); - target << storedPathname - << compressedData; - - return true; - } - - bool writeDirectoryEntry (OutputStream& target) - { - target.writeInt (0x02014b50); - target.writeShort (20); // version written - writeFlagsAndSizes (target); - target.writeShort (0); // comment length - target.writeShort (0); // start disk num - target.writeShort (0); // internal attributes - target.writeInt (0); // external attributes - target.writeInt (headerStart); - target << storedPathname; - - return true; - } - -private: - const File file; - ScopedPointer stream; - String storedPathname; - Time fileTime; - int compressionLevel, compressedSize, uncompressedSize, headerStart; - unsigned long checksum; - - static void writeTimeAndDate (OutputStream& target, Time t) - { - target.writeShort ((short) (t.getSeconds() + (t.getMinutes() << 5) + (t.getHours() << 11))); - target.writeShort ((short) (t.getDayOfMonth() + ((t.getMonth() + 1) << 5) + ((t.getYear() - 1980) << 9))); - } - - bool writeSource (OutputStream& target) - { - if (stream == nullptr) - { - stream = file.createInputStream(); - - if (stream == nullptr) - return false; - } - - checksum = 0; - uncompressedSize = 0; - const int bufferSize = 4096; - HeapBlock buffer (bufferSize); - - while (! stream->isExhausted()) - { - const int bytesRead = stream->read (buffer, bufferSize); - - if (bytesRead < 0) - return false; - - checksum = zlibNamespace::crc32 (checksum, buffer, (unsigned int) bytesRead); - target.write (buffer, (size_t) bytesRead); - uncompressedSize += bytesRead; - } - - stream = nullptr; - return true; - } - - void writeFlagsAndSizes (OutputStream& target) const - { - target.writeShort (10); // version needed - target.writeShort ((short) (1 << 11)); // this flag indicates UTF-8 filename encoding - target.writeShort (compressionLevel > 0 ? (short) 8 : (short) 0); - writeTimeAndDate (target, fileTime); - target.writeInt ((int) checksum); - target.writeInt (compressedSize); - target.writeInt (uncompressedSize); - target.writeShort ((short) storedPathname.toUTF8().sizeInBytes() - 1); - target.writeShort (0); // extra field length - } - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Item) -}; - -//============================================================================= -ZipFile::Builder::Builder() {} -ZipFile::Builder::~Builder() {} - -void ZipFile::Builder::addFile (const File& file, const int compression, const String& path) -{ - items.add (new Item (file, nullptr, compression, - path.isEmpty() ? file.getFileName() : path, - file.getLastModificationTime())); -} - -void ZipFile::Builder::addEntry (InputStream* stream, int compression, const String& path, Time time) -{ - jassert (stream != nullptr); // must not be null! - jassert (path.isNotEmpty()); - items.add (new Item (File(), stream, compression, path, time)); -} - -bool ZipFile::Builder::writeToStream (OutputStream& target, double* const progress) const -{ - const int64 fileStart = target.getPosition(); - - for (int i = 0; i < items.size(); ++i) - { - if (progress != nullptr) - *progress = (i + 0.5) / items.size(); - - if (! items.getUnchecked (i)->writeData (target, fileStart)) - return false; - } - - const int64 directoryStart = target.getPosition(); - - for (int i = 0; i < items.size(); ++i) - if (! items.getUnchecked (i)->writeDirectoryEntry (target)) - return false; - - const int64 directoryEnd = target.getPosition(); - - target.writeInt (0x06054b50); - target.writeShort (0); - target.writeShort (0); - target.writeShort ((short) items.size()); - target.writeShort ((short) items.size()); - target.writeInt ((int) (directoryEnd - directoryStart)); - target.writeInt ((int) (directoryStart - fileStart)); - target.writeShort (0); - - if (progress != nullptr) - *progress = 1.0; - - return true; -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/zip/juce_ZipFile.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/zip/juce_ZipFile.h deleted file mode 100644 index ccf9064cec..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_core/zip/juce_ZipFile.h +++ /dev/null @@ -1,259 +0,0 @@ -/* - ============================================================================== - - This file is part of the juce_core module of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission to use, copy, modify, and/or distribute this software for any purpose with - or without fee is hereby granted, provided that the above copyright notice and this - permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ------------------------------------------------------------------------------ - - NOTE! This permissive ISC license applies ONLY to files within the juce_core module! - All other JUCE modules are covered by a dual GPL/commercial license, so if you are - using any other modules, be sure to check that you also comply with their license. - - For more details, visit www.juce.com - - ============================================================================== -*/ - -#ifndef JUCE_ZIPFILE_H_INCLUDED -#define JUCE_ZIPFILE_H_INCLUDED - - -//============================================================================== -/** - Decodes a ZIP file from a stream. - - This can enumerate the items in a ZIP file and can create suitable stream objects - to read each one. -*/ -class JUCE_API ZipFile -{ -public: - /** Creates a ZipFile based for a file. */ - explicit ZipFile (const File& file); - - //============================================================================== - /** Creates a ZipFile for a given stream. - - @param inputStream the stream to read from - @param deleteStreamWhenDestroyed if set to true, the object passed-in - will be deleted when this ZipFile object is deleted - */ - ZipFile (InputStream* inputStream, bool deleteStreamWhenDestroyed); - - /** Creates a ZipFile for a given stream. - The stream will not be owned or deleted by this class - if you want the ZipFile to - manage the stream's lifetime, use the other constructor. - */ - explicit ZipFile (InputStream& inputStream); - - /** Creates a ZipFile for an input source. - - The inputSource object will be owned by the zip file, which will delete - it later when not needed. - */ - explicit ZipFile (InputSource* inputSource); - - /** Destructor. */ - ~ZipFile(); - - //============================================================================== - /** - Contains information about one of the entries in a ZipFile. - - @see ZipFile::getEntry - */ - struct ZipEntry - { - /** The name of the file, which may also include a partial pathname. */ - String filename; - - /** The file's original size. */ - unsigned int uncompressedSize; - - /** The last time the file was modified. */ - Time fileTime; - }; - - //============================================================================== - /** Returns the number of items in the zip file. */ - int getNumEntries() const noexcept; - - /** Returns a structure that describes one of the entries in the zip file. - - This may return zero if the index is out of range. - - @see ZipFile::ZipEntry - */ - const ZipEntry* getEntry (int index) const noexcept; - - /** Returns the index of the first entry with a given filename. - - This uses a case-sensitive comparison to look for a filename in the - list of entries. It might return -1 if no match is found. - - @see ZipFile::ZipEntry - */ - int getIndexOfFileName (const String& fileName) const noexcept; - - /** Returns a structure that describes one of the entries in the zip file. - - This uses a case-sensitive comparison to look for a filename in the - list of entries. It might return 0 if no match is found. - - @see ZipFile::ZipEntry - */ - const ZipEntry* getEntry (const String& fileName) const noexcept; - - /** Sorts the list of entries, based on the filename. - */ - void sortEntriesByFilename(); - - //============================================================================== - /** Creates a stream that can read from one of the zip file's entries. - - The stream that is returned must be deleted by the caller (and - zero might be returned if a stream can't be opened for some reason). - - The stream must not be used after the ZipFile object that created - has been deleted. - */ - InputStream* createStreamForEntry (int index); - - /** Creates a stream that can read from one of the zip file's entries. - - The stream that is returned must be deleted by the caller (and - zero might be returned if a stream can't be opened for some reason). - - The stream must not be used after the ZipFile object that created - has been deleted. - */ - InputStream* createStreamForEntry (const ZipEntry& entry); - - //============================================================================== - /** Uncompresses all of the files in the zip file. - - This will expand all the entries into a target directory. The relative - paths of the entries are used. - - @param targetDirectory the root folder to uncompress to - @param shouldOverwriteFiles whether to overwrite existing files with similarly-named ones - @returns success if the file is successfully unzipped - */ - Result uncompressTo (const File& targetDirectory, - bool shouldOverwriteFiles = true); - - /** Uncompresses one of the entries from the zip file. - - This will expand the entry and write it in a target directory. The entry's path is used to - determine which subfolder of the target should contain the new file. - - @param index the index of the entry to uncompress - this must be a valid index - between 0 and (getNumEntries() - 1). - @param targetDirectory the root folder to uncompress into - @param shouldOverwriteFiles whether to overwrite existing files with similarly-named ones - @returns success if all the files are successfully unzipped - */ - Result uncompressEntry (int index, - const File& targetDirectory, - bool shouldOverwriteFiles = true); - - - //============================================================================== - /** Used to create a new zip file. - - Create a ZipFile::Builder object, and call its addFile() method to add some files, - then you can write it to a stream with write(). - - Currently this just stores the files with no compression.. That will be added - soon! - */ - class Builder - { - public: - Builder(); - ~Builder(); - - /** Adds a file while should be added to the archive. - The file isn't read immediately, all the files will be read later when the writeToStream() - method is called. - - The compressionLevel can be between 0 (no compression), and 9 (maximum compression). - If the storedPathName parameter is specified, you can customise the partial pathname that - will be stored for this file. - */ - void addFile (const File& fileToAdd, int compressionLevel, - const String& storedPathName = String::empty); - - /** Adds a file while should be added to the archive. - - @param streamToRead this stream isn't read immediately - a pointer to the stream is - stored, then used later when the writeToStream() method is called, and - deleted by the Builder object when no longer needed, so be very careful - about its lifetime and the lifetime of any objects on which it depends! - This must not be null. - @param compressionLevel this can be between 0 (no compression), and 9 (maximum compression). - @param storedPathName the partial pathname that will be stored for this file - @param fileModificationTime the timestamp that will be stored as the last modification time - of this entry - */ - void addEntry (InputStream* streamToRead, int compressionLevel, - const String& storedPathName, Time fileModificationTime); - - /** Generates the zip file, writing it to the specified stream. - If the progress parameter is non-null, it will be updated with an approximate - progress status between 0 and 1.0 - */ - bool writeToStream (OutputStream& target, double* progress) const; - - //============================================================================== - private: - class Item; - friend struct ContainerDeletePolicy; - OwnedArray items; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Builder) - }; - -private: - //============================================================================== - class ZipInputStream; - class ZipEntryHolder; - friend class ZipInputStream; - friend class ZipEntryHolder; - - OwnedArray entries; - CriticalSection lock; - InputStream* inputStream; - ScopedPointer streamToDelete; - ScopedPointer inputSource; - - #if JUCE_DEBUG - struct OpenStreamCounter - { - OpenStreamCounter() : numOpenStreams (0) {} - ~OpenStreamCounter(); - - int numOpenStreams; - }; - - OpenStreamCounter streamCounter; - #endif - - void init(); - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ZipFile) -}; - -#endif // JUCE_ZIPFILE_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_cryptography/encryption/juce_BlowFish.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_cryptography/encryption/juce_BlowFish.cpp deleted file mode 100644 index 3ff839b39d..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_cryptography/encryption/juce_BlowFish.cpp +++ /dev/null @@ -1,271 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -BlowFish::BlowFish (const void* const keyData, const int keyBytes) -{ - jassert (keyData != nullptr); - jassert (keyBytes > 0); - - static const uint32 initialPValues [18] = - { - 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, 0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89, - 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c, 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917, - 0x9216d5d9, 0x8979fb1b - }; - - static const uint32 initialSValues [4 * 256] = - { - 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99, - 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16, 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e, - 0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee, 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013, - 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef, 0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e, - 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60, 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440, - 0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce, 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a, - 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e, 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677, - 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193, 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032, - 0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88, 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239, - 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e, 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0, - 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3, 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98, - 0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88, 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe, - 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d, - 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b, 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7, - 0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba, 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463, - 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, 0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09, - 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3, 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb, - 0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279, 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8, - 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab, 0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82, - 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db, 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573, - 0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0, 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b, - 0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790, 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8, - 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4, 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0, - 0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7, 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c, - 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad, 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1, - 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299, 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9, - 0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477, 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf, - 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49, 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af, - 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa, 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5, - 0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41, 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915, - 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, 0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915, - 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664, 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a, - 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623, 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266, - 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1, 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e, - 0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6, 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1, - 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e, 0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1, - 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737, 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8, - 0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff, 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd, - 0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701, 0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7, - 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41, 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331, - 0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf, 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af, - 0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e, 0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87, - 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c, 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2, - 0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16, 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd, - 0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b, 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509, - 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e, 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3, - 0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f, 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a, - 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4, 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960, - 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66, 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28, - 0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802, 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84, - 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510, 0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf, - 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14, 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e, - 0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50, 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7, - 0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8, 0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281, - 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99, 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696, - 0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128, 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73, - 0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0, 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0, - 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105, 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250, - 0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3, 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285, - 0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00, 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061, - 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb, 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e, - 0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735, 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc, - 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9, 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340, - 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20, 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7, - 0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934, 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068, - 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af, 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840, - 0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45, 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504, - 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a, 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb, - 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee, 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6, - 0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42, 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b, - 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2, 0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb, - 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527, 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b, - 0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33, 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c, - 0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3, 0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc, - 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17, 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564, - 0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b, 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115, - 0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922, 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728, - 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0, 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e, - 0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37, 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d, - 0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804, 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b, - 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3, 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb, - 0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d, 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c, - 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350, 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9, - 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a, 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe, - 0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d, 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc, - 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f, 0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61, - 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2, 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9, - 0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2, 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c, - 0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e, 0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633, - 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10, 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169, - 0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52, 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027, - 0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5, 0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62, - 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634, 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76, - 0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24, 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc, - 0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4, 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c, - 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837, 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0, - 0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b, 0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe, - 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b, 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4, - 0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8, 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6, - 0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304, 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22, - 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4, 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6, - 0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9, 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59, - 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593, 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51, - 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28, 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c, - 0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b, 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28, - 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, 0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd, - 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a, 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319, - 0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb, 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f, - 0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991, 0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32, - 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680, 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166, - 0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae, 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb, - 0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5, 0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47, - 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370, 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d, - 0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84, 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048, - 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8, 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd, - 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9, 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7, - 0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38, 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f, - 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c, 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525, - 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1, 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442, - 0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964, 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e, - 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8, 0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d, - 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f, 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299, - 0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02, 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc, - 0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614, 0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a, - 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6, 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b, - 0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0, 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060, - 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e, 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9, - 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f, 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6 - }; - - memcpy (p, initialPValues, sizeof (p)); - - int i, j = 0; - for (i = 4; --i >= 0;) - { - s[i].malloc (256); - memcpy (s[i], initialSValues + i * 256, 256 * sizeof (uint32)); - } - - for (i = 0; i < 18; ++i) - { - uint32 d = 0; - - for (int k = 0; k < 4; ++k) - { - d = (d << 8) | static_cast (keyData)[j]; - - if (++j >= keyBytes) - j = 0; - } - - p[i] = initialPValues[i] ^ d; - } - - uint32 l = 0, r = 0; - - for (i = 0; i < 18; i += 2) - { - encrypt (l, r); - - p[i] = l; - p[i + 1] = r; - } - - for (i = 0; i < 4; ++i) - { - for (j = 0; j < 256; j += 2) - { - encrypt (l, r); - - s[i][j] = l; - s[i][j + 1] = r; - } - } -} - -BlowFish::BlowFish (const BlowFish& other) -{ - for (int i = 4; --i >= 0;) - s[i].malloc (256); - - operator= (other); -} - -BlowFish& BlowFish::operator= (const BlowFish& other) noexcept -{ - memcpy (p, other.p, sizeof (p)); - - for (int i = 4; --i >= 0;) - memcpy (s[i], other.s[i], 256 * sizeof (uint32)); - - return *this; -} - -BlowFish::~BlowFish() noexcept {} - -uint32 BlowFish::F (const uint32 x) const noexcept -{ - return ((s[0][(x >> 24) & 0xff] + s[1][(x >> 16) & 0xff]) - ^ s[2][(x >> 8) & 0xff]) + s[3][x & 0xff]; -} - -void BlowFish::encrypt (uint32& data1, uint32& data2) const noexcept -{ - uint32 l = data1; - uint32 r = data2; - - for (int i = 0; i < 16; ++i) - { - l ^= p[i]; - r ^= F(l); - std::swap (l, r); - } - - data1 = r ^ p[17]; - data2 = l ^ p[16]; -} - -void BlowFish::decrypt (uint32& data1, uint32& data2) const noexcept -{ - uint32 l = data1; - uint32 r = data2; - - for (int i = 17; i > 1; --i) - { - l ^= p[i]; - r ^= F(l); - std::swap (l, r); - } - - data1 = r ^ p[0]; - data2 = l ^ p[1]; -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_cryptography/encryption/juce_BlowFish.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_cryptography/encryption/juce_BlowFish.h deleted file mode 100644 index 1b28091818..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_cryptography/encryption/juce_BlowFish.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_BLOWFISH_H_INCLUDED -#define JUCE_BLOWFISH_H_INCLUDED - - -//============================================================================== -/** - BlowFish encryption class. - -*/ -class JUCE_API BlowFish -{ -public: - //============================================================================== - /** Creates an object that can encode/decode based on the specified key. - - The key data can be up to 72 bytes long. - */ - BlowFish (const void* keyData, int keyBytes); - - /** Creates a copy of another blowfish object. */ - BlowFish (const BlowFish&); - - /** Copies another blowfish object. */ - BlowFish& operator= (const BlowFish&) noexcept; - - /** Destructor. */ - ~BlowFish() noexcept; - - //============================================================================== - /** Encrypts a pair of 32-bit integers. */ - void encrypt (uint32& data1, uint32& data2) const noexcept; - - /** Decrypts a pair of 32-bit integers. */ - void decrypt (uint32& data1, uint32& data2) const noexcept; - - -private: - //============================================================================== - uint32 p[18]; - HeapBlock s[4]; - - uint32 F (uint32) const noexcept; - - JUCE_LEAK_DETECTOR (BlowFish) -}; - - -#endif // JUCE_BLOWFISH_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_cryptography/encryption/juce_Primes.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_cryptography/encryption/juce_Primes.cpp deleted file mode 100644 index 058635bbc4..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_cryptography/encryption/juce_Primes.cpp +++ /dev/null @@ -1,238 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -namespace PrimesHelpers -{ - static void createSmallSieve (const int numBits, BigInteger& result) - { - result.setBit (numBits); - result.clearBit (numBits); // to enlarge the array - - result.setBit (0); - int n = 2; - - do - { - for (int i = n + n; i < numBits; i += n) - result.setBit (i); - - n = result.findNextClearBit (n + 1); - } - while (n <= (numBits >> 1)); - } - - static void bigSieve (const BigInteger& base, const int numBits, BigInteger& result, - const BigInteger& smallSieve, const int smallSieveSize) - { - jassert (! base[0]); // must be even! - - result.setBit (numBits); - result.clearBit (numBits); // to enlarge the array - - int index = smallSieve.findNextClearBit (0); - - do - { - const unsigned int prime = ((unsigned int) index << 1) + 1; - - BigInteger r (base), remainder; - r.divideBy (prime, remainder); - - unsigned int i = prime - remainder.getBitRangeAsInt (0, 32); - - if (r.isZero()) - i += prime; - - if ((i & 1) == 0) - i += prime; - - i = (i - 1) >> 1; - - while (i < (unsigned int) numBits) - { - result.setBit ((int) i); - i += prime; - } - - index = smallSieve.findNextClearBit (index + 1); - } - while (index < smallSieveSize); - } - - static bool findCandidate (const BigInteger& base, const BigInteger& sieve, - const int numBits, BigInteger& result, const int certainty) - { - for (int i = 0; i < numBits; ++i) - { - if (! sieve[i]) - { - result = base + (unsigned int) ((i << 1) + 1); - - if (Primes::isProbablyPrime (result, certainty)) - return true; - } - } - - return false; - } - - static bool passesMillerRabin (const BigInteger& n, int iterations) - { - const BigInteger one (1), two (2); - const BigInteger nMinusOne (n - one); - - BigInteger d (nMinusOne); - const int s = d.findNextSetBit (0); - d >>= s; - - BigInteger smallPrimes; - int numBitsInSmallPrimes = 0; - - for (;;) - { - numBitsInSmallPrimes += 256; - createSmallSieve (numBitsInSmallPrimes, smallPrimes); - - const int numPrimesFound = numBitsInSmallPrimes - smallPrimes.countNumberOfSetBits(); - - if (numPrimesFound > iterations + 1) - break; - } - - int smallPrime = 2; - - while (--iterations >= 0) - { - smallPrime = smallPrimes.findNextClearBit (smallPrime + 1); - - BigInteger r (smallPrime); - r.exponentModulo (d, n); - - if (r != one && r != nMinusOne) - { - for (int j = 0; j < s; ++j) - { - r.exponentModulo (two, n); - - if (r == nMinusOne) - break; - } - - if (r != nMinusOne) - return false; - } - } - - return true; - } -} - -//============================================================================== -BigInteger Primes::createProbablePrime (const int bitLength, - const int certainty, - const int* randomSeeds, - int numRandomSeeds) -{ - using namespace PrimesHelpers; - int defaultSeeds [16]; - - if (numRandomSeeds <= 0) - { - randomSeeds = defaultSeeds; - numRandomSeeds = numElementsInArray (defaultSeeds); - Random r1, r2; - - for (int j = 10; --j >= 0;) - { - r1.setSeedRandomly(); - - for (int i = numRandomSeeds; --i >= 0;) - defaultSeeds[i] ^= r1.nextInt() ^ r2.nextInt(); - } - } - - BigInteger smallSieve; - const int smallSieveSize = 15000; - createSmallSieve (smallSieveSize, smallSieve); - - BigInteger p; - - for (int i = numRandomSeeds; --i >= 0;) - { - BigInteger p2; - - Random r (randomSeeds[i]); - r.fillBitsRandomly (p2, 0, bitLength); - - p ^= p2; - } - - p.setBit (bitLength - 1); - p.clearBit (0); - - const int searchLen = jmax (1024, (bitLength / 20) * 64); - - while (p.getHighestBit() < bitLength) - { - p += 2 * searchLen; - - BigInteger sieve; - bigSieve (p, searchLen, sieve, - smallSieve, smallSieveSize); - - BigInteger candidate; - - if (findCandidate (p, sieve, searchLen, candidate, certainty)) - return candidate; - } - - jassertfalse; - return BigInteger(); -} - -bool Primes::isProbablyPrime (const BigInteger& number, const int certainty) -{ - using namespace PrimesHelpers; - - if (! number[0]) - return false; - - if (number.getHighestBit() <= 10) - { - const unsigned int num = number.getBitRangeAsInt (0, 10); - - for (unsigned int i = num / 2; --i > 1;) - if (num % i == 0) - return false; - - return true; - } - else - { - if (number.findGreatestCommonDivisor (2 * 3 * 5 * 7 * 11 * 13 * 17 * 19 * 23) != 1) - return false; - - return passesMillerRabin (number, certainty); - } -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_cryptography/encryption/juce_Primes.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_cryptography/encryption/juce_Primes.h deleted file mode 100644 index f8f47764d0..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_cryptography/encryption/juce_Primes.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_PRIMES_H_INCLUDED -#define JUCE_PRIMES_H_INCLUDED - - -//============================================================================== -/** - Prime number creation class. - - This class contains static methods for generating and testing prime numbers. - - @see BigInteger -*/ -class JUCE_API Primes -{ -public: - //============================================================================== - /** Creates a random prime number with a given bit-length. - - The certainty parameter specifies how many iterations to use when testing - for primality. A safe value might be anything over about 20-30. - - The randomSeeds parameter lets you optionally pass it a set of values with - which to seed the random number generation, improving the security of the - keys generated. - */ - static BigInteger createProbablePrime (int bitLength, - int certainty, - const int* randomSeeds = 0, - int numRandomSeeds = 0); - - /** Tests a number to see if it's prime. - - This isn't a bulletproof test, it uses a Miller-Rabin test to determine - whether the number is prime. - - The certainty parameter specifies how many iterations to use when testing - a - safe value might be anything over about 20-30. - */ - static bool isProbablyPrime (const BigInteger& number, int certainty); - - -private: - Primes(); - - JUCE_DECLARE_NON_COPYABLE (Primes) -}; - - -#endif // JUCE_PRIMES_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_cryptography/encryption/juce_RSAKey.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_cryptography/encryption/juce_RSAKey.cpp deleted file mode 100644 index 2c1e9d8154..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_cryptography/encryption/juce_RSAKey.cpp +++ /dev/null @@ -1,135 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -RSAKey::RSAKey() -{ -} - -RSAKey::RSAKey (const String& s) -{ - if (s.containsChar (',')) - { - part1.parseString (s.upToFirstOccurrenceOf (",", false, false), 16); - part2.parseString (s.fromFirstOccurrenceOf (",", false, false), 16); - } - else - { - // the string needs to be two hex numbers, comma-separated.. - jassertfalse; - } -} - -RSAKey::~RSAKey() -{ -} - -bool RSAKey::operator== (const RSAKey& other) const noexcept -{ - return part1 == other.part1 && part2 == other.part2; -} - -bool RSAKey::operator!= (const RSAKey& other) const noexcept -{ - return ! operator== (other); -} - -bool RSAKey::isValid() const noexcept -{ - return operator!= (RSAKey()); -} - -String RSAKey::toString() const -{ - return part1.toString (16) + "," + part2.toString (16); -} - -bool RSAKey::applyToValue (BigInteger& value) const -{ - if (part1.isZero() || part2.isZero() || value <= 0) - { - jassertfalse; // using an uninitialised key - value.clear(); - return false; - } - - BigInteger result; - - while (! value.isZero()) - { - result *= part2; - - BigInteger remainder; - value.divideBy (part2, remainder); - - remainder.exponentModulo (part1, part2); - - result += remainder; - } - - value.swapWith (result); - return true; -} - -BigInteger RSAKey::findBestCommonDivisor (const BigInteger& p, const BigInteger& q) -{ - // try 3, 5, 9, 17, etc first because these only contain 2 bits and so - // are fast to divide + multiply - for (int i = 2; i <= 65536; i *= 2) - { - const BigInteger e (1 + i); - - if (e.findGreatestCommonDivisor (p).isOne() && e.findGreatestCommonDivisor (q).isOne()) - return e; - } - - BigInteger e (4); - - while (! (e.findGreatestCommonDivisor (p).isOne() && e.findGreatestCommonDivisor (q).isOne())) - ++e; - - return e; -} - -void RSAKey::createKeyPair (RSAKey& publicKey, RSAKey& privateKey, - const int numBits, const int* randomSeeds, const int numRandomSeeds) -{ - jassert (numBits > 16); // not much point using less than this.. - jassert (numRandomSeeds == 0 || numRandomSeeds >= 2); // you need to provide plenty of seeds here! - - BigInteger p (Primes::createProbablePrime (numBits / 2, 30, randomSeeds, numRandomSeeds / 2)); - BigInteger q (Primes::createProbablePrime (numBits - numBits / 2, 30, randomSeeds == nullptr ? 0 : (randomSeeds + numRandomSeeds / 2), numRandomSeeds - numRandomSeeds / 2)); - - const BigInteger n (p * q); - const BigInteger m (--p * --q); - const BigInteger e (findBestCommonDivisor (p, q)); - - BigInteger d (e); - d.inverseModulo (m); - - publicKey.part1 = e; - publicKey.part2 = n; - - privateKey.part1 = d; - privateKey.part2 = n; -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_cryptography/encryption/juce_RSAKey.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_cryptography/encryption/juce_RSAKey.h deleted file mode 100644 index 8df7eeca54..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_cryptography/encryption/juce_RSAKey.h +++ /dev/null @@ -1,174 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_RSAKEY_H_INCLUDED -#define JUCE_RSAKEY_H_INCLUDED - - -//============================================================================== -/** - RSA public/private key-pair encryption class. - - An object of this type makes up one half of a public/private RSA key pair. Use the - createKeyPair() method to create a matching pair for encoding/decoding. - - If you need to use this class in conjunction with a compatible enc/decryption - algorithm on a webserver, you can achieve the same thing in PHP like this: - - @code - include ('Math/BigInteger.php'); // get this from: phpseclib.sourceforge.net - - function applyToValue ($message, $key_part1, $key_part2) - { - $result = new Math_BigInteger(); - $zero = new Math_BigInteger(); - $value = new Math_BigInteger (strrev ($message), 256); - $part1 = new Math_BigInteger ($key_part1, 16); - $part2 = new Math_BigInteger ($key_part2, 16); - - while (! $value->equals ($zero)) - { - $result = $result->multiply ($part2); - list ($value, $remainder) = $value->divide ($part2); - $result = $result->add ($remainder->modPow ($part1, $part2)); - } - - return strrev ($result->toBytes()); - } - @endcode - - ..or in Java with something like this: - - @code - public class RSAKey - { - static BigInteger applyToValue (BigInteger value, String key_part1, String key_part2) - { - BigInteger result = BigInteger.ZERO; - BigInteger part1 = new BigInteger (key_part1, 16); - BigInteger part2 = new BigInteger (key_part2, 16); - - if (part1.equals (BigInteger.ZERO) || part2.equals (BigInteger.ZERO) - || value.compareTo (BigInteger.ZERO) <= 0) - return result; - - while (! value.equals (BigInteger.ZERO)) - { - result = result.multiply (part2); - BigInteger[] div = value.divideAndRemainder (part2); - value = div[0]; - result = result.add (div[1].modPow (part1, part2)); - } - - return result; - } - } - @endcode - - Disclaimer: neither of the code snippets above are tested! Please let me know if you have - any corrections for them! -*/ -class JUCE_API RSAKey -{ -public: - //============================================================================== - /** Creates a null key object. - - Initialise a pair of objects for use with the createKeyPair() method. - */ - RSAKey(); - - /** Loads a key from an encoded string representation. - - This reloads a key from a string created by the toString() method. - */ - explicit RSAKey (const String& stringRepresentation); - - /** Destructor. */ - ~RSAKey(); - - bool operator== (const RSAKey& other) const noexcept; - bool operator!= (const RSAKey& other) const noexcept; - - //============================================================================== - /** Turns the key into a string representation. - This can be reloaded using the constructor that takes a string. - */ - String toString() const; - - /** Returns true if the object is a valid key, or false if it was created by - the default constructor. - */ - bool isValid() const noexcept; - - //============================================================================== - /** Encodes or decodes a value. - - Call this on the public key object to encode some data, then use the matching - private key object to decode it. - - Returns false if the operation couldn't be completed, e.g. if this key hasn't been - initialised correctly. - - NOTE: This method dumbly applies this key to this data. If you encode some data - and then try to decode it with a key that doesn't match, this method will still - happily do its job and return true, but the result won't be what you were expecting. - It's your responsibility to check that the result is what you wanted. - */ - bool applyToValue (BigInteger& value) const; - - //============================================================================== - /** Creates a public/private key-pair. - - Each key will perform one-way encryption that can only be reversed by - using the other key. - - The numBits parameter specifies the size of key, e.g. 128, 256, 512 bit. Bigger - sizes are more secure, but this method will take longer to execute. - - The randomSeeds parameter lets you optionally pass it a set of values with - which to seed the random number generation, improving the security of the - keys generated. If you supply these, make sure you provide more than 2 values, - and the more your provide, the better the security. - */ - static void createKeyPair (RSAKey& publicKey, - RSAKey& privateKey, - int numBits, - const int* randomSeeds = nullptr, - int numRandomSeeds = 0); - - -protected: - //============================================================================== - BigInteger part1, part2; - -private: - //============================================================================== - static BigInteger findBestCommonDivisor (const BigInteger& p, const BigInteger& q); - - JUCE_LEAK_DETECTOR (RSAKey) -}; - - -#endif // JUCE_RSAKEY_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_cryptography/hashing/juce_MD5.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_cryptography/hashing/juce_MD5.cpp deleted file mode 100644 index 889f6d3706..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_cryptography/hashing/juce_MD5.cpp +++ /dev/null @@ -1,336 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -class MD5Generator -{ -public: - MD5Generator() noexcept - { - state[0] = 0x67452301; - state[1] = 0xefcdab89; - state[2] = 0x98badcfe; - state[3] = 0x10325476; - - count[0] = 0; - count[1] = 0; - } - - void processBlock (const void* data, size_t dataSize) noexcept - { - int bufferPos = ((count[0] >> 3) & 0x3F); - - count[0] += (uint32) (dataSize << 3); - - if (count[0] < ((uint32) dataSize << 3)) - count[1]++; - - count[1] += (uint32) (dataSize >> 29); - - const size_t spaceLeft = 64 - (size_t) bufferPos; - size_t i = 0; - - if (dataSize >= spaceLeft) - { - memcpy (buffer + bufferPos, data, spaceLeft); - transform (buffer); - - for (i = spaceLeft; i + 64 <= dataSize; i += 64) - transform (static_cast (data) + i); - - bufferPos = 0; - } - - memcpy (buffer + bufferPos, static_cast (data) + i, dataSize - i); - } - - void transform (const void* bufferToTransform) noexcept - { - uint32 a = state[0]; - uint32 b = state[1]; - uint32 c = state[2]; - uint32 d = state[3]; - uint32 x[16]; - - encode (x, bufferToTransform, 64); - - enum Constants - { - S11 = 7, S12 = 12, S13 = 17, S14 = 22, S21 = 5, S22 = 9, S23 = 14, S24 = 20, - S31 = 4, S32 = 11, S33 = 16, S34 = 23, S41 = 6, S42 = 10, S43 = 15, S44 = 21 - }; - - FF (a, b, c, d, x[ 0], S11, 0xd76aa478); FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); - FF (c, d, a, b, x[ 2], S13, 0x242070db); FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); - FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); FF (d, a, b, c, x[ 5], S12, 0x4787c62a); - FF (c, d, a, b, x[ 6], S13, 0xa8304613); FF (b, c, d, a, x[ 7], S14, 0xfd469501); - FF (a, b, c, d, x[ 8], S11, 0x698098d8); FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); - FF (c, d, a, b, x[10], S13, 0xffff5bb1); FF (b, c, d, a, x[11], S14, 0x895cd7be); - FF (a, b, c, d, x[12], S11, 0x6b901122); FF (d, a, b, c, x[13], S12, 0xfd987193); - FF (c, d, a, b, x[14], S13, 0xa679438e); FF (b, c, d, a, x[15], S14, 0x49b40821); - - GG (a, b, c, d, x[ 1], S21, 0xf61e2562); GG (d, a, b, c, x[ 6], S22, 0xc040b340); - GG (c, d, a, b, x[11], S23, 0x265e5a51); GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); - GG (a, b, c, d, x[ 5], S21, 0xd62f105d); GG (d, a, b, c, x[10], S22, 0x02441453); - GG (c, d, a, b, x[15], S23, 0xd8a1e681); GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); - GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); GG (d, a, b, c, x[14], S22, 0xc33707d6); - GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); GG (b, c, d, a, x[ 8], S24, 0x455a14ed); - GG (a, b, c, d, x[13], S21, 0xa9e3e905); GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); - GG (c, d, a, b, x[ 7], S23, 0x676f02d9); GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); - - HH (a, b, c, d, x[ 5], S31, 0xfffa3942); HH (d, a, b, c, x[ 8], S32, 0x8771f681); - HH (c, d, a, b, x[11], S33, 0x6d9d6122); HH (b, c, d, a, x[14], S34, 0xfde5380c); - HH (a, b, c, d, x[ 1], S31, 0xa4beea44); HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); - HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); HH (b, c, d, a, x[10], S34, 0xbebfbc70); - HH (a, b, c, d, x[13], S31, 0x289b7ec6); HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); - HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); HH (b, c, d, a, x[ 6], S34, 0x04881d05); - HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); HH (d, a, b, c, x[12], S32, 0xe6db99e5); - HH (c, d, a, b, x[15], S33, 0x1fa27cf8); HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); - - II (a, b, c, d, x[ 0], S41, 0xf4292244); II (d, a, b, c, x[ 7], S42, 0x432aff97); - II (c, d, a, b, x[14], S43, 0xab9423a7); II (b, c, d, a, x[ 5], S44, 0xfc93a039); - II (a, b, c, d, x[12], S41, 0x655b59c3); II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); - II (c, d, a, b, x[10], S43, 0xffeff47d); II (b, c, d, a, x[ 1], S44, 0x85845dd1); - II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); II (d, a, b, c, x[15], S42, 0xfe2ce6e0); - II (c, d, a, b, x[ 6], S43, 0xa3014314); II (b, c, d, a, x[13], S44, 0x4e0811a1); - II (a, b, c, d, x[ 4], S41, 0xf7537e82); II (d, a, b, c, x[11], S42, 0xbd3af235); - II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); II (b, c, d, a, x[ 9], S44, 0xeb86d391); - - state[0] += a; - state[1] += b; - state[2] += c; - state[3] += d; - - zerostruct (x); - } - - void finish (void* result) noexcept - { - unsigned char encodedLength[8]; - encode (encodedLength, count, 8); - - // Pad out to 56 mod 64. - const int index = (count[0] >> 3) & 0x3f; - - const int paddingLength = (index < 56) ? (56 - index) - : (120 - index); - - uint8 paddingBuffer[64] = { 0x80 }; // first byte is 0x80, remaining bytes are zero. - processBlock (paddingBuffer, (size_t) paddingLength); - - processBlock (encodedLength, 8); - - encode (result, state, 16); - zerostruct (buffer); - } - -private: - uint8 buffer [64]; - uint32 state [4]; - uint32 count [2]; - - static void encode (void* const output, const void* const input, const int numBytes) noexcept - { - for (int i = 0; i < (numBytes >> 2); ++i) - static_cast (output)[i] = ByteOrder::swapIfBigEndian (static_cast (input) [i]); - } - - static inline uint32 rotateLeft (const uint32 x, const uint32 n) noexcept { return (x << n) | (x >> (32 - n)); } - - static inline uint32 F (const uint32 x, const uint32 y, const uint32 z) noexcept { return (x & y) | (~x & z); } - static inline uint32 G (const uint32 x, const uint32 y, const uint32 z) noexcept { return (x & z) | (y & ~z); } - static inline uint32 H (const uint32 x, const uint32 y, const uint32 z) noexcept { return x ^ y ^ z; } - static inline uint32 I (const uint32 x, const uint32 y, const uint32 z) noexcept { return y ^ (x | ~z); } - - static void FF (uint32& a, const uint32 b, const uint32 c, const uint32 d, const uint32 x, const uint32 s, const uint32 ac) noexcept - { - a += F (b, c, d) + x + ac; - a = rotateLeft (a, s) + b; - } - - static void GG (uint32& a, const uint32 b, const uint32 c, const uint32 d, const uint32 x, const uint32 s, const uint32 ac) noexcept - { - a += G (b, c, d) + x + ac; - a = rotateLeft (a, s) + b; - } - - static void HH (uint32& a, const uint32 b, const uint32 c, const uint32 d, const uint32 x, const uint32 s, const uint32 ac) noexcept - { - a += H (b, c, d) + x + ac; - a = rotateLeft (a, s) + b; - } - - static void II (uint32& a, const uint32 b, const uint32 c, const uint32 d, const uint32 x, const uint32 s, const uint32 ac) noexcept - { - a += I (b, c, d) + x + ac; - a = rotateLeft (a, s) + b; - } -}; - -//============================================================================== -MD5::MD5() noexcept -{ - zerostruct (result); -} - -MD5::MD5 (const MD5& other) noexcept -{ - memcpy (result, other.result, sizeof (result)); -} - -MD5& MD5::operator= (const MD5& other) noexcept -{ - memcpy (result, other.result, sizeof (result)); - return *this; -} - -//============================================================================== -MD5::MD5 (const MemoryBlock& data) noexcept -{ - processData (data.getData(), data.getSize()); -} - -MD5::MD5 (const void* data, const size_t numBytes) noexcept -{ - processData (data, numBytes); -} - -MD5::MD5 (CharPointer_UTF8 utf8) noexcept -{ - jassert (utf8.getAddress() != nullptr); - processData (utf8.getAddress(), utf8.sizeInBytes() - 1); -} - -MD5 MD5::fromUTF32 (StringRef text) -{ - MD5Generator generator; - String::CharPointerType t (text.text); - - while (! t.isEmpty()) - { - uint32 unicodeChar = ByteOrder::swapIfBigEndian ((uint32) t.getAndAdvance()); - generator.processBlock (&unicodeChar, sizeof (unicodeChar)); - } - - MD5 m; - generator.finish (m.result); - return m; -} - -MD5::MD5 (InputStream& input, int64 numBytesToRead) -{ - processStream (input, numBytesToRead); -} - -MD5::MD5 (const File& file) -{ - FileInputStream fin (file); - - if (fin.getStatus().wasOk()) - processStream (fin, -1); - else - zerostruct (result); -} - -MD5::~MD5() noexcept {} - -void MD5::processData (const void* data, size_t numBytes) noexcept -{ - MD5Generator generator; - generator.processBlock (data, numBytes); - generator.finish (result); -} - -void MD5::processStream (InputStream& input, int64 numBytesToRead) -{ - MD5Generator generator; - - if (numBytesToRead < 0) - numBytesToRead = std::numeric_limits::max(); - - while (numBytesToRead > 0) - { - uint8 tempBuffer [512]; - const int bytesRead = input.read (tempBuffer, (int) jmin (numBytesToRead, (int64) sizeof (tempBuffer))); - - if (bytesRead <= 0) - break; - - numBytesToRead -= bytesRead; - generator.processBlock (tempBuffer, (size_t) bytesRead); - } - - generator.finish (result); -} - -//============================================================================== -MemoryBlock MD5::getRawChecksumData() const -{ - return MemoryBlock (result, sizeof (result)); -} - -String MD5::toHexString() const -{ - return String::toHexString (result, sizeof (result), 0); -} - -//============================================================================== -bool MD5::operator== (const MD5& other) const noexcept { return memcmp (result, other.result, sizeof (result)) == 0; } -bool MD5::operator!= (const MD5& other) const noexcept { return ! operator== (other); } - - -//============================================================================== -#if JUCE_UNIT_TESTS - -class MD5Tests : public UnitTest -{ -public: - MD5Tests() : UnitTest ("MD5") {} - - void test (const char* input, const char* expected) - { - { - MD5 hash (input, strlen (input)); - expectEquals (hash.toHexString(), String (expected)); - } - - { - MemoryInputStream m (input, strlen (input), false); - MD5 hash (m); - expectEquals (hash.toHexString(), String (expected)); - } - } - - void runTest() - { - beginTest ("MD5"); - - test ("", "d41d8cd98f00b204e9800998ecf8427e"); - test ("The quick brown fox jumps over the lazy dog", "9e107d9d372bb6826bd81d3542a419d6"); - test ("The quick brown fox jumps over the lazy dog.", "e4d909c290d0fb1ca068ffaddf22cbd0"); - } -}; - -static MD5Tests MD5UnitTests; - -#endif diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_cryptography/hashing/juce_MD5.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_cryptography/hashing/juce_MD5.h deleted file mode 100644 index f984cf5dc5..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_cryptography/hashing/juce_MD5.h +++ /dev/null @@ -1,119 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_MD5_H_INCLUDED -#define JUCE_MD5_H_INCLUDED - - -//============================================================================== -/** - MD5 checksum class. - - Create one of these with a block of source data or a stream, and it calculates - the MD5 checksum of that data. - - You can then retrieve this checksum as a 16-byte block, or as a hex string. - @see SHA256 -*/ -class JUCE_API MD5 -{ -public: - //============================================================================== - /** Creates a null MD5 object. */ - MD5() noexcept; - - /** Creates a copy of another MD5. */ - MD5 (const MD5&) noexcept; - - /** Copies another MD5. */ - MD5& operator= (const MD5&) noexcept; - - //============================================================================== - /** Creates a checksum for a block of binary data. */ - explicit MD5 (const MemoryBlock&) noexcept; - - /** Creates a checksum for a block of binary data. */ - MD5 (const void* data, size_t numBytes) noexcept; - - /** Creates a checksum for the input from a stream. - - This will read up to the given number of bytes from the stream, and produce the - checksum of that. If the number of bytes to read is negative, it'll read - until the stream is exhausted. - */ - MD5 (InputStream& input, int64 numBytesToRead = -1); - - /** Creates a checksum for the contents of a file. */ - explicit MD5 (const File&); - - /** Creates a checksum of the characters in a UTF-8 buffer. - E.g. - @code MD5 checksum (myString.toUTF8()); - @endcode - */ - explicit MD5 (CharPointer_UTF8 utf8Text) noexcept; - - /** Destructor. */ - ~MD5() noexcept; - - //============================================================================== - /** Returns the checksum as a 16-byte block of data. */ - MemoryBlock getRawChecksumData() const; - - /** Returns a pointer to the 16-byte array of result data. */ - const uint8* getChecksumDataArray() const noexcept { return result; } - - /** Returns the checksum as a 32-digit hex string. */ - String toHexString() const; - - /** Creates an MD5 from a little-endian UTF-32 encoded string. - - Note that this method is provided for backwards-compatibility with the old - version of this class, which had a constructor that took a string and performed - this operation on it. In new code, you shouldn't use this, and are recommended to - use the constructor that takes a CharPointer_UTF8 instead. - */ - static MD5 fromUTF32 (StringRef); - - //============================================================================== - bool operator== (const MD5&) const noexcept; - bool operator!= (const MD5&) const noexcept; - - -private: - //============================================================================== - uint8 result [16]; - - void processData (const void*, size_t) noexcept; - void processStream (InputStream&, int64); - - // This private constructor is declared here to prevent you accidentally passing a - // String and having it unexpectedly call the constructor that takes a File. - explicit MD5 (const String&) JUCE_DELETED_FUNCTION; - - JUCE_LEAK_DETECTOR (MD5) -}; - - -#endif // JUCE_MD5_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_cryptography/hashing/juce_SHA256.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_cryptography/hashing/juce_SHA256.cpp deleted file mode 100644 index 15e6840c07..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_cryptography/hashing/juce_SHA256.cpp +++ /dev/null @@ -1,275 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -class SHA256Processor -{ -public: - SHA256Processor() noexcept - : length (0) - { - state[0] = 0x6a09e667; - state[1] = 0xbb67ae85; - state[2] = 0x3c6ef372; - state[3] = 0xa54ff53a; - state[4] = 0x510e527f; - state[5] = 0x9b05688c; - state[6] = 0x1f83d9ab; - state[7] = 0x5be0cd19; - } - - // expects 64 bytes of data - void processFullBlock (const void* const data) noexcept - { - const uint32 constants[] = - { - 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, - 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, - 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, - 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, - 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, - 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, - 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, - 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 - }; - - uint32 block[16], s[8]; - memcpy (s, state, sizeof (s)); - - for (int i = 0; i < 16; ++i) - block[i] = ByteOrder::bigEndianInt (addBytesToPointer (data, i * 4)); - - for (uint32 j = 0; j < 64; j += 16) - { - #define JUCE_SHA256(i) \ - s[(7 - i) & 7] += S1 (s[(4 - i) & 7]) + ch (s[(4 - i) & 7], s[(5 - i) & 7], s[(6 - i) & 7]) + constants[i + j] \ - + (j != 0 ? (block[i & 15] += s1 (block[(i - 2) & 15]) + block[(i - 7) & 15] + s0 (block[(i - 15) & 15])) \ - : block[i]); \ - s[(3 - i) & 7] += s[(7 - i) & 7]; \ - s[(7 - i) & 7] += S0 (s[(0 - i) & 7]) + maj (s[(0 - i) & 7], s[(1 - i) & 7], s[(2 - i) & 7]) - - JUCE_SHA256(0); JUCE_SHA256(1); JUCE_SHA256(2); JUCE_SHA256(3); JUCE_SHA256(4); JUCE_SHA256(5); JUCE_SHA256(6); JUCE_SHA256(7); - JUCE_SHA256(8); JUCE_SHA256(9); JUCE_SHA256(10); JUCE_SHA256(11); JUCE_SHA256(12); JUCE_SHA256(13); JUCE_SHA256(14); JUCE_SHA256(15); - #undef JUCE_SHA256 - } - - for (int i = 0; i < 8; ++i) - state[i] += s[i]; - - length += 64; - } - - void processFinalBlock (const void* const data, unsigned int numBytes) noexcept - { - jassert (numBytes < 64); - - length += numBytes; - length *= 8; // (the length is stored as a count of bits, not bytes) - - uint8 finalBlocks[128]; - - memcpy (finalBlocks, data, numBytes); - finalBlocks [numBytes++] = 128; // append a '1' bit - - while (numBytes != 56 && numBytes < 64 + 56) - finalBlocks [numBytes++] = 0; // pad with zeros.. - - for (int i = 8; --i >= 0;) - finalBlocks [numBytes++] = (uint8) (length >> (i * 8)); // append the length. - - jassert (numBytes == 64 || numBytes == 128); - - processFullBlock (finalBlocks); - - if (numBytes > 64) - processFullBlock (finalBlocks + 64); - } - - void copyResult (uint8* result) const noexcept - { - for (int i = 0; i < 8; ++i) - { - *result++ = (uint8) (state[i] >> 24); - *result++ = (uint8) (state[i] >> 16); - *result++ = (uint8) (state[i] >> 8); - *result++ = (uint8) state[i]; - } - } - - void processStream (InputStream& input, int64 numBytesToRead, uint8* const result) - { - if (numBytesToRead < 0) - numBytesToRead = std::numeric_limits::max(); - - for (;;) - { - uint8 buffer [64]; - const int bytesRead = input.read (buffer, (int) jmin (numBytesToRead, (int64) sizeof (buffer))); - - if (bytesRead < (int) sizeof (buffer)) - { - processFinalBlock (buffer, (unsigned int) bytesRead); - break; - } - - numBytesToRead -= sizeof (buffer); - processFullBlock (buffer); - } - - copyResult (result); - } - -private: - uint32 state[8]; - uint64 length; - - static inline uint32 rotate (const uint32 x, const uint32 y) noexcept { return (x >> y) | (x << (32 - y)); } - static inline uint32 ch (const uint32 x, const uint32 y, const uint32 z) noexcept { return z ^ ((y ^ z) & x); } - static inline uint32 maj (const uint32 x, const uint32 y, const uint32 z) noexcept { return y ^ ((y ^ z) & (x ^ y)); } - - static inline uint32 s0 (const uint32 x) noexcept { return rotate (x, 7) ^ rotate (x, 18) ^ (x >> 3); } - static inline uint32 s1 (const uint32 x) noexcept { return rotate (x, 17) ^ rotate (x, 19) ^ (x >> 10); } - static inline uint32 S0 (const uint32 x) noexcept { return rotate (x, 2) ^ rotate (x, 13) ^ rotate (x, 22); } - static inline uint32 S1 (const uint32 x) noexcept { return rotate (x, 6) ^ rotate (x, 11) ^ rotate (x, 25); } - - JUCE_DECLARE_NON_COPYABLE (SHA256Processor) -}; - -//============================================================================== -SHA256::SHA256() noexcept -{ - zerostruct (result); -} - -SHA256::~SHA256() noexcept {} - -SHA256::SHA256 (const SHA256& other) noexcept -{ - memcpy (result, other.result, sizeof (result)); -} - -SHA256& SHA256::operator= (const SHA256& other) noexcept -{ - memcpy (result, other.result, sizeof (result)); - return *this; -} - -SHA256::SHA256 (const MemoryBlock& data) -{ - process (data.getData(), data.getSize()); -} - -SHA256::SHA256 (const void* const data, const size_t numBytes) -{ - process (data, numBytes); -} - -SHA256::SHA256 (InputStream& input, const int64 numBytesToRead) -{ - SHA256Processor processor; - processor.processStream (input, numBytesToRead, result); -} - -SHA256::SHA256 (const File& file) -{ - FileInputStream fin (file); - - if (fin.getStatus().wasOk()) - { - SHA256Processor processor; - processor.processStream (fin, -1, result); - } - else - { - zerostruct (result); - } -} - -SHA256::SHA256 (CharPointer_UTF8 utf8) noexcept -{ - jassert (utf8.getAddress() != nullptr); - process (utf8.getAddress(), utf8.sizeInBytes() - 1); -} - -void SHA256::process (const void* const data, size_t numBytes) -{ - MemoryInputStream m (data, numBytes, false); - SHA256Processor processor; - processor.processStream (m, -1, result); -} - -MemoryBlock SHA256::getRawData() const -{ - return MemoryBlock (result, sizeof (result)); -} - -String SHA256::toHexString() const -{ - return String::toHexString (result, sizeof (result), 0); -} - -bool SHA256::operator== (const SHA256& other) const noexcept { return memcmp (result, other.result, sizeof (result)) == 0; } -bool SHA256::operator!= (const SHA256& other) const noexcept { return ! operator== (other); } - - -//============================================================================== -#if JUCE_UNIT_TESTS - -class SHA256Tests : public UnitTest -{ -public: - SHA256Tests() : UnitTest ("SHA-256") {} - - void test (const char* input, const char* expected) - { - { - SHA256 hash (input, strlen (input)); - expectEquals (hash.toHexString(), String (expected)); - } - - { - CharPointer_UTF8 utf8 (input); - SHA256 hash (utf8); - expectEquals (hash.toHexString(), String (expected)); - } - - { - MemoryInputStream m (input, strlen (input), false); - SHA256 hash (m); - expectEquals (hash.toHexString(), String (expected)); - } - } - - void runTest() - { - beginTest ("SHA256"); - - test ("", "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"); - test ("The quick brown fox jumps over the lazy dog", "d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592"); - test ("The quick brown fox jumps over the lazy dog.", "ef537f25c895bfa782526529a9b63d97aa631564d5d789c2b765448c8635fb6c"); - } -}; - -static SHA256Tests sha256UnitTests; - -#endif diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_cryptography/hashing/juce_SHA256.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_cryptography/hashing/juce_SHA256.h deleted file mode 100644 index d3d8e7f55d..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_cryptography/hashing/juce_SHA256.h +++ /dev/null @@ -1,107 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_SHA256_H_INCLUDED -#define JUCE_SHA256_H_INCLUDED - - -//============================================================================== -/** - SHA-256 secure hash generator. - - Create one of these objects from a block of source data or a stream, and it - calculates the SHA-256 hash of that data. - - You can retrieve the hash as a raw 32-byte block, or as a 64-digit hex string. - @see MD5 -*/ -class JUCE_API SHA256 -{ -public: - //============================================================================== - /** Creates an empty SHA256 object. - The default constructor just creates a hash filled with zeros. (This is not - equal to the hash of an empty block of data). - */ - SHA256() noexcept; - - /** Destructor. */ - ~SHA256() noexcept; - - /** Creates a copy of another SHA256. */ - SHA256 (const SHA256& other) noexcept; - - /** Copies another SHA256. */ - SHA256& operator= (const SHA256& other) noexcept; - - //============================================================================== - /** Creates a hash from a block of raw data. */ - explicit SHA256 (const MemoryBlock& data); - - /** Creates a hash from a block of raw data. */ - SHA256 (const void* data, size_t numBytes); - - /** Creates a hash from the contents of a stream. - - This will read from the stream until the stream is exhausted, or until - maxBytesToRead bytes have been read. If maxBytesToRead is negative, the entire - stream will be read. - */ - SHA256 (InputStream& input, int64 maxBytesToRead = -1); - - /** Reads a file and generates the hash of its contents. - If the file can't be opened, the hash will be left uninitialised (i.e. full - of zeros). - */ - explicit SHA256 (const File& file); - - /** Creates a checksum from a UTF-8 buffer. - E.g. - @code SHA256 checksum (myString.toUTF8()); - @endcode - */ - explicit SHA256 (CharPointer_UTF8 utf8Text) noexcept; - - //============================================================================== - /** Returns the hash as a 32-byte block of data. */ - MemoryBlock getRawData() const; - - /** Returns the checksum as a 64-digit hex string. */ - String toHexString() const; - - //============================================================================== - bool operator== (const SHA256&) const noexcept; - bool operator!= (const SHA256&) const noexcept; - - -private: - //============================================================================== - uint8 result [32]; - void process (const void*, size_t); - - JUCE_LEAK_DETECTOR (SHA256) -}; - - -#endif // JUCE_SHA256_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_cryptography/juce_cryptography.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_cryptography/juce_cryptography.cpp deleted file mode 100644 index 63e37a8cea..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_cryptography/juce_cryptography.cpp +++ /dev/null @@ -1,49 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#if defined (JUCE_CRYPTOGRAPHY_H_INCLUDED) && ! JUCE_AMALGAMATED_INCLUDE - /* When you add this cpp file to your project, you mustn't include it in a file where you've - already included any other headers - just put it inside a file on its own, possibly with your config - flags preceding it, but don't include anything else. That also includes avoiding any automatic prefix - header files that the compiler may be using. - */ - #error "Incorrect use of JUCE cpp file" -#endif - -// Your project must contain an AppConfig.h file with your project-specific settings in it, -// and your header search path must make it accessible to the module's files. -#include "AppConfig.h" - -#include "juce_cryptography.h" - -namespace juce -{ - -#include "encryption/juce_BlowFish.cpp" -#include "encryption/juce_Primes.cpp" -#include "encryption/juce_RSAKey.cpp" -#include "hashing/juce_MD5.cpp" -#include "hashing/juce_SHA256.cpp" - -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_cryptography/juce_cryptography.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_cryptography/juce_cryptography.h index 5ab40809ff..860c0221c7 100644 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_cryptography/juce_cryptography.h +++ b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_cryptography/juce_cryptography.h @@ -1,42 +1,5 @@ -/* - ============================================================================== +// This is an auto-generated file to redirect any included +// module headers to the correct external folder. - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. +#include "../../../../../modules/juce_cryptography/juce_cryptography.h" - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_CRYPTOGRAPHY_H_INCLUDED -#define JUCE_CRYPTOGRAPHY_H_INCLUDED - -//============================================================================= -#include "../juce_core/juce_core.h" - -namespace juce -{ - -#include "encryption/juce_BlowFish.h" -#include "encryption/juce_Primes.h" -#include "encryption/juce_RSAKey.h" -#include "hashing/juce_MD5.h" -#include "hashing/juce_SHA256.h" - -} - -#endif // JUCE_CRYPTOGRAPHY_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_cryptography/juce_cryptography.mm b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_cryptography/juce_cryptography.mm deleted file mode 100644 index 7c3e4bfd32..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_cryptography/juce_cryptography.mm +++ /dev/null @@ -1,25 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#include "juce_cryptography.cpp" diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_cryptography/juce_module_info b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_cryptography/juce_module_info deleted file mode 100644 index 6960eef0d3..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_cryptography/juce_module_info +++ /dev/null @@ -1,18 +0,0 @@ -{ - "id": "juce_cryptography", - "name": "JUCE cryptography classes", - "version": "3.0.8", - "description": "Classes for various basic cryptography functions, including RSA, Blowfish, MD5, SHA, etc.", - "website": "http://www.juce.com/juce", - "license": "GPL/Commercial", - - "dependencies": [ { "id": "juce_core", "version": "matching" } ], - - "include": "juce_cryptography.h", - - "compile": [ { "file": "juce_cryptography.cpp", "target": "! xcode" }, - { "file": "juce_cryptography.mm", "target": "xcode" } ], - - "browse": [ "encryption/*", - "hashing/*" ] -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_data_structures/app_properties/juce_ApplicationProperties.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_data_structures/app_properties/juce_ApplicationProperties.cpp deleted file mode 100644 index 6db825e896..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_data_structures/app_properties/juce_ApplicationProperties.cpp +++ /dev/null @@ -1,102 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -ApplicationProperties::ApplicationProperties() - : commonSettingsAreReadOnly (0) -{ -} - -ApplicationProperties::~ApplicationProperties() -{ - closeFiles(); -} - -//============================================================================== -void ApplicationProperties::setStorageParameters (const PropertiesFile::Options& newOptions) -{ - options = newOptions; -} - -//============================================================================== -void ApplicationProperties::openFiles() -{ - // You need to call setStorageParameters() before trying to get hold of the properties! - jassert (options.applicationName.isNotEmpty()); - - if (options.applicationName.isNotEmpty()) - { - PropertiesFile::Options o (options); - - if (userProps == nullptr) - { - o.commonToAllUsers = false; - userProps = new PropertiesFile (o); - } - - if (commonProps == nullptr) - { - o.commonToAllUsers = true; - commonProps = new PropertiesFile (o); - } - - userProps->setFallbackPropertySet (commonProps); - } -} - -PropertiesFile* ApplicationProperties::getUserSettings() -{ - if (userProps == nullptr) - openFiles(); - - return userProps; -} - -PropertiesFile* ApplicationProperties::getCommonSettings (const bool returnUserPropsIfReadOnly) -{ - if (commonProps == nullptr) - openFiles(); - - if (returnUserPropsIfReadOnly) - { - if (commonSettingsAreReadOnly == 0) - commonSettingsAreReadOnly = commonProps->save() ? -1 : 1; - - if (commonSettingsAreReadOnly > 0) - return userProps; - } - - return commonProps; -} - -bool ApplicationProperties::saveIfNeeded() -{ - return (userProps == nullptr || userProps->saveIfNeeded()) - && (commonProps == nullptr || commonProps->saveIfNeeded()); -} - -void ApplicationProperties::closeFiles() -{ - userProps = nullptr; - commonProps = nullptr; -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_data_structures/app_properties/juce_ApplicationProperties.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_data_structures/app_properties/juce_ApplicationProperties.h deleted file mode 100644 index 21edbc2afe..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_data_structures/app_properties/juce_ApplicationProperties.h +++ /dev/null @@ -1,132 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_APPLICATIONPROPERTIES_H_INCLUDED -#define JUCE_APPLICATIONPROPERTIES_H_INCLUDED - - -//============================================================================== -/** - Manages a collection of properties. - - This is a slightly higher-level wrapper for managing PropertiesFile objects. - - It holds two different PropertiesFile objects internally, one for user-specific - settings (stored in your user directory), and one for settings that are common to - all users (stored in a folder accessible to all users). - - The class manages the creation of these files on-demand, allowing access via the - getUserSettings() and getCommonSettings() methods. - - After creating an instance of an ApplicationProperties object, you should first - of all call setStorageParameters() to tell it the parameters to use to create - its files. - - @see PropertiesFile -*/ -class JUCE_API ApplicationProperties -{ -public: - //============================================================================== - /** - Creates an ApplicationProperties object. - - Before using it, you must call setStorageParameters() to give it the info - it needs to create the property files. - */ - ApplicationProperties(); - - /** Destructor. */ - ~ApplicationProperties(); - - //============================================================================== - /** Gives the object the information it needs to create the appropriate properties files. - See the PropertiesFile::Options class for details about what options you need to set. - */ - void setStorageParameters (const PropertiesFile::Options& options); - - /** Returns the current storage parameters. - @see setStorageParameters - */ - const PropertiesFile::Options& getStorageParameters() const noexcept { return options; } - - //============================================================================== - /** Returns the user settings file. - - The first time this is called, it will create and load the properties file. - - Note that when you search the user PropertiesFile for a value that it doesn't contain, - the common settings are used as a second-chance place to look. This is done via the - PropertySet::setFallbackPropertySet() method - by default the common settings are set - to the fallback for the user settings. - - @see getCommonSettings - */ - PropertiesFile* getUserSettings(); - - /** Returns the common settings file. - - The first time this is called, it will create and load the properties file. - - @param returnUserPropsIfReadOnly if this is true, and the common properties file is - read-only (e.g. because the user doesn't have permission to write - to shared files), then this will return the user settings instead, - (like getUserSettings() would do). This is handy if you'd like to - write a value to the common settings, but if that's no possible, - then you'd rather write to the user settings than none at all. - If returnUserPropsIfReadOnly is false, this method will always return - the common settings, even if any changes to them can't be saved. - @see getUserSettings - */ - PropertiesFile* getCommonSettings (bool returnUserPropsIfReadOnly); - - //============================================================================== - /** Saves both files if they need to be saved. - - @see PropertiesFile::saveIfNeeded - */ - bool saveIfNeeded(); - - /** Flushes and closes both files if they are open. - - This flushes any pending changes to disk with PropertiesFile::saveIfNeeded() - and closes both files. They will then be re-opened the next time getUserSettings() - or getCommonSettings() is called. - */ - void closeFiles(); - - -private: - //============================================================================== - PropertiesFile::Options options; - ScopedPointer userProps, commonProps; - int commonSettingsAreReadOnly; - - void openFiles(); - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ApplicationProperties) -}; - - -#endif // JUCE_APPLICATIONPROPERTIES_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_data_structures/app_properties/juce_PropertiesFile.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_data_structures/app_properties/juce_PropertiesFile.cpp deleted file mode 100644 index ece2121f3c..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_data_structures/app_properties/juce_PropertiesFile.cpp +++ /dev/null @@ -1,355 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -namespace PropertyFileConstants -{ - static const int magicNumber = (int) ByteOrder::littleEndianInt ("PROP"); - static const int magicNumberCompressed = (int) ByteOrder::littleEndianInt ("CPRP"); - - static const char* const fileTag = "PROPERTIES"; - static const char* const valueTag = "VALUE"; - static const char* const nameAttribute = "name"; - static const char* const valueAttribute = "val"; -} - -//============================================================================== -PropertiesFile::Options::Options() - : commonToAllUsers (false), - ignoreCaseOfKeyNames (false), - doNotSave (false), - millisecondsBeforeSaving (3000), - storageFormat (PropertiesFile::storeAsXML), - processLock (nullptr) -{ -} - -File PropertiesFile::Options::getDefaultFile() const -{ - // mustn't have illegal characters in this name.. - jassert (applicationName == File::createLegalFileName (applicationName)); - - #if JUCE_MAC || JUCE_IOS - File dir (commonToAllUsers ? "/Library/" - : "~/Library/"); - - if (osxLibrarySubFolder != "Preferences" && ! osxLibrarySubFolder.startsWith ("Application Support")) - { - /* The PropertiesFile class always used to put its settings files in "Library/Preferences", but Apple - have changed their advice, and now stipulate that settings should go in "Library/Application Support". - - Because older apps would be broken by a silent change in this class's behaviour, you must now - explicitly set the osxLibrarySubFolder value to indicate which path you want to use. - - In newer apps, you should always set this to "Application Support" - or "Application Support/YourSubFolderName". - - If your app needs to load settings files that were created by older versions of juce and - you want to maintain backwards-compatibility, then you can set this to "Preferences". - But.. for better Apple-compliance, the recommended approach would be to write some code that - finds your old settings files in ~/Library/Preferences, moves them to ~/Library/Application Support, - and then uses the new path. - */ - jassertfalse; - - dir = dir.getChildFile ("Application Support"); - } - else - { - dir = dir.getChildFile (osxLibrarySubFolder); - } - - if (folderName.isNotEmpty()) - dir = dir.getChildFile (folderName); - - #elif JUCE_LINUX || JUCE_ANDROID - const File dir (File (commonToAllUsers ? "/var" : "~") - .getChildFile (folderName.isNotEmpty() ? folderName - : ("." + applicationName))); - - #elif JUCE_WINDOWS - File dir (File::getSpecialLocation (commonToAllUsers ? File::commonApplicationDataDirectory - : File::userApplicationDataDirectory)); - - if (dir == File()) - return File(); - - dir = dir.getChildFile (folderName.isNotEmpty() ? folderName - : applicationName); - #endif - - return dir.getChildFile (applicationName) - .withFileExtension (filenameSuffix); -} - - -//============================================================================== -PropertiesFile::PropertiesFile (const File& f, const Options& o) - : PropertySet (o.ignoreCaseOfKeyNames), - file (f), options (o), - loadedOk (false), needsWriting (false) -{ - reload(); -} - -PropertiesFile::PropertiesFile (const Options& o) - : PropertySet (o.ignoreCaseOfKeyNames), - file (o.getDefaultFile()), options (o), - loadedOk (false), needsWriting (false) -{ - reload(); -} - -bool PropertiesFile::reload() -{ - ProcessScopedLock pl (createProcessLock()); - - if (pl != nullptr && ! pl->isLocked()) - return false; // locking failure.. - - loadedOk = (! file.exists()) || loadAsBinary() || loadAsXml(); - return loadedOk; -} - -PropertiesFile::~PropertiesFile() -{ - saveIfNeeded(); -} - -InterProcessLock::ScopedLockType* PropertiesFile::createProcessLock() const -{ - return options.processLock != nullptr ? new InterProcessLock::ScopedLockType (*options.processLock) : nullptr; -} - -bool PropertiesFile::saveIfNeeded() -{ - const ScopedLock sl (getLock()); - return (! needsWriting) || save(); -} - -bool PropertiesFile::needsToBeSaved() const -{ - const ScopedLock sl (getLock()); - return needsWriting; -} - -void PropertiesFile::setNeedsToBeSaved (const bool needsToBeSaved_) -{ - const ScopedLock sl (getLock()); - needsWriting = needsToBeSaved_; -} - -bool PropertiesFile::save() -{ - const ScopedLock sl (getLock()); - - stopTimer(); - - if (options.doNotSave - || file == File() - || file.isDirectory() - || ! file.getParentDirectory().createDirectory()) - return false; - - if (options.storageFormat == storeAsXML) - return saveAsXml(); - - return saveAsBinary(); -} - -bool PropertiesFile::loadAsXml() -{ - XmlDocument parser (file); - ScopedPointer doc (parser.getDocumentElement (true)); - - if (doc != nullptr && doc->hasTagName (PropertyFileConstants::fileTag)) - { - doc = parser.getDocumentElement(); - - if (doc != nullptr) - { - forEachXmlChildElementWithTagName (*doc, e, PropertyFileConstants::valueTag) - { - const String name (e->getStringAttribute (PropertyFileConstants::nameAttribute)); - - if (name.isNotEmpty()) - { - getAllProperties().set (name, - e->getFirstChildElement() != nullptr - ? e->getFirstChildElement()->createDocument ("", true) - : e->getStringAttribute (PropertyFileConstants::valueAttribute)); - } - } - - return true; - } - - // must be a pretty broken XML file we're trying to parse here, - // or a sign that this object needs an InterProcessLock, - // or just a failure reading the file. This last reason is why - // we don't jassertfalse here. - } - - return false; -} - -bool PropertiesFile::saveAsXml() -{ - XmlElement doc (PropertyFileConstants::fileTag); - const StringPairArray& props = getAllProperties(); - - for (int i = 0; i < props.size(); ++i) - { - XmlElement* const e = doc.createNewChildElement (PropertyFileConstants::valueTag); - e->setAttribute (PropertyFileConstants::nameAttribute, props.getAllKeys() [i]); - - // if the value seems to contain xml, store it as such.. - if (XmlElement* const childElement = XmlDocument::parse (props.getAllValues() [i])) - e->addChildElement (childElement); - else - e->setAttribute (PropertyFileConstants::valueAttribute, props.getAllValues() [i]); - } - - ProcessScopedLock pl (createProcessLock()); - - if (pl != nullptr && ! pl->isLocked()) - return false; // locking failure.. - - if (doc.writeToFile (file, String())) - { - needsWriting = false; - return true; - } - - return false; -} - -bool PropertiesFile::loadAsBinary() -{ - FileInputStream fileStream (file); - - if (fileStream.openedOk()) - { - const int magicNumber = fileStream.readInt(); - - if (magicNumber == PropertyFileConstants::magicNumberCompressed) - { - SubregionStream subStream (&fileStream, 4, -1, false); - GZIPDecompressorInputStream gzip (subStream); - return loadAsBinary (gzip); - } - - if (magicNumber == PropertyFileConstants::magicNumber) - return loadAsBinary (fileStream); - } - - return false; -} - -bool PropertiesFile::loadAsBinary (InputStream& input) -{ - BufferedInputStream in (input, 2048); - - int numValues = in.readInt(); - - while (--numValues >= 0 && ! in.isExhausted()) - { - const String key (in.readString()); - const String value (in.readString()); - - jassert (key.isNotEmpty()); - if (key.isNotEmpty()) - getAllProperties().set (key, value); - } - - return true; -} - -bool PropertiesFile::saveAsBinary() -{ - ProcessScopedLock pl (createProcessLock()); - - if (pl != nullptr && ! pl->isLocked()) - return false; // locking failure.. - - TemporaryFile tempFile (file); - ScopedPointer out (tempFile.getFile().createOutputStream()); - - if (out != nullptr) - { - if (options.storageFormat == storeAsCompressedBinary) - { - out->writeInt (PropertyFileConstants::magicNumberCompressed); - out->flush(); - - out = new GZIPCompressorOutputStream (out.release(), 9, true); - } - else - { - // have you set up the storage option flags correctly? - jassert (options.storageFormat == storeAsBinary); - - out->writeInt (PropertyFileConstants::magicNumber); - } - - const StringPairArray& props = getAllProperties(); - const int numProperties = props.size(); - const StringArray& keys = props.getAllKeys(); - const StringArray& values = props.getAllValues(); - - out->writeInt (numProperties); - - for (int i = 0; i < numProperties; ++i) - { - out->writeString (keys[i]); - out->writeString (values[i]); - } - - out = nullptr; - - if (tempFile.overwriteTargetFileWithTemporary()) - { - needsWriting = false; - return true; - } - } - - return false; -} - -void PropertiesFile::timerCallback() -{ - saveIfNeeded(); -} - -void PropertiesFile::propertyChanged() -{ - sendChangeMessage(); - - needsWriting = true; - - if (options.millisecondsBeforeSaving > 0) - startTimer (options.millisecondsBeforeSaving); - else if (options.millisecondsBeforeSaving == 0) - saveIfNeeded(); -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_data_structures/app_properties/juce_PropertiesFile.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_data_structures/app_properties/juce_PropertiesFile.h deleted file mode 100644 index f3d9551b11..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_data_structures/app_properties/juce_PropertiesFile.h +++ /dev/null @@ -1,247 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_PROPERTIESFILE_H_INCLUDED -#define JUCE_PROPERTIESFILE_H_INCLUDED - - -//============================================================================== -/** Wrapper on a file that stores a list of key/value data pairs. - - Useful for storing application settings, etc. See the PropertySet class for - the interfaces that read and write values. - - Not designed for very large amounts of data, as it keeps all the values in - memory and writes them out to disk lazily when they are changed. - - Because this class derives from ChangeBroadcaster, ChangeListeners can be registered - with it, and these will be signalled when a value changes. - - @see PropertySet -*/ -class JUCE_API PropertiesFile : public PropertySet, - public ChangeBroadcaster, - private Timer -{ -public: - //============================================================================== - enum StorageFormat - { - storeAsBinary, - storeAsCompressedBinary, - storeAsXML - }; - - //============================================================================== - struct JUCE_API Options - { - /** Creates an empty Options structure. - You'll need to fill-in the data members appropriately before using this structure. - */ - Options(); - - /** The name of your application - this is used to help generate the path and filename - at which the properties file will be stored. */ - String applicationName; - - /** The suffix to use for your properties file. - It doesn't really matter what this is - you may want to use ".settings" or - ".properties" or something. - */ - String filenameSuffix; - - /** The name of a subfolder in which you'd like your properties file to live. - See the getDefaultFile() method for more details about how this is used. - */ - String folderName; - - /** If you're using properties files on a Mac, you must set this value - failure to - do so will cause a runtime assertion. - - The PropertiesFile class always used to put its settings files in "Library/Preferences", but Apple - have changed their advice, and now stipulate that settings should go in "Library/Application Support". - - Because older apps would be broken by a silent change in this class's behaviour, you must now - explicitly set the osxLibrarySubFolder value to indicate which path you want to use. - - In newer apps, you should always set this to "Application Support" or - "Application Support/YourSubFolderName". - - If your app needs to load settings files that were created by older versions of juce and - you want to maintain backwards-compatibility, then you can set this to "Preferences". - But.. for better Apple-compliance, the recommended approach would be to write some code that - finds your old settings files in ~/Library/Preferences, moves them to ~/Library/Application Support, - and then uses the new path. - */ - String osxLibrarySubFolder; - - /** If true, the file will be created in a location that's shared between users. - The default constructor initialises this value to false. - */ - bool commonToAllUsers; - - /** If true, this means that property names are matched in a case-insensitive manner. - See the PropertySet constructor for more info. - The default constructor initialises this value to false. - */ - bool ignoreCaseOfKeyNames; - - /** If set to true, this prevents the file from being written to disk. */ - bool doNotSave; - - /** If this is zero or greater, then after a value is changed, the object will wait - for this amount of time and then save the file. If this zero, the file will be - written to disk immediately on being changed (which might be slow, as it'll re-write - synchronously each time a value-change method is called). If it is less than zero, - the file won't be saved until save() or saveIfNeeded() are explicitly called. - The default constructor sets this to a reasonable value of a few seconds, so you - only need to change it if you need a special case. - */ - int millisecondsBeforeSaving; - - /** Specifies whether the file should be written as XML, binary, etc. - The default constructor sets this to storeAsXML, so you only need to set it explicitly - if you want to use a different format. - */ - StorageFormat storageFormat; - - /** An optional InterprocessLock object that will be used to prevent multiple threads or - processes from writing to the file at the same time. The PropertiesFile will keep a - pointer to this object but will not take ownership of it - the caller is responsible for - making sure that the lock doesn't get deleted before the PropertiesFile has been deleted. - The default constructor initialises this value to nullptr, so you don't need to touch it - unless you want to use a lock. - */ - InterProcessLock* processLock; - - /** This can be called to suggest a file that should be used, based on the values - in this structure. - - So on a Mac, this will return a file called: - ~/Library/[osxLibrarySubFolder]/[folderName]/[applicationName].[filenameSuffix] - - On Windows it'll return something like: - C:\\Documents and Settings\\username\\Application Data\\[folderName]\\[applicationName].[filenameSuffix] - - On Linux it'll return - ~/[folderName]/[applicationName].[filenameSuffix] - - If the folderName variable is empty, it'll use the app name for this (or omit the - folder name on the Mac). - - The paths will also vary depending on whether commonToAllUsers is true. - */ - File getDefaultFile() const; - }; - - //============================================================================== - /** Creates a PropertiesFile object. - The file used will be chosen by calling PropertiesFile::Options::getDefaultFile() - for the options provided. To set the file explicitly, use the other constructor. - */ - explicit PropertiesFile (const Options& options); - - /** Creates a PropertiesFile object. - Unlike the other constructor, this one allows you to explicitly set the file that you - want to be used, rather than using the default one. - */ - PropertiesFile (const File& file, - const Options& options); - - /** Destructor. - When deleted, the file will first call saveIfNeeded() to flush any changes to disk. - */ - ~PropertiesFile(); - - //============================================================================== - /** Returns true if this file was created from a valid (or non-existent) file. - If the file failed to load correctly because it was corrupt or had insufficient - access, this will be false. - */ - bool isValidFile() const noexcept { return loadedOk; } - - //============================================================================== - /** This will flush all the values to disk if they've changed since the last - time they were saved. - - Returns false if it fails to write to the file for some reason (maybe because - it's read-only or the directory doesn't exist or something). - - @see save - */ - bool saveIfNeeded(); - - /** This will force a write-to-disk of the current values, regardless of whether - anything has changed since the last save. - - Returns false if it fails to write to the file for some reason (maybe because - it's read-only or the directory doesn't exist or something). - - @see saveIfNeeded - */ - bool save(); - - /** Returns true if the properties have been altered since the last time they were saved. - The file is flagged as needing to be saved when you change a value, but you can - explicitly set this flag with setNeedsToBeSaved(). - */ - bool needsToBeSaved() const; - - /** Explicitly sets the flag to indicate whether the file needs saving or not. - @see needsToBeSaved - */ - void setNeedsToBeSaved (bool needsToBeSaved); - - /** Attempts to reload the settings from the file. */ - bool reload(); - - //============================================================================== - /** Returns the file that's being used. */ - const File& getFile() const noexcept { return file; } - - -protected: - /** @internal */ - virtual void propertyChanged(); - -private: - //============================================================================== - File file; - Options options; - bool loadedOk, needsWriting; - - typedef const ScopedPointer ProcessScopedLock; - InterProcessLock::ScopedLockType* createProcessLock() const; - - void timerCallback() override; - bool saveAsXml(); - bool saveAsBinary(); - bool loadAsXml(); - bool loadAsBinary(); - bool loadAsBinary (InputStream&); - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (PropertiesFile) -}; - -#endif // JUCE_PROPERTIESFILE_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_data_structures/juce_data_structures.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_data_structures/juce_data_structures.cpp deleted file mode 100644 index fd1d12aaca..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_data_structures/juce_data_structures.cpp +++ /dev/null @@ -1,49 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#if defined (JUCE_DATA_STRUCTURES_H_INCLUDED) && ! JUCE_AMALGAMATED_INCLUDE - /* When you add this cpp file to your project, you mustn't include it in a file where you've - already included any other headers - just put it inside a file on its own, possibly with your config - flags preceding it, but don't include anything else. That also includes avoiding any automatic prefix - header files that the compiler may be using. - */ - #error "Incorrect use of JUCE cpp file" -#endif - -// Your project must contain an AppConfig.h file with your project-specific settings in it, -// and your header search path must make it accessible to the module's files. -#include "AppConfig.h" - -#include "juce_data_structures.h" - -namespace juce -{ - -#include "values/juce_Value.cpp" -#include "values/juce_ValueTree.cpp" -#include "undomanager/juce_UndoManager.cpp" -#include "app_properties/juce_ApplicationProperties.cpp" -#include "app_properties/juce_PropertiesFile.cpp" - -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_data_structures/juce_data_structures.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_data_structures/juce_data_structures.h index 629b88ddf6..00f01d46aa 100644 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_data_structures/juce_data_structures.h +++ b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_data_structures/juce_data_structures.h @@ -1,43 +1,5 @@ -/* - ============================================================================== +// This is an auto-generated file to redirect any included +// module headers to the correct external folder. - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. +#include "../../../../../modules/juce_data_structures/juce_data_structures.h" - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_DATA_STRUCTURES_H_INCLUDED -#define JUCE_DATA_STRUCTURES_H_INCLUDED - -//============================================================================= -#include "../juce_events/juce_events.h" - -namespace juce -{ - -#include "undomanager/juce_UndoableAction.h" -#include "undomanager/juce_UndoManager.h" -#include "values/juce_Value.h" -#include "values/juce_ValueTree.h" -#include "app_properties/juce_PropertiesFile.h" -#include "app_properties/juce_ApplicationProperties.h" - -} - -#endif // JUCE_DATA_STRUCTURES_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_data_structures/juce_data_structures.mm b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_data_structures/juce_data_structures.mm deleted file mode 100644 index 2eb4fb4347..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_data_structures/juce_data_structures.mm +++ /dev/null @@ -1,25 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#include "juce_data_structures.cpp" diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_data_structures/juce_module_info b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_data_structures/juce_module_info deleted file mode 100644 index 09b96f8e8f..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_data_structures/juce_module_info +++ /dev/null @@ -1,20 +0,0 @@ -{ - "id": "juce_data_structures", - "name": "JUCE data model helper classes", - "version": "3.0.8", - "description": "Classes for undo/redo management, and smart data structures.", - "website": "http://www.juce.com/juce", - "license": "GPL/Commercial", - - "dependencies": [ { "id": "juce_core", "version": "matching" }, - { "id": "juce_events", "version": "matching" } ], - - "include": "juce_data_structures.h", - - "compile": [ { "file": "juce_data_structures.cpp", "target": "! xcode" }, - { "file": "juce_data_structures.mm", "target": "xcode" } ], - - "browse": [ "values/*", - "undomanager/*", - "app_properties/*" ] -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_data_structures/undomanager/juce_UndoManager.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_data_structures/undomanager/juce_UndoManager.cpp deleted file mode 100644 index 07948c69eb..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_data_structures/undomanager/juce_UndoManager.cpp +++ /dev/null @@ -1,303 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -struct UndoManager::ActionSet -{ - ActionSet (const String& transactionName) - : name (transactionName), - time (Time::getCurrentTime()) - {} - - bool perform() const - { - for (int i = 0; i < actions.size(); ++i) - if (! actions.getUnchecked(i)->perform()) - return false; - - return true; - } - - bool undo() const - { - for (int i = actions.size(); --i >= 0;) - if (! actions.getUnchecked(i)->undo()) - return false; - - return true; - } - - int getTotalSize() const - { - int total = 0; - - for (int i = actions.size(); --i >= 0;) - total += actions.getUnchecked(i)->getSizeInUnits(); - - return total; - } - - OwnedArray actions; - String name; - Time time; -}; - -//============================================================================== -UndoManager::UndoManager (const int maxNumberOfUnitsToKeep, - const int minimumTransactions) - : totalUnitsStored (0), - nextIndex (0), - newTransaction (true), - reentrancyCheck (false) -{ - setMaxNumberOfStoredUnits (maxNumberOfUnitsToKeep, - minimumTransactions); -} - -UndoManager::~UndoManager() -{ -} - -//============================================================================== -void UndoManager::clearUndoHistory() -{ - transactions.clear(); - totalUnitsStored = 0; - nextIndex = 0; - sendChangeMessage(); -} - -int UndoManager::getNumberOfUnitsTakenUpByStoredCommands() const -{ - return totalUnitsStored; -} - -void UndoManager::setMaxNumberOfStoredUnits (const int maxNumberOfUnitsToKeep, - const int minimumTransactions) -{ - maxNumUnitsToKeep = jmax (1, maxNumberOfUnitsToKeep); - minimumTransactionsToKeep = jmax (1, minimumTransactions); -} - -//============================================================================== -bool UndoManager::perform (UndoableAction* const newAction, const String& actionName) -{ - if (perform (newAction)) - { - if (actionName.isNotEmpty()) - setCurrentTransactionName (actionName); - - return true; - } - - return false; -} - -bool UndoManager::perform (UndoableAction* const newAction) -{ - if (newAction != nullptr) - { - ScopedPointer action (newAction); - - if (reentrancyCheck) - { - jassertfalse; // don't call perform() recursively from the UndoableAction::perform() - // or undo() methods, or else these actions will be discarded! - return false; - } - - if (action->perform()) - { - ActionSet* actionSet = getCurrentSet(); - - if (actionSet != nullptr && ! newTransaction) - { - if (UndoableAction* const lastAction = actionSet->actions.getLast()) - { - if (UndoableAction* const coalescedAction = lastAction->createCoalescedAction (action)) - { - action = coalescedAction; - totalUnitsStored -= lastAction->getSizeInUnits(); - actionSet->actions.removeLast(); - } - } - } - else - { - actionSet = new ActionSet (newTransactionName); - transactions.insert (nextIndex, actionSet); - ++nextIndex; - } - - totalUnitsStored += action->getSizeInUnits(); - actionSet->actions.add (action.release()); - newTransaction = false; - - clearFutureTransactions(); - sendChangeMessage(); - return true; - } - } - - return false; -} - -void UndoManager::clearFutureTransactions() -{ - while (nextIndex < transactions.size()) - { - totalUnitsStored -= transactions.getLast()->getTotalSize(); - transactions.removeLast(); - } - - while (nextIndex > 0 - && totalUnitsStored > maxNumUnitsToKeep - && transactions.size() > minimumTransactionsToKeep) - { - totalUnitsStored -= transactions.getFirst()->getTotalSize(); - transactions.remove (0); - --nextIndex; - - // if this fails, then some actions may not be returning - // consistent results from their getSizeInUnits() method - jassert (totalUnitsStored >= 0); - } -} - -void UndoManager::beginNewTransaction() noexcept -{ - beginNewTransaction (String()); -} - -void UndoManager::beginNewTransaction (const String& actionName) noexcept -{ - newTransaction = true; - newTransactionName = actionName; -} - -void UndoManager::setCurrentTransactionName (const String& newName) noexcept -{ - if (newTransaction) - newTransactionName = newName; - else if (ActionSet* action = getCurrentSet()) - action->name = newName; -} - -//============================================================================== -UndoManager::ActionSet* UndoManager::getCurrentSet() const noexcept { return transactions [nextIndex - 1]; } -UndoManager::ActionSet* UndoManager::getNextSet() const noexcept { return transactions [nextIndex]; } - -bool UndoManager::canUndo() const noexcept { return getCurrentSet() != nullptr; } -bool UndoManager::canRedo() const noexcept { return getNextSet() != nullptr; } - -bool UndoManager::undo() -{ - if (const ActionSet* const s = getCurrentSet()) - { - const ScopedValueSetter setter (reentrancyCheck, true); - - if (s->undo()) - --nextIndex; - else - clearUndoHistory(); - - beginNewTransaction(); - sendChangeMessage(); - return true; - } - - return false; -} - -bool UndoManager::redo() -{ - if (const ActionSet* const s = getNextSet()) - { - const ScopedValueSetter setter (reentrancyCheck, true); - - if (s->perform()) - ++nextIndex; - else - clearUndoHistory(); - - beginNewTransaction(); - sendChangeMessage(); - return true; - } - - return false; -} - -String UndoManager::getUndoDescription() const -{ - if (const ActionSet* const s = getCurrentSet()) - return s->name; - - return String(); -} - -String UndoManager::getRedoDescription() const -{ - if (const ActionSet* const s = getNextSet()) - return s->name; - - return String(); -} - -Time UndoManager::getTimeOfUndoTransaction() const -{ - if (const ActionSet* const s = getCurrentSet()) - return s->time; - - return Time(); -} - -Time UndoManager::getTimeOfRedoTransaction() const -{ - if (const ActionSet* const s = getNextSet()) - return s->time; - - return Time::getCurrentTime(); -} - -bool UndoManager::undoCurrentTransactionOnly() -{ - return newTransaction ? false : undo(); -} - -void UndoManager::getActionsInCurrentTransaction (Array& actionsFound) const -{ - if (! newTransaction) - if (const ActionSet* const s = getCurrentSet()) - for (int i = 0; i < s->actions.size(); ++i) - actionsFound.add (s->actions.getUnchecked(i)); -} - -int UndoManager::getNumActionsInCurrentTransaction() const -{ - if (! newTransaction) - if (const ActionSet* const s = getCurrentSet()) - return s->actions.size(); - - return 0; -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_data_structures/undomanager/juce_UndoManager.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_data_structures/undomanager/juce_UndoManager.h deleted file mode 100644 index a3b691b692..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_data_structures/undomanager/juce_UndoManager.h +++ /dev/null @@ -1,239 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_UNDOMANAGER_H_INCLUDED -#define JUCE_UNDOMANAGER_H_INCLUDED - - -//============================================================================== -/** - Manages a list of undo/redo commands. - - An UndoManager object keeps a list of past actions and can use these actions - to move backwards and forwards through an undo history. - - To use it, create subclasses of UndoableAction which perform all the - actions you need, then when you need to actually perform an action, create one - and pass it to the UndoManager's perform() method. - - The manager also uses the concept of 'transactions' to group the actions - together - all actions performed between calls to beginNewTransaction() are - grouped together and are all undone/redone as a group. - - The UndoManager is a ChangeBroadcaster, so listeners can register to be told - when actions are performed or undone. - - @see UndoableAction -*/ -class JUCE_API UndoManager : public ChangeBroadcaster -{ -public: - //============================================================================== - /** Creates an UndoManager. - - @param maxNumberOfUnitsToKeep each UndoableAction object returns a value - to indicate how much storage it takes up - (UndoableAction::getSizeInUnits()), so this - lets you specify the maximum total number of - units that the undomanager is allowed to - keep in memory before letting the older actions - drop off the end of the list. - @param minimumTransactionsToKeep this specifies the minimum number of transactions - that will be kept, even if this involves exceeding - the amount of space specified in maxNumberOfUnitsToKeep - */ - UndoManager (int maxNumberOfUnitsToKeep = 30000, - int minimumTransactionsToKeep = 30); - - /** Destructor. */ - ~UndoManager(); - - //============================================================================== - /** Deletes all stored actions in the list. */ - void clearUndoHistory(); - - /** Returns the current amount of space to use for storing UndoableAction objects. - @see setMaxNumberOfStoredUnits - */ - int getNumberOfUnitsTakenUpByStoredCommands() const; - - /** Sets the amount of space that can be used for storing UndoableAction objects. - - @param maxNumberOfUnitsToKeep each UndoableAction object returns a value - to indicate how much storage it takes up - (UndoableAction::getSizeInUnits()), so this - lets you specify the maximum total number of - units that the undomanager is allowed to - keep in memory before letting the older actions - drop off the end of the list. - @param minimumTransactionsToKeep this specifies the minimum number of transactions - that will be kept, even if this involves exceeding - the amount of space specified in maxNumberOfUnitsToKeep - @see getNumberOfUnitsTakenUpByStoredCommands - */ - void setMaxNumberOfStoredUnits (int maxNumberOfUnitsToKeep, - int minimumTransactionsToKeep); - - //============================================================================== - /** Performs an action and adds it to the undo history list. - - @param action the action to perform - this object will be deleted by - the UndoManager when no longer needed - @returns true if the command succeeds - see UndoableAction::perform - @see beginNewTransaction - */ - bool perform (UndoableAction* action); - - /** Performs an action and also gives it a name. - - @param action the action to perform - this object will be deleted by - the UndoManager when no longer needed - @param actionName if this string is non-empty, the current transaction will be - given this name; if it's empty, the current transaction name will - be left unchanged. See setCurrentTransactionName() - @returns true if the command succeeds - see UndoableAction::perform - @see beginNewTransaction - */ - bool perform (UndoableAction* action, const String& actionName); - - /** Starts a new group of actions that together will be treated as a single transaction. - - All actions that are passed to the perform() method between calls to this - method are grouped together and undone/redone together by a single call to - undo() or redo(). - */ - void beginNewTransaction() noexcept; - - /** Starts a new group of actions that together will be treated as a single transaction. - - All actions that are passed to the perform() method between calls to this - method are grouped together and undone/redone together by a single call to - undo() or redo(). - - @param actionName a description of the transaction that is about to be - performed - */ - void beginNewTransaction (const String& actionName) noexcept; - - /** Changes the name stored for the current transaction. - - Each transaction is given a name when the beginNewTransaction() method is - called, but this can be used to change that name without starting a new - transaction. - */ - void setCurrentTransactionName (const String& newName) noexcept; - - //============================================================================== - /** Returns true if there's at least one action in the list to undo. - @see getUndoDescription, undo, canRedo - */ - bool canUndo() const noexcept; - - /** Returns the name of the transaction that will be rolled-back when undo() is called. - @see undo - */ - String getUndoDescription() const; - - /** Tries to roll-back the last transaction. - @returns true if the transaction can be undone, and false if it fails, or - if there aren't any transactions to undo - */ - bool undo(); - - /** Tries to roll-back any actions that were added to the current transaction. - - This will perform an undo() only if there are some actions in the undo list - that were added after the last call to beginNewTransaction(). - - This is useful because it lets you call beginNewTransaction(), then - perform an operation which may or may not actually perform some actions, and - then call this method to get rid of any actions that might have been done - without it rolling back the previous transaction if nothing was actually - done. - - @returns true if any actions were undone. - */ - bool undoCurrentTransactionOnly(); - - /** Returns a list of the UndoableAction objects that have been performed during the - transaction that is currently open. - - Effectively, this is the list of actions that would be undone if undoCurrentTransactionOnly() - were to be called now. - - The first item in the list is the earliest action performed. - */ - void getActionsInCurrentTransaction (Array& actionsFound) const; - - /** Returns the number of UndoableAction objects that have been performed during the - transaction that is currently open. - @see getActionsInCurrentTransaction - */ - int getNumActionsInCurrentTransaction() const; - - /** Returns the time to which the state would be restored if undo() was to be called. - If an undo isn't currently possible, it'll return Time(). - */ - Time getTimeOfUndoTransaction() const; - - /** Returns the time to which the state would be restored if redo() was to be called. - If a redo isn't currently possible, it'll return Time::getCurrentTime(). - */ - Time getTimeOfRedoTransaction() const; - - //============================================================================== - /** Returns true if there's at least one action in the list to redo. - @see getRedoDescription, redo, canUndo - */ - bool canRedo() const noexcept; - - /** Returns the name of the transaction that will be redone when redo() is called. - @see redo - */ - String getRedoDescription() const; - - /** Tries to redo the last transaction that was undone. - @returns true if the transaction can be redone, and false if it fails, or - if there aren't any transactions to redo - */ - bool redo(); - - -private: - //============================================================================== - struct ActionSet; - friend struct ContainerDeletePolicy; - OwnedArray transactions; - String newTransactionName; - int totalUnitsStored, maxNumUnitsToKeep, minimumTransactionsToKeep, nextIndex; - bool newTransaction, reentrancyCheck; - ActionSet* getCurrentSet() const noexcept; - ActionSet* getNextSet() const noexcept; - void clearFutureTransactions(); - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (UndoManager) -}; - - -#endif // JUCE_UNDOMANAGER_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_data_structures/undomanager/juce_UndoableAction.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_data_structures/undomanager/juce_UndoableAction.h deleted file mode 100644 index 866d48825f..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_data_structures/undomanager/juce_UndoableAction.h +++ /dev/null @@ -1,99 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_UNDOABLEACTION_H_INCLUDED -#define JUCE_UNDOABLEACTION_H_INCLUDED - - -//============================================================================== -/** - Used by the UndoManager class to store an action which can be done - and undone. - - @see UndoManager -*/ -class JUCE_API UndoableAction -{ -protected: - /** Creates an action. */ - UndoableAction() noexcept {} - -public: - /** Destructor. */ - virtual ~UndoableAction() {} - - //============================================================================== - /** Overridden by a subclass to perform the action. - - This method is called by the UndoManager, and shouldn't be used directly by - applications. - - Be careful not to make any calls in a perform() method that could call - recursively back into the UndoManager::perform() method - - @returns true if the action could be performed. - @see UndoManager::perform - */ - virtual bool perform() = 0; - - /** Overridden by a subclass to undo the action. - - This method is called by the UndoManager, and shouldn't be used directly by - applications. - - Be careful not to make any calls in an undo() method that could call - recursively back into the UndoManager::perform() method - - @returns true if the action could be undone without any errors. - @see UndoManager::perform - */ - virtual bool undo() = 0; - - //============================================================================== - /** Returns a value to indicate how much memory this object takes up. - - Because the UndoManager keeps a list of UndoableActions, this is used - to work out how much space each one will take up, so that the UndoManager - can work out how many to keep. - - The default value returned here is 10 - units are arbitrary and - don't have to be accurate. - - @see UndoManager::getNumberOfUnitsTakenUpByStoredCommands, - UndoManager::setMaxNumberOfStoredUnits - */ - virtual int getSizeInUnits() { return 10; } - - /** Allows multiple actions to be coalesced into a single action object, to reduce storage space. - - If possible, this method should create and return a single action that does the same job as - this one followed by the supplied action. - - If it's not possible to merge the two actions, the method should return zero. - */ - virtual UndoableAction* createCoalescedAction (UndoableAction* nextAction) { (void) nextAction; return nullptr; } -}; - - -#endif // JUCE_UNDOABLEACTION_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_data_structures/values/juce_Value.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_data_structures/values/juce_Value.cpp deleted file mode 100644 index 55b37fe17b..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_data_structures/values/juce_Value.cpp +++ /dev/null @@ -1,243 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -Value::ValueSource::ValueSource() -{ -} - -Value::ValueSource::~ValueSource() -{ - cancelPendingUpdate(); -} - -void Value::ValueSource::handleAsyncUpdate() -{ - sendChangeMessage (true); -} - -void Value::ValueSource::sendChangeMessage (const bool synchronous) -{ - const int numListeners = valuesWithListeners.size(); - - if (numListeners > 0) - { - if (synchronous) - { - const ReferenceCountedObjectPtr localRef (this); - - cancelPendingUpdate(); - - for (int i = numListeners; --i >= 0;) - if (Value* const v = valuesWithListeners[i]) - v->callListeners(); - } - else - { - triggerAsyncUpdate(); - } - } -} - -//============================================================================== -class SimpleValueSource : public Value::ValueSource -{ -public: - SimpleValueSource() - { - } - - SimpleValueSource (const var& initialValue) - : value (initialValue) - { - } - - var getValue() const - { - return value; - } - - void setValue (const var& newValue) - { - if (! newValue.equalsWithSameType (value)) - { - value = newValue; - sendChangeMessage (false); - } - } - -private: - var value; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (SimpleValueSource) -}; - - -//============================================================================== -Value::Value() : value (new SimpleValueSource()) -{ -} - -Value::Value (ValueSource* const v) : value (v) -{ - jassert (v != nullptr); -} - -Value::Value (const var& initialValue) : value (new SimpleValueSource (initialValue)) -{ -} - -Value::Value (const Value& other) : value (other.value) -{ -} - -Value& Value::operator= (const Value& other) -{ - value = other.value; - return *this; -} - -#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS -Value::Value (Value&& other) noexcept -{ - // moving a Value with listeners will lose those listeners, which - // probably isn't what you wanted to happen! - jassert (other.listeners.size() == 0); - - other.removeFromListenerList(); - value = static_cast&&> (other.value); -} - -Value& Value::operator= (Value&& other) noexcept -{ - // moving a Value with listeners will lose those listeners, which - // probably isn't what you wanted to happen! - jassert (other.listeners.size() == 0); - - other.removeFromListenerList(); - value = static_cast&&> (other.value); - return *this; -} -#endif - -Value::~Value() -{ - removeFromListenerList(); -} - -void Value::removeFromListenerList() -{ - if (listeners.size() > 0 && value != nullptr) // may be nullptr after a move operation - value->valuesWithListeners.removeValue (this); -} - -//============================================================================== -var Value::getValue() const -{ - return value->getValue(); -} - -Value::operator var() const -{ - return value->getValue(); -} - -void Value::setValue (const var& newValue) -{ - value->setValue (newValue); -} - -String Value::toString() const -{ - return value->getValue().toString(); -} - -Value& Value::operator= (const var& newValue) -{ - value->setValue (newValue); - return *this; -} - -void Value::referTo (const Value& valueToReferTo) -{ - if (valueToReferTo.value != value) - { - if (listeners.size() > 0) - { - value->valuesWithListeners.removeValue (this); - valueToReferTo.value->valuesWithListeners.add (this); - } - - value = valueToReferTo.value; - callListeners(); - } -} - -bool Value::refersToSameSourceAs (const Value& other) const -{ - return value == other.value; -} - -bool Value::operator== (const Value& other) const -{ - return value == other.value || value->getValue() == other.getValue(); -} - -bool Value::operator!= (const Value& other) const -{ - return value != other.value && value->getValue() != other.getValue(); -} - -//============================================================================== -void Value::addListener (ValueListener* const listener) -{ - if (listener != nullptr) - { - if (listeners.size() == 0) - value->valuesWithListeners.add (this); - - listeners.add (listener); - } -} - -void Value::removeListener (ValueListener* const listener) -{ - listeners.remove (listener); - - if (listeners.size() == 0) - value->valuesWithListeners.removeValue (this); -} - -void Value::callListeners() -{ - if (listeners.size() > 0) - { - Value v (*this); // (create a copy in case this gets deleted by a callback) - listeners.call (&ValueListener::valueChanged, v); - } -} - -OutputStream& JUCE_CALLTYPE operator<< (OutputStream& stream, const Value& value) -{ - return stream << value.toString(); -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_data_structures/values/juce_Value.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_data_structures/values/juce_Value.h deleted file mode 100644 index f8fc631f33..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_data_structures/values/juce_Value.h +++ /dev/null @@ -1,233 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_VALUE_H_INCLUDED -#define JUCE_VALUE_H_INCLUDED - - -//============================================================================== -/** - Represents a shared variant value. - - A Value object contains a reference to a var object, and can get and set its value. - Listeners can be attached to be told when the value is changed. - - The Value class is a wrapper around a shared, reference-counted underlying data - object - this means that multiple Value objects can all refer to the same piece of - data, allowing all of them to be notified when any of them changes it. - - When you create a Value with its default constructor, it acts as a wrapper around a - simple var object, but by creating a Value that refers to a custom subclass of ValueSource, - you can map the Value onto any kind of underlying data. -*/ -class JUCE_API Value -{ -public: - //============================================================================== - /** Creates an empty Value, containing a void var. */ - Value(); - - /** Creates a Value that refers to the same value as another one. - - Note that this doesn't make a copy of the other value - both this and the other - Value will share the same underlying value, so that when either one alters it, both - will see it change. - */ - Value (const Value& other); - - /** Creates a Value that is set to the specified value. */ - explicit Value (const var& initialValue); - - #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS - Value (Value&&) noexcept; - Value& operator= (Value&&) noexcept; - #endif - - /** Destructor. */ - ~Value(); - - //============================================================================== - /** Returns the current value. */ - var getValue() const; - - /** Returns the current value. */ - operator var() const; - - /** Returns the value as a string. - This is a shortcut for "myValue.getValue().toString()". - */ - String toString() const; - - /** Sets the current value. - - You can also use operator= to set the value. - - If there are any listeners registered, they will be notified of the - change asynchronously. - */ - void setValue (const var& newValue); - - /** Sets the current value. - - This is the same as calling setValue(). - - If there are any listeners registered, they will be notified of the - change asynchronously. - */ - Value& operator= (const var& newValue); - - /** Makes this object refer to the same underlying ValueSource as another one. - - Once this object has been connected to another one, changing either one - will update the other. - - Existing listeners will still be registered after you call this method, and - they'll continue to receive messages when the new value changes. - */ - void referTo (const Value& valueToReferTo); - - /** Returns true if this value and the other one are references to the same value. - */ - bool refersToSameSourceAs (const Value& other) const; - - /** Compares two values. - This is a compare-by-value comparison, so is effectively the same as - saying (this->getValue() == other.getValue()). - */ - bool operator== (const Value& other) const; - - /** Compares two values. - This is a compare-by-value comparison, so is effectively the same as - saying (this->getValue() != other.getValue()). - */ - bool operator!= (const Value& other) const; - - //============================================================================== - /** Receives callbacks when a Value object changes. - @see Value::addListener - */ - class JUCE_API Listener - { - public: - Listener() {} - virtual ~Listener() {} - - /** Called when a Value object is changed. - - Note that the Value object passed as a parameter may not be exactly the same - object that you registered the listener with - it might be a copy that refers - to the same underlying ValueSource. To find out, you can call Value::refersToSameSourceAs(). - */ - virtual void valueChanged (Value& value) = 0; - }; - - /** Adds a listener to receive callbacks when the value changes. - - The listener is added to this specific Value object, and not to the shared - object that it refers to. When this object is deleted, all the listeners will - be lost, even if other references to the same Value still exist. So when you're - adding a listener, make sure that you add it to a Value instance that will last - for as long as you need the listener. In general, you'd never want to add a listener - to a local stack-based Value, but more likely to one that's a member variable. - - @see removeListener - */ - void addListener (Listener* listener); - - /** Removes a listener that was previously added with addListener(). */ - void removeListener (Listener* listener); - - - //============================================================================== - /** - Used internally by the Value class as the base class for its shared value objects. - - The Value class is essentially a reference-counted pointer to a shared instance - of a ValueSource object. If you're feeling adventurous, you can create your own custom - ValueSource classes to allow Value objects to represent your own custom data items. - */ - class JUCE_API ValueSource : public ReferenceCountedObject, - private AsyncUpdater - { - public: - ValueSource(); - virtual ~ValueSource(); - - /** Returns the current value of this object. */ - virtual var getValue() const = 0; - - /** Changes the current value. - This must also trigger a change message if the value actually changes. - */ - virtual void setValue (const var& newValue) = 0; - - /** Delivers a change message to all the listeners that are registered with - this value. - - If dispatchSynchronously is true, the method will call all the listeners - before returning; otherwise it'll dispatch a message and make the call later. - */ - void sendChangeMessage (bool dispatchSynchronously); - - protected: - //============================================================================== - friend class Value; - SortedSet valuesWithListeners; - - private: - void handleAsyncUpdate() override; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ValueSource) - }; - - - //============================================================================== - /** Creates a Value object that uses this valueSource object as its underlying data. */ - explicit Value (ValueSource* valueSource); - - /** Returns the ValueSource that this value is referring to. */ - ValueSource& getValueSource() noexcept { return *value; } - - -private: - //============================================================================== - friend class ValueSource; - ReferenceCountedObjectPtr value; - ListenerList listeners; - - void callListeners(); - void removeFromListenerList(); - - // This is disallowed to avoid confusion about whether it should - // do a by-value or by-reference copy. - Value& operator= (const Value&); -}; - -/** Writes a Value to an OutputStream as a UTF8 string. */ -OutputStream& JUCE_CALLTYPE operator<< (OutputStream&, const Value&); - -/** This typedef is just for compatibility with old code - newer code should use the Value::Listener class directly. */ -typedef Value::Listener ValueListener; - -#endif // JUCE_VALUE_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_data_structures/values/juce_ValueTree.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_data_structures/values/juce_ValueTree.cpp deleted file mode 100644 index ee13400512..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_data_structures/values/juce_ValueTree.cpp +++ /dev/null @@ -1,1123 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -class ValueTree::SharedObject : public ReferenceCountedObject -{ -public: - typedef ReferenceCountedObjectPtr Ptr; - - explicit SharedObject (Identifier t) noexcept - : type (t), parent (nullptr) - { - } - - SharedObject (const SharedObject& other) - : ReferenceCountedObject(), - type (other.type), properties (other.properties), parent (nullptr) - { - for (int i = 0; i < other.children.size(); ++i) - { - SharedObject* const child = new SharedObject (*other.children.getObjectPointerUnchecked(i)); - child->parent = this; - children.add (child); - } - } - - ~SharedObject() - { - jassert (parent == nullptr); // this should never happen unless something isn't obeying the ref-counting! - - for (int i = children.size(); --i >= 0;) - { - const Ptr c (children.getObjectPointerUnchecked(i)); - c->parent = nullptr; - children.remove (i); - c->sendParentChangeMessage(); - } - } - - template - void callListeners (Method method, ValueTree& tree) const - { - const int numListeners = valueTreesWithListeners.size(); - - if (numListeners > 0) - { - if (numListeners == 1) - { - valueTreesWithListeners.getUnchecked(0)->listeners.call (method, tree); - } - else - { - const SortedSet listenersCopy (valueTreesWithListeners); - - for (int i = 0; i < numListeners; ++i) - { - ValueTree* const v = listenersCopy.getUnchecked(i); - - if (i == 0 || valueTreesWithListeners.contains (v)) - v->listeners.call (method, tree); - } - } - } - } - - template - void callListeners (Method method, ValueTree& tree, ParamType& param2) const - { - const int numListeners = valueTreesWithListeners.size(); - - if (numListeners > 0) - { - if (numListeners == 1) - { - valueTreesWithListeners.getUnchecked(0)->listeners.call (method, tree, param2); - } - else - { - const SortedSet listenersCopy (valueTreesWithListeners); - - for (int i = 0; i < numListeners; ++i) - { - ValueTree* const v = listenersCopy.getUnchecked(i); - - if (i == 0 || valueTreesWithListeners.contains (v)) - v->listeners.call (method, tree, param2); - } - } - } - } - - void sendPropertyChangeMessage (const Identifier property) - { - ValueTree tree (this); - - for (ValueTree::SharedObject* t = this; t != nullptr; t = t->parent) - t->callListeners (&ValueTree::Listener::valueTreePropertyChanged, tree, property); - } - - void sendChildAddedMessage (ValueTree child) - { - ValueTree tree (this); - - for (ValueTree::SharedObject* t = this; t != nullptr; t = t->parent) - t->callListeners (&ValueTree::Listener::valueTreeChildAdded, tree, child); - } - - void sendChildRemovedMessage (ValueTree child) - { - ValueTree tree (this); - - for (ValueTree::SharedObject* t = this; t != nullptr; t = t->parent) - t->callListeners (&ValueTree::Listener::valueTreeChildRemoved, tree, child); - } - - void sendChildOrderChangedMessage() - { - ValueTree tree (this); - - for (ValueTree::SharedObject* t = this; t != nullptr; t = t->parent) - t->callListeners (&ValueTree::Listener::valueTreeChildOrderChanged, tree); - } - - void sendParentChangeMessage() - { - ValueTree tree (this); - - for (int j = children.size(); --j >= 0;) - if (SharedObject* const child = children.getObjectPointer (j)) - child->sendParentChangeMessage(); - - callListeners (&ValueTree::Listener::valueTreeParentChanged, tree); - } - - void setProperty (const Identifier name, const var& newValue, UndoManager* const undoManager) - { - if (undoManager == nullptr) - { - if (properties.set (name, newValue)) - sendPropertyChangeMessage (name); - } - else - { - if (const var* const existingValue = properties.getVarPointer (name)) - { - if (*existingValue != newValue) - undoManager->perform (new SetPropertyAction (this, name, newValue, *existingValue, false, false)); - } - else - { - undoManager->perform (new SetPropertyAction (this, name, newValue, var(), true, false)); - } - } - } - - bool hasProperty (const Identifier name) const noexcept - { - return properties.contains (name); - } - - void removeProperty (const Identifier name, UndoManager* const undoManager) - { - if (undoManager == nullptr) - { - if (properties.remove (name)) - sendPropertyChangeMessage (name); - } - else - { - if (properties.contains (name)) - undoManager->perform (new SetPropertyAction (this, name, var(), properties [name], false, true)); - } - } - - void removeAllProperties (UndoManager* const undoManager) - { - if (undoManager == nullptr) - { - while (properties.size() > 0) - { - const Identifier name (properties.getName (properties.size() - 1)); - properties.remove (name); - sendPropertyChangeMessage (name); - } - } - else - { - for (int i = properties.size(); --i >= 0;) - undoManager->perform (new SetPropertyAction (this, properties.getName(i), var(), - properties.getValueAt(i), false, true)); - } - } - - void copyPropertiesFrom (const SharedObject& source, UndoManager* const undoManager) - { - for (int i = properties.size(); --i >= 0;) - if (! source.properties.contains (properties.getName (i))) - removeProperty (properties.getName (i), undoManager); - - for (int i = 0; i < source.properties.size(); ++i) - setProperty (source.properties.getName(i), source.properties.getValueAt(i), undoManager); - } - - ValueTree getChildWithName (const Identifier typeToMatch) const - { - for (int i = 0; i < children.size(); ++i) - { - SharedObject* const s = children.getObjectPointerUnchecked (i); - if (s->type == typeToMatch) - return ValueTree (s); - } - - return ValueTree(); - } - - ValueTree getOrCreateChildWithName (const Identifier typeToMatch, UndoManager* undoManager) - { - for (int i = 0; i < children.size(); ++i) - { - SharedObject* const s = children.getObjectPointerUnchecked (i); - if (s->type == typeToMatch) - return ValueTree (s); - } - - SharedObject* const newObject = new SharedObject (typeToMatch); - addChild (newObject, -1, undoManager); - return ValueTree (newObject); - - } - - ValueTree getChildWithProperty (const Identifier propertyName, const var& propertyValue) const - { - for (int i = 0; i < children.size(); ++i) - { - SharedObject* const s = children.getObjectPointerUnchecked (i); - if (s->properties[propertyName] == propertyValue) - return ValueTree (s); - } - - return ValueTree(); - } - - bool isAChildOf (const SharedObject* const possibleParent) const noexcept - { - for (const SharedObject* p = parent; p != nullptr; p = p->parent) - if (p == possibleParent) - return true; - - return false; - } - - int indexOf (const ValueTree& child) const noexcept - { - return children.indexOf (child.object); - } - - void addChild (SharedObject* child, int index, UndoManager* const undoManager) - { - if (child != nullptr && child->parent != this) - { - if (child != this && ! isAChildOf (child)) - { - // You should always make sure that a child is removed from its previous parent before - // adding it somewhere else - otherwise, it's ambiguous as to whether a different - // undomanager should be used when removing it from its current parent.. - jassert (child->parent == nullptr); - - if (child->parent != nullptr) - { - jassert (child->parent->children.indexOf (child) >= 0); - child->parent->removeChild (child->parent->children.indexOf (child), undoManager); - } - - if (undoManager == nullptr) - { - children.insert (index, child); - child->parent = this; - sendChildAddedMessage (ValueTree (child)); - child->sendParentChangeMessage(); - } - else - { - if (! isPositiveAndBelow (index, children.size())) - index = children.size(); - - undoManager->perform (new AddOrRemoveChildAction (this, index, child)); - } - } - else - { - // You're attempting to create a recursive loop! A node - // can't be a child of one of its own children! - jassertfalse; - } - } - } - - void removeChild (const int childIndex, UndoManager* const undoManager) - { - if (const Ptr child = children.getObjectPointer (childIndex)) - { - if (undoManager == nullptr) - { - children.remove (childIndex); - child->parent = nullptr; - sendChildRemovedMessage (ValueTree (child)); - child->sendParentChangeMessage(); - } - else - { - undoManager->perform (new AddOrRemoveChildAction (this, childIndex, nullptr)); - } - } - } - - void removeAllChildren (UndoManager* const undoManager) - { - while (children.size() > 0) - removeChild (children.size() - 1, undoManager); - } - - void moveChild (int currentIndex, int newIndex, UndoManager* undoManager) - { - // The source index must be a valid index! - jassert (isPositiveAndBelow (currentIndex, children.size())); - - if (currentIndex != newIndex - && isPositiveAndBelow (currentIndex, children.size())) - { - if (undoManager == nullptr) - { - children.move (currentIndex, newIndex); - sendChildOrderChangedMessage(); - } - else - { - if (! isPositiveAndBelow (newIndex, children.size())) - newIndex = children.size() - 1; - - undoManager->perform (new MoveChildAction (this, currentIndex, newIndex)); - } - } - } - - void reorderChildren (const OwnedArray& newOrder, UndoManager* undoManager) - { - jassert (newOrder.size() == children.size()); - - if (undoManager == nullptr) - { - children.clear(); - children.ensureStorageAllocated (newOrder.size()); - - for (int i = 0; i < newOrder.size(); ++i) - children.add (newOrder.getUnchecked(i)->object); - - sendChildOrderChangedMessage(); - } - else - { - for (int i = 0; i < children.size(); ++i) - { - SharedObject* const child = newOrder.getUnchecked(i)->object; - - if (children.getObjectPointerUnchecked (i) != child) - { - const int oldIndex = children.indexOf (child); - jassert (oldIndex >= 0); - moveChild (oldIndex, i, undoManager); - } - } - } - } - - bool isEquivalentTo (const SharedObject& other) const - { - if (type != other.type - || properties.size() != other.properties.size() - || children.size() != other.children.size() - || properties != other.properties) - return false; - - for (int i = 0; i < children.size(); ++i) - if (! children.getObjectPointerUnchecked(i)->isEquivalentTo (*other.children.getObjectPointerUnchecked(i))) - return false; - - return true; - } - - XmlElement* createXml() const - { - XmlElement* const xml = new XmlElement (type); - properties.copyToXmlAttributes (*xml); - - // (NB: it's faster to add nodes to XML elements in reverse order) - for (int i = children.size(); --i >= 0;) - xml->prependChildElement (children.getObjectPointerUnchecked(i)->createXml()); - - return xml; - } - - void writeToStream (OutputStream& output) const - { - output.writeString (type.toString()); - output.writeCompressedInt (properties.size()); - - for (int j = 0; j < properties.size(); ++j) - { - output.writeString (properties.getName (j).toString()); - properties.getValueAt(j).writeToStream (output); - } - - output.writeCompressedInt (children.size()); - - for (int i = 0; i < children.size(); ++i) - writeObjectToStream (output, children.getObjectPointerUnchecked(i)); - } - - static void writeObjectToStream (OutputStream& output, const SharedObject* const object) - { - if (object != nullptr) - { - object->writeToStream (output); - } - else - { - output.writeString (String()); - output.writeCompressedInt (0); - output.writeCompressedInt (0); - } - } - - //============================================================================== - class SetPropertyAction : public UndoableAction - { - public: - SetPropertyAction (SharedObject* const so, const Identifier propertyName, - const var& newVal, const var& oldVal, bool isAdding, bool isDeleting) - : target (so), name (propertyName), newValue (newVal), oldValue (oldVal), - isAddingNewProperty (isAdding), isDeletingProperty (isDeleting) - { - } - - bool perform() - { - jassert (! (isAddingNewProperty && target->hasProperty (name))); - - if (isDeletingProperty) - target->removeProperty (name, nullptr); - else - target->setProperty (name, newValue, nullptr); - - return true; - } - - bool undo() - { - if (isAddingNewProperty) - target->removeProperty (name, nullptr); - else - target->setProperty (name, oldValue, nullptr); - - return true; - } - - int getSizeInUnits() - { - return (int) sizeof (*this); //xxx should be more accurate - } - - UndoableAction* createCoalescedAction (UndoableAction* nextAction) - { - if (! (isAddingNewProperty || isDeletingProperty)) - { - if (SetPropertyAction* const next = dynamic_cast (nextAction)) - if (next->target == target && next->name == name - && ! (next->isAddingNewProperty || next->isDeletingProperty)) - return new SetPropertyAction (target, name, next->newValue, oldValue, false, false); - } - - return nullptr; - } - - private: - const Ptr target; - const Identifier name; - const var newValue; - var oldValue; - const bool isAddingNewProperty : 1, isDeletingProperty : 1; - - JUCE_DECLARE_NON_COPYABLE (SetPropertyAction) - }; - - //============================================================================== - class AddOrRemoveChildAction : public UndoableAction - { - public: - AddOrRemoveChildAction (SharedObject* parentObject, int index, SharedObject* newChild) - : target (parentObject), - child (newChild != nullptr ? newChild : parentObject->children.getObjectPointer (index)), - childIndex (index), - isDeleting (newChild == nullptr) - { - jassert (child != nullptr); - } - - bool perform() - { - if (isDeleting) - target->removeChild (childIndex, nullptr); - else - target->addChild (child, childIndex, nullptr); - - return true; - } - - bool undo() - { - if (isDeleting) - { - target->addChild (child, childIndex, nullptr); - } - else - { - // If you hit this, it seems that your object's state is getting confused - probably - // because you've interleaved some undoable and non-undoable operations? - jassert (childIndex < target->children.size()); - target->removeChild (childIndex, nullptr); - } - - return true; - } - - int getSizeInUnits() - { - return (int) sizeof (*this); //xxx should be more accurate - } - - private: - const Ptr target, child; - const int childIndex; - const bool isDeleting; - - JUCE_DECLARE_NON_COPYABLE (AddOrRemoveChildAction) - }; - - //============================================================================== - class MoveChildAction : public UndoableAction - { - public: - MoveChildAction (SharedObject* parentObject, int fromIndex, int toIndex) noexcept - : parent (parentObject), startIndex (fromIndex), endIndex (toIndex) - { - } - - bool perform() - { - parent->moveChild (startIndex, endIndex, nullptr); - return true; - } - - bool undo() - { - parent->moveChild (endIndex, startIndex, nullptr); - return true; - } - - int getSizeInUnits() - { - return (int) sizeof (*this); //xxx should be more accurate - } - - UndoableAction* createCoalescedAction (UndoableAction* nextAction) - { - if (MoveChildAction* next = dynamic_cast (nextAction)) - if (next->parent == parent && next->startIndex == endIndex) - return new MoveChildAction (parent, startIndex, next->endIndex); - - return nullptr; - } - - private: - const Ptr parent; - const int startIndex, endIndex; - - JUCE_DECLARE_NON_COPYABLE (MoveChildAction) - }; - - //============================================================================== - const Identifier type; - NamedValueSet properties; - ReferenceCountedArray children; - SortedSet valueTreesWithListeners; - SharedObject* parent; - -private: - SharedObject& operator= (const SharedObject&); - JUCE_LEAK_DETECTOR (SharedObject) -}; - -//============================================================================== -ValueTree::ValueTree() noexcept -{ -} - -const ValueTree ValueTree::invalid; - -ValueTree::ValueTree (Identifier type) : object (new ValueTree::SharedObject (type)) -{ - jassert (type.toString().isNotEmpty()); // All objects must be given a sensible type name! -} - -ValueTree::ValueTree (SharedObject* so) : object (so) -{ -} - -ValueTree::ValueTree (const ValueTree& other) : object (other.object) -{ -} - -ValueTree& ValueTree::operator= (const ValueTree& other) -{ - if (object != other.object) - { - if (listeners.isEmpty()) - { - object = other.object; - } - else - { - if (object != nullptr) - object->valueTreesWithListeners.removeValue (this); - - if (other.object != nullptr) - other.object->valueTreesWithListeners.add (this); - - object = other.object; - - listeners.call (&ValueTree::Listener::valueTreeRedirected, *this); - } - } - - return *this; -} - -#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS -ValueTree::ValueTree (ValueTree&& other) noexcept - : object (static_cast (other.object)) -{ -} -#endif - -ValueTree::~ValueTree() -{ - if (listeners.size() > 0 && object != nullptr) - object->valueTreesWithListeners.removeValue (this); -} - -bool ValueTree::operator== (const ValueTree& other) const noexcept -{ - return object == other.object; -} - -bool ValueTree::operator!= (const ValueTree& other) const noexcept -{ - return object != other.object; -} - -bool ValueTree::isEquivalentTo (const ValueTree& other) const -{ - return object == other.object - || (object != nullptr && other.object != nullptr - && object->isEquivalentTo (*other.object)); -} - -ValueTree ValueTree::createCopy() const -{ - return ValueTree (createCopyIfNotNull (object.get())); -} - -bool ValueTree::hasType (const Identifier typeName) const -{ - return object != nullptr && object->type == typeName; -} - -Identifier ValueTree::getType() const -{ - return object != nullptr ? object->type : Identifier(); -} - -ValueTree ValueTree::getParent() const -{ - return ValueTree (object != nullptr ? object->parent - : static_cast (nullptr)); -} - -ValueTree ValueTree::getSibling (const int delta) const -{ - if (object == nullptr || object->parent == nullptr) - return invalid; - - const int index = object->parent->indexOf (*this) + delta; - return ValueTree (object->parent->children.getObjectPointer (index)); -} - -const var& ValueTree::operator[] (const Identifier name) const -{ - return object == nullptr ? var::null : object->properties[name]; -} - -const var& ValueTree::getProperty (const Identifier name) const -{ - return object == nullptr ? var::null : object->properties[name]; -} - -var ValueTree::getProperty (const Identifier name, const var& defaultReturnValue) const -{ - return object == nullptr ? defaultReturnValue - : object->properties.getWithDefault (name, defaultReturnValue); -} - -ValueTree& ValueTree::setProperty (const Identifier name, const var& newValue, - UndoManager* const undoManager) -{ - jassert (name.toString().isNotEmpty()); // Must have a valid property name! - jassert (object != nullptr); // Trying to add a property to a null ValueTree will fail! - - if (object != nullptr) - object->setProperty (name, newValue, undoManager); - - return *this; -} - -bool ValueTree::hasProperty (const Identifier name) const -{ - return object != nullptr && object->hasProperty (name); -} - -void ValueTree::removeProperty (const Identifier name, UndoManager* const undoManager) -{ - if (object != nullptr) - object->removeProperty (name, undoManager); -} - -void ValueTree::removeAllProperties (UndoManager* const undoManager) -{ - if (object != nullptr) - object->removeAllProperties (undoManager); -} - -int ValueTree::getNumProperties() const -{ - return object == nullptr ? 0 : object->properties.size(); -} - -Identifier ValueTree::getPropertyName (const int index) const -{ - return object == nullptr ? Identifier() - : object->properties.getName (index); -} - -void ValueTree::copyPropertiesFrom (const ValueTree& source, UndoManager* const undoManager) -{ - jassert (object != nullptr || source.object == nullptr); // Trying to add properties to a null ValueTree will fail! - - if (source.object == nullptr) - removeAllProperties (undoManager); - else if (object != nullptr) - object->copyPropertiesFrom (*(source.object), undoManager); -} - -int ValueTree::getReferenceCount() const noexcept -{ - return object != nullptr ? object->getReferenceCount() : 0; -} - -//============================================================================== -class ValueTreePropertyValueSource : public Value::ValueSource, - private ValueTree::Listener -{ -public: - ValueTreePropertyValueSource (const ValueTree& vt, const Identifier prop, UndoManager* um) - : tree (vt), property (prop), undoManager (um) - { - tree.addListener (this); - } - - ~ValueTreePropertyValueSource() - { - tree.removeListener (this); - } - - var getValue() const { return tree [property]; } - void setValue (const var& newValue) { tree.setProperty (property, newValue, undoManager); } - -private: - ValueTree tree; - const Identifier property; - UndoManager* const undoManager; - - void valueTreePropertyChanged (ValueTree& changedTree, const Identifier& changedProperty) override - { - if (tree == changedTree && property == changedProperty) - sendChangeMessage (false); - } - - void valueTreeChildAdded (ValueTree&, ValueTree&) override {} - void valueTreeChildRemoved (ValueTree&, ValueTree&) override {} - void valueTreeChildOrderChanged (ValueTree&) override {} - void valueTreeParentChanged (ValueTree&) override {} - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ValueTreePropertyValueSource) -}; - -Value ValueTree::getPropertyAsValue (const Identifier name, UndoManager* const undoManager) -{ - return Value (new ValueTreePropertyValueSource (*this, name, undoManager)); -} - -//============================================================================== -int ValueTree::getNumChildren() const -{ - return object == nullptr ? 0 : object->children.size(); -} - -ValueTree ValueTree::getChild (int index) const -{ - return ValueTree (object != nullptr ? object->children.getObjectPointer (index) - : static_cast (nullptr)); -} - -ValueTree ValueTree::getChildWithName (const Identifier type) const -{ - return object != nullptr ? object->getChildWithName (type) : ValueTree(); -} - -ValueTree ValueTree::getOrCreateChildWithName (const Identifier type, UndoManager* undoManager) -{ - return object != nullptr ? object->getOrCreateChildWithName (type, undoManager) : ValueTree(); -} - -ValueTree ValueTree::getChildWithProperty (const Identifier propertyName, const var& propertyValue) const -{ - return object != nullptr ? object->getChildWithProperty (propertyName, propertyValue) : ValueTree(); -} - -bool ValueTree::isAChildOf (const ValueTree& possibleParent) const -{ - return object != nullptr && object->isAChildOf (possibleParent.object); -} - -int ValueTree::indexOf (const ValueTree& child) const -{ - return object != nullptr ? object->indexOf (child) : -1; -} - -void ValueTree::addChild (const ValueTree& child, int index, UndoManager* const undoManager) -{ - jassert (object != nullptr); // Trying to add a child to a null ValueTree! - - if (object != nullptr) - object->addChild (child.object, index, undoManager); -} - -void ValueTree::removeChild (const int childIndex, UndoManager* const undoManager) -{ - if (object != nullptr) - object->removeChild (childIndex, undoManager); -} - -void ValueTree::removeChild (const ValueTree& child, UndoManager* const undoManager) -{ - if (object != nullptr) - object->removeChild (object->children.indexOf (child.object), undoManager); -} - -void ValueTree::removeAllChildren (UndoManager* const undoManager) -{ - if (object != nullptr) - object->removeAllChildren (undoManager); -} - -void ValueTree::moveChild (int currentIndex, int newIndex, UndoManager* undoManager) -{ - if (object != nullptr) - object->moveChild (currentIndex, newIndex, undoManager); -} - -//============================================================================== -void ValueTree::createListOfChildren (OwnedArray& list) const -{ - jassert (object != nullptr); - - for (int i = 0; i < object->children.size(); ++i) - list.add (new ValueTree (object->children.getObjectPointerUnchecked(i))); -} - -void ValueTree::reorderChildren (const OwnedArray& newOrder, UndoManager* undoManager) -{ - jassert (object != nullptr); - object->reorderChildren (newOrder, undoManager); -} - -//============================================================================== -void ValueTree::addListener (Listener* listener) -{ - if (listener != nullptr) - { - if (listeners.isEmpty() && object != nullptr) - object->valueTreesWithListeners.add (this); - - listeners.add (listener); - } -} - -void ValueTree::removeListener (Listener* listener) -{ - listeners.remove (listener); - - if (listeners.isEmpty() && object != nullptr) - object->valueTreesWithListeners.removeValue (this); -} - -void ValueTree::sendPropertyChangeMessage (const Identifier property) -{ - if (object != nullptr) - object->sendPropertyChangeMessage (property); -} - -//============================================================================== -XmlElement* ValueTree::createXml() const -{ - return object != nullptr ? object->createXml() : nullptr; -} - -ValueTree ValueTree::fromXml (const XmlElement& xml) -{ - // ValueTrees don't have any equivalent to XML text elements! - jassert (! xml.isTextElement()); - - ValueTree v (xml.getTagName()); - v.object->properties.setFromXmlAttributes (xml); - - forEachXmlChildElement (xml, e) - v.addChild (fromXml (*e), -1, nullptr); - - return v; -} - -String ValueTree::toXmlString() const -{ - const ScopedPointer xml (createXml()); - return xml != nullptr ? xml->createDocument ("") : String(); -} - -//============================================================================== -void ValueTree::writeToStream (OutputStream& output) const -{ - SharedObject::writeObjectToStream (output, object); -} - -ValueTree ValueTree::readFromStream (InputStream& input) -{ - const String type (input.readString()); - - if (type.isEmpty()) - return ValueTree(); - - ValueTree v (type); - - const int numProps = input.readCompressedInt(); - - if (numProps < 0) - { - jassertfalse; // trying to read corrupted data! - return v; - } - - for (int i = 0; i < numProps; ++i) - { - const String name (input.readString()); - jassert (name.isNotEmpty()); - const var value (var::readFromStream (input)); - v.object->properties.set (name, value); - } - - const int numChildren = input.readCompressedInt(); - v.object->children.ensureStorageAllocated (numChildren); - - for (int i = 0; i < numChildren; ++i) - { - ValueTree child (readFromStream (input)); - - v.object->children.add (child.object); - child.object->parent = v.object; - } - - return v; -} - -ValueTree ValueTree::readFromData (const void* const data, const size_t numBytes) -{ - MemoryInputStream in (data, numBytes, false); - return readFromStream (in); -} - -ValueTree ValueTree::readFromGZIPData (const void* const data, const size_t numBytes) -{ - MemoryInputStream in (data, numBytes, false); - GZIPDecompressorInputStream gzipStream (in); - return readFromStream (gzipStream); -} - -void ValueTree::Listener::valueTreeRedirected (ValueTree&) {} - -//============================================================================== -#if JUCE_UNIT_TESTS - -class ValueTreeTests : public UnitTest -{ -public: - ValueTreeTests() : UnitTest ("ValueTrees") {} - - static String createRandomIdentifier (Random& r) - { - char buffer[50] = { 0 }; - const char chars[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-:"; - - for (int i = 1 + r.nextInt (numElementsInArray (buffer) - 2); --i >= 0;) - buffer[i] = chars [r.nextInt (sizeof (chars) - 1)]; - - return CharPointer_ASCII (buffer); - } - - static String createRandomWideCharString (Random& r) - { - juce_wchar buffer[50] = { 0 }; - - for (int i = r.nextInt (numElementsInArray (buffer) - 1); --i >= 0;) - { - if (r.nextBool()) - { - do - { - buffer[i] = (juce_wchar) (1 + r.nextInt (0x10ffff - 1)); - } - while (! CharPointer_UTF16::canRepresent (buffer[i])); - } - else - buffer[i] = (juce_wchar) (1 + r.nextInt (0x7e)); - } - - return CharPointer_UTF32 (buffer); - } - - static ValueTree createRandomTree (UndoManager* undoManager, int depth, Random& r) - { - ValueTree v (createRandomIdentifier (r)); - - for (int i = r.nextInt (10); --i >= 0;) - { - switch (r.nextInt (5)) - { - case 0: v.setProperty (createRandomIdentifier (r), createRandomWideCharString (r), undoManager); break; - case 1: v.setProperty (createRandomIdentifier (r), r.nextInt(), undoManager); break; - case 2: if (depth < 5) v.addChild (createRandomTree (undoManager, depth + 1, r), r.nextInt (v.getNumChildren() + 1), undoManager); break; - case 3: v.setProperty (createRandomIdentifier (r), r.nextBool(), undoManager); break; - case 4: v.setProperty (createRandomIdentifier (r), r.nextDouble(), undoManager); break; - default: break; - } - } - - return v; - } - - void runTest() - { - beginTest ("ValueTree"); - Random r = getRandom(); - - for (int i = 10; --i >= 0;) - { - MemoryOutputStream mo; - ValueTree v1 (createRandomTree (nullptr, 0, r)); - v1.writeToStream (mo); - - MemoryInputStream mi (mo.getData(), mo.getDataSize(), false); - ValueTree v2 = ValueTree::readFromStream (mi); - expect (v1.isEquivalentTo (v2)); - - ScopedPointer xml1 (v1.createXml()); - ScopedPointer xml2 (v2.createCopy().createXml()); - expect (xml1->isEquivalentTo (xml2, false)); - - ValueTree v4 = v2.createCopy(); - expect (v1.isEquivalentTo (v4)); - } - } -}; - -static ValueTreeTests valueTreeTests; - -#endif diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_data_structures/values/juce_ValueTree.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_data_structures/values/juce_ValueTree.h deleted file mode 100644 index 42dd778116..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_data_structures/values/juce_ValueTree.h +++ /dev/null @@ -1,531 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_VALUETREE_H_INCLUDED -#define JUCE_VALUETREE_H_INCLUDED - - -//============================================================================== -/** - A powerful tree structure that can be used to hold free-form data, and which can - handle its own undo and redo behaviour. - - A ValueTree contains a list of named properties as var objects, and also holds - any number of sub-trees. - - Create ValueTree objects on the stack, and don't be afraid to copy them around, as - they're simply a lightweight reference to a shared data container. Creating a copy - of another ValueTree simply creates a new reference to the same underlying object - to - make a separate, deep copy of a tree you should explicitly call createCopy(). - - Each ValueTree has a type name, in much the same way as an XmlElement has a tag name, - and much of the structure of a ValueTree is similar to an XmlElement tree. - You can convert a ValueTree to and from an XmlElement, and as long as the XML doesn't - contain text elements, the conversion works well and makes a good serialisation - format. They can also be serialised to a binary format, which is very fast and compact. - - All the methods that change data take an optional UndoManager, which will be used - to track any changes to the object. For this to work, you have to be careful to - consistently always use the same UndoManager for all operations to any node inside - the tree. - - A ValueTree can only be a child of one parent at a time, so if you're moving one from - one tree to another, be careful to always remove it first, before adding it. This - could also mess up your undo/redo chain, so be wary! In a debug build you should hit - assertions if you try to do anything dangerous, but there are still plenty of ways it - could go wrong. - - Listeners can be added to a ValueTree to be told when properies change and when - nodes are added or removed. - - @see var, XmlElement -*/ -class JUCE_API ValueTree -{ -public: - //============================================================================== - /** Creates an empty, invalid ValueTree. - - A ValueTree that is created with this constructor can't actually be used for anything, - it's just a default 'null' ValueTree that can be returned to indicate some sort of failure. - To create a real one, use the constructor that takes a string. - - @see ValueTree::invalid - */ - ValueTree() noexcept; - - /** Creates an empty ValueTree with the given type name. - Like an XmlElement, each ValueTree node has a type, which you can access with - getType() and hasType(). - */ - explicit ValueTree (Identifier type); - - /** Creates a reference to another ValueTree. */ - ValueTree (const ValueTree&); - - /** Makes this object reference another node. */ - ValueTree& operator= (const ValueTree&); - - #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS - ValueTree (ValueTree&&) noexcept; - #endif - - /** Destructor. */ - ~ValueTree(); - - /** Returns true if both this and the other tree node refer to the same underlying structure. - Note that this isn't a value comparison - two independently-created trees which - contain identical data are not considered equal. - */ - bool operator== (const ValueTree&) const noexcept; - - /** Returns true if this and the other node refer to different underlying structures. - Note that this isn't a value comparison - two independently-created trees which - contain identical data are not considered equal. - */ - bool operator!= (const ValueTree&) const noexcept; - - /** Performs a deep comparison between the properties and children of two trees. - If all the properties and children of the two trees are the same (recursively), this - returns true. - The normal operator==() only checks whether two trees refer to the same shared data - structure, so use this method if you need to do a proper value comparison. - */ - bool isEquivalentTo (const ValueTree&) const; - - //============================================================================== - /** Returns true if this node refers to some valid data. - It's hard to create an invalid node, but you might get one returned, e.g. by an out-of-range - call to getChild(). - */ - bool isValid() const { return object != nullptr; } - - /** Returns a deep copy of this tree and all its sub-nodes. */ - ValueTree createCopy() const; - - //============================================================================== - /** Returns the type of this node. - The type is specified when the ValueTree is created. - @see hasType - */ - Identifier getType() const; - - /** Returns true if the node has this type. - The comparison is case-sensitive. - */ - bool hasType (const Identifier typeName) const; - - //============================================================================== - /** Returns the value of a named property. - If no such property has been set, this will return a void variant. - You can also use operator[] to get a property. - @see var, setProperty, hasProperty - */ - const var& getProperty (const Identifier name) const; - - /** Returns the value of a named property, or a user-specified default if the property doesn't exist. - If no such property has been set, this will return the value of defaultReturnValue. - You can also use operator[] and getProperty to get a property. - @see var, getProperty, setProperty, hasProperty - */ - var getProperty (const Identifier name, const var& defaultReturnValue) const; - - /** Returns the value of a named property. - If no such property has been set, this will return a void variant. This is the same as - calling getProperty(). - @see getProperty - */ - const var& operator[] (const Identifier name) const; - - /** Changes a named property of the node. - The name identifier must not be an empty string. - If the undoManager parameter is non-null, its UndoManager::perform() method will be used, - so that this change can be undone. - @see var, getProperty, removeProperty - @returns a reference to the value tree, so that you can daisy-chain calls to this method. - */ - ValueTree& setProperty (const Identifier name, const var& newValue, UndoManager* undoManager); - - /** Returns true if the node contains a named property. */ - bool hasProperty (const Identifier name) const; - - /** Removes a property from the node. - If the undoManager parameter is non-null, its UndoManager::perform() method will be used, - so that this change can be undone. - */ - void removeProperty (const Identifier name, UndoManager* undoManager); - - /** Removes all properties from the node. - If the undoManager parameter is non-null, its UndoManager::perform() method will be used, - so that this change can be undone. - */ - void removeAllProperties (UndoManager* undoManager); - - /** Returns the total number of properties that the node contains. - @see getProperty. - */ - int getNumProperties() const; - - /** Returns the identifier of the property with a given index. - @see getNumProperties - */ - Identifier getPropertyName (int index) const; - - /** Returns a Value object that can be used to control and respond to one of the tree's properties. - - The Value object will maintain a reference to this tree, and will use the undo manager when - it needs to change the value. Attaching a Value::Listener to the value object will provide - callbacks whenever the property changes. - */ - Value getPropertyAsValue (const Identifier name, UndoManager* undoManager); - - /** Overwrites all the properties in this tree with the properties of the source tree. - Any properties that already exist will be updated; and new ones will be added, and - any that are not present in the source tree will be removed. - */ - void copyPropertiesFrom (const ValueTree& source, UndoManager* undoManager); - - //============================================================================== - /** Returns the number of child nodes belonging to this one. - @see getChild - */ - int getNumChildren() const; - - /** Returns one of this node's child nodes. - If the index is out of range, it'll return an invalid node. (See isValid() to find out - whether a node is valid). - */ - ValueTree getChild (int index) const; - - /** Returns the first child node with the speficied type name. - If no such node is found, it'll return an invalid node. (See isValid() to find out - whether a node is valid). - @see getOrCreateChildWithName - */ - ValueTree getChildWithName (const Identifier type) const; - - /** Returns the first child node with the speficied type name, creating and adding - a child with this name if there wasn't already one there. - - The only time this will return an invalid object is when the object that you're calling - the method on is itself invalid. - @see getChildWithName - */ - ValueTree getOrCreateChildWithName (const Identifier type, UndoManager* undoManager); - - /** Looks for the first child node that has the speficied property value. - - This will scan the child nodes in order, until it finds one that has property that matches - the specified value. - - If no such node is found, it'll return an invalid node. (See isValid() to find out - whether a node is valid). - */ - ValueTree getChildWithProperty (const Identifier propertyName, const var& propertyValue) const; - - /** Adds a child to this node. - - Make sure that the child is removed from any former parent node before calling this, or - you'll hit an assertion. - - If the index is < 0 or greater than the current number of child nodes, the new node will - be added at the end of the list. - - If the undoManager parameter is non-null, its UndoManager::perform() method will be used, - so that this change can be undone. - */ - void addChild (const ValueTree& child, int index, UndoManager* undoManager); - - /** Removes the specified child from this node's child-list. - If the undoManager parameter is non-null, its UndoManager::perform() method will be used, - so that this change can be undone. - */ - void removeChild (const ValueTree& child, UndoManager* undoManager); - - /** Removes a child from this node's child-list. - If the undoManager parameter is non-null, its UndoManager::perform() method will be used, - so that this change can be undone. - */ - void removeChild (int childIndex, UndoManager* undoManager); - - /** Removes all child-nodes from this node. - If the undoManager parameter is non-null, its UndoManager::perform() method will be used, - so that this change can be undone. - */ - void removeAllChildren (UndoManager* undoManager); - - /** Moves one of the children to a different index. - - This will move the child to a specified index, shuffling along any intervening - items as required. So for example, if you have a list of { 0, 1, 2, 3, 4, 5 }, then - calling move (2, 4) would result in { 0, 1, 3, 4, 2, 5 }. - - @param currentIndex the index of the item to be moved. If this isn't a - valid index, then nothing will be done - @param newIndex the index at which you'd like this item to end up. If this - is less than zero, the value will be moved to the end - of the list - @param undoManager the optional UndoManager to use to store this transaction - */ - void moveChild (int currentIndex, int newIndex, UndoManager* undoManager); - - /** Returns true if this node is anywhere below the specified parent node. - This returns true if the node is a child-of-a-child, as well as a direct child. - */ - bool isAChildOf (const ValueTree& possibleParent) const; - - /** Returns the index of a child item in this parent. - If the child isn't found, this returns -1. - */ - int indexOf (const ValueTree& child) const; - - /** Returns the parent node that contains this one. - If the node has no parent, this will return an invalid node. (See isValid() to find out - whether a node is valid). - */ - ValueTree getParent() const; - - /** Returns one of this node's siblings in its parent's child list. - - The delta specifies how far to move through the list, so a value of 1 would return the node - that follows this one, -1 would return the node before it, 0 will return this node itself, etc. - If the requested position is beyond the range of available nodes, this will return ValueTree::invalid. - */ - ValueTree getSibling (int delta) const; - - //============================================================================== - /** Creates an XmlElement that holds a complete image of this node and all its children. - - If this node is invalid, this may return nullptr. Otherwise, the XML that is produced can - be used to recreate a similar node by calling fromXml(). - - The caller must delete the object that is returned. - - @see fromXml - */ - XmlElement* createXml() const; - - /** Tries to recreate a node from its XML representation. - - This isn't designed to cope with random XML data - for a sensible result, it should only - be fed XML that was created by the createXml() method. - */ - static ValueTree fromXml (const XmlElement& xml); - - /** This returns a string containing an XML representation of the tree. - This is quite handy for debugging purposes, as it provides a quick way to view a tree. - */ - String toXmlString() const; - - //============================================================================== - /** Stores this tree (and all its children) in a binary format. - - Once written, the data can be read back with readFromStream(). - - It's much faster to load/save your tree in binary form than as XML, but - obviously isn't human-readable. - */ - void writeToStream (OutputStream& output) const; - - /** Reloads a tree from a stream that was written with writeToStream(). */ - static ValueTree readFromStream (InputStream& input); - - /** Reloads a tree from a data block that was written with writeToStream(). */ - static ValueTree readFromData (const void* data, size_t numBytes); - - /** Reloads a tree from a data block that was written with writeToStream() and - then zipped using GZIPCompressorOutputStream. - */ - static ValueTree readFromGZIPData (const void* data, size_t numBytes); - - //============================================================================== - /** Listener class for events that happen to a ValueTree. - - To get events from a ValueTree, make your class implement this interface, and use - ValueTree::addListener() and ValueTree::removeListener() to register it. - */ - class JUCE_API Listener - { - public: - /** Destructor. */ - virtual ~Listener() {} - - /** This method is called when a property of this node (or of one of its sub-nodes) has - changed. - - The tree parameter indicates which tree has had its property changed, and the property - parameter indicates the property. - - Note that when you register a listener to a tree, it will receive this callback for - property changes in that tree, and also for any of its children, (recursively, at any depth). - If your tree has sub-trees but you only want to know about changes to the top level tree, - simply check the tree parameter in this callback to make sure it's the tree you're interested in. - */ - virtual void valueTreePropertyChanged (ValueTree& treeWhosePropertyHasChanged, - const Identifier& property) = 0; - - /** This method is called when a child sub-tree is added. - - Note that when you register a listener to a tree, it will receive this callback for - child changes in both that tree and any of its children, (recursively, at any depth). - If your tree has sub-trees but you only want to know about changes to the top level tree, - just check the parentTree parameter to make sure it's the one that you're interested in. - */ - virtual void valueTreeChildAdded (ValueTree& parentTree, - ValueTree& childWhichHasBeenAdded) = 0; - - /** This method is called when a child sub-tree is removed. - - Note that when you register a listener to a tree, it will receive this callback for - child changes in both that tree and any of its children, (recursively, at any depth). - If your tree has sub-trees but you only want to know about changes to the top level tree, - just check the parentTree parameter to make sure it's the one that you're interested in. - */ - virtual void valueTreeChildRemoved (ValueTree& parentTree, - ValueTree& childWhichHasBeenRemoved) = 0; - - /** This method is called when a tree's children have been re-shuffled. - - Note that when you register a listener to a tree, it will receive this callback for - child changes in both that tree and any of its children, (recursively, at any depth). - If your tree has sub-trees but you only want to know about changes to the top level tree, - just check the parameter to make sure it's the tree that you're interested in. - */ - virtual void valueTreeChildOrderChanged (ValueTree& parentTreeWhoseChildrenHaveMoved) = 0; - - /** This method is called when a tree has been added or removed from a parent node. - - This callback happens when the tree to which the listener was registered is added or - removed from a parent. Unlike the other callbacks, it applies only to the tree to which - the listener is registered, and not to any of its children. - */ - virtual void valueTreeParentChanged (ValueTree& treeWhoseParentHasChanged) = 0; - - /** This method is called when a tree is made to point to a different internal shared object. - When operator= is used to make a ValueTree refer to a different object, this callback - will be made. - */ - virtual void valueTreeRedirected (ValueTree& treeWhichHasBeenChanged); - }; - - /** Adds a listener to receive callbacks when this node is changed. - - The listener is added to this specific ValueTree object, and not to the shared - object that it refers to. When this object is deleted, all the listeners will - be lost, even if other references to the same ValueTree still exist. And if you - use the operator= to make this refer to a different ValueTree, any listeners will - begin listening to changes to the new tree instead of the old one. - - When you're adding a listener, make sure that you add it to a ValueTree instance that - will last for as long as you need the listener. In general, you'd never want to add a - listener to a local stack-based ValueTree, and would usually add one to a member variable. - - @see removeListener - */ - void addListener (Listener* listener); - - /** Removes a listener that was previously added with addListener(). */ - void removeListener (Listener* listener); - - /** Causes a property-change callback to be triggered for the specified property, - calling any listeners that are registered. - */ - void sendPropertyChangeMessage (const Identifier property); - - //============================================================================== - /** This method uses a comparator object to sort the tree's children into order. - - The object provided must have a method of the form: - @code - int compareElements (const ValueTree& first, const ValueTree& second); - @endcode - - ..and this method must return: - - a value of < 0 if the first comes before the second - - a value of 0 if the two objects are equivalent - - a value of > 0 if the second comes before the first - - To improve performance, the compareElements() method can be declared as static or const. - - @param comparator the comparator to use for comparing elements. - @param undoManager optional UndoManager for storing the changes - @param retainOrderOfEquivalentItems if this is true, then items which the comparator says are - equivalent will be kept in the order in which they currently appear in the array. - This is slower to perform, but may be important in some cases. If it's false, a - faster algorithm is used, but equivalent elements may be rearranged. - */ - template - void sort (ElementComparator& comparator, UndoManager* undoManager, bool retainOrderOfEquivalentItems) - { - if (object != nullptr) - { - OwnedArray sortedList; - createListOfChildren (sortedList); - ComparatorAdapter adapter (comparator); - sortedList.sort (adapter, retainOrderOfEquivalentItems); - reorderChildren (sortedList, undoManager); - } - } - - /** An invalid ValueTree that can be used if you need to return one as an error condition, etc. - This invalid object is equivalent to ValueTree created with its default constructor. - */ - static const ValueTree invalid; - - /** Returns the total number of references to the shared underlying data structure that this - ValueTree is using. - */ - int getReferenceCount() const noexcept; - -private: - //============================================================================== - JUCE_PUBLIC_IN_DLL_BUILD (class SharedObject) - friend class SharedObject; - - ReferenceCountedObjectPtr object; - ListenerList listeners; - - template - struct ComparatorAdapter - { - ComparatorAdapter (ElementComparator& comp) noexcept : comparator (comp) {} - - int compareElements (const ValueTree* const first, const ValueTree* const second) - { - return comparator.compareElements (*first, *second); - } - - private: - ElementComparator& comparator; - JUCE_DECLARE_NON_COPYABLE (ComparatorAdapter) - }; - - void createListOfChildren (OwnedArray&) const; - void reorderChildren (const OwnedArray&, UndoManager*); - - explicit ValueTree (SharedObject*); -}; - - -#endif // JUCE_VALUETREE_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/broadcasters/juce_ActionBroadcaster.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/broadcasters/juce_ActionBroadcaster.cpp deleted file mode 100644 index 33f232d5b8..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/broadcasters/juce_ActionBroadcaster.cpp +++ /dev/null @@ -1,91 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -class ActionBroadcaster::ActionMessage : public MessageManager::MessageBase -{ -public: - ActionMessage (const ActionBroadcaster* ab, - const String& messageText, ActionListener* l) noexcept - : broadcaster (const_cast (ab)), - message (messageText), - listener (l) - {} - - void messageCallback() override - { - if (const ActionBroadcaster* const b = broadcaster) - if (b->actionListeners.contains (listener)) - listener->actionListenerCallback (message); - } - -private: - WeakReference broadcaster; - const String message; - ActionListener* const listener; - - JUCE_DECLARE_NON_COPYABLE (ActionMessage) -}; - -//============================================================================== -ActionBroadcaster::ActionBroadcaster() -{ - // are you trying to create this object before or after juce has been intialised?? - jassert (MessageManager::getInstanceWithoutCreating() != nullptr); -} - -ActionBroadcaster::~ActionBroadcaster() -{ - // all event-based objects must be deleted BEFORE juce is shut down! - jassert (MessageManager::getInstanceWithoutCreating() != nullptr); - - masterReference.clear(); -} - -void ActionBroadcaster::addActionListener (ActionListener* const listener) -{ - const ScopedLock sl (actionListenerLock); - - if (listener != nullptr) - actionListeners.add (listener); -} - -void ActionBroadcaster::removeActionListener (ActionListener* const listener) -{ - const ScopedLock sl (actionListenerLock); - actionListeners.removeValue (listener); -} - -void ActionBroadcaster::removeAllActionListeners() -{ - const ScopedLock sl (actionListenerLock); - actionListeners.clear(); -} - -void ActionBroadcaster::sendActionMessage (const String& message) const -{ - const ScopedLock sl (actionListenerLock); - - for (int i = actionListeners.size(); --i >= 0;) - (new ActionMessage (this, message, actionListeners.getUnchecked(i)))->post(); -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/broadcasters/juce_ActionBroadcaster.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/broadcasters/juce_ActionBroadcaster.h deleted file mode 100644 index 8052bed3c8..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/broadcasters/juce_ActionBroadcaster.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_ACTIONBROADCASTER_H_INCLUDED -#define JUCE_ACTIONBROADCASTER_H_INCLUDED - - -//============================================================================== -/** Manages a list of ActionListeners, and can send them messages. - - To quickly add methods to your class that can add/remove action - listeners and broadcast to them, you can derive from this. - - @see ActionListener, ChangeListener -*/ -class JUCE_API ActionBroadcaster -{ -public: - //============================================================================== - /** Creates an ActionBroadcaster. */ - ActionBroadcaster(); - - /** Destructor. */ - virtual ~ActionBroadcaster(); - - //============================================================================== - /** Adds a listener to the list. - Trying to add a listener that's already on the list will have no effect. - */ - void addActionListener (ActionListener* listener); - - /** Removes a listener from the list. - If the listener isn't on the list, this won't have any effect. - */ - void removeActionListener (ActionListener* listener); - - /** Removes all listeners from the list. */ - void removeAllActionListeners(); - - //============================================================================== - /** Broadcasts a message to all the registered listeners. - @see ActionListener::actionListenerCallback - */ - void sendActionMessage (const String& message) const; - - -private: - //============================================================================== - friend class WeakReference; - WeakReference::Master masterReference; - - class ActionMessage; - friend class ActionMessage; - - SortedSet actionListeners; - CriticalSection actionListenerLock; - - JUCE_DECLARE_NON_COPYABLE (ActionBroadcaster) -}; - - -#endif // JUCE_ACTIONBROADCASTER_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/broadcasters/juce_ActionListener.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/broadcasters/juce_ActionListener.h deleted file mode 100644 index 12257f93d7..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/broadcasters/juce_ActionListener.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_ACTIONLISTENER_H_INCLUDED -#define JUCE_ACTIONLISTENER_H_INCLUDED - - -//============================================================================== -/** - Interface class for delivery of events that are sent by an ActionBroadcaster. - - @see ActionBroadcaster, ChangeListener -*/ -class JUCE_API ActionListener -{ -public: - /** Destructor. */ - virtual ~ActionListener() {} - - /** Overridden by your subclass to receive the callback. - - @param message the string that was specified when the event was triggered - by a call to ActionBroadcaster::sendActionMessage() - */ - virtual void actionListenerCallback (const String& message) = 0; -}; - - -#endif // JUCE_ACTIONLISTENER_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/broadcasters/juce_AsyncUpdater.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/broadcasters/juce_AsyncUpdater.cpp deleted file mode 100644 index 980eb41461..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/broadcasters/juce_AsyncUpdater.cpp +++ /dev/null @@ -1,86 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -class AsyncUpdater::AsyncUpdaterMessage : public CallbackMessage -{ -public: - AsyncUpdaterMessage (AsyncUpdater& au) : owner (au) {} - - void messageCallback() override - { - if (shouldDeliver.compareAndSetBool (0, 1)) - owner.handleAsyncUpdate(); - } - - Atomic shouldDeliver; - -private: - AsyncUpdater& owner; - - JUCE_DECLARE_NON_COPYABLE (AsyncUpdaterMessage) -}; - -//============================================================================== -AsyncUpdater::AsyncUpdater() -{ - activeMessage = new AsyncUpdaterMessage (*this); -} - -AsyncUpdater::~AsyncUpdater() -{ - // You're deleting this object with a background thread while there's an update - // pending on the main event thread - that's pretty dodgy threading, as the callback could - // happen after this destructor has finished. You should either use a MessageManagerLock while - // deleting this object, or find some other way to avoid such a race condition. - jassert ((! isUpdatePending()) || MessageManager::getInstance()->currentThreadHasLockedMessageManager()); - - activeMessage->shouldDeliver.set (0); -} - -void AsyncUpdater::triggerAsyncUpdate() -{ - if (activeMessage->shouldDeliver.compareAndSetBool (1, 0)) - if (! activeMessage->post()) - cancelPendingUpdate(); // if the message queue fails, this avoids getting - // trapped waiting for the message to arrive -} - -void AsyncUpdater::cancelPendingUpdate() noexcept -{ - activeMessage->shouldDeliver.set (0); -} - -void AsyncUpdater::handleUpdateNowIfNeeded() -{ - // This can only be called by the event thread. - jassert (MessageManager::getInstance()->currentThreadHasLockedMessageManager()); - - if (activeMessage->shouldDeliver.exchange (0) != 0) - handleAsyncUpdate(); -} - -bool AsyncUpdater::isUpdatePending() const noexcept -{ - return activeMessage->shouldDeliver.value != 0; -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/broadcasters/juce_AsyncUpdater.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/broadcasters/juce_AsyncUpdater.h deleted file mode 100644 index 79ab6e1cae..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/broadcasters/juce_AsyncUpdater.h +++ /dev/null @@ -1,109 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_ASYNCUPDATER_H_INCLUDED -#define JUCE_ASYNCUPDATER_H_INCLUDED - - -//============================================================================== -/** - Has a callback method that is triggered asynchronously. - - This object allows an asynchronous callback function to be triggered, for - tasks such as coalescing multiple updates into a single callback later on. - - Basically, one or more calls to the triggerAsyncUpdate() will result in the - message thread calling handleAsyncUpdate() as soon as it can. -*/ -class JUCE_API AsyncUpdater -{ -public: - //============================================================================== - /** Creates an AsyncUpdater object. */ - AsyncUpdater(); - - /** Destructor. - If there are any pending callbacks when the object is deleted, these are lost. - */ - virtual ~AsyncUpdater(); - - //============================================================================== - /** Causes the callback to be triggered at a later time. - - This method returns immediately, having made sure that a callback - to the handleAsyncUpdate() method will occur as soon as possible. - - If an update callback is already pending but hasn't happened yet, calls - to this method will be ignored. - - It's thread-safe to call this method from any number of threads without - needing to worry about locking. - */ - void triggerAsyncUpdate(); - - /** This will stop any pending updates from happening. - - If called after triggerAsyncUpdate() and before the handleAsyncUpdate() - callback happens, this will cancel the handleAsyncUpdate() callback. - - Note that this method simply cancels the next callback - if a callback is already - in progress on a different thread, this won't block until the callback finishes, so - there's no guarantee that the callback isn't still running when the method returns. - */ - void cancelPendingUpdate() noexcept; - - /** If an update has been triggered and is pending, this will invoke it - synchronously. - - Use this as a kind of "flush" operation - if an update is pending, the - handleAsyncUpdate() method will be called immediately; if no update is - pending, then nothing will be done. - - Because this may invoke the callback, this method must only be called on - the main event thread. - */ - void handleUpdateNowIfNeeded(); - - /** Returns true if there's an update callback in the pipeline. */ - bool isUpdatePending() const noexcept; - - //============================================================================== - /** Called back to do whatever your class needs to do. - - This method is called by the message thread at the next convenient time - after the triggerAsyncUpdate() method has been called. - */ - virtual void handleAsyncUpdate() = 0; - -private: - //============================================================================== - class AsyncUpdaterMessage; - friend class ReferenceCountedObjectPtr; - ReferenceCountedObjectPtr activeMessage; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AsyncUpdater) -}; - - -#endif // JUCE_ASYNCUPDATER_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/broadcasters/juce_ChangeBroadcaster.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/broadcasters/juce_ChangeBroadcaster.cpp deleted file mode 100644 index bff1f1a2dd..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/broadcasters/juce_ChangeBroadcaster.cpp +++ /dev/null @@ -1,96 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -ChangeBroadcaster::ChangeBroadcaster() noexcept -{ - callback.owner = this; -} - -ChangeBroadcaster::~ChangeBroadcaster() -{ -} - -void ChangeBroadcaster::addChangeListener (ChangeListener* const listener) -{ - // Listeners can only be safely added when the event thread is locked - // You can use a MessageManagerLock if you need to call this from another thread. - jassert (MessageManager::getInstance()->currentThreadHasLockedMessageManager()); - - changeListeners.add (listener); -} - -void ChangeBroadcaster::removeChangeListener (ChangeListener* const listener) -{ - // Listeners can only be safely added when the event thread is locked - // You can use a MessageManagerLock if you need to call this from another thread. - jassert (MessageManager::getInstance()->currentThreadHasLockedMessageManager()); - - changeListeners.remove (listener); -} - -void ChangeBroadcaster::removeAllChangeListeners() -{ - // Listeners can only be safely added when the event thread is locked - // You can use a MessageManagerLock if you need to call this from another thread. - jassert (MessageManager::getInstance()->currentThreadHasLockedMessageManager()); - - changeListeners.clear(); -} - -void ChangeBroadcaster::sendChangeMessage() -{ - if (changeListeners.size() > 0) - callback.triggerAsyncUpdate(); -} - -void ChangeBroadcaster::sendSynchronousChangeMessage() -{ - // This can only be called by the event thread. - jassert (MessageManager::getInstance()->isThisTheMessageThread()); - - callback.cancelPendingUpdate(); - callListeners(); -} - -void ChangeBroadcaster::dispatchPendingMessages() -{ - callback.handleUpdateNowIfNeeded(); -} - -void ChangeBroadcaster::callListeners() -{ - changeListeners.call (&ChangeListener::changeListenerCallback, this); -} - -//============================================================================== -ChangeBroadcaster::ChangeBroadcasterCallback::ChangeBroadcasterCallback() - : owner (nullptr) -{ -} - -void ChangeBroadcaster::ChangeBroadcasterCallback::handleAsyncUpdate() -{ - jassert (owner != nullptr); - owner->callListeners(); -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/broadcasters/juce_ChangeBroadcaster.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/broadcasters/juce_ChangeBroadcaster.h deleted file mode 100644 index 8d9aca9d05..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/broadcasters/juce_ChangeBroadcaster.h +++ /dev/null @@ -1,105 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_CHANGEBROADCASTER_H_INCLUDED -#define JUCE_CHANGEBROADCASTER_H_INCLUDED - - -//============================================================================== -/** - Holds a list of ChangeListeners, and sends messages to them when instructed. - - @see ChangeListener -*/ -class JUCE_API ChangeBroadcaster -{ -public: - //============================================================================== - /** Creates an ChangeBroadcaster. */ - ChangeBroadcaster() noexcept; - - /** Destructor. */ - virtual ~ChangeBroadcaster(); - - //============================================================================== - /** Registers a listener to receive change callbacks from this broadcaster. - Trying to add a listener that's already on the list will have no effect. - */ - void addChangeListener (ChangeListener* listener); - - /** Unregisters a listener from the list. - If the listener isn't on the list, this won't have any effect. - */ - void removeChangeListener (ChangeListener* listener); - - /** Removes all listeners from the list. */ - void removeAllChangeListeners(); - - //============================================================================== - /** Causes an asynchronous change message to be sent to all the registered listeners. - - The message will be delivered asynchronously by the main message thread, so this - method will return immediately. To call the listeners synchronously use - sendSynchronousChangeMessage(). - */ - void sendChangeMessage(); - - /** Sends a synchronous change message to all the registered listeners. - - This will immediately call all the listeners that are registered. For thread-safety - reasons, you must only call this method on the main message thread. - - @see dispatchPendingMessages - */ - void sendSynchronousChangeMessage(); - - /** If a change message has been sent but not yet dispatched, this will call - sendSynchronousChangeMessage() to make the callback immediately. - - For thread-safety reasons, you must only call this method on the main message thread. - */ - void dispatchPendingMessages(); - -private: - //============================================================================== - class ChangeBroadcasterCallback : public AsyncUpdater - { - public: - ChangeBroadcasterCallback(); - void handleAsyncUpdate() override; - - ChangeBroadcaster* owner; - }; - - friend class ChangeBroadcasterCallback; - ChangeBroadcasterCallback callback; - ListenerList changeListeners; - - void callListeners(); - - JUCE_DECLARE_NON_COPYABLE (ChangeBroadcaster) -}; - - -#endif // JUCE_CHANGEBROADCASTER_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/broadcasters/juce_ChangeListener.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/broadcasters/juce_ChangeListener.h deleted file mode 100644 index 59e3025bba..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/broadcasters/juce_ChangeListener.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_CHANGELISTENER_H_INCLUDED -#define JUCE_CHANGELISTENER_H_INCLUDED - -class ChangeBroadcaster; - -//============================================================================== -/** - Receives change event callbacks that are sent out by a ChangeBroadcaster. - - A ChangeBroadcaster keeps a set of listeners to which it broadcasts a message when - the ChangeBroadcaster::sendChangeMessage() method is called. A subclass of - ChangeListener is used to receive these callbacks. - - Note that the major difference between an ActionListener and a ChangeListener - is that for a ChangeListener, multiple changes will be coalesced into fewer - callbacks, but ActionListeners perform one callback for every event posted. - - @see ChangeBroadcaster, ActionListener -*/ -class JUCE_API ChangeListener -{ -public: - /** Destructor. */ - virtual ~ChangeListener() {} - - /** Your subclass should implement this method to receive the callback. - @param source the ChangeBroadcaster that triggered the callback. - */ - virtual void changeListenerCallback (ChangeBroadcaster* source) = 0; - - - //============================================================================== - #if JUCE_CATCH_DEPRECATED_CODE_MISUSE - // This method's signature has changed to take a ChangeBroadcaster parameter - please update your code! - private: virtual int changeListenerCallback (void*) { return 0; } - #endif -}; - - -#endif // JUCE_CHANGELISTENER_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/broadcasters/juce_ListenerList.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/broadcasters/juce_ListenerList.h deleted file mode 100644 index 853e252dba..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/broadcasters/juce_ListenerList.h +++ /dev/null @@ -1,359 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_LISTENERLIST_H_INCLUDED -#define JUCE_LISTENERLIST_H_INCLUDED - - -//============================================================================== -/** - Holds a set of objects and can invoke a member function callback on each object - in the set with a single call. - - Use a ListenerList to manage a set of objects which need a callback, and you - can invoke a member function by simply calling call() or callChecked(). - - E.g. - @code - class MyListenerType - { - public: - void myCallbackMethod (int foo, bool bar); - }; - - ListenerList listeners; - listeners.add (someCallbackObjects...); - - // This will invoke myCallbackMethod (1234, true) on each of the objects - // in the list... - listeners.call (&MyListenerType::myCallbackMethod, 1234, true); - @endcode - - If you add or remove listeners from the list during one of the callbacks - i.e. while - it's in the middle of iterating the listeners, then it's guaranteed that no listeners - will be mistakenly called after they've been removed, but it may mean that some of the - listeners could be called more than once, or not at all, depending on the list's order. - - Sometimes, there's a chance that invoking one of the callbacks might result in the - list itself being deleted while it's still iterating - to survive this situation, you can - use callChecked() instead of call(), passing it a local object to act as a "BailOutChecker". - The BailOutChecker must implement a method of the form "bool shouldBailOut()", and - the list will check this after each callback to determine whether it should abort the - operation. For an example of a bail-out checker, see the Component::BailOutChecker class, - which can be used to check when a Component has been deleted. See also - ListenerList::DummyBailOutChecker, which is a dummy checker that always returns false. -*/ -template > -class ListenerList -{ - // Horrible macros required to support VC7.. - #ifndef DOXYGEN - #if JUCE_VC8_OR_EARLIER - #define LL_TEMPLATE(a) typename P##a, typename Q##a - #define LL_PARAM(a) Q##a& param##a - #else - #define LL_TEMPLATE(a) typename P##a - #define LL_PARAM(a) PARAMETER_TYPE(P##a) param##a - #endif - #endif - -public: - //============================================================================== - /** Creates an empty list. */ - ListenerList() - { - } - - /** Destructor. */ - ~ListenerList() - { - } - - //============================================================================== - /** Adds a listener to the list. - A listener can only be added once, so if the listener is already in the list, - this method has no effect. - @see remove - */ - void add (ListenerClass* const listenerToAdd) - { - // Listeners can't be null pointers! - jassert (listenerToAdd != nullptr); - - if (listenerToAdd != nullptr) - listeners.addIfNotAlreadyThere (listenerToAdd); - } - - /** Removes a listener from the list. - If the listener wasn't in the list, this has no effect. - */ - void remove (ListenerClass* const listenerToRemove) - { - // Listeners can't be null pointers! - jassert (listenerToRemove != nullptr); - - listeners.removeFirstMatchingValue (listenerToRemove); - } - - /** Returns the number of registered listeners. */ - int size() const noexcept - { - return listeners.size(); - } - - /** Returns true if any listeners are registered. */ - bool isEmpty() const noexcept - { - return listeners.size() == 0; - } - - /** Clears the list. */ - void clear() - { - listeners.clear(); - } - - /** Returns true if the specified listener has been added to the list. */ - bool contains (ListenerClass* const listener) const noexcept - { - return listeners.contains (listener); - } - - //============================================================================== - /** Calls a member function on each listener in the list, with no parameters. */ - void call (void (ListenerClass::*callbackFunction) ()) - { - callChecked (static_cast (DummyBailOutChecker()), callbackFunction); - } - - /** Calls a member function on each listener in the list, with no parameters and a bail-out-checker. - See the class description for info about writing a bail-out checker. */ - template - void callChecked (const BailOutCheckerType& bailOutChecker, - void (ListenerClass::*callbackFunction) ()) - { - for (Iterator iter (*this); iter.next (bailOutChecker);) - (iter.getListener()->*callbackFunction) (); - } - - //============================================================================== - /** Calls a member function on each listener in the list, with 1 parameter. */ - template - void call (void (ListenerClass::*callbackFunction) (P1), LL_PARAM(1)) - { - for (Iterator iter (*this); iter.next();) - (iter.getListener()->*callbackFunction) (param1); - } - - /** Calls a member function on each listener in the list, with one parameter and a bail-out-checker. - See the class description for info about writing a bail-out checker. */ - template - void callChecked (const BailOutCheckerType& bailOutChecker, - void (ListenerClass::*callbackFunction) (P1), - LL_PARAM(1)) - { - for (Iterator iter (*this); iter.next (bailOutChecker);) - (iter.getListener()->*callbackFunction) (param1); - } - - //============================================================================== - /** Calls a member function on each listener in the list, with 2 parameters. */ - template - void call (void (ListenerClass::*callbackFunction) (P1, P2), - LL_PARAM(1), LL_PARAM(2)) - { - for (Iterator iter (*this); iter.next();) - (iter.getListener()->*callbackFunction) (param1, param2); - } - - /** Calls a member function on each listener in the list, with 2 parameters and a bail-out-checker. - See the class description for info about writing a bail-out checker. */ - template - void callChecked (const BailOutCheckerType& bailOutChecker, - void (ListenerClass::*callbackFunction) (P1, P2), - LL_PARAM(1), LL_PARAM(2)) - { - for (Iterator iter (*this); iter.next (bailOutChecker);) - (iter.getListener()->*callbackFunction) (param1, param2); - } - - //============================================================================== - /** Calls a member function on each listener in the list, with 3 parameters. */ - template - void call (void (ListenerClass::*callbackFunction) (P1, P2, P3), - LL_PARAM(1), LL_PARAM(2), LL_PARAM(3)) - { - for (Iterator iter (*this); iter.next();) - (iter.getListener()->*callbackFunction) (param1, param2, param3); - } - - /** Calls a member function on each listener in the list, with 3 parameters and a bail-out-checker. - See the class description for info about writing a bail-out checker. */ - template - void callChecked (const BailOutCheckerType& bailOutChecker, - void (ListenerClass::*callbackFunction) (P1, P2, P3), - LL_PARAM(1), LL_PARAM(2), LL_PARAM(3)) - { - for (Iterator iter (*this); iter.next (bailOutChecker);) - (iter.getListener()->*callbackFunction) (param1, param2, param3); - } - - //============================================================================== - /** Calls a member function on each listener in the list, with 4 parameters. */ - template - void call (void (ListenerClass::*callbackFunction) (P1, P2, P3, P4), - LL_PARAM(1), LL_PARAM(2), LL_PARAM(3), LL_PARAM(4)) - { - for (Iterator iter (*this); iter.next();) - (iter.getListener()->*callbackFunction) (param1, param2, param3, param4); - } - - /** Calls a member function on each listener in the list, with 4 parameters and a bail-out-checker. - See the class description for info about writing a bail-out checker. */ - template - void callChecked (const BailOutCheckerType& bailOutChecker, - void (ListenerClass::*callbackFunction) (P1, P2, P3, P4), - LL_PARAM(1), LL_PARAM(2), LL_PARAM(3), LL_PARAM(4)) - { - for (Iterator iter (*this); iter.next (bailOutChecker);) - (iter.getListener()->*callbackFunction) (param1, param2, param3, param4); - } - - //============================================================================== - /** Calls a member function on each listener in the list, with 5 parameters. */ - template - void call (void (ListenerClass::*callbackFunction) (P1, P2, P3, P4, P5), - LL_PARAM(1), LL_PARAM(2), LL_PARAM(3), LL_PARAM(4), LL_PARAM(5)) - { - for (Iterator iter (*this); iter.next();) - (iter.getListener()->*callbackFunction) (param1, param2, param3, param4, param5); - } - - /** Calls a member function on each listener in the list, with 5 parameters and a bail-out-checker. - See the class description for info about writing a bail-out checker. */ - template - void callChecked (const BailOutCheckerType& bailOutChecker, - void (ListenerClass::*callbackFunction) (P1, P2, P3, P4, P5), - LL_PARAM(1), LL_PARAM(2), LL_PARAM(3), LL_PARAM(4), LL_PARAM(5)) - { - for (Iterator iter (*this); iter.next (bailOutChecker);) - (iter.getListener()->*callbackFunction) (param1, param2, param3, param4, param5); - } - - //============================================================================== - /** Calls a member function on each listener in the list, with 5 parameters. */ - template - void call (void (ListenerClass::*callbackFunction) (P1, P2, P3, P4, P5, P6), - LL_PARAM(1), LL_PARAM(2), LL_PARAM(3), LL_PARAM(4), LL_PARAM(5), LL_PARAM(6)) - { - for (Iterator iter (*this); iter.next();) - (iter.getListener()->*callbackFunction) (param1, param2, param3, param4, param5, param6); - } - - /** Calls a member function on each listener in the list, with 5 parameters and a bail-out-checker. - See the class description for info about writing a bail-out checker. */ - template - void callChecked (const BailOutCheckerType& bailOutChecker, - void (ListenerClass::*callbackFunction) (P1, P2, P3, P4, P5, P6), - LL_PARAM(1), LL_PARAM(2), LL_PARAM(3), LL_PARAM(4), LL_PARAM(5), LL_PARAM(6)) - { - for (Iterator iter (*this); iter.next (bailOutChecker);) - (iter.getListener()->*callbackFunction) (param1, param2, param3, param4, param5, param6); - } - - - //============================================================================== - /** A dummy bail-out checker that always returns false. - See the ListenerList notes for more info about bail-out checkers. - */ - class DummyBailOutChecker - { - public: - inline bool shouldBailOut() const noexcept { return false; } - }; - - //============================================================================== - /** Iterates the listeners in a ListenerList. */ - template - class Iterator - { - public: - //============================================================================== - Iterator (const ListType& listToIterate) noexcept - : list (listToIterate), index (listToIterate.size()) - {} - - ~Iterator() noexcept {} - - //============================================================================== - bool next() noexcept - { - if (index <= 0) - return false; - - const int listSize = list.size(); - - if (--index < listSize) - return true; - - index = listSize - 1; - return index >= 0; - } - - bool next (const BailOutCheckerType& bailOutChecker) noexcept - { - return (! bailOutChecker.shouldBailOut()) && next(); - } - - typename ListType::ListenerType* getListener() const noexcept - { - return list.getListeners().getUnchecked (index); - } - - //============================================================================== - private: - const ListType& list; - int index; - - JUCE_DECLARE_NON_COPYABLE (Iterator) - }; - - typedef ListenerList ThisType; - typedef ListenerClass ListenerType; - - const ArrayType& getListeners() const noexcept { return listeners; } - -private: - //============================================================================== - ArrayType listeners; - - JUCE_DECLARE_NON_COPYABLE (ListenerList) - - #undef LL_TEMPLATE - #undef LL_PARAM -}; - - -#endif // JUCE_LISTENERLIST_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/interprocess/juce_ConnectedChildProcess.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/interprocess/juce_ConnectedChildProcess.cpp deleted file mode 100644 index 2c36c2c64e..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/interprocess/juce_ConnectedChildProcess.cpp +++ /dev/null @@ -1,264 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -enum { magicMastSlaveConnectionHeader = 0x712baf04 }; - -static const char* startMessage = "__ipc_st"; -static const char* killMessage = "__ipc_k_"; -static const char* pingMessage = "__ipc_p_"; -enum { specialMessageSize = 8, defaultTimeoutMs = 8000 }; - -static String getCommandLinePrefix (const String& commandLineUniqueID) -{ - return "--" + commandLineUniqueID + ":"; -} - -//============================================================================== -// This thread sends and receives ping messages every second, so that it -// can find out if the other process has stopped running. -struct ChildProcessPingThread : public Thread, - private AsyncUpdater -{ - ChildProcessPingThread (int timeout) : Thread ("IPC ping"), timeoutMs (timeout) - { - pingReceived(); - } - - static bool isPingMessage (const MemoryBlock& m) noexcept - { - return memcmp (m.getData(), pingMessage, specialMessageSize) == 0; - } - - void pingReceived() noexcept { countdown = timeoutMs / 1000 + 1; } - void triggerConnectionLostMessage() { triggerAsyncUpdate(); } - - virtual bool sendPingMessage (const MemoryBlock&) = 0; - virtual void pingFailed() = 0; - - int timeoutMs; - -private: - Atomic countdown; - - void handleAsyncUpdate() override { pingFailed(); } - - void run() override - { - while (! threadShouldExit()) - { - if (--countdown <= 0 || ! sendPingMessage (MemoryBlock (pingMessage, specialMessageSize))) - { - triggerConnectionLostMessage(); - break; - } - - wait (1000); - } - } - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ChildProcessPingThread) -}; - -//============================================================================== -struct ChildProcessMaster::Connection : public InterprocessConnection, - private ChildProcessPingThread -{ - Connection (ChildProcessMaster& m, const String& pipeName, int timeout) - : InterprocessConnection (false, magicMastSlaveConnectionHeader), - ChildProcessPingThread (timeout), - owner (m) - { - if (createPipe (pipeName, timeoutMs)) - startThread (4); - } - - ~Connection() - { - stopThread (10000); - } - -private: - void connectionMade() override {} - void connectionLost() override { owner.handleConnectionLost(); } - - bool sendPingMessage (const MemoryBlock& m) override { return owner.sendMessageToSlave (m); } - void pingFailed() override { connectionLost(); } - - void messageReceived (const MemoryBlock& m) override - { - pingReceived(); - - if (m.getSize() != specialMessageSize || ! isPingMessage (m)) - owner.handleMessageFromSlave (m); - } - - ChildProcessMaster& owner; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Connection) -}; - -//============================================================================== -ChildProcessMaster::ChildProcessMaster() {} - -ChildProcessMaster::~ChildProcessMaster() -{ - if (connection != nullptr) - { - sendMessageToSlave (MemoryBlock (killMessage, specialMessageSize)); - connection->disconnect(); - connection = nullptr; - } -} - -void ChildProcessMaster::handleConnectionLost() {} - -bool ChildProcessMaster::sendMessageToSlave (const MemoryBlock& mb) -{ - if (connection != nullptr) - return connection->sendMessage (mb); - - jassertfalse; // this can only be used when the connection is active! - return false; -} - -bool ChildProcessMaster::launchSlaveProcess (const File& executable, const String& commandLineUniqueID, int timeoutMs) -{ - connection = nullptr; - jassert (childProcess.kill()); - - const String pipeName ("p" + String::toHexString (Random().nextInt64())); - - StringArray args; - args.add (executable.getFullPathName()); - args.add (getCommandLinePrefix (commandLineUniqueID) + pipeName); - - if (childProcess.start (args)) - { - connection = new Connection (*this, pipeName, timeoutMs <= 0 ? defaultTimeoutMs : timeoutMs); - - if (connection->isConnected()) - { - sendMessageToSlave (MemoryBlock (startMessage, specialMessageSize)); - return true; - } - - connection = nullptr; - } - - return false; -} - -//============================================================================== -struct ChildProcessSlave::Connection : public InterprocessConnection, - private ChildProcessPingThread -{ - Connection (ChildProcessSlave& p, const String& pipeName, int timeout) - : InterprocessConnection (false, magicMastSlaveConnectionHeader), - ChildProcessPingThread (timeout), - owner (p) - { - connectToPipe (pipeName, timeoutMs); - startThread (4); - } - - ~Connection() - { - stopThread (10000); - } - -private: - ChildProcessSlave& owner; - - void connectionMade() override {} - void connectionLost() override { owner.handleConnectionLost(); } - - bool sendPingMessage (const MemoryBlock& m) override { return owner.sendMessageToMaster (m); } - void pingFailed() override { connectionLost(); } - - void messageReceived (const MemoryBlock& m) override - { - pingReceived(); - - if (m.getSize() == specialMessageSize) - { - if (isPingMessage (m)) - return; - - if (memcmp (m.getData(), killMessage, specialMessageSize) == 0) - { - triggerConnectionLostMessage(); - return; - } - - if (memcmp (m.getData(), startMessage, specialMessageSize) == 0) - { - owner.handleConnectionMade(); - return; - } - } - - owner.handleMessageFromMaster (m); - } - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Connection) -}; - -//============================================================================== -ChildProcessSlave::ChildProcessSlave() {} -ChildProcessSlave::~ChildProcessSlave() {} - -void ChildProcessSlave::handleConnectionMade() {} -void ChildProcessSlave::handleConnectionLost() {} - -bool ChildProcessSlave::sendMessageToMaster (const MemoryBlock& mb) -{ - if (connection != nullptr) - return connection->sendMessage (mb); - - jassertfalse; // this can only be used when the connection is active! - return false; -} - -bool ChildProcessSlave::initialiseFromCommandLine (const String& commandLine, - const String& commandLineUniqueID, - int timeoutMs) -{ - String prefix (getCommandLinePrefix (commandLineUniqueID)); - - if (commandLine.trim().startsWith (prefix)) - { - String pipeName (commandLine.fromFirstOccurrenceOf (prefix, false, false) - .upToFirstOccurrenceOf (" ", false, false).trim()); - - if (pipeName.isNotEmpty()) - { - connection = new Connection (*this, pipeName, timeoutMs <= 0 ? defaultTimeoutMs : timeoutMs); - - if (! connection->isConnected()) - connection = nullptr; - } - } - - return connection != nullptr; -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/interprocess/juce_ConnectedChildProcess.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/interprocess/juce_ConnectedChildProcess.h deleted file mode 100644 index 60e3b7105e..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/interprocess/juce_ConnectedChildProcess.h +++ /dev/null @@ -1,191 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_CONNECTEDCHILDPROCESS_H_INCLUDED -#define JUCE_CONNECTEDCHILDPROCESS_H_INCLUDED - -//============================================================================== -/** - Acts as the slave end of a master/slave pair of connected processes. - - The ChildProcessSlave and ChildProcessMaster classes make it easy for an app - to spawn a child process, and to manage a 2-way messaging connection to control it. - - To use the system, you need to create subclasses of both ChildProcessSlave and - ChildProcessMaster. To instantiate the ChildProcessSlave object, you must - add some code to your main() or JUCEApplication::initialise() function that - calls the initialiseFromCommandLine() method to check the app's command-line - parameters to see whether it's being launched as a child process. If this returns - true then the slave process can be allowed to run, and its handleMessageFromMaster() - method will be called whenever a message arrives. - - The juce demo app has a good example of this class in action. - - @see ChildProcessMaster, InterprocessConnection, ChildProcess -*/ -class JUCE_API ChildProcessSlave -{ -public: - /** Creates a non-connected slave process. - Use initialiseFromCommandLine to connect to a master process. - */ - ChildProcessSlave(); - - /** Destructor. */ - virtual ~ChildProcessSlave(); - - /** This checks some command-line parameters to see whether they were generated by - ChildProcessMaster::launchSlaveProcess(), and if so, connects to that master process. - - In an exe that can be used as a child process, you should add some code to your - main() or JUCEApplication::initialise() that calls this method. - - The commandLineUniqueID should be a short alphanumeric identifier (no spaces!) - that matches the string passed to ChildProcessMaster::launchSlaveProcess(). - - The timeoutMs parameter lets you specify how long the child process is allowed - to run without receiving a ping from the master before the master is considered to - have died, and handleConnectionLost() will be called. Passing <= 0 for this timeout - makes it use a default value. - - Returns true if the command-line matches and the connection is made successfully. - */ - bool initialiseFromCommandLine (const String& commandLine, - const String& commandLineUniqueID, - int timeoutMs = 0); - - //============================================================================== - /** This will be called to deliver messages from the master process. - The call will probably be made on a background thread, so be careful with your - thread-safety! You may want to respond by sending back a message with - sendMessageToMaster() - */ - virtual void handleMessageFromMaster (const MemoryBlock&) = 0; - - /** This will be called when the master process finishes connecting to this slave. - The call will probably be made on a background thread, so be careful with your thread-safety! - */ - virtual void handleConnectionMade(); - - /** This will be called when the connection to the master process is lost. - The call may be made from any thread (including the message thread). - Typically, if your process only exists to act as a slave, you should probably exit - when this happens. - */ - virtual void handleConnectionLost(); - - /** Tries to send a message to the master process. - This returns true if the message was sent, but doesn't check that it actually gets - delivered at the other end. If successful, the data will emerge in a call to your - ChildProcessMaster::handleMessageFromSlave(). - */ - bool sendMessageToMaster (const MemoryBlock&); - -private: - struct Connection; - friend struct Connection; - friend struct ContainerDeletePolicy; - ScopedPointer connection; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ChildProcessSlave) -}; - -//============================================================================== -/** - Acts as the master in a master/slave pair of connected processes. - - The ChildProcessSlave and ChildProcessMaster classes make it easy for an app - to spawn a child process, and to manage a 2-way messaging connection to control it. - - To use the system, you need to create subclasses of both ChildProcessSlave and - ChildProcessMaster. When you want your master process to launch the slave, you - just call launchSlaveProcess(), and it'll attempt to launch the executable that - you specify (which may be the same exe), and assuming it has been set-up to - correctly parse the command-line parameters (see ChildProcessSlave) then a - two-way connection will be created. - - The juce demo app has a good example of this class in action. - - @see ChildProcessSlave, InterprocessConnection, ChildProcess -*/ -class JUCE_API ChildProcessMaster -{ -public: - /** Creates an uninitialised master process object. - Use launchSlaveProcess to launch and connect to a child process. - */ - ChildProcessMaster(); - - /** Destructor. */ - virtual ~ChildProcessMaster(); - - /** Attempts to launch and connect to a slave process. - This will start the given executable, passing it a special command-line - parameter based around the commandLineUniqueID string, which must be a - short alphanumeric string (no spaces!) that identifies your app. The exe - that gets launched must respond by calling ChildProcessSlave::initialiseFromCommandLine() - in its startup code, and must use a matching ID to commandLineUniqueID. - - The timeoutMs parameter lets you specify how long the child process is allowed - to go without sending a ping before it is considered to have died and - handleConnectionLost() will be called. Passing <= 0 for this timeout makes - it use a default value. - - If this all works, the method returns true, and you can begin sending and - receiving messages with the slave process. - */ - bool launchSlaveProcess (const File& executableToLaunch, - const String& commandLineUniqueID, - int timeoutMs = 0); - - /** This will be called to deliver a message from the slave process. - The call will probably be made on a background thread, so be careful with your thread-safety! - */ - virtual void handleMessageFromSlave (const MemoryBlock&) = 0; - - /** This will be called when the slave process dies or is somehow disconnected. - The call will probably be made on a background thread, so be careful with your thread-safety! - */ - virtual void handleConnectionLost(); - - /** Attempts to send a message to the slave process. - This returns true if the message was dispatched, but doesn't check that it actually - gets delivered at the other end. If successful, the data will emerge in a call to - your ChildProcessSlave::handleMessageFromMaster(). - */ - bool sendMessageToSlave (const MemoryBlock&); - -private: - ChildProcess childProcess; - - struct Connection; - friend struct Connection; - friend struct ContainerDeletePolicy; - ScopedPointer connection; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ChildProcessMaster) -}; - - -#endif // JUCE_CONNECTEDCHILDPROCESS_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/interprocess/juce_InterprocessConnection.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/interprocess/juce_InterprocessConnection.cpp deleted file mode 100644 index f008cd133c..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/interprocess/juce_InterprocessConnection.cpp +++ /dev/null @@ -1,365 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -struct InterprocessConnection::ConnectionThread : public Thread -{ - ConnectionThread (InterprocessConnection& c) : Thread ("JUCE IPC"), owner (c) {} - - void run() override { owner.runThread(); } - -private: - InterprocessConnection& owner; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ConnectionThread) -}; - -//============================================================================== -InterprocessConnection::InterprocessConnection (const bool callbacksOnMessageThread, - const uint32 magicMessageHeaderNumber) - : callbackConnectionState (false), - useMessageThread (callbacksOnMessageThread), - magicMessageHeader (magicMessageHeaderNumber), - pipeReceiveMessageTimeout (-1) -{ - thread = new ConnectionThread (*this); -} - -InterprocessConnection::~InterprocessConnection() -{ - callbackConnectionState = false; - disconnect(); - masterReference.clear(); - thread = nullptr; -} - -//============================================================================== -bool InterprocessConnection::connectToSocket (const String& hostName, - const int portNumber, - const int timeOutMillisecs) -{ - disconnect(); - - const ScopedLock sl (pipeAndSocketLock); - socket = new StreamingSocket(); - - if (socket->connect (hostName, portNumber, timeOutMillisecs)) - { - connectionMadeInt(); - thread->startThread(); - return true; - } - - socket = nullptr; - return false; -} - -bool InterprocessConnection::connectToPipe (const String& pipeName, const int timeoutMs) -{ - disconnect(); - - ScopedPointer newPipe (new NamedPipe()); - - if (newPipe->openExisting (pipeName)) - { - const ScopedLock sl (pipeAndSocketLock); - pipeReceiveMessageTimeout = timeoutMs; - initialiseWithPipe (newPipe.release()); - return true; - } - - return false; -} - -bool InterprocessConnection::createPipe (const String& pipeName, const int timeoutMs) -{ - disconnect(); - - ScopedPointer newPipe (new NamedPipe()); - - if (newPipe->createNewPipe (pipeName)) - { - const ScopedLock sl (pipeAndSocketLock); - pipeReceiveMessageTimeout = timeoutMs; - initialiseWithPipe (newPipe.release()); - return true; - } - - return false; -} - -void InterprocessConnection::disconnect() -{ - thread->signalThreadShouldExit(); - - { - const ScopedLock sl (pipeAndSocketLock); - if (socket != nullptr) socket->close(); - if (pipe != nullptr) pipe->close(); - } - - thread->stopThread (4000); - deletePipeAndSocket(); - connectionLostInt(); -} - -void InterprocessConnection::deletePipeAndSocket() -{ - const ScopedLock sl (pipeAndSocketLock); - socket = nullptr; - pipe = nullptr; -} - -bool InterprocessConnection::isConnected() const -{ - const ScopedLock sl (pipeAndSocketLock); - - return ((socket != nullptr && socket->isConnected()) - || (pipe != nullptr && pipe->isOpen())) - && thread->isThreadRunning(); -} - -String InterprocessConnection::getConnectedHostName() const -{ - { - const ScopedLock sl (pipeAndSocketLock); - - if (pipe == nullptr && socket == nullptr) - return String(); - - if (socket != nullptr && ! socket->isLocal()) - return socket->getHostName(); - } - - return IPAddress::local().toString(); -} - -//============================================================================== -bool InterprocessConnection::sendMessage (const MemoryBlock& message) -{ - uint32 messageHeader[2] = { ByteOrder::swapIfBigEndian (magicMessageHeader), - ByteOrder::swapIfBigEndian ((uint32) message.getSize()) }; - - MemoryBlock messageData (sizeof (messageHeader) + message.getSize()); - messageData.copyFrom (messageHeader, 0, sizeof (messageHeader)); - messageData.copyFrom (message.getData(), sizeof (messageHeader), message.getSize()); - - return writeData (messageData.getData(), (int) messageData.getSize()) == (int) messageData.getSize(); -} - -int InterprocessConnection::writeData (void* data, int dataSize) -{ - const ScopedLock sl (pipeAndSocketLock); - - if (socket != nullptr) - return socket->write (data, dataSize); - - if (pipe != nullptr) - return pipe->write (data, dataSize, pipeReceiveMessageTimeout); - - return 0; -} - -//============================================================================== -void InterprocessConnection::initialiseWithSocket (StreamingSocket* newSocket) -{ - jassert (socket == nullptr && pipe == nullptr); - socket = newSocket; - connectionMadeInt(); - thread->startThread(); -} - -void InterprocessConnection::initialiseWithPipe (NamedPipe* newPipe) -{ - jassert (socket == nullptr && pipe == nullptr); - pipe = newPipe; - connectionMadeInt(); - thread->startThread(); -} - -//============================================================================== -struct ConnectionStateMessage : public MessageManager::MessageBase -{ - ConnectionStateMessage (InterprocessConnection* ipc, bool connected) noexcept - : owner (ipc), connectionMade (connected) - {} - - void messageCallback() override - { - if (InterprocessConnection* const ipc = owner) - { - if (connectionMade) - ipc->connectionMade(); - else - ipc->connectionLost(); - } - } - - WeakReference owner; - bool connectionMade; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ConnectionStateMessage) -}; - -void InterprocessConnection::connectionMadeInt() -{ - if (! callbackConnectionState) - { - callbackConnectionState = true; - - if (useMessageThread) - (new ConnectionStateMessage (this, true))->post(); - else - connectionMade(); - } -} - -void InterprocessConnection::connectionLostInt() -{ - if (callbackConnectionState) - { - callbackConnectionState = false; - - if (useMessageThread) - (new ConnectionStateMessage (this, false))->post(); - else - connectionLost(); - } -} - -struct DataDeliveryMessage : public Message -{ - DataDeliveryMessage (InterprocessConnection* ipc, const MemoryBlock& d) - : owner (ipc), data (d) - {} - - void messageCallback() override - { - if (InterprocessConnection* const ipc = owner) - ipc->messageReceived (data); - } - - WeakReference owner; - MemoryBlock data; -}; - -void InterprocessConnection::deliverDataInt (const MemoryBlock& data) -{ - jassert (callbackConnectionState); - - if (useMessageThread) - (new DataDeliveryMessage (this, data))->post(); - else - messageReceived (data); -} - -//============================================================================== -bool InterprocessConnection::readNextMessageInt() -{ - uint32 messageHeader[2]; - const int bytes = socket != nullptr ? socket->read (messageHeader, sizeof (messageHeader), true) - : pipe ->read (messageHeader, sizeof (messageHeader), -1); - - if (bytes == sizeof (messageHeader) - && ByteOrder::swapIfBigEndian (messageHeader[0]) == magicMessageHeader) - { - int bytesInMessage = (int) ByteOrder::swapIfBigEndian (messageHeader[1]); - - if (bytesInMessage > 0) - { - MemoryBlock messageData ((size_t) bytesInMessage, true); - int bytesRead = 0; - - while (bytesInMessage > 0) - { - if (thread->threadShouldExit()) - return false; - - const int numThisTime = jmin (bytesInMessage, 65536); - void* const data = addBytesToPointer (messageData.getData(), bytesRead); - - const int bytesIn = socket != nullptr ? socket->read (data, numThisTime, true) - : pipe ->read (data, numThisTime, -1); - - if (bytesIn <= 0) - break; - - bytesRead += bytesIn; - bytesInMessage -= bytesIn; - } - - if (bytesRead >= 0) - deliverDataInt (messageData); - } - } - else if (bytes < 0) - { - if (socket != nullptr) - deletePipeAndSocket(); - - connectionLostInt(); - return false; - } - - return true; -} - -void InterprocessConnection::runThread() -{ - while (! thread->threadShouldExit()) - { - if (socket != nullptr) - { - const int ready = socket->waitUntilReady (true, 0); - - if (ready < 0) - { - deletePipeAndSocket(); - connectionLostInt(); - break; - } - - if (ready == 0) - { - thread->wait (1); - continue; - } - } - else if (pipe != nullptr) - { - if (! pipe->isOpen()) - { - deletePipeAndSocket(); - connectionLostInt(); - break; - } - } - else - { - break; - } - - if (thread->threadShouldExit() || ! readNextMessageInt()) - break; - } -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/interprocess/juce_InterprocessConnection.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/interprocess/juce_InterprocessConnection.h deleted file mode 100644 index a88e8fdc5c..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/interprocess/juce_InterprocessConnection.h +++ /dev/null @@ -1,209 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_INTERPROCESSCONNECTION_H_INCLUDED -#define JUCE_INTERPROCESSCONNECTION_H_INCLUDED - -class InterprocessConnectionServer; -class MemoryBlock; - - -//============================================================================== -/** - Manages a simple two-way messaging connection to another process, using either - a socket or a named pipe as the transport medium. - - To connect to a waiting socket or an open pipe, use the connectToSocket() or - connectToPipe() methods. If this succeeds, messages can be sent to the other end, - and incoming messages will result in a callback via the messageReceived() - method. - - To open a pipe and wait for another client to connect to it, use the createPipe() - method. - - To act as a socket server and create connections for one or more client, see the - InterprocessConnectionServer class. - - @see InterprocessConnectionServer, Socket, NamedPipe -*/ -class JUCE_API InterprocessConnection -{ -public: - //============================================================================== - /** Creates a connection. - - Connections are created manually, connecting them with the connectToSocket() - or connectToPipe() methods, or they are created automatically by a InterprocessConnectionServer - when a client wants to connect. - - @param callbacksOnMessageThread if true, callbacks to the connectionMade(), - connectionLost() and messageReceived() methods will - always be made using the message thread; if false, - these will be called immediately on the connection's - own thread. - @param magicMessageHeaderNumber a magic number to use in the header to check the - validity of the data blocks being sent and received. This - can be any number, but the sender and receiver must obviously - use matching values or they won't recognise each other. - */ - InterprocessConnection (bool callbacksOnMessageThread = true, - uint32 magicMessageHeaderNumber = 0xf2b49e2c); - - /** Destructor. */ - virtual ~InterprocessConnection(); - - //============================================================================== - /** Tries to connect this object to a socket. - - For this to work, the machine on the other end needs to have a InterprocessConnectionServer - object waiting to receive client connections on this port number. - - @param hostName the host computer, either a network address or name - @param portNumber the socket port number to try to connect to - @param timeOutMillisecs how long to keep trying before giving up - @returns true if the connection is established successfully - @see Socket - */ - bool connectToSocket (const String& hostName, - int portNumber, - int timeOutMillisecs); - - /** Tries to connect the object to an existing named pipe. - - For this to work, another process on the same computer must already have opened - an InterprocessConnection object and used createPipe() to create a pipe for this - to connect to. - - @param pipeName the name to use for the pipe - this should be unique to your app - @param pipeReceiveMessageTimeoutMs a timeout length to be used when reading or writing - to the pipe, or -1 for an infinite timeout. - @returns true if it connects successfully. - @see createPipe, NamedPipe - */ - bool connectToPipe (const String& pipeName, int pipeReceiveMessageTimeoutMs); - - /** Tries to create a new pipe for other processes to connect to. - - This creates a pipe with the given name, so that other processes can use - connectToPipe() to connect to the other end. - - @param pipeName the name to use for the pipe - this should be unique to your app - @param pipeReceiveMessageTimeoutMs a timeout length to be used when reading or writing - to the pipe, or -1 for an infinite timeout. - @returns true if the pipe was created, or false if it fails (e.g. if another process is - already using using the pipe). - */ - bool createPipe (const String& pipeName, int pipeReceiveMessageTimeoutMs); - - /** Disconnects and closes any currently-open sockets or pipes. */ - void disconnect(); - - /** True if a socket or pipe is currently active. */ - bool isConnected() const; - - /** Returns the socket that this connection is using (or nullptr if it uses a pipe). */ - StreamingSocket* getSocket() const noexcept { return socket; } - - /** Returns the pipe that this connection is using (or nullptr if it uses a socket). */ - NamedPipe* getPipe() const noexcept { return pipe; } - - /** Returns the name of the machine at the other end of this connection. - This may return an empty string if the name is unknown. - */ - String getConnectedHostName() const; - - //============================================================================== - /** Tries to send a message to the other end of this connection. - - This will fail if it's not connected, or if there's some kind of write error. If - it succeeds, the connection object at the other end will receive the message by - a callback to its messageReceived() method. - - @see messageReceived - */ - bool sendMessage (const MemoryBlock& message); - - //============================================================================== - /** Called when the connection is first connected. - - If the connection was created with the callbacksOnMessageThread flag set, then - this will be called on the message thread; otherwise it will be called on a server - thread. - */ - virtual void connectionMade() = 0; - - /** Called when the connection is broken. - - If the connection was created with the callbacksOnMessageThread flag set, then - this will be called on the message thread; otherwise it will be called on a server - thread. - */ - virtual void connectionLost() = 0; - - /** Called when a message arrives. - - When the object at the other end of this connection sends us a message with sendMessage(), - this callback is used to deliver it to us. - - If the connection was created with the callbacksOnMessageThread flag set, then - this will be called on the message thread; otherwise it will be called on a server - thread. - - @see sendMessage - */ - virtual void messageReceived (const MemoryBlock& message) = 0; - - -private: - //============================================================================== - WeakReference::Master masterReference; - friend class WeakReference; - CriticalSection pipeAndSocketLock; - ScopedPointer socket; - ScopedPointer pipe; - bool callbackConnectionState; - const bool useMessageThread; - const uint32 magicMessageHeader; - int pipeReceiveMessageTimeout; - - friend class InterprocessConnectionServer; - void initialiseWithSocket (StreamingSocket*); - void initialiseWithPipe (NamedPipe*); - void deletePipeAndSocket(); - void connectionMadeInt(); - void connectionLostInt(); - void deliverDataInt (const MemoryBlock&); - bool readNextMessageInt(); - - struct ConnectionThread; - friend struct ConnectionThread; - friend struct ContainerDeletePolicy; - ScopedPointer thread; - void runThread(); - int writeData (void*, int); - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (InterprocessConnection) -}; - -#endif // JUCE_INTERPROCESSCONNECTION_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/interprocess/juce_InterprocessConnectionServer.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/interprocess/juce_InterprocessConnectionServer.cpp deleted file mode 100644 index e9b5426493..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/interprocess/juce_InterprocessConnectionServer.cpp +++ /dev/null @@ -1,73 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -InterprocessConnectionServer::InterprocessConnectionServer() - : Thread ("Juce IPC server") -{ -} - -InterprocessConnectionServer::~InterprocessConnectionServer() -{ - stop(); -} - -//============================================================================== -bool InterprocessConnectionServer::beginWaitingForSocket (const int portNumber) -{ - stop(); - - socket = new StreamingSocket(); - - if (socket->createListener (portNumber)) - { - startThread(); - return true; - } - - socket = nullptr; - return false; -} - -void InterprocessConnectionServer::stop() -{ - signalThreadShouldExit(); - - if (socket != nullptr) - socket->close(); - - stopThread (4000); - socket = nullptr; -} - -void InterprocessConnectionServer::run() -{ - while ((! threadShouldExit()) && socket != nullptr) - { - ScopedPointer clientSocket (socket->waitForNextConnection()); - - if (clientSocket != nullptr) - if (InterprocessConnection* newConnection = createConnectionObject()) - newConnection->initialiseWithSocket (clientSocket.release()); - } -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/interprocess/juce_InterprocessConnectionServer.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/interprocess/juce_InterprocessConnectionServer.h deleted file mode 100644 index 8de7b8f288..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/interprocess/juce_InterprocessConnectionServer.h +++ /dev/null @@ -1,93 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_INTERPROCESSCONNECTIONSERVER_H_INCLUDED -#define JUCE_INTERPROCESSCONNECTIONSERVER_H_INCLUDED - - -//============================================================================== -/** - An object that waits for client sockets to connect to a port on this host, and - creates InterprocessConnection objects for each one. - - To use this, create a class derived from it which implements the createConnectionObject() - method, so that it creates suitable connection objects for each client that tries - to connect. - - @see InterprocessConnection -*/ -class JUCE_API InterprocessConnectionServer : private Thread -{ -public: - //============================================================================== - /** Creates an uninitialised server object. - */ - InterprocessConnectionServer(); - - /** Destructor. */ - ~InterprocessConnectionServer(); - - //============================================================================== - /** Starts an internal thread which listens on the given port number. - - While this is running, in another process tries to connect with the - InterprocessConnection::connectToSocket() method, this object will call - createConnectionObject() to create a connection to that client. - - Use stop() to stop the thread running. - - @see createConnectionObject, stop - */ - bool beginWaitingForSocket (int portNumber); - - /** Terminates the listener thread, if it's active. - - @see beginWaitingForSocket - */ - void stop(); - -protected: - /** Creates a suitable connection object for a client process that wants to - connect to this one. - - This will be called by the listener thread when a client process tries - to connect, and must return a new InterprocessConnection object that will - then run as this end of the connection. - - @see InterprocessConnection - */ - virtual InterprocessConnection* createConnectionObject() = 0; - - -private: - //============================================================================== - ScopedPointer socket; - - void run() override; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (InterprocessConnectionServer) -}; - - -#endif // JUCE_INTERPROCESSCONNECTIONSERVER_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/juce_events.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/juce_events.cpp deleted file mode 100644 index 2110d0a5dc..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/juce_events.cpp +++ /dev/null @@ -1,103 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#if defined (JUCE_EVENTS_H_INCLUDED) && ! JUCE_AMALGAMATED_INCLUDE - /* When you add this cpp file to your project, you mustn't include it in a file where you've - already included any other headers - just put it inside a file on its own, possibly with your config - flags preceding it, but don't include anything else. That also includes avoiding any automatic prefix - header files that the compiler may be using. - */ - #error "Incorrect use of JUCE cpp file" -#endif - -// Your project must contain an AppConfig.h file with your project-specific settings in it, -// and your header search path must make it accessible to the module's files. -#include "AppConfig.h" - -#include "../juce_core/native/juce_BasicNativeHeaders.h" -#include "juce_events.h" - -#if JUCE_CATCH_UNHANDLED_EXCEPTIONS && JUCE_MODULE_AVAILABLE_juce_gui_basics - #include "../juce_gui_basics/juce_gui_basics.h" -#endif - -//============================================================================== -#if JUCE_MAC - #import - #import - #import - #import - #import - -#elif JUCE_LINUX - #include - #include - #include - #undef KeyPress - #include -#endif - -//============================================================================== -namespace juce -{ - -#include "messages/juce_ApplicationBase.cpp" -#include "messages/juce_DeletedAtShutdown.cpp" -#include "messages/juce_MessageListener.cpp" -#include "messages/juce_MessageManager.cpp" -#include "broadcasters/juce_ActionBroadcaster.cpp" -#include "broadcasters/juce_AsyncUpdater.cpp" -#include "broadcasters/juce_ChangeBroadcaster.cpp" -#include "timers/juce_MultiTimer.cpp" -#include "timers/juce_Timer.cpp" -#include "interprocess/juce_InterprocessConnection.cpp" -#include "interprocess/juce_InterprocessConnectionServer.cpp" -#include "interprocess/juce_ConnectedChildProcess.cpp" - -//============================================================================== -#if JUCE_MAC - #include "../juce_core/native/juce_osx_ObjCHelpers.h" - #include "native/juce_osx_MessageQueue.h" - #include "native/juce_mac_MessageManager.mm" - -#elif JUCE_IOS - #include "../juce_core/native/juce_osx_ObjCHelpers.h" - #include "native/juce_osx_MessageQueue.h" - #include "native/juce_ios_MessageManager.mm" - -#elif JUCE_WINDOWS - #include "native/juce_win32_HiddenMessageWindow.h" - #include "native/juce_win32_Messaging.cpp" - -#elif JUCE_LINUX - #include "native/juce_ScopedXLock.h" - #include "native/juce_linux_Messaging.cpp" - -#elif JUCE_ANDROID - #include "../juce_core/native/juce_android_JNIHelpers.h" - #include "native/juce_android_Messaging.cpp" - -#endif - -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/juce_events.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/juce_events.h index 7af9c9c539..d0b4133815 100644 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/juce_events.h +++ b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/juce_events.h @@ -1,58 +1,5 @@ -/* - ============================================================================== +// This is an auto-generated file to redirect any included +// module headers to the correct external folder. - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. +#include "../../../../../modules/juce_events/juce_events.h" - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_EVENTS_H_INCLUDED -#define JUCE_EVENTS_H_INCLUDED - -//============================================================================= -#include "../juce_core/juce_core.h" - -namespace juce -{ - -#include "messages/juce_MessageManager.h" -#include "messages/juce_Message.h" -#include "messages/juce_MessageListener.h" -#include "messages/juce_CallbackMessage.h" -#include "messages/juce_DeletedAtShutdown.h" -#include "messages/juce_NotificationType.h" -#include "messages/juce_ApplicationBase.h" -#include "messages/juce_Initialisation.h" -#include "messages/juce_MountedVolumeListChangeDetector.h" -#include "broadcasters/juce_ListenerList.h" -#include "broadcasters/juce_ActionBroadcaster.h" -#include "broadcasters/juce_ActionListener.h" -#include "broadcasters/juce_AsyncUpdater.h" -#include "broadcasters/juce_ChangeListener.h" -#include "broadcasters/juce_ChangeBroadcaster.h" -#include "timers/juce_Timer.h" -#include "timers/juce_MultiTimer.h" -#include "interprocess/juce_InterprocessConnection.h" -#include "interprocess/juce_InterprocessConnectionServer.h" -#include "interprocess/juce_ConnectedChildProcess.h" -#include "native/juce_ScopedXLock.h" - -} - -#endif // JUCE_EVENTS_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/juce_events.mm b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/juce_events.mm deleted file mode 100644 index 45263f14d7..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/juce_events.mm +++ /dev/null @@ -1,25 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#include "juce_events.cpp" diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/juce_module_info b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/juce_module_info deleted file mode 100644 index 69e90c9f77..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/juce_module_info +++ /dev/null @@ -1,23 +0,0 @@ -{ - "id": "juce_events", - "name": "JUCE message and event handling classes", - "version": "3.0.8", - "description": "Classes for running an application's main event loop and sending/receiving messages, timers, etc.", - "website": "http://www.juce.com/juce", - "license": "GPL/Commercial", - - "dependencies": [ { "id": "juce_core", "version": "matching" } ], - - "include": "juce_events.h", - - "compile": [ { "file": "juce_events.cpp", "target": "! xcode" }, - { "file": "juce_events.mm", "target": "xcode" } ], - - "browse": [ "messages/*", - "timers/*", - "broadcasters/*", - "interprocess/*", - "native/*" ], - - "LinuxLibs": "X11" -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/messages/juce_ApplicationBase.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/messages/juce_ApplicationBase.cpp deleted file mode 100644 index dafc27e66b..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/messages/juce_ApplicationBase.cpp +++ /dev/null @@ -1,294 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -JUCEApplicationBase::CreateInstanceFunction JUCEApplicationBase::createInstance = 0; -JUCEApplicationBase* JUCEApplicationBase::appInstance = nullptr; - -JUCEApplicationBase::JUCEApplicationBase() - : appReturnValue (0), - stillInitialising (true) -{ - jassert (isStandaloneApp() && appInstance == nullptr); - appInstance = this; -} - -JUCEApplicationBase::~JUCEApplicationBase() -{ - jassert (appInstance == this); - appInstance = nullptr; -} - -void JUCEApplicationBase::setApplicationReturnValue (const int newReturnValue) noexcept -{ - appReturnValue = newReturnValue; -} - -// This is called on the Mac and iOS where the OS doesn't allow the stack to unwind on shutdown.. -void JUCEApplicationBase::appWillTerminateByForce() -{ - JUCE_AUTORELEASEPOOL - { - { - const ScopedPointer app (appInstance); - - if (app != nullptr) - app->shutdownApp(); - } - - DeletedAtShutdown::deleteAll(); - MessageManager::deleteInstance(); - } -} - -void JUCEApplicationBase::quit() -{ - MessageManager::getInstance()->stopDispatchLoop(); -} - -void JUCEApplicationBase::sendUnhandledException (const std::exception* const e, - const char* const sourceFile, - const int lineNumber) -{ - if (JUCEApplicationBase* const app = JUCEApplicationBase::getInstance()) - app->unhandledException (e, sourceFile, lineNumber); -} - -//============================================================================== -#if ! (JUCE_IOS || JUCE_ANDROID) - #define JUCE_HANDLE_MULTIPLE_INSTANCES 1 -#endif - -#if JUCE_HANDLE_MULTIPLE_INSTANCES -struct JUCEApplicationBase::MultipleInstanceHandler : public ActionListener -{ -public: - MultipleInstanceHandler (const String& appName) - : appLock ("juceAppLock_" + appName) - { - } - - bool sendCommandLineToPreexistingInstance() - { - if (appLock.enter (0)) - return false; - - JUCEApplicationBase* const app = JUCEApplicationBase::getInstance(); - jassert (app != nullptr); - - MessageManager::broadcastMessage (app->getApplicationName() - + "/" + app->getCommandLineParameters()); - return true; - } - - void actionListenerCallback (const String& message) override - { - if (JUCEApplicationBase* const app = JUCEApplicationBase::getInstance()) - { - const String appName (app->getApplicationName()); - - if (message.startsWith (appName + "/")) - app->anotherInstanceStarted (message.substring (appName.length() + 1)); - } - } - -private: - InterProcessLock appLock; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MultipleInstanceHandler) -}; - -bool JUCEApplicationBase::sendCommandLineToPreexistingInstance() -{ - jassert (multipleInstanceHandler == nullptr); // this must only be called once! - - multipleInstanceHandler = new MultipleInstanceHandler (getApplicationName()); - return multipleInstanceHandler->sendCommandLineToPreexistingInstance(); -} - -#else -struct JUCEApplicationBase::MultipleInstanceHandler {}; -#endif - -//============================================================================== -#if JUCE_ANDROID - -StringArray JUCEApplicationBase::getCommandLineParameterArray() { return StringArray(); } -String JUCEApplicationBase::getCommandLineParameters() { return String(); } - -#else - -#if JUCE_WINDOWS && ! defined (_CONSOLE) - -String JUCE_CALLTYPE JUCEApplicationBase::getCommandLineParameters() -{ - return CharacterFunctions::findEndOfToken (CharPointer_UTF16 (GetCommandLineW()), - CharPointer_UTF16 (L" "), - CharPointer_UTF16 (L"\"")).findEndOfWhitespace(); -} - -StringArray JUCE_CALLTYPE JUCEApplicationBase::getCommandLineParameterArray() -{ - StringArray s; - - int argc = 0; - if (LPWSTR* const argv = CommandLineToArgvW (GetCommandLineW(), &argc)) - { - s = StringArray (argv + 1, argc - 1); - LocalFree (argv); - } - - return s; -} - -#else - -#if JUCE_IOS - extern int juce_iOSMain (int argc, const char* argv[]); -#endif - -#if JUCE_MAC - extern void initialiseNSApplication(); -#endif - -#if JUCE_WINDOWS - const char* const* juce_argv = nullptr; - int juce_argc = 0; -#else - extern const char* const* juce_argv; // declared in juce_core - extern int juce_argc; -#endif - -String JUCEApplicationBase::getCommandLineParameters() -{ - String argString; - - for (int i = 1; i < juce_argc; ++i) - { - String arg (juce_argv[i]); - - if (arg.containsChar (' ') && ! arg.isQuotedString()) - arg = arg.quoted ('"'); - - argString << arg << ' '; - } - - return argString.trim(); -} - -StringArray JUCEApplicationBase::getCommandLineParameterArray() -{ - return StringArray (juce_argv + 1, juce_argc - 1); -} - -int JUCEApplicationBase::main (int argc, const char* argv[]) -{ - JUCE_AUTORELEASEPOOL - { - juce_argc = argc; - juce_argv = argv; - - #if JUCE_MAC - initialiseNSApplication(); - #endif - - #if JUCE_IOS - return juce_iOSMain (argc, argv); - #else - return JUCEApplicationBase::main(); - #endif - } -} - -#endif - -//============================================================================== -int JUCEApplicationBase::main() -{ - ScopedJuceInitialiser_GUI libraryInitialiser; - jassert (createInstance != nullptr); - - const ScopedPointer app (createInstance()); - jassert (app != nullptr); - - if (! app->initialiseApp()) - return app->getApplicationReturnValue(); - - JUCE_TRY - { - // loop until a quit message is received.. - MessageManager::getInstance()->runDispatchLoop(); - } - JUCE_CATCH_EXCEPTION - - return app->shutdownApp(); -} - -#endif - -//============================================================================== -bool JUCEApplicationBase::initialiseApp() -{ - #if JUCE_HANDLE_MULTIPLE_INSTANCES - if ((! moreThanOneInstanceAllowed()) && sendCommandLineToPreexistingInstance()) - { - DBG ("Another instance is running - quitting..."); - return false; - } - #endif - - // let the app do its setting-up.. - initialise (getCommandLineParameters()); - - stillInitialising = false; - - if (MessageManager::getInstance()->hasStopMessageBeenSent()) - return false; - - #if JUCE_HANDLE_MULTIPLE_INSTANCES - if (multipleInstanceHandler != nullptr) - MessageManager::getInstance()->registerBroadcastListener (multipleInstanceHandler); - #endif - - return true; -} - -int JUCEApplicationBase::shutdownApp() -{ - jassert (JUCEApplicationBase::getInstance() == this); - - #if JUCE_HANDLE_MULTIPLE_INSTANCES - if (multipleInstanceHandler != nullptr) - MessageManager::getInstance()->deregisterBroadcastListener (multipleInstanceHandler); - #endif - - JUCE_TRY - { - // give the app a chance to clean up.. - shutdown(); - } - JUCE_CATCH_EXCEPTION - - multipleInstanceHandler = nullptr; - return getApplicationReturnValue(); -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/messages/juce_ApplicationBase.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/messages/juce_ApplicationBase.h deleted file mode 100644 index 073e5d6c71..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/messages/juce_ApplicationBase.h +++ /dev/null @@ -1,283 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_APPLICATIONBASE_H_INCLUDED -#define JUCE_APPLICATIONBASE_H_INCLUDED - - -//============================================================================== -/** - Abstract base class for application classes. - - Note that in the juce_gui_basics module, there's a utility class JUCEApplication - which derives from JUCEApplicationBase, and takes care of a few chores. Most - of the time you'll want to derive your class from JUCEApplication rather than - using JUCEApplicationBase directly, but if you're not using the juce_gui_basics - module then you might need to go straight to this base class. - - Any application that wants to run an event loop must declare a subclass of - JUCEApplicationBase, and implement its various pure virtual methods. - - It then needs to use the START_JUCE_APPLICATION macro somewhere in a CPP file - to declare an instance of this class and generate suitable platform-specific - boilerplate code to launch the app. - - e.g. @code - class MyJUCEApp : public JUCEApplication - { - public: - MyJUCEApp() {} - ~MyJUCEApp() {} - - void initialise (const String& commandLine) override - { - myMainWindow = new MyApplicationWindow(); - myMainWindow->setBounds (100, 100, 400, 500); - myMainWindow->setVisible (true); - } - - void shutdown() override - { - myMainWindow = nullptr; - } - - const String getApplicationName() override - { - return "Super JUCE-o-matic"; - } - - const String getApplicationVersion() override - { - return "1.0"; - } - - private: - ScopedPointer myMainWindow; - }; - - // this generates boilerplate code to launch our app class: - START_JUCE_APPLICATION (MyJUCEApp) - @endcode - - @see JUCEApplication, START_JUCE_APPLICATION -*/ -class JUCE_API JUCEApplicationBase -{ -protected: - //============================================================================== - JUCEApplicationBase(); - -public: - /** Destructor. */ - virtual ~JUCEApplicationBase(); - - //============================================================================== - /** Returns the global instance of the application object that's running. */ - static JUCEApplicationBase* getInstance() noexcept { return appInstance; } - - //============================================================================== - /** Returns the application's name. */ - virtual const String getApplicationName() = 0; - - /** Returns the application's version number. */ - virtual const String getApplicationVersion() = 0; - - /** Checks whether multiple instances of the app are allowed. - - If you application class returns true for this, more than one instance is - permitted to run (except on the Mac where this isn't possible). - - If it's false, the second instance won't start, but it you will still get a - callback to anotherInstanceStarted() to tell you about this - which - gives you a chance to react to what the user was trying to do. - */ - virtual bool moreThanOneInstanceAllowed() = 0; - - /** Called when the application starts. - - This will be called once to let the application do whatever initialisation - it needs, create its windows, etc. - - After the method returns, the normal event-dispatch loop will be run, - until the quit() method is called, at which point the shutdown() - method will be called to let the application clear up anything it needs - to delete. - - If during the initialise() method, the application decides not to start-up - after all, it can just call the quit() method and the event loop won't be run. - - @param commandLineParameters the line passed in does not include the name of - the executable, just the parameter list. To get the - parameters as an array, you can call - JUCEApplication::getCommandLineParameters() - @see shutdown, quit - */ - virtual void initialise (const String& commandLineParameters) = 0; - - /* Called to allow the application to clear up before exiting. - - After JUCEApplication::quit() has been called, the event-dispatch loop will - terminate, and this method will get called to allow the app to sort itself - out. - - Be careful that nothing happens in this method that might rely on messages - being sent, or any kind of window activity, because the message loop is no - longer running at this point. - - @see DeletedAtShutdown - */ - virtual void shutdown() = 0; - - /** Indicates that the user has tried to start up another instance of the app. - - This will get called even if moreThanOneInstanceAllowed() is false. - */ - virtual void anotherInstanceStarted (const String& commandLine) = 0; - - /** Called when the operating system is trying to close the application. - - The default implementation of this method is to call quit(), but it may - be overloaded to ignore the request or do some other special behaviour - instead. For example, you might want to offer the user the chance to save - their changes before quitting, and give them the chance to cancel. - - If you want to send a quit signal to your app, this is the correct method - to call, because it means that requests that come from the system get handled - in the same way as those from your own application code. So e.g. you'd - call this method from a "quit" item on a menu bar. - */ - virtual void systemRequestedQuit() = 0; - - /** This method is called when the application is being put into background mode - by the operating system. - */ - virtual void suspended() = 0; - - /** This method is called when the application is being woken from background mode - by the operating system. - */ - virtual void resumed() = 0; - - /** If any unhandled exceptions make it through to the message dispatch loop, this - callback will be triggered, in case you want to log them or do some other - type of error-handling. - - If the type of exception is derived from the std::exception class, the pointer - passed-in will be valid. If the exception is of unknown type, this pointer - will be null. - */ - virtual void unhandledException (const std::exception*, - const String& sourceFilename, - int lineNumber) = 0; - - //============================================================================== - /** Signals that the main message loop should stop and the application should terminate. - - This isn't synchronous, it just posts a quit message to the main queue, and - when this message arrives, the message loop will stop, the shutdown() method - will be called, and the app will exit. - - Note that this will cause an unconditional quit to happen, so if you need an - extra level before this, e.g. to give the user the chance to save their work - and maybe cancel the quit, you'll need to handle this in the systemRequestedQuit() - method - see that method's help for more info. - - @see MessageManager - */ - static void quit(); - - //============================================================================== - /** Returns the application's command line parameters as a set of strings. - @see getCommandLineParameters - */ - static StringArray JUCE_CALLTYPE getCommandLineParameterArray(); - - /** Returns the application's command line parameters as a single string. - @see getCommandLineParameterArray - */ - static String JUCE_CALLTYPE getCommandLineParameters(); - - //============================================================================== - /** Sets the value that should be returned as the application's exit code when the - app quits. - - This is the value that's returned by the main() function. Normally you'd leave this - as 0 unless you want to indicate an error code. - - @see getApplicationReturnValue - */ - void setApplicationReturnValue (int newReturnValue) noexcept; - - /** Returns the value that has been set as the application's exit code. - @see setApplicationReturnValue - */ - int getApplicationReturnValue() const noexcept { return appReturnValue; } - - //============================================================================== - /** Returns true if this executable is running as an app (as opposed to being a plugin - or other kind of shared library. */ - static bool isStandaloneApp() noexcept { return createInstance != nullptr; } - - /** Returns true if the application hasn't yet completed its initialise() method - and entered the main event loop. - - This is handy for things like splash screens to know when the app's up-and-running - properly. - */ - bool isInitialising() const noexcept { return stillInitialising; } - - - //============================================================================== - #ifndef DOXYGEN - // The following methods are for internal use only... - static int main(); - static int main (int argc, const char* argv[]); - - static void appWillTerminateByForce(); - typedef JUCEApplicationBase* (*CreateInstanceFunction)(); - static CreateInstanceFunction createInstance; - - virtual bool initialiseApp(); - static void JUCE_CALLTYPE sendUnhandledException (const std::exception*, const char* sourceFile, int lineNumber); - bool sendCommandLineToPreexistingInstance(); - #endif - -private: - //============================================================================== - static JUCEApplicationBase* appInstance; - int appReturnValue; - bool stillInitialising; - - struct MultipleInstanceHandler; - friend struct MultipleInstanceHandler; - friend struct ContainerDeletePolicy; - ScopedPointer multipleInstanceHandler; - - int shutdownApp(); - - JUCE_DECLARE_NON_COPYABLE (JUCEApplicationBase) -}; - - -#endif // JUCE_APPLICATIONBASE_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/messages/juce_CallbackMessage.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/messages/juce_CallbackMessage.h deleted file mode 100644 index 799defdfec..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/messages/juce_CallbackMessage.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_CALLBACKMESSAGE_H_INCLUDED -#define JUCE_CALLBACKMESSAGE_H_INCLUDED - - -//============================================================================== -/** - A message that invokes a callback method when it gets delivered. - - You can use this class to fire off actions that you want to be performed later - on the message thread. - - To use it, create a subclass of CallbackMessage which implements the messageCallback() - method, then call post() to dispatch it. The event thread will then invoke your - messageCallback() method later on, and will automatically delete the message object - afterwards. - - Always create a new instance of a CallbackMessage on the heap, as it will be - deleted automatically after the message has been delivered. - - @see MessageManager, MessageListener, ActionListener, ChangeListener -*/ -class JUCE_API CallbackMessage : public MessageManager::MessageBase -{ -public: - //============================================================================== - CallbackMessage() noexcept {} - - /** Destructor. */ - ~CallbackMessage() {} - - //============================================================================== - /** Called when the message is delivered. - - You should implement this method and make it do whatever action you want - to perform. - - Note that like all other messages, this object will be deleted immediately - after this method has been invoked. - */ - virtual void messageCallback() = 0; - -private: - // Avoid the leak-detector because for plugins, the host can unload our DLL with undelivered - // messages still in the system event queue. These aren't harmful, but can cause annoying assertions. - JUCE_DECLARE_NON_COPYABLE (CallbackMessage) -}; - - -#endif // JUCE_CALLBACKMESSAGE_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/messages/juce_DeletedAtShutdown.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/messages/juce_DeletedAtShutdown.cpp deleted file mode 100644 index d3c6e97251..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/messages/juce_DeletedAtShutdown.cpp +++ /dev/null @@ -1,79 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -static SpinLock deletedAtShutdownLock; - -DeletedAtShutdown::DeletedAtShutdown() -{ - const SpinLock::ScopedLockType sl (deletedAtShutdownLock); - getObjects().add (this); -} - -DeletedAtShutdown::~DeletedAtShutdown() -{ - const SpinLock::ScopedLockType sl (deletedAtShutdownLock); - getObjects().removeFirstMatchingValue (this); -} - -void DeletedAtShutdown::deleteAll() -{ - // make a local copy of the array, so it can't get into a loop if something - // creates another DeletedAtShutdown object during its destructor. - Array localCopy; - - { - const SpinLock::ScopedLockType sl (deletedAtShutdownLock); - localCopy = getObjects(); - } - - for (int i = localCopy.size(); --i >= 0;) - { - JUCE_TRY - { - DeletedAtShutdown* deletee = localCopy.getUnchecked(i); - - // double-check that it's not already been deleted during another object's destructor. - { - const SpinLock::ScopedLockType sl (deletedAtShutdownLock); - if (! getObjects().contains (deletee)) - deletee = nullptr; - } - - delete deletee; - } - JUCE_CATCH_EXCEPTION - } - - // if no objects got re-created during shutdown, this should have been emptied by their - // destructors - jassert (getObjects().size() == 0); - - getObjects().clear(); // just to make sure the array doesn't have any memory still allocated -} - -Array & DeletedAtShutdown::getObjects() -{ - static Array objects; - return objects; -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/messages/juce_DeletedAtShutdown.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/messages/juce_DeletedAtShutdown.h deleted file mode 100644 index ce1f10eddb..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/messages/juce_DeletedAtShutdown.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_DELETEDATSHUTDOWN_H_INCLUDED -#define JUCE_DELETEDATSHUTDOWN_H_INCLUDED - - -//============================================================================== -/** - Classes derived from this will be automatically deleted when the application exits. - - After JUCEApplicationBase::shutdown() has been called, any objects derived from - DeletedAtShutdown which are still in existence will be deleted in the reverse - order to that in which they were created. - - So if you've got a singleton and don't want to have to explicitly delete it, just - inherit from this and it'll be taken care of. -*/ -class JUCE_API DeletedAtShutdown -{ -protected: - /** Creates a DeletedAtShutdown object. */ - DeletedAtShutdown(); - - /** Destructor. - - It's ok to delete these objects explicitly - it's only the ones left - dangling at the end that will be deleted automatically. - */ - virtual ~DeletedAtShutdown(); - - -public: - /** Deletes all extant objects. - - This shouldn't be used by applications, as it's called automatically - in the shutdown code of the JUCEApplicationBase class. - */ - static void deleteAll(); - -private: - static Array & getObjects(); - - JUCE_DECLARE_NON_COPYABLE (DeletedAtShutdown) -}; - -#endif // JUCE_DELETEDATSHUTDOWN_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/messages/juce_Initialisation.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/messages/juce_Initialisation.h deleted file mode 100644 index d3302dd74c..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/messages/juce_Initialisation.h +++ /dev/null @@ -1,112 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_INITIALISATION_H_INCLUDED -#define JUCE_INITIALISATION_H_INCLUDED - - -//============================================================================== -/** Initialises Juce's GUI classes. - - If you're embedding Juce into an application that uses its own event-loop rather - than using the START_JUCE_APPLICATION macro, call this function before making any - Juce calls, to make sure things are initialised correctly. - - Note that if you're creating a Juce DLL for Windows, you may also need to call the - Process::setCurrentModuleInstanceHandle() method. - - @see shutdownJuce_GUI() -*/ -JUCE_API void JUCE_CALLTYPE initialiseJuce_GUI(); - -/** Clears up any static data being used by Juce's GUI classes. - - If you're embedding Juce into an application that uses its own event-loop rather - than using the START_JUCE_APPLICATION macro, call this function in your shutdown - code to clean up any juce objects that might be lying around. - - @see initialiseJuce_GUI() -*/ -JUCE_API void JUCE_CALLTYPE shutdownJuce_GUI(); - - -//============================================================================== -/** A utility object that helps you initialise and shutdown Juce correctly - using an RAII pattern. - - When the first instance of this class is created, it calls initialiseJuce_GUI(), - and when the last instance is deleted, it calls shutdownJuce_GUI(), so that you - can easily be sure that as long as at least one instance of the class exists, the - library will be initialised. - - This class is particularly handy to use at the beginning of a console app's - main() function, because it'll take care of shutting down whenever you return - from the main() call. - - Be careful with your threading though - to be safe, you should always make sure - that these objects are created and deleted on the message thread. -*/ -class JUCE_API ScopedJuceInitialiser_GUI -{ -public: - /** The constructor simply calls initialiseJuce_GUI(). */ - ScopedJuceInitialiser_GUI(); - - /** The destructor simply calls shutdownJuce_GUI(). */ - ~ScopedJuceInitialiser_GUI(); -}; - - -//============================================================================== -/** - To start a JUCE app, use this macro: START_JUCE_APPLICATION (AppSubClass) where - AppSubClass is the name of a class derived from JUCEApplication or JUCEApplicationBase. - - See the JUCEApplication and JUCEApplicationBase class documentation for more details. -*/ -#ifdef DOXYGEN - #define START_JUCE_APPLICATION(AppClass) -#elif JUCE_ANDROID - #define START_JUCE_APPLICATION(AppClass) \ - juce::JUCEApplicationBase* juce_CreateApplication() { return new AppClass(); } - -#else - #if JUCE_WINDOWS && ! defined (_CONSOLE) - #define JUCE_MAIN_FUNCTION int __stdcall WinMain (struct HINSTANCE__*, struct HINSTANCE__*, char*, int) - #define JUCE_MAIN_FUNCTION_ARGS - #else - #define JUCE_MAIN_FUNCTION int main (int argc, char* argv[]) - #define JUCE_MAIN_FUNCTION_ARGS argc, (const char**) argv - #endif - - #define START_JUCE_APPLICATION(AppClass) \ - static juce::JUCEApplicationBase* juce_CreateApplication() { return new AppClass(); } \ - extern "C" JUCE_MAIN_FUNCTION \ - { \ - juce::JUCEApplicationBase::createInstance = &juce_CreateApplication; \ - return juce::JUCEApplicationBase::main (JUCE_MAIN_FUNCTION_ARGS); \ - } -#endif - -#endif // JUCE_INITIALISATION_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/messages/juce_Message.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/messages/juce_Message.h deleted file mode 100644 index 4ae55f6f1e..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/messages/juce_Message.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_MESSAGE_H_INCLUDED -#define JUCE_MESSAGE_H_INCLUDED - -class MessageListener; - - -//============================================================================== -/** The base class for objects that can be sent to a MessageListener. - - If you want to send a message that carries some kind of custom data, just - create a subclass of Message with some appropriate member variables to hold - your data. - - Always create a new instance of a Message object on the heap, as it will be - deleted automatically after the message has been delivered. - - @see MessageListener, MessageManager, ActionListener, ChangeListener -*/ -class JUCE_API Message : public MessageManager::MessageBase -{ -public: - //============================================================================== - /** Creates an uninitialised message. */ - Message() noexcept; - ~Message(); - - typedef ReferenceCountedObjectPtr Ptr; - - //============================================================================== -private: - friend class MessageListener; - WeakReference recipient; - void messageCallback() override; - - // Avoid the leak-detector because for plugins, the host can unload our DLL with undelivered - // messages still in the system event queue. These aren't harmful, but can cause annoying assertions. - JUCE_DECLARE_NON_COPYABLE (Message) -}; - - -#endif // JUCE_MESSAGE_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/messages/juce_MessageListener.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/messages/juce_MessageListener.cpp deleted file mode 100644 index b398ffa3fe..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/messages/juce_MessageListener.cpp +++ /dev/null @@ -1,49 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -Message::Message() noexcept {} -Message::~Message() {} - -void Message::messageCallback() -{ - if (MessageListener* const r = recipient) - r->handleMessage (*this); -} - -MessageListener::MessageListener() noexcept -{ - // Are you trying to create a messagelistener before or after juce has been intialised?? - jassert (MessageManager::getInstanceWithoutCreating() != nullptr); -} - -MessageListener::~MessageListener() -{ - masterReference.clear(); -} - -void MessageListener::postMessage (Message* const message) const -{ - message->recipient = const_cast (this); - message->post(); -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/messages/juce_MessageListener.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/messages/juce_MessageListener.h deleted file mode 100644 index ddd51e23b5..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/messages/juce_MessageListener.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_MESSAGELISTENER_H_INCLUDED -#define JUCE_MESSAGELISTENER_H_INCLUDED - - -//============================================================================== -/** - MessageListener subclasses can post and receive Message objects. - - @see Message, MessageManager, ActionListener, ChangeListener -*/ -class JUCE_API MessageListener -{ -public: - //============================================================================== - MessageListener() noexcept; - - /** Destructor. */ - virtual ~MessageListener(); - - //============================================================================== - /** This is the callback method that receives incoming messages. - - This is called by the MessageManager from its dispatch loop. - - @see postMessage - */ - virtual void handleMessage (const Message& message) = 0; - - //============================================================================== - /** Sends a message to the message queue, for asynchronous delivery to this listener - later on. - - This method can be called safely by any thread. - - @param message the message object to send - this will be deleted - automatically by the message queue, so make sure it's - allocated on the heap, not the stack! - @see handleMessage - */ - void postMessage (Message* message) const; - -private: - WeakReference::Master masterReference; - friend class WeakReference; -}; - - -#endif // JUCE_MESSAGELISTENER_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/messages/juce_MessageManager.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/messages/juce_MessageManager.cpp deleted file mode 100644 index 44c2adc80f..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/messages/juce_MessageManager.cpp +++ /dev/null @@ -1,375 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -MessageManager::MessageManager() noexcept - : quitMessagePosted (false), - quitMessageReceived (false), - messageThreadId (Thread::getCurrentThreadId()), - threadWithLock (0) -{ - if (JUCEApplicationBase::isStandaloneApp()) - Thread::setCurrentThreadName ("Juce Message Thread"); -} - -MessageManager::~MessageManager() noexcept -{ - broadcaster = nullptr; - - doPlatformSpecificShutdown(); - - jassert (instance == this); - instance = nullptr; // do this last in case this instance is still needed by doPlatformSpecificShutdown() -} - -MessageManager* MessageManager::instance = nullptr; - -MessageManager* MessageManager::getInstance() -{ - if (instance == nullptr) - { - instance = new MessageManager(); - doPlatformSpecificInitialisation(); - } - - return instance; -} - -MessageManager* MessageManager::getInstanceWithoutCreating() noexcept -{ - return instance; -} - -void MessageManager::deleteInstance() -{ - deleteAndZero (instance); -} - -//============================================================================== -bool MessageManager::MessageBase::post() -{ - MessageManager* const mm = MessageManager::instance; - - if (mm == nullptr || mm->quitMessagePosted || ! postMessageToSystemQueue (this)) - { - Ptr deleter (this); // (this will delete messages that were just created with a 0 ref count) - return false; - } - - return true; -} - -//============================================================================== -#if JUCE_MODAL_LOOPS_PERMITTED && ! (JUCE_MAC || JUCE_IOS) -void MessageManager::runDispatchLoop() -{ - runDispatchLoopUntil (-1); -} - -bool MessageManager::runDispatchLoopUntil (int millisecondsToRunFor) -{ - jassert (isThisTheMessageThread()); // must only be called by the message thread - - const int64 endTime = Time::currentTimeMillis() + millisecondsToRunFor; - - while (! quitMessageReceived) - { - JUCE_TRY - { - if (! dispatchNextMessageOnSystemQueue (millisecondsToRunFor >= 0)) - Thread::sleep (1); - } - JUCE_CATCH_EXCEPTION - - if (millisecondsToRunFor >= 0 && Time::currentTimeMillis() >= endTime) - break; - } - - return ! quitMessageReceived; -} - -class MessageManager::QuitMessage : public MessageManager::MessageBase -{ -public: - QuitMessage() {} - - void messageCallback() override - { - if (MessageManager* const mm = MessageManager::instance) - mm->quitMessageReceived = true; - } - - JUCE_DECLARE_NON_COPYABLE (QuitMessage) -}; - -void MessageManager::stopDispatchLoop() -{ - (new QuitMessage())->post(); - quitMessagePosted = true; -} - -#endif - -//============================================================================== -#if JUCE_COMPILER_SUPPORTS_LAMBDAS -struct AsyncFunction : private MessageManager::MessageBase -{ - AsyncFunction (std::function f) : fn (f) { post(); } - -private: - std::function fn; - void messageCallback() override { fn(); } - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AsyncFunction) -}; - -void MessageManager::callAsync (std::function f) -{ - new AsyncFunction (f); -} -#endif - -//============================================================================== -class AsyncFunctionCallback : public MessageManager::MessageBase -{ -public: - AsyncFunctionCallback (MessageCallbackFunction* const f, void* const param) - : result (nullptr), func (f), parameter (param) - {} - - void messageCallback() override - { - result = (*func) (parameter); - finished.signal(); - } - - WaitableEvent finished; - void* volatile result; - -private: - MessageCallbackFunction* const func; - void* const parameter; - - JUCE_DECLARE_NON_COPYABLE (AsyncFunctionCallback) -}; - -void* MessageManager::callFunctionOnMessageThread (MessageCallbackFunction* const func, void* const parameter) -{ - if (isThisTheMessageThread()) - return func (parameter); - - // If this thread has the message manager locked, then this will deadlock! - jassert (! currentThreadHasLockedMessageManager()); - - const ReferenceCountedObjectPtr message (new AsyncFunctionCallback (func, parameter)); - - if (message->post()) - { - message->finished.wait(); - return message->result; - } - - jassertfalse; // the OS message queue failed to send the message! - return nullptr; -} - -//============================================================================== -void MessageManager::deliverBroadcastMessage (const String& value) -{ - if (broadcaster != nullptr) - broadcaster->sendActionMessage (value); -} - -void MessageManager::registerBroadcastListener (ActionListener* const listener) -{ - if (broadcaster == nullptr) - broadcaster = new ActionBroadcaster(); - - broadcaster->addActionListener (listener); -} - -void MessageManager::deregisterBroadcastListener (ActionListener* const listener) -{ - if (broadcaster != nullptr) - broadcaster->removeActionListener (listener); -} - -//============================================================================== -bool MessageManager::isThisTheMessageThread() const noexcept -{ - return Thread::getCurrentThreadId() == messageThreadId; -} - -void MessageManager::setCurrentThreadAsMessageThread() -{ - const Thread::ThreadID thisThread = Thread::getCurrentThreadId(); - - if (messageThreadId != thisThread) - { - messageThreadId = thisThread; - - // This is needed on windows to make sure the message window is created by this thread - doPlatformSpecificShutdown(); - doPlatformSpecificInitialisation(); - } -} - -bool MessageManager::currentThreadHasLockedMessageManager() const noexcept -{ - const Thread::ThreadID thisThread = Thread::getCurrentThreadId(); - return thisThread == messageThreadId || thisThread == threadWithLock; -} - -//============================================================================== -//============================================================================== -/* The only safe way to lock the message thread while another thread does - some work is by posting a special message, whose purpose is to tie up the event - loop until the other thread has finished its business. - - Any other approach can get horribly deadlocked if the OS uses its own hidden locks which - get locked before making an event callback, because if the same OS lock gets indirectly - accessed from another thread inside a MM lock, you're screwed. (this is exactly what happens - in Cocoa). -*/ -class MessageManagerLock::BlockingMessage : public MessageManager::MessageBase -{ -public: - BlockingMessage() noexcept {} - - void messageCallback() override - { - lockedEvent.signal(); - releaseEvent.wait(); - } - - WaitableEvent lockedEvent, releaseEvent; - - JUCE_DECLARE_NON_COPYABLE (BlockingMessage) -}; - -//============================================================================== -MessageManagerLock::MessageManagerLock (Thread* const threadToCheck) - : blockingMessage(), locked (attemptLock (threadToCheck, nullptr)) -{ -} - -MessageManagerLock::MessageManagerLock (ThreadPoolJob* const jobToCheckForExitSignal) - : blockingMessage(), locked (attemptLock (nullptr, jobToCheckForExitSignal)) -{ -} - -bool MessageManagerLock::attemptLock (Thread* const threadToCheck, ThreadPoolJob* const job) -{ - MessageManager* const mm = MessageManager::instance; - - if (mm == nullptr) - return false; - - if (mm->currentThreadHasLockedMessageManager()) - return true; - - if (threadToCheck == nullptr && job == nullptr) - { - mm->lockingLock.enter(); - } - else - { - while (! mm->lockingLock.tryEnter()) - { - if ((threadToCheck != nullptr && threadToCheck->threadShouldExit()) - || (job != nullptr && job->shouldExit())) - return false; - - Thread::yield(); - } - } - - blockingMessage = new BlockingMessage(); - - if (! blockingMessage->post()) - { - blockingMessage = nullptr; - return false; - } - - while (! blockingMessage->lockedEvent.wait (20)) - { - if ((threadToCheck != nullptr && threadToCheck->threadShouldExit()) - || (job != nullptr && job->shouldExit())) - { - blockingMessage->releaseEvent.signal(); - blockingMessage = nullptr; - mm->lockingLock.exit(); - return false; - } - } - - jassert (mm->threadWithLock == 0); - - mm->threadWithLock = Thread::getCurrentThreadId(); - return true; -} - -MessageManagerLock::~MessageManagerLock() noexcept -{ - if (blockingMessage != nullptr) - { - MessageManager* const mm = MessageManager::instance; - - jassert (mm == nullptr || mm->currentThreadHasLockedMessageManager()); - - blockingMessage->releaseEvent.signal(); - blockingMessage = nullptr; - - if (mm != nullptr) - { - mm->threadWithLock = 0; - mm->lockingLock.exit(); - } - } -} - -//============================================================================== -JUCE_API void JUCE_CALLTYPE initialiseJuce_GUI(); -JUCE_API void JUCE_CALLTYPE initialiseJuce_GUI() -{ - JUCE_AUTORELEASEPOOL - { - MessageManager::getInstance(); - } -} - -JUCE_API void JUCE_CALLTYPE shutdownJuce_GUI(); -JUCE_API void JUCE_CALLTYPE shutdownJuce_GUI() -{ - JUCE_AUTORELEASEPOOL - { - DeletedAtShutdown::deleteAll(); - MessageManager::deleteInstance(); - } -} - -static int numScopedInitInstances = 0; - -ScopedJuceInitialiser_GUI::ScopedJuceInitialiser_GUI() { if (numScopedInitInstances++ == 0) initialiseJuce_GUI(); } -ScopedJuceInitialiser_GUI::~ScopedJuceInitialiser_GUI() { if (--numScopedInitInstances == 0) shutdownJuce_GUI(); } diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/messages/juce_MessageManager.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/messages/juce_MessageManager.h deleted file mode 100644 index 0901b29d3b..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/messages/juce_MessageManager.h +++ /dev/null @@ -1,335 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_MESSAGEMANAGER_H_INCLUDED -#define JUCE_MESSAGEMANAGER_H_INCLUDED - -class MessageManagerLock; -class ThreadPoolJob; -class ActionListener; -class ActionBroadcaster; - - -//============================================================================== -/** See MessageManager::callFunctionOnMessageThread() for use of this function type -*/ -typedef void* (MessageCallbackFunction) (void* userData); - - -//============================================================================== -/** - This class is in charge of the application's event-dispatch loop. - - @see Message, CallbackMessage, MessageManagerLock, JUCEApplication, JUCEApplicationBase -*/ -class JUCE_API MessageManager -{ -public: - //============================================================================== - /** Returns the global instance of the MessageManager. */ - static MessageManager* getInstance(); - - /** Returns the global instance of the MessageManager, or nullptr if it doesn't exist. */ - static MessageManager* getInstanceWithoutCreating() noexcept; - - /** Deletes the global MessageManager instance. - Does nothing if no instance had been created. - */ - static void deleteInstance(); - - //============================================================================== - /** Runs the event dispatch loop until a stop message is posted. - - This method is only intended to be run by the application's startup routine, - as it blocks, and will only return after the stopDispatchLoop() method has been used. - - @see stopDispatchLoop - */ - void runDispatchLoop(); - - /** Sends a signal that the dispatch loop should terminate. - - After this is called, the runDispatchLoop() or runDispatchLoopUntil() methods - will be interrupted and will return. - - @see runDispatchLoop - */ - void stopDispatchLoop(); - - /** Returns true if the stopDispatchLoop() method has been called. - */ - bool hasStopMessageBeenSent() const noexcept { return quitMessagePosted; } - - #if JUCE_MODAL_LOOPS_PERMITTED || DOXYGEN - /** Synchronously dispatches messages until a given time has elapsed. - - Returns false if a quit message has been posted by a call to stopDispatchLoop(), - otherwise returns true. - */ - bool runDispatchLoopUntil (int millisecondsToRunFor); - #endif - - //============================================================================== - #if JUCE_COMPILER_SUPPORTS_LAMBDAS - /** Asynchronously invokes a function or C++11 lambda on the message thread. - Internally this uses the CallbackMessage class to invoke the callback. - */ - static void callAsync (std::function); - #endif - - /** Calls a function using the message-thread. - - This can be used by any thread to cause this function to be called-back - by the message thread. If it's the message-thread that's calling this method, - then the function will just be called; if another thread is calling, a message - will be posted to the queue, and this method will block until that message - is delivered, the function is called, and the result is returned. - - Be careful not to cause any deadlocks with this! It's easy to do - e.g. if the caller - thread has a critical section locked, which an unrelated message callback then tries to lock - before the message thread gets round to processing this callback. - - @param callback the function to call - its signature must be @code - void* myCallbackFunction (void*) @endcode - @param userData a user-defined pointer that will be passed to the function that gets called - @returns the value that the callback function returns. - @see MessageManagerLock - */ - void* callFunctionOnMessageThread (MessageCallbackFunction* callback, void* userData); - - /** Returns true if the caller-thread is the message thread. */ - bool isThisTheMessageThread() const noexcept; - - /** Called to tell the manager that the current thread is the one that's running the dispatch loop. - - (Best to ignore this method unless you really know what you're doing..) - @see getCurrentMessageThread - */ - void setCurrentThreadAsMessageThread(); - - /** Returns the ID of the current message thread, as set by setCurrentThreadAsMessageThread(). - - (Best to ignore this method unless you really know what you're doing..) - @see setCurrentThreadAsMessageThread - */ - Thread::ThreadID getCurrentMessageThread() const noexcept { return messageThreadId; } - - /** Returns true if the caller thread has currently got the message manager locked. - - see the MessageManagerLock class for more info about this. - - This will be true if the caller is the message thread, because that automatically - gains a lock while a message is being dispatched. - */ - bool currentThreadHasLockedMessageManager() const noexcept; - - //============================================================================== - /** Sends a message to all other JUCE applications that are running. - - @param messageText the string that will be passed to the actionListenerCallback() - method of the broadcast listeners in the other app. - @see registerBroadcastListener, ActionListener - */ - static void broadcastMessage (const String& messageText); - - /** Registers a listener to get told about broadcast messages. - - The actionListenerCallback() callback's string parameter - is the message passed into broadcastMessage(). - - @see broadcastMessage - */ - void registerBroadcastListener (ActionListener* listener); - - /** Deregisters a broadcast listener. */ - void deregisterBroadcastListener (ActionListener* listener); - - //============================================================================== - /** Internal class used as the base class for all message objects. - You shouldn't need to use this directly - see the CallbackMessage or Message - classes instead. - */ - class JUCE_API MessageBase : public ReferenceCountedObject - { - public: - MessageBase() noexcept {} - virtual ~MessageBase() {} - - virtual void messageCallback() = 0; - bool post(); - - typedef ReferenceCountedObjectPtr Ptr; - - JUCE_DECLARE_NON_COPYABLE (MessageBase) - }; - - //============================================================================== - #ifndef DOXYGEN - // Internal methods - do not use! - void deliverBroadcastMessage (const String&); - ~MessageManager() noexcept; - #endif - -private: - //============================================================================== - MessageManager() noexcept; - - static MessageManager* instance; - - friend class MessageBase; - class QuitMessage; - friend class QuitMessage; - friend class MessageManagerLock; - - ScopedPointer broadcaster; - bool quitMessagePosted, quitMessageReceived; - Thread::ThreadID messageThreadId; - Thread::ThreadID volatile threadWithLock; - CriticalSection lockingLock; - - static bool postMessageToSystemQueue (MessageBase*); - static void* exitModalLoopCallback (void*); - static void doPlatformSpecificInitialisation(); - static void doPlatformSpecificShutdown(); - static bool dispatchNextMessageOnSystemQueue (bool returnIfNoPendingMessages); - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MessageManager) -}; - - -//============================================================================== -/** Used to make sure that the calling thread has exclusive access to the message loop. - - Because it's not thread-safe to call any of the Component or other UI classes - from threads other than the message thread, one of these objects can be used to - lock the message loop and allow this to be done. The message thread will be - suspended for the lifetime of the MessageManagerLock object, so create one on - the stack like this: @code - void MyThread::run() - { - someData = 1234; - - const MessageManagerLock mmLock; - // the event loop will now be locked so it's safe to make a few calls.. - - myComponent->setBounds (newBounds); - myComponent->repaint(); - - // ..the event loop will now be unlocked as the MessageManagerLock goes out of scope - } - @endcode - - Obviously be careful not to create one of these and leave it lying around, or - your app will grind to a halt! - - Another caveat is that using this in conjunction with other CriticalSections - can create lots of interesting ways of producing a deadlock! In particular, if - your message thread calls stopThread() for a thread that uses these locks, - you'll get an (occasional) deadlock.. - - @see MessageManager, MessageManager::currentThreadHasLockedMessageManager -*/ -class JUCE_API MessageManagerLock -{ -public: - //============================================================================== - /** Tries to acquire a lock on the message manager. - - The constructor attempts to gain a lock on the message loop, and the lock will be - kept for the lifetime of this object. - - Optionally, you can pass a thread object here, and while waiting to obtain the lock, - this method will keep checking whether the thread has been given the - Thread::signalThreadShouldExit() signal. If this happens, then it will return - without gaining the lock. If you pass a thread, you must check whether the lock was - successful by calling lockWasGained(). If this is false, your thread is being told to - die, so you should take evasive action. - - If you pass nullptr for the thread object, it will wait indefinitely for the lock - be - careful when doing this, because it's very easy to deadlock if your message thread - attempts to call stopThread() on a thread just as that thread attempts to get the - message lock. - - If the calling thread already has the lock, nothing will be done, so it's safe and - quick to use these locks recursively. - - E.g. - @code - void run() - { - ... - - while (! threadShouldExit()) - { - MessageManagerLock mml (Thread::getCurrentThread()); - - if (! mml.lockWasGained()) - return; // another thread is trying to kill us! - - ..do some locked stuff here.. - } - - ..and now the MM is now unlocked.. - } - @endcode - - */ - MessageManagerLock (Thread* threadToCheckForExitSignal = nullptr); - - //============================================================================== - /** This has the same behaviour as the other constructor, but takes a ThreadPoolJob - instead of a thread. - - See the MessageManagerLock (Thread*) constructor for details on how this works. - */ - MessageManagerLock (ThreadPoolJob* jobToCheckForExitSignal); - - - //============================================================================== - /** Releases the current thread's lock on the message manager. - - Make sure this object is created and deleted by the same thread, - otherwise there are no guarantees what will happen! - */ - ~MessageManagerLock() noexcept; - - //============================================================================== - /** Returns true if the lock was successfully acquired. - (See the constructor that takes a Thread for more info). - */ - bool lockWasGained() const noexcept { return locked; } - -private: - class BlockingMessage; - friend class ReferenceCountedObjectPtr; - ReferenceCountedObjectPtr blockingMessage; - bool locked; - - bool attemptLock (Thread*, ThreadPoolJob*); - - JUCE_DECLARE_NON_COPYABLE (MessageManagerLock) -}; - - -#endif // JUCE_MESSAGEMANAGER_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/messages/juce_MountedVolumeListChangeDetector.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/messages/juce_MountedVolumeListChangeDetector.h deleted file mode 100644 index fe62875439..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/messages/juce_MountedVolumeListChangeDetector.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_MOUNTEDVOLUMELISTCHANGEDETECTOR_H_INCLUDED -#define JUCE_MOUNTEDVOLUMELISTCHANGEDETECTOR_H_INCLUDED - -#if JUCE_MAC || JUCE_WINDOWS || defined (DOXYGEN) - -//============================================================================== -/** - An instance of this class will provide callbacks when drives are - mounted or unmounted on the system. - - Just inherit from this class and implement the pure virtual method - to get the callbacks, there's no need to do anything else. - - @see File::findFileSystemRoots() -*/ -class JUCE_API MountedVolumeListChangeDetector -{ -public: - MountedVolumeListChangeDetector(); - virtual ~MountedVolumeListChangeDetector(); - - /** This method is called when a volume is mounted or unmounted. */ - virtual void mountedVolumeListChanged() = 0; - -private: - JUCE_PUBLIC_IN_DLL_BUILD (struct Pimpl) - friend struct ContainerDeletePolicy; - ScopedPointer pimpl; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MountedVolumeListChangeDetector) -}; - -#endif - -#endif // JUCE_MOUNTEDVOLUMELISTCHANGEDETECTOR_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/messages/juce_NotificationType.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/messages/juce_NotificationType.h deleted file mode 100644 index c3ecccc66b..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/messages/juce_NotificationType.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_NOTIFICATIONTYPE_H_INCLUDED -#define JUCE_NOTIFICATIONTYPE_H_INCLUDED - -//============================================================================== -/** - These enums are used in various classes to indicate whether a notification - event should be sent out. -*/ -enum NotificationType -{ - dontSendNotification = 0, /**< No notification message should be sent. */ - sendNotification = 1, /**< Requests a notification message, either synchronous or not. */ - sendNotificationSync, /**< Requests a synchronous notification. */ - sendNotificationAsync, /**< Requests an asynchronous notification. */ -}; - - -#endif // JUCE_NOTIFICATIONTYPE_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/native/juce_ScopedXLock.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/native/juce_ScopedXLock.h deleted file mode 100644 index d2136c728e..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/native/juce_ScopedXLock.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_SCOPEDXLOCK_H_INCLUDED -#define JUCE_SCOPEDXLOCK_H_INCLUDED - - -//============================================================================== -#if JUCE_LINUX || DOXYGEN - -/** A handy class that uses XLockDisplay and XUnlockDisplay to lock the X server - using RAII (Only available in Linux!). -*/ -class ScopedXLock -{ -public: - /** Creating a ScopedXLock object locks the X display. - This uses XLockDisplay() to grab the display that Juce is using. - */ - ScopedXLock(); - - /** Deleting a ScopedXLock object unlocks the X display. - This calls XUnlockDisplay() to release the lock. - */ - ~ScopedXLock(); -}; - -#endif -#endif // JUCE_SCOPEDXLOCK_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/native/juce_android_Messaging.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/native/juce_android_Messaging.cpp deleted file mode 100644 index 733994ad6c..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/native/juce_android_Messaging.cpp +++ /dev/null @@ -1,79 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -void MessageManager::doPlatformSpecificInitialisation() {} -void MessageManager::doPlatformSpecificShutdown() {} - -//============================================================================== -bool MessageManager::dispatchNextMessageOnSystemQueue (const bool returnIfNoPendingMessages) -{ - Logger::outputDebugString ("*** Modal loops are not possible in Android!! Exiting..."); - exit (1); - - return true; -} - -//============================================================================== -bool MessageManager::postMessageToSystemQueue (MessageManager::MessageBase* const message) -{ - message->incReferenceCount(); - android.activity.callVoidMethod (JuceAppActivity.postMessage, (jlong) (pointer_sized_uint) message); - return true; -} - -JUCE_JNI_CALLBACK (JUCE_ANDROID_ACTIVITY_CLASSNAME, deliverMessage, void, (jobject activity, jlong value)) -{ - JUCE_TRY - { - MessageManager::MessageBase* const message = (MessageManager::MessageBase*) (pointer_sized_uint) value; - message->messageCallback(); - message->decReferenceCount(); - } - JUCE_CATCH_EXCEPTION -} - -//============================================================================== -void MessageManager::broadcastMessage (const String&) -{ -} - -void MessageManager::runDispatchLoop() -{ -} - -void MessageManager::stopDispatchLoop() -{ - struct QuitCallback : public CallbackMessage - { - QuitCallback() {} - - void messageCallback() override - { - android.activity.callVoidMethod (JuceAppActivity.finish); - } - }; - - (new QuitCallback())->post(); - quitMessagePosted = true; -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/native/juce_ios_MessageManager.mm b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/native/juce_ios_MessageManager.mm deleted file mode 100644 index bdfed65999..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/native/juce_ios_MessageManager.mm +++ /dev/null @@ -1,88 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -void MessageManager::runDispatchLoop() -{ - jassert (isThisTheMessageThread()); // must only be called by the message thread - runDispatchLoopUntil (-1); -} - -void MessageManager::stopDispatchLoop() -{ - [[[UIApplication sharedApplication] delegate] applicationWillTerminate: [UIApplication sharedApplication]]; - exit (0); // iOS apps get no mercy.. -} - -bool MessageManager::runDispatchLoopUntil (int millisecondsToRunFor) -{ - JUCE_AUTORELEASEPOOL - { - jassert (isThisTheMessageThread()); // must only be called by the message thread - - uint32 startTime = Time::getMillisecondCounter(); - NSDate* endDate = [NSDate dateWithTimeIntervalSinceNow: millisecondsToRunFor * 0.001]; - - while (! quitMessagePosted) - { - JUCE_AUTORELEASEPOOL - { - [[NSRunLoop currentRunLoop] runMode: NSDefaultRunLoopMode - beforeDate: endDate]; - - if (millisecondsToRunFor >= 0 - && Time::getMillisecondCounter() >= startTime + (uint32) millisecondsToRunFor) - break; - } - } - - return ! quitMessagePosted; - } -} - -//============================================================================== -static ScopedPointer messageQueue; - -void MessageManager::doPlatformSpecificInitialisation() -{ - if (messageQueue == nullptr) - messageQueue = new MessageQueue(); -} - -void MessageManager::doPlatformSpecificShutdown() -{ - messageQueue = nullptr; -} - -bool MessageManager::postMessageToSystemQueue (MessageManager::MessageBase* const message) -{ - if (messageQueue != nullptr) - messageQueue->post (message); - - return true; -} - -void MessageManager::broadcastMessage (const String&) -{ - // N/A on current iOS -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/native/juce_linux_Messaging.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/native/juce_linux_Messaging.cpp deleted file mode 100644 index 48e28a7395..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/native/juce_linux_Messaging.cpp +++ /dev/null @@ -1,398 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#if JUCE_DEBUG && ! defined (JUCE_DEBUG_XERRORS) - #define JUCE_DEBUG_XERRORS 1 -#endif - -Display* display = nullptr; -Window juce_messageWindowHandle = None; -XContext windowHandleXContext; // This is referenced from Windowing.cpp - -typedef bool (*WindowMessageReceiveCallback) (XEvent&); -WindowMessageReceiveCallback dispatchWindowMessage = nullptr; - -typedef void (*SelectionRequestCallback) (XSelectionRequestEvent&); -SelectionRequestCallback handleSelectionRequest = nullptr; - -//============================================================================== -ScopedXLock::ScopedXLock() { XLockDisplay (display); } -ScopedXLock::~ScopedXLock() { XUnlockDisplay (display); } - -//============================================================================== -class InternalMessageQueue -{ -public: - InternalMessageQueue() - : bytesInSocket (0), - totalEventCount (0) - { - int ret = ::socketpair (AF_LOCAL, SOCK_STREAM, 0, fd); - (void) ret; jassert (ret == 0); - } - - ~InternalMessageQueue() - { - close (fd[0]); - close (fd[1]); - - clearSingletonInstance(); - } - - //============================================================================== - void postMessage (MessageManager::MessageBase* const msg) - { - const int maxBytesInSocketQueue = 128; - - ScopedLock sl (lock); - queue.add (msg); - - if (bytesInSocket < maxBytesInSocketQueue) - { - ++bytesInSocket; - - ScopedUnlock ul (lock); - const unsigned char x = 0xff; - size_t bytesWritten = write (fd[0], &x, 1); - (void) bytesWritten; - } - } - - bool isEmpty() const - { - ScopedLock sl (lock); - return queue.size() == 0; - } - - bool dispatchNextEvent() - { - // This alternates between giving priority to XEvents or internal messages, - // to keep everything running smoothly.. - if ((++totalEventCount & 1) != 0) - return dispatchNextXEvent() || dispatchNextInternalMessage(); - - return dispatchNextInternalMessage() || dispatchNextXEvent(); - } - - // Wait for an event (either XEvent, or an internal Message) - bool sleepUntilEvent (const int timeoutMs) - { - if (! isEmpty()) - return true; - - if (display != 0) - { - ScopedXLock xlock; - if (XPending (display)) - return true; - } - - struct timeval tv; - tv.tv_sec = 0; - tv.tv_usec = timeoutMs * 1000; - int fd0 = getWaitHandle(); - int fdmax = fd0; - - fd_set readset; - FD_ZERO (&readset); - FD_SET (fd0, &readset); - - if (display != 0) - { - ScopedXLock xlock; - int fd1 = XConnectionNumber (display); - FD_SET (fd1, &readset); - fdmax = jmax (fd0, fd1); - } - - const int ret = select (fdmax + 1, &readset, 0, 0, &tv); - return (ret > 0); // ret <= 0 if error or timeout - } - - //============================================================================== - juce_DeclareSingleton_SingleThreaded_Minimal (InternalMessageQueue); - -private: - CriticalSection lock; - ReferenceCountedArray queue; - int fd[2]; - int bytesInSocket; - int totalEventCount; - - int getWaitHandle() const noexcept { return fd[1]; } - - static bool setNonBlocking (int handle) - { - int socketFlags = fcntl (handle, F_GETFL, 0); - if (socketFlags == -1) - return false; - - socketFlags |= O_NONBLOCK; - return fcntl (handle, F_SETFL, socketFlags) == 0; - } - - static bool dispatchNextXEvent() - { - if (display == 0) - return false; - - XEvent evt; - - { - ScopedXLock xlock; - if (! XPending (display)) - return false; - - XNextEvent (display, &evt); - } - - if (evt.type == SelectionRequest && evt.xany.window == juce_messageWindowHandle - && handleSelectionRequest != nullptr) - handleSelectionRequest (evt.xselectionrequest); - else if (evt.xany.window != juce_messageWindowHandle && dispatchWindowMessage != nullptr) - dispatchWindowMessage (evt); - - return true; - } - - MessageManager::MessageBase::Ptr popNextMessage() - { - const ScopedLock sl (lock); - - if (bytesInSocket > 0) - { - --bytesInSocket; - - const ScopedUnlock ul (lock); - unsigned char x; - size_t numBytes = read (fd[1], &x, 1); - (void) numBytes; - } - - return queue.removeAndReturn (0); - } - - bool dispatchNextInternalMessage() - { - if (const MessageManager::MessageBase::Ptr msg = popNextMessage()) - { - JUCE_TRY - { - msg->messageCallback(); - return true; - } - JUCE_CATCH_EXCEPTION - } - - return false; - } -}; - -juce_ImplementSingleton_SingleThreaded (InternalMessageQueue); - - -//============================================================================== -namespace LinuxErrorHandling -{ - static bool errorOccurred = false; - static bool keyboardBreakOccurred = false; - static XErrorHandler oldErrorHandler = (XErrorHandler) 0; - static XIOErrorHandler oldIOErrorHandler = (XIOErrorHandler) 0; - - //============================================================================== - // Usually happens when client-server connection is broken - int ioErrorHandler (Display*) - { - DBG ("ERROR: connection to X server broken.. terminating."); - - if (JUCEApplicationBase::isStandaloneApp()) - MessageManager::getInstance()->stopDispatchLoop(); - - errorOccurred = true; - return 0; - } - - int errorHandler (Display* display, XErrorEvent* event) - { - #if JUCE_DEBUG_XERRORS - char errorStr[64] = { 0 }; - char requestStr[64] = { 0 }; - - XGetErrorText (display, event->error_code, errorStr, 64); - XGetErrorDatabaseText (display, "XRequest", String (event->request_code).toUTF8(), "Unknown", requestStr, 64); - DBG ("ERROR: X returned " << errorStr << " for operation " << requestStr); - #endif - - return 0; - } - - void installXErrorHandlers() - { - oldIOErrorHandler = XSetIOErrorHandler (ioErrorHandler); - oldErrorHandler = XSetErrorHandler (errorHandler); - } - - void removeXErrorHandlers() - { - if (JUCEApplicationBase::isStandaloneApp()) - { - XSetIOErrorHandler (oldIOErrorHandler); - oldIOErrorHandler = 0; - - XSetErrorHandler (oldErrorHandler); - oldErrorHandler = 0; - } - } - - //============================================================================== - void keyboardBreakSignalHandler (int sig) - { - if (sig == SIGINT) - keyboardBreakOccurred = true; - } - - void installKeyboardBreakHandler() - { - struct sigaction saction; - sigset_t maskSet; - sigemptyset (&maskSet); - saction.sa_handler = keyboardBreakSignalHandler; - saction.sa_mask = maskSet; - saction.sa_flags = 0; - sigaction (SIGINT, &saction, 0); - } -} - -//============================================================================== -void MessageManager::doPlatformSpecificInitialisation() -{ - if (JUCEApplicationBase::isStandaloneApp()) - { - // Initialise xlib for multiple thread support - static bool initThreadCalled = false; - - if (! initThreadCalled) - { - if (! XInitThreads()) - { - // This is fatal! Print error and closedown - Logger::outputDebugString ("Failed to initialise xlib thread support."); - Process::terminate(); - return; - } - - initThreadCalled = true; - } - - LinuxErrorHandling::installXErrorHandlers(); - LinuxErrorHandling::installKeyboardBreakHandler(); - } - - // Create the internal message queue - InternalMessageQueue::getInstance(); - - // Try to connect to a display - String displayName (getenv ("DISPLAY")); - if (displayName.isEmpty()) - displayName = ":0.0"; - - display = XOpenDisplay (displayName.toUTF8()); - - if (display != 0) // This is not fatal! we can run headless. - { - // Create a context to store user data associated with Windows we create - windowHandleXContext = XUniqueContext(); - - // We're only interested in client messages for this window, which are always sent - XSetWindowAttributes swa; - swa.event_mask = NoEventMask; - - // Create our message window (this will never be mapped) - const int screen = DefaultScreen (display); - juce_messageWindowHandle = XCreateWindow (display, RootWindow (display, screen), - 0, 0, 1, 1, 0, 0, InputOnly, - DefaultVisual (display, screen), - CWEventMask, &swa); - } -} - -void MessageManager::doPlatformSpecificShutdown() -{ - InternalMessageQueue::deleteInstance(); - - if (display != 0 && ! LinuxErrorHandling::errorOccurred) - { - XDestroyWindow (display, juce_messageWindowHandle); - XCloseDisplay (display); - - juce_messageWindowHandle = 0; - display = nullptr; - - LinuxErrorHandling::removeXErrorHandlers(); - } -} - -bool MessageManager::postMessageToSystemQueue (MessageManager::MessageBase* const message) -{ - if (LinuxErrorHandling::errorOccurred) - return false; - - InternalMessageQueue::getInstanceWithoutCreating()->postMessage (message); - return true; -} - -void MessageManager::broadcastMessage (const String& /* value */) -{ - /* TODO */ -} - -// this function expects that it will NEVER be called simultaneously for two concurrent threads -bool MessageManager::dispatchNextMessageOnSystemQueue (bool returnIfNoPendingMessages) -{ - while (! LinuxErrorHandling::errorOccurred) - { - if (LinuxErrorHandling::keyboardBreakOccurred) - { - LinuxErrorHandling::errorOccurred = true; - - if (JUCEApplicationBase::isStandaloneApp()) - Process::terminate(); - - break; - } - - InternalMessageQueue* const queue = InternalMessageQueue::getInstanceWithoutCreating(); - jassert (queue != nullptr); - - if (queue->dispatchNextEvent()) - return true; - - if (returnIfNoPendingMessages) - break; - - queue->sleepUntilEvent (2000); - } - - return false; -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/native/juce_mac_MessageManager.mm b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/native/juce_mac_MessageManager.mm deleted file mode 100644 index 7b2068ebfb..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/native/juce_mac_MessageManager.mm +++ /dev/null @@ -1,418 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -typedef void (*AppFocusChangeCallback)(); -AppFocusChangeCallback appFocusChangeCallback = nullptr; - -typedef bool (*CheckEventBlockedByModalComps) (NSEvent*); -CheckEventBlockedByModalComps isEventBlockedByModalComps = nullptr; - -typedef void (*MenuTrackingChangedCallback)(bool); -MenuTrackingChangedCallback menuTrackingChangedCallback = nullptr; - -//============================================================================== -struct AppDelegate -{ -public: - AppDelegate() - { - static AppDelegateClass cls; - delegate = [cls.createInstance() init]; - - NSNotificationCenter* center = [NSNotificationCenter defaultCenter]; - - [center addObserver: delegate selector: @selector (mainMenuTrackingBegan:) - name: NSMenuDidBeginTrackingNotification object: nil]; - [center addObserver: delegate selector: @selector (mainMenuTrackingEnded:) - name: NSMenuDidEndTrackingNotification object: nil]; - - if (JUCEApplicationBase::isStandaloneApp()) - { - [NSApp setDelegate: delegate]; - - [[NSDistributedNotificationCenter defaultCenter] addObserver: delegate - selector: @selector (broadcastMessageCallback:) - name: getBroacastEventName() - object: nil]; - } - else - { - [center addObserver: delegate selector: @selector (applicationDidResignActive:) - name: NSApplicationDidResignActiveNotification object: NSApp]; - - [center addObserver: delegate selector: @selector (applicationDidBecomeActive:) - name: NSApplicationDidBecomeActiveNotification object: NSApp]; - - [center addObserver: delegate selector: @selector (applicationWillUnhide:) - name: NSApplicationWillUnhideNotification object: NSApp]; - } - } - - ~AppDelegate() - { - [[NSRunLoop currentRunLoop] cancelPerformSelectorsWithTarget: delegate]; - [[NSNotificationCenter defaultCenter] removeObserver: delegate]; - - if (JUCEApplicationBase::isStandaloneApp()) - { - [NSApp setDelegate: nil]; - - [[NSDistributedNotificationCenter defaultCenter] removeObserver: delegate - name: getBroacastEventName() - object: nil]; - } - - [delegate release]; - } - - static NSString* getBroacastEventName() - { - return juceStringToNS ("juce_" + String::toHexString (File::getSpecialLocation (File::currentExecutableFile).hashCode64())); - } - - MessageQueue messageQueue; - id delegate; - -private: - //============================================================================== - struct AppDelegateClass : public ObjCClass - { - AppDelegateClass() : ObjCClass ("JUCEAppDelegate_") - { - addMethod (@selector (applicationShouldTerminate:), applicationShouldTerminate, "I@:@"); - addMethod (@selector (applicationWillTerminate:), applicationWillTerminate, "v@:@"); - addMethod (@selector (application:openFile:), application_openFile, "c@:@@"); - addMethod (@selector (application:openFiles:), application_openFiles, "v@:@@"); - addMethod (@selector (applicationDidBecomeActive:), applicationDidBecomeActive, "v@:@"); - addMethod (@selector (applicationDidResignActive:), applicationDidResignActive, "v@:@"); - addMethod (@selector (applicationWillUnhide:), applicationWillUnhide, "v@:@"); - addMethod (@selector (broadcastMessageCallback:), broadcastMessageCallback, "v@:@"); - addMethod (@selector (mainMenuTrackingBegan:), mainMenuTrackingBegan, "v@:@"); - addMethod (@selector (mainMenuTrackingEnded:), mainMenuTrackingEnded, "v@:@"); - addMethod (@selector (dummyMethod), dummyMethod, "v@:"); - - registerClass(); - } - - private: - static NSApplicationTerminateReply applicationShouldTerminate (id /*self*/, SEL, NSApplication*) - { - if (JUCEApplicationBase* const app = JUCEApplicationBase::getInstance()) - { - app->systemRequestedQuit(); - - if (! MessageManager::getInstance()->hasStopMessageBeenSent()) - return NSTerminateCancel; - } - - return NSTerminateNow; - } - - static void applicationWillTerminate (id /*self*/, SEL, NSNotification*) - { - JUCEApplicationBase::appWillTerminateByForce(); - } - - static BOOL application_openFile (id /*self*/, SEL, NSApplication*, NSString* filename) - { - if (JUCEApplicationBase* const app = JUCEApplicationBase::getInstance()) - { - app->anotherInstanceStarted (quotedIfContainsSpaces (filename)); - return YES; - } - - return NO; - } - - static void application_openFiles (id /*self*/, SEL, NSApplication*, NSArray* filenames) - { - if (JUCEApplicationBase* const app = JUCEApplicationBase::getInstance()) - { - StringArray files; - - for (NSString* f in filenames) - files.add (quotedIfContainsSpaces (f)); - - if (files.size() > 0) - app->anotherInstanceStarted (files.joinIntoString (" ")); - } - } - - static void applicationDidBecomeActive (id /*self*/, SEL, NSNotification*) { focusChanged(); } - static void applicationDidResignActive (id /*self*/, SEL, NSNotification*) { focusChanged(); } - static void applicationWillUnhide (id /*self*/, SEL, NSNotification*) { focusChanged(); } - - static void broadcastMessageCallback (id /*self*/, SEL, NSNotification* n) - { - NSDictionary* dict = (NSDictionary*) [n userInfo]; - const String messageString (nsStringToJuce ((NSString*) [dict valueForKey: nsStringLiteral ("message")])); - MessageManager::getInstance()->deliverBroadcastMessage (messageString); - } - - static void mainMenuTrackingBegan (id /*self*/, SEL, NSNotification*) - { - if (menuTrackingChangedCallback != nullptr) - (*menuTrackingChangedCallback) (true); - } - - static void mainMenuTrackingEnded (id /*self*/, SEL, NSNotification*) - { - if (menuTrackingChangedCallback != nullptr) - (*menuTrackingChangedCallback) (false); - } - - static void dummyMethod (id /*self*/, SEL) {} // (used as a way of running a dummy thread) - - private: - static void focusChanged() - { - if (appFocusChangeCallback != nullptr) - (*appFocusChangeCallback)(); - } - - static String quotedIfContainsSpaces (NSString* file) - { - String s (nsStringToJuce (file)); - if (s.containsChar (' ')) - s = s.quoted ('"'); - - return s; - } - }; -}; - -//============================================================================== -void MessageManager::runDispatchLoop() -{ - if (! quitMessagePosted) // check that the quit message wasn't already posted.. - { - JUCE_AUTORELEASEPOOL - { - // must only be called by the message thread! - jassert (isThisTheMessageThread()); - - #if JUCE_PROJUCER_LIVE_BUILD - runDispatchLoopUntil (std::numeric_limits::max()); - #else - #if JUCE_CATCH_UNHANDLED_EXCEPTIONS - @try - { - [NSApp run]; - } - @catch (NSException* e) - { - // An AppKit exception will kill the app, but at least this provides a chance to log it., - std::runtime_error ex (std::string ("NSException: ") + [[e name] UTF8String] + ", Reason:" + [[e reason] UTF8String]); - JUCEApplication::sendUnhandledException (&ex, __FILE__, __LINE__); - } - @finally - { - } - #else - [NSApp run]; - #endif - #endif - } - } -} - -static void shutdownNSApp() -{ - [NSApp stop: nil]; - [NSApp activateIgnoringOtherApps: YES]; // (if the app is inactive, it sits there and ignores the quit request until the next time it gets activated) - [NSEvent startPeriodicEventsAfterDelay: 0 withPeriod: 0.1]; -} - -void MessageManager::stopDispatchLoop() -{ - quitMessagePosted = true; - - #if ! JUCE_PROJUCER_LIVE_BUILD - if (isThisTheMessageThread()) - { - shutdownNSApp(); - } - else - { - struct QuitCallback : public CallbackMessage - { - QuitCallback() {} - void messageCallback() override { shutdownNSApp(); } - }; - - (new QuitCallback())->post(); - } - #endif -} - -#if JUCE_MODAL_LOOPS_PERMITTED -bool MessageManager::runDispatchLoopUntil (int millisecondsToRunFor) -{ - jassert (millisecondsToRunFor >= 0); - jassert (isThisTheMessageThread()); // must only be called by the message thread - - uint32 endTime = Time::getMillisecondCounter() + (uint32) millisecondsToRunFor; - - while (! quitMessagePosted) - { - JUCE_AUTORELEASEPOOL - { - CFRunLoopRunInMode (kCFRunLoopDefaultMode, 0.001, true); - - NSEvent* e = [NSApp nextEventMatchingMask: NSAnyEventMask - untilDate: [NSDate dateWithTimeIntervalSinceNow: 0.001] - inMode: NSDefaultRunLoopMode - dequeue: YES]; - - if (e != nil && (isEventBlockedByModalComps == nullptr || ! (*isEventBlockedByModalComps) (e))) - [NSApp sendEvent: e]; - - if (Time::getMillisecondCounter() >= endTime) - break; - } - } - - return ! quitMessagePosted; -} -#endif - -//============================================================================== -void initialiseNSApplication(); -void initialiseNSApplication() -{ - JUCE_AUTORELEASEPOOL - { - [NSApplication sharedApplication]; - } -} - -static AppDelegate* appDelegate = nullptr; - -void MessageManager::doPlatformSpecificInitialisation() -{ - if (appDelegate == nil) - appDelegate = new AppDelegate(); - - #if ! (defined (MAC_OS_X_VERSION_10_5) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5) - // This launches a dummy thread, which forces Cocoa to initialise NSThreads correctly (needed prior to 10.5) - if (! [NSThread isMultiThreaded]) - [NSThread detachNewThreadSelector: @selector (dummyMethod) - toTarget: appDelegate->delegate - withObject: nil]; - #endif -} - -void MessageManager::doPlatformSpecificShutdown() -{ - delete appDelegate; - appDelegate = nullptr; -} - -bool MessageManager::postMessageToSystemQueue (MessageBase* message) -{ - jassert (appDelegate != nil); - appDelegate->messageQueue.post (message); - return true; -} - -void MessageManager::broadcastMessage (const String& message) -{ - NSDictionary* info = [NSDictionary dictionaryWithObject: juceStringToNS (message) - forKey: nsStringLiteral ("message")]; - - [[NSDistributedNotificationCenter defaultCenter] postNotificationName: AppDelegate::getBroacastEventName() - object: nil - userInfo: info]; -} - -// Special function used by some plugin classes to re-post carbon events -void repostCurrentNSEvent(); -void repostCurrentNSEvent() -{ - struct EventReposter : public CallbackMessage - { - EventReposter() : e ([[NSApp currentEvent] retain]) {} - ~EventReposter() { [e release]; } - - void messageCallback() override - { - [NSApp postEvent: e atStart: YES]; - } - - NSEvent* e; - }; - - (new EventReposter())->post(); -} - - -//============================================================================== -#if JUCE_MAC -struct MountedVolumeListChangeDetector::Pimpl -{ - Pimpl (MountedVolumeListChangeDetector& d) : owner (d) - { - static ObserverClass cls; - delegate = [cls.createInstance() init]; - ObserverClass::setOwner (delegate, this); - - NSNotificationCenter* nc = [[NSWorkspace sharedWorkspace] notificationCenter]; - - [nc addObserver: delegate selector: @selector (changed:) name: NSWorkspaceDidMountNotification object: nil]; - [nc addObserver: delegate selector: @selector (changed:) name: NSWorkspaceDidUnmountNotification object: nil]; - } - - ~Pimpl() - { - [[[NSWorkspace sharedWorkspace] notificationCenter] removeObserver: delegate]; - [delegate release]; - } - -private: - MountedVolumeListChangeDetector& owner; - id delegate; - - struct ObserverClass : public ObjCClass - { - ObserverClass() : ObjCClass ("JUCEDriveObserver_") - { - addIvar ("owner"); - addMethod (@selector (changed:), changed, "v@:@"); - addProtocol (@protocol (NSTextInput)); - registerClass(); - } - - static Pimpl* getOwner (id self) { return getIvar (self, "owner"); } - static void setOwner (id self, Pimpl* owner) { object_setInstanceVariable (self, "owner", owner); } - - static void changed (id self, SEL, NSNotification*) - { - getOwner (self)->owner.mountedVolumeListChanged(); - } - }; -}; - -MountedVolumeListChangeDetector::MountedVolumeListChangeDetector() { pimpl = new Pimpl (*this); } -MountedVolumeListChangeDetector::~MountedVolumeListChangeDetector() {} -#endif diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/native/juce_osx_MessageQueue.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/native/juce_osx_MessageQueue.h deleted file mode 100644 index 6ffbefe6bd..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/native/juce_osx_MessageQueue.h +++ /dev/null @@ -1,103 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_OSX_MESSAGEQUEUE_H_INCLUDED -#define JUCE_OSX_MESSAGEQUEUE_H_INCLUDED - -//============================================================================== -/* An internal message pump class used in OSX and iOS. */ -class MessageQueue -{ -public: - MessageQueue() - { - #if MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_4 && ! JUCE_IOS - runLoop = CFRunLoopGetMain(); - #else - runLoop = CFRunLoopGetCurrent(); - #endif - - CFRunLoopSourceContext sourceContext; - zerostruct (sourceContext); // (can't use "= { 0 }" on this object because it's typedef'ed as a C struct) - sourceContext.info = this; - sourceContext.perform = runLoopSourceCallback; - runLoopSource = CFRunLoopSourceCreate (kCFAllocatorDefault, 1, &sourceContext); - CFRunLoopAddSource (runLoop, runLoopSource, kCFRunLoopCommonModes); - } - - ~MessageQueue() - { - CFRunLoopRemoveSource (runLoop, runLoopSource, kCFRunLoopCommonModes); - CFRunLoopSourceInvalidate (runLoopSource); - CFRelease (runLoopSource); - } - - void post (MessageManager::MessageBase* const message) - { - messages.add (message); - CFRunLoopSourceSignal (runLoopSource); - CFRunLoopWakeUp (runLoop); - } - -private: - ReferenceCountedArray messages; - CFRunLoopRef runLoop; - CFRunLoopSourceRef runLoopSource; - - bool deliverNextMessage() - { - const MessageManager::MessageBase::Ptr nextMessage (messages.removeAndReturn (0)); - - if (nextMessage == nullptr) - return false; - - JUCE_AUTORELEASEPOOL - { - JUCE_TRY - { - nextMessage->messageCallback(); - } - JUCE_CATCH_EXCEPTION - } - - return true; - } - - void runLoopCallback() - { - for (int i = 4; --i >= 0;) - if (! deliverNextMessage()) - return; - - CFRunLoopSourceSignal (runLoopSource); - CFRunLoopWakeUp (runLoop); - } - - static void runLoopSourceCallback (void* info) - { - static_cast (info)->runLoopCallback(); - } -}; - -#endif // JUCE_OSX_MESSAGEQUEUE_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/native/juce_win32_HiddenMessageWindow.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/native/juce_win32_HiddenMessageWindow.h deleted file mode 100644 index e0df59ad0b..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/native/juce_win32_HiddenMessageWindow.h +++ /dev/null @@ -1,137 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_WIN32_HIDDENMESSAGEWINDOW_H_INCLUDED -#define JUCE_WIN32_HIDDENMESSAGEWINDOW_H_INCLUDED - -//============================================================================== -class HiddenMessageWindow -{ -public: - HiddenMessageWindow (const TCHAR* const messageWindowName, WNDPROC wndProc) - { - String className ("JUCE_"); - className << String::toHexString (Time::getHighResolutionTicks()); - - HMODULE moduleHandle = (HMODULE) Process::getCurrentModuleInstanceHandle(); - - WNDCLASSEX wc = { 0 }; - wc.cbSize = sizeof (wc); - wc.lpfnWndProc = wndProc; - wc.cbWndExtra = 4; - wc.hInstance = moduleHandle; - wc.lpszClassName = className.toWideCharPointer(); - - atom = RegisterClassEx (&wc); - jassert (atom != 0); - - hwnd = CreateWindow (getClassNameFromAtom(), messageWindowName, - 0, 0, 0, 0, 0, 0, 0, moduleHandle, 0); - jassert (hwnd != 0); - } - - ~HiddenMessageWindow() - { - DestroyWindow (hwnd); - UnregisterClass (getClassNameFromAtom(), 0); - } - - inline HWND getHWND() const noexcept { return hwnd; } - -private: - ATOM atom; - HWND hwnd; - - LPCTSTR getClassNameFromAtom() noexcept { return (LPCTSTR) MAKELONG (atom, 0); } -}; - -//============================================================================== -class JuceWindowIdentifier -{ -public: - static bool isJUCEWindow (HWND hwnd) noexcept - { - return GetWindowLongPtr (hwnd, GWLP_USERDATA) == getImprobableWindowNumber(); - } - - static void setAsJUCEWindow (HWND hwnd, bool isJuceWindow) noexcept - { - SetWindowLongPtr (hwnd, GWLP_USERDATA, isJuceWindow ? getImprobableWindowNumber() : 0); - } - -private: - static LONG_PTR getImprobableWindowNumber() noexcept - { - static LONG_PTR number = (LONG_PTR) Random::getSystemRandom().nextInt64(); - return number; - } -}; - -//============================================================================== -class DeviceChangeDetector : private Timer -{ -public: - DeviceChangeDetector (const wchar_t* const name) - : messageWindow (name, (WNDPROC) deviceChangeEventCallback) - { - SetWindowLongPtr (messageWindow.getHWND(), GWLP_USERDATA, (LONG_PTR) this); - } - - virtual ~DeviceChangeDetector() {} - - virtual void systemDeviceChanged() = 0; - - void triggerAsyncDeviceChangeCallback() - { - // We'll pause before sending a message, because on device removal, the OS hasn't always updated - // its device lists correctly at this point. This also helps avoid repeated callbacks. - startTimer (500); - } - -private: - HiddenMessageWindow messageWindow; - - static LRESULT CALLBACK deviceChangeEventCallback (HWND h, const UINT message, - const WPARAM wParam, const LPARAM lParam) - { - if (message == WM_DEVICECHANGE - && (wParam == 0x8000 /*DBT_DEVICEARRIVAL*/ - || wParam == 0x8004 /*DBT_DEVICEREMOVECOMPLETE*/ - || wParam == 0x0007 /*DBT_DEVNODES_CHANGED*/)) - { - ((DeviceChangeDetector*) GetWindowLongPtr (h, GWLP_USERDATA)) - ->triggerAsyncDeviceChangeCallback(); - } - - return DefWindowProc (h, message, wParam, lParam); - } - - void timerCallback() override - { - stopTimer(); - systemDeviceChanged(); - } -}; - -#endif // JUCE_WIN32_HIDDENMESSAGEWINDOW_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/native/juce_win32_Messaging.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/native/juce_win32_Messaging.cpp deleted file mode 100644 index 853f54d84f..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/native/juce_win32_Messaging.cpp +++ /dev/null @@ -1,217 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -extern HWND juce_messageWindowHandle; - -typedef bool (*CheckEventBlockedByModalComps) (const MSG&); -CheckEventBlockedByModalComps isEventBlockedByModalComps = nullptr; - -//============================================================================== -namespace WindowsMessageHelpers -{ - const unsigned int specialId = WM_APP + 0x4400; - const unsigned int broadcastId = WM_APP + 0x4403; - - const TCHAR messageWindowName[] = _T("JUCEWindow"); - ScopedPointer messageWindow; - - void dispatchMessageFromLParam (LPARAM lParam) - { - MessageManager::MessageBase* const message = reinterpret_cast (lParam); - - JUCE_TRY - { - message->messageCallback(); - } - JUCE_CATCH_EXCEPTION - - message->decReferenceCount(); - } - - //============================================================================== - LRESULT CALLBACK messageWndProc (HWND h, const UINT message, const WPARAM wParam, const LPARAM lParam) noexcept - { - if (h == juce_messageWindowHandle) - { - if (message == specialId) - { - // (These are trapped early in our dispatch loop, but must also be checked - // here in case some 3rd-party code is running the dispatch loop). - dispatchMessageFromLParam (lParam); - return 0; - } - else if (message == broadcastId) - { - const ScopedPointer messageString ((String*) lParam); - MessageManager::getInstance()->deliverBroadcastMessage (*messageString); - return 0; - } - else if (message == WM_COPYDATA) - { - const COPYDATASTRUCT* const data = reinterpret_cast (lParam); - - if (data->dwData == broadcastId) - { - const String messageString (CharPointer_UTF32 ((const CharPointer_UTF32::CharType*) data->lpData), - data->cbData / sizeof (CharPointer_UTF32::CharType)); - - PostMessage (juce_messageWindowHandle, broadcastId, 0, (LPARAM) new String (messageString)); - return 0; - } - } - } - - return DefWindowProc (h, message, wParam, lParam); - } - - BOOL CALLBACK broadcastEnumWindowProc (HWND hwnd, LPARAM lParam) - { - if (hwnd != juce_messageWindowHandle) - reinterpret_cast *> (lParam)->add (hwnd); - - return TRUE; - } -} - -//============================================================================== -bool MessageManager::dispatchNextMessageOnSystemQueue (const bool returnIfNoPendingMessages) -{ - using namespace WindowsMessageHelpers; - MSG m; - - if (returnIfNoPendingMessages && ! PeekMessage (&m, (HWND) 0, 0, 0, PM_NOREMOVE)) - return false; - - if (GetMessage (&m, (HWND) 0, 0, 0) >= 0) - { - if (m.message == specialId && m.hwnd == juce_messageWindowHandle) - { - dispatchMessageFromLParam (m.lParam); - } - else if (m.message == WM_QUIT) - { - if (JUCEApplicationBase* const app = JUCEApplicationBase::getInstance()) - app->systemRequestedQuit(); - } - else if (isEventBlockedByModalComps == nullptr || ! isEventBlockedByModalComps (m)) - { - if ((m.message == WM_LBUTTONDOWN || m.message == WM_RBUTTONDOWN) - && ! JuceWindowIdentifier::isJUCEWindow (m.hwnd)) - { - // if it's someone else's window being clicked on, and the focus is - // currently on a juce window, pass the kb focus over.. - HWND currentFocus = GetFocus(); - - if (currentFocus == 0 || JuceWindowIdentifier::isJUCEWindow (currentFocus)) - SetFocus (m.hwnd); - } - - TranslateMessage (&m); - DispatchMessage (&m); - } - } - - return true; -} - -bool MessageManager::postMessageToSystemQueue (MessageManager::MessageBase* const message) -{ - message->incReferenceCount(); - return PostMessage (juce_messageWindowHandle, WindowsMessageHelpers::specialId, 0, (LPARAM) message) != 0; -} - -void MessageManager::broadcastMessage (const String& value) -{ - Array windows; - EnumWindows (&WindowsMessageHelpers::broadcastEnumWindowProc, (LPARAM) &windows); - - const String localCopy (value); - - COPYDATASTRUCT data; - data.dwData = WindowsMessageHelpers::broadcastId; - data.cbData = (localCopy.length() + 1) * sizeof (CharPointer_UTF32::CharType); - data.lpData = (void*) localCopy.toUTF32().getAddress(); - - for (int i = windows.size(); --i >= 0;) - { - HWND hwnd = windows.getUnchecked(i); - - TCHAR windowName [64]; // no need to read longer strings than this - GetWindowText (hwnd, windowName, 64); - windowName [63] = 0; - - if (String (windowName) == WindowsMessageHelpers::messageWindowName) - { - DWORD_PTR result; - SendMessageTimeout (hwnd, WM_COPYDATA, - (WPARAM) juce_messageWindowHandle, - (LPARAM) &data, - SMTO_BLOCK | SMTO_ABORTIFHUNG, 8000, &result); - } - } -} - -//============================================================================== -void MessageManager::doPlatformSpecificInitialisation() -{ - OleInitialize (0); - - using namespace WindowsMessageHelpers; - messageWindow = new HiddenMessageWindow (messageWindowName, (WNDPROC) messageWndProc); - juce_messageWindowHandle = messageWindow->getHWND(); -} - -void MessageManager::doPlatformSpecificShutdown() -{ - WindowsMessageHelpers::messageWindow = nullptr; - - OleUninitialize(); -} - -//============================================================================== -struct MountedVolumeListChangeDetector::Pimpl : private DeviceChangeDetector -{ - Pimpl (MountedVolumeListChangeDetector& d) : DeviceChangeDetector (L"MountedVolumeList"), owner (d) - { - File::findFileSystemRoots (lastVolumeList); - } - - void systemDeviceChanged() override - { - Array newList; - File::findFileSystemRoots (newList); - - if (lastVolumeList != newList) - { - lastVolumeList = newList; - owner.mountedVolumeListChanged(); - } - } - - MountedVolumeListChangeDetector& owner; - Array lastVolumeList; -}; - -MountedVolumeListChangeDetector::MountedVolumeListChangeDetector() { pimpl = new Pimpl (*this); } -MountedVolumeListChangeDetector::~MountedVolumeListChangeDetector() {} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/timers/juce_MultiTimer.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/timers/juce_MultiTimer.cpp deleted file mode 100644 index 4885e7b5fe..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/timers/juce_MultiTimer.cpp +++ /dev/null @@ -1,105 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -struct MultiTimerCallback : public Timer -{ - MultiTimerCallback (const int tid, MultiTimer& mt) noexcept - : owner (mt), timerID (tid) - { - } - - void timerCallback() override - { - owner.timerCallback (timerID); - } - - MultiTimer& owner; - const int timerID; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MultiTimerCallback) -}; - -//============================================================================== -MultiTimer::MultiTimer() noexcept {} -MultiTimer::MultiTimer (const MultiTimer&) noexcept {} - -MultiTimer::~MultiTimer() -{ - const SpinLock::ScopedLockType sl (timerListLock); - timers.clear(); -} - -//============================================================================== -Timer* MultiTimer::getCallback (int timerID) const noexcept -{ - for (int i = timers.size(); --i >= 0;) - { - MultiTimerCallback* const t = static_cast (timers.getUnchecked(i)); - - if (t->timerID == timerID) - return t; - } - - return nullptr; -} - -void MultiTimer::startTimer (const int timerID, const int intervalInMilliseconds) noexcept -{ - const SpinLock::ScopedLockType sl (timerListLock); - - Timer* timer = getCallback (timerID); - - if (timer == nullptr) - timers.add (timer = new MultiTimerCallback (timerID, *this)); - - timer->startTimer (intervalInMilliseconds); -} - -void MultiTimer::stopTimer (const int timerID) noexcept -{ - const SpinLock::ScopedLockType sl (timerListLock); - - if (Timer* const t = getCallback (timerID)) - t->stopTimer(); -} - -bool MultiTimer::isTimerRunning (const int timerID) const noexcept -{ - const SpinLock::ScopedLockType sl (timerListLock); - - if (Timer* const t = getCallback (timerID)) - return t->isTimerRunning(); - - return false; -} - -int MultiTimer::getTimerInterval (const int timerID) const noexcept -{ - const SpinLock::ScopedLockType sl (timerListLock); - - if (Timer* const t = getCallback (timerID)) - return t->getTimerInterval(); - - return 0; -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/timers/juce_MultiTimer.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/timers/juce_MultiTimer.h deleted file mode 100644 index c7fe0e43ef..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/timers/juce_MultiTimer.h +++ /dev/null @@ -1,126 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_MULTITIMER_H_INCLUDED -#define JUCE_MULTITIMER_H_INCLUDED - - -//============================================================================== -/** - A type of timer class that can run multiple timers with different frequencies, - all of which share a single callback. - - This class is very similar to the Timer class, but allows you run multiple - separate timers, where each one has a unique ID number. The methods in this - class are exactly equivalent to those in Timer, but with the addition of - this ID number. - - To use it, you need to create a subclass of MultiTimer, implementing the - timerCallback() method. Then you can start timers with startTimer(), and - each time the callback is triggered, it passes in the ID of the timer that - caused it. - - @see Timer -*/ -class JUCE_API MultiTimer -{ -protected: - //============================================================================== - /** Creates a MultiTimer. - - When created, no timers are running, so use startTimer() to start things off. - */ - MultiTimer() noexcept; - - /** Creates a copy of another timer. - - Note that this timer will not contain any running timers, even if the one you're - copying from was running. - */ - MultiTimer (const MultiTimer&) noexcept; - -public: - //============================================================================== - /** Destructor. */ - virtual ~MultiTimer(); - - //============================================================================== - /** The user-defined callback routine that actually gets called by each of the - timers that are running. - - It's perfectly ok to call startTimer() or stopTimer() from within this - callback to change the subsequent intervals. - */ - virtual void timerCallback (int timerID) = 0; - - //============================================================================== - /** Starts a timer and sets the length of interval required. - - If the timer is already started, this will reset it, so the - time between calling this method and the next timer callback - will not be less than the interval length passed in. - - @param timerID a unique Id number that identifies the timer to - start. This is the id that will be passed back - to the timerCallback() method when this timer is - triggered - @param intervalInMilliseconds the interval to use (any values less than 1 will be - rounded up to 1) - */ - void startTimer (int timerID, int intervalInMilliseconds) noexcept; - - /** Stops a timer. - - If a timer has been started with the given ID number, it will be cancelled. - No more callbacks will be made for the specified timer after this method returns. - - If this is called from a different thread, any callbacks that may - be currently executing may be allowed to finish before the method - returns. - */ - void stopTimer (int timerID) noexcept; - - //============================================================================== - /** Checks whether a timer has been started for a specified ID. - @returns true if a timer with the given ID is running. - */ - bool isTimerRunning (int timerID) const noexcept; - - /** Returns the interval for a specified timer ID. - @returns the timer's interval in milliseconds if it's running, or 0 if no - timer was running for the ID number specified. - */ - int getTimerInterval (int timerID) const noexcept; - - - //============================================================================== -private: - SpinLock timerListLock; - OwnedArray timers; - - Timer* getCallback (int) const noexcept; - MultiTimer& operator= (const MultiTimer&); -}; - -#endif // JUCE_MULTITIMER_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/timers/juce_Timer.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/timers/juce_Timer.cpp deleted file mode 100644 index 6b7343a559..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/timers/juce_Timer.cpp +++ /dev/null @@ -1,350 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -class Timer::TimerThread : private Thread, - private DeletedAtShutdown, - private AsyncUpdater -{ -public: - typedef CriticalSection LockType; // (mysteriously, using a SpinLock here causes problems on some XP machines..) - - TimerThread() - : Thread ("Juce Timer"), - firstTimer (nullptr), - callbackNeeded (0) - { - triggerAsyncUpdate(); - } - - ~TimerThread() noexcept - { - stopThread (4000); - - jassert (instance == this || instance == nullptr); - if (instance == this) - instance = nullptr; - } - - void run() override - { - uint32 lastTime = Time::getMillisecondCounter(); - MessageManager::MessageBase::Ptr messageToSend (new CallTimersMessage()); - - while (! threadShouldExit()) - { - const uint32 now = Time::getMillisecondCounter(); - - if (now == lastTime) - { - wait (1); - continue; - } - - const int elapsed = (int) (now >= lastTime ? (now - lastTime) - : (std::numeric_limits::max() - (lastTime - now))); - lastTime = now; - - const int timeUntilFirstTimer = getTimeUntilFirstTimer (elapsed); - - if (timeUntilFirstTimer <= 0) - { - /* If we managed to set the atomic boolean to true then send a message, this is needed - as a memory barrier so the message won't be sent before callbackNeeded is set to true, - but if it fails it means the message-thread changed the value from under us so at least - some processing is happenening and we can just loop around and try again - */ - if (callbackNeeded.compareAndSetBool (1, 0)) - { - messageToSend->post(); - - /* Sometimes our message can get discarded by the OS (e.g. when running as an RTAS - when the app has a modal loop), so this is how long to wait before assuming the - message has been lost and trying again. - */ - const uint32 messageDeliveryTimeout = now + 300; - - while (callbackNeeded.get() != 0) - { - wait (4); - - if (threadShouldExit()) - return; - - if (Time::getMillisecondCounter() > messageDeliveryTimeout) - { - messageToSend->post(); - break; - } - } - } - } - else - { - // don't wait for too long because running this loop also helps keep the - // Time::getApproximateMillisecondTimer value stay up-to-date - wait (jlimit (1, 50, timeUntilFirstTimer)); - } - } - } - - void callTimers() - { - const LockType::ScopedLockType sl (lock); - - while (firstTimer != nullptr && firstTimer->countdownMs <= 0) - { - Timer* const t = firstTimer; - t->countdownMs = t->periodMs; - - removeTimer (t); - addTimer (t); - - const LockType::ScopedUnlockType ul (lock); - - JUCE_TRY - { - t->timerCallback(); - } - JUCE_CATCH_EXCEPTION - } - - /* This is needed as a memory barrier to make sure all processing of current timers is done - before the boolean is set. This set should never fail since if it was false in the first place, - we wouldn't get a message (so it can't be changed from false to true from under us), and if we - get a message then the value is true and the other thread can only set it to true again and - we will get another callback to set it to false. - */ - callbackNeeded.set (0); - } - - void callTimersSynchronously() - { - if (! isThreadRunning()) - { - // (This is relied on by some plugins in cases where the MM has - // had to restart and the async callback never started) - cancelPendingUpdate(); - triggerAsyncUpdate(); - } - - callTimers(); - } - - static inline void add (Timer* const tim) noexcept - { - if (instance == nullptr) - instance = new TimerThread(); - - instance->addTimer (tim); - } - - static inline void remove (Timer* const tim) noexcept - { - if (instance != nullptr) - instance->removeTimer (tim); - } - - static inline void resetCounter (Timer* const tim, const int newCounter) noexcept - { - if (instance != nullptr) - { - tim->countdownMs = newCounter; - tim->periodMs = newCounter; - - if ((tim->next != nullptr && tim->next->countdownMs < tim->countdownMs) - || (tim->previous != nullptr && tim->previous->countdownMs > tim->countdownMs)) - { - instance->removeTimer (tim); - instance->addTimer (tim); - } - } - } - - static TimerThread* instance; - static LockType lock; - -private: - Timer* volatile firstTimer; - Atomic callbackNeeded; - - struct CallTimersMessage : public MessageManager::MessageBase - { - CallTimersMessage() {} - - void messageCallback() override - { - if (instance != nullptr) - instance->callTimers(); - } - }; - - //============================================================================== - void addTimer (Timer* const t) noexcept - { - #if JUCE_DEBUG - // trying to add a timer that's already here - shouldn't get to this point, - // so if you get this assertion, let me know! - jassert (! timerExists (t)); - #endif - - Timer* i = firstTimer; - - if (i == nullptr || i->countdownMs > t->countdownMs) - { - t->next = firstTimer; - firstTimer = t; - } - else - { - while (i->next != nullptr && i->next->countdownMs <= t->countdownMs) - i = i->next; - - jassert (i != nullptr); - - t->next = i->next; - t->previous = i; - i->next = t; - } - - if (t->next != nullptr) - t->next->previous = t; - - jassert ((t->next == nullptr || t->next->countdownMs >= t->countdownMs) - && (t->previous == nullptr || t->previous->countdownMs <= t->countdownMs)); - - notify(); - } - - void removeTimer (Timer* const t) noexcept - { - #if JUCE_DEBUG - // trying to remove a timer that's not here - shouldn't get to this point, - // so if you get this assertion, let me know! - jassert (timerExists (t)); - #endif - - if (t->previous != nullptr) - { - jassert (firstTimer != t); - t->previous->next = t->next; - } - else - { - jassert (firstTimer == t); - firstTimer = t->next; - } - - if (t->next != nullptr) - t->next->previous = t->previous; - - t->next = nullptr; - t->previous = nullptr; - } - - int getTimeUntilFirstTimer (const int numMillisecsElapsed) const - { - const LockType::ScopedLockType sl (lock); - - for (Timer* t = firstTimer; t != nullptr; t = t->next) - t->countdownMs -= numMillisecsElapsed; - - return firstTimer != nullptr ? firstTimer->countdownMs : 1000; - } - - void handleAsyncUpdate() override - { - startThread (7); - } - - #if JUCE_DEBUG - bool timerExists (Timer* const t) const noexcept - { - for (Timer* tt = firstTimer; tt != nullptr; tt = tt->next) - if (tt == t) - return true; - - return false; - } - #endif - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (TimerThread) -}; - -Timer::TimerThread* Timer::TimerThread::instance = nullptr; -Timer::TimerThread::LockType Timer::TimerThread::lock; - -//============================================================================== -Timer::Timer() noexcept - : countdownMs (0), - periodMs (0), - previous (nullptr), - next (nullptr) -{ -} - -Timer::Timer (const Timer&) noexcept - : countdownMs (0), - periodMs (0), - previous (nullptr), - next (nullptr) -{ -} - -Timer::~Timer() -{ - stopTimer(); -} - -void Timer::startTimer (const int interval) noexcept -{ - const TimerThread::LockType::ScopedLockType sl (TimerThread::lock); - - if (periodMs == 0) - { - countdownMs = interval; - periodMs = jmax (1, interval); - TimerThread::add (this); - } - else - { - TimerThread::resetCounter (this, interval); - } -} - -void Timer::stopTimer() noexcept -{ - const TimerThread::LockType::ScopedLockType sl (TimerThread::lock); - - if (periodMs > 0) - { - TimerThread::remove (this); - periodMs = 0; - } -} - -void JUCE_CALLTYPE Timer::callPendingTimersSynchronously() -{ - if (TimerThread::instance != nullptr) - TimerThread::instance->callTimersSynchronously(); -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/timers/juce_Timer.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/timers/juce_Timer.h deleted file mode 100644 index a2f823af24..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_events/timers/juce_Timer.h +++ /dev/null @@ -1,134 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_TIMER_H_INCLUDED -#define JUCE_TIMER_H_INCLUDED - - -//============================================================================== -/** - Makes repeated callbacks to a virtual method at a specified time interval. - - A Timer's timerCallback() method will be repeatedly called at a given - interval. When you create a Timer object, it will do nothing until the - startTimer() method is called, which will cause the message thread to - start making callbacks at the specified interval, until stopTimer() is called - or the object is deleted. - - The time interval isn't guaranteed to be precise to any more than maybe - 10-20ms, and the intervals may end up being much longer than requested if the - system is busy. Because the callbacks are made by the main message thread, - anything that blocks the message queue for a period of time will also prevent - any timers from running until it can carry on. - - If you need to have a single callback that is shared by multiple timers with - different frequencies, then the MultiTimer class allows you to do that - its - structure is very similar to the Timer class, but contains multiple timers - internally, each one identified by an ID number. - - @see HighResolutionTimer, MultiTimer -*/ -class JUCE_API Timer -{ -protected: - //============================================================================== - /** Creates a Timer. - - When created, the timer is stopped, so use startTimer() to get it going. - */ - Timer() noexcept; - - /** Creates a copy of another timer. - - Note that this timer won't be started, even if the one you're copying - is running. - */ - Timer (const Timer& other) noexcept; - -public: - //============================================================================== - /** Destructor. */ - virtual ~Timer(); - - //============================================================================== - /** The user-defined callback routine that actually gets called periodically. - - It's perfectly ok to call startTimer() or stopTimer() from within this - callback to change the subsequent intervals. - */ - virtual void timerCallback() = 0; - - //============================================================================== - /** Starts the timer and sets the length of interval required. - - If the timer is already started, this will reset it, so the - time between calling this method and the next timer callback - will not be less than the interval length passed in. - - @param intervalInMilliseconds the interval to use (any values less than 1 will be - rounded up to 1) - */ - void startTimer (int intervalInMilliseconds) noexcept; - - /** Stops the timer. - - No more callbacks will be made after this method returns. - - If this is called from a different thread, any callbacks that may - be currently executing may be allowed to finish before the method - returns. - */ - void stopTimer() noexcept; - - //============================================================================== - /** Checks if the timer has been started. - - @returns true if the timer is running. - */ - bool isTimerRunning() const noexcept { return periodMs > 0; } - - /** Returns the timer's interval. - - @returns the timer's interval in milliseconds if it's running, or 0 if it's not. - */ - int getTimerInterval() const noexcept { return periodMs; } - - - //============================================================================== - /** For internal use only: invokes any timers that need callbacks. - Don't call this unless you really know what you're doing! - */ - static void JUCE_CALLTYPE callPendingTimersSynchronously(); - -private: - class TimerThread; - friend class TimerThread; - int countdownMs, periodMs; - Timer* previous; - Timer* next; - - Timer& operator= (const Timer&); -}; - -#endif // JUCE_TIMER_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/colour/juce_Colour.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/colour/juce_Colour.cpp deleted file mode 100644 index aaf9468651..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/colour/juce_Colour.cpp +++ /dev/null @@ -1,444 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -namespace ColourHelpers -{ - static uint8 floatToUInt8 (const float n) noexcept - { - return n <= 0.0f ? 0 : (n >= 1.0f ? 255 : static_cast (n * 255.996f)); - } - - //============================================================================== - struct HSB - { - HSB (Colour col) noexcept - { - const int r = col.getRed(); - const int g = col.getGreen(); - const int b = col.getBlue(); - - const int hi = jmax (r, g, b); - const int lo = jmin (r, g, b); - - if (hi != 0) - { - saturation = (hi - lo) / (float) hi; - - if (saturation > 0) - { - const float invDiff = 1.0f / (hi - lo); - - const float red = (hi - r) * invDiff; - const float green = (hi - g) * invDiff; - const float blue = (hi - b) * invDiff; - - if (r == hi) - hue = blue - green; - else if (g == hi) - hue = 2.0f + red - blue; - else - hue = 4.0f + green - red; - - hue *= 1.0f / 6.0f; - - if (hue < 0) - ++hue; - } - else - { - hue = 0; - } - } - else - { - saturation = hue = 0; - } - - brightness = hi / 255.0f; - } - - Colour toColour (Colour original) const noexcept - { - return Colour (hue, saturation, brightness, original.getAlpha()); - } - - static PixelARGB toRGB (float h, float s, float v, const uint8 alpha) noexcept - { - v = jlimit (0.0f, 255.0f, v * 255.0f); - const uint8 intV = (uint8) roundToInt (v); - - if (s <= 0) - return PixelARGB (alpha, intV, intV, intV); - - s = jmin (1.0f, s); - h = (h - std::floor (h)) * 6.0f + 0.00001f; // need a small adjustment to compensate for rounding errors - const float f = h - std::floor (h); - const uint8 x = (uint8) roundToInt (v * (1.0f - s)); - - if (h < 1.0f) return PixelARGB (alpha, intV, (uint8) roundToInt (v * (1.0f - (s * (1.0f - f)))), x); - if (h < 2.0f) return PixelARGB (alpha, (uint8) roundToInt (v * (1.0f - s * f)), intV, x); - if (h < 3.0f) return PixelARGB (alpha, x, intV, (uint8) roundToInt (v * (1.0f - (s * (1.0f - f))))); - if (h < 4.0f) return PixelARGB (alpha, x, (uint8) roundToInt (v * (1.0f - s * f)), intV); - if (h < 5.0f) return PixelARGB (alpha, (uint8) roundToInt (v * (1.0f - (s * (1.0f - f)))), x, intV); - return PixelARGB (alpha, intV, x, (uint8) roundToInt (v * (1.0f - s * f))); - } - - float hue, saturation, brightness; - }; - - //============================================================================== - struct YIQ - { - YIQ (Colour c) noexcept - { - const float r = c.getFloatRed(); - const float g = c.getFloatGreen(); - const float b = c.getFloatBlue(); - - y = 0.2999f * r + 0.5870f * g + 0.1140f * b; - i = 0.5957f * r - 0.2744f * g - 0.3212f * b; - q = 0.2114f * r - 0.5225f * g - 0.3113f * b; - alpha = c.getFloatAlpha(); - } - - Colour toColour() const noexcept - { - return Colour::fromFloatRGBA (y + 0.9563f * i + 0.6210f * q, - y - 0.2721f * i - 0.6474f * q, - y - 1.1070f * i + 1.7046f * q, - alpha); - } - - float y, i, q, alpha; - }; -} - -//============================================================================== -Colour::Colour() noexcept - : argb (0) -{ -} - -Colour::Colour (const Colour& other) noexcept - : argb (other.argb) -{ -} - -Colour& Colour::operator= (const Colour& other) noexcept -{ - argb = other.argb; - return *this; -} - -bool Colour::operator== (const Colour& other) const noexcept { return argb.getARGB() == other.argb.getARGB(); } -bool Colour::operator!= (const Colour& other) const noexcept { return argb.getARGB() != other.argb.getARGB(); } - -//============================================================================== -Colour::Colour (const uint32 col) noexcept : argb (col) -{ -} - -Colour::Colour (const uint8 red, const uint8 green, const uint8 blue) noexcept -{ - argb.setARGB (0xff, red, green, blue); -} - -Colour Colour::fromRGB (const uint8 red, const uint8 green, const uint8 blue) noexcept -{ - return Colour (red, green, blue); -} - -Colour::Colour (const uint8 red, const uint8 green, const uint8 blue, const uint8 alpha) noexcept -{ - argb.setARGB (alpha, red, green, blue); -} - -Colour Colour::fromRGBA (const uint8 red, const uint8 green, const uint8 blue, const uint8 alpha) noexcept -{ - return Colour (red, green, blue, alpha); -} - -Colour::Colour (const uint8 red, const uint8 green, const uint8 blue, const float alpha) noexcept -{ - argb.setARGB (ColourHelpers::floatToUInt8 (alpha), red, green, blue); -} - -Colour Colour::fromFloatRGBA (const float red, const float green, const float blue, const float alpha) noexcept -{ - return Colour (ColourHelpers::floatToUInt8 (red), - ColourHelpers::floatToUInt8 (green), - ColourHelpers::floatToUInt8 (blue), alpha); -} - -Colour::Colour (const float hue, const float saturation, const float brightness, const float alpha) noexcept - : argb (ColourHelpers::HSB::toRGB (hue, saturation, brightness, ColourHelpers::floatToUInt8 (alpha))) -{ -} - -Colour Colour::fromHSV (const float hue, const float saturation, const float brightness, const float alpha) noexcept -{ - return Colour (hue, saturation, brightness, alpha); -} - -Colour::Colour (const float hue, const float saturation, const float brightness, const uint8 alpha) noexcept - : argb (ColourHelpers::HSB::toRGB (hue, saturation, brightness, alpha)) -{ -} - -Colour::~Colour() noexcept -{ -} - -//============================================================================== -const PixelARGB Colour::getPixelARGB() const noexcept -{ - PixelARGB p (argb); - p.premultiply(); - return p; -} - -uint32 Colour::getARGB() const noexcept -{ - return argb.getARGB(); -} - -//============================================================================== -bool Colour::isTransparent() const noexcept -{ - return getAlpha() == 0; -} - -bool Colour::isOpaque() const noexcept -{ - return getAlpha() == 0xff; -} - -Colour Colour::withAlpha (const uint8 newAlpha) const noexcept -{ - PixelARGB newCol (argb); - newCol.setAlpha (newAlpha); - return Colour (newCol.getARGB()); -} - -Colour Colour::withAlpha (const float newAlpha) const noexcept -{ - jassert (newAlpha >= 0 && newAlpha <= 1.0f); - - PixelARGB newCol (argb); - newCol.setAlpha (ColourHelpers::floatToUInt8 (newAlpha)); - return Colour (newCol.getARGB()); -} - -Colour Colour::withMultipliedAlpha (const float alphaMultiplier) const noexcept -{ - jassert (alphaMultiplier >= 0); - - PixelARGB newCol (argb); - newCol.setAlpha ((uint8) jmin (0xff, roundToInt (alphaMultiplier * newCol.getAlpha()))); - return Colour (newCol.getARGB()); -} - -//============================================================================== -Colour Colour::overlaidWith (Colour src) const noexcept -{ - const int destAlpha = getAlpha(); - - if (destAlpha <= 0) - return src; - - const int invA = 0xff - (int) src.getAlpha(); - const int resA = 0xff - (((0xff - destAlpha) * invA) >> 8); - - if (resA <= 0) - return *this; - - const int da = (invA * destAlpha) / resA; - - return Colour ((uint8) (src.getRed() + ((((int) getRed() - src.getRed()) * da) >> 8)), - (uint8) (src.getGreen() + ((((int) getGreen() - src.getGreen()) * da) >> 8)), - (uint8) (src.getBlue() + ((((int) getBlue() - src.getBlue()) * da) >> 8)), - (uint8) resA); -} - -Colour Colour::interpolatedWith (Colour other, float proportionOfOther) const noexcept -{ - if (proportionOfOther <= 0) - return *this; - - if (proportionOfOther >= 1.0f) - return other; - - PixelARGB c1 (getPixelARGB()); - const PixelARGB c2 (other.getPixelARGB()); - c1.tween (c2, (uint32) roundToInt (proportionOfOther * 255.0f)); - c1.unpremultiply(); - - return Colour (c1.getARGB()); -} - -//============================================================================== -float Colour::getFloatRed() const noexcept { return getRed() / 255.0f; } -float Colour::getFloatGreen() const noexcept { return getGreen() / 255.0f; } -float Colour::getFloatBlue() const noexcept { return getBlue() / 255.0f; } -float Colour::getFloatAlpha() const noexcept { return getAlpha() / 255.0f; } - -//============================================================================== -void Colour::getHSB (float& h, float& s, float& v) const noexcept -{ - const ColourHelpers::HSB hsb (*this); - h = hsb.hue; - s = hsb.saturation; - v = hsb.brightness; -} - -float Colour::getHue() const noexcept { return ColourHelpers::HSB (*this).hue; } -float Colour::getSaturation() const noexcept { return ColourHelpers::HSB (*this).saturation; } -float Colour::getBrightness() const noexcept { return ColourHelpers::HSB (*this).brightness; } - -Colour Colour::withHue (float h) const noexcept { ColourHelpers::HSB hsb (*this); hsb.hue = h; return hsb.toColour (*this); } -Colour Colour::withSaturation (float s) const noexcept { ColourHelpers::HSB hsb (*this); hsb.saturation = s; return hsb.toColour (*this); } -Colour Colour::withBrightness (float v) const noexcept { ColourHelpers::HSB hsb (*this); hsb.brightness = v; return hsb.toColour (*this); } - -float Colour::getPerceivedBrightness() const noexcept -{ - return std::sqrt (0.241f * square (getFloatRed()) - + 0.691f * square (getFloatGreen()) - + 0.068f * square (getFloatBlue())); -} - -//============================================================================== -Colour Colour::withRotatedHue (const float amountToRotate) const noexcept -{ - ColourHelpers::HSB hsb (*this); - hsb.hue += amountToRotate; - return hsb.toColour (*this); -} - -Colour Colour::withMultipliedSaturation (const float amount) const noexcept -{ - ColourHelpers::HSB hsb (*this); - hsb.saturation = jmin (1.0f, hsb.saturation * amount); - return hsb.toColour (*this); -} - -Colour Colour::withMultipliedBrightness (const float amount) const noexcept -{ - ColourHelpers::HSB hsb (*this); - hsb.brightness = jmin (1.0f, hsb.brightness * amount); - return hsb.toColour (*this); -} - -//============================================================================== -Colour Colour::brighter (float amount) const noexcept -{ - amount = 1.0f / (1.0f + amount); - - return Colour ((uint8) (255 - (amount * (255 - getRed()))), - (uint8) (255 - (amount * (255 - getGreen()))), - (uint8) (255 - (amount * (255 - getBlue()))), - getAlpha()); -} - -Colour Colour::darker (float amount) const noexcept -{ - amount = 1.0f / (1.0f + amount); - - return Colour ((uint8) (amount * getRed()), - (uint8) (amount * getGreen()), - (uint8) (amount * getBlue()), - getAlpha()); -} - -//============================================================================== -Colour Colour::greyLevel (const float brightness) noexcept -{ - const uint8 level = ColourHelpers::floatToUInt8 (brightness); - return Colour (level, level, level); -} - -//============================================================================== -Colour Colour::contrasting (const float amount) const noexcept -{ - return overlaidWith ((getPerceivedBrightness() >= 0.5f - ? Colours::black - : Colours::white).withAlpha (amount)); -} - -Colour Colour::contrasting (Colour target, float minContrast) const noexcept -{ - const ColourHelpers::YIQ bg (*this); - ColourHelpers::YIQ fg (target); - - if (std::abs (bg.y - fg.y) >= minContrast) - return target; - - const float y1 = jmax (0.0f, bg.y - minContrast); - const float y2 = jmin (1.0f, bg.y + minContrast); - fg.y = (std::abs (y1 - bg.y) > std::abs (y2 - bg.y)) ? y1 : y2; - - return fg.toColour(); -} - -Colour Colour::contrasting (Colour colour1, - Colour colour2) noexcept -{ - const float b1 = colour1.getPerceivedBrightness(); - const float b2 = colour2.getPerceivedBrightness(); - float best = 0.0f; - float bestDist = 0.0f; - - for (float i = 0.0f; i < 1.0f; i += 0.02f) - { - const float d1 = std::abs (i - b1); - const float d2 = std::abs (i - b2); - const float dist = jmin (d1, d2, 1.0f - d1, 1.0f - d2); - - if (dist > bestDist) - { - best = i; - bestDist = dist; - } - } - - return colour1.overlaidWith (colour2.withMultipliedAlpha (0.5f)) - .withBrightness (best); -} - -//============================================================================== -String Colour::toString() const -{ - return String::toHexString ((int) argb.getARGB()); -} - -Colour Colour::fromString (StringRef encodedColourString) -{ - return Colour ((uint32) CharacterFunctions::HexParser::parse (encodedColourString.text)); -} - -String Colour::toDisplayString (const bool includeAlphaValue) const -{ - return String::toHexString ((int) (argb.getARGB() & (includeAlphaValue ? 0xffffffff : 0xffffff))) - .paddedLeft ('0', includeAlphaValue ? 8 : 6) - .toUpperCase(); -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/colour/juce_Colour.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/colour/juce_Colour.h deleted file mode 100644 index 4d845048f2..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/colour/juce_Colour.h +++ /dev/null @@ -1,360 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_COLOUR_H_INCLUDED -#define JUCE_COLOUR_H_INCLUDED - - -//============================================================================== -/** - Represents a colour, also including a transparency value. - - The colour is stored internally as unsigned 8-bit red, green, blue and alpha values. -*/ -class JUCE_API Colour -{ -public: - //============================================================================== - /** Creates a transparent black colour. */ - Colour() noexcept; - - /** Creates a copy of another Colour object. */ - Colour (const Colour& other) noexcept; - - /** Creates a colour from a 32-bit ARGB value. - - The format of this number is: - ((alpha << 24) | (red << 16) | (green << 8) | blue). - - All components in the range 0x00 to 0xff. - An alpha of 0x00 is completely transparent, alpha of 0xff is opaque. - - @see getPixelARGB - */ - explicit Colour (uint32 argb) noexcept; - - /** Creates an opaque colour using 8-bit red, green and blue values */ - Colour (uint8 red, - uint8 green, - uint8 blue) noexcept; - - /** Creates an opaque colour using 8-bit red, green and blue values */ - static Colour fromRGB (uint8 red, - uint8 green, - uint8 blue) noexcept; - - /** Creates a colour using 8-bit red, green, blue and alpha values. */ - Colour (uint8 red, - uint8 green, - uint8 blue, - uint8 alpha) noexcept; - - /** Creates a colour using 8-bit red, green, blue and alpha values. */ - static Colour fromRGBA (uint8 red, - uint8 green, - uint8 blue, - uint8 alpha) noexcept; - - /** Creates a colour from 8-bit red, green, and blue values, and a floating-point alpha. - - Alpha of 0.0 is transparent, alpha of 1.0f is opaque. - Values outside the valid range will be clipped. - */ - Colour (uint8 red, - uint8 green, - uint8 blue, - float alpha) noexcept; - - /** Creates a colour using floating point red, green, blue and alpha values. - Numbers outside the range 0..1 will be clipped. - */ - static Colour fromFloatRGBA (float red, - float green, - float blue, - float alpha) noexcept; - - /** Creates a colour using floating point hue, saturation and brightness values, and an 8-bit alpha. - - The floating point values must be between 0.0 and 1.0. - An alpha of 0x00 is completely transparent, alpha of 0xff is opaque. - Values outside the valid range will be clipped. - */ - Colour (float hue, - float saturation, - float brightness, - uint8 alpha) noexcept; - - /** Creates a colour using floating point hue, saturation, brightness and alpha values. - - All values must be between 0.0 and 1.0. - Numbers outside the valid range will be clipped. - */ - Colour (float hue, - float saturation, - float brightness, - float alpha) noexcept; - - /** Creates a colour using floating point hue, saturation and brightness values, and an 8-bit alpha. - - The floating point values must be between 0.0 and 1.0. - An alpha of 0x00 is completely transparent, alpha of 0xff is opaque. - Values outside the valid range will be clipped. - */ - static Colour fromHSV (float hue, - float saturation, - float brightness, - float alpha) noexcept; - - /** Destructor. */ - ~Colour() noexcept; - - /** Copies another Colour object. */ - Colour& operator= (const Colour& other) noexcept; - - /** Compares two colours. */ - bool operator== (const Colour& other) const noexcept; - /** Compares two colours. */ - bool operator!= (const Colour& other) const noexcept; - - //============================================================================== - /** Returns the red component of this colour. - @returns a value between 0x00 and 0xff. - */ - uint8 getRed() const noexcept { return argb.getRed(); } - - /** Returns the green component of this colour. - @returns a value between 0x00 and 0xff. - */ - uint8 getGreen() const noexcept { return argb.getGreen(); } - - /** Returns the blue component of this colour. - @returns a value between 0x00 and 0xff. - */ - uint8 getBlue() const noexcept { return argb.getBlue(); } - - /** Returns the red component of this colour as a floating point value. - @returns a value between 0.0 and 1.0 - */ - float getFloatRed() const noexcept; - - /** Returns the green component of this colour as a floating point value. - @returns a value between 0.0 and 1.0 - */ - float getFloatGreen() const noexcept; - - /** Returns the blue component of this colour as a floating point value. - @returns a value between 0.0 and 1.0 - */ - float getFloatBlue() const noexcept; - - /** Returns a premultiplied ARGB pixel object that represents this colour. - */ - const PixelARGB getPixelARGB() const noexcept; - - /** Returns a 32-bit integer that represents this colour. - - The format of this number is: - ((alpha << 24) | (red << 16) | (green << 16) | blue). - */ - uint32 getARGB() const noexcept; - - //============================================================================== - /** Returns the colour's alpha (opacity). - - Alpha of 0x00 is completely transparent, 0xff is completely opaque. - */ - uint8 getAlpha() const noexcept { return argb.getAlpha(); } - - /** Returns the colour's alpha (opacity) as a floating point value. - - Alpha of 0.0 is completely transparent, 1.0 is completely opaque. - */ - float getFloatAlpha() const noexcept; - - /** Returns true if this colour is completely opaque. - - Equivalent to (getAlpha() == 0xff). - */ - bool isOpaque() const noexcept; - - /** Returns true if this colour is completely transparent. - - Equivalent to (getAlpha() == 0x00). - */ - bool isTransparent() const noexcept; - - /** Returns a colour that's the same colour as this one, but with a new alpha value. */ - Colour withAlpha (uint8 newAlpha) const noexcept; - - /** Returns a colour that's the same colour as this one, but with a new alpha value. */ - Colour withAlpha (float newAlpha) const noexcept; - - /** Returns a colour that's the same colour as this one, but with a modified alpha value. - The new colour's alpha will be this object's alpha multiplied by the value passed-in. - */ - Colour withMultipliedAlpha (float alphaMultiplier) const noexcept; - - //============================================================================== - /** Returns a colour that is the result of alpha-compositing a new colour over this one. - If the foreground colour is semi-transparent, it is blended onto this colour accordingly. - */ - Colour overlaidWith (Colour foregroundColour) const noexcept; - - /** Returns a colour that lies somewhere between this one and another. - If amountOfOther is zero, the result is 100% this colour, if amountOfOther - is 1.0, the result is 100% of the other colour. - */ - Colour interpolatedWith (Colour other, float proportionOfOther) const noexcept; - - //============================================================================== - /** Returns the colour's hue component. - The value returned is in the range 0.0 to 1.0 - */ - float getHue() const noexcept; - - /** Returns the colour's saturation component. - The value returned is in the range 0.0 to 1.0 - */ - float getSaturation() const noexcept; - - /** Returns the colour's brightness component. - The value returned is in the range 0.0 to 1.0 - */ - float getBrightness() const noexcept; - - /** Returns a skewed brightness value, adjusted to better reflect the way the human - eye responds to different colour channels. This makes it better than getBrightness() - for comparing differences in brightness. - */ - float getPerceivedBrightness() const noexcept; - - /** Returns the colour's hue, saturation and brightness components all at once. - The values returned are in the range 0.0 to 1.0 - */ - void getHSB (float& hue, - float& saturation, - float& brightness) const noexcept; - - //============================================================================== - /** Returns a copy of this colour with a different hue. */ - Colour withHue (float newHue) const noexcept; - - /** Returns a copy of this colour with a different saturation. */ - Colour withSaturation (float newSaturation) const noexcept; - - /** Returns a copy of this colour with a different brightness. - @see brighter, darker, withMultipliedBrightness - */ - Colour withBrightness (float newBrightness) const noexcept; - - /** Returns a copy of this colour with it hue rotated. - - The new colour's hue is ((this->getHue() + amountToRotate) % 1.0) - - @see brighter, darker, withMultipliedBrightness - */ - Colour withRotatedHue (float amountToRotate) const noexcept; - - /** Returns a copy of this colour with its saturation multiplied by the given value. - - The new colour's saturation is (this->getSaturation() * multiplier) - (the result is clipped to legal limits). - */ - Colour withMultipliedSaturation (float multiplier) const noexcept; - - /** Returns a copy of this colour with its brightness multiplied by the given value. - - The new colour's saturation is (this->getBrightness() * multiplier) - (the result is clipped to legal limits). - */ - Colour withMultipliedBrightness (float amount) const noexcept; - - //============================================================================== - /** Returns a brighter version of this colour. - - @param amountBrighter how much brighter to make it - a value from 0 to 1.0 where 0 is - unchanged, and higher values make it brighter - @see withMultipliedBrightness - */ - Colour brighter (float amountBrighter = 0.4f) const noexcept; - - /** Returns a darker version of this colour. - - @param amountDarker how much darker to make it - a value from 0 to 1.0 where 0 is - unchanged, and higher values make it darker - @see withMultipliedBrightness - */ - Colour darker (float amountDarker = 0.4f) const noexcept; - - //============================================================================== - /** Returns a colour that will be clearly visible against this colour. - - The amount parameter indicates how contrasting the new colour should - be, so e.g. Colours::black.contrasting (0.1f) will return a colour - that's just a little bit lighter; Colours::black.contrasting (1.0f) will - return white; Colours::white.contrasting (1.0f) will return black, etc. - */ - Colour contrasting (float amount = 1.0f) const noexcept; - - /** Returns a colour that is as close as possible to a target colour whilst - still being in contrast to this one. - - The colour that is returned will be the targetColour, but with its luminosity - nudged up or down so that it differs from the luminosity of this colour - by at least the amount specified by minLuminosityDiff. - */ - Colour contrasting (Colour targetColour, float minLuminosityDiff) const noexcept; - - /** Returns a colour that contrasts against two colours. - Looks for a colour that contrasts with both of the colours passed-in. - Handy for things like choosing a highlight colour in text editors, etc. - */ - static Colour contrasting (Colour colour1, - Colour colour2) noexcept; - - //============================================================================== - /** Returns an opaque shade of grey. - @param brightness the level of grey to return - 0 is black, 1.0 is white - */ - static Colour greyLevel (float brightness) noexcept; - - //============================================================================== - /** Returns a stringified version of this colour. - The string can be turned back into a colour using the fromString() method. - */ - String toString() const; - - /** Reads the colour from a string that was created with toString(). */ - static Colour fromString (StringRef encodedColourString); - - /** Returns the colour as a hex string in the form RRGGBB or AARRGGBB. */ - String toDisplayString (bool includeAlphaValue) const; - -private: - //============================================================================== - PixelARGB argb; -}; - - -#endif // JUCE_COLOUR_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/colour/juce_ColourGradient.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/colour/juce_ColourGradient.cpp deleted file mode 100644 index 75d1712958..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/colour/juce_ColourGradient.cpp +++ /dev/null @@ -1,220 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -ColourGradient::ColourGradient() noexcept -{ - #if JUCE_DEBUG - point1.setX (987654.0f); - #define JUCE_COLOURGRADIENT_CHECK_COORDS_INITIALISED jassert (point1.x != 987654.0f); - #else - #define JUCE_COLOURGRADIENT_CHECK_COORDS_INITIALISED - #endif -} - -ColourGradient::ColourGradient (Colour colour1, const float x1_, const float y1_, - Colour colour2, const float x2_, const float y2_, - const bool isRadial_) - : point1 (x1_, y1_), - point2 (x2_, y2_), - isRadial (isRadial_) -{ - colours.add (ColourPoint (0.0, colour1)); - colours.add (ColourPoint (1.0, colour2)); -} - -ColourGradient::~ColourGradient() -{ -} - -bool ColourGradient::operator== (const ColourGradient& other) const noexcept -{ - return point1 == other.point1 && point2 == other.point2 - && isRadial == other.isRadial - && colours == other.colours; -} - -bool ColourGradient::operator!= (const ColourGradient& other) const noexcept -{ - return ! operator== (other); -} - -//============================================================================== -void ColourGradient::clearColours() -{ - colours.clear(); -} - -int ColourGradient::addColour (const double proportionAlongGradient, Colour colour) -{ - // must be within the two end-points - jassert (proportionAlongGradient >= 0 && proportionAlongGradient <= 1.0); - - const double pos = jlimit (0.0, 1.0, proportionAlongGradient); - - int i; - for (i = 0; i < colours.size(); ++i) - if (colours.getReference(i).position > pos) - break; - - colours.insert (i, ColourPoint (pos, colour)); - return i; -} - -void ColourGradient::removeColour (int index) -{ - jassert (index > 0 && index < colours.size() - 1); - colours.remove (index); -} - -void ColourGradient::multiplyOpacity (const float multiplier) noexcept -{ - for (int i = 0; i < colours.size(); ++i) - { - Colour& c = colours.getReference(i).colour; - c = c.withMultipliedAlpha (multiplier); - } -} - -//============================================================================== -int ColourGradient::getNumColours() const noexcept -{ - return colours.size(); -} - -double ColourGradient::getColourPosition (const int index) const noexcept -{ - if (isPositiveAndBelow (index, colours.size())) - return colours.getReference (index).position; - - return 0; - } - -Colour ColourGradient::getColour (const int index) const noexcept -{ - if (isPositiveAndBelow (index, colours.size())) - return colours.getReference (index).colour; - - return Colour(); -} - -void ColourGradient::setColour (int index, Colour newColour) noexcept -{ - if (isPositiveAndBelow (index, colours.size())) - colours.getReference (index).colour = newColour; -} - -Colour ColourGradient::getColourAtPosition (const double position) const noexcept -{ - jassert (colours.getReference(0).position == 0); // the first colour specified has to go at position 0 - - if (position <= 0 || colours.size() <= 1) - return colours.getReference(0).colour; - - int i = colours.size() - 1; - while (position < colours.getReference(i).position) - --i; - - const ColourPoint& p1 = colours.getReference (i); - - if (i >= colours.size() - 1) - return p1.colour; - - const ColourPoint& p2 = colours.getReference (i + 1); - - return p1.colour.interpolatedWith (p2.colour, (float) ((position - p1.position) / (p2.position - p1.position))); -} - -//============================================================================== -void ColourGradient::createLookupTable (PixelARGB* const lookupTable, const int numEntries) const noexcept -{ - JUCE_COLOURGRADIENT_CHECK_COORDS_INITIALISED // Trying to use this object without setting its coordinates? - jassert (colours.size() >= 2); - jassert (numEntries > 0); - jassert (colours.getReference(0).position == 0); // The first colour specified has to go at position 0 - - PixelARGB pix1 (colours.getReference (0).colour.getPixelARGB()); - int index = 0; - - for (int j = 1; j < colours.size(); ++j) - { - const ColourPoint& p = colours.getReference (j); - const int numToDo = roundToInt (p.position * (numEntries - 1)) - index; - const PixelARGB pix2 (p.colour.getPixelARGB()); - - for (int i = 0; i < numToDo; ++i) - { - jassert (index >= 0 && index < numEntries); - - lookupTable[index] = pix1; - lookupTable[index].tween (pix2, (uint32) ((i << 8) / numToDo)); - ++index; - } - - pix1 = pix2; - } - - while (index < numEntries) - lookupTable [index++] = pix1; -} - -int ColourGradient::createLookupTable (const AffineTransform& transform, HeapBlock & lookupTable) const -{ - JUCE_COLOURGRADIENT_CHECK_COORDS_INITIALISED // Trying to use this object without setting its coordinates? - jassert (colours.size() >= 2); - - const int numEntries = jlimit (1, jmax (1, (colours.size() - 1) << 8), - 3 * (int) point1.transformedBy (transform) - .getDistanceFrom (point2.transformedBy (transform))); - lookupTable.malloc ((size_t) numEntries); - createLookupTable (lookupTable, numEntries); - return numEntries; -} - -bool ColourGradient::isOpaque() const noexcept -{ - for (int i = 0; i < colours.size(); ++i) - if (! colours.getReference(i).colour.isOpaque()) - return false; - - return true; -} - -bool ColourGradient::isInvisible() const noexcept -{ - for (int i = 0; i < colours.size(); ++i) - if (! colours.getReference(i).colour.isTransparent()) - return false; - - return true; -} - -bool ColourGradient::ColourPoint::operator== (const ColourPoint& other) const noexcept -{ - return position == other.position && colour == other.colour; -} - -bool ColourGradient::ColourPoint::operator!= (const ColourPoint& other) const noexcept -{ - return position != other.position || colour != other.colour; -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/colour/juce_ColourGradient.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/colour/juce_ColourGradient.h deleted file mode 100644 index 73e6631ceb..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/colour/juce_ColourGradient.h +++ /dev/null @@ -1,181 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_COLOURGRADIENT_H_INCLUDED -#define JUCE_COLOURGRADIENT_H_INCLUDED - - -//============================================================================== -/** - Describes the layout and colours that should be used to paint a colour gradient. - - @see Graphics::setGradientFill -*/ -class JUCE_API ColourGradient -{ -public: - //============================================================================== - /** Creates a gradient object. - - (x1, y1) is the location to draw with colour1. Likewise (x2, y2) is where - colour2 should be. In between them there's a gradient. - - If isRadial is true, the colours form a circular gradient with (x1, y1) at - its centre. - - The alpha transparencies of the colours are used, so note that - if you blend from transparent to a solid colour, the RGB of the transparent - colour will become visible in parts of the gradient. e.g. blending - from Colour::transparentBlack to Colours::white will produce a - muddy grey colour midway, but Colour::transparentWhite to Colours::white - will be white all the way across. - - @see ColourGradient - */ - ColourGradient (Colour colour1, float x1, float y1, - Colour colour2, float x2, float y2, - bool isRadial); - - /** Creates an uninitialised gradient. - - If you use this constructor instead of the other one, be sure to set all the - object's public member variables before using it! - */ - ColourGradient() noexcept; - - /** Destructor */ - ~ColourGradient(); - - //============================================================================== - /** Removes any colours that have been added. - - This will also remove any start and end colours, so the gradient won't work. You'll - need to add more colours with addColour(). - */ - void clearColours(); - - /** Adds a colour at a point along the length of the gradient. - - This allows the gradient to go through a spectrum of colours, instead of just a - start and end colour. - - @param proportionAlongGradient a value between 0 and 1.0, which is the proportion - of the distance along the line between the two points - at which the colour should occur. - @param colour the colour that should be used at this point - @returns the index at which the new point was added - */ - int addColour (double proportionAlongGradient, - Colour colour); - - /** Removes one of the colours from the gradient. */ - void removeColour (int index); - - /** Multiplies the alpha value of all the colours by the given scale factor */ - void multiplyOpacity (float multiplier) noexcept; - - //============================================================================== - /** Returns the number of colour-stops that have been added. */ - int getNumColours() const noexcept; - - /** Returns the position along the length of the gradient of the colour with this index. - - The index is from 0 to getNumColours() - 1. The return value will be between 0.0 and 1.0 - */ - double getColourPosition (int index) const noexcept; - - /** Returns the colour that was added with a given index. - The index is from 0 to getNumColours() - 1. - */ - Colour getColour (int index) const noexcept; - - /** Changes the colour at a given index. - The index is from 0 to getNumColours() - 1. - */ - void setColour (int index, Colour newColour) noexcept; - - /** Returns the an interpolated colour at any position along the gradient. - @param position the position along the gradient, between 0 and 1 - */ - Colour getColourAtPosition (double position) const noexcept; - - //============================================================================== - /** Creates a set of interpolated premultiplied ARGB values. - This will resize the HeapBlock, fill it with the colours, and will return the number of - colours that it added. - When calling this, the ColourGradient must have at least 2 colour stops specified. - */ - int createLookupTable (const AffineTransform& transform, HeapBlock & resultLookupTable) const; - - /** Creates a set of interpolated premultiplied ARGB values. - This will fill an array of a user-specified size with the gradient, interpolating to fit. - The numEntries argument specifies the size of the array, and this size must be greater than zero. - When calling this, the ColourGradient must have at least 2 colour stops specified. - */ - void createLookupTable (PixelARGB* resultLookupTable, int numEntries) const noexcept; - - /** Returns true if all colours are opaque. */ - bool isOpaque() const noexcept; - - /** Returns true if all colours are completely transparent. */ - bool isInvisible() const noexcept; - - //============================================================================== - Point point1, point2; - - /** If true, the gradient should be filled circularly, centred around - point1, with point2 defining a point on the circumference. - - If false, the gradient is linear between the two points. - */ - bool isRadial; - - bool operator== (const ColourGradient&) const noexcept; - bool operator!= (const ColourGradient&) const noexcept; - - -private: - //============================================================================== - struct ColourPoint - { - ColourPoint() noexcept {} - - ColourPoint (const double pos, Colour col) noexcept - : position (pos), colour (col) - {} - - bool operator== (const ColourPoint&) const noexcept; - bool operator!= (const ColourPoint&) const noexcept; - - double position; - Colour colour; - }; - - Array colours; - - JUCE_LEAK_DETECTOR (ColourGradient) -}; - - -#endif // JUCE_COLOURGRADIENT_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/colour/juce_Colours.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/colour/juce_Colours.cpp deleted file mode 100644 index fbde0ba6e7..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/colour/juce_Colours.cpp +++ /dev/null @@ -1,320 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -const Colour Colours::transparentBlack (0); -const Colour Colours::transparentWhite (0x00ffffff); - -const Colour Colours::aliceblue (0xfff0f8ff); -const Colour Colours::antiquewhite (0xfffaebd7); -const Colour Colours::aqua (0xff00ffff); -const Colour Colours::aquamarine (0xff7fffd4); -const Colour Colours::azure (0xfff0ffff); -const Colour Colours::beige (0xfff5f5dc); -const Colour Colours::bisque (0xffffe4c4); -const Colour Colours::black (0xff000000); -const Colour Colours::blanchedalmond (0xffffebcd); -const Colour Colours::blue (0xff0000ff); -const Colour Colours::blueviolet (0xff8a2be2); -const Colour Colours::brown (0xffa52a2a); -const Colour Colours::burlywood (0xffdeb887); -const Colour Colours::cadetblue (0xff5f9ea0); -const Colour Colours::chartreuse (0xff7fff00); -const Colour Colours::chocolate (0xffd2691e); -const Colour Colours::coral (0xffff7f50); -const Colour Colours::cornflowerblue (0xff6495ed); -const Colour Colours::cornsilk (0xfffff8dc); -const Colour Colours::crimson (0xffdc143c); -const Colour Colours::cyan (0xff00ffff); -const Colour Colours::darkblue (0xff00008b); -const Colour Colours::darkcyan (0xff008b8b); -const Colour Colours::darkgoldenrod (0xffb8860b); -const Colour Colours::darkgrey (0xff555555); -const Colour Colours::darkgreen (0xff006400); -const Colour Colours::darkkhaki (0xffbdb76b); -const Colour Colours::darkmagenta (0xff8b008b); -const Colour Colours::darkolivegreen (0xff556b2f); -const Colour Colours::darkorange (0xffff8c00); -const Colour Colours::darkorchid (0xff9932cc); -const Colour Colours::darkred (0xff8b0000); -const Colour Colours::darksalmon (0xffe9967a); -const Colour Colours::darkseagreen (0xff8fbc8f); -const Colour Colours::darkslateblue (0xff483d8b); -const Colour Colours::darkslategrey (0xff2f4f4f); -const Colour Colours::darkturquoise (0xff00ced1); -const Colour Colours::darkviolet (0xff9400d3); -const Colour Colours::deeppink (0xffff1493); -const Colour Colours::deepskyblue (0xff00bfff); -const Colour Colours::dimgrey (0xff696969); -const Colour Colours::dodgerblue (0xff1e90ff); -const Colour Colours::firebrick (0xffb22222); -const Colour Colours::floralwhite (0xfffffaf0); -const Colour Colours::forestgreen (0xff228b22); -const Colour Colours::fuchsia (0xffff00ff); -const Colour Colours::gainsboro (0xffdcdcdc); -const Colour Colours::gold (0xffffd700); -const Colour Colours::goldenrod (0xffdaa520); -const Colour Colours::grey (0xff808080); -const Colour Colours::green (0xff008000); -const Colour Colours::greenyellow (0xffadff2f); -const Colour Colours::honeydew (0xfff0fff0); -const Colour Colours::hotpink (0xffff69b4); -const Colour Colours::indianred (0xffcd5c5c); -const Colour Colours::indigo (0xff4b0082); -const Colour Colours::ivory (0xfffffff0); -const Colour Colours::khaki (0xfff0e68c); -const Colour Colours::lavender (0xffe6e6fa); -const Colour Colours::lavenderblush (0xfffff0f5); -const Colour Colours::lemonchiffon (0xfffffacd); -const Colour Colours::lightblue (0xffadd8e6); -const Colour Colours::lightcoral (0xfff08080); -const Colour Colours::lightcyan (0xffe0ffff); -const Colour Colours::lightgoldenrodyellow (0xfffafad2); -const Colour Colours::lightgreen (0xff90ee90); -const Colour Colours::lightgrey (0xffd3d3d3); -const Colour Colours::lightpink (0xffffb6c1); -const Colour Colours::lightsalmon (0xffffa07a); -const Colour Colours::lightseagreen (0xff20b2aa); -const Colour Colours::lightskyblue (0xff87cefa); -const Colour Colours::lightslategrey (0xff778899); -const Colour Colours::lightsteelblue (0xffb0c4de); -const Colour Colours::lightyellow (0xffffffe0); -const Colour Colours::lime (0xff00ff00); -const Colour Colours::limegreen (0xff32cd32); -const Colour Colours::linen (0xfffaf0e6); -const Colour Colours::magenta (0xffff00ff); -const Colour Colours::maroon (0xff800000); -const Colour Colours::mediumaquamarine (0xff66cdaa); -const Colour Colours::mediumblue (0xff0000cd); -const Colour Colours::mediumorchid (0xffba55d3); -const Colour Colours::mediumpurple (0xff9370db); -const Colour Colours::mediumseagreen (0xff3cb371); -const Colour Colours::mediumslateblue (0xff7b68ee); -const Colour Colours::mediumspringgreen (0xff00fa9a); -const Colour Colours::mediumturquoise (0xff48d1cc); -const Colour Colours::mediumvioletred (0xffc71585); -const Colour Colours::midnightblue (0xff191970); -const Colour Colours::mintcream (0xfff5fffa); -const Colour Colours::mistyrose (0xffffe4e1); -const Colour Colours::navajowhite (0xffffdead); -const Colour Colours::navy (0xff000080); -const Colour Colours::oldlace (0xfffdf5e6); -const Colour Colours::olive (0xff808000); -const Colour Colours::olivedrab (0xff6b8e23); -const Colour Colours::orange (0xffffa500); -const Colour Colours::orangered (0xffff4500); -const Colour Colours::orchid (0xffda70d6); -const Colour Colours::palegoldenrod (0xffeee8aa); -const Colour Colours::palegreen (0xff98fb98); -const Colour Colours::paleturquoise (0xffafeeee); -const Colour Colours::palevioletred (0xffdb7093); -const Colour Colours::papayawhip (0xffffefd5); -const Colour Colours::peachpuff (0xffffdab9); -const Colour Colours::peru (0xffcd853f); -const Colour Colours::pink (0xffffc0cb); -const Colour Colours::plum (0xffdda0dd); -const Colour Colours::powderblue (0xffb0e0e6); -const Colour Colours::purple (0xff800080); -const Colour Colours::red (0xffff0000); -const Colour Colours::rosybrown (0xffbc8f8f); -const Colour Colours::royalblue (0xff4169e1); -const Colour Colours::saddlebrown (0xff8b4513); -const Colour Colours::salmon (0xfffa8072); -const Colour Colours::sandybrown (0xfff4a460); -const Colour Colours::seagreen (0xff2e8b57); -const Colour Colours::seashell (0xfffff5ee); -const Colour Colours::sienna (0xffa0522d); -const Colour Colours::silver (0xffc0c0c0); -const Colour Colours::skyblue (0xff87ceeb); -const Colour Colours::slateblue (0xff6a5acd); -const Colour Colours::slategrey (0xff708090); -const Colour Colours::snow (0xfffffafa); -const Colour Colours::springgreen (0xff00ff7f); -const Colour Colours::steelblue (0xff4682b4); -const Colour Colours::tan (0xffd2b48c); -const Colour Colours::teal (0xff008080); -const Colour Colours::thistle (0xffd8bfd8); -const Colour Colours::tomato (0xffff6347); -const Colour Colours::turquoise (0xff40e0d0); -const Colour Colours::violet (0xffee82ee); -const Colour Colours::wheat (0xfff5deb3); -const Colour Colours::white (0xffffffff); -const Colour Colours::whitesmoke (0xfff5f5f5); -const Colour Colours::yellow (0xffffff00); -const Colour Colours::yellowgreen (0xff9acd32); - -//============================================================================== -Colour Colours::findColourForName (const String& colourName, - Colour defaultColour) -{ - static const uint32 presets[] = - { - // (first value is the string's hashcode, second is ARGB) - - 0x05978fff, 0xff000000, /* black */ - 0x06bdcc29, 0xffffffff, /* white */ - 0x002e305a, 0xff0000ff, /* blue */ - 0x00308adf, 0xff808080, /* grey */ - 0x05e0cf03, 0xff008000, /* green */ - 0x0001b891, 0xffff0000, /* red */ - 0xd43c6474, 0xffffff00, /* yellow */ - 0x620886da, 0xfff0f8ff, /* aliceblue */ - 0x20a2676a, 0xfffaebd7, /* antiquewhite */ - 0x002dcebc, 0xff00ffff, /* aqua */ - 0x46bb5f7e, 0xff7fffd4, /* aquamarine */ - 0x0590228f, 0xfff0ffff, /* azure */ - 0x05947fe4, 0xfff5f5dc, /* beige */ - 0xad388e35, 0xffffe4c4, /* bisque */ - 0x00674f7e, 0xffffebcd, /* blanchedalmond */ - 0x39129959, 0xff8a2be2, /* blueviolet */ - 0x059a8136, 0xffa52a2a, /* brown */ - 0x89cea8f9, 0xffdeb887, /* burlywood */ - 0x0fa260cf, 0xff5f9ea0, /* cadetblue */ - 0x6b748956, 0xff7fff00, /* chartreuse */ - 0x2903623c, 0xffd2691e, /* chocolate */ - 0x05a74431, 0xffff7f50, /* coral */ - 0x618d42dd, 0xff6495ed, /* cornflowerblue */ - 0xe4b479fd, 0xfffff8dc, /* cornsilk */ - 0x3d8c4edf, 0xffdc143c, /* crimson */ - 0x002ed323, 0xff00ffff, /* cyan */ - 0x67cc74d0, 0xff00008b, /* darkblue */ - 0x67cd1799, 0xff008b8b, /* darkcyan */ - 0x31bbd168, 0xffb8860b, /* darkgoldenrod */ - 0x67cecf55, 0xff555555, /* darkgrey */ - 0x920b194d, 0xff006400, /* darkgreen */ - 0x923edd4c, 0xffbdb76b, /* darkkhaki */ - 0x5c293873, 0xff8b008b, /* darkmagenta */ - 0x6b6671fe, 0xff556b2f, /* darkolivegreen */ - 0xbcfd2524, 0xffff8c00, /* darkorange */ - 0xbcfdf799, 0xff9932cc, /* darkorchid */ - 0x55ee0d5b, 0xff8b0000, /* darkred */ - 0xc2e5f564, 0xffe9967a, /* darksalmon */ - 0x61be858a, 0xff8fbc8f, /* darkseagreen */ - 0xc2b0f2bd, 0xff483d8b, /* darkslateblue */ - 0xc2b34d42, 0xff2f4f4f, /* darkslategrey */ - 0x7cf2b06b, 0xff00ced1, /* darkturquoise */ - 0xc8769375, 0xff9400d3, /* darkviolet */ - 0x25832862, 0xffff1493, /* deeppink */ - 0xfcad568f, 0xff00bfff, /* deepskyblue */ - 0x634c8b67, 0xff696969, /* dimgrey */ - 0x45c1ce55, 0xff1e90ff, /* dodgerblue */ - 0xef19e3cb, 0xffb22222, /* firebrick */ - 0xb852b195, 0xfffffaf0, /* floralwhite */ - 0xd086fd06, 0xff228b22, /* forestgreen */ - 0xe106b6d7, 0xffff00ff, /* fuchsia */ - 0x7880d61e, 0xffdcdcdc, /* gainsboro */ - 0x00308060, 0xffffd700, /* gold */ - 0xb3b3bc1e, 0xffdaa520, /* goldenrod */ - 0xbab8a537, 0xffadff2f, /* greenyellow */ - 0xe4cacafb, 0xfff0fff0, /* honeydew */ - 0x41892743, 0xffff69b4, /* hotpink */ - 0xd5796f1a, 0xffcd5c5c, /* indianred */ - 0xb969fed2, 0xff4b0082, /* indigo */ - 0x05fef6a9, 0xfffffff0, /* ivory */ - 0x06149302, 0xfff0e68c, /* khaki */ - 0xad5a05c7, 0xffe6e6fa, /* lavender */ - 0x7c4d5b99, 0xfffff0f5, /* lavenderblush */ - 0x195756f0, 0xfffffacd, /* lemonchiffon */ - 0x28e4ea70, 0xffadd8e6, /* lightblue */ - 0xf3c7ccdb, 0xfff08080, /* lightcoral */ - 0x28e58d39, 0xffe0ffff, /* lightcyan */ - 0x21234e3c, 0xfffafad2, /* lightgoldenrodyellow */ - 0xf40157ad, 0xff90ee90, /* lightgreen */ - 0x28e744f5, 0xffd3d3d3, /* lightgrey */ - 0x28eb3b8c, 0xffffb6c1, /* lightpink */ - 0x9fb78304, 0xffffa07a, /* lightsalmon */ - 0x50632b2a, 0xff20b2aa, /* lightseagreen */ - 0x68fb7b25, 0xff87cefa, /* lightskyblue */ - 0xa8a35ba2, 0xff778899, /* lightslategrey */ - 0xa20d484f, 0xffb0c4de, /* lightsteelblue */ - 0xaa2cf10a, 0xffffffe0, /* lightyellow */ - 0x0032afd5, 0xff00ff00, /* lime */ - 0x607bbc4e, 0xff32cd32, /* limegreen */ - 0x06234efa, 0xfffaf0e6, /* linen */ - 0x316858a9, 0xffff00ff, /* magenta */ - 0xbf8ca470, 0xff800000, /* maroon */ - 0xbd58e0b3, 0xff66cdaa, /* mediumaquamarine */ - 0x967dfd4f, 0xff0000cd, /* mediumblue */ - 0x056f5c58, 0xffba55d3, /* mediumorchid */ - 0x07556b71, 0xff9370db, /* mediumpurple */ - 0x5369b689, 0xff3cb371, /* mediumseagreen */ - 0x066be19e, 0xff7b68ee, /* mediumslateblue */ - 0x3256b281, 0xff00fa9a, /* mediumspringgreen */ - 0xc0ad9f4c, 0xff48d1cc, /* mediumturquoise */ - 0x628e63dd, 0xffc71585, /* mediumvioletred */ - 0x168eb32a, 0xff191970, /* midnightblue */ - 0x4306b960, 0xfff5fffa, /* mintcream */ - 0x4cbc0e6b, 0xffffe4e1, /* mistyrose */ - 0xe97218a6, 0xffffdead, /* navajowhite */ - 0x00337bb6, 0xff000080, /* navy */ - 0xadd2d33e, 0xfffdf5e6, /* oldlace */ - 0x064ee1db, 0xff808000, /* olive */ - 0x9e33a98a, 0xff6b8e23, /* olivedrab */ - 0xc3de262e, 0xffffa500, /* orange */ - 0x58bebba3, 0xffff4500, /* orangered */ - 0xc3def8a3, 0xffda70d6, /* orchid */ - 0x28cb4834, 0xffeee8aa, /* palegoldenrod */ - 0x3d9dd619, 0xff98fb98, /* palegreen */ - 0x74022737, 0xffafeeee, /* paleturquoise */ - 0x15e2ebc8, 0xffdb7093, /* palevioletred */ - 0x5fd898e2, 0xffffefd5, /* papayawhip */ - 0x93e1b776, 0xffffdab9, /* peachpuff */ - 0x003472f8, 0xffcd853f, /* peru */ - 0x00348176, 0xffffc0cb, /* pink */ - 0x00348d94, 0xffdda0dd, /* plum */ - 0xd036be93, 0xffb0e0e6, /* powderblue */ - 0xc5c507bc, 0xff800080, /* purple */ - 0xa89d65b3, 0xffbc8f8f, /* rosybrown */ - 0xbd9413e1, 0xff4169e1, /* royalblue */ - 0xf456044f, 0xff8b4513, /* saddlebrown */ - 0xc9c6f66e, 0xfffa8072, /* salmon */ - 0x0bb131e1, 0xfff4a460, /* sandybrown */ - 0x34636c14, 0xff2e8b57, /* seagreen */ - 0x3507fb41, 0xfffff5ee, /* seashell */ - 0xca348772, 0xffa0522d, /* sienna */ - 0xca37d30d, 0xffc0c0c0, /* silver */ - 0x80da74fb, 0xff87ceeb, /* skyblue */ - 0x44a8dd73, 0xff6a5acd, /* slateblue */ - 0x44ab37f8, 0xff708090, /* slategrey */ - 0x0035f183, 0xfffffafa, /* snow */ - 0xd5440d16, 0xff00ff7f, /* springgreen */ - 0x3e1524a5, 0xff4682b4, /* steelblue */ - 0x0001bfa1, 0xffd2b48c, /* tan */ - 0x0036425c, 0xff008080, /* teal */ - 0xafc8858f, 0xffd8bfd8, /* thistle */ - 0xcc41600a, 0xffff6347, /* tomato */ - 0xfeea9b21, 0xff40e0d0, /* turquoise */ - 0xcf57947f, 0xffee82ee, /* violet */ - 0x06bdbae7, 0xfff5deb3, /* wheat */ - 0x10802ee6, 0xfff5f5f5, /* whitesmoke */ - 0xe1b5130f, 0xff9acd32 /* yellowgreen */ - }; - - const uint32 hash = (uint32) colourName.trim().toLowerCase().hashCode(); - - for (int i = 0; i < numElementsInArray (presets); i += 2) - if (presets [i] == hash) - return Colour (presets [i + 1]); - - return defaultColour; -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/colour/juce_Colours.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/colour/juce_Colours.h deleted file mode 100644 index 90e4aa5555..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/colour/juce_Colours.h +++ /dev/null @@ -1,107 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_COLOURS_H_INCLUDED -#define JUCE_COLOURS_H_INCLUDED - - -//============================================================================== -/** - Contains a set of predefined named colours (mostly standard HTML colours) - - @see Colour, Colours::greyLevel -*/ -class Colours -{ -public: - static JUCE_API const Colour - - //============================================================================== - transparentBlack, /**< ARGB = 0x00000000 */ - transparentWhite, /**< ARGB = 0x00ffffff */ - - //============================================================================== - black, /**< ARGB = 0xff000000 */ - white, /**< ARGB = 0xffffffff */ - blue, /**< ARGB = 0xff0000ff */ - grey, /**< ARGB = 0xff808080 */ - green, /**< ARGB = 0xff008000 */ - red, /**< ARGB = 0xffff0000 */ - yellow, /**< ARGB = 0xffffff00 */ - - //============================================================================== - aliceblue, antiquewhite, aqua, aquamarine, - azure, beige, bisque, blanchedalmond, - blueviolet, brown, burlywood, cadetblue, - chartreuse, chocolate, coral, cornflowerblue, - cornsilk, crimson, cyan, darkblue, - darkcyan, darkgoldenrod, darkgrey, darkgreen, - darkkhaki, darkmagenta, darkolivegreen, darkorange, - darkorchid, darkred, darksalmon, darkseagreen, - darkslateblue, darkslategrey, darkturquoise, darkviolet, - deeppink, deepskyblue, dimgrey, dodgerblue, - firebrick, floralwhite, forestgreen, fuchsia, - gainsboro, gold, goldenrod, greenyellow, - honeydew, hotpink, indianred, indigo, - ivory, khaki, lavender, lavenderblush, - lemonchiffon, lightblue, lightcoral, lightcyan, - lightgoldenrodyellow, lightgreen, lightgrey, lightpink, - lightsalmon, lightseagreen, lightskyblue, lightslategrey, - lightsteelblue, lightyellow, lime, limegreen, - linen, magenta, maroon, mediumaquamarine, - mediumblue, mediumorchid, mediumpurple, mediumseagreen, - mediumslateblue, mediumspringgreen, mediumturquoise, mediumvioletred, - midnightblue, mintcream, mistyrose, navajowhite, - navy, oldlace, olive, olivedrab, - orange, orangered, orchid, palegoldenrod, - palegreen, paleturquoise, palevioletred, papayawhip, - peachpuff, peru, pink, plum, - powderblue, purple, rosybrown, royalblue, - saddlebrown, salmon, sandybrown, seagreen, - seashell, sienna, silver, skyblue, - slateblue, slategrey, snow, springgreen, - steelblue, tan, teal, thistle, - tomato, turquoise, violet, wheat, - whitesmoke, yellowgreen; - - /** Attempts to look up a string in the list of known colour names, and return - the appropriate colour. - - A non-case-sensitive search is made of the list of predefined colours, and - if a match is found, that colour is returned. If no match is found, the - colour passed in as the defaultColour parameter is returned. - */ - static JUCE_API Colour findColourForName (const String& colourName, - Colour defaultColour); - -private: - //============================================================================== - // this isn't a class you should ever instantiate - it's just here for the - // static values in it. - Colours(); - - JUCE_DECLARE_NON_COPYABLE (Colours) -}; - -#endif // JUCE_COLOURS_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/colour/juce_FillType.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/colour/juce_FillType.cpp deleted file mode 100644 index 5e5db5632a..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/colour/juce_FillType.cpp +++ /dev/null @@ -1,148 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -FillType::FillType() noexcept - : colour (0xff000000) -{ -} - -FillType::FillType (Colour c) noexcept - : colour (c) -{ -} - -FillType::FillType (const ColourGradient& gradient_) - : colour (0xff000000), gradient (new ColourGradient (gradient_)) -{ -} - -FillType::FillType (const Image& image_, const AffineTransform& transform_) noexcept - : colour (0xff000000), image (image_), transform (transform_) -{ -} - -FillType::FillType (const FillType& other) - : colour (other.colour), - gradient (other.gradient.createCopy()), - image (other.image), - transform (other.transform) -{ -} - -FillType& FillType::operator= (const FillType& other) -{ - if (this != &other) - { - colour = other.colour; - gradient = other.gradient.createCopy(); - image = other.image; - transform = other.transform; - } - - return *this; -} - -#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS -FillType::FillType (FillType&& other) noexcept - : colour (other.colour), - gradient (other.gradient.release()), - image (static_cast (other.image)), - transform (other.transform) -{ -} - -FillType& FillType::operator= (FillType&& other) noexcept -{ - jassert (this != &other); // hopefully the compiler should make this situation impossible! - - colour = other.colour; - gradient = other.gradient.release(); - image = static_cast (other.image); - transform = other.transform; - return *this; -} -#endif - -FillType::~FillType() noexcept -{ -} - -bool FillType::operator== (const FillType& other) const -{ - return colour == other.colour && image == other.image - && transform == other.transform - && (gradient == other.gradient - || (gradient != nullptr && other.gradient != nullptr && *gradient == *other.gradient)); -} - -bool FillType::operator!= (const FillType& other) const -{ - return ! operator== (other); -} - -void FillType::setColour (Colour newColour) noexcept -{ - gradient = nullptr; - image = Image::null; - colour = newColour; -} - -void FillType::setGradient (const ColourGradient& newGradient) -{ - if (gradient != nullptr) - { - *gradient = newGradient; - } - else - { - image = Image::null; - gradient = new ColourGradient (newGradient); - colour = Colours::black; - } -} - -void FillType::setTiledImage (const Image& image_, const AffineTransform& transform_) noexcept -{ - gradient = nullptr; - image = image_; - transform = transform_; - colour = Colours::black; -} - -void FillType::setOpacity (const float newOpacity) noexcept -{ - colour = colour.withAlpha (newOpacity); -} - -bool FillType::isInvisible() const noexcept -{ - return colour.isTransparent() || (gradient != nullptr && gradient->isInvisible()); -} - -FillType FillType::transformed (const AffineTransform& t) const -{ - FillType f (*this); - f.transform = f.transform.followedBy (t); - return f; -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/colour/juce_FillType.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/colour/juce_FillType.h deleted file mode 100644 index 19401d66ad..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/colour/juce_FillType.h +++ /dev/null @@ -1,149 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_FILLTYPE_H_INCLUDED -#define JUCE_FILLTYPE_H_INCLUDED - - -//============================================================================== -/** - Represents a colour or fill pattern to use for rendering paths. - - This is used by the Graphics and DrawablePath classes as a way to encapsulate - a brush type. It can either be a solid colour, a gradient, or a tiled image. - - @see Graphics::setFillType, DrawablePath::setFill -*/ -class JUCE_API FillType -{ -public: - //============================================================================== - /** Creates a default fill type, of solid black. */ - FillType() noexcept; - - /** Creates a fill type of a solid colour. - @see setColour - */ - FillType (Colour colour) noexcept; - - /** Creates a gradient fill type. - @see setGradient - */ - FillType (const ColourGradient& gradient); - - /** Creates a tiled image fill type. The transform allows you to set the scaling, offset - and rotation of the pattern. - @see setTiledImage - */ - FillType (const Image& image, const AffineTransform& transform) noexcept; - - /** Creates a copy of another FillType. */ - FillType (const FillType&); - - /** Makes a copy of another FillType. */ - FillType& operator= (const FillType&); - - #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS - FillType (FillType&&) noexcept; - FillType& operator= (FillType&&) noexcept; - #endif - - /** Destructor. */ - ~FillType() noexcept; - - //============================================================================== - /** Returns true if this is a solid colour fill, and not a gradient or image. */ - bool isColour() const noexcept { return gradient == nullptr && image.isNull(); } - - /** Returns true if this is a gradient fill. */ - bool isGradient() const noexcept { return gradient != nullptr; } - - /** Returns true if this is a tiled image pattern fill. */ - bool isTiledImage() const noexcept { return image.isValid(); } - - /** Turns this object into a solid colour fill. - If the object was an image or gradient, those fields will no longer be valid. */ - void setColour (Colour newColour) noexcept; - - /** Turns this object into a gradient fill. */ - void setGradient (const ColourGradient& newGradient); - - /** Turns this object into a tiled image fill type. The transform allows you to set - the scaling, offset and rotation of the pattern. - */ - void setTiledImage (const Image& image, const AffineTransform& transform) noexcept; - - /** Changes the opacity that should be used. - If the fill is a solid colour, this just changes the opacity of that colour. For - gradients and image tiles, it changes the opacity that will be used for them. - */ - void setOpacity (float newOpacity) noexcept; - - /** Returns the current opacity to be applied to the colour, gradient, or image. - @see setOpacity - */ - float getOpacity() const noexcept { return colour.getFloatAlpha(); } - - /** Returns true if this fill type is completely transparent. */ - bool isInvisible() const noexcept; - - /** Returns a copy of this fill, adding the specified transform applied to the - existing transform. - */ - FillType transformed (const AffineTransform& transform) const; - - //============================================================================== - /** The solid colour being used. - - If the fill type is not a solid colour, the alpha channel of this colour indicates - the opacity that should be used for the fill, and the RGB channels are ignored. - */ - Colour colour; - - /** Returns the gradient that should be used for filling. - This will be zero if the object is some other type of fill. - If a gradient is active, the overall opacity with which it should be applied - is indicated by the alpha channel of the colour variable. - */ - ScopedPointer gradient; - - /** The image that should be used for tiling. - If an image fill is active, the overall opacity with which it should be applied - is indicated by the alpha channel of the colour variable. - */ - Image image; - - /** The transform that should be applied to the image or gradient that's being drawn. */ - AffineTransform transform; - - //============================================================================== - bool operator== (const FillType&) const; - bool operator!= (const FillType&) const; - -private: - JUCE_LEAK_DETECTOR (FillType) -}; - - -#endif // JUCE_FILLTYPE_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/colour/juce_PixelFormats.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/colour/juce_PixelFormats.h deleted file mode 100644 index 2715cb2edf..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/colour/juce_PixelFormats.h +++ /dev/null @@ -1,604 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_PIXELFORMATS_H_INCLUDED -#define JUCE_PIXELFORMATS_H_INCLUDED - - -//============================================================================== -#if JUCE_MSVC - #pragma pack (push, 1) -#endif - -class PixelRGB; -class PixelAlpha; - -inline uint32 maskPixelComponents (uint32 x) noexcept -{ - return (x >> 8) & 0x00ff00ff; -} - -inline uint32 clampPixelComponents (uint32 x) noexcept -{ - return (x | (0x01000100 - maskPixelComponents (x))) & 0x00ff00ff; -} - -//============================================================================== -/** - Represents a 32-bit ARGB pixel with premultiplied alpha, and can perform compositing - operations with it. - - This is used internally by the imaging classes. - - @see PixelRGB -*/ -class JUCE_API PixelARGB -{ -public: - /** Creates a pixel without defining its colour. */ - PixelARGB() noexcept {} - ~PixelARGB() noexcept {} - - /** Creates a pixel from a 32-bit argb value. - */ - PixelARGB (const uint32 argbValue) noexcept - : argb (argbValue) - { - } - - PixelARGB (const uint8 a, const uint8 r, const uint8 g, const uint8 b) noexcept - { - components.b = b; - components.g = g; - components.r = r; - components.a = a; - } - - forcedinline uint32 getARGB() const noexcept { return argb; } - forcedinline uint32 getUnpremultipliedARGB() const noexcept { PixelARGB p (argb); p.unpremultiply(); return p.getARGB(); } - - forcedinline uint32 getRB() const noexcept { return 0x00ff00ff & argb; } - forcedinline uint32 getAG() const noexcept { return 0x00ff00ff & (argb >> 8); } - - forcedinline uint8 getAlpha() const noexcept { return components.a; } - forcedinline uint8 getRed() const noexcept { return components.r; } - forcedinline uint8 getGreen() const noexcept { return components.g; } - forcedinline uint8 getBlue() const noexcept { return components.b; } - - #if JUCE_GCC && ! JUCE_CLANG - // NB these are here as a workaround because GCC refuses to bind to packed values. - forcedinline uint8& getAlpha() noexcept { return comps [indexA]; } - forcedinline uint8& getRed() noexcept { return comps [indexR]; } - forcedinline uint8& getGreen() noexcept { return comps [indexG]; } - forcedinline uint8& getBlue() noexcept { return comps [indexB]; } - #else - forcedinline uint8& getAlpha() noexcept { return components.a; } - forcedinline uint8& getRed() noexcept { return components.r; } - forcedinline uint8& getGreen() noexcept { return components.g; } - forcedinline uint8& getBlue() noexcept { return components.b; } - #endif - - /** Blends another pixel onto this one. - - This takes into account the opacity of the pixel being overlaid, and blends - it accordingly. - */ - template - forcedinline void blend (const Pixel& src) noexcept - { - const uint32 alpha = 0x100 - src.getAlpha(); - uint32 rb = src.getRB() + maskPixelComponents (getRB() * alpha); - uint32 ag = src.getAG() + maskPixelComponents (getAG() * alpha); - argb = clampPixelComponents (rb) + (clampPixelComponents (ag) << 8); - } - - /** Blends another pixel onto this one. - - This takes into account the opacity of the pixel being overlaid, and blends - it accordingly. - */ - forcedinline void blend (const PixelRGB src) noexcept; - - - /** Blends another pixel onto this one, applying an extra multiplier to its opacity. - - The opacity of the pixel being overlaid is scaled by the extraAlpha factor before - being used, so this can blend semi-transparently from a PixelRGB argument. - */ - template - forcedinline void blend (const Pixel& src, uint32 extraAlpha) noexcept - { - uint32 ag = maskPixelComponents (extraAlpha * src.getAG()); - const uint32 alpha = 0x100 - (ag >> 16); - ag += maskPixelComponents (getAG() * alpha); - - uint32 rb = maskPixelComponents (extraAlpha * src.getRB()) - + maskPixelComponents (getRB() * alpha); - - argb = clampPixelComponents(rb) + (clampPixelComponents (ag) << 8); - } - - /** Blends another pixel with this one, creating a colour that is somewhere - between the two, as specified by the amount. - */ - template - forcedinline void tween (const Pixel& src, const uint32 amount) noexcept - { - uint32 drb = getRB(); - drb += (((src.getRB() - drb) * amount) >> 8); - drb &= 0x00ff00ff; - - uint32 dag = getAG(); - dag += (((src.getAG() - dag) * amount) >> 8); - dag &= 0x00ff00ff; - dag <<= 8; - - dag |= drb; - argb = dag; - } - - /** Copies another pixel colour over this one. - - This doesn't blend it - this colour is simply replaced by the other one. - */ - template - forcedinline void set (const Pixel& src) noexcept - { - argb = src.getARGB(); - } - - /** Replaces the colour's alpha value with another one. */ - forcedinline void setAlpha (const uint8 newAlpha) noexcept - { - components.a = newAlpha; - } - - /** Multiplies the colour's alpha value with another one. */ - forcedinline void multiplyAlpha (int multiplier) noexcept - { - ++multiplier; - - argb = ((((uint32) multiplier) * getAG()) & 0xff00ff00) - | (((((uint32) multiplier) * getRB()) >> 8) & 0x00ff00ff); - } - - forcedinline void multiplyAlpha (const float multiplier) noexcept - { - multiplyAlpha ((int) (multiplier * 255.0f)); - } - - /** Sets the pixel's colour from individual components. */ - void setARGB (const uint8 a, const uint8 r, const uint8 g, const uint8 b) noexcept - { - components.b = b; - components.g = g; - components.r = r; - components.a = a; - } - - /** Premultiplies the pixel's RGB values by its alpha. */ - forcedinline void premultiply() noexcept - { - const uint32 alpha = components.a; - - if (alpha < 0xff) - { - if (alpha == 0) - { - components.b = 0; - components.g = 0; - components.r = 0; - } - else - { - components.b = (uint8) ((components.b * alpha + 0x7f) >> 8); - components.g = (uint8) ((components.g * alpha + 0x7f) >> 8); - components.r = (uint8) ((components.r * alpha + 0x7f) >> 8); - } - } - } - - /** Unpremultiplies the pixel's RGB values. */ - forcedinline void unpremultiply() noexcept - { - const uint32 alpha = components.a; - - if (alpha < 0xff) - { - if (alpha == 0) - { - components.b = 0; - components.g = 0; - components.r = 0; - } - else - { - components.b = (uint8) jmin ((uint32) 0xff, (components.b * 0xff) / alpha); - components.g = (uint8) jmin ((uint32) 0xff, (components.g * 0xff) / alpha); - components.r = (uint8) jmin ((uint32) 0xff, (components.r * 0xff) / alpha); - } - } - } - - forcedinline void desaturate() noexcept - { - if (components.a < 0xff && components.a > 0) - { - const int newUnpremultipliedLevel = (0xff * ((int) components.r + (int) components.g + (int) components.b) / (3 * components.a)); - - components.r = components.g = components.b - = (uint8) ((newUnpremultipliedLevel * components.a + 0x7f) >> 8); - } - else - { - components.r = components.g = components.b - = (uint8) (((int) components.r + (int) components.g + (int) components.b) / 3); - } - } - - /** Returns a uint32 which when written to memory, will be in the order r, g, b, a. */ - inline uint32 getInRGBAMemoryOrder() const noexcept - { - #if JUCE_BIG_ENDIAN - return (((uint32) components.r) << 24) | (((uint32) components.g) << 16) | (((uint32) components.b) << 8) | components.a; - #else - return (((uint32) components.a) << 24) | (((uint32) components.b) << 16) | (((uint32) components.g) << 8) | components.r; - #endif - } - - //============================================================================== - /** The indexes of the different components in the byte layout of this type of colour. */ - #if JUCE_BIG_ENDIAN - enum { indexA = 0, indexR = 1, indexG = 2, indexB = 3 }; - #else - enum { indexA = 3, indexR = 2, indexG = 1, indexB = 0 }; - #endif - -private: - //============================================================================== - struct Components - { - #if JUCE_BIG_ENDIAN - uint8 a, r, g, b; - #else - uint8 b, g, r, a; - #endif - } JUCE_PACKED; - - union - { - uint32 argb; - Components components; - #if JUCE_GCC - uint8 comps[4]; - #endif - }; -} -#ifndef DOXYGEN - JUCE_PACKED -#endif -; - - -//============================================================================== -/** - Represents a 24-bit RGB pixel, and can perform compositing operations on it. - - This is used internally by the imaging classes. - - @see PixelARGB -*/ -class JUCE_API PixelRGB -{ -public: - /** Creates a pixel without defining its colour. */ - PixelRGB() noexcept {} - ~PixelRGB() noexcept {} - - /** Creates a pixel from a 32-bit argb value. - - (The argb format is that used by PixelARGB) - */ - PixelRGB (const uint32 argb) noexcept - { - r = (uint8) (argb >> 16); - g = (uint8) (argb >> 8); - b = (uint8) (argb); - } - - forcedinline uint32 getARGB() const noexcept { return 0xff000000 | b | (((uint32) g) << 8) | (((uint32) r) << 16); } - forcedinline uint32 getUnpremultipliedARGB() const noexcept { return getARGB(); } - - forcedinline uint32 getRB() const noexcept { return b | (uint32) (r << 16); } - forcedinline uint32 getAG() const noexcept { return (uint32) (0xff0000 | g); } - - forcedinline uint8 getAlpha() const noexcept { return 0xff; } - forcedinline uint8 getRed() const noexcept { return r; } - forcedinline uint8 getGreen() const noexcept { return g; } - forcedinline uint8 getBlue() const noexcept { return b; } - - forcedinline uint8& getRed() noexcept { return r; } - forcedinline uint8& getGreen() noexcept { return g; } - forcedinline uint8& getBlue() noexcept { return b; } - - /** Blends another pixel onto this one. - - This takes into account the opacity of the pixel being overlaid, and blends - it accordingly. - */ - template - forcedinline void blend (const Pixel& src) noexcept - { - const uint32 alpha = 0x100 - src.getAlpha(); - - uint32 rb = clampPixelComponents (src.getRB() + maskPixelComponents (getRB() * alpha)); - uint32 ag = src.getAG() + (g * alpha >> 8); - - r = (uint8) (rb >> 16); - g = (uint8) clampPixelComponents (ag); - b = (uint8) rb; - } - - forcedinline void blend (const PixelRGB src) noexcept - { - set (src); - } - - /** Blends another pixel onto this one, applying an extra multiplier to its opacity. - - The opacity of the pixel being overlaid is scaled by the extraAlpha factor before - being used, so this can blend semi-transparently from a PixelRGB argument. - */ - template - forcedinline void blend (const Pixel& src, uint32 extraAlpha) noexcept - { - uint32 ag = maskPixelComponents (extraAlpha * src.getAG()); - const uint32 alpha = 0x100 - (ag >> 16); - ag += g * alpha >> 8; - - uint32 rb = clampPixelComponents (maskPixelComponents (extraAlpha * src.getRB()) - + maskPixelComponents (getRB() * alpha)); - - b = (uint8) rb; - g = (uint8) clampPixelComponents (ag); - r = (uint8) (rb >> 16); - } - - /** Blends another pixel with this one, creating a colour that is somewhere - between the two, as specified by the amount. - */ - template - forcedinline void tween (const Pixel& src, const uint32 amount) noexcept - { - uint32 drb = getRB(); - drb += (((src.getRB() - drb) * amount) >> 8); - - uint32 dag = getAG(); - dag += (((src.getAG() - dag) * amount) >> 8); - - b = (uint8) drb; - g = (uint8) dag; - r = (uint8) (drb >> 16); - } - - /** Copies another pixel colour over this one. - - This doesn't blend it - this colour is simply replaced by the other one. - Because PixelRGB has no alpha channel, any alpha value in the source pixel - is thrown away. - */ - template - forcedinline void set (const Pixel& src) noexcept - { - b = src.getBlue(); - g = src.getGreen(); - r = src.getRed(); - } - - /** This method is included for compatibility with the PixelARGB class. */ - forcedinline void setAlpha (const uint8) noexcept {} - - /** Multiplies the colour's alpha value with another one. */ - forcedinline void multiplyAlpha (int) noexcept {} - - /** Multiplies the colour's alpha value with another one. */ - forcedinline void multiplyAlpha (float) noexcept {} - - /** Sets the pixel's colour from individual components. */ - void setARGB (const uint8, const uint8 red, const uint8 green, const uint8 blue) noexcept - { - r = red; - g = green; - b = blue; - } - - /** Premultiplies the pixel's RGB values by its alpha. */ - forcedinline void premultiply() noexcept {} - - /** Unpremultiplies the pixel's RGB values. */ - forcedinline void unpremultiply() noexcept {} - - forcedinline void desaturate() noexcept - { - r = g = b = (uint8) (((int) r + (int) g + (int) b) / 3); - } - - //============================================================================== - /** The indexes of the different components in the byte layout of this type of colour. */ - #if JUCE_MAC - enum { indexR = 0, indexG = 1, indexB = 2 }; - #else - enum { indexR = 2, indexG = 1, indexB = 0 }; - #endif - -private: - //============================================================================== - #if JUCE_MAC - uint8 r, g, b; - #else - uint8 b, g, r; - #endif - -} -#ifndef DOXYGEN - JUCE_PACKED -#endif -; - -forcedinline void PixelARGB::blend (const PixelRGB src) noexcept -{ - set (src); -} - -//============================================================================== -/** - Represents an 8-bit single-channel pixel, and can perform compositing operations on it. - - This is used internally by the imaging classes. - - @see PixelARGB, PixelRGB -*/ -class JUCE_API PixelAlpha -{ -public: - /** Creates a pixel without defining its colour. */ - PixelAlpha() noexcept {} - ~PixelAlpha() noexcept {} - - /** Creates a pixel from a 32-bit argb value. - - (The argb format is that used by PixelARGB) - */ - PixelAlpha (const uint32 argb) noexcept - { - a = (uint8) (argb >> 24); - } - - forcedinline uint32 getARGB() const noexcept { return (((uint32) a) << 24) | (((uint32) a) << 16) | (((uint32) a) << 8) | a; } - forcedinline uint32 getUnpremultipliedARGB() const noexcept { return (((uint32) a) << 24) | 0xffffff; } - - forcedinline uint32 getRB() const noexcept { return (((uint32) a) << 16) | a; } - forcedinline uint32 getAG() const noexcept { return (((uint32) a) << 16) | a; } - - forcedinline uint8 getAlpha() const noexcept { return a; } - forcedinline uint8& getAlpha() noexcept { return a; } - - forcedinline uint8 getRed() const noexcept { return 0; } - forcedinline uint8 getGreen() const noexcept { return 0; } - forcedinline uint8 getBlue() const noexcept { return 0; } - - /** Blends another pixel onto this one. - - This takes into account the opacity of the pixel being overlaid, and blends - it accordingly. - */ - template - forcedinline void blend (const Pixel& src) noexcept - { - const int srcA = src.getAlpha(); - a = (uint8) ((a * (0x100 - srcA) >> 8) + srcA); - } - - /** Blends another pixel onto this one, applying an extra multiplier to its opacity. - - The opacity of the pixel being overlaid is scaled by the extraAlpha factor before - being used, so this can blend semi-transparently from a PixelRGB argument. - */ - template - forcedinline void blend (const Pixel& src, uint32 extraAlpha) noexcept - { - ++extraAlpha; - const int srcAlpha = (int) ((extraAlpha * src.getAlpha()) >> 8); - a = (uint8) ((a * (0x100 - srcAlpha) >> 8) + srcAlpha); - } - - /** Blends another pixel with this one, creating a colour that is somewhere - between the two, as specified by the amount. - */ - template - forcedinline void tween (const Pixel& src, const uint32 amount) noexcept - { - a += ((src.getAlpha() - a) * amount) >> 8; - } - - /** Copies another pixel colour over this one. - - This doesn't blend it - this colour is simply replaced by the other one. - */ - template - forcedinline void set (const Pixel& src) noexcept - { - a = src.getAlpha(); - } - - /** Replaces the colour's alpha value with another one. */ - forcedinline void setAlpha (const uint8 newAlpha) noexcept - { - a = newAlpha; - } - - /** Multiplies the colour's alpha value with another one. */ - forcedinline void multiplyAlpha (int multiplier) noexcept - { - ++multiplier; - a = (uint8) ((a * multiplier) >> 8); - } - - forcedinline void multiplyAlpha (const float multiplier) noexcept - { - a = (uint8) (a * multiplier); - } - - /** Sets the pixel's colour from individual components. */ - forcedinline void setARGB (const uint8 a_, const uint8 /*r*/, const uint8 /*g*/, const uint8 /*b*/) noexcept - { - a = a_; - } - - /** Premultiplies the pixel's RGB values by its alpha. */ - forcedinline void premultiply() noexcept {} - - /** Unpremultiplies the pixel's RGB values. */ - forcedinline void unpremultiply() noexcept {} - - forcedinline void desaturate() noexcept {} - - //============================================================================== - /** The indexes of the different components in the byte layout of this type of colour. */ - enum { indexA = 0 }; - -private: - //============================================================================== - uint8 a; -} -#ifndef DOXYGEN - JUCE_PACKED -#endif -; - -#if JUCE_MSVC - #pragma pack (pop) -#endif - -#endif // JUCE_PIXELFORMATS_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/contexts/juce_GraphicsContext.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/contexts/juce_GraphicsContext.cpp deleted file mode 100644 index a0dcd80fd0..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/contexts/juce_GraphicsContext.cpp +++ /dev/null @@ -1,678 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -namespace -{ - template - Rectangle coordsToRectangle (Type x, Type y, Type w, Type h) - { - #if JUCE_DEBUG - const int maxVal = 0x3fffffff; - - jassert ((int) x >= -maxVal && (int) x <= maxVal - && (int) y >= -maxVal && (int) y <= maxVal - && (int) w >= -maxVal && (int) w <= maxVal - && (int) h >= -maxVal && (int) h <= maxVal); - #endif - - return Rectangle (x, y, w, h); - } -} - -//============================================================================== -LowLevelGraphicsContext::LowLevelGraphicsContext() {} -LowLevelGraphicsContext::~LowLevelGraphicsContext() {} - -//============================================================================== -Graphics::Graphics (const Image& imageToDrawOnto) - : context (*imageToDrawOnto.createLowLevelContext()), - contextToDelete (&context), - saveStatePending (false) -{ - jassert (imageToDrawOnto.isValid()); // Can't draw into a null image! -} - -Graphics::Graphics (LowLevelGraphicsContext& internalContext) noexcept - : context (internalContext), - saveStatePending (false) -{ -} - -Graphics::~Graphics() -{ -} - -//============================================================================== -void Graphics::resetToDefaultState() -{ - saveStateIfPending(); - context.setFill (FillType()); - context.setFont (Font()); - context.setInterpolationQuality (Graphics::mediumResamplingQuality); -} - -bool Graphics::isVectorDevice() const -{ - return context.isVectorDevice(); -} - -bool Graphics::reduceClipRegion (const Rectangle& area) -{ - saveStateIfPending(); - return context.clipToRectangle (area); -} - -bool Graphics::reduceClipRegion (const int x, const int y, const int w, const int h) -{ - return reduceClipRegion (Rectangle (x, y, w, h)); -} - -bool Graphics::reduceClipRegion (const RectangleList& clipRegion) -{ - saveStateIfPending(); - return context.clipToRectangleList (clipRegion); -} - -bool Graphics::reduceClipRegion (const Path& path, const AffineTransform& transform) -{ - saveStateIfPending(); - context.clipToPath (path, transform); - return ! context.isClipEmpty(); -} - -bool Graphics::reduceClipRegion (const Image& image, const AffineTransform& transform) -{ - saveStateIfPending(); - context.clipToImageAlpha (image, transform); - return ! context.isClipEmpty(); -} - -void Graphics::excludeClipRegion (const Rectangle& rectangleToExclude) -{ - saveStateIfPending(); - context.excludeClipRectangle (rectangleToExclude); -} - -bool Graphics::isClipEmpty() const -{ - return context.isClipEmpty(); -} - -Rectangle Graphics::getClipBounds() const -{ - return context.getClipBounds(); -} - -void Graphics::saveState() -{ - saveStateIfPending(); - saveStatePending = true; -} - -void Graphics::restoreState() -{ - if (saveStatePending) - saveStatePending = false; - else - context.restoreState(); -} - -void Graphics::saveStateIfPending() -{ - if (saveStatePending) - { - saveStatePending = false; - context.saveState(); - } -} - -void Graphics::setOrigin (Point newOrigin) -{ - saveStateIfPending(); - context.setOrigin (newOrigin); -} - -void Graphics::setOrigin (int x, int y) -{ - setOrigin (Point (x, y)); -} - -void Graphics::addTransform (const AffineTransform& transform) -{ - saveStateIfPending(); - context.addTransform (transform); -} - -bool Graphics::clipRegionIntersects (const Rectangle& area) const -{ - return context.clipRegionIntersects (area); -} - -void Graphics::beginTransparencyLayer (float layerOpacity) -{ - saveStateIfPending(); - context.beginTransparencyLayer (layerOpacity); -} - -void Graphics::endTransparencyLayer() -{ - context.endTransparencyLayer(); -} - -//============================================================================== -void Graphics::setColour (Colour newColour) -{ - saveStateIfPending(); - context.setFill (newColour); -} - -void Graphics::setOpacity (const float newOpacity) -{ - saveStateIfPending(); - context.setOpacity (newOpacity); -} - -void Graphics::setGradientFill (const ColourGradient& gradient) -{ - setFillType (gradient); -} - -void Graphics::setTiledImageFill (const Image& imageToUse, const int anchorX, const int anchorY, const float opacity) -{ - saveStateIfPending(); - context.setFill (FillType (imageToUse, AffineTransform::translation ((float) anchorX, (float) anchorY))); - context.setOpacity (opacity); -} - -void Graphics::setFillType (const FillType& newFill) -{ - saveStateIfPending(); - context.setFill (newFill); -} - -//============================================================================== -void Graphics::setFont (const Font& newFont) -{ - saveStateIfPending(); - context.setFont (newFont); -} - -void Graphics::setFont (const float newFontHeight) -{ - setFont (context.getFont().withHeight (newFontHeight)); -} - -Font Graphics::getCurrentFont() const -{ - return context.getFont(); -} - -//============================================================================== -void Graphics::drawSingleLineText (const String& text, const int startX, const int baselineY, - Justification justification) const -{ - if (text.isNotEmpty()) - { - // Don't pass any vertical placement flags to this method - they'll be ignored. - jassert (justification.getOnlyVerticalFlags() == 0); - - const int flags = justification.getOnlyHorizontalFlags(); - - if (flags == Justification::right) - { - if (startX < context.getClipBounds().getX()) - return; - } - else if (flags == Justification::left) - if (startX > context.getClipBounds().getRight()) - return; - - GlyphArrangement arr; - arr.addLineOfText (context.getFont(), text, (float) startX, (float) baselineY); - - if (flags != Justification::left) - { - float w = arr.getBoundingBox (0, -1, true).getWidth(); - - if ((flags & (Justification::horizontallyCentred | Justification::horizontallyJustified)) != 0) - w /= 2.0f; - - arr.draw (*this, AffineTransform::translation (-w, 0)); - } - else - { - arr.draw (*this); - } - } -} - -void Graphics::drawMultiLineText (const String& text, const int startX, - const int baselineY, const int maximumLineWidth) const -{ - if (text.isNotEmpty() - && startX < context.getClipBounds().getRight()) - { - GlyphArrangement arr; - arr.addJustifiedText (context.getFont(), text, - (float) startX, (float) baselineY, (float) maximumLineWidth, - Justification::left); - arr.draw (*this); - } -} - -void Graphics::drawText (const String& text, const Rectangle& area, - Justification justificationType, bool useEllipsesIfTooBig) const -{ - if (text.isNotEmpty() && context.clipRegionIntersects (area.getSmallestIntegerContainer())) - { - GlyphArrangement arr; - arr.addCurtailedLineOfText (context.getFont(), text, 0.0f, 0.0f, - area.getWidth(), useEllipsesIfTooBig); - - arr.justifyGlyphs (0, arr.getNumGlyphs(), - area.getX(), area.getY(), area.getWidth(), area.getHeight(), - justificationType); - arr.draw (*this); - } -} - -void Graphics::drawText (const String& text, const Rectangle& area, - Justification justificationType, bool useEllipsesIfTooBig) const -{ - drawText (text, area.toFloat(), justificationType, useEllipsesIfTooBig); -} - -void Graphics::drawText (const String& text, const int x, const int y, const int width, const int height, - Justification justificationType, const bool useEllipsesIfTooBig) const -{ - drawText (text, Rectangle (x, y, width, height), justificationType, useEllipsesIfTooBig); -} - -void Graphics::drawFittedText (const String& text, const Rectangle& area, - Justification justification, - const int maximumNumberOfLines, - const float minimumHorizontalScale) const -{ - if (text.isNotEmpty() && (! area.isEmpty()) && context.clipRegionIntersects (area)) - { - GlyphArrangement arr; - arr.addFittedText (context.getFont(), text, - (float) area.getX(), (float) area.getY(), - (float) area.getWidth(), (float) area.getHeight(), - justification, - maximumNumberOfLines, - minimumHorizontalScale); - - arr.draw (*this); - } -} - -void Graphics::drawFittedText (const String& text, const int x, const int y, const int width, const int height, - Justification justification, - const int maximumNumberOfLines, - const float minimumHorizontalScale) const -{ - drawFittedText (text, coordsToRectangle (x, y, width, height), - justification, maximumNumberOfLines, minimumHorizontalScale); -} - -//============================================================================== -void Graphics::fillRect (const Rectangle& r) const -{ - context.fillRect (r, false); -} - -void Graphics::fillRect (const Rectangle& r) const -{ - context.fillRect (r); -} - -void Graphics::fillRect (int x, int y, int width, int height) const -{ - context.fillRect (coordsToRectangle (x, y, width, height), false); -} - -void Graphics::fillRect (float x, float y, float width, float height) const -{ - fillRect (coordsToRectangle (x, y, width, height)); -} - -void Graphics::fillRectList (const RectangleList& rectangles) const -{ - context.fillRectList (rectangles); -} - -void Graphics::fillRectList (const RectangleList& rects) const -{ - for (const Rectangle* r = rects.begin(), * const e = rects.end(); r != e; ++r) - context.fillRect (*r, false); -} - -void Graphics::setPixel (int x, int y) const -{ - context.fillRect (Rectangle (x, y, 1, 1), false); -} - -void Graphics::fillAll() const -{ - fillRect (context.getClipBounds()); -} - -void Graphics::fillAll (Colour colourToUse) const -{ - if (! colourToUse.isTransparent()) - { - const Rectangle clip (context.getClipBounds()); - - context.saveState(); - context.setFill (colourToUse); - context.fillRect (clip, false); - context.restoreState(); - } -} - - -//============================================================================== -void Graphics::fillPath (const Path& path, const AffineTransform& transform) const -{ - if ((! context.isClipEmpty()) && ! path.isEmpty()) - context.fillPath (path, transform); -} - -void Graphics::strokePath (const Path& path, - const PathStrokeType& strokeType, - const AffineTransform& transform) const -{ - Path stroke; - strokeType.createStrokedPath (stroke, path, transform, context.getPhysicalPixelScaleFactor()); - fillPath (stroke); -} - -//============================================================================== -void Graphics::drawRect (float x, float y, float width, float height, float lineThickness) const -{ - drawRect (coordsToRectangle (x, y, width, height), lineThickness); -} - -void Graphics::drawRect (int x, int y, int width, int height, int lineThickness) const -{ - drawRect (coordsToRectangle (x, y, width, height), lineThickness); -} - -void Graphics::drawRect (const Rectangle& r, int lineThickness) const -{ - drawRect (r.toFloat(), (float) lineThickness); -} - -void Graphics::drawRect (Rectangle r, const float lineThickness) const -{ - RectangleList rects; - rects.addWithoutMerging (r.removeFromTop (lineThickness)); - rects.addWithoutMerging (r.removeFromBottom (lineThickness)); - rects.addWithoutMerging (r.removeFromLeft (lineThickness)); - rects.addWithoutMerging (r.removeFromRight (lineThickness)); - context.fillRectList (rects); -} - -//============================================================================== -void Graphics::fillEllipse (const Rectangle& area) const -{ - Path p; - p.addEllipse (area); - fillPath (p); -} - -void Graphics::fillEllipse (float x, float y, float w, float h) const -{ - fillEllipse (Rectangle (x, y, w, h)); -} - -void Graphics::drawEllipse (float x, float y, float width, float height, float lineThickness) const -{ - Path p; - p.addEllipse (x, y, width, height); - strokePath (p, PathStrokeType (lineThickness)); -} - -void Graphics::drawEllipse (const Rectangle& area, float lineThickness) const -{ - drawEllipse (area.getX(), area.getY(), area.getWidth(), area.getHeight(), lineThickness); -} - -void Graphics::fillRoundedRectangle (float x, float y, float width, float height, float cornerSize) const -{ - fillRoundedRectangle (coordsToRectangle (x, y, width, height), cornerSize); -} - -void Graphics::fillRoundedRectangle (const Rectangle& r, const float cornerSize) const -{ - Path p; - p.addRoundedRectangle (r, cornerSize); - fillPath (p); -} - -void Graphics::drawRoundedRectangle (float x, float y, float width, float height, - float cornerSize, float lineThickness) const -{ - drawRoundedRectangle (coordsToRectangle (x, y, width, height), cornerSize, lineThickness); -} - -void Graphics::drawRoundedRectangle (const Rectangle& r, float cornerSize, float lineThickness) const -{ - Path p; - p.addRoundedRectangle (r, cornerSize); - strokePath (p, PathStrokeType (lineThickness)); -} - -void Graphics::drawArrow (const Line& line, float lineThickness, float arrowheadWidth, float arrowheadLength) const -{ - Path p; - p.addArrow (line, lineThickness, arrowheadWidth, arrowheadLength); - fillPath (p); -} - -void Graphics::fillCheckerBoard (const Rectangle& area, - const int checkWidth, const int checkHeight, - Colour colour1, Colour colour2) const -{ - jassert (checkWidth > 0 && checkHeight > 0); // can't be zero or less! - - if (checkWidth > 0 && checkHeight > 0) - { - context.saveState(); - - if (colour1 == colour2) - { - context.setFill (colour1); - context.fillRect (area, false); - } - else - { - const Rectangle clipped (context.getClipBounds().getIntersection (area)); - - if (! clipped.isEmpty()) - { - context.clipToRectangle (clipped); - - const int checkNumX = (clipped.getX() - area.getX()) / checkWidth; - const int checkNumY = (clipped.getY() - area.getY()) / checkHeight; - const int startX = area.getX() + checkNumX * checkWidth; - const int startY = area.getY() + checkNumY * checkHeight; - const int right = clipped.getRight(); - const int bottom = clipped.getBottom(); - - for (int i = 0; i < 2; ++i) - { - context.setFill (i == ((checkNumX ^ checkNumY) & 1) ? colour1 : colour2); - - int cy = i; - for (int y = startY; y < bottom; y += checkHeight) - for (int x = startX + (cy++ & 1) * checkWidth; x < right; x += checkWidth * 2) - context.fillRect (Rectangle (x, y, checkWidth, checkHeight), false); - } - } - } - - context.restoreState(); - } -} - -//============================================================================== -void Graphics::drawVerticalLine (const int x, float top, float bottom) const -{ - if (top < bottom) - context.fillRect (Rectangle ((float) x, top, 1.0f, bottom - top)); -} - -void Graphics::drawHorizontalLine (const int y, float left, float right) const -{ - if (left < right) - context.fillRect (Rectangle (left, (float) y, right - left, 1.0f)); -} - -void Graphics::drawLine (const Line& line) const -{ - context.drawLine (line); -} - -void Graphics::drawLine (float x1, float y1, float x2, float y2) const -{ - context.drawLine (Line (x1, y1, x2, y2)); -} - -void Graphics::drawLine (float x1, float y1, float x2, float y2, float lineThickness) const -{ - drawLine (Line (x1, y1, x2, y2), lineThickness); -} - -void Graphics::drawLine (const Line& line, const float lineThickness) const -{ - Path p; - p.addLineSegment (line, lineThickness); - fillPath (p); -} - -void Graphics::drawDashedLine (const Line& line, const float* const dashLengths, - const int numDashLengths, const float lineThickness, int n) const -{ - jassert (n >= 0 && n < numDashLengths); // your start index must be valid! - - const Point delta ((line.getEnd() - line.getStart()).toDouble()); - const double totalLen = delta.getDistanceFromOrigin(); - - if (totalLen >= 0.1) - { - const double onePixAlpha = 1.0 / totalLen; - - for (double alpha = 0.0; alpha < 1.0;) - { - jassert (dashLengths[n] > 0); // can't have zero-length dashes! - - const double lastAlpha = alpha; - alpha += dashLengths [n] * onePixAlpha; - n = (n + 1) % numDashLengths; - - if ((n & 1) != 0) - { - const Line segment (line.getStart() + (delta * lastAlpha).toFloat(), - line.getStart() + (delta * jmin (1.0, alpha)).toFloat()); - - if (lineThickness != 1.0f) - drawLine (segment, lineThickness); - else - context.drawLine (segment); - } - } - } -} - -//============================================================================== -void Graphics::setImageResamplingQuality (const Graphics::ResamplingQuality newQuality) -{ - saveStateIfPending(); - context.setInterpolationQuality (newQuality); -} - -//============================================================================== -void Graphics::drawImageAt (const Image& imageToDraw, int x, int y, bool fillAlphaChannel) const -{ - drawImageTransformed (imageToDraw, - AffineTransform::translation ((float) x, (float) y), - fillAlphaChannel); -} - -void Graphics::drawImageWithin (const Image& imageToDraw, - int dx, int dy, int dw, int dh, - RectanglePlacement placementWithinTarget, - const bool fillAlphaChannelWithCurrentBrush) const -{ - if (imageToDraw.isValid()) - drawImageTransformed (imageToDraw, - placementWithinTarget.getTransformToFit (imageToDraw.getBounds().toFloat(), - coordsToRectangle (dx, dy, dw, dh).toFloat()), - fillAlphaChannelWithCurrentBrush); -} - -void Graphics::drawImage (const Image& imageToDraw, - int dx, int dy, int dw, int dh, - int sx, int sy, int sw, int sh, - const bool fillAlphaChannelWithCurrentBrush) const -{ - if (imageToDraw.isValid() && context.clipRegionIntersects (coordsToRectangle (dx, dy, dw, dh))) - drawImageTransformed (imageToDraw.getClippedImage (coordsToRectangle (sx, sy, sw, sh)), - AffineTransform::scale (dw / (float) sw, dh / (float) sh) - .translated ((float) dx, (float) dy), - fillAlphaChannelWithCurrentBrush); -} - -void Graphics::drawImageTransformed (const Image& imageToDraw, - const AffineTransform& transform, - const bool fillAlphaChannelWithCurrentBrush) const -{ - if (imageToDraw.isValid() && ! context.isClipEmpty()) - { - if (fillAlphaChannelWithCurrentBrush) - { - context.saveState(); - context.clipToImageAlpha (imageToDraw, transform); - fillAll(); - context.restoreState(); - } - else - { - context.drawImage (imageToDraw, transform); - } - } -} - -//============================================================================== -Graphics::ScopedSaveState::ScopedSaveState (Graphics& g) : context (g) -{ - context.saveState(); -} - -Graphics::ScopedSaveState::~ScopedSaveState() -{ - context.restoreState(); -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/contexts/juce_GraphicsContext.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/contexts/juce_GraphicsContext.h deleted file mode 100644 index ed0bc404b5..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/contexts/juce_GraphicsContext.h +++ /dev/null @@ -1,730 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_GRAPHICSCONTEXT_H_INCLUDED -#define JUCE_GRAPHICSCONTEXT_H_INCLUDED - - -//============================================================================== -/** - A graphics context, used for drawing a component or image. - - When a Component needs painting, a Graphics context is passed to its - Component::paint() method, and this you then call methods within this - object to actually draw the component's content. - - A Graphics can also be created from an image, to allow drawing directly onto - that image. - - @see Component::paint -*/ -class JUCE_API Graphics -{ -public: - //============================================================================== - /** Creates a Graphics object to draw directly onto the given image. - - The graphics object that is created will be set up to draw onto the image, - with the context's clipping area being the entire size of the image, and its - origin being the image's origin. To draw into a subsection of an image, use the - reduceClipRegion() and setOrigin() methods. - - Obviously you shouldn't delete the image before this context is deleted. - */ - explicit Graphics (const Image& imageToDrawOnto); - - /** Destructor. */ - ~Graphics(); - - //============================================================================== - /** Changes the current drawing colour. - - This sets the colour that will now be used for drawing operations - it also - sets the opacity to that of the colour passed-in. - - If a brush is being used when this method is called, the brush will be deselected, - and any subsequent drawing will be done with a solid colour brush instead. - - @see setOpacity - */ - void setColour (Colour newColour); - - /** Changes the opacity to use with the current colour. - - If a solid colour is being used for drawing, this changes its opacity - to this new value (i.e. it doesn't multiply the colour's opacity by this amount). - - If a gradient is being used, this will have no effect on it. - - A value of 0.0 is completely transparent, 1.0 is completely opaque. - */ - void setOpacity (float newOpacity); - - /** Sets the context to use a gradient for its fill pattern. - */ - void setGradientFill (const ColourGradient& gradient); - - /** Sets the context to use a tiled image pattern for filling. - Make sure that you don't delete this image while it's still being used by - this context! - */ - void setTiledImageFill (const Image& imageToUse, - int anchorX, int anchorY, - float opacity); - - /** Changes the current fill settings. - @see setColour, setGradientFill, setTiledImageFill - */ - void setFillType (const FillType& newFill); - - //============================================================================== - /** Changes the font to use for subsequent text-drawing functions. - - Note there's also a setFont (float, int) method to quickly change the size and - style of the current font. - - @see drawSingleLineText, drawMultiLineText, drawText, drawFittedText - */ - void setFont (const Font& newFont); - - /** Changes the size of the currently-selected font. - This is a convenient shortcut that changes the context's current font to a - different size. The typeface won't be changed. - @see Font - */ - void setFont (float newFontHeight); - - /** Returns the currently selected font. */ - Font getCurrentFont() const; - - /** Draws a one-line text string. - - This will use the current colour (or brush) to fill the text. The font is the last - one specified by setFont(). - - @param text the string to draw - @param startX the position to draw the left-hand edge of the text - @param baselineY the position of the text's baseline - @param justification the horizontal flags indicate which end of the text string is - anchored at the specified point. - @see drawMultiLineText, drawText, drawFittedText, GlyphArrangement::addLineOfText - */ - void drawSingleLineText (const String& text, - int startX, int baselineY, - Justification justification = Justification::left) const; - - /** Draws text across multiple lines. - - This will break the text onto a new line where there's a new-line or - carriage-return character, or at a word-boundary when the text becomes wider - than the size specified by the maximumLineWidth parameter. - - @see setFont, drawSingleLineText, drawFittedText, GlyphArrangement::addJustifiedText - */ - void drawMultiLineText (const String& text, - int startX, int baselineY, - int maximumLineWidth) const; - - /** Draws a line of text within a specified rectangle. - - The text will be positioned within the rectangle based on the justification - flags passed-in. If the string is too long to fit inside the rectangle, it will - either be truncated or will have ellipsis added to its end (if the useEllipsesIfTooBig - flag is true). - - @see drawSingleLineText, drawFittedText, drawMultiLineText, GlyphArrangement::addJustifiedText - */ - void drawText (const String& text, - int x, int y, int width, int height, - Justification justificationType, - bool useEllipsesIfTooBig = true) const; - - /** Draws a line of text within a specified rectangle. - - The text will be positioned within the rectangle based on the justification - flags passed-in. If the string is too long to fit inside the rectangle, it will - either be truncated or will have ellipsis added to its end (if the useEllipsesIfTooBig - flag is true). - - @see drawSingleLineText, drawFittedText, drawMultiLineText, GlyphArrangement::addJustifiedText - */ - void drawText (const String& text, - const Rectangle& area, - Justification justificationType, - bool useEllipsesIfTooBig = true) const; - - /** Draws a line of text within a specified rectangle. - - The text will be positioned within the rectangle based on the justification - flags passed-in. If the string is too long to fit inside the rectangle, it will - either be truncated or will have ellipsis added to its end (if the useEllipsesIfTooBig - flag is true). - - @see drawSingleLineText, drawFittedText, drawMultiLineText, GlyphArrangement::addJustifiedText - */ - void drawText (const String& text, - const Rectangle& area, - Justification justificationType, - bool useEllipsesIfTooBig = true) const; - - /** Tries to draw a text string inside a given space. - - This does its best to make the given text readable within the specified rectangle, - so it useful for labelling things. - - If the text is too big, it'll be squashed horizontally or broken over multiple lines - if the maximumLinesToUse value allows this. If the text just won't fit into the space, - it'll cram as much as possible in there, and put some ellipsis at the end to show that - it's been truncated. - - A Justification parameter lets you specify how the text is laid out within the rectangle, - both horizontally and vertically. - - The minimumHorizontalScale parameter specifies how much the text can be squashed horizontally - to try to squeeze it into the space. If you don't want any horizontal scaling to occur, you - can set this value to 1.0f. - - @see GlyphArrangement::addFittedText - */ - void drawFittedText (const String& text, - int x, int y, int width, int height, - Justification justificationFlags, - int maximumNumberOfLines, - float minimumHorizontalScale = 0.7f) const; - - /** Tries to draw a text string inside a given space. - - This does its best to make the given text readable within the specified rectangle, - so it useful for labelling things. - - If the text is too big, it'll be squashed horizontally or broken over multiple lines - if the maximumLinesToUse value allows this. If the text just won't fit into the space, - it'll cram as much as possible in there, and put some ellipsis at the end to show that - it's been truncated. - - A Justification parameter lets you specify how the text is laid out within the rectangle, - both horizontally and vertically. - - The minimumHorizontalScale parameter specifies how much the text can be squashed horizontally - to try to squeeze it into the space. If you don't want any horizontal scaling to occur, you - can set this value to 1.0f. - - @see GlyphArrangement::addFittedText - */ - void drawFittedText (const String& text, - const Rectangle& area, - Justification justificationFlags, - int maximumNumberOfLines, - float minimumHorizontalScale = 0.7f) const; - - //============================================================================== - /** Fills the context's entire clip region with the current colour or brush. - - (See also the fillAll (Colour) method which is a quick way of filling - it with a given colour). - */ - void fillAll() const; - - /** Fills the context's entire clip region with a given colour. - - This leaves the context's current colour and brush unchanged, it just - uses the specified colour temporarily. - */ - void fillAll (Colour colourToUse) const; - - //============================================================================== - /** Fills a rectangle with the current colour or brush. - @see drawRect, fillRoundedRectangle - */ - void fillRect (const Rectangle& rectangle) const; - - /** Fills a rectangle with the current colour or brush. - @see drawRect, fillRoundedRectangle - */ - void fillRect (const Rectangle& rectangle) const; - - /** Fills a rectangle with the current colour or brush. - @see drawRect, fillRoundedRectangle - */ - void fillRect (int x, int y, int width, int height) const; - - /** Fills a rectangle with the current colour or brush. - @see drawRect, fillRoundedRectangle - */ - void fillRect (float x, float y, float width, float height) const; - - /** Fills a set of rectangles using the current colour or brush. - If you have a lot of rectangles to draw, it may be more efficient - to create a RectangleList and use this method than to call fillRect() - multiple times. - */ - void fillRectList (const RectangleList& rectangles) const; - - /** Fills a set of rectangles using the current colour or brush. - If you have a lot of rectangles to draw, it may be more efficient - to create a RectangleList and use this method than to call fillRect() - multiple times. - */ - void fillRectList (const RectangleList& rectangles) const; - - /** Uses the current colour or brush to fill a rectangle with rounded corners. - @see drawRoundedRectangle, Path::addRoundedRectangle - */ - void fillRoundedRectangle (float x, float y, float width, float height, - float cornerSize) const; - - /** Uses the current colour or brush to fill a rectangle with rounded corners. - @see drawRoundedRectangle, Path::addRoundedRectangle - */ - void fillRoundedRectangle (const Rectangle& rectangle, - float cornerSize) const; - - /** Fills a rectangle with a checkerboard pattern, alternating between two colours. */ - void fillCheckerBoard (const Rectangle& area, - int checkWidth, int checkHeight, - Colour colour1, Colour colour2) const; - - /** Draws a rectangular outline, using the current colour or brush. - The lines are drawn inside the given rectangle, and greater line thicknesses extend inwards. - @see fillRect - */ - void drawRect (int x, int y, int width, int height, int lineThickness = 1) const; - - /** Draws a rectangular outline, using the current colour or brush. - The lines are drawn inside the given rectangle, and greater line thicknesses extend inwards. - @see fillRect - */ - void drawRect (float x, float y, float width, float height, float lineThickness = 1.0f) const; - - /** Draws a rectangular outline, using the current colour or brush. - The lines are drawn inside the given rectangle, and greater line thicknesses extend inwards. - @see fillRect - */ - void drawRect (const Rectangle& rectangle, int lineThickness = 1) const; - - /** Draws a rectangular outline, using the current colour or brush. - The lines are drawn inside the given rectangle, and greater line thicknesses extend inwards. - @see fillRect - */ - void drawRect (Rectangle rectangle, float lineThickness = 1.0f) const; - - /** Uses the current colour or brush to draw the outline of a rectangle with rounded corners. - @see fillRoundedRectangle, Path::addRoundedRectangle - */ - void drawRoundedRectangle (float x, float y, float width, float height, - float cornerSize, float lineThickness) const; - - /** Uses the current colour or brush to draw the outline of a rectangle with rounded corners. - @see fillRoundedRectangle, Path::addRoundedRectangle - */ - void drawRoundedRectangle (const Rectangle& rectangle, - float cornerSize, float lineThickness) const; - - /** Fills a 1x1 pixel using the current colour or brush. - Note that because the context may be transformed, this is effectively the same as - calling fillRect (x, y, 1, 1), and the actual result may involve multiple pixels. - */ - void setPixel (int x, int y) const; - - //============================================================================== - /** Fills an ellipse with the current colour or brush. - The ellipse is drawn to fit inside the given rectangle. - @see drawEllipse, Path::addEllipse - */ - void fillEllipse (float x, float y, float width, float height) const; - - /** Fills an ellipse with the current colour or brush. - The ellipse is drawn to fit inside the given rectangle. - @see drawEllipse, Path::addEllipse - */ - void fillEllipse (const Rectangle& area) const; - - /** Draws an elliptical stroke using the current colour or brush. - @see fillEllipse, Path::addEllipse - */ - void drawEllipse (float x, float y, float width, float height, - float lineThickness) const; - - /** Draws an elliptical stroke using the current colour or brush. - @see fillEllipse, Path::addEllipse - */ - void drawEllipse (const Rectangle& area, float lineThickness) const; - - //============================================================================== - /** Draws a line between two points. - The line is 1 pixel wide and drawn with the current colour or brush. - */ - void drawLine (float startX, float startY, float endX, float endY) const; - - /** Draws a line between two points with a given thickness. - @see Path::addLineSegment - */ - void drawLine (float startX, float startY, float endX, float endY, float lineThickness) const; - - /** Draws a line between two points. - The line is 1 pixel wide and drawn with the current colour or brush. - */ - void drawLine (const Line& line) const; - - /** Draws a line between two points with a given thickness. - @see Path::addLineSegment - */ - void drawLine (const Line& line, float lineThickness) const; - - /** Draws a dashed line using a custom set of dash-lengths. - - @param line the line to draw - @param dashLengths a series of lengths to specify the on/off lengths - e.g. - { 4, 5, 6, 7 } will draw a line of 4 pixels, skip 5 pixels, - draw 6 pixels, skip 7 pixels, and then repeat. - @param numDashLengths the number of elements in the array (this must be an even number). - @param lineThickness the thickness of the line to draw - @param dashIndexToStartFrom the index in the dash-length array to use for the first segment - @see PathStrokeType::createDashedStroke - */ - void drawDashedLine (const Line& line, - const float* dashLengths, int numDashLengths, - float lineThickness = 1.0f, - int dashIndexToStartFrom = 0) const; - - /** Draws a vertical line of pixels at a given x position. - - The x position is an integer, but the top and bottom of the line can be sub-pixel - positions, and these will be anti-aliased if necessary. - - The bottom parameter must be greater than or equal to the top parameter. - */ - void drawVerticalLine (int x, float top, float bottom) const; - - /** Draws a horizontal line of pixels at a given y position. - - The y position is an integer, but the left and right ends of the line can be sub-pixel - positions, and these will be anti-aliased if necessary. - - The right parameter must be greater than or equal to the left parameter. - */ - void drawHorizontalLine (int y, float left, float right) const; - - //============================================================================== - /** Fills a path using the currently selected colour or brush. */ - void fillPath (const Path& path, - const AffineTransform& transform = AffineTransform::identity) const; - - /** Draws a path's outline using the currently selected colour or brush. */ - void strokePath (const Path& path, - const PathStrokeType& strokeType, - const AffineTransform& transform = AffineTransform::identity) const; - - /** Draws a line with an arrowhead at its end. - - @param line the line to draw - @param lineThickness the thickness of the line - @param arrowheadWidth the width of the arrow head (perpendicular to the line) - @param arrowheadLength the length of the arrow head (along the length of the line) - */ - void drawArrow (const Line& line, - float lineThickness, - float arrowheadWidth, - float arrowheadLength) const; - - - //============================================================================== - /** Types of rendering quality that can be specified when drawing images. - - @see blendImage, Graphics::setImageResamplingQuality - */ - enum ResamplingQuality - { - lowResamplingQuality = 0, /**< Just uses a nearest-neighbour algorithm for resampling. */ - mediumResamplingQuality = 1, /**< Uses bilinear interpolation for upsampling and area-averaging for downsampling. */ - highResamplingQuality = 2 /**< Uses bicubic interpolation for upsampling and area-averaging for downsampling. */ - }; - - /** Changes the quality that will be used when resampling images. - By default a Graphics object will be set to mediumRenderingQuality. - @see Graphics::drawImage, Graphics::drawImageTransformed, Graphics::drawImageWithin - */ - void setImageResamplingQuality (const ResamplingQuality newQuality); - - /** Draws an image. - - This will draw the whole of an image, positioning its top-left corner at the - given coordinates, and keeping its size the same. This is the simplest image - drawing method - the others give more control over the scaling and clipping - of the images. - - Images are composited using the context's current opacity, so if you - don't want it to be drawn semi-transparently, be sure to call setOpacity (1.0f) - (or setColour() with an opaque colour) before drawing images. - */ - void drawImageAt (const Image& imageToDraw, int topLeftX, int topLeftY, - bool fillAlphaChannelWithCurrentBrush = false) const; - - /** Draws part of an image, rescaling it to fit in a given target region. - - The specified area of the source image is rescaled and drawn to fill the - specifed destination rectangle. - - Images are composited using the context's current opacity, so if you - don't want it to be drawn semi-transparently, be sure to call setOpacity (1.0f) - (or setColour() with an opaque colour) before drawing images. - - @param imageToDraw the image to overlay - @param destX the left of the destination rectangle - @param destY the top of the destination rectangle - @param destWidth the width of the destination rectangle - @param destHeight the height of the destination rectangle - @param sourceX the left of the rectangle to copy from the source image - @param sourceY the top of the rectangle to copy from the source image - @param sourceWidth the width of the rectangle to copy from the source image - @param sourceHeight the height of the rectangle to copy from the source image - @param fillAlphaChannelWithCurrentBrush if true, then instead of drawing the source image's pixels, - the source image's alpha channel is used as a mask with - which to fill the destination using the current colour - or brush. (If the source is has no alpha channel, then - it will just fill the target with a solid rectangle) - @see setImageResamplingQuality, drawImageAt, drawImageWithin, fillAlphaMap - */ - void drawImage (const Image& imageToDraw, - int destX, int destY, int destWidth, int destHeight, - int sourceX, int sourceY, int sourceWidth, int sourceHeight, - bool fillAlphaChannelWithCurrentBrush = false) const; - - /** Draws an image, having applied an affine transform to it. - - This lets you throw the image around in some wacky ways, rotate it, shear, - scale it, etc. - - Images are composited using the context's current opacity, so if you - don't want it to be drawn semi-transparently, be sure to call setOpacity (1.0f) - (or setColour() with an opaque colour) before drawing images. - - If fillAlphaChannelWithCurrentBrush is set to true, then the image's RGB channels - are ignored and it is filled with the current brush, masked by its alpha channel. - - If you want to render only a subsection of an image, use Image::getClippedImage() to - create the section that you need. - - @see setImageResamplingQuality, drawImage - */ - void drawImageTransformed (const Image& imageToDraw, - const AffineTransform& transform, - bool fillAlphaChannelWithCurrentBrush = false) const; - - /** Draws an image to fit within a designated rectangle. - - If the image is too big or too small for the space, it will be rescaled - to fit as nicely as it can do without affecting its aspect ratio. It will - then be placed within the target rectangle according to the justification flags - specified. - - @param imageToDraw the source image to draw - @param destX top-left of the target rectangle to fit it into - @param destY top-left of the target rectangle to fit it into - @param destWidth size of the target rectangle to fit the image into - @param destHeight size of the target rectangle to fit the image into - @param placementWithinTarget this specifies how the image should be positioned - within the target rectangle - see the RectanglePlacement - class for more details about this. - @param fillAlphaChannelWithCurrentBrush if true, then instead of drawing the image, just its - alpha channel will be used as a mask with which to - draw with the current brush or colour. This is - similar to fillAlphaMap(), and see also drawImage() - @see setImageResamplingQuality, drawImage, drawImageTransformed, drawImageAt, RectanglePlacement - */ - void drawImageWithin (const Image& imageToDraw, - int destX, int destY, int destWidth, int destHeight, - RectanglePlacement placementWithinTarget, - bool fillAlphaChannelWithCurrentBrush = false) const; - - - //============================================================================== - /** Returns the position of the bounding box for the current clipping region. - @see getClipRegion, clipRegionIntersects - */ - Rectangle getClipBounds() const; - - /** Checks whether a rectangle overlaps the context's clipping region. - - If this returns false, no part of the given area can be drawn onto, so this - method can be used to optimise a component's paint() method, by letting it - avoid drawing complex objects that aren't within the region being repainted. - */ - bool clipRegionIntersects (const Rectangle& area) const; - - /** Intersects the current clipping region with another region. - - @returns true if the resulting clipping region is non-zero in size - @see setOrigin, clipRegionIntersects - */ - bool reduceClipRegion (int x, int y, int width, int height); - - /** Intersects the current clipping region with another region. - - @returns true if the resulting clipping region is non-zero in size - @see setOrigin, clipRegionIntersects - */ - bool reduceClipRegion (const Rectangle& area); - - /** Intersects the current clipping region with a rectangle list region. - - @returns true if the resulting clipping region is non-zero in size - @see setOrigin, clipRegionIntersects - */ - bool reduceClipRegion (const RectangleList& clipRegion); - - /** Intersects the current clipping region with a path. - - @returns true if the resulting clipping region is non-zero in size - @see reduceClipRegion - */ - bool reduceClipRegion (const Path& path, const AffineTransform& transform = AffineTransform::identity); - - /** Intersects the current clipping region with an image's alpha-channel. - - The current clipping path is intersected with the area covered by this image's - alpha-channel, after the image has been transformed by the specified matrix. - - @param image the image whose alpha-channel should be used. If the image doesn't - have an alpha-channel, it is treated as entirely opaque. - @param transform a matrix to apply to the image - @returns true if the resulting clipping region is non-zero in size - @see reduceClipRegion - */ - bool reduceClipRegion (const Image& image, const AffineTransform& transform); - - /** Excludes a rectangle to stop it being drawn into. */ - void excludeClipRegion (const Rectangle& rectangleToExclude); - - /** Returns true if no drawing can be done because the clip region is zero. */ - bool isClipEmpty() const; - - //============================================================================== - /** Saves the current graphics state on an internal stack. - To restore the state, use restoreState(). - @see ScopedSaveState - */ - void saveState(); - - /** Restores a graphics state that was previously saved with saveState(). - @see ScopedSaveState - */ - void restoreState(); - - /** Uses RAII to save and restore the state of a graphics context. - On construction, this calls Graphics::saveState(), and on destruction it calls - Graphics::restoreState() on the Graphics object that you supply. - */ - class ScopedSaveState - { - public: - ScopedSaveState (Graphics&); - ~ScopedSaveState(); - - private: - Graphics& context; - JUCE_DECLARE_NON_COPYABLE (ScopedSaveState) - }; - - //============================================================================== - /** Begins rendering to an off-screen bitmap which will later be flattened onto the current - context with the given opacity. - - The context uses an internal stack of temporary image layers to do this. When you've - finished drawing to the layer, call endTransparencyLayer() to complete the operation and - composite the finished layer. Every call to beginTransparencyLayer() MUST be matched - by a corresponding call to endTransparencyLayer()! - - This call also saves the current state, and endTransparencyLayer() restores it. - */ - void beginTransparencyLayer (float layerOpacity); - - /** Completes a drawing operation to a temporary semi-transparent buffer. - See beginTransparencyLayer() for more details. - */ - void endTransparencyLayer(); - - /** Moves the position of the context's origin. - - This changes the position that the context considers to be (0, 0) to - the specified position. - - So if you call setOrigin with (100, 100), then the position that was previously - referred to as (100, 100) will subsequently be considered to be (0, 0). - - @see reduceClipRegion, addTransform - */ - void setOrigin (Point newOrigin); - - /** Moves the position of the context's origin. - - This changes the position that the context considers to be (0, 0) to - the specified position. - - So if you call setOrigin (100, 100), then the position that was previously - referred to as (100, 100) will subsequently be considered to be (0, 0). - - @see reduceClipRegion, addTransform - */ - void setOrigin (int newOriginX, int newOriginY); - - /** Adds a transformation which will be performed on all the graphics operations that - the context subsequently performs. - - After calling this, all the coordinates that are passed into the context will be - transformed by this matrix. - - @see setOrigin - */ - void addTransform (const AffineTransform& transform); - - /** Resets the current colour, brush, and font to default settings. */ - void resetToDefaultState(); - - /** Returns true if this context is drawing to a vector-based device, such as a printer. */ - bool isVectorDevice() const; - - //============================================================================== - /** Create a graphics that draws with a given low-level renderer. - This method is intended for use only by people who know what they're doing. - Note that the LowLevelGraphicsContext will NOT be deleted by this object. - */ - Graphics (LowLevelGraphicsContext&) noexcept; - - /** @internal */ - LowLevelGraphicsContext& getInternalContext() const noexcept { return context; } - -private: - //============================================================================== - LowLevelGraphicsContext& context; - ScopedPointer contextToDelete; - - bool saveStatePending; - void saveStateIfPending(); - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Graphics) -}; - - -#endif // JUCE_GRAPHICSCONTEXT_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/contexts/juce_LowLevelGraphicsContext.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/contexts/juce_LowLevelGraphicsContext.h deleted file mode 100644 index 8a0176f8a3..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/contexts/juce_LowLevelGraphicsContext.h +++ /dev/null @@ -1,101 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_LOWLEVELGRAPHICSCONTEXT_H_INCLUDED -#define JUCE_LOWLEVELGRAPHICSCONTEXT_H_INCLUDED - - -//============================================================================== -/** - Interface class for graphics context objects, used internally by the Graphics class. - - Users are not supposed to create instances of this class directly - do your drawing - via the Graphics object instead. - - It's a base class for different types of graphics context, that may perform software-based - or OS-accelerated rendering. - - E.g. the LowLevelGraphicsSoftwareRenderer renders onto an image in memory, but other - subclasses could render directly to a windows HDC, a Quartz context, or an OpenGL - context. -*/ -class JUCE_API LowLevelGraphicsContext -{ -protected: - //============================================================================== - LowLevelGraphicsContext(); - -public: - virtual ~LowLevelGraphicsContext(); - - /** Returns true if this device is vector-based, e.g. a printer. */ - virtual bool isVectorDevice() const = 0; - - //============================================================================== - /** Moves the origin to a new position. - - The coordinates are relative to the current origin, and indicate the new position - of (0, 0). - */ - virtual void setOrigin (Point) = 0; - virtual void addTransform (const AffineTransform&) = 0; - virtual float getPhysicalPixelScaleFactor() = 0; - - virtual bool clipToRectangle (const Rectangle&) = 0; - virtual bool clipToRectangleList (const RectangleList&) = 0; - virtual void excludeClipRectangle (const Rectangle&) = 0; - virtual void clipToPath (const Path&, const AffineTransform&) = 0; - virtual void clipToImageAlpha (const Image&, const AffineTransform&) = 0; - - virtual bool clipRegionIntersects (const Rectangle&) = 0; - virtual Rectangle getClipBounds() const = 0; - virtual bool isClipEmpty() const = 0; - - virtual void saveState() = 0; - virtual void restoreState() = 0; - - virtual void beginTransparencyLayer (float opacity) = 0; - virtual void endTransparencyLayer() = 0; - - //============================================================================== - virtual void setFill (const FillType&) = 0; - virtual void setOpacity (float) = 0; - virtual void setInterpolationQuality (Graphics::ResamplingQuality) = 0; - - //============================================================================== - virtual void fillRect (const Rectangle&, bool replaceExistingContents) = 0; - virtual void fillRect (const Rectangle&) = 0; - virtual void fillRectList (const RectangleList&) = 0; - virtual void fillPath (const Path&, const AffineTransform&) = 0; - virtual void drawImage (const Image&, const AffineTransform&) = 0; - virtual void drawLine (const Line&) = 0; - - virtual void setFont (const Font&) = 0; - virtual const Font& getFont() = 0; - virtual void drawGlyph (int glyphNumber, const AffineTransform&) = 0; - virtual bool drawTextLayout (const AttributedString&, const Rectangle&) { return false; } -}; - - -#endif // JUCE_LOWLEVELGRAPHICSCONTEXT_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/contexts/juce_LowLevelGraphicsPostScriptRenderer.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/contexts/juce_LowLevelGraphicsPostScriptRenderer.cpp deleted file mode 100644 index d963ed640e..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/contexts/juce_LowLevelGraphicsPostScriptRenderer.cpp +++ /dev/null @@ -1,533 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -// this will throw an assertion if you try to draw something that's not -// possible in postscript -#define WARN_ABOUT_NON_POSTSCRIPT_OPERATIONS 0 - -//============================================================================== -#if JUCE_DEBUG && WARN_ABOUT_NON_POSTSCRIPT_OPERATIONS - #define notPossibleInPostscriptAssert jassertfalse -#else - #define notPossibleInPostscriptAssert -#endif - -//============================================================================== -LowLevelGraphicsPostScriptRenderer::LowLevelGraphicsPostScriptRenderer (OutputStream& resultingPostScript, - const String& documentTitle, - const int totalWidth_, - const int totalHeight_) - : out (resultingPostScript), - totalWidth (totalWidth_), - totalHeight (totalHeight_), - needToClip (true) -{ - stateStack.add (new SavedState()); - stateStack.getLast()->clip = Rectangle (totalWidth_, totalHeight_); - - const float scale = jmin ((520.0f / totalWidth_), (750.0f / totalHeight)); - - out << "%!PS-Adobe-3.0 EPSF-3.0" - "\n%%BoundingBox: 0 0 600 824" - "\n%%Pages: 0" - "\n%%Creator: Raw Material Software JUCE" - "\n%%Title: " << documentTitle << - "\n%%CreationDate: none" - "\n%%LanguageLevel: 2" - "\n%%EndComments" - "\n%%BeginProlog" - "\n%%BeginResource: JRes" - "\n/bd {bind def} bind def" - "\n/c {setrgbcolor} bd" - "\n/m {moveto} bd" - "\n/l {lineto} bd" - "\n/rl {rlineto} bd" - "\n/ct {curveto} bd" - "\n/cp {closepath} bd" - "\n/pr {3 index 3 index moveto 1 index 0 rlineto 0 1 index rlineto pop neg 0 rlineto pop pop closepath} bd" - "\n/doclip {initclip newpath} bd" - "\n/endclip {clip newpath} bd" - "\n%%EndResource" - "\n%%EndProlog" - "\n%%BeginSetup" - "\n%%EndSetup" - "\n%%Page: 1 1" - "\n%%BeginPageSetup" - "\n%%EndPageSetup\n\n" - << "40 800 translate\n" - << scale << ' ' << scale << " scale\n\n"; -} - -LowLevelGraphicsPostScriptRenderer::~LowLevelGraphicsPostScriptRenderer() -{ -} - -//============================================================================== -bool LowLevelGraphicsPostScriptRenderer::isVectorDevice() const -{ - return true; -} - -void LowLevelGraphicsPostScriptRenderer::setOrigin (Point o) -{ - if (! o.isOrigin()) - { - stateStack.getLast()->xOffset += o.x; - stateStack.getLast()->yOffset += o.y; - needToClip = true; - } -} - -void LowLevelGraphicsPostScriptRenderer::addTransform (const AffineTransform& /*transform*/) -{ - //xxx - jassertfalse; -} - -float LowLevelGraphicsPostScriptRenderer::getPhysicalPixelScaleFactor() { return 1.0f; } - -bool LowLevelGraphicsPostScriptRenderer::clipToRectangle (const Rectangle& r) -{ - needToClip = true; - return stateStack.getLast()->clip.clipTo (r.translated (stateStack.getLast()->xOffset, stateStack.getLast()->yOffset)); -} - -bool LowLevelGraphicsPostScriptRenderer::clipToRectangleList (const RectangleList& clipRegion) -{ - needToClip = true; - return stateStack.getLast()->clip.clipTo (clipRegion); -} - -void LowLevelGraphicsPostScriptRenderer::excludeClipRectangle (const Rectangle& r) -{ - needToClip = true; - stateStack.getLast()->clip.subtract (r.translated (stateStack.getLast()->xOffset, stateStack.getLast()->yOffset)); -} - -void LowLevelGraphicsPostScriptRenderer::clipToPath (const Path& path, const AffineTransform& transform) -{ - writeClip(); - - Path p (path); - p.applyTransform (transform.translated ((float) stateStack.getLast()->xOffset, (float) stateStack.getLast()->yOffset)); - writePath (p); - out << "clip\n"; -} - -void LowLevelGraphicsPostScriptRenderer::clipToImageAlpha (const Image& /*sourceImage*/, const AffineTransform& /*transform*/) -{ - needToClip = true; - jassertfalse; // xxx -} - -bool LowLevelGraphicsPostScriptRenderer::clipRegionIntersects (const Rectangle& r) -{ - return stateStack.getLast()->clip.intersectsRectangle (r.translated (stateStack.getLast()->xOffset, stateStack.getLast()->yOffset)); -} - -Rectangle LowLevelGraphicsPostScriptRenderer::getClipBounds() const -{ - return stateStack.getLast()->clip.getBounds().translated (-stateStack.getLast()->xOffset, - -stateStack.getLast()->yOffset); -} - -bool LowLevelGraphicsPostScriptRenderer::isClipEmpty() const -{ - return stateStack.getLast()->clip.isEmpty(); -} - -//============================================================================== -LowLevelGraphicsPostScriptRenderer::SavedState::SavedState() - : xOffset (0), - yOffset (0) -{ -} - -LowLevelGraphicsPostScriptRenderer::SavedState::~SavedState() -{ -} - -void LowLevelGraphicsPostScriptRenderer::saveState() -{ - stateStack.add (new SavedState (*stateStack.getLast())); -} - -void LowLevelGraphicsPostScriptRenderer::restoreState() -{ - jassert (stateStack.size() > 0); - - if (stateStack.size() > 0) - stateStack.removeLast(); -} - -void LowLevelGraphicsPostScriptRenderer::beginTransparencyLayer (float) -{ -} - -void LowLevelGraphicsPostScriptRenderer::endTransparencyLayer() -{ -} - -//============================================================================== -void LowLevelGraphicsPostScriptRenderer::writeClip() -{ - if (needToClip) - { - needToClip = false; - - out << "doclip "; - - int itemsOnLine = 0; - - for (const Rectangle* i = stateStack.getLast()->clip.begin(), * const e = stateStack.getLast()->clip.end(); i != e; ++i) - { - if (++itemsOnLine == 6) - { - itemsOnLine = 0; - out << '\n'; - } - - out << i->getX() << ' ' << -i->getY() << ' ' - << i->getWidth() << ' ' << -i->getHeight() << " pr "; - } - - out << "endclip\n"; - } -} - -void LowLevelGraphicsPostScriptRenderer::writeColour (Colour colour) -{ - Colour c (Colours::white.overlaidWith (colour)); - - if (lastColour != c) - { - lastColour = c; - - out << String (c.getFloatRed(), 3) << ' ' - << String (c.getFloatGreen(), 3) << ' ' - << String (c.getFloatBlue(), 3) << " c\n"; - } -} - -void LowLevelGraphicsPostScriptRenderer::writeXY (const float x, const float y) const -{ - out << String (x, 2) << ' ' - << String (-y, 2) << ' '; -} - -void LowLevelGraphicsPostScriptRenderer::writePath (const Path& path) const -{ - out << "newpath "; - - float lastX = 0.0f; - float lastY = 0.0f; - int itemsOnLine = 0; - - Path::Iterator i (path); - - while (i.next()) - { - if (++itemsOnLine == 4) - { - itemsOnLine = 0; - out << '\n'; - } - - switch (i.elementType) - { - case Path::Iterator::startNewSubPath: - writeXY (i.x1, i.y1); - lastX = i.x1; - lastY = i.y1; - out << "m "; - break; - - case Path::Iterator::lineTo: - writeXY (i.x1, i.y1); - lastX = i.x1; - lastY = i.y1; - out << "l "; - break; - - case Path::Iterator::quadraticTo: - { - const float cp1x = lastX + (i.x1 - lastX) * 2.0f / 3.0f; - const float cp1y = lastY + (i.y1 - lastY) * 2.0f / 3.0f; - const float cp2x = cp1x + (i.x2 - lastX) / 3.0f; - const float cp2y = cp1y + (i.y2 - lastY) / 3.0f; - - writeXY (cp1x, cp1y); - writeXY (cp2x, cp2y); - writeXY (i.x2, i.y2); - out << "ct "; - lastX = i.x2; - lastY = i.y2; - } - break; - - case Path::Iterator::cubicTo: - writeXY (i.x1, i.y1); - writeXY (i.x2, i.y2); - writeXY (i.x3, i.y3); - out << "ct "; - lastX = i.x3; - lastY = i.y3; - break; - - case Path::Iterator::closePath: - out << "cp "; - break; - - default: - jassertfalse; - break; - } - } - - out << '\n'; -} - -void LowLevelGraphicsPostScriptRenderer::writeTransform (const AffineTransform& trans) const -{ - out << "[ " - << trans.mat00 << ' ' - << trans.mat10 << ' ' - << trans.mat01 << ' ' - << trans.mat11 << ' ' - << trans.mat02 << ' ' - << trans.mat12 << " ] concat "; -} - -//============================================================================== -void LowLevelGraphicsPostScriptRenderer::setFill (const FillType& fillType) -{ - stateStack.getLast()->fillType = fillType; -} - -void LowLevelGraphicsPostScriptRenderer::setOpacity (float /*opacity*/) -{ -} - -void LowLevelGraphicsPostScriptRenderer::setInterpolationQuality (Graphics::ResamplingQuality /*quality*/) -{ -} - -//============================================================================== -void LowLevelGraphicsPostScriptRenderer::fillRect (const Rectangle& r, const bool /*replaceExistingContents*/) -{ - fillRect (r.toFloat()); -} - -void LowLevelGraphicsPostScriptRenderer::fillRect (const Rectangle& r) -{ - if (stateStack.getLast()->fillType.isColour()) - { - writeClip(); - writeColour (stateStack.getLast()->fillType.colour); - - Rectangle r2 (r.translated ((float) stateStack.getLast()->xOffset, - (float) stateStack.getLast()->yOffset)); - - out << r2.getX() << ' ' << -r2.getBottom() << ' ' << r2.getWidth() << ' ' << r2.getHeight() << " rectfill\n"; - } - else - { - Path p; - p.addRectangle (r); - fillPath (p, AffineTransform::identity); - } -} - -void LowLevelGraphicsPostScriptRenderer::fillRectList (const RectangleList& list) -{ - fillPath (list.toPath(), AffineTransform::identity); -} - -//============================================================================== -void LowLevelGraphicsPostScriptRenderer::fillPath (const Path& path, const AffineTransform& t) -{ - if (stateStack.getLast()->fillType.isColour()) - { - writeClip(); - - Path p (path); - p.applyTransform (t.translated ((float) stateStack.getLast()->xOffset, - (float) stateStack.getLast()->yOffset)); - writePath (p); - - writeColour (stateStack.getLast()->fillType.colour); - - out << "fill\n"; - } - else if (stateStack.getLast()->fillType.isGradient()) - { - // this doesn't work correctly yet - it could be improved to handle solid gradients, but - // postscript can't do semi-transparent ones. - notPossibleInPostscriptAssert; // you can disable this warning by setting the WARN_ABOUT_NON_POSTSCRIPT_OPERATIONS flag at the top of this file - - writeClip(); - out << "gsave "; - - { - Path p (path); - p.applyTransform (t.translated ((float) stateStack.getLast()->xOffset, (float) stateStack.getLast()->yOffset)); - writePath (p); - out << "clip\n"; - } - - const Rectangle bounds (stateStack.getLast()->clip.getBounds()); - - // ideally this would draw lots of lines or ellipses to approximate the gradient, but for the - // time-being, this just fills it with the average colour.. - writeColour (stateStack.getLast()->fillType.gradient->getColourAtPosition (0.5f)); - out << bounds.getX() << ' ' << -bounds.getBottom() << ' ' << bounds.getWidth() << ' ' << bounds.getHeight() << " rectfill\n"; - - out << "grestore\n"; - } -} - -//============================================================================== -void LowLevelGraphicsPostScriptRenderer::writeImage (const Image& im, - const int sx, const int sy, - const int maxW, const int maxH) const -{ - out << "{<\n"; - - const int w = jmin (maxW, im.getWidth()); - const int h = jmin (maxH, im.getHeight()); - - int charsOnLine = 0; - const Image::BitmapData srcData (im, 0, 0, w, h); - Colour pixel; - - for (int y = h; --y >= 0;) - { - for (int x = 0; x < w; ++x) - { - const uint8* pixelData = srcData.getPixelPointer (x, y); - - if (x >= sx && y >= sy) - { - if (im.isARGB()) - { - PixelARGB p (*(const PixelARGB*) pixelData); - p.unpremultiply(); - pixel = Colours::white.overlaidWith (Colour (p.getARGB())); - } - else if (im.isRGB()) - { - pixel = Colour (((const PixelRGB*) pixelData)->getARGB()); - } - else - { - pixel = Colour ((uint8) 0, (uint8) 0, (uint8) 0, *pixelData); - } - } - else - { - pixel = Colours::transparentWhite; - } - - const uint8 pixelValues[3] = { pixel.getRed(), pixel.getGreen(), pixel.getBlue() }; - - out << String::toHexString (pixelValues, 3, 0); - charsOnLine += 3; - - if (charsOnLine > 100) - { - out << '\n'; - charsOnLine = 0; - } - } - } - - out << "\n>}\n"; -} - -void LowLevelGraphicsPostScriptRenderer::drawImage (const Image& sourceImage, const AffineTransform& transform) -{ - const int w = sourceImage.getWidth(); - const int h = sourceImage.getHeight(); - - writeClip(); - - out << "gsave "; - writeTransform (transform.translated ((float) stateStack.getLast()->xOffset, (float) stateStack.getLast()->yOffset) - .scaled (1.0f, -1.0f)); - - RectangleList imageClip; - sourceImage.createSolidAreaMask (imageClip, 0.5f); - - out << "newpath "; - int itemsOnLine = 0; - - for (const Rectangle* i = imageClip.begin(), * const e = imageClip.end(); i != e; ++i) - { - if (++itemsOnLine == 6) - { - out << '\n'; - itemsOnLine = 0; - } - - out << i->getX() << ' ' << i->getY() << ' ' << i->getWidth() << ' ' << i->getHeight() << " pr "; - } - - out << " clip newpath\n"; - - out << w << ' ' << h << " scale\n"; - out << w << ' ' << h << " 8 [" << w << " 0 0 -" << h << ' ' << (int) 0 << ' ' << h << " ]\n"; - - writeImage (sourceImage, 0, 0, w, h); - - out << "false 3 colorimage grestore\n"; - needToClip = true; -} - - -//============================================================================== -void LowLevelGraphicsPostScriptRenderer::drawLine (const Line & line) -{ - Path p; - p.addLineSegment (line, 1.0f); - fillPath (p, AffineTransform::identity); -} - -//============================================================================== -void LowLevelGraphicsPostScriptRenderer::setFont (const Font& newFont) -{ - stateStack.getLast()->font = newFont; -} - -const Font& LowLevelGraphicsPostScriptRenderer::getFont() -{ - return stateStack.getLast()->font; -} - -void LowLevelGraphicsPostScriptRenderer::drawGlyph (int glyphNumber, const AffineTransform& transform) -{ - Path p; - Font& font = stateStack.getLast()->font; - font.getTypeface()->getOutlineForGlyph (glyphNumber, p); - fillPath (p, AffineTransform::scale (font.getHeight() * font.getHorizontalScale(), font.getHeight()).followedBy (transform)); -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/contexts/juce_LowLevelGraphicsPostScriptRenderer.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/contexts/juce_LowLevelGraphicsPostScriptRenderer.h deleted file mode 100644 index 2b893a3606..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/contexts/juce_LowLevelGraphicsPostScriptRenderer.h +++ /dev/null @@ -1,121 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_LOWLEVELGRAPHICSPOSTSCRIPTRENDERER_H_INCLUDED -#define JUCE_LOWLEVELGRAPHICSPOSTSCRIPTRENDERER_H_INCLUDED - - -//============================================================================== -/** - An implementation of LowLevelGraphicsContext that turns the drawing operations - into a PostScript document. - -*/ -class JUCE_API LowLevelGraphicsPostScriptRenderer : public LowLevelGraphicsContext -{ -public: - //============================================================================== - LowLevelGraphicsPostScriptRenderer (OutputStream& resultingPostScript, - const String& documentTitle, - int totalWidth, - int totalHeight); - - ~LowLevelGraphicsPostScriptRenderer(); - - //============================================================================== - bool isVectorDevice() const override; - void setOrigin (Point) override; - void addTransform (const AffineTransform&) override; - float getPhysicalPixelScaleFactor() override; - - bool clipToRectangle (const Rectangle&) override; - bool clipToRectangleList (const RectangleList&) override; - void excludeClipRectangle (const Rectangle&) override; - void clipToPath (const Path&, const AffineTransform&) override; - void clipToImageAlpha (const Image&, const AffineTransform&) override; - - void saveState() override; - void restoreState() override; - - void beginTransparencyLayer (float) override; - void endTransparencyLayer() override; - - bool clipRegionIntersects (const Rectangle&) override; - Rectangle getClipBounds() const override; - bool isClipEmpty() const override; - - //============================================================================== - void setFill (const FillType&) override; - void setOpacity (float) override; - void setInterpolationQuality (Graphics::ResamplingQuality) override; - - //============================================================================== - void fillRect (const Rectangle&, bool replaceExistingContents) override; - void fillRect (const Rectangle&) override; - void fillRectList (const RectangleList&) override; - void fillPath (const Path&, const AffineTransform&) override; - void drawImage (const Image&, const AffineTransform&) override; - void drawLine (const Line &) override; - - //============================================================================== - const Font& getFont() override; - void setFont (const Font&) override; - void drawGlyph (int glyphNumber, const AffineTransform&) override; - -protected: - //============================================================================== - OutputStream& out; - int totalWidth, totalHeight; - bool needToClip; - Colour lastColour; - - struct SavedState - { - SavedState(); - ~SavedState(); - - RectangleList clip; - int xOffset, yOffset; - FillType fillType; - Font font; - - private: - SavedState& operator= (const SavedState&); - }; - - OwnedArray stateStack; - - void writeClip(); - void writeColour (Colour colour); - void writePath (const Path&) const; - void writeXY (float x, float y) const; - void writeTransform (const AffineTransform&) const; - void writeImage (const Image&, int sx, int sy, int maxW, int maxH) const; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (LowLevelGraphicsPostScriptRenderer) -}; - - - -#endif // JUCE_LOWLEVELGRAPHICSPOSTSCRIPTRENDERER_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.cpp deleted file mode 100644 index a57e4d62d7..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.cpp +++ /dev/null @@ -1,38 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -LowLevelGraphicsSoftwareRenderer::LowLevelGraphicsSoftwareRenderer (const Image& image) - : RenderingHelpers::StackBasedLowLevelGraphicsContext - (new RenderingHelpers::SoftwareRendererSavedState (image, image.getBounds())) -{ -} - -LowLevelGraphicsSoftwareRenderer::LowLevelGraphicsSoftwareRenderer (const Image& image, Point origin, - const RectangleList& initialClip) - : RenderingHelpers::StackBasedLowLevelGraphicsContext - (new RenderingHelpers::SoftwareRendererSavedState (image, initialClip, origin)) -{ -} - -LowLevelGraphicsSoftwareRenderer::~LowLevelGraphicsSoftwareRenderer() {} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.h deleted file mode 100644 index 9928092cab..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_LOWLEVELGRAPHICSSOFTWARERENDERER_H_INCLUDED -#define JUCE_LOWLEVELGRAPHICSSOFTWARERENDERER_H_INCLUDED - - -//============================================================================== -/** - A lowest-common-denominator implementation of LowLevelGraphicsContext that does all - its rendering in memory. - - User code is not supposed to create instances of this class directly - do all your - rendering via the Graphics class instead. -*/ -class JUCE_API LowLevelGraphicsSoftwareRenderer : public RenderingHelpers::StackBasedLowLevelGraphicsContext -{ -public: - //============================================================================== - /** Creates a context to render into an image. */ - LowLevelGraphicsSoftwareRenderer (const Image& imageToRenderOnto); - - /** Creates a context to render into a clipped subsection of an image. */ - LowLevelGraphicsSoftwareRenderer (const Image& imageToRenderOnto, Point origin, - const RectangleList& initialClip); - - /** Destructor. */ - ~LowLevelGraphicsSoftwareRenderer(); - -private: - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (LowLevelGraphicsSoftwareRenderer) -}; - - -#endif // JUCE_LOWLEVELGRAPHICSSOFTWARERENDERER_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/effects/juce_DropShadowEffect.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/effects/juce_DropShadowEffect.cpp deleted file mode 100644 index 448fab8760..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/effects/juce_DropShadowEffect.cpp +++ /dev/null @@ -1,182 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -static inline void blurDataTriplets (uint8* d, int num, const int delta) noexcept -{ - uint32 last = d[0]; - d[0] = (uint8) ((d[0] + d[delta] + 1) / 3); - d += delta; - - num -= 2; - - do - { - const uint32 newLast = d[0]; - d[0] = (uint8) ((last + d[0] + d[delta] + 1) / 3); - d += delta; - last = newLast; - } - while (--num > 0); - - d[0] = (uint8) ((last + d[0] + 1) / 3); -} - -static void blurSingleChannelImage (uint8* const data, const int width, const int height, - const int lineStride, const int repetitions) noexcept -{ - jassert (width > 2 && height > 2); - - for (int y = 0; y < height; ++y) - for (int i = repetitions; --i >= 0;) - blurDataTriplets (data + lineStride * y, width, 1); - - for (int x = 0; x < width; ++x) - for (int i = repetitions; --i >= 0;) - blurDataTriplets (data + x, height, lineStride); -} - -static void blurSingleChannelImage (Image& image, int radius) -{ - const Image::BitmapData bm (image, Image::BitmapData::readWrite); - blurSingleChannelImage (bm.data, bm.width, bm.height, bm.lineStride, 2 * radius); -} - -//============================================================================== -DropShadow::DropShadow() noexcept - : colour (0x90000000), radius (4) -{ -} - -DropShadow::DropShadow (Colour shadowColour, const int r, Point o) noexcept - : colour (shadowColour), radius (r), offset (o) -{ - jassert (radius > 0); -} - -void DropShadow::drawForImage (Graphics& g, const Image& srcImage) const -{ - jassert (radius > 0); - - if (srcImage.isValid()) - { - Image shadowImage (srcImage.convertedToFormat (Image::SingleChannel)); - shadowImage.duplicateIfShared(); - - blurSingleChannelImage (shadowImage, radius); - - g.setColour (colour); - g.drawImageAt (shadowImage, offset.x, offset.y, true); - } -} - -void DropShadow::drawForPath (Graphics& g, const Path& path) const -{ - jassert (radius > 0); - - const Rectangle area ((path.getBounds().getSmallestIntegerContainer() + offset) - .expanded (radius + 1) - .getIntersection (g.getClipBounds().expanded (radius + 1))); - - if (area.getWidth() > 2 && area.getHeight() > 2) - { - Image renderedPath (Image::SingleChannel, area.getWidth(), area.getHeight(), true); - - { - Graphics g2 (renderedPath); - g2.setColour (Colours::white); - g2.fillPath (path, AffineTransform::translation ((float) (offset.x - area.getX()), - (float) (offset.y - area.getY()))); - } - - blurSingleChannelImage (renderedPath, radius); - - g.setColour (colour); - g.drawImageAt (renderedPath, area.getX(), area.getY(), true); - } -} - -static void drawShadowSection (Graphics& g, ColourGradient& cg, const Rectangle& area, - bool isCorner, float centreX, float centreY, float edgeX, float edgeY) -{ - cg.point1 = area.getRelativePoint (centreX, centreY).toFloat(); - cg.point2 = area.getRelativePoint (edgeX, edgeY).toFloat(); - cg.isRadial = isCorner; - - g.setGradientFill (cg); - g.fillRect (area); -} - -void DropShadow::drawForRectangle (Graphics& g, const Rectangle& targetArea) const -{ - ColourGradient cg (colour, 0, 0, colour.withAlpha (0.0f), 0, 0, false); - - for (float i = 0.05f; i < 1.0f; i += 0.1f) - cg.addColour (1.0 - i, colour.withMultipliedAlpha (i * i)); - - const int radiusInset = (radius + 1) / 2; - const int expandedRadius = radius + radiusInset; - - const Rectangle area (targetArea.reduced (radiusInset) + offset); - - Rectangle r (area.expanded (expandedRadius)); - Rectangle top (r.removeFromTop (expandedRadius)); - Rectangle bottom (r.removeFromBottom (expandedRadius)); - - drawShadowSection (g, cg, top.removeFromLeft (expandedRadius), true, 1.0f, 1.0f, 0, 1.0f); - drawShadowSection (g, cg, top.removeFromRight (expandedRadius), true, 0, 1.0f, 1.0f, 1.0f); - drawShadowSection (g, cg, top, false, 0, 1.0f, 0, 0); - - drawShadowSection (g, cg, bottom.removeFromLeft (expandedRadius), true, 1.0f, 0, 0, 0); - drawShadowSection (g, cg, bottom.removeFromRight (expandedRadius), true, 0, 0, 1.0f, 0); - drawShadowSection (g, cg, bottom, false, 0, 0, 0, 1.0f); - - drawShadowSection (g, cg, r.removeFromLeft (expandedRadius), false, 1.0f, 0, 0, 0); - drawShadowSection (g, cg, r.removeFromRight (expandedRadius), false, 0, 0, 1.0f, 0); - - g.setColour (colour); - g.fillRect (area); -} - -//============================================================================== -DropShadowEffect::DropShadowEffect() {} -DropShadowEffect::~DropShadowEffect() {} - -void DropShadowEffect::setShadowProperties (const DropShadow& newShadow) -{ - shadow = newShadow; -} - -void DropShadowEffect::applyEffect (Image& image, Graphics& g, float scaleFactor, float alpha) -{ - DropShadow s (shadow); - s.radius = roundToInt (s.radius * scaleFactor); - s.colour = s.colour.withMultipliedAlpha (alpha); - s.offset.x = roundToInt (s.offset.x * scaleFactor); - s.offset.y = roundToInt (s.offset.y * scaleFactor); - - s.drawForImage (g, image); - - g.setOpacity (alpha); - g.drawImageAt (image, 0, 0); -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/effects/juce_DropShadowEffect.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/effects/juce_DropShadowEffect.h deleted file mode 100644 index 1f9362a0b8..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/effects/juce_DropShadowEffect.h +++ /dev/null @@ -1,110 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_DROPSHADOWEFFECT_H_INCLUDED -#define JUCE_DROPSHADOWEFFECT_H_INCLUDED - - -//============================================================================== -/** - Defines a drop-shadow effect. -*/ -struct JUCE_API DropShadow -{ - /** Creates a default drop-shadow effect. */ - DropShadow() noexcept; - - /** Creates a drop-shadow object with the given parameters. */ - DropShadow (Colour shadowColour, int radius, Point offset) noexcept; - - /** Renders a drop-shadow based on the alpha-channel of the given image. */ - void drawForImage (Graphics& g, const Image& srcImage) const; - - /** Renders a drop-shadow based on the shape of a path. */ - void drawForPath (Graphics& g, const Path& path) const; - - /** Renders a drop-shadow for a rectangle. - Note that for speed, this approximates the shadow using gradients. - */ - void drawForRectangle (Graphics& g, const Rectangle& area) const; - - /** The colour with which to render the shadow. - In most cases you'll probably want to leave this as black with an alpha - value of around 0.5 - */ - Colour colour; - - /** The approximate spread of the shadow. */ - int radius; - - /** The offset of the shadow. */ - Point offset; -}; - -//============================================================================== -/** - An effect filter that adds a drop-shadow behind the image's content. - - (This will only work on images/components that aren't opaque, of course). - - When added to a component, this effect will draw a soft-edged - shadow based on what gets drawn inside it. The shadow will also - be applied to the component's children. - - For speed, this doesn't use a proper gaussian blur, but cheats by - using a simple bilinear filter. If you need a really high-quality - shadow, check out ImageConvolutionKernel::createGaussianBlur() - - @see Component::setComponentEffect -*/ -class JUCE_API DropShadowEffect : public ImageEffectFilter -{ -public: - //============================================================================== - /** Creates a default drop-shadow effect. - To customise the shadow's appearance, use the setShadowProperties() method. - */ - DropShadowEffect(); - - /** Destructor. */ - ~DropShadowEffect(); - - //============================================================================== - /** Sets up parameters affecting the shadow's appearance. */ - void setShadowProperties (const DropShadow& newShadow); - - //============================================================================== - /** @internal */ - void applyEffect (Image& sourceImage, Graphics& destContext, float scaleFactor, float alpha); - - -private: - //============================================================================== - DropShadow shadow; - - JUCE_LEAK_DETECTOR (DropShadowEffect) -}; - - -#endif // JUCE_DROPSHADOWEFFECT_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/effects/juce_GlowEffect.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/effects/juce_GlowEffect.cpp deleted file mode 100644 index 7db7ef5f83..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/effects/juce_GlowEffect.cpp +++ /dev/null @@ -1,58 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -GlowEffect::GlowEffect() - : radius (2.0f), - colour (Colours::white) -{ -} - -GlowEffect::~GlowEffect() -{ -} - -void GlowEffect::setGlowProperties (const float newRadius, - Colour newColour) -{ - radius = newRadius; - colour = newColour; -} - -void GlowEffect::applyEffect (Image& image, Graphics& g, float scaleFactor, float alpha) -{ - Image temp (image.getFormat(), image.getWidth(), image.getHeight(), true); - - ImageConvolutionKernel blurKernel (roundToInt (radius * scaleFactor * 2.0f)); - - blurKernel.createGaussianBlur (radius); - blurKernel.rescaleAllValues (radius); - - blurKernel.applyToImage (temp, image, image.getBounds()); - - g.setColour (colour.withMultipliedAlpha (alpha)); - g.drawImageAt (temp, 0, 0, true); - - g.setOpacity (alpha); - g.drawImageAt (image, 0, 0, false); -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/effects/juce_GlowEffect.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/effects/juce_GlowEffect.h deleted file mode 100644 index ab9ce3b026..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/effects/juce_GlowEffect.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_GLOWEFFECT_H_INCLUDED -#define JUCE_GLOWEFFECT_H_INCLUDED - - -//============================================================================== -/** - A component effect that adds a coloured blur around the component's contents. - - (This will only work on non-opaque components). - - @see Component::setComponentEffect, DropShadowEffect -*/ -class JUCE_API GlowEffect : public ImageEffectFilter -{ -public: - //============================================================================== - /** Creates a default 'glow' effect. - - To customise its appearance, use the setGlowProperties() method. - */ - GlowEffect(); - - /** Destructor. */ - ~GlowEffect(); - - //============================================================================== - /** Sets the glow's radius and colour. - - The radius is how large the blur should be, and the colour is - used to render it (for a less intense glow, lower the colour's - opacity). - */ - void setGlowProperties (float newRadius, - Colour newColour); - - - //============================================================================== - /** @internal */ - void applyEffect (Image& sourceImage, Graphics& destContext, float scaleFactor, float alpha); - -private: - //============================================================================== - float radius; - Colour colour; - - JUCE_LEAK_DETECTOR (GlowEffect) -}; - - -#endif // JUCE_GLOWEFFECT_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/effects/juce_ImageEffectFilter.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/effects/juce_ImageEffectFilter.h deleted file mode 100644 index 84d6b0b93a..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/effects/juce_ImageEffectFilter.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_IMAGEEFFECTFILTER_H_INCLUDED -#define JUCE_IMAGEEFFECTFILTER_H_INCLUDED - - -//============================================================================== -/** - A graphical effect filter that can be applied to components. - - An ImageEffectFilter can be applied to the image that a component - paints before it hits the screen. - - This is used for adding effects like shadows, blurs, etc. - - @see Component::setComponentEffect -*/ -class JUCE_API ImageEffectFilter -{ -public: - //============================================================================== - /** Overridden to render the effect. - - The implementation of this method must use the image that is passed in - as its source, and should render its output to the graphics context passed in. - - @param sourceImage the image that the source component has just rendered with - its paint() method. The image may or may not have an alpha - channel, depending on whether the component is opaque. - @param destContext the graphics context to use to draw the resultant image. - @param scaleFactor a scale factor that has been applied to the image - e.g. if - this is 2, then the image is actually scaled-up to twice the - original resolution - @param alpha the alpha with which to draw the resultant image to the - target context - */ - virtual void applyEffect (Image& sourceImage, - Graphics& destContext, - float scaleFactor, - float alpha) = 0; - - /** Destructor. */ - virtual ~ImageEffectFilter() {} - -}; - -#endif // JUCE_IMAGEEFFECTFILTER_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/fonts/juce_AttributedString.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/fonts/juce_AttributedString.cpp deleted file mode 100644 index 43b6318f11..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/fonts/juce_AttributedString.cpp +++ /dev/null @@ -1,232 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -AttributedString::Attribute::Attribute (Range range_, Colour colour_) - : range (range_), colour (new Colour (colour_)) -{ -} - -AttributedString::Attribute::Attribute (Range range_, const Font& font_) - : range (range_), font (new Font (font_)) -{ -} - -AttributedString::Attribute::Attribute (const Attribute& other) - : range (other.range), - font (other.font.createCopy()), - colour (other.colour.createCopy()) -{ -} - -AttributedString::Attribute::Attribute (const Attribute& other, const int offset) - : range (other.range + offset), - font (other.font.createCopy()), - colour (other.colour.createCopy()) -{ -} - -AttributedString::Attribute::~Attribute() {} - -//============================================================================== -AttributedString::AttributedString() - : lineSpacing (0.0f), - justification (Justification::left), - wordWrap (AttributedString::byWord), - readingDirection (AttributedString::natural) -{ -} - -AttributedString::AttributedString (const String& newString) - : text (newString), - lineSpacing (0.0f), - justification (Justification::left), - wordWrap (AttributedString::byWord), - readingDirection (AttributedString::natural) -{ -} - -AttributedString::AttributedString (const AttributedString& other) - : text (other.text), - lineSpacing (other.lineSpacing), - justification (other.justification), - wordWrap (other.wordWrap), - readingDirection (other.readingDirection) -{ - attributes.addCopiesOf (other.attributes); -} - -AttributedString& AttributedString::operator= (const AttributedString& other) -{ - if (this != &other) - { - text = other.text; - lineSpacing = other.lineSpacing; - justification = other.justification; - wordWrap = other.wordWrap; - readingDirection = other.readingDirection; - attributes.clear(); - attributes.addCopiesOf (other.attributes); - } - - return *this; -} - -#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS -AttributedString::AttributedString (AttributedString&& other) noexcept - : text (static_cast (other.text)), - lineSpacing (other.lineSpacing), - justification (other.justification), - wordWrap (other.wordWrap), - readingDirection (other.readingDirection), - attributes (static_cast &&> (other.attributes)) -{ -} - -AttributedString& AttributedString::operator= (AttributedString&& other) noexcept -{ - text = static_cast (other.text); - lineSpacing = other.lineSpacing; - justification = other.justification; - wordWrap = other.wordWrap; - readingDirection = other.readingDirection; - attributes = static_cast &&> (other.attributes); - return *this; -} -#endif - -AttributedString::~AttributedString() {} - -void AttributedString::setText (const String& other) -{ - text = other; -} - -void AttributedString::append (const String& textToAppend) -{ - text += textToAppend; -} - -void AttributedString::append (const String& textToAppend, const Font& font) -{ - const int oldLength = text.length(); - const int newLength = textToAppend.length(); - - text += textToAppend; - setFont (Range (oldLength, oldLength + newLength), font); -} - -void AttributedString::append (const String& textToAppend, Colour colour) -{ - const int oldLength = text.length(); - const int newLength = textToAppend.length(); - - text += textToAppend; - setColour (Range (oldLength, oldLength + newLength), colour); -} - -void AttributedString::append (const String& textToAppend, const Font& font, Colour colour) -{ - const int oldLength = text.length(); - const int newLength = textToAppend.length(); - - text += textToAppend; - setFont (Range (oldLength, oldLength + newLength), font); - setColour (Range (oldLength, oldLength + newLength), colour); -} - -void AttributedString::append (const AttributedString& other) -{ - const int originalLength = text.length(); - text += other.text; - - for (int i = 0; i < other.attributes.size(); ++i) - attributes.add (new Attribute (*other.attributes.getUnchecked(i), originalLength)); -} - -void AttributedString::clear() -{ - text.clear(); - attributes.clear(); -} - -void AttributedString::setJustification (Justification newJustification) noexcept -{ - justification = newJustification; -} - -void AttributedString::setWordWrap (WordWrap newWordWrap) noexcept -{ - wordWrap = newWordWrap; -} - -void AttributedString::setReadingDirection (ReadingDirection newReadingDirection) noexcept -{ - readingDirection = newReadingDirection; -} - -void AttributedString::setLineSpacing (const float newLineSpacing) noexcept -{ - lineSpacing = newLineSpacing; -} - -void AttributedString::setColour (Range range, Colour colour) -{ - attributes.add (new Attribute (range, colour)); -} - -void AttributedString::setColour (Colour colour) -{ - for (int i = attributes.size(); --i >= 0;) - if (attributes.getUnchecked(i)->getColour() != nullptr) - attributes.remove (i); - - setColour (Range (0, text.length()), colour); -} - -void AttributedString::setFont (Range range, const Font& font) -{ - attributes.add (new Attribute (range, font)); -} - -void AttributedString::setFont (const Font& font) -{ - for (int i = attributes.size(); --i >= 0;) - if (attributes.getUnchecked(i)->getFont() != nullptr) - attributes.remove (i); - - setFont (Range (0, text.length()), font); -} - -void AttributedString::draw (Graphics& g, const Rectangle& area) const -{ - if (text.isNotEmpty() && g.clipRegionIntersects (area.getSmallestIntegerContainer())) - { - if (! g.getInternalContext().drawTextLayout (*this, area)) - { - TextLayout layout; - layout.createLayout (*this, area.getWidth()); - layout.draw (g, area); - } - } -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/fonts/juce_AttributedString.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/fonts/juce_AttributedString.h deleted file mode 100644 index 8c33d75d38..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/fonts/juce_AttributedString.h +++ /dev/null @@ -1,218 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_ATTRIBUTEDSTRING_H_INCLUDED -#define JUCE_ATTRIBUTEDSTRING_H_INCLUDED - - -//============================================================================== -/** - A text string with a set of colour/font settings that are associated with sub-ranges - of the text. - - An attributed string lets you create a string with varied fonts, colours, word-wrapping, - layout, etc., and draw it using AttributedString::draw(). - - @see TextLayout -*/ -class JUCE_API AttributedString -{ -public: - /** Creates an empty attributed string. */ - AttributedString(); - - /** Creates an attributed string with the given text. */ - explicit AttributedString (const String& text); - - AttributedString (const AttributedString&); - AttributedString& operator= (const AttributedString&); - #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS - AttributedString (AttributedString&&) noexcept; - AttributedString& operator= (AttributedString&&) noexcept; - #endif - - /** Destructor. */ - ~AttributedString(); - - //============================================================================== - /** Returns the complete text of this attributed string. */ - const String& getText() const noexcept { return text; } - - /** Replaces all the text. - This will change the text, but won't affect any of the colour or font attributes - that have been added. - */ - void setText (const String& newText); - - /** Appends some text (with a default font and colour). */ - void append (const String& textToAppend); - /** Appends some text, with a specified font, and the default colour (black). */ - void append (const String& textToAppend, const Font& font); - /** Appends some text, with a specified colour, and the default font. */ - void append (const String& textToAppend, Colour colour); - /** Appends some text, with a specified font and colour. */ - void append (const String& textToAppend, const Font& font, Colour colour); - - /** Appends another AttributedString to this one. - Note that this will only append the text, fonts, and colours - it won't copy any - other properties such as justification, line-spacing, etc from the other object. - */ - void append (const AttributedString& other); - - /** Resets the string, clearing all text and attributes. - Note that this won't affect global settings like the justification type, - word-wrap mode, etc. - */ - void clear(); - - //============================================================================== - /** Draws this string within the given area. - The layout of the string within the rectangle is controlled by the justification - value passed to setJustification(). - */ - void draw (Graphics& g, const Rectangle& area) const; - - //============================================================================== - /** Returns the justification that should be used for laying-out the text. - This may include both vertical and horizontal flags. - */ - Justification getJustification() const noexcept { return justification; } - - /** Sets the justification that should be used for laying-out the text. - This may include both vertical and horizontal flags. - */ - void setJustification (Justification newJustification) noexcept; - - //============================================================================== - /** Types of word-wrap behaviour. - @see getWordWrap, setWordWrap - */ - enum WordWrap - { - none, /**< No word-wrapping: lines extend indefinitely. */ - byWord, /**< Lines are wrapped on a word boundary. */ - byChar, /**< Lines are wrapped on a character boundary. */ - }; - - /** Returns the word-wrapping behaviour. */ - WordWrap getWordWrap() const noexcept { return wordWrap; } - - /** Sets the word-wrapping behaviour. */ - void setWordWrap (WordWrap newWordWrap) noexcept; - - //============================================================================== - /** Types of reading direction that can be used. - @see getReadingDirection, setReadingDirection - */ - enum ReadingDirection - { - natural, - leftToRight, - rightToLeft, - }; - - /** Returns the reading direction for the text. */ - ReadingDirection getReadingDirection() const noexcept { return readingDirection; } - - /** Sets the reading direction that should be used for the text. */ - void setReadingDirection (ReadingDirection newReadingDirection) noexcept; - - //============================================================================== - /** Returns the extra line-spacing distance. */ - float getLineSpacing() const noexcept { return lineSpacing; } - - /** Sets an extra line-spacing distance. */ - void setLineSpacing (float newLineSpacing) noexcept; - - //============================================================================== - /** An attribute that has been applied to a range of characters in an AttributedString. */ - class JUCE_API Attribute - { - public: - /** Creates an attribute that changes the colour for a range of characters. - @see AttributedString::setColour() - */ - Attribute (Range range, Colour colour); - - /** Creates an attribute that changes the font for a range of characters. - @see AttributedString::setFont() - */ - Attribute (Range range, const Font& font); - - Attribute (const Attribute&); - ~Attribute(); - - /** If this attribute specifies a font, this returns it; otherwise it returns nullptr. */ - const Font* getFont() const noexcept { return font; } - - /** If this attribute specifies a colour, this returns it; otherwise it returns nullptr. */ - const Colour* getColour() const noexcept { return colour; } - - /** The range of characters to which this attribute will be applied. */ - const Range range; - - private: - ScopedPointer font; - ScopedPointer colour; - - friend class AttributedString; - Attribute (const Attribute&, int); - Attribute& operator= (const Attribute&); - - JUCE_LEAK_DETECTOR (Attribute) - }; - - /** Returns the number of attributes that have been added to this string. */ - int getNumAttributes() const noexcept { return attributes.size(); } - - /** Returns one of the string's attributes. - The index provided must be less than getNumAttributes(), and >= 0. - */ - const Attribute* getAttribute (int index) const noexcept { return attributes.getUnchecked (index); } - - //============================================================================== - /** Adds a colour attribute for the specified range. */ - void setColour (Range range, Colour colour); - - /** Removes all existing colour attributes, and applies this colour to the whole string. */ - void setColour (Colour colour); - - /** Adds a font attribute for the specified range. */ - void setFont (Range range, const Font& font); - - /** Removes all existing font attributes, and applies this font to the whole string. */ - void setFont (const Font& font); - -private: - String text; - float lineSpacing; - Justification justification; - WordWrap wordWrap; - ReadingDirection readingDirection; - OwnedArray attributes; - - JUCE_LEAK_DETECTOR (AttributedString) -}; - -#endif // JUCE_ATTRIBUTEDSTRING_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/fonts/juce_CustomTypeface.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/fonts/juce_CustomTypeface.cpp deleted file mode 100644 index a2adb04296..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/fonts/juce_CustomTypeface.cpp +++ /dev/null @@ -1,406 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -class CustomTypeface::GlyphInfo -{ -public: - GlyphInfo (const juce_wchar c, const Path& p, const float w) noexcept - : character (c), path (p), width (w) - { - } - - struct KerningPair - { - juce_wchar character2; - float kerningAmount; - }; - - void addKerningPair (const juce_wchar subsequentCharacter, - const float extraKerningAmount) noexcept - { - KerningPair kp; - kp.character2 = subsequentCharacter; - kp.kerningAmount = extraKerningAmount; - kerningPairs.add (kp); - } - - float getHorizontalSpacing (const juce_wchar subsequentCharacter) const noexcept - { - if (subsequentCharacter != 0) - for (int i = kerningPairs.size(); --i >= 0;) - if (kerningPairs.getReference(i).character2 == subsequentCharacter) - return width + kerningPairs.getReference(i).kerningAmount; - - return width; - } - - const juce_wchar character; - const Path path; - float width; - Array kerningPairs; - -private: - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (GlyphInfo) -}; - -//============================================================================== -namespace CustomTypefaceHelpers -{ - static juce_wchar readChar (InputStream& in) - { - uint32 n = (uint32) (uint16) in.readShort(); - - if (n >= 0xd800 && n <= 0xdfff) - { - const uint32 nextWord = (uint32) (uint16) in.readShort(); - jassert (nextWord >= 0xdc00); // illegal unicode character! - - n = 0x10000 + (((n - 0xd800) << 10) | (nextWord - 0xdc00)); - } - - return (juce_wchar) n; - } - - static void writeChar (OutputStream& out, juce_wchar charToWrite) - { - if (charToWrite >= 0x10000) - { - charToWrite -= 0x10000; - out.writeShort ((short) (uint16) (0xd800 + (charToWrite >> 10))); - out.writeShort ((short) (uint16) (0xdc00 + (charToWrite & 0x3ff))); - } - else - { - out.writeShort ((short) (uint16) charToWrite); - } - } -} - -//============================================================================== -CustomTypeface::CustomTypeface() - : Typeface (String(), String()) -{ - clear(); -} - -CustomTypeface::CustomTypeface (InputStream& serialisedTypefaceStream) - : Typeface (String(), String()) -{ - clear(); - - GZIPDecompressorInputStream gzin (serialisedTypefaceStream); - BufferedInputStream in (gzin, 32768); - - name = in.readString(); - - const bool isBold = in.readBool(); - const bool isItalic = in.readBool(); - style = FontStyleHelpers::getStyleName (isBold, isItalic); - - ascent = in.readFloat(); - defaultCharacter = CustomTypefaceHelpers::readChar (in); - - int numChars = in.readInt(); - - for (int i = 0; i < numChars; ++i) - { - const juce_wchar c = CustomTypefaceHelpers::readChar (in); - const float width = in.readFloat(); - - Path p; - p.loadPathFromStream (in); - addGlyph (c, p, width); - } - - const int numKerningPairs = in.readInt(); - - for (int i = 0; i < numKerningPairs; ++i) - { - const juce_wchar char1 = CustomTypefaceHelpers::readChar (in); - const juce_wchar char2 = CustomTypefaceHelpers::readChar (in); - - addKerningPair (char1, char2, in.readFloat()); - } -} - -CustomTypeface::~CustomTypeface() -{ -} - -//============================================================================== -void CustomTypeface::clear() -{ - defaultCharacter = 0; - ascent = 1.0f; - style = "Regular"; - zeromem (lookupTable, sizeof (lookupTable)); - glyphs.clear(); -} - -void CustomTypeface::setCharacteristics (const String& newName, const float newAscent, const bool isBold, - const bool isItalic, const juce_wchar newDefaultCharacter) noexcept -{ - name = newName; - defaultCharacter = newDefaultCharacter; - ascent = newAscent; - style = FontStyleHelpers::getStyleName (isBold, isItalic); -} - -void CustomTypeface::setCharacteristics (const String& newName, const String& newStyle, const float newAscent, - const juce_wchar newDefaultCharacter) noexcept -{ - name = newName; - style = newStyle; - defaultCharacter = newDefaultCharacter; - ascent = newAscent; -} - -void CustomTypeface::addGlyph (const juce_wchar character, const Path& path, const float width) noexcept -{ - // Check that you're not trying to add the same character twice.. - jassert (findGlyph (character, false) == nullptr); - - if (isPositiveAndBelow ((int) character, (int) numElementsInArray (lookupTable))) - lookupTable [character] = (short) glyphs.size(); - - glyphs.add (new GlyphInfo (character, path, width)); -} - -void CustomTypeface::addKerningPair (const juce_wchar char1, const juce_wchar char2, const float extraAmount) noexcept -{ - if (extraAmount != 0) - { - if (GlyphInfo* const g = findGlyph (char1, true)) - g->addKerningPair (char2, extraAmount); - else - jassertfalse; // can only add kerning pairs for characters that exist! - } -} - -CustomTypeface::GlyphInfo* CustomTypeface::findGlyph (const juce_wchar character, const bool loadIfNeeded) noexcept -{ - if (isPositiveAndBelow ((int) character, (int) numElementsInArray (lookupTable)) && lookupTable [character] > 0) - return glyphs [(int) lookupTable [(int) character]]; - - for (int i = 0; i < glyphs.size(); ++i) - { - GlyphInfo* const g = glyphs.getUnchecked(i); - if (g->character == character) - return g; - } - - if (loadIfNeeded && loadGlyphIfPossible (character)) - return findGlyph (character, false); - - return nullptr; -} - -bool CustomTypeface::loadGlyphIfPossible (const juce_wchar /*characterNeeded*/) -{ - return false; -} - -void CustomTypeface::addGlyphsFromOtherTypeface (Typeface& typefaceToCopy, juce_wchar characterStartIndex, int numCharacters) noexcept -{ - setCharacteristics (name, style, typefaceToCopy.getAscent(), defaultCharacter); - - for (int i = 0; i < numCharacters; ++i) - { - const juce_wchar c = (juce_wchar) (characterStartIndex + i); - - Array glyphIndexes; - Array offsets; - typefaceToCopy.getGlyphPositions (String::charToString (c), glyphIndexes, offsets); - - const int glyphIndex = glyphIndexes.getFirst(); - - if (glyphIndex >= 0 && glyphIndexes.size() > 0) - { - const float glyphWidth = offsets[1]; - - Path p; - typefaceToCopy.getOutlineForGlyph (glyphIndex, p); - - addGlyph (c, p, glyphWidth); - - for (int j = glyphs.size() - 1; --j >= 0;) - { - const juce_wchar char2 = glyphs.getUnchecked (j)->character; - glyphIndexes.clearQuick(); - offsets.clearQuick(); - typefaceToCopy.getGlyphPositions (String::charToString (c) + String::charToString (char2), glyphIndexes, offsets); - - if (offsets.size() > 1) - addKerningPair (c, char2, offsets[1] - glyphWidth); - } - } - } -} - -bool CustomTypeface::writeToStream (OutputStream& outputStream) -{ - GZIPCompressorOutputStream out (&outputStream); - - out.writeString (name); - out.writeBool (FontStyleHelpers::isBold (style)); - out.writeBool (FontStyleHelpers::isItalic (style)); - out.writeFloat (ascent); - CustomTypefaceHelpers::writeChar (out, defaultCharacter); - out.writeInt (glyphs.size()); - - int numKerningPairs = 0; - - for (int i = 0; i < glyphs.size(); ++i) - { - const GlyphInfo* const g = glyphs.getUnchecked (i); - CustomTypefaceHelpers::writeChar (out, g->character); - out.writeFloat (g->width); - g->path.writePathToStream (out); - - numKerningPairs += g->kerningPairs.size(); - } - - out.writeInt (numKerningPairs); - - for (int i = 0; i < glyphs.size(); ++i) - { - const GlyphInfo* const g = glyphs.getUnchecked (i); - - for (int j = 0; j < g->kerningPairs.size(); ++j) - { - const GlyphInfo::KerningPair& p = g->kerningPairs.getReference (j); - CustomTypefaceHelpers::writeChar (out, g->character); - CustomTypefaceHelpers::writeChar (out, p.character2); - out.writeFloat (p.kerningAmount); - } - } - - return true; -} - -//============================================================================== -float CustomTypeface::getAscent() const { return ascent; } -float CustomTypeface::getDescent() const { return 1.0f - ascent; } -float CustomTypeface::getHeightToPointsFactor() const { return ascent; } - -float CustomTypeface::getStringWidth (const String& text) -{ - float x = 0; - - for (String::CharPointerType t (text.getCharPointer()); ! t.isEmpty();) - { - const juce_wchar c = t.getAndAdvance(); - - if (const GlyphInfo* const glyph = findGlyph (c, true)) - { - x += glyph->getHorizontalSpacing (*t); - } - else - { - const Typeface::Ptr fallbackTypeface (Typeface::getFallbackTypeface()); - - if (fallbackTypeface != nullptr && fallbackTypeface != this) - x += fallbackTypeface->getStringWidth (String::charToString (c)); - } - } - - return x; -} - -void CustomTypeface::getGlyphPositions (const String& text, Array & resultGlyphs, Array& xOffsets) -{ - xOffsets.add (0); - float x = 0; - - for (String::CharPointerType t (text.getCharPointer()); ! t.isEmpty();) - { - float width = 0.0f; - int glyphChar = 0; - - const juce_wchar c = t.getAndAdvance(); - - if (const GlyphInfo* const glyph = findGlyph (c, true)) - { - width = glyph->getHorizontalSpacing (*t); - glyphChar = (int) glyph->character; - } - else - { - const Typeface::Ptr fallbackTypeface (getFallbackTypeface()); - - if (fallbackTypeface != nullptr && fallbackTypeface != this) - { - Array subGlyphs; - Array subOffsets; - fallbackTypeface->getGlyphPositions (String::charToString (c), subGlyphs, subOffsets); - - if (subGlyphs.size() > 0) - { - glyphChar = subGlyphs.getFirst(); - width = subOffsets[1]; - } - } - } - - x += width; - resultGlyphs.add (glyphChar); - xOffsets.add (x); - } -} - -bool CustomTypeface::getOutlineForGlyph (int glyphNumber, Path& path) -{ - if (const GlyphInfo* const glyph = findGlyph ((juce_wchar) glyphNumber, true)) - { - path = glyph->path; - return true; - } - - const Typeface::Ptr fallbackTypeface (getFallbackTypeface()); - - if (fallbackTypeface != nullptr && fallbackTypeface != this) - return fallbackTypeface->getOutlineForGlyph (glyphNumber, path); - - return false; -} - -EdgeTable* CustomTypeface::getEdgeTableForGlyph (int glyphNumber, const AffineTransform& transform, float fontHeight) -{ - if (const GlyphInfo* const glyph = findGlyph ((juce_wchar) glyphNumber, true)) - { - if (! glyph->path.isEmpty()) - return new EdgeTable (glyph->path.getBoundsTransformed (transform) - .getSmallestIntegerContainer().expanded (1, 0), - glyph->path, transform); - } - else - { - const Typeface::Ptr fallbackTypeface (getFallbackTypeface()); - - if (fallbackTypeface != nullptr && fallbackTypeface != this) - return fallbackTypeface->getEdgeTableForGlyph (glyphNumber, transform, fontHeight); - } - - return nullptr; -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/fonts/juce_CustomTypeface.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/fonts/juce_CustomTypeface.h deleted file mode 100644 index 25db68b72f..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/fonts/juce_CustomTypeface.h +++ /dev/null @@ -1,164 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_CUSTOMTYPEFACE_H_INCLUDED -#define JUCE_CUSTOMTYPEFACE_H_INCLUDED - - -//============================================================================== -/** - A typeface that can be populated with custom glyphs. - - You can create a CustomTypeface if you need one that contains your own glyphs, - or if you need to load a typeface from a Juce-formatted binary stream. - - If you want to create a copy of a native face, you can use addGlyphsFromOtherTypeface() - to copy glyphs into this face. - - NOTE! For most people this class is almost certainly NOT the right tool to use! - If what you want to do is to embed a font into your exe, then your best plan is - probably to embed your TTF/OTF font file into your binary using the Introjucer, - and then call Typeface::createSystemTypefaceFor() to load it from memory. - - @see Typeface, Font -*/ -class JUCE_API CustomTypeface : public Typeface -{ -public: - //============================================================================== - /** Creates a new, empty typeface. */ - CustomTypeface(); - - /** Loads a typeface from a previously saved stream. - The stream must have been created by writeToStream(). - - NOTE! Since this class was written, support was added for loading real font files from - memory, so for most people, using Typeface::createSystemTypefaceFor() to load a real font - is more appropriate than using this class to store it in a proprietary format. - - @see writeToStream - */ - explicit CustomTypeface (InputStream& serialisedTypefaceStream); - - /** Destructor. */ - ~CustomTypeface(); - - //============================================================================== - /** Resets this typeface, deleting all its glyphs and settings. */ - void clear(); - - /** Sets the vital statistics for the typeface. - @param fontFamily the typeface's font family - @param ascent the ascent - this is normalised to a height of 1.0 and this is - the value that will be returned by Typeface::getAscent(). The - descent is assumed to be (1.0 - ascent) - @param isBold should be true if the typeface is bold - @param isItalic should be true if the typeface is italic - @param defaultCharacter the character to be used as a replacement if there's - no glyph available for the character that's being drawn - */ - void setCharacteristics (const String& fontFamily, float ascent, - bool isBold, bool isItalic, - juce_wchar defaultCharacter) noexcept; - - /** Sets the vital statistics for the typeface. - @param fontFamily the typeface's font family - @param fontStyle the typeface's font style - @param ascent the ascent - this is normalised to a height of 1.0 and this is - the value that will be returned by Typeface::getAscent(). The - descent is assumed to be (1.0 - ascent) - @param defaultCharacter the character to be used as a replacement if there's - no glyph available for the character that's being drawn - */ - void setCharacteristics (const String& fontFamily, const String& fontStyle, - float ascent, juce_wchar defaultCharacter) noexcept; - - /** Adds a glyph to the typeface. - - The path that is passed in is normalised so that the font height is 1.0, and its - origin is the anchor point of the character on its baseline. - - The width is the nominal width of the character, and any extra kerning values that - are specified will be added to this width. - */ - void addGlyph (juce_wchar character, const Path& path, float width) noexcept; - - /** Specifies an extra kerning amount to be used between a pair of characters. - The amount will be added to the nominal width of the first character when laying out a string. - */ - void addKerningPair (juce_wchar char1, juce_wchar char2, float extraAmount) noexcept; - - /** Adds a range of glyphs from another typeface. - This will attempt to pull in the paths and kerning information from another typeface and - add it to this one. - */ - void addGlyphsFromOtherTypeface (Typeface& typefaceToCopy, juce_wchar characterStartIndex, int numCharacters) noexcept; - - /** Saves this typeface as a Juce-formatted font file. - A CustomTypeface can be created to reload the data that is written - see the CustomTypeface - constructor. - - NOTE! Since this class was written, support was added for loading real font files from - memory, so for most people, using Typeface::createSystemTypefaceFor() to load a real font - is more appropriate than using this class to store it in a proprietary format. - */ - bool writeToStream (OutputStream& outputStream); - - //============================================================================== - // The following methods implement the basic Typeface behaviour. - float getAscent() const override; - float getDescent() const override; - float getHeightToPointsFactor() const override; - float getStringWidth (const String&) override; - void getGlyphPositions (const String&, Array & glyphs, Array& xOffsets) override; - bool getOutlineForGlyph (int glyphNumber, Path&) override; - EdgeTable* getEdgeTableForGlyph (int glyphNumber, const AffineTransform&, float fontHeight) override; - -protected: - //============================================================================== - juce_wchar defaultCharacter; - float ascent; - - //============================================================================== - /** If a subclass overrides this, it can load glyphs into the font on-demand. - When methods such as getGlyphPositions() or getOutlineForGlyph() are asked for a - particular character and there's no corresponding glyph, they'll call this - method so that a subclass can try to add that glyph, returning true if it - manages to do so. - */ - virtual bool loadGlyphIfPossible (juce_wchar characterNeeded); - -private: - //============================================================================== - class GlyphInfo; - friend struct ContainerDeletePolicy; - OwnedArray glyphs; - short lookupTable [128]; - - GlyphInfo* findGlyph (const juce_wchar character, bool loadIfNeeded) noexcept; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (CustomTypeface) -}; - -#endif // JUCE_CUSTOMTYPEFACE_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/fonts/juce_Font.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/fonts/juce_Font.cpp deleted file mode 100644 index 1b4fc04abf..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/fonts/juce_Font.cpp +++ /dev/null @@ -1,720 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -namespace FontValues -{ - static float limitFontHeight (const float height) noexcept - { - return jlimit (0.1f, 10000.0f, height); - } - - const float defaultFontHeight = 14.0f; - String fallbackFont; - String fallbackFontStyle; -} - -typedef Typeface::Ptr (*GetTypefaceForFont) (const Font&); -GetTypefaceForFont juce_getTypefaceForFont = nullptr; - -//============================================================================== -class TypefaceCache : private DeletedAtShutdown -{ -public: - TypefaceCache() : counter (0) - { - setSize (10); - } - - ~TypefaceCache() - { - clearSingletonInstance(); - } - - juce_DeclareSingleton (TypefaceCache, false); - - void setSize (const int numToCache) - { - const ScopedWriteLock sl (lock); - - faces.clear(); - faces.insertMultiple (-1, CachedFace(), numToCache); - } - - void clear() - { - const ScopedWriteLock sl (lock); - - setSize (faces.size()); - defaultFace = nullptr; - } - - Typeface::Ptr findTypefaceFor (const Font& font) - { - const ScopedReadLock slr (lock); - - const String faceName (font.getTypefaceName()); - const String faceStyle (font.getTypefaceStyle()); - - jassert (faceName.isNotEmpty()); - - for (int i = faces.size(); --i >= 0;) - { - CachedFace& face = faces.getReference(i); - - if (face.typefaceName == faceName - && face.typefaceStyle == faceStyle - && face.typeface != nullptr - && face.typeface->isSuitableForFont (font)) - { - face.lastUsageCount = ++counter; - return face.typeface; - } - } - - const ScopedWriteLock slw (lock); - int replaceIndex = 0; - size_t bestLastUsageCount = std::numeric_limits::max(); - - for (int i = faces.size(); --i >= 0;) - { - const size_t lu = faces.getReference(i).lastUsageCount; - - if (bestLastUsageCount > lu) - { - bestLastUsageCount = lu; - replaceIndex = i; - } - } - - CachedFace& face = faces.getReference (replaceIndex); - face.typefaceName = faceName; - face.typefaceStyle = faceStyle; - face.lastUsageCount = ++counter; - - if (juce_getTypefaceForFont == nullptr) - face.typeface = Font::getDefaultTypefaceForFont (font); - else - face.typeface = juce_getTypefaceForFont (font); - - jassert (face.typeface != nullptr); // the look and feel must return a typeface! - - if (defaultFace == nullptr && font == Font()) - defaultFace = face.typeface; - - return face.typeface; - } - - Typeface::Ptr defaultFace; - -private: - struct CachedFace - { - CachedFace() noexcept : lastUsageCount (0) {} - - // Although it seems a bit wacky to store the name here, it's because it may be a - // placeholder rather than a real one, e.g. "" vs the actual typeface name. - // Since the typeface itself doesn't know that it may have this alias, the name under - // which it was fetched needs to be stored separately. - String typefaceName, typefaceStyle; - size_t lastUsageCount; - Typeface::Ptr typeface; - }; - - ReadWriteLock lock; - Array faces; - size_t counter; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (TypefaceCache) -}; - -juce_ImplementSingleton (TypefaceCache) - -void Typeface::setTypefaceCacheSize (int numFontsToCache) -{ - TypefaceCache::getInstance()->setSize (numFontsToCache); -} - -#if JUCE_MODULE_AVAILABLE_juce_opengl -extern void clearOpenGLGlyphCache(); -#endif - -void Typeface::clearTypefaceCache() -{ - TypefaceCache::getInstance()->clear(); - - RenderingHelpers::SoftwareRendererSavedState::clearGlyphCache(); - - #if JUCE_MODULE_AVAILABLE_juce_opengl - clearOpenGLGlyphCache(); - #endif -} - -//============================================================================== -class Font::SharedFontInternal : public ReferenceCountedObject -{ -public: - SharedFontInternal() noexcept - : typeface (TypefaceCache::getInstance()->defaultFace), - typefaceName (Font::getDefaultSansSerifFontName()), - typefaceStyle (Font::getDefaultStyle()), - height (FontValues::defaultFontHeight), - horizontalScale (1.0f), kerning (0), ascent (0), underline (false) - { - } - - SharedFontInternal (int styleFlags, float fontHeight) noexcept - : typefaceName (Font::getDefaultSansSerifFontName()), - typefaceStyle (FontStyleHelpers::getStyleName (styleFlags)), - height (fontHeight), - horizontalScale (1.0f), kerning (0), ascent (0), underline ((styleFlags & underlined) != 0) - { - if (styleFlags == plain) - typeface = TypefaceCache::getInstance()->defaultFace; - } - - SharedFontInternal (const String& name, int styleFlags, float fontHeight) noexcept - : typefaceName (name), - typefaceStyle (FontStyleHelpers::getStyleName (styleFlags)), - height (fontHeight), - horizontalScale (1.0f), kerning (0), ascent (0), underline ((styleFlags & underlined) != 0) - { - if (styleFlags == plain && typefaceName.isEmpty()) - typeface = TypefaceCache::getInstance()->defaultFace; - } - - SharedFontInternal (const String& name, const String& style, float fontHeight) noexcept - : typefaceName (name), typefaceStyle (style), height (fontHeight), - horizontalScale (1.0f), kerning (0), ascent (0), underline (false) - { - if (typefaceName.isEmpty()) - typefaceName = Font::getDefaultSansSerifFontName(); - } - - explicit SharedFontInternal (const Typeface::Ptr& face) noexcept - : typeface (face), - typefaceName (face->getName()), - typefaceStyle (face->getStyle()), - height (FontValues::defaultFontHeight), - horizontalScale (1.0f), kerning (0), ascent (0), underline (false) - { - jassert (typefaceName.isNotEmpty()); - } - - SharedFontInternal (const SharedFontInternal& other) noexcept - : ReferenceCountedObject(), - typeface (other.typeface), - typefaceName (other.typefaceName), - typefaceStyle (other.typefaceStyle), - height (other.height), - horizontalScale (other.horizontalScale), - kerning (other.kerning), - ascent (other.ascent), - underline (other.underline) - { - } - - bool operator== (const SharedFontInternal& other) const noexcept - { - return height == other.height - && underline == other.underline - && horizontalScale == other.horizontalScale - && kerning == other.kerning - && typefaceName == other.typefaceName - && typefaceStyle == other.typefaceStyle; - } - - Typeface::Ptr typeface; - String typefaceName, typefaceStyle; - float height, horizontalScale, kerning, ascent; - bool underline; -}; - -//============================================================================== -Font::Font() : font (new SharedFontInternal()) {} -Font::Font (const Typeface::Ptr& typeface) : font (new SharedFontInternal (typeface)) {} -Font::Font (const Font& other) noexcept : font (other.font) {} - -Font::Font (float fontHeight, int styleFlags) - : font (new SharedFontInternal (styleFlags, FontValues::limitFontHeight (fontHeight))) -{ -} - -Font::Font (const String& typefaceName, float fontHeight, int styleFlags) - : font (new SharedFontInternal (typefaceName, styleFlags, FontValues::limitFontHeight (fontHeight))) -{ -} - -Font::Font (const String& typefaceName, const String& typefaceStyle, float fontHeight) - : font (new SharedFontInternal (typefaceName, typefaceStyle, FontValues::limitFontHeight (fontHeight))) -{ -} - -Font& Font::operator= (const Font& other) noexcept -{ - font = other.font; - return *this; -} - -#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS -Font::Font (Font&& other) noexcept - : font (static_cast&&> (other.font)) -{ -} - -Font& Font::operator= (Font&& other) noexcept -{ - font = static_cast&&> (other.font); - return *this; -} -#endif - -Font::~Font() noexcept -{ -} - -bool Font::operator== (const Font& other) const noexcept -{ - return font == other.font - || *font == *other.font; -} - -bool Font::operator!= (const Font& other) const noexcept -{ - return ! operator== (other); -} - -void Font::dupeInternalIfShared() -{ - if (font->getReferenceCount() > 1) - font = new SharedFontInternal (*font); -} - -void Font::checkTypefaceSuitability() -{ - if (font->typeface != nullptr && ! font->typeface->isSuitableForFont (*this)) - font->typeface = nullptr; -} - -//============================================================================== -struct FontPlaceholderNames -{ - FontPlaceholderNames() - : sans (""), - serif (""), - mono (""), - regular ("") - { - } - - String sans, serif, mono, regular; -}; - -const FontPlaceholderNames& getFontPlaceholderNames() -{ - static FontPlaceholderNames names; - return names; -} - -#if JUCE_MSVC -// This is a workaround for the lack of thread-safety in MSVC's handling of function-local -// statics - if multiple threads all try to create the first Font object at the same time, -// it can cause a race-condition in creating these placeholder strings. -struct FontNamePreloader { FontNamePreloader() { getFontPlaceholderNames(); } }; -static FontNamePreloader fnp; -#endif - -const String& Font::getDefaultSansSerifFontName() { return getFontPlaceholderNames().sans; } -const String& Font::getDefaultSerifFontName() { return getFontPlaceholderNames().serif; } -const String& Font::getDefaultMonospacedFontName() { return getFontPlaceholderNames().mono; } -const String& Font::getDefaultStyle() { return getFontPlaceholderNames().regular; } - -const String& Font::getTypefaceName() const noexcept { return font->typefaceName; } -const String& Font::getTypefaceStyle() const noexcept { return font->typefaceStyle; } - -void Font::setTypefaceName (const String& faceName) -{ - if (faceName != font->typefaceName) - { - jassert (faceName.isNotEmpty()); - - dupeInternalIfShared(); - font->typefaceName = faceName; - font->typeface = nullptr; - font->ascent = 0; - } -} - -void Font::setTypefaceStyle (const String& typefaceStyle) -{ - if (typefaceStyle != font->typefaceStyle) - { - dupeInternalIfShared(); - font->typefaceStyle = typefaceStyle; - font->typeface = nullptr; - font->ascent = 0; - } -} - -Font Font::withTypefaceStyle (const String& newStyle) const -{ - Font f (*this); - f.setTypefaceStyle (newStyle); - return f; -} - -StringArray Font::getAvailableStyles() const -{ - return findAllTypefaceStyles (getTypeface()->getName()); -} - -Typeface* Font::getTypeface() const -{ - if (font->typeface == nullptr) - { - font->typeface = TypefaceCache::getInstance()->findTypefaceFor (*this); - jassert (font->typeface != nullptr); - } - - return font->typeface; -} - -//============================================================================== -const String& Font::getFallbackFontName() -{ - return FontValues::fallbackFont; -} - -void Font::setFallbackFontName (const String& name) -{ - FontValues::fallbackFont = name; - - #if JUCE_MAC || JUCE_IOS - jassertfalse; // Note that use of a fallback font isn't currently implemented in OSX.. - #endif -} - -const String& Font::getFallbackFontStyle() -{ - return FontValues::fallbackFontStyle; -} - -void Font::setFallbackFontStyle (const String& style) -{ - FontValues::fallbackFontStyle = style; - - #if JUCE_MAC || JUCE_IOS - jassertfalse; // Note that use of a fallback font isn't currently implemented in OSX.. - #endif -} - -//============================================================================== -Font Font::withHeight (const float newHeight) const -{ - Font f (*this); - f.setHeight (newHeight); - return f; -} - -float Font::getHeightToPointsFactor() const -{ - return getTypeface()->getHeightToPointsFactor(); -} - -Font Font::withPointHeight (float heightInPoints) const -{ - Font f (*this); - f.setHeight (heightInPoints / getHeightToPointsFactor()); - return f; -} - -void Font::setHeight (float newHeight) -{ - newHeight = FontValues::limitFontHeight (newHeight); - - if (font->height != newHeight) - { - dupeInternalIfShared(); - font->height = newHeight; - checkTypefaceSuitability(); - } -} - -void Font::setHeightWithoutChangingWidth (float newHeight) -{ - newHeight = FontValues::limitFontHeight (newHeight); - - if (font->height != newHeight) - { - dupeInternalIfShared(); - font->horizontalScale *= (font->height / newHeight); - font->height = newHeight; - checkTypefaceSuitability(); - } -} - -int Font::getStyleFlags() const noexcept -{ - int styleFlags = font->underline ? underlined : plain; - - if (isBold()) styleFlags |= bold; - if (isItalic()) styleFlags |= italic; - - return styleFlags; -} - -Font Font::withStyle (const int newFlags) const -{ - Font f (*this); - f.setStyleFlags (newFlags); - return f; -} - -void Font::setStyleFlags (const int newFlags) -{ - if (getStyleFlags() != newFlags) - { - dupeInternalIfShared(); - font->typeface = nullptr; - font->typefaceStyle = FontStyleHelpers::getStyleName (newFlags); - font->underline = (newFlags & underlined) != 0; - font->ascent = 0; - } -} - -void Font::setSizeAndStyle (float newHeight, - const int newStyleFlags, - const float newHorizontalScale, - const float newKerningAmount) -{ - newHeight = FontValues::limitFontHeight (newHeight); - - if (font->height != newHeight - || font->horizontalScale != newHorizontalScale - || font->kerning != newKerningAmount) - { - dupeInternalIfShared(); - font->height = newHeight; - font->horizontalScale = newHorizontalScale; - font->kerning = newKerningAmount; - checkTypefaceSuitability(); - } - - setStyleFlags (newStyleFlags); -} - -void Font::setSizeAndStyle (float newHeight, - const String& newStyle, - const float newHorizontalScale, - const float newKerningAmount) -{ - newHeight = FontValues::limitFontHeight (newHeight); - - if (font->height != newHeight - || font->horizontalScale != newHorizontalScale - || font->kerning != newKerningAmount) - { - dupeInternalIfShared(); - font->height = newHeight; - font->horizontalScale = newHorizontalScale; - font->kerning = newKerningAmount; - checkTypefaceSuitability(); - } - - setTypefaceStyle (newStyle); -} - -Font Font::withHorizontalScale (const float newHorizontalScale) const -{ - Font f (*this); - f.setHorizontalScale (newHorizontalScale); - return f; -} - -void Font::setHorizontalScale (const float scaleFactor) -{ - dupeInternalIfShared(); - font->horizontalScale = scaleFactor; - checkTypefaceSuitability(); -} - -float Font::getHorizontalScale() const noexcept -{ - return font->horizontalScale; -} - -float Font::getExtraKerningFactor() const noexcept -{ - return font->kerning; -} - -Font Font::withExtraKerningFactor (const float extraKerning) const -{ - Font f (*this); - f.setExtraKerningFactor (extraKerning); - return f; -} - -void Font::setExtraKerningFactor (const float extraKerning) -{ - dupeInternalIfShared(); - font->kerning = extraKerning; - checkTypefaceSuitability(); -} - -Font Font::boldened() const { return withStyle (getStyleFlags() | bold); } -Font Font::italicised() const { return withStyle (getStyleFlags() | italic); } - -bool Font::isBold() const noexcept { return FontStyleHelpers::isBold (font->typefaceStyle); } -bool Font::isItalic() const noexcept { return FontStyleHelpers::isItalic (font->typefaceStyle); } -bool Font::isUnderlined() const noexcept { return font->underline; } - -void Font::setBold (const bool shouldBeBold) -{ - const int flags = getStyleFlags(); - setStyleFlags (shouldBeBold ? (flags | bold) - : (flags & ~bold)); -} - -void Font::setItalic (const bool shouldBeItalic) -{ - const int flags = getStyleFlags(); - setStyleFlags (shouldBeItalic ? (flags | italic) - : (flags & ~italic)); -} - -void Font::setUnderline (const bool shouldBeUnderlined) -{ - dupeInternalIfShared(); - font->underline = shouldBeUnderlined; - checkTypefaceSuitability(); -} - -float Font::getAscent() const -{ - if (font->ascent == 0) - font->ascent = getTypeface()->getAscent(); - - return font->height * font->ascent; -} - -float Font::getHeight() const noexcept { return font->height; } -float Font::getDescent() const { return font->height - getAscent(); } - -float Font::getHeightInPoints() const { return getHeight() * getHeightToPointsFactor(); } -float Font::getAscentInPoints() const { return getAscent() * getHeightToPointsFactor(); } -float Font::getDescentInPoints() const { return getDescent() * getHeightToPointsFactor(); } - -int Font::getStringWidth (const String& text) const -{ - return roundToInt (getStringWidthFloat (text)); -} - -float Font::getStringWidthFloat (const String& text) const -{ - float w = getTypeface()->getStringWidth (text); - - if (font->kerning != 0) - w += font->kerning * text.length(); - - return w * font->height * font->horizontalScale; -} - -void Font::getGlyphPositions (const String& text, Array& glyphs, Array& xOffsets) const -{ - getTypeface()->getGlyphPositions (text, glyphs, xOffsets); - - const int num = xOffsets.size(); - - if (num > 0) - { - const float scale = font->height * font->horizontalScale; - float* const x = xOffsets.getRawDataPointer(); - - if (font->kerning != 0) - { - for (int i = 0; i < num; ++i) - x[i] = (x[i] + i * font->kerning) * scale; - } - else - { - for (int i = 0; i < num; ++i) - x[i] *= scale; - } - } -} - -void Font::findFonts (Array& destArray) -{ - const StringArray names (findAllTypefaceNames()); - - for (int i = 0; i < names.size(); ++i) - { - const StringArray styles (findAllTypefaceStyles (names[i])); - - String style ("Regular"); - - if (! styles.contains (style, true)) - style = styles[0]; - - destArray.add (Font (names[i], style, FontValues::defaultFontHeight)); - } -} - -//============================================================================== -String Font::toString() const -{ - String s; - - if (getTypefaceName() != getDefaultSansSerifFontName()) - s << getTypefaceName() << "; "; - - s << String (getHeight(), 1); - - if (getTypefaceStyle() != getDefaultStyle()) - s << ' ' << getTypefaceStyle(); - - return s; -} - -Font Font::fromString (const String& fontDescription) -{ - const int separator = fontDescription.indexOfChar (';'); - String name; - - if (separator > 0) - name = fontDescription.substring (0, separator).trim(); - - if (name.isEmpty()) - name = getDefaultSansSerifFontName(); - - String sizeAndStyle (fontDescription.substring (separator + 1).trimStart()); - - float height = sizeAndStyle.getFloatValue(); - if (height <= 0) - height = 10.0f; - - const String style (sizeAndStyle.fromFirstOccurrenceOf (" ", false, false)); - - return Font (name, style, height); -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/fonts/juce_Font.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/fonts/juce_Font.h deleted file mode 100644 index 9888b27887..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/fonts/juce_Font.h +++ /dev/null @@ -1,460 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_FONT_H_INCLUDED -#define JUCE_FONT_H_INCLUDED - - -//============================================================================== -/** - Represents a particular font, including its size, style, etc. - - Apart from the typeface to be used, a Font object also dictates whether - the font is bold, italic, underlined, how big it is, and its kerning and - horizontal scale factor. - - @see Typeface -*/ -class JUCE_API Font -{ -public: - //============================================================================== - /** A combination of these values is used by the constructor to specify the - style of font to use. - */ - enum FontStyleFlags - { - plain = 0, /**< indicates a plain, non-bold, non-italic version of the font. @see setStyleFlags */ - bold = 1, /**< boldens the font. @see setStyleFlags */ - italic = 2, /**< finds an italic version of the font. @see setStyleFlags */ - underlined = 4 /**< underlines the font. @see setStyleFlags */ - }; - - //============================================================================== - /** Creates a sans-serif font in a given size. - - @param fontHeight the height in pixels (can be fractional) - @param styleFlags the style to use - this can be a combination of the - Font::bold, Font::italic and Font::underlined, or - just Font::plain for the normal style. - @see FontStyleFlags, getDefaultSansSerifFontName - */ - Font (float fontHeight, int styleFlags = plain); - - /** Creates a font with a given typeface and parameters. - - @param typefaceName the font family of the typeface to use - @param fontHeight the height in pixels (can be fractional) - @param styleFlags the style to use - this can be a combination of the - Font::bold, Font::italic and Font::underlined, or - just Font::plain for the normal style. - @see FontStyleFlags, getDefaultSansSerifFontName - */ - Font (const String& typefaceName, float fontHeight, int styleFlags); - - /** Creates a font with a given typeface and parameters. - - @param typefaceName the font family of the typeface to use - @param typefaceStyle the font style of the typeface to use - @param fontHeight the height in pixels (can be fractional) - */ - Font (const String& typefaceName, const String& typefaceStyle, float fontHeight); - - /** Creates a copy of another Font object. */ - Font (const Font& other) noexcept; - - /** Creates a font for a typeface. */ - Font (const Typeface::Ptr& typeface); - - /** Creates a basic sans-serif font at a default height. - - You should use one of the other constructors for creating a font that you're planning - on drawing with - this constructor is here to help initialise objects before changing - the font's settings later. - */ - Font(); - - #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS - Font (Font&& other) noexcept; - Font& operator= (Font&& other) noexcept; - #endif - - /** Copies this font from another one. */ - Font& operator= (const Font& other) noexcept; - - bool operator== (const Font& other) const noexcept; - bool operator!= (const Font& other) const noexcept; - - /** Destructor. */ - ~Font() noexcept; - - //============================================================================== - /** Changes the font family of the typeface. - - e.g. "Arial", "Courier", etc. - - This may also be set to Font::getDefaultSansSerifFontName(), Font::getDefaultSerifFontName(), - or Font::getDefaultMonospacedFontName(), which are not actual platform-specific font family names, - but are generic font family names that are used to represent the various default fonts. - If you need to know the exact typeface font family being used, you can call - Font::getTypeface()->getName(), which will give you the platform-specific font family. - - If a suitable font isn't found on the machine, it'll just use a default instead. - */ - void setTypefaceName (const String& faceName); - - /** Returns the font family of the typeface that this font uses. - - e.g. "Arial", "Courier", etc. - - This may also be set to Font::getDefaultSansSerifFontName(), Font::getDefaultSerifFontName(), - or Font::getDefaultMonospacedFontName(), which are not actual platform-specific font family names, - but are generic font familiy names that are used to represent the various default fonts. - - If you need to know the exact typeface font family being used, you can call - Font::getTypeface()->getName(), which will give you the platform-specific font family. - */ - const String& getTypefaceName() const noexcept; - - //============================================================================== - /** Returns the font style of the typeface that this font uses. - @see withTypefaceStyle, getAvailableStyles() - */ - const String& getTypefaceStyle() const noexcept; - - /** Changes the font style of the typeface. - @see getAvailableStyles() - */ - void setTypefaceStyle (const String& newStyle); - - /** Returns a copy of this font with a new typeface style. - @see getAvailableStyles() - */ - Font withTypefaceStyle (const String& newStyle) const; - - /** Returns a list of the styles that this font can use. */ - StringArray getAvailableStyles() const; - - //============================================================================== - /** Returns a typeface font family that represents the default sans-serif font. - - This is also the typeface that will be used when a font is created without - specifying any typeface details. - - Note that this method just returns a generic placeholder string that means "the default - sans-serif font" - it's not the actual font family of this font. - - @see setTypefaceName, getDefaultSerifFontName, getDefaultMonospacedFontName - */ - static const String& getDefaultSansSerifFontName(); - - /** Returns a typeface font family that represents the default serif font. - - Note that this method just returns a generic placeholder string that means "the default - serif font" - it's not the actual font family of this font. - - @see setTypefaceName, getDefaultSansSerifFontName, getDefaultMonospacedFontName - */ - static const String& getDefaultSerifFontName(); - - /** Returns a typeface font family that represents the default monospaced font. - - Note that this method just returns a generic placeholder string that means "the default - monospaced font" - it's not the actual font family of this font. - - @see setTypefaceName, getDefaultSansSerifFontName, getDefaultSerifFontName - */ - static const String& getDefaultMonospacedFontName(); - - /** Returns a font style name that represents the default style. - - Note that this method just returns a generic placeholder string that means "the default - font style" - it's not the actual name of the font style of any particular font. - - @see setTypefaceStyle - */ - static const String& getDefaultStyle(); - - /** Returns the default system typeface for the given font. */ - static Typeface::Ptr getDefaultTypefaceForFont (const Font& font); - - //============================================================================== - /** Returns a copy of this font with a new height. */ - Font withHeight (float height) const; - - /** Returns a copy of this font with a new height, specified in points. */ - Font withPointHeight (float heightInPoints) const; - - /** Changes the font's height. - @see getHeight, withHeight, setHeightWithoutChangingWidth - */ - void setHeight (float newHeight); - - /** Changes the font's height without changing its width. - This alters the horizontal scale to compensate for the change in height. - */ - void setHeightWithoutChangingWidth (float newHeight); - - /** Returns the total height of this font, in pixels. - This is the maximum height, from the top of the ascent to the bottom of the - descenders. - - @see withHeight, setHeightWithoutChangingWidth, getAscent - */ - float getHeight() const noexcept; - - /** Returns the total height of this font, in points. - This is the maximum height, from the top of the ascent to the bottom of the - descenders. - - @see withPointHeight, getHeight - */ - float getHeightInPoints() const; - - /** Returns the height of the font above its baseline, in pixels. - This is the maximum height from the baseline to the top. - @see getHeight, getDescent - */ - float getAscent() const; - - /** Returns the height of the font above its baseline, in points. - This is the maximum height from the baseline to the top. - @see getHeight, getDescent - */ - float getAscentInPoints() const; - - /** Returns the amount that the font descends below its baseline, in pixels. - This is calculated as (getHeight() - getAscent()). - @see getAscent, getHeight - */ - float getDescent() const; - - /** Returns the amount that the font descends below its baseline, in points. - This is calculated as (getHeight() - getAscent()). - @see getAscent, getHeight - */ - float getDescentInPoints() const; - - //============================================================================== - /** Returns the font's style flags. - This will return a bitwise-or'ed combination of values from the FontStyleFlags - enum, to describe whether the font is bold, italic, etc. - @see FontStyleFlags, withStyle - */ - int getStyleFlags() const noexcept; - - /** Returns a copy of this font with the given set of style flags. - @param styleFlags a bitwise-or'ed combination of values from the FontStyleFlags enum. - @see FontStyleFlags, getStyleFlags - */ - Font withStyle (int styleFlags) const; - - /** Changes the font's style. - @param newFlags a bitwise-or'ed combination of values from the FontStyleFlags enum. - @see FontStyleFlags, withStyle - */ - void setStyleFlags (int newFlags); - - //============================================================================== - /** Makes the font bold or non-bold. */ - void setBold (bool shouldBeBold); - /** Returns a copy of this font with the bold attribute set. */ - Font boldened() const; - /** Returns true if the font is bold. */ - bool isBold() const noexcept; - - /** Makes the font italic or non-italic. */ - void setItalic (bool shouldBeItalic); - /** Returns a copy of this font with the italic attribute set. */ - Font italicised() const; - /** Returns true if the font is italic. */ - bool isItalic() const noexcept; - - /** Makes the font underlined or non-underlined. */ - void setUnderline (bool shouldBeUnderlined); - /** Returns true if the font is underlined. */ - bool isUnderlined() const noexcept; - - - //============================================================================== - /** Returns the font's horizontal scale. - A value of 1.0 is the normal scale, less than this will be narrower, greater - than 1.0 will be stretched out. - - @see withHorizontalScale - */ - float getHorizontalScale() const noexcept; - - /** Returns a copy of this font with a new horizontal scale. - @param scaleFactor a value of 1.0 is the normal scale, less than this will be - narrower, greater than 1.0 will be stretched out. - @see getHorizontalScale - */ - Font withHorizontalScale (float scaleFactor) const; - - /** Changes the font's horizontal scale factor. - @param scaleFactor a value of 1.0 is the normal scale, less than this will be - narrower, greater than 1.0 will be stretched out. - */ - void setHorizontalScale (float scaleFactor); - - /** Returns the font's kerning. - - This is the extra space added between adjacent characters, as a proportion - of the font's height. - - A value of zero is normal spacing, positive values will spread the letters - out more, and negative values make them closer together. - */ - float getExtraKerningFactor() const noexcept; - - /** Returns a copy of this font with a new kerning factor. - @param extraKerning a multiple of the font's height that will be added - to space between the characters. So a value of zero is - normal spacing, positive values spread the letters out, - negative values make them closer together. - */ - Font withExtraKerningFactor (float extraKerning) const; - - /** Changes the font's kerning. - @param extraKerning a multiple of the font's height that will be added - to space between the characters. So a value of zero is - normal spacing, positive values spread the letters out, - negative values make them closer together. - */ - void setExtraKerningFactor (float extraKerning); - - //============================================================================== - /** Changes all the font's characteristics with one call. */ - void setSizeAndStyle (float newHeight, - int newStyleFlags, - float newHorizontalScale, - float newKerningAmount); - - /** Changes all the font's characteristics with one call. */ - void setSizeAndStyle (float newHeight, - const String& newStyle, - float newHorizontalScale, - float newKerningAmount); - - //============================================================================== - /** Returns the total width of a string as it would be drawn using this font. - For a more accurate floating-point result, use getStringWidthFloat(). - */ - int getStringWidth (const String& text) const; - - /** Returns the total width of a string as it would be drawn using this font. - @see getStringWidth - */ - float getStringWidthFloat (const String& text) const; - - /** Returns the series of glyph numbers and their x offsets needed to represent a string. - - An extra x offset is added at the end of the run, to indicate where the right hand - edge of the last character is. - */ - void getGlyphPositions (const String& text, Array & glyphs, Array & xOffsets) const; - - //============================================================================== - /** Returns the typeface used by this font. - - Note that the object returned may go out of scope if this font is deleted - or has its style changed. - */ - Typeface* getTypeface() const; - - /** Creates an array of Font objects to represent all the fonts on the system. - - If you just need the font family names of the typefaces, you can also use - findAllTypefaceNames() instead. - - @param results the array to which new Font objects will be added. - */ - static void findFonts (Array& results); - - /** Returns a list of all the available typeface font families. - - The names returned can be passed into setTypefaceName(). - - You can use this instead of findFonts() if you only need their font family names, - and not font objects. - */ - static StringArray findAllTypefaceNames(); - - /** Returns a list of all the available typeface font styles. - - The names returned can be passed into setTypefaceStyle(). - - You can use this instead of findFonts() if you only need their styles, and not - font objects. - */ - static StringArray findAllTypefaceStyles (const String& family); - - //============================================================================== - /** Returns the font family of the typeface to be used for rendering glyphs that aren't - found in the requested typeface. - */ - static const String& getFallbackFontName(); - - /** Sets the (platform-specific) font family of the typeface to use to find glyphs that - aren't available in whatever font you're trying to use. - */ - static void setFallbackFontName (const String& name); - - /** Returns the font style of the typeface to be used for rendering glyphs that aren't - found in the requested typeface. - */ - static const String& getFallbackFontStyle(); - - /** Sets the (platform-specific) font style of the typeface to use to find glyphs that - aren't available in whatever font you're trying to use. - */ - static void setFallbackFontStyle (const String& style); - - //============================================================================== - /** Creates a string to describe this font. - The string will contain information to describe the font's typeface, size, and - style. To recreate the font from this string, use fromString(). - */ - String toString() const; - - /** Recreates a font from its stringified encoding. - This method takes a string that was created by toString(), and recreates the - original font. - */ - static Font fromString (const String& fontDescription); - - -private: - //============================================================================== - class SharedFontInternal; - ReferenceCountedObjectPtr font; - void dupeInternalIfShared(); - void checkTypefaceSuitability(); - float getHeightToPointsFactor() const; - - JUCE_LEAK_DETECTOR (Font) -}; - -#endif // JUCE_FONT_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/fonts/juce_GlyphArrangement.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/fonts/juce_GlyphArrangement.cpp deleted file mode 100644 index 8ad3b7b2ff..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/fonts/juce_GlyphArrangement.cpp +++ /dev/null @@ -1,798 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -PositionedGlyph::PositionedGlyph() noexcept - : character (0), glyph (0), x (0), y (0), w (0), whitespace (false) -{ -} - -PositionedGlyph::PositionedGlyph (const Font& font_, const juce_wchar character_, const int glyph_, - const float x_, const float y_, const float w_, const bool whitespace_) - : font (font_), character (character_), glyph (glyph_), - x (x_), y (y_), w (w_), whitespace (whitespace_) -{ -} - -PositionedGlyph::PositionedGlyph (const PositionedGlyph& other) - : font (other.font), character (other.character), glyph (other.glyph), - x (other.x), y (other.y), w (other.w), whitespace (other.whitespace) -{ -} - -#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS -PositionedGlyph::PositionedGlyph (PositionedGlyph&& other) noexcept - : font (static_cast (other.font)), - character (other.character), glyph (other.glyph), - x (other.x), y (other.y), w (other.w), whitespace (other.whitespace) -{ -} - -PositionedGlyph& PositionedGlyph::operator= (PositionedGlyph&& other) noexcept -{ - font = static_cast (other.font); - character = other.character; - glyph = other.glyph; - x = other.x; - y = other.y; - w = other.w; - whitespace = other.whitespace; - return *this; -} -#endif - -PositionedGlyph::~PositionedGlyph() {} - -PositionedGlyph& PositionedGlyph::operator= (const PositionedGlyph& other) -{ - font = other.font; - character = other.character; - glyph = other.glyph; - x = other.x; - y = other.y; - w = other.w; - whitespace = other.whitespace; - return *this; -} - -static inline void drawGlyphWithFont (const Graphics& g, int glyph, const Font& font, const AffineTransform& t) -{ - LowLevelGraphicsContext& context = g.getInternalContext(); - context.setFont (font); - context.drawGlyph (glyph, t); -} - -void PositionedGlyph::draw (const Graphics& g) const -{ - if (! isWhitespace()) - drawGlyphWithFont (g, glyph, font, AffineTransform::translation (x, y)); -} - -void PositionedGlyph::draw (const Graphics& g, const AffineTransform& transform) const -{ - if (! isWhitespace()) - drawGlyphWithFont (g, glyph, font, AffineTransform::translation (x, y).followedBy (transform)); -} - -void PositionedGlyph::createPath (Path& path) const -{ - if (! isWhitespace()) - { - if (Typeface* const t = font.getTypeface()) - { - Path p; - t->getOutlineForGlyph (glyph, p); - - path.addPath (p, AffineTransform::scale (font.getHeight() * font.getHorizontalScale(), font.getHeight()) - .translated (x, y)); - } - } -} - -bool PositionedGlyph::hitTest (float px, float py) const -{ - if (getBounds().contains (px, py) && ! isWhitespace()) - { - if (Typeface* const t = font.getTypeface()) - { - Path p; - t->getOutlineForGlyph (glyph, p); - - AffineTransform::translation (-x, -y) - .scaled (1.0f / (font.getHeight() * font.getHorizontalScale()), 1.0f / font.getHeight()) - .transformPoint (px, py); - - return p.contains (px, py); - } - } - - return false; -} - -void PositionedGlyph::moveBy (const float deltaX, - const float deltaY) -{ - x += deltaX; - y += deltaY; -} - - -//============================================================================== -GlyphArrangement::GlyphArrangement() -{ - glyphs.ensureStorageAllocated (128); -} - -GlyphArrangement::GlyphArrangement (const GlyphArrangement& other) - : glyphs (other.glyphs) -{ -} - -GlyphArrangement& GlyphArrangement::operator= (const GlyphArrangement& other) -{ - glyphs = other.glyphs; - return *this; -} - -GlyphArrangement::~GlyphArrangement() -{ -} - -//============================================================================== -void GlyphArrangement::clear() -{ - glyphs.clear(); -} - -PositionedGlyph& GlyphArrangement::getGlyph (const int index) const noexcept -{ - return glyphs.getReference (index); -} - -//============================================================================== -void GlyphArrangement::addGlyphArrangement (const GlyphArrangement& other) -{ - glyphs.addArray (other.glyphs); -} - -void GlyphArrangement::addGlyph (const PositionedGlyph& glyph) -{ - glyphs.add (glyph); -} - -void GlyphArrangement::removeRangeOfGlyphs (int startIndex, const int num) -{ - glyphs.removeRange (startIndex, num < 0 ? glyphs.size() : num); -} - -//============================================================================== -void GlyphArrangement::addLineOfText (const Font& font, - const String& text, - const float xOffset, - const float yOffset) -{ - addCurtailedLineOfText (font, text, xOffset, yOffset, 1.0e10f, false); -} - -void GlyphArrangement::addCurtailedLineOfText (const Font& font, - const String& text, - const float xOffset, - const float yOffset, - const float maxWidthPixels, - const bool useEllipsis) -{ - if (text.isNotEmpty()) - { - Array newGlyphs; - Array xOffsets; - font.getGlyphPositions (text, newGlyphs, xOffsets); - const int textLen = newGlyphs.size(); - glyphs.ensureStorageAllocated (glyphs.size() + textLen); - - String::CharPointerType t (text.getCharPointer()); - - for (int i = 0; i < textLen; ++i) - { - const float nextX = xOffsets.getUnchecked (i + 1); - - if (nextX > maxWidthPixels + 1.0f) - { - // curtail the string if it's too wide.. - if (useEllipsis && textLen > 3 && glyphs.size() >= 3) - insertEllipsis (font, xOffset + maxWidthPixels, 0, glyphs.size()); - - break; - } - else - { - const float thisX = xOffsets.getUnchecked (i); - const bool isWhitespace = t.isWhitespace(); - - glyphs.add (PositionedGlyph (font, t.getAndAdvance(), - newGlyphs.getUnchecked(i), - xOffset + thisX, yOffset, - nextX - thisX, isWhitespace)); - } - } - } -} - -int GlyphArrangement::insertEllipsis (const Font& font, const float maxXPos, - const int startIndex, int endIndex) -{ - int numDeleted = 0; - - if (glyphs.size() > 0) - { - Array dotGlyphs; - Array dotXs; - font.getGlyphPositions ("..", dotGlyphs, dotXs); - - const float dx = dotXs[1]; - float xOffset = 0.0f, yOffset = 0.0f; - - while (endIndex > startIndex) - { - const PositionedGlyph& pg = glyphs.getReference (--endIndex); - xOffset = pg.x; - yOffset = pg.y; - - glyphs.remove (endIndex); - ++numDeleted; - - if (xOffset + dx * 3 <= maxXPos) - break; - } - - for (int i = 3; --i >= 0;) - { - glyphs.insert (endIndex++, PositionedGlyph (font, '.', dotGlyphs.getFirst(), - xOffset, yOffset, dx, false)); - --numDeleted; - xOffset += dx; - - if (xOffset > maxXPos) - break; - } - } - - return numDeleted; -} - -void GlyphArrangement::addJustifiedText (const Font& font, - const String& text, - float x, float y, - const float maxLineWidth, - Justification horizontalLayout) -{ - int lineStartIndex = glyphs.size(); - addLineOfText (font, text, x, y); - - const float originalY = y; - - while (lineStartIndex < glyphs.size()) - { - int i = lineStartIndex; - - if (glyphs.getReference(i).getCharacter() != '\n' - && glyphs.getReference(i).getCharacter() != '\r') - ++i; - - const float lineMaxX = glyphs.getReference (lineStartIndex).getLeft() + maxLineWidth; - int lastWordBreakIndex = -1; - - while (i < glyphs.size()) - { - const PositionedGlyph& pg = glyphs.getReference (i); - const juce_wchar c = pg.getCharacter(); - - if (c == '\r' || c == '\n') - { - ++i; - - if (c == '\r' && i < glyphs.size() - && glyphs.getReference(i).getCharacter() == '\n') - ++i; - - break; - } - else if (pg.isWhitespace()) - { - lastWordBreakIndex = i + 1; - } - else if (pg.getRight() - 0.0001f >= lineMaxX) - { - if (lastWordBreakIndex >= 0) - i = lastWordBreakIndex; - - break; - } - - ++i; - } - - const float currentLineStartX = glyphs.getReference (lineStartIndex).getLeft(); - float currentLineEndX = currentLineStartX; - - for (int j = i; --j >= lineStartIndex;) - { - if (! glyphs.getReference (j).isWhitespace()) - { - currentLineEndX = glyphs.getReference (j).getRight(); - break; - } - } - - float deltaX = 0.0f; - - if (horizontalLayout.testFlags (Justification::horizontallyJustified)) - spreadOutLine (lineStartIndex, i - lineStartIndex, maxLineWidth); - else if (horizontalLayout.testFlags (Justification::horizontallyCentred)) - deltaX = (maxLineWidth - (currentLineEndX - currentLineStartX)) * 0.5f; - else if (horizontalLayout.testFlags (Justification::right)) - deltaX = maxLineWidth - (currentLineEndX - currentLineStartX); - - moveRangeOfGlyphs (lineStartIndex, i - lineStartIndex, - x + deltaX - currentLineStartX, y - originalY); - - lineStartIndex = i; - - y += font.getHeight(); - } -} - -void GlyphArrangement::addFittedText (const Font& f, - const String& text, - const float x, const float y, - const float width, const float height, - Justification layout, - int maximumLines, - const float minimumHorizontalScale) -{ - // doesn't make much sense if this is outside a sensible range of 0.5 to 1.0 - jassert (minimumHorizontalScale > 0 && minimumHorizontalScale <= 1.0f); - - if (text.containsAnyOf ("\r\n")) - { - addLinesWithLineBreaks (text, f, x, y, width, height, layout); - } - else - { - const int startIndex = glyphs.size(); - const String trimmed (text.trim()); - addLineOfText (f, trimmed, x, y); - const int numGlyphs = glyphs.size() - startIndex; - - if (numGlyphs > 0) - { - const float lineWidth = glyphs.getReference (glyphs.size() - 1).getRight() - - glyphs.getReference (startIndex).getLeft(); - - if (lineWidth > 0) - { - if (lineWidth * minimumHorizontalScale < width) - { - if (lineWidth > width) - stretchRangeOfGlyphs (startIndex, numGlyphs, width / lineWidth); - - justifyGlyphs (startIndex, numGlyphs, x, y, width, height, layout); - } - else if (maximumLines <= 1) - { - fitLineIntoSpace (startIndex, numGlyphs, x, y, width, height, - f, layout, minimumHorizontalScale); - } - else - { - splitLines (trimmed, f, startIndex, x, y, width, height, - maximumLines, lineWidth, layout, minimumHorizontalScale); - } - } - } - } -} - -//============================================================================== -void GlyphArrangement::moveRangeOfGlyphs (int startIndex, int num, const float dx, const float dy) -{ - jassert (startIndex >= 0); - - if (dx != 0.0f || dy != 0.0f) - { - if (num < 0 || startIndex + num > glyphs.size()) - num = glyphs.size() - startIndex; - - while (--num >= 0) - glyphs.getReference (startIndex++).moveBy (dx, dy); - } -} - -void GlyphArrangement::addLinesWithLineBreaks (const String& text, const Font& f, - float x, float y, float width, float height, Justification layout) -{ - GlyphArrangement ga; - ga.addJustifiedText (f, text, x, y, width, layout); - - const Rectangle bb (ga.getBoundingBox (0, -1, false)); - - float dy = y - bb.getY(); - - if (layout.testFlags (Justification::verticallyCentred)) dy += (height - bb.getHeight()) * 0.5f; - else if (layout.testFlags (Justification::bottom)) dy += (height - bb.getHeight()); - - ga.moveRangeOfGlyphs (0, -1, 0.0f, dy); - - glyphs.addArray (ga.glyphs); -} - -int GlyphArrangement::fitLineIntoSpace (int start, int numGlyphs, float x, float y, float w, float h, const Font& font, - Justification justification, float minimumHorizontalScale) -{ - int numDeleted = 0; - const float lineStartX = glyphs.getReference (start).getLeft(); - float lineWidth = glyphs.getReference (start + numGlyphs - 1).getRight() - lineStartX; - - if (lineWidth > w) - { - if (minimumHorizontalScale < 1.0f) - { - stretchRangeOfGlyphs (start, numGlyphs, jmax (minimumHorizontalScale, w / lineWidth)); - lineWidth = glyphs.getReference (start + numGlyphs - 1).getRight() - lineStartX - 0.5f; - } - - if (lineWidth > w) - { - numDeleted = insertEllipsis (font, lineStartX + w, start, start + numGlyphs); - numGlyphs -= numDeleted; - } - } - - justifyGlyphs (start, numGlyphs, x, y, w, h, justification); - return numDeleted; -} - -void GlyphArrangement::stretchRangeOfGlyphs (int startIndex, int num, - const float horizontalScaleFactor) -{ - jassert (startIndex >= 0); - - if (num < 0 || startIndex + num > glyphs.size()) - num = glyphs.size() - startIndex; - - if (num > 0) - { - const float xAnchor = glyphs.getReference (startIndex).getLeft(); - - while (--num >= 0) - { - PositionedGlyph& pg = glyphs.getReference (startIndex++); - - pg.x = xAnchor + (pg.x - xAnchor) * horizontalScaleFactor; - pg.font.setHorizontalScale (pg.font.getHorizontalScale() * horizontalScaleFactor); - pg.w *= horizontalScaleFactor; - } - } -} - -Rectangle GlyphArrangement::getBoundingBox (int startIndex, int num, const bool includeWhitespace) const -{ - jassert (startIndex >= 0); - - if (num < 0 || startIndex + num > glyphs.size()) - num = glyphs.size() - startIndex; - - Rectangle result; - - while (--num >= 0) - { - const PositionedGlyph& pg = glyphs.getReference (startIndex++); - - if (includeWhitespace || ! pg.isWhitespace()) - result = result.getUnion (pg.getBounds()); - } - - return result; -} - -void GlyphArrangement::justifyGlyphs (const int startIndex, const int num, - const float x, const float y, const float width, const float height, - Justification justification) -{ - jassert (num >= 0 && startIndex >= 0); - - if (glyphs.size() > 0 && num > 0) - { - const Rectangle bb (getBoundingBox (startIndex, num, ! justification.testFlags (Justification::horizontallyJustified - | Justification::horizontallyCentred))); - float deltaX = 0.0f, deltaY = 0.0f; - - if (justification.testFlags (Justification::horizontallyJustified)) deltaX = x - bb.getX(); - else if (justification.testFlags (Justification::horizontallyCentred)) deltaX = x + (width - bb.getWidth()) * 0.5f - bb.getX(); - else if (justification.testFlags (Justification::right)) deltaX = x + width - bb.getRight(); - else deltaX = x - bb.getX(); - - if (justification.testFlags (Justification::top)) deltaY = y - bb.getY(); - else if (justification.testFlags (Justification::bottom)) deltaY = y + height - bb.getBottom(); - else deltaY = y + (height - bb.getHeight()) * 0.5f - bb.getY(); - - moveRangeOfGlyphs (startIndex, num, deltaX, deltaY); - - if (justification.testFlags (Justification::horizontallyJustified)) - { - int lineStart = 0; - float baseY = glyphs.getReference (startIndex).getBaselineY(); - - int i; - for (i = 0; i < num; ++i) - { - const float glyphY = glyphs.getReference (startIndex + i).getBaselineY(); - - if (glyphY != baseY) - { - spreadOutLine (startIndex + lineStart, i - lineStart, width); - - lineStart = i; - baseY = glyphY; - } - } - - if (i > lineStart) - spreadOutLine (startIndex + lineStart, i - lineStart, width); - } - } -} - -void GlyphArrangement::spreadOutLine (const int start, const int num, const float targetWidth) -{ - if (start + num < glyphs.size() - && glyphs.getReference (start + num - 1).getCharacter() != '\r' - && glyphs.getReference (start + num - 1).getCharacter() != '\n') - { - int numSpaces = 0; - int spacesAtEnd = 0; - - for (int i = 0; i < num; ++i) - { - if (glyphs.getReference (start + i).isWhitespace()) - { - ++spacesAtEnd; - ++numSpaces; - } - else - { - spacesAtEnd = 0; - } - } - - numSpaces -= spacesAtEnd; - - if (numSpaces > 0) - { - const float startX = glyphs.getReference (start).getLeft(); - const float endX = glyphs.getReference (start + num - 1 - spacesAtEnd).getRight(); - - const float extraPaddingBetweenWords - = (targetWidth - (endX - startX)) / (float) numSpaces; - - float deltaX = 0.0f; - - for (int i = 0; i < num; ++i) - { - glyphs.getReference (start + i).moveBy (deltaX, 0.0f); - - if (glyphs.getReference (start + i).isWhitespace()) - deltaX += extraPaddingBetweenWords; - } - } - } -} - - -void GlyphArrangement::splitLines (const String& text, Font font, int startIndex, - float x, float y, float width, float height, int maximumLines, - float lineWidth, Justification layout, float minimumHorizontalScale) -{ - const int length = text.length(); - const int originalStartIndex = startIndex; - int numLines = 1; - - if (length <= 12 && ! text.containsAnyOf (" -\t\r\n")) - maximumLines = 1; - - maximumLines = jmin (maximumLines, length); - - while (numLines < maximumLines) - { - ++numLines; - - const float newFontHeight = height / (float) numLines; - - if (newFontHeight < font.getHeight()) - { - font.setHeight (jmax (8.0f, newFontHeight)); - - removeRangeOfGlyphs (startIndex, -1); - addLineOfText (font, text, x, y); - - lineWidth = glyphs.getReference (glyphs.size() - 1).getRight() - - glyphs.getReference (startIndex).getLeft(); - } - - // Try to estimate the point at which there are enough lines to fit the text, - // allowing for unevenness in the lengths due to differently sized words. - const float lineLengthUnevennessAllowance = 80.0f; - - if (numLines > (lineWidth + lineLengthUnevennessAllowance) / width || newFontHeight < 8.0f) - break; - } - - if (numLines < 1) - numLines = 1; - - float lineY = y; - float widthPerLine = lineWidth / numLines; - - for (int line = 0; line < numLines; ++line) - { - int i = startIndex; - float lineStartX = glyphs.getReference (startIndex).getLeft(); - - if (line == numLines - 1) - { - widthPerLine = width; - i = glyphs.size(); - } - else - { - while (i < glyphs.size()) - { - lineWidth = (glyphs.getReference (i).getRight() - lineStartX); - - if (lineWidth > widthPerLine) - { - // got to a point where the line's too long, so skip forward to find a - // good place to break it.. - const int searchStartIndex = i; - - while (i < glyphs.size()) - { - if ((glyphs.getReference (i).getRight() - lineStartX) * minimumHorizontalScale < width) - { - if (glyphs.getReference (i).isWhitespace() - || glyphs.getReference (i).getCharacter() == '-') - { - ++i; - break; - } - } - else - { - // can't find a suitable break, so try looking backwards.. - i = searchStartIndex; - - for (int back = 1; back < jmin (7, i - startIndex - 1); ++back) - { - if (glyphs.getReference (i - back).isWhitespace() - || glyphs.getReference (i - back).getCharacter() == '-') - { - i -= back - 1; - break; - } - } - - break; - } - - ++i; - } - - break; - } - - ++i; - } - - int wsStart = i; - while (wsStart > 0 && glyphs.getReference (wsStart - 1).isWhitespace()) - --wsStart; - - int wsEnd = i; - while (wsEnd < glyphs.size() && glyphs.getReference (wsEnd).isWhitespace()) - ++wsEnd; - - removeRangeOfGlyphs (wsStart, wsEnd - wsStart); - i = jmax (wsStart, startIndex + 1); - } - - i -= fitLineIntoSpace (startIndex, i - startIndex, - x, lineY, width, font.getHeight(), font, - layout.getOnlyHorizontalFlags() | Justification::verticallyCentred, - minimumHorizontalScale); - - startIndex = i; - lineY += font.getHeight(); - - if (startIndex >= glyphs.size()) - break; - } - - justifyGlyphs (originalStartIndex, glyphs.size() - originalStartIndex, - x, y, width, height, layout.getFlags() & ~Justification::horizontallyJustified); -} - -//============================================================================== -void GlyphArrangement::drawGlyphUnderline (const Graphics& g, const PositionedGlyph& pg, - const int i, const AffineTransform& transform) const -{ - const float lineThickness = (pg.font.getDescent()) * 0.3f; - - float nextX = pg.x + pg.w; - - if (i < glyphs.size() - 1 && glyphs.getReference (i + 1).y == pg.y) - nextX = glyphs.getReference (i + 1).x; - - Path p; - p.addRectangle (pg.x, pg.y + lineThickness * 2.0f, nextX - pg.x, lineThickness); - g.fillPath (p, transform); -} - -void GlyphArrangement::draw (const Graphics& g) const -{ - for (int i = 0; i < glyphs.size(); ++i) - { - const PositionedGlyph& pg = glyphs.getReference(i); - - if (pg.font.isUnderlined()) - drawGlyphUnderline (g, pg, i, AffineTransform::identity); - - pg.draw (g); - } -} - -void GlyphArrangement::draw (const Graphics& g, const AffineTransform& transform) const -{ - for (int i = 0; i < glyphs.size(); ++i) - { - const PositionedGlyph& pg = glyphs.getReference(i); - - if (pg.font.isUnderlined()) - drawGlyphUnderline (g, pg, i, transform); - - pg.draw (g, transform); - } -} - -void GlyphArrangement::createPath (Path& path) const -{ - for (int i = 0; i < glyphs.size(); ++i) - glyphs.getReference (i).createPath (path); -} - -int GlyphArrangement::findGlyphIndexAt (const float x, const float y) const -{ - for (int i = 0; i < glyphs.size(); ++i) - if (glyphs.getReference (i).hitTest (x, y)) - return i; - - return -1; -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/fonts/juce_GlyphArrangement.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/fonts/juce_GlyphArrangement.h deleted file mode 100644 index ad27a57ed6..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/fonts/juce_GlyphArrangement.h +++ /dev/null @@ -1,319 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_GLYPHARRANGEMENT_H_INCLUDED -#define JUCE_GLYPHARRANGEMENT_H_INCLUDED - - -//============================================================================== -/** - A glyph from a particular font, with a particular size, style, - typeface and position. - - You should rarely need to use this class directly - for most purposes, the - GlyphArrangement class will do what you need for text layout. - - @see GlyphArrangement, Font -*/ -class JUCE_API PositionedGlyph -{ -public: - //============================================================================== - PositionedGlyph() noexcept; - PositionedGlyph (const Font& font, juce_wchar character, int glyphNumber, - float anchorX, float baselineY, float width, bool isWhitespace); - - PositionedGlyph (const PositionedGlyph&); - PositionedGlyph& operator= (const PositionedGlyph&); - - #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS - PositionedGlyph (PositionedGlyph&&) noexcept; - PositionedGlyph& operator= (PositionedGlyph&&) noexcept; - #endif - - ~PositionedGlyph(); - - /** Returns the character the glyph represents. */ - juce_wchar getCharacter() const noexcept { return character; } - /** Checks whether the glyph is actually empty. */ - bool isWhitespace() const noexcept { return whitespace; } - - /** Returns the position of the glyph's left-hand edge. */ - float getLeft() const noexcept { return x; } - /** Returns the position of the glyph's right-hand edge. */ - float getRight() const noexcept { return x + w; } - /** Returns the y position of the glyph's baseline. */ - float getBaselineY() const noexcept { return y; } - /** Returns the y position of the top of the glyph. */ - float getTop() const { return y - font.getAscent(); } - /** Returns the y position of the bottom of the glyph. */ - float getBottom() const { return y + font.getDescent(); } - /** Returns the bounds of the glyph. */ - Rectangle getBounds() const { return Rectangle (x, getTop(), w, font.getHeight()); } - - //============================================================================== - /** Shifts the glyph's position by a relative amount. */ - void moveBy (float deltaX, float deltaY); - - //============================================================================== - /** Draws the glyph into a graphics context. */ - void draw (const Graphics& g) const; - - /** Draws the glyph into a graphics context, with an extra transform applied to it. */ - void draw (const Graphics& g, const AffineTransform& transform) const; - - /** Returns the path for this glyph. - - @param path the glyph's outline will be appended to this path - */ - void createPath (Path& path) const; - - /** Checks to see if a point lies within this glyph. */ - bool hitTest (float x, float y) const; - -private: - //============================================================================== - friend class GlyphArrangement; - Font font; - juce_wchar character; - int glyph; - float x, y, w; - bool whitespace; - - JUCE_LEAK_DETECTOR (PositionedGlyph) -}; - - -//============================================================================== -/** - A set of glyphs, each with a position. - - You can create a GlyphArrangement, text to it and then draw it onto a - graphics context. It's used internally by the text methods in the - Graphics class, but can be used directly if more control is needed. - - @see Font, PositionedGlyph -*/ -class JUCE_API GlyphArrangement -{ -public: - //============================================================================== - /** Creates an empty arrangement. */ - GlyphArrangement(); - - /** Takes a copy of another arrangement. */ - GlyphArrangement (const GlyphArrangement&); - - /** Copies another arrangement onto this one. - To add another arrangement without clearing this one, use addGlyphArrangement(). - */ - GlyphArrangement& operator= (const GlyphArrangement&); - - /** Destructor. */ - ~GlyphArrangement(); - - //============================================================================== - /** Returns the total number of glyphs in the arrangement. */ - int getNumGlyphs() const noexcept { return glyphs.size(); } - - /** Returns one of the glyphs from the arrangement. - - @param index the glyph's index, from 0 to (getNumGlyphs() - 1). Be - careful not to pass an out-of-range index here, as it - doesn't do any bounds-checking. - */ - PositionedGlyph& getGlyph (int index) const noexcept; - - //============================================================================== - /** Clears all text from the arrangement and resets it. */ - void clear(); - - /** Appends a line of text to the arrangement. - - This will add the text as a single line, where x is the left-hand edge of the - first character, and y is the position for the text's baseline. - - If the text contains new-lines or carriage-returns, this will ignore them - use - addJustifiedText() to add multi-line arrangements. - */ - void addLineOfText (const Font& font, - const String& text, - float x, float y); - - /** Adds a line of text, truncating it if it's wider than a specified size. - - This is the same as addLineOfText(), but if the line's width exceeds the value - specified in maxWidthPixels, it will be truncated using either ellipsis (i.e. dots: "..."), - if useEllipsis is true, or if this is false, it will just drop any subsequent characters. - */ - void addCurtailedLineOfText (const Font& font, - const String& text, - float x, float y, - float maxWidthPixels, - bool useEllipsis); - - /** Adds some multi-line text, breaking lines at word-boundaries if they are too wide. - - This will add text to the arrangement, breaking it into new lines either where there - is a new-line or carriage-return character in the text, or where a line's width - exceeds the value set in maxLineWidth. - - Each line that is added will be laid out using the flags set in horizontalLayout, so - the lines can be left- or right-justified, or centred horizontally in the space - between x and (x + maxLineWidth). - - The y coordinate is the position of the baseline of the first line of text - subsequent - lines will be placed below it, separated by a distance of font.getHeight(). - */ - void addJustifiedText (const Font& font, - const String& text, - float x, float y, - float maxLineWidth, - Justification horizontalLayout); - - /** Tries to fit some text withing a given space. - - This does its best to make the given text readable within the specified rectangle, - so it useful for labelling things. - - If the text is too big, it'll be squashed horizontally or broken over multiple lines - if the maximumLinesToUse value allows this. If the text just won't fit into the space, - it'll cram as much as possible in there, and put some ellipsis at the end to show that - it's been truncated. - - A Justification parameter lets you specify how the text is laid out within the rectangle, - both horizontally and vertically. - - @see Graphics::drawFittedText - */ - void addFittedText (const Font& font, - const String& text, - float x, float y, float width, float height, - Justification layout, - int maximumLinesToUse, - float minimumHorizontalScale = 0.7f); - - /** Appends another glyph arrangement to this one. */ - void addGlyphArrangement (const GlyphArrangement&); - - /** Appends a custom glyph to the arrangement. */ - void addGlyph (const PositionedGlyph&); - - //============================================================================== - /** Draws this glyph arrangement to a graphics context. - - This uses cached bitmaps so is much faster than the draw (Graphics&, const AffineTransform&) - method, which renders the glyphs as filled vectors. - */ - void draw (const Graphics&) const; - - /** Draws this glyph arrangement to a graphics context. - - This renders the paths as filled vectors, so is far slower than the draw (Graphics&) - method for non-transformed arrangements. - */ - void draw (const Graphics&, const AffineTransform&) const; - - /** Converts the set of glyphs into a path. - @param path the glyphs' outlines will be appended to this path - */ - void createPath (Path& path) const; - - /** Looks for a glyph that contains the given coordinate. - @returns the index of the glyph, or -1 if none were found. - */ - int findGlyphIndexAt (float x, float y) const; - - //============================================================================== - /** Finds the smallest rectangle that will enclose a subset of the glyphs. - - - @param startIndex the first glyph to test - @param numGlyphs the number of glyphs to include; if this is < 0, all glyphs after - startIndex will be included - @param includeWhitespace if true, the extent of any whitespace characters will also - be taken into account - */ - Rectangle getBoundingBox (int startIndex, int numGlyphs, bool includeWhitespace) const; - - /** Shifts a set of glyphs by a given amount. - - @param startIndex the first glyph to transform - @param numGlyphs the number of glyphs to move; if this is < 0, all glyphs after - startIndex will be used - @param deltaX the amount to add to their x-positions - @param deltaY the amount to add to their y-positions - */ - void moveRangeOfGlyphs (int startIndex, int numGlyphs, - float deltaX, float deltaY); - - /** Removes a set of glyphs from the arrangement. - - @param startIndex the first glyph to remove - @param numGlyphs the number of glyphs to remove; if this is < 0, all glyphs after - startIndex will be deleted - */ - void removeRangeOfGlyphs (int startIndex, int numGlyphs); - - /** Expands or compresses a set of glyphs horizontally. - - @param startIndex the first glyph to transform - @param numGlyphs the number of glyphs to stretch; if this is < 0, all glyphs after - startIndex will be used - @param horizontalScaleFactor how much to scale their horizontal width by - */ - void stretchRangeOfGlyphs (int startIndex, int numGlyphs, - float horizontalScaleFactor); - - /** Justifies a set of glyphs within a given space. - - This moves the glyphs as a block so that the whole thing is located within the - given rectangle with the specified layout. - - If the Justification::horizontallyJustified flag is specified, each line will - be stretched out to fill the specified width. - */ - void justifyGlyphs (int startIndex, int numGlyphs, - float x, float y, float width, float height, - Justification justification); - - -private: - //============================================================================== - Array glyphs; - - int insertEllipsis (const Font&, float maxXPos, int startIndex, int endIndex); - int fitLineIntoSpace (int start, int numGlyphs, float x, float y, float w, float h, const Font&, - Justification, float minimumHorizontalScale); - void spreadOutLine (int start, int numGlyphs, float targetWidth); - void splitLines (const String&, Font, int start, float x, float y, float w, float h, int maxLines, - float lineWidth, Justification, float minimumHorizontalScale); - void addLinesWithLineBreaks (const String&, const Font&, float x, float y, float width, float height, Justification); - void drawGlyphUnderline (const Graphics&, const PositionedGlyph&, int, const AffineTransform&) const; - - JUCE_LEAK_DETECTOR (GlyphArrangement) -}; - - -#endif // JUCE_GLYPHARRANGEMENT_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/fonts/juce_TextLayout.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/fonts/juce_TextLayout.cpp deleted file mode 100644 index 526cac1a9b..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/fonts/juce_TextLayout.cpp +++ /dev/null @@ -1,620 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -TextLayout::Glyph::Glyph (const int glyphCode_, Point anchor_, float width_) noexcept - : glyphCode (glyphCode_), anchor (anchor_), width (width_) -{ -} - -TextLayout::Glyph::Glyph (const Glyph& other) noexcept - : glyphCode (other.glyphCode), anchor (other.anchor), width (other.width) -{ -} - -TextLayout::Glyph& TextLayout::Glyph::operator= (const Glyph& other) noexcept -{ - glyphCode = other.glyphCode; - anchor = other.anchor; - width = other.width; - return *this; -} - -TextLayout::Glyph::~Glyph() noexcept {} - -//============================================================================== -TextLayout::Run::Run() noexcept - : colour (0xff000000) -{ -} - -TextLayout::Run::Run (Range range, const int numGlyphsToPreallocate) - : colour (0xff000000), stringRange (range) -{ - glyphs.ensureStorageAllocated (numGlyphsToPreallocate); -} - -TextLayout::Run::Run (const Run& other) - : font (other.font), - colour (other.colour), - glyphs (other.glyphs), - stringRange (other.stringRange) -{ -} - -TextLayout::Run::~Run() noexcept {} - -//============================================================================== -TextLayout::Line::Line() noexcept - : ascent (0.0f), descent (0.0f), leading (0.0f) -{ -} - -TextLayout::Line::Line (Range stringRange_, Point lineOrigin_, - const float ascent_, const float descent_, const float leading_, - const int numRunsToPreallocate) - : stringRange (stringRange_), lineOrigin (lineOrigin_), - ascent (ascent_), descent (descent_), leading (leading_) -{ - runs.ensureStorageAllocated (numRunsToPreallocate); -} - -TextLayout::Line::Line (const Line& other) - : stringRange (other.stringRange), lineOrigin (other.lineOrigin), - ascent (other.ascent), descent (other.descent), leading (other.leading) -{ - runs.addCopiesOf (other.runs); -} - -TextLayout::Line::~Line() noexcept -{ -} - -Range TextLayout::Line::getLineBoundsX() const noexcept -{ - Range range; - bool isFirst = true; - - for (int i = runs.size(); --i >= 0;) - { - const Run& run = *runs.getUnchecked(i); - - if (run.glyphs.size() > 0) - { - float minX = run.glyphs.getReference(0).anchor.x; - float maxX = minX; - - for (int j = run.glyphs.size(); --j >= 0;) - { - const Glyph& glyph = run.glyphs.getReference (j); - const float x = glyph.anchor.x; - minX = jmin (minX, x); - maxX = jmax (maxX, x + glyph.width); - } - - if (isFirst) - { - isFirst = false; - range = Range (minX, maxX); - } - else - { - range = range.getUnionWith (Range (minX, maxX)); - } - } - } - - return range + lineOrigin.x; -} - -//============================================================================== -TextLayout::TextLayout() - : width (0), justification (Justification::topLeft) -{ -} - -TextLayout::TextLayout (const TextLayout& other) - : width (other.width), - justification (other.justification) -{ - lines.addCopiesOf (other.lines); -} - -#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS -TextLayout::TextLayout (TextLayout&& other) noexcept - : lines (static_cast &&> (other.lines)), - width (other.width), - justification (other.justification) -{ -} - -TextLayout& TextLayout::operator= (TextLayout&& other) noexcept -{ - lines = static_cast &&> (other.lines); - width = other.width; - justification = other.justification; - return *this; -} -#endif - -TextLayout& TextLayout::operator= (const TextLayout& other) -{ - width = other.width; - justification = other.justification; - lines.clear(); - lines.addCopiesOf (other.lines); - return *this; -} - -TextLayout::~TextLayout() -{ -} - -float TextLayout::getHeight() const noexcept -{ - if (const Line* const lastLine = lines.getLast()) - return lastLine->lineOrigin.y + lastLine->descent; - - return 0.0f; -} - -TextLayout::Line& TextLayout::getLine (const int index) const -{ - return *lines[index]; -} - -void TextLayout::ensureStorageAllocated (int numLinesNeeded) -{ - lines.ensureStorageAllocated (numLinesNeeded); -} - -void TextLayout::addLine (Line* line) -{ - lines.add (line); -} - -void TextLayout::draw (Graphics& g, const Rectangle& area) const -{ - const Point origin (justification.appliedToRectangle (Rectangle (width, getHeight()), area).getPosition()); - - LowLevelGraphicsContext& context = g.getInternalContext(); - - for (int i = 0; i < getNumLines(); ++i) - { - const Line& line = getLine (i); - const Point lineOrigin (origin + line.lineOrigin); - - for (int j = 0; j < line.runs.size(); ++j) - { - const Run& run = *line.runs.getUnchecked (j); - context.setFont (run.font); - context.setFill (run.colour); - - for (int k = 0; k < run.glyphs.size(); ++k) - { - const Glyph& glyph = run.glyphs.getReference (k); - context.drawGlyph (glyph.glyphCode, AffineTransform::translation (lineOrigin.x + glyph.anchor.x, - lineOrigin.y + glyph.anchor.y)); - } - } - } -} - -void TextLayout::createLayout (const AttributedString& text, float maxWidth) -{ - lines.clear(); - width = maxWidth; - justification = text.getJustification(); - - if (! createNativeLayout (text)) - createStandardLayout (text); - - recalculateWidth (text); -} - -//============================================================================== -namespace TextLayoutHelpers -{ - struct FontAndColour - { - FontAndColour (const Font* f) noexcept : font (f), colour (0xff000000) {} - - const Font* font; - Colour colour; - - bool operator!= (const FontAndColour& other) const noexcept - { - return (font != other.font && *font != *other.font) || colour != other.colour; - } - }; - - struct RunAttribute - { - RunAttribute (const FontAndColour& fc, const Range r) noexcept - : fontAndColour (fc), range (r) - {} - - FontAndColour fontAndColour; - Range range; - }; - - struct Token - { - Token (const String& t, const Font& f, Colour c, const bool whitespace) - : text (t), font (f), colour (c), - area (font.getStringWidthFloat (t), f.getHeight()), - isWhitespace (whitespace), - isNewLine (t.containsChar ('\n') || t.containsChar ('\r')) - {} - - const String text; - const Font font; - const Colour colour; - Rectangle area; - int line; - float lineHeight; - const bool isWhitespace, isNewLine; - - private: - Token& operator= (const Token&); - }; - - class TokenList - { - public: - TokenList() noexcept : totalLines (0) {} - - void createLayout (const AttributedString& text, TextLayout& layout) - { - tokens.ensureStorageAllocated (64); - layout.ensureStorageAllocated (totalLines); - - addTextRuns (text); - layoutRuns (layout.getWidth()); - - int charPosition = 0; - int lineStartPosition = 0; - int runStartPosition = 0; - - ScopedPointer currentLine; - ScopedPointer currentRun; - - bool needToSetLineOrigin = true; - - for (int i = 0; i < tokens.size(); ++i) - { - const Token& t = *tokens.getUnchecked (i); - - Array newGlyphs; - Array xOffsets; - t.font.getGlyphPositions (getTrimmedEndIfNotAllWhitespace (t.text), newGlyphs, xOffsets); - - if (currentRun == nullptr) currentRun = new TextLayout::Run(); - if (currentLine == nullptr) currentLine = new TextLayout::Line(); - - if (newGlyphs.size() > 0) - { - currentRun->glyphs.ensureStorageAllocated (currentRun->glyphs.size() + newGlyphs.size()); - const Point tokenOrigin (t.area.getPosition().translated (0, t.font.getAscent())); - - if (needToSetLineOrigin) - { - needToSetLineOrigin = false; - currentLine->lineOrigin = tokenOrigin; - } - - const Point glyphOffset (tokenOrigin - currentLine->lineOrigin); - - for (int j = 0; j < newGlyphs.size(); ++j) - { - const float x = xOffsets.getUnchecked (j); - currentRun->glyphs.add (TextLayout::Glyph (newGlyphs.getUnchecked(j), - glyphOffset.translated (x, 0), - xOffsets.getUnchecked (j + 1) - x)); - } - - charPosition += newGlyphs.size(); - } - - if (t.isWhitespace || t.isNewLine) - ++charPosition; - - const Token* const nextToken = tokens [i + 1]; - - if (nextToken == nullptr) // this is the last token - { - addRun (*currentLine, currentRun.release(), t, runStartPosition, charPosition); - currentLine->stringRange = Range (lineStartPosition, charPosition); - - if (! needToSetLineOrigin) - layout.addLine (currentLine.release()); - - needToSetLineOrigin = true; - } - else - { - if (t.font != nextToken->font || t.colour != nextToken->colour) - { - addRun (*currentLine, currentRun.release(), t, runStartPosition, charPosition); - runStartPosition = charPosition; - } - - if (t.line != nextToken->line) - { - if (currentRun == nullptr) - currentRun = new TextLayout::Run(); - - addRun (*currentLine, currentRun.release(), t, runStartPosition, charPosition); - currentLine->stringRange = Range (lineStartPosition, charPosition); - - if (! needToSetLineOrigin) - layout.addLine (currentLine.release()); - - runStartPosition = charPosition; - lineStartPosition = charPosition; - needToSetLineOrigin = true; - } - } - } - - if ((text.getJustification().getFlags() & (Justification::right | Justification::horizontallyCentred)) != 0) - { - const float totalW = layout.getWidth(); - const bool isCentred = (text.getJustification().getFlags() & Justification::horizontallyCentred) != 0; - - for (int i = 0; i < layout.getNumLines(); ++i) - { - float dx = totalW - layout.getLine(i).getLineBoundsX().getLength(); - - if (isCentred) - dx /= 2.0f; - - layout.getLine(i).lineOrigin.x += dx; - } - } - } - - private: - static void addRun (TextLayout::Line& glyphLine, TextLayout::Run* glyphRun, - const Token& t, const int start, const int end) - { - glyphRun->stringRange = Range (start, end); - glyphRun->font = t.font; - glyphRun->colour = t.colour; - glyphLine.ascent = jmax (glyphLine.ascent, t.font.getAscent()); - glyphLine.descent = jmax (glyphLine.descent, t.font.getDescent()); - glyphLine.runs.add (glyphRun); - } - - static int getCharacterType (const juce_wchar c) noexcept - { - if (c == '\r' || c == '\n') - return 0; - - return CharacterFunctions::isWhitespace (c) ? 2 : 1; - } - - void appendText (const AttributedString& text, const Range stringRange, - const Font& font, Colour colour) - { - const String stringText (text.getText().substring (stringRange.getStart(), stringRange.getEnd())); - String::CharPointerType t (stringText.getCharPointer()); - String currentString; - int lastCharType = 0; - - for (;;) - { - const juce_wchar c = t.getAndAdvance(); - if (c == 0) - break; - - const int charType = getCharacterType (c); - - if (charType == 0 || charType != lastCharType) - { - if (currentString.isNotEmpty()) - tokens.add (new Token (currentString, font, colour, - lastCharType == 2 || lastCharType == 0)); - - currentString = String::charToString (c); - - if (c == '\r' && *t == '\n') - currentString += t.getAndAdvance(); - } - else - { - currentString += c; - } - - lastCharType = charType; - } - - if (currentString.isNotEmpty()) - tokens.add (new Token (currentString, font, colour, lastCharType == 2)); - } - - void layoutRuns (const float maxWidth) - { - float x = 0, y = 0, h = 0; - int i; - - for (i = 0; i < tokens.size(); ++i) - { - Token& t = *tokens.getUnchecked(i); - t.area.setPosition (x, y); - t.line = totalLines; - x += t.area.getWidth(); - h = jmax (h, t.area.getHeight()); - - const Token* const nextTok = tokens[i + 1]; - - if (nextTok == nullptr) - break; - - if (t.isNewLine || ((! nextTok->isWhitespace) && x + nextTok->area.getWidth() > maxWidth)) - { - setLastLineHeight (i + 1, h); - x = 0; - y += h; - h = 0; - ++totalLines; - } - } - - setLastLineHeight (jmin (i + 1, tokens.size()), h); - ++totalLines; - } - - void setLastLineHeight (int i, const float height) noexcept - { - while (--i >= 0) - { - Token& tok = *tokens.getUnchecked (i); - - if (tok.line == totalLines) - tok.lineHeight = height; - else - break; - } - } - - void addTextRuns (const AttributedString& text) - { - Font defaultFont; - Array runAttributes; - - { - const int stringLength = text.getText().length(); - int rangeStart = 0; - FontAndColour lastFontAndColour (&defaultFont); - - // Iterate through every character in the string - for (int i = 0; i < stringLength; ++i) - { - FontAndColour newFontAndColour (&defaultFont); - const int numCharacterAttributes = text.getNumAttributes(); - - for (int j = 0; j < numCharacterAttributes; ++j) - { - const AttributedString::Attribute& attr = *text.getAttribute (j); - - if (attr.range.contains (i)) - { - if (const Font* f = attr.getFont()) newFontAndColour.font = f; - if (const Colour* c = attr.getColour()) newFontAndColour.colour = *c; - } - } - - if (i > 0 && newFontAndColour != lastFontAndColour) - { - runAttributes.add (RunAttribute (lastFontAndColour, Range (rangeStart, i))); - rangeStart = i; - } - - lastFontAndColour = newFontAndColour; - } - - if (rangeStart < stringLength) - runAttributes.add (RunAttribute (lastFontAndColour, Range (rangeStart, stringLength))); - } - - for (int i = 0; i < runAttributes.size(); ++i) - { - const RunAttribute& r = runAttributes.getReference(i); - appendText (text, r.range, *(r.fontAndColour.font), r.fontAndColour.colour); - } - } - - static String getTrimmedEndIfNotAllWhitespace (const String& s) - { - String trimmed (s.trimEnd()); - if (trimmed.isEmpty() && ! s.isEmpty()) - trimmed = s.replaceCharacters ("\r\n\t", " "); - - return trimmed; - } - - OwnedArray tokens; - int totalLines; - - JUCE_DECLARE_NON_COPYABLE (TokenList) - }; -} - -//============================================================================== -void TextLayout::createLayoutWithBalancedLineLengths (const AttributedString& text, float maxWidth) -{ - const float minimumWidth = maxWidth / 2.0f; - float bestWidth = maxWidth; - float bestLineProportion = 0.0f; - - while (maxWidth > minimumWidth) - { - createLayout (text, maxWidth); - - if (getNumLines() < 2) - return; - - const float line1 = lines.getUnchecked (lines.size() - 1)->getLineBoundsX().getLength(); - const float line2 = lines.getUnchecked (lines.size() - 2)->getLineBoundsX().getLength(); - const float shortestLine = jmin (line1, line2); - const float prop = (shortestLine > 0) ? jmax (line1, line2) / shortestLine : 1.0f; - - if (prop > 0.9f) - return; - - if (prop > bestLineProportion) - { - bestLineProportion = prop; - bestWidth = maxWidth; - } - - maxWidth -= 10.0f; - } - - if (bestWidth != maxWidth) - createLayout (text, bestWidth); -} - -//============================================================================== -void TextLayout::createStandardLayout (const AttributedString& text) -{ - TextLayoutHelpers::TokenList l; - l.createLayout (text, *this); -} - -void TextLayout::recalculateWidth (const AttributedString& text) -{ - if (lines.size() > 0 && text.getReadingDirection() != AttributedString::rightToLeft) - { - Range range (lines.getFirst()->getLineBoundsX()); - - for (int i = lines.size(); --i > 0;) - range = range.getUnionWith (lines.getUnchecked(i)->getLineBoundsX()); - - for (int i = lines.size(); --i >= 0;) - lines.getUnchecked(i)->lineOrigin.x -= range.getStart(); - - width = range.getLength(); - } -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/fonts/juce_TextLayout.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/fonts/juce_TextLayout.h deleted file mode 100644 index b5f9eeadd1..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/fonts/juce_TextLayout.h +++ /dev/null @@ -1,177 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_TEXTLAYOUT_H_INCLUDED -#define JUCE_TEXTLAYOUT_H_INCLUDED - - -//============================================================================== -/** - A Pre-formatted piece of text, which may contain multiple fonts and colours. - - A TextLayout is created from an AttributedString, and once created can be - quickly drawn into a Graphics context. - - @see AttributedString -*/ -class JUCE_API TextLayout -{ -public: - /** Creates an empty layout. - Having created a TextLayout, you can populate it using createLayout() or - createLayoutWithBalancedLineLengths(). - */ - TextLayout(); - TextLayout (const TextLayout&); - TextLayout& operator= (const TextLayout&); - #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS - TextLayout (TextLayout&& other) noexcept; - TextLayout& operator= (TextLayout&&) noexcept; - #endif - - /** Destructor. */ - ~TextLayout(); - - //============================================================================== - /** Creates a layout from the given attributed string. - This will replace any data that is currently stored in the layout. - */ - void createLayout (const AttributedString& text, float maxWidth); - - /** Creates a layout, attempting to choose a width which results in lines - of a similar length. - - This will be slower than the normal createLayout method, but produces a - tidier result. - */ - void createLayoutWithBalancedLineLengths (const AttributedString& text, float maxWidth); - - /** Draws the layout within the specified area. - The position of the text within the rectangle is controlled by the justification - flags set in the original AttributedString that was used to create this layout. - */ - void draw (Graphics& g, const Rectangle& area) const; - - //============================================================================== - /** A positioned glyph. */ - class JUCE_API Glyph - { - public: - Glyph (int glyphCode, Point anchor, float width) noexcept; - Glyph (const Glyph&) noexcept; - Glyph& operator= (const Glyph&) noexcept; - ~Glyph() noexcept; - - /** The code number of this glyph. */ - int glyphCode; - - /** The glyph's anchor point - this is relative to the line's origin. - @see TextLayout::Line::lineOrigin - */ - Point anchor; - - float width; - - private: - JUCE_LEAK_DETECTOR (Glyph) - }; - - //============================================================================== - /** A sequence of glyphs with a common font and colour. */ - class JUCE_API Run - { - public: - Run() noexcept; - Run (const Run&); - Run (Range stringRange, int numGlyphsToPreallocate); - ~Run() noexcept; - - Font font; /**< The run's font. */ - Colour colour; /**< The run's colour. */ - Array glyphs; /**< The glyphs in this run. */ - Range stringRange; /**< The character range that this run represents in the - original string that was used to create it. */ - private: - Run& operator= (const Run&); - JUCE_LEAK_DETECTOR (Run) - }; - - //============================================================================== - /** A line containing a sequence of glyph-runs. */ - class JUCE_API Line - { - public: - Line() noexcept; - Line (const Line&); - Line (Range stringRange, Point lineOrigin, - float ascent, float descent, float leading, int numRunsToPreallocate); - ~Line() noexcept; - - /** Returns the X position range which contains all the glyphs in this line. */ - Range getLineBoundsX() const noexcept; - - OwnedArray runs; /**< The glyph-runs in this line. */ - Range stringRange; /**< The character range that this line represents in the - original string that was used to create it. */ - Point lineOrigin; /**< The line's baseline origin. */ - float ascent, descent, leading; - - private: - Line& operator= (const Line&); - JUCE_LEAK_DETECTOR (Line) - }; - - //============================================================================== - /** Returns the maximum width of the content. */ - float getWidth() const noexcept { return width; } - - /** Returns the maximum height of the content. */ - float getHeight() const noexcept; - - /** Returns the number of lines in the layout. */ - int getNumLines() const noexcept { return lines.size(); } - - /** Returns one of the lines. */ - Line& getLine (int index) const; - - /** Adds a line to the layout. The layout will take ownership of this line object - and will delete it when it is no longer needed. */ - void addLine (Line* line); - - /** Pre-allocates space for the specified number of lines. */ - void ensureStorageAllocated (int numLinesNeeded); - -private: - OwnedArray lines; - float width; - Justification justification; - - void createStandardLayout (const AttributedString&); - bool createNativeLayout (const AttributedString&); - void recalculateWidth (const AttributedString&); - - JUCE_LEAK_DETECTOR (TextLayout) -}; - -#endif // JUCE_TEXTLAYOUT_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/fonts/juce_Typeface.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/fonts/juce_Typeface.cpp deleted file mode 100644 index 4eda6b0345..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/fonts/juce_Typeface.cpp +++ /dev/null @@ -1,260 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -struct FontStyleHelpers -{ - static const char* getStyleName (const bool bold, - const bool italic) noexcept - { - if (bold && italic) return "Bold Italic"; - if (bold) return "Bold"; - if (italic) return "Italic"; - return "Regular"; - } - - static const char* getStyleName (const int styleFlags) noexcept - { - return getStyleName ((styleFlags & Font::bold) != 0, - (styleFlags & Font::italic) != 0); - } - - static bool isBold (const String& style) noexcept - { - return style.containsWholeWordIgnoreCase ("Bold"); - } - - static bool isItalic (const String& style) noexcept - { - return style.containsWholeWordIgnoreCase ("Italic") - || style.containsWholeWordIgnoreCase ("Oblique"); - } - - static bool isPlaceholderFamilyName (const String& family) - { - return family == Font::getDefaultSansSerifFontName() - || family == Font::getDefaultSerifFontName() - || family == Font::getDefaultMonospacedFontName(); - } - - struct ConcreteFamilyNames - { - ConcreteFamilyNames() - : sans (findName (Font::getDefaultSansSerifFontName())), - serif (findName (Font::getDefaultSerifFontName())), - mono (findName (Font::getDefaultMonospacedFontName())) - { - } - - String lookUp (const String& placeholder) - { - if (placeholder == Font::getDefaultSansSerifFontName()) return sans; - if (placeholder == Font::getDefaultSerifFontName()) return serif; - if (placeholder == Font::getDefaultMonospacedFontName()) return mono; - - return findName (placeholder); - } - - private: - static String findName (const String& placeholder) - { - const Font f (placeholder, Font::getDefaultStyle(), 15.0f); - return Font::getDefaultTypefaceForFont (f)->getName(); - } - - String sans, serif, mono; - }; - - static String getConcreteFamilyNameFromPlaceholder (const String& placeholder) - { - static ConcreteFamilyNames names; - return names.lookUp (placeholder); - } - - static String getConcreteFamilyName (const Font& font) - { - const String& family = font.getTypefaceName(); - - return isPlaceholderFamilyName (family) ? getConcreteFamilyNameFromPlaceholder (family) - : family; - } -}; - -//============================================================================== -Typeface::Typeface (const String& faceName, const String& styleName) noexcept - : name (faceName), style (styleName) -{ -} - -Typeface::~Typeface() -{ -} - -Typeface::Ptr Typeface::getFallbackTypeface() -{ - const Font fallbackFont (Font::getFallbackFontName(), Font::getFallbackFontStyle(), 10.0f); - return fallbackFont.getTypeface(); -} - -EdgeTable* Typeface::getEdgeTableForGlyph (int glyphNumber, const AffineTransform& transform, float fontHeight) -{ - Path path; - - if (getOutlineForGlyph (glyphNumber, path) && ! path.isEmpty()) - { - applyVerticalHintingTransform (fontHeight, path); - - return new EdgeTable (path.getBoundsTransformed (transform).getSmallestIntegerContainer().expanded (1, 0), - path, transform); - } - - return nullptr; -} - -//============================================================================== -struct Typeface::HintingParams -{ - HintingParams (Typeface& t) - : cachedSize (0), top (0), middle (0), bottom (0) - { - Font font (&t); - font = font.withHeight ((float) standardHeight); - - top = getAverageY (font, "BDEFPRTZOQ", true); - middle = getAverageY (font, "acegmnopqrsuvwxy", true); - bottom = getAverageY (font, "BDELZOC", false); - } - - void applyVerticalHintingTransform (float fontSize, Path& path) - { - if (cachedSize != fontSize) - { - cachedSize = fontSize; - cachedScale = Scaling (top, middle, bottom, fontSize); - } - - if (bottom < top + 3.0f / fontSize) - return; - - Path result; - - for (Path::Iterator i (path); i.next();) - { - switch (i.elementType) - { - case Path::Iterator::startNewSubPath: result.startNewSubPath (i.x1, cachedScale.apply (i.y1)); break; - case Path::Iterator::lineTo: result.lineTo (i.x1, cachedScale.apply (i.y1)); break; - case Path::Iterator::quadraticTo: result.quadraticTo (i.x1, cachedScale.apply (i.y1), - i.x2, cachedScale.apply (i.y2)); break; - case Path::Iterator::cubicTo: result.cubicTo (i.x1, cachedScale.apply (i.y1), - i.x2, cachedScale.apply (i.y2), - i.x3, cachedScale.apply (i.y3)); break; - case Path::Iterator::closePath: result.closeSubPath(); break; - default: jassertfalse; break; - } - } - - result.swapWithPath (path); - } - -private: - struct Scaling - { - Scaling() noexcept : middle(), upperScale(), upperOffset(), lowerScale(), lowerOffset() {} - - Scaling (float t, float m, float b, float fontSize) noexcept : middle (m) - { - const float newT = std::floor (fontSize * t + 0.5f) / fontSize; - const float newB = std::floor (fontSize * b + 0.5f) / fontSize; - const float newM = std::floor (fontSize * m + 0.3f) / fontSize; // this is slightly biased so that lower-case letters - // are more likely to become taller than shorter. - upperScale = jlimit (0.9f, 1.1f, (newM - newT) / (m - t)); - lowerScale = jlimit (0.9f, 1.1f, (newB - newM) / (b - m)); - - upperOffset = newM - m * upperScale; - lowerOffset = newB - b * lowerScale; - } - - float apply (float y) const noexcept - { - return y < middle ? (y * upperScale + upperOffset) - : (y * lowerScale + lowerOffset); - } - - float middle, upperScale, upperOffset, lowerScale, lowerOffset; - }; - - float cachedSize; - Scaling cachedScale; - - static float getAverageY (const Font& font, const char* chars, bool getTop) - { - GlyphArrangement ga; - ga.addLineOfText (font, chars, 0, 0); - - Array y; - DefaultElementComparator sorter; - - for (int i = 0; i < ga.getNumGlyphs(); ++i) - { - Path p; - ga.getGlyph (i).createPath (p); - Rectangle bounds (p.getBounds()); - - if (! p.isEmpty()) - y.addSorted (sorter, getTop ? bounds.getY() : bounds.getBottom()); - } - - float median = y[y.size() / 2]; - - float total = 0; - int num = 0; - - for (int i = 0; i < y.size(); ++i) - { - if (std::abs (median - y.getUnchecked(i)) < 0.05f * (float) standardHeight) - { - total += y.getUnchecked(i); - ++num; - } - } - - return num < 4 ? 0.0f : total / (num * (float) standardHeight); - } - - enum { standardHeight = 100 }; - float top, middle, bottom; -}; - -void Typeface::applyVerticalHintingTransform (float fontSize, Path& path) -{ - if (fontSize > 3.0f && fontSize < 25.0f) - { - ScopedLock sl (hintingLock); - - if (hintingParams == nullptr) - hintingParams = new HintingParams (*this); - - return hintingParams->applyVerticalHintingTransform (fontSize, path); - } -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/fonts/juce_Typeface.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/fonts/juce_Typeface.h deleted file mode 100644 index a392fb705d..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/fonts/juce_Typeface.h +++ /dev/null @@ -1,161 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_TYPEFACE_H_INCLUDED -#define JUCE_TYPEFACE_H_INCLUDED - - -//============================================================================== -/** - A typeface represents a size-independent font. - - This base class is abstract, but calling createSystemTypefaceFor() will return - a platform-specific subclass that can be used. - - The CustomTypeface subclass allow you to build your own typeface, and to - load and save it in the Juce typeface format. - - Normally you should never need to deal directly with Typeface objects - the Font - class does everything you typically need for rendering text. - - @see CustomTypeface, Font -*/ -class JUCE_API Typeface : public ReferenceCountedObject -{ -public: - //============================================================================== - /** A handy typedef for a pointer to a typeface. */ - typedef ReferenceCountedObjectPtr Ptr; - - //============================================================================== - /** Returns the font family of the typeface. - @see Font::getTypefaceName - */ - const String& getName() const noexcept { return name; } - - //============================================================================== - /** Returns the font style of the typeface. - @see Font::getTypefaceStyle - */ - const String& getStyle() const noexcept { return style; } - - //============================================================================== - /** Creates a new system typeface. */ - static Ptr createSystemTypefaceFor (const Font& font); - - /** Attempts to create a font from some raw font file data (e.g. a TTF or OTF file image). - The system will take its own internal copy of the data, so you can free the block once - this method has returned. - */ - static Ptr createSystemTypefaceFor (const void* fontFileData, size_t fontFileDataSize); - - //============================================================================== - /** Destructor. */ - virtual ~Typeface(); - - /** Returns true if this typeface can be used to render the specified font. - When called, the font will already have been checked to make sure that its name and - style flags match the typeface. - */ - virtual bool isSuitableForFont (const Font&) const { return true; } - - /** Returns the ascent of the font, as a proportion of its height. - The height is considered to always be normalised as 1.0, so this will be a - value less that 1.0, indicating the proportion of the font that lies above - its baseline. - */ - virtual float getAscent() const = 0; - - /** Returns the descent of the font, as a proportion of its height. - The height is considered to always be normalised as 1.0, so this will be a - value less that 1.0, indicating the proportion of the font that lies below - its baseline. - */ - virtual float getDescent() const = 0; - - /** Returns the value by which you should multiply a juce font-height value to - convert it to the equivalent point-size. - */ - virtual float getHeightToPointsFactor() const = 0; - - /** Measures the width of a line of text. - The distance returned is based on the font having an normalised height of 1.0. - You should never need to call this directly! Use Font::getStringWidth() instead! - */ - virtual float getStringWidth (const String& text) = 0; - - /** Converts a line of text into its glyph numbers and their positions. - The distances returned are based on the font having an normalised height of 1.0. - You should never need to call this directly! Use Font::getGlyphPositions() instead! - */ - virtual void getGlyphPositions (const String& text, Array & glyphs, Array& xOffsets) = 0; - - /** Returns the outline for a glyph. - The path returned will be normalised to a font height of 1.0. - */ - virtual bool getOutlineForGlyph (int glyphNumber, Path& path) = 0; - - /** Returns a new EdgeTable that contains the path for the givem glyph, with the specified transform applied. */ - virtual EdgeTable* getEdgeTableForGlyph (int glyphNumber, const AffineTransform& transform, float fontHeight); - - /** Returns true if the typeface uses hinting. */ - virtual bool isHinted() const { return false; } - - //============================================================================== - /** Changes the number of fonts that are cached in memory. */ - static void setTypefaceCacheSize (int numFontsToCache); - - /** Clears any fonts that are currently cached in memory. */ - static void clearTypefaceCache(); - - /** On some platforms, this allows a specific path to be scanned. - Currently only available when using FreeType. - */ - static void scanFolderForFonts (const File& folder); - - /** Makes an attempt at performing a good overall distortion that will scale a font of - the given size to align vertically with the pixel grid. The path should be an unscaled - (i.e. normalised to height of 1.0) path for a glyph. - */ - void applyVerticalHintingTransform (float fontHeight, Path& path); - -protected: - //============================================================================== - String name, style; - - Typeface (const String& name, const String& style) noexcept; - - static Ptr getFallbackTypeface(); - -private: - struct HintingParams; - friend struct ContainerDeletePolicy; - ScopedPointer hintingParams; - CriticalSection hintingLock; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Typeface) -}; - - -#endif // JUCE_TYPEFACE_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/geometry/juce_AffineTransform.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/geometry/juce_AffineTransform.cpp deleted file mode 100644 index 85d6f4e8ed..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/geometry/juce_AffineTransform.cpp +++ /dev/null @@ -1,262 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -AffineTransform::AffineTransform() noexcept - : mat00 (1.0f), mat01 (0), mat02 (0), - mat10 (0), mat11 (1.0f), mat12 (0) -{ -} - -AffineTransform::AffineTransform (const AffineTransform& other) noexcept - : mat00 (other.mat00), mat01 (other.mat01), mat02 (other.mat02), - mat10 (other.mat10), mat11 (other.mat11), mat12 (other.mat12) -{ -} - -AffineTransform::AffineTransform (const float m00, const float m01, const float m02, - const float m10, const float m11, const float m12) noexcept - : mat00 (m00), mat01 (m01), mat02 (m02), - mat10 (m10), mat11 (m11), mat12 (m12) -{ -} - -AffineTransform& AffineTransform::operator= (const AffineTransform& other) noexcept -{ - mat00 = other.mat00; - mat01 = other.mat01; - mat02 = other.mat02; - mat10 = other.mat10; - mat11 = other.mat11; - mat12 = other.mat12; - - return *this; -} - -bool AffineTransform::operator== (const AffineTransform& other) const noexcept -{ - return mat00 == other.mat00 - && mat01 == other.mat01 - && mat02 == other.mat02 - && mat10 == other.mat10 - && mat11 == other.mat11 - && mat12 == other.mat12; -} - -bool AffineTransform::operator!= (const AffineTransform& other) const noexcept -{ - return ! operator== (other); -} - -//============================================================================== -bool AffineTransform::isIdentity() const noexcept -{ - return (mat01 == 0) - && (mat02 == 0) - && (mat10 == 0) - && (mat12 == 0) - && (mat00 == 1.0f) - && (mat11 == 1.0f); -} - -const AffineTransform AffineTransform::identity; - -//============================================================================== -AffineTransform AffineTransform::followedBy (const AffineTransform& other) const noexcept -{ - return AffineTransform (other.mat00 * mat00 + other.mat01 * mat10, - other.mat00 * mat01 + other.mat01 * mat11, - other.mat00 * mat02 + other.mat01 * mat12 + other.mat02, - other.mat10 * mat00 + other.mat11 * mat10, - other.mat10 * mat01 + other.mat11 * mat11, - other.mat10 * mat02 + other.mat11 * mat12 + other.mat12); -} - -AffineTransform AffineTransform::translated (const float dx, const float dy) const noexcept -{ - return AffineTransform (mat00, mat01, mat02 + dx, - mat10, mat11, mat12 + dy); -} - -AffineTransform AffineTransform::translation (const float dx, const float dy) noexcept -{ - return AffineTransform (1.0f, 0, dx, - 0, 1.0f, dy); -} - -AffineTransform AffineTransform::withAbsoluteTranslation (const float tx, const float ty) const noexcept -{ - return AffineTransform (mat00, mat01, tx, - mat10, mat11, ty); -} - -AffineTransform AffineTransform::rotated (const float rad) const noexcept -{ - const float cosRad = std::cos (rad); - const float sinRad = std::sin (rad); - - return AffineTransform (cosRad * mat00 + -sinRad * mat10, - cosRad * mat01 + -sinRad * mat11, - cosRad * mat02 + -sinRad * mat12, - sinRad * mat00 + cosRad * mat10, - sinRad * mat01 + cosRad * mat11, - sinRad * mat02 + cosRad * mat12); -} - -AffineTransform AffineTransform::rotation (const float rad) noexcept -{ - const float cosRad = std::cos (rad); - const float sinRad = std::sin (rad); - - return AffineTransform (cosRad, -sinRad, 0, - sinRad, cosRad, 0); -} - -AffineTransform AffineTransform::rotation (const float rad, const float pivotX, const float pivotY) noexcept -{ - const float cosRad = std::cos (rad); - const float sinRad = std::sin (rad); - - return AffineTransform (cosRad, -sinRad, -cosRad * pivotX + sinRad * pivotY + pivotX, - sinRad, cosRad, -sinRad * pivotX + -cosRad * pivotY + pivotY); -} - -AffineTransform AffineTransform::rotated (const float angle, const float pivotX, const float pivotY) const noexcept -{ - return followedBy (rotation (angle, pivotX, pivotY)); -} - -AffineTransform AffineTransform::scaled (const float factorX, const float factorY) const noexcept -{ - return AffineTransform (factorX * mat00, factorX * mat01, factorX * mat02, - factorY * mat10, factorY * mat11, factorY * mat12); -} - -AffineTransform AffineTransform::scaled (const float factor) const noexcept -{ - return AffineTransform (factor * mat00, factor * mat01, factor * mat02, - factor * mat10, factor * mat11, factor * mat12); -} - -AffineTransform AffineTransform::scale (const float factorX, const float factorY) noexcept -{ - return AffineTransform (factorX, 0, 0, 0, factorY, 0); -} - -AffineTransform AffineTransform::scale (const float factor) noexcept -{ - return AffineTransform (factor, 0, 0, 0, factor, 0); -} - -AffineTransform AffineTransform::scaled (const float factorX, const float factorY, - const float pivotX, const float pivotY) const noexcept -{ - return AffineTransform (factorX * mat00, factorX * mat01, factorX * mat02 + pivotX * (1.0f - factorX), - factorY * mat10, factorY * mat11, factorY * mat12 + pivotY * (1.0f - factorY)); -} - -AffineTransform AffineTransform::scale (const float factorX, const float factorY, - const float pivotX, const float pivotY) noexcept -{ - return AffineTransform (factorX, 0, pivotX * (1.0f - factorX), - 0, factorY, pivotY * (1.0f - factorY)); -} - -AffineTransform AffineTransform::shear (float shearX, float shearY) noexcept -{ - return AffineTransform (1.0f, shearX, 0, - shearY, 1.0f, 0); -} - -AffineTransform AffineTransform::sheared (const float shearX, const float shearY) const noexcept -{ - return AffineTransform (mat00 + shearX * mat10, - mat01 + shearX * mat11, - mat02 + shearX * mat12, - mat10 + shearY * mat00, - mat11 + shearY * mat01, - mat12 + shearY * mat02); -} - -AffineTransform AffineTransform::verticalFlip (const float height) noexcept -{ - return AffineTransform (1.0f, 0, 0, 0, -1.0f, height); -} - -AffineTransform AffineTransform::inverted() const noexcept -{ - double determinant = (mat00 * mat11 - mat10 * mat01); - - if (determinant != 0.0) - { - determinant = 1.0 / determinant; - - const float dst00 = (float) ( mat11 * determinant); - const float dst10 = (float) (-mat10 * determinant); - const float dst01 = (float) (-mat01 * determinant); - const float dst11 = (float) ( mat00 * determinant); - - return AffineTransform (dst00, dst01, -mat02 * dst00 - mat12 * dst01, - dst10, dst11, -mat02 * dst10 - mat12 * dst11); - } - else - { - // singularity.. - return *this; - } -} - -bool AffineTransform::isSingularity() const noexcept -{ - return (mat00 * mat11 - mat10 * mat01) == 0; -} - -AffineTransform AffineTransform::fromTargetPoints (const float x00, const float y00, - const float x10, const float y10, - const float x01, const float y01) noexcept -{ - return AffineTransform (x10 - x00, x01 - x00, x00, - y10 - y00, y01 - y00, y00); -} - -AffineTransform AffineTransform::fromTargetPoints (const float sx1, const float sy1, const float tx1, const float ty1, - const float sx2, const float sy2, const float tx2, const float ty2, - const float sx3, const float sy3, const float tx3, const float ty3) noexcept -{ - return fromTargetPoints (sx1, sy1, sx2, sy2, sx3, sy3) - .inverted() - .followedBy (fromTargetPoints (tx1, ty1, tx2, ty2, tx3, ty3)); -} - -bool AffineTransform::isOnlyTranslation() const noexcept -{ - return (mat01 == 0) - && (mat10 == 0) - && (mat00 == 1.0f) - && (mat11 == 1.0f); -} - -float AffineTransform::getScaleFactor() const noexcept -{ - return (std::abs (mat00) + std::abs (mat11)) / 2.0f; -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/geometry/juce_AffineTransform.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/geometry/juce_AffineTransform.h deleted file mode 100644 index f30fdb81f8..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/geometry/juce_AffineTransform.h +++ /dev/null @@ -1,285 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_AFFINETRANSFORM_H_INCLUDED -#define JUCE_AFFINETRANSFORM_H_INCLUDED - - -//============================================================================== -/** - Represents a 2D affine-transformation matrix. - - An affine transformation is a transformation such as a rotation, scale, shear, - resize or translation. - - These are used for various 2D transformation tasks, e.g. with Path objects. - - @see Path, Point, Line -*/ -class JUCE_API AffineTransform -{ -public: - //============================================================================== - /** Creates an identity transform. */ - AffineTransform() noexcept; - - /** Creates a copy of another transform. */ - AffineTransform (const AffineTransform& other) noexcept; - - /** Creates a transform from a set of raw matrix values. - - The resulting matrix is: - - (mat00 mat01 mat02) - (mat10 mat11 mat12) - ( 0 0 1 ) - */ - AffineTransform (float mat00, float mat01, float mat02, - float mat10, float mat11, float mat12) noexcept; - - /** Copies from another AffineTransform object */ - AffineTransform& operator= (const AffineTransform& other) noexcept; - - /** Compares two transforms. */ - bool operator== (const AffineTransform& other) const noexcept; - - /** Compares two transforms. */ - bool operator!= (const AffineTransform& other) const noexcept; - - /** A ready-to-use identity transform, which you can use to append other - transformations to. - - e.g. @code - AffineTransform myTransform = AffineTransform::identity.rotated (.5f) - .scaled (2.0f); - @endcode - */ - static const AffineTransform identity; - - //============================================================================== - /** Transforms a 2D coordinate using this matrix. */ - template - void transformPoint (ValueType& x, ValueType& y) const noexcept - { - const ValueType oldX = x; - x = static_cast (mat00 * oldX + mat01 * y + mat02); - y = static_cast (mat10 * oldX + mat11 * y + mat12); - } - - /** Transforms two 2D coordinates using this matrix. - This is just a shortcut for calling transformPoint() on each of these pairs of - coordinates in turn. (And putting all the calculations into one function hopefully - also gives the compiler a bit more scope for pipelining it). - */ - template - void transformPoints (ValueType& x1, ValueType& y1, - ValueType& x2, ValueType& y2) const noexcept - { - const ValueType oldX1 = x1, oldX2 = x2; - x1 = static_cast (mat00 * oldX1 + mat01 * y1 + mat02); - y1 = static_cast (mat10 * oldX1 + mat11 * y1 + mat12); - x2 = static_cast (mat00 * oldX2 + mat01 * y2 + mat02); - y2 = static_cast (mat10 * oldX2 + mat11 * y2 + mat12); - } - - /** Transforms three 2D coordinates using this matrix. - This is just a shortcut for calling transformPoint() on each of these pairs of - coordinates in turn. (And putting all the calculations into one function hopefully - also gives the compiler a bit more scope for pipelining it). - */ - template - void transformPoints (ValueType& x1, ValueType& y1, - ValueType& x2, ValueType& y2, - ValueType& x3, ValueType& y3) const noexcept - { - const ValueType oldX1 = x1, oldX2 = x2, oldX3 = x3; - x1 = static_cast (mat00 * oldX1 + mat01 * y1 + mat02); - y1 = static_cast (mat10 * oldX1 + mat11 * y1 + mat12); - x2 = static_cast (mat00 * oldX2 + mat01 * y2 + mat02); - y2 = static_cast (mat10 * oldX2 + mat11 * y2 + mat12); - x3 = static_cast (mat00 * oldX3 + mat01 * y3 + mat02); - y3 = static_cast (mat10 * oldX3 + mat11 * y3 + mat12); - } - - //============================================================================== - /** Returns a new transform which is the same as this one followed by a translation. */ - AffineTransform translated (float deltaX, - float deltaY) const noexcept; - - /** Returns a new transform which is the same as this one followed by a translation. */ - template - AffineTransform translated (PointType delta) const noexcept - { - return translated ((float) delta.x, (float) delta.y); - } - - /** Returns a new transform which is a translation. */ - static AffineTransform translation (float deltaX, - float deltaY) noexcept; - - /** Returns a new transform which is a translation. */ - template - static AffineTransform translation (PointType delta) noexcept - { - return translation ((float) delta.x, (float) delta.y); - } - - /** Returns a copy of this transform with the specified translation matrix values. */ - AffineTransform withAbsoluteTranslation (float translationX, - float translationY) const noexcept; - - /** Returns a transform which is the same as this one followed by a rotation. - - The rotation is specified by a number of radians to rotate clockwise, centred around - the origin (0, 0). - */ - AffineTransform rotated (float angleInRadians) const noexcept; - - /** Returns a transform which is the same as this one followed by a rotation about a given point. - - The rotation is specified by a number of radians to rotate clockwise, centred around - the coordinates passed in. - */ - AffineTransform rotated (float angleInRadians, - float pivotX, - float pivotY) const noexcept; - - /** Returns a new transform which is a rotation about (0, 0). */ - static AffineTransform rotation (float angleInRadians) noexcept; - - /** Returns a new transform which is a rotation about a given point. */ - static AffineTransform rotation (float angleInRadians, - float pivotX, - float pivotY) noexcept; - - /** Returns a transform which is the same as this one followed by a re-scaling. - The scaling is centred around the origin (0, 0). - */ - AffineTransform scaled (float factorX, - float factorY) const noexcept; - - /** Returns a transform which is the same as this one followed by a re-scaling. - The scaling is centred around the origin (0, 0). - */ - AffineTransform scaled (float factor) const noexcept; - - /** Returns a transform which is the same as this one followed by a re-scaling. - The scaling is centred around the origin provided. - */ - AffineTransform scaled (float factorX, float factorY, - float pivotX, float pivotY) const noexcept; - - /** Returns a new transform which is a re-scale about the origin. */ - static AffineTransform scale (float factorX, - float factorY) noexcept; - - /** Returns a new transform which is a re-scale about the origin. */ - static AffineTransform scale (float factor) noexcept; - - /** Returns a new transform which is a re-scale centred around the point provided. */ - static AffineTransform scale (float factorX, float factorY, - float pivotX, float pivotY) noexcept; - - /** Returns a transform which is the same as this one followed by a shear. - The shear is centred around the origin (0, 0). - */ - AffineTransform sheared (float shearX, float shearY) const noexcept; - - /** Returns a shear transform, centred around the origin (0, 0). */ - static AffineTransform shear (float shearX, float shearY) noexcept; - - /** Returns a transform that will flip coordinates vertically within a window of the given height. - This is handy for converting between upside-down coordinate systems such as OpenGL or CoreGraphics. - */ - static AffineTransform verticalFlip (float height) noexcept; - - /** Returns a matrix which is the inverse operation of this one. - - Some matrices don't have an inverse - in this case, the method will just return - an identity transform. - */ - AffineTransform inverted() const noexcept; - - /** Returns the transform that will map three known points onto three coordinates - that are supplied. - - This returns the transform that will transform (0, 0) into (x00, y00), - (1, 0) to (x10, y10), and (0, 1) to (x01, y01). - */ - static AffineTransform fromTargetPoints (float x00, float y00, - float x10, float y10, - float x01, float y01) noexcept; - - /** Returns the transform that will map three specified points onto three target points. */ - static AffineTransform fromTargetPoints (float sourceX1, float sourceY1, float targetX1, float targetY1, - float sourceX2, float sourceY2, float targetX2, float targetY2, - float sourceX3, float sourceY3, float targetX3, float targetY3) noexcept; - - //============================================================================== - /** Returns the result of concatenating another transformation after this one. */ - AffineTransform followedBy (const AffineTransform& other) const noexcept; - - /** Returns true if this transform has no effect on points. */ - bool isIdentity() const noexcept; - - /** Returns true if this transform maps to a singularity - i.e. if it has no inverse. */ - bool isSingularity() const noexcept; - - /** Returns true if the transform only translates, and doesn't scale or rotate the - points. */ - bool isOnlyTranslation() const noexcept; - - /** If this transform is only a translation, this returns the X offset. - @see isOnlyTranslation - */ - float getTranslationX() const noexcept { return mat02; } - - /** If this transform is only a translation, this returns the X offset. - @see isOnlyTranslation - */ - float getTranslationY() const noexcept { return mat12; } - - /** Returns the approximate scale factor by which lengths will be transformed. - Obviously a length may be scaled by entirely different amounts depending on its - direction, so this is only appropriate as a rough guide. - */ - float getScaleFactor() const noexcept; - - //============================================================================== - /* The transform matrix is: - - (mat00 mat01 mat02) - (mat10 mat11 mat12) - ( 0 0 1 ) - */ - float mat00, mat01, mat02; - float mat10, mat11, mat12; - - -private: - //============================================================================== - JUCE_LEAK_DETECTOR (AffineTransform) -}; - -#endif // JUCE_AFFINETRANSFORM_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/geometry/juce_BorderSize.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/geometry/juce_BorderSize.h deleted file mode 100644 index b6a6686a76..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/geometry/juce_BorderSize.h +++ /dev/null @@ -1,153 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_BORDERSIZE_H_INCLUDED -#define JUCE_BORDERSIZE_H_INCLUDED - - -//============================================================================== -/** - Specifies a set of gaps to be left around the sides of a rectangle. - - This is basically the size of the spaces at the top, bottom, left and right of - a rectangle. It's used by various component classes to specify borders. - - @see Rectangle -*/ -template -class BorderSize -{ -public: - //============================================================================== - /** Creates a null border. - All sizes are left as 0. - */ - BorderSize() noexcept - : top(), left(), bottom(), right() - { - } - - /** Creates a copy of another border. */ - BorderSize (const BorderSize& other) noexcept - : top (other.top), left (other.left), bottom (other.bottom), right (other.right) - { - } - - /** Creates a border with the given gaps. */ - BorderSize (ValueType topGap, ValueType leftGap, ValueType bottomGap, ValueType rightGap) noexcept - : top (topGap), left (leftGap), bottom (bottomGap), right (rightGap) - { - } - - /** Creates a border with the given gap on all sides. */ - explicit BorderSize (ValueType allGaps) noexcept - : top (allGaps), left (allGaps), bottom (allGaps), right (allGaps) - { - } - - //============================================================================== - /** Returns the gap that should be left at the top of the region. */ - ValueType getTop() const noexcept { return top; } - - /** Returns the gap that should be left at the top of the region. */ - ValueType getLeft() const noexcept { return left; } - - /** Returns the gap that should be left at the top of the region. */ - ValueType getBottom() const noexcept { return bottom; } - - /** Returns the gap that should be left at the top of the region. */ - ValueType getRight() const noexcept { return right; } - - /** Returns the sum of the top and bottom gaps. */ - ValueType getTopAndBottom() const noexcept { return top + bottom; } - - /** Returns the sum of the left and right gaps. */ - ValueType getLeftAndRight() const noexcept { return left + right; } - - /** Returns true if this border has no thickness along any edge. */ - bool isEmpty() const noexcept { return left + right + top + bottom == ValueType(); } - - //============================================================================== - /** Changes the top gap. */ - void setTop (ValueType newTopGap) noexcept { top = newTopGap; } - - /** Changes the left gap. */ - void setLeft (ValueType newLeftGap) noexcept { left = newLeftGap; } - - /** Changes the bottom gap. */ - void setBottom (ValueType newBottomGap) noexcept { bottom = newBottomGap; } - - /** Changes the right gap. */ - void setRight (ValueType newRightGap) noexcept { right = newRightGap; } - - //============================================================================== - /** Returns a rectangle with these borders removed from it. */ - Rectangle subtractedFrom (const Rectangle& original) const noexcept - { - return Rectangle (original.getX() + left, - original.getY() + top, - original.getWidth() - (left + right), - original.getHeight() - (top + bottom)); - } - - /** Removes this border from a given rectangle. */ - void subtractFrom (Rectangle& rectangle) const noexcept - { - rectangle = subtractedFrom (rectangle); - } - - /** Returns a rectangle with these borders added around it. */ - Rectangle addedTo (const Rectangle& original) const noexcept - { - return Rectangle (original.getX() - left, - original.getY() - top, - original.getWidth() + (left + right), - original.getHeight() + (top + bottom)); - } - - - /** Adds this border around a given rectangle. */ - void addTo (Rectangle& rectangle) const noexcept - { - rectangle = addedTo (rectangle); - } - - //============================================================================== - bool operator== (const BorderSize& other) const noexcept - { - return top == other.top && left == other.left && bottom == other.bottom && right == other.right; - } - - bool operator!= (const BorderSize& other) const noexcept - { - return ! operator== (other); - } - -private: - //============================================================================== - ValueType top, left, bottom, right; -}; - - -#endif // JUCE_BORDERSIZE_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/geometry/juce_EdgeTable.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/geometry/juce_EdgeTable.cpp deleted file mode 100644 index 73ee1c3c2b..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/geometry/juce_EdgeTable.cpp +++ /dev/null @@ -1,831 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -const int juce_edgeTableDefaultEdgesPerLine = 32; - -//============================================================================== -EdgeTable::EdgeTable (const Rectangle& area, - const Path& path, const AffineTransform& transform) - : bounds (area), - maxEdgesPerLine (juce_edgeTableDefaultEdgesPerLine), - lineStrideElements (juce_edgeTableDefaultEdgesPerLine * 2 + 1), - needToCheckEmptiness (true) -{ - allocate(); - int* t = table; - - for (int i = bounds.getHeight(); --i >= 0;) - { - *t = 0; - t += lineStrideElements; - } - - const int leftLimit = bounds.getX() << 8; - const int topLimit = bounds.getY() << 8; - const int rightLimit = bounds.getRight() << 8; - const int heightLimit = bounds.getHeight() << 8; - - PathFlatteningIterator iter (path, transform); - - while (iter.next()) - { - int y1 = roundToInt (iter.y1 * 256.0f); - int y2 = roundToInt (iter.y2 * 256.0f); - - if (y1 != y2) - { - y1 -= topLimit; - y2 -= topLimit; - - const int startY = y1; - int direction = -1; - - if (y1 > y2) - { - std::swap (y1, y2); - direction = 1; - } - - if (y1 < 0) - y1 = 0; - - if (y2 > heightLimit) - y2 = heightLimit; - - if (y1 < y2) - { - const double startX = 256.0f * iter.x1; - const double multiplier = (iter.x2 - iter.x1) / (iter.y2 - iter.y1); - const int stepSize = jlimit (1, 256, 256 / (1 + (int) std::abs (multiplier))); - - do - { - const int step = jmin (stepSize, y2 - y1, 256 - (y1 & 255)); - int x = roundToInt (startX + multiplier * ((y1 + (step >> 1)) - startY)); - - if (x < leftLimit) - x = leftLimit; - else if (x >= rightLimit) - x = rightLimit - 1; - - addEdgePoint (x, y1 >> 8, direction * step); - y1 += step; - } - while (y1 < y2); - } - } - } - - sanitiseLevels (path.isUsingNonZeroWinding()); -} - -EdgeTable::EdgeTable (const Rectangle& rectangleToAdd) - : bounds (rectangleToAdd), - maxEdgesPerLine (juce_edgeTableDefaultEdgesPerLine), - lineStrideElements (juce_edgeTableDefaultEdgesPerLine * 2 + 1), - needToCheckEmptiness (true) -{ - allocate(); - table[0] = 0; - - const int x1 = rectangleToAdd.getX() << 8; - const int x2 = rectangleToAdd.getRight() << 8; - - int* t = table; - for (int i = rectangleToAdd.getHeight(); --i >= 0;) - { - t[0] = 2; - t[1] = x1; - t[2] = 255; - t[3] = x2; - t[4] = 0; - t += lineStrideElements; - } -} - -EdgeTable::EdgeTable (const RectangleList& rectanglesToAdd) - : bounds (rectanglesToAdd.getBounds()), - maxEdgesPerLine (juce_edgeTableDefaultEdgesPerLine), - lineStrideElements (juce_edgeTableDefaultEdgesPerLine * 2 + 1), - needToCheckEmptiness (true) -{ - allocate(); - clearLineSizes(); - - for (const Rectangle* r = rectanglesToAdd.begin(), * const e = rectanglesToAdd.end(); r != e; ++r) - { - const int x1 = r->getX() << 8; - const int x2 = r->getRight() << 8; - int y = r->getY() - bounds.getY(); - - for (int j = r->getHeight(); --j >= 0;) - addEdgePointPair (x1, x2, y++, 255); - } - - sanitiseLevels (true); -} - -EdgeTable::EdgeTable (const RectangleList& rectanglesToAdd) - : bounds (rectanglesToAdd.getBounds().getSmallestIntegerContainer()), - maxEdgesPerLine (rectanglesToAdd.getNumRectangles() * 2), - lineStrideElements (rectanglesToAdd.getNumRectangles() * 4 + 1), - needToCheckEmptiness (true) -{ - bounds.setHeight (bounds.getHeight() + 1); - allocate(); - clearLineSizes(); - - for (const Rectangle* r = rectanglesToAdd.begin(), * const e = rectanglesToAdd.end(); r != e; ++r) - { - const int x1 = roundToInt (r->getX() * 256.0f); - const int x2 = roundToInt (r->getRight() * 256.0f); - - const int y1 = roundToInt (r->getY() * 256.0f) - (bounds.getY() << 8); - const int y2 = roundToInt (r->getBottom() * 256.0f) - (bounds.getY() << 8); - - if (x2 <= x1 || y2 <= y1) - continue; - - int y = y1 >> 8; - const int lastLine = y2 >> 8; - - if (y == lastLine) - { - addEdgePointPair (x1, x2, y, y2 - y1); - } - else - { - addEdgePointPair (x1, x2, y++, 255 - (y1 & 255)); - - while (y < lastLine) - addEdgePointPair (x1, x2, y++, 255); - - jassert (y < bounds.getHeight()); - addEdgePointPair (x1, x2, y, y2 & 255); - } - } - - sanitiseLevels (true); -} - -EdgeTable::EdgeTable (const Rectangle& rectangleToAdd) - : bounds (Rectangle ((int) std::floor (rectangleToAdd.getX()), - roundToInt (rectangleToAdd.getY() * 256.0f) >> 8, - 2 + (int) rectangleToAdd.getWidth(), - 2 + (int) rectangleToAdd.getHeight())), - maxEdgesPerLine (juce_edgeTableDefaultEdgesPerLine), - lineStrideElements ((juce_edgeTableDefaultEdgesPerLine << 1) + 1), - needToCheckEmptiness (true) -{ - jassert (! rectangleToAdd.isEmpty()); - allocate(); - table[0] = 0; - - const int x1 = roundToInt (rectangleToAdd.getX() * 256.0f); - const int x2 = roundToInt (rectangleToAdd.getRight() * 256.0f); - - int y1 = roundToInt (rectangleToAdd.getY() * 256.0f) - (bounds.getY() << 8); - jassert (y1 < 256); - int y2 = roundToInt (rectangleToAdd.getBottom() * 256.0f) - (bounds.getY() << 8); - - if (x2 <= x1 || y2 <= y1) - { - bounds.setHeight (0); - return; - } - - int lineY = 0; - int* t = table; - - if ((y1 >> 8) == (y2 >> 8)) - { - t[0] = 2; - t[1] = x1; - t[2] = y2 - y1; - t[3] = x2; - t[4] = 0; - ++lineY; - t += lineStrideElements; - } - else - { - t[0] = 2; - t[1] = x1; - t[2] = 255 - (y1 & 255); - t[3] = x2; - t[4] = 0; - ++lineY; - t += lineStrideElements; - - while (lineY < (y2 >> 8)) - { - t[0] = 2; - t[1] = x1; - t[2] = 255; - t[3] = x2; - t[4] = 0; - ++lineY; - t += lineStrideElements; - } - - jassert (lineY < bounds.getHeight()); - t[0] = 2; - t[1] = x1; - t[2] = y2 & 255; - t[3] = x2; - t[4] = 0; - ++lineY; - t += lineStrideElements; - } - - while (lineY < bounds.getHeight()) - { - t[0] = 0; - t += lineStrideElements; - ++lineY; - } -} - -EdgeTable::EdgeTable (const EdgeTable& other) -{ - operator= (other); -} - -EdgeTable& EdgeTable::operator= (const EdgeTable& other) -{ - bounds = other.bounds; - maxEdgesPerLine = other.maxEdgesPerLine; - lineStrideElements = other.lineStrideElements; - needToCheckEmptiness = other.needToCheckEmptiness; - - allocate(); - copyEdgeTableData (table, lineStrideElements, other.table, lineStrideElements, bounds.getHeight()); - return *this; -} - -EdgeTable::~EdgeTable() -{ -} - -//============================================================================== -static size_t getEdgeTableAllocationSize (int lineStride, int height) noexcept -{ - // (leave an extra line at the end for use as scratch space) - return (size_t) (lineStride * (2 + jmax (0, height))); -} - -void EdgeTable::allocate() -{ - table.malloc (getEdgeTableAllocationSize (lineStrideElements, bounds.getHeight())); -} - -void EdgeTable::clearLineSizes() noexcept -{ - int* t = table; - for (int i = bounds.getHeight(); --i >= 0;) - { - *t = 0; - t += lineStrideElements; - } -} - -void EdgeTable::copyEdgeTableData (int* dest, const int destLineStride, const int* src, const int srcLineStride, int numLines) noexcept -{ - while (--numLines >= 0) - { - memcpy (dest, src, (size_t) (src[0] * 2 + 1) * sizeof (int)); - src += srcLineStride; - dest += destLineStride; - } -} - -void EdgeTable::sanitiseLevels (const bool useNonZeroWinding) noexcept -{ - // Convert the table from relative windings to absolute levels.. - int* lineStart = table; - - for (int y = bounds.getHeight(); --y >= 0;) - { - int num = lineStart[0]; - - if (num > 0) - { - LineItem* items = reinterpret_cast (lineStart + 1); - LineItem* const itemsEnd = items + num; - - // sort the X coords - std::sort (items, itemsEnd); - - const LineItem* src = items; - int correctedNum = num; - int level = 0; - - while (src < itemsEnd) - { - level += src->level; - const int x = src->x; - ++src; - - while (src < itemsEnd && src->x == x) - { - level += src->level; - ++src; - --correctedNum; - } - - int corrected = std::abs (level); - - if (corrected >> 8) - { - if (useNonZeroWinding) - { - corrected = 255; - } - else - { - corrected &= 511; - if (corrected >> 8) - corrected = 511 - corrected; - } - } - - items->x = x; - items->level = corrected; - ++items; - } - - lineStart[0] = correctedNum; - (items - 1)->level = 0; // force the last level to 0, just in case something went wrong in creating the table - } - - lineStart += lineStrideElements; - } -} - -void EdgeTable::remapTableForNumEdges (const int newNumEdgesPerLine) -{ - if (newNumEdgesPerLine != maxEdgesPerLine) - { - maxEdgesPerLine = newNumEdgesPerLine; - - jassert (bounds.getHeight() > 0); - const int newLineStrideElements = maxEdgesPerLine * 2 + 1; - - HeapBlock newTable (getEdgeTableAllocationSize (newLineStrideElements, bounds.getHeight())); - - copyEdgeTableData (newTable, newLineStrideElements, table, lineStrideElements, bounds.getHeight()); - - table.swapWith (newTable); - lineStrideElements = newLineStrideElements; - } -} - -void EdgeTable::optimiseTable() -{ - int maxLineElements = 0; - - for (int i = bounds.getHeight(); --i >= 0;) - maxLineElements = jmax (maxLineElements, table [i * lineStrideElements]); - - remapTableForNumEdges (maxLineElements); -} - -void EdgeTable::addEdgePoint (const int x, const int y, const int winding) -{ - jassert (y >= 0 && y < bounds.getHeight()); - - int* line = table + lineStrideElements * y; - const int numPoints = line[0]; - - if (numPoints >= maxEdgesPerLine) - { - remapTableForNumEdges (maxEdgesPerLine + juce_edgeTableDefaultEdgesPerLine); - jassert (numPoints < maxEdgesPerLine); - line = table + lineStrideElements * y; - } - - line[0]++; - int n = numPoints << 1; - line [n + 1] = x; - line [n + 2] = winding; -} - -void EdgeTable::addEdgePointPair (int x1, int x2, int y, int winding) -{ - jassert (y >= 0 && y < bounds.getHeight()); - - int* line = table + lineStrideElements * y; - const int numPoints = line[0]; - - if (numPoints + 1 >= maxEdgesPerLine) - { - remapTableForNumEdges (maxEdgesPerLine + juce_edgeTableDefaultEdgesPerLine); - jassert (numPoints < maxEdgesPerLine); - line = table + lineStrideElements * y; - } - - line[0] = numPoints + 2; - line += numPoints << 1; - line[1] = x1; - line[2] = winding; - line[3] = x2; - line[4] = -winding; -} - -void EdgeTable::translate (float dx, const int dy) noexcept -{ - bounds.translate ((int) std::floor (dx), dy); - - int* lineStart = table; - const int intDx = (int) (dx * 256.0f); - - for (int i = bounds.getHeight(); --i >= 0;) - { - int* line = lineStart; - lineStart += lineStrideElements; - int num = *line++; - - while (--num >= 0) - { - *line += intDx; - line += 2; - } - } -} - -void EdgeTable::multiplyLevels (float amount) -{ - int* lineStart = table; - const int multiplier = (int) (amount * 256.0f); - - for (int y = 0; y < bounds.getHeight(); ++y) - { - int numPoints = lineStart[0]; - LineItem* item = reinterpret_cast (lineStart + 1); - lineStart += lineStrideElements; - - while (--numPoints > 0) - { - item->level = jmin (255, (item->level * multiplier) >> 8); - ++item; - } - } -} - -void EdgeTable::intersectWithEdgeTableLine (const int y, const int* const otherLine) -{ - jassert (y >= 0 && y < bounds.getHeight()); - - int* srcLine = table + lineStrideElements * y; - int srcNum1 = *srcLine; - - if (srcNum1 == 0) - return; - - int srcNum2 = *otherLine; - - if (srcNum2 == 0) - { - *srcLine = 0; - return; - } - - const int right = bounds.getRight() << 8; - - // optimise for the common case where our line lies entirely within a - // single pair of points, as happens when clipping to a simple rect. - if (srcNum2 == 2 && otherLine[2] >= 255) - { - clipEdgeTableLineToRange (srcLine, otherLine[1], jmin (right, otherLine[3])); - return; - } - - bool isUsingTempSpace = false; - - const int* src1 = srcLine + 1; - int x1 = *src1++; - - const int* src2 = otherLine + 1; - int x2 = *src2++; - - int destIndex = 0, destTotal = 0; - int level1 = 0, level2 = 0; - int lastX = std::numeric_limits::min(), lastLevel = 0; - - while (srcNum1 > 0 && srcNum2 > 0) - { - int nextX; - - if (x1 <= x2) - { - if (x1 == x2) - { - level2 = *src2++; - x2 = *src2++; - --srcNum2; - } - - nextX = x1; - level1 = *src1++; - x1 = *src1++; - --srcNum1; - } - else - { - nextX = x2; - level2 = *src2++; - x2 = *src2++; - --srcNum2; - } - - if (nextX > lastX) - { - if (nextX >= right) - break; - - lastX = nextX; - - const int nextLevel = (level1 * (level2 + 1)) >> 8; - jassert (isPositiveAndBelow (nextLevel, (int) 256)); - - if (nextLevel != lastLevel) - { - if (destTotal >= maxEdgesPerLine) - { - srcLine[0] = destTotal; - - if (isUsingTempSpace) - { - const size_t tempSize = (size_t) srcNum1 * 2 * sizeof (int); - int* const oldTemp = static_cast (alloca (tempSize)); - memcpy (oldTemp, src1, tempSize); - - remapTableForNumEdges (jmax (256, destTotal * 2)); - srcLine = table + lineStrideElements * y; - - int* const newTemp = table + lineStrideElements * bounds.getHeight(); - memcpy (newTemp, oldTemp, tempSize); - src1 = newTemp; - } - else - { - remapTableForNumEdges (jmax (256, destTotal * 2)); - srcLine = table + lineStrideElements * y; - } - } - - ++destTotal; - lastLevel = nextLevel; - - if (! isUsingTempSpace) - { - isUsingTempSpace = true; - int* const temp = table + lineStrideElements * bounds.getHeight(); - memcpy (temp, src1, (size_t) srcNum1 * 2 * sizeof (int)); - src1 = temp; - } - - srcLine[++destIndex] = nextX; - srcLine[++destIndex] = nextLevel; - } - } - } - - if (lastLevel > 0) - { - if (destTotal >= maxEdgesPerLine) - { - srcLine[0] = destTotal; - remapTableForNumEdges (jmax (256, destTotal * 2)); - srcLine = table + lineStrideElements * y; - } - - ++destTotal; - srcLine[++destIndex] = right; - srcLine[++destIndex] = 0; - } - - srcLine[0] = destTotal; -} - -void EdgeTable::clipEdgeTableLineToRange (int* dest, const int x1, const int x2) noexcept -{ - int* lastItem = dest + (dest[0] * 2 - 1); - - if (x2 < lastItem[0]) - { - if (x2 <= dest[1]) - { - dest[0] = 0; - return; - } - - while (x2 < lastItem[-2]) - { - --(dest[0]); - lastItem -= 2; - } - - lastItem[0] = x2; - lastItem[1] = 0; - } - - if (x1 > dest[1]) - { - while (lastItem[0] > x1) - lastItem -= 2; - - const int itemsRemoved = (int) (lastItem - (dest + 1)) / 2; - - if (itemsRemoved > 0) - { - dest[0] -= itemsRemoved; - memmove (dest + 1, lastItem, (size_t) dest[0] * (sizeof (int) * 2)); - } - - dest[1] = x1; - } -} - - -//============================================================================== -void EdgeTable::clipToRectangle (const Rectangle& r) -{ - const Rectangle clipped (r.getIntersection (bounds)); - - if (clipped.isEmpty()) - { - needToCheckEmptiness = false; - bounds.setHeight (0); - } - else - { - const int top = clipped.getY() - bounds.getY(); - const int bottom = clipped.getBottom() - bounds.getY(); - - if (bottom < bounds.getHeight()) - bounds.setHeight (bottom); - - for (int i = top; --i >= 0;) - table [lineStrideElements * i] = 0; - - if (clipped.getX() > bounds.getX() || clipped.getRight() < bounds.getRight()) - { - const int x1 = clipped.getX() << 8; - const int x2 = jmin (bounds.getRight(), clipped.getRight()) << 8; - int* line = table + lineStrideElements * top; - - for (int i = bottom - top; --i >= 0;) - { - if (line[0] != 0) - clipEdgeTableLineToRange (line, x1, x2); - - line += lineStrideElements; - } - } - - needToCheckEmptiness = true; - } -} - -void EdgeTable::excludeRectangle (const Rectangle& r) -{ - const Rectangle clipped (r.getIntersection (bounds)); - - if (! clipped.isEmpty()) - { - const int top = clipped.getY() - bounds.getY(); - const int bottom = clipped.getBottom() - bounds.getY(); - - const int rectLine[] = { 4, std::numeric_limits::min(), 255, - clipped.getX() << 8, 0, - clipped.getRight() << 8, 255, - std::numeric_limits::max(), 0 }; - - for (int i = top; i < bottom; ++i) - intersectWithEdgeTableLine (i, rectLine); - - needToCheckEmptiness = true; - } -} - -void EdgeTable::clipToEdgeTable (const EdgeTable& other) -{ - const Rectangle clipped (other.bounds.getIntersection (bounds)); - - if (clipped.isEmpty()) - { - needToCheckEmptiness = false; - bounds.setHeight (0); - } - else - { - const int top = clipped.getY() - bounds.getY(); - const int bottom = clipped.getBottom() - bounds.getY(); - - if (bottom < bounds.getHeight()) - bounds.setHeight (bottom); - - if (clipped.getRight() < bounds.getRight()) - bounds.setRight (clipped.getRight()); - - for (int i = 0; i < top; ++i) - table [lineStrideElements * i] = 0; - - const int* otherLine = other.table + other.lineStrideElements * (clipped.getY() - other.bounds.getY()); - - for (int i = top; i < bottom; ++i) - { - intersectWithEdgeTableLine (i, otherLine); - otherLine += other.lineStrideElements; - } - - needToCheckEmptiness = true; - } -} - -void EdgeTable::clipLineToMask (int x, int y, const uint8* mask, int maskStride, int numPixels) -{ - y -= bounds.getY(); - - if (y < 0 || y >= bounds.getHeight()) - return; - - needToCheckEmptiness = true; - - if (numPixels <= 0) - { - table [lineStrideElements * y] = 0; - return; - } - - int* tempLine = static_cast (alloca ((size_t) (numPixels * 2 + 4) * sizeof (int))); - int destIndex = 0, lastLevel = 0; - - while (--numPixels >= 0) - { - const int alpha = *mask; - mask += maskStride; - - if (alpha != lastLevel) - { - tempLine[++destIndex] = (x << 8); - tempLine[++destIndex] = alpha; - lastLevel = alpha; - } - - ++x; - } - - if (lastLevel > 0) - { - tempLine[++destIndex] = (x << 8); - tempLine[++destIndex] = 0; - } - - tempLine[0] = destIndex >> 1; - - intersectWithEdgeTableLine (y, tempLine); -} - -bool EdgeTable::isEmpty() noexcept -{ - if (needToCheckEmptiness) - { - needToCheckEmptiness = false; - int* t = table; - - for (int i = bounds.getHeight(); --i >= 0;) - { - if (t[0] > 1) - return false; - - t += lineStrideElements; - } - - bounds.setHeight (0); - } - - return bounds.getHeight() == 0; -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/geometry/juce_EdgeTable.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/geometry/juce_EdgeTable.h deleted file mode 100644 index d8b6d66ae1..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/geometry/juce_EdgeTable.h +++ /dev/null @@ -1,220 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_EDGETABLE_H_INCLUDED -#define JUCE_EDGETABLE_H_INCLUDED - - -//============================================================================== -/** - A table of horizontal scan-line segments - used for rasterising Paths. - - @see Path, Graphics -*/ -class JUCE_API EdgeTable -{ -public: - //============================================================================== - /** Creates an edge table containing a path. - - A table is created with a fixed vertical range, and only sections of the path - which lie within this range will be added to the table. - - @param clipLimits only the region of the path that lies within this area will be added - @param pathToAdd the path to add to the table - @param transform a transform to apply to the path being added - */ - EdgeTable (const Rectangle& clipLimits, - const Path& pathToAdd, - const AffineTransform& transform); - - /** Creates an edge table containing a rectangle. */ - explicit EdgeTable (const Rectangle& rectangleToAdd); - - /** Creates an edge table containing a rectangle list. */ - explicit EdgeTable (const RectangleList& rectanglesToAdd); - - /** Creates an edge table containing a rectangle list. */ - explicit EdgeTable (const RectangleList& rectanglesToAdd); - - /** Creates an edge table containing a rectangle. */ - explicit EdgeTable (const Rectangle& rectangleToAdd); - - /** Creates a copy of another edge table. */ - EdgeTable (const EdgeTable&); - - /** Copies from another edge table. */ - EdgeTable& operator= (const EdgeTable&); - - /** Destructor. */ - ~EdgeTable(); - - //============================================================================== - void clipToRectangle (const Rectangle& r); - void excludeRectangle (const Rectangle& r); - void clipToEdgeTable (const EdgeTable&); - void clipLineToMask (int x, int y, const uint8* mask, int maskStride, int numPixels); - bool isEmpty() noexcept; - const Rectangle& getMaximumBounds() const noexcept { return bounds; } - void translate (float dx, int dy) noexcept; - - /** Scales all the alpha-levels in the table by the given multiplier. */ - void multiplyLevels (float factor); - - /** Reduces the amount of space the table has allocated. - - This will shrink the table down to use as little memory as possible - useful for - read-only tables that get stored and re-used for rendering. - */ - void optimiseTable(); - - - //============================================================================== - /** Iterates the lines in the table, for rendering. - - This function will iterate each line in the table, and call a user-defined class - to render each pixel or continuous line of pixels that the table contains. - - @param iterationCallback this templated class must contain the following methods: - @code - inline void setEdgeTableYPos (int y); - inline void handleEdgeTablePixel (int x, int alphaLevel) const; - inline void handleEdgeTablePixelFull (int x) const; - inline void handleEdgeTableLine (int x, int width, int alphaLevel) const; - inline void handleEdgeTableLineFull (int x, int width) const; - @endcode - (these don't necessarily have to be 'const', but it might help it go faster) - */ - template - void iterate (EdgeTableIterationCallback& iterationCallback) const noexcept - { - const int* lineStart = table; - - for (int y = 0; y < bounds.getHeight(); ++y) - { - const int* line = lineStart; - lineStart += lineStrideElements; - int numPoints = line[0]; - - if (--numPoints > 0) - { - int x = *++line; - jassert ((x >> 8) >= bounds.getX() && (x >> 8) < bounds.getRight()); - int levelAccumulator = 0; - - iterationCallback.setEdgeTableYPos (bounds.getY() + y); - - while (--numPoints >= 0) - { - const int level = *++line; - jassert (isPositiveAndBelow (level, (int) 256)); - const int endX = *++line; - jassert (endX >= x); - const int endOfRun = (endX >> 8); - - if (endOfRun == (x >> 8)) - { - // small segment within the same pixel, so just save it for the next - // time round.. - levelAccumulator += (endX - x) * level; - } - else - { - // plot the fist pixel of this segment, including any accumulated - // levels from smaller segments that haven't been drawn yet - levelAccumulator += (0x100 - (x & 0xff)) * level; - levelAccumulator >>= 8; - x >>= 8; - - if (levelAccumulator > 0) - { - if (levelAccumulator >= 255) - iterationCallback.handleEdgeTablePixelFull (x); - else - iterationCallback.handleEdgeTablePixel (x, levelAccumulator); - } - - // if there's a run of similar pixels, do it all in one go.. - if (level > 0) - { - jassert (endOfRun <= bounds.getRight()); - const int numPix = endOfRun - ++x; - - if (numPix > 0) - iterationCallback.handleEdgeTableLine (x, numPix, level); - } - - // save the bit at the end to be drawn next time round the loop. - levelAccumulator = (endX & 0xff) * level; - } - - x = endX; - } - - levelAccumulator >>= 8; - - if (levelAccumulator > 0) - { - x >>= 8; - jassert (x >= bounds.getX() && x < bounds.getRight()); - - if (levelAccumulator >= 255) - iterationCallback.handleEdgeTablePixelFull (x); - else - iterationCallback.handleEdgeTablePixel (x, levelAccumulator); - } - } - } - } - -private: - //============================================================================== - // table line format: number of points; point0 x, point0 levelDelta, point1 x, point1 levelDelta, etc - struct LineItem - { - int x, level; - - bool operator< (const LineItem& other) const noexcept { return x < other.x; } - }; - - HeapBlock table; - Rectangle bounds; - int maxEdgesPerLine, lineStrideElements; - bool needToCheckEmptiness; - - void allocate(); - void clearLineSizes() noexcept; - void addEdgePoint (int x, int y, int winding); - void addEdgePointPair (int x1, int x2, int y, int winding); - void remapTableForNumEdges (int newNumEdgesPerLine); - void intersectWithEdgeTableLine (int y, const int* otherLine); - void clipEdgeTableLineToRange (int* line, int x1, int x2) noexcept; - void sanitiseLevels (bool useNonZeroWinding) noexcept; - static void copyEdgeTableData (int* dest, int destLineStride, const int* src, int srcLineStride, int numLines) noexcept; - - JUCE_LEAK_DETECTOR (EdgeTable) -}; - - -#endif // JUCE_EDGETABLE_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/geometry/juce_Line.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/geometry/juce_Line.h deleted file mode 100644 index 95665c5235..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/geometry/juce_Line.h +++ /dev/null @@ -1,416 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_LINE_H_INCLUDED -#define JUCE_LINE_H_INCLUDED - - -//============================================================================== -/** - Represents a line. - - This class contains a bunch of useful methods for various geometric - tasks. - - The ValueType template parameter should be a primitive type - float or double - are what it's designed for. Integer types will work in a basic way, but some methods - that perform mathematical operations may not compile, or they may not produce - sensible results. - - @see Point, Rectangle, Path, Graphics::drawLine -*/ -template -class Line -{ -public: - //============================================================================== - /** Creates a line, using (0, 0) as its start and end points. */ - Line() noexcept {} - - /** Creates a copy of another line. */ - Line (const Line& other) noexcept - : start (other.start), - end (other.end) - { - } - - /** Creates a line based on the coordinates of its start and end points. */ - Line (ValueType startX, ValueType startY, ValueType endX, ValueType endY) noexcept - : start (startX, startY), - end (endX, endY) - { - } - - /** Creates a line from its start and end points. */ - Line (const Point startPoint, - const Point endPoint) noexcept - : start (startPoint), - end (endPoint) - { - } - - /** Copies a line from another one. */ - Line& operator= (const Line& other) noexcept - { - start = other.start; - end = other.end; - return *this; - } - - /** Destructor. */ - ~Line() noexcept {} - - //============================================================================== - /** Returns the x coordinate of the line's start point. */ - inline ValueType getStartX() const noexcept { return start.x; } - - /** Returns the y coordinate of the line's start point. */ - inline ValueType getStartY() const noexcept { return start.y; } - - /** Returns the x coordinate of the line's end point. */ - inline ValueType getEndX() const noexcept { return end.x; } - - /** Returns the y coordinate of the line's end point. */ - inline ValueType getEndY() const noexcept { return end.y; } - - /** Returns the line's start point. */ - inline Point getStart() const noexcept { return start; } - - /** Returns the line's end point. */ - inline Point getEnd() const noexcept { return end; } - - /** Changes this line's start point */ - void setStart (ValueType newStartX, ValueType newStartY) noexcept { start.setXY (newStartX, newStartY); } - - /** Changes this line's end point */ - void setEnd (ValueType newEndX, ValueType newEndY) noexcept { end.setXY (newEndX, newEndY); } - - /** Changes this line's start point */ - void setStart (const Point newStart) noexcept { start = newStart; } - - /** Changes this line's end point */ - void setEnd (const Point newEnd) noexcept { end = newEnd; } - - /** Returns a line that is the same as this one, but with the start and end reversed, */ - const Line reversed() const noexcept { return Line (end, start); } - - /** Applies an affine transform to the line's start and end points. */ - void applyTransform (const AffineTransform& transform) noexcept - { - start.applyTransform (transform); - end.applyTransform (transform); - } - - //============================================================================== - /** Returns the length of the line. */ - ValueType getLength() const noexcept { return start.getDistanceFrom (end); } - - /** Returns true if the line's start and end x coordinates are the same. */ - bool isVertical() const noexcept { return start.x == end.x; } - - /** Returns true if the line's start and end y coordinates are the same. */ - bool isHorizontal() const noexcept { return start.y == end.y; } - - /** Returns the line's angle. - - This value is the number of radians clockwise from the 12 o'clock direction, - where the line's start point is considered to be at the centre. - */ - typename Point::FloatType getAngle() const noexcept { return start.getAngleToPoint (end); } - - /** Casts this line to float coordinates. */ - Line toFloat() const noexcept { return Line (start.toFloat(), end.toFloat()); } - - /** Casts this line to double coordinates. */ - Line toDouble() const noexcept { return Line (start.toDouble(), end.toDouble()); } - - //============================================================================== - /** Compares two lines. */ - bool operator== (const Line& other) const noexcept { return start == other.start && end == other.end; } - - /** Compares two lines. */ - bool operator!= (const Line& other) const noexcept { return start != other.start || end != other.end; } - - //============================================================================== - /** Finds the intersection between two lines. - - @param line the line to intersect with - @returns the point at which the lines intersect, even if this lies beyond the end of the lines - */ - Point getIntersection (const Line& line) const noexcept - { - Point p; - findIntersection (start, end, line.start, line.end, p); - return p; - } - - /** Finds the intersection between two lines. - - @param line the other line - @param intersection the position of the point where the lines meet (or - where they would meet if they were infinitely long) - the intersection (if the lines intersect). If the lines - are parallel, this will just be set to the position - of one of the line's endpoints. - @returns true if the line segments intersect; false if they dont. Even if they - don't intersect, the intersection coordinates returned will still - be valid - */ - bool intersects (const Line& line, Point& intersection) const noexcept - { - return findIntersection (start, end, line.start, line.end, intersection); - } - - /** Returns true if this line intersects another. */ - bool intersects (const Line& other) const noexcept - { - Point ignored; - return findIntersection (start, end, other.start, other.end, ignored); - } - - //============================================================================== - /** Returns the location of the point which is a given distance along this line. - - @param distanceFromStart the distance to move along the line from its - start point. This value can be negative or longer - than the line itself - @see getPointAlongLineProportionally - */ - Point getPointAlongLine (ValueType distanceFromStart) const noexcept - { - return start + (end - start) * (distanceFromStart / getLength()); - } - - /** Returns a point which is a certain distance along and to the side of this line. - - This effectively moves a given distance along the line, then another distance - perpendicularly to this, and returns the resulting position. - - @param distanceFromStart the distance to move along the line from its - start point. This value can be negative or longer - than the line itself - @param perpendicularDistance how far to move sideways from the line. If you're - looking along the line from its start towards its - end, then a positive value here will move to the - right, negative value move to the left. - */ - Point getPointAlongLine (ValueType distanceFromStart, - ValueType perpendicularDistance) const noexcept - { - const Point delta (end - start); - const double length = juce_hypot ((double) delta.x, - (double) delta.y); - if (length <= 0) - return start; - - return Point (start.x + static_cast ((delta.x * distanceFromStart - delta.y * perpendicularDistance) / length), - start.y + static_cast ((delta.y * distanceFromStart + delta.x * perpendicularDistance) / length)); - } - - /** Returns the location of the point which is a given distance along this line - proportional to the line's length. - - @param proportionOfLength the distance to move along the line from its - start point, in multiples of the line's length. - So a value of 0.0 will return the line's start point - and a value of 1.0 will return its end point. (This value - can be negative or greater than 1.0). - @see getPointAlongLine - */ - Point getPointAlongLineProportionally (ValueType proportionOfLength) const noexcept - { - return start + (end - start) * proportionOfLength; - } - - /** Returns the smallest distance between this line segment and a given point. - - So if the point is close to the line, this will return the perpendicular - distance from the line; if the point is a long way beyond one of the line's - end-point's, it'll return the straight-line distance to the nearest end-point. - - pointOnLine receives the position of the point that is found. - - @returns the point's distance from the line - @see getPositionAlongLineOfNearestPoint - */ - ValueType getDistanceFromPoint (const Point targetPoint, - Point& pointOnLine) const noexcept - { - const Point delta (end - start); - const double length = delta.x * delta.x + delta.y * delta.y; - - if (length > 0) - { - const double prop = ((targetPoint.x - start.x) * delta.x - + (targetPoint.y - start.y) * delta.y) / length; - - if (prop >= 0 && prop <= 1.0) - { - pointOnLine = start + delta * static_cast (prop); - return targetPoint.getDistanceFrom (pointOnLine); - } - } - - const float fromStart = targetPoint.getDistanceFrom (start); - const float fromEnd = targetPoint.getDistanceFrom (end); - - if (fromStart < fromEnd) - { - pointOnLine = start; - return fromStart; - } - else - { - pointOnLine = end; - return fromEnd; - } - } - - /** Finds the point on this line which is nearest to a given point, and - returns its position as a proportional position along the line. - - @returns a value 0 to 1.0 which is the distance along this line from the - line's start to the point which is nearest to the point passed-in. To - turn this number into a position, use getPointAlongLineProportionally(). - @see getDistanceFromPoint, getPointAlongLineProportionally - */ - ValueType findNearestProportionalPositionTo (const Point point) const noexcept - { - const Point delta (end - start); - const double length = delta.x * delta.x + delta.y * delta.y; - - return length <= 0 ? 0 - : jlimit (ValueType(), static_cast (1), - static_cast ((((point.x - start.x) * delta.x - + (point.y - start.y) * delta.y) / length))); - } - - /** Finds the point on this line which is nearest to a given point. - @see getDistanceFromPoint, findNearestProportionalPositionTo - */ - Point findNearestPointTo (const Point point) const noexcept - { - return getPointAlongLineProportionally (findNearestProportionalPositionTo (point)); - } - - /** Returns true if the given point lies above this line. - - The return value is true if the point's y coordinate is less than the y - coordinate of this line at the given x (assuming the line extends infinitely - in both directions). - */ - bool isPointAbove (const Point point) const noexcept - { - return start.x != end.x - && point.y < ((end.y - start.y) - * (point.x - start.x)) / (end.x - start.x) + start.y; - } - - //============================================================================== - /** Returns a shortened copy of this line. - - This will chop off part of the start of this line by a certain amount, (leaving the - end-point the same), and return the new line. - */ - Line withShortenedStart (ValueType distanceToShortenBy) const noexcept - { - return Line (getPointAlongLine (jmin (distanceToShortenBy, getLength())), end); - } - - /** Returns a shortened copy of this line. - - This will chop off part of the end of this line by a certain amount, (leaving the - start-point the same), and return the new line. - */ - Line withShortenedEnd (ValueType distanceToShortenBy) const noexcept - { - const ValueType length = getLength(); - return Line (start, getPointAlongLine (length - jmin (distanceToShortenBy, length))); - } - -private: - //============================================================================== - Point start, end; - - static bool findIntersection (const Point p1, const Point p2, - const Point p3, const Point p4, - Point& intersection) noexcept - { - if (p2 == p3) - { - intersection = p2; - return true; - } - - const Point d1 (p2 - p1); - const Point d2 (p4 - p3); - const ValueType divisor = d1.x * d2.y - d2.x * d1.y; - - if (divisor == 0) - { - if (! (d1.isOrigin() || d2.isOrigin())) - { - if (d1.y == 0 && d2.y != 0) - { - const ValueType along = (p1.y - p3.y) / d2.y; - intersection = p1.withX (p3.x + along * d2.x); - return along >= 0 && along <= static_cast (1); - } - else if (d2.y == 0 && d1.y != 0) - { - const ValueType along = (p3.y - p1.y) / d1.y; - intersection = p3.withX (p1.x + along * d1.x); - return along >= 0 && along <= static_cast (1); - } - else if (d1.x == 0 && d2.x != 0) - { - const ValueType along = (p1.x - p3.x) / d2.x; - intersection = p1.withY (p3.y + along * d2.y); - return along >= 0 && along <= static_cast (1); - } - else if (d2.x == 0 && d1.x != 0) - { - const ValueType along = (p3.x - p1.x) / d1.x; - intersection = p3.withY (p1.y + along * d1.y); - return along >= 0 && along <= static_cast (1); - } - } - - intersection = (p2 + p3) / static_cast (2); - return false; - } - - const ValueType along1 = ((p1.y - p3.y) * d2.x - (p1.x - p3.x) * d2.y) / divisor; - intersection = p1 + d1 * along1; - - if (along1 < 0 || along1 > static_cast (1)) - return false; - - const ValueType along2 = ((p1.y - p3.y) * d1.x - (p1.x - p3.x) * d1.y) / divisor; - return along2 >= 0 && along2 <= static_cast (1); - } -}; - - -#endif // JUCE_LINE_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/geometry/juce_Path.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/geometry/juce_Path.cpp deleted file mode 100644 index 5a6b2f8662..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/geometry/juce_Path.cpp +++ /dev/null @@ -1,1608 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -// tests that some coordinates aren't NaNs -#define JUCE_CHECK_COORDS_ARE_VALID(x, y) \ - jassert (x == x && y == y); - -//============================================================================== -namespace PathHelpers -{ - const float ellipseAngularIncrement = 0.05f; - - static String nextToken (String::CharPointerType& t) - { - t = t.findEndOfWhitespace(); - - String::CharPointerType start (t); - size_t numChars = 0; - - while (! (t.isEmpty() || t.isWhitespace())) - { - ++t; - ++numChars; - } - - return String (start, numChars); - } - - inline double lengthOf (float x1, float y1, float x2, float y2) noexcept - { - return juce_hypot ((double) (x1 - x2), (double) (y1 - y2)); - } -} - -//============================================================================== -const float Path::lineMarker = 100001.0f; -const float Path::moveMarker = 100002.0f; -const float Path::quadMarker = 100003.0f; -const float Path::cubicMarker = 100004.0f; -const float Path::closeSubPathMarker = 100005.0f; - -//============================================================================== -Path::PathBounds::PathBounds() noexcept - : pathXMin (0), pathXMax (0), pathYMin (0), pathYMax (0) -{ -} - -Rectangle Path::PathBounds::getRectangle() const noexcept -{ - return Rectangle (pathXMin, pathYMin, pathXMax - pathXMin, pathYMax - pathYMin); -} - -void Path::PathBounds::reset() noexcept -{ - pathXMin = pathYMin = pathYMax = pathXMax = 0; -} - -void Path::PathBounds::reset (const float x, const float y) noexcept -{ - pathXMin = pathXMax = x; - pathYMin = pathYMax = y; -} - -void Path::PathBounds::extend (const float x, const float y) noexcept -{ - pathXMin = jmin (pathXMin, x); - pathXMax = jmax (pathXMax, x); - pathYMin = jmin (pathYMin, y); - pathYMax = jmax (pathYMax, y); -} - -void Path::PathBounds::extend (const float x1, const float y1, const float x2, const float y2) noexcept -{ - if (x1 < x2) - { - pathXMin = jmin (pathXMin, x1); - pathXMax = jmax (pathXMax, x2); - } - else - { - pathXMin = jmin (pathXMin, x2); - pathXMax = jmax (pathXMax, x1); - } - - if (y1 < y2) - { - pathYMin = jmin (pathYMin, y1); - pathYMax = jmax (pathYMax, y2); - } - else - { - pathYMin = jmin (pathYMin, y2); - pathYMax = jmax (pathYMax, y1); - } -} - -//============================================================================== -Path::Path() - : numElements (0), useNonZeroWinding (true) -{ -} - -Path::~Path() -{ -} - -Path::Path (const Path& other) - : numElements (other.numElements), - bounds (other.bounds), - useNonZeroWinding (other.useNonZeroWinding) -{ - if (numElements > 0) - { - data.setAllocatedSize ((int) numElements); - memcpy (data.elements, other.data.elements, numElements * sizeof (float)); - } -} - -Path& Path::operator= (const Path& other) -{ - if (this != &other) - { - data.ensureAllocatedSize ((int) other.numElements); - - numElements = other.numElements; - bounds = other.bounds; - useNonZeroWinding = other.useNonZeroWinding; - - if (numElements > 0) - memcpy (data.elements, other.data.elements, numElements * sizeof (float)); - } - - return *this; -} - -#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS -Path::Path (Path&& other) noexcept - : data (static_cast &&> (other.data)), - numElements (other.numElements), - bounds (other.bounds), - useNonZeroWinding (other.useNonZeroWinding) -{ -} - -Path& Path::operator= (Path&& other) noexcept -{ - data = static_cast &&> (other.data); - numElements = other.numElements; - bounds = other.bounds; - useNonZeroWinding = other.useNonZeroWinding; - return *this; -} -#endif - -bool Path::operator== (const Path& other) const noexcept -{ - return ! operator!= (other); -} - -bool Path::operator!= (const Path& other) const noexcept -{ - if (numElements != other.numElements || useNonZeroWinding != other.useNonZeroWinding) - return true; - - for (size_t i = 0; i < numElements; ++i) - if (data.elements[i] != other.data.elements[i]) - return true; - - return false; -} - -void Path::clear() noexcept -{ - numElements = 0; - bounds.reset(); -} - -void Path::swapWithPath (Path& other) noexcept -{ - data.swapWith (other.data); - std::swap (numElements, other.numElements); - std::swap (bounds.pathXMin, other.bounds.pathXMin); - std::swap (bounds.pathXMax, other.bounds.pathXMax); - std::swap (bounds.pathYMin, other.bounds.pathYMin); - std::swap (bounds.pathYMax, other.bounds.pathYMax); - std::swap (useNonZeroWinding, other.useNonZeroWinding); -} - -//============================================================================== -void Path::setUsingNonZeroWinding (const bool isNonZero) noexcept -{ - useNonZeroWinding = isNonZero; -} - -void Path::scaleToFit (const float x, const float y, const float w, const float h, - const bool preserveProportions) noexcept -{ - applyTransform (getTransformToScaleToFit (x, y, w, h, preserveProportions)); -} - -//============================================================================== -bool Path::isEmpty() const noexcept -{ - size_t i = 0; - - while (i < numElements) - { - const float type = data.elements [i++]; - - if (type == moveMarker) - { - i += 2; - } - else if (type == lineMarker - || type == quadMarker - || type == cubicMarker) - { - return false; - } - } - - return true; -} - -Rectangle Path::getBounds() const noexcept -{ - return bounds.getRectangle(); -} - -Rectangle Path::getBoundsTransformed (const AffineTransform& transform) const noexcept -{ - return getBounds().transformedBy (transform); -} - -//============================================================================== -void Path::preallocateSpace (int numExtraCoordsToMakeSpaceFor) -{ - data.ensureAllocatedSize ((int) numElements + numExtraCoordsToMakeSpaceFor); -} - -void Path::startNewSubPath (const float x, const float y) -{ - JUCE_CHECK_COORDS_ARE_VALID (x, y); - - if (numElements == 0) - bounds.reset (x, y); - else - bounds.extend (x, y); - - preallocateSpace (3); - - data.elements [numElements++] = moveMarker; - data.elements [numElements++] = x; - data.elements [numElements++] = y; -} - -void Path::startNewSubPath (const Point start) -{ - startNewSubPath (start.x, start.y); -} - -void Path::lineTo (const float x, const float y) -{ - JUCE_CHECK_COORDS_ARE_VALID (x, y); - - if (numElements == 0) - startNewSubPath (0, 0); - - preallocateSpace (3); - - data.elements [numElements++] = lineMarker; - data.elements [numElements++] = x; - data.elements [numElements++] = y; - - bounds.extend (x, y); -} - -void Path::lineTo (const Point end) -{ - lineTo (end.x, end.y); -} - -void Path::quadraticTo (const float x1, const float y1, - const float x2, const float y2) -{ - JUCE_CHECK_COORDS_ARE_VALID (x1, y1); - JUCE_CHECK_COORDS_ARE_VALID (x2, y2); - - if (numElements == 0) - startNewSubPath (0, 0); - - preallocateSpace (5); - - data.elements [numElements++] = quadMarker; - data.elements [numElements++] = x1; - data.elements [numElements++] = y1; - data.elements [numElements++] = x2; - data.elements [numElements++] = y2; - - bounds.extend (x1, y1, x2, y2); -} - -void Path::quadraticTo (const Point controlPoint, - const Point endPoint) -{ - quadraticTo (controlPoint.x, controlPoint.y, - endPoint.x, endPoint.y); -} - -void Path::cubicTo (const float x1, const float y1, - const float x2, const float y2, - const float x3, const float y3) -{ - JUCE_CHECK_COORDS_ARE_VALID (x1, y1); - JUCE_CHECK_COORDS_ARE_VALID (x2, y2); - JUCE_CHECK_COORDS_ARE_VALID (x3, y3); - - if (numElements == 0) - startNewSubPath (0, 0); - - preallocateSpace (7); - - data.elements [numElements++] = cubicMarker; - data.elements [numElements++] = x1; - data.elements [numElements++] = y1; - data.elements [numElements++] = x2; - data.elements [numElements++] = y2; - data.elements [numElements++] = x3; - data.elements [numElements++] = y3; - - bounds.extend (x1, y1, x2, y2); - bounds.extend (x3, y3); -} - -void Path::cubicTo (const Point controlPoint1, - const Point controlPoint2, - const Point endPoint) -{ - cubicTo (controlPoint1.x, controlPoint1.y, - controlPoint2.x, controlPoint2.y, - endPoint.x, endPoint.y); -} - -void Path::closeSubPath() -{ - if (numElements > 0 - && data.elements [numElements - 1] != closeSubPathMarker) - { - preallocateSpace (1); - data.elements [numElements++] = closeSubPathMarker; - } -} - -Point Path::getCurrentPosition() const -{ - int i = (int) numElements - 1; - - if (i > 0 && data.elements[i] == closeSubPathMarker) - { - while (i >= 0) - { - if (data.elements[i] == moveMarker) - { - i += 2; - break; - } - - --i; - } - } - - if (i > 0) - return Point (data.elements [i - 1], data.elements [i]); - - return Point(); -} - -void Path::addRectangle (const float x, const float y, - const float w, const float h) -{ - float x1 = x, y1 = y, x2 = x + w, y2 = y + h; - - if (w < 0) std::swap (x1, x2); - if (h < 0) std::swap (y1, y2); - - preallocateSpace (13); - - if (numElements == 0) - { - bounds.pathXMin = x1; - bounds.pathXMax = x2; - bounds.pathYMin = y1; - bounds.pathYMax = y2; - } - else - { - bounds.pathXMin = jmin (bounds.pathXMin, x1); - bounds.pathXMax = jmax (bounds.pathXMax, x2); - bounds.pathYMin = jmin (bounds.pathYMin, y1); - bounds.pathYMax = jmax (bounds.pathYMax, y2); - } - - data.elements [numElements++] = moveMarker; - data.elements [numElements++] = x1; - data.elements [numElements++] = y2; - data.elements [numElements++] = lineMarker; - data.elements [numElements++] = x1; - data.elements [numElements++] = y1; - data.elements [numElements++] = lineMarker; - data.elements [numElements++] = x2; - data.elements [numElements++] = y1; - data.elements [numElements++] = lineMarker; - data.elements [numElements++] = x2; - data.elements [numElements++] = y2; - data.elements [numElements++] = closeSubPathMarker; -} - -void Path::addRoundedRectangle (float x, float y, float w, float h, float csx, float csy) -{ - addRoundedRectangle (x, y, w, h, csx, csy, true, true, true, true); -} - -void Path::addRoundedRectangle (const float x, const float y, const float w, const float h, - float csx, float csy, - const bool curveTopLeft, const bool curveTopRight, - const bool curveBottomLeft, const bool curveBottomRight) -{ - csx = jmin (csx, w * 0.5f); - csy = jmin (csy, h * 0.5f); - const float cs45x = csx * 0.45f; - const float cs45y = csy * 0.45f; - const float x2 = x + w; - const float y2 = y + h; - - if (curveTopLeft) - { - startNewSubPath (x, y + csy); - cubicTo (x, y + cs45y, x + cs45x, y, x + csx, y); - } - else - { - startNewSubPath (x, y); - } - - if (curveTopRight) - { - lineTo (x2 - csx, y); - cubicTo (x2 - cs45x, y, x2, y + cs45y, x2, y + csy); - } - else - { - lineTo (x2, y); - } - - if (curveBottomRight) - { - lineTo (x2, y2 - csy); - cubicTo (x2, y2 - cs45y, x2 - cs45x, y2, x2 - csx, y2); - } - else - { - lineTo (x2, y2); - } - - if (curveBottomLeft) - { - lineTo (x + csx, y2); - cubicTo (x + cs45x, y2, x, y2 - cs45y, x, y2 - csy); - } - else - { - lineTo (x, y2); - } - - closeSubPath(); -} - -void Path::addRoundedRectangle (float x, float y, float w, float h, float cs) -{ - addRoundedRectangle (x, y, w, h, cs, cs); -} - -void Path::addTriangle (const float x1, const float y1, - const float x2, const float y2, - const float x3, const float y3) -{ - startNewSubPath (x1, y1); - lineTo (x2, y2); - lineTo (x3, y3); - closeSubPath(); -} - -void Path::addQuadrilateral (const float x1, const float y1, - const float x2, const float y2, - const float x3, const float y3, - const float x4, const float y4) -{ - startNewSubPath (x1, y1); - lineTo (x2, y2); - lineTo (x3, y3); - lineTo (x4, y4); - closeSubPath(); -} - -void Path::addEllipse (float x, float y, float w, float h) -{ - addEllipse (Rectangle (x, y, w, h)); -} - -void Path::addEllipse (Rectangle area) -{ - const float hw = area.getWidth() * 0.5f; - const float hw55 = hw * 0.55f; - const float hh = area.getHeight() * 0.5f; - const float hh55 = hh * 0.55f; - const float cx = area.getX() + hw; - const float cy = area.getY() + hh; - - startNewSubPath (cx, cy - hh); - cubicTo (cx + hw55, cy - hh, cx + hw, cy - hh55, cx + hw, cy); - cubicTo (cx + hw, cy + hh55, cx + hw55, cy + hh, cx, cy + hh); - cubicTo (cx - hw55, cy + hh, cx - hw, cy + hh55, cx - hw, cy); - cubicTo (cx - hw, cy - hh55, cx - hw55, cy - hh, cx, cy - hh); - closeSubPath(); -} - -void Path::addArc (const float x, const float y, - const float w, const float h, - const float fromRadians, - const float toRadians, - const bool startAsNewSubPath) -{ - const float radiusX = w / 2.0f; - const float radiusY = h / 2.0f; - - addCentredArc (x + radiusX, - y + radiusY, - radiusX, radiusY, - 0.0f, - fromRadians, toRadians, - startAsNewSubPath); -} - -void Path::addCentredArc (const float centreX, const float centreY, - const float radiusX, const float radiusY, - const float rotationOfEllipse, - const float fromRadians, - float toRadians, - const bool startAsNewSubPath) -{ - if (radiusX > 0.0f && radiusY > 0.0f) - { - const Point centre (centreX, centreY); - const AffineTransform rotation (AffineTransform::rotation (rotationOfEllipse, centreX, centreY)); - float angle = fromRadians; - - if (startAsNewSubPath) - startNewSubPath (centre.getPointOnCircumference (radiusX, radiusY, angle).transformedBy (rotation)); - - if (fromRadians < toRadians) - { - if (startAsNewSubPath) - angle += PathHelpers::ellipseAngularIncrement; - - while (angle < toRadians) - { - lineTo (centre.getPointOnCircumference (radiusX, radiusY, angle).transformedBy (rotation)); - angle += PathHelpers::ellipseAngularIncrement; - } - } - else - { - if (startAsNewSubPath) - angle -= PathHelpers::ellipseAngularIncrement; - - while (angle > toRadians) - { - lineTo (centre.getPointOnCircumference (radiusX, radiusY, angle).transformedBy (rotation)); - angle -= PathHelpers::ellipseAngularIncrement; - } - } - - lineTo (centre.getPointOnCircumference (radiusX, radiusY, toRadians).transformedBy (rotation)); - } -} - -void Path::addPieSegment (const float x, const float y, - const float width, const float height, - const float fromRadians, - const float toRadians, - const float innerCircleProportionalSize) -{ - float radiusX = width * 0.5f; - float radiusY = height * 0.5f; - const Point centre (x + radiusX, y + radiusY); - - startNewSubPath (centre.getPointOnCircumference (radiusX, radiusY, fromRadians)); - addArc (x, y, width, height, fromRadians, toRadians); - - if (std::abs (fromRadians - toRadians) > float_Pi * 1.999f) - { - closeSubPath(); - - if (innerCircleProportionalSize > 0) - { - radiusX *= innerCircleProportionalSize; - radiusY *= innerCircleProportionalSize; - - startNewSubPath (centre.getPointOnCircumference (radiusX, radiusY, toRadians)); - addArc (centre.x - radiusX, centre.y - radiusY, radiusX * 2.0f, radiusY * 2.0f, toRadians, fromRadians); - } - } - else - { - if (innerCircleProportionalSize > 0) - { - radiusX *= innerCircleProportionalSize; - radiusY *= innerCircleProportionalSize; - - addArc (centre.x - radiusX, centre.y - radiusY, radiusX * 2.0f, radiusY * 2.0f, toRadians, fromRadians); - } - else - { - lineTo (centre); - } - } - - closeSubPath(); -} - -//============================================================================== -void Path::addLineSegment (const Line& line, float lineThickness) -{ - const Line reversed (line.reversed()); - lineThickness *= 0.5f; - - startNewSubPath (line.getPointAlongLine (0, lineThickness)); - lineTo (line.getPointAlongLine (0, -lineThickness)); - lineTo (reversed.getPointAlongLine (0, lineThickness)); - lineTo (reversed.getPointAlongLine (0, -lineThickness)); - closeSubPath(); -} - -void Path::addArrow (const Line& line, float lineThickness, - float arrowheadWidth, float arrowheadLength) -{ - const Line reversed (line.reversed()); - lineThickness *= 0.5f; - arrowheadWidth *= 0.5f; - arrowheadLength = jmin (arrowheadLength, 0.8f * line.getLength()); - - startNewSubPath (line.getPointAlongLine (0, lineThickness)); - lineTo (line.getPointAlongLine (0, -lineThickness)); - lineTo (reversed.getPointAlongLine (arrowheadLength, lineThickness)); - lineTo (reversed.getPointAlongLine (arrowheadLength, arrowheadWidth)); - lineTo (line.getEnd()); - lineTo (reversed.getPointAlongLine (arrowheadLength, -arrowheadWidth)); - lineTo (reversed.getPointAlongLine (arrowheadLength, -lineThickness)); - closeSubPath(); -} - -void Path::addPolygon (const Point centre, const int numberOfSides, - const float radius, const float startAngle) -{ - jassert (numberOfSides > 1); // this would be silly. - - if (numberOfSides > 1) - { - const float angleBetweenPoints = float_Pi * 2.0f / numberOfSides; - - for (int i = 0; i < numberOfSides; ++i) - { - const float angle = startAngle + i * angleBetweenPoints; - const Point p (centre.getPointOnCircumference (radius, angle)); - - if (i == 0) - startNewSubPath (p); - else - lineTo (p); - } - - closeSubPath(); - } -} - -void Path::addStar (const Point centre, const int numberOfPoints, - const float innerRadius, const float outerRadius, const float startAngle) -{ - jassert (numberOfPoints > 1); // this would be silly. - - if (numberOfPoints > 1) - { - const float angleBetweenPoints = float_Pi * 2.0f / numberOfPoints; - - for (int i = 0; i < numberOfPoints; ++i) - { - const float angle = startAngle + i * angleBetweenPoints; - const Point p (centre.getPointOnCircumference (outerRadius, angle)); - - if (i == 0) - startNewSubPath (p); - else - lineTo (p); - - lineTo (centre.getPointOnCircumference (innerRadius, angle + angleBetweenPoints * 0.5f)); - } - - closeSubPath(); - } -} - -void Path::addBubble (const Rectangle& bodyArea, - const Rectangle& maximumArea, - const Point arrowTip, - const float cornerSize, - const float arrowBaseWidth) -{ - const float halfW = bodyArea.getWidth() / 2.0f; - const float halfH = bodyArea.getHeight() / 2.0f; - const float cornerSizeW = jmin (cornerSize, halfW); - const float cornerSizeH = jmin (cornerSize, halfH); - const float cornerSizeW2 = 2.0f * cornerSizeW; - const float cornerSizeH2 = 2.0f * cornerSizeH; - - startNewSubPath (bodyArea.getX() + cornerSizeW, bodyArea.getY()); - - const Rectangle targetLimit (bodyArea.reduced (jmin (halfW - 1.0f, cornerSizeW + arrowBaseWidth), - jmin (halfH - 1.0f, cornerSizeH + arrowBaseWidth))); - - if (Rectangle (targetLimit.getX(), maximumArea.getY(), - targetLimit.getWidth(), bodyArea.getY() - maximumArea.getY()).contains (arrowTip)) - { - lineTo (arrowTip.x - arrowBaseWidth, bodyArea.getY()); - lineTo (arrowTip.x, arrowTip.y); - lineTo (arrowTip.x + arrowBaseWidth, bodyArea.getY()); - } - - lineTo (bodyArea.getRight() - cornerSizeW, bodyArea.getY()); - addArc (bodyArea.getRight() - cornerSizeW2, bodyArea.getY(), cornerSizeW2, cornerSizeH2, 0, float_Pi * 0.5f); - - if (Rectangle (bodyArea.getRight(), targetLimit.getY(), - maximumArea.getRight() - bodyArea.getRight(), targetLimit.getHeight()).contains (arrowTip)) - { - lineTo (bodyArea.getRight(), arrowTip.y - arrowBaseWidth); - lineTo (arrowTip.x, arrowTip.y); - lineTo (bodyArea.getRight(), arrowTip.y + arrowBaseWidth); - } - - lineTo (bodyArea.getRight(), bodyArea.getBottom() - cornerSizeH); - addArc (bodyArea.getRight() - cornerSizeW2, bodyArea.getBottom() - cornerSizeH2, cornerSizeW2, cornerSizeH2, float_Pi * 0.5f, float_Pi); - - if (Rectangle (targetLimit.getX(), bodyArea.getBottom(), - targetLimit.getWidth(), maximumArea.getBottom() - bodyArea.getBottom()).contains (arrowTip)) - { - lineTo (arrowTip.x + arrowBaseWidth, bodyArea.getBottom()); - lineTo (arrowTip.x, arrowTip.y); - lineTo (arrowTip.x - arrowBaseWidth, bodyArea.getBottom()); - } - - lineTo (bodyArea.getX() + cornerSizeW, bodyArea.getBottom()); - addArc (bodyArea.getX(), bodyArea.getBottom() - cornerSizeH2, cornerSizeW2, cornerSizeH2, float_Pi, float_Pi * 1.5f); - - if (Rectangle (maximumArea.getX(), targetLimit.getY(), - bodyArea.getX() - maximumArea.getX(), targetLimit.getHeight()).contains (arrowTip)) - { - lineTo (bodyArea.getX(), arrowTip.y + arrowBaseWidth); - lineTo (arrowTip.x, arrowTip.y); - lineTo (bodyArea.getX(), arrowTip.y - arrowBaseWidth); - } - - lineTo (bodyArea.getX(), bodyArea.getY() + cornerSizeH); - addArc (bodyArea.getX(), bodyArea.getY(), cornerSizeW2, cornerSizeH2, float_Pi * 1.5f, float_Pi * 2.0f - 0.05f); - - closeSubPath(); -} - -void Path::addPath (const Path& other) -{ - size_t i = 0; - const float* const d = other.data.elements; - - while (i < other.numElements) - { - const float type = d[i++]; - - if (type == moveMarker) - { - startNewSubPath (d[i], d[i + 1]); - i += 2; - } - else if (type == lineMarker) - { - lineTo (d[i], d[i + 1]); - i += 2; - } - else if (type == quadMarker) - { - quadraticTo (d[i], d[i + 1], d[i + 2], d[i + 3]); - i += 4; - } - else if (type == cubicMarker) - { - cubicTo (d[i], d[i + 1], d[i + 2], d[i + 3], d[i + 4], d[i + 5]); - i += 6; - } - else if (type == closeSubPathMarker) - { - closeSubPath(); - } - else - { - // something's gone wrong with the element list! - jassertfalse; - } - } -} - -void Path::addPath (const Path& other, - const AffineTransform& transformToApply) -{ - size_t i = 0; - const float* const d = other.data.elements; - - while (i < other.numElements) - { - const float type = d [i++]; - - if (type == closeSubPathMarker) - { - closeSubPath(); - } - else - { - float x = d[i++]; - float y = d[i++]; - transformToApply.transformPoint (x, y); - - if (type == moveMarker) - { - startNewSubPath (x, y); - } - else if (type == lineMarker) - { - lineTo (x, y); - } - else if (type == quadMarker) - { - float x2 = d [i++]; - float y2 = d [i++]; - transformToApply.transformPoint (x2, y2); - - quadraticTo (x, y, x2, y2); - } - else if (type == cubicMarker) - { - float x2 = d [i++]; - float y2 = d [i++]; - float x3 = d [i++]; - float y3 = d [i++]; - transformToApply.transformPoints (x2, y2, x3, y3); - - cubicTo (x, y, x2, y2, x3, y3); - } - else - { - // something's gone wrong with the element list! - jassertfalse; - } - } - } -} - -//============================================================================== -void Path::applyTransform (const AffineTransform& transform) noexcept -{ - bounds.reset(); - bool firstPoint = true; - float* d = data.elements; - float* const end = d + numElements; - - while (d < end) - { - const float type = *d++; - - if (type == moveMarker) - { - transform.transformPoint (d[0], d[1]); - - if (firstPoint) - { - firstPoint = false; - bounds.reset (d[0], d[1]); - } - else - { - bounds.extend (d[0], d[1]); - } - - d += 2; - } - else if (type == lineMarker) - { - transform.transformPoint (d[0], d[1]); - bounds.extend (d[0], d[1]); - d += 2; - } - else if (type == quadMarker) - { - transform.transformPoints (d[0], d[1], d[2], d[3]); - bounds.extend (d[0], d[1], d[2], d[3]); - d += 4; - } - else if (type == cubicMarker) - { - transform.transformPoints (d[0], d[1], d[2], d[3], d[4], d[5]); - bounds.extend (d[0], d[1], d[2], d[3]); - bounds.extend (d[4], d[5]); - d += 6; - } - } -} - - -//============================================================================== -AffineTransform Path::getTransformToScaleToFit (const Rectangle& area, - bool preserveProportions, Justification justification) const -{ - return getTransformToScaleToFit (area.getX(), area.getY(), area.getWidth(), area.getHeight(), - preserveProportions, justification); -} - -AffineTransform Path::getTransformToScaleToFit (const float x, const float y, - const float w, const float h, - const bool preserveProportions, - Justification justification) const -{ - Rectangle boundsRect (getBounds()); - - if (preserveProportions) - { - if (w <= 0 || h <= 0 || boundsRect.isEmpty()) - return AffineTransform::identity; - - float newW, newH; - const float srcRatio = boundsRect.getHeight() / boundsRect.getWidth(); - - if (srcRatio > h / w) - { - newW = h / srcRatio; - newH = h; - } - else - { - newW = w; - newH = w * srcRatio; - } - - float newXCentre = x; - float newYCentre = y; - - if (justification.testFlags (Justification::left)) newXCentre += newW * 0.5f; - else if (justification.testFlags (Justification::right)) newXCentre += w - newW * 0.5f; - else newXCentre += w * 0.5f; - - if (justification.testFlags (Justification::top)) newYCentre += newH * 0.5f; - else if (justification.testFlags (Justification::bottom)) newYCentre += h - newH * 0.5f; - else newYCentre += h * 0.5f; - - return AffineTransform::translation (boundsRect.getWidth() * -0.5f - boundsRect.getX(), - boundsRect.getHeight() * -0.5f - boundsRect.getY()) - .scaled (newW / boundsRect.getWidth(), - newH / boundsRect.getHeight()) - .translated (newXCentre, newYCentre); - } - else - { - return AffineTransform::translation (-boundsRect.getX(), -boundsRect.getY()) - .scaled (w / boundsRect.getWidth(), - h / boundsRect.getHeight()) - .translated (x, y); - } -} - -//============================================================================== -bool Path::contains (const float x, const float y, const float tolerance) const -{ - if (x <= bounds.pathXMin || x >= bounds.pathXMax - || y <= bounds.pathYMin || y >= bounds.pathYMax) - return false; - - PathFlatteningIterator i (*this, AffineTransform::identity, tolerance); - - int positiveCrossings = 0; - int negativeCrossings = 0; - - while (i.next()) - { - if ((i.y1 <= y && i.y2 > y) || (i.y2 <= y && i.y1 > y)) - { - const float intersectX = i.x1 + (i.x2 - i.x1) * (y - i.y1) / (i.y2 - i.y1); - - if (intersectX <= x) - { - if (i.y1 < i.y2) - ++positiveCrossings; - else - ++negativeCrossings; - } - } - } - - return useNonZeroWinding ? (negativeCrossings != positiveCrossings) - : ((negativeCrossings + positiveCrossings) & 1) != 0; -} - -bool Path::contains (const Point point, const float tolerance) const -{ - return contains (point.x, point.y, tolerance); -} - -bool Path::intersectsLine (const Line& line, const float tolerance) -{ - PathFlatteningIterator i (*this, AffineTransform::identity, tolerance); - Point intersection; - - while (i.next()) - if (line.intersects (Line (i.x1, i.y1, i.x2, i.y2), intersection)) - return true; - - return false; -} - -Line Path::getClippedLine (const Line& line, const bool keepSectionOutsidePath) const -{ - Line result (line); - const bool startInside = contains (line.getStart()); - const bool endInside = contains (line.getEnd()); - - if (startInside == endInside) - { - if (keepSectionOutsidePath == startInside) - result = Line(); - } - else - { - PathFlatteningIterator i (*this, AffineTransform::identity); - Point intersection; - - while (i.next()) - { - if (line.intersects (Line (i.x1, i.y1, i.x2, i.y2), intersection)) - { - if ((startInside && keepSectionOutsidePath) || (endInside && ! keepSectionOutsidePath)) - result.setStart (intersection); - else - result.setEnd (intersection); - } - } - } - - return result; -} - -float Path::getLength (const AffineTransform& transform) const -{ - float length = 0; - PathFlatteningIterator i (*this, transform); - - while (i.next()) - length += Line (i.x1, i.y1, i.x2, i.y2).getLength(); - - return length; -} - -Point Path::getPointAlongPath (float distanceFromStart, const AffineTransform& transform) const -{ - PathFlatteningIterator i (*this, transform); - - while (i.next()) - { - const Line line (i.x1, i.y1, i.x2, i.y2); - const float lineLength = line.getLength(); - - if (distanceFromStart <= lineLength) - return line.getPointAlongLine (distanceFromStart); - - distanceFromStart -= lineLength; - } - - return Point (i.x2, i.y2); -} - -float Path::getNearestPoint (const Point targetPoint, Point& pointOnPath, - const AffineTransform& transform) const -{ - PathFlatteningIterator i (*this, transform); - float bestPosition = 0, bestDistance = std::numeric_limits::max(); - float length = 0; - Point pointOnLine; - - while (i.next()) - { - const Line line (i.x1, i.y1, i.x2, i.y2); - const float distance = line.getDistanceFromPoint (targetPoint, pointOnLine); - - if (distance < bestDistance) - { - bestDistance = distance; - bestPosition = length + pointOnLine.getDistanceFrom (line.getStart()); - pointOnPath = pointOnLine; - } - - length += line.getLength(); - } - - return bestPosition; -} - -//============================================================================== -Path Path::createPathWithRoundedCorners (const float cornerRadius) const -{ - if (cornerRadius <= 0.01f) - return *this; - - size_t indexOfPathStart = 0, indexOfPathStartThis = 0; - size_t n = 0; - bool lastWasLine = false, firstWasLine = false; - Path p; - - while (n < numElements) - { - const float type = data.elements [n++]; - - if (type == moveMarker) - { - indexOfPathStart = p.numElements; - indexOfPathStartThis = n - 1; - const float x = data.elements [n++]; - const float y = data.elements [n++]; - p.startNewSubPath (x, y); - lastWasLine = false; - firstWasLine = (data.elements [n] == lineMarker); - } - else if (type == lineMarker || type == closeSubPathMarker) - { - float startX = 0, startY = 0, joinX = 0, joinY = 0, endX, endY; - - if (type == lineMarker) - { - endX = data.elements [n++]; - endY = data.elements [n++]; - - if (n > 8) - { - startX = data.elements [n - 8]; - startY = data.elements [n - 7]; - joinX = data.elements [n - 5]; - joinY = data.elements [n - 4]; - } - } - else - { - endX = data.elements [indexOfPathStartThis + 1]; - endY = data.elements [indexOfPathStartThis + 2]; - - if (n > 6) - { - startX = data.elements [n - 6]; - startY = data.elements [n - 5]; - joinX = data.elements [n - 3]; - joinY = data.elements [n - 2]; - } - } - - if (lastWasLine) - { - const double len1 = PathHelpers::lengthOf (startX, startY, joinX, joinY); - - if (len1 > 0) - { - const double propNeeded = jmin (0.5, cornerRadius / len1); - - p.data.elements [p.numElements - 2] = (float) (joinX - (joinX - startX) * propNeeded); - p.data.elements [p.numElements - 1] = (float) (joinY - (joinY - startY) * propNeeded); - } - - const double len2 = PathHelpers::lengthOf (endX, endY, joinX, joinY); - - if (len2 > 0) - { - const double propNeeded = jmin (0.5, cornerRadius / len2); - - p.quadraticTo (joinX, joinY, - (float) (joinX + (endX - joinX) * propNeeded), - (float) (joinY + (endY - joinY) * propNeeded)); - } - - p.lineTo (endX, endY); - } - else if (type == lineMarker) - { - p.lineTo (endX, endY); - lastWasLine = true; - } - - if (type == closeSubPathMarker) - { - if (firstWasLine) - { - startX = data.elements [n - 3]; - startY = data.elements [n - 2]; - joinX = endX; - joinY = endY; - endX = data.elements [indexOfPathStartThis + 4]; - endY = data.elements [indexOfPathStartThis + 5]; - - const double len1 = PathHelpers::lengthOf (startX, startY, joinX, joinY); - - if (len1 > 0) - { - const double propNeeded = jmin (0.5, cornerRadius / len1); - - p.data.elements [p.numElements - 2] = (float) (joinX - (joinX - startX) * propNeeded); - p.data.elements [p.numElements - 1] = (float) (joinY - (joinY - startY) * propNeeded); - } - - const double len2 = PathHelpers::lengthOf (endX, endY, joinX, joinY); - - if (len2 > 0) - { - const double propNeeded = jmin (0.5, cornerRadius / len2); - - endX = (float) (joinX + (endX - joinX) * propNeeded); - endY = (float) (joinY + (endY - joinY) * propNeeded); - - p.quadraticTo (joinX, joinY, endX, endY); - - p.data.elements [indexOfPathStart + 1] = endX; - p.data.elements [indexOfPathStart + 2] = endY; - } - } - - p.closeSubPath(); - } - } - else if (type == quadMarker) - { - lastWasLine = false; - const float x1 = data.elements [n++]; - const float y1 = data.elements [n++]; - const float x2 = data.elements [n++]; - const float y2 = data.elements [n++]; - p.quadraticTo (x1, y1, x2, y2); - } - else if (type == cubicMarker) - { - lastWasLine = false; - const float x1 = data.elements [n++]; - const float y1 = data.elements [n++]; - const float x2 = data.elements [n++]; - const float y2 = data.elements [n++]; - const float x3 = data.elements [n++]; - const float y3 = data.elements [n++]; - p.cubicTo (x1, y1, x2, y2, x3, y3); - } - } - - return p; -} - -//============================================================================== -void Path::loadPathFromStream (InputStream& source) -{ - while (! source.isExhausted()) - { - switch (source.readByte()) - { - case 'm': - { - const float x = source.readFloat(); - const float y = source.readFloat(); - startNewSubPath (x, y); - break; - } - - case 'l': - { - const float x = source.readFloat(); - const float y = source.readFloat(); - lineTo (x, y); - break; - } - - case 'q': - { - const float x1 = source.readFloat(); - const float y1 = source.readFloat(); - const float x2 = source.readFloat(); - const float y2 = source.readFloat(); - quadraticTo (x1, y1, x2, y2); - break; - } - - case 'b': - { - const float x1 = source.readFloat(); - const float y1 = source.readFloat(); - const float x2 = source.readFloat(); - const float y2 = source.readFloat(); - const float x3 = source.readFloat(); - const float y3 = source.readFloat(); - cubicTo (x1, y1, x2, y2, x3, y3); - break; - } - - case 'c': - closeSubPath(); - break; - - case 'n': - useNonZeroWinding = true; - break; - - case 'z': - useNonZeroWinding = false; - break; - - case 'e': - return; // end of path marker - - default: - jassertfalse; // illegal char in the stream - break; - } - } -} - -void Path::loadPathFromData (const void* const pathData, const size_t numberOfBytes) -{ - MemoryInputStream in (pathData, numberOfBytes, false); - loadPathFromStream (in); -} - -void Path::writePathToStream (OutputStream& dest) const -{ - dest.writeByte (useNonZeroWinding ? 'n' : 'z'); - - size_t i = 0; - while (i < numElements) - { - const float type = data.elements [i++]; - - if (type == moveMarker) - { - dest.writeByte ('m'); - dest.writeFloat (data.elements [i++]); - dest.writeFloat (data.elements [i++]); - } - else if (type == lineMarker) - { - dest.writeByte ('l'); - dest.writeFloat (data.elements [i++]); - dest.writeFloat (data.elements [i++]); - } - else if (type == quadMarker) - { - dest.writeByte ('q'); - dest.writeFloat (data.elements [i++]); - dest.writeFloat (data.elements [i++]); - dest.writeFloat (data.elements [i++]); - dest.writeFloat (data.elements [i++]); - } - else if (type == cubicMarker) - { - dest.writeByte ('b'); - dest.writeFloat (data.elements [i++]); - dest.writeFloat (data.elements [i++]); - dest.writeFloat (data.elements [i++]); - dest.writeFloat (data.elements [i++]); - dest.writeFloat (data.elements [i++]); - dest.writeFloat (data.elements [i++]); - } - else if (type == closeSubPathMarker) - { - dest.writeByte ('c'); - } - } - - dest.writeByte ('e'); // marks the end-of-path -} - -String Path::toString() const -{ - MemoryOutputStream s (2048); - if (! useNonZeroWinding) - s << 'a'; - - size_t i = 0; - float lastMarker = 0.0f; - - while (i < numElements) - { - const float marker = data.elements [i++]; - char markerChar = 0; - int numCoords = 0; - - if (marker == moveMarker) - { - markerChar = 'm'; - numCoords = 2; - } - else if (marker == lineMarker) - { - markerChar = 'l'; - numCoords = 2; - } - else if (marker == quadMarker) - { - markerChar = 'q'; - numCoords = 4; - } - else if (marker == cubicMarker) - { - markerChar = 'c'; - numCoords = 6; - } - else - { - jassert (marker == closeSubPathMarker); - markerChar = 'z'; - } - - if (marker != lastMarker) - { - if (s.getDataSize() != 0) - s << ' '; - - s << markerChar; - lastMarker = marker; - } - - while (--numCoords >= 0 && i < numElements) - { - String coord (data.elements [i++], 3); - - while (coord.endsWithChar ('0') && coord != "0") - coord = coord.dropLastCharacters (1); - - if (coord.endsWithChar ('.')) - coord = coord.dropLastCharacters (1); - - if (s.getDataSize() != 0) - s << ' '; - - s << coord; - } - } - - return s.toUTF8(); -} - -void Path::restoreFromString (StringRef stringVersion) -{ - clear(); - setUsingNonZeroWinding (true); - - String::CharPointerType t (stringVersion.text); - juce_wchar marker = 'm'; - int numValues = 2; - float values [6]; - - for (;;) - { - const String token (PathHelpers::nextToken (t)); - const juce_wchar firstChar = token[0]; - int startNum = 0; - - if (firstChar == 0) - break; - - if (firstChar == 'm' || firstChar == 'l') - { - marker = firstChar; - numValues = 2; - } - else if (firstChar == 'q') - { - marker = firstChar; - numValues = 4; - } - else if (firstChar == 'c') - { - marker = firstChar; - numValues = 6; - } - else if (firstChar == 'z') - { - marker = firstChar; - numValues = 0; - } - else if (firstChar == 'a') - { - setUsingNonZeroWinding (false); - continue; - } - else - { - ++startNum; - values [0] = token.getFloatValue(); - } - - for (int i = startNum; i < numValues; ++i) - values [i] = PathHelpers::nextToken (t).getFloatValue(); - - switch (marker) - { - case 'm': startNewSubPath (values[0], values[1]); break; - case 'l': lineTo (values[0], values[1]); break; - case 'q': quadraticTo (values[0], values[1], values[2], values[3]); break; - case 'c': cubicTo (values[0], values[1], values[2], values[3], values[4], values[5]); break; - case 'z': closeSubPath(); break; - default: jassertfalse; break; // illegal string format? - } - } -} - -//============================================================================== -Path::Iterator::Iterator (const Path& path_) - : path (path_), - index (0) -{ -} - -Path::Iterator::~Iterator() -{ -} - -bool Path::Iterator::next() -{ - const float* const elements = path.data.elements; - - if (index < path.numElements) - { - const float type = elements [index++]; - - if (type == moveMarker) - { - elementType = startNewSubPath; - x1 = elements [index++]; - y1 = elements [index++]; - } - else if (type == lineMarker) - { - elementType = lineTo; - x1 = elements [index++]; - y1 = elements [index++]; - } - else if (type == quadMarker) - { - elementType = quadraticTo; - x1 = elements [index++]; - y1 = elements [index++]; - x2 = elements [index++]; - y2 = elements [index++]; - } - else if (type == cubicMarker) - { - elementType = cubicTo; - x1 = elements [index++]; - y1 = elements [index++]; - x2 = elements [index++]; - y2 = elements [index++]; - x3 = elements [index++]; - y3 = elements [index++]; - } - else if (type == closeSubPathMarker) - { - elementType = closePath; - } - - return true; - } - - return false; -} - -#undef JUCE_CHECK_COORDS_ARE_VALID diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/geometry/juce_Path.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/geometry/juce_Path.h deleted file mode 100644 index ac319f96f3..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/geometry/juce_Path.h +++ /dev/null @@ -1,792 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_PATH_H_INCLUDED -#define JUCE_PATH_H_INCLUDED - - -//============================================================================== -/** - A path is a sequence of lines and curves that may either form a closed shape - or be open-ended. - - To use a path, you can create an empty one, then add lines and curves to it - to create shapes, then it can be rendered by a Graphics context or used - for geometric operations. - - e.g. @code - Path myPath; - - myPath.startNewSubPath (10.0f, 10.0f); // move the current position to (10, 10) - myPath.lineTo (100.0f, 200.0f); // draw a line from here to (100, 200) - myPath.quadraticTo (0.0f, 150.0f, 5.0f, 50.0f); // draw a curve that ends at (5, 50) - myPath.closeSubPath(); // close the subpath with a line back to (10, 10) - - // add an ellipse as well, which will form a second sub-path within the path.. - myPath.addEllipse (50.0f, 50.0f, 40.0f, 30.0f); - - // double the width of the whole thing.. - myPath.applyTransform (AffineTransform::scale (2.0f, 1.0f)); - - // and draw it to a graphics context with a 5-pixel thick outline. - g.strokePath (myPath, PathStrokeType (5.0f)); - - @endcode - - A path object can actually contain multiple sub-paths, which may themselves - be open or closed. - - @see PathFlatteningIterator, PathStrokeType, Graphics -*/ -class JUCE_API Path -{ -public: - //============================================================================== - /** Creates an empty path. */ - Path(); - - /** Creates a copy of another path. */ - Path (const Path&); - - /** Destructor. */ - ~Path(); - - /** Copies this path from another one. */ - Path& operator= (const Path&); - - #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS - Path (Path&&) noexcept; - Path& operator= (Path&&) noexcept; - #endif - - bool operator== (const Path&) const noexcept; - bool operator!= (const Path&) const noexcept; - - //============================================================================== - /** Returns true if the path doesn't contain any lines or curves. */ - bool isEmpty() const noexcept; - - /** Returns the smallest rectangle that contains all points within the path. - */ - Rectangle getBounds() const noexcept; - - /** Returns the smallest rectangle that contains all points within the path - after it's been transformed with the given tranasform matrix. - */ - Rectangle getBoundsTransformed (const AffineTransform& transform) const noexcept; - - /** Checks whether a point lies within the path. - - This is only relevent for closed paths (see closeSubPath()), and - may produce false results if used on a path which has open sub-paths. - - The path's winding rule is taken into account by this method. - - The tolerance parameter is the maximum error allowed when flattening the path, - so this method could return a false positive when your point is up to this distance - outside the path's boundary. - - @see closeSubPath, setUsingNonZeroWinding - */ - bool contains (float x, float y, - float tolerance = 1.0f) const; - - /** Checks whether a point lies within the path. - - This is only relevent for closed paths (see closeSubPath()), and - may produce false results if used on a path which has open sub-paths. - - The path's winding rule is taken into account by this method. - - The tolerance parameter is the maximum error allowed when flattening the path, - so this method could return a false positive when your point is up to this distance - outside the path's boundary. - - @see closeSubPath, setUsingNonZeroWinding - */ - bool contains (const Point point, - float tolerance = 1.0f) const; - - /** Checks whether a line crosses the path. - - This will return positive if the line crosses any of the paths constituent - lines or curves. It doesn't take into account whether the line is inside - or outside the path, or whether the path is open or closed. - - The tolerance parameter is the maximum error allowed when flattening the path, - so this method could return a false positive when your point is up to this distance - outside the path's boundary. - */ - bool intersectsLine (const Line& line, - float tolerance = 1.0f); - - /** Cuts off parts of a line to keep the parts that are either inside or - outside this path. - - Note that this isn't smart enough to cope with situations where the - line would need to be cut into multiple pieces to correctly clip against - a re-entrant shape. - - @param line the line to clip - @param keepSectionOutsidePath if true, it's the section outside the path - that will be kept; if false its the section inside - the path - */ - Line getClippedLine (const Line& line, bool keepSectionOutsidePath) const; - - /** Returns the length of the path. - @see getPointAlongPath - */ - float getLength (const AffineTransform& transform = AffineTransform::identity) const; - - /** Returns a point that is the specified distance along the path. - If the distance is greater than the total length of the path, this will return the - end point. - @see getLength - */ - Point getPointAlongPath (float distanceFromStart, - const AffineTransform& transform = AffineTransform::identity) const; - - /** Finds the point along the path which is nearest to a given position. - This sets pointOnPath to the nearest point, and returns the distance of this point from the start - of the path. - */ - float getNearestPoint (const Point targetPoint, - Point& pointOnPath, - const AffineTransform& transform = AffineTransform::identity) const; - - //============================================================================== - /** Removes all lines and curves, resetting the path completely. */ - void clear() noexcept; - - /** Begins a new subpath with a given starting position. - - This will move the path's current position to the coordinates passed in and - make it ready to draw lines or curves starting from this position. - - After adding whatever lines and curves are needed, you can either - close the current sub-path using closeSubPath() or call startNewSubPath() - to move to a new sub-path, leaving the old one open-ended. - - @see lineTo, quadraticTo, cubicTo, closeSubPath - */ - void startNewSubPath (float startX, float startY); - - /** Begins a new subpath with a given starting position. - - This will move the path's current position to the coordinates passed in and - make it ready to draw lines or curves starting from this position. - - After adding whatever lines and curves are needed, you can either - close the current sub-path using closeSubPath() or call startNewSubPath() - to move to a new sub-path, leaving the old one open-ended. - - @see lineTo, quadraticTo, cubicTo, closeSubPath - */ - void startNewSubPath (const Point start); - - /** Closes a the current sub-path with a line back to its start-point. - - When creating a closed shape such as a triangle, don't use 3 lineTo() - calls - instead use two lineTo() calls, followed by a closeSubPath() - to join the final point back to the start. - - This ensures that closes shapes are recognised as such, and this is - important for tasks like drawing strokes, which needs to know whether to - draw end-caps or not. - - @see startNewSubPath, lineTo, quadraticTo, cubicTo, closeSubPath - */ - void closeSubPath(); - - /** Adds a line from the shape's last position to a new end-point. - - This will connect the end-point of the last line or curve that was added - to a new point, using a straight line. - - See the class description for an example of how to add lines and curves to a path. - - @see startNewSubPath, quadraticTo, cubicTo, closeSubPath - */ - void lineTo (float endX, float endY); - - /** Adds a line from the shape's last position to a new end-point. - - This will connect the end-point of the last line or curve that was added - to a new point, using a straight line. - - See the class description for an example of how to add lines and curves to a path. - - @see startNewSubPath, quadraticTo, cubicTo, closeSubPath - */ - void lineTo (const Point end); - - /** Adds a quadratic bezier curve from the shape's last position to a new position. - - This will connect the end-point of the last line or curve that was added - to a new point, using a quadratic spline with one control-point. - - See the class description for an example of how to add lines and curves to a path. - - @see startNewSubPath, lineTo, cubicTo, closeSubPath - */ - void quadraticTo (float controlPointX, - float controlPointY, - float endPointX, - float endPointY); - - /** Adds a quadratic bezier curve from the shape's last position to a new position. - - This will connect the end-point of the last line or curve that was added - to a new point, using a quadratic spline with one control-point. - - See the class description for an example of how to add lines and curves to a path. - - @see startNewSubPath, lineTo, cubicTo, closeSubPath - */ - void quadraticTo (const Point controlPoint, - const Point endPoint); - - /** Adds a cubic bezier curve from the shape's last position to a new position. - - This will connect the end-point of the last line or curve that was added - to a new point, using a cubic spline with two control-points. - - See the class description for an example of how to add lines and curves to a path. - - @see startNewSubPath, lineTo, quadraticTo, closeSubPath - */ - void cubicTo (float controlPoint1X, - float controlPoint1Y, - float controlPoint2X, - float controlPoint2Y, - float endPointX, - float endPointY); - - /** Adds a cubic bezier curve from the shape's last position to a new position. - - This will connect the end-point of the last line or curve that was added - to a new point, using a cubic spline with two control-points. - - See the class description for an example of how to add lines and curves to a path. - - @see startNewSubPath, lineTo, quadraticTo, closeSubPath - */ - void cubicTo (const Point controlPoint1, - const Point controlPoint2, - const Point endPoint); - - /** Returns the last point that was added to the path by one of the drawing methods. - */ - Point getCurrentPosition() const; - - //============================================================================== - /** Adds a rectangle to the path. - The rectangle is added as a new sub-path. (Any currently open paths will be left open). - @see addRoundedRectangle, addTriangle - */ - void addRectangle (float x, float y, float width, float height); - - /** Adds a rectangle to the path. - The rectangle is added as a new sub-path. (Any currently open paths will be left open). - @see addRoundedRectangle, addTriangle - */ - template - void addRectangle (const Rectangle& rectangle) - { - addRectangle (static_cast (rectangle.getX()), static_cast (rectangle.getY()), - static_cast (rectangle.getWidth()), static_cast (rectangle.getHeight())); - } - - /** Adds a rectangle with rounded corners to the path. - The rectangle is added as a new sub-path. (Any currently open paths will be left open). - @see addRectangle, addTriangle - */ - void addRoundedRectangle (float x, float y, float width, float height, - float cornerSize); - - /** Adds a rectangle with rounded corners to the path. - The rectangle is added as a new sub-path. (Any currently open paths will be left open). - @see addRectangle, addTriangle - */ - void addRoundedRectangle (float x, float y, float width, float height, - float cornerSizeX, - float cornerSizeY); - - /** Adds a rectangle with rounded corners to the path. - The rectangle is added as a new sub-path. (Any currently open paths will be left open). - @see addRectangle, addTriangle - */ - void addRoundedRectangle (float x, float y, float width, float height, - float cornerSizeX, float cornerSizeY, - bool curveTopLeft, bool curveTopRight, - bool curveBottomLeft, bool curveBottomRight); - - /** Adds a rectangle with rounded corners to the path. - The rectangle is added as a new sub-path. (Any currently open paths will be left open). - @see addRectangle, addTriangle - */ - template - void addRoundedRectangle (const Rectangle& rectangle, float cornerSizeX, float cornerSizeY) - { - addRoundedRectangle (static_cast (rectangle.getX()), static_cast (rectangle.getY()), - static_cast (rectangle.getWidth()), static_cast (rectangle.getHeight()), - cornerSizeX, cornerSizeY); - } - - /** Adds a rectangle with rounded corners to the path. - The rectangle is added as a new sub-path. (Any currently open paths will be left open). - @see addRectangle, addTriangle - */ - template - void addRoundedRectangle (const Rectangle& rectangle, float cornerSize) - { - addRoundedRectangle (rectangle, cornerSize, cornerSize); - } - - /** Adds a triangle to the path. - - The triangle is added as a new closed sub-path. (Any currently open paths will be left open). - - Note that whether the vertices are specified in clockwise or anticlockwise - order will affect how the triangle is filled when it overlaps other - shapes (the winding order setting will affect this of course). - */ - void addTriangle (float x1, float y1, - float x2, float y2, - float x3, float y3); - - /** Adds a quadrilateral to the path. - - The quad is added as a new closed sub-path. (Any currently open paths will be left open). - - Note that whether the vertices are specified in clockwise or anticlockwise - order will affect how the quad is filled when it overlaps other - shapes (the winding order setting will affect this of course). - */ - void addQuadrilateral (float x1, float y1, - float x2, float y2, - float x3, float y3, - float x4, float y4); - - /** Adds an ellipse to the path. - The shape is added as a new sub-path. (Any currently open paths will be left open). - @see addArc - */ - void addEllipse (float x, float y, float width, float height); - - /** Adds an ellipse to the path. - The shape is added as a new sub-path. (Any currently open paths will be left open). - @see addArc - */ - void addEllipse (Rectangle area); - - /** Adds an elliptical arc to the current path. - - Note that when specifying the start and end angles, the curve will be drawn either clockwise - or anti-clockwise according to whether the end angle is greater than the start. This means - that sometimes you may need to use values greater than 2*Pi for the end angle. - - @param x the left-hand edge of the rectangle in which the elliptical outline fits - @param y the top edge of the rectangle in which the elliptical outline fits - @param width the width of the rectangle in which the elliptical outline fits - @param height the height of the rectangle in which the elliptical outline fits - @param fromRadians the angle (clockwise) in radians at which to start the arc segment (where 0 is the - top-centre of the ellipse) - @param toRadians the angle (clockwise) in radians at which to end the arc segment (where 0 is the - top-centre of the ellipse). This angle can be greater than 2*Pi, so for example to - draw a curve clockwise from the 9 o'clock position to the 3 o'clock position via - 12 o'clock, you'd use 1.5*Pi and 2.5*Pi as the start and finish points. - @param startAsNewSubPath if true, the arc will begin a new subpath from its starting point; if false, - it will be added to the current sub-path, continuing from the current postition - - @see addCentredArc, arcTo, addPieSegment, addEllipse - */ - void addArc (float x, float y, float width, float height, - float fromRadians, - float toRadians, - bool startAsNewSubPath = false); - - /** Adds an arc which is centred at a given point, and can have a rotation specified. - - Note that when specifying the start and end angles, the curve will be drawn either clockwise - or anti-clockwise according to whether the end angle is greater than the start. This means - that sometimes you may need to use values greater than 2*Pi for the end angle. - - @param centreX the centre x of the ellipse - @param centreY the centre y of the ellipse - @param radiusX the horizontal radius of the ellipse - @param radiusY the vertical radius of the ellipse - @param rotationOfEllipse an angle by which the whole ellipse should be rotated about its centre, in radians (clockwise) - @param fromRadians the angle (clockwise) in radians at which to start the arc segment (where 0 is the - top-centre of the ellipse) - @param toRadians the angle (clockwise) in radians at which to end the arc segment (where 0 is the - top-centre of the ellipse). This angle can be greater than 2*Pi, so for example to - draw a curve clockwise from the 9 o'clock position to the 3 o'clock position via - 12 o'clock, you'd use 1.5*Pi and 2.5*Pi as the start and finish points. - @param startAsNewSubPath if true, the arc will begin a new subpath from its starting point; if false, - it will be added to the current sub-path, continuing from the current postition - - @see addArc, arcTo - */ - void addCentredArc (float centreX, float centreY, - float radiusX, float radiusY, - float rotationOfEllipse, - float fromRadians, - float toRadians, - bool startAsNewSubPath = false); - - /** Adds a "pie-chart" shape to the path. - - The shape is added as a new sub-path. (Any currently open paths will be - left open). - - Note that when specifying the start and end angles, the curve will be drawn either clockwise - or anti-clockwise according to whether the end angle is greater than the start. This means - that sometimes you may need to use values greater than 2*Pi for the end angle. - - @param x the left-hand edge of the rectangle in which the elliptical outline fits - @param y the top edge of the rectangle in which the elliptical outline fits - @param width the width of the rectangle in which the elliptical outline fits - @param height the height of the rectangle in which the elliptical outline fits - @param fromRadians the angle (clockwise) in radians at which to start the arc segment (where 0 is the - top-centre of the ellipse) - @param toRadians the angle (clockwise) in radians at which to end the arc segment (where 0 is the - top-centre of the ellipse) - @param innerCircleProportionalSize if this is > 0, then the pie will be drawn as a curved band around a hollow - ellipse at its centre, where this value indicates the inner ellipse's size with - respect to the outer one. - - @see addArc - */ - void addPieSegment (float x, float y, - float width, float height, - float fromRadians, - float toRadians, - float innerCircleProportionalSize); - - /** Adds a line with a specified thickness. - - The line is added as a new closed sub-path. (Any currently open paths will be - left open). - - @see addArrow - */ - void addLineSegment (const Line& line, float lineThickness); - - /** Adds a line with an arrowhead on the end. - The arrow is added as a new closed sub-path. (Any currently open paths will be left open). - @see PathStrokeType::createStrokeWithArrowheads - */ - void addArrow (const Line& line, - float lineThickness, - float arrowheadWidth, - float arrowheadLength); - - /** Adds a polygon shape to the path. - @see addStar - */ - void addPolygon (const Point centre, - int numberOfSides, - float radius, - float startAngle = 0.0f); - - /** Adds a star shape to the path. - @see addPolygon - */ - void addStar (const Point centre, - int numberOfPoints, - float innerRadius, - float outerRadius, - float startAngle = 0.0f); - - /** Adds a speech-bubble shape to the path. - - @param bodyArea the area of the body of the bubble shape - @param maximumArea an area which encloses the body area and defines the limits within which - the arrow tip can be drawn - if the tip lies outside this area, the bubble - will be drawn without an arrow - @param arrowTipPosition the location of the tip of the arrow - @param cornerSize the size of the rounded corners - @param arrowBaseWidth the width of the base of the arrow where it joins the main rectangle - */ - void addBubble (const Rectangle& bodyArea, - const Rectangle& maximumArea, - const Point arrowTipPosition, - const float cornerSize, - const float arrowBaseWidth); - - /** Adds another path to this one. - - The new path is added as a new sub-path. (Any currently open paths in this - path will be left open). - - @param pathToAppend the path to add - */ - void addPath (const Path& pathToAppend); - - /** Adds another path to this one, transforming it on the way in. - - The new path is added as a new sub-path, its points being transformed by the given - matrix before being added. - - @param pathToAppend the path to add - @param transformToApply an optional transform to apply to the incoming vertices - */ - void addPath (const Path& pathToAppend, - const AffineTransform& transformToApply); - - /** Swaps the contents of this path with another one. - - The internal data of the two paths is swapped over, so this is much faster than - copying it to a temp variable and back. - */ - void swapWithPath (Path&) noexcept; - - //============================================================================== - /** Preallocates enough space for adding the given number of coordinates to the path. - If you're about to add a large number of lines or curves to the path, it can make - the task much more efficient to call this first and avoid costly reallocations - as the structure grows. - The actual value to pass is a bit tricky to calculate because the space required - depends on what you're adding - e.g. each lineTo() or startNewSubPath() will - require 3 coords (x, y and a type marker). Each quadraticTo() will need 5, and - a cubicTo() will require 7. Closing a sub-path will require 1. - */ - void preallocateSpace (int numExtraCoordsToMakeSpaceFor); - - //============================================================================== - /** Applies a 2D transform to all the vertices in the path. - - @see AffineTransform, scaleToFit, getTransformToScaleToFit - */ - void applyTransform (const AffineTransform& transform) noexcept; - - /** Rescales this path to make it fit neatly into a given space. - - This is effectively a quick way of calling - applyTransform (getTransformToScaleToFit (x, y, w, h, preserveProportions)) - - @param x the x position of the rectangle to fit the path inside - @param y the y position of the rectangle to fit the path inside - @param width the width of the rectangle to fit the path inside - @param height the height of the rectangle to fit the path inside - @param preserveProportions if true, it will fit the path into the space without altering its - horizontal/vertical scale ratio; if false, it will distort the - path to fill the specified ratio both horizontally and vertically - - @see applyTransform, getTransformToScaleToFit - */ - void scaleToFit (float x, float y, float width, float height, - bool preserveProportions) noexcept; - - /** Returns a transform that can be used to rescale the path to fit into a given space. - - @param x the x position of the rectangle to fit the path inside - @param y the y position of the rectangle to fit the path inside - @param width the width of the rectangle to fit the path inside - @param height the height of the rectangle to fit the path inside - @param preserveProportions if true, it will fit the path into the space without altering its - horizontal/vertical scale ratio; if false, it will distort the - path to fill the specified ratio both horizontally and vertically - @param justificationType if the proportions are preseved, the resultant path may be smaller - than the available rectangle, so this describes how it should be - positioned within the space. - @returns an appropriate transformation - - @see applyTransform, scaleToFit - - */ - AffineTransform getTransformToScaleToFit (float x, float y, float width, float height, - bool preserveProportions, - Justification justificationType = Justification::centred) const; - - /** Returns a transform that can be used to rescale the path to fit into a given space. - - @param area the rectangle to fit the path inside - @param preserveProportions if true, it will fit the path into the space without altering its - horizontal/vertical scale ratio; if false, it will distort the - path to fill the specified ratio both horizontally and vertically - @param justificationType if the proportions are preseved, the resultant path may be smaller - than the available rectangle, so this describes how it should be - positioned within the space. - @returns an appropriate transformation - - @see applyTransform, scaleToFit - - */ - AffineTransform getTransformToScaleToFit (const Rectangle& area, - bool preserveProportions, - Justification justificationType = Justification::centred) const; - - /** Creates a version of this path where all sharp corners have been replaced by curves. - - Wherever two lines meet at an angle, this will replace the corner with a curve - of the given radius. - */ - Path createPathWithRoundedCorners (float cornerRadius) const; - - //============================================================================== - /** Changes the winding-rule to be used when filling the path. - - If set to true (which is the default), then the path uses a non-zero-winding rule - to determine which points are inside the path. If set to false, it uses an - alternate-winding rule. - - The winding-rule comes into play when areas of the shape overlap other - areas, and determines whether the overlapping regions are considered to be - inside or outside. - - Changing this value just sets a flag - it doesn't affect the contents of the - path. - - @see isUsingNonZeroWinding - */ - void setUsingNonZeroWinding (bool isNonZeroWinding) noexcept; - - /** Returns the flag that indicates whether the path should use a non-zero winding rule. - - The default for a new path is true. - - @see setUsingNonZeroWinding - */ - bool isUsingNonZeroWinding() const { return useNonZeroWinding; } - - - //============================================================================== - /** Iterates the lines and curves that a path contains. - - @see Path, PathFlatteningIterator - */ - class JUCE_API Iterator - { - public: - //============================================================================== - Iterator (const Path& path); - ~Iterator(); - - //============================================================================== - /** Moves onto the next element in the path. - - If this returns false, there are no more elements. If it returns true, - the elementType variable will be set to the type of the current element, - and some of the x and y variables will be filled in with values. - */ - bool next(); - - //============================================================================== - enum PathElementType - { - startNewSubPath, /**< For this type, x1 and y1 will be set to indicate the first point in the subpath. */ - lineTo, /**< For this type, x1 and y1 indicate the end point of the line. */ - quadraticTo, /**< For this type, x1, y1, x2, y2 indicate the control point and endpoint of a quadratic curve. */ - cubicTo, /**< For this type, x1, y1, x2, y2, x3, y3 indicate the two control points and the endpoint of a cubic curve. */ - closePath /**< Indicates that the sub-path is being closed. None of the x or y values are valid in this case. */ - }; - - PathElementType elementType; - - float x1, y1, x2, y2, x3, y3; - - //============================================================================== - private: - const Path& path; - size_t index; - - JUCE_DECLARE_NON_COPYABLE (Iterator) - }; - - //============================================================================== - /** Loads a stored path from a data stream. - - The data in the stream must have been written using writePathToStream(). - - Note that this will append the stored path to whatever is currently in - this path, so you might need to call clear() beforehand. - - @see loadPathFromData, writePathToStream - */ - void loadPathFromStream (InputStream& source); - - /** Loads a stored path from a block of data. - - This is similar to loadPathFromStream(), but just reads from a block - of data. Useful if you're including stored shapes in your code as a - block of static data. - - @see loadPathFromStream, writePathToStream - */ - void loadPathFromData (const void* data, size_t numberOfBytes); - - /** Stores the path by writing it out to a stream. - - After writing out a path, you can reload it using loadPathFromStream(). - - @see loadPathFromStream, loadPathFromData - */ - void writePathToStream (OutputStream& destination) const; - - //============================================================================== - /** Creates a string containing a textual representation of this path. - @see restoreFromString - */ - String toString() const; - - /** Restores this path from a string that was created with the toString() method. - @see toString() - */ - void restoreFromString (StringRef stringVersion); - -private: - //============================================================================== - friend class PathFlatteningIterator; - friend class Path::Iterator; - ArrayAllocationBase data; - size_t numElements; - - struct PathBounds - { - PathBounds() noexcept; - Rectangle getRectangle() const noexcept; - void reset() noexcept; - void reset (float, float) noexcept; - void extend (float, float) noexcept; - void extend (float, float, float, float) noexcept; - - float pathXMin, pathXMax, pathYMin, pathYMax; - }; - - PathBounds bounds; - bool useNonZeroWinding; - - static const float lineMarker; - static const float moveMarker; - static const float quadMarker; - static const float cubicMarker; - static const float closeSubPathMarker; - - JUCE_LEAK_DETECTOR (Path) -}; - -#endif // JUCE_PATH_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/geometry/juce_PathIterator.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/geometry/juce_PathIterator.cpp deleted file mode 100644 index 0a15581ceb..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/geometry/juce_PathIterator.cpp +++ /dev/null @@ -1,286 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#if JUCE_MSVC && JUCE_DEBUG - #pragma optimize ("t", on) -#endif - -const float PathFlatteningIterator::defaultTolerance = 0.6f; - -//============================================================================== -PathFlatteningIterator::PathFlatteningIterator (const Path& path_, - const AffineTransform& transform_, - const float tolerance) - : x2 (0), - y2 (0), - closesSubPath (false), - subPathIndex (-1), - path (path_), - transform (transform_), - points (path_.data.elements), - toleranceSquared (tolerance * tolerance), - subPathCloseX (0), - subPathCloseY (0), - isIdentityTransform (transform_.isIdentity()), - stackBase (32), - index (0), - stackSize (32) -{ - stackPos = stackBase; -} - -PathFlatteningIterator::~PathFlatteningIterator() -{ -} - -bool PathFlatteningIterator::isLastInSubpath() const noexcept -{ - return stackPos == stackBase.getData() - && (index >= path.numElements || points [index] == Path::moveMarker); -} - -bool PathFlatteningIterator::next() -{ - x1 = x2; - y1 = y2; - - float x3 = 0; - float y3 = 0; - float x4 = 0; - float y4 = 0; - - for (;;) - { - float type; - - if (stackPos == stackBase) - { - if (index >= path.numElements) - return false; - - type = points [index++]; - - if (type != Path::closeSubPathMarker) - { - x2 = points [index++]; - y2 = points [index++]; - - if (type == Path::quadMarker) - { - x3 = points [index++]; - y3 = points [index++]; - - if (! isIdentityTransform) - transform.transformPoints (x2, y2, x3, y3); - } - else if (type == Path::cubicMarker) - { - x3 = points [index++]; - y3 = points [index++]; - x4 = points [index++]; - y4 = points [index++]; - - if (! isIdentityTransform) - transform.transformPoints (x2, y2, x3, y3, x4, y4); - } - else - { - if (! isIdentityTransform) - transform.transformPoint (x2, y2); - } - } - } - else - { - type = *--stackPos; - - if (type != Path::closeSubPathMarker) - { - x2 = *--stackPos; - y2 = *--stackPos; - - if (type == Path::quadMarker) - { - x3 = *--stackPos; - y3 = *--stackPos; - } - else if (type == Path::cubicMarker) - { - x3 = *--stackPos; - y3 = *--stackPos; - x4 = *--stackPos; - y4 = *--stackPos; - } - } - } - - if (type == Path::lineMarker) - { - ++subPathIndex; - - closesSubPath = (stackPos == stackBase) - && (index < path.numElements) - && (points [index] == Path::closeSubPathMarker) - && x2 == subPathCloseX - && y2 == subPathCloseY; - - return true; - } - - if (type == Path::quadMarker) - { - const size_t offset = (size_t) (stackPos - stackBase); - - if (offset >= stackSize - 10) - { - stackSize <<= 1; - stackBase.realloc (stackSize); - stackPos = stackBase + offset; - } - - const float m1x = (x1 + x2) * 0.5f; - const float m1y = (y1 + y2) * 0.5f; - const float m2x = (x2 + x3) * 0.5f; - const float m2y = (y2 + y3) * 0.5f; - const float m3x = (m1x + m2x) * 0.5f; - const float m3y = (m1y + m2y) * 0.5f; - - const float errorX = m3x - x2; - const float errorY = m3y - y2; - - if (errorX * errorX + errorY * errorY > toleranceSquared) - { - *stackPos++ = y3; - *stackPos++ = x3; - *stackPos++ = m2y; - *stackPos++ = m2x; - *stackPos++ = Path::quadMarker; - - *stackPos++ = m3y; - *stackPos++ = m3x; - *stackPos++ = m1y; - *stackPos++ = m1x; - *stackPos++ = Path::quadMarker; - } - else - { - *stackPos++ = y3; - *stackPos++ = x3; - *stackPos++ = Path::lineMarker; - - *stackPos++ = m3y; - *stackPos++ = m3x; - *stackPos++ = Path::lineMarker; - } - - jassert (stackPos < stackBase + stackSize); - } - else if (type == Path::cubicMarker) - { - const size_t offset = (size_t) (stackPos - stackBase); - - if (offset >= stackSize - 16) - { - stackSize <<= 1; - stackBase.realloc (stackSize); - stackPos = stackBase + offset; - } - - const float m1x = (x1 + x2) * 0.5f; - const float m1y = (y1 + y2) * 0.5f; - const float m2x = (x3 + x2) * 0.5f; - const float m2y = (y3 + y2) * 0.5f; - const float m3x = (x3 + x4) * 0.5f; - const float m3y = (y3 + y4) * 0.5f; - const float m4x = (m1x + m2x) * 0.5f; - const float m4y = (m1y + m2y) * 0.5f; - const float m5x = (m3x + m2x) * 0.5f; - const float m5y = (m3y + m2y) * 0.5f; - - const float error1X = m4x - x2; - const float error1Y = m4y - y2; - const float error2X = m5x - x3; - const float error2Y = m5y - y3; - - if (error1X * error1X + error1Y * error1Y > toleranceSquared - || error2X * error2X + error2Y * error2Y > toleranceSquared) - { - *stackPos++ = y4; - *stackPos++ = x4; - *stackPos++ = m3y; - *stackPos++ = m3x; - *stackPos++ = m5y; - *stackPos++ = m5x; - *stackPos++ = Path::cubicMarker; - - *stackPos++ = (m4y + m5y) * 0.5f; - *stackPos++ = (m4x + m5x) * 0.5f; - *stackPos++ = m4y; - *stackPos++ = m4x; - *stackPos++ = m1y; - *stackPos++ = m1x; - *stackPos++ = Path::cubicMarker; - } - else - { - *stackPos++ = y4; - *stackPos++ = x4; - *stackPos++ = Path::lineMarker; - - *stackPos++ = m5y; - *stackPos++ = m5x; - *stackPos++ = Path::lineMarker; - - *stackPos++ = m4y; - *stackPos++ = m4x; - *stackPos++ = Path::lineMarker; - } - } - else if (type == Path::closeSubPathMarker) - { - if (x2 != subPathCloseX || y2 != subPathCloseY) - { - x1 = x2; - y1 = y2; - x2 = subPathCloseX; - y2 = subPathCloseY; - closesSubPath = true; - - return true; - } - } - else - { - jassert (type == Path::moveMarker); - - subPathIndex = -1; - subPathCloseX = x1 = x2; - subPathCloseY = y1 = y2; - } - } -} - -#if JUCE_MSVC && JUCE_DEBUG - #pragma optimize ("", on) // resets optimisations to the project defaults -#endif diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/geometry/juce_PathIterator.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/geometry/juce_PathIterator.h deleted file mode 100644 index dcb8b90319..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/geometry/juce_PathIterator.h +++ /dev/null @@ -1,113 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_PATHITERATOR_H_INCLUDED -#define JUCE_PATHITERATOR_H_INCLUDED - - -//============================================================================== -/** - Flattens a Path object into a series of straight-line sections. - - Use one of these to iterate through a Path object, and it will convert - all the curves into line sections so it's easy to render or perform - geometric operations on. - - @see Path -*/ -class JUCE_API PathFlatteningIterator -{ -public: - //============================================================================== - /** Creates a PathFlatteningIterator. - - After creation, use the next() method to initialise the fields in the - object with the first line's position. - - @param path the path to iterate along - @param transform a transform to apply to each point in the path being iterated - @param tolerance the amount by which the curves are allowed to deviate from the lines - into which they are being broken down - a higher tolerance contains - less lines, so can be generated faster, but will be less smooth. - */ - PathFlatteningIterator (const Path& path, - const AffineTransform& transform = AffineTransform::identity, - float tolerance = defaultTolerance); - - /** Destructor. */ - ~PathFlatteningIterator(); - - //============================================================================== - /** Fetches the next line segment from the path. - - This will update the member variables x1, y1, x2, y2, subPathIndex and closesSubPath - so that they describe the new line segment. - - @returns false when there are no more lines to fetch. - */ - bool next(); - - float x1; /**< The x position of the start of the current line segment. */ - float y1; /**< The y position of the start of the current line segment. */ - float x2; /**< The x position of the end of the current line segment. */ - float y2; /**< The y position of the end of the current line segment. */ - - /** Indicates whether the current line segment is closing a sub-path. - - If the current line is the one that connects the end of a sub-path - back to the start again, this will be true. - */ - bool closesSubPath; - - /** The index of the current line within the current sub-path. - - E.g. you can use this to see whether the line is the first one in the - subpath by seeing if it's 0. - */ - int subPathIndex; - - /** Returns true if the current segment is the last in the current sub-path. */ - bool isLastInSubpath() const noexcept; - - /** This is the default value that should be used for the tolerance value (see the constructor parameters). */ - static const float defaultTolerance; - -private: - //============================================================================== - const Path& path; - const AffineTransform transform; - float* points; - const float toleranceSquared; - float subPathCloseX, subPathCloseY; - const bool isIdentityTransform; - - HeapBlock stackBase; - float* stackPos; - size_t index, stackSize; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (PathFlatteningIterator) -}; - - -#endif // JUCE_PATHITERATOR_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/geometry/juce_PathStrokeType.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/geometry/juce_PathStrokeType.cpp deleted file mode 100644 index bdac333d3d..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/geometry/juce_PathStrokeType.cpp +++ /dev/null @@ -1,740 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -PathStrokeType::PathStrokeType (float strokeThickness) noexcept - : thickness (strokeThickness), jointStyle (mitered), endStyle (butt) -{ -} - -PathStrokeType::PathStrokeType (float strokeThickness, JointStyle joint, EndCapStyle end) noexcept - : thickness (strokeThickness), jointStyle (joint), endStyle (end) -{ -} - -PathStrokeType::PathStrokeType (const PathStrokeType& other) noexcept - : thickness (other.thickness), - jointStyle (other.jointStyle), - endStyle (other.endStyle) -{ -} - -PathStrokeType& PathStrokeType::operator= (const PathStrokeType& other) noexcept -{ - thickness = other.thickness; - jointStyle = other.jointStyle; - endStyle = other.endStyle; - return *this; -} - -PathStrokeType::~PathStrokeType() noexcept -{ -} - -bool PathStrokeType::operator== (const PathStrokeType& other) const noexcept -{ - return thickness == other.thickness - && jointStyle == other.jointStyle - && endStyle == other.endStyle; -} - -bool PathStrokeType::operator!= (const PathStrokeType& other) const noexcept -{ - return ! operator== (other); -} - -//============================================================================== -namespace PathStrokeHelpers -{ - static bool lineIntersection (const float x1, const float y1, - const float x2, const float y2, - const float x3, const float y3, - const float x4, const float y4, - float& intersectionX, - float& intersectionY, - float& distanceBeyondLine1EndSquared) noexcept - { - if (x2 != x3 || y2 != y3) - { - const float dx1 = x2 - x1; - const float dy1 = y2 - y1; - const float dx2 = x4 - x3; - const float dy2 = y4 - y3; - const float divisor = dx1 * dy2 - dx2 * dy1; - - if (divisor == 0) - { - if (! ((dx1 == 0 && dy1 == 0) || (dx2 == 0 && dy2 == 0))) - { - if (dy1 == 0 && dy2 != 0) - { - const float along = (y1 - y3) / dy2; - intersectionX = x3 + along * dx2; - intersectionY = y1; - - distanceBeyondLine1EndSquared = intersectionX - x2; - distanceBeyondLine1EndSquared *= distanceBeyondLine1EndSquared; - if ((x2 > x1) == (intersectionX < x2)) - distanceBeyondLine1EndSquared = -distanceBeyondLine1EndSquared; - - return along >= 0 && along <= 1.0f; - } - else if (dy2 == 0 && dy1 != 0) - { - const float along = (y3 - y1) / dy1; - intersectionX = x1 + along * dx1; - intersectionY = y3; - - distanceBeyondLine1EndSquared = (along - 1.0f) * dx1; - distanceBeyondLine1EndSquared *= distanceBeyondLine1EndSquared; - if (along < 1.0f) - distanceBeyondLine1EndSquared = -distanceBeyondLine1EndSquared; - - return along >= 0 && along <= 1.0f; - } - else if (dx1 == 0 && dx2 != 0) - { - const float along = (x1 - x3) / dx2; - intersectionX = x1; - intersectionY = y3 + along * dy2; - - distanceBeyondLine1EndSquared = intersectionY - y2; - distanceBeyondLine1EndSquared *= distanceBeyondLine1EndSquared; - - if ((y2 > y1) == (intersectionY < y2)) - distanceBeyondLine1EndSquared = -distanceBeyondLine1EndSquared; - - return along >= 0 && along <= 1.0f; - } - else if (dx2 == 0 && dx1 != 0) - { - const float along = (x3 - x1) / dx1; - intersectionX = x3; - intersectionY = y1 + along * dy1; - - distanceBeyondLine1EndSquared = (along - 1.0f) * dy1; - distanceBeyondLine1EndSquared *= distanceBeyondLine1EndSquared; - if (along < 1.0f) - distanceBeyondLine1EndSquared = -distanceBeyondLine1EndSquared; - - return along >= 0 && along <= 1.0f; - } - } - - intersectionX = 0.5f * (x2 + x3); - intersectionY = 0.5f * (y2 + y3); - - distanceBeyondLine1EndSquared = 0.0f; - return false; - } - else - { - const float along1 = ((y1 - y3) * dx2 - (x1 - x3) * dy2) / divisor; - - intersectionX = x1 + along1 * dx1; - intersectionY = y1 + along1 * dy1; - - if (along1 >= 0 && along1 <= 1.0f) - { - const float along2 = ((y1 - y3) * dx1 - (x1 - x3) * dy1); - - if (along2 >= 0 && along2 <= divisor) - { - distanceBeyondLine1EndSquared = 0.0f; - return true; - } - } - - distanceBeyondLine1EndSquared = along1 - 1.0f; - distanceBeyondLine1EndSquared *= distanceBeyondLine1EndSquared; - distanceBeyondLine1EndSquared *= (dx1 * dx1 + dy1 * dy1); - - if (along1 < 1.0f) - distanceBeyondLine1EndSquared = -distanceBeyondLine1EndSquared; - - return false; - } - } - - intersectionX = x2; - intersectionY = y2; - - distanceBeyondLine1EndSquared = 0.0f; - return true; - } - - static void addEdgeAndJoint (Path& destPath, - const PathStrokeType::JointStyle style, - const float maxMiterExtensionSquared, const float width, - const float x1, const float y1, - const float x2, const float y2, - const float x3, const float y3, - const float x4, const float y4, - const float midX, const float midY) - { - if (style == PathStrokeType::beveled - || (x3 == x4 && y3 == y4) - || (x1 == x2 && y1 == y2)) - { - destPath.lineTo (x2, y2); - destPath.lineTo (x3, y3); - } - else - { - float jx, jy, distanceBeyondLine1EndSquared; - - // if they intersect, use this point.. - if (lineIntersection (x1, y1, x2, y2, - x3, y3, x4, y4, - jx, jy, distanceBeyondLine1EndSquared)) - { - destPath.lineTo (jx, jy); - } - else - { - if (style == PathStrokeType::mitered) - { - if (distanceBeyondLine1EndSquared < maxMiterExtensionSquared - && distanceBeyondLine1EndSquared > 0.0f) - { - destPath.lineTo (jx, jy); - } - else - { - // the end sticks out too far, so just use a blunt joint - destPath.lineTo (x2, y2); - destPath.lineTo (x3, y3); - } - } - else - { - // curved joints - float angle1 = std::atan2 (x2 - midX, y2 - midY); - float angle2 = std::atan2 (x3 - midX, y3 - midY); - const float angleIncrement = 0.1f; - - destPath.lineTo (x2, y2); - - if (std::abs (angle1 - angle2) > angleIncrement) - { - if (angle2 > angle1 + float_Pi - || (angle2 < angle1 && angle2 >= angle1 - float_Pi)) - { - if (angle2 > angle1) - angle2 -= float_Pi * 2.0f; - - jassert (angle1 <= angle2 + float_Pi); - - angle1 -= angleIncrement; - while (angle1 > angle2) - { - destPath.lineTo (midX + width * std::sin (angle1), - midY + width * std::cos (angle1)); - - angle1 -= angleIncrement; - } - } - else - { - if (angle1 > angle2) - angle1 -= float_Pi * 2.0f; - - jassert (angle1 >= angle2 - float_Pi); - - angle1 += angleIncrement; - while (angle1 < angle2) - { - destPath.lineTo (midX + width * std::sin (angle1), - midY + width * std::cos (angle1)); - - angle1 += angleIncrement; - } - } - } - - destPath.lineTo (x3, y3); - } - } - } - } - - static void addLineEnd (Path& destPath, - const PathStrokeType::EndCapStyle style, - const float x1, const float y1, - const float x2, const float y2, - const float width) - { - if (style == PathStrokeType::butt) - { - destPath.lineTo (x2, y2); - } - else - { - float offx1, offy1, offx2, offy2; - - float dx = x2 - x1; - float dy = y2 - y1; - const float len = juce_hypot (dx, dy); - - if (len == 0) - { - offx1 = offx2 = x1; - offy1 = offy2 = y1; - } - else - { - const float offset = width / len; - dx *= offset; - dy *= offset; - - offx1 = x1 + dy; - offy1 = y1 - dx; - offx2 = x2 + dy; - offy2 = y2 - dx; - } - - if (style == PathStrokeType::square) - { - // sqaure ends - destPath.lineTo (offx1, offy1); - destPath.lineTo (offx2, offy2); - destPath.lineTo (x2, y2); - } - else - { - // rounded ends - const float midx = (offx1 + offx2) * 0.5f; - const float midy = (offy1 + offy2) * 0.5f; - - destPath.cubicTo (x1 + (offx1 - x1) * 0.55f, y1 + (offy1 - y1) * 0.55f, - offx1 + (midx - offx1) * 0.45f, offy1 + (midy - offy1) * 0.45f, - midx, midy); - - destPath.cubicTo (midx + (offx2 - midx) * 0.55f, midy + (offy2 - midy) * 0.55f, - offx2 + (x2 - offx2) * 0.45f, offy2 + (y2 - offy2) * 0.45f, - x2, y2); - } - } - } - - struct Arrowhead - { - float startWidth, startLength; - float endWidth, endLength; - }; - - static void addArrowhead (Path& destPath, - const float x1, const float y1, - const float x2, const float y2, - const float tipX, const float tipY, - const float width, - const float arrowheadWidth) - { - Line line (x1, y1, x2, y2); - destPath.lineTo (line.getPointAlongLine (-(arrowheadWidth / 2.0f - width), 0)); - destPath.lineTo (tipX, tipY); - destPath.lineTo (line.getPointAlongLine (arrowheadWidth - (arrowheadWidth / 2.0f - width), 0)); - destPath.lineTo (x2, y2); - } - - struct LineSection - { - float x1, y1, x2, y2; // original line - float lx1, ly1, lx2, ly2; // the left-hand stroke - float rx1, ry1, rx2, ry2; // the right-hand stroke - }; - - static void shortenSubPath (Array& subPath, float amountAtStart, float amountAtEnd) - { - while (amountAtEnd > 0 && subPath.size() > 0) - { - LineSection& l = subPath.getReference (subPath.size() - 1); - float dx = l.rx2 - l.rx1; - float dy = l.ry2 - l.ry1; - const float len = juce_hypot (dx, dy); - - if (len <= amountAtEnd && subPath.size() > 1) - { - LineSection& prev = subPath.getReference (subPath.size() - 2); - prev.x2 = l.x2; - prev.y2 = l.y2; - subPath.removeLast(); - amountAtEnd -= len; - } - else - { - const float prop = jmin (0.9999f, amountAtEnd / len); - dx *= prop; - dy *= prop; - l.rx1 += dx; - l.ry1 += dy; - l.lx2 += dx; - l.ly2 += dy; - break; - } - } - - while (amountAtStart > 0 && subPath.size() > 0) - { - LineSection& l = subPath.getReference (0); - float dx = l.rx2 - l.rx1; - float dy = l.ry2 - l.ry1; - const float len = juce_hypot (dx, dy); - - if (len <= amountAtStart && subPath.size() > 1) - { - LineSection& next = subPath.getReference (1); - next.x1 = l.x1; - next.y1 = l.y1; - subPath.remove (0); - amountAtStart -= len; - } - else - { - const float prop = jmin (0.9999f, amountAtStart / len); - dx *= prop; - dy *= prop; - l.rx2 -= dx; - l.ry2 -= dy; - l.lx1 -= dx; - l.ly1 -= dy; - break; - } - } - } - - static void addSubPath (Path& destPath, Array& subPath, - const bool isClosed, const float width, const float maxMiterExtensionSquared, - const PathStrokeType::JointStyle jointStyle, const PathStrokeType::EndCapStyle endStyle, - const Arrowhead* const arrowhead) - { - jassert (subPath.size() > 0); - - if (arrowhead != nullptr) - shortenSubPath (subPath, arrowhead->startLength, arrowhead->endLength); - - const LineSection& firstLine = subPath.getReference (0); - - float lastX1 = firstLine.lx1; - float lastY1 = firstLine.ly1; - float lastX2 = firstLine.lx2; - float lastY2 = firstLine.ly2; - - if (isClosed) - { - destPath.startNewSubPath (lastX1, lastY1); - } - else - { - destPath.startNewSubPath (firstLine.rx2, firstLine.ry2); - - if (arrowhead != nullptr) - addArrowhead (destPath, firstLine.rx2, firstLine.ry2, lastX1, lastY1, firstLine.x1, firstLine.y1, - width, arrowhead->startWidth); - else - addLineEnd (destPath, endStyle, firstLine.rx2, firstLine.ry2, lastX1, lastY1, width); - } - - for (int i = 1; i < subPath.size(); ++i) - { - const LineSection& l = subPath.getReference (i); - - addEdgeAndJoint (destPath, jointStyle, - maxMiterExtensionSquared, width, - lastX1, lastY1, lastX2, lastY2, - l.lx1, l.ly1, l.lx2, l.ly2, - l.x1, l.y1); - - lastX1 = l.lx1; - lastY1 = l.ly1; - lastX2 = l.lx2; - lastY2 = l.ly2; - } - - const LineSection& lastLine = subPath.getReference (subPath.size() - 1); - - if (isClosed) - { - const LineSection& l = subPath.getReference (0); - - addEdgeAndJoint (destPath, jointStyle, - maxMiterExtensionSquared, width, - lastX1, lastY1, lastX2, lastY2, - l.lx1, l.ly1, l.lx2, l.ly2, - l.x1, l.y1); - - destPath.closeSubPath(); - destPath.startNewSubPath (lastLine.rx1, lastLine.ry1); - } - else - { - destPath.lineTo (lastX2, lastY2); - - if (arrowhead != nullptr) - addArrowhead (destPath, lastX2, lastY2, lastLine.rx1, lastLine.ry1, lastLine.x2, lastLine.y2, - width, arrowhead->endWidth); - else - addLineEnd (destPath, endStyle, lastX2, lastY2, lastLine.rx1, lastLine.ry1, width); - } - - lastX1 = lastLine.rx1; - lastY1 = lastLine.ry1; - lastX2 = lastLine.rx2; - lastY2 = lastLine.ry2; - - for (int i = subPath.size() - 1; --i >= 0;) - { - const LineSection& l = subPath.getReference (i); - - addEdgeAndJoint (destPath, jointStyle, - maxMiterExtensionSquared, width, - lastX1, lastY1, lastX2, lastY2, - l.rx1, l.ry1, l.rx2, l.ry2, - l.x2, l.y2); - - lastX1 = l.rx1; - lastY1 = l.ry1; - lastX2 = l.rx2; - lastY2 = l.ry2; - } - - if (isClosed) - { - addEdgeAndJoint (destPath, jointStyle, - maxMiterExtensionSquared, width, - lastX1, lastY1, lastX2, lastY2, - lastLine.rx1, lastLine.ry1, lastLine.rx2, lastLine.ry2, - lastLine.x2, lastLine.y2); - } - else - { - // do the last line - destPath.lineTo (lastX2, lastY2); - } - - destPath.closeSubPath(); - } - - static void createStroke (const float thickness, const PathStrokeType::JointStyle jointStyle, - const PathStrokeType::EndCapStyle endStyle, - Path& destPath, const Path& source, - const AffineTransform& transform, - const float extraAccuracy, const Arrowhead* const arrowhead) - { - jassert (extraAccuracy > 0); - - if (thickness <= 0) - { - destPath.clear(); - return; - } - - const Path* sourcePath = &source; - Path temp; - - if (sourcePath == &destPath) - { - destPath.swapWithPath (temp); - sourcePath = &temp; - } - else - { - destPath.clear(); - } - - destPath.setUsingNonZeroWinding (true); - - const float maxMiterExtensionSquared = 9.0f * thickness * thickness; - const float width = 0.5f * thickness; - - // Iterate the path, creating a list of the - // left/right-hand lines along either side of it... - PathFlatteningIterator it (*sourcePath, transform, PathFlatteningIterator::defaultTolerance / extraAccuracy); - - Array subPath; - subPath.ensureStorageAllocated (512); - LineSection l; - l.x1 = 0; - l.y1 = 0; - - const float minSegmentLength = 0.0001f; - - while (it.next()) - { - if (it.subPathIndex == 0) - { - if (subPath.size() > 0) - { - addSubPath (destPath, subPath, false, width, maxMiterExtensionSquared, jointStyle, endStyle, arrowhead); - subPath.clearQuick(); - } - - l.x1 = it.x1; - l.y1 = it.y1; - } - - l.x2 = it.x2; - l.y2 = it.y2; - - float dx = l.x2 - l.x1; - float dy = l.y2 - l.y1; - - const float hypotSquared = dx*dx + dy*dy; - - if (it.closesSubPath || hypotSquared > minSegmentLength || it.isLastInSubpath()) - { - const float len = std::sqrt (hypotSquared); - - if (len == 0) - { - l.rx1 = l.rx2 = l.lx1 = l.lx2 = l.x1; - l.ry1 = l.ry2 = l.ly1 = l.ly2 = l.y1; - } - else - { - const float offset = width / len; - dx *= offset; - dy *= offset; - - l.rx2 = l.x1 - dy; - l.ry2 = l.y1 + dx; - l.lx1 = l.x1 + dy; - l.ly1 = l.y1 - dx; - - l.lx2 = l.x2 + dy; - l.ly2 = l.y2 - dx; - l.rx1 = l.x2 - dy; - l.ry1 = l.y2 + dx; - } - - subPath.add (l); - - if (it.closesSubPath) - { - addSubPath (destPath, subPath, true, width, maxMiterExtensionSquared, jointStyle, endStyle, arrowhead); - subPath.clearQuick(); - } - else - { - l.x1 = it.x2; - l.y1 = it.y2; - } - } - } - - if (subPath.size() > 0) - addSubPath (destPath, subPath, false, width, maxMiterExtensionSquared, jointStyle, endStyle, arrowhead); - } -} - -void PathStrokeType::createStrokedPath (Path& destPath, const Path& sourcePath, - const AffineTransform& transform, const float extraAccuracy) const -{ - PathStrokeHelpers::createStroke (thickness, jointStyle, endStyle, destPath, sourcePath, - transform, extraAccuracy, 0); -} - -void PathStrokeType::createDashedStroke (Path& destPath, - const Path& sourcePath, - const float* dashLengths, - int numDashLengths, - const AffineTransform& transform, - const float extraAccuracy) const -{ - jassert (extraAccuracy > 0); - - if (thickness <= 0) - return; - - // this should really be an even number.. - jassert ((numDashLengths & 1) == 0); - - Path newDestPath; - PathFlatteningIterator it (sourcePath, transform, PathFlatteningIterator::defaultTolerance / extraAccuracy); - - bool first = true; - int dashNum = 0; - float pos = 0.0f, lineLen = 0.0f, lineEndPos = 0.0f; - float dx = 0.0f, dy = 0.0f; - - for (;;) - { - const bool isSolid = ((dashNum & 1) == 0); - const float dashLen = dashLengths [dashNum++ % numDashLengths]; - - jassert (dashLen > 0); // must be a positive increment! - if (dashLen <= 0) - break; - - pos += dashLen; - - while (pos > lineEndPos) - { - if (! it.next()) - { - if (isSolid && ! first) - newDestPath.lineTo (it.x2, it.y2); - - createStrokedPath (destPath, newDestPath, AffineTransform::identity, extraAccuracy); - return; - } - - if (isSolid && ! first) - newDestPath.lineTo (it.x1, it.y1); - else - newDestPath.startNewSubPath (it.x1, it.y1); - - dx = it.x2 - it.x1; - dy = it.y2 - it.y1; - lineLen = juce_hypot (dx, dy); - lineEndPos += lineLen; - first = it.closesSubPath; - } - - const float alpha = (pos - (lineEndPos - lineLen)) / lineLen; - - if (isSolid) - newDestPath.lineTo (it.x1 + dx * alpha, - it.y1 + dy * alpha); - else - newDestPath.startNewSubPath (it.x1 + dx * alpha, - it.y1 + dy * alpha); - } -} - -void PathStrokeType::createStrokeWithArrowheads (Path& destPath, - const Path& sourcePath, - const float arrowheadStartWidth, const float arrowheadStartLength, - const float arrowheadEndWidth, const float arrowheadEndLength, - const AffineTransform& transform, - const float extraAccuracy) const -{ - PathStrokeHelpers::Arrowhead head; - head.startWidth = arrowheadStartWidth; - head.startLength = arrowheadStartLength; - head.endWidth = arrowheadEndWidth; - head.endLength = arrowheadEndLength; - - PathStrokeHelpers::createStroke (thickness, jointStyle, endStyle, - destPath, sourcePath, transform, extraAccuracy, &head); -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/geometry/juce_PathStrokeType.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/geometry/juce_PathStrokeType.h deleted file mode 100644 index 63747419c2..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/geometry/juce_PathStrokeType.h +++ /dev/null @@ -1,204 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_PATHSTROKETYPE_H_INCLUDED -#define JUCE_PATHSTROKETYPE_H_INCLUDED - - -//============================================================================== -/** - Describes a type of stroke used to render a solid outline along a path. - - A PathStrokeType object can be used directly to create the shape of an outline - around a path, and is used by Graphics::strokePath to specify the type of - stroke to draw. - - @see Path, Graphics::strokePath -*/ -class JUCE_API PathStrokeType -{ -public: - //============================================================================== - /** The type of shape to use for the corners between two adjacent line segments. */ - enum JointStyle - { - mitered, /**< Indicates that corners should be drawn with sharp joints. - Note that for angles that curve back on themselves, drawing a - mitre could require extending the point too far away from the - path, so a mitre limit is imposed and any corners that exceed it - are drawn as bevelled instead. */ - curved, /**< Indicates that corners should be drawn as rounded-off. */ - beveled /**< Indicates that corners should be drawn with a line flattening their - outside edge. */ - }; - - /** The type shape to use for the ends of lines. */ - enum EndCapStyle - { - butt, /**< Ends of lines are flat and don't extend beyond the end point. */ - square, /**< Ends of lines are flat, but stick out beyond the end point for half - the thickness of the stroke. */ - rounded /**< Ends of lines are rounded-off with a circular shape. */ - }; - - //============================================================================== - /** Creates a stroke type with a given line-width, and default joint/end styles. */ - explicit PathStrokeType (float strokeThickness) noexcept; - - /** Creates a stroke type. - - @param strokeThickness the width of the line to use - @param jointStyle the type of joints to use for corners - @param endStyle the type of end-caps to use for the ends of open paths. - */ - PathStrokeType (float strokeThickness, - JointStyle jointStyle, - EndCapStyle endStyle = butt) noexcept; - - /** Creates a copy of another stroke type. */ - PathStrokeType (const PathStrokeType&) noexcept; - - /** Copies another stroke onto this one. */ - PathStrokeType& operator= (const PathStrokeType&) noexcept; - - /** Destructor. */ - ~PathStrokeType() noexcept; - - //============================================================================== - /** Applies this stroke type to a path and returns the resultant stroke as another Path. - - @param destPath the resultant stroked outline shape will be copied into this path. - Note that it's ok for the source and destination Paths to be - the same object, so you can easily turn a path into a stroked version - of itself. - @param sourcePath the path to use as the source - @param transform an optional transform to apply to the points from the source path - as they are being used - @param extraAccuracy if this is greater than 1.0, it will subdivide the path to - a higher resolution, which improves the quality if you'll later want - to enlarge the stroked path. So for example, if you're planning on drawing - the stroke at 3x the size that you're creating it, you should set this to 3. - - @see createDashedStroke - */ - void createStrokedPath (Path& destPath, - const Path& sourcePath, - const AffineTransform& transform = AffineTransform::identity, - float extraAccuracy = 1.0f) const; - - - //============================================================================== - /** Applies this stroke type to a path, creating a dashed line. - - This is similar to createStrokedPath, but uses the array passed in to - break the stroke up into a series of dashes. - - @param destPath the resultant stroked outline shape will be copied into this path. - Note that it's ok for the source and destination Paths to be - the same object, so you can easily turn a path into a stroked version - of itself. - @param sourcePath the path to use as the source - @param dashLengths An array of alternating on/off lengths. E.g. { 2, 3, 4, 5 } will create - a line of length 2, then skip a length of 3, then add a line of length 4, - skip 5, and keep repeating this pattern. - @param numDashLengths The number of lengths in the dashLengths array. This should really be - an even number, otherwise the pattern will get out of step as it - repeats. - @param transform an optional transform to apply to the points from the source path - as they are being used - @param extraAccuracy if this is greater than 1.0, it will subdivide the path to - a higher resolution, which improves the quality if you'll later want - to enlarge the stroked path. So for example, if you're planning on drawing - the stroke at 3x the size that you're creating it, you should set this to 3. - */ - void createDashedStroke (Path& destPath, - const Path& sourcePath, - const float* dashLengths, - int numDashLengths, - const AffineTransform& transform = AffineTransform::identity, - float extraAccuracy = 1.0f) const; - - //============================================================================== - /** Applies this stroke type to a path and returns the resultant stroke as another Path. - - @param destPath the resultant stroked outline shape will be copied into this path. - Note that it's ok for the source and destination Paths to be - the same object, so you can easily turn a path into a stroked version - of itself. - @param sourcePath the path to use as the source - @param arrowheadStartWidth the width of the arrowhead at the start of the path - @param arrowheadStartLength the length of the arrowhead at the start of the path - @param arrowheadEndWidth the width of the arrowhead at the end of the path - @param arrowheadEndLength the length of the arrowhead at the end of the path - @param transform an optional transform to apply to the points from the source path - as they are being used - @param extraAccuracy if this is greater than 1.0, it will subdivide the path to - a higher resolution, which improves the quality if you'll later want - to enlarge the stroked path. So for example, if you're planning on drawing - the stroke at 3x the size that you're creating it, you should set this to 3. - @see createDashedStroke - */ - void createStrokeWithArrowheads (Path& destPath, - const Path& sourcePath, - float arrowheadStartWidth, float arrowheadStartLength, - float arrowheadEndWidth, float arrowheadEndLength, - const AffineTransform& transform = AffineTransform::identity, - float extraAccuracy = 1.0f) const; - - //============================================================================== - /** Returns the stroke thickness. */ - float getStrokeThickness() const noexcept { return thickness; } - - /** Sets the stroke thickness. */ - void setStrokeThickness (float newThickness) noexcept { thickness = newThickness; } - - /** Returns the joint style. */ - JointStyle getJointStyle() const noexcept { return jointStyle; } - - /** Sets the joint style. */ - void setJointStyle (JointStyle newStyle) noexcept { jointStyle = newStyle; } - - /** Returns the end-cap style. */ - EndCapStyle getEndStyle() const noexcept { return endStyle; } - - /** Sets the end-cap style. */ - void setEndStyle (EndCapStyle newStyle) noexcept { endStyle = newStyle; } - - //============================================================================== - /** Compares the stroke thickness, joint and end styles of two stroke types. */ - bool operator== (const PathStrokeType&) const noexcept; - - /** Compares the stroke thickness, joint and end styles of two stroke types. */ - bool operator!= (const PathStrokeType&) const noexcept; - -private: - //============================================================================== - float thickness; - JointStyle jointStyle; - EndCapStyle endStyle; - - JUCE_LEAK_DETECTOR (PathStrokeType) -}; - -#endif // JUCE_PATHSTROKETYPE_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/geometry/juce_Point.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/geometry/juce_Point.h deleted file mode 100644 index 7cc5d4990c..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/geometry/juce_Point.h +++ /dev/null @@ -1,228 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_POINT_H_INCLUDED -#define JUCE_POINT_H_INCLUDED - - -//============================================================================== -/** - A pair of (x, y) coordinates. - - The ValueType template should be a primitive type such as int, float, double, - rather than a class. - - @see Line, Path, AffineTransform -*/ -template -class Point -{ -public: - /** Creates a point at the origin */ - Point() noexcept : x(), y() {} - - /** Creates a copy of another point. */ - Point (const Point& other) noexcept : x (other.x), y (other.y) {} - - /** Creates a point from an (x, y) position. */ - Point (ValueType initialX, ValueType initialY) noexcept : x (initialX), y (initialY) {} - - //============================================================================== - /** Copies this point from another one. */ - Point& operator= (const Point& other) noexcept { x = other.x; y = other.y; return *this; } - - inline bool operator== (Point other) const noexcept { return x == other.x && y == other.y; } - inline bool operator!= (Point other) const noexcept { return x != other.x || y != other.y; } - - /** Returns true if the point is (0, 0). */ - bool isOrigin() const noexcept { return x == ValueType() && y == ValueType(); } - - /** Returns the point's x coordinate. */ - inline ValueType getX() const noexcept { return x; } - - /** Returns the point's y coordinate. */ - inline ValueType getY() const noexcept { return y; } - - /** Sets the point's x coordinate. */ - inline void setX (ValueType newX) noexcept { x = newX; } - - /** Sets the point's y coordinate. */ - inline void setY (ValueType newY) noexcept { y = newY; } - - /** Returns a point which has the same Y position as this one, but a new X. */ - Point withX (ValueType newX) const noexcept { return Point (newX, y); } - - /** Returns a point which has the same X position as this one, but a new Y. */ - Point withY (ValueType newY) const noexcept { return Point (x, newY); } - - /** Changes the point's x and y coordinates. */ - void setXY (ValueType newX, ValueType newY) noexcept { x = newX; y = newY; } - - /** Adds a pair of coordinates to this value. */ - void addXY (ValueType xToAdd, ValueType yToAdd) noexcept { x += xToAdd; y += yToAdd; } - - //============================================================================== - /** Returns a point with a given offset from this one. */ - Point translated (ValueType deltaX, ValueType deltaY) const noexcept { return Point (x + deltaX, y + deltaY); } - - /** Adds two points together */ - Point operator+ (Point other) const noexcept { return Point (x + other.x, y + other.y); } - - /** Adds another point's coordinates to this one */ - Point& operator+= (Point other) noexcept { x += other.x; y += other.y; return *this; } - - /** Subtracts one points from another */ - Point operator- (Point other) const noexcept { return Point (x - other.x, y - other.y); } - - /** Subtracts another point's coordinates to this one */ - Point& operator-= (Point other) noexcept { x -= other.x; y -= other.y; return *this; } - - /** Multiplies two points together */ - template - Point operator* (Point other) const noexcept { return Point ((ValueType) (x * other.x), (ValueType) (y * other.y)); } - - /** Multiplies another point's coordinates to this one */ - template - Point& operator*= (Point other) noexcept { *this = *this * other; return *this; } - - /** Divides one point by another */ - template - Point operator/ (Point other) const noexcept { return Point ((ValueType) (x / other.x), (ValueType) (y / other.y)); } - - /** Divides this point's coordinates by another */ - template - Point& operator/= (Point other) noexcept { *this = *this / other; return *this; } - - /** Returns a point whose coordinates are multiplied by a given scalar value. */ - template - Point operator* (FloatType multiplier) const noexcept { return Point ((ValueType) (x * multiplier), (ValueType) (y * multiplier)); } - - /** Returns a point whose coordinates are divided by a given scalar value. */ - template - Point operator/ (FloatType divisor) const noexcept { return Point ((ValueType) (x / divisor), (ValueType) (y / divisor)); } - - /** Multiplies the point's coordinates by a scalar value. */ - template - Point& operator*= (FloatType multiplier) noexcept { x = (ValueType) (x * multiplier); y = (ValueType) (y * multiplier); return *this; } - - /** Divides the point's coordinates by a scalar value. */ - template - Point& operator/= (FloatType divisor) noexcept { x = (ValueType) (x / divisor); y = (ValueType) (y / divisor); return *this; } - - /** Returns the inverse of this point. */ - Point operator-() const noexcept { return Point (-x, -y); } - - //============================================================================== - /** This type will be double if the Point's type is double, otherwise it will be float. */ - typedef typename TypeHelpers::SmallestFloatType::type FloatType; - - //============================================================================== - /** Returns the straight-line distance between this point and the origin. */ - ValueType getDistanceFromOrigin() const noexcept { return juce_hypot (x, y); } - - /** Returns the straight-line distance between this point and another one. */ - ValueType getDistanceFrom (Point other) const noexcept { return juce_hypot (x - other.x, y - other.y); } - - /** Returns the angle from this point to another one. - - The return value is the number of radians clockwise from the 12 o'clock direction, - where this point is the centre and the other point is on the circumference. - */ - FloatType getAngleToPoint (Point other) const noexcept - { - return static_cast (std::atan2 (static_cast (other.x - x), - static_cast (y - other.y))); - } - - /** Returns the point that would be reached by rotating this point clockwise - about the origin by the specified angle. - */ - Point rotatedAboutOrigin (ValueType angleRadians) const noexcept - { - return Point (x * std::cos (angleRadians) - y * std::sin (angleRadians), - x * std::sin (angleRadians) + y * std::cos (angleRadians)); - } - - /** Taking this point to be the centre of a circle, this returns a point on its circumference. - @param radius the radius of the circle. - @param angle the angle of the point, in radians clockwise from the 12 o'clock position. - */ - Point getPointOnCircumference (float radius, float angle) const noexcept - { - return Point (static_cast (x + radius * std::sin (angle)), - static_cast (y - radius * std::cos (angle))); - } - - /** Taking this point to be the centre of an ellipse, this returns a point on its circumference. - @param radiusX the horizontal radius of the circle. - @param radiusY the vertical radius of the circle. - @param angle the angle of the point, in radians clockwise from the 12 o'clock position. - */ - Point getPointOnCircumference (float radiusX, float radiusY, float angle) const noexcept - { - return Point (static_cast (x + radiusX * std::sin (angle)), - static_cast (y - radiusY * std::cos (angle))); - } - - /** Returns the dot-product of two points (x1 * x2 + y1 * y2). */ - FloatType getDotProduct (Point other) const noexcept { return x * other.x + y * other.y; } - - //============================================================================== - /** Uses a transform to change the point's coordinates. - This will only compile if ValueType = float! - - @see AffineTransform::transformPoint - */ - void applyTransform (const AffineTransform& transform) noexcept { transform.transformPoint (x, y); } - - /** Returns the position of this point, if it is transformed by a given AffineTransform. */ - Point transformedBy (const AffineTransform& transform) const noexcept - { - return Point (static_cast (transform.mat00 * x + transform.mat01 * y + transform.mat02), - static_cast (transform.mat10 * x + transform.mat11 * y + transform.mat12)); - } - - //============================================================================== - /** Casts this point to a Point object. */ - Point toInt() const noexcept { return Point (static_cast (x), static_cast (y)); } - - /** Casts this point to a Point object. */ - Point toFloat() const noexcept { return Point (static_cast (x), static_cast (y)); } - - /** Casts this point to a Point object. */ - Point toDouble() const noexcept { return Point (static_cast (x), static_cast (y)); } - - /** Casts this point to a Point object using roundToInt() to convert the values. */ - Point roundToInt() const noexcept { return Point (juce::roundToInt (x), juce::roundToInt (y)); } - - /** Returns the point as a string in the form "x, y". */ - String toString() const { return String (x) + ", " + String (y); } - - //============================================================================== - ValueType x; /**< The point's X coordinate. */ - ValueType y; /**< The point's Y coordinate. */ -}; - - -#endif // JUCE_POINT_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/geometry/juce_Rectangle.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/geometry/juce_Rectangle.h deleted file mode 100644 index 6191d1aa7f..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/geometry/juce_Rectangle.h +++ /dev/null @@ -1,917 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_RECTANGLE_H_INCLUDED -#define JUCE_RECTANGLE_H_INCLUDED - - -//============================================================================== -/** - Manages a rectangle and allows geometric operations to be performed on it. - - @see RectangleList, Path, Line, Point -*/ -template -class Rectangle -{ -public: - //============================================================================== - /** Creates a rectangle of zero size. - The default coordinates will be (0, 0, 0, 0). - */ - Rectangle() noexcept - : w(), h() - { - } - - /** Creates a copy of another rectangle. */ - Rectangle (const Rectangle& other) noexcept - : pos (other.pos), w (other.w), h (other.h) - { - } - - /** Creates a rectangle with a given position and size. */ - Rectangle (const ValueType initialX, const ValueType initialY, - const ValueType width, const ValueType height) noexcept - : pos (initialX, initialY), - w (width), h (height) - { - } - - /** Creates a rectangle with a given size, and a position of (0, 0). */ - Rectangle (const ValueType width, const ValueType height) noexcept - : w (width), h (height) - { - } - - /** Creates a Rectangle from the positions of two opposite corners. */ - Rectangle (const Point corner1, const Point corner2) noexcept - : pos (jmin (corner1.x, corner2.x), - jmin (corner1.y, corner2.y)), - w (corner1.x - corner2.x), - h (corner1.y - corner2.y) - { - if (w < ValueType()) w = -w; - if (h < ValueType()) h = -h; - } - - /** Creates a Rectangle from a set of left, right, top, bottom coordinates. - The right and bottom values must be larger than the left and top ones, or the resulting - rectangle will have a negative size. - */ - static Rectangle leftTopRightBottom (const ValueType left, const ValueType top, - const ValueType right, const ValueType bottom) noexcept - { - return Rectangle (left, top, right - left, bottom - top); - } - - Rectangle& operator= (const Rectangle& other) noexcept - { - pos = other.pos; - w = other.w; h = other.h; - return *this; - } - - /** Destructor. */ - ~Rectangle() noexcept {} - - //============================================================================== - /** Returns true if the rectangle's width or height are zero or less */ - bool isEmpty() const noexcept { return w <= ValueType() || h <= ValueType(); } - - /** Returns the x coordinate of the rectangle's left-hand-side. */ - inline ValueType getX() const noexcept { return pos.x; } - - /** Returns the y coordinate of the rectangle's top edge. */ - inline ValueType getY() const noexcept { return pos.y; } - - /** Returns the width of the rectangle. */ - inline ValueType getWidth() const noexcept { return w; } - - /** Returns the height of the rectangle. */ - inline ValueType getHeight() const noexcept { return h; } - - /** Returns the x coordinate of the rectangle's right-hand-side. */ - inline ValueType getRight() const noexcept { return pos.x + w; } - - /** Returns the y coordinate of the rectangle's bottom edge. */ - inline ValueType getBottom() const noexcept { return pos.y + h; } - - /** Returns the x coordinate of the rectangle's centre. */ - ValueType getCentreX() const noexcept { return pos.x + w / (ValueType) 2; } - - /** Returns the y coordinate of the rectangle's centre. */ - ValueType getCentreY() const noexcept { return pos.y + h / (ValueType) 2; } - - /** Returns the centre point of the rectangle. */ - Point getCentre() const noexcept { return Point (pos.x + w / (ValueType) 2, - pos.y + h / (ValueType) 2); } - - /** Returns the aspect ratio of the rectangle's width / height. - If widthOverHeight is true, it returns width / height; if widthOverHeight is false, - it returns height / width. */ - ValueType getAspectRatio (const bool widthOverHeight = true) const noexcept { return widthOverHeight ? w / h : h / w; } - - //============================================================================== - /** Returns the rectangle's top-left position as a Point. */ - inline Point getPosition() const noexcept { return pos; } - - /** Changes the position of the rectangle's top-left corner (leaving its size unchanged). */ - inline void setPosition (const Point newPos) noexcept { pos = newPos; } - - /** Changes the position of the rectangle's top-left corner (leaving its size unchanged). */ - inline void setPosition (const ValueType newX, const ValueType newY) noexcept { pos.setXY (newX, newY); } - - /** Returns the rectangle's top-left position as a Point. */ - Point getTopLeft() const noexcept { return pos; } - - /** Returns the rectangle's top-right position as a Point. */ - Point getTopRight() const noexcept { return Point (pos.x + w, pos.y); } - - /** Returns the rectangle's bottom-left position as a Point. */ - Point getBottomLeft() const noexcept { return Point (pos.x, pos.y + h); } - - /** Returns the rectangle's bottom-right position as a Point. */ - Point getBottomRight() const noexcept { return Point (pos.x + w, pos.y + h); } - - /** Changes the rectangle's size, leaving the position of its top-left corner unchanged. */ - void setSize (const ValueType newWidth, const ValueType newHeight) noexcept { w = newWidth; h = newHeight; } - - /** Changes all the rectangle's coordinates. */ - void setBounds (const ValueType newX, const ValueType newY, - const ValueType newWidth, const ValueType newHeight) noexcept { pos.x = newX; pos.y = newY; w = newWidth; h = newHeight; } - - /** Changes the rectangle's X coordinate */ - inline void setX (const ValueType newX) noexcept { pos.x = newX; } - - /** Changes the rectangle's Y coordinate */ - inline void setY (const ValueType newY) noexcept { pos.y = newY; } - - /** Changes the rectangle's width */ - inline void setWidth (const ValueType newWidth) noexcept { w = newWidth; } - - /** Changes the rectangle's height */ - inline void setHeight (const ValueType newHeight) noexcept { h = newHeight; } - - /** Changes the position of the rectangle's centre (leaving its size unchanged). */ - inline void setCentre (const ValueType newCentreX, const ValueType newCentreY) noexcept { pos.x = newCentreX - w / (ValueType) 2; pos.y = newCentreY - h / (ValueType) 2; } - - /** Changes the position of the rectangle's centre (leaving its size unchanged). */ - inline void setCentre (const Point newCentre) noexcept { setCentre (newCentre.x, newCentre.y); } - - /** Returns a rectangle which has the same size and y-position as this one, but with a different x-position. */ - Rectangle withX (const ValueType newX) const noexcept { return Rectangle (newX, pos.y, w, h); } - - /** Returns a rectangle which has the same size and x-position as this one, but with a different y-position. */ - Rectangle withY (const ValueType newY) const noexcept { return Rectangle (pos.x, newY, w, h); } - - /** Returns a rectangle with the same size as this one, but a new position. */ - Rectangle withPosition (const ValueType newX, const ValueType newY) const noexcept { return Rectangle (newX, newY, w, h); } - - /** Returns a rectangle with the same size as this one, but a new position. */ - Rectangle withPosition (const Point newPos) const noexcept { return Rectangle (newPos.x, newPos.y, w, h); } - - /** Returns a rectangle whose size is the same as this one, but whose top-left position is (0, 0). */ - Rectangle withZeroOrigin() const noexcept { return Rectangle (w, h); } - - /** Returns a rectangle with the same size as this one, but a new centre position. */ - Rectangle withCentre (const Point newCentre) const noexcept { return Rectangle (newCentre.x - w / (ValueType) 2, - newCentre.y - h / (ValueType) 2, w, h); } - - /** Returns a rectangle which has the same position and height as this one, but with a different width. */ - Rectangle withWidth (ValueType newWidth) const noexcept { return Rectangle (pos.x, pos.y, newWidth, h); } - - /** Returns a rectangle which has the same position and width as this one, but with a different height. */ - Rectangle withHeight (ValueType newHeight) const noexcept { return Rectangle (pos.x, pos.y, w, newHeight); } - - /** Returns a rectangle with the same top-left position as this one, but a new size. */ - Rectangle withSize (ValueType newWidth, ValueType newHeight) const noexcept { return Rectangle (pos.x, pos.y, newWidth, newHeight); } - - /** Returns a rectangle with the same centre position as this one, but a new size. */ - Rectangle withSizeKeepingCentre (ValueType newWidth, ValueType newHeight) const noexcept { return Rectangle (pos.x + (w - newWidth) / (ValueType) 2, - pos.y + (h - newHeight) / (ValueType) 2, newWidth, newHeight); } - - /** Moves the x position, adjusting the width so that the right-hand edge remains in the same place. - If the x is moved to be on the right of the current right-hand edge, the width will be set to zero. - @see withLeft - */ - void setLeft (ValueType newLeft) noexcept { w = jmax (ValueType(), pos.x + w - newLeft); pos.x = newLeft; } - - /** Returns a new rectangle with a different x position, but the same right-hand edge as this one. - If the new x is beyond the right of the current right-hand edge, the width will be set to zero. - @see setLeft - */ - Rectangle withLeft (ValueType newLeft) const noexcept { return Rectangle (newLeft, pos.y, jmax (ValueType(), pos.x + w - newLeft), h); } - - /** Moves the y position, adjusting the height so that the bottom edge remains in the same place. - If the y is moved to be below the current bottom edge, the height will be set to zero. - @see withTop - */ - void setTop (ValueType newTop) noexcept { h = jmax (ValueType(), pos.y + h - newTop); pos.y = newTop; } - - /** Returns a new rectangle with a different y position, but the same bottom edge as this one. - If the new y is beyond the bottom of the current rectangle, the height will be set to zero. - @see setTop - */ - Rectangle withTop (ValueType newTop) const noexcept { return Rectangle (pos.x, newTop, w, jmax (ValueType(), pos.y + h - newTop)); } - - /** Adjusts the width so that the right-hand edge of the rectangle has this new value. - If the new right is below the current X value, the X will be pushed down to match it. - @see getRight, withRight - */ - void setRight (ValueType newRight) noexcept { pos.x = jmin (pos.x, newRight); w = newRight - pos.x; } - - /** Returns a new rectangle with a different right-hand edge position, but the same left-hand edge as this one. - If the new right edge is below the current left-hand edge, the width will be set to zero. - @see setRight - */ - Rectangle withRight (ValueType newRight) const noexcept { return Rectangle (jmin (pos.x, newRight), pos.y, jmax (ValueType(), newRight - pos.x), h); } - - /** Adjusts the height so that the bottom edge of the rectangle has this new value. - If the new bottom is lower than the current Y value, the Y will be pushed down to match it. - @see getBottom, withBottom - */ - void setBottom (ValueType newBottom) noexcept { pos.y = jmin (pos.y, newBottom); h = newBottom - pos.y; } - - /** Returns a new rectangle with a different bottom edge position, but the same top edge as this one. - If the new y is beyond the bottom of the current rectangle, the height will be set to zero. - @see setBottom - */ - Rectangle withBottom (ValueType newBottom) const noexcept { return Rectangle (pos.x, jmin (pos.y, newBottom), w, jmax (ValueType(), newBottom - pos.y)); } - - /** Returns a version of this rectangle with the given amount removed from its left-hand edge. */ - Rectangle withTrimmedLeft (ValueType amountToRemove) const noexcept { return withLeft (pos.x + amountToRemove); } - - /** Returns a version of this rectangle with the given amount removed from its right-hand edge. */ - Rectangle withTrimmedRight (ValueType amountToRemove) const noexcept { return withWidth (w - amountToRemove); } - - /** Returns a version of this rectangle with the given amount removed from its top edge. */ - Rectangle withTrimmedTop (ValueType amountToRemove) const noexcept { return withTop (pos.y + amountToRemove); } - - /** Returns a version of this rectangle with the given amount removed from its bottom edge. */ - Rectangle withTrimmedBottom (ValueType amountToRemove) const noexcept { return withHeight (h - amountToRemove); } - - //============================================================================== - /** Moves the rectangle's position by adding amount to its x and y coordinates. */ - void translate (const ValueType deltaX, - const ValueType deltaY) noexcept - { - pos.x += deltaX; - pos.y += deltaY; - } - - /** Returns a rectangle which is the same as this one moved by a given amount. */ - Rectangle translated (const ValueType deltaX, - const ValueType deltaY) const noexcept - { - return Rectangle (pos.x + deltaX, pos.y + deltaY, w, h); - } - - /** Returns a rectangle which is the same as this one moved by a given amount. */ - Rectangle operator+ (const Point deltaPosition) const noexcept - { - return Rectangle (pos.x + deltaPosition.x, pos.y + deltaPosition.y, w, h); - } - - /** Moves this rectangle by a given amount. */ - Rectangle& operator+= (const Point deltaPosition) noexcept - { - pos += deltaPosition; - return *this; - } - - /** Returns a rectangle which is the same as this one moved by a given amount. */ - Rectangle operator- (const Point deltaPosition) const noexcept - { - return Rectangle (pos.x - deltaPosition.x, pos.y - deltaPosition.y, w, h); - } - - /** Moves this rectangle by a given amount. */ - Rectangle& operator-= (const Point deltaPosition) noexcept - { - pos -= deltaPosition; - return *this; - } - - /** Returns a rectangle that has been scaled by the given amount, centred around the origin. - Note that if the rectangle has int coordinates and it's scaled by a - floating-point amount, then the result will be converted back to integer - coordinates using getSmallestIntegerContainer(). - */ - template - Rectangle operator* (FloatType scaleFactor) const noexcept - { - Rectangle r (*this); - r *= scaleFactor; - return r; - } - - /** Scales this rectangle by the given amount, centred around the origin. - Note that if the rectangle has int coordinates and it's scaled by a - floating-point amount, then the result will be converted back to integer - coordinates using getSmallestIntegerContainer(). - */ - template - Rectangle operator*= (FloatType scaleFactor) noexcept - { - Rectangle (pos.x * scaleFactor, - pos.y * scaleFactor, - w * scaleFactor, - h * scaleFactor).copyWithRounding (*this); - return *this; - } - - /** Scales this rectangle by the given X and Y factors, centred around the origin. - Note that if the rectangle has int coordinates and it's scaled by a - floating-point amount, then the result will be converted back to integer - coordinates using getSmallestIntegerContainer(). - */ - template - Rectangle operator*= (Point scaleFactor) noexcept - { - Rectangle (pos.x * scaleFactor.x, - pos.y * scaleFactor.y, - w * scaleFactor.x, - h * scaleFactor.y).copyWithRounding (*this); - return *this; - } - - /** Scales this rectangle by the given amount, centred around the origin. */ - template - Rectangle operator/ (FloatType scaleFactor) const noexcept - { - Rectangle r (*this); - r /= scaleFactor; - return r; - } - - /** Scales this rectangle by the given amount, centred around the origin. */ - template - Rectangle operator/= (FloatType scaleFactor) noexcept - { - Rectangle (pos.x / scaleFactor, - pos.y / scaleFactor, - w / scaleFactor, - h / scaleFactor).copyWithRounding (*this); - return *this; - } - - /** Scales this rectangle by the given X and Y factors, centred around the origin. */ - template - Rectangle operator/= (Point scaleFactor) noexcept - { - Rectangle (pos.x / scaleFactor.x, - pos.y / scaleFactor.y, - w / scaleFactor.x, - h / scaleFactor.y).copyWithRounding (*this); - return *this; - } - - /** Expands the rectangle by a given amount. - - Effectively, its new size is (x - deltaX, y - deltaY, w + deltaX * 2, h + deltaY * 2). - @see expanded, reduce, reduced - */ - void expand (const ValueType deltaX, - const ValueType deltaY) noexcept - { - const ValueType nw = jmax (ValueType(), w + deltaX * 2); - const ValueType nh = jmax (ValueType(), h + deltaY * 2); - setBounds (pos.x - deltaX, pos.y - deltaY, nw, nh); - } - - /** Returns a rectangle that is larger than this one by a given amount. - - Effectively, the rectangle returned is (x - deltaX, y - deltaY, w + deltaX * 2, h + deltaY * 2). - @see expand, reduce, reduced - */ - Rectangle expanded (const ValueType deltaX, - const ValueType deltaY) const noexcept - { - const ValueType nw = jmax (ValueType(), w + deltaX * 2); - const ValueType nh = jmax (ValueType(), h + deltaY * 2); - return Rectangle (pos.x - deltaX, pos.y - deltaY, nw, nh); - } - - /** Returns a rectangle that is larger than this one by a given amount. - - Effectively, the rectangle returned is (x - delta, y - delta, w + delta * 2, h + delta * 2). - @see expand, reduce, reduced - */ - Rectangle expanded (const ValueType delta) const noexcept - { - return expanded (delta, delta); - } - - /** Shrinks the rectangle by a given amount. - - Effectively, its new size is (x + deltaX, y + deltaY, w - deltaX * 2, h - deltaY * 2). - @see reduced, expand, expanded - */ - void reduce (const ValueType deltaX, - const ValueType deltaY) noexcept - { - expand (-deltaX, -deltaY); - } - - /** Returns a rectangle that is smaller than this one by a given amount. - - Effectively, the rectangle returned is (x + deltaX, y + deltaY, w - deltaX * 2, h - deltaY * 2). - @see reduce, expand, expanded - */ - Rectangle reduced (const ValueType deltaX, - const ValueType deltaY) const noexcept - { - return expanded (-deltaX, -deltaY); - } - - /** Returns a rectangle that is smaller than this one by a given amount. - - Effectively, the rectangle returned is (x + delta, y + delta, w - delta * 2, h - delta * 2). - @see reduce, expand, expanded - */ - Rectangle reduced (const ValueType delta) const noexcept - { - return reduced (delta, delta); - } - - /** Removes a strip from the top of this rectangle, reducing this rectangle - by the specified amount and returning the section that was removed. - - E.g. if this rectangle is (100, 100, 300, 300) and amountToRemove is 50, this will - return (100, 100, 300, 50) and leave this rectangle as (100, 150, 300, 250). - - If amountToRemove is greater than the height of this rectangle, it'll be clipped to - that value. - */ - Rectangle removeFromTop (const ValueType amountToRemove) noexcept - { - const Rectangle r (pos.x, pos.y, w, jmin (amountToRemove, h)); - pos.y += r.h; h -= r.h; - return r; - } - - /** Removes a strip from the left-hand edge of this rectangle, reducing this rectangle - by the specified amount and returning the section that was removed. - - E.g. if this rectangle is (100, 100, 300, 300) and amountToRemove is 50, this will - return (100, 100, 50, 300) and leave this rectangle as (150, 100, 250, 300). - - If amountToRemove is greater than the width of this rectangle, it'll be clipped to - that value. - */ - Rectangle removeFromLeft (const ValueType amountToRemove) noexcept - { - const Rectangle r (pos.x, pos.y, jmin (amountToRemove, w), h); - pos.x += r.w; w -= r.w; - return r; - } - - /** Removes a strip from the right-hand edge of this rectangle, reducing this rectangle - by the specified amount and returning the section that was removed. - - E.g. if this rectangle is (100, 100, 300, 300) and amountToRemove is 50, this will - return (250, 100, 50, 300) and leave this rectangle as (100, 100, 250, 300). - - If amountToRemove is greater than the width of this rectangle, it'll be clipped to - that value. - */ - Rectangle removeFromRight (ValueType amountToRemove) noexcept - { - amountToRemove = jmin (amountToRemove, w); - const Rectangle r (pos.x + w - amountToRemove, pos.y, amountToRemove, h); - w -= amountToRemove; - return r; - } - - /** Removes a strip from the bottom of this rectangle, reducing this rectangle - by the specified amount and returning the section that was removed. - - E.g. if this rectangle is (100, 100, 300, 300) and amountToRemove is 50, this will - return (100, 250, 300, 50) and leave this rectangle as (100, 100, 300, 250). - - If amountToRemove is greater than the height of this rectangle, it'll be clipped to - that value. - */ - Rectangle removeFromBottom (ValueType amountToRemove) noexcept - { - amountToRemove = jmin (amountToRemove, h); - const Rectangle r (pos.x, pos.y + h - amountToRemove, w, amountToRemove); - h -= amountToRemove; - return r; - } - - //============================================================================== - /** Returns true if the two rectangles are identical. */ - bool operator== (const Rectangle& other) const noexcept { return pos == other.pos && w == other.w && h == other.h; } - - /** Returns true if the two rectangles are not identical. */ - bool operator!= (const Rectangle& other) const noexcept { return pos != other.pos || w != other.w || h != other.h; } - - /** Returns true if this coordinate is inside the rectangle. */ - bool contains (const ValueType xCoord, const ValueType yCoord) const noexcept - { - return xCoord >= pos.x && yCoord >= pos.y && xCoord < pos.x + w && yCoord < pos.y + h; - } - - /** Returns true if this coordinate is inside the rectangle. */ - bool contains (const Point point) const noexcept - { - return point.x >= pos.x && point.y >= pos.y && point.x < pos.x + w && point.y < pos.y + h; - } - - /** Returns true if this other rectangle is completely inside this one. */ - bool contains (const Rectangle& other) const noexcept - { - return pos.x <= other.pos.x && pos.y <= other.pos.y - && pos.x + w >= other.pos.x + other.w && pos.y + h >= other.pos.y + other.h; - } - - /** Returns the nearest point to the specified point that lies within this rectangle. */ - Point getConstrainedPoint (const Point point) const noexcept - { - return Point (jlimit (pos.x, pos.x + w, point.x), - jlimit (pos.y, pos.y + h, point.y)); - } - - /** Returns a point within this rectangle, specified as proportional coordinates. - The relative X and Y values should be between 0 and 1, where 0 is the left or - top of this rectangle, and 1 is the right or bottom. (Out-of-bounds values - will return a point outside the rectangle). - */ - Point getRelativePoint (double relativeX, double relativeY) const noexcept - { - return Point (pos.x + static_cast (w * relativeX), - pos.y + static_cast (h * relativeY)); - } - - /** Returns true if any part of another rectangle overlaps this one. */ - bool intersects (const Rectangle& other) const noexcept - { - return pos.x + w > other.pos.x - && pos.y + h > other.pos.y - && pos.x < other.pos.x + other.w - && pos.y < other.pos.y + other.h - && w > ValueType() && h > ValueType() - && other.w > ValueType() && other.h > ValueType(); - } - - /** Returns true if any part of the given line lies inside this rectangle. */ - bool intersects (const Line& line) const noexcept - { - return contains (line.getStart()) || contains (line.getEnd()) - || line.intersects (Line (getTopLeft(), getTopRight())) - || line.intersects (Line (getTopRight(), getBottomRight())) - || line.intersects (Line (getBottomRight(), getBottomLeft())) - || line.intersects (Line (getBottomLeft(), getTopLeft())); - } - - /** Returns the region that is the overlap between this and another rectangle. - If the two rectangles don't overlap, the rectangle returned will be empty. - */ - Rectangle getIntersection (const Rectangle& other) const noexcept - { - const ValueType nx = jmax (pos.x, other.pos.x); - const ValueType ny = jmax (pos.y, other.pos.y); - const ValueType nw = jmin (pos.x + w, other.pos.x + other.w) - nx; - const ValueType nh = jmin (pos.y + h, other.pos.y + other.h) - ny; - - if (nw >= ValueType() && nh >= ValueType()) - return Rectangle (nx, ny, nw, nh); - - return Rectangle(); - } - - /** Clips a set of rectangle coordinates so that they lie only within this one. - This is a non-static version of intersectRectangles(). - Returns false if the two rectangles didn't overlap. - */ - bool intersectRectangle (ValueType& otherX, ValueType& otherY, ValueType& otherW, ValueType& otherH) const noexcept - { - const ValueType maxX (jmax (otherX, pos.x)); - otherW = jmin (otherX + otherW, pos.x + w) - maxX; - - if (otherW > ValueType()) - { - const ValueType maxY (jmax (otherY, pos.y)); - otherH = jmin (otherY + otherH, pos.y + h) - maxY; - - if (otherH > ValueType()) - { - otherX = maxX; otherY = maxY; - return true; - } - } - - return false; - } - - /** Clips a rectangle so that it lies only within this one. - Returns false if the two rectangles didn't overlap. - */ - bool intersectRectangle (Rectangle& rectangleToClip) const noexcept - { - return intersectRectangle (rectangleToClip.pos.x, rectangleToClip.pos.y, - rectangleToClip.w, rectangleToClip.h); - } - - /** Returns the smallest rectangle that contains both this one and the one passed-in. - - If either this or the other rectangle are empty, they will not be counted as - part of the resulting region. - */ - Rectangle getUnion (const Rectangle& other) const noexcept - { - if (other.isEmpty()) return *this; - if (isEmpty()) return other; - - const ValueType newX = jmin (pos.x, other.pos.x); - const ValueType newY = jmin (pos.y, other.pos.y); - - return Rectangle (newX, newY, - jmax (pos.x + w, other.pos.x + other.w) - newX, - jmax (pos.y + h, other.pos.y + other.h) - newY); - } - - /** If this rectangle merged with another one results in a simple rectangle, this - will set this rectangle to the result, and return true. - - Returns false and does nothing to this rectangle if the two rectangles don't overlap, - or if they form a complex region. - */ - bool enlargeIfAdjacent (const Rectangle& other) noexcept - { - if (pos.x == other.pos.x && getRight() == other.getRight() - && (other.getBottom() >= pos.y && other.pos.y <= getBottom())) - { - const ValueType newY = jmin (pos.y, other.pos.y); - h = jmax (getBottom(), other.getBottom()) - newY; - pos.y = newY; - return true; - } - - if (pos.y == other.pos.y && getBottom() == other.getBottom() - && (other.getRight() >= pos.x && other.pos.x <= getRight())) - { - const ValueType newX = jmin (pos.x, other.pos.x); - w = jmax (getRight(), other.getRight()) - newX; - pos.x = newX; - return true; - } - - return false; - } - - /** If after removing another rectangle from this one the result is a simple rectangle, - this will set this object's bounds to be the result, and return true. - - Returns false and does nothing to this rectangle if the two rectangles don't overlap, - or if removing the other one would form a complex region. - */ - bool reduceIfPartlyContainedIn (const Rectangle& other) noexcept - { - int inside = 0; - const ValueType otherR (other.getRight()); - if (pos.x >= other.pos.x && pos.x < otherR) inside = 1; - const ValueType otherB (other.getBottom()); - if (pos.y >= other.pos.y && pos.y < otherB) inside |= 2; - const ValueType r (pos.x + w); - if (r >= other.pos.x && r < otherR) inside |= 4; - const ValueType b (pos.y + h); - if (b >= other.pos.y && b < otherB) inside |= 8; - - switch (inside) - { - case 1 + 2 + 8: w = r - otherR; pos.x = otherR; return true; - case 1 + 2 + 4: h = b - otherB; pos.y = otherB; return true; - case 2 + 4 + 8: w = other.pos.x - pos.x; return true; - case 1 + 4 + 8: h = other.pos.y - pos.y; return true; - } - - return false; - } - - /** Tries to fit this rectangle within a target area, returning the result. - - If this rectangle is not completely inside the target area, then it'll be - shifted (without changing its size) so that it lies within the target. If it - is larger than the target rectangle in either dimension, then that dimension - will be reduced to fit within the target. - */ - Rectangle constrainedWithin (const Rectangle& areaToFitWithin) const noexcept - { - const ValueType newW (jmin (w, areaToFitWithin.getWidth())); - const ValueType newH (jmin (h, areaToFitWithin.getHeight())); - - return Rectangle (jlimit (areaToFitWithin.getX(), areaToFitWithin.getRight() - newW, pos.x), - jlimit (areaToFitWithin.getY(), areaToFitWithin.getBottom() - newH, pos.y), - newW, newH); - } - - /** Returns the smallest rectangle that can contain the shape created by applying - a transform to this rectangle. - - This should only be used on floating point rectangles. - */ - Rectangle transformedBy (const AffineTransform& transform) const noexcept - { - typedef typename TypeHelpers::SmallestFloatType::type FloatType; - - FloatType x1 = static_cast (pos.x), y1 = static_cast (pos.y); - FloatType x2 = static_cast (pos.x + w), y2 = static_cast (pos.y); - FloatType x3 = static_cast (pos.x), y3 = static_cast (pos.y + h); - FloatType x4 = static_cast (x2), y4 = static_cast (y3); - - transform.transformPoints (x1, y1, x2, y2); - transform.transformPoints (x3, y3, x4, y4); - - const FloatType rx1 = jmin (x1, x2, x3, x4); - const FloatType rx2 = jmax (x1, x2, x3, x4); - const FloatType ry1 = jmin (y1, y2, y3, y4); - const FloatType ry2 = jmax (y1, y2, y3, y4); - - Rectangle r; - Rectangle (rx1, ry1, rx2 - rx1, ry2 - ry1).copyWithRounding (r); - return r; - } - - /** Returns the smallest integer-aligned rectangle that completely contains this one. - This is only relevent for floating-point rectangles, of course. - @see toFloat() - */ - Rectangle getSmallestIntegerContainer() const noexcept - { - const int x1 = floorAsInt (pos.x); - const int y1 = floorAsInt (pos.y); - const int x2 = ceilAsInt (pos.x + w); - const int y2 = ceilAsInt (pos.y + h); - - return Rectangle (x1, y1, x2 - x1, y2 - y1); - } - - /** Casts this rectangle to a Rectangle. - @see getSmallestIntegerContainer - */ - Rectangle toFloat() const noexcept - { - return Rectangle (static_cast (pos.x), static_cast (pos.y), - static_cast (w), static_cast (h)); - } - - /** Casts this rectangle to a Rectangle. - @see getSmallestIntegerContainer - */ - Rectangle toDouble() const noexcept - { - return Rectangle (static_cast (pos.x), static_cast (pos.y), - static_cast (w), static_cast (h)); - } - - /** Casts this rectangle to a Rectangle with the given type. - If the target type is a conversion from float to int, then the conversion - will be done using getSmallestIntegerContainer(). - */ - template - Rectangle toType() const noexcept - { - Rectangle r; - copyWithRounding (r); - return r; - } - - /** Returns the smallest Rectangle that can contain a set of points. */ - static Rectangle findAreaContainingPoints (const Point* const points, const int numPoints) noexcept - { - if (numPoints == 0) - return Rectangle(); - - ValueType minX (points[0].x); - ValueType maxX (minX); - ValueType minY (points[0].y); - ValueType maxY (minY); - - for (int i = 1; i < numPoints; ++i) - { - minX = jmin (minX, points[i].x); - maxX = jmax (maxX, points[i].x); - minY = jmin (minY, points[i].y); - maxY = jmax (maxY, points[i].y); - } - - return Rectangle (minX, minY, maxX - minX, maxY - minY); - } - - //============================================================================== - /** Static utility to intersect two sets of rectangular coordinates. - Returns false if the two regions didn't overlap. - @see intersectRectangle - */ - static bool intersectRectangles (ValueType& x1, ValueType& y1, ValueType& w1, ValueType& h1, - const ValueType x2, const ValueType y2, const ValueType w2, const ValueType h2) noexcept - { - const ValueType x (jmax (x1, x2)); - w1 = jmin (x1 + w1, x2 + w2) - x; - - if (w1 > ValueType()) - { - const ValueType y (jmax (y1, y2)); - h1 = jmin (y1 + h1, y2 + h2) - y; - - if (h1 > ValueType()) - { - x1 = x; y1 = y; - return true; - } - } - - return false; - } - - //============================================================================== - /** Creates a string describing this rectangle. - - The string will be of the form "x y width height", e.g. "100 100 400 200". - - Coupled with the fromString() method, this is very handy for things like - storing rectangles (particularly component positions) in XML attributes. - - @see fromString - */ - String toString() const - { - String s; - s.preallocateBytes (32); - s << pos.x << ' ' << pos.y << ' ' << w << ' ' << h; - return s; - } - - /** Parses a string containing a rectangle's details. - - The string should contain 4 integer tokens, in the form "x y width height". They - can be comma or whitespace separated. - - This method is intended to go with the toString() method, to form an easy way - of saving/loading rectangles as strings. - - @see toString - */ - static Rectangle fromString (StringRef stringVersion) - { - StringArray toks; - toks.addTokens (stringVersion.text.findEndOfWhitespace(), ",; \t\r\n", ""); - - return Rectangle (parseIntAfterSpace (toks[0]), - parseIntAfterSpace (toks[1]), - parseIntAfterSpace (toks[2]), - parseIntAfterSpace (toks[3])); - } - - #ifndef DOXYGEN - // This has been renamed by transformedBy, in order to match the method names used in the Point class. - JUCE_DEPRECATED_WITH_BODY (Rectangle transformed (const AffineTransform& t) const noexcept, { return transformedBy (t); }) - #endif - -private: - template friend class Rectangle; - - Point pos; - ValueType w, h; - - static int parseIntAfterSpace (StringRef s) noexcept - { return s.text.findEndOfWhitespace().getIntValue32(); } - - void copyWithRounding (Rectangle& result) const noexcept { result = getSmallestIntegerContainer(); } - void copyWithRounding (Rectangle& result) const noexcept { result = toFloat(); } - void copyWithRounding (Rectangle& result) const noexcept { result = toDouble(); } - - static int floorAsInt (int n) noexcept { return n; } - static int floorAsInt (float n) noexcept { return (int) std::floor (n); } - static int floorAsInt (double n) noexcept { return (int) std::floor (n); } - static int ceilAsInt (int n) noexcept { return n; } - static int ceilAsInt (float n) noexcept { return (int) std::ceil (n); } - static int ceilAsInt (double n) noexcept { return (int) std::ceil (n); } -}; - - -#endif // JUCE_RECTANGLE_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/geometry/juce_RectangleList.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/geometry/juce_RectangleList.h deleted file mode 100644 index f1b81a74ac..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/geometry/juce_RectangleList.h +++ /dev/null @@ -1,648 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_RECTANGLELIST_H_INCLUDED -#define JUCE_RECTANGLELIST_H_INCLUDED - - -//============================================================================== -/** - Maintains a set of rectangles as a complex region. - - This class allows a set of rectangles to be treated as a solid shape, and can - add and remove rectangular sections of it, and simplify overlapping or - adjacent rectangles. - - @see Rectangle -*/ -template -class RectangleList -{ -public: - typedef Rectangle RectangleType; - - //============================================================================== - /** Creates an empty RectangleList */ - RectangleList() noexcept {} - - /** Creates a copy of another list */ - RectangleList (const RectangleList& other) : rects (other.rects) - { - } - - /** Creates a list containing just one rectangle. */ - RectangleList (const RectangleType& rect) - { - addWithoutMerging (rect); - } - - /** Copies this list from another one. */ - RectangleList& operator= (const RectangleList& other) - { - rects = other.rects; - return *this; - } - - #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS - RectangleList (RectangleList&& other) noexcept - : rects (static_cast&&> (other.rects)) - { - } - - RectangleList& operator= (RectangleList&& other) noexcept - { - rects = static_cast&&> (other.rects); - return *this; - } - #endif - - //============================================================================== - /** Returns true if the region is empty. */ - bool isEmpty() const noexcept { return rects.size() == 0; } - - /** Returns the number of rectangles in the list. */ - int getNumRectangles() const noexcept { return rects.size(); } - - /** Returns one of the rectangles at a particular index. - @returns the rectangle at the index, or an empty rectangle if the index is out-of-range. - */ - RectangleType getRectangle (int index) const noexcept { return rects[index]; } - - //============================================================================== - /** Removes all rectangles to leave an empty region. */ - void clear() - { - rects.clearQuick(); - } - - /** Merges a new rectangle into the list. - - The rectangle being added will first be clipped to remove any parts of it - that overlap existing rectangles in the list, and adjacent rectangles will be - merged into it. - */ - void add (const RectangleType& rect) - { - if (! rect.isEmpty()) - { - if (rects.size() == 0) - { - rects.add (rect); - } - else - { - bool anyOverlaps = false; - - for (int j = rects.size(); --j >= 0;) - { - RectangleType& ourRect = rects.getReference (j); - - if (rect.intersects (ourRect)) - { - if (rect.contains (ourRect)) - rects.remove (j); - else if (! ourRect.reduceIfPartlyContainedIn (rect)) - anyOverlaps = true; - } - } - - if (anyOverlaps && rects.size() > 0) - { - RectangleList r (rect); - - for (int i = rects.size(); --i >= 0;) - { - const RectangleType& ourRect = rects.getReference (i); - - if (rect.intersects (ourRect)) - { - r.subtract (ourRect); - - if (r.rects.size() == 0) - return; - } - } - - rects.addArray (r.rects); - } - else - { - rects.add (rect); - } - } - } - } - - /** Merges a new rectangle into the list. - - The rectangle being added will first be clipped to remove any parts of it - that overlap existing rectangles in the list. - */ - void add (ValueType x, ValueType y, ValueType width, ValueType height) - { - add (RectangleType (x, y, width, height)); - } - - /** Dumbly adds a rectangle to the list without checking for overlaps. - - This simply adds the rectangle to the end, it doesn't merge it or remove - any overlapping bits. - */ - void addWithoutMerging (const RectangleType& rect) - { - if (! rect.isEmpty()) - rects.add (rect); - } - - /** Merges another rectangle list into this one. - - Any overlaps between the two lists will be clipped, so that the result is - the union of both lists. - */ - void add (const RectangleList& other) - { - for (const RectangleType* r = other.begin(), * const e = other.end(); r != e; ++r) - add (*r); - } - - /** Removes a rectangular region from the list. - - Any rectangles in the list which overlap this will be clipped and subdivided - if necessary. - */ - void subtract (const RectangleType& rect) - { - const int originalNumRects = rects.size(); - - if (originalNumRects > 0) - { - const ValueType x1 = rect.getX(); - const ValueType y1 = rect.getY(); - const ValueType x2 = x1 + rect.getWidth(); - const ValueType y2 = y1 + rect.getHeight(); - - for (int i = getNumRectangles(); --i >= 0;) - { - RectangleType& r = rects.getReference (i); - - const ValueType rx1 = r.getX(); - const ValueType ry1 = r.getY(); - const ValueType rx2 = rx1 + r.getWidth(); - const ValueType ry2 = ry1 + r.getHeight(); - - if (! (x2 <= rx1 || x1 >= rx2 || y2 <= ry1 || y1 >= ry2)) - { - if (x1 > rx1 && x1 < rx2) - { - if (y1 <= ry1 && y2 >= ry2 && x2 >= rx2) - { - r.setWidth (x1 - rx1); - } - else - { - r.setX (x1); - r.setWidth (rx2 - x1); - - rects.insert (++i, RectangleType (rx1, ry1, x1 - rx1, ry2 - ry1)); - ++i; - } - } - else if (x2 > rx1 && x2 < rx2) - { - r.setX (x2); - r.setWidth (rx2 - x2); - - if (y1 > ry1 || y2 < ry2 || x1 > rx1) - { - rects.insert (++i, RectangleType (rx1, ry1, x2 - rx1, ry2 - ry1)); - ++i; - } - } - else if (y1 > ry1 && y1 < ry2) - { - if (x1 <= rx1 && x2 >= rx2 && y2 >= ry2) - { - r.setHeight (y1 - ry1); - } - else - { - r.setY (y1); - r.setHeight (ry2 - y1); - - rects.insert (++i, RectangleType (rx1, ry1, rx2 - rx1, y1 - ry1)); - ++i; - } - } - else if (y2 > ry1 && y2 < ry2) - { - r.setY (y2); - r.setHeight (ry2 - y2); - - if (x1 > rx1 || x2 < rx2 || y1 > ry1) - { - rects.insert (++i, RectangleType (rx1, ry1, rx2 - rx1, y2 - ry1)); - ++i; - } - } - else - { - rects.remove (i); - } - } - } - } - } - - /** Removes all areas in another RectangleList from this one. - - Any rectangles in the list which overlap this will be clipped and subdivided - if necessary. - - @returns true if the resulting list is non-empty. - */ - bool subtract (const RectangleList& otherList) - { - for (int i = otherList.rects.size(); --i >= 0 && rects.size() > 0;) - subtract (otherList.rects.getReference (i)); - - return rects.size() > 0; - } - - /** Removes any areas of the region that lie outside a given rectangle. - - Any rectangles in the list which overlap this will be clipped and subdivided - if necessary. - - Returns true if the resulting region is not empty, false if it is empty. - - @see getIntersectionWith - */ - bool clipTo (const RectangleType& rect) - { - bool notEmpty = false; - - if (rect.isEmpty()) - { - clear(); - } - else - { - for (int i = rects.size(); --i >= 0;) - { - RectangleType& r = rects.getReference (i); - - if (! rect.intersectRectangle (r)) - rects.remove (i); - else - notEmpty = true; - } - } - - return notEmpty; - } - - /** Removes any areas of the region that lie outside a given rectangle list. - - Any rectangles in this object which overlap the specified list will be clipped - and subdivided if necessary. - - Returns true if the resulting region is not empty, false if it is empty. - - @see getIntersectionWith - */ - template - bool clipTo (const RectangleList& other) - { - if (rects.size() == 0) - return false; - - RectangleList result; - - for (int j = 0; j < rects.size(); ++j) - { - const RectangleType& rect = rects.getReference (j); - - for (const Rectangle* r = other.begin(), * const e = other.end(); r != e; ++r) - { - RectangleType clipped (r->template toType()); - - if (rect.intersectRectangle (clipped)) - result.rects.add (clipped); - } - } - - swapWith (result); - return ! isEmpty(); - } - - /** Creates a region which is the result of clipping this one to a given rectangle. - - Unlike the other clipTo method, this one doesn't affect this object - it puts the - resulting region into the list whose reference is passed-in. - - Returns true if the resulting region is not empty, false if it is empty. - - @see clipTo - */ - bool getIntersectionWith (const RectangleType& rect, RectangleList& destRegion) const - { - destRegion.clear(); - - if (! rect.isEmpty()) - { - for (int i = rects.size(); --i >= 0;) - { - RectangleType r (rects.getReference (i)); - - if (rect.intersectRectangle (r)) - destRegion.rects.add (r); - } - } - - return destRegion.rects.size() > 0; - } - - /** Swaps the contents of this and another list. - - This swaps their internal pointers, so is hugely faster than using copy-by-value - to swap them. - */ - void swapWith (RectangleList& otherList) noexcept - { - rects.swapWith (otherList.rects); - } - - //============================================================================== - /** Checks whether the region contains a given point. - @returns true if the point lies within one of the rectangles in the list - */ - bool containsPoint (Point point) const noexcept - { - for (const RectangleType* r = rects.begin(), * const e = rects.end(); r != e; ++r) - if (r->contains (point)) - return true; - - return false; - } - - /** Checks whether the region contains a given point. - @returns true if the point lies within one of the rectangles in the list - */ - bool containsPoint (ValueType x, ValueType y) const noexcept - { - return containsPoint (Point (x, y)); - } - - /** Checks whether the region contains the whole of a given rectangle. - - @returns true all parts of the rectangle passed in lie within the region - defined by this object - @see intersectsRectangle, containsPoint - */ - bool containsRectangle (const RectangleType& rectangleToCheck) const - { - if (rects.size() > 1) - { - RectangleList r (rectangleToCheck); - - for (int i = rects.size(); --i >= 0;) - { - r.subtract (rects.getReference (i)); - - if (r.rects.size() == 0) - return true; - } - } - else if (rects.size() > 0) - { - return rects.getReference (0).contains (rectangleToCheck); - } - - return false; - } - - /** Checks whether the region contains any part of a given rectangle. - - @returns true if any part of the rectangle passed in lies within the region - defined by this object - @see containsRectangle - */ - bool intersectsRectangle (const RectangleType& rectangleToCheck) const noexcept - { - for (const RectangleType* r = rects.begin(), * const e = rects.end(); r != e; ++r) - if (r->intersects (rectangleToCheck)) - return true; - - return false; - } - - /** Checks whether this region intersects any part of another one. - - @see intersectsRectangle - */ - bool intersects (const RectangleList& other) const noexcept - { - for (const RectangleType* r = rects.begin(), * const e = rects.end(); r != e; ++r) - if (other.intersectsRectangle (*r)) - return true; - - return false; - } - - //============================================================================== - /** Returns the smallest rectangle that can enclose the whole of this region. */ - RectangleType getBounds() const noexcept - { - if (rects.size() <= 1) - { - if (rects.size() == 0) - return RectangleType(); - - return rects.getReference (0); - } - - const RectangleType& r = rects.getReference (0); - - ValueType minX = r.getX(); - ValueType minY = r.getY(); - ValueType maxX = minX + r.getWidth(); - ValueType maxY = minY + r.getHeight(); - - for (int i = rects.size(); --i > 0;) - { - const RectangleType& r2 = rects.getReference (i); - - minX = jmin (minX, r2.getX()); - minY = jmin (minY, r2.getY()); - maxX = jmax (maxX, r2.getRight()); - maxY = jmax (maxY, r2.getBottom()); - } - - return RectangleType (minX, minY, maxX - minX, maxY - minY); - } - - /** Optimises the list into a minimum number of constituent rectangles. - - This will try to combine any adjacent rectangles into larger ones where - possible, to simplify lists that might have been fragmented by repeated - add/subtract calls. - */ - void consolidate() - { - for (int i = 0; i < getNumRectangles() - 1; ++i) - { - RectangleType& r = rects.getReference (i); - const ValueType rx1 = r.getX(); - const ValueType ry1 = r.getY(); - const ValueType rx2 = rx1 + r.getWidth(); - const ValueType ry2 = ry1 + r.getHeight(); - - for (int j = rects.size(); --j > i;) - { - RectangleType& r2 = rects.getReference (j); - const ValueType jrx1 = r2.getX(); - const ValueType jry1 = r2.getY(); - const ValueType jrx2 = jrx1 + r2.getWidth(); - const ValueType jry2 = jry1 + r2.getHeight(); - - // if the vertical edges of any blocks are touching and their horizontals don't - // line up, split them horizontally.. - if (jrx1 == rx2 || jrx2 == rx1) - { - if (jry1 > ry1 && jry1 < ry2) - { - r.setHeight (jry1 - ry1); - rects.add (RectangleType (rx1, jry1, rx2 - rx1, ry2 - jry1)); - i = -1; - break; - } - - if (jry2 > ry1 && jry2 < ry2) - { - r.setHeight (jry2 - ry1); - rects.add (RectangleType (rx1, jry2, rx2 - rx1, ry2 - jry2)); - i = -1; - break; - } - else if (ry1 > jry1 && ry1 < jry2) - { - r2.setHeight (ry1 - jry1); - rects.add (RectangleType (jrx1, ry1, jrx2 - jrx1, jry2 - ry1)); - i = -1; - break; - } - else if (ry2 > jry1 && ry2 < jry2) - { - r2.setHeight (ry2 - jry1); - rects.add (RectangleType (jrx1, ry2, jrx2 - jrx1, jry2 - ry2)); - i = -1; - break; - } - } - } - } - - for (int i = 0; i < rects.size() - 1; ++i) - { - RectangleType& r = rects.getReference (i); - - for (int j = rects.size(); --j > i;) - { - if (r.enlargeIfAdjacent (rects.getReference (j))) - { - rects.remove (j); - i = -1; - break; - } - } - } - } - - /** Adds an x and y value to all the coordinates. */ - void offsetAll (Point offset) noexcept - { - for (RectangleType* r = rects.begin(), * const e = rects.end(); r != e; ++r) - *r += offset; - } - - /** Adds an x and y value to all the coordinates. */ - void offsetAll (ValueType dx, ValueType dy) noexcept - { - offsetAll (Point (dx, dy)); - } - - /** Scales all the coordinates. */ - template - void scaleAll (ScaleType scaleFactor) noexcept - { - for (RectangleType* r = rects.begin(), * const e = rects.end(); r != e; ++r) - *r *= scaleFactor; - } - - /** Applies a transform to all the rectangles. - Obviously this will create a mess if the transform involves any - rotation or skewing. - */ - void transformAll (const AffineTransform& transform) noexcept - { - for (RectangleType* r = rects.begin(), * const e = rects.end(); r != e; ++r) - *r = r->transformedBy (transform); - } - - //============================================================================== - /** Creates a Path object to represent this region. */ - Path toPath() const - { - Path p; - - for (int i = 0; i < rects.size(); ++i) - p.addRectangle (rects.getReference (i)); - - return p; - } - - //============================================================================== - /** Standard method for iterating the rectangles in the list. */ - const RectangleType* begin() const noexcept { return rects.begin(); } - /** Standard method for iterating the rectangles in the list. */ - const RectangleType* end() const noexcept { return rects.end(); } - - /** Increases the internal storage to hold a minimum number of rectangles. - Calling this before adding a large number of rectangles means that - the array won't have to keep dynamically resizing itself as the elements - are added, and it'll therefore be more efficient. - @see Array::ensureStorageAllocated - */ - void ensureStorageAllocated (int minNumRectangles) - { - rects.ensureStorageAllocated (minNumRectangles); - } - -private: - //============================================================================== - Array rects; -}; - - -#endif // JUCE_RECTANGLELIST_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/image_formats/juce_GIFLoader.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/image_formats/juce_GIFLoader.cpp deleted file mode 100644 index 2c9066f5bd..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/image_formats/juce_GIFLoader.cpp +++ /dev/null @@ -1,444 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#if (JUCE_MAC || JUCE_IOS) && USE_COREGRAPHICS_RENDERING && JUCE_USE_COREIMAGE_LOADER - Image juce_loadWithCoreImage (InputStream& input); -#else - -//============================================================================== -class GIFLoader -{ -public: - GIFLoader (InputStream& in) - : input (in), - dataBlockIsZero (false), fresh (false), finished (false), - currentBit (0), lastBit (0), lastByteIndex (0), - codeSize (0), setCodeSize (0), maxCode (0), maxCodeSize (0), - firstcode (0), oldcode (0), clearCode (0), endCode (0) - { - int imageWidth, imageHeight; - if (! getSizeFromHeader (imageWidth, imageHeight)) - return; - - uint8 buf [16]; - if (in.read (buf, 3) != 3) - return; - - int numColours = 2 << (buf[0] & 7); - int transparent = -1; - - if ((buf[0] & 0x80) != 0) - readPalette (numColours); - - for (;;) - { - if (input.read (buf, 1) != 1 || buf[0] == ';') - break; - - if (buf[0] == '!') - { - if (readExtension (transparent)) - continue; - - break; - } - - if (buf[0] != ',') - continue; - - if (input.read (buf, 9) == 9) - { - imageWidth = (int) ByteOrder::littleEndianShort (buf + 4); - imageHeight = (int) ByteOrder::littleEndianShort (buf + 6); - - numColours = 2 << (buf[8] & 7); - - if ((buf[8] & 0x80) != 0) - if (! readPalette (numColours)) - break; - - image = Image (transparent >= 0 ? Image::ARGB : Image::RGB, - imageWidth, imageHeight, transparent >= 0); - - image.getProperties()->set ("originalImageHadAlpha", transparent >= 0); - - readImage ((buf[8] & 0x40) != 0, transparent); - } - - break; - } - } - - Image image; - -private: - InputStream& input; - uint8 buffer [260]; - PixelARGB palette [256]; - bool dataBlockIsZero, fresh, finished; - int currentBit, lastBit, lastByteIndex; - int codeSize, setCodeSize; - int maxCode, maxCodeSize; - int firstcode, oldcode; - int clearCode, endCode; - enum { maxGifCode = 1 << 12 }; - int table [2] [maxGifCode]; - int stack [2 * maxGifCode]; - int* sp; - - bool getSizeFromHeader (int& w, int& h) - { - char b[6]; - - if (input.read (b, 6) == 6 - && (strncmp ("GIF87a", b, 6) == 0 - || strncmp ("GIF89a", b, 6) == 0)) - { - if (input.read (b, 4) == 4) - { - w = (int) ByteOrder::littleEndianShort (b); - h = (int) ByteOrder::littleEndianShort (b + 2); - return w > 0 && h > 0; - } - } - - return false; - } - - bool readPalette (const int numCols) - { - for (int i = 0; i < numCols; ++i) - { - uint8 rgb[4]; - input.read (rgb, 3); - - palette[i].setARGB (0xff, rgb[0], rgb[1], rgb[2]); - palette[i].premultiply(); - } - - return true; - } - - int readDataBlock (uint8* const dest) - { - uint8 n; - if (input.read (&n, 1) == 1) - { - dataBlockIsZero = (n == 0); - - if (dataBlockIsZero || (input.read (dest, n) == n)) - return n; - } - - return -1; - } - - int readExtension (int& transparent) - { - uint8 type; - if (input.read (&type, 1) != 1) - return false; - - uint8 b [260]; - int n = 0; - - if (type == 0xf9) - { - n = readDataBlock (b); - if (n < 0) - return 1; - - if ((b[0] & 1) != 0) - transparent = b[3]; - } - - do - { - n = readDataBlock (b); - } - while (n > 0); - - return n >= 0; - } - - void clearTable() - { - int i; - for (i = 0; i < clearCode; ++i) - { - table[0][i] = 0; - table[1][i] = i; - } - - for (; i < maxGifCode; ++i) - { - table[0][i] = 0; - table[1][i] = 0; - } - } - - void initialise (const int inputCodeSize) - { - setCodeSize = inputCodeSize; - codeSize = setCodeSize + 1; - clearCode = 1 << setCodeSize; - endCode = clearCode + 1; - maxCodeSize = 2 * clearCode; - maxCode = clearCode + 2; - - getCode (0, true); - - fresh = true; - clearTable(); - sp = stack; - } - - int readLZWByte() - { - if (fresh) - { - fresh = false; - - for (;;) - { - firstcode = oldcode = getCode (codeSize, false); - - if (firstcode != clearCode) - return firstcode; - } - } - - if (sp > stack) - return *--sp; - - int code; - - while ((code = getCode (codeSize, false)) >= 0) - { - if (code == clearCode) - { - clearTable(); - codeSize = setCodeSize + 1; - maxCodeSize = 2 * clearCode; - maxCode = clearCode + 2; - sp = stack; - firstcode = oldcode = getCode (codeSize, false); - return firstcode; - } - else if (code == endCode) - { - if (dataBlockIsZero) - return -2; - - uint8 buf [260]; - int n; - - while ((n = readDataBlock (buf)) > 0) - {} - - if (n != 0) - return -2; - } - - const int incode = code; - - if (code >= maxCode) - { - *sp++ = firstcode; - code = oldcode; - } - - while (code >= clearCode) - { - *sp++ = table[1][code]; - if (code == table[0][code]) - return -2; - - code = table[0][code]; - } - - *sp++ = firstcode = table[1][code]; - - if ((code = maxCode) < maxGifCode) - { - table[0][code] = oldcode; - table[1][code] = firstcode; - ++maxCode; - - if (maxCode >= maxCodeSize && maxCodeSize < maxGifCode) - { - maxCodeSize <<= 1; - ++codeSize; - } - } - - oldcode = incode; - - if (sp > stack) - return *--sp; - } - - return code; - } - - int getCode (const int codeSize_, const bool shouldInitialise) - { - if (shouldInitialise) - { - currentBit = 0; - lastBit = 0; - finished = false; - return 0; - } - - if ((currentBit + codeSize_) >= lastBit) - { - if (finished) - return -1; - - buffer[0] = buffer [lastByteIndex - 2]; - buffer[1] = buffer [lastByteIndex - 1]; - - const int n = readDataBlock (buffer + 2); - - if (n == 0) - finished = true; - - lastByteIndex = 2 + n; - currentBit = (currentBit - lastBit) + 16; - lastBit = (2 + n) * 8 ; - } - - int result = 0; - int i = currentBit; - - for (int j = 0; j < codeSize_; ++j) - { - result |= ((buffer[i >> 3] & (1 << (i & 7))) != 0) << j; - ++i; - } - - currentBit += codeSize_; - return result; - } - - bool readImage (const int interlace, const int transparent) - { - uint8 c; - if (input.read (&c, 1) != 1) - return false; - - initialise (c); - - if (transparent >= 0) - palette [transparent].setARGB (0, 0, 0, 0); - - int xpos = 0, ypos = 0, yStep = 8, pass = 0; - - const Image::BitmapData destData (image, Image::BitmapData::writeOnly); - uint8* p = destData.getPixelPointer (0, 0); - const bool hasAlpha = image.hasAlphaChannel(); - - for (;;) - { - const int index = readLZWByte(); - if (index < 0) - break; - - if (hasAlpha) - ((PixelARGB*) p)->set (palette [index]); - else - ((PixelRGB*) p)->set (palette [index]); - - p += destData.pixelStride; - - if (++xpos == destData.width) - { - xpos = 0; - - if (interlace) - { - ypos += yStep; - - while (ypos >= destData.height) - { - switch (++pass) - { - case 1: ypos = 4; yStep = 8; break; - case 2: ypos = 2; yStep = 4; break; - case 3: ypos = 1; yStep = 2; break; - default: return true; - } - } - } - else - { - if (++ypos >= destData.height) - break; - } - - p = destData.getPixelPointer (xpos, ypos); - } - } - - return true; - } - - JUCE_DECLARE_NON_COPYABLE (GIFLoader) -}; - -#endif - -//============================================================================== -GIFImageFormat::GIFImageFormat() {} -GIFImageFormat::~GIFImageFormat() {} - -String GIFImageFormat::getFormatName() { return "GIF"; } -bool GIFImageFormat::usesFileExtension (const File& f) { return f.hasFileExtension ("gif"); } - -bool GIFImageFormat::canUnderstand (InputStream& in) -{ - char header [4]; - - return (in.read (header, sizeof (header)) == sizeof (header)) - && header[0] == 'G' - && header[1] == 'I' - && header[2] == 'F'; -} - -Image GIFImageFormat::decodeImage (InputStream& in) -{ - #if (JUCE_MAC || JUCE_IOS) && USE_COREGRAPHICS_RENDERING && JUCE_USE_COREIMAGE_LOADER - return juce_loadWithCoreImage (in); - #else - const ScopedPointer loader (new GIFLoader (in)); - return loader->image; - #endif -} - -bool GIFImageFormat::writeImageToStream (const Image& /*sourceImage*/, OutputStream& /*destStream*/) -{ - jassertfalse; // writing isn't implemented for GIFs! - return false; -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/image_formats/juce_JPEGLoader.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/image_formats/juce_JPEGLoader.cpp deleted file mode 100644 index 0f56e32c81..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/image_formats/juce_JPEGLoader.cpp +++ /dev/null @@ -1,430 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#if JUCE_MSVC - #pragma warning (push) - #pragma warning (disable: 4365) -#endif - -namespace jpeglibNamespace -{ -#if JUCE_INCLUDE_JPEGLIB_CODE || ! defined (JUCE_INCLUDE_JPEGLIB_CODE) - #if JUCE_MINGW - typedef unsigned char boolean; - #endif - - #if JUCE_CLANG - #pragma clang diagnostic push - #pragma clang diagnostic ignored "-Wconversion" - #pragma clang diagnostic ignored "-Wdeprecated-register" - #endif - - #define JPEG_INTERNALS - #undef FAR - #include "jpglib/jpeglib.h" - - #include "jpglib/jcapimin.c" - #include "jpglib/jcapistd.c" - #include "jpglib/jccoefct.c" - #include "jpglib/jccolor.c" - #undef FIX - #include "jpglib/jcdctmgr.c" - #undef CONST_BITS - #include "jpglib/jchuff.c" - #undef emit_byte - #include "jpglib/jcinit.c" - #include "jpglib/jcmainct.c" - #include "jpglib/jcmarker.c" - #include "jpglib/jcmaster.c" - #include "jpglib/jcomapi.c" - #include "jpglib/jcparam.c" - #include "jpglib/jcphuff.c" - #include "jpglib/jcprepct.c" - #include "jpglib/jcsample.c" - #include "jpglib/jctrans.c" - #include "jpglib/jdapistd.c" - #include "jpglib/jdapimin.c" - #include "jpglib/jdatasrc.c" - #include "jpglib/jdcoefct.c" - #undef FIX - #include "jpglib/jdcolor.c" - #undef FIX - #include "jpglib/jddctmgr.c" - #undef CONST_BITS - #undef ASSIGN_STATE - #include "jpglib/jdhuff.c" - #include "jpglib/jdinput.c" - #include "jpglib/jdmainct.c" - #include "jpglib/jdmarker.c" - #include "jpglib/jdmaster.c" - #undef FIX - #include "jpglib/jdmerge.c" - #undef ASSIGN_STATE - #include "jpglib/jdphuff.c" - #include "jpglib/jdpostct.c" - #undef FIX - #include "jpglib/jdsample.c" - #include "jpglib/jdtrans.c" - #include "jpglib/jfdctflt.c" - #include "jpglib/jfdctint.c" - #undef CONST_BITS - #undef MULTIPLY - #undef FIX_0_541196100 - #include "jpglib/jfdctfst.c" - #undef FIX_0_541196100 - #include "jpglib/jidctflt.c" - #undef CONST_BITS - #undef FIX_1_847759065 - #undef MULTIPLY - #undef DEQUANTIZE - #undef DESCALE - #include "jpglib/jidctfst.c" - #undef CONST_BITS - #undef FIX_1_847759065 - #undef MULTIPLY - #undef DEQUANTIZE - #include "jpglib/jidctint.c" - #include "jpglib/jidctred.c" - #include "jpglib/jmemmgr.c" - #include "jpglib/jmemnobs.c" - #include "jpglib/jquant1.c" - #include "jpglib/jquant2.c" - #include "jpglib/jutils.c" - #include "jpglib/transupp.c" - - #if JUCE_CLANG - #pragma clang diagnostic pop - #endif -#else - #define JPEG_INTERNALS - #undef FAR - #include -#endif -} - -#undef max -#undef min - -#if JUCE_MSVC - #pragma warning (pop) -#endif - -//============================================================================== -namespace JPEGHelpers -{ - using namespace jpeglibNamespace; - - #if ! JUCE_MSVC - using jpeglibNamespace::boolean; - #endif - - struct JPEGDecodingFailure {}; - - static void fatalErrorHandler (j_common_ptr) { throw JPEGDecodingFailure(); } - static void silentErrorCallback1 (j_common_ptr) {} - static void silentErrorCallback2 (j_common_ptr, int) {} - static void silentErrorCallback3 (j_common_ptr, char*) {} - - static void setupSilentErrorHandler (struct jpeg_error_mgr& err) - { - zerostruct (err); - - err.error_exit = fatalErrorHandler; - err.emit_message = silentErrorCallback2; - err.output_message = silentErrorCallback1; - err.format_message = silentErrorCallback3; - err.reset_error_mgr = silentErrorCallback1; - } - - //============================================================================== - #if ! JUCE_USING_COREIMAGE_LOADER - static void dummyCallback1 (j_decompress_ptr) {} - - static void jpegSkip (j_decompress_ptr decompStruct, long num) - { - decompStruct->src->next_input_byte += num; - - num = jmin (num, (long) decompStruct->src->bytes_in_buffer); - decompStruct->src->bytes_in_buffer -= (size_t) num; - } - - static boolean jpegFill (j_decompress_ptr) - { - return 0; - } - #endif - - //============================================================================== - const int jpegBufferSize = 512; - - struct JuceJpegDest : public jpeg_destination_mgr - { - OutputStream* output; - char* buffer; - }; - - static void jpegWriteInit (j_compress_ptr) {} - - static void jpegWriteTerminate (j_compress_ptr cinfo) - { - JuceJpegDest* const dest = static_cast (cinfo->dest); - - const size_t numToWrite = jpegBufferSize - dest->free_in_buffer; - dest->output->write (dest->buffer, numToWrite); - } - - static boolean jpegWriteFlush (j_compress_ptr cinfo) - { - JuceJpegDest* const dest = static_cast (cinfo->dest); - - const int numToWrite = jpegBufferSize; - - dest->next_output_byte = reinterpret_cast (dest->buffer); - dest->free_in_buffer = jpegBufferSize; - - return (boolean) dest->output->write (dest->buffer, (size_t) numToWrite); - } -} - -//============================================================================== -JPEGImageFormat::JPEGImageFormat() - : quality (-1.0f) -{ -} - -JPEGImageFormat::~JPEGImageFormat() {} - -void JPEGImageFormat::setQuality (const float newQuality) -{ - quality = newQuality; -} - -String JPEGImageFormat::getFormatName() { return "JPEG"; } -bool JPEGImageFormat::usesFileExtension (const File& f) { return f.hasFileExtension ("jpeg;jpg"); } - -bool JPEGImageFormat::canUnderstand (InputStream& in) -{ - const int bytesNeeded = 10; - uint8 header [bytesNeeded]; - - return in.read (header, bytesNeeded) == bytesNeeded - && header[0] == 0xff - && header[1] == 0xd8 - && header[2] == 0xff; -} - -#if JUCE_USING_COREIMAGE_LOADER - Image juce_loadWithCoreImage (InputStream& input); -#endif - -Image JPEGImageFormat::decodeImage (InputStream& in) -{ -#if JUCE_USING_COREIMAGE_LOADER - return juce_loadWithCoreImage (in); -#else - using namespace jpeglibNamespace; - using namespace JPEGHelpers; - - MemoryOutputStream mb; - mb << in; - - Image image; - - if (mb.getDataSize() > 16) - { - struct jpeg_decompress_struct jpegDecompStruct; - - struct jpeg_error_mgr jerr; - setupSilentErrorHandler (jerr); - jpegDecompStruct.err = &jerr; - - jpeg_create_decompress (&jpegDecompStruct); - - jpegDecompStruct.src = (jpeg_source_mgr*)(jpegDecompStruct.mem->alloc_small) - ((j_common_ptr)(&jpegDecompStruct), JPOOL_PERMANENT, sizeof (jpeg_source_mgr)); - - jpegDecompStruct.src->init_source = dummyCallback1; - jpegDecompStruct.src->fill_input_buffer = jpegFill; - jpegDecompStruct.src->skip_input_data = jpegSkip; - jpegDecompStruct.src->resync_to_restart = jpeg_resync_to_restart; - jpegDecompStruct.src->term_source = dummyCallback1; - - jpegDecompStruct.src->next_input_byte = static_cast (mb.getData()); - jpegDecompStruct.src->bytes_in_buffer = mb.getDataSize(); - - try - { - jpeg_read_header (&jpegDecompStruct, TRUE); - - jpeg_calc_output_dimensions (&jpegDecompStruct); - - const int width = (int) jpegDecompStruct.output_width; - const int height = (int) jpegDecompStruct.output_height; - - jpegDecompStruct.out_color_space = JCS_RGB; - - JSAMPARRAY buffer - = (*jpegDecompStruct.mem->alloc_sarray) ((j_common_ptr) &jpegDecompStruct, - JPOOL_IMAGE, - (JDIMENSION) width * 3, 1); - - if (jpeg_start_decompress (&jpegDecompStruct)) - { - image = Image (Image::RGB, width, height, false); - image.getProperties()->set ("originalImageHadAlpha", false); - const bool hasAlphaChan = image.hasAlphaChannel(); // (the native image creator may not give back what we expect) - - const Image::BitmapData destData (image, Image::BitmapData::writeOnly); - - for (int y = 0; y < height; ++y) - { - jpeg_read_scanlines (&jpegDecompStruct, buffer, 1); - - const uint8* src = *buffer; - uint8* dest = destData.getLinePointer (y); - - if (hasAlphaChan) - { - for (int i = width; --i >= 0;) - { - ((PixelARGB*) dest)->setARGB (0xff, src[0], src[1], src[2]); - ((PixelARGB*) dest)->premultiply(); - dest += destData.pixelStride; - src += 3; - } - } - else - { - for (int i = width; --i >= 0;) - { - ((PixelRGB*) dest)->setARGB (0xff, src[0], src[1], src[2]); - dest += destData.pixelStride; - src += 3; - } - } - } - - jpeg_finish_decompress (&jpegDecompStruct); - - in.setPosition (((char*) jpegDecompStruct.src->next_input_byte) - (char*) mb.getData()); - } - - jpeg_destroy_decompress (&jpegDecompStruct); - } - catch (...) - {} - } - - return image; -#endif -} - -bool JPEGImageFormat::writeImageToStream (const Image& image, OutputStream& out) -{ - using namespace jpeglibNamespace; - using namespace JPEGHelpers; - - jpeg_compress_struct jpegCompStruct; - zerostruct (jpegCompStruct); - jpeg_create_compress (&jpegCompStruct); - - struct jpeg_error_mgr jerr; - setupSilentErrorHandler (jerr); - jpegCompStruct.err = &jerr; - - JuceJpegDest dest; - jpegCompStruct.dest = &dest; - - dest.output = &out; - HeapBlock tempBuffer (jpegBufferSize); - dest.buffer = tempBuffer; - dest.next_output_byte = (JOCTET*) dest.buffer; - dest.free_in_buffer = jpegBufferSize; - dest.init_destination = jpegWriteInit; - dest.empty_output_buffer = jpegWriteFlush; - dest.term_destination = jpegWriteTerminate; - - jpegCompStruct.image_width = (JDIMENSION) image.getWidth(); - jpegCompStruct.image_height = (JDIMENSION) image.getHeight(); - jpegCompStruct.input_components = 3; - jpegCompStruct.in_color_space = JCS_RGB; - jpegCompStruct.write_JFIF_header = 1; - - jpegCompStruct.X_density = 72; - jpegCompStruct.Y_density = 72; - - jpeg_set_defaults (&jpegCompStruct); - - jpegCompStruct.dct_method = JDCT_FLOAT; - jpegCompStruct.optimize_coding = 1; - - if (quality < 0.0f) - quality = 0.85f; - - jpeg_set_quality (&jpegCompStruct, jlimit (0, 100, roundToInt (quality * 100.0f)), TRUE); - - jpeg_start_compress (&jpegCompStruct, TRUE); - - const int strideBytes = (int) (jpegCompStruct.image_width * (unsigned int) jpegCompStruct.input_components); - - JSAMPARRAY buffer = (*jpegCompStruct.mem->alloc_sarray) ((j_common_ptr) &jpegCompStruct, - JPOOL_IMAGE, (JDIMENSION) strideBytes, 1); - - const Image::BitmapData srcData (image, Image::BitmapData::readOnly); - - while (jpegCompStruct.next_scanline < jpegCompStruct.image_height) - { - uint8* dst = *buffer; - - if (srcData.pixelFormat == Image::RGB) - { - const uint8* src = srcData.getLinePointer ((int) jpegCompStruct.next_scanline); - - for (int i = srcData.width; --i >= 0;) - { - *dst++ = ((const PixelRGB*) src)->getRed(); - *dst++ = ((const PixelRGB*) src)->getGreen(); - *dst++ = ((const PixelRGB*) src)->getBlue(); - src += srcData.pixelStride; - } - } - else - { - for (int x = 0; x < srcData.width; ++x) - { - const Colour pixel (srcData.getPixelColour (x, (int) jpegCompStruct.next_scanline)); - *dst++ = pixel.getRed(); - *dst++ = pixel.getGreen(); - *dst++ = pixel.getBlue(); - } - } - - jpeg_write_scanlines (&jpegCompStruct, buffer, 1); - } - - jpeg_finish_compress (&jpegCompStruct); - jpeg_destroy_compress (&jpegCompStruct); - - return true; -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/image_formats/juce_PNGLoader.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/image_formats/juce_PNGLoader.cpp deleted file mode 100644 index 636b293869..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/image_formats/juce_PNGLoader.cpp +++ /dev/null @@ -1,546 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#if JUCE_MSVC - #pragma warning (push) - #pragma warning (disable: 4390 4611 4365 4267) - #ifdef __INTEL_COMPILER - #pragma warning (disable: 2544 2545) - #endif -#endif - -namespace zlibNamespace -{ -#if JUCE_INCLUDE_ZLIB_CODE - #undef OS_CODE - #undef fdopen - #include "../../juce_core/zip/zlib/zlib.h" - #undef OS_CODE -#else - #include JUCE_ZLIB_INCLUDE_PATH -#endif -} - -namespace pnglibNamespace -{ - using namespace zlibNamespace; - -#if JUCE_INCLUDE_PNGLIB_CODE || ! defined (JUCE_INCLUDE_PNGLIB_CODE) - - #if _MSC_VER != 1310 - using std::calloc; // (causes conflict in VS.NET 2003) - using std::malloc; - using std::free; - #endif - - #if JUCE_CLANG - #pragma clang diagnostic push - #pragma clang diagnostic ignored "-Wsign-conversion" - #endif - - using std::abs; - #define NO_DUMMY_DECL - #define PNGLCONF_H 1 - - #if JUCE_ANDROID - #define PNG_ARM_NEON_SUPPORTED - #endif - - #define PNG_16BIT_SUPPORTED - #define PNG_ALIGNED_MEMORY_SUPPORTED - #define PNG_BENIGN_ERRORS_SUPPORTED - #define PNG_BENIGN_READ_ERRORS_SUPPORTED - #define PNG_BUILD_GRAYSCALE_PALETTE_SUPPORTED - #define PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED - #define PNG_COLORSPACE_SUPPORTED - #define PNG_CONSOLE_IO_SUPPORTED - #define PNG_EASY_ACCESS_SUPPORTED - #define PNG_FIXED_POINT_SUPPORTED - #define PNG_FLOATING_ARITHMETIC_SUPPORTED - #define PNG_FLOATING_POINT_SUPPORTED - #define PNG_FORMAT_AFIRST_SUPPORTED - #define PNG_FORMAT_BGR_SUPPORTED - #define PNG_GAMMA_SUPPORTED - #define PNG_GET_PALETTE_MAX_SUPPORTED - #define PNG_HANDLE_AS_UNKNOWN_SUPPORTED - #define PNG_INCH_CONVERSIONS_SUPPORTED - #define PNG_INFO_IMAGE_SUPPORTED - #define PNG_IO_STATE_SUPPORTED - #define PNG_MNG_FEATURES_SUPPORTED - #define PNG_POINTER_INDEXING_SUPPORTED - #define PNG_PROGRESSIVE_READ_SUPPORTED - #define PNG_READ_16BIT_SUPPORTED - #define PNG_READ_ALPHA_MODE_SUPPORTED - #define PNG_READ_ANCILLARY_CHUNKS_SUPPORTED - #define PNG_READ_BACKGROUND_SUPPORTED - #define PNG_READ_BGR_SUPPORTED - #define PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED - #define PNG_READ_COMPOSITE_NODIV_SUPPORTED - #define PNG_READ_COMPRESSED_TEXT_SUPPORTED - #define PNG_READ_EXPAND_16_SUPPORTED - #define PNG_READ_EXPAND_SUPPORTED - #define PNG_READ_FILLER_SUPPORTED - #define PNG_READ_GAMMA_SUPPORTED - #define PNG_READ_GET_PALETTE_MAX_SUPPORTED - #define PNG_READ_GRAY_TO_RGB_SUPPORTED - #define PNG_READ_INTERLACING_SUPPORTED - #define PNG_READ_INT_FUNCTIONS_SUPPORTED - #define PNG_READ_INVERT_ALPHA_SUPPORTED - #define PNG_READ_INVERT_SUPPORTED - #define PNG_READ_OPT_PLTE_SUPPORTED - #define PNG_READ_PACKSWAP_SUPPORTED - #define PNG_READ_PACK_SUPPORTED - #define PNG_READ_QUANTIZE_SUPPORTED - #define PNG_READ_RGB_TO_GRAY_SUPPORTED - #define PNG_READ_SCALE_16_TO_8_SUPPORTED - #define PNG_READ_SHIFT_SUPPORTED - #define PNG_READ_STRIP_16_TO_8_SUPPORTED - #define PNG_READ_STRIP_ALPHA_SUPPORTED - #define PNG_READ_SUPPORTED - #define PNG_READ_SWAP_ALPHA_SUPPORTED - #define PNG_READ_SWAP_SUPPORTED - #define PNG_READ_TEXT_SUPPORTED - #define PNG_READ_TRANSFORMS_SUPPORTED - #define PNG_READ_UNKNOWN_CHUNKS_SUPPORTED - #define PNG_READ_USER_CHUNKS_SUPPORTED - #define PNG_READ_USER_TRANSFORM_SUPPORTED - #define PNG_READ_bKGD_SUPPORTED - #define PNG_READ_cHRM_SUPPORTED - #define PNG_READ_gAMA_SUPPORTED - #define PNG_READ_hIST_SUPPORTED - #define PNG_READ_iCCP_SUPPORTED - #define PNG_READ_iTXt_SUPPORTED - #define PNG_READ_oFFs_SUPPORTED - #define PNG_READ_pCAL_SUPPORTED - #define PNG_READ_pHYs_SUPPORTED - #define PNG_READ_sBIT_SUPPORTED - #define PNG_READ_sCAL_SUPPORTED - #define PNG_READ_sPLT_SUPPORTED - #define PNG_READ_sRGB_SUPPORTED - #define PNG_READ_tEXt_SUPPORTED - #define PNG_READ_tIME_SUPPORTED - #define PNG_READ_tRNS_SUPPORTED - #define PNG_READ_zTXt_SUPPORTED - #define PNG_SAVE_INT_32_SUPPORTED - #define PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED - #define PNG_SEQUENTIAL_READ_SUPPORTED - #define PNG_SET_CHUNK_CACHE_LIMIT_SUPPORTED - #define PNG_SET_CHUNK_MALLOC_LIMIT_SUPPORTED - #define PNG_SET_UNKNOWN_CHUNKS_SUPPORTED - #define PNG_SET_USER_LIMITS_SUPPORTED - #define PNG_SIMPLIFIED_READ_AFIRST_SUPPORTED - #define PNG_SIMPLIFIED_READ_BGR_SUPPORTED - #define PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED - #define PNG_SIMPLIFIED_WRITE_BGR_SUPPORTED - #define PNG_STDIO_SUPPORTED - #define PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED - #define PNG_TEXT_SUPPORTED - #define PNG_TIME_RFC1123_SUPPORTED - #define PNG_UNKNOWN_CHUNKS_SUPPORTED - #define PNG_USER_CHUNKS_SUPPORTED - #define PNG_USER_LIMITS_SUPPORTED - #define PNG_USER_TRANSFORM_INFO_SUPPORTED - #define PNG_USER_TRANSFORM_PTR_SUPPORTED - #define PNG_WARNINGS_SUPPORTED - #define PNG_WRITE_16BIT_SUPPORTED - #define PNG_WRITE_ANCILLARY_CHUNKS_SUPPORTED - #define PNG_WRITE_BGR_SUPPORTED - #define PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED - #define PNG_WRITE_COMPRESSED_TEXT_SUPPORTED - #define PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED - #define PNG_WRITE_FILLER_SUPPORTED - #define PNG_WRITE_FILTER_SUPPORTED - #define PNG_WRITE_FLUSH_SUPPORTED - #define PNG_WRITE_GET_PALETTE_MAX_SUPPORTED - #define PNG_WRITE_INTERLACING_SUPPORTED - #define PNG_WRITE_INT_FUNCTIONS_SUPPORTED - #define PNG_WRITE_INVERT_ALPHA_SUPPORTED - #define PNG_WRITE_INVERT_SUPPORTED - #define PNG_WRITE_OPTIMIZE_CMF_SUPPORTED - #define PNG_WRITE_PACKSWAP_SUPPORTED - #define PNG_WRITE_PACK_SUPPORTED - #define PNG_WRITE_SHIFT_SUPPORTED - #define PNG_WRITE_SUPPORTED - #define PNG_WRITE_SWAP_ALPHA_SUPPORTED - #define PNG_WRITE_SWAP_SUPPORTED - #define PNG_WRITE_TEXT_SUPPORTED - #define PNG_WRITE_TRANSFORMS_SUPPORTED - #define PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED - #define PNG_WRITE_USER_TRANSFORM_SUPPORTED - #define PNG_WRITE_WEIGHTED_FILTER_SUPPORTED - #define PNG_WRITE_bKGD_SUPPORTED - #define PNG_WRITE_cHRM_SUPPORTED - #define PNG_WRITE_gAMA_SUPPORTED - #define PNG_WRITE_hIST_SUPPORTED - #define PNG_WRITE_iCCP_SUPPORTED - #define PNG_WRITE_iTXt_SUPPORTED - #define PNG_WRITE_oFFs_SUPPORTED - #define PNG_WRITE_pCAL_SUPPORTED - #define PNG_WRITE_pHYs_SUPPORTED - #define PNG_WRITE_sBIT_SUPPORTED - #define PNG_WRITE_sCAL_SUPPORTED - #define PNG_WRITE_sPLT_SUPPORTED - #define PNG_WRITE_sRGB_SUPPORTED - #define PNG_WRITE_tEXt_SUPPORTED - #define PNG_WRITE_tIME_SUPPORTED - #define PNG_WRITE_tRNS_SUPPORTED - #define PNG_WRITE_zTXt_SUPPORTED - #define PNG_bKGD_SUPPORTED - #define PNG_cHRM_SUPPORTED - #define PNG_gAMA_SUPPORTED - #define PNG_hIST_SUPPORTED - #define PNG_iCCP_SUPPORTED - #define PNG_iTXt_SUPPORTED - #define PNG_oFFs_SUPPORTED - #define PNG_pCAL_SUPPORTED - #define PNG_pHYs_SUPPORTED - #define PNG_sBIT_SUPPORTED - #define PNG_sCAL_SUPPORTED - #define PNG_sPLT_SUPPORTED - #define PNG_sRGB_SUPPORTED - #define PNG_tEXt_SUPPORTED - #define PNG_tIME_SUPPORTED - #define PNG_tRNS_SUPPORTED - #define PNG_zTXt_SUPPORTED - - #define PNG_STRING_COPYRIGHT ""; - #define PNG_STRING_NEWLINE "\n" - #define PNG_LITERAL_SHARP 0x23 - #define PNG_LITERAL_LEFT_SQUARE_BRACKET 0x5b - #define PNG_LITERAL_RIGHT_SQUARE_BRACKET 0x5d - - #define PNG_API_RULE 0 - #define PNG_CALLOC_SUPPORTED - #define PNG_COST_SHIFT 3 - #define PNG_DEFAULT_READ_MACROS 1 - #define PNG_GAMMA_THRESHOLD_FIXED 5000 - #define PNG_IDAT_READ_SIZE PNG_ZBUF_SIZE - #define PNG_INFLATE_BUF_SIZE 1024 - #define PNG_MAX_GAMMA_8 11 - #define PNG_QUANTIZE_BLUE_BITS 5 - #define PNG_QUANTIZE_GREEN_BITS 5 - #define PNG_QUANTIZE_RED_BITS 5 - #define PNG_TEXT_Z_DEFAULT_COMPRESSION (-1) - #define PNG_TEXT_Z_DEFAULT_STRATEGY 0 - #define PNG_WEIGHT_SHIFT 8 - #define PNG_ZBUF_SIZE 8192 - #define PNG_Z_DEFAULT_COMPRESSION (-1) - #define PNG_Z_DEFAULT_NOFILTER_STRATEGY 0 - #define PNG_Z_DEFAULT_STRATEGY 1 - #define PNG_sCAL_PRECISION 5 - #define PNG_sRGB_PROFILE_CHECKS 2 - - #define png_debug(a, b) - #define png_debug1(a, b, c) - #define png_debug2(a, b, c, d) - - #include "pnglib/png.h" - #include "pnglib/pngconf.h" - - #define PNG_NO_EXTERN - #include "pnglib/png.c" - #include "pnglib/pngerror.c" - #include "pnglib/pngget.c" - #include "pnglib/pngmem.c" - #include "pnglib/pngread.c" - #include "pnglib/pngpread.c" - #include "pnglib/pngrio.c" - #include "pnglib/pngrtran.c" - #include "pnglib/pngrutil.c" - #include "pnglib/pngset.c" - #include "pnglib/pngtrans.c" - #include "pnglib/pngwio.c" - #include "pnglib/pngwrite.c" - #include "pnglib/pngwtran.c" - #include "pnglib/pngwutil.c" - - #if JUCE_CLANG - #pragma clang diagnostic pop - #endif -#else - extern "C" - { - #include - #include - } -#endif -} - -#undef max -#undef min -#undef fdopen - -#if JUCE_MSVC - #pragma warning (pop) -#endif - -//============================================================================== -namespace PNGHelpers -{ - using namespace pnglibNamespace; - - static void JUCE_CDECL writeDataCallback (png_structp png, png_bytep data, png_size_t length) - { - static_cast (png_get_io_ptr (png))->write (data, length); - } - - #if ! JUCE_USING_COREIMAGE_LOADER - static void JUCE_CDECL readCallback (png_structp png, png_bytep data, png_size_t length) - { - static_cast (png_get_io_ptr (png))->read (data, (int) length); - } - - struct PNGErrorStruct {}; - - static void JUCE_CDECL errorCallback (png_structp, png_const_charp) - { - throw PNGErrorStruct(); - } - - static void JUCE_CDECL warningCallback (png_structp, png_const_charp) {} - #endif -} - -//============================================================================== -PNGImageFormat::PNGImageFormat() {} -PNGImageFormat::~PNGImageFormat() {} - -String PNGImageFormat::getFormatName() { return "PNG"; } -bool PNGImageFormat::usesFileExtension (const File& f) { return f.hasFileExtension ("png"); } - -bool PNGImageFormat::canUnderstand (InputStream& in) -{ - const int bytesNeeded = 4; - char header [bytesNeeded]; - - return in.read (header, bytesNeeded) == bytesNeeded - && header[1] == 'P' - && header[2] == 'N' - && header[3] == 'G'; -} - -#if JUCE_USING_COREIMAGE_LOADER - Image juce_loadWithCoreImage (InputStream& input); -#endif - -Image PNGImageFormat::decodeImage (InputStream& in) -{ -#if JUCE_USING_COREIMAGE_LOADER - return juce_loadWithCoreImage (in); -#else - using namespace pnglibNamespace; - Image image; - - if (png_structp pngReadStruct = png_create_read_struct (PNG_LIBPNG_VER_STRING, 0, 0, 0)) - { - try - { - png_infop pngInfoStruct = png_create_info_struct (pngReadStruct); - - if (pngInfoStruct == nullptr) - { - png_destroy_read_struct (&pngReadStruct, 0, 0); - return Image::null; - } - - png_set_error_fn (pngReadStruct, 0, PNGHelpers::errorCallback, PNGHelpers::warningCallback); - - // read the header.. - png_set_read_fn (pngReadStruct, &in, PNGHelpers::readCallback); - - png_uint_32 width = 0, height = 0; - int bitDepth = 0, colorType = 0, interlaceType; - - png_read_info (pngReadStruct, pngInfoStruct); - - png_get_IHDR (pngReadStruct, pngInfoStruct, - &width, &height, - &bitDepth, &colorType, - &interlaceType, 0, 0); - - if (bitDepth == 16) - png_set_strip_16 (pngReadStruct); - - if (colorType == PNG_COLOR_TYPE_PALETTE) - png_set_expand (pngReadStruct); - - if (bitDepth < 8) - png_set_expand (pngReadStruct); - - if (png_get_valid (pngReadStruct, pngInfoStruct, PNG_INFO_tRNS)) - png_set_expand (pngReadStruct); - - if (colorType == PNG_COLOR_TYPE_GRAY || colorType == PNG_COLOR_TYPE_GRAY_ALPHA) - png_set_gray_to_rgb (pngReadStruct); - - png_set_add_alpha (pngReadStruct, 0xff, PNG_FILLER_AFTER); - - bool hasAlphaChan = (colorType & PNG_COLOR_MASK_ALPHA) != 0 - || pngInfoStruct->num_trans > 0; - - // Load the image into a temp buffer in the pnglib format.. - const size_t lineStride = width * 4; - HeapBlock tempBuffer (height * lineStride); - - HeapBlock rows (height); - for (size_t y = 0; y < height; ++y) - rows[y] = (png_bytep) (tempBuffer + lineStride * y); - - try - { - png_read_image (pngReadStruct, rows); - png_read_end (pngReadStruct, pngInfoStruct); - } - catch (PNGHelpers::PNGErrorStruct&) - {} - - png_destroy_read_struct (&pngReadStruct, &pngInfoStruct, 0); - - // now convert the data to a juce image format.. - image = Image (hasAlphaChan ? Image::ARGB : Image::RGB, - (int) width, (int) height, hasAlphaChan); - - image.getProperties()->set ("originalImageHadAlpha", image.hasAlphaChannel()); - hasAlphaChan = image.hasAlphaChannel(); // (the native image creator may not give back what we expect) - - const Image::BitmapData destData (image, Image::BitmapData::writeOnly); - - for (int y = 0; y < (int) height; ++y) - { - const uint8* src = rows[y]; - uint8* dest = destData.getLinePointer (y); - - if (hasAlphaChan) - { - for (int i = (int) width; --i >= 0;) - { - ((PixelARGB*) dest)->setARGB (src[3], src[0], src[1], src[2]); - ((PixelARGB*) dest)->premultiply(); - dest += destData.pixelStride; - src += 4; - } - } - else - { - for (int i = (int) width; --i >= 0;) - { - ((PixelRGB*) dest)->setARGB (0, src[0], src[1], src[2]); - dest += destData.pixelStride; - src += 4; - } - } - } - } - catch (PNGHelpers::PNGErrorStruct&) - {} - } - - return image; -#endif -} - -bool PNGImageFormat::writeImageToStream (const Image& image, OutputStream& out) -{ - using namespace pnglibNamespace; - const int width = image.getWidth(); - const int height = image.getHeight(); - - png_structp pngWriteStruct = png_create_write_struct (PNG_LIBPNG_VER_STRING, 0, 0, 0); - - if (pngWriteStruct == nullptr) - return false; - - png_infop pngInfoStruct = png_create_info_struct (pngWriteStruct); - - if (pngInfoStruct == nullptr) - { - png_destroy_write_struct (&pngWriteStruct, (png_infopp) nullptr); - return false; - } - - png_set_write_fn (pngWriteStruct, &out, PNGHelpers::writeDataCallback, 0); - - png_set_IHDR (pngWriteStruct, pngInfoStruct, (png_uint_32) width, (png_uint_32) height, 8, - image.hasAlphaChannel() ? PNG_COLOR_TYPE_RGB_ALPHA - : PNG_COLOR_TYPE_RGB, - PNG_INTERLACE_NONE, - PNG_COMPRESSION_TYPE_BASE, - PNG_FILTER_TYPE_BASE); - - HeapBlock rowData ((size_t) width * 4); - - png_color_8 sig_bit; - sig_bit.red = 8; - sig_bit.green = 8; - sig_bit.blue = 8; - sig_bit.gray = 0; - sig_bit.alpha = 8; - png_set_sBIT (pngWriteStruct, pngInfoStruct, &sig_bit); - - png_write_info (pngWriteStruct, pngInfoStruct); - - png_set_shift (pngWriteStruct, &sig_bit); - png_set_packing (pngWriteStruct); - - const Image::BitmapData srcData (image, Image::BitmapData::readOnly); - - for (int y = 0; y < height; ++y) - { - uint8* dst = rowData; - const uint8* src = srcData.getLinePointer (y); - - if (image.hasAlphaChannel()) - { - for (int i = width; --i >= 0;) - { - PixelARGB p (*(const PixelARGB*) src); - p.unpremultiply(); - - *dst++ = p.getRed(); - *dst++ = p.getGreen(); - *dst++ = p.getBlue(); - *dst++ = p.getAlpha(); - src += srcData.pixelStride; - } - } - else - { - for (int i = width; --i >= 0;) - { - *dst++ = ((const PixelRGB*) src)->getRed(); - *dst++ = ((const PixelRGB*) src)->getGreen(); - *dst++ = ((const PixelRGB*) src)->getBlue(); - src += srcData.pixelStride; - } - } - - png_bytep rowPtr = rowData; - png_write_rows (pngWriteStruct, &rowPtr, 1); - } - - png_write_end (pngWriteStruct, pngInfoStruct); - png_destroy_write_struct (&pngWriteStruct, &pngInfoStruct); - - return true; -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/images/juce_Image.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/images/juce_Image.cpp deleted file mode 100644 index e7be9a3f47..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/images/juce_Image.cpp +++ /dev/null @@ -1,659 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -ImagePixelData::ImagePixelData (const Image::PixelFormat format, const int w, const int h) - : pixelFormat (format), width (w), height (h) -{ - jassert (format == Image::RGB || format == Image::ARGB || format == Image::SingleChannel); - jassert (w > 0 && h > 0); // It's illegal to create a zero-sized image! -} - -ImagePixelData::~ImagePixelData() -{ - listeners.call (&Listener::imageDataBeingDeleted, this); -} - -void ImagePixelData::sendDataChangeMessage() -{ - listeners.call (&Listener::imageDataChanged, this); -} - -//============================================================================== -ImageType::ImageType() {} -ImageType::~ImageType() {} - -Image ImageType::convert (const Image& source) const -{ - if (source.isNull() || getTypeID() == (ScopedPointer (source.getPixelData()->createType())->getTypeID())) - return source; - - const Image::BitmapData src (source, Image::BitmapData::readOnly); - - Image newImage (create (src.pixelFormat, src.width, src.height, false)); - Image::BitmapData dest (newImage, Image::BitmapData::writeOnly); - - jassert (src.pixelStride == dest.pixelStride && src.pixelFormat == dest.pixelFormat); - - for (int y = 0; y < dest.height; ++y) - memcpy (dest.getLinePointer (y), src.getLinePointer (y), (size_t) dest.lineStride); - - return newImage; -} - -//============================================================================== -class SoftwarePixelData : public ImagePixelData -{ -public: - SoftwarePixelData (const Image::PixelFormat format_, const int w, const int h, const bool clearImage) - : ImagePixelData (format_, w, h), - pixelStride (format_ == Image::RGB ? 3 : ((format_ == Image::ARGB) ? 4 : 1)), - lineStride ((pixelStride * jmax (1, w) + 3) & ~3) - { - imageData.allocate ((size_t) (lineStride * jmax (1, h)), clearImage); - } - - LowLevelGraphicsContext* createLowLevelContext() override - { - sendDataChangeMessage(); - return new LowLevelGraphicsSoftwareRenderer (Image (this)); - } - - void initialiseBitmapData (Image::BitmapData& bitmap, int x, int y, Image::BitmapData::ReadWriteMode mode) override - { - bitmap.data = imageData + x * pixelStride + y * lineStride; - bitmap.pixelFormat = pixelFormat; - bitmap.lineStride = lineStride; - bitmap.pixelStride = pixelStride; - - if (mode != Image::BitmapData::readOnly) - sendDataChangeMessage(); - } - - ImagePixelData* clone() override - { - SoftwarePixelData* s = new SoftwarePixelData (pixelFormat, width, height, false); - memcpy (s->imageData, imageData, (size_t) (lineStride * height)); - return s; - } - - ImageType* createType() const override { return new SoftwareImageType(); } - -private: - HeapBlock imageData; - const int pixelStride, lineStride; - - JUCE_LEAK_DETECTOR (SoftwarePixelData) -}; - -SoftwareImageType::SoftwareImageType() {} -SoftwareImageType::~SoftwareImageType() {} - -ImagePixelData::Ptr SoftwareImageType::create (Image::PixelFormat format, int width, int height, bool clearImage) const -{ - return new SoftwarePixelData (format, width, height, clearImage); -} - -int SoftwareImageType::getTypeID() const -{ - return 2; -} - -//============================================================================== -NativeImageType::NativeImageType() {} -NativeImageType::~NativeImageType() {} - -int NativeImageType::getTypeID() const -{ - return 1; -} - -#if JUCE_WINDOWS || JUCE_LINUX -ImagePixelData::Ptr NativeImageType::create (Image::PixelFormat format, int width, int height, bool clearImage) const -{ - return new SoftwarePixelData (format, width, height, clearImage); -} -#endif - -//============================================================================== -class SubsectionPixelData : public ImagePixelData -{ -public: - SubsectionPixelData (ImagePixelData* const im, const Rectangle& r) - : ImagePixelData (im->pixelFormat, r.getWidth(), r.getHeight()), - image (im), area (r) - { - } - - LowLevelGraphicsContext* createLowLevelContext() override - { - LowLevelGraphicsContext* g = image->createLowLevelContext(); - g->clipToRectangle (area); - g->setOrigin (area.getPosition()); - return g; - } - - void initialiseBitmapData (Image::BitmapData& bitmap, int x, int y, Image::BitmapData::ReadWriteMode mode) override - { - image->initialiseBitmapData (bitmap, x + area.getX(), y + area.getY(), mode); - - if (mode != Image::BitmapData::readOnly) - sendDataChangeMessage(); - } - - ImagePixelData* clone() override - { - jassert (getReferenceCount() > 0); // (This method can't be used on an unowned pointer, as it will end up self-deleting) - const ScopedPointer type (image->createType()); - - Image newImage (type->create (pixelFormat, area.getWidth(), area.getHeight(), pixelFormat != Image::RGB)); - - { - Graphics g (newImage); - g.drawImageAt (Image (this), 0, 0); - } - - newImage.getPixelData()->incReferenceCount(); - return newImage.getPixelData(); - } - - ImageType* createType() const override { return image->createType(); } - -private: - const ImagePixelData::Ptr image; - const Rectangle area; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (SubsectionPixelData) -}; - -Image Image::getClippedImage (const Rectangle& area) const -{ - if (area.contains (getBounds())) - return *this; - - const Rectangle validArea (area.getIntersection (getBounds())); - return Image (validArea.isEmpty() ? nullptr : new SubsectionPixelData (image, validArea)); -} - - -//============================================================================== -Image::Image() noexcept -{ -} - -Image::Image (ImagePixelData* const instance) noexcept - : image (instance) -{ -} - -Image::Image (const PixelFormat format, int width, int height, bool clearImage) - : image (NativeImageType().create (format, width, height, clearImage)) -{ -} - -Image::Image (const PixelFormat format, int width, int height, bool clearImage, const ImageType& type) - : image (type.create (format, width, height, clearImage)) -{ -} - -Image::Image (const Image& other) noexcept - : image (other.image) -{ -} - -Image& Image::operator= (const Image& other) -{ - image = other.image; - return *this; -} - -#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS -Image::Image (Image&& other) noexcept - : image (static_cast (other.image)) -{ -} - -Image& Image::operator= (Image&& other) noexcept -{ - image = static_cast (other.image); - return *this; -} -#endif - -Image::~Image() -{ -} - -const Image Image::null; - -int Image::getReferenceCount() const noexcept { return image == nullptr ? 0 : image->getReferenceCount(); } -int Image::getWidth() const noexcept { return image == nullptr ? 0 : image->width; } -int Image::getHeight() const noexcept { return image == nullptr ? 0 : image->height; } -Rectangle Image::getBounds() const noexcept { return image == nullptr ? Rectangle() : Rectangle (image->width, image->height); } -Image::PixelFormat Image::getFormat() const noexcept { return image == nullptr ? UnknownFormat : image->pixelFormat; } -bool Image::isARGB() const noexcept { return getFormat() == ARGB; } -bool Image::isRGB() const noexcept { return getFormat() == RGB; } -bool Image::isSingleChannel() const noexcept { return getFormat() == SingleChannel; } -bool Image::hasAlphaChannel() const noexcept { return getFormat() != RGB; } - -LowLevelGraphicsContext* Image::createLowLevelContext() const -{ - return image == nullptr ? nullptr : image->createLowLevelContext(); -} - -void Image::duplicateIfShared() -{ - if (image != nullptr && image->getReferenceCount() > 1) - image = image->clone(); -} - -Image Image::createCopy() const -{ - if (image != nullptr) - return Image (image->clone()); - - return Image(); -} - -Image Image::rescaled (const int newWidth, const int newHeight, const Graphics::ResamplingQuality quality) const -{ - if (image == nullptr || (image->width == newWidth && image->height == newHeight)) - return *this; - - const ScopedPointer type (image->createType()); - Image newImage (type->create (image->pixelFormat, newWidth, newHeight, hasAlphaChannel())); - - Graphics g (newImage); - g.setImageResamplingQuality (quality); - g.drawImageTransformed (*this, AffineTransform::scale (newWidth / (float) image->width, - newHeight / (float) image->height), false); - return newImage; -} - -Image Image::convertedToFormat (PixelFormat newFormat) const -{ - if (image == nullptr || newFormat == image->pixelFormat) - return *this; - - const int w = image->width, h = image->height; - - const ScopedPointer type (image->createType()); - Image newImage (type->create (newFormat, w, h, false)); - - if (newFormat == SingleChannel) - { - if (! hasAlphaChannel()) - { - newImage.clear (getBounds(), Colours::black); - } - else - { - const BitmapData destData (newImage, 0, 0, w, h, BitmapData::writeOnly); - const BitmapData srcData (*this, 0, 0, w, h); - - for (int y = 0; y < h; ++y) - { - const PixelARGB* const src = (const PixelARGB*) srcData.getLinePointer (y); - uint8* const dst = destData.getLinePointer (y); - - for (int x = 0; x < w; ++x) - dst[x] = src[x].getAlpha(); - } - } - } - else if (image->pixelFormat == SingleChannel && newFormat == Image::ARGB) - { - const BitmapData destData (newImage, 0, 0, w, h, BitmapData::writeOnly); - const BitmapData srcData (*this, 0, 0, w, h); - - for (int y = 0; y < h; ++y) - { - const PixelAlpha* const src = (const PixelAlpha*) srcData.getLinePointer (y); - PixelARGB* const dst = (PixelARGB*) destData.getLinePointer (y); - - for (int x = 0; x < w; ++x) - dst[x].set (src[x]); - } - } - else - { - if (hasAlphaChannel()) - newImage.clear (getBounds()); - - Graphics g (newImage); - g.drawImageAt (*this, 0, 0); - } - - return newImage; -} - -NamedValueSet* Image::getProperties() const -{ - return image == nullptr ? nullptr : &(image->userData); -} - -//============================================================================== -Image::BitmapData::BitmapData (Image& im, const int x, const int y, const int w, const int h, BitmapData::ReadWriteMode mode) - : width (w), height (h) -{ - // The BitmapData class must be given a valid image, and a valid rectangle within it! - jassert (im.image != nullptr); - jassert (x >= 0 && y >= 0 && w > 0 && h > 0 && x + w <= im.getWidth() && y + h <= im.getHeight()); - - im.image->initialiseBitmapData (*this, x, y, mode); - jassert (data != nullptr && pixelStride > 0 && lineStride != 0); -} - -Image::BitmapData::BitmapData (const Image& im, const int x, const int y, const int w, const int h) - : width (w), height (h) -{ - // The BitmapData class must be given a valid image, and a valid rectangle within it! - jassert (im.image != nullptr); - jassert (x >= 0 && y >= 0 && w > 0 && h > 0 && x + w <= im.getWidth() && y + h <= im.getHeight()); - - im.image->initialiseBitmapData (*this, x, y, readOnly); - jassert (data != nullptr && pixelStride > 0 && lineStride != 0); -} - -Image::BitmapData::BitmapData (const Image& im, BitmapData::ReadWriteMode mode) - : width (im.getWidth()), - height (im.getHeight()) -{ - // The BitmapData class must be given a valid image! - jassert (im.image != nullptr); - - im.image->initialiseBitmapData (*this, 0, 0, mode); - jassert (data != nullptr && pixelStride > 0 && lineStride != 0); -} - -Image::BitmapData::~BitmapData() -{ -} - -Colour Image::BitmapData::getPixelColour (const int x, const int y) const noexcept -{ - jassert (isPositiveAndBelow (x, width) && isPositiveAndBelow (y, height)); - - const uint8* const pixel = getPixelPointer (x, y); - - switch (pixelFormat) - { - case Image::ARGB: return Colour (((const PixelARGB*) pixel)->getUnpremultipliedARGB()); - case Image::RGB: return Colour (((const PixelRGB*) pixel)->getUnpremultipliedARGB()); - case Image::SingleChannel: return Colour (((const PixelAlpha*) pixel)->getUnpremultipliedARGB()); - default: jassertfalse; break; - } - - return Colour(); -} - -void Image::BitmapData::setPixelColour (const int x, const int y, Colour colour) const noexcept -{ - jassert (isPositiveAndBelow (x, width) && isPositiveAndBelow (y, height)); - - uint8* const pixel = getPixelPointer (x, y); - const PixelARGB col (colour.getPixelARGB()); - - switch (pixelFormat) - { - case Image::ARGB: ((PixelARGB*) pixel)->set (col); break; - case Image::RGB: ((PixelRGB*) pixel)->set (col); break; - case Image::SingleChannel: ((PixelAlpha*) pixel)->set (col); break; - default: jassertfalse; break; - } -} - -//============================================================================== -void Image::clear (const Rectangle& area, Colour colourToClearTo) -{ - const ScopedPointer g (image->createLowLevelContext()); - g->setFill (colourToClearTo); - g->fillRect (area, true); -} - -//============================================================================== -Colour Image::getPixelAt (const int x, const int y) const -{ - if (isPositiveAndBelow (x, getWidth()) && isPositiveAndBelow (y, getHeight())) - { - const BitmapData srcData (*this, x, y, 1, 1); - return srcData.getPixelColour (0, 0); - } - - return Colour(); -} - -void Image::setPixelAt (const int x, const int y, Colour colour) -{ - if (isPositiveAndBelow (x, getWidth()) && isPositiveAndBelow (y, getHeight())) - { - const BitmapData destData (*this, x, y, 1, 1, BitmapData::writeOnly); - destData.setPixelColour (0, 0, colour); - } -} - -void Image::multiplyAlphaAt (const int x, const int y, const float multiplier) -{ - if (isPositiveAndBelow (x, getWidth()) && isPositiveAndBelow (y, getHeight()) - && hasAlphaChannel()) - { - const BitmapData destData (*this, x, y, 1, 1, BitmapData::readWrite); - - if (isARGB()) - ((PixelARGB*) destData.data)->multiplyAlpha (multiplier); - else - *(destData.data) = (uint8) (*(destData.data) * multiplier); - } -} - -template -struct PixelIterator -{ - template - static void iterate (const Image::BitmapData& data, const PixelOperation& pixelOp) - { - for (int y = 0; y < data.height; ++y) - { - uint8* p = data.getLinePointer (y); - - for (int x = 0; x < data.width; ++x) - { - pixelOp (*(PixelType*) p); - p += data.pixelStride; - } - } - } -}; - -template -static void performPixelOp (const Image::BitmapData& data, const PixelOperation& pixelOp) -{ - switch (data.pixelFormat) - { - case Image::ARGB: PixelIterator ::iterate (data, pixelOp); break; - case Image::RGB: PixelIterator ::iterate (data, pixelOp); break; - case Image::SingleChannel: PixelIterator::iterate (data, pixelOp); break; - default: jassertfalse; break; - } -} - -struct AlphaMultiplyOp -{ - AlphaMultiplyOp (float alpha_) noexcept : alpha (alpha_) {} - - const float alpha; - - template - void operator() (PixelType& pixel) const - { - pixel.multiplyAlpha (alpha); - } - - JUCE_DECLARE_NON_COPYABLE (AlphaMultiplyOp) -}; - -void Image::multiplyAllAlphas (const float amountToMultiplyBy) -{ - jassert (hasAlphaChannel()); - - const BitmapData destData (*this, 0, 0, getWidth(), getHeight(), BitmapData::readWrite); - performPixelOp (destData, AlphaMultiplyOp (amountToMultiplyBy)); -} - -struct DesaturateOp -{ - template - void operator() (PixelType& pixel) const - { - pixel.desaturate(); - } -}; - -void Image::desaturate() -{ - if (isARGB() || isRGB()) - { - const BitmapData destData (*this, 0, 0, getWidth(), getHeight(), BitmapData::readWrite); - performPixelOp (destData, DesaturateOp()); - } -} - -void Image::createSolidAreaMask (RectangleList& result, const float alphaThreshold) const -{ - if (hasAlphaChannel()) - { - const uint8 threshold = (uint8) jlimit (0, 255, roundToInt (alphaThreshold * 255.0f)); - SparseSet pixelsOnRow; - - const BitmapData srcData (*this, 0, 0, getWidth(), getHeight()); - - for (int y = 0; y < srcData.height; ++y) - { - pixelsOnRow.clear(); - const uint8* lineData = srcData.getLinePointer (y); - - if (isARGB()) - { - for (int x = 0; x < srcData.width; ++x) - { - if (((const PixelARGB*) lineData)->getAlpha() >= threshold) - pixelsOnRow.addRange (Range (x, x + 1)); - - lineData += srcData.pixelStride; - } - } - else - { - for (int x = 0; x < srcData.width; ++x) - { - if (*lineData >= threshold) - pixelsOnRow.addRange (Range (x, x + 1)); - - lineData += srcData.pixelStride; - } - } - - for (int i = 0; i < pixelsOnRow.getNumRanges(); ++i) - { - const Range range (pixelsOnRow.getRange (i)); - result.add (Rectangle (range.getStart(), y, range.getLength(), 1)); - } - - result.consolidate(); - } - } - else - { - result.add (0, 0, getWidth(), getHeight()); - } -} - -void Image::moveImageSection (int dx, int dy, - int sx, int sy, - int w, int h) -{ - if (dx < 0) - { - w += dx; - sx -= dx; - dx = 0; - } - - if (dy < 0) - { - h += dy; - sy -= dy; - dy = 0; - } - - if (sx < 0) - { - w += sx; - dx -= sx; - sx = 0; - } - - if (sy < 0) - { - h += sy; - dy -= sy; - sy = 0; - } - - const int minX = jmin (dx, sx); - const int minY = jmin (dy, sy); - - w = jmin (w, getWidth() - jmax (sx, dx)); - h = jmin (h, getHeight() - jmax (sy, dy)); - - if (w > 0 && h > 0) - { - const int maxX = jmax (dx, sx) + w; - const int maxY = jmax (dy, sy) + h; - - const BitmapData destData (*this, minX, minY, maxX - minX, maxY - minY, BitmapData::readWrite); - - uint8* dst = destData.getPixelPointer (dx - minX, dy - minY); - const uint8* src = destData.getPixelPointer (sx - minX, sy - minY); - - const size_t lineSize = (size_t) (destData.pixelStride * w); - - if (dy > sy) - { - while (--h >= 0) - { - const int offset = h * destData.lineStride; - memmove (dst + offset, src + offset, lineSize); - } - } - else if (dst != src) - { - while (--h >= 0) - { - memmove (dst, src, lineSize); - dst += destData.lineStride; - src += destData.lineStride; - } - } - } -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/images/juce_Image.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/images/juce_Image.h deleted file mode 100644 index 0f67b4eefe..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/images/juce_Image.h +++ /dev/null @@ -1,533 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_IMAGE_H_INCLUDED -#define JUCE_IMAGE_H_INCLUDED - -class ImageType; -class ImagePixelData; - - -//============================================================================== -/** - Holds a fixed-size bitmap. - - The image is stored in either 24-bit RGB or 32-bit premultiplied-ARGB format. - - To draw into an image, create a Graphics object for it. - e.g. @code - - // create a transparent 500x500 image.. - Image myImage (Image::RGB, 500, 500, true); - - Graphics g (myImage); - g.setColour (Colours::red); - g.fillEllipse (20, 20, 300, 200); // draws a red ellipse in our image. - @endcode - - Other useful ways to create an image are with the ImageCache class, or the - ImageFileFormat, which provides a way to load common image files. - - @see Graphics, ImageFileFormat, ImageCache, ImageConvolutionKernel -*/ -class JUCE_API Image -{ -public: - //============================================================================== - /** - */ - enum PixelFormat - { - UnknownFormat, - RGB, /**<< each pixel is a 3-byte packed RGB colour value. For byte order, see the PixelRGB class. */ - ARGB, /**<< each pixel is a 4-byte ARGB premultiplied colour value. For byte order, see the PixelARGB class. */ - SingleChannel /**<< each pixel is a 1-byte alpha channel value. */ - }; - - //============================================================================== - /** Creates a null image. */ - Image() noexcept; - - /** Creates an image with a specified size and format. - - The image's internal type will be of the NativeImageType class - to specify a - different type, use the other constructor, which takes an ImageType to use. - - @param format the number of colour channels in the image - @param imageWidth the desired width of the image, in pixels - this value must be - greater than zero (otherwise a width of 1 will be used) - @param imageHeight the desired width of the image, in pixels - this value must be - greater than zero (otherwise a height of 1 will be used) - @param clearImage if true, the image will initially be cleared to black (if it's RGB) - or transparent black (if it's ARGB). If false, the image may contain - junk initially, so you need to make sure you overwrite it thoroughly. - */ - Image (PixelFormat format, int imageWidth, int imageHeight, bool clearImage); - - /** Creates an image with a specified size and format. - - @param format the number of colour channels in the image - @param imageWidth the desired width of the image, in pixels - this value must be - greater than zero (otherwise a width of 1 will be used) - @param imageHeight the desired width of the image, in pixels - this value must be - greater than zero (otherwise a height of 1 will be used) - @param clearImage if true, the image will initially be cleared to black (if it's RGB) - or transparent black (if it's ARGB). If false, the image may contain - junk initially, so you need to make sure you overwrite it thoroughly. - @param type the type of image - this lets you specify the internal format that will - be used to allocate and manage the image data. - */ - Image (PixelFormat format, int imageWidth, int imageHeight, bool clearImage, const ImageType& type); - - /** Creates a shared reference to another image. - - This won't create a duplicate of the image - when Image objects are copied, they simply - point to the same shared image data. To make sure that an Image object has its own unique, - unshared internal data, call duplicateIfShared(). - */ - Image (const Image&) noexcept; - - /** Makes this image refer to the same underlying image as another object. - - This won't create a duplicate of the image - when Image objects are copied, they simply - point to the same shared image data. To make sure that an Image object has its own unique, - unshared internal data, call duplicateIfShared(). - */ - Image& operator= (const Image&); - - #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS - Image (Image&&) noexcept; - Image& operator= (Image&&) noexcept; - #endif - - /** Destructor. */ - ~Image(); - - /** Returns true if the two images are referring to the same internal, shared image. */ - bool operator== (const Image& other) const noexcept { return image == other.image; } - - /** Returns true if the two images are not referring to the same internal, shared image. */ - bool operator!= (const Image& other) const noexcept { return image != other.image; } - - /** Returns true if this image isn't null. - If you create an Image with the default constructor, it has no size or content, and is null - until you reassign it to an Image which contains some actual data. - The isNull() method is the opposite of isValid(). - @see isNull - */ - inline bool isValid() const noexcept { return image != nullptr; } - - /** Returns true if this image is not valid. - If you create an Image with the default constructor, it has no size or content, and is null - until you reassign it to an Image which contains some actual data. - The isNull() method is the opposite of isValid(). - @see isValid - */ - inline bool isNull() const noexcept { return image == nullptr; } - - /** A null Image object that can be used when you need to return an invalid image. - This object is the equivalient to an Image created with the default constructor. - */ - static const Image null; - - //============================================================================== - /** Returns the image's width (in pixels). */ - int getWidth() const noexcept; - - /** Returns the image's height (in pixels). */ - int getHeight() const noexcept; - - /** Returns a rectangle with the same size as this image. - The rectangle's origin is always (0, 0). - */ - Rectangle getBounds() const noexcept; - - /** Returns the image's pixel format. */ - PixelFormat getFormat() const noexcept; - - /** True if the image's format is ARGB. */ - bool isARGB() const noexcept; - - /** True if the image's format is RGB. */ - bool isRGB() const noexcept; - - /** True if the image's format is a single-channel alpha map. */ - bool isSingleChannel() const noexcept; - - /** True if the image contains an alpha-channel. */ - bool hasAlphaChannel() const noexcept; - - //============================================================================== - /** Clears a section of the image with a given colour. - - This won't do any alpha-blending - it just sets all pixels in the image to - the given colour (which may be non-opaque if the image has an alpha channel). - */ - void clear (const Rectangle& area, Colour colourToClearTo = Colour (0x00000000)); - - /** Returns a rescaled version of this image. - - A new image is returned which is a copy of this one, rescaled to the given size. - - Note that if the new size is identical to the existing image, this will just return - a reference to the original image, and won't actually create a duplicate. - */ - Image rescaled (int newWidth, int newHeight, - Graphics::ResamplingQuality quality = Graphics::mediumResamplingQuality) const; - - /** Creates a copy of this image. - Note that it's usually more efficient to use duplicateIfShared(), because it may not be necessary - to copy an image if nothing else is using it. - @see getReferenceCount - */ - Image createCopy() const; - - /** Returns a version of this image with a different image format. - - A new image is returned which has been converted to the specified format. - - Note that if the new format is no different to the current one, this will just return - a reference to the original image, and won't actually create a copy. - */ - Image convertedToFormat (PixelFormat newFormat) const; - - /** Makes sure that no other Image objects share the same underlying data as this one. - - If no other Image objects refer to the same shared data as this one, this method has no - effect. But if there are other references to the data, this will create a new copy of - the data internally. - - Call this if you want to draw onto the image, but want to make sure that this doesn't - affect any other code that may be sharing the same data. - - @see getReferenceCount - */ - void duplicateIfShared(); - - /** Returns an image which refers to a subsection of this image. - - This will not make a copy of the original - the new image will keep a reference to it, so that - if the original image is changed, the contents of the subsection will also change. Likewise if you - draw into the subimage, you'll also be drawing onto that area of the original image. Note that if - you use operator= to make the original Image object refer to something else, the subsection image - won't pick up this change, it'll remain pointing at the original. - - The area passed-in will be clipped to the bounds of this image, so this may return a smaller - image than the area you asked for, or even a null image if the area was out-of-bounds. - */ - Image getClippedImage (const Rectangle& area) const; - - //============================================================================== - /** Returns the colour of one of the pixels in the image. - - If the coordinates given are beyond the image's boundaries, this will - return Colours::transparentBlack. - - @see setPixelAt, Image::BitmapData::getPixelColour - */ - Colour getPixelAt (int x, int y) const; - - /** Sets the colour of one of the image's pixels. - - If the coordinates are beyond the image's boundaries, then nothing will happen. - - Note that this won't do any alpha-blending, it'll just replace the existing pixel - with the given one. The colour's opacity will be ignored if this image doesn't have - an alpha-channel. - - @see getPixelAt, Image::BitmapData::setPixelColour - */ - void setPixelAt (int x, int y, Colour colour); - - /** Changes the opacity of a pixel. - - This only has an effect if the image has an alpha channel and if the - given coordinates are inside the image's boundary. - - The multiplier must be in the range 0 to 1.0, and the current alpha - at the given coordinates will be multiplied by this value. - - @see setPixelAt - */ - void multiplyAlphaAt (int x, int y, float multiplier); - - /** Changes the overall opacity of the image. - - This will multiply the alpha value of each pixel in the image by the given - amount (limiting the resulting alpha values between 0 and 255). This allows - you to make an image more or less transparent. - - If the image doesn't have an alpha channel, this won't have any effect. - */ - void multiplyAllAlphas (float amountToMultiplyBy); - - /** Changes all the colours to be shades of grey, based on their current luminosity. - */ - void desaturate(); - - //============================================================================== - /** Retrieves a section of an image as raw pixel data, so it can be read or written to. - - You should only use this class as a last resort - messing about with the internals of - an image is only recommended for people who really know what they're doing! - - A BitmapData object should be used as a temporary, stack-based object. Don't keep one - hanging around while the image is being used elsewhere. - - Depending on the way the image class is implemented, this may create a temporary buffer - which is copied back to the image when the object is deleted, or it may just get a pointer - directly into the image's raw data. - - You can use the stride and data values in this class directly, but don't alter them! - The actual format of the pixel data depends on the image's format - see Image::getFormat(), - and the PixelRGB, PixelARGB and PixelAlpha classes for more info. - */ - class JUCE_API BitmapData - { - public: - enum ReadWriteMode - { - readOnly, - writeOnly, - readWrite - }; - - BitmapData (Image& image, int x, int y, int w, int h, ReadWriteMode mode); - BitmapData (const Image& image, int x, int y, int w, int h); - BitmapData (const Image& image, ReadWriteMode mode); - ~BitmapData(); - - /** Returns a pointer to the start of a line in the image. - The coordinate you provide here isn't checked, so it's the caller's responsibility to make - sure it's not out-of-range. - */ - inline uint8* getLinePointer (int y) const noexcept { return data + y * lineStride; } - - /** Returns a pointer to a pixel in the image. - The coordinates you give here are not checked, so it's the caller's responsibility to make sure they're - not out-of-range. - */ - inline uint8* getPixelPointer (int x, int y) const noexcept { return data + y * lineStride + x * pixelStride; } - - /** Returns the colour of a given pixel. - For performance reasons, this won't do any bounds-checking on the coordinates, so it's the caller's - repsonsibility to make sure they're within the image's size. - */ - Colour getPixelColour (int x, int y) const noexcept; - - /** Sets the colour of a given pixel. - For performance reasons, this won't do any bounds-checking on the coordinates, so it's the caller's - repsonsibility to make sure they're within the image's size. - */ - void setPixelColour (int x, int y, Colour colour) const noexcept; - - /** Returns the size of the bitmap. */ - Rectangle getBounds() const noexcept { return Rectangle (width, height); } - - uint8* data; /**< The raw pixel data, packed according to the image's pixel format. */ - PixelFormat pixelFormat; /**< The format of the data. */ - int lineStride; /**< The number of bytes between each line. */ - int pixelStride; /**< The number of bytes between each pixel. */ - int width, height; - - //============================================================================== - /** Used internally by custom image types to manage pixel data lifetime. */ - class BitmapDataReleaser - { - protected: - BitmapDataReleaser() {} - public: - virtual ~BitmapDataReleaser() {} - }; - - ScopedPointer dataReleaser; - - private: - JUCE_DECLARE_NON_COPYABLE (BitmapData) - }; - - //============================================================================== - /** Copies a section of the image to somewhere else within itself. */ - void moveImageSection (int destX, int destY, - int sourceX, int sourceY, - int width, int height); - - /** Creates a RectangleList containing rectangles for all non-transparent pixels - of the image. - - @param result the list that will have the area added to it - @param alphaThreshold for a semi-transparent image, any pixels whose alpha is - above this level will be considered opaque - */ - void createSolidAreaMask (RectangleList& result, float alphaThreshold) const; - - //============================================================================== - /** Returns a NamedValueSet that is attached to the image and which can be used for - associating custom values with it. - - If this is a null image, this will return a null pointer. - */ - NamedValueSet* getProperties() const; - - //============================================================================== - /** Creates a context suitable for drawing onto this image. - Don't call this method directly! It's used internally by the Graphics class. - */ - LowLevelGraphicsContext* createLowLevelContext() const; - - /** Returns the number of Image objects which are currently referring to the same internal - shared image data. - - @see duplicateIfShared - */ - int getReferenceCount() const noexcept; - - //============================================================================== - /** @internal */ - ImagePixelData* getPixelData() const noexcept { return image; } - - /** @internal */ - explicit Image (ImagePixelData*) noexcept; - -private: - //============================================================================== - ReferenceCountedObjectPtr image; - - JUCE_LEAK_DETECTOR (Image) -}; - - -//============================================================================== -/** - This is a base class for holding image data in implementation-specific ways. - - You may never need to use this class directly - it's used internally - by the Image class to store the actual image data. To access pixel data directly, - you should use Image::BitmapData rather than this class. - - ImagePixelData objects are created indirectly, by subclasses of ImageType. - @see Image, ImageType -*/ -class JUCE_API ImagePixelData : public ReferenceCountedObject -{ -public: - ImagePixelData (Image::PixelFormat, int width, int height); - ~ImagePixelData(); - - /** Creates a context that will draw into this image. */ - virtual LowLevelGraphicsContext* createLowLevelContext() = 0; - /** Creates a copy of this image. */ - virtual ImagePixelData* clone() = 0; - /** Creates an instance of the type of this image. */ - virtual ImageType* createType() const = 0; - /** Initialises a BitmapData object. */ - virtual void initialiseBitmapData (Image::BitmapData&, int x, int y, Image::BitmapData::ReadWriteMode) = 0; - - /** The pixel format of the image data. */ - const Image::PixelFormat pixelFormat; - const int width, height; - - /** User-defined settings that are attached to this image. - @see Image::getProperties(). - */ - NamedValueSet userData; - - typedef ReferenceCountedObjectPtr Ptr; - - //============================================================================== - struct Listener - { - virtual ~Listener() {} - - virtual void imageDataChanged (ImagePixelData*) = 0; - virtual void imageDataBeingDeleted (ImagePixelData*) = 0; - }; - - ListenerList listeners; - - void sendDataChangeMessage(); - -private: - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ImagePixelData) -}; - -//============================================================================== -/** - This base class is for handlers that control a type of image manipulation format, - e.g. an in-memory bitmap, an OpenGL image, CoreGraphics image, etc. - - @see SoftwareImageType, NativeImageType, OpenGLImageType -*/ -class JUCE_API ImageType -{ -public: - ImageType(); - virtual ~ImageType(); - - /** Creates a new image of this type, and the specified parameters. */ - virtual ImagePixelData::Ptr create (Image::PixelFormat format, int width, int height, bool shouldClearImage) const = 0; - - /** Must return a unique number to identify this type. */ - virtual int getTypeID() const = 0; - - /** Returns an image which is a copy of the source image, but using this type of storage mechanism. - For example, to make sure that an image is stored in-memory, you could use: - @code myImage = SoftwareImageType().convert (myImage); @endcode - */ - virtual Image convert (const Image& source) const; -}; - -//============================================================================== -/** - An image storage type which holds the pixels in-memory as a simple block of values. - @see ImageType, NativeImageType -*/ -class JUCE_API SoftwareImageType : public ImageType -{ -public: - SoftwareImageType(); - ~SoftwareImageType(); - - ImagePixelData::Ptr create (Image::PixelFormat, int width, int height, bool clearImage) const override; - int getTypeID() const override; -}; - -//============================================================================== -/** - An image storage type which holds the pixels using whatever is the default storage - format on the current platform. - @see ImageType, SoftwareImageType -*/ -class JUCE_API NativeImageType : public ImageType -{ -public: - NativeImageType(); - ~NativeImageType(); - - ImagePixelData::Ptr create (Image::PixelFormat, int width, int height, bool clearImage) const override; - int getTypeID() const override; -}; - - -#endif // JUCE_IMAGE_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/images/juce_ImageCache.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/images/juce_ImageCache.cpp deleted file mode 100644 index 992ff328b9..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/images/juce_ImageCache.cpp +++ /dev/null @@ -1,176 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -class ImageCache::Pimpl : private Timer, - private DeletedAtShutdown -{ -public: - Pimpl() : cacheTimeout (5000) - { - } - - ~Pimpl() - { - clearSingletonInstance(); - } - - Image getFromHashCode (const int64 hashCode) - { - const ScopedLock sl (lock); - - for (int i = images.size(); --i >= 0;) - { - const Item* const item = images.getUnchecked(i); - - if (item->hashCode == hashCode) - return item->image; - } - - return Image::null; - } - - void addImageToCache (const Image& image, const int64 hashCode) - { - if (image.isValid()) - { - if (! isTimerRunning()) - startTimer (2000); - - Item* const item = new Item(); - item->hashCode = hashCode; - item->image = image; - item->lastUseTime = Time::getApproximateMillisecondCounter(); - - const ScopedLock sl (lock); - images.add (item); - } - } - - void timerCallback() override - { - const uint32 now = Time::getApproximateMillisecondCounter(); - - const ScopedLock sl (lock); - - for (int i = images.size(); --i >= 0;) - { - Item* const item = images.getUnchecked(i); - - if (item->image.getReferenceCount() <= 1) - { - if (now > item->lastUseTime + cacheTimeout || now < item->lastUseTime - 1000) - images.remove (i); - } - else - { - item->lastUseTime = now; // multiply-referenced, so this image is still in use. - } - } - - if (images.size() == 0) - stopTimer(); - } - - void releaseUnusedImages() - { - const ScopedLock sl (lock); - - for (int i = images.size(); --i >= 0;) - if (images.getUnchecked(i)->image.getReferenceCount() <= 1) - images.remove (i); - } - - struct Item - { - Image image; - int64 hashCode; - uint32 lastUseTime; - }; - - unsigned int cacheTimeout; - - juce_DeclareSingleton_SingleThreaded_Minimal (ImageCache::Pimpl); - -private: - OwnedArray images; - CriticalSection lock; - - JUCE_DECLARE_NON_COPYABLE (Pimpl) -}; - -juce_ImplementSingleton_SingleThreaded (ImageCache::Pimpl); - - -//============================================================================== -Image ImageCache::getFromHashCode (const int64 hashCode) -{ - if (Pimpl::getInstanceWithoutCreating() != nullptr) - return Pimpl::getInstanceWithoutCreating()->getFromHashCode (hashCode); - - return Image::null; -} - -void ImageCache::addImageToCache (const Image& image, const int64 hashCode) -{ - Pimpl::getInstance()->addImageToCache (image, hashCode); -} - -Image ImageCache::getFromFile (const File& file) -{ - const int64 hashCode = file.hashCode64(); - Image image (getFromHashCode (hashCode)); - - if (image.isNull()) - { - image = ImageFileFormat::loadFrom (file); - addImageToCache (image, hashCode); - } - - return image; -} - -Image ImageCache::getFromMemory (const void* imageData, const int dataSize) -{ - const int64 hashCode = (int64) (pointer_sized_int) imageData; - Image image (getFromHashCode (hashCode)); - - if (image.isNull()) - { - image = ImageFileFormat::loadFrom (imageData, (size_t) dataSize); - addImageToCache (image, hashCode); - } - - return image; -} - -void ImageCache::setCacheTimeout (const int millisecs) -{ - jassert (millisecs >= 0); - Pimpl::getInstance()->cacheTimeout = (unsigned int) millisecs; -} - -void ImageCache::releaseUnusedImages() -{ - Pimpl::getInstance()->releaseUnusedImages(); -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/images/juce_ImageCache.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/images/juce_ImageCache.h deleted file mode 100644 index c4243952b6..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/images/juce_ImageCache.h +++ /dev/null @@ -1,125 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_IMAGECACHE_H_INCLUDED -#define JUCE_IMAGECACHE_H_INCLUDED - - -//============================================================================== -/** - A global cache of images that have been loaded from files or memory. - - If you're loading an image and may need to use the image in more than one - place, this is used to allow the same image to be shared rather than loading - multiple copies into memory. - - Another advantage is that after images are released, they will be kept in - memory for a few seconds before it is actually deleted, so if you're repeatedly - loading/deleting the same image, it'll reduce the chances of having to reload it - each time. - - @see Image, ImageFileFormat -*/ -class JUCE_API ImageCache -{ -public: - //============================================================================== - /** Loads an image from a file, (or just returns the image if it's already cached). - - If the cache already contains an image that was loaded from this file, - that image will be returned. Otherwise, this method will try to load the - file, add it to the cache, and return it. - - Remember that the image returned is shared, so drawing into it might - affect other things that are using it! If you want to draw on it, first - call Image::duplicateIfShared() - - @param file the file to try to load - @returns the image, or null if it there was an error loading it - @see getFromMemory, getFromCache, ImageFileFormat::loadFrom - */ - static Image getFromFile (const File& file); - - /** Loads an image from an in-memory image file, (or just returns the image if it's already cached). - - If the cache already contains an image that was loaded from this block of memory, - that image will be returned. Otherwise, this method will try to load the - file, add it to the cache, and return it. - - Remember that the image returned is shared, so drawing into it might - affect other things that are using it! If you want to draw on it, first - call Image::duplicateIfShared() - - @param imageData the block of memory containing the image data - @param dataSize the data size in bytes - @returns the image, or an invalid image if it there was an error loading it - @see getFromMemory, getFromCache, ImageFileFormat::loadFrom - */ - static Image getFromMemory (const void* imageData, int dataSize); - - //============================================================================== - /** Checks the cache for an image with a particular hashcode. - - If there's an image in the cache with this hashcode, it will be returned, - otherwise it will return an invalid image. - - @param hashCode the hash code that was associated with the image by addImageToCache() - @see addImageToCache - */ - static Image getFromHashCode (int64 hashCode); - - /** Adds an image to the cache with a user-defined hash-code. - - The image passed-in will be referenced (not copied) by the cache, so it's probably - a good idea not to draw into it after adding it, otherwise this will affect all - instances of it that may be in use. - - @param image the image to add - @param hashCode the hash-code to associate with it - @see getFromHashCode - */ - static void addImageToCache (const Image& image, int64 hashCode); - - /** Changes the amount of time before an unused image will be removed from the cache. - By default this is about 5 seconds. - */ - static void setCacheTimeout (int millisecs); - - /** Releases any images in the cache that aren't being referenced by active - Image objects. - */ - static void releaseUnusedImages(); - -private: - //============================================================================== - class Pimpl; - friend class Pimpl; - - ImageCache(); - ~ImageCache(); - - JUCE_DECLARE_NON_COPYABLE (ImageCache) -}; - -#endif // JUCE_IMAGECACHE_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/images/juce_ImageConvolutionKernel.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/images/juce_ImageConvolutionKernel.cpp deleted file mode 100644 index 78e4fb8d61..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/images/juce_ImageConvolutionKernel.cpp +++ /dev/null @@ -1,290 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -ImageConvolutionKernel::ImageConvolutionKernel (const int size_) - : values ((size_t) (size_ * size_)), - size (size_) -{ - clear(); -} - -ImageConvolutionKernel::~ImageConvolutionKernel() -{ -} - -//============================================================================== -float ImageConvolutionKernel::getKernelValue (const int x, const int y) const noexcept -{ - if (isPositiveAndBelow (x, size) && isPositiveAndBelow (y, size)) - return values [x + y * size]; - - jassertfalse; - return 0; -} - -void ImageConvolutionKernel::setKernelValue (const int x, const int y, const float value) noexcept -{ - if (isPositiveAndBelow (x, size) && isPositiveAndBelow (y, size)) - { - values [x + y * size] = value; - } - else - { - jassertfalse; - } -} - -void ImageConvolutionKernel::clear() -{ - for (int i = size * size; --i >= 0;) - values[i] = 0; -} - -void ImageConvolutionKernel::setOverallSum (const float desiredTotalSum) -{ - double currentTotal = 0.0; - - for (int i = size * size; --i >= 0;) - currentTotal += values[i]; - - rescaleAllValues ((float) (desiredTotalSum / currentTotal)); -} - -void ImageConvolutionKernel::rescaleAllValues (const float multiplier) -{ - for (int i = size * size; --i >= 0;) - values[i] *= multiplier; -} - -//============================================================================== -void ImageConvolutionKernel::createGaussianBlur (const float radius) -{ - const double radiusFactor = -1.0 / (radius * radius * 2); - const int centre = size >> 1; - - for (int y = size; --y >= 0;) - { - for (int x = size; --x >= 0;) - { - const int cx = x - centre; - const int cy = y - centre; - - values [x + y * size] = (float) exp (radiusFactor * (cx * cx + cy * cy)); - } - } - - setOverallSum (1.0f); -} - -//============================================================================== -void ImageConvolutionKernel::applyToImage (Image& destImage, - const Image& sourceImage, - const Rectangle& destinationArea) const -{ - if (sourceImage == destImage) - { - destImage.duplicateIfShared(); - } - else - { - if (sourceImage.getWidth() != destImage.getWidth() - || sourceImage.getHeight() != destImage.getHeight() - || sourceImage.getFormat() != destImage.getFormat()) - { - jassertfalse; - return; - } - } - - const Rectangle area (destinationArea.getIntersection (destImage.getBounds())); - - if (area.isEmpty()) - return; - - const int right = area.getRight(); - const int bottom = area.getBottom(); - - const Image::BitmapData destData (destImage, area.getX(), area.getY(), area.getWidth(), area.getHeight(), - Image::BitmapData::writeOnly); - uint8* line = destData.data; - - const Image::BitmapData srcData (sourceImage, Image::BitmapData::readOnly); - - if (destData.pixelStride == 4) - { - for (int y = area.getY(); y < bottom; ++y) - { - uint8* dest = line; - line += destData.lineStride; - - for (int x = area.getX(); x < right; ++x) - { - float c1 = 0; - float c2 = 0; - float c3 = 0; - float c4 = 0; - - for (int yy = 0; yy < size; ++yy) - { - const int sy = y + yy - (size >> 1); - - if (sy >= srcData.height) - break; - - if (sy >= 0) - { - int sx = x - (size >> 1); - const uint8* src = srcData.getPixelPointer (sx, sy); - - for (int xx = 0; xx < size; ++xx) - { - if (sx >= srcData.width) - break; - - if (sx >= 0) - { - const float kernelMult = values [xx + yy * size]; - c1 += kernelMult * *src++; - c2 += kernelMult * *src++; - c3 += kernelMult * *src++; - c4 += kernelMult * *src++; - } - else - { - src += 4; - } - - ++sx; - } - } - } - - *dest++ = (uint8) jmin (0xff, roundToInt (c1)); - *dest++ = (uint8) jmin (0xff, roundToInt (c2)); - *dest++ = (uint8) jmin (0xff, roundToInt (c3)); - *dest++ = (uint8) jmin (0xff, roundToInt (c4)); - } - } - } - else if (destData.pixelStride == 3) - { - for (int y = area.getY(); y < bottom; ++y) - { - uint8* dest = line; - line += destData.lineStride; - - for (int x = area.getX(); x < right; ++x) - { - float c1 = 0; - float c2 = 0; - float c3 = 0; - - for (int yy = 0; yy < size; ++yy) - { - const int sy = y + yy - (size >> 1); - - if (sy >= srcData.height) - break; - - if (sy >= 0) - { - int sx = x - (size >> 1); - const uint8* src = srcData.getPixelPointer (sx, sy); - - for (int xx = 0; xx < size; ++xx) - { - if (sx >= srcData.width) - break; - - if (sx >= 0) - { - const float kernelMult = values [xx + yy * size]; - c1 += kernelMult * *src++; - c2 += kernelMult * *src++; - c3 += kernelMult * *src++; - } - else - { - src += 3; - } - - ++sx; - } - } - } - - *dest++ = (uint8) roundToInt (c1); - *dest++ = (uint8) roundToInt (c2); - *dest++ = (uint8) roundToInt (c3); - } - } - } - else if (destData.pixelStride == 1) - { - for (int y = area.getY(); y < bottom; ++y) - { - uint8* dest = line; - line += destData.lineStride; - - for (int x = area.getX(); x < right; ++x) - { - float c1 = 0; - - for (int yy = 0; yy < size; ++yy) - { - const int sy = y + yy - (size >> 1); - - if (sy >= srcData.height) - break; - - if (sy >= 0) - { - int sx = x - (size >> 1); - const uint8* src = srcData.getPixelPointer (sx, sy); - - for (int xx = 0; xx < size; ++xx) - { - if (sx >= srcData.width) - break; - - if (sx >= 0) - { - const float kernelMult = values [xx + yy * size]; - c1 += kernelMult * *src++; - } - else - { - src += 3; - } - - ++sx; - } - } - } - - *dest++ = (uint8) roundToInt (c1); - } - } - } -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/images/juce_ImageConvolutionKernel.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/images/juce_ImageConvolutionKernel.h deleted file mode 100644 index 885dc6bf3d..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/images/juce_ImageConvolutionKernel.h +++ /dev/null @@ -1,111 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_IMAGECONVOLUTIONKERNEL_H_INCLUDED -#define JUCE_IMAGECONVOLUTIONKERNEL_H_INCLUDED - - -//============================================================================== -/** - Represents a filter kernel to use in convoluting an image. - - @see Image::applyConvolution -*/ -class JUCE_API ImageConvolutionKernel -{ -public: - //============================================================================== - /** Creates an empty convulution kernel. - - @param size the length of each dimension of the kernel, so e.g. if the size - is 5, it will create a 5x5 kernel - */ - ImageConvolutionKernel (int size); - - /** Destructor. */ - ~ImageConvolutionKernel(); - - //============================================================================== - /** Resets all values in the kernel to zero. */ - void clear(); - - /** Returns one of the kernel values. */ - float getKernelValue (int x, int y) const noexcept; - - /** Sets the value of a specific cell in the kernel. - - The x and y parameters must be in the range 0 < x < getKernelSize(). - - @see setOverallSum - */ - void setKernelValue (int x, int y, float value) noexcept; - - /** Rescales all values in the kernel to make the total add up to a fixed value. - - This will multiply all values in the kernel by (desiredTotalSum / currentTotalSum). - */ - void setOverallSum (float desiredTotalSum); - - /** Multiplies all values in the kernel by a value. */ - void rescaleAllValues (float multiplier); - - /** Intialises the kernel for a gaussian blur. - - @param blurRadius this may be larger or smaller than the kernel's actual - size but this will obviously be wasteful or clip at the - edges. Ideally the kernel should be just larger than - (blurRadius * 2). - */ - void createGaussianBlur (float blurRadius); - - //============================================================================== - /** Returns the size of the kernel. - - E.g. if it's a 3x3 kernel, this returns 3. - */ - int getKernelSize() const { return size; } - - //============================================================================== - /** Applies the kernel to an image. - - @param destImage the image that will receive the resultant convoluted pixels. - @param sourceImage the source image to read from - this can be the same image as - the destination, but if different, it must be exactly the same - size and format. - @param destinationArea the region of the image to apply the filter to - */ - void applyToImage (Image& destImage, - const Image& sourceImage, - const Rectangle& destinationArea) const; - -private: - //============================================================================== - HeapBlock values; - const int size; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ImageConvolutionKernel) -}; - - -#endif // JUCE_IMAGECONVOLUTIONKERNEL_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/images/juce_ImageFileFormat.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/images/juce_ImageFileFormat.cpp deleted file mode 100644 index a1cfd6a44f..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/images/juce_ImageFileFormat.cpp +++ /dev/null @@ -1,107 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -struct DefaultImageFormats -{ - static ImageFileFormat** get() - { - static DefaultImageFormats formats; - return formats.formats; - } - -private: - DefaultImageFormats() noexcept - { - formats[0] = &png; - formats[1] = &jpg; - formats[2] = &gif; - formats[3] = nullptr; - } - - PNGImageFormat png; - JPEGImageFormat jpg; - GIFImageFormat gif; - - ImageFileFormat* formats[4]; -}; - -ImageFileFormat* ImageFileFormat::findImageFormatForStream (InputStream& input) -{ - const int64 streamPos = input.getPosition(); - - for (ImageFileFormat** i = DefaultImageFormats::get(); *i != nullptr; ++i) - { - const bool found = (*i)->canUnderstand (input); - input.setPosition (streamPos); - - if (found) - return *i; - } - - return nullptr; -} - -ImageFileFormat* ImageFileFormat::findImageFormatForFileExtension (const File& file) -{ - for (ImageFileFormat** i = DefaultImageFormats::get(); *i != nullptr; ++i) - if ((*i)->usesFileExtension (file)) - return *i; - - return nullptr; -} - -//============================================================================== -Image ImageFileFormat::loadFrom (InputStream& input) -{ - ImageFileFormat* const format = findImageFormatForStream (input); - - if (format != nullptr) - return format->decodeImage (input); - - return Image::null; -} - -Image ImageFileFormat::loadFrom (const File& file) -{ - FileInputStream stream (file); - - if (stream.openedOk()) - { - BufferedInputStream b (stream, 8192); - return loadFrom (b); - } - - return Image::null; -} - -Image ImageFileFormat::loadFrom (const void* rawData, const size_t numBytes) -{ - if (rawData != nullptr && numBytes > 4) - { - MemoryInputStream stream (rawData, numBytes, false); - return loadFrom (stream); - } - - return Image::null; -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/images/juce_ImageFileFormat.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/images/juce_ImageFileFormat.h deleted file mode 100644 index 76a13d25a3..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/images/juce_ImageFileFormat.h +++ /dev/null @@ -1,216 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_IMAGEFILEFORMAT_H_INCLUDED -#define JUCE_IMAGEFILEFORMAT_H_INCLUDED - - -//============================================================================== -/** - Base-class for codecs that can read and write image file formats such - as PNG, JPEG, etc. - - This class also contains static methods to make it easy to load images - from files, streams or from memory. - - @see Image, ImageCache -*/ -class JUCE_API ImageFileFormat -{ -protected: - //============================================================================== - /** Creates an ImageFormat. */ - ImageFileFormat() {} - -public: - /** Destructor. */ - virtual ~ImageFileFormat() {} - - //============================================================================== - /** Returns a description of this file format. - - E.g. "JPEG", "PNG" - */ - virtual String getFormatName() = 0; - - /** Returns true if the given stream seems to contain data that this format understands. - - The format class should only read the first few bytes of the stream and sniff - for header bytes that it understands. - - Note that this will advance the stream and leave it in a new position, so if you're - planning on re-using it, you may want to rewind it after calling this method. - - @see decodeImage - */ - virtual bool canUnderstand (InputStream& input) = 0; - - /** Returns true if this format uses the file extension of the given file. */ - virtual bool usesFileExtension (const File& possibleFile) = 0; - - /** Tries to decode and return an image from the given stream. - - This will be called for an image format after calling its canUnderStand() method - to see if it can handle the stream. - - @param input the stream to read the data from. The stream will be positioned - at the start of the image data (but this may not necessarily - be position 0) - @returns the image that was decoded, or an invalid image if it fails. - @see loadFrom - */ - virtual Image decodeImage (InputStream& input) = 0; - - //============================================================================== - /** Attempts to write an image to a stream. - - To specify extra information like encoding quality, there will be appropriate parameters - in the subclasses of the specific file types. - - @returns true if it nothing went wrong. - */ - virtual bool writeImageToStream (const Image& sourceImage, - OutputStream& destStream) = 0; - - //============================================================================== - /** Tries the built-in formats to see if it can find one to read this stream. - There are currently built-in decoders for PNG, JPEG and GIF formats. - The object that is returned should not be deleted by the caller. - @see canUnderstand, decodeImage, loadFrom - */ - static ImageFileFormat* findImageFormatForStream (InputStream& input); - - /** Looks for a format that can handle the given file extension. - There are currently built-in formats for PNG, JPEG and GIF formats. - The object that is returned should not be deleted by the caller. - */ - static ImageFileFormat* findImageFormatForFileExtension (const File& file); - - //============================================================================== - /** Tries to load an image from a stream. - - This will use the findImageFormatForStream() method to locate a suitable - codec, and use that to load the image. - - @returns the image that was decoded, or an invalid image if it fails. - */ - static Image loadFrom (InputStream& input); - - /** Tries to load an image from a file. - - This will use the findImageFormatForStream() method to locate a suitable - codec, and use that to load the image. - - @returns the image that was decoded, or an invalid image if it fails. - */ - static Image loadFrom (const File& file); - - /** Tries to load an image from a block of raw image data. - - This will use the findImageFormatForStream() method to locate a suitable - codec, and use that to load the image. - - @returns the image that was decoded, or an invalid image if it fails. - */ - static Image loadFrom (const void* rawData, - size_t numBytesOfData); -}; - -//============================================================================== -/** - A subclass of ImageFileFormat for reading and writing PNG files. - - @see ImageFileFormat, JPEGImageFormat -*/ -class JUCE_API PNGImageFormat : public ImageFileFormat -{ -public: - //============================================================================== - PNGImageFormat(); - ~PNGImageFormat(); - - //============================================================================== - String getFormatName() override; - bool usesFileExtension (const File&) override; - bool canUnderstand (InputStream&) override; - Image decodeImage (InputStream&) override; - bool writeImageToStream (const Image&, OutputStream&) override; -}; - - -//============================================================================== -/** - A subclass of ImageFileFormat for reading and writing JPEG files. - - @see ImageFileFormat, PNGImageFormat -*/ -class JUCE_API JPEGImageFormat : public ImageFileFormat -{ -public: - //============================================================================== - JPEGImageFormat(); - ~JPEGImageFormat(); - - //============================================================================== - /** Specifies the quality to be used when writing a JPEG file. - - @param newQuality a value 0 to 1.0, where 0 is low quality, 1.0 is best, or - any negative value is "default" quality - */ - void setQuality (float newQuality); - - //============================================================================== - String getFormatName() override; - bool usesFileExtension (const File&) override; - bool canUnderstand (InputStream&) override; - Image decodeImage (InputStream&) override; - bool writeImageToStream (const Image&, OutputStream&) override; - -private: - float quality; -}; - -//============================================================================== -/** - A subclass of ImageFileFormat for reading GIF files. - - @see ImageFileFormat, PNGImageFormat, JPEGImageFormat -*/ -class JUCE_API GIFImageFormat : public ImageFileFormat -{ -public: - //============================================================================== - GIFImageFormat(); - ~GIFImageFormat(); - - //============================================================================== - String getFormatName() override; - bool usesFileExtension (const File&) override; - bool canUnderstand (InputStream&) override; - Image decodeImage (InputStream&) override; - bool writeImageToStream (const Image&, OutputStream&) override; -}; - - -#endif // JUCE_IMAGEFILEFORMAT_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/juce_graphics.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/juce_graphics.cpp deleted file mode 100644 index 627d5654a5..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/juce_graphics.cpp +++ /dev/null @@ -1,171 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#if defined (JUCE_GRAPHICS_H_INCLUDED) && ! JUCE_AMALGAMATED_INCLUDE - /* When you add this cpp file to your project, you mustn't include it in a file where you've - already included any other headers - just put it inside a file on its own, possibly with your config - flags preceding it, but don't include anything else. That also includes avoiding any automatic prefix - header files that the compiler may be using. - */ - #error "Incorrect use of JUCE cpp file" -#endif - -// Your project must contain an AppConfig.h file with your project-specific settings in it, -// and your header search path must make it accessible to the module's files. -#include "AppConfig.h" - -#include "../juce_core/native/juce_BasicNativeHeaders.h" -#include "juce_graphics.h" - -//============================================================================== -#if JUCE_MAC - #import - -#elif JUCE_WINDOWS - #if JUCE_MINGW && JUCE_USE_DIRECTWRITE - #warning "DirectWrite not currently implemented with mingw..." - #undef JUCE_USE_DIRECTWRITE - #endif - - #if JUCE_USE_DIRECTWRITE - /* If you hit a compile error trying to include these files, you may need to update - your version of the Windows SDK to the latest one. The DirectWrite and Direct2D - headers are in the version 7 SDKs. - */ - #include - #include - #endif - - #if JUCE_MINGW - #include - #endif - -#elif JUCE_IOS - #import - #import - - #if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_3_2 - #error "JUCE no longer supports targets earlier than iOS 3.2" - #endif - -#elif JUCE_LINUX - #ifndef JUCE_USE_FREETYPE - #define JUCE_USE_FREETYPE 1 - #endif - - #if ! JUCE_USE_FREETYPE_AMALGAMATED - #include - #include FT_FREETYPE_H - #endif -#endif - -#if JUCE_USE_FREETYPE && JUCE_USE_FREETYPE_AMALGAMATED - #include "native/freetype/FreeTypeAmalgam.h" -#endif - -#undef SIZEOF - -#if (JUCE_MAC || JUCE_IOS) && USE_COREGRAPHICS_RENDERING && JUCE_USE_COREIMAGE_LOADER - #define JUCE_USING_COREIMAGE_LOADER 1 -#else - #define JUCE_USING_COREIMAGE_LOADER 0 -#endif - -//============================================================================== -namespace juce -{ - -#include "colour/juce_Colour.cpp" -#include "colour/juce_ColourGradient.cpp" -#include "colour/juce_Colours.cpp" -#include "colour/juce_FillType.cpp" -#include "geometry/juce_AffineTransform.cpp" -#include "geometry/juce_EdgeTable.cpp" -#include "geometry/juce_Path.cpp" -#include "geometry/juce_PathIterator.cpp" -#include "geometry/juce_PathStrokeType.cpp" -#include "placement/juce_RectanglePlacement.cpp" -#include "contexts/juce_GraphicsContext.cpp" -#include "contexts/juce_LowLevelGraphicsPostScriptRenderer.cpp" -#include "contexts/juce_LowLevelGraphicsSoftwareRenderer.cpp" -#include "images/juce_Image.cpp" -#include "images/juce_ImageCache.cpp" -#include "images/juce_ImageConvolutionKernel.cpp" -#include "images/juce_ImageFileFormat.cpp" -#include "image_formats/juce_GIFLoader.cpp" -#include "image_formats/juce_JPEGLoader.cpp" -#include "image_formats/juce_PNGLoader.cpp" -#include "fonts/juce_AttributedString.cpp" -#include "fonts/juce_Typeface.cpp" -#include "fonts/juce_CustomTypeface.cpp" -#include "fonts/juce_Font.cpp" -#include "fonts/juce_GlyphArrangement.cpp" -#include "fonts/juce_TextLayout.cpp" -#include "effects/juce_DropShadowEffect.cpp" -#include "effects/juce_GlowEffect.cpp" - -#if JUCE_USE_FREETYPE - #include "native/juce_freetype_Fonts.cpp" -#endif - -//============================================================================== -#if JUCE_MAC || JUCE_IOS - #include "../juce_core/native/juce_osx_ObjCHelpers.h" - #include "native/juce_mac_CoreGraphicsHelpers.h" - #include "native/juce_mac_Fonts.mm" - #include "native/juce_mac_CoreGraphicsContext.mm" - -#elif JUCE_WINDOWS - #include "../juce_core/native/juce_win32_ComSmartPtr.h" - #include "native/juce_win32_DirectWriteTypeface.cpp" - #include "native/juce_win32_DirectWriteTypeLayout.cpp" - #include "native/juce_win32_Fonts.cpp" - #if JUCE_DIRECT2D - #include "native/juce_win32_Direct2DGraphicsContext.cpp" - #endif - -#elif JUCE_LINUX - #include "native/juce_linux_Fonts.cpp" - -#elif JUCE_ANDROID - #include "../juce_core/native/juce_android_JNIHelpers.h" - #include "native/juce_android_GraphicsContext.cpp" - #include "native/juce_android_Fonts.cpp" - -#endif -} - -//============================================================================== -#if JUCE_USE_FREETYPE && JUCE_USE_FREETYPE_AMALGAMATED - #undef PIXEL_MASK - #undef ZLIB_VERSION - #undef Z_ASCII - #undef ZEXTERN - #undef ZEXPORT - - extern "C" - { - #include "native/freetype/FreeTypeAmalgam.c" - } -#endif diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/juce_graphics.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/juce_graphics.h index 9a5a0150f4..f287a18ee6 100644 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/juce_graphics.h +++ b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/juce_graphics.h @@ -1,113 +1,5 @@ -/* - ============================================================================== +// This is an auto-generated file to redirect any included +// module headers to the correct external folder. - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. +#include "../../../../../modules/juce_graphics/juce_graphics.h" - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_GRAPHICS_H_INCLUDED // %% -#define JUCE_GRAPHICS_H_INCLUDED - -#include "../juce_core/juce_core.h" -#include "../juce_events/juce_events.h" - -//============================================================================= -/** Config: JUCE_USE_COREIMAGE_LOADER - - On OSX, enabling this flag means that the CoreImage codecs will be used to load - PNG/JPEG/GIF files. It is enabled by default, but you may want to disable it if - you'd rather use libpng, libjpeg, etc. -*/ -#ifndef JUCE_USE_COREIMAGE_LOADER - #define JUCE_USE_COREIMAGE_LOADER 1 -#endif - -/** Config: JUCE_USE_DIRECTWRITE - - Enabling this flag means that DirectWrite will be used when available for font - management and layout. -*/ -#ifndef JUCE_USE_DIRECTWRITE - #define JUCE_USE_DIRECTWRITE 1 -#endif - -#ifndef JUCE_INCLUDE_PNGLIB_CODE - #define JUCE_INCLUDE_PNGLIB_CODE 1 -#endif - -#ifndef JUCE_INCLUDE_JPEGLIB_CODE - #define JUCE_INCLUDE_JPEGLIB_CODE 1 -#endif - -#ifndef USE_COREGRAPHICS_RENDERING - #define USE_COREGRAPHICS_RENDERING 1 -#endif - -//============================================================================= -namespace juce -{ - -class Image; -class AffineTransform; -class Path; -class Font; -class Graphics; -class FillType; -class LowLevelGraphicsContext; - -#include "geometry/juce_AffineTransform.h" -#include "geometry/juce_Point.h" -#include "geometry/juce_Line.h" -#include "geometry/juce_Rectangle.h" -#include "placement/juce_Justification.h" -#include "geometry/juce_Path.h" -#include "geometry/juce_RectangleList.h" -#include "colour/juce_PixelFormats.h" -#include "colour/juce_Colour.h" -#include "colour/juce_ColourGradient.h" -#include "colour/juce_Colours.h" -#include "geometry/juce_BorderSize.h" -#include "geometry/juce_EdgeTable.h" -#include "geometry/juce_PathIterator.h" -#include "geometry/juce_PathStrokeType.h" -#include "placement/juce_RectanglePlacement.h" -#include "images/juce_ImageCache.h" -#include "images/juce_ImageConvolutionKernel.h" -#include "images/juce_ImageFileFormat.h" -#include "fonts/juce_AttributedString.h" -#include "fonts/juce_Typeface.h" -#include "fonts/juce_Font.h" -#include "fonts/juce_GlyphArrangement.h" -#include "fonts/juce_TextLayout.h" -#include "fonts/juce_CustomTypeface.h" -#include "contexts/juce_GraphicsContext.h" -#include "contexts/juce_LowLevelGraphicsContext.h" -#include "images/juce_Image.h" -#include "colour/juce_FillType.h" -#include "native/juce_RenderingHelpers.h" -#include "contexts/juce_LowLevelGraphicsSoftwareRenderer.h" -#include "contexts/juce_LowLevelGraphicsPostScriptRenderer.h" -#include "effects/juce_ImageEffectFilter.h" -#include "effects/juce_DropShadowEffect.h" -#include "effects/juce_GlowEffect.h" - -} - -#endif // JUCE_GRAPHICS_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/juce_graphics.mm b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/juce_graphics.mm deleted file mode 100644 index b36b0edcec..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/juce_graphics.mm +++ /dev/null @@ -1,25 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#include "juce_graphics.cpp" diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/juce_module_info b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/juce_module_info deleted file mode 100644 index 75903c2bfd..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/juce_module_info +++ /dev/null @@ -1,30 +0,0 @@ -{ - "id": "juce_graphics", - "name": "JUCE graphics classes", - "version": "3.0.8", - "description": "Classes for 2D vector graphics, image loading/saving, font handling, etc.", - "website": "http://www.juce.com/juce", - "license": "GPL/Commercial", - - "dependencies": [ { "id": "juce_core", "version": "matching" }, - { "id": "juce_events", "version": "matching" } ], - - "include": "juce_graphics.h", - - "compile": [ { "file": "juce_graphics.cpp", "target": "! xcode" }, - { "file": "juce_graphics.mm", "target": "xcode" } ], - - "browse": [ "colour/*", - "contexts/*", - "images/*", - "image_formats/*", - "geometry/*", - "placement/*", - "fonts/*", - "effects/*", - "native/*" ], - - "OSXFrameworks": "Cocoa QuartzCore", - "iOSFrameworks": "CoreGraphics CoreText QuartzCore", - "LinuxLibs": "X11 Xinerama Xext freetype" -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/native/juce_RenderingHelpers.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/native/juce_RenderingHelpers.h deleted file mode 100644 index 885cebd002..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/native/juce_RenderingHelpers.h +++ /dev/null @@ -1,2684 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_RENDERINGHELPERS_H_INCLUDED -#define JUCE_RENDERINGHELPERS_H_INCLUDED - -#if JUCE_MSVC - #pragma warning (push) - #pragma warning (disable: 4127) // "expression is constant" warning -#endif - -namespace RenderingHelpers -{ - -//============================================================================== -/** Holds either a simple integer translation, or an affine transform. -*/ -class TranslationOrTransform -{ -public: - TranslationOrTransform (Point origin) noexcept - : offset (origin), isOnlyTranslated (true), isRotated (false) - { - } - - TranslationOrTransform (const TranslationOrTransform& other) noexcept - : complexTransform (other.complexTransform), offset (other.offset), - isOnlyTranslated (other.isOnlyTranslated), isRotated (other.isRotated) - { - } - - AffineTransform getTransform() const noexcept - { - return isOnlyTranslated ? AffineTransform::translation (offset) - : complexTransform; - } - - AffineTransform getTransformWith (const AffineTransform& userTransform) const noexcept - { - return isOnlyTranslated ? userTransform.translated (offset) - : userTransform.followedBy (complexTransform); - } - - void setOrigin (Point delta) noexcept - { - if (isOnlyTranslated) - offset += delta; - else - complexTransform = AffineTransform::translation (delta) - .followedBy (complexTransform); - } - - void addTransform (const AffineTransform& t) noexcept - { - if (isOnlyTranslated && t.isOnlyTranslation()) - { - const int tx = (int) (t.getTranslationX() * 256.0f); - const int ty = (int) (t.getTranslationY() * 256.0f); - - if (((tx | ty) & 0xf8) == 0) - { - offset += Point (tx >> 8, ty >> 8); - return; - } - } - - complexTransform = getTransformWith (t); - isOnlyTranslated = false; - isRotated = (complexTransform.mat01 != 0 || complexTransform.mat10 != 0 - || complexTransform.mat00 < 0 || complexTransform.mat11 < 0); - } - - float getPhysicalPixelScaleFactor() const noexcept - { - return isOnlyTranslated ? 1.0f : std::abs (complexTransform.getScaleFactor()); - } - - void moveOriginInDeviceSpace (Point delta) noexcept - { - if (isOnlyTranslated) - offset += delta; - else - complexTransform = complexTransform.translated (delta); - } - - Rectangle translated (const Rectangle& r) const noexcept - { - jassert (isOnlyTranslated); - return r + offset; - } - - Rectangle translated (const Rectangle& r) const noexcept - { - jassert (isOnlyTranslated); - return r + offset.toFloat(); - } - - template - RectangleOrPoint transformed (const RectangleOrPoint& r) const noexcept - { - jassert (! isOnlyTranslated); - return r.transformedBy (complexTransform); - } - - template - Rectangle deviceSpaceToUserSpace (const Rectangle& r) const noexcept - { - return isOnlyTranslated ? r - offset - : r.transformedBy (complexTransform.inverted()); - } - - AffineTransform complexTransform; - Point offset; - bool isOnlyTranslated, isRotated; -}; - -//============================================================================== -/** Holds a cache of recently-used glyph objects of some type. */ -template -class GlyphCache : private DeletedAtShutdown -{ -public: - GlyphCache() - { - reset(); - } - - ~GlyphCache() - { - getSingletonPointer() = nullptr; - } - - static GlyphCache& getInstance() - { - GlyphCache*& g = getSingletonPointer(); - - if (g == nullptr) - g = new GlyphCache(); - - return *g; - } - - //============================================================================== - void drawGlyph (RenderTargetType& target, const Font& font, const int glyphNumber, Point pos) - { - if (ReferenceCountedObjectPtr glyph = findOrCreateGlyph (font, glyphNumber)) - { - glyph->lastAccessCount = ++accessCounter; - glyph->draw (target, pos); - } - } - - void reset() - { - const ScopedLock sl (lock); - glyphs.clear(); - addNewGlyphSlots (120); - hits.set (0); - misses.set (0); - } - -private: - friend struct ContainerDeletePolicy; - ReferenceCountedArray glyphs; - Atomic accessCounter, hits, misses; - CriticalSection lock; - - ReferenceCountedObjectPtr findOrCreateGlyph (const Font& font, int glyphNumber) - { - const ScopedLock sl (lock); - - if (CachedGlyphType* g = findExistingGlyph (font, glyphNumber)) - { - ++hits; - return g; - } - - ++misses; - CachedGlyphType* g = getGlyphForReuse(); - jassert (g != nullptr); - g->generate (font, glyphNumber); - return g; - } - - CachedGlyphType* findExistingGlyph (const Font& font, int glyphNumber) const - { - for (int i = 0; i < glyphs.size(); ++i) - { - CachedGlyphType* const g = glyphs.getUnchecked (i); - - if (g->glyph == glyphNumber && g->font == font) - return g; - } - - return nullptr; - } - - CachedGlyphType* getGlyphForReuse() - { - if (hits.value + misses.value > glyphs.size() * 16) - { - if (misses.value * 2 > hits.value) - addNewGlyphSlots (32); - - hits.set (0); - misses.set (0); - } - - if (CachedGlyphType* g = findLeastRecentlyUsedGlyph()) - return g; - - addNewGlyphSlots (32); - return glyphs.getLast(); - } - - void addNewGlyphSlots (int num) - { - glyphs.ensureStorageAllocated (glyphs.size() + num); - - while (--num >= 0) - glyphs.add (new CachedGlyphType()); - } - - CachedGlyphType* findLeastRecentlyUsedGlyph() const noexcept - { - CachedGlyphType* oldest = nullptr; - int oldestCounter = std::numeric_limits::max(); - - for (int i = glyphs.size() - 1; --i >= 0;) - { - CachedGlyphType* const glyph = glyphs.getUnchecked(i); - - if (glyph->lastAccessCount <= oldestCounter - && glyph->getReferenceCount() == 1) - { - oldestCounter = glyph->lastAccessCount; - oldest = glyph; - } - } - - return oldest; - } - - static GlyphCache*& getSingletonPointer() noexcept - { - static GlyphCache* g = nullptr; - return g; - } - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (GlyphCache) -}; - -//============================================================================== -/** Caches a glyph as an edge-table. */ -template -class CachedGlyphEdgeTable : public ReferenceCountedObject -{ -public: - CachedGlyphEdgeTable() : glyph (0), lastAccessCount (0) {} - - void draw (RendererType& state, Point pos) const - { - if (snapToIntegerCoordinate) - pos.x = std::floor (pos.x + 0.5f); - - if (edgeTable != nullptr) - state.fillEdgeTable (*edgeTable, pos.x, roundToInt (pos.y)); - } - - void generate (const Font& newFont, const int glyphNumber) - { - font = newFont; - Typeface* const typeface = newFont.getTypeface(); - snapToIntegerCoordinate = typeface->isHinted(); - glyph = glyphNumber; - - const float fontHeight = font.getHeight(); - edgeTable = typeface->getEdgeTableForGlyph (glyphNumber, - AffineTransform::scale (fontHeight * font.getHorizontalScale(), - fontHeight), fontHeight); - } - - Font font; - int glyph, lastAccessCount; - bool snapToIntegerCoordinate; - -private: - ScopedPointer edgeTable; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (CachedGlyphEdgeTable) -}; - -//============================================================================== -/** Calculates the alpha values and positions for rendering the edges of a - non-pixel-aligned rectangle. -*/ -struct FloatRectangleRasterisingInfo -{ - FloatRectangleRasterisingInfo (const Rectangle& area) - : left (roundToInt (256.0f * area.getX())), - top (roundToInt (256.0f * area.getY())), - right (roundToInt (256.0f * area.getRight())), - bottom (roundToInt (256.0f * area.getBottom())) - { - if ((top >> 8) == (bottom >> 8)) - { - topAlpha = bottom - top; - bottomAlpha = 0; - totalTop = top >> 8; - totalBottom = bottom = top = totalTop + 1; - } - else - { - if ((top & 255) == 0) - { - topAlpha = 0; - top = totalTop = (top >> 8); - } - else - { - topAlpha = 255 - (top & 255); - totalTop = (top >> 8); - top = totalTop + 1; - } - - bottomAlpha = bottom & 255; - bottom >>= 8; - totalBottom = bottom + (bottomAlpha != 0 ? 1 : 0); - } - - if ((left >> 8) == (right >> 8)) - { - leftAlpha = right - left; - rightAlpha = 0; - totalLeft = (left >> 8); - totalRight = right = left = totalLeft + 1; - } - else - { - if ((left & 255) == 0) - { - leftAlpha = 0; - left = totalLeft = (left >> 8); - } - else - { - leftAlpha = 255 - (left & 255); - totalLeft = (left >> 8); - left = totalLeft + 1; - } - - rightAlpha = right & 255; - right >>= 8; - totalRight = right + (rightAlpha != 0 ? 1 : 0); - } - } - - template - void iterate (Callback& callback) const - { - if (topAlpha != 0) callback (totalLeft, totalTop, totalRight - totalLeft, 1, topAlpha); - if (bottomAlpha != 0) callback (totalLeft, bottom, totalRight - totalLeft, 1, bottomAlpha); - if (leftAlpha != 0) callback (totalLeft, totalTop, 1, totalBottom - totalTop, leftAlpha); - if (rightAlpha != 0) callback (right, totalTop, 1, totalBottom - totalTop, rightAlpha); - - callback (left, top, right - left, bottom - top, 255); - } - - inline bool isOnePixelWide() const noexcept { return right - left == 1 && leftAlpha + rightAlpha == 0; } - - inline int getTopLeftCornerAlpha() const noexcept { return (topAlpha * leftAlpha) >> 8; } - inline int getTopRightCornerAlpha() const noexcept { return (topAlpha * rightAlpha) >> 8; } - inline int getBottomLeftCornerAlpha() const noexcept { return (bottomAlpha * leftAlpha) >> 8; } - inline int getBottomRightCornerAlpha() const noexcept { return (bottomAlpha * rightAlpha) >> 8; } - - //============================================================================== - int left, top, right, bottom; // bounds of the solid central area, excluding anti-aliased edges - int totalTop, totalLeft, totalBottom, totalRight; // bounds of the total area, including edges - int topAlpha, leftAlpha, bottomAlpha, rightAlpha; // alpha of each anti-aliased edge -}; - -//============================================================================== -/** Contains classes for calculating the colour of pixels within various types of gradient. */ -namespace GradientPixelIterators -{ - /** Iterates the colour of pixels in a linear gradient */ - class Linear - { - public: - Linear (const ColourGradient& gradient, const AffineTransform& transform, - const PixelARGB* const colours, const int numColours) - : lookupTable (colours), - numEntries (numColours) - { - jassert (numColours >= 0); - Point p1 (gradient.point1); - Point p2 (gradient.point2); - - if (! transform.isIdentity()) - { - const Line l (p2, p1); - Point p3 = l.getPointAlongLine (0.0f, 100.0f); - - p1.applyTransform (transform); - p2.applyTransform (transform); - p3.applyTransform (transform); - - p2 = Line (p2, p3).findNearestPointTo (p1); - } - - vertical = std::abs (p1.x - p2.x) < 0.001f; - horizontal = std::abs (p1.y - p2.y) < 0.001f; - - if (vertical) - { - scale = roundToInt ((numEntries << (int) numScaleBits) / (double) (p2.y - p1.y)); - start = roundToInt (p1.y * scale); - } - else if (horizontal) - { - scale = roundToInt ((numEntries << (int) numScaleBits) / (double) (p2.x - p1.x)); - start = roundToInt (p1.x * scale); - } - else - { - grad = (p2.getY() - p1.y) / (double) (p1.x - p2.x); - yTerm = p1.getY() - p1.x / grad; - scale = roundToInt ((numEntries << (int) numScaleBits) / (yTerm * grad - (p2.y * grad - p2.x))); - grad *= scale; - } - } - - forcedinline void setY (const int y) noexcept - { - if (vertical) - linePix = lookupTable [jlimit (0, numEntries, (y * scale - start) >> (int) numScaleBits)]; - else if (! horizontal) - start = roundToInt ((y - yTerm) * grad); - } - - inline PixelARGB getPixel (const int x) const noexcept - { - return vertical ? linePix - : lookupTable [jlimit (0, numEntries, (x * scale - start) >> (int) numScaleBits)]; - } - - private: - const PixelARGB* const lookupTable; - const int numEntries; - PixelARGB linePix; - int start, scale; - double grad, yTerm; - bool vertical, horizontal; - enum { numScaleBits = 12 }; - - JUCE_DECLARE_NON_COPYABLE (Linear) - }; - - //============================================================================== - /** Iterates the colour of pixels in a circular radial gradient */ - class Radial - { - public: - Radial (const ColourGradient& gradient, const AffineTransform&, - const PixelARGB* const colours, const int numColours) - : lookupTable (colours), - numEntries (numColours), - gx1 (gradient.point1.x), - gy1 (gradient.point1.y) - { - jassert (numColours >= 0); - const Point diff (gradient.point1 - gradient.point2); - maxDist = diff.x * diff.x + diff.y * diff.y; - invScale = numEntries / std::sqrt (maxDist); - jassert (roundToInt (std::sqrt (maxDist) * invScale) <= numEntries); - } - - forcedinline void setY (const int y) noexcept - { - dy = y - gy1; - dy *= dy; - } - - inline PixelARGB getPixel (const int px) const noexcept - { - double x = px - gx1; - x *= x; - x += dy; - - return lookupTable [x >= maxDist ? numEntries : roundToInt (std::sqrt (x) * invScale)]; - } - - protected: - const PixelARGB* const lookupTable; - const int numEntries; - const double gx1, gy1; - double maxDist, invScale, dy; - - JUCE_DECLARE_NON_COPYABLE (Radial) - }; - - //============================================================================== - /** Iterates the colour of pixels in a skewed radial gradient */ - class TransformedRadial : public Radial - { - public: - TransformedRadial (const ColourGradient& gradient, const AffineTransform& transform, - const PixelARGB* const colours, const int numColours) - : Radial (gradient, transform, colours, numColours), - inverseTransform (transform.inverted()) - { - tM10 = inverseTransform.mat10; - tM00 = inverseTransform.mat00; - } - - forcedinline void setY (const int y) noexcept - { - lineYM01 = inverseTransform.mat01 * y + inverseTransform.mat02 - gx1; - lineYM11 = inverseTransform.mat11 * y + inverseTransform.mat12 - gy1; - } - - inline PixelARGB getPixel (const int px) const noexcept - { - double x = px; - const double y = tM10 * x + lineYM11; - x = tM00 * x + lineYM01; - x *= x; - x += y * y; - - if (x >= maxDist) - return lookupTable [numEntries]; - - return lookupTable [jmin (numEntries, roundToInt (std::sqrt (x) * invScale))]; - } - - private: - double tM10, tM00, lineYM01, lineYM11; - const AffineTransform inverseTransform; - - JUCE_DECLARE_NON_COPYABLE (TransformedRadial) - }; -} - -#define JUCE_PERFORM_PIXEL_OP_LOOP(op) \ -{ \ - const int destStride = destData.pixelStride; \ - do { dest->op; dest = addBytesToPointer (dest, destStride); } while (--width > 0); \ -} - -//============================================================================== -/** Contains classes for filling edge tables with various fill types. */ -namespace EdgeTableFillers -{ - /** Fills an edge-table with a solid colour. */ - template - class SolidColour - { - public: - SolidColour (const Image::BitmapData& image, const PixelARGB colour) - : destData (image), sourceColour (colour) - { - if (sizeof (PixelType) == 3 && destData.pixelStride == sizeof (PixelType)) - { - areRGBComponentsEqual = sourceColour.getRed() == sourceColour.getGreen() - && sourceColour.getGreen() == sourceColour.getBlue(); - filler[0].set (sourceColour); - filler[1].set (sourceColour); - filler[2].set (sourceColour); - filler[3].set (sourceColour); - } - else - { - areRGBComponentsEqual = false; - } - } - - forcedinline void setEdgeTableYPos (const int y) noexcept - { - linePixels = (PixelType*) destData.getLinePointer (y); - } - - forcedinline void handleEdgeTablePixel (const int x, const int alphaLevel) const noexcept - { - if (replaceExisting) - getPixel (x)->set (sourceColour); - else - getPixel (x)->blend (sourceColour, (uint32) alphaLevel); - } - - forcedinline void handleEdgeTablePixelFull (const int x) const noexcept - { - if (replaceExisting) - getPixel (x)->set (sourceColour); - else - getPixel (x)->blend (sourceColour); - } - - forcedinline void handleEdgeTableLine (const int x, const int width, const int alphaLevel) const noexcept - { - PixelARGB p (sourceColour); - p.multiplyAlpha (alphaLevel); - - PixelType* dest = getPixel (x); - - if (replaceExisting || p.getAlpha() >= 0xff) - replaceLine (dest, p, width); - else - blendLine (dest, p, width); - } - - forcedinline void handleEdgeTableLineFull (const int x, const int width) const noexcept - { - PixelType* dest = getPixel (x); - - if (replaceExisting || sourceColour.getAlpha() >= 0xff) - replaceLine (dest, sourceColour, width); - else - blendLine (dest, sourceColour, width); - } - - private: - const Image::BitmapData& destData; - PixelType* linePixels; - PixelARGB sourceColour; - PixelRGB filler [4]; - bool areRGBComponentsEqual; - - forcedinline PixelType* getPixel (const int x) const noexcept - { - return addBytesToPointer (linePixels, x * destData.pixelStride); - } - - inline void blendLine (PixelType* dest, const PixelARGB colour, int width) const noexcept - { - JUCE_PERFORM_PIXEL_OP_LOOP (blend (colour)) - } - - forcedinline void replaceLine (PixelRGB* dest, const PixelARGB colour, int width) const noexcept - { - if (destData.pixelStride == sizeof (*dest)) - { - if (areRGBComponentsEqual) // if all the component values are the same, we can cheat.. - { - memset (dest, colour.getRed(), (size_t) width * 3); - } - else - { - if (width >> 5) - { - const int* const intFiller = reinterpret_cast (filler); - - while (width > 8 && (((pointer_sized_int) dest) & 7) != 0) - { - dest->set (colour); - ++dest; - --width; - } - - while (width > 4) - { - int* d = reinterpret_cast (dest); - *d++ = intFiller[0]; - *d++ = intFiller[1]; - *d++ = intFiller[2]; - dest = reinterpret_cast (d); - width -= 4; - } - } - - while (--width >= 0) - { - dest->set (colour); - ++dest; - } - } - } - else - { - JUCE_PERFORM_PIXEL_OP_LOOP (set (colour)) - } - } - - forcedinline void replaceLine (PixelAlpha* dest, const PixelARGB colour, int width) const noexcept - { - if (destData.pixelStride == sizeof (*dest)) - memset (dest, colour.getAlpha(), (size_t) width); - else - JUCE_PERFORM_PIXEL_OP_LOOP (setAlpha (colour.getAlpha())) - } - - forcedinline void replaceLine (PixelARGB* dest, const PixelARGB colour, int width) const noexcept - { - JUCE_PERFORM_PIXEL_OP_LOOP (set (colour)) - } - - JUCE_DECLARE_NON_COPYABLE (SolidColour) - }; - - //============================================================================== - /** Fills an edge-table with a gradient. */ - template - class Gradient : public GradientType - { - public: - Gradient (const Image::BitmapData& dest, const ColourGradient& gradient, const AffineTransform& transform, - const PixelARGB* const colours, const int numColours) - : GradientType (gradient, transform, colours, numColours - 1), - destData (dest) - { - } - - forcedinline void setEdgeTableYPos (const int y) noexcept - { - linePixels = (PixelType*) destData.getLinePointer (y); - GradientType::setY (y); - } - - forcedinline void handleEdgeTablePixel (const int x, const int alphaLevel) const noexcept - { - getPixel (x)->blend (GradientType::getPixel (x), (uint32) alphaLevel); - } - - forcedinline void handleEdgeTablePixelFull (const int x) const noexcept - { - getPixel (x)->blend (GradientType::getPixel (x)); - } - - void handleEdgeTableLine (int x, int width, const int alphaLevel) const noexcept - { - PixelType* dest = getPixel (x); - - if (alphaLevel < 0xff) - JUCE_PERFORM_PIXEL_OP_LOOP (blend (GradientType::getPixel (x++), (uint32) alphaLevel)) - else - JUCE_PERFORM_PIXEL_OP_LOOP (blend (GradientType::getPixel (x++))) - } - - void handleEdgeTableLineFull (int x, int width) const noexcept - { - PixelType* dest = getPixel (x); - JUCE_PERFORM_PIXEL_OP_LOOP (blend (GradientType::getPixel (x++))) - } - - private: - const Image::BitmapData& destData; - PixelType* linePixels; - - forcedinline PixelType* getPixel (const int x) const noexcept - { - return addBytesToPointer (linePixels, x * destData.pixelStride); - } - - JUCE_DECLARE_NON_COPYABLE (Gradient) - }; - - //============================================================================== - /** Fills an edge-table with a non-transformed image. */ - template - class ImageFill - { - public: - ImageFill (const Image::BitmapData& dest, const Image::BitmapData& src, - const int alpha, const int x, const int y) - : destData (dest), - srcData (src), - extraAlpha (alpha + 1), - xOffset (repeatPattern ? negativeAwareModulo (x, src.width) - src.width : x), - yOffset (repeatPattern ? negativeAwareModulo (y, src.height) - src.height : y) - { - } - - forcedinline void setEdgeTableYPos (int y) noexcept - { - linePixels = (DestPixelType*) destData.getLinePointer (y); - - y -= yOffset; - if (repeatPattern) - { - jassert (y >= 0); - y %= srcData.height; - } - - sourceLineStart = (SrcPixelType*) srcData.getLinePointer (y); - } - - forcedinline void handleEdgeTablePixel (const int x, int alphaLevel) const noexcept - { - alphaLevel = (alphaLevel * extraAlpha) >> 8; - - getDestPixel (x)->blend (*getSrcPixel (repeatPattern ? ((x - xOffset) % srcData.width) : (x - xOffset)), (uint32) alphaLevel); - } - - forcedinline void handleEdgeTablePixelFull (const int x) const noexcept - { - getDestPixel (x)->blend (*getSrcPixel (repeatPattern ? ((x - xOffset) % srcData.width) : (x - xOffset)), (uint32) extraAlpha); - } - - void handleEdgeTableLine (int x, int width, int alphaLevel) const noexcept - { - DestPixelType* dest = getDestPixel (x); - alphaLevel = (alphaLevel * extraAlpha) >> 8; - x -= xOffset; - - if (repeatPattern) - { - if (alphaLevel < 0xfe) - JUCE_PERFORM_PIXEL_OP_LOOP (blend (*getSrcPixel (x++ % srcData.width), (uint32) alphaLevel)) - else - JUCE_PERFORM_PIXEL_OP_LOOP (blend (*getSrcPixel (x++ % srcData.width))) - } - else - { - jassert (x >= 0 && x + width <= srcData.width); - - if (alphaLevel < 0xfe) - JUCE_PERFORM_PIXEL_OP_LOOP (blend (*getSrcPixel (x++), (uint32) alphaLevel)) - else - copyRow (dest, getSrcPixel (x), width); - } - } - - void handleEdgeTableLineFull (int x, int width) const noexcept - { - DestPixelType* dest = getDestPixel (x); - x -= xOffset; - - if (repeatPattern) - { - if (extraAlpha < 0xfe) - JUCE_PERFORM_PIXEL_OP_LOOP (blend (*getSrcPixel (x++ % srcData.width), (uint32) extraAlpha)) - else - JUCE_PERFORM_PIXEL_OP_LOOP (blend (*getSrcPixel (x++ % srcData.width))) - } - else - { - jassert (x >= 0 && x + width <= srcData.width); - - if (extraAlpha < 0xfe) - JUCE_PERFORM_PIXEL_OP_LOOP (blend (*getSrcPixel (x++), (uint32) extraAlpha)) - else - copyRow (dest, getSrcPixel (x), width); - } - } - - void clipEdgeTableLine (EdgeTable& et, int x, int y, int width) - { - jassert (x - xOffset >= 0 && x + width - xOffset <= srcData.width); - SrcPixelType* s = (SrcPixelType*) srcData.getLinePointer (y - yOffset); - uint8* mask = (uint8*) (s + x - xOffset); - - if (sizeof (SrcPixelType) == sizeof (PixelARGB)) - mask += PixelARGB::indexA; - - et.clipLineToMask (x, y, mask, sizeof (SrcPixelType), width); - } - - private: - const Image::BitmapData& destData; - const Image::BitmapData& srcData; - const int extraAlpha, xOffset, yOffset; - DestPixelType* linePixels; - SrcPixelType* sourceLineStart; - - forcedinline DestPixelType* getDestPixel (int const x) const noexcept - { - return addBytesToPointer (linePixels, x * destData.pixelStride); - } - - forcedinline SrcPixelType const* getSrcPixel (int const x) const noexcept - { - return addBytesToPointer (sourceLineStart, x * srcData.pixelStride); - } - - forcedinline void copyRow (DestPixelType* dest, SrcPixelType const* src, int width) const noexcept - { - const int destStride = destData.pixelStride; - const int srcStride = srcData.pixelStride; - - if (destStride == srcStride - && srcData.pixelFormat == Image::RGB - && destData.pixelFormat == Image::RGB) - { - memcpy (dest, src, (size_t) (width * srcStride)); - } - else - { - do - { - dest->blend (*src); - dest = addBytesToPointer (dest, destStride); - src = addBytesToPointer (src, srcStride); - } while (--width > 0); - } - } - - JUCE_DECLARE_NON_COPYABLE (ImageFill) - }; - - //============================================================================== - /** Fills an edge-table with a transformed image. */ - template - class TransformedImageFill - { - public: - TransformedImageFill (const Image::BitmapData& dest, const Image::BitmapData& src, - const AffineTransform& transform, const int alpha, const Graphics::ResamplingQuality q) - : interpolator (transform, - q != Graphics::lowResamplingQuality ? 0.5f : 0.0f, - q != Graphics::lowResamplingQuality ? -128 : 0), - destData (dest), - srcData (src), - extraAlpha (alpha + 1), - quality (q), - maxX (src.width - 1), - maxY (src.height - 1), - scratchSize (2048) - { - scratchBuffer.malloc (scratchSize); - } - - forcedinline void setEdgeTableYPos (const int newY) noexcept - { - y = newY; - linePixels = (DestPixelType*) destData.getLinePointer (newY); - } - - forcedinline void handleEdgeTablePixel (const int x, const int alphaLevel) noexcept - { - SrcPixelType p; - generate (&p, x, 1); - - getDestPixel (x)->blend (p, (uint32) (alphaLevel * extraAlpha) >> 8); - } - - forcedinline void handleEdgeTablePixelFull (const int x) noexcept - { - SrcPixelType p; - generate (&p, x, 1); - - getDestPixel (x)->blend (p, (uint32) extraAlpha); - } - - void handleEdgeTableLine (const int x, int width, int alphaLevel) noexcept - { - if (width > (int) scratchSize) - { - scratchSize = (size_t) width; - scratchBuffer.malloc (scratchSize); - } - - SrcPixelType* span = scratchBuffer; - generate (span, x, width); - - DestPixelType* dest = getDestPixel (x); - alphaLevel *= extraAlpha; - alphaLevel >>= 8; - - if (alphaLevel < 0xfe) - JUCE_PERFORM_PIXEL_OP_LOOP (blend (*span++, (uint32) alphaLevel)) - else - JUCE_PERFORM_PIXEL_OP_LOOP (blend (*span++)) - } - - forcedinline void handleEdgeTableLineFull (const int x, int width) noexcept - { - handleEdgeTableLine (x, width, 255); - } - - void clipEdgeTableLine (EdgeTable& et, int x, int y_, int width) - { - if (width > (int) scratchSize) - { - scratchSize = (size_t) width; - scratchBuffer.malloc (scratchSize); - } - - y = y_; - generate (scratchBuffer.getData(), x, width); - - et.clipLineToMask (x, y_, - reinterpret_cast (scratchBuffer.getData()) + SrcPixelType::indexA, - sizeof (SrcPixelType), width); - } - - private: - forcedinline DestPixelType* getDestPixel (const int x) const noexcept - { - return addBytesToPointer (linePixels, x * destData.pixelStride); - } - - //============================================================================== - template - void generate (PixelType* dest, const int x, int numPixels) noexcept - { - this->interpolator.setStartOfLine ((float) x, (float) y, numPixels); - - do - { - int hiResX, hiResY; - this->interpolator.next (hiResX, hiResY); - - int loResX = hiResX >> 8; - int loResY = hiResY >> 8; - - if (repeatPattern) - { - loResX = negativeAwareModulo (loResX, srcData.width); - loResY = negativeAwareModulo (loResY, srcData.height); - } - - if (quality != Graphics::lowResamplingQuality) - { - if (isPositiveAndBelow (loResX, maxX)) - { - if (isPositiveAndBelow (loResY, maxY)) - { - // In the centre of the image.. - render4PixelAverage (dest, this->srcData.getPixelPointer (loResX, loResY), - hiResX & 255, hiResY & 255); - ++dest; - continue; - } - - if (! repeatPattern) - { - // At a top or bottom edge.. - if (loResY < 0) - render2PixelAverageX (dest, this->srcData.getPixelPointer (loResX, 0), hiResX & 255); - else - render2PixelAverageX (dest, this->srcData.getPixelPointer (loResX, maxY), hiResX & 255); - - ++dest; - continue; - } - } - else - { - if (isPositiveAndBelow (loResY, maxY) && ! repeatPattern) - { - // At a left or right hand edge.. - if (loResX < 0) - render2PixelAverageY (dest, this->srcData.getPixelPointer (0, loResY), hiResY & 255); - else - render2PixelAverageY (dest, this->srcData.getPixelPointer (maxX, loResY), hiResY & 255); - - ++dest; - continue; - } - } - } - - if (! repeatPattern) - { - if (loResX < 0) loResX = 0; - if (loResY < 0) loResY = 0; - if (loResX > maxX) loResX = maxX; - if (loResY > maxY) loResY = maxY; - } - - dest->set (*(const PixelType*) this->srcData.getPixelPointer (loResX, loResY)); - ++dest; - - } while (--numPixels > 0); - } - - //============================================================================== - void render4PixelAverage (PixelARGB* const dest, const uint8* src, const int subPixelX, const int subPixelY) noexcept - { - uint32 c[4] = { 256 * 128, 256 * 128, 256 * 128, 256 * 128 }; - - uint32 weight = (uint32) ((256 - subPixelX) * (256 - subPixelY)); - c[0] += weight * src[0]; - c[1] += weight * src[1]; - c[2] += weight * src[2]; - c[3] += weight * src[3]; - - src += this->srcData.pixelStride; - - weight = (uint32) (subPixelX * (256 - subPixelY)); - c[0] += weight * src[0]; - c[1] += weight * src[1]; - c[2] += weight * src[2]; - c[3] += weight * src[3]; - - src += this->srcData.lineStride; - - weight = (uint32) (subPixelX * subPixelY); - c[0] += weight * src[0]; - c[1] += weight * src[1]; - c[2] += weight * src[2]; - c[3] += weight * src[3]; - - src -= this->srcData.pixelStride; - - weight = (uint32) ((256 - subPixelX) * subPixelY); - c[0] += weight * src[0]; - c[1] += weight * src[1]; - c[2] += weight * src[2]; - c[3] += weight * src[3]; - - dest->setARGB ((uint8) (c[PixelARGB::indexA] >> 16), - (uint8) (c[PixelARGB::indexR] >> 16), - (uint8) (c[PixelARGB::indexG] >> 16), - (uint8) (c[PixelARGB::indexB] >> 16)); - } - - void render2PixelAverageX (PixelARGB* const dest, const uint8* src, const uint32 subPixelX) noexcept - { - uint32 c[4] = { 128, 128, 128, 128 }; - - uint32 weight = 256 - subPixelX; - c[0] += weight * src[0]; - c[1] += weight * src[1]; - c[2] += weight * src[2]; - c[3] += weight * src[3]; - - src += this->srcData.pixelStride; - - weight = subPixelX; - c[0] += weight * src[0]; - c[1] += weight * src[1]; - c[2] += weight * src[2]; - c[3] += weight * src[3]; - - dest->setARGB ((uint8) (c[PixelARGB::indexA] >> 8), - (uint8) (c[PixelARGB::indexR] >> 8), - (uint8) (c[PixelARGB::indexG] >> 8), - (uint8) (c[PixelARGB::indexB] >> 8)); - } - - void render2PixelAverageY (PixelARGB* const dest, const uint8* src, const uint32 subPixelY) noexcept - { - uint32 c[4] = { 128, 128, 128, 128 }; - - uint32 weight = 256 - subPixelY; - c[0] += weight * src[0]; - c[1] += weight * src[1]; - c[2] += weight * src[2]; - c[3] += weight * src[3]; - - src += this->srcData.lineStride; - - weight = subPixelY; - c[0] += weight * src[0]; - c[1] += weight * src[1]; - c[2] += weight * src[2]; - c[3] += weight * src[3]; - - dest->setARGB ((uint8) (c[PixelARGB::indexA] >> 8), - (uint8) (c[PixelARGB::indexR] >> 8), - (uint8) (c[PixelARGB::indexG] >> 8), - (uint8) (c[PixelARGB::indexB] >> 8)); - } - - //============================================================================== - void render4PixelAverage (PixelRGB* const dest, const uint8* src, const uint32 subPixelX, const uint32 subPixelY) noexcept - { - uint32 c[3] = { 256 * 128, 256 * 128, 256 * 128 }; - - uint32 weight = (256 - subPixelX) * (256 - subPixelY); - c[0] += weight * src[0]; - c[1] += weight * src[1]; - c[2] += weight * src[2]; - - src += this->srcData.pixelStride; - - weight = subPixelX * (256 - subPixelY); - c[0] += weight * src[0]; - c[1] += weight * src[1]; - c[2] += weight * src[2]; - - src += this->srcData.lineStride; - - weight = subPixelX * subPixelY; - c[0] += weight * src[0]; - c[1] += weight * src[1]; - c[2] += weight * src[2]; - - src -= this->srcData.pixelStride; - - weight = (256 - subPixelX) * subPixelY; - c[0] += weight * src[0]; - c[1] += weight * src[1]; - c[2] += weight * src[2]; - - dest->setARGB ((uint8) 255, - (uint8) (c[PixelRGB::indexR] >> 16), - (uint8) (c[PixelRGB::indexG] >> 16), - (uint8) (c[PixelRGB::indexB] >> 16)); - } - - void render2PixelAverageX (PixelRGB* const dest, const uint8* src, const uint32 subPixelX) noexcept - { - uint32 c[3] = { 128, 128, 128 }; - - const uint32 weight = 256 - subPixelX; - c[0] += weight * src[0]; - c[1] += weight * src[1]; - c[2] += weight * src[2]; - - src += this->srcData.pixelStride; - - c[0] += subPixelX * src[0]; - c[1] += subPixelX * src[1]; - c[2] += subPixelX * src[2]; - - dest->setARGB ((uint8) 255, - (uint8) (c[PixelRGB::indexR] >> 8), - (uint8) (c[PixelRGB::indexG] >> 8), - (uint8) (c[PixelRGB::indexB] >> 8)); - } - - void render2PixelAverageY (PixelRGB* const dest, const uint8* src, const uint32 subPixelY) noexcept - { - uint32 c[3] = { 128, 128, 128 }; - - const uint32 weight = 256 - subPixelY; - c[0] += weight * src[0]; - c[1] += weight * src[1]; - c[2] += weight * src[2]; - - src += this->srcData.lineStride; - - c[0] += subPixelY * src[0]; - c[1] += subPixelY * src[1]; - c[2] += subPixelY * src[2]; - - dest->setARGB ((uint8) 255, - (uint8) (c[PixelRGB::indexR] >> 8), - (uint8) (c[PixelRGB::indexG] >> 8), - (uint8) (c[PixelRGB::indexB] >> 8)); - } - - //============================================================================== - void render4PixelAverage (PixelAlpha* const dest, const uint8* src, const uint32 subPixelX, const uint32 subPixelY) noexcept - { - uint32 c = 256 * 128; - c += src[0] * ((256 - subPixelX) * (256 - subPixelY)); - src += this->srcData.pixelStride; - c += src[1] * (subPixelX * (256 - subPixelY)); - src += this->srcData.lineStride; - c += src[1] * (subPixelX * subPixelY); - src -= this->srcData.pixelStride; - - c += src[0] * ((256 - subPixelX) * subPixelY); - - *((uint8*) dest) = (uint8) (c >> 16); - } - - void render2PixelAverageX (PixelAlpha* const dest, const uint8* src, const uint32 subPixelX) noexcept - { - uint32 c = 128; - c += src[0] * (256 - subPixelX); - src += this->srcData.pixelStride; - c += src[0] * subPixelX; - *((uint8*) dest) = (uint8) (c >> 8); - } - - void render2PixelAverageY (PixelAlpha* const dest, const uint8* src, const uint32 subPixelY) noexcept - { - uint32 c = 128; - c += src[0] * (256 - subPixelY); - src += this->srcData.lineStride; - c += src[0] * subPixelY; - *((uint8*) dest) = (uint8) (c >> 8); - } - - //============================================================================== - class TransformedImageSpanInterpolator - { - public: - TransformedImageSpanInterpolator (const AffineTransform& transform, - const float offsetFloat, const int offsetInt) noexcept - : inverseTransform (transform.inverted()), - pixelOffset (offsetFloat), pixelOffsetInt (offsetInt) - {} - - void setStartOfLine (float sx, float sy, const int numPixels) noexcept - { - jassert (numPixels > 0); - - sx += pixelOffset; - sy += pixelOffset; - float x1 = sx, y1 = sy; - sx += numPixels; - inverseTransform.transformPoints (x1, y1, sx, sy); - - xBresenham.set ((int) (x1 * 256.0f), (int) (sx * 256.0f), numPixels, pixelOffsetInt); - yBresenham.set ((int) (y1 * 256.0f), (int) (sy * 256.0f), numPixels, pixelOffsetInt); - } - - void next (int& px, int& py) noexcept - { - px = xBresenham.n; xBresenham.stepToNext(); - py = yBresenham.n; yBresenham.stepToNext(); - } - - private: - class BresenhamInterpolator - { - public: - BresenhamInterpolator() noexcept {} - - void set (const int n1, const int n2, const int steps, const int offsetInt) noexcept - { - numSteps = steps; - step = (n2 - n1) / numSteps; - remainder = modulo = (n2 - n1) % numSteps; - n = n1 + offsetInt; - - if (modulo <= 0) - { - modulo += numSteps; - remainder += numSteps; - --step; - } - - modulo -= numSteps; - } - - forcedinline void stepToNext() noexcept - { - modulo += remainder; - n += step; - - if (modulo > 0) - { - modulo -= numSteps; - ++n; - } - } - - int n; - - private: - int numSteps, step, modulo, remainder; - }; - - const AffineTransform inverseTransform; - BresenhamInterpolator xBresenham, yBresenham; - const float pixelOffset; - const int pixelOffsetInt; - - JUCE_DECLARE_NON_COPYABLE (TransformedImageSpanInterpolator) - }; - - //============================================================================== - TransformedImageSpanInterpolator interpolator; - const Image::BitmapData& destData; - const Image::BitmapData& srcData; - const int extraAlpha; - const Graphics::ResamplingQuality quality; - const int maxX, maxY; - int y; - DestPixelType* linePixels; - HeapBlock scratchBuffer; - size_t scratchSize; - - JUCE_DECLARE_NON_COPYABLE (TransformedImageFill) - }; - - - //============================================================================== - template - void renderImageTransformed (Iterator& iter, const Image::BitmapData& destData, const Image::BitmapData& srcData, - const int alpha, const AffineTransform& transform, Graphics::ResamplingQuality quality, bool tiledFill) - { - switch (destData.pixelFormat) - { - case Image::ARGB: - switch (srcData.pixelFormat) - { - case Image::ARGB: - if (tiledFill) { TransformedImageFill r (destData, srcData, transform, alpha, quality); iter.iterate (r); } - else { TransformedImageFill r (destData, srcData, transform, alpha, quality); iter.iterate (r); } - break; - case Image::RGB: - if (tiledFill) { TransformedImageFill r (destData, srcData, transform, alpha, quality); iter.iterate (r); } - else { TransformedImageFill r (destData, srcData, transform, alpha, quality); iter.iterate (r); } - break; - default: - if (tiledFill) { TransformedImageFill r (destData, srcData, transform, alpha, quality); iter.iterate (r); } - else { TransformedImageFill r (destData, srcData, transform, alpha, quality); iter.iterate (r); } - break; - } - break; - - case Image::RGB: - switch (srcData.pixelFormat) - { - case Image::ARGB: - if (tiledFill) { TransformedImageFill r (destData, srcData, transform, alpha, quality); iter.iterate (r); } - else { TransformedImageFill r (destData, srcData, transform, alpha, quality); iter.iterate (r); } - break; - case Image::RGB: - if (tiledFill) { TransformedImageFill r (destData, srcData, transform, alpha, quality); iter.iterate (r); } - else { TransformedImageFill r (destData, srcData, transform, alpha, quality); iter.iterate (r); } - break; - default: - if (tiledFill) { TransformedImageFill r (destData, srcData, transform, alpha, quality); iter.iterate (r); } - else { TransformedImageFill r (destData, srcData, transform, alpha, quality); iter.iterate (r); } - break; - } - break; - - default: - switch (srcData.pixelFormat) - { - case Image::ARGB: - if (tiledFill) { TransformedImageFill r (destData, srcData, transform, alpha, quality); iter.iterate (r); } - else { TransformedImageFill r (destData, srcData, transform, alpha, quality); iter.iterate (r); } - break; - case Image::RGB: - if (tiledFill) { TransformedImageFill r (destData, srcData, transform, alpha, quality); iter.iterate (r); } - else { TransformedImageFill r (destData, srcData, transform, alpha, quality); iter.iterate (r); } - break; - default: - if (tiledFill) { TransformedImageFill r (destData, srcData, transform, alpha, quality); iter.iterate (r); } - else { TransformedImageFill r (destData, srcData, transform, alpha, quality); iter.iterate (r); } - break; - } - break; - } - } - - template - void renderImageUntransformed (Iterator& iter, const Image::BitmapData& destData, const Image::BitmapData& srcData, const int alpha, int x, int y, bool tiledFill) - { - switch (destData.pixelFormat) - { - case Image::ARGB: - switch (srcData.pixelFormat) - { - case Image::ARGB: - if (tiledFill) { ImageFill r (destData, srcData, alpha, x, y); iter.iterate (r); } - else { ImageFill r (destData, srcData, alpha, x, y); iter.iterate (r); } - break; - case Image::RGB: - if (tiledFill) { ImageFill r (destData, srcData, alpha, x, y); iter.iterate (r); } - else { ImageFill r (destData, srcData, alpha, x, y); iter.iterate (r); } - break; - default: - if (tiledFill) { ImageFill r (destData, srcData, alpha, x, y); iter.iterate (r); } - else { ImageFill r (destData, srcData, alpha, x, y); iter.iterate (r); } - break; - } - break; - - case Image::RGB: - switch (srcData.pixelFormat) - { - case Image::ARGB: - if (tiledFill) { ImageFill r (destData, srcData, alpha, x, y); iter.iterate (r); } - else { ImageFill r (destData, srcData, alpha, x, y); iter.iterate (r); } - break; - case Image::RGB: - if (tiledFill) { ImageFill r (destData, srcData, alpha, x, y); iter.iterate (r); } - else { ImageFill r (destData, srcData, alpha, x, y); iter.iterate (r); } - break; - default: - if (tiledFill) { ImageFill r (destData, srcData, alpha, x, y); iter.iterate (r); } - else { ImageFill r (destData, srcData, alpha, x, y); iter.iterate (r); } - break; - } - break; - - default: - switch (srcData.pixelFormat) - { - case Image::ARGB: - if (tiledFill) { ImageFill r (destData, srcData, alpha, x, y); iter.iterate (r); } - else { ImageFill r (destData, srcData, alpha, x, y); iter.iterate (r); } - break; - case Image::RGB: - if (tiledFill) { ImageFill r (destData, srcData, alpha, x, y); iter.iterate (r); } - else { ImageFill r (destData, srcData, alpha, x, y); iter.iterate (r); } - break; - default: - if (tiledFill) { ImageFill r (destData, srcData, alpha, x, y); iter.iterate (r); } - else { ImageFill r (destData, srcData, alpha, x, y); iter.iterate (r); } - break; - } - break; - } - } - - template - void renderSolidFill (Iterator& iter, const Image::BitmapData& destData, const PixelARGB fillColour, const bool replaceContents, DestPixelType*) - { - if (replaceContents) - { - EdgeTableFillers::SolidColour r (destData, fillColour); - iter.iterate (r); - } - else - { - EdgeTableFillers::SolidColour r (destData, fillColour); - iter.iterate (r); - } - } - - template - void renderGradient (Iterator& iter, const Image::BitmapData& destData, const ColourGradient& g, const AffineTransform& transform, - const PixelARGB* const lookupTable, const int numLookupEntries, const bool isIdentity, DestPixelType*) - { - if (g.isRadial) - { - if (isIdentity) - { - EdgeTableFillers::Gradient renderer (destData, g, transform, lookupTable, numLookupEntries); - iter.iterate (renderer); - } - else - { - EdgeTableFillers::Gradient renderer (destData, g, transform, lookupTable, numLookupEntries); - iter.iterate (renderer); - } - } - else - { - EdgeTableFillers::Gradient renderer (destData, g, transform, lookupTable, numLookupEntries); - iter.iterate (renderer); - } - } -} - -//============================================================================== -template -struct ClipRegions -{ - class Base : public SingleThreadedReferenceCountedObject - { - public: - Base() {} - virtual ~Base() {} - - typedef ReferenceCountedObjectPtr Ptr; - - virtual Ptr clone() const = 0; - virtual Ptr applyClipTo (const Ptr& target) const = 0; - - virtual Ptr clipToRectangle (const Rectangle&) = 0; - virtual Ptr clipToRectangleList (const RectangleList&) = 0; - virtual Ptr excludeClipRectangle (const Rectangle&) = 0; - virtual Ptr clipToPath (const Path&, const AffineTransform&) = 0; - virtual Ptr clipToEdgeTable (const EdgeTable& et) = 0; - virtual Ptr clipToImageAlpha (const Image&, const AffineTransform&, const Graphics::ResamplingQuality) = 0; - virtual void translate (Point delta) = 0; - - virtual bool clipRegionIntersects (const Rectangle&) const = 0; - virtual Rectangle getClipBounds() const = 0; - - virtual void fillRectWithColour (SavedStateType&, const Rectangle&, const PixelARGB colour, bool replaceContents) const = 0; - virtual void fillRectWithColour (SavedStateType&, const Rectangle&, const PixelARGB colour) const = 0; - virtual void fillAllWithColour (SavedStateType&, const PixelARGB colour, bool replaceContents) const = 0; - virtual void fillAllWithGradient (SavedStateType&, ColourGradient&, const AffineTransform&, bool isIdentity) const = 0; - virtual void renderImageTransformed (SavedStateType&, const Image&, const int alpha, const AffineTransform&, Graphics::ResamplingQuality, bool tiledFill) const = 0; - virtual void renderImageUntransformed (SavedStateType&, const Image&, const int alpha, int x, int y, bool tiledFill) const = 0; - }; - - //============================================================================== - class EdgeTableRegion : public Base - { - public: - EdgeTableRegion (const EdgeTable& e) : edgeTable (e) {} - EdgeTableRegion (const Rectangle& r) : edgeTable (r) {} - EdgeTableRegion (const Rectangle& r) : edgeTable (r) {} - EdgeTableRegion (const RectangleList& r) : edgeTable (r) {} - EdgeTableRegion (const RectangleList& r) : edgeTable (r) {} - EdgeTableRegion (const Rectangle& bounds, const Path& p, const AffineTransform& t) : edgeTable (bounds, p, t) {} - EdgeTableRegion (const EdgeTableRegion& other) : Base(), edgeTable (other.edgeTable) {} - - typedef typename Base::Ptr Ptr; - - Ptr clone() const { return new EdgeTableRegion (*this); } - Ptr applyClipTo (const Ptr& target) const { return target->clipToEdgeTable (edgeTable); } - - Ptr clipToRectangle (const Rectangle& r) - { - edgeTable.clipToRectangle (r); - return edgeTable.isEmpty() ? nullptr : this; - } - - Ptr clipToRectangleList (const RectangleList& r) - { - RectangleList inverse (edgeTable.getMaximumBounds()); - - if (inverse.subtract (r)) - for (const Rectangle* i = inverse.begin(), * const e = inverse.end(); i != e; ++i) - edgeTable.excludeRectangle (*i); - - return edgeTable.isEmpty() ? nullptr : this; - } - - Ptr excludeClipRectangle (const Rectangle& r) - { - edgeTable.excludeRectangle (r); - return edgeTable.isEmpty() ? nullptr : this; - } - - Ptr clipToPath (const Path& p, const AffineTransform& transform) - { - EdgeTable et (edgeTable.getMaximumBounds(), p, transform); - edgeTable.clipToEdgeTable (et); - return edgeTable.isEmpty() ? nullptr : this; - } - - Ptr clipToEdgeTable (const EdgeTable& et) - { - edgeTable.clipToEdgeTable (et); - return edgeTable.isEmpty() ? nullptr : this; - } - - Ptr clipToImageAlpha (const Image& image, const AffineTransform& transform, const Graphics::ResamplingQuality quality) - { - const Image::BitmapData srcData (image, Image::BitmapData::readOnly); - - if (transform.isOnlyTranslation()) - { - // If our translation doesn't involve any distortion, just use a simple blit.. - const int tx = (int) (transform.getTranslationX() * 256.0f); - const int ty = (int) (transform.getTranslationY() * 256.0f); - - if (quality == Graphics::lowResamplingQuality || ((tx | ty) & 224) == 0) - { - const int imageX = ((tx + 128) >> 8); - const int imageY = ((ty + 128) >> 8); - - if (image.getFormat() == Image::ARGB) - straightClipImage (srcData, imageX, imageY, (PixelARGB*) 0); - else - straightClipImage (srcData, imageX, imageY, (PixelAlpha*) 0); - - return edgeTable.isEmpty() ? nullptr : this; - } - } - - if (transform.isSingularity()) - return Ptr(); - - { - Path p; - p.addRectangle (0, 0, (float) srcData.width, (float) srcData.height); - EdgeTable et2 (edgeTable.getMaximumBounds(), p, transform); - edgeTable.clipToEdgeTable (et2); - } - - if (! edgeTable.isEmpty()) - { - if (image.getFormat() == Image::ARGB) - transformedClipImage (srcData, transform, quality, (PixelARGB*) 0); - else - transformedClipImage (srcData, transform, quality, (PixelAlpha*) 0); - } - - return edgeTable.isEmpty() ? nullptr : this; - } - - void translate (Point delta) - { - edgeTable.translate ((float) delta.x, delta.y); - } - - bool clipRegionIntersects (const Rectangle& r) const - { - return edgeTable.getMaximumBounds().intersects (r); - } - - Rectangle getClipBounds() const - { - return edgeTable.getMaximumBounds(); - } - - void fillRectWithColour (SavedStateType& state, const Rectangle& area, const PixelARGB colour, bool replaceContents) const - { - const Rectangle totalClip (edgeTable.getMaximumBounds()); - const Rectangle clipped (totalClip.getIntersection (area)); - - if (! clipped.isEmpty()) - { - EdgeTableRegion et (clipped); - et.edgeTable.clipToEdgeTable (edgeTable); - state.fillWithSolidColour (et.edgeTable, colour, replaceContents); - } - } - - void fillRectWithColour (SavedStateType& state, const Rectangle& area, const PixelARGB colour) const - { - const Rectangle totalClip (edgeTable.getMaximumBounds().toFloat()); - const Rectangle clipped (totalClip.getIntersection (area)); - - if (! clipped.isEmpty()) - { - EdgeTableRegion et (clipped); - et.edgeTable.clipToEdgeTable (edgeTable); - state.fillWithSolidColour (et.edgeTable, colour, false); - } - } - - void fillAllWithColour (SavedStateType& state, const PixelARGB colour, bool replaceContents) const - { - state.fillWithSolidColour (edgeTable, colour, replaceContents); - } - - void fillAllWithGradient (SavedStateType& state, ColourGradient& gradient, const AffineTransform& transform, bool isIdentity) const - { - state.fillWithGradient (edgeTable, gradient, transform, isIdentity); - } - - void renderImageTransformed (SavedStateType& state, const Image& src, const int alpha, const AffineTransform& transform, Graphics::ResamplingQuality quality, bool tiledFill) const - { - state.renderImageTransformed (edgeTable, src, alpha, transform, quality, tiledFill); - } - - void renderImageUntransformed (SavedStateType& state, const Image& src, const int alpha, int x, int y, bool tiledFill) const - { - state.renderImageUntransformed (edgeTable, src, alpha, x, y, tiledFill); - } - - EdgeTable edgeTable; - - private: - template - void transformedClipImage (const Image::BitmapData& srcData, const AffineTransform& transform, const Graphics::ResamplingQuality quality, const SrcPixelType*) - { - EdgeTableFillers::TransformedImageFill renderer (srcData, srcData, transform, 255, quality); - - for (int y = 0; y < edgeTable.getMaximumBounds().getHeight(); ++y) - renderer.clipEdgeTableLine (edgeTable, edgeTable.getMaximumBounds().getX(), y + edgeTable.getMaximumBounds().getY(), - edgeTable.getMaximumBounds().getWidth()); - } - - template - void straightClipImage (const Image::BitmapData& srcData, int imageX, int imageY, const SrcPixelType*) - { - Rectangle r (imageX, imageY, srcData.width, srcData.height); - edgeTable.clipToRectangle (r); - - EdgeTableFillers::ImageFill renderer (srcData, srcData, 255, imageX, imageY); - - for (int y = 0; y < r.getHeight(); ++y) - renderer.clipEdgeTableLine (edgeTable, r.getX(), y + r.getY(), r.getWidth()); - } - - EdgeTableRegion& operator= (const EdgeTableRegion&); - }; - - //============================================================================== - class RectangleListRegion : public Base - { - public: - RectangleListRegion (const Rectangle& r) : clip (r) {} - RectangleListRegion (const RectangleList& r) : clip (r) {} - RectangleListRegion (const RectangleListRegion& other) : Base(), clip (other.clip) {} - - typedef typename Base::Ptr Ptr; - - Ptr clone() const { return new RectangleListRegion (*this); } - Ptr applyClipTo (const Ptr& target) const { return target->clipToRectangleList (clip); } - - Ptr clipToRectangle (const Rectangle& r) - { - clip.clipTo (r); - return clip.isEmpty() ? nullptr : this; - } - - Ptr clipToRectangleList (const RectangleList& r) - { - clip.clipTo (r); - return clip.isEmpty() ? nullptr : this; - } - - Ptr excludeClipRectangle (const Rectangle& r) - { - clip.subtract (r); - return clip.isEmpty() ? nullptr : this; - } - - Ptr clipToPath (const Path& p, const AffineTransform& transform) { return toEdgeTable()->clipToPath (p, transform); } - Ptr clipToEdgeTable (const EdgeTable& et) { return toEdgeTable()->clipToEdgeTable (et); } - - Ptr clipToImageAlpha (const Image& image, const AffineTransform& transform, const Graphics::ResamplingQuality quality) - { - return toEdgeTable()->clipToImageAlpha (image, transform, quality); - } - - void translate (Point delta) { clip.offsetAll (delta); } - bool clipRegionIntersects (const Rectangle& r) const { return clip.intersects (r); } - Rectangle getClipBounds() const { return clip.getBounds(); } - - void fillRectWithColour (SavedStateType& state, const Rectangle& area, const PixelARGB colour, bool replaceContents) const - { - SubRectangleIterator iter (clip, area); - state.fillWithSolidColour (iter, colour, replaceContents); - } - - void fillRectWithColour (SavedStateType& state, const Rectangle& area, const PixelARGB colour) const - { - SubRectangleIteratorFloat iter (clip, area); - state.fillWithSolidColour (iter, colour, false); - } - - void fillAllWithColour (SavedStateType& state, const PixelARGB colour, bool replaceContents) const - { - state.fillWithSolidColour (*this, colour, replaceContents); - } - - void fillAllWithGradient (SavedStateType& state, ColourGradient& gradient, const AffineTransform& transform, bool isIdentity) const - { - state.fillWithGradient (*this, gradient, transform, isIdentity); - } - - void renderImageTransformed (SavedStateType& state, const Image& src, const int alpha, const AffineTransform& transform, Graphics::ResamplingQuality quality, bool tiledFill) const - { - state.renderImageTransformed (*this, src, alpha, transform, quality, tiledFill); - } - - void renderImageUntransformed (SavedStateType& state, const Image& src, const int alpha, int x, int y, bool tiledFill) const - { - state.renderImageUntransformed (*this, src, alpha, x, y, tiledFill); - } - - RectangleList clip; - - //============================================================================== - template - void iterate (Renderer& r) const noexcept - { - for (const Rectangle* i = clip.begin(), * const e = clip.end(); i != e; ++i) - { - const int x = i->getX(); - const int w = i->getWidth(); - jassert (w > 0); - const int bottom = i->getBottom(); - - for (int y = i->getY(); y < bottom; ++y) - { - r.setEdgeTableYPos (y); - r.handleEdgeTableLineFull (x, w); - } - } - } - - private: - //============================================================================== - class SubRectangleIterator - { - public: - SubRectangleIterator (const RectangleList& clipList, const Rectangle& clipBounds) - : clip (clipList), area (clipBounds) - {} - - template - void iterate (Renderer& r) const noexcept - { - for (const Rectangle* i = clip.begin(), * const e = clip.end(); i != e; ++i) - { - const Rectangle rect (i->getIntersection (area)); - - if (! rect.isEmpty()) - { - const int x = rect.getX(); - const int w = rect.getWidth(); - const int bottom = rect.getBottom(); - - for (int y = rect.getY(); y < bottom; ++y) - { - r.setEdgeTableYPos (y); - r.handleEdgeTableLineFull (x, w); - } - } - } - } - - private: - const RectangleList& clip; - const Rectangle area; - - JUCE_DECLARE_NON_COPYABLE (SubRectangleIterator) - }; - - //============================================================================== - class SubRectangleIteratorFloat - { - public: - SubRectangleIteratorFloat (const RectangleList& clipList, const Rectangle& clipBounds) noexcept - : clip (clipList), area (clipBounds) - { - } - - template - void iterate (Renderer& r) const noexcept - { - const RenderingHelpers::FloatRectangleRasterisingInfo f (area); - - for (const Rectangle* i = clip.begin(), * const e = clip.end(); i != e; ++i) - { - const int clipLeft = i->getX(); - const int clipRight = i->getRight(); - const int clipTop = i->getY(); - const int clipBottom = i->getBottom(); - - if (f.totalBottom > clipTop && f.totalTop < clipBottom - && f.totalRight > clipLeft && f.totalLeft < clipRight) - { - if (f.isOnePixelWide()) - { - if (f.topAlpha != 0 && f.totalTop >= clipTop) - { - r.setEdgeTableYPos (f.totalTop); - r.handleEdgeTablePixel (f.left, f.topAlpha); - } - - const int endY = jmin (f.bottom, clipBottom); - for (int y = jmax (clipTop, f.top); y < endY; ++y) - { - r.setEdgeTableYPos (y); - r.handleEdgeTablePixelFull (f.left); - } - - if (f.bottomAlpha != 0 && f.bottom < clipBottom) - { - r.setEdgeTableYPos (f.bottom); - r.handleEdgeTablePixel (f.left, f.bottomAlpha); - } - } - else - { - const int clippedLeft = jmax (f.left, clipLeft); - const int clippedWidth = jmin (f.right, clipRight) - clippedLeft; - const bool doLeftAlpha = f.leftAlpha != 0 && f.totalLeft >= clipLeft; - const bool doRightAlpha = f.rightAlpha != 0 && f.right < clipRight; - - if (f.topAlpha != 0 && f.totalTop >= clipTop) - { - r.setEdgeTableYPos (f.totalTop); - - if (doLeftAlpha) r.handleEdgeTablePixel (f.totalLeft, f.getTopLeftCornerAlpha()); - if (clippedWidth > 0) r.handleEdgeTableLine (clippedLeft, clippedWidth, f.topAlpha); - if (doRightAlpha) r.handleEdgeTablePixel (f.right, f.getTopRightCornerAlpha()); - } - - const int endY = jmin (f.bottom, clipBottom); - for (int y = jmax (clipTop, f.top); y < endY; ++y) - { - r.setEdgeTableYPos (y); - - if (doLeftAlpha) r.handleEdgeTablePixel (f.totalLeft, f.leftAlpha); - if (clippedWidth > 0) r.handleEdgeTableLineFull (clippedLeft, clippedWidth); - if (doRightAlpha) r.handleEdgeTablePixel (f.right, f.rightAlpha); - } - - if (f.bottomAlpha != 0 && f.bottom < clipBottom) - { - r.setEdgeTableYPos (f.bottom); - - if (doLeftAlpha) r.handleEdgeTablePixel (f.totalLeft, f.getBottomLeftCornerAlpha()); - if (clippedWidth > 0) r.handleEdgeTableLine (clippedLeft, clippedWidth, f.bottomAlpha); - if (doRightAlpha) r.handleEdgeTablePixel (f.right, f.getBottomRightCornerAlpha()); - } - } - } - } - } - - private: - const RectangleList& clip; - const Rectangle& area; - - JUCE_DECLARE_NON_COPYABLE (SubRectangleIteratorFloat) - }; - - Ptr toEdgeTable() const { return new EdgeTableRegion (clip); } - - RectangleListRegion& operator= (const RectangleListRegion&); - }; -}; - -//============================================================================== -template -class SavedStateBase -{ -public: - typedef typename ClipRegions::Base BaseRegionType; - typedef typename ClipRegions::EdgeTableRegion EdgeTableRegionType; - typedef typename ClipRegions::RectangleListRegion RectangleListRegionType; - - SavedStateBase (const Rectangle& initialClip) - : clip (new RectangleListRegionType (initialClip)), transform (Point()), - interpolationQuality (Graphics::mediumResamplingQuality), transparencyLayerAlpha (1.0f) - { - } - - SavedStateBase (const RectangleList& clipList, Point origin) - : clip (new RectangleListRegionType (clipList)), transform (origin), - interpolationQuality (Graphics::mediumResamplingQuality), transparencyLayerAlpha (1.0f) - { - } - - SavedStateBase (const SavedStateBase& other) - : clip (other.clip), transform (other.transform), fillType (other.fillType), - interpolationQuality (other.interpolationQuality), - transparencyLayerAlpha (other.transparencyLayerAlpha) - { - } - - SavedStateType& getThis() noexcept { return *static_cast (this); } - - bool clipToRectangle (const Rectangle& r) - { - if (clip != nullptr) - { - if (transform.isOnlyTranslated) - { - cloneClipIfMultiplyReferenced(); - clip = clip->clipToRectangle (transform.translated (r)); - } - else if (! transform.isRotated) - { - cloneClipIfMultiplyReferenced(); - clip = clip->clipToRectangle (transform.transformed (r)); - } - else - { - Path p; - p.addRectangle (r); - clipToPath (p, AffineTransform::identity); - } - } - - return clip != nullptr; - } - - bool clipToRectangleList (const RectangleList& r) - { - if (clip != nullptr) - { - if (transform.isOnlyTranslated) - { - cloneClipIfMultiplyReferenced(); - RectangleList offsetList (r); - offsetList.offsetAll (transform.offset.x, transform.offset.y); - clip = clip->clipToRectangleList (offsetList); - } - else if (! transform.isRotated) - { - cloneClipIfMultiplyReferenced(); - RectangleList scaledList; - - for (const Rectangle* i = r.begin(), * const e = r.end(); i != e; ++i) - scaledList.add (transform.transformed (*i)); - - clip = clip->clipToRectangleList (scaledList); - } - else - { - clipToPath (r.toPath(), AffineTransform::identity); - } - } - - return clip != nullptr; - } - - static Rectangle getLargestIntegerWithin (Rectangle r) - { - const int x1 = (int) std::ceil (r.getX()); - const int y1 = (int) std::ceil (r.getY()); - const int x2 = (int) std::floor (r.getRight()); - const int y2 = (int) std::floor (r.getBottom()); - - return Rectangle (x1, y1, x2 - x1, y2 - y1); - } - - bool excludeClipRectangle (const Rectangle& r) - { - if (clip != nullptr) - { - cloneClipIfMultiplyReferenced(); - - if (transform.isOnlyTranslated) - { - clip = clip->excludeClipRectangle (getLargestIntegerWithin (transform.translated (r.toFloat()))); - } - else if (! transform.isRotated) - { - clip = clip->excludeClipRectangle (getLargestIntegerWithin (transform.transformed (r.toFloat()))); - } - else - { - Path p; - p.addRectangle (r.toFloat()); - p.applyTransform (transform.complexTransform); - p.addRectangle (clip->getClipBounds().toFloat()); - p.setUsingNonZeroWinding (false); - clip = clip->clipToPath (p, AffineTransform::identity); - } - } - - return clip != nullptr; - } - - void clipToPath (const Path& p, const AffineTransform& t) - { - if (clip != nullptr) - { - cloneClipIfMultiplyReferenced(); - clip = clip->clipToPath (p, transform.getTransformWith (t)); - } - } - - void clipToImageAlpha (const Image& sourceImage, const AffineTransform& t) - { - if (clip != nullptr) - { - if (sourceImage.hasAlphaChannel()) - { - cloneClipIfMultiplyReferenced(); - clip = clip->clipToImageAlpha (sourceImage, transform.getTransformWith (t), interpolationQuality); - } - else - { - Path p; - p.addRectangle (sourceImage.getBounds()); - clipToPath (p, t); - } - } - } - - bool clipRegionIntersects (const Rectangle& r) const - { - if (clip != nullptr) - { - if (transform.isOnlyTranslated) - return clip->clipRegionIntersects (transform.translated (r)); - - return getClipBounds().intersects (r); - } - - return false; - } - - Rectangle getClipBounds() const - { - return clip != nullptr ? transform.deviceSpaceToUserSpace (clip->getClipBounds()) - : Rectangle(); - } - - void setFillType (const FillType& newFill) - { - fillType = newFill; - } - - void fillTargetRect (const Rectangle& r, const bool replaceContents) - { - if (fillType.isColour()) - { - clip->fillRectWithColour (getThis(), r, fillType.colour.getPixelARGB(), replaceContents); - } - else - { - const Rectangle clipped (clip->getClipBounds().getIntersection (r)); - - if (! clipped.isEmpty()) - fillShape (new RectangleListRegionType (clipped), false); - } - } - - void fillTargetRect (const Rectangle& r) - { - if (fillType.isColour()) - { - clip->fillRectWithColour (getThis(), r, fillType.colour.getPixelARGB()); - } - else - { - const Rectangle clipped (clip->getClipBounds().toFloat().getIntersection (r)); - - if (! clipped.isEmpty()) - fillShape (new EdgeTableRegionType (clipped), false); - } - } - - template - void fillRectAsPath (const Rectangle& r) - { - Path p; - p.addRectangle (r); - fillPath (p, AffineTransform::identity); - } - - void fillRect (const Rectangle& r, const bool replaceContents) - { - if (clip != nullptr) - { - if (transform.isOnlyTranslated) - { - fillTargetRect (transform.translated (r), replaceContents); - } - else if (! transform.isRotated) - { - fillTargetRect (transform.transformed (r), replaceContents); - } - else - { - jassert (! replaceContents); // not implemented.. - fillRectAsPath (r); - } - } - } - - void fillRect (const Rectangle& r) - { - if (clip != nullptr) - { - if (transform.isOnlyTranslated) - fillTargetRect (transform.translated (r)); - else if (! transform.isRotated) - fillTargetRect (transform.transformed (r)); - else - fillRectAsPath (r); - } - } - - void fillRectList (const RectangleList& list) - { - if (clip != nullptr) - { - if (! transform.isRotated) - { - RectangleList transformed (list); - - if (transform.isOnlyTranslated) - transformed.offsetAll (transform.offset.toFloat()); - else - transformed.transformAll (transform.getTransform()); - - fillShape (new EdgeTableRegionType (transformed), false); - } - else - { - fillPath (list.toPath(), AffineTransform::identity); - } - } - } - - void fillPath (const Path& path, const AffineTransform& t) - { - if (clip != nullptr) - fillShape (new EdgeTableRegionType (clip->getClipBounds(), path, transform.getTransformWith (t)), false); - } - - void fillEdgeTable (const EdgeTable& edgeTable, const float x, const int y) - { - if (clip != nullptr) - { - EdgeTableRegionType* edgeTableClip = new EdgeTableRegionType (edgeTable); - edgeTableClip->edgeTable.translate (x, y); - - if (fillType.isColour()) - { - float brightness = fillType.colour.getBrightness() - 0.5f; - - if (brightness > 0.0f) - edgeTableClip->edgeTable.multiplyLevels (1.0f + 1.6f * brightness); - } - - fillShape (edgeTableClip, false); - } - } - - void drawLine (const Line& line) - { - Path p; - p.addLineSegment (line, 1.0f); - fillPath (p, AffineTransform::identity); - } - - void drawImage (const Image& sourceImage, const AffineTransform& trans) - { - if (clip != nullptr && ! fillType.colour.isTransparent()) - renderImage (sourceImage, trans, nullptr); - } - - static bool isOnlyTranslationAllowingError (const AffineTransform& t) - { - return (std::abs (t.mat01) < 0.002) - && (std::abs (t.mat10) < 0.002) - && (std::abs (t.mat00 - 1.0f) < 0.002) - && (std::abs (t.mat11 - 1.0f) < 0.002); - } - - void renderImage (const Image& sourceImage, const AffineTransform& trans, - const BaseRegionType* const tiledFillClipRegion) - { - const AffineTransform t (transform.getTransformWith (trans)); - - const int alpha = fillType.colour.getAlpha(); - - if (isOnlyTranslationAllowingError (t)) - { - // If our translation doesn't involve any distortion, just use a simple blit.. - int tx = (int) (t.getTranslationX() * 256.0f); - int ty = (int) (t.getTranslationY() * 256.0f); - - if (interpolationQuality == Graphics::lowResamplingQuality || ((tx | ty) & 224) == 0) - { - tx = ((tx + 128) >> 8); - ty = ((ty + 128) >> 8); - - if (tiledFillClipRegion != nullptr) - { - tiledFillClipRegion->renderImageUntransformed (getThis(), sourceImage, alpha, tx, ty, true); - } - else - { - Rectangle area (tx, ty, sourceImage.getWidth(), sourceImage.getHeight()); - area = area.getIntersection (getThis().getMaximumBounds()); - - if (! area.isEmpty()) - if (typename BaseRegionType::Ptr c = clip->applyClipTo (new EdgeTableRegionType (area))) - c->renderImageUntransformed (getThis(), sourceImage, alpha, tx, ty, false); - } - - return; - } - } - - if (! t.isSingularity()) - { - if (tiledFillClipRegion != nullptr) - { - tiledFillClipRegion->renderImageTransformed (getThis(), sourceImage, alpha, t, interpolationQuality, true); - } - else - { - Path p; - p.addRectangle (sourceImage.getBounds()); - - typename BaseRegionType::Ptr c (clip->clone()); - c = c->clipToPath (p, t); - - if (c != nullptr) - c->renderImageTransformed (getThis(), sourceImage, alpha, t, interpolationQuality, false); - } - } - } - - void fillShape (typename BaseRegionType::Ptr shapeToFill, const bool replaceContents) - { - jassert (clip != nullptr); - - shapeToFill = clip->applyClipTo (shapeToFill); - - if (shapeToFill != nullptr) - { - if (fillType.isGradient()) - { - jassert (! replaceContents); // that option is just for solid colours - - ColourGradient g2 (*(fillType.gradient)); - g2.multiplyOpacity (fillType.getOpacity()); - AffineTransform t (transform.getTransformWith (fillType.transform).translated (-0.5f, -0.5f)); - - const bool isIdentity = t.isOnlyTranslation(); - - if (isIdentity) - { - // If our translation doesn't involve any distortion, we can speed it up.. - g2.point1.applyTransform (t); - g2.point2.applyTransform (t); - t = AffineTransform::identity; - } - - shapeToFill->fillAllWithGradient (getThis(), g2, t, isIdentity); - } - else if (fillType.isTiledImage()) - { - renderImage (fillType.image, fillType.transform, shapeToFill); - } - else - { - shapeToFill->fillAllWithColour (getThis(), fillType.colour.getPixelARGB(), replaceContents); - } - } - } - - void cloneClipIfMultiplyReferenced() - { - if (clip->getReferenceCount() > 1) - clip = clip->clone(); - } - - typename BaseRegionType::Ptr clip; - RenderingHelpers::TranslationOrTransform transform; - FillType fillType; - Graphics::ResamplingQuality interpolationQuality; - float transparencyLayerAlpha; -}; - -//============================================================================== -class SoftwareRendererSavedState : public SavedStateBase -{ - typedef SavedStateBase BaseClass; - -public: - SoftwareRendererSavedState (const Image& im, const Rectangle& clipBounds) - : BaseClass (clipBounds), image (im) - { - } - - SoftwareRendererSavedState (const Image& im, const RectangleList& clipList, Point origin) - : BaseClass (clipList, origin), image (im) - { - } - - SoftwareRendererSavedState (const SoftwareRendererSavedState& other) - : BaseClass (other), image (other.image), font (other.font) - { - } - - SoftwareRendererSavedState* beginTransparencyLayer (float opacity) - { - SoftwareRendererSavedState* s = new SoftwareRendererSavedState (*this); - - if (clip != nullptr) - { - const Rectangle layerBounds (clip->getClipBounds()); - - s->image = Image (Image::ARGB, layerBounds.getWidth(), layerBounds.getHeight(), true); - s->transparencyLayerAlpha = opacity; - s->transform.moveOriginInDeviceSpace (-layerBounds.getPosition()); - s->cloneClipIfMultiplyReferenced(); - s->clip->translate (-layerBounds.getPosition()); - } - - return s; - } - - void endTransparencyLayer (SoftwareRendererSavedState& finishedLayerState) - { - if (clip != nullptr) - { - const Rectangle layerBounds (clip->getClipBounds()); - - const ScopedPointer g (image.createLowLevelContext()); - g->setOpacity (finishedLayerState.transparencyLayerAlpha); - g->drawImage (finishedLayerState.image, AffineTransform::translation (layerBounds.getPosition())); - } - } - - typedef GlyphCache, SoftwareRendererSavedState> GlyphCacheType; - - static void clearGlyphCache() - { - GlyphCacheType::getInstance().reset(); - } - - //============================================================================== - void drawGlyph (int glyphNumber, const AffineTransform& trans) - { - if (clip != nullptr) - { - if (trans.isOnlyTranslation() && ! transform.isRotated) - { - GlyphCacheType& cache = GlyphCacheType::getInstance(); - - Point pos (trans.getTranslationX(), trans.getTranslationY()); - - if (transform.isOnlyTranslated) - { - cache.drawGlyph (*this, font, glyphNumber, pos + transform.offset.toFloat()); - } - else - { - pos = transform.transformed (pos); - - Font f (font); - f.setHeight (font.getHeight() * transform.complexTransform.mat11); - - const float xScale = transform.complexTransform.mat00 / transform.complexTransform.mat11; - if (std::abs (xScale - 1.0f) > 0.01f) - f.setHorizontalScale (xScale); - - cache.drawGlyph (*this, f, glyphNumber, pos); - } - } - else - { - const float fontHeight = font.getHeight(); - - AffineTransform t (transform.getTransformWith (AffineTransform::scale (fontHeight * font.getHorizontalScale(), fontHeight) - .followedBy (trans))); - - const ScopedPointer et (font.getTypeface()->getEdgeTableForGlyph (glyphNumber, t, fontHeight)); - - if (et != nullptr) - fillShape (new EdgeTableRegionType (*et), false); - } - } - } - - Rectangle getMaximumBounds() const { return image.getBounds(); } - - //============================================================================== - template - void renderImageTransformed (IteratorType& iter, const Image& src, const int alpha, const AffineTransform& trans, Graphics::ResamplingQuality quality, bool tiledFill) const - { - Image::BitmapData destData (image, Image::BitmapData::readWrite); - const Image::BitmapData srcData (src, Image::BitmapData::readOnly); - EdgeTableFillers::renderImageTransformed (iter, destData, srcData, alpha, trans, quality, tiledFill); - } - - template - void renderImageUntransformed (IteratorType& iter, const Image& src, const int alpha, int x, int y, bool tiledFill) const - { - Image::BitmapData destData (image, Image::BitmapData::readWrite); - const Image::BitmapData srcData (src, Image::BitmapData::readOnly); - EdgeTableFillers::renderImageUntransformed (iter, destData, srcData, alpha, x, y, tiledFill); - } - - template - void fillWithSolidColour (IteratorType& iter, const PixelARGB colour, bool replaceContents) const - { - Image::BitmapData destData (image, Image::BitmapData::readWrite); - - switch (destData.pixelFormat) - { - case Image::ARGB: EdgeTableFillers::renderSolidFill (iter, destData, colour, replaceContents, (PixelARGB*) 0); break; - case Image::RGB: EdgeTableFillers::renderSolidFill (iter, destData, colour, replaceContents, (PixelRGB*) 0); break; - default: EdgeTableFillers::renderSolidFill (iter, destData, colour, replaceContents, (PixelAlpha*) 0); break; - } - } - - template - void fillWithGradient (IteratorType& iter, ColourGradient& gradient, const AffineTransform& trans, bool isIdentity) const - { - HeapBlock lookupTable; - const int numLookupEntries = gradient.createLookupTable (trans, lookupTable); - jassert (numLookupEntries > 0); - - Image::BitmapData destData (image, Image::BitmapData::readWrite); - - switch (destData.pixelFormat) - { - case Image::ARGB: EdgeTableFillers::renderGradient (iter, destData, gradient, trans, lookupTable, numLookupEntries, isIdentity, (PixelARGB*) 0); break; - case Image::RGB: EdgeTableFillers::renderGradient (iter, destData, gradient, trans, lookupTable, numLookupEntries, isIdentity, (PixelRGB*) 0); break; - default: EdgeTableFillers::renderGradient (iter, destData, gradient, trans, lookupTable, numLookupEntries, isIdentity, (PixelAlpha*) 0); break; - } - } - - //============================================================================== - Image image; - Font font; - -private: - SoftwareRendererSavedState& operator= (const SoftwareRendererSavedState&); -}; - -//============================================================================== -template -class SavedStateStack -{ -public: - SavedStateStack (StateObjectType* const initialState) noexcept - : currentState (initialState) - {} - - SavedStateStack() noexcept {} - - void initialise (StateObjectType* state) - { - currentState = state; - } - - inline StateObjectType* operator->() const noexcept { return currentState; } - inline StateObjectType& operator*() const noexcept { return *currentState; } - - void save() - { - stack.add (new StateObjectType (*currentState)); - } - - void restore() - { - if (StateObjectType* const top = stack.getLast()) - { - currentState = top; - stack.removeLast (1, false); - } - else - { - jassertfalse; // trying to pop with an empty stack! - } - } - - void beginTransparencyLayer (float opacity) - { - save(); - currentState = currentState->beginTransparencyLayer (opacity); - } - - void endTransparencyLayer() - { - const ScopedPointer finishedTransparencyLayer (currentState); - restore(); - currentState->endTransparencyLayer (*finishedTransparencyLayer); - } - -private: - ScopedPointer currentState; - OwnedArray stack; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (SavedStateStack) -}; - -//============================================================================== -template -class StackBasedLowLevelGraphicsContext : public LowLevelGraphicsContext -{ -public: - bool isVectorDevice() const override { return false; } - void setOrigin (Point o) override { stack->transform.setOrigin (o); } - void addTransform (const AffineTransform& t) override { stack->transform.addTransform (t); } - float getPhysicalPixelScaleFactor() override { return stack->transform.getPhysicalPixelScaleFactor(); } - Rectangle getClipBounds() const override { return stack->getClipBounds(); } - bool isClipEmpty() const override { return stack->clip == nullptr; } - bool clipRegionIntersects (const Rectangle& r) override { return stack->clipRegionIntersects (r); } - bool clipToRectangle (const Rectangle& r) override { return stack->clipToRectangle (r); } - bool clipToRectangleList (const RectangleList& r) override { return stack->clipToRectangleList (r); } - void excludeClipRectangle (const Rectangle& r) override { stack->excludeClipRectangle (r); } - void clipToPath (const Path& path, const AffineTransform& t) override { stack->clipToPath (path, t); } - void clipToImageAlpha (const Image& im, const AffineTransform& t) override { stack->clipToImageAlpha (im, t); } - void saveState() override { stack.save(); } - void restoreState() override { stack.restore(); } - void beginTransparencyLayer (float opacity) override { stack.beginTransparencyLayer (opacity); } - void endTransparencyLayer() override { stack.endTransparencyLayer(); } - void setFill (const FillType& fillType) override { stack->setFillType (fillType); } - void setOpacity (float newOpacity) override { stack->fillType.setOpacity (newOpacity); } - void setInterpolationQuality (Graphics::ResamplingQuality quality) override { stack->interpolationQuality = quality; } - void fillRect (const Rectangle& r, bool replace) override { stack->fillRect (r, replace); } - void fillRect (const Rectangle& r) override { stack->fillRect (r); } - void fillRectList (const RectangleList& list) override { stack->fillRectList (list); } - void fillPath (const Path& path, const AffineTransform& t) override { stack->fillPath (path, t); } - void drawImage (const Image& im, const AffineTransform& t) override { stack->drawImage (im, t); } - void drawGlyph (int glyphNumber, const AffineTransform& t) override { stack->drawGlyph (glyphNumber, t); } - void drawLine (const Line& line) override { stack->drawLine (line); } - void setFont (const Font& newFont) override { stack->font = newFont; } - const Font& getFont() override { return stack->font; } - -protected: - StackBasedLowLevelGraphicsContext (SavedStateType* initialState) : stack (initialState) {} - StackBasedLowLevelGraphicsContext() {} - - RenderingHelpers::SavedStateStack stack; -}; - -} - -#if JUCE_MSVC - #pragma warning (pop) -#endif - -#endif // JUCE_RENDERINGHELPERS_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/native/juce_android_Fonts.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/native/juce_android_Fonts.cpp deleted file mode 100644 index 29702a20b5..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/native/juce_android_Fonts.cpp +++ /dev/null @@ -1,334 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -struct DefaultFontNames -{ - DefaultFontNames() - : defaultSans ("sans"), - defaultSerif ("serif"), - defaultFixed ("monospace"), - defaultFallback ("sans") - { - } - - String getRealFontName (const String& faceName) const - { - if (faceName == Font::getDefaultSansSerifFontName()) return defaultSans; - if (faceName == Font::getDefaultSerifFontName()) return defaultSerif; - if (faceName == Font::getDefaultMonospacedFontName()) return defaultFixed; - - return faceName; - } - - String defaultSans, defaultSerif, defaultFixed, defaultFallback; -}; - -Typeface::Ptr Font::getDefaultTypefaceForFont (const Font& font) -{ - static DefaultFontNames defaultNames; - - Font f (font); - f.setTypefaceName (defaultNames.getRealFontName (font.getTypefaceName())); - return Typeface::createSystemTypefaceFor (f); -} - -//============================================================================== -#if JUCE_USE_FREETYPE - -StringArray FTTypefaceList::getDefaultFontDirectories() -{ - return StringArray ("/system/fonts"); -} - -Typeface::Ptr Typeface::createSystemTypefaceFor (const Font& font) -{ - return new FreeTypeTypeface (font); -} - -void Typeface::scanFolderForFonts (const File& folder) -{ - FTTypefaceList::getInstance()->scanFontPaths (StringArray (folder.getFullPathName())); -} - -StringArray Font::findAllTypefaceNames() -{ - return FTTypefaceList::getInstance()->findAllFamilyNames(); -} - -StringArray Font::findAllTypefaceStyles (const String& family) -{ - return FTTypefaceList::getInstance()->findAllTypefaceStyles (family); -} - -bool TextLayout::createNativeLayout (const AttributedString&) -{ - return false; -} - -#else - -//============================================================================== -#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD) \ - STATICMETHOD (create, "create", "(Ljava/lang/String;I)Landroid/graphics/Typeface;") \ - STATICMETHOD (createFromFile, "createFromFile", "(Ljava/lang/String;)Landroid/graphics/Typeface;") \ - -DECLARE_JNI_CLASS (TypefaceClass, "android/graphics/Typeface"); -#undef JNI_CLASS_MEMBERS - -//============================================================================== -StringArray Font::findAllTypefaceNames() -{ - StringArray results; - - Array fonts; - File ("/system/fonts").findChildFiles (fonts, File::findFiles, false, "*.ttf"); - - for (int i = 0; i < fonts.size(); ++i) - results.addIfNotAlreadyThere (fonts.getReference(i).getFileNameWithoutExtension() - .upToLastOccurrenceOf ("-", false, false)); - - return results; -} - -StringArray Font::findAllTypefaceStyles (const String& family) -{ - StringArray results ("Regular"); - - Array fonts; - File ("/system/fonts").findChildFiles (fonts, File::findFiles, false, family + "-*.ttf"); - - for (int i = 0; i < fonts.size(); ++i) - results.addIfNotAlreadyThere (fonts.getReference(i).getFileNameWithoutExtension() - .fromLastOccurrenceOf ("-", false, false)); - - return results; -} - -const float referenceFontSize = 256.0f; -const float referenceFontToUnits = 1.0f / referenceFontSize; - -//============================================================================== -class AndroidTypeface : public Typeface -{ -public: - AndroidTypeface (const Font& font) - : Typeface (font.getTypefaceName(), font.getTypefaceStyle()), - ascent (0), descent (0), heightToPointsFactor (1.0f) - { - JNIEnv* const env = getEnv(); - - const bool isBold = style.contains ("Bold"); - const bool isItalic = style.contains ("Italic"); - - File fontFile (getFontFile (name, style)); - - if (! fontFile.exists()) - fontFile = findFontFile (name, isBold, isItalic); - - if (fontFile.exists()) - typeface = GlobalRef (env->CallStaticObjectMethod (TypefaceClass, TypefaceClass.createFromFile, - javaString (fontFile.getFullPathName()).get())); - else - typeface = GlobalRef (env->CallStaticObjectMethod (TypefaceClass, TypefaceClass.create, - javaString (getName()).get(), - (isBold ? 1 : 0) + (isItalic ? 2 : 0))); - - rect = GlobalRef (env->NewObject (RectClass, RectClass.constructor, 0, 0, 0, 0)); - - paint = GlobalRef (GraphicsHelpers::createPaint (Graphics::highResamplingQuality)); - const LocalRef ignored (paint.callObjectMethod (Paint.setTypeface, typeface.get())); - - paint.callVoidMethod (Paint.setTextSize, referenceFontSize); - - const float fullAscent = std::abs (paint.callFloatMethod (Paint.ascent)); - const float fullDescent = paint.callFloatMethod (Paint.descent); - const float totalHeight = fullAscent + fullDescent; - - ascent = fullAscent / totalHeight; - descent = fullDescent / totalHeight; - heightToPointsFactor = referenceFontSize / totalHeight; - } - - float getAscent() const override { return ascent; } - float getDescent() const override { return descent; } - float getHeightToPointsFactor() const override { return heightToPointsFactor; } - - float getStringWidth (const String& text) override - { - JNIEnv* env = getEnv(); - const int numChars = text.length(); - jfloatArray widths = env->NewFloatArray (numChars); - - const int numDone = paint.callIntMethod (Paint.getTextWidths, javaString (text).get(), widths); - - HeapBlock localWidths (numDone); - env->GetFloatArrayRegion (widths, 0, numDone, localWidths); - env->DeleteLocalRef (widths); - - float x = 0; - for (int i = 0; i < numDone; ++i) - x += localWidths[i]; - - return x * referenceFontToUnits; - } - - void getGlyphPositions (const String& text, Array& glyphs, Array& xOffsets) override - { - JNIEnv* env = getEnv(); - const int numChars = text.length(); - jfloatArray widths = env->NewFloatArray (numChars); - - const int numDone = paint.callIntMethod (Paint.getTextWidths, javaString (text).get(), widths); - - HeapBlock localWidths (numDone); - env->GetFloatArrayRegion (widths, 0, numDone, localWidths); - env->DeleteLocalRef (widths); - - String::CharPointerType s (text.getCharPointer()); - - xOffsets.add (0); - - float x = 0; - for (int i = 0; i < numDone; ++i) - { - glyphs.add ((int) s.getAndAdvance()); - x += localWidths[i]; - xOffsets.add (x * referenceFontToUnits); - } - } - - bool getOutlineForGlyph (int /*glyphNumber*/, Path& /*destPath*/) override - { - return false; - } - - EdgeTable* getEdgeTableForGlyph (int glyphNumber, const AffineTransform& t, float /*fontHeight*/) override - { - JNIEnv* env = getEnv(); - - jobject matrix = GraphicsHelpers::createMatrix (env, AffineTransform::scale (referenceFontToUnits).followedBy (t)); - jintArray maskData = (jintArray) android.activity.callObjectMethod (JuceAppActivity.renderGlyph, (jchar) glyphNumber, paint.get(), matrix, rect.get()); - - env->DeleteLocalRef (matrix); - - const int left = env->GetIntField (rect.get(), RectClass.left); - const int top = env->GetIntField (rect.get(), RectClass.top); - const int right = env->GetIntField (rect.get(), RectClass.right); - const int bottom = env->GetIntField (rect.get(), RectClass.bottom); - - const Rectangle bounds (left, top, right - left, bottom - top); - - EdgeTable* et = nullptr; - - if (! bounds.isEmpty()) - { - et = new EdgeTable (bounds); - - jint* const maskDataElements = env->GetIntArrayElements (maskData, 0); - const jint* mask = maskDataElements; - - for (int y = top; y < bottom; ++y) - { - #if JUCE_LITTLE_ENDIAN - const uint8* const lineBytes = ((const uint8*) mask) + 3; - #else - const uint8* const lineBytes = (const uint8*) mask; - #endif - - et->clipLineToMask (left, y, lineBytes, 4, bounds.getWidth()); - mask += bounds.getWidth(); - } - - env->ReleaseIntArrayElements (maskData, maskDataElements, 0); - } - - env->DeleteLocalRef (maskData); - return et; - } - - GlobalRef typeface, paint, rect; - float ascent, descent, heightToPointsFactor; - -private: - static File findFontFile (const String& family, - const bool bold, const bool italic) - { - File file; - - if (bold || italic) - { - String suffix; - if (bold) suffix = "Bold"; - if (italic) suffix << "Italic"; - - file = getFontFile (family, suffix); - - if (file.exists()) - return file; - } - - file = getFontFile (family, "Regular"); - - if (! file.exists()) - file = getFontFile (family, String()); - - return file; - } - - static File getFontFile (const String& family, const String& style) - { - String path ("/system/fonts/" + family); - - if (style.isNotEmpty()) - path << '-' << style; - - return File (path + ".ttf"); - } - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AndroidTypeface) -}; - -//============================================================================== -Typeface::Ptr Typeface::createSystemTypefaceFor (const Font& font) -{ - return new AndroidTypeface (font); -} - -Typeface::Ptr Typeface::createSystemTypefaceFor (const void*, size_t) -{ - jassertfalse; // not yet implemented! - return nullptr; -} - -void Typeface::scanFolderForFonts (const File&) -{ - jassertfalse; // not available unless using FreeType -} - -bool TextLayout::createNativeLayout (const AttributedString&) -{ - return false; -} - -#endif diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/native/juce_android_GraphicsContext.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/native/juce_android_GraphicsContext.cpp deleted file mode 100644 index 9382c1db62..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/native/juce_android_GraphicsContext.cpp +++ /dev/null @@ -1,60 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -namespace GraphicsHelpers -{ - jobject createPaint (Graphics::ResamplingQuality quality) - { - jint constructorFlags = 1 /*ANTI_ALIAS_FLAG*/ - | 4 /*DITHER_FLAG*/ - | 128 /*SUBPIXEL_TEXT_FLAG*/; - - if (quality > Graphics::lowResamplingQuality) - constructorFlags |= 2; /*FILTER_BITMAP_FLAG*/ - - return getEnv()->NewObject (Paint, Paint.constructor, constructorFlags); - } - - const jobject createMatrix (JNIEnv* env, const AffineTransform& t) - { - jobject m = env->NewObject (Matrix, Matrix.constructor); - - jfloat values[9] = { t.mat00, t.mat01, t.mat02, - t.mat10, t.mat11, t.mat12, - 0.0f, 0.0f, 1.0f }; - - jfloatArray javaArray = env->NewFloatArray (9); - env->SetFloatArrayRegion (javaArray, 0, 9, values); - - env->CallVoidMethod (m, Matrix.setValues, javaArray); - env->DeleteLocalRef (javaArray); - - return m; - } -} - -ImagePixelData::Ptr NativeImageType::create (Image::PixelFormat format, int width, int height, bool clearImage) const -{ - return SoftwareImageType().create (format, width, height, clearImage); -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/native/juce_freetype_Fonts.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/native/juce_freetype_Fonts.cpp deleted file mode 100644 index 43a6436e91..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/native/juce_freetype_Fonts.cpp +++ /dev/null @@ -1,455 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -struct FTLibWrapper : public ReferenceCountedObject -{ - FTLibWrapper() : library (0) - { - if (FT_Init_FreeType (&library) != 0) - { - library = 0; - DBG ("Failed to initialize FreeType"); - } - } - - ~FTLibWrapper() - { - if (library != 0) - FT_Done_FreeType (library); - } - - FT_Library library; - - typedef ReferenceCountedObjectPtr Ptr; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (FTLibWrapper) -}; - -//============================================================================== -struct FTFaceWrapper : public ReferenceCountedObject -{ - FTFaceWrapper (const FTLibWrapper::Ptr& ftLib, const File& file, int faceIndex) - : face (0), library (ftLib) - { - if (FT_New_Face (ftLib->library, file.getFullPathName().toUTF8(), faceIndex, &face) != 0) - face = 0; - } - - FTFaceWrapper (const FTLibWrapper::Ptr& ftLib, const void* data, size_t dataSize, int faceIndex) - : face (0), library (ftLib), savedFaceData (data, dataSize) - { - if (FT_New_Memory_Face (ftLib->library, (const FT_Byte*) savedFaceData.getData(), - (FT_Long) savedFaceData.getSize(), faceIndex, &face) != 0) - face = 0; - } - - ~FTFaceWrapper() - { - if (face != 0) - FT_Done_Face (face); - } - - FT_Face face; - FTLibWrapper::Ptr library; - MemoryBlock savedFaceData; - - typedef ReferenceCountedObjectPtr Ptr; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (FTFaceWrapper) -}; - -//============================================================================== -class FTTypefaceList : private DeletedAtShutdown -{ -public: - FTTypefaceList() : library (new FTLibWrapper()) - { - scanFontPaths (getDefaultFontDirectories()); - } - - ~FTTypefaceList() - { - clearSingletonInstance(); - } - - //============================================================================== - struct KnownTypeface - { - KnownTypeface (const File& f, const int index, const FTFaceWrapper& face) - : file (f), - family (face.face->family_name), - style (face.face->style_name), - faceIndex (index), - isMonospaced ((face.face->face_flags & FT_FACE_FLAG_FIXED_WIDTH) != 0), - isSansSerif (isFaceSansSerif (family)) - { - } - - const File file; - const String family, style; - const int faceIndex; - const bool isMonospaced, isSansSerif; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (KnownTypeface) - }; - - //============================================================================== - static FTFaceWrapper::Ptr selectUnicodeCharmap (FTFaceWrapper* face) - { - if (face != nullptr) - if (FT_Select_Charmap (face->face, ft_encoding_unicode) != 0) - FT_Set_Charmap (face->face, face->face->charmaps[0]); - - return face; - } - - FTFaceWrapper::Ptr createFace (const void* data, size_t dataSize, int index) - { - return selectUnicodeCharmap (new FTFaceWrapper (library, data, dataSize, index)); - } - - FTFaceWrapper::Ptr createFace (const File& file, int index) - { - return selectUnicodeCharmap (new FTFaceWrapper (library, file, index)); - } - - FTFaceWrapper::Ptr createFace (const String& fontName, const String& fontStyle) - { - const KnownTypeface* ftFace = matchTypeface (fontName, fontStyle); - - if (ftFace == nullptr) ftFace = matchTypeface (fontName, "Regular"); - if (ftFace == nullptr) ftFace = matchTypeface (fontName, String()); - - if (ftFace != nullptr) - return createFace (ftFace->file, ftFace->faceIndex); - - return nullptr; - } - - //============================================================================== - StringArray findAllFamilyNames() const - { - StringArray s; - - for (int i = 0; i < faces.size(); ++i) - s.addIfNotAlreadyThere (faces.getUnchecked(i)->family); - - return s; - } - - static int indexOfRegularStyle (const StringArray& styles) - { - int i = styles.indexOf ("Regular", true); - - if (i < 0) - for (i = 0; i < styles.size(); ++i) - if (! (styles[i].containsIgnoreCase ("Bold") || styles[i].containsIgnoreCase ("Italic"))) - break; - - return i; - } - - StringArray findAllTypefaceStyles (const String& family) const - { - StringArray s; - - for (int i = 0; i < faces.size(); ++i) - { - const KnownTypeface* const face = faces.getUnchecked(i); - - if (face->family == family) - s.addIfNotAlreadyThere (face->style); - } - - // try to get a regular style to be first in the list - const int regular = indexOfRegularStyle (s); - if (regular > 0) - s.strings.swap (0, regular); - - return s; - } - - void scanFontPaths (const StringArray& paths) - { - for (int i = 0; i < paths.size(); ++i) - { - DirectoryIterator iter (File::getCurrentWorkingDirectory() - .getChildFile (paths[i]), true); - - while (iter.next()) - if (iter.getFile().hasFileExtension ("ttf;pfb;pcf;otf")) - scanFont (iter.getFile()); - } - } - - void getMonospacedNames (StringArray& monoSpaced) const - { - for (int i = 0; i < faces.size(); ++i) - if (faces.getUnchecked(i)->isMonospaced) - monoSpaced.addIfNotAlreadyThere (faces.getUnchecked(i)->family); - } - - void getSerifNames (StringArray& serif) const - { - for (int i = 0; i < faces.size(); ++i) - if (! faces.getUnchecked(i)->isSansSerif) - serif.addIfNotAlreadyThere (faces.getUnchecked(i)->family); - } - - void getSansSerifNames (StringArray& sansSerif) const - { - for (int i = 0; i < faces.size(); ++i) - if (faces.getUnchecked(i)->isSansSerif) - sansSerif.addIfNotAlreadyThere (faces.getUnchecked(i)->family); - } - - juce_DeclareSingleton_SingleThreaded_Minimal (FTTypefaceList); - -private: - FTLibWrapper::Ptr library; - OwnedArray faces; - - static StringArray getDefaultFontDirectories(); - - void scanFont (const File& file) - { - int faceIndex = 0; - int numFaces = 0; - - do - { - FTFaceWrapper face (library, file, faceIndex); - - if (face.face != 0) - { - if (faceIndex == 0) - numFaces = face.face->num_faces; - - if ((face.face->face_flags & FT_FACE_FLAG_SCALABLE) != 0) - faces.add (new KnownTypeface (file, faceIndex, face)); - } - - ++faceIndex; - } - while (faceIndex < numFaces); - } - - const KnownTypeface* matchTypeface (const String& familyName, const String& style) const noexcept - { - for (int i = 0; i < faces.size(); ++i) - { - const KnownTypeface* const face = faces.getUnchecked(i); - - if (face->family == familyName - && (face->style.equalsIgnoreCase (style) || style.isEmpty())) - return face; - } - - return nullptr; - } - - static bool isFaceSansSerif (const String& family) - { - static const char* sansNames[] = { "Sans", "Verdana", "Arial", "Ubuntu" }; - - for (int i = 0; i < numElementsInArray (sansNames); ++i) - if (family.containsIgnoreCase (sansNames[i])) - return true; - - return false; - } - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (FTTypefaceList) -}; - -juce_ImplementSingleton_SingleThreaded (FTTypefaceList) - - -//============================================================================== -class FreeTypeTypeface : public CustomTypeface -{ -public: - FreeTypeTypeface (const Font& font) - : faceWrapper (FTTypefaceList::getInstance()->createFace (font.getTypefaceName(), - font.getTypefaceStyle())) - { - if (faceWrapper != nullptr) - initialiseCharacteristics (font.getTypefaceName(), - font.getTypefaceStyle()); - } - - FreeTypeTypeface (const void* data, size_t dataSize) - : faceWrapper (FTTypefaceList::getInstance()->createFace (data, dataSize, 0)) - { - if (faceWrapper != nullptr) - initialiseCharacteristics (faceWrapper->face->family_name, - faceWrapper->face->style_name); - } - - void initialiseCharacteristics (const String& name, const String& style) - { - setCharacteristics (name, style, - faceWrapper->face->ascender / (float) (faceWrapper->face->ascender - faceWrapper->face->descender), - L' '); - } - - bool loadGlyphIfPossible (const juce_wchar character) - { - if (faceWrapper != nullptr) - { - FT_Face face = faceWrapper->face; - const unsigned int glyphIndex = FT_Get_Char_Index (face, character); - - if (FT_Load_Glyph (face, glyphIndex, FT_LOAD_NO_SCALE | FT_LOAD_NO_BITMAP | FT_LOAD_IGNORE_TRANSFORM | FT_LOAD_NO_HINTING) == 0 - && face->glyph->format == ft_glyph_format_outline) - { - const float scale = 1.0f / (float) (face->ascender - face->descender); - Path destShape; - - if (getGlyphShape (destShape, face->glyph->outline, scale)) - { - addGlyph (character, destShape, face->glyph->metrics.horiAdvance * scale); - - if ((face->face_flags & FT_FACE_FLAG_KERNING) != 0) - addKerning (face, character, glyphIndex); - - return true; - } - } - } - - return false; - } - -private: - FTFaceWrapper::Ptr faceWrapper; - - bool getGlyphShape (Path& destShape, const FT_Outline& outline, const float scaleX) - { - const float scaleY = -scaleX; - const short* const contours = outline.contours; - const char* const tags = outline.tags; - const FT_Vector* const points = outline.points; - - for (int c = 0; c < outline.n_contours; ++c) - { - const int startPoint = (c == 0) ? 0 : contours [c - 1] + 1; - const int endPoint = contours[c]; - - for (int p = startPoint; p <= endPoint; ++p) - { - const float x = scaleX * points[p].x; - const float y = scaleY * points[p].y; - - if (p == startPoint) - { - if (FT_CURVE_TAG (tags[p]) == FT_Curve_Tag_Conic) - { - float x2 = scaleX * points [endPoint].x; - float y2 = scaleY * points [endPoint].y; - - if (FT_CURVE_TAG (tags[endPoint]) != FT_Curve_Tag_On) - { - x2 = (x + x2) * 0.5f; - y2 = (y + y2) * 0.5f; - } - - destShape.startNewSubPath (x2, y2); - } - else - { - destShape.startNewSubPath (x, y); - } - } - - if (FT_CURVE_TAG (tags[p]) == FT_Curve_Tag_On) - { - if (p != startPoint) - destShape.lineTo (x, y); - } - else if (FT_CURVE_TAG (tags[p]) == FT_Curve_Tag_Conic) - { - const int nextIndex = (p == endPoint) ? startPoint : p + 1; - float x2 = scaleX * points [nextIndex].x; - float y2 = scaleY * points [nextIndex].y; - - if (FT_CURVE_TAG (tags [nextIndex]) == FT_Curve_Tag_Conic) - { - x2 = (x + x2) * 0.5f; - y2 = (y + y2) * 0.5f; - } - else - { - ++p; - } - - destShape.quadraticTo (x, y, x2, y2); - } - else if (FT_CURVE_TAG (tags[p]) == FT_Curve_Tag_Cubic) - { - const int next1 = p + 1; - const int next2 = (p == (endPoint - 1)) ? startPoint : (p + 2); - - if (p >= endPoint - || FT_CURVE_TAG (tags[next1]) != FT_Curve_Tag_Cubic - || FT_CURVE_TAG (tags[next2]) != FT_Curve_Tag_On) - return false; - - const float x2 = scaleX * points [next1].x; - const float y2 = scaleY * points [next1].y; - const float x3 = scaleX * points [next2].x; - const float y3 = scaleY * points [next2].y; - - destShape.cubicTo (x, y, x2, y2, x3, y3); - p += 2; - } - } - - destShape.closeSubPath(); - } - - return true; - } - - void addKerning (FT_Face face, const uint32 character, const uint32 glyphIndex) - { - const float height = (float) (face->ascender - face->descender); - - uint32 rightGlyphIndex; - uint32 rightCharCode = FT_Get_First_Char (face, &rightGlyphIndex); - - while (rightGlyphIndex != 0) - { - FT_Vector kerning; - - if (FT_Get_Kerning (face, glyphIndex, rightGlyphIndex, ft_kerning_unscaled, &kerning) == 0 - && kerning.x != 0) - addKerningPair (character, rightCharCode, kerning.x / height); - - rightCharCode = FT_Get_Next_Char (face, rightCharCode, &rightGlyphIndex); - } - } - - JUCE_DECLARE_NON_COPYABLE (FreeTypeTypeface) -}; diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/native/juce_linux_Fonts.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/native/juce_linux_Fonts.cpp deleted file mode 100644 index 0869ec719c..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/native/juce_linux_Fonts.cpp +++ /dev/null @@ -1,180 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -StringArray FTTypefaceList::getDefaultFontDirectories() -{ - StringArray fontDirs; - - fontDirs.addTokens (String (CharPointer_UTF8 (getenv ("JUCE_FONT_PATH"))), ";,", ""); - fontDirs.removeEmptyStrings (true); - - if (fontDirs.size() == 0) - { - const ScopedPointer fontsInfo (XmlDocument::parse (File ("/etc/fonts/fonts.conf"))); - - if (fontsInfo != nullptr) - { - forEachXmlChildElementWithTagName (*fontsInfo, e, "dir") - { - String fontPath (e->getAllSubText().trim()); - - if (fontPath.isNotEmpty()) - { - if (e->getStringAttribute ("prefix") == "xdg") - { - String xdgDataHome (SystemStats::getEnvironmentVariable ("XDG_DATA_HOME", String())); - - if (xdgDataHome.trimStart().isEmpty()) - xdgDataHome = "~/.local/share"; - - fontPath = File (xdgDataHome).getChildFile (fontPath).getFullPathName(); - } - - fontDirs.add (fontPath); - } - } - } - } - - if (fontDirs.size() == 0) - fontDirs.add ("/usr/X11R6/lib/X11/fonts"); - - fontDirs.removeDuplicates (false); - return fontDirs; -} - -Typeface::Ptr Typeface::createSystemTypefaceFor (const Font& font) -{ - return new FreeTypeTypeface (font); -} - -Typeface::Ptr Typeface::createSystemTypefaceFor (const void* data, size_t dataSize) -{ - return new FreeTypeTypeface (data, dataSize); -} - -void Typeface::scanFolderForFonts (const File& folder) -{ - FTTypefaceList::getInstance()->scanFontPaths (StringArray (folder.getFullPathName())); -} - -StringArray Font::findAllTypefaceNames() -{ - return FTTypefaceList::getInstance()->findAllFamilyNames(); -} - -StringArray Font::findAllTypefaceStyles (const String& family) -{ - return FTTypefaceList::getInstance()->findAllTypefaceStyles (family); -} - -bool TextLayout::createNativeLayout (const AttributedString&) -{ - return false; -} - -//============================================================================== -struct DefaultFontNames -{ - DefaultFontNames() - : defaultSans (getDefaultSansSerifFontName()), - defaultSerif (getDefaultSerifFontName()), - defaultFixed (getDefaultMonospacedFontName()) - { - } - - String getRealFontName (const String& faceName) const - { - if (faceName == Font::getDefaultSansSerifFontName()) return defaultSans; - if (faceName == Font::getDefaultSerifFontName()) return defaultSerif; - if (faceName == Font::getDefaultMonospacedFontName()) return defaultFixed; - - return faceName; - } - - String defaultSans, defaultSerif, defaultFixed; - -private: - static String pickBestFont (const StringArray& names, const char* const* choicesArray) - { - const StringArray choices (choicesArray); - - for (int j = 0; j < choices.size(); ++j) - if (names.contains (choices[j], true)) - return choices[j]; - - for (int j = 0; j < choices.size(); ++j) - for (int i = 0; i < names.size(); ++i) - if (names[i].startsWithIgnoreCase (choices[j])) - return names[i]; - - for (int j = 0; j < choices.size(); ++j) - for (int i = 0; i < names.size(); ++i) - if (names[i].containsIgnoreCase (choices[j])) - return names[i]; - - return names[0]; - } - - static String getDefaultSansSerifFontName() - { - StringArray allFonts; - FTTypefaceList::getInstance()->getSansSerifNames (allFonts); - - static const char* targets[] = { "Verdana", "Bitstream Vera Sans", "Luxi Sans", - "Liberation Sans", "DejaVu Sans", "Sans", nullptr }; - return pickBestFont (allFonts, targets); - } - - static String getDefaultSerifFontName() - { - StringArray allFonts; - FTTypefaceList::getInstance()->getSerifNames (allFonts); - - static const char* targets[] = { "Bitstream Vera Serif", "Times", "Nimbus Roman", - "Liberation Serif", "DejaVu Serif", "Serif", nullptr }; - return pickBestFont (allFonts, targets); - } - - static String getDefaultMonospacedFontName() - { - StringArray allFonts; - FTTypefaceList::getInstance()->getMonospacedNames (allFonts); - - static const char* targets[] = { "DejaVu Sans Mono", "Bitstream Vera Sans Mono", "Sans Mono", - "Liberation Mono", "Courier", "DejaVu Mono", "Mono", nullptr }; - return pickBestFont (allFonts, targets); - } - - JUCE_DECLARE_NON_COPYABLE (DefaultFontNames) -}; - -Typeface::Ptr Font::getDefaultTypefaceForFont (const Font& font) -{ - static DefaultFontNames defaultNames; - - Font f (font); - f.setTypefaceName (defaultNames.getRealFontName (font.getTypefaceName())); - return Typeface::createSystemTypefaceFor (f); -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/native/juce_mac_CoreGraphicsContext.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/native/juce_mac_CoreGraphicsContext.h deleted file mode 100644 index bf26ce8ee2..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/native/juce_mac_CoreGraphicsContext.h +++ /dev/null @@ -1,121 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_MAC_COREGRAPHICSCONTEXT_H_INCLUDED -#define JUCE_MAC_COREGRAPHICSCONTEXT_H_INCLUDED - -//============================================================================== -class CoreGraphicsContext : public LowLevelGraphicsContext -{ -public: - CoreGraphicsContext (CGContextRef context, const float flipHeight, const float targetScale); - ~CoreGraphicsContext(); - - //============================================================================== - bool isVectorDevice() const override { return false; } - - void setOrigin (Point) override; - void addTransform (const AffineTransform&) override; - float getPhysicalPixelScaleFactor() override; - bool clipToRectangle (const Rectangle&) override; - bool clipToRectangleList (const RectangleList&) override; - void excludeClipRectangle (const Rectangle&) override; - void clipToPath (const Path&, const AffineTransform&) override; - void clipToImageAlpha (const Image&, const AffineTransform&) override; - bool clipRegionIntersects (const Rectangle&) override; - Rectangle getClipBounds() const override; - bool isClipEmpty() const override; - - //============================================================================== - void saveState() override; - void restoreState() override; - void beginTransparencyLayer (float opacity) override; - void endTransparencyLayer() override; - - //============================================================================== - void setFill (const FillType&) override; - void setOpacity (float) override; - void setInterpolationQuality (Graphics::ResamplingQuality) override; - - //============================================================================== - void fillRect (const Rectangle&, bool replaceExistingContents) override; - void fillRect (const Rectangle&) override; - void fillRectList (const RectangleList&) override; - void fillPath (const Path&, const AffineTransform&) override; - void drawImage (const Image& sourceImage, const AffineTransform&) override; - - //============================================================================== - void drawLine (const Line&) override; - void setFont (const Font&) override; - const Font& getFont() override; - void drawGlyph (int glyphNumber, const AffineTransform&) override; - bool drawTextLayout (const AttributedString&, const Rectangle&) override; - -private: - CGContextRef context; - const CGFloat flipHeight; - float targetScale; - CGColorSpaceRef rgbColourSpace, greyColourSpace; - CGFunctionCallbacks gradientCallbacks; - mutable Rectangle lastClipRect; - mutable bool lastClipRectIsValid; - - struct SavedState - { - SavedState(); - SavedState (const SavedState&); - ~SavedState(); - - void setFill (const FillType& newFill); - CGShadingRef getShading (CoreGraphicsContext& owner); - - static void gradientCallback (void* info, const CGFloat* inData, CGFloat* outData); - - FillType fillType; - Font font; - CGFontRef fontRef; - CGAffineTransform fontTransform; - - private: - CGShadingRef shading; - HeapBlock gradientLookupTable; - int numGradientLookupEntries; - }; - - ScopedPointer state; - OwnedArray stateStack; - - void drawGradient(); - void createPath (const Path&) const; - void createPath (const Path&, const AffineTransform&) const; - void flip() const; - void applyTransform (const AffineTransform&) const; - void drawImage (const Image&, const AffineTransform&, bool fillEntireClipAsTiles); - bool clipToRectangleListWithoutTest (const RectangleList&); - void fillCGRect (const CGRect&, bool replaceExistingContents); - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (CoreGraphicsContext) -}; - -#endif // JUCE_MAC_COREGRAPHICSCONTEXT_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/native/juce_mac_CoreGraphicsContext.mm b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/native/juce_mac_CoreGraphicsContext.mm deleted file mode 100644 index 44e344f16c..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/native/juce_mac_CoreGraphicsContext.mm +++ /dev/null @@ -1,927 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#include "juce_mac_CoreGraphicsContext.h" - -//============================================================================== -class CoreGraphicsImage : public ImagePixelData -{ -public: - CoreGraphicsImage (const Image::PixelFormat format, const int w, const int h, const bool clearImage) - : ImagePixelData (format, w, h), cachedImageRef (0) - { - pixelStride = format == Image::RGB ? 3 : ((format == Image::ARGB) ? 4 : 1); - lineStride = (pixelStride * jmax (1, width) + 3) & ~3; - - imageData.allocate ((size_t) (lineStride * jmax (1, height)), clearImage); - - CGColorSpaceRef colourSpace = (format == Image::SingleChannel) ? CGColorSpaceCreateDeviceGray() - : CGColorSpaceCreateDeviceRGB(); - - context = CGBitmapContextCreate (imageData, (size_t) width, (size_t) height, 8, (size_t) lineStride, - colourSpace, getCGImageFlags (format)); - - CGColorSpaceRelease (colourSpace); - } - - ~CoreGraphicsImage() - { - freeCachedImageRef(); - CGContextRelease (context); - } - - LowLevelGraphicsContext* createLowLevelContext() override - { - freeCachedImageRef(); - sendDataChangeMessage(); - return new CoreGraphicsContext (context, height, 1.0f); - } - - void initialiseBitmapData (Image::BitmapData& bitmap, int x, int y, Image::BitmapData::ReadWriteMode mode) override - { - bitmap.data = imageData + x * pixelStride + y * lineStride; - bitmap.pixelFormat = pixelFormat; - bitmap.lineStride = lineStride; - bitmap.pixelStride = pixelStride; - - if (mode != Image::BitmapData::readOnly) - { - freeCachedImageRef(); - sendDataChangeMessage(); - } - } - - ImagePixelData* clone() override - { - CoreGraphicsImage* im = new CoreGraphicsImage (pixelFormat, width, height, false); - memcpy (im->imageData, imageData, (size_t) (lineStride * height)); - return im; - } - - ImageType* createType() const override { return new NativeImageType(); } - - //============================================================================== - static CGImageRef getCachedImageRef (const Image& juceImage, CGColorSpaceRef colourSpace) - { - CoreGraphicsImage* const cgim = dynamic_cast (juceImage.getPixelData()); - - if (cgim != nullptr && cgim->cachedImageRef != 0) - { - CGImageRetain (cgim->cachedImageRef); - return cgim->cachedImageRef; - } - - CGImageRef ref = createImage (juceImage, colourSpace, false); - - if (cgim != nullptr) - { - CGImageRetain (ref); - cgim->cachedImageRef = ref; - } - - return ref; - } - - static CGImageRef createImage (const Image& juceImage, CGColorSpaceRef colourSpace, const bool mustOutliveSource) - { - const Image::BitmapData srcData (juceImage, Image::BitmapData::readOnly); - CGDataProviderRef provider; - - if (mustOutliveSource) - { - CFDataRef data = CFDataCreate (0, (const UInt8*) srcData.data, (CFIndex) (srcData.lineStride * srcData.height)); - provider = CGDataProviderCreateWithCFData (data); - CFRelease (data); - } - else - { - provider = CGDataProviderCreateWithData (0, srcData.data, (size_t) (srcData.lineStride * srcData.height), 0); - } - - CGImageRef imageRef = CGImageCreate ((size_t) srcData.width, - (size_t) srcData.height, - 8, (size_t) srcData.pixelStride * 8, - (size_t) srcData.lineStride, - colourSpace, getCGImageFlags (juceImage.getFormat()), provider, - 0, true, kCGRenderingIntentDefault); - - CGDataProviderRelease (provider); - return imageRef; - } - - //============================================================================== - CGContextRef context; - CGImageRef cachedImageRef; - HeapBlock imageData; - int pixelStride, lineStride; - -private: - void freeCachedImageRef() - { - if (cachedImageRef != 0) - { - CGImageRelease (cachedImageRef); - cachedImageRef = 0; - } - } - - static CGBitmapInfo getCGImageFlags (const Image::PixelFormat& format) - { - #if JUCE_BIG_ENDIAN - return format == Image::ARGB ? (kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Big) : kCGBitmapByteOrderDefault; - #else - return format == Image::ARGB ? (kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Little) : kCGBitmapByteOrderDefault; - #endif - } - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (CoreGraphicsImage) -}; - -ImagePixelData::Ptr NativeImageType::create (Image::PixelFormat format, int width, int height, bool clearImage) const -{ - return new CoreGraphicsImage (format == Image::RGB ? Image::ARGB : format, width, height, clearImage); -} - -//============================================================================== -CoreGraphicsContext::CoreGraphicsContext (CGContextRef c, const float h, const float scale) - : context (c), - flipHeight (h), - targetScale (scale), - lastClipRectIsValid (false), - state (new SavedState()) -{ - CGContextRetain (context); - CGContextSaveGState(context); - CGContextSetShouldSmoothFonts (context, true); - CGContextSetShouldAntialias (context, true); - CGContextSetBlendMode (context, kCGBlendModeNormal); - rgbColourSpace = CGColorSpaceCreateDeviceRGB(); - greyColourSpace = CGColorSpaceCreateDeviceGray(); - gradientCallbacks.version = 0; - gradientCallbacks.evaluate = SavedState::gradientCallback; - gradientCallbacks.releaseInfo = 0; - setFont (Font()); -} - -CoreGraphicsContext::~CoreGraphicsContext() -{ - CGContextRestoreGState (context); - CGContextRelease (context); - CGColorSpaceRelease (rgbColourSpace); - CGColorSpaceRelease (greyColourSpace); -} - -//============================================================================== -void CoreGraphicsContext::setOrigin (Point o) -{ - CGContextTranslateCTM (context, o.x, -o.y); - - if (lastClipRectIsValid) - lastClipRect.translate (-o.x, -o.y); -} - -void CoreGraphicsContext::addTransform (const AffineTransform& transform) -{ - applyTransform (AffineTransform::verticalFlip ((float) flipHeight) - .followedBy (transform) - .translated (0, (float) -flipHeight) - .scaled (1.0f, -1.0f)); - lastClipRectIsValid = false; - - jassert (getPhysicalPixelScaleFactor() > 0.0f); - jassert (getPhysicalPixelScaleFactor() > 0.0f); -} - -float CoreGraphicsContext::getPhysicalPixelScaleFactor() -{ - const CGAffineTransform t = CGContextGetCTM (context); - - return targetScale * (float) (juce_hypot (t.a, t.c) + juce_hypot (t.b, t.d)) / 2.0f; - -// return targetScale * (float) (t.a + t.d) / 2.0f; -} - -bool CoreGraphicsContext::clipToRectangle (const Rectangle& r) -{ - CGContextClipToRect (context, CGRectMake (r.getX(), flipHeight - r.getBottom(), r.getWidth(), r.getHeight())); - - if (lastClipRectIsValid) - { - // This is actually incorrect, because the actual clip region may be complex, and - // clipping its bounds to a rect may not be right... But, removing this shortcut - // doesn't actually fix anything because CoreGraphics also ignores complex regions - // when calculating the resultant clip bounds, and makes the same mistake! - lastClipRect = lastClipRect.getIntersection (r); - return ! lastClipRect.isEmpty(); - } - - return ! isClipEmpty(); -} - -bool CoreGraphicsContext::clipToRectangleListWithoutTest (const RectangleList& clipRegion) -{ - if (clipRegion.isEmpty()) - { - CGContextClipToRect (context, CGRectZero); - lastClipRectIsValid = true; - lastClipRect = Rectangle(); - return false; - } - else - { - const size_t numRects = (size_t) clipRegion.getNumRectangles(); - HeapBlock rects (numRects); - - int i = 0; - for (const Rectangle* r = clipRegion.begin(), * const e = clipRegion.end(); r != e; ++r) - rects[i++] = CGRectMake (r->getX(), flipHeight - r->getBottom(), r->getWidth(), r->getHeight()); - - CGContextClipToRects (context, rects, numRects); - lastClipRectIsValid = false; - return true; - } -} - -bool CoreGraphicsContext::clipToRectangleList (const RectangleList& clipRegion) -{ - return clipToRectangleListWithoutTest (clipRegion) && ! isClipEmpty(); -} - -void CoreGraphicsContext::excludeClipRectangle (const Rectangle& r) -{ - RectangleList remaining (getClipBounds()); - remaining.subtract (r); - clipToRectangleListWithoutTest (remaining); -} - -void CoreGraphicsContext::clipToPath (const Path& path, const AffineTransform& transform) -{ - createPath (path, transform); - CGContextClip (context); - lastClipRectIsValid = false; -} - -void CoreGraphicsContext::clipToImageAlpha (const Image& sourceImage, const AffineTransform& transform) -{ - if (! transform.isSingularity()) - { - Image singleChannelImage (sourceImage); - - if (sourceImage.getFormat() != Image::SingleChannel) - singleChannelImage = sourceImage.convertedToFormat (Image::SingleChannel); - - CGImageRef image = CoreGraphicsImage::createImage (singleChannelImage, greyColourSpace, true); - - flip(); - AffineTransform t (AffineTransform::verticalFlip (sourceImage.getHeight()).followedBy (transform)); - applyTransform (t); - - CGRect r = convertToCGRect (sourceImage.getBounds()); - CGContextClipToMask (context, r, image); - - applyTransform (t.inverted()); - flip(); - - CGImageRelease (image); - lastClipRectIsValid = false; - } -} - -bool CoreGraphicsContext::clipRegionIntersects (const Rectangle& r) -{ - return getClipBounds().intersects (r); -} - -Rectangle CoreGraphicsContext::getClipBounds() const -{ - if (! lastClipRectIsValid) - { - CGRect bounds = CGRectIntegral (CGContextGetClipBoundingBox (context)); - - lastClipRectIsValid = true; - lastClipRect.setBounds (roundToInt (bounds.origin.x), - roundToInt (flipHeight - (bounds.origin.y + bounds.size.height)), - roundToInt (bounds.size.width), - roundToInt (bounds.size.height)); - } - - return lastClipRect; -} - -bool CoreGraphicsContext::isClipEmpty() const -{ - return getClipBounds().isEmpty(); -} - -//============================================================================== -void CoreGraphicsContext::saveState() -{ - CGContextSaveGState (context); - stateStack.add (new SavedState (*state)); -} - -void CoreGraphicsContext::restoreState() -{ - CGContextRestoreGState (context); - - if (SavedState* const top = stateStack.getLast()) - { - state = top; - stateStack.removeLast (1, false); - lastClipRectIsValid = false; - } - else - { - jassertfalse; // trying to pop with an empty stack! - } -} - -void CoreGraphicsContext::beginTransparencyLayer (float opacity) -{ - saveState(); - CGContextSetAlpha (context, opacity); - CGContextBeginTransparencyLayer (context, 0); -} - -void CoreGraphicsContext::endTransparencyLayer() -{ - CGContextEndTransparencyLayer (context); - restoreState(); -} - -//============================================================================== -void CoreGraphicsContext::setFill (const FillType& fillType) -{ - state->setFill (fillType); - - if (fillType.isColour()) - { - CGContextSetRGBFillColor (context, fillType.colour.getFloatRed(), fillType.colour.getFloatGreen(), - fillType.colour.getFloatBlue(), fillType.colour.getFloatAlpha()); - CGContextSetAlpha (context, 1.0f); - } -} - -void CoreGraphicsContext::setOpacity (float newOpacity) -{ - state->fillType.setOpacity (newOpacity); - setFill (state->fillType); -} - -void CoreGraphicsContext::setInterpolationQuality (Graphics::ResamplingQuality quality) -{ - CGContextSetInterpolationQuality (context, quality == Graphics::lowResamplingQuality - ? kCGInterpolationLow - : kCGInterpolationHigh); -} - -//============================================================================== -void CoreGraphicsContext::fillRect (const Rectangle& r, const bool replaceExistingContents) -{ - fillCGRect (CGRectMake (r.getX(), flipHeight - r.getBottom(), r.getWidth(), r.getHeight()), replaceExistingContents); -} - -void CoreGraphicsContext::fillRect (const Rectangle& r) -{ - fillCGRect (CGRectMake (r.getX(), flipHeight - r.getBottom(), r.getWidth(), r.getHeight()), false); -} - -void CoreGraphicsContext::fillCGRect (const CGRect& cgRect, const bool replaceExistingContents) -{ - if (replaceExistingContents) - { - #if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_5 - CGContextClearRect (context, cgRect); - #else - #if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5 - if (CGContextDrawLinearGradient == 0) // (just a way of checking whether we're running in 10.5 or later) - CGContextClearRect (context, cgRect); - else - #endif - CGContextSetBlendMode (context, kCGBlendModeCopy); - #endif - - fillCGRect (cgRect, false); - CGContextSetBlendMode (context, kCGBlendModeNormal); - } - else - { - if (state->fillType.isColour()) - { - CGContextFillRect (context, cgRect); - } - else if (state->fillType.isGradient()) - { - CGContextSaveGState (context); - CGContextClipToRect (context, cgRect); - drawGradient(); - CGContextRestoreGState (context); - } - else - { - CGContextSaveGState (context); - CGContextClipToRect (context, cgRect); - drawImage (state->fillType.image, state->fillType.transform, true); - CGContextRestoreGState (context); - } - } -} - -void CoreGraphicsContext::fillPath (const Path& path, const AffineTransform& transform) -{ - CGContextSaveGState (context); - - if (state->fillType.isColour()) - { - flip(); - applyTransform (transform); - createPath (path); - - if (path.isUsingNonZeroWinding()) - CGContextFillPath (context); - else - CGContextEOFillPath (context); - } - else - { - createPath (path, transform); - - if (path.isUsingNonZeroWinding()) - CGContextClip (context); - else - CGContextEOClip (context); - - if (state->fillType.isGradient()) - drawGradient(); - else - drawImage (state->fillType.image, state->fillType.transform, true); - } - - CGContextRestoreGState (context); -} - -void CoreGraphicsContext::drawImage (const Image& sourceImage, const AffineTransform& transform) -{ - drawImage (sourceImage, transform, false); -} - -void CoreGraphicsContext::drawImage (const Image& sourceImage, const AffineTransform& transform, const bool fillEntireClipAsTiles) -{ - const int iw = sourceImage.getWidth(); - const int ih = sourceImage.getHeight(); - CGImageRef image = CoreGraphicsImage::getCachedImageRef (sourceImage, rgbColourSpace); - - CGContextSaveGState (context); - CGContextSetAlpha (context, state->fillType.getOpacity()); - - flip(); - applyTransform (AffineTransform::verticalFlip (ih).followedBy (transform)); - CGRect imageRect = CGRectMake (0, 0, iw, ih); - - if (fillEntireClipAsTiles) - { - #if JUCE_IOS - CGContextDrawTiledImage (context, imageRect, image); - #else - #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 - // There's a bug in CGContextDrawTiledImage that makes it incredibly slow - // if it's doing a transformation - it's quicker to just draw lots of images manually - if (CGContextDrawTiledImage != 0 && transform.isOnlyTranslation()) - CGContextDrawTiledImage (context, imageRect, image); - else - #endif - { - // Fallback to manually doing a tiled fill on 10.4 - CGRect clip = CGRectIntegral (CGContextGetClipBoundingBox (context)); - - int x = 0, y = 0; - while (x > clip.origin.x) x -= iw; - while (y > clip.origin.y) y -= ih; - - const int right = (int) (clip.origin.x + clip.size.width); - const int bottom = (int) (clip.origin.y + clip.size.height); - - while (y < bottom) - { - for (int x2 = x; x2 < right; x2 += iw) - CGContextDrawImage (context, CGRectMake (x2, y, iw, ih), image); - - y += ih; - } - } - #endif - } - else - { - CGContextDrawImage (context, imageRect, image); - } - - CGImageRelease (image); // (This causes a memory bug in iOS sim 3.0 - try upgrading to a later version if you hit this) - CGContextRestoreGState (context); -} - -//============================================================================== -void CoreGraphicsContext::drawLine (const Line& line) -{ - if (state->fillType.isColour()) - { - CGContextSetLineCap (context, kCGLineCapSquare); - CGContextSetLineWidth (context, 1.0f); - CGContextSetRGBStrokeColor (context, - state->fillType.colour.getFloatRed(), state->fillType.colour.getFloatGreen(), - state->fillType.colour.getFloatBlue(), state->fillType.colour.getFloatAlpha()); - - CGPoint cgLine[] = { { (CGFloat) line.getStartX(), flipHeight - (CGFloat) line.getStartY() }, - { (CGFloat) line.getEndX(), flipHeight - (CGFloat) line.getEndY() } }; - - CGContextStrokeLineSegments (context, cgLine, 1); - } - else - { - Path p; - p.addLineSegment (line, 1.0f); - fillPath (p, AffineTransform::identity); - } -} - -void CoreGraphicsContext::fillRectList (const RectangleList& list) -{ - HeapBlock rects ((size_t) list.getNumRectangles()); - - size_t num = 0; - for (const Rectangle* r = list.begin(), * const e = list.end(); r != e; ++r) - rects[num++] = CGRectMake (r->getX(), flipHeight - r->getBottom(), r->getWidth(), r->getHeight()); - - if (state->fillType.isColour()) - { - CGContextFillRects (context, rects, num); - } - else if (state->fillType.isGradient()) - { - CGContextSaveGState (context); - CGContextClipToRects (context, rects, num); - drawGradient(); - CGContextRestoreGState (context); - } - else - { - CGContextSaveGState (context); - CGContextClipToRects (context, rects, num); - drawImage (state->fillType.image, state->fillType.transform, true); - CGContextRestoreGState (context); - } -} - -void CoreGraphicsContext::setFont (const Font& newFont) -{ - if (state->font != newFont) - { - state->fontRef = 0; - state->font = newFont; - - if (OSXTypeface* osxTypeface = dynamic_cast (state->font.getTypeface())) - { - state->fontRef = osxTypeface->fontRef; - CGContextSetFont (context, state->fontRef); - CGContextSetFontSize (context, state->font.getHeight() * osxTypeface->fontHeightToPointsFactor); - - state->fontTransform = osxTypeface->renderingTransform; - state->fontTransform.a *= state->font.getHorizontalScale(); - CGContextSetTextMatrix (context, state->fontTransform); - } - } -} - -const Font& CoreGraphicsContext::getFont() -{ - return state->font; -} - -void CoreGraphicsContext::drawGlyph (int glyphNumber, const AffineTransform& transform) -{ - if (state->fontRef != 0 && state->fillType.isColour()) - { - #if JUCE_CLANG - #pragma clang diagnostic push - #pragma clang diagnostic ignored "-Wdeprecated-declarations" - #endif - - if (transform.isOnlyTranslation()) - { - CGContextSetTextMatrix (context, state->fontTransform); // have to set this each time, as it's not saved as part of the state - - CGGlyph g = (CGGlyph) glyphNumber; - CGContextShowGlyphsAtPoint (context, transform.getTranslationX(), - flipHeight - roundToInt (transform.getTranslationY()), &g, 1); - } - else - { - CGContextSaveGState (context); - flip(); - applyTransform (transform); - - CGAffineTransform t = state->fontTransform; - t.d = -t.d; - CGContextSetTextMatrix (context, t); - - CGGlyph g = (CGGlyph) glyphNumber; - CGContextShowGlyphsAtPoint (context, 0, 0, &g, 1); - - CGContextRestoreGState (context); - } - - #if JUCE_CLANG - #pragma clang diagnostic pop - #endif - } - else - { - Path p; - Font& f = state->font; - f.getTypeface()->getOutlineForGlyph (glyphNumber, p); - - fillPath (p, AffineTransform::scale (f.getHeight() * f.getHorizontalScale(), f.getHeight()) - .followedBy (transform)); - } -} - -bool CoreGraphicsContext::drawTextLayout (const AttributedString& text, const Rectangle& area) -{ - #if JUCE_CORETEXT_AVAILABLE - CoreTextTypeLayout::drawToCGContext (text, area, context, (float) flipHeight); - return true; - #else - (void) text; (void) area; - return false; - #endif -} - -CoreGraphicsContext::SavedState::SavedState() - : font (1.0f), fontRef (0), fontTransform (CGAffineTransformIdentity), - shading (0), numGradientLookupEntries (0) -{ -} - -CoreGraphicsContext::SavedState::SavedState (const SavedState& other) - : fillType (other.fillType), font (other.font), fontRef (other.fontRef), - fontTransform (other.fontTransform), shading (0), - gradientLookupTable ((size_t) other.numGradientLookupEntries), - numGradientLookupEntries (other.numGradientLookupEntries) -{ - memcpy (gradientLookupTable, other.gradientLookupTable, sizeof (PixelARGB) * (size_t) numGradientLookupEntries); -} - -CoreGraphicsContext::SavedState::~SavedState() -{ - if (shading != 0) - CGShadingRelease (shading); -} - -void CoreGraphicsContext::SavedState::setFill (const FillType& newFill) -{ - fillType = newFill; - - if (fillType.isGradient() && shading != 0) - { - CGShadingRelease (shading); - shading = 0; - } -} - -CGShadingRef CoreGraphicsContext::SavedState::getShading (CoreGraphicsContext& owner) -{ - if (shading == 0) - { - ColourGradient& g = *(fillType.gradient); - numGradientLookupEntries = g.createLookupTable (fillType.transform, gradientLookupTable) - 1; - - CGFunctionRef function = CGFunctionCreate (this, 1, 0, 4, 0, &(owner.gradientCallbacks)); - CGPoint p1 (convertToCGPoint (g.point1)); - - if (g.isRadial) - { - shading = CGShadingCreateRadial (owner.rgbColourSpace, p1, 0, - p1, g.point1.getDistanceFrom (g.point2), - function, true, true); - } - else - { - shading = CGShadingCreateAxial (owner.rgbColourSpace, p1, - convertToCGPoint (g.point2), - function, true, true); - } - - CGFunctionRelease (function); - } - - return shading; -} - -void CoreGraphicsContext::SavedState::gradientCallback (void* info, const CGFloat* inData, CGFloat* outData) -{ - const SavedState* const s = static_cast (info); - - const int index = roundToInt (s->numGradientLookupEntries * inData[0]); - PixelARGB colour (s->gradientLookupTable [jlimit (0, s->numGradientLookupEntries, index)]); - colour.unpremultiply(); - - outData[0] = colour.getRed() / 255.0f; - outData[1] = colour.getGreen() / 255.0f; - outData[2] = colour.getBlue() / 255.0f; - outData[3] = colour.getAlpha() / 255.0f; -} - -void CoreGraphicsContext::drawGradient() -{ - flip(); - applyTransform (state->fillType.transform); - - CGContextSetInterpolationQuality (context, kCGInterpolationDefault); // (This is required for 10.4, where there's a crash if - // you draw a gradient with high quality interp enabled). - CGContextSetAlpha (context, state->fillType.getOpacity()); - CGContextDrawShading (context, state->getShading (*this)); -} - -void CoreGraphicsContext::createPath (const Path& path) const -{ - CGContextBeginPath (context); - Path::Iterator i (path); - - while (i.next()) - { - switch (i.elementType) - { - case Path::Iterator::startNewSubPath: CGContextMoveToPoint (context, i.x1, i.y1); break; - case Path::Iterator::lineTo: CGContextAddLineToPoint (context, i.x1, i.y1); break; - case Path::Iterator::quadraticTo: CGContextAddQuadCurveToPoint (context, i.x1, i.y1, i.x2, i.y2); break; - case Path::Iterator::cubicTo: CGContextAddCurveToPoint (context, i.x1, i.y1, i.x2, i.y2, i.x3, i.y3); break; - case Path::Iterator::closePath: CGContextClosePath (context); break; - default: jassertfalse; break; - } - } -} - -void CoreGraphicsContext::createPath (const Path& path, const AffineTransform& transform) const -{ - CGContextBeginPath (context); - Path::Iterator i (path); - - while (i.next()) - { - switch (i.elementType) - { - case Path::Iterator::startNewSubPath: - transform.transformPoint (i.x1, i.y1); - CGContextMoveToPoint (context, i.x1, flipHeight - i.y1); - break; - case Path::Iterator::lineTo: - transform.transformPoint (i.x1, i.y1); - CGContextAddLineToPoint (context, i.x1, flipHeight - i.y1); - break; - case Path::Iterator::quadraticTo: - transform.transformPoints (i.x1, i.y1, i.x2, i.y2); - CGContextAddQuadCurveToPoint (context, i.x1, flipHeight - i.y1, i.x2, flipHeight - i.y2); - break; - case Path::Iterator::cubicTo: - transform.transformPoints (i.x1, i.y1, i.x2, i.y2, i.x3, i.y3); - CGContextAddCurveToPoint (context, i.x1, flipHeight - i.y1, i.x2, flipHeight - i.y2, i.x3, flipHeight - i.y3); - break; - case Path::Iterator::closePath: - CGContextClosePath (context); break; - default: - jassertfalse; - break; - } - } -} - -void CoreGraphicsContext::flip() const -{ - CGContextConcatCTM (context, CGAffineTransformMake (1, 0, 0, -1, 0, flipHeight)); -} - -void CoreGraphicsContext::applyTransform (const AffineTransform& transform) const -{ - CGAffineTransform t; - t.a = transform.mat00; - t.b = transform.mat10; - t.c = transform.mat01; - t.d = transform.mat11; - t.tx = transform.mat02; - t.ty = transform.mat12; - CGContextConcatCTM (context, t); -} - -//============================================================================== -#if USE_COREGRAPHICS_RENDERING && JUCE_USE_COREIMAGE_LOADER -Image juce_loadWithCoreImage (InputStream& input) -{ - MemoryBlock data; - input.readIntoMemoryBlock (data, -1); - - #if JUCE_IOS - JUCE_AUTORELEASEPOOL - #endif - { - #if JUCE_IOS - if (UIImage* uiImage = [UIImage imageWithData: [NSData dataWithBytesNoCopy: data.getData() - length: data.getSize() - freeWhenDone: NO]]) - { - CGImageRef loadedImage = uiImage.CGImage; - - #else - CGDataProviderRef provider = CGDataProviderCreateWithData (0, data.getData(), data.getSize(), 0); - CGImageSourceRef imageSource = CGImageSourceCreateWithDataProvider (provider, 0); - CGDataProviderRelease (provider); - - if (imageSource != 0) - { - CGImageRef loadedImage = CGImageSourceCreateImageAtIndex (imageSource, 0, 0); - CFRelease (imageSource); - #endif - - if (loadedImage != 0) - { - CGImageAlphaInfo alphaInfo = CGImageGetAlphaInfo (loadedImage); - const bool hasAlphaChan = (alphaInfo != kCGImageAlphaNone - && alphaInfo != kCGImageAlphaNoneSkipLast - && alphaInfo != kCGImageAlphaNoneSkipFirst); - - Image image (NativeImageType().create (Image::ARGB, // (CoreImage doesn't work with 24-bit images) - (int) CGImageGetWidth (loadedImage), - (int) CGImageGetHeight (loadedImage), - hasAlphaChan)); - - CoreGraphicsImage* const cgImage = dynamic_cast (image.getPixelData()); - jassert (cgImage != nullptr); // if USE_COREGRAPHICS_RENDERING is set, the CoreGraphicsImage class should have been used. - - CGContextDrawImage (cgImage->context, convertToCGRect (image.getBounds()), loadedImage); - CGContextFlush (cgImage->context); - - #if ! JUCE_IOS - CFRelease (loadedImage); - #endif - - // Because it's impossible to create a truly 24-bit CG image, this flag allows a user - // to find out whether the file they just loaded the image from had an alpha channel or not. - image.getProperties()->set ("originalImageHadAlpha", hasAlphaChan); - return image; - } - } - } - - return Image::null; -} -#endif - -#if JUCE_MAC -Image juce_createImageFromCIImage (CIImage*, int, int); -Image juce_createImageFromCIImage (CIImage* im, int w, int h) -{ - CoreGraphicsImage* cgImage = new CoreGraphicsImage (Image::ARGB, w, h, false); - - CIContext* cic = [CIContext contextWithCGContext: cgImage->context options: nil]; - [cic drawImage: im inRect: CGRectMake (0, 0, w, h) fromRect: CGRectMake (0, 0, w, h)]; - CGContextFlush (cgImage->context); - - return Image (cgImage); -} - -CGImageRef juce_createCoreGraphicsImage (const Image& juceImage, CGColorSpaceRef colourSpace, - const bool mustOutliveSource) -{ - return CoreGraphicsImage::createImage (juceImage, colourSpace, mustOutliveSource); -} - -CGContextRef juce_getImageContext (const Image& image) -{ - if (CoreGraphicsImage* const cgi = dynamic_cast (image.getPixelData())) - return cgi->context; - - jassertfalse; - return 0; -} - -#endif diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/native/juce_mac_CoreGraphicsHelpers.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/native/juce_mac_CoreGraphicsHelpers.h deleted file mode 100644 index ca6f699268..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/native/juce_mac_CoreGraphicsHelpers.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_MAC_COREGRAPHICSHELPERS_H_INCLUDED -#define JUCE_MAC_COREGRAPHICSHELPERS_H_INCLUDED - - -//============================================================================== -namespace -{ - template - Rectangle convertToRectInt (const RectType& r) noexcept - { - return Rectangle ((int) r.origin.x, (int) r.origin.y, (int) r.size.width, (int) r.size.height); - } - - template - Rectangle convertToRectFloat (const RectType& r) noexcept - { - return Rectangle (r.origin.x, r.origin.y, r.size.width, r.size.height); - } - - template - CGRect convertToCGRect (const RectType& r) noexcept - { - return CGRectMake ((CGFloat) r.getX(), (CGFloat) r.getY(), (CGFloat) r.getWidth(), (CGFloat) r.getHeight()); - } - - template - CGPoint convertToCGPoint (const PointType& p) noexcept - { - return CGPointMake ((CGFloat) p.x, (CGFloat) p.y); - } -} - -extern CGImageRef juce_createCoreGraphicsImage (const Image&, CGColorSpaceRef, bool mustOutliveSource); -extern CGContextRef juce_getImageContext (const Image&); - -#endif // JUCE_MAC_COREGRAPHICSHELPERS_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/native/juce_mac_Fonts.mm b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/native/juce_mac_Fonts.mm deleted file mode 100644 index 81a29a8047..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/native/juce_mac_Fonts.mm +++ /dev/null @@ -1,1321 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#if (! defined (JUCE_CORETEXT_AVAILABLE)) \ - && (JUCE_IOS || (JUCE_MAC && MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_4)) - #define JUCE_CORETEXT_AVAILABLE 1 -#endif - -const float referenceFontSize = 1024.0f; - -#if JUCE_CORETEXT_AVAILABLE - -#if JUCE_MAC && MAC_OS_X_VERSION_MAX_ALLOWED == MAC_OS_X_VERSION_10_5 -extern "C" -{ - void CTRunGetAdvances (CTRunRef, CFRange, CGSize buffer[]); - const CGSize* CTRunGetAdvancesPtr (CTRunRef); -} -#endif - -static CTFontRef getCTFontFromTypeface (const Font& f); - -namespace CoreTextTypeLayout -{ - static String findBestAvailableStyle (const Font& font, CGAffineTransform& requiredTransform) - { - const StringArray availableStyles (Font::findAllTypefaceStyles (font.getTypefaceName())); - const String style (font.getTypefaceStyle()); - - if (! availableStyles.contains (style)) - { - if (font.isItalic()) // Fake-up an italic font if there isn't a real one. - requiredTransform = CGAffineTransformMake (1.0f, 0, 0.25f, 1.0f, 0, 0); - - return availableStyles[0]; - } - - return style; - } - - // Workaround for Apple bug in CTFontCreateWithFontDescriptor in Garageband/Logic on 10.6 - #if JUCE_MAC && ((! defined (MAC_OS_X_VERSION_10_7)) || MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_7) - static CTFontRef getFontWithTrait (CTFontRef ctFontRef, CTFontSymbolicTraits trait) - { - if (CTFontRef newFont = CTFontCreateCopyWithSymbolicTraits (ctFontRef, 0.0f, nullptr, trait, trait)) - { - CFRelease (ctFontRef); - return newFont; - } - - return ctFontRef; - } - - static CTFontRef useStyleFallbackIfNecessary (CTFontRef ctFontRef, CFStringRef cfFontFamily, - const float fontSizePoints, const Font& font) - { - CFStringRef cfActualFontFamily = (CFStringRef) CTFontCopyAttribute (ctFontRef, kCTFontFamilyNameAttribute); - - if (CFStringCompare (cfFontFamily, cfActualFontFamily, 0) != kCFCompareEqualTo) - { - CFRelease (ctFontRef); - ctFontRef = CTFontCreateWithName (cfFontFamily, fontSizePoints, nullptr); - - if (font.isItalic()) ctFontRef = getFontWithTrait (ctFontRef, kCTFontItalicTrait); - if (font.isBold()) ctFontRef = getFontWithTrait (ctFontRef, kCTFontBoldTrait); - } - - CFRelease (cfActualFontFamily); - return ctFontRef; - } - #endif - - static float getFontTotalHeight (CTFontRef font) - { - return std::abs ((float) CTFontGetAscent (font)) + std::abs ((float) CTFontGetDescent (font)); - } - - static float getHeightToPointsFactor (CTFontRef font) - { - return referenceFontSize / getFontTotalHeight (font); - } - - static CTFontRef getFontWithPointSize (CTFontRef font, float size) - { - CTFontRef newFont = CTFontCreateCopyWithAttributes (font, size, nullptr, nullptr); - CFRelease (font); - return newFont; - } - - static CTFontRef createCTFont (const Font& font, const float fontSizePoints, CGAffineTransform& transformRequired) - { - CFStringRef cfFontFamily = FontStyleHelpers::getConcreteFamilyName (font).toCFString(); - CFStringRef cfFontStyle = findBestAvailableStyle (font, transformRequired).toCFString(); - CFStringRef keys[] = { kCTFontFamilyNameAttribute, kCTFontStyleNameAttribute }; - CFTypeRef values[] = { cfFontFamily, cfFontStyle }; - - CFDictionaryRef fontDescAttributes = CFDictionaryCreate (nullptr, (const void**) &keys, - (const void**) &values, - numElementsInArray (keys), - &kCFTypeDictionaryKeyCallBacks, - &kCFTypeDictionaryValueCallBacks); - CFRelease (cfFontStyle); - - CTFontDescriptorRef ctFontDescRef = CTFontDescriptorCreateWithAttributes (fontDescAttributes); - CFRelease (fontDescAttributes); - - CTFontRef ctFontRef = CTFontCreateWithFontDescriptor (ctFontDescRef, fontSizePoints, nullptr); - CFRelease (ctFontDescRef); - - #if JUCE_MAC && ((! defined (MAC_OS_X_VERSION_10_7)) || MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_7) - ctFontRef = useStyleFallbackIfNecessary (ctFontRef, cfFontFamily, fontSizePoints, font); - #endif - - CFRelease (cfFontFamily); - - return ctFontRef; - } - - //============================================================================== - struct Advances - { - Advances (CTRunRef run, const CFIndex numGlyphs) - : advances (CTRunGetAdvancesPtr (run)) - { - if (advances == nullptr) - { - local.malloc ((size_t) numGlyphs); - CTRunGetAdvances (run, CFRangeMake (0, 0), local); - advances = local; - } - } - - const CGSize* advances; - HeapBlock local; - }; - - struct Glyphs - { - Glyphs (CTRunRef run, const size_t numGlyphs) - : glyphs (CTRunGetGlyphsPtr (run)) - { - if (glyphs == nullptr) - { - local.malloc (numGlyphs); - CTRunGetGlyphs (run, CFRangeMake (0, 0), local); - glyphs = local; - } - } - - const CGGlyph* glyphs; - HeapBlock local; - }; - - struct Positions - { - Positions (CTRunRef run, const size_t numGlyphs) - : points (CTRunGetPositionsPtr (run)) - { - if (points == nullptr) - { - local.malloc (numGlyphs); - CTRunGetPositions (run, CFRangeMake (0, 0), local); - points = local; - } - } - - const CGPoint* points; - HeapBlock local; - }; - - struct LineInfo - { - LineInfo (CTFrameRef frame, CTLineRef line, CFIndex lineIndex) - { - CTFrameGetLineOrigins (frame, CFRangeMake (lineIndex, 1), &origin); - CTLineGetTypographicBounds (line, &ascent, &descent, &leading); - } - - CGPoint origin; - CGFloat ascent, descent, leading; - }; - - static CTFontRef getOrCreateFont (const Font& f) - { - if (CTFontRef ctf = getCTFontFromTypeface (f)) - { - CFRetain (ctf); - return ctf; - } - - CGAffineTransform transform; - return createCTFont (f, referenceFontSize, transform); - } - - //============================================================================== - static CFAttributedStringRef createCFAttributedString (const AttributedString& text) - { - #if JUCE_IOS - CGColorSpaceRef rgbColourSpace = CGColorSpaceCreateDeviceRGB(); - #endif - - CFStringRef cfText = text.getText().toCFString(); - CFMutableAttributedStringRef attribString = CFAttributedStringCreateMutable (kCFAllocatorDefault, 0); - CFAttributedStringReplaceString (attribString, CFRangeMake(0, 0), cfText); - CFRelease (cfText); - - const int numCharacterAttributes = text.getNumAttributes(); - - for (int i = 0; i < numCharacterAttributes; ++i) - { - const AttributedString::Attribute& attr = *text.getAttribute (i); - - if (attr.range.getStart() > CFAttributedStringGetLength (attribString)) - continue; - - Range range (attr.range); - range.setEnd (jmin (range.getEnd(), (int) CFAttributedStringGetLength (attribString))); - - if (const Font* const f = attr.getFont()) - { - if (CTFontRef ctFontRef = getOrCreateFont (*f)) - { - ctFontRef = getFontWithPointSize (ctFontRef, f->getHeight() * getHeightToPointsFactor (ctFontRef)); - - CFAttributedStringSetAttribute (attribString, CFRangeMake (range.getStart(), range.getLength()), - kCTFontAttributeName, ctFontRef); - CFRelease (ctFontRef); - } - } - - if (const Colour* const col = attr.getColour()) - { - #if JUCE_IOS - const CGFloat components[] = { col->getFloatRed(), - col->getFloatGreen(), - col->getFloatBlue(), - col->getFloatAlpha() }; - CGColorRef colour = CGColorCreate (rgbColourSpace, components); - #else - CGColorRef colour = CGColorCreateGenericRGB (col->getFloatRed(), - col->getFloatGreen(), - col->getFloatBlue(), - col->getFloatAlpha()); - #endif - - CFAttributedStringSetAttribute (attribString, - CFRangeMake (range.getStart(), range.getLength()), - kCTForegroundColorAttributeName, colour); - CGColorRelease (colour); - } - } - - // Paragraph Attributes - CTTextAlignment ctTextAlignment = kCTLeftTextAlignment; - CTLineBreakMode ctLineBreakMode = kCTLineBreakByWordWrapping; - const CGFloat ctLineSpacing = text.getLineSpacing(); - - switch (text.getJustification().getOnlyHorizontalFlags()) - { - case Justification::left: break; - case Justification::right: ctTextAlignment = kCTRightTextAlignment; break; - case Justification::horizontallyCentred: ctTextAlignment = kCTCenterTextAlignment; break; - case Justification::horizontallyJustified: ctTextAlignment = kCTJustifiedTextAlignment; break; - default: jassertfalse; break; // Illegal justification flags - } - - switch (text.getWordWrap()) - { - case AttributedString::byWord: break; - case AttributedString::none: ctLineBreakMode = kCTLineBreakByClipping; break; - case AttributedString::byChar: ctLineBreakMode = kCTLineBreakByCharWrapping; break; - default: break; - } - - CTParagraphStyleSetting settings[] = - { - { kCTParagraphStyleSpecifierAlignment, sizeof (CTTextAlignment), &ctTextAlignment }, - { kCTParagraphStyleSpecifierLineBreakMode, sizeof (CTLineBreakMode), &ctLineBreakMode }, - - #if defined (MAC_OS_X_VERSION_10_7) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7 - { kCTParagraphStyleSpecifierLineSpacingAdjustment, sizeof (CGFloat), &ctLineSpacing } - #else - { kCTParagraphStyleSpecifierLineSpacing, sizeof (CGFloat), &ctLineSpacing } - #endif - }; - - CTParagraphStyleRef ctParagraphStyleRef = CTParagraphStyleCreate (settings, (size_t) numElementsInArray (settings)); - CFAttributedStringSetAttribute (attribString, CFRangeMake (0, CFAttributedStringGetLength (attribString)), - kCTParagraphStyleAttributeName, ctParagraphStyleRef); - CFRelease (ctParagraphStyleRef); - #if JUCE_IOS - CGColorSpaceRelease (rgbColourSpace); - #endif - return attribString; - } - - static CTFrameRef createCTFrame (const AttributedString& text, CGRect bounds) - { - CFAttributedStringRef attribString = createCFAttributedString (text); - CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString (attribString); - CFRelease (attribString); - - CGMutablePathRef path = CGPathCreateMutable(); - CGPathAddRect (path, nullptr, bounds); - - CTFrameRef frame = CTFramesetterCreateFrame (framesetter, CFRangeMake (0, 0), path, nullptr); - CFRelease (framesetter); - CGPathRelease (path); - - return frame; - } - - static Range getLineVerticalRange (CTFrameRef frame, CFArrayRef lines, int lineIndex) - { - LineInfo info (frame, (CTLineRef) CFArrayGetValueAtIndex (lines, lineIndex), lineIndex); - return Range ((float) (info.origin.y - info.descent), - (float) (info.origin.y + info.ascent)); - } - - static float findCTFrameHeight (CTFrameRef frame) - { - CFArrayRef lines = CTFrameGetLines (frame); - const CFIndex numLines = CFArrayGetCount (lines); - - if (numLines == 0) - return 0; - - Range range (getLineVerticalRange (frame, lines, 0)); - - if (numLines > 1) - range = range.getUnionWith (getLineVerticalRange (frame, lines, (int) numLines - 1)); - - return range.getLength(); - } - - static void drawToCGContext (const AttributedString& text, const Rectangle& area, - const CGContextRef& context, const float flipHeight) - { - CTFrameRef frame = createCTFrame (text, CGRectMake ((CGFloat) area.getX(), flipHeight - (CGFloat) area.getBottom(), - (CGFloat) area.getWidth(), (CGFloat) area.getHeight())); - - const int verticalJustification = text.getJustification().getOnlyVerticalFlags(); - - if (verticalJustification == Justification::verticallyCentred - || verticalJustification == Justification::bottom) - { - float adjust = area.getHeight() - findCTFrameHeight (frame); - - if (verticalJustification == Justification::verticallyCentred) - adjust *= 0.5f; - - CGContextSaveGState (context); - CGContextTranslateCTM (context, 0, -adjust); - CTFrameDraw (frame, context); - CGContextRestoreGState (context); - } - else - { - CTFrameDraw (frame, context); - } - - CFRelease (frame); - } - - static void createLayout (TextLayout& glyphLayout, const AttributedString& text) - { - const CGFloat boundsHeight = 1.0e6f; - CTFrameRef frame = createCTFrame (text, CGRectMake (0, 0, glyphLayout.getWidth(), boundsHeight)); - - CFArrayRef lines = CTFrameGetLines (frame); - const CFIndex numLines = CFArrayGetCount (lines); - - glyphLayout.ensureStorageAllocated ((int) numLines); - - for (CFIndex i = 0; i < numLines; ++i) - { - CTLineRef line = (CTLineRef) CFArrayGetValueAtIndex (lines, i); - - CFArrayRef runs = CTLineGetGlyphRuns (line); - const CFIndex numRuns = CFArrayGetCount (runs); - - const CFRange cfrlineStringRange = CTLineGetStringRange (line); - const CFIndex lineStringEnd = cfrlineStringRange.location + cfrlineStringRange.length - 1; - const Range lineStringRange ((int) cfrlineStringRange.location, (int) lineStringEnd); - - LineInfo lineInfo (frame, line, i); - - TextLayout::Line* const glyphLine = new TextLayout::Line (lineStringRange, - Point ((float) lineInfo.origin.x, - (float) (boundsHeight - lineInfo.origin.y)), - (float) lineInfo.ascent, - (float) lineInfo.descent, - (float) lineInfo.leading, - (int) numRuns); - glyphLayout.addLine (glyphLine); - - for (CFIndex j = 0; j < numRuns; ++j) - { - CTRunRef run = (CTRunRef) CFArrayGetValueAtIndex (runs, j); - const CFIndex numGlyphs = CTRunGetGlyphCount (run); - const CFRange runStringRange = CTRunGetStringRange (run); - - TextLayout::Run* const glyphRun = new TextLayout::Run (Range ((int) runStringRange.location, - (int) (runStringRange.location + runStringRange.length - 1)), - (int) numGlyphs); - glyphLine->runs.add (glyphRun); - - CFDictionaryRef runAttributes = CTRunGetAttributes (run); - - CTFontRef ctRunFont; - if (CFDictionaryGetValueIfPresent (runAttributes, kCTFontAttributeName, (const void **) &ctRunFont)) - { - CFStringRef cfsFontName = CTFontCopyPostScriptName (ctRunFont); - CTFontRef ctFontRef = CTFontCreateWithName (cfsFontName, referenceFontSize, nullptr); - CFRelease (cfsFontName); - - const float fontHeightToPointsFactor = getHeightToPointsFactor (ctFontRef); - CFRelease (ctFontRef); - - CFStringRef cfsFontFamily = (CFStringRef) CTFontCopyAttribute (ctRunFont, kCTFontFamilyNameAttribute); - CFStringRef cfsFontStyle = (CFStringRef) CTFontCopyAttribute (ctRunFont, kCTFontStyleNameAttribute); - - glyphRun->font = Font (String::fromCFString (cfsFontFamily), - String::fromCFString (cfsFontStyle), - (float) (CTFontGetSize (ctRunFont) / fontHeightToPointsFactor)); - - CFRelease (cfsFontStyle); - CFRelease (cfsFontFamily); - } - - CGColorRef cgRunColor; - if (CFDictionaryGetValueIfPresent (runAttributes, kCTForegroundColorAttributeName, (const void**) &cgRunColor) - && CGColorGetNumberOfComponents (cgRunColor) == 4) - { - const CGFloat* const components = CGColorGetComponents (cgRunColor); - - glyphRun->colour = Colour::fromFloatRGBA ((float) components[0], - (float) components[1], - (float) components[2], - (float) components[3]); - } - - const Glyphs glyphs (run, (size_t) numGlyphs); - const Advances advances (run, numGlyphs); - const Positions positions (run, (size_t) numGlyphs); - - for (CFIndex k = 0; k < numGlyphs; ++k) - glyphRun->glyphs.add (TextLayout::Glyph (glyphs.glyphs[k], Point ((float) positions.points[k].x, - (float) positions.points[k].y), - (float) advances.advances[k].width)); - } - } - - CFRelease (frame); - } -} - - -//============================================================================== -class OSXTypeface : public Typeface -{ -public: - OSXTypeface (const Font& font) - : Typeface (font.getTypefaceName(), - font.getTypefaceStyle()), - fontRef (nullptr), - ctFontRef (nullptr), - fontHeightToPointsFactor (1.0f), - renderingTransform (CGAffineTransformIdentity), - isMemoryFont (false), - attributedStringAtts (nullptr), - ascent (0.0f), - unitsToHeightScaleFactor (0.0f) - { - ctFontRef = CoreTextTypeLayout::createCTFont (font, referenceFontSize, renderingTransform); - - if (ctFontRef != nullptr) - { - fontRef = CTFontCopyGraphicsFont (ctFontRef, nullptr); - initialiseMetrics(); - } - } - - OSXTypeface (const void* data, size_t dataSize) - : Typeface (String(), String()), - fontRef (nullptr), - ctFontRef (nullptr), - fontHeightToPointsFactor (1.0f), - renderingTransform (CGAffineTransformIdentity), - isMemoryFont (true), - attributedStringAtts (nullptr), - ascent (0.0f), - unitsToHeightScaleFactor (0.0f) - { - CFDataRef cfData = CFDataCreate (kCFAllocatorDefault, (const UInt8*) data, (CFIndex) dataSize); - CGDataProviderRef provider = CGDataProviderCreateWithCFData (cfData); - CFRelease (cfData); - - fontRef = CGFontCreateWithDataProvider (provider); - CGDataProviderRelease (provider); - - if (fontRef != nullptr) - { - ctFontRef = CTFontCreateWithGraphicsFont (fontRef, referenceFontSize, nullptr, nullptr); - - if (ctFontRef != nullptr) - { - if (CFStringRef fontName = CTFontCopyName (ctFontRef, kCTFontFamilyNameKey)) - { - name = String::fromCFString (fontName); - CFRelease (fontName); - } - - if (CFStringRef fontStyle = CTFontCopyName (ctFontRef, kCTFontStyleNameKey)) - { - style = String::fromCFString (fontStyle); - CFRelease (fontStyle); - } - - initialiseMetrics(); - } - } - } - - void initialiseMetrics() - { - const float ctAscent = std::abs ((float) CTFontGetAscent (ctFontRef)); - const float ctDescent = std::abs ((float) CTFontGetDescent (ctFontRef)); - const float ctTotalHeight = ctAscent + ctDescent; - - ascent = ctAscent / ctTotalHeight; - unitsToHeightScaleFactor = 1.0f / ctTotalHeight; - pathTransform = AffineTransform::identity.scale (unitsToHeightScaleFactor); - - fontHeightToPointsFactor = referenceFontSize / ctTotalHeight; - - const short zero = 0; - CFNumberRef numberRef = CFNumberCreate (0, kCFNumberShortType, &zero); - - CFStringRef keys[] = { kCTFontAttributeName, kCTLigatureAttributeName }; - CFTypeRef values[] = { ctFontRef, numberRef }; - attributedStringAtts = CFDictionaryCreate (nullptr, (const void**) &keys, (const void**) &values, numElementsInArray (keys), - &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); - CFRelease (numberRef); - } - - ~OSXTypeface() - { - if (attributedStringAtts != nullptr) - CFRelease (attributedStringAtts); - - if (fontRef != nullptr) - CGFontRelease (fontRef); - - if (ctFontRef != nullptr) - CFRelease (ctFontRef); - } - - float getAscent() const override { return ascent; } - float getDescent() const override { return 1.0f - ascent; } - float getHeightToPointsFactor() const override { return fontHeightToPointsFactor; } - - float getStringWidth (const String& text) override - { - float x = 0; - - if (ctFontRef != nullptr && text.isNotEmpty()) - { - CFStringRef cfText = text.toCFString(); - CFAttributedStringRef attribString = CFAttributedStringCreate (kCFAllocatorDefault, cfText, attributedStringAtts); - CFRelease (cfText); - - CTLineRef line = CTLineCreateWithAttributedString (attribString); - CFArrayRef runArray = CTLineGetGlyphRuns (line); - - for (CFIndex i = 0; i < CFArrayGetCount (runArray); ++i) - { - CTRunRef run = (CTRunRef) CFArrayGetValueAtIndex (runArray, i); - CFIndex length = CTRunGetGlyphCount (run); - - const CoreTextTypeLayout::Advances advances (run, length); - - for (int j = 0; j < length; ++j) - x += (float) advances.advances[j].width; - } - - CFRelease (line); - CFRelease (attribString); - - x *= unitsToHeightScaleFactor; - } - - return x; - } - - void getGlyphPositions (const String& text, Array & resultGlyphs, Array & xOffsets) override - { - xOffsets.add (0); - - if (ctFontRef != nullptr && text.isNotEmpty()) - { - float x = 0; - - CFStringRef cfText = text.toCFString(); - CFAttributedStringRef attribString = CFAttributedStringCreate (kCFAllocatorDefault, cfText, attributedStringAtts); - CFRelease (cfText); - - CTLineRef line = CTLineCreateWithAttributedString (attribString); - CFArrayRef runArray = CTLineGetGlyphRuns (line); - - for (CFIndex i = 0; i < CFArrayGetCount (runArray); ++i) - { - CTRunRef run = (CTRunRef) CFArrayGetValueAtIndex (runArray, i); - CFIndex length = CTRunGetGlyphCount (run); - - const CoreTextTypeLayout::Advances advances (run, length); - const CoreTextTypeLayout::Glyphs glyphs (run, (size_t) length); - - for (int j = 0; j < length; ++j) - { - x += (float) advances.advances[j].width; - xOffsets.add (x * unitsToHeightScaleFactor); - resultGlyphs.add (glyphs.glyphs[j]); - } - } - - CFRelease (line); - CFRelease (attribString); - } - } - - bool getOutlineForGlyph (int glyphNumber, Path& path) override - { - jassert (path.isEmpty()); // we might need to apply a transform to the path, so this must be empty - - CGPathRef pathRef = CTFontCreatePathForGlyph (ctFontRef, (CGGlyph) glyphNumber, &renderingTransform); - if (pathRef == 0) - return false; - - CGPathApply (pathRef, &path, pathApplier); - CFRelease (pathRef); - - if (! pathTransform.isIdentity()) - path.applyTransform (pathTransform); - - return true; - } - - //============================================================================== - CGFontRef fontRef; - CTFontRef ctFontRef; - - float fontHeightToPointsFactor; - CGAffineTransform renderingTransform; - - bool isMemoryFont; - -private: - CFDictionaryRef attributedStringAtts; - float ascent, unitsToHeightScaleFactor; - AffineTransform pathTransform; - - static void pathApplier (void* info, const CGPathElement* const element) - { - Path& path = *static_cast (info); - const CGPoint* const p = element->points; - - switch (element->type) - { - case kCGPathElementMoveToPoint: path.startNewSubPath ((float) p[0].x, (float) -p[0].y); break; - case kCGPathElementAddLineToPoint: path.lineTo ((float) p[0].x, (float) -p[0].y); break; - case kCGPathElementAddQuadCurveToPoint: path.quadraticTo ((float) p[0].x, (float) -p[0].y, - (float) p[1].x, (float) -p[1].y); break; - case kCGPathElementAddCurveToPoint: path.cubicTo ((float) p[0].x, (float) -p[0].y, - (float) p[1].x, (float) -p[1].y, - (float) p[2].x, (float) -p[2].y); break; - case kCGPathElementCloseSubpath: path.closeSubPath(); break; - default: jassertfalse; break; - } - } - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (OSXTypeface) -}; - -CTFontRef getCTFontFromTypeface (const Font& f) -{ - if (OSXTypeface* tf = dynamic_cast (f.getTypeface())) - return tf->ctFontRef; - - return 0; -} - -StringArray Font::findAllTypefaceNames() -{ - StringArray names; - - #if MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_5 && ! JUCE_IOS - // CTFontManager only exists on OS X 10.6 and later, it does not exist on iOS - CFArrayRef fontFamilyArray = CTFontManagerCopyAvailableFontFamilyNames(); - - for (CFIndex i = 0; i < CFArrayGetCount (fontFamilyArray); ++i) - { - const String family (String::fromCFString ((CFStringRef) CFArrayGetValueAtIndex (fontFamilyArray, i))); - - if (! family.startsWithChar ('.')) // ignore fonts that start with a '.' - names.addIfNotAlreadyThere (family); - } - - CFRelease (fontFamilyArray); - #else - CTFontCollectionRef fontCollectionRef = CTFontCollectionCreateFromAvailableFonts (nullptr); - CFArrayRef fontDescriptorArray = CTFontCollectionCreateMatchingFontDescriptors (fontCollectionRef); - CFRelease (fontCollectionRef); - - for (CFIndex i = 0; i < CFArrayGetCount (fontDescriptorArray); ++i) - { - CTFontDescriptorRef ctFontDescriptorRef = (CTFontDescriptorRef) CFArrayGetValueAtIndex (fontDescriptorArray, i); - CFStringRef cfsFontFamily = (CFStringRef) CTFontDescriptorCopyAttribute (ctFontDescriptorRef, kCTFontFamilyNameAttribute); - - names.addIfNotAlreadyThere (String::fromCFString (cfsFontFamily)); - - CFRelease (cfsFontFamily); - } - - CFRelease (fontDescriptorArray); - #endif - - names.sort (true); - return names; -} - -StringArray Font::findAllTypefaceStyles (const String& family) -{ - if (FontStyleHelpers::isPlaceholderFamilyName (family)) - return findAllTypefaceStyles (FontStyleHelpers::getConcreteFamilyNameFromPlaceholder (family)); - - StringArray results; - - CFStringRef cfsFontFamily = family.toCFString(); - CFStringRef keys[] = { kCTFontFamilyNameAttribute }; - CFTypeRef values[] = { cfsFontFamily }; - - CFDictionaryRef fontDescAttributes = CFDictionaryCreate (nullptr, (const void**) &keys, (const void**) &values, numElementsInArray (keys), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); - CFRelease (cfsFontFamily); - - CTFontDescriptorRef ctFontDescRef = CTFontDescriptorCreateWithAttributes (fontDescAttributes); - CFRelease (fontDescAttributes); - - CFArrayRef fontFamilyArray = CFArrayCreate (kCFAllocatorDefault, (const void**) &ctFontDescRef, 1, &kCFTypeArrayCallBacks); - CFRelease (ctFontDescRef); - - CTFontCollectionRef fontCollectionRef = CTFontCollectionCreateWithFontDescriptors (fontFamilyArray, nullptr); - CFRelease (fontFamilyArray); - - CFArrayRef fontDescriptorArray = CTFontCollectionCreateMatchingFontDescriptors (fontCollectionRef); - CFRelease (fontCollectionRef); - - if (fontDescriptorArray != nullptr) - { - for (CFIndex i = 0; i < CFArrayGetCount (fontDescriptorArray); ++i) - { - CTFontDescriptorRef ctFontDescriptorRef = (CTFontDescriptorRef) CFArrayGetValueAtIndex (fontDescriptorArray, i); - CFStringRef cfsFontStyle = (CFStringRef) CTFontDescriptorCopyAttribute (ctFontDescriptorRef, kCTFontStyleNameAttribute); - results.add (String::fromCFString (cfsFontStyle)); - CFRelease (cfsFontStyle); - } - - CFRelease (fontDescriptorArray); - } - - return results; -} - -#else - -//============================================================================== -// The stuff that follows is a mash-up that supports pre-OSX 10.5 APIs. -// (Hopefully all of this can be ditched at some point in the future). - -//============================================================================== -#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5 - #define SUPPORT_10_4_FONTS 1 - #define NEW_CGFONT_FUNCTIONS_UNAVAILABLE (CGFontCreateWithFontName == 0) - - #if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_5 - #define SUPPORT_ONLY_10_4_FONTS 1 - #endif - - } // (juce namespace) - - @interface NSFont (PrivateHack) - - (NSGlyph) _defaultGlyphForChar: (unichar) theChar; - @end - - namespace juce - { -#endif - -//============================================================================== -class OSXTypeface : public Typeface -{ -public: - OSXTypeface (const Font& font) - : Typeface (font.getTypefaceName(), font.getTypefaceStyle()) - { - JUCE_AUTORELEASEPOOL - { - renderingTransform = CGAffineTransformIdentity; - - NSDictionary* nsDict = [NSDictionary dictionaryWithObjectsAndKeys: - juceStringToNS (name), NSFontFamilyAttribute, - juceStringToNS (style), NSFontFaceAttribute, nil]; - - NSFontDescriptor* nsFontDesc = [NSFontDescriptor fontDescriptorWithFontAttributes: nsDict]; - nsFont = [NSFont fontWithDescriptor: nsFontDesc size: referenceFontSize]; - - [nsFont retain]; - - #if SUPPORT_ONLY_10_4_FONTS - initWithATSFont(); - #else - #if SUPPORT_10_4_FONTS - if (NEW_CGFONT_FUNCTIONS_UNAVAILABLE) - { - initWithATSFont(); - } - else - #endif - { - fontRef = CGFontCreateWithFontName ((CFStringRef) [nsFont fontName]); - - const float absAscent = std::abs ((float) CGFontGetAscent (fontRef)); - const float totalHeight = absAscent + std::abs ((float) CGFontGetDescent (fontRef)); - - ascent = absAscent / totalHeight; - unitsToHeightScaleFactor = 1.0f / totalHeight; - - const float nsFontAscent = std::abs ([nsFont ascender]); - const float nsFontDescent = std::abs ([nsFont descender]); - - fontHeightToPointsFactor = referenceFontSize / (nsFontAscent + nsFontDescent); - } - #endif - - pathTransform = AffineTransform::identity.scale (unitsToHeightScaleFactor); - } - } - - ~OSXTypeface() - { - #if ! JUCE_IOS - [nsFont release]; - #endif - - if (fontRef != 0) - CGFontRelease (fontRef); - } - - #if SUPPORT_10_4_FONTS - void initWithATSFont() - { - ATSFontRef atsFont = ATSFontFindFromName ((CFStringRef) [nsFont fontName], kATSOptionFlagsDefault); - - if (atsFont == 0) - atsFont = ATSFontFindFromPostScriptName ((CFStringRef) [nsFont fontName], kATSOptionFlagsDefault); - - fontRef = CGFontCreateWithPlatformFont (&atsFont); - - const float absAscent = std::abs ([nsFont ascender]); - const float absDescent = std::abs ([nsFont descender]); - const float totalHeight = absAscent + absDescent; - - unitsToHeightScaleFactor = 1.0f / totalHeight; - fontHeightToPointsFactor = referenceFontSize / totalHeight; - ascent = absAscent / totalHeight; - } - #endif - - - float getAscent() const override { return ascent; } - float getDescent() const override { return 1.0f - ascent; } - float getHeightToPointsFactor() const override { return fontHeightToPointsFactor; } - - float getStringWidth (const String& text) override - { - if (fontRef == 0 || text.isEmpty()) - return 0; - - const int length = text.length(); - HeapBlock glyphs; - createGlyphsForString (text.getCharPointer(), length, glyphs); - - float x = 0; - -#if SUPPORT_ONLY_10_4_FONTS - HeapBlock advances (length); - [nsFont getAdvancements: advances forGlyphs: reinterpret_cast (glyphs.getData()) count: length]; - - for (int i = 0; i < length; ++i) - x += advances[i].width; -#else - #if SUPPORT_10_4_FONTS - if (NEW_CGFONT_FUNCTIONS_UNAVAILABLE) - { - HeapBlock advances (length); - [nsFont getAdvancements: advances forGlyphs: reinterpret_cast (glyphs.getData()) count: length]; - - for (int i = 0; i < length; ++i) - x += advances[i].width; - } - else - #endif - { - HeapBlock advances (length); - - if (CGFontGetGlyphAdvances (fontRef, glyphs, length, advances)) - for (int i = 0; i < length; ++i) - x += advances[i]; - } -#endif - - return x * unitsToHeightScaleFactor; - } - - void getGlyphPositions (const String& text, Array& resultGlyphs, Array& xOffsets) override - { - xOffsets.add (0); - - if (fontRef == 0 || text.isEmpty()) - return; - - const int length = text.length(); - HeapBlock glyphs; - createGlyphsForString (text.getCharPointer(), length, glyphs); - -#if SUPPORT_ONLY_10_4_FONTS - HeapBlock advances (length); - [nsFont getAdvancements: advances forGlyphs: reinterpret_cast (glyphs.getData()) count: length]; - - int x = 0; - for (int i = 0; i < length; ++i) - { - x += advances[i].width; - xOffsets.add (x * unitsToHeightScaleFactor); - resultGlyphs.add (reinterpret_cast (glyphs.getData())[i]); - } - -#else - #if SUPPORT_10_4_FONTS - if (NEW_CGFONT_FUNCTIONS_UNAVAILABLE) - { - HeapBlock advances (length); - NSGlyph* const nsGlyphs = reinterpret_cast (glyphs.getData()); - [nsFont getAdvancements: advances forGlyphs: nsGlyphs count: length]; - - float x = 0; - for (int i = 0; i < length; ++i) - { - x += advances[i].width; - xOffsets.add (x * unitsToHeightScaleFactor); - resultGlyphs.add (nsGlyphs[i]); - } - } - else - #endif - { - HeapBlock advances (length); - - if (CGFontGetGlyphAdvances (fontRef, glyphs, length, advances)) - { - int x = 0; - for (int i = 0; i < length; ++i) - { - x += advances [i]; - xOffsets.add (x * unitsToHeightScaleFactor); - resultGlyphs.add (glyphs[i]); - } - } - } -#endif - } - - bool getOutlineForGlyph (int glyphNumber, Path& path) override - { - #if JUCE_IOS - return false; - #else - if (nsFont == nil) - return false; - - // we might need to apply a transform to the path, so it mustn't have anything else in it - jassert (path.isEmpty()); - - JUCE_AUTORELEASEPOOL - { - NSBezierPath* bez = [NSBezierPath bezierPath]; - [bez moveToPoint: NSMakePoint (0, 0)]; - [bez appendBezierPathWithGlyph: (NSGlyph) glyphNumber - inFont: nsFont]; - - for (int i = 0; i < [bez elementCount]; ++i) - { - NSPoint p[3]; - switch ([bez elementAtIndex: i associatedPoints: p]) - { - case NSMoveToBezierPathElement: path.startNewSubPath ((float) p[0].x, (float) -p[0].y); break; - case NSLineToBezierPathElement: path.lineTo ((float) p[0].x, (float) -p[0].y); break; - case NSCurveToBezierPathElement: path.cubicTo ((float) p[0].x, (float) -p[0].y, - (float) p[1].x, (float) -p[1].y, - (float) p[2].x, (float) -p[2].y); break; - case NSClosePathBezierPathElement: path.closeSubPath(); break; - default: jassertfalse; break; - } - } - - path.applyTransform (pathTransform); - } - return true; - #endif - } - - //============================================================================== - CGFontRef fontRef; - float fontHeightToPointsFactor; - CGAffineTransform renderingTransform; - -private: - float ascent, unitsToHeightScaleFactor; - - #if ! JUCE_IOS - NSFont* nsFont; - AffineTransform pathTransform; - #endif - - void createGlyphsForString (String::CharPointerType text, const int length, HeapBlock & glyphs) - { - #if SUPPORT_10_4_FONTS - #if ! SUPPORT_ONLY_10_4_FONTS - if (NEW_CGFONT_FUNCTIONS_UNAVAILABLE) - #endif - { - glyphs.malloc (sizeof (NSGlyph) * length, 1); - NSGlyph* const nsGlyphs = reinterpret_cast (glyphs.getData()); - - for (int i = 0; i < length; ++i) - nsGlyphs[i] = (NSGlyph) [nsFont _defaultGlyphForChar: text.getAndAdvance()]; - - return; - } - #endif - - #if ! SUPPORT_ONLY_10_4_FONTS - if (charToGlyphMapper == nullptr) - charToGlyphMapper = new CharToGlyphMapper (fontRef); - - glyphs.malloc (length); - - for (int i = 0; i < length; ++i) - glyphs[i] = (CGGlyph) charToGlyphMapper->getGlyphForCharacter (text.getAndAdvance()); - #endif - } - - #if ! SUPPORT_ONLY_10_4_FONTS - // Reads a CGFontRef's character map table to convert unicode into glyph numbers - class CharToGlyphMapper - { - public: - CharToGlyphMapper (CGFontRef cgFontRef) - : segCount (0), endCode (0), startCode (0), idDelta (0), - idRangeOffset (0), glyphIndexes (0) - { - CFDataRef cmapTable = CGFontCopyTableForTag (cgFontRef, 'cmap'); - - if (cmapTable != 0) - { - const int numSubtables = getValue16 (cmapTable, 2); - - for (int i = 0; i < numSubtables; ++i) - { - if (getValue16 (cmapTable, i * 8 + 4) == 0) // check for platform ID of 0 - { - const int offset = getValue32 (cmapTable, i * 8 + 8); - - if (getValue16 (cmapTable, offset) == 4) // check that it's format 4.. - { - const int length = getValue16 (cmapTable, offset + 2); - const int segCountX2 = getValue16 (cmapTable, offset + 6); - segCount = segCountX2 / 2; - const int endCodeOffset = offset + 14; - const int startCodeOffset = endCodeOffset + 2 + segCountX2; - const int idDeltaOffset = startCodeOffset + segCountX2; - const int idRangeOffsetOffset = idDeltaOffset + segCountX2; - const int glyphIndexesOffset = idRangeOffsetOffset + segCountX2; - - endCode = CFDataCreate (kCFAllocatorDefault, CFDataGetBytePtr (cmapTable) + endCodeOffset, segCountX2); - startCode = CFDataCreate (kCFAllocatorDefault, CFDataGetBytePtr (cmapTable) + startCodeOffset, segCountX2); - idDelta = CFDataCreate (kCFAllocatorDefault, CFDataGetBytePtr (cmapTable) + idDeltaOffset, segCountX2); - idRangeOffset = CFDataCreate (kCFAllocatorDefault, CFDataGetBytePtr (cmapTable) + idRangeOffsetOffset, segCountX2); - glyphIndexes = CFDataCreate (kCFAllocatorDefault, CFDataGetBytePtr (cmapTable) + glyphIndexesOffset, offset + length - glyphIndexesOffset); - } - - break; - } - } - - CFRelease (cmapTable); - } - } - - ~CharToGlyphMapper() - { - if (endCode != 0) - { - CFRelease (endCode); - CFRelease (startCode); - CFRelease (idDelta); - CFRelease (idRangeOffset); - CFRelease (glyphIndexes); - } - } - - int getGlyphForCharacter (const juce_wchar c) const - { - for (int i = 0; i < segCount; ++i) - { - if (getValue16 (endCode, i * 2) >= c) - { - const int start = getValue16 (startCode, i * 2); - if (start > c) - break; - - const int delta = getValue16 (idDelta, i * 2); - const int rangeOffset = getValue16 (idRangeOffset, i * 2); - - if (rangeOffset == 0) - return delta + c; - - return getValue16 (glyphIndexes, 2 * ((rangeOffset / 2) + (c - start) - (segCount - i))); - } - } - - // If we failed to find it "properly", this dodgy fall-back seems to do the trick for most fonts! - return jmax (-1, (int) c - 29); - } - - private: - int segCount; - CFDataRef endCode, startCode, idDelta, idRangeOffset, glyphIndexes; - - static uint16 getValue16 (CFDataRef data, const int index) - { - return CFSwapInt16BigToHost (*(UInt16*) (CFDataGetBytePtr (data) + index)); - } - - static uint32 getValue32 (CFDataRef data, const int index) - { - return CFSwapInt32BigToHost (*(UInt32*) (CFDataGetBytePtr (data) + index)); - } - }; - - ScopedPointer charToGlyphMapper; - #endif - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (OSXTypeface) -}; - -StringArray Font::findAllTypefaceNames() -{ - StringArray names; - - JUCE_AUTORELEASEPOOL - { - #if JUCE_IOS - for (NSString* name in [UIFont familyNames]) - #else - for (NSString* name in [[NSFontManager sharedFontManager] availableFontFamilies]) - #endif - names.add (nsStringToJuce (name)); - - names.sort (true); - } - - return names; -} - -StringArray Font::findAllTypefaceStyles (const String& family) -{ - if (FontStyleHelpers::isPlaceholderFamilyName (family)) - return findAllTypefaceStyles (FontStyleHelpers::getConcreteFamilyNameFromPlaceholder (family)); - - StringArray results; - - JUCE_AUTORELEASEPOOL - { - for (NSArray* style in [[NSFontManager sharedFontManager] availableMembersOfFontFamily: juceStringToNS (family)]) - results.add (nsStringToJuce ((NSString*) [style objectAtIndex: 1])); - } - - return results; -} - -#endif - -//============================================================================== -Typeface::Ptr Typeface::createSystemTypefaceFor (const Font& font) -{ - return new OSXTypeface (font); -} - -Typeface::Ptr Typeface::createSystemTypefaceFor (const void* data, size_t dataSize) -{ - #if JUCE_CORETEXT_AVAILABLE - return new OSXTypeface (data, dataSize); - #else - jassertfalse; // You need CoreText enabled to use this feature! - return nullptr; - #endif -} - -void Typeface::scanFolderForFonts (const File&) -{ - jassertfalse; // not implemented on this platform -} - -struct DefaultFontNames -{ - DefaultFontNames() - #if JUCE_IOS - : defaultSans ("Helvetica"), - defaultSerif ("Times New Roman"), - defaultFixed ("Courier New"), - #else - : defaultSans ("Lucida Grande"), - defaultSerif ("Times New Roman"), - defaultFixed ("Menlo"), - #endif - defaultFallback ("Arial Unicode MS") - { - } - - String defaultSans, defaultSerif, defaultFixed, defaultFallback; -}; - -Typeface::Ptr Font::getDefaultTypefaceForFont (const Font& font) -{ - static DefaultFontNames defaultNames; - - Font newFont (font); - const String& faceName = font.getTypefaceName(); - - if (faceName == getDefaultSansSerifFontName()) newFont.setTypefaceName (defaultNames.defaultSans); - else if (faceName == getDefaultSerifFontName()) newFont.setTypefaceName (defaultNames.defaultSerif); - else if (faceName == getDefaultMonospacedFontName()) newFont.setTypefaceName (defaultNames.defaultFixed); - - if (font.getTypefaceStyle() == getDefaultStyle()) - newFont.setTypefaceStyle ("Regular"); - - return Typeface::createSystemTypefaceFor (newFont); -} - -#if JUCE_CORETEXT_AVAILABLE -static bool canAllTypefacesBeUsedInLayout (const AttributedString& text) -{ - const int numCharacterAttributes = text.getNumAttributes(); - - for (int i = 0; i < numCharacterAttributes; ++i) - { - if (const Font* const f = text.getAttribute (i)->getFont()) - { - if (OSXTypeface* tf = dynamic_cast (f->getTypeface())) - { - if (tf->isMemoryFont) - return false; - } - else if (dynamic_cast (f->getTypeface()) != nullptr) - { - return false; - } - } - } - - return true; -} -#endif - -bool TextLayout::createNativeLayout (const AttributedString& text) -{ - #if JUCE_CORETEXT_AVAILABLE - // Seems to be an unfathomable bug in CoreText which prevents the layout working with - // typefaces that were loaded from memory, so have to fallback if we hit any of those.. - if (canAllTypefacesBeUsedInLayout (text)) - { - CoreTextTypeLayout::createLayout (*this, text); - return true; - } - #endif - - (void) text; - return false; -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/native/juce_win32_Direct2DGraphicsContext.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/native/juce_win32_Direct2DGraphicsContext.cpp deleted file mode 100644 index e4356b724e..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/native/juce_win32_Direct2DGraphicsContext.cpp +++ /dev/null @@ -1,838 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -class Direct2DLowLevelGraphicsContext : public LowLevelGraphicsContext -{ -public: - Direct2DLowLevelGraphicsContext (HWND hwnd_) - : hwnd (hwnd_), - currentState (nullptr) - { - RECT windowRect; - GetClientRect (hwnd, &windowRect); - D2D1_SIZE_U size = { windowRect.right - windowRect.left, windowRect.bottom - windowRect.top }; - bounds.setSize (size.width, size.height); - - D2D1_RENDER_TARGET_PROPERTIES props = D2D1::RenderTargetProperties(); - D2D1_HWND_RENDER_TARGET_PROPERTIES propsHwnd = D2D1::HwndRenderTargetProperties (hwnd, size); - - if (factories->d2dFactory != nullptr) - { - HRESULT hr = factories->d2dFactory->CreateHwndRenderTarget (props, propsHwnd, renderingTarget.resetAndGetPointerAddress()); - jassert (SUCCEEDED (hr)); (void) hr; - hr = renderingTarget->CreateSolidColorBrush (D2D1::ColorF::ColorF (0.0f, 0.0f, 0.0f, 1.0f), colourBrush.resetAndGetPointerAddress()); - } - } - - ~Direct2DLowLevelGraphicsContext() - { - states.clear(); - } - - void resized() - { - RECT windowRect; - GetClientRect (hwnd, &windowRect); - D2D1_SIZE_U size = { windowRect.right - windowRect.left, windowRect.bottom - windowRect.top }; - - renderingTarget->Resize (size); - bounds.setSize (size.width, size.height); - } - - void clear() - { - renderingTarget->Clear (D2D1::ColorF (D2D1::ColorF::White, 0.0f)); // xxx why white and not black? - } - - void start() - { - renderingTarget->BeginDraw(); - saveState(); - } - - void end() - { - states.clear(); - currentState = 0; - renderingTarget->EndDraw(); - renderingTarget->CheckWindowState(); - } - - bool isVectorDevice() const { return false; } - - void setOrigin (Point o) - { - addTransform (AffineTransform::translation ((float) o.x, (float) o.y)); - } - - void addTransform (const AffineTransform& transform) - { - currentState->transform = transform.followedBy (currentState->transform); - } - - float getPhysicalPixelScaleFactor() - { - return currentState->transform.getScaleFactor(); - } - - bool clipToRectangle (const Rectangle& r) - { - currentState->clipToRectangle (r); - return ! isClipEmpty(); - } - - bool clipToRectangleList (const RectangleList& clipRegion) - { - currentState->clipToRectList (rectListToPathGeometry (clipRegion)); - return ! isClipEmpty(); - } - - void excludeClipRectangle (const Rectangle&) - { - //xxx - } - - void clipToPath (const Path& path, const AffineTransform& transform) - { - currentState->clipToPath (pathToPathGeometry (path, transform)); - } - - void clipToImageAlpha (const Image& sourceImage, const AffineTransform& transform) - { - currentState->clipToImage (sourceImage, transform); - } - - bool clipRegionIntersects (const Rectangle& r) - { - return currentState->clipRect.intersects (r.toFloat().transformed (currentState->transform).getSmallestIntegerContainer()); - } - - Rectangle getClipBounds() const - { - // xxx could this take into account complex clip regions? - return currentState->clipRect.toFloat().transformed (currentState->transform.inverted()).getSmallestIntegerContainer(); - } - - bool isClipEmpty() const - { - return currentState->clipRect.isEmpty(); - } - - void saveState() - { - states.add (new SavedState (*this)); - currentState = states.getLast(); - } - - void restoreState() - { - jassert (states.size() > 1) //you should never pop the last state! - states.removeLast (1); - currentState = states.getLast(); - } - - void beginTransparencyLayer (float /*opacity*/) - { - jassertfalse; //xxx todo - } - - void endTransparencyLayer() - { - jassertfalse; //xxx todo - } - - void setFill (const FillType& fillType) - { - currentState->setFill (fillType); - } - - void setOpacity (float newOpacity) - { - currentState->setOpacity (newOpacity); - } - - void setInterpolationQuality (Graphics::ResamplingQuality /*quality*/) - { - } - - void fillRect (const Rectangle& r, bool /*replaceExistingContents*/) - { - fillRect (r.toFloat()); - } - - void fillRect (const Rectangle& r) - { - renderingTarget->SetTransform (transformToMatrix (currentState->transform)); - currentState->createBrush(); - renderingTarget->FillRectangle (rectangleToRectF (r), currentState->currentBrush); - renderingTarget->SetTransform (D2D1::IdentityMatrix()); - } - - void fillRectList (const RectangleList& list) - { - for (const Rectangle* r = list.begin(), * const e = list.end(); r != e; ++r) - fillRect (*r); - } - - void fillPath (const Path& p, const AffineTransform& transform) - { - currentState->createBrush(); - ComSmartPtr geometry (pathToPathGeometry (p, transform.followedBy (currentState->transform))); - - if (renderingTarget != nullptr) - renderingTarget->FillGeometry (geometry, currentState->currentBrush); - } - - void drawImage (const Image& image, const AffineTransform& transform) - { - renderingTarget->SetTransform (transformToMatrix (transform.followedBy (currentState->transform))); - - D2D1_SIZE_U size; - size.width = image.getWidth(); - size.height = image.getHeight(); - - D2D1_BITMAP_PROPERTIES bp = D2D1::BitmapProperties(); - - Image img (image.convertedToFormat (Image::ARGB)); - Image::BitmapData bd (img, Image::BitmapData::readOnly); - bp.pixelFormat = renderingTarget->GetPixelFormat(); - bp.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED; - - { - ComSmartPtr tempBitmap; - renderingTarget->CreateBitmap (size, bd.data, bd.lineStride, bp, tempBitmap.resetAndGetPointerAddress()); - if (tempBitmap != nullptr) - renderingTarget->DrawBitmap (tempBitmap); - } - - renderingTarget->SetTransform (D2D1::IdentityMatrix()); - } - - void drawLine (const Line & line) - { - // xxx doesn't seem to be correctly aligned, may need nudging by 0.5 to match the software renderer's behaviour - renderingTarget->SetTransform (transformToMatrix (currentState->transform)); - currentState->createBrush(); - - renderingTarget->DrawLine (D2D1::Point2F (line.getStartX(), line.getStartY()), - D2D1::Point2F (line.getEndX(), line.getEndY()), - currentState->currentBrush); - renderingTarget->SetTransform (D2D1::IdentityMatrix()); - } - - void setFont (const Font& newFont) - { - currentState->setFont (newFont); - } - - const Font& getFont() - { - return currentState->font; - } - - void drawGlyph (int glyphNumber, const AffineTransform& transform) - { - currentState->createBrush(); - currentState->createFont(); - - float hScale = currentState->font.getHorizontalScale(); - - renderingTarget->SetTransform (transformToMatrix (AffineTransform::scale (hScale, 1.0f) - .followedBy (transform) - .followedBy (currentState->transform))); - - const UINT16 glyphIndices = (UINT16) glyphNumber; - const FLOAT glyphAdvances = 0; - DWRITE_GLYPH_OFFSET offset; - offset.advanceOffset = 0; - offset.ascenderOffset = 0; - - DWRITE_GLYPH_RUN glyphRun; - glyphRun.fontFace = currentState->currentFontFace; - glyphRun.fontEmSize = (FLOAT) (currentState->font.getHeight() * currentState->fontHeightToEmSizeFactor); - glyphRun.glyphCount = 1; - glyphRun.glyphIndices = &glyphIndices; - glyphRun.glyphAdvances = &glyphAdvances; - glyphRun.glyphOffsets = &offset; - glyphRun.isSideways = FALSE; - glyphRun.bidiLevel = 0; - - renderingTarget->DrawGlyphRun (D2D1::Point2F (0, 0), &glyphRun, currentState->currentBrush); - renderingTarget->SetTransform (D2D1::IdentityMatrix()); - } - - bool drawTextLayout (const AttributedString& text, const Rectangle& area) - { - renderingTarget->SetTransform (transformToMatrix (currentState->transform)); - - DirectWriteTypeLayout::drawToD2DContext (text, area, renderingTarget, factories->directWriteFactory, - factories->d2dFactory, factories->systemFonts); - - renderingTarget->SetTransform (D2D1::IdentityMatrix()); - return true; - } - - //============================================================================== - class SavedState - { - public: - SavedState (Direct2DLowLevelGraphicsContext& owner_) - : owner (owner_), currentBrush (0), - fontHeightToEmSizeFactor (1.0f), currentFontFace (0), - clipsRect (false), shouldClipRect (false), - clipsRectList (false), shouldClipRectList (false), - clipsComplex (false), shouldClipComplex (false), - clipsBitmap (false), shouldClipBitmap (false) - { - if (owner.currentState != nullptr) - { - // xxx seems like a very slow way to create one of these, and this is a performance - // bottleneck.. Can the same internal objects be shared by multiple state objects, maybe using copy-on-write? - setFill (owner.currentState->fillType); - currentBrush = owner.currentState->currentBrush; - clipRect = owner.currentState->clipRect; - transform = owner.currentState->transform; - - font = owner.currentState->font; - currentFontFace = owner.currentState->currentFontFace; - } - else - { - const D2D1_SIZE_U size (owner.renderingTarget->GetPixelSize()); - clipRect.setSize (size.width, size.height); - setFill (FillType (Colours::black)); - } - } - - ~SavedState() - { - clearClip(); - clearFont(); - clearFill(); - clearPathClip(); - clearImageClip(); - complexClipLayer = 0; - bitmapMaskLayer = 0; - } - - void clearClip() - { - popClips(); - shouldClipRect = false; - } - - void clipToRectangle (const Rectangle& r) - { - clearClip(); - clipRect = r.toFloat().transformed (transform).getSmallestIntegerContainer(); - shouldClipRect = true; - pushClips(); - } - - void clearPathClip() - { - popClips(); - - if (shouldClipComplex) - { - complexClipGeometry = 0; - shouldClipComplex = false; - } - } - - void clipToPath (ID2D1Geometry* geometry) - { - clearPathClip(); - - if (complexClipLayer == 0) - owner.renderingTarget->CreateLayer (complexClipLayer.resetAndGetPointerAddress()); - - complexClipGeometry = geometry; - shouldClipComplex = true; - pushClips(); - } - - void clearRectListClip() - { - popClips(); - - if (shouldClipRectList) - { - rectListGeometry = 0; - shouldClipRectList = false; - } - } - - void clipToRectList (ID2D1Geometry* geometry) - { - clearRectListClip(); - - if (rectListLayer == 0) - owner.renderingTarget->CreateLayer (rectListLayer.resetAndGetPointerAddress()); - - rectListGeometry = geometry; - shouldClipRectList = true; - pushClips(); - } - - void clearImageClip() - { - popClips(); - - if (shouldClipBitmap) - { - maskBitmap = 0; - bitmapMaskBrush = 0; - shouldClipBitmap = false; - } - } - - void clipToImage (const Image& image, const AffineTransform& transform) - { - clearImageClip(); - - if (bitmapMaskLayer == 0) - owner.renderingTarget->CreateLayer (bitmapMaskLayer.resetAndGetPointerAddress()); - - D2D1_BRUSH_PROPERTIES brushProps; - brushProps.opacity = 1; - brushProps.transform = transformToMatrix (transform); - - D2D1_BITMAP_BRUSH_PROPERTIES bmProps = D2D1::BitmapBrushProperties (D2D1_EXTEND_MODE_WRAP, D2D1_EXTEND_MODE_WRAP); - - D2D1_SIZE_U size; - size.width = image.getWidth(); - size.height = image.getHeight(); - - D2D1_BITMAP_PROPERTIES bp = D2D1::BitmapProperties(); - - maskImage = image.convertedToFormat (Image::ARGB); - Image::BitmapData bd (this->image, Image::BitmapData::readOnly); // xxx should be maskImage? - bp.pixelFormat = owner.renderingTarget->GetPixelFormat(); - bp.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED; - - HRESULT hr = owner.renderingTarget->CreateBitmap (size, bd.data, bd.lineStride, bp, maskBitmap.resetAndGetPointerAddress()); - hr = owner.renderingTarget->CreateBitmapBrush (maskBitmap, bmProps, brushProps, bitmapMaskBrush.resetAndGetPointerAddress()); - - imageMaskLayerParams = D2D1::LayerParameters(); - imageMaskLayerParams.opacityBrush = bitmapMaskBrush; - - shouldClipBitmap = true; - pushClips(); - } - - void popClips() - { - if (clipsBitmap) - { - owner.renderingTarget->PopLayer(); - clipsBitmap = false; - } - - if (clipsComplex) - { - owner.renderingTarget->PopLayer(); - clipsComplex = false; - } - - if (clipsRectList) - { - owner.renderingTarget->PopLayer(); - clipsRectList = false; - } - - if (clipsRect) - { - owner.renderingTarget->PopAxisAlignedClip(); - clipsRect = false; - } - } - - void pushClips() - { - if (shouldClipRect && ! clipsRect) - { - owner.renderingTarget->PushAxisAlignedClip (rectangleToRectF (clipRect), D2D1_ANTIALIAS_MODE_PER_PRIMITIVE); - clipsRect = true; - } - - if (shouldClipRectList && ! clipsRectList) - { - D2D1_LAYER_PARAMETERS layerParams = D2D1::LayerParameters(); - rectListGeometry->GetBounds (D2D1::IdentityMatrix(), &layerParams.contentBounds); - layerParams.geometricMask = rectListGeometry; - owner.renderingTarget->PushLayer (layerParams, rectListLayer); - clipsRectList = true; - } - - if (shouldClipComplex && ! clipsComplex) - { - D2D1_LAYER_PARAMETERS layerParams = D2D1::LayerParameters(); - complexClipGeometry->GetBounds (D2D1::IdentityMatrix(), &layerParams.contentBounds); - layerParams.geometricMask = complexClipGeometry; - owner.renderingTarget->PushLayer (layerParams, complexClipLayer); - clipsComplex = true; - } - - if (shouldClipBitmap && ! clipsBitmap) - { - owner.renderingTarget->PushLayer (imageMaskLayerParams, bitmapMaskLayer); - clipsBitmap = true; - } - } - - void setFill (const FillType& newFillType) - { - if (fillType != newFillType) - { - fillType = newFillType; - clearFill(); - } - } - - void clearFont() - { - currentFontFace = localFontFace = 0; - } - - void setFont (const Font& newFont) - { - if (font != newFont) - { - font = newFont; - clearFont(); - } - } - - void createFont() - { - if (currentFontFace == nullptr) - { - WindowsDirectWriteTypeface* typeface = dynamic_cast (font.getTypeface()); - currentFontFace = typeface->getIDWriteFontFace(); - fontHeightToEmSizeFactor = typeface->unitsToHeightScaleFactor(); - } - } - - void setOpacity (float newOpacity) - { - fillType.setOpacity (newOpacity); - - if (currentBrush != nullptr) - currentBrush->SetOpacity (newOpacity); - } - - void clearFill() - { - gradientStops = 0; - linearGradient = 0; - radialGradient = 0; - bitmap = 0; - bitmapBrush = 0; - currentBrush = 0; - } - - void createBrush() - { - if (currentBrush == 0) - { - if (fillType.isColour()) - { - D2D1_COLOR_F colour = colourToD2D (fillType.colour); - owner.colourBrush->SetColor (colour); - currentBrush = owner.colourBrush; - } - else if (fillType.isTiledImage()) - { - D2D1_BRUSH_PROPERTIES brushProps; - brushProps.opacity = fillType.getOpacity(); - brushProps.transform = transformToMatrix (fillType.transform); - - D2D1_BITMAP_BRUSH_PROPERTIES bmProps = D2D1::BitmapBrushProperties (D2D1_EXTEND_MODE_WRAP,D2D1_EXTEND_MODE_WRAP); - - image = fillType.image; - - D2D1_SIZE_U size; - size.width = image.getWidth(); - size.height = image.getHeight(); - - D2D1_BITMAP_PROPERTIES bp = D2D1::BitmapProperties(); - - this->image = image.convertedToFormat (Image::ARGB); - Image::BitmapData bd (this->image, Image::BitmapData::readOnly); - bp.pixelFormat = owner.renderingTarget->GetPixelFormat(); - bp.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED; - - HRESULT hr = owner.renderingTarget->CreateBitmap (size, bd.data, bd.lineStride, bp, bitmap.resetAndGetPointerAddress()); - hr = owner.renderingTarget->CreateBitmapBrush (bitmap, bmProps, brushProps, bitmapBrush.resetAndGetPointerAddress()); - - currentBrush = bitmapBrush; - } - else if (fillType.isGradient()) - { - gradientStops = 0; - - D2D1_BRUSH_PROPERTIES brushProps; - brushProps.opacity = fillType.getOpacity(); - brushProps.transform = transformToMatrix (fillType.transform.followedBy (transform)); - - const int numColors = fillType.gradient->getNumColours(); - - HeapBlock stops (numColors); - - for (int i = fillType.gradient->getNumColours(); --i >= 0;) - { - stops[i].color = colourToD2D (fillType.gradient->getColour(i)); - stops[i].position = (FLOAT) fillType.gradient->getColourPosition(i); - } - - owner.renderingTarget->CreateGradientStopCollection (stops.getData(), numColors, gradientStops.resetAndGetPointerAddress()); - - if (fillType.gradient->isRadial) - { - radialGradient = 0; - - const Point p1 = fillType.gradient->point1; - const Point p2 = fillType.gradient->point2; - float r = p1.getDistanceFrom (p2); - - D2D1_RADIAL_GRADIENT_BRUSH_PROPERTIES props = - D2D1::RadialGradientBrushProperties (D2D1::Point2F (p1.x, p1.y), - D2D1::Point2F (0, 0), - r, r); - - owner.renderingTarget->CreateRadialGradientBrush (props, brushProps, gradientStops, radialGradient.resetAndGetPointerAddress()); - currentBrush = radialGradient; - } - else - { - linearGradient = 0; - - const Point p1 = fillType.gradient->point1; - const Point p2 = fillType.gradient->point2; - - D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES props = - D2D1::LinearGradientBrushProperties (D2D1::Point2F (p1.x, p1.y), - D2D1::Point2F (p2.x, p2.y)); - - owner.renderingTarget->CreateLinearGradientBrush (props, brushProps, gradientStops, linearGradient.resetAndGetPointerAddress()); - - currentBrush = linearGradient; - } - } - } - } - - //============================================================================== - //xxx most of these members should probably be private... - - Direct2DLowLevelGraphicsContext& owner; - - AffineTransform transform; - - Font font; - float fontHeightToEmSizeFactor; - IDWriteFontFace* currentFontFace; - ComSmartPtr localFontFace; - - FillType fillType; - - Image image; - ComSmartPtr bitmap; // xxx needs a better name - what is this for?? - - Rectangle clipRect; - bool clipsRect, shouldClipRect; - - ComSmartPtr complexClipGeometry; - D2D1_LAYER_PARAMETERS complexClipLayerParams; - ComSmartPtr complexClipLayer; - bool clipsComplex, shouldClipComplex; - - ComSmartPtr rectListGeometry; - D2D1_LAYER_PARAMETERS rectListLayerParams; - ComSmartPtr rectListLayer; - bool clipsRectList, shouldClipRectList; - - Image maskImage; - D2D1_LAYER_PARAMETERS imageMaskLayerParams; - ComSmartPtr bitmapMaskLayer; - ComSmartPtr maskBitmap; - ComSmartPtr bitmapMaskBrush; - bool clipsBitmap, shouldClipBitmap; - - ID2D1Brush* currentBrush; - ComSmartPtr bitmapBrush; - ComSmartPtr linearGradient; - ComSmartPtr radialGradient; - ComSmartPtr gradientStops; - - private: - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (SavedState) - }; - - //============================================================================== -private: - SharedResourcePointer factories; - HWND hwnd; - ComSmartPtr renderingTarget; - ComSmartPtr colourBrush; - Rectangle bounds; - - SavedState* currentState; - OwnedArray states; - - //============================================================================== - template - static D2D1_RECT_F rectangleToRectF (const Rectangle& r) - { - return D2D1::RectF ((float) r.getX(), (float) r.getY(), (float) r.getRight(), (float) r.getBottom()); - } - - static D2D1_COLOR_F colourToD2D (Colour c) - { - return D2D1::ColorF::ColorF (c.getFloatRed(), c.getFloatGreen(), c.getFloatBlue(), c.getFloatAlpha()); - } - - static D2D1_POINT_2F pointTransformed (int x, int y, const AffineTransform& transform) - { - transform.transformPoint (x, y); - return D2D1::Point2F ((FLOAT) x, (FLOAT) y); - } - - static void rectToGeometrySink (const Rectangle& rect, ID2D1GeometrySink* sink) - { - sink->BeginFigure (pointTransformed (rect.getX(), rect.getY()), D2D1_FIGURE_BEGIN_FILLED); - sink->AddLine (pointTransformed (rect.getRight(), rect.getY())); - sink->AddLine (pointTransformed (rect.getRight(), rect.getBottom())); - sink->AddLine (pointTransformed (rect.getX(), rect.getBottom())); - sink->EndFigure (D2D1_FIGURE_END_CLOSED); - } - - static ID2D1PathGeometry* rectListToPathGeometry (const RectangleList& clipRegion) - { - ID2D1PathGeometry* p = nullptr; - factories->d2dFactory->CreatePathGeometry (&p); - - ComSmartPtr sink; - HRESULT hr = p->Open (sink.resetAndGetPointerAddress()); // xxx handle error - sink->SetFillMode (D2D1_FILL_MODE_WINDING); - - for (int i = clipRegion.getNumRectangles(); --i >= 0;) - rectToGeometrySink (clipRegion.getRectangle(i), sink); - - hr = sink->Close(); - return p; - } - - static void pathToGeometrySink (const Path& path, ID2D1GeometrySink* sink, const AffineTransform& transform) - { - Path::Iterator it (path); - - while (it.next()) - { - switch (it.elementType) - { - case Path::Iterator::cubicTo: - { - D2D1_BEZIER_SEGMENT seg; - - transform.transformPoint (it.x1, it.y1); - seg.point1 = D2D1::Point2F (it.x1, it.y1); - - transform.transformPoint (it.x2, it.y2); - seg.point2 = D2D1::Point2F (it.x2, it.y2); - - transform.transformPoint(it.x3, it.y3); - seg.point3 = D2D1::Point2F (it.x3, it.y3); - - sink->AddBezier (seg); - break; - } - - case Path::Iterator::lineTo: - { - transform.transformPoint (it.x1, it.y1); - sink->AddLine (D2D1::Point2F (it.x1, it.y1)); - break; - } - - case Path::Iterator::quadraticTo: - { - D2D1_QUADRATIC_BEZIER_SEGMENT seg; - - transform.transformPoint (it.x1, it.y1); - seg.point1 = D2D1::Point2F (it.x1, it.y1); - - transform.transformPoint (it.x2, it.y2); - seg.point2 = D2D1::Point2F (it.x2, it.y2); - - sink->AddQuadraticBezier (seg); - break; - } - - case Path::Iterator::closePath: - { - sink->EndFigure (D2D1_FIGURE_END_CLOSED); - break; - } - - case Path::Iterator::startNewSubPath: - { - transform.transformPoint (it.x1, it.y1); - sink->BeginFigure (D2D1::Point2F (it.x1, it.y1), D2D1_FIGURE_BEGIN_FILLED); - break; - } - } - } - } - - static ID2D1PathGeometry* pathToPathGeometry (const Path& path, const AffineTransform& transform) - { - ID2D1PathGeometry* p = nullptr; - factories->d2dFactory->CreatePathGeometry (&p); - - ComSmartPtr sink; - HRESULT hr = p->Open (sink.resetAndGetPointerAddress()); - sink->SetFillMode (D2D1_FILL_MODE_WINDING); // xxx need to check Path::isUsingNonZeroWinding() - - pathToGeometrySink (path, sink, transform); - - hr = sink->Close(); - return p; - } - - static D2D1::Matrix3x2F transformToMatrix (const AffineTransform& transform) - { - D2D1::Matrix3x2F matrix; - matrix._11 = transform.mat00; - matrix._12 = transform.mat10; - matrix._21 = transform.mat01; - matrix._22 = transform.mat11; - matrix._31 = transform.mat02; - matrix._32 = transform.mat12; - return matrix; - } - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Direct2DLowLevelGraphicsContext) -}; diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/native/juce_win32_DirectWriteTypeLayout.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/native/juce_win32_DirectWriteTypeLayout.cpp deleted file mode 100644 index 83e3c9d94f..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/native/juce_win32_DirectWriteTypeLayout.cpp +++ /dev/null @@ -1,436 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -//================================================================================================== -#if JUCE_USE_DIRECTWRITE -namespace DirectWriteTypeLayout -{ - class CustomDirectWriteTextRenderer : public ComBaseClassHelper - { - public: - CustomDirectWriteTextRenderer (IDWriteFontCollection* const fonts, const AttributedString& as) - : ComBaseClassHelper (0), - attributedString (as), - fontCollection (fonts), - currentLine (-1), - lastOriginY (-10000.0f) - { - } - - JUCE_COMRESULT QueryInterface (REFIID refId, void** result) - { - if (refId == __uuidof (IDWritePixelSnapping)) - return castToType (result); - - return ComBaseClassHelper::QueryInterface (refId, result); - } - - JUCE_COMRESULT IsPixelSnappingDisabled (void* /*clientDrawingContext*/, BOOL* isDisabled) - { - *isDisabled = FALSE; - return S_OK; - } - - JUCE_COMRESULT GetCurrentTransform (void*, DWRITE_MATRIX*) { return S_OK; } - JUCE_COMRESULT GetPixelsPerDip (void*, FLOAT*) { return S_OK; } - JUCE_COMRESULT DrawUnderline (void*, FLOAT, FLOAT, DWRITE_UNDERLINE const*, IUnknown*) { return S_OK; } - JUCE_COMRESULT DrawStrikethrough (void*, FLOAT, FLOAT, DWRITE_STRIKETHROUGH const*, IUnknown*) { return S_OK; } - JUCE_COMRESULT DrawInlineObject (void*, FLOAT, FLOAT, IDWriteInlineObject*, BOOL, BOOL, IUnknown*) { return E_NOTIMPL; } - - JUCE_COMRESULT DrawGlyphRun (void* clientDrawingContext, FLOAT baselineOriginX, FLOAT baselineOriginY, DWRITE_MEASURING_MODE, - DWRITE_GLYPH_RUN const* glyphRun, DWRITE_GLYPH_RUN_DESCRIPTION const* runDescription, - IUnknown* clientDrawingEffect) - { - TextLayout* const layout = static_cast (clientDrawingContext); - - if (! (baselineOriginY >= -1.0e10f && baselineOriginY <= 1.0e10f)) - baselineOriginY = 0; // DirectWrite sometimes sends NaNs in this parameter - - if (baselineOriginY != lastOriginY) - { - lastOriginY = baselineOriginY; - ++currentLine; - - if (currentLine >= layout->getNumLines()) - { - jassert (currentLine == layout->getNumLines()); - TextLayout::Line* const newLine = new TextLayout::Line(); - layout->addLine (newLine); - - newLine->lineOrigin = Point (baselineOriginX, baselineOriginY); - } - } - - TextLayout::Line& glyphLine = layout->getLine (currentLine); - - DWRITE_FONT_METRICS dwFontMetrics; - glyphRun->fontFace->GetMetrics (&dwFontMetrics); - - glyphLine.ascent = jmax (glyphLine.ascent, scaledFontSize (dwFontMetrics.ascent, dwFontMetrics, glyphRun)); - glyphLine.descent = jmax (glyphLine.descent, scaledFontSize (dwFontMetrics.descent, dwFontMetrics, glyphRun)); - - TextLayout::Run* const glyphRunLayout = new TextLayout::Run (Range (runDescription->textPosition, - runDescription->textPosition + runDescription->stringLength), - glyphRun->glyphCount); - glyphLine.runs.add (glyphRunLayout); - - glyphRun->fontFace->GetMetrics (&dwFontMetrics); - const float totalHeight = std::abs ((float) dwFontMetrics.ascent) + std::abs ((float) dwFontMetrics.descent); - const float fontHeightToEmSizeFactor = (float) dwFontMetrics.designUnitsPerEm / totalHeight; - - glyphRunLayout->font = getFontForRun (glyphRun, glyphRun->fontEmSize / fontHeightToEmSizeFactor); - glyphRunLayout->colour = getColourOf (static_cast (clientDrawingEffect)); - - const Point lineOrigin (layout->getLine (currentLine).lineOrigin); - float x = baselineOriginX - lineOrigin.x; - - for (UINT32 i = 0; i < glyphRun->glyphCount; ++i) - { - const float advance = glyphRun->glyphAdvances[i]; - - if ((glyphRun->bidiLevel & 1) != 0) - x -= advance; // RTL text - - glyphRunLayout->glyphs.add (TextLayout::Glyph (glyphRun->glyphIndices[i], - Point (x, baselineOriginY - lineOrigin.y), - advance)); - - if ((glyphRun->bidiLevel & 1) == 0) - x += advance; // LTR text - } - - return S_OK; - } - - private: - const AttributedString& attributedString; - IDWriteFontCollection* const fontCollection; - int currentLine; - float lastOriginY; - - static float scaledFontSize (int n, const DWRITE_FONT_METRICS& metrics, const DWRITE_GLYPH_RUN* glyphRun) noexcept - { - return (std::abs ((float) n) / (float) metrics.designUnitsPerEm) * glyphRun->fontEmSize; - } - - static Colour getColourOf (ID2D1SolidColorBrush* d2dBrush) - { - if (d2dBrush == nullptr) - return Colours::black; - - const D2D1_COLOR_F colour (d2dBrush->GetColor()); - return Colour::fromFloatRGBA (colour.r, colour.g, colour.b, colour.a); - } - - Font getFontForRun (DWRITE_GLYPH_RUN const* glyphRun, float fontHeight) - { - for (int i = 0; i < attributedString.getNumAttributes(); ++i) - if (const Font* font = attributedString.getAttribute(i)->getFont()) - if (WindowsDirectWriteTypeface* wt = dynamic_cast (font->getTypeface())) - if (wt->getIDWriteFontFace() == glyphRun->fontFace) - return font->withHeight (fontHeight); - - ComSmartPtr dwFont; - HRESULT hr = fontCollection->GetFontFromFontFace (glyphRun->fontFace, dwFont.resetAndGetPointerAddress()); - jassert (dwFont != nullptr); - - ComSmartPtr dwFontFamily; - hr = dwFont->GetFontFamily (dwFontFamily.resetAndGetPointerAddress()); - - return Font (getFontFamilyName (dwFontFamily), getFontFaceName (dwFont), fontHeight); - } - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (CustomDirectWriteTextRenderer) - }; - - //================================================================================================== - static float getFontHeightToEmSizeFactor (IDWriteFont* const dwFont) - { - ComSmartPtr dwFontFace; - dwFont->CreateFontFace (dwFontFace.resetAndGetPointerAddress()); - - if (dwFontFace == nullptr) - return 1.0f; - - DWRITE_FONT_METRICS dwFontMetrics; - dwFontFace->GetMetrics (&dwFontMetrics); - - const float totalHeight = (float) (std::abs (dwFontMetrics.ascent) + std::abs (dwFontMetrics.descent)); - return dwFontMetrics.designUnitsPerEm / totalHeight; - } - - void setTextFormatProperties (const AttributedString& text, IDWriteTextFormat* const format) - { - DWRITE_TEXT_ALIGNMENT alignment = DWRITE_TEXT_ALIGNMENT_LEADING; - DWRITE_WORD_WRAPPING wrapType = DWRITE_WORD_WRAPPING_WRAP; - - switch (text.getJustification().getOnlyHorizontalFlags()) - { - case Justification::left: break; - case Justification::right: alignment = DWRITE_TEXT_ALIGNMENT_TRAILING; break; - case Justification::horizontallyCentred: alignment = DWRITE_TEXT_ALIGNMENT_CENTER; break; - case Justification::horizontallyJustified: break; // DirectWrite cannot justify text, default to left alignment - default: jassertfalse; break; // Illegal justification flags - } - - switch (text.getWordWrap()) - { - case AttributedString::none: wrapType = DWRITE_WORD_WRAPPING_NO_WRAP; break; - case AttributedString::byWord: break; - case AttributedString::byChar: break; // DirectWrite doesn't support wrapping by character, default to word-wrap - default: jassertfalse; break; // Illegal flags! - } - - // DirectWrite does not automatically set reading direction - // This must be set correctly and manually when using RTL Scripts (Hebrew, Arabic) - if (text.getReadingDirection() == AttributedString::rightToLeft) - { - format->SetReadingDirection (DWRITE_READING_DIRECTION_RIGHT_TO_LEFT); - - switch (text.getJustification().getOnlyHorizontalFlags()) - { - case Justification::left: alignment = DWRITE_TEXT_ALIGNMENT_TRAILING; break; - case Justification::right: alignment = DWRITE_TEXT_ALIGNMENT_LEADING; break; - default: break; - } - } - - format->SetTextAlignment (alignment); - format->SetWordWrapping (wrapType); - } - - void addAttributedRange (const AttributedString::Attribute& attr, IDWriteTextLayout* textLayout, - const int textLen, ID2D1RenderTarget* const renderTarget, IDWriteFontCollection* const fontCollection) - { - DWRITE_TEXT_RANGE range; - range.startPosition = attr.range.getStart(); - range.length = jmin (attr.range.getLength(), textLen - attr.range.getStart()); - - if (const Font* const font = attr.getFont()) - { - const String familyName (FontStyleHelpers::getConcreteFamilyName (*font)); - - BOOL fontFound = false; - uint32 fontIndex; - fontCollection->FindFamilyName (familyName.toWideCharPointer(), - &fontIndex, &fontFound); - - if (! fontFound) - fontIndex = 0; - - ComSmartPtr fontFamily; - HRESULT hr = fontCollection->GetFontFamily (fontIndex, fontFamily.resetAndGetPointerAddress()); - - ComSmartPtr dwFont; - uint32 fontFacesCount = 0; - fontFacesCount = fontFamily->GetFontCount(); - - for (int i = fontFacesCount; --i >= 0;) - { - hr = fontFamily->GetFont (i, dwFont.resetAndGetPointerAddress()); - - if (font->getTypefaceStyle() == getFontFaceName (dwFont)) - break; - } - - textLayout->SetFontFamilyName (familyName.toWideCharPointer(), range); - textLayout->SetFontWeight (dwFont->GetWeight(), range); - textLayout->SetFontStretch (dwFont->GetStretch(), range); - textLayout->SetFontStyle (dwFont->GetStyle(), range); - - const float fontHeightToEmSizeFactor = getFontHeightToEmSizeFactor (dwFont); - textLayout->SetFontSize (font->getHeight() * fontHeightToEmSizeFactor, range); - } - - if (const Colour* const colour = attr.getColour()) - { - ComSmartPtr d2dBrush; - renderTarget->CreateSolidColorBrush (D2D1::ColorF (D2D1::ColorF (colour->getFloatRed(), - colour->getFloatGreen(), - colour->getFloatBlue(), - colour->getFloatAlpha())), - d2dBrush.resetAndGetPointerAddress()); - - // We need to call SetDrawingEffect with a legimate brush to get DirectWrite to break text based on colours - textLayout->SetDrawingEffect (d2dBrush, range); - } - } - - bool setupLayout (const AttributedString& text, const float maxWidth, const float maxHeight, - ID2D1RenderTarget* const renderTarget, IDWriteFactory* const directWriteFactory, - IDWriteFontCollection* const fontCollection, ComSmartPtr& textLayout) - { - // To add color to text, we need to create a D2D render target - // Since we are not actually rendering to a D2D context we create a temporary GDI render target - - Font defaultFont; - BOOL fontFound = false; - uint32 fontIndex; - fontCollection->FindFamilyName (defaultFont.getTypeface()->getName().toWideCharPointer(), &fontIndex, &fontFound); - - if (! fontFound) - fontIndex = 0; - - ComSmartPtr dwFontFamily; - HRESULT hr = fontCollection->GetFontFamily (fontIndex, dwFontFamily.resetAndGetPointerAddress()); - - ComSmartPtr dwFont; - hr = dwFontFamily->GetFirstMatchingFont (DWRITE_FONT_WEIGHT_NORMAL, DWRITE_FONT_STRETCH_NORMAL, DWRITE_FONT_STYLE_NORMAL, - dwFont.resetAndGetPointerAddress()); - - const float defaultFontHeightToEmSizeFactor = getFontHeightToEmSizeFactor (dwFont); - - jassert (directWriteFactory != nullptr); - - ComSmartPtr dwTextFormat; - hr = directWriteFactory->CreateTextFormat (defaultFont.getTypefaceName().toWideCharPointer(), fontCollection, - DWRITE_FONT_WEIGHT_REGULAR, DWRITE_FONT_STYLE_NORMAL, DWRITE_FONT_STRETCH_NORMAL, - defaultFont.getHeight() * defaultFontHeightToEmSizeFactor, - L"en-us", dwTextFormat.resetAndGetPointerAddress()); - - setTextFormatProperties (text, dwTextFormat); - - const int textLen = text.getText().length(); - - hr = directWriteFactory->CreateTextLayout (text.getText().toWideCharPointer(), textLen, dwTextFormat, - maxWidth, maxHeight, textLayout.resetAndGetPointerAddress()); - - if (FAILED (hr) || textLayout == nullptr) - return false; - - const int numAttributes = text.getNumAttributes(); - - for (int i = 0; i < numAttributes; ++i) - addAttributedRange (*text.getAttribute (i), textLayout, textLen, renderTarget, fontCollection); - - return true; - } - - void createLayout (TextLayout& layout, const AttributedString& text, IDWriteFactory* const directWriteFactory, - ID2D1Factory* const direct2dFactory, IDWriteFontCollection* const fontCollection) - { - // To add color to text, we need to create a D2D render target - // Since we are not actually rendering to a D2D context we create a temporary GDI render target - - D2D1_RENDER_TARGET_PROPERTIES d2dRTProp = D2D1::RenderTargetProperties (D2D1_RENDER_TARGET_TYPE_SOFTWARE, - D2D1::PixelFormat (DXGI_FORMAT_B8G8R8A8_UNORM, - D2D1_ALPHA_MODE_IGNORE), - 0, 0, - D2D1_RENDER_TARGET_USAGE_GDI_COMPATIBLE, - D2D1_FEATURE_LEVEL_DEFAULT); - ComSmartPtr renderTarget; - HRESULT hr = direct2dFactory->CreateDCRenderTarget (&d2dRTProp, renderTarget.resetAndGetPointerAddress()); - - ComSmartPtr dwTextLayout; - - if (! setupLayout (text, layout.getWidth(), 1.0e7f, renderTarget, directWriteFactory, fontCollection, dwTextLayout)) - return; - - UINT32 actualLineCount = 0; - hr = dwTextLayout->GetLineMetrics (nullptr, 0, &actualLineCount); - - layout.ensureStorageAllocated (actualLineCount); - - { - ComSmartPtr textRenderer (new CustomDirectWriteTextRenderer (fontCollection, text)); - hr = dwTextLayout->Draw (&layout, textRenderer, 0, 0); - } - - HeapBlock dwLineMetrics (actualLineCount); - hr = dwTextLayout->GetLineMetrics (dwLineMetrics, actualLineCount, &actualLineCount); - int lastLocation = 0; - const int numLines = jmin ((int) actualLineCount, layout.getNumLines()); - - for (int i = 0; i < numLines; ++i) - { - layout.getLine(i).stringRange = Range (lastLocation, (int) lastLocation + dwLineMetrics[i].length); - lastLocation += dwLineMetrics[i].length; - } - } - - void drawToD2DContext (const AttributedString& text, const Rectangle& area, ID2D1RenderTarget* const renderTarget, - IDWriteFactory* const directWriteFactory, IDWriteFontCollection* const fontCollection) - { - ComSmartPtr dwTextLayout; - - if (setupLayout (text, area.getWidth(), area.getHeight(), renderTarget, directWriteFactory, fontCollection, dwTextLayout)) - { - ComSmartPtr d2dBrush; - renderTarget->CreateSolidColorBrush (D2D1::ColorF (D2D1::ColorF (0.0f, 0.0f, 0.0f, 1.0f)), - d2dBrush.resetAndGetPointerAddress()); - - renderTarget->DrawTextLayout (D2D1::Point2F ((float) area.getX(), (float) area.getY()), - dwTextLayout, d2dBrush, D2D1_DRAW_TEXT_OPTIONS_CLIP); - } - } -} - -static bool canAllTypefacesBeUsedInLayout (const AttributedString& text) -{ - const int numCharacterAttributes = text.getNumAttributes(); - - for (int i = 0; i < numCharacterAttributes; ++i) - if (const Font* const font = text.getAttribute (i)->getFont()) - if (dynamic_cast (font->getTypeface()) == nullptr) - return false; - - return true; -} - -#endif - -bool TextLayout::createNativeLayout (const AttributedString& text) -{ - #if JUCE_USE_DIRECTWRITE - if (! canAllTypefacesBeUsedInLayout (text)) - return false; - - SharedResourcePointer factories; - - if (factories->d2dFactory != nullptr && factories->systemFonts != nullptr) - { - #if JUCE_64BIT - // There's a mysterious bug in 64-bit Windows that causes garbage floating-point - // values to be returned to DrawGlyphRun the first time that it gets used. - // In lieu of a better plan, this bodge uses a dummy call to work around this. - static bool hasBeenCalled = false; - if (! hasBeenCalled) - { - hasBeenCalled = true; - TextLayout dummy; - DirectWriteTypeLayout::createLayout (dummy, text, factories->directWriteFactory, - factories->d2dFactory, factories->systemFonts); - } - #endif - - DirectWriteTypeLayout::createLayout (*this, text, factories->directWriteFactory, - factories->d2dFactory, factories->systemFonts); - return true; - } - #else - (void) text; - #endif - - return false; -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/native/juce_win32_DirectWriteTypeface.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/native/juce_win32_DirectWriteTypeface.cpp deleted file mode 100644 index 0673aa556b..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/native/juce_win32_DirectWriteTypeface.cpp +++ /dev/null @@ -1,307 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#if JUCE_USE_DIRECTWRITE -namespace -{ - static String getLocalisedName (IDWriteLocalizedStrings* names) - { - jassert (names != nullptr); - - uint32 index = 0; - BOOL exists = false; - HRESULT hr = names->FindLocaleName (L"en-us", &index, &exists); - if (! exists) - index = 0; - - uint32 length = 0; - hr = names->GetStringLength (index, &length); - - HeapBlock name (length + 1); - hr = names->GetString (index, name, length + 1); - - return static_cast (name); - } - - static String getFontFamilyName (IDWriteFontFamily* family) - { - jassert (family != nullptr); - ComSmartPtr familyNames; - HRESULT hr = family->GetFamilyNames (familyNames.resetAndGetPointerAddress()); - jassert (SUCCEEDED (hr)); (void) hr; - return getLocalisedName (familyNames); - } - - static String getFontFaceName (IDWriteFont* font) - { - jassert (font != nullptr); - ComSmartPtr faceNames; - HRESULT hr = font->GetFaceNames (faceNames.resetAndGetPointerAddress()); - jassert (SUCCEEDED (hr)); (void) hr; - - return getLocalisedName (faceNames); - } -} - -class Direct2DFactories -{ -public: - Direct2DFactories() - { - if (direct2dDll.open ("d2d1.dll")) - { - JUCE_LOAD_WINAPI_FUNCTION (direct2dDll, D2D1CreateFactory, d2d1CreateFactory, - HRESULT, (D2D1_FACTORY_TYPE, REFIID, D2D1_FACTORY_OPTIONS*, void**)) - - if (d2d1CreateFactory != nullptr) - { - D2D1_FACTORY_OPTIONS options; - options.debugLevel = D2D1_DEBUG_LEVEL_NONE; - - d2d1CreateFactory (D2D1_FACTORY_TYPE_SINGLE_THREADED, __uuidof (ID2D1Factory), &options, - (void**) d2dFactory.resetAndGetPointerAddress()); - } - } - - if (directWriteDll.open ("DWrite.dll")) - { - JUCE_LOAD_WINAPI_FUNCTION (directWriteDll, DWriteCreateFactory, dWriteCreateFactory, - HRESULT, (DWRITE_FACTORY_TYPE, REFIID, IUnknown**)) - - if (dWriteCreateFactory != nullptr) - { - dWriteCreateFactory (DWRITE_FACTORY_TYPE_SHARED, __uuidof (IDWriteFactory), - (IUnknown**) directWriteFactory.resetAndGetPointerAddress()); - - if (directWriteFactory != nullptr) - directWriteFactory->GetSystemFontCollection (systemFonts.resetAndGetPointerAddress()); - } - } - } - - ~Direct2DFactories() - { - d2dFactory = nullptr; // (need to make sure these are released before deleting the DynamicLibrary objects) - directWriteFactory = nullptr; - systemFonts = nullptr; - } - - ComSmartPtr d2dFactory; - ComSmartPtr directWriteFactory; - ComSmartPtr systemFonts; - -private: - DynamicLibrary direct2dDll, directWriteDll; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Direct2DFactories) -}; - -//================================================================================================== -class WindowsDirectWriteTypeface : public Typeface -{ -public: - WindowsDirectWriteTypeface (const Font& font, IDWriteFontCollection* fontCollection) - : Typeface (font.getTypefaceName(), font.getTypefaceStyle()), - unitsToHeightScaleFactor (1.0f), heightToPointsFactor (1.0f), ascent (0.0f) - { - jassert (fontCollection != nullptr); - - BOOL fontFound = false; - uint32 fontIndex = 0; - HRESULT hr = fontCollection->FindFamilyName (font.getTypefaceName().toWideCharPointer(), &fontIndex, &fontFound); - if (! fontFound) - fontIndex = 0; - - // Get the font family using the search results - // Fonts like: Times New Roman, Times New Roman Bold, Times New Roman Italic are all in the same font family - ComSmartPtr dwFontFamily; - hr = fontCollection->GetFontFamily (fontIndex, dwFontFamily.resetAndGetPointerAddress()); - - // Get a specific font in the font family using typeface style - { - ComSmartPtr dwFont; - - for (int i = (int) dwFontFamily->GetFontCount(); --i >= 0;) - { - hr = dwFontFamily->GetFont (i, dwFont.resetAndGetPointerAddress()); - - if (i == 0) - break; - - ComSmartPtr faceNames; - hr = dwFont->GetFaceNames (faceNames.resetAndGetPointerAddress()); - - if (font.getTypefaceStyle() == getLocalisedName (faceNames)) - break; - } - - jassert (dwFont != nullptr); - hr = dwFont->CreateFontFace (dwFontFace.resetAndGetPointerAddress()); - } - - if (dwFontFace != nullptr) - { - DWRITE_FONT_METRICS dwFontMetrics; - dwFontFace->GetMetrics (&dwFontMetrics); - - // All Font Metrics are in design units so we need to get designUnitsPerEm value - // to get the metrics into Em/Design Independent Pixels - designUnitsPerEm = dwFontMetrics.designUnitsPerEm; - - ascent = std::abs ((float) dwFontMetrics.ascent); - const float totalSize = ascent + std::abs ((float) dwFontMetrics.descent); - ascent /= totalSize; - unitsToHeightScaleFactor = designUnitsPerEm / totalSize; - - HDC tempDC = GetDC (0); - float dpi = (GetDeviceCaps (tempDC, LOGPIXELSX) + GetDeviceCaps (tempDC, LOGPIXELSY)) / 2.0f; - heightToPointsFactor = (dpi / GetDeviceCaps (tempDC, LOGPIXELSY)) * unitsToHeightScaleFactor; - ReleaseDC (0, tempDC); - - const float pathAscent = (1024.0f * dwFontMetrics.ascent) / designUnitsPerEm; - const float pathDescent = (1024.0f * dwFontMetrics.descent) / designUnitsPerEm; - const float pathScale = 1.0f / (std::abs (pathAscent) + std::abs (pathDescent)); - pathTransform = AffineTransform::scale (pathScale); - } - } - - bool loadedOk() const noexcept { return dwFontFace != nullptr; } - - float getAscent() const { return ascent; } - float getDescent() const { return 1.0f - ascent; } - float getHeightToPointsFactor() const { return heightToPointsFactor; } - - float getStringWidth (const String& text) - { - const CharPointer_UTF32 textUTF32 (text.toUTF32()); - const size_t len = textUTF32.length(); - - HeapBlock glyphIndices (len); - dwFontFace->GetGlyphIndices (textUTF32, (UINT32) len, glyphIndices); - - HeapBlock dwGlyphMetrics (len); - dwFontFace->GetDesignGlyphMetrics (glyphIndices, (UINT32) len, dwGlyphMetrics, false); - - float x = 0; - for (size_t i = 0; i < len; ++i) - x += (float) dwGlyphMetrics[i].advanceWidth / designUnitsPerEm; - - return x * unitsToHeightScaleFactor; - } - - void getGlyphPositions (const String& text, Array & resultGlyphs, Array & xOffsets) - { - xOffsets.add (0); - - const CharPointer_UTF32 textUTF32 (text.toUTF32()); - const size_t len = textUTF32.length(); - - HeapBlock glyphIndices (len); - dwFontFace->GetGlyphIndices (textUTF32, (UINT32) len, glyphIndices); - HeapBlock dwGlyphMetrics (len); - dwFontFace->GetDesignGlyphMetrics (glyphIndices, (UINT32) len, dwGlyphMetrics, false); - - float x = 0; - for (size_t i = 0; i < len; ++i) - { - x += (float) dwGlyphMetrics[i].advanceWidth / designUnitsPerEm; - xOffsets.add (x * unitsToHeightScaleFactor); - resultGlyphs.add (glyphIndices[i]); - } - } - - bool getOutlineForGlyph (int glyphNumber, Path& path) - { - jassert (path.isEmpty()); // we might need to apply a transform to the path, so this must be empty - UINT16 glyphIndex = (UINT16) glyphNumber; - ComSmartPtr pathGeometrySink (new PathGeometrySink()); - - dwFontFace->GetGlyphRunOutline (1024.0f, &glyphIndex, nullptr, nullptr, 1, false, false, pathGeometrySink); - path = pathGeometrySink->path; - - if (! pathTransform.isIdentity()) - path.applyTransform (pathTransform); - - return true; - } - - IDWriteFontFace* getIDWriteFontFace() const noexcept { return dwFontFace; } - -private: - SharedResourcePointer factories; - ComSmartPtr dwFontFace; - float unitsToHeightScaleFactor, heightToPointsFactor, ascent; - int designUnitsPerEm; - AffineTransform pathTransform; - - class PathGeometrySink : public ComBaseClassHelper - { - public: - PathGeometrySink() : ComBaseClassHelper (0) {} - - void __stdcall AddBeziers (const D2D1_BEZIER_SEGMENT *beziers, UINT beziersCount) - { - for (UINT i = 0; i < beziersCount; ++i) - path.cubicTo ((float) beziers[i].point1.x, (float) beziers[i].point1.y, - (float) beziers[i].point2.x, (float) beziers[i].point2.y, - (float) beziers[i].point3.x, (float) beziers[i].point3.y); - } - - void __stdcall AddLines (const D2D1_POINT_2F* points, UINT pointsCount) - { - for (UINT i = 0; i < pointsCount; ++i) - path.lineTo ((float) points[i].x, - (float) points[i].y); - } - - void __stdcall BeginFigure (D2D1_POINT_2F startPoint, D2D1_FIGURE_BEGIN) - { - path.startNewSubPath ((float) startPoint.x, - (float) startPoint.y); - } - - void __stdcall EndFigure (D2D1_FIGURE_END figureEnd) - { - if (figureEnd == D2D1_FIGURE_END_CLOSED) - path.closeSubPath(); - } - - void __stdcall SetFillMode (D2D1_FILL_MODE fillMode) - { - path.setUsingNonZeroWinding (fillMode == D2D1_FILL_MODE_WINDING); - } - - void __stdcall SetSegmentFlags (D2D1_PATH_SEGMENT) {} - JUCE_COMRESULT Close() { return S_OK; } - - Path path; - - private: - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (PathGeometrySink) - }; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (WindowsDirectWriteTypeface) -}; - -#endif diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/native/juce_win32_Fonts.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/native/juce_win32_Fonts.cpp deleted file mode 100644 index bc5bb35203..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/native/juce_win32_Fonts.cpp +++ /dev/null @@ -1,644 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -/* This is some quick-and-dirty code to extract the typeface name from a lump of TTF file data. - It's needed because although win32 will happily load a TTF file from in-memory data, it won't - tell you the name of the damned font that it just loaded.. and in order to actually use the font, - you need to know its name!! Anyway, this awful hack seems to work for most fonts. -*/ -namespace TTFNameExtractor -{ - struct OffsetTable - { - uint32 version; - uint16 numTables, searchRange, entrySelector, rangeShift; - }; - - struct TableDirectory - { - char tag[4]; - uint32 checkSum, offset, length; - }; - - struct NamingTable - { - uint16 formatSelector; - uint16 numberOfNameRecords; - uint16 offsetStartOfStringStorage; - }; - - struct NameRecord - { - uint16 platformID, encodingID, languageID; - uint16 nameID, stringLength, offsetFromStorageArea; - }; - - static String parseNameRecord (MemoryInputStream& input, const NameRecord& nameRecord, - const int64 directoryOffset, const int64 offsetOfStringStorage) - { - String result; - const int64 oldPos = input.getPosition(); - input.setPosition (directoryOffset + offsetOfStringStorage + ByteOrder::swapIfLittleEndian (nameRecord.offsetFromStorageArea)); - const int stringLength = (int) ByteOrder::swapIfLittleEndian (nameRecord.stringLength); - const int platformID = ByteOrder::swapIfLittleEndian (nameRecord.platformID); - - if (platformID == 0 || platformID == 3) - { - const int numChars = stringLength / 2 + 1; - HeapBlock buffer; - buffer.calloc (numChars + 1); - input.read (buffer, stringLength); - - for (int i = 0; i < numChars; ++i) - buffer[i] = ByteOrder::swapIfLittleEndian (buffer[i]); - - static_jassert (sizeof (CharPointer_UTF16::CharType) == sizeof (uint16)); - result = CharPointer_UTF16 ((CharPointer_UTF16::CharType*) buffer.getData()); - } - else - { - HeapBlock buffer; - buffer.calloc (stringLength + 1); - input.read (buffer, stringLength); - result = CharPointer_UTF8 (buffer.getData()); - } - - input.setPosition (oldPos); - return result; - } - - static String parseNameTable (MemoryInputStream& input, int64 directoryOffset) - { - input.setPosition (directoryOffset); - - NamingTable namingTable = { 0 }; - input.read (&namingTable, sizeof (namingTable)); - - for (int i = 0; i < (int) ByteOrder::swapIfLittleEndian (namingTable.numberOfNameRecords); ++i) - { - NameRecord nameRecord = { 0 }; - input.read (&nameRecord, sizeof (nameRecord)); - - if (ByteOrder::swapIfLittleEndian (nameRecord.nameID) == 4) - { - const String result (parseNameRecord (input, nameRecord, directoryOffset, - ByteOrder::swapIfLittleEndian (namingTable.offsetStartOfStringStorage))); - - if (result.isNotEmpty()) - return result; - } - } - - return String(); - } - - static String getTypefaceNameFromFile (MemoryInputStream& input) - { - OffsetTable offsetTable = { 0 }; - input.read (&offsetTable, sizeof (offsetTable)); - - for (int i = 0; i < (int) ByteOrder::swapIfLittleEndian (offsetTable.numTables); ++i) - { - TableDirectory tableDirectory; - zerostruct (tableDirectory); - input.read (&tableDirectory, sizeof (tableDirectory)); - - if (String (tableDirectory.tag, sizeof (tableDirectory.tag)).equalsIgnoreCase ("name")) - return parseNameTable (input, ByteOrder::swapIfLittleEndian (tableDirectory.offset)); - } - - return String(); - } -} - -namespace FontEnumerators -{ - static int CALLBACK fontEnum2 (ENUMLOGFONTEXW* lpelfe, NEWTEXTMETRICEXW*, int type, LPARAM lParam) - { - if (lpelfe != nullptr && (type & RASTER_FONTTYPE) == 0) - { - const String fontName (lpelfe->elfLogFont.lfFaceName); - ((StringArray*) lParam)->addIfNotAlreadyThere (fontName.removeCharacters ("@")); - } - - return 1; - } - - static int CALLBACK fontEnum1 (ENUMLOGFONTEXW* lpelfe, NEWTEXTMETRICEXW*, int type, LPARAM lParam) - { - if (lpelfe != nullptr && (type & RASTER_FONTTYPE) == 0) - { - LOGFONTW lf = { 0 }; - lf.lfWeight = FW_DONTCARE; - lf.lfOutPrecision = OUT_OUTLINE_PRECIS; - lf.lfQuality = DEFAULT_QUALITY; - lf.lfCharSet = DEFAULT_CHARSET; - lf.lfClipPrecision = CLIP_DEFAULT_PRECIS; - lf.lfPitchAndFamily = FF_DONTCARE; - - const String fontName (lpelfe->elfLogFont.lfFaceName); - fontName.copyToUTF16 (lf.lfFaceName, sizeof (lf.lfFaceName)); - - HDC dc = CreateCompatibleDC (0); - EnumFontFamiliesEx (dc, &lf, - (FONTENUMPROCW) &fontEnum2, - lParam, 0); - DeleteDC (dc); - } - - return 1; - } -} - -StringArray Font::findAllTypefaceNames() -{ - StringArray results; - - #if JUCE_USE_DIRECTWRITE - SharedResourcePointer factories; - - if (factories->systemFonts != nullptr) - { - ComSmartPtr fontFamily; - uint32 fontFamilyCount = 0; - fontFamilyCount = factories->systemFonts->GetFontFamilyCount(); - - for (uint32 i = 0; i < fontFamilyCount; ++i) - { - HRESULT hr = factories->systemFonts->GetFontFamily (i, fontFamily.resetAndGetPointerAddress()); - - if (SUCCEEDED (hr)) - results.addIfNotAlreadyThere (getFontFamilyName (fontFamily)); - } - } - else - #endif - { - HDC dc = CreateCompatibleDC (0); - - { - LOGFONTW lf = { 0 }; - lf.lfWeight = FW_DONTCARE; - lf.lfOutPrecision = OUT_OUTLINE_PRECIS; - lf.lfQuality = DEFAULT_QUALITY; - lf.lfCharSet = DEFAULT_CHARSET; - lf.lfClipPrecision = CLIP_DEFAULT_PRECIS; - lf.lfPitchAndFamily = FF_DONTCARE; - - EnumFontFamiliesEx (dc, &lf, - (FONTENUMPROCW) &FontEnumerators::fontEnum1, - (LPARAM) &results, 0); - } - - DeleteDC (dc); - } - - results.sort (true); - return results; -} - -StringArray Font::findAllTypefaceStyles (const String& family) -{ - if (FontStyleHelpers::isPlaceholderFamilyName (family)) - return findAllTypefaceStyles (FontStyleHelpers::getConcreteFamilyNameFromPlaceholder (family)); - - StringArray results; - - #if JUCE_USE_DIRECTWRITE - SharedResourcePointer factories; - - if (factories->systemFonts != nullptr) - { - BOOL fontFound = false; - uint32 fontIndex = 0; - HRESULT hr = factories->systemFonts->FindFamilyName (family.toWideCharPointer(), &fontIndex, &fontFound); - if (! fontFound) - fontIndex = 0; - - // Get the font family using the search results - // Fonts like: Times New Roman, Times New Roman Bold, Times New Roman Italic are all in the same font family - ComSmartPtr fontFamily; - hr = factories->systemFonts->GetFontFamily (fontIndex, fontFamily.resetAndGetPointerAddress()); - - // Get the font faces - ComSmartPtr dwFont; - uint32 fontFacesCount = 0; - fontFacesCount = fontFamily->GetFontCount(); - - for (uint32 i = 0; i < fontFacesCount; ++i) - { - hr = fontFamily->GetFont (i, dwFont.resetAndGetPointerAddress()); - - // Ignore any algorithmically generated bold and oblique styles.. - if (dwFont->GetSimulations() == DWRITE_FONT_SIMULATIONS_NONE) - results.addIfNotAlreadyThere (getFontFaceName (dwFont)); - } - } - else - #endif - { - results.add ("Regular"); - results.add ("Italic"); - results.add ("Bold"); - results.add ("Bold Italic"); - } - - return results; -} - -extern bool juce_isRunningInWine(); - -struct DefaultFontNames -{ - DefaultFontNames() - { - if (juce_isRunningInWine()) - { - // If we're running in Wine, then use fonts that might be available on Linux.. - defaultSans = "Bitstream Vera Sans"; - defaultSerif = "Bitstream Vera Serif"; - defaultFixed = "Bitstream Vera Sans Mono"; - } - else - { - defaultSans = "Verdana"; - defaultSerif = "Times New Roman"; - defaultFixed = "Lucida Console"; - defaultFallback = "Tahoma"; // (contains plenty of unicode characters) - } - } - - String defaultSans, defaultSerif, defaultFixed, defaultFallback; -}; - -Typeface::Ptr Font::getDefaultTypefaceForFont (const Font& font) -{ - static DefaultFontNames defaultNames; - - Font newFont (font); - const String& faceName = font.getTypefaceName(); - - if (faceName == getDefaultSansSerifFontName()) newFont.setTypefaceName (defaultNames.defaultSans); - else if (faceName == getDefaultSerifFontName()) newFont.setTypefaceName (defaultNames.defaultSerif); - else if (faceName == getDefaultMonospacedFontName()) newFont.setTypefaceName (defaultNames.defaultFixed); - - if (font.getTypefaceStyle() == getDefaultStyle()) - newFont.setTypefaceStyle ("Regular"); - - return Typeface::createSystemTypefaceFor (newFont); -} - -//============================================================================== -class WindowsTypeface : public Typeface -{ -public: - WindowsTypeface (const Font& font) - : Typeface (font.getTypefaceName(), font.getTypefaceStyle()), - fontH (0), previousFontH (0), - dc (CreateCompatibleDC (0)), memoryFont (0), - ascent (1.0f), heightToPointsFactor (1.0f), - defaultGlyph (-1) - { - loadFont(); - } - - WindowsTypeface (const void* data, size_t dataSize) - : Typeface (String(), String()), - fontH (0), previousFontH (0), - dc (CreateCompatibleDC (0)), memoryFont (0), - ascent (1.0f), heightToPointsFactor (1.0f), - defaultGlyph (-1) - { - DWORD numInstalled = 0; - memoryFont = AddFontMemResourceEx (const_cast (data), (DWORD) dataSize, - nullptr, &numInstalled); - - MemoryInputStream m (data, dataSize, false); - name = TTFNameExtractor::getTypefaceNameFromFile (m); - loadFont(); - } - - ~WindowsTypeface() - { - SelectObject (dc, previousFontH); // Replacing the previous font before deleting the DC avoids a warning in BoundsChecker - DeleteDC (dc); - - if (fontH != 0) - DeleteObject (fontH); - - if (memoryFont != 0) - RemoveFontMemResourceEx (memoryFont); - } - - float getAscent() const { return ascent; } - float getDescent() const { return 1.0f - ascent; } - float getHeightToPointsFactor() const { return heightToPointsFactor; } - - float getStringWidth (const String& text) - { - const CharPointer_UTF16 utf16 (text.toUTF16()); - const size_t numChars = utf16.length(); - HeapBlock results (numChars + 1); - results[numChars] = -1; - float x = 0; - - if (GetGlyphIndices (dc, utf16, (int) numChars, reinterpret_cast (results.getData()), - GGI_MARK_NONEXISTING_GLYPHS) != GDI_ERROR) - { - for (size_t i = 0; i < numChars; ++i) - x += getKerning (dc, results[i], results[i + 1]); - } - - return x; - } - - void getGlyphPositions (const String& text, Array & resultGlyphs, Array & xOffsets) - { - const CharPointer_UTF16 utf16 (text.toUTF16()); - const size_t numChars = utf16.length(); - HeapBlock results (numChars + 1); - results[numChars] = -1; - float x = 0; - - if (GetGlyphIndices (dc, utf16, (int) numChars, reinterpret_cast (results.getData()), - GGI_MARK_NONEXISTING_GLYPHS) != GDI_ERROR) - { - resultGlyphs.ensureStorageAllocated ((int) numChars); - xOffsets.ensureStorageAllocated ((int) numChars + 1); - - for (size_t i = 0; i < numChars; ++i) - { - resultGlyphs.add (results[i]); - xOffsets.add (x); - x += getKerning (dc, results[i], results[i + 1]); - } - } - - xOffsets.add (x); - } - - bool getOutlineForGlyph (int glyphNumber, Path& glyphPath) - { - if (glyphNumber < 0) - glyphNumber = defaultGlyph; - - GLYPHMETRICS gm; - // (although GetGlyphOutline returns a DWORD, it may be -1 on failure, so treat it as signed int..) - const int bufSize = (int) GetGlyphOutline (dc, (UINT) glyphNumber, GGO_NATIVE | GGO_GLYPH_INDEX, - &gm, 0, 0, &identityMatrix); - - if (bufSize > 0) - { - HeapBlock data (bufSize); - GetGlyphOutline (dc, (UINT) glyphNumber, GGO_NATIVE | GGO_GLYPH_INDEX, &gm, - bufSize, data, &identityMatrix); - - const TTPOLYGONHEADER* pheader = reinterpret_cast (data.getData()); - - const float scaleX = 1.0f / tm.tmHeight; - const float scaleY = -scaleX; - - while ((char*) pheader < data + bufSize) - { - glyphPath.startNewSubPath (scaleX * pheader->pfxStart.x.value, - scaleY * pheader->pfxStart.y.value); - - const TTPOLYCURVE* curve = (const TTPOLYCURVE*) ((const char*) pheader + sizeof (TTPOLYGONHEADER)); - const char* const curveEnd = ((const char*) pheader) + pheader->cb; - - while ((const char*) curve < curveEnd) - { - if (curve->wType == TT_PRIM_LINE) - { - for (int i = 0; i < curve->cpfx; ++i) - glyphPath.lineTo (scaleX * curve->apfx[i].x.value, - scaleY * curve->apfx[i].y.value); - } - else if (curve->wType == TT_PRIM_QSPLINE) - { - for (int i = 0; i < curve->cpfx - 1; ++i) - { - const float x2 = scaleX * curve->apfx[i].x.value; - const float y2 = scaleY * curve->apfx[i].y.value; - float x3 = scaleX * curve->apfx[i + 1].x.value; - float y3 = scaleY * curve->apfx[i + 1].y.value; - - if (i < curve->cpfx - 2) - { - x3 = 0.5f * (x2 + x3); - y3 = 0.5f * (y2 + y3); - } - - glyphPath.quadraticTo (x2, y2, x3, y3); - } - } - - curve = (const TTPOLYCURVE*) &(curve->apfx [curve->cpfx]); - } - - pheader = (const TTPOLYGONHEADER*) curve; - - glyphPath.closeSubPath(); - } - } - - return true; - } - -private: - static const MAT2 identityMatrix; - HFONT fontH; - HGDIOBJ previousFontH; - HDC dc; - TEXTMETRIC tm; - HANDLE memoryFont; - float ascent, heightToPointsFactor; - int defaultGlyph, heightInPoints; - - struct KerningPair - { - int glyph1, glyph2; - float kerning; - - bool operator== (const KerningPair& other) const noexcept - { - return glyph1 == other.glyph1 && glyph2 == other.glyph2; - } - - bool operator< (const KerningPair& other) const noexcept - { - return glyph1 < other.glyph1 - || (glyph1 == other.glyph1 && glyph2 < other.glyph2); - } - }; - - SortedSet kerningPairs; - - void loadFont() - { - SetMapperFlags (dc, 0); - SetMapMode (dc, MM_TEXT); - - LOGFONTW lf = { 0 }; - lf.lfCharSet = DEFAULT_CHARSET; - lf.lfClipPrecision = CLIP_DEFAULT_PRECIS; - lf.lfOutPrecision = OUT_OUTLINE_PRECIS; - lf.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE; - lf.lfQuality = PROOF_QUALITY; - lf.lfItalic = (BYTE) (style.contains ("Italic") ? TRUE : FALSE); - lf.lfWeight = style.contains ("Bold") ? FW_BOLD : FW_NORMAL; - lf.lfHeight = -256; - name.copyToUTF16 (lf.lfFaceName, sizeof (lf.lfFaceName)); - - HFONT standardSizedFont = CreateFontIndirect (&lf); - - if (standardSizedFont != 0) - { - if ((previousFontH = SelectObject (dc, standardSizedFont)) != 0) - { - fontH = standardSizedFont; - - OUTLINETEXTMETRIC otm; - if (GetOutlineTextMetrics (dc, sizeof (otm), &otm) != 0) - { - heightInPoints = otm.otmEMSquare; - lf.lfHeight = -(int) heightInPoints; - fontH = CreateFontIndirect (&lf); - - SelectObject (dc, fontH); - DeleteObject (standardSizedFont); - } - } - } - - if (GetTextMetrics (dc, &tm)) - { - float dpi = (GetDeviceCaps (dc, LOGPIXELSX) + GetDeviceCaps (dc, LOGPIXELSY)) / 2.0f; - heightToPointsFactor = (dpi / GetDeviceCaps (dc, LOGPIXELSY)) * heightInPoints / (float) tm.tmHeight; - ascent = tm.tmAscent / (float) tm.tmHeight; - defaultGlyph = getGlyphForChar (dc, tm.tmDefaultChar); - createKerningPairs (dc, (float) tm.tmHeight); - } - } - - void createKerningPairs (HDC dc, const float height) - { - HeapBlock rawKerning; - const DWORD numKPs = GetKerningPairs (dc, 0, 0); - rawKerning.calloc (numKPs); - GetKerningPairs (dc, numKPs, rawKerning); - - kerningPairs.ensureStorageAllocated ((int) numKPs); - - for (DWORD i = 0; i < numKPs; ++i) - { - KerningPair kp; - kp.glyph1 = getGlyphForChar (dc, rawKerning[i].wFirst); - kp.glyph2 = getGlyphForChar (dc, rawKerning[i].wSecond); - - const int standardWidth = getGlyphWidth (dc, kp.glyph1); - kp.kerning = (standardWidth + rawKerning[i].iKernAmount) / height; - kerningPairs.add (kp); - - kp.glyph2 = -1; // add another entry for the standard width version.. - kp.kerning = standardWidth / height; - kerningPairs.add (kp); - } - } - - static int getGlyphForChar (HDC dc, juce_wchar character) - { - const WCHAR charToTest[] = { (WCHAR) character, 0 }; - WORD index = 0; - - if (GetGlyphIndices (dc, charToTest, 1, &index, GGI_MARK_NONEXISTING_GLYPHS) == GDI_ERROR - || index == 0xffff) - return -1; - - return index; - } - - static int getGlyphWidth (HDC dc, int glyphNumber) - { - GLYPHMETRICS gm; - gm.gmCellIncX = 0; - GetGlyphOutline (dc, (UINT) glyphNumber, GGO_NATIVE | GGO_GLYPH_INDEX, &gm, 0, 0, &identityMatrix); - return gm.gmCellIncX; - } - - float getKerning (HDC dc, const int glyph1, const int glyph2) - { - KerningPair kp; - kp.glyph1 = glyph1; - kp.glyph2 = glyph2; - int index = kerningPairs.indexOf (kp); - - if (index < 0) - { - kp.glyph2 = -1; - index = kerningPairs.indexOf (kp); - - if (index < 0) - { - kp.glyph2 = -1; - kp.kerning = getGlyphWidth (dc, kp.glyph1) / (float) tm.tmHeight; - kerningPairs.add (kp); - return kp.kerning; - } - } - - return kerningPairs.getReference (index).kerning; - } - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (WindowsTypeface) -}; - -const MAT2 WindowsTypeface::identityMatrix = { { 0, 1 }, { 0, 0 }, { 0, 0 }, { 0, 1 } }; - -Typeface::Ptr Typeface::createSystemTypefaceFor (const Font& font) -{ - #if JUCE_USE_DIRECTWRITE - SharedResourcePointer factories; - - if (factories->systemFonts != nullptr) - { - ScopedPointer wtf (new WindowsDirectWriteTypeface (font, factories->systemFonts)); - - if (wtf->loadedOk()) - return wtf.release(); - } - #endif - - return new WindowsTypeface (font); -} - -Typeface::Ptr Typeface::createSystemTypefaceFor (const void* data, size_t dataSize) -{ - return new WindowsTypeface (data, dataSize); -} - -void Typeface::scanFolderForFonts (const File&) -{ - jassertfalse; // not implemented on this platform -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/placement/juce_Justification.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/placement/juce_Justification.h deleted file mode 100644 index f80fa217dd..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/placement/juce_Justification.h +++ /dev/null @@ -1,189 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_JUSTIFICATION_H_INCLUDED -#define JUCE_JUSTIFICATION_H_INCLUDED - - -//============================================================================== -/** - Represents a type of justification to be used when positioning graphical items. - - e.g. it indicates whether something should be placed top-left, top-right, - centred, etc. - - It is used in various places wherever this kind of information is needed. -*/ -class Justification -{ -public: - //============================================================================== - /** Creates a Justification object using a combination of flags from the Flags enum. */ - Justification (int justificationFlags) noexcept : flags (justificationFlags) {} - - /** Creates a copy of another Justification object. */ - Justification (const Justification& other) noexcept : flags (other.flags) {} - - /** Copies another Justification object. */ - Justification& operator= (const Justification& other) noexcept - { - flags = other.flags; - return *this; - } - - bool operator== (const Justification& other) const noexcept { return flags == other.flags; } - bool operator!= (const Justification& other) const noexcept { return flags != other.flags; } - - //============================================================================== - /** Returns the raw flags that are set for this Justification object. */ - inline int getFlags() const noexcept { return flags; } - - /** Tests a set of flags for this object. - @returns true if any of the flags passed in are set on this object. - */ - inline bool testFlags (int flagsToTest) const noexcept { return (flags & flagsToTest) != 0; } - - /** Returns just the flags from this object that deal with vertical layout. */ - int getOnlyVerticalFlags() const noexcept { return flags & (top | bottom | verticallyCentred); } - - /** Returns just the flags from this object that deal with horizontal layout. */ - int getOnlyHorizontalFlags() const noexcept { return flags & (left | right | horizontallyCentred | horizontallyJustified); } - - //============================================================================== - /** Adjusts the position of a rectangle to fit it into a space. - - The (x, y) position of the rectangle will be updated to position it inside the - given space according to the justification flags. - */ - template - void applyToRectangle (ValueType& x, ValueType& y, ValueType w, ValueType h, - ValueType spaceX, ValueType spaceY, ValueType spaceW, ValueType spaceH) const noexcept - { - x = spaceX; - if ((flags & horizontallyCentred) != 0) x += (spaceW - w) / (ValueType) 2; - else if ((flags & right) != 0) x += spaceW - w; - - y = spaceY; - if ((flags & verticallyCentred) != 0) y += (spaceH - h) / (ValueType) 2; - else if ((flags & bottom) != 0) y += spaceH - h; - } - - /** Returns the new position of a rectangle that has been justified to fit within a given space. - */ - template - const Rectangle appliedToRectangle (const Rectangle& areaToAdjust, - const Rectangle& targetSpace) const noexcept - { - ValueType x = areaToAdjust.getX(), y = areaToAdjust.getY(); - applyToRectangle (x, y, areaToAdjust.getWidth(), areaToAdjust.getHeight(), - targetSpace.getX(), targetSpace.getY(), targetSpace.getWidth(), targetSpace.getHeight()); - return areaToAdjust.withPosition (x, y); - } - - //============================================================================== - /** Flag values that can be combined and used in the constructor. */ - enum Flags - { - //============================================================================== - /** Indicates that the item should be aligned against the left edge of the available space. */ - left = 1, - - /** Indicates that the item should be aligned against the right edge of the available space. */ - right = 2, - - /** Indicates that the item should be placed in the centre between the left and right - sides of the available space. */ - horizontallyCentred = 4, - - //============================================================================== - /** Indicates that the item should be aligned against the top edge of the available space. */ - top = 8, - - /** Indicates that the item should be aligned against the bottom edge of the available space. */ - bottom = 16, - - /** Indicates that the item should be placed in the centre between the top and bottom - sides of the available space. */ - verticallyCentred = 32, - - //============================================================================== - /** Indicates that lines of text should be spread out to fill the maximum width - available, so that both margins are aligned vertically. - */ - horizontallyJustified = 64, - - //============================================================================== - /** Indicates that the item should be centred vertically and horizontally. - This is equivalent to (horizontallyCentred | verticallyCentred) - */ - centred = 36, - - /** Indicates that the item should be centred vertically but placed on the left hand side. - This is equivalent to (left | verticallyCentred) - */ - centredLeft = 33, - - /** Indicates that the item should be centred vertically but placed on the right hand side. - This is equivalent to (right | verticallyCentred) - */ - centredRight = 34, - - /** Indicates that the item should be centred horizontally and placed at the top. - This is equivalent to (horizontallyCentred | top) - */ - centredTop = 12, - - /** Indicates that the item should be centred horizontally and placed at the bottom. - This is equivalent to (horizontallyCentred | bottom) - */ - centredBottom = 20, - - /** Indicates that the item should be placed in the top-left corner. - This is equivalent to (left | top) - */ - topLeft = 9, - - /** Indicates that the item should be placed in the top-right corner. - This is equivalent to (right | top) - */ - topRight = 10, - - /** Indicates that the item should be placed in the bottom-left corner. - This is equivalent to (left | bottom) - */ - bottomLeft = 17, - - /** Indicates that the item should be placed in the bottom-left corner. - This is equivalent to (right | bottom) - */ - bottomRight = 18 - }; - - -private: - //============================================================================== - int flags; -}; - -#endif // JUCE_JUSTIFICATION_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/placement/juce_RectanglePlacement.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/placement/juce_RectanglePlacement.cpp deleted file mode 100644 index 031048e308..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/placement/juce_RectanglePlacement.cpp +++ /dev/null @@ -1,127 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -RectanglePlacement::RectanglePlacement (const RectanglePlacement& other) noexcept - : flags (other.flags) -{ -} - -RectanglePlacement& RectanglePlacement::operator= (const RectanglePlacement& other) noexcept -{ - flags = other.flags; - return *this; -} - -bool RectanglePlacement::operator== (const RectanglePlacement& other) const noexcept -{ - return flags == other.flags; -} - -bool RectanglePlacement::operator!= (const RectanglePlacement& other) const noexcept -{ - return flags != other.flags; -} - -void RectanglePlacement::applyTo (double& x, double& y, double& w, double& h, - const double dx, const double dy, const double dw, const double dh) const noexcept -{ - if (w == 0 || h == 0) - return; - - if ((flags & stretchToFit) != 0) - { - x = dx; - y = dy; - w = dw; - h = dh; - } - else - { - double scale = (flags & fillDestination) != 0 ? jmax (dw / w, dh / h) - : jmin (dw / w, dh / h); - - if ((flags & onlyReduceInSize) != 0) - scale = jmin (scale, 1.0); - - if ((flags & onlyIncreaseInSize) != 0) - scale = jmax (scale, 1.0); - - w *= scale; - h *= scale; - - if ((flags & xLeft) != 0) - x = dx; - else if ((flags & xRight) != 0) - x = dx + dw - w; - else - x = dx + (dw - w) * 0.5; - - if ((flags & yTop) != 0) - y = dy; - else if ((flags & yBottom) != 0) - y = dy + dh - h; - else - y = dy + (dh - h) * 0.5; - } -} - -AffineTransform RectanglePlacement::getTransformToFit (const Rectangle& source, const Rectangle& destination) const noexcept -{ - if (source.isEmpty()) - return AffineTransform::identity; - - float newX = destination.getX(); - float newY = destination.getY(); - - float scaleX = destination.getWidth() / source.getWidth(); - float scaleY = destination.getHeight() / source.getHeight(); - - if ((flags & stretchToFit) == 0) - { - scaleX = (flags & fillDestination) != 0 ? jmax (scaleX, scaleY) - : jmin (scaleX, scaleY); - - if ((flags & onlyReduceInSize) != 0) - scaleX = jmin (scaleX, 1.0f); - - if ((flags & onlyIncreaseInSize) != 0) - scaleX = jmax (scaleX, 1.0f); - - scaleY = scaleX; - - if ((flags & xRight) != 0) - newX += destination.getWidth() - source.getWidth() * scaleX; // right - else if ((flags & xLeft) == 0) - newX += (destination.getWidth() - source.getWidth() * scaleX) / 2.0f; // centre - - if ((flags & yBottom) != 0) - newY += destination.getHeight() - source.getHeight() * scaleX; // bottom - else if ((flags & yTop) == 0) - newY += (destination.getHeight() - source.getHeight() * scaleX) / 2.0f; // centre - } - - return AffineTransform::translation (-source.getX(), -source.getY()) - .scaled (scaleX, scaleY) - .translated (newX, newY); -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/placement/juce_RectanglePlacement.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/placement/juce_RectanglePlacement.h deleted file mode 100644 index 9341e67428..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_graphics/placement/juce_RectanglePlacement.h +++ /dev/null @@ -1,172 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_RECTANGLEPLACEMENT_H_INCLUDED -#define JUCE_RECTANGLEPLACEMENT_H_INCLUDED - - -//============================================================================== -/** - Defines the method used to postion some kind of rectangular object within - a rectangular viewport. - - Although similar to Justification, this is more specific, and has some extra - options. -*/ -class JUCE_API RectanglePlacement -{ -public: - //============================================================================== - /** Creates a RectanglePlacement object using a combination of flags from the Flags enum. */ - inline RectanglePlacement (int placementFlags) noexcept : flags (placementFlags) {} - - /** Creates a default RectanglePlacement object, which is equivalent to using the 'centred' flag. */ - inline RectanglePlacement() noexcept : flags (centred) {} - - /** Creates a copy of another RectanglePlacement object. */ - RectanglePlacement (const RectanglePlacement&) noexcept; - - /** Copies another RectanglePlacement object. */ - RectanglePlacement& operator= (const RectanglePlacement&) noexcept; - - bool operator== (const RectanglePlacement&) const noexcept; - bool operator!= (const RectanglePlacement&) const noexcept; - - //============================================================================== - /** Flag values that can be combined and used in the constructor. */ - enum Flags - { - //============================================================================== - /** Indicates that the source rectangle's left edge should be aligned with the left edge of the target rectangle. */ - xLeft = 1, - - /** Indicates that the source rectangle's right edge should be aligned with the right edge of the target rectangle. */ - xRight = 2, - - /** Indicates that the source should be placed in the centre between the left and right - sides of the available space. */ - xMid = 4, - - //============================================================================== - /** Indicates that the source's top edge should be aligned with the top edge of the - destination rectangle. */ - yTop = 8, - - /** Indicates that the source's bottom edge should be aligned with the bottom edge of the - destination rectangle. */ - yBottom = 16, - - /** Indicates that the source should be placed in the centre between the top and bottom - sides of the available space. */ - yMid = 32, - - //============================================================================== - /** If this flag is set, then the source rectangle will be resized to completely fill - the destination rectangle, and all other flags are ignored. - */ - stretchToFit = 64, - - //============================================================================== - /** If this flag is set, then the source rectangle will be resized so that it is the - minimum size to completely fill the destination rectangle, without changing its - aspect ratio. This means that some of the source rectangle may fall outside - the destination. - - If this flag is not set, the source will be given the maximum size at which none - of it falls outside the destination rectangle. - */ - fillDestination = 128, - - /** Indicates that the source rectangle can be reduced in size if required, but should - never be made larger than its original size. - */ - onlyReduceInSize = 256, - - /** Indicates that the source rectangle can be enlarged if required, but should - never be made smaller than its original size. - */ - onlyIncreaseInSize = 512, - - /** Indicates that the source rectangle's size should be left unchanged. - */ - doNotResize = (onlyIncreaseInSize | onlyReduceInSize), - - //============================================================================== - /** A shorthand value that is equivalent to (xMid | yMid). */ - centred = 4 + 32 - }; - - //============================================================================== - /** Returns the raw flags that are set for this object. */ - inline int getFlags() const noexcept { return flags; } - - /** Tests a set of flags for this object. - - @returns true if any of the flags passed in are set on this object. - */ - inline bool testFlags (int flagsToTest) const noexcept { return (flags & flagsToTest) != 0; } - - - //============================================================================== - /** Adjusts the position and size of a rectangle to fit it into a space. - - The source rectangle coordinates will be adjusted so that they fit into - the destination rectangle based on this object's flags. - */ - void applyTo (double& sourceX, - double& sourceY, - double& sourceW, - double& sourceH, - double destinationX, - double destinationY, - double destinationW, - double destinationH) const noexcept; - - /** Returns the rectangle that should be used to fit the given source rectangle - into the destination rectangle using the current flags. - */ - template - Rectangle appliedTo (const Rectangle& source, - const Rectangle& destination) const noexcept - { - double x = source.getX(), y = source.getY(), w = source.getWidth(), h = source.getHeight(); - applyTo (x, y, w, h, static_cast (destination.getX()), static_cast (destination.getY()), - static_cast (destination.getWidth()), static_cast (destination.getHeight())); - return Rectangle (static_cast (x), static_cast (y), - static_cast (w), static_cast (h)); - } - - /** Returns the transform that should be applied to these source coordinates to fit them - into the destination rectangle using the current flags. - */ - AffineTransform getTransformToFit (const Rectangle& source, - const Rectangle& destination) const noexcept; - - -private: - //============================================================================== - int flags; -}; - -#endif // JUCE_RECTANGLEPLACEMENT_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/application/juce_Application.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/application/juce_Application.cpp deleted file mode 100644 index 4e21873168..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/application/juce_Application.cpp +++ /dev/null @@ -1,98 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -JUCEApplication::JUCEApplication() {} -JUCEApplication::~JUCEApplication() {} - -//============================================================================== -JUCEApplication* JUCE_CALLTYPE JUCEApplication::getInstance() noexcept -{ - return dynamic_cast (JUCEApplicationBase::getInstance()); -} - -bool JUCEApplication::moreThanOneInstanceAllowed() { return true; } -void JUCEApplication::anotherInstanceStarted (const String&) {} - -void JUCEApplication::suspended() {} -void JUCEApplication::resumed() {} - -void JUCEApplication::systemRequestedQuit() { quit(); } - -void JUCEApplication::unhandledException (const std::exception*, const String&, int) -{ - jassertfalse; -} - -//============================================================================== -ApplicationCommandTarget* JUCEApplication::getNextCommandTarget() -{ - return nullptr; -} - -void JUCEApplication::getAllCommands (Array& commands) -{ - commands.add (StandardApplicationCommandIDs::quit); -} - -void JUCEApplication::getCommandInfo (const CommandID commandID, ApplicationCommandInfo& result) -{ - if (commandID == StandardApplicationCommandIDs::quit) - { - result.setInfo (TRANS("Quit"), - TRANS("Quits the application"), - "Application", 0); - - result.defaultKeypresses.add (KeyPress ('q', ModifierKeys::commandModifier, 0)); - } -} - -bool JUCEApplication::perform (const InvocationInfo& info) -{ - if (info.commandID == StandardApplicationCommandIDs::quit) - { - systemRequestedQuit(); - return true; - } - - return false; -} - -//============================================================================== -#if JUCE_MAC - extern void juce_initialiseMacMainMenu(); -#endif - -bool JUCEApplication::initialiseApp() -{ - if (JUCEApplicationBase::initialiseApp()) - { - #if JUCE_MAC - juce_initialiseMacMainMenu(); // (needs to get the app's name) - #endif - - return true; - } - - return false; -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/application/juce_Application.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/application/juce_Application.h deleted file mode 100644 index 140cf9df21..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/application/juce_Application.h +++ /dev/null @@ -1,190 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_APPLICATION_H_INCLUDED -#define JUCE_APPLICATION_H_INCLUDED - - -//============================================================================== -/** - An instance of this class is used to specify initialisation and shutdown - code for the application. - - Any application that wants to run an event loop must declare a subclass of - JUCEApplicationBase or JUCEApplication, and implement its various pure virtual - methods. - - It then needs to use the START_JUCE_APPLICATION macro somewhere in a CPP file - to declare an instance of this class and generate suitable platform-specific - boilerplate code to launch the app. - - Note that this class is derived from JUCEApplicationBase, which contains most - of the useful methods and functionality. This derived class is here simply as - a convenient way to also inherit from an ApplicationCommandTarget, and to implement - default versions of some of the pure virtual base class methods. But you can derive - your app object directly from JUCEApplicationBase if you want to, and by doing so - can avoid having a dependency on the juce_gui_basics module. - - e.g. @code - class MyJUCEApp : public JUCEApplication - { - public: - MyJUCEApp() {} - ~MyJUCEApp() {} - - void initialise (const String& commandLine) override - { - myMainWindow = new MyApplicationWindow(); - myMainWindow->setBounds (100, 100, 400, 500); - myMainWindow->setVisible (true); - } - - void shutdown() override - { - myMainWindow = nullptr; - } - - const String getApplicationName() override - { - return "Super JUCE-o-matic"; - } - - const String getApplicationVersion() override - { - return "1.0"; - } - - private: - ScopedPointer myMainWindow; - }; - - // this generates boilerplate code to launch our app class: - START_JUCE_APPLICATION (MyJUCEApp) - @endcode - - @see JUCEApplicationBase, START_JUCE_APPLICATION -*/ -class JUCE_API JUCEApplication : public JUCEApplicationBase, - public ApplicationCommandTarget -{ -public: - //============================================================================== - /** Constructs a JUCE app object. - - If subclasses implement a constructor or destructor, they shouldn't call any - JUCE code in there - put your startup/shutdown code in initialise() and - shutdown() instead. - */ - JUCEApplication(); - - /** Destructor. - - If subclasses implement a constructor or destructor, they shouldn't call any - JUCE code in there - put your startup/shutdown code in initialise() and - shutdown() instead. - */ - ~JUCEApplication(); - - //============================================================================== - /** Returns the global instance of the application object being run. */ - static JUCEApplication* JUCE_CALLTYPE getInstance() noexcept; - - //============================================================================== - /** Returns the application's name. */ - virtual const String getApplicationName() = 0; - - /** Returns the application's version number. */ - virtual const String getApplicationVersion() = 0; - - /** Checks whether multiple instances of the app are allowed. - - If you application class returns true for this, more than one instance is - permitted to run (except on OSX where the OS automatically stops you launching - a second instance of an app without explicitly starting it from the command-line). - - If it's false, the second instance won't start, but it you will still get a - callback to anotherInstanceStarted() to tell you about this - which - gives you a chance to react to what the user was trying to do. - */ - bool moreThanOneInstanceAllowed() override; - - /** Indicates that the user has tried to start up another instance of the app. - This will get called even if moreThanOneInstanceAllowed() is false. - */ - void anotherInstanceStarted (const String& commandLine) override; - - /** Called when the operating system is trying to close the application. - - The default implementation of this method is to call quit(), but it may - be overloaded to ignore the request or do some other special behaviour - instead. For example, you might want to offer the user the chance to save - their changes before quitting, and give them the chance to cancel. - - If you want to send a quit signal to your app, this is the correct method - to call, because it means that requests that come from the system get handled - in the same way as those from your own application code. So e.g. you'd - call this method from a "quit" item on a menu bar. - */ - void systemRequestedQuit() override; - - /** This method is called when the application is being put into background mode - by the operating system. - */ - void suspended() override; - - /** This method is called when the application is being woken from background mode - by the operating system. - */ - void resumed() override; - - /** If any unhandled exceptions make it through to the message dispatch loop, this - callback will be triggered, in case you want to log them or do some other - type of error-handling. - - If the type of exception is derived from the std::exception class, the pointer - passed-in will be valid. If the exception is of unknown type, this pointer - will be null. - */ - void unhandledException (const std::exception* e, - const String& sourceFilename, - int lineNumber) override; - - //============================================================================== - /** @internal */ - ApplicationCommandTarget* getNextCommandTarget(); - /** @internal */ - void getCommandInfo (CommandID, ApplicationCommandInfo&); - /** @internal */ - void getAllCommands (Array&); - /** @internal */ - bool perform (const InvocationInfo&); - -private: - bool initialiseApp() override; - - JUCE_DECLARE_NON_COPYABLE (JUCEApplication) -}; - - -#endif // JUCE_APPLICATION_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/buttons/juce_ArrowButton.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/buttons/juce_ArrowButton.cpp deleted file mode 100644 index 75f8590c68..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/buttons/juce_ArrowButton.cpp +++ /dev/null @@ -1,45 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -ArrowButton::ArrowButton (const String& name, float arrowDirectionInRadians, Colour arrowColour) - : Button (name), colour (arrowColour) -{ - path.addTriangle (0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f); - path.applyTransform (AffineTransform::rotation (float_Pi * 2.0f * arrowDirectionInRadians, 0.5f, 0.5f)); -} - -ArrowButton::~ArrowButton() {} - -void ArrowButton::paintButton (Graphics& g, bool /*isMouseOverButton*/, bool isButtonDown) -{ - Path p (path); - - const float offset = isButtonDown ? 1.0f : 0.0f; - p.applyTransform (path.getTransformToScaleToFit (offset, offset, getWidth() - 3.0f, getHeight() - 3.0f, false)); - - DropShadow (Colours::black.withAlpha (0.3f), isButtonDown ? 2 : 4, Point()).drawForPath (g, p); - - g.setColour (colour); - g.fillPath (p); -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/buttons/juce_ArrowButton.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/buttons/juce_ArrowButton.h deleted file mode 100644 index 5d64123ab5..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/buttons/juce_ArrowButton.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_ARROWBUTTON_H_INCLUDED -#define JUCE_ARROWBUTTON_H_INCLUDED - - -//============================================================================== -/** - A button with an arrow in it. - - @see Button -*/ -class JUCE_API ArrowButton : public Button -{ -public: - //============================================================================== - /** Creates an ArrowButton. - - @param buttonName the name to give the button - @param arrowDirection the direction the arrow should point in, where 0.0 is - pointing right, 0.25 is down, 0.5 is left, 0.75 is up - @param arrowColour the colour to use for the arrow - */ - ArrowButton (const String& buttonName, - float arrowDirection, - Colour arrowColour); - - /** Destructor. */ - ~ArrowButton(); - - /** @internal */ - void paintButton (Graphics&, bool isMouseOverButton, bool isButtonDown) override; - -private: - Colour colour; - Path path; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ArrowButton) -}; - - -#endif // JUCE_ARROWBUTTON_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/buttons/juce_Button.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/buttons/juce_Button.cpp deleted file mode 100644 index 10d6e03f64..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/buttons/juce_Button.cpp +++ /dev/null @@ -1,674 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -class Button::CallbackHelper : public Timer, - public ApplicationCommandManagerListener, - public ValueListener, - public KeyListener -{ -public: - CallbackHelper (Button& b) : button (b) {} - - void timerCallback() override - { - button.repeatTimerCallback(); - } - - bool keyStateChanged (bool, Component*) override - { - return button.keyStateChangedCallback(); - } - - void valueChanged (Value& value) override - { - if (value.refersToSameSourceAs (button.isOn)) - button.setToggleState (button.isOn.getValue(), sendNotification); - } - - bool keyPressed (const KeyPress&, Component*) override - { - // returning true will avoid forwarding events for keys that we're using as shortcuts - return button.isShortcutPressed(); - } - - void applicationCommandInvoked (const ApplicationCommandTarget::InvocationInfo& info) override - { - if (info.commandID == button.commandID - && (info.commandFlags & ApplicationCommandInfo::dontTriggerVisualFeedback) == 0) - button.flashButtonState(); - } - - void applicationCommandListChanged() override - { - button.applicationCommandListChangeCallback(); - } - -private: - Button& button; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (CallbackHelper) -}; - -//============================================================================== -Button::Button (const String& name) - : Component (name), - text (name), - buttonPressTime (0), - lastRepeatTime (0), - commandManagerToUse (nullptr), - autoRepeatDelay (-1), - autoRepeatSpeed (0), - autoRepeatMinimumDelay (-1), - radioGroupId (0), - connectedEdgeFlags (0), - commandID(), - buttonState (buttonNormal), - lastToggleState (false), - clickTogglesState (false), - needsToRelease (false), - needsRepainting (false), - isKeyDown (false), - triggerOnMouseDown (false), - generateTooltip (false) -{ - callbackHelper = new CallbackHelper (*this); - - setWantsKeyboardFocus (true); - isOn.addListener (callbackHelper); -} - -Button::~Button() -{ - clearShortcuts(); - - if (commandManagerToUse != nullptr) - commandManagerToUse->removeListener (callbackHelper); - - isOn.removeListener (callbackHelper); - callbackHelper = nullptr; -} - -//============================================================================== -void Button::setButtonText (const String& newText) -{ - if (text != newText) - { - text = newText; - repaint(); - } -} - -void Button::setTooltip (const String& newTooltip) -{ - SettableTooltipClient::setTooltip (newTooltip); - generateTooltip = false; -} - -void Button::updateAutomaticTooltip (const ApplicationCommandInfo& info) -{ - if (generateTooltip && commandManagerToUse != nullptr) - { - String tt (info.description.isNotEmpty() ? info.description - : info.shortName); - - Array keyPresses (commandManagerToUse->getKeyMappings()->getKeyPressesAssignedToCommand (commandID)); - - for (int i = 0; i < keyPresses.size(); ++i) - { - const String key (keyPresses.getReference(i).getTextDescription()); - - tt << " ["; - - if (key.length() == 1) - tt << TRANS("shortcut") << ": '" << key << "']"; - else - tt << key << ']'; - } - - SettableTooltipClient::setTooltip (tt); - } -} - -void Button::setConnectedEdges (const int newFlags) -{ - if (connectedEdgeFlags != newFlags) - { - connectedEdgeFlags = newFlags; - repaint(); - } -} - -//============================================================================== -void Button::setToggleState (const bool shouldBeOn, const NotificationType notification) -{ - if (shouldBeOn != lastToggleState) - { - WeakReference deletionWatcher (this); - - if (shouldBeOn) - { - turnOffOtherButtonsInGroup (notification); - - if (deletionWatcher == nullptr) - return; - } - - if (getToggleState() != shouldBeOn) // this test means that if the value is void rather than explicitly set to - isOn = shouldBeOn; // false, it won't be changed unless the required value is true. - - lastToggleState = shouldBeOn; - repaint(); - - if (notification != dontSendNotification) - { - // async callbacks aren't possible here - jassert (notification != sendNotificationAsync); - - sendClickMessage (ModifierKeys::getCurrentModifiers()); - - if (deletionWatcher == nullptr) - return; - } - - if (notification != dontSendNotification) - sendStateMessage(); - else - buttonStateChanged(); - } -} - -void Button::setToggleState (const bool shouldBeOn, bool sendChange) -{ - setToggleState (shouldBeOn, sendChange ? sendNotification : dontSendNotification); -} - -void Button::setClickingTogglesState (const bool shouldToggle) noexcept -{ - clickTogglesState = shouldToggle; - - // if you've got clickTogglesState turned on, you shouldn't also connect the button - // up to be a command invoker. Instead, your command handler must flip the state of whatever - // it is that this button represents, and the button will update its state to reflect this - // in the applicationCommandListChanged() method. - jassert (commandManagerToUse == nullptr || ! clickTogglesState); -} - -bool Button::getClickingTogglesState() const noexcept -{ - return clickTogglesState; -} - -void Button::setRadioGroupId (const int newGroupId, NotificationType notification) -{ - if (radioGroupId != newGroupId) - { - radioGroupId = newGroupId; - - if (lastToggleState) - turnOffOtherButtonsInGroup (notification); - } -} - -void Button::turnOffOtherButtonsInGroup (const NotificationType notification) -{ - if (Component* const p = getParentComponent()) - { - if (radioGroupId != 0) - { - WeakReference deletionWatcher (this); - - for (int i = p->getNumChildComponents(); --i >= 0;) - { - Component* const c = p->getChildComponent (i); - - if (c != this) - { - if (Button* const b = dynamic_cast (c)) - { - if (b->getRadioGroupId() == radioGroupId) - { - b->setToggleState (false, notification); - - if (deletionWatcher == nullptr) - return; - } - } - } - } - } - } -} - -//============================================================================== -void Button::enablementChanged() -{ - updateState(); - repaint(); -} - -Button::ButtonState Button::updateState() -{ - return updateState (isMouseOver (true), isMouseButtonDown()); -} - -Button::ButtonState Button::updateState (const bool over, const bool down) -{ - ButtonState newState = buttonNormal; - - if (isEnabled() && isVisible() && ! isCurrentlyBlockedByAnotherModalComponent()) - { - if ((down && (over || (triggerOnMouseDown && buttonState == buttonDown))) || isKeyDown) - newState = buttonDown; - else if (over) - newState = buttonOver; - } - - setState (newState); - return newState; -} - -void Button::setState (const ButtonState newState) -{ - if (buttonState != newState) - { - buttonState = newState; - repaint(); - - if (buttonState == buttonDown) - { - buttonPressTime = Time::getApproximateMillisecondCounter(); - lastRepeatTime = 0; - } - - sendStateMessage(); - } -} - -bool Button::isDown() const noexcept { return buttonState == buttonDown; } -bool Button::isOver() const noexcept { return buttonState != buttonNormal; } - -void Button::buttonStateChanged() {} - -uint32 Button::getMillisecondsSinceButtonDown() const noexcept -{ - const uint32 now = Time::getApproximateMillisecondCounter(); - return now > buttonPressTime ? now - buttonPressTime : 0; -} - -void Button::setTriggeredOnMouseDown (const bool isTriggeredOnMouseDown) noexcept -{ - triggerOnMouseDown = isTriggeredOnMouseDown; -} - -//============================================================================== -void Button::clicked() -{ -} - -void Button::clicked (const ModifierKeys&) -{ - clicked(); -} - -enum { clickMessageId = 0x2f3f4f99 }; - -void Button::triggerClick() -{ - postCommandMessage (clickMessageId); -} - -void Button::internalClickCallback (const ModifierKeys& modifiers) -{ - if (clickTogglesState) - { - const bool shouldBeOn = (radioGroupId != 0 || ! lastToggleState); - - if (shouldBeOn != getToggleState()) - { - setToggleState (shouldBeOn, sendNotification); - return; - } - } - - sendClickMessage (modifiers); -} - -void Button::flashButtonState() -{ - if (isEnabled()) - { - needsToRelease = true; - setState (buttonDown); - callbackHelper->startTimer (100); - } -} - -void Button::handleCommandMessage (int commandId) -{ - if (commandId == clickMessageId) - { - if (isEnabled()) - { - flashButtonState(); - internalClickCallback (ModifierKeys::getCurrentModifiers()); - } - } - else - { - Component::handleCommandMessage (commandId); - } -} - -//============================================================================== -void Button::addListener (ButtonListener* const newListener) -{ - buttonListeners.add (newListener); -} - -void Button::removeListener (ButtonListener* const listener) -{ - buttonListeners.remove (listener); -} - -void Button::sendClickMessage (const ModifierKeys& modifiers) -{ - Component::BailOutChecker checker (this); - - if (commandManagerToUse != nullptr && commandID != 0) - { - ApplicationCommandTarget::InvocationInfo info (commandID); - info.invocationMethod = ApplicationCommandTarget::InvocationInfo::fromButton; - info.originatingComponent = this; - - commandManagerToUse->invoke (info, true); - } - - clicked (modifiers); - - if (! checker.shouldBailOut()) - buttonListeners.callChecked (checker, &ButtonListener::buttonClicked, this); // (can't use Button::Listener due to idiotic VC2005 bug) -} - -void Button::sendStateMessage() -{ - Component::BailOutChecker checker (this); - - buttonStateChanged(); - - if (! checker.shouldBailOut()) - buttonListeners.callChecked (checker, &ButtonListener::buttonStateChanged, this); -} - -//============================================================================== -void Button::paint (Graphics& g) -{ - if (needsToRelease && isEnabled()) - { - needsToRelease = false; - needsRepainting = true; - } - - paintButton (g, isOver(), isDown()); -} - -//============================================================================== -void Button::mouseEnter (const MouseEvent&) { updateState (true, false); } -void Button::mouseExit (const MouseEvent&) { updateState (false, false); } - -void Button::mouseDown (const MouseEvent& e) -{ - updateState (true, true); - - if (isDown()) - { - if (autoRepeatDelay >= 0) - callbackHelper->startTimer (autoRepeatDelay); - - if (triggerOnMouseDown) - internalClickCallback (e.mods); - } -} - -void Button::mouseUp (const MouseEvent& e) -{ - const bool wasDown = isDown(); - const bool wasOver = isOver(); - updateState (isMouseOver(), false); - - if (wasDown && wasOver && ! triggerOnMouseDown) - internalClickCallback (e.mods); -} - -void Button::mouseDrag (const MouseEvent&) -{ - const ButtonState oldState = buttonState; - updateState (isMouseOver(), true); - - if (autoRepeatDelay >= 0 && buttonState != oldState && isDown()) - callbackHelper->startTimer (autoRepeatSpeed); -} - -void Button::focusGained (FocusChangeType) -{ - updateState(); - repaint(); -} - -void Button::focusLost (FocusChangeType) -{ - updateState(); - repaint(); -} - -void Button::visibilityChanged() -{ - needsToRelease = false; - updateState(); -} - -void Button::parentHierarchyChanged() -{ - Component* const newKeySource = (shortcuts.size() == 0) ? nullptr : getTopLevelComponent(); - - if (newKeySource != keySource.get()) - { - if (keySource != nullptr) - keySource->removeKeyListener (callbackHelper); - - keySource = newKeySource; - - if (keySource != nullptr) - keySource->addKeyListener (callbackHelper); - } -} - -//============================================================================== -void Button::setCommandToTrigger (ApplicationCommandManager* const newCommandManager, - const CommandID newCommandID, const bool generateTip) -{ - commandID = newCommandID; - generateTooltip = generateTip; - - if (commandManagerToUse != newCommandManager) - { - if (commandManagerToUse != nullptr) - commandManagerToUse->removeListener (callbackHelper); - - commandManagerToUse = newCommandManager; - - if (commandManagerToUse != nullptr) - commandManagerToUse->addListener (callbackHelper); - - // if you've got clickTogglesState turned on, you shouldn't also connect the button - // up to be a command invoker. Instead, your command handler must flip the state of whatever - // it is that this button represents, and the button will update its state to reflect this - // in the applicationCommandListChanged() method. - jassert (commandManagerToUse == nullptr || ! clickTogglesState); - } - - if (commandManagerToUse != nullptr) - applicationCommandListChangeCallback(); - else - setEnabled (true); -} - -void Button::applicationCommandListChangeCallback() -{ - if (commandManagerToUse != nullptr) - { - ApplicationCommandInfo info (0); - - if (commandManagerToUse->getTargetForCommand (commandID, info) != nullptr) - { - updateAutomaticTooltip (info); - setEnabled ((info.flags & ApplicationCommandInfo::isDisabled) == 0); - setToggleState ((info.flags & ApplicationCommandInfo::isTicked) != 0, dontSendNotification); - } - else - { - setEnabled (false); - } - } -} - -//============================================================================== -void Button::addShortcut (const KeyPress& key) -{ - if (key.isValid()) - { - jassert (! isRegisteredForShortcut (key)); // already registered! - - shortcuts.add (key); - parentHierarchyChanged(); - } -} - -void Button::clearShortcuts() -{ - shortcuts.clear(); - parentHierarchyChanged(); -} - -bool Button::isShortcutPressed() const -{ - if (isShowing() && ! isCurrentlyBlockedByAnotherModalComponent()) - for (int i = shortcuts.size(); --i >= 0;) - if (shortcuts.getReference(i).isCurrentlyDown()) - return true; - - return false; -} - -bool Button::isRegisteredForShortcut (const KeyPress& key) const -{ - for (int i = shortcuts.size(); --i >= 0;) - if (key == shortcuts.getReference(i)) - return true; - - return false; -} - -bool Button::keyStateChangedCallback() -{ - if (! isEnabled()) - return false; - - const bool wasDown = isKeyDown; - isKeyDown = isShortcutPressed(); - - if (autoRepeatDelay >= 0 && (isKeyDown && ! wasDown)) - callbackHelper->startTimer (autoRepeatDelay); - - updateState(); - - if (isEnabled() && wasDown && ! isKeyDown) - { - internalClickCallback (ModifierKeys::getCurrentModifiers()); - - // (return immediately - this button may now have been deleted) - return true; - } - - return wasDown || isKeyDown; -} - -bool Button::keyPressed (const KeyPress& key) -{ - if (isEnabled() && key.isKeyCode (KeyPress::returnKey)) - { - triggerClick(); - return true; - } - - return false; -} - -//============================================================================== -void Button::setRepeatSpeed (const int initialDelayMillisecs, - const int repeatMillisecs, - const int minimumDelayInMillisecs) noexcept -{ - autoRepeatDelay = initialDelayMillisecs; - autoRepeatSpeed = repeatMillisecs; - autoRepeatMinimumDelay = jmin (autoRepeatSpeed, minimumDelayInMillisecs); -} - -void Button::repeatTimerCallback() -{ - if (needsRepainting) - { - callbackHelper->stopTimer(); - updateState(); - needsRepainting = false; - } - else if (autoRepeatSpeed > 0 && (isKeyDown || (updateState() == buttonDown))) - { - int repeatSpeed = autoRepeatSpeed; - - if (autoRepeatMinimumDelay >= 0) - { - double timeHeldDown = jmin (1.0, getMillisecondsSinceButtonDown() / 4000.0); - timeHeldDown *= timeHeldDown; - - repeatSpeed = repeatSpeed + (int) (timeHeldDown * (autoRepeatMinimumDelay - repeatSpeed)); - } - - repeatSpeed = jmax (1, repeatSpeed); - - const uint32 now = Time::getMillisecondCounter(); - - // if we've been blocked from repeating often enough, speed up the repeat timer to compensate.. - if (lastRepeatTime != 0 && (int) (now - lastRepeatTime) > repeatSpeed * 2) - repeatSpeed = jmax (1, repeatSpeed / 2); - - lastRepeatTime = now; - callbackHelper->startTimer (repeatSpeed); - - internalClickCallback (ModifierKeys::getCurrentModifiers()); - } - else if (! needsToRelease) - { - callbackHelper->stopTimer(); - } -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/buttons/juce_Button.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/buttons/juce_Button.h deleted file mode 100644 index a58342d563..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/buttons/juce_Button.h +++ /dev/null @@ -1,514 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_BUTTON_H_INCLUDED -#define JUCE_BUTTON_H_INCLUDED - - -//============================================================================== -/** - A base class for buttons. - - This contains all the logic for button behaviours such as enabling/disabling, - responding to shortcut keystrokes, auto-repeating when held down, toggle-buttons - and radio groups, etc. - - @see TextButton, DrawableButton, ToggleButton -*/ -class JUCE_API Button : public Component, - public SettableTooltipClient -{ -protected: - //============================================================================== - /** Creates a button. - - @param buttonName the text to put in the button (the component's name is also - initially set to this string, but these can be changed later - using the setName() and setButtonText() methods) - */ - explicit Button (const String& buttonName); - -public: - /** Destructor. */ - virtual ~Button(); - - //============================================================================== - /** Changes the button's text. - @see getButtonText - */ - void setButtonText (const String& newText); - - /** Returns the text displayed in the button. - @see setButtonText - */ - const String& getButtonText() const { return text; } - - //============================================================================== - /** Returns true if the button is currently being held down. - @see isOver - */ - bool isDown() const noexcept; - - /** Returns true if the mouse is currently over the button. - This will be also be true if the button is being held down. - @see isDown - */ - bool isOver() const noexcept; - - //============================================================================== - /** A button has an on/off state associated with it, and this changes that. - - By default buttons are 'off' and for simple buttons that you click to perform - an action you won't change this. Toggle buttons, however will want to - change their state when turned on or off. - - @param shouldBeOn whether to set the button's toggle state to be on or - off. If it's a member of a button group, this will - always try to turn it on, and to turn off any other - buttons in the group - @param notification determines the behaviour if the value changes - this - can invoke a synchronous call to clicked(), but - sendNotificationAsync is not supported - @see getToggleState, setRadioGroupId - */ - void setToggleState (bool shouldBeOn, NotificationType notification); - - /** Returns true if the button is 'on'. - - By default buttons are 'off' and for simple buttons that you click to perform - an action you won't change this. Toggle buttons, however will want to - change their state when turned on or off. - - @see setToggleState - */ - bool getToggleState() const noexcept { return isOn.getValue(); } - - /** Returns the Value object that represents the botton's toggle state. - You can use this Value object to connect the button's state to external values or setters, - either by taking a copy of the Value, or by using Value::referTo() to make it point to - your own Value object. - @see getToggleState, Value - */ - Value& getToggleStateValue() noexcept { return isOn; } - - /** This tells the button to automatically flip the toggle state when - the button is clicked. - - If set to true, then before the clicked() callback occurs, the toggle-state - of the button is flipped. - */ - void setClickingTogglesState (bool shouldAutoToggleOnClick) noexcept; - - /** Returns true if this button is set to be an automatic toggle-button. - This returns the last value that was passed to setClickingTogglesState(). - */ - bool getClickingTogglesState() const noexcept; - - //============================================================================== - /** Enables the button to act as a member of a mutually-exclusive group - of 'radio buttons'. - - If the group ID is set to a non-zero number, then this button will - act as part of a group of buttons with the same ID, only one of - which can be 'on' at the same time. Note that when it's part of - a group, clicking a toggle-button that's 'on' won't turn it off. - - To find other buttons with the same ID, this button will search through - its sibling components for ToggleButtons, so all the buttons for a - particular group must be placed inside the same parent component. - - Set the group ID back to zero if you want it to act as a normal toggle - button again. - - The notification argument lets you specify how other buttons should react - to being turned on or off in response to this call. - - @see getRadioGroupId - */ - void setRadioGroupId (int newGroupId, NotificationType notification = sendNotification); - - /** Returns the ID of the group to which this button belongs. - (See setRadioGroupId() for an explanation of this). - */ - int getRadioGroupId() const noexcept { return radioGroupId; } - - //============================================================================== - /** - Used to receive callbacks when a button is clicked. - - @see Button::addListener, Button::removeListener - */ - class JUCE_API Listener - { - public: - /** Destructor. */ - virtual ~Listener() {} - - /** Called when the button is clicked. */ - virtual void buttonClicked (Button*) = 0; - - /** Called when the button's state changes. */ - virtual void buttonStateChanged (Button*) {} - }; - - /** Registers a listener to receive events when this button's state changes. - If the listener is already registered, this will not register it again. - @see removeListener - */ - void addListener (Listener* newListener); - - /** Removes a previously-registered button listener - @see addListener - */ - void removeListener (Listener* listener); - - //============================================================================== - /** Causes the button to act as if it's been clicked. - - This will asynchronously make the button draw itself going down and up, and - will then call back the clicked() method as if mouse was clicked on it. - - @see clicked - */ - virtual void triggerClick(); - - //============================================================================== - /** Sets a command ID for this button to automatically invoke when it's clicked. - - When the button is pressed, it will use the given manager to trigger the - command ID. - - Obviously be careful that the ApplicationCommandManager doesn't get deleted - before this button is. To disable the command triggering, call this method and - pass nullptr as the command manager. - - If generateTooltip is true, then the button's tooltip will be automatically - generated based on the name of this command and its current shortcut key. - - @see addShortcut, getCommandID - */ - void setCommandToTrigger (ApplicationCommandManager* commandManagerToUse, - CommandID commandID, - bool generateTooltip); - - /** Returns the command ID that was set by setCommandToTrigger(). */ - CommandID getCommandID() const noexcept { return commandID; } - - //============================================================================== - /** Assigns a shortcut key to trigger the button. - - The button registers itself with its top-level parent component for keypresses. - - Note that a different way of linking buttons to keypresses is by using the - setCommandToTrigger() method to invoke a command. - - @see clearShortcuts - */ - void addShortcut (const KeyPress&); - - /** Removes all key shortcuts that had been set for this button. - @see addShortcut - */ - void clearShortcuts(); - - /** Returns true if the given keypress is a shortcut for this button. - @see addShortcut - */ - bool isRegisteredForShortcut (const KeyPress&) const; - - //============================================================================== - /** Sets an auto-repeat speed for the button when it is held down. - - (Auto-repeat is disabled by default). - - @param initialDelayInMillisecs how long to wait after the mouse is pressed before - triggering the next click. If this is zero, auto-repeat - is disabled - @param repeatDelayInMillisecs the frequently subsequent repeated clicks should be - triggered - @param minimumDelayInMillisecs if this is greater than 0, the auto-repeat speed will - get faster, the longer the button is held down, up to the - minimum interval specified here - */ - void setRepeatSpeed (int initialDelayInMillisecs, - int repeatDelayInMillisecs, - int minimumDelayInMillisecs = -1) noexcept; - - /** Sets whether the button click should happen when the mouse is pressed or released. - - By default the button is only considered to have been clicked when the mouse is - released, but setting this to true will make it call the clicked() method as soon - as the button is pressed. - - This is useful if the button is being used to show a pop-up menu, as it allows - the click to be used as a drag onto the menu. - */ - void setTriggeredOnMouseDown (bool isTriggeredOnMouseDown) noexcept; - - /** Returns the number of milliseconds since the last time the button - went into the 'down' state. - */ - uint32 getMillisecondsSinceButtonDown() const noexcept; - - //============================================================================== - /** Sets the tooltip for this button. - @see TooltipClient, TooltipWindow - */ - void setTooltip (const String& newTooltip) override; - - //============================================================================== - /** A combination of these flags are used by setConnectedEdges(). */ - enum ConnectedEdgeFlags - { - ConnectedOnLeft = 1, - ConnectedOnRight = 2, - ConnectedOnTop = 4, - ConnectedOnBottom = 8 - }; - - /** Hints about which edges of the button might be connected to adjoining buttons. - - The value passed in is a bitwise combination of any of the values in the - ConnectedEdgeFlags enum. - - E.g. if you are placing two buttons adjacent to each other, you could use this to - indicate which edges are touching, and the LookAndFeel might choose to drawn them - without rounded corners on the edges that connect. It's only a hint, so the - LookAndFeel can choose to ignore it if it's not relevent for this type of - button. - */ - void setConnectedEdges (int connectedEdgeFlags); - - /** Returns the set of flags passed into setConnectedEdges(). */ - int getConnectedEdgeFlags() const noexcept { return connectedEdgeFlags; } - - /** Indicates whether the button adjoins another one on its left edge. - @see setConnectedEdges - */ - bool isConnectedOnLeft() const noexcept { return (connectedEdgeFlags & ConnectedOnLeft) != 0; } - - /** Indicates whether the button adjoins another one on its right edge. - @see setConnectedEdges - */ - bool isConnectedOnRight() const noexcept { return (connectedEdgeFlags & ConnectedOnRight) != 0; } - - /** Indicates whether the button adjoins another one on its top edge. - @see setConnectedEdges - */ - bool isConnectedOnTop() const noexcept { return (connectedEdgeFlags & ConnectedOnTop) != 0; } - - /** Indicates whether the button adjoins another one on its bottom edge. - @see setConnectedEdges - */ - bool isConnectedOnBottom() const noexcept { return (connectedEdgeFlags & ConnectedOnBottom) != 0; } - - - //============================================================================== - /** Used by setState(). */ - enum ButtonState - { - buttonNormal, - buttonOver, - buttonDown - }; - - /** Can be used to force the button into a particular state. - - This only changes the button's appearance, it won't trigger a click, or stop any mouse-clicks - from happening. - - The state that you set here will only last until it is automatically changed when the mouse - enters or exits the button, or the mouse-button is pressed or released. - */ - void setState (ButtonState newState); - - /** Returns the button's current over/down/up state. */ - ButtonState getState() const noexcept { return buttonState; } - - // This method's parameters have changed - see the new version. - JUCE_DEPRECATED (void setToggleState (bool, bool)); - - //============================================================================== - /** This abstract base class is implemented by LookAndFeel classes to provide - button-drawing functionality. - */ - struct JUCE_API LookAndFeelMethods - { - virtual ~LookAndFeelMethods() {} - - virtual void drawButtonBackground (Graphics&, Button&, const Colour& backgroundColour, - bool isMouseOverButton, bool isButtonDown) = 0; - - virtual Font getTextButtonFont (TextButton&, int buttonHeight) = 0; - virtual int getTextButtonWidthToFitText (TextButton&, int buttonHeight) = 0; - - /** Draws the text for a TextButton. */ - virtual void drawButtonText (Graphics&, TextButton&, bool isMouseOverButton, bool isButtonDown) = 0; - - /** Draws the contents of a standard ToggleButton. */ - virtual void drawToggleButton (Graphics&, ToggleButton&, bool isMouseOverButton, bool isButtonDown) = 0; - - virtual void changeToggleButtonWidthToFitText (ToggleButton&) = 0; - - virtual void drawTickBox (Graphics&, Component&, float x, float y, float w, float h, - bool ticked, bool isEnabled, bool isMouseOverButton, bool isButtonDown) = 0; - - virtual void drawDrawableButton (Graphics&, DrawableButton&, bool isMouseOverButton, bool isButtonDown) = 0; - - private: - #if JUCE_CATCH_DEPRECATED_CODE_MISUSE - // These method have been deprecated: see their replacements above. - virtual int getTextButtonFont (TextButton&) { return 0; } - virtual int changeTextButtonWidthToFitText (TextButton&, int) { return 0; } - #endif - }; - -protected: - //============================================================================== - /** This method is called when the button has been clicked. - - Subclasses can override this to perform whatever they actions they need - to do. - - Alternatively, a ButtonListener can be added to the button, and these listeners - will be called when the click occurs. - - @see triggerClick - */ - virtual void clicked(); - - /** This method is called when the button has been clicked. - - By default it just calls clicked(), but you might want to override it to handle - things like clicking when a modifier key is pressed, etc. - - @see ModifierKeys - */ - virtual void clicked (const ModifierKeys& modifiers); - - /** Subclasses should override this to actually paint the button's contents. - - It's better to use this than the paint method, because it gives you information - about the over/down state of the button. - - @param g the graphics context to use - @param isMouseOverButton true if the button is either in the 'over' or - 'down' state - @param isButtonDown true if the button should be drawn in the 'down' position - */ - virtual void paintButton (Graphics& g, - bool isMouseOverButton, - bool isButtonDown) = 0; - - /** Called when the button's up/down/over state changes. - - Subclasses can override this if they need to do something special when the button - goes up or down. - - @see isDown, isOver - */ - virtual void buttonStateChanged(); - - //============================================================================== - /** @internal */ - virtual void internalClickCallback (const ModifierKeys&); - /** @internal */ - void handleCommandMessage (int commandId) override; - /** @internal */ - void mouseEnter (const MouseEvent&) override; - /** @internal */ - void mouseExit (const MouseEvent&) override; - /** @internal */ - void mouseDown (const MouseEvent&) override; - /** @internal */ - void mouseDrag (const MouseEvent&) override; - /** @internal */ - void mouseUp (const MouseEvent&) override; - /** @internal */ - bool keyPressed (const KeyPress&) override; - /** @internal */ - using Component::keyStateChanged; - /** @internal */ - void paint (Graphics&) override; - /** @internal */ - void parentHierarchyChanged() override; - /** @internal */ - void visibilityChanged() override; - /** @internal */ - void focusGained (FocusChangeType) override; - /** @internal */ - void focusLost (FocusChangeType) override; - /** @internal */ - void enablementChanged() override; - -private: - //============================================================================== - Array shortcuts; - WeakReference keySource; - String text; - ListenerList buttonListeners; - - class CallbackHelper; - friend class CallbackHelper; - friend struct ContainerDeletePolicy; - ScopedPointer callbackHelper; - uint32 buttonPressTime, lastRepeatTime; - ApplicationCommandManager* commandManagerToUse; - int autoRepeatDelay, autoRepeatSpeed, autoRepeatMinimumDelay; - int radioGroupId, connectedEdgeFlags; - CommandID commandID; - ButtonState buttonState; - - Value isOn; - bool lastToggleState; - bool clickTogglesState; - bool needsToRelease; - bool needsRepainting; - bool isKeyDown; - bool triggerOnMouseDown; - bool generateTooltip; - - void repeatTimerCallback(); - bool keyStateChangedCallback(); - void applicationCommandListChangeCallback(); - void updateAutomaticTooltip (const ApplicationCommandInfo&); - - ButtonState updateState(); - ButtonState updateState (bool isOver, bool isDown); - bool isShortcutPressed() const; - void turnOffOtherButtonsInGroup (NotificationType); - - void flashButtonState(); - void sendClickMessage (const ModifierKeys&); - void sendStateMessage(); - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Button) -}; - -#ifndef DOXYGEN - /** This typedef is just for compatibility with old code and VC6 - newer code should use Button::Listener instead. */ - typedef Button::Listener ButtonListener; -#endif - -#endif // JUCE_BUTTON_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/buttons/juce_DrawableButton.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/buttons/juce_DrawableButton.cpp deleted file mode 100644 index 83e9c893f4..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/buttons/juce_DrawableButton.cpp +++ /dev/null @@ -1,221 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -DrawableButton::DrawableButton (const String& name, const DrawableButton::ButtonStyle buttonStyle) - : Button (name), - style (buttonStyle), - currentImage (nullptr), - edgeIndent (3) -{ -} - -DrawableButton::~DrawableButton() -{ -} - -//============================================================================== -static Drawable* copyDrawableIfNotNull (const Drawable* const d) -{ - return d != nullptr ? d->createCopy() : nullptr; -} - -void DrawableButton::setImages (const Drawable* normal, - const Drawable* over, - const Drawable* down, - const Drawable* disabled, - const Drawable* normalOn, - const Drawable* overOn, - const Drawable* downOn, - const Drawable* disabledOn) -{ - jassert (normal != nullptr); // you really need to give it at least a normal image.. - - normalImage = copyDrawableIfNotNull (normal); - overImage = copyDrawableIfNotNull (over); - downImage = copyDrawableIfNotNull (down); - disabledImage = copyDrawableIfNotNull (disabled); - normalImageOn = copyDrawableIfNotNull (normalOn); - overImageOn = copyDrawableIfNotNull (overOn); - downImageOn = copyDrawableIfNotNull (downOn); - disabledImageOn = copyDrawableIfNotNull (disabledOn); - - buttonStateChanged(); -} - -//============================================================================== -void DrawableButton::setButtonStyle (const DrawableButton::ButtonStyle newStyle) -{ - if (style != newStyle) - { - style = newStyle; - buttonStateChanged(); - } -} - -void DrawableButton::setEdgeIndent (const int numPixelsIndent) -{ - edgeIndent = numPixelsIndent; - repaint(); - resized(); -} - -Rectangle DrawableButton::getImageBounds() const -{ - Rectangle r (getLocalBounds()); - - if (style != ImageStretched) - { - int indentX = jmin (edgeIndent, proportionOfWidth (0.3f)); - int indentY = jmin (edgeIndent, proportionOfHeight (0.3f)); - - if (style == ImageOnButtonBackground) - { - indentX = jmax (getWidth() / 4, indentX); - indentY = jmax (getHeight() / 4, indentY); - } - else if (style == ImageAboveTextLabel) - { - r = r.withTrimmedBottom (jmin (16, proportionOfHeight (0.25f))); - } - - r = r.reduced (indentX, indentY); - } - - return r.toFloat(); -} - -void DrawableButton::resized() -{ - Button::resized(); - - if (currentImage != nullptr) - { - if (style == ImageRaw) - currentImage->setOriginWithOriginalSize (Point()); - else - currentImage->setTransformToFit (getImageBounds(), - style == ImageStretched ? RectanglePlacement::stretchToFit - : RectanglePlacement::centred); - } -} - -void DrawableButton::buttonStateChanged() -{ - repaint(); - - Drawable* imageToDraw = nullptr; - float opacity = 1.0f; - - if (isEnabled()) - { - imageToDraw = getCurrentImage(); - } - else - { - imageToDraw = getToggleState() ? disabledImageOn - : disabledImage; - - if (imageToDraw == nullptr) - { - opacity = 0.4f; - imageToDraw = getNormalImage(); - } - } - - if (imageToDraw != currentImage) - { - removeChildComponent (currentImage); - currentImage = imageToDraw; - - if (currentImage != nullptr) - { - currentImage->setInterceptsMouseClicks (false, false); - addAndMakeVisible (currentImage); - resized(); - } - } - - if (currentImage != nullptr) - currentImage->setAlpha (opacity); -} - -void DrawableButton::enablementChanged() -{ - Button::enablementChanged(); - buttonStateChanged(); -} - -void DrawableButton::colourChanged() -{ - repaint(); -} - -void DrawableButton::paintButton (Graphics& g, - const bool isMouseOverButton, - const bool isButtonDown) -{ - LookAndFeel& lf = getLookAndFeel(); - - if (style == ImageOnButtonBackground) - lf.drawButtonBackground (g, *this, - findColour (getToggleState() ? TextButton::buttonOnColourId - : TextButton::buttonColourId), - isMouseOverButton, isButtonDown); - else - lf.drawDrawableButton (g, *this, isMouseOverButton, isButtonDown); -} - -//============================================================================== -Drawable* DrawableButton::getCurrentImage() const noexcept -{ - if (isDown()) return getDownImage(); - if (isOver()) return getOverImage(); - - return getNormalImage(); -} - -Drawable* DrawableButton::getNormalImage() const noexcept -{ - return (getToggleState() && normalImageOn != nullptr) ? normalImageOn - : normalImage; -} - -Drawable* DrawableButton::getOverImage() const noexcept -{ - if (getToggleState()) - { - if (overImageOn != nullptr) return overImageOn; - if (normalImageOn != nullptr) return normalImageOn; - } - - return overImage != nullptr ? overImage : normalImage; -} - -Drawable* DrawableButton::getDownImage() const noexcept -{ - if (Drawable* const d = getToggleState() ? downImageOn : downImage) - return d; - - return getOverImage(); -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/buttons/juce_DrawableButton.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/buttons/juce_DrawableButton.h deleted file mode 100644 index f07616fd11..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/buttons/juce_DrawableButton.h +++ /dev/null @@ -1,188 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_DRAWABLEBUTTON_H_INCLUDED -#define JUCE_DRAWABLEBUTTON_H_INCLUDED - - -//============================================================================== -/** - A button that displays a Drawable. - - Up to three Drawable objects can be given to this button, to represent the - 'normal', 'over' and 'down' states. - - @see Button -*/ -class JUCE_API DrawableButton : public Button -{ -public: - //============================================================================== - enum ButtonStyle - { - ImageFitted, /**< The button will just display the images, but will resize and centre them to fit inside it. */ - ImageRaw, /**< The button will just display the images in their normal size and position. - This leaves it up to the caller to make sure the images are the correct size and position for the button. */ - ImageAboveTextLabel, /**< Draws the button as a text label across the bottom with the image resized and scaled to fit above it. */ - ImageOnButtonBackground, /**< Draws the button as a standard rounded-rectangle button with the image on top. - Note that if you use this style, the colour IDs that control the button colour are - TextButton::buttonColourId and TextButton::buttonOnColourId. */ - ImageStretched /**< Fills the button with a stretched version of the image. */ - }; - - //============================================================================== - /** Creates a DrawableButton. - - After creating one of these, use setImages() to specify the drawables to use. - - @param buttonName the name to give the component - @param buttonStyle the layout to use - - @see ButtonStyle, setButtonStyle, setImages - */ - DrawableButton (const String& buttonName, - ButtonStyle buttonStyle); - - /** Destructor. */ - ~DrawableButton(); - - //============================================================================== - /** Sets up the images to draw for the various button states. - - The button will keep its own internal copies of these drawables. - - @param normalImage the thing to draw for the button's 'normal' state. An internal copy - will be made of the object passed-in if it is non-zero. - @param overImage the thing to draw for the button's 'over' state - if this is - zero, the button's normal image will be used when the mouse is - over it. An internal copy will be made of the object passed-in - if it is non-zero. - @param downImage the thing to draw for the button's 'down' state - if this is - zero, the 'over' image will be used instead (or the normal image - as a last resort). An internal copy will be made of the object - passed-in if it is non-zero. - @param disabledImage an image to draw when the button is disabled. If this is zero, - the normal image will be drawn with a reduced opacity instead. - An internal copy will be made of the object passed-in if it is - non-zero. - @param normalImageOn same as the normalImage, but this is used when the button's toggle - state is 'on'. If this is nullptr, the normal image is used instead - @param overImageOn same as the overImage, but this is used when the button's toggle - state is 'on'. If this is nullptr, the normalImageOn is drawn instead - @param downImageOn same as the downImage, but this is used when the button's toggle - state is 'on'. If this is nullptr, the overImageOn is drawn instead - @param disabledImageOn same as the disabledImage, but this is used when the button's toggle - state is 'on'. If this is nullptr, the normal image will be drawn instead - with a reduced opacity - */ - void setImages (const Drawable* normalImage, - const Drawable* overImage = nullptr, - const Drawable* downImage = nullptr, - const Drawable* disabledImage = nullptr, - const Drawable* normalImageOn = nullptr, - const Drawable* overImageOn = nullptr, - const Drawable* downImageOn = nullptr, - const Drawable* disabledImageOn = nullptr); - - - //============================================================================== - /** Changes the button's style. - @see ButtonStyle - */ - void setButtonStyle (ButtonStyle newStyle); - - /** Returns the current style. */ - ButtonStyle getStyle() const noexcept { return style; } - - //============================================================================== - /** Gives the button an optional amount of space around the edge of the drawable. - By default there's a gap of about 3 pixels. - */ - void setEdgeIndent (int numPixelsIndent); - - //============================================================================== - /** Returns the image that the button is currently displaying. */ - Drawable* getCurrentImage() const noexcept; - - /** Returns the image that the button will use for its normal state. */ - Drawable* getNormalImage() const noexcept; - /** Returns the image that the button will use when the mouse is over it. */ - Drawable* getOverImage() const noexcept; - /** Returns the image that the button will use when the mouse is held down on it. */ - Drawable* getDownImage() const noexcept; - - /** Can be overridden to specify a custom position for the image within the button. */ - virtual Rectangle getImageBounds() const; - - //============================================================================== - /** A set of colour IDs to use to change the colour of various aspects of the link. - - These constants can be used either via the Component::setColour(), or LookAndFeel::setColour() - methods. - - Note that when the ImageOnButtonBackground style is used, the colour IDs that control - the button colour are TextButton::buttonColourId and TextButton::buttonOnColourId. - - @see Component::setColour, Component::findColour, LookAndFeel::setColour, LookAndFeel::findColour - */ - enum ColourIds - { - textColourId = 0x1004010, /**< The colour to use for the button's text label. */ - textColourOnId = 0x1004013, /**< The colour to use for the button's text.when the button's toggle state is "on". */ - - backgroundColourId = 0x1004011, /**< The colour used to fill the button's background (when - the button is toggled 'off'). Note that if you use the - ImageOnButtonBackground style, you should use TextButton::buttonColourId - to change the button's colour. */ - backgroundOnColourId = 0x1004012, /**< The colour used to fill the button's background (when - the button is toggled 'on'). Note that if you use the - ImageOnButtonBackground style, you should use TextButton::buttonOnColourId - to change the button's colour. */ - }; - - //============================================================================== - /** @internal */ - void paintButton (Graphics&, bool isMouseOverButton, bool isButtonDown) override; - /** @internal */ - void buttonStateChanged() override; - /** @internal */ - void resized() override; - /** @internal */ - void enablementChanged() override; - /** @internal */ - void colourChanged() override; - -private: - //============================================================================== - ButtonStyle style; - ScopedPointer normalImage, overImage, downImage, disabledImage, - normalImageOn, overImageOn, downImageOn, disabledImageOn; - Drawable* currentImage; - int edgeIndent; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (DrawableButton) -}; - - -#endif // JUCE_DRAWABLEBUTTON_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/buttons/juce_HyperlinkButton.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/buttons/juce_HyperlinkButton.cpp deleted file mode 100644 index 8274f4c123..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/buttons/juce_HyperlinkButton.cpp +++ /dev/null @@ -1,109 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -HyperlinkButton::HyperlinkButton (const String& linkText, - const URL& linkURL) - : Button (linkText), - url (linkURL), - font (14.0f, Font::underlined), - resizeFont (true), - justification (Justification::centred) -{ - setMouseCursor (MouseCursor::PointingHandCursor); - setTooltip (linkURL.toString (false)); -} - -HyperlinkButton::HyperlinkButton () - : Button (String::empty), - font (14.0f, Font::underlined), - resizeFont (true), - justification (Justification::centred) -{ - setMouseCursor (MouseCursor::PointingHandCursor); -} - -HyperlinkButton::~HyperlinkButton() -{ -} - -//============================================================================== -void HyperlinkButton::setFont (const Font& newFont, - const bool resizeToMatchComponentHeight, - Justification justificationType) -{ - font = newFont; - resizeFont = resizeToMatchComponentHeight; - justification = justificationType; - repaint(); -} - -void HyperlinkButton::setURL (const URL& newURL) noexcept -{ - url = newURL; - setTooltip (newURL.toString (false)); -} - -Font HyperlinkButton::getFontToUse() const -{ - if (resizeFont) - return font.withHeight (getHeight() * 0.7f); - - return font; -} - -void HyperlinkButton::changeWidthToFitText() -{ - setSize (getFontToUse().getStringWidth (getButtonText()) + 6, getHeight()); -} - -void HyperlinkButton::colourChanged() -{ - repaint(); -} - -//============================================================================== -void HyperlinkButton::clicked() -{ - if (url.isWellFormed()) - url.launchInDefaultBrowser(); -} - -void HyperlinkButton::paintButton (Graphics& g, - bool isMouseOverButton, - bool isButtonDown) -{ - const Colour textColour (findColour (textColourId)); - - if (isEnabled()) - g.setColour ((isMouseOverButton) ? textColour.darker ((isButtonDown) ? 1.3f : 0.4f) - : textColour); - else - g.setColour (textColour.withMultipliedAlpha (0.4f)); - - g.setFont (getFontToUse()); - - g.drawText (getButtonText(), getLocalBounds().reduced (1, 0), - justification.getOnlyHorizontalFlags() | Justification::verticallyCentred, - true); -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/buttons/juce_HyperlinkButton.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/buttons/juce_HyperlinkButton.h deleted file mode 100644 index 4cd3f52920..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/buttons/juce_HyperlinkButton.h +++ /dev/null @@ -1,114 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_HYPERLINKBUTTON_H_INCLUDED -#define JUCE_HYPERLINKBUTTON_H_INCLUDED - - -//============================================================================== -/** - A button showing an underlined weblink, that will launch the link - when it's clicked. - - @see Button -*/ -class JUCE_API HyperlinkButton : public Button -{ -public: - //============================================================================== - /** Creates a HyperlinkButton. - - @param linkText the text that will be displayed in the button - this is - also set as the Component's name, but the text can be - changed later with the Button::getButtonText() method - @param linkURL the URL to launch when the user clicks the button - */ - HyperlinkButton (const String& linkText, - const URL& linkURL); - - /** Creates a HyperlinkButton. */ - HyperlinkButton(); - - /** Destructor. */ - ~HyperlinkButton(); - - //============================================================================== - /** Changes the font to use for the text. - - If resizeToMatchComponentHeight is true, the font's height will be adjusted - to match the size of the component. - */ - void setFont (const Font& newFont, - bool resizeToMatchComponentHeight, - Justification justificationType = Justification::horizontallyCentred); - - //============================================================================== - /** A set of colour IDs to use to change the colour of various aspects of the link. - - These constants can be used either via the Component::setColour(), or LookAndFeel::setColour() - methods. - - @see Component::setColour, Component::findColour, LookAndFeel::setColour, LookAndFeel::findColour - */ - enum ColourIds - { - textColourId = 0x1001f00, /**< The colour to use for the URL text. */ - }; - - //============================================================================== - /** Changes the URL that the button will trigger. */ - void setURL (const URL& newURL) noexcept; - - /** Returns the URL that the button will trigger. */ - const URL& getURL() const noexcept { return url; } - - //============================================================================== - /** Resizes the button horizontally to fit snugly around the text. - - This won't affect the button's height. - */ - void changeWidthToFitText(); - -protected: - //============================================================================== - /** @internal */ - void clicked() override; - /** @internal */ - void colourChanged() override; - /** @internal */ - void paintButton (Graphics&, bool isMouseOver, bool isButtonDown) override; - -private: - //============================================================================== - URL url; - Font font; - bool resizeFont; - Justification justification; - - Font getFontToUse() const; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (HyperlinkButton) -}; - -#endif // JUCE_HYPERLINKBUTTON_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/buttons/juce_ImageButton.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/buttons/juce_ImageButton.cpp deleted file mode 100644 index 3170d05f64..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/buttons/juce_ImageButton.cpp +++ /dev/null @@ -1,189 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -ImageButton::ImageButton (const String& text_) - : Button (text_), - scaleImageToFit (true), - preserveProportions (true), - alphaThreshold (0) -{ -} - -ImageButton::~ImageButton() -{ -} - -void ImageButton::setImages (const bool resizeButtonNowToFitThisImage, - const bool rescaleImagesWhenButtonSizeChanges, - const bool preserveImageProportions, - const Image& normalImage_, - const float imageOpacityWhenNormal, - Colour overlayColourWhenNormal, - const Image& overImage_, - const float imageOpacityWhenOver, - Colour overlayColourWhenOver, - const Image& downImage_, - const float imageOpacityWhenDown, - Colour overlayColourWhenDown, - const float hitTestAlphaThreshold) -{ - normalImage = normalImage_; - overImage = overImage_; - downImage = downImage_; - - if (resizeButtonNowToFitThisImage && normalImage.isValid()) - { - imageBounds.setSize (normalImage.getWidth(), - normalImage.getHeight()); - - setSize (imageBounds.getWidth(), imageBounds.getHeight()); - } - - scaleImageToFit = rescaleImagesWhenButtonSizeChanges; - preserveProportions = preserveImageProportions; - - normalOpacity = imageOpacityWhenNormal; - normalOverlay = overlayColourWhenNormal; - overOpacity = imageOpacityWhenOver; - overOverlay = overlayColourWhenOver; - downOpacity = imageOpacityWhenDown; - downOverlay = overlayColourWhenDown; - - alphaThreshold = (uint8) jlimit (0, 0xff, roundToInt (255.0f * hitTestAlphaThreshold)); - - repaint(); -} - -Image ImageButton::getCurrentImage() const -{ - if (isDown() || getToggleState()) - return getDownImage(); - - if (isOver()) - return getOverImage(); - - return getNormalImage(); -} - -Image ImageButton::getNormalImage() const -{ - return normalImage; -} - -Image ImageButton::getOverImage() const -{ - return overImage.isValid() ? overImage - : normalImage; -} - -Image ImageButton::getDownImage() const -{ - return downImage.isValid() ? downImage - : getOverImage(); -} - -void ImageButton::paintButton (Graphics& g, - bool isMouseOverButton, - bool isButtonDown) -{ - if (! isEnabled()) - { - isMouseOverButton = false; - isButtonDown = false; - } - - Image im (getCurrentImage()); - - if (im.isValid()) - { - const int iw = im.getWidth(); - const int ih = im.getHeight(); - int w = getWidth(); - int h = getHeight(); - int x = (w - iw) / 2; - int y = (h - ih) / 2; - - if (scaleImageToFit) - { - if (preserveProportions) - { - int newW, newH; - const float imRatio = ih / (float) iw; - const float destRatio = h / (float) w; - - if (imRatio > destRatio) - { - newW = roundToInt (h / imRatio); - newH = h; - } - else - { - newW = w; - newH = roundToInt (w * imRatio); - } - - x = (w - newW) / 2; - y = (h - newH) / 2; - w = newW; - h = newH; - } - else - { - x = 0; - y = 0; - } - } - - if (! scaleImageToFit) - { - w = iw; - h = ih; - } - - imageBounds.setBounds (x, y, w, h); - - const bool useDownImage = isButtonDown || getToggleState(); - - getLookAndFeel().drawImageButton (g, &im, x, y, w, h, - useDownImage ? downOverlay - : (isMouseOverButton ? overOverlay - : normalOverlay), - useDownImage ? downOpacity - : (isMouseOverButton ? overOpacity - : normalOpacity), - *this); - } -} - -bool ImageButton::hitTest (int x, int y) -{ - if (alphaThreshold == 0) - return true; - - Image im (getCurrentImage()); - - return im.isNull() || ((! imageBounds.isEmpty()) - && alphaThreshold < im.getPixelAt (((x - imageBounds.getX()) * im.getWidth()) / imageBounds.getWidth(), - ((y - imageBounds.getY()) * im.getHeight()) / imageBounds.getHeight()).getAlpha()); -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/buttons/juce_ImageButton.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/buttons/juce_ImageButton.h deleted file mode 100644 index 64db59df26..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/buttons/juce_ImageButton.h +++ /dev/null @@ -1,160 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_IMAGEBUTTON_H_INCLUDED -#define JUCE_IMAGEBUTTON_H_INCLUDED - - -//============================================================================== -/** - As the title suggests, this is a button containing an image. - - The colour and transparency of the image can be set to vary when the - button state changes. - - @see Button, ShapeButton, TextButton -*/ -class JUCE_API ImageButton : public Button -{ -public: - //============================================================================== - /** Creates an ImageButton. - - Use setImage() to specify the image to use. The colours and opacities that - are specified here can be changed later using setImages(). - - @param name the name to give the component - */ - explicit ImageButton (const String& name = String::empty); - - /** Destructor. */ - ~ImageButton(); - - //============================================================================== - /** Sets up the images to draw in various states. - - @param resizeButtonNowToFitThisImage if true, the button will be immediately - resized to the same dimensions as the normal image - @param rescaleImagesWhenButtonSizeChanges if true, the image will be rescaled to fit the - button when the button's size changes - @param preserveImageProportions if true then any rescaling of the image to fit - the button will keep the image's x and y proportions - correct - i.e. it won't distort its shape, although - this might create gaps around the edges - @param normalImage the image to use when the button is in its normal state. - button no longer needs it. - @param imageOpacityWhenNormal the opacity to use when drawing the normal image. - @param overlayColourWhenNormal an overlay colour to use to fill the alpha channel of the - normal image - if this colour is transparent, no overlay - will be drawn. The overlay will be drawn over the top of the - image, so you can basically add a solid or semi-transparent - colour to the image to brighten or darken it - @param overImage the image to use when the mouse is over the button. If - you want to use the same image as was set in the normalImage - parameter, this value can be a null image. - @param imageOpacityWhenOver the opacity to use when drawing the image when the mouse - is over the button - @param overlayColourWhenOver an overlay colour to use to fill the alpha channel of the - image when the mouse is over - if this colour is transparent, - no overlay will be drawn - @param downImage an image to use when the button is pressed down. If set - to a null image, the 'over' image will be drawn instead (or the - normal image if there isn't an 'over' image either). - @param imageOpacityWhenDown the opacity to use when drawing the image when the button - is pressed - @param overlayColourWhenDown an overlay colour to use to fill the alpha channel of the - image when the button is pressed down - if this colour is - transparent, no overlay will be drawn - @param hitTestAlphaThreshold if set to zero, the mouse is considered to be over the button - whenever it's inside the button's bounding rectangle. If - set to values higher than 0, the mouse will only be - considered to be over the image when the value of the - image's alpha channel at that position is greater than - this level. - */ - void setImages (bool resizeButtonNowToFitThisImage, - bool rescaleImagesWhenButtonSizeChanges, - bool preserveImageProportions, - const Image& normalImage, - float imageOpacityWhenNormal, - Colour overlayColourWhenNormal, - const Image& overImage, - float imageOpacityWhenOver, - Colour overlayColourWhenOver, - const Image& downImage, - float imageOpacityWhenDown, - Colour overlayColourWhenDown, - float hitTestAlphaThreshold = 0.0f); - - /** Returns the currently set 'normal' image. */ - Image getNormalImage() const; - - /** Returns the image that's drawn when the mouse is over the button. - - If a valid 'over' image has been set, this will return it; otherwise it'll - just return the normal image. - */ - Image getOverImage() const; - - /** Returns the image that's drawn when the button is held down. - - If a valid 'down' image has been set, this will return it; otherwise it'll - return the 'over' image or normal image, depending on what's available. - */ - Image getDownImage() const; - - //============================================================================== - /** This abstract base class is implemented by LookAndFeel classes. */ - struct JUCE_API LookAndFeelMethods - { - virtual ~LookAndFeelMethods() {} - - virtual void drawImageButton (Graphics&, Image*, - int imageX, int imageY, int imageW, int imageH, - const Colour& overlayColour, float imageOpacity, ImageButton&) = 0; - }; - -protected: - //============================================================================== - /** @internal */ - bool hitTest (int x, int y) override; - /** @internal */ - void paintButton (Graphics&, bool isMouseOver, bool isButtonDown) override; - -private: - //============================================================================== - bool scaleImageToFit, preserveProportions; - uint8 alphaThreshold; - Rectangle imageBounds; - Image normalImage, overImage, downImage; - float normalOpacity, overOpacity, downOpacity; - Colour normalOverlay, overOverlay, downOverlay; - - Image getCurrentImage() const; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ImageButton) -}; - - -#endif // JUCE_IMAGEBUTTON_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/buttons/juce_ShapeButton.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/buttons/juce_ShapeButton.cpp deleted file mode 100644 index 28cd8de826..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/buttons/juce_ShapeButton.cpp +++ /dev/null @@ -1,114 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -ShapeButton::ShapeButton (const String& t, Colour n, Colour o, Colour d) - : Button (t), - normalColour (n), overColour (o), downColour (d), - maintainShapeProportions (false), - outlineWidth (0.0f) -{ -} - -ShapeButton::~ShapeButton() {} - -void ShapeButton::setColours (Colour newNormalColour, Colour newOverColour, Colour newDownColour) -{ - normalColour = newNormalColour; - overColour = newOverColour; - downColour = newDownColour; -} - -void ShapeButton::setOutline (Colour newOutlineColour, const float newOutlineWidth) -{ - outlineColour = newOutlineColour; - outlineWidth = newOutlineWidth; -} - -void ShapeButton::setBorderSize (BorderSize newBorder) -{ - border = newBorder; -} - -void ShapeButton::setShape (const Path& newShape, - const bool resizeNowToFitThisShape, - const bool maintainShapeProportions_, - const bool hasShadow) -{ - shape = newShape; - maintainShapeProportions = maintainShapeProportions_; - - shadow.setShadowProperties (DropShadow (Colours::black.withAlpha (0.5f), 3, Point())); - setComponentEffect (hasShadow ? &shadow : nullptr); - - if (resizeNowToFitThisShape) - { - Rectangle newBounds (shape.getBounds()); - - if (hasShadow) - newBounds = newBounds.expanded (4.0f); - - shape.applyTransform (AffineTransform::translation (-newBounds.getX(), - -newBounds.getY())); - - setSize (1 + (int) (newBounds.getWidth() + outlineWidth) + border.getLeftAndRight(), - 1 + (int) (newBounds.getHeight() + outlineWidth) + border.getTopAndBottom()); - } - - repaint(); -} - -void ShapeButton::paintButton (Graphics& g, bool isMouseOverButton, bool isButtonDown) -{ - if (! isEnabled()) - { - isMouseOverButton = false; - isButtonDown = false; - } - - Rectangle r (border.subtractedFrom (getLocalBounds()).toFloat().reduced (outlineWidth * 0.5f)); - - if (getComponentEffect() != nullptr) - r = r.reduced (2.0f); - - if (isButtonDown) - { - const float sizeReductionWhenPressed = 0.04f; - - r = r.reduced (sizeReductionWhenPressed * r.getWidth(), - sizeReductionWhenPressed * r.getHeight()); - } - - const AffineTransform trans (shape.getTransformToScaleToFit (r, maintainShapeProportions)); - - g.setColour (isButtonDown ? downColour - : isMouseOverButton ? overColour - : normalColour); - g.fillPath (shape, trans); - - if (outlineWidth > 0.0f) - { - g.setColour (outlineColour); - g.strokePath (shape, PathStrokeType (outlineWidth), trans); - } -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/buttons/juce_ShapeButton.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/buttons/juce_ShapeButton.h deleted file mode 100644 index ddc462521a..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/buttons/juce_ShapeButton.h +++ /dev/null @@ -1,106 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_SHAPEBUTTON_H_INCLUDED -#define JUCE_SHAPEBUTTON_H_INCLUDED - - -//============================================================================== -/** - A button that contains a filled shape. - - @see Button, ImageButton, TextButton, ArrowButton -*/ -class JUCE_API ShapeButton : public Button -{ -public: - //============================================================================== - /** Creates a ShapeButton. - - @param name a name to give the component - see Component::setName() - @param normalColour the colour to fill the shape with when the mouse isn't over - @param overColour the colour to use when the mouse is over the shape - @param downColour the colour to use when the button is in the pressed-down state - */ - ShapeButton (const String& name, - Colour normalColour, - Colour overColour, - Colour downColour); - - /** Destructor. */ - ~ShapeButton(); - - //============================================================================== - /** Sets the shape to use. - - @param newShape the shape to use - @param resizeNowToFitThisShape if true, the button will be resized to fit the shape's bounds - @param maintainShapeProportions if true, the shape's proportions will be kept fixed when - the button is resized - @param hasDropShadow if true, the button will be given a drop-shadow effect - */ - void setShape (const Path& newShape, - bool resizeNowToFitThisShape, - bool maintainShapeProportions, - bool hasDropShadow); - - /** Set the colours to use for drawing the shape. - - @param normalColour the colour to fill the shape with when the mouse isn't over - @param overColour the colour to use when the mouse is over the shape - @param downColour the colour to use when the button is in the pressed-down state - */ - void setColours (Colour normalColour, - Colour overColour, - Colour downColour); - - /** Sets up an outline to draw around the shape. - - @param outlineColour the colour to use - @param outlineStrokeWidth the thickness of line to draw - */ - void setOutline (Colour outlineColour, float outlineStrokeWidth); - - /** This lets you specify a border to be left around the edge of the button when - drawing the shape. - */ - void setBorderSize (BorderSize border); - - /** @internal */ - void paintButton (Graphics&, bool isMouseOverButton, bool isButtonDown) override; - -private: - //============================================================================== - Colour normalColour, overColour, downColour, outlineColour; - DropShadowEffect shadow; - Path shape; - BorderSize border; - bool maintainShapeProportions; - float outlineWidth; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ShapeButton) -}; - - -#endif // JUCE_SHAPEBUTTON_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/buttons/juce_TextButton.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/buttons/juce_TextButton.cpp deleted file mode 100644 index b51ea6587d..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/buttons/juce_TextButton.cpp +++ /dev/null @@ -1,70 +0,0 @@ -/* - ============================================================================== - file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -TextButton::TextButton() : Button (String()) -{ -} - -TextButton::TextButton (const String& name) : Button (name) -{ -} - -TextButton::TextButton (const String& name, const String& toolTip) : Button (name) -{ - setTooltip (toolTip); -} - -TextButton::~TextButton() -{ -} - -void TextButton::paintButton (Graphics& g, bool isMouseOverButton, bool isButtonDown) -{ - LookAndFeel& lf = getLookAndFeel(); - - lf.drawButtonBackground (g, *this, - findColour (getToggleState() ? buttonOnColourId : buttonColourId), - isMouseOverButton, isButtonDown); - - lf.drawButtonText (g, *this, isMouseOverButton, isButtonDown); -} - -void TextButton::colourChanged() -{ - repaint(); -} - -void TextButton::changeWidthToFitText() -{ - changeWidthToFitText (getHeight()); -} - -void TextButton::changeWidthToFitText (const int newHeight) -{ - setSize (getBestWidthForHeight (newHeight), newHeight); -} - -int TextButton::getBestWidthForHeight (int buttonHeight) -{ - return getLookAndFeel().getTextButtonWidthToFitText (*this, buttonHeight); -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/buttons/juce_TextButton.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/buttons/juce_TextButton.h deleted file mode 100644 index b9093b27bd..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/buttons/juce_TextButton.h +++ /dev/null @@ -1,113 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_TEXTBUTTON_H_INCLUDED -#define JUCE_TEXTBUTTON_H_INCLUDED - - -//============================================================================== -/** - A button that uses the standard lozenge-shaped background with a line of - text on it. - - @see Button, DrawableButton -*/ -class JUCE_API TextButton : public Button -{ -public: - //============================================================================== - /** Creates a TextButton. */ - TextButton(); - - /** Creates a TextButton. - @param buttonName the text to put in the button (the component's name is also - initially set to this string, but these can be changed later - using the setName() and setButtonText() methods) - */ - explicit TextButton (const String& buttonName); - - /** Creates a TextButton. - @param buttonName the text to put in the button (the component's name is also - initially set to this string, but these can be changed later - using the setName() and setButtonText() methods) - @param toolTip an optional string to use as a toolip - */ - TextButton (const String& buttonName, const String& toolTip); - - /** Destructor. */ - ~TextButton(); - - //============================================================================== - /** A set of colour IDs to use to change the colour of various aspects of the button. - - These constants can be used either via the Component::setColour(), or LookAndFeel::setColour() - methods. - - @see Component::setColour, Component::findColour, LookAndFeel::setColour, LookAndFeel::findColour - */ - enum ColourIds - { - buttonColourId = 0x1000100, /**< The colour used to fill the button shape (when the button is toggled - 'off'). The look-and-feel class might re-interpret this to add - effects, etc. */ - buttonOnColourId = 0x1000101, /**< The colour used to fill the button shape (when the button is toggled - 'on'). The look-and-feel class might re-interpret this to add - effects, etc. */ - textColourOffId = 0x1000102, /**< The colour to use for the button's text when the button's toggle state is "off". */ - textColourOnId = 0x1000103 /**< The colour to use for the button's text.when the button's toggle state is "on". */ - }; - - //============================================================================== - /** Changes this button's width to fit neatly around its current text, without - changing its height. - */ - void changeWidthToFitText(); - - /** Resizes the button's width to fit neatly around its current text, and gives it - the specified height. - */ - void changeWidthToFitText (int newHeight); - - /** Returns the width that the LookAndFeel suggests would be best for this button if it - had the given height. - */ - int getBestWidthForHeight (int buttonHeight); - - //============================================================================== - /** @internal */ - void paintButton (Graphics&, bool isMouseOverButton, bool isButtonDown) override; - /** @internal */ - void colourChanged() override; - -private: - #if JUCE_CATCH_DEPRECATED_CODE_MISUSE - // Note that this method has been removed - instead, see LookAndFeel::getTextButtonWidthToFitText() - virtual int getFont() { return 0; } - #endif - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (TextButton) -}; - - -#endif // JUCE_TEXTBUTTON_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/buttons/juce_ToggleButton.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/buttons/juce_ToggleButton.cpp deleted file mode 100644 index edaf7ab0ae..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/buttons/juce_ToggleButton.cpp +++ /dev/null @@ -1,54 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -ToggleButton::ToggleButton() - : Button (String::empty) -{ - setClickingTogglesState (true); -} - -ToggleButton::ToggleButton (const String& buttonText) - : Button (buttonText) -{ - setClickingTogglesState (true); -} - -ToggleButton::~ToggleButton() -{ -} - -void ToggleButton::paintButton (Graphics& g, bool isMouseOverButton, bool isButtonDown) -{ - getLookAndFeel().drawToggleButton (g, *this, isMouseOverButton, isButtonDown); -} - -void ToggleButton::changeWidthToFitText() -{ - getLookAndFeel().changeToggleButtonWidthToFitText (*this); -} - -void ToggleButton::colourChanged() -{ - repaint(); -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/buttons/juce_ToggleButton.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/buttons/juce_ToggleButton.h deleted file mode 100644 index 911bc5991b..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/buttons/juce_ToggleButton.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_TOGGLEBUTTON_H_INCLUDED -#define JUCE_TOGGLEBUTTON_H_INCLUDED - - -//============================================================================== -/** - A button that can be toggled on/off. - - All buttons can be toggle buttons, but this lets you create one of the - standard ones which has a tick-box and a text label next to it. - - @see Button, DrawableButton, TextButton -*/ -class JUCE_API ToggleButton : public Button -{ -public: - //============================================================================== - /** Creates a ToggleButton. */ - ToggleButton(); - - /** Creates a ToggleButton. - - @param buttonText the text to put in the button (the component's name is also - initially set to this string, but these can be changed later - using the setName() and setButtonText() methods) - */ - explicit ToggleButton (const String& buttonText); - - /** Destructor. */ - ~ToggleButton(); - - //============================================================================== - /** Resizes the button to fit neatly around its current text. - The button's height won't be affected, only its width. - */ - void changeWidthToFitText(); - - //============================================================================== - /** A set of colour IDs to use to change the colour of various aspects of the button. - - These constants can be used either via the Component::setColour(), or LookAndFeel::setColour() - methods. - - @see Component::setColour, Component::findColour, LookAndFeel::setColour, LookAndFeel::findColour - */ - enum ColourIds - { - textColourId = 0x1006501 /**< The colour to use for the button's text. */ - }; - -protected: - //============================================================================== - /** @internal */ - void paintButton (Graphics&, bool isMouseOverButton, bool isButtonDown) override; - /** @internal */ - void colourChanged() override; - -private: - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ToggleButton) -}; - - -#endif // JUCE_TOGGLEBUTTON_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/buttons/juce_ToolbarButton.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/buttons/juce_ToolbarButton.cpp deleted file mode 100644 index f7ef1b0969..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/buttons/juce_ToolbarButton.cpp +++ /dev/null @@ -1,107 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -ToolbarButton::ToolbarButton (const int iid, const String& buttonText, - Drawable* const normalIm, Drawable* const toggledOnIm) - : ToolbarItemComponent (iid, buttonText, true), - normalImage (normalIm), - toggledOnImage (toggledOnIm), - currentImage (nullptr) -{ - jassert (normalImage != nullptr); -} - -ToolbarButton::~ToolbarButton() -{ -} - -//============================================================================== -bool ToolbarButton::getToolbarItemSizes (int toolbarDepth, bool /*isToolbarVertical*/, int& preferredSize, int& minSize, int& maxSize) -{ - preferredSize = minSize = maxSize = toolbarDepth; - return true; -} - -void ToolbarButton::paintButtonArea (Graphics&, int /*width*/, int /*height*/, bool /*isMouseOver*/, bool /*isMouseDown*/) -{ -} - -void ToolbarButton::contentAreaChanged (const Rectangle&) -{ - buttonStateChanged(); -} - -void ToolbarButton::setCurrentImage (Drawable* const newImage) -{ - if (newImage != currentImage) - { - removeChildComponent (currentImage); - currentImage = newImage; - - if (currentImage != nullptr) - { - enablementChanged(); - addAndMakeVisible (currentImage); - updateDrawable(); - } - } -} - -void ToolbarButton::updateDrawable() -{ - if (currentImage != nullptr) - { - currentImage->setInterceptsMouseClicks (false, false); - currentImage->setTransformToFit (getContentArea().toFloat(), RectanglePlacement::centred); - currentImage->setAlpha (isEnabled() ? 1.0f : 0.5f); - } -} - -void ToolbarButton::resized() -{ - ToolbarItemComponent::resized(); - updateDrawable(); -} - -void ToolbarButton::enablementChanged() -{ - ToolbarItemComponent::enablementChanged(); - updateDrawable(); -} - -Drawable* ToolbarButton::getImageToUse() const -{ - if (getStyle() == Toolbar::textOnly) - return nullptr; - - if (getToggleState() && toggledOnImage != nullptr) - return toggledOnImage; - - return normalImage; -} - -void ToolbarButton::buttonStateChanged() -{ - setCurrentImage (getImageToUse()); -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/buttons/juce_ToolbarButton.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/buttons/juce_ToolbarButton.h deleted file mode 100644 index 1f2548f071..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/buttons/juce_ToolbarButton.h +++ /dev/null @@ -1,97 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_TOOLBARBUTTON_H_INCLUDED -#define JUCE_TOOLBARBUTTON_H_INCLUDED - - -//============================================================================== -/** - A type of button designed to go on a toolbar. - - This simple button can have two Drawable objects specified - one for normal - use and another one (optionally) for the button's "on" state if it's a - toggle button. - - @see Toolbar, ToolbarItemFactory, ToolbarItemComponent, Drawable, Button -*/ -class JUCE_API ToolbarButton : public ToolbarItemComponent -{ -public: - //============================================================================== - /** Creates a ToolbarButton. - - @param itemId the ID for this toolbar item type. This is passed through to the - ToolbarItemComponent constructor - @param labelText the text to display on the button (if the toolbar is using a style - that shows text labels). This is passed through to the - ToolbarItemComponent constructor - @param normalImage a drawable object that the button should use as its icon. The object - that is passed-in here will be kept by this object and will be - deleted when no longer needed or when this button is deleted. - @param toggledOnImage a drawable object that the button can use as its icon if the button - is in a toggled-on state (see the Button::getToggleState() method). If - nullptr is passed-in here, then the normal image will be used instead, - regardless of the toggle state. The object that is passed-in here will be - owned by this object and will be deleted when no longer needed or when - this button is deleted. - */ - ToolbarButton (int itemId, - const String& labelText, - Drawable* normalImage, - Drawable* toggledOnImage); - - /** Destructor. */ - ~ToolbarButton(); - - - //============================================================================== - /** @internal */ - bool getToolbarItemSizes (int toolbarDepth, bool isToolbarVertical, int& preferredSize, - int& minSize, int& maxSize) override; - /** @internal */ - void paintButtonArea (Graphics&, int width, int height, bool isMouseOver, bool isMouseDown) override; - /** @internal */ - void contentAreaChanged (const Rectangle&) override; - /** @internal */ - void buttonStateChanged() override; - /** @internal */ - void resized() override; - /** @internal */ - void enablementChanged() override; - -private: - //============================================================================== - ScopedPointer normalImage, toggledOnImage; - Drawable* currentImage; - - void updateDrawable(); - Drawable* getImageToUse() const; - void setCurrentImage (Drawable*); - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ToolbarButton) -}; - - -#endif // JUCE_TOOLBARBUTTON_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/commands/juce_ApplicationCommandID.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/commands/juce_ApplicationCommandID.h deleted file mode 100644 index 9a00cbc8c5..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/commands/juce_ApplicationCommandID.h +++ /dev/null @@ -1,91 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_APPLICATIONCOMMANDID_H_INCLUDED -#define JUCE_APPLICATIONCOMMANDID_H_INCLUDED - - -//============================================================================== -/** A type used to hold the unique ID for an application command. - - This is a numeric type, so it can be stored as an integer. - - @see ApplicationCommandInfo, ApplicationCommandManager, - ApplicationCommandTarget, KeyPressMappingSet -*/ -typedef int CommandID; - - -//============================================================================== -/** A set of general-purpose application command IDs. - - Because these commands are likely to be used in most apps, they're defined - here to help different apps to use the same numeric values for them. - - Of course you don't have to use these, but some of them are used internally by - Juce - e.g. the quit ID is recognised as a command by the JUCEApplication class. - - @see ApplicationCommandInfo, ApplicationCommandManager, - ApplicationCommandTarget, KeyPressMappingSet -*/ -namespace StandardApplicationCommandIDs -{ - enum - { - /** This command ID should be used to send a "Quit the App" command. - - This command is recognised by the JUCEApplication class, so if it is invoked - and no other ApplicationCommandTarget handles the event first, the JUCEApplication - object will catch it and call JUCEApplicationBase::systemRequestedQuit(). - */ - quit = 0x1001, - - /** The command ID that should be used to send a "Delete" command. */ - del = 0x1002, - - /** The command ID that should be used to send a "Cut" command. */ - cut = 0x1003, - - /** The command ID that should be used to send a "Copy to clipboard" command. */ - copy = 0x1004, - - /** The command ID that should be used to send a "Paste from clipboard" command. */ - paste = 0x1005, - - /** The command ID that should be used to send a "Select all" command. */ - selectAll = 0x1006, - - /** The command ID that should be used to send a "Deselect all" command. */ - deselectAll = 0x1007, - - /** The command ID that should be used to send a "undo" command. */ - undo = 0x1008, - - /** The command ID that should be used to send a "redo" command. */ - redo = 0x1009 - }; -} - - -#endif // JUCE_APPLICATIONCOMMANDID_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/commands/juce_ApplicationCommandInfo.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/commands/juce_ApplicationCommandInfo.cpp deleted file mode 100644 index 174ec80f33..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/commands/juce_ApplicationCommandInfo.cpp +++ /dev/null @@ -1,60 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -ApplicationCommandInfo::ApplicationCommandInfo (const CommandID cid) noexcept - : commandID (cid), flags (0) -{ -} - -void ApplicationCommandInfo::setInfo (const String& shortName_, - const String& description_, - const String& categoryName_, - const int flags_) noexcept -{ - shortName = shortName_; - description = description_; - categoryName = categoryName_; - flags = flags_; -} - -void ApplicationCommandInfo::setActive (const bool b) noexcept -{ - if (b) - flags &= ~isDisabled; - else - flags |= isDisabled; -} - -void ApplicationCommandInfo::setTicked (const bool b) noexcept -{ - if (b) - flags |= isTicked; - else - flags &= ~isTicked; -} - -void ApplicationCommandInfo::addDefaultKeypress (const int keyCode, ModifierKeys modifiers) noexcept -{ - defaultKeypresses.add (KeyPress (keyCode, modifiers, 0)); -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/commands/juce_ApplicationCommandInfo.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/commands/juce_ApplicationCommandInfo.h deleted file mode 100644 index f906f43472..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/commands/juce_ApplicationCommandInfo.h +++ /dev/null @@ -1,189 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_APPLICATIONCOMMANDINFO_H_INCLUDED -#define JUCE_APPLICATIONCOMMANDINFO_H_INCLUDED - - -//============================================================================== -/** - Holds information describing an application command. - - This object is used to pass information about a particular command, such as its - name, description and other usage flags. - - When an ApplicationCommandTarget is asked to provide information about the commands - it can perform, this is the structure gets filled-in to describe each one. - - @see ApplicationCommandTarget, ApplicationCommandTarget::getCommandInfo(), - ApplicationCommandManager -*/ -struct JUCE_API ApplicationCommandInfo -{ - //============================================================================== - explicit ApplicationCommandInfo (CommandID commandID) noexcept; - - //============================================================================== - /** Sets a number of the structures values at once. - - The meanings of each of the parameters is described below, in the appropriate - member variable's description. - */ - void setInfo (const String& shortName, - const String& description, - const String& categoryName, - int flags) noexcept; - - /** An easy way to set or remove the isDisabled bit in the structure's flags field. - - If isActive is true, the flags member has the isDisabled bit cleared; if isActive - is false, the bit is set. - */ - void setActive (bool isActive) noexcept; - - /** An easy way to set or remove the isTicked bit in the structure's flags field. - */ - void setTicked (bool isTicked) noexcept; - - /** Handy method for adding a keypress to the defaultKeypresses array. - - This is just so you can write things like: - @code - myinfo.addDefaultKeypress ('s', ModifierKeys::commandModifier); - @endcode - instead of - @code - myinfo.defaultKeypresses.add (KeyPress ('s', ModifierKeys::commandModifier)); - @endcode - */ - void addDefaultKeypress (int keyCode, ModifierKeys modifiers) noexcept; - - //============================================================================== - /** The command's unique ID number. - */ - CommandID commandID; - - /** A short name to describe the command. - - This should be suitable for use in menus, on buttons that trigger the command, etc. - - You can use the setInfo() method to quickly set this and some of the command's - other properties. - */ - String shortName; - - /** A longer description of the command. - - This should be suitable for use in contexts such as a KeyMappingEditorComponent or - pop-up tooltip describing what the command does. - - You can use the setInfo() method to quickly set this and some of the command's - other properties. - */ - String description; - - /** A named category that the command fits into. - - You can give your commands any category you like, and these will be displayed in - contexts such as the KeyMappingEditorComponent, where the category is used to group - commands together. - - You can use the setInfo() method to quickly set this and some of the command's - other properties. - */ - String categoryName; - - /** A list of zero or more keypresses that should be used as the default keys for - this command. - - Methods such as KeyPressMappingSet::resetToDefaultMappings() will use the keypresses in - this list to initialise the default set of key-to-command mappings. - - @see addDefaultKeypress - */ - Array defaultKeypresses; - - //============================================================================== - /** Flags describing the ways in which this command should be used. - - A bitwise-OR of these values is stored in the ApplicationCommandInfo::flags - variable. - */ - enum CommandFlags - { - /** Indicates that the command can't currently be performed. - - The ApplicationCommandTarget::getCommandInfo() method must set this flag if it's - not currently permissable to perform the command. If the flag is set, then - components that trigger the command, e.g. PopupMenu, may choose to grey-out the - command or show themselves as not being enabled. - - @see ApplicationCommandInfo::setActive - */ - isDisabled = 1 << 0, - - /** Indicates that the command should have a tick next to it on a menu. - - If your command is shown on a menu and this is set, it'll show a tick next to - it. Other components such as buttons may also use this flag to indicate that it - is a value that can be toggled, and is currently in the 'on' state. - - @see ApplicationCommandInfo::setTicked - */ - isTicked = 1 << 1, - - /** If this flag is present, then when a KeyPressMappingSet invokes the command, - it will call the command twice, once on key-down and again on key-up. - - @see ApplicationCommandTarget::InvocationInfo - */ - wantsKeyUpDownCallbacks = 1 << 2, - - /** If this flag is present, then a KeyMappingEditorComponent will not display the - command in its list. - */ - hiddenFromKeyEditor = 1 << 3, - - /** If this flag is present, then a KeyMappingEditorComponent will display the - command in its list, but won't allow the assigned keypress to be changed. - */ - readOnlyInKeyEditor = 1 << 4, - - /** If this flag is present and the command is invoked from a keypress, then any - buttons or menus that are also connected to the command will not flash to - indicate that they've been triggered. - */ - dontTriggerVisualFeedback = 1 << 5 - }; - - /** A bitwise-OR of the values specified in the CommandFlags enum. - - You can use the setInfo() method to quickly set this and some of the command's - other properties. - */ - int flags; -}; - - -#endif // JUCE_APPLICATIONCOMMANDINFO_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/commands/juce_ApplicationCommandManager.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/commands/juce_ApplicationCommandManager.cpp deleted file mode 100644 index 82ec3a248b..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/commands/juce_ApplicationCommandManager.cpp +++ /dev/null @@ -1,312 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -ApplicationCommandManager::ApplicationCommandManager() - : firstTarget (nullptr) -{ - keyMappings = new KeyPressMappingSet (*this); - Desktop::getInstance().addFocusChangeListener (this); -} - -ApplicationCommandManager::~ApplicationCommandManager() -{ - Desktop::getInstance().removeFocusChangeListener (this); - keyMappings = nullptr; -} - -//============================================================================== -void ApplicationCommandManager::clearCommands() -{ - commands.clear(); - keyMappings->clearAllKeyPresses(); - triggerAsyncUpdate(); -} - -void ApplicationCommandManager::registerCommand (const ApplicationCommandInfo& newCommand) -{ - // zero isn't a valid command ID! - jassert (newCommand.commandID != 0); - - // the name isn't optional! - jassert (newCommand.shortName.isNotEmpty()); - - if (ApplicationCommandInfo* command = getMutableCommandForID (newCommand.commandID)) - { - // Trying to re-register the same command ID with different parameters can often indicate a typo. - // This assertion is here because I've found it useful catching some mistakes, but it may also cause - // false alarms if you're deliberately updating some flags for a command. - jassert (newCommand.shortName == getCommandForID (newCommand.commandID)->shortName - && newCommand.categoryName == getCommandForID (newCommand.commandID)->categoryName - && newCommand.defaultKeypresses == getCommandForID (newCommand.commandID)->defaultKeypresses - && (newCommand.flags & (ApplicationCommandInfo::wantsKeyUpDownCallbacks | ApplicationCommandInfo::hiddenFromKeyEditor | ApplicationCommandInfo::readOnlyInKeyEditor)) - == (getCommandForID (newCommand.commandID)->flags & (ApplicationCommandInfo::wantsKeyUpDownCallbacks | ApplicationCommandInfo::hiddenFromKeyEditor | ApplicationCommandInfo::readOnlyInKeyEditor))); - - *command = newCommand; - } - else - { - ApplicationCommandInfo* const newInfo = new ApplicationCommandInfo (newCommand); - newInfo->flags &= ~ApplicationCommandInfo::isTicked; - commands.add (newInfo); - - keyMappings->resetToDefaultMapping (newCommand.commandID); - - triggerAsyncUpdate(); - } -} - -void ApplicationCommandManager::registerAllCommandsForTarget (ApplicationCommandTarget* target) -{ - if (target != nullptr) - { - Array commandIDs; - target->getAllCommands (commandIDs); - - for (int i = 0; i < commandIDs.size(); ++i) - { - ApplicationCommandInfo info (commandIDs.getUnchecked(i)); - target->getCommandInfo (info.commandID, info); - - registerCommand (info); - } - } -} - -void ApplicationCommandManager::removeCommand (const CommandID commandID) -{ - for (int i = commands.size(); --i >= 0;) - { - if (commands.getUnchecked (i)->commandID == commandID) - { - commands.remove (i); - triggerAsyncUpdate(); - - const Array keys (keyMappings->getKeyPressesAssignedToCommand (commandID)); - - for (int j = keys.size(); --j >= 0;) - keyMappings->removeKeyPress (keys.getReference (j)); - } - } -} - -void ApplicationCommandManager::commandStatusChanged() -{ - triggerAsyncUpdate(); -} - -//============================================================================== -ApplicationCommandInfo* ApplicationCommandManager::getMutableCommandForID (CommandID commandID) const noexcept -{ - for (int i = commands.size(); --i >= 0;) - if (commands.getUnchecked(i)->commandID == commandID) - return commands.getUnchecked(i); - - return nullptr; -} - -const ApplicationCommandInfo* ApplicationCommandManager::getCommandForID (const CommandID commandID) const noexcept -{ - return getMutableCommandForID (commandID); -} - -String ApplicationCommandManager::getNameOfCommand (const CommandID commandID) const noexcept -{ - if (const ApplicationCommandInfo* const ci = getCommandForID (commandID)) - return ci->shortName; - - return String(); -} - -String ApplicationCommandManager::getDescriptionOfCommand (const CommandID commandID) const noexcept -{ - if (const ApplicationCommandInfo* const ci = getCommandForID (commandID)) - return ci->description.isNotEmpty() ? ci->description - : ci->shortName; - - return String(); -} - -StringArray ApplicationCommandManager::getCommandCategories() const -{ - StringArray s; - - for (int i = 0; i < commands.size(); ++i) - s.addIfNotAlreadyThere (commands.getUnchecked(i)->categoryName, false); - - return s; -} - -Array ApplicationCommandManager::getCommandsInCategory (const String& categoryName) const -{ - Array results; - - for (int i = 0; i < commands.size(); ++i) - if (commands.getUnchecked(i)->categoryName == categoryName) - results.add (commands.getUnchecked(i)->commandID); - - return results; -} - -//============================================================================== -bool ApplicationCommandManager::invokeDirectly (const CommandID commandID, const bool asynchronously) -{ - ApplicationCommandTarget::InvocationInfo info (commandID); - info.invocationMethod = ApplicationCommandTarget::InvocationInfo::direct; - - return invoke (info, asynchronously); -} - -bool ApplicationCommandManager::invoke (const ApplicationCommandTarget::InvocationInfo& inf, const bool asynchronously) -{ - // This call isn't thread-safe for use from a non-UI thread without locking the message - // manager first.. - jassert (MessageManager::getInstance()->currentThreadHasLockedMessageManager()); - - bool ok = false; - ApplicationCommandInfo commandInfo (0); - - if (ApplicationCommandTarget* const target = getTargetForCommand (inf.commandID, commandInfo)) - { - ApplicationCommandTarget::InvocationInfo info (inf); - info.commandFlags = commandInfo.flags; - - sendListenerInvokeCallback (info); - ok = target->invoke (info, asynchronously); - commandStatusChanged(); - } - - return ok; -} - -//============================================================================== -ApplicationCommandTarget* ApplicationCommandManager::getFirstCommandTarget (const CommandID) -{ - return firstTarget != nullptr ? firstTarget - : findDefaultComponentTarget(); -} - -void ApplicationCommandManager::setFirstCommandTarget (ApplicationCommandTarget* const newTarget) noexcept -{ - firstTarget = newTarget; -} - -ApplicationCommandTarget* ApplicationCommandManager::getTargetForCommand (const CommandID commandID, - ApplicationCommandInfo& upToDateInfo) -{ - ApplicationCommandTarget* target = getFirstCommandTarget (commandID); - - if (target == nullptr) - target = JUCEApplication::getInstance(); - - if (target != nullptr) - target = target->getTargetForCommand (commandID); - - if (target != nullptr) - { - upToDateInfo.commandID = commandID; - target->getCommandInfo (commandID, upToDateInfo); - } - - return target; -} - -//============================================================================== -ApplicationCommandTarget* ApplicationCommandManager::findTargetForComponent (Component* c) -{ - ApplicationCommandTarget* target = dynamic_cast (c); - - if (target == nullptr && c != nullptr) - target = c->findParentComponentOfClass(); - - return target; -} - -ApplicationCommandTarget* ApplicationCommandManager::findDefaultComponentTarget() -{ - Component* c = Component::getCurrentlyFocusedComponent(); - - if (c == nullptr) - { - if (TopLevelWindow* const activeWindow = TopLevelWindow::getActiveTopLevelWindow()) - { - c = activeWindow->getPeer()->getLastFocusedSubcomponent(); - - if (c == nullptr) - c = activeWindow; - } - } - - if (c == nullptr && Process::isForegroundProcess()) - { - Desktop& desktop = Desktop::getInstance(); - - // getting a bit desperate now: try all desktop comps.. - for (int i = desktop.getNumComponents(); --i >= 0;) - if (ComponentPeer* const peer = desktop.getComponent(i)->getPeer()) - if (ApplicationCommandTarget* const target = findTargetForComponent (peer->getLastFocusedSubcomponent())) - return target; - } - - if (c != nullptr) - { - // if we're focused on a ResizableWindow, chances are that it's the content - // component that really should get the event. And if not, the event will - // still be passed up to the top level window anyway, so let's send it to the - // content comp. - if (ResizableWindow* const resizableWindow = dynamic_cast (c)) - if (Component* const content = resizableWindow->getContentComponent()) - c = content; - - if (ApplicationCommandTarget* const target = findTargetForComponent (c)) - return target; - } - - return JUCEApplication::getInstance(); -} - -//============================================================================== -void ApplicationCommandManager::addListener (ApplicationCommandManagerListener* const listener) -{ - listeners.add (listener); -} - -void ApplicationCommandManager::removeListener (ApplicationCommandManagerListener* const listener) -{ - listeners.remove (listener); -} - -void ApplicationCommandManager::sendListenerInvokeCallback (const ApplicationCommandTarget::InvocationInfo& info) -{ - listeners.call (&ApplicationCommandManagerListener::applicationCommandInvoked, info); -} - -void ApplicationCommandManager::handleAsyncUpdate() -{ - listeners.call (&ApplicationCommandManagerListener::applicationCommandListChanged); -} - -void ApplicationCommandManager::globalFocusChanged (Component*) -{ - commandStatusChanged(); -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/commands/juce_ApplicationCommandManager.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/commands/juce_ApplicationCommandManager.h deleted file mode 100644 index 5be135a7d4..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/commands/juce_ApplicationCommandManager.h +++ /dev/null @@ -1,353 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_APPLICATIONCOMMANDMANAGER_H_INCLUDED -#define JUCE_APPLICATIONCOMMANDMANAGER_H_INCLUDED - - -//============================================================================== -/** - One of these objects holds a list of all the commands your app can perform, - and despatches these commands when needed. - - Application commands are a good way to trigger actions in your app, e.g. "Quit", - "Copy", "Paste", etc. Menus, buttons and keypresses can all be given commands - to invoke automatically, which means you don't have to handle the result of a menu - or button click manually. Commands are despatched to ApplicationCommandTarget objects - which can choose which events they want to handle. - - This architecture also allows for nested ApplicationCommandTargets, so that for example - you could have two different objects, one inside the other, both of which can respond to - a "delete" command. Depending on which one has focus, the command will be sent to the - appropriate place, regardless of whether it was triggered by a menu, keypress or some other - method. - - To set up your app to use commands, you'll need to do the following: - - - Create a global ApplicationCommandManager to hold the list of all possible - commands. (This will also manage a set of key-mappings for them). - - - Make some of your UI components (or other objects) inherit from ApplicationCommandTarget. - This allows the object to provide a list of commands that it can perform, and - to handle them. - - - Register each type of command using ApplicationCommandManager::registerAllCommandsForTarget(), - or ApplicationCommandManager::registerCommand(). - - - If you want key-presses to trigger your commands, use the ApplicationCommandManager::getKeyMappings() - method to access the key-mapper object, which you will need to register as a key-listener - in whatever top-level component you're using. See the KeyPressMappingSet class for more help - about setting this up. - - - Use methods such as PopupMenu::addCommandItem() or Button::setCommandToTrigger() to - cause these commands to be invoked automatically. - - - Commands can be invoked directly by your code using ApplicationCommandManager::invokeDirectly(). - - When a command is invoked, the ApplicationCommandManager will try to choose the best - ApplicationCommandTarget to receive the specified command. To do this it will use the - current keyboard focus to see which component might be interested, and will search the - component hierarchy for those that also implement the ApplicationCommandTarget interface. - If an ApplicationCommandTarget isn't interested in the command that is being invoked, then - the next one in line will be tried (see the ApplicationCommandTarget::getNextCommandTarget() - method), and so on until ApplicationCommandTarget::getNextCommandTarget() returns nullptr. - At this point if the command still hasn't been performed, it will be passed to the current - JUCEApplication object (which is itself an ApplicationCommandTarget). - - To exert some custom control over which ApplicationCommandTarget is chosen to invoke a command, - you can override the ApplicationCommandManager::getFirstCommandTarget() method and choose - the object yourself. - - @see ApplicationCommandTarget, ApplicationCommandInfo -*/ -class JUCE_API ApplicationCommandManager : private AsyncUpdater, - private FocusChangeListener -{ -public: - //============================================================================== - /** Creates an ApplicationCommandManager. - - Once created, you'll need to register all your app's commands with it, using - ApplicationCommandManager::registerAllCommandsForTarget() or - ApplicationCommandManager::registerCommand(). - */ - ApplicationCommandManager(); - - /** Destructor. - - Make sure that you don't delete this if pointers to it are still being used by - objects such as PopupMenus or Buttons. - */ - virtual ~ApplicationCommandManager(); - - //============================================================================== - /** Clears the current list of all commands. - Note that this will also clear the contents of the KeyPressMappingSet. - */ - void clearCommands(); - - /** Adds a command to the list of registered commands. - @see registerAllCommandsForTarget - */ - void registerCommand (const ApplicationCommandInfo& newCommand); - - /** Adds all the commands that this target publishes to the manager's list. - - This will use ApplicationCommandTarget::getAllCommands() and ApplicationCommandTarget::getCommandInfo() - to get details about all the commands that this target can do, and will call - registerCommand() to add each one to the manger's list. - - @see registerCommand - */ - void registerAllCommandsForTarget (ApplicationCommandTarget* target); - - /** Removes the command with a specified ID. - Note that this will also remove any key mappings that are mapped to the command. - */ - void removeCommand (CommandID commandID); - - /** This should be called to tell the manager that one of its registered commands may have changed - its active status. - - Because the command manager only finds out whether a command is active or inactive by querying - the current ApplicationCommandTarget, this is used to tell it that things may have changed. It - allows things like buttons to update their enablement, etc. - - This method will cause an asynchronous call to ApplicationCommandManagerListener::applicationCommandListChanged() - for any registered listeners. - */ - void commandStatusChanged(); - - //============================================================================== - /** Returns the number of commands that have been registered. - @see registerCommand - */ - int getNumCommands() const noexcept { return commands.size(); } - - /** Returns the details about one of the registered commands. - The index is between 0 and (getNumCommands() - 1). - */ - const ApplicationCommandInfo* getCommandForIndex (int index) const noexcept { return commands [index]; } - - /** Returns the details about a given command ID. - - This will search the list of registered commands for one with the given command - ID number, and return its associated info. If no matching command is found, this - will return 0. - */ - const ApplicationCommandInfo* getCommandForID (CommandID commandID) const noexcept; - - /** Returns the name field for a command. - - An empty string is returned if no command with this ID has been registered. - @see getDescriptionOfCommand - */ - String getNameOfCommand (CommandID commandID) const noexcept; - - /** Returns the description field for a command. - - An empty string is returned if no command with this ID has been registered. If the - command has no description, this will return its short name field instead. - - @see getNameOfCommand - */ - String getDescriptionOfCommand (CommandID commandID) const noexcept; - - /** Returns the list of categories. - - This will go through all registered commands, and return a list of all the distinct - categoryName values from their ApplicationCommandInfo structure. - - @see getCommandsInCategory() - */ - StringArray getCommandCategories() const; - - /** Returns a list of all the command UIDs in a particular category. - @see getCommandCategories() - */ - Array getCommandsInCategory (const String& categoryName) const; - - //============================================================================== - /** Returns the manager's internal set of key mappings. - - This object can be used to edit the keypresses. To actually link this object up - to invoke commands when a key is pressed, see the comments for the KeyPressMappingSet - class. - - @see KeyPressMappingSet - */ - KeyPressMappingSet* getKeyMappings() const noexcept { return keyMappings; } - - - //============================================================================== - /** Invokes the given command directly, sending it to the default target. - This is just an easy way to call invoke() without having to fill out the InvocationInfo - structure. - */ - bool invokeDirectly (CommandID commandID, bool asynchronously); - - /** Sends a command to the default target. - - This will choose a target using getFirstCommandTarget(), and send the specified command - to it using the ApplicationCommandTarget::invoke() method. This means that if the - first target can't handle the command, it will be passed on to targets further down the - chain (see ApplicationCommandTarget::invoke() for more info). - - @param invocationInfo this must be correctly filled-in, describing the context for - the invocation. - @param asynchronously if false, the command will be performed before this method returns. - If true, a message will be posted so that the command will be performed - later on the message thread, and this method will return immediately. - - @see ApplicationCommandTarget::invoke - */ - bool invoke (const ApplicationCommandTarget::InvocationInfo& invocationInfo, - bool asynchronously); - - - //============================================================================== - /** Chooses the ApplicationCommandTarget to which a command should be sent. - - Whenever the manager needs to know which target a command should be sent to, it calls - this method to determine the first one to try. - - By default, this method will return the target that was set by calling setFirstCommandTarget(). - If no target is set, it will return the result of findDefaultComponentTarget(). - - If you need to make sure all commands go via your own custom target, then you can - either use setFirstCommandTarget() to specify a single target, or override this method - if you need more complex logic to choose one. - - It may return nullptr if no targets are available. - - @see getTargetForCommand, invoke, invokeDirectly - */ - virtual ApplicationCommandTarget* getFirstCommandTarget (CommandID commandID); - - /** Sets a target to be returned by getFirstCommandTarget(). - - If this is set to nullptr, then getFirstCommandTarget() will by default return the - result of findDefaultComponentTarget(). - - If you use this to set a target, make sure you call setFirstCommandTarget(nullptr) - before deleting the target object. - */ - void setFirstCommandTarget (ApplicationCommandTarget* newTarget) noexcept; - - /** Tries to find the best target to use to perform a given command. - - This will call getFirstCommandTarget() to find the preferred target, and will - check whether that target can handle the given command. If it can't, then it'll use - ApplicationCommandTarget::getNextCommandTarget() to find the next one to try, and - so on until no more are available. - - If no targets are found that can perform the command, this method will return nullptr. - - If a target is found, then it will get the target to fill-in the upToDateInfo - structure with the latest info about that command, so that the caller can see - whether the command is disabled, ticked, etc. - */ - ApplicationCommandTarget* getTargetForCommand (CommandID commandID, - ApplicationCommandInfo& upToDateInfo); - - //============================================================================== - /** Registers a listener that will be called when various events occur. */ - void addListener (ApplicationCommandManagerListener* listener); - - /** Deregisters a previously-added listener. */ - void removeListener (ApplicationCommandManagerListener* listener); - - //============================================================================== - /** Looks for a suitable command target based on which Components have the keyboard focus. - - This is used by the default implementation of ApplicationCommandTarget::getFirstCommandTarget(), - but is exposed here in case it's useful. - - It tries to pick the best ApplicationCommandTarget by looking at focused components, top level - windows, etc., and using the findTargetForComponent() method. - */ - static ApplicationCommandTarget* findDefaultComponentTarget(); - - /** Examines this component and all its parents in turn, looking for the first one - which is an ApplicationCommandTarget. - - Returns the first ApplicationCommandTarget that it finds, or nullptr if none of them - implement that class. - */ - static ApplicationCommandTarget* findTargetForComponent (Component*); - - -private: - //============================================================================== - OwnedArray commands; - ListenerList listeners; - ScopedPointer keyMappings; - ApplicationCommandTarget* firstTarget; - - void sendListenerInvokeCallback (const ApplicationCommandTarget::InvocationInfo&); - void handleAsyncUpdate() override; - void globalFocusChanged (Component*) override; - ApplicationCommandInfo* getMutableCommandForID (CommandID) const noexcept; - - #if JUCE_CATCH_DEPRECATED_CODE_MISUSE - // This is just here to cause a compile error in old code that hasn't been changed to use the new - // version of this method. - virtual short getFirstCommandTarget() { return 0; } - #endif - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ApplicationCommandManager) -}; - - -//============================================================================== -/** - A listener that receives callbacks from an ApplicationCommandManager when - commands are invoked or the command list is changed. - - @see ApplicationCommandManager::addListener, ApplicationCommandManager::removeListener - -*/ -class JUCE_API ApplicationCommandManagerListener -{ -public: - //============================================================================== - /** Destructor. */ - virtual ~ApplicationCommandManagerListener() {} - - /** Called when an app command is about to be invoked. */ - virtual void applicationCommandInvoked (const ApplicationCommandTarget::InvocationInfo&) = 0; - - /** Called when commands are registered or deregistered from the - command manager, or when commands are made active or inactive. - - Note that if you're using this to watch for changes to whether a command is disabled, - you'll need to make sure that ApplicationCommandManager::commandStatusChanged() is called - whenever the status of your command might have changed. - */ - virtual void applicationCommandListChanged() = 0; -}; - - - -#endif // JUCE_APPLICATIONCOMMANDMANAGER_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/commands/juce_ApplicationCommandTarget.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/commands/juce_ApplicationCommandTarget.cpp deleted file mode 100644 index c31d1874d5..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/commands/juce_ApplicationCommandTarget.cpp +++ /dev/null @@ -1,186 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -class ApplicationCommandTarget::CommandMessage : public MessageManager::MessageBase -{ -public: - CommandMessage (ApplicationCommandTarget* const target, const InvocationInfo& inf) - : owner (target), info (inf) - { - } - - void messageCallback() override - { - if (ApplicationCommandTarget* const target = owner) - target->tryToInvoke (info, false); - } - -private: - WeakReference owner; - const InvocationInfo info; - - JUCE_DECLARE_NON_COPYABLE (CommandMessage) -}; - -//============================================================================== -ApplicationCommandTarget::ApplicationCommandTarget() -{ -} - -ApplicationCommandTarget::~ApplicationCommandTarget() -{ - masterReference.clear(); -} - -//============================================================================== -bool ApplicationCommandTarget::tryToInvoke (const InvocationInfo& info, const bool async) -{ - if (isCommandActive (info.commandID)) - { - if (async) - { - (new CommandMessage (this, info))->post(); - return true; - } - - if (perform (info)) - return true; - - // Hmm.. your target claimed that it could perform this command, but failed to do so. - // If it can't do it at the moment for some reason, it should clear the 'isActive' flag - // when it returns the command's info. - jassertfalse; - } - - return false; -} - -ApplicationCommandTarget* ApplicationCommandTarget::findFirstTargetParentComponent() -{ - if (Component* const c = dynamic_cast (this)) - return c->findParentComponentOfClass(); - - return nullptr; -} - -ApplicationCommandTarget* ApplicationCommandTarget::getTargetForCommand (const CommandID commandID) -{ - ApplicationCommandTarget* target = this; - int depth = 0; - - while (target != nullptr) - { - Array commandIDs; - target->getAllCommands (commandIDs); - - if (commandIDs.contains (commandID)) - return target; - - target = target->getNextCommandTarget(); - - ++depth; - jassert (depth < 100); // could be a recursive command chain?? - jassert (target != this); // definitely a recursive command chain! - - if (depth > 100 || target == this) - break; - } - - if (target == nullptr) - { - target = JUCEApplication::getInstance(); - - if (target != nullptr) - { - Array commandIDs; - target->getAllCommands (commandIDs); - - if (commandIDs.contains (commandID)) - return target; - } - } - - return nullptr; -} - -bool ApplicationCommandTarget::isCommandActive (const CommandID commandID) -{ - ApplicationCommandInfo info (commandID); - info.flags = ApplicationCommandInfo::isDisabled; - - getCommandInfo (commandID, info); - - return (info.flags & ApplicationCommandInfo::isDisabled) == 0; -} - -//============================================================================== -bool ApplicationCommandTarget::invoke (const InvocationInfo& info, const bool async) -{ - ApplicationCommandTarget* target = this; - int depth = 0; - - while (target != nullptr) - { - if (target->tryToInvoke (info, async)) - return true; - - target = target->getNextCommandTarget(); - - ++depth; - jassert (depth < 100); // could be a recursive command chain?? - jassert (target != this); // definitely a recursive command chain! - - if (depth > 100 || target == this) - break; - } - - if (target == nullptr) - { - target = JUCEApplication::getInstance(); - - if (target != nullptr) - return target->tryToInvoke (info, async); - } - - return false; -} - -bool ApplicationCommandTarget::invokeDirectly (const CommandID commandID, const bool asynchronously) -{ - ApplicationCommandTarget::InvocationInfo info (commandID); - info.invocationMethod = ApplicationCommandTarget::InvocationInfo::direct; - - return invoke (info, asynchronously); -} - -//============================================================================== -ApplicationCommandTarget::InvocationInfo::InvocationInfo (const CommandID command) - : commandID (command), - commandFlags (0), - invocationMethod (direct), - originatingComponent (nullptr), - isKeyDown (false), - millisecsSinceKeyPressed (0) -{ -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/commands/juce_ApplicationCommandTarget.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/commands/juce_ApplicationCommandTarget.h deleted file mode 100644 index c14faa818c..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/commands/juce_ApplicationCommandTarget.h +++ /dev/null @@ -1,245 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_APPLICATIONCOMMANDTARGET_H_INCLUDED -#define JUCE_APPLICATIONCOMMANDTARGET_H_INCLUDED - - -//============================================================================== -/** - A command target publishes a list of command IDs that it can perform. - - An ApplicationCommandManager despatches commands to targets, which must be - able to provide information about what commands they can handle. - - To create a target, you'll need to inherit from this class, implementing all of - its pure virtual methods. - - For info about how a target is chosen to receive a command, see - ApplicationCommandManager::getFirstCommandTarget(). - - @see ApplicationCommandManager, ApplicationCommandInfo -*/ -class JUCE_API ApplicationCommandTarget -{ -public: - //============================================================================== - /** Creates a command target. */ - ApplicationCommandTarget(); - - /** Destructor. */ - virtual ~ApplicationCommandTarget(); - - //============================================================================== - /** - Contains contextual details about the invocation of a command. - */ - struct JUCE_API InvocationInfo - { - //============================================================================== - InvocationInfo (const CommandID commandID); - - //============================================================================== - /** The UID of the command that should be performed. */ - CommandID commandID; - - /** The command's flags. - See ApplicationCommandInfo for a description of these flag values. - */ - int commandFlags; - - //============================================================================== - /** The types of context in which the command might be called. */ - enum InvocationMethod - { - direct = 0, /**< The command is being invoked directly by a piece of code. */ - fromKeyPress, /**< The command is being invoked by a key-press. */ - fromMenu, /**< The command is being invoked by a menu selection. */ - fromButton /**< The command is being invoked by a button click. */ - }; - - /** The type of event that triggered this command. */ - InvocationMethod invocationMethod; - - //============================================================================== - /** If triggered by a keypress or menu, this will be the component that had the - keyboard focus at the time. - - If triggered by a button, it may be set to that component, or it may be null. - */ - Component* originatingComponent; - - //============================================================================== - /** The keypress that was used to invoke it. - - Note that this will be an invalid keypress if the command was invoked - by some other means than a keyboard shortcut. - */ - KeyPress keyPress; - - /** True if the callback is being invoked when the key is pressed, - false if the key is being released. - - @see KeyPressMappingSet::addCommand() - */ - bool isKeyDown; - - /** If the key is being released, this indicates how long it had been held - down for. - - (Only relevant if isKeyDown is false.) - */ - int millisecsSinceKeyPressed; - }; - - //============================================================================== - /** This must return the next target to try after this one. - - When a command is being sent, and the first target can't handle - that command, this method is used to determine the next target that should - be tried. - - It may return nullptr if it doesn't know of another target. - - If your target is a Component, you would usually use the findFirstTargetParentComponent() - method to return a parent component that might want to handle it. - - @see invoke - */ - virtual ApplicationCommandTarget* getNextCommandTarget() = 0; - - /** This must return a complete list of commands that this target can handle. - - Your target should add all the command IDs that it handles to the array that is - passed-in. - */ - virtual void getAllCommands (Array& commands) = 0; - - /** This must provide details about one of the commands that this target can perform. - - This will be called with one of the command IDs that the target provided in its - getAllCommands() methods. - - It should fill-in all appropriate fields of the ApplicationCommandInfo structure with - suitable information about the command. (The commandID field will already have been filled-in - by the caller). - - The easiest way to set the info is using the ApplicationCommandInfo::setInfo() method to - set all the fields at once. - - If the command is currently inactive for some reason, this method must use - ApplicationCommandInfo::setActive() to make that clear, (or it should set the isDisabled - bit of the ApplicationCommandInfo::flags field). - - Any default key-presses for the command should be appended to the - ApplicationCommandInfo::defaultKeypresses field. - - Note that if you change something that affects the status of the commands - that would be returned by this method (e.g. something that makes some commands - active or inactive), you should call ApplicationCommandManager::commandStatusChanged() - to cause the manager to refresh its status. - */ - virtual void getCommandInfo (CommandID commandID, ApplicationCommandInfo& result) = 0; - - /** This must actually perform the specified command. - - If this target is able to perform the command specified by the commandID field of the - InvocationInfo structure, then it should do so, and must return true. - - If it can't handle this command, it should return false, which tells the caller to pass - the command on to the next target in line. - - @see invoke, ApplicationCommandManager::invoke - */ - virtual bool perform (const InvocationInfo& info) = 0; - - //============================================================================== - /** Makes this target invoke a command. - - Your code can call this method to invoke a command on this target, but normally - you'd call it indirectly via ApplicationCommandManager::invoke() or - ApplicationCommandManager::invokeDirectly(). - - If this target can perform the given command, it will call its perform() method to - do so. If not, then getNextCommandTarget() will be used to determine the next target - to try, and the command will be passed along to it. - - @param invocationInfo this must be correctly filled-in, describing the context for - the invocation. - @param asynchronously if false, the command will be performed before this method returns. - If true, a message will be posted so that the command will be performed - later on the message thread, and this method will return immediately. - @see perform, ApplicationCommandManager::invoke - */ - bool invoke (const InvocationInfo& invocationInfo, - const bool asynchronously); - - /** Invokes a given command directly on this target. - - This is just an easy way to call invoke() without having to fill out the InvocationInfo - structure. - */ - bool invokeDirectly (const CommandID commandID, - const bool asynchronously); - - //============================================================================== - /** Searches this target and all subsequent ones for the first one that can handle - the specified command. - - This will use getNextCommandTarget() to determine the chain of targets to try - after this one. - */ - ApplicationCommandTarget* getTargetForCommand (const CommandID commandID); - - /** Checks whether this command can currently be performed by this target. - - This will return true only if a call to getCommandInfo() doesn't set the - isDisabled flag to indicate that the command is inactive. - */ - bool isCommandActive (const CommandID commandID); - - /** If this object is a Component, this method will seach upwards in its current - UI hierarchy for the next parent component that implements the - ApplicationCommandTarget class. - - If your target is a Component, this is a very handy method to use in your - getNextCommandTarget() implementation. - */ - ApplicationCommandTarget* findFirstTargetParentComponent(); - -private: - //============================================================================== - WeakReference::Master masterReference; - friend class WeakReference; - - class CommandMessage; - friend class CommandMessage; - - bool tryToInvoke (const InvocationInfo&, bool async); - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ApplicationCommandTarget) -}; - - -#endif // JUCE_APPLICATIONCOMMANDTARGET_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/commands/juce_KeyPressMappingSet.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/commands/juce_KeyPressMappingSet.cpp deleted file mode 100644 index bcfac4e80c..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/commands/juce_KeyPressMappingSet.cpp +++ /dev/null @@ -1,412 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -KeyPressMappingSet::KeyPressMappingSet (ApplicationCommandManager& cm) - : commandManager (cm) -{ - Desktop::getInstance().addFocusChangeListener (this); -} - -KeyPressMappingSet::KeyPressMappingSet (const KeyPressMappingSet& other) - : KeyListener(), ChangeBroadcaster(), FocusChangeListener(), commandManager (other.commandManager) -{ - Desktop::getInstance().addFocusChangeListener (this); -} - -KeyPressMappingSet::~KeyPressMappingSet() -{ - Desktop::getInstance().removeFocusChangeListener (this); -} - -//============================================================================== -Array KeyPressMappingSet::getKeyPressesAssignedToCommand (const CommandID commandID) const -{ - for (int i = 0; i < mappings.size(); ++i) - if (mappings.getUnchecked(i)->commandID == commandID) - return mappings.getUnchecked (i)->keypresses; - - return Array(); -} - -void KeyPressMappingSet::addKeyPress (const CommandID commandID, const KeyPress& newKeyPress, int insertIndex) -{ - // If you specify an upper-case letter but no shift key, how is the user supposed to press it!? - // Stick to lower-case letters when defining a keypress, to avoid ambiguity. - jassert (! (CharacterFunctions::isUpperCase (newKeyPress.getTextCharacter()) - && ! newKeyPress.getModifiers().isShiftDown())); - - if (findCommandForKeyPress (newKeyPress) != commandID) - { - if (newKeyPress.isValid()) - { - for (int i = mappings.size(); --i >= 0;) - { - if (mappings.getUnchecked(i)->commandID == commandID) - { - mappings.getUnchecked(i)->keypresses.insert (insertIndex, newKeyPress); - - sendChangeMessage(); - return; - } - } - - if (const ApplicationCommandInfo* const ci = commandManager.getCommandForID (commandID)) - { - CommandMapping* const cm = new CommandMapping(); - cm->commandID = commandID; - cm->keypresses.add (newKeyPress); - cm->wantsKeyUpDownCallbacks = (ci->flags & ApplicationCommandInfo::wantsKeyUpDownCallbacks) != 0; - - mappings.add (cm); - sendChangeMessage(); - } - else - { - // If you hit this, you're trying to attach a keypress to a command ID that - // doesn't exist, so the key is not being attached. - jassertfalse; - } - } - } -} - -static void addKeyPresses (KeyPressMappingSet& set, const ApplicationCommandInfo* const ci) -{ - for (int j = 0; j < ci->defaultKeypresses.size(); ++j) - set.addKeyPress (ci->commandID, ci->defaultKeypresses.getReference (j)); -} - -void KeyPressMappingSet::resetToDefaultMappings() -{ - mappings.clear(); - - for (int i = 0; i < commandManager.getNumCommands(); ++i) - addKeyPresses (*this, commandManager.getCommandForIndex (i)); - - sendChangeMessage(); -} - -void KeyPressMappingSet::resetToDefaultMapping (const CommandID commandID) -{ - clearAllKeyPresses (commandID); - - if (const ApplicationCommandInfo* const ci = commandManager.getCommandForID (commandID)) - addKeyPresses (*this, ci); -} - -void KeyPressMappingSet::clearAllKeyPresses() -{ - if (mappings.size() > 0) - { - sendChangeMessage(); - mappings.clear(); - } -} - -void KeyPressMappingSet::clearAllKeyPresses (const CommandID commandID) -{ - for (int i = mappings.size(); --i >= 0;) - { - if (mappings.getUnchecked(i)->commandID == commandID) - { - mappings.remove (i); - sendChangeMessage(); - } - } -} - -void KeyPressMappingSet::removeKeyPress (const KeyPress& keypress) -{ - if (keypress.isValid()) - { - for (int i = mappings.size(); --i >= 0;) - { - CommandMapping& cm = *mappings.getUnchecked(i); - - for (int j = cm.keypresses.size(); --j >= 0;) - { - if (keypress == cm.keypresses [j]) - { - cm.keypresses.remove (j); - sendChangeMessage(); - } - } - } - } -} - -void KeyPressMappingSet::removeKeyPress (const CommandID commandID, const int keyPressIndex) -{ - for (int i = mappings.size(); --i >= 0;) - { - if (mappings.getUnchecked(i)->commandID == commandID) - { - mappings.getUnchecked(i)->keypresses.remove (keyPressIndex); - sendChangeMessage(); - break; - } - } -} - -//============================================================================== -CommandID KeyPressMappingSet::findCommandForKeyPress (const KeyPress& keyPress) const noexcept -{ - for (int i = 0; i < mappings.size(); ++i) - if (mappings.getUnchecked(i)->keypresses.contains (keyPress)) - return mappings.getUnchecked(i)->commandID; - - return 0; -} - -bool KeyPressMappingSet::containsMapping (const CommandID commandID, const KeyPress& keyPress) const noexcept -{ - for (int i = mappings.size(); --i >= 0;) - if (mappings.getUnchecked(i)->commandID == commandID) - return mappings.getUnchecked(i)->keypresses.contains (keyPress); - - return false; -} - -void KeyPressMappingSet::invokeCommand (const CommandID commandID, - const KeyPress& key, - const bool isKeyDown, - const int millisecsSinceKeyPressed, - Component* const originatingComponent) const -{ - ApplicationCommandTarget::InvocationInfo info (commandID); - - info.invocationMethod = ApplicationCommandTarget::InvocationInfo::fromKeyPress; - info.isKeyDown = isKeyDown; - info.keyPress = key; - info.millisecsSinceKeyPressed = millisecsSinceKeyPressed; - info.originatingComponent = originatingComponent; - - commandManager.invoke (info, false); -} - -//============================================================================== -bool KeyPressMappingSet::restoreFromXml (const XmlElement& xmlVersion) -{ - if (xmlVersion.hasTagName ("KEYMAPPINGS")) - { - if (xmlVersion.getBoolAttribute ("basedOnDefaults", true)) - { - // if the XML was created as a set of differences from the default mappings, - // (i.e. by calling createXml (true)), then we need to first restore the defaults. - resetToDefaultMappings(); - } - else - { - // if the XML was created calling createXml (false), then we need to clear all - // the keys and treat the xml as describing the entire set of mappings. - clearAllKeyPresses(); - } - - forEachXmlChildElement (xmlVersion, map) - { - const CommandID commandId = map->getStringAttribute ("commandId").getHexValue32(); - - if (commandId != 0) - { - const KeyPress key (KeyPress::createFromDescription (map->getStringAttribute ("key"))); - - if (map->hasTagName ("MAPPING")) - { - addKeyPress (commandId, key); - } - else if (map->hasTagName ("UNMAPPING")) - { - for (int i = mappings.size(); --i >= 0;) - if (mappings.getUnchecked(i)->commandID == commandId) - mappings.getUnchecked(i)->keypresses.removeAllInstancesOf (key); - } - } - } - - return true; - } - - return false; -} - -XmlElement* KeyPressMappingSet::createXml (const bool saveDifferencesFromDefaultSet) const -{ - ScopedPointer defaultSet; - - if (saveDifferencesFromDefaultSet) - { - defaultSet = new KeyPressMappingSet (commandManager); - defaultSet->resetToDefaultMappings(); - } - - XmlElement* const doc = new XmlElement ("KEYMAPPINGS"); - - doc->setAttribute ("basedOnDefaults", saveDifferencesFromDefaultSet); - - for (int i = 0; i < mappings.size(); ++i) - { - const CommandMapping& cm = *mappings.getUnchecked(i); - - for (int j = 0; j < cm.keypresses.size(); ++j) - { - if (defaultSet == nullptr - || ! defaultSet->containsMapping (cm.commandID, cm.keypresses.getReference (j))) - { - XmlElement* const map = doc->createNewChildElement ("MAPPING"); - - map->setAttribute ("commandId", String::toHexString ((int) cm.commandID)); - map->setAttribute ("description", commandManager.getDescriptionOfCommand (cm.commandID)); - map->setAttribute ("key", cm.keypresses.getReference (j).getTextDescription()); - } - } - } - - if (defaultSet != nullptr) - { - for (int i = 0; i < defaultSet->mappings.size(); ++i) - { - const CommandMapping& cm = *defaultSet->mappings.getUnchecked(i); - - for (int j = 0; j < cm.keypresses.size(); ++j) - { - if (! containsMapping (cm.commandID, cm.keypresses.getReference (j))) - { - XmlElement* const map = doc->createNewChildElement ("UNMAPPING"); - - map->setAttribute ("commandId", String::toHexString ((int) cm.commandID)); - map->setAttribute ("description", commandManager.getDescriptionOfCommand (cm.commandID)); - map->setAttribute ("key", cm.keypresses.getReference (j).getTextDescription()); - } - } - } - } - - return doc; -} - -//============================================================================== -bool KeyPressMappingSet::keyPressed (const KeyPress& key, Component* const originatingComponent) -{ - bool commandWasDisabled = false; - - for (int i = 0; i < mappings.size(); ++i) - { - CommandMapping& cm = *mappings.getUnchecked(i); - - if (cm.keypresses.contains (key)) - { - if (const ApplicationCommandInfo* const ci = commandManager.getCommandForID (cm.commandID)) - { - if ((ci->flags & ApplicationCommandInfo::wantsKeyUpDownCallbacks) == 0) - { - ApplicationCommandInfo info (0); - - if (commandManager.getTargetForCommand (cm.commandID, info) != nullptr) - { - if ((info.flags & ApplicationCommandInfo::isDisabled) == 0) - { - invokeCommand (cm.commandID, key, true, 0, originatingComponent); - return true; - } - - commandWasDisabled = true; - } - } - } - } - } - - if (originatingComponent != nullptr && commandWasDisabled) - originatingComponent->getLookAndFeel().playAlertSound(); - - return false; -} - -bool KeyPressMappingSet::keyStateChanged (const bool /*isKeyDown*/, Component* originatingComponent) -{ - bool used = false; - const uint32 now = Time::getMillisecondCounter(); - - for (int i = mappings.size(); --i >= 0;) - { - CommandMapping& cm = *mappings.getUnchecked(i); - - if (cm.wantsKeyUpDownCallbacks) - { - for (int j = cm.keypresses.size(); --j >= 0;) - { - const KeyPress key (cm.keypresses.getReference (j)); - const bool isDown = key.isCurrentlyDown(); - - int keyPressEntryIndex = 0; - bool wasDown = false; - - for (int k = keysDown.size(); --k >= 0;) - { - if (key == keysDown.getUnchecked(k)->key) - { - keyPressEntryIndex = k; - wasDown = true; - used = true; - break; - } - } - - if (isDown != wasDown) - { - int millisecs = 0; - - if (isDown) - { - KeyPressTime* const k = new KeyPressTime(); - k->key = key; - k->timeWhenPressed = now; - - keysDown.add (k); - } - else - { - const uint32 pressTime = keysDown.getUnchecked (keyPressEntryIndex)->timeWhenPressed; - - if (now > pressTime) - millisecs = (int) (now - pressTime); - - keysDown.remove (keyPressEntryIndex); - } - - invokeCommand (cm.commandID, key, isDown, millisecs, originatingComponent); - used = true; - } - } - } - } - - return used; -} - -void KeyPressMappingSet::globalFocusChanged (Component* focusedComponent) -{ - if (focusedComponent != nullptr) - focusedComponent->keyStateChanged (false); -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/commands/juce_KeyPressMappingSet.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/commands/juce_KeyPressMappingSet.h deleted file mode 100644 index d3351aca58..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/commands/juce_KeyPressMappingSet.h +++ /dev/null @@ -1,245 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_KEYPRESSMAPPINGSET_H_INCLUDED -#define JUCE_KEYPRESSMAPPINGSET_H_INCLUDED - - -//============================================================================== -/** - Manages and edits a list of keypresses, which it uses to invoke the appropriate - command in an ApplicationCommandManager. - - Normally, you won't actually create a KeyPressMappingSet directly, because - each ApplicationCommandManager contains its own KeyPressMappingSet, so typically - you'd create yourself an ApplicationCommandManager, and call its - ApplicationCommandManager::getKeyMappings() method to get a pointer to its - KeyPressMappingSet. - - For one of these to actually use keypresses, you'll need to add it as a KeyListener - to the top-level component for which you want to handle keystrokes. So for example: - - @code - class MyMainWindow : public Component - { - ApplicationCommandManager* myCommandManager; - - public: - MyMainWindow() - { - myCommandManager = new ApplicationCommandManager(); - - // first, make sure the command manager has registered all the commands that its - // targets can perform.. - myCommandManager->registerAllCommandsForTarget (myCommandTarget1); - myCommandManager->registerAllCommandsForTarget (myCommandTarget2); - - // this will use the command manager to initialise the KeyPressMappingSet with - // the default keypresses that were specified when the targets added their commands - // to the manager. - myCommandManager->getKeyMappings()->resetToDefaultMappings(); - - // having set up the default key-mappings, you might now want to load the last set - // of mappings that the user configured. - myCommandManager->getKeyMappings()->restoreFromXml (lastSavedKeyMappingsXML); - - // Now tell our top-level window to send any keypresses that arrive to the - // KeyPressMappingSet, which will use them to invoke the appropriate commands. - addKeyListener (myCommandManager->getKeyMappings()); - } - - ... - } - @endcode - - KeyPressMappingSet derives from ChangeBroadcaster so that interested parties can - register to be told when a command or mapping is added, removed, etc. - - There's also a UI component called KeyMappingEditorComponent that can be used - to easily edit the key mappings. - - @see Component::addKeyListener(), KeyMappingEditorComponent, ApplicationCommandManager -*/ -class JUCE_API KeyPressMappingSet : public KeyListener, - public ChangeBroadcaster, - private FocusChangeListener -{ -public: - //============================================================================== - /** Creates a KeyPressMappingSet for a given command manager. - - Normally, you won't actually create a KeyPressMappingSet directly, because - each ApplicationCommandManager contains its own KeyPressMappingSet, so the - best thing to do is to create your ApplicationCommandManager, and use the - ApplicationCommandManager::getKeyMappings() method to access its mappings. - - When a suitable keypress happens, the manager's invoke() method will be - used to invoke the appropriate command. - - @see ApplicationCommandManager - */ - explicit KeyPressMappingSet (ApplicationCommandManager&); - - /** Creates an copy of a KeyPressMappingSet. */ - KeyPressMappingSet (const KeyPressMappingSet&); - - /** Destructor. */ - ~KeyPressMappingSet(); - - //============================================================================== - ApplicationCommandManager& getCommandManager() const noexcept { return commandManager; } - - //============================================================================== - /** Returns a list of keypresses that are assigned to a particular command. - - @param commandID the command's ID - */ - Array getKeyPressesAssignedToCommand (CommandID commandID) const; - - /** Assigns a keypress to a command. - - If the keypress is already assigned to a different command, it will first be - removed from that command, to avoid it triggering multiple functions. - - @param commandID the ID of the command that you want to add a keypress to. If - this is 0, the keypress will be removed from anything that it - was previously assigned to, but not re-assigned - @param newKeyPress the new key-press - @param insertIndex if this is less than zero, the key will be appended to the - end of the list of keypresses; otherwise the new keypress will - be inserted into the existing list at this index - */ - void addKeyPress (CommandID commandID, - const KeyPress& newKeyPress, - int insertIndex = -1); - - /** Reset all mappings to the defaults, as dictated by the ApplicationCommandManager. - @see resetToDefaultMapping - */ - void resetToDefaultMappings(); - - /** Resets all key-mappings to the defaults for a particular command. - @see resetToDefaultMappings - */ - void resetToDefaultMapping (CommandID commandID); - - /** Removes all keypresses that are assigned to any commands. */ - void clearAllKeyPresses(); - - /** Removes all keypresses that are assigned to a particular command. */ - void clearAllKeyPresses (CommandID commandID); - - /** Removes one of the keypresses that are assigned to a command. - See the getKeyPressesAssignedToCommand() for the list of keypresses to - which the keyPressIndex refers. - */ - void removeKeyPress (CommandID commandID, int keyPressIndex); - - /** Removes a keypress from any command that it may be assigned to. */ - void removeKeyPress (const KeyPress& keypress); - - /** Returns true if the given command is linked to this key. */ - bool containsMapping (CommandID commandID, const KeyPress& keyPress) const noexcept; - - //============================================================================== - /** Looks for a command that corresponds to a keypress. - @returns the UID of the command or 0 if none was found - */ - CommandID findCommandForKeyPress (const KeyPress& keyPress) const noexcept; - - //============================================================================== - /** Tries to recreate the mappings from a previously stored state. - - The XML passed in must have been created by the createXml() method. - - If the stored state makes any reference to commands that aren't - currently available, these will be ignored. - - If the set of mappings being loaded was a set of differences (using createXml (true)), - then this will call resetToDefaultMappings() and then merge the saved mappings - on top. If the saved set was created with createXml (false), then this method - will first clear all existing mappings and load the saved ones as a complete set. - - @returns true if it manages to load the XML correctly - @see createXml - */ - bool restoreFromXml (const XmlElement& xmlVersion); - - /** Creates an XML representation of the current mappings. - - This will produce a lump of XML that can be later reloaded using - restoreFromXml() to recreate the current mapping state. - - The object that is returned must be deleted by the caller. - - @param saveDifferencesFromDefaultSet if this is false, then all keypresses - will be saved into the XML. If it's true, then the XML will - only store the differences between the current mappings and - the default mappings you'd get from calling resetToDefaultMappings(). - The advantage of saving a set of differences from the default is that - if you change the default mappings (in a new version of your app, for - example), then these will be merged into a user's saved preferences. - - @see restoreFromXml - */ - XmlElement* createXml (bool saveDifferencesFromDefaultSet) const; - - //============================================================================== - /** @internal */ - bool keyPressed (const KeyPress&, Component*) override; - /** @internal */ - bool keyStateChanged (bool isKeyDown, Component*) override; - /** @internal */ - void globalFocusChanged (Component*) override; - -private: - //============================================================================== - ApplicationCommandManager& commandManager; - - struct CommandMapping - { - CommandID commandID; - Array keypresses; - bool wantsKeyUpDownCallbacks; - }; - - OwnedArray mappings; - - struct KeyPressTime - { - KeyPress key; - uint32 timeWhenPressed; - }; - - OwnedArray keysDown; - - void invokeCommand (const CommandID, const KeyPress&, const bool isKeyDown, - const int millisecsSinceKeyPressed, Component* originator) const; - - KeyPressMappingSet& operator= (const KeyPressMappingSet&); - JUCE_LEAK_DETECTOR (KeyPressMappingSet) -}; - - -#endif // JUCE_KEYPRESSMAPPINGSET_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/components/juce_CachedComponentImage.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/components/juce_CachedComponentImage.h deleted file mode 100644 index 3f273cba07..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/components/juce_CachedComponentImage.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_CACHEDCOMPONENTIMAGE_H_INCLUDED -#define JUCE_CACHEDCOMPONENTIMAGE_H_INCLUDED - - -//============================================================================== -/** - Base class used internally for structures that can store cached images of - component state. - - Most people are unlikely to ever need to know about this class - it's really - only for power-users! - - @see Component::setCachedComponentImage -*/ -class JUCE_API CachedComponentImage -{ -public: - CachedComponentImage() noexcept {} - virtual ~CachedComponentImage() {} - - //============================================================================== - /** Called as part of the parent component's paint method, this must draw - the given component into the target graphics context, using the cached - version where possible. - */ - virtual void paint (Graphics&) = 0; - - /** Invalidates all cached image data. - @returns true if the peer should also be repainted, or false if this object - handles all repaint work internally. - */ - virtual bool invalidateAll() = 0; - - /** Invalidates a section of the cached image data. - @returns true if the peer should also be repainted, or false if this object - handles all repaint work internally. - */ - virtual bool invalidate (const Rectangle& area) = 0; - - /** Called to indicate that the component is no longer active, so - any cached data should be released if possible. - */ - virtual void releaseResources() = 0; -}; - -#endif // JUCE_CACHEDCOMPONENTIMAGE_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/components/juce_Component.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/components/juce_Component.cpp deleted file mode 100644 index 7cbe59fb97..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/components/juce_Component.cpp +++ /dev/null @@ -1,3029 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -Component* Component::currentlyFocusedComponent = nullptr; - - -//============================================================================== -class Component::MouseListenerList -{ -public: - MouseListenerList() noexcept - : numDeepMouseListeners (0) - { - } - - void addListener (MouseListener* const newListener, const bool wantsEventsForAllNestedChildComponents) - { - if (! listeners.contains (newListener)) - { - if (wantsEventsForAllNestedChildComponents) - { - listeners.insert (0, newListener); - ++numDeepMouseListeners; - } - else - { - listeners.add (newListener); - } - } - } - - void removeListener (MouseListener* const listenerToRemove) - { - const int index = listeners.indexOf (listenerToRemove); - - if (index >= 0) - { - if (index < numDeepMouseListeners) - --numDeepMouseListeners; - - listeners.remove (index); - } - } - - static void sendMouseEvent (Component& comp, Component::BailOutChecker& checker, - void (MouseListener::*eventMethod) (const MouseEvent&), const MouseEvent& e) - { - if (checker.shouldBailOut()) - return; - - if (MouseListenerList* const list = comp.mouseListeners) - { - for (int i = list->listeners.size(); --i >= 0;) - { - (list->listeners.getUnchecked(i)->*eventMethod) (e); - - if (checker.shouldBailOut()) - return; - - i = jmin (i, list->listeners.size()); - } - } - - for (Component* p = comp.parentComponent; p != nullptr; p = p->parentComponent) - { - MouseListenerList* const list = p->mouseListeners; - - if (list != nullptr && list->numDeepMouseListeners > 0) - { - BailOutChecker2 checker2 (checker, p); - - for (int i = list->numDeepMouseListeners; --i >= 0;) - { - (list->listeners.getUnchecked(i)->*eventMethod) (e); - - if (checker2.shouldBailOut()) - return; - - i = jmin (i, list->numDeepMouseListeners); - } - } - } - } - - static void sendWheelEvent (Component& comp, Component::BailOutChecker& checker, - const MouseEvent& e, const MouseWheelDetails& wheel) - { - if (MouseListenerList* const list = comp.mouseListeners) - { - for (int i = list->listeners.size(); --i >= 0;) - { - list->listeners.getUnchecked(i)->mouseWheelMove (e, wheel); - - if (checker.shouldBailOut()) - return; - - i = jmin (i, list->listeners.size()); - } - } - - for (Component* p = comp.parentComponent; p != nullptr; p = p->parentComponent) - { - MouseListenerList* const list = p->mouseListeners; - - if (list != nullptr && list->numDeepMouseListeners > 0) - { - BailOutChecker2 checker2 (checker, p); - - for (int i = list->numDeepMouseListeners; --i >= 0;) - { - list->listeners.getUnchecked(i)->mouseWheelMove (e, wheel); - - if (checker2.shouldBailOut()) - return; - - i = jmin (i, list->numDeepMouseListeners); - } - } - } - } - -private: - Array listeners; - int numDeepMouseListeners; - - class BailOutChecker2 - { - public: - BailOutChecker2 (Component::BailOutChecker& boc, Component* const comp) - : checker (boc), safePointer (comp) - { - } - - bool shouldBailOut() const noexcept - { - return checker.shouldBailOut() || safePointer == 0; - } - - private: - Component::BailOutChecker& checker; - const WeakReference safePointer; - - JUCE_DECLARE_NON_COPYABLE (BailOutChecker2) - }; - - JUCE_DECLARE_NON_COPYABLE (MouseListenerList) -}; - -//============================================================================== -struct FocusRestorer -{ - FocusRestorer() : lastFocus (Component::getCurrentlyFocusedComponent()) {} - - ~FocusRestorer() - { - if (lastFocus != nullptr && ! lastFocus->isCurrentlyBlockedByAnotherModalComponent()) - lastFocus->grabKeyboardFocus(); - } - - WeakReference lastFocus; - - JUCE_DECLARE_NON_COPYABLE (FocusRestorer) -}; - -//============================================================================== -struct ScalingHelpers -{ - template - static PointOrRect unscaledScreenPosToScaled (float scale, PointOrRect pos) noexcept - { - return scale != 1.0f ? pos / scale : pos; - } - - template - static PointOrRect scaledScreenPosToUnscaled (float scale, PointOrRect pos) noexcept - { - return scale != 1.0f ? pos * scale : pos; - } - - // For these, we need to avoid getSmallestIntegerContainer being used, which causes - // judder when moving windows - static Rectangle unscaledScreenPosToScaled (float scale, const Rectangle& pos) noexcept - { - return scale != 1.0f ? Rectangle (roundToInt (pos.getX() / scale), - roundToInt (pos.getY() / scale), - roundToInt (pos.getWidth() / scale), - roundToInt (pos.getHeight() / scale)) : pos; - } - - static Rectangle scaledScreenPosToUnscaled (float scale, Rectangle& pos) noexcept - { - return scale != 1.0f ? Rectangle (roundToInt (pos.getX() * scale), - roundToInt (pos.getY() * scale), - roundToInt (pos.getWidth() * scale), - roundToInt (pos.getHeight() * scale)) : pos; - } - - template - static PointOrRect unscaledScreenPosToScaled (PointOrRect pos) noexcept - { - return unscaledScreenPosToScaled (Desktop::getInstance().getGlobalScaleFactor(), pos); - } - - template - static PointOrRect scaledScreenPosToUnscaled (PointOrRect pos) noexcept - { - return scaledScreenPosToUnscaled (Desktop::getInstance().getGlobalScaleFactor(), pos); - } - - template - static PointOrRect unscaledScreenPosToScaled (const Component& comp, PointOrRect pos) noexcept - { - return unscaledScreenPosToScaled (comp.getDesktopScaleFactor(), pos); - } - - template - static PointOrRect scaledScreenPosToUnscaled (const Component& comp, PointOrRect pos) noexcept - { - return scaledScreenPosToUnscaled (comp.getDesktopScaleFactor(), pos); - } - - static Point addPosition (Point p, const Component& c) noexcept { return p + c.getPosition(); } - static Rectangle addPosition (Rectangle p, const Component& c) noexcept { return p + c.getPosition(); } - static Point addPosition (Point p, const Component& c) noexcept { return p + c.getPosition().toFloat(); } - static Rectangle addPosition (Rectangle p, const Component& c) noexcept { return p + c.getPosition().toFloat(); } - static Point subtractPosition (Point p, const Component& c) noexcept { return p - c.getPosition(); } - static Rectangle subtractPosition (Rectangle p, const Component& c) noexcept { return p - c.getPosition(); } - static Point subtractPosition (Point p, const Component& c) noexcept { return p - c.getPosition().toFloat(); } - static Rectangle subtractPosition (Rectangle p, const Component& c) noexcept { return p - c.getPosition().toFloat(); } -}; - -//============================================================================== -struct Component::ComponentHelpers -{ - #if JUCE_MODAL_LOOPS_PERMITTED - static void* runModalLoopCallback (void* userData) - { - return (void*) (pointer_sized_int) static_cast (userData)->runModalLoop(); - } - #endif - - static Identifier getColourPropertyId (int colourId) - { - char reversedHex[32]; - char* t = reversedHex; - - for (unsigned int v = (unsigned int) colourId;;) - { - *t++ = "0123456789abcdef" [(int) (v & 15)]; - v >>= 4; - - if (v == 0) - break; - } - - char destBuffer[32]; - char* dest = destBuffer; - memcpy (dest, "jcclr_", 6); - dest += 6; - - while (t > reversedHex) - *dest++ = *--t; - - *dest++ = 0; - return destBuffer; - } - - //============================================================================== - static inline bool hitTest (Component& comp, Point localPoint) - { - return isPositiveAndBelow (localPoint.x, comp.getWidth()) - && isPositiveAndBelow (localPoint.y, comp.getHeight()) - && comp.hitTest (localPoint.x, localPoint.y); - } - - // converts an unscaled position within a peer to the local position within that peer's component - template - static PointOrRect rawPeerPositionToLocal (const Component& comp, PointOrRect pos) noexcept - { - if (comp.isTransformed()) - pos = pos.transformedBy (comp.getTransform().inverted()); - - return ScalingHelpers::unscaledScreenPosToScaled (comp, pos); - } - - // converts a position within a peer's component to the unscaled position within the peer - template - static PointOrRect localPositionToRawPeerPos (const Component& comp, PointOrRect pos) noexcept - { - if (comp.isTransformed()) - pos = pos.transformedBy (comp.getTransform()); - - return ScalingHelpers::scaledScreenPosToUnscaled (comp, pos); - } - - template - static PointOrRect convertFromParentSpace (const Component& comp, PointOrRect pointInParentSpace) - { - if (comp.affineTransform != nullptr) - pointInParentSpace = pointInParentSpace.transformedBy (comp.affineTransform->inverted()); - - if (comp.isOnDesktop()) - { - if (ComponentPeer* peer = comp.getPeer()) - pointInParentSpace = ScalingHelpers::unscaledScreenPosToScaled - (comp, peer->globalToLocal (ScalingHelpers::scaledScreenPosToUnscaled (pointInParentSpace))); - else - jassertfalse; - } - else - { - pointInParentSpace = ScalingHelpers::subtractPosition (pointInParentSpace, comp); - } - - return pointInParentSpace; - } - - template - static PointOrRect convertToParentSpace (const Component& comp, PointOrRect pointInLocalSpace) - { - if (comp.isOnDesktop()) - { - if (ComponentPeer* peer = comp.getPeer()) - pointInLocalSpace = ScalingHelpers::unscaledScreenPosToScaled - (peer->localToGlobal (ScalingHelpers::scaledScreenPosToUnscaled (comp, pointInLocalSpace))); - else - jassertfalse; - } - else - { - pointInLocalSpace = ScalingHelpers::addPosition (pointInLocalSpace, comp); - } - - if (comp.affineTransform != nullptr) - pointInLocalSpace = pointInLocalSpace.transformedBy (*comp.affineTransform); - - return pointInLocalSpace; - } - - template - static PointOrRect convertFromDistantParentSpace (const Component* parent, const Component& target, const PointOrRect& coordInParent) - { - const Component* const directParent = target.getParentComponent(); - jassert (directParent != nullptr); - - if (directParent == parent) - return convertFromParentSpace (target, coordInParent); - - return convertFromParentSpace (target, convertFromDistantParentSpace (parent, *directParent, coordInParent)); - } - - template - static PointOrRect convertCoordinate (const Component* target, const Component* source, PointOrRect p) - { - while (source != nullptr) - { - if (source == target) - return p; - - if (source->isParentOf (target)) - return convertFromDistantParentSpace (source, *target, p); - - p = convertToParentSpace (*source, p); - source = source->getParentComponent(); - } - - jassert (source == nullptr); - if (target == nullptr) - return p; - - const Component* const topLevelComp = target->getTopLevelComponent(); - - p = convertFromParentSpace (*topLevelComp, p); - - if (topLevelComp == target) - return p; - - return convertFromDistantParentSpace (topLevelComp, *target, p); - } - - static bool clipObscuredRegions (const Component& comp, Graphics& g, const Rectangle& clipRect, Point delta) - { - bool nothingChanged = true; - - for (int i = comp.childComponentList.size(); --i >= 0;) - { - const Component& child = *comp.childComponentList.getUnchecked(i); - - if (child.isVisible() && ! child.isTransformed()) - { - const Rectangle newClip (clipRect.getIntersection (child.bounds)); - - if (! newClip.isEmpty()) - { - if (child.isOpaque() && child.componentTransparency == 0) - { - g.excludeClipRegion (newClip + delta); - nothingChanged = false; - } - else - { - const Point childPos (child.getPosition()); - if (clipObscuredRegions (child, g, newClip - childPos, childPos + delta)) - nothingChanged = false; - } - } - } - } - - return nothingChanged; - } - - static Rectangle getParentOrMainMonitorBounds (const Component& comp) - { - if (Component* p = comp.getParentComponent()) - return p->getLocalBounds(); - - return Desktop::getInstance().getDisplays().getMainDisplay().userArea; - } -}; - -//============================================================================== -Component::Component() noexcept - : parentComponent (nullptr), - lookAndFeel (nullptr), - effect (nullptr), - componentFlags (0), - componentTransparency (0) -{ -} - -Component::Component (const String& name) noexcept - : componentName (name), - parentComponent (nullptr), - lookAndFeel (nullptr), - effect (nullptr), - componentFlags (0), - componentTransparency (0) -{ -} - -Component::~Component() -{ - static_jassert (sizeof (flags) <= sizeof (componentFlags)); - - componentListeners.call (&ComponentListener::componentBeingDeleted, *this); - - masterReference.clear(); - - while (childComponentList.size() > 0) - removeChildComponent (childComponentList.size() - 1, false, true); - - if (parentComponent != nullptr) - parentComponent->removeChildComponent (parentComponent->childComponentList.indexOf (this), true, false); - else if (currentlyFocusedComponent == this || isParentOf (currentlyFocusedComponent)) - giveAwayFocus (currentlyFocusedComponent != this); - - if (flags.hasHeavyweightPeerFlag) - removeFromDesktop(); - - // Something has added some children to this component during its destructor! Not a smart idea! - jassert (childComponentList.size() == 0); -} - -//============================================================================== -void Component::setName (const String& name) -{ - // if component methods are being called from threads other than the message - // thread, you'll need to use a MessageManagerLock object to make sure it's thread-safe. - ASSERT_MESSAGE_MANAGER_IS_LOCKED_OR_OFFSCREEN - - if (componentName != name) - { - componentName = name; - - if (flags.hasHeavyweightPeerFlag) - if (ComponentPeer* const peer = getPeer()) - peer->setTitle (name); - - BailOutChecker checker (this); - componentListeners.callChecked (checker, &ComponentListener::componentNameChanged, *this); - } -} - -void Component::setComponentID (const String& newID) -{ - componentID = newID; -} - -void Component::setVisible (bool shouldBeVisible) -{ - if (flags.visibleFlag != shouldBeVisible) - { - // if component methods are being called from threads other than the message - // thread, you'll need to use a MessageManagerLock object to make sure it's thread-safe. - ASSERT_MESSAGE_MANAGER_IS_LOCKED_OR_OFFSCREEN - - const WeakReference safePointer (this); - flags.visibleFlag = shouldBeVisible; - - if (shouldBeVisible) - repaint(); - else - repaintParent(); - - sendFakeMouseMove(); - - if (! shouldBeVisible) - { - if (cachedImage != nullptr) - cachedImage->releaseResources(); - - if (currentlyFocusedComponent == this || isParentOf (currentlyFocusedComponent)) - { - if (parentComponent != nullptr) - parentComponent->grabKeyboardFocus(); - else - giveAwayFocus (true); - } - } - - if (safePointer != nullptr) - { - sendVisibilityChangeMessage(); - - if (safePointer != nullptr && flags.hasHeavyweightPeerFlag) - { - if (ComponentPeer* const peer = getPeer()) - { - peer->setVisible (shouldBeVisible); - internalHierarchyChanged(); - } - } - } - } -} - -void Component::visibilityChanged() {} - -void Component::sendVisibilityChangeMessage() -{ - BailOutChecker checker (this); - visibilityChanged(); - - if (! checker.shouldBailOut()) - componentListeners.callChecked (checker, &ComponentListener::componentVisibilityChanged, *this); -} - -bool Component::isShowing() const -{ - if (! flags.visibleFlag) - return false; - - if (parentComponent != nullptr) - return parentComponent->isShowing(); - - if (const ComponentPeer* const peer = getPeer()) - return ! peer->isMinimised(); - - return false; -} - -//============================================================================== -void* Component::getWindowHandle() const -{ - if (const ComponentPeer* const peer = getPeer()) - return peer->getNativeHandle(); - - return nullptr; -} - -//============================================================================== -void Component::addToDesktop (int styleWanted, void* nativeWindowToAttachTo) -{ - // if component methods are being called from threads other than the message - // thread, you'll need to use a MessageManagerLock object to make sure it's thread-safe. - ASSERT_MESSAGE_MANAGER_IS_LOCKED - - if (isOpaque()) - styleWanted &= ~ComponentPeer::windowIsSemiTransparent; - else - styleWanted |= ComponentPeer::windowIsSemiTransparent; - - // don't use getPeer(), so that we only get the peer that's specifically - // for this comp, and not for one of its parents. - ComponentPeer* peer = ComponentPeer::getPeerFor (this); - - if (peer == nullptr || styleWanted != peer->getStyleFlags()) - { - const WeakReference safePointer (this); - - #if JUCE_LINUX - // it's wise to give the component a non-zero size before - // putting it on the desktop, as X windows get confused by this, and - // a (1, 1) minimum size is enforced here. - setSize (jmax (1, getWidth()), - jmax (1, getHeight())); - #endif - - const Point topLeft (getScreenPosition()); - - bool wasFullscreen = false; - bool wasMinimised = false; - ComponentBoundsConstrainer* currentConstrainer = nullptr; - Rectangle oldNonFullScreenBounds; - int oldRenderingEngine = -1; - - if (peer != nullptr) - { - ScopedPointer oldPeerToDelete (peer); - - wasFullscreen = peer->isFullScreen(); - wasMinimised = peer->isMinimised(); - currentConstrainer = peer->getConstrainer(); - oldNonFullScreenBounds = peer->getNonFullScreenBounds(); - oldRenderingEngine = peer->getCurrentRenderingEngine(); - - flags.hasHeavyweightPeerFlag = false; - Desktop::getInstance().removeDesktopComponent (this); - internalHierarchyChanged(); // give comps a chance to react to the peer change before the old peer is deleted. - - if (safePointer == nullptr) - return; - - setTopLeftPosition (topLeft); - } - - if (parentComponent != nullptr) - parentComponent->removeChildComponent (this); - - if (safePointer != nullptr) - { - flags.hasHeavyweightPeerFlag = true; - - peer = createNewPeer (styleWanted, nativeWindowToAttachTo); - - Desktop::getInstance().addDesktopComponent (this); - - bounds.setPosition (topLeft); - peer->updateBounds(); - - if (oldRenderingEngine >= 0) - peer->setCurrentRenderingEngine (oldRenderingEngine); - - peer->setVisible (isVisible()); - - peer = ComponentPeer::getPeerFor (this); - if (peer == nullptr) - return; - - if (wasFullscreen) - { - peer->setFullScreen (true); - peer->setNonFullScreenBounds (oldNonFullScreenBounds); - } - - if (wasMinimised) - peer->setMinimised (true); - - #if JUCE_WINDOWS - if (isAlwaysOnTop()) - peer->setAlwaysOnTop (true); - #endif - - peer->setConstrainer (currentConstrainer); - - repaint(); - internalHierarchyChanged(); - } - } -} - -void Component::removeFromDesktop() -{ - // if component methods are being called from threads other than the message - // thread, you'll need to use a MessageManagerLock object to make sure it's thread-safe. - ASSERT_MESSAGE_MANAGER_IS_LOCKED_OR_OFFSCREEN - - if (flags.hasHeavyweightPeerFlag) - { - ComponentPeer* const peer = ComponentPeer::getPeerFor (this); - jassert (peer != nullptr); - - flags.hasHeavyweightPeerFlag = false; - delete peer; - - Desktop::getInstance().removeDesktopComponent (this); - } -} - -bool Component::isOnDesktop() const noexcept -{ - return flags.hasHeavyweightPeerFlag; -} - -ComponentPeer* Component::getPeer() const -{ - if (flags.hasHeavyweightPeerFlag) - return ComponentPeer::getPeerFor (this); - - if (parentComponent == nullptr) - return nullptr; - - return parentComponent->getPeer(); -} - -void Component::userTriedToCloseWindow() -{ - /* This means that the user's trying to get rid of your window with the 'close window' system - menu option (on windows) or possibly the task manager - you should really handle this - and delete or hide your component in an appropriate way. - - If you want to ignore the event and don't want to trigger this assertion, just override - this method and do nothing. - */ - jassertfalse; -} - -void Component::minimisationStateChanged (bool) {} - -float Component::getDesktopScaleFactor() const { return Desktop::getInstance().getGlobalScaleFactor(); } - -//============================================================================== -void Component::setOpaque (const bool shouldBeOpaque) -{ - if (shouldBeOpaque != flags.opaqueFlag) - { - flags.opaqueFlag = shouldBeOpaque; - - if (flags.hasHeavyweightPeerFlag) - if (const ComponentPeer* const peer = ComponentPeer::getPeerFor (this)) - addToDesktop (peer->getStyleFlags()); // recreates the heavyweight window - - repaint(); - } -} - -bool Component::isOpaque() const noexcept -{ - return flags.opaqueFlag; -} - -//============================================================================== -class StandardCachedComponentImage : public CachedComponentImage -{ -public: - StandardCachedComponentImage (Component& c) noexcept : owner (c), scale (1.0f) {} - - void paint (Graphics& g) override - { - scale = g.getInternalContext().getPhysicalPixelScaleFactor(); - const Rectangle compBounds (owner.getLocalBounds()); - const Rectangle imageBounds (compBounds * scale); - - if (image.isNull() || image.getBounds() != imageBounds) - { - image = Image (owner.isOpaque() ? Image::RGB - : Image::ARGB, - jmax (1, imageBounds.getWidth()), - jmax (1, imageBounds.getHeight()), - ! owner.isOpaque()); - - validArea.clear(); - } - - { - Graphics imG (image); - LowLevelGraphicsContext& lg = imG.getInternalContext(); - - for (const Rectangle* i = validArea.begin(), * const e = validArea.end(); i != e; ++i) - lg.excludeClipRectangle (*i); - - if (! lg.isClipEmpty()) - { - if (! owner.isOpaque()) - { - lg.setFill (Colours::transparentBlack); - lg.fillRect (imageBounds, true); - lg.setFill (Colours::black); - } - - lg.addTransform (AffineTransform::scale (scale)); - owner.paintEntireComponent (imG, true); - } - } - - validArea = imageBounds; - - g.setColour (Colours::black.withAlpha (owner.getAlpha())); - g.drawImageTransformed (image, AffineTransform::scale (compBounds.getWidth() / (float) imageBounds.getWidth(), - compBounds.getHeight() / (float) imageBounds.getHeight()), false); - } - - bool invalidateAll() override { validArea.clear(); return true; } - bool invalidate (const Rectangle& area) override { validArea.subtract (area * scale); return true; } - void releaseResources() override { image = Image::null; } - -private: - Image image; - RectangleList validArea; - Component& owner; - float scale; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (StandardCachedComponentImage) -}; - -void Component::setCachedComponentImage (CachedComponentImage* newCachedImage) -{ - if (cachedImage != newCachedImage) - { - cachedImage = newCachedImage; - repaint(); - } -} - -void Component::setBufferedToImage (const bool shouldBeBuffered) -{ - // This assertion means that this component is already using a custom CachedComponentImage, - // so by calling setBufferedToImage, you'll be deleting the custom one - this is almost certainly - // not what you wanted to happen... If you really do know what you're doing here, and want to - // avoid this assertion, just call setCachedComponentImage (nullptr) before setBufferedToImage(). - jassert (cachedImage == nullptr || dynamic_cast (cachedImage.get()) != nullptr); - - if (shouldBeBuffered) - { - if (cachedImage == nullptr) - cachedImage = new StandardCachedComponentImage (*this); - } - else - { - cachedImage = nullptr; - } -} - -//============================================================================== -void Component::reorderChildInternal (const int sourceIndex, const int destIndex) -{ - if (sourceIndex != destIndex) - { - Component* const c = childComponentList.getUnchecked (sourceIndex); - jassert (c != nullptr); - c->repaintParent(); - - childComponentList.move (sourceIndex, destIndex); - - sendFakeMouseMove(); - internalChildrenChanged(); - } -} - -void Component::toFront (const bool setAsForeground) -{ - // if component methods are being called from threads other than the message - // thread, you'll need to use a MessageManagerLock object to make sure it's thread-safe. - ASSERT_MESSAGE_MANAGER_IS_LOCKED_OR_OFFSCREEN - - if (flags.hasHeavyweightPeerFlag) - { - if (ComponentPeer* const peer = getPeer()) - { - peer->toFront (setAsForeground); - - if (setAsForeground && ! hasKeyboardFocus (true)) - grabKeyboardFocus(); - } - } - else if (parentComponent != nullptr) - { - const Array& childList = parentComponent->childComponentList; - - if (childList.getLast() != this) - { - const int index = childList.indexOf (this); - - if (index >= 0) - { - int insertIndex = -1; - - if (! flags.alwaysOnTopFlag) - { - insertIndex = childList.size() - 1; - - while (insertIndex > 0 && childList.getUnchecked (insertIndex)->isAlwaysOnTop()) - --insertIndex; - } - - parentComponent->reorderChildInternal (index, insertIndex); - } - } - - if (setAsForeground) - { - internalBroughtToFront(); - grabKeyboardFocus(); - } - } -} - -void Component::toBehind (Component* const other) -{ - if (other != nullptr && other != this) - { - // the two components must belong to the same parent.. - jassert (parentComponent == other->parentComponent); - - if (parentComponent != nullptr) - { - const Array& childList = parentComponent->childComponentList; - const int index = childList.indexOf (this); - - if (index >= 0 && childList [index + 1] != other) - { - int otherIndex = childList.indexOf (other); - - if (otherIndex >= 0) - { - if (index < otherIndex) - --otherIndex; - - parentComponent->reorderChildInternal (index, otherIndex); - } - } - } - else if (isOnDesktop()) - { - jassert (other->isOnDesktop()); - - if (other->isOnDesktop()) - { - ComponentPeer* const us = getPeer(); - ComponentPeer* const them = other->getPeer(); - - jassert (us != nullptr && them != nullptr); - if (us != nullptr && them != nullptr) - us->toBehind (them); - } - } - } -} - -void Component::toBack() -{ - if (isOnDesktop()) - { - jassertfalse; //xxx need to add this to native window - } - else if (parentComponent != nullptr) - { - const Array& childList = parentComponent->childComponentList; - - if (childList.getFirst() != this) - { - const int index = childList.indexOf (this); - - if (index > 0) - { - int insertIndex = 0; - - if (flags.alwaysOnTopFlag) - while (insertIndex < childList.size() && ! childList.getUnchecked (insertIndex)->isAlwaysOnTop()) - ++insertIndex; - - parentComponent->reorderChildInternal (index, insertIndex); - } - } - } -} - -void Component::setAlwaysOnTop (const bool shouldStayOnTop) -{ - if (shouldStayOnTop != flags.alwaysOnTopFlag) - { - BailOutChecker checker (this); - - flags.alwaysOnTopFlag = shouldStayOnTop; - - if (isOnDesktop()) - { - if (ComponentPeer* const peer = getPeer()) - { - if (! peer->setAlwaysOnTop (shouldStayOnTop)) - { - // some kinds of peer can't change their always-on-top status, so - // for these, we'll need to create a new window - const int oldFlags = peer->getStyleFlags(); - removeFromDesktop(); - addToDesktop (oldFlags); - } - } - } - - if (shouldStayOnTop && ! checker.shouldBailOut()) - toFront (false); - - if (! checker.shouldBailOut()) - internalHierarchyChanged(); - } -} - -bool Component::isAlwaysOnTop() const noexcept -{ - return flags.alwaysOnTopFlag; -} - -//============================================================================== -int Component::proportionOfWidth (const float proportion) const noexcept { return roundToInt (proportion * bounds.getWidth()); } -int Component::proportionOfHeight (const float proportion) const noexcept { return roundToInt (proportion * bounds.getHeight()); } - -int Component::getParentWidth() const noexcept -{ - return parentComponent != nullptr ? parentComponent->getWidth() - : getParentMonitorArea().getWidth(); -} - -int Component::getParentHeight() const noexcept -{ - return parentComponent != nullptr ? parentComponent->getHeight() - : getParentMonitorArea().getHeight(); -} - -int Component::getScreenX() const { return getScreenPosition().x; } -int Component::getScreenY() const { return getScreenPosition().y; } - -Point Component::getScreenPosition() const { return localPointToGlobal (Point()); } -Rectangle Component::getScreenBounds() const { return localAreaToGlobal (getLocalBounds()); } - -Rectangle Component::getParentMonitorArea() const -{ - return Desktop::getInstance().getDisplays().getDisplayContaining (getScreenBounds().getCentre()).userArea; -} - -Point Component::getLocalPoint (const Component* source, Point point) const -{ - return ComponentHelpers::convertCoordinate (this, source, point); -} - -Point Component::getLocalPoint (const Component* source, Point point) const -{ - return ComponentHelpers::convertCoordinate (this, source, point); -} - -Rectangle Component::getLocalArea (const Component* source, const Rectangle& area) const -{ - return ComponentHelpers::convertCoordinate (this, source, area); -} - -Point Component::localPointToGlobal (Point point) const -{ - return ComponentHelpers::convertCoordinate (nullptr, this, point); -} - -Point Component::localPointToGlobal (Point point) const -{ - return ComponentHelpers::convertCoordinate (nullptr, this, point); -} - -Rectangle Component::localAreaToGlobal (const Rectangle& area) const -{ - return ComponentHelpers::convertCoordinate (nullptr, this, area); -} - -// Deprecated methods... -Point Component::relativePositionToGlobal (Point relativePosition) const -{ - return localPointToGlobal (relativePosition); -} - -Point Component::globalPositionToRelative (Point screenPosition) const -{ - return getLocalPoint (nullptr, screenPosition); -} - -Point Component::relativePositionToOtherComponent (const Component* const targetComponent, Point positionRelativeToThis) const -{ - return targetComponent == nullptr ? localPointToGlobal (positionRelativeToThis) - : targetComponent->getLocalPoint (this, positionRelativeToThis); -} - - -//============================================================================== -void Component::setBounds (const int x, const int y, int w, int h) -{ - // if component methods are being called from threads other than the message - // thread, you'll need to use a MessageManagerLock object to make sure it's thread-safe. - ASSERT_MESSAGE_MANAGER_IS_LOCKED_OR_OFFSCREEN - - if (w < 0) w = 0; - if (h < 0) h = 0; - - const bool wasResized = (getWidth() != w || getHeight() != h); - const bool wasMoved = (getX() != x || getY() != y); - - #if JUCE_DEBUG - // It's a very bad idea to try to resize a window during its paint() method! - jassert (! (flags.isInsidePaintCall && wasResized && isOnDesktop())); - #endif - - if (wasMoved || wasResized) - { - const bool showing = isShowing(); - if (showing) - { - // send a fake mouse move to trigger enter/exit messages if needed.. - sendFakeMouseMove(); - - if (! flags.hasHeavyweightPeerFlag) - repaintParent(); - } - - bounds.setBounds (x, y, w, h); - - if (showing) - { - if (wasResized) - repaint(); - else if (! flags.hasHeavyweightPeerFlag) - repaintParent(); - } - else if (cachedImage != nullptr) - { - cachedImage->invalidateAll(); - } - - flags.isMoveCallbackPending = wasMoved; - flags.isResizeCallbackPending = wasResized; - - if (flags.hasHeavyweightPeerFlag) - if (ComponentPeer* const peer = getPeer()) - peer->updateBounds(); - - sendMovedResizedMessagesIfPending(); - } -} - -void Component::sendMovedResizedMessagesIfPending() -{ - if (flags.isMoveCallbackPending || flags.isResizeCallbackPending) - { - sendMovedResizedMessages (flags.isMoveCallbackPending, flags.isResizeCallbackPending); - - flags.isMoveCallbackPending = false; - flags.isResizeCallbackPending = false; - } -} - -void Component::sendMovedResizedMessages (const bool wasMoved, const bool wasResized) -{ - BailOutChecker checker (this); - - if (wasMoved) - { - moved(); - - if (checker.shouldBailOut()) - return; - } - - if (wasResized) - { - resized(); - - if (checker.shouldBailOut()) - return; - - for (int i = childComponentList.size(); --i >= 0;) - { - childComponentList.getUnchecked(i)->parentSizeChanged(); - - if (checker.shouldBailOut()) - return; - - i = jmin (i, childComponentList.size()); - } - } - - if (parentComponent != nullptr) - parentComponent->childBoundsChanged (this); - - if (! checker.shouldBailOut()) - componentListeners.callChecked (checker, &ComponentListener::componentMovedOrResized, - *this, wasMoved, wasResized); -} - -void Component::setSize (const int w, const int h) -{ - setBounds (getX(), getY(), w, h); -} - -void Component::setTopLeftPosition (const int x, const int y) -{ - setBounds (x, y, getWidth(), getHeight()); -} - -void Component::setTopLeftPosition (Point pos) -{ - setBounds (pos.x, pos.y, getWidth(), getHeight()); -} - -void Component::setTopRightPosition (const int x, const int y) -{ - setTopLeftPosition (x - getWidth(), y); -} - -void Component::setBounds (const Rectangle& r) -{ - setBounds (r.getX(), r.getY(), r.getWidth(), r.getHeight()); -} - -void Component::setBounds (const RelativeRectangle& newBounds) -{ - newBounds.applyToComponent (*this); -} - -void Component::setBounds (const String& newBoundsExpression) -{ - setBounds (RelativeRectangle (newBoundsExpression)); -} - -void Component::setBoundsRelative (const float x, const float y, - const float w, const float h) -{ - const int pw = getParentWidth(); - const int ph = getParentHeight(); - - setBounds (roundToInt (x * pw), - roundToInt (y * ph), - roundToInt (w * pw), - roundToInt (h * ph)); -} - -void Component::setCentrePosition (const int x, const int y) -{ - setTopLeftPosition (x - getWidth() / 2, - y - getHeight() / 2); -} - -void Component::setCentreRelative (const float x, const float y) -{ - setCentrePosition (roundToInt (getParentWidth() * x), - roundToInt (getParentHeight() * y)); -} - -void Component::centreWithSize (const int width, const int height) -{ - const Rectangle parentArea (ComponentHelpers::getParentOrMainMonitorBounds (*this)); - - setBounds (parentArea.getCentreX() - width / 2, - parentArea.getCentreY() - height / 2, - width, height); -} - -void Component::setBoundsInset (const BorderSize& borders) -{ - setBounds (borders.subtractedFrom (ComponentHelpers::getParentOrMainMonitorBounds (*this))); -} - -void Component::setBoundsToFit (int x, int y, int width, int height, - Justification justification, - const bool onlyReduceInSize) -{ - // it's no good calling this method unless both the component and - // target rectangle have a finite size. - jassert (getWidth() > 0 && getHeight() > 0 && width > 0 && height > 0); - - if (getWidth() > 0 && getHeight() > 0 - && width > 0 && height > 0) - { - int newW, newH; - - if (onlyReduceInSize && getWidth() <= width && getHeight() <= height) - { - newW = getWidth(); - newH = getHeight(); - } - else - { - const double imageRatio = getHeight() / (double) getWidth(); - const double targetRatio = height / (double) width; - - if (imageRatio <= targetRatio) - { - newW = width; - newH = jmin (height, roundToInt (newW * imageRatio)); - } - else - { - newH = height; - newW = jmin (width, roundToInt (newH / imageRatio)); - } - } - - if (newW > 0 && newH > 0) - setBounds (justification.appliedToRectangle (Rectangle (newW, newH), - Rectangle (x, y, width, height))); - } -} - -//============================================================================== -void Component::setTransform (const AffineTransform& newTransform) -{ - // If you pass in a transform with no inverse, the component will have no dimensions, - // and there will be all sorts of maths errors when converting coordinates. - jassert (! newTransform.isSingularity()); - - if (newTransform.isIdentity()) - { - if (affineTransform != nullptr) - { - repaint(); - affineTransform = nullptr; - repaint(); - - sendMovedResizedMessages (false, false); - } - } - else if (affineTransform == nullptr) - { - repaint(); - affineTransform = new AffineTransform (newTransform); - repaint(); - sendMovedResizedMessages (false, false); - } - else if (*affineTransform != newTransform) - { - repaint(); - *affineTransform = newTransform; - repaint(); - sendMovedResizedMessages (false, false); - } -} - -bool Component::isTransformed() const noexcept -{ - return affineTransform != nullptr; -} - -AffineTransform Component::getTransform() const -{ - return affineTransform != nullptr ? *affineTransform : AffineTransform::identity; -} - -//============================================================================== -bool Component::hitTest (int x, int y) -{ - if (! flags.ignoresMouseClicksFlag) - return true; - - if (flags.allowChildMouseClicksFlag) - { - for (int i = childComponentList.size(); --i >= 0;) - { - Component& child = *childComponentList.getUnchecked (i); - - if (child.isVisible() - && ComponentHelpers::hitTest (child, ComponentHelpers::convertFromParentSpace (child, Point (x, y)))) - return true; - } - } - - return false; -} - -void Component::setInterceptsMouseClicks (const bool allowClicks, - const bool allowClicksOnChildComponents) noexcept -{ - flags.ignoresMouseClicksFlag = ! allowClicks; - flags.allowChildMouseClicksFlag = allowClicksOnChildComponents; -} - -void Component::getInterceptsMouseClicks (bool& allowsClicksOnThisComponent, - bool& allowsClicksOnChildComponents) const noexcept -{ - allowsClicksOnThisComponent = ! flags.ignoresMouseClicksFlag; - allowsClicksOnChildComponents = flags.allowChildMouseClicksFlag; -} - -bool Component::contains (Point point) -{ - if (ComponentHelpers::hitTest (*this, point)) - { - if (parentComponent != nullptr) - return parentComponent->contains (ComponentHelpers::convertToParentSpace (*this, point)); - - if (flags.hasHeavyweightPeerFlag) - if (const ComponentPeer* const peer = getPeer()) - return peer->contains (ComponentHelpers::localPositionToRawPeerPos (*this, point), true); - } - - return false; -} - -bool Component::reallyContains (Point point, const bool returnTrueIfWithinAChild) -{ - if (! contains (point)) - return false; - - Component* const top = getTopLevelComponent(); - const Component* const compAtPosition = top->getComponentAt (top->getLocalPoint (this, point)); - - return (compAtPosition == this) || (returnTrueIfWithinAChild && isParentOf (compAtPosition)); -} - -Component* Component::getComponentAt (Point position) -{ - if (flags.visibleFlag && ComponentHelpers::hitTest (*this, position)) - { - for (int i = childComponentList.size(); --i >= 0;) - { - Component* child = childComponentList.getUnchecked(i); - child = child->getComponentAt (ComponentHelpers::convertFromParentSpace (*child, position)); - - if (child != nullptr) - return child; - } - - return this; - } - - return nullptr; -} - -Component* Component::getComponentAt (const int x, const int y) -{ - return getComponentAt (Point (x, y)); -} - -//============================================================================== -void Component::addChildComponent (Component& child, int zOrder) -{ - // if component methods are being called from threads other than the message - // thread, you'll need to use a MessageManagerLock object to make sure it's thread-safe. - ASSERT_MESSAGE_MANAGER_IS_LOCKED_OR_OFFSCREEN - - if (child.parentComponent != this) - { - if (child.parentComponent != nullptr) - child.parentComponent->removeChildComponent (&child); - else - child.removeFromDesktop(); - - child.parentComponent = this; - - if (child.isVisible()) - child.repaintParent(); - - if (! child.isAlwaysOnTop()) - { - if (zOrder < 0 || zOrder > childComponentList.size()) - zOrder = childComponentList.size(); - - while (zOrder > 0) - { - if (! childComponentList.getUnchecked (zOrder - 1)->isAlwaysOnTop()) - break; - - --zOrder; - } - } - - childComponentList.insert (zOrder, &child); - - child.internalHierarchyChanged(); - internalChildrenChanged(); - } -} - -void Component::addAndMakeVisible (Component& child, int zOrder) -{ - child.setVisible (true); - addChildComponent (child, zOrder); -} - -void Component::addChildComponent (Component* const child, int zOrder) -{ - if (child != nullptr) - addChildComponent (*child, zOrder); -} - -void Component::addAndMakeVisible (Component* const child, int zOrder) -{ - if (child != nullptr) - addAndMakeVisible (*child, zOrder); -} - -void Component::addChildAndSetID (Component* const child, const String& childID) -{ - if (child != nullptr) - { - child->setComponentID (childID); - addAndMakeVisible (child); - } -} - -void Component::removeChildComponent (Component* const child) -{ - removeChildComponent (childComponentList.indexOf (child), true, true); -} - -Component* Component::removeChildComponent (const int index) -{ - return removeChildComponent (index, true, true); -} - -Component* Component::removeChildComponent (const int index, bool sendParentEvents, const bool sendChildEvents) -{ - // if component methods are being called from threads other than the message - // thread, you'll need to use a MessageManagerLock object to make sure it's thread-safe. - ASSERT_MESSAGE_MANAGER_IS_LOCKED_OR_OFFSCREEN - - Component* const child = childComponentList [index]; - - if (child != nullptr) - { - sendParentEvents = sendParentEvents && child->isShowing(); - - if (sendParentEvents) - { - sendFakeMouseMove(); - - if (child->isVisible()) - child->repaintParent(); - } - - childComponentList.remove (index); - child->parentComponent = nullptr; - - if (child->cachedImage != nullptr) - child->cachedImage->releaseResources(); - - // (NB: there are obscure situations where child->isShowing() = false, but it still has the focus) - if (currentlyFocusedComponent == child || child->isParentOf (currentlyFocusedComponent)) - { - if (sendParentEvents) - { - const WeakReference thisPointer (this); - - giveAwayFocus (sendChildEvents || currentlyFocusedComponent != child); - - if (thisPointer == nullptr) - return child; - - grabKeyboardFocus(); - } - else - { - giveAwayFocus (sendChildEvents || currentlyFocusedComponent != child); - } - } - - if (sendChildEvents) - child->internalHierarchyChanged(); - - if (sendParentEvents) - internalChildrenChanged(); - } - - return child; -} - -//============================================================================== -void Component::removeAllChildren() -{ - while (childComponentList.size() > 0) - removeChildComponent (childComponentList.size() - 1); -} - -void Component::deleteAllChildren() -{ - while (childComponentList.size() > 0) - delete (removeChildComponent (childComponentList.size() - 1)); -} - -int Component::getNumChildComponents() const noexcept -{ - return childComponentList.size(); -} - -Component* Component::getChildComponent (const int index) const noexcept -{ - return childComponentList [index]; -} - -int Component::getIndexOfChildComponent (const Component* const child) const noexcept -{ - return childComponentList.indexOf (const_cast (child)); -} - -Component* Component::findChildWithID (StringRef targetID) const noexcept -{ - for (int i = childComponentList.size(); --i >= 0;) - { - Component* const c = childComponentList.getUnchecked(i); - if (c->componentID == targetID) - return c; - } - - return nullptr; -} - -Component* Component::getTopLevelComponent() const noexcept -{ - const Component* comp = this; - - while (comp->parentComponent != nullptr) - comp = comp->parentComponent; - - return const_cast (comp); -} - -bool Component::isParentOf (const Component* possibleChild) const noexcept -{ - while (possibleChild != nullptr) - { - possibleChild = possibleChild->parentComponent; - - if (possibleChild == this) - return true; - } - - return false; -} - -//============================================================================== -void Component::parentHierarchyChanged() {} -void Component::childrenChanged() {} - -void Component::internalChildrenChanged() -{ - if (componentListeners.isEmpty()) - { - childrenChanged(); - } - else - { - BailOutChecker checker (this); - - childrenChanged(); - - if (! checker.shouldBailOut()) - componentListeners.callChecked (checker, &ComponentListener::componentChildrenChanged, *this); - } -} - -void Component::internalHierarchyChanged() -{ - BailOutChecker checker (this); - - parentHierarchyChanged(); - - if (checker.shouldBailOut()) - return; - - componentListeners.callChecked (checker, &ComponentListener::componentParentHierarchyChanged, *this); - - if (checker.shouldBailOut()) - return; - - for (int i = childComponentList.size(); --i >= 0;) - { - childComponentList.getUnchecked (i)->internalHierarchyChanged(); - - if (checker.shouldBailOut()) - { - // you really shouldn't delete the parent component during a callback telling you - // that it's changed.. - jassertfalse; - return; - } - - i = jmin (i, childComponentList.size()); - } -} - -//============================================================================== -#if JUCE_MODAL_LOOPS_PERMITTED -int Component::runModalLoop() -{ - if (! MessageManager::getInstance()->isThisTheMessageThread()) - { - // use a callback so this can be called from non-gui threads - return (int) (pointer_sized_int) MessageManager::getInstance() - ->callFunctionOnMessageThread (&ComponentHelpers::runModalLoopCallback, this); - } - - if (! isCurrentlyModal()) - enterModalState (true); - - return ModalComponentManager::getInstance()->runEventLoopForCurrentComponent(); -} -#endif - -//============================================================================== -void Component::enterModalState (const bool shouldTakeKeyboardFocus, - ModalComponentManager::Callback* callback, - const bool deleteWhenDismissed) -{ - // if component methods are being called from threads other than the message - // thread, you'll need to use a MessageManagerLock object to make sure it's thread-safe. - ASSERT_MESSAGE_MANAGER_IS_LOCKED - - // Check for an attempt to make a component modal when it already is! - // This can cause nasty problems.. - jassert (! flags.currentlyModalFlag); - - if (! isCurrentlyModal()) - { - ModalComponentManager* const mcm = ModalComponentManager::getInstance(); - mcm->startModal (this, deleteWhenDismissed); - mcm->attachCallback (this, callback); - - flags.currentlyModalFlag = true; - setVisible (true); - - if (shouldTakeKeyboardFocus) - grabKeyboardFocus(); - } -} - -void Component::exitModalState (const int returnValue) -{ - if (flags.currentlyModalFlag) - { - if (MessageManager::getInstance()->isThisTheMessageThread()) - { - ModalComponentManager::getInstance()->endModal (this, returnValue); - flags.currentlyModalFlag = false; - - ModalComponentManager::getInstance()->bringModalComponentsToFront(); - } - else - { - class ExitModalStateMessage : public CallbackMessage - { - public: - ExitModalStateMessage (Component* const c, const int res) - : target (c), result (res) {} - - void messageCallback() override - { - if (target.get() != nullptr) // (get() required for VS2003 bug) - target->exitModalState (result); - } - - private: - WeakReference target; - int result; - }; - - (new ExitModalStateMessage (this, returnValue))->post(); - } - } -} - -bool Component::isCurrentlyModal() const noexcept -{ - return flags.currentlyModalFlag - && getCurrentlyModalComponent() == this; -} - -bool Component::isCurrentlyBlockedByAnotherModalComponent() const -{ - Component* const mc = getCurrentlyModalComponent(); - - return ! (mc == nullptr || mc == this || mc->isParentOf (this) - || mc->canModalEventBeSentToComponent (this)); -} - -int JUCE_CALLTYPE Component::getNumCurrentlyModalComponents() noexcept -{ - return ModalComponentManager::getInstance()->getNumModalComponents(); -} - -Component* JUCE_CALLTYPE Component::getCurrentlyModalComponent (int index) noexcept -{ - return ModalComponentManager::getInstance()->getModalComponent (index); -} - -//============================================================================== -void Component::setBroughtToFrontOnMouseClick (const bool shouldBeBroughtToFront) noexcept -{ - flags.bringToFrontOnClickFlag = shouldBeBroughtToFront; -} - -bool Component::isBroughtToFrontOnMouseClick() const noexcept -{ - return flags.bringToFrontOnClickFlag; -} - -//============================================================================== -void Component::setMouseCursor (const MouseCursor& newCursor) -{ - if (cursor != newCursor) - { - cursor = newCursor; - - if (flags.visibleFlag) - updateMouseCursor(); - } -} - -MouseCursor Component::getMouseCursor() -{ - return cursor; -} - -void Component::updateMouseCursor() const -{ - Desktop::getInstance().getMainMouseSource().forceMouseCursorUpdate(); -} - -//============================================================================== -void Component::setRepaintsOnMouseActivity (const bool shouldRepaint) noexcept -{ - flags.repaintOnMouseActivityFlag = shouldRepaint; -} - -//============================================================================== -void Component::setAlpha (const float newAlpha) -{ - const uint8 newIntAlpha = (uint8) (255 - jlimit (0, 255, roundToInt (newAlpha * 255.0))); - - if (componentTransparency != newIntAlpha) - { - componentTransparency = newIntAlpha; - - if (flags.hasHeavyweightPeerFlag) - { - if (ComponentPeer* const peer = getPeer()) - peer->setAlpha (newAlpha); - } - else - { - repaint(); - } - } -} - -float Component::getAlpha() const -{ - return (255 - componentTransparency) / 255.0f; -} - -//============================================================================== -void Component::repaint() -{ - internalRepaintUnchecked (getLocalBounds(), true); -} - -void Component::repaint (const int x, const int y, const int w, const int h) -{ - internalRepaint (Rectangle (x, y, w, h)); -} - -void Component::repaint (const Rectangle& area) -{ - internalRepaint (area); -} - -void Component::repaintParent() -{ - if (parentComponent != nullptr) - parentComponent->internalRepaint (ComponentHelpers::convertToParentSpace (*this, getLocalBounds())); -} - -void Component::internalRepaint (const Rectangle& area) -{ - const Rectangle r (area.getIntersection (getLocalBounds())); - - if (! r.isEmpty()) - internalRepaintUnchecked (r, false); -} - -void Component::internalRepaintUnchecked (const Rectangle& area, const bool isEntireComponent) -{ - if (flags.visibleFlag) - { - if (cachedImage != nullptr) - if (! (isEntireComponent ? cachedImage->invalidateAll() - : cachedImage->invalidate (area))) - return; - - if (flags.hasHeavyweightPeerFlag) - { - // if component methods are being called from threads other than the message - // thread, you'll need to use a MessageManagerLock object to make sure it's thread-safe. - ASSERT_MESSAGE_MANAGER_IS_LOCKED - - if (ComponentPeer* const peer = getPeer()) - { - // Tweak the scaling so that the component's integer size exactly aligns with the peer's scaled size - const Rectangle peerBounds (peer->getBounds()); - const Rectangle scaled (area * Point (peerBounds.getWidth() / (float) getWidth(), - peerBounds.getHeight() / (float) getHeight())); - - peer->repaint (affineTransform != nullptr ? scaled.transformedBy (*affineTransform) : scaled); - } - } - else - { - if (parentComponent != nullptr) - parentComponent->internalRepaint (ComponentHelpers::convertToParentSpace (*this, area)); - } - } -} - -//============================================================================== -void Component::paint (Graphics&) -{ - // if your component is marked as opaque, you must implement a paint - // method and ensure that its entire area is completely painted. - jassert (getBounds().isEmpty() || ! isOpaque()); -} - -void Component::paintOverChildren (Graphics&) -{ - // all painting is done in the subclasses -} - -//============================================================================== -void Component::paintWithinParentContext (Graphics& g) -{ - g.setOrigin (getPosition()); - - if (cachedImage != nullptr) - cachedImage->paint (g); - else - paintEntireComponent (g, false); -} - -void Component::paintComponentAndChildren (Graphics& g) -{ - const Rectangle clipBounds (g.getClipBounds()); - - if (flags.dontClipGraphicsFlag) - { - paint (g); - } - else - { - g.saveState(); - - if (ComponentHelpers::clipObscuredRegions (*this, g, clipBounds, Point()) || ! g.isClipEmpty()) - paint (g); - - g.restoreState(); - } - - for (int i = 0; i < childComponentList.size(); ++i) - { - Component& child = *childComponentList.getUnchecked (i); - - if (child.isVisible()) - { - if (child.affineTransform != nullptr) - { - g.saveState(); - g.addTransform (*child.affineTransform); - - if ((child.flags.dontClipGraphicsFlag && ! g.isClipEmpty()) || g.reduceClipRegion (child.getBounds())) - child.paintWithinParentContext (g); - - g.restoreState(); - } - else if (clipBounds.intersects (child.getBounds())) - { - g.saveState(); - - if (child.flags.dontClipGraphicsFlag) - { - child.paintWithinParentContext (g); - } - else if (g.reduceClipRegion (child.getBounds())) - { - bool nothingClipped = true; - - for (int j = i + 1; j < childComponentList.size(); ++j) - { - const Component& sibling = *childComponentList.getUnchecked (j); - - if (sibling.flags.opaqueFlag && sibling.isVisible() && sibling.affineTransform == nullptr) - { - nothingClipped = false; - g.excludeClipRegion (sibling.getBounds()); - } - } - - if (nothingClipped || ! g.isClipEmpty()) - child.paintWithinParentContext (g); - } - - g.restoreState(); - } - } - } - - g.saveState(); - paintOverChildren (g); - g.restoreState(); -} - -void Component::paintEntireComponent (Graphics& g, const bool ignoreAlphaLevel) -{ - // If sizing a top-level-window and the OS paint message is delivered synchronously - // before resized() is called, then we'll invoke the callback here, to make sure - // the components inside have had a chance to sort their sizes out.. - #if JUCE_DEBUG - if (! flags.isInsidePaintCall) // (avoids an assertion in plugins hosted in WaveLab) - #endif - sendMovedResizedMessagesIfPending(); - - #if JUCE_DEBUG - flags.isInsidePaintCall = true; - #endif - - if (effect != nullptr) - { - const float scale = g.getInternalContext().getPhysicalPixelScaleFactor(); - - const Rectangle scaledBounds (getLocalBounds() * scale); - - Image effectImage (flags.opaqueFlag ? Image::RGB : Image::ARGB, - scaledBounds.getWidth(), scaledBounds.getHeight(), ! flags.opaqueFlag); - { - Graphics g2 (effectImage); - g2.addTransform (AffineTransform::scale (scaledBounds.getWidth() / (float) getWidth(), - scaledBounds.getHeight() / (float) getHeight())); - paintComponentAndChildren (g2); - } - - g.saveState(); - g.addTransform (AffineTransform::scale (1.0f / scale)); - effect->applyEffect (effectImage, g, scale, ignoreAlphaLevel ? 1.0f : getAlpha()); - g.restoreState(); - } - else if (componentTransparency > 0 && ! ignoreAlphaLevel) - { - if (componentTransparency < 255) - { - g.beginTransparencyLayer (getAlpha()); - paintComponentAndChildren (g); - g.endTransparencyLayer(); - } - } - else - { - paintComponentAndChildren (g); - } - - #if JUCE_DEBUG - flags.isInsidePaintCall = false; - #endif -} - -void Component::setPaintingIsUnclipped (const bool shouldPaintWithoutClipping) noexcept -{ - flags.dontClipGraphicsFlag = shouldPaintWithoutClipping; -} - -//============================================================================== -Image Component::createComponentSnapshot (const Rectangle& areaToGrab, - bool clipImageToComponentBounds, float scaleFactor) -{ - Rectangle r (areaToGrab); - - if (clipImageToComponentBounds) - r = r.getIntersection (getLocalBounds()); - - if (r.isEmpty()) - return Image(); - - const int w = roundToInt (scaleFactor * r.getWidth()); - const int h = roundToInt (scaleFactor * r.getHeight()); - - Image image (flags.opaqueFlag ? Image::RGB : Image::ARGB, w, h, true); - - Graphics g (image); - - if (w != getWidth() || h != getHeight()) - g.addTransform (AffineTransform::scale (w / (float) r.getWidth(), - h / (float) r.getHeight())); - g.setOrigin (-r.getPosition()); - - paintEntireComponent (g, true); - - return image; -} - -void Component::setComponentEffect (ImageEffectFilter* const newEffect) -{ - if (effect != newEffect) - { - effect = newEffect; - repaint(); - } -} - -//============================================================================== -LookAndFeel& Component::getLookAndFeel() const noexcept -{ - for (const Component* c = this; c != nullptr; c = c->parentComponent) - if (c->lookAndFeel != nullptr) - return *(c->lookAndFeel); - - return LookAndFeel::getDefaultLookAndFeel(); -} - -void Component::setLookAndFeel (LookAndFeel* const newLookAndFeel) -{ - if (lookAndFeel != newLookAndFeel) - { - lookAndFeel = newLookAndFeel; - sendLookAndFeelChange(); - } -} - -void Component::lookAndFeelChanged() {} -void Component::colourChanged() {} - -void Component::sendLookAndFeelChange() -{ - const WeakReference safePointer (this); - repaint(); - lookAndFeelChanged(); - - if (safePointer != nullptr) - { - colourChanged(); - - if (safePointer != nullptr) - { - for (int i = childComponentList.size(); --i >= 0;) - { - childComponentList.getUnchecked (i)->sendLookAndFeelChange(); - - if (safePointer == nullptr) - return; - - i = jmin (i, childComponentList.size()); - } - } - } -} - -Colour Component::findColour (const int colourId, const bool inheritFromParent) const -{ - if (const var* const v = properties.getVarPointer (ComponentHelpers::getColourPropertyId (colourId))) - return Colour ((uint32) static_cast (*v)); - - if (inheritFromParent && parentComponent != nullptr - && (lookAndFeel == nullptr || ! lookAndFeel->isColourSpecified (colourId))) - return parentComponent->findColour (colourId, true); - - return getLookAndFeel().findColour (colourId); -} - -bool Component::isColourSpecified (const int colourId) const -{ - return properties.contains (ComponentHelpers::getColourPropertyId (colourId)); -} - -void Component::removeColour (const int colourId) -{ - if (properties.remove (ComponentHelpers::getColourPropertyId (colourId))) - colourChanged(); -} - -void Component::setColour (const int colourId, Colour colour) -{ - if (properties.set (ComponentHelpers::getColourPropertyId (colourId), (int) colour.getARGB())) - colourChanged(); -} - -void Component::copyAllExplicitColoursTo (Component& target) const -{ - bool changed = false; - - for (int i = properties.size(); --i >= 0;) - { - const Identifier name (properties.getName(i)); - - if (name.toString().startsWith ("jcclr_")) - if (target.properties.set (name, properties [name])) - changed = true; - } - - if (changed) - target.colourChanged(); -} - -//============================================================================== -MarkerList* Component::getMarkers (bool /*xAxis*/) -{ - return nullptr; -} - -//============================================================================== -Component::Positioner::Positioner (Component& c) noexcept - : component (c) -{ -} - -Component::Positioner* Component::getPositioner() const noexcept -{ - return positioner; -} - -void Component::setPositioner (Positioner* newPositioner) -{ - // You can only assign a positioner to the component that it was created for! - jassert (newPositioner == nullptr || this == &(newPositioner->getComponent())); - positioner = newPositioner; -} - -//============================================================================== -Rectangle Component::getLocalBounds() const noexcept -{ - return bounds.withZeroOrigin(); -} - -Rectangle Component::getBoundsInParent() const noexcept -{ - return affineTransform == nullptr ? bounds - : bounds.transformedBy (*affineTransform); -} - -//============================================================================== -void Component::mouseEnter (const MouseEvent&) {} -void Component::mouseExit (const MouseEvent&) {} -void Component::mouseDown (const MouseEvent&) {} -void Component::mouseUp (const MouseEvent&) {} -void Component::mouseDrag (const MouseEvent&) {} -void Component::mouseMove (const MouseEvent&) {} -void Component::mouseDoubleClick (const MouseEvent&) {} - -void Component::mouseWheelMove (const MouseEvent& e, const MouseWheelDetails& wheel) -{ - // the base class just passes this event up to its parent.. - if (parentComponent != nullptr) - parentComponent->mouseWheelMove (e.getEventRelativeTo (parentComponent), wheel); -} - -void Component::mouseMagnify (const MouseEvent& e, float magnifyAmount) -{ - // the base class just passes this event up to its parent.. - if (parentComponent != nullptr) - parentComponent->mouseMagnify (e.getEventRelativeTo (parentComponent), magnifyAmount); -} - -//============================================================================== -void Component::resized() {} -void Component::moved() {} -void Component::childBoundsChanged (Component*) {} -void Component::parentSizeChanged() {} - -void Component::addComponentListener (ComponentListener* const newListener) -{ - // if component methods are being called from threads other than the message - // thread, you'll need to use a MessageManagerLock object to make sure it's thread-safe. - #if JUCE_DEBUG || JUCE_LOG_ASSERTIONS - if (getParentComponent() != nullptr) - ASSERT_MESSAGE_MANAGER_IS_LOCKED; - #endif - - componentListeners.add (newListener); -} - -void Component::removeComponentListener (ComponentListener* const listenerToRemove) -{ - componentListeners.remove (listenerToRemove); -} - -//============================================================================== -void Component::inputAttemptWhenModal() -{ - ModalComponentManager::getInstance()->bringModalComponentsToFront(); - getLookAndFeel().playAlertSound(); -} - -bool Component::canModalEventBeSentToComponent (const Component*) -{ - return false; -} - -void Component::internalModalInputAttempt() -{ - if (Component* const current = getCurrentlyModalComponent()) - current->inputAttemptWhenModal(); -} - -//============================================================================== -void Component::postCommandMessage (const int commandId) -{ - class CustomCommandMessage : public CallbackMessage - { - public: - CustomCommandMessage (Component* const c, const int command) - : target (c), commandId (command) {} - - void messageCallback() override - { - if (target.get() != nullptr) // (get() required for VS2003 bug) - target->handleCommandMessage (commandId); - } - - private: - WeakReference target; - int commandId; - }; - - (new CustomCommandMessage (this, commandId))->post(); -} - -void Component::handleCommandMessage (int) -{ - // used by subclasses -} - -//============================================================================== -void Component::addMouseListener (MouseListener* const newListener, - const bool wantsEventsForAllNestedChildComponents) -{ - // if component methods are being called from threads other than the message - // thread, you'll need to use a MessageManagerLock object to make sure it's thread-safe. - ASSERT_MESSAGE_MANAGER_IS_LOCKED - - // If you register a component as a mouselistener for itself, it'll receive all the events - // twice - once via the direct callback that all components get anyway, and then again as a listener! - jassert ((newListener != this) || wantsEventsForAllNestedChildComponents); - - if (mouseListeners == nullptr) - mouseListeners = new MouseListenerList(); - - mouseListeners->addListener (newListener, wantsEventsForAllNestedChildComponents); -} - -void Component::removeMouseListener (MouseListener* const listenerToRemove) -{ - // if component methods are being called from threads other than the message - // thread, you'll need to use a MessageManagerLock object to make sure it's thread-safe. - ASSERT_MESSAGE_MANAGER_IS_LOCKED - - if (mouseListeners != nullptr) - mouseListeners->removeListener (listenerToRemove); -} - -//============================================================================== -void Component::internalMouseEnter (MouseInputSource source, Point relativePos, Time time) -{ - if (isCurrentlyBlockedByAnotherModalComponent()) - { - // if something else is modal, always just show a normal mouse cursor - source.showMouseCursor (MouseCursor::NormalCursor); - return; - } - - if (flags.repaintOnMouseActivityFlag) - repaint(); - - BailOutChecker checker (this); - - const MouseEvent me (source, relativePos, source.getCurrentModifiers(), - this, this, time, relativePos, time, 0, false); - mouseEnter (me); - - if (checker.shouldBailOut()) - return; - - Desktop::getInstance().getMouseListeners().callChecked (checker, &MouseListener::mouseEnter, me); - - MouseListenerList::sendMouseEvent (*this, checker, &MouseListener::mouseEnter, me); -} - -void Component::internalMouseExit (MouseInputSource source, Point relativePos, Time time) -{ - if (flags.repaintOnMouseActivityFlag) - repaint(); - - BailOutChecker checker (this); - - const MouseEvent me (source, relativePos, source.getCurrentModifiers(), - this, this, time, relativePos, time, 0, false); - - mouseExit (me); - - if (checker.shouldBailOut()) - return; - - Desktop::getInstance().getMouseListeners().callChecked (checker, &MouseListener::mouseExit, me); - - MouseListenerList::sendMouseEvent (*this, checker, &MouseListener::mouseExit, me); -} - -void Component::internalMouseDown (MouseInputSource source, Point relativePos, Time time) -{ - Desktop& desktop = Desktop::getInstance(); - BailOutChecker checker (this); - - if (isCurrentlyBlockedByAnotherModalComponent()) - { - flags.mouseDownWasBlocked = true; - internalModalInputAttempt(); - - if (checker.shouldBailOut()) - return; - - // If processing the input attempt has exited the modal loop, we'll allow the event - // to be delivered.. - if (isCurrentlyBlockedByAnotherModalComponent()) - { - // allow blocked mouse-events to go to global listeners.. - const MouseEvent me (source, relativePos, source.getCurrentModifiers(), - this, this, time, relativePos, time, - source.getNumberOfMultipleClicks(), false); - - desktop.getMouseListeners().callChecked (checker, &MouseListener::mouseDown, me); - return; - } - } - - flags.mouseDownWasBlocked = false; - - for (Component* c = this; c != nullptr; c = c->parentComponent) - { - if (c->isBroughtToFrontOnMouseClick()) - { - c->toFront (true); - - if (checker.shouldBailOut()) - return; - } - } - - if (! flags.dontFocusOnMouseClickFlag) - { - grabFocusInternal (focusChangedByMouseClick, true); - - if (checker.shouldBailOut()) - return; - } - - if (flags.repaintOnMouseActivityFlag) - repaint(); - - const MouseEvent me (source, relativePos, source.getCurrentModifiers(), - this, this, time, relativePos, time, - source.getNumberOfMultipleClicks(), false); - mouseDown (me); - - if (checker.shouldBailOut()) - return; - - desktop.getMouseListeners().callChecked (checker, &MouseListener::mouseDown, me); - - MouseListenerList::sendMouseEvent (*this, checker, &MouseListener::mouseDown, me); -} - -void Component::internalMouseUp (MouseInputSource source, Point relativePos, - Time time, const ModifierKeys oldModifiers) -{ - if (flags.mouseDownWasBlocked && isCurrentlyBlockedByAnotherModalComponent()) - return; - - BailOutChecker checker (this); - - if (flags.repaintOnMouseActivityFlag) - repaint(); - - const MouseEvent me (source, relativePos, - oldModifiers, this, this, time, - getLocalPoint (nullptr, source.getLastMouseDownPosition()), - source.getLastMouseDownTime(), - source.getNumberOfMultipleClicks(), - source.hasMouseMovedSignificantlySincePressed()); - mouseUp (me); - - if (checker.shouldBailOut()) - return; - - Desktop& desktop = Desktop::getInstance(); - desktop.getMouseListeners().callChecked (checker, &MouseListener::mouseUp, me); - - MouseListenerList::sendMouseEvent (*this, checker, &MouseListener::mouseUp, me); - - if (checker.shouldBailOut()) - return; - - // check for double-click - if (me.getNumberOfClicks() >= 2) - { - mouseDoubleClick (me); - - if (checker.shouldBailOut()) - return; - - desktop.mouseListeners.callChecked (checker, &MouseListener::mouseDoubleClick, me); - MouseListenerList::sendMouseEvent (*this, checker, &MouseListener::mouseDoubleClick, me); - } -} - -void Component::internalMouseDrag (MouseInputSource source, Point relativePos, Time time) -{ - if (! isCurrentlyBlockedByAnotherModalComponent()) - { - BailOutChecker checker (this); - - const MouseEvent me (source, relativePos, - source.getCurrentModifiers(), this, this, time, - getLocalPoint (nullptr, source.getLastMouseDownPosition()), - source.getLastMouseDownTime(), - source.getNumberOfMultipleClicks(), - source.hasMouseMovedSignificantlySincePressed()); - mouseDrag (me); - - if (checker.shouldBailOut()) - return; - - Desktop::getInstance().getMouseListeners().callChecked (checker, &MouseListener::mouseDrag, me); - - MouseListenerList::sendMouseEvent (*this, checker, &MouseListener::mouseDrag, me); - } -} - -void Component::internalMouseMove (MouseInputSource source, Point relativePos, Time time) -{ - Desktop& desktop = Desktop::getInstance(); - - if (isCurrentlyBlockedByAnotherModalComponent()) - { - // allow blocked mouse-events to go to global listeners.. - desktop.sendMouseMove(); - } - else - { - BailOutChecker checker (this); - - const MouseEvent me (source, relativePos, source.getCurrentModifiers(), - this, this, time, relativePos, time, 0, false); - mouseMove (me); - - if (checker.shouldBailOut()) - return; - - desktop.getMouseListeners().callChecked (checker, &MouseListener::mouseMove, me); - - MouseListenerList::sendMouseEvent (*this, checker, &MouseListener::mouseMove, me); - } -} - -void Component::internalMouseWheel (MouseInputSource source, Point relativePos, - Time time, const MouseWheelDetails& wheel) -{ - Desktop& desktop = Desktop::getInstance(); - BailOutChecker checker (this); - - const MouseEvent me (source, relativePos, source.getCurrentModifiers(), - this, this, time, relativePos, time, 0, false); - - if (isCurrentlyBlockedByAnotherModalComponent()) - { - // allow blocked mouse-events to go to global listeners.. - desktop.mouseListeners.callChecked (checker, &MouseListener::mouseWheelMove, me, wheel); - } - else - { - mouseWheelMove (me, wheel); - - if (checker.shouldBailOut()) - return; - - desktop.mouseListeners.callChecked (checker, &MouseListener::mouseWheelMove, me, wheel); - - if (! checker.shouldBailOut()) - MouseListenerList::sendWheelEvent (*this, checker, me, wheel); - } -} - -void Component::internalMagnifyGesture (MouseInputSource source, Point relativePos, - Time time, float amount) -{ - if (! isCurrentlyBlockedByAnotherModalComponent()) - { - const MouseEvent me (source, relativePos, source.getCurrentModifiers(), - this, this, time, relativePos, time, 0, false); - - mouseMagnify (me, amount); - } -} - -void Component::sendFakeMouseMove() const -{ - MouseInputSource mainMouse = Desktop::getInstance().getMainMouseSource(); - - if (! mainMouse.isDragging()) - mainMouse.triggerFakeMove(); -} - -void JUCE_CALLTYPE Component::beginDragAutoRepeat (const int interval) -{ - Desktop::getInstance().beginDragAutoRepeat (interval); -} - -//============================================================================== -void Component::broughtToFront() -{ -} - -void Component::internalBroughtToFront() -{ - if (flags.hasHeavyweightPeerFlag) - Desktop::getInstance().componentBroughtToFront (this); - - BailOutChecker checker (this); - broughtToFront(); - - if (checker.shouldBailOut()) - return; - - componentListeners.callChecked (checker, &ComponentListener::componentBroughtToFront, *this); - - if (checker.shouldBailOut()) - return; - - // When brought to the front and there's a modal component blocking this one, - // we need to bring the modal one to the front instead.. - if (Component* const cm = getCurrentlyModalComponent()) - if (cm->getTopLevelComponent() != getTopLevelComponent()) - ModalComponentManager::getInstance()->bringModalComponentsToFront (false); // very important that this is false, otherwise in Windows, - // non-front components can't get focus when another modal comp is - // active, and therefore can't receive mouse-clicks -} - -//============================================================================== -void Component::focusGained (FocusChangeType) {} -void Component::focusLost (FocusChangeType) {} -void Component::focusOfChildComponentChanged (FocusChangeType) {} - -void Component::internalFocusGain (const FocusChangeType cause) -{ - internalFocusGain (cause, WeakReference (this)); -} - -void Component::internalFocusGain (const FocusChangeType cause, const WeakReference& safePointer) -{ - focusGained (cause); - - if (safePointer != nullptr) - internalChildFocusChange (cause, safePointer); -} - -void Component::internalFocusLoss (const FocusChangeType cause) -{ - const WeakReference safePointer (this); - - focusLost (focusChangedDirectly); - - if (safePointer != nullptr) - internalChildFocusChange (cause, safePointer); -} - -void Component::internalChildFocusChange (FocusChangeType cause, const WeakReference& safePointer) -{ - const bool childIsNowFocused = hasKeyboardFocus (true); - - if (flags.childCompFocusedFlag != childIsNowFocused) - { - flags.childCompFocusedFlag = childIsNowFocused; - - focusOfChildComponentChanged (cause); - - if (safePointer == nullptr) - return; - } - - if (parentComponent != nullptr) - parentComponent->internalChildFocusChange (cause, WeakReference (parentComponent)); -} - -void Component::setWantsKeyboardFocus (const bool wantsFocus) noexcept -{ - flags.wantsFocusFlag = wantsFocus; -} - -void Component::setMouseClickGrabsKeyboardFocus (const bool shouldGrabFocus) -{ - flags.dontFocusOnMouseClickFlag = ! shouldGrabFocus; -} - -bool Component::getMouseClickGrabsKeyboardFocus() const noexcept -{ - return ! flags.dontFocusOnMouseClickFlag; -} - -bool Component::getWantsKeyboardFocus() const noexcept -{ - return flags.wantsFocusFlag && ! flags.isDisabledFlag; -} - -void Component::setFocusContainer (const bool shouldBeFocusContainer) noexcept -{ - flags.isFocusContainerFlag = shouldBeFocusContainer; -} - -bool Component::isFocusContainer() const noexcept -{ - return flags.isFocusContainerFlag; -} - -static const Identifier juce_explicitFocusOrderId ("_jexfo"); - -int Component::getExplicitFocusOrder() const -{ - return properties [juce_explicitFocusOrderId]; -} - -void Component::setExplicitFocusOrder (const int newFocusOrderIndex) -{ - properties.set (juce_explicitFocusOrderId, newFocusOrderIndex); -} - -KeyboardFocusTraverser* Component::createFocusTraverser() -{ - if (flags.isFocusContainerFlag || parentComponent == nullptr) - return new KeyboardFocusTraverser(); - - return parentComponent->createFocusTraverser(); -} - -void Component::takeKeyboardFocus (const FocusChangeType cause) -{ - // give the focus to this component - if (currentlyFocusedComponent != this) - { - // get the focus onto our desktop window - if (ComponentPeer* const peer = getPeer()) - { - const WeakReference safePointer (this); - peer->grabFocus(); - - if (peer->isFocused() && currentlyFocusedComponent != this) - { - WeakReference componentLosingFocus (currentlyFocusedComponent); - currentlyFocusedComponent = this; - - Desktop::getInstance().triggerFocusCallback(); - - // call this after setting currentlyFocusedComponent so that the one that's - // losing it has a chance to see where focus is going - if (componentLosingFocus != nullptr) - componentLosingFocus->internalFocusLoss (cause); - - if (currentlyFocusedComponent == this) - internalFocusGain (cause, safePointer); - } - } - } -} - -void Component::grabFocusInternal (const FocusChangeType cause, const bool canTryParent) -{ - if (isShowing()) - { - if (flags.wantsFocusFlag && (isEnabled() || parentComponent == nullptr)) - { - takeKeyboardFocus (cause); - } - else - { - if (isParentOf (currentlyFocusedComponent) - && currentlyFocusedComponent->isShowing()) - { - // do nothing if the focused component is actually a child of ours.. - } - else - { - // find the default child component.. - ScopedPointer traverser (createFocusTraverser()); - - if (traverser != nullptr) - { - Component* const defaultComp = traverser->getDefaultComponent (this); - traverser = nullptr; - - if (defaultComp != nullptr) - { - defaultComp->grabFocusInternal (cause, false); - return; - } - } - - if (canTryParent && parentComponent != nullptr) - { - // if no children want it and we're allowed to try our parent comp, - // then pass up to parent, which will try our siblings. - parentComponent->grabFocusInternal (cause, true); - } - } - } - } -} - -void Component::grabKeyboardFocus() -{ - // if component methods are being called from threads other than the message - // thread, you'll need to use a MessageManagerLock object to make sure it's thread-safe. - ASSERT_MESSAGE_MANAGER_IS_LOCKED - - grabFocusInternal (focusChangedDirectly, true); -} - -void Component::moveKeyboardFocusToSibling (const bool moveToNext) -{ - // if component methods are being called from threads other than the message - // thread, you'll need to use a MessageManagerLock object to make sure it's thread-safe. - ASSERT_MESSAGE_MANAGER_IS_LOCKED - - if (parentComponent != nullptr) - { - ScopedPointer traverser (createFocusTraverser()); - - if (traverser != nullptr) - { - Component* const nextComp = moveToNext ? traverser->getNextComponent (this) - : traverser->getPreviousComponent (this); - traverser = nullptr; - - if (nextComp != nullptr) - { - if (nextComp->isCurrentlyBlockedByAnotherModalComponent()) - { - const WeakReference nextCompPointer (nextComp); - internalModalInputAttempt(); - - if (nextCompPointer == nullptr || nextComp->isCurrentlyBlockedByAnotherModalComponent()) - return; - } - - nextComp->grabFocusInternal (focusChangedByTabKey, true); - return; - } - } - - parentComponent->moveKeyboardFocusToSibling (moveToNext); - } -} - -bool Component::hasKeyboardFocus (const bool trueIfChildIsFocused) const -{ - return (currentlyFocusedComponent == this) - || (trueIfChildIsFocused && isParentOf (currentlyFocusedComponent)); -} - -Component* JUCE_CALLTYPE Component::getCurrentlyFocusedComponent() noexcept -{ - return currentlyFocusedComponent; -} - -void JUCE_CALLTYPE Component::unfocusAllComponents() -{ - if (Component* c = getCurrentlyFocusedComponent()) - c->giveAwayFocus (true); -} - -void Component::giveAwayFocus (const bool sendFocusLossEvent) -{ - Component* const componentLosingFocus = currentlyFocusedComponent; - currentlyFocusedComponent = nullptr; - - if (sendFocusLossEvent && componentLosingFocus != nullptr) - componentLosingFocus->internalFocusLoss (focusChangedDirectly); - - Desktop::getInstance().triggerFocusCallback(); -} - -//============================================================================== -bool Component::isEnabled() const noexcept -{ - return (! flags.isDisabledFlag) - && (parentComponent == nullptr || parentComponent->isEnabled()); -} - -void Component::setEnabled (const bool shouldBeEnabled) -{ - if (flags.isDisabledFlag == shouldBeEnabled) - { - flags.isDisabledFlag = ! shouldBeEnabled; - - // if any parent components are disabled, setting our flag won't make a difference, - // so no need to send a change message - if (parentComponent == nullptr || parentComponent->isEnabled()) - sendEnablementChangeMessage(); - } -} - -void Component::enablementChanged() {} - -void Component::sendEnablementChangeMessage() -{ - const WeakReference safePointer (this); - - enablementChanged(); - - if (safePointer == nullptr) - return; - - for (int i = getNumChildComponents(); --i >= 0;) - { - if (Component* const c = getChildComponent (i)) - { - c->sendEnablementChangeMessage(); - - if (safePointer == nullptr) - return; - } - } -} - -//============================================================================== -bool Component::isMouseOver (const bool includeChildren) const -{ - const Array& mouseSources = Desktop::getInstance().getMouseSources(); - - for (MouseInputSource* mi = mouseSources.begin(), * const e = mouseSources.end(); mi != e; ++mi) - { - Component* const c = mi->getComponentUnderMouse(); - - if ((c == this || (includeChildren && isParentOf (c))) - && c->reallyContains (c->getLocalPoint (nullptr, mi->getScreenPosition()).roundToInt(), false) - && (mi->isMouse() || mi->isDragging())) - return true; - } - - return false; -} - -bool Component::isMouseButtonDown() const -{ - const Array& mouseSources = Desktop::getInstance().getMouseSources(); - - for (MouseInputSource* mi = mouseSources.begin(), * const e = mouseSources.end(); mi != e; ++mi) - if (mi->isDragging() && mi->getComponentUnderMouse() == this) - return true; - - return false; -} - -bool Component::isMouseOverOrDragging() const -{ - const Array& mouseSources = Desktop::getInstance().getMouseSources(); - - for (MouseInputSource* mi = mouseSources.begin(), * const e = mouseSources.end(); mi != e; ++mi) - if (mi->getComponentUnderMouse() == this - && (mi->isMouse() || mi->isDragging())) - return true; - - return false; -} - -bool JUCE_CALLTYPE Component::isMouseButtonDownAnywhere() noexcept -{ - return ModifierKeys::getCurrentModifiers().isAnyMouseButtonDown(); -} - -Point Component::getMouseXYRelative() const -{ - return getLocalPoint (nullptr, Desktop::getMousePosition()); -} - -//============================================================================== -void Component::addKeyListener (KeyListener* const newListener) -{ - if (keyListeners == nullptr) - keyListeners = new Array(); - - keyListeners->addIfNotAlreadyThere (newListener); -} - -void Component::removeKeyListener (KeyListener* const listenerToRemove) -{ - if (keyListeners != nullptr) - keyListeners->removeFirstMatchingValue (listenerToRemove); -} - -bool Component::keyPressed (const KeyPress&) { return false; } -bool Component::keyStateChanged (const bool /*isKeyDown*/) { return false; } - -void Component::modifierKeysChanged (const ModifierKeys& modifiers) -{ - if (parentComponent != nullptr) - parentComponent->modifierKeysChanged (modifiers); -} - -void Component::internalModifierKeysChanged() -{ - sendFakeMouseMove(); - modifierKeysChanged (ModifierKeys::getCurrentModifiers()); -} - -//============================================================================== -Component::BailOutChecker::BailOutChecker (Component* const component) - : safePointer (component) -{ - jassert (component != nullptr); -} - -bool Component::BailOutChecker::shouldBailOut() const noexcept -{ - return safePointer == nullptr; -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/components/juce_Component.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/components/juce_Component.h deleted file mode 100644 index edc1957a3e..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/components/juce_Component.h +++ /dev/null @@ -1,2378 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_COMPONENT_H_INCLUDED -#define JUCE_COMPONENT_H_INCLUDED - - -//============================================================================== -/** - The base class for all JUCE user-interface objects. -*/ -class JUCE_API Component : public MouseListener -{ -public: - //============================================================================== - /** Creates a component. - - To get it to actually appear, you'll also need to: - - Either add it to a parent component or use the addToDesktop() method to - make it a desktop window - - Set its size and position to something sensible - - Use setVisible() to make it visible - - And for it to serve any useful purpose, you'll need to write a - subclass of Component or use one of the other types of component from - the library. - */ - Component() noexcept; - - /** Destructor. - - Note that when a component is deleted, any child components it contains are NOT - automatically deleted. It's your responsibilty to manage their lifespan - you - may want to use helper methods like deleteAllChildren(), or less haphazard - approaches like using ScopedPointers or normal object aggregation to manage them. - - If the component being deleted is currently the child of another one, then during - deletion, it will be removed from its parent, and the parent will receive a childrenChanged() - callback. Any ComponentListener objects that have registered with it will also have their - ComponentListener::componentBeingDeleted() methods called. - */ - virtual ~Component(); - - //============================================================================== - /** Creates a component, setting its name at the same time. - @see getName, setName - */ - explicit Component (const String& componentName) noexcept; - - /** Returns the name of this component. - @see setName - */ - const String& getName() const noexcept { return componentName; } - - /** Sets the name of this component. - - When the name changes, all registered ComponentListeners will receive a - ComponentListener::componentNameChanged() callback. - - @see getName - */ - virtual void setName (const String& newName); - - /** Returns the ID string that was set by setComponentID(). - @see setComponentID, findChildWithID - */ - const String& getComponentID() const noexcept { return componentID; } - - /** Sets the component's ID string. - You can retrieve the ID using getComponentID(). - @see getComponentID, findChildWithID - */ - void setComponentID (const String& newID); - - //============================================================================== - /** Makes the component visible or invisible. - - This method will show or hide the component. - Note that components default to being non-visible when first created. - Also note that visible components won't be seen unless all their parent components - are also visible. - - This method will call visibilityChanged() and also componentVisibilityChanged() - for any component listeners that are interested in this component. - - @param shouldBeVisible whether to show or hide the component - @see isVisible, isShowing, visibilityChanged, ComponentListener::componentVisibilityChanged - */ - virtual void setVisible (bool shouldBeVisible); - - /** Tests whether the component is visible or not. - - this doesn't necessarily tell you whether this comp is actually on the screen - because this depends on whether all the parent components are also visible - use - isShowing() to find this out. - - @see isShowing, setVisible - */ - bool isVisible() const noexcept { return flags.visibleFlag; } - - /** Called when this component's visibility changes. - @see setVisible, isVisible - */ - virtual void visibilityChanged(); - - /** Tests whether this component and all its parents are visible. - - @returns true only if this component and all its parents are visible. - @see isVisible - */ - bool isShowing() const; - - //============================================================================== - /** Makes this component appear as a window on the desktop. - - Note that before calling this, you should make sure that the component's opacity is - set correctly using setOpaque(). If the component is non-opaque, the windowing - system will try to create a special transparent window for it, which will generally take - a lot more CPU to operate (and might not even be possible on some platforms). - - If the component is inside a parent component at the time this method is called, it - will be first be removed from that parent. Likewise if a component on the desktop - is subsequently added to another component, it'll be removed from the desktop. - - @param windowStyleFlags a combination of the flags specified in the - ComponentPeer::StyleFlags enum, which define the - window's characteristics. - @param nativeWindowToAttachTo this allows an OS object to be passed-in as the window - in which the juce component should place itself. On Windows, - this would be a HWND, a HIViewRef on the Mac. Not necessarily - supported on all platforms, and best left as 0 unless you know - what you're doing - @see removeFromDesktop, isOnDesktop, userTriedToCloseWindow, - getPeer, ComponentPeer::setMinimised, ComponentPeer::StyleFlags, - ComponentPeer::getStyleFlags, ComponentPeer::setFullScreen - */ - virtual void addToDesktop (int windowStyleFlags, - void* nativeWindowToAttachTo = nullptr); - - /** If the component is currently showing on the desktop, this will hide it. - - You can also use setVisible() to hide a desktop window temporarily, but - removeFromDesktop() will free any system resources that are being used up. - - @see addToDesktop, isOnDesktop - */ - void removeFromDesktop(); - - /** Returns true if this component is currently showing on the desktop. - @see addToDesktop, removeFromDesktop - */ - bool isOnDesktop() const noexcept; - - /** Returns the heavyweight window that contains this component. - - If this component is itself on the desktop, this will return the window - object that it is using. Otherwise, it will return the window of - its top-level parent component. - - This may return nullptr if there isn't a desktop component. - - @see addToDesktop, isOnDesktop - */ - ComponentPeer* getPeer() const; - - /** For components on the desktop, this is called if the system wants to close the window. - - This is a signal that either the user or the system wants the window to close. The - default implementation of this method will trigger an assertion to warn you that your - component should do something about it, but you can override this to ignore the event - if you want. - */ - virtual void userTriedToCloseWindow(); - - /** Called for a desktop component which has just been minimised or un-minimised. - This will only be called for components on the desktop. - @see getPeer, ComponentPeer::setMinimised, ComponentPeer::isMinimised - */ - virtual void minimisationStateChanged (bool isNowMinimised); - - /** Returns the default scale factor to use for this component when it is placed - on the desktop. - The default implementation of this method just returns the value from - Desktop::getGlobalScaleFactor(), but it can be overridden if a particular component - has different requirements. The method only used if this component is added - to the desktop - it has no effect for child components. - */ - virtual float getDesktopScaleFactor() const; - - //============================================================================== - /** Brings the component to the front of its siblings. - - If some of the component's siblings have had their 'always-on-top' flag set, - then they will still be kept in front of this one (unless of course this - one is also 'always-on-top'). - - @param shouldAlsoGainFocus if true, this will also try to assign keyboard focus - to the component (see grabKeyboardFocus() for more details) - @see toBack, toBehind, setAlwaysOnTop - */ - void toFront (bool shouldAlsoGainFocus); - - /** Changes this component's z-order to be at the back of all its siblings. - - If the component is set to be 'always-on-top', it will only be moved to the - back of the other other 'always-on-top' components. - - @see toFront, toBehind, setAlwaysOnTop - */ - void toBack(); - - /** Changes this component's z-order so that it's just behind another component. - @see toFront, toBack - */ - void toBehind (Component* other); - - /** Sets whether the component should always be kept at the front of its siblings. - @see isAlwaysOnTop - */ - void setAlwaysOnTop (bool shouldStayOnTop); - - /** Returns true if this component is set to always stay in front of its siblings. - @see setAlwaysOnTop - */ - bool isAlwaysOnTop() const noexcept; - - //============================================================================== - /** Returns the x coordinate of the component's left edge. - This is a distance in pixels from the left edge of the component's parent. - - Note that if you've used setTransform() to apply a transform, then the component's - bounds will no longer be a direct reflection of the position at which it appears within - its parent, as the transform will be applied to its bounding box. - */ - int getX() const noexcept { return bounds.getX(); } - - /** Returns the y coordinate of the top of this component. - This is a distance in pixels from the top edge of the component's parent. - - Note that if you've used setTransform() to apply a transform, then the component's - bounds will no longer be a direct reflection of the position at which it appears within - its parent, as the transform will be applied to its bounding box. - */ - int getY() const noexcept { return bounds.getY(); } - - /** Returns the component's width in pixels. */ - int getWidth() const noexcept { return bounds.getWidth(); } - - /** Returns the component's height in pixels. */ - int getHeight() const noexcept { return bounds.getHeight(); } - - /** Returns the x coordinate of the component's right-hand edge. - This is a distance in pixels from the left edge of the component's parent. - - Note that if you've used setTransform() to apply a transform, then the component's - bounds will no longer be a direct reflection of the position at which it appears within - its parent, as the transform will be applied to its bounding box. - */ - int getRight() const noexcept { return bounds.getRight(); } - - /** Returns the component's top-left position as a Point. */ - Point getPosition() const noexcept { return bounds.getPosition(); } - - /** Returns the y coordinate of the bottom edge of this component. - This is a distance in pixels from the top edge of the component's parent. - - Note that if you've used setTransform() to apply a transform, then the component's - bounds will no longer be a direct reflection of the position at which it appears within - its parent, as the transform will be applied to its bounding box. - */ - int getBottom() const noexcept { return bounds.getBottom(); } - - /** Returns this component's bounding box. - The rectangle returned is relative to the top-left of the component's parent. - - Note that if you've used setTransform() to apply a transform, then the component's - bounds will no longer be a direct reflection of the position at which it appears within - its parent, as the transform will be applied to its bounding box. - */ - const Rectangle& getBounds() const noexcept { return bounds; } - - /** Returns the component's bounds, relative to its own origin. - This is like getBounds(), but returns the rectangle in local coordinates, In practice, it'll - return a rectangle with position (0, 0), and the same size as this component. - */ - Rectangle getLocalBounds() const noexcept; - - /** Returns the area of this component's parent which this component covers. - - The returned area is relative to the parent's coordinate space. - If the component has an affine transform specified, then the resulting area will be - the smallest rectangle that fully covers the component's transformed bounding box. - If this component has no parent, the return value will simply be the same as getBounds(). - */ - Rectangle getBoundsInParent() const noexcept; - - //============================================================================== - /** Returns this component's x coordinate relative the screen's top-left origin. - @see getX, localPointToGlobal - */ - int getScreenX() const; - - /** Returns this component's y coordinate relative the screen's top-left origin. - @see getY, localPointToGlobal - */ - int getScreenY() const; - - /** Returns the position of this component's top-left corner relative to the screen's top-left. - @see getScreenBounds - */ - Point getScreenPosition() const; - - /** Returns the bounds of this component, relative to the screen's top-left. - @see getScreenPosition - */ - Rectangle getScreenBounds() const; - - /** Converts a point to be relative to this component's coordinate space. - - This takes a point relative to a different component, and returns its position relative to this - component. If the sourceComponent parameter is null, the source point is assumed to be a global - screen coordinate. - */ - Point getLocalPoint (const Component* sourceComponent, - Point pointRelativeToSourceComponent) const; - - /** Converts a point to be relative to this component's coordinate space. - - This takes a point relative to a different component, and returns its position relative to this - component. If the sourceComponent parameter is null, the source point is assumed to be a global - screen coordinate. - */ - Point getLocalPoint (const Component* sourceComponent, - Point pointRelativeToSourceComponent) const; - - /** Converts a rectangle to be relative to this component's coordinate space. - - This takes a rectangle that is relative to a different component, and returns its position relative - to this component. If the sourceComponent parameter is null, the source rectangle is assumed to be - a screen coordinate. - - If you've used setTransform() to apply one or more transforms to components, then the source rectangle - may not actually be rectanglular when converted to the target space, so in that situation this will return - the smallest rectangle that fully contains the transformed area. - */ - Rectangle getLocalArea (const Component* sourceComponent, - const Rectangle& areaRelativeToSourceComponent) const; - - /** Converts a point relative to this component's top-left into a screen coordinate. - @see getLocalPoint, localAreaToGlobal - */ - Point localPointToGlobal (Point localPoint) const; - - /** Converts a point relative to this component's top-left into a screen coordinate. - @see getLocalPoint, localAreaToGlobal - */ - Point localPointToGlobal (Point localPoint) const; - - /** Converts a rectangle from this component's coordinate space to a screen coordinate. - - If you've used setTransform() to apply one or more transforms to components, then the source rectangle - may not actually be rectanglular when converted to the target space, so in that situation this will return - the smallest rectangle that fully contains the transformed area. - @see getLocalPoint, localPointToGlobal - */ - Rectangle localAreaToGlobal (const Rectangle& localArea) const; - - //============================================================================== - /** Moves the component to a new position. - - Changes the component's top-left position (without changing its size). - The position is relative to the top-left of the component's parent. - - If the component actually moves, this method will make a synchronous call to moved(). - - Note that if you've used setTransform() to apply a transform, then the component's - bounds will no longer be a direct reflection of the position at which it appears within - its parent, as the transform will be applied to whatever bounds you set for it. - - @see setBounds, ComponentListener::componentMovedOrResized - */ - void setTopLeftPosition (int x, int y); - - /** Moves the component to a new position. - - Changes the component's top-left position (without changing its size). - The position is relative to the top-left of the component's parent. - - If the component actually moves, this method will make a synchronous call to moved(). - - Note that if you've used setTransform() to apply a transform, then the component's - bounds will no longer be a direct reflection of the position at which it appears within - its parent, as the transform will be applied to whatever bounds you set for it. - - @see setBounds, ComponentListener::componentMovedOrResized - */ - void setTopLeftPosition (Point newTopLeftPosition); - - /** Moves the component to a new position. - - Changes the position of the component's top-right corner (keeping it the same size). - The position is relative to the top-left of the component's parent. - - If the component actually moves, this method will make a synchronous call to moved(). - - Note that if you've used setTransform() to apply a transform, then the component's - bounds will no longer be a direct reflection of the position at which it appears within - its parent, as the transform will be applied to whatever bounds you set for it. - */ - void setTopRightPosition (int x, int y); - - /** Changes the size of the component. - - A synchronous call to resized() will be occur if the size actually changes. - - Note that if you've used setTransform() to apply a transform, then the component's - bounds will no longer be a direct reflection of the position at which it appears within - its parent, as the transform will be applied to whatever bounds you set for it. - */ - void setSize (int newWidth, int newHeight); - - /** Changes the component's position and size. - - The coordinates are relative to the top-left of the component's parent, or relative - to the origin of the screen is the component is on the desktop. - - If this method changes the component's top-left position, it will make a synchronous - call to moved(). If it changes the size, it will also make a call to resized(). - - Note that if you've used setTransform() to apply a transform, then the component's - bounds will no longer be a direct reflection of the position at which it appears within - its parent, as the transform will be applied to whatever bounds you set for it. - - @see setTopLeftPosition, setSize, ComponentListener::componentMovedOrResized - */ - void setBounds (int x, int y, int width, int height); - - /** Changes the component's position and size. - - The coordinates are relative to the top-left of the component's parent, or relative - to the origin of the screen is the component is on the desktop. - - If this method changes the component's top-left position, it will make a synchronous - call to moved(). If it changes the size, it will also make a call to resized(). - - Note that if you've used setTransform() to apply a transform, then the component's - bounds will no longer be a direct reflection of the position at which it appears within - its parent, as the transform will be applied to whatever bounds you set for it. - - @see setBounds - */ - void setBounds (const Rectangle& newBounds); - - /** Changes the component's position and size. - - This is similar to the other setBounds() methods, but uses RelativeRectangle::applyToComponent() - to set the position, This uses a Component::Positioner to make sure that any dynamic - expressions are used in the RelativeRectangle will be automatically re-applied to the - component's bounds when the source values change. See RelativeRectangle::applyToComponent() - for more details. - - When using relative expressions, the following symbols are available: - - "left", "right", "top", "bottom" refer to the position of those edges in this component, so - e.g. for a component whose width is always 100, you might set the right edge to the "left + 100". - - "[id].left", "[id].right", "[id].top", "[id].bottom", "[id].width", "[id].height", where [id] is - the identifier of one of this component's siblings. A component's identifier is set with - Component::setComponentID(). So for example if you want your component to always be 50 pixels to the - right of the one called "xyz", you could set your left edge to be "xyz.right + 50". - - Instead of an [id], you can use the name "parent" to refer to this component's parent. Like - any other component, these values are relative to their component's parent, so "parent.right" won't be - very useful for positioning a component because it refers to a position with the parent's parent.. but - "parent.width" can be used for setting positions relative to the parent's size. E.g. to make a 10x10 - component which remains 1 pixel away from its parent's bottom-right, you could use - "right - 10, bottom - 10, parent.width - 1, parent.height - 1". - - The name of one of the parent component's markers can also be used as a symbol. For markers to be - used, the parent component must implement its Component::getMarkers() method, and return at least one - valid MarkerList. So if you want your component's top edge to be 10 pixels below the - marker called "foobar", you'd set it to "foobar + 10". - - See the Expression class for details about the operators that are supported, but for example - if you wanted to make your component remain centred within its parent with a size of 100, 100, - you could express it as: - @code myComp.setBounds (RelativeBounds ("parent.width / 2 - 50, parent.height / 2 - 50, left + 100, top + 100")); - @endcode - ..or an alternative way to achieve the same thing: - @code myComp.setBounds (RelativeBounds ("right - 100, bottom - 100, parent.width / 2 + 50, parent.height / 2 + 50")); - @endcode - - Or if you wanted a 100x100 component whose top edge is lined up to a marker called "topMarker" and - which is positioned 50 pixels to the right of another component called "otherComp", you could write: - @code myComp.setBounds (RelativeBounds ("otherComp.right + 50, topMarker, left + 100, top + 100")); - @endcode - - Be careful not to make your coordinate expressions recursive, though, or exceptions and assertions will - be thrown! - - @see setBounds, RelativeRectangle::applyToComponent(), Expression - */ - void setBounds (const RelativeRectangle& newBounds); - - /** Sets the component's bounds with an expression. - The string is parsed as a RelativeRectangle expression - see the notes for - Component::setBounds (const RelativeRectangle&) for more information. This method is - basically just a shortcut for writing setBounds (RelativeRectangle ("...")) - */ - void setBounds (const String& newBoundsExpression); - - /** Changes the component's position and size in terms of fractions of its parent's size. - - The values are factors of the parent's size, so for example - setBoundsRelative (0.2f, 0.2f, 0.5f, 0.5f) would give it half the - width and height of the parent, with its top-left position 20% of - the way across and down the parent. - - @see setBounds - */ - void setBoundsRelative (float proportionalX, float proportionalY, - float proportionalWidth, float proportionalHeight); - - /** Changes the component's position and size based on the amount of space to leave around it. - - This will position the component within its parent, leaving the specified number of - pixels around each edge. - - @see setBounds - */ - void setBoundsInset (const BorderSize& borders); - - /** Positions the component within a given rectangle, keeping its proportions - unchanged. - - If onlyReduceInSize is false, the component will be resized to fill as much of the - rectangle as possible without changing its aspect ratio (the component's - current size is used to determine its aspect ratio, so a zero-size component - won't work here). If onlyReduceInSize is true, it will only be resized if it's - too big to fit inside the rectangle. - - It will then be positioned within the rectangle according to the justification flags - specified. - - @see setBounds - */ - void setBoundsToFit (int x, int y, int width, int height, - Justification justification, - bool onlyReduceInSize); - - /** Changes the position of the component's centre. - - Leaves the component's size unchanged, but sets the position of its centre - relative to its parent's top-left. - - @see setBounds - */ - void setCentrePosition (int x, int y); - - /** Changes the position of the component's centre. - - Leaves the position unchanged, but positions its centre relative to its - parent's size. E.g. setCentreRelative (0.5f, 0.5f) would place it centrally in - its parent. - */ - void setCentreRelative (float x, float y); - - /** Changes the component's size and centres it within its parent. - - After changing the size, the component will be moved so that it's - centred within its parent. If the component is on the desktop (or has no - parent component), then it'll be centred within the main monitor area. - */ - void centreWithSize (int width, int height); - - //============================================================================== - /** Sets a transform matrix to be applied to this component. - - If you set a transform for a component, the component's position will be warped by it, relative to - the component's parent's top-left origin. This means that the values you pass into setBounds() will no - longer reflect the actual area within the parent that the component covers, as the bounds will be - transformed and the component will probably end up actually appearing somewhere else within its parent. - - When using transforms you need to be extremely careful when converting coordinates between the - coordinate spaces of different components or the screen - you should always use getLocalPoint(), - getLocalArea(), etc to do this, and never just manually add a component's position to a point in order to - convert it between different components (but I'm sure you would never have done that anyway...). - - Currently, transforms are not supported for desktop windows, so the transform will be ignored if you - put a component on the desktop. - - To remove a component's transform, simply pass AffineTransform::identity as the parameter to this method. - */ - void setTransform (const AffineTransform& transform); - - /** Returns the transform that is currently being applied to this component. - For more details about transforms, see setTransform(). - @see setTransform - */ - AffineTransform getTransform() const; - - /** Returns true if a non-identity transform is being applied to this component. - For more details about transforms, see setTransform(). - @see setTransform - */ - bool isTransformed() const noexcept; - - //============================================================================== - /** Returns a proportion of the component's width. - This is a handy equivalent of (getWidth() * proportion). - */ - int proportionOfWidth (float proportion) const noexcept; - - /** Returns a proportion of the component's height. - This is a handy equivalent of (getHeight() * proportion). - */ - int proportionOfHeight (float proportion) const noexcept; - - /** Returns the width of the component's parent. - - If the component has no parent (i.e. if it's on the desktop), this will return - the width of the screen. - */ - int getParentWidth() const noexcept; - - /** Returns the height of the component's parent. - - If the component has no parent (i.e. if it's on the desktop), this will return - the height of the screen. - */ - int getParentHeight() const noexcept; - - /** Returns the screen coordinates of the monitor that contains this component. - - If there's only one monitor, this will return its size - if there are multiple - monitors, it will return the area of the monitor that contains the component's - centre. - */ - Rectangle getParentMonitorArea() const; - - //============================================================================== - /** Returns the number of child components that this component contains. - - @see getChildComponent, getIndexOfChildComponent - */ - int getNumChildComponents() const noexcept; - - /** Returns one of this component's child components, by it index. - - The component with index 0 is at the back of the z-order, the one at the - front will have index (getNumChildComponents() - 1). - - If the index is out-of-range, this will return a null pointer. - - @see getNumChildComponents, getIndexOfChildComponent - */ - Component* getChildComponent (int index) const noexcept; - - /** Returns the index of this component in the list of child components. - - A value of 0 means it is first in the list (i.e. behind all other components). Higher - values are further towards the front. - - Returns -1 if the component passed-in is not a child of this component. - - @see getNumChildComponents, getChildComponent, addChildComponent, toFront, toBack, toBehind - */ - int getIndexOfChildComponent (const Component* child) const noexcept; - - /** Looks for a child component with the specified ID. - @see setComponentID, getComponentID - */ - Component* findChildWithID (StringRef componentID) const noexcept; - - /** Adds a child component to this one. - - Adding a child component does not mean that the component will own or delete the child - it's - your responsibility to delete the component. Note that it's safe to delete a component - without first removing it from its parent - doing so will automatically remove it and - send out the appropriate notifications before the deletion completes. - - If the child is already a child of this component, then no action will be taken, and its - z-order will be left unchanged. - - @param child the new component to add. If the component passed-in is already - the child of another component, it'll first be removed from it current parent. - @param zOrder The index in the child-list at which this component should be inserted. - A value of -1 will insert it in front of the others, 0 is the back. - @see removeChildComponent, addAndMakeVisible, addChildAndSetID, getChild, ComponentListener::componentChildrenChanged - */ - void addChildComponent (Component* child, int zOrder = -1); - - /** Adds a child component to this one. - - Adding a child component does not mean that the component will own or delete the child - it's - your responsibility to delete the component. Note that it's safe to delete a component - without first removing it from its parent - doing so will automatically remove it and - send out the appropriate notifications before the deletion completes. - - If the child is already a child of this component, then no action will be taken, and its - z-order will be left unchanged. - - @param child the new component to add. If the component passed-in is already - the child of another component, it'll first be removed from it current parent. - @param zOrder The index in the child-list at which this component should be inserted. - A value of -1 will insert it in front of the others, 0 is the back. - @see removeChildComponent, addAndMakeVisible, addChildAndSetID, getChild, ComponentListener::componentChildrenChanged - */ - void addChildComponent (Component& child, int zOrder = -1); - - /** Adds a child component to this one, and also makes the child visible if it isn't already. - - This is the same as calling setVisible (true) on the child and then addChildComponent(). - See addChildComponent() for more details. - */ - void addAndMakeVisible (Component* child, int zOrder = -1); - - /** Adds a child component to this one, and also makes the child visible if it isn't already. - - This is the same as calling setVisible (true) on the child and then addChildComponent(). - See addChildComponent() for more details. - */ - void addAndMakeVisible (Component& child, int zOrder = -1); - - /** Adds a child component to this one, makes it visible, and sets its component ID. - @see addAndMakeVisible, addChildComponent - */ - void addChildAndSetID (Component* child, const String& componentID); - - /** Removes one of this component's child-components. - - If the child passed-in isn't actually a child of this component (either because - it's invalid or is the child of a different parent), then no action is taken. - - Note that removing a child will not delete it! But it's ok to delete a component - without first removing it - doing so will automatically remove it and send out the - appropriate notifications before the deletion completes. - - @see addChildComponent, ComponentListener::componentChildrenChanged - */ - void removeChildComponent (Component* childToRemove); - - /** Removes one of this component's child-components by index. - - This will return a pointer to the component that was removed, or null if - the index was out-of-range. - - Note that removing a child will not delete it! But it's ok to delete a component - without first removing it - doing so will automatically remove it and send out the - appropriate notifications before the deletion completes. - - @see addChildComponent, ComponentListener::componentChildrenChanged - */ - Component* removeChildComponent (int childIndexToRemove); - - /** Removes all this component's children. - Note that this won't delete them! To do that, use deleteAllChildren() instead. - */ - void removeAllChildren(); - - /** Removes all this component's children, and deletes them. - @see removeAllChildren - */ - void deleteAllChildren(); - - /** Returns the component which this component is inside. - - If this is the highest-level component or hasn't yet been added to - a parent, this will return null. - */ - Component* getParentComponent() const noexcept { return parentComponent; } - - /** Searches the parent components for a component of a specified class. - - For example findParentComponentOfClass \() would return the first parent - component that can be dynamically cast to a MyComp, or will return 0 if none - of the parents are suitable. - */ - template - TargetClass* findParentComponentOfClass() const - { - for (Component* p = parentComponent; p != nullptr; p = p->parentComponent) - if (TargetClass* const target = dynamic_cast (p)) - return target; - - return nullptr; - } - - /** Returns the highest-level component which contains this one or its parents. - - This will search upwards in the parent-hierarchy from this component, until it - finds the highest one that doesn't have a parent (i.e. is on the desktop or - not yet added to a parent), and will return that. - */ - Component* getTopLevelComponent() const noexcept; - - /** Checks whether a component is anywhere inside this component or its children. - - This will recursively check through this component's children to see if the - given component is anywhere inside. - */ - bool isParentOf (const Component* possibleChild) const noexcept; - - //============================================================================== - /** Called to indicate that the component's parents have changed. - - When a component is added or removed from its parent, this method will - be called on all of its children (recursively - so all children of its - children will also be called as well). - - Subclasses can override this if they need to react to this in some way. - - @see getParentComponent, isShowing, ComponentListener::componentParentHierarchyChanged - */ - virtual void parentHierarchyChanged(); - - /** Subclasses can use this callback to be told when children are added or removed, or - when their z-order changes. - @see parentHierarchyChanged, ComponentListener::componentChildrenChanged - */ - virtual void childrenChanged(); - - //============================================================================== - /** Tests whether a given point inside the component. - - Overriding this method allows you to create components which only intercept - mouse-clicks within a user-defined area. - - This is called to find out whether a particular x, y coordinate is - considered to be inside the component or not, and is used by methods such - as contains() and getComponentAt() to work out which component - the mouse is clicked on. - - Components with custom shapes will probably want to override it to perform - some more complex hit-testing. - - The default implementation of this method returns either true or false, - depending on the value that was set by calling setInterceptsMouseClicks() (true - is the default return value). - - Note that the hit-test region is not related to the opacity with which - areas of a component are painted. - - Applications should never call hitTest() directly - instead use the - contains() method, because this will also test for occlusion by the - component's parent. - - Note that for components on the desktop, this method will be ignored, because it's - not always possible to implement this behaviour on all platforms. - - @param x the x coordinate to test, relative to the left hand edge of this - component. This value is guaranteed to be greater than or equal to - zero, and less than the component's width - @param y the y coordinate to test, relative to the top edge of this - component. This value is guaranteed to be greater than or equal to - zero, and less than the component's height - @returns true if the click is considered to be inside the component - @see setInterceptsMouseClicks, contains - */ - virtual bool hitTest (int x, int y); - - /** Changes the default return value for the hitTest() method. - - Setting this to false is an easy way to make a component pass its mouse-clicks - through to the components behind it. - - When a component is created, the default setting for this is true. - - @param allowClicksOnThisComponent if true, hitTest() will always return true; if false, it will - return false (or true for child components if allowClicksOnChildComponents - is true) - @param allowClicksOnChildComponents if this is true and allowClicksOnThisComponent is false, then child - components can be clicked on as normal but clicks on this component pass - straight through; if this is false and allowClicksOnThisComponent - is false, then neither this component nor any child components can - be clicked on - @see hitTest, getInterceptsMouseClicks - */ - void setInterceptsMouseClicks (bool allowClicksOnThisComponent, - bool allowClicksOnChildComponents) noexcept; - - /** Retrieves the current state of the mouse-click interception flags. - - On return, the two parameters are set to the state used in the last call to - setInterceptsMouseClicks(). - - @see setInterceptsMouseClicks - */ - void getInterceptsMouseClicks (bool& allowsClicksOnThisComponent, - bool& allowsClicksOnChildComponents) const noexcept; - - - /** Returns true if a given point lies within this component or one of its children. - - Never override this method! Use hitTest to create custom hit regions. - - @param localPoint the coordinate to test, relative to this component's top-left. - @returns true if the point is within the component's hit-test area, but only if - that part of the component isn't clipped by its parent component. Note - that this won't take into account any overlapping sibling components - which might be in the way - for that, see reallyContains() - @see hitTest, reallyContains, getComponentAt - */ - bool contains (Point localPoint); - - /** Returns true if a given point lies in this component, taking any overlapping - siblings into account. - - @param localPoint the coordinate to test, relative to this component's top-left. - @param returnTrueIfWithinAChild if the point actually lies within a child of this component, - this determines whether that is counted as a hit. - @see contains, getComponentAt - */ - bool reallyContains (Point localPoint, bool returnTrueIfWithinAChild); - - /** Returns the component at a certain point within this one. - - @param x the x coordinate to test, relative to this component's left edge. - @param y the y coordinate to test, relative to this component's top edge. - @returns the component that is at this position - which may be 0, this component, - or one of its children. Note that overlapping siblings that might actually - be in the way are not taken into account by this method - to account for these, - instead call getComponentAt on the top-level parent of this component. - @see hitTest, contains, reallyContains - */ - Component* getComponentAt (int x, int y); - - /** Returns the component at a certain point within this one. - - @param position the coordinate to test, relative to this component's top-left. - @returns the component that is at this position - which may be 0, this component, - or one of its children. Note that overlapping siblings that might actually - be in the way are not taken into account by this method - to account for these, - instead call getComponentAt on the top-level parent of this component. - @see hitTest, contains, reallyContains - */ - Component* getComponentAt (Point position); - - //============================================================================== - /** Marks the whole component as needing to be redrawn. - - Calling this will not do any repainting immediately, but will mark the component - as 'dirty'. At some point in the near future the operating system will send a paint - message, which will redraw all the dirty regions of all components. - There's no guarantee about how soon after calling repaint() the redraw will actually - happen, and other queued events may be delivered before a redraw is done. - - If the setBufferedToImage() method has been used to cause this component to use a - buffer, the repaint() call will invalidate the cached buffer. If setCachedComponentImage() - has been used to provide a custom image cache, that cache will be invalidated appropriately. - - To redraw just a subsection of the component rather than the whole thing, - use the repaint (int, int, int, int) method. - - @see paint - */ - void repaint(); - - /** Marks a subsection of this component as needing to be redrawn. - - Calling this will not do any repainting immediately, but will mark the given region - of the component as 'dirty'. At some point in the near future the operating system - will send a paint message, which will redraw all the dirty regions of all components. - There's no guarantee about how soon after calling repaint() the redraw will actually - happen, and other queued events may be delivered before a redraw is done. - - The region that is passed in will be clipped to keep it within the bounds of this - component. - - @see repaint() - */ - void repaint (int x, int y, int width, int height); - - /** Marks a subsection of this component as needing to be redrawn. - - Calling this will not do any repainting immediately, but will mark the given region - of the component as 'dirty'. At some point in the near future the operating system - will send a paint message, which will redraw all the dirty regions of all components. - There's no guarantee about how soon after calling repaint() the redraw will actually - happen, and other queued events may be delivered before a redraw is done. - - The region that is passed in will be clipped to keep it within the bounds of this - component. - - @see repaint() - */ - void repaint (const Rectangle& area); - - //============================================================================== - /** Makes the component use an internal buffer to optimise its redrawing. - - Setting this flag to true will cause the component to allocate an - internal buffer into which it paints itself, so that when asked to - redraw itself, it can use this buffer rather than actually calling the - paint() method. - - The buffer is kept until the repaint() method is called directly on - this component (or until it is resized), when the image is invalidated - and then redrawn the next time the component is painted. - - Note that only the drawing that happens within the component's paint() - method is drawn into the buffer, it's child components are not buffered, and - nor is the paintOverChildren() method. - - @see repaint, paint, createComponentSnapshot - */ - void setBufferedToImage (bool shouldBeBuffered); - - /** Generates a snapshot of part of this component. - - This will return a new Image, the size of the rectangle specified, - containing a snapshot of the specified area of the component and all - its children. - - The image may or may not have an alpha-channel, depending on whether the - image is opaque or not. - - If the clipImageToComponentBounds parameter is true and the area is greater than - the size of the component, it'll be clipped. If clipImageToComponentBounds is false - then parts of the component beyond its bounds can be drawn. - - @see paintEntireComponent - */ - Image createComponentSnapshot (const Rectangle& areaToGrab, - bool clipImageToComponentBounds = true, - float scaleFactor = 1.0f); - - /** Draws this component and all its subcomponents onto the specified graphics - context. - - You should very rarely have to use this method, it's simply there in case you need - to draw a component with a custom graphics context for some reason, e.g. for - creating a snapshot of the component. - - It calls paint(), paintOverChildren() and recursively calls paintEntireComponent() - on its children in order to render the entire tree. - - The graphics context may be left in an undefined state after this method returns, - so you may need to reset it if you're going to use it again. - - If ignoreAlphaLevel is false, then the component will be drawn with the opacity level - specified by getAlpha(); if ignoreAlphaLevel is true, then this will be ignored and - an alpha of 1.0 will be used. - */ - void paintEntireComponent (Graphics& context, bool ignoreAlphaLevel); - - /** This allows you to indicate that this component doesn't require its graphics - context to be clipped when it is being painted. - - Most people will never need to use this setting, but in situations where you have a very large - number of simple components being rendered, and where they are guaranteed never to do any drawing - beyond their own boundaries, setting this to true will reduce the overhead involved in clipping - the graphics context that gets passed to the component's paint() callback. - If you enable this mode, you'll need to make sure your paint method doesn't call anything like - Graphics::fillAll(), and doesn't draw beyond the component's bounds, because that'll produce - artifacts. Your component also can't have any child components that may be placed beyond its - bounds. - */ - void setPaintingIsUnclipped (bool shouldPaintWithoutClipping) noexcept; - - //============================================================================== - /** Adds an effect filter to alter the component's appearance. - - When a component has an effect filter set, then this is applied to the - results of its paint() method. There are a few preset effects, such as - a drop-shadow or glow, but they can be user-defined as well. - - The effect that is passed in will not be deleted by the component - the - caller must take care of deleting it. - - To remove an effect from a component, pass a null pointer in as the parameter. - - @see ImageEffectFilter, DropShadowEffect, GlowEffect - */ - void setComponentEffect (ImageEffectFilter* newEffect); - - /** Returns the current component effect. - @see setComponentEffect - */ - ImageEffectFilter* getComponentEffect() const noexcept { return effect; } - - //============================================================================== - /** Finds the appropriate look-and-feel to use for this component. - - If the component hasn't had a look-and-feel explicitly set, this will - return the parent's look-and-feel, or just the default one if there's no - parent. - - @see setLookAndFeel, lookAndFeelChanged - */ - LookAndFeel& getLookAndFeel() const noexcept; - - /** Sets the look and feel to use for this component. - - This will also change the look and feel for any child components that haven't - had their look set explicitly. - - The object passed in will not be deleted by the component, so it's the caller's - responsibility to manage it. It may be used at any time until this component - has been deleted. - - Calling this method will also invoke the sendLookAndFeelChange() method. - - @see getLookAndFeel, lookAndFeelChanged - */ - void setLookAndFeel (LookAndFeel* newLookAndFeel); - - /** Called to let the component react to a change in the look-and-feel setting. - - When the look-and-feel is changed for a component, this will be called in - all its child components, recursively. - - It can also be triggered manually by the sendLookAndFeelChange() method, in case - an application uses a LookAndFeel class that might have changed internally. - - @see sendLookAndFeelChange, getLookAndFeel - */ - virtual void lookAndFeelChanged(); - - /** Calls the lookAndFeelChanged() method in this component and all its children. - - This will recurse through the children and their children, calling lookAndFeelChanged() - on them all. - - @see lookAndFeelChanged - */ - void sendLookAndFeelChange(); - - //============================================================================== - /** Indicates whether any parts of the component might be transparent. - - Components that always paint all of their contents with solid colour and - thus completely cover any components behind them should use this method - to tell the repaint system that they are opaque. - - This information is used to optimise drawing, because it means that - objects underneath opaque windows don't need to be painted. - - By default, components are considered transparent, unless this is used to - make it otherwise. - - @see isOpaque - */ - void setOpaque (bool shouldBeOpaque); - - /** Returns true if no parts of this component are transparent. - - @returns the value that was set by setOpaque, (the default being false) - @see setOpaque - */ - bool isOpaque() const noexcept; - - //============================================================================== - /** Indicates whether the component should be brought to the front when clicked. - - Setting this flag to true will cause the component to be brought to the front - when the mouse is clicked somewhere inside it or its child components. - - Note that a top-level desktop window might still be brought to the front by the - operating system when it's clicked, depending on how the OS works. - - By default this is set to false. - - @see setMouseClickGrabsKeyboardFocus - */ - void setBroughtToFrontOnMouseClick (bool shouldBeBroughtToFront) noexcept; - - /** Indicates whether the component should be brought to the front when clicked-on. - @see setBroughtToFrontOnMouseClick - */ - bool isBroughtToFrontOnMouseClick() const noexcept; - - //============================================================================== - // Keyboard focus methods - - /** Sets a flag to indicate whether this component needs keyboard focus or not. - - By default components aren't actually interested in gaining the - focus, but this method can be used to turn this on. - - See the grabKeyboardFocus() method for details about the way a component - is chosen to receive the focus. - - @see grabKeyboardFocus, getWantsKeyboardFocus - */ - void setWantsKeyboardFocus (bool wantsFocus) noexcept; - - /** Returns true if the component is interested in getting keyboard focus. - - This returns the flag set by setWantsKeyboardFocus(). The default - setting is false. - - @see setWantsKeyboardFocus - */ - bool getWantsKeyboardFocus() const noexcept; - - //============================================================================== - /** Chooses whether a click on this component automatically grabs the focus. - - By default this is set to true, but you might want a component which can - be focused, but where you don't want the user to be able to affect it directly - by clicking. - */ - void setMouseClickGrabsKeyboardFocus (bool shouldGrabFocus); - - /** Returns the last value set with setMouseClickGrabsKeyboardFocus(). - See setMouseClickGrabsKeyboardFocus() for more info. - */ - bool getMouseClickGrabsKeyboardFocus() const noexcept; - - //============================================================================== - /** Tries to give keyboard focus to this component. - - When the user clicks on a component or its grabKeyboardFocus() - method is called, the following procedure is used to work out which - component should get it: - - - if the component that was clicked on actually wants focus (as indicated - by calling getWantsKeyboardFocus), it gets it. - - if the component itself doesn't want focus, it will try to pass it - on to whichever of its children is the default component, as determined by - KeyboardFocusTraverser::getDefaultComponent() - - if none of its children want focus at all, it will pass it up to its - parent instead, unless it's a top-level component without a parent, - in which case it just takes the focus itself. - - @see setWantsKeyboardFocus, getWantsKeyboardFocus, hasKeyboardFocus, - getCurrentlyFocusedComponent, focusGained, focusLost, - keyPressed, keyStateChanged - */ - void grabKeyboardFocus(); - - /** Returns true if this component currently has the keyboard focus. - - @param trueIfChildIsFocused if this is true, then the method returns true if - either this component or any of its children (recursively) - have the focus. If false, the method only returns true if - this component has the focus. - - @see grabKeyboardFocus, setWantsKeyboardFocus, getCurrentlyFocusedComponent, - focusGained, focusLost - */ - bool hasKeyboardFocus (bool trueIfChildIsFocused) const; - - /** Returns the component that currently has the keyboard focus. - @returns the focused component, or null if nothing is focused. - */ - static Component* JUCE_CALLTYPE getCurrentlyFocusedComponent() noexcept; - - /** If any component has keyboard focus, this will defocus it. */ - static void JUCE_CALLTYPE unfocusAllComponents(); - - //============================================================================== - /** Tries to move the keyboard focus to one of this component's siblings. - - This will try to move focus to either the next or previous component. (This - is the method that is used when shifting focus by pressing the tab key). - - Components for which getWantsKeyboardFocus() returns false are not looked at. - - @param moveToNext if true, the focus will move forwards; if false, it will - move backwards - @see grabKeyboardFocus, setFocusContainer, setWantsKeyboardFocus - */ - void moveKeyboardFocusToSibling (bool moveToNext); - - /** Creates a KeyboardFocusTraverser object to use to determine the logic by - which focus should be passed from this component. - - The default implementation of this method will return a default - KeyboardFocusTraverser if this component is a focus container (as determined - by the setFocusContainer() method). If the component isn't a focus - container, then it will recursively ask its parents for a KeyboardFocusTraverser. - - If you overrride this to return a custom KeyboardFocusTraverser, then - this component and all its sub-components will use the new object to - make their focusing decisions. - - The method should return a new object, which the caller is required to - delete when no longer needed. - */ - virtual KeyboardFocusTraverser* createFocusTraverser(); - - /** Returns the focus order of this component, if one has been specified. - - By default components don't have a focus order - in that case, this - will return 0. Lower numbers indicate that the component will be - earlier in the focus traversal order. - - To change the order, call setExplicitFocusOrder(). - - The focus order may be used by the KeyboardFocusTraverser class as part of - its algorithm for deciding the order in which components should be traversed. - See the KeyboardFocusTraverser class for more details on this. - - @see moveKeyboardFocusToSibling, createFocusTraverser, KeyboardFocusTraverser - */ - int getExplicitFocusOrder() const; - - /** Sets the index used in determining the order in which focusable components - should be traversed. - - A value of 0 or less is taken to mean that no explicit order is wanted, and - that traversal should use other factors, like the component's position. - - @see getExplicitFocusOrder, moveKeyboardFocusToSibling - */ - void setExplicitFocusOrder (int newFocusOrderIndex); - - /** Indicates whether this component is a parent for components that can have - their focus traversed. - - This flag is used by the default implementation of the createFocusTraverser() - method, which uses the flag to find the first parent component (of the currently - focused one) which wants to be a focus container. - - So using this method to set the flag to 'true' causes this component to - act as the top level within which focus is passed around. - - @see isFocusContainer, createFocusTraverser, moveKeyboardFocusToSibling - */ - void setFocusContainer (bool shouldBeFocusContainer) noexcept; - - /** Returns true if this component has been marked as a focus container. - - See setFocusContainer() for more details. - - @see setFocusContainer, moveKeyboardFocusToSibling, createFocusTraverser - */ - bool isFocusContainer() const noexcept; - - //============================================================================== - /** Returns true if the component (and all its parents) are enabled. - - Components are enabled by default, and can be disabled with setEnabled(). Exactly - what difference this makes to the component depends on the type. E.g. buttons - and sliders will choose to draw themselves differently, etc. - - Note that if one of this component's parents is disabled, this will always - return false, even if this component itself is enabled. - - @see setEnabled, enablementChanged - */ - bool isEnabled() const noexcept; - - /** Enables or disables this component. - - Disabling a component will also cause all of its child components to become - disabled. - - Similarly, enabling a component which is inside a disabled parent - component won't make any difference until the parent is re-enabled. - - @see isEnabled, enablementChanged - */ - void setEnabled (bool shouldBeEnabled); - - /** Callback to indicate that this component has been enabled or disabled. - - This can be triggered by one of the component's parent components - being enabled or disabled, as well as changes to the component itself. - - The default implementation of this method does nothing; your class may - wish to repaint itself or something when this happens. - - @see setEnabled, isEnabled - */ - virtual void enablementChanged(); - - /** Changes the transparency of this component. - When painted, the entire component and all its children will be rendered - with this as the overall opacity level, where 0 is completely invisible, and - 1.0 is fully opaque (i.e. normal). - - @see getAlpha - */ - void setAlpha (float newAlpha); - - /** Returns the component's current transparancy level. - See setAlpha() for more details. - */ - float getAlpha() const; - - //============================================================================== - /** Changes the mouse cursor shape to use when the mouse is over this component. - - Note that the cursor set by this method can be overridden by the getMouseCursor - method. - - @see MouseCursor - */ - void setMouseCursor (const MouseCursor& cursorType); - - /** Returns the mouse cursor shape to use when the mouse is over this component. - - The default implementation will return the cursor that was set by setCursor() - but can be overridden for more specialised purposes, e.g. returning different - cursors depending on the mouse position. - - @see MouseCursor - */ - virtual MouseCursor getMouseCursor(); - - /** Forces the current mouse cursor to be updated. - - If you're overriding the getMouseCursor() method to control which cursor is - displayed, then this will only be checked each time the user moves the mouse. So - if you want to force the system to check that the cursor being displayed is - up-to-date (even if the mouse is just sitting there), call this method. - - (If you're changing the cursor using setMouseCursor(), you don't need to bother - calling this). - */ - void updateMouseCursor() const; - - //============================================================================== - /** Components can override this method to draw their content. - - The paint() method gets called when a region of a component needs redrawing, - either because the component's repaint() method has been called, or because - something has happened on the screen that means a section of a window needs - to be redrawn. - - Any child components will draw themselves over whatever this method draws. If - you need to paint over the top of your child components, you can also implement - the paintOverChildren() method to do this. - - If you want to cause a component to redraw itself, this is done asynchronously - - calling the repaint() method marks a region of the component as "dirty", and the - paint() method will automatically be called sometime later, by the message thread, - to paint any bits that need refreshing. In Juce (and almost all modern UI frameworks), - you never redraw something synchronously. - - You should never need to call this method directly - to take a snapshot of the - component you could use createComponentSnapshot() or paintEntireComponent(). - - @param g the graphics context that must be used to do the drawing operations. - @see repaint, paintOverChildren, Graphics - */ - virtual void paint (Graphics& g); - - /** Components can override this method to draw over the top of their children. - - For most drawing operations, it's better to use the normal paint() method, - but if you need to overlay something on top of the children, this can be - used. - - @see paint, Graphics - */ - virtual void paintOverChildren (Graphics& g); - - - //============================================================================== - /** Called when the mouse moves inside a component. - - If the mouse button isn't pressed and the mouse moves over a component, - this will be called to let the component react to this. - - A component will always get a mouseEnter callback before a mouseMove. - - @param event details about the position and status of the mouse event, including - the source component in which it occurred - @see mouseEnter, mouseExit, mouseDrag, contains - */ - virtual void mouseMove (const MouseEvent& event) override; - - /** Called when the mouse first enters a component. - - If the mouse button isn't pressed and the mouse moves into a component, - this will be called to let the component react to this. - - When the mouse button is pressed and held down while being moved in - or out of a component, no mouseEnter or mouseExit callbacks are made - only - mouseDrag messages are sent to the component that the mouse was originally - clicked on, until the button is released. - - @param event details about the position and status of the mouse event, including - the source component in which it occurred - @see mouseExit, mouseDrag, mouseMove, contains - */ - virtual void mouseEnter (const MouseEvent& event) override; - - /** Called when the mouse moves out of a component. - - This will be called when the mouse moves off the edge of this - component. - - If the mouse button was pressed, and it was then dragged off the - edge of the component and released, then this callback will happen - when the button is released, after the mouseUp callback. - - @param event details about the position and status of the mouse event, including - the source component in which it occurred - @see mouseEnter, mouseDrag, mouseMove, contains - */ - virtual void mouseExit (const MouseEvent& event) override; - - /** Called when a mouse button is pressed. - - The MouseEvent object passed in contains lots of methods for finding out - which button was pressed, as well as which modifier keys (e.g. shift, ctrl) - were held down at the time. - - Once a button is held down, the mouseDrag method will be called when the - mouse moves, until the button is released. - - @param event details about the position and status of the mouse event, including - the source component in which it occurred - @see mouseUp, mouseDrag, mouseDoubleClick, contains - */ - virtual void mouseDown (const MouseEvent& event) override; - - /** Called when the mouse is moved while a button is held down. - - When a mouse button is pressed inside a component, that component - receives mouseDrag callbacks each time the mouse moves, even if the - mouse strays outside the component's bounds. - - @param event details about the position and status of the mouse event, including - the source component in which it occurred - @see mouseDown, mouseUp, mouseMove, contains, setDragRepeatInterval - */ - virtual void mouseDrag (const MouseEvent& event) override; - - /** Called when a mouse button is released. - - A mouseUp callback is sent to the component in which a button was pressed - even if the mouse is actually over a different component when the - button is released. - - The MouseEvent object passed in contains lots of methods for finding out - which buttons were down just before they were released. - - @param event details about the position and status of the mouse event, including - the source component in which it occurred - @see mouseDown, mouseDrag, mouseDoubleClick, contains - */ - virtual void mouseUp (const MouseEvent& event) override; - - /** Called when a mouse button has been double-clicked on a component. - - The MouseEvent object passed in contains lots of methods for finding out - which button was pressed, as well as which modifier keys (e.g. shift, ctrl) - were held down at the time. - - @param event details about the position and status of the mouse event, including - the source component in which it occurred - @see mouseDown, mouseUp - */ - virtual void mouseDoubleClick (const MouseEvent& event) override; - - /** Called when the mouse-wheel is moved. - - This callback is sent to the component that the mouse is over when the - wheel is moved. - - If not overridden, a component will forward this message to its parent, so - that parent components can collect mouse-wheel messages that happen to - child components which aren't interested in them. (Bear in mind that if - you attach a component as a mouse-listener to other components, then - those wheel moves will also end up calling this method and being passed up - to the parents, which may not be what you intended to happen). - - @param event details about the mouse event - @param wheel details about the mouse wheel movement - */ - virtual void mouseWheelMove (const MouseEvent& event, - const MouseWheelDetails& wheel) override; - - /** Called when a pinch-to-zoom mouse-gesture is used. - - If not overridden, a component will forward this message to its parent, so - that parent components can collect gesture messages that are unused by child - components. - - @param event details about the mouse event - @param scaleFactor a multiplier to indicate by how much the size of the target - should be changed. A value of 1.0 would indicate no change, - values greater than 1.0 mean it should be enlarged. - */ - virtual void mouseMagnify (const MouseEvent& event, float scaleFactor); - - //============================================================================== - /** Ensures that a non-stop stream of mouse-drag events will be sent during the - current mouse-drag operation. - - This allows you to make sure that mouseDrag() events are sent continuously, even - when the mouse isn't moving. This can be useful for things like auto-scrolling - components when the mouse is near an edge. - - Call this method during a mouseDown() or mouseDrag() callback, specifying the - minimum interval between consecutive mouse drag callbacks. The callbacks - will continue until the mouse is released, and then the interval will be reset, - so you need to make sure it's called every time you begin a drag event. - Passing an interval of 0 or less will cancel the auto-repeat. - - @see mouseDrag, Desktop::beginDragAutoRepeat - */ - static void JUCE_CALLTYPE beginDragAutoRepeat (int millisecondsBetweenCallbacks); - - /** Causes automatic repaints when the mouse enters or exits this component. - - If turned on, then when the mouse enters/exits, or when the button is pressed/released - on the component, it will trigger a repaint. - - This is handy for things like buttons that need to draw themselves differently when - the mouse moves over them, and it avoids having to override all the different mouse - callbacks and call repaint(). - - @see mouseEnter, mouseExit, mouseDown, mouseUp - */ - void setRepaintsOnMouseActivity (bool shouldRepaint) noexcept; - - /** Registers a listener to be told when mouse events occur in this component. - - If you need to get informed about mouse events in a component but can't or - don't want to override its methods, you can attach any number of listeners - to the component, and these will get told about the events in addition to - the component's own callbacks being called. - - Note that a MouseListener can also be attached to more than one component. - - @param newListener the listener to register - @param wantsEventsForAllNestedChildComponents if true, the listener will receive callbacks - for events that happen to any child component - within this component, including deeply-nested - child components. If false, it will only be - told about events that this component handles. - @see MouseListener, removeMouseListener - */ - void addMouseListener (MouseListener* newListener, - bool wantsEventsForAllNestedChildComponents); - - /** Deregisters a mouse listener. - @see addMouseListener, MouseListener - */ - void removeMouseListener (MouseListener* listenerToRemove); - - //============================================================================== - /** Adds a listener that wants to hear about keypresses that this component receives. - - The listeners that are registered with a component are called by its keyPressed() or - keyStateChanged() methods (assuming these haven't been overridden to do something else). - - If you add an object as a key listener, be careful to remove it when the object - is deleted, or the component will be left with a dangling pointer. - - @see keyPressed, keyStateChanged, removeKeyListener - */ - void addKeyListener (KeyListener* newListener); - - /** Removes a previously-registered key listener. - @see addKeyListener - */ - void removeKeyListener (KeyListener* listenerToRemove); - - /** Called when a key is pressed. - - When a key is pressed, the component that has the keyboard focus will have this - method called. Remember that a component will only be given the focus if its - setWantsKeyboardFocus() method has been used to enable this. - - If your implementation returns true, the event will be consumed and not passed - on to any other listeners. If it returns false, the key will be passed to any - KeyListeners that have been registered with this component. As soon as one of these - returns true, the process will stop, but if they all return false, the event will - be passed upwards to this component's parent, and so on. - - The default implementation of this method does nothing and returns false. - - @see keyStateChanged, getCurrentlyFocusedComponent, addKeyListener - */ - virtual bool keyPressed (const KeyPress& key); - - /** Called when a key is pressed or released. - - Whenever a key on the keyboard is pressed or released (including modifier keys - like shift and ctrl), this method will be called on the component that currently - has the keyboard focus. Remember that a component will only be given the focus if - its setWantsKeyboardFocus() method has been used to enable this. - - If your implementation returns true, the event will be consumed and not passed - on to any other listeners. If it returns false, then any KeyListeners that have - been registered with this component will have their keyStateChanged methods called. - As soon as one of these returns true, the process will stop, but if they all return - false, the event will be passed upwards to this component's parent, and so on. - - The default implementation of this method does nothing and returns false. - - To find out which keys are up or down at any time, see the KeyPress::isKeyCurrentlyDown() - method. - - @param isKeyDown true if a key has been pressed; false if it has been released - - @see keyPressed, KeyPress, getCurrentlyFocusedComponent, addKeyListener - */ - virtual bool keyStateChanged (bool isKeyDown); - - /** Called when a modifier key is pressed or released. - - Whenever the shift, control, alt or command keys are pressed or released, - this method will be called on the component that currently has the keyboard focus. - Remember that a component will only be given the focus if its setWantsKeyboardFocus() - method has been used to enable this. - - The default implementation of this method actually calls its parent's modifierKeysChanged - method, so that focused components which aren't interested in this will give their - parents a chance to act on the event instead. - - @see keyStateChanged, ModifierKeys - */ - virtual void modifierKeysChanged (const ModifierKeys& modifiers); - - //============================================================================== - /** Enumeration used by the focusChanged() and focusLost() methods. */ - enum FocusChangeType - { - focusChangedByMouseClick, /**< Means that the user clicked the mouse to change focus. */ - focusChangedByTabKey, /**< Means that the user pressed the tab key to move the focus. */ - focusChangedDirectly /**< Means that the focus was changed by a call to grabKeyboardFocus(). */ - }; - - /** Called to indicate that this component has just acquired the keyboard focus. - @see focusLost, setWantsKeyboardFocus, getCurrentlyFocusedComponent, hasKeyboardFocus - */ - virtual void focusGained (FocusChangeType cause); - - /** Called to indicate that this component has just lost the keyboard focus. - @see focusGained, setWantsKeyboardFocus, getCurrentlyFocusedComponent, hasKeyboardFocus - */ - virtual void focusLost (FocusChangeType cause); - - /** Called to indicate a change in whether or not this component is the parent of the - currently-focused component. - - Essentially this is called when the return value of a call to hasKeyboardFocus (true) has - changed. It happens when focus moves from one of this component's children (at any depth) - to a component that isn't contained in this one, (or vice-versa). - Note that this method does NOT get called to when focus simply moves from one of its - child components to another. - - @see focusGained, setWantsKeyboardFocus, getCurrentlyFocusedComponent, hasKeyboardFocus - */ - virtual void focusOfChildComponentChanged (FocusChangeType cause); - - //============================================================================== - /** Returns true if the mouse is currently over this component. - - If the mouse isn't over the component, this will return false, even if the - mouse is currently being dragged - so you can use this in your mouseDrag - method to find out whether it's really over the component or not. - - Note that when the mouse button is being held down, then the only component - for which this method will return true is the one that was originally - clicked on. - - If includeChildren is true, then this will also return true if the mouse is over - any of the component's children (recursively) as well as the component itself. - - @see isMouseButtonDown. isMouseOverOrDragging, mouseDrag - */ - bool isMouseOver (bool includeChildren = false) const; - - /** Returns true if the mouse button is currently held down in this component. - - Note that this is a test to see whether the mouse is being pressed in this - component, so it'll return false if called on component A when the mouse - is actually being dragged in component B. - - @see isMouseButtonDownAnywhere, isMouseOver, isMouseOverOrDragging - */ - bool isMouseButtonDown() const; - - /** True if the mouse is over this component, or if it's being dragged in this component. - This is a handy equivalent to (isMouseOver() || isMouseButtonDown()). - @see isMouseOver, isMouseButtonDown, isMouseButtonDownAnywhere - */ - bool isMouseOverOrDragging() const; - - /** Returns true if a mouse button is currently down. - - Unlike isMouseButtonDown, this will test the current state of the - buttons without regard to which component (if any) it has been - pressed in. - - @see isMouseButtonDown, ModifierKeys - */ - static bool JUCE_CALLTYPE isMouseButtonDownAnywhere() noexcept; - - /** Returns the mouse's current position, relative to this component. - The return value is relative to the component's top-left corner. - */ - Point getMouseXYRelative() const; - - //============================================================================== - /** Called when this component's size has been changed. - - A component can implement this method to do things such as laying out its - child components when its width or height changes. - - The method is called synchronously as a result of the setBounds or setSize - methods, so repeatedly changing a components size will repeatedly call its - resized method (unlike things like repainting, where multiple calls to repaint - are coalesced together). - - If the component is a top-level window on the desktop, its size could also - be changed by operating-system factors beyond the application's control. - - @see moved, setSize - */ - virtual void resized(); - - /** Called when this component's position has been changed. - - This is called when the position relative to its parent changes, not when - its absolute position on the screen changes (so it won't be called for - all child components when a parent component is moved). - - The method is called synchronously as a result of the setBounds, setTopLeftPosition - or any of the other repositioning methods, and like resized(), it will be - called each time those methods are called. - - If the component is a top-level window on the desktop, its position could also - be changed by operating-system factors beyond the application's control. - - @see resized, setBounds - */ - virtual void moved(); - - /** Called when one of this component's children is moved or resized. - - If the parent wants to know about changes to its immediate children (not - to children of its children), this is the method to override. - - @see moved, resized, parentSizeChanged - */ - virtual void childBoundsChanged (Component* child); - - /** Called when this component's immediate parent has been resized. - - If the component is a top-level window, this indicates that the screen size - has changed. - - @see childBoundsChanged, moved, resized - */ - virtual void parentSizeChanged(); - - /** Called when this component has been moved to the front of its siblings. - - The component may have been brought to the front by the toFront() method, or - by the operating system if it's a top-level window. - - @see toFront - */ - virtual void broughtToFront(); - - /** Adds a listener to be told about changes to the component hierarchy or position. - - Component listeners get called when this component's size, position or children - change - see the ComponentListener class for more details. - - @param newListener the listener to register - if this is already registered, it - will be ignored. - @see ComponentListener, removeComponentListener - */ - void addComponentListener (ComponentListener* newListener); - - /** Removes a component listener. - @see addComponentListener - */ - void removeComponentListener (ComponentListener* listenerToRemove); - - //============================================================================== - /** Dispatches a numbered message to this component. - - This is a quick and cheap way of allowing simple asynchronous messages to - be sent to components. It's also safe, because if the component that you - send the message to is a null or dangling pointer, this won't cause an error. - - The command ID is later delivered to the component's handleCommandMessage() method by - the application's message queue. - - @see handleCommandMessage - */ - void postCommandMessage (int commandId); - - /** Called to handle a command that was sent by postCommandMessage(). - - This is called by the message thread when a command message arrives, and - the component can override this method to process it in any way it needs to. - - @see postCommandMessage - */ - virtual void handleCommandMessage (int commandId); - - //============================================================================== - /** Runs a component modally, waiting until the loop terminates. - - This method first makes the component visible, brings it to the front and - gives it the keyboard focus. - - It then runs a loop, dispatching messages from the system message queue, but - blocking all mouse or keyboard messages from reaching any components other - than this one and its children. - - This loop continues until the component's exitModalState() method is called (or - the component is deleted), and then this method returns, returning the value - passed into exitModalState(). - - @see enterModalState, exitModalState, isCurrentlyModal, getCurrentlyModalComponent, - isCurrentlyBlockedByAnotherModalComponent, ModalComponentManager - */ - #if JUCE_MODAL_LOOPS_PERMITTED - int runModalLoop(); - #endif - - /** Puts the component into a modal state. - - This makes the component modal, so that messages are blocked from reaching - any components other than this one and its children, but unlike runModalLoop(), - this method returns immediately. - - If takeKeyboardFocus is true, the component will use grabKeyboardFocus() to - get the focus, which is usually what you'll want it to do. If not, it will leave - the focus unchanged. - - The callback is an optional object which will receive a callback when the modal - component loses its modal status, either by being hidden or when exitModalState() - is called. If you pass an object in here, the system will take care of deleting it - later, after making the callback - - If deleteWhenDismissed is true, then when it is dismissed, the component will be - deleted and then the callback will be called. (This will safely handle the situation - where the component is deleted before its exitModalState() method is called). - - @see exitModalState, runModalLoop, ModalComponentManager::attachCallback - */ - void enterModalState (bool takeKeyboardFocus = true, - ModalComponentManager::Callback* callback = nullptr, - bool deleteWhenDismissed = false); - - /** Ends a component's modal state. - - If this component is currently modal, this will turn off its modalness, and return - a value to the runModalLoop() method that might have be running its modal loop. - - @see runModalLoop, enterModalState, isCurrentlyModal - */ - void exitModalState (int returnValue); - - /** Returns true if this component is the modal one. - - It's possible to have nested modal components, e.g. a pop-up dialog box - that launches another pop-up, but this will only return true for - the one at the top of the stack. - - @see getCurrentlyModalComponent - */ - bool isCurrentlyModal() const noexcept; - - /** Returns the number of components that are currently in a modal state. - @see getCurrentlyModalComponent - */ - static int JUCE_CALLTYPE getNumCurrentlyModalComponents() noexcept; - - /** Returns one of the components that are currently modal. - - The index specifies which of the possible modal components to return. The order - of the components in this list is the reverse of the order in which they became - modal - so the component at index 0 is always the active component, and the others - are progressively earlier ones that are themselves now blocked by later ones. - - @returns the modal component, or null if no components are modal (or if the - index is out of range) - @see getNumCurrentlyModalComponents, runModalLoop, isCurrentlyModal - */ - static Component* JUCE_CALLTYPE getCurrentlyModalComponent (int index = 0) noexcept; - - /** Checks whether there's a modal component somewhere that's stopping this one - from receiving messages. - - If there is a modal component, its canModalEventBeSentToComponent() method - will be called to see if it will still allow this component to receive events. - - @see runModalLoop, getCurrentlyModalComponent - */ - bool isCurrentlyBlockedByAnotherModalComponent() const; - - /** When a component is modal, this callback allows it to choose which other - components can still receive events. - - When a modal component is active and the user clicks on a non-modal component, - this method is called on the modal component, and if it returns true, the - event is allowed to reach its target. If it returns false, the event is blocked - and the inputAttemptWhenModal() callback is made. - - It called by the isCurrentlyBlockedByAnotherModalComponent() method. The default - implementation just returns false in all cases. - */ - virtual bool canModalEventBeSentToComponent (const Component* targetComponent); - - /** Called when the user tries to click on a component that is blocked by another - modal component. - - When a component is modal and the user clicks on one of the other components, - the modal component will receive this callback. - - The default implementation of this method will play a beep, and bring the currently - modal component to the front, but it can be overridden to do other tasks. - - @see isCurrentlyBlockedByAnotherModalComponent, canModalEventBeSentToComponent - */ - virtual void inputAttemptWhenModal(); - - - //============================================================================== - /** Returns the set of properties that belong to this component. - Each component has a NamedValueSet object which you can use to attach arbitrary - items of data to it. - */ - NamedValueSet& getProperties() noexcept { return properties; } - - /** Returns the set of properties that belong to this component. - Each component has a NamedValueSet object which you can use to attach arbitrary - items of data to it. - */ - const NamedValueSet& getProperties() const noexcept { return properties; } - - //============================================================================== - /** Looks for a colour that has been registered with the given colour ID number. - - If a colour has been set for this ID number using setColour(), then it is - returned. If none has been set, the method will try calling the component's - LookAndFeel class's findColour() method. If none has been registered with the - look-and-feel either, it will just return black. - - The colour IDs for various purposes are stored as enums in the components that - they are relevent to - for an example, see Slider::ColourIds, - Label::ColourIds, TextEditor::ColourIds, TreeView::ColourIds, etc. - - @see setColour, isColourSpecified, colourChanged, LookAndFeel::findColour, LookAndFeel::setColour - */ - Colour findColour (int colourId, bool inheritFromParent = false) const; - - /** Registers a colour to be used for a particular purpose. - - Changing a colour will cause a synchronous callback to the colourChanged() - method, which your component can override if it needs to do something when - colours are altered. - - For more details about colour IDs, see the comments for findColour(). - - @see findColour, isColourSpecified, colourChanged, LookAndFeel::findColour, LookAndFeel::setColour - */ - void setColour (int colourId, Colour newColour); - - /** If a colour has been set with setColour(), this will remove it. - This allows you to make a colour revert to its default state. - */ - void removeColour (int colourId); - - /** Returns true if the specified colour ID has been explicitly set for this - component using the setColour() method. - */ - bool isColourSpecified (int colourId) const; - - /** This looks for any colours that have been specified for this component, - and copies them to the specified target component. - */ - void copyAllExplicitColoursTo (Component& target) const; - - /** This method is called when a colour is changed by the setColour() method. - @see setColour, findColour - */ - virtual void colourChanged(); - - //============================================================================== - /** Components can implement this method to provide a MarkerList. - The default implementation of this method returns nullptr, but you can override - it to return a pointer to the component's marker list. If xAxis is true, it should - return the X marker list; if false, it should return the Y markers. - */ - virtual MarkerList* getMarkers (bool xAxis); - - //============================================================================== - /** Returns the underlying native window handle for this component. - - This is platform-dependent and strictly for power-users only! - */ - void* getWindowHandle() const; - - //============================================================================== - /** Holds a pointer to some type of Component, which automatically becomes null if - the component is deleted. - - If you're using a component which may be deleted by another event that's outside - of your control, use a SafePointer instead of a normal pointer to refer to it, - and you can test whether it's null before using it to see if something has deleted - it. - - The ComponentType typedef must be Component, or some subclass of Component. - - You may also want to use a WeakReference object for the same purpose. - */ - template - class SafePointer - { - public: - /** Creates a null SafePointer. */ - SafePointer() noexcept {} - - /** Creates a SafePointer that points at the given component. */ - SafePointer (ComponentType* component) : weakRef (component) {} - - /** Creates a copy of another SafePointer. */ - SafePointer (const SafePointer& other) noexcept : weakRef (other.weakRef) {} - - /** Copies another pointer to this one. */ - SafePointer& operator= (const SafePointer& other) { weakRef = other.weakRef; return *this; } - - /** Copies another pointer to this one. */ - SafePointer& operator= (ComponentType* newComponent) { weakRef = newComponent; return *this; } - - /** Returns the component that this pointer refers to, or null if the component no longer exists. */ - ComponentType* getComponent() const noexcept { return dynamic_cast (weakRef.get()); } - - /** Returns the component that this pointer refers to, or null if the component no longer exists. */ - operator ComponentType*() const noexcept { return getComponent(); } - - /** Returns the component that this pointer refers to, or null if the component no longer exists. */ - ComponentType* operator->() noexcept { return getComponent(); } - - /** Returns the component that this pointer refers to, or null if the component no longer exists. */ - const ComponentType* operator->() const noexcept { return getComponent(); } - - /** If the component is valid, this deletes it and sets this pointer to null. */ - void deleteAndZero() { delete getComponent(); } - - bool operator== (ComponentType* component) const noexcept { return weakRef == component; } - bool operator!= (ComponentType* component) const noexcept { return weakRef != component; } - - private: - WeakReference weakRef; - }; - - //============================================================================== - /** A class to keep an eye on a component and check for it being deleted. - - This is designed for use with the ListenerList::callChecked() methods, to allow - the list iterator to stop cleanly if the component is deleted by a listener callback - while the list is still being iterated. - */ - class JUCE_API BailOutChecker - { - public: - /** Creates a checker that watches one component. */ - BailOutChecker (Component* component); - - /** Returns true if either of the two components have been deleted since this object was created. */ - bool shouldBailOut() const noexcept; - - private: - const WeakReference safePointer; - - JUCE_DECLARE_NON_COPYABLE (BailOutChecker) - }; - - //============================================================================== - /** - Base class for objects that can be used to automatically position a component according to - some kind of algorithm. - - The component class simply holds onto a reference to a Positioner, but doesn't actually do - anything with it - all the functionality must be implemented by the positioner itself (e.g. - it might choose to watch some kind of value and move the component when the value changes). - */ - class JUCE_API Positioner - { - public: - /** Creates a Positioner which can control the specified component. */ - explicit Positioner (Component& component) noexcept; - /** Destructor. */ - virtual ~Positioner() {} - - /** Returns the component that this positioner controls. */ - Component& getComponent() const noexcept { return component; } - - /** Attempts to set the component's position to the given rectangle. - Unlike simply calling Component::setBounds(), this may involve the positioner - being smart enough to adjust itself to fit the new bounds, e.g. a RelativeRectangle's - positioner may try to reverse the expressions used to make them fit these new coordinates. - */ - virtual void applyNewBounds (const Rectangle& newBounds) = 0; - - private: - Component& component; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Positioner) - }; - - /** Returns the Positioner object that has been set for this component. - @see setPositioner() - */ - Positioner* getPositioner() const noexcept; - - /** Sets a new Positioner object for this component. - If there's currently another positioner set, it will be deleted. The object that is passed in - will be deleted automatically by this component when it's no longer required. Pass a null pointer - to clear the current positioner. - @see getPositioner() - */ - void setPositioner (Positioner* newPositioner); - - /** Gives the component a CachedComponentImage that should be used to buffer its painting. - The object that is passed-in will be owned by this component, and will be deleted automatically - later on. - @see setBufferedToImage - */ - void setCachedComponentImage (CachedComponentImage* newCachedImage); - - /** Returns the object that was set by setCachedComponentImage(). - @see setCachedComponentImage - */ - CachedComponentImage* getCachedComponentImage() const noexcept { return cachedImage; } - - //============================================================================== - // These methods are deprecated - use localPointToGlobal, getLocalPoint, getLocalPoint, etc instead. - JUCE_DEPRECATED (Point relativePositionToGlobal (Point) const); - JUCE_DEPRECATED (Point globalPositionToRelative (Point) const); - JUCE_DEPRECATED (Point relativePositionToOtherComponent (const Component*, Point) const); - -private: - //============================================================================== - friend class ComponentPeer; - friend class MouseInputSource; - friend class MouseInputSourceInternal; - - #ifndef DOXYGEN - static Component* currentlyFocusedComponent; - - //============================================================================== - String componentName, componentID; - Component* parentComponent; - Rectangle bounds; - ScopedPointer positioner; - ScopedPointer affineTransform; - Array childComponentList; - LookAndFeel* lookAndFeel; - MouseCursor cursor; - ImageEffectFilter* effect; - ScopedPointer cachedImage; - - class MouseListenerList; - friend class MouseListenerList; - friend struct ContainerDeletePolicy; - ScopedPointer mouseListeners; - ScopedPointer > keyListeners; - ListenerList componentListeners; - NamedValueSet properties; - - friend class WeakReference; - WeakReference::Master masterReference; - - struct ComponentFlags - { - bool hasHeavyweightPeerFlag : 1; - bool visibleFlag : 1; - bool opaqueFlag : 1; - bool ignoresMouseClicksFlag : 1; - bool allowChildMouseClicksFlag : 1; - bool wantsFocusFlag : 1; - bool isFocusContainerFlag : 1; - bool dontFocusOnMouseClickFlag : 1; - bool alwaysOnTopFlag : 1; - bool bufferToImageFlag : 1; - bool bringToFrontOnClickFlag : 1; - bool repaintOnMouseActivityFlag : 1; - bool currentlyModalFlag : 1; - bool isDisabledFlag : 1; - bool childCompFocusedFlag : 1; - bool dontClipGraphicsFlag : 1; - bool mouseDownWasBlocked : 1; - bool isMoveCallbackPending : 1; - bool isResizeCallbackPending : 1; - #if JUCE_DEBUG - bool isInsidePaintCall : 1; - #endif - }; - - union - { - uint32 componentFlags; - ComponentFlags flags; - }; - - uint8 componentTransparency; - - //============================================================================== - void internalMouseEnter (MouseInputSource, Point, Time); - void internalMouseExit (MouseInputSource, Point, Time); - void internalMouseDown (MouseInputSource, Point, Time); - void internalMouseUp (MouseInputSource, Point, Time, const ModifierKeys oldModifiers); - void internalMouseDrag (MouseInputSource, Point, Time); - void internalMouseMove (MouseInputSource, Point, Time); - void internalMouseWheel (MouseInputSource, Point, Time, const MouseWheelDetails&); - void internalMagnifyGesture (MouseInputSource, Point, Time, float); - void internalBroughtToFront(); - void internalFocusGain (FocusChangeType, const WeakReference&); - void internalFocusGain (FocusChangeType); - void internalFocusLoss (FocusChangeType); - void internalChildFocusChange (FocusChangeType, const WeakReference&); - void internalModalInputAttempt(); - void internalModifierKeysChanged(); - void internalChildrenChanged(); - void internalHierarchyChanged(); - void internalRepaint (const Rectangle&); - void internalRepaintUnchecked (const Rectangle&, bool); - Component* removeChildComponent (int index, bool sendParentEvents, bool sendChildEvents); - void reorderChildInternal (int sourceIndex, int destIndex); - void paintComponentAndChildren (Graphics&); - void paintWithinParentContext (Graphics&); - void sendMovedResizedMessages (bool wasMoved, bool wasResized); - void sendMovedResizedMessagesIfPending(); - void repaintParent(); - void sendFakeMouseMove() const; - void takeKeyboardFocus (const FocusChangeType); - void grabFocusInternal (const FocusChangeType, bool canTryParent); - static void giveAwayFocus (bool sendFocusLossEvent); - void sendEnablementChangeMessage(); - void sendVisibilityChangeMessage(); - - struct ComponentHelpers; - friend struct ComponentHelpers; - - /* Components aren't allowed to have copy constructors, as this would mess up parent hierarchies. - You might need to give your subclasses a private dummy constructor to avoid compiler warnings. - */ - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Component) - - //============================================================================== - #if JUCE_CATCH_DEPRECATED_CODE_MISUSE - // This is included here just to cause a compile error if your code is still handling - // drag-and-drop with this method. If so, just update it to use the new FileDragAndDropTarget - // class, which is easy (just make your class inherit from FileDragAndDropTarget, and - // implement its methods instead of this Component method). - virtual void filesDropped (const StringArray&, int, int) {} - - // This is included here to cause an error if you use or overload it - it has been deprecated in - // favour of contains (Point) - void contains (int, int) JUCE_DELETED_FUNCTION; - #endif - -protected: - //============================================================================== - /** @internal */ - virtual ComponentPeer* createNewPeer (int styleFlags, void* nativeWindowToAttachTo); - #endif -}; - - -#endif // JUCE_COMPONENT_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/components/juce_ComponentListener.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/components/juce_ComponentListener.cpp deleted file mode 100644 index 3e5cd35ebf..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/components/juce_ComponentListener.cpp +++ /dev/null @@ -1,31 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -void ComponentListener::componentMovedOrResized (Component&, bool, bool) {} -void ComponentListener::componentBroughtToFront (Component&) {} -void ComponentListener::componentVisibilityChanged (Component&) {} -void ComponentListener::componentChildrenChanged (Component&) {} -void ComponentListener::componentParentHierarchyChanged (Component&) {} -void ComponentListener::componentNameChanged (Component&) {} -void ComponentListener::componentBeingDeleted (Component&) {} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/components/juce_ComponentListener.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/components/juce_ComponentListener.h deleted file mode 100644 index 56c06311b8..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/components/juce_ComponentListener.h +++ /dev/null @@ -1,111 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_COMPONENTLISTENER_H_INCLUDED -#define JUCE_COMPONENTLISTENER_H_INCLUDED - - -//============================================================================== -/** - Gets informed about changes to a component's hierarchy or position. - - To monitor a component for changes, register a subclass of ComponentListener - with the component using Component::addComponentListener(). - - Be sure to deregister listeners before you delete them! - - @see Component::addComponentListener, Component::removeComponentListener -*/ -class JUCE_API ComponentListener -{ -public: - /** Destructor. */ - virtual ~ComponentListener() {} - - /** Called when the component's position or size changes. - - @param component the component that was moved or resized - @param wasMoved true if the component's top-left corner has just moved - @param wasResized true if the component's width or height has just changed - @see Component::setBounds, Component::resized, Component::moved - */ - virtual void componentMovedOrResized (Component& component, - bool wasMoved, - bool wasResized); - - /** Called when the component is brought to the top of the z-order. - - @param component the component that was moved - @see Component::toFront, Component::broughtToFront - */ - virtual void componentBroughtToFront (Component& component); - - /** Called when the component is made visible or invisible. - - @param component the component that changed - @see Component::setVisible - */ - virtual void componentVisibilityChanged (Component& component); - - /** Called when the component has children added or removed, or their z-order - changes. - - @param component the component whose children have changed - @see Component::childrenChanged, Component::addChildComponent, - Component::removeChildComponent - */ - virtual void componentChildrenChanged (Component& component); - - /** Called to indicate that the component's parents have changed. - - When a component is added or removed from its parent, all of its children - will produce this notification (recursively - so all children of its - children will also be called as well). - - @param component the component that this listener is registered with - @see Component::parentHierarchyChanged - */ - virtual void componentParentHierarchyChanged (Component& component); - - /** Called when the component's name is changed. - - @see Component::setName, Component::getName - */ - virtual void componentNameChanged (Component& component); - - /** Called when the component is in the process of being deleted. - - This callback is made from inside the destructor, so be very, very cautious - about what you do in here. - - In particular, bear in mind that it's the Component base class's destructor that calls - this - so if the object that's being deleted is a subclass of Component, then the - subclass layers of the object will already have been destructed when it gets to this - point! - */ - virtual void componentBeingDeleted (Component& component); -}; - - -#endif // JUCE_COMPONENTLISTENER_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/components/juce_Desktop.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/components/juce_Desktop.cpp deleted file mode 100644 index bb77371eff..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/components/juce_Desktop.cpp +++ /dev/null @@ -1,415 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -Desktop::Desktop() - : mouseSources (new MouseInputSource::SourceList()), - mouseClickCounter (0), mouseWheelCounter (0), - kioskModeComponent (nullptr), - kioskModeReentrant (false), - allowedOrientations (allOrientations), - masterScaleFactor ((float) getDefaultMasterScale()) -{ - displays = new Displays (*this); -} - -Desktop::~Desktop() -{ - setScreenSaverEnabled (true); - - jassert (instance == this); - instance = nullptr; - - // doh! If you don't delete all your windows before exiting, you're going to - // be leaking memory! - jassert (desktopComponents.size() == 0); -} - -Desktop& JUCE_CALLTYPE Desktop::getInstance() -{ - if (instance == nullptr) - instance = new Desktop(); - - return *instance; -} - -Desktop* Desktop::instance = nullptr; - -//============================================================================== -int Desktop::getNumComponents() const noexcept -{ - return desktopComponents.size(); -} - -Component* Desktop::getComponent (const int index) const noexcept -{ - return desktopComponents [index]; -} - -Component* Desktop::findComponentAt (Point screenPosition) const -{ - ASSERT_MESSAGE_MANAGER_IS_LOCKED - - for (int i = desktopComponents.size(); --i >= 0;) - { - Component* const c = desktopComponents.getUnchecked(i); - - if (c->isVisible()) - { - const Point relative (c->getLocalPoint (nullptr, screenPosition)); - - if (c->contains (relative)) - return c->getComponentAt (relative); - } - } - - return nullptr; -} - -//============================================================================== -LookAndFeel& Desktop::getDefaultLookAndFeel() noexcept -{ - if (currentLookAndFeel == nullptr) - { - if (defaultLookAndFeel == nullptr) - defaultLookAndFeel = new LookAndFeel_V2(); - - currentLookAndFeel = defaultLookAndFeel; - } - - return *currentLookAndFeel; -} - -void Desktop::setDefaultLookAndFeel (LookAndFeel* newDefaultLookAndFeel) -{ - ASSERT_MESSAGE_MANAGER_IS_LOCKED - currentLookAndFeel = newDefaultLookAndFeel; - - for (int i = getNumComponents(); --i >= 0;) - if (Component* const c = getComponent (i)) - c->sendLookAndFeelChange(); -} - -//============================================================================== -void Desktop::addDesktopComponent (Component* const c) -{ - jassert (c != nullptr); - jassert (! desktopComponents.contains (c)); - desktopComponents.addIfNotAlreadyThere (c); -} - -void Desktop::removeDesktopComponent (Component* const c) -{ - desktopComponents.removeFirstMatchingValue (c); -} - -void Desktop::componentBroughtToFront (Component* const c) -{ - const int index = desktopComponents.indexOf (c); - jassert (index >= 0); - - if (index >= 0) - { - int newIndex = -1; - - if (! c->isAlwaysOnTop()) - { - newIndex = desktopComponents.size(); - - while (newIndex > 0 && desktopComponents.getUnchecked (newIndex - 1)->isAlwaysOnTop()) - --newIndex; - - --newIndex; - } - - desktopComponents.move (index, newIndex); - } -} - -//============================================================================== -Point Desktop::getMousePosition() -{ - return getMousePositionFloat().roundToInt(); -} - -Point Desktop::getMousePositionFloat() -{ - return getInstance().getMainMouseSource().getScreenPosition(); -} - -void Desktop::setMousePosition (Point newPosition) -{ - getInstance().getMainMouseSource().setScreenPosition (newPosition.toFloat()); -} - -Point Desktop::getLastMouseDownPosition() -{ - return getInstance().getMainMouseSource().getLastMouseDownPosition().roundToInt(); -} - -int Desktop::getMouseButtonClickCounter() const noexcept { return mouseClickCounter; } -int Desktop::getMouseWheelMoveCounter() const noexcept { return mouseWheelCounter; } - -void Desktop::incrementMouseClickCounter() noexcept { ++mouseClickCounter; } -void Desktop::incrementMouseWheelCounter() noexcept { ++mouseWheelCounter; } - -const Array& Desktop::getMouseSources() const noexcept { return mouseSources->sourceArray; } -int Desktop::getNumMouseSources() const noexcept { return mouseSources->sources.size(); } -int Desktop::getNumDraggingMouseSources() const noexcept { return mouseSources->getNumDraggingMouseSources(); } -MouseInputSource* Desktop::getMouseSource (int index) const noexcept { return mouseSources->getMouseSource (index); } -MouseInputSource* Desktop::getDraggingMouseSource (int index) const noexcept { return mouseSources->getDraggingMouseSource (index); } -MouseInputSource Desktop::getMainMouseSource() const noexcept { return MouseInputSource (mouseSources->sources.getUnchecked(0)); } -void Desktop::beginDragAutoRepeat (int interval) { mouseSources->beginDragAutoRepeat (interval); } - -//============================================================================== -void Desktop::addFocusChangeListener (FocusChangeListener* const listener) { focusListeners.add (listener); } -void Desktop::removeFocusChangeListener (FocusChangeListener* const listener) { focusListeners.remove (listener); } -void Desktop::triggerFocusCallback() { triggerAsyncUpdate(); } - -void Desktop::handleAsyncUpdate() -{ - // The component may be deleted during this operation, but we'll use a SafePointer rather than a - // BailOutChecker so that any remaining listeners will still get a callback (with a null pointer). - WeakReference currentFocus (Component::getCurrentlyFocusedComponent()); - focusListeners.call (&FocusChangeListener::globalFocusChanged, currentFocus); -} - -//============================================================================== -void Desktop::resetTimer() -{ - if (mouseListeners.size() == 0) - stopTimer(); - else - startTimer (100); - - lastFakeMouseMove = getMousePositionFloat(); -} - -ListenerList& Desktop::getMouseListeners() -{ - resetTimer(); - return mouseListeners; -} - -void Desktop::addGlobalMouseListener (MouseListener* const listener) -{ - ASSERT_MESSAGE_MANAGER_IS_LOCKED - mouseListeners.add (listener); - resetTimer(); -} - -void Desktop::removeGlobalMouseListener (MouseListener* const listener) -{ - ASSERT_MESSAGE_MANAGER_IS_LOCKED - mouseListeners.remove (listener); - resetTimer(); -} - -void Desktop::timerCallback() -{ - if (lastFakeMouseMove != getMousePositionFloat()) - sendMouseMove(); -} - -void Desktop::sendMouseMove() -{ - if (! mouseListeners.isEmpty()) - { - startTimer (20); - - lastFakeMouseMove = getMousePositionFloat(); - - if (Component* const target = findComponentAt (lastFakeMouseMove.roundToInt())) - { - Component::BailOutChecker checker (target); - const Point pos (target->getLocalPoint (nullptr, lastFakeMouseMove)); - const Time now (Time::getCurrentTime()); - - const MouseEvent me (getMainMouseSource(), pos, ModifierKeys::getCurrentModifiers(), - target, target, now, pos, now, 0, false); - - if (me.mods.isAnyMouseButtonDown()) - mouseListeners.callChecked (checker, &MouseListener::mouseDrag, me); - else - mouseListeners.callChecked (checker, &MouseListener::mouseMove, me); - } - } -} - - -//============================================================================== -Desktop::Displays::Displays (Desktop& desktop) { init (desktop); } -Desktop::Displays::~Displays() {} - -const Desktop::Displays::Display& Desktop::Displays::getMainDisplay() const noexcept -{ - ASSERT_MESSAGE_MANAGER_IS_LOCKED - jassert (displays.getReference(0).isMain); - return displays.getReference(0); -} - -const Desktop::Displays::Display& Desktop::Displays::getDisplayContaining (Point position) const noexcept -{ - ASSERT_MESSAGE_MANAGER_IS_LOCKED - const Display* best = &displays.getReference(0); - double bestDistance = 1.0e10; - - for (int i = displays.size(); --i >= 0;) - { - const Display& d = displays.getReference(i); - - if (d.totalArea.contains (position)) - { - best = &d; - break; - } - - const double distance = d.totalArea.getCentre().getDistanceFrom (position); - - if (distance < bestDistance) - { - bestDistance = distance; - best = &d; - } - } - - return *best; -} - -RectangleList Desktop::Displays::getRectangleList (bool userAreasOnly) const -{ - ASSERT_MESSAGE_MANAGER_IS_LOCKED - RectangleList rl; - - for (int i = 0; i < displays.size(); ++i) - { - const Display& d = displays.getReference(i); - rl.addWithoutMerging (userAreasOnly ? d.userArea : d.totalArea); - } - - return rl; -} - -Rectangle Desktop::Displays::getTotalBounds (bool userAreasOnly) const -{ - return getRectangleList (userAreasOnly).getBounds(); -} - -bool operator== (const Desktop::Displays::Display& d1, const Desktop::Displays::Display& d2) noexcept; -bool operator== (const Desktop::Displays::Display& d1, const Desktop::Displays::Display& d2) noexcept -{ - return d1.userArea == d2.userArea - && d1.totalArea == d2.totalArea - && d1.scale == d2.scale - && d1.isMain == d2.isMain; -} - -bool operator!= (const Desktop::Displays::Display& d1, const Desktop::Displays::Display& d2) noexcept; -bool operator!= (const Desktop::Displays::Display& d1, const Desktop::Displays::Display& d2) noexcept -{ - return ! (d1 == d2); -} - -void Desktop::Displays::init (Desktop& desktop) -{ - findDisplays (desktop.getGlobalScaleFactor()); - jassert (displays.size() > 0); -} - -void Desktop::Displays::refresh() -{ - Array oldDisplays; - oldDisplays.swapWith (displays); - - init (Desktop::getInstance()); - jassert (displays.size() > 0); - - if (oldDisplays != displays) - { - for (int i = ComponentPeer::getNumPeers(); --i >= 0;) - if (ComponentPeer* const peer = ComponentPeer::getPeer (i)) - peer->handleScreenSizeChange(); - } -} - -//============================================================================== -void Desktop::setKioskModeComponent (Component* componentToUse, const bool allowMenusAndBars) -{ - if (kioskModeReentrant) - return; - - const ScopedValueSetter setter (kioskModeReentrant, true, false); - - if (kioskModeComponent != componentToUse) - { - // agh! Don't delete or remove a component from the desktop while it's still the kiosk component! - jassert (kioskModeComponent == nullptr || ComponentPeer::getPeerFor (kioskModeComponent) != nullptr); - - if (Component* const oldKioskComp = kioskModeComponent) - { - kioskModeComponent = nullptr; // (to make sure that isKioskMode() returns false when resizing the old one) - setKioskComponent (oldKioskComp, false, allowMenusAndBars); - oldKioskComp->setBounds (kioskComponentOriginalBounds); - } - - kioskModeComponent = componentToUse; - - if (kioskModeComponent != nullptr) - { - // Only components that are already on the desktop can be put into kiosk mode! - jassert (ComponentPeer::getPeerFor (kioskModeComponent) != nullptr); - - kioskComponentOriginalBounds = kioskModeComponent->getBounds(); - setKioskComponent (kioskModeComponent, true, allowMenusAndBars); - } - } -} - -//============================================================================== -void Desktop::setOrientationsEnabled (const int newOrientations) -{ - // Dodgy set of flags being passed here! Make sure you specify at least one permitted orientation. - jassert (newOrientations != 0 && (newOrientations & ~allOrientations) == 0); - - allowedOrientations = newOrientations; -} - -bool Desktop::isOrientationEnabled (const DisplayOrientation orientation) const noexcept -{ - // Make sure you only pass one valid flag in here... - jassert (orientation == upright || orientation == upsideDown - || orientation == rotatedClockwise || orientation == rotatedAntiClockwise); - - return (allowedOrientations & orientation) != 0; -} - -void Desktop::setGlobalScaleFactor (float newScaleFactor) noexcept -{ - ASSERT_MESSAGE_MANAGER_IS_LOCKED - - if (masterScaleFactor != newScaleFactor) - { - masterScaleFactor = newScaleFactor; - displays->refresh(); - } -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/components/juce_Desktop.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/components/juce_Desktop.h deleted file mode 100644 index 4cc33171c6..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/components/juce_Desktop.h +++ /dev/null @@ -1,460 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_DESKTOP_H_INCLUDED -#define JUCE_DESKTOP_H_INCLUDED - - -//============================================================================== -/** - Classes can implement this interface and register themselves with the Desktop class - to receive callbacks when the currently focused component changes. - - @see Desktop::addFocusChangeListener, Desktop::removeFocusChangeListener -*/ -class JUCE_API FocusChangeListener -{ -public: - /** Destructor. */ - virtual ~FocusChangeListener() {} - - /** Callback to indicate that the currently focused component has changed. */ - virtual void globalFocusChanged (Component* focusedComponent) = 0; -}; - - -//============================================================================== -/** - Describes and controls aspects of the computer's desktop. - -*/ -class JUCE_API Desktop : private DeletedAtShutdown, - private Timer, - private AsyncUpdater -{ -public: - //============================================================================== - /** There's only one desktop object, and this method will return it. */ - static Desktop& JUCE_CALLTYPE getInstance(); - - //============================================================================== - /** Returns the mouse position. - - The coordinates are relative to the top-left of the main monitor. - - Note that this is just a shortcut for calling getMainMouseSource().getScreenPosition(), and - you should only resort to grabbing the global mouse position if there's really no - way to get the coordinates via a mouse event callback instead. - */ - static Point getMousePosition(); - - /** Makes the mouse pointer jump to a given location. - The coordinates are relative to the top-left of the main monitor. - */ - static void setMousePosition (Point newPosition); - - /** Returns the last position at which a mouse button was pressed. - - Note that this is just a shortcut for calling getMainMouseSource().getLastMouseDownPosition(), - and in a multi-touch environment, it doesn't make much sense. ALWAYS prefer to - get this information via other means, such as MouseEvent::getMouseDownScreenPosition() - if possible, and only ever call this as a last resort. - */ - static Point getLastMouseDownPosition(); - - /** Returns the number of times the mouse button has been clicked since the app started. - Each mouse-down event increments this number by 1. - @see getMouseWheelMoveCounter - */ - int getMouseButtonClickCounter() const noexcept; - - /** Returns the number of times the mouse wheel has been moved since the app started. - Each mouse-wheel event increments this number by 1. - @see getMouseButtonClickCounter - */ - int getMouseWheelMoveCounter() const noexcept; - - //============================================================================== - /** This lets you prevent the screensaver from becoming active. - - Handy if you're running some sort of presentation app where having a screensaver - appear would be annoying. - - Pass false to disable the screensaver, and true to re-enable it. (Note that this - won't enable a screensaver unless the user has actually set one up). - - The disablement will only happen while the Juce application is the foreground - process - if another task is running in front of it, then the screensaver will - be unaffected. - - @see isScreenSaverEnabled - */ - static void setScreenSaverEnabled (bool isEnabled); - - /** Returns true if the screensaver has not been turned off. - - This will return the last value passed into setScreenSaverEnabled(). Note that - it won't tell you whether the user is actually using a screen saver, just - whether this app is deliberately preventing one from running. - - @see setScreenSaverEnabled - */ - static bool isScreenSaverEnabled(); - - //============================================================================== - /** Registers a MouseListener that will receive all mouse events that occur on - any component. - - @see removeGlobalMouseListener - */ - void addGlobalMouseListener (MouseListener* listener); - - /** Unregisters a MouseListener that was added with the addGlobalMouseListener() - method. - - @see addGlobalMouseListener - */ - void removeGlobalMouseListener (MouseListener* listener); - - //============================================================================== - /** Registers a MouseListener that will receive a callback whenever the focused - component changes. - */ - void addFocusChangeListener (FocusChangeListener* listener); - - /** Unregisters a listener that was added with addFocusChangeListener(). */ - void removeFocusChangeListener (FocusChangeListener* listener); - - //============================================================================== - /** Takes a component and makes it full-screen, removing the taskbar, dock, etc. - - The component must already be on the desktop for this method to work. It will - be resized to completely fill the screen and any extraneous taskbars, menu bars, - etc will be hidden. - - To exit kiosk mode, just call setKioskModeComponent (nullptr). When this is called, - the component that's currently being used will be resized back to the size - and position it was in before being put into this mode. - - If allowMenusAndBars is true, things like the menu and dock (on mac) are still - allowed to pop up when the mouse moves onto them. If this is false, it'll try - to hide as much on-screen paraphenalia as possible. - */ - void setKioskModeComponent (Component* componentToUse, - bool allowMenusAndBars = true); - - /** Returns the component that is currently being used in kiosk-mode. - - This is the component that was last set by setKioskModeComponent(). If none - has been set, this returns nullptr. - */ - Component* getKioskModeComponent() const noexcept { return kioskModeComponent; } - - //============================================================================== - /** Returns the number of components that are currently active as top-level - desktop windows. - - @see getComponent, Component::addToDesktop - */ - int getNumComponents() const noexcept; - - /** Returns one of the top-level desktop window components. - - The index is from 0 to getNumComponents() - 1. This could return 0 if the - index is out-of-range. - - @see getNumComponents, Component::addToDesktop - */ - Component* getComponent (int index) const noexcept; - - /** Finds the component at a given screen location. - - This will drill down into top-level windows to find the child component at - the given position. - - Returns nullptr if the coordinates are inside a non-Juce window. - */ - Component* findComponentAt (Point screenPosition) const; - - /** The Desktop object has a ComponentAnimator instance which can be used for performing - your animations. - - Having a single shared ComponentAnimator object makes it more efficient when multiple - components are being moved around simultaneously. It's also more convenient than having - to manage your own instance of one. - - @see ComponentAnimator - */ - ComponentAnimator& getAnimator() noexcept { return animator; } - - //============================================================================== - /** Returns the current default look-and-feel for components which don't have one - explicitly set. - @see setDefaultLookAndFeel - */ - LookAndFeel& getDefaultLookAndFeel() noexcept; - - /** Changes the default look-and-feel. - @param newDefaultLookAndFeel the new look-and-feel object to use - if this is - set to nullptr, it will revert to using the system's - default one. The object passed-in must be deleted by the - caller when it's no longer needed. - @see getDefaultLookAndFeel - */ - void setDefaultLookAndFeel (LookAndFeel* newDefaultLookAndFeel); - - //============================================================================== - /** Provides access to the array of mouse sources, for iteration. - In a traditional single-mouse system, there might be only one MouseInputSource. On a - multi-touch system, there could be one input source per potential finger. The number - of mouse sources returned here may increase dynamically as the program runs. - To find out how many mouse events are currently happening, use getNumDraggingMouseSources(). - */ - const Array& getMouseSources() const noexcept; - - /** Returns the number of MouseInputSource objects the system has at its disposal. - In a traditional single-mouse system, there might be only one MouseInputSource. On a - multi-touch system, there could be one input source per potential finger. The number - of mouse sources returned here may increase dynamically as the program runs. - To find out how many mouse events are currently happening, use getNumDraggingMouseSources(). - @see getMouseSource - */ - int getNumMouseSources() const noexcept; - - /** Returns one of the system's MouseInputSource objects. - The index should be from 0 to getNumMouseSources() - 1. Out-of-range indexes will return - a null pointer. - In a traditional single-mouse system, there might be only one object. On a multi-touch - system, there could be one input source per potential finger. - */ - MouseInputSource* getMouseSource (int index) const noexcept; - - /** Returns the main mouse input device that the system is using. - @see getNumMouseSources() - */ - MouseInputSource getMainMouseSource() const noexcept; - - /** Returns the number of mouse-sources that are currently being dragged. - In a traditional single-mouse system, this will be 0 or 1, depending on whether a - juce component has the button down on it. In a multi-touch system, this could - be any number from 0 to the number of simultaneous touches that can be detected. - */ - int getNumDraggingMouseSources() const noexcept; - - /** Returns one of the mouse sources that's currently being dragged. - The index should be between 0 and getNumDraggingMouseSources() - 1. If the index is - out of range, or if no mice or fingers are down, this will return a null pointer. - */ - MouseInputSource* getDraggingMouseSource (int index) const noexcept; - - /** Ensures that a non-stop stream of mouse-drag events will be sent during the - current mouse-drag operation. - - This allows you to make sure that mouseDrag() events are sent continuously, even - when the mouse isn't moving. This can be useful for things like auto-scrolling - components when the mouse is near an edge. - - Call this method during a mouseDown() or mouseDrag() callback, specifying the - minimum interval between consecutive mouse drag callbacks. The callbacks - will continue until the mouse is released, and then the interval will be reset, - so you need to make sure it's called every time you begin a drag event. - Passing an interval of 0 or less will cancel the auto-repeat. - - @see mouseDrag - */ - void beginDragAutoRepeat (int millisecondsBetweenCallbacks); - - //============================================================================== - /** In a tablet device which can be turned around, this is used to inidicate the orientation. */ - enum DisplayOrientation - { - upright = 1, /**< Indicates that the display is the normal way up. */ - upsideDown = 2, /**< Indicates that the display is upside-down. */ - rotatedClockwise = 4, /**< Indicates that the display is turned 90 degrees clockwise from its upright position. */ - rotatedAntiClockwise = 8, /**< Indicates that the display is turned 90 degrees anti-clockwise from its upright position. */ - - allOrientations = 1 + 2 + 4 + 8 /**< A combination of all the orientation values */ - }; - - /** In a tablet device which can be turned around, this returns the current orientation. */ - DisplayOrientation getCurrentOrientation() const; - - /** Sets which orientations the display is allowed to auto-rotate to. - - For devices that support rotating desktops, this lets you specify which of the orientations your app can use. - - The parameter is a bitwise or-ed combination of the values in DisplayOrientation, and must contain at least one - set bit. - */ - void setOrientationsEnabled (int allowedOrientations); - - /** Returns whether the display is allowed to auto-rotate to the given orientation. - Each orientation can be enabled using setOrientationEnabled(). By default, all orientations are allowed. - */ - bool isOrientationEnabled (DisplayOrientation orientation) const noexcept; - - //============================================================================== - class JUCE_API Displays - { - public: - /** Contains details about a display device. */ - struct Display - { - /** This is the bounds of the area of this display which isn't covered by - OS-dependent objects like the taskbar, menu bar, etc. */ - Rectangle userArea; - - /** This is the total physical area of this display, including any taskbars, etc */ - Rectangle totalArea; - - /** This is the scale-factor of this display. - If you create a component with size 1x1, this scale factor indicates the actual - size of the component in terms of physical pixels. - For higher-resolution displays, it may be a value greater than 1.0 - */ - double scale; - - /** The DPI of the display. - This is the number of physical pixels per inch. To get the number of logical - pixels per inch, divide this by the Display::scale value. - */ - double dpi; - - /** This will be true if this is the user's main screen. */ - bool isMain; - }; - - /** Returns the display which acts as user's main screen. */ - const Display& getMainDisplay() const noexcept; - - /** Returns the display which contains a particular point. - If the point lies outside all the displays, the nearest one will be returned. - */ - const Display& getDisplayContaining (Point position) const noexcept; - - /** Returns a RectangleList made up of all the displays. */ - RectangleList getRectangleList (bool userAreasOnly) const; - - /** Returns the smallest bounding box which contains all the displays. */ - Rectangle getTotalBounds (bool userAreasOnly) const; - - /** The list of displays. */ - Array displays; - - #ifndef DOXYGEN - /** @internal */ - void refresh(); - #endif - - private: - friend class Desktop; - friend struct ContainerDeletePolicy; - Displays (Desktop&); - ~Displays(); - - void init (Desktop&); - void findDisplays (float masterScale); - }; - - const Displays& getDisplays() const noexcept { return *displays; } - - //============================================================================== - /** Sets a global scale factor to be used for all desktop windows. - Setting this will also scale the monitor sizes that are returned by getDisplays(). - */ - void setGlobalScaleFactor (float newScaleFactor) noexcept; - - /** Returns the current global scale factor, as set by setGlobalScaleFactor(). - @see setGlobalScaleFactor - */ - float getGlobalScaleFactor() const noexcept { return masterScaleFactor; } - - //============================================================================== - /** True if the OS supports semitransparent windows */ - static bool canUseSemiTransparentWindows() noexcept; - -private: - //============================================================================== - static Desktop* instance; - - friend class Component; - friend class ComponentPeer; - friend class MouseInputSourceInternal; - friend class DeletedAtShutdown; - friend class TopLevelWindowManager; - - ScopedPointer mouseSources; - - ListenerList mouseListeners; - ListenerList focusListeners; - - Array desktopComponents; - Array peers; - - ScopedPointer displays; - - Point lastFakeMouseMove; - void sendMouseMove(); - - int mouseClickCounter, mouseWheelCounter; - void incrementMouseClickCounter() noexcept; - void incrementMouseWheelCounter() noexcept; - - ScopedPointer defaultLookAndFeel; - WeakReference currentLookAndFeel; - - Component* kioskModeComponent; - Rectangle kioskComponentOriginalBounds; - bool kioskModeReentrant; - - int allowedOrientations; - float masterScaleFactor; - - ComponentAnimator animator; - - void timerCallback() override; - void resetTimer(); - ListenerList& getMouseListeners(); - - void addDesktopComponent (Component*); - void removeDesktopComponent (Component*); - void componentBroughtToFront (Component*); - - void setKioskComponent (Component*, bool shouldBeEnabled, bool allowMenusAndBars); - - void triggerFocusCallback(); - void handleAsyncUpdate() override; - - static Point getMousePositionFloat(); - - static double getDefaultMasterScale(); - - Desktop(); - ~Desktop(); - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Desktop) -}; - - -#endif // JUCE_DESKTOP_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/components/juce_ModalComponentManager.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/components/juce_ModalComponentManager.cpp deleted file mode 100644 index a6e7b07116..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/components/juce_ModalComponentManager.cpp +++ /dev/null @@ -1,294 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -class ModalComponentManager::ModalItem : public ComponentMovementWatcher -{ -public: - ModalItem (Component* const comp, const bool autoDelete_) - : ComponentMovementWatcher (comp), - component (comp), returnValue (0), - isActive (true), autoDelete (autoDelete_) - { - jassert (comp != nullptr); - } - - void componentMovedOrResized (bool, bool) override {} - - void componentPeerChanged() override - { - if (! component->isShowing()) - cancel(); - } - - void componentVisibilityChanged() override - { - if (! component->isShowing()) - cancel(); - } - - void componentBeingDeleted (Component& comp) override - { - ComponentMovementWatcher::componentBeingDeleted (comp); - - if (component == &comp || comp.isParentOf (component)) - { - autoDelete = false; - cancel(); - } - } - - void cancel() - { - if (isActive) - { - isActive = false; - - if (ModalComponentManager* mcm = ModalComponentManager::getInstanceWithoutCreating()) - mcm->triggerAsyncUpdate(); - } - } - - Component* component; - OwnedArray callbacks; - int returnValue; - bool isActive, autoDelete; - -private: - JUCE_DECLARE_NON_COPYABLE (ModalItem) -}; - -//============================================================================== -ModalComponentManager::ModalComponentManager() -{ -} - -ModalComponentManager::~ModalComponentManager() -{ - stack.clear(); - clearSingletonInstance(); -} - -juce_ImplementSingleton_SingleThreaded (ModalComponentManager); - - -//============================================================================== -void ModalComponentManager::startModal (Component* component, bool autoDelete) -{ - if (component != nullptr) - stack.add (new ModalItem (component, autoDelete)); -} - -void ModalComponentManager::attachCallback (Component* component, Callback* callback) -{ - if (callback != nullptr) - { - ScopedPointer callbackDeleter (callback); - - for (int i = stack.size(); --i >= 0;) - { - ModalItem* const item = stack.getUnchecked(i); - - if (item->component == component) - { - item->callbacks.add (callback); - callbackDeleter.release(); - break; - } - } - } -} - -void ModalComponentManager::endModal (Component* component) -{ - for (int i = stack.size(); --i >= 0;) - { - ModalItem* const item = stack.getUnchecked(i); - - if (item->component == component) - item->cancel(); - } -} - -void ModalComponentManager::endModal (Component* component, int returnValue) -{ - for (int i = stack.size(); --i >= 0;) - { - ModalItem* const item = stack.getUnchecked(i); - - if (item->component == component) - { - item->returnValue = returnValue; - item->cancel(); - } - } -} - -int ModalComponentManager::getNumModalComponents() const -{ - int n = 0; - for (int i = 0; i < stack.size(); ++i) - if (stack.getUnchecked(i)->isActive) - ++n; - - return n; -} - -Component* ModalComponentManager::getModalComponent (const int index) const -{ - int n = 0; - for (int i = stack.size(); --i >= 0;) - { - const ModalItem* const item = stack.getUnchecked(i); - if (item->isActive) - if (n++ == index) - return item->component; - } - - return nullptr; -} - -bool ModalComponentManager::isModal (Component* const comp) const -{ - for (int i = stack.size(); --i >= 0;) - { - const ModalItem* const item = stack.getUnchecked(i); - if (item->isActive && item->component == comp) - return true; - } - - return false; -} - -bool ModalComponentManager::isFrontModalComponent (Component* const comp) const -{ - return comp == getModalComponent (0); -} - -void ModalComponentManager::handleAsyncUpdate() -{ - for (int i = stack.size(); --i >= 0;) - { - const ModalItem* const item = stack.getUnchecked(i); - - if (! item->isActive) - { - ScopedPointer deleter (stack.removeAndReturn (i)); - Component::SafePointer compToDelete (item->autoDelete ? item->component : nullptr); - - for (int j = item->callbacks.size(); --j >= 0;) - item->callbacks.getUnchecked(j)->modalStateFinished (item->returnValue); - - compToDelete.deleteAndZero(); - } - } -} - -void ModalComponentManager::bringModalComponentsToFront (bool topOneShouldGrabFocus) -{ - ComponentPeer* lastOne = nullptr; - - for (int i = 0; i < getNumModalComponents(); ++i) - { - Component* const c = getModalComponent (i); - - if (c == nullptr) - break; - - ComponentPeer* peer = c->getPeer(); - - if (peer != nullptr && peer != lastOne) - { - if (lastOne == nullptr) - { - peer->toFront (topOneShouldGrabFocus); - - if (topOneShouldGrabFocus) - peer->grabFocus(); - } - else - peer->toBehind (lastOne); - - lastOne = peer; - } - } -} - -bool ModalComponentManager::cancelAllModalComponents() -{ - const int numModal = getNumModalComponents(); - - for (int i = numModal; --i >= 0;) - if (Component* const c = getModalComponent(i)) - c->exitModalState (0); - - return numModal > 0; -} - -#if JUCE_MODAL_LOOPS_PERMITTED -class ModalComponentManager::ReturnValueRetriever : public ModalComponentManager::Callback -{ -public: - ReturnValueRetriever (int& v, bool& done) : value (v), finished (done) {} - - void modalStateFinished (int returnValue) - { - finished = true; - value = returnValue; - } - -private: - int& value; - bool& finished; - - JUCE_DECLARE_NON_COPYABLE (ReturnValueRetriever) -}; - -int ModalComponentManager::runEventLoopForCurrentComponent() -{ - // This can only be run from the message thread! - jassert (MessageManager::getInstance()->isThisTheMessageThread()); - - int returnValue = 0; - - if (Component* currentlyModal = getModalComponent (0)) - { - FocusRestorer focusRestorer; - - bool finished = false; - attachCallback (currentlyModal, new ReturnValueRetriever (returnValue, finished)); - - JUCE_TRY - { - while (! finished) - { - if (! MessageManager::getInstance()->runDispatchLoopUntil (20)) - break; - } - } - JUCE_CATCH_EXCEPTION - } - - return returnValue; -} -#endif diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/components/juce_ModalComponentManager.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/components/juce_ModalComponentManager.h deleted file mode 100644 index b21421ebf0..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/components/juce_ModalComponentManager.h +++ /dev/null @@ -1,369 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_MODALCOMPONENTMANAGER_H_INCLUDED -#define JUCE_MODALCOMPONENTMANAGER_H_INCLUDED - - -//============================================================================== -/** - Manages the system's stack of modal components. - - Normally you'll just use the Component methods to invoke modal states in components, - and won't have to deal with this class directly, but this is the singleton object that's - used internally to manage the stack. - - @see Component::enterModalState, Component::exitModalState, Component::isCurrentlyModal, - Component::getCurrentlyModalComponent, Component::isCurrentlyBlockedByAnotherModalComponent -*/ -class JUCE_API ModalComponentManager : private AsyncUpdater, - private DeletedAtShutdown -{ -public: - //============================================================================== - /** Receives callbacks when a modal component is dismissed. - - You can register a callback using Component::enterModalState() or - ModalComponentManager::attachCallback(). - - For some quick ways of creating callback objects, see the ModalCallbackFunction class. - @see ModalCallbackFunction - */ - class Callback - { - public: - /** */ - Callback() {} - - /** Destructor. */ - virtual ~Callback() {} - - /** Called to indicate that a modal component has been dismissed. - - You can register a callback using Component::enterModalState() or - ModalComponentManager::attachCallback(). - - The returnValue parameter is the value that was passed to Component::exitModalState() - when the component was dismissed. - - The callback object will be deleted shortly after this method is called. - */ - virtual void modalStateFinished (int returnValue) = 0; - }; - - //============================================================================== - /** Returns the number of components currently being shown modally. - @see getModalComponent - */ - int getNumModalComponents() const; - - /** Returns one of the components being shown modally. - An index of 0 is the most recently-shown, topmost component. - */ - Component* getModalComponent (int index) const; - - /** Returns true if the specified component is in a modal state. */ - bool isModal (Component* component) const; - - /** Returns true if the specified component is currently the topmost modal component. */ - bool isFrontModalComponent (Component* component) const; - - /** Adds a new callback that will be called when the specified modal component is dismissed. - - If the component is modal, then when it is dismissed, either by being hidden, or by calling - Component::exitModalState(), then the Callback::modalStateFinished() method will be - called. - - Each component can have any number of callbacks associated with it, and this one is added - to that list. - - The object that is passed in will be deleted by the manager when it's no longer needed. If - the given component is not currently modal, the callback object is deleted immediately and - no action is taken. - */ - void attachCallback (Component* component, Callback* callback); - - /** Brings any modal components to the front. */ - void bringModalComponentsToFront (bool topOneShouldGrabFocus = true); - - /** Calls exitModalState (0) on any components that are currently modal. - @returns true if any components were modal; false if nothing needed cancelling - */ - bool cancelAllModalComponents(); - - #if JUCE_MODAL_LOOPS_PERMITTED - /** Runs the event loop until the currently topmost modal component is dismissed, and - returns the exit code for that component. - */ - int runEventLoopForCurrentComponent(); - #endif - - //============================================================================== - juce_DeclareSingleton_SingleThreaded_Minimal (ModalComponentManager); - -protected: - /** Creates a ModalComponentManager. - You shouldn't ever call the constructor - it's a singleton, so use ModalComponentManager::getInstance() - */ - ModalComponentManager(); - - /** Destructor. */ - ~ModalComponentManager(); - - /** @internal */ - void handleAsyncUpdate() override; - -private: - //============================================================================== - class ModalItem; - class ReturnValueRetriever; - - friend class Component; - friend struct ContainerDeletePolicy; - OwnedArray stack; - - void startModal (Component*, bool autoDelete); - void endModal (Component*, int returnValue); - void endModal (Component*); - - JUCE_DECLARE_NON_COPYABLE (ModalComponentManager) -}; - -//============================================================================== -/** - This class provides some handy utility methods for creating ModalComponentManager::Callback - objects that will invoke a static function with some parameters when a modal component is dismissed. -*/ -class ModalCallbackFunction -{ -public: - //============================================================================== - /** This is a utility function to create a ModalComponentManager::Callback that will - call a static function with a parameter. - - The function that you supply must take two parameters - the first being an int, which is - the result code that was used when the modal component was dismissed, and the second - can be a custom type. Note that this custom value will be copied and stored, so it must - be a primitive type or a class that provides copy-by-value semantics. - - E.g. @code - static void myCallbackFunction (int modalResult, double customValue) - { - if (modalResult == 1) - doSomethingWith (customValue); - } - - Component* someKindOfComp; - ... - someKindOfComp->enterModalState (ModalCallbackFunction::create (myCallbackFunction, 3.0)); - @endcode - @see ModalComponentManager::Callback - */ - template - static ModalComponentManager::Callback* create (void (*functionToCall) (int, ParamType), - ParamType parameterValue) - { - return new FunctionCaller1 (functionToCall, parameterValue); - } - - //============================================================================== - /** This is a utility function to create a ModalComponentManager::Callback that will - call a static function with two custom parameters. - - The function that you supply must take three parameters - the first being an int, which is - the result code that was used when the modal component was dismissed, and the next two are - your custom types. Note that these custom values will be copied and stored, so they must - be primitive types or classes that provide copy-by-value semantics. - - E.g. @code - static void myCallbackFunction (int modalResult, double customValue1, String customValue2) - { - if (modalResult == 1) - doSomethingWith (customValue1, customValue2); - } - - Component* someKindOfComp; - ... - someKindOfComp->enterModalState (ModalCallbackFunction::create (myCallbackFunction, 3.0, String ("xyz"))); - @endcode - @see ModalComponentManager::Callback - */ - template - static ModalComponentManager::Callback* withParam (void (*functionToCall) (int, ParamType1, ParamType2), - ParamType1 parameterValue1, - ParamType2 parameterValue2) - { - return new FunctionCaller2 (functionToCall, parameterValue1, parameterValue2); - } - - //============================================================================== - /** This is a utility function to create a ModalComponentManager::Callback that will - call a static function with a component. - - The function that you supply must take two parameters - the first being an int, which is - the result code that was used when the modal component was dismissed, and the second - can be a Component class. The component will be stored as a WeakReference, so that if it gets - deleted before this callback is invoked, the pointer that is passed to the function will be null. - - E.g. @code - static void myCallbackFunction (int modalResult, Slider* mySlider) - { - if (modalResult == 1 && mySlider != nullptr) // (must check that mySlider isn't null in case it was deleted..) - mySlider->setValue (0.0); - } - - Component* someKindOfComp; - Slider* mySlider; - ... - someKindOfComp->enterModalState (ModalCallbackFunction::forComponent (myCallbackFunction, mySlider)); - @endcode - @see ModalComponentManager::Callback - */ - template - static ModalComponentManager::Callback* forComponent (void (*functionToCall) (int, ComponentType*), - ComponentType* component) - { - return new ComponentCaller1 (functionToCall, component); - } - - //============================================================================== - /** Creates a ModalComponentManager::Callback that will call a static function with a component. - - The function that you supply must take three parameters - the first being an int, which is - the result code that was used when the modal component was dismissed, the second being a Component - class, and the third being a custom type (which must be a primitive type or have copy-by-value semantics). - The component will be stored as a WeakReference, so that if it gets deleted before this callback is - invoked, the pointer that is passed into the function will be null. - - E.g. @code - static void myCallbackFunction (int modalResult, Slider* mySlider, String customParam) - { - if (modalResult == 1 && mySlider != nullptr) // (must check that mySlider isn't null in case it was deleted..) - mySlider->setName (customParam); - } - - Component* someKindOfComp; - Slider* mySlider; - ... - someKindOfComp->enterModalState (ModalCallbackFunction::forComponent (myCallbackFunction, mySlider, String ("hello"))); - @endcode - @see ModalComponentManager::Callback - */ - template - static ModalComponentManager::Callback* forComponent (void (*functionToCall) (int, ComponentType*, ParamType), - ComponentType* component, - ParamType param) - { - return new ComponentCaller2 (functionToCall, component, param); - } - -private: - //============================================================================== - template - class FunctionCaller1 : public ModalComponentManager::Callback - { - public: - typedef void (*FunctionType) (int, ParamType); - - FunctionCaller1 (FunctionType& f, ParamType& p1) - : function (f), param (p1) {} - - void modalStateFinished (int returnValue) { function (returnValue, param); } - - private: - const FunctionType function; - ParamType param; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (FunctionCaller1) - }; - - template - class FunctionCaller2 : public ModalComponentManager::Callback - { - public: - typedef void (*FunctionType) (int, ParamType1, ParamType2); - - FunctionCaller2 (FunctionType& f, ParamType1& p1, ParamType2& p2) - : function (f), param1 (p1), param2 (p2) {} - - void modalStateFinished (int returnValue) { function (returnValue, param1, param2); } - - private: - const FunctionType function; - ParamType1 param1; - ParamType2 param2; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (FunctionCaller2) - }; - - template - class ComponentCaller1 : public ModalComponentManager::Callback - { - public: - typedef void (*FunctionType) (int, ComponentType*); - - ComponentCaller1 (FunctionType& f, ComponentType* c) - : function (f), comp (c) {} - - void modalStateFinished (int returnValue) - { - function (returnValue, static_cast (comp.get())); - } - - private: - const FunctionType function; - WeakReference comp; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ComponentCaller1) - }; - - template - class ComponentCaller2 : public ModalComponentManager::Callback - { - public: - typedef void (*FunctionType) (int, ComponentType*, ParamType1); - - ComponentCaller2 (FunctionType& f, ComponentType* c, ParamType1 p1) - : function (f), comp (c), param1 (p1) {} - - void modalStateFinished (int returnValue) - { - function (returnValue, static_cast (comp.get()), param1); - } - - private: - const FunctionType function; - WeakReference comp; - ParamType1 param1; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ComponentCaller2) - }; - - ModalCallbackFunction(); - ~ModalCallbackFunction(); - JUCE_DECLARE_NON_COPYABLE (ModalCallbackFunction) -}; - - -#endif // JUCE_MODALCOMPONENTMANAGER_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/drawables/juce_Drawable.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/drawables/juce_Drawable.cpp deleted file mode 100644 index 3e88318804..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/drawables/juce_Drawable.cpp +++ /dev/null @@ -1,251 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -Drawable::Drawable() -{ - setInterceptsMouseClicks (false, false); - setPaintingIsUnclipped (true); -} - -Drawable::Drawable (const Drawable& other) - : Component (other.getName()) -{ - setComponentID (other.getComponentID()); -} - -Drawable::~Drawable() -{ -} - -//============================================================================== -void Drawable::draw (Graphics& g, float opacity, const AffineTransform& transform) const -{ - const_cast (this)->nonConstDraw (g, opacity, transform); -} - -void Drawable::nonConstDraw (Graphics& g, float opacity, const AffineTransform& transform) -{ - Graphics::ScopedSaveState ss (g); - - g.addTransform (AffineTransform::translation ((float) -(originRelativeToComponent.x), - (float) -(originRelativeToComponent.y)) - .followedBy (getTransform()) - .followedBy (transform)); - - if (! g.isClipEmpty()) - { - if (opacity < 1.0f) - { - g.beginTransparencyLayer (opacity); - paintEntireComponent (g, true); - g.endTransparencyLayer(); - } - else - { - paintEntireComponent (g, true); - } - } -} - -void Drawable::drawAt (Graphics& g, float x, float y, float opacity) const -{ - draw (g, opacity, AffineTransform::translation (x, y)); -} - -void Drawable::drawWithin (Graphics& g, const Rectangle& destArea, - RectanglePlacement placement, float opacity) const -{ - draw (g, opacity, placement.getTransformToFit (getDrawableBounds(), destArea)); -} - -//============================================================================== -DrawableComposite* Drawable::getParent() const -{ - return dynamic_cast (getParentComponent()); -} - -void Drawable::transformContextToCorrectOrigin (Graphics& g) -{ - g.setOrigin (originRelativeToComponent); -} - -void Drawable::parentHierarchyChanged() -{ - setBoundsToEnclose (getDrawableBounds()); -} - -void Drawable::setBoundsToEnclose (const Rectangle& area) -{ - Drawable* const parent = getParent(); - Point parentOrigin; - if (parent != nullptr) - parentOrigin = parent->originRelativeToComponent; - - const Rectangle newBounds (area.getSmallestIntegerContainer() + parentOrigin); - originRelativeToComponent = parentOrigin - newBounds.getPosition(); - setBounds (newBounds); -} - -//============================================================================== -bool Drawable::replaceColour (Colour original, Colour replacement) -{ - bool changed = false; - - for (int i = getNumChildComponents(); --i >= 0;) - if (Drawable* d = dynamic_cast (getChildComponent(i))) - changed = d->replaceColour (original, replacement) || changed; - - return changed; -} - -//============================================================================== -void Drawable::setOriginWithOriginalSize (Point originWithinParent) -{ - setTransform (AffineTransform::translation (originWithinParent.x, originWithinParent.y)); -} - -void Drawable::setTransformToFit (const Rectangle& area, RectanglePlacement placement) -{ - if (! area.isEmpty()) - setTransform (placement.getTransformToFit (getDrawableBounds(), area)); -} - -//============================================================================== -Drawable* Drawable::createFromImageData (const void* data, const size_t numBytes) -{ - Drawable* result = nullptr; - - Image image (ImageFileFormat::loadFrom (data, numBytes)); - - if (image.isValid()) - { - DrawableImage* const di = new DrawableImage(); - di->setImage (image); - result = di; - } - else - { - const String asString (String::createStringFromData (data, (int) numBytes)); - - XmlDocument doc (asString); - ScopedPointer outer (doc.getDocumentElement (true)); - - if (outer != nullptr && outer->hasTagName ("svg")) - { - ScopedPointer svg (doc.getDocumentElement()); - - if (svg != nullptr) - result = Drawable::createFromSVG (*svg); - } - } - - return result; -} - -Drawable* Drawable::createFromImageDataStream (InputStream& dataSource) -{ - MemoryOutputStream mo; - mo << dataSource; - - return createFromImageData (mo.getData(), mo.getDataSize()); -} - -Drawable* Drawable::createFromImageFile (const File& file) -{ - FileInputStream fin (file); - - return fin.openedOk() ? createFromImageDataStream (fin) : nullptr; -} - -//============================================================================== -template -class DrawableTypeHandler : public ComponentBuilder::TypeHandler -{ -public: - DrawableTypeHandler() - : ComponentBuilder::TypeHandler (DrawableClass::valueTreeType) - { - } - - Component* addNewComponentFromState (const ValueTree& state, Component* parent) - { - DrawableClass* const d = new DrawableClass(); - - if (parent != nullptr) - parent->addAndMakeVisible (d); - - updateComponentFromState (d, state); - return d; - } - - void updateComponentFromState (Component* component, const ValueTree& state) - { - DrawableClass* const d = dynamic_cast (component); - jassert (d != nullptr); - d->refreshFromValueTree (state, *this->getBuilder()); - } -}; - -void Drawable::registerDrawableTypeHandlers (ComponentBuilder& builder) -{ - builder.registerTypeHandler (new DrawableTypeHandler ()); - builder.registerTypeHandler (new DrawableTypeHandler ()); - builder.registerTypeHandler (new DrawableTypeHandler ()); - builder.registerTypeHandler (new DrawableTypeHandler ()); - builder.registerTypeHandler (new DrawableTypeHandler ()); -} - -Drawable* Drawable::createFromValueTree (const ValueTree& tree, ComponentBuilder::ImageProvider* imageProvider) -{ - ComponentBuilder builder (tree); - builder.setImageProvider (imageProvider); - registerDrawableTypeHandlers (builder); - - ScopedPointer comp (builder.createComponent()); - Drawable* const d = dynamic_cast (static_cast (comp)); - - if (d != nullptr) - comp.release(); - - return d; -} - -//============================================================================== -Drawable::ValueTreeWrapperBase::ValueTreeWrapperBase (const ValueTree& state_) - : state (state_) -{ -} - -String Drawable::ValueTreeWrapperBase::getID() const -{ - return state [ComponentBuilder::idProperty]; -} - -void Drawable::ValueTreeWrapperBase::setID (const String& newID) -{ - if (newID.isEmpty()) - state.removeProperty (ComponentBuilder::idProperty, nullptr); - else - state.setProperty (ComponentBuilder::idProperty, newID, nullptr); -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/drawables/juce_Drawable.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/drawables/juce_Drawable.h deleted file mode 100644 index b8956d5a0f..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/drawables/juce_Drawable.h +++ /dev/null @@ -1,259 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_DRAWABLE_H_INCLUDED -#define JUCE_DRAWABLE_H_INCLUDED - - -//============================================================================== -/** - The base class for objects which can draw themselves, e.g. polygons, images, etc. - - @see DrawableComposite, DrawableImage, DrawablePath, DrawableText -*/ -class JUCE_API Drawable : public Component -{ -protected: - //============================================================================== - /** The base class can't be instantiated directly. - - @see DrawableComposite, DrawableImage, DrawablePath, DrawableText - */ - Drawable(); - -public: - /** Destructor. */ - virtual ~Drawable(); - - //============================================================================== - /** Creates a deep copy of this Drawable object. - - Use this to create a new copy of this and any sub-objects in the tree. - */ - virtual Drawable* createCopy() const = 0; - - //============================================================================== - /** Renders this Drawable object. - - Note that the preferred way to render a drawable in future is by using it - as a component and adding it to a parent, so you might want to consider that - before using this method. - - @see drawWithin - */ - void draw (Graphics& g, float opacity, - const AffineTransform& transform = AffineTransform::identity) const; - - /** Renders the Drawable at a given offset within the Graphics context. - - The coordinates passed-in are used to translate the object relative to its own - origin before drawing it - this is basically a quick way of saying: - - @code - draw (g, AffineTransform::translation (x, y)). - @endcode - - Note that the preferred way to render a drawable in future is by using it - as a component and adding it to a parent, so you might want to consider that - before using this method. - */ - void drawAt (Graphics& g, float x, float y, float opacity) const; - - /** Renders the Drawable within a rectangle, scaling it to fit neatly inside without - changing its aspect-ratio. - - The object can placed arbitrarily within the rectangle based on a Justification type, - and can either be made as big as possible, or just reduced to fit. - - Note that the preferred way to render a drawable in future is by using it - as a component and adding it to a parent, so you might want to consider that - before using this method. - - @param g the graphics context to render onto - @param destArea the target rectangle to fit the drawable into - @param placement defines the alignment and rescaling to use to fit - this object within the target rectangle. - @param opacity the opacity to use, in the range 0 to 1.0 - */ - void drawWithin (Graphics& g, - const Rectangle& destArea, - RectanglePlacement placement, - float opacity) const; - - - //============================================================================== - /** Resets any transformations on this drawable, and positions its origin within - its parent component. - */ - void setOriginWithOriginalSize (Point originWithinParent); - - /** Sets a transform for this drawable that will position it within the specified - area of its parent component. - */ - void setTransformToFit (const Rectangle& areaInParent, RectanglePlacement placement); - - /** Returns the DrawableComposite that contains this object, if there is one. */ - DrawableComposite* getParent() const; - - //============================================================================== - /** Tries to turn some kind of image file into a drawable. - - The data could be an image that the ImageFileFormat class understands, or it - could be SVG. - */ - static Drawable* createFromImageData (const void* data, size_t numBytes); - - /** Tries to turn a stream containing some kind of image data into a drawable. - - The data could be an image that the ImageFileFormat class understands, or it - could be SVG. - */ - static Drawable* createFromImageDataStream (InputStream& dataSource); - - /** Tries to turn a file containing some kind of image data into a drawable. - - The data could be an image that the ImageFileFormat class understands, or it - could be SVG. - */ - static Drawable* createFromImageFile (const File& file); - - /** Attempts to parse an SVG (Scalable Vector Graphics) document, and to turn this - into a Drawable tree. - - The object returned must be deleted by the caller. If something goes wrong - while parsing, it may return nullptr. - - SVG is a pretty large and complex spec, and this doesn't aim to be a full - implementation, but it can return the basic vector objects. - */ - static Drawable* createFromSVG (const XmlElement& svgDocument); - - /** Parses an SVG path string and returns it. */ - static Path parseSVGPath (const String& svgPath); - - //============================================================================== - /** Tries to create a Drawable from a previously-saved ValueTree. - The ValueTree must have been created by the createValueTree() method. - If there are any images used within the drawable, you'll need to provide a valid - ImageProvider object that can be used to retrieve these images from whatever type - of identifier is used to represent them. - Internally, this uses a ComponentBuilder, and registerDrawableTypeHandlers(). - */ - static Drawable* createFromValueTree (const ValueTree& tree, ComponentBuilder::ImageProvider* imageProvider); - - /** Creates a ValueTree to represent this Drawable. - The ValueTree that is returned can be turned back into a Drawable with createFromValueTree(). - If there are any images used in this drawable, you'll need to provide a valid ImageProvider - object that can be used to create storable representations of them. - */ - virtual ValueTree createValueTree (ComponentBuilder::ImageProvider* imageProvider) const = 0; - - /** Returns the area that this drawble covers. - The result is expressed in this drawable's own coordinate space, and does not take - into account any transforms that may be applied to the component. - */ - virtual Rectangle getDrawableBounds() const = 0; - - /** Recursively replaces a colour that might be used for filling or stroking. - return true if any instances of this colour were found. - */ - virtual bool replaceColour (Colour originalColour, Colour replacementColour); - - //============================================================================== - /** Internal class used to manage ValueTrees that represent Drawables. */ - class ValueTreeWrapperBase - { - public: - ValueTreeWrapperBase (const ValueTree& state); - - ValueTree& getState() noexcept { return state; } - - String getID() const; - void setID (const String& newID); - - ValueTree state; - }; - - //============================================================================== - /** Registers a set of ComponentBuilder::TypeHandler objects that can be used to - load all the different Drawable types from a saved state. - @see ComponentBuilder::registerTypeHandler() - */ - static void registerDrawableTypeHandlers (ComponentBuilder& componentBuilder); - -protected: - //============================================================================== - friend class DrawableComposite; - friend class DrawableShape; - - /** @internal */ - void transformContextToCorrectOrigin (Graphics&); - /** @internal */ - void parentHierarchyChanged() override; - /** @internal */ - void setBoundsToEnclose (const Rectangle&); - - Point originRelativeToComponent; - - #ifndef DOXYGEN - /** Internal utility class used by Drawables. */ - template - class Positioner : public RelativeCoordinatePositionerBase - { - public: - Positioner (DrawableType& c) - : RelativeCoordinatePositionerBase (c), - owner (c) - {} - - bool registerCoordinates() { return owner.registerCoordinates (*this); } - void applyToComponentBounds() - { - ComponentScope scope (getComponent()); - owner.recalculateCoordinates (&scope); - } - - void applyNewBounds (const Rectangle&) - { - jassertfalse; // drawables can't be resized directly! - } - - private: - DrawableType& owner; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Positioner) - }; - - Drawable (const Drawable&); - #endif - -private: - void nonConstDraw (Graphics&, float opacity, const AffineTransform&); - - Drawable& operator= (const Drawable&); - JUCE_LEAK_DETECTOR (Drawable) -}; - - -#endif // JUCE_DRAWABLE_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/drawables/juce_DrawableComposite.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/drawables/juce_DrawableComposite.cpp deleted file mode 100644 index 688507fd55..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/drawables/juce_DrawableComposite.cpp +++ /dev/null @@ -1,327 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -DrawableComposite::DrawableComposite() - : bounds (Point(), Point (100.0f, 0.0f), Point (0.0f, 100.0f)), - updateBoundsReentrant (false) -{ - setContentArea (RelativeRectangle (RelativeCoordinate (0.0), - RelativeCoordinate (100.0), - RelativeCoordinate (0.0), - RelativeCoordinate (100.0))); -} - -DrawableComposite::DrawableComposite (const DrawableComposite& other) - : Drawable (other), - bounds (other.bounds), - markersX (other.markersX), - markersY (other.markersY), - updateBoundsReentrant (false) -{ - for (int i = 0; i < other.getNumChildComponents(); ++i) - if (const Drawable* const d = dynamic_cast (other.getChildComponent(i))) - addAndMakeVisible (d->createCopy()); -} - -DrawableComposite::~DrawableComposite() -{ - deleteAllChildren(); -} - -Drawable* DrawableComposite::createCopy() const -{ - return new DrawableComposite (*this); -} - -//============================================================================== -Rectangle DrawableComposite::getDrawableBounds() const -{ - Rectangle r; - - for (int i = getNumChildComponents(); --i >= 0;) - if (const Drawable* const d = dynamic_cast (getChildComponent(i))) - r = r.getUnion (d->isTransformed() ? d->getDrawableBounds().transformedBy (d->getTransform()) - : d->getDrawableBounds()); - - return r; -} - -MarkerList* DrawableComposite::getMarkers (bool xAxis) -{ - return xAxis ? &markersX : &markersY; -} - -RelativeRectangle DrawableComposite::getContentArea() const -{ - jassert (markersX.getNumMarkers() >= 2 && markersX.getMarker (0)->name == contentLeftMarkerName && markersX.getMarker (1)->name == contentRightMarkerName); - jassert (markersY.getNumMarkers() >= 2 && markersY.getMarker (0)->name == contentTopMarkerName && markersY.getMarker (1)->name == contentBottomMarkerName); - - return RelativeRectangle (markersX.getMarker(0)->position, markersX.getMarker(1)->position, - markersY.getMarker(0)->position, markersY.getMarker(1)->position); -} - -void DrawableComposite::setContentArea (const RelativeRectangle& newArea) -{ - markersX.setMarker (contentLeftMarkerName, newArea.left); - markersX.setMarker (contentRightMarkerName, newArea.right); - markersY.setMarker (contentTopMarkerName, newArea.top); - markersY.setMarker (contentBottomMarkerName, newArea.bottom); -} - -void DrawableComposite::setBoundingBox (const RelativeParallelogram& newBounds) -{ - if (bounds != newBounds) - { - bounds = newBounds; - - if (bounds.isDynamic()) - { - Drawable::Positioner* const p = new Drawable::Positioner (*this); - setPositioner (p); - p->apply(); - } - else - { - setPositioner (nullptr); - recalculateCoordinates (nullptr); - } - } -} - -void DrawableComposite::resetBoundingBoxToContentArea() -{ - const RelativeRectangle content (getContentArea()); - - setBoundingBox (RelativeParallelogram (RelativePoint (content.left, content.top), - RelativePoint (content.right, content.top), - RelativePoint (content.left, content.bottom))); -} - -void DrawableComposite::resetContentAreaAndBoundingBoxToFitChildren() -{ - const Rectangle activeArea (getDrawableBounds()); - - setContentArea (RelativeRectangle (RelativeCoordinate (activeArea.getX()), - RelativeCoordinate (activeArea.getRight()), - RelativeCoordinate (activeArea.getY()), - RelativeCoordinate (activeArea.getBottom()))); - resetBoundingBoxToContentArea(); -} - -bool DrawableComposite::registerCoordinates (RelativeCoordinatePositionerBase& pos) -{ - bool ok = pos.addPoint (bounds.topLeft); - ok = pos.addPoint (bounds.topRight) && ok; - return pos.addPoint (bounds.bottomLeft) && ok; -} - -void DrawableComposite::recalculateCoordinates (Expression::Scope* scope) -{ - Point resolved[3]; - bounds.resolveThreePoints (resolved, scope); - - const Rectangle content (getContentArea().resolve (scope)); - - AffineTransform t (AffineTransform::fromTargetPoints (content.getX(), content.getY(), resolved[0].x, resolved[0].y, - content.getRight(), content.getY(), resolved[1].x, resolved[1].y, - content.getX(), content.getBottom(), resolved[2].x, resolved[2].y)); - - if (t.isSingularity()) - t = AffineTransform::identity; - - setTransform (t); -} - -void DrawableComposite::parentHierarchyChanged() -{ - DrawableComposite* parent = getParent(); - if (parent != nullptr) - originRelativeToComponent = parent->originRelativeToComponent - getPosition(); -} - -void DrawableComposite::childBoundsChanged (Component*) -{ - updateBoundsToFitChildren(); -} - -void DrawableComposite::childrenChanged() -{ - updateBoundsToFitChildren(); -} - -void DrawableComposite::updateBoundsToFitChildren() -{ - if (! updateBoundsReentrant) - { - const ScopedValueSetter setter (updateBoundsReentrant, true, false); - - Rectangle childArea; - - for (int i = getNumChildComponents(); --i >= 0;) - childArea = childArea.getUnion (getChildComponent(i)->getBoundsInParent()); - - const Point delta (childArea.getPosition()); - childArea += getPosition(); - - if (childArea != getBounds()) - { - if (! delta.isOrigin()) - { - originRelativeToComponent -= delta; - - for (int i = getNumChildComponents(); --i >= 0;) - if (Component* const c = getChildComponent(i)) - c->setBounds (c->getBounds() - delta); - } - - setBounds (childArea); - } - } -} - -//============================================================================== -const char* const DrawableComposite::contentLeftMarkerName = "left"; -const char* const DrawableComposite::contentRightMarkerName = "right"; -const char* const DrawableComposite::contentTopMarkerName = "top"; -const char* const DrawableComposite::contentBottomMarkerName = "bottom"; - -//============================================================================== -const Identifier DrawableComposite::valueTreeType ("Group"); - -const Identifier DrawableComposite::ValueTreeWrapper::topLeft ("topLeft"); -const Identifier DrawableComposite::ValueTreeWrapper::topRight ("topRight"); -const Identifier DrawableComposite::ValueTreeWrapper::bottomLeft ("bottomLeft"); -const Identifier DrawableComposite::ValueTreeWrapper::childGroupTag ("Drawables"); -const Identifier DrawableComposite::ValueTreeWrapper::markerGroupTagX ("MarkersX"); -const Identifier DrawableComposite::ValueTreeWrapper::markerGroupTagY ("MarkersY"); - -//============================================================================== -DrawableComposite::ValueTreeWrapper::ValueTreeWrapper (const ValueTree& state_) - : ValueTreeWrapperBase (state_) -{ - jassert (state.hasType (valueTreeType)); -} - -ValueTree DrawableComposite::ValueTreeWrapper::getChildList() const -{ - return state.getChildWithName (childGroupTag); -} - -ValueTree DrawableComposite::ValueTreeWrapper::getChildListCreating (UndoManager* undoManager) -{ - return state.getOrCreateChildWithName (childGroupTag, undoManager); -} - -RelativeParallelogram DrawableComposite::ValueTreeWrapper::getBoundingBox() const -{ - return RelativeParallelogram (state.getProperty (topLeft, "0, 0"), - state.getProperty (topRight, "100, 0"), - state.getProperty (bottomLeft, "0, 100")); -} - -void DrawableComposite::ValueTreeWrapper::setBoundingBox (const RelativeParallelogram& newBounds, UndoManager* undoManager) -{ - state.setProperty (topLeft, newBounds.topLeft.toString(), undoManager); - state.setProperty (topRight, newBounds.topRight.toString(), undoManager); - state.setProperty (bottomLeft, newBounds.bottomLeft.toString(), undoManager); -} - -void DrawableComposite::ValueTreeWrapper::resetBoundingBoxToContentArea (UndoManager* undoManager) -{ - const RelativeRectangle content (getContentArea()); - - setBoundingBox (RelativeParallelogram (RelativePoint (content.left, content.top), - RelativePoint (content.right, content.top), - RelativePoint (content.left, content.bottom)), undoManager); -} - -RelativeRectangle DrawableComposite::ValueTreeWrapper::getContentArea() const -{ - MarkerList::ValueTreeWrapper marksX (getMarkerList (true)); - MarkerList::ValueTreeWrapper marksY (getMarkerList (false)); - - return RelativeRectangle (marksX.getMarker (marksX.getMarkerState (0)).position, - marksX.getMarker (marksX.getMarkerState (1)).position, - marksY.getMarker (marksY.getMarkerState (0)).position, - marksY.getMarker (marksY.getMarkerState (1)).position); -} - -void DrawableComposite::ValueTreeWrapper::setContentArea (const RelativeRectangle& newArea, UndoManager* undoManager) -{ - MarkerList::ValueTreeWrapper marksX (getMarkerListCreating (true, nullptr)); - MarkerList::ValueTreeWrapper marksY (getMarkerListCreating (false, nullptr)); - - marksX.setMarker (MarkerList::Marker (contentLeftMarkerName, newArea.left), undoManager); - marksX.setMarker (MarkerList::Marker (contentRightMarkerName, newArea.right), undoManager); - marksY.setMarker (MarkerList::Marker (contentTopMarkerName, newArea.top), undoManager); - marksY.setMarker (MarkerList::Marker (contentBottomMarkerName, newArea.bottom), undoManager); -} - -MarkerList::ValueTreeWrapper DrawableComposite::ValueTreeWrapper::getMarkerList (bool xAxis) const -{ - return state.getChildWithName (xAxis ? markerGroupTagX : markerGroupTagY); -} - -MarkerList::ValueTreeWrapper DrawableComposite::ValueTreeWrapper::getMarkerListCreating (bool xAxis, UndoManager* undoManager) -{ - return state.getOrCreateChildWithName (xAxis ? markerGroupTagX : markerGroupTagY, undoManager); -} - -//============================================================================== -void DrawableComposite::refreshFromValueTree (const ValueTree& tree, ComponentBuilder& builder) -{ - const ValueTreeWrapper wrapper (tree); - setComponentID (wrapper.getID()); - - wrapper.getMarkerList (true).applyTo (markersX); - wrapper.getMarkerList (false).applyTo (markersY); - - setBoundingBox (wrapper.getBoundingBox()); - - builder.updateChildComponents (*this, wrapper.getChildList()); -} - -ValueTree DrawableComposite::createValueTree (ComponentBuilder::ImageProvider* imageProvider) const -{ - ValueTree tree (valueTreeType); - ValueTreeWrapper v (tree); - - v.setID (getComponentID()); - v.setBoundingBox (bounds, nullptr); - - ValueTree childList (v.getChildListCreating (nullptr)); - - for (int i = 0; i < getNumChildComponents(); ++i) - { - const Drawable* const d = dynamic_cast (getChildComponent(i)); - jassert (d != nullptr); // You can't save a mix of Drawables and normal components! - - childList.addChild (d->createValueTree (imageProvider), -1, nullptr); - } - - v.getMarkerListCreating (true, nullptr).readFrom (markersX, nullptr); - v.getMarkerListCreating (false, nullptr).readFrom (markersY, nullptr); - - return tree; -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/drawables/juce_DrawableComposite.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/drawables/juce_DrawableComposite.h deleted file mode 100644 index 1de9111c45..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/drawables/juce_DrawableComposite.h +++ /dev/null @@ -1,156 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_DRAWABLECOMPOSITE_H_INCLUDED -#define JUCE_DRAWABLECOMPOSITE_H_INCLUDED - - -//============================================================================== -/** - A drawable object which acts as a container for a set of other Drawables. - - @see Drawable -*/ -class JUCE_API DrawableComposite : public Drawable -{ -public: - //============================================================================== - /** Creates a composite Drawable. */ - DrawableComposite(); - - /** Creates a copy of a DrawableComposite. */ - DrawableComposite (const DrawableComposite&); - - /** Destructor. */ - ~DrawableComposite(); - - //============================================================================== - /** Sets the parallelogram that defines the target position of the content rectangle when the drawable is rendered. - @see setContentArea - */ - void setBoundingBox (const RelativeParallelogram& newBoundingBox); - - /** Returns the parallelogram that defines the target position of the content rectangle when the drawable is rendered. - @see setBoundingBox - */ - const RelativeParallelogram& getBoundingBox() const noexcept { return bounds; } - - /** Changes the bounding box transform to match the content area, so that any sub-items will - be drawn at their untransformed positions. - */ - void resetBoundingBoxToContentArea(); - - /** Returns the main content rectangle. - The content area is actually defined by the markers named "left", "right", "top" and - "bottom", but this method is a shortcut that returns them all at once. - @see contentLeftMarkerName, contentRightMarkerName, contentTopMarkerName, contentBottomMarkerName - */ - RelativeRectangle getContentArea() const; - - /** Changes the main content area. - The content area is actually defined by the markers named "left", "right", "top" and - "bottom", but this method is a shortcut that sets them all at once. - @see setBoundingBox, contentLeftMarkerName, contentRightMarkerName, contentTopMarkerName, contentBottomMarkerName - */ - void setContentArea (const RelativeRectangle& newArea); - - /** Resets the content area and the bounding transform to fit around the area occupied - by the child components (ignoring any markers). - */ - void resetContentAreaAndBoundingBoxToFitChildren(); - - //============================================================================== - /** The name of the marker that defines the left edge of the content area. */ - static const char* const contentLeftMarkerName; - /** The name of the marker that defines the right edge of the content area. */ - static const char* const contentRightMarkerName; - /** The name of the marker that defines the top edge of the content area. */ - static const char* const contentTopMarkerName; - /** The name of the marker that defines the bottom edge of the content area. */ - static const char* const contentBottomMarkerName; - - //============================================================================== - /** @internal */ - Drawable* createCopy() const; - /** @internal */ - void refreshFromValueTree (const ValueTree& tree, ComponentBuilder& builder); - /** @internal */ - ValueTree createValueTree (ComponentBuilder::ImageProvider* imageProvider) const; - /** @internal */ - static const Identifier valueTreeType; - /** @internal */ - Rectangle getDrawableBounds() const; - /** @internal */ - void childBoundsChanged (Component*) override; - /** @internal */ - void childrenChanged() override; - /** @internal */ - void parentHierarchyChanged() override; - /** @internal */ - MarkerList* getMarkers (bool xAxis) override; - - //============================================================================== - /** Internally-used class for wrapping a DrawableComposite's state into a ValueTree. */ - class ValueTreeWrapper : public Drawable::ValueTreeWrapperBase - { - public: - ValueTreeWrapper (const ValueTree& state); - - ValueTree getChildList() const; - ValueTree getChildListCreating (UndoManager* undoManager); - - RelativeParallelogram getBoundingBox() const; - void setBoundingBox (const RelativeParallelogram& newBounds, UndoManager* undoManager); - void resetBoundingBoxToContentArea (UndoManager* undoManager); - - RelativeRectangle getContentArea() const; - void setContentArea (const RelativeRectangle& newArea, UndoManager* undoManager); - - MarkerList::ValueTreeWrapper getMarkerList (bool xAxis) const; - MarkerList::ValueTreeWrapper getMarkerListCreating (bool xAxis, UndoManager* undoManager); - - static const Identifier topLeft, topRight, bottomLeft; - - private: - static const Identifier childGroupTag, markerGroupTagX, markerGroupTagY; - }; - -private: - //============================================================================== - RelativeParallelogram bounds; - MarkerList markersX, markersY; - bool updateBoundsReentrant; - - friend class Drawable::Positioner; - bool registerCoordinates (RelativeCoordinatePositionerBase&); - void recalculateCoordinates (Expression::Scope*); - - void updateBoundsToFitChildren(); - - DrawableComposite& operator= (const DrawableComposite&); - JUCE_LEAK_DETECTOR (DrawableComposite) -}; - - -#endif // JUCE_DRAWABLECOMPOSITE_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/drawables/juce_DrawableImage.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/drawables/juce_DrawableImage.cpp deleted file mode 100644 index 7c29dee045..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/drawables/juce_DrawableImage.cpp +++ /dev/null @@ -1,289 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -DrawableImage::DrawableImage() - : opacity (1.0f), - overlayColour (0x00000000) -{ - bounds.topRight = RelativePoint (Point (1.0f, 0.0f)); - bounds.bottomLeft = RelativePoint (Point (0.0f, 1.0f)); -} - -DrawableImage::DrawableImage (const DrawableImage& other) - : Drawable (other), - image (other.image), - opacity (other.opacity), - overlayColour (other.overlayColour), - bounds (other.bounds) -{ -} - -DrawableImage::~DrawableImage() -{ -} - -//============================================================================== -void DrawableImage::setImage (const Image& imageToUse) -{ - image = imageToUse; - setBounds (imageToUse.getBounds()); - - bounds.topLeft = RelativePoint (Point (0.0f, 0.0f)); - bounds.topRight = RelativePoint (Point ((float) image.getWidth(), 0.0f)); - bounds.bottomLeft = RelativePoint (Point (0.0f, (float) image.getHeight())); - recalculateCoordinates (nullptr); - - repaint(); -} - -void DrawableImage::setOpacity (const float newOpacity) -{ - opacity = newOpacity; -} - -void DrawableImage::setOverlayColour (Colour newOverlayColour) -{ - overlayColour = newOverlayColour; -} - -void DrawableImage::setBoundingBox (const RelativeParallelogram& newBounds) -{ - if (bounds != newBounds) - { - bounds = newBounds; - - if (bounds.isDynamic()) - { - Drawable::Positioner* const p = new Drawable::Positioner (*this); - setPositioner (p); - p->apply(); - } - else - { - setPositioner (nullptr); - recalculateCoordinates (nullptr); - } - } -} - -//============================================================================== -bool DrawableImage::registerCoordinates (RelativeCoordinatePositionerBase& pos) -{ - bool ok = pos.addPoint (bounds.topLeft); - ok = pos.addPoint (bounds.topRight) && ok; - return pos.addPoint (bounds.bottomLeft) && ok; -} - -void DrawableImage::recalculateCoordinates (Expression::Scope* scope) -{ - if (image.isValid()) - { - Point resolved[3]; - bounds.resolveThreePoints (resolved, scope); - - const Point tr (resolved[0] + (resolved[1] - resolved[0]) / (float) image.getWidth()); - const Point bl (resolved[0] + (resolved[2] - resolved[0]) / (float) image.getHeight()); - - AffineTransform t (AffineTransform::fromTargetPoints (resolved[0].x, resolved[0].y, - tr.x, tr.y, - bl.x, bl.y)); - - if (t.isSingularity()) - t = AffineTransform::identity; - - setTransform (t); - } -} - -//============================================================================== -void DrawableImage::paint (Graphics& g) -{ - if (image.isValid()) - { - if (opacity > 0.0f && ! overlayColour.isOpaque()) - { - g.setOpacity (opacity); - g.drawImageAt (image, 0, 0, false); - } - - if (! overlayColour.isTransparent()) - { - g.setColour (overlayColour.withMultipliedAlpha (opacity)); - g.drawImageAt (image, 0, 0, true); - } - } -} - -Rectangle DrawableImage::getDrawableBounds() const -{ - return image.getBounds().toFloat(); -} - -bool DrawableImage::hitTest (int x, int y) -{ - return Drawable::hitTest (x, y) && image.isValid() && image.getPixelAt (x, y).getAlpha() >= 127; -} - -Drawable* DrawableImage::createCopy() const -{ - return new DrawableImage (*this); -} - -//============================================================================== -const Identifier DrawableImage::valueTreeType ("Image"); - -const Identifier DrawableImage::ValueTreeWrapper::opacity ("opacity"); -const Identifier DrawableImage::ValueTreeWrapper::overlay ("overlay"); -const Identifier DrawableImage::ValueTreeWrapper::image ("image"); -const Identifier DrawableImage::ValueTreeWrapper::topLeft ("topLeft"); -const Identifier DrawableImage::ValueTreeWrapper::topRight ("topRight"); -const Identifier DrawableImage::ValueTreeWrapper::bottomLeft ("bottomLeft"); - -//============================================================================== -DrawableImage::ValueTreeWrapper::ValueTreeWrapper (const ValueTree& state_) - : ValueTreeWrapperBase (state_) -{ - jassert (state.hasType (valueTreeType)); -} - -var DrawableImage::ValueTreeWrapper::getImageIdentifier() const -{ - return state [image]; -} - -Value DrawableImage::ValueTreeWrapper::getImageIdentifierValue (UndoManager* undoManager) -{ - return state.getPropertyAsValue (image, undoManager); -} - -void DrawableImage::ValueTreeWrapper::setImageIdentifier (const var& newIdentifier, UndoManager* undoManager) -{ - state.setProperty (image, newIdentifier, undoManager); -} - -float DrawableImage::ValueTreeWrapper::getOpacity() const -{ - return (float) state.getProperty (opacity, 1.0); -} - -Value DrawableImage::ValueTreeWrapper::getOpacityValue (UndoManager* undoManager) -{ - if (! state.hasProperty (opacity)) - state.setProperty (opacity, 1.0, undoManager); - - return state.getPropertyAsValue (opacity, undoManager); -} - -void DrawableImage::ValueTreeWrapper::setOpacity (float newOpacity, UndoManager* undoManager) -{ - state.setProperty (opacity, newOpacity, undoManager); -} - -Colour DrawableImage::ValueTreeWrapper::getOverlayColour() const -{ - return Colour::fromString (state [overlay].toString()); -} - -void DrawableImage::ValueTreeWrapper::setOverlayColour (Colour newColour, UndoManager* undoManager) -{ - if (newColour.isTransparent()) - state.removeProperty (overlay, undoManager); - else - state.setProperty (overlay, String::toHexString ((int) newColour.getARGB()), undoManager); -} - -Value DrawableImage::ValueTreeWrapper::getOverlayColourValue (UndoManager* undoManager) -{ - return state.getPropertyAsValue (overlay, undoManager); -} - -RelativeParallelogram DrawableImage::ValueTreeWrapper::getBoundingBox() const -{ - return RelativeParallelogram (state.getProperty (topLeft, "0, 0"), - state.getProperty (topRight, "100, 0"), - state.getProperty (bottomLeft, "0, 100")); -} - -void DrawableImage::ValueTreeWrapper::setBoundingBox (const RelativeParallelogram& newBounds, UndoManager* undoManager) -{ - state.setProperty (topLeft, newBounds.topLeft.toString(), undoManager); - state.setProperty (topRight, newBounds.topRight.toString(), undoManager); - state.setProperty (bottomLeft, newBounds.bottomLeft.toString(), undoManager); -} - - -//============================================================================== -void DrawableImage::refreshFromValueTree (const ValueTree& tree, ComponentBuilder& builder) -{ - const ValueTreeWrapper controller (tree); - setComponentID (controller.getID()); - - const float newOpacity = controller.getOpacity(); - const Colour newOverlayColour (controller.getOverlayColour()); - - Image newImage; - const var imageIdentifier (controller.getImageIdentifier()); - - - jassert (builder.getImageProvider() != 0 || imageIdentifier.isVoid()); // if you're using images, you need to provide something that can load and save them! - - if (builder.getImageProvider() != nullptr) - newImage = builder.getImageProvider()->getImageForIdentifier (imageIdentifier); - - const RelativeParallelogram newBounds (controller.getBoundingBox()); - - if (bounds != newBounds || newOpacity != opacity - || overlayColour != newOverlayColour || image != newImage) - { - repaint(); - opacity = newOpacity; - overlayColour = newOverlayColour; - - if (image != newImage) - setImage (newImage); - - setBoundingBox (newBounds); - } -} - -ValueTree DrawableImage::createValueTree (ComponentBuilder::ImageProvider* imageProvider) const -{ - ValueTree tree (valueTreeType); - ValueTreeWrapper v (tree); - - v.setID (getComponentID()); - v.setOpacity (opacity, nullptr); - v.setOverlayColour (overlayColour, nullptr); - v.setBoundingBox (bounds, nullptr); - - if (image.isValid()) - { - jassert (imageProvider != nullptr); // if you're using images, you need to provide something that can load and save them! - - if (imageProvider != nullptr) - v.setImageIdentifier (imageProvider->getIdentifierForImage (image), nullptr); - } - - return tree; -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/drawables/juce_DrawableImage.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/drawables/juce_DrawableImage.h deleted file mode 100644 index 6089dee8a2..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/drawables/juce_DrawableImage.h +++ /dev/null @@ -1,138 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_DRAWABLEIMAGE_H_INCLUDED -#define JUCE_DRAWABLEIMAGE_H_INCLUDED - - -//============================================================================== -/** - A drawable object which is a bitmap image. - - @see Drawable -*/ -class JUCE_API DrawableImage : public Drawable -{ -public: - //============================================================================== - DrawableImage(); - DrawableImage (const DrawableImage&); - - /** Destructor. */ - ~DrawableImage(); - - //============================================================================== - /** Sets the image that this drawable will render. */ - void setImage (const Image& imageToUse); - - /** Returns the current image. */ - const Image& getImage() const noexcept { return image; } - - /** Sets the opacity to use when drawing the image. */ - void setOpacity (float newOpacity); - - /** Returns the image's opacity. */ - float getOpacity() const noexcept { return opacity; } - - /** Sets a colour to draw over the image's alpha channel. - - By default this is transparent so isn't drawn, but if you set a non-transparent - colour here, then it will be overlaid on the image, using the image's alpha - channel as a mask. - - This is handy for doing things like darkening or lightening an image by overlaying - it with semi-transparent black or white. - */ - void setOverlayColour (Colour newOverlayColour); - - /** Returns the overlay colour. */ - Colour getOverlayColour() const noexcept { return overlayColour; } - - /** Sets the bounding box within which the image should be displayed. */ - void setBoundingBox (const RelativeParallelogram& newBounds); - - /** Returns the position to which the image's top-left corner should be remapped in the target - coordinate space when rendering this object. - @see setTransform - */ - const RelativeParallelogram& getBoundingBox() const noexcept { return bounds; } - - //============================================================================== - /** @internal */ - void paint (Graphics&) override; - /** @internal */ - bool hitTest (int x, int y) override; - /** @internal */ - Drawable* createCopy() const override; - /** @internal */ - Rectangle getDrawableBounds() const override; - /** @internal */ - void refreshFromValueTree (const ValueTree& tree, ComponentBuilder&); - /** @internal */ - ValueTree createValueTree (ComponentBuilder::ImageProvider*) const override; - /** @internal */ - static const Identifier valueTreeType; - - //============================================================================== - /** Internally-used class for wrapping a DrawableImage's state into a ValueTree. */ - class ValueTreeWrapper : public Drawable::ValueTreeWrapperBase - { - public: - ValueTreeWrapper (const ValueTree& state); - - var getImageIdentifier() const; - void setImageIdentifier (const var&, UndoManager*); - Value getImageIdentifierValue (UndoManager*); - - float getOpacity() const; - void setOpacity (float newOpacity, UndoManager*); - Value getOpacityValue (UndoManager*); - - Colour getOverlayColour() const; - void setOverlayColour (Colour newColour, UndoManager*); - Value getOverlayColourValue (UndoManager*); - - RelativeParallelogram getBoundingBox() const; - void setBoundingBox (const RelativeParallelogram&, UndoManager*); - - static const Identifier opacity, overlay, image, topLeft, topRight, bottomLeft; - }; - -private: - //============================================================================== - Image image; - float opacity; - Colour overlayColour; - RelativeParallelogram bounds; - - friend class Drawable::Positioner; - bool registerCoordinates (RelativeCoordinatePositionerBase&); - void recalculateCoordinates (Expression::Scope*); - - DrawableImage& operator= (const DrawableImage&); - JUCE_LEAK_DETECTOR (DrawableImage) -}; - - -#endif // JUCE_DRAWABLEIMAGE_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/drawables/juce_DrawablePath.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/drawables/juce_DrawablePath.cpp deleted file mode 100644 index 6dc46ba649..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/drawables/juce_DrawablePath.cpp +++ /dev/null @@ -1,570 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -DrawablePath::DrawablePath() -{ -} - -DrawablePath::DrawablePath (const DrawablePath& other) - : DrawableShape (other) -{ - if (other.relativePath != nullptr) - setPath (*other.relativePath); - else - setPath (other.path); -} - -DrawablePath::~DrawablePath() -{ -} - -Drawable* DrawablePath::createCopy() const -{ - return new DrawablePath (*this); -} - -//============================================================================== -void DrawablePath::setPath (const Path& newPath) -{ - path = newPath; - pathChanged(); -} - -const Path& DrawablePath::getPath() const -{ - return path; -} - -const Path& DrawablePath::getStrokePath() const -{ - return strokePath; -} - -void DrawablePath::applyRelativePath (const RelativePointPath& newRelativePath, Expression::Scope* scope) -{ - Path newPath; - newRelativePath.createPath (newPath, scope); - - if (path != newPath) - { - path.swapWithPath (newPath); - pathChanged(); - } -} - -//============================================================================== -class DrawablePath::RelativePositioner : public RelativeCoordinatePositionerBase -{ -public: - RelativePositioner (DrawablePath& comp) - : RelativeCoordinatePositionerBase (comp), - owner (comp) - { - } - - bool registerCoordinates() - { - bool ok = true; - - jassert (owner.relativePath != nullptr); - const RelativePointPath& path = *owner.relativePath; - - for (int i = 0; i < path.elements.size(); ++i) - { - RelativePointPath::ElementBase* const e = path.elements.getUnchecked(i); - - int numPoints; - RelativePoint* const points = e->getControlPoints (numPoints); - - for (int j = numPoints; --j >= 0;) - ok = addPoint (points[j]) && ok; - } - - return ok; - } - - void applyToComponentBounds() - { - jassert (owner.relativePath != nullptr); - - ComponentScope scope (getComponent()); - owner.applyRelativePath (*owner.relativePath, &scope); - } - - void applyNewBounds (const Rectangle&) - { - jassertfalse; // drawables can't be resized directly! - } - -private: - DrawablePath& owner; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (RelativePositioner) -}; - -void DrawablePath::setPath (const RelativePointPath& newRelativePath) -{ - if (newRelativePath.containsAnyDynamicPoints()) - { - if (relativePath == nullptr || newRelativePath != *relativePath) - { - relativePath = new RelativePointPath (newRelativePath); - - RelativePositioner* const p = new RelativePositioner (*this); - setPositioner (p); - p->apply(); - } - } - else - { - relativePath = nullptr; - applyRelativePath (newRelativePath, nullptr); - } -} - -//============================================================================== -const Identifier DrawablePath::valueTreeType ("Path"); - -const Identifier DrawablePath::ValueTreeWrapper::nonZeroWinding ("nonZeroWinding"); -const Identifier DrawablePath::ValueTreeWrapper::point1 ("p1"); -const Identifier DrawablePath::ValueTreeWrapper::point2 ("p2"); -const Identifier DrawablePath::ValueTreeWrapper::point3 ("p3"); - -//============================================================================== -DrawablePath::ValueTreeWrapper::ValueTreeWrapper (const ValueTree& state_) - : FillAndStrokeState (state_) -{ - jassert (state.hasType (valueTreeType)); -} - -ValueTree DrawablePath::ValueTreeWrapper::getPathState() -{ - return state.getOrCreateChildWithName (path, nullptr); -} - -bool DrawablePath::ValueTreeWrapper::usesNonZeroWinding() const -{ - return state [nonZeroWinding]; -} - -void DrawablePath::ValueTreeWrapper::setUsesNonZeroWinding (bool b, UndoManager* undoManager) -{ - state.setProperty (nonZeroWinding, b, undoManager); -} - -void DrawablePath::ValueTreeWrapper::readFrom (const RelativePointPath& p, UndoManager* undoManager) -{ - setUsesNonZeroWinding (p.usesNonZeroWinding, undoManager); - - ValueTree pathTree (getPathState()); - pathTree.removeAllChildren (undoManager); - - for (int i = 0; i < p.elements.size(); ++i) - pathTree.addChild (p.elements.getUnchecked(i)->createTree(), -1, undoManager); -} - -void DrawablePath::ValueTreeWrapper::writeTo (RelativePointPath& p) const -{ - p.usesNonZeroWinding = usesNonZeroWinding(); - RelativePoint points[3]; - - const ValueTree pathTree (state.getChildWithName (path)); - const int num = pathTree.getNumChildren(); - for (int i = 0; i < num; ++i) - { - const Element e (pathTree.getChild(i)); - - const int numCps = e.getNumControlPoints(); - for (int j = 0; j < numCps; ++j) - points[j] = e.getControlPoint (j); - - RelativePointPath::ElementBase* newElement = nullptr; - const Identifier t (e.getType()); - - if (t == Element::startSubPathElement) newElement = new RelativePointPath::StartSubPath (points[0]); - else if (t == Element::closeSubPathElement) newElement = new RelativePointPath::CloseSubPath(); - else if (t == Element::lineToElement) newElement = new RelativePointPath::LineTo (points[0]); - else if (t == Element::quadraticToElement) newElement = new RelativePointPath::QuadraticTo (points[0], points[1]); - else if (t == Element::cubicToElement) newElement = new RelativePointPath::CubicTo (points[0], points[1], points[2]); - else jassertfalse; - - p.addElement (newElement); - } -} - -//============================================================================== -const Identifier DrawablePath::ValueTreeWrapper::Element::mode ("mode"); -const Identifier DrawablePath::ValueTreeWrapper::Element::startSubPathElement ("Move"); -const Identifier DrawablePath::ValueTreeWrapper::Element::closeSubPathElement ("Close"); -const Identifier DrawablePath::ValueTreeWrapper::Element::lineToElement ("Line"); -const Identifier DrawablePath::ValueTreeWrapper::Element::quadraticToElement ("Quad"); -const Identifier DrawablePath::ValueTreeWrapper::Element::cubicToElement ("Cubic"); - -const char* DrawablePath::ValueTreeWrapper::Element::cornerMode = "corner"; -const char* DrawablePath::ValueTreeWrapper::Element::roundedMode = "round"; -const char* DrawablePath::ValueTreeWrapper::Element::symmetricMode = "symm"; - -DrawablePath::ValueTreeWrapper::Element::Element (const ValueTree& state_) - : state (state_) -{ -} - -DrawablePath::ValueTreeWrapper::Element::~Element() -{ -} - -DrawablePath::ValueTreeWrapper DrawablePath::ValueTreeWrapper::Element::getParent() const -{ - return ValueTreeWrapper (state.getParent().getParent()); -} - -DrawablePath::ValueTreeWrapper::Element DrawablePath::ValueTreeWrapper::Element::getPreviousElement() const -{ - return Element (state.getSibling (-1)); -} - -int DrawablePath::ValueTreeWrapper::Element::getNumControlPoints() const noexcept -{ - const Identifier i (state.getType()); - if (i == startSubPathElement || i == lineToElement) return 1; - if (i == quadraticToElement) return 2; - if (i == cubicToElement) return 3; - return 0; -} - -RelativePoint DrawablePath::ValueTreeWrapper::Element::getControlPoint (const int index) const -{ - jassert (index >= 0 && index < getNumControlPoints()); - return RelativePoint (state [index == 0 ? point1 : (index == 1 ? point2 : point3)].toString()); -} - -Value DrawablePath::ValueTreeWrapper::Element::getControlPointValue (int index, UndoManager* undoManager) -{ - jassert (index >= 0 && index < getNumControlPoints()); - return state.getPropertyAsValue (index == 0 ? point1 : (index == 1 ? point2 : point3), undoManager); -} - -void DrawablePath::ValueTreeWrapper::Element::setControlPoint (const int index, const RelativePoint& point, UndoManager* undoManager) -{ - jassert (index >= 0 && index < getNumControlPoints()); - state.setProperty (index == 0 ? point1 : (index == 1 ? point2 : point3), point.toString(), undoManager); -} - -RelativePoint DrawablePath::ValueTreeWrapper::Element::getStartPoint() const -{ - const Identifier i (state.getType()); - - if (i == startSubPathElement) - return getControlPoint (0); - - jassert (i == lineToElement || i == quadraticToElement || i == cubicToElement || i == closeSubPathElement); - - return getPreviousElement().getEndPoint(); -} - -RelativePoint DrawablePath::ValueTreeWrapper::Element::getEndPoint() const -{ - const Identifier i (state.getType()); - if (i == startSubPathElement || i == lineToElement) return getControlPoint (0); - if (i == quadraticToElement) return getControlPoint (1); - if (i == cubicToElement) return getControlPoint (2); - - jassert (i == closeSubPathElement); - return RelativePoint(); -} - -float DrawablePath::ValueTreeWrapper::Element::getLength (Expression::Scope* scope) const -{ - const Identifier i (state.getType()); - - if (i == lineToElement || i == closeSubPathElement) - return getEndPoint().resolve (scope).getDistanceFrom (getStartPoint().resolve (scope)); - - if (i == cubicToElement) - { - Path p; - p.startNewSubPath (getStartPoint().resolve (scope)); - p.cubicTo (getControlPoint (0).resolve (scope), getControlPoint (1).resolve (scope), getControlPoint (2).resolve (scope)); - return p.getLength(); - } - - if (i == quadraticToElement) - { - Path p; - p.startNewSubPath (getStartPoint().resolve (scope)); - p.quadraticTo (getControlPoint (0).resolve (scope), getControlPoint (1).resolve (scope)); - return p.getLength(); - } - - jassert (i == startSubPathElement); - return 0; -} - -String DrawablePath::ValueTreeWrapper::Element::getModeOfEndPoint() const -{ - return state [mode].toString(); -} - -void DrawablePath::ValueTreeWrapper::Element::setModeOfEndPoint (const String& newMode, UndoManager* undoManager) -{ - if (state.hasType (cubicToElement)) - state.setProperty (mode, newMode, undoManager); -} - -void DrawablePath::ValueTreeWrapper::Element::convertToLine (UndoManager* undoManager) -{ - const Identifier i (state.getType()); - - if (i == quadraticToElement || i == cubicToElement) - { - ValueTree newState (lineToElement); - Element e (newState); - e.setControlPoint (0, getEndPoint(), undoManager); - state = newState; - } -} - -void DrawablePath::ValueTreeWrapper::Element::convertToCubic (Expression::Scope* scope, UndoManager* undoManager) -{ - const Identifier i (state.getType()); - - if (i == lineToElement || i == quadraticToElement) - { - ValueTree newState (cubicToElement); - Element e (newState); - - const RelativePoint start (getStartPoint()); - const RelativePoint end (getEndPoint()); - const Point startResolved (start.resolve (scope)); - const Point endResolved (end.resolve (scope)); - e.setControlPoint (0, startResolved + (endResolved - startResolved) * 0.3f, undoManager); - e.setControlPoint (1, startResolved + (endResolved - startResolved) * 0.7f, undoManager); - e.setControlPoint (2, end, undoManager); - - state = newState; - } -} - -void DrawablePath::ValueTreeWrapper::Element::convertToPathBreak (UndoManager* undoManager) -{ - const Identifier i (state.getType()); - - if (i != startSubPathElement) - { - ValueTree newState (startSubPathElement); - Element e (newState); - e.setControlPoint (0, getEndPoint(), undoManager); - state = newState; - } -} - -namespace DrawablePathHelpers -{ - static Point findCubicSubdivisionPoint (float proportion, const Point points[4]) - { - const Point mid1 (points[0] + (points[1] - points[0]) * proportion), - mid2 (points[1] + (points[2] - points[1]) * proportion), - mid3 (points[2] + (points[3] - points[2]) * proportion); - - const Point newCp1 (mid1 + (mid2 - mid1) * proportion), - newCp2 (mid2 + (mid3 - mid2) * proportion); - - return newCp1 + (newCp2 - newCp1) * proportion; - } - - static Point findQuadraticSubdivisionPoint (float proportion, const Point points[3]) - { - const Point mid1 (points[0] + (points[1] - points[0]) * proportion), - mid2 (points[1] + (points[2] - points[1]) * proportion); - - return mid1 + (mid2 - mid1) * proportion; - } -} - -float DrawablePath::ValueTreeWrapper::Element::findProportionAlongLine (Point targetPoint, Expression::Scope* scope) const -{ - using namespace DrawablePathHelpers; - const Identifier pointType (state.getType()); - float bestProp = 0; - - if (pointType == cubicToElement) - { - RelativePoint rp1 (getStartPoint()), rp2 (getControlPoint (0)), rp3 (getControlPoint (1)), rp4 (getEndPoint()); - - const Point points[] = { rp1.resolve (scope), rp2.resolve (scope), rp3.resolve (scope), rp4.resolve (scope) }; - - float bestDistance = std::numeric_limits::max(); - - for (int i = 110; --i >= 0;) - { - float prop = i > 10 ? ((i - 10) / 100.0f) : (bestProp + ((i - 5) / 1000.0f)); - const Point centre (findCubicSubdivisionPoint (prop, points)); - const float distance = centre.getDistanceFrom (targetPoint); - - if (distance < bestDistance) - { - bestProp = prop; - bestDistance = distance; - } - } - } - else if (pointType == quadraticToElement) - { - RelativePoint rp1 (getStartPoint()), rp2 (getControlPoint (0)), rp3 (getEndPoint()); - const Point points[] = { rp1.resolve (scope), rp2.resolve (scope), rp3.resolve (scope) }; - - float bestDistance = std::numeric_limits::max(); - - for (int i = 110; --i >= 0;) - { - float prop = i > 10 ? ((i - 10) / 100.0f) : (bestProp + ((i - 5) / 1000.0f)); - const Point centre (findQuadraticSubdivisionPoint ((float) prop, points)); - const float distance = centre.getDistanceFrom (targetPoint); - - if (distance < bestDistance) - { - bestProp = prop; - bestDistance = distance; - } - } - } - else if (pointType == lineToElement) - { - RelativePoint rp1 (getStartPoint()), rp2 (getEndPoint()); - const Line line (rp1.resolve (scope), rp2.resolve (scope)); - bestProp = line.findNearestProportionalPositionTo (targetPoint); - } - - return bestProp; -} - -ValueTree DrawablePath::ValueTreeWrapper::Element::insertPoint (Point targetPoint, Expression::Scope* scope, UndoManager* undoManager) -{ - ValueTree newTree; - const Identifier pointType (state.getType()); - - if (pointType == cubicToElement) - { - float bestProp = findProportionAlongLine (targetPoint, scope); - - RelativePoint rp1 (getStartPoint()), rp2 (getControlPoint (0)), rp3 (getControlPoint (1)), rp4 (getEndPoint()); - const Point points[] = { rp1.resolve (scope), rp2.resolve (scope), rp3.resolve (scope), rp4.resolve (scope) }; - - const Point mid1 (points[0] + (points[1] - points[0]) * bestProp), - mid2 (points[1] + (points[2] - points[1]) * bestProp), - mid3 (points[2] + (points[3] - points[2]) * bestProp); - - const Point newCp1 (mid1 + (mid2 - mid1) * bestProp), - newCp2 (mid2 + (mid3 - mid2) * bestProp); - - const Point newCentre (newCp1 + (newCp2 - newCp1) * bestProp); - - setControlPoint (0, mid1, undoManager); - setControlPoint (1, newCp1, undoManager); - setControlPoint (2, newCentre, undoManager); - setModeOfEndPoint (roundedMode, undoManager); - - Element newElement (newTree = ValueTree (cubicToElement)); - newElement.setControlPoint (0, newCp2, nullptr); - newElement.setControlPoint (1, mid3, nullptr); - newElement.setControlPoint (2, rp4, nullptr); - - state.getParent().addChild (newTree, state.getParent().indexOf (state) + 1, undoManager); - } - else if (pointType == quadraticToElement) - { - float bestProp = findProportionAlongLine (targetPoint, scope); - - RelativePoint rp1 (getStartPoint()), rp2 (getControlPoint (0)), rp3 (getEndPoint()); - const Point points[] = { rp1.resolve (scope), rp2.resolve (scope), rp3.resolve (scope) }; - - const Point mid1 (points[0] + (points[1] - points[0]) * bestProp), - mid2 (points[1] + (points[2] - points[1]) * bestProp); - - const Point newCentre (mid1 + (mid2 - mid1) * bestProp); - - setControlPoint (0, mid1, undoManager); - setControlPoint (1, newCentre, undoManager); - setModeOfEndPoint (roundedMode, undoManager); - - Element newElement (newTree = ValueTree (quadraticToElement)); - newElement.setControlPoint (0, mid2, nullptr); - newElement.setControlPoint (1, rp3, nullptr); - - state.getParent().addChild (newTree, state.getParent().indexOf (state) + 1, undoManager); - } - else if (pointType == lineToElement) - { - RelativePoint rp1 (getStartPoint()), rp2 (getEndPoint()); - const Line line (rp1.resolve (scope), rp2.resolve (scope)); - const Point newPoint (line.findNearestPointTo (targetPoint)); - - setControlPoint (0, newPoint, undoManager); - - Element newElement (newTree = ValueTree (lineToElement)); - newElement.setControlPoint (0, rp2, nullptr); - - state.getParent().addChild (newTree, state.getParent().indexOf (state) + 1, undoManager); - } - else if (pointType == closeSubPathElement) - { - } - - return newTree; -} - -void DrawablePath::ValueTreeWrapper::Element::removePoint (UndoManager* undoManager) -{ - state.getParent().removeChild (state, undoManager); -} - -//============================================================================== -void DrawablePath::refreshFromValueTree (const ValueTree& tree, ComponentBuilder& builder) -{ - ValueTreeWrapper v (tree); - setComponentID (v.getID()); - - refreshFillTypes (v, builder.getImageProvider()); - setStrokeType (v.getStrokeType()); - - RelativePointPath newRelativePath; - v.writeTo (newRelativePath); - setPath (newRelativePath); -} - -ValueTree DrawablePath::createValueTree (ComponentBuilder::ImageProvider* imageProvider) const -{ - ValueTree tree (valueTreeType); - ValueTreeWrapper v (tree); - - v.setID (getComponentID()); - writeTo (v, imageProvider, nullptr); - - if (relativePath != nullptr) - v.readFrom (*relativePath, nullptr); - else - v.readFrom (RelativePointPath (path), nullptr); - - return tree; -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/drawables/juce_DrawablePath.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/drawables/juce_DrawablePath.h deleted file mode 100644 index bed3895d1c..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/drawables/juce_DrawablePath.h +++ /dev/null @@ -1,145 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_DRAWABLEPATH_H_INCLUDED -#define JUCE_DRAWABLEPATH_H_INCLUDED - - -//============================================================================== -/** - A drawable object which renders a filled or outlined shape. - - For details on how to change the fill and stroke, see the DrawableShape class. - - @see Drawable, DrawableShape -*/ -class JUCE_API DrawablePath : public DrawableShape -{ -public: - //============================================================================== - /** Creates a DrawablePath. */ - DrawablePath(); - DrawablePath (const DrawablePath&); - - /** Destructor. */ - ~DrawablePath(); - - //============================================================================== - /** Changes the path that will be drawn. - @see setFillColour, setStrokeType - */ - void setPath (const Path& newPath); - - /** Sets the path using a RelativePointPath. - Calling this will set up a Component::Positioner to automatically update the path - if any of the points in the source path are dynamic. - */ - void setPath (const RelativePointPath& newPath); - - /** Returns the current path. */ - const Path& getPath() const; - - /** Returns the current path for the outline. */ - const Path& getStrokePath() const; - - //============================================================================== - /** @internal */ - Drawable* createCopy() const; - /** @internal */ - void refreshFromValueTree (const ValueTree& tree, ComponentBuilder& builder); - /** @internal */ - ValueTree createValueTree (ComponentBuilder::ImageProvider* imageProvider) const; - /** @internal */ - static const Identifier valueTreeType; - - //============================================================================== - /** Internally-used class for wrapping a DrawablePath's state into a ValueTree. */ - class ValueTreeWrapper : public DrawableShape::FillAndStrokeState - { - public: - ValueTreeWrapper (const ValueTree& state); - - bool usesNonZeroWinding() const; - void setUsesNonZeroWinding (bool b, UndoManager* undoManager); - - class Element - { - public: - explicit Element (const ValueTree& state); - ~Element(); - - const Identifier getType() const noexcept { return state.getType(); } - int getNumControlPoints() const noexcept; - - RelativePoint getControlPoint (int index) const; - Value getControlPointValue (int index, UndoManager*); - RelativePoint getStartPoint() const; - RelativePoint getEndPoint() const; - void setControlPoint (int index, const RelativePoint& point, UndoManager*); - float getLength (Expression::Scope*) const; - - ValueTreeWrapper getParent() const; - Element getPreviousElement() const; - - String getModeOfEndPoint() const; - void setModeOfEndPoint (const String& newMode, UndoManager*); - - void convertToLine (UndoManager*); - void convertToCubic (Expression::Scope*, UndoManager*); - void convertToPathBreak (UndoManager* undoManager); - ValueTree insertPoint (Point targetPoint, Expression::Scope*, UndoManager*); - void removePoint (UndoManager* undoManager); - float findProportionAlongLine (Point targetPoint, Expression::Scope*) const; - - static const Identifier mode, startSubPathElement, closeSubPathElement, - lineToElement, quadraticToElement, cubicToElement; - static const char* cornerMode; - static const char* roundedMode; - static const char* symmetricMode; - - ValueTree state; - }; - - ValueTree getPathState(); - - void readFrom (const RelativePointPath& path, UndoManager* undoManager); - void writeTo (RelativePointPath& path) const; - - static const Identifier nonZeroWinding, point1, point2, point3; - }; - -private: - //============================================================================== - ScopedPointer relativePath; - - class RelativePositioner; - friend class RelativePositioner; - void applyRelativePath (const RelativePointPath&, Expression::Scope*); - - DrawablePath& operator= (const DrawablePath&); - JUCE_LEAK_DETECTOR (DrawablePath) -}; - - -#endif // JUCE_DRAWABLEPATH_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/drawables/juce_DrawableRectangle.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/drawables/juce_DrawableRectangle.cpp deleted file mode 100644 index 5a8c1c85e4..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/drawables/juce_DrawableRectangle.cpp +++ /dev/null @@ -1,182 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -DrawableRectangle::DrawableRectangle() -{ -} - -DrawableRectangle::DrawableRectangle (const DrawableRectangle& other) - : DrawableShape (other), - bounds (other.bounds), - cornerSize (other.cornerSize) -{ -} - -DrawableRectangle::~DrawableRectangle() -{ -} - -Drawable* DrawableRectangle::createCopy() const -{ - return new DrawableRectangle (*this); -} - -//============================================================================== -void DrawableRectangle::setRectangle (const RelativeParallelogram& newBounds) -{ - if (bounds != newBounds) - { - bounds = newBounds; - rebuildPath(); - } -} - -void DrawableRectangle::setCornerSize (const RelativePoint& newSize) -{ - if (cornerSize != newSize) - { - cornerSize = newSize; - rebuildPath(); - } -} - -void DrawableRectangle::rebuildPath() -{ - if (bounds.isDynamic() || cornerSize.isDynamic()) - { - Drawable::Positioner* const p = new Drawable::Positioner (*this); - setPositioner (p); - p->apply(); - } - else - { - setPositioner (nullptr); - recalculateCoordinates (nullptr); - } -} - -bool DrawableRectangle::registerCoordinates (RelativeCoordinatePositionerBase& pos) -{ - bool ok = pos.addPoint (bounds.topLeft); - ok = pos.addPoint (bounds.topRight) && ok; - ok = pos.addPoint (bounds.bottomLeft) && ok; - return pos.addPoint (cornerSize) && ok; -} - -void DrawableRectangle::recalculateCoordinates (Expression::Scope* scope) -{ - Point points[3]; - bounds.resolveThreePoints (points, scope); - - const float cornerSizeX = (float) cornerSize.x.resolve (scope); - const float cornerSizeY = (float) cornerSize.y.resolve (scope); - - const float w = Line (points[0], points[1]).getLength(); - const float h = Line (points[0], points[2]).getLength(); - - Path newPath; - - if (cornerSizeX > 0 && cornerSizeY > 0) - newPath.addRoundedRectangle (0, 0, w, h, cornerSizeX, cornerSizeY); - else - newPath.addRectangle (0, 0, w, h); - - newPath.applyTransform (AffineTransform::fromTargetPoints (0, 0, points[0].x, points[0].y, - w, 0, points[1].x, points[1].y, - 0, h, points[2].x, points[2].y)); - - if (path != newPath) - { - path.swapWithPath (newPath); - pathChanged(); - } -} - -//============================================================================== -const Identifier DrawableRectangle::valueTreeType ("Rectangle"); -const Identifier DrawableRectangle::ValueTreeWrapper::topLeft ("topLeft"); -const Identifier DrawableRectangle::ValueTreeWrapper::topRight ("topRight"); -const Identifier DrawableRectangle::ValueTreeWrapper::bottomLeft ("bottomLeft"); -const Identifier DrawableRectangle::ValueTreeWrapper::cornerSize ("cornerSize"); - -//============================================================================== -DrawableRectangle::ValueTreeWrapper::ValueTreeWrapper (const ValueTree& state_) - : FillAndStrokeState (state_) -{ - jassert (state.hasType (valueTreeType)); -} - -RelativeParallelogram DrawableRectangle::ValueTreeWrapper::getRectangle() const -{ - return RelativeParallelogram (state.getProperty (topLeft, "0, 0"), - state.getProperty (topRight, "100, 0"), - state.getProperty (bottomLeft, "0, 100")); -} - -void DrawableRectangle::ValueTreeWrapper::setRectangle (const RelativeParallelogram& newBounds, UndoManager* undoManager) -{ - state.setProperty (topLeft, newBounds.topLeft.toString(), undoManager); - state.setProperty (topRight, newBounds.topRight.toString(), undoManager); - state.setProperty (bottomLeft, newBounds.bottomLeft.toString(), undoManager); -} - -void DrawableRectangle::ValueTreeWrapper::setCornerSize (const RelativePoint& newSize, UndoManager* undoManager) -{ - state.setProperty (cornerSize, newSize.toString(), undoManager); -} - -RelativePoint DrawableRectangle::ValueTreeWrapper::getCornerSize() const -{ - return RelativePoint (state [cornerSize]); -} - -Value DrawableRectangle::ValueTreeWrapper::getCornerSizeValue (UndoManager* undoManager) -{ - return state.getPropertyAsValue (cornerSize, undoManager); -} - -//============================================================================== -void DrawableRectangle::refreshFromValueTree (const ValueTree& tree, ComponentBuilder& builder) -{ - ValueTreeWrapper v (tree); - setComponentID (v.getID()); - - refreshFillTypes (v, builder.getImageProvider()); - setStrokeType (v.getStrokeType()); - setRectangle (v.getRectangle()); - setCornerSize (v.getCornerSize()); -} - -ValueTree DrawableRectangle::createValueTree (ComponentBuilder::ImageProvider* imageProvider) const -{ - ValueTree tree (valueTreeType); - ValueTreeWrapper v (tree); - - v.setID (getComponentID()); - writeTo (v, imageProvider, nullptr); - v.setRectangle (bounds, nullptr); - v.setCornerSize (cornerSize, nullptr); - - return tree; -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/drawables/juce_DrawableRectangle.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/drawables/juce_DrawableRectangle.h deleted file mode 100644 index 9bae02e9f8..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/drawables/juce_DrawableRectangle.h +++ /dev/null @@ -1,103 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_DRAWABLERECTANGLE_H_INCLUDED -#define JUCE_DRAWABLERECTANGLE_H_INCLUDED - - -//============================================================================== -/** - A Drawable object which draws a rectangle. - - For details on how to change the fill and stroke, see the DrawableShape class. - - @see Drawable, DrawableShape -*/ -class JUCE_API DrawableRectangle : public DrawableShape -{ -public: - //============================================================================== - DrawableRectangle(); - DrawableRectangle (const DrawableRectangle&); - - /** Destructor. */ - ~DrawableRectangle(); - - //============================================================================== - /** Sets the rectangle's bounds. */ - void setRectangle (const RelativeParallelogram& newBounds); - - /** Returns the rectangle's bounds. */ - const RelativeParallelogram& getRectangle() const noexcept { return bounds; } - - /** Returns the corner size to be used. */ - const RelativePoint& getCornerSize() const noexcept { return cornerSize; } - - /** Sets a new corner size for the rectangle */ - void setCornerSize (const RelativePoint& newSize); - - //============================================================================== - /** @internal */ - Drawable* createCopy() const; - /** @internal */ - void refreshFromValueTree (const ValueTree& tree, ComponentBuilder& builder); - /** @internal */ - ValueTree createValueTree (ComponentBuilder::ImageProvider* imageProvider) const; - /** @internal */ - static const Identifier valueTreeType; - - //============================================================================== - /** Internally-used class for wrapping a DrawableRectangle's state into a ValueTree. */ - class ValueTreeWrapper : public DrawableShape::FillAndStrokeState - { - public: - ValueTreeWrapper (const ValueTree& state); - - RelativeParallelogram getRectangle() const; - void setRectangle (const RelativeParallelogram& newBounds, UndoManager*); - - void setCornerSize (const RelativePoint& cornerSize, UndoManager*); - RelativePoint getCornerSize() const; - Value getCornerSizeValue (UndoManager*); - - static const Identifier topLeft, topRight, bottomLeft, cornerSize; - }; - - -private: - friend class Drawable::Positioner; - - RelativeParallelogram bounds; - RelativePoint cornerSize; - - void rebuildPath(); - bool registerCoordinates (RelativeCoordinatePositionerBase&); - void recalculateCoordinates (Expression::Scope*); - - DrawableRectangle& operator= (const DrawableRectangle&); - JUCE_LEAK_DETECTOR (DrawableRectangle) -}; - - -#endif // JUCE_DRAWABLERECTANGLE_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/drawables/juce_DrawableShape.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/drawables/juce_DrawableShape.cpp deleted file mode 100644 index 5813493c81..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/drawables/juce_DrawableShape.cpp +++ /dev/null @@ -1,472 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -DrawableShape::DrawableShape() - : strokeType (0.0f), - mainFill (Colours::black), - strokeFill (Colours::black) -{ -} - -DrawableShape::DrawableShape (const DrawableShape& other) - : Drawable (other), - strokeType (other.strokeType), - mainFill (other.mainFill), - strokeFill (other.strokeFill) -{ -} - -DrawableShape::~DrawableShape() -{ -} - -//============================================================================== -class DrawableShape::RelativePositioner : public RelativeCoordinatePositionerBase -{ -public: - RelativePositioner (DrawableShape& comp, const DrawableShape::RelativeFillType& f, bool isMain) - : RelativeCoordinatePositionerBase (comp), - owner (comp), - fill (f), - isMainFill (isMain) - { - } - - bool registerCoordinates() - { - bool ok = addPoint (fill.gradientPoint1); - ok = addPoint (fill.gradientPoint2) && ok; - return addPoint (fill.gradientPoint3) && ok; - } - - void applyToComponentBounds() - { - ComponentScope scope (owner); - if (isMainFill ? owner.mainFill.recalculateCoords (&scope) - : owner.strokeFill.recalculateCoords (&scope)) - owner.repaint(); - } - - void applyNewBounds (const Rectangle&) - { - jassertfalse; // drawables can't be resized directly! - } - -private: - DrawableShape& owner; - const DrawableShape::RelativeFillType fill; - const bool isMainFill; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (RelativePositioner) -}; - -void DrawableShape::setFill (const FillType& newFill) -{ - setFill (RelativeFillType (newFill)); -} - -void DrawableShape::setStrokeFill (const FillType& newFill) -{ - setStrokeFill (RelativeFillType (newFill)); -} - -void DrawableShape::setFillInternal (RelativeFillType& fill, const RelativeFillType& newFill, - ScopedPointer& pos) -{ - if (fill != newFill) - { - fill = newFill; - pos = nullptr; - - if (fill.isDynamic()) - { - pos = new RelativePositioner (*this, fill, true); - pos->apply(); - } - else - { - fill.recalculateCoords (nullptr); - } - - repaint(); - } -} - -void DrawableShape::setFill (const RelativeFillType& newFill) -{ - setFillInternal (mainFill, newFill, mainFillPositioner); -} - -void DrawableShape::setStrokeFill (const RelativeFillType& newFill) -{ - setFillInternal (strokeFill, newFill, strokeFillPositioner); -} - -void DrawableShape::setStrokeType (const PathStrokeType& newStrokeType) -{ - if (strokeType != newStrokeType) - { - strokeType = newStrokeType; - strokeChanged(); - } -} - -void DrawableShape::setStrokeThickness (const float newThickness) -{ - setStrokeType (PathStrokeType (newThickness, strokeType.getJointStyle(), strokeType.getEndStyle())); -} - -bool DrawableShape::isStrokeVisible() const noexcept -{ - return strokeType.getStrokeThickness() > 0.0f && ! strokeFill.fill.isInvisible(); -} - -void DrawableShape::refreshFillTypes (const FillAndStrokeState& newState, ComponentBuilder::ImageProvider* imageProvider) -{ - setFill (newState.getFill (FillAndStrokeState::fill, imageProvider)); - setStrokeFill (newState.getFill (FillAndStrokeState::stroke, imageProvider)); -} - -void DrawableShape::writeTo (FillAndStrokeState& state, ComponentBuilder::ImageProvider* imageProvider, UndoManager* undoManager) const -{ - state.setFill (FillAndStrokeState::fill, mainFill, imageProvider, undoManager); - state.setFill (FillAndStrokeState::stroke, strokeFill, imageProvider, undoManager); - state.setStrokeType (strokeType, undoManager); -} - -//============================================================================== -void DrawableShape::paint (Graphics& g) -{ - transformContextToCorrectOrigin (g); - - g.setFillType (mainFill.fill); - g.fillPath (path); - - if (isStrokeVisible()) - { - g.setFillType (strokeFill.fill); - g.fillPath (strokePath); - } -} - -void DrawableShape::pathChanged() -{ - strokeChanged(); -} - -void DrawableShape::strokeChanged() -{ - strokePath.clear(); - strokeType.createStrokedPath (strokePath, path, AffineTransform::identity, 4.0f); - - setBoundsToEnclose (getDrawableBounds()); - repaint(); -} - -Rectangle DrawableShape::getDrawableBounds() const -{ - if (isStrokeVisible()) - return strokePath.getBounds(); - - return path.getBounds(); -} - -bool DrawableShape::hitTest (int x, int y) -{ - bool allowsClicksOnThisComponent, allowsClicksOnChildComponents; - getInterceptsMouseClicks (allowsClicksOnThisComponent, allowsClicksOnChildComponents); - - if (! allowsClicksOnThisComponent) - return false; - - const float globalX = (float) (x - originRelativeToComponent.x); - const float globalY = (float) (y - originRelativeToComponent.y); - - return path.contains (globalX, globalY) - || (isStrokeVisible() && strokePath.contains (globalX, globalY)); -} - -//============================================================================== -DrawableShape::RelativeFillType::RelativeFillType() -{ -} - -DrawableShape::RelativeFillType::RelativeFillType (const FillType& fill_) - : fill (fill_) -{ - if (fill.isGradient()) - { - const ColourGradient& g = *fill.gradient; - - gradientPoint1 = g.point1.transformedBy (fill.transform); - gradientPoint2 = g.point2.transformedBy (fill.transform); - gradientPoint3 = Point (g.point1.x + g.point2.y - g.point1.y, - g.point1.y + g.point1.x - g.point2.x) - .transformedBy (fill.transform); - fill.transform = AffineTransform::identity; - } -} - -DrawableShape::RelativeFillType::RelativeFillType (const RelativeFillType& other) - : fill (other.fill), - gradientPoint1 (other.gradientPoint1), - gradientPoint2 (other.gradientPoint2), - gradientPoint3 (other.gradientPoint3) -{ -} - -DrawableShape::RelativeFillType& DrawableShape::RelativeFillType::operator= (const RelativeFillType& other) -{ - fill = other.fill; - gradientPoint1 = other.gradientPoint1; - gradientPoint2 = other.gradientPoint2; - gradientPoint3 = other.gradientPoint3; - return *this; -} - -bool DrawableShape::RelativeFillType::operator== (const RelativeFillType& other) const -{ - return fill == other.fill - && ((! fill.isGradient()) - || (gradientPoint1 == other.gradientPoint1 - && gradientPoint2 == other.gradientPoint2 - && gradientPoint3 == other.gradientPoint3)); -} - -bool DrawableShape::RelativeFillType::operator!= (const RelativeFillType& other) const -{ - return ! operator== (other); -} - -bool DrawableShape::RelativeFillType::recalculateCoords (Expression::Scope* scope) -{ - if (fill.isGradient()) - { - const Point g1 (gradientPoint1.resolve (scope)); - const Point g2 (gradientPoint2.resolve (scope)); - AffineTransform t; - - ColourGradient& g = *fill.gradient; - - if (g.isRadial) - { - const Point g3 (gradientPoint3.resolve (scope)); - const Point g3Source (g1.x + g2.y - g1.y, - g1.y + g1.x - g2.x); - - t = AffineTransform::fromTargetPoints (g1.x, g1.y, g1.x, g1.y, - g2.x, g2.y, g2.x, g2.y, - g3Source.x, g3Source.y, g3.x, g3.y); - } - - if (g.point1 != g1 || g.point2 != g2 || fill.transform != t) - { - g.point1 = g1; - g.point2 = g2; - fill.transform = t; - return true; - } - } - - return false; -} - -bool DrawableShape::RelativeFillType::isDynamic() const -{ - return gradientPoint1.isDynamic() || gradientPoint2.isDynamic() || gradientPoint3.isDynamic(); -} - -void DrawableShape::RelativeFillType::writeTo (ValueTree& v, ComponentBuilder::ImageProvider* imageProvider, UndoManager* undoManager) const -{ - if (fill.isColour()) - { - v.setProperty (FillAndStrokeState::type, "solid", undoManager); - v.setProperty (FillAndStrokeState::colour, String::toHexString ((int) fill.colour.getARGB()), undoManager); - } - else if (fill.isGradient()) - { - v.setProperty (FillAndStrokeState::type, "gradient", undoManager); - v.setProperty (FillAndStrokeState::gradientPoint1, gradientPoint1.toString(), undoManager); - v.setProperty (FillAndStrokeState::gradientPoint2, gradientPoint2.toString(), undoManager); - v.setProperty (FillAndStrokeState::gradientPoint3, gradientPoint3.toString(), undoManager); - - const ColourGradient& cg = *fill.gradient; - v.setProperty (FillAndStrokeState::radial, cg.isRadial, undoManager); - - String s; - for (int i = 0; i < cg.getNumColours(); ++i) - s << ' ' << cg.getColourPosition (i) - << ' ' << String::toHexString ((int) cg.getColour(i).getARGB()); - - v.setProperty (FillAndStrokeState::colours, s.trimStart(), undoManager); - } - else if (fill.isTiledImage()) - { - v.setProperty (FillAndStrokeState::type, "image", undoManager); - - if (imageProvider != nullptr) - v.setProperty (FillAndStrokeState::imageId, imageProvider->getIdentifierForImage (fill.image), undoManager); - - if (fill.getOpacity() < 1.0f) - v.setProperty (FillAndStrokeState::imageOpacity, fill.getOpacity(), undoManager); - else - v.removeProperty (FillAndStrokeState::imageOpacity, undoManager); - } - else - { - jassertfalse; - } -} - -bool DrawableShape::RelativeFillType::readFrom (const ValueTree& v, ComponentBuilder::ImageProvider* imageProvider) -{ - const String newType (v [FillAndStrokeState::type].toString()); - - if (newType == "solid") - { - const String colourString (v [FillAndStrokeState::colour].toString()); - fill.setColour (colourString.isEmpty() ? Colours::black - : Colour::fromString (colourString)); - return true; - } - else if (newType == "gradient") - { - ColourGradient g; - g.isRadial = v [FillAndStrokeState::radial]; - - StringArray colourSteps; - colourSteps.addTokens (v [FillAndStrokeState::colours].toString(), false); - - for (int i = 0; i < colourSteps.size() / 2; ++i) - g.addColour (colourSteps[i * 2].getDoubleValue(), - Colour::fromString (colourSteps[i * 2 + 1])); - - fill.setGradient (g); - - gradientPoint1 = RelativePoint (v [FillAndStrokeState::gradientPoint1]); - gradientPoint2 = RelativePoint (v [FillAndStrokeState::gradientPoint2]); - gradientPoint3 = RelativePoint (v [FillAndStrokeState::gradientPoint3]); - return true; - } - else if (newType == "image") - { - Image im; - if (imageProvider != nullptr) - im = imageProvider->getImageForIdentifier (v [FillAndStrokeState::imageId]); - - fill.setTiledImage (im, AffineTransform::identity); - fill.setOpacity ((float) v.getProperty (FillAndStrokeState::imageOpacity, 1.0f)); - return true; - } - - jassertfalse; - return false; -} - -//============================================================================== -const Identifier DrawableShape::FillAndStrokeState::type ("type"); -const Identifier DrawableShape::FillAndStrokeState::colour ("colour"); -const Identifier DrawableShape::FillAndStrokeState::colours ("colours"); -const Identifier DrawableShape::FillAndStrokeState::fill ("Fill"); -const Identifier DrawableShape::FillAndStrokeState::stroke ("Stroke"); -const Identifier DrawableShape::FillAndStrokeState::path ("Path"); -const Identifier DrawableShape::FillAndStrokeState::jointStyle ("jointStyle"); -const Identifier DrawableShape::FillAndStrokeState::capStyle ("capStyle"); -const Identifier DrawableShape::FillAndStrokeState::strokeWidth ("strokeWidth"); -const Identifier DrawableShape::FillAndStrokeState::gradientPoint1 ("point1"); -const Identifier DrawableShape::FillAndStrokeState::gradientPoint2 ("point2"); -const Identifier DrawableShape::FillAndStrokeState::gradientPoint3 ("point3"); -const Identifier DrawableShape::FillAndStrokeState::radial ("radial"); -const Identifier DrawableShape::FillAndStrokeState::imageId ("imageId"); -const Identifier DrawableShape::FillAndStrokeState::imageOpacity ("imageOpacity"); - -DrawableShape::FillAndStrokeState::FillAndStrokeState (const ValueTree& state_) - : Drawable::ValueTreeWrapperBase (state_) -{ -} - -DrawableShape::RelativeFillType DrawableShape::FillAndStrokeState::getFill (const Identifier& fillOrStrokeType, ComponentBuilder::ImageProvider* imageProvider) const -{ - DrawableShape::RelativeFillType f; - f.readFrom (state.getChildWithName (fillOrStrokeType), imageProvider); - return f; -} - -ValueTree DrawableShape::FillAndStrokeState::getFillState (const Identifier& fillOrStrokeType) -{ - ValueTree v (state.getChildWithName (fillOrStrokeType)); - if (v.isValid()) - return v; - - setFill (fillOrStrokeType, FillType (Colours::black), nullptr, nullptr); - return getFillState (fillOrStrokeType); -} - -void DrawableShape::FillAndStrokeState::setFill (const Identifier& fillOrStrokeType, const RelativeFillType& newFill, - ComponentBuilder::ImageProvider* imageProvider, UndoManager* undoManager) -{ - ValueTree v (state.getOrCreateChildWithName (fillOrStrokeType, undoManager)); - newFill.writeTo (v, imageProvider, undoManager); -} - -PathStrokeType DrawableShape::FillAndStrokeState::getStrokeType() const -{ - const String jointStyleString (state [jointStyle].toString()); - const String capStyleString (state [capStyle].toString()); - - return PathStrokeType (state [strokeWidth], - jointStyleString == "curved" ? PathStrokeType::curved - : (jointStyleString == "bevel" ? PathStrokeType::beveled - : PathStrokeType::mitered), - capStyleString == "square" ? PathStrokeType::square - : (capStyleString == "round" ? PathStrokeType::rounded - : PathStrokeType::butt)); -} - -void DrawableShape::FillAndStrokeState::setStrokeType (const PathStrokeType& newStrokeType, UndoManager* undoManager) -{ - state.setProperty (strokeWidth, (double) newStrokeType.getStrokeThickness(), undoManager); - state.setProperty (jointStyle, newStrokeType.getJointStyle() == PathStrokeType::mitered - ? "miter" : (newStrokeType.getJointStyle() == PathStrokeType::curved ? "curved" : "bevel"), undoManager); - state.setProperty (capStyle, newStrokeType.getEndStyle() == PathStrokeType::butt - ? "butt" : (newStrokeType.getEndStyle() == PathStrokeType::square ? "square" : "round"), undoManager); -} - -static bool replaceColourInFill (DrawableShape::RelativeFillType& fill, Colour original, Colour replacement) -{ - if (fill.fill.colour == original && fill.fill.isColour()) - { - fill = FillType (replacement); - return true; - } - - return false; -} - -bool DrawableShape::replaceColour (Colour original, Colour replacement) -{ - bool changed1 = replaceColourInFill (mainFill, original, replacement); - bool changed2 = replaceColourInFill (strokeFill, original, replacement); - return changed1 || changed2; -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/drawables/juce_DrawableShape.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/drawables/juce_DrawableShape.h deleted file mode 100644 index ed893f14ca..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/drawables/juce_DrawableShape.h +++ /dev/null @@ -1,182 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_DRAWABLESHAPE_H_INCLUDED -#define JUCE_DRAWABLESHAPE_H_INCLUDED - - -//============================================================================== -/** - A base class implementing common functionality for Drawable classes which - consist of some kind of filled and stroked outline. - - @see DrawablePath, DrawableRectangle -*/ -class JUCE_API DrawableShape : public Drawable -{ -protected: - //============================================================================== - DrawableShape(); - DrawableShape (const DrawableShape&); - -public: - /** Destructor. */ - ~DrawableShape(); - - //============================================================================== - /** A FillType wrapper that allows the gradient coordinates to be implemented using RelativePoint. - */ - class RelativeFillType - { - public: - RelativeFillType(); - RelativeFillType (const FillType& fill); - RelativeFillType (const RelativeFillType&); - RelativeFillType& operator= (const RelativeFillType&); - - bool operator== (const RelativeFillType&) const; - bool operator!= (const RelativeFillType&) const; - - bool isDynamic() const; - bool recalculateCoords (Expression::Scope* scope); - - void writeTo (ValueTree& v, ComponentBuilder::ImageProvider*, UndoManager*) const; - bool readFrom (const ValueTree& v, ComponentBuilder::ImageProvider*); - - //============================================================================== - FillType fill; - RelativePoint gradientPoint1, gradientPoint2, gradientPoint3; - }; - - //============================================================================== - /** Sets a fill type for the path. - This colour is used to fill the path - if you don't want the path to be - filled (e.g. if you're just drawing an outline), set this to a transparent - colour. - - @see setPath, setStrokeFill - */ - void setFill (const FillType& newFill); - - /** Sets a fill type for the path. - This colour is used to fill the path - if you don't want the path to be - filled (e.g. if you're just drawing an outline), set this to a transparent - colour. - - @see setPath, setStrokeFill - */ - void setFill (const RelativeFillType& newFill); - - /** Returns the current fill type. - @see setFill - */ - const RelativeFillType& getFill() const noexcept { return mainFill; } - - /** Sets the fill type with which the outline will be drawn. - @see setFill - */ - void setStrokeFill (const FillType& newStrokeFill); - - /** Sets the fill type with which the outline will be drawn. - @see setFill - */ - void setStrokeFill (const RelativeFillType& newStrokeFill); - - /** Returns the current stroke fill. - @see setStrokeFill - */ - const RelativeFillType& getStrokeFill() const noexcept { return strokeFill; } - - /** Changes the properties of the outline that will be drawn around the path. - If the stroke has 0 thickness, no stroke will be drawn. - @see setStrokeThickness, setStrokeColour - */ - void setStrokeType (const PathStrokeType& newStrokeType); - - /** Changes the stroke thickness. - This is a shortcut for calling setStrokeType. - */ - void setStrokeThickness (float newThickness); - - /** Returns the current outline style. */ - const PathStrokeType& getStrokeType() const noexcept { return strokeType; } - - //============================================================================== - /** @internal */ - class FillAndStrokeState : public Drawable::ValueTreeWrapperBase - { - public: - FillAndStrokeState (const ValueTree& state); - - ValueTree getFillState (const Identifier& fillOrStrokeType); - RelativeFillType getFill (const Identifier& fillOrStrokeType, ComponentBuilder::ImageProvider*) const; - void setFill (const Identifier& fillOrStrokeType, const RelativeFillType& newFill, - ComponentBuilder::ImageProvider*, UndoManager*); - - PathStrokeType getStrokeType() const; - void setStrokeType (const PathStrokeType& newStrokeType, UndoManager*); - - static const Identifier type, colour, colours, fill, stroke, path, jointStyle, capStyle, strokeWidth, - gradientPoint1, gradientPoint2, gradientPoint3, radial, imageId, imageOpacity; - }; - - /** @internal */ - Rectangle getDrawableBounds() const override; - /** @internal */ - void paint (Graphics&) override; - /** @internal */ - bool hitTest (int x, int y) override; - /** @internal */ - bool replaceColour (Colour originalColour, Colour replacementColour) override; - -protected: - //============================================================================== - /** Called when the cached path should be updated. */ - void pathChanged(); - /** Called when the cached stroke should be updated. */ - void strokeChanged(); - /** True if there's a stroke with a non-zero thickness and non-transparent colour. */ - bool isStrokeVisible() const noexcept; - /** Updates the details from a FillAndStrokeState object, returning true if something changed. */ - void refreshFillTypes (const FillAndStrokeState& newState, ComponentBuilder::ImageProvider*); - /** Writes the stroke and fill details to a FillAndStrokeState object. */ - void writeTo (FillAndStrokeState& state, ComponentBuilder::ImageProvider*, UndoManager*) const; - - //============================================================================== - PathStrokeType strokeType; - Path path, strokePath; - -private: - class RelativePositioner; - RelativeFillType mainFill, strokeFill; - ScopedPointer mainFillPositioner, strokeFillPositioner; - - void setFillInternal (RelativeFillType& fill, const RelativeFillType& newFill, - ScopedPointer& positioner); - - DrawableShape& operator= (const DrawableShape&); -}; - - -#endif // JUCE_DRAWABLESHAPE_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/drawables/juce_DrawableText.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/drawables/juce_DrawableText.cpp deleted file mode 100644 index e9c980212d..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/drawables/juce_DrawableText.cpp +++ /dev/null @@ -1,334 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -DrawableText::DrawableText() - : colour (Colours::black), - justification (Justification::centredLeft) -{ - setBoundingBox (RelativeParallelogram (RelativePoint (0.0f, 0.0f), - RelativePoint (50.0f, 0.0f), - RelativePoint (0.0f, 20.0f))); - setFont (Font (15.0f), true); -} - -DrawableText::DrawableText (const DrawableText& other) - : Drawable (other), - bounds (other.bounds), - fontHeight (other.fontHeight), - fontHScale (other.fontHScale), - font (other.font), - text (other.text), - colour (other.colour), - justification (other.justification) -{ - refreshBounds(); -} - -DrawableText::~DrawableText() -{ -} - -//============================================================================== -void DrawableText::setText (const String& newText) -{ - if (text != newText) - { - text = newText; - refreshBounds(); - } -} - -void DrawableText::setColour (Colour newColour) -{ - if (colour != newColour) - { - colour = newColour; - repaint(); - } -} - -void DrawableText::setFont (const Font& newFont, bool applySizeAndScale) -{ - if (font != newFont) - { - font = newFont; - - if (applySizeAndScale) - { - fontHeight = font.getHeight(); - fontHScale = font.getHorizontalScale(); - } - - refreshBounds(); - } -} - -void DrawableText::setJustification (Justification newJustification) -{ - justification = newJustification; - repaint(); -} - -void DrawableText::setBoundingBox (const RelativeParallelogram& newBounds) -{ - if (bounds != newBounds) - { - bounds = newBounds; - refreshBounds(); - } -} - -void DrawableText::setFontHeight (const RelativeCoordinate& newHeight) -{ - if (fontHeight != newHeight) - { - fontHeight = newHeight; - refreshBounds(); - } -} - -void DrawableText::setFontHorizontalScale (const RelativeCoordinate& newScale) -{ - if (fontHScale != newScale) - { - fontHScale = newScale; - refreshBounds(); - } -} - -void DrawableText::refreshBounds() -{ - if (bounds.isDynamic() || fontHeight.isDynamic() || fontHScale.isDynamic()) - { - Drawable::Positioner* const p = new Drawable::Positioner (*this); - setPositioner (p); - p->apply(); - } - else - { - setPositioner (0); - recalculateCoordinates (0); - } -} - -bool DrawableText::registerCoordinates (RelativeCoordinatePositionerBase& pos) -{ - bool ok = pos.addPoint (bounds.topLeft); - ok = pos.addPoint (bounds.topRight) && ok; - ok = pos.addPoint (bounds.bottomLeft) && ok; - ok = pos.addCoordinate (fontHeight) && ok; - return pos.addCoordinate (fontHScale) && ok; -} - -void DrawableText::recalculateCoordinates (Expression::Scope* scope) -{ - bounds.resolveThreePoints (resolvedPoints, scope); - - const float w = Line (resolvedPoints[0], resolvedPoints[1]).getLength(); - const float h = Line (resolvedPoints[0], resolvedPoints[2]).getLength(); - - const float height = jlimit (0.01f, jmax (0.01f, h), (float) fontHeight.resolve (scope)); - const float hscale = jlimit (0.01f, jmax (0.01f, w), (float) fontHScale.resolve (scope)); - - scaledFont = font; - scaledFont.setHeight (height); - scaledFont.setHorizontalScale (hscale); - - setBoundsToEnclose (getDrawableBounds()); - repaint(); -} - -//============================================================================== -void DrawableText::paint (Graphics& g) -{ - transformContextToCorrectOrigin (g); - - const float w = Line (resolvedPoints[0], resolvedPoints[1]).getLength(); - const float h = Line (resolvedPoints[0], resolvedPoints[2]).getLength(); - - g.addTransform (AffineTransform::fromTargetPoints (0, 0, resolvedPoints[0].x, resolvedPoints[0].y, - w, 0, resolvedPoints[1].x, resolvedPoints[1].y, - 0, h, resolvedPoints[2].x, resolvedPoints[2].y)); - g.setFont (scaledFont); - g.setColour (colour); - - g.drawFittedText (text, Rectangle (w, h).getSmallestIntegerContainer(), justification, 0x100000); -} - -Rectangle DrawableText::getDrawableBounds() const -{ - return RelativeParallelogram::getBoundingBox (resolvedPoints); -} - -Drawable* DrawableText::createCopy() const -{ - return new DrawableText (*this); -} - -//============================================================================== -const Identifier DrawableText::valueTreeType ("Text"); - -const Identifier DrawableText::ValueTreeWrapper::text ("text"); -const Identifier DrawableText::ValueTreeWrapper::colour ("colour"); -const Identifier DrawableText::ValueTreeWrapper::font ("font"); -const Identifier DrawableText::ValueTreeWrapper::justification ("justification"); -const Identifier DrawableText::ValueTreeWrapper::topLeft ("topLeft"); -const Identifier DrawableText::ValueTreeWrapper::topRight ("topRight"); -const Identifier DrawableText::ValueTreeWrapper::bottomLeft ("bottomLeft"); -const Identifier DrawableText::ValueTreeWrapper::fontHeight ("fontHeight"); -const Identifier DrawableText::ValueTreeWrapper::fontHScale ("fontHScale"); - -//============================================================================== -DrawableText::ValueTreeWrapper::ValueTreeWrapper (const ValueTree& state_) - : ValueTreeWrapperBase (state_) -{ - jassert (state.hasType (valueTreeType)); -} - -String DrawableText::ValueTreeWrapper::getText() const -{ - return state [text].toString(); -} - -void DrawableText::ValueTreeWrapper::setText (const String& newText, UndoManager* undoManager) -{ - state.setProperty (text, newText, undoManager); -} - -Value DrawableText::ValueTreeWrapper::getTextValue (UndoManager* undoManager) -{ - return state.getPropertyAsValue (text, undoManager); -} - -Colour DrawableText::ValueTreeWrapper::getColour() const -{ - return Colour::fromString (state [colour].toString()); -} - -void DrawableText::ValueTreeWrapper::setColour (Colour newColour, UndoManager* undoManager) -{ - state.setProperty (colour, newColour.toString(), undoManager); -} - -Justification DrawableText::ValueTreeWrapper::getJustification() const -{ - return Justification ((int) state [justification]); -} - -void DrawableText::ValueTreeWrapper::setJustification (Justification newJustification, UndoManager* undoManager) -{ - state.setProperty (justification, newJustification.getFlags(), undoManager); -} - -Font DrawableText::ValueTreeWrapper::getFont() const -{ - return Font::fromString (state [font]); -} - -void DrawableText::ValueTreeWrapper::setFont (const Font& newFont, UndoManager* undoManager) -{ - state.setProperty (font, newFont.toString(), undoManager); -} - -Value DrawableText::ValueTreeWrapper::getFontValue (UndoManager* undoManager) -{ - return state.getPropertyAsValue (font, undoManager); -} - -RelativeParallelogram DrawableText::ValueTreeWrapper::getBoundingBox() const -{ - return RelativeParallelogram (state [topLeft].toString(), state [topRight].toString(), state [bottomLeft].toString()); -} - -void DrawableText::ValueTreeWrapper::setBoundingBox (const RelativeParallelogram& newBounds, UndoManager* undoManager) -{ - state.setProperty (topLeft, newBounds.topLeft.toString(), undoManager); - state.setProperty (topRight, newBounds.topRight.toString(), undoManager); - state.setProperty (bottomLeft, newBounds.bottomLeft.toString(), undoManager); -} - -RelativeCoordinate DrawableText::ValueTreeWrapper::getFontHeight() const -{ - return state [fontHeight].toString(); -} - -void DrawableText::ValueTreeWrapper::setFontHeight (const RelativeCoordinate& coord, UndoManager* undoManager) -{ - state.setProperty (fontHeight, coord.toString(), undoManager); -} - -RelativeCoordinate DrawableText::ValueTreeWrapper::getFontHorizontalScale() const -{ - return state [fontHScale].toString(); -} - -void DrawableText::ValueTreeWrapper::setFontHorizontalScale (const RelativeCoordinate& coord, UndoManager* undoManager) -{ - state.setProperty (fontHScale, coord.toString(), undoManager); -} - -//============================================================================== -void DrawableText::refreshFromValueTree (const ValueTree& tree, ComponentBuilder&) -{ - ValueTreeWrapper v (tree); - setComponentID (v.getID()); - - const RelativeParallelogram newBounds (v.getBoundingBox()); - const RelativeCoordinate newFontHeight (v.getFontHeight()); - const RelativeCoordinate newFontHScale (v.getFontHorizontalScale()); - const Colour newColour (v.getColour()); - const Justification newJustification (v.getJustification()); - const String newText (v.getText()); - const Font newFont (v.getFont()); - - if (text != newText || font != newFont || justification != newJustification - || colour != newColour || bounds != newBounds - || newFontHeight != fontHeight || newFontHScale != fontHScale) - { - setBoundingBox (newBounds); - setFontHeight (newFontHeight); - setFontHorizontalScale (newFontHScale); - setColour (newColour); - setFont (newFont, false); - setJustification (newJustification); - setText (newText); - } -} - -ValueTree DrawableText::createValueTree (ComponentBuilder::ImageProvider*) const -{ - ValueTree tree (valueTreeType); - ValueTreeWrapper v (tree); - - v.setID (getComponentID()); - v.setText (text, nullptr); - v.setFont (font, nullptr); - v.setJustification (justification, nullptr); - v.setColour (colour, nullptr); - v.setBoundingBox (bounds, nullptr); - v.setFontHeight (fontHeight, nullptr); - v.setFontHorizontalScale (fontHScale, nullptr); - - return tree; -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/drawables/juce_DrawableText.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/drawables/juce_DrawableText.h deleted file mode 100644 index ac44fb49f1..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/drawables/juce_DrawableText.h +++ /dev/null @@ -1,155 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_DRAWABLETEXT_H_INCLUDED -#define JUCE_DRAWABLETEXT_H_INCLUDED - - -//============================================================================== -/** - A drawable object which renders a line of text. - - @see Drawable -*/ -class JUCE_API DrawableText : public Drawable -{ -public: - //============================================================================== - /** Creates a DrawableText object. */ - DrawableText(); - DrawableText (const DrawableText&); - - /** Destructor. */ - ~DrawableText(); - - //============================================================================== - /** Sets the text to display.*/ - void setText (const String& newText); - - /** Returns the currently displayed text */ - const String& getText() const noexcept { return text;} - - /** Sets the colour of the text. */ - void setColour (Colour newColour); - - /** Returns the current text colour. */ - Colour getColour() const noexcept { return colour; } - - /** Sets the font to use. - Note that the font height and horizontal scale are set as RelativeCoordinates using - setFontHeight and setFontHorizontalScale. If applySizeAndScale is true, then these height - and scale values will be changed to match the dimensions of the font supplied; - if it is false, then the new font object's height and scale are ignored. - */ - void setFont (const Font& newFont, bool applySizeAndScale); - - /** Returns the current font. */ - const Font& getFont() const noexcept { return font; } - - /** Changes the justification of the text within the bounding box. */ - void setJustification (Justification newJustification); - - /** Returns the current justification. */ - Justification getJustification() const noexcept { return justification; } - - /** Returns the parallelogram that defines the text bounding box. */ - const RelativeParallelogram& getBoundingBox() const noexcept { return bounds; } - - /** Sets the bounding box that contains the text. */ - void setBoundingBox (const RelativeParallelogram& newBounds); - - const RelativeCoordinate& getFontHeight() const { return fontHeight; } - void setFontHeight (const RelativeCoordinate& newHeight); - - const RelativeCoordinate& getFontHorizontalScale() const { return fontHScale; } - void setFontHorizontalScale (const RelativeCoordinate& newScale); - - //============================================================================== - /** @internal */ - void paint (Graphics&) override; - /** @internal */ - Drawable* createCopy() const override; - /** @internal */ - void refreshFromValueTree (const ValueTree& tree, ComponentBuilder& builder); - /** @internal */ - ValueTree createValueTree (ComponentBuilder::ImageProvider* imageProvider) const override; - /** @internal */ - static const Identifier valueTreeType; - /** @internal */ - Rectangle getDrawableBounds() const override; - - //============================================================================== - /** Internally-used class for wrapping a DrawableText's state into a ValueTree. */ - class ValueTreeWrapper : public Drawable::ValueTreeWrapperBase - { - public: - ValueTreeWrapper (const ValueTree& state); - - String getText() const; - void setText (const String& newText, UndoManager* undoManager); - Value getTextValue (UndoManager* undoManager); - - Colour getColour() const; - void setColour (Colour newColour, UndoManager* undoManager); - - Justification getJustification() const; - void setJustification (Justification newJustification, UndoManager* undoManager); - - Font getFont() const; - void setFont (const Font& newFont, UndoManager* undoManager); - Value getFontValue (UndoManager* undoManager); - - RelativeParallelogram getBoundingBox() const; - void setBoundingBox (const RelativeParallelogram& newBounds, UndoManager* undoManager); - - RelativeCoordinate getFontHeight() const; - void setFontHeight (const RelativeCoordinate& newHeight, UndoManager* undoManager); - - RelativeCoordinate getFontHorizontalScale() const; - void setFontHorizontalScale (const RelativeCoordinate& newScale, UndoManager* undoManager); - - static const Identifier text, colour, font, justification, topLeft, topRight, bottomLeft, fontHeight, fontHScale; - }; - -private: - //============================================================================== - RelativeParallelogram bounds; - RelativeCoordinate fontHeight, fontHScale; - Point resolvedPoints[3]; - Font font, scaledFont; - String text; - Colour colour; - Justification justification; - - friend class Drawable::Positioner; - bool registerCoordinates (RelativeCoordinatePositionerBase&); - void recalculateCoordinates (Expression::Scope*); - void refreshBounds(); - - DrawableText& operator= (const DrawableText&); - JUCE_LEAK_DETECTOR (DrawableText) -}; - - -#endif // JUCE_DRAWABLETEXT_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/drawables/juce_SVGParser.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/drawables/juce_SVGParser.cpp deleted file mode 100644 index cfb6b7b5f0..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/drawables/juce_SVGParser.cpp +++ /dev/null @@ -1,1325 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -class SVGState -{ -public: - //============================================================================== - explicit SVGState (const XmlElement* const topLevel) - : topLevelXml (topLevel, nullptr), - elementX (0), elementY (0), - width (512), height (512), - viewBoxW (0), viewBoxH (0) - { - } - - struct XmlPath - { - XmlPath (const XmlElement* e, const XmlPath* p) noexcept : xml (e), parent (p) {} - - const XmlElement& operator*() const noexcept { jassert (xml != nullptr); return *xml; } - const XmlElement* operator->() const noexcept { return xml; } - XmlPath getChild (const XmlElement* e) const noexcept { return XmlPath (e, this); } - - const XmlElement* xml; - const XmlPath* parent; - }; - - //============================================================================== - Drawable* parseSVGElement (const XmlPath& xml) - { - if (! xml->hasTagNameIgnoringNamespace ("svg")) - return nullptr; - - DrawableComposite* const drawable = new DrawableComposite(); - - setDrawableID (*drawable, xml); - - SVGState newState (*this); - - if (xml->hasAttribute ("transform")) - newState.addTransform (xml); - - newState.elementX = getCoordLength (xml->getStringAttribute ("x", String (newState.elementX)), viewBoxW); - newState.elementY = getCoordLength (xml->getStringAttribute ("y", String (newState.elementY)), viewBoxH); - newState.width = getCoordLength (xml->getStringAttribute ("width", String (newState.width)), viewBoxW); - newState.height = getCoordLength (xml->getStringAttribute ("height", String (newState.height)), viewBoxH); - - if (newState.width <= 0) newState.width = 100; - if (newState.height <= 0) newState.height = 100; - - Point viewboxXY; - - if (xml->hasAttribute ("viewBox")) - { - const String viewBoxAtt (xml->getStringAttribute ("viewBox")); - String::CharPointerType viewParams (viewBoxAtt.getCharPointer()); - Point vwh; - - if (parseCoords (viewParams, viewboxXY, true) - && parseCoords (viewParams, vwh, true) - && vwh.x > 0 - && vwh.y > 0) - { - newState.viewBoxW = vwh.x; - newState.viewBoxH = vwh.y; - - const int placementFlags = parsePlacementFlags (xml->getStringAttribute ("preserveAspectRatio").trim()); - - if (placementFlags != 0) - newState.transform = RectanglePlacement (placementFlags) - .getTransformToFit (Rectangle (viewboxXY.x, viewboxXY.y, vwh.x, vwh.y), - Rectangle (newState.width, newState.height)) - .followedBy (newState.transform); - } - } - else - { - if (viewBoxW == 0) newState.viewBoxW = newState.width; - if (viewBoxH == 0) newState.viewBoxH = newState.height; - } - - newState.parseSubElements (xml, *drawable); - - drawable->setContentArea (RelativeRectangle (RelativeCoordinate (viewboxXY.x), - RelativeCoordinate (viewboxXY.x + newState.viewBoxW), - RelativeCoordinate (viewboxXY.y), - RelativeCoordinate (viewboxXY.y + newState.viewBoxH))); - drawable->resetBoundingBoxToContentArea(); - - return drawable; - } - - //============================================================================== - void parsePathString (Path& path, const String& pathString) const - { - String::CharPointerType d (pathString.getCharPointer().findEndOfWhitespace()); - - Point subpathStart, last, last2, p1, p2, p3; - juce_wchar lastCommandChar = 0; - bool isRelative = true; - bool carryOn = true; - - const CharPointer_ASCII validCommandChars ("MmLlHhVvCcSsQqTtAaZz"); - - while (! d.isEmpty()) - { - if (validCommandChars.indexOf (*d) >= 0) - { - lastCommandChar = d.getAndAdvance(); - isRelative = (lastCommandChar >= 'a' && lastCommandChar <= 'z'); - } - - switch (lastCommandChar) - { - case 'M': - case 'm': - case 'L': - case 'l': - if (parseCoordsOrSkip (d, p1, false)) - { - if (isRelative) - p1 += last; - - if (lastCommandChar == 'M' || lastCommandChar == 'm') - { - subpathStart = p1; - path.startNewSubPath (p1); - lastCommandChar = 'l'; - } - else - path.lineTo (p1); - - last2 = last; - last = p1; - } - break; - - case 'H': - case 'h': - if (parseCoord (d, p1.x, false, true)) - { - if (isRelative) - p1.x += last.x; - - path.lineTo (p1.x, last.y); - - last2.x = last.x; - last.x = p1.x; - } - else - { - ++d; - } - break; - - case 'V': - case 'v': - if (parseCoord (d, p1.y, false, false)) - { - if (isRelative) - p1.y += last.y; - - path.lineTo (last.x, p1.y); - - last2.y = last.y; - last.y = p1.y; - } - else - { - ++d; - } - break; - - case 'C': - case 'c': - if (parseCoordsOrSkip (d, p1, false) - && parseCoordsOrSkip (d, p2, false) - && parseCoordsOrSkip (d, p3, false)) - { - if (isRelative) - { - p1 += last; - p2 += last; - p3 += last; - } - - path.cubicTo (p1, p2, p3); - - last2 = p2; - last = p3; - } - break; - - case 'S': - case 's': - if (parseCoordsOrSkip (d, p1, false) - && parseCoordsOrSkip (d, p3, false)) - { - if (isRelative) - { - p1 += last; - p3 += last; - } - - p2 = last + (last - last2); - path.cubicTo (p2, p1, p3); - - last2 = p1; - last = p3; - } - break; - - case 'Q': - case 'q': - if (parseCoordsOrSkip (d, p1, false) - && parseCoordsOrSkip (d, p2, false)) - { - if (isRelative) - { - p1 += last; - p2 += last; - } - - path.quadraticTo (p1, p2); - - last2 = p1; - last = p2; - } - break; - - case 'T': - case 't': - if (parseCoordsOrSkip (d, p1, false)) - { - if (isRelative) - p1 += last; - - p2 = last + (last - last2); - path.quadraticTo (p2, p1); - - last2 = p2; - last = p1; - } - break; - - case 'A': - case 'a': - if (parseCoordsOrSkip (d, p1, false)) - { - String num; - - if (parseNextNumber (d, num, false)) - { - const float angle = num.getFloatValue() * (180.0f / float_Pi); - - if (parseNextNumber (d, num, false)) - { - const bool largeArc = num.getIntValue() != 0; - - if (parseNextNumber (d, num, false)) - { - const bool sweep = num.getIntValue() != 0; - - if (parseCoordsOrSkip (d, p2, false)) - { - if (isRelative) - p2 += last; - - if (last != p2) - { - double centreX, centreY, startAngle, deltaAngle; - double rx = p1.x, ry = p1.y; - - endpointToCentreParameters (last.x, last.y, p2.x, p2.y, - angle, largeArc, sweep, - rx, ry, centreX, centreY, - startAngle, deltaAngle); - - path.addCentredArc ((float) centreX, (float) centreY, - (float) rx, (float) ry, - angle, (float) startAngle, (float) (startAngle + deltaAngle), - false); - - path.lineTo (p2); - } - - last2 = last; - last = p2; - } - } - } - } - } - - break; - - case 'Z': - case 'z': - path.closeSubPath(); - last = last2 = subpathStart; - d = d.findEndOfWhitespace(); - lastCommandChar = 'M'; - break; - - default: - carryOn = false; - break; - } - - if (! carryOn) - break; - } - - // paths that finish back at their start position often seem to be - // left without a 'z', so need to be closed explicitly.. - if (path.getCurrentPosition() == subpathStart) - path.closeSubPath(); - } - -private: - //============================================================================== - const XmlPath topLevelXml; - float elementX, elementY, width, height, viewBoxW, viewBoxH; - AffineTransform transform; - String cssStyleText; - - static void setDrawableID (Drawable& d, const XmlPath& xml) - { - String compID (xml->getStringAttribute ("id")); - d.setName (compID); - d.setComponentID (compID); - } - - //============================================================================== - void parseSubElements (const XmlPath& xml, DrawableComposite& parentDrawable) - { - forEachXmlChildElement (*xml, e) - parentDrawable.addAndMakeVisible (parseSubElement (xml.getChild (e))); - } - - Drawable* parseSubElement (const XmlPath& xml) - { - const String tag (xml->getTagNameWithoutNamespace()); - - if (tag == "g") return parseGroupElement (xml); - if (tag == "svg") return parseSVGElement (xml); - if (tag == "path") return parsePath (xml); - if (tag == "rect") return parseRect (xml); - if (tag == "circle") return parseCircle (xml); - if (tag == "ellipse") return parseEllipse (xml); - if (tag == "line") return parseLine (xml); - if (tag == "polyline") return parsePolygon (xml, true); - if (tag == "polygon") return parsePolygon (xml, false); - if (tag == "text") return parseText (xml); - if (tag == "switch") return parseSwitch (xml); - if (tag == "style") parseCSSStyle (xml); - - return nullptr; - } - - DrawableComposite* parseSwitch (const XmlPath& xml) - { - if (const XmlElement* const group = xml->getChildByName ("g")) - return parseGroupElement (xml.getChild (group)); - - return nullptr; - } - - DrawableComposite* parseGroupElement (const XmlPath& xml) - { - DrawableComposite* const drawable = new DrawableComposite(); - - setDrawableID (*drawable, xml); - - if (xml->hasAttribute ("transform")) - { - SVGState newState (*this); - newState.addTransform (xml); - - newState.parseSubElements (xml, *drawable); - } - else - { - parseSubElements (xml, *drawable); - } - - drawable->resetContentAreaAndBoundingBoxToFitChildren(); - return drawable; - } - - //============================================================================== - Drawable* parsePath (const XmlPath& xml) const - { - Path path; - parsePathString (path, xml->getStringAttribute ("d")); - - if (getStyleAttribute (xml, "fill-rule").trim().equalsIgnoreCase ("evenodd")) - path.setUsingNonZeroWinding (false); - - return parseShape (xml, path); - } - - Drawable* parseRect (const XmlPath& xml) const - { - Path rect; - - const bool hasRX = xml->hasAttribute ("rx"); - const bool hasRY = xml->hasAttribute ("ry"); - - if (hasRX || hasRY) - { - float rx = getCoordLength (xml, "rx", viewBoxW); - float ry = getCoordLength (xml, "ry", viewBoxH); - - if (! hasRX) - rx = ry; - else if (! hasRY) - ry = rx; - - rect.addRoundedRectangle (getCoordLength (xml, "x", viewBoxW), - getCoordLength (xml, "y", viewBoxH), - getCoordLength (xml, "width", viewBoxW), - getCoordLength (xml, "height", viewBoxH), - rx, ry); - } - else - { - rect.addRectangle (getCoordLength (xml, "x", viewBoxW), - getCoordLength (xml, "y", viewBoxH), - getCoordLength (xml, "width", viewBoxW), - getCoordLength (xml, "height", viewBoxH)); - } - - return parseShape (xml, rect); - } - - Drawable* parseCircle (const XmlPath& xml) const - { - Path circle; - - const float cx = getCoordLength (xml, "cx", viewBoxW); - const float cy = getCoordLength (xml, "cy", viewBoxH); - const float radius = getCoordLength (xml, "r", viewBoxW); - - circle.addEllipse (cx - radius, cy - radius, radius * 2.0f, radius * 2.0f); - - return parseShape (xml, circle); - } - - Drawable* parseEllipse (const XmlPath& xml) const - { - Path ellipse; - - const float cx = getCoordLength (xml, "cx", viewBoxW); - const float cy = getCoordLength (xml, "cy", viewBoxH); - const float radiusX = getCoordLength (xml, "rx", viewBoxW); - const float radiusY = getCoordLength (xml, "ry", viewBoxH); - - ellipse.addEllipse (cx - radiusX, cy - radiusY, radiusX * 2.0f, radiusY * 2.0f); - - return parseShape (xml, ellipse); - } - - Drawable* parseLine (const XmlPath& xml) const - { - Path line; - - const float x1 = getCoordLength (xml, "x1", viewBoxW); - const float y1 = getCoordLength (xml, "y1", viewBoxH); - const float x2 = getCoordLength (xml, "x2", viewBoxW); - const float y2 = getCoordLength (xml, "y2", viewBoxH); - - line.startNewSubPath (x1, y1); - line.lineTo (x2, y2); - - return parseShape (xml, line); - } - - Drawable* parsePolygon (const XmlPath& xml, const bool isPolyline) const - { - const String pointsAtt (xml->getStringAttribute ("points")); - String::CharPointerType points (pointsAtt.getCharPointer()); - Path path; - Point p; - - if (parseCoords (points, p, true)) - { - Point first (p), last; - - path.startNewSubPath (first); - - while (parseCoords (points, p, true)) - { - last = p; - path.lineTo (p); - } - - if ((! isPolyline) || first == last) - path.closeSubPath(); - } - - return parseShape (xml, path); - } - - //============================================================================== - Drawable* parseShape (const XmlPath& xml, Path& path, - const bool shouldParseTransform = true) const - { - if (shouldParseTransform && xml->hasAttribute ("transform")) - { - SVGState newState (*this); - newState.addTransform (xml); - - return newState.parseShape (xml, path, false); - } - - DrawablePath* dp = new DrawablePath(); - setDrawableID (*dp, xml); - dp->setFill (Colours::transparentBlack); - - path.applyTransform (transform); - dp->setPath (path); - - dp->setFill (getPathFillType (path, - getStyleAttribute (xml, "fill"), - getStyleAttribute (xml, "fill-opacity"), - getStyleAttribute (xml, "opacity"), - pathContainsClosedSubPath (path) ? Colours::black - : Colours::transparentBlack)); - - const String strokeType (getStyleAttribute (xml, "stroke")); - - if (strokeType.isNotEmpty() && ! strokeType.equalsIgnoreCase ("none")) - { - dp->setStrokeFill (getPathFillType (path, strokeType, - getStyleAttribute (xml, "stroke-opacity"), - getStyleAttribute (xml, "opacity"), - Colours::transparentBlack)); - - dp->setStrokeType (getStrokeFor (xml)); - } - - return dp; - } - - static bool pathContainsClosedSubPath (const Path& path) noexcept - { - for (Path::Iterator iter (path); iter.next();) - if (iter.elementType == Path::Iterator::closePath) - return true; - - return false; - } - - struct SetGradientStopsOp - { - const SVGState* state; - ColourGradient* gradient; - - void operator() (const XmlPath& xml) - { - state->addGradientStopsIn (*gradient, xml); - } - }; - - void addGradientStopsIn (ColourGradient& cg, const XmlPath& fillXml) const - { - if (fillXml.xml != nullptr) - { - forEachXmlChildElementWithTagName (*fillXml, e, "stop") - { - int index = 0; - Colour col (parseColour (getStyleAttribute (fillXml.getChild (e), "stop-color"), index, Colours::black)); - - const String opacity (getStyleAttribute (fillXml.getChild (e), "stop-opacity", "1")); - col = col.withMultipliedAlpha (jlimit (0.0f, 1.0f, opacity.getFloatValue())); - - double offset = e->getDoubleAttribute ("offset"); - - if (e->getStringAttribute ("offset").containsChar ('%')) - offset *= 0.01; - - cg.addColour (jlimit (0.0, 1.0, offset), col); - } - } - } - - FillType getGradientFillType (const XmlPath& fillXml, - const Path& path, - const float opacity) const - { - ColourGradient gradient; - - { - const String id (fillXml->getStringAttribute ("xlink:href")); - - if (id.startsWithChar ('#')) - { - SetGradientStopsOp op = { this, &gradient, }; - findElementForId (topLevelXml, id.substring (1), op); - } - } - - addGradientStopsIn (gradient, fillXml); - - if (gradient.getNumColours() > 0) - { - gradient.addColour (0.0, gradient.getColour (0)); - gradient.addColour (1.0, gradient.getColour (gradient.getNumColours() - 1)); - } - else - { - gradient.addColour (0.0, Colours::black); - gradient.addColour (1.0, Colours::black); - } - - if (opacity < 1.0f) - gradient.multiplyOpacity (opacity); - - jassert (gradient.getNumColours() > 0); - - gradient.isRadial = fillXml->hasTagNameIgnoringNamespace ("radialGradient"); - - float gradientWidth = viewBoxW; - float gradientHeight = viewBoxH; - float dx = 0.0f; - float dy = 0.0f; - - const bool userSpace = fillXml->getStringAttribute ("gradientUnits").equalsIgnoreCase ("userSpaceOnUse"); - - if (! userSpace) - { - const Rectangle bounds (path.getBounds()); - dx = bounds.getX(); - dy = bounds.getY(); - gradientWidth = bounds.getWidth(); - gradientHeight = bounds.getHeight(); - } - - if (gradient.isRadial) - { - if (userSpace) - gradient.point1.setXY (dx + getCoordLength (fillXml->getStringAttribute ("cx", "50%"), gradientWidth), - dy + getCoordLength (fillXml->getStringAttribute ("cy", "50%"), gradientHeight)); - else - gradient.point1.setXY (dx + gradientWidth * getCoordLength (fillXml->getStringAttribute ("cx", "50%"), 1.0f), - dy + gradientHeight * getCoordLength (fillXml->getStringAttribute ("cy", "50%"), 1.0f)); - - const float radius = getCoordLength (fillXml->getStringAttribute ("r", "50%"), gradientWidth); - gradient.point2 = gradient.point1 + Point (radius, 0.0f); - - //xxx (the fx, fy focal point isn't handled properly here..) - } - else - { - if (userSpace) - { - gradient.point1.setXY (dx + getCoordLength (fillXml->getStringAttribute ("x1", "0%"), gradientWidth), - dy + getCoordLength (fillXml->getStringAttribute ("y1", "0%"), gradientHeight)); - - gradient.point2.setXY (dx + getCoordLength (fillXml->getStringAttribute ("x2", "100%"), gradientWidth), - dy + getCoordLength (fillXml->getStringAttribute ("y2", "0%"), gradientHeight)); - } - else - { - gradient.point1.setXY (dx + gradientWidth * getCoordLength (fillXml->getStringAttribute ("x1", "0%"), 1.0f), - dy + gradientHeight * getCoordLength (fillXml->getStringAttribute ("y1", "0%"), 1.0f)); - - gradient.point2.setXY (dx + gradientWidth * getCoordLength (fillXml->getStringAttribute ("x2", "100%"), 1.0f), - dy + gradientHeight * getCoordLength (fillXml->getStringAttribute ("y2", "0%"), 1.0f)); - } - - if (gradient.point1 == gradient.point2) - return Colour (gradient.getColour (gradient.getNumColours() - 1)); - } - - FillType type (gradient); - - const AffineTransform gradientTransform (parseTransform (fillXml->getStringAttribute ("gradientTransform")) - .followedBy (transform)); - - if (gradient.isRadial) - { - type.transform = gradientTransform; - } - else - { - // Transform the perpendicular vector into the new coordinate space for the gradient. - // This vector is now the slope of the linear gradient as it should appear in the new coord space - const Point perpendicular (Point (gradient.point2.y - gradient.point1.y, - gradient.point1.x - gradient.point2.x) - .transformedBy (gradientTransform.withAbsoluteTranslation (0, 0))); - - const Point newGradPoint1 (gradient.point1.transformedBy (gradientTransform)); - const Point newGradPoint2 (gradient.point2.transformedBy (gradientTransform)); - - // Project the transformed gradient vector onto the transformed slope of the linear - // gradient as it should appear in the new coordinate space - const float scale = perpendicular.getDotProduct (newGradPoint2 - newGradPoint1) - / perpendicular.getDotProduct (perpendicular); - - type.gradient->point1 = newGradPoint1; - type.gradient->point2 = newGradPoint2 - perpendicular * scale; - } - - return type; - } - - struct GetFillTypeOp - { - const SVGState* state; - FillType* dest; - const Path* path; - float opacity; - - void operator() (const XmlPath& xml) - { - if (xml->hasTagNameIgnoringNamespace ("linearGradient") - || xml->hasTagNameIgnoringNamespace ("radialGradient")) - *dest = state->getGradientFillType (xml, *path, opacity); - } - }; - - FillType getPathFillType (const Path& path, - const String& fill, - const String& fillOpacity, - const String& overallOpacity, - const Colour defaultColour) const - { - float opacity = 1.0f; - - if (overallOpacity.isNotEmpty()) - opacity = jlimit (0.0f, 1.0f, overallOpacity.getFloatValue()); - - if (fillOpacity.isNotEmpty()) - opacity *= (jlimit (0.0f, 1.0f, fillOpacity.getFloatValue())); - - if (fill.startsWithIgnoreCase ("url")) - { - const String id (fill.fromFirstOccurrenceOf ("#", false, false) - .upToLastOccurrenceOf (")", false, false).trim()); - - FillType result; - GetFillTypeOp op = { this, &result, &path, opacity }; - - if (findElementForId (topLevelXml, id, op)) - return result; - } - - if (fill.equalsIgnoreCase ("none")) - return Colours::transparentBlack; - - int i = 0; - return parseColour (fill, i, defaultColour).withMultipliedAlpha (opacity); - } - - static PathStrokeType::JointStyle getJointStyle (const String& join) noexcept - { - if (join.equalsIgnoreCase ("round")) return PathStrokeType::curved; - if (join.equalsIgnoreCase ("bevel")) return PathStrokeType::beveled; - - return PathStrokeType::mitered; - } - - static PathStrokeType::EndCapStyle getEndCapStyle (const String& cap) noexcept - { - if (cap.equalsIgnoreCase ("round")) return PathStrokeType::rounded; - if (cap.equalsIgnoreCase ("square")) return PathStrokeType::square; - - return PathStrokeType::butt; - } - - float getStrokeWidth (const String& strokeWidth) const noexcept - { - return transform.getScaleFactor() * getCoordLength (strokeWidth, viewBoxW); - } - - PathStrokeType getStrokeFor (const XmlPath& xml) const - { - return PathStrokeType (getStrokeWidth (getStyleAttribute (xml, "stroke-width", "1")), - getJointStyle (getStyleAttribute (xml, "stroke-linejoin")), - getEndCapStyle (getStyleAttribute (xml, "stroke-linecap"))); - } - - //============================================================================== - Drawable* parseText (const XmlPath& xml) - { - Array xCoords, yCoords, dxCoords, dyCoords; - - getCoordList (xCoords, getInheritedAttribute (xml, "x"), true, true); - getCoordList (yCoords, getInheritedAttribute (xml, "y"), true, false); - getCoordList (dxCoords, getInheritedAttribute (xml, "dx"), true, true); - getCoordList (dyCoords, getInheritedAttribute (xml, "dy"), true, false); - - - //xxx not done text yet! - - - forEachXmlChildElement (*xml, e) - { - if (e->isTextElement()) - { - const String text (e->getText()); - - Path path; - Drawable* s = parseShape (xml.getChild (e), path); - delete s; // xxx not finished! - } - else if (e->hasTagNameIgnoringNamespace ("tspan")) - { - Drawable* s = parseText (xml.getChild (e)); - delete s; // xxx not finished! - } - } - - return nullptr; - } - - //============================================================================== - void addTransform (const XmlPath& xml) - { - transform = parseTransform (xml->getStringAttribute ("transform")) - .followedBy (transform); - } - - //============================================================================== - bool parseCoord (String::CharPointerType& s, float& value, const bool allowUnits, const bool isX) const - { - String number; - - if (! parseNextNumber (s, number, allowUnits)) - { - value = 0; - return false; - } - - value = getCoordLength (number, isX ? viewBoxW : viewBoxH); - return true; - } - - bool parseCoords (String::CharPointerType& s, Point& p, const bool allowUnits) const - { - return parseCoord (s, p.x, allowUnits, true) - && parseCoord (s, p.y, allowUnits, false); - } - - bool parseCoordsOrSkip (String::CharPointerType& s, Point& p, const bool allowUnits) const - { - if (parseCoords (s, p, allowUnits)) - return true; - - if (! s.isEmpty()) ++s; - return false; - } - - float getCoordLength (const String& s, const float sizeForProportions) const noexcept - { - float n = s.getFloatValue(); - const int len = s.length(); - - if (len > 2) - { - const float dpi = 96.0f; - - const juce_wchar n1 = s [len - 2]; - const juce_wchar n2 = s [len - 1]; - - if (n1 == 'i' && n2 == 'n') n *= dpi; - else if (n1 == 'm' && n2 == 'm') n *= dpi / 25.4f; - else if (n1 == 'c' && n2 == 'm') n *= dpi / 2.54f; - else if (n1 == 'p' && n2 == 'c') n *= 15.0f; - else if (n2 == '%') n *= 0.01f * sizeForProportions; - } - - return n; - } - - float getCoordLength (const XmlPath& xml, const char* attName, const float sizeForProportions) const noexcept - { - return getCoordLength (xml->getStringAttribute (attName), sizeForProportions); - } - - void getCoordList (Array& coords, const String& list, bool allowUnits, const bool isX) const - { - String::CharPointerType text (list.getCharPointer()); - float value; - - while (parseCoord (text, value, allowUnits, isX)) - coords.add (value); - } - - //============================================================================== - void parseCSSStyle (const XmlPath& xml) - { - cssStyleText = xml->getAllSubText() + "\n" + cssStyleText; - } - - static String::CharPointerType findStyleItem (String::CharPointerType source, String::CharPointerType name) - { - const int nameLength = (int) name.length(); - - while (! source.isEmpty()) - { - if (source.getAndAdvance() == '.' - && CharacterFunctions::compareIgnoreCaseUpTo (source, name, nameLength) == 0) - { - String::CharPointerType endOfName ((source + nameLength).findEndOfWhitespace()); - - if (*endOfName == '{') - return endOfName; - } - } - - return source; - } - - String getStyleAttribute (const XmlPath& xml, StringRef attributeName, - const String& defaultValue = String()) const - { - if (xml->hasAttribute (attributeName)) - return xml->getStringAttribute (attributeName, defaultValue); - - const String styleAtt (xml->getStringAttribute ("style")); - - if (styleAtt.isNotEmpty()) - { - const String value (getAttributeFromStyleList (styleAtt, attributeName, String())); - - if (value.isNotEmpty()) - return value; - } - else if (xml->hasAttribute ("class")) - { - String::CharPointerType openBrace = findStyleItem (cssStyleText.getCharPointer(), - xml->getStringAttribute ("class").getCharPointer()); - - if (! openBrace.isEmpty()) - { - String::CharPointerType closeBrace = CharacterFunctions::find (openBrace, (juce_wchar) '}'); - - if (closeBrace != openBrace) - { - const String value (getAttributeFromStyleList (String (openBrace + 1, closeBrace), - attributeName, defaultValue)); - if (value.isNotEmpty()) - return value; - } - } - } - - if (xml.parent != nullptr) - return getStyleAttribute (*xml.parent, attributeName, defaultValue); - - return defaultValue; - } - - String getInheritedAttribute (const XmlPath& xml, StringRef attributeName) const - { - if (xml->hasAttribute (attributeName)) - return xml->getStringAttribute (attributeName); - - if (xml.parent != nullptr) - return getInheritedAttribute (*xml.parent, attributeName); - - return String(); - } - - static int parsePlacementFlags (const String& align) noexcept - { - if (align.isEmpty()) - return 0; - - if (align.containsIgnoreCase ("none")) - return RectanglePlacement::stretchToFit; - - return (align.containsIgnoreCase ("slice") ? RectanglePlacement::fillDestination : 0) - | (align.containsIgnoreCase ("xMin") ? RectanglePlacement::xLeft - : (align.containsIgnoreCase ("xMax") ? RectanglePlacement::xRight - : RectanglePlacement::xMid)) - | (align.containsIgnoreCase ("yMin") ? RectanglePlacement::yTop - : (align.containsIgnoreCase ("yMax") ? RectanglePlacement::yBottom - : RectanglePlacement::yMid)); - } - - //============================================================================== - static bool isIdentifierChar (const juce_wchar c) - { - return CharacterFunctions::isLetter (c) || c == '-'; - } - - static String getAttributeFromStyleList (const String& list, StringRef attributeName, const String& defaultValue) - { - int i = 0; - - for (;;) - { - i = list.indexOf (i, attributeName); - - if (i < 0) - break; - - if ((i == 0 || (i > 0 && ! isIdentifierChar (list [i - 1]))) - && ! isIdentifierChar (list [i + attributeName.length()])) - { - i = list.indexOfChar (i, ':'); - - if (i < 0) - break; - - int end = list.indexOfChar (i, ';'); - - if (end < 0) - end = 0x7ffff; - - return list.substring (i + 1, end).trim(); - } - - ++i; - } - - return defaultValue; - } - - //============================================================================== - static bool parseNextNumber (String::CharPointerType& text, String& value, const bool allowUnits) - { - String::CharPointerType s (text); - - while (s.isWhitespace() || *s == ',') - ++s; - - String::CharPointerType start (s); - - if (s.isDigit() || *s == '.' || *s == '-') - ++s; - - while (s.isDigit() || *s == '.') - ++s; - - if ((*s == 'e' || *s == 'E') - && ((s + 1).isDigit() || s[1] == '-' || s[1] == '+')) - { - s += 2; - - while (s.isDigit()) - ++s; - } - - if (allowUnits) - while (s.isLetter()) - ++s; - - if (s == start) - { - text = s; - return false; - } - - value = String (start, s); - - while (s.isWhitespace() || *s == ',') - ++s; - - text = s; - return true; - } - - //============================================================================== - static Colour parseColour (const String& s, int& index, const Colour defaultColour) - { - if (s [index] == '#') - { - uint32 hex[6] = { 0 }; - int numChars = 0; - - for (int i = 6; --i >= 0;) - { - const int hexValue = CharacterFunctions::getHexDigitValue (s [++index]); - - if (hexValue >= 0) - hex [numChars++] = (uint32) hexValue; - else - break; - } - - if (numChars <= 3) - return Colour ((uint8) (hex [0] * 0x11), - (uint8) (hex [1] * 0x11), - (uint8) (hex [2] * 0x11)); - - return Colour ((uint8) ((hex [0] << 4) + hex [1]), - (uint8) ((hex [2] << 4) + hex [3]), - (uint8) ((hex [4] << 4) + hex [5])); - } - - if (s [index] == 'r' - && s [index + 1] == 'g' - && s [index + 2] == 'b') - { - const int openBracket = s.indexOfChar (index, '('); - const int closeBracket = s.indexOfChar (openBracket, ')'); - - if (openBracket >= 3 && closeBracket > openBracket) - { - index = closeBracket; - - StringArray tokens; - tokens.addTokens (s.substring (openBracket + 1, closeBracket), ",", ""); - tokens.trim(); - tokens.removeEmptyStrings(); - - if (tokens[0].containsChar ('%')) - return Colour ((uint8) roundToInt (2.55 * tokens[0].getDoubleValue()), - (uint8) roundToInt (2.55 * tokens[1].getDoubleValue()), - (uint8) roundToInt (2.55 * tokens[2].getDoubleValue())); - else - return Colour ((uint8) tokens[0].getIntValue(), - (uint8) tokens[1].getIntValue(), - (uint8) tokens[2].getIntValue()); - } - } - - return Colours::findColourForName (s, defaultColour); - } - - static AffineTransform parseTransform (String t) - { - AffineTransform result; - - while (t.isNotEmpty()) - { - StringArray tokens; - tokens.addTokens (t.fromFirstOccurrenceOf ("(", false, false) - .upToFirstOccurrenceOf (")", false, false), - ", ", ""); - - tokens.removeEmptyStrings (true); - - float numbers [6]; - - for (int i = 0; i < 6; ++i) - numbers[i] = tokens[i].getFloatValue(); - - AffineTransform trans; - - if (t.startsWithIgnoreCase ("matrix")) - { - trans = AffineTransform (numbers[0], numbers[2], numbers[4], - numbers[1], numbers[3], numbers[5]); - } - else if (t.startsWithIgnoreCase ("translate")) - { - jassert (tokens.size() == 2); - trans = AffineTransform::translation (numbers[0], numbers[1]); - } - else if (t.startsWithIgnoreCase ("scale")) - { - if (tokens.size() == 1) - trans = AffineTransform::scale (numbers[0]); - else - trans = AffineTransform::scale (numbers[0], numbers[1]); - } - else if (t.startsWithIgnoreCase ("rotate")) - { - if (tokens.size() != 3) - trans = AffineTransform::rotation (numbers[0] / (180.0f / float_Pi)); - else - trans = AffineTransform::rotation (numbers[0] / (180.0f / float_Pi), - numbers[1], numbers[2]); - } - else if (t.startsWithIgnoreCase ("skewX")) - { - trans = AffineTransform (1.0f, std::tan (numbers[0] * (float_Pi / 180.0f)), 0.0f, - 0.0f, 1.0f, 0.0f); - } - else if (t.startsWithIgnoreCase ("skewY")) - { - trans = AffineTransform (1.0f, 0.0f, 0.0f, - std::tan (numbers[0] * (float_Pi / 180.0f)), 1.0f, 0.0f); - } - - result = trans.followedBy (result); - t = t.fromFirstOccurrenceOf (")", false, false).trimStart(); - } - - return result; - } - - static void endpointToCentreParameters (const double x1, const double y1, - const double x2, const double y2, - const double angle, - const bool largeArc, const bool sweep, - double& rx, double& ry, - double& centreX, double& centreY, - double& startAngle, double& deltaAngle) noexcept - { - const double midX = (x1 - x2) * 0.5; - const double midY = (y1 - y2) * 0.5; - - const double cosAngle = cos (angle); - const double sinAngle = sin (angle); - const double xp = cosAngle * midX + sinAngle * midY; - const double yp = cosAngle * midY - sinAngle * midX; - const double xp2 = xp * xp; - const double yp2 = yp * yp; - - double rx2 = rx * rx; - double ry2 = ry * ry; - - const double s = (xp2 / rx2) + (yp2 / ry2); - double c; - - if (s <= 1.0) - { - c = std::sqrt (jmax (0.0, ((rx2 * ry2) - (rx2 * yp2) - (ry2 * xp2)) - / (( rx2 * yp2) + (ry2 * xp2)))); - - if (largeArc == sweep) - c = -c; - } - else - { - const double s2 = std::sqrt (s); - rx *= s2; - ry *= s2; - c = 0; - } - - const double cpx = ((rx * yp) / ry) * c; - const double cpy = ((-ry * xp) / rx) * c; - - centreX = ((x1 + x2) * 0.5) + (cosAngle * cpx) - (sinAngle * cpy); - centreY = ((y1 + y2) * 0.5) + (sinAngle * cpx) + (cosAngle * cpy); - - const double ux = (xp - cpx) / rx; - const double uy = (yp - cpy) / ry; - const double vx = (-xp - cpx) / rx; - const double vy = (-yp - cpy) / ry; - - const double length = juce_hypot (ux, uy); - - startAngle = acos (jlimit (-1.0, 1.0, ux / length)); - - if (uy < 0) - startAngle = -startAngle; - - startAngle += double_Pi * 0.5; - - deltaAngle = acos (jlimit (-1.0, 1.0, ((ux * vx) + (uy * vy)) - / (length * juce_hypot (vx, vy)))); - - if ((ux * vy) - (uy * vx) < 0) - deltaAngle = -deltaAngle; - - if (sweep) - { - if (deltaAngle < 0) - deltaAngle += double_Pi * 2.0; - } - else - { - if (deltaAngle > 0) - deltaAngle -= double_Pi * 2.0; - } - - deltaAngle = fmod (deltaAngle, double_Pi * 2.0); - } - - template - static bool findElementForId (const XmlPath& parent, const String& id, OperationType& op) - { - forEachXmlChildElement (*parent, e) - { - if (e->compareAttribute ("id", id)) - { - op (parent.getChild (e)); - return true; - } - - if (findElementForId (parent.getChild (e), id, op)) - return true; - } - - return false; - } - - SVGState& operator= (const SVGState&) JUCE_DELETED_FUNCTION; -}; - - -//============================================================================== -Drawable* Drawable::createFromSVG (const XmlElement& svgDocument) -{ - SVGState state (&svgDocument); - return state.parseSVGElement (SVGState::XmlPath (&svgDocument, nullptr)); -} - -Path Drawable::parseSVGPath (const String& svgPath) -{ - SVGState state (nullptr); - Path p; - state.parsePathString (p, svgPath); - return p; -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/filebrowser/juce_DirectoryContentsDisplayComponent.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/filebrowser/juce_DirectoryContentsDisplayComponent.cpp deleted file mode 100644 index 265df83127..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/filebrowser/juce_DirectoryContentsDisplayComponent.cpp +++ /dev/null @@ -1,71 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -DirectoryContentsDisplayComponent::DirectoryContentsDisplayComponent (DirectoryContentsList& listToShow) - : fileList (listToShow) -{ -} - -DirectoryContentsDisplayComponent::~DirectoryContentsDisplayComponent() -{ -} - -//============================================================================== -FileBrowserListener::~FileBrowserListener() -{ -} - -void DirectoryContentsDisplayComponent::addListener (FileBrowserListener* const listener) -{ - listeners.add (listener); -} - -void DirectoryContentsDisplayComponent::removeListener (FileBrowserListener* const listener) -{ - listeners.remove (listener); -} - -void DirectoryContentsDisplayComponent::sendSelectionChangeMessage() -{ - Component::BailOutChecker checker (dynamic_cast (this)); - listeners.callChecked (checker, &FileBrowserListener::selectionChanged); -} - -void DirectoryContentsDisplayComponent::sendMouseClickMessage (const File& file, const MouseEvent& e) -{ - if (fileList.getDirectory().exists()) - { - Component::BailOutChecker checker (dynamic_cast (this)); - listeners.callChecked (checker, &FileBrowserListener::fileClicked, file, e); - } -} - -void DirectoryContentsDisplayComponent::sendDoubleClickMessage (const File& file) -{ - if (fileList.getDirectory().exists()) - { - Component::BailOutChecker checker (dynamic_cast (this)); - listeners.callChecked (checker, &FileBrowserListener::fileDoubleClicked, file); - } -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/filebrowser/juce_DirectoryContentsDisplayComponent.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/filebrowser/juce_DirectoryContentsDisplayComponent.h deleted file mode 100644 index ebe16805f2..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/filebrowser/juce_DirectoryContentsDisplayComponent.h +++ /dev/null @@ -1,111 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_DIRECTORYCONTENTSDISPLAYCOMPONENT_H_INCLUDED -#define JUCE_DIRECTORYCONTENTSDISPLAYCOMPONENT_H_INCLUDED - - -//============================================================================== -/** - A base class for components that display a list of the files in a directory. - - @see DirectoryContentsList -*/ -class JUCE_API DirectoryContentsDisplayComponent -{ -public: - //============================================================================== - /** Creates a DirectoryContentsDisplayComponent for a given list of files. */ - DirectoryContentsDisplayComponent (DirectoryContentsList& listToShow); - - /** Destructor. */ - virtual ~DirectoryContentsDisplayComponent(); - - //============================================================================== - /** Returns the number of files the user has got selected. - @see getSelectedFile - */ - virtual int getNumSelectedFiles() const = 0; - - /** Returns one of the files that the user has currently selected. - The index should be in the range 0 to (getNumSelectedFiles() - 1). - @see getNumSelectedFiles - */ - virtual File getSelectedFile (int index) const = 0; - - /** Deselects any selected files. */ - virtual void deselectAllFiles() = 0; - - /** Scrolls this view to the top. */ - virtual void scrollToTop() = 0; - - /** If the specified file is in the list, it will become the only selected item - (and if the file isn't in the list, all other items will be deselected). */ - virtual void setSelectedFile (const File&) = 0; - - //============================================================================== - /** Adds a listener to be told when files are selected or clicked. - @see removeListener - */ - void addListener (FileBrowserListener* listener); - - /** Removes a listener. - @see addListener - */ - void removeListener (FileBrowserListener* listener); - - - //============================================================================== - /** A set of colour IDs to use to change the colour of various aspects of the list. - - These constants can be used either via the Component::setColour(), or LookAndFeel::setColour() - methods. - - @see Component::setColour, Component::findColour, LookAndFeel::setColour, LookAndFeel::findColour - */ - enum ColourIds - { - highlightColourId = 0x1000540, /**< The colour to use to fill a highlighted row of the list. */ - textColourId = 0x1000541, /**< The colour for the text. */ - }; - - //============================================================================== - /** @internal */ - void sendSelectionChangeMessage(); - /** @internal */ - void sendDoubleClickMessage (const File& file); - /** @internal */ - void sendMouseClickMessage (const File& file, const MouseEvent& e); - -protected: - //============================================================================== - DirectoryContentsList& fileList; - ListenerList listeners; - -private: - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (DirectoryContentsDisplayComponent) -}; - - -#endif // JUCE_DIRECTORYCONTENTSDISPLAYCOMPONENT_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/filebrowser/juce_DirectoryContentsList.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/filebrowser/juce_DirectoryContentsList.cpp deleted file mode 100644 index db98eb25c7..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/filebrowser/juce_DirectoryContentsList.cpp +++ /dev/null @@ -1,258 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -DirectoryContentsList::DirectoryContentsList (const FileFilter* f, TimeSliceThread& t) - : fileFilter (f), thread (t), - fileTypeFlags (File::ignoreHiddenFiles | File::findFiles), - shouldStop (true) -{ -} - -DirectoryContentsList::~DirectoryContentsList() -{ - stopSearching(); -} - -void DirectoryContentsList::setIgnoresHiddenFiles (const bool shouldIgnoreHiddenFiles) -{ - setTypeFlags (shouldIgnoreHiddenFiles ? (fileTypeFlags | File::ignoreHiddenFiles) - : (fileTypeFlags & ~File::ignoreHiddenFiles)); -} - -bool DirectoryContentsList::ignoresHiddenFiles() const -{ - return (fileTypeFlags & File::ignoreHiddenFiles) != 0; -} - -//============================================================================== -void DirectoryContentsList::setDirectory (const File& directory, - const bool includeDirectories, - const bool includeFiles) -{ - jassert (includeDirectories || includeFiles); // you have to speciify at least one of these! - - if (directory != root) - { - clear(); - root = directory; - changed(); - - // (this forces a refresh when setTypeFlags() is called, rather than triggering two refreshes) - fileTypeFlags &= ~(File::findDirectories | File::findFiles); - } - - int newFlags = fileTypeFlags; - if (includeDirectories) newFlags |= File::findDirectories; else newFlags &= ~File::findDirectories; - if (includeFiles) newFlags |= File::findFiles; else newFlags &= ~File::findFiles; - - setTypeFlags (newFlags); -} - -void DirectoryContentsList::setTypeFlags (const int newFlags) -{ - if (fileTypeFlags != newFlags) - { - fileTypeFlags = newFlags; - refresh(); - } -} - -void DirectoryContentsList::stopSearching() -{ - shouldStop = true; - thread.removeTimeSliceClient (this); - fileFindHandle = nullptr; -} - -void DirectoryContentsList::clear() -{ - stopSearching(); - - if (files.size() > 0) - { - files.clear(); - changed(); - } -} - -void DirectoryContentsList::refresh() -{ - clear(); - - if (root.isDirectory()) - { - fileFindHandle = new DirectoryIterator (root, false, "*", fileTypeFlags); - shouldStop = false; - thread.addTimeSliceClient (this); - } -} - -void DirectoryContentsList::setFileFilter (const FileFilter* newFileFilter) -{ - const ScopedLock sl (fileListLock); - fileFilter = newFileFilter; -} - -//============================================================================== -bool DirectoryContentsList::getFileInfo (const int index, FileInfo& result) const -{ - const ScopedLock sl (fileListLock); - - if (const FileInfo* const info = files [index]) - { - result = *info; - return true; - } - - return false; -} - -File DirectoryContentsList::getFile (const int index) const -{ - const ScopedLock sl (fileListLock); - - if (const FileInfo* const info = files [index]) - return root.getChildFile (info->filename); - - return File(); -} - -bool DirectoryContentsList::contains (const File& targetFile) const -{ - const ScopedLock sl (fileListLock); - - for (int i = files.size(); --i >= 0;) - if (root.getChildFile (files.getUnchecked(i)->filename) == targetFile) - return true; - - return false; -} - -bool DirectoryContentsList::isStillLoading() const -{ - return fileFindHandle != nullptr; -} - -void DirectoryContentsList::changed() -{ - sendChangeMessage(); -} - -//============================================================================== -int DirectoryContentsList::useTimeSlice() -{ - const uint32 startTime = Time::getApproximateMillisecondCounter(); - bool hasChanged = false; - - for (int i = 100; --i >= 0;) - { - if (! checkNextFile (hasChanged)) - { - if (hasChanged) - changed(); - - return 500; - } - - if (shouldStop || (Time::getApproximateMillisecondCounter() > startTime + 150)) - break; - } - - if (hasChanged) - changed(); - - return 0; -} - -bool DirectoryContentsList::checkNextFile (bool& hasChanged) -{ - if (fileFindHandle != nullptr) - { - bool fileFoundIsDir, isHidden, isReadOnly; - int64 fileSize; - Time modTime, creationTime; - - if (fileFindHandle->next (&fileFoundIsDir, &isHidden, &fileSize, - &modTime, &creationTime, &isReadOnly)) - { - if (addFile (fileFindHandle->getFile(), fileFoundIsDir, - fileSize, modTime, creationTime, isReadOnly)) - { - hasChanged = true; - } - - return true; - } - - fileFindHandle = nullptr; - } - - return false; -} - -struct FileInfoComparator -{ - static int compareElements (const DirectoryContentsList::FileInfo* const first, - const DirectoryContentsList::FileInfo* const second) - { - #if JUCE_WINDOWS - if (first->isDirectory != second->isDirectory) - return first->isDirectory ? -1 : 1; - #endif - - return first->filename.compareNatural (second->filename); - } -}; - -bool DirectoryContentsList::addFile (const File& file, const bool isDir, - const int64 fileSize, - Time modTime, Time creationTime, - const bool isReadOnly) -{ - const ScopedLock sl (fileListLock); - - if (fileFilter == nullptr - || ((! isDir) && fileFilter->isFileSuitable (file)) - || (isDir && fileFilter->isDirectorySuitable (file))) - { - ScopedPointer info (new FileInfo()); - - info->filename = file.getFileName(); - info->fileSize = fileSize; - info->modificationTime = modTime; - info->creationTime = creationTime; - info->isDirectory = isDir; - info->isReadOnly = isReadOnly; - - for (int i = files.size(); --i >= 0;) - if (files.getUnchecked(i)->filename == info->filename) - return false; - - FileInfoComparator comp; - files.addSorted (comp, info.release()); - return true; - } - - return false; -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/filebrowser/juce_DirectoryContentsList.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/filebrowser/juce_DirectoryContentsList.h deleted file mode 100644 index b2e6a21d09..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/filebrowser/juce_DirectoryContentsList.h +++ /dev/null @@ -1,223 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_DIRECTORYCONTENTSLIST_H_INCLUDED -#define JUCE_DIRECTORYCONTENTSLIST_H_INCLUDED - - -//============================================================================== -/** - A class to asynchronously scan for details about the files in a directory. - - This keeps a list of files and some information about them, using a background - thread to scan for more files. As files are found, it broadcasts change messages - to tell any listeners. - - @see FileListComponent, FileBrowserComponent -*/ -class JUCE_API DirectoryContentsList : public ChangeBroadcaster, - private TimeSliceClient -{ -public: - //============================================================================== - /** Creates a directory list. - - To set the directory it should point to, use setDirectory(), which will - also start it scanning for files on the background thread. - - When the background thread finds and adds new files to this list, the - ChangeBroadcaster class will send a change message, so you can register - listeners and update them when the list changes. - - @param fileFilter an optional filter to select which files are - included in the list. If this is nullptr, then all files - and directories are included. Make sure that the filter - doesn't get deleted during the lifetime of this object - @param threadToUse a thread object that this list can use - to scan for files as a background task. Make sure - that the thread you give it has been started, or you - won't get any files! - */ - DirectoryContentsList (const FileFilter* fileFilter, - TimeSliceThread& threadToUse); - - /** Destructor. */ - ~DirectoryContentsList(); - - - //============================================================================== - /** Returns the directory that's currently being used. */ - const File& getDirectory() const noexcept { return root; } - - /** Sets the directory to look in for files. - - If the directory that's passed in is different to the current one, this will - also start the background thread scanning it for files. - */ - void setDirectory (const File& directory, - bool includeDirectories, - bool includeFiles); - - /** Returns true if this list contains directories. - @see setDirectory - */ - bool isFindingDirectories() const noexcept { return (fileTypeFlags & File::findDirectories) != 0; } - - /** Returns true if this list contains files. - @see setDirectory - */ - bool isFindingFiles() const noexcept { return (fileTypeFlags & File::findFiles) != 0; } - - /** Clears the list, and stops the thread scanning for files. */ - void clear(); - - /** Clears the list and restarts scanning the directory for files. */ - void refresh(); - - /** True if the background thread hasn't yet finished scanning for files. */ - bool isStillLoading() const; - - /** Tells the list whether or not to ignore hidden files. - By default these are ignored. - */ - void setIgnoresHiddenFiles (bool shouldIgnoreHiddenFiles); - - /** Returns true if hidden files are ignored. - @see setIgnoresHiddenFiles - */ - bool ignoresHiddenFiles() const; - - /** Replaces the current FileFilter. - This can be nullptr to have no filter. The DirectoryContentList does not take - ownership of this object - it just keeps a pointer to it, so you must manage its - lifetime. - Note that this only replaces the filter, it doesn't refresh the list - you'll - probably want to call refresh() after calling this. - */ - void setFileFilter (const FileFilter* newFileFilter); - - //============================================================================== - /** Contains cached information about one of the files in a DirectoryContentsList. - */ - struct FileInfo - { - //============================================================================== - /** The filename. - - This isn't a full pathname, it's just the last part of the path, same as you'd - get from File::getFileName(). - - To get the full pathname, use DirectoryContentsList::getDirectory().getChildFile (filename). - */ - String filename; - - /** File size in bytes. */ - int64 fileSize; - - /** File modification time. - As supplied by File::getLastModificationTime(). - */ - Time modificationTime; - - /** File creation time. - As supplied by File::getCreationTime(). - */ - Time creationTime; - - /** True if the file is a directory. */ - bool isDirectory; - - /** True if the file is read-only. */ - bool isReadOnly; - }; - - //============================================================================== - /** Returns the number of files currently available in the list. - - The info about one of these files can be retrieved with getFileInfo() or getFile(). - - Obviously as the background thread runs and scans the directory for files, this - number will change. - - @see getFileInfo, getFile - */ - int getNumFiles() const noexcept { return files.size(); } - - /** Returns the cached information about one of the files in the list. - - If the index is in-range, this will return true and will copy the file's details - to the structure that is passed-in. - - If it returns false, then the index wasn't in range, and the structure won't - be affected. - - @see getNumFiles, getFile - */ - bool getFileInfo (int index, FileInfo& resultInfo) const; - - /** Returns one of the files in the list. - - @param index should be less than getNumFiles(). If this is out-of-range, the - return value will be File::nonexistent - @see getNumFiles, getFileInfo - */ - File getFile (int index) const; - - /** Returns the file filter being used. - The filter is specified in the constructor. - */ - const FileFilter* getFilter() const noexcept { return fileFilter; } - - /** Returns true if the list contains the specified file. */ - bool contains (const File&) const; - - //============================================================================== - /** @internal */ - TimeSliceThread& getTimeSliceThread() const noexcept { return thread; } - -private: - File root; - const FileFilter* fileFilter; - TimeSliceThread& thread; - int fileTypeFlags; - - CriticalSection fileListLock; - OwnedArray files; - - ScopedPointer fileFindHandle; - bool volatile shouldStop; - - int useTimeSlice() override; - void stopSearching(); - void changed(); - bool checkNextFile (bool& hasChanged); - bool addFile (const File&, bool isDir, int64 fileSize, Time modTime, - Time creationTime, bool isReadOnly); - void setTypeFlags (int); - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (DirectoryContentsList) -}; - - -#endif // JUCE_DIRECTORYCONTENTSLIST_H_INCLUDED diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/filebrowser/juce_FileBrowserComponent.cpp b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/filebrowser/juce_FileBrowserComponent.cpp deleted file mode 100644 index 4a2f023877..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/filebrowser/juce_FileBrowserComponent.cpp +++ /dev/null @@ -1,586 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -FileBrowserComponent::FileBrowserComponent (int flags_, - const File& initialFileOrDirectory, - const FileFilter* fileFilter_, - FilePreviewComponent* previewComp_) - : FileFilter (String::empty), - fileFilter (fileFilter_), - flags (flags_), - previewComp (previewComp_), - currentPathBox ("path"), - fileLabel ("f", TRANS ("file:")), - thread ("Juce FileBrowser") -{ - // You need to specify one or other of the open/save flags.. - jassert ((flags & (saveMode | openMode)) != 0); - jassert ((flags & (saveMode | openMode)) != (saveMode | openMode)); - - // You need to specify at least one of these flags.. - jassert ((flags & (canSelectFiles | canSelectDirectories)) != 0); - - String filename; - - if (initialFileOrDirectory == File::nonexistent) - { - currentRoot = File::getCurrentWorkingDirectory(); - } - else if (initialFileOrDirectory.isDirectory()) - { - currentRoot = initialFileOrDirectory; - } - else - { - chosenFiles.add (initialFileOrDirectory); - currentRoot = initialFileOrDirectory.getParentDirectory(); - filename = initialFileOrDirectory.getFileName(); - } - - fileList = new DirectoryContentsList (this, thread); - - if ((flags & useTreeView) != 0) - { - FileTreeComponent* const tree = new FileTreeComponent (*fileList); - fileListComponent = tree; - - if ((flags & canSelectMultipleItems) != 0) - tree->setMultiSelectEnabled (true); - - addAndMakeVisible (tree); - } - else - { - FileListComponent* const list = new FileListComponent (*fileList); - fileListComponent = list; - list->setOutlineThickness (1); - - if ((flags & canSelectMultipleItems) != 0) - list->setMultipleSelectionEnabled (true); - - addAndMakeVisible (list); - } - - fileListComponent->addListener (this); - - addAndMakeVisible (currentPathBox); - currentPathBox.setEditableText (true); - resetRecentPaths(); - currentPathBox.addListener (this); - - addAndMakeVisible (filenameBox); - filenameBox.setMultiLine (false); - filenameBox.setSelectAllWhenFocused (true); - filenameBox.setText (filename, false); - filenameBox.addListener (this); - filenameBox.setReadOnly ((flags & (filenameBoxIsReadOnly | canSelectMultipleItems)) != 0); - - addAndMakeVisible (fileLabel); - fileLabel.attachToComponent (&filenameBox, true); - - addAndMakeVisible (goUpButton = getLookAndFeel().createFileBrowserGoUpButton()); - goUpButton->addListener (this); - goUpButton->setTooltip (TRANS ("Go up to parent directory")); - - if (previewComp != nullptr) - addAndMakeVisible (previewComp); - - setRoot (currentRoot); - - thread.startThread (4); -} - -FileBrowserComponent::~FileBrowserComponent() -{ - fileListComponent = nullptr; - fileList = nullptr; - thread.stopThread (10000); -} - -//============================================================================== -void FileBrowserComponent::addListener (FileBrowserListener* const newListener) -{ - listeners.add (newListener); -} - -void FileBrowserComponent::removeListener (FileBrowserListener* const listener) -{ - listeners.remove (listener); -} - -//============================================================================== -bool FileBrowserComponent::isSaveMode() const noexcept -{ - return (flags & saveMode) != 0; -} - -int FileBrowserComponent::getNumSelectedFiles() const noexcept -{ - if (chosenFiles.size() == 0 && currentFileIsValid()) - return 1; - - return chosenFiles.size(); -} - -File FileBrowserComponent::getSelectedFile (int index) const noexcept -{ - if ((flags & canSelectDirectories) != 0 && filenameBox.getText().isEmpty()) - return currentRoot; - - if (! filenameBox.isReadOnly()) - return currentRoot.getChildFile (filenameBox.getText()); - - return chosenFiles[index]; -} - -bool FileBrowserComponent::currentFileIsValid() const -{ - const File f (getSelectedFile (0)); - - if (isSaveMode()) - return (flags & canSelectDirectories) != 0 || ! f.isDirectory(); - - return f.exists(); -} - -File FileBrowserComponent::getHighlightedFile() const noexcept -{ - return fileListComponent->getSelectedFile (0); -} - -void FileBrowserComponent::deselectAllFiles() -{ - fileListComponent->deselectAllFiles(); -} - -//============================================================================== -bool FileBrowserComponent::isFileSuitable (const File& file) const -{ - return (flags & canSelectFiles) != 0 - && (fileFilter == nullptr || fileFilter->isFileSuitable (file)); -} - -bool FileBrowserComponent::isDirectorySuitable (const File&) const -{ - return true; -} - -bool FileBrowserComponent::isFileOrDirSuitable (const File& f) const -{ - if (f.isDirectory()) - return (flags & canSelectDirectories) != 0 - && (fileFilter == nullptr || fileFilter->isDirectorySuitable (f)); - - return (flags & canSelectFiles) != 0 && f.exists() - && (fileFilter == nullptr || fileFilter->isFileSuitable (f)); -} - -//============================================================================== -const File& FileBrowserComponent::getRoot() const -{ - return currentRoot; -} - -void FileBrowserComponent::setRoot (const File& newRootDirectory) -{ - bool callListeners = false; - - if (currentRoot != newRootDirectory) - { - callListeners = true; - fileListComponent->scrollToTop(); - - String path (newRootDirectory.getFullPathName()); - - if (path.isEmpty()) - path = File::separatorString; - - StringArray rootNames, rootPaths; - getRoots (rootNames, rootPaths); - - if (! rootPaths.contains (path, true)) - { - bool alreadyListed = false; - - for (int i = currentPathBox.getNumItems(); --i >= 0;) - { - if (currentPathBox.getItemText (i).equalsIgnoreCase (path)) - { - alreadyListed = true; - break; - } - } - - if (! alreadyListed) - currentPathBox.addItem (path, currentPathBox.getNumItems() + 2); - } - } - - currentRoot = newRootDirectory; - fileList->setDirectory (currentRoot, true, true); - - String currentRootName (currentRoot.getFullPathName()); - if (currentRootName.isEmpty()) - currentRootName = File::separatorString; - - currentPathBox.setText (currentRootName, dontSendNotification); - - goUpButton->setEnabled (currentRoot.getParentDirectory().isDirectory() - && currentRoot.getParentDirectory() != currentRoot); - - if (callListeners) - { - Component::BailOutChecker checker (this); - listeners.callChecked (checker, &FileBrowserListener::browserRootChanged, currentRoot); - } -} - -void FileBrowserComponent::setFileName (const String& newName) -{ - filenameBox.setText (newName, true); - - fileListComponent->setSelectedFile (currentRoot.getChildFile (newName)); -} - -void FileBrowserComponent::resetRecentPaths() -{ - currentPathBox.clear(); - - StringArray rootNames, rootPaths; - getRoots (rootNames, rootPaths); - - for (int i = 0; i < rootNames.size(); ++i) - { - if (rootNames[i].isEmpty()) - currentPathBox.addSeparator(); - else - currentPathBox.addItem (rootNames[i], i + 1); - } - - currentPathBox.addSeparator(); -} - -void FileBrowserComponent::goUp() -{ - setRoot (getRoot().getParentDirectory()); -} - -void FileBrowserComponent::refresh() -{ - fileList->refresh(); -} - -void FileBrowserComponent::setFileFilter (const FileFilter* const newFileFilter) -{ - if (fileFilter != newFileFilter) - { - fileFilter = newFileFilter; - refresh(); - } -} - -String FileBrowserComponent::getActionVerb() const -{ - return isSaveMode() ? ((flags & canSelectDirectories) != 0 ? TRANS("Choose") - : TRANS("Save")) - : TRANS("Open"); -} - -void FileBrowserComponent::setFilenameBoxLabel (const String& name) -{ - fileLabel.setText (name, dontSendNotification); -} - -FilePreviewComponent* FileBrowserComponent::getPreviewComponent() const noexcept -{ - return previewComp; -} - -DirectoryContentsDisplayComponent* FileBrowserComponent::getDisplayComponent() const noexcept -{ - return fileListComponent; -} - -//============================================================================== -void FileBrowserComponent::resized() -{ - getLookAndFeel() - .layoutFileBrowserComponent (*this, fileListComponent, previewComp, - ¤tPathBox, &filenameBox, goUpButton); -} - -//============================================================================== -void FileBrowserComponent::sendListenerChangeMessage() -{ - Component::BailOutChecker checker (this); - - if (previewComp != nullptr) - previewComp->selectedFileChanged (getSelectedFile (0)); - - // You shouldn't delete the browser when the file gets changed! - jassert (! checker.shouldBailOut()); - - listeners.callChecked (checker, &FileBrowserListener::selectionChanged); -} - -void FileBrowserComponent::selectionChanged() -{ - StringArray newFilenames; - bool resetChosenFiles = true; - - for (int i = 0; i < fileListComponent->getNumSelectedFiles(); ++i) - { - const File f (fileListComponent->getSelectedFile (i)); - - if (isFileOrDirSuitable (f)) - { - if (resetChosenFiles) - { - chosenFiles.clear(); - resetChosenFiles = false; - } - - chosenFiles.add (f); - newFilenames.add (f.getRelativePathFrom (getRoot())); - } - } - - if (newFilenames.size() > 0) - filenameBox.setText (newFilenames.joinIntoString (", "), false); - - sendListenerChangeMessage(); -} - -void FileBrowserComponent::fileClicked (const File& f, const MouseEvent& e) -{ - Component::BailOutChecker checker (this); - listeners.callChecked (checker, &FileBrowserListener::fileClicked, f, e); -} - -void FileBrowserComponent::fileDoubleClicked (const File& f) -{ - if (f.isDirectory()) - { - setRoot (f); - - if ((flags & canSelectDirectories) != 0) - filenameBox.setText (String::empty); - } - else - { - Component::BailOutChecker checker (this); - listeners.callChecked (checker, &FileBrowserListener::fileDoubleClicked, f); - } -} - -void FileBrowserComponent::browserRootChanged (const File&) {} - -bool FileBrowserComponent::keyPressed (const KeyPress& key) -{ - (void) key; - - #if JUCE_LINUX || JUCE_WINDOWS - if (key.getModifiers().isCommandDown() - && (key.getKeyCode() == 'H' || key.getKeyCode() == 'h')) - { - fileList->setIgnoresHiddenFiles (! fileList->ignoresHiddenFiles()); - fileList->refresh(); - return true; - } - #endif - - return false; -} - -//============================================================================== -void FileBrowserComponent::textEditorTextChanged (TextEditor&) -{ - sendListenerChangeMessage(); -} - -void FileBrowserComponent::textEditorReturnKeyPressed (TextEditor&) -{ - if (filenameBox.getText().containsChar (File::separator)) - { - const File f (currentRoot.getChildFile (filenameBox.getText())); - - if (f.isDirectory()) - { - setRoot (f); - chosenFiles.clear(); - filenameBox.setText (String::empty); - } - else - { - setRoot (f.getParentDirectory()); - chosenFiles.clear(); - chosenFiles.add (f); - filenameBox.setText (f.getFileName()); - } - } - else - { - fileDoubleClicked (getSelectedFile (0)); - } -} - -void FileBrowserComponent::textEditorEscapeKeyPressed (TextEditor&) -{ -} - -void FileBrowserComponent::textEditorFocusLost (TextEditor&) -{ - if (! isSaveMode()) - selectionChanged(); -} - -//============================================================================== -void FileBrowserComponent::buttonClicked (Button*) -{ - goUp(); -} - -void FileBrowserComponent::comboBoxChanged (ComboBox*) -{ - const String newText (currentPathBox.getText().trim().unquoted()); - - if (newText.isNotEmpty()) - { - const int index = currentPathBox.getSelectedId() - 1; - - StringArray rootNames, rootPaths; - getRoots (rootNames, rootPaths); - - if (rootPaths [index].isNotEmpty()) - { - setRoot (File (rootPaths [index])); - } - else - { - File f (newText); - - for (;;) - { - if (f.isDirectory()) - { - setRoot (f); - break; - } - - if (f.getParentDirectory() == f) - break; - - f = f.getParentDirectory(); - } - } - } -} - -void FileBrowserComponent::getDefaultRoots (StringArray& rootNames, StringArray& rootPaths) -{ - #if JUCE_WINDOWS - Array roots; - File::findFileSystemRoots (roots); - rootPaths.clear(); - - for (int i = 0; i < roots.size(); ++i) - { - const File& drive = roots.getReference(i); - - String name (drive.getFullPathName()); - rootPaths.add (name); - - if (drive.isOnHardDisk()) - { - String volume (drive.getVolumeLabel()); - - if (volume.isEmpty()) - volume = TRANS("Hard Drive"); - - name << " [" << volume << ']'; - } - else if (drive.isOnCDRomDrive()) - { - name << " [" << TRANS("CD/DVD drive") << ']'; - } - - rootNames.add (name); - } - - rootPaths.add (String::empty); - rootNames.add (String::empty); - - rootPaths.add (File::getSpecialLocation (File::userDocumentsDirectory).getFullPathName()); - rootNames.add (TRANS("Documents")); - rootPaths.add (File::getSpecialLocation (File::userMusicDirectory).getFullPathName()); - rootNames.add (TRANS("Music")); - rootPaths.add (File::getSpecialLocation (File::userPicturesDirectory).getFullPathName()); - rootNames.add (TRANS("Pictures")); - rootPaths.add (File::getSpecialLocation (File::userDesktopDirectory).getFullPathName()); - rootNames.add (TRANS("Desktop")); - - #elif JUCE_MAC - rootPaths.add (File::getSpecialLocation (File::userHomeDirectory).getFullPathName()); - rootNames.add (TRANS("Home folder")); - rootPaths.add (File::getSpecialLocation (File::userDocumentsDirectory).getFullPathName()); - rootNames.add (TRANS("Documents")); - rootPaths.add (File::getSpecialLocation (File::userMusicDirectory).getFullPathName()); - rootNames.add (TRANS("Music")); - rootPaths.add (File::getSpecialLocation (File::userPicturesDirectory).getFullPathName()); - rootNames.add (TRANS("Pictures")); - rootPaths.add (File::getSpecialLocation (File::userDesktopDirectory).getFullPathName()); - rootNames.add (TRANS("Desktop")); - - rootPaths.add (String::empty); - rootNames.add (String::empty); - - Array volumes; - File vol ("/Volumes"); - vol.findChildFiles (volumes, File::findDirectories, false); - - for (int i = 0; i < volumes.size(); ++i) - { - const File& volume = volumes.getReference(i); - - if (volume.isDirectory() && ! volume.getFileName().startsWithChar ('.')) - { - rootPaths.add (volume.getFullPathName()); - rootNames.add (volume.getFileName()); - } - } - - #else - rootPaths.add ("/"); - rootNames.add ("/"); - rootPaths.add (File::getSpecialLocation (File::userHomeDirectory).getFullPathName()); - rootNames.add (TRANS("Home folder")); - rootPaths.add (File::getSpecialLocation (File::userDesktopDirectory).getFullPathName()); - rootNames.add (TRANS("Desktop")); - #endif -} - -void FileBrowserComponent::getRoots (StringArray& rootNames, StringArray& rootPaths) -{ - getDefaultRoots (rootNames, rootPaths); -} diff --git a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/filebrowser/juce_FileBrowserComponent.h b/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/filebrowser/juce_FileBrowserComponent.h deleted file mode 100644 index a1151ef02f..0000000000 --- a/examples/AnimationAppExample/JuceLibraryCode/modules/juce_gui_basics/filebrowser/juce_FileBrowserComponent.h +++ /dev/null @@ -1,290 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2013 - Raw Material Software Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_FILEBROWSERCOMPONENT_H_INCLUDED -#define JUCE_FILEBROWSERCOMPONENT_H_INCLUDED - - -//============================================================================== -/** - A component for browsing and selecting a file or directory to open or save. - - This contains a FileListComponent and adds various boxes and controls for - navigating and selecting a file. It can work in different modes so that it can - be used for loading or saving a file, or for choosing a directory. - - @see FileChooserDialogBox, FileChooser, FileListComponent -*/ -class JUCE_API FileBrowserComponent : public Component, - private FileBrowserListener, - private TextEditorListener, - private ButtonListener, - private ComboBoxListener, // (can't use ComboBox::Listener due to idiotic VC2005 bug) - private FileFilter -{ -public: - //============================================================================== - /** Various options for the browser. - - A combination of these is passed into the FileBrowserComponent constructor. - */ - enum FileChooserFlags - { - openMode = 1, /**< specifies that the component should allow the user to - choose an existing file with the intention of opening it. */ - saveMode = 2, /**< specifies that the component should allow the user to specify - the name of a file that will be used to save something. */ - canSelectFiles = 4, /**< specifies that the user can select files (can be used in - conjunction with canSelectDirectories). */ - canSelectDirectories = 8, /**< specifies that the user can select directories (can be used in - conjuction with canSelectFiles). */ - canSelectMultipleItems = 16, /**< specifies that the user can select multiple items. */ - useTreeView = 32, /**< specifies that a tree-view should be shown instead of a file list. */ - filenameBoxIsReadOnly = 64, /**< specifies that the user can't type directly into the filename box. */ - warnAboutOverwriting = 128 /**< specifies that the dialog should warn about overwriting existing files (if possible). */ - }; - - //============================================================================== - /** Creates a FileBrowserComponent. - - @param flags A combination of flags from the FileChooserFlags enumeration, used to - specify the component's behaviour. The flags must contain either openMode - or saveMode, and canSelectFiles and/or canSelectDirectories. - @param initialFileOrDirectory The file or directory that should be selected when the component begins. - If this is File::nonexistent, a default directory will be chosen. - @param fileFilter an optional filter to use to determine which files are shown. - If this is nullptr then all files are displayed. Note that a pointer - is kept internally to this object, so make sure that it is not deleted - before the FileBrowserComponent object is deleted. - @param previewComp an optional preview component that will be used to show previews of - files that the user selects - */ - FileBrowserComponent (int flags, - const File& initialFileOrDirectory, - const FileFilter* fileFilter, - FilePreviewComponent* previewComp); - - /** Destructor. */ - ~FileBrowserComponent(); - - //============================================================================== - /** Returns the number of files that the user has got selected. - If multiple select isn't active, this will only be 0 or 1. To get the complete - list of files they've chosen, pass an index to getCurrentFile(). - */ - int getNumSelectedFiles() const noexcept; - - /** Returns one of the files that the user has chosen. - If the box has multi-select enabled, the index lets you specify which of the files - to get - see getNumSelectedFiles() to find out how many files were chosen. - @see getHighlightedFile - */ - File getSelectedFile (int index) const noexcept; - - /** Deselects any files that are currently selected. - */ - void deselectAllFiles(); - - /** Returns true if the currently selected file(s) are usable. - - This can be used to decide whether the user can press "ok" for the - current file. What it does depends on the mode, so for example in an "open" - mode, this only returns true if a file has been selected and if it exists. - In a "save" mode, a non-existent file would also be valid. - */ - bool currentFileIsValid() const; - - /** This returns the last item in the view that the user has highlighted. - This may be different from getCurrentFile(), which returns the value - that is shown in the filename box, and if there are multiple selections, - this will only return one of them. - @see getSelectedFile - */ - File getHighlightedFile() const noexcept; - - //============================================================================== - /** Returns the directory whose contents are currently being shown in the listbox. */ - const File& getRoot() const; - - /** Changes the directory that's being shown in the listbox. */ - void setRoot (const File& newRootDirectory); - - /** Changes the name that is currently shown in the filename box. */ - void setFileName (const String& newName); - - /** Equivalent to pressing the "up" button to browse the parent directory. */ - void goUp(); - - /** Refreshes the directory that's currently being listed. */ - void refresh(); - - /** Changes the filter that's being used to sift the files. */ - void setFileFilter (const FileFilter* newFileFilter); - - /** Returns a verb to describe what should happen when the file is accepted. - - E.g. if browsing in "load file" mode, this will be "Open", if in "save file" - mode, it'll be "Save", etc. - */ - virtual String getActionVerb() const; - - /** Returns true if the saveMode flag was set when this component was created. - */ - bool isSaveMode() const noexcept; - - /** Sets the label that will be displayed next to the filename entry box. - By default this is just "file", but you might want to change it to something more - appropriate for your app. - */ - void setFilenameBoxLabel (const String& name); - - //============================================================================== - /** Adds a listener to be told when the user selects and clicks on files. - @see removeListener - */ - void addListener (FileBrowserListener* listener); - - /** Removes a listener. - @see addListener - */ - void removeListener (FileBrowserListener* listener); - - /** Returns a platform-specific list of names and paths for some suggested places the user - might want to use as root folders. - The list returned contains empty strings to indicate section breaks. - @see getRoots() - */ - static void getDefaultRoots (StringArray& rootNames, StringArray& rootPaths); - - //============================================================================== - /** This abstract base class is implemented by LookAndFeel classes to provide - various file-browser layout and drawing methods. - */ - struct JUCE_API LookAndFeelMethods - { - virtual ~LookAndFeelMethods() {} - - // These return a pointer to an internally cached drawable - make sure you don't keep - // a copy of this pointer anywhere, as it may become invalid in the future. - virtual const Drawable* getDefaultFolderImage() = 0; - virtual const Drawable* getDefaultDocumentFileImage() = 0; - - virtual AttributedString createFileChooserHeaderText (const String& title, - const String& instructions) = 0; - - virtual void drawFileBrowserRow (Graphics&, int width, int height, - const String& filename, - Image* optionalIcon, - const String& fileSizeDescription, - const String& fileTimeDescription, - bool isDirectory, - bool isItemSelected, - int itemIndex, - DirectoryContentsDisplayComponent&) = 0; - - virtual Button* createFileBrowserGoUpButton() = 0; - - virtual void layoutFileBrowserComponent (FileBrowserComponent& browserComp, - DirectoryContentsDisplayComponent* fileListComponent, - FilePreviewComponent* previewComp, - ComboBox* currentPathBox, - TextEditor* filenameBox, - Button* goUpButton) = 0; - }; - - //============================================================================== - /** @internal */ - void resized() override; - /** @internal */ - void buttonClicked (Button*) override; - /** @internal */ - void comboBoxChanged (ComboBox*) override; - /** @internal */ - void textEditorTextChanged (TextEditor&) override; - /** @internal */ - void textEditorReturnKeyPressed (TextEditor&) override; - /** @internal */ - void textEditorEscapeKeyPressed (TextEditor&) override; - /** @internal */ - void textEditorFocusLost (TextEditor&) override; - /** @internal */ - bool keyPressed (const KeyPress&) override; - /** @internal */ - void selectionChanged() override; - /** @internal */ - void fileClicked (const File&, const MouseEvent&) override; - /** @internal */ - void fileDoubleClicked (const File&) override; - /** @internal */ - void browserRootChanged (const File&) override; - /** @internal */ - bool isFileSuitable (const File&) const override; - /** @internal */ - bool isDirectorySuitable (const File&) const override; - - /** @internal */ - FilePreviewComponent* getPreviewComponent() const noexcept; - - /** @internal */ - DirectoryContentsDisplayComponent* getDisplayComponent() const noexcept; - -protected: - /** Returns a list of names and paths for the default places the user might want to look. - - By default this just calls getDefaultRoots(), but you may want to override it to - return a custom list. - */ - virtual void getRoots (StringArray& rootNames, StringArray& rootPaths); - - /** Updates the items in the dropdown list of recent paths with the values from getRoots(). */ - void resetRecentPaths(); - -private: - //============================================================================== - ScopedPointer fileList; - const FileFilter* fileFilter; - - int flags; - File currentRoot; - Array chosenFiles; - ListenerList listeners; - - ScopedPointer fileListComponent; - FilePreviewComponent* previewComp; - ComboBox currentPathBox; - TextEditor filenameBox; - Label fileLabel; - ScopedPointer