comparison layer/FlexiNoteLayer.cpp @ 754:efbb6b8f943b tony_integration

Merge from branch tonioni
author Chris Cannam
date Mon, 31 Mar 2014 13:00:42 +0100
parents 03423269a9d0
children 09e2677e34e7
comparison
equal deleted inserted replaced
744:b6dc57688c72 754:efbb6b8f943b
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());
1222 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());
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!)
1226 FlexiNote newNote1(note.frame, note.value, 1232 FlexiNote newNote1(note.frame, note.value,
1227 frame - note.frame - gap, 1233 frame - note.frame - gap,
1228 note.level, note.label); 1234 note.level, note.label);
1229 1235
1230 FlexiNote newNote2(frame, note.value, 1236 FlexiNote newNote2(frame, note.value,
1231 note.duration - newNote1.duration, 1237 note.duration - newNote1.duration,
1232 note.level, note.label); 1238 note.level, note.label);
1233
1234 if (m_intelligentActions) {
1235 updateNoteValue(v,newNote1);
1236 updateNoteValue(v,newNote2);
1237 }
1238 1239
1239 FlexiNoteModel::EditCommand *command = new FlexiNoteModel::EditCommand 1240 FlexiNoteModel::EditCommand *command = new FlexiNoteModel::EditCommand
1240 (m_model, tr("Edit Point")); 1241 (m_model, tr("Edit Point"));
1241 command->deletePoint(note); 1242 command->deletePoint(note);
1242 if ((e->modifiers() & Qt::ShiftModifier)) { 1243
1243 finish(command); 1244 if (m_intelligentActions) {
1244 return; 1245 if (updateNoteValue(v, newNote1)) {
1245 } 1246 command->addPoint(newNote1);
1246 command->addPoint(newNote1); 1247 }
1247 command->addPoint(newNote2); 1248 if (updateNoteValue(v, newNote2)) {
1249 command->addPoint(newNote2);
1250 }
1251 } else {
1252 command->addPoint(newNote1);
1253 command->addPoint(newNote2);
1254 }
1255
1248 finish(command); 1256 finish(command);
1249
1250 } 1257 }
1251 1258
1252 void 1259 void
1253 FlexiNoteLayer::addNote(View *v, QMouseEvent *e) 1260 FlexiNoteLayer::addNote(View *v, QMouseEvent *e)
1254 { 1261 {
1274 duration = std::min(smallestRightNeighbourFrame - frame + 1, duration); 1281 duration = std::min(smallestRightNeighbourFrame - frame + 1, duration);
1275 duration = (duration > 0) ? duration : 0; 1282 duration = (duration > 0) ? duration : 0;
1276 } 1283 }
1277 1284
1278 if (!m_intelligentActions || 1285 if (!m_intelligentActions ||
1279 m_model->getPoints(frame).empty() && duration > 0) 1286 (m_model->getPoints(frame).empty() && duration > 0)) {
1280 {
1281 FlexiNote newNote(frame, value, duration, 100, "new note"); 1287 FlexiNote newNote(frame, value, duration, 100, "new note");
1282 FlexiNoteModel::EditCommand *command = new FlexiNoteModel::EditCommand 1288 FlexiNoteModel::EditCommand *command = new FlexiNoteModel::EditCommand
1283 (m_model, tr("Add Point")); 1289 (m_model, tr("Add Point"));
1284 command->addPoint(newNote); 1290 command->addPoint(newNote);
1285 finish(command); 1291 finish(command);
1286 } 1292 }
1287 } 1293 }
1288 1294
1289 1295 SparseTimeValueModel *
1290 void 1296 FlexiNoteLayer::getAssociatedPitchModel(View *v) const
1297 {
1298 // Better than we used to do, but still not very satisfactory
1299
1300 cerr << "FlexiNoteLayer::getAssociatedPitchModel()" << endl;
1301
1302 for (int i = 0; i < v->getLayerCount(); ++i) {
1303 Layer *layer = v->getLayer(i);
1304 if (layer && !layer->isLayerDormant(v) &&
1305 layer->getLayerPresentationName() != "candidate") {
1306 cerr << "FlexiNoteLayer::getAssociatedPitchModel: looks like our layer is " << layer << endl;
1307 SparseTimeValueModel *model = qobject_cast<SparseTimeValueModel *>
1308 (layer->getModel());
1309 cerr << "FlexiNoteLayer::getAssociatedPitchModel: and its model is " << model << endl;
1310 if (model && model->getScaleUnits() == "Hz") {
1311 cerr << "FlexiNoteLayer::getAssociatedPitchModel: it's good, returning " << model << endl;
1312 return model;
1313 }
1314 }
1315 }
1316 return 0;
1317 }
1318
1319 void
1320 FlexiNoteLayer::snapSelectedNotesToPitchTrack(View *v, Selection s)
1321 {
1322 if (!m_model) return;
1323
1324 FlexiNoteModel::PointList points =
1325 m_model->getPoints(s.getStartFrame(), s.getEndFrame());
1326
1327 FlexiNoteModel::EditCommand *command = new FlexiNoteModel::EditCommand
1328 (m_model, tr("Snap Notes"));
1329
1330 cerr << "snapSelectedNotesToPitchTrack: selection is from " << s.getStartFrame() << " to " << s.getEndFrame() << endl;
1331
1332 for (FlexiNoteModel::PointList::iterator i = points.begin();
1333 i != points.end(); ++i) {
1334
1335 FlexiNote note(*i);
1336
1337 cerr << "snapSelectedNotesToPitchTrack: looking at note from " << note.frame << " to " << note.frame + note.duration << endl;
1338
1339 if (!s.contains(note.frame) &&
1340 !s.contains(note.frame + note.duration - 1)) {
1341 continue;
1342 }
1343
1344 FlexiNote newNote(note);
1345
1346 command->deletePoint(note);
1347
1348 if (updateNoteValue(v, newNote)) {
1349 command->addPoint(newNote);
1350 }
1351 }
1352
1353 finish(command);
1354 }
1355
1356 void
1357 FlexiNoteLayer::mergeNotes(View *v, Selection s, bool inclusive)
1358 {
1359 FlexiNoteModel::PointList points =
1360 m_model->getPoints(s.getStartFrame(), s.getEndFrame());
1361
1362 FlexiNoteModel::PointList::iterator i = points.begin();
1363 if (inclusive) {
1364 while (i != points.end() && i->frame + i->duration < s.getStartFrame()) {
1365 ++i;
1366 }
1367 } else {
1368 while (i != points.end() && i->frame < s.getStartFrame()) {
1369 ++i;
1370 }
1371 }
1372
1373 if (i == points.end()) return;
1374
1375 FlexiNoteModel::EditCommand *command =
1376 new FlexiNoteModel::EditCommand(m_model, tr("Merge Notes"));
1377
1378 FlexiNote newNote(*i);
1379
1380 while (i != points.end()) {
1381
1382 if (inclusive) {
1383 if (i->frame >= s.getEndFrame()) break;
1384 } else {
1385 if (i->frame + i->duration > s.getEndFrame()) break;
1386 }
1387
1388 newNote.duration = i->frame + i->duration - newNote.frame;
1389 command->deletePoint(*i);
1390
1391 ++i;
1392 }
1393
1394 updateNoteValue(v, newNote);
1395 command->addPoint(newNote);
1396 finish(command);
1397 }
1398
1399 bool
1291 FlexiNoteLayer::updateNoteValue(View *v, FlexiNoteModel::Point &note) const 1400 FlexiNoteLayer::updateNoteValue(View *v, FlexiNoteModel::Point &note) const
1292 { 1401 {
1293 //GF: update the note value conforming the median of pitch values in the underlying note layer 1402 SparseTimeValueModel *model = getAssociatedPitchModel(v);
1294 Layer *layer = v->getLayer(1); // GF: !!! gross assumption about correct layer order 1403 if (!model) return false;
1295 SparseTimeValueModel *model = 0;
1296 if (layer && layer->getModel())
1297 model = dynamic_cast<SparseTimeValueModel *>(layer->getModel());
1298
1299 if (!model) return;
1300 1404
1301 std::cerr << model->getTypeName() << std::endl; 1405 std::cerr << model->getTypeName() << std::endl;
1302 1406
1303 SparseModel<TimeValuePoint>::PointList dataPoints = model->getPoints(note.frame, note.frame + note.duration); 1407 SparseModel<TimeValuePoint>::PointList dataPoints =
1304 if (dataPoints.empty()) return; 1408 model->getPoints(note.frame, note.frame + note.duration);
1305 1409
1306 // std::cerr << "frame " << note.frame << ": " << dataPoints.size() << " candidate points" << std::endl; 1410 std::cerr << "frame " << note.frame << ": " << dataPoints.size() << " candidate points" << std::endl;
1307 1411
1412 if (dataPoints.empty()) return false;
1413
1308 std::vector<float> pitchValues; 1414 std::vector<float> pitchValues;
1309 1415
1310 for (SparseModel<TimeValuePoint>::PointList::const_iterator i = dataPoints.begin(); 1416 for (SparseModel<TimeValuePoint>::PointList::const_iterator i =
1311 i != dataPoints.end(); ++i) { 1417 dataPoints.begin(); i != dataPoints.end(); ++i) {
1312 pitchValues.push_back((*i).value); 1418 if (i->frame >= note.frame &&
1313 } 1419 i->frame < note.frame + note.duration) {
1420 pitchValues.push_back(i->value);
1421 }
1422 }
1423
1424 if (pitchValues.empty()) return false;
1425
1314 sort(pitchValues.begin(), pitchValues.end()); 1426 sort(pitchValues.begin(), pitchValues.end());
1315 size_t size = pitchValues.size(); 1427 size_t size = pitchValues.size();
1316 double median; 1428 double median;
1317 1429
1318 if (size % 2 == 0) { 1430 if (size % 2 == 0) {
1320 } else { 1432 } else {
1321 median = pitchValues[size/2]; 1433 median = pitchValues[size/2];
1322 } 1434 }
1323 1435
1324 note.value = median; 1436 note.value = median;
1437
1438 return true;
1325 } 1439 }
1326 1440
1327 void 1441 void
1328 FlexiNoteLayer::mouseMoveEvent(View *v, QMouseEvent *e) 1442 FlexiNoteLayer::mouseMoveEvent(View *v, QMouseEvent *e)
1329 { 1443 {