Large nasty commit in the form of a 5000 line patch chock-full of completely
[ardour.git] / libs / ardour / audio_playlist.cc
index 6f4217c3ec6c125a766894a75bc23ba538f396a1..be5c9ab5d95c563002bf818bb2802e0c33fa0214 100644 (file)
@@ -37,6 +37,7 @@
 using namespace ARDOUR;
 using namespace sigc;
 using namespace std;
+using namespace PBD;
 
 AudioPlaylist::State::~State ()
 {
@@ -203,7 +204,7 @@ AudioPlaylist::read (Sample *buf, Sample *mixdown_buffer, float *gain_buffer, ch
           its OK to block (for short intervals).
        */
 
-       LockMonitor rm (region_lock, __LINE__, __FILE__);
+       Glib::Mutex::Lock rm (region_lock);
 
        end =  start + cnt - 1;
 
@@ -242,16 +243,18 @@ AudioPlaylist::read (Sample *buf, Sample *mixdown_buffer, float *gain_buffer, ch
 
        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<Crossfade*>& x (relevant_xfades[*l]);
 
                for (vector<Region*>::iterator i = r.begin(); i != r.end(); ++i) {
-                       (*i)->read_at (buf, mixdown_buffer, gain_buffer, workbuf, start, cnt, chan_n, read_frames, skip_frames);
-                       _read_data_count += (*i)->read_data_count();
+                       AudioRegion* const ar = dynamic_cast<AudioRegion*>(*i);
+                       assert(ar);
+                       ar->read_at (buf, mixdown_buffer, gain_buffer, workbuf, start, cnt, chan_n, read_frames, skip_frames);
+                       _read_data_count += ar->read_data_count();
                }
                
                for (vector<Crossfade*>::iterator i = x.begin(); i != x.end(); ++i) {
-                       
                        (*i)->read_at (buf, mixdown_buffer, gain_buffer, workbuf, start, cnt, chan_n);
 
                        /* don't JACK up _read_data_count, since its the same data as we just
@@ -351,17 +354,36 @@ AudioPlaylist::finalize_split_region (Region *o, Region *l, Region *r)
        AudioRegion *left  = dynamic_cast<AudioRegion*>(l);
        AudioRegion *right = dynamic_cast<AudioRegion*>(r);
 
-       for (Crossfades::iterator x = _crossfades.begin(); x != _crossfades.end(); ++x) {
+       for (Crossfades::iterator x = _crossfades.begin(); x != _crossfades.end();) {
                Crossfades::iterator tmp;
+               tmp = x;
+               ++tmp;
 
+               Crossfade *fade = 0;
+               
                if ((*x)->_in == orig) {
-                       (*x)->_in = left;
+                       if (! (*x)->covers(right->position())) {
+                               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);
+                       }
                }
-
+               
                if ((*x)->_out == orig) {
-                       (*x)->_out = right;
+                       if (! (*x)->covers(right->position())) {
+                               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);
+                       }
                }
                
+               if (fade) {
+                       _crossfades.remove( (*x) );
+                       add_crossfade (*fade);
+               }
+               x = tmp;
        }
 }
 
@@ -485,7 +507,7 @@ AudioPlaylist::add_crossfade (Crossfade& xfade)
        
 void AudioPlaylist::notify_crossfade_added (Crossfade *x)
 {
-       if (atomic_read(&block_notifications)) {
+       if (g_atomic_int_get(&block_notifications)) {
                _pending_xfade_adds.insert (_pending_xfade_adds.end(), x);
        } else {
                NewCrossfade (x); /* EMIT SIGNAL */
@@ -867,8 +889,14 @@ AudioPlaylist::get_equivalent_regions (const AudioRegion& other, vector<AudioReg
 
                AudioRegion* ar = dynamic_cast<AudioRegion*> (*i);
 
-               if (ar && ar->equivalent (other)) {
-                       results.push_back (ar);
+               if (ar) {
+                       if (Config->get_use_overlap_equivalency()) {
+                               if (ar->overlap_equivalent (other)) {
+                                       results.push_back (ar);
+                               } else if (ar->equivalent (other)) {
+                                       results.push_back (ar);
+                               }
+                       }
                }
        }
 }