2 Copyright (C) 2003 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.
24 #include "ardour/types.h"
25 #include "ardour/debug.h"
26 #include "ardour/configuration.h"
27 #include "ardour/audioplaylist.h"
28 #include "ardour/audioregion.h"
29 #include "ardour/crossfade.h"
30 #include "ardour/session.h"
31 #include "pbd/enumwriter.h"
35 using namespace ARDOUR;
40 namespace Properties {
41 PBD::PropertyDescriptor<bool> crossfades;
46 AudioPlaylist::make_property_quarks ()
48 Properties::crossfades.property_id = g_quark_from_static_string (X_("crossfades"));
49 DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for crossfades = %1\n", Properties::crossfades.property_id));
52 CrossfadeListProperty::CrossfadeListProperty (AudioPlaylist& pl)
53 : SequenceProperty<std::list<boost::shared_ptr<Crossfade> > > (Properties::crossfades.property_id, boost::bind (&AudioPlaylist::update, &pl, _1))
59 CrossfadeListProperty::CrossfadeListProperty (CrossfadeListProperty const & p)
60 : PBD::SequenceProperty<std::list<boost::shared_ptr<Crossfade> > > (p)
61 , _playlist (p._playlist)
67 CrossfadeListProperty *
68 CrossfadeListProperty::create () const
70 return new CrossfadeListProperty (_playlist);
73 CrossfadeListProperty *
74 CrossfadeListProperty::clone () const
76 return new CrossfadeListProperty (*this);
80 CrossfadeListProperty::get_content_as_xml (boost::shared_ptr<Crossfade> xfade, XMLNode & node) const
82 /* Crossfades are not written to any state when they are no
83 longer in use, so we must write their state here.
86 XMLNode& c = xfade->get_state ();
87 node.add_child_nocopy (c);
90 boost::shared_ptr<Crossfade>
91 CrossfadeListProperty::get_content_from_xml (XMLNode const & node) const
93 XMLNodeList const c = node.children ();
94 assert (c.size() == 1);
95 return boost::shared_ptr<Crossfade> (new Crossfade (_playlist, *c.front()));
99 AudioPlaylist::AudioPlaylist (Session& session, const XMLNode& node, bool hidden)
100 : Playlist (session, node, DataType::AUDIO, hidden)
101 , _crossfades (*this)
104 const XMLProperty* prop = node.property("type");
105 assert(!prop || DataType(prop->value()) == DataType::AUDIO);
108 add_property (_crossfades);
111 set_state (node, Stateful::loading_state_version);
115 AudioPlaylist::AudioPlaylist (Session& session, string name, bool hidden)
116 : Playlist (session, name, DataType::AUDIO, hidden)
117 , _crossfades (*this)
119 add_property (_crossfades);
122 AudioPlaylist::AudioPlaylist (boost::shared_ptr<const AudioPlaylist> other, string name, bool hidden)
123 : Playlist (other, name, hidden)
124 , _crossfades (*this)
126 add_property (_crossfades);
128 RegionList::const_iterator in_o = other->regions.begin();
129 RegionList::iterator in_n = regions.begin();
131 while (in_o != other->regions.end()) {
132 boost::shared_ptr<AudioRegion> ar = boost::dynamic_pointer_cast<AudioRegion>(*in_o);
134 // We look only for crossfades which begin with the current region, so we don't get doubles
135 for (Crossfades::const_iterator xfades = other->_crossfades.begin(); xfades != other->_crossfades.end(); ++xfades) {
136 if ((*xfades)->in() == ar) {
137 // We found one! Now copy it!
139 RegionList::const_iterator out_o = other->regions.begin();
140 RegionList::const_iterator out_n = regions.begin();
142 while (out_o != other->regions.end()) {
144 boost::shared_ptr<AudioRegion>ar2 = boost::dynamic_pointer_cast<AudioRegion>(*out_o);
146 if ((*xfades)->out() == ar2) {
147 boost::shared_ptr<AudioRegion>in = boost::dynamic_pointer_cast<AudioRegion>(*in_n);
148 boost::shared_ptr<AudioRegion>out = boost::dynamic_pointer_cast<AudioRegion>(*out_n);
149 boost::shared_ptr<Crossfade> new_fade = boost::shared_ptr<Crossfade> (new Crossfade (*xfades, in, out));
150 add_crossfade(new_fade);
157 // cerr << "HUH!? second region in the crossfade not found!" << endl;
166 AudioPlaylist::AudioPlaylist (boost::shared_ptr<const AudioPlaylist> other, framepos_t start, framecnt_t cnt, string name, bool hidden)
167 : Playlist (other, start, cnt, name, hidden)
168 , _crossfades (*this)
170 RegionLock rlock2 (const_cast<AudioPlaylist*> (other.get()));
173 add_property (_crossfades);
175 framepos_t const end = start + cnt - 1;
177 /* Audio regions that have been created by the Playlist constructor
178 will currently have the same fade in/out as the regions that they
179 were created from. This is wrong, so reset the fades here.
182 RegionList::iterator ours = regions.begin ();
184 for (RegionList::const_iterator i = other->regions.begin(); i != other->regions.end(); ++i) {
185 boost::shared_ptr<AudioRegion> region = boost::dynamic_pointer_cast<AudioRegion> (*i);
188 framecnt_t fade_in = 64;
189 framecnt_t fade_out = 64;
191 switch (region->coverage (start, end)) {
195 case OverlapInternal:
197 framecnt_t const offset = start - region->position ();
198 framecnt_t const trim = region->last_frame() - end;
199 if (region->fade_in()->back()->when > offset) {
200 fade_in = region->fade_in()->back()->when - offset;
202 if (region->fade_out()->back()->when > trim) {
203 fade_out = region->fade_out()->back()->when - trim;
210 if (region->fade_in()->back()->when > 0) {
211 fade_in = region->fade_in()->back()->when;
213 if (start > region->last_frame() - region->fade_out()->back()->when) {
214 fade_out = region->last_frame() - start;
221 framecnt_t const offset = start - region->position();
222 if (region->fade_in()->back()->when > offset) {
223 fade_in = region->fade_in()->back()->when - offset;
225 if (start > region->last_frame() - region->fade_out()->back()->when) {
226 fade_out = region->last_frame() - start;
228 fade_out = region->fade_out()->back()->when;
233 case OverlapExternal:
234 fade_in = region->fade_in()->back()->when;
235 fade_out = region->fade_out()->back()->when;
239 boost::shared_ptr<AudioRegion> our_region = boost::dynamic_pointer_cast<AudioRegion> (*ours);
242 our_region->set_fade_in_length (fade_in);
243 our_region->set_fade_out_length (fade_out);
249 /* this constructor does NOT notify others (session) */
252 AudioPlaylist::~AudioPlaylist ()
254 _crossfades.clear ();
257 struct RegionSortByLayer {
258 bool operator() (boost::shared_ptr<Region> a, boost::shared_ptr<Region> b) {
259 return a->layer() < b->layer();
264 AudioPlaylist::read (Sample *buf, Sample *mixdown_buffer, float *gain_buffer, framepos_t start,
265 framecnt_t cnt, unsigned chan_n)
267 framecnt_t ret = cnt;
269 /* optimizing this memset() away involves a lot of conditionals
270 that may well cause more of a hit due to cache misses
271 and related stuff than just doing this here.
273 it would be great if someone could measure this
276 one way or another, parts of the requested area
277 that are not written to by Region::region_at()
278 for all Regions that cover the area need to be
282 memset (buf, 0, sizeof (Sample) * cnt);
284 /* this function is never called from a realtime thread, so
285 its OK to block (for short intervals).
288 Glib::RecMutex::Lock rm (region_lock);
290 framepos_t const end = start + cnt - 1;
291 framecnt_t read_frames = 0;
292 framecnt_t skip_frames = 0;
293 _read_data_count = 0;
295 _read_data_count = 0;
297 RegionList* rlist = regions_to_read (start, start+cnt);
299 if (rlist->empty()) {
304 map<uint32_t,vector<boost::shared_ptr<Region> > > relevant_regions;
305 map<uint32_t,vector<boost::shared_ptr<Crossfade> > > relevant_xfades;
306 vector<uint32_t> relevant_layers;
308 for (RegionList::iterator i = rlist->begin(); i != rlist->end(); ++i) {
309 if ((*i)->coverage (start, end) != OverlapNone) {
310 relevant_regions[(*i)->layer()].push_back (*i);
311 relevant_layers.push_back ((*i)->layer());
315 for (Crossfades::iterator i = _crossfades.begin(); i != _crossfades.end(); ++i) {
316 if ((*i)->coverage (start, end) != OverlapNone) {
317 relevant_xfades[(*i)->upper_layer()].push_back (*i);
321 // RegionSortByLayer layer_cmp;
322 // relevant_regions.sort (layer_cmp);
324 /* XXX this whole per-layer approach is a hack that
325 should be removed once Crossfades become
326 CrossfadeRegions and we just grab a list of relevant
327 regions and call read_at() on all of them.
330 sort (relevant_layers.begin(), relevant_layers.end());
332 for (vector<uint32_t>::iterator l = relevant_layers.begin(); l != relevant_layers.end(); ++l) {
334 vector<boost::shared_ptr<Region> > r (relevant_regions[*l]);
335 vector<boost::shared_ptr<Crossfade> >& x (relevant_xfades[*l]);
338 for (vector<boost::shared_ptr<Region> >::iterator i = r.begin(); i != r.end(); ++i) {
339 boost::shared_ptr<AudioRegion> ar = boost::dynamic_pointer_cast<AudioRegion>(*i);
340 DEBUG_TRACE (DEBUG::AudioPlayback, string_compose ("read from region %1\n", ar->name()));
342 ar->read_at (buf, mixdown_buffer, gain_buffer, start, cnt, chan_n, read_frames, skip_frames);
343 _read_data_count += ar->read_data_count();
346 for (vector<boost::shared_ptr<Crossfade> >::iterator i = x.begin(); i != x.end(); ++i) {
347 (*i)->read_at (buf, mixdown_buffer, gain_buffer, start, cnt, chan_n);
349 /* don't JACK up _read_data_count, since its the same data as we just
350 read from the regions, and the OS should handle that for us.
361 AudioPlaylist::remove_dependents (boost::shared_ptr<Region> region)
363 boost::shared_ptr<AudioRegion> r = boost::dynamic_pointer_cast<AudioRegion> (region);
370 fatal << _("programming error: non-audio Region passed to remove_overlap in audio playlist")
375 for (Crossfades::iterator i = _crossfades.begin(); i != _crossfades.end(); ) {
377 if ((*i)->involves (r)) {
378 i = _crossfades.erase (i);
387 AudioPlaylist::flush_notifications (bool from_undo)
389 Playlist::flush_notifications (from_undo);
397 Crossfades::iterator a;
398 for (a = _pending_xfade_adds.begin(); a != _pending_xfade_adds.end(); ++a) {
399 NewCrossfade (*a); /* EMIT SIGNAL */
402 _pending_xfade_adds.clear ();
408 AudioPlaylist::refresh_dependents (boost::shared_ptr<Region> r)
410 boost::shared_ptr<AudioRegion> ar = boost::dynamic_pointer_cast<AudioRegion>(r);
411 set<boost::shared_ptr<Crossfade> > updated;
417 for (Crossfades::iterator x = _crossfades.begin(); x != _crossfades.end();) {
419 Crossfades::iterator tmp;
424 /* only update them once */
426 if ((*x)->involves (ar)) {
428 pair<set<boost::shared_ptr<Crossfade> >::iterator, bool> const u = updated.insert (*x);
431 /* x was successfully inserted into the set, so it has not already been updated */
436 catch (Crossfade::NoCrossfadeHere& err) {
437 // relax, Invalidated during refresh
447 AudioPlaylist::finalize_split_region (boost::shared_ptr<Region> o, boost::shared_ptr<Region> l, boost::shared_ptr<Region> r)
449 boost::shared_ptr<AudioRegion> orig = boost::dynamic_pointer_cast<AudioRegion>(o);
450 boost::shared_ptr<AudioRegion> left = boost::dynamic_pointer_cast<AudioRegion>(l);
451 boost::shared_ptr<AudioRegion> right = boost::dynamic_pointer_cast<AudioRegion>(r);
453 for (Crossfades::iterator x = _crossfades.begin(); x != _crossfades.end();) {
454 Crossfades::iterator tmp;
458 boost::shared_ptr<Crossfade> fade;
460 if ((*x)->_in == orig) {
461 if (! (*x)->covers(right->position())) {
462 fade = boost::shared_ptr<Crossfade> (new Crossfade (*x, left, (*x)->_out));
464 // Overlap, the crossfade is copied on the left side of the right region instead
465 fade = boost::shared_ptr<Crossfade> (new Crossfade (*x, right, (*x)->_out));
469 if ((*x)->_out == orig) {
470 if (! (*x)->covers(right->position())) {
471 fade = boost::shared_ptr<Crossfade> (new Crossfade (*x, (*x)->_in, right));
473 // Overlap, the crossfade is copied on the right side of the left region instead
474 fade = boost::shared_ptr<Crossfade> (new Crossfade (*x, (*x)->_in, left));
479 _crossfades.remove (*x);
480 add_crossfade (fade);
487 AudioPlaylist::check_dependents (boost::shared_ptr<Region> r, bool norefresh)
489 boost::shared_ptr<AudioRegion> other;
490 boost::shared_ptr<AudioRegion> region;
491 boost::shared_ptr<AudioRegion> top;
492 boost::shared_ptr<AudioRegion> bottom;
493 boost::shared_ptr<Crossfade> xfade;
494 RegionList* touched_regions = 0;
496 if (in_set_state || in_partition) {
500 if ((region = boost::dynamic_pointer_cast<AudioRegion> (r)) == 0) {
501 fatal << _("programming error: non-audio Region tested for overlap in audio playlist")
507 refresh_dependents (r);
511 if (!_session.config.get_auto_xfade()) {
515 for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) {
516 other = boost::dynamic_pointer_cast<AudioRegion> (*i);
518 if (other == region) {
522 if (other->muted() || region->muted()) {
526 if (other->position() == r->position() && other->length() == r->length()) {
527 /* precise overlay of two regions - no xfade */
531 if (other->layer() < region->layer()) {
539 if (!top->opaque()) {
543 OverlapType c = top->coverage (bottom->position(), bottom->last_frame());
545 delete touched_regions;
549 framecnt_t xfade_length;
554 case OverlapInternal:
555 /* {=============== top =============}
556 * [ ----- bottom ------- ]
560 case OverlapExternal:
562 /* [ -------- top ------- ]
563 * {=========== bottom =============}
566 /* to avoid discontinuities at the region boundaries of an internal
567 overlap (this region is completely within another), we create
568 two hidden crossfades at each boundary. this is not dependent
569 on the auto-xfade option, because we require it as basic
573 xfade_length = min ((framecnt_t) 720, top->length());
575 if (top_region_at (top->first_frame()) == top) {
577 xfade = boost::shared_ptr<Crossfade> (new Crossfade (top, bottom, xfade_length, top->first_frame(), StartOfIn));
578 add_crossfade (xfade);
581 if (top_region_at (top->last_frame() - 1) == top) {
584 only add a fade out if there is no region on top of the end of 'top' (which
588 xfade = boost::shared_ptr<Crossfade> (new Crossfade (bottom, top, xfade_length, top->last_frame() - xfade_length, EndOfOut));
589 add_crossfade (xfade);
594 /* { ==== top ============ }
595 * [---- bottom -------------------]
598 if (_session.config.get_xfade_model() == FullCrossfade) {
599 touched_regions = regions_touched (top->first_frame(), bottom->last_frame());
600 if (touched_regions->size() <= 2) {
601 xfade = boost::shared_ptr<Crossfade> (new Crossfade (region, other, _session.config.get_xfade_model(), _session.config.get_xfades_active()));
602 add_crossfade (xfade);
606 touched_regions = regions_touched (top->first_frame(),
607 top->first_frame() + min ((framecnt_t) _session.config.get_short_xfade_seconds() * _session.frame_rate(),
609 if (touched_regions->size() <= 2) {
610 xfade = boost::shared_ptr<Crossfade> (new Crossfade (region, other, _session.config.get_xfade_model(), _session.config.get_xfades_active()));
611 add_crossfade (xfade);
618 /* [---- top ------------------------]
619 * { ==== bottom ============ }
622 if (_session.config.get_xfade_model() == FullCrossfade) {
624 touched_regions = regions_touched (bottom->first_frame(), top->last_frame());
625 if (touched_regions->size() <= 2) {
626 xfade = boost::shared_ptr<Crossfade> (new Crossfade (region, other,
627 _session.config.get_xfade_model(), _session.config.get_xfades_active()));
628 add_crossfade (xfade);
632 touched_regions = regions_touched (bottom->first_frame(),
633 bottom->first_frame() + min ((framecnt_t)_session.config.get_short_xfade_seconds() * _session.frame_rate(),
635 if (touched_regions->size() <= 2) {
636 xfade = boost::shared_ptr<Crossfade> (new Crossfade (region, other, _session.config.get_xfade_model(), _session.config.get_xfades_active()));
637 add_crossfade (xfade);
642 xfade = boost::shared_ptr<Crossfade> (new Crossfade (region, other,
643 _session.config.get_xfade_model(), _session.config.get_xfades_active()));
644 add_crossfade (xfade);
648 catch (failed_constructor& err) {
652 catch (Crossfade::NoCrossfadeHere& err) {
658 delete touched_regions;
662 AudioPlaylist::add_crossfade (boost::shared_ptr<Crossfade> xfade)
664 Crossfades::iterator ci;
666 for (ci = _crossfades.begin(); ci != _crossfades.end(); ++ci) {
667 if (*(*ci) == *xfade) { // Crossfade::operator==()
672 if (ci != _crossfades.end()) {
673 // it will just go away
675 _crossfades.push_back (xfade);
677 xfade->Invalidated.connect_same_thread (*this, boost::bind (&AudioPlaylist::crossfade_invalidated, this, _1));
678 xfade->PropertyChanged.connect_same_thread (*this, boost::bind (&AudioPlaylist::crossfade_changed, this, _1));
680 notify_crossfade_added (xfade);
684 void AudioPlaylist::notify_crossfade_added (boost::shared_ptr<Crossfade> x)
686 if (g_atomic_int_get(&block_notifications)) {
687 _pending_xfade_adds.insert (_pending_xfade_adds.end(), x);
689 NewCrossfade (x); /* EMIT SIGNAL */
694 AudioPlaylist::crossfade_invalidated (boost::shared_ptr<Region> r)
696 Crossfades::iterator i;
697 boost::shared_ptr<Crossfade> xfade = boost::dynamic_pointer_cast<Crossfade> (r);
699 xfade->in()->resume_fade_in ();
700 xfade->out()->resume_fade_out ();
702 if ((i = find (_crossfades.begin(), _crossfades.end(), xfade)) != _crossfades.end()) {
703 _crossfades.erase (i);
708 AudioPlaylist::set_state (const XMLNode& node, int version)
712 XMLNodeConstIterator niter;
716 Playlist::set_state (node, version);
720 nlist = node.children();
722 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
726 if (child->name() != "Crossfade") {
731 boost::shared_ptr<Crossfade> xfade = boost::shared_ptr<Crossfade> (new Crossfade (*((const Playlist *)this), *child));
732 _crossfades.push_back (xfade);
733 xfade->Invalidated.connect_same_thread (*this, boost::bind (&AudioPlaylist::crossfade_invalidated, this, _1));
734 xfade->PropertyChanged.connect_same_thread (*this, boost::bind (&AudioPlaylist::crossfade_changed, this, _1));
738 catch (failed_constructor& err) {
739 // cout << string_compose (_("could not create crossfade object in playlist %1"),
753 AudioPlaylist::clear (bool with_signals)
755 _crossfades.clear ();
756 Playlist::clear (with_signals);
760 AudioPlaylist::state (bool full_state)
762 XMLNode& node = Playlist::state (full_state);
765 for (Crossfades::iterator i = _crossfades.begin(); i != _crossfades.end(); ++i) {
766 node.add_child_nocopy ((*i)->get_state());
774 AudioPlaylist::dump () const
776 boost::shared_ptr<Region>r;
777 boost::shared_ptr<Crossfade> x;
779 cerr << "Playlist \"" << _name << "\" " << endl
780 << regions.size() << " regions "
781 << _crossfades.size() << " crossfades"
784 for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) {
786 cerr << " " << r->name() << " @ " << r << " ["
787 << r->start() << "+" << r->length()
795 for (Crossfades::const_iterator i = _crossfades.begin(); i != _crossfades.end(); ++i) {
806 << (x->active() ? "yes" : "no")
812 AudioPlaylist::destroy_region (boost::shared_ptr<Region> region)
814 boost::shared_ptr<AudioRegion> r = boost::dynamic_pointer_cast<AudioRegion> (region);
820 bool changed = false;
821 Crossfades::iterator c, ctmp;
822 set<boost::shared_ptr<Crossfade> > unique_xfades;
825 RegionLock rlock (this);
827 for (RegionList::iterator i = regions.begin(); i != regions.end(); ) {
829 RegionList::iterator tmp = i;
832 if ((*i) == region) {
840 for (set<boost::shared_ptr<Region> >::iterator x = all_regions.begin(); x != all_regions.end(); ) {
842 set<boost::shared_ptr<Region> >::iterator xtmp = x;
845 if ((*x) == region) {
846 all_regions.erase (x);
853 region->set_playlist (boost::shared_ptr<Playlist>());
856 for (c = _crossfades.begin(); c != _crossfades.end(); ) {
860 if ((*c)->involves (r)) {
861 unique_xfades.insert (*c);
862 _crossfades.erase (c);
869 /* overload this, it normally means "removed", not destroyed */
870 notify_region_removed (region);
877 AudioPlaylist::crossfade_changed (const PropertyChange&)
879 if (in_flush || in_set_state) {
883 /* XXX is there a loop here? can an xfade change not happen
884 due to a playlist change? well, sure activation would
885 be an example. maybe we should check the type of change
889 notify_contents_changed ();
893 AudioPlaylist::region_changed (const PropertyChange& what_changed, boost::shared_ptr<Region> region)
895 if (in_flush || in_set_state) {
899 PropertyChange our_interests;
901 our_interests.add (Properties::fade_in_active);
902 our_interests.add (Properties::fade_out_active);
903 our_interests.add (Properties::scale_amplitude);
904 our_interests.add (Properties::envelope_active);
905 our_interests.add (Properties::envelope);
906 our_interests.add (Properties::fade_in);
907 our_interests.add (Properties::fade_out);
909 bool parent_wants_notify;
911 parent_wants_notify = Playlist::region_changed (what_changed, region);
913 if (parent_wants_notify || (what_changed.contains (our_interests))) {
914 notify_contents_changed ();
921 AudioPlaylist::crossfades_at (framepos_t frame, Crossfades& clist)
923 RegionLock rlock (this);
925 for (Crossfades::iterator i = _crossfades.begin(); i != _crossfades.end(); ++i) {
926 framepos_t const start = (*i)->position ();
927 framepos_t const end = start + (*i)->overlap_length(); // not length(), important difference
929 if (frame >= start && frame <= end) {
930 clist.push_back (*i);
936 AudioPlaylist::foreach_crossfade (boost::function<void (boost::shared_ptr<Crossfade>)> s)
938 RegionLock rl (this, false);
939 for (Crossfades::iterator i = _crossfades.begin(); i != _crossfades.end(); ++i) {
945 AudioPlaylist::update (const CrossfadeListProperty::ChangeRecord& change)
947 for (CrossfadeListProperty::ChangeContainer::const_iterator i = change.added.begin(); i != change.added.end(); ++i) {
951 /* don't remove crossfades here; they will be dealt with by the dependency code */
954 boost::shared_ptr<Crossfade>
955 AudioPlaylist::find_crossfade (const PBD::ID& id) const
957 Crossfades::const_iterator i = _crossfades.begin ();
958 while (i != _crossfades.end() && (*i)->id() != id) {
962 if (i == _crossfades.end()) {
963 return boost::shared_ptr<Crossfade> ();