[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.
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:
void
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
AutomationLiest.
***In /libs/ardour/automation_event.cc I changed the following functions:
void
AutomationList::start_touch ()
{
_touching = true;
_new_touch = true;
}
void
AutomationList::stop_touch ()
{
_touching = false;
_new_touch = false;
}
void
AutomationList::rt_add (double when, double value)
{
/* this is for automation recording */
if ((_state & Touch) && !_touching) {
return;
}
{
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) {
break;
}
++far;
}
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;
--previous;
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