comparison layer/FlexiNoteLayer.cpp @ 746:8d5df70b5ed7 tonioni

Add command to snap notes back to pitch track median on request; add split at selection boundaries
author Chris Cannam
date Thu, 27 Mar 2014 15:59:46 +0000
parents d50f91fe374e
children bc049f1f080e
comparison
equal deleted inserted replaced
745:d50f91fe374e 746:8d5df70b5ed7
1212 if (xdist != 0 || ydist != 0) { 1212 if (xdist != 0 || ydist != 0) {
1213 std::cerr << "mouse moved" << std::endl; 1213 std::cerr << "mouse moved" << std::endl;
1214 return; 1214 return;
1215 } 1215 }
1216 1216
1217 // MM: simpler declaration
1218 FlexiNote note(0);
1219 if (!getPointToDrag(v, e->x(), e->y(), note)) return;
1220
1221 long frame = v->getFrameForX(e->x()); 1217 long frame = v->getFrameForX(e->x());
1218
1219 splitNotesAt(v, frame);
1220 }
1221
1222 void
1223 FlexiNoteLayer::splitNotesAt(View *v, int frame)
1224 {
1225 FlexiNoteModel::PointList onPoints = m_model->getPoints(frame);
1226 if (onPoints.empty()) return;
1227
1228 FlexiNote note(*onPoints.begin());
1222 1229
1223 int gap = 0; // MM: I prefer a gap of 0, but we can decide later 1230 int gap = 0; // MM: I prefer a gap of 0, but we can decide later
1224 1231
1225 // MM: changed this a bit, to make it slightly clearer (// GF: nice changes!) 1232 // MM: changed this a bit, to make it slightly clearer (// GF: nice changes!)
1226 FlexiNote newNote1(note.frame, note.value, 1233 FlexiNote newNote1(note.frame, note.value,
1237 } 1244 }
1238 1245
1239 FlexiNoteModel::EditCommand *command = new FlexiNoteModel::EditCommand 1246 FlexiNoteModel::EditCommand *command = new FlexiNoteModel::EditCommand
1240 (m_model, tr("Edit Point")); 1247 (m_model, tr("Edit Point"));
1241 command->deletePoint(note); 1248 command->deletePoint(note);
1249
1250 /* cc can this be the best way to delete a note?
1242 if ((e->modifiers() & Qt::ShiftModifier)) { 1251 if ((e->modifiers() & Qt::ShiftModifier)) {
1243 finish(command); 1252 finish(command);
1244 return; 1253 return;
1245 } 1254 }
1255 */
1246 command->addPoint(newNote1); 1256 command->addPoint(newNote1);
1247 command->addPoint(newNote2); 1257 command->addPoint(newNote2);
1248 finish(command); 1258 finish(command);
1249
1250 } 1259 }
1251 1260
1252 void 1261 void
1253 FlexiNoteLayer::addNote(View *v, QMouseEvent *e) 1262 FlexiNoteLayer::addNote(View *v, QMouseEvent *e)
1254 { 1263 {
1274 duration = std::min(smallestRightNeighbourFrame - frame + 1, duration); 1283 duration = std::min(smallestRightNeighbourFrame - frame + 1, duration);
1275 duration = (duration > 0) ? duration : 0; 1284 duration = (duration > 0) ? duration : 0;
1276 } 1285 }
1277 1286
1278 if (!m_intelligentActions || 1287 if (!m_intelligentActions ||
1279 m_model->getPoints(frame).empty() && duration > 0) 1288 (m_model->getPoints(frame).empty() && duration > 0)) {
1280 {
1281 FlexiNote newNote(frame, value, duration, 100, "new note"); 1289 FlexiNote newNote(frame, value, duration, 100, "new note");
1282 FlexiNoteModel::EditCommand *command = new FlexiNoteModel::EditCommand 1290 FlexiNoteModel::EditCommand *command = new FlexiNoteModel::EditCommand
1283 (m_model, tr("Add Point")); 1291 (m_model, tr("Add Point"));
1284 command->addPoint(newNote); 1292 command->addPoint(newNote);
1285 finish(command); 1293 finish(command);
1289 SparseTimeValueModel * 1297 SparseTimeValueModel *
1290 FlexiNoteLayer::getAssociatedPitchModel(View *v) const 1298 FlexiNoteLayer::getAssociatedPitchModel(View *v) const
1291 { 1299 {
1292 // Better than we used to do, but still not very satisfactory 1300 // Better than we used to do, but still not very satisfactory
1293 1301
1302 cerr << "FlexiNoteLayer::getAssociatedPitchModel()" << endl;
1303
1294 for (int i = 0; i < v->getLayerCount(); ++i) { 1304 for (int i = 0; i < v->getLayerCount(); ++i) {
1295 Layer *layer = v->getLayer(i); 1305 Layer *layer = v->getLayer(i);
1296 if (layer) { 1306 if (layer && !layer->isLayerDormant(v)) {
1307 cerr << "FlexiNoteLayer::getAssociatedPitchModel: looks like our layer is " << layer << endl;
1297 SparseTimeValueModel *model = qobject_cast<SparseTimeValueModel *> 1308 SparseTimeValueModel *model = qobject_cast<SparseTimeValueModel *>
1298 (layer->getModel()); 1309 (layer->getModel());
1310 cerr << "FlexiNoteLayer::getAssociatedPitchModel: and its model is " << model << endl;
1299 if (model && model->getScaleUnits() == "Hz") { 1311 if (model && model->getScaleUnits() == "Hz") {
1312 cerr << "FlexiNoteLayer::getAssociatedPitchModel: it's good, returning " << model << endl;
1300 return model; 1313 return model;
1301 } 1314 }
1302 } 1315 }
1303 } 1316 }
1304 return 0; 1317 return 0;
1318 }
1319
1320 void
1321 FlexiNoteLayer::snapSelectedNotesToPitchTrack(View *v, Selection s)
1322 {
1323 if (!m_model) return;
1324
1325 FlexiNoteModel::PointList points =
1326 m_model->getPoints(s.getStartFrame(), s.getEndFrame());
1327
1328 FlexiNoteModel::EditCommand *command = new FlexiNoteModel::EditCommand
1329 (m_model, tr("Snap Notes"));
1330
1331 cerr << "snapSelectedNotesToPitchTrack: selection is from " << s.getStartFrame() << " to " << s.getEndFrame() << endl;
1332
1333 for (FlexiNoteModel::PointList::iterator i = points.begin();
1334 i != points.end(); ++i) {
1335
1336 FlexiNote note(*i);
1337
1338 cerr << "snapSelectedNotesToPitchTrack: looking at note from " << note.frame << " to " << note.frame + note.duration << endl;
1339
1340 if (!s.contains(note.frame) ||
1341 !s.contains(note.frame + note.duration - 1)) {
1342 continue;
1343 }
1344
1345 FlexiNote newNote(note);
1346
1347 command->deletePoint(note);
1348
1349 updateNoteValue(v, newNote);
1350
1351 command->addPoint(newNote);
1352 }
1353
1354 finish(command);
1305 } 1355 }
1306 1356
1307 void 1357 void
1308 FlexiNoteLayer::updateNoteValue(View *v, FlexiNoteModel::Point &note) const 1358 FlexiNoteLayer::updateNoteValue(View *v, FlexiNoteModel::Point &note) const
1309 { 1359 {
1311 if (!model) return; 1361 if (!model) return;
1312 1362
1313 std::cerr << model->getTypeName() << std::endl; 1363 std::cerr << model->getTypeName() << std::endl;
1314 1364
1315 SparseModel<TimeValuePoint>::PointList dataPoints = model->getPoints(note.frame, note.frame + note.duration); 1365 SparseModel<TimeValuePoint>::PointList dataPoints = model->getPoints(note.frame, note.frame + note.duration);
1366
1367 std::cerr << "frame " << note.frame << ": " << dataPoints.size() << " candidate points" << std::endl;
1368
1316 if (dataPoints.empty()) return; 1369 if (dataPoints.empty()) return;
1317 1370
1318 // std::cerr << "frame " << note.frame << ": " << dataPoints.size() << " candidate points" << std::endl;
1319
1320 std::vector<float> pitchValues; 1371 std::vector<float> pitchValues;
1321 1372
1322 for (SparseModel<TimeValuePoint>::PointList::const_iterator i = dataPoints.begin(); 1373 for (SparseModel<TimeValuePoint>::PointList::const_iterator i = dataPoints.begin();
1323 i != dataPoints.end(); ++i) { 1374 i != dataPoints.end(); ++i) {
1324 pitchValues.push_back((*i).value); 1375 pitchValues.push_back((*i).value);