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