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;