13
0

Handle overlaps better when executing DiffCommands.

git-svn-id: svn://localhost/ardour2/branches/3.0@8233 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
Carl Hetherington 2010-12-09 21:37:14 +00:00
parent 555c7ac094
commit 627385cab4
2 changed files with 35 additions and 9 deletions

View File

@ -141,9 +141,9 @@ public:
}; };
/* Currently this class only supports changes of sys-ex time, but could be expanded */ /* Currently this class only supports changes of sys-ex time, but could be expanded */
class SysexDiffCommand : public DiffCommand { class SysExDiffCommand : public DiffCommand {
public: public:
SysexDiffCommand (boost::shared_ptr<MidiModel> m, const XMLNode& node); SysExDiffCommand (boost::shared_ptr<MidiModel> m, const XMLNode& node);
enum Property { enum Property {
Time, Time,
@ -160,7 +160,7 @@ public:
private: private:
struct Change { struct Change {
boost::shared_ptr<Evoral::Event<TimeType> > sysex; boost::shared_ptr<Evoral::Event<TimeType> > sysex;
SysexDiffCommand::Property property; SysExDiffCommand::Property property;
TimeType old_time; TimeType old_time;
TimeType new_time; TimeType new_time;
}; };
@ -172,7 +172,8 @@ public:
Change unmarshal_change (XMLNode *); Change unmarshal_change (XMLNode *);
}; };
MidiModel::NoteDiffCommand* new_note_diff_command (const std::string name="midi edit"); MidiModel::NoteDiffCommand* new_note_diff_command (const std::string name = "midi edit");
MidiModel::SysExDiffCommand* new_sysex_diff_command (const std::string name = "midi edit");
void apply_command (Session& session, Command* cmd); void apply_command (Session& session, Command* cmd);
void apply_command_as_subcommand (Session& session, Command* cmd); void apply_command_as_subcommand (Session& session, Command* cmd);

View File

@ -147,6 +147,8 @@ void
MidiModel::NoteDiffCommand::change (const NotePtr note, Property prop, MidiModel::NoteDiffCommand::change (const NotePtr note, Property prop,
uint8_t new_value) uint8_t new_value)
{ {
assert (note);
NoteChange change; NoteChange change;
switch (prop) { switch (prop) {
@ -191,6 +193,8 @@ void
MidiModel::NoteDiffCommand::change (const NotePtr note, Property prop, MidiModel::NoteDiffCommand::change (const NotePtr note, Property prop,
TimeType new_time) TimeType new_time)
{ {
assert (note);
NoteChange change; NoteChange change;
switch (prop) { switch (prop) {
@ -307,8 +311,30 @@ MidiModel::NoteDiffCommand::operator() ()
for (set<NotePtr>::iterator i = temporary_removals.begin(); i != temporary_removals.end(); ++i) { for (set<NotePtr>::iterator i = temporary_removals.begin(); i != temporary_removals.end(); ++i) {
NoteDiffCommand side_effects (model(), "side effects"); NoteDiffCommand side_effects (model(), "side effects");
_model->add_note_unlocked (*i, &side_effects); if (_model->add_note_unlocked (*i, &side_effects)) {
*this += side_effects; /* The note was re-added ok */
*this += side_effects;
} else {
/* The note that we removed earlier could not be re-added. This change record
must say that the note was removed. It is an un-note.
*/
/* We didn't change it... */
for (ChangeList::iterator j = _changes.begin(); j != _changes.end(); ) {
ChangeList::iterator k = j;
++k;
if (*i == j->note) {
_changes.erase (j);
}
j = k;
}
/* ...in fact, we removed it */
_removed_notes.push_back (*i);
}
} }
if (!side_effect_removals.empty()) { if (!side_effect_removals.empty()) {
@ -1124,7 +1150,7 @@ MidiModel::resolve_overlaps_unlocked (const NotePtr note, void* arg)
TimeType note_length = note->length(); TimeType note_length = note->length();
DEBUG_TRACE (DEBUG::Sequence, string_compose ("%1 checking overlaps for note %2 @ %3\n", this, (int)note->note(), note->time())); DEBUG_TRACE (DEBUG::Sequence, string_compose ("%1 checking overlaps for note %2 @ %3\n", this, (int)note->note(), note->time()));
for (Pitches::const_iterator i = p.lower_bound (search_note); for (Pitches::const_iterator i = p.lower_bound (search_note);
i != p.end() && (*i)->note() == note->note(); ++i) { i != p.end() && (*i)->note() == note->note(); ++i) {
@ -1132,7 +1158,6 @@ MidiModel::resolve_overlaps_unlocked (const NotePtr note, void* arg)
TimeType eb = (*i)->end_time(); TimeType eb = (*i)->end_time();
OverlapType overlap = OverlapNone; OverlapType overlap = OverlapNone;
if ((sb > sa) && (eb <= ea)) { if ((sb > sa) && (eb <= ea)) {
overlap = OverlapInternal; overlap = OverlapInternal;
} else if ((eb >= sa) && (eb <= ea)) { } else if ((eb >= sa) && (eb <= ea)) {
@ -1146,7 +1171,7 @@ MidiModel::resolve_overlaps_unlocked (const NotePtr note, void* arg)
continue; continue;
} }
DEBUG_TRACE (DEBUG::Sequence, string_compose ("\toverlap is %1 for (%2,%3) vs (%4,%5)\n", enum_2_string(overlap), DEBUG_TRACE (DEBUG::Sequence, string_compose ("\toverlap is %1 for (%2,%3) vs (%4,%5)\n", enum_2_string(overlap),
sa, ea, sb, eb)); sa, ea, sb, eb));
if (insert_merge_policy() == InsertMergeReject) { if (insert_merge_policy() == InsertMergeReject) {