Chris@147
|
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
|
Chris@147
|
2
|
Chris@147
|
3 /*
|
Chris@147
|
4 Sonic Visualiser
|
Chris@147
|
5 An audio file viewer and annotation editor.
|
Chris@147
|
6 Centre for Digital Music, Queen Mary, University of London.
|
Chris@202
|
7 This file copyright 2006 Chris Cannam and QMUL.
|
Chris@147
|
8
|
Chris@147
|
9 This program is free software; you can redistribute it and/or
|
Chris@147
|
10 modify it under the terms of the GNU General Public License as
|
Chris@147
|
11 published by the Free Software Foundation; either version 2 of the
|
Chris@147
|
12 License, or (at your option) any later version. See the file
|
Chris@147
|
13 COPYING included with this distribution for more information.
|
Chris@147
|
14 */
|
Chris@147
|
15
|
Chris@147
|
16 #ifndef _DENSE_THREE_DIMENSIONAL_MODEL_H_
|
Chris@147
|
17 #define _DENSE_THREE_DIMENSIONAL_MODEL_H_
|
Chris@147
|
18
|
Chris@150
|
19 #include "Model.h"
|
Chris@500
|
20 #include "TabularModel.h"
|
Chris@1187
|
21 #include "base/ColumnOp.h"
|
Chris@147
|
22 #include "base/ZoomConstraint.h"
|
Chris@500
|
23 #include "base/RealTime.h"
|
Chris@147
|
24
|
Chris@147
|
25 #include <QMutex>
|
Chris@533
|
26 #include <QVector>
|
Chris@147
|
27
|
Chris@500
|
28 class DenseThreeDimensionalModel : public Model,
|
Chris@500
|
29 public TabularModel
|
Chris@147
|
30 {
|
Chris@147
|
31 Q_OBJECT
|
Chris@147
|
32
|
Chris@147
|
33 public:
|
Chris@147
|
34 /**
|
Chris@182
|
35 * Return the number of sample frames covered by each column of bins.
|
Chris@147
|
36 */
|
Chris@929
|
37 virtual int getResolution() const = 0;
|
Chris@147
|
38
|
Chris@147
|
39 /**
|
Chris@182
|
40 * Return the number of columns of bins in the model.
|
Chris@147
|
41 */
|
Chris@929
|
42 virtual int getWidth() const = 0;
|
Chris@147
|
43
|
Chris@147
|
44 /**
|
Chris@182
|
45 * Return the number of bins in each column.
|
Chris@182
|
46 */
|
Chris@929
|
47 virtual int getHeight() const = 0;
|
Chris@182
|
48
|
Chris@182
|
49 /**
|
Chris@182
|
50 * Return the minimum permissible value in each bin.
|
Chris@147
|
51 */
|
Chris@152
|
52 virtual float getMinimumLevel() const = 0;
|
Chris@147
|
53
|
Chris@147
|
54 /**
|
Chris@182
|
55 * Return the maximum permissible value in each bin.
|
Chris@147
|
56 */
|
Chris@152
|
57 virtual float getMaximumLevel() const = 0;
|
Chris@147
|
58
|
Chris@1187
|
59 typedef ColumnOp::Column Column;
|
Chris@147
|
60
|
Chris@147
|
61 /**
|
Chris@182
|
62 * Get data from the given column of bin values.
|
Chris@147
|
63 */
|
Chris@929
|
64 virtual Column getColumn(int column) const = 0;
|
Chris@147
|
65
|
Chris@147
|
66 /**
|
Chris@182
|
67 * Get the single data point from the n'th bin of the given column.
|
Chris@147
|
68 */
|
Chris@929
|
69 virtual float getValueAt(int column, int n) const = 0;
|
Chris@147
|
70
|
Chris@182
|
71 /**
|
Chris@182
|
72 * Get the name of a given bin (i.e. a label to associate with
|
Chris@182
|
73 * that bin across all columns).
|
Chris@182
|
74 */
|
Chris@929
|
75 virtual QString getBinName(int n) const = 0;
|
Chris@147
|
76
|
Chris@182
|
77 /**
|
Chris@887
|
78 * Return true if the bins have values as well as names. If this
|
Chris@887
|
79 * returns true, getBinValue() may be used to retrieve the values.
|
Chris@887
|
80 */
|
Chris@887
|
81 virtual bool hasBinValues() const { return false; }
|
Chris@887
|
82
|
Chris@887
|
83 /**
|
Chris@887
|
84 * Return the value of bin n, if any. This is a "vertical scale"
|
Chris@887
|
85 * value which does not vary from one column to the next. This is
|
Chris@887
|
86 * only meaningful if hasBinValues() returns true.
|
Chris@887
|
87 */
|
Chris@1038
|
88 virtual float getBinValue(int n) const { return float(n); }
|
Chris@887
|
89
|
Chris@887
|
90 /**
|
Chris@887
|
91 * Obtain the name of the unit of the values returned from
|
Chris@887
|
92 * getBinValue(), if any.
|
Chris@887
|
93 */
|
Chris@887
|
94 virtual QString getBinValueUnit() const { return ""; }
|
Chris@887
|
95
|
Chris@887
|
96 /**
|
Chris@478
|
97 * Estimate whether a logarithmic scale might be appropriate for
|
Chris@478
|
98 * the value scale.
|
Chris@478
|
99 */
|
Chris@478
|
100 virtual bool shouldUseLogValueScale() const = 0;
|
Chris@478
|
101
|
Chris@478
|
102 /**
|
Chris@182
|
103 * Utility function to query whether a given bin is greater than
|
Chris@182
|
104 * its (vertical) neighbours.
|
Chris@182
|
105 */
|
Chris@929
|
106 bool isLocalPeak(int x, int y) {
|
Chris@182
|
107 float value = getValueAt(x, y);
|
Chris@182
|
108 if (y > 0 && value < getValueAt(x, y - 1)) return false;
|
Chris@182
|
109 if (y < getHeight() - 1 && value < getValueAt(x, y + 1)) return false;
|
Chris@182
|
110 return true;
|
Chris@182
|
111 }
|
Chris@182
|
112
|
Chris@182
|
113 /**
|
Chris@182
|
114 * Utility function to query whether a given bin is greater than a
|
Chris@182
|
115 * certain threshold.
|
Chris@182
|
116 */
|
Chris@929
|
117 bool isOverThreshold(int x, int y, float threshold) {
|
Chris@182
|
118 return getValueAt(x, y) > threshold;
|
Chris@182
|
119 }
|
Chris@182
|
120
|
Chris@1580
|
121 QString getTypeName() const override { return tr("Dense 3-D"); }
|
Chris@345
|
122
|
Chris@152
|
123 virtual int getCompletion() const = 0;
|
Chris@147
|
124
|
Chris@500
|
125 /*
|
Chris@500
|
126 TabularModel methods.
|
Chris@500
|
127 This class is non-editable -- subclasses may be editable.
|
Chris@500
|
128 Row and column are transposed for the tabular view (which is
|
Chris@500
|
129 "on its side").
|
Chris@500
|
130 */
|
Chris@500
|
131
|
Chris@1580
|
132 int getRowCount() const override { return getWidth(); }
|
Chris@1580
|
133 int getColumnCount() const override { return getHeight() + 2; }
|
Chris@500
|
134
|
Chris@1580
|
135 QString getHeading(int column) const override
|
Chris@500
|
136 {
|
Chris@500
|
137 switch (column) {
|
Chris@500
|
138 case 0: return tr("Time");
|
Chris@500
|
139 case 1: return tr("Frame");
|
Chris@1548
|
140 default:
|
Chris@1548
|
141 QString name = getBinName(column - 2);
|
Chris@1548
|
142 if (name == "") {
|
Chris@1548
|
143 name = tr("(bin %1)").arg(column - 2);
|
Chris@1548
|
144 }
|
Chris@1548
|
145 return name;
|
Chris@500
|
146 }
|
Chris@500
|
147 }
|
Chris@500
|
148
|
Chris@1580
|
149 QVariant getData(int row, int column, int) const
|
Chris@1580
|
150 override {
|
Chris@500
|
151 switch (column) {
|
Chris@500
|
152 case 0: {
|
Chris@1171
|
153 RealTime rt = RealTime::frame2RealTime
|
Chris@1171
|
154 (row * getResolution() + getStartFrame(), getSampleRate());
|
Chris@500
|
155 return rt.toText().c_str();
|
Chris@500
|
156 }
|
Chris@500
|
157 case 1:
|
Chris@1171
|
158 return int(row * getResolution() + getStartFrame());
|
Chris@500
|
159 default:
|
Chris@500
|
160 return getValueAt(row, column - 2);
|
Chris@500
|
161 }
|
Chris@500
|
162 }
|
Chris@500
|
163
|
Chris@1580
|
164 bool isColumnTimeValue(int col) const override {
|
Chris@500
|
165 return col < 2;
|
Chris@500
|
166 }
|
Chris@1580
|
167 SortType getSortType(int) const override {
|
Chris@500
|
168 return SortNumeric;
|
Chris@500
|
169 }
|
Chris@500
|
170
|
Chris@1580
|
171 sv_frame_t getFrameForRow(int row) const override {
|
Chris@1171
|
172 return sv_frame_t(row) * getResolution() + getStartFrame();
|
Chris@500
|
173 }
|
Chris@1580
|
174 int getRowForFrame(sv_frame_t frame) const override {
|
Chris@1171
|
175 return int((frame - getStartFrame()) / getResolution());
|
Chris@500
|
176 }
|
Chris@500
|
177
|
Chris@147
|
178 protected:
|
Chris@152
|
179 DenseThreeDimensionalModel() { }
|
Chris@147
|
180 };
|
Chris@147
|
181
|
Chris@147
|
182 #endif
|