summaryrefslogtreecommitdiff
path: root/libs/ardour
diff options
context:
space:
mode:
authorCarl Hetherington <carl@carlh.net>2011-12-30 20:05:48 +0000
committerCarl Hetherington <carl@carlh.net>2011-12-30 20:05:48 +0000
commitdd53e7284ae1ef8ae594cb1a34db6500f944eab3 (patch)
tree88efed9f99a937cb065f8cbff81c441d8d3abcfb /libs/ardour
parent2c23ff8ceb51297aee7ae71d96e9b61dc9089343 (diff)
Set up layering_index immediately on an explicit layer, so that undo
works properly. Stop the layer being a stateful property, as it is always derived from layering_index, unambigiously, by relayer(). git-svn-id: svn://localhost/ardour2/branches/3.0@11120 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'libs/ardour')
-rw-r--r--libs/ardour/ardour/playlist.h4
-rw-r--r--libs/ardour/ardour/region.h8
-rw-r--r--libs/ardour/audio_diskstream.cc2
-rw-r--r--libs/ardour/audio_playlist.cc2
-rw-r--r--libs/ardour/audioregion.cc2
-rw-r--r--libs/ardour/midi_playlist.cc2
-rw-r--r--libs/ardour/playlist.cc131
-rw-r--r--libs/ardour/region.cc33
8 files changed, 81 insertions, 103 deletions
diff --git a/libs/ardour/ardour/playlist.h b/libs/ardour/ardour/playlist.h
index a7ead83eef..67cc1ccf54 100644
--- a/libs/ardour/ardour/playlist.h
+++ b/libs/ardour/ardour/playlist.h
@@ -223,6 +223,8 @@ public:
uint32_t combine_ops() const { return _combine_ops; }
uint64_t highest_layering_index () const;
+
+ void set_layer (boost::shared_ptr<Region>, double);
protected:
friend class Session;
@@ -271,7 +273,7 @@ public:
bool save_on_thaw;
std::string last_save_reason;
uint32_t in_set_state;
- bool in_update;
+ bool in_undo;
bool first_set_state;
bool _hidden;
bool _splicing;
diff --git a/libs/ardour/ardour/region.h b/libs/ardour/ardour/region.h
index ab1559fc4a..cf180556b4 100644
--- a/libs/ardour/ardour/region.h
+++ b/libs/ardour/ardour/region.h
@@ -294,10 +294,6 @@ class Region
void invalidate_transients ();
- void set_pending_layer (double);
- bool reset_pending_layer ();
- boost::optional<double> pending_layer () const;
-
void drop_sources ();
protected:
@@ -341,7 +337,6 @@ class Region
PBD::Property<framepos_t> _position;
/** Sync position relative to the start of our file */
PBD::Property<framepos_t> _sync_position;
- PBD::Property<layer_t> _layer;
SourceList _sources;
/** Used when timefx are applied, so we can always use the original source */
@@ -389,8 +384,7 @@ class Region
framepos_t _last_position;
mutable RegionEditState _first_edit;
Timecode::BBT_Time _bbt_time;
-
- boost::optional<double> _pending_layer;
+ layer_t _layer;
void register_properties ();
diff --git a/libs/ardour/audio_diskstream.cc b/libs/ardour/audio_diskstream.cc
index 9a227bf7a5..037ff34eb5 100644
--- a/libs/ardour/audio_diskstream.cc
+++ b/libs/ardour/audio_diskstream.cc
@@ -1511,8 +1511,8 @@ AudioDiskstream::transport_stopped_wallclock (struct tm& when, time_t twhen, boo
i_am_the_modifier++;
- region->set_pending_layer (max_layer);
_playlist->add_region (region, (*ci)->start, 1, non_layered());
+ _playlist->set_layer (region, DBL_MAX);
i_am_the_modifier--;
buffer_position += (*ci)->frames;
diff --git a/libs/ardour/audio_playlist.cc b/libs/ardour/audio_playlist.cc
index b62aeb3ee7..fca042e2c5 100644
--- a/libs/ardour/audio_playlist.cc
+++ b/libs/ardour/audio_playlist.cc
@@ -113,6 +113,8 @@ AudioPlaylist::AudioPlaylist (Session& session, const XMLNode& node, bool hidden
throw failed_constructor();
}
in_set_state--;
+
+ relayer ();
}
AudioPlaylist::AudioPlaylist (Session& session, string name, bool hidden)
diff --git a/libs/ardour/audioregion.cc b/libs/ardour/audioregion.cc
index 5ea7b5cbef..e8681cd32c 100644
--- a/libs/ardour/audioregion.cc
+++ b/libs/ardour/audioregion.cc
@@ -1071,7 +1071,7 @@ AudioRegion::separate_by_channel (Session& /*session*/, vector<boost::shared_ptr
plist.add (Properties::start, _start.val());
plist.add (Properties::length, _length.val());
plist.add (Properties::name, new_name);
- plist.add (Properties::layer, _layer.val());
+ plist.add (Properties::layer, layer ());
v.push_back(RegionFactory::create (srcs, plist));
v.back()->set_whole_file (false);
diff --git a/libs/ardour/midi_playlist.cc b/libs/ardour/midi_playlist.cc
index 39f603a6e9..84bcc70d0b 100644
--- a/libs/ardour/midi_playlist.cc
+++ b/libs/ardour/midi_playlist.cc
@@ -57,6 +57,8 @@ MidiPlaylist::MidiPlaylist (Session& session, const XMLNode& node, bool hidden)
throw failed_constructor ();
}
in_set_state--;
+
+ relayer ();
}
MidiPlaylist::MidiPlaylist (Session& session, string name, bool hidden)
diff --git a/libs/ardour/playlist.cc b/libs/ardour/playlist.cc
index 7ef59645d1..cd45eb5d47 100644
--- a/libs/ardour/playlist.cc
+++ b/libs/ardour/playlist.cc
@@ -310,7 +310,7 @@ Playlist::init (bool hide)
_shuffling = false;
_nudging = false;
in_set_state = 0;
- in_update = false;
+ in_undo = false;
_edit_mode = Config->get_edit_mode();
in_flush = false;
in_partition = false;
@@ -396,7 +396,7 @@ Playlist::set_name (const string& str)
void
Playlist::begin_undo ()
{
- in_update = true;
+ in_undo = true;
freeze ();
}
@@ -404,7 +404,7 @@ void
Playlist::end_undo ()
{
thaw (true);
- in_update = false;
+ in_undo = false;
}
void
@@ -563,7 +563,7 @@ Playlist::flush_notifications (bool from_undo)
{
set<boost::shared_ptr<Region> > dependent_checks_needed;
set<boost::shared_ptr<Region> >::iterator s;
- uint32_t regions_changed = false;
+ bool regions_changed = false;
if (in_flush) {
return;
@@ -603,14 +603,17 @@ Playlist::flush_notifications (bool from_undo)
dependent_checks_needed.insert (*s);
}
+ if (
+ ((regions_changed || pending_contents_change) && !in_set_state) ||
+ pending_layering
+ ) {
+
+ relayer ();
+ }
+
if (regions_changed || pending_contents_change) {
- if (!in_set_state) {
- relayer ();
- }
pending_contents_change = false;
- // cerr << _name << " sends 5 contents change @ " << get_microseconds() << endl;
ContentsChanged (); /* EMIT SIGNAL */
- // cerr << _name << "done contents change @ " << get_microseconds() << endl;
}
for (s = pending_adds.begin(); s != pending_adds.end(); ++s) {
@@ -665,8 +668,8 @@ Playlist::flush_notifications (bool from_undo)
}
if (itimes >= 1) {
- region->set_pending_layer (DBL_MAX);
add_region_internal (region, pos);
+ set_layer (region, DBL_MAX);
pos += region->length();
--itimes;
}
@@ -678,8 +681,8 @@ Playlist::flush_notifications (bool from_undo)
for (int i = 0; i < itimes; ++i) {
boost::shared_ptr<Region> copy = RegionFactory::create (region, true);
- copy->set_pending_layer (DBL_MAX);
add_region_internal (copy, pos);
+ set_layer (copy, DBL_MAX);
pos += region->length();
}
@@ -699,8 +702,8 @@ Playlist::flush_notifications (bool from_undo)
plist.add (Properties::layer, region->layer());
boost::shared_ptr<Region> sub = RegionFactory::create (region, plist);
- sub->set_pending_layer (DBL_MAX);
add_region_internal (sub, pos);
+ set_layer (sub, DBL_MAX);
}
}
@@ -767,8 +770,8 @@ Playlist::flush_notifications (bool from_undo)
_splicing = true;
remove_region_internal (old);
- newr->set_pending_layer (newr->layer ());
add_region_internal (newr, pos);
+ set_layer (newr, old->layer ());
_splicing = old_sp;
@@ -1207,8 +1210,8 @@ Playlist::flush_notifications (bool from_undo)
the ordering they had in the original playlist.
*/
- copy_of_region->set_pending_layer (copy_of_region->layer() + top);
add_region_internal (copy_of_region, (*i)->position() + pos);
+ set_layer (copy_of_region, copy_of_region->layer() + top);
}
pos += shift;
}
@@ -1229,8 +1232,8 @@ Playlist::flush_notifications (bool from_undo)
while (itimes--) {
boost::shared_ptr<Region> copy = RegionFactory::create (region, true);
- copy->set_pending_layer (DBL_MAX);
add_region_internal (copy, pos);
+ set_layer (copy, DBL_MAX);
pos += region->length();
}
@@ -1247,8 +1250,8 @@ Playlist::flush_notifications (bool from_undo)
plist.add (Properties::name, name);
boost::shared_ptr<Region> sub = RegionFactory::create (region, plist);
- sub->set_pending_layer (DBL_MAX);
add_region_internal (sub, pos);
+ set_layer (sub, DBL_MAX);
}
}
}
@@ -2185,7 +2188,10 @@ Playlist::flush_notifications (bool from_undo)
return -1;
}
- add_region (region, region->position(), 1.0);
+ {
+ RegionLock rlock (this);
+ add_region_internal (region, region->position());
+ }
region->resume_property_changes ();
@@ -2210,6 +2216,7 @@ Playlist::flush_notifications (bool from_undo)
in_set_state--;
first_set_state = false;
+
return ret;
}
@@ -2340,12 +2347,46 @@ struct RelayerSort {
}
};
+/** Set a new layer for a region. This adjusts the layering indices of all
+ * regions in the playlist to put the specified region in the appropriate
+ * place. The actual layering will be fixed up when relayer() happens.
+ */
+
+void
+Playlist::set_layer (boost::shared_ptr<Region> region, double new_layer)
+{
+ /* Remove the layer we are setting from our region list, and sort it */
+ RegionList copy = regions.rlist();
+ copy.remove (region);
+ copy.sort (RelayerSort ());
+
+ /* Put region back in the right place */
+ RegionList::iterator i = copy.begin();
+ while (i != copy.end ()) {
+ if ((*i)->layer() > new_layer) {
+ break;
+ }
+ ++i;
+ }
+
+ copy.insert (i, region);
+
+ /* Then re-write layering indices */
+ uint64_t j = 0;
+ for (RegionList::iterator k = copy.begin(); k != copy.end(); ++k) {
+ (*k)->set_layering_index (j++);
+ }
+}
+
+/** Take the layering indices of each of our regions, compute the layers
+ * that they should be on, and write the layers back to the regions.
+ */
void
Playlist::relayer ()
{
- /* never compute layers when changing state for undo/redo or setting from XML */
+ /* never compute layers when setting from XML */
- if (in_update || in_set_state) {
+ if (in_set_state) {
return;
}
@@ -2373,47 +2414,12 @@ Playlist::relayer ()
vector<vector<RegionList> > layers;
layers.push_back (vector<RegionList> (divisions));
+ /* Sort our regions into layering index order */
RegionList copy = regions.rlist();
- RegionList pending;
-
- /* Remove regions with pending relayers */
- for (RegionList::iterator i = copy.begin(); i != copy.end(); ) {
-
- RegionList::iterator j = i;
- ++j;
-
- if ((*i)->pending_layer()) {
- pending.push_back (*i);
- copy.erase (i);
- }
-
- i = j;
- }
-
- /* Sort the remainder */
copy.sort (RelayerSort ());
- /* Re-insert the pending layers in the right places */
- for (RegionList::iterator i = pending.begin(); i != pending.end(); ++i) {
- RegionList::iterator j = copy.begin();
- while (j != copy.end ()) {
- if ((*j)->pending_layer().get_value_or ((*j)->layer ()) > (*i)->pending_layer().get ()) {
- break;
- }
- ++j;
- }
- copy.insert (j, *i);
- }
-
- bool had_pending = false;
-
for (RegionList::iterator i = copy.begin(); i != copy.end(); ++i) {
- /* reset the pending layer for every region now that we're relayering */
- if ((*i)->reset_pending_layer ()) {
- had_pending = true;
- }
-
/* find the time divisions that this region covers; if there are no regions on the list,
division_size will equal 0 and in this case we'll just say that
start_division = end_division = 0.
@@ -2482,40 +2488,33 @@ Playlist::relayer ()
if (changed) {
notify_layering_changed ();
}
-
- if (had_pending) {
- uint64_t i = 0;
- for (RegionList::iterator j = copy.begin(); j != copy.end(); ++j) {
- (*j)->set_layering_index (i++);
- }
- }
}
void
Playlist::raise_region (boost::shared_ptr<Region> region)
{
- region->set_pending_layer (region->layer() + 1.5);
+ set_layer (region, region->layer() + 1.5);
relayer ();
}
void
Playlist::lower_region (boost::shared_ptr<Region> region)
{
- region->set_pending_layer (region->layer() - 1.5);
+ set_layer (region, region->layer() - 1.5);
relayer ();
}
void
Playlist::raise_region_to_top (boost::shared_ptr<Region> region)
{
- region->set_pending_layer (DBL_MAX);
+ set_layer (region, DBL_MAX);
relayer ();
}
void
Playlist::lower_region_to_bottom (boost::shared_ptr<Region> region)
{
- region->set_pending_layer (-0.5);
+ set_layer (region, -0.5);
relayer ();
}
diff --git a/libs/ardour/region.cc b/libs/ardour/region.cc
index 0ec8ee001b..d863a0e6fd 100644
--- a/libs/ardour/region.cc
+++ b/libs/ardour/region.cc
@@ -154,7 +154,6 @@ Region::register_properties ()
add_property (_length);
add_property (_position);
add_property (_sync_position);
- add_property (_layer);
add_property (_ancestral_start);
add_property (_ancestral_length);
add_property (_stretch);
@@ -172,7 +171,6 @@ Region::register_properties ()
, _length (Properties::length, (l)) \
, _position (Properties::position, 0) \
, _sync_position (Properties::sync_position, (s)) \
- , _layer (Properties::layer, 0) \
, _muted (Properties::muted, false) \
, _opaque (Properties::opaque, true) \
, _locked (Properties::locked, false) \
@@ -198,7 +196,6 @@ Region::register_properties ()
, _length(Properties::length, other->_length) \
, _position(Properties::position, other->_position) \
, _sync_position(Properties::sync_position, other->_sync_position) \
- , _layer (Properties::layer, other->_layer) \
, _muted (Properties::muted, other->_muted) \
, _opaque (Properties::opaque, other->_opaque) \
, _locked (Properties::locked, other->_locked) \
@@ -223,6 +220,7 @@ Region::Region (Session& s, framepos_t start, framecnt_t length, const string& n
, _last_length (length)
, _last_position (0)
, _first_edit (EditChangesNothing)
+ , _layer (0)
{
register_properties ();
@@ -237,6 +235,7 @@ Region::Region (const SourceList& srcs)
, _last_length (0)
, _last_position (0)
, _first_edit (EditChangesNothing)
+ , _layer (0)
{
register_properties ();
@@ -256,6 +255,7 @@ Region::Region (boost::shared_ptr<const Region> other)
, _last_length (other->_last_length)
, _last_position(other->_last_position) \
, _first_edit (EditChangesNothing)
+ , _layer (other->_layer)
{
register_properties ();
@@ -325,6 +325,7 @@ Region::Region (boost::shared_ptr<const Region> other, frameoffset_t offset)
, _last_length (other->_last_length)
, _last_position(other->_last_position) \
, _first_edit (EditChangesNothing)
+ , _layer (other->_layer)
{
register_properties ();
@@ -379,6 +380,7 @@ Region::Region (boost::shared_ptr<const Region> other, const SourceList& srcs)
, _last_length (other->_last_length)
, _last_position (other->_last_position)
, _first_edit (EditChangesID)
+ , _layer (other->_layer)
{
register_properties ();
@@ -1115,11 +1117,7 @@ Region::lower_to_bottom ()
void
Region::set_layer (layer_t l)
{
- if (_layer != l) {
- _layer = l;
-
- send_change (Properties::layer);
- }
+ _layer = l;
}
XMLNode&
@@ -1650,22 +1648,3 @@ Region::post_set (const PropertyChange& pc)
}
}
-void
-Region::set_pending_layer (double l)
-{
- _pending_layer = l;
-}
-
-bool
-Region::reset_pending_layer ()
-{
- bool const had = _pending_layer;
- _pending_layer = boost::optional<double> ();
- return had;
-}
-
-boost::optional<double>
-Region::pending_layer () const
-{
- return _pending_layer;
-}