Is `applyGainRamp` ramping all numSamples asked?


#1

I have a question regarding the applyGainRamp in AudioSampleBuffer. Pardon me, if i am not reading something correctly.

The signature is

applyGainRamp (int channel, int startSample, int numSamples, Type startGain, Type endGain).

I find that the current implementation is not setting the last sample’s value(the one with index startSample+numSamples) to endGain.

Shouldn’t
const auto increment = (endGain - startGain) / (float) numSamples;
be
const auto increment = (endGain - startGain) / (numSamples-1.0f);?

Also, shouldn’t
startSample + numSamples <= size
in the assertion be
startSample + numSamples < size?


#2

If you ramp over 5 samples, you increment 5 times, so the equation should add up:

endGain = startGain + numSamples * increment;
endGain = startGain + numSamples * ((endGain - startGain) / numSamples);
endGain = startGain + (endGain - startGain);
endGain = endGain
qed.

I don’t think so, if the block has a size of 5, it would be legit to have a ramp of 5 samples, wouldn’t it?

Hope that makes sense.

EDIT: now I get your point, if you ramp a buffer of 5 samples, you only increment only 4 times, so either the startGain or the endGain are outside of the interval.
So it seems no sample gets assigned endGain…
In practise I think the implementation makes sense, since if you keep going with ramps, the next block would start with the previous endGain. If you change this you would add steps on each buffer size…


#3

I think any messing comes from mixing indexes and lengths in the same math.


#4

For a 5 sample buffer, a ramp over 5 samples would require 4 steps/increments/decrements.


#5

I know, but if you divide a ramp from 0 to 1 over 1024 samples into 4 calls, you would call

applyGainRamp (0,   0, 256, 0.0,  0.25);
applyGainRamp (0, 256, 256, 0.25, 0.5);
applyGainRamp (0, 512, 256, 0.5,  0.75);
applyGainRamp (0, 768, 256, 0.75, 1.0);

If you do it your way, sample 255 AND 256 had the gain 0.25, the sample 511 AND 512 had 0.5 and so on. This is not the desired behaviour.


#6

However, the 0 gain will never be applied. I guess the zeroing would be expected at the next sample after the range.

But, I think i see the point of the current implementation.

Thanks


#7

Also, i think *c++ goes beyond the buffer’s limit. :thinking:

EDIT: e.g. for a 5 sample buffer, having numSamples==5


#8

It points to the address after the buffer, but it is not accessing the memory after it was incremented to point there, so totally legit AFAIK.


#9

Oh, ok. So the *= is invoked prior to the ++. Thanks again.


#10

Yes, that’s the difference of d++; vs. ++d; if the ++ is written before the variable, it is incremented before the rest of the statement, otherwise afterwards.