13
0

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
This commit is contained in:
nick_m 2016-08-13 04:02:46 +10:00
parent 5c2ccc4f3e
commit 172bcc8165
2 changed files with 48 additions and 10 deletions

View File

@ -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

View File

@ -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);