comparison plugin/LADSPAPluginInstance.cpp @ 0:fc9323a41f5a

start base : Sonic Visualiser sv1-1.0rc1
author lbajardsilogic
date Fri, 11 May 2007 09:08:14 +0000
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:fc9323a41f5a
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
2
3 /*
4 Sonic Visualiser
5 An audio file viewer and annotation editor.
6 Centre for Digital Music, Queen Mary, University of London.
7
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License as
10 published by the Free Software Foundation; either version 2 of the
11 License, or (at your option) any later version. See the file
12 COPYING included with this distribution for more information.
13 */
14
15 /*
16 This is a modified version of a source file from the
17 Rosegarden MIDI and audio sequencer and notation editor.
18 This file copyright 2000-2006 Chris Cannam, Richard Bown, and QMUL.
19 */
20
21 #include <iostream>
22 #include <cassert>
23
24 #include "LADSPAPluginInstance.h"
25 #include "LADSPAPluginFactory.h"
26
27 #ifdef HAVE_LRDF
28 #include "lrdf.h"
29 #endif // HAVE_LRDF
30
31 //#define DEBUG_LADSPA 1
32
33 #include <cmath>
34
35
36 LADSPAPluginInstance::LADSPAPluginInstance(RealTimePluginFactory *factory,
37 int clientId,
38 QString identifier,
39 int position,
40 unsigned long sampleRate,
41 size_t blockSize,
42 int idealChannelCount,
43 const LADSPA_Descriptor* descriptor) :
44 RealTimePluginInstance(factory, identifier),
45 m_client(clientId),
46 m_position(position),
47 m_instanceCount(0),
48 m_descriptor(descriptor),
49 m_blockSize(blockSize),
50 m_sampleRate(sampleRate),
51 m_latencyPort(0),
52 m_run(false),
53 m_bypassed(false)
54 {
55 init(idealChannelCount);
56
57 if (m_audioPortsIn.size() == 0) {
58 m_inputBuffers = 0;
59 } else {
60 m_inputBuffers = new sample_t*[m_instanceCount * m_audioPortsIn.size()];
61 }
62
63 if (m_audioPortsOut.size() == 0) {
64 m_outputBuffers = 0;
65 } else {
66 m_outputBuffers = new sample_t*[m_instanceCount * m_audioPortsOut.size()];
67 }
68
69 for (size_t i = 0; i < m_instanceCount * m_audioPortsIn.size(); ++i) {
70 m_inputBuffers[i] = new sample_t[blockSize];
71 }
72 for (size_t i = 0; i < m_instanceCount * m_audioPortsOut.size(); ++i) {
73 m_outputBuffers[i] = new sample_t[blockSize];
74 }
75
76 m_ownBuffers = true;
77
78 instantiate(sampleRate);
79 if (isOK()) {
80 connectPorts();
81 activate();
82 }
83 }
84
85 std::string
86 LADSPAPluginInstance::getIdentifier() const
87 {
88 return m_descriptor->Label;
89 }
90
91 std::string
92 LADSPAPluginInstance::getName() const
93 {
94 return m_descriptor->Name;
95 }
96
97 std::string
98 LADSPAPluginInstance::getDescription() const
99 {
100 return "";
101 }
102
103 std::string
104 LADSPAPluginInstance::getMaker() const
105 {
106 return m_descriptor->Maker;
107 }
108
109 int
110 LADSPAPluginInstance::getPluginVersion() const
111 {
112 return 1;
113 }
114
115 std::string
116 LADSPAPluginInstance::getCopyright() const
117 {
118 return m_descriptor->Copyright;
119 }
120
121 LADSPAPluginInstance::ParameterList
122 LADSPAPluginInstance::getParameterDescriptors() const
123 {
124 ParameterList list;
125 LADSPAPluginFactory *f = dynamic_cast<LADSPAPluginFactory *>(m_factory);
126
127 for (unsigned int i = 0; i < m_controlPortsIn.size(); ++i) {
128
129 ParameterDescriptor pd;
130 unsigned int pn = m_controlPortsIn[i].first;
131
132 pd.identifier = m_descriptor->PortNames[pn];
133 pd.name = pd.identifier;
134 pd.description = "";
135 pd.minValue = f->getPortMinimum(m_descriptor, pn);
136 pd.maxValue = f->getPortMaximum(m_descriptor, pn);
137 pd.defaultValue = f->getPortDefault(m_descriptor, pn);
138
139 float q = f->getPortQuantization(m_descriptor, pn);
140 if (q == 0.0) {
141 pd.isQuantized = false;
142 } else {
143 pd.isQuantized = true;
144 pd.quantizeStep = q;
145 }
146
147 bool haveLabels = false;
148
149 #ifdef HAVE_LRDF
150 if (pd.isQuantized && pd.quantizeStep == 1.0) {
151
152 lrdf_defaults *defaults =
153 lrdf_get_scale_values(m_descriptor->UniqueID, pn);
154
155 if (defaults) {
156 if (defaults->count > 0) {
157 std::map<int, std::string> values;
158 size_t v = 0;
159 for (size_t i = 0; i < defaults->count; ++i) {
160 v = size_t(lrintf(fabsf(defaults->items[i].value)));
161 values[v] = defaults->items[i].label;
162 }
163 for (size_t i = 0; i <= v; ++i) {
164 pd.valueNames.push_back(values[i]);
165 }
166 haveLabels = true;
167 }
168 lrdf_free_setting_values(defaults);
169 }
170 }
171 #endif
172
173 if (haveLabels) {
174 pd.name = QString(pd.name.c_str())
175 .replace(QRegExp("\\([^\\(\\)]+=[^\\(\\)]+\\)$"), "")
176 .toStdString();
177 } else {
178 static QRegExp unitRE("[\\[\\(]([A-Za-z0-9/]+)[\\)\\]]$");
179 if (unitRE.indexIn(pd.name.c_str()) >= 0) {
180 pd.unit = unitRE.cap(1).toStdString();
181 pd.name = QString(pd.name.c_str())
182 .replace(unitRE, "").toStdString();
183 }
184 }
185
186 list.push_back(pd);
187 }
188
189 return list;
190 }
191
192 float
193 LADSPAPluginInstance::getParameter(std::string id) const
194 {
195 for (unsigned int i = 0; i < m_controlPortsIn.size(); ++i) {
196 if (id == m_descriptor->PortNames[m_controlPortsIn[i].first]) {
197 return getParameterValue(i);
198 }
199 }
200
201 return 0.0;
202 }
203
204 void
205 LADSPAPluginInstance::setParameter(std::string id, float value)
206 {
207 for (unsigned int i = 0; i < m_controlPortsIn.size(); ++i) {
208 if (id == m_descriptor->PortNames[m_controlPortsIn[i].first]) {
209 #ifdef DEBUG_LADSPA
210 std::cerr << "LADSPAPluginInstance::setParameter: Found id "
211 << id << " at control port " << i << std::endl;
212 #endif
213 setParameterValue(i, value);
214 break;
215 }
216 }
217 }
218
219 void
220 LADSPAPluginInstance::init(int idealChannelCount)
221 {
222 #ifdef DEBUG_LADSPA
223 std::cerr << "LADSPAPluginInstance::init(" << idealChannelCount << "): plugin has "
224 << m_descriptor->PortCount << " ports" << std::endl;
225 #endif
226
227 // Discover ports numbers and identities
228 //
229 for (unsigned long i = 0; i < m_descriptor->PortCount; ++i) {
230
231 if (LADSPA_IS_PORT_AUDIO(m_descriptor->PortDescriptors[i])) {
232
233 if (LADSPA_IS_PORT_INPUT(m_descriptor->PortDescriptors[i])) {
234 #ifdef DEBUG_LADSPA
235 std::cerr << "LADSPAPluginInstance::init: port " << i << " is audio in" << std::endl;
236 #endif
237 m_audioPortsIn.push_back(i);
238 } else {
239 #ifdef DEBUG_LADSPA
240 std::cerr << "LADSPAPluginInstance::init: port " << i << " is audio out" << std::endl;
241 #endif
242 m_audioPortsOut.push_back(i);
243 }
244
245 } else if (LADSPA_IS_PORT_CONTROL(m_descriptor->PortDescriptors[i])) {
246
247 if (LADSPA_IS_PORT_INPUT(m_descriptor->PortDescriptors[i])) {
248
249 #ifdef DEBUG_LADSPA
250 std::cerr << "LADSPAPluginInstance::init: port " << i << " is control in" << std::endl;
251 #endif
252 LADSPA_Data *data = new LADSPA_Data(0.0);
253 m_controlPortsIn.push_back(
254 std::pair<unsigned long, LADSPA_Data*>(i, data));
255
256 } else {
257
258 #ifdef DEBUG_LADSPA
259 std::cerr << "LADSPAPluginInstance::init: port " << i << " is control out" << std::endl;
260 #endif
261 LADSPA_Data *data = new LADSPA_Data(0.0);
262 m_controlPortsOut.push_back(
263 std::pair<unsigned long, LADSPA_Data*>(i, data));
264 if (!strcmp(m_descriptor->PortNames[i], "latency") ||
265 !strcmp(m_descriptor->PortNames[i], "_latency")) {
266 #ifdef DEBUG_LADSPA
267 std::cerr << "Wooo! We have a latency port!" << std::endl;
268 #endif
269 m_latencyPort = data;
270 }
271
272 }
273 }
274 #ifdef DEBUG_LADSPA
275 else
276 std::cerr << "LADSPAPluginInstance::init - "
277 << "unrecognised port type" << std::endl;
278 #endif
279 }
280
281 m_instanceCount = 1;
282
283 if (idealChannelCount > 0) {
284 if (m_audioPortsIn.size() == 1) {
285 // mono plugin: duplicate it if need be
286 m_instanceCount = idealChannelCount;
287 }
288 }
289 }
290
291 size_t
292 LADSPAPluginInstance::getLatency()
293 {
294 if (m_latencyPort) {
295 if (!m_run) {
296 for (size_t i = 0; i < getAudioInputCount(); ++i) {
297 for (size_t j = 0; j < m_blockSize; ++j) {
298 m_inputBuffers[i][j] = 0.f;
299 }
300 }
301 run(Vamp::RealTime::zeroTime);
302 }
303 if (*m_latencyPort > 0) return (size_t)*m_latencyPort;
304 }
305 return 0;
306 }
307
308 void
309 LADSPAPluginInstance::silence()
310 {
311 if (isOK()) {
312 deactivate();
313 activate();
314 }
315 }
316
317 void
318 LADSPAPluginInstance::setIdealChannelCount(size_t channels)
319 {
320 if (m_audioPortsIn.size() != 1 || channels == m_instanceCount) {
321 silence();
322 return;
323 }
324
325 if (isOK()) {
326 deactivate();
327 }
328
329 //!!! don't we need to reallocate inputBuffers and outputBuffers?
330
331 cleanup();
332 m_instanceCount = channels;
333 instantiate(m_sampleRate);
334 if (isOK()) {
335 connectPorts();
336 activate();
337 }
338 }
339
340
341 LADSPAPluginInstance::~LADSPAPluginInstance()
342 {
343 #ifdef DEBUG_LADSPA
344 std::cerr << "LADSPAPluginInstance::~LADSPAPluginInstance" << std::endl;
345 #endif
346
347 if (m_instanceHandles.size() != 0) { // "isOK()"
348 deactivate();
349 }
350
351 cleanup();
352
353 for (unsigned int i = 0; i < m_controlPortsIn.size(); ++i)
354 delete m_controlPortsIn[i].second;
355
356 for (unsigned int i = 0; i < m_controlPortsOut.size(); ++i)
357 delete m_controlPortsOut[i].second;
358
359 m_controlPortsIn.clear();
360 m_controlPortsOut.clear();
361
362 if (m_ownBuffers) {
363 for (size_t i = 0; i < m_instanceCount * m_audioPortsIn.size(); ++i) {
364 delete[] m_inputBuffers[i];
365 }
366 for (size_t i = 0; i < m_instanceCount * m_audioPortsOut.size(); ++i) {
367 delete[] m_outputBuffers[i];
368 }
369
370 delete[] m_inputBuffers;
371 delete[] m_outputBuffers;
372 }
373
374 m_audioPortsIn.clear();
375 m_audioPortsOut.clear();
376 }
377
378
379 void
380 LADSPAPluginInstance::instantiate(unsigned long sampleRate)
381 {
382 #ifdef DEBUG_LADSPA
383 std::cout << "LADSPAPluginInstance::instantiate - plugin unique id = "
384 << m_descriptor->UniqueID << std::endl;
385 #endif
386 if (!m_descriptor) return;
387
388 if (!m_descriptor->instantiate) {
389 std::cerr << "Bad plugin: plugin id " << m_descriptor->UniqueID
390 << ":" << m_descriptor->Label
391 << " has no instantiate method!" << std::endl;
392 return;
393 }
394
395 for (size_t i = 0; i < m_instanceCount; ++i) {
396 m_instanceHandles.push_back
397 (m_descriptor->instantiate(m_descriptor, sampleRate));
398 }
399 }
400
401 void
402 LADSPAPluginInstance::activate()
403 {
404 if (!m_descriptor || !m_descriptor->activate) return;
405
406 for (std::vector<LADSPA_Handle>::iterator hi = m_instanceHandles.begin();
407 hi != m_instanceHandles.end(); ++hi) {
408 m_descriptor->activate(*hi);
409 }
410 }
411
412 void
413 LADSPAPluginInstance::connectPorts()
414 {
415 if (!m_descriptor || !m_descriptor->connect_port) return;
416
417 assert(sizeof(LADSPA_Data) == sizeof(float));
418 assert(sizeof(sample_t) == sizeof(float));
419
420 LADSPAPluginFactory *f = dynamic_cast<LADSPAPluginFactory *>(m_factory);
421 int inbuf = 0, outbuf = 0;
422
423 for (std::vector<LADSPA_Handle>::iterator hi = m_instanceHandles.begin();
424 hi != m_instanceHandles.end(); ++hi) {
425
426 for (unsigned int i = 0; i < m_audioPortsIn.size(); ++i) {
427 m_descriptor->connect_port(*hi,
428 m_audioPortsIn[i],
429 (LADSPA_Data *)m_inputBuffers[inbuf]);
430 ++inbuf;
431 }
432
433 for (unsigned int i = 0; i < m_audioPortsOut.size(); ++i) {
434 m_descriptor->connect_port(*hi,
435 m_audioPortsOut[i],
436 (LADSPA_Data *)m_outputBuffers[outbuf]);
437 ++outbuf;
438 }
439
440 // If there is more than one instance, they all share the same
441 // control port ins (and outs, for the moment, because we
442 // don't actually do anything with the outs anyway -- but they
443 // do have to be connected as the plugin can't know if they're
444 // not and will write to them anyway).
445
446 for (unsigned int i = 0; i < m_controlPortsIn.size(); ++i) {
447 m_descriptor->connect_port(*hi,
448 m_controlPortsIn[i].first,
449 m_controlPortsIn[i].second);
450 if (f) {
451 float defaultValue = f->getPortDefault
452 (m_descriptor, m_controlPortsIn[i].first);
453 *m_controlPortsIn[i].second = defaultValue;
454 }
455 }
456
457 for (unsigned int i = 0; i < m_controlPortsOut.size(); ++i) {
458 m_descriptor->connect_port(*hi,
459 m_controlPortsOut[i].first,
460 m_controlPortsOut[i].second);
461 }
462 }
463 }
464
465 unsigned int
466 LADSPAPluginInstance::getParameterCount() const
467 {
468 return m_controlPortsIn.size();
469 }
470
471 void
472 LADSPAPluginInstance::setParameterValue(unsigned int parameter, float value)
473 {
474 if (parameter >= m_controlPortsIn.size()) return;
475
476 unsigned int portNumber = m_controlPortsIn[parameter].first;
477
478 LADSPAPluginFactory *f = dynamic_cast<LADSPAPluginFactory *>(m_factory);
479 if (f) {
480 if (value < f->getPortMinimum(m_descriptor, portNumber)) {
481 value = f->getPortMinimum(m_descriptor, portNumber);
482 }
483 if (value > f->getPortMaximum(m_descriptor, portNumber)) {
484 value = f->getPortMaximum(m_descriptor, portNumber);
485 }
486 }
487
488 (*m_controlPortsIn[parameter].second) = value;
489 }
490
491 float
492 LADSPAPluginInstance::getControlOutputValue(size_t output) const
493 {
494 if (output > m_controlPortsOut.size()) return 0.0;
495 return (*m_controlPortsOut[output].second);
496 }
497
498 float
499 LADSPAPluginInstance::getParameterValue(unsigned int parameter) const
500 {
501 if (parameter >= m_controlPortsIn.size()) return 0.0;
502 return (*m_controlPortsIn[parameter].second);
503 }
504
505 float
506 LADSPAPluginInstance::getParameterDefault(unsigned int parameter) const
507 {
508 if (parameter >= m_controlPortsIn.size()) return 0.0;
509
510 LADSPAPluginFactory *f = dynamic_cast<LADSPAPluginFactory *>(m_factory);
511 if (f) {
512 return f->getPortDefault(m_descriptor, m_controlPortsIn[parameter].first);
513 } else {
514 return 0.0f;
515 }
516 }
517
518 void
519 LADSPAPluginInstance::run(const Vamp::RealTime &)
520 {
521 if (!m_descriptor || !m_descriptor->run) return;
522
523 for (std::vector<LADSPA_Handle>::iterator hi = m_instanceHandles.begin();
524 hi != m_instanceHandles.end(); ++hi) {
525
526 m_descriptor->run(*hi, m_blockSize);
527 }
528
529 m_run = true;
530 }
531
532 void
533 LADSPAPluginInstance::deactivate()
534 {
535 if (!m_descriptor || !m_descriptor->deactivate) return;
536
537 for (std::vector<LADSPA_Handle>::iterator hi = m_instanceHandles.begin();
538 hi != m_instanceHandles.end(); ++hi) {
539 m_descriptor->deactivate(*hi);
540 }
541 }
542
543 void
544 LADSPAPluginInstance::cleanup()
545 {
546 if (!m_descriptor) return;
547
548 if (!m_descriptor->cleanup) {
549 std::cerr << "Bad plugin: plugin id " << m_descriptor->UniqueID
550 << ":" << m_descriptor->Label
551 << " has no cleanup method!" << std::endl;
552 return;
553 }
554
555 for (std::vector<LADSPA_Handle>::iterator hi = m_instanceHandles.begin();
556 hi != m_instanceHandles.end(); ++hi) {
557 m_descriptor->cleanup(*hi);
558 }
559
560 m_instanceHandles.clear();
561 }
562
563