You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
181 lines
7.8 KiB
181 lines
7.8 KiB
/* //device/include/server/AudioFlinger/AudioBiquadFilter.h
|
|
**
|
|
** Copyright 2007, The Android Open Source Project
|
|
**
|
|
** Licensed under the Apache License, Version 2.0 (the "License");
|
|
** you may not use this file except in compliance with the License.
|
|
** You may obtain a copy of the License at
|
|
**
|
|
** http://www.apache.org/licenses/LICENSE-2.0
|
|
**
|
|
** Unless required by applicable law or agreed to in writing, software
|
|
** distributed under the License is distributed on an "AS IS" BASIS,
|
|
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
** See the License for the specific language governing permissions and
|
|
** limitations under the License.
|
|
*/
|
|
|
|
#ifndef ANDROID_AUDIO_BIQUAD_FILTER_H
|
|
#define ANDROID_AUDIO_BIQUAD_FILTER_H
|
|
|
|
#include "AudioCommon.h"
|
|
|
|
namespace android {
|
|
// A biquad filter.
|
|
// Implements the recursion y[n]=a0*y[n-1]+a1*y[n-2]+b0*x[n]+b1*x[n-1]+b2*x[n-2]
|
|
// (the a0 and a1 coefficients have an opposite sign to the common convention)
|
|
// The filter works on fixed sized blocks of data (frameCount multi-channel
|
|
// samples, as defined during construction). An arbitrary number of interlaced
|
|
// channels is supported.
|
|
// Filter can operate in an enabled (active) or disabled (bypassed) states.
|
|
// A mechanism for suppression of artifacts caused by abrupt coefficient changes
|
|
// is implemented: normally, when the enable(), disable() and setCoefs() methods
|
|
// are called without the immediate flag set, the filter smoothly transitions
|
|
// from its current state to the desired state.
|
|
class AudioBiquadFilter {
|
|
public:
|
|
// Max number of channels (can be changed here, and everything should work).
|
|
static const int MAX_CHANNELS = 2;
|
|
// Number of coefficients.
|
|
static const int NUM_COEFS = 5;
|
|
|
|
// Constructor.
|
|
// nChannels Number of input/output channels.
|
|
// sampleRate Sample rate, in Hz.
|
|
AudioBiquadFilter(int nChannels, int sampleRate);
|
|
|
|
// Reconfiguration of the filter. Implies clear().
|
|
// nChannels Number of input/output channels.
|
|
// sampleRate Sample rate, in Hz.
|
|
void configure(int nChannels, int sampleRate);
|
|
|
|
// Resets the internal state of the filter.
|
|
// Coefficients are reset to identity, state becomes disabled. This change
|
|
// happens immediately and might cause discontinuities in the output.
|
|
// Delay lines are not cleared.
|
|
void reset();
|
|
|
|
// Clears the delay lines.
|
|
// This change happens immediately and might cause discontinuities in the
|
|
// output.
|
|
void clear();
|
|
|
|
// Sets the coefficients.
|
|
// If called when filter is disabled, will have no immediate effect, but the
|
|
// new coefficients will be set and used next time the filter is enabled.
|
|
// coefs The new coefficients.
|
|
// immediate If true, transitions to new coefficients smoothly, without
|
|
// introducing discontinuities in the output. Otherwise,
|
|
// transitions immediately.
|
|
void setCoefs(const audio_coef_t coefs[NUM_COEFS], bool immediate = false);
|
|
|
|
// Process a buffer of data. Always processes frameCount multi-channel
|
|
// samples. Processing can be done in-place, by passing the same buffer as
|
|
// both arguments.
|
|
// in The input buffer. Should be of size frameCount * nChannels.
|
|
// out The output buffer. Should be of size frameCount * nChannels.
|
|
// frameCount Number of multi-channel samples to process.
|
|
void process(const audio_sample_t in[], audio_sample_t out[],
|
|
int frameCount);
|
|
|
|
// Enables (activates) the filter.
|
|
// immediate If true, transitions to new state smoothly, without
|
|
// introducing discontinuities in the output. Otherwise,
|
|
// transitions immediately.
|
|
void enable(bool immediate = false);
|
|
|
|
// Disables (bypasses) the filter.
|
|
// immediate If true, transitions to new state smoothly, without
|
|
// introducing discontinuities in the output. Otherwise,
|
|
// transitions immediately.
|
|
void disable(bool immediate = false);
|
|
|
|
private:
|
|
// A prototype of the actual processing function. Has the same semantics as
|
|
// the process() method.
|
|
typedef void (AudioBiquadFilter::*process_func)(const audio_sample_t[],
|
|
audio_sample_t[],
|
|
int frameCount);
|
|
|
|
// The maximum rate of coefficient change, measured in coefficient units per
|
|
// second.
|
|
static const audio_coef_t MAX_DELTA_PER_SEC = 2000;
|
|
|
|
// Coefficients of identity transformation.
|
|
static const audio_coef_t IDENTITY_COEFS[NUM_COEFS];
|
|
|
|
// Filter state.
|
|
enum state_t {
|
|
// Bypass.
|
|
STATE_BYPASS = 0x01,
|
|
// In the process of smooth transition to bypass state.
|
|
STATE_TRANSITION_TO_BYPASS = 0x02,
|
|
// In the process of smooth transition to normal (enabled) state.
|
|
STATE_TRANSITION_TO_NORMAL = 0x04,
|
|
// In normal (enabled) state.
|
|
STATE_NORMAL = 0x05,
|
|
// A bit-mask for determining whether the filter is enabled or disabled
|
|
// in the eyes of the client.
|
|
STATE_ENABLED_MASK = 0x04
|
|
};
|
|
|
|
// Number of channels.
|
|
int mNumChannels;
|
|
// Current state.
|
|
state_t mState;
|
|
// Maximum coefficient delta per sample.
|
|
audio_coef_t mMaxDelta;
|
|
|
|
// A bit-mask designating for which coefficients the current value is not
|
|
// necessarily identical to the target value (since we're in transition
|
|
// state).
|
|
uint32_t mCoefDirtyBits;
|
|
// The current coefficients.
|
|
audio_coef_t mCoefs[NUM_COEFS];
|
|
// The target coefficients. Will not be identical to mCoefs if we are in a
|
|
// transition state.
|
|
audio_coef_t mTargetCoefs[NUM_COEFS];
|
|
|
|
// The delay lines.
|
|
audio_sample_t mDelays[MAX_CHANNELS][4];
|
|
|
|
// Current processing function (determines according to current state and
|
|
// number of channels).
|
|
process_func mCurProcessFunc;
|
|
|
|
// Sets a new state. Updates the processing function accordingly, and sets
|
|
// the dirty bits if changing to a transition state.
|
|
void setState(state_t state);
|
|
|
|
// In a transition state, modifies the current coefs towards the passed
|
|
// coefs, while keeping a smooth change rate. Whenever a coef reaches its
|
|
// target value, the dirty bit is cleared. If all are clear, the function
|
|
// returns true, and we can then change to our target state.
|
|
bool updateCoefs(const audio_coef_t coefs[NUM_COEFS], int frameCount);
|
|
|
|
// Processing function when in disabled state.
|
|
void process_bypass(const audio_sample_t * in, audio_sample_t * out,
|
|
int frameCount);
|
|
// Processing function when in normal state, mono.
|
|
void process_normal_mono(const audio_sample_t * in, audio_sample_t * out,
|
|
int frameCount);
|
|
// Processing function when transitioning to normal state, mono.
|
|
void process_transition_normal_mono(const audio_sample_t * in,
|
|
audio_sample_t * out, int frameCount);
|
|
// Processing function when transitioning to bypass state, mono.
|
|
void process_transition_bypass_mono(const audio_sample_t * in,
|
|
audio_sample_t * out, int frameCount);
|
|
// Processing function when in normal state, multi-channel.
|
|
void process_normal_multi(const audio_sample_t * in, audio_sample_t * out,
|
|
int frameCount);
|
|
// Processing function when transitioning to normal state, multi-channel.
|
|
void process_transition_normal_multi(const audio_sample_t * in,
|
|
audio_sample_t * out, int frameCount);
|
|
// Processing function when transitioning to bypass state, multi-channel.
|
|
void process_transition_bypass_multi(const audio_sample_t * in,
|
|
audio_sample_t * out, int frameCount);
|
|
};
|
|
}
|
|
|
|
#endif // ANDROID_AUDIO_BIQUAD_FILTER_H
|