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.cc115
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 ();
+}
+