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 }