summaryrefslogtreecommitdiff
path: root/libs/ardour/region.cc
diff options
context:
space:
mode:
Diffstat (limited to 'libs/ardour/region.cc')
-rw-r--r--libs/ardour/region.cc140
1 files changed, 99 insertions, 41 deletions
diff --git a/libs/ardour/region.cc b/libs/ardour/region.cc
index 0d0a40d17a..4eda001708 100644
--- a/libs/ardour/region.cc
+++ b/libs/ardour/region.cc
@@ -329,7 +329,7 @@ Region::Region (boost::shared_ptr<const Region> other)
the start within \a other is given by \a offset
(i.e. relative to the start of \a other's sources, the start is \a offset + \a other.start()
*/
-Region::Region (boost::shared_ptr<const Region> other, frameoffset_t offset, const int32_t sub_num)
+Region::Region (boost::shared_ptr<const Region> other, MusicFrame offset)
: SessionObject(other->session(), other->name())
, _type (other->data_type())
, REGION_COPY_STATE (other)
@@ -343,7 +343,6 @@ Region::Region (boost::shared_ptr<const Region> other, frameoffset_t offset, con
/* override state that may have been incorrectly inherited from the other region
*/
- _position = other->_position + offset;
_locked = false;
_whole_file = false;
_hidden = false;
@@ -351,9 +350,17 @@ Region::Region (boost::shared_ptr<const Region> other, frameoffset_t offset, con
use_sources (other->_sources);
set_master_sources (other->_master_sources);
- _start = other->_start + offset;
- _beat = _session.tempo_map().exact_beat_at_frame (_position, sub_num);
- _quarter_note = _session.tempo_map().exact_qn_at_frame (_position, sub_num);
+ _position = other->_position + offset.frame;
+ _start = other->_start + offset.frame;
+
+ /* prevent offset of 0 from altering musical position */
+ if (offset.frame != 0) {
+ const double offset_qn = _session.tempo_map().exact_qn_at_frame (other->_position + offset.frame, offset.division)
+ - other->_quarter_note;
+
+ _quarter_note = other->_quarter_note + offset_qn;
+ _beat = _session.tempo_map().beat_at_quarter_note (_quarter_note);
+ }
/* if the other region had a distinct sync point
set, then continue to use it as best we can.
@@ -589,6 +596,13 @@ Region::set_position (framepos_t pos, int32_t sub_num)
return;
}
+ /* do this even if the position is the same. this helps out
+ a GUI that has moved its representation already.
+ */
+ PropertyChange p_and_l;
+
+ p_and_l.add (Properties::position);
+
if (position_lock_style() == AudioTime) {
set_position_internal (pos, true, sub_num);
} else {
@@ -596,67 +610,79 @@ Region::set_position (framepos_t pos, int32_t sub_num)
_beat = _session.tempo_map().exact_beat_at_frame (pos, sub_num);
}
- /* will set pulse accordingly */
+ /* will set quarter note accordingly */
set_position_internal (pos, false, sub_num);
}
- /* do this even if the position is the same. this helps out
- a GUI that has moved its representation already.
- */
- PropertyChange p_and_l;
-
- p_and_l.add (Properties::position);
- /* Currently length change due to position change is only implemented
- for MidiRegion (Region has no length in beats).
- Notify a length change regardless (its more efficient for MidiRegions),
- and when Region has a _length_beats we will need it here anyway).
- */
- p_and_l.add (Properties::length);
+ if (position_lock_style() == MusicTime) {
+ p_and_l.add (Properties::length);
+ }
send_change (p_and_l);
}
-/** A gui may need to create a region, then place it in an initial
- * position determined by the user.
- * When this takes place within one gui operation, we have to reset
- * _last_position to prevent an implied move.
- */
void
-Region::set_initial_position (framepos_t pos)
+Region::set_position_internal (framepos_t pos, bool allow_bbt_recompute, const int32_t sub_num)
{
- if (!can_move()) {
- return;
- }
+ /* We emit a change of Properties::position even if the position hasn't changed
+ (see Region::set_position), so we must always set this up so that
+ e.g. Playlist::notify_region_moved doesn't use an out-of-date last_position.
+ */
+ _last_position = _position;
if (_position != pos) {
_position = pos;
+ if (allow_bbt_recompute) {
+ recompute_position_from_lock_style (sub_num);
+ } else {
+ /* MusicTime dictates that we glue to ardour beats. the pulse may have changed.*/
+ _quarter_note = _session.tempo_map().quarter_note_at_beat (_beat);
+ }
+
/* check that the new _position wouldn't make the current
length impossible - if so, change the length.
XXX is this the right thing to do?
*/
-
if (max_framepos - _length < _position) {
_last_length = _length;
_length = max_framepos - _position;
}
-
- recompute_position_from_lock_style (0);
- /* ensure that this move doesn't cause a range move */
- _last_position = _position;
}
+}
+void
+Region::set_position_music (double qn)
+{
+ if (!can_move()) {
+ return;
+ }
/* do this even if the position is the same. this helps out
a GUI that has moved its representation already.
*/
- send_change (Properties::position);
+ PropertyChange p_and_l;
+
+ p_and_l.add (Properties::position);
+
+ if (!_session.loading()) {
+ _beat = _session.tempo_map().beat_at_quarter_note (qn);
+ }
+
+ /* will set frame accordingly */
+ set_position_music_internal (qn);
+
+ if (position_lock_style() == MusicTime) {
+ p_and_l.add (Properties::length);
+ }
+
+ send_change (p_and_l);
}
void
-Region::set_position_internal (framepos_t pos, bool allow_bbt_recompute, const int32_t sub_num)
+Region::set_position_music_internal (double qn)
{
/* We emit a change of Properties::position even if the position hasn't changed
(see Region::set_position), so we must always set this up so that
@@ -664,26 +690,58 @@ Region::set_position_internal (framepos_t pos, bool allow_bbt_recompute, const i
*/
_last_position = _position;
- if (_position != pos) {
- _position = pos;
+ if (_quarter_note != qn) {
+ _position = _session.tempo_map().frame_at_quarter_note (qn);
+ _quarter_note = qn;
- if (allow_bbt_recompute) {
- recompute_position_from_lock_style (sub_num);
- } else {
- /* MusicTime dictates that we glue to ardour beats. the pulse may have changed.*/
- _quarter_note = _session.tempo_map().quarter_note_at_beat (_beat);
+ /* check that the new _position wouldn't make the current
+ length impossible - if so, change the length.
+
+ XXX is this the right thing to do?
+ */
+ if (max_framepos - _length < _position) {
+ _last_length = _length;
+ _length = max_framepos - _position;
}
+ }
+}
+
+/** A gui may need to create a region, then place it in an initial
+ * position determined by the user.
+ * When this takes place within one gui operation, we have to reset
+ * _last_position to prevent an implied move.
+ */
+void
+Region::set_initial_position (framepos_t pos)
+{
+ if (!can_move()) {
+ return;
+ }
+
+ if (_position != pos) {
+ _position = pos;
/* check that the new _position wouldn't make the current
length impossible - if so, change the length.
XXX is this the right thing to do?
*/
+
if (max_framepos - _length < _position) {
_last_length = _length;
_length = max_framepos - _position;
}
+
+ recompute_position_from_lock_style (0);
+ /* ensure that this move doesn't cause a range move */
+ _last_position = _position;
}
+
+
+ /* do this even if the position is the same. this helps out
+ a GUI that has moved its representation already.
+ */
+ send_change (Properties::position);
}
void