From da7215e1ad6ebcf99cf5874cf676c460dcbb7ee7 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Thu, 10 May 2012 12:14:26 +0000 Subject: [PATCH] if an xfade involves only 2 regions, clamp its length to the overlap between them git-svn-id: svn://localhost/ardour2/branches/3.0@12238 d708f5d6-7413-0410-9779-e7cbd77b26cf --- gtk2_ardour/editor_drag.cc | 16 +++++----- gtk2_ardour/editor_drag.h | 1 - libs/ardour/ardour/audioregion.h | 2 ++ libs/ardour/audioregion.cc | 53 ++++++++++++++++++++++++++++++++ 4 files changed, 63 insertions(+), 9 deletions(-) diff --git a/gtk2_ardour/editor_drag.cc b/gtk2_ardour/editor_drag.cc index a075008d20..e9ab0d3a60 100644 --- a/gtk2_ardour/editor_drag.cc +++ b/gtk2_ardour/editor_drag.cc @@ -4559,12 +4559,6 @@ CrossfadeEdgeDrag::CrossfadeEdgeDrag (Editor* e, AudioRegionView* rv, ArdourCanv , arv (rv) , start (start_yn) { - cerr << "new xfade drag\n"; -} - -CrossfadeEdgeDrag::~CrossfadeEdgeDrag () -{ - cerr << "destory xfade drag\n"; } void @@ -4590,8 +4584,14 @@ CrossfadeEdgeDrag::motion (GdkEvent*, bool) len = ar->fade_out()->back()->when; } + /* how long should it be ? */ + new_length = len + _editor->unit_to_frame (distance); - + + /* now check with the region that this is legal */ + + new_length = ar->verify_xfade_bounds (new_length, start); + if (start) { arv->redraw_start_xfade_to (ar, new_length); } else { @@ -4616,7 +4616,7 @@ CrossfadeEdgeDrag::finished (GdkEvent*, bool) len = ar->fade_out()->back()->when; } - new_length = len + _editor->unit_to_frame (distance); + new_length = ar->verify_xfade_bounds (len + _editor->unit_to_frame (distance), start); if (start) { ar->set_fade_in_length (new_length); diff --git a/gtk2_ardour/editor_drag.h b/gtk2_ardour/editor_drag.h index 70ec45ac99..724c2eb355 100644 --- a/gtk2_ardour/editor_drag.h +++ b/gtk2_ardour/editor_drag.h @@ -978,7 +978,6 @@ class CrossfadeEdgeDrag : public Drag { public: CrossfadeEdgeDrag (Editor*, AudioRegionView*, ArdourCanvas::Item*, bool start); - ~CrossfadeEdgeDrag (); void start_grab (GdkEvent*, Gdk::Cursor* c = 0); void motion (GdkEvent*, bool); diff --git a/libs/ardour/ardour/audioregion.h b/libs/ardour/ardour/audioregion.h index fe9f991ed0..fd6c3a8528 100644 --- a/libs/ardour/ardour/audioregion.h +++ b/libs/ardour/ardour/audioregion.h @@ -142,6 +142,8 @@ class AudioRegion : public Region void set_default_fade_in (); void set_default_fade_out (); + + framecnt_t verify_xfade_bounds (framecnt_t, bool start); void set_envelope_active (bool yn); void set_default_envelope (); diff --git a/libs/ardour/audioregion.cc b/libs/ardour/audioregion.cc index e217783760..4ba383b37e 100644 --- a/libs/ardour/audioregion.cc +++ b/libs/ardour/audioregion.cc @@ -1801,6 +1801,59 @@ 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 pl (playlist()); + + if (!pl) { + /* not currently in a playlist - xfade length is unbounded + (and irrelevant) + */ + return len; + } + + boost::shared_ptr rl; + framecnt_t maxlen; + + if (start) { + rl = pl->regions_at (position()); + } else { + rl = pl->regions_at (last_frame()); + } + + RegionList::iterator i; + boost::shared_ptr other; + uint32_t n = 0; + + /* count and find the other region in a single pass through the list */ + + for (i = rl->begin(); i != rl->end(); ++i) { + if ((*i).get() != this) { + other = *i; + } + ++n; + } + + if (n != 2) { + /* zero or multiple regions stacked here - don't care about xfades */ + return len; + } + + /* we overlap a single region. clamp the length of an xfade to + the duration of the overlap. + */ + + if (start) { + maxlen = other->last_frame() - position(); + } else { + maxlen = last_frame() - other->position(); + } + + return min (maxlen, len); + +} + extern "C" { int region_read_peaks_from_c (void *arg, uint32_t npeaks, uint32_t start, uint32_t cnt, intptr_t data, uint32_t n_chan, double samples_per_unit)