1 /* /android/src/frameworks/base/libs/audioflinger/AudioShelvingFilter.h
2 **
3 ** Copyright 2009, 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 AUDIO_SHELVING_FILTER_H
19 #define AUDIO_SHELVING_FILTER_H
20 
21 #include "AudioBiquadFilter.h"
22 #include "AudioCoefInterpolator.h"
23 
24 namespace android {
25 
26 // A shelving audio filter, with unity skirt gain, and controllable cutoff
27 // frequency and gain.
28 // This filter is able to suppress introduce discontinuities and other artifacts
29 // in the output, even when changing parameters abruptly.
30 // Parameters can be set to any value - this class will make sure to clip them
31 // when they are out of supported range.
32 //
33 // Implementation notes:
34 // This class uses an underlying biquad filter whose parameters are determined
35 // using a linear interpolation from a coefficient table, using a
36 // AudioCoefInterpolator.
37 // All is left for this class to do is mapping between high-level parameters to
38 // fractional indices into the coefficient table.
39 class AudioShelvingFilter {
40 public:
41     // Shelf type
42     enum ShelfType {
43         kLowShelf,
44         kHighShelf
45     };
46 
47     // Constructor. Resets the filter (see reset()).
48     // type       Type of the filter (high shelf or low shelf).
49     // nChannels  Number of input/output channels (interlaced).
50     // sampleRate The input/output sample rate, in Hz.
51     AudioShelvingFilter(ShelfType type, int nChannels, int sampleRate);
52 
53     // Reconfiguration of the filter. Changes input/output format, but does not
54     // alter current parameter values. Clears delay lines.
55     // nChannels  Number of input/output channels (interlaced).
56     // sampleRate The input/output sample rate, in Hz.
57     void configure(int nChannels, int sampleRate);
58 
59     // Resets the filter parameters to the following values:
60     // frequency: 0
61     // gain: 0
62     // It also disables the filter. Does not clear the delay lines.
63     void reset();
64 
65     // Clears delay lines. Does not alter parameter values.
clear()66     void clear() { mBiquad.clear(); }
67 
68     // Sets gain value. Actual change will only take place upon commit().
69     // This value will be remembered even if the filter is in disabled() state.
70     // millibel Gain value in millibel (1/100 of decibel).
71     void setGain(int32_t millibel);
72 
73     // Gets the gain, in millibel, as set.
getGain()74     int32_t getGain() const { return mGain - 9600; }
75 
76     // Sets cutoff frequency value. Actual change will only take place upon
77     // commit().
78     // This value will be remembered even if the filter is in disabled() state.
79     // millihertz Frequency value in mHz.
80     void setFrequency(uint32_t millihertz);
81 
82     // Gets the frequency, in mHz, as set.
getFrequency()83     uint32_t getFrequency() const { return mNominalFrequency; }
84 
85     // Applies all parameter changes done to this point in time.
86     // If the filter is disabled, the new parameters will take place when it is
87     // enabled again. Does not introduce artifacts, unless immediate is set.
88     // immediate    Whether to apply change abruptly (ignored if filter is
89     // disabled).
90    void commit(bool immediate = false);
91 
92     // Process a buffer of input data. The input and output should contain
93     // frameCount * nChannels interlaced samples. Processing can be done
94     // in-place, by passing the same buffer as both arguments.
95     // in   Input buffer.
96     // out  Output buffer.
97    // frameCount   Number of frames to produce.
process(const audio_sample_t in[],audio_sample_t out[],int frameCount)98    void process(const audio_sample_t in[], audio_sample_t out[],
99                  int frameCount) { mBiquad.process(in, out, frameCount); }
100 
101     // Enables the filter, so it would start processing input. Does not
102     // introduce artifacts, unless immediate is set.
103     // immediate    Whether to apply change abruptly.
104     void enable(bool immediate = false) { mBiquad.enable(immediate); }
105 
106     // Disabled (bypasses) the filter. Does not introduce artifacts, unless
107     // immediate is set.
108     // immediate    Whether to apply change abruptly.
109     void disable(bool immediate = false) { mBiquad.disable(immediate); }
110 
111 private:
112     // Precision for the mFrequency member.
113     static const int FREQ_PRECISION_BITS = 26;
114     // Precision for the mGain member.
115     static const int GAIN_PRECISION_BITS = 10;
116 
117     // Shelf type.
118     ShelfType mType;
119     // Nyquist, in mHz.
120     uint32_t mNiquistFreq;
121     // Fractional index into the gain dimension of the coef table in
122     // GAIN_PRECISION_BITS precision.
123     int32_t mGain;
124     // Fractional index into the frequency dimension of the coef table in
125     // FREQ_PRECISION_BITS precision.
126     uint32_t mFrequency;
127     // Nominal value of frequency, as set.
128     uint32_t mNominalFrequency;
129    // 1/Nyquist[mHz], in 42-bit precision (very small).
130     // Used for scaling the frequency.
131     uint32_t mFrequencyFactor;
132 
133     // A biquad filter, used for the actual processing.
134     AudioBiquadFilter mBiquad;
135     // A coefficient interpolator, used for mapping the high level parameters to
136     // the low-level biquad coefficients. This one is used for the high shelf.
137     static AudioCoefInterpolator mHiCoefInterp;
138     // A coefficient interpolator, used for mapping the high level parameters to
139     // the low-level biquad coefficients. This one is used for the low shelf.
140     static AudioCoefInterpolator mLoCoefInterp;
141 };
142 
143 }
144 
145 
146 #endif // AUDIO_SHELVING_FILTER_H
147