Mercurial > hg > svgui
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 ¬e) const | 1400 FlexiNoteLayer::updateNoteValue(View *v, FlexiNoteModel::Point ¬e) 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 { |