~ubuntu-branches/ubuntu/utopic/ardour3/utopic

« back to all changes in this revision

Viewing changes to libs/ardour/plugin_insert.cc

  • Committer: Package Import Robot
  • Author(s): Felipe Sateler
  • Date: 2013-09-21 19:05:02 UTC
  • Revision ID: package-import@ubuntu.com-20130921190502-8gsftrku6jnzhd7v
Tags: upstream-3.4~dfsg
ImportĀ upstreamĀ versionĀ 3.4~dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
    Copyright (C) 2000 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 <string>
 
25
 
 
26
#include "pbd/failed_constructor.h"
 
27
#include "pbd/xml++.h"
 
28
#include "pbd/convert.h"
 
29
 
 
30
#include "ardour/audio_buffer.h"
 
31
#include "ardour/automation_list.h"
 
32
#include "ardour/buffer_set.h"
 
33
#include "ardour/debug.h"
 
34
#include "ardour/event_type_map.h"
 
35
#include "ardour/ladspa_plugin.h"
 
36
#include "ardour/plugin.h"
 
37
#include "ardour/plugin_insert.h"
 
38
 
 
39
#ifdef LV2_SUPPORT
 
40
#include "ardour/lv2_plugin.h"
 
41
#endif
 
42
 
 
43
#ifdef WINDOWS_VST_SUPPORT
 
44
#include "ardour/windows_vst_plugin.h"
 
45
#endif
 
46
 
 
47
#ifdef LXVST_SUPPORT
 
48
#include "ardour/lxvst_plugin.h"
 
49
#endif
 
50
 
 
51
#ifdef AUDIOUNIT_SUPPORT
 
52
#include "ardour/audio_unit.h"
 
53
#endif
 
54
 
 
55
#include "ardour/session.h"
 
56
#include "ardour/types.h"
 
57
 
 
58
#include "i18n.h"
 
59
 
 
60
using namespace std;
 
61
using namespace ARDOUR;
 
62
using namespace PBD;
 
63
 
 
64
const string PluginInsert::port_automation_node_name = "PortAutomation";
 
65
 
 
66
PluginInsert::PluginInsert (Session& s, boost::shared_ptr<Plugin> plug)
 
67
        : Processor (s, (plug ? plug->name() : string ("toBeRenamed")))
 
68
        , _signal_analysis_collected_nframes(0)
 
69
        , _signal_analysis_collect_nframes_max(0)
 
70
{
 
71
        /* the first is the master */
 
72
 
 
73
        if (plug) {
 
74
                add_plugin (plug);
 
75
                create_automatable_parameters ();
 
76
        }
 
77
}
 
78
 
 
79
bool
 
80
PluginInsert::set_count (uint32_t num)
 
81
{
 
82
        bool require_state = !_plugins.empty();
 
83
 
 
84
        /* this is a bad idea.... we shouldn't do this while active.
 
85
           only a route holding their redirect_lock should be calling this
 
86
        */
 
87
 
 
88
        if (num == 0) {
 
89
                return false;
 
90
        } else if (num > _plugins.size()) {
 
91
                uint32_t diff = num - _plugins.size();
 
92
 
 
93
                for (uint32_t n = 0; n < diff; ++n) {
 
94
                        boost::shared_ptr<Plugin> p = plugin_factory (_plugins[0]);
 
95
                        add_plugin (p);
 
96
                        if (active ()) {
 
97
                                p->activate ();
 
98
                        }
 
99
 
 
100
                        if (require_state) {
 
101
                                /* XXX do something */
 
102
                        }
 
103
                }
 
104
 
 
105
        } else if (num < _plugins.size()) {
 
106
                uint32_t diff = _plugins.size() - num;
 
107
                for (uint32_t n= 0; n < diff; ++n) {
 
108
                        _plugins.pop_back();
 
109
                }
 
110
        }
 
111
 
 
112
        return true;
 
113
}
 
114
 
 
115
PluginInsert::~PluginInsert ()
 
116
{
 
117
}
 
118
 
 
119
void
 
120
PluginInsert::control_list_automation_state_changed (Evoral::Parameter which, AutoState s)
 
121
{
 
122
        if (which.type() != PluginAutomation)
 
123
                return;
 
124
 
 
125
        boost::shared_ptr<AutomationControl> c
 
126
                        = boost::dynamic_pointer_cast<AutomationControl>(control (which));
 
127
 
 
128
        if (c && s != Off) {
 
129
                _plugins[0]->set_parameter (which.id(), c->list()->eval (_session.transport_frame()));
 
130
        }
 
131
}
 
132
 
 
133
ChanCount
 
134
PluginInsert::output_streams() const
 
135
{
 
136
        assert (!_plugins.empty());
 
137
 
 
138
        PluginInfoPtr info = _plugins.front()->get_info();
 
139
 
 
140
        if (info->reconfigurable_io()) {
 
141
                ChanCount out = _plugins.front()->output_streams ();
 
142
                // DEBUG_TRACE (DEBUG::Processors, string_compose ("Plugin insert, reconfigur(able) output streams = %1\n", out));
 
143
                return out;
 
144
        } else {
 
145
                ChanCount out = info->n_outputs;
 
146
                // DEBUG_TRACE (DEBUG::Processors, string_compose ("Plugin insert, static output streams = %1 for %2 plugins\n", out, _plugins.size()));
 
147
                out.set_audio (out.n_audio() * _plugins.size());
 
148
                out.set_midi (out.n_midi() * _plugins.size() + midi_bypass.n_midi());
 
149
                return out;
 
150
        }
 
151
}
 
152
 
 
153
ChanCount
 
154
PluginInsert::input_streams() const
 
155
{
 
156
        assert (!_plugins.empty());
 
157
 
 
158
        ChanCount in;
 
159
 
 
160
        PluginInfoPtr info = _plugins.front()->get_info();
 
161
 
 
162
        if (info->reconfigurable_io()) {
 
163
                assert (_plugins.size() == 1);
 
164
                in = _plugins.front()->input_streams();
 
165
        } else {
 
166
                in = info->n_inputs;
 
167
        }
 
168
 
 
169
        DEBUG_TRACE (DEBUG::Processors, string_compose ("Plugin insert, input streams = %1, match using %2\n", in, _match.method));
 
170
        
 
171
        if (_match.method == Split) {
 
172
 
 
173
                /* we are splitting 1 processor input to multiple plugin inputs,
 
174
                   so we have a maximum of 1 stream of each type.
 
175
                */
 
176
                for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
 
177
                        if (in.get (*t) > 1) {
 
178
                                in.set (*t, 1);
 
179
                        }
 
180
                }
 
181
                return in;
 
182
 
 
183
        } else if (_match.method == Hide) {
 
184
 
 
185
                for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
 
186
                        in.set (*t, in.get (*t) - _match.hide.get (*t));
 
187
                }
 
188
                return in;
 
189
 
 
190
        } else {
 
191
                
 
192
                for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
 
193
                        in.set (*t, in.get (*t) * _plugins.size ());
 
194
                }
 
195
 
 
196
                return in;
 
197
        }
 
198
}
 
199
 
 
200
ChanCount
 
201
PluginInsert::natural_output_streams() const
 
202
{
 
203
        return _plugins[0]->get_info()->n_outputs;
 
204
}
 
205
 
 
206
ChanCount
 
207
PluginInsert::natural_input_streams() const
 
208
{
 
209
        return _plugins[0]->get_info()->n_inputs;
 
210
}
 
211
 
 
212
bool
 
213
PluginInsert::has_no_inputs() const
 
214
{
 
215
        return _plugins[0]->get_info()->n_inputs == ChanCount::ZERO;
 
216
}
 
217
 
 
218
bool
 
219
PluginInsert::has_no_audio_inputs() const
 
220
{
 
221
        return _plugins[0]->get_info()->n_inputs.n_audio() == 0;
 
222
}
 
223
 
 
224
bool
 
225
PluginInsert::is_midi_instrument() const
 
226
{
 
227
        /* XXX more finesse is possible here. VST plugins have a
 
228
           a specific "instrument" flag, for example.
 
229
         */
 
230
        PluginInfoPtr pi = _plugins[0]->get_info();
 
231
 
 
232
        return pi->n_inputs.n_midi() != 0 &&
 
233
                pi->n_outputs.n_audio() > 0;
 
234
}
 
235
 
 
236
void
 
237
PluginInsert::create_automatable_parameters ()
 
238
{
 
239
        assert (!_plugins.empty());
 
240
 
 
241
        set<Evoral::Parameter> a = _plugins.front()->automatable ();
 
242
 
 
243
        Plugin::ParameterDescriptor desc;
 
244
 
 
245
        for (set<Evoral::Parameter>::iterator i = a.begin(); i != a.end(); ++i) {
 
246
                if (i->type() == PluginAutomation) {
 
247
 
 
248
                        Evoral::Parameter param(*i);
 
249
 
 
250
                        _plugins.front()->get_parameter_descriptor(i->id(), desc);
 
251
 
 
252
                        /* the Parameter belonging to the actual plugin doesn't have its range set
 
253
                           but we want the Controllable related to this Parameter to have those limits.
 
254
                        */
 
255
 
 
256
                        param.set_range (desc.lower, desc.upper, _plugins.front()->default_value(i->id()), desc.toggled);
 
257
                        can_automate (param);
 
258
                        boost::shared_ptr<AutomationList> list(new AutomationList(param));
 
259
                        add_control (boost::shared_ptr<AutomationControl> (new PluginControl(this, param, list)));
 
260
                }
 
261
        }
 
262
}
 
263
 
 
264
void
 
265
PluginInsert::parameter_changed (uint32_t which, float val)
 
266
{
 
267
        boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter (PluginAutomation, 0, which));
 
268
 
 
269
        if (ac) {
 
270
                ac->set_value (val);
 
271
                
 
272
                Plugins::iterator i = _plugins.begin();
 
273
                
 
274
                /* don't set the first plugin, just all the slaves */
 
275
                
 
276
                if (i != _plugins.end()) {
 
277
                        ++i;
 
278
                        for (; i != _plugins.end(); ++i) {
 
279
                                (*i)->set_parameter (which, val);
 
280
                        }
 
281
                }
 
282
        }
 
283
}
 
284
 
 
285
int
 
286
PluginInsert::set_block_size (pframes_t nframes)
 
287
{
 
288
        int ret = 0;
 
289
        for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
 
290
                if ((*i)->set_block_size (nframes) != 0) {
 
291
                        ret = -1;
 
292
                }
 
293
        }
 
294
        return ret;
 
295
}
 
296
 
 
297
void
 
298
PluginInsert::activate ()
 
299
{
 
300
        for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
 
301
                (*i)->activate ();
 
302
        }
 
303
 
 
304
        Processor::activate ();
 
305
}
 
306
 
 
307
void
 
308
PluginInsert::deactivate ()
 
309
{
 
310
        Processor::deactivate ();
 
311
 
 
312
        for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
 
313
                (*i)->deactivate ();
 
314
        }
 
315
}
 
316
 
 
317
void
 
318
PluginInsert::flush ()
 
319
{
 
320
        for (vector<boost::shared_ptr<Plugin> >::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
 
321
                (*i)->flush ();
 
322
        }
 
323
}
 
324
 
 
325
void
 
326
PluginInsert::connect_and_run (BufferSet& bufs, pframes_t nframes, framecnt_t offset, bool with_auto, framepos_t now)
 
327
{
 
328
        // Calculate if, and how many frames we need to collect for analysis
 
329
        framecnt_t collect_signal_nframes = (_signal_analysis_collect_nframes_max -
 
330
                                             _signal_analysis_collected_nframes);
 
331
        if (nframes < collect_signal_nframes) { // we might not get all frames now
 
332
                collect_signal_nframes = nframes;
 
333
        }
 
334
 
 
335
        ChanCount const in_streams = input_streams ();
 
336
        ChanCount const out_streams = output_streams ();
 
337
 
 
338
        ChanMapping in_map (in_streams);
 
339
        ChanMapping out_map (out_streams);
 
340
        bool valid;
 
341
        if (_match.method == Split) {
 
342
                /* fix the input mapping so that we have maps for each of the plugin's inputs */
 
343
                in_map = ChanMapping (natural_input_streams ());
 
344
 
 
345
                /* copy the first stream's buffer contents to the others */
 
346
                /* XXX: audio only */
 
347
                uint32_t first_idx = in_map.get (DataType::AUDIO, 0, &valid);
 
348
                if (valid) {
 
349
                        Sample const * mono = bufs.get_audio (first_idx).data (offset);
 
350
                        for (uint32_t i = in_streams.n_audio(); i < natural_input_streams().n_audio(); ++i) {
 
351
                                memcpy (bufs.get_audio (in_map.get (DataType::AUDIO, i, &valid)).data (offset), mono, sizeof (Sample) * nframes);
 
352
                        }
 
353
                }
 
354
        }
 
355
 
 
356
        /* Note that we've already required that plugins
 
357
           be able to handle in-place processing.
 
358
        */
 
359
 
 
360
        if (with_auto) {
 
361
 
 
362
                uint32_t n = 0;
 
363
 
 
364
                for (Controls::iterator li = controls().begin(); li != controls().end(); ++li, ++n) {
 
365
 
 
366
                        boost::shared_ptr<AutomationControl> c
 
367
                                = boost::dynamic_pointer_cast<AutomationControl>(li->second);
 
368
 
 
369
                        if (c->parameter().type() == PluginAutomation && c->automation_playback()) {
 
370
                                bool valid;
 
371
 
 
372
                                const float val = c->list()->rt_safe_eval (now, valid);
 
373
 
 
374
                                if (valid) {
 
375
                                        c->set_value(val);
 
376
                                }
 
377
 
 
378
                        }
 
379
                }
 
380
        }
 
381
 
 
382
        if (collect_signal_nframes > 0) {
 
383
                // collect input
 
384
                //std::cerr << "collect input, bufs " << bufs.count().n_audio() << " count,  " << bufs.available().n_audio() << " available" << std::endl;
 
385
                //std::cerr << "               streams " << input_streams().n_audio() << std::endl;
 
386
                //std::cerr << "filling buffer with " << collect_signal_nframes << " frames at " << _signal_analysis_collected_nframes << std::endl;
 
387
 
 
388
                _signal_analysis_inputs.set_count(input_streams());
 
389
 
 
390
                for (uint32_t i = 0; i < input_streams().n_audio(); ++i) {
 
391
                        _signal_analysis_inputs.get_audio(i).read_from(
 
392
                                bufs.get_audio(i),
 
393
                                collect_signal_nframes,
 
394
                                _signal_analysis_collected_nframes); // offset is for target buffer
 
395
                }
 
396
 
 
397
        }
 
398
 
 
399
        for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
 
400
                (*i)->connect_and_run(bufs, in_map, out_map, nframes, offset);
 
401
                for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
 
402
                        in_map.offset_to(*t, natural_input_streams().get(*t));
 
403
                        out_map.offset_to(*t, natural_output_streams().get(*t));
 
404
                }
 
405
        }
 
406
 
 
407
        if (collect_signal_nframes > 0) {
 
408
                // collect output
 
409
                //std::cerr << "       output, bufs " << bufs.count().n_audio() << " count,  " << bufs.available().n_audio() << " available" << std::endl;
 
410
                //std::cerr << "               streams " << output_streams().n_audio() << std::endl;
 
411
 
 
412
                _signal_analysis_outputs.set_count(output_streams());
 
413
 
 
414
                for (uint32_t i = 0; i < output_streams().n_audio(); ++i) {
 
415
                        _signal_analysis_outputs.get_audio(i).read_from(
 
416
                                bufs.get_audio(i),
 
417
                                collect_signal_nframes,
 
418
                                _signal_analysis_collected_nframes); // offset is for target buffer
 
419
                }
 
420
 
 
421
                _signal_analysis_collected_nframes += collect_signal_nframes;
 
422
                assert(_signal_analysis_collected_nframes <= _signal_analysis_collect_nframes_max);
 
423
 
 
424
                if (_signal_analysis_collected_nframes == _signal_analysis_collect_nframes_max) {
 
425
                        _signal_analysis_collect_nframes_max = 0;
 
426
                        _signal_analysis_collected_nframes   = 0;
 
427
 
 
428
                        AnalysisDataGathered(&_signal_analysis_inputs,
 
429
                                             &_signal_analysis_outputs);
 
430
                }
 
431
        }
 
432
        /* leave remaining channel buffers alone */
 
433
}
 
434
 
 
435
void
 
436
PluginInsert::silence (framecnt_t nframes)
 
437
{
 
438
        if (!active ()) {
 
439
                return;
 
440
        }
 
441
 
 
442
        ChanMapping in_map(input_streams());
 
443
        ChanMapping out_map(output_streams());
 
444
 
 
445
        if (_match.method == Split) {
 
446
                /* fix the input mapping so that we have maps for each of the plugin's inputs */
 
447
                in_map = ChanMapping (natural_input_streams ());
 
448
        }
 
449
 
 
450
        for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
 
451
                (*i)->connect_and_run (_session.get_scratch_buffers ((*i)->get_info()->n_inputs, true), in_map, out_map, nframes, 0);
 
452
        }
 
453
}
 
454
 
 
455
void
 
456
PluginInsert::run (BufferSet& bufs, framepos_t /*start_frame*/, framepos_t /*end_frame*/, pframes_t nframes, bool)
 
457
{
 
458
        if (_pending_active) {
 
459
                /* run as normal if we are active or moving from inactive to active */
 
460
 
 
461
                if (_session.transport_rolling()) {
 
462
                        automation_run (bufs, nframes);
 
463
                } else {
 
464
                        connect_and_run (bufs, nframes, 0, false);
 
465
                }
 
466
 
 
467
        } else {
 
468
                if (has_no_audio_inputs()) {
 
469
 
 
470
                        /* silence all (audio) outputs. Should really declick
 
471
                         * at the transitions of "active"
 
472
                         */
 
473
 
 
474
                        uint32_t out = output_streams().n_audio ();
 
475
 
 
476
                        for (uint32_t n = 0; n < out; ++n) {
 
477
                                bufs.get_audio (n).silence (nframes);
 
478
                        }
 
479
 
 
480
                        bufs.count().set_audio (out);
 
481
 
 
482
                } else {
 
483
 
 
484
                        /* does this need to be done with MIDI? it appears not */
 
485
 
 
486
                        uint32_t in = input_streams ().n_audio ();
 
487
                        uint32_t out = output_streams().n_audio ();
 
488
 
 
489
                        if (out > in) {
 
490
 
 
491
                                /* not active, but something has make up for any channel count increase */
 
492
                                
 
493
                                for (uint32_t n = out - in; n < out; ++n) {
 
494
                                        memcpy (bufs.get_audio (n).data(), bufs.get_audio(in - 1).data(), sizeof (Sample) * nframes);
 
495
                                }
 
496
                        }
 
497
 
 
498
                        bufs.count().set_audio (out);
 
499
                }
 
500
        }
 
501
 
 
502
        _active = _pending_active;
 
503
 
 
504
        /* we have no idea whether the plugin generated silence or not, so mark
 
505
         * all buffers appropriately.
 
506
         */
 
507
 
 
508
        bufs.set_is_silent (false);
 
509
}
 
510
 
 
511
void
 
512
PluginInsert::set_parameter (Evoral::Parameter param, float val)
 
513
{
 
514
        if (param.type() != PluginAutomation) {
 
515
                return;
 
516
        }
 
517
 
 
518
        /* the others will be set from the event triggered by this */
 
519
 
 
520
        _plugins[0]->set_parameter (param.id(), val);
 
521
 
 
522
        boost::shared_ptr<AutomationControl> ac
 
523
                        = boost::dynamic_pointer_cast<AutomationControl>(control(param));
 
524
 
 
525
        if (ac) {
 
526
                ac->set_value(val);
 
527
        } else {
 
528
                warning << "set_parameter called for nonexistant parameter "
 
529
                        << EventTypeMap::instance().to_symbol(param) << endmsg;
 
530
        }
 
531
 
 
532
        _session.set_dirty();
 
533
}
 
534
 
 
535
float
 
536
PluginInsert::get_parameter (Evoral::Parameter param)
 
537
{
 
538
        if (param.type() != PluginAutomation) {
 
539
                return 0.0;
 
540
        } else {
 
541
                assert (!_plugins.empty ());
 
542
                return _plugins[0]->get_parameter (param.id());
 
543
        }
 
544
}
 
545
 
 
546
void
 
547
PluginInsert::automation_run (BufferSet& bufs, pframes_t nframes)
 
548
{
 
549
        Evoral::ControlEvent next_event (0, 0.0f);
 
550
        framepos_t now = _session.transport_frame ();
 
551
        framepos_t end = now + nframes;
 
552
        framecnt_t offset = 0;
 
553
 
 
554
        Glib::Threads::Mutex::Lock lm (control_lock(), Glib::Threads::TRY_LOCK);
 
555
 
 
556
        if (!lm.locked()) {
 
557
                connect_and_run (bufs, nframes, offset, false);
 
558
                return;
 
559
        }
 
560
 
 
561
        if (!find_next_event (now, end, next_event) || requires_fixed_sized_buffers()) {
 
562
 
 
563
                /* no events have a time within the relevant range */
 
564
 
 
565
                connect_and_run (bufs, nframes, offset, true, now);
 
566
                return;
 
567
        }
 
568
 
 
569
        while (nframes) {
 
570
 
 
571
                framecnt_t cnt = min (((framecnt_t) ceil (next_event.when) - now), (framecnt_t) nframes);
 
572
 
 
573
                connect_and_run (bufs, cnt, offset, true, now);
 
574
 
 
575
                nframes -= cnt;
 
576
                offset += cnt;
 
577
                now += cnt;
 
578
 
 
579
                if (!find_next_event (now, end, next_event)) {
 
580
                        break;
 
581
                }
 
582
        }
 
583
 
 
584
        /* cleanup anything that is left to do */
 
585
 
 
586
        if (nframes) {
 
587
                connect_and_run (bufs, nframes, offset, true, now);
 
588
        }
 
589
}
 
590
 
 
591
float
 
592
PluginInsert::default_parameter_value (const Evoral::Parameter& param)
 
593
{
 
594
        if (param.type() != PluginAutomation)
 
595
                return 1.0;
 
596
 
 
597
        if (_plugins.empty()) {
 
598
                fatal << _("programming error: ") << X_("PluginInsert::default_parameter_value() called with no plugin")
 
599
                      << endmsg;
 
600
                /*NOTREACHED*/
 
601
        }
 
602
 
 
603
        return _plugins[0]->default_value (param.id());
 
604
}
 
605
 
 
606
boost::shared_ptr<Plugin>
 
607
PluginInsert::plugin_factory (boost::shared_ptr<Plugin> other)
 
608
{
 
609
        boost::shared_ptr<LadspaPlugin> lp;
 
610
#ifdef LV2_SUPPORT
 
611
        boost::shared_ptr<LV2Plugin> lv2p;
 
612
#endif
 
613
#ifdef WINDOWS_VST_SUPPORT
 
614
        boost::shared_ptr<WindowsVSTPlugin> vp;
 
615
#endif
 
616
#ifdef LXVST_SUPPORT
 
617
        boost::shared_ptr<LXVSTPlugin> lxvp;
 
618
#endif
 
619
#ifdef AUDIOUNIT_SUPPORT
 
620
        boost::shared_ptr<AUPlugin> ap;
 
621
#endif
 
622
 
 
623
        if ((lp = boost::dynamic_pointer_cast<LadspaPlugin> (other)) != 0) {
 
624
                return boost::shared_ptr<Plugin> (new LadspaPlugin (*lp));
 
625
#ifdef LV2_SUPPORT
 
626
        } else if ((lv2p = boost::dynamic_pointer_cast<LV2Plugin> (other)) != 0) {
 
627
                return boost::shared_ptr<Plugin> (new LV2Plugin (*lv2p));
 
628
#endif
 
629
#ifdef WINDOWS_VST_SUPPORT
 
630
        } else if ((vp = boost::dynamic_pointer_cast<WindowsVSTPlugin> (other)) != 0) {
 
631
                return boost::shared_ptr<Plugin> (new WindowsVSTPlugin (*vp));
 
632
#endif
 
633
#ifdef LXVST_SUPPORT
 
634
        } else if ((lxvp = boost::dynamic_pointer_cast<LXVSTPlugin> (other)) != 0) {
 
635
                return boost::shared_ptr<Plugin> (new LXVSTPlugin (*lxvp));
 
636
#endif
 
637
#ifdef AUDIOUNIT_SUPPORT
 
638
        } else if ((ap = boost::dynamic_pointer_cast<AUPlugin> (other)) != 0) {
 
639
                return boost::shared_ptr<Plugin> (new AUPlugin (*ap));
 
640
#endif
 
641
        }
 
642
 
 
643
        fatal << string_compose (_("programming error: %1"),
 
644
                          X_("unknown plugin type in PluginInsert::plugin_factory"))
 
645
              << endmsg;
 
646
        /*NOTREACHED*/
 
647
        return boost::shared_ptr<Plugin> ((Plugin*) 0);
 
648
}
 
649
 
 
650
bool
 
651
PluginInsert::configure_io (ChanCount in, ChanCount out)
 
652
{
 
653
        Match old_match = _match;
 
654
 
 
655
        /* set the matching method and number of plugins that we will use to meet this configuration */
 
656
        _match = private_can_support_io_configuration (in, out);
 
657
        if (set_count (_match.plugins) == false) {
 
658
                return false;
 
659
        }
 
660
 
 
661
        /* a signal needs emitting if we start or stop splitting */
 
662
        if (old_match.method != _match.method && (old_match.method == Split || _match.method == Split)) {
 
663
                SplittingChanged (); /* EMIT SIGNAL */
 
664
        }
 
665
 
 
666
        /* configure plugins */
 
667
        switch (_match.method) {
 
668
        case Split:
 
669
        case Hide:
 
670
                if (_plugins.front()->configure_io (_plugins.front()->get_info()->n_inputs, out)) {
 
671
                        return false;
 
672
                }
 
673
                break;
 
674
 
 
675
        default:
 
676
                if (_plugins.front()->configure_io (in, out) == false) {
 
677
                        return false;
 
678
                }
 
679
                break;
 
680
        }
 
681
 
 
682
        // we don't know the analysis window size, so we must work with the
 
683
        // current buffer size here. each request for data fills in these
 
684
        // buffers and the analyser makes sure it gets enough data for the
 
685
        // analysis window
 
686
        session().ensure_buffer_set (_signal_analysis_inputs, in);
 
687
        //_signal_analysis_inputs.set_count (in);
 
688
 
 
689
        session().ensure_buffer_set (_signal_analysis_outputs, out);
 
690
        //_signal_analysis_outputs.set_count (out);
 
691
 
 
692
        // std::cerr << "set counts to i" << in.n_audio() << "/o" << out.n_audio() << std::endl;
 
693
 
 
694
        return Processor::configure_io (in, out);
 
695
}
 
696
 
 
697
/** Decide whether this PluginInsert can support a given IO configuration.
 
698
 *  To do this, we run through a set of possible solutions in rough order of
 
699
 *  preference.
 
700
 *
 
701
 *  @param in Required input channel count.
 
702
 *  @param out Filled in with the output channel count if we return true.
 
703
 *  @return true if the given IO configuration can be supported.
 
704
 */
 
705
bool
 
706
PluginInsert::can_support_io_configuration (const ChanCount& in, ChanCount& out)
 
707
{
 
708
        return private_can_support_io_configuration (in, out).method != Impossible;
 
709
}
 
710
 
 
711
/** A private version of can_support_io_configuration which returns the method
 
712
 *  by which the configuration can be matched, rather than just whether or not
 
713
 *  it can be.
 
714
 */
 
715
PluginInsert::Match
 
716
PluginInsert::private_can_support_io_configuration (ChanCount const & inx, ChanCount& out)
 
717
{
 
718
        PluginInfoPtr info = _plugins.front()->get_info();
 
719
        ChanCount in; in += inx;
 
720
        midi_bypass.reset();
 
721
 
 
722
        if (info->reconfigurable_io()) {
 
723
                /* Plugin has flexible I/O, so delegate to it */
 
724
                bool const r = _plugins.front()->can_support_io_configuration (in, out);
 
725
                if (!r) {
 
726
                        return Match (Impossible, 0);
 
727
                }
 
728
 
 
729
                return Match (Delegate, 1);
 
730
        }
 
731
 
 
732
        ChanCount inputs  = info->n_inputs;
 
733
        ChanCount outputs = info->n_outputs;
 
734
 
 
735
        if (in.get(DataType::MIDI) == 1 && outputs.get(DataType::MIDI) == 0) {
 
736
                DEBUG_TRACE ( DEBUG::Processors, string_compose ("bypassing midi-data around %1\n", name()));
 
737
                midi_bypass.set(DataType::MIDI, 1);
 
738
        }
 
739
        if (in.get(DataType::MIDI) == 1 && inputs.get(DataType::MIDI) == 0) {
 
740
                DEBUG_TRACE ( DEBUG::Processors, string_compose ("hiding midi-port from plugin %1\n", name()));
 
741
                in.set(DataType::MIDI, 0);
 
742
        }
 
743
 
 
744
        bool no_inputs = true;
 
745
        for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
 
746
                if (inputs.get (*t) != 0) {
 
747
                        no_inputs = false;
 
748
                        break;
 
749
                }
 
750
        }
 
751
 
 
752
        if (no_inputs) {
 
753
                /* no inputs so we can take any input configuration since we throw it away */
 
754
                out = outputs + midi_bypass;
 
755
                return Match (NoInputs, 1);
 
756
        }
 
757
 
 
758
        /* Plugin inputs match requested inputs exactly */
 
759
        if (inputs == in) {
 
760
                out = outputs + midi_bypass;
 
761
                return Match (ExactMatch, 1);
 
762
        }
 
763
 
 
764
        /* We may be able to run more than one copy of the plugin within this insert
 
765
           to cope with the insert having more inputs than the plugin.
 
766
           We allow replication only for plugins with either zero or 1 inputs and outputs
 
767
           for every valid data type.
 
768
        */
 
769
        
 
770
        uint32_t f             = 0;
 
771
        bool     can_replicate = true;
 
772
        for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
 
773
 
 
774
                uint32_t nin = inputs.get (*t);
 
775
 
 
776
                // No inputs of this type
 
777
                if (nin == 0 && in.get(*t) == 0) {
 
778
                        continue;
 
779
                }
 
780
 
 
781
                if (nin != 1 || outputs.get (*t) != 1) {
 
782
                        can_replicate = false;
 
783
                        break;
 
784
                }
 
785
 
 
786
                // Potential factor not set yet
 
787
                if (f == 0) {
 
788
                        f = in.get(*t) / nin;
 
789
                }
 
790
 
 
791
                // Factor for this type does not match another type, can not replicate
 
792
                if (f != (in.get(*t) / nin)) {
 
793
                        can_replicate = false;
 
794
                        break;
 
795
                }
 
796
        }
 
797
 
 
798
        if (can_replicate) {
 
799
                for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
 
800
                        out.set (*t, outputs.get(*t) * f);
 
801
                }
 
802
                out += midi_bypass;
 
803
                return Match (Replicate, f);
 
804
        }
 
805
 
 
806
        /* If the processor has exactly one input of a given type, and
 
807
           the plugin has more, we can feed the single processor input
 
808
           to some or all of the plugin inputs.  This is rather
 
809
           special-case-y, but the 1-to-many case is by far the
 
810
           simplest.  How do I split thy 2 processor inputs to 3
 
811
           plugin inputs?  Let me count the ways ...
 
812
        */
 
813
 
 
814
        bool can_split = true;
 
815
        for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
 
816
 
 
817
                bool const can_split_type = (in.get (*t) == 1 && inputs.get (*t) > 1);
 
818
                bool const nothing_to_do_for_type = (in.get (*t) == 0 && inputs.get (*t) == 0);
 
819
 
 
820
                if (!can_split_type && !nothing_to_do_for_type) {
 
821
                        can_split = false;
 
822
                }
 
823
        }
 
824
 
 
825
        if (can_split) {
 
826
                out = outputs + midi_bypass;
 
827
                return Match (Split, 1);
 
828
        }
 
829
 
 
830
        /* If the plugin has more inputs than we want, we can `hide' some of them
 
831
           by feeding them silence.
 
832
        */
 
833
 
 
834
        bool could_hide = false;
 
835
        bool cannot_hide = false;
 
836
        ChanCount hide_channels;
 
837
        
 
838
        for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
 
839
                if (inputs.get(*t) > in.get(*t)) {
 
840
                        /* there is potential to hide, since the plugin has more inputs of type t than the insert */
 
841
                        hide_channels.set (*t, inputs.get(*t) - in.get(*t));
 
842
                        could_hide = true;
 
843
                } else if (inputs.get(*t) < in.get(*t)) {
 
844
                        /* we definitely cannot hide, since the plugin has fewer inputs of type t than the insert */
 
845
                        cannot_hide = true;
 
846
                }
 
847
        }
 
848
 
 
849
        if (could_hide && !cannot_hide) {
 
850
                out = outputs + midi_bypass;
 
851
                return Match (Hide, 1, hide_channels);
 
852
        }
 
853
 
 
854
        midi_bypass.reset();
 
855
        return Match (Impossible, 0);
 
856
}
 
857
 
 
858
XMLNode&
 
859
PluginInsert::get_state ()
 
860
{
 
861
        return state (true);
 
862
}
 
863
 
 
864
XMLNode&
 
865
PluginInsert::state (bool full)
 
866
{
 
867
        XMLNode& node = Processor::state (full);
 
868
 
 
869
        node.add_property("type", _plugins[0]->state_node_name());
 
870
        node.add_property("unique-id", _plugins[0]->unique_id());
 
871
        node.add_property("count", string_compose("%1", _plugins.size()));
 
872
        node.add_child_nocopy (_plugins[0]->get_state());
 
873
 
 
874
        for (Controls::iterator c = controls().begin(); c != controls().end(); ++c) {
 
875
                boost::shared_ptr<AutomationControl> ac = boost::dynamic_pointer_cast<AutomationControl> ((*c).second);
 
876
                if (ac) {
 
877
                        node.add_child_nocopy (ac->get_state());
 
878
                }
 
879
        }
 
880
 
 
881
        return node;
 
882
}
 
883
 
 
884
void
 
885
PluginInsert::set_control_ids (const XMLNode& node, int version)
 
886
{
 
887
        const XMLNodeList& nlist = node.children();
 
888
        XMLNodeConstIterator iter;
 
889
        set<Evoral::Parameter>::const_iterator p;
 
890
 
 
891
        for (iter = nlist.begin(); iter != nlist.end(); ++iter) {
 
892
                if ((*iter)->name() == Controllable::xml_node_name) {
 
893
                        const XMLProperty* prop;
 
894
 
 
895
                        if ((prop = (*iter)->property (X_("parameter"))) != 0) {
 
896
                                uint32_t p = atoi (prop->value());
 
897
 
 
898
                                /* this may create the new controllable */
 
899
 
 
900
                                boost::shared_ptr<Evoral::Control> c = control (Evoral::Parameter (PluginAutomation, 0, p));
 
901
 
 
902
#ifndef NO_PLUGIN_STATE
 
903
                                if (!c) {
 
904
                                        continue;
 
905
                                }
 
906
                                boost::shared_ptr<AutomationControl> ac = boost::dynamic_pointer_cast<AutomationControl> (c);
 
907
                                if (ac) {
 
908
                                        ac->set_state (**iter, version);
 
909
                                }
 
910
#endif
 
911
                        }
 
912
                }
 
913
        }
 
914
}
 
915
 
 
916
int
 
917
PluginInsert::set_state(const XMLNode& node, int version)
 
918
{
 
919
        XMLNodeList nlist = node.children();
 
920
        XMLNodeIterator niter;
 
921
        XMLPropertyList plist;
 
922
        const XMLProperty *prop;
 
923
        ARDOUR::PluginType type;
 
924
 
 
925
        if ((prop = node.property ("type")) == 0) {
 
926
                error << _("XML node describing plugin is missing the `type' field") << endmsg;
 
927
                return -1;
 
928
        }
 
929
 
 
930
        if (prop->value() == X_("ladspa") || prop->value() == X_("Ladspa")) { /* handle old school sessions */
 
931
                type = ARDOUR::LADSPA;
 
932
        } else if (prop->value() == X_("lv2")) {
 
933
                type = ARDOUR::LV2;
 
934
        } else if (prop->value() == X_("windows-vst")) {
 
935
                type = ARDOUR::Windows_VST;
 
936
        } else if (prop->value() == X_("lxvst")) {
 
937
                type = ARDOUR::LXVST;
 
938
        } else if (prop->value() == X_("audiounit")) {
 
939
                type = ARDOUR::AudioUnit;
 
940
        } else {
 
941
                error << string_compose (_("unknown plugin type %1 in plugin insert state"),
 
942
                                  prop->value())
 
943
                      << endmsg;
 
944
                return -1;
 
945
        }
 
946
 
 
947
        prop = node.property ("unique-id");
 
948
 
 
949
        if (prop == 0) {
 
950
#ifdef WINDOWS_VST_SUPPORT
 
951
                /* older sessions contain VST plugins with only an "id" field.
 
952
                 */
 
953
 
 
954
                if (type == ARDOUR::Windows_VST) {
 
955
                        prop = node.property ("id");
 
956
                }
 
957
#endif
 
958
 
 
959
#ifdef LXVST_SUPPORT
 
960
                /*There shouldn't be any older sessions with linuxVST support.. but anyway..*/
 
961
 
 
962
                if (type == ARDOUR::LXVST) {
 
963
                        prop = node.property ("id");
 
964
                }
 
965
#endif
 
966
                /* recheck  */
 
967
 
 
968
                if (prop == 0) {
 
969
                        error << _("Plugin has no unique ID field") << endmsg;
 
970
                        return -1;
 
971
                }
 
972
        }
 
973
 
 
974
        boost::shared_ptr<Plugin> plugin = find_plugin (_session, prop->value(), type);
 
975
 
 
976
        if (plugin == 0) {
 
977
                error << string_compose(
 
978
                        _("Found a reference to a plugin (\"%1\") that is unknown.\n"
 
979
                          "Perhaps it was removed or moved since it was last used."),
 
980
                        prop->value())
 
981
                      << endmsg;
 
982
                return -1;
 
983
        }
 
984
 
 
985
        // The name of the PluginInsert comes from the plugin, nothing else
 
986
        _name = plugin->get_info()->name;
 
987
 
 
988
        uint32_t count = 1;
 
989
 
 
990
        // Processor::set_state() will set this, but too late
 
991
        // for it to be available when setting up plugin
 
992
        // state. We can't call Processor::set_state() until
 
993
        // the plugins themselves are created and added.
 
994
 
 
995
        set_id (node);
 
996
 
 
997
        if (_plugins.empty()) {
 
998
                /* if we are adding the first plugin, we will need to set
 
999
                   up automatable controls.
 
1000
                */
 
1001
                add_plugin (plugin);
 
1002
                create_automatable_parameters ();
 
1003
                set_control_ids (node, version);
 
1004
        }
 
1005
 
 
1006
        if ((prop = node.property ("count")) != 0) {
 
1007
                sscanf (prop->value().c_str(), "%u", &count);
 
1008
        }
 
1009
 
 
1010
        if (_plugins.size() != count) {
 
1011
                for (uint32_t n = 1; n < count; ++n) {
 
1012
                        add_plugin (plugin_factory (plugin));
 
1013
                }
 
1014
        }
 
1015
 
 
1016
        Processor::set_state (node, version);
 
1017
 
 
1018
        for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
 
1019
 
 
1020
                /* find the node with the type-specific node name ("lv2", "ladspa", etc)
 
1021
                   and set all plugins to the same state.
 
1022
                */
 
1023
 
 
1024
                if ((*niter)->name() == plugin->state_node_name()) {
 
1025
 
 
1026
                        plugin->set_state (**niter, version);
 
1027
 
 
1028
                        for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
 
1029
                                (*i)->set_state (**niter, version);
 
1030
                        }
 
1031
 
 
1032
                        break;
 
1033
                }
 
1034
        }
 
1035
 
 
1036
        if (version < 3000) {
 
1037
 
 
1038
                /* Only 2.X sessions need a call to set_parameter_state() - in 3.X and above
 
1039
                   this is all handled by Automatable
 
1040
                */
 
1041
 
 
1042
                for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
 
1043
                        if ((*niter)->name() == "Redirect") {
 
1044
                                /* XXX do we need to tackle placement? i think not (pd; oct 16 2009) */
 
1045
                                Processor::set_state (**niter, version);
 
1046
                                break;
 
1047
                        }
 
1048
                }
 
1049
 
 
1050
                set_parameter_state_2X (node, version);
 
1051
        }
 
1052
 
 
1053
        for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
 
1054
                if (active()) {
 
1055
                        (*i)->activate ();
 
1056
                } else {
 
1057
                        (*i)->deactivate ();
 
1058
                }
 
1059
        }
 
1060
 
 
1061
        return 0;
 
1062
}
 
1063
 
 
1064
void
 
1065
PluginInsert::set_parameter_state_2X (const XMLNode& node, int version)
 
1066
{
 
1067
        XMLNodeList nlist = node.children();
 
1068
        XMLNodeIterator niter;
 
1069
 
 
1070
        /* look for port automation node */
 
1071
 
 
1072
        for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
 
1073
 
 
1074
                if ((*niter)->name() != port_automation_node_name) {
 
1075
                        continue;
 
1076
                }
 
1077
 
 
1078
                XMLNodeList cnodes;
 
1079
                XMLProperty *cprop;
 
1080
                XMLNodeConstIterator iter;
 
1081
                XMLNode *child;
 
1082
                const char *port;
 
1083
                uint32_t port_id;
 
1084
 
 
1085
                cnodes = (*niter)->children ("port");
 
1086
 
 
1087
                for (iter = cnodes.begin(); iter != cnodes.end(); ++iter){
 
1088
 
 
1089
                        child = *iter;
 
1090
 
 
1091
                        if ((cprop = child->property("number")) != 0) {
 
1092
                                port = cprop->value().c_str();
 
1093
                        } else {
 
1094
                                warning << _("PluginInsert: Auto: no ladspa port number") << endmsg;
 
1095
                                continue;
 
1096
                        }
 
1097
 
 
1098
                        sscanf (port, "%" PRIu32, &port_id);
 
1099
 
 
1100
                        if (port_id >= _plugins[0]->parameter_count()) {
 
1101
                                warning << _("PluginInsert: Auto: port id out of range") << endmsg;
 
1102
                                continue;
 
1103
                        }
 
1104
 
 
1105
                        boost::shared_ptr<AutomationControl> c = boost::dynamic_pointer_cast<AutomationControl>(
 
1106
                                        control(Evoral::Parameter(PluginAutomation, 0, port_id), true));
 
1107
 
 
1108
                        if (c) {
 
1109
                                if (!child->children().empty()) {
 
1110
                                        c->alist()->set_state (*child->children().front(), version);
 
1111
 
 
1112
                                        /* In some cases 2.X saves lists with min_yval and max_yval
 
1113
                                           being FLT_MIN and FLT_MAX respectively.  This causes problems
 
1114
                                           in A3 because these min/max values are used to compute
 
1115
                                           where GUI control points should be drawn.  If we see such
 
1116
                                           values, `correct' them to the min/max of the appropriate
 
1117
                                           parameter.
 
1118
                                        */
 
1119
 
 
1120
                                        float min_y = c->alist()->get_min_y ();
 
1121
                                        float max_y = c->alist()->get_max_y ();
 
1122
 
 
1123
                                        Plugin::ParameterDescriptor desc;
 
1124
                                        _plugins.front()->get_parameter_descriptor (port_id, desc);
 
1125
 
 
1126
                                        if (min_y == FLT_MIN) {
 
1127
                                                min_y = desc.lower;
 
1128
                                        }
 
1129
 
 
1130
                                        if (max_y == FLT_MAX) {
 
1131
                                                max_y = desc.upper;
 
1132
                                        }
 
1133
 
 
1134
                                        c->alist()->set_yrange (min_y, max_y);
 
1135
                                }
 
1136
                        } else {
 
1137
                                error << string_compose (_("PluginInsert: automatable control %1 not found - ignored"), port_id) << endmsg;
 
1138
                        }
 
1139
                }
 
1140
 
 
1141
                /* done */
 
1142
 
 
1143
                break;
 
1144
        }
 
1145
}
 
1146
 
 
1147
 
 
1148
string
 
1149
PluginInsert::describe_parameter (Evoral::Parameter param)
 
1150
{
 
1151
        if (param.type() != PluginAutomation) {
 
1152
                return Automatable::describe_parameter(param);
 
1153
        }
 
1154
 
 
1155
        return _plugins[0]->describe_parameter (param);
 
1156
}
 
1157
 
 
1158
ARDOUR::framecnt_t
 
1159
PluginInsert::signal_latency() const
 
1160
{
 
1161
        if (_user_latency) {
 
1162
                return _user_latency;
 
1163
        }
 
1164
 
 
1165
        return _plugins[0]->signal_latency ();
 
1166
}
 
1167
 
 
1168
ARDOUR::PluginType
 
1169
PluginInsert::type ()
 
1170
{
 
1171
       return plugin()->get_info()->type;
 
1172
}
 
1173
 
 
1174
PluginInsert::PluginControl::PluginControl (PluginInsert* p, const Evoral::Parameter &param, boost::shared_ptr<AutomationList> list)
 
1175
        : AutomationControl (p->session(), param, list, p->describe_parameter(param))
 
1176
        , _plugin (p)
 
1177
{
 
1178
        Plugin::ParameterDescriptor desc;
 
1179
        boost::shared_ptr<Plugin> plugin = p->plugin (0);
 
1180
        
 
1181
        alist()->reset_default (plugin->default_value (param.id()));
 
1182
 
 
1183
        plugin->get_parameter_descriptor (param.id(), desc);
 
1184
        _logarithmic = desc.logarithmic;
 
1185
        _sr_dependent = desc.sr_dependent;
 
1186
        _toggled = desc.toggled;
 
1187
}
 
1188
 
 
1189
/** @param val `user' value */
 
1190
void
 
1191
PluginInsert::PluginControl::set_value (double user_val)
 
1192
{
 
1193
        /* FIXME: probably should be taking out some lock here.. */
 
1194
 
 
1195
        for (Plugins::iterator i = _plugin->_plugins.begin(); i != _plugin->_plugins.end(); ++i) {
 
1196
                (*i)->set_parameter (_list->parameter().id(), user_val);
 
1197
        }
 
1198
 
 
1199
        boost::shared_ptr<Plugin> iasp = _plugin->_impulseAnalysisPlugin.lock();
 
1200
        if (iasp) {
 
1201
                iasp->set_parameter (_list->parameter().id(), user_val);
 
1202
        }
 
1203
 
 
1204
        AutomationControl::set_value (user_val);
 
1205
}
 
1206
 
 
1207
double
 
1208
PluginInsert::PluginControl::internal_to_interface (double val) const
 
1209
{
 
1210
        if (_logarithmic) {
 
1211
                if (val > 0) {
 
1212
                        val = log (val);
 
1213
                } else {
 
1214
                        val = 0;
 
1215
                }
 
1216
        }
 
1217
 
 
1218
        return val;
 
1219
}
 
1220
 
 
1221
double
 
1222
PluginInsert::PluginControl::interface_to_internal (double val) const
 
1223
{
 
1224
        if (_logarithmic) {
 
1225
                val = exp (val);
 
1226
        }
 
1227
 
 
1228
        return val;
 
1229
}
 
1230
 
 
1231
XMLNode&
 
1232
PluginInsert::PluginControl::get_state ()
 
1233
{
 
1234
        stringstream ss;
 
1235
 
 
1236
        XMLNode& node (AutomationControl::get_state());
 
1237
        ss << parameter().id();
 
1238
        node.add_property (X_("parameter"), ss.str());
 
1239
 
 
1240
        return node;
 
1241
}
 
1242
 
 
1243
/** @return `user' val */
 
1244
double
 
1245
PluginInsert::PluginControl::get_value () const
 
1246
{
 
1247
        /* FIXME: probably should be taking out some lock here.. */
 
1248
        return _plugin->get_parameter (_list->parameter());
 
1249
}
 
1250
 
 
1251
boost::shared_ptr<Plugin>
 
1252
PluginInsert::get_impulse_analysis_plugin()
 
1253
{
 
1254
        boost::shared_ptr<Plugin> ret;
 
1255
        if (_impulseAnalysisPlugin.expired()) {
 
1256
                ret = plugin_factory(_plugins[0]);
 
1257
                _impulseAnalysisPlugin = ret;
 
1258
        } else {
 
1259
                ret = _impulseAnalysisPlugin.lock();
 
1260
        }
 
1261
 
 
1262
        return ret;
 
1263
}
 
1264
 
 
1265
void
 
1266
PluginInsert::collect_signal_for_analysis (framecnt_t nframes)
 
1267
{
 
1268
        // called from outside the audio thread, so this should be safe
 
1269
        // only do audio as analysis is (currently) only for audio plugins
 
1270
        _signal_analysis_inputs.ensure_buffers(  DataType::AUDIO, input_streams().n_audio(),  nframes);
 
1271
        _signal_analysis_outputs.ensure_buffers( DataType::AUDIO, output_streams().n_audio(), nframes);
 
1272
 
 
1273
        _signal_analysis_collected_nframes   = 0;
 
1274
        _signal_analysis_collect_nframes_max = nframes;
 
1275
}
 
1276
 
 
1277
/** Add a plugin to our list */
 
1278
void
 
1279
PluginInsert::add_plugin (boost::shared_ptr<Plugin> plugin)
 
1280
{
 
1281
        plugin->set_insert_info (this);
 
1282
        
 
1283
        if (_plugins.empty()) {
 
1284
                /* first (and probably only) plugin instance - connect to relevant signals 
 
1285
                 */
 
1286
 
 
1287
                plugin->ParameterChanged.connect_same_thread (*this, boost::bind (&PluginInsert::parameter_changed, this, _1, _2));
 
1288
                plugin->StartTouch.connect_same_thread (*this, boost::bind (&PluginInsert::start_touch, this, _1));
 
1289
                plugin->EndTouch.connect_same_thread (*this, boost::bind (&PluginInsert::end_touch, this, _1));
 
1290
        }
 
1291
 
 
1292
        _plugins.push_back (plugin);
 
1293
}
 
1294
 
 
1295
void
 
1296
PluginInsert::realtime_handle_transport_stopped ()
 
1297
{
 
1298
        for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
 
1299
                (*i)->realtime_handle_transport_stopped ();
 
1300
        }
 
1301
}
 
1302
 
 
1303
void
 
1304
PluginInsert::realtime_locate ()
 
1305
{
 
1306
        for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
 
1307
                (*i)->realtime_locate ();
 
1308
        }
 
1309
}
 
1310
 
 
1311
void
 
1312
PluginInsert::monitoring_changed ()
 
1313
{
 
1314
        for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
 
1315
                (*i)->monitoring_changed ();
 
1316
        }
 
1317
}
 
1318
 
 
1319
void
 
1320
PluginInsert::start_touch (uint32_t param_id)
 
1321
{
 
1322
        boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter (PluginAutomation, 0, param_id));
 
1323
        if (ac) {
 
1324
                ac->start_touch (session().audible_frame());
 
1325
        }
 
1326
}
 
1327
 
 
1328
void
 
1329
PluginInsert::end_touch (uint32_t param_id)
 
1330
{
 
1331
        boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter (PluginAutomation, 0, param_id));
 
1332
        if (ac) {
 
1333
                ac->stop_touch (true, session().audible_frame());
 
1334
        }
 
1335
}