comparison layer/SliceLayer.cpp @ 195:4a3bdde1ef13

* beginnings of spectrum scales
author Chris Cannam
date Mon, 29 Jan 2007 18:11:20 +0000
parents d13e209bfa94
children 6b023411087b
comparison
equal deleted inserted replaced
194:d13e209bfa94 195:4a3bdde1ef13
3 3
4 /* 4 /*
5 Sonic Visualiser 5 Sonic Visualiser
6 An audio file viewer and annotation editor. 6 An audio file viewer and annotation editor.
7 Centre for Digital Music, Queen Mary, University of London. 7 Centre for Digital Music, Queen Mary, University of London.
8 This file copyright 2006 QMUL. 8 This file copyright 2006-2007 QMUL.
9 9
10 This program is free software; you can redistribute it and/or 10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License as 11 modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2 of the 12 published by the Free Software Foundation; either version 2 of the
13 License, or (at your option) any later version. See the file 13 License, or (at your option) any later version. See the file
17 #include "SliceLayer.h" 17 #include "SliceLayer.h"
18 18
19 #include "view/View.h" 19 #include "view/View.h"
20 #include "base/AudioLevel.h" 20 #include "base/AudioLevel.h"
21 #include "base/RangeMapper.h" 21 #include "base/RangeMapper.h"
22 #include "base/RealTime.h"
23
24 #include "PaintAssistant.h"
22 25
23 #include <QPainter> 26 #include <QPainter>
24 #include <QPainterPath> 27 #include <QPainterPath>
25 28
26 SliceLayer::SliceLayer() : 29 SliceLayer::SliceLayer() :
27 m_sliceableModel(0), 30 m_sliceableModel(0),
28 m_colour(Qt::darkBlue), 31 m_colour(Qt::darkBlue),
29 m_energyScale(dBScale), 32 m_energyScale(dBScale),
30 m_samplingMode(SamplePeak), 33 m_samplingMode(SamplePeak),
31 m_plotStyle(PlotLines), 34 m_plotStyle(PlotSteps),
32 m_binScale(LinearBins), 35 m_binScale(LinearBins),
33 m_normalize(false), 36 m_normalize(false),
34 m_bias(false), 37 m_bias(false),
35 m_gain(1.0) 38 m_gain(1.0)
36 { 39 {
92 void 95 void
93 SliceLayer::paint(View *v, QPainter &paint, QRect rect) const 96 SliceLayer::paint(View *v, QPainter &paint, QRect rect) const
94 { 97 {
95 if (!m_sliceableModel) return; 98 if (!m_sliceableModel) return;
96 99
97 int w = (v->width() * 2) / 3; 100 paint.save();
98 int xorigin = (v->width() / 2) - (w / 2); 101 paint.setRenderHint(QPainter::Antialiasing, false);
102
103 if (v->getViewManager() && v->getViewManager()->shouldShowScaleGuides()) {
104 if (!m_scalePoints.empty()) {
105 paint.setPen(QColor(240, 240, 240)); //!!! and dark background?
106 for (size_t i = 0; i < m_scalePoints.size(); ++i) {
107 paint.drawLine(0, m_scalePoints[i], rect.width(), m_scalePoints[i]);
108 }
109 }
110 }
111
112 paint.setPen(m_colour);
113
114 // int w = (v->width() * 2) / 3;
115 int xorigin = getVerticalScaleWidth(v, paint) + 1; //!!! (v->width() / 2) - (w / 2);
116 int w = v->width() - xorigin - 1;
99 117
100 int h = (v->height() * 2) / 3; 118 int yorigin = v->height() - 20 - paint.fontMetrics().height() - 7;
101 int yorigin = (v->height() / 2) + (h / 2); 119 int h = yorigin - paint.fontMetrics().height() - 8;
102 120 if (h < 0) return;
103 paint.save(); 121
104 paint.setPen(m_colour); 122 // int h = (v->height() * 3) / 4;
105 paint.setRenderHint(QPainter::Antialiasing, false); 123 // int yorigin = (v->height() / 2) + (h / 2);
106 124
107 QPainterPath path; 125 QPainterPath path;
108 float thresh = -80.f; 126 float thresh = -80.f;
109 127
110 int mh = m_sliceableModel->getHeight(); 128 int mh = m_sliceableModel->getHeight();
116 values[bin] = 0.f; 134 values[bin] = 0.f;
117 } 135 }
118 136
119 size_t f0 = v->getCentreFrame(); 137 size_t f0 = v->getCentreFrame();
120 int f0x = v->getXForFrame(f0); 138 int f0x = v->getXForFrame(f0);
139 f0 = v->getFrameForX(f0x);
121 size_t f1 = v->getFrameForX(f0x + 1); 140 size_t f1 = v->getFrameForX(f0x + 1);
141 if (f1 > f0) --f1;
122 142
123 size_t col0 = f0 / m_sliceableModel->getResolution(); 143 size_t col0 = f0 / m_sliceableModel->getResolution();
124 size_t col1 = col0; 144 size_t col1 = col0;
125 if (m_samplingMode != NearestSample) { 145 if (m_samplingMode != NearestSample) {
126 col1 = f1 / m_sliceableModel->getResolution(); 146 col1 = f1 / m_sliceableModel->getResolution();
127 } 147 }
128 if (col1 <= col0) col1 = col0 + 1; 148 f0 = col0 * m_sliceableModel->getResolution();
129 149 f1 = (col1 + 1) * m_sliceableModel->getResolution() - 1;
130 for (size_t col = col0; col < col1; ++col) { 150
151 for (size_t col = col0; col <= col1; ++col) {
131 for (size_t bin = 0; bin < mh; ++bin) { 152 for (size_t bin = 0; bin < mh; ++bin) {
132 float value = m_sliceableModel->getValueAt(col, bin); 153 float value = m_sliceableModel->getValueAt(col, bin);
133 if (m_bias) value *= bin + 1; 154 if (m_bias) value *= bin + 1;
134 if (m_samplingMode == SamplePeak) { 155 if (m_samplingMode == SamplePeak) {
135 if (value > values[bin]) values[bin] = value; 156 if (value > values[bin]) values[bin] = value;
234 } 255 }
235 256
236 paint.drawPath(path); 257 paint.drawPath(path);
237 paint.restore(); 258 paint.restore();
238 259
260 if (v->getViewManager() && v->getViewManager()->shouldShowFrameCount()) {
261
262 int sampleRate = m_sliceableModel->getSampleRate();
263
264 QString startText = QString("%1 / %2")
265 .arg(QString::fromStdString
266 (RealTime::frame2RealTime
267 (f0, sampleRate).toText(true)))
268 .arg(f0);
269
270 QString endText = QString(" %1 / %2")
271 .arg(QString::fromStdString
272 (RealTime::frame2RealTime
273 (f1, sampleRate).toText(true)))
274 .arg(f1);
275
276 QString durationText = QString("(%1 / %2) ")
277 .arg(QString::fromStdString
278 (RealTime::frame2RealTime
279 (f1 - f0 + 1, sampleRate).toText(true)))
280 .arg(f1 - f0 + 1);
281
282 v->drawVisibleText
283 (paint, xorigin + 5,
284 paint.fontMetrics().ascent() + 5,
285 startText, View::OutlinedText);
286
287 v->drawVisibleText
288 (paint, xorigin + 5,
289 paint.fontMetrics().ascent() + paint.fontMetrics().height() + 10,
290 endText, View::OutlinedText);
291
292 v->drawVisibleText
293 (paint, xorigin + 5,
294 paint.fontMetrics().ascent() + 2*paint.fontMetrics().height() + 15,
295 durationText, View::OutlinedText);
296 }
297
298 /*
299
300 QString frameRange;
301 if (f1 != f0) {
302 frameRange = QString("%1 - %2").arg(f0).arg(f1);
303 } else {
304 frameRange = QString("%1").arg(f0);
305 }
306
307 QString colRange;
308 if (col1 != col0) {
309 colRange = tr("%1 hops").arg(col1 - col0 + 1);
310 } else {
311 colRange = tr("1 hop");
312 }
313
314 if (v->getViewManager() && v->getViewManager()->shouldShowFrameCount()) {
315
316 v->drawVisibleText
317 (paint, xorigin + 5,
318 paint.fontMetrics().ascent() + 5,
319 frameRange, View::OutlinedText);
320
321 v->drawVisibleText
322 (paint, xorigin + 5,
323 paint.fontMetrics().ascent() + paint.fontMetrics().height() + 10,
324 colRange, View::OutlinedText);
325 }
326 */
327 }
328
329 int
330 SliceLayer::getVerticalScaleWidth(View *v, QPainter &paint) const
331 {
332 if (m_energyScale == LinearScale) {
333 return paint.fontMetrics().width("0.0") + 13;
334 } else {
335 return std::max(paint.fontMetrics().width(tr("0dB")),
336 paint.fontMetrics().width(tr("-Inf"))) + 13;
337 }
338 }
339
340 void
341 SliceLayer::paintVerticalScale(View *v, QPainter &paint, QRect rect) const
342 {
343 float thresh = 0;
344 if (m_energyScale != LinearScale) {
345 thresh = AudioLevel::dB_to_multiplier(-80); //!!! thresh
346 }
347
348 // int h = (rect.height() * 3) / 4;
349 // int y = (rect.height() / 2) - (h / 2);
350
351 int yorigin = v->height() - 20 - paint.fontMetrics().height() - 6;
352 int h = yorigin - paint.fontMetrics().height() - 8;
353 if (h < 0) return;
354
355 QRect actual(rect.x(), rect.y() + yorigin - h, rect.width(), h);
356
357 PaintAssistant::paintVerticalLevelScale
358 (paint, actual, thresh, 1.0 / m_gain,
359 PaintAssistant::Scale(m_energyScale),
360 const_cast<std::vector<int> *>(&m_scalePoints));
239 } 361 }
240 362
241 Layer::PropertyList 363 Layer::PropertyList
242 SliceLayer::getProperties() const 364 SliceLayer::getProperties() const
243 { 365 {