00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <iostream>
00022 #include <cassert>
00023
00024 #include "LADSPAPluginInstance.h"
00025 #include "LADSPAPluginFactory.h"
00026
00027 #ifdef HAVE_LRDF
00028 #include "lrdf.h"
00029 #endif // HAVE_LRDF
00030
00031
00032
00033 #include <cmath>
00034
00035
00036 LADSPAPluginInstance::LADSPAPluginInstance(RealTimePluginFactory *factory,
00037 int clientId,
00038 QString identifier,
00039 int position,
00040 unsigned long sampleRate,
00041 size_t blockSize,
00042 int idealChannelCount,
00043 const LADSPA_Descriptor* descriptor) :
00044 RealTimePluginInstance(factory, identifier),
00045 m_client(clientId),
00046 m_position(position),
00047 m_instanceCount(0),
00048 m_descriptor(descriptor),
00049 m_blockSize(blockSize),
00050 m_sampleRate(sampleRate),
00051 m_latencyPort(0),
00052 m_run(false),
00053 m_bypassed(false)
00054 {
00055 init(idealChannelCount);
00056
00057 if (m_audioPortsIn.size() == 0) {
00058 m_inputBuffers = 0;
00059 } else {
00060 m_inputBuffers = new sample_t*[m_instanceCount * m_audioPortsIn.size()];
00061 }
00062
00063 if (m_audioPortsOut.size() == 0) {
00064 m_outputBuffers = 0;
00065 } else {
00066 m_outputBuffers = new sample_t*[m_instanceCount * m_audioPortsOut.size()];
00067 }
00068
00069 for (size_t i = 0; i < m_instanceCount * m_audioPortsIn.size(); ++i) {
00070 m_inputBuffers[i] = new sample_t[blockSize];
00071 }
00072 for (size_t i = 0; i < m_instanceCount * m_audioPortsOut.size(); ++i) {
00073 m_outputBuffers[i] = new sample_t[blockSize];
00074 }
00075
00076 m_ownBuffers = true;
00077
00078 instantiate(sampleRate);
00079 if (isOK()) {
00080 connectPorts();
00081 activate();
00082 }
00083 }
00084
00085 std::string
00086 LADSPAPluginInstance::getIdentifier() const
00087 {
00088 return m_descriptor->Label;
00089 }
00090
00091 std::string
00092 LADSPAPluginInstance::getName() const
00093 {
00094 return m_descriptor->Name;
00095 }
00096
00097 std::string
00098 LADSPAPluginInstance::getDescription() const
00099 {
00100 return "";
00101 }
00102
00103 std::string
00104 LADSPAPluginInstance::getMaker() const
00105 {
00106 return m_descriptor->Maker;
00107 }
00108
00109 int
00110 LADSPAPluginInstance::getPluginVersion() const
00111 {
00112 return 1;
00113 }
00114
00115 std::string
00116 LADSPAPluginInstance::getCopyright() const
00117 {
00118 return m_descriptor->Copyright;
00119 }
00120
00121 LADSPAPluginInstance::ParameterList
00122 LADSPAPluginInstance::getParameterDescriptors() const
00123 {
00124 ParameterList list;
00125 LADSPAPluginFactory *f = dynamic_cast<LADSPAPluginFactory *>(m_factory);
00126
00127 for (unsigned int i = 0; i < m_controlPortsIn.size(); ++i) {
00128
00129 ParameterDescriptor pd;
00130 unsigned int pn = m_controlPortsIn[i].first;
00131
00132 pd.identifier = m_descriptor->PortNames[pn];
00133 pd.name = pd.identifier;
00134 pd.description = "";
00135 pd.minValue = f->getPortMinimum(m_descriptor, pn);
00136 pd.maxValue = f->getPortMaximum(m_descriptor, pn);
00137 pd.defaultValue = f->getPortDefault(m_descriptor, pn);
00138
00139 float q = f->getPortQuantization(m_descriptor, pn);
00140 if (q == 0.0) {
00141 pd.isQuantized = false;
00142 } else {
00143 pd.isQuantized = true;
00144 pd.quantizeStep = q;
00145 }
00146
00147 bool haveLabels = false;
00148
00149 #ifdef HAVE_LRDF
00150 if (pd.isQuantized && pd.quantizeStep == 1.0) {
00151
00152 lrdf_defaults *defaults =
00153 lrdf_get_scale_values(m_descriptor->UniqueID, pn);
00154
00155 if (defaults) {
00156 if (defaults->count > 0) {
00157 std::map<int, std::string> values;
00158 size_t v = 0;
00159 for (size_t i = 0; i < defaults->count; ++i) {
00160 v = size_t(lrintf(fabsf(defaults->items[i].value)));
00161 values[v] = defaults->items[i].label;
00162 }
00163 for (size_t i = 0; i <= v; ++i) {
00164 pd.valueNames.push_back(values[i]);
00165 }
00166 haveLabels = true;
00167 }
00168 lrdf_free_setting_values(defaults);
00169 }
00170 }
00171 #endif
00172
00173 if (haveLabels) {
00174 pd.name = QString(pd.name.c_str())
00175 .replace(QRegExp("\\([^\\(\\)]+=[^\\(\\)]+\\)$"), "")
00176 .toStdString();
00177 } else {
00178 static QRegExp unitRE("[\\[\\(]([A-Za-z0-9/]+)[\\)\\]]$");
00179 if (unitRE.indexIn(pd.name.c_str()) >= 0) {
00180 pd.unit = unitRE.cap(1).toStdString();
00181 pd.name = QString(pd.name.c_str())
00182 .replace(unitRE, "").toStdString();
00183 }
00184 }
00185
00186 list.push_back(pd);
00187 }
00188
00189 return list;
00190 }
00191
00192 float
00193 LADSPAPluginInstance::getParameter(std::string id) const
00194 {
00195 for (unsigned int i = 0; i < m_controlPortsIn.size(); ++i) {
00196 if (id == m_descriptor->PortNames[m_controlPortsIn[i].first]) {
00197 return getParameterValue(i);
00198 }
00199 }
00200
00201 return 0.0;
00202 }
00203
00204 void
00205 LADSPAPluginInstance::setParameter(std::string id, float value)
00206 {
00207 for (unsigned int i = 0; i < m_controlPortsIn.size(); ++i) {
00208 if (id == m_descriptor->PortNames[m_controlPortsIn[i].first]) {
00209 #ifdef DEBUG_LADSPA
00210 std::cerr << "LADSPAPluginInstance::setParameter: Found id "
00211 << id << " at control port " << i << std::endl;
00212 #endif
00213 setParameterValue(i, value);
00214 break;
00215 }
00216 }
00217 }
00218
00219 void
00220 LADSPAPluginInstance::init(int idealChannelCount)
00221 {
00222 #ifdef DEBUG_LADSPA
00223 std::cerr << "LADSPAPluginInstance::init(" << idealChannelCount << "): plugin has "
00224 << m_descriptor->PortCount << " ports" << std::endl;
00225 #endif
00226
00227
00228
00229 for (unsigned long i = 0; i < m_descriptor->PortCount; ++i) {
00230
00231 if (LADSPA_IS_PORT_AUDIO(m_descriptor->PortDescriptors[i])) {
00232
00233 if (LADSPA_IS_PORT_INPUT(m_descriptor->PortDescriptors[i])) {
00234 #ifdef DEBUG_LADSPA
00235 std::cerr << "LADSPAPluginInstance::init: port " << i << " is audio in" << std::endl;
00236 #endif
00237 m_audioPortsIn.push_back(i);
00238 } else {
00239 #ifdef DEBUG_LADSPA
00240 std::cerr << "LADSPAPluginInstance::init: port " << i << " is audio out" << std::endl;
00241 #endif
00242 m_audioPortsOut.push_back(i);
00243 }
00244
00245 } else if (LADSPA_IS_PORT_CONTROL(m_descriptor->PortDescriptors[i])) {
00246
00247 if (LADSPA_IS_PORT_INPUT(m_descriptor->PortDescriptors[i])) {
00248
00249 #ifdef DEBUG_LADSPA
00250 std::cerr << "LADSPAPluginInstance::init: port " << i << " is control in" << std::endl;
00251 #endif
00252 LADSPA_Data *data = new LADSPA_Data(0.0);
00253 m_controlPortsIn.push_back(
00254 std::pair<unsigned long, LADSPA_Data*>(i, data));
00255
00256 } else {
00257
00258 #ifdef DEBUG_LADSPA
00259 std::cerr << "LADSPAPluginInstance::init: port " << i << " is control out" << std::endl;
00260 #endif
00261 LADSPA_Data *data = new LADSPA_Data(0.0);
00262 m_controlPortsOut.push_back(
00263 std::pair<unsigned long, LADSPA_Data*>(i, data));
00264 if (!strcmp(m_descriptor->PortNames[i], "latency") ||
00265 !strcmp(m_descriptor->PortNames[i], "_latency")) {
00266 #ifdef DEBUG_LADSPA
00267 std::cerr << "Wooo! We have a latency port!" << std::endl;
00268 #endif
00269 m_latencyPort = data;
00270 }
00271
00272 }
00273 }
00274 #ifdef DEBUG_LADSPA
00275 else
00276 std::cerr << "LADSPAPluginInstance::init - "
00277 << "unrecognised port type" << std::endl;
00278 #endif
00279 }
00280
00281 m_instanceCount = 1;
00282
00283 if (idealChannelCount > 0) {
00284 if (m_audioPortsIn.size() == 1) {
00285
00286 m_instanceCount = idealChannelCount;
00287 }
00288 }
00289 }
00290
00291 size_t
00292 LADSPAPluginInstance::getLatency()
00293 {
00294 if (m_latencyPort) {
00295 if (!m_run) {
00296 for (size_t i = 0; i < getAudioInputCount(); ++i) {
00297 for (size_t j = 0; j < m_blockSize; ++j) {
00298 m_inputBuffers[i][j] = 0.f;
00299 }
00300 }
00301 run(Vamp::RealTime::zeroTime);
00302 }
00303 if (*m_latencyPort > 0) return (size_t)*m_latencyPort;
00304 }
00305 return 0;
00306 }
00307
00308 void
00309 LADSPAPluginInstance::silence()
00310 {
00311 if (isOK()) {
00312 deactivate();
00313 activate();
00314 }
00315 }
00316
00317 void
00318 LADSPAPluginInstance::setIdealChannelCount(size_t channels)
00319 {
00320 if (m_audioPortsIn.size() != 1 || channels == m_instanceCount) {
00321 silence();
00322 return;
00323 }
00324
00325 if (isOK()) {
00326 deactivate();
00327 }
00328
00330
00331 cleanup();
00332 m_instanceCount = channels;
00333 instantiate(m_sampleRate);
00334 if (isOK()) {
00335 connectPorts();
00336 activate();
00337 }
00338 }
00339
00340
00341 LADSPAPluginInstance::~LADSPAPluginInstance()
00342 {
00343 #ifdef DEBUG_LADSPA
00344 std::cerr << "LADSPAPluginInstance::~LADSPAPluginInstance" << std::endl;
00345 #endif
00346
00347 if (m_instanceHandles.size() != 0) {
00348 deactivate();
00349 }
00350
00351 cleanup();
00352
00353 for (unsigned int i = 0; i < m_controlPortsIn.size(); ++i)
00354 delete m_controlPortsIn[i].second;
00355
00356 for (unsigned int i = 0; i < m_controlPortsOut.size(); ++i)
00357 delete m_controlPortsOut[i].second;
00358
00359 m_controlPortsIn.clear();
00360 m_controlPortsOut.clear();
00361
00362 if (m_ownBuffers) {
00363 for (size_t i = 0; i < m_instanceCount * m_audioPortsIn.size(); ++i) {
00364 delete[] m_inputBuffers[i];
00365 }
00366 for (size_t i = 0; i < m_instanceCount * m_audioPortsOut.size(); ++i) {
00367 delete[] m_outputBuffers[i];
00368 }
00369
00370 delete[] m_inputBuffers;
00371 delete[] m_outputBuffers;
00372 }
00373
00374 m_audioPortsIn.clear();
00375 m_audioPortsOut.clear();
00376 }
00377
00378
00379 void
00380 LADSPAPluginInstance::instantiate(unsigned long sampleRate)
00381 {
00382 #ifdef DEBUG_LADSPA
00383 std::cout << "LADSPAPluginInstance::instantiate - plugin unique id = "
00384 << m_descriptor->UniqueID << std::endl;
00385 #endif
00386 if (!m_descriptor) return;
00387
00388 if (!m_descriptor->instantiate) {
00389 std::cerr << "Bad plugin: plugin id " << m_descriptor->UniqueID
00390 << ":" << m_descriptor->Label
00391 << " has no instantiate method!" << std::endl;
00392 return;
00393 }
00394
00395 for (size_t i = 0; i < m_instanceCount; ++i) {
00396 m_instanceHandles.push_back
00397 (m_descriptor->instantiate(m_descriptor, sampleRate));
00398 }
00399 }
00400
00401 void
00402 LADSPAPluginInstance::activate()
00403 {
00404 if (!m_descriptor || !m_descriptor->activate) return;
00405
00406 for (std::vector<LADSPA_Handle>::iterator hi = m_instanceHandles.begin();
00407 hi != m_instanceHandles.end(); ++hi) {
00408 m_descriptor->activate(*hi);
00409 }
00410 }
00411
00412 void
00413 LADSPAPluginInstance::connectPorts()
00414 {
00415 if (!m_descriptor || !m_descriptor->connect_port) return;
00416
00417 assert(sizeof(LADSPA_Data) == sizeof(float));
00418 assert(sizeof(sample_t) == sizeof(float));
00419
00420 LADSPAPluginFactory *f = dynamic_cast<LADSPAPluginFactory *>(m_factory);
00421 int inbuf = 0, outbuf = 0;
00422
00423 for (std::vector<LADSPA_Handle>::iterator hi = m_instanceHandles.begin();
00424 hi != m_instanceHandles.end(); ++hi) {
00425
00426 for (unsigned int i = 0; i < m_audioPortsIn.size(); ++i) {
00427 m_descriptor->connect_port(*hi,
00428 m_audioPortsIn[i],
00429 (LADSPA_Data *)m_inputBuffers[inbuf]);
00430 ++inbuf;
00431 }
00432
00433 for (unsigned int i = 0; i < m_audioPortsOut.size(); ++i) {
00434 m_descriptor->connect_port(*hi,
00435 m_audioPortsOut[i],
00436 (LADSPA_Data *)m_outputBuffers[outbuf]);
00437 ++outbuf;
00438 }
00439
00440
00441
00442
00443
00444
00445
00446 for (unsigned int i = 0; i < m_controlPortsIn.size(); ++i) {
00447 m_descriptor->connect_port(*hi,
00448 m_controlPortsIn[i].first,
00449 m_controlPortsIn[i].second);
00450 if (f) {
00451 float defaultValue = f->getPortDefault
00452 (m_descriptor, m_controlPortsIn[i].first);
00453 *m_controlPortsIn[i].second = defaultValue;
00454 }
00455 }
00456
00457 for (unsigned int i = 0; i < m_controlPortsOut.size(); ++i) {
00458 m_descriptor->connect_port(*hi,
00459 m_controlPortsOut[i].first,
00460 m_controlPortsOut[i].second);
00461 }
00462 }
00463 }
00464
00465 unsigned int
00466 LADSPAPluginInstance::getParameterCount() const
00467 {
00468 return m_controlPortsIn.size();
00469 }
00470
00471 void
00472 LADSPAPluginInstance::setParameterValue(unsigned int parameter, float value)
00473 {
00474 if (parameter >= m_controlPortsIn.size()) return;
00475
00476 unsigned int portNumber = m_controlPortsIn[parameter].first;
00477
00478 LADSPAPluginFactory *f = dynamic_cast<LADSPAPluginFactory *>(m_factory);
00479 if (f) {
00480 if (value < f->getPortMinimum(m_descriptor, portNumber)) {
00481 value = f->getPortMinimum(m_descriptor, portNumber);
00482 }
00483 if (value > f->getPortMaximum(m_descriptor, portNumber)) {
00484 value = f->getPortMaximum(m_descriptor, portNumber);
00485 }
00486 }
00487
00488 (*m_controlPortsIn[parameter].second) = value;
00489 }
00490
00491 float
00492 LADSPAPluginInstance::getControlOutputValue(size_t output) const
00493 {
00494 if (output > m_controlPortsOut.size()) return 0.0;
00495 return (*m_controlPortsOut[output].second);
00496 }
00497
00498 float
00499 LADSPAPluginInstance::getParameterValue(unsigned int parameter) const
00500 {
00501 if (parameter >= m_controlPortsIn.size()) return 0.0;
00502 return (*m_controlPortsIn[parameter].second);
00503 }
00504
00505 float
00506 LADSPAPluginInstance::getParameterDefault(unsigned int parameter) const
00507 {
00508 if (parameter >= m_controlPortsIn.size()) return 0.0;
00509
00510 LADSPAPluginFactory *f = dynamic_cast<LADSPAPluginFactory *>(m_factory);
00511 if (f) {
00512 return f->getPortDefault(m_descriptor, m_controlPortsIn[parameter].first);
00513 } else {
00514 return 0.0f;
00515 }
00516 }
00517
00518 int
00519 LADSPAPluginInstance::getParameterDisplayHint(unsigned int parameter) const
00520 {
00521 if (parameter >= m_controlPortsIn.size()) return 0.0;
00522
00523 LADSPAPluginFactory *f = dynamic_cast<LADSPAPluginFactory *>(m_factory);
00524 if (f) {
00525 return f->getPortDisplayHint(m_descriptor, m_controlPortsIn[parameter].first);
00526 } else {
00527 return PortHint::NoHint;
00528 }
00529 }
00530
00531 void
00532 LADSPAPluginInstance::run(const Vamp::RealTime &)
00533 {
00534 if (!m_descriptor || !m_descriptor->run) return;
00535
00536 for (std::vector<LADSPA_Handle>::iterator hi = m_instanceHandles.begin();
00537 hi != m_instanceHandles.end(); ++hi) {
00538
00539 m_descriptor->run(*hi, m_blockSize);
00540 }
00541
00542 m_run = true;
00543 }
00544
00545 void
00546 LADSPAPluginInstance::deactivate()
00547 {
00548 if (!m_descriptor || !m_descriptor->deactivate) return;
00549
00550 for (std::vector<LADSPA_Handle>::iterator hi = m_instanceHandles.begin();
00551 hi != m_instanceHandles.end(); ++hi) {
00552 m_descriptor->deactivate(*hi);
00553 }
00554 }
00555
00556 void
00557 LADSPAPluginInstance::cleanup()
00558 {
00559 if (!m_descriptor) return;
00560
00561 if (!m_descriptor->cleanup) {
00562 std::cerr << "Bad plugin: plugin id " << m_descriptor->UniqueID
00563 << ":" << m_descriptor->Label
00564 << " has no cleanup method!" << std::endl;
00565 return;
00566 }
00567
00568 for (std::vector<LADSPA_Handle>::iterator hi = m_instanceHandles.begin();
00569 hi != m_instanceHandles.end(); ++hi) {
00570 m_descriptor->cleanup(*hi);
00571 }
00572
00573 m_instanceHandles.clear();
00574 }
00575
00576