Mercurial > hg > svgui
comparison layer/SpectrumLayer.cpp @ 254:a2ae3d93c645
* bit of work on harmonic cursor in spectrum
| author | Chris Cannam |
|---|---|
| date | Mon, 11 Jun 2007 12:14:52 +0000 |
| parents | 28c8e8e3c537 |
| children | 6d113226bb4c |
comparison
equal
deleted
inserted
replaced
| 253:1b1e6947c124 | 254:a2ae3d93c645 |
|---|---|
| 19 #include "data/model/FFTModel.h" | 19 #include "data/model/FFTModel.h" |
| 20 #include "view/View.h" | 20 #include "view/View.h" |
| 21 #include "base/AudioLevel.h" | 21 #include "base/AudioLevel.h" |
| 22 #include "base/Preferences.h" | 22 #include "base/Preferences.h" |
| 23 #include "base/RangeMapper.h" | 23 #include "base/RangeMapper.h" |
| 24 #include "ColourMapper.h" | |
| 25 | |
| 26 #include <QPainter> | |
| 24 | 27 |
| 25 SpectrumLayer::SpectrumLayer() : | 28 SpectrumLayer::SpectrumLayer() : |
| 26 m_originModel(0), | 29 m_originModel(0), |
| 27 m_channel(-1), | 30 m_channel(-1), |
| 28 m_channelSet(false), | 31 m_channelSet(false), |
| 71 m_windowSize, | 74 m_windowSize, |
| 72 true); | 75 true); |
| 73 | 76 |
| 74 setSliceableModel(newFFT); | 77 setSliceableModel(newFFT); |
| 75 | 78 |
| 79 m_biasCurve.clear(); | |
| 80 for (size_t i = 0; i < m_windowSize; ++i) { | |
| 81 m_biasCurve.push_back(1.f / (float(m_windowSize)/2.f)); | |
| 82 } | |
| 83 | |
| 76 newFFT->resume(); | 84 newFFT->resume(); |
| 77 } | 85 } |
| 78 | 86 |
| 79 void | 87 void |
| 80 SpectrumLayer::setChannel(int channel) | 88 SpectrumLayer::setChannel(int channel) |
| 141 if (!deflt) deflt = &garbage2; | 149 if (!deflt) deflt = &garbage2; |
| 142 | 150 |
| 143 if (name == "Window Size") { | 151 if (name == "Window Size") { |
| 144 | 152 |
| 145 *min = 0; | 153 *min = 0; |
| 146 *max = 10; | 154 *max = 15; |
| 147 *deflt = 5; | 155 *deflt = 5; |
| 148 | 156 |
| 149 val = 0; | 157 val = 0; |
| 150 int ws = m_windowSize; | 158 int ws = m_windowSize; |
| 151 while (ws > 32) { ws >>= 1; val ++; } | 159 while (ws > 32) { ws >>= 1; val ++; } |
| 245 SpectrumLayer::getValueExtents(float &, float &, bool &, QString &) const | 253 SpectrumLayer::getValueExtents(float &, float &, bool &, QString &) const |
| 246 { | 254 { |
| 247 return false; | 255 return false; |
| 248 } | 256 } |
| 249 | 257 |
| 258 bool | |
| 259 SpectrumLayer::getCrosshairExtents(View *v, QPainter &, | |
| 260 QPoint cursorPos, | |
| 261 std::vector<QRect> &extents) const | |
| 262 { | |
| 263 QRect vertical(cursorPos.x(), cursorPos.y(), 1, v->height() - cursorPos.y()); | |
| 264 extents.push_back(vertical); | |
| 265 | |
| 266 QRect horizontal(0, cursorPos.y(), v->width(), 12); | |
| 267 extents.push_back(horizontal); | |
| 268 | |
| 269 return true; | |
| 270 } | |
| 271 | |
| 272 float | |
| 273 SpectrumLayer::getFrequencyForX(float x, float w) const | |
| 274 { | |
| 275 float freq = 0; | |
| 276 | |
| 277 int sampleRate = m_sliceableModel->getSampleRate(); | |
| 278 | |
| 279 float maxfreq = float(sampleRate) / 2; | |
| 280 | |
| 281 switch (m_binScale) { | |
| 282 | |
| 283 case LinearBins: | |
| 284 freq = ((x * maxfreq) / w); | |
| 285 break; | |
| 286 | |
| 287 case LogBins: | |
| 288 freq = powf(10.f, (x * log10f(maxfreq)) / w); | |
| 289 break; | |
| 290 | |
| 291 case InvertedLogBins: | |
| 292 freq = maxfreq - powf(10.f, ((w - x) * log10f(maxfreq)) / w); | |
| 293 break; | |
| 294 } | |
| 295 | |
| 296 return freq; | |
| 297 } | |
| 298 | |
| 299 float | |
| 300 SpectrumLayer::getXForFrequency(float freq, float w) const | |
| 301 { | |
| 302 float x = 0; | |
| 303 | |
| 304 int sampleRate = m_sliceableModel->getSampleRate(); | |
| 305 | |
| 306 float maxfreq = float(sampleRate) / 2; | |
| 307 | |
| 308 switch (m_binScale) { | |
| 309 | |
| 310 case LinearBins: | |
| 311 x = (freq * w) / maxfreq; | |
| 312 break; | |
| 313 | |
| 314 case LogBins: | |
| 315 x = (log10f(freq) * w) / log10f(maxfreq); | |
| 316 break; | |
| 317 | |
| 318 case InvertedLogBins: | |
| 319 x = (w - log10f(maxfreq - freq) * w) / log10f(maxfreq); | |
| 320 break; | |
| 321 } | |
| 322 | |
| 323 return x; | |
| 324 } | |
| 325 | |
| 326 void | |
| 327 SpectrumLayer::paintCrosshairs(View *v, QPainter &paint, | |
| 328 QPoint cursorPos) const | |
| 329 { | |
| 330 paint.save(); | |
| 331 | |
| 332 ColourMapper mapper(m_colourMap, 0, 1); | |
| 333 paint.setPen(mapper.getContrastingColour()); | |
| 334 | |
| 335 int xorigin = m_xorigins[v]; | |
| 336 int w = v->width() - xorigin - 1; | |
| 337 | |
| 338 paint.drawLine(xorigin, cursorPos.y(), v->width(), cursorPos.y()); | |
| 339 paint.drawLine(cursorPos.x(), cursorPos.y(), cursorPos.x(), v->height()); | |
| 340 | |
| 341 float fundamental = getFrequencyForX(cursorPos.x() - xorigin, w); | |
| 342 | |
| 343 int harmonic = 2; | |
| 344 | |
| 345 while (harmonic < 100) { | |
| 346 | |
| 347 float hx = lrintf(getXForFrequency(fundamental * harmonic, w)); | |
| 348 hx += xorigin; | |
| 349 | |
| 350 if (hx < xorigin || hx > v->width()) break; | |
| 351 | |
| 352 int len = 7; | |
| 353 | |
| 354 if (harmonic % 2 == 0) { | |
| 355 if (harmonic % 4 == 0) { | |
| 356 len = 12; | |
| 357 } else { | |
| 358 len = 10; | |
| 359 } | |
| 360 } | |
| 361 | |
| 362 paint.drawLine(int(hx), | |
| 363 cursorPos.y(), | |
| 364 int(hx), | |
| 365 cursorPos.y() + len); | |
| 366 | |
| 367 ++harmonic; | |
| 368 } | |
| 369 | |
| 370 paint.restore(); | |
| 371 } | |
| 372 | |
| 250 QString | 373 QString |
| 251 SpectrumLayer::getFeatureDescription(View *v, QPoint &p) const | 374 SpectrumLayer::getFeatureDescription(View *v, QPoint &p) const |
| 252 { | 375 { |
| 253 if (!m_sliceableModel) return ""; | 376 if (!m_sliceableModel) return ""; |
| 254 | 377 |
| 334 } | 457 } |
| 335 | 458 |
| 336 return description; | 459 return description; |
| 337 } | 460 } |
| 338 | 461 |
| 462 void | |
| 463 SpectrumLayer::getBiasCurve(BiasCurve &curve) const | |
| 464 { | |
| 465 curve = m_biasCurve; | |
| 466 } | |
| 339 | 467 |
| 340 QString | 468 QString |
| 341 SpectrumLayer::toXmlString(QString indent, QString extraAttributes) const | 469 SpectrumLayer::toXmlString(QString indent, QString extraAttributes) const |
| 342 { | 470 { |
| 343 QString s; | 471 QString s; |
