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