This is proof of concept only (but code works--I have it in my synth now).

Note that x must come in as 0<x<=4096. If you want to scale it to something else (like 0<x<=2*M_PI), do it in the call. Or do the math to scale the constants properly.

There's not much noise in here. A few little peaks here and there. When the signal is at -20dB, the worst noise is at around -90dB.

For speed, you can go all floats without much difference. You can get rid of that unitary negate pretty easily, as well. A couple other tricks can speed it up further--I went for clarity in the code.

The result comes out a bit shy of the range -1<x<1. That is, the peak is something like 0.999.

Where did this come from? I'm experimenting with getting rid of my waveform tables, which require huge amounts of memory. Once I had the Hamming anti-ringing code in, it looked like all my waveforms were smooth enough to approximate with curves. So I started with sine. Pulled my table data into Excel and then threw the data into a curve-fitting application.

This would be fine for a synth. The noise is low enough that you could easily get away with it. Ideal for a low-memory situation. My final code will be a bit harder to understand, as I'll break the curve up and curve-fit smaller sections.

float xSin(double x)

{

//x is scaled 0<=x<4096

const double A=-0.015959964859;

const double B=217.68468676;

const double C=0.000028716332164;

const double D=-0.0030591066066;

const double E=-7.3316892871734489e-005;

double y;

bool negate=false;

if (x>2048)

{

negate=true;

x-=2048;

}

if (x>1024)

x=2048-x;

if (negate)

y=-((A+x)/(B+C*x*x)+D*x-E);

else

y=(A+x)/(B+C*x*x)+D*x-E;

return (float)y;

}