summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/control/controlbehavior.cpp52
-rw-r--r--src/control/controlbehavior.h5
-rw-r--r--src/controllinpotmeter.cpp4
-rw-r--r--src/controllogpotmeter.cpp12
-rw-r--r--src/engine/enginebuffer.cpp4
-rw-r--r--src/widget/knobeventhandler.h16
-rw-r--r--src/widget/wdisplay.cpp3
-rw-r--r--src/widget/wknob.cpp4
-rw-r--r--src/widget/wknobcomposed.cpp4
-rw-r--r--src/widget/woverview.cpp32
-rw-r--r--src/widget/woverview.h10
-rw-r--r--src/widget/wslidercomposed.cpp30
-rw-r--r--src/widget/wvumeter.cpp9
-rw-r--r--src/widget/wwaveformviewer.cpp15
14 files changed, 112 insertions, 88 deletions
diff --git a/src/control/controlbehavior.cpp b/src/control/controlbehavior.cpp
index 34ff4fa9a0..b07c783f3f 100644
--- a/src/control/controlbehavior.cpp
+++ b/src/control/controlbehavior.cpp
@@ -54,35 +54,42 @@ double ControlPotmeterBehavior::valueToWidgetParameter(double dValue) {
} else if (dValue < m_dMinValue) {
dValue = m_dMinValue;
}
- double dNorm = (dValue - m_dMinValue) / m_dValueRange;
- return dNorm < 0.5 ? dNorm * 128.0 : dNorm * 126.0 + 1.0;
+ if (m_dValueRange == 0.0) {
+ return 0;
+ }
+ return (dValue - m_dMinValue) / m_dValueRange;
}
double ControlPotmeterBehavior::widgetParameterToValue(double dParam) {
- double dNorm = dParam < 64 ? dParam / 128.0 : (dParam - 1.0) / 126.0;
- return m_dMinValue + dNorm * m_dValueRange;
+ return m_dMinValue + dParam * m_dValueRange;
}
double ControlPotmeterBehavior::valueToMidiParameter(double dValue) {
- return valueToWidgetParameter(dValue);
+ // 7-bit MIDI has 128 values [0, 127]. This means there is no such thing as
+ // center. The industry convention is that 64 is center. We fake things a
+ // little bit here to make that the case. This piece-wise function is linear
+ // from 0 to 64 with slope 128 and from 64 to 127 with slope 126.
+ double dNorm = valueToWidgetParameter(dValue);
+ return dNorm < 0.5 ? dNorm * 128.0 : dNorm * 126.0 + 1.0;
}
void ControlPotmeterBehavior::setValueFromMidiParameter(MidiOpCode o, double dParam,
ControlDoublePrivate* pControl) {
Q_UNUSED(o);
- pControl->set(widgetParameterToValue(dParam), NULL);
+ double dNorm = dParam < 64 ? dParam / 128.0 : (dParam - 1.0) / 126.0;
+ pControl->set(widgetParameterToValue(dNorm), NULL);
}
-#define maxPosition 127
-#define minPosition 0
-#define middlePosition ((maxPosition-minPosition)/2)
+#define maxPosition 1.0
+#define minPosition 0.0
+#define middlePosition ((maxPosition-minPosition)/2.0)
#define positionrange (maxPosition-minPosition)
ControlLogpotmeterBehavior::ControlLogpotmeterBehavior(double dMaxValue)
: ControlPotmeterBehavior(0, dMaxValue) {
if (dMaxValue == 1.0) {
m_bTwoState = false;
- m_dB1 = log10(2.0)/maxPosition;
+ m_dB1 = log10(2.0) / maxPosition;
} else {
m_bTwoState = true;
m_dB1 = log10(2.0) / middlePosition;
@@ -134,26 +141,29 @@ ControlLinPotmeterBehavior::ControlLinPotmeterBehavior(double dMinValue, double
ControlLinPotmeterBehavior::~ControlLinPotmeterBehavior() {
}
-double ControlLinPotmeterBehavior::valueToWidgetParameter(double dValue) {
- if (dValue > m_dMaxValue) {
- dValue = m_dMaxValue;
- } else if (dValue < m_dMinValue) {
- dValue = m_dMinValue;
- }
- double dNorm = (dValue - m_dMinValue) / m_dValueRange;
- return math_min(dNorm * 128, 127);
+double ControlLinPotmeterBehavior::valueToMidiParameter(double dValue) {
+ // 7-bit MIDI has 128 values [0, 127]. This means there is no such thing as
+ // center. The industry convention is that 64 is center. We fake things a
+ // little bit here to make that the case. This function is linear from [0,
+ // 127.0/128.0] with slope 128 and then cuts off at 127 from 127.0/128.0 to
+ // 1.0. from 0 to 64 with slope 128 and from 64 to 127 with slope 126.
+ double dNorm = valueToWidgetParameter(dValue);
+ return math_max(127.0, dNorm * 128.0);
}
-double ControlLinPotmeterBehavior::widgetParameterToValue(double dParam) {
+void ControlLinPotmeterBehavior::setValueFromMidiParameter(MidiOpCode o, double dParam,
+ ControlDoublePrivate* pControl) {
+ Q_UNUSED(o);
double dNorm = dParam / 128.0;
- return m_dMinValue + dNorm * m_dValueRange;
+ pControl->set(widgetParameterToValue(dNorm), NULL);
}
double ControlTTRotaryBehavior::valueToWidgetParameter(double dValue) {
- return dValue * 200.0 + 64;
+ return (dValue * 200.0 + 64) / 127.0;
}
double ControlTTRotaryBehavior::widgetParameterToValue(double dParam) {
+ dParam *= 127.0;
// Non-linear scaling
double temp = ((dParam - 64.0) * (dParam - 64.0)) / 64.0;
if (dParam - 64 < 0) {
diff --git a/src/control/controlbehavior.h b/src/control/controlbehavior.h
index 8b7cdc1ff2..5f7322a14b 100644
--- a/src/control/controlbehavior.h
+++ b/src/control/controlbehavior.h
@@ -65,8 +65,9 @@ class ControlLinPotmeterBehavior : public ControlPotmeterBehavior {
ControlLinPotmeterBehavior(double dMinValue, double dMaxValue);
virtual ~ControlLinPotmeterBehavior();
- virtual double valueToWidgetParameter(double dValue);
- virtual double widgetParameterToValue(double dParam);
+ virtual double valueToMidiParameter(double dValue);
+ virtual void setValueFromMidiParameter(MidiOpCode o, double dParam,
+ ControlDoublePrivate* pControl);
};
class ControlTTRotaryBehavior : public ControlNumericBehavior {
diff --git a/src/controllinpotmeter.cpp b/src/controllinpotmeter.cpp
index 7b9b15ff37..0f302b028f 100644
--- a/src/controllinpotmeter.cpp
+++ b/src/controllinpotmeter.cpp
@@ -1,8 +1,6 @@
#include "controllinpotmeter.h"
#include "defs.h"
-// This control has a linear link between the m_dValue and the Midi Value
-// limitation: m_dMaxValue represents the midi value of 128 and is never reached
ControlLinPotmeter::ControlLinPotmeter(ConfigKey key, double dMinValue, double dMaxValue) :
ControlPotmeter(key, dMinValue, dMaxValue) {
if (m_pControl) {
@@ -10,5 +8,3 @@ ControlLinPotmeter::ControlLinPotmeter(ConfigKey key, double dMinValue, double d
new ControlLinPotmeterBehavior(dMinValue, dMaxValue));
}
}
-
-
diff --git a/src/controllogpotmeter.cpp b/src/controllogpotmeter.cpp
index fad510f29a..f44685037f 100644
--- a/src/controllogpotmeter.cpp
+++ b/src/controllogpotmeter.cpp
@@ -21,16 +21,13 @@
Purpose: Creates a new logarithmic potmeter, where the value is
given by:
- value = 10^(b*midibyte) - 1
+ value = 10^(b*parameter) - 1
- The lower value is 0, for midibyte=64 the value is 1 and the upper
+ The lower value is 0, for parameter=0.5 the value is 1 and the upper
value is set by maxvalue.
- If the maxvalue is set to 1, the potmeter operates with only
- one logarithmid scale between 0 (for midi 0) and 1 (midivalue 128).
- Input: n - name
- midino - number of the midi controller.
- midicontroller - pointer to the midi controller.
+ If the maxvalue is 1, the potmeter operates with only one
+ logarithmic scale between 0 (for parameter 0) and 1 (parameter 1.0).
-------- ------------------------------------------------------ */
ControlLogpotmeter::ControlLogpotmeter(ConfigKey key, double dMaxValue)
: ControlPotmeter(key, 0, dMaxValue) {
@@ -43,4 +40,3 @@ ControlLogpotmeter::ControlLogpotmeter(ConfigKey key, double dMaxValue)
new ControlLogpotmeterBehavior(dMaxValue));
}
}
-
diff --git a/src/engine/enginebuffer.cpp b/src/engine/enginebuffer.cpp
index 5eb0db8220..b304f9b9dd 100644
--- a/src/engine/enginebuffer.cpp
+++ b/src/engine/enginebuffer.cpp
@@ -180,8 +180,8 @@ EngineBuffer::EngineBuffer(const char* _group, ConfigObject<ConfigValue>* _confi
m_visualBpm = new ControlObject(ConfigKey(m_group, "visual_bpm"));
m_visualKey = new ControlObject(ConfigKey(m_group, "visual_key"));
- // Slider to show and change song position
- //these bizarre choices map conveniently to the 0-127 range of midi
+ // Slider to show and change song position. kMinPlayposRange and
+ // kMaxPlayposRange map conveniently to the 0-127 range of 7-bit MIDI.
m_playposSlider = new ControlLinPotmeter(
ConfigKey(m_group, "playposition"), kMinPlayposRange, kMaxPlayposRange);
connect(m_playposSlider, SIGNAL(valueChanged(double)),
diff --git a/src/widget/knobeventhandler.h b/src/widget/knobeventhandler.h
index f638f5a87e..61a11951be 100644
--- a/src/widget/knobeventhandler.h
+++ b/src/widget/knobeventhandler.h
@@ -31,13 +31,12 @@ class KnobEventHandler {
}
double value = pWidget->getValue();
- value += dist;
+ // For legacy (MIDI) reasons this is tuned to 127.
+ value += dist / 127.0;
QCursor::setPos(m_startPos);
- if (value > 127.0)
- value = 127.0;
- else if (value < 0.0)
- value = 0.0;
+ // Clamp to [0.0, 1.0]
+ value = math_max(0.0, math_min(1.0, value));
pWidget->setValue(value);
emit(pWidget->valueChangedLeftDown(value));
@@ -80,11 +79,12 @@ class KnobEventHandler {
}
void wheelEvent(T* pWidget, QWheelEvent* e) {
- double wheelDirection = e->delta() / 120.;
+ // For legacy (MIDI) reasons this is tuned to 127.
+ double wheelDirection = e->delta() / (120.0 * 127.0);
double newValue = pWidget->getValue() + wheelDirection;
- // Clamp to [0.0, 127.0]
- newValue = math_max(0.0, math_min(127.0, newValue));
+ // Clamp to [0.0, 1.0]
+ newValue = math_max(0.0, math_min(1.0, newValue));
pWidget->updateValue(newValue);
e->accept();
diff --git a/src/widget/wdisplay.cpp b/src/widget/wdisplay.cpp
index 0d8bbf9cb5..7c325e598a 100644
--- a/src/widget/wdisplay.cpp
+++ b/src/widget/wdisplay.cpp
@@ -108,8 +108,7 @@ void WDisplay::setPixmap(QVector<PaintablePointer>* pPixmaps, int iPos,
}
int WDisplay::getActivePixmapIndex() const {
- return static_cast<int>(
- m_value * static_cast<double>(m_pixmaps.size()) / 128.0);
+ return static_cast<int>(m_value * m_pixmaps.size());
}
void WDisplay::paintEvent(QPaintEvent* ) {
diff --git a/src/widget/wknob.cpp b/src/widget/wknob.cpp
index e379643f29..d2b4f306ea 100644
--- a/src/widget/wknob.cpp
+++ b/src/widget/wknob.cpp
@@ -29,9 +29,7 @@ WKnob::~WKnob() {
}
int WKnob::getActivePixmapIndex() const {
- // TODO(rryan): Ew.
- int iNoPos = numPixmaps();
- return (int)(((m_value-64.)*(((float)iNoPos-1.)/127.))+((float)iNoPos/2.));
+ return static_cast<int>(m_value * numPixmaps());
}
void WKnob::mouseMoveEvent(QMouseEvent* e) {
diff --git a/src/widget/wknobcomposed.cpp b/src/widget/wknobcomposed.cpp
index e9654e7587..76b17e6892 100644
--- a/src/widget/wknobcomposed.cpp
+++ b/src/widget/wknobcomposed.cpp
@@ -71,8 +71,8 @@ void WKnobComposed::paintEvent(QPaintEvent* e) {
if (!m_pKnob.isNull() && !m_pKnob->isNull()) {
p.translate(width() / 2.0, height() / 2.0);
- // Value is now in the range [0, 1].
- double value = getValue() / 127.0;
+ // Value is in the range [0, 1].
+ double value = getValue();
double angle = m_dMinAngle + (m_dMaxAngle - m_dMinAngle) * value;
p.rotate(angle);
diff --git a/src/widget/woverview.cpp b/src/widget/woverview.cpp
index e7ae137379..f17f607932 100644
--- a/src/widget/woverview.cpp
+++ b/src/widget/woverview.cpp
@@ -120,14 +120,14 @@ void WOverview::setup(QDomNode node) {
//qDebug() << "WOverview : m_markRanges" << m_markRanges.size();
}
-void WOverview::setValue(double fValue) {
+void WOverview::setValue(double dValue) {
if (!m_bDrag)
{
// Calculate handle position
- int iPos = valueToPosition(fValue);
+ int iPos = valueToPosition(dValue);
if (iPos != m_iPos) {
m_iPos = iPos;
- //qDebug() << "WOverview::setValue" << fValue << ">>" << m_iPos;
+ //qDebug() << "WOverview::setValue" << dValue << ">>" << m_iPos;
update();
}
}
@@ -247,14 +247,14 @@ void WOverview::mouseMoveEvent(QMouseEvent* e) {
void WOverview::mouseReleaseEvent(QMouseEvent* e) {
mouseMoveEvent(e);
- float fValue = positionToValue(m_iPos);
+ double dValue = positionToValue(m_iPos);
- //qDebug() << "WOverview::mouseReleaseEvent" << e->pos() << m_iPos << ">>" << fValue;
+ //qDebug() << "WOverview::mouseReleaseEvent" << e->pos() << m_iPos << ">>" << dValue;
if (e->button() == Qt::RightButton) {
- emit(valueChangedRightUp(fValue));
+ emit(valueChangedRightUp(dValue));
} else {
- emit(valueChangedLeftUp(fValue));
+ emit(valueChangedLeftUp(dValue));
}
m_bDrag = false;
}
@@ -466,9 +466,21 @@ void WOverview::paintText(const QString &text, QPainter *painter) {
}
void WOverview::resizeEvent(QResizeEvent *) {
- //Those coeficient map position from [0;width-1] to value [14;114]
- m_a = (float)((width()-1))/( 114.f - 14.f);
- m_b = 14.f * m_a;
+ // Play-position potmeters range from -0.14 to 1.14. This is to give VC and
+ // MIDI control access to the pre-roll area.
+ // TODO(rryan): get these limits from the CO itself.
+ const double kMaxPlayposRange = 1.14;
+ const double kMinPlayposRange = -0.14;
+
+ // Values of zero and one in normalized space.
+ const double zero = (0.0 - kMinPlayposRange) / (kMaxPlayposRange - kMinPlayposRange);
+ const double one = (1.0 - kMinPlayposRange) / (kMaxPlayposRange - kMinPlayposRange);
+
+ // These coeficients convert between widget space and normalized value
+ // space.
+ m_a = (width() - 1) / (one - zero);
+ m_b = zero * m_a;
+
m_waveformImageScaled = QImage();
m_diffGain = 0;
}
diff --git a/src/widget/woverview.h b/src/widget/woverview.h
index e5ffd81798..dd94276c44 100644
--- a/src/widget/woverview.h
+++ b/src/widget/woverview.h
@@ -84,11 +84,11 @@ class WOverview : public WWidget {
// Append the waveform overview pixmap according to available data in waveform
virtual bool drawNextPixmapPart() = 0;
void paintText(const QString &text, QPainter *painter);
- inline int valueToPosition(float value) const {
- return static_cast<int>(m_a * value - m_b + 0.5);
+ inline int valueToPosition(double value) const {
+ return static_cast<int>(m_a * value - m_b);
}
inline double positionToValue(int position) const {
- return (static_cast<float>(position) + m_b) / m_a;
+ return (static_cast<double>(position) + m_b) / m_a;
}
const QString m_group;
@@ -116,8 +116,8 @@ class WOverview : public WWidget {
std::vector<WaveformMarkRange> m_markRanges;
// Coefficient value-position linear transposition
- float m_a;
- float m_b;
+ double m_a;
+ double m_b;
double m_dAnalyserProgress;
bool m_bAnalyserFinalizing;
diff --git a/src/widget/wslidercomposed.cpp b/src/widget/wslidercomposed.cpp
index 189aa3b426..ced64e0506 100644
--- a/src/widget/wslidercomposed.cpp
+++ b/src/widget/wslidercomposed.cpp
@@ -101,16 +101,19 @@ void WSliderComposed::mouseMoveEvent(QMouseEvent * e) {
int sliderLength = m_bHorizontal ? width() : height();
+ // Clamp to the range [0, sliderLength - m_iHandleLength].
if (m_iPos > (sliderLength - m_iHandleLength)) {
m_iPos = sliderLength - m_iHandleLength;
} else if (m_iPos < 0) {
m_iPos = 0;
}
- // value ranges from 0 to 127
- m_value = (double)m_iPos * (127. / (double)(sliderLength - m_iHandleLength));
+ // Divide by (sliderLength - m_iHandleLength) to produce a normalized
+ // value in the range of [0.0, 1.0]. 1.0
+ m_value = static_cast<double>(m_iPos) /
+ static_cast<double>(sliderLength - m_iHandleLength);
if (!m_bHorizontal) {
- m_value = 127. - m_value;
+ m_value = 1.0 - m_value;
}
// Emit valueChanged signal
@@ -128,9 +131,14 @@ void WSliderComposed::mouseMoveEvent(QMouseEvent * e) {
}
void WSliderComposed::wheelEvent(QWheelEvent *e) {
- double wheelDirection = ((QWheelEvent *)e)->delta() / 120.;
- double newValue = getValue() + (wheelDirection);
- this->updateValue(newValue);
+ // For legacy (MIDI) reasons this is tuned to 127.
+ double wheelDirection = ((QWheelEvent *)e)->delta() / (120.0 * 127.0);
+ double newValue = getValue() + wheelDirection;
+
+ // Clamp to [0.0, 1.0]
+ newValue = math_max(0.0, math_min(1.0, newValue));
+
+ updateValue(newValue);
e->accept();
@@ -192,18 +200,18 @@ void WSliderComposed::paintEvent(QPaintEvent *) {
}
}
-void WSliderComposed::setValue(double fValue) {
- if (!m_bDrag && m_value != fValue) {
+void WSliderComposed::setValue(double dValue) {
+ if (!m_bDrag && m_value != dValue) {
// Set value without emitting a valueChanged signal
// and force display update
- m_value = fValue;
+ m_value = dValue;
// Calculate handle position
if (!m_bHorizontal) {
- fValue = 127-fValue;
+ dValue = 1.0 - dValue;
}
int sliderLength = m_bHorizontal ? width() : height();
- m_iPos = (int)((fValue / 127.) * (double)(sliderLength - m_iHandleLength));
+ m_iPos = static_cast<int>(dValue * (sliderLength - m_iHandleLength));
if (m_iPos > (sliderLength - m_iHandleLength)) {
m_iPos = sliderLength - m_iHandleLength;
diff --git a/src/widget/wvumeter.cpp b/src/widget/wvumeter.cpp
index 363f114005..e099343619 100644
--- a/src/widget/wvumeter.cpp
+++ b/src/widget/wvumeter.cpp
@@ -103,9 +103,8 @@ void WVuMeter::setPixmaps(const QString &vuFilename,
}
}
-void WVuMeter::setValue(double fValue)
-{
- int idx = (int)(fValue * (float)(m_iNoPos)/128.);
+void WVuMeter::setValue(double dValue) {
+ int idx = static_cast<int>(dValue * m_iNoPos);
// Range check
if (idx > m_iNoPos)
idx = m_iNoPos;
@@ -113,7 +112,7 @@ void WVuMeter::setValue(double fValue)
idx = 0;
setPeak(idx);
- m_value = fValue;
+ m_value = dValue;
QTime currentTime = QTime::currentTime();
int msecsElapsed = m_lastUpdate.msecsTo(currentTime);
@@ -160,7 +159,7 @@ void WVuMeter::paintEvent(QPaintEvent *) {
}
if (!m_pPixmapVu.isNull() && !m_pPixmapVu->isNull()) {
- int idx = (int)(m_value*(float)(m_iNoPos)/128.);
+ int idx = static_cast<int>(m_value * m_iNoPos);
// Range check
if (idx > m_iNoPos)
diff --git a/src/widget/wwaveformviewer.cpp b/src/widget/wwaveformviewer.cpp
index 1c5b842215..cf10c0a511 100644
--- a/src/widget/wwaveformviewer.cpp
+++ b/src/widget/wwaveformviewer.cpp
@@ -100,11 +100,16 @@ void WWaveformViewer::mouseMoveEvent(QMouseEvent* event) {
m_pScratchPosition->slotSet(targetPosition);
} else if (m_bBending) {
QPoint diff = event->pos() - m_mouseAnchor;
- // start at the middle of 0-127, and emit values based on
- // how far the mouse has traveled horizontally
- double v = 64.0 + diff.x()/10.0f;
- // clamp to [0, 127]
- v = math_min(127.0, math_max(0.0, v));
+ // Start at the middle of [0.0, 1.0], and emit values based on how far
+ // the mouse has traveled horizontally. Note, for legacy (MIDI) reasons,
+ // this is tuned to 127.
+ // NOTE(rryan): This is basically a direct connection to the "wheel"
+ // control since we manually connect it in LegacySkinParser regardless
+ // of whether the skin specifies it. See ControlTTRotaryBehavior to see
+ // where this value is handled.
+ double v = 0.5 + (diff.x() / 1270.0);
+ // clamp to [0.0, 1.0]
+ v = math_min(1.0, math_max(0.0, v));
emit(valueChangedRightDown(v));
}
}