Mercurial > hg > svgui
diff 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 |
line wrap: on
line diff
--- a/layer/FlexiNoteLayer.cpp Tue Mar 25 13:06:27 2014 +0000 +++ b/layer/FlexiNoteLayer.cpp Thu Mar 27 15:59:46 2014 +0000 @@ -1214,11 +1214,18 @@ return; } - // MM: simpler declaration - FlexiNote note(0); - if (!getPointToDrag(v, e->x(), e->y(), note)) return; + long frame = v->getFrameForX(e->x()); - long frame = v->getFrameForX(e->x()); + splitNotesAt(v, frame); +} + +void +FlexiNoteLayer::splitNotesAt(View *v, int frame) +{ + FlexiNoteModel::PointList onPoints = m_model->getPoints(frame); + if (onPoints.empty()) return; + + FlexiNote note(*onPoints.begin()); int gap = 0; // MM: I prefer a gap of 0, but we can decide later @@ -1239,14 +1246,16 @@ FlexiNoteModel::EditCommand *command = new FlexiNoteModel::EditCommand (m_model, tr("Edit Point")); command->deletePoint(note); + +/* 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); - } void @@ -1276,8 +1285,7 @@ } if (!m_intelligentActions || - m_model->getPoints(frame).empty() && duration > 0) - { + (m_model->getPoints(frame).empty() && duration > 0)) { FlexiNote newNote(frame, value, duration, 100, "new note"); FlexiNoteModel::EditCommand *command = new FlexiNoteModel::EditCommand (m_model, tr("Add Point")); @@ -1291,12 +1299,17 @@ { // Better than we used to do, but still not very satisfactory + cerr << "FlexiNoteLayer::getAssociatedPitchModel()" << endl; + for (int i = 0; i < v->getLayerCount(); ++i) { Layer *layer = v->getLayer(i); - if (layer) { + if (layer && !layer->isLayerDormant(v)) { + cerr << "FlexiNoteLayer::getAssociatedPitchModel: looks like our layer is " << layer << endl; SparseTimeValueModel *model = qobject_cast<SparseTimeValueModel *> (layer->getModel()); + cerr << "FlexiNoteLayer::getAssociatedPitchModel: and its model is " << model << endl; if (model && model->getScaleUnits() == "Hz") { + cerr << "FlexiNoteLayer::getAssociatedPitchModel: it's good, returning " << model << endl; return model; } } @@ -1305,6 +1318,43 @@ } void +FlexiNoteLayer::snapSelectedNotesToPitchTrack(View *v, Selection s) +{ + if (!m_model) return; + + FlexiNoteModel::PointList points = + m_model->getPoints(s.getStartFrame(), s.getEndFrame()); + + FlexiNoteModel::EditCommand *command = new FlexiNoteModel::EditCommand + (m_model, tr("Snap Notes")); + + cerr << "snapSelectedNotesToPitchTrack: selection is from " << s.getStartFrame() << " to " << s.getEndFrame() << endl; + + for (FlexiNoteModel::PointList::iterator i = points.begin(); + i != points.end(); ++i) { + + FlexiNote note(*i); + + cerr << "snapSelectedNotesToPitchTrack: looking at note from " << note.frame << " to " << note.frame + note.duration << endl; + + if (!s.contains(note.frame) || + !s.contains(note.frame + note.duration - 1)) { + continue; + } + + FlexiNote newNote(note); + + command->deletePoint(note); + + updateNoteValue(v, newNote); + + command->addPoint(newNote); + } + + finish(command); +} + +void FlexiNoteLayer::updateNoteValue(View *v, FlexiNoteModel::Point ¬e) const { SparseTimeValueModel *model = getAssociatedPitchModel(v); @@ -1313,10 +1363,11 @@ std::cerr << model->getTypeName() << std::endl; 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; - - // std::cerr << "frame " << note.frame << ": " << dataPoints.size() << " candidate points" << std::endl; - + std::vector<float> pitchValues; for (SparseModel<TimeValuePoint>::PointList::const_iterator i = dataPoints.begin();