Hacker News new | ask | show | jobs
by Animats 3370 days ago
If you're interpolating and only need 16 bits of precision, you need only a small table. 32 or 64 entries should be enough for sine and cosine.
2 comments

An example of the linear-interpolated lookup table approach using fixed-point math is the sine generation[0] in my music synthesizer. It generates a table of 1024 entries, then lerps between those. This gives you precision beyond the least perceptible audio error, and is pretty fast.

When I first wrote that code, I was targeting 32 bit ARM, with possibly very weak floating point units. These days, on the types of chips you'd see in phones (or computers in the $9-$40 range like rpi 3), the floating point calculation is _so_ fast (especially with simd) that the cost of the memory lookup starts dominating. So, the NEON implementation computes 4 sin values in a gulp, using a floating point polynomial approximation about the same precision as above[1].

[0] https://github.com/google/music-synthesizer-for-android/blob...

[1] https://github.com/google/music-synthesizer-for-android/blob...

It’s probably a generally better idea to use a polynomial approximation if you have a floating point unit; a degree 8 polynomial for sin(x) on the range [0, π/2] gets you to just about the limits of single precision floating point. If you only need about 4 digits of precision, you can use a degree 5 polynomial.
Couldn't you do better by only using the range [0, π/4] and noting that sin(x) = cos(x - π/2)?
Sure, then you can get away with an even smaller degree polynomial.
FWIW, Applesoft for the 6502 uses a 5th order poly.