summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2012-05-10 18:17:47 +0000
committerPaul Davis <paul@linuxaudiosystems.com>2012-05-10 18:17:47 +0000
commit6e6b3d325bffe5b654f94cb3ef91c829786bc7a5 (patch)
tree758b387ea5fbed971660a8a166d5a87ee3778058
parent916202ea649fbc430b63afa3e93efde20c52de8a (diff)
trim a single other region when adjusting xfade length
git-svn-id: svn://localhost/ardour2/branches/3.0@12241 d708f5d6-7413-0410-9779-e7cbd77b26cf
-rw-r--r--libs/ardour/ardour/audioregion.h2
-rw-r--r--libs/ardour/ardour/region.h9
-rw-r--r--libs/ardour/audioregion.cc53
-rw-r--r--libs/ardour/region.cc30
4 files changed, 86 insertions, 8 deletions
diff --git a/libs/ardour/ardour/audioregion.h b/libs/ardour/ardour/audioregion.h
index fd6c3a8528..013629637d 100644
--- a/libs/ardour/ardour/audioregion.h
+++ b/libs/ardour/ardour/audioregion.h
@@ -238,6 +238,8 @@ class AudioRegion : public Region
bool _fade_in_is_xfade;
bool _fade_out_is_xfade;
+ boost::shared_ptr<ARDOUR::Region> get_single_other_xfade_region (bool start) const;
+
protected:
/* default constructor for derived (compound) types */
diff --git a/libs/ardour/ardour/region.h b/libs/ardour/ardour/region.h
index 788a8d90c9..1d7894fac5 100644
--- a/libs/ardour/ardour/region.h
+++ b/libs/ardour/ardour/region.h
@@ -141,6 +141,15 @@ class Region
framepos_t first_frame () const { return _position; }
framepos_t last_frame () const { return _position + _length - 1; }
+ /** Return the earliest possible value of _position given the
+ * value of _start within the region's sources
+ */
+ framepos_t earliest_possible_position () const;
+ /** Return the last possible value of _last_frame given the
+ * value of _startin the regions's sources
+ */
+ framepos_t latest_possible_frame () const;
+
Evoral::Range<framepos_t> last_range () const {
return Evoral::Range<framepos_t> (_last_position, _last_position + _last_length - 1);
}
diff --git a/libs/ardour/audioregion.cc b/libs/ardour/audioregion.cc
index 4ba383b37e..36d5cf0a8c 100644
--- a/libs/ardour/audioregion.cc
+++ b/libs/ardour/audioregion.cc
@@ -1148,6 +1148,20 @@ AudioRegion::set_fade_in_length (framecnt_t len)
if (_inverse_fade_in) {
_inverse_fade_in->extend_to (len);
}
+
+ if (_fade_in_is_xfade) {
+
+ /* trim a single other region below us to the new start
+ of the fade.
+ */
+
+ boost::shared_ptr<Region> other = get_single_other_xfade_region (true);
+ if (other) {
+ other->trim_end (position() + len);
+ }
+ }
+
+
_default_fade_in = false;
send_change (PropertyChange (Properties::fade_in));
}
@@ -1167,10 +1181,24 @@ AudioRegion::set_fade_out_length (framecnt_t len)
bool changed = _fade_out->extend_to (len);
if (changed) {
+
if (_inverse_fade_out) {
_inverse_fade_out->extend_to (len);
}
_default_fade_out = false;
+
+ if (_fade_out_is_xfade) {
+
+ /* trim a single other region below us to the new start
+ of the fade.
+ */
+
+ boost::shared_ptr<Region> other = get_single_other_xfade_region (false);
+ if (other) {
+ other->trim_front (last_frame() - len);
+ }
+ }
+
send_change (PropertyChange (Properties::fade_out));
}
}
@@ -1801,8 +1829,8 @@ AudioRegion::set_fade_out_is_xfade (bool yn)
_fade_out_is_xfade = yn;
}
-framecnt_t
-AudioRegion::verify_xfade_bounds (framecnt_t len, bool start)
+boost::shared_ptr<Region>
+AudioRegion::get_single_other_xfade_region (bool start) const
{
boost::shared_ptr<Playlist> pl (playlist());
@@ -1810,11 +1838,10 @@ AudioRegion::verify_xfade_bounds (framecnt_t len, bool start)
/* not currently in a playlist - xfade length is unbounded
(and irrelevant)
*/
- return len;
+ return boost::shared_ptr<AudioRegion> ();
}
boost::shared_ptr<RegionList> rl;
- framecnt_t maxlen;
if (start) {
rl = pl->regions_at (position());
@@ -1837,17 +1864,27 @@ AudioRegion::verify_xfade_bounds (framecnt_t len, bool start)
if (n != 2) {
/* zero or multiple regions stacked here - don't care about xfades */
- return len;
+ return boost::shared_ptr<AudioRegion> ();
}
+ return other;
+}
+
+framecnt_t
+AudioRegion::verify_xfade_bounds (framecnt_t len, bool start)
+{
+ boost::shared_ptr<Region> other = get_single_other_xfade_region (start);
+ framecnt_t maxlen;
+
/* we overlap a single region. clamp the length of an xfade to
- the duration of the overlap.
+ the maximum possible duration of the overlap (if the other
+ region were trimmed appropriately).
*/
if (start) {
- maxlen = other->last_frame() - position();
+ maxlen = other->latest_possible_frame() - position();
} else {
- maxlen = last_frame() - other->position();
+ maxlen = last_frame() - other->earliest_possible_position();
}
return min (maxlen, len);
diff --git a/libs/ardour/region.cc b/libs/ardour/region.cc
index efaa104d35..a4a1584792 100644
--- a/libs/ardour/region.cc
+++ b/libs/ardour/region.cc
@@ -1654,3 +1654,33 @@ Region::set_start_internal (framecnt_t s)
{
_start = s;
}
+
+framepos_t
+Region::earliest_possible_position () const
+{
+ if (_start > _position) {
+ return 0;
+ } else {
+ return _position - _start;
+ }
+}
+
+framecnt_t
+Region::latest_possible_frame () const
+{
+ framecnt_t minlen = max_framecnt;
+
+ for (SourceList::const_iterator i = _sources.begin(); i != _sources.end(); ++i) {
+ /* non-audio regions have a length that may vary based on their
+ * position, so we have to pass it in the call.
+ */
+ minlen = min (minlen, (*i)->length (_position));
+ }
+
+ /* the latest possible last frame is determined by the current
+ * position, plus the shortest source extent past _start.
+ */
+
+ return _position + (minlen - _start) - 1;
+}
+