diff options
Diffstat (limited to 'attic/muse2-oom/muse2/muse/plugin.cpp')
-rw-r--r-- | attic/muse2-oom/muse2/muse/plugin.cpp | 3880 |
1 files changed, 0 insertions, 3880 deletions
diff --git a/attic/muse2-oom/muse2/muse/plugin.cpp b/attic/muse2-oom/muse2/muse/plugin.cpp deleted file mode 100644 index 5bacf092..00000000 --- a/attic/muse2-oom/muse2/muse/plugin.cpp +++ /dev/null @@ -1,3880 +0,0 @@ -//========================================================= -// MusE -// Linux Music Editor -// $Id: plugin.cpp,v 1.21.2.23 2009/12/15 22:07:12 spamatica Exp $ -// -// (C) Copyright 2000 Werner Schweer (ws@seh.de) -//========================================================= - -#include <stdio.h> -#include <stdlib.h> -#include <dlfcn.h> -#include <cmath> -#include <math.h> - -#include <QButtonGroup> -#include <QCheckBox> -#include <QComboBox> -#include <QDir> -#include <QFile> -#include <QGridLayout> -#include <QGroupBox> -#include <QHBoxLayout> -#include <QLabel> -#include <QMainWindow> -#include <QMessageBox> -#include <QPushButton> -#include <QRadioButton> -#include <QSignalMapper> -#include <QSizePolicy> -#include <QScrollArea> -#include <QTimer> -#include <QToolBar> -#include <QToolButton> -#include <QTreeWidget> -#include <QVBoxLayout> -#include <QWhatsThis> - -#include "globals.h" -#include "gconfig.h" -#include "filedialog.h" -#include "slider.h" -#include "midictrl.h" -#include "plugin.h" -#include "xml.h" -#include "icons.h" -#include "song.h" -#include "doublelabel.h" -#include "fastlog.h" -#include "checkbox.h" - -#include "audio.h" -#include "al/dsp.h" - -#include "config.h" - -// Turn on debugging messages. -//#define PLUGIN_DEBUGIN - -PluginList plugins; - -/* -static const char* preset_file_pattern[] = { - QT_TRANSLATE_NOOP("@default", "Presets (*.pre *.pre.gz *.pre.bz2)"), - QT_TRANSLATE_NOOP("@default", "All Files (*)"), - 0 - }; - -static const char* preset_file_save_pattern[] = { - QT_TRANSLATE_NOOP("@default", "Presets (*.pre)"), - QT_TRANSLATE_NOOP("@default", "gzip compressed presets (*.pre.gz)"), - QT_TRANSLATE_NOOP("@default", "bzip2 compressed presets (*.pre.bz2)"), - QT_TRANSLATE_NOOP("@default", "All Files (*)"), - 0 - }; -*/ - -int PluginDialog::selectedPlugType = 0; -QStringList PluginDialog::sortItems = QStringList(); - -//--------------------------------------------------------- -// ladspa2MidiControlValues -//--------------------------------------------------------- - -bool ladspa2MidiControlValues(const LADSPA_Descriptor* plugin, int port, int ctlnum, int* min, int* max, int* def) -{ - LADSPA_PortRangeHint range = plugin->PortRangeHints[port]; - LADSPA_PortRangeHintDescriptor desc = range.HintDescriptor; - - float fmin, fmax, fdef; - int imin, imax; - float frng; - //int idef; - - //ladspaControlRange(plugin, port, &fmin, &fmax); - - bool hasdef = ladspaDefaultValue(plugin, port, &fdef); - //bool isint = desc & LADSPA_HINT_INTEGER; - MidiController::ControllerType t = midiControllerType(ctlnum); - - #ifdef PLUGIN_DEBUGIN - printf("ladspa2MidiControlValues: ctlnum:%d ladspa port:%d has default?:%d default:%f\n", ctlnum, port, hasdef, fdef); - #endif - - if(desc & LADSPA_HINT_TOGGLED) - { - #ifdef PLUGIN_DEBUGIN - printf("ladspa2MidiControlValues: has LADSPA_HINT_TOGGLED\n"); - #endif - - *min = 0; - *max = 1; - *def = (int)lrint(fdef); - return hasdef; - } - - float m = 1.0; - if(desc & LADSPA_HINT_SAMPLE_RATE) - { - #ifdef PLUGIN_DEBUGIN - printf("ladspa2MidiControlValues: has LADSPA_HINT_SAMPLE_RATE\n"); - #endif - - m = float(sampleRate); - } - - if(desc & LADSPA_HINT_BOUNDED_BELOW) - { - #ifdef PLUGIN_DEBUGIN - printf("ladspa2MidiControlValues: has LADSPA_HINT_BOUNDED_BELOW\n"); - #endif - - fmin = range.LowerBound * m; - } - else - fmin = 0.0; - - if(desc & LADSPA_HINT_BOUNDED_ABOVE) - { - #ifdef PLUGIN_DEBUGIN - printf("ladspa2MidiControlValues: has LADSPA_HINT_BOUNDED_ABOVE\n"); - #endif - - fmax = range.UpperBound * m; - } - else - fmax = 1.0; - - frng = fmax - fmin; - imin = lrint(fmin); - imax = lrint(fmax); - //irng = imax - imin; - - int ctlmn = 0; - int ctlmx = 127; - - #ifdef PLUGIN_DEBUGIN - printf("ladspa2MidiControlValues: port min:%f max:%f \n", fmin, fmax); - #endif - - //bool isneg = (fmin < 0.0); - bool isneg = (imin < 0); - int bias = 0; - switch(t) - { - case MidiController::RPN: - case MidiController::NRPN: - case MidiController::Controller7: - if(isneg) - { - ctlmn = -64; - ctlmx = 63; - bias = -64; - } - else - { - ctlmn = 0; - ctlmx = 127; - } - break; - case MidiController::Controller14: - case MidiController::RPN14: - case MidiController::NRPN14: - if(isneg) - { - ctlmn = -8192; - ctlmx = 8191; - bias = -8192; - } - else - { - ctlmn = 0; - ctlmx = 16383; - } - break; - case MidiController::Program: - ctlmn = 0; - //ctlmx = 0xffffff; - ctlmx = 0x3fff; // FIXME: Really should not happen or be allowed. What to do here... - break; - case MidiController::Pitch: - ctlmn = -8192; - ctlmx = 8191; - break; - case MidiController::Velo: // cannot happen - default: - break; - } - //int ctlrng = ctlmx - ctlmn; - float fctlrng = float(ctlmx - ctlmn); - - // Is it an integer control? - if(desc & LADSPA_HINT_INTEGER) - { - #ifdef PLUGIN_DEBUGIN - printf("ladspa2MidiControlValues: has LADSPA_HINT_INTEGER\n"); - #endif - - // If the upper or lower limit is beyond the controller limits, just scale the whole range to fit. - // We could get fancy by scaling only the negative or positive domain, or each one separately, but no... - //if((imin < ctlmn) || (imax > ctlmx)) - //{ - // float scl = float(irng) / float(fctlrng); - // if((ctlmn - imin) > (ctlmx - imax)) - // scl = float(ctlmn - imin); - // else - // scl = float(ctlmx - imax); - //} - // No, instead just clip the limits. ie fit the range into clipped space. - if(imin < ctlmn) - imin = ctlmn; - if(imax > ctlmx) - imax = ctlmx; - - *min = imin; - *max = imax; - - //int idef = (int)lrint(fdef); - //if(idef < ctlmn) - // idef = ctlmn; - //if(idef > ctlmx) - // idef = ctlmx; - //*def = idef; - - *def = (int)lrint(fdef); - - return hasdef; - } - - // It's a floating point control, just use wide open maximum range. - *min = ctlmn; - *max = ctlmx; - - // Orcan: commented out next 2 lines to suppress compiler warning: - //float fbias = (fmin + fmax) / 2.0; - //float normbias = fbias / frng; - float normdef = fdef / frng; - fdef = normdef * fctlrng; - - // FIXME: TODO: Incorrect... Fix this somewhat more trivial stuff later.... - - *def = (int)lrint(fdef) + bias; - - #ifdef PLUGIN_DEBUGIN - printf("ladspa2MidiControlValues: setting default:%d\n", *def); - #endif - - return hasdef; -} - -//--------------------------------------------------------- -// midi2LadspaValue -//--------------------------------------------------------- - -float midi2LadspaValue(const LADSPA_Descriptor* plugin, int port, int ctlnum, int val) -{ - LADSPA_PortRangeHint range = plugin->PortRangeHints[port]; - LADSPA_PortRangeHintDescriptor desc = range.HintDescriptor; - - float fmin, fmax; - int imin; - //int imax; - float frng; - //int idef; - - //ladspaControlRange(plugin, port, &fmin, &fmax); - - //bool hasdef = ladspaDefaultValue(plugin, port, &fdef); - //bool isint = desc & LADSPA_HINT_INTEGER; - MidiController::ControllerType t = midiControllerType(ctlnum); - - #ifdef PLUGIN_DEBUGIN - printf("midi2LadspaValue: ctlnum:%d ladspa port:%d val:%d\n", ctlnum, port, val); - #endif - - float m = 1.0; - if(desc & LADSPA_HINT_SAMPLE_RATE) - { - #ifdef PLUGIN_DEBUGIN - printf("midi2LadspaValue: has LADSPA_HINT_SAMPLE_RATE\n"); - #endif - - m = float(sampleRate); - } - - if(desc & LADSPA_HINT_BOUNDED_BELOW) - { - #ifdef PLUGIN_DEBUGIN - printf("midi2LadspaValue: has LADSPA_HINT_BOUNDED_BELOW\n"); - #endif - - fmin = range.LowerBound * m; - } - else - fmin = 0.0; - - if(desc & LADSPA_HINT_BOUNDED_ABOVE) - { - #ifdef PLUGIN_DEBUGIN - printf("midi2LadspaValue: has LADSPA_HINT_BOUNDED_ABOVE\n"); - #endif - - fmax = range.UpperBound * m; - } - else - fmax = 1.0; - - frng = fmax - fmin; - imin = lrint(fmin); - //imax = lrint(fmax); - //irng = imax - imin; - - if(desc & LADSPA_HINT_TOGGLED) - { - #ifdef PLUGIN_DEBUGIN - printf("midi2LadspaValue: has LADSPA_HINT_TOGGLED\n"); - #endif - - if(val > 0) - return fmax; - else - return fmin; - } - - int ctlmn = 0; - int ctlmx = 127; - - #ifdef PLUGIN_DEBUGIN - printf("midi2LadspaValue: port min:%f max:%f \n", fmin, fmax); - #endif - - //bool isneg = (fmin < 0.0); - bool isneg = (imin < 0); - int bval = val; - int cval = val; - switch(t) - { - case MidiController::RPN: - case MidiController::NRPN: - case MidiController::Controller7: - if(isneg) - { - ctlmn = -64; - ctlmx = 63; - bval -= 64; - cval -= 64; - } - else - { - ctlmn = 0; - ctlmx = 127; - cval -= 64; - } - break; - case MidiController::Controller14: - case MidiController::RPN14: - case MidiController::NRPN14: - if(isneg) - { - ctlmn = -8192; - ctlmx = 8191; - bval -= 8192; - cval -= 8192; - } - else - { - ctlmn = 0; - ctlmx = 16383; - cval -= 8192; - } - break; - case MidiController::Program: - ctlmn = 0; - ctlmx = 0xffffff; - break; - case MidiController::Pitch: - ctlmn = -8192; - ctlmx = 8191; - break; - case MidiController::Velo: // cannot happen - default: - break; - } - int ctlrng = ctlmx - ctlmn; - float fctlrng = float(ctlmx - ctlmn); - - // Is it an integer control? - if(desc & LADSPA_HINT_INTEGER) - { - float ret = float(cval); - if(ret < fmin) - ret = fmin; - if(ret > fmax) - ret = fmax; - #ifdef PLUGIN_DEBUGIN - printf("midi2LadspaValue: has LADSPA_HINT_INTEGER returning:%f\n", ret); - #endif - - return ret; - } - - // Avoid divide-by-zero error below. - if(ctlrng == 0) - return 0.0; - - // It's a floating point control, just use wide open maximum range. - float normval = float(bval) / fctlrng; - //float fbias = (fmin + fmax) / 2.0; - //float normfbias = fbias / frng; - //float ret = (normdef + normbias) * fctlrng; - //float normdef = fdef / frng; - - float ret = normval * frng + fmin; - - #ifdef PLUGIN_DEBUGIN - printf("midi2LadspaValue: float returning:%f\n", ret); - #endif - - return ret; -} - - -// Works but not needed. -/* -//--------------------------------------------------------- -// ladspa2MidiController -//--------------------------------------------------------- - -MidiController* ladspa2MidiController(const LADSPA_Descriptor* plugin, int port, int ctlnum) -{ - int min, max, def; - - if(!ladspa2MidiControlValues(plugin, port, ctlnum, &min, &max, &def)) - return 0; - - MidiController* mc = new MidiController(QString(plugin->PortNames[port]), ctlnum, min, max, def); - - return mc; -} -*/ - -//---------------------------------------------------------------------------------- -// defaultValue -// If no default ladspa value found, still sets *def to 1.0, but returns false. -//--------------------------------------------------------------------------------- - -//float ladspaDefaultValue(const LADSPA_Descriptor* plugin, int k) -bool ladspaDefaultValue(const LADSPA_Descriptor* plugin, int port, float* val) -{ - LADSPA_PortRangeHint range = plugin->PortRangeHints[port]; - LADSPA_PortRangeHintDescriptor rh = range.HintDescriptor; -// bool isLog = LADSPA_IS_HINT_LOGARITHMIC(rh); - //double val = 1.0; - float m = (rh & LADSPA_HINT_SAMPLE_RATE) ? float(sampleRate) : 1.0f; - if (LADSPA_IS_HINT_DEFAULT_MINIMUM(rh)) - { - *val = range.LowerBound * m; - return true; - } - else if (LADSPA_IS_HINT_DEFAULT_LOW(rh)) - { - if (LADSPA_IS_HINT_LOGARITHMIC(rh)) - { - *val = exp(fast_log10(range.LowerBound * m) * .75 + - log(range.UpperBound * m) * .25); - return true; - } - else - { - *val = range.LowerBound*.75*m + range.UpperBound*.25*m; - return true; - } - } - else if (LADSPA_IS_HINT_DEFAULT_MIDDLE(rh)) - { - if (LADSPA_IS_HINT_LOGARITHMIC(rh)) - { - *val = exp(log(range.LowerBound * m) * .5 + - log10(range.UpperBound * m) * .5); - return true; - } - else - { - *val = range.LowerBound*.5*m + range.UpperBound*.5*m; - return true; - } - } - else if (LADSPA_IS_HINT_DEFAULT_HIGH(rh)) - { - if (LADSPA_IS_HINT_LOGARITHMIC(rh)) - { - *val = exp(log(range.LowerBound * m) * .25 + - log(range.UpperBound * m) * .75); - return true; - } - else - { - *val = range.LowerBound*.25*m + range.UpperBound*.75*m; - return true; - } - } - else if (LADSPA_IS_HINT_DEFAULT_MAXIMUM(rh)) - { - *val = range.UpperBound*m; - return true; - } - else if (LADSPA_IS_HINT_DEFAULT_0(rh)) - { - *val = 0.0; - return true; - } - else if (LADSPA_IS_HINT_DEFAULT_1(rh)) - { - *val = 1.0; - return true; - } - else if (LADSPA_IS_HINT_DEFAULT_100(rh)) - { - *val = 100.0; - return true; - } - else if (LADSPA_IS_HINT_DEFAULT_440(rh)) - { - *val = 440.0; - return true; - } - - // No default found. Set return value to 1.0, but return false. - *val = 1.0; - return false; -} - -//--------------------------------------------------------- -// ladspaControlRange -//--------------------------------------------------------- - -void ladspaControlRange(const LADSPA_Descriptor* plugin, int i, float* min, float* max) - { - 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(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; - } - -//--------------------------------------------------------- -// Plugin -//--------------------------------------------------------- - -Plugin::Plugin(QFileInfo* f, const LADSPA_Descriptor* d, bool isDssi) -{ - _isDssi = isDssi; - #ifdef DSSI_SUPPORT - dssi_descr = NULL; - #endif - - fi = *f; - plugin = NULL; - ladspa = NULL; - _handle = 0; - _references = 0; - _instNo = 0; - _label = QString(d->Label); - _name = QString(d->Name); - _uniqueID = d->UniqueID; - _maker = QString(d->Maker); - _copyright = QString(d->Copyright); - - _portCount = d->PortCount; - //_portDescriptors = 0; - //if(_portCount) - // _portDescriptors = new LADSPA_PortDescriptor[_portCount]; - - - _inports = 0; - _outports = 0; - _controlInPorts = 0; - _controlOutPorts = 0; - for(unsigned long k = 0; k < _portCount; ++k) - { - LADSPA_PortDescriptor pd = d->PortDescriptors[k]; - //_portDescriptors[k] = pd; - if(pd & LADSPA_PORT_AUDIO) - { - if(pd & LADSPA_PORT_INPUT) - ++_inports; - else - if(pd & LADSPA_PORT_OUTPUT) - ++_outports; - } - else - if(pd & LADSPA_PORT_CONTROL) - { - if(pd & LADSPA_PORT_INPUT) - ++_controlInPorts; - else - if(pd & LADSPA_PORT_OUTPUT) - ++_controlOutPorts; - } - } - - _inPlaceCapable = !LADSPA_IS_INPLACE_BROKEN(d->Properties); - - // By T356. Blacklist vst plugins in-place configurable for now. At one point they - // were working with in-place here, but not now, and RJ also reported they weren't working. - // Fixes problem with vst plugins not working or feeding back loudly. - // I can only think of two things that made them stop working: - // 1): I switched back from Jack-2 to Jack-1 - // 2): I changed winecfg audio to use Jack instead of ALSA. - // Will test later... - // Possibly the first one because under Mandriva2007.1 (Jack-1), no matter how hard I tried, - // the same problem existed. It may have been when using Jack-2 with Mandriva2009 that they worked. - // Apparently the plugins are lying about their in-place capability. - // Quote: - /* Property LADSPA_PROPERTY_INPLACE_BROKEN indicates that the plugin - may cease to work correctly if the host elects to use the same data - location for both input and output (see connect_port()). This - should be avoided as enabling this flag makes it impossible for - hosts to use the plugin to process audio `in-place.' */ - // Examination of all my ladspa and vst synths and effects plugins showed only one - - // EnsembleLite (EnsLite VST) has the flag set, but it is a vst synth and is not involved here! - // Yet many (all?) ladspa vst effect plugins exhibit this problem. - // Changed by Tim. p3.3.14 - if ((_inports != _outports) || (fi.completeBaseName() == QString("dssi-vst") && !config.vstInPlace)) - _inPlaceCapable = false; -} - -Plugin::~Plugin() -{ - //if(_portDescriptors) - // delete[] _portDescriptors; -} - -//--------------------------------------------------------- -// incReferences -//--------------------------------------------------------- - -int Plugin::incReferences(int val) -{ - #ifdef PLUGIN_DEBUGIN - fprintf(stderr, "Plugin::incReferences _references:%d val:%d\n", _references, val); - #endif - - int newref = _references + val; - - if(newref == 0) - { - _references = 0; - if(_handle) - { - #ifdef PLUGIN_DEBUGIN - fprintf(stderr, "Plugin::incReferences no more instances, closing library\n"); - #endif - - dlclose(_handle); - } - - _handle = 0; - ladspa = NULL; - plugin = NULL; - rpIdx.clear(); - - #ifdef DSSI_SUPPORT - dssi_descr = NULL; - #endif - - return 0; - } - - //if(_references == 0) - if(_handle == 0) - { - //_references = 0; - _handle = dlopen(fi.filePath().toLatin1().constData(), RTLD_NOW); - //handle = dlopen(fi.absFilePath().toLatin1().constData(), RTLD_NOW); - - if(_handle == 0) - { - fprintf(stderr, "Plugin::incReferences dlopen(%s) failed: %s\n", - fi.filePath().toLatin1().constData(), dlerror()); - //fi.absFilePath().toLatin1().constData(), dlerror()); - return 0; - } - - #ifdef DSSI_SUPPORT - DSSI_Descriptor_Function dssi = (DSSI_Descriptor_Function)dlsym(_handle, "dssi_descriptor"); - if(dssi) - { - const DSSI_Descriptor* descr; - for(int i = 0;; ++i) - { - descr = dssi(i); - if(descr == NULL) - break; - - QString label(descr->LADSPA_Plugin->Label); - // Listing effect plugins only while excluding synths: - // Do exactly what dssi-vst.cpp does for listing ladspa plugins. - //if(label == _name && - if(label == _label && - !descr->run_synth && - !descr->run_synth_adding && - !descr->run_multiple_synths && - !descr->run_multiple_synths_adding) - { - _isDssi = true; - ladspa = NULL; - dssi_descr = descr; - plugin = descr->LADSPA_Plugin; - break; - } - } - } - else - #endif // DSSI_SUPPORT - { - LADSPA_Descriptor_Function ladspadf = (LADSPA_Descriptor_Function)dlsym(_handle, "ladspa_descriptor"); - if(ladspadf) - { - const LADSPA_Descriptor* descr; - for(int i = 0;; ++i) - { - descr = ladspadf(i); - if(descr == NULL) - break; - - QString label(descr->Label); - //if(label == _name) - if(label == _label) - { - _isDssi = false; - ladspa = ladspadf; - plugin = descr; - - #ifdef DSSI_SUPPORT - dssi_descr = NULL; - #endif - - break; - } - } - } - } - - if(plugin != NULL) - { - //_instNo = 0; - _name = QString(plugin->Name); - _uniqueID = plugin->UniqueID; - _maker = QString(plugin->Maker); - _copyright = QString(plugin->Copyright); - - //if(_portDescriptors) - // delete[] _portDescriptors; - //_portDescriptors = 0; - _portCount = plugin->PortCount; - //if(_portCount) - // _portDescriptors = new LADSPA_PortDescriptor[_portCount]; - - _inports = 0; - _outports = 0; - _controlInPorts = 0; - _controlOutPorts = 0; - for(unsigned long k = 0; k < _portCount; ++k) - { - LADSPA_PortDescriptor pd = plugin->PortDescriptors[k]; - //_portDescriptors[k] = pd; - if(pd & LADSPA_PORT_AUDIO) - { - if(pd & LADSPA_PORT_INPUT) - ++_inports; - else - if(pd & LADSPA_PORT_OUTPUT) - ++_outports; - - rpIdx.push_back((unsigned long)-1); - } - else - if(pd & LADSPA_PORT_CONTROL) - { - if(pd & LADSPA_PORT_INPUT) - { - rpIdx.push_back(_controlInPorts); - ++_controlInPorts; - } - else - if(pd & LADSPA_PORT_OUTPUT) - { - rpIdx.push_back((unsigned long)-1); - ++_controlOutPorts; - } - } - } - - _inPlaceCapable = !LADSPA_IS_INPLACE_BROKEN(plugin->Properties); - - // Blacklist vst plugins in-place configurable for now. - if ((_inports != _outports) || (fi.completeBaseName() == QString("dssi-vst") && !config.vstInPlace)) - _inPlaceCapable = false; - } - } - - if(plugin == NULL) - { - dlclose(_handle); - _handle = 0; - _references = 0; - fprintf(stderr, "Plugin::incReferences Error: %s no plugin!\n", fi.filePath().toLatin1().constData()); - return 0; - } - - _references = newref; - - //QString guiPath(info.dirPath() + "/" + info.baseName()); - //QDir guiDir(guiPath, "*", QDir::Unsorted, QDir::Files); - //_hasGui = guiDir.exists(); - - return _references; -} - -//--------------------------------------------------------- -// range -//--------------------------------------------------------- - -void Plugin::range(unsigned long i, float* min, float* max) const - { - 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(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; - } - -//--------------------------------------------------------- -// defaultValue -//--------------------------------------------------------- - -double Plugin::defaultValue(unsigned long port) const -{ - if(port >= plugin->PortCount) - return 0.0; - - LADSPA_PortRangeHint range = plugin->PortRangeHints[port]; - 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; - - return val; -} - -//--------------------------------------------------------- -// loadPluginLib -//--------------------------------------------------------- - -static void loadPluginLib(QFileInfo* fi) -{ - void* handle = dlopen(fi->filePath().toAscii().constData(), RTLD_NOW); - if (handle == 0) { - fprintf(stderr, "dlopen(%s) failed: %s\n", - fi->filePath().toAscii().constData(), dlerror()); - return; - } - - #ifdef DSSI_SUPPORT - DSSI_Descriptor_Function dssi = (DSSI_Descriptor_Function)dlsym(handle, "dssi_descriptor"); - if(dssi) - { - const DSSI_Descriptor* descr; - for (int i = 0;; ++i) - { - descr = dssi(i); - if (descr == 0) - break; - - // Listing effect plugins only while excluding synths: - // Do exactly what dssi-vst.cpp does for listing ladspa plugins. - if(!descr->run_synth && - !descr->run_synth_adding && - !descr->run_multiple_synths && - !descr->run_multiple_synths_adding) - { - // Make sure it doesn't already exist. - if(plugins.find(fi->completeBaseName(), QString(descr->LADSPA_Plugin->Label)) != 0) - continue; - - #ifdef PLUGIN_DEBUGIN - fprintf(stderr, "loadPluginLib: dssi effect name:%s inPlaceBroken:%d\n", descr->LADSPA_Plugin->Name, LADSPA_IS_INPLACE_BROKEN(descr->LADSPA_Plugin->Properties)); - #endif - - //LADSPA_Properties properties = descr->LADSPA_Plugin->Properties; - //bool inPlaceBroken = LADSPA_IS_INPLACE_BROKEN(properties); - //plugins.add(fi, descr, !inPlaceBroken); - if(debugMsg) - fprintf(stderr, "loadPluginLib: adding dssi effect plugin:%s name:%s label:%s\n", fi->filePath().toLatin1().constData(), descr->LADSPA_Plugin->Name, descr->LADSPA_Plugin->Label); - - plugins.add(fi, descr->LADSPA_Plugin, true); - } - } - } - else - #endif - { - 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().toAscii().constData(), - txt); - } - dlclose(handle); - return; - } - - const LADSPA_Descriptor* descr; - for (int i = 0;; ++i) - { - descr = ladspa(i); - if (descr == NULL) - break; - - // Make sure it doesn't already exist. - if(plugins.find(fi->completeBaseName(), QString(descr->Label)) != 0) - continue; - - #ifdef PLUGIN_DEBUGIN - fprintf(stderr, "loadPluginLib: ladspa effect name:%s inPlaceBroken:%d\n", descr->Name, LADSPA_IS_INPLACE_BROKEN(descr->Properties)); - #endif - - //LADSPA_Properties properties = descr->Properties; - //bool inPlaceBroken = LADSPA_IS_INPLACE_BROKEN(properties); - //plugins.add(fi, ladspa, descr, !inPlaceBroken); - if(debugMsg) - fprintf(stderr, "loadPluginLib: adding ladspa plugin:%s name:%s label:%s\n", fi->filePath().toLatin1().constData(), descr->Name, descr->Label); - plugins.add(fi, descr); - } - } - - dlclose(handle); -} - -//--------------------------------------------------------- -// loadPluginDir -//--------------------------------------------------------- - -static void loadPluginDir(const QString& s) - { - if (debugMsg) - printf("scan ladspa plugin dir <%s>\n", s.toLatin1().constData()); - QDir pluginDir(s, QString("*.so")); // ddskrjo - if (pluginDir.exists()) { - QFileInfoList list = pluginDir.entryInfoList(); - QFileInfoList::iterator it=list.begin(); - while(it != list.end()) { - loadPluginLib(&*it); - ++it; - } - } - } - -//--------------------------------------------------------- -// initPlugins -//--------------------------------------------------------- - -void initPlugins() - { - loadPluginDir(museGlobalLib + QString("/plugins")); - - const char* p = 0; - - // Take care of DSSI plugins first... - #ifdef DSSI_SUPPORT - const char* dssiPath = getenv("DSSI_PATH"); - if (dssiPath == 0) - dssiPath = "/usr/local/lib64/dssi:/usr/lib64/dssi:/usr/local/lib/dssi:/usr/lib/dssi"; - p = dssiPath; - 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++; - } - #endif - - // Now do LADSPA 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"; - p = ladspaPath; - - if(debugMsg) - fprintf(stderr, "loadPluginDir: ladspa path:%s\n", 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'; - if(debugMsg) - fprintf(stderr, "loadPluginDir: loading ladspa dir:%s\n", buffer); - - loadPluginDir(QString(buffer)); - delete[] buffer; - } - p = pe; - if (*p == ':') - p++; - } - } - -//--------------------------------------------------------- -// find -//--------------------------------------------------------- - -Plugin* PluginList::find(const QString& file, const QString& name) - { - for (iPlugin i = begin(); i != end(); ++i) { - if ((file == i->lib()) && (name == i->label())) - return &*i; - } - //printf("Plugin <%s> not found\n", name.ascii()); - return 0; - } - -//--------------------------------------------------------- -// Pipeline -//--------------------------------------------------------- - -Pipeline::Pipeline() - : std::vector<PluginI*>() - { - // Added by Tim. p3.3.15 - for (int i = 0; i < MAX_CHANNELS; ++i) - posix_memalign((void**)(buffer + i), 16, sizeof(float) * segmentSize); - - for (int i = 0; i < PipelineDepth; ++i) - push_back(0); - } - -//--------------------------------------------------------- -// ~Pipeline -//--------------------------------------------------------- - -Pipeline::~Pipeline() - { - removeAll(); - for (int i = 0; i < MAX_CHANNELS; ++i) - ::free(buffer[i]); - } - -//--------------------------------------------------------- -// setChannels -//--------------------------------------------------------- - -void Pipeline::setChannels(int n) - { - for (int i = 0; i < PipelineDepth; ++i) - if ((*this)[i]) - (*this)[i]->setChannels(n); - } - -//--------------------------------------------------------- -// insert -// give ownership of object plugin to Pipeline -//--------------------------------------------------------- - -void Pipeline::insert(PluginI* plugin, int index) - { - remove(index); - (*this)[index] = plugin; - } - -//--------------------------------------------------------- -// remove -//--------------------------------------------------------- - -void Pipeline::remove(int index) - { - PluginI* plugin = (*this)[index]; - if (plugin) - delete plugin; - (*this)[index] = 0; - } - -//--------------------------------------------------------- -// removeAll -//--------------------------------------------------------- - -void Pipeline::removeAll() - { - for (int i = 0; i < PipelineDepth; ++i) - remove(i); - } - -//--------------------------------------------------------- -// isOn -//--------------------------------------------------------- - -bool Pipeline::isOn(int idx) const - { - PluginI* p = (*this)[idx]; - if (p) - return p->on(); - return false; - } - -//--------------------------------------------------------- -// setOn -//--------------------------------------------------------- - -void Pipeline::setOn(int idx, bool flag) - { - PluginI* p = (*this)[idx]; - if (p) { - p->setOn(flag); - if (p->gui()) - p->gui()->setOn(flag); - } - } - -//--------------------------------------------------------- -// label -//--------------------------------------------------------- - -QString Pipeline::label(int idx) const - { - PluginI* p = (*this)[idx]; - if (p) - return p->label(); - return QString(""); - } - -//--------------------------------------------------------- -// name -//--------------------------------------------------------- - -QString Pipeline::name(int idx) const - { - PluginI* p = (*this)[idx]; - if (p) - return p->name(); - return QString("empty"); - } - -//--------------------------------------------------------- -// empty -//--------------------------------------------------------- - -bool Pipeline::empty(int idx) const - { - PluginI* p = (*this)[idx]; - return p == 0; - } - -//--------------------------------------------------------- -// move -//--------------------------------------------------------- - -void Pipeline::move(int idx, bool up) -{ - PluginI* p1 = (*this)[idx]; - if (up) - { - (*this)[idx] = (*this)[idx-1]; - - if((*this)[idx]) - (*this)[idx]->setID(idx); - - (*this)[idx-1] = p1; - - if(p1) - { - p1->setID(idx - 1); - if(p1->track()) - audio->msgSwapControllerIDX(p1->track(), idx, idx - 1); - } - } - else - { - (*this)[idx] = (*this)[idx+1]; - - if((*this)[idx]) - (*this)[idx]->setID(idx); - - (*this)[idx+1] = p1; - - if(p1) - { - p1->setID(idx + 1); - if(p1->track()) - audio->msgSwapControllerIDX(p1->track(), idx, idx + 1); - } - } -} - -//--------------------------------------------------------- -// isDssiPlugin -//--------------------------------------------------------- - -bool Pipeline::isDssiPlugin(int idx) const -{ - PluginI* p = (*this)[idx]; - if(p) - return p->isDssiPlugin(); - - return false; -} - -//--------------------------------------------------------- -// showGui -//--------------------------------------------------------- - -void Pipeline::showGui(int idx, bool flag) - { - PluginI* p = (*this)[idx]; - if (p) - p->showGui(flag); - } - -//--------------------------------------------------------- -// showNativeGui -//--------------------------------------------------------- - -void Pipeline::showNativeGui(int idx, bool flag) - { - #ifdef OSC_SUPPORT - PluginI* p = (*this)[idx]; - if (p) - p->oscIF().oscShowGui(flag); - #endif - } - -//--------------------------------------------------------- -// deleteGui -//--------------------------------------------------------- - -void Pipeline::deleteGui(int idx) -{ - if(idx >= PipelineDepth) - return; - PluginI* p = (*this)[idx]; - if(p) - p->deleteGui(); -} - -//--------------------------------------------------------- -// deleteAllGuis -//--------------------------------------------------------- - -void Pipeline::deleteAllGuis() -{ - for(int i = 0; i < PipelineDepth; i++) - deleteGui(i); -} - -//--------------------------------------------------------- -// guiVisible -//--------------------------------------------------------- - -bool Pipeline::guiVisible(int idx) - { - PluginI* p = (*this)[idx]; - if (p) - return p->guiVisible(); - return false; - } - -//--------------------------------------------------------- -// nativeGuiVisible -//--------------------------------------------------------- - -bool Pipeline::nativeGuiVisible(int idx) - { - PluginI* p = (*this)[idx]; - if (p) - return p->nativeGuiVisible(); - return false; - } - -//--------------------------------------------------------- -// apply -//--------------------------------------------------------- - -void Pipeline::apply(int ports, unsigned long nframes, float** buffer1) -{ - // prepare a second set of buffers in case a plugin is not - // capable of inPlace processing - - // Removed by Tim. p3.3.15 - //float* buffer2[ports]; - //float data[nframes * ports]; - //for (int i = 0; i < ports; ++i) - // buffer2[i] = data + i * nframes; - - // p3.3.41 - //fprintf(stderr, "Pipeline::apply data: nframes:%ld %e %e %e %e\n", nframes, buffer1[0][0], buffer1[0][1], buffer1[0][2], buffer1[0][3]); - - bool swap = false; - - for (iPluginI ip = begin(); ip != end(); ++ip) { - PluginI* p = *ip; - if (p && p->on()) { - if (p->inPlaceCapable()) - { - if (swap) - //p->connect(ports, buffer2, buffer2); - p->connect(ports, buffer, buffer); - else - p->connect(ports, buffer1, buffer1); - } - else - { - if (swap) - //p->connect(ports, buffer2, buffer1); - p->connect(ports, buffer, buffer1); - else - //p->connect(ports, buffer1, buffer2); - p->connect(ports, buffer1, buffer); - swap = !swap; - } - p->apply(nframes); - } - } - if (swap) - { - for (int i = 0; i < ports; ++i) - //memcpy(buffer1[i], buffer2[i], sizeof(float) * nframes); - //memcpy(buffer1[i], buffer[i], sizeof(float) * nframes); - AL::dsp->cpy(buffer1[i], buffer[i], nframes); - } - - // p3.3.41 - //fprintf(stderr, "Pipeline::apply after data: nframes:%ld %e %e %e %e\n", nframes, buffer1[0][0], buffer1[0][1], buffer1[0][2], buffer1[0][3]); - -} - -//--------------------------------------------------------- -// PluginI -//--------------------------------------------------------- - -void PluginI::init() - { - _plugin = 0; - instances = 0; - handle = 0; - controls = 0; - controlsOut = 0; - controlPorts = 0; - controlOutPorts = 0; - _gui = 0; - _on = true; - initControlValues = false; - _showNativeGuiPending = false; - } - -PluginI::PluginI() - { - _id = -1; - _track = 0; - - init(); - } - -//--------------------------------------------------------- -// PluginI -//--------------------------------------------------------- - -PluginI::~PluginI() - { - if (_plugin) { - deactivate(); - _plugin->incReferences(-1); - } - if (_gui) - delete _gui; - if (controlsOut) - delete[] controlsOut; - if (controls) - delete[] controls; - if (handle) - delete[] handle; - } - -//--------------------------------------------------------- -// setID -//--------------------------------------------------------- - -void PluginI::setID(int i) -{ - _id = i; -} - -//--------------------------------------------------------- -// updateControllers -//--------------------------------------------------------- - -void PluginI::updateControllers() -{ - if(!_track) - return; - - for(int i = 0; i < controlPorts; ++i) - //audio->msgSetPluginCtrlVal(this, genACnum(_id, i), controls[i].val); - // p3.3.43 - audio->msgSetPluginCtrlVal(_track, genACnum(_id, i), controls[i].val); -} - -//--------------------------------------------------------- -// valueType -//--------------------------------------------------------- - -CtrlValueType PluginI::valueType() const - { - return VAL_LINEAR; - } - -//--------------------------------------------------------- -// setChannel -//--------------------------------------------------------- - -void PluginI::setChannels(int c) -{ - // p3.3.41 Removed - //if (channel == c) - // return; - - // p3.3.41 - channel = c; - - //int ni = c / _plugin->outports(); - //if (ni == 0) - // ni = 1; - // p3.3.41 Some plugins have zero out ports, causing exception with the above line. - // Also, pick the least number of ins or outs, and base the number of instances on that. - unsigned long ins = _plugin->inports(); - unsigned long outs = _plugin->outports(); - /* - unsigned long minports = ~0ul; - if(outs && outs < minports) - minports = outs; - if(ins && ins < minports) - minports = ins; - if(minports == ~0ul) - minports = 1; - int ni = c / minports; - */ - int ni = 1; - if(outs) - ni = c / outs; - else - if(ins) - ni = c / ins; - - if(ni < 1) - ni = 1; - - if (ni == instances) - return; - - // p3.3.41 Moved above. - //channel = c; - - // remove old instances: - deactivate(); - delete[] handle; - instances = ni; - handle = new LADSPA_Handle[instances]; - for (int i = 0; i < instances; ++i) { - handle[i] = _plugin->instantiate(); - if (handle[i] == NULL) { - printf("cannot instantiate instance %d\n", i); - return; - } - } - - int curPort = 0; - int curOutPort = 0; - unsigned long ports = _plugin->ports(); - for (unsigned long k = 0; k < ports; ++k) - { - LADSPA_PortDescriptor pd = _plugin->portd(k); - if (pd & LADSPA_PORT_CONTROL) - { - if(pd & LADSPA_PORT_INPUT) - { - for (int i = 0; i < instances; ++i) - _plugin->connectPort(handle[i], k, &controls[curPort].val); - controls[curPort].idx = k; - ++curPort; - } - else - if(pd & LADSPA_PORT_OUTPUT) - { - for (int i = 0; i < instances; ++i) - _plugin->connectPort(handle[i], k, &controlsOut[curOutPort].val); - controlsOut[curOutPort].idx = k; - ++curOutPort; - } - } - } - - activate(); -} - -//--------------------------------------------------------- -// defaultValue -//--------------------------------------------------------- - -double PluginI::defaultValue(unsigned int param) const -{ -//#warning controlPorts should really be unsigned - if(param >= (unsigned)controlPorts) - return 0.0; - - return _plugin->defaultValue(controls[param].idx); -} - -LADSPA_Handle Plugin::instantiate() -{ - LADSPA_Handle h = plugin->instantiate(plugin, sampleRate); - if(h == NULL) - { - fprintf(stderr, "Plugin::instantiate() Error: plugin:%s instantiate failed!\n", plugin->Label); - return NULL; - } - - //QString guiPath(info.dirPath() + "/" + info.baseName()); - //QDir guiDir(guiPath, "*", QDir::Unsorted, QDir::Files); - //_hasGui = guiDir.exists(); - - return h; -} - -//--------------------------------------------------------- -// initPluginInstance -// return true on error -//--------------------------------------------------------- - -bool PluginI::initPluginInstance(Plugin* plug, int c) - { - channel = c; - if(plug == 0) - { - printf("initPluginInstance: zero plugin\n"); - return true; - } - _plugin = plug; - - _plugin->incReferences(1); - - #ifdef OSC_SUPPORT - _oscif.oscSetPluginI(this); - #endif - - QString inst("-" + QString::number(_plugin->instNo())); - _name = _plugin->name() + inst; - _label = _plugin->label() + inst; - - //instances = channel/plug->outports(); - // p3.3.41 Some plugins have zero out ports, causing exception with the above line. - // Also, pick the least number of ins or outs, and base the number of instances on that. - unsigned long ins = plug->inports(); - unsigned long outs = plug->outports(); - /* - unsigned long minports = ~0ul; - if(outs && outs < minports) - minports = outs; - if(ins && ins < minports) - minports = ins; - if(minports == ~0ul) - minports = 1; - instances = channel / minports; - if(instances < 1) - instances = 1; - */ - if(outs) - { - instances = channel / outs; - if(instances < 1) - instances = 1; - } - else - if(ins) - { - instances = channel / ins; - if(instances < 1) - instances = 1; - } - else - instances = 1; - - handle = new LADSPA_Handle[instances]; - for(int i = 0; i < instances; ++i) - { - #ifdef PLUGIN_DEBUGIN - fprintf(stderr, "PluginI::initPluginInstance instance:%d\n", i); - #endif - - handle[i] = _plugin->instantiate(); - //if (handle[i] == 0) - if(handle[i] == NULL) - return true; - } - - unsigned long ports = _plugin->ports(); - - controlPorts = 0; - controlOutPorts = 0; - - for(unsigned long k = 0; k < ports; ++k) - { - LADSPA_PortDescriptor pd = _plugin->portd(k); - if(pd & LADSPA_PORT_CONTROL) - { - if(pd & LADSPA_PORT_INPUT) - ++controlPorts; - else - if(pd & LADSPA_PORT_OUTPUT) - ++controlOutPorts; - } - } - - controls = new Port[controlPorts]; - controlsOut = new Port[controlOutPorts]; - - int i = 0; - int ii = 0; - for(unsigned long k = 0; k < ports; ++k) - { - LADSPA_PortDescriptor pd = _plugin->portd(k); - if(pd & LADSPA_PORT_CONTROL) - { - if(pd & LADSPA_PORT_INPUT) - { - double val = _plugin->defaultValue(k); - controls[i].val = val; - controls[i].tmpVal = val; - controls[i].enCtrl = true; - controls[i].en2Ctrl = true; - ++i; - } - else - if(pd & LADSPA_PORT_OUTPUT) - { - //double val = _plugin->defaultValue(k); - controlsOut[ii].val = 0.0; - controlsOut[ii].tmpVal = 0.0; - controlsOut[ii].enCtrl = false; - controlsOut[ii].en2Ctrl = false; - ++ii; - } - } - } - unsigned long curPort = 0; - unsigned long curOutPort = 0; - for(unsigned long k = 0; k < ports; ++k) - { - LADSPA_PortDescriptor pd = _plugin->portd(k); - if(pd & LADSPA_PORT_CONTROL) - { - if(pd & LADSPA_PORT_INPUT) - { - for(int i = 0; i < instances; ++i) - _plugin->connectPort(handle[i], k, &controls[curPort].val); - controls[curPort].idx = k; - ++curPort; - } - else - if(pd & LADSPA_PORT_OUTPUT) - { - for(int i = 0; i < instances; ++i) - _plugin->connectPort(handle[i], k, &controlsOut[curOutPort].val); - controlsOut[curOutPort].idx = k; - ++curOutPort; - } - } - } - activate(); - return false; - } - -//--------------------------------------------------------- -// connect -//--------------------------------------------------------- - -void PluginI::connect(int ports, float** src, float** dst) - { - int port = 0; - for (int i = 0; i < instances; ++i) { - for (unsigned long k = 0; k < _plugin->ports(); ++k) { - if (isAudioIn(k)) { - _plugin->connectPort(handle[i], k, src[port]); - port = (port + 1) % ports; - } - } - } - port = 0; - for (int i = 0; i < instances; ++i) { - for (unsigned long k = 0; k < _plugin->ports(); ++k) { - if (isAudioOut(k)) { - _plugin->connectPort(handle[i], k, dst[port]); - port = (port + 1) % ports; // overwrite output? -// ++port; -// if (port >= ports) { -// return; -// } - } - } - } - } - -//--------------------------------------------------------- -// deactivate -//--------------------------------------------------------- - -void PluginI::deactivate() - { - for (int i = 0; i < instances; ++i) { - _plugin->deactivate(handle[i]); - _plugin->cleanup(handle[i]); - } - } - -//--------------------------------------------------------- -// activate -//--------------------------------------------------------- - -void PluginI::activate() - { - for (int i = 0; i < instances; ++i) - _plugin->activate(handle[i]); - if (initControlValues) { - for (int i = 0; i < controlPorts; ++i) { - controls[i].val = controls[i].tmpVal; - } - } - else { - // - // get initial control values from plugin - // - for (int i = 0; i < controlPorts; ++i) { - controls[i].tmpVal = controls[i].val; - } - } - } - -//--------------------------------------------------------- -// setControl -// set plugin instance controller value by name -//--------------------------------------------------------- - -bool PluginI::setControl(const QString& s, double val) - { - for (int i = 0; i < controlPorts; ++i) { - if (_plugin->portName(controls[i].idx) == s) { - controls[i].val = controls[i].tmpVal = val; - return false; - } - } - printf("PluginI:setControl(%s, %f) controller not found\n", - s.toLatin1().constData(), val); - return true; - } - -//--------------------------------------------------------- -// saveConfiguration -//--------------------------------------------------------- - -void PluginI::writeConfiguration(int level, Xml& xml) - { - xml.tag(level++, "plugin file=\"%s\" label=\"%s\" channel=\"%d\"", - //_plugin->lib().toLatin1().constData(), _plugin->label().toLatin1().constData(), instances * _plugin->inports()); - // p3.3.41 - //_plugin->lib().toLatin1().constData(), _plugin->label().toLatin1().constData(), channel); - Xml::xmlString(_plugin->lib()).toLatin1().constData(), Xml::xmlString(_plugin->label()).toLatin1().constData(), channel); - - for (int i = 0; i < controlPorts; ++i) { - int idx = controls[i].idx; - QString s("control name=\"%1\" val=\"%2\" /"); - //xml.tag(level, s.arg(_plugin->portName(idx)).arg(controls[i].tmpVal).toLatin1().constData()); - xml.tag(level, s.arg(Xml::xmlString(_plugin->portName(idx)).toLatin1().constData()).arg(controls[i].tmpVal).toLatin1().constData()); - } - if (_on == false) - xml.intTag(level, "on", _on); - if (guiVisible()) { - xml.intTag(level, "gui", 1); - xml.geometryTag(level, "geometry", _gui); - } - if (nativeGuiVisible()) { - xml.intTag(level, "nativegui", 1); - // TODO: - //xml.geometryTag(level, "nativegeometry", ?); - } - xml.tag(level--, "/plugin"); - } - -//--------------------------------------------------------- -// loadControl -//--------------------------------------------------------- - -bool PluginI::loadControl(Xml& xml) - { - QString file; - QString label; - QString name("mops"); - double val = 0.0; - - for (;;) { - Xml::Token token = xml.parse(); - const QString& tag = xml.s1(); - - switch (token) { - case Xml::Error: - case Xml::End: - return true; - case Xml::TagStart: - xml.unknown("PluginI-Control"); - break; - case Xml::Attribut: - if (tag == "name") - name = xml.s2(); - else if (tag == "val") - val = xml.s2().toDouble(); - break; - case Xml::TagEnd: - if (tag == "control") { - if (setControl(name, val)) { - return false; - } - initControlValues = true; - } - return true; - default: - break; - } - } - return true; - } - -//--------------------------------------------------------- -// readConfiguration -// return true on error -//--------------------------------------------------------- - -bool PluginI::readConfiguration(Xml& xml, bool readPreset) - { - QString file; - QString label; - if (!readPreset) - //instances = 1; - // p3.3.41 - channel = 1; - - for (;;) { - Xml::Token token(xml.parse()); - const QString& tag(xml.s1()); - switch (token) { - case Xml::Error: - case Xml::End: - return true; - case Xml::TagStart: - if (!readPreset && _plugin == 0) { - _plugin = plugins.find(file, label); - - //if (_plugin && initPluginInstance(_plugin, instances)) { - // p3.3.41 - if (_plugin && initPluginInstance(_plugin, channel)) { - _plugin = 0; - xml.parse1(); - break; - } - } - if (tag == "control") - loadControl(xml); - else if (tag == "on") { - bool flag = xml.parseInt(); - if (!readPreset) - _on = flag; - } - else if (tag == "gui") { - bool flag = xml.parseInt(); - showGui(flag); - } - else if (tag == "nativegui") { - // We can't tell OSC to show the native plugin gui - // until the parent track is added to the lists. - // OSC needs to find the plugin in the track lists. - // Use this 'pending' flag so it gets done later. - _showNativeGuiPending = xml.parseInt(); - } - else if (tag == "geometry") { - QRect r(readGeometry(xml, tag)); - if (_gui) { - _gui->resize(r.size()); - _gui->move(r.topLeft()); - } - } - else - xml.unknown("PluginI"); - break; - case Xml::Attribut: - if (tag == "file") { - QString s = xml.s2(); - if (readPreset) { - if (s != plugin()->lib()) { - printf("Error: Wrong preset type %s. Type must be a %s\n", - s.toLatin1().constData(), plugin()->lib().toLatin1().constData()); - return true; - } - } - else { - file = s; - } - } - else if (tag == "label") { - if (!readPreset) - label = xml.s2(); - } - else if (tag == "channel") { - if (!readPreset) - //instances = xml.s2().toInt(); - // p3.3.41 - channel = xml.s2().toInt(); - } - break; - case Xml::TagEnd: - if (tag == "plugin") { - if (!readPreset && _plugin == 0) { - _plugin = plugins.find(file, label); - if (_plugin == 0) - return true; - - //if (initPluginInstance(_plugin, instances)) - // p3.3.41 - if (initPluginInstance(_plugin, channel)) - return true; - } - if (_gui) - _gui->updateValues(); - return false; - } - return true; - default: - break; - } - } - return true; - } - -//--------------------------------------------------------- -// showGui -//--------------------------------------------------------- - -void PluginI::showGui() - { - if (_plugin) { - if (_gui == 0) - makeGui(); - if (_gui->isVisible()) - _gui->hide(); - else - _gui->show(); - } - } - -void PluginI::showGui(bool flag) - { - if (_plugin) { - if (flag) { - if (_gui == 0) - makeGui(); - _gui->show(); - } - else { - if (_gui) - _gui->hide(); - } - } - } - -//--------------------------------------------------------- -// guiVisible -//--------------------------------------------------------- - -bool PluginI::guiVisible() - { - return _gui && _gui->isVisible(); - } - -//--------------------------------------------------------- -// showNativeGui -//--------------------------------------------------------- - -void PluginI::showNativeGui() -{ - #ifdef OSC_SUPPORT - if (_plugin) - { - if (_oscif.oscGuiVisible()) - _oscif.oscShowGui(false); - else - _oscif.oscShowGui(true); - } - #endif - _showNativeGuiPending = false; -} - -void PluginI::showNativeGui(bool flag) -{ - #ifdef OSC_SUPPORT - if(_plugin) - { - _oscif.oscShowGui(flag); - } - #endif - _showNativeGuiPending = false; -} - -//--------------------------------------------------------- -// nativeGuiVisible -//--------------------------------------------------------- - -bool PluginI::nativeGuiVisible() -{ - #ifdef OSC_SUPPORT - return _oscif.oscGuiVisible(); - #endif - - return false; -} - -//--------------------------------------------------------- -// makeGui -//--------------------------------------------------------- - -void PluginI::makeGui() - { - _gui = new PluginGui(this); - } - -//--------------------------------------------------------- -// deleteGui -//--------------------------------------------------------- -void PluginI::deleteGui() -{ - if(_gui) - { - delete _gui; - _gui = 0; - } -} - -//--------------------------------------------------------- -// enableAllControllers -//--------------------------------------------------------- - -void PluginI::enableAllControllers(bool v) -{ - for(int i = 0; i < controlPorts; ++i) - controls[i].enCtrl = v; -} - -//--------------------------------------------------------- -// enable2AllControllers -//--------------------------------------------------------- - -void PluginI::enable2AllControllers(bool v) -{ - for(int i = 0; i < controlPorts; ++i) - controls[i].en2Ctrl = v; -} - -//--------------------------------------------------------- -// apply -//--------------------------------------------------------- - -void PluginI::apply(int n) -{ - // Process control value changes. - //if(automation && _track && _track->automationType() != AUTO_OFF && _id != -1) - //{ - // for(int i = 0; i < controlPorts; ++i) - // { - // if( controls[i].enCtrl && controls[i].en2Ctrl ) - // controls[i].tmpVal = _track->pluginCtrlVal(genACnum(_id, i)); - // } - //} - - unsigned long ctls = controlPorts; - for(unsigned long k = 0; k < ctls; ++k) - { - // First, update the temporary value if needed... - - #ifdef OSC_SUPPORT - // Process OSC gui input control fifo events. - // It is probably more important that these are processed so that they take precedence over all other - // events because OSC + DSSI/DSSI-VST are fussy about receiving feedback via these control ports, from GUI changes. - - OscControlFifo* cfifo = _oscif.oscFifo(k); - //if(!cfifo) - // continue; - - // If there are 'events' in the fifo, get exactly one 'event' per control per process cycle... - //if(!cfifo->isEmpty()) - if(cfifo && !cfifo->isEmpty()) - { - OscControlValue v = cfifo->get(); - - #ifdef PLUGIN_DEBUGIN - fprintf(stderr, "PluginI::apply OscControlFifo event input control number:%ld value:%f\n", k, v.value); - #endif - - // Set the ladspa control port value. - controls[k].tmpVal = v.value; - - // Need to update the automation value, otherwise it overwrites later with the last automation value. - if(_track && _id != -1) - { - // Since we are now in the audio thread context, there's no need to send a message, - // just modify directly. - //audio->msgSetPluginCtrlVal(this, genACnum(_id, k), controls[k].val); - // p3.3.43 - //audio->msgSetPluginCtrlVal(_track, genACnum(_id, k), controls[k].val); - _track->setPluginCtrlVal(genACnum(_id, k), v.value); - - // Record automation. - // NO! Take care of this immediately in the OSC control handler, because we don't want - // the silly delay associated with processing the fifo one-at-a-time here. - - //AutomationType at = _track->automationType(); - // TODO: Taken from our native gui control handlers. - // This may need modification or may cause problems - - // we don't have the luxury of access to the dssi gui controls ! - //if(at == AUTO_WRITE || (audio->isPlaying() && at == AUTO_TOUCH)) - // enableController(k, false); - //_track->recordAutomation(id, v.value); - } - } - else - #endif // OSC_SUPPORT - { - // Process automation control value. - if(automation && _track && _track->automationType() != AUTO_OFF && _id != -1) - { - if(controls[k].enCtrl && controls[k].en2Ctrl ) - controls[k].tmpVal = _track->pluginCtrlVal(genACnum(_id, k)); - } - } - - // Now update the actual value from the temporary value... - controls[k].val = controls[k].tmpVal; - } - - //for (int i = 0; i < controlPorts; ++i) - // controls[i].val = controls[i].tmpVal; - - for (int i = 0; i < instances; ++i) - { - // p3.3.41 - //fprintf(stderr, "PluginI::apply handle %d\n", i); - _plugin->apply(handle[i], n); - } - } - -//--------------------------------------------------------- -// oscConfigure -//--------------------------------------------------------- - -#ifdef OSC_SUPPORT -int Plugin::oscConfigure(LADSPA_Handle handle, const char* key, const char* value) - { - #ifdef PLUGIN_DEBUGIN - printf("Plugin::oscConfigure effect plugin label:%s key:%s value:%s\n", plugin->Label, key, value); - #endif - - #ifdef DSSI_SUPPORT - if(!dssi_descr || !dssi_descr->configure) - return 0; - - if (!strncmp(key, DSSI_RESERVED_CONFIGURE_PREFIX, - strlen(DSSI_RESERVED_CONFIGURE_PREFIX))) { - fprintf(stderr, "Plugin::oscConfigure OSC: UI for plugin '%s' attempted to use reserved configure key \"%s\", ignoring\n", - plugin->Label, key); - - return 0; - } - - char* message = dssi_descr->configure(handle, key, value); - if (message) { - printf("Plugin::oscConfigure on configure '%s' '%s', plugin '%s' returned error '%s'\n", - //key, value, synti->name().toAscii().data(), message); - key, value, plugin->Label, message); - - free(message); - } - - // also call back on UIs for plugins other than the one - // that requested this: - // if (n != instance->number && instances[n].uiTarget) { - // lo_send(instances[n].uiTarget, - // instances[n].ui_osc_configure_path, "ss", key, value); - // } - - // configure invalidates bank and program information, so - // we should do this again now: - //queryPrograms(); - - #endif // DSSI_SUPPORT - - return 0; -} - -//--------------------------------------------------------- -// oscConfigure -//--------------------------------------------------------- - -int PluginI::oscConfigure(const char *key, const char *value) - { - if(!_plugin) - return 0; - - // This is pretty much the simplest legal implementation of - // configure in a DSSI host. - - // The host has the option to remember the set of (key,value) - // pairs associated with a particular instance, so that if it - // wants to restore the "same" instance on another occasion it can - // just call configure() on it for each of those pairs and so - // restore state without any input from a GUI. Any real-world GUI - // host will probably want to do that. This host doesn't have any - // concept of restoring an instance from one run to the next, so - // we don't bother remembering these at all. - - //const char *key = (const char *)&argv[0]->s; - //const char *value = (const char *)&argv[1]->s; - - #ifdef PLUGIN_DEBUGIN - printf("PluginI::oscConfigure effect plugin name:%s label:%s key:%s value:%s\n", _name.toLatin1().constData(), _label.toLatin1().constData(), key, value); - #endif - - #ifdef DSSI_SUPPORT - // FIXME: Don't think this is right, should probably do as example shows below. - for(int i = 0; i < instances; ++i) - _plugin->oscConfigure(handle[i], key, value); - - // also call back on UIs for plugins other than the one - // that requested this: - // if (n != instance->number && instances[n].uiTarget) { - // lo_send(instances[n].uiTarget, - // instances[n].ui_osc_configure_path, "ss", key, value); - // } - - // configure invalidates bank and program information, so - // we should do this again now: - //queryPrograms(); - #endif // DSSI_SUPPORT - - return 0; -} - -//--------------------------------------------------------- -// oscUpdate -//--------------------------------------------------------- - -int PluginI::oscUpdate() -{ - #ifdef DSSI_SUPPORT - // Send project directory. - _oscif.oscSendConfigure(DSSI_PROJECT_DIRECTORY_KEY, museProject.toLatin1().constData()); // song->projectPath() - #endif - - /* - // Send current string configuration parameters. - StringParamMap& map = synti->stringParameters(); - int i = 0; - for(ciStringParamMap r = map.begin(); r != map.end(); ++r) - { - _oscIF.oscSendConfigure(r->first.c_str(), r->second.c_str()); - // Avoid overloading the GUI if there are lots and lots of params. - if((i+1) % 50 == 0) - usleep(300000); - ++i; - } - - // Send current bank and program. - unsigned long bank, prog; - synti->currentProg(&prog, &bank, 0); - _oscIF.oscSendProgram(prog, bank); - - // Send current control values. - unsigned long ports = synth->_controlInPorts; - for(unsigned long i = 0; i < ports; ++i) - { - unsigned long k = synth->pIdx(i); - _oscIF.oscSendControl(k, controls[i]); - // Avoid overloading the GUI if there are lots and lots of ports. - if((i+1) % 50 == 0) - usleep(300000); - } - - */ - - return 0; -} - -//--------------------------------------------------------- -// oscControl -//--------------------------------------------------------- - -int PluginI::oscControl(unsigned long port, float value) -{ - //int port = argv[0]->i; - //LADSPA_Data value = argv[1]->f; - - #ifdef PLUGIN_DEBUGIN - printf("PluginI::oscControl received oscControl port:%ld val:%f\n", port, value); - #endif - - //int controlPorts = synth->_controller; - - //if(port >= controlPorts) - //if(port < 0 || port >= _plugin->rpIdx.size()) - //{ - //fprintf(stderr, "DssiSynthIF::oscControl: port number:%d is out of range of number of ports:%d\n", port, controlPorts); - // fprintf(stderr, "PluginI::oscControl: port number:%d is out of range of index list size:%d\n", port, _plugin->rpIdx.size()); - // return 0; - //} - - // Convert from DSSI port number to control input port index. - //unsigned long cport = _plugin->rpIdx[port]; - unsigned long cport = _plugin->port2InCtrl(port); - - if((int)cport == -1) - { - fprintf(stderr, "PluginI::oscControl: port number:%ld is not a control input\n", port); - return 0; - } - - // (From DSSI module). - // p3.3.39 Set the DSSI control input port's value. - // Observations: With a native DSSI synth like LessTrivialSynth, the native GUI's controls do not change the sound at all - // ie. they don't update the DSSI control port values themselves. - // Hence in response to the call to this oscControl, sent by the native GUI, it is required to that here. -/// controls[cport].val = value; - // DSSI-VST synths however, unlike DSSI synths, DO change their OWN sound in response to their gui controls. - // AND this function is called ! - // Despite the descrepency we are STILL required to update the DSSI control port values here - // because dssi-vst is WAITING FOR A RESPONSE! (A CHANGE in the control port value). - // It will output something like "...4 events expected..." and count that number down as 4 actual control port value CHANGES - // are done here in response. Normally it says "...0 events expected..." when MusE is the one doing the DSSI control changes. - // TODO: May need FIFOs on each control(!) so that the control changes get sent one per process cycle! - // Observed countdown not actually going to zero upon string of changes. - // Try this ... - OscControlFifo* cfifo = _oscif.oscFifo(cport); - if(cfifo) - { - OscControlValue cv; - //cv.idx = cport; - cv.value = value; - if(cfifo->put(cv)) - { - fprintf(stderr, "PluginI::oscControl: fifo overflow: in control number:%ld\n", cport); - } - } - - // Record automation: - // Take care of this immediately, because we don't want the silly delay associated with - // processing the fifo one-at-a-time in the apply(). - // NOTE: Ahh crap! We don't receive control events until the user RELEASES a control ! - // So the events all arrive at once when the user releases a control. - // That makes this pretty useless... But what the heck... - if(_track && _id != -1) - { - int id = genACnum(_id, cport); - AutomationType at = _track->automationType(); - - // TODO: Taken from our native gui control handlers. - // This may need modification or may cause problems - - // we don't have the luxury of access to the dssi gui controls ! - if(at == AUTO_WRITE || (audio->isPlaying() && at == AUTO_TOUCH)) - enableController(cport, false); - - _track->recordAutomation(id, value); - } - - /* - const DSSI_Descriptor* dssi = synth->dssi; - const LADSPA_Descriptor* ld = dssi->LADSPA_Plugin; - - ciMidiCtl2LadspaPort ip = synth->port2MidiCtlMap.find(cport); - if(ip != synth->port2MidiCtlMap.end()) - { - // TODO: TODO: Update midi MusE's midi controller knobs, sliders, boxes etc with a call to the midi port's setHwCtrlState() etc. - // But first we need a ladspa2MidiValue() function! ... - // - // - //float val = ladspa2MidiValue(ld, i, ?, ?); - - } - */ - -#if 0 - int port = argv[0]->i; - LADSPA_Data value = argv[1]->f; - - if (port < 0 || port > instance->plugin->descriptor->LADSPA_Plugin->PortCount) { - fprintf(stderr, "MusE: OSC: %s port number (%d) is out of range\n", - instance->friendly_name, port); - return 0; - } - if (instance->pluginPortControlInNumbers[port] == -1) { - fprintf(stderr, "MusE: OSC: %s port %d is not a control in\n", - instance->friendly_name, port); - return 0; - } - pluginControlIns[instance->pluginPortControlInNumbers[port]] = value; - if (verbose) { - printf("MusE: OSC: %s port %d = %f\n", - instance->friendly_name, port, value); - } -#endif - return 0; - } - -#endif // OSC_SUPPORT - - -//--------------------------------------------------------- -// PluginDialog -// select Plugin dialog -//--------------------------------------------------------- - -PluginDialog::PluginDialog(QWidget* parent) - : QDialog(parent) - { - setWindowTitle(tr("MusE: select plugin")); - QVBoxLayout* layout = new QVBoxLayout(this); - - pList = new QTreeWidget(this); - pList->setColumnCount(11); - pList->setSortingEnabled(true); - QStringList headerLabels; - headerLabels << tr("Lib"); - headerLabels << tr("Label"); - headerLabels << tr("Name"); - headerLabels << tr("AI"); - headerLabels << tr("AO"); - headerLabels << tr("CI"); - headerLabels << tr("CO"); - headerLabels << tr("IP"); - headerLabels << tr("id"); - headerLabels << tr("Maker"); - headerLabels << tr("Copyright"); - - int sizes[] = { 110, 110, 0, 30, 30, 30, 30, 30, 40, 110, 110 }; - for (int i = 0; i < 11; ++i) { - if (sizes[i] == 0) { - pList->header()->setResizeMode(i, QHeaderView::Stretch); - } - else { - if (sizes[i] <= 40) // hack alert! - pList->header()->setResizeMode(i, QHeaderView::Custom); - pList->header()->resizeSection(i, sizes[i]); - } - } - - pList->setHeaderLabels(headerLabels); - - pList->setSelectionBehavior(QAbstractItemView::SelectRows); - pList->setSelectionMode(QAbstractItemView::SingleSelection); - pList->setAlternatingRowColors(true); - - fillPlugs(selectedPlugType); - layout->addWidget(pList); - - //--------------------------------------------------- - // Ok/Cancel Buttons - //--------------------------------------------------- - - QBoxLayout* w5 = new QHBoxLayout; - layout->addLayout(w5); - - okB = new QPushButton(tr("Ok"), this); - okB->setDefault(true); - QPushButton* cancelB = new QPushButton(tr("Cancel"), this); - okB->setFixedWidth(80); - okB->setEnabled(false); - cancelB->setFixedWidth(80); - w5->addWidget(okB); - w5->addSpacing(12); - w5->addWidget(cancelB); - - QGroupBox* plugSelGroup = new QGroupBox; - plugSelGroup->setTitle("Show plugs:"); - QHBoxLayout* psl = new QHBoxLayout; - plugSelGroup->setLayout(psl); - - QButtonGroup* plugSel = new QButtonGroup(plugSelGroup); - onlySM = new QRadioButton; - onlySM->setText(tr("Mono and Stereo")); - onlySM->setCheckable(true); - plugSel->addButton(onlySM); - psl->addWidget(onlySM); - onlyS = new QRadioButton; - onlyS->setText(tr("Stereo")); - onlyS->setCheckable(true); - plugSel->addButton(onlyS); - psl->addWidget(onlyS); - onlyM = new QRadioButton; - onlyM->setText(tr("Mono")); - onlyM->setCheckable(true); - plugSel->addButton(onlyM); - psl->addWidget(onlyM); - allPlug = new QRadioButton; - allPlug->setText(tr("Show All")); - allPlug->setCheckable(true); - plugSel->addButton(allPlug); - psl->addWidget(allPlug); - plugSel->setExclusive(true); - - switch(selectedPlugType) { - case SEL_SM: onlySM->setChecked(true); break; - case SEL_S: onlyS->setChecked(true); break; - case SEL_M: onlyM->setChecked(true); break; - case SEL_ALL: allPlug->setChecked(true); break; - } - - plugSelGroup->setToolTip(tr("Select which types of plugins should be visible in the list.<br>" - "Note that using mono plugins on stereo tracks is not a problem, two will be used in parallell.<br>" - "Also beware that the 'all' alternative includes plugins that probably not are usable by MusE.")); - - w5->addSpacing(12); - w5->addWidget(plugSelGroup); - w5->addSpacing(12); - - QLabel *sortLabel = new QLabel; - sortLabel->setText(tr("Search in 'Label' and 'Name':")); - w5->addWidget(sortLabel); - w5->addSpacing(2); - - sortBox = new QComboBox(this); - sortBox->setEditable(true); - if (!sortItems.empty()) - sortBox->addItems(sortItems); - - sortBox->setMinimumSize(100, 10); - w5->addWidget(sortBox); - w5->addStretch(-1); - - if (!sortBox->currentText().isEmpty()) - fillPlugs(sortBox->currentText()); - else - fillPlugs(selectedPlugType); - - connect(pList, SIGNAL(itemDoubleClicked(QTreeWidgetItem*,int)), SLOT(accept())); - connect(pList, SIGNAL(itemClicked(QTreeWidgetItem*,int)), SLOT(enableOkB())); - connect(cancelB, SIGNAL(clicked()), SLOT(reject())); - connect(okB, SIGNAL(clicked()), SLOT(accept())); - connect(plugSel, SIGNAL(buttonClicked(QAbstractButton*)), SLOT(fillPlugs(QAbstractButton*))); - connect(sortBox, SIGNAL(editTextChanged(const QString&)),SLOT(fillPlugs(const QString&))); - sortBox->setFocus(); - } - -//--------------------------------------------------------- -// enableOkB -//--------------------------------------------------------- - -void PluginDialog::enableOkB() - { - okB->setEnabled(true); - } - -//--------------------------------------------------------- -// value -//--------------------------------------------------------- - -Plugin* PluginDialog::value() - { - QTreeWidgetItem* item = pList->currentItem(); - if (item) - return plugins.find(item->text(0), item->text(1)); - printf("plugin not found\n"); - return 0; - } - -//--------------------------------------------------------- -// accept -//--------------------------------------------------------- - -void PluginDialog::accept() - { - if (!sortBox->currentText().isEmpty()) { - foreach (QString item, sortItems) - if(item == sortBox->currentText()) { - QDialog::accept(); - return; - } - sortItems.push_front(sortBox->currentText()); - } - QDialog::accept(); - } - -//--------------------------------------------------------- -// fillPlugs -//--------------------------------------------------------- - -void PluginDialog::fillPlugs(QAbstractButton* ab) - { - if (ab == allPlug) - fillPlugs(SEL_ALL); - else if (ab == onlyM) - fillPlugs(SEL_M); - else if (ab == onlyS) - fillPlugs(SEL_S); - else if (ab == onlySM) - fillPlugs(SEL_SM); - } - -void PluginDialog::fillPlugs(int nbr) -{ - pList->clear(); - for (iPlugin i = plugins.begin(); i != plugins.end(); ++i) { - int ai = i->inports(); - int ao = i->outports(); - int ci = i->controlInPorts(); - int co = i->controlOutPorts(); - bool addFlag = false; - switch (nbr) { - case SEL_SM: // stereo & mono - if ((ai == 1 || ai == 2) && (ao == 1 || ao ==2)) { - addFlag = true; - } - break; - case SEL_S: // stereo - if ((ai == 1 || ai == 2) && ao ==2) { - addFlag = true; - } - break; - case SEL_M: // mono - if (ai == 1 && ao == 1) { - addFlag = true; - } - break; - case SEL_ALL: // all - addFlag = true; - break; - } - if (addFlag) { - QTreeWidgetItem* item = new QTreeWidgetItem; - item->setText(0, i->lib()); - item->setText(1, i->label()); - item->setText(2, i->name()); - item->setText(3, QString().setNum(ai)); - item->setText(4, QString().setNum(ao)); - item->setText(5, QString().setNum(ci)); - item->setText(6, QString().setNum(co)); - item->setText(7, QString().setNum(i->inPlaceCapable())); - item->setText(8, QString().setNum(i->id())); - item->setText(9, i->maker()); - item->setText(10, i->copyright()); - pList->addTopLevelItem(item); - } - } - selectedPlugType = nbr; -} - -void PluginDialog::fillPlugs(const QString &sortValue) -{ - pList->clear(); - for (iPlugin i = plugins.begin(); i != plugins.end(); ++i) { - int ai = i->inports(); - int ao = i->outports(); - int ci = i->controlInPorts(); - int co = i->controlOutPorts(); - - bool addFlag = false; - - if (i->label().toLower().contains(sortValue.toLower())) - addFlag = true; - else if (i->name().toLower().contains(sortValue.toLower())) - addFlag = true; - if (addFlag) { - QTreeWidgetItem* item = new QTreeWidgetItem; - item->setText(0, i->lib()); - item->setText(1, i->label()); - item->setText(2, i->name()); - item->setText(3, QString().setNum(ai)); - item->setText(4, QString().setNum(ao)); - item->setText(5, QString().setNum(ci)); - item->setText(6, QString().setNum(co)); - item->setText(7, QString().setNum(i->inPlaceCapable())); - item->setText(8, QString().setNum(i->id())); - item->setText(9, i->maker()); - item->setText(10, i->copyright()); - pList->addTopLevelItem(item); - } - } -} - -//--------------------------------------------------------- -// getPlugin -//--------------------------------------------------------- - -Plugin* PluginDialog::getPlugin(QWidget* parent) - { - PluginDialog* dialog = new PluginDialog(parent); - if (dialog->exec()) - return dialog->value(); - return 0; - } - -// TODO: We need to use .qrc files to use icons in WhatsThis bubbles. See Qt -// Resource System in Qt documentation - ORCAN -//const char* presetOpenText = "<img source=\"fileopen\"> " -// "Click this button to load a saved <em>preset</em>."; -const char* presetOpenText = "Click this button to load a saved <em>preset</em>."; -const char* presetSaveText = "Click this button to save curent parameter " - "settings as a <em>preset</em>. You will be prompted for a file name."; -const char* presetBypassText = "Click this button to bypass effect unit"; - -//--------------------------------------------------------- -// PluginGui -//--------------------------------------------------------- - -//PluginGui::PluginGui(PluginI* p) -// p3.3.43 -PluginGui::PluginGui(PluginIBase* p) - : QMainWindow(0) - { - gw = 0; - params = 0; - plugin = p; - setWindowTitle(plugin->name()); - - QToolBar* tools = addToolBar(tr("File Buttons")); - - QAction* fileOpen = new QAction(QIcon(*openIconS), tr("Load Preset"), this); - connect(fileOpen, SIGNAL(triggered()), this, SLOT(load())); - tools->addAction(fileOpen); - - QAction* fileSave = new QAction(QIcon(*saveIconS), tr("Save Preset"), this); - connect(fileSave, SIGNAL(triggered()), this, SLOT(save())); - tools->addAction(fileSave); - - tools->addAction(QWhatsThis::createAction(this)); - - onOff = new QAction(QIcon(*exitIconS), tr("bypass plugin"), this); - onOff->setCheckable(true); - onOff->setChecked(plugin->on()); - onOff->setToolTip(tr("bypass plugin")); - connect(onOff, SIGNAL(toggled(bool)), SLOT(bypassToggled(bool))); - tools->addAction(onOff); - - // TODO: We need to use .qrc files to use icons in WhatsThis bubbles. See Qt - // Resource System in Qt documentation - ORCAN - //Q3MimeSourceFactory::defaultFactory()->setPixmap(QString("fileopen"), *openIcon ); - fileOpen->setWhatsThis(tr(presetOpenText)); - onOff->setWhatsThis(tr(presetBypassText)); - fileSave->setWhatsThis(tr(presetSaveText)); - - QString id; - //id.setNum(plugin->plugin()->id()); - id.setNum(plugin->pluginID()); - QString name(museGlobalShare + QString("/plugins/") + id + QString(".ui")); - QFile uifile(name); - if (uifile.exists()) { - // - // construct GUI from *.ui file - // - PluginLoader loader; - QFile file(uifile.fileName()); - file.open(QFile::ReadOnly); - mw = loader.load(&file, this); - file.close(); - setCentralWidget(mw); - - QObjectList l = mw->children(); - QObject *obj; - - nobj = 0; - QList<QObject*>::iterator it; - for (it = l.begin(); it != l.end(); ++it) { - obj = *it; - QByteArray ba = obj->objectName().toLatin1(); - const char* name = ba.constData(); - if (*name !='P') - continue; - int parameter = -1; - sscanf(name, "P%d", ¶meter); - if (parameter == -1) - continue; - ++nobj; - } - it = l.begin(); - gw = new GuiWidgets[nobj]; - nobj = 0; - QSignalMapper* mapper = new QSignalMapper(this); - connect(mapper, SIGNAL(mapped(int)), SLOT(guiParamChanged(int))); - - QSignalMapper* mapperPressed = new QSignalMapper(this); - QSignalMapper* mapperReleased = new QSignalMapper(this); - connect(mapperPressed, SIGNAL(mapped(int)), SLOT(guiParamPressed(int))); - connect(mapperReleased, SIGNAL(mapped(int)), SLOT(guiParamReleased(int))); - - for (it = l.begin(); it != l.end(); ++it) { - obj = *it; - QByteArray ba = obj->objectName().toLatin1(); - const char* name = ba.constData(); - if (*name !='P') - continue; - int parameter = -1; - sscanf(name, "P%d", ¶meter); - if (parameter == -1) - continue; - - mapper->setMapping(obj, nobj); - mapperPressed->setMapping(obj, nobj); - mapperReleased->setMapping(obj, nobj); - - gw[nobj].widget = (QWidget*)obj; - gw[nobj].param = parameter; - gw[nobj].type = -1; - - if (strcmp(obj->metaObject()->className(), "Slider") == 0) { - gw[nobj].type = GuiWidgets::SLIDER; - ((Slider*)obj)->setId(nobj); - ((Slider*)obj)->setCursorHoming(true); - for(int i = 0; i < nobj; i++) - { - if(gw[i].type == GuiWidgets::DOUBLE_LABEL && gw[i].param == parameter) - ((DoubleLabel*)gw[i].widget)->setSlider((Slider*)obj); - } - connect(obj, SIGNAL(sliderMoved(double,int)), mapper, SLOT(map())); - connect(obj, SIGNAL(sliderPressed(int)), SLOT(guiSliderPressed(int))); - connect(obj, SIGNAL(sliderReleased(int)), SLOT(guiSliderReleased(int))); - connect(obj, SIGNAL(sliderRightClicked(const QPoint &, int)), SLOT(guiSliderRightClicked(const QPoint &, int))); - } - else if (strcmp(obj->metaObject()->className(), "DoubleLabel") == 0) { - gw[nobj].type = GuiWidgets::DOUBLE_LABEL; - ((DoubleLabel*)obj)->setId(nobj); - for(int i = 0; i < nobj; i++) - { - if(gw[i].type == GuiWidgets::SLIDER && gw[i].param == parameter) - { - ((DoubleLabel*)obj)->setSlider((Slider*)gw[i].widget); - break; - } - } - connect(obj, SIGNAL(valueChanged(double,int)), mapper, SLOT(map())); - } - else if (strcmp(obj->metaObject()->className(), "QCheckBox") == 0) { - gw[nobj].type = GuiWidgets::QCHECKBOX; - connect(obj, SIGNAL(toggled(bool)), mapper, SLOT(map())); - connect(obj, SIGNAL(pressed()), mapperPressed, SLOT(map())); - connect(obj, SIGNAL(released()), mapperReleased, SLOT(map())); - } - else if (strcmp(obj->metaObject()->className(), "QComboBox") == 0) { - gw[nobj].type = GuiWidgets::QCOMBOBOX; - connect(obj, SIGNAL(activated(int)), mapper, SLOT(map())); - } - else { - printf("unknown widget class %s\n", obj->metaObject()->className()); - continue; - } - ++nobj; - } - updateValues(); // otherwise the GUI won't have valid data - } - else { - //mw = new QWidget(this); - //setCentralWidget(mw); - // p3.4.43 - view = new QScrollArea; - view->setWidgetResizable(true); - setCentralWidget(view); - //view->setVScrollBarMode(QScrollView::AlwaysOff); - - mw = new QWidget; - QGridLayout* grid = new QGridLayout; - grid->setSpacing(2); - - mw->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding)); - - int n = plugin->parameters(); - params = new GuiParam[n]; - - // Changed p3.3.43 - //resize(280, n*20+30); - //int nh = n*20+40; - //if(nh > 760) - // nh = 760; - //resize(280, nh); - - //int style = Slider::BgTrough | Slider::BgSlot; - QFontMetrics fm = fontMetrics(); - int h = fm.height() + 4; - - for (int i = 0; i < n; ++i) { - QLabel* label = 0; - LADSPA_PortRangeHint range = plugin->range(i); - double lower = 0.0; // default values - double upper = 1.0; - double dlower = lower; - double dupper = upper; - double val = plugin->param(i); - double dval = val; - params[i].hint = range.HintDescriptor; - - if (LADSPA_IS_HINT_BOUNDED_BELOW(range.HintDescriptor)) { - dlower = lower = range.LowerBound; - } - if (LADSPA_IS_HINT_BOUNDED_ABOVE(range.HintDescriptor)) { - dupper = upper = range.UpperBound; - } - if (LADSPA_IS_HINT_SAMPLE_RATE(range.HintDescriptor)) { - lower *= sampleRate; - upper *= sampleRate; - dlower = lower; - dupper = upper; - } - if (LADSPA_IS_HINT_LOGARITHMIC(range.HintDescriptor)) { - if (lower == 0.0) - lower = 0.001; - dlower = fast_log10(lower)*20.0; - dupper = fast_log10(upper)*20.0; - dval = fast_log10(val) * 20.0; - } - if (LADSPA_IS_HINT_TOGGLED(range.HintDescriptor)) { - params[i].type = GuiParam::GUI_SWITCH; - CheckBox* cb = new CheckBox(mw, i, "param"); - cb->setId(i); - cb->setText(QString(plugin->paramName(i))); - cb->setChecked(plugin->param(i) != 0.0); - cb->setFixedHeight(h); - params[i].actuator = cb; - } - else { - label = new QLabel(QString(plugin->paramName(i)), 0); - params[i].type = GuiParam::GUI_SLIDER; - params[i].label = new DoubleLabel(val, lower, upper, 0); - params[i].label->setFrame(true); - params[i].label->setPrecision(2); - params[i].label->setId(i); - - //params[i].label->setContentsMargins(2, 2, 2, 2); - //params[i].label->setFixedHeight(h); - - Slider* s = new Slider(0, "param", Qt::Horizontal, - Slider::None); //, style); - - s->setCursorHoming(true); - s->setId(i); - //s->setFixedHeight(h); - s->setRange(dlower, dupper); - if(LADSPA_IS_HINT_INTEGER(range.HintDescriptor)) - s->setStep(1.0); - s->setValue(dval); - params[i].actuator = s; - params[i].label->setSlider((Slider*)params[i].actuator); - } - //params[i].actuator->setSizePolicy(QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Maximum)); - params[i].actuator->setSizePolicy(QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed)); - if (params[i].type == GuiParam::GUI_SLIDER) { - //label->setFixedHeight(20); - //label->setSizePolicy(QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Maximum)); - label->setSizePolicy(QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed)); - //params[i].label->setSizePolicy(QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Maximum)); - params[i].label->setSizePolicy(QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed)); - grid->addWidget(label, i, 0); - grid->addWidget(params[i].label, i, 1); - grid->addWidget(params[i].actuator, i, 2); - } - else if (params[i].type == GuiParam::GUI_SWITCH) { - //grid->addMultiCellWidget(params[i].actuator, i, i, 0, 2); - grid->addWidget(params[i].actuator, i, 0, 1, 3); - } - if (params[i].type == GuiParam::GUI_SLIDER) { - connect(params[i].actuator, SIGNAL(sliderMoved(double,int)), SLOT(sliderChanged(double,int))); - connect(params[i].label, SIGNAL(valueChanged(double,int)), SLOT(labelChanged(double,int))); - connect(params[i].actuator, SIGNAL(sliderPressed(int)), SLOT(ctrlPressed(int))); - connect(params[i].actuator, SIGNAL(sliderReleased(int)), SLOT(ctrlReleased(int))); - connect(params[i].actuator, SIGNAL(sliderRightClicked(const QPoint &, int)), SLOT(ctrlRightClicked(const QPoint &, int))); - } - else if (params[i].type == GuiParam::GUI_SWITCH){ - connect(params[i].actuator, SIGNAL(checkboxPressed(int)), SLOT(ctrlPressed(int))); - connect(params[i].actuator, SIGNAL(checkboxReleased(int)), SLOT(ctrlReleased(int))); - connect(params[i].actuator, SIGNAL(checkboxRightClicked(const QPoint &, int)), SLOT(ctrlRightClicked(const QPoint &, int))); - } - } - // p3.3.43 - resize(280, height()); - - grid->setColumnStretch(2, 10); - mw->setLayout(grid); - view->setWidget(mw); - } - connect(heartBeatTimer, SIGNAL(timeout()), SLOT(heartBeat())); - } - -//--------------------------------------------------------- -// PluginGui -//--------------------------------------------------------- - -PluginGui::~PluginGui() - { - if (gw) - delete[] gw; - if (params) - delete[] params; - } - -//--------------------------------------------------------- -// heartBeat -//--------------------------------------------------------- - -void PluginGui::heartBeat() -{ - updateControls(); -} - -//--------------------------------------------------------- -// ctrlPressed -//--------------------------------------------------------- - -void PluginGui::ctrlPressed(int param) -{ - AutomationType at = AUTO_OFF; - AudioTrack* track = plugin->track(); - if(track) - at = track->automationType(); - - if(at != AUTO_OFF) - plugin->enableController(param, false); - - int id = plugin->id(); - - if(id == -1) - return; - - id = genACnum(id, param); - - if(params[param].type == GuiParam::GUI_SLIDER) - { - double val = ((Slider*)params[param].actuator)->value(); - if (LADSPA_IS_HINT_LOGARITHMIC(params[param].hint)) - val = pow(10.0, val/20.0); - else if (LADSPA_IS_HINT_INTEGER(params[param].hint)) - val = rint(val); - plugin->setParam(param, val); - ((DoubleLabel*)params[param].label)->setValue(val); - - // p3.3.43 - //audio->msgSetPluginCtrlVal(((PluginI*)plugin), id, val); - - if(track) - { - // p3.3.43 - audio->msgSetPluginCtrlVal(track, id, val); - - track->startAutoRecord(id, val); - } - } - else if(params[param].type == GuiParam::GUI_SWITCH) - { - double val = (double)((CheckBox*)params[param].actuator)->isChecked(); - plugin->setParam(param, val); - - // p3.3.43 - //audio->msgSetPluginCtrlVal(((PluginI*)plugin), id, val); - - if(track) - { - // p3.3.43 - audio->msgSetPluginCtrlVal(track, id, val); - - track->startAutoRecord(id, val); - } - } -} - -//--------------------------------------------------------- -// ctrlReleased -//--------------------------------------------------------- - -void PluginGui::ctrlReleased(int param) -{ - AutomationType at = AUTO_OFF; - AudioTrack* track = plugin->track(); - if(track) - at = track->automationType(); - - // Special for switch - don't enable controller until transport stopped. - if(at != AUTO_WRITE && ((params[param].type != GuiParam::GUI_SWITCH - || !audio->isPlaying() - || at != AUTO_TOUCH) || (!audio->isPlaying() && at == AUTO_TOUCH)) ) - plugin->enableController(param, true); - - int id = plugin->id(); - if(!track || id == -1) - return; - id = genACnum(id, param); - - if(params[param].type == GuiParam::GUI_SLIDER) - { - double val = ((Slider*)params[param].actuator)->value(); - if (LADSPA_IS_HINT_LOGARITHMIC(params[param].hint)) - val = pow(10.0, val/20.0); - else if (LADSPA_IS_HINT_INTEGER(params[param].hint)) - val = rint(val); - track->stopAutoRecord(id, val); - } - //else if(params[param].type == GuiParam::GUI_SWITCH) - //{ - //double val = (double)((CheckBox*)params[param].actuator)->isChecked(); - // No concept of 'untouching' a checkbox. Remain 'touched' until stop. - //plugin->track()->stopAutoRecord(genACnum(plugin->id(), param), val); - //} -} - -//--------------------------------------------------------- -// ctrlRightClicked -//--------------------------------------------------------- - -void PluginGui::ctrlRightClicked(const QPoint &p, int param) -{ - int id = plugin->id(); - if(id != -1) - //song->execAutomationCtlPopup((AudioTrack*)plugin->track(), p, genACnum(id, param)); - song->execAutomationCtlPopup(plugin->track(), p, genACnum(id, param)); -} - -//--------------------------------------------------------- -// sliderChanged -//--------------------------------------------------------- - -void PluginGui::sliderChanged(double val, int param) -{ - AutomationType at = AUTO_OFF; - AudioTrack* track = plugin->track(); - if(track) - at = track->automationType(); - - if(at == AUTO_WRITE || (audio->isPlaying() && at == AUTO_TOUCH)) - plugin->enableController(param, false); - - if (LADSPA_IS_HINT_LOGARITHMIC(params[param].hint)) - val = pow(10.0, val/20.0); - else if (LADSPA_IS_HINT_INTEGER(params[param].hint)) - val = rint(val); - if (plugin->param(param) != val) { - plugin->setParam(param, val); - ((DoubleLabel*)params[param].label)->setValue(val); - } - - int id = plugin->id(); - if(id == -1) - return; - id = genACnum(id, param); - - // p3.3.43 - //audio->msgSetPluginCtrlVal(((PluginI*)plugin), id, val); - - if(track) - { - // p3.3.43 - audio->msgSetPluginCtrlVal(track, id, val); - - track->recordAutomation(id, val); - } -} - -//--------------------------------------------------------- -// labelChanged -//--------------------------------------------------------- - -void PluginGui::labelChanged(double val, int param) -{ - AutomationType at = AUTO_OFF; - AudioTrack* track = plugin->track(); - if(track) - at = track->automationType(); - - if(at == AUTO_WRITE || (audio->isPlaying() && at == AUTO_TOUCH)) - plugin->enableController(param, false); - - double dval = val; - if (LADSPA_IS_HINT_LOGARITHMIC(params[param].hint)) - dval = fast_log10(val) * 20.0; - else if (LADSPA_IS_HINT_INTEGER(params[param].hint)) - dval = rint(val); - if (plugin->param(param) != val) { - plugin->setParam(param, val); - ((Slider*)params[param].actuator)->setValue(dval); - } - - int id = plugin->id(); - if(id == -1) - return; - - id = genACnum(id, param); - - // p3.3.43 - //audio->msgSetPluginCtrlVal(((PluginI*)plugin), id, val); - - if(track) - { - // p3.3.43 - audio->msgSetPluginCtrlVal(track, id, val); - - track->startAutoRecord(id, val); - } -} - -//--------------------------------------------------------- -// load -//--------------------------------------------------------- - -void PluginGui::load() - { - QString s("presets/plugins/"); - //s += plugin->plugin()->label(); - s += plugin->pluginLabel(); - s += "/"; - - QString fn = getOpenFileName(s, preset_file_pattern, - this, tr("MusE: load preset"), 0); - if (fn.isEmpty()) - return; - bool popenFlag; - FILE* f = fileOpen(this, fn, QString(".pre"), "r", popenFlag, true); - if (f == 0) - return; - - Xml xml(f); - int mode = 0; - for (;;) { - Xml::Token token = xml.parse(); - QString tag = xml.s1(); - switch (token) { - case Xml::Error: - case Xml::End: - return; - case Xml::TagStart: - if (mode == 0 && tag == "muse") - mode = 1; - else if (mode == 1 && tag == "plugin") { - - if(plugin->readConfiguration(xml, true)) - { - QMessageBox::critical(this, QString("MusE"), - tr("Error reading preset. Might not be right type for this plugin")); - goto ende; - } - - mode = 0; - } - else - xml.unknown("PluginGui"); - break; - case Xml::Attribut: - break; - case Xml::TagEnd: - if (!mode && tag == "muse") - { - plugin->updateControllers(); - goto ende; - } - default: - break; - } - } -ende: - if (popenFlag) - pclose(f); - else - fclose(f); - } - -//--------------------------------------------------------- -// save -//--------------------------------------------------------- - -void PluginGui::save() - { - QString s("presets/plugins/"); - //s += plugin->plugin()->label(); - s += plugin->pluginLabel(); - s += "/"; - - //QString fn = getSaveFileName(s, preset_file_pattern, this, - QString fn = getSaveFileName(s, preset_file_save_pattern, this, - tr("MusE: save preset")); - if (fn.isEmpty()) - return; - bool popenFlag; - FILE* f = fileOpen(this, fn, QString(".pre"), "w", popenFlag, false, true); - if (f == 0) - return; - Xml xml(f); - xml.header(); - xml.tag(0, "muse version=\"1.0\""); - plugin->writeConfiguration(1, xml); - xml.tag(1, "/muse"); - - if (popenFlag) - pclose(f); - else - fclose(f); - } - -//--------------------------------------------------------- -// bypassToggled -//--------------------------------------------------------- - -void PluginGui::bypassToggled(bool val) - { - plugin->setOn(val); - song->update(SC_ROUTE); - } - -//--------------------------------------------------------- -// songChanged -//--------------------------------------------------------- - -void PluginGui::setOn(bool val) - { - onOff->blockSignals(true); - onOff->setChecked(val); - onOff->blockSignals(false); - } - -//--------------------------------------------------------- -// updateValues -//--------------------------------------------------------- - -void PluginGui::updateValues() - { - if (params) { - for (int i = 0; i < plugin->parameters(); ++i) { - GuiParam* gp = ¶ms[i]; - if (gp->type == GuiParam::GUI_SLIDER) { - double lv = plugin->param(i); - double sv = lv; - if (LADSPA_IS_HINT_LOGARITHMIC(params[i].hint)) - sv = fast_log10(lv) * 20.0; - else if (LADSPA_IS_HINT_INTEGER(params[i].hint)) - { - sv = rint(lv); - lv = sv; - } - gp->label->setValue(lv); - ((Slider*)(gp->actuator))->setValue(sv); - } - else if (gp->type == GuiParam::GUI_SWITCH) { - ((CheckBox*)(gp->actuator))->setChecked(int(plugin->param(i))); - } - } - } - else if (gw) { - for (int i = 0; i < nobj; ++i) { - QWidget* widget = gw[i].widget; - int type = gw[i].type; - int param = gw[i].param; - double val = plugin->param(param); - switch(type) { - case GuiWidgets::SLIDER: - ((Slider*)widget)->setValue(val); - break; - case GuiWidgets::DOUBLE_LABEL: - ((DoubleLabel*)widget)->setValue(val); - break; - case GuiWidgets::QCHECKBOX: - ((QCheckBox*)widget)->setChecked(int(val)); - break; - case GuiWidgets::QCOMBOBOX: - ((QComboBox*)widget)->setCurrentIndex(int(val)); - break; - } - } - } - } - -//--------------------------------------------------------- -// updateControls -//--------------------------------------------------------- - -void PluginGui::updateControls() - { - if(!automation || !plugin->track() || plugin->id() == -1) - return; - AutomationType at = plugin->track()->automationType(); - if(at == AUTO_OFF) - return; - if (params) { - for (int i = 0; i < plugin->parameters(); ++i) { - GuiParam* gp = ¶ms[i]; - if (gp->type == GuiParam::GUI_SLIDER) { - if( plugin->controllerEnabled(i) && plugin->controllerEnabled2(i) ) - { - double lv = plugin->track()->pluginCtrlVal(genACnum(plugin->id(), i)); - double sv = lv; - if (LADSPA_IS_HINT_LOGARITHMIC(params[i].hint)) - sv = fast_log10(lv) * 20.0; - else - if (LADSPA_IS_HINT_INTEGER(params[i].hint)) - { - sv = rint(lv); - lv = sv; - } - if(((Slider*)(gp->actuator))->value() != sv) - { - //printf("PluginGui::updateControls slider\n"); - - gp->label->blockSignals(true); - ((Slider*)(gp->actuator))->blockSignals(true); - ((Slider*)(gp->actuator))->setValue(sv); - gp->label->setValue(lv); - ((Slider*)(gp->actuator))->blockSignals(false); - gp->label->blockSignals(false); - } - } - - } - else if (gp->type == GuiParam::GUI_SWITCH) { - if( plugin->controllerEnabled(i) && plugin->controllerEnabled2(i) ) - { - bool v = (int)plugin->track()->pluginCtrlVal(genACnum(plugin->id(), i)); - if(((CheckBox*)(gp->actuator))->isChecked() != v) - { - //printf("PluginGui::updateControls switch\n"); - - ((CheckBox*)(gp->actuator))->blockSignals(true); - ((CheckBox*)(gp->actuator))->setChecked(v); - ((CheckBox*)(gp->actuator))->blockSignals(false); - } - } - } - } - } - else if (gw) { - for (int i = 0; i < nobj; ++i) { - QWidget* widget = gw[i].widget; - int type = gw[i].type; - int param = gw[i].param; - switch(type) { - case GuiWidgets::SLIDER: - if( plugin->controllerEnabled(param) && plugin->controllerEnabled2(param) ) - { - double v = plugin->track()->pluginCtrlVal(genACnum(plugin->id(), param)); - if(((Slider*)widget)->value() != v) - { - //printf("PluginGui::updateControls slider\n"); - - ((Slider*)widget)->blockSignals(true); - ((Slider*)widget)->setValue(v); - ((Slider*)widget)->blockSignals(false); - } - } - break; - case GuiWidgets::DOUBLE_LABEL: - if( plugin->controllerEnabled(param) && plugin->controllerEnabled2(param) ) - { - double v = plugin->track()->pluginCtrlVal(genACnum(plugin->id(), param)); - if(((DoubleLabel*)widget)->value() != v) - { - //printf("PluginGui::updateControls label\n"); - - ((DoubleLabel*)widget)->blockSignals(true); - ((DoubleLabel*)widget)->setValue(v); - ((DoubleLabel*)widget)->blockSignals(false); - } - } - break; - case GuiWidgets::QCHECKBOX: - if( plugin->controllerEnabled(param) && plugin->controllerEnabled2(param) ) - { - bool b = (bool) plugin->track()->pluginCtrlVal(genACnum(plugin->id(), param)); - if(((QCheckBox*)widget)->isChecked() != b) - { - //printf("PluginGui::updateControls checkbox\n"); - - ((QCheckBox*)widget)->blockSignals(true); - ((QCheckBox*)widget)->setChecked(b); - ((QCheckBox*)widget)->blockSignals(false); - } - } - break; - case GuiWidgets::QCOMBOBOX: - if( plugin->controllerEnabled(param) && plugin->controllerEnabled2(param) ) - { - int n = (int) plugin->track()->pluginCtrlVal(genACnum(plugin->id(), param)); - if(((QComboBox*)widget)->currentIndex() != n) - { - //printf("PluginGui::updateControls combobox\n"); - - ((QComboBox*)widget)->blockSignals(true); - ((QComboBox*)widget)->setCurrentIndex(n); - ((QComboBox*)widget)->blockSignals(false); - } - } - break; - } - } - } - } - -//--------------------------------------------------------- -// guiParamChanged -//--------------------------------------------------------- - -void PluginGui::guiParamChanged(int idx) -{ - QWidget* w = gw[idx].widget; - int param = gw[idx].param; - int type = gw[idx].type; - - AutomationType at = AUTO_OFF; - AudioTrack* track = plugin->track(); - if(track) - at = track->automationType(); - - if(at == AUTO_WRITE || (audio->isPlaying() && at == AUTO_TOUCH)) - plugin->enableController(param, false); - - double val = 0.0; - switch(type) { - case GuiWidgets::SLIDER: - val = ((Slider*)w)->value(); - break; - case GuiWidgets::DOUBLE_LABEL: - val = ((DoubleLabel*)w)->value(); - break; - case GuiWidgets::QCHECKBOX: - val = double(((QCheckBox*)w)->isChecked()); - break; - case GuiWidgets::QCOMBOBOX: - val = double(((QComboBox*)w)->currentIndex()); - break; - } - - for (int i = 0; i < nobj; ++i) { - QWidget* widget = gw[i].widget; - if (widget == w || param != gw[i].param) - continue; - int type = gw[i].type; - switch(type) { - case GuiWidgets::SLIDER: - ((Slider*)widget)->setValue(val); - break; - case GuiWidgets::DOUBLE_LABEL: - ((DoubleLabel*)widget)->setValue(val); - break; - case GuiWidgets::QCHECKBOX: - ((QCheckBox*)widget)->setChecked(int(val)); - break; - case GuiWidgets::QCOMBOBOX: - ((QComboBox*)widget)->setCurrentIndex(int(val)); - break; - } - } - - int id = plugin->id(); - if(track && id != -1) - { - id = genACnum(id, param); - - // p3.3.43 - //audio->msgSetPluginCtrlVal(((PluginI*)plugin), id, val); - - //if(track) - //{ - // p3.3.43 - audio->msgSetPluginCtrlVal(track, id, val); - - switch(type) - { - case GuiWidgets::DOUBLE_LABEL: - case GuiWidgets::QCHECKBOX: - track->startAutoRecord(id, val); - break; - default: - track->recordAutomation(id, val); - break; - } - //} - } - plugin->setParam(param, val); -} - -//--------------------------------------------------------- -// guiParamPressed -//--------------------------------------------------------- - -void PluginGui::guiParamPressed(int idx) - { - int param = gw[idx].param; - - AutomationType at = AUTO_OFF; - AudioTrack* track = plugin->track(); - if(track) - at = track->automationType(); - - if(at != AUTO_OFF) - plugin->enableController(param, false); - - int id = plugin->id(); - if(!track || id == -1) - return; - - id = genACnum(id, param); - - // NOTE: For this to be of any use, the freeverb gui 2142.ui - // would have to be used, and changed to use CheckBox and ComboBox - // instead of QCheckBox and QComboBox, since both of those would - // need customization (Ex. QCheckBox doesn't check on click). - /* - switch(type) { - case GuiWidgets::QCHECKBOX: - double val = (double)((CheckBox*)w)->isChecked(); - track->startAutoRecord(id, val); - break; - case GuiWidgets::QCOMBOBOX: - double val = (double)((ComboBox*)w)->currentIndex(); - track->startAutoRecord(id, val); - break; - } - */ - } - -//--------------------------------------------------------- -// guiParamReleased -//--------------------------------------------------------- - -void PluginGui::guiParamReleased(int idx) - { - int param = gw[idx].param; - int type = gw[idx].type; - - AutomationType at = AUTO_OFF; - AudioTrack* track = plugin->track(); - if(track) - at = track->automationType(); - - // Special for switch - don't enable controller until transport stopped. - if(at != AUTO_WRITE && (type != GuiWidgets::QCHECKBOX - || !audio->isPlaying() - || at != AUTO_TOUCH)) - plugin->enableController(param, true); - - int id = plugin->id(); - - if(!track || id == -1) - return; - - id = genACnum(id, param); - - // NOTE: For this to be of any use, the freeverb gui 2142.ui - // would have to be used, and changed to use CheckBox and ComboBox - // instead of QCheckBox and QComboBox, since both of those would - // need customization (Ex. QCheckBox doesn't check on click). - /* - switch(type) { - case GuiWidgets::QCHECKBOX: - double val = (double)((CheckBox*)w)->isChecked(); - track->stopAutoRecord(id, param); - break; - case GuiWidgets::QCOMBOBOX: - double val = (double)((ComboBox*)w)->currentIndex(); - track->stopAutoRecord(id, param); - break; - } - */ - } - -//--------------------------------------------------------- -// guiSliderPressed -//--------------------------------------------------------- - -void PluginGui::guiSliderPressed(int idx) - { - int param = gw[idx].param; - QWidget *w = gw[idx].widget; - - AutomationType at = AUTO_OFF; - AudioTrack* track = plugin->track(); - if(track) - at = track->automationType(); - - int id = plugin->id(); - - if(at == AUTO_WRITE || (at == AUTO_READ || at == AUTO_TOUCH)) - plugin->enableController(param, false); - - if(!track || id == -1) - return; - - id = genACnum(id, param); - - double val = ((Slider*)w)->value(); - plugin->setParam(param, val); - - //audio->msgSetPluginCtrlVal(((PluginI*)plugin), id, val); - // p3.3.43 - audio->msgSetPluginCtrlVal(track, id, val); - - track->startAutoRecord(id, val); - - // Needed so that paging a slider updates a label or other buddy control. - for (int i = 0; i < nobj; ++i) { - QWidget* widget = gw[i].widget; - if (widget == w || param != gw[i].param) - continue; - int type = gw[i].type; - switch(type) { - case GuiWidgets::SLIDER: - ((Slider*)widget)->setValue(val); - break; - case GuiWidgets::DOUBLE_LABEL: - ((DoubleLabel*)widget)->setValue(val); - break; - case GuiWidgets::QCHECKBOX: - ((QCheckBox*)widget)->setChecked(int(val)); - break; - case GuiWidgets::QCOMBOBOX: - ((QComboBox*)widget)->setCurrentIndex(int(val)); - break; - } - } - } - -//--------------------------------------------------------- -// guiSliderReleased -//--------------------------------------------------------- - -void PluginGui::guiSliderReleased(int idx) - { - int param = gw[idx].param; - QWidget *w = gw[idx].widget; - - AutomationType at = AUTO_OFF; - AudioTrack* track = plugin->track(); - if(track) - at = track->automationType(); - - if(at != AUTO_WRITE || (!audio->isPlaying() && at == AUTO_TOUCH)) - plugin->enableController(param, true); - - int id = plugin->id(); - - if(!track || id == -1) - return; - - id = genACnum(id, param); - - double val = ((Slider*)w)->value(); - track->stopAutoRecord(id, val); - } - -//--------------------------------------------------------- -// guiSliderRightClicked -//--------------------------------------------------------- - -void PluginGui::guiSliderRightClicked(const QPoint &p, int idx) -{ - int param = gw[idx].param; - int id = plugin->id(); - if(id != -1) - //song->execAutomationCtlPopup((AudioTrack*)plugin->track(), p, genACnum(id, param)); - song->execAutomationCtlPopup(plugin->track(), p, genACnum(id, param)); -} - -//--------------------------------------------------------- -// PluginLoader -//--------------------------------------------------------- -QWidget* PluginLoader::createWidget(const QString & className, QWidget * parent, const QString & name) -{ - if(className == QString("DoubleLabel")) - return new DoubleLabel(parent, name.toLatin1().constData()); - if(className == QString("Slider")) - return new Slider(parent, name.toLatin1().constData(), Qt::Horizontal); - - return QUiLoader::createWidget(className, parent, name); -}; |