diff options
author | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-03-01 18:37:05 +0000 |
---|---|---|
committer | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-03-01 18:37:05 +0000 |
commit | 145364a8af6a1fec06556221e66d4b724a62fc9a (patch) | |
tree | 53bd71a544008c518034f208d64c932dc2883f50 /src/sound/LADSPAPluginInstance.cpp | |
download | rosegarden-145364a8af6a1fec06556221e66d4b724a62fc9a.tar.gz rosegarden-145364a8af6a1fec06556221e66d4b724a62fc9a.zip |
Added old abandoned KDE3 version of the RoseGarden MIDI tool
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/rosegarden@1097595 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'src/sound/LADSPAPluginInstance.cpp')
-rw-r--r-- | src/sound/LADSPAPluginInstance.cpp | 435 |
1 files changed, 435 insertions, 0 deletions
diff --git a/src/sound/LADSPAPluginInstance.cpp b/src/sound/LADSPAPluginInstance.cpp new file mode 100644 index 0000000..e2b8890 --- /dev/null +++ b/src/sound/LADSPAPluginInstance.cpp @@ -0,0 +1,435 @@ +// -*- c-indentation-style:"stroustrup" c-basic-offset: 4 -*- +/* + Rosegarden + A sequencer and musical notation editor. + + This program is Copyright 2000-2008 + Guillaume Laurent <[email protected]>, + Chris Cannam <[email protected]>, + Richard Bown <[email protected]> + + The moral right of the authors to claim authorship of this work + has been asserted. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. See the file + COPYING included with this distribution for more information. +*/ + +#include <iostream> +#include <cassert> + +#include "LADSPAPluginInstance.h" +#include "LADSPAPluginFactory.h" + +#ifdef HAVE_LADSPA + +//#define DEBUG_LADSPA 1 + +namespace Rosegarden +{ + + +LADSPAPluginInstance::LADSPAPluginInstance(PluginFactory *factory, + InstrumentId instrument, + QString identifier, + int position, + unsigned long sampleRate, + size_t blockSize, + int idealChannelCount, + const LADSPA_Descriptor* descriptor) : + RunnablePluginInstance(factory, identifier), + m_instrument(instrument), + m_position(position), + m_instanceCount(0), + m_descriptor(descriptor), + m_blockSize(blockSize), + m_sampleRate(sampleRate), + m_latencyPort(0), + m_run(false), + m_bypassed(false) +{ + init(idealChannelCount); + + m_inputBuffers = new sample_t * [m_instanceCount * m_audioPortsIn.size()]; + m_outputBuffers = new sample_t * [m_instanceCount * m_audioPortsOut.size()]; + + for (size_t i = 0; i < m_instanceCount * m_audioPortsIn.size(); ++i) { + m_inputBuffers[i] = new sample_t[blockSize]; + } + for (size_t i = 0; i < m_instanceCount * m_audioPortsOut.size(); ++i) { + m_outputBuffers[i] = new sample_t[blockSize]; + } + + m_ownBuffers = true; + + instantiate(sampleRate); + if (isOK()) { + connectPorts(); + activate(); + } +} + +LADSPAPluginInstance::LADSPAPluginInstance(PluginFactory *factory, + InstrumentId instrument, + QString identifier, + int position, + unsigned long sampleRate, + size_t blockSize, + sample_t **inputBuffers, + sample_t **outputBuffers, + const LADSPA_Descriptor* descriptor) : + RunnablePluginInstance(factory, identifier), + m_instrument(instrument), + m_position(position), + m_instanceCount(0), + m_descriptor(descriptor), + m_blockSize(blockSize), + m_inputBuffers(inputBuffers), + m_outputBuffers(outputBuffers), + m_ownBuffers(false), + m_sampleRate(sampleRate), + m_latencyPort(0), + m_run(false), + m_bypassed(false) +{ + init(); + + instantiate(sampleRate); + if (isOK()) { + connectPorts(); + activate(); + } +} + + +void +LADSPAPluginInstance::init(int idealChannelCount) +{ +#ifdef DEBUG_LADSPA + std::cerr << "LADSPAPluginInstance::init(" << idealChannelCount << "): plugin has " + << m_descriptor->PortCount << " ports" << std::endl; +#endif + + // Discover ports numbers and identities + // + for (unsigned long i = 0; i < m_descriptor->PortCount; ++i) { + if (LADSPA_IS_PORT_AUDIO(m_descriptor->PortDescriptors[i])) { + if (LADSPA_IS_PORT_INPUT(m_descriptor->PortDescriptors[i])) { +#ifdef DEBUG_LADSPA + std::cerr << "LADSPAPluginInstance::init: port " << i << " is audio in" << std::endl; +#endif + + m_audioPortsIn.push_back(i); + } else { +#ifdef DEBUG_LADSPA + std::cerr << "LADSPAPluginInstance::init: port " << i << " is audio out" << std::endl; +#endif + + m_audioPortsOut.push_back(i); + } + } else + if (LADSPA_IS_PORT_CONTROL(m_descriptor->PortDescriptors[i])) { + if (LADSPA_IS_PORT_INPUT(m_descriptor->PortDescriptors[i])) { +#ifdef DEBUG_LADSPA + std::cerr << "LADSPAPluginInstance::init: port " << i << " is control in" << std::endl; +#endif + + LADSPA_Data *data = new LADSPA_Data(0.0); + m_controlPortsIn.push_back( + std::pair<unsigned long, LADSPA_Data*>(i, data)); + } else { +#ifdef DEBUG_LADSPA + std::cerr << "LADSPAPluginInstance::init: port " << i << " is control out" << std::endl; +#endif + + LADSPA_Data *data = new LADSPA_Data(0.0); + m_controlPortsOut.push_back( + std::pair<unsigned long, LADSPA_Data*>(i, data)); + if (!strcmp(m_descriptor->PortNames[i], "latency") || + !strcmp(m_descriptor->PortNames[i], "_latency")) { +#ifdef DEBUG_LADSPA + std::cerr << "Wooo! We have a latency port!" << std::endl; +#endif + + m_latencyPort = data; + } + } + } +#ifdef DEBUG_LADSPA + else + std::cerr << "LADSPAPluginInstance::init - " + << "unrecognised port type" << std::endl; +#endif + + } + + m_instanceCount = 1; + + if (idealChannelCount > 0) { + if (m_audioPortsIn.size() == 1) { + // mono plugin: duplicate it if need be + m_instanceCount = idealChannelCount; + } + } +} + +size_t +LADSPAPluginInstance::getLatency() +{ + if (m_latencyPort) { + if (!m_run) { + for (int i = 0; i < getAudioInputCount(); ++i) { + for (int j = 0; j < m_blockSize; ++j) { + m_inputBuffers[i][j] = 0.f; + } + } + run(RealTime::zeroTime); + } + return *m_latencyPort; + } + return 0; +} + +void +LADSPAPluginInstance::silence() +{ + if (isOK()) { + deactivate(); + activate(); + } +} + +void +LADSPAPluginInstance::setIdealChannelCount(size_t channels) +{ + if (m_audioPortsIn.size() != 1 || channels == m_instanceCount) { + silence(); + return ; + } + + if (isOK()) { + deactivate(); + } + + //!!! don't we need to reallocate inputBuffers and outputBuffers? + + cleanup(); + m_instanceCount = channels; + instantiate(m_sampleRate); + if (isOK()) { + connectPorts(); + activate(); + } +} + + +LADSPAPluginInstance::~LADSPAPluginInstance() +{ +#ifdef DEBUG_LADSPA + std::cerr << "LADSPAPluginInstance::~LADSPAPluginInstance" << std::endl; +#endif + + if (m_instanceHandles.size() != 0) { // "isOK()" + deactivate(); + } + + cleanup(); + + for (unsigned int i = 0; i < m_controlPortsIn.size(); ++i) + delete m_controlPortsIn[i].second; + + for (unsigned int i = 0; i < m_controlPortsOut.size(); ++i) + delete m_controlPortsOut[i].second; + + m_controlPortsIn.clear(); + m_controlPortsOut.clear(); + + if (m_ownBuffers) { + for (size_t i = 0; i < m_audioPortsIn.size(); ++i) { + delete[] m_inputBuffers[i]; + } + for (size_t i = 0; i < m_audioPortsOut.size(); ++i) { + delete[] m_outputBuffers[i]; + } + + delete[] m_inputBuffers; + delete[] m_outputBuffers; + } + + m_audioPortsIn.clear(); + m_audioPortsOut.clear(); +} + + +void +LADSPAPluginInstance::instantiate(unsigned long sampleRate) +{ +#ifdef DEBUG_LADSPA + std::cout << "LADSPAPluginInstance::instantiate - plugin unique id = " + << m_descriptor->UniqueID << std::endl; +#endif + + if (!m_descriptor) + return ; + + if (!m_descriptor->instantiate) { + std::cerr << "Bad plugin: plugin id " << m_descriptor->UniqueID + << ":" << m_descriptor->Label + << " has no instantiate method!" << std::endl; + return ; + } + + for (int i = 0; i < m_instanceCount; ++i) { + m_instanceHandles.push_back + (m_descriptor->instantiate(m_descriptor, sampleRate)); + } +} + +void +LADSPAPluginInstance::activate() +{ + if (!m_descriptor || !m_descriptor->activate) + return ; + + for (std::vector<LADSPA_Handle>::iterator hi = m_instanceHandles.begin(); + hi != m_instanceHandles.end(); ++hi) { + m_descriptor->activate(*hi); + } +} + +void +LADSPAPluginInstance::connectPorts() +{ + if (!m_descriptor || !m_descriptor->connect_port) + return ; + + assert(sizeof(LADSPA_Data) == sizeof(float)); + assert(sizeof(sample_t) == sizeof(float)); + + int inbuf = 0, outbuf = 0; + + for (std::vector<LADSPA_Handle>::iterator hi = m_instanceHandles.begin(); + hi != m_instanceHandles.end(); ++hi) { + + for (unsigned int i = 0; i < m_audioPortsIn.size(); ++i) { + m_descriptor->connect_port(*hi, + m_audioPortsIn[i], + (LADSPA_Data *)m_inputBuffers[inbuf]); + ++inbuf; + } + + for (unsigned int i = 0; i < m_audioPortsOut.size(); ++i) { + m_descriptor->connect_port(*hi, + m_audioPortsOut[i], + (LADSPA_Data *)m_outputBuffers[outbuf]); + ++outbuf; + } + + // If there is more than one instance, they all share the same + // control port ins (and outs, for the moment, because we + // don't actually do anything with the outs anyway -- but they + // do have to be connected as the plugin can't know if they're + // not and will write to them anyway). + + for (unsigned int i = 0; i < m_controlPortsIn.size(); ++i) { + m_descriptor->connect_port(*hi, + m_controlPortsIn[i].first, + m_controlPortsIn[i].second); + } + + for (unsigned int i = 0; i < m_controlPortsOut.size(); ++i) { + m_descriptor->connect_port(*hi, + m_controlPortsOut[i].first, + m_controlPortsOut[i].second); + } + } +} + +void +LADSPAPluginInstance::setPortValue(unsigned int portNumber, float value) +{ + for (unsigned int i = 0; i < m_controlPortsIn.size(); ++i) { + if (m_controlPortsIn[i].first == portNumber) { + LADSPAPluginFactory *f = dynamic_cast<LADSPAPluginFactory *>(m_factory); + if (f) { + if (value < f->getPortMinimum(m_descriptor, portNumber)) { + value = f->getPortMinimum(m_descriptor, portNumber); + } + if (value > f->getPortMaximum(m_descriptor, portNumber)) { + value = f->getPortMaximum(m_descriptor, portNumber); + } + } + (*m_controlPortsIn[i].second) = value; + } + } +} + +float +LADSPAPluginInstance::getPortValue(unsigned int portNumber) +{ + for (unsigned int i = 0; i < m_controlPortsIn.size(); ++i) { + if (m_controlPortsIn[i].first == portNumber) { + return (*m_controlPortsIn[i].second); + } + } + + return 0.0; +} + +void +LADSPAPluginInstance::run(const RealTime &) +{ + if (!m_descriptor || !m_descriptor->run) + return ; + + for (std::vector<LADSPA_Handle>::iterator hi = m_instanceHandles.begin(); + hi != m_instanceHandles.end(); ++hi) { + m_descriptor->run(*hi, m_blockSize); + } + + m_run = true; +} + +void +LADSPAPluginInstance::deactivate() +{ + if (!m_descriptor || !m_descriptor->deactivate) + return ; + + for (std::vector<LADSPA_Handle>::iterator hi = m_instanceHandles.begin(); + hi != m_instanceHandles.end(); ++hi) { + m_descriptor->deactivate(*hi); + } +} + +void +LADSPAPluginInstance::cleanup() +{ + if (!m_descriptor) + return ; + + if (!m_descriptor->cleanup) { + std::cerr << "Bad plugin: plugin id " << m_descriptor->UniqueID + << ":" << m_descriptor->Label + << " has no cleanup method!" << std::endl; + return ; + } + + for (std::vector<LADSPA_Handle>::iterator hi = m_instanceHandles.begin(); + hi != m_instanceHandles.end(); ++hi) { + m_descriptor->cleanup(*hi); + } + + m_instanceHandles.clear(); +} + + + +} + +#endif // HAVE_LADSPA + + |