[linux-audio-dev] XAP: Some thoughts on control ramping

David Olofson david at olofson.net
Mon Jan 20 18:49:00 UTC 2003


On Monday 20 January 2003 18.59, Steve Harris wrote:
> On Mon, Jan 20, 2003 at 06:08:48 +0100, David Olofson wrote:
> > > but the cases I can think of it wont hurt:
> > >
> > > notched switches: will always jump to the target value anyway,
> > > so wont have to do any interpolation.
> >
> > RAMP is always interpreted as SET? Not the best way to fake
> > ramping, but then, if you say you do not ramp, you shouldn't be
> > expected to even fake it. Makes sense.
>
> Well, youd have to extrapolate the ramp to the pint where the next
> notch is reached and reshedule a 0 duration event for there if the
> timing was critical.

Yeah - but then you really have a continous control with some 
internal processing. I think a control is either continous or not, 
from the API POV. If it's continous, it should implement or "fake" 
ramping in the way expected. If it's not continous, it shouldn't have 
to worry about ramping.

Anyway, inserting an event a bit later in your own queue doesn't 
sound all that hard, but there's a "hidden" problem: If the event 
lands beyond the end of the block, event ordering will be screwed up. 
Senders just add events at the end of queues, assuming that there are 
no events for the current block when they start sending.

One solution would be to always insert/sort, but I don't see many 
situations where this overhead and complexity *really* adds anything. 
Also, such a design would be in conflict with the idea that controls 
are driven by structured data; an efficient alternative to audio rate 
controls, rather than a "sequencer database interface".


> > So, alternative 1; RAMP events only:
> >
> > 	  case XAP_A_RAMP:
> > 		if(ev->duration)
> > 			dvalue = (ev->value - value) / ev->duration;
>
> I think you'll find that that should be
> 		dvalue = (ev->value - value) / (ev->duration + 1.0f);
>
> Otherwise you end up with unwanted shelves or delays in the ramp
> shape.

Yes, you're right. My confusion is because Audiality (for some 
reason) applies dv *after* using v for each sample.


> No branch is needed,

Excellent! :-)


> cos the next delta of the control value will
> set it to the correct value, but it may well just be easier to set
> it and not have to cancel the delta next sample.

That sounds like the case where you're looking for a STOP event - and 
I don't think there's a real need for that.

If you say "aim at (y, t)", you mean exactly that - and what the 
receiver does when passing t is really *undefined*. It might try to 
continue ramping, but you should *never* allow it to, because the 
plugin might blow up if the ramping isn't as linear as you think it 
is!

Just always tell the receiver what to do at or before the current aim 
point, and you're safe. Ramped controls are driven by a chain of RAMP 
events.

It may feel a bit scary that you can't reliably stop ramping, but 
it's not very different from audio streaming. You don't have a 
definitive stable/dead/stopped state until you kill the stream - and 
that means disconnecting the input, or taking the receiver out of the 
net. Untill you do that, you have to do *something* to keep the 
receiver happy.


> > Using only RAMP events definitely looks like a great idea to me.
> > I'm going to try it in Audiality right away! :-)
>
> Yup, I like it too.
>
> > BTW, using INFINITY for duration (MAXINT for fixed point,
> > provided MAXINT is not a valid control value) has the same effect
> > as a STOP event... Should this be allowed? We've already
> > concluded that the
>
> No, getting Infs into float code can cause problems down the line.

Yeah, you're probably right - and again, the usefullness of the STOP 
feature is an illusion. Old habit or something; I tend to like the 
idea of stable states.


> > And yes, duration would be of the same type as the control value,
> > I think. There's no point in making it an integer for float
> > controls, since plugins will only use it for a aim point -> dv
> > transformation anyway.
>
> Yes, though there is the problem of what happens when the host
> specifies a non integer duration,

That would be illegal... Which is a good reason to prevent it, to 
eliminate the possibility, as well as any doubts about what 
'duration' really is.


> events cant arrive at non integer
> timestamps, so you will end up with overshoot or undershoot.

Yes...


> It may
> be safer to make them ints. int -> float cast is not expensive.

Right, and the cast has to be done *somewhere* anyway, I think. 
(Except when playing back prerecorded events, but that's not really 
something to optimize for.)

At least, the Audiality EG calculates 'duration' as the # of frames 
to the next node or other event, so it's all integer math in that end 
of the connection anyway. Well, the node timing is derived from fixed 
point values, but that's *before* we start talking about event 
timestamps. Any other way could potentially have 'duration' disagree 
with event timing due to rounding errors. *heh*


//David Olofson - Programmer, Composer, Open Source Advocate

.- The Return of Audiality! --------------------------------.
| Free/Open Source Audio Engine for use in Games or Studio. |
| RT and off-line synth. Scripting. Sample accurate timing. |
`---------------------------> http://olofson.net/audiality -'
   --- http://olofson.net --- http://www.reologica.se ---



More information about the Linux-audio-dev mailing list