Add AutomationControl::parameter() for terseness.
[ardour.git] / libs / ardour / audio_playlist.cc
index 06060061e0599f76629f5bf3b12a65e318842329..d28d88488ed651b853eb7b8d231142ec127a2f32 100644 (file)
@@ -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 <algorithm>
@@ -31,6 +30,7 @@
 #include <ardour/crossfade.h>
 #include <ardour/crossfade_compare.h>
 #include <ardour/session.h>
+#include <pbd/enumwriter.h>
 
 #include "i18n.h"
 
@@ -40,15 +40,18 @@ using namespace std;
 using namespace PBD;
 
 AudioPlaylist::AudioPlaylist (Session& session, const XMLNode& node, bool hidden)
-       : Playlist (session, node, hidden)
+       : Playlist (session, node, DataType::AUDIO, hidden)
 {
+       const XMLProperty* prop = node.property("type");
+       assert(!prop || DataType(prop->value()) == DataType::AUDIO);
+
        in_set_state++;
        set_state (node);
        in_set_state--;
 }
 
 AudioPlaylist::AudioPlaylist (Session& session, string name, bool hidden)
-       : Playlist (session, name, hidden)
+       : Playlist (session, name, DataType::AUDIO, hidden)
 {
 }
 
@@ -76,7 +79,7 @@ AudioPlaylist::AudioPlaylist (boost::shared_ptr<const AudioPlaylist> other, stri
                                        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);
-                                               boost::shared_ptr<Crossfade> new_fade = boost::shared_ptr<Crossfade> (new Crossfade (*(*xfades), in, out));
+                                               boost::shared_ptr<Crossfade> new_fade = boost::shared_ptr<Crossfade> (new Crossfade (*xfades, in, out));
                                                add_crossfade(new_fade);
                                                break;
                                        }
@@ -106,24 +109,21 @@ AudioPlaylist::~AudioPlaylist ()
        /* drop connections to signals */
 
        notify_callbacks ();
-
+       
        _crossfades.clear ();
 }
 
 struct RegionSortByLayer {
-    bool operator() (boost::shared_ptr<Region>a, boost::shared_ptr<Region>b) {
+    bool operator() (boost::shared_ptr<Region> a, boost::shared_ptr<Region> b) {
            return a->layer() < b->layer();
     }
 };
 
-nframes_t
+ARDOUR::nframes_t
 AudioPlaylist::read (Sample *buf, Sample *mixdown_buffer, float *gain_buffer, nframes_t start,
                     nframes_t cnt, unsigned chan_n)
 {
-       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 
@@ -148,8 +148,6 @@ AudioPlaylist::read (Sample *buf, Sample *mixdown_buffer, float *gain_buffer, nf
 
        end =  start + cnt - 1;
 
-       read_frames = 0;
-       skip_frames = 0;
        _read_data_count = 0;
 
        map<uint32_t,vector<boost::shared_ptr<Region> > > relevant_regions;
@@ -188,7 +186,7 @@ AudioPlaylist::read (Sample *buf, Sample *mixdown_buffer, float *gain_buffer, nf
                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);
+                       ar->read_at (buf, mixdown_buffer, gain_buffer, start, cnt, chan_n);
                        _read_data_count += ar->read_data_count();
                }
                
@@ -201,7 +199,7 @@ AudioPlaylist::read (Sample *buf, Sample *mixdown_buffer, float *gain_buffer, nf
                }
        }
 
-       return ret;
+       return cnt;
 }
 
 
@@ -274,9 +272,14 @@ AudioPlaylist::refresh_dependents (boost::shared_ptr<Region> 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);
+                               try { 
+                                       if ((*x)->refresh ()) {
+                                               updated.insert (*x);
+                                       }
+                               }
+
+                               catch (Crossfade::NoCrossfadeHere& err) {
+                                       // relax, Invalidated during refresh
                                }
                        }
                }
@@ -301,19 +304,19 @@ AudioPlaylist::finalize_split_region (boost::shared_ptr<Region> o, boost::shared
                
                if ((*x)->_in == orig) {
                        if (! (*x)->covers(right->position())) {
-                               fade = boost::shared_ptr<Crossfade> (new Crossfade (**x, left, (*x)->_out));
+                               fade = boost::shared_ptr<Crossfade> (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<Crossfade> (new Crossfade (**x, right, (*x)->_out));
+                               fade = boost::shared_ptr<Crossfade> (new Crossfade (*x, right, (*x)->_out));
                        }
                }
                
                if ((*x)->_out == orig) {
                        if (! (*x)->covers(right->position())) {
-                               fade = boost::shared_ptr<Crossfade> (new Crossfade (**x, (*x)->_in, right));
+                               fade = boost::shared_ptr<Crossfade> (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<Crossfade> (new Crossfade (**x, (*x)->_in, left));
+                               fade = boost::shared_ptr<Crossfade> (new Crossfade (*x, (*x)->_in, left));
                        }
                }
                
@@ -348,6 +351,7 @@ AudioPlaylist::check_dependents (boost::shared_ptr<Region> r, bool norefresh)
                refresh_dependents (r);
        }
 
+
        if (!Config->get_auto_xfade()) {
                return;
        }
@@ -376,8 +380,9 @@ AudioPlaylist::check_dependents (boost::shared_ptr<Region> r, bool norefresh)
                }
 
 
+
                OverlapType c = top->coverage (bottom->position(), bottom->last_frame());
-               
+
                try {
                        switch (c) {
                        case OverlapNone:
@@ -406,7 +411,7 @@ AudioPlaylist::check_dependents (boost::shared_ptr<Region> r, bool norefresh)
                                
                                xfade = boost::shared_ptr<Crossfade> (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 
@@ -468,9 +473,10 @@ void AudioPlaylist::notify_crossfade_added (boost::shared_ptr<Crossfade> x)
 }
 
 void
-AudioPlaylist::crossfade_invalidated (boost::shared_ptr<Crossfade> xfade)
+AudioPlaylist::crossfade_invalidated (boost::shared_ptr<Region> r)
 {
        Crossfades::iterator i;
+       boost::shared_ptr<Crossfade> xfade = boost::dynamic_pointer_cast<Crossfade> (r);
 
        xfade->in()->resume_fade_in ();
        xfade->out()->resume_fade_out ();