X-Git-Url: https://git.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Faudio_playlist.cc;h=6439c1b91776dec6f96d9ebdcaa5ef5e3eb81a89;hb=015fc7b39fab97cee1875231694adce43155ceb5;hp=dcba0ae31c6e83d4465ad44c79dd942593eb4375;hpb=f7563c2b158252339f98e38719cfc3e092ef7ac7;p=ardour.git diff --git a/libs/ardour/audio_playlist.cc b/libs/ardour/audio_playlist.cc index dcba0ae31c..6439c1b917 100644 --- a/libs/ardour/audio_playlist.cc +++ b/libs/ardour/audio_playlist.cc @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #include @@ -24,13 +23,14 @@ #include -#include -#include -#include -#include -#include -#include -#include +#include "ardour/types.h" +#include "ardour/configuration.h" +#include "ardour/audioplaylist.h" +#include "ardour/audioregion.h" +#include "ardour/crossfade.h" +#include "ardour/crossfade_compare.h" +#include "ardour/session.h" +#include "pbd/enumwriter.h" #include "i18n.h" @@ -79,7 +79,7 @@ AudioPlaylist::AudioPlaylist (boost::shared_ptr other, stri if ((*xfades)->out() == ar2) { boost::shared_ptrin = boost::dynamic_pointer_cast(*in_n); boost::shared_ptrout = boost::dynamic_pointer_cast(*out_n); - boost::shared_ptr new_fade = boost::shared_ptr (new Crossfade (*(*xfades), in, out)); + boost::shared_ptr new_fade = boost::shared_ptr (new Crossfade (*xfades, in, out)); add_crossfade(new_fade); break; } @@ -147,19 +147,27 @@ AudioPlaylist::read (Sample *buf, Sample *mixdown_buffer, float *gain_buffer, nf its OK to block (for short intervals). */ - Glib::Mutex::Lock rm (region_lock); + Glib::RecMutex::Lock rm (region_lock); end = start + cnt - 1; - read_frames = 0; skip_frames = 0; _read_data_count = 0; + _read_data_count = 0; + + RegionList* rlist = regions_to_read (start, start+cnt); + + if (rlist->empty()) { + delete rlist; + return cnt; + } + map > > relevant_regions; map > > relevant_xfades; vector relevant_layers; - for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) { + for (RegionList::iterator i = rlist->begin(); i != rlist->end(); ++i) { if ((*i)->coverage (start, end) != OverlapNone) { relevant_regions[(*i)->layer()].push_back (*i); relevant_layers.push_back ((*i)->layer()); @@ -204,6 +212,7 @@ AudioPlaylist::read (Sample *buf, Sample *mixdown_buffer, float *gain_buffer, nf } } + delete rlist; return ret; } @@ -276,10 +285,16 @@ AudioPlaylist::refresh_dependents (boost::shared_ptr r) if ((*x)->involves (ar)) { - if (find (updated.begin(), updated.end(), *x) == updated.end()) { - if ((*x)->refresh ()) { - /* not invalidated by the refresh */ - updated.insert (*x); + pair >::iterator, bool> const u = updated.insert (*x); + + if (u.second) { + /* x was successfully inserted into the set, so it has not already been updated */ + try { + (*x)->refresh (); + } + + catch (Crossfade::NoCrossfadeHere& err) { + // relax, Invalidated during refresh } } } @@ -304,19 +319,19 @@ AudioPlaylist::finalize_split_region (boost::shared_ptr o, boost::shared if ((*x)->_in == orig) { if (! (*x)->covers(right->position())) { - fade = boost::shared_ptr (new Crossfade (**x, left, (*x)->_out)); + fade = boost::shared_ptr (new Crossfade (*x, left, (*x)->_out)); } else { // Overlap, the crossfade is copied on the left side of the right region instead - fade = boost::shared_ptr (new Crossfade (**x, right, (*x)->_out)); + fade = boost::shared_ptr (new Crossfade (*x, right, (*x)->_out)); } } if ((*x)->_out == orig) { if (! (*x)->covers(right->position())) { - fade = boost::shared_ptr (new Crossfade (**x, (*x)->_in, right)); + fade = boost::shared_ptr (new Crossfade (*x, (*x)->_in, right)); } else { // Overlap, the crossfade is copied on the right side of the left region instead - fade = boost::shared_ptr (new Crossfade (**x, (*x)->_in, left)); + fade = boost::shared_ptr (new Crossfade (*x, (*x)->_in, left)); } } @@ -336,13 +351,12 @@ AudioPlaylist::check_dependents (boost::shared_ptr r, bool norefresh) boost::shared_ptr top; boost::shared_ptr bottom; boost::shared_ptr xfade; + RegionList* touched_regions; if (in_set_state || in_partition) { return; } - cerr << "Check dependents of " << r->name() << endl; - if ((region = boost::dynamic_pointer_cast (r)) == 0) { fatal << _("programming error: non-audio Region tested for overlap in audio playlist") << endmsg; @@ -353,7 +367,8 @@ AudioPlaylist::check_dependents (boost::shared_ptr r, bool norefresh) refresh_dependents (r); } - if (!Config->get_auto_xfade()) { + + if (!_session.config.get_auto_xfade()) { return; } @@ -380,9 +395,12 @@ AudioPlaylist::check_dependents (boost::shared_ptr r, bool norefresh) bottom = region; } + if (!top->opaque()) { + continue; + } OverlapType c = top->coverage (bottom->position(), bottom->last_frame()); - + try { switch (c) { case OverlapNone: @@ -395,7 +413,7 @@ AudioPlaylist::check_dependents (boost::shared_ptr r, bool norefresh) break; case OverlapExternal: - + /* [ -------- top ------- ] * {=========== bottom =============} */ @@ -408,11 +426,15 @@ AudioPlaylist::check_dependents (boost::shared_ptr r, bool norefresh) */ xfade_length = min ((nframes_t) 720, top->length()); - - xfade = boost::shared_ptr (new Crossfade (top, bottom, xfade_length, top->first_frame(), StartOfIn)); - add_crossfade (xfade); - + + if (top_region_at (top->first_frame()) == top) { + + xfade = boost::shared_ptr (new Crossfade (top, bottom, xfade_length, top->first_frame(), StartOfIn)); + add_crossfade (xfade); + } + if (top_region_at (top->last_frame() - 1) == top) { + /* only add a fade out if there is no region on top of the end of 'top' (which would cover it). @@ -422,9 +444,58 @@ AudioPlaylist::check_dependents (boost::shared_ptr r, bool norefresh) add_crossfade (xfade); } break; - + case OverlapStart: + + /* { ==== top ============ } + * [---- bottom -------------------] + */ + + if (_session.config.get_xfade_model() == FullCrossfade) { + touched_regions = regions_touched (top->first_frame(), bottom->last_frame()); + if (touched_regions->size() <= 2) { + xfade = boost::shared_ptr (new Crossfade (region, other, _session.config.get_xfade_model(), _session.config.get_xfades_active())); + add_crossfade (xfade); + } + } else { + + touched_regions = regions_touched (top->first_frame(), + top->first_frame() + min ((nframes_t)_session.config.get_short_xfade_seconds() * _session.frame_rate(), + top->length())); + if (touched_regions->size() <= 2) { + xfade = boost::shared_ptr (new Crossfade (region, other, _session.config.get_xfade_model(), _session.config.get_xfades_active())); + add_crossfade (xfade); + } + } + break; + case OverlapEnd: + + + /* [---- top ------------------------] + * { ==== bottom ============ } + */ + + if (_session.config.get_xfade_model() == FullCrossfade) { + + touched_regions = regions_touched (bottom->first_frame(), top->last_frame()); + if (touched_regions->size() <= 2) { + xfade = boost::shared_ptr (new Crossfade (region, other, + _session.config.get_xfade_model(), _session.config.get_xfades_active())); + add_crossfade (xfade); + } + + } else { + touched_regions = regions_touched (bottom->first_frame(), + bottom->first_frame() + min ((nframes_t)_session.config.get_short_xfade_seconds() * _session.frame_rate(), + bottom->length())); + if (touched_regions->size() <= 2) { + xfade = boost::shared_ptr (new Crossfade (region, other, _session.config.get_xfade_model(), _session.config.get_xfades_active())); + add_crossfade (xfade); + } + } + break; default: - xfade = boost::shared_ptr (new Crossfade (region, other, Config->get_xfade_model(), Config->get_xfades_active())); + xfade = boost::shared_ptr (new Crossfade (region, other, + _session.config.get_xfade_model(), _session.config.get_xfades_active())); add_crossfade (xfade); } } @@ -468,14 +539,16 @@ void AudioPlaylist::notify_crossfade_added (boost::shared_ptr x) if (g_atomic_int_get(&block_notifications)) { _pending_xfade_adds.insert (_pending_xfade_adds.end(), x); } else { + NewCrossfade (x); /* EMIT SIGNAL */ } } void -AudioPlaylist::crossfade_invalidated (boost::shared_ptr xfade) +AudioPlaylist::crossfade_invalidated (boost::shared_ptr r) { Crossfades::iterator i; + boost::shared_ptr xfade = boost::dynamic_pointer_cast (r); xfade->in()->resume_fade_in (); xfade->out()->resume_fade_out (); @@ -603,7 +676,7 @@ AudioPlaylist::destroy_region (boost::shared_ptr region) return false; } - { + { RegionLock rlock (this); for (RegionList::iterator i = regions.begin(); i != regions.end(); ) {