annotate plugin/LADSPAPluginInstance.cpp @ 184:5a916fee6d2d

* Handle generator transforms (plugins whose channel count isn't dependent on number of audio inputs, as they have none) * Be less keen to suspend writing FFT data in spectrogram repaint -- only do it if we find we actually need to query the FFT data (i.e. we aren't repainting an area that hasn't been generated at all yet)
author Chris Cannam
date Tue, 10 Oct 2006 19:04:57 +0000
parents 570794f6f6a7
children 91fdc752e540
rev   line source
Chris@49 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@0 2
Chris@0 3 /*
Chris@52 4 Sonic Visualiser
Chris@52 5 An audio file viewer and annotation editor.
Chris@52 6 Centre for Digital Music, Queen Mary, University of London.
Chris@0 7
Chris@52 8 This program is free software; you can redistribute it and/or
Chris@52 9 modify it under the terms of the GNU General Public License as
Chris@52 10 published by the Free Software Foundation; either version 2 of the
Chris@52 11 License, or (at your option) any later version. See the file
Chris@52 12 COPYING included with this distribution for more information.
Chris@0 13 */
Chris@0 14
Chris@0 15 /*
Chris@0 16 This is a modified version of a source file from the
Chris@0 17 Rosegarden MIDI and audio sequencer and notation editor.
Chris@17 18 This file copyright 2000-2006 Chris Cannam and Richard Bown.
Chris@0 19 */
Chris@0 20
Chris@0 21 #include <iostream>
Chris@0 22 #include <cassert>
Chris@0 23
Chris@0 24 #include "LADSPAPluginInstance.h"
Chris@0 25 #include "LADSPAPluginFactory.h"
Chris@0 26
Chris@166 27 #ifdef HAVE_LRDF
Chris@166 28 #include "lrdf.h"
Chris@166 29 #endif // HAVE_LRDF
Chris@166 30
Chris@117 31 //#define DEBUG_LADSPA 1
Chris@0 32
Chris@0 33
Chris@0 34 LADSPAPluginInstance::LADSPAPluginInstance(RealTimePluginFactory *factory,
Chris@0 35 int clientId,
Chris@0 36 QString identifier,
Chris@0 37 int position,
Chris@0 38 unsigned long sampleRate,
Chris@0 39 size_t blockSize,
Chris@0 40 int idealChannelCount,
Chris@0 41 const LADSPA_Descriptor* descriptor) :
Chris@0 42 RealTimePluginInstance(factory, identifier),
Chris@0 43 m_client(clientId),
Chris@0 44 m_position(position),
Chris@0 45 m_instanceCount(0),
Chris@0 46 m_descriptor(descriptor),
Chris@0 47 m_blockSize(blockSize),
Chris@0 48 m_sampleRate(sampleRate),
Chris@0 49 m_latencyPort(0),
Chris@0 50 m_run(false),
Chris@0 51 m_bypassed(false)
Chris@0 52 {
Chris@0 53 init(idealChannelCount);
Chris@0 54
Chris@176 55 if (m_audioPortsIn.size() == 0) {
Chris@176 56 m_inputBuffers = 0;
Chris@176 57 } else {
Chris@176 58 m_inputBuffers = new sample_t*[m_instanceCount * m_audioPortsIn.size()];
Chris@176 59 }
Chris@176 60
Chris@176 61 if (m_audioPortsOut.size() == 0) {
Chris@176 62 m_outputBuffers = 0;
Chris@176 63 } else {
Chris@176 64 m_outputBuffers = new sample_t*[m_instanceCount * m_audioPortsOut.size()];
Chris@176 65 }
Chris@0 66
Chris@0 67 for (size_t i = 0; i < m_instanceCount * m_audioPortsIn.size(); ++i) {
Chris@0 68 m_inputBuffers[i] = new sample_t[blockSize];
Chris@0 69 }
Chris@0 70 for (size_t i = 0; i < m_instanceCount * m_audioPortsOut.size(); ++i) {
Chris@0 71 m_outputBuffers[i] = new sample_t[blockSize];
Chris@0 72 }
Chris@0 73
Chris@0 74 m_ownBuffers = true;
Chris@0 75
Chris@0 76 instantiate(sampleRate);
Chris@0 77 if (isOK()) {
Chris@0 78 connectPorts();
Chris@0 79 activate();
Chris@0 80 }
Chris@0 81 }
Chris@0 82
Chris@51 83 std::string
Chris@51 84 LADSPAPluginInstance::getName() const
Chris@0 85 {
Chris@51 86 return m_descriptor->Label;
Chris@0 87 }
Chris@0 88
Chris@51 89 std::string
Chris@51 90 LADSPAPluginInstance::getDescription() const
Chris@51 91 {
Chris@51 92 return m_descriptor->Name;
Chris@51 93 }
Chris@51 94
Chris@51 95 std::string
Chris@51 96 LADSPAPluginInstance::getMaker() const
Chris@51 97 {
Chris@51 98 return m_descriptor->Maker;
Chris@51 99 }
Chris@51 100
Chris@51 101 int
Chris@51 102 LADSPAPluginInstance::getPluginVersion() const
Chris@51 103 {
Chris@51 104 return 1;
Chris@51 105 }
Chris@51 106
Chris@51 107 std::string
Chris@51 108 LADSPAPluginInstance::getCopyright() const
Chris@51 109 {
Chris@51 110 return m_descriptor->Copyright;
Chris@51 111 }
Chris@51 112
Chris@51 113 LADSPAPluginInstance::ParameterList
Chris@51 114 LADSPAPluginInstance::getParameterDescriptors() const
Chris@51 115 {
Chris@51 116 ParameterList list;
Chris@51 117 LADSPAPluginFactory *f = dynamic_cast<LADSPAPluginFactory *>(m_factory);
Chris@51 118
Chris@51 119 for (unsigned int i = 0; i < m_controlPortsIn.size(); ++i) {
Chris@51 120
Chris@51 121 ParameterDescriptor pd;
Chris@51 122 unsigned int pn = m_controlPortsIn[i].first;
Chris@51 123
Chris@51 124 pd.name = m_descriptor->PortNames[pn];
Chris@51 125 pd.description = pd.name;
Chris@51 126 pd.minValue = f->getPortMinimum(m_descriptor, pn);
Chris@51 127 pd.maxValue = f->getPortMaximum(m_descriptor, pn);
Chris@51 128 pd.defaultValue = f->getPortDefault(m_descriptor, pn);
Chris@57 129
Chris@57 130 float q = f->getPortQuantization(m_descriptor, pn);
Chris@57 131 if (q == 0.0) {
Chris@57 132 pd.isQuantized = false;
Chris@57 133 } else {
Chris@57 134 pd.isQuantized = true;
Chris@57 135 pd.quantizeStep = q;
Chris@57 136 }
Chris@51 137
Chris@166 138 bool haveLabels = false;
Chris@166 139
Chris@166 140 #ifdef HAVE_LRDF
Chris@166 141 if (pd.isQuantized && pd.quantizeStep == 1.0) {
Chris@166 142
Chris@166 143 lrdf_defaults *defaults =
Chris@166 144 lrdf_get_scale_values(m_descriptor->UniqueID, pn);
Chris@166 145
Chris@166 146 if (defaults) {
Chris@166 147 if (defaults->count > 0) {
Chris@166 148 std::map<int, std::string> values;
Chris@166 149 int v = 0;
Chris@166 150 for (size_t i = 0; i < defaults->count; ++i) {
Chris@166 151 v = defaults->items[i].value;
Chris@166 152 values[v] = defaults->items[i].label;
Chris@166 153 }
Chris@166 154 for (size_t i = 0; i <= v; ++i) {
Chris@166 155 pd.valueNames.push_back(values[i]);
Chris@166 156 }
Chris@166 157 haveLabels = true;
Chris@166 158 }
Chris@166 159 lrdf_free_setting_values(defaults);
Chris@166 160 }
Chris@166 161 }
Chris@166 162 #endif
Chris@166 163
Chris@166 164 if (haveLabels) {
Chris@166 165 pd.description = QString(pd.description.c_str())
Chris@166 166 .replace(QRegExp("\\([^\\(\\)]+=[^\\(\\)]+\\)$"), "")
Chris@166 167 .toStdString();
Chris@166 168 } else {
Chris@166 169 static QRegExp unitRE("[\\[\\(]([A-Za-z0-9/]+)[\\)\\]]$");
Chris@166 170 if (unitRE.indexIn(pd.name.c_str()) >= 0) {
Chris@166 171 pd.unit = unitRE.cap(1).toStdString();
Chris@166 172 pd.description = QString(pd.description.c_str())
Chris@166 173 .replace(unitRE, "").toStdString();
Chris@166 174 }
Chris@166 175 }
Chris@166 176
Chris@51 177 list.push_back(pd);
Chris@51 178 }
Chris@51 179
Chris@51 180 return list;
Chris@51 181 }
Chris@51 182
Chris@51 183 float
Chris@51 184 LADSPAPluginInstance::getParameter(std::string name) const
Chris@51 185 {
Chris@51 186 for (unsigned int i = 0; i < m_controlPortsIn.size(); ++i) {
Chris@51 187 if (name == m_descriptor->PortNames[m_controlPortsIn[i].first]) {
Chris@51 188 return getParameterValue(i);
Chris@51 189 }
Chris@51 190 }
Chris@51 191
Chris@51 192 return 0.0;
Chris@51 193 }
Chris@51 194
Chris@51 195 void
Chris@51 196 LADSPAPluginInstance::setParameter(std::string name, float value)
Chris@51 197 {
Chris@51 198 for (unsigned int i = 0; i < m_controlPortsIn.size(); ++i) {
Chris@51 199 if (name == m_descriptor->PortNames[m_controlPortsIn[i].first]) {
Chris@51 200 setParameterValue(i, value);
Chris@51 201 break;
Chris@51 202 }
Chris@51 203 }
Chris@51 204 }
Chris@0 205
Chris@0 206 void
Chris@0 207 LADSPAPluginInstance::init(int idealChannelCount)
Chris@0 208 {
Chris@0 209 #ifdef DEBUG_LADSPA
Chris@0 210 std::cerr << "LADSPAPluginInstance::init(" << idealChannelCount << "): plugin has "
Chris@0 211 << m_descriptor->PortCount << " ports" << std::endl;
Chris@0 212 #endif
Chris@0 213
Chris@0 214 // Discover ports numbers and identities
Chris@0 215 //
Chris@0 216 for (unsigned long i = 0; i < m_descriptor->PortCount; ++i)
Chris@0 217 {
Chris@0 218 if (LADSPA_IS_PORT_AUDIO(m_descriptor->PortDescriptors[i]))
Chris@0 219 {
Chris@0 220 if (LADSPA_IS_PORT_INPUT(m_descriptor->PortDescriptors[i])) {
Chris@0 221 #ifdef DEBUG_LADSPA
Chris@0 222 std::cerr << "LADSPAPluginInstance::init: port " << i << " is audio in" << std::endl;
Chris@0 223 #endif
Chris@0 224 m_audioPortsIn.push_back(i);
Chris@0 225 } else {
Chris@0 226 #ifdef DEBUG_LADSPA
Chris@0 227 std::cerr << "LADSPAPluginInstance::init: port " << i << " is audio out" << std::endl;
Chris@0 228 #endif
Chris@0 229 m_audioPortsOut.push_back(i);
Chris@0 230 }
Chris@0 231 }
Chris@0 232 else
Chris@0 233 if (LADSPA_IS_PORT_CONTROL(m_descriptor->PortDescriptors[i]))
Chris@0 234 {
Chris@0 235 if (LADSPA_IS_PORT_INPUT(m_descriptor->PortDescriptors[i])) {
Chris@0 236 #ifdef DEBUG_LADSPA
Chris@0 237 std::cerr << "LADSPAPluginInstance::init: port " << i << " is control in" << std::endl;
Chris@0 238 #endif
Chris@0 239 LADSPA_Data *data = new LADSPA_Data(0.0);
Chris@0 240 m_controlPortsIn.push_back(
Chris@0 241 std::pair<unsigned long, LADSPA_Data*>(i, data));
Chris@0 242 } else {
Chris@0 243 #ifdef DEBUG_LADSPA
Chris@0 244 std::cerr << "LADSPAPluginInstance::init: port " << i << " is control out" << std::endl;
Chris@0 245 #endif
Chris@0 246 LADSPA_Data *data = new LADSPA_Data(0.0);
Chris@0 247 m_controlPortsOut.push_back(
Chris@0 248 std::pair<unsigned long, LADSPA_Data*>(i, data));
Chris@0 249 if (!strcmp(m_descriptor->PortNames[i], "latency") ||
Chris@0 250 !strcmp(m_descriptor->PortNames[i], "_latency")) {
Chris@0 251 #ifdef DEBUG_LADSPA
Chris@0 252 std::cerr << "Wooo! We have a latency port!" << std::endl;
Chris@0 253 #endif
Chris@0 254 m_latencyPort = data;
Chris@0 255 }
Chris@0 256 }
Chris@0 257 }
Chris@0 258 #ifdef DEBUG_LADSPA
Chris@0 259 else
Chris@0 260 std::cerr << "LADSPAPluginInstance::init - "
Chris@0 261 << "unrecognised port type" << std::endl;
Chris@0 262 #endif
Chris@0 263 }
Chris@0 264
Chris@0 265 m_instanceCount = 1;
Chris@0 266
Chris@0 267 if (idealChannelCount > 0) {
Chris@0 268 if (m_audioPortsIn.size() == 1) {
Chris@0 269 // mono plugin: duplicate it if need be
Chris@0 270 m_instanceCount = idealChannelCount;
Chris@0 271 }
Chris@0 272 }
Chris@0 273 }
Chris@0 274
Chris@0 275 size_t
Chris@0 276 LADSPAPluginInstance::getLatency()
Chris@0 277 {
Chris@0 278 if (m_latencyPort) {
Chris@66 279 if (!m_run) run(Vamp::RealTime::zeroTime);
Chris@0 280 if (*m_latencyPort > 0) return (size_t)*m_latencyPort;
Chris@0 281 }
Chris@0 282 return 0;
Chris@0 283 }
Chris@0 284
Chris@0 285 void
Chris@0 286 LADSPAPluginInstance::silence()
Chris@0 287 {
Chris@0 288 if (isOK()) {
Chris@0 289 deactivate();
Chris@0 290 activate();
Chris@0 291 }
Chris@0 292 }
Chris@0 293
Chris@0 294 void
Chris@0 295 LADSPAPluginInstance::setIdealChannelCount(size_t channels)
Chris@0 296 {
Chris@0 297 if (m_audioPortsIn.size() != 1 || channels == m_instanceCount) {
Chris@0 298 silence();
Chris@0 299 return;
Chris@0 300 }
Chris@0 301
Chris@0 302 if (isOK()) {
Chris@0 303 deactivate();
Chris@0 304 }
Chris@0 305
Chris@0 306 //!!! don't we need to reallocate inputBuffers and outputBuffers?
Chris@0 307
Chris@0 308 cleanup();
Chris@0 309 m_instanceCount = channels;
Chris@0 310 instantiate(m_sampleRate);
Chris@0 311 if (isOK()) {
Chris@0 312 connectPorts();
Chris@0 313 activate();
Chris@0 314 }
Chris@0 315 }
Chris@0 316
Chris@0 317
Chris@0 318 LADSPAPluginInstance::~LADSPAPluginInstance()
Chris@0 319 {
Chris@0 320 #ifdef DEBUG_LADSPA
Chris@0 321 std::cerr << "LADSPAPluginInstance::~LADSPAPluginInstance" << std::endl;
Chris@0 322 #endif
Chris@0 323
Chris@0 324 if (m_instanceHandles.size() != 0) { // "isOK()"
Chris@0 325 deactivate();
Chris@0 326 }
Chris@0 327
Chris@0 328 cleanup();
Chris@0 329
Chris@0 330 for (unsigned int i = 0; i < m_controlPortsIn.size(); ++i)
Chris@0 331 delete m_controlPortsIn[i].second;
Chris@0 332
Chris@0 333 for (unsigned int i = 0; i < m_controlPortsOut.size(); ++i)
Chris@0 334 delete m_controlPortsOut[i].second;
Chris@0 335
Chris@0 336 m_controlPortsIn.clear();
Chris@0 337 m_controlPortsOut.clear();
Chris@0 338
Chris@0 339 if (m_ownBuffers) {
Chris@184 340 for (size_t i = 0; i < m_instanceCount * m_audioPortsIn.size(); ++i) {
Chris@0 341 delete[] m_inputBuffers[i];
Chris@0 342 }
Chris@184 343 for (size_t i = 0; i < m_instanceCount * m_audioPortsOut.size(); ++i) {
Chris@0 344 delete[] m_outputBuffers[i];
Chris@0 345 }
Chris@0 346
Chris@0 347 delete[] m_inputBuffers;
Chris@0 348 delete[] m_outputBuffers;
Chris@0 349 }
Chris@0 350
Chris@0 351 m_audioPortsIn.clear();
Chris@0 352 m_audioPortsOut.clear();
Chris@0 353 }
Chris@0 354
Chris@0 355
Chris@0 356 void
Chris@0 357 LADSPAPluginInstance::instantiate(unsigned long sampleRate)
Chris@0 358 {
Chris@0 359 #ifdef DEBUG_LADSPA
Chris@0 360 std::cout << "LADSPAPluginInstance::instantiate - plugin unique id = "
Chris@0 361 << m_descriptor->UniqueID << std::endl;
Chris@0 362 #endif
Chris@0 363 if (!m_descriptor) return;
Chris@0 364
Chris@0 365 if (!m_descriptor->instantiate) {
Chris@0 366 std::cerr << "Bad plugin: plugin id " << m_descriptor->UniqueID
Chris@0 367 << ":" << m_descriptor->Label
Chris@0 368 << " has no instantiate method!" << std::endl;
Chris@0 369 return;
Chris@0 370 }
Chris@0 371
Chris@0 372 for (size_t i = 0; i < m_instanceCount; ++i) {
Chris@0 373 m_instanceHandles.push_back
Chris@0 374 (m_descriptor->instantiate(m_descriptor, sampleRate));
Chris@0 375 }
Chris@0 376 }
Chris@0 377
Chris@0 378 void
Chris@0 379 LADSPAPluginInstance::activate()
Chris@0 380 {
Chris@0 381 if (!m_descriptor || !m_descriptor->activate) return;
Chris@0 382
Chris@0 383 for (std::vector<LADSPA_Handle>::iterator hi = m_instanceHandles.begin();
Chris@0 384 hi != m_instanceHandles.end(); ++hi) {
Chris@0 385 m_descriptor->activate(*hi);
Chris@0 386 }
Chris@0 387 }
Chris@0 388
Chris@0 389 void
Chris@0 390 LADSPAPluginInstance::connectPorts()
Chris@0 391 {
Chris@0 392 if (!m_descriptor || !m_descriptor->connect_port) return;
Chris@0 393
Chris@0 394 assert(sizeof(LADSPA_Data) == sizeof(float));
Chris@0 395 assert(sizeof(sample_t) == sizeof(float));
Chris@0 396
Chris@57 397 LADSPAPluginFactory *f = dynamic_cast<LADSPAPluginFactory *>(m_factory);
Chris@0 398 int inbuf = 0, outbuf = 0;
Chris@0 399
Chris@0 400 for (std::vector<LADSPA_Handle>::iterator hi = m_instanceHandles.begin();
Chris@0 401 hi != m_instanceHandles.end(); ++hi) {
Chris@0 402
Chris@0 403 for (unsigned int i = 0; i < m_audioPortsIn.size(); ++i) {
Chris@0 404 m_descriptor->connect_port(*hi,
Chris@0 405 m_audioPortsIn[i],
Chris@0 406 (LADSPA_Data *)m_inputBuffers[inbuf]);
Chris@0 407 ++inbuf;
Chris@0 408 }
Chris@0 409
Chris@0 410 for (unsigned int i = 0; i < m_audioPortsOut.size(); ++i) {
Chris@0 411 m_descriptor->connect_port(*hi,
Chris@0 412 m_audioPortsOut[i],
Chris@0 413 (LADSPA_Data *)m_outputBuffers[outbuf]);
Chris@0 414 ++outbuf;
Chris@0 415 }
Chris@0 416
Chris@0 417 // If there is more than one instance, they all share the same
Chris@0 418 // control port ins (and outs, for the moment, because we
Chris@0 419 // don't actually do anything with the outs anyway -- but they
Chris@0 420 // do have to be connected as the plugin can't know if they're
Chris@0 421 // not and will write to them anyway).
Chris@0 422
Chris@0 423 for (unsigned int i = 0; i < m_controlPortsIn.size(); ++i) {
Chris@0 424 m_descriptor->connect_port(*hi,
Chris@0 425 m_controlPortsIn[i].first,
Chris@0 426 m_controlPortsIn[i].second);
Chris@57 427 if (f) {
Chris@57 428 float defaultValue = f->getPortDefault
Chris@57 429 (m_descriptor, m_controlPortsIn[i].first);
Chris@57 430 *m_controlPortsIn[i].second = defaultValue;
Chris@57 431 }
Chris@0 432 }
Chris@0 433
Chris@0 434 for (unsigned int i = 0; i < m_controlPortsOut.size(); ++i) {
Chris@0 435 m_descriptor->connect_port(*hi,
Chris@0 436 m_controlPortsOut[i].first,
Chris@0 437 m_controlPortsOut[i].second);
Chris@0 438 }
Chris@0 439 }
Chris@0 440 }
Chris@0 441
Chris@0 442 unsigned int
Chris@0 443 LADSPAPluginInstance::getParameterCount() const
Chris@0 444 {
Chris@0 445 return m_controlPortsIn.size();
Chris@0 446 }
Chris@0 447
Chris@0 448 void
Chris@0 449 LADSPAPluginInstance::setParameterValue(unsigned int parameter, float value)
Chris@0 450 {
Chris@0 451 if (parameter >= m_controlPortsIn.size()) return;
Chris@0 452
Chris@0 453 unsigned int portNumber = m_controlPortsIn[parameter].first;
Chris@0 454
Chris@0 455 LADSPAPluginFactory *f = dynamic_cast<LADSPAPluginFactory *>(m_factory);
Chris@0 456 if (f) {
Chris@0 457 if (value < f->getPortMinimum(m_descriptor, portNumber)) {
Chris@0 458 value = f->getPortMinimum(m_descriptor, portNumber);
Chris@0 459 }
Chris@0 460 if (value > f->getPortMaximum(m_descriptor, portNumber)) {
Chris@0 461 value = f->getPortMaximum(m_descriptor, portNumber);
Chris@0 462 }
Chris@0 463 }
Chris@0 464
Chris@0 465 (*m_controlPortsIn[parameter].second) = value;
Chris@0 466 }
Chris@0 467
Chris@0 468 float
Martin@62 469 LADSPAPluginInstance::getControlOutputValue(size_t output) const
Chris@60 470 {
Chris@60 471 if (output > m_controlPortsOut.size()) return 0.0;
Chris@60 472 return (*m_controlPortsOut[output].second);
Chris@60 473 }
Chris@60 474
Chris@60 475 float
Chris@0 476 LADSPAPluginInstance::getParameterValue(unsigned int parameter) const
Chris@0 477 {
Chris@0 478 if (parameter >= m_controlPortsIn.size()) return 0.0;
Chris@0 479 return (*m_controlPortsIn[parameter].second);
Chris@0 480 }
Chris@0 481
Chris@0 482 float
Chris@0 483 LADSPAPluginInstance::getParameterDefault(unsigned int parameter) const
Chris@0 484 {
Chris@0 485 if (parameter >= m_controlPortsIn.size()) return 0.0;
Chris@0 486
Chris@0 487 LADSPAPluginFactory *f = dynamic_cast<LADSPAPluginFactory *>(m_factory);
Chris@0 488 if (f) {
Chris@0 489 return f->getPortDefault(m_descriptor, m_controlPortsIn[parameter].first);
Chris@0 490 } else {
Chris@0 491 return 0.0f;
Chris@0 492 }
Chris@0 493 }
Chris@0 494
Chris@0 495 void
Chris@66 496 LADSPAPluginInstance::run(const Vamp::RealTime &)
Chris@0 497 {
Chris@0 498 if (!m_descriptor || !m_descriptor->run) return;
Chris@0 499
Chris@0 500 for (std::vector<LADSPA_Handle>::iterator hi = m_instanceHandles.begin();
Chris@0 501 hi != m_instanceHandles.end(); ++hi) {
Chris@0 502 m_descriptor->run(*hi, m_blockSize);
Chris@0 503 }
Chris@0 504
Chris@0 505 m_run = true;
Chris@0 506 }
Chris@0 507
Chris@0 508 void
Chris@0 509 LADSPAPluginInstance::deactivate()
Chris@0 510 {
Chris@0 511 if (!m_descriptor || !m_descriptor->deactivate) return;
Chris@0 512
Chris@0 513 for (std::vector<LADSPA_Handle>::iterator hi = m_instanceHandles.begin();
Chris@0 514 hi != m_instanceHandles.end(); ++hi) {
Chris@0 515 m_descriptor->deactivate(*hi);
Chris@0 516 }
Chris@0 517 }
Chris@0 518
Chris@0 519 void
Chris@0 520 LADSPAPluginInstance::cleanup()
Chris@0 521 {
Chris@0 522 if (!m_descriptor) return;
Chris@0 523
Chris@0 524 if (!m_descriptor->cleanup) {
Chris@0 525 std::cerr << "Bad plugin: plugin id " << m_descriptor->UniqueID
Chris@0 526 << ":" << m_descriptor->Label
Chris@0 527 << " has no cleanup method!" << std::endl;
Chris@0 528 return;
Chris@0 529 }
Chris@0 530
Chris@0 531 for (std::vector<LADSPA_Handle>::iterator hi = m_instanceHandles.begin();
Chris@0 532 hi != m_instanceHandles.end(); ++hi) {
Chris@0 533 m_descriptor->cleanup(*hi);
Chris@0 534 }
Chris@0 535
Chris@0 536 m_instanceHandles.clear();
Chris@0 537 }
Chris@0 538
Chris@0 539