Mercurial > hg > svgui
comparison layer/SpectrogramLayer.cpp @ 221:9e739f92c0b8
* Add fuzzy interpolation option as an alternative to zero padding in
spectrogram (looks terrible though)
* Make spectrogram appear more quickly by having the FFT server notify of
updates more often near the start of its run
author | Chris Cannam |
---|---|
date | Mon, 05 Mar 2007 15:32:55 +0000 |
parents | 34bbbcb3c01f |
children | cd81066ac7ad |
comparison
equal
deleted
inserted
replaced
220:8dc50f57d480 | 221:9e739f92c0b8 |
---|---|
574 | 574 |
575 if (name == "Window Type") { | 575 if (name == "Window Type") { |
576 setWindowType(Preferences::getInstance()->getWindowType()); | 576 setWindowType(Preferences::getInstance()->getWindowType()); |
577 return; | 577 return; |
578 } | 578 } |
579 if (name == "Smooth Spectrogram") { | 579 if (name == "Spectrogram Smoothing") { |
580 invalidatePixmapCaches(); | 580 invalidatePixmapCaches(); |
581 invalidateMagnitudes(); | 581 invalidateMagnitudes(); |
582 emit layerParametersChanged(); | 582 emit layerParametersChanged(); |
583 } | 583 } |
584 if (name == "Tuning Frequency") { | 584 if (name == "Tuning Frequency") { |
1492 SpectrogramLayer::getZeroPadLevel(const View *v) const | 1492 SpectrogramLayer::getZeroPadLevel(const View *v) const |
1493 { | 1493 { |
1494 //!!! tidy all this stuff | 1494 //!!! tidy all this stuff |
1495 | 1495 |
1496 if (m_binDisplay != AllBins) return 0; | 1496 if (m_binDisplay != AllBins) return 0; |
1497 if (!Preferences::getInstance()->getSmoothSpectrogram()) return 0; | 1497 |
1498 Preferences::SpectrogramSmoothing smoothing = | |
1499 Preferences::getInstance()->getSpectrogramSmoothing(); | |
1500 | |
1501 if (smoothing == Preferences::NoSpectrogramSmoothing || | |
1502 smoothing == Preferences::SpectrogramInterpolated) return 0; | |
1503 | |
1498 if (m_frequencyScale == LogFrequencyScale) return 3; | 1504 if (m_frequencyScale == LogFrequencyScale) return 3; |
1499 | 1505 |
1500 int sr = m_model->getSampleRate(); | 1506 int sr = m_model->getSampleRate(); |
1501 | 1507 |
1502 size_t maxbin = m_fftSize / 2; | 1508 size_t maxbin = m_fftSize / 2; |
2014 MagnitudeRange overallMag = m_viewMags[v]; | 2020 MagnitudeRange overallMag = m_viewMags[v]; |
2015 bool overallMagChanged = false; | 2021 bool overallMagChanged = false; |
2016 | 2022 |
2017 bool fftSuspended = false; | 2023 bool fftSuspended = false; |
2018 | 2024 |
2025 bool interpolate = false; | |
2026 Preferences::SpectrogramSmoothing smoothing = | |
2027 Preferences::getInstance()->getSpectrogramSmoothing(); | |
2028 if (smoothing == Preferences::SpectrogramInterpolated || | |
2029 smoothing == Preferences::SpectrogramZeroPaddedAndInterpolated) { | |
2030 interpolate = true; | |
2031 } | |
2032 | |
2033 | |
2019 #ifdef DEBUG_SPECTROGRAM_REPAINT | 2034 #ifdef DEBUG_SPECTROGRAM_REPAINT |
2020 std::cerr << (float(v->getFrameForX(1) - v->getFrameForX(0)) / increment) << " bins per pixel" << std::endl; | 2035 std::cerr << (float(v->getFrameForX(1) - v->getFrameForX(0)) / increment) << " bins per pixel" << std::endl; |
2021 #endif | 2036 #endif |
2022 | 2037 |
2023 for (int x = 0; x < w; ++x) { | 2038 for (int x = 0; x < w; ++x) { |
2106 value = fft->getMagnitudeAt(s, q); | 2121 value = fft->getMagnitudeAt(s, q); |
2107 mag.sample(value); | 2122 mag.sample(value); |
2108 value *= m_gain; | 2123 value *= m_gain; |
2109 } | 2124 } |
2110 | 2125 |
2111 for (int y = y0i; y <= y1i; ++y) { | 2126 if (interpolate) { |
2127 | |
2128 int ypi = y0i; | |
2129 if (q < maxbin - 1) ypi = int(yval[q + 2]); | |
2130 | |
2131 for (int y = ypi; y <= y1i; ++y) { | |
2132 | |
2133 if (y < 0 || y >= h) continue; | |
2134 | |
2135 float yprop = sprop; | |
2136 float iprop = yprop; | |
2137 | |
2138 if (ypi < y0i && y <= y0i) { | |
2139 | |
2140 float half = float(y0i - ypi) / 2; | |
2141 float dist = y - (ypi + half); | |
2142 | |
2143 if (dist >= 0) { | |
2144 iprop = (iprop * dist) / half; | |
2145 ymag[y] += iprop * value; | |
2146 } | |
2147 } else { | |
2148 if (y1i > y0i) { | |
2149 | |
2150 float half = float(y1i - y0i) / 2; | |
2151 float dist = y - (y0i + half); | |
2152 | |
2153 if (dist >= 0) { | |
2154 iprop = (iprop * (half - dist)) / half; | |
2155 } | |
2156 } | |
2157 | |
2158 ymag[y] += iprop * value; | |
2159 ydiv[y] += yprop; | |
2160 } | |
2161 } | |
2162 | |
2163 } else { | |
2164 | |
2165 for (int y = y0i; y <= y1i; ++y) { | |
2166 | |
2167 if (y < 0 || y >= h) continue; | |
2168 | |
2169 float yprop = sprop; | |
2170 if (y == y0i) yprop *= (y + 1) - y0; | |
2171 if (y == y1i) yprop *= y1 - y; | |
2172 | |
2173 for (int y = y0i; y <= y1i; ++y) { | |
2112 | 2174 |
2113 if (y < 0 || y >= h) continue; | 2175 if (y < 0 || y >= h) continue; |
2114 | 2176 |
2115 float yprop = sprop; | 2177 float yprop = sprop; |
2116 if (y == y0i) yprop *= (y + 1) - y0; | 2178 if (y == y0i) yprop *= (y + 1) - y0; |
2117 if (y == y1i) yprop *= y1 - y; | 2179 if (y == y1i) yprop *= y1 - y; |
2118 ymag[y] += yprop * value; | 2180 ymag[y] += yprop * value; |
2119 ydiv[y] += yprop; | 2181 ydiv[y] += yprop; |
2120 } | 2182 } |
2183 } | |
2184 } | |
2121 } | 2185 } |
2122 | 2186 |
2123 if (mag.isSet()) { | 2187 if (mag.isSet()) { |
2124 | |
2125 | 2188 |
2126 if (s >= m_columnMags.size()) { | 2189 if (s >= m_columnMags.size()) { |
2127 std::cerr << "INTERNAL ERROR: " << s << " >= " | 2190 std::cerr << "INTERNAL ERROR: " << s << " >= " |
2128 << m_columnMags.size() << " at SpectrogramLayer.cpp:2087" << std::endl; | 2191 << m_columnMags.size() << " at SpectrogramLayer.cpp:2087" << std::endl; |
2129 } | 2192 } |