not actually working attempt to copy relevant xfades into compound regions; fix compi...
authorPaul Davis <paul@linuxaudiosystems.com>
Tue, 17 May 2011 16:45:22 +0000 (16:45 +0000)
committerPaul Davis <paul@linuxaudiosystems.com>
Tue, 17 May 2011 16:45:22 +0000 (16:45 +0000)
git-svn-id: svn://localhost/ardour2/branches/3.0@9544 d708f5d6-7413-0410-9779-e7cbd77b26cf

libs/ardour/ardour/audioplaylist.h
libs/ardour/ardour/playlist.h
libs/ardour/audio_playlist.cc
libs/ardour/playlist.cc

index 6c3169070faebb25de1a5c7cd621e0c2e78165e1..b9ed739a791927e2ba329d9a0d51da6b544ca04c 100644 (file)
@@ -104,6 +104,7 @@ public:
         void refresh_dependents (boost::shared_ptr<Region> region);
         void check_dependents (boost::shared_ptr<Region> region, bool norefresh);
         void remove_dependents (boost::shared_ptr<Region> region);
+       void copy_dependents (const std::vector<TwoRegions>&, boost::shared_ptr<Playlist>);
 
     private:
        CrossfadeListProperty _crossfades;
index 7411468fe8b4b5cb5f25e18fdb30f4d674f95da4..6385def78594d57e35af60885bd738578649b90d 100644 (file)
@@ -379,6 +379,9 @@ public:
 
        void _split_region (boost::shared_ptr<Region>, framepos_t position);
        void load_nested_sources (const XMLNode& node);
+
+       typedef std::pair<boost::shared_ptr<Region>, boost::shared_ptr<Region> > TwoRegions;
+       virtual void copy_dependents (const std::vector<TwoRegions>&, boost::shared_ptr<Playlist>) { }
 };
 
 } /* namespace ARDOUR */
index 07a6d099eaa34b43408968d066299e684ba55ac4..e120ebb5ab15cf097bcffe078965cd9186d3e84d 100644 (file)
@@ -187,6 +187,9 @@ AudioPlaylist::AudioPlaylist (boost::shared_ptr<const AudioPlaylist> other, fram
 
                framecnt_t fade_in = 64;
                framecnt_t fade_out = 64;
+               framepos_t position;
+               framecnt_t len;
+               frameoffset_t offset;
 
                switch (region->coverage (start, end)) {
                case OverlapNone:
@@ -209,10 +212,10 @@ AudioPlaylist::AudioPlaylist (boost::shared_ptr<const AudioPlaylist> other, fram
                        position = region->position() - start;
                        len = end - region->position();
 
-                       if (end > region->position() + region->fade_in().back()->when)
-                               fade_in_len = region->fade_in().back()->when;  //end is after fade-in, preserve the fade-in
-                       if (end > region->last_frame() - region->fade_out().back()->when)
-                               fade_out_len = region->fade_out().back()->when - ( region->last_frame() - end );  //end is inside the fadeout, preserve the fades endpoint
+                       if (end > region->position() + region->fade_in()->back()->when)
+                               fade_in = region->fade_in()->back()->when;  //end is after fade-in, preserve the fade-in
+                       if (end > region->last_frame() - region->fade_out()->back()->when)
+                               fade_out = region->fade_out()->back()->when - ( region->last_frame() - end );  //end is inside the fadeout, preserve the fades endpoint
                        break;
                }
                
@@ -221,11 +224,11 @@ AudioPlaylist::AudioPlaylist (boost::shared_ptr<const AudioPlaylist> other, fram
                        offset = start - region->position();
                        len = region->length() - offset;
 
-                       if (start < region->last_frame() - region->fade_out().back()->when)  //start is before fade-out, preserve the fadeout
-                               fade_out_len = region->fade_out().back()->when;
+                       if (start < region->last_frame() - region->fade_out()->back()->when)  //start is before fade-out, preserve the fadeout
+                               fade_out = region->fade_out()->back()->when;
                        
-                       if (start < region->position() + region->fade_in().back()->when)
-                               fade_in_len = region->fade_in().back()->when - (start - region->position());  //end is inside the fade-in, preserve the fade-in endpoint
+                       if (start < region->position() + region->fade_in()->back()->when)
+                               fade_in = region->fade_in()->back()->when - (start - region->position());  //end is inside the fade-in, preserve the fade-in endpoint
                        break;
                }
                
@@ -964,3 +967,116 @@ AudioPlaylist::find_crossfade (const PBD::ID& id) const
 
        return *i;
 }
+
+struct crossfade_triple {
+    boost::shared_ptr<Region> old_in;
+    boost::shared_ptr<Region> new_in;
+    boost::shared_ptr<Region> new_out;
+};
+
+void
+AudioPlaylist::copy_dependents (const vector<TwoRegions>& old_and_new, boost::shared_ptr<Playlist> other)
+{
+       boost::shared_ptr<AudioPlaylist> other_audio = boost::dynamic_pointer_cast<AudioPlaylist>(other);
+
+       if (!other_audio) {
+               return;
+       }
+
+       /* our argument is a vector of old and new regions. Each old region
+          might be participant in a crossfade that is already present. Each new
+          region is a copy of the old region, present in the other playlist.
+
+          our task is to find all the relevant xfades in our playlist (involving
+          the "old" regions) and place copies of them in the other playlist.
+       */
+
+       typedef map<boost::shared_ptr<Crossfade>,crossfade_triple> CrossfadeInfo;
+       CrossfadeInfo crossfade_info;
+
+       /* build up a record that links crossfades, old regions and new regions
+        */
+
+       for (vector<TwoRegions>::const_iterator on = old_and_new.begin(); on != old_and_new.end(); ++on) {
+
+               for (Crossfades::iterator i = _crossfades.begin(); i != _crossfades.end(); ++i) {
+
+                       if ((*i)->in() == on->first) {
+                               
+                               CrossfadeInfo::iterator cf;
+
+                               if ((cf = crossfade_info.find (*i)) != crossfade_info.end()) {
+
+                                       /* already have a record for the old fade-in region, 
+                                          so note the new fade-in region
+                                       */
+                                       
+                                       cf->second.new_in = on->second;
+                                       
+                               } else {
+                                       
+                                       /* add a record of this crossfade, keeping an association
+                                          with the new fade-in region
+                                       */
+                                       
+                                       crossfade_triple ct;
+                                       
+                                       ct.old_in = on->first;
+                                       ct.new_in = on->second;
+
+                                       crossfade_info[*i] = ct;
+                               }
+
+                       } else if ((*i)->out() == on->first) {
+                               
+                               /* this old region is the fade-out region of this crossfade */
+                               
+                               CrossfadeInfo::iterator cf;
+                               
+                               if ((cf = crossfade_info.find (*i)) != crossfade_info.end()) {
+                                       
+                                       /* already have a record for this crossfade, so just keep
+                                          an association for the new fade out region
+                                       */
+                                       
+                                       cf->second.new_out = on->second;
+                                       
+                               } else {
+                                       
+                                       /* add a record of this crossfade, keeping an association
+                                          with the new fade-in region
+                                       */
+
+                                       crossfade_triple ct;
+
+                                       ct.old_in = on->first;
+                                       ct.new_out = on->second;
+
+                                       crossfade_info[*i] = ct;
+                               }
+                       }
+               }
+       }
+
+       for (CrossfadeInfo::iterator ci = crossfade_info.begin(); ci != crossfade_info.end(); ++ci) {
+               
+               /* for each crossfade that involves at least two of the old regions,
+                  create a new identical crossfade with the new regions
+               */
+               
+               if (!ci->second.new_in || !ci->second.new_out) {
+                       continue;
+               }
+
+               boost::shared_ptr<Crossfade> new_xfade (new Crossfade (ci->first, 
+                                                                      boost::dynamic_pointer_cast<AudioRegion>(ci->second.new_in),
+                                                                      boost::dynamic_pointer_cast<AudioRegion>(ci->second.new_out)));
+               
+               /* add it at the right position */
+
+               new_xfade->set_position (new_xfade->position() + (ci->second.new_in->position() - ci->second.old_in->position()), this);
+               cerr << "Add new xfade to new playlist @ " << new_xfade->position() << " len " << new_xfade->length()
+                    << " in = " << new_xfade->in()->name() << " out = " << new_xfade->out()->name() << endl;
+               other_audio->add_crossfade (new_xfade);
+       }
+}
index d933594d3da1b165f0839060911322cc32a42b1b..d635819963434fd95353efc2b9a0acdcc991f803 100644 (file)
@@ -3157,13 +3157,20 @@ Playlist::join (const RegionList& r, const std::string& name)
        uint32_t channels = 0;
        uint32_t layer = 0;
        framepos_t earliest_position = max_framepos;
+       vector<TwoRegions> old_and_new_regions;
 
        boost::shared_ptr<Playlist> pl = PlaylistFactory::create (_type, _session, name, true);
-       
+
        for (RegionList::const_iterator i = r.begin(); i != r.end(); ++i) {
                earliest_position = min (earliest_position, (*i)->position());
        }
 
+       /* enable this so that we do not try to create xfades etc. as we add
+        * regions
+        */
+
+       pl->in_partition = true;
+
        for (RegionList::const_iterator i = r.begin(); i != r.end(); ++i) {
 
                /* copy the region */
@@ -3171,6 +3178,8 @@ Playlist::join (const RegionList& r, const std::string& name)
                boost::shared_ptr<Region> original_region = (*i);
                boost::shared_ptr<Region> copied_region = RegionFactory::create (original_region, false);
 
+               old_and_new_regions.push_back (TwoRegions (original_region,copied_region));
+
                /* make position relative to zero */
 
                pl->add_region (copied_region, original_region->position() - earliest_position);
@@ -3184,6 +3193,8 @@ Playlist::join (const RegionList& r, const std::string& name)
                layer = max (layer, original_region->layer());
        }
 
+       pl->in_partition = false;
+
        /* now create a new PlaylistSource for each channel in the new playlist */
 
        SourceList sources;
@@ -3202,6 +3213,10 @@ Playlist::join (const RegionList& r, const std::string& name)
        
        boost::shared_ptr<Region> compound_region = RegionFactory::create (sources, plist, true);
 
+       /* add any dependent regions to the new playlist */
+
+       copy_dependents (old_and_new_regions, pl);
+
        /* remove all the selected regions from the current playlist
         */
 
@@ -3214,6 +3229,7 @@ Playlist::join (const RegionList& r, const std::string& name)
        /* add the new region at the right location */
        
        add_region (compound_region, earliest_position);
+
        _combine_ops++;
 
        thaw ();