From 1128dce7d78ce44f6157259efc73b38ae7005133 Mon Sep 17 00:00:00 2001 From: trialuser02 Date: Mon, 7 Dec 2009 12:58:18 +0000 Subject: some ladspa plugin changes git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@1426 90c681e8-e032-0410-971d-27865f9a5e38 --- src/plugins/Effect/ladspa/effectladspafactory.cpp | 2 +- src/plugins/Effect/ladspa/ladspa.pro | 7 +- src/plugins/Effect/ladspa/ladspahost.cpp | 488 ++++++++++++++++++++++ src/plugins/Effect/ladspa/ladspahost.h | 110 +++++ src/plugins/Effect/ladspa/ladspaplugin.cpp | 487 --------------------- src/plugins/Effect/ladspa/ladspaplugin.h | 112 ----- src/plugins/Effect/ladspa/ladspaslider.cpp | 2 +- src/plugins/Effect/ladspa/ladspaslider.h | 2 +- src/plugins/Effect/ladspa/settingsdialog.cpp | 4 +- src/plugins/Effect/ladspa/settingsdialog.ui | 2 +- 10 files changed, 609 insertions(+), 607 deletions(-) create mode 100644 src/plugins/Effect/ladspa/ladspahost.cpp create mode 100644 src/plugins/Effect/ladspa/ladspahost.h delete mode 100644 src/plugins/Effect/ladspa/ladspaplugin.cpp delete mode 100644 src/plugins/Effect/ladspa/ladspaplugin.h (limited to 'src') diff --git a/src/plugins/Effect/ladspa/effectladspafactory.cpp b/src/plugins/Effect/ladspa/effectladspafactory.cpp index 6c517408f..792e113b6 100644 --- a/src/plugins/Effect/ladspa/effectladspafactory.cpp +++ b/src/plugins/Effect/ladspa/effectladspafactory.cpp @@ -22,7 +22,7 @@ #include #include "effectladspafactory.h" #include "settingsdialog.h" -#include "ladspaplugin.h" +#include "ladspahost.h" const EffectProperties EffectLADSPAFactory::properties() const { diff --git a/src/plugins/Effect/ladspa/ladspa.pro b/src/plugins/Effect/ladspa/ladspa.pro index 2e50e43c2..ee2be3f34 100644 --- a/src/plugins/Effect/ladspa/ladspa.pro +++ b/src/plugins/Effect/ladspa/ladspa.pro @@ -1,9 +1,10 @@ include(../../plugins.pri) -HEADERS += ladspaplugin.h \ +HEADERS += ladspahost.h \ effectladspafactory.h \ settingsdialog.h \ - ladspaslider.h -SOURCES += ladspaplugin.cpp \ + ladspaslider.h \ + ladspa.h +SOURCES += ladspahost.cpp \ effectladspafactory.cpp \ settingsdialog.cpp \ ladspaslider.cpp diff --git a/src/plugins/Effect/ladspa/ladspahost.cpp b/src/plugins/Effect/ladspa/ladspahost.cpp new file mode 100644 index 000000000..a204f2c2b --- /dev/null +++ b/src/plugins/Effect/ladspa/ladspahost.cpp @@ -0,0 +1,488 @@ +/*************************************************************************** + * Copyright (C) 2009 by Ilya Kotov * + * * + * * + * 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. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "ladspahost.h" + +#ifndef PATH_MAX +#define PATH_MAX 4096 +#endif + +#undef CLAMP +#define CLAMP(x, low, high) (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x))) + +LADSPAHost *LADSPAHost::m_instance = 0; + +LADSPAHost::LADSPAHost() : Effect() +{ + m_instance = this; + findAllPlugins(); +} + +LADSPAHost::~LADSPAHost() +{ + m_instance = 0; + foreach(LADSPAEffect *instance, m_effects) + { + unload(instance); + } +} + +ulong LADSPAHost::process(char *in_data, const ulong size, char **out_data) +{ + applyEffect((qint16 *) in_data, size); + memcpy(*out_data, in_data, size); + return size; +} + +void LADSPAHost::configure(quint32 freq, int chan, int res) +{ + Effect::configure(freq, chan, res); +} + +LADSPAHost* LADSPAHost::instance() +{ + return m_instance; +} + +QList LADSPAHost::plugins() +{ + return m_plugins; +} + +QList LADSPAHost::runningPlugins() +{ + return m_effects; +} + +/*!!!!*/ +void LADSPAHost::findAllPlugins() +{ + while(!m_plugins.isEmpty()) /* empty list */ + delete m_plugins.takeFirst(); + + QString ladspa_path = qgetenv("LADSPA_PATH"); + QStringList directories; + + if (ladspa_path.isEmpty()) + { + /* Fallback, look in obvious places */ + directories << "/usr/lib/ladspa"; + directories << "/usr/local/lib/ladspa"; + } + else + directories = ladspa_path.split(':'); + foreach(QString dir, directories) + findPlugins(dir); +} + +LADSPAEffect *LADSPAHost::load(const QString &filename, long int num) +{ + LADSPA_Descriptor_Function descriptor_fn; + LADSPAEffect *instance = new LADSPAEffect; + + instance->fileName = filename; + instance->library = dlopen(qPrintable(filename), RTLD_NOW); + instance->handle = 0; + instance->handle2 = 0; + if (!instance->library) + { + delete instance; + return 0; + } + descriptor_fn = (LADSPA_Descriptor_Function) dlsym(instance->library, "ladspa_descriptor"); + if (!descriptor_fn) + { + dlclose(instance->library); + delete instance; + return 0; + } + instance->descriptor = descriptor_fn(num); + + return instance; +} + +void LADSPAHost::unload(LADSPAEffect *instance) +{ + const LADSPA_Descriptor *descriptor = instance->descriptor; + + if (instance->handle) + { + if (descriptor->deactivate) + descriptor->deactivate(instance->handle); + descriptor->cleanup(instance->handle); + instance->handle = 0; + } + if (instance->handle2) + { + if (descriptor->deactivate) + descriptor->deactivate(instance->handle2); + descriptor->cleanup(instance->handle2); + instance->handle2 = 0; + } + + if (instance->library) + { + dlclose(instance->library); + instance->library = 0; + } + m_effects.removeAll(instance); + qDeleteAll(instance->controls); + delete instance; +} + +void LADSPAHost::bootPlugin(LADSPAEffect *instance) +{ + const LADSPA_Descriptor *descriptor = instance->descriptor; + + instance->handle = descriptor->instantiate(descriptor, (int)sampleRate()); + if (channels() > 1 && !instance->stereo) + { + /* Create an additional instance */ + instance->handle2 = descriptor->instantiate(descriptor, (int)sampleRate()); + } + + portAssign(instance); + + if (descriptor->activate) + { + descriptor->activate(instance->handle); + if (instance->handle2) + descriptor->activate(instance->handle2); + } +} + +int LADSPAHost::applyEffect(qint16 *d, int length) +{ + qint16 *raw16 = d; + LADSPAEffect *instance; + int k; + int nch = channels(); + + if (m_effects.isEmpty()) + return length; + + if (nch == 1) + { + for (k = 0; k < length / 2; ++k) + m_left[k] = ((LADSPA_Data) raw16[k]) * (1.0f / 32768.0f); + foreach(instance, m_effects) + { + if (instance->handle) + instance->descriptor->run(instance->handle, length / 2); + } + for (k = 0; k < length / 2; ++k) + raw16[k] = CLAMP((int)(m_left[k] * 32768.0f), -32768, 32767); + } + else + { + for (k = 0; k < length / 2; k += 2) + { + m_left[k/2] = ((LADSPA_Data) raw16[k]) * (1.0f / 32768.0f); + m_right[(k+1)/2] = ((LADSPA_Data) raw16[k+1]) * (1.0f / 32768.0f); + } + foreach(instance, m_effects) + { + if (instance->handle) + instance->descriptor->run(instance->handle, length/4); + if (instance->handle2) + instance->descriptor->run(instance->handle2, length/4); + } + for (k = 0; k < length / 2; k += 2) + { + raw16[k] = CLAMP((int)(m_left[k/2] * 32768.0f), -32768, 32767); + raw16[k+1] = CLAMP((int)(m_right[(k+1)/2] * 32768.0f), -32768, 32767); + + } + } + return length; +} + +void LADSPAHost::portAssign(LADSPAEffect *instance) +{ + unsigned long port; + unsigned long inputs = 0, outputs = 0; + const LADSPA_Descriptor *plugin = instance->descriptor; + + for (port = 0; port < plugin->PortCount; ++port) + { + if (LADSPA_IS_PORT_CONTROL(plugin->PortDescriptors[port])) + { + if (port < MAX_KNOBS) + { + plugin->connect_port(instance->handle, port, &(instance->knobs[port])); + if (instance->handle2) + plugin->connect_port(instance->handle2, port, &(instance->knobs[port])); + } + else + { + plugin->connect_port(instance->handle, port, m_trash); + if (instance->handle2) + plugin->connect_port(instance->handle2, port, m_trash); + } + + } + else if (LADSPA_IS_PORT_AUDIO(plugin->PortDescriptors[port])) + { + + if (LADSPA_IS_PORT_INPUT(plugin->PortDescriptors[port])) + { + if (inputs == 0) + { + plugin->connect_port(instance->handle, port, m_left); + if (instance->handle2) + plugin->connect_port(instance->handle2, port, m_right); + } + else if (inputs == 1 && instance->stereo) + { + plugin->connect_port(instance->handle, port, m_right); + } + else + { + plugin->connect_port(instance->handle, port, m_trash); + if (instance->handle2) + plugin->connect_port(instance->handle2, port, m_trash); + } + inputs++; + + } + else if (LADSPA_IS_PORT_OUTPUT(plugin->PortDescriptors[port])) + { + if (outputs == 0) + { + plugin->connect_port(instance->handle, port, m_left); + if (instance->handle2) + plugin->connect_port(instance->handle2, port, m_right); + } + else if (outputs == 1 && instance->stereo) + { + plugin->connect_port(instance->handle, port, m_right); + } + else + { + plugin->connect_port(instance->handle, port, m_trash); + if (instance->handle2) + plugin->connect_port(instance->handle2, port, m_trash); + } + outputs++; + } + } + } +} + +void LADSPAHost::findPlugins(const QString &path_entry) +{ + LADSPAPlugin *plugin; + void *library = 0; + LADSPA_Descriptor_Function descriptor_fn; + const LADSPA_Descriptor *descriptor; + long int k; + unsigned long int port, input, output; + + QDir dir (path_entry); + dir.setFilter(QDir::Files | QDir::Hidden); + dir.setSorting(QDir::Name); + QFileInfoList files = dir.entryInfoList((QStringList() << "*.so")); + + foreach(QFileInfo file, files) + { + library = dlopen(qPrintable(file.absoluteFilePath ()), RTLD_LAZY); + if (library == 0) + { + continue; + } + descriptor_fn = (LADSPA_Descriptor_Function) dlsym(library, "ladspa_descriptor"); + if (descriptor_fn == 0) + { + dlclose(library); + continue; + } + + for (k = 0;; ++k) + { + descriptor = descriptor_fn(k); + if (descriptor == 0) + { + break; + } + plugin = new LADSPAPlugin; + plugin->name = strdup(descriptor->Name); + plugin->fileName = file.absoluteFilePath (); + plugin->id = k; + plugin->unique_id = descriptor->UniqueID; + for (input = output = port = 0; port < descriptor->PortCount; ++port) + { + if (LADSPA_IS_PORT_AUDIO(descriptor->PortDescriptors[port])) + { + if (LADSPA_IS_PORT_INPUT(descriptor->PortDescriptors[port])) + input++; + if (LADSPA_IS_PORT_OUTPUT(descriptor->PortDescriptors[port])) + output++; + } + else if (LADSPA_IS_PORT_CONTROL(descriptor->PortDescriptors[port])) + { + } + } + plugin->stereo = (input >= 2 && output >= 2); + m_plugins.append(plugin); + } + dlclose(library); + } +} + +LADSPAEffect *LADSPAHost::addPlugin(LADSPAPlugin *plugin) +{ + if (!plugin) + return 0; + LADSPAEffect *instance; + if (!(instance = load(plugin->fileName, plugin->id))) + return 0; + instance->stereo = plugin->stereo; + if (channels() && sampleRate()) + bootPlugin(instance); + initialize(instance); + m_effects.append(instance); + return instance; +} + +void LADSPAHost::initialize(LADSPAEffect *instance) +{ + const LADSPA_Descriptor *plugin = instance->descriptor; + const LADSPA_PortRangeHint *hints = plugin->PortRangeHints; + LADSPA_Data fact, min, max, step, start; + int dp; + + for (unsigned long k = 0; k < MAX_KNOBS && k < plugin->PortCount; ++k) + { + if (!LADSPA_IS_PORT_CONTROL(plugin->PortDescriptors[k])) + continue; + + LADSPAControl *c = new LADSPAControl; + c->name = QString(plugin->PortNames[k]); + + if (LADSPA_IS_HINT_TOGGLED(hints[k].HintDescriptor)) + { + c->type = LADSPAControl::BUTTON; + c->min = 0; + c->max = 0; + c->step = 0; + c->value = &instance->knobs[k]; + instance->controls << c; + continue; + } + + if (LADSPA_IS_HINT_SAMPLE_RATE(hints[k].HintDescriptor)) + fact = sampleRate(); + else + fact = 1.0f; + + if (LADSPA_IS_HINT_BOUNDED_BELOW(hints[k].HintDescriptor)) + min = hints[k].LowerBound * fact; + else + min = -10000.0f; + + if (LADSPA_IS_HINT_BOUNDED_ABOVE(hints[k].HintDescriptor)) + max = hints[k].UpperBound * fact; + else + max = 10000.0f; + + /* infinity */ + if (10000.0f <= max - min) + { + dp = 1; + step = 5.0f; + + /* 100.0 ... lots */ + } + else if (100.0f < max - min) + { + dp = 0; + step = 5.0f; + + /* 10.0 ... 100.0 */ + } + else if (10.0f < max - min) + { + dp = 1; + step = 0.5f; + + /* 1.0 ... 10.0 */ + } + else if (1.0f < max - min) + { + dp = 2; + step = 0.05f; + + /* 0.0 ... 1.0 */ + } + else + { + dp = 3; + step = 0.005f; + } + + if (LADSPA_IS_HINT_INTEGER(hints[k].HintDescriptor)) + { + dp = 0; + if (step < 1.0f) + step = 1.0f; + } + + if (LADSPA_IS_HINT_DEFAULT_MINIMUM(hints[k].HintDescriptor)) + start = min; + else if (LADSPA_IS_HINT_DEFAULT_LOW(hints[k].HintDescriptor)) + start = min * 0.75f + max * 0.25f; + else if (LADSPA_IS_HINT_DEFAULT_MIDDLE(hints[k].HintDescriptor)) + start = min * 0.5f + max * 0.5f; + else if (LADSPA_IS_HINT_DEFAULT_HIGH(hints[k].HintDescriptor)) + start = min * 0.25f + max * 0.75f; + else if (LADSPA_IS_HINT_DEFAULT_MAXIMUM(hints[k].HintDescriptor)) + start = max; + else if (LADSPA_IS_HINT_DEFAULT_0(hints[k].HintDescriptor)) + start = 0.0f; + else if (LADSPA_IS_HINT_DEFAULT_1(hints[k].HintDescriptor)) + start = 1.0f; + else if (LADSPA_IS_HINT_DEFAULT_100(hints[k].HintDescriptor)) + start = 100.0f; + else if (LADSPA_IS_HINT_DEFAULT_440(hints[k].HintDescriptor)) + start = 440.0f; + else if (LADSPA_IS_HINT_INTEGER(hints[k].HintDescriptor)) + start = min; + else if (max >= 0.0f && min <= 0.0f) + start = 0.0f; + else + start = min * 0.5f + max * 0.5f; + + instance->knobs[k] = start; + c->type = LADSPAControl::SLIDER; + c->min = min; + c->max = max; + c->step = step; + c->value = &instance->knobs[k]; + instance->controls << c; + } +} diff --git a/src/plugins/Effect/ladspa/ladspahost.h b/src/plugins/Effect/ladspa/ladspahost.h new file mode 100644 index 000000000..c73d81ab3 --- /dev/null +++ b/src/plugins/Effect/ladspa/ladspahost.h @@ -0,0 +1,110 @@ +/*************************************************************************** + * Copyright (C) 2009 by Ilya Kotov * + * forkotov02@hotmail.ru * + * * + * 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. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef LADSPAHOST_H +#define LADSPAHOST_H + +#include +#include +#include +#include "ladspa.h" + +class QWidget; + +#define MAX_SAMPLES 8192 +#define MAX_KNOBS 64 + +/** + @author Ilya Kotov +*/ +class LADSPAPlugin +{ +public: + QString name; + QString fileName; + long id; + long unique_id; + bool stereo; +}; + +class LADSPAControl +{ +public: + enum Type + { + BUTTON = 0, + SLIDER + }; + double min; + double max; + double step; + LADSPA_Data *value; + bool type; + QString name; +}; + +class LADSPAEffect +{ +public: + void *library; + QString fileName; + bool stereo; + const LADSPA_Descriptor *descriptor; + LADSPA_Handle handle; /* left or mono */ + LADSPA_Handle handle2; /* right stereo */ + LADSPA_Data knobs[MAX_KNOBS]; + QList controls; +}; + + +class LADSPAHost : public Effect +{ +public: + LADSPAHost(); + + virtual ~LADSPAHost(); + + ulong process(char *in_data, const ulong size, char **out_data); + void configure(quint32 freq, int chan, int res); + QList plugins(); + QList runningPlugins(); + LADSPAEffect *addPlugin(LADSPAPlugin * plugin); + void unload(LADSPAEffect *instance); + + static LADSPAHost* instance(); + +private: + int applyEffect(qint16 *d, int length); + + void bootPlugin(LADSPAEffect *instance); + void findAllPlugins(); + void findPlugins(const QString &path); + LADSPAEffect *load(const QString &path, long num); + void portAssign(LADSPAEffect *instance); + void initialize(LADSPAEffect *instance); + + QList m_plugins; + QList m_effects; + + LADSPA_Data m_left[MAX_SAMPLES], m_right[MAX_SAMPLES], m_trash[MAX_SAMPLES]; + + static LADSPAHost *m_instance; +}; + +#endif diff --git a/src/plugins/Effect/ladspa/ladspaplugin.cpp b/src/plugins/Effect/ladspa/ladspaplugin.cpp deleted file mode 100644 index bef363397..000000000 --- a/src/plugins/Effect/ladspa/ladspaplugin.cpp +++ /dev/null @@ -1,487 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2009 by Ilya Kotov * - * * - * * - * 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. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include "ladspaplugin.h" - -#ifndef PATH_MAX -#define PATH_MAX 4096 -#endif - -#undef CLAMP -#define CLAMP(x, low, high) (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x))) - -LADSPAHost *LADSPAHost::m_instance = 0; - -LADSPAHost::LADSPAHost() : Effect() -{ - m_instance = this; - findAllPlugins(); -} - -LADSPAHost::~LADSPAHost() -{ - m_instance = 0; - foreach(LADSPAEffect *instance, m_effects) - { - unload(instance); - } -} - -ulong LADSPAHost::process(char *in_data, const ulong size, char **out_data) -{ - applyEffect((qint16 *) in_data, size); - memcpy(*out_data, in_data, size); - return size; -} - -void LADSPAHost::configure(quint32 freq, int chan, int res) -{ - Effect::configure(freq, chan, res); -} - -LADSPAHost* LADSPAHost::instance() -{ - return m_instance; -} - -QList LADSPAHost::plugins() -{ - return m_plugins; -} - -QList LADSPAHost::runningPlugins() -{ - return m_effects; -} - -/*!!!!*/ -void LADSPAHost::findAllPlugins() -{ - while(!m_plugins.isEmpty()) /* empty list */ - delete m_plugins.takeFirst(); - - QString ladspa_path = qgetenv("LADSPA_PATH"); - QStringList directories; - - if (ladspa_path.isEmpty()) - { - /* Fallback, look in obvious places */ - directories << "/usr/lib/ladspa"; - directories << "/usr/local/lib/ladspa"; - } - else - directories = ladspa_path.split(':'); - foreach(QString dir, directories) - findPlugins(dir); -} - -LADSPAEffect *LADSPAHost::load(const QString &filename, long int num) -{ - LADSPA_Descriptor_Function descriptor_fn; - LADSPAEffect *instance = new LADSPAEffect; - - instance->fileName = filename; - instance->library = dlopen(qPrintable(filename), RTLD_NOW); - instance->handle = 0; - instance->handle2 = 0; - if (!instance->library) - { - delete instance; - return 0; - } - descriptor_fn = (LADSPA_Descriptor_Function) dlsym(instance->library, "ladspa_descriptor"); - if (!descriptor_fn) - { - dlclose(instance->library); - delete instance; - return 0; - } - instance->descriptor = descriptor_fn(num); - - return instance; -} - -void LADSPAHost::unload(LADSPAEffect *instance) -{ - const LADSPA_Descriptor *descriptor = instance->descriptor; - - if (instance->handle) - { - if (descriptor->deactivate) - descriptor->deactivate(instance->handle); - descriptor->cleanup(instance->handle); - instance->handle = 0; - } - if (instance->handle2) - { - if (descriptor->deactivate) - descriptor->deactivate(instance->handle2); - descriptor->cleanup(instance->handle2); - instance->handle2 = 0; - } - - if (instance->library) - { - dlclose(instance->library); - instance->library = 0; - } - m_effects.removeAll(instance); - delete instance; -} - -void LADSPAHost::bootPlugin(LADSPAEffect *instance) -{ - const LADSPA_Descriptor *descriptor = instance->descriptor; - - instance->handle = descriptor->instantiate(descriptor, (int)sampleRate()); - if (channels() > 1 && !instance->stereo) - { - /* Create an additional instance */ - instance->handle2 = descriptor->instantiate(descriptor, (int)sampleRate()); - } - - portAssign(instance); - - if (descriptor->activate) - { - descriptor->activate(instance->handle); - if (instance->handle2) - descriptor->activate(instance->handle2); - } -} - -int LADSPAHost::applyEffect(qint16 *d, int length) -{ - qint16 *raw16 = d; - LADSPAEffect *instance; - int k; - int nch = channels(); - - if (m_effects.isEmpty()) - return length; - - if (nch == 1) - { - for (k = 0; k < length / 2; ++k) - m_left[k] = ((LADSPA_Data) raw16[k]) * (1.0f / 32768.0f); - foreach(instance, m_effects) - { - if (instance->handle) - instance->descriptor->run(instance->handle, length / 2); - } - for (k = 0; k < length / 2; ++k) - raw16[k] = CLAMP((int)(m_left[k] * 32768.0f), -32768, 32767); - } - else - { - for (k = 0; k < length / 2; k += 2) - { - m_left[k/2] = ((LADSPA_Data) raw16[k]) * (1.0f / 32768.0f); - m_right[(k+1)/2] = ((LADSPA_Data) raw16[k+1]) * (1.0f / 32768.0f); - } - foreach(instance, m_effects) - { - if (instance->handle) - instance->descriptor->run(instance->handle, length/4); - if (instance->handle2) - instance->descriptor->run(instance->handle2, length/4); - } - for (k = 0; k < length / 2; k += 2) - { - raw16[k] = CLAMP((int)(m_left[k/2] * 32768.0f), -32768, 32767); - raw16[k+1] = CLAMP((int)(m_right[(k+1)/2] * 32768.0f), -32768, 32767); - - } - } - return length; -} - -void LADSPAHost::portAssign(LADSPAEffect *instance) -{ - unsigned long port; - unsigned long inputs = 0, outputs = 0; - const LADSPA_Descriptor *plugin = instance->descriptor; - - for (port = 0; port < plugin->PortCount; ++port) - { - if (LADSPA_IS_PORT_CONTROL(plugin->PortDescriptors[port])) - { - if (port < MAX_KNOBS) - { - plugin->connect_port(instance->handle, port, &(instance->knobs[port])); - if (instance->handle2) - plugin->connect_port(instance->handle2, port, &(instance->knobs[port])); - } - else - { - plugin->connect_port(instance->handle, port, m_trash); - if (instance->handle2) - plugin->connect_port(instance->handle2, port, m_trash); - } - - } - else if (LADSPA_IS_PORT_AUDIO(plugin->PortDescriptors[port])) - { - - if (LADSPA_IS_PORT_INPUT(plugin->PortDescriptors[port])) - { - if (inputs == 0) - { - plugin->connect_port(instance->handle, port, m_left); - if (instance->handle2) - plugin->connect_port(instance->handle2, port, m_right); - } - else if (inputs == 1 && instance->stereo) - { - plugin->connect_port(instance->handle, port, m_right); - } - else - { - plugin->connect_port(instance->handle, port, m_trash); - if (instance->handle2) - plugin->connect_port(instance->handle2, port, m_trash); - } - inputs++; - - } - else if (LADSPA_IS_PORT_OUTPUT(plugin->PortDescriptors[port])) - { - if (outputs == 0) - { - plugin->connect_port(instance->handle, port, m_left); - if (instance->handle2) - plugin->connect_port(instance->handle2, port, m_right); - } - else if (outputs == 1 && instance->stereo) - { - plugin->connect_port(instance->handle, port, m_right); - } - else - { - plugin->connect_port(instance->handle, port, m_trash); - if (instance->handle2) - plugin->connect_port(instance->handle2, port, m_trash); - } - outputs++; - } - } - } -} - -void LADSPAHost::findPlugins(const QString &path_entry) -{ - LADSPAPlugin *plugin; - void *library = 0; - LADSPA_Descriptor_Function descriptor_fn; - const LADSPA_Descriptor *descriptor; - long int k; - unsigned long int port, input, output; - - QDir dir (path_entry); - dir.setFilter(QDir::Files | QDir::Hidden); - dir.setSorting(QDir::Name); - QFileInfoList files = dir.entryInfoList((QStringList() << "*.so")); - - foreach(QFileInfo file, files) - { - library = dlopen(qPrintable(file.absoluteFilePath ()), RTLD_LAZY); - if (library == 0) - { - continue; - } - descriptor_fn = (LADSPA_Descriptor_Function) dlsym(library, "ladspa_descriptor"); - if (descriptor_fn == 0) - { - dlclose(library); - continue; - } - - for (k = 0;; ++k) - { - descriptor = descriptor_fn(k); - if (descriptor == 0) - { - break; - } - plugin = new LADSPAPlugin; - plugin->name = strdup(descriptor->Name); - plugin->fileName = file.absoluteFilePath (); - plugin->id = k; - plugin->unique_id = descriptor->UniqueID; - for (input = output = port = 0; port < descriptor->PortCount; ++port) - { - if (LADSPA_IS_PORT_AUDIO(descriptor->PortDescriptors[port])) - { - if (LADSPA_IS_PORT_INPUT(descriptor->PortDescriptors[port])) - input++; - if (LADSPA_IS_PORT_OUTPUT(descriptor->PortDescriptors[port])) - output++; - } - else if (LADSPA_IS_PORT_CONTROL(descriptor->PortDescriptors[port])) - { - } - } - plugin->stereo = (input >= 2 && output >= 2); - m_plugins.append(plugin); - } - dlclose(library); - } -} - -LADSPAEffect *LADSPAHost::addPlugin(LADSPAPlugin *plugin) -{ - if (!plugin) - return 0; - LADSPAEffect *instance; - if (!(instance = load(plugin->fileName, plugin->id))) - return 0; - instance->stereo = plugin->stereo; - if (channels() && sampleRate()) - bootPlugin(instance); - initialize(instance); - m_effects.append(instance); - return instance; -} - -void LADSPAHost::initialize(LADSPAEffect *instance) -{ - const LADSPA_Descriptor *plugin = instance->descriptor; - const LADSPA_PortRangeHint *hints = plugin->PortRangeHints; - LADSPA_Data fact, min, max, step, start; - int dp; - - for (unsigned long k = 0; k < MAX_KNOBS && k < plugin->PortCount; ++k) - { - if (!LADSPA_IS_PORT_CONTROL(plugin->PortDescriptors[k])) - continue; - - LADSPAControl *c = new LADSPAControl; - c->name = QString(plugin->PortNames[k]); - - if (LADSPA_IS_HINT_TOGGLED(hints[k].HintDescriptor)) - { - c->type = LADSPAControl::BUTTON; - c->min = 0; - c->max = 0; - c->step = 0; - c->value = &instance->knobs[k]; - instance->controls << c; - continue; - } - - if (LADSPA_IS_HINT_SAMPLE_RATE(hints[k].HintDescriptor)) - fact = sampleRate(); - else - fact = 1.0f; - - if (LADSPA_IS_HINT_BOUNDED_BELOW(hints[k].HintDescriptor)) - min = hints[k].LowerBound * fact; - else - min = -10000.0f; - - if (LADSPA_IS_HINT_BOUNDED_ABOVE(hints[k].HintDescriptor)) - max = hints[k].UpperBound * fact; - else - max = 10000.0f; - - /* infinity */ - if (10000.0f <= max - min) - { - dp = 1; - step = 5.0f; - - /* 100.0 ... lots */ - } - else if (100.0f < max - min) - { - dp = 0; - step = 5.0f; - - /* 10.0 ... 100.0 */ - } - else if (10.0f < max - min) - { - dp = 1; - step = 0.5f; - - /* 1.0 ... 10.0 */ - } - else if (1.0f < max - min) - { - dp = 2; - step = 0.05f; - - /* 0.0 ... 1.0 */ - } - else - { - dp = 3; - step = 0.005f; - } - - if (LADSPA_IS_HINT_INTEGER(hints[k].HintDescriptor)) - { - dp = 0; - if (step < 1.0f) - step = 1.0f; - } - - if (LADSPA_IS_HINT_DEFAULT_MINIMUM(hints[k].HintDescriptor)) - start = min; - else if (LADSPA_IS_HINT_DEFAULT_LOW(hints[k].HintDescriptor)) - start = min * 0.75f + max * 0.25f; - else if (LADSPA_IS_HINT_DEFAULT_MIDDLE(hints[k].HintDescriptor)) - start = min * 0.5f + max * 0.5f; - else if (LADSPA_IS_HINT_DEFAULT_HIGH(hints[k].HintDescriptor)) - start = min * 0.25f + max * 0.75f; - else if (LADSPA_IS_HINT_DEFAULT_MAXIMUM(hints[k].HintDescriptor)) - start = max; - else if (LADSPA_IS_HINT_DEFAULT_0(hints[k].HintDescriptor)) - start = 0.0f; - else if (LADSPA_IS_HINT_DEFAULT_1(hints[k].HintDescriptor)) - start = 1.0f; - else if (LADSPA_IS_HINT_DEFAULT_100(hints[k].HintDescriptor)) - start = 100.0f; - else if (LADSPA_IS_HINT_DEFAULT_440(hints[k].HintDescriptor)) - start = 440.0f; - else if (LADSPA_IS_HINT_INTEGER(hints[k].HintDescriptor)) - start = min; - else if (max >= 0.0f && min <= 0.0f) - start = 0.0f; - else - start = min * 0.5f + max * 0.5f; - - instance->knobs[k] = start; - c->type = LADSPAControl::SLIDER; - c->min = min; - c->max = max; - c->step = step; - c->value = &instance->knobs[k]; - instance->controls << c; - } -} diff --git a/src/plugins/Effect/ladspa/ladspaplugin.h b/src/plugins/Effect/ladspa/ladspaplugin.h deleted file mode 100644 index fa9b0200e..000000000 --- a/src/plugins/Effect/ladspa/ladspaplugin.h +++ /dev/null @@ -1,112 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2009 by Ilya Kotov * - * forkotov02@hotmail.ru * - * * - * 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. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#ifndef LADSPAPLUGIN_H -#define LADSPAPLUGIN_H - -#include -#include -#include -#include - -class QWidget; - -/** - @author Ilya Kotov -*/ - -#define MAX_SAMPLES 8192 -#define MAX_KNOBS 64 - - -class LADSPAPlugin -{ -public: - QString name; - QString fileName; - long id; - long unique_id; - bool stereo; -}; - -class LADSPAControl -{ -public: - enum Type - { - BUTTON = 0, - SLIDER - }; - double min; - double max; - double step; - LADSPA_Data *value; - bool type; - QString name; -}; - -class LADSPAEffect -{ -public: - void *library; - QString fileName; - bool stereo; - const LADSPA_Descriptor *descriptor; - LADSPA_Handle handle; /* left or mono */ - LADSPA_Handle handle2; /* right stereo */ - LADSPA_Data knobs[MAX_KNOBS]; - QList controls; -}; - - -class LADSPAHost : public Effect -{ -public: - LADSPAHost(); - - virtual ~LADSPAHost(); - - ulong process(char *in_data, const ulong size, char **out_data); - void configure(quint32 freq, int chan, int res); - QList plugins(); - QList runningPlugins(); - LADSPAEffect *addPlugin(LADSPAPlugin * plugin); - void unload(LADSPAEffect *instance); - - static LADSPAHost* instance(); - -private: - int applyEffect(qint16 *d, int length); - - void bootPlugin(LADSPAEffect *instance); - void findAllPlugins(); - void findPlugins(const QString &path); - LADSPAEffect *load(const QString &path, long num); - void portAssign(LADSPAEffect *instance); - void initialize(LADSPAEffect *instance); - - QList m_plugins; - QList m_effects; - - LADSPA_Data m_left[MAX_SAMPLES], m_right[MAX_SAMPLES], m_trash[MAX_SAMPLES]; - - static LADSPAHost *m_instance; -}; - -#endif diff --git a/src/plugins/Effect/ladspa/ladspaslider.cpp b/src/plugins/Effect/ladspa/ladspaslider.cpp index 067a3d5ab..87e3c01f2 100644 --- a/src/plugins/Effect/ladspa/ladspaslider.cpp +++ b/src/plugins/Effect/ladspa/ladspaslider.cpp @@ -22,7 +22,7 @@ #include #include #include -#include "ladspaplugin.h" +#include "ladspahost.h" #include "ladspaslider.h" LADSPASlider::LADSPASlider(double min, double max, double step, LADSPA_Data *value, diff --git a/src/plugins/Effect/ladspa/ladspaslider.h b/src/plugins/Effect/ladspa/ladspaslider.h index c0863b902..a7290581a 100644 --- a/src/plugins/Effect/ladspa/ladspaslider.h +++ b/src/plugins/Effect/ladspa/ladspaslider.h @@ -21,7 +21,7 @@ #define LADSPASLIDER_H #include -#include +#include "ladspa.h" class QDoubleSpinBox; class QSlider; diff --git a/src/plugins/Effect/ladspa/settingsdialog.cpp b/src/plugins/Effect/ladspa/settingsdialog.cpp index e4d78a698..b91fbb2d7 100644 --- a/src/plugins/Effect/ladspa/settingsdialog.cpp +++ b/src/plugins/Effect/ladspa/settingsdialog.cpp @@ -27,7 +27,7 @@ #include #include #include "ladspaslider.h" -#include "ladspaplugin.h" +#include "ladspahost.h" #include "settingsdialog.h" SettingsDialog::SettingsDialog(QWidget *parent) @@ -59,6 +59,8 @@ SettingsDialog::SettingsDialog(QWidget *parent) m_model->setData(m_model->index(i, 0), (uint) plugin_list[i]->unique_id); m_model->setData(m_model->index(i, 1), plugin_list[i]->name); } + ui.pluginsTreeView->resizeColumnToContents (0); + ui.pluginsTreeView->resizeColumnToContents (1); updateRunningPlugins(); } diff --git a/src/plugins/Effect/ladspa/settingsdialog.ui b/src/plugins/Effect/ladspa/settingsdialog.ui index c47d52a5f..8c1653224 100644 --- a/src/plugins/Effect/ladspa/settingsdialog.ui +++ b/src/plugins/Effect/ladspa/settingsdialog.ui @@ -11,7 +11,7 @@ - BS2B Plugin Settings + LADSPA Host Catalog -- cgit v1.2.3-13-gbd6f