michael@0: /* michael@0: * Copyright (C) 2010 Google Inc. All rights reserved. michael@0: * michael@0: * Redistribution and use in source and binary forms, with or without michael@0: * modification, are permitted provided that the following conditions michael@0: * are met: michael@0: * michael@0: * 1. Redistributions of source code must retain the above copyright michael@0: * notice, this list of conditions and the following disclaimer. michael@0: * 2. Redistributions in binary form must reproduce the above copyright michael@0: * notice, this list of conditions and the following disclaimer in the michael@0: * documentation and/or other materials provided with the distribution. michael@0: * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of michael@0: * its contributors may be used to endorse or promote products derived michael@0: * from this software without specific prior written permission. michael@0: * michael@0: * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY michael@0: * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED michael@0: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE michael@0: * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY michael@0: * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES michael@0: * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; michael@0: * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND michael@0: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT michael@0: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF michael@0: * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. michael@0: */ michael@0: michael@0: #ifndef Biquad_h michael@0: #define Biquad_h michael@0: michael@0: #include michael@0: michael@0: namespace WebCore { michael@0: michael@0: typedef std::complex Complex; michael@0: michael@0: // A basic biquad (two-zero / two-pole digital filter) michael@0: // michael@0: // It can be configured to a number of common and very useful filters: michael@0: // lowpass, highpass, shelving, parameteric, notch, allpass, ... michael@0: michael@0: class Biquad { michael@0: public: michael@0: Biquad(); michael@0: ~Biquad(); michael@0: michael@0: void process(const float* sourceP, float* destP, size_t framesToProcess); michael@0: michael@0: // frequency is 0 - 1 normalized, resonance and dbGain are in decibels. michael@0: // Q is a unitless quality factor. michael@0: void setLowpassParams(double frequency, double resonance); michael@0: void setHighpassParams(double frequency, double resonance); michael@0: void setBandpassParams(double frequency, double Q); michael@0: void setLowShelfParams(double frequency, double dbGain); michael@0: void setHighShelfParams(double frequency, double dbGain); michael@0: void setPeakingParams(double frequency, double Q, double dbGain); michael@0: void setAllpassParams(double frequency, double Q); michael@0: void setNotchParams(double frequency, double Q); michael@0: michael@0: // Set the biquad coefficients given a single zero (other zero will be conjugate) michael@0: // and a single pole (other pole will be conjugate) michael@0: void setZeroPolePairs(const Complex& zero, const Complex& pole); michael@0: michael@0: // Set the biquad coefficients given a single pole (other pole will be conjugate) michael@0: // (The zeroes will be the inverse of the poles) michael@0: void setAllpassPole(const Complex& pole); michael@0: michael@0: // Return true iff the next output block will contain sound even with michael@0: // silent input. michael@0: bool hasTail() const { return m_y1 || m_y2 || m_x1 || m_x2; } michael@0: michael@0: // Resets filter state michael@0: void reset(); michael@0: michael@0: // Filter response at a set of n frequencies. The magnitude and michael@0: // phase response are returned in magResponse and phaseResponse. michael@0: // The phase response is in radians. michael@0: void getFrequencyResponse(int nFrequencies, michael@0: const float* frequency, michael@0: float* magResponse, michael@0: float* phaseResponse); michael@0: private: michael@0: void setNormalizedCoefficients(double b0, double b1, double b2, double a0, double a1, double a2); michael@0: michael@0: // Filter coefficients. The filter is defined as michael@0: // michael@0: // y[n] + m_a1*y[n-1] + m_a2*y[n-2] = m_b0*x[n] + m_b1*x[n-1] + m_b2*x[n-2]. michael@0: double m_b0; michael@0: double m_b1; michael@0: double m_b2; michael@0: double m_a1; michael@0: double m_a2; michael@0: michael@0: // Filter memory michael@0: // michael@0: // Double precision for the output values is valuable because errors can michael@0: // accumulate. Input values are also stored as double so they need not be michael@0: // converted again for computation. michael@0: double m_x1; // input delayed by 1 sample michael@0: double m_x2; // input delayed by 2 samples michael@0: double m_y1; // output delayed by 1 sample michael@0: double m_y2; // output delayed by 2 samples michael@0: }; michael@0: michael@0: } // namespace WebCore michael@0: michael@0: #endif // Biquad_h