Mercurial > hg > svgui
comparison layer/SpectrogramLayer.cpp @ 1143:c53ed1a6fcbd spectrogram-minor-refactor
Fixes to phase display and colour scale for it; tidy up some debug output
author | Chris Cannam |
---|---|
date | Fri, 05 Aug 2016 14:31:16 +0100 |
parents | 8f4634b82e36 |
children | 6eef0330ef12 |
comparison
equal
deleted
inserted
replaced
1142:8f4634b82e36 | 1143:c53ed1a6fcbd |
---|---|
49 | 49 |
50 #ifndef __GNUC__ | 50 #ifndef __GNUC__ |
51 #include <alloca.h> | 51 #include <alloca.h> |
52 #endif | 52 #endif |
53 | 53 |
54 #define DEBUG_SPECTROGRAM 1 | 54 //#define DEBUG_SPECTROGRAM 1 |
55 #define DEBUG_SPECTROGRAM_REPAINT 1 | 55 //#define DEBUG_SPECTROGRAM_REPAINT 1 |
56 | 56 |
57 using namespace std; | 57 using namespace std; |
58 | 58 |
59 SpectrogramLayer::SpectrogramLayer(Configuration config) : | 59 SpectrogramLayer::SpectrogramLayer(Configuration config) : |
60 m_model(0), | 60 m_model(0), |
1505 | 1505 |
1506 } else { | 1506 } else { |
1507 | 1507 |
1508 result = renderer->renderTimeConstrained(v, paint, rect); | 1508 result = renderer->renderTimeConstrained(v, paint, rect); |
1509 | 1509 |
1510 #ifdef DEBUG_SPECTROGRAM_REPAINT | |
1510 cerr << "rect width from this paint: " << result.rendered.width() | 1511 cerr << "rect width from this paint: " << result.rendered.width() |
1511 << ", mag range in this paint: " << result.range.getMin() << " -> " | 1512 << ", mag range in this paint: " << result.range.getMin() << " -> " |
1512 << result.range.getMax() << endl; | 1513 << result.range.getMax() << endl; |
1514 #endif | |
1513 | 1515 |
1514 QRect uncached = renderer->getLargestUncachedRect(v); | 1516 QRect uncached = renderer->getLargestUncachedRect(v); |
1515 if (uncached.width() > 0) { | 1517 if (uncached.width() > 0) { |
1516 v->updatePaintRect(uncached); | 1518 v->updatePaintRect(uncached); |
1517 } | 1519 } |
1520 magRange.sample(result.range); | 1522 magRange.sample(result.range); |
1521 | 1523 |
1522 if (magRange.isSet()) { | 1524 if (magRange.isSet()) { |
1523 if (m_viewMags[viewId] != magRange) { | 1525 if (m_viewMags[viewId] != magRange) { |
1524 m_viewMags[viewId] = magRange; | 1526 m_viewMags[viewId] = magRange; |
1527 #ifdef DEBUG_SPECTROGRAM_REPAINT | |
1525 cerr << "mag range in this view has changed: " | 1528 cerr << "mag range in this view has changed: " |
1526 << magRange.getMin() << " -> " << magRange.getMax() << endl; | 1529 << magRange.getMin() << " -> " << magRange.getMax() << endl; |
1530 #endif | |
1527 } | 1531 } |
1528 } | 1532 } |
1529 | 1533 |
1530 if (!continuingPaint && m_normalizeVisibleArea && | 1534 if (!continuingPaint && m_normalizeVisibleArea && |
1531 m_viewMags[viewId] != m_lastRenderedMags[viewId]) { | 1535 m_viewMags[viewId] != m_lastRenderedMags[viewId]) { |
1536 #ifdef DEBUG_SPECTROGRAM_REPAINT | |
1532 cerr << "mag range has changed from last rendered range: re-rendering" | 1537 cerr << "mag range has changed from last rendered range: re-rendering" |
1533 << endl; | 1538 << endl; |
1539 #endif | |
1534 delete m_renderers[viewId]; | 1540 delete m_renderers[viewId]; |
1535 m_renderers.erase(viewId); | 1541 m_renderers.erase(viewId); |
1536 v->updatePaintRect(v->getPaintRect()); | 1542 v->updatePaintRect(v->getPaintRect()); |
1537 } | 1543 } |
1538 } | 1544 } |
1569 QPoint localPos; | 1575 QPoint localPos; |
1570 if (!v->shouldIlluminateLocalFeatures(this, localPos) || !m_model) { | 1576 if (!v->shouldIlluminateLocalFeatures(this, localPos) || !m_model) { |
1571 return; | 1577 return; |
1572 } | 1578 } |
1573 | 1579 |
1580 #ifdef DEBUG_SPECTROGRAM_REPAINT | |
1574 cerr << "SpectrogramLayer: illuminateLocalFeatures(" | 1581 cerr << "SpectrogramLayer: illuminateLocalFeatures(" |
1575 << localPos.x() << "," << localPos.y() << ")" << endl; | 1582 << localPos.x() << "," << localPos.y() << ")" << endl; |
1583 #endif | |
1576 | 1584 |
1577 double s0, s1; | 1585 double s0, s1; |
1578 double f0, f1; | 1586 double f0, f1; |
1579 | 1587 |
1580 if (getXBinRange(v, localPos.x(), s0, s1) && | 1588 if (getXBinRange(v, localPos.x(), s0, s1) && |
1587 int x1 = v->getXForFrame((s1i + 1) * getWindowIncrement()); | 1595 int x1 = v->getXForFrame((s1i + 1) * getWindowIncrement()); |
1588 | 1596 |
1589 int y1 = int(getYForFrequency(v, f1)); | 1597 int y1 = int(getYForFrequency(v, f1)); |
1590 int y0 = int(getYForFrequency(v, f0)); | 1598 int y0 = int(getYForFrequency(v, f0)); |
1591 | 1599 |
1600 #ifdef DEBUG_SPECTROGRAM_REPAINT | |
1592 cerr << "SpectrogramLayer: illuminate " | 1601 cerr << "SpectrogramLayer: illuminate " |
1593 << x0 << "," << y1 << " -> " << x1 << "," << y0 << endl; | 1602 << x0 << "," << y1 << " -> " << x1 << "," << y0 << endl; |
1603 #endif | |
1594 | 1604 |
1595 paint.setPen(v->getForeground()); | 1605 paint.setPen(v->getForeground()); |
1596 | 1606 |
1597 //!!! should we be using paintCrosshairs for this? | 1607 //!!! should we be using paintCrosshairs for this? |
1598 | 1608 |
2091 void | 2101 void |
2092 SpectrogramLayer::paintDetailedScale(LayerGeometryProvider *v, | 2102 SpectrogramLayer::paintDetailedScale(LayerGeometryProvider *v, |
2093 QPainter &paint, QRect rect) const | 2103 QPainter &paint, QRect rect) const |
2094 { | 2104 { |
2095 // The colour scale | 2105 // The colour scale |
2106 | |
2107 if (m_colourScale == ColourScaleType::Phase) { | |
2108 paintDetailedScalePhase(v, paint, rect); | |
2109 return; | |
2110 } | |
2096 | 2111 |
2097 int h = rect.height(); | 2112 int h = rect.height(); |
2098 int textHeight = paint.fontMetrics().height(); | 2113 int textHeight = paint.fontMetrics().height(); |
2099 int toff = -textHeight + paint.fontMetrics().ascent() + 2; | 2114 int toff = -textHeight + paint.fontMetrics().ascent() + 2; |
2100 | 2115 |
2101 int cw = getColourScaleWidth(paint); | 2116 int cw = getColourScaleWidth(paint); |
2102 int cbw = paint.fontMetrics().width("dB"); | 2117 int cbw = paint.fontMetrics().width("dB"); |
2103 | 2118 |
2104 int topLines = 2; | 2119 int topLines = 2; |
2105 if (m_colourScale == ColourScaleType::Phase) topLines = 1; | |
2106 | 2120 |
2107 int ch = h - textHeight * (topLines + 1) - 8; | 2121 int ch = h - textHeight * (topLines + 1) - 8; |
2108 // paint.drawRect(4, textHeight + 4, cw - 1, ch + 1); | 2122 // paint.drawRect(4, textHeight + 4, cw - 1, ch + 1); |
2109 paint.drawRect(4 + cw - cbw, textHeight * topLines + 4, cbw - 1, ch + 1); | 2123 paint.drawRect(4 + cw - cbw, textHeight * topLines + 4, cbw - 1, ch + 1); |
2110 | 2124 |
2133 #ifdef DEBUG_SPECTROGRAM_REPAINT | 2147 #ifdef DEBUG_SPECTROGRAM_REPAINT |
2134 cerr << "adjusted dB range to min = " << dBmin << ", max = " << dBmax | 2148 cerr << "adjusted dB range to min = " << dBmin << ", max = " << dBmax |
2135 << endl; | 2149 << endl; |
2136 #endif | 2150 #endif |
2137 | 2151 |
2138 //!!! & phase etc | 2152 paint.drawText((cw + 6 - paint.fontMetrics().width("dBFS")) / 2, |
2139 | 2153 2 + textHeight + toff, "dBFS"); |
2140 if (m_colourScale != ColourScaleType::Phase) { | |
2141 paint.drawText((cw + 6 - paint.fontMetrics().width("dBFS")) / 2, | |
2142 2 + textHeight + toff, "dBFS"); | |
2143 } | |
2144 | 2154 |
2145 // paint.drawText((cw + 6 - paint.fontMetrics().width(top)) / 2, | 2155 // paint.drawText((cw + 6 - paint.fontMetrics().width(top)) / 2, |
2146 paint.drawText(3 + cw - cbw - paint.fontMetrics().width(top), | 2156 paint.drawText(3 + cw - cbw - paint.fontMetrics().width(top), |
2147 2 + textHeight * topLines + toff + textHeight/2, top); | 2157 2 + textHeight * topLines + toff + textHeight/2, top); |
2148 | 2158 |
2183 paint.setPen(v->getForeground()); | 2193 paint.setPen(v->getForeground()); |
2184 paint.drawLine(5 + cw - cbw, y, 8 + cw - cbw, y); | 2194 paint.drawLine(5 + cw - cbw, y, 8 + cw - cbw, y); |
2185 lasty = y; | 2195 lasty = y; |
2186 lastdb = idb; | 2196 lastdb = idb; |
2187 } | 2197 } |
2198 } | |
2199 paint.restore(); | |
2200 } | |
2201 | |
2202 void | |
2203 SpectrogramLayer::paintDetailedScalePhase(LayerGeometryProvider *v, | |
2204 QPainter &paint, QRect rect) const | |
2205 { | |
2206 // The colour scale in phase mode | |
2207 | |
2208 int h = rect.height(); | |
2209 int textHeight = paint.fontMetrics().height(); | |
2210 int toff = -textHeight + paint.fontMetrics().ascent() + 2; | |
2211 | |
2212 int cw = getColourScaleWidth(paint); | |
2213 | |
2214 // Phase is not measured in dB of course, but this places the | |
2215 // scale at the same position as in the magnitude spectrogram | |
2216 int cbw = paint.fontMetrics().width("dB"); | |
2217 | |
2218 int topLines = 1; | |
2219 | |
2220 int ch = h - textHeight * (topLines + 1) - 8; | |
2221 paint.drawRect(4 + cw - cbw, textHeight * topLines + 4, cbw - 1, ch + 1); | |
2222 | |
2223 QString top, bottom, middle; | |
2224 top = QString("%1").arg(QChar(0x3c0)); // pi | |
2225 bottom = "-" + top; | |
2226 middle = "0"; | |
2227 | |
2228 double min = -M_PI; | |
2229 double max = M_PI; | |
2230 | |
2231 paint.drawText(3 + cw - cbw - paint.fontMetrics().width(top), | |
2232 2 + textHeight * topLines + toff + textHeight/2, top); | |
2233 | |
2234 paint.drawText(3 + cw - cbw - paint.fontMetrics().width(middle), | |
2235 2 + textHeight * topLines + ch/2 + toff + textHeight/2, middle); | |
2236 | |
2237 paint.drawText(3 + cw - cbw - paint.fontMetrics().width(bottom), | |
2238 h + toff - 3 - textHeight/2, bottom); | |
2239 | |
2240 paint.save(); | |
2241 paint.setBrush(Qt::NoBrush); | |
2242 | |
2243 for (int i = 0; i < ch; ++i) { | |
2244 double val = min + (((max - min) * i) / (ch - 1)); | |
2245 paint.setPen(getRenderer(v)->getColour(val)); | |
2246 int y = textHeight * topLines + 4 + ch - i; | |
2247 paint.drawLine(5 + cw - cbw, y, cw + 2, y); | |
2188 } | 2248 } |
2189 paint.restore(); | 2249 paint.restore(); |
2190 } | 2250 } |
2191 | 2251 |
2192 class SpectrogramRangeMapper : public RangeMapper | 2252 class SpectrogramRangeMapper : public RangeMapper |