diff options
Diffstat (limited to 'libs/ardour/region.cc')
-rw-r--r-- | libs/ardour/region.cc | 152 |
1 files changed, 114 insertions, 38 deletions
diff --git a/libs/ardour/region.cc b/libs/ardour/region.cc index 982eb3e023..6375527664 100644 --- a/libs/ardour/region.cc +++ b/libs/ardour/region.cc @@ -38,6 +38,7 @@ #include <ardour/tempo.h> #include <ardour/region_factory.h> #include <ardour/filter.h> +#include <ardour/profile.h> #include "i18n.h" @@ -153,50 +154,90 @@ Region::Region (const SourceList& srcs, nframes_t start, nframes_t length, const /** Create a new Region from part of an existing one */ Region::Region (boost::shared_ptr<const Region> other, nframes_t offset, nframes_t length, const string& name, layer_t layer, Flag flags) : SessionObject(other->session(), name) - , _type(other->data_type()) - , _flags(Flag(flags & ~(Locked|PositionLocked|WholeFile|Hidden))) - , _start(other->_start + offset) - , _length(length) - , _position(0) - , _last_position(0) - , _positional_lock_style(other->_positional_lock_style) - , _sync_position(_start) - , _layer(layer) - , _first_edit(EditChangesNothing) - , _frozen(0) - , _ancestral_start (other->_ancestral_start + offset) - , _ancestral_length (length) - , _stretch (other->_stretch) - , _shift (other->_shift) - , _valid_transients(false) - , _read_data_count(0) - , _pending_changed(Change (0)) - , _last_layer_op(0) + , _type (other->data_type()) + { - if (other->_sync_position < offset) - _sync_position = other->_sync_position; + _start = other->_start + offset; + copy_stuff (other, offset, length, name, layer, flags); - set<boost::shared_ptr<Source> > unique_srcs; + /* if the other region had a distinct sync point + set, then continue to use it as best we can. + otherwise, reset sync point back to start. + */ - for (SourceList::const_iterator i= other->_sources.begin(); i != other->_sources.end(); ++i) { - _sources.push_back (*i); - (*i)->GoingAway.connect (bind (mem_fun (*this, &Region::source_deleted), (*i))); - unique_srcs.insert (*i); - } - - if (other->_sync_position < offset) { - _sync_position = other->_sync_position; + if (other->flags() & SyncMarked) { + if (other->_sync_position < _start) { + _flags = Flag (_flags & ~SyncMarked); + _sync_position = _start; + } else { + _sync_position = other->_sync_position; + } + } else { + _flags = Flag (_flags & ~SyncMarked); + _sync_position = _start; } + if (Profile->get_sae()) { + /* reset sync point to start if its ended up + outside region bounds. + */ - for (SourceList::const_iterator i = other->_master_sources.begin(); i != other->_master_sources.end(); ++i) { - if (unique_srcs.find (*i) == unique_srcs.end()) { - (*i)->GoingAway.connect (bind (mem_fun (*this, &Region::source_deleted), (*i))); + if (_sync_position < _start || _sync_position >= _start + _length) { + _flags = Flag (_flags & ~SyncMarked); + _sync_position = _start; } - _master_sources.push_back (*i); } +} + +Region::Region (boost::shared_ptr<const Region> other, nframes_t length, const string& name, layer_t layer, Flag flags) + : SessionObject(other->session(), name) + , _type (other->data_type()) +{ + /* create a new Region exactly like another but starting at 0 in its sources */ + + _start = 0; + copy_stuff (other, 0, length, name, layer, flags); + + /* 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 + _start and _sync_pos was in the other region. + + result is that our new sync pos points to the same point in our source(s) + as the sync in the other region did in its source(s). + + since we start at zero in our source(s), it is not possible to use a sync point that + is before the start. reset it to _start if that was true in the other region. + */ - assert(_sources.size() > 0); + if (other->flags() & SyncMarked) { + if (other->_start < other->_sync_position) { + /* sync pos was after the start point of the other region */ + _sync_position = other->_sync_position - other->_start; + } else { + /* sync pos was before the start point of the other region. not possible here. */ + _flags = Flag (_flags & ~SyncMarked); + _sync_position = _start; + } + } else { + _flags = Flag (_flags & ~SyncMarked); + _sync_position = _start; + } + + if (Profile->get_sae()) { + /* reset sync point to start if its ended up + outside region bounds. + */ + + if (_sync_position < _start || _sync_position >= _start + _length) { + _flags = Flag (_flags & ~SyncMarked); + _sync_position = _start; + } + } + + /* reset a couple of things that copy_stuff() gets wrong in this particular case */ + + _positional_lock_style = other->_positional_lock_style; + _first_edit = other->_first_edit; } /** Pure copy constructor */ @@ -337,6 +378,31 @@ Region::~Region () } void +Region::copy_stuff (boost::shared_ptr<const Region> other, nframes_t offset, nframes_t length, const string& name, layer_t layer, Flag flags) +{ + _frozen = 0; + _pending_changed = Change (0); + _read_data_count = 0; + _valid_transients = false; + + _length = length; + _last_length = length; + _sync_position = other->_sync_position; + _ancestral_start = other->_ancestral_start; + _ancestral_length = other->_ancestral_length; + _stretch = other->_stretch; + _shift = other->_shift; + _name = name; + _last_position = 0; + _position = 0; + _layer = layer; + _flags = Flag (flags & ~(Locked|WholeFile|Hidden)); + _first_edit = EditChangesNothing; + _last_layer_op = 0; + _positional_lock_style = AudioTime; +} + +void Region::set_playlist (boost::weak_ptr<Playlist> wpl) { boost::shared_ptr<Playlist> old_playlist = (_playlist.lock()); @@ -982,7 +1048,7 @@ Region::sync_offset (int& dir) const } nframes_t -Region::adjust_to_sync (nframes_t pos) +Region::adjust_to_sync (nframes_t pos) const { int sync_dir; nframes_t offset = sync_offset (sync_dir); @@ -1245,16 +1311,26 @@ Region::set_live_state (const XMLNode& node, Change& what_changed, bool send) if ((prop = node.property ("stretch")) != 0) { _stretch = atof (prop->value()); - if( _stretch == 0.0 ) + + /* fix problem with old sessions corrupted by an impossible + value for _stretch + */ + if (_stretch == 0.0) { _stretch = 1.0; + } } else { _stretch = 1.0; } if ((prop = node.property ("shift")) != 0) { _shift = atof (prop->value()); - if( _shift == 0.0 ) + + /* fix problem with old sessions corrupted by an impossible + value for _shift + */ + if (_shift == 0.0) { _shift = 1.0; + } } else { _shift = 1.0; } |