X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Fplugin.cc;h=9bbe21aabf652ebe6d300979636c85cdaba7f92f;hb=db6706429643d80e68a050daa015d17f36d5321b;hp=8d200b0ee413b30a273de56d59d90e81335bd72e;hpb=017e16c530bb1a9f186aa81893089dc79b4ddc24;p=ardour.git diff --git a/libs/ardour/plugin.cc b/libs/ardour/plugin.cc index 8d200b0ee4..9bbe21aabf 100644 --- a/libs/ardour/plugin.cc +++ b/libs/ardour/plugin.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2000-2002 Paul Davis + Copyright (C) 2000-2002 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 @@ -15,9 +15,12 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ +#ifdef WAF_BUILD +#include "libardour-config.h" +#endif + #include #include @@ -27,166 +30,125 @@ #include #include #include +#include #include -#include -#include -#include -#include +#include "pbd/compose.h" +#include "pbd/error.h" +#include "pbd/xml++.h" + +#include "ardour/ardour.h" +#include "ardour/session.h" +#include "ardour/audioengine.h" +#include "ardour/plugin.h" +#include "ardour/ladspa_plugin.h" +#include "ardour/plugin_manager.h" + +#ifdef HAVE_AUDIOUNITS +#include "ardour/audio_unit.h" +#endif -#include -#include -#include -#include -#include -#include +#ifdef HAVE_SLV2 +#include "ardour/lv2_plugin.h" +#endif -#include +#include "pbd/stl_delete.h" #include "i18n.h" #include +using namespace std; using namespace ARDOUR; using namespace PBD; Plugin::Plugin (AudioEngine& e, Session& s) - : _engine (e), _session (s) + : _engine (e) + , _session (s) + , _cycles (0) { } Plugin::Plugin (const Plugin& other) - : _engine (other._engine), _session (other._session), _info (other._info) + : StatefulDestructible() + , Latent() + , _engine (other._engine) + , _session (other._session) + , _info (other._info) + , _cycles (0) + , presets (other.presets) { } -void -Plugin::setup_controls () +Plugin::~Plugin () { - uint32_t port_cnt = parameter_count(); - - /* set up a vector of null pointers for the controls. - we'll fill this in on an as-needed basis. - */ - - for (uint32_t i = 0; i < port_cnt; ++i) { - controls.push_back (0); - } } -Plugin::~Plugin () +const Plugin::PresetRecord* +Plugin::preset_by_label(const string& label) { - for (vector::iterator i = controls.begin(); i != controls.end(); ++i) { - if (*i) { - delete *i; + // FIXME: O(n) + for (map::const_iterator i = presets.begin(); i != presets.end(); ++i) { + if (i->second.label == label) { + return &i->second; } } + return NULL; } -Controllable * -Plugin::get_nth_control (uint32_t n) +const Plugin::PresetRecord* +Plugin::preset_by_uri(const string& uri) { - if (n >= parameter_count()) { - return 0; + map::const_iterator pr = presets.find(uri); + if (pr != presets.end()) { + return &pr->second; + } else { + return NULL; } - - if (controls[n] == 0) { - - Plugin::ParameterDescriptor desc; - - get_parameter_descriptor (n, desc); - - controls[n] = new PortControllable (*this, n, desc.lower, desc.upper, desc.toggled, desc.logarithmic); - } - - return controls[n]; -} - -Plugin::PortControllable::PortControllable (Plugin& p, uint32_t port_id, float low, float up, bool t, bool loga) - : plugin (p), absolute_port (port_id) -{ - toggled = t; - logarithmic = loga; - lower = low; - upper = up; - range = upper - lower; } -void -Plugin::PortControllable::set_value (float value) +vector +Plugin::get_presets() { - if (toggled) { - if (value > 0.5) { - value = 1.0; - } else { - value = 0.0; - } - } else { + vector result; + uint32_t id; + std::string unique (unique_id()); - if (!logarithmic) { - value = lower + (range * value); - } else { - float _lower = 0.0f; - if (lower > 0.0f) { - _lower = log(lower); - } + /* XXX problem: AU plugins don't have numeric ID's. + Solution: they have a different method of providing presets. + XXX sub-problem: implement it. + */ - value = exp(_lower + log(range) * value); - } + if (!isdigit (unique[0])) { + return result; } - plugin.set_parameter (absolute_port, value); -} + id = atol (unique.c_str()); -float -Plugin::PortControllable::get_value (void) const -{ - float val = plugin.get_parameter (absolute_port); - - if (toggled) { - - return val; - - } else { - - if (logarithmic) { - val = log(val); - } - - return ((val - lower) / range); - } -} - -vector -Plugin::get_presets() -{ - vector labels; - lrdf_uris* set_uris = lrdf_get_setting_uris(unique_id()); + lrdf_uris* set_uris = lrdf_get_setting_uris(id); if (set_uris) { for (uint32_t i = 0; i < (uint32_t) set_uris->count; ++i) { if (char* label = lrdf_get_label(set_uris->items[i])) { - labels.push_back(label); - presets[label] = set_uris->items[i]; + PresetRecord rec(set_uris->items[i], label); + result.push_back(rec); + presets.insert(std::make_pair(set_uris->items[i], rec)); } } lrdf_free_uris(set_uris); } - // GTK2FIX find an equivalent way to do this with a vector (needed by GUI apis) - // labels.unique(); - - return labels; + return result; } bool -Plugin::load_preset(const string preset_label) +Plugin::load_preset(const string& preset_uri) { - lrdf_defaults* defs = lrdf_get_setting_values(presets[preset_label].c_str()); + lrdf_defaults* defs = lrdf_get_setting_values(preset_uri.c_str()); if (defs) { for (uint32_t i = 0; i < (uint32_t) defs->count; ++i) { - // The defs->items[i].pid < defs->count check is to work around + // The defs->items[i].pid < defs->count check is to work around // a bug in liblrdf that saves invalid values into the presets file. if (((uint32_t) defs->items[i].pid < (uint32_t) defs->count) && parameter_is_input (defs->items[i].pid)) { set_parameter(defs->items[i].pid, defs->items[i].value); @@ -203,6 +165,20 @@ Plugin::save_preset (string name, string domain) { lrdf_portvalue portvalues[parameter_count()]; lrdf_defaults defaults; + uint32_t id; + std::string unique (unique_id()); + + /* XXX problem: AU plugins don't have numeric ID's. + Solution: they have a different method of providing/saving presets. + XXX sub-problem: implement it. + */ + + if (!isdigit (unique[0])) { + return false; + } + + id = atol (unique.c_str()); + defaults.count = parameter_count(); defaults.items = portvalues; @@ -218,23 +194,28 @@ Plugin::save_preset (string name, string domain) warning << _("Could not locate HOME. Preset not saved.") << endmsg; return false; } - + string source(string_compose("file:%1/.%2/rdf/ardour-presets.n3", envvar, domain)); - free(lrdf_add_preset(source.c_str(), name.c_str(), unique_id(), &defaults)); + char* uri = lrdf_add_preset (source.c_str(), name.c_str(), id, &defaults); + + /* XXX: why is the uri apparently kept as the key in the `presets' map and also in the PresetRecord? */ + + presets.insert (make_pair (uri, PresetRecord (uri, name))); + free (uri); string path = string_compose("%1/.%2", envvar, domain); - if (mkdir(path.c_str(), 0775) && errno != EEXIST) { + if (g_mkdir_with_parents (path.c_str(), 0775)) { warning << string_compose(_("Could not create %1. Preset not saved. (%2)"), path, strerror(errno)) << endmsg; return false; } - + path += "/rdf"; - if (mkdir(path.c_str(), 0775) && errno != EEXIST) { + if (g_mkdir_with_parents (path.c_str(), 0775)) { warning << string_compose(_("Could not create %1. Preset not saved. (%2)"), path, strerror(errno)) << endmsg; return false; } - + if (lrdf_export_by_source(source.c_str(), source.substr(5).c_str())) { warning << string_compose(_("Error saving presets file %1."), source) << endmsg; return false; @@ -244,7 +225,7 @@ Plugin::save_preset (string name, string domain) } PluginPtr -ARDOUR::find_plugin(Session& session, string name, long unique_id, PluginType type) +ARDOUR::find_plugin(Session& session, string identifier, PluginType type) { PluginManager *mgr = PluginManager::the_manager(); PluginInfoList plugs; @@ -254,17 +235,21 @@ ARDOUR::find_plugin(Session& session, string name, long unique_id, PluginType ty plugs = mgr->ladspa_plugin_info(); break; +#ifdef HAVE_SLV2 + case ARDOUR::LV2: + plugs = mgr->lv2_plugin_info(); + break; +#endif + #ifdef VST_SUPPORT case ARDOUR::VST: plugs = mgr->vst_plugin_info(); - unique_id = 0; // VST plugins don't have a unique id. break; #endif #ifdef HAVE_AUDIOUNITS case ARDOUR::AudioUnit: - plugs = AUPluginInfo::discover (); - unique_id = 0; // Neither do AU. + plugs = mgr->au_plugin_info(); break; #endif @@ -273,13 +258,45 @@ ARDOUR::find_plugin(Session& session, string name, long unique_id, PluginType ty } PluginInfoList::iterator i; + for (i = plugs.begin(); i != plugs.end(); ++i) { - if ((name == "" || (*i)->name == name) && - (unique_id == 0 || (*i)->unique_id == unique_id)) { - return (*i)->load (session); + if (identifier == (*i)->unique_id){ + return (*i)->load (session); } } - + +#ifdef VST_SUPPORT + /* hmm, we didn't find it. could be because in older versions of Ardour. + we used to store the name of a VST plugin, not its unique ID. so try + again. + */ + + for (i = plugs.begin(); i != plugs.end(); ++i) { + if (identifier == (*i)->name){ + return (*i)->load (session); + } + } +#endif + return PluginPtr ((Plugin*) 0); } +ChanCount +Plugin::output_streams () const +{ + /* LADSPA & VST should not get here because they do not + return "infinite" i/o counts. + */ + return ChanCount::ZERO; +} + +ChanCount +Plugin::input_streams () const +{ + /* LADSPA & VST should not get here because they do not + return "infinite" i/o counts. + */ + return ChanCount::ZERO; +} + +