View Issue Details

IDProjectCategoryView StatusLast Update
0002994ardourfeaturespublic2020-04-19 20:14
Reporterlincoln Assigned Tocth103  
PrioritynormalSeverityfeatureReproducibilityN/A
Status closedResolutionfixed 
Target Version3.0-beta1 
Summary0002994: [PATCH] Separate Region Under Selected Region
DescriptionI am attaching a patch that adds a function to separated regions under a selected regions. For example:

|----------------|
   |-----|

becomes

|--| |------|
   |------|

After applying this function. This is handy for removing region overlaps when you want to work on regions on either side of an overdub and you do not have the no-overlap track mode set up.

Function can be accessed from Edit->Separate->Separate Under Selected Regions
TagsNo tags attached.

Activities

2010-01-16 14:54

 

separate-under-region.patch (7,363 bytes)   
Index: gtk2_ardour/ardour.menus.in
===================================================================
--- gtk2_ardour/ardour.menus.in	(revision 6505)
+++ gtk2_ardour/ardour.menus.in	(working copy)
@@ -170,12 +170,13 @@
                <menuitem action='editor-delete'/>
                <menuitem action='editor-crop'/>
                <menuitem action='split-region'/>
+	       <menuitem action='split-region-at-transients'/>
 	       <menu action="SeparateMenu">
+		    <menuitem action='separate-under-region'/>
 	            <menuitem action='editor-separate'/>
 	            <menuitem action='separate-from-loop'/>
 	            <menuitem action='separate-from-punch'/>
 		    <separator/>
-		    <menuitem action='split-region-at-transients'/>
                </menu>
 	       <menu action="AlignMenu">
 		   <menuitem action='align-regions-start'/>
Index: gtk2_ardour/editor_actions.cc
===================================================================
--- gtk2_ardour/editor_actions.cc	(revision 6505)
+++ gtk2_ardour/editor_actions.cc	(working copy)
@@ -479,20 +479,28 @@
 	act = ActionManager::register_action (editor_actions, "export-range", _("Export Range"), sigc::mem_fun(*this, &Editor::export_range));
 	ActionManager::session_sensitive_actions.push_back (act);
 
+	act = ActionManager::register_action (editor_actions, "separate-under-region", _("Separate Under Selected Regions"), sigc::mem_fun(*this, &Editor::separate_under_selected_regions));
+	ActionManager::session_sensitive_actions.push_back (act);
+
 	act = ActionManager::register_action (editor_actions, "editor-separate", _("Separate"), sigc::mem_fun(*this, &Editor::separate_region_from_selection));
 	ActionManager::session_sensitive_actions.push_back (act);
 	ActionManager::mouse_edit_point_requires_canvas_actions.push_back (act);
+	
 	act = ActionManager::register_action (editor_actions, "separate-from-punch", _("Separate Using Punch Range"), sigc::mem_fun(*this, &Editor::separate_region_from_punch));
 	ActionManager::session_sensitive_actions.push_back (act);
 	ActionManager::mouse_edit_point_requires_canvas_actions.push_back (act);
+	
 	act = ActionManager::register_action (editor_actions, "separate-from-loop", _("Separate Using Loop Range"), sigc::mem_fun(*this, &Editor::separate_region_from_loop));
 	ActionManager::session_sensitive_actions.push_back (act);
 	ActionManager::mouse_edit_point_requires_canvas_actions.push_back (act);
+	
 	act = ActionManager::register_action (editor_actions, "editor-crop", _("Crop"), sigc::mem_fun(*this, &Editor::crop_region_to_selection));
 	ActionManager::session_sensitive_actions.push_back (act);
 	ActionManager::mouse_edit_point_requires_canvas_actions.push_back (act);
+	
 	act = ActionManager::register_action (editor_actions, "editor-cut", _("Cut"), sigc::mem_fun(*this, &Editor::cut));
 	ActionManager::session_sensitive_actions.push_back (act);
+	
 	/* Note: for now, editor-delete does the exact same thing as editor-cut */
 	act = ActionManager::register_action (editor_actions, "editor-delete", _("Delete"), sigc::mem_fun(*this, &Editor::cut));
 	ActionManager::session_sensitive_actions.push_back (act);
Index: gtk2_ardour/editor_ops.cc
===================================================================
--- gtk2_ardour/editor_ops.cc	(revision 6505)
+++ gtk2_ardour/editor_ops.cc	(working copy)
@@ -2822,6 +2822,7 @@
 
 						sigc::connection c = rtv->view()->RegionViewAdded.connect (
 								sigc::mem_fun(*this, &Editor::collect_new_region_view));
+
 						latest_regionviews.clear ();
 
 						playlist->partition ((nframes64_t)((*t).start * speed),
@@ -2863,6 +2864,11 @@
 	}
 }
 
+struct PlaylistState {
+    boost::shared_ptr<Playlist> playlist;
+    XMLNode*  before;
+};
+
 /** Take tracks from get_tracks_for_range_action and cut any regions
  *  on those tracks so that the tracks are empty over the time
  *  selection.
@@ -2928,7 +2934,86 @@
 	separate_regions_between (ts);
 }
 
+/** Separate regions under the selected region */
 void
+Editor::separate_under_selected_regions ()
+{
+	RegionSelection rs;
+	get_regions_for_action (rs);
+	
+	vector<PlaylistState> playlists;
+
+	if (!_session) {
+		return;
+	}
+
+	if (rs.empty()) {
+		return;
+	}
+
+	begin_reversible_command (_("separate region under"));
+
+	list<boost::shared_ptr<Region> > regions_to_remove;
+
+	for (RegionSelection::iterator i = rs.begin(); i != rs.end(); ++i) {
+		// we can't just remove the region(s) in this loop because
+		// this removes them from the RegionSelection, and they thus
+		// disappear from underneath the iterator, and the ++i above
+		// SEGVs in a puzzling fashion.
+
+		// so, first iterate over the regions to be removed from rs and
+		// add them to the regions_to_remove list, and then
+		// iterate over the list to actually remove them.
+
+		regions_to_remove.push_back ((*i)->region());
+	}
+
+	for (list<boost::shared_ptr<Region> >::iterator rl = regions_to_remove.begin(); rl != regions_to_remove.end(); ++rl) {
+
+		boost::shared_ptr<Playlist> playlist = (*rl)->playlist();
+
+	        if (!playlist) {
+			// is this check necessary?
+	        	continue;
+	        }
+
+		vector<PlaylistState>::iterator i;
+
+		//only take state if this is a new playlist.
+		for (i = playlists.begin(); i != playlists.end(); ++i) {
+			if ((*i).playlist == playlist) {
+				break;
+			}
+		}
+
+		if (i == playlists.end()) {
+
+			PlaylistState before;
+			before.playlist = playlist;
+			before.before = &playlist->get_state();
+
+			playlist->freeze ();
+			playlists.push_back(before);
+		}
+
+		//Partition on the region bounds
+		playlist->partition ((*rl)->first_frame() - 1, (*rl)->last_frame() + 1, true);
+		
+		//Re-add region that was just removed due to the partition operation
+		playlist->add_region( (*rl), (*rl)->first_frame() );
+	}
+
+	vector<PlaylistState>::iterator pl;
+
+	for (pl = playlists.begin(); pl != playlists.end(); ++pl) {
+		(*pl).playlist->thaw ();
+		_session->add_command(new MementoCommand<Playlist>(*(*pl).playlist, (*pl).before, &(*pl).playlist->get_state()));
+	}
+
+	commit_reversible_command ();
+}
+
+void
 Editor::crop_region_to_selection ()
 {
 	if (!selection->time.empty()) {
@@ -3954,11 +4039,8 @@
 	}
 }
 
-struct PlaylistState {
-    boost::shared_ptr<Playlist> playlist;
-    XMLNode*  before;
-};
 
+
 struct lt_playlist {
     bool operator () (const PlaylistState& a, const PlaylistState& b) {
 	    return a.playlist < b.playlist;
@@ -4341,7 +4423,7 @@
 
  		playlist = (*i)->region()->playlist();
                 XMLNode &before = playlist->get_state();
-		playlist->duplicate (r, end_frame + (r->first_frame() - start_frame) + 1, times);
+		playlist->duplicate (r, end_frame + (r->first_frame() - start_frame), times);
 		_session->add_command(new MementoCommand<Playlist>(*playlist, &before, &playlist->get_state()));
 
 		c.disconnect ();
Index: gtk2_ardour/editor.h
===================================================================
--- gtk2_ardour/editor.h	(revision 6505)
+++ gtk2_ardour/editor.h	(working copy)
@@ -233,6 +233,7 @@
 	void new_region_from_selection ();
 	void separate_regions_between (const TimeSelection&);
 	void separate_region_from_selection ();
+	void separate_under_selected_regions ();
 	void separate_region_from_punch ();
 	void separate_region_from_loop ();
 	void separate_regions_using_location (ARDOUR::Location&);
separate-under-region.patch (7,363 bytes)   

lincoln

2010-07-24 11:37

reporter   ~0008624

It looks like this patch has been applied. Probably as part of the beat slicing patch.

cth103

2010-07-25 00:57

administrator   ~0008628

Looks that way. Thanks!

system

2020-04-19 20:14

developer   ~0022023

Issue has been closed automatically, by Trigger Close Plugin.
Feel free to re-open with additional information if you think the issue is not resolved.

Issue History

Date Modified Username Field Change
2010-01-16 14:54 lincoln New Issue
2010-01-16 14:54 lincoln File Added: separate-under-region.patch
2010-07-21 15:42 cth103 cost => 0.00
2010-07-21 15:42 cth103 Target Version => 3.0-beta1
2010-07-21 15:42 cth103 Summary Separate Region Under Selected Region => [PATCH] Separate Region Under Selected Region
2010-07-24 11:37 lincoln Note Added: 0008624
2010-07-25 00:57 cth103 Note Added: 0008628
2010-07-25 00:57 cth103 Status new => resolved
2010-07-25 00:57 cth103 Resolution open => fixed
2010-07-25 00:57 cth103 Assigned To => cth103
2020-04-19 20:14 system Note Added: 0022023
2020-04-19 20:14 system Status resolved => closed