annotate layer/WaveformLayer.h @ 1212:a1ee3108d1d3 3.0-integration

Make the colour 3d plot renderer able to support more than one level of peak cache; introduce a second "peak" cache for the spectrogram layer that actually has a 1-1 column relationship with the underlying FFT model, and use it in addition to the existing peak cache if memory is plentiful. Makes spectrograms appear much faster in many common situations.
author Chris Cannam
date Thu, 05 Jan 2017 14:02:54 +0000
parents e3c7da3d896e
children a34a2a25907c
rev   line source
Chris@58 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@0 2
Chris@0 3 /*
Chris@59 4 Sonic Visualiser
Chris@59 5 An audio file viewer and annotation editor.
Chris@59 6 Centre for Digital Music, Queen Mary, University of London.
Chris@182 7 This file copyright 2006 Chris Cannam and QMUL.
Chris@0 8
Chris@59 9 This program is free software; you can redistribute it and/or
Chris@59 10 modify it under the terms of the GNU General Public License as
Chris@59 11 published by the Free Software Foundation; either version 2 of the
Chris@59 12 License, or (at your option) any later version. See the file
Chris@59 13 COPYING included with this distribution for more information.
Chris@0 14 */
Chris@0 15
Chris@30 16 #ifndef _WAVEFORM_LAYER_H_
Chris@30 17 #define _WAVEFORM_LAYER_H_
Chris@0 18
Chris@0 19 #include <QRect>
Chris@0 20
Chris@287 21 #include "SingleColourLayer.h"
Chris@0 22
Chris@128 23 #include "data/model/RangeSummarisableTimeValueModel.h"
Chris@0 24
Chris@0 25 class View;
Chris@0 26 class QPainter;
Chris@0 27 class QPixmap;
Chris@0 28
Chris@287 29 class WaveformLayer : public SingleColourLayer
Chris@0 30 {
Chris@0 31 Q_OBJECT
Chris@0 32
Chris@0 33 public:
Chris@44 34 WaveformLayer();
Chris@0 35 ~WaveformLayer();
Chris@0 36
Chris@156 37 virtual const ZoomConstraint *getZoomConstraint() const {
Chris@156 38 return m_model ? m_model->getZoomConstraint() : 0;
Chris@156 39 }
Chris@0 40 virtual const Model *getModel() const { return m_model; }
Chris@916 41 virtual void paint(LayerGeometryProvider *v, QPainter &paint, QRect rect) const;
Chris@0 42
Chris@918 43 virtual QString getFeatureDescription(LayerGeometryProvider *v, QPoint &) const;
Chris@25 44
Chris@287 45 virtual ColourSignificance getLayerColourSignificance() const {
Chris@287 46 return ColourAndBackgroundSignificant;
Chris@287 47 }
Chris@287 48
Chris@918 49 virtual int getVerticalScaleWidth(LayerGeometryProvider *v, bool detailed, QPainter &) const;
Chris@918 50 virtual void paintVerticalScale(LayerGeometryProvider *v, bool detailed, QPainter &paint, QRect rect) const;
Chris@0 51
Chris@0 52 void setModel(const RangeSummarisableTimeValueModel *model);
Chris@0 53
Chris@0 54 virtual PropertyList getProperties() const;
Chris@87 55 virtual QString getPropertyLabel(const PropertyName &) const;
Chris@335 56 virtual QString getPropertyIconName(const PropertyName &) const;
Chris@0 57 virtual PropertyType getPropertyType(const PropertyName &) const;
Chris@0 58 virtual QString getPropertyGroupName(const PropertyName &) const;
Chris@0 59 virtual int getPropertyRangeAndValue(const PropertyName &,
Chris@216 60 int *min, int *max, int *deflt) const;
Chris@0 61 virtual QString getPropertyValueLabel(const PropertyName &,
Chris@0 62 int value) const;
Chris@167 63 virtual RangeMapper *getNewPropertyRangeMapper(const PropertyName &) const;
Chris@0 64 virtual void setProperty(const PropertyName &, int value);
Chris@0 65
Chris@0 66 /**
Chris@0 67 * Set the gain multiplier for sample values in this view.
Chris@0 68 *
Chris@0 69 * The default is 1.0.
Chris@0 70 */
Chris@0 71 void setGain(float gain);
Chris@0 72 float getGain() const { return m_gain; }
Chris@0 73
Chris@0 74 /**
Chris@67 75 * Toggle automatic normalization of the currently visible waveform.
Chris@67 76 */
Chris@67 77 void setAutoNormalize(bool);
Chris@67 78 bool getAutoNormalize() const { return m_autoNormalize; }
Chris@67 79
Chris@67 80 /**
Chris@0 81 * Set whether to display mean values as a lighter-coloured area
Chris@0 82 * beneath the peaks. Rendering will be slightly faster without
Chris@0 83 * but arguably prettier with.
Chris@0 84 *
Chris@0 85 * The default is to display means.
Chris@0 86 */
Chris@0 87 void setShowMeans(bool);
Chris@0 88 bool getShowMeans() const { return m_showMeans; }
Chris@0 89
Chris@0 90 /**
Chris@0 91 * Set whether to use shades of grey (or of the base colour) to
Chris@0 92 * provide additional perceived vertical resolution (i.e. using
Chris@0 93 * half-filled pixels to represent levels that only just meet the
Chris@0 94 * pixel unit boundary). This provides a small improvement in
Chris@0 95 * waveform quality at a small cost in rendering speed.
Chris@0 96 *
Chris@0 97 * The default is to use greyscale.
Chris@0 98 */
Chris@0 99 void setUseGreyscale(bool);
Chris@0 100 bool getUseGreyscale() const { return m_greyscale; }
Chris@0 101
Chris@0 102
Chris@67 103 enum ChannelMode { SeparateChannels, MixChannels, MergeChannels };
Chris@0 104
Chris@0 105 /**
Chris@0 106 * Specify whether multi-channel audio data should be displayed
Chris@67 107 * with a separate axis per channel (SeparateChannels), with a
Chris@0 108 * single synthetic axis showing channel 0 above the axis and
Chris@67 109 * channel 1 below (MergeChannels), or with a single axis showing
Chris@67 110 * the average of the channels (MixChannels).
Chris@0 111 *
Chris@0 112 * MergeChannels does not work for files with more than 2
Chris@0 113 * channels.
Chris@0 114 *
Chris@0 115 * The default is SeparateChannels.
Chris@0 116 */
Chris@0 117 void setChannelMode(ChannelMode);
Chris@0 118 ChannelMode getChannelMode() const { return m_channelMode; }
Chris@0 119
Chris@0 120
Chris@0 121 /**
Chris@0 122 * Specify the channel to use from the source model. A value of
Chris@0 123 * -1 means to show all available channels (laid out to the
Chris@0 124 * channel mode). The default is -1.
Chris@0 125 */
Chris@0 126 void setChannel(int);
Chris@0 127 int getChannel() const { return m_channel; }
Chris@0 128
Chris@0 129
Chris@0 130 enum Scale { LinearScale, MeterScale, dBScale };
Chris@0 131
Chris@0 132 /**
Chris@0 133 * Specify the vertical scale for sample levels. With LinearScale,
Chris@0 134 * the scale is directly proportional to the raw [-1, +1)
Chris@0 135 * floating-point audio sample values. With dBScale the
Chris@0 136 * vertical scale is proportional to dB level (truncated at
Chris@0 137 * -50dB). MeterScale provides a hybrid variable scale based on
Chris@0 138 * IEC meter scale, intended to provide a clear overview at
Chris@0 139 * relatively small heights.
Chris@0 140 *
Chris@0 141 * Note that the effective gain (see setGain()) is applied before
Chris@0 142 * vertical scaling.
Chris@0 143 *
Chris@0 144 * The default is LinearScale.
Chris@0 145 */
Chris@0 146 void setScale(Scale);
Chris@0 147 Scale getScale() const { return m_scale; }
Chris@0 148
Chris@0 149 /**
Chris@709 150 * Specify the height of the middle of the waveform track or
Chris@709 151 * tracks within the layer, from 0.0 to 1.0.
Chris@709 152 *
Chris@709 153 * A value of 0.0 would indicate that the waveform occupies
Chris@709 154 * effectively no space at the very top of the layer; 1.0 would
Chris@709 155 * indicate that the waveform occupies no space at the very
Chris@709 156 * bottom; the default value of 0.5 indicates that it occupies the
Chris@709 157 * whole layer, centred at the middle.
Chris@709 158 */
Chris@905 159 void setMiddleLineHeight(double);
Chris@905 160 double getMiddleLineHeight() const { return m_middleLineHeight; }
Chris@709 161
Chris@709 162 /**
Chris@0 163 * Enable or disable aggressive pixmap cacheing. If enabled,
Chris@0 164 * waveforms will be rendered to an off-screen pixmap and
Chris@0 165 * refreshed from there instead of being redrawn from the peak
Chris@0 166 * data each time. This may be faster if the data and zoom level
Chris@0 167 * do not change often, but it may be slower for frequently zoomed
Chris@0 168 * data and it will only work if the waveform is the "bottom"
Chris@0 169 * layer on the displayed widget, as each refresh will erase
Chris@0 170 * anything beneath the waveform.
Chris@0 171 *
Chris@0 172 * This is intended specifically for a panner widget display in
Chris@0 173 * which the waveform never moves, zooms, or changes, but some
Chris@0 174 * graphic such as a panner outline is frequently redrawn over the
Chris@0 175 * waveform. This situation would necessitate a lot of waveform
Chris@0 176 * refresh if the default cacheing strategy was used.
Chris@0 177 *
Chris@0 178 * The default is not to use aggressive cacheing.
Chris@0 179 */
Chris@0 180 void setAggressiveCacheing(bool);
Chris@0 181 bool getAggressiveCacheing() const { return m_aggressive; }
Chris@0 182
Chris@918 183 virtual bool isLayerScrollable(const LayerGeometryProvider *) const;
Chris@67 184
Chris@918 185 virtual int getCompletion(LayerGeometryProvider *) const;
Chris@0 186
Chris@905 187 virtual bool getValueExtents(double &min, double &max,
Chris@101 188 bool &log, QString &unit) const;
Chris@79 189
Chris@918 190 virtual bool getYScaleValue(const LayerGeometryProvider *v, int y,
Chris@905 191 double &value, QString &unit) const;
Chris@274 192
Chris@918 193 virtual bool getYScaleDifference(const LayerGeometryProvider *v, int y0, int y1,
Chris@905 194 double &diff, QString &unit) const;
Chris@261 195
Chris@316 196 virtual void toXml(QTextStream &stream, QString indent = "",
Chris@316 197 QString extraAttributes = "") const;
Chris@6 198
Chris@287 199 virtual void setProperties(const QXmlAttributes &attributes);
Chris@11 200
Chris@133 201 virtual int getVerticalZoomSteps(int &defaultStep) const;
Chris@133 202 virtual int getCurrentVerticalZoomStep() const;
Chris@133 203 virtual void setVerticalZoomStep(int);
Chris@133 204
Chris@947 205 virtual bool canExistWithoutModel() const { return true; }
Chris@947 206
Chris@0 207 protected:
Chris@908 208 int dBscale(double sample, int m) const;
Chris@0 209
Chris@0 210 const RangeSummarisableTimeValueModel *m_model; // I do not own this
Chris@0 211
Chris@0 212 /// Return value is number of channels displayed
Chris@805 213 int getChannelArrangement(int &min, int &max,
Chris@67 214 bool &merging, bool &mixing) const;
Chris@0 215
Chris@918 216 int getYForValue(const LayerGeometryProvider *v, double value, int channel) const;
Chris@68 217
Chris@918 218 double getValueForY(const LayerGeometryProvider *v, int y, int &channel) const;
Chris@261 219
Chris@918 220 bool getSourceFramesForX(LayerGeometryProvider *v, int x, int modelZoomLevel,
Chris@908 221 sv_frame_t &f0, sv_frame_t &f1) const;
Chris@365 222
Chris@918 223 float getNormalizeGain(LayerGeometryProvider *v, int channel) const;
Chris@365 224
Chris@287 225 virtual void flagBaseColourChanged() { m_cacheValid = false; }
Chris@287 226
Chris@6 227 float m_gain;
Chris@67 228 bool m_autoNormalize;
Chris@6 229 bool m_showMeans;
Chris@6 230 bool m_greyscale;
Chris@6 231 ChannelMode m_channelMode;
Chris@6 232 int m_channel;
Chris@6 233 Scale m_scale;
Chris@905 234 double m_middleLineHeight;
Chris@6 235 bool m_aggressive;
Chris@0 236
Chris@67 237 mutable std::vector<float> m_effectiveGains;
Chris@67 238
Chris@0 239 mutable QPixmap *m_cache;
Chris@0 240 mutable bool m_cacheValid;
Chris@0 241 mutable int m_cacheZoomLevel;
Chris@0 242 };
Chris@0 243
Chris@0 244 #endif