Post some code. :)
In both [line~] and [vline~] I believe the increment is calculated, set, and unset set once per event, since all the info you need for the ramp is given by the event definition. Unsetting it is the fun part -- it doesn't unset once it's reached its target, but rather once the number of blocks or samples has passed. Check out these lines of code, though:
if (x->x_ticksleft)
{
t_sample f = x->x_value;
while (n--) *out++ = f, f += x->x_inc;
x->x_value += x->x_biginc;
x->x_ticksleft--;
}
else
{
t_sample g = x->x_value = x->x_target;
while (n--)
*out++ = g;
}
if (x->x_targettime <= timenext)
f = x->x_target, inc = x->x_inc = 0, x->x_targettime = 1e20;
*out++ = f;
f = f + inc;
In [line~]: if there are still blocks to ramp over, get the value set from the last block, increment all the samples in the new block by the increment, store what will be the value for the next block, and decrement the number of blocks left. If there are no blocks left, then manually set a variable and the next block value to the target, and write that to all the points in the block.
In [vline~]: if the target time has elapsed, set the variable f to the target, the increment to zero, and put the next target time WAY off in the future. Then continue to increment successive values in the block by 0. Since it's checking every sample here instead of every block, a conditional here would be more expensive than just adding 0 every time.
Anyway, manually setting the output value to the target at the end of the ramp ensures that you'll make your target. That way you don't have to worry about trying to time exactly when to unset the increment right when it's finally incremented to the target, which is a great way to get an off-by-one error.
Matt