summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libs/ardour/ardour/buffer_set.h6
-rw-r--r--libs/ardour/ardour/mac_vst_plugin.h55
-rw-r--r--libs/ardour/ardour/mac_vst_support.h39
-rw-r--r--libs/ardour/ardour/plugin_manager.h7
-rw-r--r--libs/ardour/ardour/plugin_types.h1
-rw-r--r--libs/ardour/ardour/rc_configuration_vars.h1
-rw-r--r--libs/ardour/ardour/vst_info_file.h4
-rw-r--r--libs/ardour/ardour/vst_types.h3
-rw-r--r--libs/ardour/buffer_set.cc8
-rw-r--r--libs/ardour/mac_vst_plugin.cc168
-rw-r--r--libs/ardour/mac_vst_support.cc303
-rw-r--r--libs/ardour/plugin.cc6
-rw-r--r--libs/ardour/plugin_insert.cc23
-rw-r--r--libs/ardour/plugin_manager.cc163
-rw-r--r--libs/ardour/route.cc2
-rw-r--r--libs/ardour/vst_info_file.cc72
-rw-r--r--libs/ardour/wscript6
-rw-r--r--libs/fst/scanner.cc9
-rw-r--r--libs/fst/wscript2
-rw-r--r--wscript2
20 files changed, 865 insertions, 15 deletions
diff --git a/libs/ardour/ardour/buffer_set.h b/libs/ardour/ardour/buffer_set.h
index 9ea6ab7d6a..f1b632e6e2 100644
--- a/libs/ardour/ardour/buffer_set.h
+++ b/libs/ardour/ardour/buffer_set.h
@@ -30,7 +30,7 @@
#include "ardour/libardour_visibility.h"
#include "ardour/types.h"
-#if defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT
+#if defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT
#include "evoral/MIDIEvent.hpp"
struct _VstEvents;
typedef struct _VstEvents VstEvents;
@@ -130,7 +130,7 @@ public:
void forward_lv2_midi(LV2_Evbuf*, size_t, bool purge_ardour_buffer = true);
#endif
-#if defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT
+#if defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT
VstEvents* get_vst_midi (size_t);
#endif
@@ -189,7 +189,7 @@ private:
LV2Buffers _lv2_buffers;
#endif
-#if defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT
+#if defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT
class VSTBuffer {
public:
VSTBuffer (size_t);
diff --git a/libs/ardour/ardour/mac_vst_plugin.h b/libs/ardour/ardour/mac_vst_plugin.h
new file mode 100644
index 0000000000..e5afab5e30
--- /dev/null
+++ b/libs/ardour/ardour/mac_vst_plugin.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2016 Robin Gareus <robin@gareus.org>
+ * Copyright (C) 2004 Paul Davis
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __ardour_mac_vst_plugin_h__
+#define __ardour_mac_vst_plugin_h__
+
+#include "ardour/vst_plugin.h"
+
+struct LIBARDOUR_API _VSTHandle;
+typedef struct _VSTHandle VSTHandle;
+
+namespace ARDOUR {
+
+class AudioEngine;
+class Session;
+
+class LIBARDOUR_API MacVSTPlugin : public VSTPlugin
+{
+public:
+ MacVSTPlugin (AudioEngine &, Session &, VSTHandle *, int unique_id);
+ MacVSTPlugin (const MacVSTPlugin &);
+ ~MacVSTPlugin ();
+
+ std::string state_node_name () const { return "mac-vst"; }
+};
+
+class LIBARDOUR_API MacVSTPluginInfo : public PluginInfo
+{
+public:
+ MacVSTPluginInfo ();
+ ~MacVSTPluginInfo () {}
+
+ PluginPtr load (Session& session);
+ std::vector<Plugin::PresetRecord> get_presets (bool user_only) const;
+};
+
+} // namespace ARDOUR
+
+#endif /* __ardour_mac_vst_plugin_h__ */
diff --git a/libs/ardour/ardour/mac_vst_support.h b/libs/ardour/ardour/mac_vst_support.h
new file mode 100644
index 0000000000..8a23960095
--- /dev/null
+++ b/libs/ardour/ardour/mac_vst_support.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2016 Robin Gareus <robin@gareus.org>
+ * Copyright (C) 2012 Paul Davis
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __mac_vst_support_h__
+#define __mac_vst_support_h__
+
+#include <setjmp.h>
+#include <signal.h>
+#include <pthread.h>
+#include <stdio.h>
+
+#include "ardour/libardour_visibility.h"
+#include "ardour/vst_types.h"
+
+LIBARDOUR_API extern void (*mac_vst_error_callback)(const char *msg);
+LIBARDOUR_API void mac_vst_error (const char *fmt, ...);
+
+LIBARDOUR_API extern VSTHandle * mac_vst_load (const char*);
+LIBARDOUR_API extern int mac_vst_unload (VSTHandle *);
+LIBARDOUR_API extern VSTState * mac_vst_instantiate (VSTHandle *, audioMasterCallback, void *);
+LIBARDOUR_API extern void mac_vst_close (VSTState*);
+
+#endif /* ____mac_vst_support_h__ */
diff --git a/libs/ardour/ardour/plugin_manager.h b/libs/ardour/ardour/plugin_manager.h
index 1a925432a0..9de951dc23 100644
--- a/libs/ardour/ardour/plugin_manager.h
+++ b/libs/ardour/ardour/plugin_manager.h
@@ -47,6 +47,7 @@ class LIBARDOUR_API PluginManager : public boost::noncopyable {
ARDOUR::PluginInfoList &windows_vst_plugin_info ();
ARDOUR::PluginInfoList &lxvst_plugin_info ();
+ ARDOUR::PluginInfoList &mac_vst_plugin_info ();
ARDOUR::PluginInfoList &ladspa_plugin_info ();
ARDOUR::PluginInfoList &lv2_plugin_info ();
ARDOUR::PluginInfoList &au_plugin_info ();
@@ -110,6 +111,7 @@ class LIBARDOUR_API PluginManager : public boost::noncopyable {
ARDOUR::PluginInfoList _empty_plugin_info;
ARDOUR::PluginInfoList* _windows_vst_plugin_info;
ARDOUR::PluginInfoList* _lxvst_plugin_info;
+ ARDOUR::PluginInfoList* _mac_vst_plugin_info;
ARDOUR::PluginInfoList* _ladspa_plugin_info;
ARDOUR::PluginInfoList* _lv2_plugin_info;
ARDOUR::PluginInfoList* _au_plugin_info;
@@ -127,11 +129,13 @@ class LIBARDOUR_API PluginManager : public boost::noncopyable {
void lua_refresh ();
void lua_refresh_cb ();
void windows_vst_refresh (bool cache_only = false);
+ void mac_vst_refresh (bool cache_only = false);
void lxvst_refresh (bool cache_only = false);
void add_lrdf_data (const std::string &path);
void add_ladspa_presets ();
void add_windows_vst_presets ();
+ void add_mac_vst_presets ();
void add_lxvst_presets ();
void add_presets (std::string domain);
@@ -142,6 +146,9 @@ class LIBARDOUR_API PluginManager : public boost::noncopyable {
int windows_vst_discover_from_path (std::string path, bool cache_only = false);
int windows_vst_discover (std::string path, bool cache_only = false);
+ int mac_vst_discover_from_path (std::string path, bool cache_only = false);
+ int mac_vst_discover (std::string path, bool cache_only = false);
+
int lxvst_discover_from_path (std::string path, bool cache_only = false);
int lxvst_discover (std::string path, bool cache_only = false);
diff --git a/libs/ardour/ardour/plugin_types.h b/libs/ardour/ardour/plugin_types.h
index d997e2891a..3c37befc40 100644
--- a/libs/ardour/ardour/plugin_types.h
+++ b/libs/ardour/ardour/plugin_types.h
@@ -28,6 +28,7 @@ namespace ARDOUR {
LV2,
Windows_VST,
LXVST,
+ MacVST,
Lua,
};
diff --git a/libs/ardour/ardour/rc_configuration_vars.h b/libs/ardour/ardour/rc_configuration_vars.h
index 62a15a3fe2..79db43a902 100644
--- a/libs/ardour/ardour/rc_configuration_vars.h
+++ b/libs/ardour/ardour/rc_configuration_vars.h
@@ -237,6 +237,7 @@ CONFIG_VARIABLE (bool, new_plugins_active, "new-plugins-active", true)
CONFIG_VARIABLE (bool, use_plugin_own_gui, "use-plugin-own-gui", true)
CONFIG_VARIABLE (bool, use_windows_vst, "use-windows-vst", true)
CONFIG_VARIABLE (bool, use_lxvst, "use-lxvst", true)
+CONFIG_VARIABLE (bool, use_macvst, "use-macvst", true)
CONFIG_VARIABLE (bool, discover_vst_on_start, "discover-vst-on-start", false)
CONFIG_VARIABLE (bool, verbose_plugin_scan, "verbose-plugin-scan", true)
CONFIG_VARIABLE (int, vst_scan_timeout, "vst-scan-timeout", 600) /* deciseconds, per plugin, <= 0 no timeout */
diff --git a/libs/ardour/ardour/vst_info_file.h b/libs/ardour/ardour/vst_info_file.h
index f253ab0b4b..b9567dec9f 100644
--- a/libs/ardour/ardour/vst_info_file.h
+++ b/libs/ardour/ardour/vst_info_file.h
@@ -60,6 +60,10 @@ LIBARDOUR_API extern std::vector<VSTInfo*> * vstfx_get_info_lx (char *, enum VST
LIBARDOUR_API extern std::vector<VSTInfo*> * vstfx_get_info_fst (char *, enum VSTScanMode mode = VST_SCAN_USE_APP);
#endif
+#ifdef MACVST_SUPPORT
+LIBARDOUR_API extern std::vector<VSTInfo*> * vstfx_get_info_mac (char *, enum VSTScanMode mode = VST_SCAN_USE_APP);
+#endif
+
#ifndef VST_SCANNER_APP
} // namespace
#endif
diff --git a/libs/ardour/ardour/vst_types.h b/libs/ardour/ardour/vst_types.h
index aa6432876e..b9c62e4fe1 100644
--- a/libs/ardour/ardour/vst_types.h
+++ b/libs/ardour/ardour/vst_types.h
@@ -68,6 +68,9 @@ struct LIBARDOUR_API _VSTHandle
main_entry_t main_entry;
int plugincnt;
+#ifdef MACVST_SUPPORT
+ int32_t res_file_id;
+#endif
};
typedef struct _VSTHandle VSTHandle;
diff --git a/libs/ardour/buffer_set.cc b/libs/ardour/buffer_set.cc
index 66564f3202..982725f491 100644
--- a/libs/ardour/buffer_set.cc
+++ b/libs/ardour/buffer_set.cc
@@ -39,7 +39,7 @@
#include "ardour/lv2_plugin.h"
#include "lv2_evbuf.h"
#endif
-#if defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT
+#if defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT
#include "ardour/vestige/aeffectx.h"
#endif
@@ -79,7 +79,7 @@ BufferSet::clear()
_count.reset();
_available.reset();
-#if defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT
+#if defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT
for (VSTBuffers::iterator i = _vst_buffers.begin(); i != _vst_buffers.end(); ++i) {
delete *i;
}
@@ -206,7 +206,7 @@ BufferSet::ensure_buffers(DataType type, size_t num_buffers, size_t buffer_capac
}
#endif
-#if defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT
+#if defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT
// As above but for VST
if (type == DataType::MIDI) {
while (_vst_buffers.size() < _buffers[type].size()) {
@@ -343,7 +343,7 @@ BufferSet::flush_lv2_midi(bool input, size_t i)
#endif /* LV2_SUPPORT */
-#if defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT
+#if defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT
VstEvents*
BufferSet::get_vst_midi (size_t b)
diff --git a/libs/ardour/mac_vst_plugin.cc b/libs/ardour/mac_vst_plugin.cc
new file mode 100644
index 0000000000..08c39b1d35
--- /dev/null
+++ b/libs/ardour/mac_vst_plugin.cc
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2016 Robin Gareus <robin@gareus.org>
+ * Copyright (C) 2004 Paul Davis
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <glibmm/fileutils.h>
+#include <glibmm/miscutils.h>
+
+#include "ardour/filesystem_paths.h"
+#include "ardour/mac_vst_plugin.h"
+#include "ardour/mac_vst_support.h"
+#include "ardour/session.h"
+
+#include "pbd/i18n.h"
+
+using namespace std;
+using namespace ARDOUR;
+using namespace PBD;
+
+MacVSTPlugin::MacVSTPlugin (AudioEngine& e, Session& session, VSTHandle* h, int unique_id)
+ : VSTPlugin (e, session, h)
+{
+ /* Instantiate the plugin and return a VSTState* */
+
+ Session::vst_current_loading_id = unique_id;
+ if ((_state = mac_vst_instantiate (_handle, Session::vst_callback, this)) == 0) {
+ throw failed_constructor ();
+ }
+ Session::vst_current_loading_id = 0;
+
+ set_plugin (_state->plugin);
+}
+
+MacVSTPlugin::MacVSTPlugin (const MacVSTPlugin &other)
+ : VSTPlugin (other)
+{
+ _handle = other._handle;
+
+ Session::vst_current_loading_id = PBD::atoi (other.unique_id ());
+ if ((_state = mac_vst_instantiate (_handle, Session::vst_callback, this)) == 0) {
+ throw failed_constructor ();
+ }
+ Session::vst_current_loading_id = 0;
+
+ _plugin = _state->plugin;
+
+ // Plugin::setup_controls ();
+}
+
+MacVSTPlugin::~MacVSTPlugin ()
+{
+ mac_vst_close (_state);
+}
+
+PluginPtr
+MacVSTPluginInfo::load (Session& session)
+{
+ try {
+ PluginPtr plugin;
+
+ if (Config->get_use_macvst ()) {
+ VSTHandle* handle;
+
+ handle = mac_vst_load (path.c_str ());
+
+ if (handle == NULL) {
+ error << string_compose (_("MacVST: cannot load module from \"%1\""), path) << endmsg;
+ }
+ else {
+ plugin.reset (new MacVSTPlugin (session.engine (), session, handle, PBD::atoi (unique_id)));
+ }
+ }
+ else {
+ error << _("You asked ardour to not use any MacVST plugins") << endmsg;
+ return PluginPtr ((Plugin*) 0);
+ }
+
+ plugin->set_info (PluginInfoPtr (new MacVSTPluginInfo (*this)));
+ return plugin;
+ }
+
+ catch (failed_constructor &err) {
+ return PluginPtr ((Plugin*) 0);
+ }
+}
+
+std::vector<Plugin::PresetRecord>
+MacVSTPluginInfo::get_presets (bool user_only) const
+{
+ std::vector<Plugin::PresetRecord> p;
+#ifndef NO_PLUGIN_STATE
+ if (!Config->get_use_macvst ()) {
+ return p;
+ }
+
+ if (!user_only) {
+ // TODO - cache, instantiating the plugin can be heavy
+ /* Built-in presets */
+ VSTHandle* handle = mac_vst_load (path.c_str ());
+ Session::vst_current_loading_id = atoi (unique_id);
+ AEffect* plugin = handle->main_entry (Session::vst_callback);
+ Session::vst_current_loading_id = 0;
+
+ plugin->dispatcher (plugin, effOpen, 0, 0, 0, 0); // :(
+ int const vst_version = plugin->dispatcher (plugin, effGetVstVersion, 0, 0, NULL, 0);
+
+ for (int i = 0; i < plugin->numPrograms; ++i) {
+ Plugin::PresetRecord r (string_compose (X_("VST:%1:%2"), unique_id, i), "", false);
+ if (vst_version >= 2) {
+ char buf[256];
+ if (plugin->dispatcher (plugin, 29, i, 0, buf, 0) == 1) {
+ r.label = buf;
+ } else {
+ r.label = string_compose (_("Preset %1"), i);
+ }
+ } else {
+ r.label = string_compose (_("Preset %1"), i);
+ }
+ p.push_back (r);
+ }
+
+ plugin->dispatcher (plugin, effMainsChanged, 0, 0, 0, 0);
+ plugin->dispatcher (plugin, effClose, 0, 0, 0, 0); // :(
+
+ if (handle->plugincnt) {
+ handle->plugincnt--;
+ }
+ mac_vst_unload (handle);
+ }
+
+ /* user presets */
+ XMLTree* t = new XMLTree;
+ std::string pf = Glib::build_filename (ARDOUR::user_config_directory (), "presets", string_compose ("vst-%1", unique_id));
+ if (Glib::file_test (pf, Glib::FILE_TEST_EXISTS)) {
+ t->set_filename (pf);
+ if (t->read ()) { // TODO read names only. skip parsing the actual data
+ XMLNode* root = t->root ();
+ for (XMLNodeList::const_iterator i = root->children ().begin (); i != root->children ().end (); ++i) {
+ XMLProperty const * uri = (*i)->property (X_("uri"));
+ XMLProperty const * label = (*i)->property (X_("label"));
+ p.push_back (Plugin::PresetRecord (uri->value (), label->value (), true));
+ }
+ }
+ }
+ delete t;
+#endif
+
+ return p;
+}
+
+MacVSTPluginInfo::MacVSTPluginInfo ()
+{
+ type = ARDOUR::MacVST;
+}
diff --git a/libs/ardour/mac_vst_support.cc b/libs/ardour/mac_vst_support.cc
new file mode 100644
index 0000000000..42eb3f70e5
--- /dev/null
+++ b/libs/ardour/mac_vst_support.cc
@@ -0,0 +1,303 @@
+/*
+ * Copyright (C) 2016 Robin Gareus <robin@gareus.org>
+ * Copyright (C) 2012 Paul Davis
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <pthread.h>
+#include <signal.h>
+#include <dlfcn.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+#include <pthread.h>
+
+#include <glib.h>
+#include "pbd/gstdio_compat.h"
+#include <glibmm/miscutils.h>
+#include <glibmm/fileutils.h>
+
+#include "ardour/mac_vst_support.h"
+#include "pbd/basename.h"
+#include "pbd/error.h"
+
+#include "pbd/i18n.h"
+
+#include <Carbon/Carbon.h>
+
+/*Simple error handler stuff for VSTFX*/
+
+void mac_vst_error (const char *fmt, ...)
+{
+ va_list ap;
+ char buffer[512];
+
+ va_start (ap, fmt);
+ vsnprintf (buffer, sizeof (buffer), fmt, ap);
+ mac_vst_error_callback (buffer);
+ va_end (ap);
+}
+
+/*default error handler callback*/
+
+static void default_mac_vst_error_callback (const char *desc)
+{
+ PBD::error << desc << endmsg;
+}
+
+void (*mac_vst_error_callback)(const char *desc) = &default_mac_vst_error_callback;
+
+/* --- */
+
+/*Create and return a pointer to a new VSTFX handle*/
+
+static VSTHandle *
+mac_vst_handle_new ()
+{
+ VSTHandle* mac_vst = (VSTHandle *) calloc (1, sizeof (VSTHandle));
+ return mac_vst;
+}
+
+/*Create and return a pointer to a new mac_vst instance*/
+
+static VSTState *
+mac_vst_new ()
+{
+ VSTState* mac_vst = (VSTState *) calloc (1, sizeof (VSTState));
+
+ /*Mutexes*/
+ pthread_mutex_init (&mac_vst->lock, 0);
+ pthread_cond_init (&mac_vst->window_status_change, 0); // XXX unused
+ pthread_cond_init (&mac_vst->plugin_dispatcher_called, 0); // XXX unused
+ pthread_cond_init (&mac_vst->window_created, 0); // XXX unused
+
+ /*Safe values*/
+ mac_vst->want_program = -1;
+ mac_vst->want_chunk = 0;
+ mac_vst->n_pending_keys = 0;
+ mac_vst->has_editor = 0;
+ mac_vst->program_set_without_editor = 0;
+ mac_vst->linux_window = 0;
+ mac_vst->linux_plugin_ui_window = 0;
+ mac_vst->eventProc = 0;
+ mac_vst->extra_data = 0;
+ mac_vst->want_resize = 0;
+
+ return mac_vst;
+}
+
+/*This loads up a plugin, given the path to its .vst bundle and
+ * finds its main entry point etc */
+
+VSTHandle *
+mac_vst_load (const char *path)
+{
+ VSTHandle* fhandle;
+
+ /*Create a new handle we can use to reference the plugin*/
+
+ fhandle = mac_vst_handle_new ();
+
+ fhandle->dll = NULL;
+
+ CFURLRef url;
+ if (!(url = CFURLCreateFromFileSystemRepresentation (0, (const UInt8*)path, (CFIndex) strlen (path), true))) {
+ return 0;
+ }
+
+ CFBundleRef bundleRef = CFBundleCreate (kCFAllocatorDefault, url);
+ CFRelease (url);
+
+ if (bundleRef == 0) {
+ return 0;
+ }
+
+ if (!CFBundleLoadExecutable (bundleRef)) {
+ CFRelease (bundleRef);
+ return 0;
+ }
+
+ fhandle->name = strdup (path);
+ fhandle->dll = (void*) &bundleRef;
+
+ fhandle->main_entry = (main_entry_t)
+ CFBundleGetFunctionPointerForName (bundleRef, CFSTR("main_macho"));
+
+ if (!fhandle->main_entry) {
+ fhandle->main_entry = (main_entry_t)
+ CFBundleGetFunctionPointerForName (bundleRef, CFSTR("VSTPluginMain"));
+ }
+
+ if (fhandle->main_entry == 0) {
+ mac_vst_unload (fhandle);
+ return 0;
+ }
+
+ fhandle->res_file_id = CFBundleOpenBundleResourceMap (bundleRef);
+
+ /*return the handle of the plugin*/
+ return fhandle;
+}
+
+/*This unloads a plugin*/
+
+int
+mac_vst_unload (VSTHandle* fhandle)
+{
+ if (fhandle->plugincnt)
+ {
+ /*Still have plugin instances - can't unload the library
+ - actually dlclose keeps an instance count anyway*/
+
+ return -1;
+ }
+
+ /*Valid plugin loaded?*/
+
+ if (fhandle->dll)
+ {
+ CFBundleRef* bundleRefPtr = (CFBundleRef*) fhandle->dll;
+ CFBundleCloseBundleResourceMap (*bundleRefPtr, (CFBundleRefNum)fhandle->res_file_id);
+ CFRelease (*bundleRefPtr);
+ fhandle->dll = 0;
+ }
+
+ if (fhandle->name)
+ {
+ free (fhandle->name);
+ }
+
+ /*Don't need the plugin handle any more*/
+
+ free (fhandle);
+ return 0;
+}
+
+/*This instantiates a plugin*/
+
+VSTState *
+mac_vst_instantiate (VSTHandle* fhandle, audioMasterCallback amc, void* userptr)
+{
+ VSTState* mac_vst = mac_vst_new ();
+
+ if (fhandle == 0)
+ {
+ mac_vst_error ( "** ERROR ** VSTFX : The handle was 0\n" );
+ free (mac_vst);
+ return 0;
+ }
+
+ if ((mac_vst->plugin = fhandle->main_entry (amc)) == 0)
+ {
+ mac_vst_error ("** ERROR ** VSTFX : %s could not be instantiated :(\n", fhandle->name);
+ free (mac_vst);
+ return 0;
+ }
+
+ mac_vst->handle = fhandle;
+ mac_vst->plugin->user = userptr;
+
+ if (mac_vst->plugin->magic != kEffectMagic)
+ {
+ mac_vst_error ("** ERROR ** VSTFX : %s is not a VST plugin\n", fhandle->name);
+ free (mac_vst);
+ return 0;
+ }
+
+ mac_vst->plugin->dispatcher (mac_vst->plugin, effOpen, 0, 0, 0, 0);
+
+ /*May or May not need to 'switch the plugin on' here - unlikely
+ since FST doesn't and most plugins start up 'On' by default - I think this is the least of our worries*/
+
+ //mac_vst->plugin->dispatcher (mac_vst->plugin, effMainsChanged, 0, 1, 0, 0);
+
+ /* configure plugin to use Cocoa View */
+ mac_vst->plugin->dispatcher (mac_vst->plugin, effCanDo, 0, 0, const_cast<char*> ("hasCockosViewAsConfig"), 0.0f);
+
+ mac_vst->vst_version = mac_vst->plugin->dispatcher (mac_vst->plugin, effGetVstVersion, 0, 0, 0, 0);
+
+ mac_vst->handle->plugincnt++;
+ mac_vst->wantIdle = 0;
+
+ return mac_vst;
+}
+
+/*Close a mac_vst instance*/
+
+void mac_vst_close (VSTState* mac_vst)
+{
+ // assert that the GUI object is destoyed
+
+ if (mac_vst->plugin)
+ {
+ mac_vst->plugin->dispatcher (mac_vst->plugin, effMainsChanged, 0, 0, 0, 0);
+
+ /*Calling dispatcher with effClose will cause the plugin's destructor to
+ be called, which will also remove the editor if it exists*/
+
+ mac_vst->plugin->dispatcher (mac_vst->plugin, effClose, 0, 0, 0, 0);
+ }
+
+ if (mac_vst->handle->plugincnt)
+ mac_vst->handle->plugincnt--;
+
+ /*mac_vst_unload will unload the dll if the instance count allows -
+ we need to do this because some plugins keep their own instance count
+ and (JUCE) manages the plugin UI in its own thread. When the plugins
+ internal instance count reaches zero, JUCE stops the UI thread and won't
+ restart it until the next time the library is loaded. If we don't unload
+ the lib JUCE will never restart*/
+
+
+ if (mac_vst->handle->plugincnt)
+ {
+ return;
+ }
+
+ /*Valid plugin loaded - so we can unload it and 0 the pointer
+ to it. We can't free the handle here because we don't know what else
+ might need it. It should be / is freed when the plugin is deleted*/
+
+ if (mac_vst->handle->dll)
+ {
+ dlclose (mac_vst->handle->dll); //dlclose keeps its own reference count
+ mac_vst->handle->dll = 0;
+ }
+ free (mac_vst);
+}
+
+#if 0 // TODO wrap dispatch
+intptr_t
+mac_vst_dispatch (VSTState* mac_vst, int op, int idx, intptr_t val, void* ptr, float opt)
+{
+ const ResFileRefNum old_resources = CurResFile();
+
+ if (mac_vst->handle->res_file_id) {
+ UseResFile (mac_vst->handle->res_file_id);
+ }
+
+ mac_vst->plugin->dispatcher (mac_vst->plugin, op, idx, val, prt, opt);
+
+ const ResFileRefNum current_res = CurResFile();
+ if (current_res != old_resources) {
+ mac_vst->handle->res_file_id = current_res;
+ UseResFile (old_resources);
+ }
+}
+#endif
diff --git a/libs/ardour/plugin.cc b/libs/ardour/plugin.cc
index f76f96af7a..d21ecfe632 100644
--- a/libs/ardour/plugin.cc
+++ b/libs/ardour/plugin.cc
@@ -195,6 +195,12 @@ ARDOUR::find_plugin(Session& session, string identifier, PluginType type)
break;
#endif
+#ifdef MACVST_SUPPORT
+ case ARDOUR::MacVST:
+ plugs = mgr.mac_vst_plugin_info();
+ break;
+#endif
+
#ifdef AUDIOUNIT_SUPPORT
case ARDOUR::AudioUnit:
plugs = mgr.au_plugin_info();
diff --git a/libs/ardour/plugin_insert.cc b/libs/ardour/plugin_insert.cc
index 2283f99e4b..d3bbbf0c0d 100644
--- a/libs/ardour/plugin_insert.cc
+++ b/libs/ardour/plugin_insert.cc
@@ -50,6 +50,10 @@
#include "ardour/lxvst_plugin.h"
#endif
+#ifdef MACVST_SUPPORT
+#include "ardour/mac_vst_plugin.h"
+#endif
+
#ifdef AUDIOUNIT_SUPPORT
#include "ardour/audio_unit.h"
#endif
@@ -1242,6 +1246,9 @@ PluginInsert::plugin_factory (boost::shared_ptr<Plugin> other)
#ifdef LXVST_SUPPORT
boost::shared_ptr<LXVSTPlugin> lxvp;
#endif
+#ifdef MACVST_SUPPORT
+ boost::shared_ptr<MacVSTPlugin> mvp;
+#endif
#ifdef AUDIOUNIT_SUPPORT
boost::shared_ptr<AUPlugin> ap;
#endif
@@ -1262,6 +1269,10 @@ PluginInsert::plugin_factory (boost::shared_ptr<Plugin> other)
} else if ((lxvp = boost::dynamic_pointer_cast<LXVSTPlugin> (other)) != 0) {
return boost::shared_ptr<Plugin> (new LXVSTPlugin (*lxvp));
#endif
+#ifdef MACVST_SUPPORT
+ } else if ((mvp = boost::dynamic_pointer_cast<MacVSTPlugin> (other)) != 0) {
+ return boost::shared_ptr<Plugin> (new MacVSTPlugin (*mvp));
+#endif
#ifdef AUDIOUNIT_SUPPORT
} else if ((ap = boost::dynamic_pointer_cast<AUPlugin> (other)) != 0) {
return boost::shared_ptr<Plugin> (new AUPlugin (*ap));
@@ -2373,6 +2384,8 @@ PluginInsert::set_state(const XMLNode& node, int version)
type = ARDOUR::Windows_VST;
} else if (prop->value() == X_("lxvst")) {
type = ARDOUR::LXVST;
+ } else if (prop->value() == X_("mac-vst")) {
+ type = ARDOUR::MacVST;
} else if (prop->value() == X_("audiounit")) {
type = ARDOUR::AudioUnit;
} else if (prop->value() == X_("luaproc")) {
@@ -2403,6 +2416,7 @@ PluginInsert::set_state(const XMLNode& node, int version)
prop = node.property ("id");
}
#endif
+
/* recheck */
if (prop == 0) {
@@ -2429,6 +2443,13 @@ PluginInsert::set_state(const XMLNode& node, int version)
}
#endif
+#ifdef MACVST_SUPPORT
+ if (plugin == 0 && type == ARDOUR::MacVST) {
+ type = ARDOUR::MacVST;
+ plugin = find_plugin (_session, prop->value(), type);
+ }
+#endif
+
if (plugin == 0 && type == ARDOUR::Lua) {
/* unique ID (sha1 of script) was not found,
* load the plugin from the serialized version in the
@@ -2937,7 +2958,7 @@ PluginInsert::add_plugin (boost::shared_ptr<Plugin> plugin)
}
}
}
-#if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT)
+#if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT)
boost::shared_ptr<VSTPlugin> vst = boost::dynamic_pointer_cast<VSTPlugin> (plugin);
if (vst) {
vst->set_insert (this, _plugins.size ());
diff --git a/libs/ardour/plugin_manager.cc b/libs/ardour/plugin_manager.cc
index 23515a2e2e..596acadf6c 100644
--- a/libs/ardour/plugin_manager.cc
+++ b/libs/ardour/plugin_manager.cc
@@ -55,6 +55,14 @@
#include <cstring>
#endif //LXVST_SUPPORT
+#ifdef MACVST_SUPPORT
+#include "ardour/vst_info_file.h"
+#include "ardour/mac_vst_support.h"
+#include "ardour/mac_vst_plugin.h"
+#include "pbd/basename.h"
+#include <cstring>
+#endif //MACVST_SUPPORT
+
#include <glibmm/miscutils.h>
#include <glibmm/pattern.h>
#include <glibmm/fileutils.h>
@@ -118,6 +126,7 @@ PluginManager::instance()
PluginManager::PluginManager ()
: _windows_vst_plugin_info(0)
, _lxvst_plugin_info(0)
+ , _mac_vst_plugin_info(0)
, _ladspa_plugin_info(0)
, _lv2_plugin_info(0)
, _au_plugin_info(0)
@@ -128,7 +137,7 @@ PluginManager::PluginManager ()
char* s;
string lrdf_path;
-#if defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT
+#if defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT
// source-tree (ardev, etc)
PBD::Searchpath vstsp(Glib::build_filename(ARDOUR::ardour_dll_directory(), "fst"));
@@ -183,6 +192,12 @@ PluginManager::PluginManager ()
}
#endif /* Native LinuxVST support*/
+#ifdef MACVST_SUPPORT
+ if (Config->get_use_macvst ()) {
+ add_mac_vst_presets ();
+ }
+#endif
+
if ((s = getenv ("VST_PATH"))) {
windows_vst_path = s;
} else if ((s = getenv ("VST_PLUGINS"))) {
@@ -229,6 +244,7 @@ PluginManager::~PluginManager()
// don't bother, just exit quickly.
delete _windows_vst_plugin_info;
delete _lxvst_plugin_info;
+ delete _mac_vst_plugin_info;
delete _ladspa_plugin_info;
delete _lv2_plugin_info;
delete _au_plugin_info;
@@ -278,7 +294,18 @@ PluginManager::refresh (bool cache_only)
}
#endif //Native linuxVST SUPPORT
-#if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT)
+#ifdef MACVST_SUPPORT
+ if(Config->get_use_macvst ()) {
+ if (cache_only) {
+ BootMessage (_("Scanning Mac VST Plugins"));
+ } else {
+ BootMessage (_("Discovering Mac VST Plugins"));
+ }
+ mac_vst_refresh (cache_only);
+ }
+#endif //Native Mac VST SUPPORT
+
+#if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT)
if (!cache_only) {
string fn = Glib::build_filename (ARDOUR::user_cache_directory(), VST_BLACKLIST);
if (Glib::file_test (fn, Glib::FILE_TEST_EXISTS)) {
@@ -383,7 +410,7 @@ PluginManager::clear_vst_cache ()
#endif
#endif // old cache cleanup
-#if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT)
+#if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT)
{
string dn = Glib::build_filename (ARDOUR::user_cache_directory(), "vst");
vector<string> fsi_files;
@@ -430,7 +457,7 @@ PluginManager::clear_vst_blacklist ()
#endif // old blacklist cleanup
-#if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT)
+#if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT)
{
string fn = Glib::build_filename (ARDOUR::user_cache_directory(), VST_BLACKLIST);
if (Glib::file_test (fn, Glib::FILE_TEST_EXISTS)) {
@@ -539,6 +566,12 @@ PluginManager::add_windows_vst_presets()
}
void
+PluginManager::add_mac_vst_presets()
+{
+ add_presets ("mac-vst");
+}
+
+void
PluginManager::add_lxvst_presets()
{
add_presets ("lxvst");
@@ -813,7 +846,7 @@ PluginManager::windows_vst_discover_from_path (string path, bool cache_only)
info << string_compose (_("--- Windows VST plugins Scan: %1"), path) << endmsg;
}
- find_files_matching_filter (plugin_objects, Config->get_plugin_path_vst(), windows_vst_filter, 0, false, true, true);
+ find_files_matching_filter (plugin_objects, path, windows_vst_filter, 0, false, true, true);
for (x = plugin_objects.begin(); x != plugin_objects.end (); ++x) {
ARDOUR::PluginScanMessage(_("VST"), *x, !cache_only && !cancelled());
@@ -979,6 +1012,112 @@ PluginManager::windows_vst_discover (string path, bool cache_only)
#endif // WINDOWS_VST_SUPPORT
+#ifdef MACVST_SUPPORT
+void
+PluginManager::mac_vst_refresh (bool cache_only)
+{
+ if (_mac_vst_plugin_info) {
+ _mac_vst_plugin_info->clear ();
+ } else {
+ _mac_vst_plugin_info = new ARDOUR::PluginInfoList();
+ }
+
+ mac_vst_discover_from_path ("~/Library/Audio/Plug-Ins/VST:/Library/Audio/Plug-Ins/VST", cache_only);
+}
+
+static bool mac_vst_filter (const string& str, void *)
+{
+ if (!Glib::file_test (str, Glib::FILE_TEST_IS_DIR)) {
+ return false;
+ }
+ string plist = Glib::build_filename (str, "Contents", "Info.plist");
+ if (!Glib::file_test (plist, Glib::FILE_TEST_IS_REGULAR)) {
+ return false;
+ }
+ return str[0] != '.' && str.length() > 4 && strings_equal_ignore_case (".vst", str.substr(str.length() - 4));
+}
+
+int
+PluginManager::mac_vst_discover_from_path (string path, bool cache_only)
+{
+ vector<string> plugin_objects;
+ vector<string>::iterator x;
+
+ find_paths_matching_filter (plugin_objects, path, mac_vst_filter, 0, true, true, false);
+
+ for (x = plugin_objects.begin(); x != plugin_objects.end (); ++x) {
+ ARDOUR::PluginScanMessage(_("MacVST"), *x, !cache_only && !cancelled());
+ mac_vst_discover (*x, cache_only || cancelled());
+ }
+ return 0;
+}
+
+int
+PluginManager::mac_vst_discover (string path, bool cache_only)
+{
+ DEBUG_TRACE (DEBUG::PluginManager, string_compose ("checking apparent MacVST plugin at %1\n", path));
+
+ _cancel_timeout = false;
+
+ vector<VSTInfo*>* finfos = vstfx_get_info_mac (const_cast<char *> (path.c_str()),
+ cache_only ? VST_SCAN_CACHE_ONLY : VST_SCAN_USE_APP);
+
+ if (finfos->empty()) {
+ DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Cannot get Mac VST information from '%1'\n", path));
+ return -1;
+ }
+
+ uint32_t discovered = 0;
+ for (vector<VSTInfo *>::iterator x = finfos->begin(); x != finfos->end(); ++x) {
+ VSTInfo* finfo = *x;
+ char buf[32];
+
+ if (!finfo->canProcessReplacing) {
+ warning << string_compose (_("Mac VST plugin %1 does not support processReplacing, and so cannot be used in %2 at this time"),
+ finfo->name, PROGRAM_NAME)
+ << endl;
+ continue;
+ }
+
+ PluginInfoPtr info (new MacVSTPluginInfo);
+
+ info->name = finfo->name;
+
+ snprintf (buf, sizeof (buf), "%d", finfo->UniqueID);
+ info->unique_id = buf;
+ info->category = "MacVST";
+ info->path = path;
+ info->creator = finfo->creator;
+ info->index = 0;
+ info->n_inputs.set_audio (finfo->numInputs);
+ info->n_outputs.set_audio (finfo->numOutputs);
+ info->n_inputs.set_midi ((finfo->wantMidi&1) ? 1 : 0);
+ info->n_outputs.set_midi ((finfo->wantMidi&2) ? 1 : 0);
+ info->type = ARDOUR::MacVST;
+
+ bool duplicate = false;
+ if (!_mac_vst_plugin_info->empty()) {
+ for (PluginInfoList::iterator i =_mac_vst_plugin_info->begin(); i != _mac_vst_plugin_info->end(); ++i) {
+ if ((info->type == (*i)->type)&&(info->unique_id == (*i)->unique_id)) {
+ warning << "Ignoring duplicate Mac VST plugin " << info->name << "\n";
+ duplicate = true;
+ break;
+ }
+ }
+ }
+
+ if (!duplicate) {
+ _mac_vst_plugin_info->push_back (info);
+ discovered++;
+ }
+ }
+
+ vstfx_free_info_list (finfos);
+ return discovered > 0 ? 0 : -1;
+}
+
+#endif // MAC_VST_SUPPORT
+
#ifdef LXVST_SUPPORT
void
@@ -1137,6 +1276,9 @@ PluginManager::save_statuses ()
case LXVST:
ofs << "LXVST";
break;
+ case MacVST:
+ ofs << "MacVST";
+ break;
case Lua:
ofs << "Lua";
break;
@@ -1267,6 +1409,17 @@ PluginManager::windows_vst_plugin_info ()
}
ARDOUR::PluginInfoList&
+PluginManager::mac_vst_plugin_info ()
+{
+#ifdef MACVST_SUPPORT
+ assert(_mac_vst_plugin_info);
+ return *_mac_vst_plugin_info;
+#else
+ return _empty_plugin_info;
+#endif
+}
+
+ARDOUR::PluginInfoList&
PluginManager::lxvst_plugin_info ()
{
#ifdef LXVST_SUPPORT
diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc
index c15877b28b..c12c971caa 100644
--- a/libs/ardour/route.cc
+++ b/libs/ardour/route.cc
@@ -836,6 +836,7 @@ Route::add_processor_from_xml_2X (const XMLNode& node, int version)
if (prop->value() == "ladspa" || prop->value() == "Ladspa" ||
prop->value() == "lv2" ||
prop->value() == "windows-vst" ||
+ prop->value() == "mac-vst" ||
prop->value() == "lxvst" ||
prop->value() == "audiounit") {
@@ -2759,6 +2760,7 @@ Route::set_processor_state (const XMLNode& node)
} else if (prop->value() == "ladspa" || prop->value() == "Ladspa" ||
prop->value() == "lv2" ||
prop->value() == "windows-vst" ||
+ prop->value() == "mac-vst" ||
prop->value() == "lxvst" ||
prop->value() == "luaproc" ||
prop->value() == "audiounit") {
diff --git a/libs/ardour/vst_info_file.cc b/libs/ardour/vst_info_file.cc
index 80d2f61a2f..dc780975b3 100644
--- a/libs/ardour/vst_info_file.cc
+++ b/libs/ardour/vst_info_file.cc
@@ -49,6 +49,7 @@
#include "ardour/filesystem_paths.h"
#include "ardour/linux_vst_support.h"
+#include "ardour/mac_vst_support.h"
#include "ardour/plugin_types.h"
#include "ardour/vst_info_file.h"
@@ -74,6 +75,10 @@ vstfx_instantiate_and_get_info_fst (const char* dllpath, vector<VSTInfo*> *infos
static bool vstfx_instantiate_and_get_info_lx (const char* dllpath, vector<VSTInfo*> *infos, int uniqueID);
#endif
+#ifdef MACVST_SUPPORT
+static bool vstfx_instantiate_and_get_info_mac (const char* dllpath, vector<VSTInfo*> *infos, int uniqueID);
+#endif
+
/* ID for shell plugins */
static int vstfx_current_loading_id = 0;
@@ -442,6 +447,8 @@ vstfx_infofile_for_read (const char* dllpath)
if (
(slen <= 3 || g_ascii_strcasecmp (&dllpath[slen-3], ".so"))
&&
+ (slen <= 4 || g_ascii_strcasecmp (&dllpath[slen-4], ".vst"))
+ &&
(slen <= 4 || g_ascii_strcasecmp (&dllpath[slen-4], ".dll"))
) {
return 0;
@@ -477,6 +484,8 @@ vstfx_infofile_for_write (const char* dllpath)
if (
(slen <= 3 || g_ascii_strcasecmp (&dllpath[slen-3], ".so"))
&&
+ (slen <= 4 || g_ascii_strcasecmp (&dllpath[slen-4], ".vst"))
+ &&
(slen <= 4 || g_ascii_strcasecmp (&dllpath[slen-4], ".dll"))
) {
return NULL;
@@ -665,6 +674,13 @@ vstfx_parse_vst_state (VSTState* vstfx)
info->ParamNames = (char **) malloc (sizeof (char*)*info->numParams);
info->ParamLabels = (char **) malloc (sizeof (char*)*info->numParams);
+#ifdef __APPLE__
+ if (info->hasEditor) {
+ /* we only support Cocoa UIs (just like Reaper) */
+ info->hasEditor = (plugin->dispatcher (plugin, effCanDo, 0, 0, const_cast<char*> ("hasCockosViewAsConfig"), 0.0f) & 0xffff0000) == 0xbeef0000;
+ }
+#endif
+
for (int i = 0; i < info->numParams; ++i) {
char name[64];
char label[64];
@@ -725,6 +741,11 @@ vstfx_info_from_plugin (const char *dllpath, VSTState* vstfx, vector<VSTInfo *>
vstfx_close (vstfx);
break;
#endif
+#ifdef MACVST_SUPPORT
+ case ARDOUR::MacVST:
+ mac_vst_close (vstfx);
+ break;
+#endif
default:
assert (0);
break;
@@ -747,6 +768,11 @@ vstfx_info_from_plugin (const char *dllpath, VSTState* vstfx, vector<VSTInfo *>
ok = vstfx_instantiate_and_get_info_lx (dllpath, infos, id);
break;
#endif
+#ifdef MACVST_SUPPORT
+ case ARDOUR::MacVST:
+ ok = vstfx_instantiate_and_get_info_mac (dllpath, infos, id);
+ break;
+#endif
default:
ok = false;
break;
@@ -778,6 +804,11 @@ vstfx_info_from_plugin (const char *dllpath, VSTState* vstfx, vector<VSTInfo *>
vstfx_close (vstfx);
break;
#endif
+#ifdef MACVST_SUPPORT
+ case ARDOUR::MacVST:
+ mac_vst_close (vstfx);
+ break;
+#endif
default:
assert (0);
break;
@@ -847,7 +878,35 @@ vstfx_instantiate_and_get_info_fst (
}
#endif
+#ifdef MACVST_SUPPORT
+static bool
+vstfx_instantiate_and_get_info_mac (
+ const char* dllpath, vector<VSTInfo*> *infos, int uniqueID)
+{
+ printf("vstfx_instantiate_and_get_info_mac %s\n", dllpath);
+ VSTHandle* h;
+ VSTState* vstfx;
+ if (!(h = mac_vst_load (dllpath))) {
+ PBD::warning << string_compose (_("Cannot get MacVST information from '%1': load failed."), dllpath) << endmsg;
+ return false;
+ }
+
+ vstfx_current_loading_id = uniqueID;
+
+ if (!(vstfx = mac_vst_instantiate (h, simple_master_callback, 0))) {
+ mac_vst_unload (h);
+ PBD::warning << string_compose (_("Cannot get MacVST information from '%1': instantiation failed."), dllpath) << endmsg;
+ return false;
+ }
+
+ vstfx_current_loading_id = 0;
+ vstfx_info_from_plugin (dllpath, vstfx, infos, ARDOUR::MacVST);
+
+ mac_vst_unload (h);
+ return true;
+}
+#endif
/* *** ERROR LOGGING *** */
#ifndef VST_SCANNER_APP
@@ -994,6 +1053,11 @@ vstfx_get_info (const char* dllpath, enum ARDOUR::PluginType type, enum VSTScanM
ok = vstfx_instantiate_and_get_info_lx (dllpath, infos, 0);
break;
#endif
+#ifdef MACVST_SUPPORT
+ case ARDOUR::MacVST:
+ ok = vstfx_instantiate_and_get_info_mac (dllpath, infos, 0);
+ break;
+#endif
default:
ok = false;
break;
@@ -1038,6 +1102,14 @@ vstfx_get_info_lx (char* dllpath, enum VSTScanMode mode)
}
#endif
+#ifdef MACVST_SUPPORT
+vector<VSTInfo *> *
+vstfx_get_info_mac (char* dllpath, enum VSTScanMode mode)
+{
+ return vstfx_get_info (dllpath, ARDOUR::MacVST, mode);
+}
+#endif
+
#ifdef WINDOWS_VST_SUPPORT
vector<VSTInfo *> *
vstfx_get_info_fst (char* dllpath, enum VSTScanMode mode)
diff --git a/libs/ardour/wscript b/libs/ardour/wscript
index c6821546d2..98dffa0384 100644
--- a/libs/ardour/wscript
+++ b/libs/ardour/wscript
@@ -435,9 +435,13 @@ def build(bld):
obj.source += [ 'lxvst_plugin.cc', 'linux_vst_support.cc' ]
obj.defines += [ 'LXVST_SUPPORT' ]
- if bld.is_defined('WINDOWS_VST_SUPPORT') or bld.is_defined('LXVST_SUPPORT'):
+ if bld.is_defined('WINDOWS_VST_SUPPORT') or bld.is_defined('LXVST_SUPPORT') or bld.is_defined('MACVST_SUPPORT'):
obj.source += [ 'session_vst.cc', 'vst_plugin.cc', 'vst_info_file.cc' ]
+ if bld.is_defined('MACVST_SUPPORT'):
+ obj.source += [ 'mac_vst_plugin.cc', 'mac_vst_support.cc' ]
+ obj.defines += [ 'MACVST_SUPPORT' ]
+
if bld.is_defined('HAVE_COREAUDIO'):
obj.source += [ 'coreaudiosource.cc', 'caimportable.cc' ]
obj.use += ['libappleutility']
diff --git a/libs/fst/scanner.cc b/libs/fst/scanner.cc
index d56bdb168c..1f8a90e7a8 100644
--- a/libs/fst/scanner.cc
+++ b/libs/fst/scanner.cc
@@ -31,6 +31,9 @@
#ifdef LXVST_SUPPORT
#include "../ardour/linux_vst_support.cc"
#endif
+#ifdef MACVST_SUPPORT
+#include "../ardour/mac_vst_support.cc"
+#endif
#include "../ardour/filesystem_paths.cc"
#include "../ardour/directory_names.cc"
@@ -117,6 +120,12 @@ int main (int argc, char **argv) {
infos = vstfx_get_info_fst(dllpath);
}
#endif
+
+#ifdef MACVST_SUPPORT
+ else if (slen > 4 && 0 == g_ascii_strcasecmp (&dllpath[slen-4], ".vst")) {
+ infos = vstfx_get_info_mac(dllpath);
+ }
+#endif
else {
fprintf(stderr, "'%s' is not a supported VST plugin.\n", dllpath);
}
diff --git a/libs/fst/wscript b/libs/fst/wscript
index a987235ec0..465ba65840 100644
--- a/libs/fst/wscript
+++ b/libs/fst/wscript
@@ -42,7 +42,7 @@ def set_winegcc(self):
def build(bld):
VERSION = "%s.%s" % (bld.env['MAJOR'], bld.env['MINOR'])
- if not (bld.is_defined('WINDOWS_VST_SUPPORT') or bld.is_defined('LXVST_SUPPORT')):
+ if not (bld.is_defined('WINDOWS_VST_SUPPORT') or bld.is_defined('LXVST_SUPPORT') or bld.is_defined ('MACVST_SUPPORT')):
return
if bld.is_defined('WINDOWS_VST_SUPPORT') and bld.env['build_target'] != 'mingw':
diff --git a/wscript b/wscript
index a91b4437d7..8beb5ecfb3 100644
--- a/wscript
+++ b/wscript
@@ -880,6 +880,7 @@ def configure(conf):
conf.define ('HAVE_COREAUDIO', 1)
conf.define ('AUDIOUNIT_SUPPORT', 1)
+ conf.define('MACVST_SUPPORT', 1)
conf.define ('TOP_MENUBAR',1)
@@ -1229,6 +1230,7 @@ const char* const ardour_config_info = "\\n\\
write_config_text('Unit tests', conf.env['BUILD_TESTS'])
write_config_text('Mac i386 Architecture', opts.generic)
write_config_text('Mac ppc Architecture', opts.ppc)
+ write_config_text('Mac VST support', conf.is_defined('MACVST_SUPPORT'))
write_config_text('Windows VST support', opts.windows_vst)
write_config_text('Wiimote support', conf.is_defined('BUILD_WIIMOTE'))
write_config_text('Windows key', opts.windows_key)