comparison layer/SpectrogramLayer.cpp @ 486:c860cab85904

* Finer locking in fft caches; fix displayed bin ranges in spectrogram
author Chris Cannam
date Thu, 05 Feb 2009 12:05:28 +0000
parents 3f9fddc890e0
children 6a5327c0a40f
comparison
equal deleted inserted replaced
485:3f9fddc890e0 486:c860cab85904
43 using std::cerr; 43 using std::cerr;
44 using std::endl; 44 using std::endl;
45 #include <cassert> 45 #include <cassert>
46 #include <cmath> 46 #include <cmath>
47 47
48 //#define DEBUG_SPECTROGRAM_REPAINT 1 48 #define DEBUG_SPECTROGRAM_REPAINT 1
49 49
50 SpectrogramLayer::SpectrogramLayer(Configuration config) : 50 SpectrogramLayer::SpectrogramLayer(Configuration config) :
51 m_model(0), 51 m_model(0),
52 m_channel(0), 52 m_channel(0),
53 m_windowSize(1024), 53 m_windowSize(1024),
1319 float minf = getEffectiveMinFrequency(); 1319 float minf = getEffectiveMinFrequency();
1320 float maxf = getEffectiveMaxFrequency(); 1320 float maxf = getEffectiveMaxFrequency();
1321 1321
1322 bool logarithmic = (m_frequencyScale == LogFrequencyScale); 1322 bool logarithmic = (m_frequencyScale == LogFrequencyScale);
1323 1323
1324 //!!! wrong for smoothing -- wrong fft size for fft model
1325
1326 q0 = v->getFrequencyForY(y, minf, maxf, logarithmic); 1324 q0 = v->getFrequencyForY(y, minf, maxf, logarithmic);
1327 q1 = v->getFrequencyForY(y - 1, minf, maxf, logarithmic); 1325 q1 = v->getFrequencyForY(y - 1, minf, maxf, logarithmic);
1328 1326
1329 // Now map these on to actual bins 1327 // Now map these on to actual bins, using raw FFT size (unsmoothed)
1330 1328
1331 int b0 = int((q0 * m_fftSize) / sr); 1329 int b0 = int((q0 * m_fftSize) / sr);
1332 int b1 = int((q1 * m_fftSize) / sr); 1330 int b1 = int((q1 * m_fftSize) / sr);
1331
1332 //!!! this is supposed to return fractions-of-bins, as it were, hence the floats
1333 q0 = b0;
1334 q1 = b1;
1335
1336 // q0 = (b0 * sr) / m_fftSize;
1337 // q1 = (b1 * sr) / m_fftSize;
1338
1339 return true;
1340 }
1341
1342 bool
1343 SpectrogramLayer::getSmoothedYBinRange(View *v, int y, float &q0, float &q1) const
1344 {
1345 Profiler profiler("SpectrogramLayer::getSmoothedYBinRange");
1346
1347 int h = v->height();
1348 if (y < 0 || y >= h) return false;
1349
1350 int sr = m_model->getSampleRate();
1351 float minf = getEffectiveMinFrequency();
1352 float maxf = getEffectiveMaxFrequency();
1353
1354 bool logarithmic = (m_frequencyScale == LogFrequencyScale);
1355
1356 q0 = v->getFrequencyForY(y, minf, maxf, logarithmic);
1357 q1 = v->getFrequencyForY(y - 1, minf, maxf, logarithmic);
1358
1359 // Now map these on to actual bins, using zero-padded FFT size if
1360 // appropriate
1361
1362 int b0 = int((q0 * getFFTSize(v)) / sr);
1363 int b1 = int((q1 * getFFTSize(v)) / sr);
1333 1364
1334 //!!! this is supposed to return fractions-of-bins, as it were, hence the floats 1365 //!!! this is supposed to return fractions-of-bins, as it were, hence the floats
1335 q0 = b0; 1366 q0 = b0;
1336 q1 = b1; 1367 q1 = b1;
1337 1368
1691 { 1722 {
1692 for (ViewFFTMap::iterator i = m_fftModels.begin(); 1723 for (ViewFFTMap::iterator i = m_fftModels.begin();
1693 i != m_fftModels.end(); ++i) { 1724 i != m_fftModels.end(); ++i) {
1694 delete i->second.first; 1725 delete i->second.first;
1695 } 1726 }
1727 for (PeakCacheMap::iterator i = m_peakCaches.begin();
1728 i != m_peakCaches.end(); ++i) {
1729 delete i->second;
1730 }
1696 1731
1697 m_fftModels.clear(); 1732 m_fftModels.clear();
1733 m_peakCaches.clear();
1698 1734
1699 if (m_sliceableModel) { 1735 if (m_sliceableModel) {
1700 std::cerr << "SpectrogramLayer: emitting sliceableModelReplaced(" << m_sliceableModel << ", 0)" << std::endl; 1736 std::cerr << "SpectrogramLayer: emitting sliceableModelReplaced(" << m_sliceableModel << ", 0)" << std::endl;
1701 emit sliceableModelReplaced(m_sliceableModel, 0); 1737 emit sliceableModelReplaced(m_sliceableModel, 0);
1702 m_sliceableModel = 0; 1738 m_sliceableModel = 0;
2261 2297
2262 m_drawBuffer.fill(0); 2298 m_drawBuffer.fill(0);
2263 2299
2264 for (int y = 0; y < h; ++y) { 2300 for (int y = 0; y < h; ++y) {
2265 float q0 = 0, q1 = 0; 2301 float q0 = 0, q1 = 0;
2266 if (!getYBinRange(v, h-y-1, q0, q1)) { 2302 if (!getSmoothedYBinRange(v, h-y-1, q0, q1)) {
2267 binfory[y] = -1; 2303 binfory[y] = -1;
2268 } else { 2304 } else {
2269 binfory[y] = int(q0 + 0.0001); 2305 binfory[y] = int(q0 + 0.0001);
2306 cerr << "binfory[" << y << "] = " << binfory[y] << endl;
2270 } 2307 }
2271 } 2308 }
2272 2309
2273 paintDrawBuffer(v, bufwid, h, binforx, binfory, usePeaksCache); 2310 paintDrawBuffer(v, bufwid, h, binforx, binfory, usePeaksCache);
2274 2311