VST3 skeleton

This commit is contained in:
Robin Gareus 2019-11-03 04:09:57 +01:00
parent 9c5f13f3fa
commit 0ca0b4f335
Signed by: rgareus
GPG Key ID: A090BCE02CF57F04
13 changed files with 506 additions and 1 deletions

View File

@ -56,6 +56,7 @@ public:
const ARDOUR::PluginInfoList& lv2_plugin_info ();
const ARDOUR::PluginInfoList& au_plugin_info ();
const ARDOUR::PluginInfoList& lua_plugin_info ();
const ARDOUR::PluginInfoList& vst3_plugin_info ();
void refresh (bool cache_only = false);
void cancel_plugin_scan();
@ -210,6 +211,7 @@ private:
ARDOUR::PluginInfoList* _windows_vst_plugin_info;
ARDOUR::PluginInfoList* _lxvst_plugin_info;
ARDOUR::PluginInfoList* _mac_vst_plugin_info;
ARDOUR::PluginInfoList* _vst3_plugin_info;
ARDOUR::PluginInfoList* _ladspa_plugin_info;
ARDOUR::PluginInfoList* _lv2_plugin_info;
ARDOUR::PluginInfoList* _au_plugin_info;
@ -238,6 +240,7 @@ private:
void windows_vst_refresh (bool cache_only = false);
void mac_vst_refresh (bool cache_only = false);
void lxvst_refresh (bool cache_only = false);
void vst3_refresh (bool cache_only = false);
void add_lrdf_data (const std::string &path);
void add_ladspa_presets ();
@ -256,6 +259,9 @@ private:
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 vst3_discover_from_path (std::string const& path, bool cache_only = false);
int vst3_discover (std::string const& 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);

View File

@ -29,6 +29,7 @@ namespace ARDOUR {
LXVST,
MacVST,
Lua,
VST3,
};
}

View File

@ -0,0 +1,96 @@
/*
* Copyright (C) 2019 Robin Gareus <robin@gareus.org>
*
* 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 of the License, 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_vst3_plugin_h_
#define _ardour_vst3_plugin_h_
#include "pbd/signals.h"
#include "vst3/vst3.h"
#include "ardour/plugin.h"
namespace ARDOUR {
class LIBARDOUR_API VST3Plugin : public ARDOUR::Plugin
{
public:
VST3Plugin (AudioEngine&, Session&, std::string const&);
VST3Plugin (const VST3Plugin&);
~VST3Plugin ();
std::string unique_id () const { return get_info ()->unique_id; }
const char* name () const { return get_info ()->name.c_str (); }
const char* label () const { return get_info ()->name.c_str (); }
const char* maker () const { return get_info ()->creator.c_str (); }
uint32_t parameter_count () const;
float default_value (uint32_t port);
void set_parameter (uint32_t port, float val);
float get_parameter (uint32_t port) const;
int get_parameter_descriptor (uint32_t which, ParameterDescriptor&) const;
uint32_t nth_parameter (uint32_t port, bool& ok) const;
bool parameter_is_audio (uint32_t) const;
bool parameter_is_control (uint32_t) const;
bool parameter_is_input (uint32_t) const;
bool parameter_is_output (uint32_t) const;
std::set<Evoral::Parameter> automatable () const;
std::string describe_parameter (Evoral::Parameter);
std::string state_node_name () const { return "vst3"; }
void add_state (XMLNode*) const;
int set_state (const XMLNode&, int version);
bool load_preset (PresetRecord);
std::string do_save_preset (std::string);
void do_remove_preset (std::string);
void activate ();
void deactivate ();
void cleanup ();
int set_block_size (pframes_t);
int connect_and_run (BufferSet& bufs,
samplepos_t start, samplepos_t end, double speed,
ChanMapping const& in, ChanMapping const& out,
pframes_t nframes, samplecnt_t offset);
bool has_editor () const;
bool configure_io (ChanCount in, ChanCount out);
private:
samplecnt_t plugin_latency () const;
void find_presets ();
};
class LIBARDOUR_API VST3PluginInfo : public PluginInfo
{
public:
VST3PluginInfo ();
~VST3PluginInfo (){};
PluginPtr load (Session& session);
std::vector<Plugin::PresetRecord> get_presets (bool user_only) const;
};
} // namespace ARDOUR
#endif

View File

@ -413,6 +413,7 @@ setup_enum_writer ()
REGISTER_ENUM (LXVST);
REGISTER_ENUM (MacVST);
REGISTER_ENUM (Lua);
REGISTER_ENUM (VST3);
REGISTER (_PluginType);
REGISTER_ENUM (MTC);

View File

@ -125,6 +125,9 @@ ARDOUR::LuaAPI::list_plugins ()
#ifdef LXVST_SUPPORT
all_plugs.insert (all_plugs.end (), manager.lxvst_plugin_info ().begin (), manager.lxvst_plugin_info ().end ());
#endif
#ifdef VST3_SUPPORT
all_plugs.insert (all_plugs.end (), manager.vst3_plugin_info ().begin (), manager.vst3_plugin_info ().end ());
#endif
#ifdef AUDIOUNIT_SUPPORT
all_plugs.insert (all_plugs.end (), manager.au_plugin_info ().begin (), manager.au_plugin_info ().end ());
#endif
@ -150,6 +153,9 @@ ARDOUR::LuaAPI::new_plugin_info (const string& name, ARDOUR::PluginType type)
#ifdef LXVST_SUPPORT
all_plugs.insert (all_plugs.end (), manager.lxvst_plugin_info ().begin (), manager.lxvst_plugin_info ().end ());
#endif
#ifdef VST3_SUPPORT
all_plugs.insert (all_plugs.end (), manager.vst3_plugin_info ().begin (), manager.vst3_plugin_info ().end ());
#endif
#ifdef AUDIOUNIT_SUPPORT
all_plugs.insert (all_plugs.end (), manager.au_plugin_info ().begin (), manager.au_plugin_info ().end ());
#endif

View File

@ -1896,6 +1896,7 @@ LuaBindings::common (lua_State* L)
.addConst ("LXVST", ARDOUR::PluginType(LXVST))
.addConst ("MacVST", ARDOUR::PluginType(MacVST))
.addConst ("Lua", ARDOUR::PluginType(Lua))
.addConst ("VST3", ARDOUR::PluginType(VST3))
.endNamespace ()
.beginNamespace ("PresentationInfo")

View File

@ -234,6 +234,12 @@ ARDOUR::find_plugin(Session& session, string identifier, PluginType type)
break;
#endif
#ifdef VST3_SUPPORT
case ARDOUR::VST3:
plugs = mgr.vst3_plugin_info();
break;
#endif
#ifdef AUDIOUNIT_SUPPORT
case ARDOUR::AudioUnit:
plugs = mgr.au_plugin_info();

View File

@ -56,6 +56,10 @@
#include "ardour/mac_vst_plugin.h"
#endif
#ifdef VST3_SUPPORT
#include "ardour/vst3_plugin.h"
#endif
#ifdef AUDIOUNIT_SUPPORT
#include "ardour/audio_unit.h"
#endif
@ -539,6 +543,7 @@ PluginInsert::create_automatable_parameters ()
}
if (_bypass_port != UINT32_MAX) {
_inverted_bypass_enable = type () == VST3;
boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter (PluginAutomation, 0, _bypass_port));
if (0 == (ac->flags () & Controllable::NotAutomatable)) {
ac->alist()->automation_state_changed.connect_same_thread (*this, boost::bind (&PluginInsert::bypassable_changed, this));
@ -1441,6 +1446,9 @@ PluginInsert::plugin_factory (boost::shared_ptr<Plugin> other)
#ifdef MACVST_SUPPORT
boost::shared_ptr<MacVSTPlugin> mvp;
#endif
#ifdef VST3_SUPPORT
boost::shared_ptr<VST3Plugin> vst3;
#endif
#ifdef AUDIOUNIT_SUPPORT
boost::shared_ptr<AUPlugin> ap;
#endif
@ -1463,6 +1471,10 @@ PluginInsert::plugin_factory (boost::shared_ptr<Plugin> other)
} else if ((mvp = boost::dynamic_pointer_cast<MacVSTPlugin> (other)) != 0) {
return boost::shared_ptr<Plugin> (new MacVSTPlugin (*mvp));
#endif
#ifdef VST3_SUPPORT
} else if ((vst3 = boost::dynamic_pointer_cast<VST3Plugin> (other)) != 0) {
return boost::shared_ptr<Plugin> (new VST3Plugin (*vst3));
#endif
#ifdef AUDIOUNIT_SUPPORT
} else if ((ap = boost::dynamic_pointer_cast<AUPlugin> (other)) != 0) {
return boost::shared_ptr<Plugin> (new AUPlugin (*ap));
@ -2616,6 +2628,8 @@ PluginInsert::set_state(const XMLNode& node, int version)
type = ARDOUR::AudioUnit;
} else if (str == X_("luaproc")) {
type = ARDOUR::Lua;
} else if (str == X_("vst3")) {
type = ARDOUR::VST3;
} else {
error << string_compose (_("unknown plugin type %1 in plugin insert state"), str) << endmsg;
return -1;

View File

@ -40,6 +40,12 @@
#include <lrdf.h>
#endif
#if defined PLATFORM_WINDOWS && defined VST3_SUPPORT
#include <windows.h>
#include <shlobj.h> // CSIDL_*
#include "pbd/windows_special_dirs.h"
#endif
#ifdef WINDOWS_VST_SUPPORT
#include "ardour/vst_info_file.h"
#include "fst.h"
@ -108,6 +114,10 @@
#include <Carbon/Carbon.h>
#endif
#ifdef VST3_SUPPORT
#include "ardour/vst3_plugin.h"
#endif
#include "pbd/error.h"
#include "pbd/stl_delete.h"
@ -135,6 +145,7 @@ PluginManager::PluginManager ()
: _windows_vst_plugin_info(0)
, _lxvst_plugin_info(0)
, _mac_vst_plugin_info(0)
, _vst3_plugin_info(0)
, _ladspa_plugin_info(0)
, _lv2_plugin_info(0)
, _au_plugin_info(0)
@ -255,6 +266,7 @@ PluginManager::~PluginManager()
delete _windows_vst_plugin_info;
delete _lxvst_plugin_info;
delete _mac_vst_plugin_info;
delete _vst3_plugin_info;
delete _ladspa_plugin_info;
delete _lv2_plugin_info;
delete _au_plugin_info;
@ -430,6 +442,15 @@ PluginManager::refresh (bool cache_only)
}
#endif
#ifdef VST3_SUPPORT
if (cache_only) {
BootMessage (_("Scanning VST3 Plugins"));
} else {
BootMessage (_("Discovering VST3 Plugins"));
}
vst3_refresh (cache_only);
#endif
#ifdef AUDIOUNIT_SUPPORT
if (cache_only) {
BootMessage (_("Scanning AU Plugins"));
@ -453,6 +474,7 @@ PluginManager::refresh (bool cache_only)
detect_name_ambiguities (_ladspa_plugin_info);
detect_name_ambiguities (_lv2_plugin_info);
detect_name_ambiguities (_lua_plugin_info);
detect_name_ambiguities (_vst3_plugin_info);
PluginInfoList all_plugs;
if (_windows_vst_plugin_info) {
@ -464,6 +486,9 @@ PluginManager::refresh (bool cache_only)
if (_mac_vst_plugin_info) {
all_plugs.insert(all_plugs.end(), _mac_vst_plugin_info->begin(), _mac_vst_plugin_info->end());
}
if (_vst3_plugin_info) {
all_plugs.insert(all_plugs.end(), _vst3_plugin_info->begin(), _vst3_plugin_info->end());
}
if (_au_plugin_info) {
all_plugs.insert(all_plugs.end(), _au_plugin_info->begin(), _au_plugin_info->end());
}
@ -1420,6 +1445,107 @@ PluginManager::lxvst_discover (string path, bool cache_only)
#endif // LXVST_SUPPORT
#ifdef VST3_SUPPORT
void
PluginManager::vst3_refresh (bool cache_only)
{
if (_vst3_plugin_info) {
_vst3_plugin_info->clear ();
} else {
_vst3_plugin_info = new ARDOUR::PluginInfoList();
}
#ifdef __APPLE__
vst3_discover_from_path ("~/Library/Audio/Plug-Ins/VST3:/Library/Audio/Plug-Ins/VST3", cache_only);
#elif defined PLATFORM_WINDOWS
std::string prog = PBD::get_win_special_folder_path (CSIDL_PROGRAM_FILES);
vst3_discover_from_path (Glib::build_filename (prog, "Common Files", "VST3"), cache_only);
#else
vst3_discover_from_path ("~/.vst3:/usr/local/lib/vst3:/usr/lib/vst3", cache_only);
#endif
}
static bool vst3_filter (const string& str, void*)
{
return str[0] != '.' && (str.length() > 4 && str.find (".vst3") == (str.length() - 5));
}
int
PluginManager::vst3_discover_from_path (string const& path, bool cache_only)
{
if (Session::get_disable_all_loaded_plugins ()) {
info << _("Disabled VST3 scan (safe mode)") << endmsg;
return -1;
}
DEBUG_TRACE (DEBUG::PluginManager, string_compose ("VST3: search along: [%1]\n", path));
Searchpath paths (path);
vector<string> plugin_objects;
find_paths_matching_filter (plugin_objects, paths, vst3_filter, 0, false, true, true);
for (vector<string>::iterator i = plugin_objects.begin(); i != plugin_objects.end (); ++i) {
ARDOUR::PluginScanMessage(_("VST3"), *i, !(cache_only || cancelled()));
vst3_discover (*i, cache_only || cancelled ());
}
return cancelled() ? -1 : 0;
}
static std::string vst3_bindir () {
#ifdef __APPLE__
return "MacOS";
#elif defined PLATFORM_WINDOWS
# if defined __x86_64__ || defined _M_X64
return "x86_64-win";
# else
return "x86-win";
# endif
#else // Linux
# if defined __x86_64__ || defined _M_X64
return "x86_64-linux";
# elif defined __i386__ || defined _M_IX86
return "i386-linux";
#endif
// ARM, PPC ?
#endif
return "";
}
static std::string vst3_suffix () {
#ifdef __APPLE__
return "";
#elif defined PLATFORM_WINDOWS
return ".vst3";
#else // Linux
return ".so";
#endif
}
int
PluginManager::vst3_discover (string const& path, bool cache_only)
{
string module_path;
if (!Glib::file_test (path, Glib::FILE_TEST_IS_DIR)) {
module_path = path;
} else {
module_path = Glib::build_filename (path, "Contents",
vst3_bindir (), basename_nosuffix (path) + vst3_suffix ());
}
if (!Glib::file_test (module_path, Glib::FILE_TEST_IS_REGULAR)) {
cerr << "VST3 not a valid bundle: '" << module_path << "'\n";
return -1;
}
ARDOUR::PluginScanMessage(_("VST3"), module_path, !(cache_only || cancelled()));
DEBUG_TRACE (DEBUG::PluginManager, string_compose ("VST3: discover %1 (%2)\n", path, module_path));
return 0;
}
#endif // VST3_SUPPORT
PluginManager::PluginStatusType
PluginManager::get_status (const PluginInfoPtr& pi) const
@ -1462,6 +1588,9 @@ PluginManager::save_statuses ()
case MacVST:
ofs << "MacVST";
break;
case VST3:
ofs << "VST3";
break;
case Lua:
ofs << "Lua";
break;
@ -1558,6 +1687,8 @@ PluginManager::load_statuses ()
type = MacVST;
} else if (stype == "Lua") {
type = Lua;
} else if (stype == "VST3") {
type = VST3;
} else {
error << string_compose (_("unknown plugin type \"%1\" - ignored"), stype)
<< endmsg;
@ -2094,6 +2225,17 @@ PluginManager::au_plugin_info ()
return _empty_plugin_info;
}
const ARDOUR::PluginInfoList&
PluginManager::vst3_plugin_info ()
{
#ifdef VST3_SUPPORT
if (_vst3_plugin_info) {
return *_vst3_plugin_info;
}
#endif
return _empty_plugin_info;
}
const ARDOUR::PluginInfoList&
PluginManager::lua_plugin_info ()
{

View File

@ -3188,6 +3188,7 @@ Route::set_processor_state (XMLNode const& node, int version, XMLProperty const*
prop->value() == "mac-vst" ||
prop->value() == "lxvst" ||
prop->value() == "luaproc" ||
prop->value() == "vst3" ||
prop->value() == "audiounit") {
if (_session.get_disable_all_loaded_plugins ()) {

219
libs/ardour/vst3_plugin.cc Normal file
View File

@ -0,0 +1,219 @@
/*
* Copyright (C) 2019 Robin Gareus <robin@gareus.org>
*
* 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 of the License, 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 "pbd/error.h"
#include "ardour/vst3_plugin.h"
#include "pbd/i18n.h"
using namespace PBD;
using namespace ARDOUR;
VST3Plugin::VST3Plugin (AudioEngine& engine, Session& session, std::string const&)
: Plugin (engine, session)
{
}
VST3Plugin::VST3Plugin (const VST3Plugin& other)
: Plugin (other)
{
}
VST3Plugin::~VST3Plugin ()
{
}
uint32_t
VST3Plugin::parameter_count () const
{
return 0;
}
float
VST3Plugin::default_value (uint32_t port)
{
return 0;
}
void
VST3Plugin::set_parameter (uint32_t port, float val)
{
}
float
VST3Plugin::get_parameter (uint32_t port) const
{
return 0.f;
}
int
VST3Plugin::get_parameter_descriptor (uint32_t port, ParameterDescriptor& desc) const
{
return 0;
}
uint32_t
VST3Plugin::nth_parameter (uint32_t port, bool& ok) const
{
ok = false;
return 0;
}
bool
VST3Plugin::parameter_is_audio (uint32_t port) const
{
return false;
}
bool
VST3Plugin::parameter_is_control (uint32_t port) const
{
return false;
}
bool
VST3Plugin::parameter_is_input (uint32_t port) const
{
return false;
}
bool
VST3Plugin::parameter_is_output (uint32_t port) const
{
return false;
}
std::set<Evoral::Parameter>
VST3Plugin::automatable () const
{
std::set<Evoral::Parameter> automatables;
return automatables;
}
std::string
VST3Plugin::describe_parameter (Evoral::Parameter param)
{
return "??";
}
bool
VST3Plugin::has_editor () const
{
return false;
}
/* ****************************************************************************/
void
VST3Plugin::add_state (XMLNode* root) const
{
}
int
VST3Plugin::set_state (const XMLNode& node, int version)
{
return Plugin::set_state (node, version);
}
/* ****************************************************************************/
int
VST3Plugin::set_block_size (pframes_t)
{
return 0;
}
samplecnt_t
VST3Plugin::plugin_latency () const
{
return 0;
}
void
VST3Plugin::activate ()
{
}
void
VST3Plugin::deactivate ()
{
}
void
VST3Plugin::cleanup ()
{
}
bool
VST3Plugin::configure_io (ChanCount in, ChanCount out)
{
return Plugin::configure_io (in, out);
}
int
VST3Plugin::connect_and_run (BufferSet& bufs,
samplepos_t start, samplepos_t end, double speed,
ChanMapping const& in_map, ChanMapping const& out_map,
pframes_t nframes, samplecnt_t offset)
{
return 0;
}
/* ****************************************************************************/
bool
VST3Plugin::load_preset (PresetRecord r)
{
return false;
}
std::string
VST3Plugin::do_save_preset (std::string name)
{
return "";
}
void
VST3Plugin::do_remove_preset (std::string name)
{
}
void
VST3Plugin::find_presets ()
{
}
/* ****************************************************************************/
VST3PluginInfo::VST3PluginInfo ()
{
type = ARDOUR::VST3;
}
PluginPtr
VST3PluginInfo::load (Session& session)
{
return PluginPtr ();
}
std::vector<Plugin::PresetRecord>
VST3PluginInfo::get_presets (bool /*user_only*/) const
{
std::vector<Plugin::PresetRecord> p;
return p;
}

View File

@ -397,7 +397,7 @@ def build(bld):
obj.defines = []
obj.export_includes = ['.']
obj.includes = ['.', '../surfaces/control_protocol', '..']
obj.includes = ['.', '../vst3/', '../surfaces/control_protocol', '..']
obj.name = 'libardour'
obj.target = 'ardour'
obj.uselib = ['GLIBMM','GTHREAD','AUBIO','SIGCPP','XML','UUID', 'LO',
@ -459,6 +459,10 @@ def build(bld):
obj.source += [ 'mac_vst_plugin.cc', 'mac_vst_support.cc' ]
obj.defines += [ 'MACVST_SUPPORT' ]
if bld.is_defined('VST3_SUPPORT'):
obj.source += [ 'vst3_plugin.cc' ]
obj.defines += [ 'VST3_SUPPORT' ]
if bld.is_defined('HAVE_COREAUDIO'):
obj.source += [ 'coreaudiosource.cc', 'caimportable.cc' ]
obj.use += ['libappleutility']

View File

@ -806,6 +806,10 @@ def options(opt):
help='Compile with support for linuxVST plugins')
opt.add_option('--no-lxvst', action='store_false', dest='lxvst',
help='Compile without support for linuxVST plugins')
opt.add_option('--vst3', action='store_true', default=True, dest='vst3',
help='Compile with support for VST3 plugins')
opt.add_option('--no-vst3', action='store_false', dest='vst3',
help='Compile without support for VST3 plugins')
opt.add_option('--no-lrdf', action='store_true', dest='no_lrdf',
help='Compile without support for LRDF LADSPA data even if present')
opt.add_option('--nls', action='store_true', default=True, dest='nls',
@ -1244,6 +1248,9 @@ int main () { return 0; }
else:
conf.define('LXVST_SUPPORT', 1)
conf.env['LXVST_SUPPORT'] = True
if opts.vst3:
conf.define('VST3_SUPPORT', 1)
conf.env['VST3_SUPPORT'] = True
conf.env['WINDOWS_KEY'] = opts.windows_key
if opts.rt_alloc_debug:
conf.define('DEBUG_RT_ALLOC', 1)
@ -1424,6 +1431,7 @@ const char* const ardour_config_info = "\\n\\
# write_config_text('Tranzport', opts.tranzport)
write_config_text('Unit tests', conf.env['BUILD_TESTS'])
write_config_text('Use LLD linker', opts.use_lld)
write_config_text('VST3 support', conf.is_defined('VST3_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)