X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Fregion.cc;h=dcca313c7921fcbb406f7e69520b99509d2fcae1;hb=a4b8955f3eb87405ceafe5c8680d9439f441458e;hp=25435024b331cb5aa5c368a0c25301db9e64437f;hpb=6f8cd634501efd70711b148b4ac0e0ce2aa5cc95;p=ardour.git diff --git a/libs/ardour/region.cc b/libs/ardour/region.cc index 25435024b3..dcca313c79 100644 --- a/libs/ardour/region.cc +++ b/libs/ardour/region.cc @@ -27,17 +27,19 @@ #include #include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include +#include "pbd/xml++.h" +#include "pbd/stacktrace.h" +#include "pbd/enumwriter.h" + +#include "ardour/region.h" +#include "ardour/playlist.h" +#include "ardour/session.h" +#include "ardour/source.h" +#include "ardour/tempo.h" +#include "ardour/region_factory.h" +#include "ardour/filter.h" +#include "ardour/profile.h" +#include "ardour/utils.h" #include "i18n.h" @@ -57,7 +59,7 @@ sigc::signal > Region::RegionPropertyChan /* derived-from-derived constructor (no sources in constructor) */ Region::Region (Session& s, nframes_t start, nframes_t length, const string& name, DataType type, layer_t layer, Region::Flag flags) - : Automatable(s, name) + : SessionObject(s, name) , _type(type) , _flags(flags) , _start(start) @@ -70,6 +72,7 @@ Region::Region (Session& s, nframes_t start, nframes_t length, const string& nam , _first_edit(EditChangesNothing) , _frozen(0) , _stretch(1.0) + , _shift(1.0) , _read_data_count(0) , _pending_changed(Change (0)) , _last_layer_op(0) @@ -79,7 +82,7 @@ Region::Region (Session& s, nframes_t start, nframes_t length, const string& nam /** Basic Region constructor (single source) */ Region::Region (boost::shared_ptr src, nframes_t start, nframes_t length, const string& name, DataType type, layer_t layer, Region::Flag flags) - : Automatable(src->session(), name) + : SessionObject(src->session(), name) , _type(type) , _flags(flags) , _start(start) @@ -91,10 +94,10 @@ Region::Region (boost::shared_ptr src, nframes_t start, nframes_t length , _layer(layer) , _first_edit(EditChangesNothing) , _frozen(0) - , _ancestral_start (start) - , _ancestral_length (length) + , _ancestral_start (0) + , _ancestral_length (0) , _stretch (1.0) - , _shift (0.0) + , _shift (1.0) , _valid_transients(false) , _read_data_count(0) , _pending_changed(Change (0)) @@ -112,7 +115,7 @@ Region::Region (boost::shared_ptr src, nframes_t start, nframes_t length /** Basic Region constructor (many sources) */ Region::Region (const SourceList& srcs, nframes_t start, nframes_t length, const string& name, DataType type, layer_t layer, Region::Flag flags) - : Automatable(srcs.front()->session(), name) + : SessionObject(srcs.front()->session(), name) , _type(type) , _flags(flags) , _start(start) @@ -125,6 +128,7 @@ Region::Region (const SourceList& srcs, nframes_t start, nframes_t length, const , _first_edit(EditChangesNothing) , _frozen(0) , _stretch(1.0) + , _shift(1.0) , _read_data_count(0) , _pending_changed(Change (0)) , _last_layer_op(0) @@ -150,56 +154,96 @@ 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 other, nframes_t offset, nframes_t length, const string& name, layer_t layer, Flag flags) - : Automatable(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 (1.0) - , _shift (0.0) - , _valid_transients(false) - , _read_data_count(0) - , _pending_changed(Change (0)) - , _last_layer_op(0) + : SessionObject(other->session(), name) + , _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 > 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 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 */ Region::Region (boost::shared_ptr other) - : Automatable(other->session(), other->name()) + : SessionObject(other->session(), other->name()) , _type(other->data_type()) , _flags(Flag(other->_flags & ~(Locked|PositionLocked))) , _start(other->_start) @@ -211,10 +255,10 @@ Region::Region (boost::shared_ptr other) , _layer(other->_layer) , _first_edit(EditChangesID) , _frozen(0) - , _ancestral_start (_start) - , _ancestral_length (_length) - , _stretch (1.0) - , _shift (0.0) + , _ancestral_start (other->_ancestral_start) + , _ancestral_length (other->_ancestral_length) + , _stretch (other->_stretch) + , _shift (other->_shift) , _valid_transients(false) , _read_data_count(0) , _pending_changed(Change(0)) @@ -247,7 +291,7 @@ Region::Region (boost::shared_ptr other) } Region::Region (const SourceList& srcs, const XMLNode& node) - : Automatable(srcs.front()->session(), X_("error: XML did not reset this")) + : SessionObject(srcs.front()->session(), X_("error: XML did not reset this")) , _type(DataType::NIL) // to be loaded from XML , _flags(Flag(0)) , _start(0) @@ -260,6 +304,7 @@ Region::Region (const SourceList& srcs, const XMLNode& node) , _first_edit(EditChangesNothing) , _frozen(0) , _stretch(1.0) + , _shift(1.0) , _read_data_count(0) , _pending_changed(Change(0)) , _last_layer_op(0) @@ -288,7 +333,7 @@ Region::Region (const SourceList& srcs, const XMLNode& node) } Region::Region (boost::shared_ptr src, const XMLNode& node) - : Automatable(src->session(), X_("error: XML did not reset this")) + : SessionObject(src->session(), X_("error: XML did not reset this")) , _type(DataType::NIL) , _flags(Flag(0)) , _start(0) @@ -301,6 +346,7 @@ Region::Region (boost::shared_ptr src, const XMLNode& node) , _first_edit(EditChangesNothing) , _frozen(0) , _stretch(1.0) + , _shift(1.0) , _read_data_count(0) , _pending_changed(Change(0)) , _last_layer_op(0) @@ -332,6 +378,31 @@ Region::~Region () GoingAway (); /* EMIT SIGNAL */ } +void +Region::copy_stuff (boost::shared_ptr 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 wpl) { @@ -978,7 +1049,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); @@ -1098,7 +1169,7 @@ Region::state (bool full_state) break; } - node->add_property ("first_edit", fe); + node->add_property ("first-edit", fe); /* note: flags are stored by derived classes */ @@ -1241,22 +1312,35 @@ Region::set_live_state (const XMLNode& node, Change& what_changed, bool send) if ((prop = node.property ("stretch")) != 0) { _stretch = atof (prop->value()); + + /* 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()); + + /* fix problem with old sessions corrupted by an impossible + value for _shift + */ + if (_shift == 0.0) { + _shift = 1.0; + } } else { _shift = 1.0; } + /* note: derived classes set flags */ - if (_extra_xml) { - delete _extra_xml; - _extra_xml = 0; - } + delete _extra_xml; + _extra_xml = 0; for (XMLNodeConstIterator niter = nlist.begin(); niter != nlist.end(); ++niter) { @@ -1264,7 +1348,7 @@ Region::set_live_state (const XMLNode& node, Change& what_changed, bool send) child = (*niter); - if (child->name () == "extra") { + if (child->name () == "Extra") { _extra_xml = new XMLNode (*child); break; } @@ -1451,6 +1535,12 @@ Region::source_equivalent (boost::shared_ptr other) const return true; } +sframes_t +Region::source_length(uint32_t n) const +{ + return _sources[n]->length(_position - _start); +} + bool Region::verify_length (nframes_t len) { @@ -1461,7 +1551,7 @@ Region::verify_length (nframes_t len) nframes_t maxlen = 0; for (uint32_t n=0; n < _sources.size(); ++n) { - maxlen = max (maxlen, _sources[n]->length() - _start); + maxlen = max (maxlen, (nframes_t)source_length(n) - _start); } len = min (len, maxlen); @@ -1479,7 +1569,7 @@ Region::verify_start_and_length (nframes_t new_start, nframes_t& new_length) nframes_t maxlen = 0; for (uint32_t n=0; n < _sources.size(); ++n) { - maxlen = max (maxlen, _sources[n]->length() - new_start); + maxlen = max (maxlen, (nframes_t)source_length(n) - new_start); } new_length = min (new_length, maxlen); @@ -1495,7 +1585,7 @@ Region::verify_start (nframes_t pos) } for (uint32_t n=0; n < _sources.size(); ++n) { - if (pos > _sources[n]->length() - _length) { + if (pos > source_length(n) - _length) { return false; } } @@ -1510,8 +1600,8 @@ Region::verify_start_mutable (nframes_t& new_start) } for (uint32_t n=0; n < _sources.size(); ++n) { - if (new_start > _sources[n]->length() - _length) { - new_start = _sources[n]->length() - _length; + if (new_start > source_length(n) - _length) { + new_start = source_length(n) - _length; } } return true;