Taylor Oscillator Algorithm

An idea I had in the context of my Flues synth experiments. I'd already got a bunch of fairly novel algorithms I've called Disyn that I found in some academic material. These I've implemented in a few forms : live on the Web, lv2 plugin and headless for the Raspberry Pi.

This morning I thought of another to try. I've implemented it in the Web & raspi versions (links above), it is quite good. I can't really claim it as my own because it's a certainty that the Taylor series has been used for approximation of a sine wave in a synth before. My only innovation, if you can call it that, is intentionally using the bad approximations, just the first few terms.

If you want some maths homework, figure out what the Fourier transform of the equations will be. The first term is x and there's wrap around so the crunchiest wave will be a simple sawtooth (maybe clipped in implementation). But next..?

Principle: Generates waveforms using truncated Taylor series expansion of sine functions. By controlling the number of terms, the algorithm produces everything from rough aliased approximations (few terms) to smooth sinusoids (many terms). Blends fundamental and second harmonic for timbral variation.

Mathematical Basis: The Taylor series for sine around x=0:

sin(x) = x - x³/3! + x⁵/5! - x⁷/7! + x⁹/9! - ...
       = Σ(n=0 to ∞) [(-1)ⁿ × x^(2n+1) / (2n+1)!]

Algorithm:

// Wrap angles to [-π, π] for convergence
θ₁ = wrap(2π × phase)
θ₂ = wrap(2 × θ₁)

// Compute truncated Taylor series (iterative)
fundamental = taylor_sine(θ₁, firstTerms)
second_harmonic = taylor_sine(θ₂, secondTerms)

// Blend outputs
s(t) = fundamental × (1-blend) + second_harmonic × blend

Iterative Computation:

float taylor_sine(float x, int num_terms) {
    float wrapped = wrap_angle(x);  // [-π, π]
    float result = 0.0f;
    float term = wrapped;
    float x_squared = wrapped * wrapped;

    for (int n = 0; n < num_terms; n++) {
        result += term;
        // Next term: multiply by -x²/((2n+2)(2n+3))
        float denom = (2*n + 2) * (2*n + 3);
        term *= -x_squared / denom;
    }

    // Clamp to prevent runaway values
    return fmaxf(-1.5f, fminf(1.5f, result));
}

Parameters:

Implementation Notes:

Convergence Behavior:

Spectral Characteristics:

Use Cases: