1135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent/* //device/include/server/AudioFlinger/AudioPeakingFilter.h
2135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent**
3135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent** Copyright 2009, 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_PEAKING_FILTER_H
19135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent#define ANDROID_AUDIO_PEAKING_FILTER_H
20135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
21135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent#include "AudioBiquadFilter.h"
22135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent#include "AudioCoefInterpolator.h"
23135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
24135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentnamespace android {
25135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
26135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent// A peaking audio filter, with unity skirt gain, and controllable peak
27135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent// frequency, gain and bandwidth.
28135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent// This filter is able to suppress introduce discontinuities and other artifacts
29135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent// in the output, even when changing parameters abruptly.
30135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent// Parameters can be set to any value - this class will make sure to clip them
31135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent// when they are out of supported range.
32135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent//
33135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent// Implementation notes:
34135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent// This class uses an underlying biquad filter whose parameters are determined
35135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent// using a linear interpolation from a coefficient table, using a
36135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent// AudioCoefInterpolator.
37135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent// All is left for this class to do is mapping between high-level parameters to
38135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent// fractional indices into the coefficient table.
39135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentclass AudioPeakingFilter {
40135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentpublic:
41135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    // Constructor. Resets the filter (see reset()).
42135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    // nChannels  Number of input/output channels (interlaced).
43135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    // sampleRate The input/output sample rate, in Hz.
44135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    AudioPeakingFilter(int nChannels, int sampleRate);
45135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
46135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    // Reconfiguration of the filter. Changes input/output format, but does not
47135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    // alter current parameter values. Clears delay lines.
48135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    // nChannels  Number of input/output channels (interlaced).
49135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    // sampleRate The input/output sample rate, in Hz.
50135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    void configure(int nChannels, int sampleRate);
51135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
52135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    // Resets the filter parameters to the following values:
53135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    // frequency: 0
54135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    // gain: 0
55135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    // bandwidth: 1200 cents.
56135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    // It also disables the filter. Does not clear the delay lines.
57135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    void reset();
58135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
59135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    // Clears delay lines. Does not alter parameter values.
60135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    void clear() { mBiquad.clear(); }
61135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
62135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    // Sets gain value. Actual change will only take place upon commit().
63135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    // This value will be remembered even if the filter is in disabled() state.
64135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    // millibel Gain value in millibel (1/100 of decibel).
65135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    void setGain(int32_t millibel);
66135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
67135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    // Gets the gain, in millibel, as set.
68135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    int32_t getGain() const { return mGain - 9600; }
69135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
70135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    // Sets bandwidth value. Actual change will only take place upon commit().
71135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    // This value will be remembered even if the filter is in disabled() state.
72135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    // cents Bandwidth value in cents (1/1200 octave).
73135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    void setBandwidth(uint32_t cents);
74135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
75135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    // Gets the gain, in cents, as set.
76135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    uint32_t getBandwidth() const { return mBandwidth + 1; }
77135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
78135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    // Sets frequency value. Actual change will only take place upon commit().
79135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    // This value will be remembered even if the filter is in disabled() state.
80135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    // millihertz Frequency value in mHz.
81135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    void setFrequency(uint32_t millihertz);
82135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
83135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    // Gets the frequency, in mHz, as set.
84135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    uint32_t getFrequency() const { return mNominalFrequency; }
85135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
86135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    // Gets gain[dB]/2 points.
87135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    // Results in mHz, and are computed based on the nominal values set, not on
88135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    // possibly rounded or truncated actual values.
89135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    void getBandRange(uint32_t & low, uint32_t & high) const;
90135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
91135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    // Applies all parameter changes done to this point in time.
92135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    // If the filter is disabled, the new parameters will take place when it is
93135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    // enabled again. Does not introduce artifacts, unless immediate is set.
94135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    // immediate    Whether to apply change abruptly (ignored if filter is
95135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    // disabled).
96135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent   void commit(bool immediate = false);
97135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
98135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    // Process a buffer of input data. The input and output should contain
99135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    // frameCount * nChannels interlaced samples. Processing can be done
100135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    // in-place, by passing the same buffer as both arguments.
101135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    // in           Input buffer.
102135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    // out          Output buffer.
103135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    // frameCount   Number of frames to produce.
104135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    void process(const audio_sample_t in[], audio_sample_t out[],
105135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent                 int frameCount) { mBiquad.process(in, out, frameCount); }
106135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
107135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    // Enables the filter, so it would start processing input. Does not
108135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    // introduce artifacts, unless immediate is set.
109135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    // immediate    Whether to apply change abruptly.
110135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    void enable(bool immediate = false) { mBiquad.enable(immediate); }
111135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
112135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    // Disabled (bypasses) the filter. Does not introduce artifacts, unless
113135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    // immediate is set.
114135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    // immediate    Whether to apply change abruptly.
115135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    void disable(bool immediate = false) { mBiquad.disable(immediate); }
116135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
117135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentprivate:
118135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    // Precision for the mFrequency member.
119135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    static const int FREQ_PRECISION_BITS = 26;
120135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    // Precision for the mGain member.
121135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    static const int GAIN_PRECISION_BITS = 10;
122135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    // Precision for the mBandwidth member.
123135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    static const int BANDWIDTH_PRECISION_BITS = 10;
124135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
125135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    // Nyquist, in mHz.
126135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    uint32_t mNiquistFreq;
127135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    // Fractional index into the gain dimension of the coef table in
128135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    // GAIN_PRECISION_BITS precision.
129135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    int32_t mGain;
130135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    // Fractional index into the bandwidth dimension of the coef table in
131135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    // BANDWIDTH_PRECISION_BITS precision.
132135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    uint32_t mBandwidth;
133135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    // Fractional index into the frequency dimension of the coef table in
134135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    // FREQ_PRECISION_BITS precision.
135135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    uint32_t mFrequency;
136135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    // Nominal value of frequency, as set.
137135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    uint32_t mNominalFrequency;
138135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    // 1/Nyquist[mHz], in 42-bit precision (very small).
139135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    // Used for scaling the frequency.
140135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    uint32_t mFrequencyFactor;
141135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
142135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    // A biquad filter, used for the actual processing.
143135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    AudioBiquadFilter mBiquad;
144135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    // A coefficient interpolator, used for mapping the high level parameters to
145135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    // the low-level biquad coefficients.
146135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    static AudioCoefInterpolator mCoefInterp;
147135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent};
148135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
149135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}
150135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
151135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent#endif // ANDROID_AUDIO_PEAKING_FILTER_H
152