From bc3aea6f93edf23c19dc672dd5b1f44bca71f571 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Fri, 1 Jun 2012 01:07:00 +0000 Subject: [PATCH] fix construction of new xfades from legacy xfades, and add a few comments here and there git-svn-id: svn://localhost/ardour2/branches/3.0@12519 d708f5d6-7413-0410-9779-e7cbd77b26cf --- libs/ardour/ardour/audioplaylist.h | 3 +- libs/ardour/audio_playlist.cc | 101 ++++++++++++++++++++++------- libs/ardour/audioregion.cc | 18 ++--- 3 files changed, 91 insertions(+), 31 deletions(-) diff --git a/libs/ardour/ardour/audioplaylist.h b/libs/ardour/ardour/audioplaylist.h index 39efd2505d..a5f6b4ef39 100644 --- a/libs/ardour/ardour/audioplaylist.h +++ b/libs/ardour/ardour/audioplaylist.h @@ -59,7 +59,8 @@ private: int set_state (const XMLNode&, int version); void dump () const; bool region_changed (const PBD::PropertyChange&, boost::shared_ptr); - void source_offset_changed (boost::shared_ptr region); + void source_offset_changed (boost::shared_ptr); + void load_legacy_crossfades (const XMLNode&, int version); }; } /* namespace ARDOUR */ diff --git a/libs/ardour/audio_playlist.cc b/libs/ardour/audio_playlist.cc index 0054b6a177..dad62daf41 100644 --- a/libs/ardour/audio_playlist.cc +++ b/libs/ardour/audio_playlist.cc @@ -49,6 +49,8 @@ AudioPlaylist::AudioPlaylist (Session& session, const XMLNode& node, bool hidden in_set_state--; relayer (); + + load_legacy_crossfades (node, Stateful::loading_state_version); } AudioPlaylist::AudioPlaylist (Session& session, string name, bool hidden) @@ -200,7 +202,7 @@ AudioPlaylist::read (Sample *buf, Sample *mixdown_buffer, float *gain_buffer, fr /* This will be a list of the bits of regions that we need to read */ list to_do; - + /* Now go through the `all' list filling in `to_do' and `done' */ for (RegionList::iterator i = all->begin(); i != all->end(); ++i) { boost::shared_ptr ar = boost::dynamic_pointer_cast (*i); @@ -213,6 +215,7 @@ AudioPlaylist::read (Sample *buf, Sample *mixdown_buffer, float *gain_buffer, fr region_range.to = min (region_range.to, start + cnt - 1); /* ... and then remove the bits that are already done */ + Evoral::RangeList region_to_do = Evoral::subtract (region_range, done); /* Read those bits, adding their bodies (the parts between end-of-fade-in @@ -239,6 +242,10 @@ AudioPlaylist::read (Sample *buf, Sample *mixdown_buffer, float *gain_buffer, fr /* Now go backwards through the to_do list doing the actual reads */ for (list::reverse_iterator i = to_do.rbegin(); i != to_do.rend(); ++i) { + DEBUG_TRACE (DEBUG::AudioPlayback, string_compose ("\tPlaylist %1 read %2 @ %3 for %4, channel %5, buf @ %6 offset %7\n", + name(), i->region->name(), i->range.from, + i->range.to - i->range.from + 1, (int) chan_n, + buf, i->range.from - start)); i->region->read_at (buf + i->range.from - start, mixdown_buffer, gain_buffer, i->range.from, i->range.to - i->range.from + 1, chan_n); } @@ -656,11 +663,12 @@ AudioPlaylist::pre_uncombine (vector >& originals, boo int AudioPlaylist::set_state (const XMLNode& node, int version) { - int const r = Playlist::set_state (node, version); - if (r) { - return r; - } + return Playlist::set_state (node, version); +} +void +AudioPlaylist::load_legacy_crossfades (const XMLNode& node, int version) +{ /* Read legacy Crossfade nodes and set up region fades accordingly */ XMLNodeList children = node.children (); @@ -689,28 +697,77 @@ AudioPlaylist::set_state (const XMLNode& node, int version) boost::shared_ptr in_a = boost::dynamic_pointer_cast (in); assert (in_a); - - const XMLNodeList c = (*i)->children (); - for (XMLNodeConstIterator j = c.begin(); j != c.end(); ++j) { - if ((*j)->name() == X_("FadeIn")) { - in_a->fade_in()->set_state (**j, version); - } else if ((*j)->name() == X_("FadeOut")) { - in_a->inverse_fade_in()->set_state (**j, version); - } + if ((p = (*i)->property (X_("out"))) == 0) { + continue; } - if ((p = (*i)->property ("follow-overlap")) != 0) { - in_a->set_fade_in_is_short (!string_is_affirmative (p->value())); - } else { - in_a->set_fade_in_is_short (false); + boost::shared_ptr out = region_by_id (PBD::ID (p->value ())); + + if (!out) { + warning << string_compose (_("Legacy crossfade involved an outgoing region not present in playlist \"%1\" - crossfade discarded"), + name()) + << endmsg; + continue; } - in_a->set_fade_in_is_xfade (true); - in_a->set_fade_in_active (true); - cerr << in_a->name() << " from playlist fade in = xfade false\n"; + boost::shared_ptr out_a = boost::dynamic_pointer_cast (out); + assert (out_a); + + /* now decide whether to add a fade in or fade out + * xfade and to which region + */ + + if (in->layer() <= out->layer()) { + + /* incoming region is below the outgoing one, + * so apply a fade out to the outgoing one + */ + + const XMLNodeList c = (*i)->children (); + + for (XMLNodeConstIterator j = c.begin(); j != c.end(); ++j) { + if ((*j)->name() == X_("FadeOut")) { + out_a->fade_out()->set_state (**j, version); + } else if ((*j)->name() == X_("FadeIn")) { + out_a->inverse_fade_out()->set_state (**j, version); + } + } + + if ((p = (*i)->property ("follow-overlap")) != 0) { + out_a->set_fade_out_is_short (!string_is_affirmative (p->value())); + } else { + out_a->set_fade_out_is_short (false); + } + + out_a->set_fade_out_is_xfade (true); + out_a->set_fade_out_active (true); + + } else { + + /* apply a fade in to the incoming region, + * since its above the outgoing one + */ + + const XMLNodeList c = (*i)->children (); + + for (XMLNodeConstIterator j = c.begin(); j != c.end(); ++j) { + if ((*j)->name() == X_("FadeIn")) { + in_a->fade_in()->set_state (**j, version); + } else if ((*j)->name() == X_("FadeOut")) { + in_a->inverse_fade_in()->set_state (**j, version); + } + } + + if ((p = (*i)->property ("follow-overlap")) != 0) { + in_a->set_fade_in_is_short (!string_is_affirmative (p->value())); + } else { + in_a->set_fade_in_is_short (false); + } + + in_a->set_fade_in_is_xfade (true); + in_a->set_fade_in_active (true); + } } } - - return 0; } diff --git a/libs/ardour/audioregion.cc b/libs/ardour/audioregion.cc index 248da95936..42a29c12af 100644 --- a/libs/ardour/audioregion.cc +++ b/libs/ardour/audioregion.cc @@ -524,7 +524,7 @@ AudioRegion::read_at (Sample *buf, Sample *mixdown_buffer, float *gain_buffer, /* COMPUTE DETAILS OF ANY FADES INVOLVED IN THIS READ */ - /* Amount of fade in that we are dealing with in this read */ + /* Amount (length) of fade in that we are dealing with in this read */ framecnt_t fade_in_limit = 0; /* Offset from buf / mixdown_buffer of the start @@ -532,7 +532,7 @@ AudioRegion::read_at (Sample *buf, Sample *mixdown_buffer, float *gain_buffer, */ frameoffset_t fade_out_offset = 0; - /* Amount of fade in that we are dealing with in this read */ + /* Amount (length) of fade out that we are dealing with in this read */ framecnt_t fade_out_limit = 0; framecnt_t fade_interval_start = 0; @@ -542,7 +542,7 @@ AudioRegion::read_at (Sample *buf, Sample *mixdown_buffer, float *gain_buffer, if (_fade_in_active && _session.config.get_use_region_fades()) { framecnt_t fade_in_length = (framecnt_t) _fade_in->back()->when; - + /* see if this read is within the fade in */ if (internal_offset < fade_in_length) { @@ -611,7 +611,6 @@ AudioRegion::read_at (Sample *buf, Sample *mixdown_buffer, float *gain_buffer, apply_gain_to_buffer (mixdown_buffer, to_read, _scale_amplitude); } - /* APPLY FADES TO THE DATA IN mixdown_buffer AND MIX THE RESULTS INTO * buf. The key things to realize here: (1) the fade being applied is * (as of April 26th 2012) just the inverse of the fade in curve (2) @@ -623,6 +622,7 @@ AudioRegion::read_at (Sample *buf, Sample *mixdown_buffer, float *gain_buffer, if (opaque()) { if (_inverse_fade_in) { + /* explicit inverse fade in curve (e.g. for constant * power), so we have to fetch it. @@ -671,7 +671,7 @@ AudioRegion::read_at (Sample *buf, Sample *mixdown_buffer, float *gain_buffer, _inverse_fade_out->curve().get_vector (curve_offset, curve_offset + fade_out_limit, gain_buffer, fade_out_limit); - /* Fade the data from lower levels out */ + /* Fade the data from lower levels in */ for (framecnt_t n = 0, m = fade_out_offset; n < fade_out_limit; ++n, ++m) { buf[m] *= gain_buffer[n]; } @@ -682,7 +682,8 @@ AudioRegion::read_at (Sample *buf, Sample *mixdown_buffer, float *gain_buffer, } else { - /* no explicit inverse fade out, so just use (1 - fade + /* no explicit inverse fade out (which is + * actually a fade in), so just use (1 - fade * out) for the fade in of lower layers */ @@ -696,12 +697,13 @@ AudioRegion::read_at (Sample *buf, Sample *mixdown_buffer, float *gain_buffer, _fade_out->curve().get_vector (curve_offset, curve_offset + fade_out_limit, gain_buffer, fade_out_limit); } - /* Mix our newly-read data out, with the fade */ + /* Mix our newly-read data with whatever was already there, + with the fade out applied to our data. + */ for (framecnt_t n = 0, m = fade_out_offset; n < fade_out_limit; ++n, ++m) { buf[m] += mixdown_buffer[m] * gain_buffer[n]; } } - /* MIX OR COPY THE REGION BODY FROM mixdown_buffer INTO buf */ -- 2.30.2