diff --git a/libs/ardour/ardour/midi_playlist.h b/libs/ardour/ardour/midi_playlist.h index 5b201a4ba2..574ad0c6ff 100644 --- a/libs/ardour/ardour/midi_playlist.h +++ b/libs/ardour/ardour/midi_playlist.h @@ -84,7 +84,7 @@ public: std::set contained_automation(); - boost::shared_ptr combine (const RegionList&); + boost::shared_ptr combine (const RegionList&, boost::shared_ptr); void uncombine (boost::shared_ptr); protected: diff --git a/libs/ardour/ardour/playlist.h b/libs/ardour/ardour/playlist.h index 59d86b6e80..6fc9a5c540 100644 --- a/libs/ardour/ardour/playlist.h +++ b/libs/ardour/ardour/playlist.h @@ -59,6 +59,7 @@ namespace ARDOUR { class Session; class Playlist; class Crossfade; +class Track; namespace Properties { /* fake the type, since regions are handled by SequenceProperty which doesn't @@ -186,7 +187,7 @@ public: void duplicate_range (TimelineRange&, float times); void duplicate_ranges (std::list&, float times); void nudge_after (timepos_t const & start, timecnt_t const & distance, bool forwards); - virtual boost::shared_ptr combine (const RegionList&); + virtual boost::shared_ptr combine (const RegionList&, boost::shared_ptr); virtual void uncombine (boost::shared_ptr); void fade_range (std::list&); void remove_gaps (timecnt_t const & gap_threshold, timecnt_t const & leave_gap, boost::function gap_callback); diff --git a/libs/ardour/midi_playlist.cc b/libs/ardour/midi_playlist.cc index fce717e3ad..b15b517c32 100644 --- a/libs/ardour/midi_playlist.cc +++ b/libs/ardour/midi_playlist.cc @@ -440,7 +440,7 @@ MidiPlaylist::rendered () } boost::shared_ptr -MidiPlaylist::combine (RegionList const & rl) +MidiPlaylist::combine (RegionList const & rl, boost::shared_ptr trk) { RegionWriteLock rwl (this, true); @@ -452,8 +452,6 @@ MidiPlaylist::combine (RegionList const & rl) sorted.sort (RegionSortByLayerAndPosition()); boost::shared_ptr first = sorted.front(); - RegionList::const_iterator i = sorted.begin(); - ++i; timepos_t earliest (timepos_t::max (Temporal::BeatTime)); timepos_t latest (Temporal::BeatTime); @@ -468,19 +466,20 @@ MidiPlaylist::combine (RegionList const & rl) } } - boost::shared_ptr new_region = boost::dynamic_pointer_cast (RegionFactory::create (first, true, true, &rwl.thawlist)); + boost::shared_ptr ms (session().create_midi_source_by_stealing_name (trk)); + boost::shared_ptr new_region = boost::dynamic_pointer_cast (RegionFactory::create (ms, first->derive_properties (false), true, &rwl.thawlist)); timepos_t pos (first->position()); + new_region->set_position (pos); - remove_region_internal (first, rwl.thawlist); - - while (i != sorted.end()) { - new_region->merge (boost::dynamic_pointer_cast (*i)); - remove_region_internal (*i, rwl.thawlist); - ++i; + for (auto const & other : sorted) { + new_region->merge (boost::dynamic_pointer_cast (other)); + remove_region_internal (other, rwl.thawlist); } - new_region->set_length (earliest.distance (latest)); + /* write MIDI to disk */ + + new_region->midi_source (0)->session_saved (); add_region_internal (new_region, pos, rwl.thawlist); diff --git a/libs/ardour/midi_region.cc b/libs/ardour/midi_region.cc index 9a74fc71d2..7a59bebaaa 100644 --- a/libs/ardour/midi_region.cc +++ b/libs/ardour/midi_region.cc @@ -550,46 +550,37 @@ MidiRegion::set_name (const std::string& str) void MidiRegion::merge (boost::shared_ptr other_region) { - Temporal::Beats last_event_time; + boost::shared_ptr other = other_region->model(); + boost::shared_ptr self = model(); - { - Source::WriterLock lm (midi_source(0)->mutex()); - boost::shared_ptr other = other_region->model(); - boost::shared_ptr self = model(); + Temporal::Beats other_region_start (other_region->start().beats()); + Temporal::Beats other_region_end ((other_region->start() + other_region->length()).beats()); - Temporal::Beats other_region_start (other_region->start().beats()); - Temporal::Beats other_region_end ((other_region->start() + other_region->length()).beats()); + self->start_write (); - midi_source (0)->mark_streaming_midi_write_started (lm, Sustained); + for (Evoral::Sequence::const_iterator e = other->begin(); e != other->end(); ++e) { - for (Evoral::Sequence::const_iterator e = other->begin(); e != other->end(); ++e) { - - if (e->time() < other_region_start) { - continue; - } - - /* other_region_end is an inclusive end, not - * exclusive, since we allow simultaneous MIDI events - * (given appropriate semantic sorting) - */ - - if (e->time() > other_region_end) { - break; - } - - Evoral::Event ev (*e, true); - - Temporal::Beats abs_time = other_region->source_beats_to_absolute_time (ev.time()).beats (); - Temporal::Beats srt = absolute_time_to_source_beats (timepos_t (abs_time)); - ev.set_time (srt); - self->append (ev, Evoral::next_event_id()); - last_event_time = abs_time; + if (e->time() < other_region_start) { + continue; } - midi_source (0)->mark_streaming_write_completed (lm); + /* other_region_end is an inclusive end, not + * exclusive, since we allow simultaneous MIDI events + * (given appropriate semantic sorting) + */ + + if (e->time() > other_region_end) { + break; + } + + Evoral::Event ev (*e, true); + timepos_t abs_time (other_region->source_beats_to_absolute_time (ev.time())); + Temporal::Beats srt = position().distance (abs_time).beats(); + ev.set_time (srt); + + self->append (ev, Evoral::next_event_id()); } - Temporal::Beats len = last_event_time - position().beats(); - - set_length (timecnt_t (len, position())); + set_length (position().distance (other_region->end())); + self->end_write (Evoral::Sequence::ResolveStuckNotes, length().beats()); } diff --git a/libs/ardour/playlist.cc b/libs/ardour/playlist.cc index df15a52774..2170f1dab1 100644 --- a/libs/ardour/playlist.cc +++ b/libs/ardour/playlist.cc @@ -3063,7 +3063,7 @@ Playlist::find_next_top_layer_position (timepos_t const & t) const } boost::shared_ptr -Playlist::combine (const RegionList& rl) +Playlist::combine (const RegionList& rl, boost::shared_ptr) { if (rl.empty()) { return boost::shared_ptr();