1 /* 2 * Copyright (c) 2023 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef FFT_H 17 #define FFT_H 18 19 #include "utils.h" 20 21 namespace OHOS { 22 namespace Sensors { 23 /** 24 * @brief The parameters and calculation results used in FFT. 25 * Used to encapsulate 6 parameters in the AlgFFT function. 26 */ 27 struct FftParaAndResult { 28 /** Number of samples */ 29 int32_t numSamples { 0 }; 30 /** The real part of the input */ 31 std::vector<float> realIn; 32 /** The imaginary part of the input */ 33 std::vector<float> imagIn; 34 /** The real part of the output */ 35 std::vector<float> realOut; 36 /** The imaginary part of the output */ 37 std::vector<float> imagOut; 38 39 FftParaAndResult() = default; FftParaAndResultFftParaAndResult40 explicit FftParaAndResult(int32_t size) 41 { 42 numSamples = size; 43 realIn.resize(size, 0.0F); 44 imagIn.resize(size, 0.0F); 45 realOut.resize(size, 0.0F); 46 imagOut.resize(size, 0.0F); 47 } 48 }; 49 50 class Fft { 51 public: 52 Fft() = default; 53 ~Fft(); 54 55 void Init(int32_t fftSize); 56 57 std::vector<float> GetReal() const; 58 std::vector<float> GetImg() const; 59 60 /* Calculate the power spectrum */ 61 void CalcFFT(const std::vector<float> &data, const std::vector<float> &window); 62 void ConvertPolar(std::vector<float> &magnitude, std::vector<float> &phase); 63 void CalculatePowerSpectrum(const std::vector<float> &data, const std::vector<float> &window, 64 std::vector<float> &magnitude, std::vector<float> &phase); 65 /** the inverse */ 66 void ConvertCart(const std::vector<float> &magnitude, const std::vector<float> &phase); 67 void CalcIFFT(const std::vector<float> &window, std::vector<float> &finalOut); 68 void InverseFFTComplex(const std::vector<float> &window, const std::vector<float> &real, 69 const std::vector<float> &imaginary, std::vector<float> &finalOut); 70 void InversePowerSpectrum(const std::vector<float> &window, const std::vector<float> &magnitude, 71 const std::vector<float> &phase, std::vector<float> &finalOut); 72 void ConvertDB(const std::vector<float> &in, std::vector<float> &out); 73 int32_t GenWindow(int32_t whichFunction, int32_t numSamples, std::vector<float> &window); 74 75 private: 76 int32_t WindowFunc(int32_t whichFunction, int32_t numSamples, float *out); 77 uint32_t FastReverseBits(uint32_t pos, uint32_t numBits); 78 79 /** 80 * @brief Power Spectrum 81 * 82 * 1. This function computes the same as AlgRealFFT, above, but adds the squares of the real and imaginary part 83 * of each coefficient, extracting the power and throwing away the phase. 84 * 2. For speed, it does not call AlgRealFFT, but duplicates some of its code. 85 * 86 * @param numSamples Number of samples. 87 * @param in The part of the input. 88 * @param out The part of the output 89 * 90 * @return Returns <b>0</b> if the operation is successful; returns a negative value otherwise. 91 */ 92 int32_t AlgPowerSpectrum(int32_t numSamples, const std::vector<float> &in, std::vector<float> &out); 93 94 /** 95 * @brief Real Fast Fourier Transform 96 * 97 * 1. This function was based on the code in Numerical Recipes in C. 98 * 2.In Num. Rec., the inner loop is based on a single 1-based array of interleaved real and imaginary numbers. 99 * Because we have two separate zero-based arrays, our indices are quite different. 100 * 3. Here is the correspondence between Num. Rec. 101 * 102 * @return Returns <b>0</b> if the operation is successful; returns a negative value otherwise. 103 */ 104 int32_t AlgRealFFT(FftParaAndResult ¶Res); 105 int32_t AlgFFT(bool inverseTransform, FftParaAndResult ¶Res); 106 int32_t AlgInitFFT(); 107 108 private: 109 /** fftSize */ 110 int32_t fftSize_ { 0 }; 111 /** halfFFTSize */ 112 int32_t half_ { 0 }; 113 114 FftParaAndResult fftParaRes_; 115 /** 116 * 'para_' needs to be created every time the sfft occurs, so it is created once during initialization. 117 * It's half the size of fftParaRes_, only used in one function. 118 */ 119 FftParaAndResult para_; 120 uint32_t** fftBitTable_ { nullptr }; 121 }; 122 } // namespace Sensors 123 } // namespace OHOS 124 #endif // FFT_H