From a196405da9fab534b5ece4d165e871d02d671b36 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Thu, 20 May 2010 22:38:12 +0000 Subject: various minor MIDI fixes: prevent duplicate note entry with mouse, show note info more often with verbose cursor, fix some crashes from click+move on notes ... lots more where this comes from git-svn-id: svn://localhost/ardour2/branches/3.0@7128 d708f5d6-7413-0410-9779-e7cbd77b26cf --- libs/ardour/ardour/midi_model.h | 5 +++-- libs/ardour/ardour/midi_source.h | 2 +- libs/ardour/midi_model.cc | 32 +++++++++++++++++++++++++++++++- libs/ardour/midi_source.cc | 12 +++++++++++- 4 files changed, 46 insertions(+), 5 deletions(-) (limited to 'libs/ardour') diff --git a/libs/ardour/ardour/midi_model.h b/libs/ardour/ardour/midi_model.h index 8d949cadbb..b3a4d746a1 100644 --- a/libs/ardour/ardour/midi_model.h +++ b/libs/ardour/ardour/midi_model.h @@ -151,8 +151,9 @@ public: void apply_command(Session& session, Command* cmd); void apply_command_as_subcommand(Session& session, Command* cmd); - bool write_to(boost::shared_ptr source, Evoral::MusicalTime begin = Evoral::MinMusicalTime, - Evoral::MusicalTime end = Evoral::MaxMusicalTime); + bool write_to(boost::shared_ptr source); + bool write_section_to(boost::shared_ptr source, Evoral::MusicalTime begin = Evoral::MinMusicalTime, + Evoral::MusicalTime end = Evoral::MaxMusicalTime); // MidiModel doesn't use the normal AutomationList serialisation code // since controller data is stored in the .mid diff --git a/libs/ardour/ardour/midi_source.h b/libs/ardour/ardour/midi_source.h index 2484d3575a..c418559d6e 100644 --- a/libs/ardour/ardour/midi_source.h +++ b/libs/ardour/ardour/midi_source.h @@ -111,7 +111,7 @@ class MidiSource : virtual public Source boost::shared_ptr model() { return _model; } void set_model(boost::shared_ptr m) { _model = m; } - void drop_model() { _model.reset(); } + void drop_model(); protected: virtual void flush_midi() = 0; diff --git a/libs/ardour/midi_model.cc b/libs/ardour/midi_model.cc index 88ef60e8e5..3b258eab09 100644 --- a/libs/ardour/midi_model.cc +++ b/libs/ardour/midi_model.cc @@ -676,6 +676,36 @@ MidiModel::DiffCommand::get_state () return *diff_command; } +/** Write all of the model to a MidiSource (i.e. save the model). + * This is different from manually using read to write to a source in that + * note off events are written regardless of the track mode. This is so the + * user can switch a recorded track (with note durations from some instrument) + * to percussive, save, reload, then switch it back to sustained without + * destroying the original note durations. + */ +bool +MidiModel::write_to (boost::shared_ptr source) +{ + ReadLock lock(read_lock()); + + const bool old_percussive = percussive(); + set_percussive(false); + + source->drop_model(); + source->mark_streaming_midi_write_started(note_mode(), _midi_source->timeline_position()); + + for (Evoral::Sequence::const_iterator i = begin(); i != end(); ++i) { + source->append_event_unlocked_beats(*i); + } + + set_percussive(old_percussive); + source->mark_streaming_write_completed(); + + set_edited(false); + + return true; +} + /** Write part or all of the model to a MidiSource (i.e. save the model). * This is different from manually using read to write to a source in that * note off events are written regardless of the track mode. This is so the @@ -684,7 +714,7 @@ MidiModel::DiffCommand::get_state () * destroying the original note durations. */ bool -MidiModel::write_to (boost::shared_ptr source, Evoral::MusicalTime begin_time, Evoral::MusicalTime end_time) +MidiModel::write_section_to (boost::shared_ptr source, Evoral::MusicalTime begin_time, Evoral::MusicalTime end_time) { ReadLock lock(read_lock()); MidiStateTracker mst; diff --git a/libs/ardour/midi_source.cc b/libs/ardour/midi_source.cc index 5e8bda1ea2..0c66879330 100644 --- a/libs/ardour/midi_source.cc +++ b/libs/ardour/midi_source.cc @@ -250,7 +250,11 @@ MidiSource::clone (Evoral::MusicalTime begin, Evoral::MusicalTime end) newsrc->set_timeline_position(_timeline_position); if (_model) { - _model->write_to (newsrc, begin, end); + if (begin == Evoral::MinMusicalTime && end == Evoral::MaxMusicalTime) { + _model->write_to (newsrc); + } else { + _model->write_section_to (newsrc, begin, end); + } } else { error << string_compose (_("programming error: %1"), X_("no model for MidiSource during ::clone()")); return boost::shared_ptr(); @@ -290,3 +294,9 @@ MidiSource::set_note_mode(NoteMode mode) } } +void +MidiSource::drop_model () +{ + cerr << name() << " drop model\n"; + _model.reset(); +} -- cgit v1.2.3