| Chris@1071 | 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */ | 
| Chris@1071 | 2 | 
| Chris@1071 | 3 /* | 
| Chris@1071 | 4     Sonic Visualiser | 
| Chris@1071 | 5     An audio file viewer and annotation editor. | 
| Chris@1071 | 6     Centre for Digital Music, Queen Mary, University of London. | 
| Chris@1071 | 7     This file copyright 2006-2016 Chris Cannam and QMUL. | 
| Chris@1071 | 8 | 
| Chris@1071 | 9     This program is free software; you can redistribute it and/or | 
| Chris@1071 | 10     modify it under the terms of the GNU General Public License as | 
| Chris@1071 | 11     published by the Free Software Foundation; either version 2 of the | 
| Chris@1071 | 12     License, or (at your option) any later version.  See the file | 
| Chris@1071 | 13     COPYING included with this distribution for more information. | 
| Chris@1071 | 14 */ | 
| Chris@1071 | 15 | 
| Chris@1071 | 16 #ifndef COLOUR_3D_PLOT_RENDERER_H | 
| Chris@1071 | 17 #define COLOUR_3D_PLOT_RENDERER_H | 
| Chris@1071 | 18 | 
| Chris@1071 | 19 #include "ColourScale.h" | 
| Chris@1073 | 20 #include "ScrollableImageCache.h" | 
| Chris@1071 | 21 | 
| Chris@1071 | 22 #include "base/ColumnOp.h" | 
| Chris@1073 | 23 #include "base/MagnitudeRange.h" | 
| Chris@1071 | 24 | 
| Chris@1073 | 25 #include <QRect> | 
| Chris@1073 | 26 #include <QPainter> | 
| Chris@1073 | 27 #include <QImage> | 
| Chris@1073 | 28 | 
| Chris@1073 | 29 class LayerGeometryProvider; | 
| Chris@1071 | 30 class DenseThreeDimensionalModel; | 
| Chris@1071 | 31 class Dense3DModelPeakCache; | 
| Chris@1071 | 32 class FFTModel; | 
| Chris@1071 | 33 | 
| Chris@1071 | 34 class Colour3DPlotRenderer | 
| Chris@1071 | 35 { | 
| Chris@1071 | 36 public: | 
| Chris@1071 | 37     enum BinDisplay { | 
| Chris@1071 | 38 	AllBins, | 
| Chris@1071 | 39 	PeakBins, | 
| Chris@1071 | 40 	PeakFrequencies | 
| Chris@1071 | 41     }; | 
| Chris@1071 | 42 | 
| Chris@1071 | 43     enum BinScale { | 
| Chris@1071 | 44 	LinearBinScale, | 
| Chris@1071 | 45 	LogBinScale | 
| Chris@1071 | 46     }; | 
| Chris@1073 | 47 | 
| Chris@1073 | 48     struct Sources { | 
| Chris@1073 | 49         Sources() : geometryProvider(0), source(0), peaks(0), fft(0) { } | 
| Chris@1073 | 50 | 
| Chris@1073 | 51         // These must all outlive this class | 
| Chris@1073 | 52         LayerGeometryProvider *geometryProvider; // always | 
| Chris@1073 | 53 	DenseThreeDimensionalModel *source;      // always | 
| Chris@1073 | 54 	Dense3DModelPeakCache *peaks;	         // optionally | 
| Chris@1073 | 55 	FFTModel *fft;			         // optionally | 
| Chris@1073 | 56     }; | 
| Chris@1073 | 57 | 
| Chris@1071 | 58     struct Parameters { | 
| Chris@1071 | 59 	Parameters() : | 
| Chris@1071 | 60 	    colourScale(ColourScale::Parameters()), | 
| Chris@1071 | 61 	    normalization(ColumnOp::NoNormalization), | 
| Chris@1073 | 62 	    binDisplay(AllBins), | 
| Chris@1073 | 63             binScale(LinearBinScale), | 
| Chris@1073 | 64 	    alwaysOpaque(false), | 
| Chris@1073 | 65             interpolate(false), | 
| Chris@1073 | 66             invertVertical(false) { } | 
| Chris@1071 | 67 | 
| Chris@1071 | 68 	ColourScale colourScale;       // complete ColourScale object by value | 
| Chris@1071 | 69 	ColumnOp::Normalization normalization; | 
| Chris@1071 | 70 	BinDisplay binDisplay; | 
| Chris@1071 | 71 	BinScale binScale; | 
| Chris@1071 | 72 	bool alwaysOpaque; | 
| Chris@1071 | 73 	bool interpolate; | 
| Chris@1071 | 74 	bool invertVertical; | 
| Chris@1071 | 75     }; | 
| Chris@1073 | 76 | 
| Chris@1073 | 77     Colour3DPlotRenderer(Sources sources, Parameters parameters) : | 
| Chris@1073 | 78         m_sources(sources), | 
| Chris@1073 | 79 	m_params(parameters), | 
| Chris@1073 | 80         m_bufferResolution(PixelResolution) | 
| Chris@1071 | 81     { } | 
| Chris@1071 | 82 | 
| Chris@1073 | 83     struct RenderResult { | 
| Chris@1073 | 84         /** | 
| Chris@1073 | 85          * The rect that was actually rendered. May be equal to the | 
| Chris@1073 | 86          * rect that was requested to render, or may be smaller if | 
| Chris@1073 | 87          * time ran out and the complete flag was not set. | 
| Chris@1073 | 88          */ | 
| Chris@1073 | 89         QRect rendered; | 
| Chris@1073 | 90 | 
| Chris@1073 | 91         /** | 
| Chris@1073 | 92          * The magnitude range of the data in the rendered area. | 
| Chris@1073 | 93          */ | 
| Chris@1073 | 94         MagnitudeRange range; | 
| Chris@1073 | 95     }; | 
| Chris@1073 | 96 | 
| Chris@1073 | 97     /** | 
| Chris@1073 | 98      * Render the requested area using the given painter, obtaining | 
| Chris@1073 | 99      * geometry (e.g. start frame) from the stored | 
| Chris@1073 | 100      * LayerGeometryProvider. | 
| Chris@1073 | 101      * | 
| Chris@1073 | 102      * If complete is false, as much of the rect will be rendered as | 
| Chris@1073 | 103      * can be managed given internal time constraints. The returned | 
| Chris@1073 | 104      * QRect (the rendered field in the RenderResult struct) will | 
| Chris@1073 | 105      * contain the area that was rendered. Note that we always render | 
| Chris@1073 | 106      * the full requested height, it's only width that is | 
| Chris@1073 | 107      * time-constrained. | 
| Chris@1073 | 108      * | 
| Chris@1073 | 109      * If complete is true, the whole rect will be rendered and the | 
| Chris@1073 | 110      * returned QRect will be equal to the passed QRect. | 
| Chris@1075 | 111      * | 
| Chris@1075 | 112      * If the model to render from is not ready, this will throw a | 
| Chris@1075 | 113      * std::logic_error exception. The model must be ready and the | 
| Chris@1075 | 114      * layer requesting the render must not be dormant in its view, so | 
| Chris@1075 | 115      * that the LayerGeometryProvider returns valid results; it is the | 
| Chris@1075 | 116      * caller's responsibility to ensure these. | 
| Chris@1073 | 117      */ | 
| Chris@1073 | 118     RenderResult render(QPainter &paint, | 
| Chris@1073 | 119                         QRect rect, | 
| Chris@1073 | 120                         bool complete); | 
| Chris@1073 | 121 | 
| Chris@1071 | 122 private: | 
| Chris@1073 | 123     Sources m_sources; | 
| Chris@1071 | 124     Parameters m_params; | 
| Chris@1072 | 125 | 
| Chris@1073 | 126     // Draw buffer is the target of each partial repaint. It is always | 
| Chris@1073 | 127     // at view height (not model height) and is cleared and repainted | 
| Chris@1073 | 128     // on each fragment render. The only reason it's stored as a data | 
| Chris@1073 | 129     // member is to avoid reallocation. | 
| Chris@1073 | 130     QImage m_drawBuffer; | 
| Chris@1072 | 131 | 
| Chris@1073 | 132     // Indicates whether the draw buffer is rendered at bin resolution | 
| Chris@1073 | 133     // or at pixel resolution. Pixel resolution is used when the zoom | 
| Chris@1073 | 134     // level is such that each pixel is backed by more than one bin; | 
| Chris@1073 | 135     // bin resolution is used when the zoom level is such that each | 
| Chris@1073 | 136     // bin is drawn to more than one pixel. | 
| Chris@1073 | 137     enum BufferResolution { | 
| Chris@1073 | 138         BinResolution, | 
| Chris@1073 | 139         PixelResolution | 
| Chris@1073 | 140     }; | 
| Chris@1073 | 141     BufferResolution m_bufferResolution; | 
| Chris@1073 | 142 | 
| Chris@1073 | 143     // Image cache is our persistent record of the visible area. It is | 
| Chris@1073 | 144     // always the same size as the view (i.e. the paint size reported | 
| Chris@1073 | 145     // by the LayerGeometryProvider) and is scrolled and partially | 
| Chris@1073 | 146     // repainted internally as appropriate. A render request is | 
| Chris@1073 | 147     // carried out by repainting to cache (via the draw buffer) any | 
| Chris@1073 | 148     // area that is being requested but is not valid in the cache, and | 
| Chris@1073 | 149     // then repainting from cache to the requested painter. | 
| Chris@1073 | 150     ScrollableImageCache m_cache; | 
| Chris@1073 | 151 | 
| Chris@1073 | 152 | 
| Chris@1072 | 153     //!!! fft model scaling? | 
| Chris@1072 | 154 | 
| Chris@1072 | 155     //!!! should we own the Dense3DModelPeakCache here? or should it persist | 
| Chris@1071 | 156 }; | 
| Chris@1071 | 157 | 
| Chris@1071 | 158 #endif | 
| Chris@1071 | 159 |