update vestige header; fix 64 bit issues
[ardour.git] / libs / ardour / lxvst_plugin.cc
1 /*
2     Copyright (C) 2004 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 /**********************************************************************/
21 /*Native linuxVST (LXVST) variant of vst_plugin.cc etc                */
22 /**********************************************************************/
23
24
25 #include <algorithm>
26 #include <vector>
27 #include <string>
28 #include <cctype>
29
30 #include <cstdlib>
31 #include <cstdio> // so libraptor doesn't complain
32 #include <cmath>
33 #include <dirent.h>
34 #include <cstring> // for memmove
35 #include <sys/stat.h>
36 #include <cerrno>
37
38 #include <glibmm/miscutils.h>
39
40 #include <lrdf.h>
41
42 /*Include for the new native vst engine - vstfx.h*/
43 #include <stdint.h>
44 #include <ardour/vstfx.h>
45
46 #include "pbd/compose.h"
47 #include "pbd/error.h"
48 #include "pbd/pathscanner.h"
49 #include "pbd/xml++.h"
50
51 #include "ardour/session.h"
52 #include "ardour/audioengine.h"
53 #include "ardour/filesystem_paths.h"
54 #include "ardour/lxvst_plugin.h"
55 #include "ardour/buffer_set.h"
56 #include "ardour/audio_buffer.h"
57 #include "ardour/midi_buffer.h"
58
59 #include "pbd/stl_delete.h"
60
61 #include "i18n.h"
62 #include <locale.h>
63
64 using namespace std;
65 using namespace ARDOUR;
66 using namespace PBD;
67 using std::min;
68 using std::max;
69
70 LXVSTPlugin::LXVSTPlugin (AudioEngine& e, Session& session, VSTFXHandle* h)
71         : Plugin (e, session)
72 {
73         handle = h;
74
75         /*Instantiate the plugin and return a VSTFX* */
76
77         if ((_vstfx = vstfx_instantiate (handle, Session::lxvst_callback, this)) == 0) {
78                 throw failed_constructor();
79         }
80
81         /* Call into vstfx to get a pointer to the instance of the VST plugin*/
82
83         _plugin = _vstfx->plugin;
84         _plugin->user = this;
85
86         /* set rate and blocksize */
87
88         _plugin->dispatcher (_plugin, effSetSampleRate, 0, 0, NULL, (float) session.frame_rate());
89         
90         _plugin->dispatcher (_plugin, effSetBlockSize, 0, session.get_block_size(), NULL, 0.0f);
91
92         /* set program to zero */
93
94         _plugin->dispatcher (_plugin, effSetProgram, 0, 0, NULL, 0.0f);
95
96         // Plugin::setup_controls ();
97 }
98
99 LXVSTPlugin::LXVSTPlugin (const LXVSTPlugin &other)
100         : Plugin (other)
101 {
102         handle = other.handle;
103
104         if ((_vstfx = vstfx_instantiate (handle, Session::lxvst_callback, this)) == 0) {
105                 throw failed_constructor();
106         }
107         _plugin = _vstfx->plugin;
108
109         // Plugin::setup_controls ();
110 }
111
112 LXVSTPlugin::~LXVSTPlugin ()
113 {
114         deactivate ();
115         vstfx_close (_vstfx);
116 }
117
118 int 
119 LXVSTPlugin::set_block_size (pframes_t nframes)
120 {
121         deactivate ();
122         _plugin->dispatcher (_plugin, effSetBlockSize, 0, nframes, NULL, 0.0f);
123         activate ();
124         return 0;
125 }
126
127 float 
128 LXVSTPlugin::default_value (uint32_t)
129 {
130         return 0;
131 }
132
133 void 
134 LXVSTPlugin::set_parameter (uint32_t which, float val)
135 {
136         _plugin->setParameter (_plugin, which, val);
137         
138         if (_vstfx->want_program == -1 && _vstfx->want_chunk == 0) {
139                 /* Heinous hack: Plugin::set_parameter below updates the `modified' status of the
140                    current preset, but if _vstfx->want_program is not -1 then there is a preset
141                    setup pending or in progress, which we don't want any `modified' updates
142                    to happen for.  So we only do this if _vstfx->want_program is -1.
143                 */
144                 Plugin::set_parameter (which, val);
145         }
146 }
147
148 float 
149 LXVSTPlugin::get_parameter (uint32_t which) const
150 {
151         return _plugin->getParameter (_plugin, which);
152
153 }
154
155 uint32_t 
156 LXVSTPlugin::nth_parameter (uint32_t n, bool& ok) const
157 {
158         ok = true;
159         return n;
160 }
161
162 /** Get VST chunk as base64-encoded data.
163  *  @param single true for single program, false for all programs.
164  *  @return 0-terminated base64-encoded data; must be passed to g_free () by caller.
165  */
166 gchar *LXVSTPlugin::get_chunk (bool single) const
167 {
168         guchar* data;
169         int32_t data_size = _plugin->dispatcher (_plugin, 23 /* effGetChunk */, single ? 1 : 0, 0, &data, 0);
170
171         if (data_size == 0) {
172                 return 0;
173         }
174
175         return g_base64_encode (data, data_size);
176 }
177
178 /** Set VST chunk from base64-encoded data.
179  *  @param 0-terminated base64-encoded data.
180  *  @param single true for single program, false for all programs.
181  *  @return 0 on success, non-0 on failure
182  */
183 int 
184 LXVSTPlugin::set_chunk (gchar const * data, bool single)
185 {
186         gsize size = 0;
187         guchar* raw_data = g_base64_decode (data, &size);
188         int const r = _plugin->dispatcher (_plugin, 24 /* effSetChunk */, single ? 1 : 0, size, raw_data, 0);
189         g_free (raw_data);
190         return r;
191 }
192
193 void 
194 LXVSTPlugin::add_state (XMLNode* root) const
195 {
196         LocaleGuard lg (X_("POSIX"));
197
198         if (_vstfx->current_program != -1) {
199                 char buf[32];
200                 snprintf (buf, sizeof (buf), "%d", _vstfx->current_program);
201                 root->add_property ("current-program", buf);
202         }
203
204         if (_plugin->flags & 32 /* effFlagsProgramsChunks */) {
205                 gchar* data = get_chunk (false);
206
207                 if (data == 0) {
208                         return;
209                 }
210
211                 /* store information */
212
213                 XMLNode* chunk_node = new XMLNode (X_("chunk"));
214
215                 chunk_node->add_content (data);
216                 g_free (data);
217
218                 root->add_child_nocopy (*chunk_node);
219
220         } else {
221                 XMLNode* parameters = new XMLNode ("parameters");
222
223                 for (int32_t n = 0; n < _plugin->numParams; ++n) {
224                         char index[64];
225                         char val[32];
226                         snprintf (index, sizeof (index), "param_%d", n);
227                         snprintf (val, sizeof (val), "%.12g", _plugin->getParameter (_plugin, n));
228                         parameters->add_property (index, val);
229                 }
230
231                 root->add_child_nocopy (*parameters);
232         }
233 }
234
235 int 
236 LXVSTPlugin::set_state (const XMLNode& node, int version)
237 {
238         LocaleGuard lg (X_("POSIX"));
239
240         if (node.name() != state_node_name()) {
241                 error << _("Bad node sent to VSTPlugin::set_state") << endmsg;
242                 return 0;
243         }
244
245         const XMLProperty* prop;
246
247         if ((prop = node.property ("current-program")) != 0) {
248                 _vstfx->want_program = atoi (prop->value().c_str());
249         }
250
251         XMLNode* child;
252         int ret = -1;
253
254         if ((child = find_named_node (node, X_("chunk"))) != 0) {
255                 XMLPropertyList::const_iterator i;
256                 XMLNodeList::const_iterator n;
257
258                 for (n = child->children ().begin (); n != child->children ().end (); ++n) {
259                         if ((*n)->is_content ()) {
260                                 /* XXX: this may be dubious for the same reasons that we delay
261                                    execution of load_preset.
262                                 */
263                                 ret = set_chunk ((*n)->content().c_str(), false);
264                         }
265                 }
266
267         } else if ((child = find_named_node (node, X_("parameters"))) != 0) {
268                 XMLPropertyList::const_iterator i;
269
270                 for (i = child->properties().begin(); i != child->properties().end(); ++i) {
271                         int32_t param;
272                         float val;
273
274                         sscanf ((*i)->name().c_str(), "param-%d", &param); //This was param_%d (from vst_plugin) which caused all sorts of odd behaviour
275                         sscanf ((*i)->value().c_str(), "%f", &val);
276
277                         _plugin->setParameter (_plugin, param, val);
278                 }
279
280                 /* program number is not knowable */
281
282                 _vstfx->current_program = -1;
283
284                 ret = 0;
285         }
286
287         Plugin::set_state (node, version);
288         return ret;
289 }
290
291 int 
292 LXVSTPlugin::get_parameter_descriptor (uint32_t which, ParameterDescriptor& desc) const
293 {
294         desc.min_unbound = false;
295         desc.max_unbound = false;
296
297         /* old style */
298
299         char label[64];
300         label[0] = '\0';
301
302         _plugin->dispatcher (_plugin, effGetParamName, which, 0, label, 0);
303
304         desc.label = label;
305         desc.integer_step = false;
306         desc.lower = 0.0f;
307         desc.upper = 1.0f;
308         desc.step = 0.01f;
309         desc.smallstep = 0.005f;
310         desc.largestep = 0.1f;
311         desc.toggled = false;
312         desc.logarithmic = false;
313         desc.sr_dependent = false;
314         
315         return 0;
316 }
317
318 bool 
319 LXVSTPlugin::load_preset (PresetRecord r)
320 {
321         bool s;
322
323         if (r.user) {
324                 s = load_user_preset (r);
325         }
326         else {
327                 s = load_plugin_preset (r);
328         }
329
330         if (s) {
331                 Plugin::load_preset (r);
332         }
333
334         return s;
335 }
336
337 bool 
338 LXVSTPlugin::load_plugin_preset (PresetRecord r)
339 {
340         /* This is a plugin-provided preset.
341            We can't dispatch directly here; too many plugins expects only one GUI thread.
342         */
343
344         /* Extract the index of this preset from the URI */
345         int id;
346         int index;
347         int const p = sscanf (r.uri.c_str(), "VST:%d:%d", &id, &index);
348         assert (p == 2);
349         
350         _vstfx->want_program = index;
351         return true;
352 }
353
354 bool 
355 LXVSTPlugin::load_user_preset (PresetRecord r)
356 {
357         /* This is a user preset; we load it, and this code also knows about the
358            non-direct-dispatch thing.
359         */
360
361         boost::shared_ptr<XMLTree> t (presets_tree ());
362         if (t == 0) {
363                 return false;
364         }
365
366         XMLNode* root = t->root ();
367
368         for (XMLNodeList::const_iterator i = root->children().begin(); i != root->children().end(); ++i) {
369                 XMLProperty* uri = (*i)->property (X_("uri"));
370                 XMLProperty* label = (*i)->property (X_("label"));
371
372                 assert (uri);
373                 assert (label);
374
375                 if (label->value() != r.label) {
376                         continue;
377                 }
378
379                 if (_plugin->flags & 32 /* effFlagsProgramsChunks */) {
380
381                         /* Load a user preset chunk from our XML file and send it via a circuitous route to the plugin */
382
383                         if (_vstfx->wanted_chunk) {
384                                 g_free (_vstfx->wanted_chunk);
385                         }
386
387                         for (XMLNodeList::const_iterator j = (*i)->children().begin(); j != (*i)->children().end(); ++j) {
388                                 if ((*j)->is_content ()) {
389                                         /* we can't dispatch directly here; too many plugins expect only one GUI thread */
390                                         gsize size = 0;
391                                         guchar* raw_data = g_base64_decode ((*j)->content().c_str(), &size);
392                                         _vstfx->wanted_chunk = raw_data;
393                                         _vstfx->wanted_chunk_size = size;
394                                         _vstfx->want_chunk = 1;
395                                         return true;
396                                 }
397                         }
398
399                         return false;
400
401                 }
402                 else {
403                         for (XMLNodeList::const_iterator j = (*i)->children().begin(); j != (*i)->children().end(); ++j) {
404                                 if ((*j)->name() == X_("Parameter")) {
405                                                 XMLProperty* index = (*j)->property (X_("index"));
406                                                 XMLProperty* value = (*j)->property (X_("value"));
407
408                                                 assert (index);
409                                                 assert (value);
410
411                                                 set_parameter (atoi (index->value().c_str()), atof (value->value().c_str ()));
412                                 }
413                         }
414                         return true;
415                 }
416         }
417         return false;
418 }
419
420 string 
421 LXVSTPlugin::do_save_preset (string name)
422 {
423         boost::shared_ptr<XMLTree> t (presets_tree ());
424         if (t == 0) {
425                 return "";
426         }
427
428         XMLNode* p = 0;
429         /* XXX: use of _presets.size() + 1 for the unique ID here is dubious at best */
430         string const uri = string_compose (X_("VST:%1:%2"), unique_id (), _presets.size() + 1);
431
432         if (_plugin->flags & 32 /* effFlagsProgramsChunks */) {
433
434                 p = new XMLNode (X_("ChunkPreset"));
435                 p->add_property (X_("uri"), uri);
436                 p->add_property (X_("label"), name);
437                 gchar* data = get_chunk (true);
438                 p->add_content (string (data));
439                 g_free (data);
440
441         }
442         else {
443
444                 p = new XMLNode (X_("Preset"));
445                 p->add_property (X_("uri"), uri);
446                 p->add_property (X_("label"), name);
447
448                 for (uint32_t i = 0; i < parameter_count(); ++i) {
449                         if (parameter_is_input (i)) {
450                                 XMLNode* c = new XMLNode (X_("Parameter"));
451                                 c->add_property (X_("index"), string_compose ("%1", i));
452                                 c->add_property (X_("value"), string_compose ("%1", get_parameter (i)));
453                                 p->add_child_nocopy (*c);
454                         }
455                 }
456         }
457
458         t->root()->add_child_nocopy (*p);
459
460         sys::path f = ARDOUR::user_config_directory ();
461         f /= "presets";
462         f /= presets_file ();
463
464         t->write (f.to_string ());
465         return uri;
466 }
467
468 void 
469 LXVSTPlugin::do_remove_preset (string name)
470 {
471         boost::shared_ptr<XMLTree> t (presets_tree ());
472         if (t == 0) {
473                 return;
474         }
475
476         t->root()->remove_nodes_and_delete (X_("label"), name);
477
478         sys::path f = ARDOUR::user_config_directory ();
479         f /= "presets";
480         f /= presets_file ();
481
482         t->write (f.to_string ());
483 }
484
485 string 
486 LXVSTPlugin::describe_parameter (Evoral::Parameter param)
487 {
488         char name[64] = "Unkown";
489         _plugin->dispatcher (_plugin, effGetParamName, param.id(), 0, name, 0);
490         return name;
491 }
492
493 framecnt_t 
494 LXVSTPlugin::signal_latency () const
495 {
496         if (_user_latency) {
497                 return _user_latency;
498         }
499
500 #ifdef VESTIGE_HEADER
501         return *((int32_t *) (((char *) &_plugin->flags) + 12)); /* initialDelay */
502 #else
503         return _plugin->initial_delay;
504 #endif
505 }
506
507 set<Evoral::Parameter> 
508 LXVSTPlugin::automatable () const
509 {
510         set<Evoral::Parameter> ret;
511
512         for (uint32_t i = 0; i < parameter_count(); ++i) {
513                 ret.insert (ret.end(), Evoral::Parameter(PluginAutomation, 0, i));
514         }
515
516         return ret;
517 }
518
519 int
520 LXVSTPlugin::connect_and_run (BufferSet& bufs,
521                               ChanMapping in_map, ChanMapping out_map,
522                               pframes_t nframes, framecnt_t offset)
523 {
524         Plugin::connect_and_run (bufs, in_map, out_map, nframes, offset);
525
526         float *ins[_plugin->numInputs];
527         float *outs[_plugin->numOutputs];
528         int32_t i;
529
530         const uint32_t nbufs = bufs.count().n_audio();
531
532         int in_index = 0;
533         for (i = 0; i < (int32_t) _plugin->numInputs; ++i) {
534                 ins[i] = bufs.get_audio(min((uint32_t) in_index, nbufs - 1)).data() + offset;
535                 in_index++;
536         }
537
538         int out_index = 0;
539         for (i = 0; i < (int32_t) _plugin->numOutputs; ++i) {
540                 outs[i] = bufs.get_audio(min((uint32_t) out_index, nbufs - 1)).data() + offset;
541                 out_index++;
542         }
543
544         if (bufs.count().n_midi() > 0) {
545                 VstEvents* v = bufs.get_vst_midi (0);
546                 _plugin->dispatcher (_plugin, effProcessEvents, 0, 0, v, 0);
547         }
548
549         /* we already know it can support processReplacing */
550
551         _plugin->processReplacing (_plugin, ins, outs, nframes);
552
553         return 0;
554 }
555
556 void 
557 LXVSTPlugin::deactivate ()
558 {
559         _plugin->dispatcher (_plugin, effMainsChanged, 0, 0, NULL, 0.0f);
560 }
561
562 void 
563 LXVSTPlugin::activate ()
564 {
565         _plugin->dispatcher (_plugin, effMainsChanged, 0, 1, NULL, 0.0f);
566 }
567
568 string 
569 LXVSTPlugin::unique_id() const
570 {
571         char buf[32];
572         
573
574         snprintf (buf, sizeof (buf), "%d", _plugin->uniqueID);
575
576         
577         return string (buf);
578 }
579
580
581 const char * 
582 LXVSTPlugin::name () const
583 {
584         return handle->name;
585 }
586
587 const char * 
588 LXVSTPlugin::maker () const
589 {
590         return _info->creator.c_str();
591 }
592
593 const char * 
594 LXVSTPlugin::label () const
595 {
596         return handle->name;
597 }
598
599 uint32_t 
600 LXVSTPlugin::parameter_count() const
601 {
602         return _plugin->numParams;
603 }
604
605 bool 
606 LXVSTPlugin::has_editor () const
607 {
608         return _plugin->flags & effFlagsHasEditor;
609 }
610
611 void 
612 LXVSTPlugin::print_parameter (uint32_t param, char *buf, uint32_t /*len*/) const
613 {
614         char *first_nonws;
615
616         _plugin->dispatcher (_plugin, 7 /* effGetParamDisplay */, param, 0, buf, 0);
617
618         if (buf[0] == '\0') {
619                 return;
620         }
621
622         first_nonws = buf;
623         while (*first_nonws && isspace (*first_nonws)) {
624                 first_nonws++;
625         }
626
627         if (*first_nonws == '\0') {
628                 return;
629         }
630
631         memmove (buf, first_nonws, strlen (buf) - (first_nonws - buf) + 1);
632 }
633
634 PluginPtr 
635 LXVSTPluginInfo::load (Session& session)
636 {
637         try {
638                 PluginPtr plugin;
639
640                 if (Config->get_use_lxvst()) {
641                         VSTFXHandle* handle;
642
643                         handle = vstfx_load(path.c_str());
644
645                         if (handle == NULL) {
646                                 error << string_compose(_("LXVST: cannot load module from \"%1\""), path) << endmsg;
647                         }
648                         else {
649                                 plugin.reset (new LXVSTPlugin (session.engine(), session, handle));
650                         }
651                 }
652                 else {
653                         error << _("You asked ardour to not use any LXVST plugins") << endmsg;
654                         return PluginPtr ((Plugin*) 0);
655                 }
656
657                 plugin->set_info(PluginInfoPtr(new LXVSTPluginInfo(*this)));
658                 return plugin;
659         }
660
661         catch (failed_constructor &err) {
662                 return PluginPtr ((Plugin*) 0);
663         }
664 }
665
666 void 
667 LXVSTPlugin::find_presets ()
668 {
669         /* Built-in presets */
670
671         int const vst_version = _plugin->dispatcher (_plugin, effGetVstVersion, 0, 0, NULL, 0);
672
673         for (int i = 0; i < _plugin->numPrograms; ++i) {
674                 PresetRecord r (string_compose (X_("LXVST:%1:%2"), unique_id (), i), "", false);
675
676                 if (vst_version >= 2) {
677                         char buf[256];
678                         if (_plugin->dispatcher (_plugin, 29, i, 0, buf, 0) == 1) {
679                                 r.label = buf;
680                         } else {
681                                 r.label = string_compose (_("Preset %1"), i);
682                         }
683                 } else {
684                         r.label = string_compose (_("Preset %1"), i);
685                 }
686
687                 _presets.insert (make_pair (r.uri, r));
688         }
689
690         /* User presets from our XML file */
691
692         boost::shared_ptr<XMLTree> t (presets_tree ());
693
694         if (t) {
695                 XMLNode* root = t->root ();
696                 for (XMLNodeList::const_iterator i = root->children().begin(); i != root->children().end(); ++i) {
697                         XMLProperty* uri = (*i)->property (X_("uri"));
698                         XMLProperty* label = (*i)->property (X_("label"));
699
700                         assert (uri);
701                         assert (label);
702
703                         PresetRecord r (uri->value(), label->value(), true);
704                         _presets.insert (make_pair (r.uri, r));
705                 }
706         }
707 }
708
709 /** @return XMLTree with our user presets; could be a new one if no existing
710  *  one was found, or 0 if one was present but badly-formatted.
711  */
712 XMLTree * 
713 LXVSTPlugin::presets_tree () const
714 {
715         XMLTree* t = new XMLTree;
716
717         sys::path p = ARDOUR::user_config_directory ();
718         p /= "presets";
719
720         if (!is_directory (p)) {
721                 create_directory (p);
722         }
723
724         p /= presets_file ();
725
726         if (!exists (p)) {
727                 t->set_root (new XMLNode (X_("LXVSTPresets")));
728                 return t;
729         }
730
731         t->set_filename (p.to_string ());
732         if (!t->read ()) {
733                 delete t;
734                 return 0;
735         }
736
737         return t;
738 }
739
740 /** @return Index of the first user preset in our lists */
741 int 
742 LXVSTPlugin::first_user_preset_index () const
743 {
744         return _plugin->numPrograms;
745 }
746
747 string LXVSTPlugin::presets_file () const
748 {
749         return string_compose ("lxvst-%1", unique_id ());
750 }
751
752 LXVSTPluginInfo::LXVSTPluginInfo()
753 {
754        type = ARDOUR::LXVST;
755 }
756