Re: [linux-audio-dev] EVO 0.0.5 released , resampling (interpolation) support added

New Message Reply About this list Date view Thread view Subject view Author view Other groups

Subject: Re: [linux-audio-dev] EVO 0.0.5 released , resampling (interpolation) support added
From: Benno Senoner (sbenno_AT_gardena.net)
Date: Wed Sep 20 2000 - 00:14:45 EEST


The problem with truncation vs rounding is the following:
assume that:
pos is the position in floating point which contains integer and fractional part
we want to separate them
normally we would do
pos_int=(int)pos;
pos_fract=pos - pos_int;

the problem is that the we have to avoid the fp->int truncation because
it is so slow.

We want to truncate and can't round because we want pos_fract within
a 0.0 and 1.0 range
one guy on music-dsp suggested
to first subtract 0.5 from pos
and then simply "fistl" the value (rounds to the neares integer)
this would work if the intel FPU (but I believe that this is specified by the
IEEE floating point standard) won't screw things when the fractional part
equals 0.5.
Basically the Intel FPU rounds to the nearest even number that means:
1.5 is rounded to 2 and 2.5 is rounded to 2 too.
3.5 is rounded to 4 , 4.5 is rounded to 4 too (because 4 is the nearest even)

so what I had in mind is the following:
fistl the pos value so that you get the rounded value
store it in pos_int
pos_fract = pos - pos_int
if(pos_fract >= 1.0) { pos_fract -= 1.0; pos_int++; }

or alternatively:
pos -= 0.5
and repeat the procedure above:
fistl the pos value so that you get the rounded value
store it in pos_int
pos_fract = pos - pos_int
if(pos_fract >= 1.0) { pos_fract -= 1.0; pos_int++; }

not sure if the first or the second solution will be faster:
in the first case the post_fract >= 1.0 condition is hit more often
in about half the cases in mean

in the second case the round produces the correct result in the
majority of the cases, except when pos = 2.5 , 4.5 , 6.5 etc
but the overhead is that we have one more subtraction compared
to the first solution.
Which one will be faster in your opinion ?
(when implemented, I'll try to determine this empirically by running
benchmarks, but some advice would be handy)

Regarding the final floatpoint->int operations when sending the final
audio sum to the audio device, here I do agree that rounding
is the right way to go ( Karl's int_to_double) ,since we gain
in mean 3dB of S/N ratio ( basically 1/2 bit))

thoughts ?
Benno.

On Tue, 19 Sep 2000, Karl JH Millar wrote:
> I'm not an x86 assembly expert, but this one is pretty simple. I believe that
> the way to do fp->int conversion quickly is this:
>
> inline int double_to_int(double f) {
> #ifdef __i386__
> int i;
> asm("fistpl %0" : "=m"(i) : "st"(f) );
> return i;
> #else
> return (int)f;
> #endif
> }
>
> inline double int_to_double(int i) {
> #ifdef __i386__
> double f;
> asm("fildl %1" : "=st"(f) : "m"(i));
> return f;
> #else
> return (double)i;
> #endif
> }
>
> To get the routines for single-precision, just replace double with float. The
> asm is the same. This should be very fast (comparable a single multiply,
> although the timings vary from processor to processor).
>
> This method makes more sense than a "portable" C only method, as for most
> processors you'd expect the direct method to be optimal.
>
> >I'll try both custom FP asm (rounding and then check if
> >the fractional part is >1.0 and in that case decrement it by
> >1.0 and increase the int part by 1),
>
> Do you really want to truncate rather than round? While the C standard
> specifies truncation, most audio needs would probably be better served by
> rounding anyway. Is it a portability/consistency concern?
>
> Karl.


New Message Reply About this list Date view Thread view Subject view Author view Other groups

This archive was generated by hypermail 2b28 : Tue Sep 19 2000 - 23:32:16 EEST