On Sat, 24 Nov 2018 14:19:01 +0100
Fons Adriaensen <f...@linuxaudio.org> wrote:

>On Sat, Nov 24, 2018 at 10:49:46AM +0000, Will Godfrey wrote:
>
>> >The safe way is of course:
>> >
>> >int i = (int) floorf (p);
>> >float f = p - i;  
> 
>> I'd been mulling over *exactly* that point for some time. My reasoning being
>> that in the latter case, if the integer was slightly wrong then using it for
>> the subtraction should give a remainder that was also slightly wrong, but in 
>> a
>> direction that tends to compensate for the error.  
>
>How can an int be 'slightly wrong' ? :-)

Ummm, bad wording on my part. I meant out by 1. The difference would be made up
next period.

>The advantage of the 'safe' way is that you always have p == i + f.
>
>> The other thing, is why do we need the floorf? Or in the original example
>> (which was taken from working code) truncf?
>> A straight cast to int seems to give exactly the same result, and is at least
>> twice as fast with -O3 and about 4 times as fast unoptimised.  
>
>We want f >= 0, so rounding must be towards -inf. Casting will truncate
>(i.e. round towards zero). This gives the correct result only if p >= 0.
>That may be all you need, but I wouldn't like to depend  on it.

Well in this particular case, it can't be less than zero - notwithstanding time
travel :)

>There is a way to avoid all float to int conversions, at least outside
>the per-sample loops.
>
>Suppose you have a wavetable of size L, current position is float p,
>and increment is float f. To generate N samples you'd have something
>like:
>
>
>for (i = 0; i < N; i++)
>{
>    k = floorf (p);
>    u = p - k;
>
>    // use k, u to interpolate in wavetable
>
>    p += f;
>    if (p >= L) p -= L;
>}
>
>To avoid floorf() inside the loop, instead of maintaining p and f
>as floats, split both of them from the start into an integer and
>float part:
>
>k = floorf (p);
>u = p - k;
>
>kf = floorf (f);
>uf = f - kf;
>
>for (i = 0; i < N; i++)
>{
>    // use k, u to  interpolate in wavetable
>
>    k += kf;
>    u += uf;
>    if (u >= 1.0f) 
>    {
>       k += 1;
>       u -= 1;
>    }
>    if (k >= L) k -= L;
>    // or k &= L-1 if L is a power of 2.       
>}
>
>
>Ciao,
>

Interesting. I'll look into this.

-- 
Will J Godfrey
http://www.musically.me.uk
Just because you know what I'm talking about, it doesn't mean *I* do.
_______________________________________________
Linux-audio-dev mailing list
Linux-audio-dev@lists.linuxaudio.org
https://lists.linuxaudio.org/listinfo/linux-audio-dev

Reply via email to