#include <sigc++/bind.h>
-#include <ardour/types.h>
-#include <ardour/configuration.h>
-#include <ardour/midi_playlist.h>
-#include <ardour/midi_region.h>
-#include <ardour/session.h>
-#include <ardour/midi_ring_buffer.h>
+#include "ardour/types.h"
+#include "ardour/configuration.h"
+#include "ardour/midi_playlist.h"
+#include "ardour/midi_region.h"
+#include "ardour/session.h"
+#include "ardour/midi_ring_buffer.h"
-#include <pbd/error.h>
+#include "pbd/error.h"
#include "i18n.h"
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);
/** Returns the number of frames in time duration read (eg could be large when 0 events are read) */
nframes_t
-MidiPlaylist::read (MidiRingBuffer& dst, nframes_t start,
- nframes_t dur, unsigned chan_n)
+MidiPlaylist::read (MidiRingBuffer<nframes_t>& dst, nframes_t start, nframes_t dur, unsigned chan_n)
{
/* this function is never called from a realtime thread, so
its OK to block (for short intervals).
*/
- Glib::Mutex::Lock rm (region_lock);
+ Glib::RecMutex::Lock rm (region_lock);
nframes_t end = start + dur - 1;
vector<boost::shared_ptr<Region> > regs;
for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) {
-
if ((*i)->coverage (start, end) != OverlapNone) {
regs.push_back(*i);
}
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?
boost::shared_ptr<MidiRegion> mr = boost::dynamic_pointer_cast<MidiRegion>(*i);
if (mr) {
mr->read_at (dst, start, dur, chan_n, _note_mode);
void
-MidiPlaylist::remove_dependents (boost::shared_ptr<Region> region)
+MidiPlaylist::remove_dependents (boost::shared_ptr<Region> /*region*/)
{
/* MIDI regions have no dependents (crossfades) */
}
void
-MidiPlaylist::refresh_dependents (boost::shared_ptr<Region> r)
+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)
+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)
+MidiPlaylist::check_dependents (boost::shared_ptr<Region> /*r*/, bool /*norefresh*/)
{
/* MIDI regions have no dependents (crossfades) */
}
return changed;
}
+set<Evoral::Parameter>
+MidiPlaylist::contained_automation()
+{
+ /* this function is never called from a realtime thread, so
+ its OK to block (for short intervals).
+ */
+
+ Glib::RecMutex::Lock rm (region_lock);
+
+ set<Evoral::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->model()->controls().begin();
+ c != mr->model()->controls().end(); ++c) {
+ ret.insert(c->first);
+ }
+ }
+
+ return ret;
+}
+
+
bool
MidiPlaylist::region_changed (Change what_changed, boost::shared_ptr<Region> region)
{