Overview
This article presents 10 methods for generating sine waves in software, ranging from simple library calls to highly optimized recursive algorithms. The goal is to find the fastest approach for a given hardware, from floating-point FPUs to bare 8-bit microcontrollers.
1. Math Library — sin(x)
The simplest approach: call the library function. Fast to write, but the slowest to execute on hardware without a dedicated FPU or co-processor.
y = sin(x); // x in radians
2. Table Look-up
Pre-compute and store sine values in a table, exploiting the four-fold symmetry of the sine function to reduce memory by 4×:
float sine[91], pi = 3.141592653;
for(int i = 0; i <= 90; i++)
sine[i] = sin(pi/180 * i);
// Accessing all quadrants using symmetry:
y = sine[x]; // 0° ≤ x ≤ 90°
y = sine[180 - x]; // 90° ≤ x ≤ 180°
y = -sine[x - 180]; // 180° ≤ x ≤ 270°
y = -sine[360 - x]; // 270° ≤ x ≤ 360°
3. Table Look-up + Linear Interpolation
Increase effective resolution without enlarging the table by interpolating between adjacent entries:
The maximum relative error for a table of N samples:
For N = 256: error ≈ 0.03%. For N = 23: error < 1%. In practice, N = 32 (one quadrant) provides excellent accuracy.
4. Trigonometric Identity Method
Generate a sequence of equally-spaced sine values using the angle addition formulas. Given starting angle \(a\) and step \(b\):
s1 = sin(a); c1 = cos(a);
sd = sin(b); cd = cos(b); // Precomputed constants
for(i = 0; i < N; i++) {
temp = s1*cd + c1*sd; // sin(a + i*b)
c1 = c1*cd - s1*sd; // cos(a + i*b)
s1 = temp;
} // 4 multiplications + 2 additions per step
5. Goertzel Algorithm (Most Efficient for Sine Only)
Requires only one multiplication per step by using a second-order recurrence:
Derivation: setting \(x = -1\), \(y = 2\cos(b)\) in the recurrence gives:
c = 2 * cos(b);
s0 = sin(a + b);
s1 = sin(a + 2*b);
for(i = 0; i < N; i++) {
s = c * s1 - s0; // 1 multiply + 1 subtract
s0 = s1;
s1 = s;
}
6. Taylor Series
The Taylor series around \(x = 0\):
Using Horner's rule for efficient evaluation (avoids computing high powers of x):
7. Padé Rational Approximation
A rational function (ratio of two polynomials) that matches the Taylor series to higher order with fewer terms:
Coefficients (Padé [6/6]):
| Numerator | Value | Denominator | Value |
|---|---|---|---|
| n₁ | −325523/2283996 | d₁ | 18381/761332 |
| n₂ | 34911/7613320 | d₂ | 1261/4567992 |
| n₃ | 479249/11511339840 | d₃ | 2623/1644477120 |
Method Comparison
| Method | Multiplies/sample | Memory | Best for |
|---|---|---|---|
| Library sin() | ~many | — | Computers with FPU |
| Table lookup | 0 | High | Fast MCUs with Flash |
| Table + interpolation | 1–2 | Low | Accuracy + speed balance |
| Trig identity | 4 | Very low | Consecutive samples |
| Goertzel | 1 | Very low | 8-bit MCUs, consecutive |
| Taylor series | 3–5 | Very low | Arbitrary angles |
| Padé | 6–8 | Low | High accuracy, FPU |