1135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent/* //device/include/server/AudioFlinger/AudioPeakingFilter.h 2135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent** 3135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent** Copyright 2009, The Android Open Source Project 4135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent** 5135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent** Licensed under the Apache License, Version 2.0 (the "License"); 6135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent** you may not use this file except in compliance with the License. 7135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent** You may obtain a copy of the License at 8135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent** 9135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent** http://www.apache.org/licenses/LICENSE-2.0 10135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent** 11135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent** Unless required by applicable law or agreed to in writing, software 12135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent** distributed under the License is distributed on an "AS IS" BASIS, 13135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent** See the License for the specific language governing permissions and 15135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent** limitations under the License. 16135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent*/ 17135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 18135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent#ifndef ANDROID_AUDIO_PEAKING_FILTER_H 19135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent#define ANDROID_AUDIO_PEAKING_FILTER_H 20135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 21135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent#include "AudioBiquadFilter.h" 22135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent#include "AudioCoefInterpolator.h" 23135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 24135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentnamespace android { 25135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 26135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent// A peaking audio filter, with unity skirt gain, and controllable peak 27135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent// frequency, gain and bandwidth. 28135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent// This filter is able to suppress introduce discontinuities and other artifacts 29135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent// in the output, even when changing parameters abruptly. 30135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent// Parameters can be set to any value - this class will make sure to clip them 31135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent// when they are out of supported range. 32135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent// 33135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent// Implementation notes: 34135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent// This class uses an underlying biquad filter whose parameters are determined 35135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent// using a linear interpolation from a coefficient table, using a 36135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent// AudioCoefInterpolator. 37135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent// All is left for this class to do is mapping between high-level parameters to 38135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent// fractional indices into the coefficient table. 39135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentclass AudioPeakingFilter { 40135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentpublic: 41135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // Constructor. Resets the filter (see reset()). 42135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // nChannels Number of input/output channels (interlaced). 43135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // sampleRate The input/output sample rate, in Hz. 44135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent AudioPeakingFilter(int nChannels, int sampleRate); 45135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 46135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // Reconfiguration of the filter. Changes input/output format, but does not 47135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // alter current parameter values. Clears delay lines. 48135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // nChannels Number of input/output channels (interlaced). 49135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // sampleRate The input/output sample rate, in Hz. 50135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent void configure(int nChannels, int sampleRate); 51135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 52135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // Resets the filter parameters to the following values: 53135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // frequency: 0 54135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // gain: 0 55135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // bandwidth: 1200 cents. 56135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // It also disables the filter. Does not clear the delay lines. 57135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent void reset(); 58135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 59135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // Clears delay lines. Does not alter parameter values. 60135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent void clear() { mBiquad.clear(); } 61135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 62135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // Sets gain value. Actual change will only take place upon commit(). 63135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // This value will be remembered even if the filter is in disabled() state. 64135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // millibel Gain value in millibel (1/100 of decibel). 65135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent void setGain(int32_t millibel); 66135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 67135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // Gets the gain, in millibel, as set. 68135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent int32_t getGain() const { return mGain - 9600; } 69135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 70135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // Sets bandwidth value. Actual change will only take place upon commit(). 71135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // This value will be remembered even if the filter is in disabled() state. 72135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // cents Bandwidth value in cents (1/1200 octave). 73135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent void setBandwidth(uint32_t cents); 74135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 75135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // Gets the gain, in cents, as set. 76135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent uint32_t getBandwidth() const { return mBandwidth + 1; } 77135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 78135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // Sets frequency value. Actual change will only take place upon commit(). 79135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // This value will be remembered even if the filter is in disabled() state. 80135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // millihertz Frequency value in mHz. 81135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent void setFrequency(uint32_t millihertz); 82135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 83135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // Gets the frequency, in mHz, as set. 84135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent uint32_t getFrequency() const { return mNominalFrequency; } 85135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 86135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // Gets gain[dB]/2 points. 87135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // Results in mHz, and are computed based on the nominal values set, not on 88135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // possibly rounded or truncated actual values. 89135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent void getBandRange(uint32_t & low, uint32_t & high) const; 90135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 91135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // Applies all parameter changes done to this point in time. 92135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // If the filter is disabled, the new parameters will take place when it is 93135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // enabled again. Does not introduce artifacts, unless immediate is set. 94135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // immediate Whether to apply change abruptly (ignored if filter is 95135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // disabled). 96135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent void commit(bool immediate = false); 97135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 98135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // Process a buffer of input data. The input and output should contain 99135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // frameCount * nChannels interlaced samples. Processing can be done 100135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // in-place, by passing the same buffer as both arguments. 101135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // in Input buffer. 102135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // out Output buffer. 103135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // frameCount Number of frames to produce. 104135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent void process(const audio_sample_t in[], audio_sample_t out[], 105135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent int frameCount) { mBiquad.process(in, out, frameCount); } 106135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 107135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // Enables the filter, so it would start processing input. Does not 108135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // introduce artifacts, unless immediate is set. 109135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // immediate Whether to apply change abruptly. 110135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent void enable(bool immediate = false) { mBiquad.enable(immediate); } 111135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 112135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // Disabled (bypasses) the filter. Does not introduce artifacts, unless 113135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // immediate is set. 114135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // immediate Whether to apply change abruptly. 115135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent void disable(bool immediate = false) { mBiquad.disable(immediate); } 116135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 117135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentprivate: 118135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // Precision for the mFrequency member. 119135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent static const int FREQ_PRECISION_BITS = 26; 120135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // Precision for the mGain member. 121135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent static const int GAIN_PRECISION_BITS = 10; 122135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // Precision for the mBandwidth member. 123135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent static const int BANDWIDTH_PRECISION_BITS = 10; 124135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 125135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // Nyquist, in mHz. 126135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent uint32_t mNiquistFreq; 127135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // Fractional index into the gain dimension of the coef table in 128135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // GAIN_PRECISION_BITS precision. 129135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent int32_t mGain; 130135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // Fractional index into the bandwidth dimension of the coef table in 131135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // BANDWIDTH_PRECISION_BITS precision. 132135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent uint32_t mBandwidth; 133135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // Fractional index into the frequency dimension of the coef table in 134135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // FREQ_PRECISION_BITS precision. 135135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent uint32_t mFrequency; 136135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // Nominal value of frequency, as set. 137135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent uint32_t mNominalFrequency; 138135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // 1/Nyquist[mHz], in 42-bit precision (very small). 139135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // Used for scaling the frequency. 140135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent uint32_t mFrequencyFactor; 141135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 142135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // A biquad filter, used for the actual processing. 143135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent AudioBiquadFilter mBiquad; 144135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // A coefficient interpolator, used for mapping the high level parameters to 145135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // the low-level biquad coefficients. 146135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent static AudioCoefInterpolator mCoefInterp; 147135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}; 148135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 149135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent} 150135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 151135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent#endif // ANDROID_AUDIO_PEAKING_FILTER_H 152