DEV Community

Shinya Kitaoka
Shinya Kitaoka

Posted on

Pulse wave in WebAudio

PeriodicWave

We can define OscillatorNode for any periodic function f(t), defined by the domain [0, 2π), using PeriodicWave:

const ω = new OscillatorNode(
    audioContext,
    {
        type: "custom",
        frequency: frequency,
        periodicWave: new PeriodicWave(
            audioContext,
            {real: a, imag: b}
        ),
    }
);
Enter fullscreen mode Exit fullscreen mode

where a and b are Float32Arrays initialized by

a0=12π02πf(t)dt,b0=0, \begin{aligned} a_{0} &= \frac{1}{2\pi}\int_{0}^{2 \pi} f(t) dt, \\ b_{0} &= 0, \\ \end{aligned}
an=1π02πf(t)cos(nt)dt,bn=1π02πf(t)sin(nt)dt. \begin{aligned} a_{n} &= \frac{1}{\pi}\int_{0}^{2 \pi} f(t) \cos(n t) dt, \\ b_{n} &= \frac{1}{\pi}\int_{0}^{2 \pi} f(t) \sin(n t) dt. \end{aligned}

Pulse Wave

Pulse wave with duty ratio r:1-r is defined

f(t)={1,πrt<π(2r),1,otherwise. f(t) = \left\{\begin{array}{rc} -1, & \pi r \leq t < \pi (2 - r), \\ 1, & \mathrm{otherwise}. \end{array}\right.

Coefficients a and b for the wave are

a0=2r1,an=4rsinc(nr)σn,bn=0, \begin{aligned} a_{0} &= 2 r - 1, \\ a_{n} &= 4 r \mathrm{sinc}(n r) \sigma_{n}, \\ b_{n} &= 0, \end{aligned}

where

sinc(x)=sin(πx)πx, \mathrm{sinc}(x) = \frac{\sin(\pi x)}{\pi x},

and σ is additional coefficient for removing ringing artifacts:

σn=NnN+1cos(nπN+1)+1N+1sin((n+1)πN+1)sin(πN+1), \sigma_{n} = \frac{N - n}{N + 1} \cos\left(n \frac{\pi}{N + 1}\right) + \frac{1}{N + 1} \frac{\sin\left((n + 1) \frac{\pi}{N + 1}\right)}{\sin\left(\frac{\pi}{N + 1}\right)},

and N is the length of Float32Array.

sinc function

We define sinc function for numerical stability:

function sinc(x) {
    const πx = Math.PI * x;
    if (Math.abs(x) < 1e-9) {
        // Taylor series centered at x=0
        const πx_sq = πx * πx;
        return (
            1 - (
                1 - (
                    1 - πx_sq / 42
                ) * πx_sq / 20
            ) * πx_sq / 6
        );
    } else {
        return Math.sin(πx) / (πx);
    }
}
Enter fullscreen mode Exit fullscreen mode

Top comments (0)