LADSPAPluginInstance.cpp

Go to the documentation of this file.
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     
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     // Discover ports numbers and identities
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             // mono plugin: duplicate it if need be
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) { // "isOK()"
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         // If there is more than one instance, they all share the same
00441         // control port ins (and outs, for the moment, because we
00442         // don't actually do anything with the outs anyway -- but they
00443         // do have to be connected as the plugin can't know if they're
00444         // not and will write to them anyway).
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 

Generated on Wed Feb 20 15:45:26 2008 for SonicVisualiser by  doxygen 1.5.1