don't re-activate LV2 plugin before cleanup.
[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/midi_buffer.h"
50 #include "ardour/midi_state_tracker.h"
51 #include "ardour/plugin.h"
52 #include "ardour/plugin_manager.h"
53 #include "ardour/port.h"
54 #include "ardour/session.h"
55 #include "ardour/types.h"
56
57 #ifdef AUDIOUNIT_SUPPORT
58 #include "ardour/audio_unit.h"
59 #endif
60
61 #ifdef LV2_SUPPORT
62 #include "ardour/lv2_plugin.h"
63 #endif
64
65 #include "pbd/stl_delete.h"
66
67 #include "i18n.h"
68 #include <locale.h>
69
70 using namespace std;
71 using namespace ARDOUR;
72 using namespace PBD;
73
74 namespace ARDOUR { class AudioEngine; }
75
76 #ifdef NO_PLUGIN_STATE
77 static bool seen_get_state_message = false;
78 static bool seen_set_state_message = false;
79 #endif
80
81 PBD::Signal2<void, std::string, Plugin*> Plugin::PresetsChanged;
82
83 bool
84 PluginInfo::is_instrument () const
85 {
86         return (n_inputs.n_midi() != 0) && (n_outputs.n_audio() > 0);
87 }
88
89 std::vector<Plugin::PresetRecord>
90 PluginInfo::get_presets(Session& session) {
91         PluginPtr plugin = load (session);
92         if (plugin) {
93                 return plugin->get_presets();
94         } else {
95                 return std::vector<Plugin::PresetRecord> ();
96         }
97 }
98
99 Plugin::Plugin (AudioEngine& e, Session& s)
100         : _engine (e)
101         , _session (s)
102         , _cycles (0)
103         , _have_presets (false)
104         , _have_pending_stop_events (false)
105         , _parameter_changed_since_last_preset (false)
106 {
107         _pending_stop_events.ensure_buffers (DataType::MIDI, 1, 4096);
108         PresetsChanged.connect_same_thread (_preset_connection, boost::bind (&Plugin::update_presets, this, _1 ,_2));
109 }
110
111 Plugin::Plugin (const Plugin& other)
112         : StatefulDestructible()
113         , Latent()
114         , _engine (other._engine)
115         , _session (other._session)
116         , _info (other._info)
117         , _cycles (0)
118         , _have_presets (false)
119         , _have_pending_stop_events (false)
120         , _parameter_changed_since_last_preset (false)
121 {
122         _pending_stop_events.ensure_buffers (DataType::MIDI, 1, 4096);
123         PresetsChanged.connect_same_thread (_preset_connection, boost::bind (&Plugin::update_presets, this, _1 ,_2));
124 }
125
126 Plugin::~Plugin ()
127 {
128 }
129
130 void
131 Plugin::remove_preset (string name)
132 {
133         do_remove_preset (name);
134         _presets.erase (preset_by_label (name)->uri);
135
136         _last_preset.uri = "";
137         _parameter_changed_since_last_preset = false;
138         PresetRemoved (); /* EMIT SIGNAL */
139         PresetsChanged (unique_id(), this); /* EMIT SIGNAL */
140 }
141
142 /** @return PresetRecord with empty URI on failure */
143 Plugin::PresetRecord
144 Plugin::save_preset (string name)
145 {
146         string const uri = do_save_preset (name);
147
148         if (!uri.empty()) {
149                 _presets.insert (make_pair (uri, PresetRecord (uri, name)));
150                 PresetAdded (); /* EMIT SIGNAL */
151                 PresetsChanged (unique_id(), this); /* EMIT SIGNAL */
152         }
153
154         return PresetRecord (uri, name);
155 }
156
157 PluginPtr
158 ARDOUR::find_plugin(Session& session, string identifier, PluginType type)
159 {
160         PluginManager& mgr (PluginManager::instance());
161         PluginInfoList plugs;
162
163         switch (type) {
164         case ARDOUR::LADSPA:
165                 plugs = mgr.ladspa_plugin_info();
166                 break;
167
168 #ifdef LV2_SUPPORT
169         case ARDOUR::LV2:
170                 plugs = mgr.lv2_plugin_info();
171                 break;
172 #endif
173
174 #ifdef WINDOWS_VST_SUPPORT
175         case ARDOUR::Windows_VST:
176                 plugs = mgr.windows_vst_plugin_info();
177                 break;
178 #endif
179
180 #ifdef LXVST_SUPPORT
181         case ARDOUR::LXVST:
182                 plugs = mgr.lxvst_plugin_info();
183                 break;
184 #endif
185
186 #ifdef AUDIOUNIT_SUPPORT
187         case ARDOUR::AudioUnit:
188                 plugs = mgr.au_plugin_info();
189                 break;
190 #endif
191
192         default:
193                 return PluginPtr ((Plugin *) 0);
194         }
195
196         PluginInfoList::iterator i;
197
198         for (i = plugs.begin(); i != plugs.end(); ++i) {
199                 if (identifier == (*i)->unique_id){
200                         return (*i)->load (session);
201                 }
202         }
203
204 #ifdef WINDOWS_VST_SUPPORT
205         /* hmm, we didn't find it. could be because in older versions of Ardour.
206            we used to store the name of a VST plugin, not its unique ID. so try
207            again.
208         */
209
210         for (i = plugs.begin(); i != plugs.end(); ++i) {
211                 if (identifier == (*i)->name){
212                         return (*i)->load (session);
213                 }
214         }
215 #endif
216
217 #ifdef LXVST_SUPPORT
218         /* hmm, we didn't find it. could be because in older versions of Ardour.
219            we used to store the name of a VST plugin, not its unique ID. so try
220            again.
221         */
222
223         for (i = plugs.begin(); i != plugs.end(); ++i) {
224                 if (identifier == (*i)->name){
225                         return (*i)->load (session);
226                 }
227         }
228 #endif
229
230         return PluginPtr ((Plugin*) 0);
231 }
232
233 ChanCount
234 Plugin::output_streams () const
235 {
236         /* LADSPA & VST should not get here because they do not
237            return "infinite" i/o counts.
238         */
239         return ChanCount::ZERO;
240 }
241
242 ChanCount
243 Plugin::input_streams () const
244 {
245         /* LADSPA & VST should not get here because they do not
246            return "infinite" i/o counts.
247         */
248         return ChanCount::ZERO;
249 }
250
251 const Plugin::PresetRecord *
252 Plugin::preset_by_label (const string& label)
253 {
254         // FIXME: O(n)
255         for (map<string, PresetRecord>::const_iterator i = _presets.begin(); i != _presets.end(); ++i) {
256                 if (i->second.label == label) {
257                         return &i->second;
258                 }
259         }
260
261         return 0;
262 }
263
264 const Plugin::PresetRecord *
265 Plugin::preset_by_uri (const string& uri)
266 {
267         map<string, PresetRecord>::const_iterator pr = _presets.find (uri);
268         if (pr != _presets.end()) {
269                 return &pr->second;
270         } else {
271                 return 0;
272         }
273 }
274
275 int
276 Plugin::connect_and_run (BufferSet& bufs,
277                          ChanMapping /*in_map*/, ChanMapping /*out_map*/,
278                          pframes_t /* nframes */, framecnt_t /*offset*/)
279 {
280         if (bufs.count().n_midi() > 0) {
281
282                 /* Track notes that we are sending to the plugin */
283
284                 const MidiBuffer& b = bufs.get_midi (0);
285
286                 _tracker.track (b.begin(), b.end());
287
288                 if (_have_pending_stop_events) {
289                         /* Transmit note-offs that are pending from the last transport stop */
290                         bufs.merge_from (_pending_stop_events, 0);
291                         _have_pending_stop_events = false;
292                 }
293         }
294
295         return 0;
296 }
297
298 void
299 Plugin::realtime_handle_transport_stopped ()
300 {
301         resolve_midi ();
302 }
303
304 void
305 Plugin::realtime_locate ()
306 {
307         resolve_midi ();
308 }
309
310 void
311 Plugin::monitoring_changed ()
312 {
313         resolve_midi ();
314 }
315
316 void
317 Plugin::resolve_midi ()
318 {
319         /* Create note-offs for any active notes and put them in _pending_stop_events, to be picked
320            up on the next call to connect_and_run ().
321         */
322
323         _pending_stop_events.get_midi(0).clear ();
324         _tracker.resolve_notes (_pending_stop_events.get_midi (0), /* split cycle offset*/ Port::port_offset());
325         _have_pending_stop_events = true;
326 }
327
328 void
329 Plugin::update_presets (std::string src_unique_id, Plugin* src )
330 {
331         if (src == this || unique_id() != src_unique_id) {
332                 return;
333         }
334         _have_presets = false;
335         // TODO check if a preset was added/removed and emit the proper signal
336         // so far no subscriber distinguishes between PresetAdded and PresetRemoved
337         PresetAdded();
338 }
339
340 vector<Plugin::PresetRecord>
341 Plugin::get_presets ()
342 {
343         vector<PresetRecord> p;
344
345 #ifndef NO_PLUGIN_STATE
346         if (!_have_presets) {
347                 find_presets ();
348                 _have_presets = true;
349         }
350
351         for (map<string, PresetRecord>::const_iterator i = _presets.begin(); i != _presets.end(); ++i) {
352                 p.push_back (i->second);
353         }
354 #else
355         if (!seen_set_state_message) {
356                 info << string_compose (_("Plugin presets are not supported in this build of %1. Consider paying for a full version"),
357                                         PROGRAM_NAME)
358                      << endmsg;
359                 seen_set_state_message = true;
360         }
361 #endif
362
363         return p;
364 }
365
366 /** Set parameters using a preset */
367 bool
368 Plugin::load_preset (PresetRecord r)
369 {
370         _last_preset = r;
371         _parameter_changed_since_last_preset = false;
372
373         PresetLoaded (); /* EMIT SIGNAL */
374         return true;
375 }
376
377 void
378 Plugin::clear_preset ()
379 {
380         _last_preset.uri = "";
381         _last_preset.label = "";
382         _parameter_changed_since_last_preset = false;
383
384         PresetLoaded (); /* EMIT SIGNAL */
385 }
386
387 void
388 Plugin::set_parameter (uint32_t /* which */, float /* value */)
389 {
390         _parameter_changed_since_last_preset = true;
391         _session.set_dirty ();
392         PresetDirty (); /* EMIT SIGNAL */
393 }
394
395 void
396 Plugin::parameter_changed_externally (uint32_t which, float /* value */)
397 {
398         _parameter_changed_since_last_preset = true;
399         _session.set_dirty ();
400         ParameterChangedExternally (which, get_parameter (which)); /* EMIT SIGNAL */
401         PresetDirty (); /* EMIT SIGNAL */
402 }
403
404 int
405 Plugin::set_state (const XMLNode& node, int /*version*/)
406 {
407         XMLProperty const * p = node.property (X_("last-preset-uri"));
408         if (p) {
409                 _last_preset.uri = p->value ();
410         }
411
412         p = node.property (X_("last-preset-label"));
413         if (p) {
414                 _last_preset.label = p->value ();
415         }
416
417         p = node.property (X_("parameter-changed-since-last-preset"));
418         if (p) {
419                 _parameter_changed_since_last_preset = string_is_affirmative (p->value ());
420         }
421
422         return 0;
423 }
424
425 XMLNode &
426 Plugin::get_state ()
427 {
428         XMLNode* root = new XMLNode (state_node_name ());
429         LocaleGuard lg (X_("C"));
430
431         root->add_property (X_("last-preset-uri"), _last_preset.uri);
432         root->add_property (X_("last-preset-label"), _last_preset.label);
433         root->add_property (X_("parameter-changed-since-last-preset"), _parameter_changed_since_last_preset ? X_("yes") : X_("no"));
434
435 #ifndef NO_PLUGIN_STATE
436         add_state (root);
437 #else
438         if (!seen_get_state_message) {
439                 info << string_compose (_("Saving plugin settings is not supported in this build of %1. Consider paying for the full version"),
440                                         PROGRAM_NAME)
441                      << endmsg;
442                 seen_get_state_message = true;
443         }
444 #endif
445
446         return *root;
447 }
448
449 void
450 Plugin::set_info (PluginInfoPtr info)
451 {
452         _info = info;
453 }
454
455