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
23namespace 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.
35class AudioBiquadFilter {
36public:
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
93private:
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