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