Mercurial > hg > svgui
comparison layer/SpectrogramLayer.cpp @ 1142:8f4634b82e36 spectrogram-minor-refactor
Pull out paintDetailedScale
author | Chris Cannam |
---|---|
date | Fri, 05 Aug 2016 14:00:58 +0100 |
parents | f19dcb288123 |
children | c53ed1a6fcbd |
comparison
equal
deleted
inserted
replaced
1141:f19dcb288123 | 1142:8f4634b82e36 |
---|---|
1999 | 1999 |
2000 return cw + tickw + tw + 13; | 2000 return cw + tickw + tw + 13; |
2001 } | 2001 } |
2002 | 2002 |
2003 void | 2003 void |
2004 SpectrogramLayer::paintVerticalScale(LayerGeometryProvider *v, bool detailed, QPainter &paint, QRect rect) const | 2004 SpectrogramLayer::paintVerticalScale(LayerGeometryProvider *v, bool detailed, |
2005 QPainter &paint, QRect rect) const | |
2005 { | 2006 { |
2006 if (!m_model || !m_model->isOK()) { | 2007 if (!m_model || !m_model->isOK()) { |
2007 return; | 2008 return; |
2008 } | 2009 } |
2009 | 2010 |
2010 Profiler profiler("SpectrogramLayer::paintVerticalScale"); | 2011 Profiler profiler("SpectrogramLayer::paintVerticalScale"); |
2011 | 2012 |
2012 //!!! cache this? | 2013 //!!! cache this? |
2013 | 2014 |
2014 int h = rect.height(), w = rect.width(); | 2015 int h = rect.height(), w = rect.width(); |
2016 int textHeight = paint.fontMetrics().height(); | |
2017 | |
2018 if (detailed && (h > textHeight * 3 + 10)) { | |
2019 paintDetailedScale(v, paint, rect); | |
2020 } | |
2021 m_haveDetailedScale = detailed; | |
2015 | 2022 |
2016 int tickw = (m_binScale == BinScale::Log ? 10 : 4); | 2023 int tickw = (m_binScale == BinScale::Log ? 10 : 4); |
2017 int pkw = (m_binScale == BinScale::Log ? 10 : 0); | 2024 int pkw = (m_binScale == BinScale::Log ? 10 : 0); |
2018 | 2025 |
2019 int bins = getFFTSize() / 2; | 2026 int bins = getFFTSize() / 2; |
2023 bins = int((double(m_maxFrequency) * getFFTSize()) / sr + 0.1); | 2030 bins = int((double(m_maxFrequency) * getFFTSize()) / sr + 0.1); |
2024 if (bins > getFFTSize() / 2) bins = getFFTSize() / 2; | 2031 if (bins > getFFTSize() / 2) bins = getFFTSize() / 2; |
2025 } | 2032 } |
2026 | 2033 |
2027 int cw = 0; | 2034 int cw = 0; |
2028 | |
2029 if (detailed) cw = getColourScaleWidth(paint); | 2035 if (detailed) cw = getColourScaleWidth(paint); |
2030 int cbw = paint.fontMetrics().width("dB"); | |
2031 | 2036 |
2032 int py = -1; | 2037 int py = -1; |
2033 int textHeight = paint.fontMetrics().height(); | |
2034 int toff = -textHeight + paint.fontMetrics().ascent() + 2; | 2038 int toff = -textHeight + paint.fontMetrics().ascent() + 2; |
2035 | |
2036 if (detailed && (h > textHeight * 3 + 10)) { | |
2037 | |
2038 int topLines = 2; | |
2039 if (m_colourScale == ColourScaleType::Phase) topLines = 1; | |
2040 | |
2041 int ch = h - textHeight * (topLines + 1) - 8; | |
2042 // paint.drawRect(4, textHeight + 4, cw - 1, ch + 1); | |
2043 paint.drawRect(4 + cw - cbw, textHeight * topLines + 4, cbw - 1, ch + 1); | |
2044 | |
2045 QString top, bottom; | |
2046 double min = m_viewMags[v->getId()].getMin(); | |
2047 double max = m_viewMags[v->getId()].getMax(); | |
2048 | |
2049 if (min < m_threshold) min = m_threshold; | |
2050 if (max <= min) max = min + 0.1; | |
2051 | |
2052 double dBmin = AudioLevel::multiplier_to_dB(min); | |
2053 double dBmax = AudioLevel::multiplier_to_dB(max); | |
2054 | |
2055 #ifdef DEBUG_SPECTROGRAM_REPAINT | |
2056 cerr << "paintVerticalScale: for view id " << v->getId() | |
2057 << ": min = " << min << ", max = " << max | |
2058 << ", dBmin = " << dBmin << ", dBmax = " << dBmax << endl; | |
2059 #endif | |
2060 | |
2061 if (dBmax < -60.f) dBmax = -60.f; | |
2062 else top = QString("%1").arg(lrint(dBmax)); | |
2063 | |
2064 if (dBmin < dBmax - 60.f) dBmin = dBmax - 60.f; | |
2065 bottom = QString("%1").arg(lrint(dBmin)); | |
2066 | |
2067 #ifdef DEBUG_SPECTROGRAM_REPAINT | |
2068 cerr << "adjusted dB range to min = " << dBmin << ", max = " << dBmax | |
2069 << endl; | |
2070 #endif | |
2071 | |
2072 //!!! & phase etc | |
2073 | |
2074 if (m_colourScale != ColourScaleType::Phase) { | |
2075 paint.drawText((cw + 6 - paint.fontMetrics().width("dBFS")) / 2, | |
2076 2 + textHeight + toff, "dBFS"); | |
2077 } | |
2078 | |
2079 // paint.drawText((cw + 6 - paint.fontMetrics().width(top)) / 2, | |
2080 paint.drawText(3 + cw - cbw - paint.fontMetrics().width(top), | |
2081 2 + textHeight * topLines + toff + textHeight/2, top); | |
2082 | |
2083 paint.drawText(3 + cw - cbw - paint.fontMetrics().width(bottom), | |
2084 h + toff - 3 - textHeight/2, bottom); | |
2085 | |
2086 paint.save(); | |
2087 paint.setBrush(Qt::NoBrush); | |
2088 | |
2089 int lasty = 0; | |
2090 int lastdb = 0; | |
2091 | |
2092 for (int i = 0; i < ch; ++i) { | |
2093 | |
2094 double dBval = dBmin + (((dBmax - dBmin) * i) / (ch - 1)); | |
2095 int idb = int(dBval); | |
2096 | |
2097 double value = AudioLevel::dB_to_multiplier(dBval); | |
2098 paint.setPen(getRenderer(v)->getColour(value)); | |
2099 | |
2100 int y = textHeight * topLines + 4 + ch - i; | |
2101 | |
2102 paint.drawLine(5 + cw - cbw, y, cw + 2, y); | |
2103 | |
2104 if (i == 0) { | |
2105 lasty = y; | |
2106 lastdb = idb; | |
2107 } else if (i < ch - paint.fontMetrics().ascent() && | |
2108 idb != lastdb && | |
2109 ((abs(y - lasty) > textHeight && | |
2110 idb % 10 == 0) || | |
2111 (abs(y - lasty) > paint.fontMetrics().ascent() && | |
2112 idb % 5 == 0))) { | |
2113 paint.setPen(v->getBackground()); | |
2114 QString text = QString("%1").arg(idb); | |
2115 paint.drawText(3 + cw - cbw - paint.fontMetrics().width(text), | |
2116 y + toff + textHeight/2, text); | |
2117 paint.setPen(v->getForeground()); | |
2118 paint.drawLine(5 + cw - cbw, y, 8 + cw - cbw, y); | |
2119 lasty = y; | |
2120 lastdb = idb; | |
2121 } | |
2122 } | |
2123 paint.restore(); | |
2124 } | |
2125 | 2039 |
2126 paint.drawLine(cw + 7, 0, cw + 7, h); | 2040 paint.drawLine(cw + 7, 0, cw + 7, h); |
2127 | 2041 |
2128 int bin = -1; | 2042 int bin = -1; |
2129 | 2043 |
2170 (v, paint, QRect(w - pkw - 1, 0, pkw, h), | 2084 (v, paint, QRect(w - pkw - 1, 0, pkw, h), |
2171 getEffectiveMinFrequency(), getEffectiveMaxFrequency()); | 2085 getEffectiveMinFrequency(), getEffectiveMaxFrequency()); |
2172 } | 2086 } |
2173 | 2087 |
2174 m_haveDetailedScale = detailed; | 2088 m_haveDetailedScale = detailed; |
2089 } | |
2090 | |
2091 void | |
2092 SpectrogramLayer::paintDetailedScale(LayerGeometryProvider *v, | |
2093 QPainter &paint, QRect rect) const | |
2094 { | |
2095 // The colour scale | |
2096 | |
2097 int h = rect.height(); | |
2098 int textHeight = paint.fontMetrics().height(); | |
2099 int toff = -textHeight + paint.fontMetrics().ascent() + 2; | |
2100 | |
2101 int cw = getColourScaleWidth(paint); | |
2102 int cbw = paint.fontMetrics().width("dB"); | |
2103 | |
2104 int topLines = 2; | |
2105 if (m_colourScale == ColourScaleType::Phase) topLines = 1; | |
2106 | |
2107 int ch = h - textHeight * (topLines + 1) - 8; | |
2108 // paint.drawRect(4, textHeight + 4, cw - 1, ch + 1); | |
2109 paint.drawRect(4 + cw - cbw, textHeight * topLines + 4, cbw - 1, ch + 1); | |
2110 | |
2111 QString top, bottom; | |
2112 double min = m_viewMags[v->getId()].getMin(); | |
2113 double max = m_viewMags[v->getId()].getMax(); | |
2114 | |
2115 if (min < m_threshold) min = m_threshold; | |
2116 if (max <= min) max = min + 0.1; | |
2117 | |
2118 double dBmin = AudioLevel::multiplier_to_dB(min); | |
2119 double dBmax = AudioLevel::multiplier_to_dB(max); | |
2120 | |
2121 #ifdef DEBUG_SPECTROGRAM_REPAINT | |
2122 cerr << "paintVerticalScale: for view id " << v->getId() | |
2123 << ": min = " << min << ", max = " << max | |
2124 << ", dBmin = " << dBmin << ", dBmax = " << dBmax << endl; | |
2125 #endif | |
2126 | |
2127 if (dBmax < -60.f) dBmax = -60.f; | |
2128 else top = QString("%1").arg(lrint(dBmax)); | |
2129 | |
2130 if (dBmin < dBmax - 60.f) dBmin = dBmax - 60.f; | |
2131 bottom = QString("%1").arg(lrint(dBmin)); | |
2132 | |
2133 #ifdef DEBUG_SPECTROGRAM_REPAINT | |
2134 cerr << "adjusted dB range to min = " << dBmin << ", max = " << dBmax | |
2135 << endl; | |
2136 #endif | |
2137 | |
2138 //!!! & phase etc | |
2139 | |
2140 if (m_colourScale != ColourScaleType::Phase) { | |
2141 paint.drawText((cw + 6 - paint.fontMetrics().width("dBFS")) / 2, | |
2142 2 + textHeight + toff, "dBFS"); | |
2143 } | |
2144 | |
2145 // paint.drawText((cw + 6 - paint.fontMetrics().width(top)) / 2, | |
2146 paint.drawText(3 + cw - cbw - paint.fontMetrics().width(top), | |
2147 2 + textHeight * topLines + toff + textHeight/2, top); | |
2148 | |
2149 paint.drawText(3 + cw - cbw - paint.fontMetrics().width(bottom), | |
2150 h + toff - 3 - textHeight/2, bottom); | |
2151 | |
2152 paint.save(); | |
2153 paint.setBrush(Qt::NoBrush); | |
2154 | |
2155 int lasty = 0; | |
2156 int lastdb = 0; | |
2157 | |
2158 for (int i = 0; i < ch; ++i) { | |
2159 | |
2160 double dBval = dBmin + (((dBmax - dBmin) * i) / (ch - 1)); | |
2161 int idb = int(dBval); | |
2162 | |
2163 double value = AudioLevel::dB_to_multiplier(dBval); | |
2164 paint.setPen(getRenderer(v)->getColour(value)); | |
2165 | |
2166 int y = textHeight * topLines + 4 + ch - i; | |
2167 | |
2168 paint.drawLine(5 + cw - cbw, y, cw + 2, y); | |
2169 | |
2170 if (i == 0) { | |
2171 lasty = y; | |
2172 lastdb = idb; | |
2173 } else if (i < ch - paint.fontMetrics().ascent() && | |
2174 idb != lastdb && | |
2175 ((abs(y - lasty) > textHeight && | |
2176 idb % 10 == 0) || | |
2177 (abs(y - lasty) > paint.fontMetrics().ascent() && | |
2178 idb % 5 == 0))) { | |
2179 paint.setPen(v->getBackground()); | |
2180 QString text = QString("%1").arg(idb); | |
2181 paint.drawText(3 + cw - cbw - paint.fontMetrics().width(text), | |
2182 y + toff + textHeight/2, text); | |
2183 paint.setPen(v->getForeground()); | |
2184 paint.drawLine(5 + cw - cbw, y, 8 + cw - cbw, y); | |
2185 lasty = y; | |
2186 lastdb = idb; | |
2187 } | |
2188 } | |
2189 paint.restore(); | |
2175 } | 2190 } |
2176 | 2191 |
2177 class SpectrogramRangeMapper : public RangeMapper | 2192 class SpectrogramRangeMapper : public RangeMapper |
2178 { | 2193 { |
2179 public: | 2194 public: |