[ardour-dev] a couple of patches for automation lines

gerard van dongen gml at xs4all.nl
Mon Jul 5 10:51:31 PDT 2004


this fixes:
incorrect lineair interpolation when there are only 2 automation points
automation not updated correctly when dragging or erasing points
first point of an automation line was not draggable,
But this fix makes all points are visible again, most of the time. There  
must be a better way here.




Index: libs/ardour/curve.cc
===================================================================
RCS file: /home/las/cvsroot/ardour/ardour/libs/ardour/curve.cc,v
retrieving revision 1.36
diff -u -r1.36 curve.cc
--- libs/ardour/curve.cc	9 Jun 2004 01:24:21 -0000	1.36
+++ libs/ardour/curve.cc	5 Jul 2004 16:38:33 -0000
@@ -222,40 +222,6 @@
  		return;
  	}

-	if (npoints == 1) {
-		for (i = 0; i < veclen; ++i) {
-			vec[i] = events.front()->value;
-		}
-		return;
-	}
-
-	if (npoints == 2) {
-
-		/* linear interpolation between 2 points */
-
-		/* XXX I'm not sure that this is the right thing to
-		   do here. but its not a common case for the envisaged
-		   uses.
-		*/
-
-		rx = lx;
-		if (veclen > 1) {
-			dx = (hx - lx) / (veclen - 1);
-		} else {
-			dx = 0; // not used
-		}
-		
-		double deltay = (*(++events.begin()))->value - events.front()->value;
-		double deltax = (*(++events.begin()))->when - events.front()->when;
-		double xfrac;
-
-		for (i = 0; i < veclen; ++i, rx += dx) {
-			xfrac = (rx - events.front()->when) / deltax;
-			vec[i] = events.front()->value + (deltay * xfrac);
-		}
-		return;
-	}
-
  	original_veclen = veclen;

  	if (x0 < min_x) {
@@ -300,9 +266,49 @@
  		veclen -= subveclen;
  	}

+
+
  	if (veclen == 0) {
  		return;
  	}
+
+
+	if (npoints == 1 ) {
+	
+		for (i = 0; i < veclen; ++i) {
+			vec[i] = events.front()->value;
+		}
+		return;
+	}
+
+
+	if (npoints == 2) {
+
+		/* linear interpolation between 2 points */
+
+		/* XXX I'm not sure that this is the right thing to
+		   do here. but its not a common case for the envisaged
+		   uses.
+		*/
+	
+		if (veclen > 1) {
+			dx = (hx - lx) / (veclen - 1) ;
+		} else {
+			dx = 0; // not used
+		}
+	
+		double slope = (events.back()->value - events.front()->value)/  
(events.back()->when - events.front()->when);
+		double yfrac = dx*slope;
+
+		vec[0] = events.front()->value + slope * (lx - events.front()->when);
+
+		for (i = 1; i < veclen; ++i) {
+			vec[i] = vec[i-1] + yfrac;
+		}
+
+		return;
+	}
+

  	rx = lx;



Index: libs/ardour/automation_event.cc
===================================================================
RCS file: /home/las/cvsroot/ardour/ardour/libs/ardour/automation_event.cc,v
retrieving revision 1.30
diff -u -r1.30 automation_event.cc
--- libs/ardour/automation_event.cc	19 Jun 2004 13:36:10 -0000	1.30
+++ libs/ardour/automation_event.cc	5 Jul 2004 16:39:37 -0000
@@ -146,6 +146,7 @@
  void
  AutomationList::maybe_signal_changed ()
  {
+
  	if (_frozen) {
  		changed_when_thawed = true;
  	} else {
@@ -391,7 +392,10 @@
  			save_state (_("removed event"));
  		}
  	}
+
+	mark_dirty();
  	maybe_signal_changed ();
+
  }

  void
@@ -405,6 +409,7 @@
  			save_state (_("removed multiple events"));
  		}
  	}
+	mark_dirty();
  	maybe_signal_changed ();
  }	

@@ -433,6 +438,7 @@
  	}

  	if (erased) {
+		mark_dirty();
  		maybe_signal_changed ();
  	}
  }
@@ -445,12 +451,16 @@
  	   points after end are later than (end)->when.
  	*/

+
  	{
+		
  		LockMonitor lm (lock, __LINE__, __FILE__);

  		while (start != end) {
+		
  			(*start)->when += xdelta;
  			(*start)->value += ydelta;
+		
  			++start;
  		}

@@ -458,7 +468,7 @@
  			save_state (_("event range adjusted"));
  		}
  	}
-
+	mark_dirty();
  	maybe_signal_changed ();
  }

@@ -478,7 +488,7 @@
  			save_state (_("event adjusted"));
  		}
  	}
-	
+	mark_dirty();
  	maybe_signal_changed ();
  }

@@ -527,7 +537,8 @@
  {
  	_frozen = false;
  	if (changed_when_thawed) {
-		 StateChanged(Change(0)); /* EMIT SIGNAL */
+
+		StateChanged(Change(0)); /* EMIT SIGNAL */
  	}
  }

@@ -711,10 +722,14 @@
  	double uval, lval;
  	double fraction;

+
+
  	if (events.empty()) {
  		return default_value;
  	}

+
+
  	/* XXX OPTIMIZE ME by caching the range iterators */

  	range = equal_range (events.begin(), events.end(), &cp, cmp);
@@ -771,6 +786,7 @@
  		}
  	}

+	mark_dirty();
  	maybe_signal_changed ();

  	return nal;
@@ -834,6 +850,7 @@
  		}
  	}

+	mark_dirty();
  	maybe_signal_changed ();

  	return nal;
@@ -936,6 +953,7 @@
  		}
  	}

+	mark_dirty();
  	maybe_signal_changed ();
  	return true;
  }



Index: gtk_ardour/automation_line.cc
===================================================================
RCS file: /home/las/cvsroot/ardour/ardour/gtk_ardour/automation_line.cc,v
retrieving revision 1.58
diff -u -r1.58 automation_line.cc
--- gtk_ardour/automation_line.cc	19 Jun 2004 13:36:10 -0000	1.58
+++ gtk_ardour/automation_line.cc	5 Jul 2004 16:38:58 -0000
@@ -109,6 +109,10 @@
  	gtk_object_destroy (GTK_OBJECT(item));
  }

+
+
+
+
  void
  ControlPoint::hide ()
  {
@@ -244,6 +248,7 @@

  	// cerr << _name << " line @ " << line << endl;

+
  	gtk_object_set_data (GTK_OBJECT(line), "line", this);
  	gtk_signal_connect (GTK_OBJECT(line), "event", (GtkSignalFunc)  
line_handler, this);

@@ -469,6 +474,7 @@
  	}
  }

+
  void
  AutomationLine::reset_line_coords (ControlPoint& cp)
  {	
@@ -504,7 +510,7 @@
  	/* how far did we move ? */

  	delta = last - first;
-
+
  	/* change all model points in the range by that amount */

  	update_pending = true;
@@ -572,6 +578,7 @@
  	}
  }

+
  void
  AutomationLine::sync_model_from (ControlPoint& cp)
  {
@@ -587,33 +594,39 @@

  	sync_model_with_view_point (cp);

+
+
  	/* now move all points after `cp' by the same amount */
+	/*we might have moved other points "with_push" so we must  
sync_model_with_viewpoint for all points after */

  	first = mr.end;
-
+	
  	lasti = control_points.size() - 1;
  	p = nth (lasti);

+	update_pending = true;
+	
  	while (!p->can_slide && p != &cp && lasti) {
  		--lasti;
  		p = nth (lasti);
+		sync_model_with_view_point( *p);
  	}
-
+	
  	model_representation (*p, mr);
-
+	
  	last = mr.end;
-
+	
  	/* we're going to reset() anyway, so don't both responding to
  	   change signals when this happens.
  	*/
-
-	update_pending = true;
-	change_model_range (first, last, xdelta, 0.0f);
+	
+	
  }

  void
  AutomationLine::sync_model_with_view_point (ControlPoint& cp)
  {
+
  	ModelRepresentation mr;
  	double ydelta;

@@ -806,15 +819,12 @@
  	if (nvalid == 1) {
  		control_points[0]->show ();
  		control_points[0]->set_visible (true);
-	} else if (nvalid) {
-		control_points[0]->hide ();
-		control_points[0]->set_visible (false);
  	}

  	/* discard extra CP's to avoid confusing ourselves */

  	while (control_points.size() > view_index) {
-		control_points.pop_back ();
+			control_points.pop_back ();
  	}

  	if (!terminal_points_can_slide) {
@@ -845,13 +855,15 @@
  		/* reset the line coordinates */

  		unsigned long pci;
-		
+	
+	
  		for (pci = 0, view_index = 0; view_index < npoints; ++view_index) {
+
  			point_coords->coords[pci++] = control_points[view_index]->get_x();
  			point_coords->coords[pci++] = control_points[view_index]->get_y();
  		}

-		// cerr << "set al2 points, nc = " << point_coords->num_points << endl;
+	
  		gtk_canvas_item_set (line, "points", point_coords, NULL);

  		if (_visible) {
@@ -1197,6 +1209,7 @@
  void
  AutomationLine::reset ()
  {
+
  	update_pending = false;

  	if (no_draw) {
@@ -1219,12 +1232,15 @@
  void
  AutomationLine::change_model (AutomationList::iterator i, double x,  
double y)
  {
+
+
  	alist.modify (i, (jack_nframes_t) x, y);
  }

  void
  AutomationLine::change_model_range (AutomationList::iterator start,  
AutomationList::iterator end, double xdelta, float ydelta)
  {
+
  	alist.move_range (start, end, xdelta, ydelta);
  }








--



More information about the Ardour-Dev mailing list