Fix yet another oversight for the windows icon file update
[ardour.git] / libs / ardour / plugin.cc
1 /*
2     Copyright (C) 2000-2002 Paul Davis
3
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.
8
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.
13
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.
17
18 */
19
20 #ifdef WAF_BUILD
21 #include "libardour-config.h"
22 #endif
23
24 #include <vector>
25 #include <string>
26
27 #include <cstdlib>
28 #include <cstdio> // so libraptor doesn't complain
29 #include <cmath>
30 #ifndef COMPILER_MSVC
31 #include <dirent.h>
32 #endif
33 #include <sys/stat.h>
34 #include <cerrno>
35 #include <utility>
36
37 #ifdef HAVE_LRDF
38 #include <lrdf.h>
39 #endif
40
41 #include "pbd/compose.h"
42 #include "pbd/error.h"
43 #include "pbd/xml++.h"
44
45 #include "ardour/buffer_set.h"
46 #include "ardour/chan_count.h"
47 #include "ardour/chan_mapping.h"
48 #include "ardour/data_type.h"
49 #include "ardour/luaproc.h"
50 #include "ardour/midi_buffer.h"
51 #include "ardour/midi_state_tracker.h"
52 #include "ardour/plugin.h"
53 #include "ardour/plugin_manager.h"
54 #include "ardour/port.h"
55 #include "ardour/session.h"
56 #include "ardour/types.h"
57
58 #ifdef AUDIOUNIT_SUPPORT
59 #include "ardour/audio_unit.h"
60 #endif
61
62 #ifdef LV2_SUPPORT
63 #include "ardour/lv2_plugin.h"
64 #endif
65
66 #include "pbd/stl_delete.h"
67
68 #include "pbd/i18n.h"
69 #include <locale.h>
70
71 using namespace std;
72 using namespace ARDOUR;
73 using namespace PBD;
74
75 namespace ARDOUR { class AudioEngine; }
76
77 #ifdef NO_PLUGIN_STATE
78 static bool seen_get_state_message = false;
79 static bool seen_set_state_message = false;
80 #endif
81
82 PBD::Signal2<void, std::string, Plugin*> Plugin::PresetsChanged;
83
84 bool
85 PluginInfo::needs_midi_input () const
86 {
87         return (n_inputs.n_midi() != 0);
88 }
89
90 bool
91 PluginInfo::is_instrument () const
92 {
93         return (n_inputs.n_midi() != 0) && (n_outputs.n_audio() > 0) && (n_inputs.n_audio() == 0);
94 }
95
96 Plugin::Plugin (AudioEngine& e, Session& s)
97         : _engine (e)
98         , _session (s)
99         , _cycles (0)
100         , _have_presets (false)
101         , _have_pending_stop_events (false)
102         , _parameter_changed_since_last_preset (false)
103 {
104         _pending_stop_events.ensure_buffers (DataType::MIDI, 1, 4096);
105 }
106
107 Plugin::Plugin (const Plugin& other)
108         : StatefulDestructible()
109         , Latent()
110         , _engine (other._engine)
111         , _session (other._session)
112         , _info (other._info)
113         , _cycles (0)
114         , _have_presets (false)
115         , _have_pending_stop_events (false)
116         , _parameter_changed_since_last_preset (false)
117 {
118         _pending_stop_events.ensure_buffers (DataType::MIDI, 1, 4096);
119 }
120
121 Plugin::~Plugin ()
122 {
123 }
124
125 void
126 Plugin::remove_preset (string name)
127 {
128         Plugin::PresetRecord const * p = preset_by_label (name);
129         if (!p) {
130                 PBD::error << _("Trying to remove nonexistent preset.") << endmsg;
131                 return;
132         }
133         if (!p->user) {
134                 PBD::error << _("Cannot remove plugin factory preset.") << endmsg;
135                 return;
136         }
137
138         do_remove_preset (name);
139         _presets.erase (p->uri);
140
141         _last_preset.uri = "";
142         _parameter_changed_since_last_preset = false;
143         _have_presets = false;
144         PresetsChanged (unique_id(), this); /* EMIT SIGNAL */
145         PresetRemoved (); /* EMIT SIGNAL */
146 }
147
148 /** @return PresetRecord with empty URI on failure */
149 Plugin::PresetRecord
150 Plugin::save_preset (string name)
151 {
152         if (preset_by_label (name)) {
153                 PBD::error << _("Preset with given name already exists.") << endmsg;
154                 return Plugin::PresetRecord ();
155         }
156
157         string const uri = do_save_preset (name);
158
159         if (!uri.empty()) {
160                 _presets.insert (make_pair (uri, PresetRecord (uri, name)));
161                 _have_presets = false;
162                 PresetsChanged (unique_id(), this); /* EMIT SIGNAL */
163                 PresetAdded (); /* EMIT SIGNAL */
164         }
165
166         return PresetRecord (uri, name);
167 }
168
169 PluginPtr
170 ARDOUR::find_plugin(Session& session, string identifier, PluginType type)
171 {
172         PluginManager& mgr (PluginManager::instance());
173         PluginInfoList plugs;
174
175         switch (type) {
176         case ARDOUR::Lua:
177                 plugs = mgr.lua_plugin_info();
178                 break;
179
180         case ARDOUR::LADSPA:
181                 plugs = mgr.ladspa_plugin_info();
182                 break;
183
184 #ifdef LV2_SUPPORT
185         case ARDOUR::LV2:
186                 plugs = mgr.lv2_plugin_info();
187                 break;
188 #endif
189
190 #ifdef WINDOWS_VST_SUPPORT
191         case ARDOUR::Windows_VST:
192                 plugs = mgr.windows_vst_plugin_info();
193                 break;
194 #endif
195
196 #ifdef LXVST_SUPPORT
197         case ARDOUR::LXVST:
198                 plugs = mgr.lxvst_plugin_info();
199                 break;
200 #endif
201
202 #ifdef MACVST_SUPPORT
203         case ARDOUR::MacVST:
204                 plugs = mgr.mac_vst_plugin_info();
205                 break;
206 #endif
207
208 #ifdef AUDIOUNIT_SUPPORT
209         case ARDOUR::AudioUnit:
210                 plugs = mgr.au_plugin_info();
211                 break;
212 #endif
213
214         default:
215                 return PluginPtr ((Plugin *) 0);
216         }
217
218         PluginInfoList::iterator i;
219
220         for (i = plugs.begin(); i != plugs.end(); ++i) {
221                 if (identifier == (*i)->unique_id){
222                         return (*i)->load (session);
223                 }
224         }
225
226 #ifdef WINDOWS_VST_SUPPORT
227         /* hmm, we didn't find it. could be because in older versions of Ardour.
228            we used to store the name of a VST plugin, not its unique ID. so try
229            again.
230         */
231
232         for (i = plugs.begin(); i != plugs.end(); ++i) {
233                 if (identifier == (*i)->name){
234                         return (*i)->load (session);
235                 }
236         }
237 #endif
238
239 #ifdef LXVST_SUPPORT
240         /* hmm, we didn't find it. could be because in older versions of Ardour.
241            we used to store the name of a VST plugin, not its unique ID. so try
242            again.
243         */
244
245         for (i = plugs.begin(); i != plugs.end(); ++i) {
246                 if (identifier == (*i)->name){
247                         return (*i)->load (session);
248                 }
249         }
250 #endif
251
252         return PluginPtr ((Plugin*) 0);
253 }
254
255 ChanCount
256 Plugin::output_streams () const
257 {
258         /* LADSPA & VST should not get here because they do not
259            return "infinite" i/o counts.
260         */
261         return ChanCount::ZERO;
262 }
263
264 ChanCount
265 Plugin::input_streams () const
266 {
267         /* LADSPA & VST should not get here because they do not
268            return "infinite" i/o counts.
269         */
270         return ChanCount::ZERO;
271 }
272
273 Plugin::IOPortDescription
274 Plugin::describe_io_port (ARDOUR::DataType dt, bool input, uint32_t id) const
275 {
276         std::stringstream ss;
277         switch (dt) {
278                 case DataType::AUDIO:
279                         ss << _("Audio") << " ";
280                         break;
281                 case DataType::MIDI:
282                         ss << _("Midi") << " ";
283                         break;
284                 default:
285                         ss << _("?") << " ";
286                         break;
287         }
288         if (input) {
289                 ss << _("In") << " ";
290         } else {
291                 ss << _("Out") << " ";
292         }
293
294         ss << (id + 1);
295
296         Plugin::IOPortDescription iod (ss.str());
297         return iod;
298 }
299
300 PluginOutputConfiguration
301 Plugin::possible_output () const
302 {
303         PluginOutputConfiguration oc;
304         if (_info) {
305                 oc.insert (_info->n_outputs.n_audio ());
306         }
307         return oc;
308 }
309
310 const Plugin::PresetRecord *
311 Plugin::preset_by_label (const string& label)
312 {
313 #ifndef NO_PLUGIN_STATE
314         if (!_have_presets) {
315                 find_presets ();
316                 _have_presets = true;
317         }
318 #endif
319         // FIXME: O(n)
320         for (map<string, PresetRecord>::const_iterator i = _presets.begin(); i != _presets.end(); ++i) {
321                 if (i->second.label == label) {
322                         return &i->second;
323                 }
324         }
325
326         return 0;
327 }
328
329 const Plugin::PresetRecord *
330 Plugin::preset_by_uri (const string& uri)
331 {
332 #ifndef NO_PLUGIN_STATE
333         if (!_have_presets) {
334                 find_presets ();
335                 _have_presets = true;
336         }
337 #endif
338         map<string, PresetRecord>::const_iterator pr = _presets.find (uri);
339         if (pr != _presets.end()) {
340                 return &pr->second;
341         } else {
342                 return 0;
343         }
344 }
345
346 int
347 Plugin::connect_and_run (BufferSet& bufs,
348                 framepos_t /*start*/, framepos_t /*end*/, double /*speed*/,
349                 ChanMapping /*in_map*/, ChanMapping /*out_map*/,
350                 pframes_t /* nframes */, framecnt_t /*offset*/)
351 {
352         if (bufs.count().n_midi() > 0) {
353
354                 /* Track notes that we are sending to the plugin */
355
356                 const MidiBuffer& b = bufs.get_midi (0);
357
358                 _tracker.track (b.begin(), b.end());
359
360                 if (_have_pending_stop_events) {
361                         /* Transmit note-offs that are pending from the last transport stop */
362                         bufs.merge_from (_pending_stop_events, 0);
363                         _have_pending_stop_events = false;
364                 }
365         }
366
367         return 0;
368 }
369
370 void
371 Plugin::realtime_handle_transport_stopped ()
372 {
373         resolve_midi ();
374 }
375
376 void
377 Plugin::realtime_locate ()
378 {
379         resolve_midi ();
380 }
381
382 void
383 Plugin::monitoring_changed ()
384 {
385         resolve_midi ();
386 }
387
388 void
389 Plugin::resolve_midi ()
390 {
391         /* Create note-offs for any active notes and put them in _pending_stop_events, to be picked
392            up on the next call to connect_and_run ().
393         */
394
395         _pending_stop_events.get_midi(0).clear ();
396         _tracker.resolve_notes (_pending_stop_events.get_midi (0), 0);
397         _have_pending_stop_events = true;
398 }
399
400 vector<Plugin::PresetRecord>
401 Plugin::get_presets ()
402 {
403         vector<PresetRecord> p;
404
405 #ifndef NO_PLUGIN_STATE
406         if (!_have_presets) {
407                 find_presets ();
408                 _have_presets = true;
409         }
410
411         for (map<string, PresetRecord>::const_iterator i = _presets.begin(); i != _presets.end(); ++i) {
412                 p.push_back (i->second);
413         }
414 #else
415         if (!seen_set_state_message) {
416                 info << string_compose (_("Plugin presets are not supported in this build of %1. Consider paying for a full version"),
417                                         PROGRAM_NAME)
418                      << endmsg;
419                 seen_set_state_message = true;
420         }
421 #endif
422
423         return p;
424 }
425
426 /** Set parameters using a preset */
427 bool
428 Plugin::load_preset (PresetRecord r)
429 {
430         _last_preset = r;
431         _parameter_changed_since_last_preset = false;
432
433         _session.set_dirty ();
434         PresetLoaded (); /* EMIT SIGNAL */
435         return true;
436 }
437
438 void
439 Plugin::clear_preset ()
440 {
441         _last_preset.uri = "";
442         _last_preset.label = "";
443         _parameter_changed_since_last_preset = false;
444
445         _session.set_dirty ();
446         PresetLoaded (); /* EMIT SIGNAL */
447 }
448
449 void
450 Plugin::set_parameter (uint32_t /* which */, float /* value */)
451 {
452         _parameter_changed_since_last_preset = true;
453         _session.set_dirty ();
454         PresetDirty (); /* EMIT SIGNAL */
455 }
456
457 void
458 Plugin::parameter_changed_externally (uint32_t which, float /* value */)
459 {
460         _parameter_changed_since_last_preset = true;
461         _session.set_dirty ();
462         ParameterChangedExternally (which, get_parameter (which)); /* EMIT SIGNAL */
463         PresetDirty (); /* EMIT SIGNAL */
464 }
465
466 int
467 Plugin::set_state (const XMLNode& node, int /*version*/)
468 {
469         XMLProperty const * p = node.property (X_("last-preset-uri"));
470         if (p) {
471                 _last_preset.uri = p->value ();
472         }
473
474         p = node.property (X_("last-preset-label"));
475         if (p) {
476                 _last_preset.label = p->value ();
477         }
478
479         p = node.property (X_("parameter-changed-since-last-preset"));
480         if (p) {
481                 _parameter_changed_since_last_preset = string_is_affirmative (p->value ());
482         }
483
484         return 0;
485 }
486
487 XMLNode &
488 Plugin::get_state ()
489 {
490         XMLNode* root = new XMLNode (state_node_name ());
491         LocaleGuard lg;
492
493         root->add_property (X_("last-preset-uri"), _last_preset.uri);
494         root->add_property (X_("last-preset-label"), _last_preset.label);
495         root->add_property (X_("parameter-changed-since-last-preset"), _parameter_changed_since_last_preset ? X_("yes") : X_("no"));
496
497 #ifndef NO_PLUGIN_STATE
498         add_state (root);
499 #else
500         if (!seen_get_state_message) {
501                 info << string_compose (_("Saving plugin settings is not supported in this build of %1. Consider paying for the full version"),
502                                         PROGRAM_NAME)
503                      << endmsg;
504                 seen_get_state_message = true;
505         }
506 #endif
507
508         return *root;
509 }
510
511 void
512 Plugin::set_info (PluginInfoPtr info)
513 {
514         _info = info;
515 }
516
517