changeset 1280:34394e8c2942 horizontal-scale

Merge
author Chris Cannam
date Wed, 02 May 2018 14:27:17 +0100
parents b6fc0970cd66 (diff) a04f1012fca2 (current diff)
children fc9d9f1103fa
files layer/SpectrumLayer.cpp
diffstat 9 files changed, 138 insertions(+), 26 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/layer/HorizontalScaleProvider.h	Wed May 02 14:27:17 2018 +0100
@@ -0,0 +1,38 @@
+/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
+
+/*
+    Sonic Visualiser
+    An audio file viewer and annotation editor.
+    Centre for Digital Music, Queen Mary, University of London.
+    This file copyright 2006-2018 Chris Cannam and QMUL.
+    
+    This program is free software; you can redistribute it and/or
+    modify it under the terms of the GNU General Public License as
+    published by the Free Software Foundation; either version 2 of the
+    License, or (at your option) any later version.  See the file
+    COPYING included with this distribution for more information.
+*/
+
+#ifndef SV_HORIZONTAL_SCALE_PROVIDER_H
+#define SV_HORIZONTAL_SCALE_PROVIDER_H
+
+class LayerGeometryProvider;
+
+/**
+ * Interface to be implemented by objects, such as layers or objects
+ * they delegate to, in which the X axis corresponds to frequency. For
+ * example, SpectrumLayer.
+ */
+class HorizontalScaleProvider
+{
+public:
+    virtual double getFrequencyForX(const LayerGeometryProvider *,
+                                    double x)
+        const = 0;
+    
+    virtual double getXForFrequency(const LayerGeometryProvider *,
+                                    double freq)
+        const = 0;
+};
+
+#endif
--- a/layer/LinearNumericalScale.cpp	Wed May 02 14:26:51 2018 +0100
+++ b/layer/LinearNumericalScale.cpp	Wed May 02 14:27:17 2018 +0100
@@ -26,9 +26,14 @@
 
 int
 LinearNumericalScale::getWidth(LayerGeometryProvider *,
-                               QPainter &paint)
+                                   QPainter &paint,
+                                   bool horizontal)
 {
-    return paint.fontMetrics().width("-000.00") + 10;
+    if (horizontal) {
+        return paint.fontMetrics().height() + 10;
+    } else {
+        return paint.fontMetrics().width("-000.00") + 10;
+    }
 }
 
 void
--- a/layer/LinearNumericalScale.h	Wed May 02 14:26:51 2018 +0100
+++ b/layer/LinearNumericalScale.h	Wed May 02 14:27:17 2018 +0100
@@ -13,23 +13,29 @@
     COPYING included with this distribution for more information.
 */
 
-#ifndef LINEAR_NUMERICAL_SCALE_H
-#define LINEAR_NUMERICAL_SCALE_H
+#ifndef SV_LINEAR_NUMERICAL_SCALE_H
+#define SV_LINEAR_NUMERICAL_SCALE_H
 
 #include <QRect>
 
 class QPainter;
 class LayerGeometryProvider;
 class VerticalScaleLayer;
+class HorizontalScaleProvider;
 
 class LinearNumericalScale
 {
 public:
-    int getWidth(LayerGeometryProvider *v, QPainter &paint);
+    int getWidth(LayerGeometryProvider *v, QPainter &paint,
+                 bool horizontal = false);
 
     void paintVertical
     (LayerGeometryProvider *v, const VerticalScaleLayer *layer,
      QPainter &paint, int x0, double minf, double maxf);
+
+    void paintHorizontal
+    (LayerGeometryProvider *v, const HorizontalScaleProvider *provider,
+     QPainter &paint, QRect r);
 };
 
 #endif
--- a/layer/LogNumericalScale.cpp	Wed May 02 14:26:51 2018 +0100
+++ b/layer/LogNumericalScale.cpp	Wed May 02 14:27:17 2018 +0100
@@ -15,22 +15,26 @@
 
 #include "LogNumericalScale.h"
 #include "VerticalScaleLayer.h"
+#include "HorizontalScaleProvider.h"
+#include "LayerGeometryProvider.h"
 
 #include "base/LogRange.h"
+#include "base/ScaleTickIntervals.h"
 
 #include <QPainter>
 
 #include <cmath>
 
-#include "LayerGeometryProvider.h"
-
-#include "base/ScaleTickIntervals.h"
-
 int
 LogNumericalScale::getWidth(LayerGeometryProvider *,
-                            QPainter &paint)
+                                QPainter &paint,
+                                bool horizontal)
 {
-    return paint.fontMetrics().width("-000.00") + 10;
+    if (horizontal) {
+        return paint.fontMetrics().height() + 10;
+    } else {
+        return paint.fontMetrics().width("-000.00") + 10;
+    }
 }
 
 void
@@ -80,3 +84,50 @@
         prevy = y;
     }
 }
+
+void
+LogNumericalScale::paintHorizontal(LayerGeometryProvider *v,
+                                   const HorizontalScaleProvider *p,
+                                   QPainter &paint,
+                                   QRect r)
+{
+    int x0 = r.x(), y0 = r.y(), x1 = r.x() + r.width(), y1 = r.y() + r.height();
+
+    paint.drawLine(x0, y0, x1, y0);
+
+    double f0 = p->getFrequencyForX(v, x0 ? x0 : 1);
+    double f1 = p->getFrequencyForX(v, x1);
+
+    cerr << "f0 = " << f0 << " at x " << (x0 ? x0 : 1) << endl;
+    cerr << "f1 = " << f1 << " at x " << x1 << endl;
+    
+    int n = 20;
+    auto ticks = ScaleTickIntervals::logarithmic({ f0, f1, n });
+    n = int(ticks.size());
+
+    int marginx = -1;
+
+    for (int i = 0; i < n; ++i) {
+        
+        double val = ticks[i].value;
+        QString label = QString::fromStdString(ticks[i].label);
+        int tw = paint.fontMetrics().width(label);
+        
+        cerr << "i = " << i << ", value = " << val << ", tw = " << tw << endl;
+
+        int x = int(round(p->getXForFrequency(v, val)));
+
+        cerr << "x = " << x << endl;
+
+        if (x < marginx) continue;
+        
+        //!!! todo: pixel scaling (here & elsewhere in these classes)
+        
+        paint.drawLine(x, y0, x, y1);
+
+        paint.drawText(x + 5, y0 + paint.fontMetrics().ascent() + 5, label);
+
+        marginx = x + tw + 10;
+    }
+}
+
--- a/layer/LogNumericalScale.h	Wed May 02 14:26:51 2018 +0100
+++ b/layer/LogNumericalScale.h	Wed May 02 14:27:17 2018 +0100
@@ -13,23 +13,29 @@
     COPYING included with this distribution for more information.
 */
 
-#ifndef LOG_NUMERICAL_SCALE_H
-#define LOG_NUMERICAL_SCALE_H
+#ifndef SV_LOG_NUMERICAL_SCALE_H
+#define SV_LOG_NUMERICAL_SCALE_H
 
 #include <QRect>
 
 class QPainter;
 class LayerGeometryProvider;
 class VerticalScaleLayer;
+class HorizontalScaleProvider;
 
 class LogNumericalScale
 {
 public:
-    int getWidth(LayerGeometryProvider *v, QPainter &paint);
+    int getWidth(LayerGeometryProvider *v, QPainter &paint,
+                 bool horizontal = false);
 
     void paintVertical
-    (LayerGeometryProvider *v, const VerticalScaleLayer *layer, QPainter &paint, int x0,
-     double minlog, double maxlog);
+    (LayerGeometryProvider *v, const VerticalScaleLayer *layer,
+     QPainter &paint, int x0, double minlog, double maxlog);
+
+    void paintHorizontal
+    (LayerGeometryProvider *v, const HorizontalScaleProvider *provider,
+     QPainter &paint, QRect r);
 };
 
 #endif
--- a/layer/PianoScale.cpp	Wed May 02 14:26:51 2018 +0100
+++ b/layer/PianoScale.cpp	Wed May 02 14:27:17 2018 +0100
@@ -22,6 +22,7 @@
 #include "base/Pitch.h"
 
 #include "LayerGeometryProvider.h"
+#include "HorizontalScaleProvider.h"
 
 #include <iostream>
 using namespace std;
--- a/layer/PianoScale.h	Wed May 02 14:26:51 2018 +0100
+++ b/layer/PianoScale.h	Wed May 02 14:27:17 2018 +0100
@@ -20,18 +20,14 @@
 
 class QPainter;
 class LayerGeometryProvider;
+class HorizontalScaleProvider;
 
 class PianoScale
 {
 public:
     void paintPianoVertical
-    (LayerGeometryProvider *v, QPainter &paint, QRect rect, double minf, double maxf);
-
-    class HorizontalScaleProvider {
-    public:
-        virtual double getFrequencyForX(const LayerGeometryProvider *, double x) const = 0;
-        virtual double getXForFrequency(const LayerGeometryProvider *, double freq) const = 0;
-    };
+    (LayerGeometryProvider *v, QPainter &paint, QRect rect,
+     double minf, double maxf);
     
     void paintPianoHorizontal
     (LayerGeometryProvider *v, const HorizontalScaleProvider *p,
--- a/layer/SpectrumLayer.cpp	Wed May 02 14:26:51 2018 +0100
+++ b/layer/SpectrumLayer.cpp	Wed May 02 14:27:17 2018 +0100
@@ -25,6 +25,8 @@
 
 #include "ColourMapper.h"
 #include "PaintAssistant.h"
+#include "PianoScale.h"
+#include "LogNumericalScale.h"
 
 #include <QPainter>
 #include <QTextStream>
@@ -603,6 +605,8 @@
     int pkh = int(paint.fontMetrics().height() * 0.7 + 0.5);
     if (pkh < 10) pkh = 10;
 
+    int scaleh = LogNumericalScale().getWidth(v, paint, true);
+
     paint.save();
 
     if (fft && m_showPeaks) {
@@ -676,8 +680,13 @@
     int h = v->getPaintHeight();
 
     PianoScale().paintPianoHorizontal
-        (v, this, paint, QRect(xorigin, h - pkh - 1, w + xorigin, pkh));
+        (v, this, paint,
+         QRect(xorigin, h - scaleh - pkh - 1, w + xorigin, pkh));
 
+    LogNumericalScale().paintHorizontal
+        (v, this, paint,
+         QRect(int(getXForBin(v, 1)), h - scaleh, w + xorigin, scaleh)); 
+    
     paint.restore();
 }
 
--- a/layer/SpectrumLayer.h	Wed May 02 14:26:51 2018 +0100
+++ b/layer/SpectrumLayer.h	Wed May 02 14:27:17 2018 +0100
@@ -23,7 +23,7 @@
 
 #include "data/model/DenseTimeValueModel.h"
 
-#include "PianoScale.h"
+#include "HorizontalScaleProvider.h"
 
 #include <QColor>
 #include <QMutex>
@@ -31,7 +31,7 @@
 class FFTModel;
 
 class SpectrumLayer : public SliceLayer,
-                      public PianoScale::HorizontalScaleProvider
+                      public HorizontalScaleProvider
 {
     Q_OBJECT