Updating SR % 8, how to get it smoother?

DSP, Plugin and Host development discussion.
Post Reply New Topic
RELATED
PRODUCTS

Post

Usually I update LFO's & envelopes at samplerate, but polyphony is killing me at the moment. So I've decided (by recommendation here) to update my LFOs at samplerate % 8 and envelopes samplerate % 4. The clock bleed is pretty bad, so I'm wondering what would be a cheap way to smooth it out, without spoiling all the CPU I gained?

Andrew

Post

Ichad.c wrote:Usually I update LFO's & envelopes at samplerate, but polyphony is killing me at the moment. So I've decided (by recommendation here) to update my LFOs at samplerate % 8 and envelopes samplerate % 4. The clock bleed is pretty bad, so I'm wondering what would be a cheap way to smooth it out, without spoiling all the CPU I gained?
Linear interpolation is probably the cheapest approach and works quite well (in my opinion much better than any simple one-pole smoothers that cost more as well).

Post

Yeah, was thinking of something similiar. Implementation wise, I assume I need to safe the previous value -> then have a "master" phase-accumulator running at SR % 8, that basically just fades between old and new value?

Just to note, both my LFOs and ENVs use phase-accumulators so the next value is unknown.

Post

Ichad.c wrote:Yeah, was thinking of something similiar. Implementation wise, I assume I need to safe the previous value -> then have a "master" phase-accumulator running at SR % 8, that basically just fades between old and new value?

Just to note, both my LFOs and ENVs use phase-accumulators so the next value is unknown.
Well, you run your LFOs and envelopes at the reduced control rate, then keep the old and new values. You can do the interpolation with single multiply add as old+t*delta where delta=new-old and t=[0,1] for the interpolation period, not counting the time to come up with the t coeff. You could also use old+=delta accumulators and delta=(new-old)*(1.0/ratediv) to do away with the parameter, at a cost of a memory write.

In either case, it's pretty cheap and even if you had an LFO or envelope that was roughtly similar anyway, you still save tests and branches for reset logic and such.

Post

Thats plenty food for thought, the last idea(memory write) sounds interisting, will definety need to bench these!

Thanks!

Post

Ichad.c wrote:Thats plenty food for thought, the last idea(memory write) sounds interisting, will definety need to bench these!
The accumulator is likely to be faster where you have an extra register to cache the values (eg simple gain control) while in other situations it depends..

Post

For SR % 8, should...

Code: Select all

//Version1
delta = (new - old) * (1/8);
old +=delta;
not be?

Code: Select all

//Version2
delta = (new - old) * (1/8);
accumulator+= delta;
Version2 is smoother albeit my implementation seems to accumulate some DC offset when phase is updated - but I have the suspicion that it has to do with the block-based implementation of SE, need to get to the bottom of this. Version1 does not have this issue though. Initial CPU tests show a CPU saving of ~60% - which is great.

Andrew

Post

Ichad.c wrote: Version2 is smoother albeit my implementation seems to accumulate some DC offset when phase is updated
You must either reset the accumulator to the old value as you update delta every 8 samples, or you must calculate the delta against the accumulated value. Otherwise you build up some rounding errors over time.

That's why I just suggested using the "old" variable directly; you still accumulate a bit of error (over the 8 samples) but then when the delta value is updated, it's calculated from the "wrong" position to the new target, so the error doesn't grow unbounded.

Also just to make sure, you are only supposed to calculate a new delta at control rate.

Post

mystran wrote: Also just to make sure, you are only supposed to calculate a new delta at control rate.
:dog: That was it. Your version(1) is cheaper. Don't think the error is much of a problem with LFOs, will check how it behaves with envelopes.

Thanks again!

Post

Ichad.c wrote:
mystran wrote: Also just to make sure, you are only supposed to calculate a new delta at control rate.
:dog: That was it. Your version(1) is cheaper. Don't think the error is much of a problem with LFOs, will check how it behaves with envelopes.
The error over 8 samples is typically very small (few least significant digits at best). It only ever becomes meaningful if you allow it to accumulate over longer periods of time and that doesn't happen if you use the accumulated value (that contains the error) to calculate a new delta as the negative feedback will result in the errors staying bounded (and in practice very small).

Post Reply

Return to “DSP and Plugin Development”