1135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent/* //device/include/server/AudioFlinger/AudioBiquadFilter.h 2135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent** 3135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent** Copyright 2007, 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_BIQUAD_FILTER_H 19135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent#define ANDROID_AUDIO_BIQUAD_FILTER_H 20135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 21135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent#include "AudioCommon.h" 22135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 23135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentnamespace android { 24135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent// A biquad filter. 25135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent// Implements the recursion y[n]=a0*y[n-1]+a1*y[n-2]+b0*x[n]+b1*x[n-1]+b2*x[n-2] 26135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent// (the a0 and a1 coefficients have an opposite sign to the common convention) 27135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent// The filter works on fixed sized blocks of data (frameCount multi-channel 28135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent// samples, as defined during construction). An arbitrary number of interlaced 29135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent// channels is supported. 30135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent// Filter can operate in an enabled (active) or disabled (bypassed) states. 31135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent// A mechanism for suppression of artifacts caused by abrupt coefficient changes 32135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent// is implemented: normally, when the enable(), disable() and setCoefs() methods 33135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent// are called without the immediate flag set, the filter smoothly transitions 34135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent// from its current state to the desired state. 35135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentclass AudioBiquadFilter { 36135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentpublic: 37135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // Max number of channels (can be changed here, and everything should work). 38135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent static const int MAX_CHANNELS = 2; 39135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // Number of coefficients. 40135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent static const int NUM_COEFS = 5; 41135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 42135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // Constructor. 43135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // nChannels Number of input/output channels. 44135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // sampleRate Sample rate, in Hz. 45135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent AudioBiquadFilter(int nChannels, int sampleRate); 46135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 47135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // Reconfiguration of the filter. Implies clear(). 48135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // nChannels Number of input/output channels. 49135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // sampleRate Sample rate, in Hz. 50135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent void configure(int nChannels, int sampleRate); 51135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 52135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // Resets the internal state of the filter. 53135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // Coefficients are reset to identity, state becomes disabled. This change 54135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // happens immediately and might cause discontinuities in the output. 55135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // Delay lines are not cleared. 56135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent void reset(); 57135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 58135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // Clears the delay lines. 59135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // This change happens immediately and might cause discontinuities in the 60135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // output. 61135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent void clear(); 62135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 63135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // Sets the coefficients. 64135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // If called when filter is disabled, will have no immediate effect, but the 65135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // new coefficients will be set and used next time the filter is enabled. 66135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // coefs The new coefficients. 67135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // immediate If true, transitions to new coefficients smoothly, without 68135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // introducing discontinuities in the output. Otherwise, 69135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // transitions immediately. 70135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent void setCoefs(const audio_coef_t coefs[NUM_COEFS], bool immediate = false); 71135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 72135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // Process a buffer of data. Always processes frameCount multi-channel 73135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // samples. Processing can be done in-place, by passing the same buffer as 74135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // both arguments. 75135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // in The input buffer. Should be of size frameCount * nChannels. 76135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // out The output buffer. Should be of size frameCount * nChannels. 77135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // frameCount Number of multi-channel samples to process. 78135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent void process(const audio_sample_t in[], audio_sample_t out[], 79135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent int frameCount); 80135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 81135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // Enables (activates) the filter. 82135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // immediate If true, transitions to new state smoothly, without 83135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // introducing discontinuities in the output. Otherwise, 84135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // transitions immediately. 85135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent void enable(bool immediate = false); 86135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 87135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // Disables (bypasses) the filter. 88135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // immediate If true, transitions to new state smoothly, without 89135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // introducing discontinuities in the output. Otherwise, 90135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // transitions immediately. 91135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent void disable(bool immediate = false); 92135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 93135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentprivate: 94135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // A prototype of the actual processing function. Has the same semantics as 95135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // the process() method. 96135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent typedef void (AudioBiquadFilter::*process_func)(const audio_sample_t[], 97135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent audio_sample_t[], 98135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent int frameCount); 99135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 100135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // The maximum rate of coefficient change, measured in coefficient units per 101135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // second. 102135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent static const audio_coef_t MAX_DELTA_PER_SEC = 2000; 103135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 104135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // Coefficients of identity transformation. 105135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent static const audio_coef_t IDENTITY_COEFS[NUM_COEFS]; 106135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 107135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // Filter state. 108135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent enum state_t { 109135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // Bypass. 110135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent STATE_BYPASS = 0x01, 111135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // In the process of smooth transition to bypass state. 112135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent STATE_TRANSITION_TO_BYPASS = 0x02, 113135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // In the process of smooth transition to normal (enabled) state. 114135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent STATE_TRANSITION_TO_NORMAL = 0x04, 115135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // In normal (enabled) state. 116135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent STATE_NORMAL = 0x05, 117135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // A bit-mask for determining whether the filter is enabled or disabled 118135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // in the eyes of the client. 119135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent STATE_ENABLED_MASK = 0x04 120135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent }; 121135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 122135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // Number of channels. 123135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent int mNumChannels; 124135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // Current state. 125135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent state_t mState; 126135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // Maximum coefficient delta per sample. 127135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent audio_coef_t mMaxDelta; 128135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 129135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // A bit-mask designating for which coefficients the current value is not 130135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // necessarily identical to the target value (since we're in transition 131135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // state). 132135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent uint32_t mCoefDirtyBits; 133135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // The current coefficients. 134135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent audio_coef_t mCoefs[NUM_COEFS]; 135135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // The target coefficients. Will not be identical to mCoefs if we are in a 136135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // transition state. 137135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent audio_coef_t mTargetCoefs[NUM_COEFS]; 138135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 139135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // The delay lines. 140135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent audio_sample_t mDelays[MAX_CHANNELS][4]; 141135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 142135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // Current processing function (determines according to current state and 143135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // number of channels). 144135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent process_func mCurProcessFunc; 145135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 146135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // Sets a new state. Updates the processing function accordingly, and sets 147135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // the dirty bits if changing to a transition state. 148135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent void setState(state_t state); 149135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 150135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // In a transition state, modifies the current coefs towards the passed 151135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // coefs, while keeping a smooth change rate. Whenever a coef reaches its 152135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // target value, the dirty bit is cleared. If all are clear, the function 153135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // returns true, and we can then change to our target state. 154135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent bool updateCoefs(const audio_coef_t coefs[NUM_COEFS], int frameCount); 155135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 156135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // Processing function when in disabled state. 157135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent void process_bypass(const audio_sample_t * in, audio_sample_t * out, 158135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent int frameCount); 159135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // Processing function when in normal state, mono. 160135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent void process_normal_mono(const audio_sample_t * in, audio_sample_t * out, 161135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent int frameCount); 162135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // Processing function when transitioning to normal state, mono. 163135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent void process_transition_normal_mono(const audio_sample_t * in, 164135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent audio_sample_t * out, int frameCount); 165135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // Processing function when transitioning to bypass state, mono. 166135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent void process_transition_bypass_mono(const audio_sample_t * in, 167135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent audio_sample_t * out, int frameCount); 168135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // Processing function when in normal state, multi-channel. 169135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent void process_normal_multi(const audio_sample_t * in, audio_sample_t * out, 170135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent int frameCount); 171135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // Processing function when transitioning to normal state, multi-channel. 172135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent void process_transition_normal_multi(const audio_sample_t * in, 173135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent audio_sample_t * out, int frameCount); 174135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // Processing function when transitioning to bypass state, multi-channel. 175135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent void process_transition_bypass_multi(const audio_sample_t * in, 176135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent audio_sample_t * out, int frameCount); 177135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}; 178135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent} 179135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 180135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent#endif // ANDROID_AUDIO_BIQUAD_FILTER_H 181