| Index: Source/modules/webaudio/PeriodicWave.cpp
|
| diff --git a/Source/modules/webaudio/PeriodicWave.cpp b/Source/modules/webaudio/PeriodicWave.cpp
|
| index 48498c63a0d2447ff3d4b8036b2c28d35048fc12..28b7a24dc191e1becbd8f52a08ae58bca29b33da 100644
|
| --- a/Source/modules/webaudio/PeriodicWave.cpp
|
| +++ b/Source/modules/webaudio/PeriodicWave.cpp
|
| @@ -234,44 +234,66 @@ void PeriodicWave::generateBasicWaveform(int shape)
|
| imagP[0] = 0;
|
|
|
| for (unsigned n = 1; n < halfSize; ++n) {
|
| - float omega = 2 * piFloat * n;
|
| - float invOmega = 1 / omega;
|
| + float piFactor = 2 / (n * piFloat);
|
| +
|
| + // All waveforms are odd functions with a positive slope at time 0. Hence the coefficients
|
| + // for cos() are always 0.
|
| +
|
| + // Fourier coefficients according to standard definition:
|
| + // b = 1/pi*integrate(f(x)*sin(n*x), x, -pi, pi)
|
| + // = 2/pi*integrate(f(x)*sin(n*x), x, 0, pi)
|
| + // since f(x) is an odd function.
|
|
|
| - // Fourier coefficients according to standard definition.
|
| - float a; // Coefficient for cos().
|
| float b; // Coefficient for sin().
|
|
|
| - // Calculate Fourier coefficients depending on the shape.
|
| - // Note that the overall scaling (magnitude) of the waveforms is normalized in createBandLimitedTables().
|
| + // Calculate Fourier coefficients depending on the shape. Note that the overall scaling
|
| + // (magnitude) of the waveforms is normalized in createBandLimitedTables().
|
| switch (shape) {
|
| case OscillatorNode::SINE:
|
| // Standard sine wave function.
|
| - a = 0;
|
| b = (n == 1) ? 1 : 0;
|
| break;
|
| case OscillatorNode::SQUARE:
|
| - // Square-shaped waveform with the first half its maximum value and the second half its minimum value.
|
| - a = 0;
|
| - b = invOmega * ((n & 1) ? 2 : 0);
|
| + // Square-shaped waveform with the first half its maximum value and the second half its
|
| + // minimum value.
|
| + //
|
| + // See http://mathworld.wolfram.com/FourierSeriesSquareWave.html
|
| + //
|
| + // b[n] = 2/n/pi*(1-(-1)^n)
|
| + // = 4/n/pi for n odd and 0 otherwise.
|
| + // = 2*(2/(n*pi)) for n odd
|
| + b = (n & 1) ? 2 * piFactor : 0;
|
| break;
|
| case OscillatorNode::SAWTOOTH:
|
| - // Sawtooth-shaped waveform with the first half ramping from zero to maximum and the second half from minimum to zero.
|
| - a = 0;
|
| - b = -invOmega * cos(0.5 * omega);
|
| + // Sawtooth-shaped waveform with the first half ramping from zero to maximum and the
|
| + // second half from minimum to zero.
|
| + //
|
| + // b[n] = -2*(-1)^n/pi/n
|
| + // = (2/(n*pi))*(-1)^(n+1)
|
| + b = piFactor * ((n & 1) ? 1 : -1);
|
| break;
|
| case OscillatorNode::TRIANGLE:
|
| - // Triangle-shaped waveform going from its maximum value to its minimum value then back to the maximum value.
|
| - a = (4 - 4 * cos(0.5 * omega)) / (n * n * piFloat * piFloat);
|
| - b = 0;
|
| + // Triangle-shaped waveform going from 0 at time 0 to 1 at time pi/2 and back to 0 at
|
| + // time pi.
|
| + //
|
| + // See http://mathworld.wolfram.com/FourierSeriesTriangleWave.html
|
| + //
|
| + // b[n] = 8*sin(pi*k/2)/(pi*k)^2
|
| + // = 8/pi^2/n^2*(-1)^((n-1)/2) for n odd and 0 otherwise
|
| + // = 2*(2/(n*pi))^2 * (-1)^((n-1)/2)
|
| + if (n & 1) {
|
| + b = 2 * (piFactor * piFactor) * ((((n - 1) >> 1) & 1) ? -1 : 1);
|
| + } else {
|
| + b = 0;
|
| + }
|
| break;
|
| default:
|
| ASSERT_NOT_REACHED();
|
| - a = 0;
|
| b = 0;
|
| break;
|
| }
|
|
|
| - realP[n] = a;
|
| + realP[n] = 0;
|
| imagP[n] = b;
|
| }
|
|
|
|
|