fix up coding errors in previous AU-related commit
[ardour2.git] / libs / ardour / plugin.cc
blobb3f547dabbc2326b29d295eaf5bee8de0672f578
1 /*
2 Copyright (C) 2000-2002 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 #include <vector>
21 #include <string>
23 #include <cstdlib>
24 #include <cstdio> // so libraptor doesn't complain
25 #include <cmath>
26 #include <dirent.h>
27 #include <sys/stat.h>
28 #include <cerrno>
30 #include <lrdf.h>
32 #include <pbd/compose.h>
33 #include <pbd/error.h>
34 #include <pbd/pathscanner.h>
35 #include <pbd/xml++.h>
36 #include <pbd/stacktrace.h>
38 #include <ardour/ardour.h>
39 #include <ardour/session.h>
40 #include <ardour/audioengine.h>
41 #include <ardour/plugin.h>
42 #include <ardour/ladspa_plugin.h>
43 #include <ardour/plugin_manager.h>
45 #ifdef HAVE_AUDIOUNITS
46 #include <ardour/audio_unit.h>
47 #endif
49 #ifdef HAVE_SLV2
50 #include <ardour/lv2_plugin.h>
51 #endif
53 #include <pbd/stl_delete.h>
55 #include "i18n.h"
56 #include <locale.h>
58 using namespace ARDOUR;
59 using namespace PBD;
61 sigc::signal<bool> Plugin::PresetFileExists;
63 Plugin::Plugin (AudioEngine& e, Session& s)
64 : _engine (e), _session (s)
68 Plugin::Plugin (const Plugin& other)
69 : _engine (other._engine), _session (other._session), _info (other._info)
73 void
74 Plugin::setup_controls ()
76 uint32_t port_cnt = parameter_count();
78 /* set up a vector of null pointers for the controls.
79 we'll fill this in on an as-needed basis.
82 controls.assign (port_cnt, (PortControllable*) 0);
85 Plugin::~Plugin ()
87 for (vector<PortControllable*>::iterator i = controls.begin(); i != controls.end(); ++i) {
88 if (*i) {
89 delete *i;
94 void
95 Plugin::make_nth_control (uint32_t n, const XMLNode& node)
97 if (controls[n]) {
98 /* already constructed */
99 return;
102 Plugin::ParameterDescriptor desc;
104 get_parameter_descriptor (n, desc);
106 controls[n] = new PortControllable (node, *this, n,
107 desc.lower, desc.upper, desc.toggled, desc.logarithmic);
110 Controllable *
111 Plugin::get_nth_control (uint32_t n, bool do_not_create)
113 if (n >= parameter_count()) {
114 return 0;
117 if (controls[n] == 0 && !do_not_create) {
119 Plugin::ParameterDescriptor desc;
121 get_parameter_descriptor (n, desc);
123 controls[n] = new PortControllable (describe_parameter (n), *this, n,
124 desc.lower, desc.upper, desc.toggled, desc.logarithmic);
127 return controls[n];
130 Plugin::PortControllable::PortControllable (string name, Plugin& p, uint32_t port_id,
131 float low, float up, bool t, bool loga)
132 : Controllable (name), plugin (p), absolute_port (port_id)
134 toggled = t;
135 logarithmic = loga;
136 lower = low;
137 upper = up;
138 range = upper - lower;
141 Plugin::PortControllable::PortControllable (const XMLNode& node, Plugin& p, uint32_t port_id,
142 float low, float up, bool t, bool loga)
143 : Controllable (node), plugin (p), absolute_port (port_id)
145 toggled = t;
146 logarithmic = loga;
147 lower = low;
148 upper = up;
149 range = upper - lower;
152 void
153 Plugin::PortControllable::set_value (float value)
155 if (toggled) {
156 if (value > 0.5) {
157 value = 1.0;
158 } else {
159 value = 0.0;
161 } else {
163 if (!logarithmic) {
164 value = lower + (range * value);
165 } else {
166 float _lower = 0.0f;
167 if (lower > 0.0f) {
168 _lower = log(lower);
171 value = exp(_lower + log(range) * value);
175 plugin.set_parameter (absolute_port, value);
178 float
179 Plugin::PortControllable::get_value (void) const
181 float val = plugin.get_parameter (absolute_port);
183 if (toggled) {
185 return val;
187 } else {
189 if (logarithmic) {
190 val = log(val);
193 return ((val - lower) / range);
197 vector<string>
198 Plugin::get_presets()
200 vector<string> labels;
201 uint32_t id;
202 std::string unique (unique_id());
204 /* XXX problem: AU plugins don't have numeric ID's.
205 Solution: they have a different method of providing presets.
206 XXX sub-problem: implement it.
209 if (!isdigit (unique[0])) {
210 return labels;
213 id = atol (unique.c_str());
215 lrdf_uris* set_uris = lrdf_get_setting_uris(id);
217 if (set_uris) {
218 for (uint32_t i = 0; i < (uint32_t) set_uris->count; ++i) {
219 if (char* label = lrdf_get_label(set_uris->items[i])) {
220 labels.push_back(label);
221 presets[label] = set_uris->items[i];
224 lrdf_free_uris(set_uris);
227 // GTK2FIX find an equivalent way to do this with a vector (needed by GUI apis)
228 // labels.unique();
230 return labels;
233 bool
234 Plugin::load_preset(const string preset_label)
236 lrdf_defaults* defs = lrdf_get_setting_values(presets[preset_label].c_str());
238 if (defs) {
239 for (uint32_t i = 0; i < (uint32_t) defs->count; ++i) {
240 // The defs->items[i].pid < defs->count check is to work around
241 // a bug in liblrdf that saves invalid values into the presets file.
242 if (((uint32_t) defs->items[i].pid < (uint32_t) defs->count) && parameter_is_input (defs->items[i].pid)) {
243 set_parameter(defs->items[i].pid, defs->items[i].value);
246 lrdf_free_setting_values(defs);
249 return true;
252 bool
253 Plugin::save_preset (string name, string domain)
255 lrdf_portvalue portvalues[parameter_count()];
256 lrdf_defaults defaults;
257 uint32_t id;
258 std::string unique (unique_id());
260 /* XXX problem: AU plugins don't have numeric ID's.
261 Solution: they have a different method of providing/saving presets.
262 XXX sub-problem: implement it.
265 if (!isdigit (unique[0])) {
266 return false;
269 id = atol (unique.c_str());
271 defaults.count = parameter_count();
272 defaults.items = portvalues;
274 for (uint32_t i = 0; i < parameter_count(); ++i) {
275 if (parameter_is_input (i)) {
276 portvalues[i].pid = i;
277 portvalues[i].value = get_parameter(i);
281 char* envvar;
282 if ((envvar = getenv ("HOME")) == 0) {
283 warning << _("Could not locate HOME. Preset not saved.") << endmsg;
284 return false;
287 string source(string_compose("file:%1/.%2/rdf/ardour-presets.n3", envvar, domain));
289 free(lrdf_add_preset(source.c_str(), name.c_str(), id, &defaults));
291 string path = string_compose("%1/.%2", envvar, domain);
292 if (g_mkdir_with_parents (path.c_str(), 0775)) {
293 warning << string_compose(_("Could not create %1. Preset not saved. (%2)"), path, strerror(errno)) << endmsg;
294 return false;
297 path += "/rdf";
298 if (g_mkdir_with_parents (path.c_str(), 0775)) {
299 warning << string_compose(_("Could not create %1. Preset not saved. (%2)"), path, strerror(errno)) << endmsg;
300 return false;
303 if (lrdf_export_by_source(source.c_str(), source.substr(5).c_str())) {
304 warning << string_compose(_("Error saving presets file %1."), source) << endmsg;
305 return false;
308 return true;
311 PluginPtr
312 ARDOUR::find_plugin(Session& session, string identifier, PluginType type)
314 PluginManager *mgr = PluginManager::the_manager();
315 PluginInfoList plugs;
317 switch (type) {
318 case ARDOUR::LADSPA:
319 plugs = mgr->ladspa_plugin_info();
320 break;
322 #ifdef HAVE_SLV2
323 case ARDOUR::LV2:
324 plugs = mgr->lv2_plugin_info();
325 break;
326 #endif
328 #ifdef VST_SUPPORT
329 case ARDOUR::VST:
330 plugs = mgr->vst_plugin_info();
331 break;
332 #endif
334 #ifdef HAVE_AUDIOUNITS
335 case ARDOUR::AudioUnit:
337 /* Ardour before 2.8.5 stored identifiers using a broken function
338 provided by Apple (StringForOSType()) that couldn't properly
339 handle some bytes stored in some plugins' multi-character literal
340 identifiers.
342 Ardour 2.8.5 switched to use a modified version of this
343 function, but one that was still problematic and not
344 backwards compatible.
346 So, if this is an AU and we didn't find it above, fix up
347 the identifier we are looking for and check again.
350 identifier = AUPlugin::maybe_fix_broken_au_id (identifier);
351 if (identifier.empty()) {
352 return PluginPtr ((Plugin*) 0);
354 plugs = mgr->au_plugin_info();
355 break;
356 #endif
358 default:
359 return PluginPtr ((Plugin *) 0);
362 PluginInfoList::iterator i;
364 for (i = plugs.begin(); i != plugs.end(); ++i) {
365 if (identifier == (*i)->unique_id){
366 return (*i)->load (session);
370 #ifdef VST_SUPPORT
371 /* hmm, we didn't find it. could be because in older versions of Ardour.
372 we used to store the name of a VST plugin, not its unique ID. so try
373 again.
375 switch (type) {
376 case ARDOUR::VST:
377 for (i = plugs.begin(); i != plugs.end(); ++i) {
378 if (identifier == (*i)->name){
379 return (*i)->load (session);
382 break;
383 default:
384 break;
386 #endif
388 return PluginPtr ((Plugin*) 0);
391 int32_t
392 Plugin::configure_io (int32_t in, int32_t out)
394 /* parent Plugin class assumes static output stream count.
395 Derived classes can override.
398 Glib::Mutex::Lock em (_session.engine().process_lock());
399 IO::MoreOutputs (output_streams());
401 return 0;
404 int32_t
405 Plugin::can_do (int32_t in, int32_t& out)
407 int32_t outputs = get_info()->n_outputs;
408 int32_t inputs = get_info()->n_inputs;
410 if (inputs == 0) {
412 /* instrument plugin, always legal, but it throws
413 away any existing active streams.
416 out = outputs;
417 return 1;
420 if (outputs == 1 && inputs == 1) {
421 /* mono plugin, replicate as needed */
422 out = in;
423 return in;
426 if (inputs == in) {
427 /* exact match */
428 out = outputs;
429 return 1;
432 if ((inputs < in) && (inputs % in == 0)) {
434 /* number of inputs is a factor of the requested input
435 configuration, so we can replicate.
438 int nplugs = in/inputs;
439 out = outputs * nplugs;
440 return nplugs;
443 /* sorry */
445 return -1;
448 uint32_t
449 Plugin::output_streams () const
451 /* LADSPA & VST should not get here because they do not
452 return negative i/o counts.
454 return 0;
457 uint32_t
458 Plugin::input_streams () const
460 /* LADSPA & VST should not get here because they do not
461 return negative i/o counts.
463 return 0;