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