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