comparison layer/SpectrogramLayer.cpp @ 184:3a6fea0abf56

* Fix miscomparison of matrix height and fft size /2 (should be /2+1)
author Chris Cannam
date Wed, 13 Dec 2006 15:53:23 +0000
parents 42118892f428
children e7cf6044c2a0
comparison
equal deleted inserted replaced
183:5f86ae638b04 184:3a6fea0abf56
926 { 926 {
927 if (!m_model) return; 927 if (!m_model) return;
928 928
929 bool allDone = true; 929 bool allDone = true;
930 930
931 #ifdef DEBUG_SPECTROGRAM_REPAINT
932 std::cerr << "SpectrogramLayer::fillTimerTimedOut: have " << m_fftModels.size() << " FFT models associated with views" << std::endl;
933 #endif
934
931 for (ViewFFTMap::iterator i = m_fftModels.begin(); 935 for (ViewFFTMap::iterator i = m_fftModels.begin();
932 i != m_fftModels.end(); ++i) { 936 i != m_fftModels.end(); ++i) {
933 937
934 const View *v = i->first; 938 const View *v = i->first;
935 const FFTModel *model = i->second.first; 939 const FFTModel *model = i->second.first;
947 if (fill >= m_model->getEndFrame() && lastFill > 0) { 951 if (fill >= m_model->getEndFrame() && lastFill > 0) {
948 #ifdef DEBUG_SPECTROGRAM_REPAINT 952 #ifdef DEBUG_SPECTROGRAM_REPAINT
949 std::cerr << "complete!" << std::endl; 953 std::cerr << "complete!" << std::endl;
950 #endif 954 #endif
951 invalidatePixmapCaches(); 955 invalidatePixmapCaches();
956 i->second.second = -1;
952 emit modelChanged(); 957 emit modelChanged();
953 i->second.second = -1;
954 958
955 } else if (fill > lastFill) { 959 } else if (fill > lastFill) {
956 #ifdef DEBUG_SPECTROGRAM_REPAINT 960 #ifdef DEBUG_SPECTROGRAM_REPAINT
957 std::cerr << "SpectrogramLayer: emitting modelChanged(" 961 std::cerr << "SpectrogramLayer: emitting modelChanged("
958 << lastFill << "," << fill << ")" << std::endl; 962 << lastFill << "," << fill << ")" << std::endl;
959 #endif 963 #endif
960 invalidatePixmapCaches(lastFill, fill); 964 invalidatePixmapCaches(lastFill, fill);
965 i->second.second = fill;
961 emit modelChanged(lastFill, fill); 966 emit modelChanged(lastFill, fill);
962 i->second.second = fill;
963 } 967 }
964 } else { 968 } else {
965 #ifdef DEBUG_SPECTROGRAM_REPAINT 969 #ifdef DEBUG_SPECTROGRAM_REPAINT
966 std::cerr << "SpectrogramLayer: going backwards, emitting modelChanged(" 970 std::cerr << "SpectrogramLayer: going backwards, emitting modelChanged("
967 << m_model->getStartFrame() << "," << m_model->getEndFrame() << ")" << std::endl; 971 << m_model->getStartFrame() << "," << m_model->getEndFrame() << ")" << std::endl;
968 #endif 972 #endif
969 invalidatePixmapCaches(); 973 invalidatePixmapCaches();
974 i->second.second = fill;
970 emit modelChanged(m_model->getStartFrame(), m_model->getEndFrame()); 975 emit modelChanged(m_model->getStartFrame(), m_model->getEndFrame());
971 i->second.second = fill;
972 } 976 }
973 977
974 if (i->second.second >= 0) { 978 if (i->second.second >= 0) {
975 allDone = false; 979 allDone = false;
976 } 980 }
1535 if (!Preferences::getInstance()->getSmoothSpectrogram()) return 0; 1539 if (!Preferences::getInstance()->getSmoothSpectrogram()) return 0;
1536 if (m_frequencyScale == LogFrequencyScale) return 3; 1540 if (m_frequencyScale == LogFrequencyScale) return 3;
1537 1541
1538 int sr = m_model->getSampleRate(); 1542 int sr = m_model->getSampleRate();
1539 1543
1540 size_t bins = m_fftSize / 2; 1544 size_t maxbin = m_fftSize / 2;
1541 if (m_maxFrequency > 0) { 1545 if (m_maxFrequency > 0) {
1542 bins = int((double(m_maxFrequency) * m_fftSize) / sr + 0.1); 1546 maxbin = int((double(m_maxFrequency) * m_fftSize) / sr + 0.1);
1543 if (bins > m_fftSize / 2) bins = m_fftSize / 2; 1547 if (maxbin > m_fftSize / 2) maxbin = m_fftSize / 2;
1544 } 1548 }
1545 1549
1546 size_t minbin = 1; 1550 size_t minbin = 1;
1547 if (m_minFrequency > 0) { 1551 if (m_minFrequency > 0) {
1548 minbin = int((double(m_minFrequency) * m_fftSize) / sr + 0.1); 1552 minbin = int((double(m_minFrequency) * m_fftSize) / sr + 0.1);
1549 if (minbin < 1) minbin = 1; 1553 if (minbin < 1) minbin = 1;
1550 if (minbin >= bins) minbin = bins - 1; 1554 if (minbin >= maxbin) minbin = maxbin - 1;
1551 } 1555 }
1552 1556
1553 float perPixel = 1557 float perPixel =
1554 float(v->height()) / 1558 float(v->height()) /
1555 float((bins - minbin) / (m_zeroPadLevel + 1)); 1559 float((maxbin - minbin) / (m_zeroPadLevel + 1));
1556 1560
1557 if (perPixel > 2.8) { 1561 if (perPixel > 2.8) {
1558 return 3; // 4x oversampling 1562 return 3; // 4x oversampling
1559 } else if (perPixel > 1.5) { 1563 } else if (perPixel > 1.5) {
1560 return 1; // 2x 1564 return 1; // 2x
1575 if (!m_model) return 0; 1579 if (!m_model) return 0;
1576 1580
1577 size_t fftSize = getFFTSize(v); 1581 size_t fftSize = getFFTSize(v);
1578 1582
1579 if (m_fftModels.find(v) != m_fftModels.end()) { 1583 if (m_fftModels.find(v) != m_fftModels.end()) {
1580 if (m_fftModels[v].first == 0) return 0; 1584 if (m_fftModels[v].first == 0) {
1581 if (m_fftModels[v].first->getHeight() != fftSize / 2) { 1585 #ifdef DEBUG_SPECTROGRAM_REPAINT
1586 std::cerr << "SpectrogramLayer::getFFTModel(" << v << "): Found null model" << std::endl;
1587 #endif
1588 return 0;
1589 }
1590 if (m_fftModels[v].first->getHeight() != fftSize / 2 + 1) {
1591 #ifdef DEBUG_SPECTROGRAM_REPAINT
1592 std::cerr << "SpectrogramLayer::getFFTModel(" << v << "): Found a model with the wrong height (" << m_fftModels[v].first->getHeight() << ", wanted " << (fftSize / 2 + 1) << ")" << std::endl;
1593 #endif
1582 delete m_fftModels[v].first; 1594 delete m_fftModels[v].first;
1583 m_fftModels.erase(v); 1595 m_fftModels.erase(v);
1596 } else {
1597 #ifdef DEBUG_SPECTROGRAM_REPAINT
1598 std::cerr << "SpectrogramLayer::getFFTModel(" << v << "): Found a good model" << std::endl;
1599 #endif
1600 return m_fftModels[v].first;
1584 } 1601 }
1585 } 1602 }
1586 1603
1587 if (m_fftModels.find(v) == m_fftModels.end()) { 1604 if (m_fftModels.find(v) == m_fftModels.end()) {
1588 1605
1662 if (m_columnMags[s].isSet()) { 1679 if (m_columnMags[s].isSet()) {
1663 mag.sample(m_columnMags[s]); 1680 mag.sample(m_columnMags[s]);
1664 } 1681 }
1665 } 1682 }
1666 1683
1684 #ifdef DEBUG_SPECTROGRAM_REPAINT
1667 std::cerr << "SpectrogramLayer::updateViewMagnitudes returning from cols " 1685 std::cerr << "SpectrogramLayer::updateViewMagnitudes returning from cols "
1668 << s0 << " -> " << s1 << " inclusive" << std::endl; 1686 << s0 << " -> " << s1 << " inclusive" << std::endl;
1687 #endif
1669 1688
1670 if (!mag.isSet()) return false; 1689 if (!mag.isSet()) return false;
1671 if (mag == m_viewMags[v]) return false; 1690 if (mag == m_viewMags[v]) return false;
1672 m_viewMags[v] = mag; 1691 m_viewMags[v] = mag;
1673 return true; 1692 return true;
1854 y1 = rect.bottom() + 1; 1873 y1 = rect.bottom() + 1;
1855 } 1874 }
1856 */ 1875 */
1857 1876
1858 if (updateViewMagnitudes(v)) { 1877 if (updateViewMagnitudes(v)) {
1878 #ifdef DEBUG_SPECTROGRAM_REPAINT
1859 std::cerr << "SpectrogramLayer: magnitude range changed to [" << m_viewMags[v].getMin() << "->" << m_viewMags[v].getMax() << "]" << std::endl; 1879 std::cerr << "SpectrogramLayer: magnitude range changed to [" << m_viewMags[v].getMin() << "->" << m_viewMags[v].getMax() << "]" << std::endl;
1880 #endif
1860 recreateWholePixmapCache = true; 1881 recreateWholePixmapCache = true;
1861 } else { 1882 } else {
1883 #ifdef DEBUG_SPECTROGRAM_REPAINT
1862 std::cerr << "No change in magnitude range [" << m_viewMags[v].getMin() << "->" << m_viewMags[v].getMax() << "]" << std::endl; 1884 std::cerr << "No change in magnitude range [" << m_viewMags[v].getMin() << "->" << m_viewMags[v].getMax() << "]" << std::endl;
1885 #endif
1863 } 1886 }
1864 1887
1865 if (recreateWholePixmapCache) { 1888 if (recreateWholePixmapCache) {
1866 x0 = 0; 1889 x0 = 0;
1867 x1 = v->width(); 1890 x1 = v->width();
1938 1961
1939 // Set minFreq and maxFreq to the frequency extents of the possibly 1962 // Set minFreq and maxFreq to the frequency extents of the possibly
1940 // zero-padded visible bin range, and displayMinFreq and displayMaxFreq 1963 // zero-padded visible bin range, and displayMinFreq and displayMaxFreq
1941 // to the actual scale frequency extents (presumably not zero padded). 1964 // to the actual scale frequency extents (presumably not zero padded).
1942 1965
1943 size_t bins = fftSize / 2; 1966 size_t maxbin = fftSize / 2;
1944 if (m_maxFrequency > 0) { 1967 if (m_maxFrequency > 0) {
1945 bins = int((double(m_maxFrequency) * fftSize) / sr + 0.1); 1968 maxbin = int((double(m_maxFrequency) * fftSize) / sr + 0.1);
1946 if (bins > fftSize / 2) bins = fftSize / 2; 1969 if (maxbin > fftSize / 2) maxbin = fftSize / 2;
1947 } 1970 }
1948 1971
1949 size_t minbin = 1; 1972 size_t minbin = 1;
1950 if (m_minFrequency > 0) { 1973 if (m_minFrequency > 0) {
1951 minbin = int((double(m_minFrequency) * fftSize) / sr + 0.1); 1974 minbin = int((double(m_minFrequency) * fftSize) / sr + 0.1);
1952 if (minbin < 1) minbin = 1; 1975 if (minbin < 1) minbin = 1;
1953 if (minbin >= bins) minbin = bins - 1; 1976 if (minbin >= maxbin) minbin = maxbin - 1;
1954 } 1977 }
1955 1978
1956 float minFreq = (float(minbin) * sr) / fftSize; 1979 float minFreq = (float(minbin) * sr) / fftSize;
1957 float maxFreq = (float(bins) * sr) / fftSize; 1980 float maxFreq = (float(maxbin) * sr) / fftSize;
1958 1981
1959 float displayMinFreq = minFreq; 1982 float displayMinFreq = minFreq;
1960 float displayMaxFreq = maxFreq; 1983 float displayMaxFreq = maxFreq;
1961 1984
1962 if (fftSize != m_fftSize) { 1985 if (fftSize != m_fftSize) {
1964 displayMaxFreq = getEffectiveMaxFrequency(); 1987 displayMaxFreq = getEffectiveMaxFrequency();
1965 } 1988 }
1966 1989
1967 float ymag[h]; 1990 float ymag[h];
1968 float ydiv[h]; 1991 float ydiv[h];
1969 float yval[bins + 1]; //!!! cache this? 1992 float yval[maxbin + 1]; //!!! cache this?
1970 1993
1971 size_t increment = getWindowIncrement(); 1994 size_t increment = getWindowIncrement();
1972 1995
1973 bool logarithmic = (m_frequencyScale == LogFrequencyScale); 1996 bool logarithmic = (m_frequencyScale == LogFrequencyScale);
1974 1997
1975 for (size_t q = minbin; q <= bins; ++q) { 1998 for (size_t q = minbin; q <= maxbin; ++q) {
1976 float f0 = (float(q) * sr) / fftSize; 1999 float f0 = (float(q) * sr) / fftSize;
1977 yval[q] = v->getYForFrequency(f0, displayMinFreq, displayMaxFreq, 2000 yval[q] = v->getYForFrequency(f0, displayMinFreq, displayMaxFreq,
1978 logarithmic); 2001 logarithmic);
1979 // std::cerr << "min: " << minFreq << ", max: " << maxFreq << ", yval[" << q << "]: " << yval[q] << std::endl; 2002 // std::cerr << "min: " << minFreq << ", max: " << maxFreq << ", yval[" << q << "]: " << yval[q] << std::endl;
1980 } 2003 }
2022 fftSuspended = true; 2045 fftSuspended = true;
2023 } 2046 }
2024 2047
2025 MagnitudeRange mag; 2048 MagnitudeRange mag;
2026 2049
2027 for (size_t q = minbin; q < bins; ++q) { 2050 for (size_t q = minbin; q < maxbin; ++q) {
2028 2051
2029 float y0 = yval[q + 1]; 2052 float y0 = yval[q + 1];
2030 float y1 = yval[q]; 2053 float y1 = yval[q];
2031 2054
2032 if (m_binDisplay == PeakBins || 2055 if (m_binDisplay == PeakBins ||