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

Side by Side 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « LayoutTests/webaudio/oscillator-triangle-expected.wav ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2012 Google Inc. All rights reserved. 2 * Copyright (C) 2012 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
6 * are met: 6 * are met:
7 * 7 *
8 * 1. Redistributions of source code must retain the above copyright 8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after
227 AudioFloatArray real(halfSize); 227 AudioFloatArray real(halfSize);
228 AudioFloatArray imag(halfSize); 228 AudioFloatArray imag(halfSize);
229 float* realP = real.data(); 229 float* realP = real.data();
230 float* imagP = imag.data(); 230 float* imagP = imag.data();
231 231
232 // Clear DC and Nyquist. 232 // Clear DC and Nyquist.
233 realP[0] = 0; 233 realP[0] = 0;
234 imagP[0] = 0; 234 imagP[0] = 0;
235 235
236 for (unsigned n = 1; n < halfSize; ++n) { 236 for (unsigned n = 1; n < halfSize; ++n) {
237 float omega = 2 * piFloat * n; 237 float piFactor = 2 / (n * piFloat);
238 float invOmega = 1 / omega;
239 238
240 // Fourier coefficients according to standard definition. 239 // All waveforms are odd functions with a positive slope at time 0. Henc e the coefficients
241 float a; // Coefficient for cos(). 240 // for cos() are always 0.
241
242 // Fourier coefficients according to standard definition:
243 // b = 1/pi*integrate(f(x)*sin(n*x), x, -pi, pi)
244 // = 2/pi*integrate(f(x)*sin(n*x), x, 0, pi)
245 // since f(x) is an odd function.
246
242 float b; // Coefficient for sin(). 247 float b; // Coefficient for sin().
243 248
244 // Calculate Fourier coefficients depending on the shape. 249 // Calculate Fourier coefficients depending on the shape. Note that the overall scaling
245 // Note that the overall scaling (magnitude) of the waveforms is normali zed in createBandLimitedTables(). 250 // (magnitude) of the waveforms is normalized in createBandLimitedTables ().
246 switch (shape) { 251 switch (shape) {
247 case OscillatorNode::SINE: 252 case OscillatorNode::SINE:
248 // Standard sine wave function. 253 // Standard sine wave function.
249 a = 0;
250 b = (n == 1) ? 1 : 0; 254 b = (n == 1) ? 1 : 0;
251 break; 255 break;
252 case OscillatorNode::SQUARE: 256 case OscillatorNode::SQUARE:
253 // Square-shaped waveform with the first half its maximum value and the second half its minimum value. 257 // Square-shaped waveform with the first half its maximum value and the second half its
254 a = 0; 258 // minimum value.
255 b = invOmega * ((n & 1) ? 2 : 0); 259 //
260 // See http://mathworld.wolfram.com/FourierSeriesSquareWave.html
261 //
262 // b[n] = 2/n/pi*(1-(-1)^n)
263 // = 4/n/pi for n odd and 0 otherwise.
264 // = 2*(2/(n*pi)) for n odd
265 b = (n & 1) ? 2 * piFactor : 0;
256 break; 266 break;
257 case OscillatorNode::SAWTOOTH: 267 case OscillatorNode::SAWTOOTH:
258 // Sawtooth-shaped waveform with the first half ramping from zero to maximum and the second half from minimum to zero. 268 // Sawtooth-shaped waveform with the first half ramping from zero to maximum and the
259 a = 0; 269 // second half from minimum to zero.
260 b = -invOmega * cos(0.5 * omega); 270 //
271 // b[n] = -2*(-1)^n/pi/n
272 // = (2/(n*pi))*(-1)^(n+1)
273 b = piFactor * ((n & 1) ? 1 : -1);
261 break; 274 break;
262 case OscillatorNode::TRIANGLE: 275 case OscillatorNode::TRIANGLE:
263 // Triangle-shaped waveform going from its maximum value to its mini mum value then back to the maximum value. 276 // Triangle-shaped waveform going from 0 at time 0 to 1 at time pi/2 and back to 0 at
264 a = (4 - 4 * cos(0.5 * omega)) / (n * n * piFloat * piFloat); 277 // time pi.
265 b = 0; 278 //
279 // See http://mathworld.wolfram.com/FourierSeriesTriangleWave.html
280 //
281 // b[n] = 8*sin(pi*k/2)/(pi*k)^2
282 // = 8/pi^2/n^2*(-1)^((n-1)/2) for n odd and 0 otherwise
283 // = 2*(2/(n*pi))^2 * (-1)^((n-1)/2)
284 if (n & 1) {
285 b = 2 * (piFactor * piFactor) * ((((n - 1) >> 1) & 1) ? -1 : 1);
286 } else {
287 b = 0;
288 }
266 break; 289 break;
267 default: 290 default:
268 ASSERT_NOT_REACHED(); 291 ASSERT_NOT_REACHED();
269 a = 0;
270 b = 0; 292 b = 0;
271 break; 293 break;
272 } 294 }
273 295
274 realP[n] = a; 296 realP[n] = 0;
275 imagP[n] = b; 297 imagP[n] = b;
276 } 298 }
277 299
278 createBandLimitedTables(realP, imagP, halfSize); 300 createBandLimitedTables(realP, imagP, halfSize);
279 } 301 }
280 302
281 } // namespace WebCore 303 } // namespace WebCore
282 304
283 #endif // ENABLE(WEB_AUDIO) 305 #endif // ENABLE(WEB_AUDIO)
OLDNEW
« 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