lbajardsilogic@0: /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ lbajardsilogic@0: lbajardsilogic@0: /* lbajardsilogic@0: Sonic Visualiser lbajardsilogic@0: An audio file viewer and annotation editor. lbajardsilogic@0: Centre for Digital Music, Queen Mary, University of London. lbajardsilogic@0: This file copyright 2006 Chris Cannam and QMUL. lbajardsilogic@0: lbajardsilogic@0: This program is free software; you can redistribute it and/or lbajardsilogic@0: modify it under the terms of the GNU General Public License as lbajardsilogic@0: published by the Free Software Foundation; either version 2 of the lbajardsilogic@0: License, or (at your option) any later version. See the file lbajardsilogic@0: COPYING included with this distribution for more information. lbajardsilogic@0: */ lbajardsilogic@0: lbajardsilogic@0: #ifndef _WAVEFORM_LAYER_H_ lbajardsilogic@0: #define _WAVEFORM_LAYER_H_ lbajardsilogic@0: lbajardsilogic@0: #include lbajardsilogic@0: #include lbajardsilogic@0: lbajardsilogic@0: #include "Layer.h" lbajardsilogic@0: lbajardsilogic@0: #include "data/model/RangeSummarisableTimeValueModel.h" lbajardsilogic@0: lbajardsilogic@0: class View; lbajardsilogic@0: class QPainter; lbajardsilogic@0: class QPixmap; lbajardsilogic@0: lbajardsilogic@0: class WaveformLayer : public Layer lbajardsilogic@0: { lbajardsilogic@0: Q_OBJECT lbajardsilogic@0: lbajardsilogic@0: public: lbajardsilogic@0: WaveformLayer(); lbajardsilogic@0: ~WaveformLayer(); lbajardsilogic@0: lbajardsilogic@0: virtual const ZoomConstraint *getZoomConstraint() const { lbajardsilogic@0: return m_model ? m_model->getZoomConstraint() : 0; lbajardsilogic@0: } lbajardsilogic@0: virtual const Model *getModel() const { return m_model; } lbajardsilogic@0: virtual void paint(View *v, QPainter &paint, QRect rect) const; lbajardsilogic@0: lbajardsilogic@0: virtual QString getFeatureDescription(View *v, QPoint &) const; lbajardsilogic@0: lbajardsilogic@0: virtual int getVerticalScaleWidth(View *v, QPainter &) const; lbajardsilogic@0: virtual void paintVerticalScale(View *v, QPainter &paint, QRect rect) const; lbajardsilogic@0: lbajardsilogic@0: void setModel(const RangeSummarisableTimeValueModel *model); lbajardsilogic@0: lbajardsilogic@0: virtual PropertyList getProperties() const; lbajardsilogic@0: virtual QString getPropertyLabel(const PropertyName &) const; lbajardsilogic@0: virtual PropertyType getPropertyType(const PropertyName &) const; lbajardsilogic@0: virtual QString getPropertyGroupName(const PropertyName &) const; lbajardsilogic@0: virtual int getPropertyRangeAndValue(const PropertyName &, lbajardsilogic@0: int *min, int *max, int *deflt) const; lbajardsilogic@0: virtual QString getPropertyValueLabel(const PropertyName &, lbajardsilogic@0: int value) const; lbajardsilogic@0: virtual RangeMapper *getNewPropertyRangeMapper(const PropertyName &) const; lbajardsilogic@0: virtual void setProperty(const PropertyName &, int value); lbajardsilogic@0: lbajardsilogic@0: /** lbajardsilogic@0: * Set the gain multiplier for sample values in this view. lbajardsilogic@0: * lbajardsilogic@0: * The default is 1.0. lbajardsilogic@0: */ lbajardsilogic@0: void setGain(float gain); lbajardsilogic@0: float getGain() const { return m_gain; } lbajardsilogic@0: lbajardsilogic@0: /** lbajardsilogic@0: * Toggle automatic normalization of the currently visible waveform. lbajardsilogic@0: */ lbajardsilogic@0: void setAutoNormalize(bool); lbajardsilogic@0: bool getAutoNormalize() const { return m_autoNormalize; } lbajardsilogic@0: benoitrigolleau@61: virtual void setBaseColour(QColor); benoitrigolleau@61: virtual QColor getBaseColour() const {return m_colour; } lbajardsilogic@0: lbajardsilogic@0: /** lbajardsilogic@0: * Set whether to display mean values as a lighter-coloured area lbajardsilogic@0: * beneath the peaks. Rendering will be slightly faster without lbajardsilogic@0: * but arguably prettier with. lbajardsilogic@0: * lbajardsilogic@0: * The default is to display means. lbajardsilogic@0: */ lbajardsilogic@0: void setShowMeans(bool); lbajardsilogic@0: bool getShowMeans() const { return m_showMeans; } lbajardsilogic@0: lbajardsilogic@0: /** lbajardsilogic@0: * Set whether to use shades of grey (or of the base colour) to lbajardsilogic@0: * provide additional perceived vertical resolution (i.e. using lbajardsilogic@0: * half-filled pixels to represent levels that only just meet the lbajardsilogic@0: * pixel unit boundary). This provides a small improvement in lbajardsilogic@0: * waveform quality at a small cost in rendering speed. lbajardsilogic@0: * lbajardsilogic@0: * The default is to use greyscale. lbajardsilogic@0: */ lbajardsilogic@0: void setUseGreyscale(bool); lbajardsilogic@0: bool getUseGreyscale() const { return m_greyscale; } lbajardsilogic@0: lbajardsilogic@0: lbajardsilogic@0: enum ChannelMode { SeparateChannels, MixChannels, MergeChannels }; lbajardsilogic@0: lbajardsilogic@0: /** lbajardsilogic@0: * Specify whether multi-channel audio data should be displayed lbajardsilogic@0: * with a separate axis per channel (SeparateChannels), with a lbajardsilogic@0: * single synthetic axis showing channel 0 above the axis and lbajardsilogic@0: * channel 1 below (MergeChannels), or with a single axis showing lbajardsilogic@0: * the average of the channels (MixChannels). lbajardsilogic@0: * lbajardsilogic@0: * MergeChannels does not work for files with more than 2 lbajardsilogic@0: * channels. lbajardsilogic@0: * lbajardsilogic@0: * The default is SeparateChannels. lbajardsilogic@0: */ lbajardsilogic@0: void setChannelMode(ChannelMode); lbajardsilogic@0: ChannelMode getChannelMode() const { return m_channelMode; } lbajardsilogic@0: lbajardsilogic@0: lbajardsilogic@0: /** lbajardsilogic@0: * Specify the channel to use from the source model. A value of lbajardsilogic@0: * -1 means to show all available channels (laid out to the lbajardsilogic@0: * channel mode). The default is -1. lbajardsilogic@0: */ lbajardsilogic@0: void setChannel(int); lbajardsilogic@0: int getChannel() const { return m_channel; } lbajardsilogic@0: lbajardsilogic@0: lbajardsilogic@0: enum Scale { LinearScale, MeterScale, dBScale }; lbajardsilogic@0: lbajardsilogic@0: /** lbajardsilogic@0: * Specify the vertical scale for sample levels. With LinearScale, lbajardsilogic@0: * the scale is directly proportional to the raw [-1, +1) lbajardsilogic@0: * floating-point audio sample values. With dBScale the lbajardsilogic@0: * vertical scale is proportional to dB level (truncated at lbajardsilogic@0: * -50dB). MeterScale provides a hybrid variable scale based on lbajardsilogic@0: * IEC meter scale, intended to provide a clear overview at lbajardsilogic@0: * relatively small heights. lbajardsilogic@0: * lbajardsilogic@0: * Note that the effective gain (see setGain()) is applied before lbajardsilogic@0: * vertical scaling. lbajardsilogic@0: * lbajardsilogic@0: * The default is LinearScale. lbajardsilogic@0: */ lbajardsilogic@0: void setScale(Scale); lbajardsilogic@0: Scale getScale() const { return m_scale; } lbajardsilogic@0: lbajardsilogic@0: /** lbajardsilogic@0: * Enable or disable aggressive pixmap cacheing. If enabled, lbajardsilogic@0: * waveforms will be rendered to an off-screen pixmap and lbajardsilogic@0: * refreshed from there instead of being redrawn from the peak lbajardsilogic@0: * data each time. This may be faster if the data and zoom level lbajardsilogic@0: * do not change often, but it may be slower for frequently zoomed lbajardsilogic@0: * data and it will only work if the waveform is the "bottom" lbajardsilogic@0: * layer on the displayed widget, as each refresh will erase lbajardsilogic@0: * anything beneath the waveform. lbajardsilogic@0: * lbajardsilogic@0: * This is intended specifically for a panner widget display in lbajardsilogic@0: * which the waveform never moves, zooms, or changes, but some lbajardsilogic@0: * graphic such as a panner outline is frequently redrawn over the lbajardsilogic@0: * waveform. This situation would necessitate a lot of waveform lbajardsilogic@0: * refresh if the default cacheing strategy was used. lbajardsilogic@0: * lbajardsilogic@0: * The default is not to use aggressive cacheing. lbajardsilogic@0: */ lbajardsilogic@0: void setAggressiveCacheing(bool); lbajardsilogic@0: bool getAggressiveCacheing() const { return m_aggressive; } lbajardsilogic@0: lbajardsilogic@0: virtual bool isLayerScrollable(const View *) const; lbajardsilogic@0: lbajardsilogic@0: virtual int getCompletion(View *) const; lbajardsilogic@0: lbajardsilogic@0: virtual bool getValueExtents(float &min, float &max, lbajardsilogic@0: bool &log, QString &unit) const; lbajardsilogic@0: lbajardsilogic@0: virtual QString toXmlString(QString indent = "", lbajardsilogic@0: QString extraAttributes = "") const; lbajardsilogic@0: lbajardsilogic@18: virtual QString toEasaierXmlString(QString indent = "", lbajardsilogic@18: QString extraAttributes = "") const; lbajardsilogic@18: lbajardsilogic@0: void setProperties(const QXmlAttributes &attributes); lbajardsilogic@0: lbajardsilogic@0: virtual int getVerticalZoomSteps(int &defaultStep) const; lbajardsilogic@0: virtual int getCurrentVerticalZoomStep() const; lbajardsilogic@0: virtual void setVerticalZoomStep(int); lbajardsilogic@0: lbajardsilogic@0: protected: lbajardsilogic@0: int dBscale(float sample, int m) const; lbajardsilogic@0: lbajardsilogic@0: const RangeSummarisableTimeValueModel *m_model; // I do not own this lbajardsilogic@0: lbajardsilogic@0: /// Return value is number of channels displayed lbajardsilogic@0: size_t getChannelArrangement(size_t &min, size_t &max, lbajardsilogic@0: bool &merging, bool &mixing) const; lbajardsilogic@0: lbajardsilogic@0: int getYForValue(View *v, Scale scale, float value, size_t channel, lbajardsilogic@0: size_t minChannel, size_t maxChannel) const; lbajardsilogic@0: lbajardsilogic@0: float m_gain; lbajardsilogic@0: bool m_autoNormalize; lbajardsilogic@0: bool m_showMeans; lbajardsilogic@0: bool m_greyscale; lbajardsilogic@0: ChannelMode m_channelMode; lbajardsilogic@0: int m_channel; lbajardsilogic@0: Scale m_scale; lbajardsilogic@0: bool m_aggressive; benoitrigolleau@61: QColor m_colour; lbajardsilogic@0: lbajardsilogic@0: mutable std::vector m_effectiveGains; lbajardsilogic@0: lbajardsilogic@0: mutable QPixmap *m_cache; lbajardsilogic@0: mutable bool m_cacheValid; lbajardsilogic@0: mutable int m_cacheZoomLevel; lbajardsilogic@0: }; lbajardsilogic@0: lbajardsilogic@0: #endif