diff options
Diffstat (limited to 'libs/ardour/midi_model.cc')
-rw-r--r-- | libs/ardour/midi_model.cc | 201 |
1 files changed, 71 insertions, 130 deletions
diff --git a/libs/ardour/midi_model.cc b/libs/ardour/midi_model.cc index b5d5d24713..6922384e71 100644 --- a/libs/ardour/midi_model.cc +++ b/libs/ardour/midi_model.cc @@ -382,25 +382,41 @@ MidiModel::DiffCommand::marshal_note(const NotePtr note) cerr << "Marshalling note: " << *note << endl; - ostringstream note_str(ios::ate); - note_str << int(note->note()); - xml_note->add_property("note", note_str.str()); + { + ostringstream id_str(ios::ate); + id_str << int(note->id()); + xml_note->add_property("id", id_str.str()); + } - ostringstream channel_str(ios::ate); - channel_str << int(note->channel()); - xml_note->add_property("channel", channel_str.str()); + { + ostringstream note_str(ios::ate); + note_str << int(note->note()); + xml_note->add_property("note", note_str.str()); + } - ostringstream time_str(ios::ate); - time_str << note->time(); - xml_note->add_property("time", time_str.str()); + { + ostringstream channel_str(ios::ate); + channel_str << int(note->channel()); + xml_note->add_property("channel", channel_str.str()); + } - ostringstream length_str(ios::ate); - length_str << note->length(); - xml_note->add_property("length", length_str.str()); + { + ostringstream time_str(ios::ate); + time_str << note->time(); + xml_note->add_property("time", time_str.str()); + } - ostringstream velocity_str(ios::ate); - velocity_str << (unsigned int) note->velocity(); - xml_note->add_property("velocity", velocity_str.str()); + { + ostringstream length_str(ios::ate); + length_str << note->length(); + xml_note->add_property("length", length_str.str()); + } + + { + ostringstream velocity_str(ios::ate); + velocity_str << (unsigned int) note->velocity(); + xml_note->add_property("velocity", velocity_str.str()); + } return *xml_note; } @@ -414,6 +430,15 @@ MidiModel::DiffCommand::unmarshal_note(XMLNode *xml_note) unsigned int time; unsigned int length; unsigned int velocity; + gint id; + + if ((prop = xml_note->property("id")) != 0) { + istringstream id_str(prop->value()); + id_str >> id; + } else { + error << "note information missing ID value" << endmsg; + id = -1; + } if ((prop = xml_note->property("note")) != 0) { istringstream note_str(prop->value()); @@ -456,6 +481,7 @@ MidiModel::DiffCommand::unmarshal_note(XMLNode *xml_note) } NotePtr note_ptr(new Evoral::Note<TimeType>(channel, time, length, note, velocity)); + note_ptr->set_id (id); return note_ptr; } @@ -463,7 +489,7 @@ MidiModel::DiffCommand::unmarshal_note(XMLNode *xml_note) XMLNode& MidiModel::DiffCommand::marshal_change(const NoteChange& change) { - XMLNode* xml_change = new XMLNode("change"); + XMLNode* xml_change = new XMLNode("Change"); /* first, the change itself */ @@ -489,49 +515,9 @@ MidiModel::DiffCommand::marshal_change(const NoteChange& change) xml_change->add_property ("new", new_value_str.str()); } - /* now the rest of the note */ - - const SMFSource* smf = dynamic_cast<const SMFSource*> (_model->midi_source()); - - if (change.property != NoteNumber) { - ostringstream note_str; - note_str << int(change.note->note()); - xml_change->add_property("note", note_str.str()); - } - - if (change.property != Channel) { - ostringstream channel_str; - channel_str << int(change.note->channel()); - xml_change->add_property("channel", channel_str.str()); - } - - if (change.property != StartTime) { - ostringstream time_str; - if (smf) { - time_str << smf->round_to_file_precision (change.note->time()); - } else { - time_str << change.note->time(); - } - xml_change->add_property("time", time_str.str()); - } - - if (change.property != Length) { - ostringstream length_str; - if (smf) { - length_str << smf->round_to_file_precision (change.note->length()); - } else { - length_str << change.note->length(); - } - xml_change->add_property ("length", length_str.str()); - } - - if (change.property != Velocity) { - ostringstream velocity_str; - velocity_str << int (change.note->velocity()); - xml_change->add_property("velocity", velocity_str.str()); - } - - /* and now notes that were remove as a side-effect */ + ostringstream id_str; + id_str << change.note->id(); + xml_change->add_property ("id", id_str.str()); return *xml_change; } @@ -541,11 +527,6 @@ MidiModel::DiffCommand::unmarshal_change(XMLNode *xml_change) { XMLProperty* prop; NoteChange change; - unsigned int note; - unsigned int channel; - unsigned int velocity; - Evoral::MusicalTime time; - Evoral::MusicalTime length; if ((prop = xml_change->property("property")) != 0) { change.property = (Property) string_2_enum (prop->value(), change.property); @@ -554,6 +535,13 @@ MidiModel::DiffCommand::unmarshal_change(XMLNode *xml_change) /*NOTREACHED*/ } + if ((prop = xml_change->property ("id")) == 0) { + error << _("No NoteID found for note property change - ignored") << endmsg; + return change; + } + + gint note_id = atoi (prop->value().c_str()); + if ((prop = xml_change->property ("old")) != 0) { istringstream old_str (prop->value()); if (change.property == StartTime || change.property == Length) { @@ -582,78 +570,15 @@ MidiModel::DiffCommand::unmarshal_change(XMLNode *xml_change) /*NOTREACHED*/ } - if (change.property != NoteNumber) { - if ((prop = xml_change->property("note")) != 0) { - istringstream note_str(prop->value()); - note_str >> note; - } else { - warning << "note information missing note value" << endmsg; - note = 127; - } - } else { - note = change.new_value; - } - - if (change.property != Channel) { - if ((prop = xml_change->property("channel")) != 0) { - istringstream channel_str(prop->value()); - channel_str >> channel; - } else { - warning << "note information missing channel" << endmsg; - channel = 0; - } - } else { - channel = change.new_value; - } - - if (change.property != StartTime) { - if ((prop = xml_change->property("time")) != 0) { - istringstream time_str(prop->value()); - time_str >> time; - } else { - warning << "note information missing time" << endmsg; - time = 0; - } - } else { - time = change.new_time; - } - - if (change.property != Length) { - if ((prop = xml_change->property("length")) != 0) { - istringstream length_str(prop->value()); - length_str >> length; - } else { - warning << "note information missing length" << endmsg; - length = 1; - } - } else { - length = change.new_time; - } - - if (change.property != Velocity) { - if ((prop = xml_change->property("velocity")) != 0) { - istringstream velocity_str(prop->value()); - velocity_str >> velocity; - } else { - warning << "note information missing velocity" << endmsg; - velocity = 127; - } - } else { - velocity = change.new_value; - } - /* we must point at the instance of the note that is actually in the model. so go look for it ... */ - NotePtr new_note (new Evoral::Note<TimeType> (channel, time, length, note, velocity)); - - change.note = _model->find_note (new_note); + change.note = _model->find_note (note_id); if (!change.note) { - warning << "MIDI note " << *new_note << " not found in model - programmers should investigate this" << endmsg; - /* use the actual new note */ - change.note = new_note; + warning << "MIDI note #" << note_id << " not found in model - programmers should investigate this" << endmsg; + return change; } return change; @@ -925,6 +850,22 @@ MidiModel::find_note (NotePtr other) return NotePtr(); } +Evoral::Sequence<MidiModel::TimeType>::NotePtr +MidiModel::find_note (gint note_id) +{ + /* used only for looking up notes when reloading history from disk, + so we don't care about performance *too* much. + */ + + for (Notes::iterator l = notes().begin(); l != notes().end(); ++l) { + if ((*l)->id() == note_id) { + return *l; + } + } + + return NotePtr(); +} + /** Lock and invalidate the source. * This should be used by commands and editing things */ |