diff options
author | nick_m <mainsbridge@gmail.com> | 2016-08-13 04:02:46 +1000 |
---|---|---|
committer | nick_m <mainsbridge@gmail.com> | 2016-08-14 03:04:53 +1000 |
commit | 172bcc816504a08eb1bccbb72f58d7db7a8cb7e4 (patch) | |
tree | 221baa1846edf97c24aae35e72b0838e2cbb307e | |
parent | 5c2ccc4f3eeccaedf8399e0c80d0394cf2b4f132 (diff) |
Audio-locked midi region fixes.
- don't alter region frame length on tempo change or position change.
- set region _start correctly (see comments) on tempo map change.
- ensure audio-locked region's beat is set on tempo map change
-rw-r--r-- | libs/ardour/midi_region.cc | 46 | ||||
-rw-r--r-- | libs/ardour/region.cc | 12 |
2 files changed, 48 insertions, 10 deletions
diff --git a/libs/ardour/midi_region.cc b/libs/ardour/midi_region.cc index eef2811c5b..0ea0ed6a99 100644 --- a/libs/ardour/midi_region.cc +++ b/libs/ardour/midi_region.cc @@ -230,7 +230,7 @@ MidiRegion::update_after_tempo_map_change (bool /* send */) { boost::shared_ptr<Playlist> pl (playlist()); - if (!pl || position_lock_style() != MusicTime) { + if (!pl) { return; } @@ -238,12 +238,42 @@ MidiRegion::update_after_tempo_map_change (bool /* send */) const framepos_t old_length = _length; const framepos_t old_start = _start; + PropertyChange s_and_l; + + if (position_lock_style() == AudioTime) { + recompute_position_from_lock_style (0); + + /* + set _start to new position in tempo map. + + The user probably expects the region contents to maintain audio position as the + tempo changes, but AFAICT this requires modifying the src file to use + SMPTE timestamps with the current disk read model (?). + + We could arguably use _start to set _start_beats here, + resulting in viewport-like behaviour (the contents maintain + their musical position while the region is stationary). + + For now, the musical position at the region start is retained, but subsequent events + will maintain their beat distance according to the map. + */ + _start = _position - _session.tempo_map().frame_at_beat (beat() - _start_beats.val().to_double()); + + /* _length doesn't change for audio-locked regions. update length_beats to match. */ + _length_beats = Evoral::Beats (_session.tempo_map().beat_at_frame (_position + _length) - _session.tempo_map().beat_at_frame (_position)); + + s_and_l.add (Properties::start); + s_and_l.add (Properties::length_beats); + + send_change (s_and_l); + return; + } + Region::update_after_tempo_map_change (false); /* _start has now been updated. */ _length = _session.tempo_map().frame_at_beat (beat() + _length_beats.val().to_double()) - _position; - PropertyChange s_and_l; if (old_start != _start) { s_and_l.add (Properties::start); } @@ -276,10 +306,14 @@ MidiRegion::set_position_internal (framepos_t pos, bool allow_bbt_recompute, con update_length_beats (sub_num); } - /* leave _length_beats alone, and change _length to reflect the state of things - at the new position (tempo map may dictate a different number of frames). - */ - Region::set_length_internal (_session.tempo_map().frame_at_beat (beat() + _length_beats.val().to_double()) - _position, sub_num); + if (position_lock_style() == AudioTime) { + _length_beats = Evoral::Beats (_session.tempo_map().beat_at_frame (_position + _length) - _session.tempo_map().beat_at_frame (_position)); + } else { + /* leave _length_beats alone, and change _length to reflect the state of things + at the new position (tempo map may dictate a different number of frames). + */ + Region::set_length_internal (_session.tempo_map().frame_at_beat (beat() + _length_beats.val().to_double()) - _position, sub_num); + } } framecnt_t diff --git a/libs/ardour/region.cc b/libs/ardour/region.cc index f7874664a5..141deac7d5 100644 --- a/libs/ardour/region.cc +++ b/libs/ardour/region.cc @@ -558,7 +558,13 @@ Region::update_after_tempo_map_change (bool send) { boost::shared_ptr<Playlist> pl (playlist()); - if (!pl || _position_lock_style != MusicTime) { + if (!pl) { + return; + } + + if (_position_lock_style == AudioTime) { + /* don't signal as the actual position has not chnged */ + recompute_position_from_lock_style (0); return; } @@ -601,9 +607,7 @@ Region::set_position (framepos_t pos, int32_t sub_num) Notify a length change regardless (its more efficient for MidiRegions), and when Region has a _length_beats we will need it here anyway). */ - if (position_lock_style() == MusicTime) { - p_and_l.add (Properties::length); - } + p_and_l.add (Properties::length); send_change (p_and_l); |