remove reference to PluginState in VST code, for real this time
[ardour.git] / libs / ardour / audio_playlist.cc
index 328c9b25f5e2b75c32ce79ff36add52f4e956d0e..19609da2a4c6df4f70fc236d930b4f20e9fa3c81 100644 (file)
@@ -39,18 +39,12 @@ using namespace sigc;
 using namespace std;
 using namespace PBD;
 
-AudioPlaylist::State::~State ()
-{
-}
-
 AudioPlaylist::AudioPlaylist (Session& session, const XMLNode& node, bool hidden)
        : Playlist (session, node, hidden)
 {
-       in_set_state = true;
+       in_set_state++;
        set_state (node);
-       in_set_state = false;
-
-       save_state (_("initial state"));
+       in_set_state--;
 
        if (!hidden) {
                PlaylistCreated (this); /* EMIT SIGNAL */
@@ -60,8 +54,6 @@ AudioPlaylist::AudioPlaylist (Session& session, const XMLNode& node, bool hidden
 AudioPlaylist::AudioPlaylist (Session& session, string name, bool hidden)
        : Playlist (session, name, hidden)
 {
-       save_state (_("initial state"));
-
        if (!hidden) {
                PlaylistCreated (this); /* EMIT SIGNAL */
        }
@@ -71,30 +63,28 @@ AudioPlaylist::AudioPlaylist (Session& session, string name, bool hidden)
 AudioPlaylist::AudioPlaylist (const AudioPlaylist& other, string name, bool hidden)
        : Playlist (other, name, hidden)
 {
-       save_state (_("initial state"));
-
-       list<Region*>::const_iterator in_o  = other.regions.begin();
-       list<Region*>::iterator in_n = regions.begin();
+       RegionList::const_iterator in_o  = other.regions.begin();
+       RegionList::iterator in_n = regions.begin();
 
        while (in_o != other.regions.end()) {
-               AudioRegion *ar = dynamic_cast<AudioRegion *>( (*in_o) );
+               boost::shared_ptr<AudioRegion> ar = boost::dynamic_pointer_cast<AudioRegion>(*in_o);
 
                // We look only for crossfades which begin with the current region, so we don't get doubles
                for (list<Crossfade *>::const_iterator xfades = other._crossfades.begin(); xfades != other._crossfades.end(); ++xfades) {
-                       if ( &(*xfades)->in() == ar) {
+                       if ((*xfades)->in() == ar) {
                                // We found one! Now copy it!
 
-                               list<Region*>::const_iterator out_o = other.regions.begin();
-                               list<Region*>::const_iterator out_n = regions.begin();
+                               RegionList::const_iterator out_o = other.regions.begin();
+                               RegionList::const_iterator out_n = regions.begin();
 
                                while (out_o != other.regions.end()) {
                                        
-                                       AudioRegion *ar2 = dynamic_cast<AudioRegion *>( (*out_o) );
+                                       boost::shared_ptr<AudioRegion>ar2 = boost::dynamic_pointer_cast<AudioRegion>(*out_o);
                                        
-                                       if ( &(*xfades)->out() == ar2) {
-                                               AudioRegion *in  = dynamic_cast<AudioRegion*>( (*in_n) );
-                                               AudioRegion *out = dynamic_cast<AudioRegion*>( (*out_n) );
-                                               Crossfade *new_fade = new Crossfade*(*xfades), in, out);
+                                       if ((*xfades)->out() == ar2) {
+                                               boost::shared_ptr<AudioRegion>in  = boost::dynamic_pointer_cast<AudioRegion>(*in_n);
+                                               boost::shared_ptr<AudioRegion>out = boost::dynamic_pointer_cast<AudioRegion>(*out_n);
+                                               Crossfade *new_fade = new Crossfade (*(*xfades), in, out);
                                                add_crossfade(*new_fade);
                                                break;
                                        }
@@ -115,75 +105,48 @@ AudioPlaylist::AudioPlaylist (const AudioPlaylist& other, string name, bool hidd
        }
 }
 
-AudioPlaylist::AudioPlaylist (const AudioPlaylist& other, jack_nframes_t start, jack_nframes_t cnt, string name, bool hidden)
+AudioPlaylist::AudioPlaylist (const AudioPlaylist& other, nframes_t start, nframes_t cnt, string name, bool hidden)
        : Playlist (other, start, cnt, name, hidden)
 {
-       save_state (_("initial state"));
-
        /* this constructor does NOT notify others (session) */
 }
 
 AudioPlaylist::~AudioPlaylist ()
 {
        set<Crossfade*> all_xfades;
-       set<Region*> all_regions;
 
-       GoingAway (this);
-
-       /* find every region we've ever used, and add it to the set of 
-          all regions. same for xfades;
-       */
+       GoingAway (); /* EMIT SIGNAL */
 
-       for (RegionList::iterator x = regions.begin(); x != regions.end(); ++x) {
-               all_regions.insert (*x);
-       }
-
-       for (Crossfades::iterator x = _crossfades.begin(); x != _crossfades.end(); ++x) {
-               all_xfades.insert (*x);
-       }
-
-       for (StateMap::iterator i = states.begin(); i != states.end(); ++i) {
-               
-               AudioPlaylist::State* apstate = dynamic_cast<AudioPlaylist::State*> (*i);
-
-               for (RegionList::iterator r = apstate->regions.begin(); r != apstate->regions.end(); ++r) {
-                       all_regions.insert (*r);
-               }
-               for (Crossfades::iterator xf = apstate->crossfades.begin(); xf != apstate->crossfades.end(); ++xf) {
-                       all_xfades.insert (*xf);
-               }
+       /* drop connections to signals */
 
-               delete apstate;
-       }
+       notify_callbacks ();
 
-       /* delete every region */
+       for (Crossfades::iterator x = _crossfades.begin(); x != _crossfades.end(); ) {
+               Crossfades::iterator tmp;
 
-       for (set<Region *>::iterator ar = all_regions.begin(); ar != all_regions.end(); ++ar) {
-               (*ar)->unlock_sources ();
-               delete *ar;
-       }
+               tmp = x;
+               ++tmp;
 
-       /* delete every crossfade */
+               delete *x;
 
-       for (set<Crossfade *>::iterator axf = all_xfades.begin(); axf != all_xfades.end(); ++axf) {
-               delete *axf;
+               x = tmp;
        }
 }
 
 struct RegionSortByLayer {
-    bool operator() (Region *a, Region *b) {
+    bool operator() (boost::shared_ptr<Region>a, boost::shared_ptr<Region>b) {
            return a->layer() < b->layer();
     }
 };
 
-jack_nframes_t
-AudioPlaylist::read (Sample *buf, Sample *mixdown_buffer, float *gain_buffer, jack_nframes_t start,
-                    jack_nframes_t cnt, unsigned chan_n)
+nframes_t
+AudioPlaylist::read (Sample *buf, Sample *mixdown_buffer, float *gain_buffer, nframes_t start,
+                    nframes_t cnt, unsigned chan_n)
 {
-       jack_nframes_t ret = cnt;
-       jack_nframes_t end;
-       jack_nframes_t read_frames;
-       jack_nframes_t skip_frames;
+       nframes_t ret = cnt;
+       nframes_t end;
+       nframes_t read_frames;
+       nframes_t skip_frames;
 
        /* optimizing this memset() away involves a lot of conditionals
           that may well cause more of a hit due to cache misses 
@@ -212,13 +175,12 @@ AudioPlaylist::read (Sample *buf, Sample *mixdown_buffer, float *gain_buffer, ja
        skip_frames = 0;
        _read_data_count = 0;
 
-       map<uint32_t,vector<Region*> > relevant_regions;
+       map<uint32_t,vector<boost::shared_ptr<Region> > > relevant_regions;
        map<uint32_t,vector<Crossfade*> > relevant_xfades;
        vector<uint32_t> relevant_layers;
 
        for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) {
                if ((*i)->coverage (start, end) != OverlapNone) {
-                       
                        relevant_regions[(*i)->layer()].push_back (*i);
                        relevant_layers.push_back ((*i)->layer());
                }
@@ -243,12 +205,11 @@ AudioPlaylist::read (Sample *buf, Sample *mixdown_buffer, float *gain_buffer, ja
 
        for (vector<uint32_t>::iterator l = relevant_layers.begin(); l != relevant_layers.end(); ++l) {
 
-               // FIXME: Should be vector<AudioRegion*>
-               vector<Region*>& r (relevant_regions[*l]);
+               vector<boost::shared_ptr<Region> > r (relevant_regions[*l]);
                vector<Crossfade*>& x (relevant_xfades[*l]);
 
-               for (vector<Region*>::iterator i = r.begin(); i != r.end(); ++i) {
-                       AudioRegion* const ar = dynamic_cast<AudioRegion*>(*i);
+               for (vector<boost::shared_ptr<Region> >::iterator i = r.begin(); i != r.end(); ++i) {
+                       boost::shared_ptr<AudioRegion> ar = boost::dynamic_pointer_cast<AudioRegion>(*i);
                        assert(ar);
                        ar->read_at (buf, mixdown_buffer, gain_buffer, start, cnt, chan_n, read_frames, skip_frames);
                        _read_data_count += ar->read_data_count();
@@ -268,10 +229,14 @@ AudioPlaylist::read (Sample *buf, Sample *mixdown_buffer, float *gain_buffer, ja
 
 
 void
-AudioPlaylist::remove_dependents (Region& region)
+AudioPlaylist::remove_dependents (boost::shared_ptr<Region> region)
 {
        Crossfades::iterator i, tmp;
-       AudioRegion* r = dynamic_cast<AudioRegion*> (&region);
+       boost::shared_ptr<AudioRegion> r = boost::dynamic_pointer_cast<AudioRegion> (region);
+
+       if (in_set_state) {
+               return;
+       }
        
        if (r == 0) {
                fatal << _("programming error: non-audio Region passed to remove_overlap in audio playlist")
@@ -283,9 +248,9 @@ AudioPlaylist::remove_dependents (Region& region)
                tmp = i;
                tmp++;
 
-               if ((*i)->involves (*r)) {
-                       /* do not delete crossfades */
-                       _crossfades.erase (i);
+               
+               if ((*i)->involves (r)) {
+                       delete *i;
                }
                
                i = tmp;
@@ -315,9 +280,9 @@ AudioPlaylist::flush_notifications ()
 }
 
 void
-AudioPlaylist::refresh_dependents (Region& r)
+AudioPlaylist::refresh_dependents (boost::shared_ptr<Region> r)
 {
-       AudioRegion* ar = dynamic_cast<AudioRegion*>(&r);
+       boost::shared_ptr<AudioRegion> ar = boost::dynamic_pointer_cast<AudioRegion>(r);
        set<Crossfade*> updated;
 
        if (ar == 0) {
@@ -333,7 +298,7 @@ AudioPlaylist::refresh_dependents (Region& r)
 
                /* only update them once */
 
-               if ((*x)->involves (*ar)) {
+               if ((*x)->involves (ar)) {
 
                        if (find (updated.begin(), updated.end(), *x) == updated.end()) {
                                if ((*x)->refresh ()) {
@@ -348,11 +313,11 @@ AudioPlaylist::refresh_dependents (Region& r)
 }
 
 void
-AudioPlaylist::finalize_split_region (Region *o, Region *l, Region *r)
+AudioPlaylist::finalize_split_region (boost::shared_ptr<Region> o, boost::shared_ptr<Region> l, boost::shared_ptr<Region> r)
 {
-       AudioRegion *orig  = dynamic_cast<AudioRegion*>(o);
-       AudioRegion *left  = dynamic_cast<AudioRegion*>(l);
-       AudioRegion *right = dynamic_cast<AudioRegion*>(r);
+       boost::shared_ptr<AudioRegion> orig  = boost::dynamic_pointer_cast<AudioRegion>(o);
+       boost::shared_ptr<AudioRegion> left  = boost::dynamic_pointer_cast<AudioRegion>(l);
+       boost::shared_ptr<AudioRegion> right = boost::dynamic_pointer_cast<AudioRegion>(r);
 
        for (Crossfades::iterator x = _crossfades.begin(); x != _crossfades.end();) {
                Crossfades::iterator tmp;
@@ -363,24 +328,24 @@ AudioPlaylist::finalize_split_region (Region *o, Region *l, Region *r)
                
                if ((*x)->_in == orig) {
                        if (! (*x)->covers(right->position())) {
-                               fade = new Crossfade( *(*x), left, (*x)->_out);
+                               fade = new Crossfade (**x, left, (*x)->_out);
                        } else {
                                // Overlap, the crossfade is copied on the left side of the right region instead
-                               fade = new Crossfade( *(*x), right, (*x)->_out);
+                               fade = new Crossfade (**x, right, (*x)->_out);
                        }
                }
                
                if ((*x)->_out == orig) {
                        if (! (*x)->covers(right->position())) {
-                               fade = new Crossfade( *(*x), (*x)->_in, right);
+                               fade = new Crossfade (**x, (*x)->_in, right);
                        } else {
                                // Overlap, the crossfade is copied on the right side of the left region instead
-                               fade = new Crossfade( *(*x), (*x)->_in, left);
+                               fade = new Crossfade (**x, (*x)->_in, left);
                        }
                }
                
                if (fade) {
-                       _crossfades.remove( (*x) );
+                       _crossfades.remove (*x);
                        add_crossfade (*fade);
                }
                x = tmp;
@@ -388,19 +353,19 @@ AudioPlaylist::finalize_split_region (Region *o, Region *l, Region *r)
 }
 
 void
-AudioPlaylist::check_dependents (Region& r, bool norefresh)
+AudioPlaylist::check_dependents (boost::shared_ptr<Region> r, bool norefresh)
 {
-       AudioRegion* other;
-       AudioRegion* region;
-       AudioRegion* top;
-       AudioRegion* bottom;
+       boost::shared_ptr<AudioRegion> other;
+       boost::shared_ptr<AudioRegion> region;
+       boost::shared_ptr<AudioRegion> top;
+       boost::shared_ptr<AudioRegion> bottom;
        Crossfade*   xfade;
 
        if (in_set_state || in_partition) {
                return;
        }
 
-       if ((region = dynamic_cast<AudioRegion*> (&r)) == 0) {
+       if ((region = boost::dynamic_pointer_cast<AudioRegion> (r)) == 0) {
                fatal << _("programming error: non-audio Region tested for overlap in audio playlist")
                      << endmsg;
                return;
@@ -416,7 +381,7 @@ AudioPlaylist::check_dependents (Region& r, bool norefresh)
 
        for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) {
 
-               other = dynamic_cast<AudioRegion*> (*i);
+               other = boost::dynamic_pointer_cast<AudioRegion> (*i);
 
                if (other == region) {
                        continue;
@@ -455,17 +420,17 @@ AudioPlaylist::check_dependents (Region& r, bool norefresh)
                                           audio engineering.
                                        */
                                        
-                                       jack_nframes_t xfade_length = min ((jack_nframes_t) 720, top->length());
+                                       nframes_t xfade_length = min ((nframes_t) 720, top->length());
                                        
                                                            /*  in,      out */
-                                       xfade = new Crossfade (*top, *bottom, xfade_length, top->first_frame(), StartOfIn);
+                                       xfade = new Crossfade (top, bottom, xfade_length, top->first_frame(), StartOfIn);
                                        add_crossfade (*xfade);
-                                       xfade = new Crossfade (*bottom, *top, xfade_length, top->last_frame() - xfade_length, EndOfOut);
+                                       xfade = new Crossfade (bottom, top, xfade_length, top->last_frame() - xfade_length, EndOfOut);
                                        add_crossfade (*xfade);
                                        
                                } else {
-               
-                                       xfade = new Crossfade (*other, *region, _session.get_xfade_model(), _session.get_crossfades_active());
+
+                                       xfade = new Crossfade (other, region, Config->get_xfade_model(), Config->get_xfades_active());
                                        add_crossfade (*xfade);
                                }
                        } 
@@ -519,8 +484,8 @@ AudioPlaylist::crossfade_invalidated (Crossfade* xfade)
 {
        Crossfades::iterator i;
 
-       xfade->in().resume_fade_in ();
-       xfade->out().resume_fade_out ();
+       xfade->in()->resume_fade_in ();
+       xfade->out()->resume_fade_out ();
 
        if ((i = find (_crossfades.begin(), _crossfades.end(), xfade)) != _crossfades.end()) {
                _crossfades.erase (i);
@@ -534,9 +499,10 @@ AudioPlaylist::set_state (const XMLNode& node)
        XMLNodeList nlist;
        XMLNodeConstIterator niter;
 
-       if (!in_set_state) {
-               Playlist::set_state (node);
-       }
+       in_set_state++;
+       freeze ();
+
+       Playlist::set_state (node);
 
        nlist = node.children();
 
@@ -544,167 +510,49 @@ AudioPlaylist::set_state (const XMLNode& node)
 
                child = *niter;
 
-               if (child->name() == "Crossfade") {
-
-                       Crossfade *xfade;
-                       
-                       try {
-                               xfade = new Crossfade (*((const Playlist *)this), *child);
-                       }
-
-                       catch (failed_constructor& err) {
-                         //    cout << string_compose (_("could not create crossfade object in playlist %1"),
-                         //      _name) 
-                         //    << endl;
-                               continue;
-                       }
-
-                       Crossfades::iterator ci;
-
-                       for (ci = _crossfades.begin(); ci != _crossfades.end(); ++ci) {
-                               if (*(*ci) == *xfade) {
-                                       break;
-                               }
-                       }
-
-                       if (ci == _crossfades.end()) {
-                               _crossfades.push_back (xfade);
-                               xfade->Invalidated.connect (mem_fun (*this, &AudioPlaylist::crossfade_invalidated));
-                               xfade->StateChanged.connect (mem_fun (*this, &AudioPlaylist::crossfade_changed));
-                               /* no need to notify here */
-                       } else {
-                               delete xfade;
-                       }
-               }
-
-       }
-
-       return 0;
-}
-
-void
-AudioPlaylist::drop_all_states ()
-{
-       set<Crossfade*> all_xfades;
-       set<Region*> all_regions;
-
-       /* find every region we've ever used, and add it to the set of 
-          all regions. same for xfades;
-       */
-
-       for (StateMap::iterator i = states.begin(); i != states.end(); ++i) {
-               
-               AudioPlaylist::State* apstate = dynamic_cast<AudioPlaylist::State*> (*i);
-
-               for (RegionList::iterator r = apstate->regions.begin(); r != apstate->regions.end(); ++r) {
-                       all_regions.insert (*r);
-               }
-               for (Crossfades::iterator xf = apstate->crossfades.begin(); xf != apstate->crossfades.end(); ++xf) {
-                       all_xfades.insert (*xf);
+               if (child->name() != "Crossfade") {
+                       continue;
                }
-       }
 
-       /* now remove from the "all" lists every region that is in the current list. */
-
-       for (list<Region*>::iterator i = regions.begin(); i != regions.end(); ++i) {
-               set<Region*>::iterator x = all_regions.find (*i);
-               if (x != all_regions.end()) {
-                       all_regions.erase (x);
+               try {
+                       Crossfade* xfade = new Crossfade (*((const Playlist *)this), *child);
+                       _crossfades.push_back (xfade);
+                       xfade->Invalidated.connect (mem_fun (*this, &AudioPlaylist::crossfade_invalidated));
+                       xfade->StateChanged.connect (mem_fun (*this, &AudioPlaylist::crossfade_changed));
+                       NewCrossfade(xfade);
                }
-       }
-
-       /* ditto for every crossfade */
-
-       for (list<Crossfade*>::iterator i = _crossfades.begin(); i != _crossfades.end(); ++i) {
-               set<Crossfade*>::iterator x = all_xfades.find (*i);
-               if (x != all_xfades.end()) {
-                       all_xfades.erase (x);
+               
+               catch (failed_constructor& err) {
+                       //      cout << string_compose (_("could not create crossfade object in playlist %1"),
+                       //        _name) 
+                       //    << endl;
+                       continue;
                }
        }
 
-       /* delete every region that is left - these are all things that are part of our "history" */
-
-       for (set<Region *>::iterator ar = all_regions.begin(); ar != all_regions.end(); ++ar) {
-               (*ar)->unlock_sources ();
-               delete *ar;
-       }
-
-       /* delete every crossfade that is left (ditto as per regions) */
-
-       for (set<Crossfade *>::iterator axf = all_xfades.begin(); axf != all_xfades.end(); ++axf) {
-               delete *axf;
-       }
+       thaw ();
+       in_set_state++;
 
-       /* Now do the generic thing ... */
-
-       StateManager::drop_all_states ();
+       return 0;
 }
 
-StateManager::State*
-AudioPlaylist::state_factory (std::string why) const
+void
+AudioPlaylist::clear (bool with_signals)
 {
-       State* state = new State (why);
-
-       state->regions = regions;
-       state->region_states.clear ();
-       for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) {
-               state->region_states.push_back ((*i)->get_memento());
-       }
-
-       state->crossfades = _crossfades;
-       state->crossfade_states.clear ();
-       for (Crossfades::const_iterator i = _crossfades.begin(); i != _crossfades.end(); ++i) {
-               state->crossfade_states.push_back ((*i)->get_memento());
-       }
-       return state;
-}
-
-Change
-AudioPlaylist::restore_state (StateManager::State& state)
-{ 
-       { 
-               RegionLock rlock (this);
-               State* apstate = dynamic_cast<State*> (&state);
-
-               in_set_state = true;
-
-               regions = apstate->regions;
-
-               for (list<UndoAction>::iterator s = apstate->region_states.begin(); s != apstate->region_states.end(); ++s) {
-                       (*s) ();
-               }
+       for (Crossfades::iterator i = _crossfades.begin(); i != _crossfades.end(); ) {
 
-               _crossfades = apstate->crossfades;
-               
-               for (list<UndoAction>::iterator s = apstate->crossfade_states.begin(); s != apstate->crossfade_states.end(); ++s) {
-                       (*s) ();
-               }
-
-               in_set_state = false;
-       }
-
-       notify_length_changed ();
-       return Change (~0);
-}
+               Crossfades::iterator tmp;
+               tmp = i;
+               ++tmp;
 
-UndoAction
-AudioPlaylist::get_memento () const
-{
-       return sigc::bind (mem_fun (*(const_cast<AudioPlaylist*> (this)), &StateManager::use_state), _current_state_id);
-}
+               delete *i;
 
-void
-AudioPlaylist::clear (bool with_delete, bool with_save)
-{
-       if (with_delete) {
-               for (Crossfades::iterator i = _crossfades.begin(); i != _crossfades.end(); ++i) {
-                       delete *i;
-               }
+               i = tmp;
        }
 
        _crossfades.clear ();
        
-       Playlist::clear (with_delete, with_save);
+       Playlist::clear (with_signals);
 }
 
 XMLNode&
@@ -724,7 +572,7 @@ AudioPlaylist::state (bool full_state)
 void
 AudioPlaylist::dump () const
 {
-       Region *r;
+       boost::shared_ptr<Region>r;
        Crossfade *x;
 
        cerr << "Playlist \"" << _name << "\" " << endl
@@ -746,9 +594,9 @@ AudioPlaylist::dump () const
        for (Crossfades::const_iterator i = _crossfades.begin(); i != _crossfades.end(); ++i) {
                x = *i;
                cerr << "  xfade [" 
-                    << x->out().name()
+                    << x->out()->name()
                     << ','
-                    << x->in().name()
+                    << x->in()->name()
                     << " @ "
                     << x->position()
                     << " length = " 
@@ -760,9 +608,9 @@ AudioPlaylist::dump () const
 }
 
 bool
-AudioPlaylist::destroy_region (Region* region)
+AudioPlaylist::destroy_region (boost::shared_ptr<Region> region)
 {
-       AudioRegion* r = dynamic_cast<AudioRegion*> (region);
+       boost::shared_ptr<AudioRegion> r = boost::dynamic_pointer_cast<AudioRegion> (region);
        bool changed = false;
        Crossfades::iterator c, ctmp;
        set<Crossfade*> unique_xfades;
@@ -785,7 +633,6 @@ AudioPlaylist::destroy_region (Region* region)
                        ++tmp;
                        
                        if ((*i) == region) {
-                               (*i)->unlock_sources ();
                                regions.erase (i);
                                changed = true;
                        }
@@ -798,7 +645,7 @@ AudioPlaylist::destroy_region (Region* region)
                ctmp = c;
                ++ctmp;
 
-               if ((*c)->involves (*r)) {
+               if ((*c)->involves (r)) {
                        unique_xfades.insert (*c);
                        _crossfades.erase (c);
                }
@@ -806,52 +653,6 @@ AudioPlaylist::destroy_region (Region* region)
                c = ctmp;
        }
 
-       for (StateMap::iterator s = states.begin(); s != states.end(); ) {
-               StateMap::iterator tmp;
-
-               tmp = s;
-               ++tmp;
-
-               State* astate = dynamic_cast<State*> (*s);
-               
-               for (c = astate->crossfades.begin(); c != astate->crossfades.end(); ) {
-
-                       ctmp = c;
-                       ++ctmp;
-
-                       if ((*c)->involves (*r)) {
-                               unique_xfades.insert (*c);
-                               _crossfades.erase (c);
-                       }
-
-                       c = ctmp;
-               }
-
-               list<UndoAction>::iterator rsi, rsitmp;
-               RegionList::iterator ri, ritmp;
-
-               for (ri = astate->regions.begin(), rsi = astate->region_states.begin(); 
-                    ri != astate->regions.end() && rsi != astate->region_states.end();) {
-
-
-                       ritmp = ri;
-                       ++ritmp;
-
-                       rsitmp = rsi; 
-                       ++rsitmp;
-
-                       if (region == (*ri)) {
-                               astate->regions.erase (ri);
-                               astate->region_states.erase (rsi);
-                       }
-
-                       ri = ritmp;
-                       rsi = rsitmp;
-               }
-               
-               s = tmp;
-       }
-
        for (set<Crossfade*>::iterator c = unique_xfades.begin(); c != unique_xfades.end(); ++c) {
                delete *c;
        }
@@ -877,13 +678,11 @@ AudioPlaylist::crossfade_changed (Change ignored)
           that occured.
        */
 
-       maybe_save_state (_("xfade change"));
-
        notify_modified ();
 }
 
 bool
-AudioPlaylist::region_changed (Change what_changed, Region* region)
+AudioPlaylist::region_changed (Change what_changed, boost::shared_ptr<Region> region)
 {
        if (in_flush || in_set_state) {
                return false;
@@ -900,8 +699,6 @@ AudioPlaylist::region_changed (Change what_changed, Region* region)
 
        parent_wants_notify = Playlist::region_changed (what_changed, region);
 
-       maybe_save_state (_("region modified"));
-
        if ((parent_wants_notify || (what_changed & our_interests))) {
                notify_modified ();
        }
@@ -910,12 +707,12 @@ AudioPlaylist::region_changed (Change what_changed, Region* region)
 }
 
 void
-AudioPlaylist::crossfades_at (jack_nframes_t frame, Crossfades& clist)
+AudioPlaylist::crossfades_at (nframes_t frame, Crossfades& clist)
 {
        RegionLock rlock (this);
 
        for (Crossfades::iterator i = _crossfades.begin(); i != _crossfades.end(); ++i) {
-               jack_nframes_t start, end;
+               nframes_t start, end;
 
                start = (*i)->position();
                end = start + (*i)->overlap_length(); // not length(), important difference
@@ -925,3 +722,4 @@ AudioPlaylist::crossfades_at (jack_nframes_t frame, Crossfades& clist)
                } 
        }
 }
+