View Issue Details

IDProjectCategoryView StatusLast Update
0002653ardourotherpublic2009-07-05 23:39
Reporterlincoln Assigned To 
PrioritynormalSeveritytweakReproducibilityN/A
Status closedResolutionfixed 
Summary0002653: Speed up playlist operations
DescriptionI am attaching a test patch that will significantly speedup playlist operations. This helps allot in sessions where there are many regions in a track.

What the patch does is add two new signals RegionAdded and RegionRemoved to playlist. Streamview will connect to these signals and do direct operations rather than re-rendering the whole playlist on every operation.

Before this change an operation like a trim would re-render the whole playlist and this can lead to pauses lasting seconds. This patch removes the redisplay_diskstream call on the Modified handler making editing ops very fast.

The only pauses to be had now is when undoing an edit operation since the whole playlist is being restored on each undo.
TagsNo tags attached.

Activities

2009-05-03 20:54

 

playlisrt-ops-optimization.diff (8,477 bytes)   
Index: gtk2_ardour/streamview.cc
===================================================================
--- gtk2_ardour/streamview.cc	(revision 5029)
+++ gtk2_ardour/streamview.cc	(working copy)
@@ -167,9 +167,19 @@
 }
 
 void
+StreamView::add_region_view_weak (boost::weak_ptr<Region> r)
+{
+	boost::shared_ptr<Region> sp (r.lock());
+	
+	if (sp) {
+		add_region_view (sp);
+	}
+}
+
+void
 StreamView::add_region_view (boost::shared_ptr<Region> r)
 {
-	// ENSURE_GUI_THREAD (bind (mem_fun (*this, &AudioStreamView::add_region_view), r));
+	ENSURE_GUI_THREAD (bind (mem_fun (*this, &StreamView::add_region_view), r));
 
 	add_region_view_internal (r, true);
 	update_contents_height ();
@@ -280,6 +290,7 @@
 StreamView::playlist_modified_weak (boost::weak_ptr<Diskstream> ds)
 {
 	boost::shared_ptr<Diskstream> sp (ds.lock());
+	
 	if (sp) {
 		playlist_modified (sp);
 	}
@@ -296,7 +307,7 @@
 		_layers = ds->playlist()->top_layer() + 1;
 		update_contents_height ();
 		update_coverage_frames ();
-		redisplay_diskstream ();
+		//redisplay_diskstream ();
 	}
 }
 
@@ -338,8 +349,13 @@
 	/* catch changes */
 
 	playlist_connections.push_back (ds->playlist()->Modified.connect (bind (
-			mem_fun (*this, &StreamView::playlist_modified_weak),
-			ds)));
+			mem_fun (*this, &StreamView::playlist_modified_weak), ds)));
+
+	playlist_connections.push_back (ds->playlist()->RegionAdded.connect (
+			mem_fun (*this, &StreamView::add_region_view_weak)));
+
+	playlist_connections.push_back (ds->playlist()->RegionRemoved.connect (
+			mem_fun (*this, &StreamView::remove_region_view)));
 }
 
 void
Index: gtk2_ardour/audio_region_view.h
===================================================================
--- gtk2_ardour/audio_region_view.h	(revision 5029)
+++ gtk2_ardour/audio_region_view.h	(working copy)
@@ -28,6 +28,7 @@
 
 #include "region_view.h"
 #include "route_time_axis.h"
+
 #include "time_axis_view_item.h"
 #include "automation_line.h"
 #include "enums.h"
Index: gtk2_ardour/streamview.h
===================================================================
--- gtk2_ardour/streamview.h	(revision 5029)
+++ gtk2_ardour/streamview.h	(working copy)
@@ -93,7 +93,10 @@
 	void get_inverted_selectables (Selection&, list<Selectable* >& results);
 
 	virtual void update_contents_metrics(boost::shared_ptr<ARDOUR::Region> r) {}
+
+	void add_region_view_weak (boost::weak_ptr<ARDOUR::Region> r);
 	void add_region_view (boost::shared_ptr<ARDOUR::Region>);
+
 	void region_layered (RegionView*);
 	virtual void update_contents_height ();
 	
@@ -114,7 +117,7 @@
 	void         update_rec_box ();
 	
 	virtual RegionView* add_region_view_internal (boost::shared_ptr<ARDOUR::Region>,
-			bool wait_for_waves, bool recording = false) = 0;
+		      bool wait_for_waves, bool recording = false) = 0;
 	virtual void remove_region_view (boost::weak_ptr<ARDOUR::Region> );
 
 	void         display_diskstream (boost::shared_ptr<ARDOUR::Diskstream>);
Index: gtk2_ardour/audio_streamview.cc
===================================================================
--- gtk2_ardour/audio_streamview.cc	(revision 5029)
+++ gtk2_ardour/audio_streamview.cc	(working copy)
@@ -108,31 +108,33 @@
 AudioStreamView::add_region_view_internal (boost::shared_ptr<Region> r, bool wait_for_waves, bool recording)
 {
 	AudioRegionView *region_view = 0;
-
 	boost::shared_ptr<AudioRegion> region = boost::dynamic_pointer_cast<AudioRegion> (r);
 
 	if (region == 0) {
 		return NULL;
 	}
 
-	for (list<RegionView *>::iterator i = region_views.begin(); i != region_views.end(); ++i) {
-		if ((*i)->region() == r) {
-			
-			/* great. we already have a AudioRegionView for this Region. use it again. */
-			
-			(*i)->set_valid (true);
-
-			// this might not be necessary
-			AudioRegionView* const arv = dynamic_cast<AudioRegionView*>(*i);
-			if (arv) {
-				arv->set_waveform_scale (_waveform_scale);
-				arv->set_waveform_shape (_waveform_shape);
-			}
+//	if(!recording){
+//		for (list<RegionView *>::iterator i = region_views.begin(); i != region_views.end(); ++i) {
+//			if ((*i)->region() == r) {
+//				cerr << "audio_streamview in add_region_view_internal region found" << endl;
+				/* great. we already have a AudioRegionView for this Region. use it again. */
 				
-			return NULL;
-		}
-	}
+//				(*i)->set_valid (true);
 
+				// this might not be necessary
+//				AudioRegionView* const arv = dynamic_cast<AudioRegionView*>(*i);
+
+//				if (arv) {
+//					arv->set_waveform_scale (_waveform_scale);
+//					arv->set_waveform_shape (_waveform_shape);
+//				}
+					
+//				return NULL;
+//			}
+//		}
+//	}
+
 	switch (_trackview.audio_track()->mode()) {
 	
 	case NonLayered:
@@ -173,6 +175,7 @@
 	   otherwise, we set it to the current value */
 	   
 	if (region_views.size() == 1) {
+
 		if (region_view->waveform_logscaled()) {
 			_waveform_scale = LogWaveform;
 		} else {
@@ -191,7 +194,6 @@
 	}
 	
 	/* follow global waveform setting */
-
 	region_view->set_waveform_visible(_trackview.editor().show_waveforms());
 
 	/* catch regionview going away */
@@ -396,6 +398,7 @@
 	}
 
 	// Add and display region and crossfade views, and flag them as valid
+
 	if (_trackview.is_audio_track()) {
 		_trackview.get_diskstream()->playlist()->foreach_region(
 				static_cast<StreamView*>(this),
Index: libs/ardour/ardour/playlist.h
===================================================================
--- libs/ardour/ardour/playlist.h	(revision 5029)
+++ libs/ardour/ardour/playlist.h	(working copy)
@@ -129,6 +129,8 @@
 
 	sigc::signal<void,bool> InUse;
 	sigc::signal<void>      Modified;
+	sigc::signal<void, boost::weak_ptr<Region> > RegionAdded;
+	sigc::signal<void, boost::weak_ptr<Region> > RegionRemoved;
 	sigc::signal<void>      NameChanged;
 	sigc::signal<void>      LengthChanged;
 	sigc::signal<void, list< Evoral::RangeMove<nframes_t> > const &> RangesMoved;
Index: libs/ardour/playlist.cc
===================================================================
--- libs/ardour/playlist.cc	(revision 5029)
+++ libs/ardour/playlist.cc	(working copy)
@@ -342,6 +342,7 @@
 		pending_length = false;
 		LengthChanged (); /* EMIT SIGNAL */
 		pending_modified = false;
+		RegionRemoved (boost::weak_ptr<Region> (r)); /* EMIT SIGNAL */
 		Modified (); /* EMIT SIGNAL */
 	}
 }
@@ -360,7 +361,6 @@
 		list< Evoral::RangeMove<nframes_t> > m;
 		m.push_back (move);
 		RangesMoved (m);
-
 	}
 
 }
@@ -380,6 +380,7 @@
 		pending_length = false;
 		LengthChanged (); /* EMIT SIGNAL */
 		pending_modified = false;
+		RegionAdded (boost::weak_ptr<Region> (r)); /* EMIT SIGNAL */
 		Modified (); /* EMIT SIGNAL */
 	}
 }
@@ -420,24 +421,29 @@
 	// pending_bounds.sort (cmp);
 
 	for (RegionList::iterator r = pending_bounds.begin(); r != pending_bounds.end(); ++r) {
+
 		if (Config->get_layer_model() == MoveAddHigher) {
 			timestamp_layer_op (*r);
 		}
+
 		pending_length = true;
 		dependent_checks_needed.insert (*r);
-		n++;
-	}
 
-	for (s = pending_adds.begin(); s != pending_adds.end(); ++s) {
-		dependent_checks_needed.insert (*s);
 		n++;
 	}
 
 	for (s = pending_removes.begin(); s != pending_removes.end(); ++s) {
 		remove_dependents (*s);
+		RegionRemoved (boost::weak_ptr<Region> (*s)); /* EMIT SIGNAL */
 		n++;
 	}
 
+	for (s = pending_adds.begin(); s != pending_adds.end(); ++s) {
+		RegionAdded (boost::weak_ptr<Region> (*s)); /* EMIT SIGNAL */
+		dependent_checks_needed.insert (*s);
+		n++;
+	}
+
 	if ((freeze_length != _get_maximum_extent()) || pending_length) {
 		pending_length = 0;
 		LengthChanged(); /* EMIT SIGNAL */
@@ -449,8 +455,7 @@
 			relayer ();
 		}
 		pending_modified = false;
-		Modified (); /* EMIT SIGNAL */
-		
+		Modified (); /* EMIT SIGNAL */		
 	}
 
 	for (s = dependent_checks_needed.begin(); s != dependent_checks_needed.end(); ++s) {
@@ -537,6 +542,7 @@
 	}
 
 	RegionSortByPosition cmp;
+	
 	nframes_t old_length = 0;
 
 	if (!holding_state()) {
@@ -567,7 +573,9 @@
 	notify_region_added (region);
 	
 	if (!holding_state ()) {
+
 		check_dependents (region, false);
+
 		if (old_length != _get_maximum_extent()) {
 			notify_length_changed ();
 		}
@@ -1345,15 +1353,14 @@
 			std::list<sigc::connection>::iterator i = region_state_changed_connections.begin ();
 			i != region_state_changed_connections.end ();
 			++i
-			) {
-
-			i->disconnect ();
-			
+		) {
+			i->disconnect ();	
 		}
 		     
 		for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) {
 			pending_removes.insert (*i);
 		}
+
 		regions.clear ();
 	}

seablade

2009-07-05 23:39

manager   ~0006368

Patch has already been applied and OP requested issue be closed. Thanks;)

Issue History

Date Modified Username Field Change
2009-05-03 20:54 lincoln New Issue
2009-05-03 20:54 lincoln File Added: playlisrt-ops-optimization.diff
2009-07-05 23:39 seablade cost => 0.00
2009-07-05 23:39 seablade Note Added: 0006368
2009-07-05 23:39 seablade Status new => closed
2009-07-05 23:39 seablade Resolution open => fixed