summaryrefslogtreecommitdiff
path: root/libs/ardour/midi_playlist.cc
diff options
context:
space:
mode:
Diffstat (limited to 'libs/ardour/midi_playlist.cc')
-rw-r--r--libs/ardour/midi_playlist.cc76
1 files changed, 76 insertions, 0 deletions
diff --git a/libs/ardour/midi_playlist.cc b/libs/ardour/midi_playlist.cc
index 67764d66ae..20c1c77111 100644
--- a/libs/ardour/midi_playlist.cc
+++ b/libs/ardour/midi_playlist.cc
@@ -33,7 +33,9 @@
#include "ardour/midi_region.h"
#include "ardour/midi_source.h"
#include "ardour/midi_state_tracker.h"
+#include "ardour/region_factory.h"
#include "ardour/session.h"
+#include "ardour/tempo.h"
#include "ardour/types.h"
#include "pbd/i18n.h"
@@ -381,6 +383,80 @@ MidiPlaylist::destroy_region (boost::shared_ptr<Region> region)
return changed;
}
+void
+MidiPlaylist::_split_region (boost::shared_ptr<Region> region, MusicFrame playlist_position)
+{
+ if (!region->covers (playlist_position.frame)) {
+ return;
+ }
+
+ if (region->position() == playlist_position.frame ||
+ region->last_frame() == playlist_position.frame) {
+ return;
+ }
+
+ boost::shared_ptr<const MidiRegion> mr = boost::dynamic_pointer_cast<MidiRegion>(region);
+
+ if (mr == 0) {
+ return;
+ }
+
+ boost::shared_ptr<Region> left;
+ boost::shared_ptr<Region> right;
+
+ string before_name;
+ string after_name;
+ const double before_qn = _session.tempo_map().exact_qn_at_frame (playlist_position.frame, playlist_position.division) - region->quarter_note();
+ const double after_qn = mr->length_beats() - before_qn;
+ MusicFrame before (playlist_position.frame - region->position(), playlist_position.division);
+ MusicFrame after (region->length() - before.frame, playlist_position.division);
+
+ /* split doesn't change anything about length, so don't try to splice */
+ bool old_sp = _splicing;
+ _splicing = true;
+
+ RegionFactory::region_name (before_name, region->name(), false);
+
+ {
+ PropertyList plist;
+
+ plist.add (Properties::length, before.frame);
+ plist.add (Properties::length_beats, before_qn);
+ plist.add (Properties::name, before_name);
+ plist.add (Properties::left_of_split, true);
+ plist.add (Properties::layering_index, region->layering_index ());
+ plist.add (Properties::layer, region->layer ());
+
+ /* note: we must use the version of ::create with an offset here,
+ since it supplies that offset to the Region constructor, which
+ is necessary to get audio region gain envelopes right.
+ */
+ left = RegionFactory::create (region, MusicFrame (0, 0), plist, true);
+ }
+
+ RegionFactory::region_name (after_name, region->name(), false);
+
+ {
+ PropertyList plist;
+
+ plist.add (Properties::length, after.frame);
+ plist.add (Properties::length_beats, after_qn);
+ plist.add (Properties::name, after_name);
+ plist.add (Properties::right_of_split, true);
+ plist.add (Properties::layering_index, region->layering_index ());
+ plist.add (Properties::layer, region->layer ());
+
+ /* same note as above */
+ right = RegionFactory::create (region, before, plist, true);
+ }
+
+ add_region_internal (left, region->position(), 0, region->quarter_note(), true);
+ add_region_internal (right, region->position() + before.frame, before.division, region->quarter_note() + before_qn, true);
+
+ remove_region_internal (region);
+
+ _splicing = old_sp;
+}
set<Evoral::Parameter>
MidiPlaylist::contained_automation()