1*05767d91SRobert Wu /* 2*05767d91SRobert Wu * Copyright 2019 The Android Open Source Project 3*05767d91SRobert Wu * 4*05767d91SRobert Wu * Licensed under the Apache License, Version 2.0 (the "License"); 5*05767d91SRobert Wu * you may not use this file except in compliance with the License. 6*05767d91SRobert Wu * You may obtain a copy of the License at 7*05767d91SRobert Wu * 8*05767d91SRobert Wu * http://www.apache.org/licenses/LICENSE-2.0 9*05767d91SRobert Wu * 10*05767d91SRobert Wu * Unless required by applicable law or agreed to in writing, software 11*05767d91SRobert Wu * distributed under the License is distributed on an "AS IS" BASIS, 12*05767d91SRobert Wu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*05767d91SRobert Wu * See the License for the specific language governing permissions and 14*05767d91SRobert Wu * limitations under the License. 15*05767d91SRobert Wu */ 16*05767d91SRobert Wu 17*05767d91SRobert Wu #ifndef RESAMPLER_KAISER_WINDOW_H 18*05767d91SRobert Wu #define RESAMPLER_KAISER_WINDOW_H 19*05767d91SRobert Wu 20*05767d91SRobert Wu #include <math.h> 21*05767d91SRobert Wu 22*05767d91SRobert Wu #include "ResamplerDefinitions.h" 23*05767d91SRobert Wu 24*05767d91SRobert Wu namespace RESAMPLER_OUTER_NAMESPACE::resampler { 25*05767d91SRobert Wu 26*05767d91SRobert Wu /** 27*05767d91SRobert Wu * Calculate a Kaiser window centered at 0. 28*05767d91SRobert Wu */ 29*05767d91SRobert Wu class KaiserWindow { 30*05767d91SRobert Wu public: KaiserWindow()31*05767d91SRobert Wu KaiserWindow() { 32*05767d91SRobert Wu setStopBandAttenuation(60); 33*05767d91SRobert Wu } 34*05767d91SRobert Wu 35*05767d91SRobert Wu /** 36*05767d91SRobert Wu * @param attenuation typical values range from 30 to 90 dB 37*05767d91SRobert Wu * @return beta 38*05767d91SRobert Wu */ setStopBandAttenuation(double attenuation)39*05767d91SRobert Wu double setStopBandAttenuation(double attenuation) { 40*05767d91SRobert Wu double beta = 0.0; 41*05767d91SRobert Wu if (attenuation > 50) { 42*05767d91SRobert Wu beta = 0.1102 * (attenuation - 8.7); 43*05767d91SRobert Wu } else if (attenuation >= 21) { 44*05767d91SRobert Wu double a21 = attenuation - 21; 45*05767d91SRobert Wu beta = 0.5842 * pow(a21, 0.4) + (0.07886 * a21); 46*05767d91SRobert Wu } 47*05767d91SRobert Wu setBeta(beta); 48*05767d91SRobert Wu return beta; 49*05767d91SRobert Wu } 50*05767d91SRobert Wu setBeta(double beta)51*05767d91SRobert Wu void setBeta(double beta) { 52*05767d91SRobert Wu mBeta = beta; 53*05767d91SRobert Wu mInverseBesselBeta = 1.0 / bessel(beta); 54*05767d91SRobert Wu } 55*05767d91SRobert Wu 56*05767d91SRobert Wu /** 57*05767d91SRobert Wu * @param x ranges from -1.0 to +1.0 58*05767d91SRobert Wu */ operator()59*05767d91SRobert Wu double operator()(double x) { 60*05767d91SRobert Wu double x2 = x * x; 61*05767d91SRobert Wu if (x2 >= 1.0) return 0.0; 62*05767d91SRobert Wu double w = mBeta * sqrt(1.0 - x2); 63*05767d91SRobert Wu return bessel(w) * mInverseBesselBeta; 64*05767d91SRobert Wu } 65*05767d91SRobert Wu 66*05767d91SRobert Wu // Approximation of a 67*05767d91SRobert Wu // modified zero order Bessel function of the first kind. 68*05767d91SRobert Wu // Based on a discussion at: 69*05767d91SRobert Wu // https://dsp.stackexchange.com/questions/37714/kaiser-window-approximation bessel(double x)70*05767d91SRobert Wu static double bessel(double x) { 71*05767d91SRobert Wu double y = cosh(0.970941817426052 * x); 72*05767d91SRobert Wu y += cosh(0.8854560256532099 * x); 73*05767d91SRobert Wu y += cosh(0.7485107481711011 * x); 74*05767d91SRobert Wu y += cosh(0.5680647467311558 * x); 75*05767d91SRobert Wu y += cosh(0.3546048870425356 * x); 76*05767d91SRobert Wu y += cosh(0.120536680255323 * x); 77*05767d91SRobert Wu y *= 2; 78*05767d91SRobert Wu y += cosh(x); 79*05767d91SRobert Wu y /= 13; 80*05767d91SRobert Wu return y; 81*05767d91SRobert Wu } 82*05767d91SRobert Wu 83*05767d91SRobert Wu private: 84*05767d91SRobert Wu double mBeta = 0.0; 85*05767d91SRobert Wu double mInverseBesselBeta = 1.0; 86*05767d91SRobert Wu }; 87*05767d91SRobert Wu 88*05767d91SRobert Wu } /* namespace RESAMPLER_OUTER_NAMESPACE::resampler */ 89*05767d91SRobert Wu 90*05767d91SRobert Wu #endif //RESAMPLER_KAISER_WINDOW_H 91