~ubuntu-branches/ubuntu/lucid/ardour/lucid-proposed

« back to all changes in this revision

Viewing changes to libs/ardour/lv2_plugin.cc

  • Committer: Bazaar Package Importer
  • Author(s): Free Ekanayaka
  • Date: 2008-02-07 20:51:55 UTC
  • mfrom: (1.1.13 upstream)
  • Revision ID: james.westby@ubuntu.com-20080207205155-xzi5lq5s2o1okvx8
Tags: 1:2.3.1-1
* New upstream release
* debian/control:
   - build-depend on libfftw3-dev (Closes: #463803)
   - added Homepage, Vcs-Svn, Vcs-Browser
* debian/patches
   - dropped 50-soundtouch.patch (fixed upstream)
   - updated 80_ardourino.patch
   - dropped unused patches from source package

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
    Copyright (C) 2008 Paul Davis 
 
3
    Author: Dave Robillard
 
4
 
 
5
    This program is free software; you can redistribute it and/or modify
 
6
    it under the terms of the GNU General Public License as published by
 
7
    the Free Software Foundation; either version 2 of the License, or
 
8
    (at your option) any later version.
 
9
 
 
10
    This program is distributed in the hope that it will be useful,
 
11
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
13
    GNU General Public License for more details.
 
14
 
 
15
    You should have received a copy of the GNU General Public License
 
16
    along with this program; if not, write to the Free Software
 
17
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
18
 
 
19
*/
 
20
 
 
21
#include <vector>
 
22
#include <string>
 
23
 
 
24
#include <cstdlib>
 
25
#include <cmath>
 
26
 
 
27
#include <pbd/compose.h>
 
28
#include <pbd/error.h>
 
29
#include <pbd/pathscanner.h>
 
30
#include <pbd/xml++.h>
 
31
 
 
32
#include <ardour/ardour.h>
 
33
#include <ardour/session.h>
 
34
#include <ardour/audioengine.h>
 
35
#include <ardour/lv2_plugin.h>
 
36
 
 
37
#include <pbd/stl_delete.h>
 
38
 
 
39
#include "i18n.h"
 
40
#include <locale.h>
 
41
 
 
42
using namespace std;
 
43
using namespace ARDOUR;
 
44
using namespace PBD;
 
45
 
 
46
LV2Plugin::LV2Plugin (AudioEngine& e, Session& session, LV2World& world, SLV2Plugin plugin, nframes_t rate)
 
47
        : Plugin (e, session)
 
48
        , _world(world)
 
49
{
 
50
        init (world, plugin, rate);
 
51
}
 
52
 
 
53
LV2Plugin::LV2Plugin (const LV2Plugin &other)
 
54
        : Plugin (other)
 
55
        , _world(other._world)
 
56
{
 
57
        init (other._world, other._plugin, other._sample_rate);
 
58
 
 
59
        for (uint32_t i = 0; i < parameter_count(); ++i) {
 
60
                _control_data[i] = other._shadow_data[i];
 
61
                _shadow_data[i] = other._shadow_data[i];
 
62
        }
 
63
}
 
64
 
 
65
void
 
66
LV2Plugin::init (LV2World& world, SLV2Plugin plugin, nframes_t rate)
 
67
{
 
68
        _world = world;
 
69
        _plugin = plugin;
 
70
        _control_data = 0;
 
71
        _shadow_data = 0;
 
72
        _latency_control_port = 0;
 
73
        _was_activated = false;
 
74
 
 
75
        _instance = slv2_plugin_instantiate(plugin, rate, NULL);
 
76
        _name = slv2_plugin_get_name(plugin);
 
77
        assert(_name);
 
78
        _author = slv2_plugin_get_author_name(plugin);
 
79
 
 
80
        if (_instance == 0) {
 
81
                error << _("LV2: Failed to instantiate plugin ") << slv2_plugin_get_uri(plugin) << endl;
 
82
                throw failed_constructor();
 
83
        }
 
84
 
 
85
        if (slv2_plugin_has_feature(plugin, world.in_place_broken)) {
 
86
                error << string_compose(_("LV2: \"%1\" cannot be used, since it cannot do inplace processing"),
 
87
                                slv2_value_as_string(_name));
 
88
                slv2_value_free(_name);
 
89
                slv2_value_free(_author);
 
90
                throw failed_constructor();
 
91
        }
 
92
 
 
93
        _sample_rate = rate;
 
94
 
 
95
        const uint32_t num_ports = slv2_plugin_get_num_ports(plugin);
 
96
 
 
97
        _control_data = new float[num_ports];
 
98
        _shadow_data = new float[num_ports];
 
99
        _defaults = new float[num_ports];
 
100
 
 
101
        const bool latent = slv2_plugin_has_latency(plugin);
 
102
        uint32_t latency_port = (latent ? slv2_plugin_get_latency_port_index(plugin) : 0);
 
103
 
 
104
        for (uint32_t i = 0; i < num_ports; ++i) {
 
105
                if (parameter_is_control(i)) {
 
106
                        SLV2Port port = slv2_plugin_get_port_by_index(plugin, i);
 
107
                        SLV2Value def;
 
108
                        slv2_port_get_range(plugin, port, &def, NULL, NULL);
 
109
                        _defaults[i] = def ? slv2_value_as_float(def) : 0.0f;
 
110
                        slv2_value_free(def);
 
111
 
 
112
                        slv2_instance_connect_port (_instance, i, &_control_data[i]);
 
113
 
 
114
                        if (latent && i == latency_port) {
 
115
                                _latency_control_port = &_control_data[i];
 
116
                                *_latency_control_port = 0;
 
117
                        }
 
118
 
 
119
                        if (parameter_is_input(i)) {
 
120
                                _shadow_data[i] = default_value (i);
 
121
                        }
 
122
                } else {
 
123
                        _defaults[i] = 0.0f;
 
124
                }
 
125
        }
 
126
 
 
127
        Plugin::setup_controls ();
 
128
 
 
129
        latency_compute_run ();
 
130
}
 
131
 
 
132
LV2Plugin::~LV2Plugin ()
 
133
{
 
134
        deactivate ();
 
135
        cleanup ();
 
136
 
 
137
        GoingAway (); /* EMIT SIGNAL */
 
138
        
 
139
        slv2_instance_free(_instance);
 
140
        slv2_value_free(_name);
 
141
        slv2_value_free(_author);
 
142
 
 
143
        if (_control_data) {
 
144
                delete [] _control_data;
 
145
        }
 
146
 
 
147
        if (_shadow_data) {
 
148
                delete [] _shadow_data;
 
149
        }
 
150
}
 
151
 
 
152
string
 
153
LV2Plugin::unique_id() const
 
154
{
 
155
        return slv2_value_as_uri(slv2_plugin_get_uri(_plugin));
 
156
}
 
157
 
 
158
 
 
159
float
 
160
LV2Plugin::default_value (uint32_t port)
 
161
{
 
162
        return _defaults[port];
 
163
}       
 
164
 
 
165
void
 
166
LV2Plugin::set_parameter (uint32_t which, float val)
 
167
{
 
168
        if (which < slv2_plugin_get_num_ports(_plugin)) {
 
169
                _shadow_data[which] = val;
 
170
                ParameterChanged (which, val); /* EMIT SIGNAL */
 
171
 
 
172
                if (which < parameter_count() && controls[which]) {
 
173
                        controls[which]->Changed ();
 
174
                }
 
175
                
 
176
        } else {
 
177
                warning << string_compose (_("Illegal parameter number used with plugin \"%1\"."
 
178
                                "This is a bug in either Ardour or the LV2 plugin (%2)"),
 
179
                                name(), unique_id()) << endmsg;
 
180
        }
 
181
}
 
182
 
 
183
float
 
184
LV2Plugin::get_parameter (uint32_t which) const
 
185
{
 
186
        if (parameter_is_input(which)) {
 
187
                return (float) _shadow_data[which];
 
188
        } else {
 
189
                return (float) _control_data[which];
 
190
        }
 
191
        return 0.0f;
 
192
}
 
193
 
 
194
uint32_t
 
195
LV2Plugin::nth_parameter (uint32_t n, bool& ok) const
 
196
{
 
197
        uint32_t x, c;
 
198
 
 
199
        ok = false;
 
200
 
 
201
        for (c = 0, x = 0; x < slv2_plugin_get_num_ports(_plugin); ++x) {
 
202
                if (parameter_is_control (x)) {
 
203
                        if (c++ == n) {
 
204
                                ok = true;
 
205
                                return x;
 
206
                        }
 
207
                }
 
208
        }
 
209
        
 
210
        return 0;
 
211
}
 
212
 
 
213
XMLNode&
 
214
LV2Plugin::get_state()
 
215
{
 
216
        XMLNode *root = new XMLNode(state_node_name());
 
217
        XMLNode *child;
 
218
        char buf[16];
 
219
        LocaleGuard lg (X_("POSIX"));
 
220
 
 
221
        for (uint32_t i = 0; i < parameter_count(); ++i){
 
222
 
 
223
                if (parameter_is_input(i) && parameter_is_control(i)) {
 
224
                        child = new XMLNode("port");
 
225
                        snprintf(buf, sizeof(buf), "%u", i);
 
226
                        child->add_property("number", string(buf));
 
227
                        snprintf(buf, sizeof(buf), "%+f", _shadow_data[i]);
 
228
                        child->add_property("value", string(buf));
 
229
                        root->add_child_nocopy (*child);
 
230
 
 
231
                        if (i < controls.size() && controls[i]) {
 
232
                                root->add_child_nocopy (controls[i]->get_state());
 
233
                        }
 
234
                }
 
235
        }
 
236
 
 
237
        return *root;
 
238
}
 
239
 
 
240
bool
 
241
LV2Plugin::save_preset (string name)
 
242
{
 
243
        return Plugin::save_preset (name, "lv2");
 
244
}
 
245
 
 
246
int
 
247
LV2Plugin::set_state(const XMLNode& node)
 
248
{
 
249
        XMLNodeList nodes;
 
250
        XMLProperty *prop;
 
251
        XMLNodeConstIterator iter;
 
252
        XMLNode *child;
 
253
        const char *port;
 
254
        const char *data;
 
255
        uint32_t port_id;
 
256
        LocaleGuard lg (X_("POSIX"));
 
257
 
 
258
        if (node.name() != state_node_name()) {
 
259
                error << _("Bad node sent to LV2Plugin::set_state") << endmsg;
 
260
                return -1;
 
261
        }
 
262
 
 
263
        nodes = node.children ("port");
 
264
 
 
265
        for(iter = nodes.begin(); iter != nodes.end(); ++iter){
 
266
 
 
267
                child = *iter;
 
268
 
 
269
                if ((prop = child->property("number")) != 0) {
 
270
                        port = prop->value().c_str();
 
271
                } else {
 
272
                        warning << _("LV2: no lv2 port number") << endmsg;
 
273
                        continue;
 
274
                }
 
275
 
 
276
                if ((prop = child->property("value")) != 0) {
 
277
                        data = prop->value().c_str();
 
278
                } else {
 
279
                        warning << _("LV2: no lv2 port data") << endmsg;
 
280
                        continue;
 
281
                }
 
282
 
 
283
                sscanf (port, "%" PRIu32, &port_id);
 
284
                set_parameter (port_id, atof(data));
 
285
        }
 
286
        
 
287
        latency_compute_run ();
 
288
 
 
289
        return 0;
 
290
}
 
291
 
 
292
int
 
293
LV2Plugin::get_parameter_descriptor (uint32_t which, ParameterDescriptor& desc) const
 
294
{
 
295
        SLV2Port port = slv2_plugin_get_port_by_index(_plugin, which);
 
296
 
 
297
        SLV2Value def, min, max;
 
298
        slv2_port_get_range(_plugin, port, &def, &min, &max);
 
299
        
 
300
    desc.integer_step = slv2_port_has_property(_plugin, port, _world.integer);
 
301
    desc.toggled = slv2_port_has_property(_plugin, port, _world.toggled);
 
302
    desc.logarithmic = false; // TODO (LV2 extension)
 
303
    desc.sr_dependent = slv2_port_has_property(_plugin, port, _world.srate);
 
304
    desc.label = slv2_value_as_string(slv2_port_get_name(_plugin, port));
 
305
    desc.lower = min ? slv2_value_as_float(min) : 0.0f;
 
306
    desc.upper = max ? slv2_value_as_float(max) : 1.0f;
 
307
    desc.min_unbound = false; // TODO (LV2 extension)
 
308
    desc.max_unbound = false; // TODO (LV2 extension)
 
309
        
 
310
        if (desc.integer_step) {
 
311
                desc.step = 1.0;
 
312
                desc.smallstep = 0.1;
 
313
                desc.largestep = 10.0;
 
314
        } else {
 
315
                const float delta = desc.upper - desc.lower;
 
316
                desc.step = delta / 1000.0f;
 
317
                desc.smallstep = delta / 10000.0f;
 
318
                desc.largestep = delta/10.0f;
 
319
        }
 
320
 
 
321
        slv2_value_free(def);
 
322
        slv2_value_free(min);
 
323
        slv2_value_free(max);
 
324
 
 
325
        return 0;
 
326
}
 
327
 
 
328
 
 
329
string
 
330
LV2Plugin::describe_parameter (uint32_t which)
 
331
{
 
332
        if (which < parameter_count()) {
 
333
                SLV2Value name = slv2_port_get_name(_plugin,
 
334
                        slv2_plugin_get_port_by_index(_plugin, which));
 
335
                string ret(slv2_value_as_string(name));
 
336
                slv2_value_free(name);
 
337
                return ret;
 
338
        } else {
 
339
                return "??";
 
340
        }
 
341
}
 
342
 
 
343
nframes_t
 
344
LV2Plugin::latency () const
 
345
{
 
346
        if (_latency_control_port) {
 
347
                return (nframes_t) floor (*_latency_control_port);
 
348
        } else {
 
349
                return 0;
 
350
        }
 
351
}
 
352
 
 
353
set<uint32_t>
 
354
LV2Plugin::automatable () const
 
355
{
 
356
        set<uint32_t> ret;
 
357
 
 
358
        for (uint32_t i = 0; i < parameter_count(); ++i){
 
359
                if (parameter_is_input(i) && parameter_is_control(i)) {
 
360
                        ret.insert (ret.end(), i);
 
361
                }
 
362
        }
 
363
 
 
364
        return ret;
 
365
}
 
366
 
 
367
int
 
368
LV2Plugin::connect_and_run (vector<Sample*>& bufs, uint32_t nbufs, int32_t& in_index, int32_t& out_index, nframes_t nframes, nframes_t offset)
 
369
{
 
370
        uint32_t port_index;
 
371
        cycles_t then, now;
 
372
 
 
373
        port_index = 0;
 
374
 
 
375
        then = get_cycles ();
 
376
 
 
377
        while (port_index < parameter_count()) {
 
378
                if (parameter_is_audio(port_index)) {
 
379
                        if (parameter_is_input(port_index)) {
 
380
                                slv2_instance_connect_port(_instance, port_index,
 
381
                                                bufs[min((uint32_t)in_index, nbufs - 1)] + offset);
 
382
                                in_index++;
 
383
                        } else if (parameter_is_output(port_index)) {
 
384
                                slv2_instance_connect_port(_instance, port_index,
 
385
                                                bufs[min((uint32_t)out_index, nbufs - 1)] + offset);
 
386
                                out_index++;
 
387
                        }
 
388
                }
 
389
                port_index++;
 
390
        }
 
391
        
 
392
        run (nframes);
 
393
        now = get_cycles ();
 
394
        set_cycles ((uint32_t) (now - then));
 
395
 
 
396
        return 0;
 
397
}
 
398
 
 
399
bool
 
400
LV2Plugin::parameter_is_control (uint32_t param) const
 
401
{
 
402
        SLV2Port port = slv2_plugin_get_port_by_index(_plugin, param);
 
403
        return slv2_port_is_a(_plugin, port, _world.control_class);
 
404
}
 
405
 
 
406
bool
 
407
LV2Plugin::parameter_is_audio (uint32_t param) const
 
408
{
 
409
        SLV2Port port = slv2_plugin_get_port_by_index(_plugin, param);
 
410
        return slv2_port_is_a(_plugin, port, _world.audio_class);
 
411
}
 
412
 
 
413
bool
 
414
LV2Plugin::parameter_is_output (uint32_t param) const
 
415
{
 
416
        SLV2Port port = slv2_plugin_get_port_by_index(_plugin, param);
 
417
        return slv2_port_is_a(_plugin, port, _world.output_class);
 
418
}
 
419
 
 
420
bool
 
421
LV2Plugin::parameter_is_input (uint32_t param) const
 
422
{
 
423
        SLV2Port port = slv2_plugin_get_port_by_index(_plugin, param);
 
424
        return slv2_port_is_a(_plugin, port, _world.input_class);
 
425
}
 
426
 
 
427
void
 
428
LV2Plugin::print_parameter (uint32_t param, char *buf, uint32_t len) const
 
429
{
 
430
        if (buf && len) {
 
431
                if (param < parameter_count()) {
 
432
                        snprintf (buf, len, "%.3f", get_parameter (param));
 
433
                } else {
 
434
                        strcat (buf, "0");
 
435
                }
 
436
        }
 
437
}
 
438
 
 
439
void
 
440
LV2Plugin::run (nframes_t nframes)
 
441
{
 
442
        for (uint32_t i = 0; i < parameter_count(); ++i) {
 
443
                if (parameter_is_control(i) && parameter_is_input(i))  {
 
444
                        _control_data[i] = _shadow_data[i];
 
445
                }
 
446
        }
 
447
 
 
448
        slv2_instance_run(_instance, nframes);
 
449
}
 
450
 
 
451
void
 
452
LV2Plugin::latency_compute_run ()
 
453
{
 
454
        if (!_latency_control_port) {
 
455
                return;
 
456
        }
 
457
 
 
458
        /* we need to run the plugin so that it can set its latency
 
459
           parameter.
 
460
        */
 
461
        
 
462
        activate ();
 
463
        
 
464
        uint32_t port_index = 0;
 
465
        uint32_t in_index = 0;
 
466
        uint32_t out_index = 0;
 
467
        const nframes_t bufsize = 1024;
 
468
        float buffer[bufsize];
 
469
 
 
470
        memset(buffer,0,sizeof(float)*bufsize);
 
471
                
 
472
        /* Note that we've already required that plugins
 
473
           be able to handle in-place processing.
 
474
        */
 
475
        
 
476
        port_index = 0;
 
477
        
 
478
        while (port_index < parameter_count()) {
 
479
                if (parameter_is_audio (port_index)) {
 
480
                        if (parameter_is_input (port_index)) {
 
481
                                slv2_instance_connect_port (_instance, port_index, buffer);
 
482
                                in_index++;
 
483
                        } else if (parameter_is_output (port_index)) {
 
484
                                slv2_instance_connect_port (_instance, port_index, buffer);
 
485
                                out_index++;
 
486
                        }
 
487
                }
 
488
                port_index++;
 
489
        }
 
490
        
 
491
        run (bufsize);
 
492
        deactivate ();
 
493
}
 
494
 
 
495
LV2World::LV2World()
 
496
        : world(slv2_world_new())
 
497
{
 
498
        slv2_world_load_all(world);
 
499
        input_class = slv2_value_new_uri(world, SLV2_PORT_CLASS_INPUT);
 
500
        output_class = slv2_value_new_uri(world, SLV2_PORT_CLASS_OUTPUT);
 
501
        control_class = slv2_value_new_uri(world, SLV2_PORT_CLASS_CONTROL);
 
502
        audio_class = slv2_value_new_uri(world, SLV2_PORT_CLASS_AUDIO);
 
503
        in_place_broken = slv2_value_new_uri(world, SLV2_NAMESPACE_LV2 "inPlaceBroken");
 
504
        integer = slv2_value_new_uri(world, SLV2_NAMESPACE_LV2 "integer");
 
505
        toggled = slv2_value_new_uri(world, SLV2_NAMESPACE_LV2 "toggled");
 
506
        srate = slv2_value_new_uri(world, SLV2_NAMESPACE_LV2 "sampleRate");
 
507
}
 
508
 
 
509
LV2World::~LV2World()
 
510
{
 
511
        slv2_value_free(input_class);
 
512
        slv2_value_free(output_class);
 
513
        slv2_value_free(control_class);
 
514
        slv2_value_free(audio_class);
 
515
        slv2_value_free(in_place_broken);
 
516
}
 
517
 
 
518
LV2PluginInfo::LV2PluginInfo (void* lv2_world, void* slv2_plugin)
 
519
        : _lv2_world(lv2_world)
 
520
        , _slv2_plugin(slv2_plugin)
 
521
{
 
522
}
 
523
 
 
524
LV2PluginInfo::~LV2PluginInfo()
 
525
{
 
526
}
 
527
 
 
528
PluginPtr
 
529
LV2PluginInfo::load (Session& session)
 
530
{
 
531
        try {
 
532
                PluginPtr plugin;
 
533
 
 
534
                plugin.reset (new LV2Plugin (session.engine(), session,
 
535
                                *(LV2World*)_lv2_world, (SLV2Plugin)_slv2_plugin, session.frame_rate()));
 
536
 
 
537
                plugin->set_info(PluginInfoPtr(new LV2PluginInfo(*this)));
 
538
                return plugin;
 
539
        }
 
540
 
 
541
        catch (failed_constructor &err) {
 
542
                return PluginPtr ((Plugin*) 0);
 
543
        }       
 
544
        
 
545
        return PluginPtr();
 
546
}
 
547
 
 
548
PluginInfoList
 
549
LV2PluginInfo::discover (void* lv2_world)
 
550
{
 
551
        PluginInfoList plugs;
 
552
        
 
553
        LV2World* world = (LV2World*)lv2_world;
 
554
        SLV2Plugins plugins = slv2_world_get_all_plugins(world->world);
 
555
 
 
556
        for (unsigned i=0; i < slv2_plugins_size(plugins); ++i) {
 
557
                SLV2Plugin p = slv2_plugins_get_at(plugins, i);
 
558
                LV2PluginInfoPtr info (new LV2PluginInfo(lv2_world, p));
 
559
 
 
560
                SLV2Value name = slv2_plugin_get_name(p);
 
561
                info->name = string(slv2_value_as_string(name));
 
562
                slv2_value_free(name);
 
563
 
 
564
                SLV2PluginClass pclass = slv2_plugin_get_class(p);
 
565
                SLV2Value label = slv2_plugin_class_get_label(pclass);
 
566
                info->category = slv2_value_as_string(label);
 
567
 
 
568
                SLV2Value author_name = slv2_plugin_get_author_name(p);
 
569
                info->creator = author_name ? string(slv2_value_as_string(author_name)) : "Unknown";
 
570
                slv2_value_free(author_name);
 
571
 
 
572
                info->path = "/NOPATH"; // Meaningless for LV2
 
573
 
 
574
                info->n_inputs = slv2_plugin_get_num_ports_of_class(p,
 
575
                                world->input_class, world->audio_class, NULL);
 
576
                
 
577
                info->n_outputs = slv2_plugin_get_num_ports_of_class(p,
 
578
                                world->output_class, world->audio_class, NULL);
 
579
 
 
580
                info->unique_id = slv2_value_as_uri(slv2_plugin_get_uri(p));
 
581
                info->index = 0; // Meaningless for LV2
 
582
                
 
583
                plugs.push_back (info);
 
584
        }
 
585
 
 
586
        return plugs;
 
587
}
 
588