Mercurial > hg > svgui
diff layer/SpectrogramLayer.cpp @ 25:dcdb21b62dbb
* Refactor sparse models. Previously the 1D and time-value models duplicated
a lot of code; now there is a base class (SparseModel) templated on the
stored point type, and the subclasses define point types with the necessary
characteristics.
* Add NoteModel, a new SparseModel subclass.
* Reorganise local feature description display. Instead of asking the layer
to draw its own, just query it for a textual description and draw that in
Pane. Greatly simplifies this part of the layer code.
* Add local feature descriptions to colour 3D plot and waveform layers.
* Add pitch in MIDI-pitch-and-cents to spectrogram layer.
* Give AudioGenerator its own mutex to shorten lock times in CallbackPlaySource.
* Minor adjustments to layers menu &c
author | Chris Cannam |
---|---|
date | Thu, 02 Feb 2006 16:10:19 +0000 |
parents | 6b794a2af3d9 |
children | 202d1dca67d2 |
line wrap: on
line diff
--- a/layer/SpectrogramLayer.cpp Wed Feb 01 14:49:49 2006 +0000 +++ b/layer/SpectrogramLayer.cpp Thu Feb 02 16:10:19 2006 +0000 @@ -1472,8 +1472,6 @@ #ifdef DEBUG_SPECTROGRAM_REPAINT std::cerr << "SpectrogramLayer::paint() returning" << std::endl; #endif - -//!!! drawLocalFeatureDescription(paint); } int @@ -1485,141 +1483,6 @@ return completion; } -QRect -SpectrogramLayer::getFeatureDescriptionRect(QPainter &paint, QPoint pos) const -{ - if (!m_model || !m_model->isOK()) return QRect(); - - QString timeLabel = tr("Time: "); - QString freqLabel = tr("Hz: "); - QString dBLabel = tr("dB: "); - - // assume time is widest - RealTime rtMin, rtMax; - if (!getXBinSourceRange(pos.x(), rtMin, rtMax)) return QRect(); - QString timeMinText = QString("%1").arg(rtMin.toText(true).c_str()); - QString timeMaxText = QString(" - %1").arg(rtMax.toText(true).c_str()); - - QFontMetrics metrics = paint.fontMetrics(); - - int labelwidth = - std::max(std::max(metrics.width(timeLabel), - metrics.width(freqLabel)), - metrics.width(dBLabel)); - - int boxwidth = labelwidth + - metrics.width(timeMinText) + metrics.width(timeMaxText); - - int fontHeight = metrics.height(); - int boxheight = fontHeight * 3 + 4; - - return QRect(0, 0, boxwidth + 20, boxheight + 15); -} - -void -SpectrogramLayer::paintLocalFeatureDescription(QPainter &paint, - QRect rect, QPoint pos) const -{ - int x = pos.x(); - int y = pos.y(); - - if (!m_model || !m_model->isOK()) return; - - float dbMin = 0, dbMax = 0; - float freqMin = 0, freqMax = 0; - RealTime rtMin, rtMax; - - bool haveDb = false; - - if (!getXBinSourceRange(x, rtMin, rtMax)) return; - if (!getYBinSourceRange(y, freqMin, freqMax)) return; - if (getXYBinSourceRange(x, y, dbMin, dbMax)) haveDb = true; - - QString timeLabel = tr("Time: "); - QString freqLabel = tr("Hz: "); - QString dBLabel = tr("dB: "); - - QString timeMinText = QString("%1").arg(rtMin.toText(true).c_str()); - QString timeMaxText = QString(" - %1").arg(rtMax.toText(true).c_str()); - - QString freqMinText = QString("%1").arg(freqMin); - QString freqMaxText = ""; - if (freqMax != freqMin) { - freqMaxText = QString(" - %1").arg(freqMax); - } - - QString dBMinText = ""; - QString dBMaxText = ""; - - if (haveDb) { - int dbmxi = int(dbMax - 0.001); - int dbmni = int(dbMin - 0.001); - dBMinText = QString("%1").arg(dbmni); - if (dbmxi != dbmni) dBMaxText = QString(" - %1").arg(dbmxi); - } - - QFontMetrics metrics = paint.fontMetrics(); - - int labelwidth = - std::max(std::max(metrics.width(timeLabel), - metrics.width(freqLabel)), - metrics.width(dBLabel)); - - int minwidth = - std::max(std::max(metrics.width(timeMinText), - metrics.width(freqMinText)), - metrics.width(dBMinText)); - - int maxwidth = - std::max(std::max(metrics.width(timeMaxText), - metrics.width(freqMaxText)), - metrics.width(dBMaxText)); - - int boxwidth = labelwidth + minwidth + maxwidth; - - int fontAscent = metrics.ascent(); - int fontHeight = metrics.height(); - - int boxheight = fontHeight * 3 + 4; - -// paint.setPen(Qt::white); -// paint.setBrush(Qt::NoBrush); - -//!!! int xbase = m_view->width() - boxwidth - 20; - int xbase = rect.x() + 5; - int ybase = rect.y() + 5; - - paint.drawRect(xbase, ybase, boxwidth + 10, - boxheight + 10 - metrics.descent() + 1); - - paint.drawText(xbase + 5 + labelwidth - metrics.width(timeLabel), - ybase + 5 + fontAscent, timeLabel); - - paint.drawText(xbase + 5 + labelwidth - metrics.width(freqLabel), - ybase + 7 + fontAscent + fontHeight, freqLabel); - - paint.drawText(xbase + 5 + labelwidth - metrics.width(dBLabel), - ybase + 9 + fontAscent + fontHeight * 2, dBLabel); - - paint.drawText(xbase + 5 + labelwidth + minwidth - metrics.width(timeMinText), - ybase + 5 + fontAscent, timeMinText); - - paint.drawText(xbase + 5 + labelwidth + minwidth - metrics.width(freqMinText), - ybase + 7 + fontAscent + fontHeight, freqMinText); - - paint.drawText(xbase + 5 + labelwidth + minwidth - metrics.width(dBMinText), - ybase + 9 + fontAscent + fontHeight * 2, dBMinText); - - paint.drawText(xbase + 5 + labelwidth + minwidth, - ybase + 5 + fontAscent, timeMaxText); - - paint.drawText(xbase + 5 + labelwidth + minwidth, - ybase + 7 + fontAscent + fontHeight, freqMaxText); - - paint.drawText(xbase + 5 + labelwidth + minwidth, - ybase + 9 + fontAscent + fontHeight * 2, dBMaxText); -} - int SpectrogramLayer::getNearestFeatureFrame(int frame, size_t &resolution, @@ -1631,48 +1494,61 @@ return snapFrame; } -/*!!! +QString +SpectrogramLayer::getFeatureDescription(QPoint &pos) const +{ + int x = pos.x(); + int y = pos.y(); -bool -SpectrogramLayer::identifyLocalFeatures(bool on, int x, int y) -{ - return true; //!!! - - m_identify = on; - m_identifyX = x; - m_identifyY = y; - - m_view->update(); -*/ -/* - if (!m_model || !m_model->isOK()) return false; - - std::cerr << "SpectrogramLayer::identifyLocalFeatures(" << on << "," << x << "," << y << ")" << std::endl; + if (!m_model || !m_model->isOK()) return ""; float dbMin = 0, dbMax = 0; float freqMin = 0, freqMax = 0; + QString pitchMin, pitchMax; RealTime rtMin, rtMax; - if (getXBinSourceRange(x, rtMin, rtMax)) { - std::cerr << "Times: " << rtMin << " -> " << rtMax << std::endl; - } else return false; + bool haveDb = false; - if (getYBinSourceRange(y, freqMin, freqMax)) { - std::cerr << "Frequencies: " << freqMin << " -> " << freqMax << std::endl; - } else return false; + if (!getXBinSourceRange(x, rtMin, rtMax)) return ""; + if (!getYBinSourceRange(y, freqMin, freqMax)) return ""; + if (getXYBinSourceRange(x, y, dbMin, dbMax)) haveDb = true; - if (getXYBinSourceRange(x, y, dbMin, dbMax)) { - std::cerr << "dB: " << dbMin << " -> " << dbMax << std::endl; + //!!! want to actually do a one-off FFT to recalculate the dB value! + + QString text; + + if (rtMin != rtMax) { + text += tr("Time:\t%1 - %2\n") + .arg(rtMin.toText(true).c_str()) + .arg(rtMax.toText(true).c_str()); + } else { + text += tr("Time:\t%1\n") + .arg(rtMin.toText(true).c_str()); } - m_identifyX = x; - m_identifyY = y; - m_identify = true; -*/ - /*!!! - return true; + if (freqMin != freqMax) { + text += tr("Frequency:\t%1 - %2 Hz\nPitch:\t%3 - %4\n") + .arg(freqMin) + .arg(freqMax) + .arg(Pitch::getPitchLabelForFrequency(freqMin)) + .arg(Pitch::getPitchLabelForFrequency(freqMax)); + } else { + text += tr("Frequency:\t%1 Hz\nPitch:\t%2\n") + .arg(freqMin) + .arg(Pitch::getPitchLabelForFrequency(freqMin)); + } + + if (haveDb) { + if (lrintf(dbMin) != lrintf(dbMax)) { + text += tr("dB:\t%1 - %2").arg(lrintf(dbMin)).arg(lrintf(dbMax)); + } else { + text += tr("dB:\t%1").arg(lrintf(dbMin)); + } + } + + return text; } - */ + int SpectrogramLayer::getVerticalScaleWidth(QPainter &paint) const {