2 Copyright (C) 2003-2006 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 #include <sigc++/bind.h>
22 #include <pbd/stacktrace.h>
24 #include <ardour/types.h>
25 #include <ardour/crossfade.h>
26 #include <ardour/crossfade_compare.h>
27 #include <ardour/audioregion.h>
28 #include <ardour/playlist.h>
29 #include <ardour/utils.h>
30 #include <ardour/session.h>
36 using namespace ARDOUR;
39 nframes_t Crossfade::_short_xfade_length = 0;
40 Change Crossfade::ActiveChanged = new_change();
41 Change Crossfade::FollowOverlapChanged = new_change();
43 /* XXX if and when we ever implement parallel processing of the process()
44 callback, these will need to be handled on a per-thread basis.
47 Sample* Crossfade::crossfade_buffer_out = 0;
48 Sample* Crossfade::crossfade_buffer_in = 0;
51 Crossfade::set_buffer_size (nframes_t sz)
53 if (crossfade_buffer_out) {
54 delete [] crossfade_buffer_out;
55 crossfade_buffer_out = 0;
58 if (crossfade_buffer_in) {
59 delete [] crossfade_buffer_in;
60 crossfade_buffer_in = 0;
64 crossfade_buffer_out = new Sample[sz];
65 crossfade_buffer_in = new Sample[sz];
70 Crossfade::operator== (const Crossfade& other)
72 return (_in == other._in) && (_out == other._out);
75 Crossfade::Crossfade (boost::shared_ptr<AudioRegion> in, boost::shared_ptr<AudioRegion> out,
79 : _fade_in (0.0, 2.0, 1.0), // linear (gain coefficient) => -inf..+6dB
80 _fade_out (0.0, 2.0, 1.0) // linear (gain coefficient) => -inf..+6dB
89 _follow_overlap = false;
91 _active = Config->get_xfades_active ();
97 Crossfade::Crossfade (boost::shared_ptr<AudioRegion> a, boost::shared_ptr<AudioRegion> b, CrossfadeModel model, bool act)
98 : _fade_in (0.0, 2.0, 1.0), // linear (gain coefficient) => -inf..+6dB
99 _fade_out (0.0, 2.0, 1.0) // linear (gain coefficient) => -inf..+6dB
103 _follow_overlap = false;
105 if (compute (a, b, model)) {
106 throw failed_constructor();
114 Crossfade::Crossfade (const Playlist& playlist, XMLNode& node)
115 : _fade_in (0.0, 2.0, 1.0), // linear (gain coefficient) => -inf..+6dB
116 _fade_out (0.0, 2.0, 1.0) // linear (gain coefficient) => -inf..+6dB
118 boost::shared_ptr<Region> r;
120 LocaleGuard lg (X_("POSIX"));
122 /* we have to find the in/out regions before we can do anything else */
124 if ((prop = node.property ("in")) == 0) {
125 error << _("Crossfade: no \"in\" region in state") << endmsg;
126 throw failed_constructor();
129 PBD::ID id (prop->value());
131 if ((r = playlist.find_region (id)) == 0) {
132 error << string_compose (_("Crossfade: no \"in\" region %1 found in playlist %2"), id, playlist.name())
134 throw failed_constructor();
137 if ((_in = boost::dynamic_pointer_cast<AudioRegion> (r)) == 0) {
138 throw failed_constructor();
141 if ((prop = node.property ("out")) == 0) {
142 error << _("Crossfade: no \"out\" region in state") << endmsg;
143 throw failed_constructor();
146 PBD::ID id2 (prop->value());
148 if ((r = playlist.find_region (id2)) == 0) {
149 error << string_compose (_("Crossfade: no \"out\" region %1 found in playlist %2"), id2, playlist.name())
151 throw failed_constructor();
154 if ((_out = boost::dynamic_pointer_cast<AudioRegion> (r)) == 0) {
155 throw failed_constructor();
159 _active = Config->get_xfades_active();
163 if (set_state (node)) {
164 throw failed_constructor();
167 /* we should not need to do this here, since all values were set via XML. however
168 some older sessions may have bugs and this allows us to fix them.
174 Crossfade::Crossfade (const Crossfade &orig, boost::shared_ptr<AudioRegion> newin, boost::shared_ptr<AudioRegion> newout)
175 : _fade_in(orig._fade_in),
176 _fade_out(orig._fade_out)
178 _active = orig._active;
179 _in_update = orig._in_update;
180 _length = orig._length;
181 _position = orig._position;
182 _anchor_point = orig._anchor_point;
183 _follow_overlap = orig._follow_overlap;
184 _fixed = orig._fixed;
189 // copied from Crossfade::initialize()
192 _out->suspend_fade_out ();
193 _in->suspend_fade_in ();
195 overlap_type = _in->coverage (_out->position(), _out->last_frame());
196 layer_relation = (int32_t) (_in->layer() - _out->layer());
198 // Let's make sure the fade isn't too long
203 Crossfade::~Crossfade ()
209 Crossfade::initialize ()
213 _out->suspend_fade_out ();
214 _in->suspend_fade_in ();
219 #define EQUAL_POWER_MINUS_3DB
220 #ifdef EQUAL_POWER_MINUS_3DB
222 _fade_out.add ((_length * 0.000000), 1.000000);
223 _fade_out.add ((_length * 0.166667), 0.948859);
224 _fade_out.add ((_length * 0.333333), 0.851507);
225 _fade_out.add ((_length * 0.500000), 0.707946);
226 _fade_out.add ((_length * 0.666667), 0.518174);
227 _fade_out.add ((_length * 0.833333), 0.282192);
228 _fade_out.add ((_length * 1.000000), 0.000000);
230 #else // EQUAL_POWER_MINUS_6DB
232 _fade_out.add ((_length * 0.000000), 1.000000);
233 _fade_out.add ((_length * 0.166667), 0.833033);
234 _fade_out.add ((_length * 0.333333), 0.666186);
235 _fade_out.add ((_length * 0.500000), 0.499459);
236 _fade_out.add ((_length * 0.666667), 0.332853);
237 _fade_out.add ((_length * 0.833333), 0.166366);
238 _fade_out.add ((_length * 1.000000), 0.000000);
246 #define EQUAL_POWER_MINUS_3DB
247 #ifdef EQUAL_POWER_MINUS_3DB
249 _fade_in.add ((_length * 0.000000), 0.000000);
250 _fade_in.add ((_length * 0.166667), 0.282192);
251 _fade_in.add ((_length * 0.333333), 0.518174);
252 _fade_in.add ((_length * 0.500000), 0.707946);
253 _fade_in.add ((_length * 0.666667), 0.851507);
254 _fade_in.add ((_length * 0.833333), 0.948859);
255 _fade_in.add ((_length * 1.000000), 1.000000);
257 #else // EQUAL_POWER_MINUS_SIX_DB
259 _fade_in.add ((_length * 0.000000), 0.000000);
260 _fade_in.add ((_length * 0.166667), 0.166366);
261 _fade_in.add ((_length * 0.333333), 0.332853);
262 _fade_in.add ((_length * 0.500000), 0.499459);
263 _fade_in.add ((_length * 0.666667), 0.666186);
264 _fade_in.add ((_length * 0.833333), 0.833033);
265 _fade_in.add ((_length * 1.000000), 1.000000);
271 overlap_type = _in->coverage (_out->position(), _out->last_frame());
272 layer_relation = (int32_t) (_in->layer() - _out->layer());
276 Crossfade::read_at (Sample *buf, Sample *mixdown_buffer,
277 float *gain_buffer, nframes_t start, nframes_t cnt, uint32_t chan_n,
278 nframes_t read_frames, nframes_t skip_frames)
287 if (start < _position) {
289 /* handle an initial section of the read area that we do not
293 offset = _position - start;
303 to_write = min (_length, cnt);
307 to_write = min (_length - (start - _position), cnt);
311 offset = start - _position;
313 /* Prevent data from piling up inthe crossfade buffers when reading a transparent region */
314 if (!(_out->opaque())) {
315 memset (crossfade_buffer_out, 0, sizeof (Sample) * to_write);
316 } else if (!(_in->opaque())) {
317 memset (crossfade_buffer_in, 0, sizeof (Sample) * to_write);
320 _out->read_at (crossfade_buffer_out, mixdown_buffer, gain_buffer, start, to_write, chan_n, read_frames, skip_frames);
321 _in->read_at (crossfade_buffer_in, mixdown_buffer, gain_buffer, start, to_write, chan_n, read_frames, skip_frames);
323 float* fiv = new float[to_write];
324 float* fov = new float[to_write];
326 _fade_in.get_vector (offset, offset+to_write, fiv, to_write);
327 _fade_out.get_vector (offset, offset+to_write, fov, to_write);
329 /* note: although we have not explicitly taken into account the return values
330 from _out->read_at() or _in->read_at(), the length() function does this
331 implicitly. why? because it computes a value based on the in+out regions'
332 position and length, and so we know precisely how much data they could return.
335 for (nframes_t n = 0; n < to_write; ++n) {
336 buf[n] = (crossfade_buffer_out[n] * fov[n]) + (crossfade_buffer_in[n] * fiv[n]);
346 Crossfade::coverage (nframes_t start, nframes_t end) const
348 nframes_t my_end = _position + _length;
350 if ((start >= _position) && (end <= my_end)) {
351 return OverlapInternal;
353 if ((end >= _position) && (end <= my_end)) {
356 if ((start >= _position) && (start <= my_end)) {
359 if ((_position >= start) && (_position <= end) && (my_end <= end)) {
360 return OverlapExternal;
366 Crossfade::set_active (bool yn)
370 StateChanged (ActiveChanged);
375 Crossfade::refresh ()
377 /* crossfades must be between non-muted regions */
379 if (_out->muted() || _in->muted()) {
380 Invalidated (shared_from_this());
384 /* Top layer shouldn't be transparent */
386 if (!((layer_relation > 0 ? _in : _out)->opaque())) {
387 Invalidated (shared_from_this());
391 /* layer ordering cannot change */
393 int32_t new_layer_relation = (int32_t) (_in->layer() - _out->layer());
395 if (new_layer_relation * layer_relation < 0) { // different sign, layers rotated
396 Invalidated (shared_from_this());
400 OverlapType ot = _in->coverage (_out->first_frame(), _out->last_frame());
402 if (ot == OverlapNone) {
403 Invalidated (shared_from_this());
409 if (ot != overlap_type) {
411 if (_follow_overlap) {
414 compute (_in, _out, Config->get_xfade_model());
417 catch (NoCrossfadeHere& err) {
418 Invalidated (shared_from_this());
426 Invalidated (shared_from_this());
432 send_signal = update ();
436 StateChanged (BoundsChanged); /* EMIT SIGNAL */
449 if (_follow_overlap) {
450 newlen = _out->first_frame() + _out->length() - _in->first_frame();
456 Invalidated (shared_from_this());
462 if ((_follow_overlap && newlen != _length) || (_length > newlen)) {
464 double factor = newlen / (double) _length;
466 _fade_out.x_scale (factor);
467 _fade_in.x_scale (factor);
472 switch (_anchor_point) {
474 _position = _in->first_frame();
478 _position = _in->last_frame() - _length + 1;
482 _position = _out->last_frame() - _length + 1;
489 Crossfade::compute (boost::shared_ptr<AudioRegion> a, boost::shared_ptr<AudioRegion> b, CrossfadeModel model)
491 boost::shared_ptr<AudioRegion> top;
492 boost::shared_ptr<AudioRegion> bottom;
493 nframes_t short_xfade_length;
495 short_xfade_length = _short_xfade_length;
497 if (a->layer() < b->layer()) {
505 /* first check for matching ends */
507 if (top->first_frame() == bottom->first_frame()) {
509 /* Both regions start at the same point */
511 if (top->last_frame() < bottom->last_frame()) {
513 /* top ends before bottom, so put an xfade
514 in at the end of top.
517 /* [-------- top ---------- ]
518 * {====== bottom =====================}
524 if (top->last_frame() < short_xfade_length) {
527 _position = top->last_frame() - short_xfade_length;
530 _length = min (short_xfade_length, top->length());
531 _follow_overlap = false;
532 _anchor_point = EndOfIn;
537 /* top ends after (or same time) as bottom - no xfade
540 /* [-------- top ------------------------ ]
541 * {====== bottom =====================}
544 throw NoCrossfadeHere();
547 } else if (top->last_frame() == bottom->last_frame()) {
549 /* Both regions end at the same point */
551 if (top->first_frame() > bottom->first_frame()) {
553 /* top starts after bottom, put an xfade in at the
557 /* [-------- top ---------- ]
558 * {====== bottom =====================}
563 _position = top->first_frame();
564 _length = min (short_xfade_length, top->length());
565 _follow_overlap = false;
566 _anchor_point = StartOfIn;
571 /* top starts before bottom - no xfade
574 /* [-------- top ------------------------ ]
575 * {====== bottom =====================}
578 throw NoCrossfadeHere();
583 /* OK, time to do more regular overlapping */
585 OverlapType ot = top->coverage (bottom->first_frame(), bottom->last_frame());
589 /* should be NOTREACHED as a precondition of creating
590 a new crossfade, but we need to handle it here.
592 throw NoCrossfadeHere();
595 case OverlapInternal:
596 case OverlapExternal:
597 /* should be NOTREACHED because of tests above */
598 throw NoCrossfadeHere();
601 case OverlapEnd: /* top covers start of bottom but ends within it */
603 /* [---- top ------------------------]
604 * { ==== bottom ============ }
609 _anchor_point = EndOfOut;
611 if (model == FullCrossfade) {
612 _position = bottom->first_frame(); // "{"
613 _length = _out->first_frame() + _out->length() - _in->first_frame();
614 /* leave active alone */
615 _follow_overlap = true;
617 _length = min (short_xfade_length, top->length());
618 _position = top->last_frame() - _length; // "]" - length
620 _follow_overlap = false;
625 case OverlapStart: /* top starts within bottom but covers bottom's end */
627 /* { ==== top ============ }
628 * [---- bottom -------------------]
633 _position = top->first_frame();
634 _anchor_point = StartOfIn;
636 if (model == FullCrossfade) {
637 _length = _out->first_frame() + _out->length() - _in->first_frame();
638 /* leave active alone */
639 _follow_overlap = true;
641 _length = min (short_xfade_length, top->length());
643 _follow_overlap = false;
655 Crossfade::get_state ()
657 XMLNode* node = new XMLNode (X_("Crossfade"));
660 LocaleGuard lg (X_("POSIX"));
662 _out->id().print (buf, sizeof (buf));
663 node->add_property ("out", buf);
664 _in->id().print (buf, sizeof (buf));
665 node->add_property ("in", buf);
666 node->add_property ("active", (_active ? "yes" : "no"));
667 node->add_property ("follow-overlap", (_follow_overlap ? "yes" : "no"));
668 node->add_property ("fixed", (_fixed ? "yes" : "no"));
669 snprintf (buf, sizeof(buf), "%" PRIu32, _length);
670 node->add_property ("length", buf);
671 snprintf (buf, sizeof(buf), "%" PRIu32, (uint32_t) _anchor_point);
672 node->add_property ("anchor-point", buf);
673 snprintf (buf, sizeof(buf), "%" PRIu32, (uint32_t) _position);
674 node->add_property ("position", buf);
676 child = node->add_child ("FadeIn");
678 for (AutomationList::iterator ii = _fade_in.begin(); ii != _fade_in.end(); ++ii) {
681 pnode = new XMLNode ("point");
683 snprintf (buf, sizeof (buf), "%" PRIu32, (nframes_t) floor ((*ii)->when));
684 pnode->add_property ("x", buf);
685 snprintf (buf, sizeof (buf), "%.12g", (*ii)->value);
686 pnode->add_property ("y", buf);
687 child->add_child_nocopy (*pnode);
690 child = node->add_child ("FadeOut");
692 for (AutomationList::iterator ii = _fade_out.begin(); ii != _fade_out.end(); ++ii) {
695 pnode = new XMLNode ("point");
697 snprintf (buf, sizeof (buf), "%" PRIu32, (nframes_t) floor ((*ii)->when));
698 pnode->add_property ("x", buf);
699 snprintf (buf, sizeof (buf), "%.12g", (*ii)->value);
700 pnode->add_property ("y", buf);
701 child->add_child_nocopy (*pnode);
708 Crossfade::set_state (const XMLNode& node)
710 XMLNodeConstIterator i;
711 XMLNodeList children;
714 const XMLProperty* prop;
715 LocaleGuard lg (X_("POSIX"));
716 Change what_changed = Change (0);
719 if ((prop = node.property ("position")) != 0) {
720 sscanf (prop->value().c_str(), "%" PRIu32, &val);
721 if (val != _position) {
723 what_changed = Change (what_changed | PositionChanged);
726 warning << _("old-style crossfade information - no position information") << endmsg;
727 _position = _in->first_frame();
730 if ((prop = node.property ("active")) != 0) {
731 bool x = string_is_affirmative (prop->value());
734 what_changed = Change (what_changed | ActiveChanged);
740 if ((prop = node.property ("follow-overlap")) != 0) {
741 _follow_overlap = string_is_affirmative (prop->value());
743 _follow_overlap = false;
746 if ((prop = node.property ("fixed")) != 0) {
747 _fixed = string_is_affirmative (prop->value());
752 if ((prop = node.property ("anchor-point")) != 0) {
753 _anchor_point = AnchorPoint (atoi ((prop->value().c_str())));
755 _anchor_point = StartOfIn;
758 if ((prop = node.property ("length")) != 0) {
760 sscanf (prop->value().c_str(), "%" PRIu32, &val);
761 if (val != _length) {
762 _length = atol (prop->value().c_str());
763 what_changed = Change (what_changed | LengthChanged);
768 /* XXX this branch is legacy code from before
769 the point where we stored xfade lengths.
772 if ((_length = overlap_length()) == 0) {
773 throw failed_constructor();
777 if ((fi = find_named_node (node, "FadeIn")) == 0) {
781 if ((fo = find_named_node (node, "FadeOut")) == 0) {
790 children = fi->children();
792 for (i = children.begin(); i != children.end(); ++i) {
793 if ((*i)->name() == "point") {
797 prop = (*i)->property ("x");
798 sscanf (prop->value().c_str(), "%" PRIu32, &x);
800 prop = (*i)->property ("y");
801 sscanf (prop->value().c_str(), "%f", &y);
814 children = fo->children();
816 for (i = children.begin(); i != children.end(); ++i) {
817 if ((*i)->name() == "point") {
822 prop = (*i)->property ("x");
823 sscanf (prop->value().c_str(), "%" PRIu32, &x);
825 prop = (*i)->property ("y");
826 sscanf (prop->value().c_str(), "%f", &y);
828 _fade_out.add (x, y);
834 StateChanged (what_changed); /* EMIT SIGNAL */
840 Crossfade::can_follow_overlap () const
846 Crossfade::set_follow_overlap (bool yn)
848 if (yn == _follow_overlap || _fixed) {
852 _follow_overlap = yn;
855 set_length (_short_xfade_length);
857 set_length (_out->first_frame() + _out->length() - _in->first_frame());
860 StateChanged (FollowOverlapChanged);
864 Crossfade::set_length (nframes_t len)
868 switch (_anchor_point) {
870 limit = _in->length();
874 limit = _in->length();
878 limit = _out->length();
883 len = min (limit, len);
885 double factor = len / (double) _length;
888 _fade_out.x_scale (factor);
889 _fade_in.x_scale (factor);
894 StateChanged (LengthChanged);
900 Crossfade::overlap_length () const
905 return _out->first_frame() + _out->length() - _in->first_frame();
909 Crossfade::set_short_xfade_length (nframes_t n)
911 _short_xfade_length = n;
915 Crossfade::invalidate ()
917 Invalidated (shared_from_this()); /* EMIT SIGNAL */