# HG changeset patch # User Chris Cannam # Date 1467392071 -3600 # Node ID 179ea8a2f650c18bd61322c6d6de13884ada0892 # Parent db976e9f385aeee70e027001a6a33cb0770d8538 Add VerticalBinLayer to SpectrogramLayer diff -r db976e9f385a -r 179ea8a2f650 layer/Colour3DPlotLayer.cpp --- a/layer/Colour3DPlotLayer.cpp Fri Jul 01 11:37:46 2016 +0100 +++ b/layer/Colour3DPlotLayer.cpp Fri Jul 01 17:54:31 2016 +0100 @@ -670,12 +670,6 @@ return y; } -int -Colour3DPlotLayer::getIYForBin(LayerGeometryProvider *v, int bin) const -{ - return int(round(getYForBin(v, bin))); -} - double Colour3DPlotLayer::getBinForY(LayerGeometryProvider *v, double y) const { @@ -694,12 +688,6 @@ return bin; } -int -Colour3DPlotLayer::getIBinForY(LayerGeometryProvider *v, int y) const -{ - return int(floor(getBinForY(v, y))); -} - QString Colour3DPlotLayer::getFeatureDescription(LayerGeometryProvider *v, QPoint &pos) const { diff -r db976e9f385a -r 179ea8a2f650 layer/Colour3DPlotLayer.h --- a/layer/Colour3DPlotLayer.h Fri Jul 01 11:37:46 2016 +0100 +++ b/layer/Colour3DPlotLayer.h Fri Jul 01 17:54:31 2016 +0100 @@ -202,11 +202,6 @@ * fractional, to obtain a position part-way through a bin. */ double getYForBin(LayerGeometryProvider *, double bin) const; - - /** - * As getYForBin, but rounding to integer values. - */ - int getIYForBin(LayerGeometryProvider *, int bin) const; /** * Return the bin number, possibly fractional, at the given y @@ -215,11 +210,6 @@ * if the vertical scale is the usual way up). */ double getBinForY(LayerGeometryProvider *, double y) const; - - /** - * As getBinForY, but rounding to integer values. - */ - int getIBinForY(LayerGeometryProvider *, int y) const; DenseThreeDimensionalModel::Column getColumn(int col) const; diff -r db976e9f385a -r 179ea8a2f650 layer/LayerGeometryProvider.h --- a/layer/LayerGeometryProvider.h Fri Jul 01 11:37:46 2016 +0100 +++ b/layer/LayerGeometryProvider.h Fri Jul 01 17:54:31 2016 +0100 @@ -103,23 +103,26 @@ virtual int getViewXForX(int x) const = 0; /** - * Return the pixel y-coordinate corresponding to a given - * frequency, if the frequency range is as specified. This does - * not imply any policy about layer frequency ranges, but it might - * be useful for layers to match theirs up if desired. + * Return the (maybe fractional) pixel y-coordinate corresponding + * to a given frequency, if the frequency range is as specified. + * This does not imply any policy about layer frequency ranges, + * but it might be useful for layers to match theirs up if + * desired. * * Not thread-safe in logarithmic mode. Call only from GUI thread. */ - virtual double getYForFrequency(double frequency, double minFreq, double maxFreq, + virtual double getYForFrequency(double frequency, + double minFreq, double maxFreq, bool logarithmic) const = 0; /** - * Return the closest frequency to the given pixel y-coordinate, - * if the frequency range is as specified. + * Return the closest frequency to the given (maybe fractional) + * pixel y-coordinate, if the frequency range is as specified. * * Not thread-safe in logarithmic mode. Call only from GUI thread. */ - virtual double getFrequencyForY(int y, double minFreq, double maxFreq, + virtual double getFrequencyForY(double y, + double minFreq, double maxFreq, bool logarithmic) const = 0; virtual int getTextLabelHeight(const Layer *layer, QPainter &) const = 0; diff -r db976e9f385a -r 179ea8a2f650 layer/SpectrogramLayer.cpp --- a/layer/SpectrogramLayer.cpp Fri Jul 01 11:37:46 2016 +0100 +++ b/layer/SpectrogramLayer.cpp Fri Jul 01 17:54:31 2016 +0100 @@ -1209,7 +1209,38 @@ return true; } + +double +SpectrogramLayer::getYForBin(LayerGeometryProvider *, double bin) const { + //!!! not implemented + throw std::logic_error("not implemented"); +} + +double +SpectrogramLayer::getBinForY(LayerGeometryProvider *v, double y) const +{ + //!!! overlap with range methods above (but using double arg) + //!!! tidy this + int h = v->getPaintHeight(); + if (y < 0 || y >= h) return false; + + sv_samplerate_t sr = m_model->getSampleRate(); + double minf = getEffectiveMinFrequency(); + double maxf = getEffectiveMaxFrequency(); + + bool logarithmic = (m_frequencyScale == LogFrequencyScale); + + double q = v->getFrequencyForY(y, minf, maxf, logarithmic); + + // Now map on to ("proportions of") actual bins, using raw FFT + // size (unsmoothed) + + q = (q * getFFTSize(v)) / sr; + + return q; +} + bool SpectrogramLayer::getXBinRange(LayerGeometryProvider *v, int x, double &s0, double &s1) const { diff -r db976e9f385a -r 179ea8a2f650 layer/SpectrogramLayer.h --- a/layer/SpectrogramLayer.h Fri Jul 01 11:37:46 2016 +0100 +++ b/layer/SpectrogramLayer.h Fri Jul 01 17:54:31 2016 +0100 @@ -27,6 +27,7 @@ #include "data/model/FFTModel.h" #include "ScrollableImageCache.h" +#include "VerticalBinLayer.h" #include #include @@ -48,6 +49,7 @@ */ class SpectrogramLayer : public SliceableLayer, + public VerticalBinLayer, public PowerOfSqrtTwoZoomConstraint { Q_OBJECT @@ -208,6 +210,10 @@ double getYForFrequency(const LayerGeometryProvider *v, double frequency) const; double getFrequencyForY(const LayerGeometryProvider *v, int y) const; + //!!! VerticalBinLayer methods. Note overlap with get*BinRange() + double getYForBin(LayerGeometryProvider *, double bin) const; + double getBinForY(LayerGeometryProvider *, double y) const; + virtual int getCompletion(LayerGeometryProvider *v) const; virtual QString getError(LayerGeometryProvider *v) const; diff -r db976e9f385a -r 179ea8a2f650 layer/VerticalBinLayer.h --- a/layer/VerticalBinLayer.h Fri Jul 01 11:37:46 2016 +0100 +++ b/layer/VerticalBinLayer.h Fri Jul 01 17:54:31 2016 +0100 @@ -36,7 +36,9 @@ /** * As getYForBin, but rounding to integer values. */ - virtual int getIYForBin(LayerGeometryProvider *, int bin) const = 0; + virtual int getIYForBin(LayerGeometryProvider *v, int bin) const { + return int(round(getYForBin(v, bin))); + } /** * Return the bin number, possibly fractional, at the given y @@ -49,7 +51,9 @@ /** * As getBinForY, but rounding to integer values. */ - virtual int getIBinForY(LayerGeometryProvider *, int y) const = 0; + virtual int getIBinForY(LayerGeometryProvider *v, int y) const { + return int(floor(getBinForY(v, y))); + } }; #endif diff -r db976e9f385a -r 179ea8a2f650 view/View.cpp --- a/view/View.cpp Fri Jul 01 11:37:46 2016 +0100 +++ b/view/View.cpp Fri Jul 01 17:54:31 2016 +0100 @@ -415,12 +415,12 @@ } double -View::getFrequencyForY(int y, +View::getFrequencyForY(double y, double minf, double maxf, bool logarithmic) const { - int h = height(); + double h = height(); if (logarithmic) { diff -r db976e9f385a -r 179ea8a2f650 view/View.h --- a/view/View.h Fri Jul 01 11:37:46 2016 +0100 +++ b/view/View.h Fri Jul 01 17:54:31 2016 +0100 @@ -144,8 +144,8 @@ * * Not thread-safe in logarithmic mode. Call only from GUI thread. */ - double getFrequencyForY(int y, double minFreq, double maxFreq, - bool logarithmic) const; + double getFrequencyForY(double y, double minFreq, double maxFreq, + bool logarithmic) const; /** * Return the zoom level, i.e. the number of frames per pixel diff -r db976e9f385a -r 179ea8a2f650 view/ViewProxy.h --- a/view/ViewProxy.h Fri Jul 01 11:37:46 2016 +0100 +++ b/view/ViewProxy.h Fri Jul 01 17:54:31 2016 +0100 @@ -63,14 +63,10 @@ return m_scaleFactor * m_view->getYForFrequency(frequency, minFreq, maxFreq, logarithmic); } - virtual double getFrequencyForY(int y, double minFreq, double maxFreq, + virtual double getFrequencyForY(double y, double minFreq, double maxFreq, bool logarithmic) const { - double f0 = m_view->getFrequencyForY + return m_view->getFrequencyForY (y / m_scaleFactor, minFreq, maxFreq, logarithmic); - if (m_scaleFactor == 1) return f0; - double f1 = m_view->getFrequencyForY - ((y / m_scaleFactor) + 1, minFreq, maxFreq, logarithmic); - return f0 + ((f1 - f0) * (y % m_scaleFactor)) / m_scaleFactor; } virtual int getTextLabelHeight(const Layer *layer, QPainter &paint) const { return m_scaleFactor * m_view->getTextLabelHeight(layer, paint);