MidiPlaylist::MidiPlaylist (Session& session, const XMLNode& node, bool hidden)
: Playlist (session, node, DataType::MIDI, hidden)
+ , _note_mode(Sustained)
{
const XMLProperty* prop = node.property("type");
assert(prop && DataType(prop->value()) == DataType::MIDI);
- in_set_state = true;
+ in_set_state++;
set_state (node);
- in_set_state = false;
+ in_set_state--;
}
MidiPlaylist::MidiPlaylist (Session& session, string name, bool hidden)
MidiPlaylist::~MidiPlaylist ()
{
GoingAway (); /* EMIT SIGNAL */
+
+ /* drop connections to signals */
+
+ notify_callbacks ();
}
struct RegionSortByLayer {
sort(regs.begin(), regs.end(), layer_cmp);
for (vector<boost::shared_ptr<Region> >::iterator i = regs.begin(); i != regs.end(); ++i) {
- // FIXME: ensure time is monotonic here
+ // FIXME: ensure time is monotonic here?
boost::shared_ptr<MidiRegion> mr = boost::dynamic_pointer_cast<MidiRegion>(*i);
- mr->read_at (dst, start, dur, chan_n);
- _read_data_count += mr->read_data_count();
+ if (mr) {
+ mr->read_at (dst, start, dur, chan_n, _note_mode);
+ _read_data_count += mr->read_data_count();
+ }
}
return dur;
void
MidiPlaylist::remove_dependents (boost::shared_ptr<Region> region)
{
+ /* MIDI regions have no dependents (crossfades) */
}
-void
-MidiPlaylist::flush_notifications ()
-{
- Playlist::flush_notifications();
-
- if (in_flush) {
- return;
- }
-
- in_flush = true;
-
- in_flush = false;
-}
-
void
MidiPlaylist::refresh_dependents (boost::shared_ptr<Region> r)
{
+ /* MIDI regions have no dependents (crossfades) */
}
void
MidiPlaylist::finalize_split_region (boost::shared_ptr<Region> original, boost::shared_ptr<Region> left, boost::shared_ptr<Region> right)
{
- throw; // I don't wanna
- /*
- MidiRegion *orig = dynamic_cast<MidiRegion*>(o);
- MidiRegion *left = dynamic_cast<MidiRegion*>(l);
- MidiRegion *right = dynamic_cast<MidiRegion*>(r);
-
- for (Crossfades::iterator x = _crossfades.begin(); x != _crossfades.end();) {
- Crossfades::iterator tmp;
- tmp = x;
- ++tmp;
-
- Crossfade *fade = 0;
-
- if ((*x)->_in == orig) {
- if (! (*x)->covers(right->position())) {
- fade = new Crossfade( *(*x), left, (*x)->_out);
- } else {
- // Overlap, the crossfade is copied on the left side of the right region instead
- fade = new Crossfade( *(*x), right, (*x)->_out);
- }
- }
-
- if ((*x)->_out == orig) {
- if (! (*x)->covers(right->position())) {
- fade = new Crossfade( *(*x), (*x)->_in, right);
- } else {
- // Overlap, the crossfade is copied on the right side of the left region instead
- fade = new Crossfade( *(*x), (*x)->_in, left);
- }
- }
-
- if (fade) {
- _crossfades.remove( (*x) );
- add_crossfade (*fade);
- }
- x = tmp;
- }*/
+ /* No MIDI crossfading (yet?), so nothing to do here */
}
void
MidiPlaylist::check_dependents (boost::shared_ptr<Region> r, bool norefresh)
{
+ /* MIDI regions have no dependents (crossfades) */
}
int
MidiPlaylist::set_state (const XMLNode& node)
{
- if (!in_set_state) {
- Playlist::set_state (node);
- }
+ in_set_state++;
+ freeze ();
- // Actually Charles, I don't much care for children
-
- /*
- XMLNodeList nlist = node.children();
+ Playlist::set_state (node);
- for (XMLNodeConstIterator niter = nlist.begin(); niter != nlist.end(); ++niter) {
-
- XMLNode* const child = *niter;
-
- }*/
+ thaw();
+ in_set_state--;
return 0;
}
-XMLNode&
-MidiPlaylist::state (bool full_state)
-{
- XMLNode& node = Playlist::state (full_state);
-
- return node;
-}
-
void
MidiPlaylist::dump () const
{
return changed;
}
+set<Parameter>
+MidiPlaylist::contained_automation()
+{
+ /* this function is never called from a realtime thread, so
+ its OK to block (for short intervals).
+ */
+
+ Glib::Mutex::Lock rm (region_lock);
+
+ set<Parameter> ret;
+
+ for (RegionList::const_iterator r = regions.begin(); r != regions.end(); ++r) {
+ boost::shared_ptr<MidiRegion> mr = boost::dynamic_pointer_cast<MidiRegion>(*r);
+
+ for (Automatable::Controls::iterator c = mr->controls().begin();
+ c != mr->controls().end(); ++c) {
+ ret.insert(c->first);
+ }
+ }
+
+ return ret;
+}
+
+
bool
MidiPlaylist::region_changed (Change what_changed, boost::shared_ptr<Region> region)
{