Main Archive Specials Wiki | FAQ Links Submit Forum


Fast SIN approximation for usage in e.g. additive synthesizers

References : Posted by neotec

Notes :
This code presents 2 'fastsin' functions. fastsin2 is less accurate than fastsin. In fact it's a simple taylor series, but optimized for integer phase.

phase is in 0 -> (2^32)-1 range and maps to 0 -> ~2PI

I get about 55000000 fastsin's per second on my P4,3.2GHz which would give a nice Kawai K5 emulation using 64 harmonics and 8->16 voices.


Code :
float fastsin(UINT32 phase)
{
const float frf3 = -1.0f / 6.0f;
const float frf5 = 1.0f / 120.0f;
const float frf7 = -1.0f / 5040.0f;
const float frf9 = 1.0f / 362880.0f;
const float f0pi5 = 1.570796327f;
float x, x2, asin;
UINT32 tmp = 0x3f800000 | (phase >> 7);
if (phase & 0x40000000)
tmp ^= 0x007fffff;
x = (*((float*)&tmp) - 1.0f) * f0pi5;
x2 = x * x;
asin = ((((frf9 * x2 + frf7) * x2 + frf5) * x2 + frf3) * x2 + 1.0f) * x;
return (phase & 0x80000000) ? -asin : asin;
}

float fastsin2(UINT32 phase)
{
const float frf3 = -1.0f / 6.0f;
const float frf5 = 1.0f / 120.0f;
const float frf7 = -1.0f / 5040.0f;
const float f0pi5 = 1.570796327f;
float x, x2, asin;
UINT32 tmp = 0x3f800000 | (phase >> 7);
if (phase & 0x40000000)
tmp ^= 0x007fffff;
x = (*((float*)&tmp) - 1.0f) * f0pi5;
x2 = x * x;
asin = (((frf7 * x2 + frf5) * x2 + frf3) * x2 + 1.0f) * x;
return (phase & 0x80000000) ? -asin : asin;
}



Comments


Added on : 09/12/08 by neotec
Comment :
PS: To use this as an OSC you'll need the following vars/equ's:

UINT32 phase = 0;
UINT32 step = frequency * powf(2.0f, 32.0f) / samplerate;

Then it's just:
...
out = fastsin(phase);
phase += step;
...




Added on : 14/12/08 by bob[ AT ]yahoot[ DOT ]com
Comment :
Woah! Seven multiplies, on top of those adds and memory lookup. Is this really all that fast?



Add your own comment
Comments are displayed in fixed width, no HTML code allowed!
Email:

Comment:

Are you human?



Site created and maintained by Bram
Graphic design by line.out | Server sponsered by fxpansion