comparison layer/FlexiNoteLayer.cpp @ 747:bc049f1f080e tonioni

Add Merge Notes
author Chris Cannam
date Thu, 27 Mar 2014 16:30:26 +0000
parents 8d5df70b5ed7
children 84e4cf889659
comparison
equal deleted inserted replaced
746:8d5df70b5ed7 747:bc049f1f080e
1227 1227
1228 FlexiNote note(*onPoints.begin()); 1228 FlexiNote note(*onPoints.begin());
1229 1229
1230 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
1231 1231
1232 // MM: changed this a bit, to make it slightly clearer (// GF: nice changes!)
1233 FlexiNote newNote1(note.frame, note.value, 1232 FlexiNote newNote1(note.frame, note.value,
1234 frame - note.frame - gap, 1233 frame - note.frame - gap,
1235 note.level, note.label); 1234 note.level, note.label);
1236 1235
1237 FlexiNote newNote2(frame, note.value, 1236 FlexiNote newNote2(frame, note.value,
1238 note.duration - newNote1.duration, 1237 note.duration - newNote1.duration,
1239 note.level, note.label); 1238 note.level, note.label);
1240
1241 if (m_intelligentActions) {
1242 updateNoteValue(v,newNote1);
1243 updateNoteValue(v,newNote2);
1244 }
1245 1239
1246 FlexiNoteModel::EditCommand *command = new FlexiNoteModel::EditCommand 1240 FlexiNoteModel::EditCommand *command = new FlexiNoteModel::EditCommand
1247 (m_model, tr("Edit Point")); 1241 (m_model, tr("Edit Point"));
1248 command->deletePoint(note); 1242 command->deletePoint(note);
1249 1243
1250 /* cc can this be the best way to delete a note? 1244 if (m_intelligentActions) {
1251 if ((e->modifiers() & Qt::ShiftModifier)) { 1245 if (updateNoteValue(v, newNote1)) {
1252 finish(command); 1246 command->addPoint(newNote1);
1253 return; 1247 }
1254 } 1248 if (updateNoteValue(v, newNote2)) {
1255 */ 1249 command->addPoint(newNote2);
1256 command->addPoint(newNote1); 1250 }
1257 command->addPoint(newNote2); 1251 } else {
1252 command->addPoint(newNote1);
1253 command->addPoint(newNote2);
1254 }
1255
1258 finish(command); 1256 finish(command);
1259 } 1257 }
1260 1258
1261 void 1259 void
1262 FlexiNoteLayer::addNote(View *v, QMouseEvent *e) 1260 FlexiNoteLayer::addNote(View *v, QMouseEvent *e)
1344 1342
1345 FlexiNote newNote(note); 1343 FlexiNote newNote(note);
1346 1344
1347 command->deletePoint(note); 1345 command->deletePoint(note);
1348 1346
1349 updateNoteValue(v, newNote); 1347 if (updateNoteValue(v, newNote)) {
1350 1348 command->addPoint(newNote);
1351 command->addPoint(newNote); 1349 }
1352 } 1350 }
1353 1351
1354 finish(command); 1352 finish(command);
1355 } 1353 }
1356 1354
1357 void 1355 void
1356 FlexiNoteLayer::mergeNotes(View *v, Selection s)
1357 {
1358 FlexiNoteModel::PointList points =
1359 m_model->getPoints(s.getStartFrame(), s.getEndFrame());
1360
1361 FlexiNoteModel::PointList::iterator i = points.begin();
1362 while (i != points.end() && i->frame + i->duration < s.getStartFrame()) {
1363 ++i;
1364 }
1365 if (i == points.end()) return;
1366
1367 FlexiNoteModel::EditCommand *command =
1368 new FlexiNoteModel::EditCommand(m_model, tr("Merge Notes"));
1369
1370 FlexiNote newNote(*i);
1371
1372 while (i != points.end()) {
1373
1374 if (i->frame >= s.getEndFrame()) break;
1375
1376 newNote.duration = i->frame + i->duration - newNote.frame;
1377 command->deletePoint(*i);
1378
1379 ++i;
1380 }
1381
1382 updateNoteValue(v, newNote);
1383 command->addPoint(newNote);
1384 finish(command);
1385 }
1386
1387 bool
1358 FlexiNoteLayer::updateNoteValue(View *v, FlexiNoteModel::Point &note) const 1388 FlexiNoteLayer::updateNoteValue(View *v, FlexiNoteModel::Point &note) const
1359 { 1389 {
1360 SparseTimeValueModel *model = getAssociatedPitchModel(v); 1390 SparseTimeValueModel *model = getAssociatedPitchModel(v);
1361 if (!model) return; 1391 if (!model) return false;
1362 1392
1363 std::cerr << model->getTypeName() << std::endl; 1393 std::cerr << model->getTypeName() << std::endl;
1364 1394
1365 SparseModel<TimeValuePoint>::PointList dataPoints = model->getPoints(note.frame, note.frame + note.duration); 1395 SparseModel<TimeValuePoint>::PointList dataPoints =
1396 model->getPoints(note.frame, note.frame + note.duration);
1366 1397
1367 std::cerr << "frame " << note.frame << ": " << dataPoints.size() << " candidate points" << std::endl; 1398 std::cerr << "frame " << note.frame << ": " << dataPoints.size() << " candidate points" << std::endl;
1368 1399
1369 if (dataPoints.empty()) return; 1400 if (dataPoints.empty()) return false;
1370 1401
1371 std::vector<float> pitchValues; 1402 std::vector<float> pitchValues;
1372 1403
1373 for (SparseModel<TimeValuePoint>::PointList::const_iterator i = dataPoints.begin(); 1404 for (SparseModel<TimeValuePoint>::PointList::const_iterator i =
1374 i != dataPoints.end(); ++i) { 1405 dataPoints.begin(); i != dataPoints.end(); ++i) {
1375 pitchValues.push_back((*i).value); 1406 if (i->frame >= note.frame &&
1376 } 1407 i->frame < note.frame + note.duration) {
1408 pitchValues.push_back((*i).value);
1409 }
1410 }
1411
1412 if (pitchValues.empty()) return false;
1413
1377 sort(pitchValues.begin(), pitchValues.end()); 1414 sort(pitchValues.begin(), pitchValues.end());
1378 size_t size = pitchValues.size(); 1415 size_t size = pitchValues.size();
1379 double median; 1416 double median;
1380 1417
1381 if (size % 2 == 0) { 1418 if (size % 2 == 0) {
1383 } else { 1420 } else {
1384 median = pitchValues[size/2]; 1421 median = pitchValues[size/2];
1385 } 1422 }
1386 1423
1387 note.value = median; 1424 note.value = median;
1425
1426 return true;
1388 } 1427 }
1389 1428
1390 void 1429 void
1391 FlexiNoteLayer::mouseMoveEvent(View *v, QMouseEvent *e) 1430 FlexiNoteLayer::mouseMoveEvent(View *v, QMouseEvent *e)
1392 { 1431 {