Browse Source

Support hosting your own VST bundles on iOS

tags/2021-05-28
hogliux 9 years ago
parent
commit
54243ef0c0
7 changed files with 84 additions and 22 deletions
  1. +1
    -1
      extras/Projucer/Source/Project Saving/jucer_ProjectExport_XCode.h
  2. +28
    -7
      modules/juce_audio_plugin_client/VST/juce_VST_Wrapper.cpp
  3. +3
    -0
      modules/juce_audio_plugin_client/VST/juce_VST_Wrapper.mm
  4. +2
    -2
      modules/juce_audio_processors/format/juce_AudioPluginFormatManager.cpp
  5. +47
    -11
      modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp
  6. +1
    -1
      modules/juce_audio_processors/format_types/juce_VSTPluginFormat.h
  7. +2
    -0
      modules/juce_audio_processors/scanning/juce_PluginListComponent.cpp

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

@@ -124,7 +124,7 @@ public:
bool isOSX() const override { return ! iOS; } bool isOSX() const override { return ! iOS; }
bool isiOS() 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 supportsVST3() const override { return ! iOS; }
bool supportsAAX() const override { return ! iOS; } bool supportsAAX() const override { return ! iOS; }
bool supportsRTAS() const override { return ! iOS; } bool supportsRTAS() const override { return ! iOS; }


+ 28
- 7
modules/juce_audio_plugin_client/VST/juce_VST_Wrapper.cpp View File

@@ -272,11 +272,13 @@ public:
firstProcessCallback (true), firstProcessCallback (true),
shouldDeleteEditor (false), shouldDeleteEditor (false),
#if JUCE_64BIT #if JUCE_64BIT
useNSView (true),
useNSView (true)
#else #else
useNSView (false),
useNSView (false)
#endif
#if ! JUCE_IOS
, hostWindow (0)
#endif #endif
hostWindow (0)
{ {
busUtils.init(); busUtils.init();
@@ -343,7 +345,9 @@ public:
delete filter; delete filter;
filter = nullptr; filter = nullptr;
#if ! JUCE_IOS
jassert (editorComp == 0); jassert (editorComp == 0);
#endif
deleteTempChannels(); deleteTempChannels();
@@ -1331,6 +1335,7 @@ public:
void createEditorComp() void createEditorComp()
{ {
#if ! JUCE_IOS
if (hasShutdown || filter == nullptr) if (hasShutdown || filter == nullptr)
return; return;
@@ -1349,12 +1354,16 @@ public:
cEffect.flags &= ~effFlagsHasEditor; cEffect.flags &= ~effFlagsHasEditor;
} }
} }
#endif
shouldDeleteEditor = false; shouldDeleteEditor = false;
} }
void deleteEditor (bool canDeleteLaterIfModal) void deleteEditor (bool canDeleteLaterIfModal)
{ {
#if JUCE_IOS
ignoreUnused (canDeleteLaterIfModal);
#else
JUCE_AUTORELEASEPOOL JUCE_AUTORELEASEPOOL
{ {
PopupMenu::dismissAllActiveMenus(); PopupMenu::dismissAllActiveMenus();
@@ -1396,6 +1405,7 @@ public:
hostWindow = 0; hostWindow = 0;
#endif #endif
} }
#endif
} }
VstIntPtr dispatcher (VstInt32 opCode, VstInt32 index, VstIntPtr value, void* ptr, float opt) override VstIntPtr dispatcher (VstInt32 opCode, VstInt32 index, VstIntPtr value, void* ptr, float opt) override
@@ -1403,6 +1413,7 @@ public:
if (hasShutdown) if (hasShutdown)
return 0; return 0;
#if ! JUCE_IOS
if (opCode == effEditIdle) if (opCode == effEditIdle)
{ {
doIdleCallback(); doIdleCallback();
@@ -1432,7 +1443,7 @@ public:
hostWindow = (Window) ptr; hostWindow = (Window) ptr;
Window editorWnd = (Window) editorComp->getWindowHandle(); Window editorWnd = (Window) editorComp->getWindowHandle();
XReparentWindow (display, editorWnd, hostWindow, 0, 0); XReparentWindow (display, editorWnd, hostWindow, 0, 0);
#else
#elif JUCE_MAC
hostWindow = attachComponentToWindowRefVST (editorComp, ptr, useNSView); hostWindow = attachComponentToWindowRefVST (editorComp, ptr, useNSView);
#endif #endif
editorComp->setVisible (true); editorComp->setVisible (true);
@@ -1467,10 +1478,11 @@ public:
return 0; return 0;
} }
#endif
return AudioEffectX::dispatcher (opCode, index, value, ptr, opt); return AudioEffectX::dispatcher (opCode, index, value, ptr, opt);
} }
#if ! JUCE_IOS
void resizeHostWindow (int newWidth, int newHeight) void resizeHostWindow (int newWidth, int newHeight)
{ {
if (editorComp != nullptr) if (editorComp != nullptr)
@@ -1659,6 +1671,7 @@ public:
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (EditorCompWrapper) JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (EditorCompWrapper)
}; };
#endif
//============================================================================== //==============================================================================
private: private:
@@ -1666,8 +1679,10 @@ private:
PluginBusUtilities busUtils; PluginBusUtilities busUtils;
juce::MemoryBlock chunkMemory; juce::MemoryBlock chunkMemory;
juce::uint32 chunkMemoryTime; juce::uint32 chunkMemoryTime;
#if ! JUCE_IOS
ScopedPointer<EditorCompWrapper> editorComp; ScopedPointer<EditorCompWrapper> editorComp;
ERect editorSize; ERect editorSize;
#endif
MidiBuffer midiEvents; MidiBuffer midiEvents;
VSTMidiEventList outgoingEvents; VSTMidiEventList outgoingEvents;
bool isProcessing, isBypassed, hasShutdown, isInSizeWindow, firstProcessCallback; bool isProcessing, isBypassed, hasShutdown, isInSizeWindow, firstProcessCallback;
@@ -1680,7 +1695,7 @@ private:
void* hostWindow; void* hostWindow;
#elif JUCE_LINUX #elif JUCE_LINUX
Window hostWindow; Window hostWindow;
#else
#elif JUCE_WINDOWS
HWND hostWindow; HWND hostWindow;
#endif #endif
@@ -1974,14 +1989,17 @@ namespace
//============================================================================== //==============================================================================
// Mac startup code.. // 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_EXPORTED_FUNCTION AEffect* VSTPluginMain (audioMasterCallback audioMaster) JUCE_EXPORTED_FUNCTION AEffect* VSTPluginMain (audioMasterCallback audioMaster)
{ {
JUCE_DECLARE_WRAPPER_TYPE (wrapperType_VST); JUCE_DECLARE_WRAPPER_TYPE (wrapperType_VST);
#if JUCE_MAC
initialiseMacVST(); initialiseMacVST();
#endif
return pluginEntryPoint (audioMaster); return pluginEntryPoint (audioMaster);
} }
@@ -1990,7 +2008,10 @@ namespace
{ {
JUCE_DECLARE_WRAPPER_TYPE (wrapperType_VST); JUCE_DECLARE_WRAPPER_TYPE (wrapperType_VST);
#if JUCE_MAC
initialiseMacVST(); initialiseMacVST();
#endif
return pluginEntryPoint (audioMaster); return pluginEntryPoint (audioMaster);
} }


+ 3
- 0
modules/juce_audio_plugin_client/VST/juce_VST_Wrapper.mm View File

@@ -22,6 +22,8 @@
============================================================================== ==============================================================================
*/ */
#if JUCE_MAC
#include "../../juce_core/system/juce_TargetPlatform.h" #include "../../juce_core/system/juce_TargetPlatform.h"
#include "../utility/juce_CheckSettingMacros.h" #include "../utility/juce_CheckSettingMacros.h"
@@ -311,3 +313,4 @@ bool forwardCurrentKeyEventToHostVST (Component* comp, bool isNSView)
} // (juce namespace) } // (juce namespace)
#endif #endif
#endif

+ 2
- 2
modules/juce_audio_processors/format/juce_AudioPluginFormatManager.cpp View File

@@ -65,7 +65,7 @@ void AudioPluginFormatManager::addDefaultFormats()
// you should only call this method once! // you should only call this method once!
for (int i = formats.size(); --i >= 0;) 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); jassert (dynamic_cast<VSTPluginFormat*> (formats[i]) == nullptr);
#endif #endif
@@ -87,7 +87,7 @@ void AudioPluginFormatManager::addDefaultFormats()
formats.add (new AudioUnitPluginFormat()); formats.add (new AudioUnitPluginFormat());
#endif #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()); formats.add (new VSTPluginFormat());
#endif #endif


+ 47
- 11
modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp View File

@@ -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 #if JUCE_MAC && JUCE_SUPPORT_CARBON
@@ -165,7 +165,7 @@ namespace
{ {
#if JUCE_WINDOWS #if JUCE_WINDOWS
return timeGetTime() * 1000000.0; return timeGetTime() * 1000000.0;
#elif JUCE_LINUX
#elif JUCE_LINUX || JUCE_IOS
timeval micro; timeval micro;
gettimeofday (&micro, 0); gettimeofday (&micro, 0);
return micro.tv_usec * 1000.0; return micro.tv_usec * 1000.0;
@@ -378,7 +378,7 @@ public:
{ {
getActiveModules().add (this); getActiveModules().add (this);
#if JUCE_WINDOWS || JUCE_LINUX
#if JUCE_WINDOWS || JUCE_LINUX || JUCE_IOS
fullParentDirectoryPathName = f.getParentDirectory().getFullPathName(); fullParentDirectoryPathName = f.getParentDirectory().getFullPathName();
#elif JUCE_MAC #elif JUCE_MAC
FSRef ref; FSRef ref;
@@ -394,9 +394,12 @@ public:
} }
//============================================================================== //==============================================================================
#if JUCE_WINDOWS || JUCE_LINUX
DynamicLibrary module;
#if ! JUCE_MAC
String fullParentDirectoryPathName; String fullParentDirectoryPathName;
#endif
#if JUCE_WINDOWS || JUCE_LINUX
DynamicLibrary module;
bool open() bool open()
{ {
@@ -457,11 +460,14 @@ public:
return String(); return String();
} }
#endif #endif
#else
#else
Handle resHandle; Handle resHandle;
CFBundleRef bundleRef; CFBundleRef bundleRef;
#if JUCE_MAC
CFBundleRefNum resFileId;
FSSpec parentDirFSSpec; FSSpec parentDirFSSpec;
ResFileRefNum resFileId;
#endif
bool open() bool open()
{ {
@@ -504,13 +510,18 @@ public:
if (pluginName.isEmpty()) if (pluginName.isEmpty())
pluginName = file.getFileNameWithoutExtension(); pluginName = file.getFileNameWithoutExtension();
#if JUCE_MAC
resFileId = CFBundleOpenBundleResourceMap (bundleRef); resFileId = CFBundleOpenBundleResourceMap (bundleRef);
#endif
ok = true; ok = true;
Array<File> vstXmlFiles; Array<File> vstXmlFiles;
file.getChildFile ("Contents")
file
#if JUCE_MAC
.getChildFile ("Contents")
.getChildFile ("Resources") .getChildFile ("Resources")
#endif
.findChildFiles (vstXmlFiles, File::findFiles, false, "*.vstxml"); .findChildFiles (vstXmlFiles, File::findFiles, false, "*.vstxml");
if (vstXmlFiles.size() > 0) if (vstXmlFiles.size() > 0)
@@ -535,7 +546,9 @@ public:
{ {
if (bundleRef != 0) if (bundleRef != 0)
{ {
#if JUCE_MAC
CFBundleCloseBundleResourceMap (bundleRef, resFileId); CFBundleCloseBundleResourceMap (bundleRef, resFileId);
#endif
if (CFGetRetainCount (bundleRef) == 1) if (CFGetRetainCount (bundleRef) == 1)
CFBundleUnloadExecutable (bundleRef); CFBundleUnloadExecutable (bundleRef);
@@ -550,7 +563,7 @@ public:
eff->dispatcher (eff, effClose, 0, 0, 0, 0); eff->dispatcher (eff, effClose, 0, 0, 0, 0);
} }
#endif
#endif
private: private:
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ModuleHandle) 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; } bool hasEditor() const override { return effect != nullptr && (effect->flags & effFlagsHasEditor) != 0; }
#endif
AudioProcessorEditor* createEditor() override; AudioProcessorEditor* createEditor() override;
//============================================================================== //==============================================================================
@@ -1787,6 +1805,7 @@ private:
}; };
//============================================================================== //==============================================================================
#if ! JUCE_IOS
class VSTPluginWindow; class VSTPluginWindow;
static Array<VSTPluginWindow*> activeVSTWindows; static Array<VSTPluginWindow*> activeVSTWindows;
@@ -2525,7 +2544,7 @@ private:
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (VSTPluginWindow) JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (VSTPluginWindow)
}; };
#endif
#if JUCE_MSVC #if JUCE_MSVC
#pragma warning (pop) #pragma warning (pop)
#endif #endif
@@ -2533,8 +2552,12 @@ private:
//============================================================================== //==============================================================================
AudioProcessorEditor* VSTPluginInstance::createEditor() AudioProcessorEditor* VSTPluginInstance::createEditor()
{ {
#if JUCE_IOS
return nullptr;
#else
return hasEditor() ? new VSTPluginWindow (*this) return hasEditor() ? new VSTPluginWindow (*this)
: nullptr; : nullptr;
#endif
} }
//============================================================================== //==============================================================================
@@ -2676,7 +2699,7 @@ bool VSTPluginFormat::fileMightContainThisPluginType (const String& fileOrIdenti
{ {
const File f (File::createFileWithoutCheckingPath (fileOrIdentifier)); const File f (File::createFileWithoutCheckingPath (fileOrIdentifier));
#if JUCE_MAC
#if JUCE_MAC || JUCE_IOS
return f.isDirectory() && f.hasFileExtension (".vst"); return f.isDirectory() && f.hasFileExtension (".vst");
#elif JUCE_WINDOWS #elif JUCE_WINDOWS
return f.existsAsFile() && f.hasFileExtension (".dll"); return f.existsAsFile() && f.hasFileExtension (".dll");
@@ -2751,6 +2774,19 @@ FileSearchPath VSTPluginFormat::getDefaultLocationsToSearch()
paths.add (WindowsRegistry::getValue ("HKEY_LOCAL_MACHINE\\Software\\VST\\VSTPluginsPath", paths.add (WindowsRegistry::getValue ("HKEY_LOCAL_MACHINE\\Software\\VST\\VSTPluginsPath",
programFiles + "\\VstPlugins")); programFiles + "\\VstPlugins"));
return paths; 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 #endif
} }


+ 1
- 1
modules/juce_audio_processors/format_types/juce_VSTPluginFormat.h View File

@@ -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
//============================================================================== //==============================================================================
/** /**


+ 2
- 0
modules/juce_audio_processors/scanning/juce_PluginListComponent.cpp View File

@@ -348,8 +348,10 @@ public:
if (path.getNumPaths() > 0) // if the path is empty, then paths aren't used for this format. if (path.getNumPaths() > 0) // if the path is empty, then paths aren't used for this format.
{ {
#if ! JUCE_IOS
if (propertiesToUse != nullptr) if (propertiesToUse != nullptr)
path = getLastSearchPath (*propertiesToUse, formatToScan); path = getLastSearchPath (*propertiesToUse, formatToScan);
#endif
pathList.setSize (500, 300); pathList.setSize (500, 300);
pathList.setPath (path); pathList.setPath (path);


Loading…
Cancel
Save