comparison layer/SpectrumLayer.cpp @ 1400:decb7741d036

Different approach to x-coord calculation in slice layer - let's acknowledge that we really do have two different types of model, those whose "bins" are actually at a single value (frequency in the case of the spectrum) and those whose bins are just labels.
author Chris Cannam
date Thu, 15 Nov 2018 13:06:38 +0000
parents ba1f0234efa7
children 10e768adaee5
comparison
equal deleted inserted replaced
1399:ba1f0234efa7 1400:decb7741d036
41 m_windowHopLevel(3), 41 m_windowHopLevel(3),
42 m_oversampling(1), 42 m_oversampling(1),
43 m_showPeaks(false), 43 m_showPeaks(false),
44 m_newFFTNeeded(true) 44 m_newFFTNeeded(true)
45 { 45 {
46 m_binAlignment = BinsCentredOnScalePoints;
47
46 Preferences *prefs = Preferences::getInstance(); 48 Preferences *prefs = Preferences::getInstance();
47 connect(prefs, SIGNAL(propertyChanged(PropertyContainer::PropertyName)), 49 connect(prefs, SIGNAL(propertyChanged(PropertyContainer::PropertyName)),
48 this, SLOT(preferenceChanged(PropertyContainer::PropertyName))); 50 this, SLOT(preferenceChanged(PropertyContainer::PropertyName)));
49 setWindowType(prefs->getWindowType()); 51 setWindowType(prefs->getWindowType());
50 52
124 126
125 if (m_minbin == 0 && m_maxbin == 0) { 127 if (m_minbin == 0 && m_maxbin == 0) {
126 m_minbin = 1; 128 m_minbin = 1;
127 m_maxbin = newFFT->getHeight(); 129 m_maxbin = newFFT->getHeight();
128 } 130 }
129 131
130 setSliceableModel(newFFT); 132 setSliceableModel(newFFT);
131 133
132 m_biasCurve.clear(); 134 m_biasCurve.clear();
133 for (int i = 0; i < fftSize; ++i) { 135 for (int i = 0; i < fftSize; ++i) {
134 m_biasCurve.push_back(1.f / (float(fftSize)/2.f)); 136 m_biasCurve.push_back(1.f / (float(fftSize)/2.f));
294 if (m_windowSize == ws) return; 296 if (m_windowSize == ws) return;
295 297
296 SVDEBUG << "setWindowSize: from " << m_windowSize 298 SVDEBUG << "setWindowSize: from " << m_windowSize
297 << " to " << ws << ": updating min and max bins from " 299 << " to " << ws << ": updating min and max bins from "
298 << m_minbin << " and " << m_maxbin << " to "; 300 << m_minbin << " and " << m_maxbin << " to ";
299 301 /*
300 m_minbin = int(round((double(m_minbin) / m_windowSize) * ws)); 302 m_minbin = int(round((double(m_minbin) / m_windowSize) * ws));
303 */
301 m_maxbin = int(round((double(m_maxbin) / m_windowSize) * ws)); 304 m_maxbin = int(round((double(m_maxbin) / m_windowSize) * ws));
302 305
306 m_windowSize = ws;
307
308 int h = getFFTSize() / 2 + 1;
309 if (m_minbin > h) m_minbin = h;
310 if (m_maxbin > h) m_maxbin = h;
311
303 SVDEBUG << m_minbin << " and " << m_maxbin << endl; 312 SVDEBUG << m_minbin << " and " << m_maxbin << endl;
304 313
305 m_windowSize = ws;
306 m_newFFTNeeded = true; 314 m_newFFTNeeded = true;
307 emit layerParametersChanged(); 315 emit layerParametersChanged();
308 } 316 }
309 317
310 void 318 void
331 if (m_oversampling == oversampling) return; 339 if (m_oversampling == oversampling) return;
332 340
333 SVDEBUG << "setOversampling: from " << m_oversampling 341 SVDEBUG << "setOversampling: from " << m_oversampling
334 << " to " << oversampling << ": updating min and max bins from " 342 << " to " << oversampling << ": updating min and max bins from "
335 << m_minbin << " and " << m_maxbin << " to "; 343 << m_minbin << " and " << m_maxbin << " to ";
336 344 /*
337 m_minbin = int(round((double(m_minbin) / m_oversampling) * oversampling)); 345 m_minbin = int(round((double(m_minbin) / m_oversampling) * oversampling));
346 */
338 m_maxbin = int(round((double(m_maxbin) / m_oversampling) * oversampling)); 347 m_maxbin = int(round((double(m_maxbin) / m_oversampling) * oversampling));
339 348
349 m_oversampling = oversampling;
350
351 int h = getFFTSize() / 2 + 1;
352 if (m_minbin > h) m_minbin = h;
353 if (m_maxbin > h) m_maxbin = h;
354
340 SVDEBUG << m_minbin << " and " << m_maxbin << endl; 355 SVDEBUG << m_minbin << " and " << m_maxbin << endl;
341 356
342 m_oversampling = oversampling;
343 m_newFFTNeeded = true; 357 m_newFFTNeeded = true;
344 358
345 emit layerParametersChanged(); 359 emit layerParametersChanged();
346 } 360 }
347 361
374 double 388 double
375 SpectrumLayer::getBinForFrequency(double freq) const 389 SpectrumLayer::getBinForFrequency(double freq) const
376 { 390 {
377 if (!m_sliceableModel) return 0; 391 if (!m_sliceableModel) return 0;
378 double bin = (freq * getFFTSize()) / m_sliceableModel->getSampleRate(); 392 double bin = (freq * getFFTSize()) / m_sliceableModel->getSampleRate();
379 // we assume the frequency of a bin corresponds to the centre of
380 // its visual range
381 bin += 0.5;
382 return bin; 393 return bin;
383 } 394 }
384 395
385 double 396 double
386 SpectrumLayer::getBinForX(const LayerGeometryProvider *v, double x) const 397 SpectrumLayer::getBinForX(const LayerGeometryProvider *v, double x) const
394 SpectrumLayer::getFrequencyForX(const LayerGeometryProvider *v, double x) const 405 SpectrumLayer::getFrequencyForX(const LayerGeometryProvider *v, double x) const
395 { 406 {
396 if (!m_sliceableModel) return 0; 407 if (!m_sliceableModel) return 0;
397 408
398 double fmin = getFrequencyForBin(m_minbin); 409 double fmin = getFrequencyForBin(m_minbin);
399
400 if (m_binScale == LogBins && m_minbin == 0) {
401 // Avoid too much space going to the first bin, but do so in a
402 // way that usually avoids us shifting left/right as the
403 // window size or oversampling ratio change - i.e. base this
404 // on frequency rather than bin number unless we have a lot of
405 // very low-resolution content
406 fmin = getFrequencyForBin(0.8);
407 if (fmin > 6.0) fmin = 6.0;
408 }
409
410 double fmax = getFrequencyForBin(m_maxbin); 410 double fmax = getFrequencyForBin(m_maxbin);
411 411
412 double freq = getScalePointForX(v, x, fmin, fmax); 412 double freq = getScalePointForX(v, x, fmin, fmax);
413 return freq; 413 return freq;
414 } 414 }
415 415
416 double 416 double
417 SpectrumLayer::getFrequencyForBin(double bin) const 417 SpectrumLayer::getFrequencyForBin(double bin) const
418 { 418 {
419 if (!m_sliceableModel) return 0; 419 if (!m_sliceableModel) return 0;
420 // we assume the frequency of a bin corresponds to the centre of
421 // its visual range
422 bin -= 0.5;
423 double freq = (bin * m_sliceableModel->getSampleRate()) / getFFTSize(); 420 double freq = (bin * m_sliceableModel->getSampleRate()) / getFFTSize();
424 return freq; 421 return freq;
425 } 422 }
426 423
427 double 424 double
436 SpectrumLayer::getXForFrequency(const LayerGeometryProvider *v, double freq) const 433 SpectrumLayer::getXForFrequency(const LayerGeometryProvider *v, double freq) const
437 { 434 {
438 if (!m_sliceableModel) return 0; 435 if (!m_sliceableModel) return 0;
439 436
440 double fmin = getFrequencyForBin(m_minbin); 437 double fmin = getFrequencyForBin(m_minbin);
441
442 if (m_binScale == LogBins && m_minbin == 0) {
443 // See comment in getFrequencyForX above
444 fmin = getFrequencyForBin(0.8);
445 if (fmin > 6.0) fmin = 6.0;
446 }
447
448 double fmax = getFrequencyForBin(m_maxbin); 438 double fmax = getFrequencyForBin(m_maxbin);
449 double x = getXForScalePoint(v, freq, fmin, fmax); 439 double x = getXForScalePoint(v, freq, fmin, fmax);
450 440
451 return x; 441 return x;
452 } 442 }