@@ -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); | |||