Mercurial > hg > svgui
comparison layer/SpectrogramLayer.cpp @ 113:7a23edd831cb
* Various fft server improvements, including the ability to pick out data from
an existing fft cache at a smaller increment or larger fft size rather than
recalculating it (if appropriate)
author | Chris Cannam |
---|---|
date | Thu, 29 Jun 2006 16:16:49 +0000 |
parents | 43b1ca9647e1 |
children | 991de8783cf5 |
comparison
equal
deleted
inserted
replaced
112:43b1ca9647e1 | 113:7a23edd831cb |
---|---|
120 } | 120 } |
121 | 121 |
122 void | 122 void |
123 SpectrogramLayer::getFFTServer() | 123 SpectrogramLayer::getFFTServer() |
124 { | 124 { |
125 //!!! really want to check that params differ from previous ones | |
126 | |
127 if (m_fftServer) { | 125 if (m_fftServer) { |
128 FFTDataServer::releaseInstance(m_fftServer); | 126 FFTDataServer::releaseInstance(m_fftServer); |
129 m_fftServer = 0; | 127 m_fftServer = 0; |
130 } | 128 } |
131 | 129 |
132 if (m_model) { | 130 if (m_model) { |
133 m_fftServer = FFTDataServer::getInstance(m_model, | 131 m_fftServer = FFTDataServer::getFuzzyInstance(m_model, |
134 m_channel, | 132 m_channel, |
135 m_windowType, | 133 m_windowType, |
136 m_windowSize, | 134 m_windowSize, |
137 getWindowIncrement(), | 135 getWindowIncrement(), |
138 m_fftSize, | 136 m_fftSize, |
139 true, | 137 true, |
140 m_candidateFillStartFrame); | 138 m_candidateFillStartFrame); |
141 | 139 |
142 m_lastFillExtent = 0; | 140 m_lastFillExtent = 0; |
143 | 141 |
144 delete m_updateTimer; | 142 delete m_updateTimer; |
145 m_updateTimer = new QTimer(this); | 143 m_updateTimer = new QTimer(this); |
1288 | 1286 |
1289 float binfreq = (sr * q) / m_windowSize; | 1287 float binfreq = (sr * q) / m_windowSize; |
1290 if (q == q0i) freqMin = binfreq; | 1288 if (q == q0i) freqMin = binfreq; |
1291 if (q == q1i) freqMax = binfreq; | 1289 if (q == q1i) freqMax = binfreq; |
1292 | 1290 |
1293 if (peaksOnly && !m_fftServer->isLocalPeak(s, q)) continue; | 1291 if (peaksOnly && !isFFTLocalPeak(s, q)) continue; |
1294 | 1292 |
1295 if (!m_fftServer->isOverThreshold(s, q, m_threshold)) continue; | 1293 if (!isFFTOverThreshold(s, q, m_threshold)) continue; |
1296 | 1294 |
1297 float freq = binfreq; | 1295 float freq = binfreq; |
1298 bool steady = false; | 1296 bool steady = false; |
1299 | 1297 |
1300 if (s < int(m_fftServer->getWidth()) - 1) { | 1298 if (s < int(getFFTWidth()) - 1) { |
1301 | 1299 |
1302 freq = calculateFrequency(q, | 1300 freq = calculateFrequency(q, |
1303 windowSize, | 1301 windowSize, |
1304 windowIncrement, | 1302 windowIncrement, |
1305 sr, | 1303 sr, |
1306 m_fftServer->getPhaseAt(s, q), | 1304 getFFTPhaseAt(s, q), |
1307 m_fftServer->getPhaseAt(s+1, q), | 1305 getFFTPhaseAt(s+1, q), |
1308 steady); | 1306 steady); |
1309 | 1307 |
1310 if (!haveAdj || freq < adjFreqMin) adjFreqMin = freq; | 1308 if (!haveAdj || freq < adjFreqMin) adjFreqMin = freq; |
1311 if (!haveAdj || freq > adjFreqMax) adjFreqMax = freq; | 1309 if (!haveAdj || freq > adjFreqMax) adjFreqMax = freq; |
1312 | 1310 |
1341 | 1339 |
1342 bool rv = false; | 1340 bool rv = false; |
1343 | 1341 |
1344 if (m_fftServer) { | 1342 if (m_fftServer) { |
1345 | 1343 |
1346 int cw = m_fftServer->getWidth(); | 1344 int cw = getFFTWidth(); |
1347 int ch = m_fftServer->getHeight(); | 1345 int ch = getFFTHeight(); |
1348 | 1346 |
1349 min = 0.0; | 1347 min = 0.0; |
1350 max = 0.0; | 1348 max = 0.0; |
1351 phaseMin = 0.0; | 1349 phaseMin = 0.0; |
1352 phaseMax = 0.0; | 1350 phaseMax = 0.0; |
1356 for (int s = s0i; s <= s1i; ++s) { | 1354 for (int s = s0i; s <= s1i; ++s) { |
1357 if (s >= 0 && q >= 0 && s < cw && q < ch) { | 1355 if (s >= 0 && q >= 0 && s < cw && q < ch) { |
1358 | 1356 |
1359 float value; | 1357 float value; |
1360 | 1358 |
1361 value = m_fftServer->getPhaseAt(s, q); | 1359 value = getFFTPhaseAt(s, q); |
1362 if (!have || value < phaseMin) { phaseMin = value; } | 1360 if (!have || value < phaseMin) { phaseMin = value; } |
1363 if (!have || value > phaseMax) { phaseMax = value; } | 1361 if (!have || value > phaseMax) { phaseMax = value; } |
1364 | 1362 |
1365 value = m_fftServer->getMagnitudeAt(s, q); | 1363 value = getFFTMagnitudeAt(s, q); |
1366 if (!have || value < min) { min = value; } | 1364 if (!have || value < min) { min = value; } |
1367 if (!have || value > max) { max = value; } | 1365 if (!have || value > max) { max = value; } |
1368 | 1366 |
1369 have = true; | 1367 have = true; |
1370 } | 1368 } |
1637 if (minbin < 1) minbin = 1; | 1635 if (minbin < 1) minbin = 1; |
1638 if (minbin >= bins) minbin = bins - 1; | 1636 if (minbin >= bins) minbin = bins - 1; |
1639 } | 1637 } |
1640 | 1638 |
1641 //!!! quite wrong and won't work for layers that may be in more than one view | 1639 //!!! quite wrong and won't work for layers that may be in more than one view |
1642 if (v->height() > (bins - minbin) / (m_zeroPadLevel + 1)) { | 1640 if (v->height() / 1.5 > (bins - minbin) / (m_zeroPadLevel + 1)) { |
1643 if (m_zeroPadLevel != 3) { | 1641 if (m_zeroPadLevel != 3) { |
1642 std::cerr << v->height()/1.5 << " > " << ((bins - minbin) / (m_zeroPadLevel + 1)) << ": switching to smoothed display" << std::endl; | |
1644 ((SpectrogramLayer *)this)->setZeroPadLevel(3); | 1643 ((SpectrogramLayer *)this)->setZeroPadLevel(3); |
1645 return; | 1644 return; |
1646 } | 1645 } |
1647 } else { | 1646 } else { |
1648 if (m_zeroPadLevel != 0) { | 1647 if (m_zeroPadLevel != 0) { |
1682 } | 1681 } |
1683 | 1682 |
1684 int s0i = int(s0 + 0.001); | 1683 int s0i = int(s0 + 0.001); |
1685 int s1i = int(s1); | 1684 int s1i = int(s1); |
1686 | 1685 |
1687 if (s1i >= m_fftServer->getWidth()) { | 1686 if (s1i >= getFFTWidth()) { |
1688 if (s0i >= m_fftServer->getWidth()) { | 1687 if (s0i >= getFFTWidth()) { |
1689 continue; | 1688 continue; |
1690 } else { | 1689 } else { |
1691 s1i = s0i; | 1690 s1i = s0i; |
1692 } | 1691 } |
1693 } | 1692 } |
1694 | 1693 |
1695 for (int s = s0i; s <= s1i; ++s) { | 1694 for (int s = s0i; s <= s1i; ++s) { |
1696 | 1695 |
1697 // if (!m_fftServer->haveSetColumnAt(s)) continue; | 1696 if (!isFFTColumnReady(s)) continue; |
1698 | 1697 |
1699 for (size_t q = minbin; q < bins; ++q) { | 1698 for (size_t q = minbin; q < bins; ++q) { |
1700 | 1699 |
1701 float y0 = yval[q + 1]; | 1700 float y0 = yval[q + 1]; |
1702 float y1 = yval[q]; | 1701 float y1 = yval[q]; |
1703 | 1702 |
1704 if (m_binDisplay == PeakBins || | 1703 if (m_binDisplay == PeakBins || |
1705 m_binDisplay == PeakFrequencies) { | 1704 m_binDisplay == PeakFrequencies) { |
1706 if (!m_fftServer->isLocalPeak(s, q)) continue; | 1705 if (!isFFTLocalPeak(s, q)) continue; |
1707 } | 1706 } |
1708 | 1707 |
1709 if (!m_fftServer->isOverThreshold(s, q, m_threshold)) continue; | 1708 if (!isFFTOverThreshold(s, q, m_threshold)) continue; |
1710 | 1709 |
1711 float sprop = 1.0; | 1710 float sprop = 1.0; |
1712 if (s == s0i) sprop *= (s + 1) - s0; | 1711 if (s == s0i) sprop *= (s + 1) - s0; |
1713 if (s == s1i) sprop *= s1 - s; | 1712 if (s == s1i) sprop *= s1 - s; |
1714 | 1713 |
1715 if (m_binDisplay == PeakFrequencies && | 1714 if (m_binDisplay == PeakFrequencies && |
1716 s < int(m_fftServer->getWidth()) - 1) { | 1715 s < int(getFFTWidth()) - 1) { |
1717 | 1716 |
1718 bool steady = false; | 1717 bool steady = false; |
1719 float f = calculateFrequency(q, | 1718 float f = calculateFrequency(q, |
1720 m_windowSize, | 1719 m_windowSize, |
1721 increment, | 1720 increment, |
1722 sr, | 1721 sr, |
1723 m_fftServer->getPhaseAt(s, q), | 1722 getFFTPhaseAt(s, q), |
1724 m_fftServer->getPhaseAt(s+1, q), | 1723 getFFTPhaseAt(s+1, q), |
1725 steady); | 1724 steady); |
1726 | 1725 |
1727 y0 = y1 = v->getYForFrequency | 1726 y0 = y1 = v->getYForFrequency |
1728 (f, minFreq, maxFreq, logarithmic); | 1727 (f, minFreq, maxFreq, logarithmic); |
1729 } | 1728 } |
1732 int y1i = int(y1); | 1731 int y1i = int(y1); |
1733 | 1732 |
1734 float value; | 1733 float value; |
1735 | 1734 |
1736 if (m_colourScale == PhaseColourScale) { | 1735 if (m_colourScale == PhaseColourScale) { |
1737 value = m_fftServer->getPhaseAt(s, q); | 1736 value = getFFTPhaseAt(s, q); |
1738 } else if (m_normalizeColumns) { | 1737 } else if (m_normalizeColumns) { |
1739 value = m_fftServer->getNormalizedMagnitudeAt(s, q) * m_gain; | 1738 value = getFFTNormalizedMagnitudeAt(s, q) * m_gain; |
1740 } else { | 1739 } else { |
1741 value = m_fftServer->getMagnitudeAt(s, q) * m_gain; | 1740 value = getFFTMagnitudeAt(s, q) * m_gain; |
1742 } | 1741 } |
1743 | 1742 |
1744 for (int y = y0i; y <= y1i; ++y) { | 1743 for (int y = y0i; y <= y1i; ++y) { |
1745 | 1744 |
1746 if (y < 0 || y >= h) continue; | 1745 if (y < 0 || y >= h) continue; |