comparison layer/SpectrumLayer.cpp @ 1382:2df1af7ac752 spectrogramparam

Add oversampling option to spectrum as well
author Chris Cannam
date Wed, 07 Nov 2018 11:37:51 +0000
parents d79e21855aef
children 37e9d6a1e00c
comparison
equal deleted inserted replaced
1381:2f4476993ae6 1382:2df1af7ac752
37 m_channel(-1), 37 m_channel(-1),
38 m_channelSet(false), 38 m_channelSet(false),
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_showPeaks(false), 43 m_showPeaks(false),
43 m_newFFTNeeded(true) 44 m_newFFTNeeded(true)
44 { 45 {
45 Preferences *prefs = Preferences::getInstance(); 46 Preferences *prefs = Preferences::getInstance();
46 connect(prefs, SIGNAL(propertyChanged(PropertyContainer::PropertyName)), 47 connect(prefs, SIGNAL(propertyChanged(PropertyContainer::PropertyName)),
110 111
111 if (!m_originModel) { 112 if (!m_originModel) {
112 return; 113 return;
113 } 114 }
114 115
116 int fftSize = getFFTSize();
117
115 FFTModel *newFFT = new FFTModel(m_originModel, 118 FFTModel *newFFT = new FFTModel(m_originModel,
116 m_channel, 119 m_channel,
117 m_windowType, 120 m_windowType,
118 m_windowSize, 121 m_windowSize,
119 getWindowIncrement(), 122 getWindowIncrement(),
120 m_windowSize); 123 fftSize);
121 124
122 setSliceableModel(newFFT); 125 setSliceableModel(newFFT);
123 126
124 m_biasCurve.clear(); 127 m_biasCurve.clear();
125 for (int i = 0; i < m_windowSize; ++i) { 128 for (int i = 0; i < fftSize; ++i) {
126 m_biasCurve.push_back(1.f / (float(m_windowSize)/2.f)); 129 m_biasCurve.push_back(1.f / (float(fftSize)/2.f));
127 } 130 }
128 131
129 m_newFFTNeeded = false; 132 m_newFFTNeeded = false;
130 } 133 }
131 134
133 SpectrumLayer::getProperties() const 136 SpectrumLayer::getProperties() const
134 { 137 {
135 PropertyList list = SliceLayer::getProperties(); 138 PropertyList list = SliceLayer::getProperties();
136 list.push_back("Window Size"); 139 list.push_back("Window Size");
137 list.push_back("Window Increment"); 140 list.push_back("Window Increment");
141 list.push_back("Oversampling");
138 list.push_back("Show Peak Frequencies"); 142 list.push_back("Show Peak Frequencies");
139 return list; 143 return list;
140 } 144 }
141 145
142 QString 146 QString
143 SpectrumLayer::getPropertyLabel(const PropertyName &name) const 147 SpectrumLayer::getPropertyLabel(const PropertyName &name) const
144 { 148 {
145 if (name == "Window Size") return tr("Window Size"); 149 if (name == "Window Size") return tr("Window Size");
146 if (name == "Window Increment") return tr("Window Overlap"); 150 if (name == "Window Increment") return tr("Window Overlap");
151 if (name == "Oversampling") return tr("Oversampling");
147 if (name == "Show Peak Frequencies") return tr("Show Peak Frequencies"); 152 if (name == "Show Peak Frequencies") return tr("Show Peak Frequencies");
148 return SliceLayer::getPropertyLabel(name); 153 return SliceLayer::getPropertyLabel(name);
149 } 154 }
150 155
151 QString 156 QString
158 Layer::PropertyType 163 Layer::PropertyType
159 SpectrumLayer::getPropertyType(const PropertyName &name) const 164 SpectrumLayer::getPropertyType(const PropertyName &name) const
160 { 165 {
161 if (name == "Window Size") return ValueProperty; 166 if (name == "Window Size") return ValueProperty;
162 if (name == "Window Increment") return ValueProperty; 167 if (name == "Window Increment") return ValueProperty;
168 if (name == "Oversampling") return ValueProperty;
163 if (name == "Show Peak Frequencies") return ToggleProperty; 169 if (name == "Show Peak Frequencies") return ToggleProperty;
164 return SliceLayer::getPropertyType(name); 170 return SliceLayer::getPropertyType(name);
165 } 171 }
166 172
167 QString 173 QString
168 SpectrumLayer::getPropertyGroupName(const PropertyName &name) const 174 SpectrumLayer::getPropertyGroupName(const PropertyName &name) const
169 { 175 {
170 if (name == "Window Size" || 176 if (name == "Window Size" ||
171 name == "Window Increment") return tr("Window"); 177 name == "Window Increment" ||
178 name == "Oversampling") return tr("Window");
172 if (name == "Show Peak Frequencies") return tr("Bins"); 179 if (name == "Show Peak Frequencies") return tr("Bins");
173 return SliceLayer::getPropertyGroupName(name); 180 return SliceLayer::getPropertyGroupName(name);
174 } 181 }
175 182
176 int 183 int
200 *max = 5; 207 *max = 5;
201 *deflt = 2; 208 *deflt = 2;
202 209
203 val = m_windowHopLevel; 210 val = m_windowHopLevel;
204 211
212 } else if (name == "Oversampling") {
213
214 *min = 0;
215 *max = 3;
216 *deflt = 0;
217
218 val = 0;
219 int ov = m_oversampling;
220 while (ov > 1) { ov >>= 1; val ++; }
221
205 } else if (name == "Show Peak Frequencies") { 222 } else if (name == "Show Peak Frequencies") {
206 223
207 return m_showPeaks ? 1 : 0; 224 return m_showPeaks ? 1 : 0;
208 225
209 } else { 226 } else {
230 case 3: return tr("75 %"); 247 case 3: return tr("75 %");
231 case 4: return tr("87.5 %"); 248 case 4: return tr("87.5 %");
232 case 5: return tr("93.75 %"); 249 case 5: return tr("93.75 %");
233 } 250 }
234 } 251 }
252 if (name == "Oversampling") {
253 switch (value) {
254 default:
255 case 0: return tr("1x");
256 case 1: return tr("2x");
257 case 2: return tr("4x");
258 case 3: return tr("8x");
259 }
260 }
235 return SliceLayer::getPropertyValueLabel(name, value); 261 return SliceLayer::getPropertyValueLabel(name, value);
236 } 262 }
237 263
238 RangeMapper * 264 RangeMapper *
239 SpectrumLayer::getNewPropertyRangeMapper(const PropertyName &name) const 265 SpectrumLayer::getNewPropertyRangeMapper(const PropertyName &name) const
246 { 272 {
247 if (name == "Window Size") { 273 if (name == "Window Size") {
248 setWindowSize(32 << value); 274 setWindowSize(32 << value);
249 } else if (name == "Window Increment") { 275 } else if (name == "Window Increment") {
250 setWindowHopLevel(value); 276 setWindowHopLevel(value);
277 } else if (name == "Oversampling") {
278 setOversampling(1 << value);
251 } else if (name == "Show Peak Frequencies") { 279 } else if (name == "Show Peak Frequencies") {
252 setShowPeaks(value ? true : false); 280 setShowPeaks(value ? true : false);
253 } else { 281 } else {
254 SliceLayer::setProperty(name, value); 282 SliceLayer::setProperty(name, value);
255 } 283 }
281 m_newFFTNeeded = true; 309 m_newFFTNeeded = true;
282 emit layerParametersChanged(); 310 emit layerParametersChanged();
283 } 311 }
284 312
285 void 313 void
314 SpectrumLayer::setOversampling(int oversampling)
315 {
316 if (m_oversampling == oversampling) return;
317 m_oversampling = oversampling;
318 m_newFFTNeeded = true;
319 emit layerParametersChanged();
320 }
321
322 int
323 SpectrumLayer::getOversampling() const
324 {
325 return m_oversampling;
326 }
327
328 void
286 SpectrumLayer::setShowPeaks(bool show) 329 SpectrumLayer::setShowPeaks(bool show)
287 { 330 {
288 if (m_showPeaks == show) return; 331 if (m_showPeaks == show) return;
289 m_showPeaks = show; 332 m_showPeaks = show;
290 emit layerParametersChanged(); 333 emit layerParametersChanged();
292 335
293 void 336 void
294 SpectrumLayer::preferenceChanged(PropertyContainer::PropertyName name) 337 SpectrumLayer::preferenceChanged(PropertyContainer::PropertyName name)
295 { 338 {
296 if (name == "Window Type") { 339 if (name == "Window Type") {
297 setWindowType(Preferences::getInstance()->getWindowType()); 340 auto type = Preferences::getInstance()->getWindowType();
341 SVDEBUG << "SpectrumLayer::preferenceChanged: Window type changed to "
342 << type << endl;
343 setWindowType(type);
298 return; 344 return;
299 } 345 }
300 } 346 }
301 347
302 double 348 double
516 if (minvalue > maxvalue) std::swap(minvalue, maxvalue); 562 if (minvalue > maxvalue) std::swap(minvalue, maxvalue);
517 563
518 QString binstr; 564 QString binstr;
519 QString hzstr; 565 QString hzstr;
520 int minfreq = int(lrint((minbin * m_sliceableModel->getSampleRate()) / 566 int minfreq = int(lrint((minbin * m_sliceableModel->getSampleRate()) /
521 m_windowSize)); 567 getFFTSize()));
522 int maxfreq = int(lrint((std::max(maxbin, minbin) 568 int maxfreq = int(lrint((std::max(maxbin, minbin)
523 * m_sliceableModel->getSampleRate()) / 569 * m_sliceableModel->getSampleRate()) /
524 m_windowSize)); 570 getFFTSize()));
525 571
526 if (maxbin != minbin) { 572 if (maxbin != minbin) {
527 binstr = tr("%1 - %2").arg(minbin+1).arg(maxbin+1); 573 binstr = tr("%1 - %2").arg(minbin+1).arg(maxbin+1);
528 } else { 574 } else {
529 binstr = QString("%1").arg(minbin+1); 575 binstr = QString("%1").arg(minbin+1);
600 } 646 }
601 647
602 FFTModel *fft = dynamic_cast<FFTModel *> 648 FFTModel *fft = dynamic_cast<FFTModel *>
603 (const_cast<DenseThreeDimensionalModel *>(m_sliceableModel)); 649 (const_cast<DenseThreeDimensionalModel *>(m_sliceableModel));
604 650
605 double thresh = (pow(10, -6) / m_gain) * (m_windowSize / 2.0); // -60dB adj 651 double thresh = (pow(10, -6) / m_gain) * (getFFTSize() / 2.0); // -60dB adj
606 652
607 int xorigin = getVerticalScaleWidth(v, false, paint) + 1; 653 int xorigin = getVerticalScaleWidth(v, false, paint) + 1;
608 int scaleHeight = getHorizontalScaleHeight(v, paint); 654 int scaleHeight = getHorizontalScaleHeight(v, paint);
609 655
610 if (fft && m_showPeaks) { 656 if (fft && m_showPeaks) {
744 SpectrumLayer::toXml(QTextStream &stream, 790 SpectrumLayer::toXml(QTextStream &stream,
745 QString indent, QString extraAttributes) const 791 QString indent, QString extraAttributes) const
746 { 792 {
747 QString s = QString("windowSize=\"%1\" " 793 QString s = QString("windowSize=\"%1\" "
748 "windowHopLevel=\"%2\" " 794 "windowHopLevel=\"%2\" "
749 "showPeaks=\"%3\" ") 795 "oversampling=\"%3\" "
796 "showPeaks=\"%4\" ")
750 .arg(m_windowSize) 797 .arg(m_windowSize)
751 .arg(m_windowHopLevel) 798 .arg(m_windowHopLevel)
799 .arg(m_oversampling)
752 .arg(m_showPeaks ? "true" : "false"); 800 .arg(m_showPeaks ? "true" : "false");
753 801
754 SliceLayer::toXml(stream, indent, extraAttributes + " " + s); 802 SliceLayer::toXml(stream, indent, extraAttributes + " " + s);
755 } 803 }
756 804
765 if (ok) setWindowSize(windowSize); 813 if (ok) setWindowSize(windowSize);
766 814
767 int windowHopLevel = attributes.value("windowHopLevel").toUInt(&ok); 815 int windowHopLevel = attributes.value("windowHopLevel").toUInt(&ok);
768 if (ok) setWindowHopLevel(windowHopLevel); 816 if (ok) setWindowHopLevel(windowHopLevel);
769 817
818 int oversampling = attributes.value("oversampling").toUInt(&ok);
819 if (ok) setOversampling(oversampling);
820
770 bool showPeaks = (attributes.value("showPeaks").trimmed() == "true"); 821 bool showPeaks = (attributes.value("showPeaks").trimmed() == "true");
771 setShowPeaks(showPeaks); 822 setShowPeaks(showPeaks);
772 } 823 }
773 824
774 825