*/
+#define __STDC_LIMIT_MACROS
+#include <stdint.h>
+
#include <set>
#include <fstream>
#include <algorithm>
}
void
-RegionListProperty::diff (PropertyList& undo, PropertyList& redo) const
+RegionListProperty::diff (PropertyList& undo, PropertyList& redo, Command* cmd) const
{
if (changed()) {
/* list of the removed/added regions since clear_history() was last called */
RegionListProperty* b = copy_for_history ();
b->invert_changes ();
+ if (cmd) {
+ /* whenever one of the regions emits DropReferences, make sure
+ that the Destructible we've been told to notify hears about
+ it. the Destructible is likely to be the Command being built
+ with this diff().
+ */
+
+ for (set<boost::shared_ptr<Region> >::iterator i = a->change().added.begin(); i != a->change().added.end(); ++i) {
+ (*i)->DropReferences.connect_same_thread (*cmd, boost::bind (&Destructible::drop_references, cmd));
+ }
+ }
+
undo.add (b);
redo.add (a);
}
, _type(type)
{
+#ifndef NDEBUG
const XMLProperty* prop = node.property("type");
assert(!prop || DataType(prop->value()) == _type);
+#endif
init (hide);
_name = "unnamed"; /* reset by set_state */
pending_contents_change = true;
pending_length = true;
} else {
+ r->clear_history ();
pending_length = false;
LengthChanged (); /* EMIT SIGNAL */
pending_contents_change = false;
for (s = pending_adds.begin(); s != pending_adds.end(); ++s) {
// cerr << _name << " sends RegionAdded\n";
- RegionAdded (boost::weak_ptr<Region> (*s)); /* EMIT SIGNAL */
+ /* don't emit RegionAdded signal until relayering is done,
+ so that the region is fully setup by the time
+ anyone hear's that its been added
+ */
dependent_checks_needed.insert (*s);
}
// cerr << _name << "done contents change @ " << get_microseconds() << endl;
}
+ for (s = pending_adds.begin(); s != pending_adds.end(); ++s) {
+ (*s)->clear_history ();
+ RegionAdded (boost::weak_ptr<Region> (*s)); /* EMIT SIGNAL */
+ }
+
for (s = dependent_checks_needed.begin(); s != dependent_checks_needed.end(); ++s) {
check_dependents (*s, false);
}
has to be done separately.
*/
- if (!ignore_music_glue && (*r)->positional_lock_style() != Region::AudioTime) {
+ if (!ignore_music_glue && (*r)->position_lock_style() != AudioTime) {
fixup.push_back (*r);
continue;
}
to_check.insert (start);
to_check.insert (end);
+ DEBUG_TRACE (DEBUG::AudioPlayback, ">>>>> REGIONS TO READ\n");
+
for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) {
/* find all/any regions that span start+end */
case OverlapInternal:
covering.push_back (*i);
+ DEBUG_TRACE (DEBUG::AudioPlayback, string_compose ("toread: will cover %1 (OInternal)\n", (*i)->name()));
break;
case OverlapStart:
to_check.insert ((*i)->position());
+ if ((*i)->position() != 0) {
+ to_check.insert ((*i)->position()-1);
+ }
+ DEBUG_TRACE (DEBUG::AudioPlayback, string_compose ("toread: will check %1 for %2\n", (*i)->position(), (*i)->name()));
covering.push_back (*i);
break;
case OverlapEnd:
to_check.insert ((*i)->last_frame());
+ to_check.insert ((*i)->last_frame()+1);
+ DEBUG_TRACE (DEBUG::AudioPlayback, string_compose ("toread: will cover %1 (OEnd)\n", (*i)->name()));
+ DEBUG_TRACE (DEBUG::AudioPlayback, string_compose ("\ttoread: will check %1 for %2\n", (*i)->last_frame(), (*i)->name()));
+ DEBUG_TRACE (DEBUG::AudioPlayback, string_compose ("\ttoread: will check %1 for %2\n", (*i)->last_frame(), (*i)->name()));
covering.push_back (*i);
break;
case OverlapExternal:
covering.push_back (*i);
to_check.insert ((*i)->position());
+ if ((*i)->position() != 0) {
+ to_check.insert ((*i)->position()-1);
+ }
to_check.insert ((*i)->last_frame());
+ to_check.insert ((*i)->last_frame()+1);
+ DEBUG_TRACE (DEBUG::AudioPlayback, string_compose ("toread: will cover %1 (OExt)\n", (*i)->name()));
+ DEBUG_TRACE (DEBUG::AudioPlayback, string_compose ("\ttoread: will check %1 for %2\n", (*i)->position(), (*i)->name()));
+ DEBUG_TRACE (DEBUG::AudioPlayback, string_compose ("\ttoread: will check %1 for %2\n", (*i)->last_frame(), (*i)->name()));
break;
}
if (covering.size() == 1) {
rlist->push_back (covering.front());
+ DEBUG_TRACE (DEBUG::AudioPlayback, string_compose ("Just one covering region (%1)\n", covering.front()->name()));
} else {
here.clear ();
+ DEBUG_TRACE (DEBUG::AudioPlayback, string_compose ("++++ Considering %1\n", *t));
+
for (RegionList::iterator x = covering.begin(); x != covering.end(); ++x) {
if ((*x)->covers (*t)) {
here.push_back (*x);
- }
+ DEBUG_TRACE (DEBUG::AudioPlayback, string_compose ("region %1 covers %2\n",
+ (*x)->name(),
+ (*t)));
+ } else {
+ DEBUG_TRACE (DEBUG::AudioPlayback, string_compose ("region %1 does NOT covers %2\n",
+ (*x)->name(),
+ (*t)));
+ }
+
}
RegionSortByLayer cmp;
if ((*c)->opaque()) {
/* the other regions at this position are hidden by this one */
-
+ DEBUG_TRACE (DEBUG::AudioPlayback, string_compose ("%1 is opaque, ignore all others\n",
+ (*c)->name()));
break;
}
}
}
}
+ DEBUG_TRACE (DEBUG::AudioPlayback, string_compose ("<<<<< REGIONS TO READ returns %1\n", rlist->size()));
+
return rlist;
}
string newname = name;
do {
- newname = bump_name_once (newname);
+ newname = bump_name_once (newname, '.');
} while (session.playlists->by_name (newname)!=NULL);
return newname;
int const divisions = 512;
/* find the start and end positions of the regions on this playlist */
- framepos_t start = UINT_MAX;
+ framepos_t start = INT64_MAX;
framepos_t end = 0;
for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) {
start = min (start, (*i)->position());
/* reset the pending explicit relayer flag for every region, now that we're relayering */
(*i)->set_pending_explicit_relayer (false);
- /* find the time divisions that this region covers */
- int const start_division = floor ( ((*i)->position() - start) / division_size);
- int end_division = floor ( ((*i)->position() + (*i)->length() - start) / division_size );
- if (end_division == divisions) {
- end_division--;
+ /* 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.
+ */
+ int start_division = 0;
+ int end_division = 0;
+
+ if (division_size > 0) {
+ start_division = floor ( ((*i)->position() - start) / division_size);
+ end_division = floor ( ((*i)->position() + (*i)->length() - start) / division_size );
+ if (end_division == divisions) {
+ end_division--;
+ }
}
- assert (end_division < divisions);
+ assert (divisions == 0 || end_division < divisions);
/* find the lowest layer that this region can go on */
size_t j = layers.size();
return (i != regions.end());
}
+
+/** Remove any region that uses a given source */
+void
+Playlist::remove_region_by_source (boost::shared_ptr<Source> s)
+{
+ RegionLock rl (this);
+
+ RegionList::iterator i = regions.begin();
+ while (i != regions.end()) {
+ RegionList::iterator j = i;
+ ++j;
+
+ if ((*i)->uses_source (s)) {
+ remove_region_internal (*i);
+ }
+
+ i = j;
+ }
+}