Mercurial > hg > svgui
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 || |