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

Side by Side Diff: third_party/WebKit/Source/platform/audio/Biquad.cpp

Issue 1885723003: Implement Biquad lowpass and highpass filters according to spec (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase Created 4 years, 7 months 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
« no previous file with comments | « third_party/WebKit/LayoutTests/webaudio/resources/biquad-testing.js ('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) 2010 Google Inc. All rights reserved. 2 * Copyright (C) 2010 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 237 matching lines...) Expand 10 before | Expand all | Expand 10 after
248 // Limit cutoff to 0 to 1. 248 // Limit cutoff to 0 to 1.
249 cutoff = clampTo(cutoff, 0.0, 1.0); 249 cutoff = clampTo(cutoff, 0.0, 1.0);
250 250
251 if (cutoff == 1) { 251 if (cutoff == 1) {
252 // When cutoff is 1, the z-transform is 1. 252 // When cutoff is 1, the z-transform is 1.
253 setNormalizedCoefficients(index, 253 setNormalizedCoefficients(index,
254 1, 0, 0, 254 1, 0, 0,
255 1, 0, 0); 255 1, 0, 0);
256 } else if (cutoff > 0) { 256 } else if (cutoff > 0) {
257 // Compute biquad coefficients for lowpass filter 257 // Compute biquad coefficients for lowpass filter
258 resonance = std::max(0.0, resonance); // can't go negative
259 double g = pow(10.0, 0.05 * resonance);
260 double d = sqrt((4 - sqrt(16 - 16 / (g * g))) / 2);
261 258
259 resonance = pow(10, resonance / 20);
262 double theta = piDouble * cutoff; 260 double theta = piDouble * cutoff;
263 double sn = 0.5 * d * sin(theta); 261 double alpha = sin(theta) / (2 * resonance);
264 double beta = 0.5 * (1 - sn) / (1 + sn); 262 double cosw = cos(theta);
265 double gamma = (0.5 + beta) * cos(theta); 263 double beta = (1 - cosw) / 2;
266 double alpha = 0.25 * (0.5 + beta - gamma);
267 264
268 double b0 = 2 * alpha; 265 double b0 = beta;
269 double b1 = 2 * 2 * alpha; 266 double b1 = 2 * beta;
270 double b2 = 2 * alpha; 267 double b2 = beta;
271 double a1 = 2 * -gamma;
272 double a2 = 2 * beta;
273 268
274 setNormalizedCoefficients(index, b0, b1, b2, 1, a1, a2); 269 double a0 = 1 + alpha;
270 double a1 = -2 * cosw;
271 double a2 = 1 - alpha;
272
273 setNormalizedCoefficients(index, b0, b1, b2, a0, a1, a2);
275 } else { 274 } else {
276 // When cutoff is zero, nothing gets through the filter, so set 275 // When cutoff is zero, nothing gets through the filter, so set
277 // coefficients up correctly. 276 // coefficients up correctly.
278 setNormalizedCoefficients(index, 277 setNormalizedCoefficients(index,
279 0, 0, 0, 278 0, 0, 0,
280 1, 0, 0); 279 1, 0, 0);
281 } 280 }
282 } 281 }
283 282
284 void Biquad::setHighpassParams(int index, double cutoff, double resonance) 283 void Biquad::setHighpassParams(int index, double cutoff, double resonance)
285 { 284 {
286 // Limit cutoff to 0 to 1. 285 // Limit cutoff to 0 to 1.
287 cutoff = clampTo(cutoff, 0.0, 1.0); 286 cutoff = clampTo(cutoff, 0.0, 1.0);
288 287
289 if (cutoff == 1) { 288 if (cutoff == 1) {
290 // The z-transform is 0. 289 // The z-transform is 0.
291 setNormalizedCoefficients(index, 290 setNormalizedCoefficients(index,
292 0, 0, 0, 291 0, 0, 0,
293 1, 0, 0); 292 1, 0, 0);
294 } else if (cutoff > 0) { 293 } else if (cutoff > 0) {
295 // Compute biquad coefficients for highpass filter 294 // Compute biquad coefficients for highpass filter
296 resonance = std::max(0.0, resonance); // can't go negative
297 double g = pow(10.0, 0.05 * resonance);
298 double d = sqrt((4 - sqrt(16 - 16 / (g * g))) / 2);
299 295
296 resonance = pow(10, resonance / 20);
300 double theta = piDouble * cutoff; 297 double theta = piDouble * cutoff;
301 double sn = 0.5 * d * sin(theta); 298 double alpha = sin(theta) / (2 * resonance);
302 double beta = 0.5 * (1 - sn) / (1 + sn); 299 double cosw = cos(theta);
303 double gamma = (0.5 + beta) * cos(theta); 300 double beta = (1 + cosw) / 2;
304 double alpha = 0.25 * (0.5 + beta + gamma);
305 301
306 double b0 = 2 * alpha; 302 double b0 = beta;
307 double b1 = 2 * -2 * alpha; 303 double b1 = -2 * beta;
308 double b2 = 2 * alpha; 304 double b2 = beta;
309 double a1 = 2 * -gamma;
310 double a2 = 2 * beta;
311 305
312 setNormalizedCoefficients(index, b0, b1, b2, 1, a1, a2); 306 double a0 = 1 + alpha;
307 double a1 = -2 * cosw;
308 double a2 = 1 - alpha;
309
310 setNormalizedCoefficients(index, b0, b1, b2, a0, a1, a2);
313 } else { 311 } else {
314 // When cutoff is zero, we need to be careful because the above 312 // When cutoff is zero, we need to be careful because the above
315 // gives a quadratic divided by the same quadratic, with poles 313 // gives a quadratic divided by the same quadratic, with poles
316 // and zeros on the unit circle in the same place. When cutoff 314 // and zeros on the unit circle in the same place. When cutoff
317 // is zero, the z-transform is 1. 315 // is zero, the z-transform is 1.
318 setNormalizedCoefficients(index, 316 setNormalizedCoefficients(index,
319 1, 0, 0, 317 1, 0, 0,
320 1, 0, 0); 318 1, 0, 0);
321 } 319 }
322 } 320 }
(...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after
609 std::complex<double> denominator = 607 std::complex<double> denominator =
610 std::complex<double>(1, 0) + (a1 + a2 * z) * z; 608 std::complex<double>(1, 0) + (a1 + a2 * z) * z;
611 std::complex<double> response = numerator / denominator; 609 std::complex<double> response = numerator / denominator;
612 magResponse[k] = static_cast<float>(abs(response)); 610 magResponse[k] = static_cast<float>(abs(response));
613 phaseResponse[k] = static_cast<float>(atan2(imag(response), real(respons e))); 611 phaseResponse[k] = static_cast<float>(atan2(imag(response), real(respons e)));
614 } 612 }
615 } 613 }
616 614
617 } // namespace blink 615 } // namespace blink
618 616
OLDNEW
« no previous file with comments | « third_party/WebKit/LayoutTests/webaudio/resources/biquad-testing.js ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698