changeset 199:45e995ed84d9

* Flesh out feature descriptions for spectrum
author Chris Cannam
date Mon, 05 Feb 2007 16:11:49 +0000
parents c2ed5014d4ff
children 17f8d9cf60d7
files layer/SliceLayer.cpp layer/SliceLayer.h layer/SpectrogramLayer.cpp layer/SpectrumLayer.cpp layer/SpectrumLayer.h
diffstat 5 files changed, 161 insertions(+), 17 deletions(-) [+]
line wrap: on
line diff
--- a/layer/SliceLayer.cpp	Thu Feb 01 16:54:42 2007 +0000
+++ b/layer/SliceLayer.cpp	Mon Feb 05 16:11:49 2007 +0000
@@ -99,15 +99,30 @@
 QString
 SliceLayer::getFeatureDescription(View *v, QPoint &p) const
 {
+    int minbin, maxbin, range;
+    return getFeatureDescription(v, p, true, minbin, maxbin, range);
+}
+
+QString
+SliceLayer::getFeatureDescription(View *v, QPoint &p,
+                                  bool includeBinDescription,
+                                  int &minbin, int &maxbin, int &range) const
+{
+    minbin = 0;
+    maxbin = 0;
     if (!m_sliceableModel) return "";
 
     int xorigin = m_xorigins[v];
     int w = v->width() - xorigin - 1;
     
     int mh = m_sliceableModel->getHeight();
-    int bin = getBinForX(p.x() - xorigin, mh, w);
-    if (bin >= mh) bin = mh - 1;
-    if (bin < 0) bin = 0;
+    minbin = getBinForX(p.x() - xorigin, mh, w);
+    maxbin = getBinForX(p.x() - xorigin + 1, mh, w);
+
+    if (minbin >= mh) minbin = mh - 1;
+    if (maxbin >= mh) maxbin = mh - 1;
+    if (minbin < 0) minbin = 0;
+    if (maxbin < 0) maxbin = 0;
     
     int sampleRate = m_sliceableModel->getSampleRate();
 
@@ -117,21 +132,52 @@
     RealTime rt0 = RealTime::frame2RealTime(f0, sampleRate);
     RealTime rt1 = RealTime::frame2RealTime(f1, sampleRate);
     
-    size_t range = f1 - f0 + 1;
+    range = f1 - f0 + 1;
 
-    float value = 0.f;
-    if (bin < m_values.size()) value = m_values[bin];
+    if (includeBinDescription) {
 
-    QString description = tr("Time:\t%1 - %2\nRange:\t%3 samples\nBin:\t%4\n%5 value:\t%6")
-        .arg(QString::fromStdString(rt0.toText(true)))
-        .arg(QString::fromStdString(rt1.toText(true)))
-        .arg(range)
-        .arg(bin + 1)
-        .arg(m_samplingMode == NearestSample ? tr("First") :
-             m_samplingMode == SampleMean ? tr("Mean") : tr("Peak"))
-        .arg(value);
+        float minvalue = 0.f;
+        if (minbin < m_values.size()) minvalue = m_values[minbin];
 
-    return description;
+        float maxvalue = minvalue;
+        if (maxbin < m_values.size()) maxvalue = m_values[maxbin];
+        
+        if (minvalue > maxvalue) std::swap(minvalue, maxvalue);
+        
+        QString binstr;
+        if (maxbin != minbin) {
+            binstr = tr("%1 - %2").arg(minbin+1).arg(maxbin+1);
+        } else {
+            binstr = QString("%1").arg(minbin+1);
+        }
+
+        QString valuestr;
+        if (maxvalue != minvalue) {
+            valuestr = tr("%1 - %2").arg(minvalue).arg(maxvalue);
+        } else {
+            valuestr = QString("%1").arg(minvalue);
+        }
+
+        QString description = tr("Time:\t%1 - %2\nRange:\t%3 samples\nBin:\t%4\n%5 value:\t%6")
+            .arg(QString::fromStdString(rt0.toText(true)))
+            .arg(QString::fromStdString(rt1.toText(true)))
+            .arg(range)
+            .arg(binstr)
+            .arg(m_samplingMode == NearestSample ? tr("First") :
+                 m_samplingMode == SampleMean ? tr("Mean") : tr("Peak"))
+            .arg(valuestr);
+        
+        return description;
+    
+    } else {
+
+        QString description = tr("Time:\t%1 - %2\nRange:\t%3 samples")
+            .arg(QString::fromStdString(rt0.toText(true)))
+            .arg(QString::fromStdString(rt1.toText(true)))
+            .arg(range);
+        
+        return description;
+    }
 }
 
 float
--- a/layer/SliceLayer.h	Thu Feb 01 16:54:42 2007 +0000
+++ b/layer/SliceLayer.h	Mon Feb 05 16:11:49 2007 +0000
@@ -106,6 +106,11 @@
     float getXForBin(int bin, int totalBins, float w) const;
     int getBinForX(float x, int totalBins, float w) const;
     
+    virtual QString getFeatureDescription(View *v, QPoint &,
+                                          bool includeBinDescription,
+                                          int &minbin, int &maxbin,
+                                          int &range) const;
+
     const DenseThreeDimensionalModel *m_sliceableModel;
     QColor                            m_colour;
     int                               m_colourMap;
--- a/layer/SpectrogramLayer.cpp	Thu Feb 01 16:54:42 2007 +0000
+++ b/layer/SpectrogramLayer.cpp	Mon Feb 05 16:11:49 2007 +0000
@@ -2471,9 +2471,9 @@
 	    dbMaxString = QString("%1").arg(lrintf(dbMax));
 	}
 	if (lrintf(dbMin) != lrintf(dbMax)) {
-	    text += tr("dB:\t%1 - %2").arg(lrintf(dbMin)).arg(lrintf(dbMax));
+	    text += tr("dB:\t%1 - %2").arg(dbMinString).arg(dbMaxString);
 	} else {
-	    text += tr("dB:\t%1").arg(lrintf(dbMin));
+	    text += tr("dB:\t%1").arg(dbMinString);
 	}
 	if (phaseMin != phaseMax) {
 	    text += tr("\nPhase:\t%1 - %2").arg(phaseMin).arg(phaseMax);
--- a/layer/SpectrumLayer.cpp	Thu Feb 01 16:54:42 2007 +0000
+++ b/layer/SpectrumLayer.cpp	Mon Feb 05 16:11:49 2007 +0000
@@ -270,3 +270,94 @@
     return false;
 }
 
+QString
+SpectrumLayer::getFeatureDescription(View *v, QPoint &p) const
+{
+    if (!m_sliceableModel) return "";
+
+    int minbin = 0, maxbin = 0, range = 0;
+    QString genericDesc = SliceLayer::getFeatureDescription
+        (v, p, false, minbin, maxbin, range);
+
+    if (genericDesc == "") return "";
+
+    float minvalue = 0.f;
+    if (minbin < m_values.size()) minvalue = m_values[minbin];
+
+    float maxvalue = minvalue;
+    if (maxbin < m_values.size()) maxvalue = m_values[maxbin];
+        
+    if (minvalue > maxvalue) std::swap(minvalue, maxvalue);
+    
+    QString binstr;
+    QString hzstr;
+    int minfreq = lrintf((minbin * m_sliceableModel->getSampleRate()) /
+                         m_windowSize);
+    int maxfreq = lrintf((std::max(maxbin, minbin+1)
+                           * m_sliceableModel->getSampleRate()) /
+                          m_windowSize);
+
+    if (maxbin != minbin) {
+        binstr = tr("%1 - %2").arg(minbin+1).arg(maxbin+1);
+    } else {
+        binstr = QString("%1").arg(minbin+1);
+    }
+    if (minfreq != maxfreq) {
+        hzstr = tr("%1 - %2 Hz").arg(minfreq).arg(maxfreq);
+    } else {
+        hzstr = tr("%1 Hz").arg(minfreq);
+    }
+    
+    QString valuestr;
+    if (maxvalue != minvalue) {
+        valuestr = tr("%1 - %2").arg(minvalue).arg(maxvalue);
+    } else {
+        valuestr = QString("%1").arg(minvalue);
+    }
+    
+    QString dbstr;
+    float mindb = AudioLevel::multiplier_to_dB(minvalue);
+    float maxdb = AudioLevel::multiplier_to_dB(maxvalue);
+    QString mindbstr;
+    QString maxdbstr;
+    if (mindb == AudioLevel::DB_FLOOR) {
+        mindbstr = tr("-Inf");
+    } else {
+        mindbstr = QString("%1").arg(lrintf(mindb));
+    }
+    if (maxdb == AudioLevel::DB_FLOOR) {
+        maxdbstr = tr("-Inf");
+    } else {
+        maxdbstr = QString("%1").arg(lrintf(maxdb));
+    }
+    if (lrintf(mindb) != lrintf(maxdb)) {
+        dbstr = tr("%1 - %2").arg(mindbstr).arg(maxdbstr);
+    } else {
+        dbstr = tr("%1").arg(mindbstr);
+    }
+
+    QString description;
+
+    if (range > m_sliceableModel->getResolution()) {
+        description = tr("%1\nBin:\t%2 (%3)\n%4 value:\t%5\ndB:\t%6")
+            .arg(genericDesc)
+            .arg(binstr)
+            .arg(hzstr)
+            .arg(m_samplingMode == NearestSample ? tr("First") :
+                 m_samplingMode == SampleMean ? tr("Mean") : tr("Peak"))
+            .arg(valuestr)
+            .arg(dbstr);
+    } else {
+        description = tr("%1\nBin:\t%2 (%3)\nValue:\t%4\ndB:\t%5")
+            .arg(genericDesc)
+            .arg(binstr)
+            .arg(hzstr)
+            .arg(valuestr)
+            .arg(dbstr);
+    }
+    
+    return description;
+}
+
+
+    
--- a/layer/SpectrumLayer.h	Thu Feb 01 16:54:42 2007 +0000
+++ b/layer/SpectrumLayer.h	Mon Feb 05 16:11:49 2007 +0000
@@ -38,6 +38,8 @@
     void setModel(DenseTimeValueModel *model);
     virtual const Model *getModel() const { return m_originModel; }
 
+    virtual QString getFeatureDescription(View *v, QPoint &) const;
+
     virtual PropertyList getProperties() const;
     virtual QString getPropertyLabel(const PropertyName &) const;
     virtual PropertyType getPropertyType(const PropertyName &) const;