Mac VST-2.x support
authorRobin Gareus <robin@gareus.org>
Sun, 13 Nov 2016 15:31:15 +0000 (16:31 +0100)
committerRobin Gareus <robin@gareus.org>
Sun, 13 Nov 2016 15:35:06 +0000 (16:35 +0100)
20 files changed:
libs/ardour/ardour/buffer_set.h
libs/ardour/ardour/mac_vst_plugin.h [new file with mode: 0644]
libs/ardour/ardour/mac_vst_support.h [new file with mode: 0644]
libs/ardour/ardour/plugin_manager.h
libs/ardour/ardour/plugin_types.h
libs/ardour/ardour/rc_configuration_vars.h
libs/ardour/ardour/vst_info_file.h
libs/ardour/ardour/vst_types.h
libs/ardour/buffer_set.cc
libs/ardour/mac_vst_plugin.cc [new file with mode: 0644]
libs/ardour/mac_vst_support.cc [new file with mode: 0644]
libs/ardour/plugin.cc
libs/ardour/plugin_insert.cc
libs/ardour/plugin_manager.cc
libs/ardour/route.cc
libs/ardour/vst_info_file.cc
libs/ardour/wscript
libs/fst/scanner.cc
libs/fst/wscript
wscript

index 9ea6ab7d6ad1d3620d347fb4eea78971d53fb481..f1b632e6e286447c32952de6f51b7e5da196da12 100644 (file)
@@ -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 (file)
index 0000000..e5afab5
--- /dev/null
@@ -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 (file)
index 0000000..8a23960
--- /dev/null
@@ -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__ */
index 1a925432a08a1dfc5a6aa35ae439f250d2f31706..9de951dc23c1cc14cd154b5782ef34d8163221a5 100644 (file)
@@ -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);
 
index d997e2891a0ca4e397ce2693cf4d2dd9acd6f79a..3c37befc408a80c97d9ad7e0caafc7af94102d24 100644 (file)
@@ -28,6 +28,7 @@ namespace ARDOUR {
                LV2,
                Windows_VST,
                LXVST,
+               MacVST,
                Lua,
        };
 
index 62a15a3fe26d2b7931f8b28cddbf7de3f4523362..79db43a9022b38080fb3a2ad40b2e2144d32609a 100644 (file)
@@ -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 */
index f253ab0b4b784beed5e255b1de18ed7f415605a5..b9567dec9fd0b9d7ef623f01cf4823b8d344153b 100644 (file)
@@ -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
index aa6432876eabea442edca5dae51bed4d50dd28a7..b9c62e4fe1711af193b91e2de4d27c8d5127e76d 100644 (file)
@@ -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;
index 66564f3202937dbf4460bfb7c8f21266c47aff95..982725f491e6de9f4bcf5fb0202b3c2b7a641e70 100644 (file)
@@ -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 (file)
index 0000000..08c39b1
--- /dev/null
@@ -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 (file)
index 0000000..42eb3f7
--- /dev/null
@@ -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
index f76f96af7a2183e17da49c911f7255e2d722213d..d21ecfe632f4d2849f7451d0a2ac9cf168ab98d4 100644 (file)
@@ -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();
index 2283f99e4bf0a4cf045e8590808277ae1efdfd02..d3bbbf0c0ddcfac3b92152e30da17e97cd0b1fac 100644 (file)
 #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 ());
index 23515a2e2e67867556cc4e167501358408fab5db..596acadf6cd24af8c20c17fda788d6f7d6c7e641 100644 (file)
 #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)) {
@@ -538,6 +565,12 @@ PluginManager::add_windows_vst_presets()
        add_presets ("windows-vst");
 }
 
+void
+PluginManager::add_mac_vst_presets()
+{
+       add_presets ("mac-vst");
+}
+
 void
 PluginManager::add_lxvst_presets()
 {
@@ -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;
@@ -1266,6 +1408,17 @@ PluginManager::windows_vst_plugin_info ()
 #endif
 }
 
+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 ()
 {
index c15877b28b176aa20507080b064d9699ce26efa0..c12c971caaeebdaf1a5a2c0c1ac053a2567bf34c 100644 (file)
@@ -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") {
index 80d2f61a2f29faab78e2cb444d02c362a8426635..dc780975b349f42717b9f7085d98c0d43ef04b95 100644 (file)
@@ -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];
@@ -724,6 +740,11 @@ vstfx_info_from_plugin (const char *dllpath, VSTState* vstfx, vector<VSTInfo *>
                        case ARDOUR::LXVST:
                                vstfx_close (vstfx);
                                break;
+#endif
+#ifdef MACVST_SUPPORT
+                       case ARDOUR::MacVST:
+                               mac_vst_close (vstfx);
+                               break;
 #endif
                        default:
                                assert (0);
@@ -746,6 +767,11 @@ vstfx_info_from_plugin (const char *dllpath, VSTState* vstfx, vector<VSTInfo *>
                                case ARDOUR::LXVST:
                                        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;
@@ -777,6 +803,11 @@ vstfx_info_from_plugin (const char *dllpath, VSTState* vstfx, vector<VSTInfo *>
                        case ARDOUR::LXVST:
                                vstfx_close (vstfx);
                                break;
+#endif
+#ifdef MACVST_SUPPORT
+                       case ARDOUR::MacVST:
+                               mac_vst_close (vstfx);
+                               break;
 #endif
                        default:
                                assert (0);
@@ -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
@@ -993,6 +1052,11 @@ vstfx_get_info (const char* dllpath, enum ARDOUR::PluginType type, enum VSTScanM
                case ARDOUR::LXVST:
                        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;
@@ -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)
index c6821546d2d816ca15b7d69deaac2174492c7b8c..98dffa0384c7bce4cd8a10294dd3b37dd4e529dd 100644 (file)
@@ -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']
index d56bdb168c5ce1b5b403392ef0ce43818078dfdb..1f8a90e7a834e3cb56e0d43919ba89d938f9d2fc 100644 (file)
@@ -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);
        }
index a987235ec00a07a8f048269abfac35cdb214860d..465ba65840ade6a35ed5de8ed623930a15a91a37 100644 (file)
@@ -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 a91b4437d783690b03b4e07d44f08604cab5eedf..8beb5ecfb37b0a7048516906bb726ba0bde93ed1 100644 (file)
--- 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)