diff options
author | David Robillard <d@drobilla.net> | 2015-03-01 13:33:25 -0500 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2015-03-05 17:30:31 -0500 |
commit | a8aae56d92699e4545b5f8a69742f9a1c75ad238 (patch) | |
tree | ae3c14f1b78fbfddf126b44e533692b137d93f28 /libs/ardour/midi_region.cc | |
parent | 09f1571fc0c9dd164601cfd3d12fac31a084b9f6 (diff) |
Handle edits while playing precisely.
This avoids stuck notes if active notes are edited, but without stopping all
active notes in the region on any edit as before.
This implementation injects note ons in places that aren't actually note
starts. Depending on how percussive the instrument is, this may not be
desired. In the future, an option for this would be an improvement, but there
are other places where "start notes in the middle" is a reasonable option. I
think that should be handled universally if we're to do it at all, so not
considering it a part of this fix for now.
Diffstat (limited to 'libs/ardour/midi_region.cc')
-rw-r--r-- | libs/ardour/midi_region.cc | 33 |
1 files changed, 9 insertions, 24 deletions
diff --git a/libs/ardour/midi_region.cc b/libs/ardour/midi_region.cc index c02caff470..5c197761ac 100644 --- a/libs/ardour/midi_region.cc +++ b/libs/ardour/midi_region.cc @@ -53,7 +53,6 @@ using namespace PBD; namespace ARDOUR { namespace Properties { - PBD::PropertyDescriptor<void*> midi_data; PBD::PropertyDescriptor<Evoral::Beats> start_beats; PBD::PropertyDescriptor<Evoral::Beats> length_beats; } @@ -62,8 +61,6 @@ namespace ARDOUR { void MidiRegion::make_property_quarks () { - Properties::midi_data.property_id = g_quark_from_static_string (X_("midi-data")); - DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for midi-data = %1\n", Properties::midi_data.property_id)); Properties::start_beats.property_id = g_quark_from_static_string (X_("start-beats")); DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for start-beats = %1\n", Properties::start_beats.property_id)); Properties::length_beats.property_id = g_quark_from_static_string (X_("length-beats")); @@ -245,11 +242,16 @@ MidiRegion::master_read_at (MidiRingBuffer<framepos_t>& out, framepos_t position } framecnt_t -MidiRegion::_read_at (const SourceList& /*srcs*/, Evoral::EventSink<framepos_t>& dst, framepos_t position, framecnt_t dur, uint32_t chan_n, - NoteMode mode, MidiStateTracker* tracker) const +MidiRegion::_read_at (const SourceList& /*srcs*/, + Evoral::EventSink<framepos_t>& dst, + framepos_t position, + framecnt_t dur, + uint32_t chan_n, + NoteMode mode, + MidiStateTracker* tracker) const { frameoffset_t internal_offset = 0; - framecnt_t to_read = 0; + framecnt_t to_read = 0; /* precondition: caller has verified that we cover the desired section */ @@ -408,24 +410,6 @@ MidiRegion::model_changed () midi_source()->AutomationStateChanged.connect_same_thread ( _model_connection, boost::bind (&MidiRegion::model_automation_state_changed, this, _1) ); - - model()->ContentsChanged.connect_same_thread ( - _model_contents_connection, boost::bind (&MidiRegion::model_contents_changed, this)); -} - -void -MidiRegion::model_contents_changed () -{ - { - /* Invalidate source iterator to force reading new contents even if the - calls to read() progress linearly. Try-lock only to avoid deadlock - when called while writing with the source already locked. */ - Glib::Threads::Mutex::Lock lm (midi_source(0)->mutex(), Glib::Threads::TRY_LOCK); - if (lm.locked()) { - midi_source(0)->invalidate (lm); - } - } - send_change (PropertyChange (Properties::midi_data)); } void @@ -448,6 +432,7 @@ MidiRegion::model_automation_state_changed (Evoral::Parameter const & p) */ Glib::Threads::Mutex::Lock lm (midi_source(0)->mutex(), Glib::Threads::TRY_LOCK); if (lm.locked()) { + /* TODO: This is too aggressive, we need more fine-grained invalidation. */ midi_source(0)->invalidate (lm); } } |