1 /* //device/include/server/AudioFlinger/AudioBiquadFilter.h 2 ** 3 ** Copyright 2007, The Android Open Source Project 4 ** 5 ** Licensed under the Apache License, Version 2.0 (the "License"); 6 ** you may not use this file except in compliance with the License. 7 ** You may obtain a copy of the License at 8 ** 9 ** http://www.apache.org/licenses/LICENSE-2.0 10 ** 11 ** Unless required by applicable law or agreed to in writing, software 12 ** distributed under the License is distributed on an "AS IS" BASIS, 13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 ** See the License for the specific language governing permissions and 15 ** limitations under the License. 16 */ 17 18 #ifndef ANDROID_AUDIO_BIQUAD_FILTER_H 19 #define ANDROID_AUDIO_BIQUAD_FILTER_H 20 21 #include "AudioCommon.h" 22 23 namespace android { 24 // A biquad filter. 25 // Implements the recursion y[n]=a0*y[n-1]+a1*y[n-2]+b0*x[n]+b1*x[n-1]+b2*x[n-2] 26 // (the a0 and a1 coefficients have an opposite sign to the common convention) 27 // The filter works on fixed sized blocks of data (frameCount multi-channel 28 // samples, as defined during construction). An arbitrary number of interlaced 29 // channels is supported. 30 // Filter can operate in an enabled (active) or disabled (bypassed) states. 31 // A mechanism for suppression of artifacts caused by abrupt coefficient changes 32 // is implemented: normally, when the enable(), disable() and setCoefs() methods 33 // are called without the immediate flag set, the filter smoothly transitions 34 // from its current state to the desired state. 35 class AudioBiquadFilter { 36 public: 37 // Max number of channels (can be changed here, and everything should work). 38 static const int MAX_CHANNELS = 2; 39 // Number of coefficients. 40 static const int NUM_COEFS = 5; 41 42 // Constructor. 43 // nChannels Number of input/output channels. 44 // sampleRate Sample rate, in Hz. 45 AudioBiquadFilter(int nChannels, int sampleRate); 46 47 // Reconfiguration of the filter. Implies clear(). 48 // nChannels Number of input/output channels. 49 // sampleRate Sample rate, in Hz. 50 void configure(int nChannels, int sampleRate); 51 52 // Resets the internal state of the filter. 53 // Coefficients are reset to identity, state becomes disabled. This change 54 // happens immediately and might cause discontinuities in the output. 55 // Delay lines are not cleared. 56 void reset(); 57 58 // Clears the delay lines. 59 // This change happens immediately and might cause discontinuities in the 60 // output. 61 void clear(); 62 63 // Sets the coefficients. 64 // If called when filter is disabled, will have no immediate effect, but the 65 // new coefficients will be set and used next time the filter is enabled. 66 // coefs The new coefficients. 67 // immediate If true, transitions to new coefficients smoothly, without 68 // introducing discontinuities in the output. Otherwise, 69 // transitions immediately. 70 void setCoefs(const audio_coef_t coefs[NUM_COEFS], bool immediate = false); 71 72 // Process a buffer of data. Always processes frameCount multi-channel 73 // samples. Processing can be done in-place, by passing the same buffer as 74 // both arguments. 75 // in The input buffer. Should be of size frameCount * nChannels. 76 // out The output buffer. Should be of size frameCount * nChannels. 77 // frameCount Number of multi-channel samples to process. 78 void process(const audio_sample_t in[], audio_sample_t out[], 79 int frameCount); 80 81 // Enables (activates) the filter. 82 // immediate If true, transitions to new state smoothly, without 83 // introducing discontinuities in the output. Otherwise, 84 // transitions immediately. 85 void enable(bool immediate = false); 86 87 // Disables (bypasses) the filter. 88 // immediate If true, transitions to new state smoothly, without 89 // introducing discontinuities in the output. Otherwise, 90 // transitions immediately. 91 void disable(bool immediate = false); 92 93 private: 94 // A prototype of the actual processing function. Has the same semantics as 95 // the process() method. 96 typedef void (AudioBiquadFilter::*process_func)(const audio_sample_t[], 97 audio_sample_t[], 98 int frameCount); 99 100 // The maximum rate of coefficient change, measured in coefficient units per 101 // second. 102 static const audio_coef_t MAX_DELTA_PER_SEC = 2000; 103 104 // Coefficients of identity transformation. 105 static const audio_coef_t IDENTITY_COEFS[NUM_COEFS]; 106 107 // Filter state. 108 enum state_t { 109 // Bypass. 110 STATE_BYPASS = 0x01, 111 // In the process of smooth transition to bypass state. 112 STATE_TRANSITION_TO_BYPASS = 0x02, 113 // In the process of smooth transition to normal (enabled) state. 114 STATE_TRANSITION_TO_NORMAL = 0x04, 115 // In normal (enabled) state. 116 STATE_NORMAL = 0x05, 117 // A bit-mask for determining whether the filter is enabled or disabled 118 // in the eyes of the client. 119 STATE_ENABLED_MASK = 0x04 120 }; 121 122 // Number of channels. 123 int mNumChannels; 124 // Current state. 125 state_t mState; 126 // Maximum coefficient delta per sample. 127 audio_coef_t mMaxDelta; 128 129 // A bit-mask designating for which coefficients the current value is not 130 // necessarily identical to the target value (since we're in transition 131 // state). 132 uint32_t mCoefDirtyBits; 133 // The current coefficients. 134 audio_coef_t mCoefs[NUM_COEFS]; 135 // The target coefficients. Will not be identical to mCoefs if we are in a 136 // transition state. 137 audio_coef_t mTargetCoefs[NUM_COEFS]; 138 139 // The delay lines. 140 audio_sample_t mDelays[MAX_CHANNELS][4]; 141 142 // Current processing function (determines according to current state and 143 // number of channels). 144 process_func mCurProcessFunc; 145 146 // Sets a new state. Updates the processing function accordingly, and sets 147 // the dirty bits if changing to a transition state. 148 void setState(state_t state); 149 150 // In a transition state, modifies the current coefs towards the passed 151 // coefs, while keeping a smooth change rate. Whenever a coef reaches its 152 // target value, the dirty bit is cleared. If all are clear, the function 153 // returns true, and we can then change to our target state. 154 bool updateCoefs(const audio_coef_t coefs[NUM_COEFS], int frameCount); 155 156 // Processing function when in disabled state. 157 void process_bypass(const audio_sample_t * in, audio_sample_t * out, 158 int frameCount); 159 // Processing function when in normal state, mono. 160 void process_normal_mono(const audio_sample_t * in, audio_sample_t * out, 161 int frameCount); 162 // Processing function when transitioning to normal state, mono. 163 void process_transition_normal_mono(const audio_sample_t * in, 164 audio_sample_t * out, int frameCount); 165 // Processing function when transitioning to bypass state, mono. 166 void process_transition_bypass_mono(const audio_sample_t * in, 167 audio_sample_t * out, int frameCount); 168 // Processing function when in normal state, multi-channel. 169 void process_normal_multi(const audio_sample_t * in, audio_sample_t * out, 170 int frameCount); 171 // Processing function when transitioning to normal state, multi-channel. 172 void process_transition_normal_multi(const audio_sample_t * in, 173 audio_sample_t * out, int frameCount); 174 // Processing function when transitioning to bypass state, multi-channel. 175 void process_transition_bypass_multi(const audio_sample_t * in, 176 audio_sample_t * out, int frameCount); 177 }; 178 } 179 180 #endif // ANDROID_AUDIO_BIQUAD_FILTER_H 181