Home | History | Annotate | Download | only in testlibs
      1 /* /android/src/frameworks/base/libs/audioflinger/AudioShelvingFilter.cpp
      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 #include "AudioShelvingFilter.h"
     19 #include "AudioCommon.h"
     20 #include "EffectsMath.h"
     21 
     22 #include <new>
     23 #include <assert.h>
     24 
     25 #define LIKELY( exp )       (__builtin_expect( (exp) != 0, true  ))
     26 #define UNLIKELY( exp )     (__builtin_expect( (exp) != 0, false ))
     27 
     28 namespace android {
     29 // Format of the coefficient tables:
     30 // kCoefTable[freq][gain][coef]
     31 // freq  - cutoff frequency, in octaves below Nyquist,from -10 to -6 in low
     32 //         shelf, -2 to 0 in high shelf.
     33 // gain  - gain, in millibel, starting at -9600, jumps of 1024, to 4736 millibel.
     34 // coef - 0: b0
     35 //        1: b1
     36 //        2: b2
     37 //        3: -a1
     38 //        4: -a2
     39 static const size_t kHiInDims[2] = {3, 15};
     40 static const audio_coef_t kHiCoefTable[3*15*5] = {
     41 #include "AudioHighShelfFilterCoef.inl"
     42 };
     43 static const size_t kLoInDims[2] = {5, 15};
     44 static const audio_coef_t kLoCoefTable[5*15*5] = {
     45 #include "AudioLowShelfFilterCoef.inl"
     46 };
     47 
     48 AudioCoefInterpolator AudioShelvingFilter::mHiCoefInterp(2, kHiInDims, 5, (const audio_coef_t*) kHiCoefTable);
     49 AudioCoefInterpolator AudioShelvingFilter::mLoCoefInterp(2, kLoInDims, 5, (const audio_coef_t*) kLoCoefTable);
     50 
     51 AudioShelvingFilter::AudioShelvingFilter(ShelfType type, int nChannels,
     52                                          int sampleRate)
     53         : mType(type),
     54           mBiquad(nChannels, sampleRate)  {
     55     configure(nChannels, sampleRate);
     56 }
     57 
     58 void AudioShelvingFilter::configure(int nChannels, int sampleRate) {
     59     mNiquistFreq = sampleRate * 500;
     60     mFrequencyFactor = ((1ull) << 42) / mNiquistFreq;
     61     mBiquad.configure(nChannels, sampleRate);
     62     setFrequency(mNominalFrequency);
     63     commit(true);
     64 }
     65 
     66 void AudioShelvingFilter::reset() {
     67     setGain(0);
     68     setFrequency(mType == kLowShelf ? 0 : mNiquistFreq);
     69     commit(true);
     70 }
     71 
     72 void AudioShelvingFilter::setFrequency(uint32_t millihertz) {
     73     mNominalFrequency = millihertz;
     74     if (UNLIKELY(millihertz > mNiquistFreq / 2)) {
     75         millihertz = mNiquistFreq / 2;
     76     }
     77     uint32_t normFreq = static_cast<uint32_t>(
     78             (static_cast<uint64_t>(millihertz) * mFrequencyFactor) >> 10);
     79     uint32_t log2minFreq = (mType == kLowShelf ? (32-10) : (32-2));
     80     if (LIKELY(normFreq > (1U << log2minFreq))) {
     81         mFrequency = (Effects_log2(normFreq) - (log2minFreq << 15)) << (FREQ_PRECISION_BITS - 15);
     82     } else {
     83         mFrequency = 0;
     84     }
     85 }
     86 
     87 void AudioShelvingFilter::setGain(int32_t millibel) {
     88     mGain = millibel + 9600;
     89 }
     90 
     91 void AudioShelvingFilter::commit(bool immediate) {
     92     audio_coef_t coefs[5];
     93     int intCoord[2] = {
     94         mFrequency >> FREQ_PRECISION_BITS,
     95         mGain >> GAIN_PRECISION_BITS
     96     };
     97     uint32_t fracCoord[2] = {
     98         mFrequency << (32 - FREQ_PRECISION_BITS),
     99         static_cast<uint32_t>(mGain) << (32 - GAIN_PRECISION_BITS)
    100     };
    101     if (mType == kHighShelf) {
    102         mHiCoefInterp.getCoef(intCoord, fracCoord, coefs);
    103     } else {
    104         mLoCoefInterp.getCoef(intCoord, fracCoord, coefs);
    105     }
    106     mBiquad.setCoefs(coefs, immediate);
    107 }
    108 
    109 }
    110