15fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent/* //device/include/server/AudioFlinger/AudioBiquadFilter.h
25fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent**
35fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent** Copyright 2007, The Android Open Source Project
45fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent**
55fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent** Licensed under the Apache License, Version 2.0 (the "License");
65fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent** you may not use this file except in compliance with the License.
75fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent** You may obtain a copy of the License at
85fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent**
95fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent**     http://www.apache.org/licenses/LICENSE-2.0
105fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent**
115fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent** Unless required by applicable law or agreed to in writing, software
125fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent** distributed under the License is distributed on an "AS IS" BASIS,
135fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
145fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent** See the License for the specific language governing permissions and
155fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent** limitations under the License.
165fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent*/
175fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent
185fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent#ifndef ANDROID_AUDIO_BIQUAD_FILTER_H
195fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent#define ANDROID_AUDIO_BIQUAD_FILTER_H
205fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent
215fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent#include "AudioCommon.h"
225fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent
235fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurentnamespace android {
245fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent// A biquad filter.
255fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent// Implements the recursion y[n]=a0*y[n-1]+a1*y[n-2]+b0*x[n]+b1*x[n-1]+b2*x[n-2]
265fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent// (the a0 and a1 coefficients have an opposite sign to the common convention)
275fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent// The filter works on fixed sized blocks of data (frameCount multi-channel
285fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent// samples, as defined during construction). An arbitrary number of interlaced
295fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent// channels is supported.
305fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent// Filter can operate in an enabled (active) or disabled (bypassed) states.
315fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent// A mechanism for suppression of artifacts caused by abrupt coefficient changes
325fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent// is implemented: normally, when the enable(), disable() and setCoefs() methods
335fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent// are called without the immediate flag set, the filter smoothly transitions
345fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent// from its current state to the desired state.
355fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurentclass AudioBiquadFilter {
365fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurentpublic:
375fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent    // Max number of channels (can be changed here, and everything should work).
385fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent    static const int MAX_CHANNELS = 2;
395fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent    // Number of coefficients.
405fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent    static const int NUM_COEFS = 5;
415fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent
425fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent    // Constructor.
435fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent    // nChannels    Number of input/output channels.
445fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent    // sampleRate   Sample rate, in Hz.
455fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent    AudioBiquadFilter(int nChannels, int sampleRate);
465fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent
475fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent    // Reconfiguration of the filter. Implies clear().
485fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent    // nChannels    Number of input/output channels.
495fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent    // sampleRate   Sample rate, in Hz.
505fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent    void configure(int nChannels, int sampleRate);
515fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent
525fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent    // Resets the internal state of the filter.
535fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent    // Coefficients are reset to identity, state becomes disabled. This change
545fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent    // happens immediately and might cause discontinuities in the output.
555fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent    // Delay lines are not cleared.
565fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent    void reset();
575fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent
585fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent    // Clears the delay lines.
595fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent    // This change happens immediately and might cause discontinuities in the
605fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent    // output.
615fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent    void clear();
625fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent
635fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent    // Sets the coefficients.
645fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent    // If called when filter is disabled, will have no immediate effect, but the
655fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent    // new coefficients will be set and used next time the filter is enabled.
665fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent    // coefs        The new coefficients.
675fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent    // immediate    If true, transitions to new coefficients smoothly, without
685fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent    //              introducing discontinuities in the output. Otherwise,
695fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent    //              transitions immediately.
705fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent    void setCoefs(const audio_coef_t coefs[NUM_COEFS], bool immediate = false);
715fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent
725fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent    // Process a buffer of data. Always processes frameCount multi-channel
735fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent    // samples. Processing can be done in-place, by passing the same buffer as
745fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent    // both arguments.
755fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent    // in           The input buffer. Should be of size frameCount * nChannels.
765fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent    // out          The output buffer. Should be of size frameCount * nChannels.
775fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent    // frameCount   Number of multi-channel samples to process.
785fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent    void process(const audio_sample_t in[], audio_sample_t out[],
795fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent                 int frameCount);
805fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent
815fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent    // Enables (activates) the filter.
825fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent    // immediate    If true, transitions to new state smoothly, without
835fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent    //              introducing discontinuities in the output. Otherwise,
845fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent    //              transitions immediately.
855fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent    void enable(bool immediate = false);
865fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent
875fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent    // Disables (bypasses) the filter.
885fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent    // immediate    If true, transitions to new state smoothly, without
895fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent    //              introducing discontinuities in the output. Otherwise,
905fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent    //              transitions immediately.
915fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent    void disable(bool immediate = false);
925fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent
935fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurentprivate:
945fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent    // A prototype of the actual processing function. Has the same semantics as
955fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent    // the process() method.
965fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent    typedef void (AudioBiquadFilter::*process_func)(const audio_sample_t[],
975fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent                                                    audio_sample_t[],
985fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent                                                    int frameCount);
995fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent
1005fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent    // The maximum rate of coefficient change, measured in coefficient units per
1015fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent    // second.
1025fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent    static const audio_coef_t MAX_DELTA_PER_SEC = 2000;
1035fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent
1045fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent    // Coefficients of identity transformation.
1055fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent    static const audio_coef_t IDENTITY_COEFS[NUM_COEFS];
1065fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent
1075fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent    // Filter state.
1085fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent    enum state_t {
1095fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent        // Bypass.
1105fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent        STATE_BYPASS = 0x01,
1115fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent        // In the process of smooth transition to bypass state.
1125fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent        STATE_TRANSITION_TO_BYPASS = 0x02,
1135fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent        // In the process of smooth transition to normal (enabled) state.
1145fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent        STATE_TRANSITION_TO_NORMAL = 0x04,
1155fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent        // In normal (enabled) state.
1165fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent        STATE_NORMAL = 0x05,
1175fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent        // A bit-mask for determining whether the filter is enabled or disabled
1185fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent        // in the eyes of the client.
1195fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent        STATE_ENABLED_MASK = 0x04
1205fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent    };
1215fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent
1225fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent    // Number of channels.
1235fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent    int mNumChannels;
1245fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent    // Current state.
1255fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent    state_t mState;
1265fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent    // Maximum coefficient delta per sample.
1275fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent    audio_coef_t mMaxDelta;
1285fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent
1295fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent    // A bit-mask designating for which coefficients the current value is not
1305fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent    // necessarily identical to the target value (since we're in transition
1315fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent    // state).
1325fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent    uint32_t mCoefDirtyBits;
1335fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent    // The current coefficients.
1345fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent    audio_coef_t mCoefs[NUM_COEFS];
1355fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent    // The target coefficients. Will not be identical to mCoefs if we are in a
1365fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent    // transition state.
1375fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent    audio_coef_t mTargetCoefs[NUM_COEFS];
1385fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent
1395fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent    // The delay lines.
1405fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent    audio_sample_t mDelays[MAX_CHANNELS][4];
1415fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent
1425fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent    // Current processing function (determines according to current state and
1435fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent    // number of channels).
1445fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent    process_func mCurProcessFunc;
1455fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent
1465fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent    // Sets a new state. Updates the processing function accordingly, and sets
1475fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent    // the dirty bits if changing to a transition state.
1485fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent    void setState(state_t state);
1495fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent
1505fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent    // In a transition state, modifies the current coefs towards the passed
1515fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent    // coefs, while keeping a smooth change rate. Whenever a coef reaches its
1525fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent    // target value, the dirty bit is cleared. If all are clear, the function
1535fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent    // returns true, and we can then change to our target state.
1545fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent    bool updateCoefs(const audio_coef_t coefs[NUM_COEFS], int frameCount);
1555fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent
1565fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent    // Processing function when in disabled state.
1575fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent    void process_bypass(const audio_sample_t * in, audio_sample_t * out,
1585fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent                        int frameCount);
1595fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent    // Processing function when in normal state, mono.
1605fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent    void process_normal_mono(const audio_sample_t * in, audio_sample_t * out,
1615fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent                             int frameCount);
1625fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent    // Processing function when transitioning to normal state, mono.
1635fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent    void process_transition_normal_mono(const audio_sample_t * in,
1645fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent                                        audio_sample_t * out, int frameCount);
1655fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent    // Processing function when transitioning to bypass state, mono.
1665fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent    void process_transition_bypass_mono(const audio_sample_t * in,
1675fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent                                        audio_sample_t * out, int frameCount);
1685fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent    // Processing function when in normal state, multi-channel.
1695fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent    void process_normal_multi(const audio_sample_t * in, audio_sample_t * out,
1705fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent                              int frameCount);
1715fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent    // Processing function when transitioning to normal state, multi-channel.
1725fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent    void process_transition_normal_multi(const audio_sample_t * in,
1735fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent                                         audio_sample_t * out, int frameCount);
1745fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent    // Processing function when transitioning to bypass state, multi-channel.
1755fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent    void process_transition_bypass_multi(const audio_sample_t * in,
1765fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent                                         audio_sample_t * out, int frameCount);
1775fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent};
1785fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent}
1795fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent
1805fe37c6838de9fbd959ad19ba44aa3d00d1b4e6fEric Laurent#endif // ANDROID_AUDIO_BIQUAD_FILTER_H
181