Mercurial > hg > svgui
comparison layer/SpectrogramLayer.cpp @ 1022:2bd5eb6a6c6b colourschemes
Tidy a bit
author | Chris Cannam |
---|---|
date | Fri, 22 Jan 2016 17:08:02 +0000 |
parents | 25ec2390fad3 |
children | 74755fa6ea9e |
comparison
equal
deleted
inserted
replaced
1021:33d7e1a6747b | 1022:2bd5eb6a6c6b |
---|---|
47 | 47 |
48 #ifndef __GNUC__ | 48 #ifndef __GNUC__ |
49 #include <alloca.h> | 49 #include <alloca.h> |
50 #endif | 50 #endif |
51 | 51 |
52 //#define DEBUG_SPECTROGRAM_REPAINT 1 | 52 #define DEBUG_SPECTROGRAM_REPAINT 1 |
53 | 53 |
54 using std::vector; | 54 using std::vector; |
55 | 55 |
56 SpectrogramLayer::SpectrogramLayer(Configuration config) : | 56 SpectrogramLayer::SpectrogramLayer(Configuration config) : |
57 m_model(0), | 57 m_model(0), |
1356 | 1356 |
1357 for (int q = q0i; q <= q1i; ++q) { | 1357 for (int q = q0i; q <= q1i; ++q) { |
1358 | 1358 |
1359 for (int s = s0i; s <= s1i; ++s) { | 1359 for (int s = s0i; s <= s1i; ++s) { |
1360 | 1360 |
1361 if (!fft->isColumnAvailable(s)) continue; | |
1362 | |
1363 double binfreq = (double(sr) * q) / m_windowSize; | 1361 double binfreq = (double(sr) * q) / m_windowSize; |
1364 if (q == q0i) freqMin = binfreq; | 1362 if (q == q0i) freqMin = binfreq; |
1365 if (q == q1i) freqMax = binfreq; | 1363 if (q == q1i) freqMax = binfreq; |
1366 | 1364 |
1367 if (peaksOnly && !fft->isLocalPeak(s, q)) continue; | 1365 if (peaksOnly && !fft->isLocalPeak(s, q)) continue; |
1431 | 1429 |
1432 for (int q = q0i; q <= q1i; ++q) { | 1430 for (int q = q0i; q <= q1i; ++q) { |
1433 for (int s = s0i; s <= s1i; ++s) { | 1431 for (int s = s0i; s <= s1i; ++s) { |
1434 if (s >= 0 && q >= 0 && s < cw && q < ch) { | 1432 if (s >= 0 && q >= 0 && s < cw && q < ch) { |
1435 | 1433 |
1436 if (!fft->isColumnAvailable(s)) continue; | |
1437 | |
1438 double value; | 1434 double value; |
1439 | 1435 |
1440 value = fft->getPhaseAt(s, q); | 1436 value = fft->getPhaseAt(s, q); |
1441 if (!have || value < phaseMin) { phaseMin = value; } | 1437 if (!have || value < phaseMin) { phaseMin = value; } |
1442 if (!have || value > phaseMax) { phaseMax = value; } | 1438 if (!have || value > phaseMax) { phaseMax = value; } |
1703 // in the cache-fill thread above. | 1699 // in the cache-fill thread above. |
1704 //!!! no inter use cache-fill thread | 1700 //!!! no inter use cache-fill thread |
1705 const_cast<SpectrogramLayer *>(this)->Layer::setLayerDormant(v, false); | 1701 const_cast<SpectrogramLayer *>(this)->Layer::setLayerDormant(v, false); |
1706 | 1702 |
1707 int fftSize = getFFTSize(v); | 1703 int fftSize = getFFTSize(v); |
1708 /* | |
1709 FFTModel *fft = getFFTModel(v); | |
1710 if (!fft) { | |
1711 cerr << "ERROR: SpectrogramLayer::paint(): No FFT model, returning" << endl; | |
1712 return; | |
1713 } | |
1714 */ | |
1715 | 1704 |
1716 const View *view = v->getView(); | 1705 const View *view = v->getView(); |
1717 | 1706 |
1718 ImageCache &cache = m_imageCaches[view]; | 1707 ImageCache &cache = m_imageCaches[view]; |
1719 | 1708 |
1730 | 1719 |
1731 bool recreateWholeImageCache = true; | 1720 bool recreateWholeImageCache = true; |
1732 | 1721 |
1733 x0 = rect.left(); | 1722 x0 = rect.left(); |
1734 x1 = rect.right() + 1; | 1723 x1 = rect.right() + 1; |
1735 /* | 1724 |
1736 double xPixelRatio = double(fft->getResolution()) / double(zoomLevel); | 1725 if (updateViewMagnitudes(v)) { |
1737 cerr << "xPixelRatio = " << xPixelRatio << endl; | 1726 #ifdef DEBUG_SPECTROGRAM_REPAINT |
1738 if (xPixelRatio < 1.f) xPixelRatio = 1.f; | 1727 cerr << "SpectrogramLayer: magnitude range changed to [" << m_viewMags[v].getMin() << "->" << m_viewMags[v].getMax() << "]" << endl; |
1739 */ | 1728 #endif |
1729 if (m_normalization == NormalizeVisibleArea) { | |
1730 cache.validArea = QRect(); | |
1731 } | |
1732 } | |
1733 | |
1740 if (cache.validArea.width() > 0) { | 1734 if (cache.validArea.width() > 0) { |
1741 | 1735 |
1742 int cw = cache.image.width(); | 1736 int cw = cache.image.width(); |
1743 int ch = cache.image.height(); | 1737 int ch = cache.image.height(); |
1744 | 1738 |
1745 if (int(cache.zoomLevel) == zoomLevel && | 1739 if (int(cache.zoomLevel) == zoomLevel && |
1746 cw == v->getPaintWidth() && | 1740 cw == v->getPaintWidth() && |
1747 ch == v->getPaintHeight()) { | 1741 ch == v->getPaintHeight()) { |
1748 | 1742 |
1743 // cache size and zoom level exactly match the view | |
1744 | |
1749 if (v->getXForFrame(cache.startFrame) == | 1745 if (v->getXForFrame(cache.startFrame) == |
1750 v->getXForFrame(startFrame) && | 1746 v->getXForFrame(startFrame) && |
1751 cache.validArea.x() <= x0 && | 1747 cache.validArea.x() <= x0 && |
1752 cache.validArea.x() + cache.validArea.width() >= x1) { | 1748 cache.validArea.x() + cache.validArea.width() >= x1) { |
1753 | 1749 |
1750 // and cache begins at the right frame, so use it whole | |
1751 | |
1754 #ifdef DEBUG_SPECTROGRAM_REPAINT | 1752 #ifdef DEBUG_SPECTROGRAM_REPAINT |
1755 cerr << "SpectrogramLayer: image cache good" << endl; | 1753 cerr << "SpectrogramLayer: image cache good" << endl; |
1756 #endif | 1754 #endif |
1757 | 1755 |
1758 paint.drawImage(rect, cache.image, rect); | 1756 paint.drawImage(rect, cache.image, rect); |
1759 //!!! | |
1760 // paint.drawImage(v->rect(), cache.image, | |
1761 // QRect(QPoint(0, 0), cache.image.size())); | |
1762 | 1757 |
1763 illuminateLocalFeatures(v, paint); | 1758 illuminateLocalFeatures(v, paint); |
1764 return; | 1759 return; |
1765 | 1760 |
1766 } else { | 1761 } else { |
1767 | 1762 |
1763 // cache doesn't begin at the right frame or doesn't | |
1764 // contain the complete view, but might be scrollable | |
1765 // or partially usable | |
1766 | |
1768 #ifdef DEBUG_SPECTROGRAM_REPAINT | 1767 #ifdef DEBUG_SPECTROGRAM_REPAINT |
1769 cerr << "SpectrogramLayer: image cache partially OK" << endl; | 1768 cerr << "SpectrogramLayer: image cache partially OK" << endl; |
1770 #endif | 1769 #endif |
1771 | 1770 |
1772 recreateWholeImageCache = false; | 1771 recreateWholeImageCache = false; |
1779 #endif | 1778 #endif |
1780 | 1779 |
1781 if (dx != 0 && | 1780 if (dx != 0 && |
1782 dx > -cw && | 1781 dx > -cw && |
1783 dx < cw) { | 1782 dx < cw) { |
1783 | |
1784 // cache is scrollable, scroll it | |
1784 | 1785 |
1785 int dxp = dx; | 1786 int dxp = dx; |
1786 if (dxp < 0) dxp = -dxp; | 1787 if (dxp < 0) dxp = -dxp; |
1787 size_t copy = (cw - dxp) * sizeof(QRgb); | 1788 size_t copy = (cw - dxp) * sizeof(QRgb); |
1788 for (int y = 0; y < ch; ++y) { | 1789 for (int y = 0; y < ch; ++y) { |
1792 } else { | 1793 } else { |
1793 memmove(line + dxp, line, copy); | 1794 memmove(line + dxp, line, copy); |
1794 } | 1795 } |
1795 } | 1796 } |
1796 | 1797 |
1798 // and calculate its new valid area | |
1799 | |
1797 int px = cache.validArea.x(); | 1800 int px = cache.validArea.x(); |
1798 int pw = cache.validArea.width(); | 1801 int pw = cache.validArea.width(); |
1799 | 1802 |
1800 if (dx < 0) { | 1803 if (dx < 0) { |
1801 x0 = cw + dx; | 1804 x0 = cw + dx; |
1824 cerr << "valid area now " | 1827 cerr << "valid area now " |
1825 << px << "," << cache.validArea.y() | 1828 << px << "," << cache.validArea.y() |
1826 << " " << pw << "x" << cache.validArea.height() | 1829 << " " << pw << "x" << cache.validArea.height() |
1827 << endl; | 1830 << endl; |
1828 #endif | 1831 #endif |
1829 /* | 1832 |
1830 paint.drawImage(rect & cache.validArea, | |
1831 cache.image, | |
1832 rect & cache.validArea); | |
1833 */ | |
1834 } else if (dx != 0) { | 1833 } else if (dx != 0) { |
1835 | 1834 |
1836 // we scrolled too far to be of use | 1835 // we've moved too far from the cached area for it |
1836 // to be of use | |
1837 | 1837 |
1838 #ifdef DEBUG_SPECTROGRAM_REPAINT | 1838 #ifdef DEBUG_SPECTROGRAM_REPAINT |
1839 cerr << "dx == " << dx << ": scrolled too far for cache to be useful" << endl; | 1839 cerr << "dx == " << dx << ": scrolled too far for cache to be useful" << endl; |
1840 #endif | 1840 #endif |
1841 | 1841 |
1858 cerr << "(cache height " << ch | 1858 cerr << "(cache height " << ch |
1859 << " != " << v->getPaintHeight(); | 1859 << " != " << v->getPaintHeight(); |
1860 } | 1860 } |
1861 #endif | 1861 #endif |
1862 cache.validArea = QRect(); | 1862 cache.validArea = QRect(); |
1863 // recreateWholeImageCache = true; | |
1864 } | 1863 } |
1865 } | |
1866 | |
1867 if (updateViewMagnitudes(v)) { | |
1868 #ifdef DEBUG_SPECTROGRAM_REPAINT | |
1869 cerr << "SpectrogramLayer: magnitude range changed to [" << m_viewMags[v].getMin() << "->" << m_viewMags[v].getMax() << "]" << endl; | |
1870 #endif | |
1871 if (m_normalization == NormalizeVisibleArea) { | |
1872 cache.validArea = QRect(); | |
1873 recreateWholeImageCache = true; | |
1874 } | |
1875 } else { | |
1876 #ifdef DEBUG_SPECTROGRAM_REPAINT | |
1877 cerr << "No change in magnitude range [" << m_viewMags[v].getMin() << "->" << m_viewMags[v].getMax() << "]" << endl; | |
1878 #endif | |
1879 } | 1864 } |
1880 | 1865 |
1881 if (recreateWholeImageCache) { | 1866 if (recreateWholeImageCache) { |
1882 x0 = 0; | 1867 x0 = 0; |
1883 x1 = v->getPaintWidth(); | 1868 x1 = v->getPaintWidth(); |
2344 (void)gettimeofday(&tv, 0); | 2329 (void)gettimeofday(&tv, 0); |
2345 m_lastPaintTime = RealTime::fromTimeval(tv) - mainPaintStart; | 2330 m_lastPaintTime = RealTime::fromTimeval(tv) - mainPaintStart; |
2346 } | 2331 } |
2347 } | 2332 } |
2348 | 2333 |
2349 bool | 2334 void |
2350 SpectrogramLayer::paintDrawBufferPeakFrequencies(LayerGeometryProvider *v, | 2335 SpectrogramLayer::paintDrawBufferPeakFrequencies(LayerGeometryProvider *v, |
2351 int w, | 2336 int w, |
2352 int h, | 2337 int h, |
2353 const vector<int> &binforx, | 2338 const vector<int> &binforx, |
2354 int minbin, | 2339 int minbin, |
2366 #endif | 2351 #endif |
2367 if (minbin < 0) minbin = 0; | 2352 if (minbin < 0) minbin = 0; |
2368 if (maxbin < 0) maxbin = minbin+1; | 2353 if (maxbin < 0) maxbin = minbin+1; |
2369 | 2354 |
2370 FFTModel *fft = getFFTModel(v); | 2355 FFTModel *fft = getFFTModel(v); |
2371 if (!fft) return false; | 2356 if (!fft) return; |
2372 | 2357 |
2373 FFTModel::PeakSet peakfreqs; | 2358 FFTModel::PeakSet peakfreqs; |
2374 | 2359 |
2375 int psx = -1; | 2360 int psx = -1; |
2376 | 2361 |
2392 if (sx1 <= sx0) sx1 = sx0 + 1; | 2377 if (sx1 <= sx0) sx1 = sx0 + 1; |
2393 | 2378 |
2394 for (int sx = sx0; sx < sx1; ++sx) { | 2379 for (int sx = sx0; sx < sx1; ++sx) { |
2395 | 2380 |
2396 if (sx < 0 || sx >= int(fft->getWidth())) continue; | 2381 if (sx < 0 || sx >= int(fft->getWidth())) continue; |
2397 | |
2398 if (!m_synchronous) { | |
2399 if (!fft->isColumnAvailable(sx)) { | |
2400 #ifdef DEBUG_SPECTROGRAM_REPAINT | |
2401 cerr << "Met unavailable column at col " << sx << endl; | |
2402 #endif | |
2403 return false; | |
2404 } | |
2405 } | |
2406 | 2382 |
2407 MagnitudeRange mag; | 2383 MagnitudeRange mag; |
2408 | 2384 |
2409 if (sx != psx) { | 2385 if (sx != psx) { |
2410 peakfreqs = fft->getPeakFrequencies(FFTModel::AllPeaks, sx, | 2386 peakfreqs = fft->getPeakFrequencies(FFTModel::AllPeaks, sx, |
2468 if (overallMag.sample(mag)) overallMagChanged = true; | 2444 if (overallMag.sample(mag)) overallMagChanged = true; |
2469 } | 2445 } |
2470 } | 2446 } |
2471 } | 2447 } |
2472 } | 2448 } |
2473 | 2449 } |
2474 return true; | 2450 |
2475 } | 2451 void |
2476 | |
2477 bool | |
2478 SpectrogramLayer::paintDrawBuffer(LayerGeometryProvider *v, | 2452 SpectrogramLayer::paintDrawBuffer(LayerGeometryProvider *v, |
2479 int w, | 2453 int w, |
2480 int h, | 2454 int h, |
2481 const vector<int> &binforx, | 2455 const vector<int> &binforx, |
2482 const vector<double> &binfory, | 2456 const vector<double> &binfory, |
2508 maxbin = sourceModel->getHeight(); | 2482 maxbin = sourceModel->getHeight(); |
2509 } else { | 2483 } else { |
2510 sourceModel = fft = getFFTModel(v); | 2484 sourceModel = fft = getFFTModel(v); |
2511 } | 2485 } |
2512 | 2486 |
2513 if (!sourceModel) return false; | 2487 if (!sourceModel) return; |
2514 | 2488 |
2515 bool interpolate = false; | 2489 bool interpolate = false; |
2516 Preferences::SpectrogramSmoothing smoothing = | 2490 Preferences::SpectrogramSmoothing smoothing = |
2517 Preferences::getInstance()->getSpectrogramSmoothing(); | 2491 Preferences::getInstance()->getSpectrogramSmoothing(); |
2518 if (smoothing == Preferences::SpectrogramInterpolated || | 2492 if (smoothing == Preferences::SpectrogramInterpolated || |
2557 #ifdef DEBUG_SPECTROGRAM_REPAINT | 2531 #ifdef DEBUG_SPECTROGRAM_REPAINT |
2558 // cerr << "sx = " << sx << endl; | 2532 // cerr << "sx = " << sx << endl; |
2559 #endif | 2533 #endif |
2560 | 2534 |
2561 if (sx < 0 || sx >= int(sourceModel->getWidth())) continue; | 2535 if (sx < 0 || sx >= int(sourceModel->getWidth())) continue; |
2562 | |
2563 if (!m_synchronous) { | |
2564 if (!sourceModel->isColumnAvailable(sx)) { | |
2565 #ifdef DEBUG_SPECTROGRAM_REPAINT | |
2566 cerr << "Met unavailable column at col " << sx << endl; | |
2567 #endif | |
2568 return false; | |
2569 } | |
2570 } | |
2571 | 2536 |
2572 MagnitudeRange mag; | 2537 MagnitudeRange mag; |
2573 | 2538 |
2574 if (sx != psx) { | 2539 if (sx != psx) { |
2575 if (fft) { | 2540 if (fft) { |
2713 unsigned char peakpix = getDisplayValue(v, peak); | 2678 unsigned char peakpix = getDisplayValue(v, peak); |
2714 | 2679 |
2715 m_drawBuffer.setPixel(x, h-y-1, peakpix); | 2680 m_drawBuffer.setPixel(x, h-y-1, peakpix); |
2716 } | 2681 } |
2717 } | 2682 } |
2718 | |
2719 return true; | |
2720 } | 2683 } |
2721 | 2684 |
2722 void | 2685 void |
2723 SpectrogramLayer::illuminateLocalFeatures(LayerGeometryProvider *v, QPainter &paint) const | 2686 SpectrogramLayer::illuminateLocalFeatures(LayerGeometryProvider *v, QPainter &paint) const |
2724 { | 2687 { |