diff layer/WaveformLayer.cpp @ 274:b9380f679f70

* Fix centre line position * Fix failure to update overview when generating peaks from wav file * Provide y-coordinate scale values and differences for spectrum measurement mode, and fix values for waveform (inc dB for both) * Add Printer colour scheme (may be futile)
author Chris Cannam
date Mon, 02 Jul 2007 13:04:17 +0000
parents 4ed1446ad604
children 9dd432665059
line wrap: on
line diff
--- a/layer/WaveformLayer.cpp	Fri Jun 29 16:50:59 2007 +0000
+++ b/layer/WaveformLayer.cpp	Mon Jul 02 13:04:17 2007 +0000
@@ -637,14 +637,14 @@
 
                 if (val < -1.0 || val > 1.0) continue;
 
-                int y = getYForValue(v, m_scale, val, ch, minChannel, maxChannel);
+                int y = getYForValue(v, val, ch);
 
                 if (py >= 0 && abs(y - py) < 10) continue;
                 else py = y;
 
                 int ny = y;
                 if (nval != 0.0) {
-                    ny = getYForValue(v, m_scale, nval, ch, minChannel, maxChannel);
+                    ny = getYForValue(v, nval, ch);
                 }
 
                 paint->drawLine(x0, y, x1, y);
@@ -995,26 +995,29 @@
 }
 
 int
-WaveformLayer::getYForValue(const View *v, Scale scale, float value, size_t channel,
-                            size_t minChannel, size_t maxChannel) const
+WaveformLayer::getYForValue(const View *v, float value, size_t channel) const
 {
+    size_t channels = 0, minChannel = 0, maxChannel = 0;
+    bool mergingChannels = false, mixingChannels = false;
+
+    channels = getChannelArrangement(minChannel, maxChannel,
+                                     mergingChannels, mixingChannels);
+
     if (maxChannel < minChannel || channel < minChannel) return 0;
 
     int h = v->height();
-
-    int channels = maxChannel - minChannel + 1;
     int m = (h / channels) / 2;
-    int my = m + (((channel - minChannel) * h) / channels);
 	
     if ((m_scale == dBScale || m_scale == MeterScale) &&
         m_channelMode != MergeChannels) {
         m = (h / channels);
-        my = m + (((channel - minChannel) * h) / channels);
     }
 
+    int my = m + (((channel - minChannel) * h) / channels);
+
     int vy = 0;
 
-    switch (scale) {
+    switch (m_scale) {
 
     case LinearScale:
         vy = int(m * value);
@@ -1033,40 +1036,33 @@
 }
 
 float
-WaveformLayer::getValueForY(const View *v, Scale scale, int y,
-                            size_t minChannel, size_t maxChannel) const
+WaveformLayer::getValueForY(const View *v, int y, size_t &channel) const
 {
+    size_t channels = 0, minChannel = 0, maxChannel = 0;
+    bool mergingChannels = false, mixingChannels = false;
+
+    channels = getChannelArrangement(minChannel, maxChannel,
+                                     mergingChannels, mixingChannels);
+
     if (maxChannel < minChannel) return 0;
 
     int h = v->height();
-
-    int channels = maxChannel - minChannel + 1;
     int m = (h / channels) / 2;
 
     if ((m_scale == dBScale || m_scale == MeterScale) &&
         m_channelMode != MergeChannels) {
         m = (h / channels);
     }
-    
-    int channel = minChannel;
-    int mind = 0;
+  
+    channel = (y * channels) / h + minChannel;
 
-    for (int c = minChannel; c <= maxChannel; ++c) {
-        int my = m + (((c - minChannel) * h) / channels);
-        int d = y - my;
-        if (d < 0) d = -d;
-        if (c == minChannel || d < mind) {
-            mind = d;
-            channel = c;
-        }
-    }
-	
     int my = m + (((channel - minChannel) * h) / channels);
 
     int vy = my - y;
     float value = 0;
+    float thresh = -50.f;
 
-    switch (scale) {
+    switch (m_scale) {
 
     case LinearScale:
         value = float(vy) / m;
@@ -1077,27 +1073,75 @@
         break;
 
     case dBScale:
-        value = AudioLevel::dB_to_multiplier((50 * float(vy)) / m - 50);
+        value = (-thresh * float(vy)) / m + thresh;
+        value = AudioLevel::dB_to_multiplier(value);
         break;
     }
 
-    return value;
+    return value / m_gain;
 }
 
 bool
 WaveformLayer::getYScaleValue(const View *v, int y,
                               float &value, QString &unit) const
 {
-    size_t channels = 0, minChannel = 0, maxChannel = 0;
-    bool mergingChannels = false, mixingChannels = false;
+    size_t channel;
 
-    channels = getChannelArrangement(minChannel, maxChannel,
-                                     mergingChannels, mixingChannels);
+    value = getValueForY(v, y, channel);
 
-    if (channels == 0) return false;
+    if (m_scale == dBScale || m_scale == MeterScale) {
 
-    value = getValueForY(v, m_scale, y, minChannel, maxChannel);
-    unit = "V";
+        float thresh = -50.f;
+        
+        if (value > 0.f) {
+            value = 10.f * log10f(value);
+            if (value < thresh) value = thresh;
+        } else value = thresh;
+
+        unit = "dBV";
+
+    } else {
+        unit = "V";
+    }
+
+    return true;
+}
+
+bool
+WaveformLayer::getYScaleDifference(const View *v, int y0, int y1,
+                                   float &diff, QString &unit) const
+{
+    size_t c0, c1;
+    float v0 = getValueForY(v, y0, c0);
+    float v1 = getValueForY(v, y1, c1);
+
+    if (c0 != c1) {
+        // different channels, not comparable
+        diff = 0.f;
+        unit = "";
+        return false;
+    }
+
+    if (m_scale == dBScale || m_scale == MeterScale) {
+
+        float thresh = -50.f;
+
+        if (v1 == v0) diff = thresh;
+        else {
+            if (v1 > v0) diff = v0 / v1;
+            else diff = v1 / v0;
+
+            diff = 10.f * log10f(diff);
+            if (diff < thresh) diff = thresh;
+        }
+
+        unit = "dBV";
+
+    } else {
+        diff = fabsf(v1 - v0);
+        unit = "V";
+    }
+
     return true;
 }
 
@@ -1180,11 +1224,11 @@
 
             if (val < -1.0 || val > 1.0) continue;
 
-            int y = getYForValue(v, m_scale, val, ch, minChannel, maxChannel);
+            int y = getYForValue(v, val, ch);
 
             int ny = y;
             if (nval != 0.0) {
-                ny = getYForValue(v, m_scale, nval, ch, minChannel, maxChannel);
+                ny = getYForValue(v, nval, ch);
             }
 
             bool spaceForLabel = (i == 0 ||