[ardour-dev] Automation Write and Touch Bug Fixes

Christopher K. George ckg at yalesda.org
Wed May 5 07:29:53 PDT 2004

I have found and fixed two small bugs in the automation code.  I have never
submitted bug fixes before, so tips on how to do it better next time are welcome.

NOTE: My understanding is that the bugs I fixed affect all kinds of
automation.  I, however, only tested the validity of the fixes with gain

Automation Write Bug

I found that when writing automation, suddenly moving the gain slider from a
lower gain to maximum gain resulted in the new high gain position point being
moved along rather than written and a new point created.  When recording
automation, only automation points that are very close together should be
connected with a non-horizontal line.  The bug resulted in automation points
that were far apart being connected by a horizontal line when what the user
really intended was for the gain to change suddenly and then continue at the
new gain level.

Automation Touch Bug

I found that while in touch mode, clicking on the slider, moving it, and then
releasing the mouse button correctly modified the automation line, however,
when a second touch was begun, all the date between the end of the previous
touch and the start of the new one were deleted.

The Fix

***In /libs/ardour/io.cc I changed the following function:

IO::set_gain (gain_t val, void *src)
	_desired_gain = val;
	gain_changed (src);
	if (_session.transport_stopped() && src != this && gain_automation_recording()) {
		// CKG: Was using add instead of rt_add.
		_gain_automation_curve.rt_add (_session.transport_frame(), val);

***In /libs/ardour/ardour/automation_event.h I added the following variable to
the protected section of the AutomationList class:

bool _new_touch;

NOTE: This variable needs to be initialized to false in the constructors for

***In /libs/ardour/automation_event.cc I changed the following functions:

AutomationList::start_touch ()
	_touching = true;
	_new_touch = true;
AutomationList::stop_touch ()
	_touching = false;
	_new_touch = false;

AutomationList::rt_add (double when, double value)
	/* this is for automation recording */
	if ((_state & Touch) && !_touching) {
		LockMonitor lm (lock, __LINE__, __FILE__);
		iterator where;
		TimeComparator cmp;
		ControlEvent cp (when, 0.0);
		bool done = false;
		if (last_rt_insertion_point != events.end()) {
			/* we have a previous insertion point, so we should delete
			   everything between it and the position where we are going
			   to insert this point.
			iterator after = last_rt_insertion_point;
			if (++after != events.end()) {
				iterator far = after;
				while (far != events.end()) {
					if ((*far)->when > when) {
				if(_new_touch) {
					where = far;
					last_rt_insertion_point = where;
					if((*where)->when == when) {
						(*where)->value = value;
						done = true;
				} else {
					where = events.erase (after, far);
			} else {
				where = after;
			iterator previous = last_rt_insertion_point;
			if (last_rt_insertion_point != events.begin() &&
(*last_rt_insertion_point)->value == value && (*previous)->value == value) {
				(*last_rt_insertion_point)->when = when;
				done = true;
		} else {
			where = lower_bound (events.begin(), events.end(), &cp, cmp);
		if (!done) {
			last_rt_insertion_point = events.insert (where, point_factory (when, value));
		_new_touch = false;
		max_x = max (when, max_x);
		min_x = min (when, min_x);
		mark_dirty ();
	maybe_signal_changed ();

More information about the Ardour-Dev mailing list