[music-dsp] fast sin(x) function

Joost Schuttelaar joost at greenskin.net
Sun Jun 22 06:44:36 EDT 2008


On Jun 21, 2008, at 10:38 , Ross Bencina wrote:

> As for lookup tables, I'd love to see some discussion of efficient  
> high-resolution modulo phase increment computations. Often 32 bits  
> of phase doesn't provide enough frequency precision for audio  
> applications.. I've been using a double precision float, limiting  
> the range to the LUT length with if() and cast to int using FISTP  
> (on IA32) -- seems like there may be some other (faster?) techniques  
> though, perhaps 64 bit integer phase variables are a practical  
> alternative these days...

I'd be interested in hearing about this as well. I have been using the  
exact same method as you but it remains one of the more heavy parts of  
my synthesis algorithms. I'd love to optimize a bit here.

I tried to optimize the cast using magic doubles, which isn't much  
faster. Another way is to use some scary bitmasks:

inline unsigned int floatTo23Bits(float x) {
	float y = x + 1.f;
	return *((unsigned long *)&y) & 0x7FFFFF; // last 23 bits
}

inline float sine(float phase) {
	// assumes SINE_TABLE_LENGTH = 256!
	// assumes BIG ENDIAN!
	float fracIndex = phase * (SINE_TABLE_LENGTH);
	int intIndex = floatTo23Bits(phase) >> (23-8);
	float perc = fracIndex - intIndex;
	return sine_table[intIndex] * (1 - perc) + sine_table[intIndex + 1] *  
perc;
}

Which performs a bit better but is very scary :)

So it might be that 64-bit integer phasors are indeed be a better idea!

-- 

Joost Schuttelaar
The Hague, NL


More information about the music-dsp mailing list