1 /*
2  * Copyright 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef RESAMPLER_HYPERBOLIC_COSINE_WINDOW_H
18 #define RESAMPLER_HYPERBOLIC_COSINE_WINDOW_H
19 
20 #include <math.h>
21 
22 namespace resampler {
23 
24 /**
25  * Calculate a HyperbolicCosineWindow window centered at 0.
26  * This can be used in place of a Kaiser window.
27  *
28  * The code is based on an anonymous contribution by "a concerned citizen":
29  * https://dsp.stackexchange.com/questions/37714/kaiser-window-approximation
30  */
31 class HyperbolicCosineWindow {
32 public:
HyperbolicCosineWindow()33     HyperbolicCosineWindow() {
34         setStopBandAttenuation(60);
35     }
36 
37     /**
38      * @param attenuation typical values range from 30 to 90 dB
39      * @return beta
40      */
setStopBandAttenuation(double attenuation)41     double setStopBandAttenuation(double attenuation) {
42         double alpha = ((-325.1e-6 * attenuation + 0.1677) * attenuation) - 3.149;
43         setAlpha(alpha);
44         return alpha;
45     }
46 
setAlpha(double alpha)47     void setAlpha(double alpha) {
48         mAlpha = alpha;
49         mInverseCoshAlpha = 1.0 / cosh(alpha);
50     }
51 
52     /**
53      * @param x ranges from -1.0 to +1.0
54      */
operator()55     double operator()(double x) {
56         double x2 = x * x;
57         if (x2 >= 1.0) return 0.0;
58         double w = mAlpha * sqrt(1.0 - x2);
59         return cosh(w) * mInverseCoshAlpha;
60     }
61 
62 private:
63     double mAlpha = 0.0;
64     double mInverseCoshAlpha = 1.0;
65 };
66 
67 } // namespace resampler
68 #endif //RESAMPLER_HYPERBOLIC_COSINE_WINDOW_H
69