Erik de Castro Lopo wrote:

On Tue, 29 Jun 2004 10:19:32 +0200
Benno Senoner <[EMAIL PROTECTED]> wrote:



In LinuxSampler we do

 double increment;
 double fullindex;
 int integer;
 double fractional;
 for (;;)
 {
   /* Bunch of other code. */

fullindex += increment;
integer = lrintf(fullindex);
fractional = fullindex - integer;
}



Have you tried compiling your code with gcc-3.4? Do you have a test suite that will pick up if the above construct turns out wrong?

Lets say that after the addition of increment, the value of fullindex
in the 80 bit internal representation is 1.99999999999999999999999.
Pass that number through lrint and you get 2 and subtract 2 from the
80 bit internal representation and you get -0.00000000000000000000001
which is excatly the sort of problem I was trying to avoid.



I did not benchmark the above code against yours but I think it should be faster.


<>
I value correct-ness above speed :-).

Perhaps I should have added that our code is used to get the fractional part and integer part in our code
is used to perform interpolation (either linear or cubic).
And even the above code based on lrintf() or FISTL can in some cases return integer=x and fractional = 1.0
the value returned by the interpolator is still correct (we discussed this years ago on the music-dsp, I'm too lazy
to dig in the archives). Even if it's a bit below zero, thanks to the continuity of the polynomial interpolator you don't get
bogus results.
This is why we believe it's the fastest (staying in the floating point domain) method possible (and stil correct for our purpose, aka doing interpolation).
One could go a bit further and use a fixed point int part/fract part index like Steve described. In that case you
could optimize the cubic interpolation (as Juan L. does in cheesetracker) and look up the coefficients from tables.
But I think in case of LinuxSampler it would not buy us a big performance increase since we do lots of other stuff too, I could be wrong.
At a later stage we will experiment with this to see if we can squeeze out even more performance from the interpolator,
but for now there are more important things to do like providing perfect GIG playback etc.



(plus instead of lrintf() we use an asm FISTL macro which is a bit faster (around 10% IIRC).



lrintf() is portable (ISO C99 standard), FISTL is not.


of course, but since we encapsulated all in a static inlined C++ class the #ifdefs in that class use the most
efficient code depending from what architecture you are compiling on.


cheers,
Benno
http://www.linuxsampler.org



Reply via email to