xref: /aosp_15_r20/external/oboe/src/flowgraph/resampler/KaiserWindow.h (revision 05767d913155b055644481607e6fa1e35e2fe72c)
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