summaryrefslogtreecommitdiff
path: root/muse/synti/simpledrums/ssplugin.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'muse/synti/simpledrums/ssplugin.cpp')
-rw-r--r--muse/synti/simpledrums/ssplugin.cpp459
1 files changed, 459 insertions, 0 deletions
diff --git a/muse/synti/simpledrums/ssplugin.cpp b/muse/synti/simpledrums/ssplugin.cpp
new file mode 100644
index 00000000..292c6029
--- /dev/null
+++ b/muse/synti/simpledrums/ssplugin.cpp
@@ -0,0 +1,459 @@
+//
+// C++ Implementation: plugin
+//
+// Description:
+//
+//
+// (C) Copyright 2000 Werner Schweer (ws@seh.de)
+// Additions/modifications: Mathias Lundgren <lunar_shuttle@users.sf.net>, (C) 2004
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <dlfcn.h>
+#include "ssplugin.h"
+#include "common.h"
+
+PluginList plugins;
+
+
+Plugin::Plugin(const QFileInfo* f)
+ : fi(*f)
+ {
+ }
+
+//---------------------------------------------------------
+// loadPluginLib
+//---------------------------------------------------------
+
+static void loadPluginLib(QFileInfo* fi)
+ {
+ SS_TRACE_IN
+ if (SS_DEBUG_LADSPA) {
+ printf("loadPluginLib: %s\n", fi->fileName().latin1());
+ }
+ void* handle = dlopen(fi->filePath().ascii(), RTLD_NOW);
+ if (handle == 0) {
+ fprintf(stderr, "dlopen(%s) failed: %s\n",
+ fi->filePath().ascii(), dlerror());
+ return;
+ }
+ LADSPA_Descriptor_Function ladspa = (LADSPA_Descriptor_Function)dlsym(handle, "ladspa_descriptor");
+
+ if (!ladspa) {
+ const char *txt = dlerror();
+ if (txt) {
+ fprintf(stderr,
+ "Unable to find ladspa_descriptor() function in plugin "
+ "library file \"%s\": %s.\n"
+ "Are you sure this is a LADSPA plugin file?\n",
+ fi->filePath().ascii(),
+ txt);
+ exit(1);
+ }
+ }
+ const LADSPA_Descriptor* descr;
+ for (int i = 0;; ++i) {
+ descr = ladspa(i);
+ if (descr == NULL)
+ break;
+ plugins.push_back(new LadspaPlugin(fi, ladspa, descr));
+ }
+ SS_TRACE_OUT
+ }
+
+//---------------------------------------------------------
+// loadPluginDir
+//---------------------------------------------------------
+
+static void loadPluginDir(const QString& s)
+ {
+ SS_TRACE_IN
+ QDir pluginDir(s, QString("*.so"), QDir::Files);
+ if (pluginDir.exists()) {
+ const QFileInfoList* list = pluginDir.entryInfoList();
+ QFileInfoListIterator it(*list);
+ QFileInfo* fi;
+ while((fi = it.current())) {
+ loadPluginLib(fi);
+ ++it;
+ }
+ }
+ SS_TRACE_OUT
+ }
+
+//---------------------------------------------------------
+// initPlugins
+// search for LADSPA plugins
+//---------------------------------------------------------
+
+void SS_initPlugins()
+ {
+ SS_TRACE_IN
+ //loadPluginDir(museGlobalLib + QString("/plugins"));
+
+ const char* ladspaPath = getenv("LADSPA_PATH");
+ if (ladspaPath == 0)
+ ladspaPath = "/usr/local/lib64/ladspa:/usr/lib64/ladspa:/usr/local/lib/ladspa:/usr/lib/ladspa";
+
+ const char* p = ladspaPath;
+ while (*p != '\0') {
+ const char* pe = p;
+ while (*pe != ':' && *pe != '\0')
+ pe++;
+
+ int n = pe - p;
+ if (n) {
+ char* buffer = new char[n + 1];
+ strncpy(buffer, p, n);
+ buffer[n] = '\0';
+ loadPluginDir(QString(buffer));
+ delete[] buffer;
+ }
+ p = pe;
+ if (*p == ':')
+ p++;
+ }
+ SS_TRACE_OUT
+ }
+
+
+//---------------------------------------------------------
+// LadspaPlugin
+//---------------------------------------------------------
+
+LadspaPlugin::LadspaPlugin(const QFileInfo* f,
+ const LADSPA_Descriptor_Function ldf,
+ const LADSPA_Descriptor* d)
+ : Plugin(f), ladspa(ldf), plugin(d)
+ {
+ SS_TRACE_IN
+ _inports = 0;
+ _outports = 0;
+ _parameter = 0;
+ handle = 0;
+ active = false;
+ controls = 0;
+ inputs = 0;
+ outputs = 0;
+
+ for (unsigned k = 0; k < plugin->PortCount; ++k) {
+ LADSPA_PortDescriptor pd = d->PortDescriptors[k];
+ static const int CI = LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT;
+ if ((pd & CI) == CI) {
+ ++_parameter;
+ pIdx.push_back(k);
+ }
+ else if (pd & LADSPA_PORT_INPUT) {
+ ++_inports;
+ iIdx.push_back(k);
+ }
+ else if (pd & LADSPA_PORT_OUTPUT) {
+ ++_outports;
+ oIdx.push_back(k);
+ }
+ }
+
+ /*if (SS_DEBUG_LADSPA) {
+ printf("Label: %s\tLib: %s\tPortCount: %d\n", this->label().latin1(), this->lib().latin1(), plugin->PortCount);
+ printf("LADSPA_PORT_CONTROL|LADSPA_PORT_INPUT: %d\t", pIdx.size());
+ printf("Input ports: %d\t", iIdx.size());
+ printf("Output ports: %d\n\n", oIdx.size());
+ }*/
+
+ LADSPA_Properties properties = plugin->Properties;
+ _inPlaceCapable = !LADSPA_IS_INPLACE_BROKEN(properties);
+ if (_inports != _outports)
+ _inPlaceCapable = false;
+ SS_TRACE_OUT
+ }
+
+//---------------------------------------------------------
+// ~LadspaPlugin
+//---------------------------------------------------------
+LadspaPlugin::~LadspaPlugin()
+ {
+ SS_TRACE_IN
+ if (active) {
+ stop();
+ }
+ if (handle) {
+ SS_DBG_LADSPA2("Cleaning up ", this->label().latin1());
+ plugin->cleanup(handle);
+ }
+
+ //Free ports:
+ if (controls)
+ delete controls;
+ if (inputs)
+ delete inputs;
+ if (outputs)
+ delete outputs;
+ SS_TRACE_OUT
+ }
+
+//---------------------------------------------------------
+// instantiate
+//---------------------------------------------------------
+
+bool LadspaPlugin::instantiate()
+ {
+ bool success = false;
+ handle = plugin->instantiate(plugin, SS_samplerate);
+ success = (handle != NULL);
+ if (success)
+ SS_DBG_LADSPA2("Plugin instantiated", label().latin1());
+ return success;
+ }
+
+//---------------------------------------------------------
+// start
+// activate and connect control ports
+//---------------------------------------------------------
+
+bool LadspaPlugin::start()
+ {
+ SS_TRACE_IN
+ if (handle) {
+ if (plugin->activate) {
+ plugin->activate(handle);
+ SS_DBG_LADSPA("Plugin activated");
+ }
+ active = true;
+ }
+ else {
+ SS_DBG_LADSPA("Error trying to activate plugin - plugin not instantiated!");
+ SS_TRACE_OUT
+ return false;
+ }
+
+ //Connect ports:
+ controls = new Port[_parameter];
+
+ for (int k = 0; k < _parameter; ++k) {
+ double val = defaultValue(k);
+ controls[k].val = val;
+ plugin->connect_port(handle, pIdx[k], &controls[k].val);
+ }
+
+ outputs = new Port[_outports];
+ inputs = new Port[_inports];
+
+ SS_TRACE_OUT
+ return true;
+ }
+
+//---------------------------------------------------------
+// stop
+// deactivate
+//---------------------------------------------------------
+void LadspaPlugin::stop()
+ {
+ SS_TRACE_IN
+ if (handle) {
+ SS_DBG_LADSPA2("Trying to stop plugin", label().latin1());
+ if (plugin->deactivate) {
+ SS_DBG_LADSPA2("Deactivating ", label().latin1());
+ plugin->deactivate(handle);
+ active = false;
+ }
+ }
+ else
+ SS_DBG_LADSPA("Warning - tried to stop plugin, but plugin was never started...\n");
+ SS_TRACE_OUT
+ }
+
+//---------------------------------------------------------
+// range
+//---------------------------------------------------------
+
+void LadspaPlugin::range(int i, float* min, float* max) const
+ {
+ SS_TRACE_IN
+ i = pIdx[i];
+ LADSPA_PortRangeHint range = plugin->PortRangeHints[i];
+ LADSPA_PortRangeHintDescriptor desc = range.HintDescriptor;
+ if (desc & LADSPA_HINT_TOGGLED) {
+ *min = 0.0;
+ *max = 1.0;
+ return;
+ }
+ float m = 1.0;
+ if (desc & LADSPA_HINT_SAMPLE_RATE)
+ m = (float) SS_samplerate;
+
+ if (desc & LADSPA_HINT_BOUNDED_BELOW)
+ *min = range.LowerBound * m;
+ else
+ *min = 0.0;
+ if (desc & LADSPA_HINT_BOUNDED_ABOVE)
+ *max = range.UpperBound * m;
+ else
+ *max = 1.0;
+ SS_TRACE_OUT
+ }
+
+//---------------------------------------------------------
+// defaultValue
+//---------------------------------------------------------
+
+float LadspaPlugin::defaultValue(int k) const
+ {
+ SS_TRACE_IN
+ k = pIdx[k];
+ LADSPA_PortRangeHint range = plugin->PortRangeHints[k];
+ LADSPA_PortRangeHintDescriptor rh = range.HintDescriptor;
+ double val = 1.0;
+ if (LADSPA_IS_HINT_DEFAULT_MINIMUM(rh))
+ val = range.LowerBound;
+ else if (LADSPA_IS_HINT_DEFAULT_LOW(rh))
+ if (LADSPA_IS_HINT_LOGARITHMIC(range.HintDescriptor))
+ val = exp(fast_log10(range.LowerBound) * .75 +
+ log(range.UpperBound) * .25);
+ else
+ val = range.LowerBound*.75 + range.UpperBound*.25;
+ else if (LADSPA_IS_HINT_DEFAULT_MIDDLE(rh))
+ if (LADSPA_IS_HINT_LOGARITHMIC(range.HintDescriptor))
+ val = exp(log(range.LowerBound) * .5 +
+ log(range.UpperBound) * .5);
+ else
+ val = range.LowerBound*.5 + range.UpperBound*.5;
+ else if (LADSPA_IS_HINT_DEFAULT_HIGH(rh))
+ if (LADSPA_IS_HINT_LOGARITHMIC(range.HintDescriptor))
+ val = exp(log(range.LowerBound) * .25 +
+ log(range.UpperBound) * .75);
+ else
+ val = range.LowerBound*.25 + range.UpperBound*.75;
+ else if (LADSPA_IS_HINT_DEFAULT_MAXIMUM(rh))
+ val = range.UpperBound;
+ else if (LADSPA_IS_HINT_DEFAULT_0(rh))
+ val = 0.0;
+ else if (LADSPA_IS_HINT_DEFAULT_1(rh))
+ val = 1.0;
+ else if (LADSPA_IS_HINT_DEFAULT_100(rh))
+ val = 100.0;
+ else if (LADSPA_IS_HINT_DEFAULT_440(rh))
+ val = 440.0;
+ SS_TRACE_OUT
+ return val;
+ }
+
+//---------------------------------------------------------
+// find
+//---------------------------------------------------------
+
+Plugin* PluginList::find(const QString& file, const QString& name)
+ {
+ SS_TRACE_IN
+ for (iPlugin i = begin(); i != end(); ++i) {
+ if ((file == (*i)->lib()) && (name == (*i)->label())) {
+ SS_TRACE_OUT
+ return *i;
+ }
+ }
+ printf("Plugin <%s> not found\n", name.latin1());
+ SS_TRACE_OUT
+ return 0;
+ }
+
+//---------------------------------------------------------
+// connectInport
+//---------------------------------------------------------
+void LadspaPlugin::connectInport(int k, LADSPA_Data* datalocation)
+ {
+ SS_TRACE_IN
+ plugin->connect_port(handle, iIdx[k], datalocation);
+ SS_TRACE_OUT
+ }
+
+//---------------------------------------------------------
+// connectOutport
+//---------------------------------------------------------
+void LadspaPlugin::connectOutport(int k, LADSPA_Data* datalocation)
+ {
+ SS_TRACE_IN
+ plugin->connect_port(handle, oIdx[k], datalocation);
+ SS_TRACE_OUT
+ }
+
+//---------------------------------------------------------
+// process
+//---------------------------------------------------------
+void LadspaPlugin::process(unsigned long frames)
+ {
+ plugin->run(handle, frames);
+ }
+
+//---------------------------------------------------------
+// setParam
+//---------------------------------------------------------
+
+void LadspaPlugin::setParam(int k, float val)
+ {
+ SS_TRACE_IN
+ controls[k].val = val;
+ SS_TRACE_OUT
+ }
+
+//---------------------------------------------------------
+// getGuiControlValue
+// scale control value to gui-slider/checkbox representation
+//---------------------------------------------------------
+
+int LadspaPlugin::getGuiControlValue(int param) const
+ {
+ SS_TRACE_IN
+ float val = getControlValue(param);
+ float min, max;
+ range(param, &min, &max);
+ int intval;
+ if (isLog(param)) {
+ intval = SS_map_logdomain2pluginparam(logf(val/(max - min) + min));
+ }
+ else if (isBool(param)) {
+ intval = (int) val;
+ }
+ else {
+ float scale = SS_PLUGIN_PARAM_MAX / (max - min);
+ intval = (int) ((val - min) * scale);
+ }
+ SS_TRACE_OUT
+ return intval;
+ }
+
+//---------------------------------------------------------
+// convertGuiControlValue
+// scale control value to gui-slider/checkbox representation
+//---------------------------------------------------------
+
+float LadspaPlugin::convertGuiControlValue(int parameter, int val) const
+ {
+ SS_TRACE_IN
+ float floatval = 0;
+ float min, max;
+ range(parameter, &min, &max);
+
+ if (isLog(parameter)) {
+ if (val > 0) {
+ float logged = SS_map_pluginparam2logdomain(val);
+ float e = expf(logged) * (max - min);
+ e+=min;
+ floatval = e;
+ }
+ }
+ else if (isBool(parameter)) {
+ floatval = (float) val;
+ }
+ else if (isInt(parameter)) {
+ float scale = (max - min) / SS_PLUGIN_PARAM_MAX;
+ floatval = (float) round((((float) val) * scale) + min);
+ }
+ else {
+ float scale = (max - min) / SS_PLUGIN_PARAM_MAX;
+ floatval = (((float) val) * scale) + min;
+ }
+ SS_TRACE_OUT
+ return floatval;
+ }