annotate layer/WaveformLayer.h @ 1447:8afea53332f3 single-point

Add option to make pane sizes auto-resize-only (i.e. remove user control via a splitter); also place alignment views above panes instead of below, meaning the extra bit of space that we currently have for the pane without one at least goes to the primary pane
author Chris Cannam
date Tue, 30 Apr 2019 15:53:21 +0100
parents 05d614f6e46d
children 696e569ff21b
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@1407 16 #ifndef SV_WAVEFORM_LAYER_H
Chris@1407 17 #define SV_WAVEFORM_LAYER_H
Chris@0 18
Chris@0 19 #include <QRect>
Chris@0 20
Chris@287 21 #include "SingleColourLayer.h"
Chris@0 22
Chris@1375 23 #include "base/ZoomLevel.h"
Chris@1375 24
Chris@128 25 #include "data/model/RangeSummarisableTimeValueModel.h"
Chris@0 26
Chris@0 27 class View;
Chris@0 28 class QPainter;
Chris@0 29 class QPixmap;
Chris@0 30
Chris@287 31 class WaveformLayer : public SingleColourLayer
Chris@0 32 {
Chris@0 33 Q_OBJECT
Chris@0 34
Chris@0 35 public:
Chris@44 36 WaveformLayer();
Chris@0 37 ~WaveformLayer();
Chris@0 38
Chris@1406 39 const ZoomConstraint *getZoomConstraint() const override {
Chris@156 40 return m_model ? m_model->getZoomConstraint() : 0;
Chris@156 41 }
Chris@1406 42 const Model *getModel() const override { return m_model; }
Chris@1406 43 void paint(LayerGeometryProvider *v, QPainter &paint, QRect rect) const override;
Chris@0 44
Chris@1406 45 QString getFeatureDescription(LayerGeometryProvider *v, QPoint &) const override;
Chris@25 46
Chris@1406 47 ColourSignificance getLayerColourSignificance() const override {
Chris@287 48 return ColourAndBackgroundSignificant;
Chris@287 49 }
Chris@287 50
Chris@1406 51 int getVerticalScaleWidth(LayerGeometryProvider *v, bool detailed, QPainter &) const override;
Chris@1406 52 void paintVerticalScale(LayerGeometryProvider *v, bool detailed, QPainter &paint, QRect rect) const override;
Chris@0 53
Chris@0 54 void setModel(const RangeSummarisableTimeValueModel *model);
Chris@0 55
Chris@1406 56 PropertyList getProperties() const override;
Chris@1406 57 QString getPropertyLabel(const PropertyName &) const override;
Chris@1406 58 QString getPropertyIconName(const PropertyName &) const override;
Chris@1406 59 PropertyType getPropertyType(const PropertyName &) const override;
Chris@1406 60 QString getPropertyGroupName(const PropertyName &) const override;
Chris@1406 61 int getPropertyRangeAndValue(const PropertyName &,
Chris@1406 62 int *min, int *max, int *deflt) const override;
Chris@1406 63 QString getPropertyValueLabel(const PropertyName &,
Chris@1406 64 int value) const override;
Chris@1406 65 RangeMapper *getNewPropertyRangeMapper(const PropertyName &) const override;
Chris@1406 66 void setProperty(const PropertyName &, int value) override;
Chris@0 67
Chris@0 68 /**
Chris@0 69 * Set the gain multiplier for sample values in this view.
Chris@0 70 *
Chris@0 71 * The default is 1.0.
Chris@0 72 */
Chris@0 73 void setGain(float gain);
Chris@0 74 float getGain() const { return m_gain; }
Chris@0 75
Chris@0 76 /**
Chris@67 77 * Toggle automatic normalization of the currently visible waveform.
Chris@67 78 */
Chris@67 79 void setAutoNormalize(bool);
Chris@67 80 bool getAutoNormalize() const { return m_autoNormalize; }
Chris@67 81
Chris@67 82 /**
Chris@0 83 * Set whether to display mean values as a lighter-coloured area
Chris@0 84 * beneath the peaks. Rendering will be slightly faster without
Chris@0 85 * but arguably prettier with.
Chris@0 86 *
Chris@0 87 * The default is to display means.
Chris@0 88 */
Chris@0 89 void setShowMeans(bool);
Chris@0 90 bool getShowMeans() const { return m_showMeans; }
Chris@0 91
Chris@67 92 enum ChannelMode { SeparateChannels, MixChannels, MergeChannels };
Chris@0 93
Chris@0 94 /**
Chris@0 95 * Specify whether multi-channel audio data should be displayed
Chris@67 96 * with a separate axis per channel (SeparateChannels), with a
Chris@0 97 * single synthetic axis showing channel 0 above the axis and
Chris@67 98 * channel 1 below (MergeChannels), or with a single axis showing
Chris@67 99 * the average of the channels (MixChannels).
Chris@0 100 *
Chris@0 101 * MergeChannels does not work for files with more than 2
Chris@0 102 * channels.
Chris@0 103 *
Chris@0 104 * The default is SeparateChannels.
Chris@0 105 */
Chris@0 106 void setChannelMode(ChannelMode);
Chris@0 107 ChannelMode getChannelMode() const { return m_channelMode; }
Chris@0 108
Chris@0 109
Chris@0 110 /**
Chris@0 111 * Specify the channel to use from the source model. A value of
Chris@0 112 * -1 means to show all available channels (laid out to the
Chris@0 113 * channel mode). The default is -1.
Chris@0 114 */
Chris@0 115 void setChannel(int);
Chris@0 116 int getChannel() const { return m_channel; }
Chris@0 117
Chris@0 118
Chris@0 119 enum Scale { LinearScale, MeterScale, dBScale };
Chris@0 120
Chris@0 121 /**
Chris@0 122 * Specify the vertical scale for sample levels. With LinearScale,
Chris@0 123 * the scale is directly proportional to the raw [-1, +1)
Chris@0 124 * floating-point audio sample values. With dBScale the
Chris@0 125 * vertical scale is proportional to dB level (truncated at
Chris@0 126 * -50dB). MeterScale provides a hybrid variable scale based on
Chris@0 127 * IEC meter scale, intended to provide a clear overview at
Chris@0 128 * relatively small heights.
Chris@0 129 *
Chris@0 130 * Note that the effective gain (see setGain()) is applied before
Chris@0 131 * vertical scaling.
Chris@0 132 *
Chris@0 133 * The default is LinearScale.
Chris@0 134 */
Chris@0 135 void setScale(Scale);
Chris@0 136 Scale getScale() const { return m_scale; }
Chris@0 137
Chris@0 138 /**
Chris@709 139 * Specify the height of the middle of the waveform track or
Chris@709 140 * tracks within the layer, from 0.0 to 1.0.
Chris@709 141 *
Chris@709 142 * A value of 0.0 would indicate that the waveform occupies
Chris@709 143 * effectively no space at the very top of the layer; 1.0 would
Chris@709 144 * indicate that the waveform occupies no space at the very
Chris@709 145 * bottom; the default value of 0.5 indicates that it occupies the
Chris@709 146 * whole layer, centred at the middle.
Chris@709 147 */
Chris@905 148 void setMiddleLineHeight(double);
Chris@905 149 double getMiddleLineHeight() const { return m_middleLineHeight; }
Chris@709 150
Chris@709 151 /**
Chris@0 152 * Enable or disable aggressive pixmap cacheing. If enabled,
Chris@0 153 * waveforms will be rendered to an off-screen pixmap and
Chris@0 154 * refreshed from there instead of being redrawn from the peak
Chris@0 155 * data each time. This may be faster if the data and zoom level
Chris@0 156 * do not change often, but it may be slower for frequently zoomed
Chris@0 157 * data and it will only work if the waveform is the "bottom"
Chris@0 158 * layer on the displayed widget, as each refresh will erase
Chris@0 159 * anything beneath the waveform.
Chris@0 160 *
Chris@0 161 * This is intended specifically for a panner widget display in
Chris@0 162 * which the waveform never moves, zooms, or changes, but some
Chris@0 163 * graphic such as a panner outline is frequently redrawn over the
Chris@0 164 * waveform. This situation would necessitate a lot of waveform
Chris@0 165 * refresh if the default cacheing strategy was used.
Chris@0 166 *
Chris@0 167 * The default is not to use aggressive cacheing.
Chris@0 168 */
Chris@0 169 void setAggressiveCacheing(bool);
Chris@0 170 bool getAggressiveCacheing() const { return m_aggressive; }
Chris@0 171
Chris@1406 172 bool isLayerScrollable(const LayerGeometryProvider *) const override;
Chris@67 173
Chris@1406 174 int getCompletion(LayerGeometryProvider *) const override;
Chris@0 175
Chris@1406 176 bool getValueExtents(double &min, double &max,
Chris@1406 177 bool &log, QString &unit) const override;
Chris@79 178
Chris@1406 179 bool getYScaleValue(const LayerGeometryProvider *v, int y,
Chris@1406 180 double &value, QString &unit) const override;
Chris@274 181
Chris@1406 182 bool getYScaleDifference(const LayerGeometryProvider *v, int y0, int y1,
Chris@1406 183 double &diff, QString &unit) const override;
Chris@261 184
Chris@1406 185 void toXml(QTextStream &stream, QString indent = "",
Chris@1406 186 QString extraAttributes = "") const override;
Chris@6 187
Chris@1406 188 void setProperties(const QXmlAttributes &attributes) override;
Chris@11 189
Chris@1406 190 int getVerticalZoomSteps(int &defaultStep) const override;
Chris@1406 191 int getCurrentVerticalZoomStep() const override;
Chris@1406 192 void setVerticalZoomStep(int) override;
Chris@133 193
Chris@1406 194 bool canExistWithoutModel() const override { return true; }
Chris@947 195
Chris@0 196 protected:
Chris@1367 197 double dBscale(double sample, int m) const;
Chris@0 198
Chris@0 199 const RangeSummarisableTimeValueModel *m_model; // I do not own this
Chris@0 200
Chris@1338 201 typedef std::vector<RangeSummarisableTimeValueModel::RangeBlock> RangeVec;
Chris@1338 202
Chris@0 203 /// Return value is number of channels displayed
Chris@805 204 int getChannelArrangement(int &min, int &max,
Chris@1332 205 bool &merging, bool &mixing) const;
Chris@0 206
Chris@1338 207 void paintChannel
Chris@1336 208 (LayerGeometryProvider *, QPainter *paint, QRect rect, int channel,
Chris@1338 209 const RangeVec &ranges,
Chris@1336 210 int blockSize, sv_frame_t frame0, sv_frame_t frame1) const;
Chris@1336 211
Chris@1335 212 void paintChannelScaleGuides(LayerGeometryProvider *, QPainter *paint,
Chris@1335 213 QRect rect, int channel) const;
Chris@1338 214
Chris@1338 215 void getSummaryRanges(int minChannel, int maxChannel,
Chris@1338 216 bool mixingOrMerging,
Chris@1338 217 sv_frame_t f0, sv_frame_t f1,
Chris@1338 218 int blockSize, RangeVec &ranges) const;
Chris@1338 219
Chris@1338 220 void getOversampledRanges(int minChannel, int maxChannel,
Chris@1338 221 bool mixingOrMerging,
Chris@1338 222 sv_frame_t f0, sv_frame_t f1,
Chris@1338 223 int oversampleBy, RangeVec &ranges) const;
Chris@1332 224
Chris@918 225 int getYForValue(const LayerGeometryProvider *v, double value, int channel) const;
Chris@68 226
Chris@918 227 double getValueForY(const LayerGeometryProvider *v, int y, int &channel) const;
Chris@261 228
Chris@918 229 bool getSourceFramesForX(LayerGeometryProvider *v, int x, int modelZoomLevel,
Chris@908 230 sv_frame_t &f0, sv_frame_t &f1) const;
Chris@365 231
Chris@918 232 float getNormalizeGain(LayerGeometryProvider *v, int channel) const;
Chris@365 233
Chris@1406 234 void flagBaseColourChanged() override { m_cacheValid = false; }
Chris@287 235
Chris@6 236 float m_gain;
Chris@67 237 bool m_autoNormalize;
Chris@6 238 bool m_showMeans;
Chris@6 239 ChannelMode m_channelMode;
Chris@6 240 int m_channel;
Chris@6 241 Scale m_scale;
Chris@905 242 double m_middleLineHeight;
Chris@6 243 bool m_aggressive;
Chris@0 244
Chris@67 245 mutable std::vector<float> m_effectiveGains;
Chris@67 246
Chris@0 247 mutable QPixmap *m_cache;
Chris@0 248 mutable bool m_cacheValid;
Chris@1325 249 mutable ZoomLevel m_cacheZoomLevel;
Chris@0 250 };
Chris@0 251
Chris@0 252 #endif