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 CONVERSION_UTILS_H
17 #define CONVERSION_UTILS_H
18 
19 #include <cfloat>
20 #include <cmath>
21 #include <functional>
22 #include <numeric>
23 #include <vector>
24 
25 namespace OHOS {
26 namespace Sensors {
27 namespace {
28 constexpr double MIN_LOG_HZ = 1000.0;
29 constexpr double MIN_LOG_MEL = 15.0;
30 constexpr double FSP = 66.6666666667;
31 constexpr double MIN_F = 0.0;
32 constexpr double LOG_STEP = 0.06875177742094912;
33 constexpr double MAXFRE = 8000.0;
34 constexpr double HZ_COEF = 700.0;
35 constexpr double MEL_COEF = 2595.0;
36 constexpr int32_t LOG_BASE = 10;
37 constexpr double EPS_MIN = 1e-10;
38 constexpr int32_t NFFT = 2048;
39 constexpr int32_t ONSET_HOP_LEN = 512;
40 constexpr int32_t ENERGY_HOP_LEN = 1024;
41 constexpr int32_t WINDOW_LENGTH = ENERGY_HOP_LEN / 2;
42 constexpr int32_t MAGS_SIZE = NFFT / 2;
43 constexpr int32_t SAMPLE_RATE = 22050;
44 constexpr int32_t FRM_LEN = 2048;
45 constexpr double F_HALF = 0.5;
46 constexpr double F_THREE = 3.0;
47 constexpr double SAMPLE_IN_MS = 1000.0;
48 constexpr double INTERSITY_BOUNDARY_POINT = 0.25;
49 constexpr double INTERSITY_NUMBER_BOUNDARY_POINT = 0.75;
50 } // namespace
51 
52 enum WindowType {
53     WND_TYPE_BARTLETT = 1,
54     WND_TYPE_HAMMING = 2,
55     WND_TYPE_HANNING = 3,
56 };
57 
58 enum FilterMethod{
59     LOW_RESONANT_FILTER = 1,
60     HIGH_RESONANT_FILTER = 2,
61     BAND_PASS_FILTER = 3,
62 };
63 
64 bool IsPowerOfTwo(uint32_t x);
65 uint32_t ObtainNumberOfBits(uint32_t powerOfTwo);
66 uint32_t ReverseBits(uint32_t index, uint32_t numBits);
67 
68 /**
69  * @brief Matrix transpose
70  *
71  * @param rows Number of rows
72  * @param values Matrix
73  *
74  * @return Returns the transposed matrix.
75  */
76 std::vector<double> TransposeMatrix(size_t rows, const std::vector<double> &values);
77 
78 /**
79  * @brief Make ID unique
80  *  idx and time appear in pairs
81  *
82  * @param idx Original series indexs.
83  * @param time Original series times.
84  * @param newIdx Processed indexs.
85  * @param newTime Processed times.
86  *
87  * @return Returns <b>0</b> if the operation is successful; returns a negative value otherwise.
88  */
89 int32_t UniqueIdx(const std::vector<int32_t> &idx, const std::vector<double> &time, std::vector<int32_t> &newIdx,
90     std::vector<double> &newTime);
91 
92 /**
93  * @brief Find the minimum and maximum in Orignal 'values', convert the values into numbers ranging from 0 to 100.
94  *
95  * @param values Original values
96  *
97  * @return Return the numbers ranging from 0 to 100.
98  */
99 std::vector<int32_t> NormalizePercentage(const std::vector<double> &values);
100 
101 /**
102  * @brief The minimum is 0, convert the values into numbers ranging from 0 to 100.
103  *
104  * @param values Original values
105  *
106  * @return Return the numbers ranging from 0 to 100.
107  */
108 std::vector<int32_t> NormalizePercentageMin(const std::vector<double> &values);
109 
110 /**
111  * @brief Based on the given minimum and maximum range, convert the values into numbers ranging from 0 to 100.
112  *
113  * @param values Original values
114  * @param minValue The minimum of range.
115  * @param maxValue The maximum of range.
116  *
117  * @return Return the numbers ranging from 0 to 100.
118  */
119 std::vector<int32_t> NormalizePercentageRange(const std::vector<double> &values, double minValue, double maxValue);
120 
121 /**
122  * @brief Processing of effective values for filling in mute positions.
123  *
124  * @param values A set of volume(DB or HZ) values.
125  * @param voiceFlag A set of voice and mute flags.
126  * @param volumeData A set of volume values.
127  * @param invalidValues Processed result, include valid values only.
128  *
129  * @return Returns <b>0</b> if the operation is successful; returns a negative value otherwise.
130  */
131 int32_t ProcessSilence(const std::vector<double> &values, const std::vector<bool> &voiceFlag,
132     const std::vector<int32_t> &volumeData, std::vector<double> &invalidValues);
133 
134 /**
135  * @brief Small window amplitude envelope.
136  *
137  * @param data Audio time series.
138  * @param count length of analysis frame (in samples) for energy calculation
139  * @param hopLength Hop length
140  *
141  * @return Returns amplitude value for each frame
142  */
143 std::vector<double> ObtainAmplitudeEnvelop(const std::vector<double> &data, size_t count, size_t hopLength);
144 
ConvertSlaneyMel(double hz)145 inline double ConvertSlaneyMel(double hz)
146 {
147     return MEL_COEF * (log10(hz / HZ_COEF + 1.0));
148 }
149 
ConvertSlaneyHz(double mel)150 inline double ConvertSlaneyHz(double mel)
151 {
152     return HZ_COEF * (pow(LOG_BASE, mel / MEL_COEF) - 1.0);
153 }
154 
155 template<typename T>
IsLessOrEqual(const T & left,const T & right)156 inline bool IsLessOrEqual(const T& left, const T& right)
157 {
158     return (left - right) < std::numeric_limits<T>::epsilon();
159 }
160 
161 template<typename T>
IsGreatOrEqual(const T & left,const T & right)162 inline bool IsGreatOrEqual(const T& left, const T& right)
163 {
164     return (left - right) > -std::numeric_limits<T>::epsilon();
165 }
166 
167 template<typename T>
IsLessNotEqual(const T & left,const T & right)168 inline bool IsLessNotEqual(const T& left, const T& right)
169 {
170     return (left - right) < -std::numeric_limits<T>::epsilon();
171 }
172 
173 template<typename T>
IsGreatNotEqual(const T & left,const T & right)174 inline bool IsGreatNotEqual(const T& left, const T& right)
175 {
176     return (left - right) > std::numeric_limits<T>::epsilon();
177 }
178 
179 template<typename T>
IsEqual(const T & left,const T & right)180 inline bool IsEqual(const T& left, const T& right)
181 {
182     return (std::abs(left - right) <= std::numeric_limits<T>::epsilon());
183 }
184 
ConvertHtkMel(double frequencies)185 inline double ConvertHtkMel(double frequencies)
186 {
187     double mels = (frequencies - MIN_F) / FSP;
188     if (IsGreatOrEqual(frequencies, MIN_LOG_HZ)) {
189         mels = (MIN_LOG_HZ - MIN_F) / FSP + log(frequencies / MIN_LOG_HZ) / LOG_STEP;
190     }
191     return mels;
192 }
193 
ConvertHtkHz(double mels)194 inline double ConvertHtkHz(double mels)
195 {
196     double freqs = MIN_F + FSP * mels;
197     if (IsGreatOrEqual(mels, MIN_LOG_MEL)) {
198         freqs = MIN_LOG_HZ * exp(LOG_STEP * (mels - MIN_LOG_MEL));
199     }
200     return freqs;
201 }
202 } // namespace Sensors
203 } // namespace OHOS
204 #endif // CONVERSION_UTILS_H