summaryrefslogtreecommitdiffstats
path: root/media/libeffects/testlibs/AudioBiquadFilter.h
diff options
context:
space:
mode:
Diffstat (limited to 'media/libeffects/testlibs/AudioBiquadFilter.h')
-rw-r--r--media/libeffects/testlibs/AudioBiquadFilter.h180
1 files changed, 180 insertions, 0 deletions
diff --git a/media/libeffects/testlibs/AudioBiquadFilter.h b/media/libeffects/testlibs/AudioBiquadFilter.h
new file mode 100644
index 0000000..2b0e2d6
--- /dev/null
+++ b/media/libeffects/testlibs/AudioBiquadFilter.h
@@ -0,0 +1,180 @@
+/* //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