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