Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(44)

Unified Diff: Source/modules/webaudio/PeriodicWave.cpp

Issue 66393004: Make triangle wave in an OscillatorNode match WebAudio spec. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « LayoutTests/webaudio/oscillator-triangle-expected.wav ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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;
}
« no previous file with comments | « LayoutTests/webaudio/oscillator-triangle-expected.wav ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698