comparison layer/FlexiNoteLayer.cpp @ 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
comparison
equal deleted inserted replaced
654:f215fba963aa 655:c572a0705223
14 */ 14 */
15 15
16 #include "FlexiNoteLayer.h" 16 #include "FlexiNoteLayer.h"
17 17
18 #include "data/model/Model.h" 18 #include "data/model/Model.h"
19 #include "data/model/SparseTimeValueModel.h"
19 #include "base/RealTime.h" 20 #include "base/RealTime.h"
20 #include "base/Profiler.h" 21 #include "base/Profiler.h"
21 #include "base/Pitch.h" 22 #include "base/Pitch.h"
22 #include "base/LogRange.h" 23 #include "base/LogRange.h"
23 #include "base/RangeMapper.h" 24 #include "base/RangeMapper.h"
35 #include <QMessageBox> 36 #include <QMessageBox>
36 37
37 #include <iostream> 38 #include <iostream>
38 #include <cmath> 39 #include <cmath>
39 #include <utility> 40 #include <utility>
40 #include <limits> 41 #include <limits> // GF: included to compile std::numerical_limits on linux
42 #include <vector>
43
41 44
42 FlexiNoteLayer::FlexiNoteLayer() : 45 FlexiNoteLayer::FlexiNoteLayer() :
43 SingleColourLayer(), 46 SingleColourLayer(),
44 47
45 // m_model(0), 48 // m_model(0),
1127 1130
1128 FlexiNote newNote2(frame, note.value, 1131 FlexiNote newNote2(frame, note.value,
1129 note.duration - newNote1.duration, 1132 note.duration - newNote1.duration,
1130 note.level, note.label); 1133 note.level, note.label);
1131 1134
1135 updateNoteValue(v,newNote1);
1136 updateNoteValue(v,newNote2);
1137
1132 FlexiNoteModel::EditCommand *command = new FlexiNoteModel::EditCommand 1138 FlexiNoteModel::EditCommand *command = new FlexiNoteModel::EditCommand
1133 (m_model, tr("Edit Point")); 1139 (m_model, tr("Edit Point"));
1134 command->deletePoint(note); 1140 command->deletePoint(note);
1135 if ((e->modifiers() & Qt::ShiftModifier)) { 1141 if ((e->modifiers() & Qt::ShiftModifier)) {
1136 finish(command); 1142 finish(command);
1138 } 1144 }
1139 command->addPoint(newNote1); 1145 command->addPoint(newNote1);
1140 command->addPoint(newNote2); 1146 command->addPoint(newNote2);
1141 finish(command); 1147 finish(command);
1142 1148
1149 }
1150
1151 void
1152 FlexiNoteLayer::updateNoteValue(View *v, FlexiNoteModel::Point &note) const
1153 {
1154 //GF: update the note value conforming the median of pitch values in the underlying note layer
1155 Layer *layer = v->getLayer(1); // GF: !!! gross assumption about correct layer order
1156 SparseTimeValueModel *model = 0;
1157 if (layer && layer->getModel())
1158 model = dynamic_cast<SparseTimeValueModel *>(layer->getModel());
1159
1160 if (!model) return;
1161
1162 std::cerr << model->getTypeName() << std::endl;
1163
1164 SparseModel<TimeValuePoint>::PointList dataPoints = model->getPoints(note.frame, note.frame + note.duration);
1165 if (dataPoints.empty()) return;
1166
1167 // std::cerr << "frame " << note.frame << ": " << dataPoints.size() << " candidate points" << std::endl;
1168
1169 std::vector<float> pitchValues;
1170
1171 for (SparseModel<TimeValuePoint>::PointList::const_iterator i = dataPoints.begin();
1172 i != dataPoints.end(); ++i) {
1173 pitchValues.push_back((*i).value);
1174 }
1175 sort(pitchValues.begin(), pitchValues.end());
1176 size_t size = pitchValues.size();
1177 double median;
1178
1179 if (size % 2 == 0) {
1180 median = (pitchValues[size/2 - 1] + pitchValues[size/2]) / 2;
1181 } else {
1182 median = pitchValues[size/2];
1183 }
1184
1185 note.value = median;
1143 } 1186 }
1144 1187
1145 void 1188 void
1146 FlexiNoteLayer::mouseMoveEvent(View *v, QMouseEvent *e) 1189 FlexiNoteLayer::mouseMoveEvent(View *v, QMouseEvent *e)
1147 { 1190 {