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 "DSSIPluginInstance.h"
00025 #include "PluginIdentifier.h"
00026 #include "LADSPAPluginFactory.h"
00027
00028
00029
00030
00031 #define EVENT_BUFFER_SIZE 1023
00032
00033 #ifdef DEBUG_DSSI
00034 static std::ostream &operator<<(std::ostream& o, const QString &s)
00035 {
00036 o << s.toLocal8Bit().data();
00037 return o;
00038 }
00039 #endif
00040
00041 DSSIPluginInstance::GroupMap DSSIPluginInstance::m_groupMap;
00042 snd_seq_event_t **DSSIPluginInstance::m_groupLocalEventBuffers = 0;
00043 size_t DSSIPluginInstance::m_groupLocalEventBufferCount = 0;
00044 Scavenger<ScavengerArrayWrapper<snd_seq_event_t *> > DSSIPluginInstance::m_bufferScavenger(2, 10);
00045 std::map<LADSPA_Handle, std::set<DSSIPluginInstance::NonRTPluginThread *> > DSSIPluginInstance::m_threads;
00046
00047
00048 DSSIPluginInstance::DSSIPluginInstance(RealTimePluginFactory *factory,
00049 int clientId,
00050 QString identifier,
00051 int position,
00052 unsigned long sampleRate,
00053 size_t blockSize,
00054 int idealChannelCount,
00055 const DSSI_Descriptor* descriptor) :
00056 RealTimePluginInstance(factory, identifier),
00057 m_client(clientId),
00058 m_position(position),
00059 m_descriptor(descriptor),
00060 m_programCacheValid(false),
00061 m_eventBuffer(EVENT_BUFFER_SIZE),
00062 m_blockSize(blockSize),
00063 m_idealChannelCount(idealChannelCount),
00064 m_sampleRate(sampleRate),
00065 m_latencyPort(0),
00066 m_run(false),
00067 m_bypassed(false),
00068 m_grouped(false),
00069 m_haveLastEventSendTime(false)
00070 {
00071 #ifdef DEBUG_DSSI
00072 std::cerr << "DSSIPluginInstance::DSSIPluginInstance(" << identifier << ")"
00073 << std::endl;
00074 #endif
00075
00076 init();
00077
00078 m_inputBuffers = new sample_t*[m_audioPortsIn.size()];
00079 m_outputBuffers = new sample_t*[m_outputBufferCount];
00080
00081 for (size_t i = 0; i < m_audioPortsIn.size(); ++i) {
00082 m_inputBuffers[i] = new sample_t[blockSize];
00083 }
00084 for (size_t i = 0; i < m_outputBufferCount; ++i) {
00085 m_outputBuffers[i] = new sample_t[blockSize];
00086 }
00087
00088 m_ownBuffers = true;
00089
00090 m_pending.lsb = m_pending.msb = m_pending.program = -1;
00091
00092 instantiate(sampleRate);
00093 if (isOK()) {
00094 connectPorts();
00095 activate();
00096 initialiseGroupMembership();
00097 }
00098 }
00099
00100 std::string
00101 DSSIPluginInstance::getIdentifier() const
00102 {
00103 return m_descriptor->LADSPA_Plugin->Label;
00104 }
00105
00106 std::string
00107 DSSIPluginInstance::getName() const
00108 {
00109 return m_descriptor->LADSPA_Plugin->Name;
00110 }
00111
00112 std::string
00113 DSSIPluginInstance::getDescription() const
00114 {
00115 return "";
00116 }
00117
00118 std::string
00119 DSSIPluginInstance::getMaker() const
00120 {
00121 return m_descriptor->LADSPA_Plugin->Maker;
00122 }
00123
00124 int
00125 DSSIPluginInstance::getPluginVersion() const
00126 {
00127 return 1;
00128 }
00129
00130 std::string
00131 DSSIPluginInstance::getCopyright() const
00132 {
00133 return m_descriptor->LADSPA_Plugin->Copyright;
00134 }
00135
00136 DSSIPluginInstance::ParameterList
00137 DSSIPluginInstance::getParameterDescriptors() const
00138 {
00139 ParameterList list;
00140 LADSPAPluginFactory *f = dynamic_cast<LADSPAPluginFactory *>(m_factory);
00141
00142 for (unsigned int i = 0; i < m_controlPortsIn.size(); ++i) {
00143
00144 ParameterDescriptor pd;
00145 unsigned int pn = m_controlPortsIn[i].first;
00146
00147 pd.identifier = m_descriptor->LADSPA_Plugin->PortNames[pn];
00148 pd.name = pd.identifier;
00149 pd.description = "";
00150 pd.minValue = f->getPortMinimum(m_descriptor->LADSPA_Plugin, pn);
00151 pd.maxValue = f->getPortMaximum(m_descriptor->LADSPA_Plugin, pn);
00152 pd.defaultValue = f->getPortDefault(m_descriptor->LADSPA_Plugin, pn);
00153
00154 float q = f->getPortQuantization(m_descriptor->LADSPA_Plugin, pn);
00155 if (q == 0.0) {
00156 pd.isQuantized = false;
00157 } else {
00158 pd.isQuantized = true;
00159 pd.quantizeStep = q;
00160 }
00161
00162 list.push_back(pd);
00163 }
00164
00165 return list;
00166 }
00167
00168 float
00169 DSSIPluginInstance::getParameter(std::string id) const
00170 {
00171 #ifdef DEBUG_DSSI
00172 std::cerr << "DSSIPluginInstance::getParameter(" << id << ")" << std::endl;
00173 #endif
00174 for (unsigned int i = 0; i < m_controlPortsIn.size(); ++i) {
00175 if (id == m_descriptor->LADSPA_Plugin->PortNames[m_controlPortsIn[i].first]) {
00176 #ifdef DEBUG_DSSI
00177 std::cerr << "Matches port " << i << std::endl;
00178 #endif
00179 float v = getParameterValue(i);
00180 #ifdef DEBUG_DSSI
00181 std::cerr << "Returning " << v << std::endl;
00182 #endif
00183 return v;
00184 }
00185 }
00186
00187 return 0.0;
00188 }
00189
00190 void
00191 DSSIPluginInstance::setParameter(std::string id, float value)
00192 {
00193 #ifdef DEBUG_DSSI
00194 std::cerr << "DSSIPluginInstance::setParameter(" << id << ", " << value << ")" << std::endl;
00195 #endif
00196
00197 for (unsigned int i = 0; i < m_controlPortsIn.size(); ++i) {
00198 if (id == m_descriptor->LADSPA_Plugin->PortNames[m_controlPortsIn[i].first]) {
00199 setParameterValue(i, value);
00200 break;
00201 }
00202 }
00203 }
00204
00205 void
00206 DSSIPluginInstance::init()
00207 {
00208 #ifdef DEBUG_DSSI
00209 std::cerr << "DSSIPluginInstance::init" << std::endl;
00210 #endif
00211
00212
00213
00214 const LADSPA_Descriptor *descriptor = m_descriptor->LADSPA_Plugin;
00215
00216 for (unsigned long i = 0; i < descriptor->PortCount; ++i)
00217 {
00218 if (LADSPA_IS_PORT_AUDIO(descriptor->PortDescriptors[i]))
00219 {
00220 if (LADSPA_IS_PORT_INPUT(descriptor->PortDescriptors[i])) {
00221 m_audioPortsIn.push_back(i);
00222 } else {
00223 m_audioPortsOut.push_back(i);
00224 }
00225 }
00226 else
00227 if (LADSPA_IS_PORT_CONTROL(descriptor->PortDescriptors[i]))
00228 {
00229 if (LADSPA_IS_PORT_INPUT(descriptor->PortDescriptors[i])) {
00230
00231 LADSPA_Data *data = new LADSPA_Data(0.0);
00232
00233 m_controlPortsIn.push_back(std::pair<unsigned long, LADSPA_Data*>
00234 (i, data));
00235
00236 m_backupControlPortsIn.push_back(0.0);
00237
00238 } else {
00239 LADSPA_Data *data = new LADSPA_Data(0.0);
00240 m_controlPortsOut.push_back(
00241 std::pair<unsigned long, LADSPA_Data*>(i, data));
00242 if (!strcmp(descriptor->PortNames[i], "latency") ||
00243 !strcmp(descriptor->PortNames[i], "_latency")) {
00244 #ifdef DEBUG_DSSI
00245 std::cerr << "Wooo! We have a latency port!" << std::endl;
00246 #endif
00247 m_latencyPort = data;
00248 }
00249 }
00250 }
00251 #ifdef DEBUG_DSSI
00252 else
00253 std::cerr << "DSSIPluginInstance::DSSIPluginInstance - "
00254 << "unrecognised port type" << std::endl;
00255 #endif
00256 }
00257
00258 m_outputBufferCount = std::max(m_idealChannelCount, m_audioPortsOut.size());
00259 }
00260
00261 size_t
00262 DSSIPluginInstance::getLatency()
00263 {
00264 size_t latency = 0;
00265
00266 #ifdef DEBUG_DSSI_PROCESS
00267 std::cerr << "DSSIPluginInstance::getLatency(): m_latencyPort " << m_latencyPort << ", m_run " << m_run << std::endl;
00268 #endif
00269
00270 if (m_latencyPort) {
00271 if (!m_run) {
00272 for (size_t i = 0; i < getAudioInputCount(); ++i) {
00273 for (size_t j = 0; j < m_blockSize; ++j) {
00274 m_inputBuffers[i][j] = 0.f;
00275 }
00276 }
00277 run(Vamp::RealTime::zeroTime);
00278 }
00279 latency = (size_t)(*m_latencyPort + 0.1);
00280 }
00281
00282 #ifdef DEBUG_DSSI_PROCESS
00283 std::cerr << "DSSIPluginInstance::getLatency(): latency is " << latency << std::endl;
00284 #endif
00285
00286 return latency;
00287 }
00288
00289 void
00290 DSSIPluginInstance::silence()
00291 {
00292 if (m_instanceHandle != 0) {
00293 deactivate();
00294 activate();
00295 }
00296 }
00297
00298 void
00299 DSSIPluginInstance::discardEvents()
00300 {
00301 m_eventBuffer.reset();
00302 }
00303
00304 void
00305 DSSIPluginInstance::setIdealChannelCount(size_t channels)
00306 {
00307 #ifdef DEBUG_DSSI
00308 std::cerr << "DSSIPluginInstance::setIdealChannelCount: channel count "
00309 << channels << " (was " << m_idealChannelCount << ")" << std::endl;
00310 #endif
00311
00312 if (channels == m_idealChannelCount) {
00313 silence();
00314 return;
00315 }
00316
00317 if (m_instanceHandle != 0) {
00318 deactivate();
00319 }
00320
00321 m_idealChannelCount = channels;
00322
00323 if (channels > m_outputBufferCount) {
00324
00325 for (size_t i = 0; i < m_outputBufferCount; ++i) {
00326 delete[] m_outputBuffers[i];
00327 }
00328
00329 delete[] m_outputBuffers;
00330
00331 m_outputBufferCount = channels;
00332
00333 m_outputBuffers = new sample_t*[m_outputBufferCount];
00334
00335 for (size_t i = 0; i < m_outputBufferCount; ++i) {
00336 m_outputBuffers[i] = new sample_t[m_blockSize];
00337 }
00338
00339 connectPorts();
00340 }
00341
00342 if (m_instanceHandle != 0) {
00343 activate();
00344 }
00345 }
00346
00347 void
00348 DSSIPluginInstance::detachFromGroup()
00349 {
00350 if (!m_grouped) return;
00351 m_groupMap[m_identifier].erase(this);
00352 m_grouped = false;
00353 }
00354
00355 void
00356 DSSIPluginInstance::initialiseGroupMembership()
00357 {
00358 if (!m_descriptor->run_multiple_synths) {
00359 m_grouped = false;
00360 return;
00361 }
00362
00364
00365 size_t pluginsInGroup = m_groupMap[m_identifier].size();
00366
00367 if (++pluginsInGroup > m_groupLocalEventBufferCount) {
00368
00369 size_t nextBufferCount = pluginsInGroup * 2;
00370
00371 snd_seq_event_t **eventLocalBuffers = new snd_seq_event_t *[nextBufferCount];
00372
00373 for (size_t i = 0; i < m_groupLocalEventBufferCount; ++i) {
00374 eventLocalBuffers[i] = m_groupLocalEventBuffers[i];
00375 }
00376 for (size_t i = m_groupLocalEventBufferCount; i < nextBufferCount; ++i) {
00377 eventLocalBuffers[i] = new snd_seq_event_t[EVENT_BUFFER_SIZE];
00378 }
00379
00380 if (m_groupLocalEventBuffers) {
00381 m_bufferScavenger.claim(new ScavengerArrayWrapper<snd_seq_event_t *>
00382 (m_groupLocalEventBuffers));
00383 }
00384
00385 m_groupLocalEventBuffers = eventLocalBuffers;
00386 m_groupLocalEventBufferCount = nextBufferCount;
00387 }
00388
00389 m_grouped = true;
00390 m_groupMap[m_identifier].insert(this);
00391 }
00392
00393 DSSIPluginInstance::~DSSIPluginInstance()
00394 {
00395 #ifdef DEBUG_DSSI
00396 std::cerr << "DSSIPluginInstance::~DSSIPluginInstance" << std::endl;
00397 #endif
00398
00399 if (m_threads.find(m_instanceHandle) != m_threads.end()) {
00400
00401 for (std::set<NonRTPluginThread *>::iterator i =
00402 m_threads[m_instanceHandle].begin();
00403 i != m_threads[m_instanceHandle].end(); ++i) {
00404
00405 (*i)->setExiting();
00406 (*i)->wait();
00407 delete *i;
00408 }
00409
00410 m_threads.erase(m_instanceHandle);
00411 }
00412
00413 detachFromGroup();
00414
00415 if (m_instanceHandle != 0) {
00416 deactivate();
00417 }
00418
00419 cleanup();
00420
00421 for (unsigned int i = 0; i < m_controlPortsIn.size(); ++i)
00422 delete m_controlPortsIn[i].second;
00423
00424 for (unsigned int i = 0; i < m_controlPortsOut.size(); ++i)
00425 delete m_controlPortsOut[i].second;
00426
00427 m_controlPortsIn.clear();
00428 m_controlPortsOut.clear();
00429
00430 if (m_ownBuffers) {
00431 for (size_t i = 0; i < m_audioPortsIn.size(); ++i) {
00432 delete[] m_inputBuffers[i];
00433 }
00434 for (size_t i = 0; i < m_outputBufferCount; ++i) {
00435 delete[] m_outputBuffers[i];
00436 }
00437
00438 delete[] m_inputBuffers;
00439 delete[] m_outputBuffers;
00440 }
00441
00442 m_audioPortsIn.clear();
00443 m_audioPortsOut.clear();
00444 }
00445
00446
00447 void
00448 DSSIPluginInstance::instantiate(unsigned long sampleRate)
00449 {
00450 #ifdef DEBUG_DSSI
00451 std::cout << "DSSIPluginInstance::instantiate - plugin \"unique\" id = "
00452 << m_descriptor->LADSPA_Plugin->UniqueID << std::endl;
00453 #endif
00454 if (!m_descriptor) return;
00455
00456 const LADSPA_Descriptor *descriptor = m_descriptor->LADSPA_Plugin;
00457
00458 if (!descriptor->instantiate) {
00459 std::cerr << "Bad plugin: plugin id " << descriptor->UniqueID
00460 << ":" << descriptor->Label
00461 << " has no instantiate method!" << std::endl;
00462 return;
00463 }
00464
00465 m_instanceHandle = descriptor->instantiate(descriptor, sampleRate);
00466
00467 if (m_instanceHandle) {
00468
00469 if (m_descriptor->get_midi_controller_for_port) {
00470
00471 for (unsigned long i = 0; i < descriptor->PortCount; ++i) {
00472
00473 if (LADSPA_IS_PORT_CONTROL(descriptor->PortDescriptors[i]) &&
00474 LADSPA_IS_PORT_INPUT(descriptor->PortDescriptors[i])) {
00475
00476 int controller = m_descriptor->get_midi_controller_for_port
00477 (m_instanceHandle, i);
00478
00479 if (controller != 0 && controller != 32 &&
00480 DSSI_IS_CC(controller)) {
00481
00482 m_controllerMap[DSSI_CC_NUMBER(controller)] = i;
00483 }
00484 }
00485 }
00486 }
00487 }
00488 }
00489
00490 void
00491 DSSIPluginInstance::checkProgramCache() const
00492 {
00493 if (m_programCacheValid) return;
00494 m_cachedPrograms.clear();
00495
00496 #ifdef DEBUG_DSSI
00497 std::cerr << "DSSIPluginInstance::checkProgramCache" << std::endl;
00498 #endif
00499
00500 if (!m_descriptor || !m_descriptor->get_program) {
00501 m_programCacheValid = true;
00502 return;
00503 }
00504
00505 unsigned long index = 0;
00506 const DSSI_Program_Descriptor *programDescriptor;
00507 while ((programDescriptor = m_descriptor->get_program(m_instanceHandle, index))) {
00508 ++index;
00509 ProgramDescriptor d;
00510 d.bank = programDescriptor->Bank;
00511 d.program = programDescriptor->Program;
00512 d.name = programDescriptor->Name;
00513 m_cachedPrograms.push_back(d);
00514 }
00515
00516 #ifdef DEBUG_DSSI
00517 std::cerr << "DSSIPluginInstance::checkProgramCache: have " << m_cachedPrograms.size() << " programs" << std::endl;
00518 #endif
00519
00520 m_programCacheValid = true;
00521 }
00522
00523 DSSIPluginInstance::ProgramList
00524 DSSIPluginInstance::getPrograms() const
00525 {
00526 #ifdef DEBUG_DSSI
00527 std::cerr << "DSSIPluginInstance::getPrograms" << std::endl;
00528 #endif
00529
00530 if (!m_descriptor) return ProgramList();
00531
00532 checkProgramCache();
00533
00534 ProgramList programs;
00535
00536 for (std::vector<ProgramDescriptor>::iterator i = m_cachedPrograms.begin();
00537 i != m_cachedPrograms.end(); ++i) {
00538 programs.push_back(i->name);
00539 }
00540
00541 return programs;
00542 }
00543
00544 std::string
00545 DSSIPluginInstance::getProgram(int bank, int program) const
00546 {
00547 #ifdef DEBUG_DSSI
00548 std::cerr << "DSSIPluginInstance::getProgram(" << bank << "," << program << ")" << std::endl;
00549 #endif
00550
00551 if (!m_descriptor) return std::string();
00552
00553 checkProgramCache();
00554
00555 for (std::vector<ProgramDescriptor>::iterator i = m_cachedPrograms.begin();
00556 i != m_cachedPrograms.end(); ++i) {
00557 if (i->bank == bank && i->program == program) return i->name;
00558 }
00559
00560 return std::string();
00561 }
00562
00563 unsigned long
00564 DSSIPluginInstance::getProgram(std::string name) const
00565 {
00566 #ifdef DEBUG_DSSI
00567 std::cerr << "DSSIPluginInstance::getProgram(" << name << ")" << std::endl;
00568 #endif
00569
00570 if (!m_descriptor) return 0;
00571
00572 checkProgramCache();
00573
00574 unsigned long rv;
00575
00576 for (std::vector<ProgramDescriptor>::iterator i = m_cachedPrograms.begin();
00577 i != m_cachedPrograms.end(); ++i) {
00578 if (i->name == name) {
00579 rv = i->bank;
00580 rv = (rv << 16) + i->program;
00581 return rv;
00582 }
00583 }
00584
00585 return 0;
00586 }
00587
00588 std::string
00589 DSSIPluginInstance::getCurrentProgram() const
00590 {
00591 return m_program;
00592 }
00593
00594 void
00595 DSSIPluginInstance::selectProgram(std::string program)
00596 {
00597 selectProgramAux(program, true);
00598 }
00599
00600 void
00601 DSSIPluginInstance::selectProgramAux(std::string program, bool backupPortValues)
00602 {
00603 #ifdef DEBUG_DSSI
00604 std::cerr << "DSSIPluginInstance::selectProgram(" << program << ")" << std::endl;
00605 #endif
00606
00607 if (!m_descriptor) return;
00608
00609 checkProgramCache();
00610
00611 if (!m_descriptor->select_program) return;
00612
00613 bool found = false;
00614 unsigned long bankNo = 0, programNo = 0;
00615
00616 for (std::vector<ProgramDescriptor>::iterator i = m_cachedPrograms.begin();
00617 i != m_cachedPrograms.end(); ++i) {
00618
00619 if (i->name == program) {
00620
00621 bankNo = i->bank;
00622 programNo = i->program;
00623 found = true;
00624
00625 #ifdef DEBUG_DSSI
00626 std::cerr << "DSSIPluginInstance::selectProgram(" << program << "): found at bank " << bankNo << ", program " << programNo << std::endl;
00627 #endif
00628
00629 break;
00630 }
00631 }
00632
00633 if (!found) return;
00634 m_program = program;
00635
00636
00637 m_processLock.lock();
00638 m_descriptor->select_program(m_instanceHandle, bankNo, programNo);
00639 m_processLock.unlock();
00640
00641 #ifdef DEBUG_DSSI
00642 std::cerr << "DSSIPluginInstance::selectProgram(" << program << "): made select_program(" << bankNo << "," << programNo << ") call" << std::endl;
00643 #endif
00644
00645 if (backupPortValues) {
00646 for (size_t i = 0; i < m_backupControlPortsIn.size(); ++i) {
00647 m_backupControlPortsIn[i] = *m_controlPortsIn[i].second;
00648 }
00649 }
00650 }
00651
00652 void
00653 DSSIPluginInstance::activate()
00654 {
00655 #ifdef DEBUG_DSSI
00656 std::cerr << "DSSIPluginInstance::activate" << std::endl;
00657 #endif
00658
00659 if (!m_descriptor || !m_descriptor->LADSPA_Plugin->activate) return;
00660 m_descriptor->LADSPA_Plugin->activate(m_instanceHandle);
00661
00662 if (m_program != "") {
00663 #ifdef DEBUG_DSSI
00664 std::cerr << "DSSIPluginInstance::activate: restoring program " << m_program << std::endl;
00665 #endif
00666 selectProgramAux(m_program, false);
00667 }
00668
00669 for (size_t i = 0; i < m_backupControlPortsIn.size(); ++i) {
00670 #ifdef DEBUG_DSSI
00671 std::cerr << "DSSIPluginInstance::activate: setting port " << m_controlPortsIn[i].first << " to " << m_backupControlPortsIn[i] << std::endl;
00672 #endif
00673 *m_controlPortsIn[i].second = m_backupControlPortsIn[i];
00674 }
00675 }
00676
00677 void
00678 DSSIPluginInstance::connectPorts()
00679 {
00680 if (!m_descriptor || !m_descriptor->LADSPA_Plugin->connect_port) return;
00681 #ifdef DEBUG_DSSI
00682 std::cerr << "DSSIPluginInstance::connectPorts: " << m_audioPortsIn.size()
00683 << " audio ports in, " << m_audioPortsOut.size() << " out, "
00684 << m_outputBufferCount << " output buffers" << std::endl;
00685 #endif
00686
00687 assert(sizeof(LADSPA_Data) == sizeof(float));
00688 assert(sizeof(sample_t) == sizeof(float));
00689
00690 LADSPAPluginFactory *f = dynamic_cast<LADSPAPluginFactory *>(m_factory);
00691 int inbuf = 0, outbuf = 0;
00692
00693 for (unsigned int i = 0; i < m_audioPortsIn.size(); ++i) {
00694 m_descriptor->LADSPA_Plugin->connect_port
00695 (m_instanceHandle,
00696 m_audioPortsIn[i],
00697 (LADSPA_Data *)m_inputBuffers[inbuf]);
00698 ++inbuf;
00699 }
00700
00701 for (unsigned int i = 0; i < m_audioPortsOut.size(); ++i) {
00702 m_descriptor->LADSPA_Plugin->connect_port
00703 (m_instanceHandle,
00704 m_audioPortsOut[i],
00705 (LADSPA_Data *)m_outputBuffers[outbuf]);
00706 ++outbuf;
00707 }
00708
00709 for (unsigned int i = 0; i < m_controlPortsIn.size(); ++i) {
00710 m_descriptor->LADSPA_Plugin->connect_port
00711 (m_instanceHandle,
00712 m_controlPortsIn[i].first,
00713 m_controlPortsIn[i].second);
00714
00715 if (f) {
00716 float defaultValue = f->getPortDefault
00717 (m_descriptor->LADSPA_Plugin, m_controlPortsIn[i].first);
00718 *m_controlPortsIn[i].second = defaultValue;
00719 m_backupControlPortsIn[i] = defaultValue;
00720 #ifdef DEBUG_DSSI
00721 std::cerr << "DSSIPluginInstance::connectPorts: set control port " << i << " to default value " << defaultValue << std::endl;
00722 #endif
00723 }
00724 }
00725
00726 for (unsigned int i = 0; i < m_controlPortsOut.size(); ++i) {
00727 m_descriptor->LADSPA_Plugin->connect_port
00728 (m_instanceHandle,
00729 m_controlPortsOut[i].first,
00730 m_controlPortsOut[i].second);
00731 }
00732 }
00733
00734 unsigned int
00735 DSSIPluginInstance::getParameterCount() const
00736 {
00737 return m_controlPortsIn.size();
00738 }
00739
00740 void
00741 DSSIPluginInstance::setParameterValue(unsigned int parameter, float value)
00742 {
00743 #ifdef DEBUG_DSSI
00744 std::cerr << "DSSIPluginInstance::setParameterValue(" << parameter << ") to " << value << std::endl;
00745 #endif
00746 if (parameter >= m_controlPortsIn.size()) return;
00747
00748 unsigned int portNumber = m_controlPortsIn[parameter].first;
00749
00750 LADSPAPluginFactory *f = dynamic_cast<LADSPAPluginFactory *>(m_factory);
00751 if (f) {
00752 if (value < f->getPortMinimum(m_descriptor->LADSPA_Plugin, portNumber)) {
00753 value = f->getPortMinimum(m_descriptor->LADSPA_Plugin, portNumber);
00754 }
00755 if (value > f->getPortMaximum(m_descriptor->LADSPA_Plugin, portNumber)) {
00756 value = f->getPortMaximum(m_descriptor->LADSPA_Plugin, portNumber);
00757 }
00758 }
00759
00760 (*m_controlPortsIn[parameter].second) = value;
00761 m_backupControlPortsIn[parameter] = value;
00762 }
00763
00764 void
00765 DSSIPluginInstance::setPortValueFromController(unsigned int port, int cv)
00766 {
00767 #ifdef DEBUG_DSSI
00768 std::cerr << "DSSIPluginInstance::setPortValueFromController(" << port << ") to " << cv << std::endl;
00769 #endif
00770
00771 const LADSPA_Descriptor *p = m_descriptor->LADSPA_Plugin;
00772 LADSPA_PortRangeHintDescriptor d = p->PortRangeHints[port].HintDescriptor;
00773 LADSPA_Data lb = p->PortRangeHints[port].LowerBound;
00774 LADSPA_Data ub = p->PortRangeHints[port].UpperBound;
00775
00776 float value = (float)cv;
00777
00778 if (!LADSPA_IS_HINT_BOUNDED_BELOW(d)) {
00779 if (!LADSPA_IS_HINT_BOUNDED_ABOVE(d)) {
00780
00781 } else {
00782
00783 value = ub - 127.0f + value;
00784 }
00785 } else {
00786 if (!LADSPA_IS_HINT_BOUNDED_ABOVE(d)) {
00787
00788 value = lb + value;
00789 } else {
00790
00791
00792 value = lb + ((ub - lb) * value / 127.0f);
00793 }
00794 }
00795
00796 for (unsigned int i = 0; i < m_controlPortsIn.size(); ++i) {
00797 if (m_controlPortsIn[i].first == port) {
00798 setParameterValue(i, value);
00799 }
00800 }
00801 }
00802
00803 float
00804 DSSIPluginInstance::getControlOutputValue(size_t output) const
00805 {
00806 if (output > m_controlPortsOut.size()) return 0.0;
00807 return (*m_controlPortsOut[output].second);
00808 }
00809
00810 float
00811 DSSIPluginInstance::getParameterValue(unsigned int parameter) const
00812 {
00813 #ifdef DEBUG_DSSI
00814 std::cerr << "DSSIPluginInstance::getParameterValue(" << parameter << ")" << std::endl;
00815 #endif
00816 if (parameter >= m_controlPortsIn.size()) return 0.0;
00817 return (*m_controlPortsIn[parameter].second);
00818 }
00819
00820 float
00821 DSSIPluginInstance::getParameterDefault(unsigned int parameter) const
00822 {
00823 if (parameter >= m_controlPortsIn.size()) return 0.0;
00824
00825 LADSPAPluginFactory *f = dynamic_cast<LADSPAPluginFactory *>(m_factory);
00826 if (f) {
00827 return f->getPortDefault(m_descriptor->LADSPA_Plugin,
00828 m_controlPortsIn[parameter].first);
00829 } else {
00830 return 0.0f;
00831 }
00832 }
00833
00834 int
00835 DSSIPluginInstance::getParameterDisplayHint(unsigned int parameter) const
00836 {
00837 if (parameter >= m_controlPortsIn.size()) return 0.0;
00838
00839 LADSPAPluginFactory *f = dynamic_cast<LADSPAPluginFactory *>(m_factory);
00840 if (f) {
00841 return f->getPortDisplayHint(m_descriptor->LADSPA_Plugin,
00842 m_controlPortsIn[parameter].first);
00843 } else {
00844 return PortHint::NoHint;
00845 }
00846 }
00847
00848 std::string
00849 DSSIPluginInstance::configure(std::string key,
00850 std::string value)
00851 {
00852 if (!m_descriptor || !m_descriptor->configure) return std::string();
00853
00854 if (key == PluginIdentifier::RESERVED_PROJECT_DIRECTORY_KEY.toStdString()) {
00855 #ifdef DSSI_PROJECT_DIRECTORY_KEY
00856 key = DSSI_PROJECT_DIRECTORY_KEY;
00857 #else
00858 return std::string();
00859 #endif
00860 }
00861
00862
00863 #ifdef DEBUG_DSSI
00864 std::cerr << "DSSIPluginInstance::configure(" << key << "," << value << ")" << std::endl;
00865 #endif
00866
00867 char *message = m_descriptor->configure(m_instanceHandle,
00868 key.c_str(),
00869 value.c_str());
00870
00871 m_programCacheValid = false;
00872
00873 m_configurationData[key] = value;
00874
00875 std::string qm;
00876
00877
00878
00879 #ifdef DSSI_RESERVED_CONFIGURE_PREFIX
00880 if (QString(key.c_str()).startsWith(DSSI_RESERVED_CONFIGURE_PREFIX)) {
00881 return qm;
00882 }
00883 #endif
00884
00885 if (message) {
00886 if (m_descriptor->LADSPA_Plugin && m_descriptor->LADSPA_Plugin->Label) {
00887 qm = std::string(m_descriptor->LADSPA_Plugin->Label) + ": ";
00888 }
00889 qm = qm + message;
00890 free(message);
00891
00892 std::cerr << "DSSIPluginInstance::configure: warning: configure returned message: \"" << qm << "\"" << std::endl;
00893 }
00894
00895 return qm;
00896 }
00897
00898 void
00899 DSSIPluginInstance::sendEvent(const Vamp::RealTime &eventTime,
00900 const void *e)
00901 {
00902 #ifdef DEBUG_DSSI_PROCESS
00903 std::cerr << "DSSIPluginInstance::sendEvent: last was " << m_lastEventSendTime << " (valid " << m_haveLastEventSendTime << "), this is " << eventTime << std::endl;
00904 #endif
00905
00906
00907
00908
00909
00910 if (m_haveLastEventSendTime &&
00911 m_lastEventSendTime > eventTime) {
00912 #ifdef DEBUG_DSSI_PROCESS
00913 std::cerr << "... clearing down" << std::endl;
00914 #endif
00915 m_haveLastEventSendTime = false;
00916 clearEvents();
00917 }
00918
00919 snd_seq_event_t *event = (snd_seq_event_t *)e;
00920 #ifdef DEBUG_DSSI_PROCESS
00921 std::cerr << "DSSIPluginInstance::sendEvent at " << eventTime << std::endl;
00922 #endif
00923 snd_seq_event_t ev(*event);
00924
00925 ev.time.time.tv_sec = eventTime.sec;
00926 ev.time.time.tv_nsec = eventTime.nsec;
00927
00928
00929 ev.data.note.channel = 0;
00930
00931 m_eventBuffer.write(&ev, 1);
00932
00933 m_lastEventSendTime = eventTime;
00934 m_haveLastEventSendTime = true;
00935 }
00936
00937 void
00938 DSSIPluginInstance::clearEvents()
00939 {
00940 m_haveLastEventSendTime = false;
00941 m_eventBuffer.reset();
00942 }
00943
00944 bool
00945 DSSIPluginInstance::handleController(snd_seq_event_t *ev)
00946 {
00947 int controller = ev->data.control.param;
00948
00949 #ifdef DEBUG_DSSI_PROCESS
00950 std::cerr << "DSSIPluginInstance::handleController " << controller << std::endl;
00951 #endif
00952
00953 if (controller == 0) {
00954
00955 m_pending.msb = ev->data.control.value;
00956
00957 } else if (controller == 32) {
00958
00959 m_pending.lsb = ev->data.control.value;
00960
00961 } else if (controller > 0 && controller < 128) {
00962
00963 if (m_controllerMap.find(controller) != m_controllerMap.end()) {
00964 int port = m_controllerMap[controller];
00965 setPortValueFromController(port, ev->data.control.value);
00966 } else {
00967 return true;
00968 }
00969 }
00970
00971 return false;
00972 }
00973
00974 void
00975 DSSIPluginInstance::run(const Vamp::RealTime &blockTime)
00976 {
00977 static snd_seq_event_t localEventBuffer[EVENT_BUFFER_SIZE];
00978 int evCount = 0;
00979
00980 bool needLock = false;
00981 if (m_descriptor->select_program) needLock = true;
00982
00983 if (needLock) {
00984 if (!m_processLock.tryLock()) {
00985 for (size_t ch = 0; ch < m_audioPortsOut.size(); ++ch) {
00986 memset(m_outputBuffers[ch], 0, m_blockSize * sizeof(sample_t));
00987 }
00988 return;
00989 }
00990 }
00991
00992 if (m_grouped) {
00993 runGrouped(blockTime);
00994 goto done;
00995 }
00996
00997 if (!m_descriptor || !m_descriptor->run_synth) {
00998 m_eventBuffer.skip(m_eventBuffer.getReadSpace());
00999 m_haveLastEventSendTime = false;
01000 if (m_descriptor->LADSPA_Plugin->run) {
01001 m_descriptor->LADSPA_Plugin->run(m_instanceHandle, m_blockSize);
01002 } else {
01003 for (size_t ch = 0; ch < m_audioPortsOut.size(); ++ch) {
01004 memset(m_outputBuffers[ch], 0, m_blockSize * sizeof(sample_t));
01005 }
01006 }
01007 m_run = true;
01008 if (needLock) m_processLock.unlock();
01009 return;
01010 }
01011
01012 #ifdef DEBUG_DSSI_PROCESS
01013 std::cerr << "DSSIPluginInstance::run(" << blockTime << ")" << std::endl;
01014 #endif
01015
01016 #ifdef DEBUG_DSSI_PROCESS
01017 if (m_eventBuffer.getReadSpace() > 0) {
01018 std::cerr << "DSSIPluginInstance::run: event buffer has "
01019 << m_eventBuffer.getReadSpace() << " event(s) in it" << std::endl;
01020 }
01021 #endif
01022
01023 while (m_eventBuffer.getReadSpace() > 0) {
01024
01025 snd_seq_event_t *ev = localEventBuffer + evCount;
01026 *ev = m_eventBuffer.peekOne();
01027 bool accept = true;
01028
01029 Vamp::RealTime evTime(ev->time.time.tv_sec, ev->time.time.tv_nsec);
01030
01031 int frameOffset = 0;
01032 if (evTime > blockTime) {
01033 frameOffset = Vamp::RealTime::realTime2Frame(evTime - blockTime, m_sampleRate);
01034 }
01035
01036 #ifdef DEBUG_DSSI_PROCESS
01037 std::cerr << "DSSIPluginInstance::run: evTime " << evTime << ", blockTime " << blockTime << ", frameOffset " << frameOffset
01038 << ", blockSize " << m_blockSize << std::endl;
01039 std::cerr << "Type: " << int(ev->type) << ", pitch: " << int(ev->data.note.note) << ", velocity: " << int(ev->data.note.velocity) << std::endl;
01040 #endif
01041
01042 if (frameOffset >= int(m_blockSize)) break;
01043 if (frameOffset < 0) {
01044 frameOffset = 0;
01045 if (ev->type == SND_SEQ_EVENT_NOTEON) {
01046 m_eventBuffer.skip(1);
01047 continue;
01048 }
01049 }
01050
01051 ev->time.tick = frameOffset;
01052 m_eventBuffer.skip(1);
01053
01054 if (ev->type == SND_SEQ_EVENT_CONTROLLER) {
01055 accept = handleController(ev);
01056 } else if (ev->type == SND_SEQ_EVENT_PGMCHANGE) {
01057 m_pending.program = ev->data.control.value;
01058 accept = false;
01059 }
01060
01061 if (accept) {
01062 if (++evCount >= EVENT_BUFFER_SIZE) break;
01063 }
01064 }
01065
01066 if (m_pending.program >= 0 && m_descriptor->select_program) {
01067
01068 int program = m_pending.program;
01069 int bank = m_pending.lsb + 128 * m_pending.msb;
01070
01071 #ifdef DEBUG_DSSI
01072 std::cerr << "DSSIPluginInstance::run: making select_program(" << bank << "," << program << ") call" << std::endl;
01073 #endif
01074
01075 m_pending.lsb = m_pending.msb = m_pending.program = -1;
01076 m_descriptor->select_program(m_instanceHandle, bank, program);
01077
01078 #ifdef DEBUG_DSSI
01079 std::cerr << "DSSIPluginInstance::run: made select_program(" << bank << "," << program << ") call" << std::endl;
01080 #endif
01081 }
01082
01083 #ifdef DEBUG_DSSI_PROCESS
01084 std::cerr << "DSSIPluginInstance::run: running with " << evCount << " events"
01085 << std::endl;
01086 #endif
01087
01088 m_descriptor->run_synth(m_instanceHandle, m_blockSize,
01089 localEventBuffer, evCount);
01090
01091 #ifdef DEBUG_DSSI_PROCESS
01092
01093
01094
01095
01096 #endif
01097
01098 done:
01099 if (needLock) m_processLock.unlock();
01100
01101 if (m_audioPortsOut.size() == 0) {
01102
01103 for (size_t ch = 0; ch < m_idealChannelCount; ++ch) {
01104 size_t sch = ch % m_audioPortsIn.size();
01105 for (size_t i = 0; i < m_blockSize; ++i) {
01106 m_outputBuffers[ch][i] = m_inputBuffers[sch][i];
01107 }
01108 }
01109 } else if (m_idealChannelCount < m_audioPortsOut.size()) {
01110 if (m_idealChannelCount == 1) {
01111
01112 for (size_t ch = 1; ch < m_audioPortsOut.size(); ++ch) {
01113 for (size_t i = 0; i < m_blockSize; ++i) {
01114 m_outputBuffers[0][i] += m_outputBuffers[ch][i];
01115 }
01116 }
01117 }
01118 } else if (m_idealChannelCount > m_audioPortsOut.size()) {
01119
01120 for (size_t ch = m_audioPortsOut.size(); ch < m_idealChannelCount; ++ch) {
01121 size_t sch = (ch - m_audioPortsOut.size()) % m_audioPortsOut.size();
01122 for (size_t i = 0; i < m_blockSize; ++i) {
01123 m_outputBuffers[ch][i] = m_outputBuffers[sch][i];
01124 }
01125 }
01126 }
01127
01128 m_lastRunTime = blockTime;
01129 m_run = true;
01130 }
01131
01132 void
01133 DSSIPluginInstance::runGrouped(const Vamp::RealTime &blockTime)
01134 {
01135
01136
01137
01138
01139
01140
01141 bool needRun = true;
01142
01143 PluginSet &s = m_groupMap[m_identifier];
01144
01145 #ifdef DEBUG_DSSI_PROCESS
01146 std::cerr << "DSSIPluginInstance::runGrouped(" << blockTime << "): this is " << this << "; " << s.size() << " elements in m_groupMap[" << m_identifier << "]" << std::endl;
01147 #endif
01148
01149 if (m_lastRunTime != blockTime) {
01150 for (PluginSet::iterator i = s.begin(); i != s.end(); ++i) {
01151 DSSIPluginInstance *instance = *i;
01152 if (instance != this && instance->m_lastRunTime == blockTime) {
01153 #ifdef DEBUG_DSSI_PROCESS
01154 std::cerr << "DSSIPluginInstance::runGrouped(" << blockTime << "): plugin " << instance << " has already been run" << std::endl;
01155 #endif
01156 needRun = false;
01157 }
01158 }
01159 }
01160
01161 if (!needRun) {
01162 #ifdef DEBUG_DSSI_PROCESS
01163 std::cerr << "DSSIPluginInstance::runGrouped(" << blockTime << "): already run, returning" << std::endl;
01164 #endif
01165 return;
01166 }
01167
01168 #ifdef DEBUG_DSSI_PROCESS
01169 std::cerr << "DSSIPluginInstance::runGrouped(" << blockTime << "): I'm the first, running" << std::endl;
01170 #endif
01171
01172 size_t index = 0;
01173 unsigned long *counts = (unsigned long *)
01174 alloca(m_groupLocalEventBufferCount * sizeof(unsigned long));
01175 LADSPA_Handle *instances = (LADSPA_Handle *)
01176 alloca(m_groupLocalEventBufferCount * sizeof(LADSPA_Handle));
01177
01178 for (PluginSet::iterator i = s.begin(); i != s.end(); ++i) {
01179
01180 if (index >= m_groupLocalEventBufferCount) break;
01181
01182 DSSIPluginInstance *instance = *i;
01183 counts[index] = 0;
01184 instances[index] = instance->m_instanceHandle;
01185
01186 #ifdef DEBUG_DSSI_PROCESS
01187 std::cerr << "DSSIPluginInstance::runGrouped(" << blockTime << "): running " << instance << std::endl;
01188 #endif
01189
01190 if (instance->m_pending.program >= 0 &&
01191 instance->m_descriptor->select_program) {
01192 int program = instance->m_pending.program;
01193 int bank = instance->m_pending.lsb + 128 * instance->m_pending.msb;
01194 instance->m_pending.lsb = instance->m_pending.msb = instance->m_pending.program = -1;
01195 instance->m_descriptor->select_program
01196 (instance->m_instanceHandle, bank, program);
01197 }
01198
01199 while (instance->m_eventBuffer.getReadSpace() > 0) {
01200
01201 snd_seq_event_t *ev = m_groupLocalEventBuffers[index] + counts[index];
01202 *ev = instance->m_eventBuffer.peekOne();
01203 bool accept = true;
01204
01205 Vamp::RealTime evTime(ev->time.time.tv_sec, ev->time.time.tv_nsec);
01206
01207 int frameOffset = 0;
01208 if (evTime > blockTime) {
01209 frameOffset = Vamp::RealTime::realTime2Frame(evTime - blockTime, m_sampleRate);
01210 }
01211
01212 #ifdef DEBUG_DSSI_PROCESS
01213 std::cerr << "DSSIPluginInstance::runGrouped: evTime " << evTime << ", frameOffset " << frameOffset
01214 << ", block size " << m_blockSize << std::endl;
01215 #endif
01216
01217 if (frameOffset >= int(m_blockSize)) break;
01218 if (frameOffset < 0) frameOffset = 0;
01219
01220 ev->time.tick = frameOffset;
01221 instance->m_eventBuffer.skip(1);
01222
01223 if (ev->type == SND_SEQ_EVENT_CONTROLLER) {
01224 accept = instance->handleController(ev);
01225 } else if (ev->type == SND_SEQ_EVENT_PGMCHANGE) {
01226 instance->m_pending.program = ev->data.control.value;
01227 accept = false;
01228 }
01229
01230 if (accept) {
01231 if (++counts[index] >= EVENT_BUFFER_SIZE) break;
01232 }
01233 }
01234
01235 ++index;
01236 }
01237
01238 m_descriptor->run_multiple_synths(index,
01239 instances,
01240 m_blockSize,
01241 m_groupLocalEventBuffers,
01242 counts);
01243 }
01244
01245 int
01246 DSSIPluginInstance::requestMidiSend(LADSPA_Handle ,
01247 unsigned char ,
01248 unsigned char )
01249 {
01250
01251
01252 std::cerr << "DSSIPluginInstance::requestMidiSend" << std::endl;
01253 return 1;
01254 }
01255
01256 void
01257 DSSIPluginInstance::midiSend(LADSPA_Handle ,
01258 snd_seq_event_t * ,
01259 unsigned long )
01260 {
01261
01262
01263 std::cerr << "DSSIPluginInstance::midiSend" << std::endl;
01264 }
01265
01266 void
01267 DSSIPluginInstance::NonRTPluginThread::run()
01268 {
01269 while (!m_exiting) {
01270 m_runFunction(m_handle);
01271 usleep(100000);
01272 }
01273 }
01274
01275 int
01276 DSSIPluginInstance::requestNonRTThread(LADSPA_Handle instance,
01277 void (*runFunction)(LADSPA_Handle))
01278 {
01279 NonRTPluginThread *thread = new NonRTPluginThread(instance, runFunction);
01280 m_threads[instance].insert(thread);
01281 thread->start();
01282 return 0;
01283 }
01284
01285 void
01286 DSSIPluginInstance::deactivate()
01287 {
01288 #ifdef DEBUG_DSSI
01289 std::cerr << "DSSIPluginInstance::deactivate " << m_identifier << std::endl;
01290 #endif
01291 if (!m_descriptor || !m_descriptor->LADSPA_Plugin->deactivate) return;
01292
01293 for (size_t i = 0; i < m_backupControlPortsIn.size(); ++i) {
01294 m_backupControlPortsIn[i] = *m_controlPortsIn[i].second;
01295 }
01296
01297 m_descriptor->LADSPA_Plugin->deactivate(m_instanceHandle);
01298 #ifdef DEBUG_DSSI
01299 std::cerr << "DSSIPluginInstance::deactivate " << m_identifier << " done" << std::endl;
01300 #endif
01301
01302 m_bufferScavenger.scavenge();
01303 }
01304
01305 void
01306 DSSIPluginInstance::cleanup()
01307 {
01308 #ifdef DEBUG_DSSI
01309 std::cerr << "DSSIPluginInstance::cleanup " << m_identifier << std::endl;
01310 #endif
01311 if (!m_descriptor) return;
01312
01313 if (!m_descriptor->LADSPA_Plugin->cleanup) {
01314 std::cerr << "Bad plugin: plugin id "
01315 << m_descriptor->LADSPA_Plugin->UniqueID
01316 << ":" << m_descriptor->LADSPA_Plugin->Label
01317 << " has no cleanup method!" << std::endl;
01318 return;
01319 }
01320
01321 m_descriptor->LADSPA_Plugin->cleanup(m_instanceHandle);
01322 m_instanceHandle = 0;
01323 #ifdef DEBUG_DSSI
01324 std::cerr << "DSSIPluginInstance::cleanup " << m_identifier << " done" << std::endl;
01325 #endif
01326 }
01327