[gmpi] Re: Reqs 3.8 Events - ramped events

  • From: David Olofson <david@xxxxxxxxxxx>
  • To: gmpi@xxxxxxxxxxxxx
  • Date: Wed, 7 Jan 2004 18:16:39 +0100

On Wednesday 07 January 2004 15.25, Steve Harris wrote:
> On Wed, Jan 07, 2004 at 02:47:46PM +0100, David Olofson wrote:
> > > That assumes that the default values cause no click on
> > > disconnection - I dont think thats likly to be true, it would
> > > be easier/better to just xfade to passthrough with latency
> > > correction.
> >
> > Well, passthrough would probably be the default value for most
> > controls - and what I'm describing *is* a fade from the current
> > value to the default value, expressed as <target, duration> ramp
> > events.
>
> I dont think you can assume that passthrough is the default.

You don't have to, if there is a way to find out the plugin's default 
value for a control. Sort of like pull-up/down in electronics; it's 
what you get if nothing drives the input.


> I
> wasnt talking about xfading the parameters, I was talking about
> xfading the audio.

I see, but I don't think it's the right solution for declicking 
control (dis)connections. It only works in special cases with certain 
kinds of plugins.

For example, if you abruptly change a parameter of a reverb plugin, 
the resulting click could be heard reverberating in the audio output 
for ages. Xfading the audio won't make much of a difference.


[...]
> > > True. Though this can be done equally well by multiplying delta
> > > by the krate.
> >
> > Yeah. (Unless we use <delta> events, but that seems like a really
> > bad idea. Rounding errors build up over time, whereas <target,
> > duration> events eliminate it by always aiming at the target
> > value.)
>
> I dont think thats a valid argument, the vast majority of plugins
> will calcuate a delta anyway.

Well, I actually missed another detail: You *can't* calculate the 
target value if you get <start, delta> or <delta> events. You need 
the duration. <target, delta> would work, but that seems like a 
rather silly format to me. (Why do you need the target when you have 
the current value and the delta, provided ramps are not required to 
stop automatically?)

Anyway, the argument you're complaining about is still valid. It 
doesn't matter what the plugin does internally - which almost 
certainly will involve a delta in some form, with inaccuracies and 
all. What *does* matter is that even if you land slightly off at the 
end of a ramp, the next ramp will correct that, since

        delta = (target - current_value);

With <delta> events, that "automatic compensation" is lost, and 
control values wander further and further off over time, unless the 
internal sender and receiver calculations give identical results.

I certainly don't think you can assume they do, since the sender and 
receiver may be using different code, they could run on different 
machines with different CPUs, there could be float<->double control 
conversions on the way and whatnot.

With <start, delta> events, the long term error buildup is eliminated, 
but instead, you risk getting a small jump in the control value 
whenever a ramp event is received. This may not be an issue with 
float or double control, but I learned the hard way that it *is* an 
issue with fixed point controls. (Unless they have much more than 
twice the number of bits of an audio sample, at least. 32:32 controls 
for 32 bit audio with 0 dB at 16 bits? I don't think so...)


> > Multiplying is usually a bit faster than dividing BTW, but
> > someone, somewhere will have to make that dreaded division
> > anyway. :-)
>
> Yes, but in the case where your given target and duration you have
> no choice but to divide.

Right. Nothing comes for free, though...


> > > Some disadvantages:
> > >
> > > * Plugin will just do delta = target/duration 99% of the time
> > > anyway.
> >
> > Probably - but if they don't, whoever generates the events will
> > have to do it instead. Sequencers might get away without doing it
> > in real time, but only if there are no non-destructive
> > transformation features.
>
> Thats assuming that the sequencer thinks in terms of targets and
> durations, they may not, and there in a better place to optimise
> it, eg. calualating the reciprocal of the duration if they're going
> to do a hundred at once (fairly likely).

Either way, you'll need to deal with the potential error buildup one 
way or another, so you can't avoid generating at least absolute 
values and at least one of deltas, durations and whatever other 
representations we can dream up.

All in all, I think any sensible representation will be slightly 
suboptimal in some cases. If we're anywhere near the right answer, 
it'll even out in any real life system, so it doesn't really matter 
which one we pick. There are more important things to consider.


> > > * Special case handling for duration = 0 (branch).
> >
> > That, or you have to check for zero duration when generating the
> > events. duration == 0 is a special case that needs to be handled
> > somewhere no matter what.
>
> Not if you pass deltas, then its not a special case.

It just becomes a special case on the sender side instead.

Consider an envelope generator that converts sections from (say) 
seconds to samples. If a section is short enough and/or the sample 
rate low enough, there'll be a division by zero (or a useless result, 
if FPU exceptions are disabled) if there's no check.


> > > * Plugin has to store what the next value will be (and at what
> > > time) if it wants to ignore ramps, or we need two seperate
> > > representations.
> >
> > That's just a matter of how "well" ramps are to be faked when
> > ramping is not supported. You can set the target value right away
> > (which is the default behavior with <target, duration> events),
> > at the end of the ramp, or in the middle of it. The last one is
> > probably the best option of those, but the real solution is to
> > support ramping, or at least approximate it properly.
>
> But all of those are more work to handle that just taking the value
> from a (value, delta) representation.

I don't see how grabbing 'target' from <target, duration> is more 
work. :-)


> > Anyway, here's a disadvantage with <start, delta> ramps:
> >
> >     * Senders and receivers of ramp events must be
> >       implemented with sufficient accuracy, or they
> >       may disagree about the current state when ramp
> >       events are delivered. Whan that happens, there
> >       will be a jump from the current value to the
> >       start value of the event.
>
> Theres no way the error is going to be significant over a
> reasonable ramp range. I just wrote some test code:
> http://plugin.org.uk/~swh/ramp.c for a ramp of 100,000 samples,
> with krate=arate the error is 0.06%. That wont be audible.

Right - but that means we need to change the ramping events and 
semantics to support integer/fixed point platforms. I don't see the 
point, when we can just use <target, duration> events and be done 
with it.


> > <target, duration> ramps don't have this issue. You don't need to
> > have a clue about the current value to generate a proper, click
> > free ramp, so it works reliably even if the control input has an
> > extremely inaccurate ramping implementation.
>
> A lot of the time the plugin will be applying its own smoothing to
> the result of the linear ramp, and I dont see this as an issue
> anyway. Why would it be that innacurate?

Try fixed point controls. :-)

Either way, as I pointed out in another mail, the whole point with 
ramped events is to avoid destructively brutal smoothing. Linear 
ramping is bad enough as it is, but at least it doesn't inherently 
generate practically random transients between sections.


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

.- Audiality -----------------------------------------------.
|  Free/Open Source audio engine for games and multimedia.  |
| MIDI, modular synthesis, real time effects, scripting,... |
`-----------------------------------> http://audiality.org -'
   --- http://olofson.net --- http://www.reologica.se ---


----------------------------------------------------------------------
Generalized Music Plugin Interface (GMPI) public discussion list
Participation in this list is contingent upon your abiding by the
following rules:  Please stay on topic.  You are responsible for your own
words.  Please respect your fellow subscribers.  Please do not
redistribute anyone else's words without their permission.

Archive: //www.freelists.org/archives/gmpi
Email gmpi-request@xxxxxxxxxxxxx w/ subject "unsubscribe" to unsubscribe

Other related posts: