annotate plugin/DSSIPluginInstance.cpp @ 282:d9319859a4cf tip

(none)
author benoitrigolleau
date Fri, 31 Oct 2008 11:00:24 +0000
parents be6d31baecb9
children
rev   line source
lbajardsilogic@0 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
lbajardsilogic@0 2
lbajardsilogic@0 3 /*
lbajardsilogic@0 4 Sonic Visualiser
lbajardsilogic@0 5 An audio file viewer and annotation editor.
lbajardsilogic@0 6 Centre for Digital Music, Queen Mary, University of London.
lbajardsilogic@0 7
lbajardsilogic@0 8 This program is free software; you can redistribute it and/or
lbajardsilogic@0 9 modify it under the terms of the GNU General Public License as
lbajardsilogic@0 10 published by the Free Software Foundation; either version 2 of the
lbajardsilogic@0 11 License, or (at your option) any later version. See the file
lbajardsilogic@0 12 COPYING included with this distribution for more information.
lbajardsilogic@0 13 */
lbajardsilogic@0 14
lbajardsilogic@0 15 /*
lbajardsilogic@0 16 This is a modified version of a source file from the
lbajardsilogic@0 17 Rosegarden MIDI and audio sequencer and notation editor.
lbajardsilogic@0 18 This file copyright 2000-2006 Chris Cannam.
lbajardsilogic@0 19 */
lbajardsilogic@0 20
lbajardsilogic@0 21 #include <iostream>
lbajardsilogic@0 22 #include <cassert>
lbajardsilogic@0 23
lbajardsilogic@0 24 #include "DSSIPluginInstance.h"
lbajardsilogic@0 25 #include "PluginIdentifier.h"
lbajardsilogic@0 26 #include "LADSPAPluginFactory.h"
lbajardsilogic@0 27
lbajardsilogic@0 28 //#define DEBUG_DSSI 1
lbajardsilogic@0 29 //#define DEBUG_DSSI_PROCESS 1
lbajardsilogic@0 30
lbajardsilogic@0 31 #define EVENT_BUFFER_SIZE 1023
lbajardsilogic@0 32
lbajardsilogic@0 33 #ifdef DEBUG_DSSI
lbajardsilogic@0 34 static std::ostream &operator<<(std::ostream& o, const QString &s)
lbajardsilogic@0 35 {
lbajardsilogic@0 36 o << s.toLocal8Bit().data();
lbajardsilogic@0 37 return o;
lbajardsilogic@0 38 }
lbajardsilogic@0 39 #endif
lbajardsilogic@0 40
lbajardsilogic@0 41 DSSIPluginInstance::GroupMap DSSIPluginInstance::m_groupMap;
lbajardsilogic@0 42 snd_seq_event_t **DSSIPluginInstance::m_groupLocalEventBuffers = 0;
lbajardsilogic@0 43 size_t DSSIPluginInstance::m_groupLocalEventBufferCount = 0;
lbajardsilogic@0 44 Scavenger<ScavengerArrayWrapper<snd_seq_event_t *> > DSSIPluginInstance::m_bufferScavenger(2, 10);
lbajardsilogic@0 45 std::map<LADSPA_Handle, std::set<DSSIPluginInstance::NonRTPluginThread *> > DSSIPluginInstance::m_threads;
lbajardsilogic@0 46
lbajardsilogic@0 47
lbajardsilogic@0 48 DSSIPluginInstance::DSSIPluginInstance(RealTimePluginFactory *factory,
lbajardsilogic@0 49 int clientId,
lbajardsilogic@0 50 QString identifier,
lbajardsilogic@0 51 int position,
lbajardsilogic@0 52 unsigned long sampleRate,
lbajardsilogic@0 53 size_t blockSize,
lbajardsilogic@0 54 int idealChannelCount,
lbajardsilogic@0 55 const DSSI_Descriptor* descriptor) :
lbajardsilogic@0 56 RealTimePluginInstance(factory, identifier),
lbajardsilogic@0 57 m_client(clientId),
lbajardsilogic@0 58 m_position(position),
lbajardsilogic@0 59 m_descriptor(descriptor),
lbajardsilogic@0 60 m_programCacheValid(false),
lbajardsilogic@0 61 m_eventBuffer(EVENT_BUFFER_SIZE),
lbajardsilogic@0 62 m_blockSize(blockSize),
lbajardsilogic@0 63 m_idealChannelCount(idealChannelCount),
lbajardsilogic@0 64 m_sampleRate(sampleRate),
lbajardsilogic@0 65 m_latencyPort(0),
lbajardsilogic@0 66 m_run(false),
lbajardsilogic@0 67 m_bypassed(false),
lbajardsilogic@0 68 m_grouped(false),
lbajardsilogic@0 69 m_haveLastEventSendTime(false)
lbajardsilogic@0 70 {
lbajardsilogic@0 71 #ifdef DEBUG_DSSI
lbajardsilogic@0 72 std::cerr << "DSSIPluginInstance::DSSIPluginInstance(" << identifier << ")"
lbajardsilogic@0 73 << std::endl;
lbajardsilogic@0 74 #endif
lbajardsilogic@0 75
lbajardsilogic@0 76 init();
lbajardsilogic@0 77
lbajardsilogic@0 78 m_inputBuffers = new sample_t*[m_audioPortsIn.size()];
lbajardsilogic@0 79 m_outputBuffers = new sample_t*[m_outputBufferCount];
lbajardsilogic@0 80
lbajardsilogic@0 81 for (size_t i = 0; i < m_audioPortsIn.size(); ++i) {
lbajardsilogic@0 82 m_inputBuffers[i] = new sample_t[blockSize];
lbajardsilogic@0 83 }
lbajardsilogic@0 84 for (size_t i = 0; i < m_outputBufferCount; ++i) {
lbajardsilogic@0 85 m_outputBuffers[i] = new sample_t[blockSize];
lbajardsilogic@0 86 }
lbajardsilogic@0 87
lbajardsilogic@0 88 m_ownBuffers = true;
lbajardsilogic@0 89
lbajardsilogic@0 90 m_pending.lsb = m_pending.msb = m_pending.program = -1;
lbajardsilogic@0 91
lbajardsilogic@0 92 instantiate(sampleRate);
lbajardsilogic@0 93 if (isOK()) {
lbajardsilogic@0 94 connectPorts();
lbajardsilogic@0 95 activate();
lbajardsilogic@0 96 initialiseGroupMembership();
lbajardsilogic@0 97 }
lbajardsilogic@0 98 }
lbajardsilogic@0 99
lbajardsilogic@0 100 std::string
lbajardsilogic@0 101 DSSIPluginInstance::getIdentifier() const
lbajardsilogic@0 102 {
lbajardsilogic@0 103 return m_descriptor->LADSPA_Plugin->Label;
lbajardsilogic@0 104 }
lbajardsilogic@0 105
lbajardsilogic@0 106 std::string
lbajardsilogic@0 107 DSSIPluginInstance::getName() const
lbajardsilogic@0 108 {
lbajardsilogic@0 109 return m_descriptor->LADSPA_Plugin->Name;
lbajardsilogic@0 110 }
lbajardsilogic@0 111
lbajardsilogic@0 112 std::string
lbajardsilogic@0 113 DSSIPluginInstance::getDescription() const
lbajardsilogic@0 114 {
lbajardsilogic@0 115 return "";
lbajardsilogic@0 116 }
lbajardsilogic@0 117
lbajardsilogic@0 118 std::string
lbajardsilogic@0 119 DSSIPluginInstance::getMaker() const
lbajardsilogic@0 120 {
lbajardsilogic@0 121 return m_descriptor->LADSPA_Plugin->Maker;
lbajardsilogic@0 122 }
lbajardsilogic@0 123
lbajardsilogic@0 124 int
lbajardsilogic@0 125 DSSIPluginInstance::getPluginVersion() const
lbajardsilogic@0 126 {
lbajardsilogic@0 127 return 1;
lbajardsilogic@0 128 }
lbajardsilogic@0 129
lbajardsilogic@0 130 std::string
lbajardsilogic@0 131 DSSIPluginInstance::getCopyright() const
lbajardsilogic@0 132 {
lbajardsilogic@0 133 return m_descriptor->LADSPA_Plugin->Copyright;
lbajardsilogic@0 134 }
lbajardsilogic@0 135
lbajardsilogic@0 136 DSSIPluginInstance::ParameterList
lbajardsilogic@0 137 DSSIPluginInstance::getParameterDescriptors() const
lbajardsilogic@0 138 {
lbajardsilogic@0 139 ParameterList list;
lbajardsilogic@0 140 LADSPAPluginFactory *f = dynamic_cast<LADSPAPluginFactory *>(m_factory);
lbajardsilogic@0 141
lbajardsilogic@0 142 for (unsigned int i = 0; i < m_controlPortsIn.size(); ++i) {
lbajardsilogic@0 143
lbajardsilogic@0 144 ParameterDescriptor pd;
lbajardsilogic@0 145 unsigned int pn = m_controlPortsIn[i].first;
lbajardsilogic@0 146
lbajardsilogic@0 147 pd.identifier = m_descriptor->LADSPA_Plugin->PortNames[pn];
lbajardsilogic@0 148 pd.name = pd.identifier;
lbajardsilogic@0 149 pd.description = "";
lbajardsilogic@0 150 pd.minValue = f->getPortMinimum(m_descriptor->LADSPA_Plugin, pn);
lbajardsilogic@0 151 pd.maxValue = f->getPortMaximum(m_descriptor->LADSPA_Plugin, pn);
lbajardsilogic@0 152 pd.defaultValue = f->getPortDefault(m_descriptor->LADSPA_Plugin, pn);
lbajardsilogic@0 153
lbajardsilogic@0 154 float q = f->getPortQuantization(m_descriptor->LADSPA_Plugin, pn);
lbajardsilogic@0 155 if (q == 0.0) {
lbajardsilogic@0 156 pd.isQuantized = false;
lbajardsilogic@0 157 } else {
lbajardsilogic@0 158 pd.isQuantized = true;
lbajardsilogic@0 159 pd.quantizeStep = q;
lbajardsilogic@0 160 }
lbajardsilogic@0 161
lbajardsilogic@0 162 list.push_back(pd);
lbajardsilogic@0 163 }
lbajardsilogic@0 164
lbajardsilogic@0 165 return list;
lbajardsilogic@0 166 }
lbajardsilogic@0 167
lbajardsilogic@0 168 float
lbajardsilogic@0 169 DSSIPluginInstance::getParameter(std::string id) const
lbajardsilogic@0 170 {
lbajardsilogic@0 171 #ifdef DEBUG_DSSI
lbajardsilogic@0 172 std::cerr << "DSSIPluginInstance::getParameter(" << id << ")" << std::endl;
lbajardsilogic@0 173 #endif
lbajardsilogic@0 174 for (unsigned int i = 0; i < m_controlPortsIn.size(); ++i) {
lbajardsilogic@0 175 if (id == m_descriptor->LADSPA_Plugin->PortNames[m_controlPortsIn[i].first]) {
lbajardsilogic@0 176 #ifdef DEBUG_DSSI
lbajardsilogic@0 177 std::cerr << "Matches port " << i << std::endl;
lbajardsilogic@0 178 #endif
lbajardsilogic@0 179 float v = getParameterValue(i);
lbajardsilogic@0 180 #ifdef DEBUG_DSSI
lbajardsilogic@0 181 std::cerr << "Returning " << v << std::endl;
lbajardsilogic@0 182 #endif
lbajardsilogic@0 183 return v;
lbajardsilogic@0 184 }
lbajardsilogic@0 185 }
lbajardsilogic@0 186
lbajardsilogic@0 187 return 0.0;
lbajardsilogic@0 188 }
lbajardsilogic@0 189
lbajardsilogic@0 190 void
lbajardsilogic@0 191 DSSIPluginInstance::setParameter(std::string id, float value)
lbajardsilogic@0 192 {
lbajardsilogic@0 193 #ifdef DEBUG_DSSI
lbajardsilogic@0 194 std::cerr << "DSSIPluginInstance::setParameter(" << id << ", " << value << ")" << std::endl;
lbajardsilogic@0 195 #endif
lbajardsilogic@0 196
lbajardsilogic@0 197 for (unsigned int i = 0; i < m_controlPortsIn.size(); ++i) {
lbajardsilogic@0 198 if (id == m_descriptor->LADSPA_Plugin->PortNames[m_controlPortsIn[i].first]) {
lbajardsilogic@0 199 setParameterValue(i, value);
lbajardsilogic@0 200 break;
lbajardsilogic@0 201 }
lbajardsilogic@0 202 }
lbajardsilogic@0 203 }
lbajardsilogic@0 204
lbajardsilogic@0 205 void
lbajardsilogic@0 206 DSSIPluginInstance::init()
lbajardsilogic@0 207 {
lbajardsilogic@0 208 #ifdef DEBUG_DSSI
lbajardsilogic@0 209 std::cerr << "DSSIPluginInstance::init" << std::endl;
lbajardsilogic@0 210 #endif
lbajardsilogic@0 211
lbajardsilogic@0 212 // Discover ports numbers and identities
lbajardsilogic@0 213 //
lbajardsilogic@0 214 const LADSPA_Descriptor *descriptor = m_descriptor->LADSPA_Plugin;
lbajardsilogic@0 215
lbajardsilogic@0 216 for (unsigned long i = 0; i < descriptor->PortCount; ++i)
lbajardsilogic@0 217 {
lbajardsilogic@0 218 if (LADSPA_IS_PORT_AUDIO(descriptor->PortDescriptors[i]))
lbajardsilogic@0 219 {
lbajardsilogic@0 220 if (LADSPA_IS_PORT_INPUT(descriptor->PortDescriptors[i])) {
lbajardsilogic@0 221 m_audioPortsIn.push_back(i);
lbajardsilogic@0 222 } else {
lbajardsilogic@0 223 m_audioPortsOut.push_back(i);
lbajardsilogic@0 224 }
lbajardsilogic@0 225 }
lbajardsilogic@0 226 else
lbajardsilogic@0 227 if (LADSPA_IS_PORT_CONTROL(descriptor->PortDescriptors[i]))
lbajardsilogic@0 228 {
lbajardsilogic@0 229 if (LADSPA_IS_PORT_INPUT(descriptor->PortDescriptors[i])) {
lbajardsilogic@0 230
lbajardsilogic@0 231 LADSPA_Data *data = new LADSPA_Data(0.0);
lbajardsilogic@0 232
lbajardsilogic@0 233 m_controlPortsIn.push_back(std::pair<unsigned long, LADSPA_Data*>
lbajardsilogic@0 234 (i, data));
lbajardsilogic@0 235
lbajardsilogic@0 236 m_backupControlPortsIn.push_back(0.0);
lbajardsilogic@0 237
lbajardsilogic@0 238 } else {
lbajardsilogic@0 239 LADSPA_Data *data = new LADSPA_Data(0.0);
lbajardsilogic@0 240 m_controlPortsOut.push_back(
lbajardsilogic@0 241 std::pair<unsigned long, LADSPA_Data*>(i, data));
lbajardsilogic@0 242 if (!strcmp(descriptor->PortNames[i], "latency") ||
lbajardsilogic@0 243 !strcmp(descriptor->PortNames[i], "_latency")) {
lbajardsilogic@0 244 #ifdef DEBUG_DSSI
lbajardsilogic@0 245 std::cerr << "Wooo! We have a latency port!" << std::endl;
lbajardsilogic@0 246 #endif
lbajardsilogic@0 247 m_latencyPort = data;
lbajardsilogic@0 248 }
lbajardsilogic@0 249 }
lbajardsilogic@0 250 }
lbajardsilogic@0 251 #ifdef DEBUG_DSSI
lbajardsilogic@0 252 else
lbajardsilogic@0 253 std::cerr << "DSSIPluginInstance::DSSIPluginInstance - "
lbajardsilogic@0 254 << "unrecognised port type" << std::endl;
lbajardsilogic@0 255 #endif
lbajardsilogic@0 256 }
lbajardsilogic@0 257
lbajardsilogic@191 258 m_outputBufferCount = MAX(m_idealChannelCount, m_audioPortsOut.size());
lbajardsilogic@0 259 }
lbajardsilogic@0 260
lbajardsilogic@0 261 size_t
lbajardsilogic@0 262 DSSIPluginInstance::getLatency()
lbajardsilogic@0 263 {
lbajardsilogic@0 264 size_t latency = 0;
lbajardsilogic@0 265
lbajardsilogic@0 266 #ifdef DEBUG_DSSI_PROCESS
lbajardsilogic@0 267 std::cerr << "DSSIPluginInstance::getLatency(): m_latencyPort " << m_latencyPort << ", m_run " << m_run << std::endl;
lbajardsilogic@0 268 #endif
lbajardsilogic@0 269
lbajardsilogic@0 270 if (m_latencyPort) {
lbajardsilogic@0 271 if (!m_run) {
lbajardsilogic@0 272 for (size_t i = 0; i < getAudioInputCount(); ++i) {
lbajardsilogic@0 273 for (size_t j = 0; j < m_blockSize; ++j) {
lbajardsilogic@0 274 m_inputBuffers[i][j] = 0.f;
lbajardsilogic@0 275 }
lbajardsilogic@0 276 }
lbajardsilogic@0 277 run(Vamp::RealTime::zeroTime);
lbajardsilogic@0 278 }
lbajardsilogic@0 279 latency = (size_t)(*m_latencyPort + 0.1);
lbajardsilogic@0 280 }
lbajardsilogic@0 281
lbajardsilogic@0 282 #ifdef DEBUG_DSSI_PROCESS
lbajardsilogic@0 283 std::cerr << "DSSIPluginInstance::getLatency(): latency is " << latency << std::endl;
lbajardsilogic@0 284 #endif
lbajardsilogic@0 285
lbajardsilogic@0 286 return latency;
lbajardsilogic@0 287 }
lbajardsilogic@0 288
lbajardsilogic@0 289 void
lbajardsilogic@0 290 DSSIPluginInstance::silence()
lbajardsilogic@0 291 {
lbajardsilogic@0 292 if (m_instanceHandle != 0) {
lbajardsilogic@0 293 deactivate();
lbajardsilogic@0 294 activate();
lbajardsilogic@0 295 }
lbajardsilogic@0 296 }
lbajardsilogic@0 297
lbajardsilogic@0 298 void
lbajardsilogic@0 299 DSSIPluginInstance::discardEvents()
lbajardsilogic@0 300 {
lbajardsilogic@0 301 m_eventBuffer.reset();
lbajardsilogic@0 302 }
lbajardsilogic@0 303
lbajardsilogic@0 304 void
lbajardsilogic@0 305 DSSIPluginInstance::setIdealChannelCount(size_t channels)
lbajardsilogic@0 306 {
lbajardsilogic@0 307 #ifdef DEBUG_DSSI
lbajardsilogic@0 308 std::cerr << "DSSIPluginInstance::setIdealChannelCount: channel count "
lbajardsilogic@0 309 << channels << " (was " << m_idealChannelCount << ")" << std::endl;
lbajardsilogic@0 310 #endif
lbajardsilogic@0 311
lbajardsilogic@0 312 if (channels == m_idealChannelCount) {
lbajardsilogic@0 313 silence();
lbajardsilogic@0 314 return;
lbajardsilogic@0 315 }
lbajardsilogic@0 316
lbajardsilogic@0 317 if (m_instanceHandle != 0) {
lbajardsilogic@0 318 deactivate();
lbajardsilogic@0 319 }
lbajardsilogic@0 320
lbajardsilogic@0 321 m_idealChannelCount = channels;
lbajardsilogic@0 322
lbajardsilogic@0 323 if (channels > m_outputBufferCount) {
lbajardsilogic@0 324
lbajardsilogic@0 325 for (size_t i = 0; i < m_outputBufferCount; ++i) {
lbajardsilogic@0 326 delete[] m_outputBuffers[i];
lbajardsilogic@0 327 }
lbajardsilogic@0 328
lbajardsilogic@0 329 delete[] m_outputBuffers;
lbajardsilogic@0 330
lbajardsilogic@0 331 m_outputBufferCount = channels;
lbajardsilogic@0 332
lbajardsilogic@0 333 m_outputBuffers = new sample_t*[m_outputBufferCount];
lbajardsilogic@0 334
lbajardsilogic@0 335 for (size_t i = 0; i < m_outputBufferCount; ++i) {
lbajardsilogic@0 336 m_outputBuffers[i] = new sample_t[m_blockSize];
lbajardsilogic@0 337 }
lbajardsilogic@0 338
lbajardsilogic@0 339 connectPorts();
lbajardsilogic@0 340 }
lbajardsilogic@0 341
lbajardsilogic@0 342 if (m_instanceHandle != 0) {
lbajardsilogic@0 343 activate();
lbajardsilogic@0 344 }
lbajardsilogic@0 345 }
lbajardsilogic@0 346
lbajardsilogic@0 347 void
lbajardsilogic@0 348 DSSIPluginInstance::detachFromGroup()
lbajardsilogic@0 349 {
lbajardsilogic@0 350 if (!m_grouped) return;
lbajardsilogic@0 351 m_groupMap[m_identifier].erase(this);
lbajardsilogic@0 352 m_grouped = false;
lbajardsilogic@0 353 }
lbajardsilogic@0 354
lbajardsilogic@0 355 void
lbajardsilogic@0 356 DSSIPluginInstance::initialiseGroupMembership()
lbajardsilogic@0 357 {
lbajardsilogic@0 358 if (!m_descriptor->run_multiple_synths) {
lbajardsilogic@0 359 m_grouped = false;
lbajardsilogic@0 360 return;
lbajardsilogic@0 361 }
lbajardsilogic@0 362
lbajardsilogic@0 363 //!!! GroupMap is not actually thread-safe.
lbajardsilogic@0 364
lbajardsilogic@0 365 size_t pluginsInGroup = m_groupMap[m_identifier].size();
lbajardsilogic@0 366
lbajardsilogic@0 367 if (++pluginsInGroup > m_groupLocalEventBufferCount) {
lbajardsilogic@0 368
lbajardsilogic@0 369 size_t nextBufferCount = pluginsInGroup * 2;
lbajardsilogic@0 370
lbajardsilogic@0 371 snd_seq_event_t **eventLocalBuffers = new snd_seq_event_t *[nextBufferCount];
lbajardsilogic@0 372
lbajardsilogic@0 373 for (size_t i = 0; i < m_groupLocalEventBufferCount; ++i) {
lbajardsilogic@0 374 eventLocalBuffers[i] = m_groupLocalEventBuffers[i];
lbajardsilogic@0 375 }
lbajardsilogic@0 376 for (size_t i = m_groupLocalEventBufferCount; i < nextBufferCount; ++i) {
lbajardsilogic@0 377 eventLocalBuffers[i] = new snd_seq_event_t[EVENT_BUFFER_SIZE];
lbajardsilogic@0 378 }
lbajardsilogic@0 379
lbajardsilogic@0 380 if (m_groupLocalEventBuffers) {
lbajardsilogic@0 381 m_bufferScavenger.claim(new ScavengerArrayWrapper<snd_seq_event_t *>
lbajardsilogic@0 382 (m_groupLocalEventBuffers));
lbajardsilogic@0 383 }
lbajardsilogic@0 384
lbajardsilogic@0 385 m_groupLocalEventBuffers = eventLocalBuffers;
lbajardsilogic@0 386 m_groupLocalEventBufferCount = nextBufferCount;
lbajardsilogic@0 387 }
lbajardsilogic@0 388
lbajardsilogic@0 389 m_grouped = true;
lbajardsilogic@0 390 m_groupMap[m_identifier].insert(this);
lbajardsilogic@0 391 }
lbajardsilogic@0 392
lbajardsilogic@0 393 DSSIPluginInstance::~DSSIPluginInstance()
lbajardsilogic@0 394 {
lbajardsilogic@0 395 #ifdef DEBUG_DSSI
lbajardsilogic@0 396 std::cerr << "DSSIPluginInstance::~DSSIPluginInstance" << std::endl;
lbajardsilogic@0 397 #endif
lbajardsilogic@0 398
lbajardsilogic@0 399 if (m_threads.find(m_instanceHandle) != m_threads.end()) {
lbajardsilogic@0 400
lbajardsilogic@0 401 for (std::set<NonRTPluginThread *>::iterator i =
lbajardsilogic@0 402 m_threads[m_instanceHandle].begin();
lbajardsilogic@0 403 i != m_threads[m_instanceHandle].end(); ++i) {
lbajardsilogic@0 404
lbajardsilogic@0 405 (*i)->setExiting();
lbajardsilogic@0 406 (*i)->wait();
lbajardsilogic@0 407 delete *i;
lbajardsilogic@0 408 }
lbajardsilogic@0 409
lbajardsilogic@0 410 m_threads.erase(m_instanceHandle);
lbajardsilogic@0 411 }
lbajardsilogic@0 412
lbajardsilogic@0 413 detachFromGroup();
lbajardsilogic@0 414
lbajardsilogic@0 415 if (m_instanceHandle != 0) {
lbajardsilogic@0 416 deactivate();
lbajardsilogic@0 417 }
lbajardsilogic@0 418
lbajardsilogic@0 419 cleanup();
lbajardsilogic@0 420
lbajardsilogic@0 421 for (unsigned int i = 0; i < m_controlPortsIn.size(); ++i)
lbajardsilogic@0 422 delete m_controlPortsIn[i].second;
lbajardsilogic@0 423
lbajardsilogic@0 424 for (unsigned int i = 0; i < m_controlPortsOut.size(); ++i)
lbajardsilogic@0 425 delete m_controlPortsOut[i].second;
lbajardsilogic@0 426
lbajardsilogic@0 427 m_controlPortsIn.clear();
lbajardsilogic@0 428 m_controlPortsOut.clear();
lbajardsilogic@0 429
lbajardsilogic@0 430 if (m_ownBuffers) {
lbajardsilogic@0 431 for (size_t i = 0; i < m_audioPortsIn.size(); ++i) {
lbajardsilogic@0 432 delete[] m_inputBuffers[i];
lbajardsilogic@0 433 }
lbajardsilogic@0 434 for (size_t i = 0; i < m_outputBufferCount; ++i) {
lbajardsilogic@0 435 delete[] m_outputBuffers[i];
lbajardsilogic@0 436 }
lbajardsilogic@0 437
lbajardsilogic@0 438 delete[] m_inputBuffers;
lbajardsilogic@0 439 delete[] m_outputBuffers;
lbajardsilogic@0 440 }
lbajardsilogic@0 441
lbajardsilogic@0 442 m_audioPortsIn.clear();
lbajardsilogic@0 443 m_audioPortsOut.clear();
lbajardsilogic@0 444 }
lbajardsilogic@0 445
lbajardsilogic@0 446
lbajardsilogic@0 447 void
lbajardsilogic@0 448 DSSIPluginInstance::instantiate(unsigned long sampleRate)
lbajardsilogic@0 449 {
lbajardsilogic@0 450 #ifdef DEBUG_DSSI
lbajardsilogic@0 451 std::cout << "DSSIPluginInstance::instantiate - plugin \"unique\" id = "
lbajardsilogic@0 452 << m_descriptor->LADSPA_Plugin->UniqueID << std::endl;
lbajardsilogic@0 453 #endif
lbajardsilogic@0 454 if (!m_descriptor) return;
lbajardsilogic@0 455
lbajardsilogic@0 456 const LADSPA_Descriptor *descriptor = m_descriptor->LADSPA_Plugin;
lbajardsilogic@0 457
lbajardsilogic@0 458 if (!descriptor->instantiate) {
lbajardsilogic@0 459 std::cerr << "Bad plugin: plugin id " << descriptor->UniqueID
lbajardsilogic@0 460 << ":" << descriptor->Label
lbajardsilogic@0 461 << " has no instantiate method!" << std::endl;
lbajardsilogic@0 462 return;
lbajardsilogic@0 463 }
lbajardsilogic@0 464
lbajardsilogic@0 465 m_instanceHandle = descriptor->instantiate(descriptor, sampleRate);
lbajardsilogic@0 466
lbajardsilogic@0 467 if (m_instanceHandle) {
lbajardsilogic@0 468
lbajardsilogic@0 469 if (m_descriptor->get_midi_controller_for_port) {
lbajardsilogic@0 470
lbajardsilogic@0 471 for (unsigned long i = 0; i < descriptor->PortCount; ++i) {
lbajardsilogic@0 472
lbajardsilogic@0 473 if (LADSPA_IS_PORT_CONTROL(descriptor->PortDescriptors[i]) &&
lbajardsilogic@0 474 LADSPA_IS_PORT_INPUT(descriptor->PortDescriptors[i])) {
lbajardsilogic@0 475
lbajardsilogic@0 476 int controller = m_descriptor->get_midi_controller_for_port
lbajardsilogic@0 477 (m_instanceHandle, i);
lbajardsilogic@0 478
lbajardsilogic@0 479 if (controller != 0 && controller != 32 &&
lbajardsilogic@0 480 DSSI_IS_CC(controller)) {
lbajardsilogic@0 481
lbajardsilogic@0 482 m_controllerMap[DSSI_CC_NUMBER(controller)] = i;
lbajardsilogic@0 483 }
lbajardsilogic@0 484 }
lbajardsilogic@0 485 }
lbajardsilogic@0 486 }
lbajardsilogic@0 487 }
lbajardsilogic@0 488 }
lbajardsilogic@0 489
lbajardsilogic@0 490 void
lbajardsilogic@0 491 DSSIPluginInstance::checkProgramCache() const
lbajardsilogic@0 492 {
lbajardsilogic@0 493 if (m_programCacheValid) return;
lbajardsilogic@0 494 m_cachedPrograms.clear();
lbajardsilogic@0 495
lbajardsilogic@0 496 #ifdef DEBUG_DSSI
lbajardsilogic@0 497 std::cerr << "DSSIPluginInstance::checkProgramCache" << std::endl;
lbajardsilogic@0 498 #endif
lbajardsilogic@0 499
lbajardsilogic@0 500 if (!m_descriptor || !m_descriptor->get_program) {
lbajardsilogic@0 501 m_programCacheValid = true;
lbajardsilogic@0 502 return;
lbajardsilogic@0 503 }
lbajardsilogic@0 504
lbajardsilogic@0 505 unsigned long index = 0;
lbajardsilogic@0 506 const DSSI_Program_Descriptor *programDescriptor;
lbajardsilogic@0 507 while ((programDescriptor = m_descriptor->get_program(m_instanceHandle, index))) {
lbajardsilogic@0 508 ++index;
lbajardsilogic@0 509 ProgramDescriptor d;
lbajardsilogic@0 510 d.bank = programDescriptor->Bank;
lbajardsilogic@0 511 d.program = programDescriptor->Program;
lbajardsilogic@0 512 d.name = programDescriptor->Name;
lbajardsilogic@0 513 m_cachedPrograms.push_back(d);
lbajardsilogic@0 514 }
lbajardsilogic@0 515
lbajardsilogic@0 516 #ifdef DEBUG_DSSI
lbajardsilogic@0 517 std::cerr << "DSSIPluginInstance::checkProgramCache: have " << m_cachedPrograms.size() << " programs" << std::endl;
lbajardsilogic@0 518 #endif
lbajardsilogic@0 519
lbajardsilogic@0 520 m_programCacheValid = true;
lbajardsilogic@0 521 }
lbajardsilogic@0 522
lbajardsilogic@0 523 DSSIPluginInstance::ProgramList
lbajardsilogic@0 524 DSSIPluginInstance::getPrograms() const
lbajardsilogic@0 525 {
lbajardsilogic@0 526 #ifdef DEBUG_DSSI
lbajardsilogic@0 527 std::cerr << "DSSIPluginInstance::getPrograms" << std::endl;
lbajardsilogic@0 528 #endif
lbajardsilogic@0 529
lbajardsilogic@0 530 if (!m_descriptor) return ProgramList();
lbajardsilogic@0 531
lbajardsilogic@0 532 checkProgramCache();
lbajardsilogic@0 533
lbajardsilogic@0 534 ProgramList programs;
lbajardsilogic@0 535
lbajardsilogic@0 536 for (std::vector<ProgramDescriptor>::iterator i = m_cachedPrograms.begin();
lbajardsilogic@0 537 i != m_cachedPrograms.end(); ++i) {
lbajardsilogic@0 538 programs.push_back(i->name);
lbajardsilogic@0 539 }
lbajardsilogic@0 540
lbajardsilogic@0 541 return programs;
lbajardsilogic@0 542 }
lbajardsilogic@0 543
lbajardsilogic@0 544 std::string
lbajardsilogic@0 545 DSSIPluginInstance::getProgram(int bank, int program) const
lbajardsilogic@0 546 {
lbajardsilogic@0 547 #ifdef DEBUG_DSSI
lbajardsilogic@0 548 std::cerr << "DSSIPluginInstance::getProgram(" << bank << "," << program << ")" << std::endl;
lbajardsilogic@0 549 #endif
lbajardsilogic@0 550
lbajardsilogic@0 551 if (!m_descriptor) return std::string();
lbajardsilogic@0 552
lbajardsilogic@0 553 checkProgramCache();
lbajardsilogic@0 554
lbajardsilogic@0 555 for (std::vector<ProgramDescriptor>::iterator i = m_cachedPrograms.begin();
lbajardsilogic@0 556 i != m_cachedPrograms.end(); ++i) {
lbajardsilogic@0 557 if (i->bank == bank && i->program == program) return i->name;
lbajardsilogic@0 558 }
lbajardsilogic@0 559
lbajardsilogic@0 560 return std::string();
lbajardsilogic@0 561 }
lbajardsilogic@0 562
lbajardsilogic@0 563 unsigned long
lbajardsilogic@0 564 DSSIPluginInstance::getProgram(std::string name) const
lbajardsilogic@0 565 {
lbajardsilogic@0 566 #ifdef DEBUG_DSSI
lbajardsilogic@0 567 std::cerr << "DSSIPluginInstance::getProgram(" << name << ")" << std::endl;
lbajardsilogic@0 568 #endif
lbajardsilogic@0 569
lbajardsilogic@0 570 if (!m_descriptor) return 0;
lbajardsilogic@0 571
lbajardsilogic@0 572 checkProgramCache();
lbajardsilogic@0 573
lbajardsilogic@0 574 unsigned long rv;
lbajardsilogic@0 575
lbajardsilogic@0 576 for (std::vector<ProgramDescriptor>::iterator i = m_cachedPrograms.begin();
lbajardsilogic@0 577 i != m_cachedPrograms.end(); ++i) {
lbajardsilogic@0 578 if (i->name == name) {
lbajardsilogic@0 579 rv = i->bank;
lbajardsilogic@0 580 rv = (rv << 16) + i->program;
lbajardsilogic@0 581 return rv;
lbajardsilogic@0 582 }
lbajardsilogic@0 583 }
lbajardsilogic@0 584
lbajardsilogic@0 585 return 0;
lbajardsilogic@0 586 }
lbajardsilogic@0 587
lbajardsilogic@0 588 std::string
lbajardsilogic@0 589 DSSIPluginInstance::getCurrentProgram() const
lbajardsilogic@0 590 {
lbajardsilogic@0 591 return m_program;
lbajardsilogic@0 592 }
lbajardsilogic@0 593
lbajardsilogic@0 594 void
lbajardsilogic@0 595 DSSIPluginInstance::selectProgram(std::string program)
lbajardsilogic@0 596 {
lbajardsilogic@0 597 selectProgramAux(program, true);
lbajardsilogic@0 598 }
lbajardsilogic@0 599
lbajardsilogic@0 600 void
lbajardsilogic@0 601 DSSIPluginInstance::selectProgramAux(std::string program, bool backupPortValues)
lbajardsilogic@0 602 {
lbajardsilogic@0 603 #ifdef DEBUG_DSSI
lbajardsilogic@0 604 std::cerr << "DSSIPluginInstance::selectProgram(" << program << ")" << std::endl;
lbajardsilogic@0 605 #endif
lbajardsilogic@0 606
lbajardsilogic@0 607 if (!m_descriptor) return;
lbajardsilogic@0 608
lbajardsilogic@0 609 checkProgramCache();
lbajardsilogic@0 610
lbajardsilogic@0 611 if (!m_descriptor->select_program) return;
lbajardsilogic@0 612
lbajardsilogic@0 613 bool found = false;
lbajardsilogic@0 614 unsigned long bankNo = 0, programNo = 0;
lbajardsilogic@0 615
lbajardsilogic@0 616 for (std::vector<ProgramDescriptor>::iterator i = m_cachedPrograms.begin();
lbajardsilogic@0 617 i != m_cachedPrograms.end(); ++i) {
lbajardsilogic@0 618
lbajardsilogic@0 619 if (i->name == program) {
lbajardsilogic@0 620
lbajardsilogic@0 621 bankNo = i->bank;
lbajardsilogic@0 622 programNo = i->program;
lbajardsilogic@0 623 found = true;
lbajardsilogic@0 624
lbajardsilogic@0 625 #ifdef DEBUG_DSSI
lbajardsilogic@0 626 std::cerr << "DSSIPluginInstance::selectProgram(" << program << "): found at bank " << bankNo << ", program " << programNo << std::endl;
lbajardsilogic@0 627 #endif
lbajardsilogic@0 628
lbajardsilogic@0 629 break;
lbajardsilogic@0 630 }
lbajardsilogic@0 631 }
lbajardsilogic@0 632
lbajardsilogic@0 633 if (!found) return;
lbajardsilogic@0 634 m_program = program;
lbajardsilogic@0 635
lbajardsilogic@0 636 // DSSI select_program is an audio context call
lbajardsilogic@0 637 m_processLock.lock();
lbajardsilogic@0 638 m_descriptor->select_program(m_instanceHandle, bankNo, programNo);
lbajardsilogic@0 639 m_processLock.unlock();
lbajardsilogic@0 640
lbajardsilogic@0 641 #ifdef DEBUG_DSSI
lbajardsilogic@0 642 std::cerr << "DSSIPluginInstance::selectProgram(" << program << "): made select_program(" << bankNo << "," << programNo << ") call" << std::endl;
lbajardsilogic@0 643 #endif
lbajardsilogic@0 644
lbajardsilogic@0 645 if (backupPortValues) {
lbajardsilogic@0 646 for (size_t i = 0; i < m_backupControlPortsIn.size(); ++i) {
lbajardsilogic@0 647 m_backupControlPortsIn[i] = *m_controlPortsIn[i].second;
lbajardsilogic@0 648 }
lbajardsilogic@0 649 }
lbajardsilogic@0 650 }
lbajardsilogic@0 651
lbajardsilogic@0 652 void
lbajardsilogic@0 653 DSSIPluginInstance::activate()
lbajardsilogic@0 654 {
lbajardsilogic@0 655 #ifdef DEBUG_DSSI
lbajardsilogic@0 656 std::cerr << "DSSIPluginInstance::activate" << std::endl;
lbajardsilogic@0 657 #endif
lbajardsilogic@0 658
lbajardsilogic@0 659 if (!m_descriptor || !m_descriptor->LADSPA_Plugin->activate) return;
lbajardsilogic@0 660 m_descriptor->LADSPA_Plugin->activate(m_instanceHandle);
lbajardsilogic@0 661
lbajardsilogic@0 662 if (m_program != "") {
lbajardsilogic@0 663 #ifdef DEBUG_DSSI
lbajardsilogic@0 664 std::cerr << "DSSIPluginInstance::activate: restoring program " << m_program << std::endl;
lbajardsilogic@0 665 #endif
lbajardsilogic@0 666 selectProgramAux(m_program, false);
lbajardsilogic@0 667 }
lbajardsilogic@0 668
lbajardsilogic@0 669 for (size_t i = 0; i < m_backupControlPortsIn.size(); ++i) {
lbajardsilogic@0 670 #ifdef DEBUG_DSSI
lbajardsilogic@0 671 std::cerr << "DSSIPluginInstance::activate: setting port " << m_controlPortsIn[i].first << " to " << m_backupControlPortsIn[i] << std::endl;
lbajardsilogic@0 672 #endif
lbajardsilogic@0 673 *m_controlPortsIn[i].second = m_backupControlPortsIn[i];
lbajardsilogic@0 674 }
lbajardsilogic@0 675 }
lbajardsilogic@0 676
lbajardsilogic@0 677 void
lbajardsilogic@0 678 DSSIPluginInstance::connectPorts()
lbajardsilogic@0 679 {
lbajardsilogic@0 680 if (!m_descriptor || !m_descriptor->LADSPA_Plugin->connect_port) return;
lbajardsilogic@0 681 #ifdef DEBUG_DSSI
lbajardsilogic@0 682 std::cerr << "DSSIPluginInstance::connectPorts: " << m_audioPortsIn.size()
lbajardsilogic@0 683 << " audio ports in, " << m_audioPortsOut.size() << " out, "
lbajardsilogic@0 684 << m_outputBufferCount << " output buffers" << std::endl;
lbajardsilogic@0 685 #endif
lbajardsilogic@0 686
lbajardsilogic@0 687 assert(sizeof(LADSPA_Data) == sizeof(float));
lbajardsilogic@0 688 assert(sizeof(sample_t) == sizeof(float));
lbajardsilogic@0 689
lbajardsilogic@0 690 LADSPAPluginFactory *f = dynamic_cast<LADSPAPluginFactory *>(m_factory);
lbajardsilogic@0 691 int inbuf = 0, outbuf = 0;
lbajardsilogic@0 692
lbajardsilogic@0 693 for (unsigned int i = 0; i < m_audioPortsIn.size(); ++i) {
lbajardsilogic@0 694 m_descriptor->LADSPA_Plugin->connect_port
lbajardsilogic@0 695 (m_instanceHandle,
lbajardsilogic@0 696 m_audioPortsIn[i],
lbajardsilogic@0 697 (LADSPA_Data *)m_inputBuffers[inbuf]);
lbajardsilogic@0 698 ++inbuf;
lbajardsilogic@0 699 }
lbajardsilogic@0 700
lbajardsilogic@0 701 for (unsigned int i = 0; i < m_audioPortsOut.size(); ++i) {
lbajardsilogic@0 702 m_descriptor->LADSPA_Plugin->connect_port
lbajardsilogic@0 703 (m_instanceHandle,
lbajardsilogic@0 704 m_audioPortsOut[i],
lbajardsilogic@0 705 (LADSPA_Data *)m_outputBuffers[outbuf]);
lbajardsilogic@0 706 ++outbuf;
lbajardsilogic@0 707 }
lbajardsilogic@0 708
lbajardsilogic@0 709 for (unsigned int i = 0; i < m_controlPortsIn.size(); ++i) {
lbajardsilogic@0 710 m_descriptor->LADSPA_Plugin->connect_port
lbajardsilogic@0 711 (m_instanceHandle,
lbajardsilogic@0 712 m_controlPortsIn[i].first,
lbajardsilogic@0 713 m_controlPortsIn[i].second);
lbajardsilogic@0 714
lbajardsilogic@0 715 if (f) {
lbajardsilogic@0 716 float defaultValue = f->getPortDefault
lbajardsilogic@0 717 (m_descriptor->LADSPA_Plugin, m_controlPortsIn[i].first);
lbajardsilogic@0 718 *m_controlPortsIn[i].second = defaultValue;
lbajardsilogic@0 719 m_backupControlPortsIn[i] = defaultValue;
lbajardsilogic@0 720 #ifdef DEBUG_DSSI
lbajardsilogic@0 721 std::cerr << "DSSIPluginInstance::connectPorts: set control port " << i << " to default value " << defaultValue << std::endl;
lbajardsilogic@0 722 #endif
lbajardsilogic@0 723 }
lbajardsilogic@0 724 }
lbajardsilogic@0 725
lbajardsilogic@0 726 for (unsigned int i = 0; i < m_controlPortsOut.size(); ++i) {
lbajardsilogic@0 727 m_descriptor->LADSPA_Plugin->connect_port
lbajardsilogic@0 728 (m_instanceHandle,
lbajardsilogic@0 729 m_controlPortsOut[i].first,
lbajardsilogic@0 730 m_controlPortsOut[i].second);
lbajardsilogic@0 731 }
lbajardsilogic@0 732 }
lbajardsilogic@0 733
lbajardsilogic@0 734 unsigned int
lbajardsilogic@0 735 DSSIPluginInstance::getParameterCount() const
lbajardsilogic@0 736 {
lbajardsilogic@0 737 return m_controlPortsIn.size();
lbajardsilogic@0 738 }
lbajardsilogic@0 739
lbajardsilogic@0 740 void
lbajardsilogic@0 741 DSSIPluginInstance::setParameterValue(unsigned int parameter, float value)
lbajardsilogic@0 742 {
lbajardsilogic@0 743 #ifdef DEBUG_DSSI
lbajardsilogic@0 744 std::cerr << "DSSIPluginInstance::setParameterValue(" << parameter << ") to " << value << std::endl;
lbajardsilogic@0 745 #endif
lbajardsilogic@0 746 if (parameter >= m_controlPortsIn.size()) return;
lbajardsilogic@0 747
lbajardsilogic@0 748 unsigned int portNumber = m_controlPortsIn[parameter].first;
lbajardsilogic@0 749
lbajardsilogic@0 750 LADSPAPluginFactory *f = dynamic_cast<LADSPAPluginFactory *>(m_factory);
lbajardsilogic@0 751 if (f) {
lbajardsilogic@0 752 if (value < f->getPortMinimum(m_descriptor->LADSPA_Plugin, portNumber)) {
lbajardsilogic@0 753 value = f->getPortMinimum(m_descriptor->LADSPA_Plugin, portNumber);
lbajardsilogic@0 754 }
lbajardsilogic@0 755 if (value > f->getPortMaximum(m_descriptor->LADSPA_Plugin, portNumber)) {
lbajardsilogic@0 756 value = f->getPortMaximum(m_descriptor->LADSPA_Plugin, portNumber);
lbajardsilogic@0 757 }
lbajardsilogic@0 758 }
lbajardsilogic@0 759
lbajardsilogic@0 760 (*m_controlPortsIn[parameter].second) = value;
lbajardsilogic@0 761 m_backupControlPortsIn[parameter] = value;
lbajardsilogic@0 762 }
lbajardsilogic@0 763
lbajardsilogic@0 764 void
lbajardsilogic@0 765 DSSIPluginInstance::setPortValueFromController(unsigned int port, int cv)
lbajardsilogic@0 766 {
lbajardsilogic@0 767 #ifdef DEBUG_DSSI
lbajardsilogic@0 768 std::cerr << "DSSIPluginInstance::setPortValueFromController(" << port << ") to " << cv << std::endl;
lbajardsilogic@0 769 #endif
lbajardsilogic@0 770
lbajardsilogic@0 771 const LADSPA_Descriptor *p = m_descriptor->LADSPA_Plugin;
lbajardsilogic@0 772 LADSPA_PortRangeHintDescriptor d = p->PortRangeHints[port].HintDescriptor;
lbajardsilogic@0 773 LADSPA_Data lb = p->PortRangeHints[port].LowerBound;
lbajardsilogic@0 774 LADSPA_Data ub = p->PortRangeHints[port].UpperBound;
lbajardsilogic@0 775
lbajardsilogic@0 776 float value = (float)cv;
lbajardsilogic@0 777
lbajardsilogic@0 778 if (!LADSPA_IS_HINT_BOUNDED_BELOW(d)) {
lbajardsilogic@0 779 if (!LADSPA_IS_HINT_BOUNDED_ABOVE(d)) {
lbajardsilogic@0 780 /* unbounded: might as well leave the value alone. */
lbajardsilogic@0 781 } else {
lbajardsilogic@0 782 /* bounded above only. just shift the range. */
lbajardsilogic@0 783 value = ub - 127.0f + value;
lbajardsilogic@0 784 }
lbajardsilogic@0 785 } else {
lbajardsilogic@0 786 if (!LADSPA_IS_HINT_BOUNDED_ABOVE(d)) {
lbajardsilogic@0 787 /* bounded below only. just shift the range. */
lbajardsilogic@0 788 value = lb + value;
lbajardsilogic@0 789 } else {
lbajardsilogic@0 790 /* bounded both ends. more interesting. */
lbajardsilogic@0 791 /* XXX !!! todo: fill in logarithmic, sample rate &c */
lbajardsilogic@0 792 value = lb + ((ub - lb) * value / 127.0f);
lbajardsilogic@0 793 }
lbajardsilogic@0 794 }
lbajardsilogic@0 795
lbajardsilogic@0 796 for (unsigned int i = 0; i < m_controlPortsIn.size(); ++i) {
lbajardsilogic@0 797 if (m_controlPortsIn[i].first == port) {
lbajardsilogic@0 798 setParameterValue(i, value);
lbajardsilogic@0 799 }
lbajardsilogic@0 800 }
lbajardsilogic@0 801 }
lbajardsilogic@0 802
lbajardsilogic@0 803 float
lbajardsilogic@0 804 DSSIPluginInstance::getControlOutputValue(size_t output) const
lbajardsilogic@0 805 {
lbajardsilogic@0 806 if (output > m_controlPortsOut.size()) return 0.0;
lbajardsilogic@0 807 return (*m_controlPortsOut[output].second);
lbajardsilogic@0 808 }
lbajardsilogic@0 809
lbajardsilogic@0 810 float
lbajardsilogic@0 811 DSSIPluginInstance::getParameterValue(unsigned int parameter) const
lbajardsilogic@0 812 {
lbajardsilogic@0 813 #ifdef DEBUG_DSSI
lbajardsilogic@0 814 std::cerr << "DSSIPluginInstance::getParameterValue(" << parameter << ")" << std::endl;
lbajardsilogic@0 815 #endif
lbajardsilogic@0 816 if (parameter >= m_controlPortsIn.size()) return 0.0;
lbajardsilogic@0 817 return (*m_controlPortsIn[parameter].second);
lbajardsilogic@0 818 }
lbajardsilogic@0 819
lbajardsilogic@0 820 float
lbajardsilogic@0 821 DSSIPluginInstance::getParameterDefault(unsigned int parameter) const
lbajardsilogic@0 822 {
lbajardsilogic@0 823 if (parameter >= m_controlPortsIn.size()) return 0.0;
lbajardsilogic@0 824
lbajardsilogic@0 825 LADSPAPluginFactory *f = dynamic_cast<LADSPAPluginFactory *>(m_factory);
lbajardsilogic@0 826 if (f) {
lbajardsilogic@0 827 return f->getPortDefault(m_descriptor->LADSPA_Plugin,
lbajardsilogic@0 828 m_controlPortsIn[parameter].first);
lbajardsilogic@0 829 } else {
lbajardsilogic@0 830 return 0.0f;
lbajardsilogic@0 831 }
lbajardsilogic@0 832 }
lbajardsilogic@0 833
lbajardsilogic@0 834 std::string
lbajardsilogic@0 835 DSSIPluginInstance::configure(std::string key,
lbajardsilogic@0 836 std::string value)
lbajardsilogic@0 837 {
lbajardsilogic@0 838 if (!m_descriptor || !m_descriptor->configure) return std::string();
lbajardsilogic@0 839
lbajardsilogic@0 840 if (key == PluginIdentifier::RESERVED_PROJECT_DIRECTORY_KEY.toStdString()) {
lbajardsilogic@0 841 #ifdef DSSI_PROJECT_DIRECTORY_KEY
lbajardsilogic@0 842 key = DSSI_PROJECT_DIRECTORY_KEY;
lbajardsilogic@0 843 #else
lbajardsilogic@0 844 return std::string();
lbajardsilogic@0 845 #endif
lbajardsilogic@0 846 }
lbajardsilogic@0 847
lbajardsilogic@0 848
lbajardsilogic@0 849 #ifdef DEBUG_DSSI
lbajardsilogic@0 850 std::cerr << "DSSIPluginInstance::configure(" << key << "," << value << ")" << std::endl;
lbajardsilogic@0 851 #endif
lbajardsilogic@0 852
lbajardsilogic@0 853 char *message = m_descriptor->configure(m_instanceHandle,
lbajardsilogic@0 854 key.c_str(),
lbajardsilogic@0 855 value.c_str());
lbajardsilogic@0 856
lbajardsilogic@0 857 m_programCacheValid = false;
lbajardsilogic@0 858
lbajardsilogic@0 859 m_configurationData[key] = value;
lbajardsilogic@0 860
lbajardsilogic@0 861 std::string qm;
lbajardsilogic@0 862
lbajardsilogic@0 863 // Ignore return values from reserved key configuration calls such
lbajardsilogic@0 864 // as project directory
lbajardsilogic@0 865 #ifdef DSSI_RESERVED_CONFIGURE_PREFIX
lbajardsilogic@0 866 if (QString(key.c_str()).startsWith(DSSI_RESERVED_CONFIGURE_PREFIX)) {
lbajardsilogic@0 867 return qm;
lbajardsilogic@0 868 }
lbajardsilogic@0 869 #endif
lbajardsilogic@0 870
lbajardsilogic@0 871 if (message) {
lbajardsilogic@0 872 if (m_descriptor->LADSPA_Plugin && m_descriptor->LADSPA_Plugin->Label) {
lbajardsilogic@0 873 qm = std::string(m_descriptor->LADSPA_Plugin->Label) + ": ";
lbajardsilogic@0 874 }
lbajardsilogic@0 875 qm = qm + message;
lbajardsilogic@0 876 free(message);
lbajardsilogic@0 877
lbajardsilogic@0 878 std::cerr << "DSSIPluginInstance::configure: warning: configure returned message: \"" << qm << "\"" << std::endl;
lbajardsilogic@0 879 }
lbajardsilogic@0 880
lbajardsilogic@0 881 return qm;
lbajardsilogic@0 882 }
lbajardsilogic@0 883
lbajardsilogic@0 884 void
lbajardsilogic@0 885 DSSIPluginInstance::sendEvent(const Vamp::RealTime &eventTime,
lbajardsilogic@0 886 const void *e)
lbajardsilogic@0 887 {
lbajardsilogic@0 888 #ifdef DEBUG_DSSI_PROCESS
lbajardsilogic@0 889 std::cerr << "DSSIPluginInstance::sendEvent: last was " << m_lastEventSendTime << " (valid " << m_haveLastEventSendTime << "), this is " << eventTime << std::endl;
lbajardsilogic@0 890 #endif
lbajardsilogic@0 891
lbajardsilogic@0 892 // The process mechanism only works correctly if the events are
lbajardsilogic@0 893 // sorted. It's the responsibility of the caller to ensure that:
lbajardsilogic@0 894 // we will happily drop events here if we find the timeline going
lbajardsilogic@0 895 // backwards.
lbajardsilogic@0 896 if (m_haveLastEventSendTime &&
lbajardsilogic@0 897 m_lastEventSendTime > eventTime) {
lbajardsilogic@0 898 #ifdef DEBUG_DSSI_PROCESS
lbajardsilogic@0 899 std::cerr << "... clearing down" << std::endl;
lbajardsilogic@0 900 #endif
lbajardsilogic@0 901 m_haveLastEventSendTime = false;
lbajardsilogic@0 902 clearEvents();
lbajardsilogic@0 903 }
lbajardsilogic@0 904
lbajardsilogic@0 905 snd_seq_event_t *event = (snd_seq_event_t *)e;
lbajardsilogic@0 906 #ifdef DEBUG_DSSI_PROCESS
lbajardsilogic@0 907 std::cerr << "DSSIPluginInstance::sendEvent at " << eventTime << std::endl;
lbajardsilogic@0 908 #endif
lbajardsilogic@0 909 snd_seq_event_t ev(*event);
lbajardsilogic@0 910
lbajardsilogic@0 911 ev.time.time.tv_sec = eventTime.sec;
lbajardsilogic@0 912 ev.time.time.tv_nsec = eventTime.nsec;
lbajardsilogic@0 913
lbajardsilogic@0 914 // DSSI doesn't use MIDI channels, it uses run_multiple_synths instead.
lbajardsilogic@0 915 ev.data.note.channel = 0;
lbajardsilogic@0 916
lbajardsilogic@0 917 m_eventBuffer.write(&ev, 1);
lbajardsilogic@0 918
lbajardsilogic@0 919 m_lastEventSendTime = eventTime;
lbajardsilogic@0 920 m_haveLastEventSendTime = true;
lbajardsilogic@0 921 }
lbajardsilogic@0 922
lbajardsilogic@0 923 void
lbajardsilogic@0 924 DSSIPluginInstance::clearEvents()
lbajardsilogic@0 925 {
lbajardsilogic@0 926 m_haveLastEventSendTime = false;
lbajardsilogic@0 927 m_eventBuffer.reset();
lbajardsilogic@0 928 }
lbajardsilogic@0 929
lbajardsilogic@0 930 bool
lbajardsilogic@0 931 DSSIPluginInstance::handleController(snd_seq_event_t *ev)
lbajardsilogic@0 932 {
lbajardsilogic@0 933 int controller = ev->data.control.param;
lbajardsilogic@0 934
lbajardsilogic@0 935 #ifdef DEBUG_DSSI_PROCESS
lbajardsilogic@0 936 std::cerr << "DSSIPluginInstance::handleController " << controller << std::endl;
lbajardsilogic@0 937 #endif
lbajardsilogic@0 938
lbajardsilogic@0 939 if (controller == 0) { // bank select MSB
lbajardsilogic@0 940
lbajardsilogic@0 941 m_pending.msb = ev->data.control.value;
lbajardsilogic@0 942
lbajardsilogic@0 943 } else if (controller == 32) { // bank select LSB
lbajardsilogic@0 944
lbajardsilogic@0 945 m_pending.lsb = ev->data.control.value;
lbajardsilogic@0 946
lbajardsilogic@0 947 } else if (controller > 0 && controller < 128) {
lbajardsilogic@0 948
lbajardsilogic@0 949 if (m_controllerMap.find(controller) != m_controllerMap.end()) {
lbajardsilogic@0 950 int port = m_controllerMap[controller];
lbajardsilogic@0 951 setPortValueFromController(port, ev->data.control.value);
lbajardsilogic@0 952 } else {
lbajardsilogic@0 953 return true; // pass through to plugin
lbajardsilogic@0 954 }
lbajardsilogic@0 955 }
lbajardsilogic@0 956
lbajardsilogic@0 957 return false;
lbajardsilogic@0 958 }
lbajardsilogic@0 959
lbajardsilogic@0 960 void
lbajardsilogic@0 961 DSSIPluginInstance::run(const Vamp::RealTime &blockTime)
lbajardsilogic@0 962 {
lbajardsilogic@0 963 static snd_seq_event_t localEventBuffer[EVENT_BUFFER_SIZE];
lbajardsilogic@0 964 int evCount = 0;
lbajardsilogic@0 965
lbajardsilogic@0 966 bool needLock = false;
lbajardsilogic@0 967 if (m_descriptor->select_program) needLock = true;
lbajardsilogic@0 968
lbajardsilogic@0 969 if (needLock) {
lbajardsilogic@0 970 if (!m_processLock.tryLock()) {
lbajardsilogic@0 971 for (size_t ch = 0; ch < m_audioPortsOut.size(); ++ch) {
lbajardsilogic@0 972 memset(m_outputBuffers[ch], 0, m_blockSize * sizeof(sample_t));
lbajardsilogic@0 973 }
lbajardsilogic@0 974 return;
lbajardsilogic@0 975 }
lbajardsilogic@0 976 }
lbajardsilogic@0 977
lbajardsilogic@0 978 if (m_grouped) {
lbajardsilogic@0 979 runGrouped(blockTime);
lbajardsilogic@0 980 goto done;
lbajardsilogic@0 981 }
lbajardsilogic@0 982
lbajardsilogic@0 983 if (!m_descriptor || !m_descriptor->run_synth) {
lbajardsilogic@0 984 m_eventBuffer.skip(m_eventBuffer.getReadSpace());
lbajardsilogic@0 985 m_haveLastEventSendTime = false;
lbajardsilogic@0 986 if (m_descriptor->LADSPA_Plugin->run) {
lbajardsilogic@0 987 m_descriptor->LADSPA_Plugin->run(m_instanceHandle, m_blockSize);
lbajardsilogic@0 988 } else {
lbajardsilogic@0 989 for (size_t ch = 0; ch < m_audioPortsOut.size(); ++ch) {
lbajardsilogic@0 990 memset(m_outputBuffers[ch], 0, m_blockSize * sizeof(sample_t));
lbajardsilogic@0 991 }
lbajardsilogic@0 992 }
lbajardsilogic@0 993 m_run = true;
lbajardsilogic@0 994 if (needLock) m_processLock.unlock();
lbajardsilogic@0 995 return;
lbajardsilogic@0 996 }
lbajardsilogic@0 997
lbajardsilogic@0 998 #ifdef DEBUG_DSSI_PROCESS
lbajardsilogic@0 999 std::cerr << "DSSIPluginInstance::run(" << blockTime << ")" << std::endl;
lbajardsilogic@0 1000 #endif
lbajardsilogic@0 1001
lbajardsilogic@0 1002 #ifdef DEBUG_DSSI_PROCESS
lbajardsilogic@0 1003 if (m_eventBuffer.getReadSpace() > 0) {
lbajardsilogic@0 1004 std::cerr << "DSSIPluginInstance::run: event buffer has "
lbajardsilogic@0 1005 << m_eventBuffer.getReadSpace() << " event(s) in it" << std::endl;
lbajardsilogic@0 1006 }
lbajardsilogic@0 1007 #endif
lbajardsilogic@0 1008
lbajardsilogic@0 1009 while (m_eventBuffer.getReadSpace() > 0) {
lbajardsilogic@0 1010
lbajardsilogic@0 1011 snd_seq_event_t *ev = localEventBuffer + evCount;
lbajardsilogic@0 1012 *ev = m_eventBuffer.peekOne();
lbajardsilogic@0 1013 bool accept = true;
lbajardsilogic@0 1014
lbajardsilogic@0 1015 Vamp::RealTime evTime(ev->time.time.tv_sec, ev->time.time.tv_nsec);
lbajardsilogic@0 1016
lbajardsilogic@0 1017 int frameOffset = 0;
lbajardsilogic@0 1018 if (evTime > blockTime) {
lbajardsilogic@0 1019 frameOffset = Vamp::RealTime::realTime2Frame(evTime - blockTime, m_sampleRate);
lbajardsilogic@0 1020 }
lbajardsilogic@0 1021
lbajardsilogic@0 1022 #ifdef DEBUG_DSSI_PROCESS
lbajardsilogic@0 1023 std::cerr << "DSSIPluginInstance::run: evTime " << evTime << ", blockTime " << blockTime << ", frameOffset " << frameOffset
lbajardsilogic@0 1024 << ", blockSize " << m_blockSize << std::endl;
lbajardsilogic@0 1025 std::cerr << "Type: " << int(ev->type) << ", pitch: " << int(ev->data.note.note) << ", velocity: " << int(ev->data.note.velocity) << std::endl;
lbajardsilogic@0 1026 #endif
lbajardsilogic@0 1027
lbajardsilogic@0 1028 if (frameOffset >= int(m_blockSize)) break;
lbajardsilogic@0 1029 if (frameOffset < 0) {
lbajardsilogic@0 1030 frameOffset = 0;
lbajardsilogic@0 1031 if (ev->type == SND_SEQ_EVENT_NOTEON) {
lbajardsilogic@0 1032 m_eventBuffer.skip(1);
lbajardsilogic@0 1033 continue;
lbajardsilogic@0 1034 }
lbajardsilogic@0 1035 }
lbajardsilogic@0 1036
lbajardsilogic@0 1037 ev->time.tick = frameOffset;
lbajardsilogic@0 1038 m_eventBuffer.skip(1);
lbajardsilogic@0 1039
lbajardsilogic@0 1040 if (ev->type == SND_SEQ_EVENT_CONTROLLER) {
lbajardsilogic@0 1041 accept = handleController(ev);
lbajardsilogic@0 1042 } else if (ev->type == SND_SEQ_EVENT_PGMCHANGE) {
lbajardsilogic@0 1043 m_pending.program = ev->data.control.value;
lbajardsilogic@0 1044 accept = false;
lbajardsilogic@0 1045 }
lbajardsilogic@0 1046
lbajardsilogic@0 1047 if (accept) {
lbajardsilogic@0 1048 if (++evCount >= EVENT_BUFFER_SIZE) break;
lbajardsilogic@0 1049 }
lbajardsilogic@0 1050 }
lbajardsilogic@0 1051
lbajardsilogic@0 1052 if (m_pending.program >= 0 && m_descriptor->select_program) {
lbajardsilogic@0 1053
lbajardsilogic@0 1054 int program = m_pending.program;
lbajardsilogic@0 1055 int bank = m_pending.lsb + 128 * m_pending.msb;
lbajardsilogic@0 1056
lbajardsilogic@0 1057 #ifdef DEBUG_DSSI
lbajardsilogic@0 1058 std::cerr << "DSSIPluginInstance::run: making select_program(" << bank << "," << program << ") call" << std::endl;
lbajardsilogic@0 1059 #endif
lbajardsilogic@0 1060
lbajardsilogic@0 1061 m_pending.lsb = m_pending.msb = m_pending.program = -1;
lbajardsilogic@0 1062 m_descriptor->select_program(m_instanceHandle, bank, program);
lbajardsilogic@0 1063
lbajardsilogic@0 1064 #ifdef DEBUG_DSSI
lbajardsilogic@0 1065 std::cerr << "DSSIPluginInstance::run: made select_program(" << bank << "," << program << ") call" << std::endl;
lbajardsilogic@0 1066 #endif
lbajardsilogic@0 1067 }
lbajardsilogic@0 1068
lbajardsilogic@0 1069 #ifdef DEBUG_DSSI_PROCESS
lbajardsilogic@0 1070 std::cerr << "DSSIPluginInstance::run: running with " << evCount << " events"
lbajardsilogic@0 1071 << std::endl;
lbajardsilogic@0 1072 #endif
lbajardsilogic@0 1073
lbajardsilogic@0 1074 m_descriptor->run_synth(m_instanceHandle, m_blockSize,
lbajardsilogic@0 1075 localEventBuffer, evCount);
lbajardsilogic@0 1076
lbajardsilogic@0 1077 #ifdef DEBUG_DSSI_PROCESS
lbajardsilogic@0 1078 // for (int i = 0; i < m_blockSize; ++i) {
lbajardsilogic@0 1079 // std::cout << m_outputBuffers[0][i] << " ";
lbajardsilogic@0 1080 // if (i % 8 == 0) std::cout << std::endl;
lbajardsilogic@0 1081 // }
lbajardsilogic@0 1082 #endif
lbajardsilogic@0 1083
lbajardsilogic@0 1084 done:
lbajardsilogic@0 1085 if (needLock) m_processLock.unlock();
lbajardsilogic@0 1086
lbajardsilogic@0 1087 if (m_audioPortsOut.size() == 0) {
lbajardsilogic@0 1088 // copy inputs to outputs
lbajardsilogic@0 1089 for (size_t ch = 0; ch < m_idealChannelCount; ++ch) {
lbajardsilogic@0 1090 size_t sch = ch % m_audioPortsIn.size();
lbajardsilogic@0 1091 for (size_t i = 0; i < m_blockSize; ++i) {
lbajardsilogic@0 1092 m_outputBuffers[ch][i] = m_inputBuffers[sch][i];
lbajardsilogic@0 1093 }
lbajardsilogic@0 1094 }
lbajardsilogic@0 1095 } else if (m_idealChannelCount < m_audioPortsOut.size()) {
lbajardsilogic@0 1096 if (m_idealChannelCount == 1) {
lbajardsilogic@0 1097 // mix down to mono
lbajardsilogic@0 1098 for (size_t ch = 1; ch < m_audioPortsOut.size(); ++ch) {
lbajardsilogic@0 1099 for (size_t i = 0; i < m_blockSize; ++i) {
lbajardsilogic@0 1100 m_outputBuffers[0][i] += m_outputBuffers[ch][i];
lbajardsilogic@0 1101 }
lbajardsilogic@0 1102 }
lbajardsilogic@0 1103 }
lbajardsilogic@0 1104 } else if (m_idealChannelCount > m_audioPortsOut.size()) {
lbajardsilogic@0 1105 // duplicate
lbajardsilogic@0 1106 for (size_t ch = m_audioPortsOut.size(); ch < m_idealChannelCount; ++ch) {
lbajardsilogic@0 1107 size_t sch = (ch - m_audioPortsOut.size()) % m_audioPortsOut.size();
lbajardsilogic@0 1108 for (size_t i = 0; i < m_blockSize; ++i) {
lbajardsilogic@0 1109 m_outputBuffers[ch][i] = m_outputBuffers[sch][i];
lbajardsilogic@0 1110 }
lbajardsilogic@0 1111 }
lbajardsilogic@0 1112 }
lbajardsilogic@0 1113
lbajardsilogic@0 1114 m_lastRunTime = blockTime;
lbajardsilogic@0 1115 m_run = true;
lbajardsilogic@0 1116 }
lbajardsilogic@0 1117
lbajardsilogic@0 1118 void
lbajardsilogic@0 1119 DSSIPluginInstance::runGrouped(const Vamp::RealTime &blockTime)
lbajardsilogic@0 1120 {
lbajardsilogic@0 1121 // If something else in our group has just been called for this
lbajardsilogic@0 1122 // block time (but we haven't) then we should just write out the
lbajardsilogic@0 1123 // results and return; if we have just been called for this block
lbajardsilogic@0 1124 // time or nothing else in the group has been, we should run the
lbajardsilogic@0 1125 // whole group.
lbajardsilogic@0 1126
lbajardsilogic@0 1127 bool needRun = true;
lbajardsilogic@0 1128
lbajardsilogic@0 1129 PluginSet &s = m_groupMap[m_identifier];
lbajardsilogic@0 1130
lbajardsilogic@0 1131 #ifdef DEBUG_DSSI_PROCESS
lbajardsilogic@0 1132 std::cerr << "DSSIPluginInstance::runGrouped(" << blockTime << "): this is " << this << "; " << s.size() << " elements in m_groupMap[" << m_identifier << "]" << std::endl;
lbajardsilogic@0 1133 #endif
lbajardsilogic@0 1134
lbajardsilogic@0 1135 if (m_lastRunTime != blockTime) {
lbajardsilogic@0 1136 for (PluginSet::iterator i = s.begin(); i != s.end(); ++i) {
lbajardsilogic@0 1137 DSSIPluginInstance *instance = *i;
lbajardsilogic@0 1138 if (instance != this && instance->m_lastRunTime == blockTime) {
lbajardsilogic@0 1139 #ifdef DEBUG_DSSI_PROCESS
lbajardsilogic@0 1140 std::cerr << "DSSIPluginInstance::runGrouped(" << blockTime << "): plugin " << instance << " has already been run" << std::endl;
lbajardsilogic@0 1141 #endif
lbajardsilogic@0 1142 needRun = false;
lbajardsilogic@0 1143 }
lbajardsilogic@0 1144 }
lbajardsilogic@0 1145 }
lbajardsilogic@0 1146
lbajardsilogic@0 1147 if (!needRun) {
lbajardsilogic@0 1148 #ifdef DEBUG_DSSI_PROCESS
lbajardsilogic@0 1149 std::cerr << "DSSIPluginInstance::runGrouped(" << blockTime << "): already run, returning" << std::endl;
lbajardsilogic@0 1150 #endif
lbajardsilogic@0 1151 return;
lbajardsilogic@0 1152 }
lbajardsilogic@0 1153
lbajardsilogic@0 1154 #ifdef DEBUG_DSSI_PROCESS
lbajardsilogic@0 1155 std::cerr << "DSSIPluginInstance::runGrouped(" << blockTime << "): I'm the first, running" << std::endl;
lbajardsilogic@0 1156 #endif
lbajardsilogic@0 1157
lbajardsilogic@0 1158 size_t index = 0;
lbajardsilogic@0 1159 unsigned long *counts = (unsigned long *)
lbajardsilogic@0 1160 alloca(m_groupLocalEventBufferCount * sizeof(unsigned long));
lbajardsilogic@0 1161 LADSPA_Handle *instances = (LADSPA_Handle *)
lbajardsilogic@0 1162 alloca(m_groupLocalEventBufferCount * sizeof(LADSPA_Handle));
lbajardsilogic@0 1163
lbajardsilogic@0 1164 for (PluginSet::iterator i = s.begin(); i != s.end(); ++i) {
lbajardsilogic@0 1165
lbajardsilogic@0 1166 if (index >= m_groupLocalEventBufferCount) break;
lbajardsilogic@0 1167
lbajardsilogic@0 1168 DSSIPluginInstance *instance = *i;
lbajardsilogic@0 1169 counts[index] = 0;
lbajardsilogic@0 1170 instances[index] = instance->m_instanceHandle;
lbajardsilogic@0 1171
lbajardsilogic@0 1172 #ifdef DEBUG_DSSI_PROCESS
lbajardsilogic@0 1173 std::cerr << "DSSIPluginInstance::runGrouped(" << blockTime << "): running " << instance << std::endl;
lbajardsilogic@0 1174 #endif
lbajardsilogic@0 1175
lbajardsilogic@0 1176 if (instance->m_pending.program >= 0 &&
lbajardsilogic@0 1177 instance->m_descriptor->select_program) {
lbajardsilogic@0 1178 int program = instance->m_pending.program;
lbajardsilogic@0 1179 int bank = instance->m_pending.lsb + 128 * instance->m_pending.msb;
lbajardsilogic@0 1180 instance->m_pending.lsb = instance->m_pending.msb = instance->m_pending.program = -1;
lbajardsilogic@0 1181 instance->m_descriptor->select_program
lbajardsilogic@0 1182 (instance->m_instanceHandle, bank, program);
lbajardsilogic@0 1183 }
lbajardsilogic@0 1184
lbajardsilogic@0 1185 while (instance->m_eventBuffer.getReadSpace() > 0) {
lbajardsilogic@0 1186
lbajardsilogic@0 1187 snd_seq_event_t *ev = m_groupLocalEventBuffers[index] + counts[index];
lbajardsilogic@0 1188 *ev = instance->m_eventBuffer.peekOne();
lbajardsilogic@0 1189 bool accept = true;
lbajardsilogic@0 1190
lbajardsilogic@0 1191 Vamp::RealTime evTime(ev->time.time.tv_sec, ev->time.time.tv_nsec);
lbajardsilogic@0 1192
lbajardsilogic@0 1193 int frameOffset = 0;
lbajardsilogic@0 1194 if (evTime > blockTime) {
lbajardsilogic@0 1195 frameOffset = Vamp::RealTime::realTime2Frame(evTime - blockTime, m_sampleRate);
lbajardsilogic@0 1196 }
lbajardsilogic@0 1197
lbajardsilogic@0 1198 #ifdef DEBUG_DSSI_PROCESS
lbajardsilogic@0 1199 std::cerr << "DSSIPluginInstance::runGrouped: evTime " << evTime << ", frameOffset " << frameOffset
lbajardsilogic@0 1200 << ", block size " << m_blockSize << std::endl;
lbajardsilogic@0 1201 #endif
lbajardsilogic@0 1202
lbajardsilogic@0 1203 if (frameOffset >= int(m_blockSize)) break;
lbajardsilogic@0 1204 if (frameOffset < 0) frameOffset = 0;
lbajardsilogic@0 1205
lbajardsilogic@0 1206 ev->time.tick = frameOffset;
lbajardsilogic@0 1207 instance->m_eventBuffer.skip(1);
lbajardsilogic@0 1208
lbajardsilogic@0 1209 if (ev->type == SND_SEQ_EVENT_CONTROLLER) {
lbajardsilogic@0 1210 accept = instance->handleController(ev);
lbajardsilogic@0 1211 } else if (ev->type == SND_SEQ_EVENT_PGMCHANGE) {
lbajardsilogic@0 1212 instance->m_pending.program = ev->data.control.value;
lbajardsilogic@0 1213 accept = false;
lbajardsilogic@0 1214 }
lbajardsilogic@0 1215
lbajardsilogic@0 1216 if (accept) {
lbajardsilogic@0 1217 if (++counts[index] >= EVENT_BUFFER_SIZE) break;
lbajardsilogic@0 1218 }
lbajardsilogic@0 1219 }
lbajardsilogic@0 1220
lbajardsilogic@0 1221 ++index;
lbajardsilogic@0 1222 }
lbajardsilogic@0 1223
lbajardsilogic@0 1224 m_descriptor->run_multiple_synths(index,
lbajardsilogic@0 1225 instances,
lbajardsilogic@0 1226 m_blockSize,
lbajardsilogic@0 1227 m_groupLocalEventBuffers,
lbajardsilogic@0 1228 counts);
lbajardsilogic@0 1229 }
lbajardsilogic@0 1230
lbajardsilogic@0 1231 int
lbajardsilogic@0 1232 DSSIPluginInstance::requestMidiSend(LADSPA_Handle /* instance */,
lbajardsilogic@0 1233 unsigned char /* ports */,
lbajardsilogic@0 1234 unsigned char /* channels */)
lbajardsilogic@0 1235 {
lbajardsilogic@0 1236 // This is called from a non-RT context (during instantiate)
lbajardsilogic@0 1237
lbajardsilogic@0 1238 std::cerr << "DSSIPluginInstance::requestMidiSend" << std::endl;
lbajardsilogic@0 1239 return 1;
lbajardsilogic@0 1240 }
lbajardsilogic@0 1241
lbajardsilogic@0 1242 void
lbajardsilogic@0 1243 DSSIPluginInstance::midiSend(LADSPA_Handle /* instance */,
lbajardsilogic@0 1244 snd_seq_event_t * /* events */,
lbajardsilogic@0 1245 unsigned long /* eventCount */)
lbajardsilogic@0 1246 {
lbajardsilogic@0 1247 // This is likely to be called from an RT context
lbajardsilogic@0 1248
lbajardsilogic@0 1249 std::cerr << "DSSIPluginInstance::midiSend" << std::endl;
lbajardsilogic@0 1250 }
lbajardsilogic@0 1251
lbajardsilogic@0 1252 void
lbajardsilogic@0 1253 DSSIPluginInstance::NonRTPluginThread::run()
lbajardsilogic@0 1254 {
lbajardsilogic@0 1255 while (!m_exiting) {
lbajardsilogic@0 1256 m_runFunction(m_handle);
lbajardsilogic@0 1257 usleep(100000);
lbajardsilogic@0 1258 }
lbajardsilogic@0 1259 }
lbajardsilogic@0 1260
lbajardsilogic@0 1261 int
lbajardsilogic@0 1262 DSSIPluginInstance::requestNonRTThread(LADSPA_Handle instance,
lbajardsilogic@0 1263 void (*runFunction)(LADSPA_Handle))
lbajardsilogic@0 1264 {
lbajardsilogic@0 1265 NonRTPluginThread *thread = new NonRTPluginThread(instance, runFunction);
lbajardsilogic@0 1266 m_threads[instance].insert(thread);
lbajardsilogic@0 1267 thread->start();
lbajardsilogic@0 1268 return 0;
lbajardsilogic@0 1269 }
lbajardsilogic@0 1270
lbajardsilogic@0 1271 void
lbajardsilogic@0 1272 DSSIPluginInstance::deactivate()
lbajardsilogic@0 1273 {
lbajardsilogic@0 1274 #ifdef DEBUG_DSSI
lbajardsilogic@0 1275 std::cerr << "DSSIPluginInstance::deactivate " << m_identifier << std::endl;
lbajardsilogic@0 1276 #endif
lbajardsilogic@0 1277 if (!m_descriptor || !m_descriptor->LADSPA_Plugin->deactivate) return;
lbajardsilogic@0 1278
lbajardsilogic@0 1279 for (size_t i = 0; i < m_backupControlPortsIn.size(); ++i) {
lbajardsilogic@0 1280 m_backupControlPortsIn[i] = *m_controlPortsIn[i].second;
lbajardsilogic@0 1281 }
lbajardsilogic@0 1282
lbajardsilogic@0 1283 m_descriptor->LADSPA_Plugin->deactivate(m_instanceHandle);
lbajardsilogic@0 1284 #ifdef DEBUG_DSSI
lbajardsilogic@0 1285 std::cerr << "DSSIPluginInstance::deactivate " << m_identifier << " done" << std::endl;
lbajardsilogic@0 1286 #endif
lbajardsilogic@0 1287
lbajardsilogic@0 1288 m_bufferScavenger.scavenge();
lbajardsilogic@0 1289 }
lbajardsilogic@0 1290
lbajardsilogic@0 1291 void
lbajardsilogic@0 1292 DSSIPluginInstance::cleanup()
lbajardsilogic@0 1293 {
lbajardsilogic@0 1294 #ifdef DEBUG_DSSI
lbajardsilogic@0 1295 std::cerr << "DSSIPluginInstance::cleanup " << m_identifier << std::endl;
lbajardsilogic@0 1296 #endif
lbajardsilogic@0 1297 if (!m_descriptor) return;
lbajardsilogic@0 1298
lbajardsilogic@0 1299 if (!m_descriptor->LADSPA_Plugin->cleanup) {
lbajardsilogic@0 1300 std::cerr << "Bad plugin: plugin id "
lbajardsilogic@0 1301 << m_descriptor->LADSPA_Plugin->UniqueID
lbajardsilogic@0 1302 << ":" << m_descriptor->LADSPA_Plugin->Label
lbajardsilogic@0 1303 << " has no cleanup method!" << std::endl;
lbajardsilogic@0 1304 return;
lbajardsilogic@0 1305 }
lbajardsilogic@0 1306
lbajardsilogic@0 1307 m_descriptor->LADSPA_Plugin->cleanup(m_instanceHandle);
lbajardsilogic@0 1308 m_instanceHandle = 0;
lbajardsilogic@0 1309 #ifdef DEBUG_DSSI
lbajardsilogic@0 1310 std::cerr << "DSSIPluginInstance::cleanup " << m_identifier << " done" << std::endl;
lbajardsilogic@0 1311 #endif
lbajardsilogic@0 1312 }
lbajardsilogic@0 1313