Mercurial > hg > svgui
comparison layer/SpectrogramLayer.cpp @ 280:3c402c6052f6
* Pull peak-picker out of SpectrumLayer and into FFTModel; use combined
peak-picker and frequency estimator for SpectrogramLayer (makes the
peak frequency spectrogram a bit quicker)
* Add more information to spectrum and spectrogram crosshairs
author | Chris Cannam |
---|---|
date | Wed, 04 Jul 2007 15:29:16 +0000 |
parents | 47fe0352861e |
children | 4edaff85875d |
comparison
equal
deleted
inserted
replaced
279:47fe0352861e | 280:3c402c6052f6 |
---|---|
2069 fftSuspended = true; | 2069 fftSuspended = true; |
2070 } | 2070 } |
2071 | 2071 |
2072 MagnitudeRange mag; | 2072 MagnitudeRange mag; |
2073 | 2073 |
2074 FFTModel::PeakSet peaks; | |
2075 if (m_binDisplay == PeakFrequencies && | |
2076 s < int(fft->getWidth()) - 1) { | |
2077 peaks = fft->getPeakFrequencies(FFTModel::AllPeaks, | |
2078 s, | |
2079 minbin, maxbin - 1); | |
2080 } | |
2081 | |
2074 for (size_t q = minbin; q < maxbin; ++q) { | 2082 for (size_t q = minbin; q < maxbin; ++q) { |
2075 | 2083 |
2076 float y0 = yval[q + 1]; | 2084 float y0 = yval[q + 1]; |
2077 float y1 = yval[q]; | 2085 float y1 = yval[q]; |
2078 | 2086 |
2079 if (m_binDisplay == PeakBins || | 2087 if (m_binDisplay == PeakBins) { |
2080 m_binDisplay == PeakFrequencies) { | |
2081 if (!fft->isLocalPeak(s, q)) continue; | 2088 if (!fft->isLocalPeak(s, q)) continue; |
2082 } | 2089 } |
2090 if (m_binDisplay == PeakFrequencies) { | |
2091 if (peaks.find(q) == peaks.end()) continue; | |
2092 } | |
2083 | 2093 |
2084 if (m_threshold != 0.f && | 2094 if (m_threshold != 0.f && |
2085 !fft->isOverThreshold(s, q, m_threshold * (m_fftSize/2))) { | 2095 !fft->isOverThreshold(s, q, m_threshold * (m_fftSize/2))) { |
2086 continue; | 2096 continue; |
2087 } | 2097 } |
2088 | 2098 |
2089 float sprop = 1.0; | 2099 float sprop = 1.0; |
2090 if (s == s0i) sprop *= (s + 1) - s0; | 2100 if (s == s0i) sprop *= (s + 1) - s0; |
2091 if (s == s1i) sprop *= s1 - s; | 2101 if (s == s1i) sprop *= s1 - s; |
2092 | 2102 |
2093 if (m_binDisplay == PeakFrequencies && | 2103 if (m_binDisplay == PeakFrequencies) { |
2094 s < int(fft->getWidth()) - 1) { | |
2095 | |
2096 float f = 0; | |
2097 fft->estimateStableFrequency(s, q, f); | |
2098 | |
2099 y0 = y1 = v->getYForFrequency | 2104 y0 = y1 = v->getYForFrequency |
2100 (f, displayMinFreq, displayMaxFreq, logarithmic); | 2105 (peaks[q], displayMinFreq, displayMaxFreq, logarithmic); |
2101 } | 2106 } |
2102 | 2107 |
2103 int y0i = int(y0 + 0.001); | 2108 int y0i = int(y0 + 0.001); |
2104 int y1i = int(y1); | 2109 int y1i = int(y1); |
2105 | 2110 |
2464 QRect horizontal(0, cursorPos.y(), cursorPos.x(), 1); | 2469 QRect horizontal(0, cursorPos.y(), cursorPos.x(), 1); |
2465 extents.push_back(horizontal); | 2470 extents.push_back(horizontal); |
2466 | 2471 |
2467 int sw = getVerticalScaleWidth(v, paint); | 2472 int sw = getVerticalScaleWidth(v, paint); |
2468 | 2473 |
2469 QRect label(sw, cursorPos.y() - paint.fontMetrics().ascent() - 2, | 2474 QRect freq(sw, cursorPos.y() - paint.fontMetrics().ascent() - 2, |
2470 paint.fontMetrics().width("123456 Hz") + 2, | 2475 paint.fontMetrics().width("123456 Hz") + 2, |
2471 paint.fontMetrics().height()); | 2476 paint.fontMetrics().height()); |
2472 extents.push_back(label); | 2477 extents.push_back(freq); |
2473 | 2478 |
2474 QRect pitch(sw, cursorPos.y() + 2, | 2479 QRect pitch(sw, cursorPos.y() + 2, |
2475 paint.fontMetrics().width("C#10+50c") + 2, | 2480 paint.fontMetrics().width("C#10+50c") + 2, |
2476 paint.fontMetrics().height()); | 2481 paint.fontMetrics().height()); |
2477 extents.push_back(pitch); | 2482 extents.push_back(pitch); |
2483 | |
2484 QRect rt(cursorPos.x(), | |
2485 v->height() - paint.fontMetrics().height() - 2, | |
2486 paint.fontMetrics().width("1234.567 s"), | |
2487 paint.fontMetrics().height()); | |
2488 extents.push_back(rt); | |
2489 | |
2490 int w(paint.fontMetrics().width("1234567890") + 2); | |
2491 QRect frame(cursorPos.x() - w - 2, | |
2492 v->height() - paint.fontMetrics().height() - 2, | |
2493 w, | |
2494 paint.fontMetrics().height()); | |
2495 extents.push_back(frame); | |
2478 | 2496 |
2479 return true; | 2497 return true; |
2480 } | 2498 } |
2481 | 2499 |
2482 void | 2500 void |
2505 cursorPos.y() + paint.fontMetrics().ascent() + 2, | 2523 cursorPos.y() + paint.fontMetrics().ascent() + 2, |
2506 pitchLabel, | 2524 pitchLabel, |
2507 View::OutlinedText); | 2525 View::OutlinedText); |
2508 } | 2526 } |
2509 | 2527 |
2510 /*!!! | 2528 long frame = v->getFrameForX(cursorPos.x()); |
2511 long frame = getFrameForX(cursorPos.x()); | |
2512 RealTime rt = RealTime::frame2RealTime(frame, m_model->getSampleRate()); | 2529 RealTime rt = RealTime::frame2RealTime(frame, m_model->getSampleRate()); |
2513 QString timeLabel = rt.toText(true).c_str(); | 2530 QString rtLabel = QString("%1 s").arg(rt.toText(true).c_str()); |
2514 ... | 2531 QString frameLabel = QString("%1").arg(frame); |
2515 */ | 2532 v->drawVisibleText(paint, |
2533 cursorPos.x() - paint.fontMetrics().width(frameLabel) - 2, | |
2534 v->height() - 2, | |
2535 frameLabel, | |
2536 View::OutlinedText); | |
2537 v->drawVisibleText(paint, | |
2538 cursorPos.x() + 2, | |
2539 v->height() - 2, | |
2540 rtLabel, | |
2541 View::OutlinedText); | |
2516 | 2542 |
2517 int harmonic = 2; | 2543 int harmonic = 2; |
2518 | 2544 |
2519 while (harmonic < 100) { | 2545 while (harmonic < 100) { |
2520 | 2546 |