[LAD] Is -ffast-math safe for audio?
Will Godfrey
willgodfrey at musically.me.uk
Sun Nov 25 11:18:06 CET 2018
On Sat, 24 Nov 2018 14:19:01 +0100
Fons Adriaensen <fons at 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.
More information about the Linux-audio-dev
mailing list