1 #include "widget/woverviewhsv.h"
2
3 #include <QPainter>
4 #include <QColor>
5
6 #include "util/timer.h"
7 #include "util/math.h"
8 #include "waveform/waveform.h"
9
WOverviewHSV(const QString & group,PlayerManager * pPlayerManager,UserSettingsPointer pConfig,QWidget * parent)10 WOverviewHSV::WOverviewHSV(
11 const QString& group,
12 PlayerManager* pPlayerManager,
13 UserSettingsPointer pConfig,
14 QWidget* parent)
15 : WOverview(group, pPlayerManager, pConfig, parent) {
16 }
17
drawNextPixmapPart()18 bool WOverviewHSV::drawNextPixmapPart() {
19 ScopedTimer t("WOverviewHSV::drawNextPixmapPart");
20
21 //qDebug() << "WOverview::drawNextPixmapPart()";
22
23 int currentCompletion;
24
25 ConstWaveformPointer pWaveform = getWaveform();
26 if (!pWaveform) {
27 return false;
28 }
29
30 const int dataSize = pWaveform->getDataSize();
31 if (dataSize == 0) {
32 return false;
33 }
34
35 if (m_waveformSourceImage.isNull()) {
36 // Waveform pixmap twice the height of the viewport to be scalable
37 // by total_gain
38 // We keep full range waveform data to scale it on paint
39 m_waveformSourceImage = QImage(dataSize / 2, 2 * 255,
40 QImage::Format_ARGB32_Premultiplied);
41 m_waveformSourceImage.fill(QColor(0, 0, 0, 0).value());
42 }
43
44 // Always multiple of 2
45 const int waveformCompletion = pWaveform->getCompletion();
46 // Test if there is some new to draw (at least of pixel width)
47 const int completionIncrement = waveformCompletion - m_actualCompletion;
48
49 int visiblePixelIncrement = completionIncrement * length() / dataSize;
50 if (waveformCompletion < (dataSize - 2) &&
51 (completionIncrement < 2 || visiblePixelIncrement == 0)) {
52 return false;
53 }
54
55 const int nextCompletion = m_actualCompletion + completionIncrement;
56
57 //qDebug() << "WOverview::drawNextPixmapPart() - nextCompletion:"
58 // << nextCompletion
59 // << "m_actualCompletion:" << m_actualCompletion
60 // << "waveformCompletion:" << waveformCompletion
61 // << "completionIncrement:" << completionIncrement;
62
63
64 QPainter painter(&m_waveformSourceImage);
65 painter.translate(0.0, static_cast<double>(m_waveformSourceImage.height()) / 2.0);
66
67 // Get HSV of low color. NOTE(rryan): On ARM, qreal is float so it's
68 // important we use qreal here and not double or float or else we will get
69 // build failures on ARM.
70 qreal h, s, v;
71 m_signalColors.getLowColor().getHsvF(&h, &s, &v);
72
73 QColor color;
74 float lo, hi, total;
75
76 unsigned char maxLow[2] = {0, 0};
77 unsigned char maxHigh[2] = {0, 0};
78 unsigned char maxMid[2] = {0, 0};
79 unsigned char maxAll[2] = {0, 0};
80
81 for (currentCompletion = m_actualCompletion;
82 currentCompletion < nextCompletion; currentCompletion += 2) {
83 maxAll[0] = pWaveform->getAll(currentCompletion);
84 maxAll[1] = pWaveform->getAll(currentCompletion+1);
85 if (maxAll[0] || maxAll[1]) {
86 maxLow[0] = pWaveform->getLow(currentCompletion);
87 maxLow[1] = pWaveform->getLow(currentCompletion+1);
88 maxMid[0] = pWaveform->getMid(currentCompletion);
89 maxMid[1] = pWaveform->getMid(currentCompletion+1);
90 maxHigh[0] = pWaveform->getHigh(currentCompletion);
91 maxHigh[1] = pWaveform->getHigh(currentCompletion+1);
92
93 total = (maxLow[0] + maxLow[1] + maxMid[0] + maxMid[1] +
94 maxHigh[0] + maxHigh[1]) *
95 1.2f;
96
97 // Prevent division by zero
98 if (total > 0) {
99 // Normalize low and high
100 // (mid not need, because it not change the color)
101 lo = (maxLow[0] + maxLow[1]) / total;
102 hi = (maxHigh[0] + maxHigh[1]) / total;
103 } else {
104 lo = hi = 0.0;
105 }
106
107 // Set color
108 color.setHsvF(h, 1.0-hi, 1.0-lo);
109
110 painter.setPen(color);
111 painter.drawLine(QPoint(currentCompletion / 2, -maxAll[0]),
112 QPoint(currentCompletion / 2, maxAll[1]));
113 }
114 }
115
116 // Evaluate waveform ratio peak
117
118 for (currentCompletion = m_actualCompletion;
119 currentCompletion < nextCompletion; currentCompletion += 2) {
120 m_waveformPeak = math_max3(
121 m_waveformPeak,
122 static_cast<float>(pWaveform->getAll(currentCompletion)),
123 static_cast<float>(pWaveform->getAll(currentCompletion + 1)));
124 }
125
126 m_actualCompletion = nextCompletion;
127 m_waveformImageScaled = QImage();
128 m_diffGain = 0;
129
130 // Test if the complete waveform is done
131 if (m_actualCompletion >= dataSize - 2) {
132 m_pixmapDone = true;
133 //qDebug() << "m_waveformPeakRatio" << m_waveformPeak;
134 }
135
136 return true;
137 }
138