From d8ac618f4dc9afd0731a9a3531d4641c9e7ea6fd Mon Sep 17 00:00:00 2001 From: Robert Jonsson Date: Wed, 27 Apr 2011 18:41:35 +0000 Subject: feedback parameters --- muse2/ChangeLog | 2 + muse2/muse/dssihost.cpp | 22 ++++ muse2/muse/dssihost.h | 8 +- muse2/muse/mixer/CMakeLists.txt | 2 - muse2/muse/mixer/meter.cpp | 217 ----------------------------------- muse2/muse/mixer/meter.h | 48 -------- muse2/muse/plugin.cpp | 138 ++++++++++++++++------ muse2/muse/plugin.h | 25 ++-- muse2/muse/widgets/CMakeLists.txt | 8 +- muse2/muse/widgets/meter.cpp | 217 +++++++++++++++++++++++++++++++++++ muse2/muse/widgets/meter.h | 49 ++++++++ muse2/muse/widgets/verticalmeter.cpp | 209 +++++++++++++++++++++++++++++++++ muse2/muse/widgets/verticalmeter.h | 43 +++++++ 13 files changed, 677 insertions(+), 311 deletions(-) delete mode 100644 muse2/muse/mixer/meter.cpp delete mode 100644 muse2/muse/mixer/meter.h create mode 100644 muse2/muse/widgets/meter.cpp create mode 100644 muse2/muse/widgets/meter.h create mode 100644 muse2/muse/widgets/verticalmeter.cpp create mode 100644 muse2/muse/widgets/verticalmeter.h (limited to 'muse2') diff --git a/muse2/ChangeLog b/muse2/ChangeLog index 95cc84b3..377a246e 100644 --- a/muse2/ChangeLog +++ b/muse2/ChangeLog @@ -1,3 +1,5 @@ +27.04.2011: + - added first version feedback parameters for plugins (rj) 25.04.2011: - added a songChanged at the end of clear when loading a new song, intended effect was to clear GUI before loading new song to fix some nasty crashes, seems to work (rj) diff --git a/muse2/muse/dssihost.cpp b/muse2/muse/dssihost.cpp index b91000be..0bf97bd4 100644 --- a/muse2/muse/dssihost.cpp +++ b/muse2/muse/dssihost.cpp @@ -1366,6 +1366,23 @@ float DssiSynthIF::getParameter(unsigned long n) const return controls[n].val; } +//--------------------------------------------------------- +// getParameter +//--------------------------------------------------------- + +float DssiSynthIF::getParameterOut(unsigned long n) const +{ + if(n >= synth->_controlOutPorts) + { + printf("DssiSynthIF::getParameter param number %ld out of range of ports:%ld\n", n, synth->_controlOutPorts); + return 0.0; + } + + if(!controlsOut) + return 0.0; + + return controlsOut[n].val; +} //--------------------------------------------------------- // setParameter @@ -3494,6 +3511,7 @@ bool DssiSynthIF::controllerEnabled2(unsigned i) const { return controls[i void DssiSynthIF::updateControllers() { } void DssiSynthIF::writeConfiguration(int /*level*/, Xml& /*xml*/) { } bool DssiSynthIF::readConfiguration(Xml& /*xml*/, bool /*readPreset*/) { return false; } + //int DssiSynthIF::parameters() const { return synth ? synth->_controlInPorts : 0; } //void DssiSynthIF::setParam(int i, double val) { setParameter(i, val); } //double DssiSynthIF::param(int i) const { return getParameter(i); } @@ -3501,11 +3519,15 @@ bool DssiSynthIF::readConfiguration(Xml& /*xml*/, bool /*readPreset*/) { return //LADSPA_PortRangeHint DssiSynthIF::range(int i) { return (synth && synth->dssi) ? synth->dssi->LADSPA_Plugin->PortRangeHints[i] : 0; } //LADSPA_PortRangeHint DssiSynthIF::range(int i) { return synth->dssi->LADSPA_Plugin->PortRangeHints[controls[i].idx]; } unsigned DssiSynthIF::parameters() const { return synth ? synth->_controlInPorts : 0; } +unsigned DssiSynthIF::parametersOut() const { return synth ? synth->_controlOutPorts : 0; } void DssiSynthIF::setParam(unsigned i, float val) { setParameter(i, val); } float DssiSynthIF::param(unsigned i) const { return getParameter(i); } +float DssiSynthIF::paramOut(unsigned i) const { return getParameter(i); } const char* DssiSynthIF::paramName(unsigned i) { return (synth && synth->dssi) ? synth->dssi->LADSPA_Plugin->PortNames[controls[i].idx] : 0; } +const char* DssiSynthIF::paramOutName(unsigned i) { return (synth && synth->dssi) ? synth->dssi->LADSPA_Plugin->PortNames[controlsOut[i].idx] : 0; } //LADSPA_PortRangeHint DssiSynthIF::range(unsigned i) { return (synth && synth->dssi) ? synth->dssi->LADSPA_Plugin->PortRangeHints[i] : 0; } LADSPA_PortRangeHint DssiSynthIF::range(unsigned i) { return synth->dssi->LADSPA_Plugin->PortRangeHints[controls[i].idx]; } +LADSPA_PortRangeHint DssiSynthIF::rangeOut(unsigned i) { return synth->dssi->LADSPA_Plugin->PortRangeHints[controlsOut[i].idx]; } #else //DSSI_SUPPORT diff --git a/muse2/muse/dssihost.h b/muse2/muse/dssihost.h index 27c0eae4..2405b1cc 100644 --- a/muse2/muse/dssihost.h +++ b/muse2/muse/dssihost.h @@ -205,6 +205,7 @@ class DssiSynthIF : public SynthIF, public PluginIBase virtual void write(int level, Xml& xml) const; virtual float getParameter(unsigned long /*idx*/) const; + virtual float getParameterOut(unsigned long n) const; virtual void setParameter(unsigned long /*idx*/, float /*value*/); //virtual int getControllerInfo(int, const char**, int*, int*, int*) { return 0; } @@ -256,16 +257,21 @@ class DssiSynthIF : public SynthIF, public PluginIBase void updateControllers(); void writeConfiguration(int /*level*/, Xml& /*xml*/); bool readConfiguration(Xml& /*xml*/, bool readPreset=false); + //int parameters() const; //void setParam(int /*i*/, double /*val*/); //double param(int /*i*/) const; //const char* paramName(int /*i*/); //LADSPA_PortRangeHint range(int /*i*/); unsigned parameters() const; // p4.0.21 + unsigned parametersOut() const; void setParam(unsigned /*i*/, float /*val*/); float param(unsigned /*i*/) const; + float paramOut(unsigned /*i*/) const; const char* paramName(unsigned /*i*/); - LADSPA_PortRangeHint range(unsigned /*i*/); + const char* paramOutName(unsigned /*i*/); + LADSPA_PortRangeHint range(unsigned /*i*/); + LADSPA_PortRangeHint rangeOut(unsigned /*i*/); friend class DssiSynth; }; diff --git a/muse2/muse/mixer/CMakeLists.txt b/muse2/muse/mixer/CMakeLists.txt index e313f44d..3d76ebd6 100644 --- a/muse2/muse/mixer/CMakeLists.txt +++ b/muse2/muse/mixer/CMakeLists.txt @@ -25,7 +25,6 @@ QT4_WRAP_CPP ( mixer_mocs amixer.h astrip.h auxknob.h - meter.h mstrip.h panknob.h rack.h @@ -48,7 +47,6 @@ file (GLOB mixer_source_files amixer.cpp astrip.cpp auxknob.cpp - meter.cpp mstrip.cpp panknob.cpp rack.cpp diff --git a/muse2/muse/mixer/meter.cpp b/muse2/muse/mixer/meter.cpp deleted file mode 100644 index eb214e77..00000000 --- a/muse2/muse/mixer/meter.cpp +++ /dev/null @@ -1,217 +0,0 @@ -//========================================================= -// MusE -// Linux Music Editor -// $Id: meter.cpp,v 1.4.2.2 2009/05/03 04:14:00 terminator356 Exp $ -// -// (C) Copyright 2000 Werner Schweer (ws@seh.de) -//========================================================= - -#include -#include - -#include -#include -#include - -#include "meter.h" -#include "gconfig.h" -#include "fastlog.h" - -//--------------------------------------------------------- -// Meter -//--------------------------------------------------------- - -Meter::Meter(QWidget* parent, MeterType type) - : QFrame(parent) //Qt::WNoAutoErase - { - setBackgroundRole(QPalette::NoRole); - setAttribute(Qt::WA_NoSystemBackground); - setAttribute(Qt::WA_StaticContents); - // This is absolutely required for speed! Otherwise painfully slow because we get - // full rect paint events even on small scrolls! See help on QPainter::scroll(). - setAttribute(Qt::WA_OpaquePaintEvent); - - mtype = type; - overflow = false; - val = 0.0; - maxVal = 0.0; - minScale = mtype == DBMeter ? config.minMeter : 0.0; // min value in dB or int - maxScale = mtype == DBMeter ? 10.0 : 127.0; - yellowScale = -10; - redScale = 0; - setLineWidth(0); - setMidLineWidth(0); - } - -//--------------------------------------------------------- -// setVal -//--------------------------------------------------------- - -void Meter::setVal(double v, double max, bool ovl) - { - overflow = ovl; - bool ud = false; - - if(mtype == DBMeter) - { - double minScaleLin = pow(10.0, minScale/20.0); - if((v >= minScaleLin && val != v) || val >= minScaleLin) - { - val = v; - ud = true; - } - } - else - { - if(val != v) - { - val = v; - ud = true; - } - } - - if(maxVal != max) - { - maxVal = max; - ud = true; - } - - if(ud) - update(); - } -//--------------------------------------------------------- -// resetPeaks -// reset peak and overflow indicator -//--------------------------------------------------------- - -void Meter::resetPeaks() - { - maxVal = val; - overflow = val > 0.0; - update(); - } - -//--------------------------------------------------------- -// setRange -//--------------------------------------------------------- - -void Meter::setRange(double min, double max) - { - minScale = min; - maxScale = max; - update(); - } - -//--------------------------------------------------------- -// paintEvent -//--------------------------------------------------------- - -void Meter::paintEvent(QPaintEvent* /*ev*/) - { - // TODO: Could make better use of event rectangle, for speed. - - QPainter p(this); - - double range = maxScale - minScale; - - int fw = frameWidth(); - int w = width() - 2*fw; - int h = height() - 2*fw; - int yv; - - if(mtype == DBMeter) - yv = val == 0 ? h : int(((maxScale - (fast_log10(val) * 20.0)) * h)/range); - else - yv = val == 0 ? h : int(((maxScale - val) * h)/range); - - if(yv > h) yv = h; - - // Draw the red, green, and yellow sections. - drawVU(p, w, h, yv); - - // Draw the peak white line. - int ymax; - if(mtype == DBMeter) - ymax = maxVal == 0 ? 0 : int(((maxScale - (fast_log10(maxVal) * 20.0)) * h)/range); - else - ymax = maxVal == 0 ? 0 : int(((maxScale - maxVal) * h)/range); - p.setPen(Qt::white); - p.drawLine(0, ymax, w, ymax); - } - -//--------------------------------------------------------- -// drawVU -//--------------------------------------------------------- - -void Meter::drawVU(QPainter& p, int w, int h, int yv) -{ - if(mtype == DBMeter) - { - double range = maxScale - minScale; - int y1 = int((maxScale - redScale) * h / range); - int y2 = int((maxScale - yellowScale) * h / range); - - if(yv < y1) - { - // Red section: - p.fillRect(0, 0, w, yv, QBrush(0x8e0000)); // dark red - p.fillRect(0, yv, w, y1-yv, QBrush(0xff0000)); // light red - - // Yellow section: - p.fillRect(0, y1, w, y2-y1, QBrush(0xffff00)); // light yellow - - // Green section: - p.fillRect(0, y2, w, h-y2, QBrush(0x00ff00)); // light green - } - else - if(yv < y2) - { - // Red section: - p.fillRect(0, 0, w, y1, QBrush(0x8e0000)); // dark red - - // Yellow section: - p.fillRect(0, y1, w, yv-y1, QBrush(0x8e8e00)); // dark yellow - p.fillRect(0, yv, w, y2-yv, QBrush(0xffff00)); // light yellow - - // Green section: - p.fillRect(0, y2, w, h-y2, QBrush(0x00ff00)); // light green - } - else - //if(yv <= y3) - { - // Red section: - p.fillRect(0, 0, w, y1, QBrush(0x8e0000)); // dark red - - // Yellow section: - p.fillRect(0, y1, w, y2-y1, QBrush(0x8e8e00)); // dark yellow - - // Green section: - p.fillRect(0, y2, w, yv-y2, QBrush(0x007000)); // dark green - p.fillRect(0, yv, w, h-yv, QBrush(0x00ff00)); // light green - } - } - else - { - p.fillRect(0, 0, w, yv, QBrush(0x007000)); // dark green - p.fillRect(0, yv, w, h-yv, QBrush(0x00ff00)); // light green - } -} - -//--------------------------------------------------------- -// resizeEvent -//--------------------------------------------------------- - -void Meter::resizeEvent(QResizeEvent* /*ev*/) - { - - } - -//--------------------------------------------------------- -// mousePressEvent -//--------------------------------------------------------- - -void Meter::mousePressEvent(QMouseEvent*) - { - emit mousePress(); - } - diff --git a/muse2/muse/mixer/meter.h b/muse2/muse/mixer/meter.h deleted file mode 100644 index 30bdfea6..00000000 --- a/muse2/muse/mixer/meter.h +++ /dev/null @@ -1,48 +0,0 @@ -//========================================================= -// MusE -// Linux Music Editor -// $Id: meter.h,v 1.1.1.1.2.2 2009/05/03 04:14:00 terminator356 Exp $ -// -// (C) Copyright 2000 Werner Schweer (ws@seh.de) -//========================================================= - -#ifndef __METER_H__ -#define __METER_H__ - -#include - -class QResizeEvent; -class QMouseEvent; -class QPainter; - -class Meter : public QFrame { - public: - enum MeterType {DBMeter, LinMeter}; - private: - MeterType mtype; - bool overflow; - double val; - double maxVal; - double minScale, maxScale; - int yellowScale, redScale; - - void drawVU(QPainter& p, int, int, int); - - Q_OBJECT - void paintEvent(QPaintEvent*); - virtual void resizeEvent(QResizeEvent*); - virtual void mousePressEvent(QMouseEvent*); - - public slots: - void resetPeaks(); - void setVal(double, double, bool); - - signals: - void mousePress(); - - public: - Meter(QWidget* parent, MeterType type = DBMeter); - void setRange(double min, double max); - }; -#endif - diff --git a/muse2/muse/plugin.cpp b/muse2/muse/plugin.cpp index 7dd2486f..fa446d2b 100644 --- a/muse2/muse/plugin.cpp +++ b/muse2/muse/plugin.cpp @@ -51,6 +51,7 @@ #include "doublelabel.h" #include "fastlog.h" #include "checkbox.h" +#include "verticalmeter.h" #include "audio.h" #include "al/dsp.h" @@ -3273,6 +3274,7 @@ PluginGui::PluginGui(PluginIBase* p) { gw = 0; params = 0; + paramsOut = 0; plugin = p; setWindowTitle(plugin->name()); @@ -3303,7 +3305,6 @@ PluginGui::PluginGui(PluginIBase* p) 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); @@ -3425,13 +3426,10 @@ PluginGui::PluginGui(PluginIBase* p) 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; @@ -3443,13 +3441,6 @@ PluginGui::PluginGui(PluginIBase* p) unsigned n = plugin->parameters(); // p4.0.21 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; @@ -3466,25 +3457,8 @@ PluginGui::PluginGui(PluginIBase* p) 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; - } + getPluginConvertedValues(range, lower, upper, dlower, dupper, dval); + if (LADSPA_IS_HINT_TOGGLED(range.HintDescriptor)) { params[i].type = GuiParam::GUI_SWITCH; CheckBox* cb = new CheckBox(mw, i, "param"); @@ -3502,9 +3476,6 @@ PluginGui::PluginGui(PluginIBase* p) 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); @@ -3547,6 +3518,52 @@ PluginGui::PluginGui(PluginIBase* p) connect(params[i].actuator, SIGNAL(checkboxRightClicked(const QPoint &, int)), SLOT(ctrlRightClicked(const QPoint &, int))); } } + + + int n2 = plugin->parametersOut(); + if (n2 > 0) { + paramsOut = new GuiParam[n2]; + + for (int i = 0; i < n2; ++i) { + QLabel* label = 0; + LADSPA_PortRangeHint range = plugin->rangeOut(i); + double lower = 0.0; // default values + double upper = 1.0; + double dlower = lower; + double dupper = upper; + double val = plugin->paramOut(i); + double dval = val; + paramsOut[i].hint = range.HintDescriptor; + + getPluginConvertedValues(range, lower, upper, dlower, dupper, dval); + label = new QLabel(QString(plugin->paramOutName(i)), 0); + paramsOut[i].type = GuiParam::GUI_METER; + paramsOut[i].label = new DoubleLabel(val, lower, upper, 0); + paramsOut[i].label->setFrame(true); + paramsOut[i].label->setPrecision(2); + paramsOut[i].label->setId(i); + + Meter::MeterType mType=Meter::LinMeter; + if(LADSPA_IS_HINT_INTEGER(range.HintDescriptor)) + mType=Meter::DBMeter; + VerticalMeter* m = new VerticalMeter(this, mType); + printf("lower =%f upper=%f dlower=%f dupper=%f\n", lower, upper,dlower,dupper); + + m->setRange(dlower, dupper); + m->setVal(dval); + paramsOut[i].actuator = m; +// paramsOut[i].label->setSlider((Slider*)params[i].actuator); + //paramsOut[i].actuator->setSizePolicy(QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed)); + label->setSizePolicy(QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed)); + paramsOut[i].label->setSizePolicy(QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed)); + grid->addWidget(label, n+i, 0); + grid->addWidget(paramsOut[i].label, n+i, 1); + grid->addWidget(paramsOut[i].actuator, n+i, 2); +// connect(paramsOut[i].label, SIGNAL(valueChanged(double,int)), SLOT(labelChanged(double,int))); + } + } + + // p3.3.43 resize(280, height()); @@ -3567,8 +3584,35 @@ PluginGui::~PluginGui() delete[] gw; if (params) delete[] params; + if (paramsOut) + delete[] paramsOut; } +void PluginGui::getPluginConvertedValues(LADSPA_PortRangeHint range, + double &lower, double &upper, double &dlower, double &dupper, double &dval) +{ + 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(dval) * 20.0; + } + +} + //--------------------------------------------------------- // heartBeat //--------------------------------------------------------- @@ -3959,7 +4003,33 @@ void PluginGui::updateValues() void PluginGui::updateControls() { - if(!automation || !plugin->track() || plugin->id() == -1) + if (!plugin->track() || plugin->id() == -1) + return; + + // update outputs + + if (paramsOut) { + for (int i = 0; i < plugin->parametersOut(); ++i) { + GuiParam* gp = ¶msOut[i]; + if (gp->type == GuiParam::GUI_METER) { + double lv = plugin->paramOut(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; + } + ((VerticalMeter*)(gp->actuator))->setVal(sv); + gp->label->setValue(lv); + + } + } + } + + + if(!automation) return; AutomationType at = plugin->track()->automationType(); if(at == AUTO_OFF) diff --git a/muse2/muse/plugin.h b/muse2/muse/plugin.h index 2d78a335..e2457eae 100644 --- a/muse2/muse/plugin.h +++ b/muse2/muse/plugin.h @@ -243,7 +243,7 @@ struct Port { struct GuiParam { enum { - GUI_SLIDER, GUI_SWITCH + GUI_SLIDER, GUI_SWITCH, GUI_METER }; int type; int hint; @@ -346,10 +346,14 @@ class PluginIBase //virtual const char* paramName(int /*i*/) = 0; //virtual LADSPA_PortRangeHint range(int /*i*/) = 0; virtual unsigned parameters() const = 0; // p4.0.21 - virtual void setParam(unsigned /*i*/, float /*val*/) = 0; + virtual unsigned parametersOut() const = 0; + virtual void setParam(unsigned /*i*/, float /*val*/) = 0; virtual float param(unsigned /*i*/) const = 0; - virtual const char* paramName(unsigned /*i*/) = 0; - virtual LADSPA_PortRangeHint range(unsigned /*i*/) = 0; + virtual float paramOut(unsigned /*i*/) const = 0; + virtual const char* paramName(unsigned /*i*/) = 0; + virtual const char* paramOutName(unsigned /*i*/) = 0; + virtual LADSPA_PortRangeHint range(unsigned /*i*/) = 0; + virtual LADSPA_PortRangeHint rangeOut(unsigned /*i*/) = 0; QString dssi_ui_filename() const; //virtual void showGui(bool) = 0; // p4.0.20 @@ -369,6 +373,7 @@ class PluginGui : public QMainWindow { PluginIBase* plugin; // plugin instance GuiParam* params; + GuiParam* paramsOut; //int nobj; unsigned nobj; // number of widgets in gw // p4.0.21 GuiWidgets* gw; @@ -378,7 +383,8 @@ class PluginGui : public QMainWindow { QScrollArea* view; void updateControls(); - + void getPluginConvertedValues(LADSPA_PortRangeHint range, + double &lower, double &upper, double &dlower, double &dupper, double &dval); private slots: void load(); void save(); @@ -526,6 +532,7 @@ class PluginI : public PluginIBase { bool isShowNativeGuiPending() { return _showNativeGuiPending; } bool guiVisible(); bool nativeGuiVisible(); + //int parameters() const { return controlPorts; } //void setParam(int i, double val) { controls[i].tmpVal = val; } //double param(int i) const { return controls[i].val; } @@ -538,16 +545,20 @@ class PluginI : public PluginIBase { //LADSPA_PortRangeHint range(int i) { return _plugin->range(controls[i].idx); } // p4.0.21 unsigned parameters() const { return controlPorts; } - //void setParam(unsigned i, float val) { controls[i].tmpVal = val; } + unsigned parametersOut() const { return controlOutPorts; } + //void setParam(unsigned i, float val) { controls[i].tmpVal = val; } void setParam(unsigned i, float val); float param(unsigned i) const { return controls[i].val; } - float defaultValue(unsigned param) const; + float paramOut(unsigned i) const { return controlsOut[i].val; } + float defaultValue(unsigned param) const; const char* paramName(unsigned i) { return _plugin->portName(controls[i].idx); } + const char* paramOutName(unsigned i) { return _plugin->portName(controlsOut[i].idx); } LADSPA_PortDescriptor portd(unsigned i) const { return _plugin->portd(controls[i].idx); } void range(unsigned i, float* min, float* max) const { _plugin->range(controls[i].idx, min, max); } bool isAudioIn(unsigned k) { return (_plugin->portd(k) & AUDIO_IN) == AUDIO_IN; } bool isAudioOut(unsigned k) { return (_plugin->portd(k) & AUDIO_OUT) == AUDIO_OUT; } LADSPA_PortRangeHint range(unsigned i) { return _plugin->range(controls[i].idx); } + LADSPA_PortRangeHint rangeOut(unsigned i) { return _plugin->range(controlsOut[i].idx); } bool inPlaceCapable() const { return _plugin->inPlaceCapable(); } }; diff --git a/muse2/muse/widgets/CMakeLists.txt b/muse2/muse/widgets/CMakeLists.txt index e3921f70..261c27a2 100644 --- a/muse2/muse/widgets/CMakeLists.txt +++ b/muse2/muse/widgets/CMakeLists.txt @@ -42,6 +42,7 @@ QT4_WRAP_CPP (widget_mocs intlabel.h knob.h lcombo.h + meter.h metronome.h midisyncimpl.h mixdowndialog.h @@ -75,7 +76,8 @@ QT4_WRAP_CPP (widget_mocs # ttoolbar.h ttoolbutton.h velocity.h - view.h + verticalmeter.h + view.h vscale.h visibletracks.h ) @@ -137,6 +139,7 @@ file (GLOB widgets_source_files intlabel.cpp knob.cpp lcombo.cpp + meter.cpp metronome.cpp midisyncimpl.cpp mixdowndialog.cpp @@ -174,7 +177,8 @@ file (GLOB widgets_source_files ttoolbutton.cpp utils.cpp velocity.cpp - view.cpp + verticalmeter.cpp + view.cpp vscale.cpp visibletracks.cpp ) diff --git a/muse2/muse/widgets/meter.cpp b/muse2/muse/widgets/meter.cpp new file mode 100644 index 00000000..6619d1dc --- /dev/null +++ b/muse2/muse/widgets/meter.cpp @@ -0,0 +1,217 @@ +//========================================================= +// MusE +// Linux Music Editor +// $Id: meter.cpp,v 1.4.2.2 2009/05/03 04:14:00 terminator356 Exp $ +// +// (C) Copyright 2000 Werner Schweer (ws@seh.de) +//========================================================= + +#include +#include + +#include +#include +#include + +#include "meter.h" +#include "gconfig.h" +#include "fastlog.h" + +//--------------------------------------------------------- +// Meter +//--------------------------------------------------------- + +Meter::Meter(QWidget* parent, MeterType type) + : QFrame(parent) //Qt::WNoAutoErase + { + setBackgroundRole(QPalette::NoRole); + setAttribute(Qt::WA_NoSystemBackground); + setAttribute(Qt::WA_StaticContents); + // This is absolutely required for speed! Otherwise painfully slow because we get + // full rect paint events even on small scrolls! See help on QPainter::scroll(). + setAttribute(Qt::WA_OpaquePaintEvent); + + mtype = type; + overflow = false; + val = 0.0; + maxVal = 0.0; + minScale = mtype == DBMeter ? config.minMeter : 0.0; // min value in dB or int + maxScale = mtype == DBMeter ? 10.0 : 127.0; + yellowScale = -10; + redScale = 0; + setLineWidth(0); + setMidLineWidth(0); + } + +//--------------------------------------------------------- +// setVal +//--------------------------------------------------------- + +void Meter::setVal(double v, double max, bool ovl) + { + overflow = ovl; + bool ud = false; + + if(mtype == DBMeter) + { + double minScaleLin = pow(10.0, minScale/20.0); + if((v >= minScaleLin && val != v) || val >= minScaleLin) + { + val = v; + ud = true; + } + } + else + { + if(val != v) + { + val = v; + ud = true; + } + } + + if(maxVal != max) + { + maxVal = max; + ud = true; + } + + if(ud) + update(); + } +//--------------------------------------------------------- +// resetPeaks +// reset peak and overflow indicator +//--------------------------------------------------------- + +void Meter::resetPeaks() + { + maxVal = val; + overflow = val > 0.0; + update(); + } + +//--------------------------------------------------------- +// setRange +//--------------------------------------------------------- + +void Meter::setRange(double min, double max) + { + minScale = min; + maxScale = max; + update(); + } + +//--------------------------------------------------------- +// paintEvent +//--------------------------------------------------------- + +void Meter::paintEvent(QPaintEvent* /*ev*/) + { + // TODO: Could make better use of event rectangle, for speed. + + QPainter p(this); + + double range = maxScale - minScale; + + int fw = frameWidth(); + int w = width() - 2*fw; + int h = height() - 2*fw; + int yv; + + if(mtype == DBMeter) + yv = val == 0 ? h : int(((maxScale - (fast_log10(val) * 20.0)) * h)/range); + else + yv = val == 0 ? h : int(((maxScale - val) * h)/range); + + if(yv > h) yv = h; + + // Draw the red, green, and yellow sections. + drawVU(p, w, h, yv); + + // Draw the peak white line. + int ymax; + if(mtype == DBMeter) + ymax = maxVal == 0 ? 0 : int(((maxScale - (fast_log10(maxVal) * 20.0)) * h)/range); + else + ymax = maxVal == 0 ? 0 : int(((maxScale - maxVal) * h)/range); + p.setPen(Qt::white); + p.drawLine(0, ymax, w, ymax); + } + +//--------------------------------------------------------- +// drawVU +//--------------------------------------------------------- + +void Meter::drawVU(QPainter& p, int w, int h, int yv) +{ + if(mtype == DBMeter) + { + double range = maxScale - minScale; + int y1 = int((maxScale - redScale) * h / range); + int y2 = int((maxScale - yellowScale) * h / range); + + if(yv < y1) + { + // Red section: + p.fillRect(0, 0, w, yv, QBrush(0x8e0000)); // dark red + p.fillRect(0, yv, w, y1-yv, QBrush(0xff0000)); // light red + + // Yellow section: + p.fillRect(0, y1, w, y2-y1, QBrush(0xffff00)); // light yellow + + // Green section: + p.fillRect(0, y2, w, h-y2, QBrush(0x00ff00)); // light green + } + else + if(yv < y2) + { + // Red section: + p.fillRect(0, 0, w, y1, QBrush(0x8e0000)); // dark red + + // Yellow section: + p.fillRect(0, y1, w, yv-y1, QBrush(0x8e8e00)); // dark yellow + p.fillRect(0, yv, w, y2-yv, QBrush(0xffff00)); // light yellow + + // Green section: + p.fillRect(0, y2, w, h-y2, QBrush(0x00ff00)); // light green + } + else + //if(yv <= y3) + { + // Red section: + p.fillRect(0, 0, w, y1, QBrush(0x8e0000)); // dark red + + // Yellow section: + p.fillRect(0, y1, w, y2-y1, QBrush(0x8e8e00)); // dark yellow + + // Green section: + p.fillRect(0, y2, w, yv-y2, QBrush(0x007000)); // dark green + p.fillRect(0, yv, w, h-yv, QBrush(0x00ff00)); // light green + } + } + else + { + p.fillRect(0, 0, w, yv, QBrush(0x007000)); // dark green + p.fillRect(0, yv, w, h-yv, QBrush(0x00ff00)); // light green + } +} + +//--------------------------------------------------------- +// resizeEvent +//--------------------------------------------------------- + +void Meter::resizeEvent(QResizeEvent* /*ev*/) + { + + } + +//--------------------------------------------------------- +// mousePressEvent +//--------------------------------------------------------- + +void Meter::mousePressEvent(QMouseEvent*) + { + emit mousePress(); + } + diff --git a/muse2/muse/widgets/meter.h b/muse2/muse/widgets/meter.h new file mode 100644 index 00000000..2b816040 --- /dev/null +++ b/muse2/muse/widgets/meter.h @@ -0,0 +1,49 @@ +//========================================================= +// MusE +// Linux Music Editor +// $Id: meter.h,v 1.1.1.1.2.2 2009/05/03 04:14:00 terminator356 Exp $ +// +// (C) Copyright 2000 Werner Schweer (ws@seh.de) +//========================================================= + +#ifndef __METER_H__ +#define __METER_H__ + +#include + +class QResizeEvent; +class QMouseEvent; +class QPainter; + + +class Meter : public QFrame { + public: + enum MeterType {DBMeter, LinMeter}; + private: + MeterType mtype; + bool overflow; + double val; + double maxVal; + double minScale, maxScale; + int yellowScale, redScale; + + void drawVU(QPainter& p, int, int, int); + + Q_OBJECT + void paintEvent(QPaintEvent*); + void resizeEvent(QResizeEvent*); + void mousePressEvent(QMouseEvent*); + + public slots: + void resetPeaks(); + void setVal(double, double, bool); + + signals: + void mousePress(); + + public: + Meter(QWidget* parent, MeterType type = DBMeter); + void setRange(double min, double max); + }; +#endif + diff --git a/muse2/muse/widgets/verticalmeter.cpp b/muse2/muse/widgets/verticalmeter.cpp new file mode 100644 index 00000000..ca846886 --- /dev/null +++ b/muse2/muse/widgets/verticalmeter.cpp @@ -0,0 +1,209 @@ +//========================================================= +// MusE +// Linux Music Editor +// $Id: meter.cpp,v 1.4.2.2 2009/05/03 04:14:00 terminator356 Exp $ +// +// (C) Copyright 2000 Werner Schweer (ws@seh.de) +//========================================================= + +#include +#include + +#include +#include +#include + +#include "verticalmeter.h" +#include "gconfig.h" +#include "fastlog.h" + +//--------------------------------------------------------- +// VerticalMeter +//--------------------------------------------------------- + +VerticalMeter::VerticalMeter(QWidget* parent, MeterType type) + : Meter(parent, type) //Qt::WNoAutoErase + { + setBackgroundRole(QPalette::NoRole); + setAttribute(Qt::WA_NoSystemBackground); + setAttribute(Qt::WA_StaticContents); + // This is absolutely required for speed! Otherwise painfully slow because we get + // full rect paint events even on small scrolls! See help on QPainter::scroll(). + setAttribute(Qt::WA_OpaquePaintEvent); + + mtype = type; + overflow = false; + val = 0.0; + maxVal = 0.0; + minScale = mtype == DBMeter ? config.minMeter : 0.0; // min value in dB or int + maxScale = mtype == DBMeter ? 10.0 : 127.0; + yellowScale = -10; + redScale = 0; + setLineWidth(0); + setMidLineWidth(0); + } + + +//--------------------------------------------------------- +// setVal +//--------------------------------------------------------- + +void VerticalMeter::setVal(double v) //, double max, bool ovl) + { + //overflow = ovl; + bool ud = false; + + if(mtype == DBMeter) + { + double minScaleLin = pow(10.0, minScale/20.0); + if((v >= minScaleLin && val != v) || val >= minScaleLin) + { + val = v; + ud = true; + } + } + else + { + if(val != v) + { + val = v; + ud = true; + } + } + +// if(maxVal != max) +// { +// maxVal = max; +// ud = true; +// } + + if(ud) + update(); + } +//--------------------------------------------------------- +// resetPeaks +// reset peak and overflow indicator +//--------------------------------------------------------- + +void VerticalMeter::resetPeaks() + { + maxVal = val; + overflow = val > 0.0; + update(); + } + +//--------------------------------------------------------- +// setRange +//--------------------------------------------------------- + +void VerticalMeter::setRange(double min, double max) + { + minScale = min; + maxScale = max; + update(); + } + +//--------------------------------------------------------- +// paintEvent +//--------------------------------------------------------- + +void VerticalMeter::paintEvent(QPaintEvent* /*ev*/) + { + // TODO: Could make better use of event rectangle, for speed. + + QPainter p(this); + + double range = maxScale - minScale; + + int fw = frameWidth(); + int w = width() - 2*fw; + int h = height() - 2*fw; + int xv; + + + if(mtype == DBMeter) + xv = val == 0 ? w : int(((maxScale - (fast_log10(val) * 20.0)) * w)/range); + else + xv = val == 0 ? w : int(((maxScale - val) * w)/range); + + if(xv > w) xv = w; + + // Draw the red, green, and yellow sections. + drawVU(p, w, h, xv); + + // Draw the peak white line. + int xcenter; + if(mtype == DBMeter) + xcenter = maxVal == 0 ? 0 : int(((maxScale - (fast_log10(0) * 20.0)) * w)/range); + else + xcenter = maxVal == 0 ? 0 : int(((0) * w)/range); + p.setPen(Qt::white); + p.drawLine(xcenter, 0, xcenter, h); + } + +//--------------------------------------------------------- +// drawVU +//--------------------------------------------------------- + +void VerticalMeter::drawVU(QPainter& p, int w, int h, int xv) +{ + if(mtype == DBMeter) + { + double range = maxScale - minScale; + int x1 = int((maxScale - redScale) * w / range); + int x2 = int((maxScale - yellowScale) * w / range); + + if(xv < x1) + { + // Red section: + p.fillRect(0, 0, xv, h, QBrush(0x8e0000)); // dark red + p.fillRect(xv, 0, x1-xv, h, QBrush(0xff0000)); // light red + + // Yellow section: + p.fillRect(x1, 0, x2-x1, h, QBrush(0xffff00)); // light yellow + + // Green section: + p.fillRect(x2, 0, w-x2, h, QBrush(0x00ff00)); // light green + } + else + if(xv < x2) + { + // Red section: + p.fillRect(0, 0, x1, h, QBrush(0x8e0000)); // dark red + + // Yellow section: + p.fillRect(x1, 0, xv-x1, h, QBrush(0x8e8e00)); // dark yellow + p.fillRect(xv, 0, x2-xv, h, QBrush(0xffff00)); // light yellow + + // Green section: + p.fillRect(x2, 0, w-x2, h, QBrush(0x00ff00)); // light green + } + else + //if(yv <= y3) + { + // Red section: + p.fillRect(0, 0, x1, h, QBrush(0x8e0000)); // dark red + + // Yellow section: + p.fillRect(x1, 0, x2-x1, h, QBrush(0x8e8e00)); // dark yellow + + // Green section: + p.fillRect(x2, 0, xv-x2, h, QBrush(0x007000)); // dark green + p.fillRect(xv, 0, w-xv, h, QBrush(0x00ff00)); // light green + } + } + else + { + p.fillRect(0, 0, xv, h, QBrush(0x00ff00)); // dark green + p.fillRect(xv, 0, w-xv, h, QBrush(0x007000)); // light green + } +} + +//--------------------------------------------------------- +// resizeEvent +//--------------------------------------------------------- + +void VerticalMeter::resizeEvent(QResizeEvent* /*ev*/) + { + + } diff --git a/muse2/muse/widgets/verticalmeter.h b/muse2/muse/widgets/verticalmeter.h new file mode 100644 index 00000000..699be1e5 --- /dev/null +++ b/muse2/muse/widgets/verticalmeter.h @@ -0,0 +1,43 @@ +//========================================================= +// MusE +// Linux Music Editor +// $Id: meter.h,v 1.1.1.1.2.2 2009/05/03 04:14:00 terminator356 Exp $ +// +// (C) Copyright 2000 Werner Schweer (ws@seh.de) +//========================================================= + +#ifndef __VERTICALMETER_H__ +#define __VERTICALMETER_H__ + +#include +#include "meter.h" + +class QResizeEvent; +class QMouseEvent; +class QPainter; + +class VerticalMeter : public Meter { + private: + MeterType mtype; + bool overflow; + double val; + double maxVal; + double minScale, maxScale; + int yellowScale, redScale; + + void drawVU(QPainter& p, int, int, int); + + Q_OBJECT + void paintEvent(QPaintEvent*); + void resizeEvent(QResizeEvent*); + + public slots: + void resetPeaks(); + void setVal(double); + + public: + VerticalMeter(QWidget* parent, MeterType type = DBMeter); + void setRange(double min, double max); + }; +#endif + -- cgit v1.2.3