summaryrefslogtreecommitdiff
path: root/libs
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2011-05-26 17:22:22 +0000
committerPaul Davis <paul@linuxaudiosystems.com>2011-05-26 17:22:22 +0000
commitd6be900da002cde17570e742bcc48f1588f73dc9 (patch)
tree8996b368649d87610329a54385960ee3c013204f /libs
parent92ede6153eaf7eaae359a456307f697d04e2fcb7 (diff)
more combine/uncombine fixes including making uncombine push the compound region gain level into the constituents and doing the right thing when we uncombine in a playlist other than the one in which the compound region was created
git-svn-id: svn://localhost/ardour2/branches/3.0@9601 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'libs')
-rw-r--r--libs/ardour/ardour/audio_playlist_source.h2
-rw-r--r--libs/ardour/ardour/playlist_source.h10
-rw-r--r--libs/ardour/ardour/source_factory.h2
-rw-r--r--libs/ardour/audio_playlist.cc67
-rw-r--r--libs/ardour/audio_playlist_source.cc4
-rw-r--r--libs/ardour/playlist.cc56
-rw-r--r--libs/ardour/playlist_source.cc10
-rw-r--r--libs/ardour/source_factory.cc4
8 files changed, 86 insertions, 69 deletions
diff --git a/libs/ardour/ardour/audio_playlist_source.h b/libs/ardour/ardour/audio_playlist_source.h
index 3514a06407..273651b7d1 100644
--- a/libs/ardour/ardour/audio_playlist_source.h
+++ b/libs/ardour/ardour/audio_playlist_source.h
@@ -56,7 +56,7 @@ class AudioPlaylistSource : public AudioSource, public PlaylistSource {
protected:
friend class SourceFactory;
- AudioPlaylistSource (Session&, const std::string& name, boost::shared_ptr<AudioPlaylist>, uint32_t chn,
+ AudioPlaylistSource (Session&, const PBD::ID& orig, const std::string& name, boost::shared_ptr<AudioPlaylist>, uint32_t chn,
frameoffset_t begin, framecnt_t len, Source::Flag flags);
AudioPlaylistSource (Session&, const XMLNode&);
diff --git a/libs/ardour/ardour/playlist_source.h b/libs/ardour/ardour/playlist_source.h
index ed48fbabd5..b41569cbdd 100644
--- a/libs/ardour/ardour/playlist_source.h
+++ b/libs/ardour/ardour/playlist_source.h
@@ -37,13 +37,15 @@ class PlaylistSource : virtual public Source {
int set_state (const XMLNode&, int version);
boost::shared_ptr<const Playlist> playlist() const { return _playlist; }
+ const PBD::ID& original() const { return _original; }
protected:
- boost::shared_ptr<Playlist> _playlist;
- frameoffset_t _playlist_offset;
- framecnt_t _playlist_length;
+ boost::shared_ptr<Playlist> _playlist;
+ PBD::ID _original;
+ frameoffset_t _playlist_offset;
+ framecnt_t _playlist_length;
- PlaylistSource (Session&, const std::string& name, boost::shared_ptr<Playlist>, DataType,
+ PlaylistSource (Session&, const PBD::ID&, const std::string& name, boost::shared_ptr<Playlist>, DataType,
frameoffset_t begin, framecnt_t len, Source::Flag flags);
PlaylistSource (Session&, const XMLNode&);
diff --git a/libs/ardour/ardour/source_factory.h b/libs/ardour/ardour/source_factory.h
index 427bf10a56..df15653c1d 100644
--- a/libs/ardour/ardour/source_factory.h
+++ b/libs/ardour/ardour/source_factory.h
@@ -56,7 +56,7 @@ class SourceFactory {
static boost::shared_ptr<Source> createFromPlaylist
- (DataType type, Session& s, boost::shared_ptr<Playlist> p, const std::string& name,
+ (DataType type, Session& s, boost::shared_ptr<Playlist> p, const PBD::ID& orig, const std::string& name,
uint32_t chn, frameoffset_t start, framecnt_t len, bool copy, bool defer_peaks);
static Glib::Cond* PeaksToBuild;
diff --git a/libs/ardour/audio_playlist.cc b/libs/ardour/audio_playlist.cc
index 59c791b8fb..7e60930e2d 100644
--- a/libs/ardour/audio_playlist.cc
+++ b/libs/ardour/audio_playlist.cc
@@ -1092,7 +1092,7 @@ AudioPlaylist::pre_combine (vector<boost::shared_ptr<Region> >& copies)
ar = boost::dynamic_pointer_cast<AudioRegion> (copies.front());
- /* copy the fade in of the first into the compound region */
+ /* disable fade in of the first region */
if (ar) {
ar->set_fade_in_active (false);
@@ -1100,6 +1100,8 @@ AudioPlaylist::pre_combine (vector<boost::shared_ptr<Region> >& copies)
ar = boost::dynamic_pointer_cast<AudioRegion> (copies.back());
+ /* disable fade out of the last region */
+
if (ar) {
ar->set_fade_out_active (false);
}
@@ -1124,7 +1126,6 @@ AudioPlaylist::post_combine (vector<boost::shared_ptr<Region> >& originals, boos
if (ar) {
cr->set_fade_in (ar->fade_in());
- ar->set_fade_in_active (false);
}
ar = boost::dynamic_pointer_cast<AudioRegion> (originals.back());
@@ -1132,13 +1133,13 @@ AudioPlaylist::post_combine (vector<boost::shared_ptr<Region> >& originals, boos
if (ar) {
/* copy the fade out of the last into the compound region */
cr->set_fade_out (ar->fade_out());
- ar->set_fade_out_active (false);
}
}
void
AudioPlaylist::pre_uncombine (vector<boost::shared_ptr<Region> >& originals, boost::shared_ptr<Region> compound_region)
{
+ RegionSortByPosition cmp;
boost::shared_ptr<AudioRegion> ar;
boost::shared_ptr<AudioRegion> cr = boost::dynamic_pointer_cast<AudioRegion>(compound_region);
@@ -1146,41 +1147,53 @@ AudioPlaylist::pre_uncombine (vector<boost::shared_ptr<Region> >& originals, boo
return;
}
+ sort (originals.begin(), originals.end(), cmp);
+
/* no need to call clear_changes() on the originals because that is
* done within Playlist::uncombine ()
*/
- if ((ar = boost::dynamic_pointer_cast<AudioRegion> (originals.front())) != 0) {
+ for (vector<boost::shared_ptr<Region> >::iterator i = originals.begin(); i != originals.end(); ++i) {
- /* copy the compound region's fade in back into the first
- original region.
- */
-
- if (cr->fade_in()->back()->when <= ar->length()) {
- /* don't do this if the fade is longer than the
- * region
- */
- ar->set_fade_in (cr->fade_in());
+ if ((ar = boost::dynamic_pointer_cast<AudioRegion> (*i)) == 0) {
+ continue;
}
- ar->set_fade_in_active (true);
- _session.add_command (new StatefulDiffCommand (originals.front()));
- }
+ /* scale the uncombined regions by any gain setting for the
+ * compound one.
+ */
- if ((ar = boost::dynamic_pointer_cast<AudioRegion> (originals.back())) != 0) {
+ ar->set_scale_amplitude (ar->scale_amplitude() * cr->scale_amplitude());
- /* copy the compound region's fade out back into the last
- original region.
- */
+ if (i == originals.begin()) {
+
+ /* copy the compound region's fade in back into the first
+ original region.
+ */
+
+ if (cr->fade_in()->back()->when <= ar->length()) {
+ /* don't do this if the fade is longer than the
+ * region
+ */
+ ar->set_fade_in (cr->fade_in());
+ }
+
+
+ } else if (*i == originals.back()) {
+
+ /* copy the compound region's fade out back into the last
+ original region.
+ */
+
+ if (cr->fade_out()->back()->when <= ar->length()) {
+ /* don't do this if the fade is longer than the
+ * region
+ */
+ ar->set_fade_out (cr->fade_out());
+ }
- if (cr->fade_out()->back()->when <= ar->length()) {
- /* don't do this if the fade is longer than the
- * region
- */
- ar->set_fade_out (cr->fade_out());
}
- ar->set_fade_out_active (true);
- _session.add_command (new StatefulDiffCommand (originals.back()));
+ _session.add_command (new StatefulDiffCommand (*i));
}
}
diff --git a/libs/ardour/audio_playlist_source.cc b/libs/ardour/audio_playlist_source.cc
index 882a1710e7..393f90938b 100644
--- a/libs/ardour/audio_playlist_source.cc
+++ b/libs/ardour/audio_playlist_source.cc
@@ -46,11 +46,11 @@ using namespace std;
using namespace ARDOUR;
using namespace PBD;
-AudioPlaylistSource::AudioPlaylistSource (Session& s, const std::string& name, boost::shared_ptr<AudioPlaylist> p,
+AudioPlaylistSource::AudioPlaylistSource (Session& s, const ID& orig, const std::string& name, boost::shared_ptr<AudioPlaylist> p,
uint32_t chn, frameoffset_t begin, framecnt_t len, Source::Flag flags)
: Source (s, DataType::AUDIO, name)
, AudioSource (s, name)
- , PlaylistSource (s, name, p, DataType::AUDIO, begin, len, flags)
+ , PlaylistSource (s, orig, name, p, DataType::AUDIO, begin, len, flags)
, _playlist_channel (chn)
{
AudioSource::_length = len;
diff --git a/libs/ardour/playlist.cc b/libs/ardour/playlist.cc
index 3f7eb1852d..a396732d56 100644
--- a/libs/ardour/playlist.cc
+++ b/libs/ardour/playlist.cc
@@ -3133,9 +3133,8 @@ Playlist::combine (const RegionList& r)
pair<framepos_t,framepos_t> extent = pl->get_extent();
for (uint32_t chn = 0; chn < channels; ++chn) {
- sources.push_back (SourceFactory::createFromPlaylist (_type, _session, pl, parent_name, chn, 0, extent.second, false, false));
+ sources.push_back (SourceFactory::createFromPlaylist (_type, _session, pl, id(), parent_name, chn, 0, extent.second, false, false));
}
-
/* now a new whole-file region using the list of sources */
@@ -3191,12 +3190,12 @@ Playlist::combine (const RegionList& r)
void
Playlist::uncombine (boost::shared_ptr<Region> target)
{
- // (1) check that its really a compound region
-
boost::shared_ptr<PlaylistSource> pls;
boost::shared_ptr<const Playlist> pl;
vector<boost::shared_ptr<Region> > originals;
+ // (1) check that its really a compound region
+
if ((pls = boost::dynamic_pointer_cast<PlaylistSource>(target->source (0))) == 0) {
return;
}
@@ -3215,14 +3214,23 @@ Playlist::uncombine (boost::shared_ptr<Region> target)
the length of the region.
*/
-
- cerr << "Compound region: bounds within nested playlist = " << adjusted_start << " .. " << adjusted_end << endl;
-
// (2) get all the original regions
const RegionList& rl (pl->region_list().rlist());
RegionFactory::CompoundAssociations& cassocs (RegionFactory::compound_associations());
frameoffset_t move_offset = 0;
+
+ /* there are two possibilities here:
+ 1) the playlist that the playlist source was based on
+ is us, so just add the originals (which belonged to
+ us anyway) back in the right place.
+
+ 2) the playlist that the playlist source was based on
+ is NOT us, so we need to make copies of each of
+ the original regions that we find, and add them
+ instead.
+ */
+ bool same_playlist = (pls->original() == id());
for (RegionList::const_iterator i = rl.begin(); i != rl.end(); ++i) {
@@ -3239,19 +3247,18 @@ Playlist::uncombine (boost::shared_ptr<Region> target)
if (i == rl.begin()) {
move_offset = (target->position() - original->position()) - target->start();
-
-
- cerr << "Move offset is " << target->position() << " - " << original->position()
- << " - " << target->start() << " = " << move_offset
- << endl;
-
adjusted_start = original->position() + target->start();
adjusted_end = adjusted_start + target->length();
+ }
- cerr << "adjusted range = " << adjusted_start << " based on "
- << original->position() << " + " << target->start() << " .. "
- << adjusted_end << " from " << target->length()
- << endl;
+ if (!same_playlist) {
+ framepos_t pos = original->position();
+ /* make a copy, but don't announce it */
+ original = RegionFactory::create (original, false);
+ /* the pure copy constructor resets position() to zero,
+ so fix that up.
+ */
+ original->set_position (pos, this);
}
/* check to see how the original region (in the
@@ -3259,12 +3266,6 @@ Playlist::uncombine (boost::shared_ptr<Region> target)
* with the new state of the compound region.
*/
- cerr << "Original " << original->name()
- << " overlaptype = " << enum_2_string (original->coverage (adjusted_start, adjusted_end))
- << " target range: " << adjusted_start << " .. " << adjusted_end
- << " orig range: " << original->position() << " .. " << original->last_frame ()
- << endl;
-
original->clear_changes ();
modified_region = false;
@@ -3273,7 +3274,6 @@ Playlist::uncombine (boost::shared_ptr<Region> target)
/* original region does not cover any part
of the current state of the compound region
*/
- cerr << "Not present - skip\n";
continue;
case OverlapInternal:
@@ -3282,14 +3282,12 @@ Playlist::uncombine (boost::shared_ptr<Region> target)
*/
original->trim_to (adjusted_start, adjusted_end - adjusted_start, this);
modified_region = true;
- cerr << "trim to\n";
break;
case OverlapExternal:
/* overlap fully covers original, so leave it
as is
*/
- cerr << "leave as is\n";
break;
case OverlapEnd:
@@ -3298,7 +3296,6 @@ Playlist::uncombine (boost::shared_ptr<Region> target)
*/
original->trim_front (adjusted_start, this);
modified_region = true;
- cerr << "trim front\n";
break;
case OverlapStart:
@@ -3307,14 +3304,12 @@ Playlist::uncombine (boost::shared_ptr<Region> target)
*/
original->trim_end (adjusted_end, this);
modified_region = true;
- cerr << "trim end\n";
break;
}
if (move_offset) {
/* fix the position to match any movement of the compound region.
*/
- cerr << "Moving region to new position based on " << original->position() << " + " << move_offset << endl;
original->set_position (original->position() + move_offset, this);
modified_region = true;
}
@@ -3339,8 +3334,7 @@ Playlist::uncombine (boost::shared_ptr<Region> target)
remove_region (target);
- // (4) add the originals. This will reset their playlist reference back
- // to us, which means they are no longer considered owned by the RegionFactory
+ // (4) add the constituent regions
for (vector<boost::shared_ptr<Region> >::iterator i = originals.begin(); i != originals.end(); ++i) {
add_region ((*i), (*i)->position());
diff --git a/libs/ardour/playlist_source.cc b/libs/ardour/playlist_source.cc
index a1597a76d2..7bbfdecd82 100644
--- a/libs/ardour/playlist_source.cc
+++ b/libs/ardour/playlist_source.cc
@@ -43,10 +43,11 @@ using namespace std;
using namespace ARDOUR;
using namespace PBD;
-PlaylistSource::PlaylistSource (Session& s, const std::string& name, boost::shared_ptr<Playlist> p, DataType type,
+PlaylistSource::PlaylistSource (Session& s, const ID& orig, const std::string& name, boost::shared_ptr<Playlist> p, DataType type,
frameoffset_t begin, framecnt_t len, Source::Flag flags)
: Source (s, type, name)
, _playlist (p)
+ , _original (orig)
{
/* PlaylistSources are never writable, renameable, removable or destructive */
_flags = Flag (_flags & ~(Writable|CanRename|Removable|RemovableIfEmpty|RemoveAtDestroy|Destructive));
@@ -85,6 +86,7 @@ PlaylistSource::add_state (XMLNode& node)
node.add_property ("offset", buf);
snprintf (buf, sizeof (buf), "%" PRIu64, _playlist_length);
node.add_property ("length", buf);
+ node.add_property ("original", _id.to_s());
node.add_child_nocopy (_playlist->get_state());
}
@@ -139,6 +141,12 @@ PlaylistSource::set_state (const XMLNode& node, int version)
sscanf (prop->value().c_str(), "%" PRIu64, &_playlist_length);
+ if ((prop = node.property (X_("original"))) == 0) {
+ throw failed_constructor ();
+ }
+
+ _id = prop->value();
+
_level = _playlist->max_source_level () + 1;
return 0;
diff --git a/libs/ardour/source_factory.cc b/libs/ardour/source_factory.cc
index 57f0fdc1ec..afc92c450c 100644
--- a/libs/ardour/source_factory.cc
+++ b/libs/ardour/source_factory.cc
@@ -347,7 +347,7 @@ SourceFactory::createWritable (DataType type, Session& s, const std::string& pat
}
boost::shared_ptr<Source>
-SourceFactory::createFromPlaylist (DataType type, Session& s, boost::shared_ptr<Playlist> p, const std::string& name,
+SourceFactory::createFromPlaylist (DataType type, Session& s, boost::shared_ptr<Playlist> p, const ID& orig, const std::string& name,
uint32_t chn, frameoffset_t start, framecnt_t len, bool copy, bool defer_peaks)
{
if (type == DataType::AUDIO) {
@@ -362,7 +362,7 @@ SourceFactory::createFromPlaylist (DataType type, Session& s, boost::shared_ptr<
start = 0;
}
- Source* src = new AudioPlaylistSource (s, name, ap, chn, start, len, Source::Flag (0));
+ Source* src = new AudioPlaylistSource (s, orig, name, ap, chn, start, len, Source::Flag (0));
boost::shared_ptr<Source> ret (src);
if (setup_peakfile (ret, defer_peaks)) {