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.cc152
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;
}