svcore
1.9
|
00001 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ 00002 00003 /* 00004 Sonic Visualiser 00005 An audio file viewer and annotation editor. 00006 Centre for Digital Music, Queen Mary, University of London. 00007 00008 This program is free software; you can redistribute it and/or 00009 modify it under the terms of the GNU General Public License as 00010 published by the Free Software Foundation; either version 2 of the 00011 License, or (at your option) any later version. See the file 00012 COPYING included with this distribution for more information. 00013 */ 00014 00015 /* 00016 This is a modified version of a source file from the 00017 Rosegarden MIDI and audio sequencer and notation editor. 00018 This file copyright 2000-2006 Chris Cannam, Richard Bown, and QMUL. 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 //#define DEBUG_LADSPA 1 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 if (!f) return list; 00127 00128 for (unsigned int i = 0; i < m_controlPortsIn.size(); ++i) { 00129 00130 ParameterDescriptor pd; 00131 unsigned int pn = m_controlPortsIn[i].first; 00132 00133 pd.identifier = m_descriptor->PortNames[pn]; 00134 pd.name = pd.identifier; 00135 pd.description = ""; 00136 pd.minValue = f->getPortMinimum(m_descriptor, pn); 00137 pd.maxValue = f->getPortMaximum(m_descriptor, pn); 00138 pd.defaultValue = f->getPortDefault(m_descriptor, pn); 00139 00140 float q = f->getPortQuantization(m_descriptor, pn); 00141 if (q == 0.0) { 00142 pd.isQuantized = false; 00143 } else { 00144 pd.isQuantized = true; 00145 pd.quantizeStep = q; 00146 } 00147 00148 bool haveLabels = false; 00149 00150 #ifdef HAVE_LRDF 00151 if (pd.isQuantized && pd.quantizeStep == 1.0) { 00152 00153 lrdf_defaults *defaults = 00154 lrdf_get_scale_values(m_descriptor->UniqueID, pn); 00155 00156 if (defaults) { 00157 if (defaults->count > 0) { 00158 std::map<int, std::string> values; 00159 size_t v = 0; 00160 for (size_t i = 0; i < defaults->count; ++i) { 00161 v = size_t(lrintf(fabsf(defaults->items[i].value))); 00162 values[v] = defaults->items[i].label; 00163 } 00164 for (size_t i = 0; i <= v; ++i) { 00165 pd.valueNames.push_back(values[i]); 00166 } 00167 haveLabels = true; 00168 } 00169 lrdf_free_setting_values(defaults); 00170 } 00171 } 00172 #endif 00173 00174 if (haveLabels) { 00175 pd.name = QString(pd.name.c_str()) 00176 .replace(QRegExp("\\([^\\(\\)]+=[^\\(\\)]+\\)$"), "") 00177 .toStdString(); 00178 } else { 00179 static QRegExp unitRE("[\\[\\(]([A-Za-z0-9/]+)[\\)\\]]$"); 00180 if (unitRE.indexIn(pd.name.c_str()) >= 0) { 00181 pd.unit = unitRE.cap(1).toStdString(); 00182 pd.name = QString(pd.name.c_str()) 00183 .replace(unitRE, "").toStdString(); 00184 } 00185 } 00186 00187 list.push_back(pd); 00188 } 00189 00190 return list; 00191 } 00192 00193 float 00194 LADSPAPluginInstance::getParameter(std::string id) const 00195 { 00196 for (unsigned int i = 0; i < m_controlPortsIn.size(); ++i) { 00197 if (id == m_descriptor->PortNames[m_controlPortsIn[i].first]) { 00198 return getParameterValue(i); 00199 } 00200 } 00201 00202 return 0.0; 00203 } 00204 00205 void 00206 LADSPAPluginInstance::setParameter(std::string id, float value) 00207 { 00208 for (unsigned int i = 0; i < m_controlPortsIn.size(); ++i) { 00209 if (id == m_descriptor->PortNames[m_controlPortsIn[i].first]) { 00210 #ifdef DEBUG_LADSPA 00211 SVDEBUG << "LADSPAPluginInstance::setParameter: Found id " 00212 << id << " at control port " << i << endl; 00213 #endif 00214 setParameterValue(i, value); 00215 break; 00216 } 00217 } 00218 } 00219 00220 void 00221 LADSPAPluginInstance::init(int idealChannelCount) 00222 { 00223 #ifdef DEBUG_LADSPA 00224 SVDEBUG << "LADSPAPluginInstance::init(" << idealChannelCount << "): plugin has " 00225 << m_descriptor->PortCount << " ports" << endl; 00226 #endif 00227 00228 // Discover ports numbers and identities 00229 // 00230 for (unsigned long i = 0; i < m_descriptor->PortCount; ++i) { 00231 00232 if (LADSPA_IS_PORT_AUDIO(m_descriptor->PortDescriptors[i])) { 00233 00234 if (LADSPA_IS_PORT_INPUT(m_descriptor->PortDescriptors[i])) { 00235 #ifdef DEBUG_LADSPA 00236 SVDEBUG << "LADSPAPluginInstance::init: port " << i << " is audio in" << endl; 00237 #endif 00238 m_audioPortsIn.push_back(i); 00239 } else { 00240 #ifdef DEBUG_LADSPA 00241 SVDEBUG << "LADSPAPluginInstance::init: port " << i << " is audio out" << endl; 00242 #endif 00243 m_audioPortsOut.push_back(i); 00244 } 00245 00246 } else if (LADSPA_IS_PORT_CONTROL(m_descriptor->PortDescriptors[i])) { 00247 00248 if (LADSPA_IS_PORT_INPUT(m_descriptor->PortDescriptors[i])) { 00249 00250 #ifdef DEBUG_LADSPA 00251 SVDEBUG << "LADSPAPluginInstance::init: port " << i << " is control in" << endl; 00252 #endif 00253 LADSPA_Data *data = new LADSPA_Data(0.0); 00254 m_controlPortsIn.push_back( 00255 std::pair<unsigned long, LADSPA_Data*>(i, data)); 00256 00257 } else { 00258 00259 #ifdef DEBUG_LADSPA 00260 SVDEBUG << "LADSPAPluginInstance::init: port " << i << " is control out" << endl; 00261 #endif 00262 LADSPA_Data *data = new LADSPA_Data(0.0); 00263 m_controlPortsOut.push_back( 00264 std::pair<unsigned long, LADSPA_Data*>(i, data)); 00265 if (!strcmp(m_descriptor->PortNames[i], "latency") || 00266 !strcmp(m_descriptor->PortNames[i], "_latency")) { 00267 #ifdef DEBUG_LADSPA 00268 cerr << "Wooo! We have a latency port!" << endl; 00269 #endif 00270 m_latencyPort = data; 00271 } 00272 00273 } 00274 } 00275 #ifdef DEBUG_LADSPA 00276 else 00277 SVDEBUG << "LADSPAPluginInstance::init - " 00278 << "unrecognised port type" << endl; 00279 #endif 00280 } 00281 00282 m_instanceCount = 1; 00283 00284 if (idealChannelCount > 0) { 00285 if (m_audioPortsIn.size() == 1) { 00286 // mono plugin: duplicate it if need be 00287 m_instanceCount = idealChannelCount; 00288 } 00289 } 00290 } 00291 00292 size_t 00293 LADSPAPluginInstance::getLatency() 00294 { 00295 if (m_latencyPort) { 00296 if (!m_run) { 00297 for (size_t i = 0; i < getAudioInputCount(); ++i) { 00298 for (size_t j = 0; j < m_blockSize; ++j) { 00299 m_inputBuffers[i][j] = 0.f; 00300 } 00301 } 00302 run(Vamp::RealTime::zeroTime); 00303 } 00304 if (*m_latencyPort > 0) return (size_t)*m_latencyPort; 00305 } 00306 return 0; 00307 } 00308 00309 void 00310 LADSPAPluginInstance::silence() 00311 { 00312 if (isOK()) { 00313 deactivate(); 00314 activate(); 00315 } 00316 } 00317 00318 void 00319 LADSPAPluginInstance::setIdealChannelCount(size_t channels) 00320 { 00321 if (m_audioPortsIn.size() != 1 || channels == m_instanceCount) { 00322 silence(); 00323 return; 00324 } 00325 00326 if (isOK()) { 00327 deactivate(); 00328 } 00329 00331 00332 cleanup(); 00333 m_instanceCount = channels; 00334 instantiate(m_sampleRate); 00335 if (isOK()) { 00336 connectPorts(); 00337 activate(); 00338 } 00339 } 00340 00341 00342 LADSPAPluginInstance::~LADSPAPluginInstance() 00343 { 00344 #ifdef DEBUG_LADSPA 00345 SVDEBUG << "LADSPAPluginInstance::~LADSPAPluginInstance" << endl; 00346 #endif 00347 00348 if (m_instanceHandles.size() != 0) { // "isOK()" 00349 deactivate(); 00350 } 00351 00352 cleanup(); 00353 00354 for (unsigned int i = 0; i < m_controlPortsIn.size(); ++i) 00355 delete m_controlPortsIn[i].second; 00356 00357 for (unsigned int i = 0; i < m_controlPortsOut.size(); ++i) 00358 delete m_controlPortsOut[i].second; 00359 00360 m_controlPortsIn.clear(); 00361 m_controlPortsOut.clear(); 00362 00363 if (m_ownBuffers) { 00364 for (size_t i = 0; i < m_instanceCount * m_audioPortsIn.size(); ++i) { 00365 delete[] m_inputBuffers[i]; 00366 } 00367 for (size_t i = 0; i < m_instanceCount * m_audioPortsOut.size(); ++i) { 00368 delete[] m_outputBuffers[i]; 00369 } 00370 00371 delete[] m_inputBuffers; 00372 delete[] m_outputBuffers; 00373 } 00374 00375 m_audioPortsIn.clear(); 00376 m_audioPortsOut.clear(); 00377 } 00378 00379 00380 void 00381 LADSPAPluginInstance::instantiate(unsigned long sampleRate) 00382 { 00383 if (!m_descriptor) return; 00384 00385 #ifdef DEBUG_LADSPA 00386 cout << "LADSPAPluginInstance::instantiate - plugin unique id = " 00387 << m_descriptor->UniqueID << endl; 00388 #endif 00389 00390 if (!m_descriptor->instantiate) { 00391 cerr << "Bad plugin: plugin id " << m_descriptor->UniqueID 00392 << ":" << m_descriptor->Label 00393 << " has no instantiate method!" << endl; 00394 return; 00395 } 00396 00397 for (size_t i = 0; i < m_instanceCount; ++i) { 00398 m_instanceHandles.push_back 00399 (m_descriptor->instantiate(m_descriptor, sampleRate)); 00400 } 00401 } 00402 00403 void 00404 LADSPAPluginInstance::activate() 00405 { 00406 if (!m_descriptor || !m_descriptor->activate) return; 00407 00408 for (std::vector<LADSPA_Handle>::iterator hi = m_instanceHandles.begin(); 00409 hi != m_instanceHandles.end(); ++hi) { 00410 m_descriptor->activate(*hi); 00411 } 00412 } 00413 00414 void 00415 LADSPAPluginInstance::connectPorts() 00416 { 00417 if (!m_descriptor || !m_descriptor->connect_port) return; 00418 00419 assert(sizeof(LADSPA_Data) == sizeof(float)); 00420 assert(sizeof(sample_t) == sizeof(float)); 00421 00422 LADSPAPluginFactory *f = dynamic_cast<LADSPAPluginFactory *>(m_factory); 00423 int inbuf = 0, outbuf = 0; 00424 00425 for (std::vector<LADSPA_Handle>::iterator hi = m_instanceHandles.begin(); 00426 hi != m_instanceHandles.end(); ++hi) { 00427 00428 for (unsigned int i = 0; i < m_audioPortsIn.size(); ++i) { 00429 m_descriptor->connect_port(*hi, 00430 m_audioPortsIn[i], 00431 (LADSPA_Data *)m_inputBuffers[inbuf]); 00432 ++inbuf; 00433 } 00434 00435 for (unsigned int i = 0; i < m_audioPortsOut.size(); ++i) { 00436 m_descriptor->connect_port(*hi, 00437 m_audioPortsOut[i], 00438 (LADSPA_Data *)m_outputBuffers[outbuf]); 00439 ++outbuf; 00440 } 00441 00442 // If there is more than one instance, they all share the same 00443 // control port ins (and outs, for the moment, because we 00444 // don't actually do anything with the outs anyway -- but they 00445 // do have to be connected as the plugin can't know if they're 00446 // not and will write to them anyway). 00447 00448 for (unsigned int i = 0; i < m_controlPortsIn.size(); ++i) { 00449 m_descriptor->connect_port(*hi, 00450 m_controlPortsIn[i].first, 00451 m_controlPortsIn[i].second); 00452 if (f) { 00453 float defaultValue = f->getPortDefault 00454 (m_descriptor, m_controlPortsIn[i].first); 00455 *m_controlPortsIn[i].second = defaultValue; 00456 } 00457 } 00458 00459 for (unsigned int i = 0; i < m_controlPortsOut.size(); ++i) { 00460 m_descriptor->connect_port(*hi, 00461 m_controlPortsOut[i].first, 00462 m_controlPortsOut[i].second); 00463 } 00464 } 00465 } 00466 00467 unsigned int 00468 LADSPAPluginInstance::getParameterCount() const 00469 { 00470 return m_controlPortsIn.size(); 00471 } 00472 00473 void 00474 LADSPAPluginInstance::setParameterValue(unsigned int parameter, float value) 00475 { 00476 if (parameter >= m_controlPortsIn.size()) return; 00477 00478 unsigned int portNumber = m_controlPortsIn[parameter].first; 00479 00480 LADSPAPluginFactory *f = dynamic_cast<LADSPAPluginFactory *>(m_factory); 00481 if (f) { 00482 if (value < f->getPortMinimum(m_descriptor, portNumber)) { 00483 value = f->getPortMinimum(m_descriptor, portNumber); 00484 } 00485 if (value > f->getPortMaximum(m_descriptor, portNumber)) { 00486 value = f->getPortMaximum(m_descriptor, portNumber); 00487 } 00488 } 00489 00490 (*m_controlPortsIn[parameter].second) = value; 00491 } 00492 00493 float 00494 LADSPAPluginInstance::getControlOutputValue(size_t output) const 00495 { 00496 if (output > m_controlPortsOut.size()) return 0.0; 00497 return (*m_controlPortsOut[output].second); 00498 } 00499 00500 float 00501 LADSPAPluginInstance::getParameterValue(unsigned int parameter) const 00502 { 00503 if (parameter >= m_controlPortsIn.size()) return 0.0; 00504 return (*m_controlPortsIn[parameter].second); 00505 } 00506 00507 float 00508 LADSPAPluginInstance::getParameterDefault(unsigned int parameter) const 00509 { 00510 if (parameter >= m_controlPortsIn.size()) return 0.0; 00511 00512 LADSPAPluginFactory *f = dynamic_cast<LADSPAPluginFactory *>(m_factory); 00513 if (f) { 00514 return f->getPortDefault(m_descriptor, m_controlPortsIn[parameter].first); 00515 } else { 00516 return 0.0f; 00517 } 00518 } 00519 00520 int 00521 LADSPAPluginInstance::getParameterDisplayHint(unsigned int parameter) const 00522 { 00523 if (parameter >= m_controlPortsIn.size()) return 0.0; 00524 00525 LADSPAPluginFactory *f = dynamic_cast<LADSPAPluginFactory *>(m_factory); 00526 if (f) { 00527 return f->getPortDisplayHint(m_descriptor, m_controlPortsIn[parameter].first); 00528 } else { 00529 return PortHint::NoHint; 00530 } 00531 } 00532 00533 void 00534 LADSPAPluginInstance::run(const Vamp::RealTime &, size_t count) 00535 { 00536 if (!m_descriptor || !m_descriptor->run) return; 00537 00538 if (count == 0) count = m_blockSize; 00539 00540 for (std::vector<LADSPA_Handle>::iterator hi = m_instanceHandles.begin(); 00541 hi != m_instanceHandles.end(); ++hi) { 00542 00543 m_descriptor->run(*hi, count); 00544 } 00545 00546 m_run = true; 00547 } 00548 00549 void 00550 LADSPAPluginInstance::deactivate() 00551 { 00552 if (!m_descriptor || !m_descriptor->deactivate) return; 00553 00554 for (std::vector<LADSPA_Handle>::iterator hi = m_instanceHandles.begin(); 00555 hi != m_instanceHandles.end(); ++hi) { 00556 m_descriptor->deactivate(*hi); 00557 } 00558 } 00559 00560 void 00561 LADSPAPluginInstance::cleanup() 00562 { 00563 if (!m_descriptor) return; 00564 00565 if (!m_descriptor->cleanup) { 00566 cerr << "Bad plugin: plugin id " << m_descriptor->UniqueID 00567 << ":" << m_descriptor->Label 00568 << " has no cleanup method!" << endl; 00569 return; 00570 } 00571 00572 for (std::vector<LADSPA_Handle>::iterator hi = m_instanceHandles.begin(); 00573 hi != m_instanceHandles.end(); ++hi) { 00574 m_descriptor->cleanup(*hi); 00575 } 00576 00577 m_instanceHandles.clear(); 00578 } 00579 00580