X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Fregion.cc;h=8640b53a6e4cd3f798ea2ea6cab0b2e561458fd3;hb=a1116ebd6f19c30c8a85200c19ec30c00337ccda;hp=ca178a9f7bad8297f48f809dc54c99e360fd4e77;hpb=d14c660261c2534bfef77be6d66092f424e562ee;p=ardour.git diff --git a/libs/ardour/region.cc b/libs/ardour/region.cc index ca178a9f7b..8640b53a6e 100644 --- a/libs/ardour/region.cc +++ b/libs/ardour/region.cc @@ -38,7 +38,7 @@ #include "ardour/tempo.h" #include "ardour/transient_detector.h" -#include "i18n.h" +#include "pbd/i18n.h" using namespace std; using namespace ARDOUR; @@ -64,6 +64,7 @@ namespace ARDOUR { PBD::PropertyDescriptor start; PBD::PropertyDescriptor length; PBD::PropertyDescriptor position; + PBD::PropertyDescriptor beat; PBD::PropertyDescriptor sync_position; PBD::PropertyDescriptor layer; PBD::PropertyDescriptor ancestral_start; @@ -81,55 +82,57 @@ void Region::make_property_quarks () { Properties::muted.property_id = g_quark_from_static_string (X_("muted")); - DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for muted = %1\n", Properties::muted.property_id)); + DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for muted = %1\n", Properties::muted.property_id)); Properties::opaque.property_id = g_quark_from_static_string (X_("opaque")); - DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for opaque = %1\n", Properties::opaque.property_id)); + DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for opaque = %1\n", Properties::opaque.property_id)); Properties::locked.property_id = g_quark_from_static_string (X_("locked")); - DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for locked = %1\n", Properties::locked.property_id)); + DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for locked = %1\n", Properties::locked.property_id)); Properties::video_locked.property_id = g_quark_from_static_string (X_("video-locked")); - DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for video-locked = %1\n", Properties::video_locked.property_id)); + DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for video-locked = %1\n", Properties::video_locked.property_id)); Properties::automatic.property_id = g_quark_from_static_string (X_("automatic")); - DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for automatic = %1\n", Properties::automatic.property_id)); + DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for automatic = %1\n", Properties::automatic.property_id)); Properties::whole_file.property_id = g_quark_from_static_string (X_("whole-file")); - DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for whole-file = %1\n", Properties::whole_file.property_id)); + DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for whole-file = %1\n", Properties::whole_file.property_id)); Properties::import.property_id = g_quark_from_static_string (X_("import")); - DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for import = %1\n", Properties::import.property_id)); + DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for import = %1\n", Properties::import.property_id)); Properties::external.property_id = g_quark_from_static_string (X_("external")); - DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for external = %1\n", Properties::external.property_id)); + DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for external = %1\n", Properties::external.property_id)); Properties::sync_marked.property_id = g_quark_from_static_string (X_("sync-marked")); - DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for sync-marked = %1\n", Properties::sync_marked.property_id)); + DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for sync-marked = %1\n", Properties::sync_marked.property_id)); Properties::left_of_split.property_id = g_quark_from_static_string (X_("left-of-split")); - DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for left-of-split = %1\n", Properties::left_of_split.property_id)); + DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for left-of-split = %1\n", Properties::left_of_split.property_id)); Properties::right_of_split.property_id = g_quark_from_static_string (X_("right-of-split")); - DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for right-of-split = %1\n", Properties::right_of_split.property_id)); + DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for right-of-split = %1\n", Properties::right_of_split.property_id)); Properties::hidden.property_id = g_quark_from_static_string (X_("hidden")); - DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for hidden = %1\n", Properties::hidden.property_id)); + DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for hidden = %1\n", Properties::hidden.property_id)); Properties::position_locked.property_id = g_quark_from_static_string (X_("position-locked")); - DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for position-locked = %1\n", Properties::position_locked.property_id)); + DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for position-locked = %1\n", Properties::position_locked.property_id)); Properties::valid_transients.property_id = g_quark_from_static_string (X_("valid-transients")); - DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for valid-transients = %1\n", Properties::valid_transients.property_id)); + DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for valid-transients = %1\n", Properties::valid_transients.property_id)); Properties::start.property_id = g_quark_from_static_string (X_("start")); - DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for start = %1\n", Properties::start.property_id)); + DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for start = %1\n", Properties::start.property_id)); Properties::length.property_id = g_quark_from_static_string (X_("length")); - DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for length = %1\n", Properties::length.property_id)); + DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for length = %1\n", Properties::length.property_id)); Properties::position.property_id = g_quark_from_static_string (X_("position")); - DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for position = %1\n", Properties::position.property_id)); + DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for position = %1\n", Properties::position.property_id)); + Properties::beat.property_id = g_quark_from_static_string (X_("beat")); + DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for beat = %1\n", Properties::beat.property_id)); Properties::sync_position.property_id = g_quark_from_static_string (X_("sync-position")); - DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for sync-position = %1\n", Properties::sync_position.property_id)); + DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for sync-position = %1\n", Properties::sync_position.property_id)); Properties::layer.property_id = g_quark_from_static_string (X_("layer")); - DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for layer = %1\n", Properties::layer.property_id)); + DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for layer = %1\n", Properties::layer.property_id)); Properties::ancestral_start.property_id = g_quark_from_static_string (X_("ancestral-start")); - DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for ancestral-start = %1\n", Properties::ancestral_start.property_id)); + DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for ancestral-start = %1\n", Properties::ancestral_start.property_id)); Properties::ancestral_length.property_id = g_quark_from_static_string (X_("ancestral-length")); - DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for ancestral-length = %1\n", Properties::ancestral_length.property_id)); + DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for ancestral-length = %1\n", Properties::ancestral_length.property_id)); Properties::stretch.property_id = g_quark_from_static_string (X_("stretch")); - DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for stretch = %1\n", Properties::stretch.property_id)); + DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for stretch = %1\n", Properties::stretch.property_id)); Properties::shift.property_id = g_quark_from_static_string (X_("shift")); - DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for shift = %1\n", Properties::shift.property_id)); + DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for shift = %1\n", Properties::shift.property_id)); Properties::position_lock_style.property_id = g_quark_from_static_string (X_("positional-lock-style")); - DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for position_lock_style = %1\n", Properties::position_lock_style.property_id)); + DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for position_lock_style = %1\n", Properties::position_lock_style.property_id)); Properties::layering_index.property_id = g_quark_from_static_string (X_("layering-index")); - DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for layering_index = %1\n", Properties::layering_index.property_id)); + DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for layering_index = %1\n", Properties::layering_index.property_id)); } void @@ -154,6 +157,7 @@ Region::register_properties () add_property (_start); add_property (_length); add_property (_position); + add_property (_beat); add_property (_sync_position); add_property (_ancestral_start); add_property (_ancestral_length); @@ -171,7 +175,9 @@ Region::register_properties () , _start (Properties::start, (s)) \ , _length (Properties::length, (l)) \ , _position (Properties::position, 0) \ + , _beat (Properties::beat, 0.0) \ , _sync_position (Properties::sync_position, (s)) \ + , _quarter_note (0.0) \ , _transient_user_start (0) \ , _transient_analysis_start (0) \ , _transient_analysis_end (0) \ @@ -200,7 +206,9 @@ Region::register_properties () , _start(Properties::start, other->_start) \ , _length(Properties::length, other->_length) \ , _position(Properties::position, other->_position) \ + , _beat (Properties::beat, other->_beat) \ , _sync_position(Properties::sync_position, other->_sync_position) \ + , _quarter_note (other->_quarter_note) \ , _user_transients (other->_user_transients) \ , _transient_user_start (other->_transient_user_start) \ , _transients (other->_transients) \ @@ -273,7 +281,7 @@ Region::Region (boost::shared_ptr other) /* override state that may have been incorrectly inherited from the other region */ - _position = 0; + _position = other->_position; _locked = false; _whole_file = false; _hidden = false; @@ -284,7 +292,9 @@ Region::Region (boost::shared_ptr other) _position_lock_style = other->_position_lock_style; _first_edit = other->_first_edit; - _start = 0; // It seems strange _start is not inherited here? + _start = other->_start; + _beat = other->_beat; + _quarter_note = other->_quarter_note; /* sync pos is relative to start of file. our start-in-file is now zero, so set our sync position to whatever the the difference between @@ -319,7 +329,7 @@ Region::Region (boost::shared_ptr 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 other, frameoffset_t offset) +Region::Region (boost::shared_ptr other, MusicFrame offset) : SessionObject(other->session(), other->name()) , _type (other->data_type()) , REGION_COPY_STATE (other) @@ -333,7 +343,6 @@ Region::Region (boost::shared_ptr other, frameoffset_t offset) /* override state that may have been incorrectly inherited from the other region */ - _position = 0; _locked = false; _whole_file = false; _hidden = false; @@ -341,7 +350,19 @@ Region::Region (boost::shared_ptr other, frameoffset_t offset) use_sources (other->_sources); set_master_sources (other->_master_sources); - _start = other->_start + offset; + _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); + } else { + _quarter_note = _session.tempo_map().quarter_note_at_beat (_beat); + } /* if the other region had a distinct sync point set, then continue to use it as best we can. @@ -416,7 +437,7 @@ Region::set_name (const std::string& str) } void -Region::set_length (framecnt_t len) +Region::set_length (framecnt_t len, const int32_t sub_num) { //cerr << "Region::set_length() len = " << len << endl; if (locked()) { @@ -438,8 +459,7 @@ Region::set_length (framecnt_t len) } - _last_length = _length; - set_length_internal (len); + set_length_internal (len, sub_num); _whole_file = false; first_edit (); maybe_uncopy (); @@ -454,8 +474,9 @@ Region::set_length (framecnt_t len) } void -Region::set_length_internal (framecnt_t len) +Region::set_length_internal (framecnt_t len, const int32_t sub_num) { + _last_length = _length; _length = len; } @@ -537,88 +558,133 @@ Region::set_position_lock_style (PositionLockStyle ps) _position_lock_style = ps; - if (_position_lock_style == MusicTime) { - _beat = _session.tempo_map().beat_at_frame (_position); - } - send_change (Properties::position_lock_style); } } void -Region::update_after_tempo_map_change () +Region::update_after_tempo_map_change (bool send) { boost::shared_ptr 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; } - TempoMap& map (_session.tempo_map()); - framepos_t pos = map.frame_at_beat (_beat); - set_position_internal (pos, false); + + /* prevent movement before 0 */ + const framepos_t pos = max ((framepos_t) 0, _session.tempo_map().frame_at_beat (_beat)); + /* we have _beat. update frame position non-musically */ + set_position_internal (pos, false, 0); /* do this even if the position is the same. this helps out a GUI that has moved its representation already. */ - send_change (Properties::position); + + if (send) { + send_change (Properties::position); + } } void -Region::set_position (framepos_t pos) +Region::set_position (framepos_t pos, int32_t sub_num) { if (!can_move()) { return; } - set_position_internal (pos, true); - /* 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 (position_lock_style() == AudioTime) { + set_position_internal (pos, true, sub_num); + } else { + if (!_session.loading()) { + _beat = _session.tempo_map().exact_beat_at_frame (pos, sub_num); + _quarter_note = _session.tempo_map().quarter_note_at_beat (_beat); + } + + set_position_internal (pos, false, sub_num); + } + + 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 (); - /* 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) +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 @@ -626,6 +692,34 @@ Region::set_position_internal (framepos_t pos, bool allow_bbt_recompute) */ _last_position = _position; + if (_quarter_note != qn) { + _position = _session.tempo_map().frame_at_quarter_note (qn); + _quarter_note = qn; + + /* 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; @@ -640,18 +734,23 @@ Region::set_position_internal (framepos_t pos, bool allow_bbt_recompute) _length = max_framepos - _position; } - if (allow_bbt_recompute) { - recompute_position_from_lock_style (); - } + 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 -Region::recompute_position_from_lock_style () +Region::recompute_position_from_lock_style (const int32_t sub_num) { - if (_position_lock_style == MusicTime) { - _beat = _session.tempo_map().beat_at_frame (_position); - } + _beat = _session.tempo_map().exact_beat_at_frame (_position, sub_num); + _quarter_note = _session.tempo_map().exact_qn_at_frame (_position, sub_num); } void @@ -680,8 +779,8 @@ Region::nudge_position (frameoffset_t n) new_position += n; } } - - set_position_internal (new_position, true); + /* assumes non-musical nudge */ + set_position_internal (new_position, true, 0); send_change (Properties::position); } @@ -722,7 +821,7 @@ Region::set_start (framepos_t pos) } void -Region::move_start (frameoffset_t distance) +Region::move_start (frameoffset_t distance, const int32_t sub_num) { if (locked() || position_locked() || video_locked()) { return; @@ -758,7 +857,7 @@ Region::move_start (frameoffset_t distance) return; } - set_start_internal (new_start); + set_start_internal (new_start, sub_num); _whole_file = false; first_edit (); @@ -767,25 +866,25 @@ Region::move_start (frameoffset_t distance) } void -Region::trim_front (framepos_t new_position) +Region::trim_front (framepos_t new_position, const int32_t sub_num) { - modify_front (new_position, false); + modify_front (new_position, false, sub_num); } void -Region::cut_front (framepos_t new_position) +Region::cut_front (framepos_t new_position, const int32_t sub_num) { - modify_front (new_position, true); + modify_front (new_position, true, sub_num); } void -Region::cut_end (framepos_t new_endpoint) +Region::cut_end (framepos_t new_endpoint, const int32_t sub_num) { - modify_end (new_endpoint, true); + modify_end (new_endpoint, true, sub_num); } void -Region::modify_front (framepos_t new_position, bool reset_fade) +Region::modify_front (framepos_t new_position, bool reset_fade, const int32_t sub_num) { if (locked()) { return; @@ -815,7 +914,7 @@ Region::modify_front (framepos_t new_position, bool reset_fade) newlen = _length + (_position - new_position); } - trim_to_internal (new_position, newlen); + trim_to_internal (new_position, newlen, sub_num); if (reset_fade) { _right_of_split = true; @@ -830,14 +929,14 @@ Region::modify_front (framepos_t new_position, bool reset_fade) } void -Region::modify_end (framepos_t new_endpoint, bool reset_fade) +Region::modify_end (framepos_t new_endpoint, bool reset_fade, const int32_t sub_num) { if (locked()) { return; } if (new_endpoint > _position) { - trim_to_internal (_position, new_endpoint - _position); + trim_to_internal (_position, new_endpoint - _position, sub_num); if (reset_fade) { _left_of_split = true; } @@ -852,19 +951,19 @@ Region::modify_end (framepos_t new_endpoint, bool reset_fade) */ void -Region::trim_end (framepos_t new_endpoint) +Region::trim_end (framepos_t new_endpoint, const int32_t sub_num) { - modify_end (new_endpoint, false); + modify_end (new_endpoint, false, sub_num); } void -Region::trim_to (framepos_t position, framecnt_t length) +Region::trim_to (framepos_t position, framecnt_t length, const int32_t sub_num) { if (locked()) { return; } - trim_to_internal (position, length); + trim_to_internal (position, length, sub_num); if (!property_changes_suspended()) { recompute_at_start (); @@ -873,7 +972,7 @@ Region::trim_to (framepos_t position, framecnt_t length) } void -Region::trim_to_internal (framepos_t position, framecnt_t length) +Region::trim_to_internal (framepos_t position, framecnt_t length, const int32_t sub_num) { framepos_t new_start; @@ -910,10 +1009,11 @@ Region::trim_to_internal (framepos_t position, framecnt_t length) PropertyChange what_changed; if (_start != new_start) { - set_start_internal (new_start); + set_start_internal (new_start, sub_num); what_changed.add (Properties::start); } + /* Set position before length, otherwise for MIDI regions this bad thing happens: * 1. we call set_length_internal; length in beats is computed using the region's current * (soon-to-be old) position @@ -926,7 +1026,7 @@ Region::trim_to_internal (framepos_t position, framecnt_t length) if (!property_changes_suspended()) { _last_position = _position; } - set_position_internal (position, true); + set_position_internal (position, true, sub_num); what_changed.add (Properties::position); } @@ -934,7 +1034,7 @@ Region::trim_to_internal (framepos_t position, framecnt_t length) if (!property_changes_suspended()) { _last_length = _length; } - set_length_internal (length); + set_length_internal (length, sub_num); what_changed.add (Properties::length); } @@ -1196,11 +1296,6 @@ Region::state () /* note: flags are stored by derived classes */ - if (_position_lock_style != AudioTime) { - snprintf (buf, sizeof(buf), "%lf", _beat); - node->add_property ("beat", buf); - } - for (uint32_t n=0; n < _sources.size(); ++n) { snprintf (buf2, sizeof(buf2), "source-%d", n); _sources[n]->id().print (buf, sizeof(buf)); @@ -1268,25 +1363,18 @@ Region::_set_state (const XMLNode& node, int /*version*/, PropertyChange& what_c set_id (node); if (_position_lock_style == MusicTime) { - if ((prop = node.property ("bbt-position")) == 0) { - if ((prop = node.property ("beat")) == 0) { - /* missing BBT info, revert to audio time locking */ - _position_lock_style = AudioTime; - } else { - if (sscanf (prop->value().c_str(), "%lf", &_beat) != 1) { - _position_lock_style = AudioTime; - } - } - - } else { + if ((prop = node.property ("bbt-position")) != 0) { if (sscanf (prop->value().c_str(), "%d|%d|%d", &bbt_time.bars, &bbt_time.beats, &bbt_time.ticks) != 3) { _position_lock_style = AudioTime; + _beat = _session.tempo_map().beat_at_frame (_position); } else { - _beat = _session.tempo_map().bbt_to_beats (bbt_time); + _beat = _session.tempo_map().beat_at_bbt (bbt_time); } + /* no position property change for legacy Property, so we do this here */ + _quarter_note = _session.tempo_map().quarter_note_at_beat (_beat); } } @@ -1505,19 +1593,59 @@ Region::source_string () const return res.str(); } +void +Region::deep_sources (std::set > & sources) const +{ + for (SourceList::const_iterator i = _sources.begin(); i != _sources.end(); ++i) { + + boost::shared_ptr ps = boost::dynamic_pointer_cast (*i); + + if (ps) { + if (sources.find (ps) == sources.end()) { + /* (Playlist)Source not currently in + accumulating set, so recurse. + */ + ps->playlist()->deep_sources (sources); + } + } + + /* add this source */ + sources.insert (*i); + } + + for (SourceList::const_iterator i = _master_sources.begin(); i != _master_sources.end(); ++i) { + + boost::shared_ptr ps = boost::dynamic_pointer_cast (*i); + + if (ps) { + if (sources.find (ps) == sources.end()) { + /* (Playlist)Source not currently in + accumulating set, so recurse. + */ + ps->playlist()->deep_sources (sources); + } + } + + /* add this source */ + sources.insert (*i); + } +} + bool -Region::uses_source (boost::shared_ptr source) const +Region::uses_source (boost::shared_ptr source, bool shallow) const { for (SourceList::const_iterator i = _sources.begin(); i != _sources.end(); ++i) { if (*i == source) { return true; } - boost::shared_ptr ps = boost::dynamic_pointer_cast (*i); + if (!shallow) { + boost::shared_ptr ps = boost::dynamic_pointer_cast (*i); - if (ps) { - if (ps->playlist()->uses_source (source)) { - return true; + if (ps) { + if (ps->playlist()->uses_source (source)) { + return true; + } } } } @@ -1527,11 +1655,13 @@ Region::uses_source (boost::shared_ptr source) const return true; } - boost::shared_ptr ps = boost::dynamic_pointer_cast (*i); + if (!shallow) { + boost::shared_ptr ps = boost::dynamic_pointer_cast (*i); - if (ps) { - if (ps->playlist()->uses_source (source)) { - return true; + if (ps) { + if (ps->playlist()->uses_source (source)) { + return true; + } } } } @@ -1539,6 +1669,7 @@ Region::uses_source (boost::shared_ptr source) const return false; } + framecnt_t Region::source_length(uint32_t n) const { @@ -1779,13 +1910,11 @@ Region::is_compound () const void Region::post_set (const PropertyChange& pc) { - if (pc.contains (Properties::position)) { - recompute_position_from_lock_style (); - } + _quarter_note = _session.tempo_map().quarter_note_at_beat (_beat); } void -Region::set_start_internal (framecnt_t s) +Region::set_start_internal (framecnt_t s, const int32_t sub_num) { _start = s; } @@ -1818,4 +1947,3 @@ Region::latest_possible_frame () const return _position + (minlen - _start) - 1; } -