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: