Mercurial > hg > svgui
changeset 120:8dfa20f1c70a
* some work on scaling and zooming for spectrogram
author | Chris Cannam |
---|---|
date | Wed, 19 Jul 2006 16:55:29 +0000 |
parents | 508276c923ba |
children | 7363cacf7de0 |
files | layer/SpectrogramLayer.cpp layer/SpectrogramLayer.h widgets/Pane.cpp |
diffstat | 3 files changed, 149 insertions(+), 8 deletions(-) [+] |
line wrap: on
line diff
--- a/layer/SpectrogramLayer.cpp Fri Jul 14 17:12:16 2006 +0000 +++ b/layer/SpectrogramLayer.cpp Wed Jul 19 16:55:29 2006 +0000 @@ -56,6 +56,7 @@ m_frequencyScale(LinearFrequencyScale), m_binDisplay(AllBins), m_normalizeColumns(false), + m_normalizeVisibleArea(false), m_updateTimer(0), m_candidateFillStartFrame(0), m_exiting(false) @@ -125,6 +126,7 @@ list.push_back("Window Size"); list.push_back("Window Increment"); list.push_back("Normalize Columns"); + list.push_back("Normalize Visible Area"); list.push_back("Bin Display"); list.push_back("Threshold"); list.push_back("Gain"); @@ -145,6 +147,7 @@ if (name == "Window Size") return tr("Window Size"); if (name == "Window Increment") return tr("Window Overlap"); if (name == "Normalize Columns") return tr("Normalize Columns"); + if (name == "Normalize Visible Area") return tr("Normalize Visible Area"); if (name == "Bin Display") return tr("Bin Display"); if (name == "Threshold") return tr("Threshold"); if (name == "Gain") return tr("Gain"); @@ -162,6 +165,7 @@ if (name == "Gain") return RangeProperty; if (name == "Colour Rotation") return RangeProperty; if (name == "Normalize Columns") return ToggleProperty; + if (name == "Normalize Visible Area") return ToggleProperty; if (name == "Threshold") return RangeProperty; if (name == "Zero Padding") return ToggleProperty; return ValueProperty; @@ -179,6 +183,7 @@ name == "Threshold" || name == "Colour Rotation") return tr("Colour"); if (name == "Normalize Columns" || + name == "Normalize Visible Area" || name == "Bin Display" || name == "Colour Scale") return tr("Scale"); if (name == "Max Frequency" || @@ -319,6 +324,10 @@ deft = (m_normalizeColumns ? 1 : 0); + } else if (name == "Normalize Visible Area") { + + deft = (m_normalizeVisibleArea ? 1 : 0); + } else { deft = Layer::getPropertyRangeAndValue(name, min, max); } @@ -511,6 +520,8 @@ } } else if (name == "Normalize Columns") { setNormalizeColumns(value ? true : false); + } else if (name == "Normalize Visible Area") { + setNormalizeVisibleArea(value ? true : false); } } @@ -823,6 +834,24 @@ } void +SpectrogramLayer::setNormalizeVisibleArea(bool n) +{ + if (m_normalizeVisibleArea == n) return; + + invalidatePixmapCaches(); + invalidateMagnitudes(); + m_normalizeVisibleArea = n; + + emit layerParametersChanged(); +} + +bool +SpectrogramLayer::getNormalizeVisibleArea() const +{ + return m_normalizeVisibleArea; +} + +void SpectrogramLayer::setLayerDormant(const View *v, bool dormant) { if (dormant == m_dormancy[v]) return; @@ -1066,9 +1095,19 @@ { int value; - //!!! for the moment we're always normalizing visible area - float min = m_viewMags[v].getMin(); - float max = m_viewMags[v].getMax(); + float min = 0.f; + float max = 1.f; + + if (m_normalizeVisibleArea) { + min = m_viewMags[v].getMin(); + max = m_viewMags[v].getMax(); + } else if (!m_normalizeColumns) { + if (m_colourScale == LinearColourScale || + m_colourScale == MeterColourScale) { + max = 0.1f; + } + } + float thresh = -80.f; if (max == 0.f) max = 1.f; @@ -1144,6 +1183,8 @@ int value = uc; float input; + //!!! incorrect for normalizing visible area (and also out of date) + switch (m_colourScale) { default: @@ -1996,7 +2037,7 @@ cachePainter.drawImage(x0, y0, m_drawBuffer, 0, 0, w, h); cachePainter.end(); - if (!overallMagChanged) { + if (!m_normalizeVisibleArea || !overallMagChanged) { cache.startFrame = startFrame; cache.zoomLevel = zoomLevel; @@ -2030,6 +2071,38 @@ v->update(); } + QPoint localPos; + + if (v->shouldIlluminateLocalFeatures(this, localPos)) { + + std::cerr << "SpectrogramLayer: shouldIlluminateLocalFeatures(" + << localPos.x() << "," << localPos.y() << ")" << std::endl; + + float s0, s1; + float q0, q1; + + if (getXBinRange(v, localPos.x(), s0, s1) && + getYBinRange(v, localPos.y(), q0, q1)) { + + int s0i = int(s0 + 0.001); + int s1i = int(s1); + + int q0i = int(q0 + 0.001); + int q1i = int(q1); + + int x0 = v->getXForFrame(s0i * getWindowIncrement()); + int x1 = v->getXForFrame(s1i * getWindowIncrement() + 1); + int y1 = yval[q0i]; + int y0 = yval[q1i + 1]; + + std::cerr << "SpectrogramLayer::paint: illuminate " + << x0 << "," << y1 << " -> " << x1 << "," << y0 << std::endl; + + paint.setPen(Qt::white); + paint.drawRect(x0, y1, x1 - x0 + 1, y0 - y1 + 1); + } + } + #ifdef DEBUG_SPECTROGRAM_REPAINT std::cerr << "SpectrogramLayer::paint() returning" << std::endl; #endif @@ -2084,6 +2157,29 @@ } bool +SpectrogramLayer::setDisplayExtents(float min, float max) +{ + if (!m_model) return false; + if (min < 0) min = 0; + if (max > m_model->getSampleRate()/2) max = m_model->getSampleRate()/2; + + size_t minf = lrintf(min); + size_t maxf = lrintf(max); + + if (m_minFrequency == minf && m_maxFrequency == maxf) return true; + + invalidatePixmapCaches(); + invalidateMagnitudes(); + + m_minFrequency = minf; + m_maxFrequency = maxf; + + emit layerParametersChanged(); + + return true; +} + +bool SpectrogramLayer::snapToFeatureFrame(View *v, int &frame, size_t &resolution, SnapType snap) const @@ -2329,6 +2425,8 @@ return; } + //!!! cache this? + int h = rect.height(), w = rect.width(); int tickw = (m_frequencyScale == LogFrequencyScale ? 10 : 4); @@ -2393,12 +2491,12 @@ float dBmin = AudioLevel::multiplier_to_dB(min); float dBmax = AudioLevel::multiplier_to_dB(max); - if (dBmin < -80.f) dBmin = -80.f; + if (dBmax < -60.f) dBmax = -60.f; + else top = QString("%1").arg(lrintf(dBmax)); + + if (dBmin < dBmax - 60.f) dBmin = dBmax - 60.f; bottom = QString("%1").arg(lrintf(dBmin)); - if (dBmax < -80.f) dBmax = -80.f; - else top = QString("%1").arg(lrintf(dBmax)); - //!!! & phase etc if (m_colourScale != PhaseColourScale) { @@ -2448,6 +2546,7 @@ lasty = y; lastdb = idb; } else if (i < ch - paint.fontMetrics().ascent() && + idb != lastdb && ((abs(y - lasty) > textHeight && idb % 10 == 0) || (abs(y - lasty) > paint.fontMetrics().ascent() &&
--- a/layer/SpectrogramLayer.h Fri Jul 14 17:12:16 2006 +0000 +++ b/layer/SpectrogramLayer.h Wed Jul 19 16:55:29 2006 +0000 @@ -166,6 +166,9 @@ void setNormalizeColumns(bool n); bool getNormalizeColumns() const; + void setNormalizeVisibleArea(bool n); + bool getNormalizeVisibleArea() const; + enum ColourScheme { DefaultColours, WhiteOnBlack, BlackOnWhite, RedOnBlue, YellowOnBlack, BlueOnBlack, Rainbow }; @@ -194,6 +197,8 @@ virtual bool getDisplayExtents(float &min, float &max) const; + virtual bool setDisplayExtents(float min, float max); + virtual QString toXmlString(QString indent = "", QString extraAttributes = "") const; @@ -229,6 +234,7 @@ FrequencyScale m_frequencyScale; BinDisplay m_binDisplay; bool m_normalizeColumns; + bool m_normalizeVisibleArea; enum { NO_VALUE = 0 }; // colour index for unused pixels
--- a/widgets/Pane.cpp Fri Jul 14 17:12:16 2006 +0000 +++ b/widgets/Pane.cpp Wed Jul 19 16:55:29 2006 +0000 @@ -604,6 +604,10 @@ int x0 = std::min(m_clickPos.x(), m_mousePos.x()); int x1 = std::max(m_clickPos.x(), m_mousePos.x()); int w = x1 - x0; + + int y0 = std::min(m_clickPos.y(), m_mousePos.y()); + int y1 = std::max(m_clickPos.y(), m_mousePos.y()); +// int h = y1 - y0; long newStartFrame = getFrameForX(x0); @@ -625,6 +629,38 @@ setZoomLevel(getZoomConstraintBlockSize(newZoomLevel)); setStartFrame(newStartFrame); + //!!! lots of faff, shouldn't be here + + QString unit; + float min, max; + bool log; + Layer *layer = 0; + for (LayerList::const_iterator i = m_layers.begin(); + i != m_layers.end(); ++i) { + if ((*i)->getValueExtents(min, max, log, unit) && + (*i)->getDisplayExtents(min, max)) { + layer = *i; + break; + } + } + + if (layer) { + if (log) { + min = (min < 0.0) ? -log10f(-min) : (min == 0.0) ? 0.0 : log10f(min); + max = (max < 0.0) ? -log10f(-max) : (max == 0.0) ? 0.0 : log10f(max); + } + float rmin = min + ((max - min) * (height() - y1)) / height(); + float rmax = min + ((max - min) * (height() - y0)) / height(); + std::cerr << "min: " << min << ", max: " << max << ", y0: " << y0 << ", y1: " << y1 << ", h: " << height() << ", rmin: " << rmin << ", rmax: " << rmax << std::endl; + if (log) { + rmin = powf(10, rmin); + rmax = powf(10, rmax); + } + std::cerr << "finally: rmin: " << rmin << ", rmax: " << rmax << " " << unit.toStdString() << std::endl; + + layer->setDisplayExtents(rmin, rmax); + } + //cerr << "mouseReleaseEvent: start frame now " << m_startFrame << endl; // update(); }