From 948472c25395c446e18b3bfb4b2b89e5ef4b90b0 Mon Sep 17 00:00:00 2001 From: Houston4444 Date: Wed, 18 Oct 2017 11:21:55 +0200 Subject: [PATCH] A better method for "Close Regions Gaps" The actual method for "Close Region Gaps" can be improved. Indeed, in the current code, each region is stretched of "pull back length" to the left, the region on the left is stretched to overlap this one of "Fade Length". The problem arises when using this method after split a region at onsets and snap to grid all new regions (Rhytme ferret). If after "split at Onsets", a gap between two regions is bigger than "Pull Back Length", then the right region will be stretched of Pull Back Lenght to the left, and the left region will be stretched to the right until overlap the right one. And what can we ear on the right side of the left region ? The attack present at the beggining of the right region. To avoid this, I propose this code which retains the same behavior except that it never stretch the left region to the right. If the left region is not close enought, the right one will be stretched to the left until the end of the left one. This avoids double attacks. So, we can rename "Pull Back Length", in "Minimum Pull Back Lenght" and set it by defaut to 10ms instead of 30ms, by experience it seems reasonable for drums or guitars. Also, the code I propose uses truely the fade duration defined by user instead of a simple overlap (for audio regions only). If "Fade Length" is set on 0ms, the default fade will be used (64samples), I think it's good the set it to 0 by default. To test this, take an audio region of rhytmic guitar or drum, apply Rhytme Ferret, analyze region, split region at Onsets, select all new regions and "snap to grid". Then use "Close Gaps". --- gtk2_ardour/editor_ops.cc | 112 ++++++++++++++++++++++++++++---------- 1 file changed, 83 insertions(+), 29 deletions(-) diff --git a/gtk2_ardour/editor_ops.cc b/gtk2_ardour/editor_ops.cc index 1f678d31f46..e4a321e576f 100644 --- a/gtk2_ardour/editor_ops.cc +++ b/gtk2_ardour/editor_ops.cc @@ -7078,12 +7078,12 @@ Editor::close_region_gaps () list > used_playlists; RegionSelection rs = get_regions_from_selection_and_entered (); - + if (!_session || rs.empty()) { return; } - - Dialog dialog (_("Close Region Gaps")); + + Dialog dialog (_("Close Region Gaps")); Table table (2, 3); table.set_spacings (12); @@ -7094,7 +7094,7 @@ Editor::close_region_gaps () SpinButton spin_crossfade (1, 0); spin_crossfade.set_range (0, 15); spin_crossfade.set_increments (1, 1); - spin_crossfade.set_value (5); + spin_crossfade.set_value (0); table.attach (spin_crossfade, 1, 2, 0, 1); table.attach (*manage (new Label (_("ms"))), 2, 3, 0, 1); @@ -7105,7 +7105,7 @@ Editor::close_region_gaps () SpinButton spin_pullback (1, 0); spin_pullback.set_range (0, 100); spin_pullback.set_increments (1, 1); - spin_pullback.set_value(30); + spin_pullback.set_value(10); table.attach (spin_pullback, 1, 2, 1, 2); table.attach (*manage (new Label (_("ms"))), 2, 3, 1, 2); @@ -7119,51 +7119,104 @@ Editor::close_region_gaps () return; } - samplepos_t crossfade_len = spin_crossfade.get_value(); - samplepos_t pull_back_samples = spin_pullback.get_value(); - - crossfade_len = lrintf (crossfade_len * _session->sample_rate()/1000); - pull_back_samples = lrintf (pull_back_samples * _session->sample_rate()/1000); + framepos_t crossfade_len = spin_crossfade.get_value(); + framepos_t pull_back_frames = spin_pullback.get_value(); + + crossfade_len = lrintf (crossfade_len * _session->frame_rate()/1000); + pull_back_frames = lrintf (pull_back_frames * _session->frame_rate()/1000); /* Iterate over the region list and make adjacent regions overlap by crossfade_len_ms */ begin_reversible_command (_("close region gaps")); int idx = 0; + bool playlist_is_audio = false; boost::shared_ptr last_region; - + boost::shared_ptr last_audio_region; + rs.sort_by_position_and_track(); for (RegionSelection::iterator r = rs.begin(); r != rs.end(); ++r) { boost::shared_ptr pl = (*r)->region()->playlist(); - + AudioRegionView* arv = dynamic_cast (*r); + if (!pl->frozen()) { /* we haven't seen this playlist before */ - + /* remember used playlists so we can thaw them later */ used_playlists.push_back(pl); pl->freeze(); + if (playlist_is_audio != bool(arv)){ + /* Change of playlist type (audio or midi), reset idx */ + idx = 0; + } + playlist_is_audio = bool(arv); } + + framepos_t position = (*r)->region()->position(); - samplepos_t position = (*r)->region()->position(); - - if (idx == 0 || position < last_region->position()){ + if (playlist_is_audio) { + if (idx == 0 || position <= last_region->position()){ + last_region = (*r)->region(); + last_audio_region = arv->audio_region(); + idx++; + continue; + } + + framepos_t last_region_end = ( last_audio_region->position() + last_audio_region->length() ); + framecnt_t tmp_crossfade_len = crossfade_len; + + /* If fade length is set to 0, then use the default fade (64samples) */ + if(tmp_crossfade_len == 0){ + tmp_crossfade_len = 64; + }; + + arv->audio_region()->clear_changes (); + last_audio_region->clear_changes (); + + if ((last_region_end - pull_back_frames) > (position - tmp_crossfade_len)){ + arv->audio_region()->trim_front( (position - pull_back_frames)); + last_audio_region->trim_end( (position - pull_back_frames + tmp_crossfade_len + 64) ); + } else { + arv->audio_region()->trim_front( (last_region_end - pull_back_frames - tmp_crossfade_len)); + last_audio_region->trim_end( (last_region_end - pull_back_frames + 64) ); + } + + arv->audio_region()->set_fade_in_length(tmp_crossfade_len); + last_audio_region->set_default_fade_out(); + + _session->add_command (new StatefulDiffCommand (arv->audio_region())); + _session->add_command (new StatefulDiffCommand (last_audio_region)); + + last_audio_region = arv->audio_region(); + last_region = (*r)->region(); + } else { + /* MIDI */ + if (idx == 0 || position <= last_region->position()){ + last_region = (*r)->region(); + idx++; + continue; + } + + framepos_t last_region_end = ( last_region->position() + last_region->length() ); + + (*r)->region()->clear_changes (); + last_region->clear_changes (); + + if ((last_region_end - pull_back_frames) > (position - crossfade_len)){ + (*r)->region()->trim_front( (position - pull_back_frames)); + last_region->trim_end((position - pull_back_frames + crossfade_len)); + } else { + (*r)->region()->trim_front( (last_region_end - pull_back_frames - crossfade_len)); + last_region->trim_end( (last_region_end - pull_back_frames) ); + } + + _session->add_command (new StatefulDiffCommand ((*r)->region())); + _session->add_command (new StatefulDiffCommand (last_region)); + last_region = (*r)->region(); - idx++; - continue; } - - (*r)->region()->clear_changes (); - (*r)->region()->trim_front( (position - pull_back_samples)); - - last_region->clear_changes (); - last_region->trim_end( (position - pull_back_samples + crossfade_len)); - - _session->add_command (new StatefulDiffCommand ((*r)->region())); - _session->add_command (new StatefulDiffCommand (last_region)); - - last_region = (*r)->region(); idx++; } @@ -7176,6 +7229,7 @@ Editor::close_region_gaps () commit_reversible_command (); } + void Editor::tab_to_transient (bool forward) {