From 539aa71d180d6b3d5c887707c356d3d00c0b37e8 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Wed, 30 May 2007 03:31:49 +0000 Subject: (MERGED FROM rev 1924 on 2.0-ongoing) fix some (all? not likely) problems with dragging close to 2^32-1 frames git-svn-id: svn://localhost/ardour2/trunk@1925 d708f5d6-7413-0410-9779-e7cbd77b26cf --- libs/ardour/audio_playlist.cc | 195 +++++++++++++++++++----------------------- 1 file changed, 90 insertions(+), 105 deletions(-) (limited to 'libs/ardour/audio_playlist.cc') diff --git a/libs/ardour/audio_playlist.cc b/libs/ardour/audio_playlist.cc index 246384689e..3eda5b57cf 100644 --- a/libs/ardour/audio_playlist.cc +++ b/libs/ardour/audio_playlist.cc @@ -65,6 +65,7 @@ AudioPlaylist::AudioPlaylist (boost::shared_ptr other, stri boost::shared_ptr ar = boost::dynamic_pointer_cast(*in_o); // We look only for crossfades which begin with the current region, so we don't get doubles + for (Crossfades::const_iterator xfades = other->_crossfades.begin(); xfades != other->_crossfades.end(); ++xfades) { if ((*xfades)->in() == ar) { // We found one! Now copy it! @@ -113,6 +114,21 @@ AudioPlaylist::~AudioPlaylist () _crossfades.clear (); } +void +AudioPlaylist::copy_regions (RegionList& newlist) const +{ + RegionLock rlock (const_cast (this)); + + Playlist::copy_regions (newlist, false); + + for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) { + if (!(*i)->is_dependent()) { + newlist.push_back (RegionFactory::RegionFactory::create (*i)); + } + } +} + + struct RegionSortByLayer { bool operator() (boost::shared_ptr a, boost::shared_ptr b) { return a->layer() < b->layer(); @@ -218,11 +234,11 @@ AudioPlaylist::remove_dependents (boost::shared_ptr region) << endmsg; return; } - - for (Crossfades::iterator i = _crossfades.begin(); i != _crossfades.end(); ) { + + for (RegionList::iterator i = regions.begin(); i != regions.end(); ) { - if ((*i)->involves (r)) { - i = _crossfades.erase (i); + if ((*i)->depends_on (r)) { + i = regions.erase (i); } else { ++i; } @@ -261,16 +277,16 @@ AudioPlaylist::refresh_dependents (boost::shared_ptr r) return; } - for (Crossfades::iterator x = _crossfades.begin(); x != _crossfades.end();) { - - Crossfades::iterator tmp; + for (RegionList::iterator x = regions.begin(); x != regions.end();) { + + RegionList::iterator tmp; tmp = x; ++tmp; /* only update them once */ - if ((*x)->involves (ar)) { + if ((*x)->depends_on (ar)) { if (find (updated.begin(), updated.end(), *x) == updated.end()) { try { @@ -296,35 +312,43 @@ AudioPlaylist::finalize_split_region (boost::shared_ptr o, boost::shared boost::shared_ptr left = boost::dynamic_pointer_cast(l); boost::shared_ptr right = boost::dynamic_pointer_cast(r); - for (Crossfades::iterator x = _crossfades.begin(); x != _crossfades.end();) { + for (RegionList::iterator x = regions.begin(); x !=regions.end();) { Crossfades::iterator tmp; + boost::shared_ptr xfade = boost::dynamic_pointer_cast(*x); + + if (!xfade) { + ++x; + continue; + } + tmp = x; ++tmp; boost::shared_ptr fade; - if ((*x)->_in == orig) { - if (! (*x)->covers(right->position())) { - fade = boost::shared_ptr (new Crossfade (*x, left, (*x)->_out)); + if (xfade->_in == orig) { + if (! xfade->covers(right->position())) { + fade = boost::shared_ptr (new Crossfade (*xfade, left, xfade->_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 (*xfade, right, xfade->_out)); } } - if ((*x)->_out == orig) { - if (! (*x)->covers(right->position())) { - fade = boost::shared_ptr (new Crossfade (*x, (*x)->_in, right)); + if (xfade->_out == orig) { + if (! xfade->covers(right->position())) { + fade = boost::shared_ptr (new Crossfade (*xfade, xfade->_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 (*xfade, xfade->_in, left)); } } if (fade) { - _crossfades.remove (*x); + regions.erase (*x); add_crossfade (fade); } + x = tmp; } } @@ -442,25 +466,29 @@ AudioPlaylist::check_dependents (boost::shared_ptr r, bool norefresh) } void -AudioPlaylist::add_crossfade (boost::shared_ptr xfade) +AudioPlaylist::add_crossfade (boost::shared_ptr new_xfade) { - Crossfades::iterator ci; + RegionList::iterator r; + boost::shared_ptr xfade; - for (ci = _crossfades.begin(); ci != _crossfades.end(); ++ci) { - if (*(*ci) == *xfade) { // Crossfade::operator==() - break; + for (r = regions.begin(); r != regions.end(); ++r) { + + if ((xfade = boost::dynamic_pointer_cast(*r))) { + if (*xfade == *new_xfade) { // Crossfade::operator==() + break; + } } } - if (ci != _crossfades.end()) { + if (r != regions.end()) { // it will just go away } else { - _crossfades.push_back (xfade); + add_region_internal (new_xfade); - xfade->Invalidated.connect (mem_fun (*this, &AudioPlaylist::crossfade_invalidated)); - xfade->StateChanged.connect (mem_fun (*this, &AudioPlaylist::crossfade_changed)); + new_xfade->Invalidated.connect (mem_fun (*this, &AudioPlaylist::crossfade_invalidated)); + new_xfade->StateChanged.connect (mem_fun (*this, &AudioPlaylist::crossfade_changed)); - notify_crossfade_added (xfade); + notify_crossfade_added (new_xfade); } } @@ -476,15 +504,12 @@ void AudioPlaylist::notify_crossfade_added (boost::shared_ptr x) void 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 (); - if ((i = find (_crossfades.begin(), _crossfades.end(), xfade)) != _crossfades.end()) { - _crossfades.erase (i); - } + remove_region_internal (r); } int @@ -505,13 +530,14 @@ AudioPlaylist::set_state (const XMLNode& node) child = *niter; - if (child->name() != "Crossfade") { + if (child->name() != Crossfade::node_name()) { continue; } - + try { - boost::shared_ptr xfade = boost::shared_ptr (new Crossfade (*((const Playlist *)this), *child)); - _crossfades.push_back (xfade); + boost::shared_ptr xfade = boost::dynamic_pointer_cast (RegionFactory::create (*((const Playlist *) this), *child)); + assert (xfade); + add_region_internal (xfade); xfade->Invalidated.connect (mem_fun (*this, &AudioPlaylist::crossfade_invalidated)); xfade->StateChanged.connect (mem_fun (*this, &AudioPlaylist::crossfade_changed)); NewCrossfade(xfade); @@ -534,24 +560,9 @@ AudioPlaylist::set_state (const XMLNode& node) void AudioPlaylist::clear (bool with_signals) { - _crossfades.clear (); Playlist::clear (with_signals); } -XMLNode& -AudioPlaylist::state (bool full_state) -{ - XMLNode& node = Playlist::state (full_state); - - if (full_state) { - for (Crossfades::iterator i = _crossfades.begin(); i != _crossfades.end(); ++i) { - node.add_child_nocopy ((*i)->get_state()); - } - } - - return node; -} - void AudioPlaylist::dump () const { @@ -560,33 +571,32 @@ AudioPlaylist::dump () const cerr << "Playlist \"" << _name << "\" " << endl << regions.size() << " regions " - << _crossfades.size() << " crossfades" << endl; for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) { r = *i; - cerr << " " << r->name() << " @ " << r << " [" - << r->start() << "+" << r->length() - << "] at " - << r->position() - << " on layer " - << r->layer () - << endl; - } - for (Crossfades::const_iterator i = _crossfades.begin(); i != _crossfades.end(); ++i) { - x = *i; - cerr << " xfade [" - << x->out()->name() - << ',' - << x->in()->name() - << " @ " - << x->position() - << " length = " - << x->length () - << " active ? " - << (x->active() ? "yes" : "no") - << endl; + if ((x = boost::dynamic_pointer_cast (r))) { + cerr << " xfade [" + << x->out()->name() + << ',' + << x->in()->name() + << " @ " + << x->position() + << " length = " + << x->length () + << " active ? " + << (x->active() ? "yes" : "no") + << endl; + } else { + cerr << " " << r->name() << " @ " << r << " [" + << r->start() << "+" << r->length() + << "] at " + << r->position() + << " on layer " + << r->layer () + << endl; + } } } @@ -595,8 +605,6 @@ AudioPlaylist::destroy_region (boost::shared_ptr region) { boost::shared_ptr r = boost::dynamic_pointer_cast (region); bool changed = false; - Crossfades::iterator c, ctmp; - set > unique_xfades; if (r == 0) { fatal << _("programming error: non-audio Region passed to remove_overlap in audio playlist") @@ -616,6 +624,9 @@ AudioPlaylist::destroy_region (boost::shared_ptr region) if ((*i) == region) { regions.erase (i); changed = true; + } else if ((*i)->depends_on (region)) { + regions.erase (i); + changed = true; } i = tmp; @@ -629,6 +640,9 @@ AudioPlaylist::destroy_region (boost::shared_ptr region) if ((*x) == region) { all_regions.erase (x); changed = true; + } else if ((*x)->depends_on (region)) { + all_regions.erase (x); + changed = true; } x = xtmp; @@ -637,18 +651,6 @@ AudioPlaylist::destroy_region (boost::shared_ptr region) region->set_playlist (boost::shared_ptr()); } - for (c = _crossfades.begin(); c != _crossfades.end(); ) { - ctmp = c; - ++ctmp; - - if ((*c)->involves (r)) { - unique_xfades.insert (*c); - _crossfades.erase (c); - } - - c = ctmp; - } - if (changed) { /* overload this, it normally means "removed", not destroyed */ notify_region_removed (region); @@ -698,20 +700,3 @@ AudioPlaylist::region_changed (Change what_changed, boost::shared_ptr re return true; } -void -AudioPlaylist::crossfades_at (nframes_t frame, Crossfades& clist) -{ - RegionLock rlock (this); - - for (Crossfades::iterator i = _crossfades.begin(); i != _crossfades.end(); ++i) { - nframes_t start, end; - - start = (*i)->position(); - end = start + (*i)->overlap_length(); // not length(), important difference - - if (frame >= start && frame <= end) { - clist.push_back (*i); - } - } -} - -- cgit v1.2.3