Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Faster Frac() imlementation?

7 views
Skip to first unread message

bur...@gmail.com

unread,
Jul 26, 2008, 4:02:36 AM7/26/08
to
Hi all.. maybe you can help me. I'm working on a freeware realtime
audio application for the Asus EEE pc (a little notebook with a modest
630MHz Celeron M). I'm trying to optimize my time critical routines as
much as possible.. (why waste cpu cycles on things that don't improve
sound quality, right?)

For linear interpolation, which I frequently need to do, I typically
have to apply the Ceil and the Frac functions. The Fastcode Ceil
functions have helped me improve performance significantly..

Does something faster for Frac also exist? (My own silly basm
experiments all turned out slower than the RTL Frac :-)

Any help greatly appreciated. Thanks!

Hubert Seidel

unread,
Jul 26, 2008, 4:47:03 AM7/26/08
to
Hello Anybody,

<bur...@gmail.com> schrieb im Newsbeitrag
news:be989259-7f51-48f7...@25g2000hsx.googlegroups.com...
...


> For linear interpolation, which I frequently need to do, I typically
> have to apply the Ceil and the Frac functions. The Fastcode Ceil
> functions have helped me improve performance significantly..
>
> Does something faster for Frac also exist? (My own silly basm
> experiments all turned out slower than the RTL Frac :-)
>
> Any help greatly appreciated. Thanks!

Change all to integer-mathematics, than you don't need ceil or frac.
(my crystal ball is broken, show me the code ;-)

mfg.
Herby

--
http://www.hubert-seidel.de


bur...@gmail.com

unread,
Jul 26, 2008, 5:02:02 AM7/26/08
to

> > Does something faster for Frac also exist?

> Change all to integer-mathematics, than you don't need ceil or frac.


> (my crystal ball is broken, show me the code ;-)

Here is my most simplified linear interpolation mechanism.
I don't see how floating point maths can be avoided.

//round the current pointer into my sample data up
p2 := ceil( fIndex );
// determine the previous sample index (and avoid going lower than
sample 0)
p1 := pred( p2 );
if p1 < 0 then p1 := 0;
// pointer is probably somewhere between samples.. determine where...
fract := frac( fIndex );
// get the 2 nearest samples from the sample data
h1 := sample[p1];
h2 := sample[p2];
// now calculate the interpolated value using the difference between
these two samples
delta := h2 - h1;
result := round( h1 + ( fract * delta ) );

Hubert Seidel

unread,
Jul 26, 2008, 7:32:29 AM7/26/08
to
Hello Anybody,

<bur...@gmail.com> schrieb im Newsbeitrag
news:d6b749d5-6577-4fb4...@l42g2000hsc.googlegroups.com...


> > > Does something faster for Frac also exist?
>
> > Change all to integer-mathematics, than you don't need ceil or frac.
> > (my crystal ball is broken, show me the code ;-)
>
> Here is my most simplified linear interpolation mechanism.
> I don't see how floating point maths can be avoided.

You can use fixpoint arithmetic e.g. 24:8 (in a 32bit Integer)
when 0..1 can represented with 8 Bits (0..255).

> //round the current pointer into my sample data up
> p2 := ceil( fIndex );
> // determine the previous sample index (and avoid going lower than
> sample 0)
> p1 := pred( p2 );
> if p1 < 0 then p1 := 0;
> // pointer is probably somewhere between samples.. determine where...
> fract := frac( fIndex );
> // get the 2 nearest samples from the sample data
> h1 := sample[p1];
> h2 := sample[p2];
> // now calculate the interpolated value using the difference between
> these two samples
> delta := h2 - h1;
> result := round( h1 + ( fract * delta ) );

You can play with 4 Scollbars and this:

procedure TForm1.ScrollBarSample1_0_65535Change(Sender: TObject);
begin
Calculate;
end;

procedure TForm1.ScrollBarSample2_0_65535Change(Sender: TObject);
begin
Calculate;
end;

procedure TForm1.ScrollBarGradient_0_255Change(Sender: TObject);
begin
Calculate;
end;

procedure TForm1.Calculate;
var
s1,s2,g,t:integer;
begin
s1:= ScrollBarSample1_0_65535.Position; // First sample 16bit
s2:= ScrollBarSample2_0_65535.Position; // Second sample 16bit
g := ScrollBarGradient_0_255.Position; // gradient 8bit

t := s1+ (((s2-s1)*g) div 256);

ScrollBarTarget_0_65535.Position := t;

Caption := '('+IntToStr(s1)+'..'+IntToStr(s2)+') ['+FormatFloat('0.000',
g/256)+']='+IntToStr(t)
end;

###### [not tested !!! only an example/examination to the understanding, it
can be optimize]

// determine the previous sample index

p1 := fIndex div 256;
p2 := p1 + 1;

// pointer is probably somewhere between samples.. determine where...

fract := fIndex and 255;

// get the 2 nearest samples from the sample data
h1 := sample[p1];
h2 := sample[p2];

// now calculate the interpolated value using the difference between these
two samples

delta := h2 - h1;

result := h1+ (((h2-h1)*delta) div 256);

######

Hubert Seidel

unread,
Jul 26, 2008, 7:37:28 AM7/26/08
to
Hello Anybody,

<bur...@gmail.com> schrieb im Newsbeitrag
news:d6b749d5-6577-4fb4...@l42g2000hsc.googlegroups.com...


> > > Does something faster for Frac also exist?
>
> > Change all to integer-mathematics, than you don't need ceil or frac.
> > (my crystal ball is broken, show me the code ;-)
>
> Here is my most simplified linear interpolation mechanism.
> I don't see how floating point maths can be avoided.

You can use fixpoint arithmetic e.g. 24:8 (in a 32bit Integer)


when 0..1 can represented with 8 Bits (0..255).

> //round the current pointer into my sample data up


> p2 := ceil( fIndex );
> // determine the previous sample index (and avoid going lower than
> sample 0)
> p1 := pred( p2 );
> if p1 < 0 then p1 := 0;
> // pointer is probably somewhere between samples.. determine where...
> fract := frac( fIndex );
> // get the 2 nearest samples from the sample data
> h1 := sample[p1];
> h2 := sample[p2];
> // now calculate the interpolated value using the difference between
> these two samples
> delta := h2 - h1;
> result := round( h1 + ( fract * delta ) );

You can play with 4 Scollbars and this:

ScrollBarTarget_0_65535.Position := t;

// determine the previous sample index


p1 := fIndex div 256;
p2 := p1 + 1;

// pointer is probably somewhere between samples.. determine where...
fract := fIndex and 255;

// get the 2 nearest samples from the sample data
h1 := sample[p1];
h2 := sample[p2];

// now calculate the interpolated value using the difference between these
two samples
delta := h2 - h1;

result := h1+ ((delta*frac) div 256);

######

bur...@gmail.com

unread,
Jul 26, 2008, 7:48:48 AM7/26/08
to
On 26 jul, 13:37, "Hubert Seidel" <nos...@hubert-seidel.de> wrote:
> Hello Anybody,
>
[snipped code]

> // now calculate the interpolated value using the difference between these
> two samples
> delta := h2 - h1;
> result := h1+ ((delta*frac) div 256);

Thanks.. that looks like it may speed things up quite a bit! I'm going
to play around with that.
I may even be able to translate that into asm with my limited
assembler skills.

Thanks a lot!

Bram


Pieter

unread,
Jul 26, 2008, 10:46:45 AM7/26/08
to
On Jul 26, 10:02 am, bur...@gmail.com wrote:
> Hi all.. maybe you can help me. I'm working on a freeware realtime
>

Just for information, you seem to be posting to USENET (via google
groups?) instead of using the newsserver of codegear directly. Posts
to USENET normally don't show up on the codegear servers. (Except the
ones from Hubert his ISP forwards messages to the codegear server
somehow).

http://support.codegear.com/newsgroups/

also see (4th item) http://www.teamb.com/newsgroups/faqs


Pieter

Bob Gonder

unread,
Jul 26, 2008, 12:32:52 PM7/26/08
to
><bur...@gmail.com> schrieb im Newsbeitrag
>news:be989259-7f51-48f7...@25g2000hsx.googlegroups.com...

It looks like the OP is posting questions to Google.
Thus none of his posts are arriving here.
He needs to use a newreader and post to a
newsgroup provider instead of a search engine.

newsgroups.borland.com is a valid news server
for the borland-only groups.


Bram

unread,
Jul 31, 2008, 11:28:58 AM7/31/08
to

Hi Hubert,

"Hubert Seidel" <nos...@hubert-seidel.de> wrote:

>You can use fixpoint arithmetic e.g. 24:8 (in a 32bit Integer)
>when 0..1 can represented with 8 Bits (0..255).

Thanks for this! I'm now busy replacing my all time-critical routines which use floating point with a fixed point mechanism based on the one you proposed and I've already achieved a 200% speed increase.

I've never thought about fixed point arithmatics before but it's simply perfect for many of my everyday purposes.

Cheers!
Bram

0 new messages