changeset 655:c572a0705223 tonioni

funky note value re-estimation using underlying pitch median value
author gyorgyf
date Wed, 19 Jun 2013 08:26:24 +0100
parents f215fba963aa
children 902c7c9d77ea
files layer/FlexiNoteLayer.cpp layer/FlexiNoteLayer.h
diffstat 2 files changed, 45 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/layer/FlexiNoteLayer.cpp	Tue Jun 18 22:18:10 2013 +0100
+++ b/layer/FlexiNoteLayer.cpp	Wed Jun 19 08:26:24 2013 +0100
@@ -16,6 +16,7 @@
 #include "FlexiNoteLayer.h"
 
 #include "data/model/Model.h"
+#include "data/model/SparseTimeValueModel.h"
 #include "base/RealTime.h"
 #include "base/Profiler.h"
 #include "base/Pitch.h"
@@ -37,7 +38,9 @@
 #include <iostream>
 #include <cmath>
 #include <utility>
-#include <limits>
+#include <limits> // GF: included to compile std::numerical_limits on linux
+#include <vector>
+
 
 FlexiNoteLayer::FlexiNoteLayer() :
     SingleColourLayer(),
@@ -1129,6 +1132,9 @@
                        note.duration - newNote1.duration, 
                        note.level, note.label);
 
+    updateNoteValue(v,newNote1);
+    updateNoteValue(v,newNote2);
+
     FlexiNoteModel::EditCommand *command = new FlexiNoteModel::EditCommand
         (m_model, tr("Edit Point"));
     command->deletePoint(note);
@@ -1142,6 +1148,43 @@
     
 }
 
+void
+FlexiNoteLayer::updateNoteValue(View *v, FlexiNoteModel::Point &note) const
+{
+    //GF: update the note value conforming the median of pitch values in the underlying note layer
+    Layer *layer = v->getLayer(1); // GF: !!! gross assumption about correct layer order
+    SparseTimeValueModel *model = 0;
+    if (layer && layer->getModel()) 
+        model = dynamic_cast<SparseTimeValueModel *>(layer->getModel());
+        
+    if (!model) return;
+        
+    std::cerr << model->getTypeName() << std::endl;
+
+    SparseModel<TimeValuePoint>::PointList dataPoints = model->getPoints(note.frame, note.frame + note.duration);
+    if (dataPoints.empty()) return;
+   
+   // std::cerr << "frame " << note.frame << ": " << dataPoints.size() << " candidate points" << std::endl;
+   
+   std::vector<float> pitchValues;
+   
+    for (SparseModel<TimeValuePoint>::PointList::const_iterator i = dataPoints.begin(); 
+        i != dataPoints.end(); ++i) {
+            pitchValues.push_back((*i).value);
+    }
+    sort(pitchValues.begin(), pitchValues.end());
+    size_t size = pitchValues.size();
+    double median;
+
+    if (size % 2 == 0) {
+        median = (pitchValues[size/2 - 1] + pitchValues[size/2]) / 2;
+    } else {
+        median = pitchValues[size/2];
+    }
+    
+    note.value = median;
+}
+
 void 
 FlexiNoteLayer::mouseMoveEvent(View *v, QMouseEvent *e)
 {
--- a/layer/FlexiNoteLayer.h	Tue Jun 18 22:18:10 2013 +0100
+++ b/layer/FlexiNoteLayer.h	Wed Jun 19 08:26:24 2013 +0100
@@ -157,6 +157,7 @@
     bool getPointToDrag(View *v, int x, int y, FlexiNoteModel::Point &) const;
     bool getNoteToEdit(View *v, int x, int y, FlexiNoteModel::Point &) const;
     void getRelativeMousePosition(View *v, FlexiNoteModel::Point &note, int x, int y, bool &closeToLeft, bool &closeToRight, bool &closeToTop, bool &closeToBottom) const;
+    void updateNoteValue(View *v, FlexiNoteModel::Point &note) const;
 
     FlexiNoteModel *m_model;
     bool m_editing;