diff options
Diffstat (limited to 'libs/ardour/region.cc')
-rw-r--r-- | libs/ardour/region.cc | 115 |
1 files changed, 111 insertions, 4 deletions
diff --git a/libs/ardour/region.cc b/libs/ardour/region.cc index 054e85cd2f..2193a69908 100644 --- a/libs/ardour/region.cc +++ b/libs/ardour/region.cc @@ -21,6 +21,7 @@ #include <cmath> #include <climits> #include <algorithm> +#include <sstream> #include <sigc++/bind.h> #include <sigc++/class_slot.h> @@ -28,11 +29,13 @@ #include <glibmm/thread.h> #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> @@ -59,6 +62,8 @@ Region::Region (Session& s, nframes_t start, nframes_t length, const string& nam , _start(start) , _length(length) , _position(0) + , _last_position(0) + , _positional_lock_style(AudioTime) , _sync_position(_start) , _layer(layer) , _first_edit(EditChangesNothing) @@ -70,7 +75,6 @@ Region::Region (Session& s, nframes_t start, nframes_t length, const string& nam /* no sources at this point */ } - /** Basic Region constructor (single source) */ Region::Region (boost::shared_ptr<Source> src, nframes_t start, nframes_t length, const string& name, DataType type, layer_t layer, Region::Flag flags) : Automatable(src->session(), name) @@ -79,6 +83,8 @@ Region::Region (boost::shared_ptr<Source> src, nframes_t start, nframes_t length , _start(start) , _length(length) , _position(0) + , _last_position(0) + , _positional_lock_style(AudioTime) , _sync_position(_start) , _layer(layer) , _first_edit(EditChangesNothing) @@ -86,6 +92,8 @@ Region::Region (boost::shared_ptr<Source> src, nframes_t start, nframes_t length , _ancestral_start (start) , _ancestral_length (length) , _stretch (1.0) + , _shift (0.0) + , _valid_transients(false) , _read_data_count(0) , _pending_changed(Change (0)) , _last_layer_op(0) @@ -96,6 +104,7 @@ Region::Region (boost::shared_ptr<Source> src, nframes_t start, nframes_t length src->GoingAway.connect (bind (mem_fun (*this, &Region::source_deleted), src)); assert(_sources.size() > 0); + _positional_lock_style = AudioTime; } /** Basic Region constructor (many sources) */ @@ -106,6 +115,8 @@ Region::Region (const SourceList& srcs, nframes_t start, nframes_t length, const , _start(start) , _length(length) , _position(0) + , _last_position(0) + , _positional_lock_style(AudioTime) , _sync_position(_start) , _layer(layer) , _first_edit(EditChangesNothing) @@ -141,6 +152,8 @@ Region::Region (boost::shared_ptr<const Region> other, nframes_t offset, nframes , _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) @@ -148,6 +161,8 @@ Region::Region (boost::shared_ptr<const Region> other, nframes_t offset, nframes , _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) @@ -185,6 +200,8 @@ Region::Region (boost::shared_ptr<const Region> other) , _start(other->_start) , _length(other->_length) , _position(other->_position) + , _last_position(other->_last_position) + , _positional_lock_style(other->_positional_lock_style) , _sync_position(other->_sync_position) , _layer(other->_layer) , _first_edit(EditChangesID) @@ -192,6 +209,8 @@ Region::Region (boost::shared_ptr<const Region> other) , _ancestral_start (_start) , _ancestral_length (_length) , _stretch (1.0) + , _shift (0.0) + , _valid_transients(false) , _read_data_count(0) , _pending_changed(Change(0)) , _last_layer_op(other->_last_layer_op) @@ -229,6 +248,8 @@ Region::Region (const SourceList& srcs, const XMLNode& node) , _start(0) , _length(0) , _position(0) + , _last_position(0) + , _positional_lock_style(AudioTime) , _sync_position(_start) , _layer(0) , _first_edit(EditChangesNothing) @@ -267,6 +288,8 @@ Region::Region (boost::shared_ptr<Source> src, const XMLNode& node) , _start(0) , _length(0) , _position(0) + , _last_position(0) + , _positional_lock_style(AudioTime) , _sync_position(_start) , _layer(0) , _first_edit(EditChangesNothing) @@ -373,6 +396,7 @@ Region::set_length (nframes_t len, void *src) first_edit (); maybe_uncopy (); + invalidate_transients (); if (!_frozen) { recompute_at_end (); @@ -450,12 +474,49 @@ Region::special_set_position (nframes_t pos) } void +Region::set_position_lock_style (PositionLockStyle ps) +{ + boost::shared_ptr<Playlist> pl (playlist()); + + if (!pl) { + return; + } + + _positional_lock_style = ps; + + if (_positional_lock_style == MusicTime) { + pl->session().tempo_map().bbt_time (_position, _bbt_time); + } + +} + +void +Region::update_position_after_tempo_map_change () +{ + boost::shared_ptr<Playlist> pl (playlist()); + + if (!pl || _positional_lock_style != MusicTime) { + return; + } + + TempoMap& map (pl->session().tempo_map()); + nframes_t pos = map.frame_time (_bbt_time); + set_position_internal (pos, false); +} + +void Region::set_position (nframes_t pos, void *src) { if (!can_move()) { return; } + set_position_internal (pos, true); +} + +void +Region::set_position_internal (nframes_t pos, bool allow_bbt_recompute) +{ if (_position != pos) { _last_position = _position; _position = pos; @@ -470,6 +531,15 @@ Region::set_position (nframes_t pos, void *src) _last_length = _length; _length = max_frames - _position; } + + if (allow_bbt_recompute && _positional_lock_style == MusicTime) { + boost::shared_ptr<Playlist> pl (playlist()); + if (pl) { + pl->session().tempo_map().bbt_time (_position, _bbt_time); + } + } + + invalidate_transients (); } /* do this even if the position is the same. this helps out @@ -563,6 +633,7 @@ Region::set_start (nframes_t pos, void *src) _start = pos; _flags = Region::Flag (_flags & ~WholeFile); first_edit (); + invalidate_transients (); send_change (StartChanged); } @@ -974,9 +1045,9 @@ Region::state (bool full_state) node->add_property ("length", buf); snprintf (buf, sizeof (buf), "%u", _position); node->add_property ("position", buf); - snprintf (buf, sizeof (buf), "%Ld", _ancestral_start); + snprintf (buf, sizeof (buf), "%" PRIi64, _ancestral_start); node->add_property ("ancestral-start", buf); - snprintf (buf, sizeof (buf), "%Ld", _ancestral_length); + snprintf (buf, sizeof (buf), "%" PRIi64, _ancestral_length); node->add_property ("ancestral-length", buf); snprintf (buf, sizeof (buf), "%.12g", _stretch); node->add_property ("stretch", buf); @@ -1007,6 +1078,13 @@ Region::state (bool full_state) snprintf (buf, sizeof (buf), "%" PRIu32, _sync_position); node->add_property ("sync-position", buf); + if (_positional_lock_style != AudioTime) { + node->add_property ("positional-lock-style", enum_2_string (_positional_lock_style)); + stringstream str; + str << _bbt_time; + node->add_property ("bbt-position", str.str()); + } + return *node; } @@ -1095,6 +1173,27 @@ Region::set_live_state (const XMLNode& node, Change& what_changed, bool send) _sync_position = _start; } + if ((prop = node.property ("positional-lock-style")) != 0) { + _positional_lock_style = PositionLockStyle (string_2_enum (prop->value(), _positional_lock_style)); + + if (_positional_lock_style == MusicTime) { + if ((prop = node.property ("bbt-position")) == 0) { + /* missing BBT info, revert to audio time locking */ + _positional_lock_style = AudioTime; + } else { + if (sscanf (prop->value().c_str(), "%d|%d|%d", + &_bbt_time.bars, + &_bbt_time.beats, + &_bbt_time.ticks) != 3) { + _positional_lock_style = AudioTime; + } + } + } + + } else { + _positional_lock_style = AudioTime; + } + /* XXX FIRST EDIT !!! */ /* these 3 properties never change as a result of any editing */ @@ -1261,7 +1360,8 @@ Region::region_list_equivalent (boost::shared_ptr<const Region> other) const void Region::source_deleted (boost::shared_ptr<Source>) { - delete this; + _sources.clear (); + drop_references (); } vector<string> @@ -1397,3 +1497,10 @@ Region::apply (Filter& filter) } +void +Region::invalidate_transients () +{ + _valid_transients = false; + _transients.clear (); +} + |