diff options
Diffstat (limited to 'WebCore/platform/audio/Biquad.cpp')
-rw-r--r-- | WebCore/platform/audio/Biquad.cpp | 282 |
1 files changed, 0 insertions, 282 deletions
diff --git a/WebCore/platform/audio/Biquad.cpp b/WebCore/platform/audio/Biquad.cpp deleted file mode 100644 index 20143e3..0000000 --- a/WebCore/platform/audio/Biquad.cpp +++ /dev/null @@ -1,282 +0,0 @@ -/* - * Copyright (C) 2010 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" - -#if ENABLE(WEB_AUDIO) - -#include "Biquad.h" - -#include <algorithm> -#include <stdio.h> -#include <wtf/MathExtras.h> - -#if OS(DARWIN) -#include <Accelerate/Accelerate.h> -#endif - -namespace WebCore { - -const int kBufferSize = 1024; - -Biquad::Biquad() -{ -#if OS(DARWIN) - // Allocate two samples more for filter history - m_inputBuffer.resize(kBufferSize + 2); - m_outputBuffer.resize(kBufferSize + 2); -#endif - - // Initialize as pass-thru (straight-wire, no filter effect) - m_a0 = 1.0; - m_a1 = 0.0; - m_a2 = 0.0; - m_b1 = 0.0; - m_b2 = 0.0; - - m_g = 1.0; - - reset(); // clear filter memory -} - -void Biquad::process(const float* sourceP, float* destP, size_t framesToProcess) -{ -#if OS(DARWIN) - // Use vecLib if available - processFast(sourceP, destP, framesToProcess); -#else - int n = framesToProcess; - - // Create local copies of member variables - double x1 = m_x1; - double x2 = m_x2; - double y1 = m_y1; - double y2 = m_y2; - - double a0 = m_a0; - double a1 = m_a1; - double a2 = m_a2; - double b1 = m_b1; - double b2 = m_b2; - - while (n--) { - // FIXME: this can be optimized by pipelining the multiply adds... - float x = *sourceP++; - float y = a0*x + a1*x1 + a2*x2 - b1*y1 - b2*y2; - - y *= m_g; - - *destP++ = y; - - // Update state variables - x2 = x1; - x1 = x; - y2 = y1; - y1 = y; - } - - // Local variables back to member - m_x1 = x1; - m_x2 = x2; - m_y1 = y1; - m_y2 = y2; - - m_a0 = a0; - m_a1 = a1; - m_a2 = a2; - m_b1 = b1; - m_b2 = b2; -#endif -} - -#if OS(DARWIN) - -// Here we have optimized version using Accelerate.framework - -void Biquad::processFast(const float* sourceP, float* destP, size_t framesToProcess) -{ - // Filter coefficients - double B[5]; - B[0] = m_a0; - B[1] = m_a1; - B[2] = m_a2; - B[3] = m_b1; - B[4] = m_b2; - - double* inputP = m_inputBuffer.data(); - double* outputP = m_outputBuffer.data(); - - double* input2P = inputP + 2; - double* output2P = outputP + 2; - - // Break up processing into smaller slices (kBufferSize) if necessary. - - int n = framesToProcess; - - while (n > 0) { - int framesThisTime = n < kBufferSize ? n : kBufferSize; - - // Copy input to input buffer - for (int i = 0; i < framesThisTime; ++i) - input2P[i] = *sourceP++; - - processSliceFast(inputP, outputP, B, framesThisTime); - - // Copy output buffer to output (converts float -> double). - for (int i = 0; i < framesThisTime; ++i) - *destP++ = static_cast<float>(output2P[i]); - - n -= framesThisTime; - } -} - -void Biquad::processSliceFast(double* sourceP, double* destP, double* coefficientsP, size_t framesToProcess) -{ - // Use double-precision for filter stability - vDSP_deq22D(sourceP, 1, coefficientsP, destP, 1, framesToProcess); - - // Save history. Note that sourceP and destP reference m_inputBuffer and m_outputBuffer respectively. - // These buffers are allocated (in the constructor) with space for two extra samples so it's OK to access - // array values two beyond framesToProcess. - sourceP[0] = sourceP[framesToProcess - 2 + 2]; - sourceP[1] = sourceP[framesToProcess - 1 + 2]; - destP[0] = destP[framesToProcess - 2 + 2]; - destP[1] = destP[framesToProcess - 1 + 2]; -} - -#endif // OS(DARWIN) - - -void Biquad::reset() -{ - m_x1 = m_x2 = m_y1 = m_y2 = 0.0; - -#if OS(DARWIN) - // Two extra samples for filter history - double* inputP = m_inputBuffer.data(); - inputP[0] = 0.0; - inputP[1] = 0.0; - - double* outputP = m_outputBuffer.data(); - outputP[0] = 0.0; - outputP[1] = 0.0; -#endif -} - -void Biquad::setLowpassParams(double cutoff, double resonance) -{ - resonance = std::max(0.0, resonance); // can't go negative - - double g = pow(10.0, 0.05 * resonance); - double d = sqrt((4.0 - sqrt(16.0 - 16.0 / (g * g))) / 2.0); - - // Compute biquad coefficients for lopass filter - double theta = piDouble * cutoff; - double sn = 0.5 * d * sin(theta); - double beta = 0.5 * (1.0 - sn) / (1.0 + sn); - double gamma = (0.5 + beta) * cos(theta); - double alpha = 0.25 * (0.5 + beta - gamma); - - m_a0 = 2.0 * alpha; - m_a1 = 2.0 * 2.0*alpha; - m_a2 = 2.0 * alpha; - m_b1 = 2.0 * -gamma; - m_b2 = 2.0 * beta; -} - -void Biquad::setHighpassParams(double cutoff, double resonance) -{ - resonance = std::max(0.0, resonance); // can't go negative - - double g = pow(10.0, 0.05 * resonance); - double d = sqrt((4.0 - sqrt(16.0 - 16.0 / (g * g))) / 2.0); - - // Compute biquad coefficients for highpass filter - double theta = piDouble * cutoff; - double sn = 0.5 * d * sin(theta); - double beta = 0.5 * (1.0 - sn) / (1.0 + sn); - double gamma = (0.5 + beta) * cos(theta); - double alpha = 0.25 * (0.5 + beta + gamma); - - m_a0 = 2.0 * alpha; - m_a1 = 2.0 * -2.0*alpha; - m_a2 = 2.0 * alpha; - m_b1 = 2.0 * -gamma; - m_b2 = 2.0 * beta; -} - -void Biquad::setLowShelfParams(double cutoff, double dbGain) -{ - double theta = piDouble * cutoff; - - double A = pow(10.0, dbGain / 40.0); - double S = 1.0; // filter slope (1.0 is max value) - double alpha = 0.5 * sin(theta) * sqrt((A + 1.0 / A) * (1.0 / S - 1.0) + 2.0); - - double k = cos(theta); - double k2 = 2.0 * sqrt(A) * alpha; - - double b0 = A * ((A + 1.0) - (A - 1.0) * k + k2); - double b1 = 2.0 * A * ((A - 1.0) - (A + 1.0) * k); - double b2 = A * ((A + 1.0) - (A - 1.0) * k - k2); - double a0 = (A + 1.0) + (A - 1.0) * k + k2; - double a1 = -2.0 * ((A - 1.0) + (A + 1.0) * k); - double a2 = (A + 1.0) + (A - 1.0) * k - k2; - - double a0Inverse = 1.0 / a0; - - m_a0 = b0 * a0Inverse; - m_a1 = b1 * a0Inverse; - m_a2 = b2 * a0Inverse; - m_b1 = a1 * a0Inverse; - m_b2 = a2 * a0Inverse; -} - -void Biquad::setZeroPolePairs(const Complex &zero, const Complex &pole) -{ - m_a0 = 1.0; - m_a1 = -2.0 * zero.real(); - - double zeroMag = abs(zero); - m_a2 = zeroMag * zeroMag; - - m_b1 = -2.0 * pole.real(); - - double poleMag = abs(pole); - m_b2 = poleMag * poleMag; -} - -void Biquad::setAllpassPole(const Complex &pole) -{ - Complex zero = Complex(1.0, 0.0) / pole; - setZeroPolePairs(zero, pole); -} - -} // namespace WebCore - -#endif // ENABLE(WEB_AUDIO) |