[music-dsp] fast sin(x) function

robert bristow-johnson rbj at audioimagination.com
Wed Jun 11 18:29:45 EDT 2008


> ----- Original Message -----
> From: "Stephen Blinkhorn" <stephen.blinkhorn at audiospillage.com>
> To: "A discussion list for music-related DSP" <music-dsp at music.columbia.edu>
> Subject: Re: [music-dsp] fast sin(x) function
> Date: Wed, 11 Jun 2008 14:40:39 -0600
> 
> 
> On 10 Jun 2008, at 15:31, robert bristow-johnson wrote:
> 
> > if the OP wants a sin() function for the purpose of generating a nice sine 
> > wave for sound, then i would also recommend LUT that is large enough that 
> > linear interpolation would be good enough.
> 
> Okay, for now I'm just using sin(x) I'll have a look at using a LUT.
> 
> >  if instead the sin() function is used in control/coefficient generation, 
> > then i would suggest using the finite order series below.  with the 
> > exception of arctan(), there is no division in any of these.  should be 
> > fast for a DSP.
> 
> thanks for these I'll experiment with them later.  I am finding that sin(x) 
> functions are cropping up in a variety of places in my work (coefficients 
> etc)

that was my intention with these finite-order polynomial approximations.  not so much for waveform generation (where i would prefer to use a phase-accumulator and LUT).

> as well as cos(x)

to do cos(x), try cos(x) = 1 - 2*(sin(x/2))^2 .  with a good sin(x) approximation, that should work good.  if you're using this cos(x) for filter coef generation or to compute the frequency response curve, then you should express all coef and such formulae in terms of 1-cos(x) instead of cos(x) for numerical reasons (when the frequency is in the bottom 3 octaves, cos(x) is too close to 1.0 that all of the salient information exists in the difference of cos(x) from 1.0, or in the least significant bits, even using floating-point arithmetic.)

so you'll see that 1-cos(x) is the same as 2*(sin(x/2))^2, which if you're using floating-point arithmetic, doesn't lose accuracy as x (or 2*pi*f/Fs) gets into the bottom couple octaves.

> so I've been on the lookout for something fast and 
> accurate but I have been trying to avoid using  lookup tables.. can't say why 
> exactly something just told me to avoid  them in certain situations.

LUT has little discontinuities in the function (or one of its derivatives if some kinda interpolation or spline is used).  the power series method, although it has *some* error (if the polynomial order is finite), is completely smooth in the domain where it is spec'ed.  no funky discontinuities.

>  Oh and I am developing for PowerPC and Intel.

then maybe division or floating-point is of no extra cost to you.  sometimes either or both of those (floating-point and/or division) are expensive in the DSP world.  LUT is real cheap in execution cycles (but expensive in terms of memory used).  LUT with linear interpolation is a little more costly, these low-order finite series are a little more expensive than simple LUT with linear interp.

--

r b-j                  rbj at audioimagination.com

"Imagination is more important than knowledge."



More information about the music-dsp mailing list