trim a single other region when adjusting xfade length
git-svn-id: svn://localhost/ardour2/branches/3.0@12241 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
916202ea64
commit
6e6b3d325b
@ -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 */
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user