comparison layer/SpectrumLayer.cpp @ 1403:10e768adaee5

Retain consistent min freq (rather than min bin no) when changing fft parameters in spectrum; scale ffts by window size rather than fft size in case of oversampling, to avoid fading out because of scale factor including zero padding
author Chris Cannam
date Thu, 15 Nov 2018 15:08:08 +0000
parents decb7741d036
children c8a6fd3f9dff
comparison
equal deleted inserted replaced
1402:b0eeec95ab5b 1403:10e768adaee5
39 m_windowSize(4096), 39 m_windowSize(4096),
40 m_windowType(HanningWindow), 40 m_windowType(HanningWindow),
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 m_freqOfMinBin(0.0)
45 { 46 {
46 m_binAlignment = BinsCentredOnScalePoints; 47 m_binAlignment = BinsCentredOnScalePoints;
47 48
48 Preferences *prefs = Preferences::getInstance(); 49 Preferences *prefs = Preferences::getInstance();
49 connect(prefs, SIGNAL(propertyChanged(PropertyContainer::PropertyName)), 50 connect(prefs, SIGNAL(propertyChanged(PropertyContainer::PropertyName)),
124 getWindowIncrement(), 125 getWindowIncrement(),
125 fftSize); 126 fftSize);
126 127
127 if (m_minbin == 0 && m_maxbin == 0) { 128 if (m_minbin == 0 && m_maxbin == 0) {
128 m_minbin = 1; 129 m_minbin = 1;
130 m_freqOfMinBin = double(m_minbin * newFFT->getSampleRate())
131 / getFFTSize();
129 m_maxbin = newFFT->getHeight(); 132 m_maxbin = newFFT->getHeight();
130 } 133 }
131 134
132 setSliceableModel(newFFT); 135 setSliceableModel(newFFT);
133 136
134 m_biasCurve.clear(); 137 m_biasCurve.clear();
135 for (int i = 0; i < fftSize; ++i) { 138 for (int i = 0; i < fftSize; ++i) {
136 m_biasCurve.push_back(1.f / (float(fftSize)/2.f)); 139 // Scale by the window size, not the FFT size, because we
140 // don't want to scale down by all the zero bins
141 m_biasCurve.push_back(1.f / (float(m_windowSize)/2.f));
137 } 142 }
138 143
139 m_newFFTNeeded = false; 144 m_newFFTNeeded = false;
140 } 145 }
141 146
296 if (m_windowSize == ws) return; 301 if (m_windowSize == ws) return;
297 302
298 SVDEBUG << "setWindowSize: from " << m_windowSize 303 SVDEBUG << "setWindowSize: from " << m_windowSize
299 << " to " << ws << ": updating min and max bins from " 304 << " to " << ws << ": updating min and max bins from "
300 << m_minbin << " and " << m_maxbin << " to "; 305 << m_minbin << " and " << m_maxbin << " to ";
301 /* 306
302 m_minbin = int(round((double(m_minbin) / m_windowSize) * ws)); 307 int previousWs = m_windowSize;
303 */
304 m_maxbin = int(round((double(m_maxbin) / m_windowSize) * ws));
305
306 m_windowSize = ws; 308 m_windowSize = ws;
309
310 m_minbin = int(round(getBinForFrequency(m_freqOfMinBin)));
311 m_maxbin = int(round((double(m_maxbin) / previousWs) * m_windowSize));
307 312
308 int h = getFFTSize() / 2 + 1; 313 int h = getFFTSize() / 2 + 1;
309 if (m_minbin > h) m_minbin = h; 314 if (m_minbin > h) m_minbin = h;
310 if (m_maxbin > h) m_maxbin = h; 315 if (m_maxbin > h) m_maxbin = h;
311 316
339 if (m_oversampling == oversampling) return; 344 if (m_oversampling == oversampling) return;
340 345
341 SVDEBUG << "setOversampling: from " << m_oversampling 346 SVDEBUG << "setOversampling: from " << m_oversampling
342 << " to " << oversampling << ": updating min and max bins from " 347 << " to " << oversampling << ": updating min and max bins from "
343 << m_minbin << " and " << m_maxbin << " to "; 348 << m_minbin << " and " << m_maxbin << " to ";
344 /* 349
345 m_minbin = int(round((double(m_minbin) / m_oversampling) * oversampling)); 350 int previousOversampling = m_oversampling;
346 */
347 m_maxbin = int(round((double(m_maxbin) / m_oversampling) * oversampling));
348
349 m_oversampling = oversampling; 351 m_oversampling = oversampling;
352
353 m_minbin = int(round(getBinForFrequency(m_freqOfMinBin)));
354 m_maxbin = int(round((double(m_maxbin) / previousOversampling) *
355 m_oversampling));
350 356
351 int h = getFFTSize() / 2 + 1; 357 int h = getFFTSize() / 2 + 1;
352 if (m_minbin > h) m_minbin = h; 358 if (m_minbin > h) m_minbin = h;
353 if (m_maxbin > h) m_maxbin = h; 359 if (m_maxbin > h) m_maxbin = h;
354 360
355 SVDEBUG << m_minbin << " and " << m_maxbin << endl; 361 SVDEBUG << m_minbin << " and " << m_maxbin << endl;
356 362
357 m_newFFTNeeded = true; 363 m_newFFTNeeded = true;
358
359 emit layerParametersChanged(); 364 emit layerParametersChanged();
360 } 365 }
361 366
362 int 367 int
363 SpectrumLayer::getOversampling() const 368 SpectrumLayer::getOversampling() const
381 SVDEBUG << "SpectrumLayer::preferenceChanged: Window type changed to " 386 SVDEBUG << "SpectrumLayer::preferenceChanged: Window type changed to "
382 << type << endl; 387 << type << endl;
383 setWindowType(type); 388 setWindowType(type);
384 return; 389 return;
385 } 390 }
391 }
392
393 bool
394 SpectrumLayer::setDisplayExtents(double min, double max)
395 {
396 bool result = SliceLayer::setDisplayExtents(min, max);
397 if (result) {
398 m_freqOfMinBin = getFrequencyForBin(m_minbin);
399 }
400 return result;
386 } 401 }
387 402
388 double 403 double
389 SpectrumLayer::getBinForFrequency(double freq) const 404 SpectrumLayer::getBinForFrequency(double freq) const
390 { 405 {