+ } else {
+ /* top ends after (or same time) as bottom - no xfade
+ */
+
+ /* [-------- top ------------------------ ]
+ * {====== bottom =====================}
+ */
+
+ throw NoCrossfadeHere();
+ }
+
+ } else if (top->last_frame() == bottom->last_frame()) {
+
+ /* Both regions end at the same point */
+
+ if (top->first_frame() > bottom->first_frame()) {
+
+ /* top starts after bottom, put an xfade in at the
+ start of top
+ */
+
+ /* [-------- top ---------- ]
+ * {====== bottom =====================}
+ */
+
+ _in = top;
+ _out = bottom;
+ _position = top->first_frame();
+ _length = min (short_xfade_length, top->length());
+ _follow_overlap = false;
+ _anchor_point = StartOfIn;
+ _active = true;
+ _fixed = true;
+
+ } else {
+ /* top starts before bottom - no xfade
+ */
+
+ /* [-------- top ------------------------ ]
+ * {====== bottom =====================}
+ */
+
+ throw NoCrossfadeHere();
+ }
+
+ } else {
+
+ /* OK, time to do more regular overlapping */
+
+ OverlapType ot = top->coverage (bottom->first_frame(), bottom->last_frame());
+
+ switch (ot) {
+ case OverlapNone:
+ /* should be NOTREACHED as a precondition of creating
+ a new crossfade, but we need to handle it here.
+ */
+ throw NoCrossfadeHere();
+ break;
+
+ case OverlapInternal:
+ case OverlapExternal:
+ /* should be NOTREACHED because of tests above */
+ throw NoCrossfadeHere();
+ break;
+
+ case OverlapEnd: /* top covers start of bottom but ends within it */
+
+ /* [---- top ------------------------]
+ * { ==== bottom ============ }
+ */
+
+ _in = bottom;
+ _out = top;
+ _anchor_point = EndOfOut;
+
+ if (model == FullCrossfade) {
+ _position = bottom->first_frame(); // "{"
+ _length = _out->first_frame() + _out->length() - _in->first_frame();
+ /* leave active alone */
+ _follow_overlap = true;
+ } else {
+ _length = min (short_xfade_length, top->length());
+ _position = top->last_frame() - _length; // "]" - length
+ _active = true;
+ _follow_overlap = false;
+
+ }
+ break;
+
+ case OverlapStart: /* top starts within bottom but covers bottom's end */
+
+ /* { ==== top ============ }
+ * [---- bottom -------------------]
+ */
+
+ _in = top;
+ _out = bottom;
+ _position = top->first_frame();
+ _anchor_point = StartOfIn;
+
+ if (model == FullCrossfade) {
+ _length = _out->first_frame() + _out->length() - _in->first_frame();
+ /* leave active alone */
+ _follow_overlap = true;
+ } else {
+ _length = min (short_xfade_length, top->length());
+ _active = true;
+ _follow_overlap = false;
+
+ }
+
+ break;
+ }
+ }
+
+ return 0;