Browse Source

Added Inter-App Audio capabilities to standalone plug-ins

tags/2021-05-28
tpoole 8 years ago
parent
commit
4c59a920b4
80 changed files with 2949 additions and 163 deletions
  1. +62
    -0
      examples/PlugInSamples/InterAppAudioEffect/Builds/iOS/Info-Standalone_Plugin.plist
  2. +8
    -0
      examples/PlugInSamples/InterAppAudioEffect/Builds/iOS/InterAppAudioEffect.entitlements
  3. +373
    -0
      examples/PlugInSamples/InterAppAudioEffect/Builds/iOS/InterAppAudioEffect.xcodeproj/project.pbxproj
  4. BIN
      examples/PlugInSamples/InterAppAudioEffect/Builds/iOS/InterAppAudioEffect/Images.xcassets/LaunchImage.launchimage/LaunchImage-ipad-landscape-1x.png
  5. BIN
      examples/PlugInSamples/InterAppAudioEffect/Builds/iOS/InterAppAudioEffect/Images.xcassets/LaunchImage.launchimage/LaunchImage-ipad-landscape-2x.png
  6. BIN
      examples/PlugInSamples/InterAppAudioEffect/Builds/iOS/InterAppAudioEffect/Images.xcassets/LaunchImage.launchimage/LaunchImage-ipad-portrait-1x.png
  7. BIN
      examples/PlugInSamples/InterAppAudioEffect/Builds/iOS/InterAppAudioEffect/Images.xcassets/LaunchImage.launchimage/LaunchImage-ipad-portrait-2x.png
  8. BIN
      examples/PlugInSamples/InterAppAudioEffect/Builds/iOS/InterAppAudioEffect/Images.xcassets/LaunchImage.launchimage/LaunchImage-iphone-2x.png
  9. BIN
      examples/PlugInSamples/InterAppAudioEffect/Builds/iOS/InterAppAudioEffect/Images.xcassets/LaunchImage.launchimage/LaunchImage-iphone-retina4.png
  10. +63
    -0
      examples/PlugInSamples/InterAppAudioEffect/InterAppAudioEffect.jucer
  11. +363
    -0
      examples/PlugInSamples/InterAppAudioEffect/JuceLibraryCode/AppConfig.h
  12. +44
    -0
      examples/PlugInSamples/InterAppAudioEffect/JuceLibraryCode/JuceHeader.h
  13. +12
    -0
      examples/PlugInSamples/InterAppAudioEffect/JuceLibraryCode/ReadMe.txt
  14. +9
    -0
      examples/PlugInSamples/InterAppAudioEffect/JuceLibraryCode/juce_audio_basics.cpp
  15. +9
    -0
      examples/PlugInSamples/InterAppAudioEffect/JuceLibraryCode/juce_audio_basics.mm
  16. +9
    -0
      examples/PlugInSamples/InterAppAudioEffect/JuceLibraryCode/juce_audio_devices.cpp
  17. +9
    -0
      examples/PlugInSamples/InterAppAudioEffect/JuceLibraryCode/juce_audio_devices.mm
  18. +9
    -0
      examples/PlugInSamples/InterAppAudioEffect/JuceLibraryCode/juce_audio_formats.cpp
  19. +9
    -0
      examples/PlugInSamples/InterAppAudioEffect/JuceLibraryCode/juce_audio_formats.mm
  20. +9
    -0
      examples/PlugInSamples/InterAppAudioEffect/JuceLibraryCode/juce_audio_plugin_client_AAX.cpp
  21. +9
    -0
      examples/PlugInSamples/InterAppAudioEffect/JuceLibraryCode/juce_audio_plugin_client_AAX.mm
  22. +9
    -0
      examples/PlugInSamples/InterAppAudioEffect/JuceLibraryCode/juce_audio_plugin_client_AU_1.mm
  23. +9
    -0
      examples/PlugInSamples/InterAppAudioEffect/JuceLibraryCode/juce_audio_plugin_client_AU_2.mm
  24. +9
    -0
      examples/PlugInSamples/InterAppAudioEffect/JuceLibraryCode/juce_audio_plugin_client_AUv3.mm
  25. +9
    -0
      examples/PlugInSamples/InterAppAudioEffect/JuceLibraryCode/juce_audio_plugin_client_RTAS_1.cpp
  26. +9
    -0
      examples/PlugInSamples/InterAppAudioEffect/JuceLibraryCode/juce_audio_plugin_client_RTAS_2.cpp
  27. +9
    -0
      examples/PlugInSamples/InterAppAudioEffect/JuceLibraryCode/juce_audio_plugin_client_RTAS_3.cpp
  28. +9
    -0
      examples/PlugInSamples/InterAppAudioEffect/JuceLibraryCode/juce_audio_plugin_client_RTAS_4.cpp
  29. +9
    -0
      examples/PlugInSamples/InterAppAudioEffect/JuceLibraryCode/juce_audio_plugin_client_RTAS_utils.cpp
  30. +9
    -0
      examples/PlugInSamples/InterAppAudioEffect/JuceLibraryCode/juce_audio_plugin_client_RTAS_utils.mm
  31. +9
    -0
      examples/PlugInSamples/InterAppAudioEffect/JuceLibraryCode/juce_audio_plugin_client_Standalone.cpp
  32. +9
    -0
      examples/PlugInSamples/InterAppAudioEffect/JuceLibraryCode/juce_audio_plugin_client_VST2.cpp
  33. +9
    -0
      examples/PlugInSamples/InterAppAudioEffect/JuceLibraryCode/juce_audio_plugin_client_VST3.cpp
  34. +9
    -0
      examples/PlugInSamples/InterAppAudioEffect/JuceLibraryCode/juce_audio_plugin_client_VST_utils.mm
  35. +9
    -0
      examples/PlugInSamples/InterAppAudioEffect/JuceLibraryCode/juce_audio_plugin_client_utils.cpp
  36. +9
    -0
      examples/PlugInSamples/InterAppAudioEffect/JuceLibraryCode/juce_audio_processors.cpp
  37. +9
    -0
      examples/PlugInSamples/InterAppAudioEffect/JuceLibraryCode/juce_audio_processors.mm
  38. +9
    -0
      examples/PlugInSamples/InterAppAudioEffect/JuceLibraryCode/juce_audio_utils.cpp
  39. +9
    -0
      examples/PlugInSamples/InterAppAudioEffect/JuceLibraryCode/juce_audio_utils.mm
  40. +9
    -0
      examples/PlugInSamples/InterAppAudioEffect/JuceLibraryCode/juce_core.cpp
  41. +9
    -0
      examples/PlugInSamples/InterAppAudioEffect/JuceLibraryCode/juce_core.mm
  42. +9
    -0
      examples/PlugInSamples/InterAppAudioEffect/JuceLibraryCode/juce_data_structures.cpp
  43. +9
    -0
      examples/PlugInSamples/InterAppAudioEffect/JuceLibraryCode/juce_data_structures.mm
  44. +9
    -0
      examples/PlugInSamples/InterAppAudioEffect/JuceLibraryCode/juce_events.cpp
  45. +9
    -0
      examples/PlugInSamples/InterAppAudioEffect/JuceLibraryCode/juce_events.mm
  46. +9
    -0
      examples/PlugInSamples/InterAppAudioEffect/JuceLibraryCode/juce_graphics.cpp
  47. +9
    -0
      examples/PlugInSamples/InterAppAudioEffect/JuceLibraryCode/juce_graphics.mm
  48. +9
    -0
      examples/PlugInSamples/InterAppAudioEffect/JuceLibraryCode/juce_gui_basics.cpp
  49. +9
    -0
      examples/PlugInSamples/InterAppAudioEffect/JuceLibraryCode/juce_gui_basics.mm
  50. +9
    -0
      examples/PlugInSamples/InterAppAudioEffect/JuceLibraryCode/juce_gui_extra.cpp
  51. +9
    -0
      examples/PlugInSamples/InterAppAudioEffect/JuceLibraryCode/juce_gui_extra.mm
  52. +277
    -0
      examples/PlugInSamples/InterAppAudioEffect/Source/IAAEffectEditor.h
  53. +169
    -0
      examples/PlugInSamples/InterAppAudioEffect/Source/IAAEffectProcessor.cpp
  54. +78
    -0
      examples/PlugInSamples/InterAppAudioEffect/Source/IAAEffectProcessor.h
  55. +97
    -0
      examples/PlugInSamples/InterAppAudioEffect/Source/SimpleMeter.h
  56. +71
    -21
      extras/Projucer/Source/Project Saving/jucer_ProjectExport_XCode.h
  57. +4
    -0
      extras/Projucer/Source/Project Saving/jucer_ProjectSaver.cpp
  58. +32
    -0
      extras/Projucer/Source/Project/jucer_Project.cpp
  59. +4
    -0
      extras/Projucer/Source/Project/jucer_Project.h
  60. +12
    -0
      modules/juce_audio_basics/audio_play_head/juce_AudioPlayHead.h
  61. +1
    -0
      modules/juce_audio_basics/juce_audio_basics.h
  62. +1
    -0
      modules/juce_audio_devices/juce_audio_devices.cpp
  63. +7
    -3
      modules/juce_audio_devices/juce_audio_devices.h
  64. +407
    -132
      modules/juce_audio_devices/native/juce_ios_Audio.cpp
  65. +107
    -0
      modules/juce_audio_devices/native/juce_ios_Audio.h
  66. +9
    -0
      modules/juce_audio_plugin_client/AU/juce_AUv3_Wrapper.mm
  67. +31
    -0
      modules/juce_audio_plugin_client/Standalone/juce_StandaloneFilterApp.cpp
  68. +62
    -1
      modules/juce_audio_plugin_client/Standalone/juce_StandaloneFilterWindow.h
  69. +8
    -0
      modules/juce_audio_plugin_client/utility/juce_PluginHostType.h
  70. +52
    -0
      modules/juce_audio_plugin_client/utility/juce_PluginUtilities.cpp
  71. +0
    -1
      modules/juce_audio_processors/juce_audio_processors.h
  72. +13
    -3
      modules/juce_graphics/image_formats/juce_JPEGLoader.cpp
  73. +4
    -0
      modules/juce_graphics/juce_graphics.cpp
  74. +1
    -1
      modules/juce_graphics/juce_graphics.h
  75. +28
    -0
      modules/juce_graphics/native/juce_android_IconHelpers.cpp
  76. +28
    -0
      modules/juce_graphics/native/juce_linux_IconHelpers.cpp
  77. +12
    -1
      modules/juce_graphics/native/juce_mac_CoreGraphicsContext.mm
  78. +4
    -0
      modules/juce_graphics/native/juce_mac_CoreGraphicsHelpers.h
  79. +135
    -0
      modules/juce_graphics/native/juce_mac_IconHelpers.cpp
  80. +28
    -0
      modules/juce_graphics/native/juce_win32_IconHelpers.cpp

+ 62
- 0
examples/PlugInSamples/InterAppAudioEffect/Builds/iOS/Info-Standalone_Plugin.plist View File

@@ -0,0 +1,62 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist>
<dict>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>NSMicrophoneUsageDescription</key>
<string>This app requires microphone input.</string>
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleName</key>
<string>InterAppAudioEffect</string>
<key>CFBundleDisplayName</key>
<string>InterAppAudioEffect</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleShortVersionString</key>
<string>1.0.0</string>
<key>CFBundleVersion</key>
<string>1.0.0</string>
<key>NSHumanReadableCopyright</key>
<string>ROLI Ltd.</string>
<key>NSHighResolutionCapable</key>
<true/>
<key>UIRequiresFullScreen</key>
<true/>
<key>UIStatusBarHidden</key>
<true/>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UIBackgroundModes</key>
<array>
<string>audio</string>
</array>
<key>AudioComponents</key>
<array>
<dict>
<key>name</key>
<string>ROLI Ltd.: InterAppAudioEffect</string>
<key>manufacturer</key>
<string>ROLI</string>
<key>type</key>
<string>aurx</string>
<key>subtype</key>
<string>IAAE</string>
<key>version</key>
<integer>65536</integer>
</dict>
</array>
</dict>
</plist>

+ 8
- 0
examples/PlugInSamples/InterAppAudioEffect/Builds/iOS/InterAppAudioEffect.entitlements View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>inter-app-audio</key>
<true/>
</dict>
</plist>

+ 373
- 0
examples/PlugInSamples/InterAppAudioEffect/Builds/iOS/InterAppAudioEffect.xcodeproj/project.pbxproj View File

@@ -0,0 +1,373 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {

48524E1776017288798AB20A = {isa = PBXBuildFile; fileRef = E9D6BA12BDD1947BDDAE08F7; };
8EF8670E422BB9CF164302DF = {isa = PBXBuildFile; fileRef = 873711620EC157BCCFFF80B1; };
61D6F1506B76AFBA614F491E = {isa = PBXBuildFile; fileRef = 67BBA32BE9EE1CAF8A105F6A; };
03A7A8C261C0A1B578F219EF = {isa = PBXBuildFile; fileRef = E43030B35C6CB127DC67FEE7; };
E9FB1841DE3518ADBD86293C = {isa = PBXBuildFile; fileRef = 53BB9950BAA9E837613ED83B; };
7B71DA92A48B9D67BA68C69E = {isa = PBXBuildFile; fileRef = 212019C041EE17C23460CE02; };
BC8485848043996AFA210EF9 = {isa = PBXBuildFile; fileRef = C293562C310CB0B3259811F0; };
7FF11BF2317D79501E0632DB = {isa = PBXBuildFile; fileRef = E4431E84242848EF9D250FC7; };
DD2143886468728A97F9586E = {isa = PBXBuildFile; fileRef = C43FC3A63342AA4CDE8F0906; };
EE6B5FC34FB47B41336EA293 = {isa = PBXBuildFile; fileRef = AD9B42ED650058295A747510; };
B2E5CB24DBACF25E2CBAC9A1 = {isa = PBXBuildFile; fileRef = F07FA71EC2B5FCA584FAA10B; };
6FAEC70FAE3DBC629160F86C = {isa = PBXBuildFile; fileRef = 41CB50701EE5BFDCE1F89BBA; };
DFF48C0819F2191B154569A9 = {isa = PBXBuildFile; fileRef = B69C94CF64688C5270D8122C; };
9BB46E700B9A4617B4CFDC24 = {isa = PBXBuildFile; fileRef = 82F310E23852E0C002F5A2D1; };
4EC4A8C3AF328E40626CBAE7 = {isa = PBXBuildFile; fileRef = E5A657DE5A5B1516B3E35FA8; };
9A7D9D7490AF3D82BA8D9686 = {isa = PBXBuildFile; fileRef = 2C4476A46744766A478A74B6; };
40833B424B5E9EC84C09EE40 = {isa = PBXBuildFile; fileRef = 131A768FD64EB99097B0B190; };
7ACC830E1DDF0F171C890B2B = {isa = PBXBuildFile; fileRef = 7C1F5AA6FE8016951F45F916; };
78BD211C42E345A8048DEDD5 = {isa = PBXBuildFile; fileRef = 0EB1F323BA52207C49A27479; };
A49F3F55F083BAD332CA4324 = {isa = PBXBuildFile; fileRef = 223C6D257BB45525A7C2D495; };
B2BE378326805DEBB71B3016 = {isa = PBXBuildFile; fileRef = D9C8C1E2D3F27800C6E774D7; };
BCA424EEB2F9F33372CA4909 = {isa = PBXBuildFile; fileRef = CDCF152172E34769B268ECDA; };
246490CF3D197E69B1F7FCC8 = {isa = PBXBuildFile; fileRef = 02ABCEB5E369CDE6AEA817B3; };
873E620B819DC84C953EC518 = {isa = PBXBuildFile; fileRef = 32E0486AA56B56AD10D18A56; };
40E6F5A9B432DEB7689AF7D0 = {isa = PBXBuildFile; fileRef = 4B55841B06C897F72BC2F8CE; };
78412E76B9D1D75907390309 = {isa = PBXBuildFile; fileRef = C450D63325E2C29C72B6606C; };
E3DD6181D2A4E2703637E1EF = {isa = PBXBuildFile; fileRef = 36A796A962C81B44E9233775; };
E8410AF631A96357D2807C3A = {isa = PBXBuildFile; fileRef = 10EEE1E56B53B7A31753365C; };
DCEE24917F78097ACF14EAD0 = {isa = PBXBuildFile; fileRef = 1F042A6F2A0986F23B7097FC; };
CA28F22C95EBC20CB37612FF = {isa = PBXBuildFile; fileRef = A3BDBD773FBCCD4F9440D174; };
02ABCEB5E369CDE6AEA817B3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_audio_processors.mm"; path = "../../JuceLibraryCode/juce_audio_processors.mm"; sourceTree = "SOURCE_ROOT"; };
0EB1F323BA52207C49A27479 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_audio_formats.mm"; path = "../../JuceLibraryCode/juce_audio_formats.mm"; sourceTree = "SOURCE_ROOT"; };
10EEE1E56B53B7A31753365C = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_graphics.mm"; path = "../../JuceLibraryCode/juce_graphics.mm"; sourceTree = "SOURCE_ROOT"; };
131A768FD64EB99097B0B190 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_audio_basics.mm"; path = "../../JuceLibraryCode/juce_audio_basics.mm"; sourceTree = "SOURCE_ROOT"; };
1F042A6F2A0986F23B7097FC = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_gui_basics.mm"; path = "../../JuceLibraryCode/juce_gui_basics.mm"; sourceTree = "SOURCE_ROOT"; };
212019C041EE17C23460CE02 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; path = System/Library/Frameworks/CoreAudio.framework; sourceTree = SDKROOT; };
223C6D257BB45525A7C2D495 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_audio_plugin_client_Standalone.cpp"; path = "../../JuceLibraryCode/juce_audio_plugin_client_Standalone.cpp"; sourceTree = "SOURCE_ROOT"; };
2A2D7663F8BC39E97FF490E3 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_core"; path = "../../../../../modules/juce_core"; sourceTree = "SOURCE_ROOT"; };
2C4476A46744766A478A74B6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = IAAEffectProcessor.cpp; path = ../../Source/IAAEffectProcessor.cpp; sourceTree = "SOURCE_ROOT"; };
3158E31C9E0DBE333E275FB1 = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = InterAppAudioEffect.entitlements; path = InterAppAudioEffect.entitlements; sourceTree = "SOURCE_ROOT"; };
32E0486AA56B56AD10D18A56 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_audio_utils.mm"; path = "../../JuceLibraryCode/juce_audio_utils.mm"; sourceTree = "SOURCE_ROOT"; };
36A796A962C81B44E9233775 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_events.mm"; path = "../../JuceLibraryCode/juce_events.mm"; sourceTree = "SOURCE_ROOT"; };
41CB50701EE5BFDCE1F89BBA = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
4B55841B06C897F72BC2F8CE = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_core.mm"; path = "../../JuceLibraryCode/juce_core.mm"; sourceTree = "SOURCE_ROOT"; };
4D36B733C9B175319B696E33 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = AppConfig.h; path = ../../JuceLibraryCode/AppConfig.h; sourceTree = "SOURCE_ROOT"; };
50724579E5DD043CD53B0C95 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_audio_plugin_client"; path = "../../../../../modules/juce_audio_plugin_client"; sourceTree = "SOURCE_ROOT"; };
51A5B253018FC02A6AFB7416 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_audio_processors"; path = "../../../../../modules/juce_audio_processors"; sourceTree = "SOURCE_ROOT"; };
53BB9950BAA9E837613ED83B = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = System/Library/Frameworks/AVFoundation.framework; sourceTree = SDKROOT; };
54EEC3679EBFF5E6C7B580F1 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_data_structures"; path = "../../../../../modules/juce_data_structures"; sourceTree = "SOURCE_ROOT"; };
59469A0541A1B91E7968B8FC = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_gui_extra"; path = "../../../../../modules/juce_gui_extra"; sourceTree = "SOURCE_ROOT"; };
67BBA32BE9EE1CAF8A105F6A = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Accelerate.framework; path = System/Library/Frameworks/Accelerate.framework; sourceTree = SDKROOT; };
6E90633D52FCA2BC0B99F9F2 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_audio_formats"; path = "../../../../../modules/juce_audio_formats"; sourceTree = "SOURCE_ROOT"; };
746E2820600C97BD2E760C34 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = IAAEffectEditor.h; path = ../../Source/IAAEffectEditor.h; sourceTree = "SOURCE_ROOT"; };
78F41A05666E3B38C9FDE9D3 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_events"; path = "../../../../../modules/juce_events"; sourceTree = "SOURCE_ROOT"; };
7B37ABD2C5B9FF909250C8DE = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = "Info-Standalone_Plugin.plist"; path = "Info-Standalone_Plugin.plist"; sourceTree = "SOURCE_ROOT"; };
7C1F5AA6FE8016951F45F916 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_audio_devices.mm"; path = "../../JuceLibraryCode/juce_audio_devices.mm"; sourceTree = "SOURCE_ROOT"; };
82F310E23852E0C002F5A2D1 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
9C809DD426D6B660393427D4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SimpleMeter.h; path = ../../Source/SimpleMeter.h; sourceTree = "SOURCE_ROOT"; };
A3BDBD773FBCCD4F9440D174 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_gui_extra.mm"; path = "../../JuceLibraryCode/juce_gui_extra.mm"; sourceTree = "SOURCE_ROOT"; };
AD9B42ED650058295A747510 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMIDI.framework; path = System/Library/Frameworks/CoreMIDI.framework; sourceTree = SDKROOT; };
B3D01A391D4DF11709AE5688 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = JuceHeader.h; path = ../../JuceLibraryCode/JuceHeader.h; sourceTree = "SOURCE_ROOT"; };
B69C94CF64688C5270D8122C = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
C1507624A4C7CFDCE375CEB6 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_graphics"; path = "../../../../../modules/juce_graphics"; sourceTree = "SOURCE_ROOT"; };
C21DF85AC43B32B0E0735A3E = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = IAAEffectProcessor.h; path = ../../Source/IAAEffectProcessor.h; sourceTree = "SOURCE_ROOT"; };
C293562C310CB0B3259811F0 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudioKit.framework; path = System/Library/Frameworks/CoreAudioKit.framework; sourceTree = SDKROOT; };
C43FC3A63342AA4CDE8F0906 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreImage.framework; path = System/Library/Frameworks/CoreImage.framework; sourceTree = SDKROOT; };
C450D63325E2C29C72B6606C = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_data_structures.mm"; path = "../../JuceLibraryCode/juce_data_structures.mm"; sourceTree = "SOURCE_ROOT"; };
C6F57BB192F1BC9BE7D82F99 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_audio_devices"; path = "../../../../../modules/juce_audio_devices"; sourceTree = "SOURCE_ROOT"; };
CB7EB47782C231D8D6CD52FD = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_audio_basics"; path = "../../../../../modules/juce_audio_basics"; sourceTree = "SOURCE_ROOT"; };
CDCF152172E34769B268ECDA = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_audio_plugin_client_VST_utils.mm"; path = "../../JuceLibraryCode/juce_audio_plugin_client_VST_utils.mm"; sourceTree = "SOURCE_ROOT"; };
E43030B35C6CB127DC67FEE7 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; };
E4431E84242848EF9D250FC7 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
E9D6BA12BDD1947BDDAE08F7 = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = InterAppAudioEffect.app; sourceTree = "BUILT_PRODUCTS_DIR"; };
873711620EC157BCCFFF80B1 = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libInterAppAudioEffect.a; sourceTree = "BUILT_PRODUCTS_DIR"; };
D9C8C1E2D3F27800C6E774D7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_audio_plugin_client_utils.cpp"; path = "../../JuceLibraryCode/juce_audio_plugin_client_utils.cpp"; sourceTree = "SOURCE_ROOT"; };
E5A657DE5A5B1516B3E35FA8 = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = InterAppAudioEffect/Images.xcassets; sourceTree = "SOURCE_ROOT"; };
EBA214D367A10FDDC99E8922 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_audio_utils"; path = "../../../../../modules/juce_audio_utils"; sourceTree = "SOURCE_ROOT"; };
F07FA71EC2B5FCA584FAA10B = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreText.framework; path = System/Library/Frameworks/CoreText.framework; sourceTree = SDKROOT; };
FEBA6F6C0A62E2749D6ACC88 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_gui_basics"; path = "../../../../../modules/juce_gui_basics"; sourceTree = "SOURCE_ROOT"; };
9D54126CE5CE65025DE4742F = {isa = PBXGroup; children = (
C21DF85AC43B32B0E0735A3E,
2C4476A46744766A478A74B6,
746E2820600C97BD2E760C34,
9C809DD426D6B660393427D4, ); name = Source; sourceTree = "<group>"; };
EB371D6195C6398C6F1946EF = {isa = PBXGroup; children = (
9D54126CE5CE65025DE4742F, ); name = InterAppAudioEffect; sourceTree = "<group>"; };
3CDCF2D2F9AA23710946CF21 = {isa = PBXGroup; children = (
CB7EB47782C231D8D6CD52FD,
C6F57BB192F1BC9BE7D82F99,
6E90633D52FCA2BC0B99F9F2,
50724579E5DD043CD53B0C95,
51A5B253018FC02A6AFB7416,
EBA214D367A10FDDC99E8922,
2A2D7663F8BC39E97FF490E3,
54EEC3679EBFF5E6C7B580F1,
78F41A05666E3B38C9FDE9D3,
C1507624A4C7CFDCE375CEB6,
FEBA6F6C0A62E2749D6ACC88,
59469A0541A1B91E7968B8FC, ); name = "Juce Modules"; sourceTree = "<group>"; };
C560791DA1D2E0CA6690BC9E = {isa = PBXGroup; children = (
4D36B733C9B175319B696E33,
131A768FD64EB99097B0B190,
7C1F5AA6FE8016951F45F916,
0EB1F323BA52207C49A27479,
223C6D257BB45525A7C2D495,
D9C8C1E2D3F27800C6E774D7,
CDCF152172E34769B268ECDA,
02ABCEB5E369CDE6AEA817B3,
32E0486AA56B56AD10D18A56,
4B55841B06C897F72BC2F8CE,
C450D63325E2C29C72B6606C,
36A796A962C81B44E9233775,
10EEE1E56B53B7A31753365C,
1F042A6F2A0986F23B7097FC,
A3BDBD773FBCCD4F9440D174,
B3D01A391D4DF11709AE5688, ); name = "Juce Library Code"; sourceTree = "<group>"; };
E1CFC4C60E9EC5DBE60DB32F = {isa = PBXGroup; children = (
7B37ABD2C5B9FF909250C8DE,
E5A657DE5A5B1516B3E35FA8, ); name = Resources; sourceTree = "<group>"; };
BF7815807DD5B5FAF4BC3669 = {isa = PBXGroup; children = (
67BBA32BE9EE1CAF8A105F6A,
E43030B35C6CB127DC67FEE7,
53BB9950BAA9E837613ED83B,
212019C041EE17C23460CE02,
C293562C310CB0B3259811F0,
E4431E84242848EF9D250FC7,
C43FC3A63342AA4CDE8F0906,
AD9B42ED650058295A747510,
F07FA71EC2B5FCA584FAA10B,
41CB50701EE5BFDCE1F89BBA,
B69C94CF64688C5270D8122C,
82F310E23852E0C002F5A2D1, ); name = Frameworks; sourceTree = "<group>"; };
196E6AA022E8A0902AB15281 = {isa = PBXGroup; children = (
E9D6BA12BDD1947BDDAE08F7,
873711620EC157BCCFFF80B1, ); name = Products; sourceTree = "<group>"; };
EC01685A042C62251C5AF093 = {isa = PBXGroup; children = (
3158E31C9E0DBE333E275FB1,
EB371D6195C6398C6F1946EF,
3CDCF2D2F9AA23710946CF21,
C560791DA1D2E0CA6690BC9E,
E1CFC4C60E9EC5DBE60DB32F,
BF7815807DD5B5FAF4BC3669,
196E6AA022E8A0902AB15281, ); name = Source; sourceTree = "<group>"; };
22DBBF091193373BEA063A5B = {isa = XCBuildConfiguration; buildSettings = { }; name = Debug; };
54D411166886E8F3BBC0E25F = {isa = XCBuildConfiguration; buildSettings = { }; name = Release; };
8DA1E39A676F877EB549B8CA = {isa = XCBuildConfiguration; buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
CLANG_CXX_LANGUAGE_STANDARD = "c++0x";
CLANG_LINK_OBJC_RUNTIME = NO;
CODE_SIGN_ENTITLEMENTS = "InterAppAudioEffect.entitlements";
COMBINE_HIDPI_IMAGES = YES;
CONFIGURATION_BUILD_DIR = "$(PROJECT_DIR)/build/$(CONFIGURATION)";
COPY_PHASE_STRIP = NO;
GCC_DYNAMIC_NO_PIC = NO;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"_DEBUG=1",
"DEBUG=1",
"JUCER_XCODE_IPHONE_5BC26AE3=1",
"JUCE_APP_VERSION=1.0.0",
"JUCE_APP_VERSION_HEX=0x10000",
"JucePlugin_Build_VST=0",
"JucePlugin_Build_VST3=0",
"JucePlugin_Build_AU=0",
"JucePlugin_Build_AUv3=0",
"JucePlugin_Build_RTAS=0",
"JucePlugin_Build_AAX=0",
"JucePlugin_Build_Standalone=1", );
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
HEADER_SEARCH_PATHS = ("../../JuceLibraryCode", "../../../../../modules", "$(inherited)");
INFOPLIST_FILE = Info-Standalone_Plugin.plist;
OTHER_CPLUSPLUSFLAGS = "-Wall -Wshadow -Wno-missing-field-initializers -Wshadow -Wshorten-64-to-32 -Wstrict-aliasing -Wuninitialized -Wunused-parameter -Wconversion -Wsign-compare -Wint-conversion -Woverloaded-virtual -Wreorder -Wconstant-conversion -Wsign-conversion";
OTHER_LDFLAGS = "-lInterAppAudioEffect";
PRODUCT_BUNDLE_IDENTIFIER = com.yourcompany.InterAppAudioEffect; }; name = Debug; };
07EA55A19B872E1F49C62539 = {isa = XCBuildConfiguration; buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
CLANG_CXX_LANGUAGE_STANDARD = "c++0x";
CLANG_LINK_OBJC_RUNTIME = NO;
CODE_SIGN_ENTITLEMENTS = "InterAppAudioEffect.entitlements";
COMBINE_HIDPI_IMAGES = YES;
CONFIGURATION_BUILD_DIR = "$(PROJECT_DIR)/build/$(CONFIGURATION)";
DEAD_CODE_STRIPPING = YES;
GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
GCC_OPTIMIZATION_LEVEL = 3;
GCC_PREPROCESSOR_DEFINITIONS = (
"_NDEBUG=1",
"NDEBUG=1",
"JUCER_XCODE_IPHONE_5BC26AE3=1",
"JUCE_APP_VERSION=1.0.0",
"JUCE_APP_VERSION_HEX=0x10000",
"JucePlugin_Build_VST=0",
"JucePlugin_Build_VST3=0",
"JucePlugin_Build_AU=0",
"JucePlugin_Build_AUv3=0",
"JucePlugin_Build_RTAS=0",
"JucePlugin_Build_AAX=0",
"JucePlugin_Build_Standalone=1", );
GCC_SYMBOLS_PRIVATE_EXTERN = YES;
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
HEADER_SEARCH_PATHS = ("../../JuceLibraryCode", "../../../../../modules", "$(inherited)");
INFOPLIST_FILE = Info-Standalone_Plugin.plist;
OTHER_CPLUSPLUSFLAGS = "-Wall -Wshadow -Wno-missing-field-initializers -Wshadow -Wshorten-64-to-32 -Wstrict-aliasing -Wuninitialized -Wunused-parameter -Wconversion -Wsign-compare -Wint-conversion -Woverloaded-virtual -Wreorder -Wconstant-conversion -Wsign-conversion";
OTHER_LDFLAGS = "-lInterAppAudioEffect";
PRODUCT_BUNDLE_IDENTIFIER = com.yourcompany.InterAppAudioEffect; }; name = Release; };
E6FA0B75AC78727D8A3F1888 = {isa = XCBuildConfiguration; buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
CLANG_CXX_LANGUAGE_STANDARD = "c++0x";
CLANG_LINK_OBJC_RUNTIME = NO;
COMBINE_HIDPI_IMAGES = YES;
CONFIGURATION_BUILD_DIR = "$(PROJECT_DIR)/build/$(CONFIGURATION)";
COPY_PHASE_STRIP = NO;
GCC_DYNAMIC_NO_PIC = NO;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"_DEBUG=1",
"DEBUG=1",
"JUCER_XCODE_IPHONE_5BC26AE3=1",
"JUCE_APP_VERSION=1.0.0",
"JUCE_APP_VERSION_HEX=0x10000",
"JucePlugin_Build_VST=0",
"JucePlugin_Build_VST3=0",
"JucePlugin_Build_AU=0",
"JucePlugin_Build_AUv3=0",
"JucePlugin_Build_RTAS=0",
"JucePlugin_Build_AAX=0",
"JucePlugin_Build_Standalone=1",
"JUCE_SHARED_CODE=1", );
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
HEADER_SEARCH_PATHS = ("../../JuceLibraryCode", "../../../../../modules", "$(inherited)");
INSTALL_PATH = "@executable_path/Frameworks";
OTHER_CPLUSPLUSFLAGS = "-Wall -Wshadow -Wno-missing-field-initializers -Wshadow -Wshorten-64-to-32 -Wstrict-aliasing -Wuninitialized -Wunused-parameter -Wconversion -Wsign-compare -Wint-conversion -Woverloaded-virtual -Wreorder -Wconstant-conversion -Wsign-conversion";
PRODUCT_BUNDLE_IDENTIFIER = com.yourcompany.InterAppAudioEffect; }; name = Debug; };
665044AFDC3F0D4E11643857 = {isa = XCBuildConfiguration; buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
CLANG_CXX_LANGUAGE_STANDARD = "c++0x";
CLANG_LINK_OBJC_RUNTIME = NO;
COMBINE_HIDPI_IMAGES = YES;
CONFIGURATION_BUILD_DIR = "$(PROJECT_DIR)/build/$(CONFIGURATION)";
DEAD_CODE_STRIPPING = YES;
GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
GCC_OPTIMIZATION_LEVEL = 3;
GCC_PREPROCESSOR_DEFINITIONS = (
"_NDEBUG=1",
"NDEBUG=1",
"JUCER_XCODE_IPHONE_5BC26AE3=1",
"JUCE_APP_VERSION=1.0.0",
"JUCE_APP_VERSION_HEX=0x10000",
"JucePlugin_Build_VST=0",
"JucePlugin_Build_VST3=0",
"JucePlugin_Build_AU=0",
"JucePlugin_Build_AUv3=0",
"JucePlugin_Build_RTAS=0",
"JucePlugin_Build_AAX=0",
"JucePlugin_Build_Standalone=1",
"JUCE_SHARED_CODE=1", );
GCC_SYMBOLS_PRIVATE_EXTERN = YES;
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
HEADER_SEARCH_PATHS = ("../../JuceLibraryCode", "../../../../../modules", "$(inherited)");
INSTALL_PATH = "@executable_path/Frameworks";
OTHER_CPLUSPLUSFLAGS = "-Wall -Wshadow -Wno-missing-field-initializers -Wshadow -Wshorten-64-to-32 -Wstrict-aliasing -Wuninitialized -Wunused-parameter -Wconversion -Wsign-compare -Wint-conversion -Woverloaded-virtual -Wreorder -Wconstant-conversion -Wsign-conversion";
PRODUCT_BUNDLE_IDENTIFIER = com.yourcompany.InterAppAudioEffect; }; name = Release; };
4650CE5DEC4B4B8ED96435A4 = {isa = XCBuildConfiguration; buildSettings = {
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
ALWAYS_SEARCH_USER_PATHS = NO;
DEBUG_INFORMATION_FORMAT = "dwarf";
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = c11;
GCC_INLINES_ARE_PRIVATE_EXTERN = YES;
GCC_MODEL_TUNING = G5;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_CHECK_SWITCH_STATEMENTS = YES;
GCC_WARN_MISSING_PARENTHESES = YES;
GCC_WARN_NON_VIRTUAL_DESTRUCTOR = YES;
GCC_WARN_TYPECHECK_CALLS_TO_PRINTF = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 9.3;
ONLY_ACTIVE_ARCH = YES;
PRODUCT_NAME = "InterAppAudioEffect";
SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
WARNING_CFLAGS = -Wreorder;
ZERO_LINK = NO; }; name = Debug; };
C2BB86E774E1461CAF0D87DD = {isa = XCBuildConfiguration; buildSettings = {
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
ALWAYS_SEARCH_USER_PATHS = NO;
DEBUG_INFORMATION_FORMAT = "dwarf";
GCC_C_LANGUAGE_STANDARD = c11;
GCC_INLINES_ARE_PRIVATE_EXTERN = YES;
GCC_MODEL_TUNING = G5;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_CHECK_SWITCH_STATEMENTS = YES;
GCC_WARN_MISSING_PARENTHESES = YES;
GCC_WARN_NON_VIRTUAL_DESTRUCTOR = YES;
GCC_WARN_TYPECHECK_CALLS_TO_PRINTF = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 9.3;
PRODUCT_NAME = "InterAppAudioEffect";
SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
WARNING_CFLAGS = -Wreorder;
ZERO_LINK = NO; }; name = Release; };
2C494CD599EC256FDB6CCE00 = {isa = PBXTargetDependency; target = 51FB6E6A2D0998D38E999826; };
CECAF531D33909A1FB3ABE80 = {isa = PBXTargetDependency; target = A3401CC1AC6C5B89EFBAEF01; };
016ACE6B9EC6F47020502F4F = {isa = XCConfigurationList; buildConfigurations = (
4650CE5DEC4B4B8ED96435A4,
C2BB86E774E1461CAF0D87DD, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Debug; };
D10DBCC16019A5712E897068 = {isa = XCConfigurationList; buildConfigurations = (
22DBBF091193373BEA063A5B,
54D411166886E8F3BBC0E25F, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Debug; };
03BD5476C606A5BA65CD4FDF = {isa = PBXAggregateTarget; buildConfigurationList = D10DBCC16019A5712E897068; buildPhases = ( ); buildRules = ( ); dependencies = (
2C494CD599EC256FDB6CCE00,
CECAF531D33909A1FB3ABE80, ); name = "InterAppAudioEffect - All"; productName = InterAppAudioEffect; };
10A00DA553BF0C30212421D2 = {isa = XCConfigurationList; buildConfigurations = (
8DA1E39A676F877EB549B8CA,
07EA55A19B872E1F49C62539, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Debug; };
C8358163192CC594074B35EA = {isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = (
4EC4A8C3AF328E40626CBAE7, ); runOnlyForDeploymentPostprocessing = 0; };
AC1841BDF7829D1EA1146F56 = {isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = (
A49F3F55F083BAD332CA4324, ); runOnlyForDeploymentPostprocessing = 0; };
A0069210E3FD182F29030BDB = {isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = (
61D6F1506B76AFBA614F491E,
03A7A8C261C0A1B578F219EF,
E9FB1841DE3518ADBD86293C,
7B71DA92A48B9D67BA68C69E,
BC8485848043996AFA210EF9,
7FF11BF2317D79501E0632DB,
DD2143886468728A97F9586E,
EE6B5FC34FB47B41336EA293,
B2E5CB24DBACF25E2CBAC9A1,
6FAEC70FAE3DBC629160F86C,
DFF48C0819F2191B154569A9,
9BB46E700B9A4617B4CFDC24, ); runOnlyForDeploymentPostprocessing = 0; };
51FB6E6A2D0998D38E999826 = {isa = PBXNativeTarget; buildConfigurationList = 10A00DA553BF0C30212421D2; buildPhases = (
C8358163192CC594074B35EA,
AC1841BDF7829D1EA1146F56,
A0069210E3FD182F29030BDB, ); buildRules = ( ); dependencies = (
CECAF531D33909A1FB3ABE80, ); name = "InterAppAudioEffect - Standalone Plugin"; productName = InterAppAudioEffect; productReference = E9D6BA12BDD1947BDDAE08F7; productType = "com.apple.product-type.application"; };
AA6F190D4FECB06C7A7A0658 = {isa = XCConfigurationList; buildConfigurations = (
E6FA0B75AC78727D8A3F1888,
665044AFDC3F0D4E11643857, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Debug; };
177DC2A7A303F23EDDE5183A = {isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = (
9A7D9D7490AF3D82BA8D9686,
40833B424B5E9EC84C09EE40,
7ACC830E1DDF0F171C890B2B,
78BD211C42E345A8048DEDD5,
B2BE378326805DEBB71B3016,
BCA424EEB2F9F33372CA4909,
246490CF3D197E69B1F7FCC8,
873E620B819DC84C953EC518,
40E6F5A9B432DEB7689AF7D0,
78412E76B9D1D75907390309,
E3DD6181D2A4E2703637E1EF,
E8410AF631A96357D2807C3A,
DCEE24917F78097ACF14EAD0,
CA28F22C95EBC20CB37612FF, ); runOnlyForDeploymentPostprocessing = 0; };
A3401CC1AC6C5B89EFBAEF01 = {isa = PBXNativeTarget; buildConfigurationList = AA6F190D4FECB06C7A7A0658; buildPhases = (
177DC2A7A303F23EDDE5183A, ); buildRules = ( ); dependencies = ( ); name = "InterAppAudioEffect - Shared Code"; productName = InterAppAudioEffect; productReference = 873711620EC157BCCFFF80B1; productType = "com.apple.product-type.library.static"; };
DF3D0C1B88ADC0274AE6BD73 = {isa = PBXProject; buildConfigurationList = 016ACE6B9EC6F47020502F4F; attributes = { LastUpgradeCheck = 0820; TargetAttributes = { 03BD5476C606A5BA65CD4FDF = { SystemCapabilities = {com.apple.InAppPurchase = { enabled = 0; }; com.apple.InterAppAudio = { enabled = 0; }; com.apple.Sandbox = { enabled = 0; }; }; };51FB6E6A2D0998D38E999826 = { SystemCapabilities = {com.apple.InAppPurchase = { enabled = 0; }; com.apple.InterAppAudio = { enabled = 1; }; com.apple.Sandbox = { enabled = 0; }; }; };A3401CC1AC6C5B89EFBAEF01 = { SystemCapabilities = {com.apple.InAppPurchase = { enabled = 0; }; com.apple.InterAppAudio = { enabled = 0; }; com.apple.Sandbox = { enabled = 0; }; }; }; }; }; compatibilityVersion = "Xcode 3.2"; hasScannedForEncodings = 0; mainGroup = EC01685A042C62251C5AF093; projectDirPath = ""; projectRoot = ""; targets = (03BD5476C606A5BA65CD4FDF, 51FB6E6A2D0998D38E999826, A3401CC1AC6C5B89EFBAEF01); };
};
rootObject = DF3D0C1B88ADC0274AE6BD73;
}

BIN
examples/PlugInSamples/InterAppAudioEffect/Builds/iOS/InterAppAudioEffect/Images.xcassets/LaunchImage.launchimage/LaunchImage-ipad-landscape-1x.png View File

Before After
Width: 1024  |  Height: 768  |  Size: 4.8KB

BIN
examples/PlugInSamples/InterAppAudioEffect/Builds/iOS/InterAppAudioEffect/Images.xcassets/LaunchImage.launchimage/LaunchImage-ipad-landscape-2x.png View File

Before After
Width: 2048  |  Height: 1536  |  Size: 16KB

BIN
examples/PlugInSamples/InterAppAudioEffect/Builds/iOS/InterAppAudioEffect/Images.xcassets/LaunchImage.launchimage/LaunchImage-ipad-portrait-1x.png View File

Before After
Width: 768  |  Height: 1024  |  Size: 5.2KB

BIN
examples/PlugInSamples/InterAppAudioEffect/Builds/iOS/InterAppAudioEffect/Images.xcassets/LaunchImage.launchimage/LaunchImage-ipad-portrait-2x.png View File

Before After
Width: 1536  |  Height: 2048  |  Size: 17KB

BIN
examples/PlugInSamples/InterAppAudioEffect/Builds/iOS/InterAppAudioEffect/Images.xcassets/LaunchImage.launchimage/LaunchImage-iphone-2x.png View File

Before After
Width: 640  |  Height: 960  |  Size: 4.4KB

BIN
examples/PlugInSamples/InterAppAudioEffect/Builds/iOS/InterAppAudioEffect/Images.xcassets/LaunchImage.launchimage/LaunchImage-iphone-retina4.png View File

Before After
Width: 640  |  Height: 1136  |  Size: 5.2KB

+ 63
- 0
examples/PlugInSamples/InterAppAudioEffect/InterAppAudioEffect.jucer View File

@@ -0,0 +1,63 @@
<?xml version="1.0" encoding="UTF-8"?>
<JUCERPROJECT id="rgYEL2" name="InterAppAudioEffect" projectType="audioplug"
version="1.0.0" bundleIdentifier="com.yourcompany.InterAppAudioEffect"
includeBinaryInAppConfig="1" buildVST="0" buildVST3="0" buildAU="0"
buildAUv3="0" buildRTAS="0" buildAAX="0" enableIAA="1" pluginName="InterAppAudioEffect"
pluginDesc="InterAppAudioEffect" pluginManufacturer="ROLI Ltd."
pluginManufacturerCode="ROLI" pluginCode="IAAE" pluginChannelConfigs=""
pluginIsSynth="0" pluginWantsMidiIn="0" pluginProducesMidiOut="0"
pluginIsMidiEffectPlugin="0" pluginEditorRequiresKeys="0" pluginAUExportPrefix="InterAppAudioEffectAU"
pluginRTASCategory="" aaxIdentifier="com.yourcompany.InterAppAudioEffect"
pluginAAXCategory="AAX_ePlugInCategory_Dynamics" jucerVersion="4.3.1"
companyName="ROLI Ltd." buildStandalone="1">
<MAINGROUP id="BhTVmm" name="InterAppAudioEffect">
<GROUP id="{79B2188B-B073-DD2F-F997-AFE1A88B5908}" name="Source">
<FILE id="s4nZon" name="IAAEffectProcessor.h" compile="0" resource="0"
file="Source/IAAEffectProcessor.h"/>
<FILE id="yg8oqf" name="IAAEffectProcessor.cpp" compile="1" resource="0"
file="Source/IAAEffectProcessor.cpp"/>
<FILE id="CRAxnV" name="IAAEffectEditor.h" compile="0" resource="0"
file="Source/IAAEffectEditor.h"/>
<FILE id="xALLmD" name="SimpleMeter.h" compile="0" resource="0" file="Source/SimpleMeter.h"/>
</GROUP>
</MAINGROUP>
<EXPORTFORMATS>
<XCODE_IPHONE targetFolder="Builds/iOS" iosScreenOrientation="portraitlandscape"
microphonePermissionNeeded="1" iosBackgroundAudio="1" extraCompilerFlags="-Wall -Wshadow -Wno-missing-field-initializers -Wshadow -Wshorten-64-to-32 -Wstrict-aliasing -Wuninitialized -Wunused-parameter -Wconversion -Wsign-compare -Wint-conversion -Woverloaded-virtual -Wreorder -Wconstant-conversion -Wsign-conversion">
<CONFIGURATIONS>
<CONFIGURATION name="Debug" isDebug="1" optimisation="1" targetName="InterAppAudioEffect"/>
<CONFIGURATION name="Release" isDebug="0" optimisation="3" targetName="InterAppAudioEffect"/>
</CONFIGURATIONS>
<MODULEPATHS>
<MODULEPATH id="juce_core" path="../../../modules"/>
<MODULEPATH id="juce_events" path="../../../modules"/>
<MODULEPATH id="juce_graphics" path="../../../modules"/>
<MODULEPATH id="juce_gui_basics" path="../../../modules"/>
<MODULEPATH id="juce_audio_basics" path="../../../modules"/>
<MODULEPATH id="juce_audio_devices" path="../../../modules"/>
<MODULEPATH id="juce_audio_formats" path="../../../modules"/>
<MODULEPATH id="juce_audio_processors" path="../../../modules"/>
<MODULEPATH id="juce_audio_plugin_client" path="../../../modules"/>
<MODULEPATH id="juce_audio_utils" path="../../../modules"/>
<MODULEPATH id="juce_data_structures" path="../../../modules"/>
<MODULEPATH id="juce_gui_extra" path="../../../modules"/>
</MODULEPATHS>
</XCODE_IPHONE>
</EXPORTFORMATS>
<MODULES>
<MODULE id="juce_audio_basics" showAllCode="1" useLocalCopy="0"/>
<MODULE id="juce_audio_devices" showAllCode="1" useLocalCopy="0"/>
<MODULE id="juce_audio_formats" showAllCode="1" useLocalCopy="0"/>
<MODULE id="juce_audio_plugin_client" showAllCode="1" useLocalCopy="0"/>
<MODULE id="juce_audio_processors" showAllCode="1" useLocalCopy="0"/>
<MODULE id="juce_audio_utils" showAllCode="1" useLocalCopy="0"/>
<MODULE id="juce_core" showAllCode="1" useLocalCopy="0"/>
<MODULE id="juce_data_structures" showAllCode="1" useLocalCopy="0"/>
<MODULE id="juce_events" showAllCode="1" useLocalCopy="0"/>
<MODULE id="juce_graphics" showAllCode="1" useLocalCopy="0"/>
<MODULE id="juce_gui_basics" showAllCode="1" useLocalCopy="0"/>
<MODULE id="juce_gui_extra" showAllCode="1" useLocalCopy="0"/>
</MODULES>
<JUCEOPTIONS JUCE_QUICKTIME="disabled"/>
</JUCERPROJECT>

+ 363
- 0
examples/PlugInSamples/InterAppAudioEffect/JuceLibraryCode/AppConfig.h View File

@@ -0,0 +1,363 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
There's a section below where you can add your own custom code safely, and the
Projucer will preserve the contents of that block, but the best way to change
any of these definitions is by using the Projucer's project settings.
Any commented-out settings will assume their default values.
*/
#pragma once
//==============================================================================
// [BEGIN_USER_CODE_SECTION]
// (You can add your own code in this section, and the Projucer will not overwrite it)
// [END_USER_CODE_SECTION]
//==============================================================================
#define JUCE_MODULE_AVAILABLE_juce_audio_basics 1
#define JUCE_MODULE_AVAILABLE_juce_audio_devices 1
#define JUCE_MODULE_AVAILABLE_juce_audio_formats 1
#define JUCE_MODULE_AVAILABLE_juce_audio_plugin_client 1
#define JUCE_MODULE_AVAILABLE_juce_audio_processors 1
#define JUCE_MODULE_AVAILABLE_juce_audio_utils 1
#define JUCE_MODULE_AVAILABLE_juce_core 1
#define JUCE_MODULE_AVAILABLE_juce_data_structures 1
#define JUCE_MODULE_AVAILABLE_juce_events 1
#define JUCE_MODULE_AVAILABLE_juce_graphics 1
#define JUCE_MODULE_AVAILABLE_juce_gui_basics 1
#define JUCE_MODULE_AVAILABLE_juce_gui_extra 1
//==============================================================================
#ifndef JUCE_STANDALONE_APPLICATION
#if defined(JucePlugin_Name) && defined(JucePlugin_Build_Standalone)
#define JUCE_STANDALONE_APPLICATION JucePlugin_Build_Standalone
#else
#define JUCE_STANDALONE_APPLICATION 0
#endif
#endif
#define JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED 1
//==============================================================================
// juce_audio_devices flags:
#ifndef JUCE_ASIO
//#define JUCE_ASIO
#endif
#ifndef JUCE_WASAPI
//#define JUCE_WASAPI
#endif
#ifndef JUCE_WASAPI_EXCLUSIVE
//#define JUCE_WASAPI_EXCLUSIVE
#endif
#ifndef JUCE_DIRECTSOUND
//#define JUCE_DIRECTSOUND
#endif
#ifndef JUCE_ALSA
//#define JUCE_ALSA
#endif
#ifndef JUCE_JACK
//#define JUCE_JACK
#endif
#ifndef JUCE_USE_ANDROID_OPENSLES
//#define JUCE_USE_ANDROID_OPENSLES
#endif
#ifndef JUCE_USE_WINRT_MIDI
//#define JUCE_USE_WINRT_MIDI
#endif
//==============================================================================
// juce_audio_formats flags:
#ifndef JUCE_USE_FLAC
//#define JUCE_USE_FLAC
#endif
#ifndef JUCE_USE_OGGVORBIS
//#define JUCE_USE_OGGVORBIS
#endif
#ifndef JUCE_USE_MP3AUDIOFORMAT
//#define JUCE_USE_MP3AUDIOFORMAT
#endif
#ifndef JUCE_USE_LAME_AUDIO_FORMAT
//#define JUCE_USE_LAME_AUDIO_FORMAT
#endif
#ifndef JUCE_USE_WINDOWS_MEDIA_FORMAT
//#define JUCE_USE_WINDOWS_MEDIA_FORMAT
#endif
//==============================================================================
// juce_audio_plugin_client flags:
#ifndef JUCE_FORCE_USE_LEGACY_PARAM_IDS
//#define JUCE_FORCE_USE_LEGACY_PARAM_IDS
#endif
#ifndef JUCE_USE_STUDIO_ONE_COMPATIBLE_PARAMETERS
//#define JUCE_USE_STUDIO_ONE_COMPATIBLE_PARAMETERS
#endif
//==============================================================================
// juce_audio_processors flags:
#ifndef JUCE_PLUGINHOST_VST
//#define JUCE_PLUGINHOST_VST
#endif
#ifndef JUCE_PLUGINHOST_VST3
//#define JUCE_PLUGINHOST_VST3
#endif
#ifndef JUCE_PLUGINHOST_AU
//#define JUCE_PLUGINHOST_AU
#endif
//==============================================================================
// juce_audio_utils flags:
#ifndef JUCE_USE_CDREADER
//#define JUCE_USE_CDREADER
#endif
#ifndef JUCE_USE_CDBURNER
//#define JUCE_USE_CDBURNER
#endif
//==============================================================================
// juce_core flags:
#ifndef JUCE_FORCE_DEBUG
//#define JUCE_FORCE_DEBUG
#endif
#ifndef JUCE_LOG_ASSERTIONS
//#define JUCE_LOG_ASSERTIONS
#endif
#ifndef JUCE_CHECK_MEMORY_LEAKS
//#define JUCE_CHECK_MEMORY_LEAKS
#endif
#ifndef JUCE_DONT_AUTOLINK_TO_WIN32_LIBRARIES
//#define JUCE_DONT_AUTOLINK_TO_WIN32_LIBRARIES
#endif
#ifndef JUCE_INCLUDE_ZLIB_CODE
//#define JUCE_INCLUDE_ZLIB_CODE
#endif
#ifndef JUCE_USE_CURL
//#define JUCE_USE_CURL
#endif
#ifndef JUCE_CATCH_UNHANDLED_EXCEPTIONS
//#define JUCE_CATCH_UNHANDLED_EXCEPTIONS
#endif
#ifndef JUCE_ALLOW_STATIC_NULL_VARIABLES
//#define JUCE_ALLOW_STATIC_NULL_VARIABLES
#endif
//==============================================================================
// juce_events flags:
#ifndef JUCE_EXECUTE_APP_SUSPEND_ON_IOS_BACKGROUND_TASK
//#define JUCE_EXECUTE_APP_SUSPEND_ON_IOS_BACKGROUND_TASK
#endif
//==============================================================================
// juce_graphics flags:
#ifndef JUCE_USE_COREIMAGE_LOADER
//#define JUCE_USE_COREIMAGE_LOADER
#endif
#ifndef JUCE_USE_DIRECTWRITE
//#define JUCE_USE_DIRECTWRITE
#endif
//==============================================================================
// juce_gui_basics flags:
#ifndef JUCE_ENABLE_REPAINT_DEBUGGING
//#define JUCE_ENABLE_REPAINT_DEBUGGING
#endif
#ifndef JUCE_USE_XSHM
//#define JUCE_USE_XSHM
#endif
#ifndef JUCE_USE_XRENDER
//#define JUCE_USE_XRENDER
#endif
#ifndef JUCE_USE_XCURSOR
//#define JUCE_USE_XCURSOR
#endif
//==============================================================================
// juce_gui_extra flags:
#ifndef JUCE_WEB_BROWSER
//#define JUCE_WEB_BROWSER
#endif
#ifndef JUCE_ENABLE_LIVE_CONSTANT_EDITOR
//#define JUCE_ENABLE_LIVE_CONSTANT_EDITOR
#endif
//==============================================================================
// Audio plugin settings..
#ifndef JucePlugin_Build_VST
#define JucePlugin_Build_VST 0
#endif
#ifndef JucePlugin_Build_VST3
#define JucePlugin_Build_VST3 0
#endif
#ifndef JucePlugin_Build_AU
#define JucePlugin_Build_AU 0
#endif
#ifndef JucePlugin_Build_AUv3
#define JucePlugin_Build_AUv3 0
#endif
#ifndef JucePlugin_Build_RTAS
#define JucePlugin_Build_RTAS 0
#endif
#ifndef JucePlugin_Build_AAX
#define JucePlugin_Build_AAX 0
#endif
#ifndef JucePlugin_Build_STANDALONE
#define JucePlugin_Build_STANDALONE 1
#endif
#ifndef JucePlugin_Enable_IAA
#define JucePlugin_Enable_IAA 1
#endif
#ifndef JucePlugin_Name
#define JucePlugin_Name "InterAppAudioEffect"
#endif
#ifndef JucePlugin_Desc
#define JucePlugin_Desc "InterAppAudioEffect"
#endif
#ifndef JucePlugin_Manufacturer
#define JucePlugin_Manufacturer "ROLI Ltd."
#endif
#ifndef JucePlugin_ManufacturerWebsite
#define JucePlugin_ManufacturerWebsite ""
#endif
#ifndef JucePlugin_ManufacturerEmail
#define JucePlugin_ManufacturerEmail ""
#endif
#ifndef JucePlugin_ManufacturerCode
#define JucePlugin_ManufacturerCode 0x524f4c49 // 'ROLI'
#endif
#ifndef JucePlugin_PluginCode
#define JucePlugin_PluginCode 0x49414145 // 'IAAE'
#endif
#ifndef JucePlugin_IsSynth
#define JucePlugin_IsSynth 0
#endif
#ifndef JucePlugin_WantsMidiInput
#define JucePlugin_WantsMidiInput 0
#endif
#ifndef JucePlugin_ProducesMidiOutput
#define JucePlugin_ProducesMidiOutput 0
#endif
#ifndef JucePlugin_IsMidiEffect
#define JucePlugin_IsMidiEffect 0
#endif
#ifndef JucePlugin_EditorRequiresKeyboardFocus
#define JucePlugin_EditorRequiresKeyboardFocus 0
#endif
#ifndef JucePlugin_Version
#define JucePlugin_Version 1.0.0
#endif
#ifndef JucePlugin_VersionCode
#define JucePlugin_VersionCode 0x10000
#endif
#ifndef JucePlugin_VersionString
#define JucePlugin_VersionString "1.0.0"
#endif
#ifndef JucePlugin_VSTUniqueID
#define JucePlugin_VSTUniqueID JucePlugin_PluginCode
#endif
#ifndef JucePlugin_VSTCategory
#define JucePlugin_VSTCategory kPlugCategEffect
#endif
#ifndef JucePlugin_AUMainType
#define JucePlugin_AUMainType kAudioUnitType_Effect
#endif
#ifndef JucePlugin_AUSubType
#define JucePlugin_AUSubType JucePlugin_PluginCode
#endif
#ifndef JucePlugin_AUExportPrefix
#define JucePlugin_AUExportPrefix InterAppAudioEffectAU
#endif
#ifndef JucePlugin_AUExportPrefixQuoted
#define JucePlugin_AUExportPrefixQuoted "InterAppAudioEffectAU"
#endif
#ifndef JucePlugin_AUManufacturerCode
#define JucePlugin_AUManufacturerCode JucePlugin_ManufacturerCode
#endif
#ifndef JucePlugin_CFBundleIdentifier
#define JucePlugin_CFBundleIdentifier com.yourcompany.InterAppAudioEffect
#endif
#ifndef JucePlugin_RTASCategory
#define JucePlugin_RTASCategory ePlugInCategory_None
#endif
#ifndef JucePlugin_RTASManufacturerCode
#define JucePlugin_RTASManufacturerCode JucePlugin_ManufacturerCode
#endif
#ifndef JucePlugin_RTASProductId
#define JucePlugin_RTASProductId JucePlugin_PluginCode
#endif
#ifndef JucePlugin_RTASDisableBypass
#define JucePlugin_RTASDisableBypass 0
#endif
#ifndef JucePlugin_RTASDisableMultiMono
#define JucePlugin_RTASDisableMultiMono 0
#endif
#ifndef JucePlugin_AAXIdentifier
#define JucePlugin_AAXIdentifier com.yourcompany.InterAppAudioEffect
#endif
#ifndef JucePlugin_AAXManufacturerCode
#define JucePlugin_AAXManufacturerCode JucePlugin_ManufacturerCode
#endif
#ifndef JucePlugin_AAXProductId
#define JucePlugin_AAXProductId JucePlugin_PluginCode
#endif
#ifndef JucePlugin_AAXCategory
#define JucePlugin_AAXCategory AAX_ePlugInCategory_Dynamics
#endif
#ifndef JucePlugin_AAXDisableBypass
#define JucePlugin_AAXDisableBypass 0
#endif
#ifndef JucePlugin_AAXDisableMultiMono
#define JucePlugin_AAXDisableMultiMono 0
#endif
#ifndef JucePlugin_IAAType
#define JucePlugin_IAAType 0x61757278 // 'aurx'
#endif
#ifndef JucePlugin_IAASubType
#define JucePlugin_IAASubType JucePlugin_PluginCode
#endif
#ifndef JucePlugin_IAAName
#define JucePlugin_IAAName "ROLI Ltd.: InterAppAudioEffect"
#endif

+ 44
- 0
examples/PlugInSamples/InterAppAudioEffect/JuceLibraryCode/JuceHeader.h View File

@@ -0,0 +1,44 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
This is the header file that your files should include in order to get all the
JUCE library headers. You should avoid including the JUCE headers directly in
your own source files, because that wouldn't pick up the correct configuration
options for your app.
*/
#pragma once
#include "AppConfig.h"
#include <juce_audio_basics/juce_audio_basics.h>
#include <juce_audio_devices/juce_audio_devices.h>
#include <juce_audio_formats/juce_audio_formats.h>
#include <juce_audio_plugin_client/juce_audio_plugin_client.h>
#include <juce_audio_processors/juce_audio_processors.h>
#include <juce_audio_utils/juce_audio_utils.h>
#include <juce_core/juce_core.h>
#include <juce_data_structures/juce_data_structures.h>
#include <juce_events/juce_events.h>
#include <juce_graphics/juce_graphics.h>
#include <juce_gui_basics/juce_gui_basics.h>
#include <juce_gui_extra/juce_gui_extra.h>
#if ! DONT_SET_USING_JUCE_NAMESPACE
// If your code uses a lot of JUCE classes, then this will obviously save you
// a lot of typing, but can be disabled by setting DONT_SET_USING_JUCE_NAMESPACE.
using namespace juce;
#endif
#if ! JUCE_DONT_DECLARE_PROJECTINFO
namespace ProjectInfo
{
const char* const projectName = "InterAppAudioEffect";
const char* const versionString = "1.0.0";
const int versionNumber = 0x10000;
}
#endif

+ 12
- 0
examples/PlugInSamples/InterAppAudioEffect/JuceLibraryCode/ReadMe.txt View File

@@ -0,0 +1,12 @@
Important Note!!
================
The purpose of this folder is to contain files that are auto-generated by the Projucer,
and ALL files in this folder will be mercilessly DELETED and completely re-written whenever
the Projucer saves your project.
Therefore, it's a bad idea to make any manual changes to the files in here, or to
put any of your own files in here if you don't want to lose them. (Of course you may choose
to add the folder's contents to your version-control system so that you can re-merge your own
modifications after the Projucer has saved its changes).

+ 9
- 0
examples/PlugInSamples/InterAppAudioEffect/JuceLibraryCode/juce_audio_basics.cpp View File

@@ -0,0 +1,9 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include "AppConfig.h"
#include <juce_audio_basics/juce_audio_basics.cpp>

+ 9
- 0
examples/PlugInSamples/InterAppAudioEffect/JuceLibraryCode/juce_audio_basics.mm View File

@@ -0,0 +1,9 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include "AppConfig.h"
#include <juce_audio_basics/juce_audio_basics.mm>

+ 9
- 0
examples/PlugInSamples/InterAppAudioEffect/JuceLibraryCode/juce_audio_devices.cpp View File

@@ -0,0 +1,9 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include "AppConfig.h"
#include <juce_audio_devices/juce_audio_devices.cpp>

+ 9
- 0
examples/PlugInSamples/InterAppAudioEffect/JuceLibraryCode/juce_audio_devices.mm View File

@@ -0,0 +1,9 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include "AppConfig.h"
#include <juce_audio_devices/juce_audio_devices.mm>

+ 9
- 0
examples/PlugInSamples/InterAppAudioEffect/JuceLibraryCode/juce_audio_formats.cpp View File

@@ -0,0 +1,9 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include "AppConfig.h"
#include <juce_audio_formats/juce_audio_formats.cpp>

+ 9
- 0
examples/PlugInSamples/InterAppAudioEffect/JuceLibraryCode/juce_audio_formats.mm View File

@@ -0,0 +1,9 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include "AppConfig.h"
#include <juce_audio_formats/juce_audio_formats.mm>

+ 9
- 0
examples/PlugInSamples/InterAppAudioEffect/JuceLibraryCode/juce_audio_plugin_client_AAX.cpp View File

@@ -0,0 +1,9 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include "AppConfig.h"
#include <juce_audio_plugin_client/juce_audio_plugin_client_AAX.cpp>

+ 9
- 0
examples/PlugInSamples/InterAppAudioEffect/JuceLibraryCode/juce_audio_plugin_client_AAX.mm View File

@@ -0,0 +1,9 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include "AppConfig.h"
#include <juce_audio_plugin_client/juce_audio_plugin_client_AAX.mm>

+ 9
- 0
examples/PlugInSamples/InterAppAudioEffect/JuceLibraryCode/juce_audio_plugin_client_AU_1.mm View File

@@ -0,0 +1,9 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include "AppConfig.h"
#include <juce_audio_plugin_client/juce_audio_plugin_client_AU_1.mm>

+ 9
- 0
examples/PlugInSamples/InterAppAudioEffect/JuceLibraryCode/juce_audio_plugin_client_AU_2.mm View File

@@ -0,0 +1,9 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include "AppConfig.h"
#include <juce_audio_plugin_client/juce_audio_plugin_client_AU_2.mm>

+ 9
- 0
examples/PlugInSamples/InterAppAudioEffect/JuceLibraryCode/juce_audio_plugin_client_AUv3.mm View File

@@ -0,0 +1,9 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include "AppConfig.h"
#include <juce_audio_plugin_client/juce_audio_plugin_client_AUv3.mm>

+ 9
- 0
examples/PlugInSamples/InterAppAudioEffect/JuceLibraryCode/juce_audio_plugin_client_RTAS_1.cpp View File

@@ -0,0 +1,9 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include "AppConfig.h"
#include <juce_audio_plugin_client/juce_audio_plugin_client_RTAS_1.cpp>

+ 9
- 0
examples/PlugInSamples/InterAppAudioEffect/JuceLibraryCode/juce_audio_plugin_client_RTAS_2.cpp View File

@@ -0,0 +1,9 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include "AppConfig.h"
#include <juce_audio_plugin_client/juce_audio_plugin_client_RTAS_2.cpp>

+ 9
- 0
examples/PlugInSamples/InterAppAudioEffect/JuceLibraryCode/juce_audio_plugin_client_RTAS_3.cpp View File

@@ -0,0 +1,9 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include "AppConfig.h"
#include <juce_audio_plugin_client/juce_audio_plugin_client_RTAS_3.cpp>

+ 9
- 0
examples/PlugInSamples/InterAppAudioEffect/JuceLibraryCode/juce_audio_plugin_client_RTAS_4.cpp View File

@@ -0,0 +1,9 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include "AppConfig.h"
#include <juce_audio_plugin_client/juce_audio_plugin_client_RTAS_4.cpp>

+ 9
- 0
examples/PlugInSamples/InterAppAudioEffect/JuceLibraryCode/juce_audio_plugin_client_RTAS_utils.cpp View File

@@ -0,0 +1,9 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include "AppConfig.h"
#include <juce_audio_plugin_client/juce_audio_plugin_client_RTAS_utils.cpp>

+ 9
- 0
examples/PlugInSamples/InterAppAudioEffect/JuceLibraryCode/juce_audio_plugin_client_RTAS_utils.mm View File

@@ -0,0 +1,9 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include "AppConfig.h"
#include <juce_audio_plugin_client/juce_audio_plugin_client_RTAS_utils.mm>

+ 9
- 0
examples/PlugInSamples/InterAppAudioEffect/JuceLibraryCode/juce_audio_plugin_client_Standalone.cpp View File

@@ -0,0 +1,9 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include "AppConfig.h"
#include <juce_audio_plugin_client/juce_audio_plugin_client_Standalone.cpp>

+ 9
- 0
examples/PlugInSamples/InterAppAudioEffect/JuceLibraryCode/juce_audio_plugin_client_VST2.cpp View File

@@ -0,0 +1,9 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include "AppConfig.h"
#include <juce_audio_plugin_client/juce_audio_plugin_client_VST2.cpp>

+ 9
- 0
examples/PlugInSamples/InterAppAudioEffect/JuceLibraryCode/juce_audio_plugin_client_VST3.cpp View File

@@ -0,0 +1,9 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include "AppConfig.h"
#include <juce_audio_plugin_client/juce_audio_plugin_client_VST3.cpp>

+ 9
- 0
examples/PlugInSamples/InterAppAudioEffect/JuceLibraryCode/juce_audio_plugin_client_VST_utils.mm View File

@@ -0,0 +1,9 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include "AppConfig.h"
#include <juce_audio_plugin_client/juce_audio_plugin_client_VST_utils.mm>

+ 9
- 0
examples/PlugInSamples/InterAppAudioEffect/JuceLibraryCode/juce_audio_plugin_client_utils.cpp View File

@@ -0,0 +1,9 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include "AppConfig.h"
#include <juce_audio_plugin_client/juce_audio_plugin_client_utils.cpp>

+ 9
- 0
examples/PlugInSamples/InterAppAudioEffect/JuceLibraryCode/juce_audio_processors.cpp View File

@@ -0,0 +1,9 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include "AppConfig.h"
#include <juce_audio_processors/juce_audio_processors.cpp>

+ 9
- 0
examples/PlugInSamples/InterAppAudioEffect/JuceLibraryCode/juce_audio_processors.mm View File

@@ -0,0 +1,9 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include "AppConfig.h"
#include <juce_audio_processors/juce_audio_processors.mm>

+ 9
- 0
examples/PlugInSamples/InterAppAudioEffect/JuceLibraryCode/juce_audio_utils.cpp View File

@@ -0,0 +1,9 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include "AppConfig.h"
#include <juce_audio_utils/juce_audio_utils.cpp>

+ 9
- 0
examples/PlugInSamples/InterAppAudioEffect/JuceLibraryCode/juce_audio_utils.mm View File

@@ -0,0 +1,9 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include "AppConfig.h"
#include <juce_audio_utils/juce_audio_utils.mm>

+ 9
- 0
examples/PlugInSamples/InterAppAudioEffect/JuceLibraryCode/juce_core.cpp View File

@@ -0,0 +1,9 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include "AppConfig.h"
#include <juce_core/juce_core.cpp>

+ 9
- 0
examples/PlugInSamples/InterAppAudioEffect/JuceLibraryCode/juce_core.mm View File

@@ -0,0 +1,9 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include "AppConfig.h"
#include <juce_core/juce_core.mm>

+ 9
- 0
examples/PlugInSamples/InterAppAudioEffect/JuceLibraryCode/juce_data_structures.cpp View File

@@ -0,0 +1,9 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include "AppConfig.h"
#include <juce_data_structures/juce_data_structures.cpp>

+ 9
- 0
examples/PlugInSamples/InterAppAudioEffect/JuceLibraryCode/juce_data_structures.mm View File

@@ -0,0 +1,9 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include "AppConfig.h"
#include <juce_data_structures/juce_data_structures.mm>

+ 9
- 0
examples/PlugInSamples/InterAppAudioEffect/JuceLibraryCode/juce_events.cpp View File

@@ -0,0 +1,9 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include "AppConfig.h"
#include <juce_events/juce_events.cpp>

+ 9
- 0
examples/PlugInSamples/InterAppAudioEffect/JuceLibraryCode/juce_events.mm View File

@@ -0,0 +1,9 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include "AppConfig.h"
#include <juce_events/juce_events.mm>

+ 9
- 0
examples/PlugInSamples/InterAppAudioEffect/JuceLibraryCode/juce_graphics.cpp View File

@@ -0,0 +1,9 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include "AppConfig.h"
#include <juce_graphics/juce_graphics.cpp>

+ 9
- 0
examples/PlugInSamples/InterAppAudioEffect/JuceLibraryCode/juce_graphics.mm View File

@@ -0,0 +1,9 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include "AppConfig.h"
#include <juce_graphics/juce_graphics.mm>

+ 9
- 0
examples/PlugInSamples/InterAppAudioEffect/JuceLibraryCode/juce_gui_basics.cpp View File

@@ -0,0 +1,9 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include "AppConfig.h"
#include <juce_gui_basics/juce_gui_basics.cpp>

+ 9
- 0
examples/PlugInSamples/InterAppAudioEffect/JuceLibraryCode/juce_gui_basics.mm View File

@@ -0,0 +1,9 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include "AppConfig.h"
#include <juce_gui_basics/juce_gui_basics.mm>

+ 9
- 0
examples/PlugInSamples/InterAppAudioEffect/JuceLibraryCode/juce_gui_extra.cpp View File

@@ -0,0 +1,9 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include "AppConfig.h"
#include <juce_gui_extra/juce_gui_extra.cpp>

+ 9
- 0
examples/PlugInSamples/InterAppAudioEffect/JuceLibraryCode/juce_gui_extra.mm View File

@@ -0,0 +1,9 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include "AppConfig.h"
#include <juce_gui_extra/juce_gui_extra.mm>

+ 277
- 0
examples/PlugInSamples/InterAppAudioEffect/Source/IAAEffectEditor.h View File

@@ -0,0 +1,277 @@
#ifndef IAAEFFECTEDITOR_H_INCLUDED
#define IAAEFFECTEDITOR_H_INCLUDED
#include "../JuceLibraryCode/JuceHeader.h"
#include "IAAEffectProcessor.h"
#include "SimpleMeter.h"
class IAAEffectEditor : public AudioProcessorEditor,
private IAAEffectProcessor::MeterListener,
private ButtonListener,
private Timer
{
public:
IAAEffectEditor (IAAEffectProcessor& p,
AudioProcessorValueTreeState& vts)
: AudioProcessorEditor (p),
processor (p),
parameters (vts)
{
// Register for meter value updates.
processor.addMeterListener (*this);
gainSlider.setSliderStyle (Slider::SliderStyle::LinearVertical);
gainSlider.setTextBoxStyle (Slider::TextEntryBoxPosition::TextBoxAbove, false, 60, 20);
addAndMakeVisible (gainSlider);
for (auto& meter : meters)
addAndMakeVisible (meter);
// Configure all the graphics for the transport control.
transportText.setColour (Label::textColourId, Colours::white);
transportText.setFont (Font (Font::getDefaultMonospacedFontName(), 18.0f, Font::plain));
transportText.setJustificationType (Justification::topLeft);
addChildComponent (transportText);
Path rewindShape;
rewindShape.addRectangle (0.0, 0.0, 5.0, buttonSize);
rewindShape.addTriangle (0.0, buttonSize / 2, buttonSize, 0.0, buttonSize, buttonSize);
rewindButton.setShape (rewindShape, true, true, false);
rewindButton.addListener (this);
addChildComponent (rewindButton);
Path playShape;
playShape.addTriangle (0.0, 0.0, 0.0, buttonSize, buttonSize, buttonSize / 2);
playButton.setShape (playShape, true, true, false);
playButton.addListener (this);
addChildComponent (playButton);
Path recordShape;
recordShape.addEllipse (0.0, 0.0, buttonSize, buttonSize);
recordButton.setShape (recordShape, true, true, false);
recordButton.addListener (this);
addChildComponent (recordButton);
// Configure the switch to host button.
switchToHostButtonLabel.setColour (Label::textColourId, Colours::white);
switchToHostButtonLabel.setFont (Font (Font::getDefaultMonospacedFontName(), 18.0f, Font::plain));
switchToHostButtonLabel.setJustificationType (Justification::centredRight);
switchToHostButtonLabel.setText ("Switch to\nhost app:", dontSendNotification);
addChildComponent (switchToHostButtonLabel);
switchToHostButton.addListener (this);
addChildComponent (switchToHostButton);
Rectangle<int> screenSize = Desktop::getInstance().getDisplays().getMainDisplay().userArea;
setSize (screenSize.getWidth(), screenSize.getHeight());
resized();
startTimerHz (60);
}
//==============================================================================
void paint (Graphics& g) override
{
g.fillAll (Colours::darkgrey);
}
void resized() override
{
auto area = getBounds().reduced (10);
gainSlider.setBounds (area.removeFromLeft (60));
for (auto& meter : meters)
{
area.removeFromLeft (10);
meter.setBounds (area.removeFromLeft (20));
}
area.removeFromLeft (20);
transportText.setBounds (area.removeFromTop (120));
auto navigationArea = area.removeFromTop (buttonSize);
rewindButton.setTopLeftPosition (navigationArea.getPosition());
navigationArea.removeFromLeft (buttonSize + 10);
playButton.setTopLeftPosition (navigationArea.getPosition());
navigationArea.removeFromLeft (buttonSize + 10);
recordButton.setTopLeftPosition (navigationArea.getPosition());
area.removeFromTop (30);
auto appSwitchArea = area.removeFromTop (buttonSize);
switchToHostButtonLabel.setBounds (appSwitchArea.removeFromLeft (100));
appSwitchArea.removeFromLeft (5);
switchToHostButton.setBounds (appSwitchArea.removeFromLeft (buttonSize));
}
private:
//==============================================================================
// Called from the audio thread.
void handleNewMeterValue (int channel, float value) override
{
meters[(size_t) channel].update (value);
}
//==============================================================================
void timerCallback () override
{
auto timeInfoSuccess = processor.updateCurrentTimeInfoFromHost (lastPosInfo);
transportText.setVisible (timeInfoSuccess);
if (timeInfoSuccess)
updateTransportTextDisplay();
updateTransportButtonsDisplay();
updateSwitchToHostDisplay();
}
//==============================================================================
void buttonClicked (Button* b) override
{
auto playHead = processor.getPlayHead();
if (playHead != nullptr && playHead->canControlTransport())
{
if (b == &rewindButton)
{
playHead->transportRewind();
}
else if (b == &playButton)
{
playHead->transportPlay(! lastPosInfo.isPlaying);
}
else if (b == &recordButton)
{
playHead->transportRecord (! lastPosInfo.isRecording);
}
else if (b == &switchToHostButton)
{
PluginHostType hostType;
hostType.switchToHostApplication();
}
}
}
//==============================================================================
// quick-and-dirty function to format a timecode string
String timeToTimecodeString (double seconds)
{
auto millisecs = roundToInt (seconds * 1000.0);
auto absMillisecs = std::abs (millisecs);
return String::formatted ("%02d:%02d:%02d.%03d",
millisecs / 360000,
(absMillisecs / 60000) % 60,
(absMillisecs / 1000) % 60,
absMillisecs % 1000);
}
// A quick-and-dirty function to format a bars/beats string.
String quarterNotePositionToBarsBeatsString (double quarterNotes, int numerator, int denominator)
{
if (numerator == 0 || denominator == 0)
return "1|1|000";
auto quarterNotesPerBar = (numerator * 4 / denominator);
auto beats = (fmod (quarterNotes, quarterNotesPerBar) / quarterNotesPerBar) * numerator;
auto bar = ((int) quarterNotes) / quarterNotesPerBar + 1;
auto beat = ((int) beats) + 1;
auto ticks = ((int) (fmod (beats, 1.0) * 960.0 + 0.5));
return String::formatted ("%d|%d|%03d", bar, beat, ticks);
}
void updateTransportTextDisplay()
{
MemoryOutputStream displayText;
displayText << "[" << SystemStats::getJUCEVersion() << "]\n"
<< String (lastPosInfo.bpm, 2) << " bpm\n"
<< lastPosInfo.timeSigNumerator << '/' << lastPosInfo.timeSigDenominator << "\n"
<< timeToTimecodeString (lastPosInfo.timeInSeconds) << "\n"
<< quarterNotePositionToBarsBeatsString (lastPosInfo.ppqPosition,
lastPosInfo.timeSigNumerator,
lastPosInfo.timeSigDenominator) << "\n";
if (lastPosInfo.isRecording)
displayText << "(recording)";
else if (lastPosInfo.isPlaying)
displayText << "(playing)";
transportText.setText (displayText.toString(), dontSendNotification);
}
void updateTransportButtonsDisplay()
{
auto visible = processor.getPlayHead() != nullptr
&& processor.getPlayHead()->canControlTransport();
if (rewindButton.isVisible() != visible)
{
rewindButton.setVisible (visible);
playButton.setVisible (visible);
recordButton.setVisible (visible);
}
if (visible)
{
Colour playColour = lastPosInfo.isPlaying ? Colours::green : defaultButtonColour;
playButton.setColours (playColour, playColour, playColour);
playButton.repaint();
Colour recordColour = lastPosInfo.isRecording ? Colours::red : defaultButtonColour;
recordButton.setColours (recordColour, recordColour, recordColour);
recordButton.repaint();
}
}
void updateSwitchToHostDisplay()
{
PluginHostType hostType;
const bool visible = hostType.isInterAppAudioConnected();
if (switchToHostButtonLabel.isVisible() != visible)
{
switchToHostButtonLabel.setVisible (visible);
switchToHostButton.setVisible (visible);
if (visible) {
auto icon = hostType.getHostIcon (buttonSize);
switchToHostButton.setImages(false, true, true,
icon, 1.0, Colours::transparentBlack,
icon, 1.0, Colours::transparentBlack,
icon, 1.0, Colours::transparentBlack);
}
}
}
IAAEffectProcessor& processor;
AudioProcessorValueTreeState& parameters;
const int buttonSize = 30;
const Colour defaultButtonColour = Colours::lightgrey;
ShapeButton rewindButton {"Rewind", defaultButtonColour, defaultButtonColour, defaultButtonColour};
ShapeButton playButton {"Play", defaultButtonColour, defaultButtonColour, defaultButtonColour};
ShapeButton recordButton {"Record", defaultButtonColour, defaultButtonColour, defaultButtonColour};
Slider gainSlider;
AudioProcessorValueTreeState::SliderAttachment gainAttachment = {parameters, "gain", gainSlider};
std::array<SimpleMeter, 2> meters;
ImageButton switchToHostButton;
Label transportText, switchToHostButtonLabel;
Image hostImage;
AudioPlayHead::CurrentPositionInfo lastPosInfo;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (IAAEffectEditor)
};
#endif // IAAEFFECTEDITOR_H_INCLUDED

+ 169
- 0
examples/PlugInSamples/InterAppAudioEffect/Source/IAAEffectProcessor.cpp View File

@@ -0,0 +1,169 @@
#include "IAAEffectProcessor.h"
#include "IAAEffectEditor.h"
IAAEffectProcessor::IAAEffectProcessor()
: AudioProcessor (BusesProperties()
.withInput ("Input", AudioChannelSet::stereo(), true)
.withOutput ("Output", AudioChannelSet::stereo(), true)),
parameters (*this, nullptr)
{
parameters.createAndAddParameter ("gain",
"Gain",
String(),
NormalisableRange<float> (0.0f, 1.0f),
(float) (1.0 / 3.14),
nullptr,
nullptr);
parameters.state = ValueTree (Identifier ("InterAppAudioEffect"));
}
IAAEffectProcessor::~IAAEffectProcessor()
{
}
//==============================================================================
const String IAAEffectProcessor::getName() const
{
return JucePlugin_Name;
}
bool IAAEffectProcessor::acceptsMidi() const
{
return false;
}
bool IAAEffectProcessor::producesMidi() const
{
return false;
}
double IAAEffectProcessor::getTailLengthSeconds() const
{
return 0.0;
}
int IAAEffectProcessor::getNumPrograms()
{
return 1;
}
int IAAEffectProcessor::getCurrentProgram()
{
return 0;
}
void IAAEffectProcessor::setCurrentProgram (int)
{
}
const String IAAEffectProcessor::getProgramName (int)
{
return String();
}
void IAAEffectProcessor::changeProgramName (int, const String&)
{
}
//==============================================================================
void IAAEffectProcessor::prepareToPlay (double, int)
{
previousGain = *parameters.getRawParameterValue ("gain");
}
void IAAEffectProcessor::releaseResources()
{
}
bool IAAEffectProcessor::isBusesLayoutSupported (const BusesLayout& layouts) const
{
if (layouts.getMainInputChannelSet() != AudioChannelSet::stereo())
return false;
if (layouts.getMainOutputChannelSet() != layouts.getMainInputChannelSet())
return false;
return true;
}
void IAAEffectProcessor::processBlock (AudioSampleBuffer& buffer, MidiBuffer&)
{
const float gain = *parameters.getRawParameterValue ("gain");
const int totalNumInputChannels = getTotalNumInputChannels();
const int totalNumOutputChannels = getTotalNumOutputChannels();
const int numSamples = buffer.getNumSamples();
for (int i = totalNumInputChannels; i < totalNumOutputChannels; ++i)
buffer.clear (i, 0, buffer.getNumSamples());
// Apply the gain to the samples using a ramp to avoid discontinuities in
// the audio between processed buffers.
for (int channel = 0; channel < totalNumInputChannels; ++channel)
{
buffer.applyGainRamp (channel, 0, numSamples, previousGain, gain);
meterListeners.call (&IAAEffectProcessor::MeterListener::handleNewMeterValue,
channel,
buffer.getMagnitude (channel, 0, numSamples));
}
previousGain = gain;
// Now ask the host for the current time so we can store it to be displayed later.
updateCurrentTimeInfoFromHost (lastPosInfo);
}
//==============================================================================
bool IAAEffectProcessor::hasEditor() const
{
return true;
}
AudioProcessorEditor* IAAEffectProcessor::createEditor()
{
return new IAAEffectEditor (*this, parameters);
}
//==============================================================================
void IAAEffectProcessor::getStateInformation (MemoryBlock& destData)
{
auto xml = std::unique_ptr<XmlElement> (parameters.state.createXml());
copyXmlToBinary (*xml, destData);
}
void IAAEffectProcessor::setStateInformation (const void* data, int sizeInBytes)
{
auto xmlState = std::unique_ptr<XmlElement> (getXmlFromBinary (data, sizeInBytes));
if (xmlState.get() != nullptr)
if (xmlState->hasTagName (parameters.state.getType()))
parameters.state = ValueTree::fromXml (*xmlState);
}
bool IAAEffectProcessor::updateCurrentTimeInfoFromHost (AudioPlayHead::CurrentPositionInfo &posInfo)
{
if (AudioPlayHead* ph = getPlayHead())
{
AudioPlayHead::CurrentPositionInfo newTime;
if (ph->getCurrentPosition (newTime))
{
posInfo = newTime; // Successfully got the current time from the host.
return true;
}
}
// If the host fails to provide the current time, we'll just reset our copy to a default.
lastPosInfo.resetToDefault();
return false;
}
//==============================================================================
AudioProcessor* JUCE_CALLTYPE createPluginFilter()
{
return new IAAEffectProcessor();
}

+ 78
- 0
examples/PlugInSamples/InterAppAudioEffect/Source/IAAEffectProcessor.h View File

@@ -0,0 +1,78 @@
#ifndef PLUGINPROCESSOR_H_INCLUDED
#define PLUGINPROCESSOR_H_INCLUDED
#include "../JuceLibraryCode/JuceHeader.h"
#include <array>
// A simple Inter-App Audio plug-in with a gain control and some meters.
class IAAEffectProcessor : public AudioProcessor
{
public:
IAAEffectProcessor();
~IAAEffectProcessor();
//==============================================================================
void prepareToPlay (double sampleRate, int samplesPerBlock) override;
void releaseResources() override;
bool isBusesLayoutSupported (const BusesLayout& layouts) const override;
void processBlock (AudioSampleBuffer&, MidiBuffer&) override;
//==============================================================================
AudioProcessorEditor* createEditor() override;
bool hasEditor() const override;
//==============================================================================
const String getName() const override;
bool acceptsMidi() const override;
bool producesMidi() const override;
double getTailLengthSeconds() const override;
//==============================================================================
int getNumPrograms() override;
int getCurrentProgram() override;
void setCurrentProgram (int index) override;
const String getProgramName (int index) override;
void changeProgramName (int index, const String& newName) override;
//==============================================================================
void getStateInformation (MemoryBlock& destData) override;
void setStateInformation (const void* data, int sizeInBytes) override;
//==============================================================================
bool updateCurrentTimeInfoFromHost (AudioPlayHead::CurrentPositionInfo&);
// Allow an IAAAudioProcessorEditor to register as a listener to receive new
// meter values directly from the audio thread.
struct MeterListener
{
virtual ~MeterListener() {};
virtual void handleNewMeterValue (int, float) = 0;
};
void addMeterListener (MeterListener& listener) { meterListeners.add (&listener); };
void removeMeterListener (MeterListener& listener) { meterListeners.remove (&listener); };
private:
//==============================================================================
AudioProcessorValueTreeState parameters;
float previousGain = 0.0;
std::array <float, 2> meterValues = { { 0, 0 } };
// This keeps a copy of the last set of timing info that was acquired during an
// audio callback - the UI component will display this.
AudioPlayHead::CurrentPositionInfo lastPosInfo;
ListenerList<MeterListener> meterListeners;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (IAAEffectProcessor)
};
#endif // PLUGINPROCESSOR_H_INCLUDED

+ 97
- 0
examples/PlugInSamples/InterAppAudioEffect/Source/SimpleMeter.h View File

@@ -0,0 +1,97 @@
#ifndef SIMPLEMETER_H_INCLUDED
#define SIMPLEMETER_H_INCLUDED
#include "../JuceLibraryCode/JuceHeader.h"
// A very simple decaying meter.
class SimpleMeter : public Component,
private Timer
{
public:
SimpleMeter()
{
startTimerHz (30);
}
//==============================================================================
void paint (Graphics& g) override
{
g.fillAll(Colours::transparentBlack);
auto area = g.getClipBounds();
g.setColour (Colours::skyblue);
g.fillRoundedRectangle(area.toFloat(), 6.0);
auto unfilledHeight = area.getHeight() * (1.0 - level);
g.reduceClipRegion (area.getX(), area.getY(),
area.getWidth(), (int) unfilledHeight);
g.setColour (Colours::grey);
g.fillRoundedRectangle(area.toFloat(), 6.0);
}
void resized() override {}
//==============================================================================
// Called from the audio thread.
void update (float newLevel)
{
// We don't care if maxLevel gets set to zero (in timerCallback) between the
// load and the assignment.
maxLevel = jmax (maxLevel.load(), newLevel);
}
private:
//==============================================================================
void timerCallback() override
{
auto callbackLevel = maxLevel.exchange (0.0);
auto decayFactor = 0.95;
if (callbackLevel > level)
level = callbackLevel;
else if (level > 0.001)
level *= decayFactor;
else
level = 0;
repaint();
}
std::atomic<float> maxLevel {0.0};
float level = 0;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (SimpleMeter)
};
#if JUCE_PROJUCER_LIVE_BUILD
// Animate the meter in the Projucer live build.
struct MockSimpleMeter : public Component,
private Timer
{
MockSimpleMeter()
{
addAndMakeVisible (meter);
resized();
startTimerHz (100);
}
void paint (Graphics&) override {}
void resized() override
{
meter.setBounds (getBounds());
}
void timerCallback() override
{
meter.update (std::pow (randomNumberGenerator.nextFloat(), 2));
}
SimpleMeter meter;
Random randomNumberGenerator;
};
#endif
#endif // SIMPLEMETER_H_INCLUDED

+ 71
- 21
extras/Projucer/Source/Project Saving/jucer_ProjectExport_XCode.h View File

@@ -732,10 +732,14 @@ public:
attributes << "DevelopmentTeam = " << developmentTeamID << "; ";
const int inAppPurchasesEnabled = (owner.iOS && owner.isInAppPurchasesEnabled()) ? 1 : 0;
const int interAppAudioEnabled = (owner.iOS
&& type == Target::StandalonePlugIn
&& owner.getProject().shouldEnableIAA()) ? 1 : 0;
const int sandboxEnabled = (type == Target::AudioUnitv3PlugIn ? 1 : 0);
attributes << "SystemCapabilities = {";
attributes << "com.apple.InAppPurchase = { enabled = " << inAppPurchasesEnabled << "; }; ";
attributes << "com.apple.InterAppAudio = { enabled = " << interAppAudioEnabled << "; }; ";
attributes << "com.apple.Sandbox = { enabled = " << sandboxEnabled << "; }; ";
attributes << "}; };";
@@ -953,8 +957,10 @@ public:
s.add ("SEPARATE_STRIP = YES");
}
if (owner.project.getProjectType().isAudioPlugin() && type == Target::AudioUnitv3PlugIn && owner.isOSX())
s.add (String ("CODE_SIGN_ENTITLEMENTS = \"") + owner.getEntitlementsFileName() + String ("\""));
if (owner.project.getProjectType().isAudioPlugin())
if ((owner.isOSX() && type == Target::AudioUnitv3PlugIn)
|| (owner.isiOS() && type == Target::StandalonePlugIn))
s.add (String ("CODE_SIGN_ENTITLEMENTS = \"") + owner.getEntitlementsFileName() + String ("\""));
defines = mergePreprocessorDefs (defines, owner.getAllPreprocessorDefs (config, type));
@@ -1112,14 +1118,36 @@ public:
if (owner.settings ["UIStatusBarHidden"] && type != AudioUnitv3PlugIn)
addPlistDictionaryKeyBool (dict, "UIStatusBarHidden", true);
if (owner.iOS && type != AudioUnitv3PlugIn)
if (owner.iOS)
{
// Forcing full screen disables the split screen feature and prevents error ITMS-90475
addPlistDictionaryKeyBool (dict, "UIRequiresFullScreen", true);
addPlistDictionaryKeyBool (dict, "UIStatusBarHidden", true);
if (type != AudioUnitv3PlugIn)
{
// Forcing full screen disables the split screen feature and prevents error ITMS-90475
addPlistDictionaryKeyBool (dict, "UIRequiresFullScreen", true);
addPlistDictionaryKeyBool (dict, "UIStatusBarHidden", true);
addIosScreenOrientations (dict);
addIosBackgroundModes (dict);
addIosScreenOrientations (dict);
addIosBackgroundModes (dict);
}
if (type == StandalonePlugIn && owner.getProject().shouldEnableIAA())
{
XmlElement audioComponentsPlistKey ("key");
audioComponentsPlistKey.addTextElement ("AudioComponents");
dict->addChildElement (new XmlElement (audioComponentsPlistKey));
XmlElement audioComponentsPlistEntry ("array");
XmlElement* audioComponentsDict = audioComponentsPlistEntry.createNewChildElement ("dict");
addPlistDictionaryKey (audioComponentsDict, "name", owner.project.getIAAPluginName());
addPlistDictionaryKey (audioComponentsDict, "manufacturer", owner.project.getPluginManufacturerCode().toString().trim().substring (0, 4));
addPlistDictionaryKey (audioComponentsDict, "type", owner.project.getIAATypeCode());
addPlistDictionaryKey (audioComponentsDict, "subtype", owner.project.getPluginCode().toString().trim().substring (0, 4));
addPlistDictionaryKeyInt (audioComponentsDict, "version", owner.project.getVersionAsHexInteger());
dict->addChildElement (new XmlElement (audioComponentsPlistEntry));
}
}
for (auto& e : xcodeExtraPListEntries)
@@ -1500,8 +1528,9 @@ private:
void addFilesAndGroupsToProject (StringArray& topLevelGroupIDs) const
{
if (! isiOS() && project.getProjectType().isAudioPlugin())
topLevelGroupIDs.add (addEntitlementsFile());
StringArray entitlements = getEntitlements();
if (! entitlements.isEmpty())
topLevelGroupIDs.add (addEntitlementsFile (entitlements));
for (auto& group : getAllGroups())
if (group.getNumChildren() > 0)
@@ -2188,20 +2217,41 @@ private:
return project.getProjectFilenameRoot() + String (".entitlements");
}
String addEntitlementsFile() const
StringArray getEntitlements() const
{
const char* sandboxEntitlement =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
"<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">"
"<plist version=\"1.0\">"
"<dict>"
" <key>com.apple.security.app-sandbox</key>"
" <true/>"
"</dict>"
"</plist>";
StringArray keys;
if (project.getProjectType().isAudioPlugin())
{
if (isiOS())
{
if (project.shouldEnableIAA())
keys.add ("inter-app-audio");
}
else
{
keys.add ("com.apple.security.app-sandbox");
}
}
return keys;
}
String addEntitlementsFile (StringArray keys) const
{
String content =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
"<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n"
"<plist version=\"1.0\">\n"
"<dict>\n";
for (auto& key : keys)
{
content += "\t<key>" + key + "</key>\n"
"\t<true/>\n";
}
content += "</dict>\n"
"</plist>\n";
File entitlementsFile = getTargetFolder().getChildFile (getEntitlementsFileName());
overwriteFileIfDifferentOrThrow (entitlementsFile, sandboxEntitlement);
overwriteFileIfDifferentOrThrow (entitlementsFile, content);
RelativePath plistPath (entitlementsFile, getTargetFolder(), RelativePath::buildTargetFolder);
return addFile (plistPath, false, false, false, false, nullptr);


+ 4
- 0
extras/Projucer/Source/Project Saving/jucer_ProjectSaver.cpp View File

@@ -80,6 +80,7 @@ void ProjectSaver::writePluginCharacteristicsFile()
flags.set ("JucePlugin_Build_RTAS", valueToBool (project.getShouldBuildRTASAsValue()));
flags.set ("JucePlugin_Build_AAX", valueToBool (project.getShouldBuildAAXAsValue()));
flags.set ("JucePlugin_Build_STANDALONE", valueToBool (project.getShouldBuildStandalonePluginAsValue()));
flags.set ("JucePlugin_Enable_IAA", valueToBool (project.getShouldEnableIAAAsValue()));
flags.set ("JucePlugin_Name", valueToStringLiteral (project.getPluginName()));
flags.set ("JucePlugin_Desc", valueToStringLiteral (project.getPluginDesc()));
flags.set ("JucePlugin_Manufacturer", valueToStringLiteral (project.getPluginManufacturer()));
@@ -114,6 +115,9 @@ void ProjectSaver::writePluginCharacteristicsFile()
flags.set ("JucePlugin_AAXCategory", project.getPluginAAXCategory().toString());
flags.set ("JucePlugin_AAXDisableBypass", valueToBool (project.getPluginAAXBypassDisabled()));
flags.set ("JucePlugin_AAXDisableMultiMono", valueToBool (project.getPluginAAXMultiMonoDisabled()));
flags.set ("JucePlugin_IAAType", valueToCharLiteral (project.getIAATypeCode()));
flags.set ("JucePlugin_IAASubType", "JucePlugin_PluginCode");
flags.set ("JucePlugin_IAAName", project.getIAAPluginName().quoted());
{
String plugInChannelConfig = project.getPluginChannelConfigs().toString();


+ 32
- 0
extras/Projucer/Source/Project/jucer_Project.cpp View File

@@ -153,6 +153,7 @@ void Project::setMissingAudioPluginDefaultValues()
setValueIfVoid (getShouldBuildRTASAsValue(), false);
setValueIfVoid (getShouldBuildAAXAsValue(), false);
setValueIfVoid (getShouldBuildStandalonePluginAsValue(), false);
setValueIfVoid (getShouldEnableIAAAsValue(), false);
setValueIfVoid (getPluginName(), getTitle());
setValueIfVoid (getPluginDesc(), getTitle());
@@ -629,6 +630,9 @@ void Project::createAudioPluginPropertyEditors (PropertyListBuilder& props)
"Whether the project should produce an AAX plugin.");
props.add (new BooleanPropertyComponent (getShouldBuildStandalonePluginAsValue(), "Build Standalone Plug-In", "Enabled"),
"Whether the project should produce a standalone version of your plugin.");
props.add (new BooleanPropertyComponent (getShouldEnableIAAAsValue(), "Enable Inter-App Audio", "Enabled"),
"Whether a standalone plug-in should be an Inter-App Audio app. You should also enable the audio "
"background capability in the iOS exporter.");
props.add (new TextPropertyComponent (getPluginName(), "Plugin Name", 128, false),
"The name of your plugin (keep it short!)");
@@ -1258,6 +1262,34 @@ String Project::getAUMainTypeCode()
return s;
}
String Project::getIAATypeCode()
{
String s;
if (getPluginWantsMidiInput().getValue())
{
if (getPluginIsSynth().getValue())
s = "auri";
else
s = "aurm";
}
else
{
if (getPluginIsSynth().getValue())
s = "aurg";
else
s = "aurx";
}
return s;
}
String Project::getIAAPluginName()
{
String s = getPluginManufacturer().toString();
s << ": ";
s << getPluginName().toString();
return s;
}
String Project::getPluginVSTCategoryString()
{
String s (getPluginVSTCategory().toString().trim());


+ 4
- 0
extras/Projucer/Source/Project/jucer_Project.h View File

@@ -130,6 +130,7 @@ public:
Value getShouldBuildRTASAsValue() { return getProjectValue ("buildRTAS"); }
Value getShouldBuildAAXAsValue() { return getProjectValue ("buildAAX"); }
Value getShouldBuildStandalonePluginAsValue() { return getProjectValue ("buildStandalone");}
Value getShouldEnableIAAAsValue() { return getProjectValue ("enableIAA"); }
bool shouldBuildVST() const { return getProjectVar ("buildVST"); }
bool shouldBuildVST3() const { return getProjectVar ("buildVST3"); }
@@ -138,6 +139,7 @@ public:
bool shouldBuildRTAS() const { return getProjectVar ("buildRTAS"); }
bool shouldBuildAAX() const { return getProjectVar ("buildAAX"); }
bool shouldBuildStandalonePlugin() const { return getProjectVar ("buildStandalone"); }
bool shouldEnableIAA() const { return getProjectVar ("enableIAA"); }
//==============================================================================
Value getPluginName() { return getProjectValue ("pluginName"); }
@@ -163,6 +165,8 @@ public:
String getPluginRTASCategoryCode();
String getAUMainTypeString();
String getAUMainTypeCode();
String getIAATypeCode();
String getIAAPluginName();
String getPluginVSTCategoryString();
bool isAUPluginHost();


modules/juce_audio_processors/processors/juce_AudioPlayHead.h → modules/juce_audio_basics/audio_play_head/juce_AudioPlayHead.h View File

@@ -137,4 +137,16 @@ public:
multithreading issues if it's not called on the audio thread.
*/
virtual bool getCurrentPosition (CurrentPositionInfo& result) = 0;
/** Returns true if this object can control the transport. */
virtual bool canControlTransport() { return false; };
/** Starts or stops the audio. */
virtual void transportPlay (bool shouldStartPlaying) { ignoreUnused (shouldStartPlaying); };
/** Starts or stops recording the audio. */
virtual void transportRecord (bool shouldStartRecording) { ignoreUnused (shouldStartRecording); };
/** Rewinds the audio. */
virtual void transportRewind() {};
};

+ 1
- 0
modules/juce_audio_basics/juce_audio_basics.h View File

@@ -101,5 +101,6 @@ namespace juce
#include "sources/juce_ReverbAudioSource.h"
#include "sources/juce_ToneGeneratorAudioSource.h"
#include "synthesisers/juce_Synthesiser.h"
#include "audio_play_head/juce_AudioPlayHead.h"
}

+ 1
- 0
modules/juce_audio_devices/juce_audio_devices.cpp View File

@@ -182,6 +182,7 @@ namespace juce
//==============================================================================
#elif JUCE_IOS
#include "native/juce_ios_Audio.h"
#include "native/juce_ios_Audio.cpp"
#include "native/juce_mac_CoreMidi.cpp"


+ 7
- 3
modules/juce_audio_devices/juce_audio_devices.h View File

@@ -62,6 +62,10 @@
#include <juce_events/juce_events.h>
#include <juce_audio_basics/juce_audio_basics.h>
#if JUCE_MODULE_AVAILABLE_juce_gui_extra
#include <juce_gui_extra/juce_gui_extra.h>
#endif
//==============================================================================
/** Config: JUCE_ASIO
Enables ASIO audio devices (MS Windows only).
@@ -147,12 +151,12 @@
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 "audio_io/juce_AudioIODevice.h"
#include "audio_io/juce_AudioIODeviceType.h"
#include "audio_io/juce_SystemAudioVolume.h"
#include "sources/juce_AudioSourcePlayer.h"
#include "sources/juce_AudioTransportSource.h"
#include "audio_io/juce_AudioDeviceManager.h"


+ 407
- 132
modules/juce_audio_devices/native/juce_ios_Audio.cpp View File

@@ -210,35 +210,24 @@ static void logNSError (NSError* e)
#define JUCE_NSERROR_CHECK(X) { NSError* error = nil; X; logNSError (error); }
#if JUCE_MODULE_AVAILABLE_juce_graphics
#include <juce_graphics/native/juce_mac_CoreGraphicsHelpers.h>
#endif
//==============================================================================
class iOSAudioIODevice : public AudioIODevice
class iOSAudioIODevice::Pimpl : public AudioPlayHead
{
public:
iOSAudioIODevice (const String& deviceName)
: AudioIODevice (deviceName, iOSAudioDeviceName)
{
sessionHolder->activeDevices.add (this);
updateSampleRateAndAudioInput();
}
~iOSAudioIODevice()
{
sessionHolder->activeDevices.removeFirstMatchingValue (this);
close();
}
StringArray getOutputChannelNames() override
Pimpl (iOSAudioIODevice& ioDevice)
: owner (ioDevice)
{
return { "Left", "Right" };
sessionHolder->activeDevices.add (&owner);
}
StringArray getInputChannelNames() override
~Pimpl()
{
if (audioInputIsAvailable)
return { "Left", "Right" };
return {};
sessionHolder->activeDevices.removeFirstMatchingValue (&owner);
owner.close();
}
static void setAudioSessionActive (bool enabled)
@@ -255,7 +244,7 @@ public:
return session.sampleRate;
}
Array<double> getAvailableSampleRates() override
Array<double> getAvailableSampleRates()
{
Array<double> rates;
@@ -279,7 +268,7 @@ public:
rate = jmax (rate, supportedRate);
}
trySampleRate (getCurrentSampleRate());
trySampleRate (owner.getCurrentSampleRate());
AudioUnitAddPropertyListener (audioUnit,
kAudioUnitProperty_StreamFormat,
@@ -295,7 +284,7 @@ public:
return rates;
}
Array<int> getAvailableBufferSizes() override
Array<int> getAvailableBufferSizes()
{
Array<int> r;
@@ -305,43 +294,33 @@ public:
return r;
}
int getDefaultBufferSize() override
{
#if TARGET_IPHONE_SIMULATOR
return 512;
#else
return 256;
#endif
}
String open (const BigInteger& inputChannelsWanted,
const BigInteger& outputChannelsWanted,
double targetSampleRate, int bufferSize) override
double targetSampleRate, int bufferSize)
{
close();
lastError.clear();
preferredBufferSize = bufferSize <= 0 ? getDefaultBufferSize()
: bufferSize;
owner.lastError.clear();
owner.preferredBufferSize = bufferSize <= 0 ? owner.getDefaultBufferSize() : bufferSize;
// xxx set up channel mapping
activeOutputChans = outputChannelsWanted;
activeOutputChans.setRange (2, activeOutputChans.getHighestBit(), false);
numOutputChannels = activeOutputChans.countNumberOfSetBits();
monoOutputChannelNumber = activeOutputChans.findNextSetBit (0);
owner.activeOutputChans = outputChannelsWanted;
owner.activeOutputChans.setRange (2, owner.activeOutputChans.getHighestBit(), false);
owner.numOutputChannels = owner.activeOutputChans.countNumberOfSetBits();
monoOutputChannelNumber = owner.activeOutputChans.findNextSetBit (0);
activeInputChans = inputChannelsWanted;
activeInputChans.setRange (2, activeInputChans.getHighestBit(), false);
numInputChannels = activeInputChans.countNumberOfSetBits();
monoInputChannelNumber = activeInputChans.findNextSetBit (0);
owner.activeInputChans = inputChannelsWanted;
owner.activeInputChans.setRange (2, owner.activeInputChans.getHighestBit(), false);
owner.numInputChannels = owner.activeInputChans.countNumberOfSetBits();
monoInputChannelNumber = owner.activeInputChans.findNextSetBit (0);
setAudioSessionActive (true);
// Set the session category & options:
auto session = [AVAudioSession sharedInstance];
const bool useInputs = (numInputChannels > 0 && audioInputIsAvailable);
const bool useInputs = (owner.numInputChannels > 0 && owner.audioInputIsAvailable);
NSString* category = (useInputs ? AVAudioSessionCategoryPlayAndRecord : AVAudioSessionCategoryPlayback);
@@ -357,26 +336,26 @@ public:
// Set the sample rate
trySampleRate (targetSampleRate);
updateSampleRateAndAudioInput();
owner.updateSampleRateAndAudioInput();
updateCurrentBufferSize();
prepareFloatBuffers (actualBufferSize);
prepareFloatBuffers (owner.actualBufferSize);
isRunning = true;
owner.isRunning = true;
handleRouteChange ("Started AudioUnit");
lastError = (audioUnit != 0 ? "" : "Couldn't open the device");
owner.lastError = (audioUnit != 0 ? "" : "Couldn't open the device");
setAudioSessionActive (true);
return lastError;
return owner.lastError;
}
void close() override
void close()
{
if (isRunning)
if (owner.isRunning)
{
isRunning = false;
owner.isRunning = false;
if (audioUnit != 0)
{
@@ -389,40 +368,28 @@ public:
}
}
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 roundToInt (getCurrentSampleRate() * [AVAudioSession sharedInstance].outputLatency); }
int getInputLatencyInSamples() override { return roundToInt (getCurrentSampleRate() * [AVAudioSession sharedInstance].inputLatency); }
void start (AudioIODeviceCallback* newCallback) override
void start (AudioIODeviceCallback* newCallback)
{
if (isRunning && callback != newCallback)
if (owner.isRunning && owner.callback != newCallback)
{
if (newCallback != nullptr)
newCallback->audioDeviceAboutToStart (this);
newCallback->audioDeviceAboutToStart (&owner);
const ScopedLock sl (callbackLock);
callback = newCallback;
owner.callback = newCallback;
}
}
void stop() override
void stop()
{
if (isRunning)
if (owner.isRunning)
{
AudioIODeviceCallback* lastCallback;
{
const ScopedLock sl (callbackLock);
lastCallback = callback;
callback = nullptr;
lastCallback = owner.callback;
owner.callback = nullptr;
}
if (lastCallback != nullptr)
@@ -430,10 +397,7 @@ public:
}
}
bool isPlaying() override { return isRunning && callback != nullptr; }
String getLastError() override { return lastError; }
bool setAudioPreprocessingEnabled (bool enable) override
bool setAudioPreprocessingEnabled (bool enable)
{
auto session = [AVAudioSession sharedInstance];
@@ -446,12 +410,169 @@ public:
return session.mode == mode;
}
//==============================================================================
bool canControlTransport() override { return owner.interAppAudioConnected; }
void transportPlay (bool shouldSartPlaying) override
{
if (! canControlTransport())
return;
HostCallbackInfo callbackInfo;
fillHostCallbackInfo (callbackInfo);
Boolean hostIsPlaying = NO;
OSStatus err = callbackInfo.transportStateProc2 (callbackInfo.hostUserData,
&hostIsPlaying,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL);
jassert (err == noErr);
if (hostIsPlaying != shouldSartPlaying)
handleAudioTransportEvent (kAudioUnitRemoteControlEvent_TogglePlayPause);
}
void transportRecord (bool shouldStartRecording) override
{
if (! canControlTransport())
return;
HostCallbackInfo callbackInfo;
fillHostCallbackInfo (callbackInfo);
Boolean hostIsRecording = NO;
OSStatus err = callbackInfo.transportStateProc2 (callbackInfo.hostUserData,
NULL,
&hostIsRecording,
NULL,
NULL,
NULL,
NULL,
NULL);
jassert (err == noErr);
if (hostIsRecording != shouldStartRecording)
handleAudioTransportEvent (kAudioUnitRemoteControlEvent_ToggleRecord);
}
void transportRewind() override
{
if (canControlTransport())
handleAudioTransportEvent (kAudioUnitRemoteControlEvent_Rewind);
}
bool getCurrentPosition (CurrentPositionInfo& result) override
{
if (! canControlTransport())
return false;
zerostruct (result);
HostCallbackInfo callbackInfo;
fillHostCallbackInfo (callbackInfo);
if (callbackInfo.hostUserData == nullptr)
return false;
Boolean hostIsPlaying = NO;
Boolean hostIsRecording = NO;
Float64 hostCurrentSampleInTimeLine = 0;
Boolean hostIsCycling = NO;
Float64 hostCycleStartBeat = 0;
Float64 hostCycleEndBeat = 0;
OSStatus err = callbackInfo.transportStateProc2 (callbackInfo.hostUserData,
&hostIsPlaying,
&hostIsRecording,
NULL,
&hostCurrentSampleInTimeLine,
&hostIsCycling,
&hostCycleStartBeat,
&hostCycleEndBeat);
if (err == kAUGraphErr_CannotDoInCurrentContext)
return false;
jassert (err == noErr);
result.timeInSamples = (int64) hostCurrentSampleInTimeLine;
result.isPlaying = hostIsPlaying;
result.isRecording = hostIsRecording;
result.isLooping = hostIsCycling;
result.ppqLoopStart = hostCycleStartBeat;
result.ppqLoopEnd = hostCycleEndBeat;
result.timeInSeconds = result.timeInSamples / owner.sampleRate;
Float64 hostBeat = 0;
Float64 hostTempo = 0;
err = callbackInfo.beatAndTempoProc (callbackInfo.hostUserData,
&hostBeat,
&hostTempo);
jassert (err == noErr);
result.ppqPosition = hostBeat;
result.bpm = hostTempo;
Float32 hostTimeSigNumerator = 0;
UInt32 hostTimeSigDenominator = 0;
Float64 hostCurrentMeasureDownBeat = 0;
err = callbackInfo.musicalTimeLocationProc (callbackInfo.hostUserData,
NULL,
&hostTimeSigNumerator,
&hostTimeSigDenominator,
&hostCurrentMeasureDownBeat);
jassert (err == noErr);
result.ppqPositionOfLastBarStart = hostCurrentMeasureDownBeat;
result.timeSigNumerator = (int) hostTimeSigNumerator;
result.timeSigDenominator = (int) hostTimeSigDenominator;
result.frameRate = AudioPlayHead::fpsUnknown;
return true;
}
//==============================================================================
#if JUCE_MODULE_AVAILABLE_juce_gui_basics
Image getIcon (int size)
{
if (owner.interAppAudioConnected)
{
UIImage* hostUIImage = AudioOutputUnitGetHostIcon (audioUnit, size);
if (hostUIImage != nullptr)
return juce_createImageFromUIImage (hostUIImage);
}
return Image();
}
#endif
void switchApplication()
{
if (! owner.interAppAudioConnected)
return;
CFURLRef hostUrl;
UInt32 dataSize = sizeof (hostUrl);
OSStatus err = AudioUnitGetProperty(audioUnit,
kAudioUnitProperty_PeerURL,
kAudioUnitScope_Global,
0,
&hostUrl,
&dataSize);
if (err == noErr)
[[UIApplication sharedApplication] openURL:(NSURL*)hostUrl];
}
//==============================================================================
void invokeAudioDeviceErrorCallback (const String& reason)
{
const ScopedLock sl (callbackLock);
if (callback != nullptr)
callback->audioDeviceError (reason);
if (owner.callback != nullptr)
owner.callback->audioDeviceError (reason);
}
void handleStatusChange (bool enabled, const char* reason)
@@ -460,7 +581,7 @@ public:
JUCE_IOS_AUDIO_LOG ("handleStatusChange: enabled: " << (int) enabled << ", reason: " << reason);
isRunning = enabled;
owner.isRunning = enabled;
setAudioSessionActive (enabled);
if (enabled)
@@ -480,10 +601,10 @@ public:
fixAudioRouteIfSetToReceiver();
if (isRunning)
if (owner.isRunning)
{
invokeAudioDeviceErrorCallback (reason);
updateSampleRateAndAudioInput();
owner.updateSampleRateAndAudioInput();
updateCurrentBufferSize();
createAudioUnit();
@@ -496,29 +617,72 @@ public:
AudioOutputUnitStart (audioUnit);
}
if (callback != nullptr)
if (owner.callback != nullptr)
{
owner.callback->audioDeviceStopped();
owner.callback->audioDeviceAboutToStart (&owner);
}
}
}
void handleAudioUnitPropertyChange (AudioUnit,
AudioUnitPropertyID propertyID,
AudioUnitScope,
AudioUnitElement)
{
const ScopedLock myScopedLock (callbackLock);
switch (propertyID)
{
case kAudioUnitProperty_IsInterAppConnected: return handleInterAppAudioConnectionChange();
default: return;
}
}
void handleInterAppAudioConnectionChange()
{
UInt32 connected;
UInt32 dataSize = sizeof (connected);
OSStatus err = AudioUnitGetProperty (audioUnit, kAudioUnitProperty_IsInterAppConnected,
kAudioUnitScope_Global, 0, &connected, &dataSize);
jassert (err == noErr);
JUCE_IOS_AUDIO_LOG ("handleInterAppAudioConnectionChange: " << connected ? "connected"
: "disconnected");
if (connected != owner.interAppAudioConnected)
{
const ScopedLock myScopedLock (callbackLock);
owner.interAppAudioConnected = connected;
UIApplicationState appstate = [UIApplication sharedApplication].applicationState;
bool inForeground = (appstate != UIApplicationStateBackground);
if (owner.interAppAudioConnected || inForeground)
{
callback->audioDeviceStopped();
callback->audioDeviceAboutToStart (this);
setAudioSessionActive (true);
AudioOutputUnitStart (audioUnit);
if (owner.callback != nullptr)
owner.callback->audioDeviceAboutToStart (&owner);
}
else if (! inForeground)
{
AudioOutputUnitStop (audioUnit);
setAudioSessionActive (false);
}
}
}
private:
//==============================================================================
iOSAudioIODevice& owner;
SharedResourcePointer<AudioSessionHolder> sessionHolder;
CriticalSection callbackLock;
NSTimeInterval sampleRate = 0;
int numInputChannels = 2, numOutputChannels = 2;
int preferredBufferSize = 0, actualBufferSize = 0;
bool isRunning = false;
String lastError;
AudioStreamBasicDescription format;
AudioUnit audioUnit {};
bool audioInputIsAvailable = false;
AudioIODeviceCallback* callback = nullptr;
BigInteger activeOutputChans, activeInputChans;
AudioSampleBuffer floatData;
float* inputChannels[3];
@@ -527,17 +691,17 @@ private:
void prepareFloatBuffers (int bufferSize)
{
if (numInputChannels + numOutputChannels > 0)
if (owner.numInputChannels + owner.numOutputChannels > 0)
{
floatData.setSize (numInputChannels + numOutputChannels, bufferSize);
floatData.setSize (owner.numInputChannels + owner.numOutputChannels, bufferSize);
zeromem (inputChannels, sizeof (inputChannels));
zeromem (outputChannels, sizeof (outputChannels));
for (int i = 0; i < numInputChannels; ++i)
for (int i = 0; i < owner.numInputChannels; ++i)
inputChannels[i] = floatData.getWritePointer (i);
for (int i = 0; i < numOutputChannels; ++i)
outputChannels[i] = floatData.getWritePointer (i + numInputChannels);
for (int i = 0; i < owner.numOutputChannels; ++i)
outputChannels[i] = floatData.getWritePointer (i + owner.numInputChannels);
}
}
@@ -547,21 +711,21 @@ private:
{
OSStatus err = noErr;
if (audioInputIsAvailable && numInputChannels > 0)
if (owner.audioInputIsAvailable && owner.numInputChannels > 0)
err = AudioUnitRender (audioUnit, flags, time, 1, numFrames, data);
const ScopedTryLock stl (callbackLock);
if (stl.isLocked() && callback != nullptr)
if (stl.isLocked() && owner.callback != nullptr)
{
if ((int) numFrames > floatData.getNumSamples())
prepareFloatBuffers ((int) numFrames);
if (audioInputIsAvailable && numInputChannels > 0)
if (owner.audioInputIsAvailable && owner.numInputChannels > 0)
{
short* shortData = (short*) data->mBuffers[0].mData;
if (numInputChannels >= 2)
if (owner.numInputChannels >= 2)
{
for (UInt32 i = 0; i < numFrames; ++i)
{
@@ -583,17 +747,17 @@ private:
}
else
{
for (int i = numInputChannels; --i >= 0;)
for (int i = owner.numInputChannels; --i >= 0;)
zeromem (inputChannels[i], sizeof (float) * numFrames);
}
callback->audioDeviceIOCallback ((const float**) inputChannels, numInputChannels,
outputChannels, numOutputChannels, (int) numFrames);
owner.callback->audioDeviceIOCallback ((const float**) inputChannels, owner.numInputChannels,
outputChannels, owner.numOutputChannels, (int) numFrames);
short* const shortData = (short*) data->mBuffers[0].mData;
int n = 0;
if (numOutputChannels >= 2)
if (owner.numOutputChannels >= 2)
{
for (UInt32 i = 0; i < numFrames; ++i)
{
@@ -601,7 +765,7 @@ private:
shortData [n++] = (short) (outputChannels[1][i] * 32767.0f);
}
}
else if (numOutputChannels == 1)
else if (owner.numOutputChannels == 1)
{
for (UInt32 i = 0; i < numFrames; ++i)
{
@@ -623,25 +787,13 @@ private:
return err;
}
void updateSampleRateAndAudioInput()
{
auto session = [AVAudioSession sharedInstance];
sampleRate = session.sampleRate;
audioInputIsAvailable = session.isInputAvailable;
actualBufferSize = roundToInt (sampleRate * session.IOBufferDuration);
JUCE_IOS_AUDIO_LOG ("AVAudioSession: sampleRate: " << sampleRate
<< " Hz, audioInputAvailable: " << (int) audioInputIsAvailable
<< ", buffer size: " << actualBufferSize);
}
void updateCurrentBufferSize()
{
NSTimeInterval bufferDuration = sampleRate > 0 ? (NSTimeInterval) ((preferredBufferSize + 1) / sampleRate) : 0.0;
NSTimeInterval bufferDuration = owner.sampleRate > 0 ? (NSTimeInterval) ((owner.preferredBufferSize + 1) / owner.sampleRate) : 0.0;
JUCE_NSERROR_CHECK ([[AVAudioSession sharedInstance] setPreferredIOBufferDuration: bufferDuration
error: &error]);
updateSampleRateAndAudioInput();
owner.updateSampleRateAndAudioInput();
}
//==============================================================================
@@ -649,7 +801,7 @@ private:
UInt32 /*busNumber*/, UInt32 numFrames, AudioBufferList* data)
{
return static_cast<iOSAudioIODevice*> (client)->process (flags, time, numFrames, data);
return static_cast<Pimpl*> (client)->process (flags, time, numFrames, data);
}
//==============================================================================
@@ -687,7 +839,32 @@ private:
if (audioUnit == 0)
return false;
if (numInputChannels > 0)
#if JucePlugin_Enable_IAA
AudioComponentDescription appDesc;
appDesc.componentType = JucePlugin_IAAType;
appDesc.componentSubType = JucePlugin_IAASubType;
appDesc.componentManufacturer = JucePlugin_ManufacturerCode;
appDesc.componentFlags = 0;
appDesc.componentFlagsMask = 0;
OSStatus err = AudioOutputUnitPublish (&appDesc,
CFSTR(JucePlugin_IAAName),
JucePlugin_VersionCode,
audioUnit);
// This assert will be hit if the Inter-App Audio entitlement has not
// been enabled, or the description being published with
// AudioOutputUnitPublish is different from any in the AudioComponents
// array in this application's .plist file.
jassert (err == noErr);
err = AudioUnitAddPropertyListener(audioUnit,
kAudioUnitProperty_IsInterAppConnected,
audioUnitPropertyChangeDispatcher,
this);
jassert (err == noErr);
#endif
if (owner.numInputChannels > 0)
{
const UInt32 one = 1;
AudioUnitSetProperty (audioUnit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input, 1, &one, sizeof (one));
@@ -721,7 +898,7 @@ private:
if (AudioUnitGetProperty (audioUnit, kAudioUnitProperty_MaximumFramesPerSlice,
kAudioUnitScope_Global, 0, &framesPerSlice, &dataSize) == noErr
&& dataSize == sizeof (framesPerSlice) && static_cast<int> (framesPerSlice) != actualBufferSize)
&& dataSize == sizeof (framesPerSlice) && static_cast<int> (framesPerSlice) != owner.actualBufferSize)
{
prepareFloatBuffers (static_cast<int> (framesPerSlice));
}
@@ -731,6 +908,26 @@ private:
return true;
}
void fillHostCallbackInfo (HostCallbackInfo& callbackInfo)
{
zerostruct (callbackInfo);
UInt32 dataSize = sizeof (HostCallbackInfo);
OSStatus err = AudioUnitGetProperty (audioUnit,
kAudioUnitProperty_HostCallbacks,
kAudioUnitScope_Global,
0,
&callbackInfo,
&dataSize);
jassert (err == noErr);
}
void handleAudioTransportEvent (AudioUnitRemoteControlEvent event)
{
OSStatus err = AudioUnitSetProperty (audioUnit, kAudioOutputUnitProperty_RemoteControlToHost,
kAudioUnitScope_Global, 0, &event, sizeof (event));
jassert (err == noErr);
}
// 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()
@@ -768,14 +965,14 @@ private:
0,
&desc,
&dataSize);
if (desc.mSampleRate != getCurrentSampleRate())
if (desc.mSampleRate != owner.getCurrentSampleRate())
{
updateSampleRateAndAudioInput();
owner.updateSampleRateAndAudioInput();
const ScopedLock sl (callbackLock);
if (callback != nullptr)
if (owner.callback != nullptr)
{
callback->audioDeviceStopped();
callback->audioDeviceAboutToStart (this);
owner.callback->audioDeviceStopped();
owner.callback->audioDeviceAboutToStart (&owner);
}
}
}
@@ -787,13 +984,91 @@ private:
AudioUnitElement element)
{
if (scope == kAudioUnitScope_Output && element == 0)
static_cast<iOSAudioIODevice*> (device)->handleStreamFormatChange();
static_cast<Pimpl*> (device)->handleStreamFormatChange();
}
static void audioUnitPropertyChangeDispatcher (void* data, AudioUnit unit, AudioUnitPropertyID propertyID,
AudioUnitScope scope, AudioUnitElement element)
{
Pimpl* device = (Pimpl*)data;
device->handleAudioUnitPropertyChange (unit, propertyID, scope, element);
}
void handleMidiMessage (MidiMessage msg)
{
if (owner.messageCollector != nullptr)
owner.messageCollector->addMessageToQueue (msg);
}
static void midiEventCallback (void *client, UInt32 status, UInt32 data1, UInt32 data2, UInt32)
{
return static_cast<Pimpl*> (client)->handleMidiMessage (MidiMessage ((int) status,
(int) data1,
(int) data2,
Time::getMillisecondCounter() / 1000.0));
}
JUCE_DECLARE_NON_COPYABLE (iOSAudioIODevice)
JUCE_DECLARE_NON_COPYABLE (Pimpl)
};
//==============================================================================
iOSAudioIODevice::iOSAudioIODevice (const String& deviceName)
: AudioIODevice (deviceName, iOSAudioDeviceName),
#if TARGET_IPHONE_SIMULATOR
defaultBufferSize (512),
#else
defaultBufferSize (256),
#endif
sampleRate (0), numInputChannels (2), numOutputChannels (2),
preferredBufferSize (0), actualBufferSize (0), isRunning (false),
audioInputIsAvailable (false), interAppAudioConnected (false),
callback (nullptr), messageCollector (nullptr),
pimpl (new Pimpl (*this))
{
updateSampleRateAndAudioInput();
}
//==============================================================================
int iOSAudioIODevice::getOutputLatencyInSamples() { return roundToInt (sampleRate * [AVAudioSession sharedInstance].outputLatency); }
int iOSAudioIODevice::getInputLatencyInSamples() { return roundToInt (sampleRate * [AVAudioSession sharedInstance].inputLatency); }
//==============================================================================
AudioPlayHead* iOSAudioIODevice::getAudioPlayHead() const { return pimpl; }
void iOSAudioIODevice::close() { pimpl->close(); }
void iOSAudioIODevice::start (AudioIODeviceCallback* callbackToUse) { pimpl->start (callbackToUse); }
void iOSAudioIODevice::stop() { pimpl->stop(); }
Array<double> iOSAudioIODevice::getAvailableSampleRates() { return pimpl->getAvailableSampleRates(); }
Array<int> iOSAudioIODevice::getAvailableBufferSizes() { return pimpl->getAvailableBufferSizes(); }
bool iOSAudioIODevice::setAudioPreprocessingEnabled (bool enabled) { return pimpl->setAudioPreprocessingEnabled (enabled); }
void iOSAudioIODevice::switchApplication() { return pimpl->switchApplication(); }
//==============================================================================
void iOSAudioIODevice::handleStatusChange (bool enabled, const char* reason) { pimpl->handleStatusChange (enabled, reason); }
void iOSAudioIODevice::handleRouteChange (const char* reason) { pimpl->handleRouteChange (reason); }
#if JUCE_MODULE_AVAILABLE_juce_gui_basics
Image iOSAudioIODevice::getIcon (int size) { return pimpl->getIcon (size); }
#endif
//==============================================================================
String iOSAudioIODevice::open (const BigInteger& inChans, const BigInteger& outChans, double requestedSampleRate, int requestedBufferSize)
{
return pimpl->open (inChans, outChans, requestedSampleRate, requestedBufferSize);
}
void iOSAudioIODevice::updateSampleRateAndAudioInput()
{
auto session = [AVAudioSession sharedInstance];
sampleRate = session.sampleRate;
audioInputIsAvailable = session.isInputAvailable;
actualBufferSize = roundToInt (sampleRate * session.IOBufferDuration);
JUCE_IOS_AUDIO_LOG ("AVAudioSession: sampleRate: " << sampleRate
<< " Hz, audioInputAvailable: " << (int) audioInputIsAvailable
<< ", buffer size: " << actualBufferSize);
}
//==============================================================================
class iOSAudioIODeviceType : public AudioIODeviceType
{


+ 107
- 0
modules/juce_audio_devices/native/juce_ios_Audio.h View File

@@ -0,0 +1,107 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2016 - ROLI Ltd.
Permission is granted to use this software under the terms of the ISC license
http://www.isc.org/downloads/software-support-policy/isc-license/
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH REGARD
TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT,
OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
OF THIS SOFTWARE.
-----------------------------------------------------------------------------
To release a closed-source product which uses other parts of JUCE not
licensed under the ISC terms, commercial licenses are available: visit
www.juce.com for more information.
==============================================================================
*/
#pragma once
class iOSAudioIODeviceType;
class iOSAudioIODevice : public AudioIODevice
{
public:
//==============================================================================
String open (const BigInteger&, const BigInteger&, double, int) override;
void close() override;
void start (AudioIODeviceCallback*) override;
void stop() override;
Array<double> getAvailableSampleRates() override;
Array<int> getAvailableBufferSizes() override;
bool setAudioPreprocessingEnabled (bool) override;
//==============================================================================
bool isPlaying() override { return isRunning && callback != nullptr; }
bool isOpen() override { return isRunning; }
String getLastError() override { return lastError; };
//==============================================================================
StringArray getOutputChannelNames() override { return { "Left", "Right" }; }
StringArray getInputChannelNames() override { return audioInputIsAvailable ? getOutputChannelNames() : StringArray(); }
int getDefaultBufferSize() override { return defaultBufferSize; }
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;
int getInputLatencyInSamples() override;
//==============================================================================
void handleStatusChange (bool enabled, const char* reason);
void handleRouteChange (const char* reason);
//==============================================================================
virtual void setMidiMessageCollector (MidiMessageCollector* collector) { messageCollector = collector; }
virtual AudioPlayHead* getAudioPlayHead() const;
//==============================================================================
virtual bool isInterAppAudioConnected() const { return interAppAudioConnected; }
#if JUCE_MODULE_AVAILABLE_juce_gui_basics
virtual Image getIcon (int size);
#endif
virtual void switchApplication();
private:
//==============================================================================
void updateSampleRateAndAudioInput();
//==============================================================================
friend class iOSAudioIODeviceType;
iOSAudioIODevice (const String& deviceName);
//==============================================================================
const int defaultBufferSize;
double sampleRate;
int numInputChannels, numOutputChannels;
int preferredBufferSize, actualBufferSize;
bool isRunning;
String lastError;
bool audioInputIsAvailable, interAppAudioConnected;
BigInteger activeOutputChans, activeInputChans;
AudioIODeviceCallback* callback;
MidiMessageCollector* messageCollector;
class Pimpl;
friend class Pimpl;
ScopedPointer<Pimpl> pimpl;
JUCE_DECLARE_NON_COPYABLE (iOSAudioIODevice)
};

+ 9
- 0
modules/juce_audio_plugin_client/AU/juce_AUv3_Wrapper.mm View File

@@ -1431,5 +1431,14 @@ private:
- (void)viewDidLayoutSubviews { return cpp->viewDidLayoutSubviews(); }
@end
//==============================================================================
#if JUCE_IOS
bool JUCE_CALLTYPE juce_isInterAppAudioConnected() { return false; }
void JUCE_CALLTYPE juce_switchToHostApplication() {}
#if JUCE_MODULE_AVAILABLE_juce_gui_basics
Image JUCE_CALLTYPE juce_getIAAHostIcon (int) { return Image(); }
#endif
#endif
#pragma clang diagnostic pop
#endif

+ 31
- 0
modules/juce_audio_plugin_client/Standalone/juce_StandaloneFilterApp.cpp View File

@@ -43,6 +43,10 @@ extern AudioProcessor* JUCE_CALLTYPE createPluginFilter();
namespace juce
{
#if JucePlugin_Enable_IAA && JUCE_IOS
#include "../../juce_audio_devices/native/juce_ios_Audio.h"
#endif
#include "juce_StandaloneFilterWindow.h"
}
@@ -107,4 +111,31 @@ protected:
ScopedPointer<StandaloneFilterWindow> mainWindow;
};
#if JucePlugin_Build_STANDALONE && JUCE_IOS
bool JUCE_CALLTYPE juce_isInterAppAudioConnected()
{
if (auto holder = StandalonePluginHolder::getInstance())
return holder->isInterAppAudioConnected();
return false;
}
void JUCE_CALLTYPE juce_switchToHostApplication()
{
if (auto holder = StandalonePluginHolder::getInstance())
holder->switchToHostApplication();
}
#if JUCE_MODULE_AVAILABLE_juce_gui_basics
Image JUCE_CALLTYPE juce_getIAAHostIcon (int size)
{
if (auto holder = StandalonePluginHolder::getInstance())
return holder->getIAAHostIcon (size);
return Image();
}
#endif
#endif
#endif

+ 62
- 1
modules/juce_audio_plugin_client/Standalone/juce_StandaloneFilterWindow.h View File

@@ -182,6 +182,14 @@ public:
void startPlaying()
{
player.setProcessor (processor);
#if JucePlugin_Enable_IAA && JUCE_IOS
if (auto device = dynamic_cast<iOSAudioIODevice*> (deviceManager.getCurrentAudioDevice()))
{
processor->setPlayHead (device->getAudioPlayHead());
device->setMidiMessageCollector (&player.getMidiMessageCollector());
}
#endif
}
void stopPlaying()
@@ -260,6 +268,41 @@ public:
}
}
//==============================================================================
void switchToHostApplication()
{
#if JUCE_IOS
if (auto device = dynamic_cast<iOSAudioIODevice*> (deviceManager.getCurrentAudioDevice()))
device->switchApplication();
#endif
}
bool isInterAppAudioConnected()
{
#if JUCE_IOS
if (auto device = dynamic_cast<iOSAudioIODevice*> (deviceManager.getCurrentAudioDevice()))
return device->isInterAppAudioConnected();
#endif
return false;
}
#if JUCE_MODULE_AVAILABLE_juce_gui_basics
Image getIAAHostIcon (int size)
{
#if JUCE_IOS && JucePlugin_Enable_IAA
if (auto device = dynamic_cast<iOSAudioIODevice*> (deviceManager.getCurrentAudioDevice()))
return device->getIcon (size);
#else
ignoreUnused (size);
#endif
return Image();
}
#endif
static StandalonePluginHolder* getInstance();
//==============================================================================
OptionalScopedPointer<PropertySet> settings;
ScopedPointer<AudioProcessor> processor;
@@ -328,7 +371,6 @@ private:
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (StandalonePluginHolder)
};
//==============================================================================
/**
A class that can be used to run a simple standalone application containing your filter.
@@ -481,6 +523,8 @@ public:
optionsButton.setBounds (8, 6, 60, getTitleBarHeight() - 8);
}
virtual StandalonePluginHolder* getPluginHolder() { return pluginHolder; }
ScopedPointer<StandalonePluginHolder> pluginHolder;
private:
@@ -489,3 +533,20 @@ private:
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (StandaloneFilterWindow)
};
StandalonePluginHolder* StandalonePluginHolder::getInstance()
{
#if JucePlugin_Enable_IAA || JucePlugin_Build_STANDALONE
if (PluginHostType::getPluginLoadedAs() == AudioProcessor::wrapperType_Standalone)
{
Desktop& desktop (Desktop::getInstance());
const int numTopLevelWindows = desktop.getNumComponents();
for (int i = 0; i < numTopLevelWindows; ++i)
if (auto window = dynamic_cast<StandaloneFilterWindow*> (desktop.getComponent (i)))
return window->getPluginHolder();
}
#endif
return nullptr;
}

+ 8
- 0
modules/juce_audio_plugin_client/utility/juce_PluginHostType.h View File

@@ -169,6 +169,14 @@ public:
return "Unknown";
}
//==============================================================================
bool isInterAppAudioConnected() const;
void switchToHostApplication() const;
#if JUCE_MODULE_AVAILABLE_juce_gui_basics
Image getHostIcon (int size) const;
#endif
//==============================================================================
static String getHostPath()
{


+ 52
- 0
modules/juce_audio_plugin_client/utility/juce_PluginUtilities.cpp View File

@@ -149,6 +149,15 @@ bool JUCE_API handleManufacturerSpecificVST2Opcode (int32 index, pointer_sized_i
*/
extern AudioProcessor* JUCE_CALLTYPE createPluginFilter();
#if JucePlugin_Enable_IAA && JucePlugin_Build_STANDALONE && JUCE_IOS && (! JUCE_USE_CUSTOM_AU3_STANDALONE_APP)
extern bool JUCE_CALLTYPE juce_isInterAppAudioConnected();
extern void JUCE_CALLTYPE juce_switchToHostApplication();
#if JUCE_MODULE_AVAILABLE_juce_gui_basics
extern Image JUCE_CALLTYPE juce_getIAAHostIcon (int);
#endif
#endif
AudioProcessor* JUCE_API JUCE_CALLTYPE createPluginFilterOfType (AudioProcessor::WrapperType type)
{
AudioProcessor::setTypeOfNextNewPlugin (type);
@@ -160,3 +169,46 @@ AudioProcessor* JUCE_API JUCE_CALLTYPE createPluginFilterOfType (AudioProcessor:
return pluginInstance;
}
bool PluginHostType::isInterAppAudioConnected() const
{
#if JucePlugin_Enable_IAA && JucePlugin_Build_STANDALONE && JUCE_IOS && (! JUCE_USE_CUSTOM_AU3_STANDALONE_APP)
if (getPluginLoadedAs() == AudioProcessor::wrapperType_Standalone)
return juce_isInterAppAudioConnected();
#endif
return false;
}
void PluginHostType::switchToHostApplication() const
{
#if JucePlugin_Enable_IAA && JucePlugin_Build_STANDALONE && JUCE_IOS && (! JUCE_USE_CUSTOM_AU3_STANDALONE_APP)
if (getPluginLoadedAs() == AudioProcessor::wrapperType_Standalone)
juce_switchToHostApplication();
#endif
}
#if JUCE_MODULE_AVAILABLE_juce_gui_basics
namespace juce {
extern Image JUCE_API getIconFromApplication (const String&, const int);
Image PluginHostType::getHostIcon (int size) const
{
ignoreUnused (size);
#if JucePlugin_Enable_IAA && JucePlugin_Build_STANDALONE && JUCE_IOS && (! JUCE_USE_CUSTOM_AU3_STANDALONE_APP)
if (isInterAppAudioConnected())
return juce_getIAAHostIcon (size);
#endif
#if JUCE_MAC
String bundlePath (getHostPath().upToLastOccurrenceOf (".app", true, true));
return getIconFromApplication (bundlePath, size);
#endif
return Image();
}
}
#endif

+ 0
- 1
modules/juce_audio_processors/juce_audio_processors.h View File

@@ -102,7 +102,6 @@ namespace juce
{
class AudioProcessor;
#include "processors/juce_AudioPlayHead.h"
#include "processors/juce_AudioProcessorEditor.h"
#include "processors/juce_AudioProcessorListener.h"
#include "processors/juce_AudioProcessorParameter.h"


+ 13
- 3
modules/juce_graphics/image_formats/juce_JPEGLoader.cpp View File

@@ -223,13 +223,23 @@ bool JPEGImageFormat::usesFileExtension (const File& f) { return f.hasFileExte
bool JPEGImageFormat::canUnderstand (InputStream& in)
{
const int bytesNeeded = 10;
const int bytesNeeded = 24;
uint8 header [bytesNeeded];
return in.read (header, bytesNeeded) == bytesNeeded
if (in.read (header, bytesNeeded) == bytesNeeded
&& header[0] == 0xff
&& header[1] == 0xd8
&& header[2] == 0xff;
&& header[2] == 0xff)
return true;
#if JUCE_USING_COREIMAGE_LOADER
return header[20] == 'j'
&& header[21] == 'p'
&& header[22] == '2'
&& header[23] == ' ';
#endif
return false;
}
#if JUCE_USING_COREIMAGE_LOADER


+ 4
- 0
modules/juce_graphics/juce_graphics.cpp View File

@@ -144,21 +144,25 @@ namespace juce
#if JUCE_MAC || JUCE_IOS
#include "native/juce_mac_Fonts.mm"
#include "native/juce_mac_CoreGraphicsContext.mm"
#include "native/juce_mac_IconHelpers.cpp"
#elif JUCE_WINDOWS
#include "native/juce_win32_DirectWriteTypeface.cpp"
#include "native/juce_win32_DirectWriteTypeLayout.cpp"
#include "native/juce_win32_Fonts.cpp"
#include "native/juce_win32_IconHelpers.cpp"
#if JUCE_DIRECT2D
#include "native/juce_win32_Direct2DGraphicsContext.cpp"
#endif
#elif JUCE_LINUX
#include "native/juce_linux_Fonts.cpp"
#include "native/juce_linux_IconHelpers.cpp"
#elif JUCE_ANDROID
#include "native/juce_android_GraphicsContext.cpp"
#include "native/juce_android_Fonts.cpp"
#include "native/juce_android_IconHelpers.cpp"
#endif
}


+ 1
- 1
modules/juce_graphics/juce_graphics.h View File

@@ -41,7 +41,7 @@
dependencies: juce_events
OSXFrameworks: Cocoa QuartzCore
iOSFrameworks: CoreGraphics CoreText QuartzCore
iOSFrameworks: CoreGraphics CoreImage CoreText QuartzCore
linuxPackages: x11 xinerama xext freetype2
END_JUCE_MODULE_DECLARATION


+ 28
- 0
modules/juce_graphics/native/juce_android_IconHelpers.cpp View File

@@ -0,0 +1,28 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2017 - ROLI Ltd.
Permission is granted to use this software under the terms of either:
a) the GPL v2 (or any later version)
b) the Affero GPL v3
Details of these licenses can be found at: www.gnu.org/licenses
JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
------------------------------------------------------------------------------
To release a closed-source product which uses JUCE, commercial licenses are
available: visit www.juce.com for more information.
==============================================================================
*/
Image JUCE_API getIconFromApplication (const String&, const int)
{
return Image();
}

+ 28
- 0
modules/juce_graphics/native/juce_linux_IconHelpers.cpp View File

@@ -0,0 +1,28 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2017 - ROLI Ltd.
Permission is granted to use this software under the terms of either:
a) the GPL v2 (or any later version)
b) the Affero GPL v3
Details of these licenses can be found at: www.gnu.org/licenses
JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
------------------------------------------------------------------------------
To release a closed-source product which uses JUCE, commercial licenses are
available: visit www.juce.com for more information.
==============================================================================
*/
Image JUCE_API getIconFromApplication (const String&, const int)
{
return Image();
}

+ 12
- 1
modules/juce_graphics/native/juce_mac_CoreGraphicsContext.mm View File

@@ -876,7 +876,6 @@ Image juce_loadWithCoreImage (InputStream& input)
}
#endif
#if JUCE_MAC
Image juce_createImageFromCIImage (CIImage*, int, int);
Image juce_createImageFromCIImage (CIImage* im, int w, int h)
{
@@ -904,4 +903,16 @@ CGContextRef juce_getImageContext (const Image& image)
return 0;
}
#if JUCE_IOS
Image juce_createImageFromUIImage (UIImage* img)
{
CGImageRef image = [img CGImage];
Image retval (Image::ARGB, (int) CGImageGetWidth (image), (int) CGImageGetHeight (image), true);
CGContextRef ctx = juce_getImageContext (retval);
CGContextDrawImage (ctx, CGRectMake (0.0f, 0.0f, CGImageGetWidth (image), CGImageGetHeight (image)), image);
return retval;
}
#endif

+ 4
- 0
modules/juce_graphics/native/juce_mac_CoreGraphicsHelpers.h View File

@@ -55,3 +55,7 @@ namespace
extern CGImageRef juce_createCoreGraphicsImage (const Image&, CGColorSpaceRef, bool mustOutliveSource);
extern CGContextRef juce_getImageContext (const Image&);
#if JUCE_IOS
extern Image juce_createImageFromUIImage (UIImage*);
#endif

+ 135
- 0
modules/juce_graphics/native/juce_mac_IconHelpers.cpp View File

@@ -0,0 +1,135 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2017 - ROLI Ltd.
Permission is granted to use this software under the terms of either:
a) the GPL v2 (or any later version)
b) the Affero GPL v3
Details of these licenses can be found at: www.gnu.org/licenses
JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
------------------------------------------------------------------------------
To release a closed-source product which uses JUCE, commercial licenses are
available: visit www.juce.com for more information.
==============================================================================
*/
Image getIconFromIcnsFile (const File& icnsFile, const int size)
{
FileInputStream stream (icnsFile);
if (! stream.openedOk())
return {};
const int numHeaderSectionBytes = 4;
char headerSection [numHeaderSectionBytes];
if (stream.read (headerSection, numHeaderSectionBytes) != numHeaderSectionBytes
|| headerSection[0] != 'i'
|| headerSection[1] != 'c'
|| headerSection[2] != 'n'
|| headerSection[3] != 's')
return {};
if (stream.read (headerSection, numHeaderSectionBytes) != numHeaderSectionBytes)
return {};
const auto dataSize = juce::ByteOrder::bigEndianInt (headerSection);
if (dataSize <= 0)
return {};
OwnedArray<juce::ImageFileFormat> internalFormats;
internalFormats.add (new PNGImageFormat());
internalFormats.add (new JPEGImageFormat());
Array<Image> images;
auto maxWidth = 0;
auto maxWidthIndex = -1;
while (stream.getPosition() < dataSize)
{
const auto sectionStart = stream.getPosition();
if (! stream.setPosition (sectionStart + 4))
break;
if (stream.read (headerSection, numHeaderSectionBytes) != numHeaderSectionBytes)
break;
const auto sectionSize = ByteOrder::bigEndianInt (headerSection);
if (sectionSize <= 0)
break;
const auto sectionDataStart = stream.getPosition();
for (auto* fmt : internalFormats)
{
if (fmt->canUnderstand (stream))
{
stream.setPosition (sectionDataStart);
images.add (fmt->decodeImage (stream));
const auto lastImageIndex = images.size() - 1;
const auto lastWidth = images.getReference (lastImageIndex).getWidth();
if (lastWidth > maxWidth)
{
maxWidthIndex = lastImageIndex;
maxWidth = lastWidth;
}
}
stream.setPosition (sectionDataStart);
}
stream.setPosition (sectionStart + sectionSize);
}
return maxWidthIndex == -1 ? juce::Image()
: images.getReference (maxWidthIndex).rescaled (size, size, Graphics::ResamplingQuality::highResamplingQuality);
}
Image JUCE_API getIconFromApplication (const String& applicationPath, const int size)
{
Image hostIcon;
if (CFStringRef pathCFString = CFStringCreateWithCString (kCFAllocatorDefault, applicationPath.toRawUTF8(), kCFStringEncodingUTF8))
{
if (CFURLRef url = CFURLCreateWithFileSystemPath (kCFAllocatorDefault, pathCFString, kCFURLPOSIXPathStyle, 1))
{
if (CFBundleRef appBundle = CFBundleCreate (kCFAllocatorDefault, url))
{
if (CFTypeRef infoValue = CFBundleGetValueForInfoDictionaryKey (appBundle, CFSTR("CFBundleIconFile")))
{
if (CFGetTypeID (infoValue) == CFStringGetTypeID())
{
CFStringRef iconFilename = reinterpret_cast<CFStringRef> (infoValue);
CFStringRef resourceURLSuffix = CFStringHasSuffix (iconFilename, CFSTR(".icns")) ? nullptr : CFSTR("icns");
if (CFURLRef iconURL = CFBundleCopyResourceURL (appBundle, iconFilename, resourceURLSuffix, nullptr))
{
if (CFStringRef iconPath = CFURLCopyFileSystemPath (iconURL, kCFURLPOSIXPathStyle))
{
File icnsFile (CFStringGetCStringPtr (iconPath, CFStringGetSystemEncoding()));
hostIcon = getIconFromIcnsFile (icnsFile, size);
CFRelease (iconPath);
}
CFRelease (iconURL);
}
}
}
CFRelease (appBundle);
}
CFRelease (url);
}
CFRelease (pathCFString);
}
return hostIcon;
}

+ 28
- 0
modules/juce_graphics/native/juce_win32_IconHelpers.cpp View File

@@ -0,0 +1,28 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2017 - ROLI Ltd.
Permission is granted to use this software under the terms of either:
a) the GPL v2 (or any later version)
b) the Affero GPL v3
Details of these licenses can be found at: www.gnu.org/licenses
JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
------------------------------------------------------------------------------
To release a closed-source product which uses JUCE, commercial licenses are
available: visit www.juce.com for more information.
==============================================================================
*/
Image JUCE_API getIconFromApplication (const String&, const int)
{
return Image();
}

Loading…
Cancel
Save