From be830adccba524b4a22587340c6fe2bb31be5cd8 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Tue, 17 May 2011 16:45:22 +0000 Subject: [PATCH] not actually working attempt to copy relevant xfades into compound regions; fix compilation issues with an earlier commit git-svn-id: svn://localhost/ardour2/branches/3.0@9544 d708f5d6-7413-0410-9779-e7cbd77b26cf --- libs/ardour/ardour/audioplaylist.h | 1 + libs/ardour/ardour/playlist.h | 3 + libs/ardour/audio_playlist.cc | 132 +++++++++++++++++++++++++++-- libs/ardour/playlist.cc | 18 +++- 4 files changed, 145 insertions(+), 9 deletions(-) diff --git a/libs/ardour/ardour/audioplaylist.h b/libs/ardour/ardour/audioplaylist.h index 6c3169070f..b9ed739a79 100644 --- a/libs/ardour/ardour/audioplaylist.h +++ b/libs/ardour/ardour/audioplaylist.h @@ -104,6 +104,7 @@ public: void refresh_dependents (boost::shared_ptr region); void check_dependents (boost::shared_ptr region, bool norefresh); void remove_dependents (boost::shared_ptr region); + void copy_dependents (const std::vector&, boost::shared_ptr); private: CrossfadeListProperty _crossfades; diff --git a/libs/ardour/ardour/playlist.h b/libs/ardour/ardour/playlist.h index 7411468fe8..6385def785 100644 --- a/libs/ardour/ardour/playlist.h +++ b/libs/ardour/ardour/playlist.h @@ -379,6 +379,9 @@ public: void _split_region (boost::shared_ptr, framepos_t position); void load_nested_sources (const XMLNode& node); + + typedef std::pair, boost::shared_ptr > TwoRegions; + virtual void copy_dependents (const std::vector&, boost::shared_ptr) { } }; } /* namespace ARDOUR */ diff --git a/libs/ardour/audio_playlist.cc b/libs/ardour/audio_playlist.cc index 07a6d099ea..e120ebb5ab 100644 --- a/libs/ardour/audio_playlist.cc +++ b/libs/ardour/audio_playlist.cc @@ -187,6 +187,9 @@ AudioPlaylist::AudioPlaylist (boost::shared_ptr 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 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 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 old_in; + boost::shared_ptr new_in; + boost::shared_ptr new_out; +}; + +void +AudioPlaylist::copy_dependents (const vector& old_and_new, boost::shared_ptr other) +{ + boost::shared_ptr other_audio = boost::dynamic_pointer_cast(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,crossfade_triple> CrossfadeInfo; + CrossfadeInfo crossfade_info; + + /* build up a record that links crossfades, old regions and new regions + */ + + for (vector::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 new_xfade (new Crossfade (ci->first, + boost::dynamic_pointer_cast(ci->second.new_in), + boost::dynamic_pointer_cast(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); + } +} diff --git a/libs/ardour/playlist.cc b/libs/ardour/playlist.cc index d933594d3d..d635819963 100644 --- a/libs/ardour/playlist.cc +++ b/libs/ardour/playlist.cc @@ -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 old_and_new_regions; boost::shared_ptr 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 original_region = (*i); boost::shared_ptr 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 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 (); -- 2.30.2