# HG changeset patch # User Chris Cannam # Date 1525267637 -3600 # Node ID 34394e8c2942fefa86478390ca94fcf1d9abc1ef # Parent b6fc0970cd662de918cd972f8eecf708f316f2fe# Parent a04f1012fca202cdf7df41d5df6d58464e0fa4bf Merge diff -r a04f1012fca2 -r 34394e8c2942 layer/HorizontalScaleProvider.h --- /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 diff -r a04f1012fca2 -r 34394e8c2942 layer/LinearNumericalScale.cpp --- 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 diff -r a04f1012fca2 -r 34394e8c2942 layer/LinearNumericalScale.h --- 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 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 diff -r a04f1012fca2 -r 34394e8c2942 layer/LogNumericalScale.cpp --- 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 #include -#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; + } +} + diff -r a04f1012fca2 -r 34394e8c2942 layer/LogNumericalScale.h --- 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 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 diff -r a04f1012fca2 -r 34394e8c2942 layer/PianoScale.cpp --- 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 using namespace std; diff -r a04f1012fca2 -r 34394e8c2942 layer/PianoScale.h --- 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, diff -r a04f1012fca2 -r 34394e8c2942 layer/SpectrumLayer.cpp --- 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 #include @@ -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(); } diff -r a04f1012fca2 -r 34394e8c2942 layer/SpectrumLayer.h --- 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 #include @@ -31,7 +31,7 @@ class FFTModel; class SpectrumLayer : public SliceLayer, - public PianoScale::HorizontalScaleProvider + public HorizontalScaleProvider { Q_OBJECT