Mercurial > hg > svgui
diff 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 |
line wrap: on
line diff
--- a/layer/FlexiNoteLayer.cpp Thu Mar 27 15:59:46 2014 +0000 +++ b/layer/FlexiNoteLayer.cpp Thu Mar 27 16:30:26 2014 +0000 @@ -1229,7 +1229,6 @@ int gap = 0; // MM: I prefer a gap of 0, but we can decide later - // MM: changed this a bit, to make it slightly clearer (// GF: nice changes!) FlexiNote newNote1(note.frame, note.value, frame - note.frame - gap, note.level, note.label); @@ -1237,24 +1236,23 @@ FlexiNote newNote2(frame, note.value, note.duration - newNote1.duration, note.level, note.label); - - if (m_intelligentActions) { - updateNoteValue(v,newNote1); - updateNoteValue(v,newNote2); - } FlexiNoteModel::EditCommand *command = new FlexiNoteModel::EditCommand (m_model, tr("Edit Point")); command->deletePoint(note); + + if (m_intelligentActions) { + if (updateNoteValue(v, newNote1)) { + command->addPoint(newNote1); + } + if (updateNoteValue(v, newNote2)) { + command->addPoint(newNote2); + } + } else { + command->addPoint(newNote1); + command->addPoint(newNote2); + } -/* cc can this be the best way to delete a note? - if ((e->modifiers() & Qt::ShiftModifier)) { - finish(command); - return; - } -*/ - command->addPoint(newNote1); - command->addPoint(newNote2); finish(command); } @@ -1346,34 +1344,73 @@ command->deletePoint(note); - updateNoteValue(v, newNote); - - command->addPoint(newNote); + if (updateNoteValue(v, newNote)) { + command->addPoint(newNote); + } } - + finish(command); } void +FlexiNoteLayer::mergeNotes(View *v, Selection s) +{ + FlexiNoteModel::PointList points = + m_model->getPoints(s.getStartFrame(), s.getEndFrame()); + + FlexiNoteModel::PointList::iterator i = points.begin(); + while (i != points.end() && i->frame + i->duration < s.getStartFrame()) { + ++i; + } + if (i == points.end()) return; + + FlexiNoteModel::EditCommand *command = + new FlexiNoteModel::EditCommand(m_model, tr("Merge Notes")); + + FlexiNote newNote(*i); + + while (i != points.end()) { + + if (i->frame >= s.getEndFrame()) break; + + newNote.duration = i->frame + i->duration - newNote.frame; + command->deletePoint(*i); + + ++i; + } + + updateNoteValue(v, newNote); + command->addPoint(newNote); + finish(command); +} + +bool FlexiNoteLayer::updateNoteValue(View *v, FlexiNoteModel::Point ¬e) const { SparseTimeValueModel *model = getAssociatedPitchModel(v); - if (!model) return; + if (!model) return false; std::cerr << model->getTypeName() << std::endl; - SparseModel<TimeValuePoint>::PointList dataPoints = model->getPoints(note.frame, note.frame + note.duration); + SparseModel<TimeValuePoint>::PointList dataPoints = + model->getPoints(note.frame, note.frame + note.duration); std::cerr << "frame " << note.frame << ": " << dataPoints.size() << " candidate points" << std::endl; - if (dataPoints.empty()) return; + if (dataPoints.empty()) return false; std::vector<float> pitchValues; - for (SparseModel<TimeValuePoint>::PointList::const_iterator i = dataPoints.begin(); - i != dataPoints.end(); ++i) { - pitchValues.push_back((*i).value); + for (SparseModel<TimeValuePoint>::PointList::const_iterator i = + dataPoints.begin(); i != dataPoints.end(); ++i) { + if (i->frame >= note.frame && + i->frame < note.frame + note.duration) { + pitchValues.push_back((*i).value); + } } + + if (pitchValues.empty()) return false; + sort(pitchValues.begin(), pitchValues.end()); size_t size = pitchValues.size(); double median; @@ -1385,6 +1422,8 @@ } note.value = median; + + return true; } void