Mercurial > hg > svgui
comparison layer/SpectrogramLayer.cpp @ 92:23d1e37bbfb4
* Make a single base Thread class for RT and non-RT threads
* Pull ResizeableBitmap out from the MatrixFile's ColumnBitmap
* Reorder SpectrogramLayer::paint somewhat so as to improve cache hit ratio
in the FFT file cache
author | Chris Cannam |
---|---|
date | Mon, 08 May 2006 16:44:47 +0000 |
parents | ed01c1261b55 |
children | 05c41701dc6c |
comparison
equal
deleted
inserted
replaced
91:ed01c1261b55 | 92:23d1e37bbfb4 |
---|---|
25 #include <QPainter> | 25 #include <QPainter> |
26 #include <QImage> | 26 #include <QImage> |
27 #include <QPixmap> | 27 #include <QPixmap> |
28 #include <QRect> | 28 #include <QRect> |
29 #include <QTimer> | 29 #include <QTimer> |
30 #include <QApplication> | |
30 | 31 |
31 #include <iostream> | 32 #include <iostream> |
32 | 33 |
33 #include <cassert> | 34 #include <cassert> |
34 #include <cmath> | 35 #include <cmath> |
35 | 36 |
36 #define DEBUG_SPECTROGRAM_REPAINT 1 | 37 //#define DEBUG_SPECTROGRAM_REPAINT 1 |
37 | 38 |
38 static double mod(double x, double y) | 39 static double mod(double x, double y) |
39 { | 40 { |
40 double a = floor(x / y); | 41 double a = floor(x / y); |
41 double b = x - (y * a); | 42 double b = x - (y * a); |
1746 int y0 = 0; | 1747 int y0 = 0; |
1747 int y1 = v->height(); | 1748 int y1 = v->height(); |
1748 | 1749 |
1749 bool recreateWholePixmapCache = true; | 1750 bool recreateWholePixmapCache = true; |
1750 | 1751 |
1752 // if (stillCacheing) { | |
1753 x0 = rect.left(); | |
1754 x1 = rect.right() + 1; | |
1755 y0 = rect.top(); | |
1756 y1 = rect.bottom() + 1; | |
1757 // } | |
1758 | |
1751 if (!m_pixmapCacheInvalid) { | 1759 if (!m_pixmapCacheInvalid) { |
1752 | 1760 |
1753 //!!! This cache may have been obsoleted entirely by the | 1761 //!!! This cache may have been obsoleted entirely by the |
1754 //scrolling cache in View. Perhaps experiment with | 1762 //scrolling cache in View. Perhaps experiment with |
1755 //removing it and see if it makes things even quicker (or else | 1763 //removing it and see if it makes things even quicker (or else |
1830 #ifdef DEBUG_SPECTROGRAM_REPAINT | 1838 #ifdef DEBUG_SPECTROGRAM_REPAINT |
1831 std::cerr << "SpectrogramLayer: pixmap cache useless" << std::endl; | 1839 std::cerr << "SpectrogramLayer: pixmap cache useless" << std::endl; |
1832 #endif | 1840 #endif |
1833 } | 1841 } |
1834 } | 1842 } |
1835 | 1843 /* |
1836 if (stillCacheing) { | 1844 if (stillCacheing) { |
1837 x0 = rect.left(); | 1845 x0 = rect.left(); |
1838 x1 = rect.right() + 1; | 1846 x1 = rect.right() + 1; |
1839 y0 = rect.top(); | 1847 y0 = rect.top(); |
1840 y1 = rect.bottom() + 1; | 1848 y1 = rect.bottom() + 1; |
1841 } | 1849 } |
1842 | 1850 */ |
1843 int w = x1 - x0; | 1851 int w = x1 - x0; |
1844 int h = y1 - y0; | 1852 int h = y1 - y0; |
1845 | 1853 |
1846 // std::cerr << "x0 " << x0 << ", x1 " << x1 << ", w " << w << ", h " << h << std::endl; | 1854 // std::cerr << "x0 " << x0 << ", x1 " << x1 << ", w " << w << ", h " << h << std::endl; |
1847 | 1855 |
1848 QImage scaled(w, h, QImage::Format_RGB32); | 1856 QImage scaled(w, h, QImage::Format_RGB32); |
1849 scaled.fill(m_colourMap.getColour(0).rgb()); | 1857 scaled.fill(m_colourMap.getColour(0).rgb()); |
1850 | |
1851 float ymag[h]; | |
1852 float ydiv[h]; | |
1853 | 1858 |
1854 int sr = m_model->getSampleRate(); | 1859 int sr = m_model->getSampleRate(); |
1855 | 1860 |
1856 size_t bins = m_windowSize / 2; | 1861 size_t bins = m_windowSize / 2; |
1857 if (m_maxFrequency > 0) { | 1862 if (m_maxFrequency > 0) { |
1867 } | 1872 } |
1868 | 1873 |
1869 float minFreq = (float(minbin) * sr) / m_windowSize; | 1874 float minFreq = (float(minbin) * sr) / m_windowSize; |
1870 float maxFreq = (float(bins) * sr) / m_windowSize; | 1875 float maxFreq = (float(bins) * sr) / m_windowSize; |
1871 | 1876 |
1877 float ymag[h]; | |
1878 float ydiv[h]; | |
1879 float yval[bins + 1]; | |
1880 | |
1872 size_t increment = getWindowIncrement(); | 1881 size_t increment = getWindowIncrement(); |
1873 | 1882 |
1874 bool logarithmic = (m_frequencyScale == LogFrequencyScale); | 1883 bool logarithmic = (m_frequencyScale == LogFrequencyScale); |
1875 | 1884 |
1876 m_mutex.unlock(); | 1885 m_mutex.unlock(); |
1886 | |
1887 for (size_t q = minbin; q <= bins; ++q) { | |
1888 float f0 = (float(q) * sr) / m_windowSize; | |
1889 yval[q] = v->getYForFrequency(f0, minFreq, maxFreq, logarithmic); | |
1890 } | |
1877 | 1891 |
1878 for (int x = 0; x < w; ++x) { | 1892 for (int x = 0; x < w; ++x) { |
1879 | 1893 |
1880 m_mutex.lock(); | 1894 m_mutex.lock(); |
1881 if (m_cacheInvalid) { | 1895 if (m_cacheInvalid) { |
1905 continue; | 1919 continue; |
1906 } else { | 1920 } else { |
1907 s1i = s0i; | 1921 s1i = s0i; |
1908 } | 1922 } |
1909 } | 1923 } |
1910 | 1924 |
1911 bool haveColumn = false; | 1925 for (int s = s0i; s <= s1i; ++s) { |
1912 for (size_t s = s0i; s <= s1i; ++s) { | 1926 |
1913 if (m_cache->haveColumnAt(s)) { | 1927 if (!m_cache->haveColumnAt(s)) continue; |
1914 haveColumn = true; | 1928 |
1915 break; | 1929 for (size_t q = minbin; q < bins; ++q) { |
1916 } | 1930 |
1917 } | 1931 // float f0 = (float(q) * sr) / m_windowSize; |
1918 if (!haveColumn) { | 1932 // float f1 = (float(q + 1) * sr) / m_windowSize; |
1919 m_mutex.unlock(); | 1933 |
1920 continue; | 1934 // float y0 = 0, y1 = 0; |
1921 } | 1935 |
1922 | 1936 float y0 = yval[q + 1]; |
1923 for (size_t q = minbin; q < bins; ++q) { | 1937 float y1 = yval[q]; |
1924 | 1938 |
1925 float f0 = (float(q) * sr) / m_windowSize; | 1939 |
1926 float f1 = (float(q + 1) * sr) / m_windowSize; | 1940 /* |
1927 | 1941 if (m_binDisplay != PeakFrequencies) { |
1928 float y0 = 0, y1 = 0; | 1942 y0 = v->getYForFrequency(f1, minFreq, maxFreq, logarithmic); |
1929 | 1943 y1 = v->getYForFrequency(f0, minFreq, maxFreq, logarithmic); |
1930 if (m_binDisplay != PeakFrequencies) { | 1944 } |
1931 y0 = v->getYForFrequency(f1, minFreq, maxFreq, logarithmic); | 1945 */ |
1932 y1 = v->getYForFrequency(f0, minFreq, maxFreq, logarithmic); | |
1933 } | |
1934 | |
1935 for (int s = s0i; s <= s1i; ++s) { | |
1936 | |
1937 if (m_binDisplay == PeakBins || | 1946 if (m_binDisplay == PeakBins || |
1938 m_binDisplay == PeakFrequencies) { | 1947 m_binDisplay == PeakFrequencies) { |
1939 if (!m_cache->isLocalPeak(s, q)) continue; | 1948 if (!m_cache->isLocalPeak(s, q)) continue; |
1940 } | 1949 } |
1941 | 1950 |
1947 | 1956 |
1948 if (m_binDisplay == PeakFrequencies && | 1957 if (m_binDisplay == PeakFrequencies && |
1949 s < int(m_cache->getWidth()) - 1) { | 1958 s < int(m_cache->getWidth()) - 1) { |
1950 | 1959 |
1951 bool steady = false; | 1960 bool steady = false; |
1952 f0 = f1 = calculateFrequency(q, | 1961 // f0 = f1 = calculateFrequency(q, |
1962 float f = calculateFrequency(q, | |
1953 m_windowSize, | 1963 m_windowSize, |
1954 increment, | 1964 increment, |
1955 sr, | 1965 sr, |
1956 m_cache->getPhaseAt(s, q), | 1966 m_cache->getPhaseAt(s, q), |
1957 m_cache->getPhaseAt(s+1, q), | 1967 m_cache->getPhaseAt(s+1, q), |
1958 steady); | 1968 steady); |
1959 | 1969 |
1960 y0 = y1 = v->getYForFrequency | 1970 y0 = y1 = v->getYForFrequency |
1961 (f0, minFreq, maxFreq, logarithmic); | 1971 // (f0, minFreq, maxFreq, logarithmic); |
1972 (f, minFreq, maxFreq, logarithmic); | |
1962 } | 1973 } |
1963 | 1974 |
1964 int y0i = int(y0 + 0.001); | 1975 int y0i = int(y0 + 0.001); |
1965 int y1i = int(y1); | 1976 int y1i = int(y1); |
1966 | 1977 |
1978 float value; | |
1979 | |
1980 if (m_colourScale == PhaseColourScale) { | |
1981 value = m_cache->getPhaseAt(s, q); | |
1982 } else if (m_normalizeColumns) { | |
1983 value = m_cache->getNormalizedMagnitudeAt(s, q) * m_gain; | |
1984 } else { | |
1985 value = m_cache->getMagnitudeAt(s, q) * m_gain; | |
1986 } | |
1987 | |
1967 for (int y = y0i; y <= y1i; ++y) { | 1988 for (int y = y0i; y <= y1i; ++y) { |
1968 | 1989 |
1969 if (y < 0 || y >= h) continue; | 1990 if (y < 0 || y >= h) continue; |
1970 | 1991 |
1971 float yprop = sprop; | 1992 float yprop = sprop; |
1972 if (y == y0i) yprop *= (y + 1) - y0; | 1993 if (y == y0i) yprop *= (y + 1) - y0; |
1973 if (y == y1i) yprop *= y1 - y; | 1994 if (y == y1i) yprop *= y1 - y; |
1974 | |
1975 float value; | |
1976 | |
1977 if (m_colourScale == PhaseColourScale) { | |
1978 value = m_cache->getPhaseAt(s, q); | |
1979 } else if (m_normalizeColumns) { | |
1980 value = m_cache->getNormalizedMagnitudeAt(s, q) * m_gain; | |
1981 } else { | |
1982 value = m_cache->getMagnitudeAt(s, q) * m_gain; | |
1983 } | |
1984 | |
1985 ymag[y] += yprop * value; | 1995 ymag[y] += yprop * value; |
1986 ydiv[y] += yprop; | 1996 ydiv[y] += yprop; |
1987 } | 1997 } |
1988 } | 1998 } |
1989 } | 1999 } |