1/* //device/include/server/AudioFlinger/AudioPeakingFilter.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 ANDROID_AUDIO_PEAKING_FILTER_H
19#define ANDROID_AUDIO_PEAKING_FILTER_H
20
21#include "AudioBiquadFilter.h"
22#include "AudioCoefInterpolator.h"
23
24namespace android {
25
26// A peaking audio filter, with unity skirt gain, and controllable peak
27// frequency, gain and bandwidth.
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.
39class AudioPeakingFilter {
40public:
41    // Constructor. Resets the filter (see reset()).
42    // nChannels  Number of input/output channels (interlaced).
43    // sampleRate The input/output sample rate, in Hz.
44    AudioPeakingFilter(int nChannels, int sampleRate);
45
46    // Reconfiguration of the filter. Changes input/output format, but does not
47    // alter current parameter values. Clears delay lines.
48    // nChannels  Number of input/output channels (interlaced).
49    // sampleRate The input/output sample rate, in Hz.
50    void configure(int nChannels, int sampleRate);
51
52    // Resets the filter parameters to the following values:
53    // frequency: 0
54    // gain: 0
55    // bandwidth: 1200 cents.
56    // It also disables the filter. Does not clear the delay lines.
57    void reset();
58
59    // Clears delay lines. Does not alter parameter values.
60    void clear() { mBiquad.clear(); }
61
62    // Sets gain value. Actual change will only take place upon commit().
63    // This value will be remembered even if the filter is in disabled() state.
64    // millibel Gain value in millibel (1/100 of decibel).
65    void setGain(int32_t millibel);
66
67    // Gets the gain, in millibel, as set.
68    int32_t getGain() const { return mGain - 9600; }
69
70    // Sets bandwidth value. Actual change will only take place upon commit().
71    // This value will be remembered even if the filter is in disabled() state.
72    // cents Bandwidth value in cents (1/1200 octave).
73    void setBandwidth(uint32_t cents);
74
75    // Gets the gain, in cents, as set.
76    uint32_t getBandwidth() const { return mBandwidth + 1; }
77
78    // Sets frequency value. Actual change will only take place upon commit().
79    // This value will be remembered even if the filter is in disabled() state.
80    // millihertz Frequency value in mHz.
81    void setFrequency(uint32_t millihertz);
82
83    // Gets the frequency, in mHz, as set.
84    uint32_t getFrequency() const { return mNominalFrequency; }
85
86    // Gets gain[dB]/2 points.
87    // Results in mHz, and are computed based on the nominal values set, not on
88    // possibly rounded or truncated actual values.
89    void getBandRange(uint32_t & low, uint32_t & high) const;
90
91    // Applies all parameter changes done to this point in time.
92    // If the filter is disabled, the new parameters will take place when it is
93    // enabled again. Does not introduce artifacts, unless immediate is set.
94    // immediate    Whether to apply change abruptly (ignored if filter is
95    // disabled).
96   void commit(bool immediate = false);
97
98    // Process a buffer of input data. The input and output should contain
99    // frameCount * nChannels interlaced samples. Processing can be done
100    // in-place, by passing the same buffer as both arguments.
101    // in           Input buffer.
102    // out          Output buffer.
103    // frameCount   Number of frames to produce.
104    void process(const audio_sample_t in[], audio_sample_t out[],
105                 int frameCount) { mBiquad.process(in, out, frameCount); }
106
107    // Enables the filter, so it would start processing input. Does not
108    // introduce artifacts, unless immediate is set.
109    // immediate    Whether to apply change abruptly.
110    void enable(bool immediate = false) { mBiquad.enable(immediate); }
111
112    // Disabled (bypasses) the filter. Does not introduce artifacts, unless
113    // immediate is set.
114    // immediate    Whether to apply change abruptly.
115    void disable(bool immediate = false) { mBiquad.disable(immediate); }
116
117private:
118    // Precision for the mFrequency member.
119    static const int FREQ_PRECISION_BITS = 26;
120    // Precision for the mGain member.
121    static const int GAIN_PRECISION_BITS = 10;
122    // Precision for the mBandwidth member.
123    static const int BANDWIDTH_PRECISION_BITS = 10;
124
125    // Nyquist, in mHz.
126    uint32_t mNiquistFreq;
127    // Fractional index into the gain dimension of the coef table in
128    // GAIN_PRECISION_BITS precision.
129    int32_t mGain;
130    // Fractional index into the bandwidth dimension of the coef table in
131    // BANDWIDTH_PRECISION_BITS precision.
132    uint32_t mBandwidth;
133    // Fractional index into the frequency dimension of the coef table in
134    // FREQ_PRECISION_BITS precision.
135    uint32_t mFrequency;
136    // Nominal value of frequency, as set.
137    uint32_t mNominalFrequency;
138    // 1/Nyquist[mHz], in 42-bit precision (very small).
139    // Used for scaling the frequency.
140    uint32_t mFrequencyFactor;
141
142    // A biquad filter, used for the actual processing.
143    AudioBiquadFilter mBiquad;
144    // A coefficient interpolator, used for mapping the high level parameters to
145    // the low-level biquad coefficients.
146    static AudioCoefInterpolator mCoefInterp;
147};
148
149}
150
151#endif // ANDROID_AUDIO_PEAKING_FILTER_H
152