| @@ -124,7 +124,7 @@ public: | |||
| bool isOSX() const override { return ! iOS; } | |||
| bool isiOS() const override { return iOS; } | |||
| bool supportsVST() const override { return ! iOS; } | |||
| bool supportsVST() const override { return true; } | |||
| bool supportsVST3() const override { return ! iOS; } | |||
| bool supportsAAX() const override { return ! iOS; } | |||
| bool supportsRTAS() const override { return ! iOS; } | |||
| @@ -272,11 +272,13 @@ public: | |||
| firstProcessCallback (true), | |||
| shouldDeleteEditor (false), | |||
| #if JUCE_64BIT | |||
| useNSView (true), | |||
| useNSView (true) | |||
| #else | |||
| useNSView (false), | |||
| useNSView (false) | |||
| #endif | |||
| #if ! JUCE_IOS | |||
| , hostWindow (0) | |||
| #endif | |||
| hostWindow (0) | |||
| { | |||
| busUtils.init(); | |||
| @@ -343,7 +345,9 @@ public: | |||
| delete filter; | |||
| filter = nullptr; | |||
| #if ! JUCE_IOS | |||
| jassert (editorComp == 0); | |||
| #endif | |||
| deleteTempChannels(); | |||
| @@ -1331,6 +1335,7 @@ public: | |||
| void createEditorComp() | |||
| { | |||
| #if ! JUCE_IOS | |||
| if (hasShutdown || filter == nullptr) | |||
| return; | |||
| @@ -1349,12 +1354,16 @@ public: | |||
| cEffect.flags &= ~effFlagsHasEditor; | |||
| } | |||
| } | |||
| #endif | |||
| shouldDeleteEditor = false; | |||
| } | |||
| void deleteEditor (bool canDeleteLaterIfModal) | |||
| { | |||
| #if JUCE_IOS | |||
| ignoreUnused (canDeleteLaterIfModal); | |||
| #else | |||
| JUCE_AUTORELEASEPOOL | |||
| { | |||
| PopupMenu::dismissAllActiveMenus(); | |||
| @@ -1396,6 +1405,7 @@ public: | |||
| hostWindow = 0; | |||
| #endif | |||
| } | |||
| #endif | |||
| } | |||
| VstIntPtr dispatcher (VstInt32 opCode, VstInt32 index, VstIntPtr value, void* ptr, float opt) override | |||
| @@ -1403,6 +1413,7 @@ public: | |||
| if (hasShutdown) | |||
| return 0; | |||
| #if ! JUCE_IOS | |||
| if (opCode == effEditIdle) | |||
| { | |||
| doIdleCallback(); | |||
| @@ -1432,7 +1443,7 @@ public: | |||
| hostWindow = (Window) ptr; | |||
| Window editorWnd = (Window) editorComp->getWindowHandle(); | |||
| XReparentWindow (display, editorWnd, hostWindow, 0, 0); | |||
| #else | |||
| #elif JUCE_MAC | |||
| hostWindow = attachComponentToWindowRefVST (editorComp, ptr, useNSView); | |||
| #endif | |||
| editorComp->setVisible (true); | |||
| @@ -1467,10 +1478,11 @@ public: | |||
| return 0; | |||
| } | |||
| #endif | |||
| return AudioEffectX::dispatcher (opCode, index, value, ptr, opt); | |||
| } | |||
| #if ! JUCE_IOS | |||
| void resizeHostWindow (int newWidth, int newHeight) | |||
| { | |||
| if (editorComp != nullptr) | |||
| @@ -1659,6 +1671,7 @@ public: | |||
| JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (EditorCompWrapper) | |||
| }; | |||
| #endif | |||
| //============================================================================== | |||
| private: | |||
| @@ -1666,8 +1679,10 @@ private: | |||
| PluginBusUtilities busUtils; | |||
| juce::MemoryBlock chunkMemory; | |||
| juce::uint32 chunkMemoryTime; | |||
| #if ! JUCE_IOS | |||
| ScopedPointer<EditorCompWrapper> editorComp; | |||
| ERect editorSize; | |||
| #endif | |||
| MidiBuffer midiEvents; | |||
| VSTMidiEventList outgoingEvents; | |||
| bool isProcessing, isBypassed, hasShutdown, isInSizeWindow, firstProcessCallback; | |||
| @@ -1680,7 +1695,7 @@ private: | |||
| void* hostWindow; | |||
| #elif JUCE_LINUX | |||
| Window hostWindow; | |||
| #else | |||
| #elif JUCE_WINDOWS | |||
| HWND hostWindow; | |||
| #endif | |||
| @@ -1974,14 +1989,17 @@ namespace | |||
| //============================================================================== | |||
| // Mac startup code.. | |||
| #if JUCE_MAC | |||
| #if JUCE_MAC || JUCE_IOS | |||
| JUCE_EXPORTED_FUNCTION AEffect* VSTPluginMain (audioMasterCallback audioMaster); | |||
| JUCE_EXPORTED_FUNCTION AEffect* VSTPluginMain (audioMasterCallback audioMaster) | |||
| { | |||
| JUCE_DECLARE_WRAPPER_TYPE (wrapperType_VST); | |||
| #if JUCE_MAC | |||
| initialiseMacVST(); | |||
| #endif | |||
| return pluginEntryPoint (audioMaster); | |||
| } | |||
| @@ -1990,7 +2008,10 @@ namespace | |||
| { | |||
| JUCE_DECLARE_WRAPPER_TYPE (wrapperType_VST); | |||
| #if JUCE_MAC | |||
| initialiseMacVST(); | |||
| #endif | |||
| return pluginEntryPoint (audioMaster); | |||
| } | |||
| @@ -22,6 +22,8 @@ | |||
| ============================================================================== | |||
| */ | |||
| #if JUCE_MAC | |||
| #include "../../juce_core/system/juce_TargetPlatform.h" | |||
| #include "../utility/juce_CheckSettingMacros.h" | |||
| @@ -311,3 +313,4 @@ bool forwardCurrentKeyEventToHostVST (Component* comp, bool isNSView) | |||
| } // (juce namespace) | |||
| #endif | |||
| #endif | |||
| @@ -65,7 +65,7 @@ void AudioPluginFormatManager::addDefaultFormats() | |||
| // you should only call this method once! | |||
| for (int i = formats.size(); --i >= 0;) | |||
| { | |||
| #if JUCE_PLUGINHOST_VST && (JUCE_MAC || JUCE_WINDOWS || JUCE_LINUX) | |||
| #if JUCE_PLUGINHOST_VST && (JUCE_MAC || JUCE_WINDOWS || JUCE_LINUX || JUCE_IOS) | |||
| jassert (dynamic_cast<VSTPluginFormat*> (formats[i]) == nullptr); | |||
| #endif | |||
| @@ -87,7 +87,7 @@ void AudioPluginFormatManager::addDefaultFormats() | |||
| formats.add (new AudioUnitPluginFormat()); | |||
| #endif | |||
| #if JUCE_PLUGINHOST_VST && (JUCE_MAC || JUCE_WINDOWS || JUCE_LINUX) | |||
| #if JUCE_PLUGINHOST_VST && (JUCE_MAC || JUCE_WINDOWS || JUCE_LINUX || JUCE_IOS) | |||
| formats.add (new VSTPluginFormat()); | |||
| #endif | |||
| @@ -22,7 +22,7 @@ | |||
| ============================================================================== | |||
| */ | |||
| #if JUCE_PLUGINHOST_VST && (JUCE_MAC || JUCE_WINDOWS || JUCE_LINUX) | |||
| #if JUCE_PLUGINHOST_VST && (JUCE_MAC || JUCE_WINDOWS || JUCE_LINUX || JUCE_IOS) | |||
| //============================================================================== | |||
| #if JUCE_MAC && JUCE_SUPPORT_CARBON | |||
| @@ -165,7 +165,7 @@ namespace | |||
| { | |||
| #if JUCE_WINDOWS | |||
| return timeGetTime() * 1000000.0; | |||
| #elif JUCE_LINUX | |||
| #elif JUCE_LINUX || JUCE_IOS | |||
| timeval micro; | |||
| gettimeofday (µ, 0); | |||
| return micro.tv_usec * 1000.0; | |||
| @@ -378,7 +378,7 @@ public: | |||
| { | |||
| getActiveModules().add (this); | |||
| #if JUCE_WINDOWS || JUCE_LINUX | |||
| #if JUCE_WINDOWS || JUCE_LINUX || JUCE_IOS | |||
| fullParentDirectoryPathName = f.getParentDirectory().getFullPathName(); | |||
| #elif JUCE_MAC | |||
| FSRef ref; | |||
| @@ -394,9 +394,12 @@ public: | |||
| } | |||
| //============================================================================== | |||
| #if JUCE_WINDOWS || JUCE_LINUX | |||
| DynamicLibrary module; | |||
| #if ! JUCE_MAC | |||
| String fullParentDirectoryPathName; | |||
| #endif | |||
| #if JUCE_WINDOWS || JUCE_LINUX | |||
| DynamicLibrary module; | |||
| bool open() | |||
| { | |||
| @@ -457,11 +460,14 @@ public: | |||
| return String(); | |||
| } | |||
| #endif | |||
| #else | |||
| #else | |||
| Handle resHandle; | |||
| CFBundleRef bundleRef; | |||
| #if JUCE_MAC | |||
| CFBundleRefNum resFileId; | |||
| FSSpec parentDirFSSpec; | |||
| ResFileRefNum resFileId; | |||
| #endif | |||
| bool open() | |||
| { | |||
| @@ -504,13 +510,18 @@ public: | |||
| if (pluginName.isEmpty()) | |||
| pluginName = file.getFileNameWithoutExtension(); | |||
| #if JUCE_MAC | |||
| resFileId = CFBundleOpenBundleResourceMap (bundleRef); | |||
| #endif | |||
| ok = true; | |||
| Array<File> vstXmlFiles; | |||
| file.getChildFile ("Contents") | |||
| file | |||
| #if JUCE_MAC | |||
| .getChildFile ("Contents") | |||
| .getChildFile ("Resources") | |||
| #endif | |||
| .findChildFiles (vstXmlFiles, File::findFiles, false, "*.vstxml"); | |||
| if (vstXmlFiles.size() > 0) | |||
| @@ -535,7 +546,9 @@ public: | |||
| { | |||
| if (bundleRef != 0) | |||
| { | |||
| #if JUCE_MAC | |||
| CFBundleCloseBundleResourceMap (bundleRef, resFileId); | |||
| #endif | |||
| if (CFGetRetainCount (bundleRef) == 1) | |||
| CFBundleUnloadExecutable (bundleRef); | |||
| @@ -550,7 +563,7 @@ public: | |||
| eff->dispatcher (eff, effClose, 0, 0, 0, 0); | |||
| } | |||
| #endif | |||
| #endif | |||
| private: | |||
| JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ModuleHandle) | |||
| @@ -856,7 +869,12 @@ public: | |||
| } | |||
| //============================================================================== | |||
| #if JUCE_IOS | |||
| bool hasEditor() const override { return false; } | |||
| #else | |||
| bool hasEditor() const override { return effect != nullptr && (effect->flags & effFlagsHasEditor) != 0; } | |||
| #endif | |||
| AudioProcessorEditor* createEditor() override; | |||
| //============================================================================== | |||
| @@ -1787,6 +1805,7 @@ private: | |||
| }; | |||
| //============================================================================== | |||
| #if ! JUCE_IOS | |||
| class VSTPluginWindow; | |||
| static Array<VSTPluginWindow*> activeVSTWindows; | |||
| @@ -2525,7 +2544,7 @@ private: | |||
| JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (VSTPluginWindow) | |||
| }; | |||
| #endif | |||
| #if JUCE_MSVC | |||
| #pragma warning (pop) | |||
| #endif | |||
| @@ -2533,8 +2552,12 @@ private: | |||
| //============================================================================== | |||
| AudioProcessorEditor* VSTPluginInstance::createEditor() | |||
| { | |||
| #if JUCE_IOS | |||
| return nullptr; | |||
| #else | |||
| return hasEditor() ? new VSTPluginWindow (*this) | |||
| : nullptr; | |||
| #endif | |||
| } | |||
| //============================================================================== | |||
| @@ -2676,7 +2699,7 @@ bool VSTPluginFormat::fileMightContainThisPluginType (const String& fileOrIdenti | |||
| { | |||
| const File f (File::createFileWithoutCheckingPath (fileOrIdentifier)); | |||
| #if JUCE_MAC | |||
| #if JUCE_MAC || JUCE_IOS | |||
| return f.isDirectory() && f.hasFileExtension (".vst"); | |||
| #elif JUCE_WINDOWS | |||
| return f.existsAsFile() && f.hasFileExtension (".dll"); | |||
| @@ -2751,6 +2774,19 @@ FileSearchPath VSTPluginFormat::getDefaultLocationsToSearch() | |||
| paths.add (WindowsRegistry::getValue ("HKEY_LOCAL_MACHINE\\Software\\VST\\VSTPluginsPath", | |||
| programFiles + "\\VstPlugins")); | |||
| return paths; | |||
| #elif JUCE_IOS | |||
| // on iOS you can only load plug-ins inside the hosts bundle folder | |||
| CFURLRef relativePluginDir = CFBundleCopyBuiltInPlugInsURL (CFBundleGetMainBundle()); | |||
| CFURLRef pluginDir = CFURLCopyAbsoluteURL (relativePluginDir); | |||
| CFRelease (relativePluginDir); | |||
| CFStringRef path = CFURLCopyFileSystemPath (pluginDir, kCFURLPOSIXPathStyle); | |||
| CFRelease (pluginDir); | |||
| FileSearchPath retval (String (CFStringGetCStringPtr (path, kCFStringEncodingUTF8))); | |||
| CFRelease (path); | |||
| return retval; | |||
| #endif | |||
| } | |||
| @@ -22,7 +22,7 @@ | |||
| ============================================================================== | |||
| */ | |||
| #if (JUCE_PLUGINHOST_VST && (JUCE_MAC || JUCE_WINDOWS || JUCE_LINUX)) || DOXYGEN | |||
| #if (JUCE_PLUGINHOST_VST && (JUCE_MAC || JUCE_WINDOWS || JUCE_LINUX || JUCE_IOS)) || DOXYGEN | |||
| //============================================================================== | |||
| /** | |||
| @@ -348,8 +348,10 @@ public: | |||
| if (path.getNumPaths() > 0) // if the path is empty, then paths aren't used for this format. | |||
| { | |||
| #if ! JUCE_IOS | |||
| if (propertiesToUse != nullptr) | |||
| path = getLastSearchPath (*propertiesToUse, formatToScan); | |||
| #endif | |||
| pathList.setSize (500, 300); | |||
| pathList.setPath (path); | |||