svcore  1.9
LADSPAPluginInstance.cpp
Go to the documentation of this file.
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 
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 {
61  }
62 
63  if (m_audioPortsOut.size() == 0) {
64  m_outputBuffers = 0;
65  } else {
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
87 {
88  return m_descriptor->Label;
89 }
90 
91 std::string
93 {
94  return m_descriptor->Name;
95 }
96 
97 std::string
99 {
100  return "";
101 }
102 
103 std::string
105 {
106  return m_descriptor->Maker;
107 }
108 
109 int
111 {
112  return -1;
113 }
114 
115 std::string
117 {
118  return m_descriptor->Copyright;
119 }
120 
121 LADSPAPluginInstance::ParameterList
123 {
124  ParameterList list;
125  LADSPAPluginFactory *f = dynamic_cast<LADSPAPluginFactory *>(m_factory);
126  if (!f) return list;
127 
128  for (unsigned int i = 0; i < m_controlPortsIn.size(); ++i) {
129 
130  ParameterDescriptor pd;
131  unsigned int pn = m_controlPortsIn[i].first;
132 
133  pd.identifier = m_descriptor->PortNames[pn];
134  pd.name = pd.identifier;
135  pd.description = "";
136  pd.minValue = f->getPortMinimum(m_descriptor, pn);
137  pd.maxValue = f->getPortMaximum(m_descriptor, pn);
138  pd.defaultValue = f->getPortDefault(m_descriptor, pn);
139 
140  float q = f->getPortQuantization(m_descriptor, pn);
141  if (q == 0.0) {
142  pd.isQuantized = false;
143  } else {
144  pd.isQuantized = true;
145  pd.quantizeStep = q;
146  }
147 
148  bool haveLabels = false;
149 
150 #ifdef HAVE_LRDF
151  if (pd.isQuantized && pd.quantizeStep == 1.0) {
152 
153  lrdf_defaults *defaults =
154  lrdf_get_scale_values(m_descriptor->UniqueID, pn);
155 
156  if (defaults) {
157  if (defaults->count > 0) {
158  std::map<int, std::string> values;
159  size_t v = 0;
160  for (size_t i = 0; i < defaults->count; ++i) {
161  v = size_t(lrintf(fabsf(defaults->items[i].value)));
162  values[v] = defaults->items[i].label;
163  }
164  for (size_t i = 0; i <= v; ++i) {
165  pd.valueNames.push_back(values[i]);
166  }
167  haveLabels = true;
168  }
169  lrdf_free_setting_values(defaults);
170  }
171  }
172 #endif
173 
174  if (haveLabels) {
175  pd.name = QString(pd.name.c_str())
176  .replace(QRegExp("\\([^\\(\\)]+=[^\\(\\)]+\\)$"), "")
177  .toStdString();
178  } else {
179  static QRegExp unitRE("[\\[\\(]([A-Za-z0-9/]+)[\\)\\]]$");
180  if (unitRE.indexIn(pd.name.c_str()) >= 0) {
181  pd.unit = unitRE.cap(1).toStdString();
182  pd.name = QString(pd.name.c_str())
183  .replace(unitRE, "").toStdString();
184  }
185  }
186 
187  list.push_back(pd);
188  }
189 
190  return list;
191 }
192 
193 float
195 {
196  for (unsigned int i = 0; i < m_controlPortsIn.size(); ++i) {
197  if (id == m_descriptor->PortNames[m_controlPortsIn[i].first]) {
198  return getParameterValue(i);
199  }
200  }
201 
202  return 0.0;
203 }
204 
205 void
206 LADSPAPluginInstance::setParameter(std::string id, float value)
207 {
208  for (unsigned int i = 0; i < m_controlPortsIn.size(); ++i) {
209  if (id == m_descriptor->PortNames[m_controlPortsIn[i].first]) {
210 #ifdef DEBUG_LADSPA
211  SVDEBUG << "LADSPAPluginInstance::setParameter: Found id "
212  << id << " at control port " << i << endl;
213 #endif
214  setParameterValue(i, value);
215  break;
216  }
217  }
218 }
219 
220 void
221 LADSPAPluginInstance::init(int idealChannelCount)
222 {
223 #ifdef DEBUG_LADSPA
224  SVDEBUG << "LADSPAPluginInstance::init(" << idealChannelCount << "): plugin has "
225  << m_descriptor->PortCount << " ports" << endl;
226 #endif
227 
228  // Discover ports numbers and identities
229  //
230  for (unsigned long i = 0; i < m_descriptor->PortCount; ++i) {
231 
232  if (LADSPA_IS_PORT_AUDIO(m_descriptor->PortDescriptors[i])) {
233 
234  if (LADSPA_IS_PORT_INPUT(m_descriptor->PortDescriptors[i])) {
235 #ifdef DEBUG_LADSPA
236  SVDEBUG << "LADSPAPluginInstance::init: port " << i << " is audio in" << endl;
237 #endif
238  m_audioPortsIn.push_back(i);
239  } else {
240 #ifdef DEBUG_LADSPA
241  SVDEBUG << "LADSPAPluginInstance::init: port " << i << " is audio out" << endl;
242 #endif
243  m_audioPortsOut.push_back(i);
244  }
245 
246  } else if (LADSPA_IS_PORT_CONTROL(m_descriptor->PortDescriptors[i])) {
247 
248  if (LADSPA_IS_PORT_INPUT(m_descriptor->PortDescriptors[i])) {
249 
250 #ifdef DEBUG_LADSPA
251  SVDEBUG << "LADSPAPluginInstance::init: port " << i << " is control in" << endl;
252 #endif
253  LADSPA_Data *data = new LADSPA_Data(0.0);
254  m_controlPortsIn.push_back(
255  std::pair<unsigned long, LADSPA_Data*>(i, data));
256 
257  } else {
258 
259 #ifdef DEBUG_LADSPA
260  SVDEBUG << "LADSPAPluginInstance::init: port " << i << " is control out" << endl;
261 #endif
262  LADSPA_Data *data = new LADSPA_Data(0.0);
263  m_controlPortsOut.push_back(
264  std::pair<unsigned long, LADSPA_Data*>(i, data));
265  if (!strcmp(m_descriptor->PortNames[i], "latency") ||
266  !strcmp(m_descriptor->PortNames[i], "_latency")) {
267 #ifdef DEBUG_LADSPA
268  cerr << "Wooo! We have a latency port!" << endl;
269 #endif
270  m_latencyPort = data;
271  }
272 
273  }
274  }
275 #ifdef DEBUG_LADSPA
276  else
277  SVDEBUG << "LADSPAPluginInstance::init - "
278  << "unrecognised port type" << endl;
279 #endif
280  }
281 
282  m_instanceCount = 1;
283 
284  if (idealChannelCount > 0) {
285  if (m_audioPortsIn.size() == 1) {
286  // mono plugin: duplicate it if need be
287  m_instanceCount = idealChannelCount;
288  }
289  }
290 }
291 
292 size_t
294 {
295  if (m_latencyPort) {
296  if (!m_run) {
297  for (size_t i = 0; i < getAudioInputCount(); ++i) {
298  for (size_t j = 0; j < m_blockSize; ++j) {
299  m_inputBuffers[i][j] = 0.f;
300  }
301  }
302  run(Vamp::RealTime::zeroTime);
303  }
304  if (*m_latencyPort > 0) return (size_t)*m_latencyPort;
305  }
306  return 0;
307 }
308 
309 void
311 {
312  if (isOK()) {
313  deactivate();
314  activate();
315  }
316 }
317 
318 void
320 {
321  if (m_audioPortsIn.size() != 1 || channels == m_instanceCount) {
322  silence();
323  return;
324  }
325 
326  if (isOK()) {
327  deactivate();
328  }
329 
331 
332  cleanup();
333  m_instanceCount = channels;
335  if (isOK()) {
336  connectPorts();
337  activate();
338  }
339 }
340 
341 
343 {
344 #ifdef DEBUG_LADSPA
345  SVDEBUG << "LADSPAPluginInstance::~LADSPAPluginInstance" << endl;
346 #endif
347 
348  if (m_instanceHandles.size() != 0) { // "isOK()"
349  deactivate();
350  }
351 
352  cleanup();
353 
354  for (unsigned int i = 0; i < m_controlPortsIn.size(); ++i)
355  delete m_controlPortsIn[i].second;
356 
357  for (unsigned int i = 0; i < m_controlPortsOut.size(); ++i)
358  delete m_controlPortsOut[i].second;
359 
360  m_controlPortsIn.clear();
361  m_controlPortsOut.clear();
362 
363  if (m_ownBuffers) {
364  for (size_t i = 0; i < m_instanceCount * m_audioPortsIn.size(); ++i) {
365  delete[] m_inputBuffers[i];
366  }
367  for (size_t i = 0; i < m_instanceCount * m_audioPortsOut.size(); ++i) {
368  delete[] m_outputBuffers[i];
369  }
370 
371  delete[] m_inputBuffers;
372  delete[] m_outputBuffers;
373  }
374 
375  m_audioPortsIn.clear();
376  m_audioPortsOut.clear();
377 }
378 
379 
380 void
381 LADSPAPluginInstance::instantiate(unsigned long sampleRate)
382 {
383  if (!m_descriptor) return;
384 
385 #ifdef DEBUG_LADSPA
386  cout << "LADSPAPluginInstance::instantiate - plugin unique id = "
387  << m_descriptor->UniqueID << endl;
388 #endif
389 
390  if (!m_descriptor->instantiate) {
391  cerr << "Bad plugin: plugin id " << m_descriptor->UniqueID
392  << ":" << m_descriptor->Label
393  << " has no instantiate method!" << endl;
394  return;
395  }
396 
397  for (size_t i = 0; i < m_instanceCount; ++i) {
398  m_instanceHandles.push_back
399  (m_descriptor->instantiate(m_descriptor, sampleRate));
400  }
401 }
402 
403 void
405 {
406  if (!m_descriptor || !m_descriptor->activate) return;
407 
408  for (std::vector<LADSPA_Handle>::iterator hi = m_instanceHandles.begin();
409  hi != m_instanceHandles.end(); ++hi) {
410  m_descriptor->activate(*hi);
411  }
412 }
413 
414 void
416 {
417  if (!m_descriptor || !m_descriptor->connect_port) return;
418 
419  assert(sizeof(LADSPA_Data) == sizeof(float));
420  assert(sizeof(sample_t) == sizeof(float));
421 
422  LADSPAPluginFactory *f = dynamic_cast<LADSPAPluginFactory *>(m_factory);
423  int inbuf = 0, outbuf = 0;
424 
425  for (std::vector<LADSPA_Handle>::iterator hi = m_instanceHandles.begin();
426  hi != m_instanceHandles.end(); ++hi) {
427 
428  for (unsigned int i = 0; i < m_audioPortsIn.size(); ++i) {
429  m_descriptor->connect_port(*hi,
430  m_audioPortsIn[i],
431  (LADSPA_Data *)m_inputBuffers[inbuf]);
432  ++inbuf;
433  }
434 
435  for (unsigned int i = 0; i < m_audioPortsOut.size(); ++i) {
436  m_descriptor->connect_port(*hi,
437  m_audioPortsOut[i],
438  (LADSPA_Data *)m_outputBuffers[outbuf]);
439  ++outbuf;
440  }
441 
442  // If there is more than one instance, they all share the same
443  // control port ins (and outs, for the moment, because we
444  // don't actually do anything with the outs anyway -- but they
445  // do have to be connected as the plugin can't know if they're
446  // not and will write to them anyway).
447 
448  for (unsigned int i = 0; i < m_controlPortsIn.size(); ++i) {
449  m_descriptor->connect_port(*hi,
450  m_controlPortsIn[i].first,
451  m_controlPortsIn[i].second);
452  if (f) {
453  float defaultValue = f->getPortDefault
454  (m_descriptor, m_controlPortsIn[i].first);
455  *m_controlPortsIn[i].second = defaultValue;
456  }
457  }
458 
459  for (unsigned int i = 0; i < m_controlPortsOut.size(); ++i) {
460  m_descriptor->connect_port(*hi,
461  m_controlPortsOut[i].first,
462  m_controlPortsOut[i].second);
463  }
464  }
465 }
466 
467 unsigned int
469 {
470  return m_controlPortsIn.size();
471 }
472 
473 void
474 LADSPAPluginInstance::setParameterValue(unsigned int parameter, float value)
475 {
476  if (parameter >= m_controlPortsIn.size()) return;
477 
478  unsigned int portNumber = m_controlPortsIn[parameter].first;
479 
480  LADSPAPluginFactory *f = dynamic_cast<LADSPAPluginFactory *>(m_factory);
481  if (f) {
482  if (value < f->getPortMinimum(m_descriptor, portNumber)) {
483  value = f->getPortMinimum(m_descriptor, portNumber);
484  }
485  if (value > f->getPortMaximum(m_descriptor, portNumber)) {
486  value = f->getPortMaximum(m_descriptor, portNumber);
487  }
488  }
489 
490  (*m_controlPortsIn[parameter].second) = value;
491 }
492 
493 float
495 {
496  if (output > m_controlPortsOut.size()) return 0.0;
497  return (*m_controlPortsOut[output].second);
498 }
499 
500 float
501 LADSPAPluginInstance::getParameterValue(unsigned int parameter) const
502 {
503  if (parameter >= m_controlPortsIn.size()) return 0.0;
504  return (*m_controlPortsIn[parameter].second);
505 }
506 
507 float
508 LADSPAPluginInstance::getParameterDefault(unsigned int parameter) const
509 {
510  if (parameter >= m_controlPortsIn.size()) return 0.0;
511 
512  LADSPAPluginFactory *f = dynamic_cast<LADSPAPluginFactory *>(m_factory);
513  if (f) {
514  return f->getPortDefault(m_descriptor, m_controlPortsIn[parameter].first);
515  } else {
516  return 0.0f;
517  }
518 }
519 
520 int
522 {
523  if (parameter >= m_controlPortsIn.size()) return 0.0;
524 
525  LADSPAPluginFactory *f = dynamic_cast<LADSPAPluginFactory *>(m_factory);
526  if (f) {
527  return f->getPortDisplayHint(m_descriptor, m_controlPortsIn[parameter].first);
528  } else {
529  return PortHint::NoHint;
530  }
531 }
532 
533 void
534 LADSPAPluginInstance::run(const Vamp::RealTime &, size_t count)
535 {
536  if (!m_descriptor || !m_descriptor->run) return;
537 
538  if (count == 0) count = m_blockSize;
539 
540  for (std::vector<LADSPA_Handle>::iterator hi = m_instanceHandles.begin();
541  hi != m_instanceHandles.end(); ++hi) {
542 
543  m_descriptor->run(*hi, count);
544  }
545 
546  m_run = true;
547 }
548 
549 void
551 {
552  if (!m_descriptor || !m_descriptor->deactivate) return;
553 
554  for (std::vector<LADSPA_Handle>::iterator hi = m_instanceHandles.begin();
555  hi != m_instanceHandles.end(); ++hi) {
556  m_descriptor->deactivate(*hi);
557  }
558 }
559 
560 void
562 {
563  if (!m_descriptor) return;
564 
565  if (!m_descriptor->cleanup) {
566  cerr << "Bad plugin: plugin id " << m_descriptor->UniqueID
567  << ":" << m_descriptor->Label
568  << " has no cleanup method!" << endl;
569  return;
570  }
571 
572  for (std::vector<LADSPA_Handle>::iterator hi = m_instanceHandles.begin();
573  hi != m_instanceHandles.end(); ++hi) {
574  m_descriptor->cleanup(*hi);
575  }
576 
577  m_instanceHandles.clear();
578 }
579 
580 
virtual void setParameter(std::string, float)
virtual float getParameterDefault(unsigned int parameter) const
virtual ParameterList getParameterDescriptors() const
int getPortDisplayHint(const LADSPA_Descriptor *, int port)
std::vector< LADSPA_Handle > m_instanceHandles
static const int NoHint
virtual void setParameterValue(unsigned int parameter, float value)
virtual std::string getMaker() const
virtual int getPluginVersion() const
std::vector< std::pair< unsigned long, LADSPA_Data * > > m_controlPortsOut
virtual float getParameter(std::string) const
float getPortDefault(const LADSPA_Descriptor *, int port)
virtual void run(const Vamp::RealTime &rt, size_t count=0)
Run for one block, starting at the given time.
float getPortMaximum(const LADSPA_Descriptor *, int port)
float getPortQuantization(const LADSPA_Descriptor *, int port)
virtual float getParameterValue(unsigned int parameter) const
virtual int getParameterDisplayHint(unsigned int parameter) const
virtual void setIdealChannelCount(size_t channels)
void instantiate(unsigned long sampleRate)
virtual std::string getName() const
virtual size_t getAudioInputCount() const
#define SVDEBUG
Definition: Debug.h:42
virtual std::string getIdentifier() const
std::vector< std::pair< unsigned long, LADSPA_Data * > > m_controlPortsIn
void init(int idealChannelCount=0)
std::vector< int > m_audioPortsOut
RealTimePluginFactory * m_factory
std::vector< int > m_audioPortsIn
LADSPAPluginInstance(RealTimePluginFactory *factory, int client, QString identifier, int position, unsigned long sampleRate, size_t blockSize, int idealChannelCount, const LADSPA_Descriptor *descriptor)
virtual unsigned int getParameterCount() const
virtual float getControlOutputValue(size_t n) const
virtual std::string getCopyright() const
const LADSPA_Descriptor * m_descriptor
float getPortMinimum(const LADSPA_Descriptor *, int port)
virtual std::string getDescription() const
virtual bool isOK() const