summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gtk2_ardour/editor_drag.cc16
-rw-r--r--gtk2_ardour/editor_drag.h1
-rw-r--r--libs/ardour/ardour/audioregion.h2
-rw-r--r--libs/ardour/audioregion.cc53
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<Playlist> pl (playlist());
+
+ if (!pl) {
+ /* not currently in a playlist - xfade length is unbounded
+ (and irrelevant)
+ */
+ return len;
+ }
+
+ boost::shared_ptr<RegionList> rl;
+ framecnt_t maxlen;
+
+ if (start) {
+ rl = pl->regions_at (position());
+ } else {
+ rl = pl->regions_at (last_frame());
+ }
+
+ RegionList::iterator i;
+ boost::shared_ptr<Region> 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)