changeset 1177:916b62baf7ac levelpanwidget

Add monitoring to level-pan widget (though not well, yet)
author Chris Cannam
date Mon, 05 Dec 2016 15:47:32 +0000
parents 125748a569fa
children ed99d432dc57
files widgets/LevelPanWidget.cpp widgets/LevelPanWidget.h
diffstat 2 files changed, 98 insertions(+), 26 deletions(-) [+]
line wrap: on
line diff
--- a/widgets/LevelPanWidget.cpp	Mon Dec 05 14:51:25 2016 +0000
+++ b/widgets/LevelPanWidget.cpp	Mon Dec 05 15:47:32 2016 +0000
@@ -37,6 +37,8 @@
     QWidget(parent),
     m_level(maxLevel),
     m_pan(0),
+    m_monitorLeft(-1),
+    m_monitorRight(-1),
     m_editable(true),
     m_includeMute(true)
 {
@@ -78,18 +80,36 @@
     else return -20.;
 }
 
+int
+LevelPanWidget::audioLevelToLevel(float audioLevel, bool withMute)
+{
+    int level;
+    if (withMute) {
+        level = AudioLevel::multiplier_to_fader
+            (audioLevel, maxLevel, AudioLevel::ShortFader);
+    } else {
+        level = db_to_level(AudioLevel::multiplier_to_dB(audioLevel));
+    }
+    if (level < 0) level = 0;
+    if (level > maxLevel) level = maxLevel;
+    return level;
+}
+
+float
+LevelPanWidget::levelToAudioLevel(int level, bool withMute)
+{
+    if (withMute) {
+        return float(AudioLevel::fader_to_multiplier
+                     (level, maxLevel, AudioLevel::ShortFader));
+    } else {
+        return float(AudioLevel::dB_to_multiplier(level_to_db(level)));
+    }
+}
+
 void
 LevelPanWidget::setLevel(float flevel)
 {
-    int level;
-    if (m_includeMute) {
-        level = AudioLevel::multiplier_to_fader
-            (flevel, maxLevel, AudioLevel::ShortFader);
-    } else {
-        level = db_to_level(AudioLevel::multiplier_to_dB(flevel));
-    }
-    if (level < 0) level = 0;
-    if (level > maxLevel) level = maxLevel;
+    int level = audioLevelToLevel(flevel, m_includeMute);
     if (level != m_level) {
 	m_level = level;
 	float convertsTo = getLevel();
@@ -103,20 +123,45 @@
 float
 LevelPanWidget::getLevel() const
 {
-    if (m_includeMute) {
-        return float(AudioLevel::fader_to_multiplier
-                     (m_level, maxLevel, AudioLevel::ShortFader));
-    } else {
-        return float(AudioLevel::dB_to_multiplier(level_to_db(m_level)));
+    return levelToAudioLevel(m_level, m_includeMute);
+}
+
+int
+LevelPanWidget::audioPanToPan(float audioPan)
+{
+    int pan = int(round(audioPan * maxPan));
+    if (pan < -maxPan) pan = -maxPan;
+    if (pan > maxPan) pan = maxPan;
+    return pan;
+}
+
+float
+LevelPanWidget::panToAudioPan(int pan)
+{
+    return float(pan) / float(maxPan);
+}
+
+void
+LevelPanWidget::setPan(float fpan)
+{
+    int pan = audioPanToPan(fpan);
+    if (pan != m_pan) {
+        m_pan = pan;
+        update();
     }
 }
 
+float
+LevelPanWidget::getPan() const
+{
+    return panToAudioPan(m_pan);
+}
+
 void
-LevelPanWidget::setPan(float pan)
+LevelPanWidget::setMonitoringLevels(float left, float right)
 {
-    m_pan = int(round(pan * maxPan));
-    if (m_pan < -maxPan) m_pan = -maxPan;
-    if (m_pan > maxPan) m_pan = maxPan;
+    m_monitorLeft = left;
+    m_monitorRight = right;
     update();
 }
 
@@ -147,12 +192,6 @@
     update();
 }
 
-float
-LevelPanWidget::getPan() const
-{
-    return float(m_pan) / float(maxPan);
-}
-
 void
 LevelPanWidget::emitLevelChanged()
 {
@@ -325,11 +364,33 @@
     pen.setWidthF(cellLightSize(rect).width() + thin);
     pen.setCapStyle(Qt::RoundCap);
     paint.setPen(pen);
+    paint.setBrush(Qt::NoBrush);
 
     for (int pan = -maxPan; pan <= maxPan; ++pan) {
 	paint.drawLine(cellCentre(rect, 0, pan), cellCentre(rect, maxLevel, pan));
     }
 
+    if (m_monitorLeft > 0.f || m_monitorRight > 0.f) {
+        paint.setPen(Qt::NoPen);
+        for (int pan = -maxPan; pan <= maxPan; ++pan) {
+            float audioPan = panToAudioPan(pan);
+            float audioLevel;
+            if (audioPan < 0.f) {
+                audioLevel = m_monitorLeft + m_monitorRight * (1.f + audioPan);
+            } else {
+                audioLevel = m_monitorRight + m_monitorLeft * (1.f - audioPan);
+            }
+            int levelHere = audioLevelToLevel(audioLevel, false);
+            for (int level = 0; level <= levelHere; ++level) {
+                paint.setBrush(level_to_colour(level));
+                QRectF clr = cellLightRect(rect, level, pan);
+                paint.drawEllipse(clr);
+            }
+        }
+        paint.setPen(pen);
+        paint.setBrush(Qt::NoBrush);
+    }
+    
     if (isEnabled()) {
 	pen.setColor(Qt::black);
     } else {
--- a/widgets/LevelPanWidget.h	Mon Dec 05 14:51:25 2016 +0000
+++ b/widgets/LevelPanWidget.h	Mon Dec 05 15:47:32 2016 +0000
@@ -53,6 +53,9 @@
     /// Set pan in the range [-1,1] -- will be rounded
     void setPan(float);
 
+    /// Set left and right peak monitoring levels in the range [0,1]
+    void setMonitoringLevels(float, float);
+    
     /// Specify whether the widget is editable or read-only (default editable)
     void setEditable(bool);
 
@@ -60,8 +63,8 @@
     void setIncludeMute(bool);
     
 signals:
-    void levelChanged(float);
-    void panChanged(float);
+    void levelChanged(float); // range [0,1]
+    void panChanged(float); // range [-1,1]
 
 protected:
     virtual void mousePressEvent(QMouseEvent *ev);
@@ -75,9 +78,17 @@
     
     int m_level;
     int m_pan;
+    float m_monitorLeft;
+    float m_monitorRight;
     bool m_editable;
     bool m_includeMute;
 
+    static int audioLevelToLevel(float audioLevel, bool withMute);
+    static float levelToAudioLevel(int level, bool withMute);
+
+    static int audioPanToPan(float audioPan);
+    static float panToAudioPan(int pan);
+    
     QSizeF cellSize(QRectF) const;
     QPointF cellCentre(QRectF, int level, int pan) const;
     QSizeF cellLightSize(QRectF) const;