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 #include "utils.h"
17
18 #include <algorithm>
19 #include <cmath>
20 #include <cstdlib>
21 #include <cstring>
22 #include <fstream>
23 #include <iterator>
24 #include <numeric>
25
26 #include <unistd.h>
27
28 #include "sensor_log.h"
29 #include "sensors_errors.h"
30
31 #undef LOG_TAG
32 #define LOG_TAG "Utils"
33
34 namespace OHOS {
35 namespace Sensors {
36 namespace {
37 constexpr double PERCENTAGE_RANGE = 100.0;
38 constexpr int32_t VOICE_MIN_INTENSITY_NORM = 25;
39 constexpr size_t MAX_SIZE = 26460000;
40 } // namespace
41
IsPowerOfTwo(uint32_t x)42 bool IsPowerOfTwo(uint32_t x)
43 {
44 if ((x & (x - 1)) || (x < 2)) {
45 return false;
46 }
47 return true;
48 }
49
ObtainNumberOfBits(uint32_t powerOfTwo)50 uint32_t ObtainNumberOfBits(uint32_t powerOfTwo)
51 {
52 if (powerOfTwo < 2) {
53 SEN_HILOGE("powerOfTwo is an invalid value");
54 return 0;
55 }
56 for (uint32_t i = 0;; i++) {
57 if (powerOfTwo & (1 << i)) {
58 return i;
59 }
60 }
61 return 0;
62 }
63
ReverseBits(uint32_t index,uint32_t numBits)64 uint32_t ReverseBits(uint32_t index, uint32_t numBits)
65 {
66 uint32_t rev = 0;
67 for (uint32_t i = 0; i < numBits; i++) {
68 rev = (rev << 1) | (index & 1);
69 index >>= 1;
70 }
71 return rev;
72 }
73
TransposeMatrix(size_t rows,const std::vector<double> & values)74 std::vector<double> TransposeMatrix(size_t rows, const std::vector<double> &values)
75 {
76 CALL_LOG_ENTER;
77 size_t valuesSize = values.size();
78 SEN_HILOGD("valuesSize:%{public}zu", valuesSize);
79 if ((rows == 0) || (valuesSize == 0) || (valuesSize > MAX_SIZE)) {
80 SEN_HILOGE("Parameter error");
81 return {};
82 }
83 std::vector<double> dst(valuesSize, 0.0);
84 size_t cols = valuesSize / rows;
85 size_t index = 0;
86 if ((((cols - 1) * rows) + (rows - 1)) >= valuesSize) {
87 SEN_HILOGE("dst cross-border access");
88 return {};
89 }
90 for (size_t i = 0; i < rows; i++) {
91 for (size_t j = 0; j < cols; j++) {
92 dst[j * rows + i] = values[index++];
93 }
94 }
95 return dst;
96 }
97
UniqueIdx(const std::vector<int32_t> & idx,const std::vector<double> & time,std::vector<int32_t> & newIdx,std::vector<double> & newTime)98 int32_t UniqueIdx(const std::vector<int32_t> &idx, const std::vector<double> &time, std::vector<int32_t> &newIdx,
99 std::vector<double> &newTime)
100 {
101 CALL_LOG_ENTER;
102 if (idx.size() != time.size()) {
103 SEN_HILOGE("size of idx and time vectors not equal");
104 return Sensors::ERROR;
105 }
106 int32_t oldIdxLen = static_cast<int32_t>(idx.size());
107 int32_t idxLen = oldIdxLen;
108 if (idxLen < 1) {
109 return Sensors::SUCCESS;
110 }
111 newIdx = idx;
112 newTime = time;
113 int32_t preIdx = newIdx[0];
114 int32_t i = 1;
115 while (i < idxLen) {
116 if (newIdx[i] == preIdx) {
117 newIdx.erase(newIdx.begin() + i);
118 newTime.erase(newTime.begin() + i);
119 --i;
120 --idxLen;
121 }
122 preIdx = newIdx[i];
123 ++i;
124 }
125 if (idxLen != oldIdxLen) {
126 SEN_HILOGI("Idx unique process");
127 }
128 return Sensors::SUCCESS;
129 }
130
NormalizePercentage(const std::vector<double> & values)131 std::vector<int32_t> NormalizePercentage(const std::vector<double> &values)
132 {
133 CALL_LOG_ENTER;
134 double minValue = *min_element(values.begin(), values.end());
135 double maxValue = *max_element(values.begin(), values.end());
136 double range = maxValue - minValue;
137 if (IsLessNotEqual(range, EPS_MIN)) {
138 SEN_HILOGE("range is less than EPS_MIN");
139 return {};
140 }
141 std::vector<int32_t> norm;
142 for (size_t i = 0; i < values.size(); i++) {
143 norm.push_back(static_cast<int32_t>(round((values[i] - minValue) / range * PERCENTAGE_RANGE)));
144 }
145 return norm;
146 }
147
NormalizePercentageMin(const std::vector<double> & values)148 std::vector<int32_t> NormalizePercentageMin(const std::vector<double> &values)
149 {
150 CALL_LOG_ENTER;
151 std::vector<double> trimValues = values;
152 for (size_t i = 0; i < trimValues.size(); i++) {
153 if (IsLessNotEqual(trimValues[i], 0.0)) {
154 trimValues[i] = 0.0;
155 }
156 }
157 double minValue = 0.0;
158 double maxValue = *max_element(trimValues.begin(), trimValues.end());
159 double range = maxValue - minValue;
160 if (IsLessNotEqual(range, EPS_MIN)) {
161 SEN_HILOGE("range is less than EPS_MIN");
162 return {};
163 }
164 std::vector<int32_t> normValues;
165 for (size_t i = 0; i < trimValues.size(); i++) {
166 normValues.push_back(static_cast<int32_t>(round((values[i] - minValue) / range * PERCENTAGE_RANGE)));
167 }
168 return normValues;
169 }
170
NormalizePercentageRange(const std::vector<double> & values,double minValue,double maxValue)171 std::vector<int32_t> NormalizePercentageRange(const std::vector<double> &values, double minValue, double maxValue)
172 {
173 CALL_LOG_ENTER;
174 std::vector<double> trimValues = values;
175 std::vector<int32_t> norm;
176 for (size_t i = 0; i < trimValues.size(); i++) {
177 if (IsLessNotEqual(trimValues[i], minValue)) {
178 trimValues[i] = minValue;
179 }
180 if (IsGreatNotEqual(trimValues[i], maxValue)) {
181 trimValues[i] = maxValue;
182 }
183 }
184 double range = maxValue - minValue;
185 if (IsLessNotEqual(range, EPS_MIN)) {
186 SEN_HILOGE("range is less than EPS_MIN");
187 return {};
188 }
189 for (size_t i = 0; i < trimValues.size(); i++) {
190 norm.push_back(static_cast<int32_t>(round((values[i] - minValue) / range * PERCENTAGE_RANGE)));
191 }
192 return norm;
193 }
194
ProcessSilence(const std::vector<double> & values,const std::vector<bool> & voiceFlag,const std::vector<int32_t> & volumeData,std::vector<double> & invalidValues)195 int32_t ProcessSilence(const std::vector<double> &values, const std::vector<bool> &voiceFlag,
196 const std::vector<int32_t> &volumeData, std::vector<double> &invalidValues)
197 {
198 CALL_LOG_ENTER;
199 std::vector<bool> flag;
200 if (!volumeData.empty()) {
201 for (size_t i = 0; i < volumeData.size(); i++) {
202 if (volumeData[i] > VOICE_MIN_INTENSITY_NORM) {
203 flag.push_back(true);
204 } else {
205 flag.push_back(false);
206 }
207 }
208 } else {
209 if (voiceFlag.size() < 1) {
210 SEN_HILOGE("The voice flag do not preprocess");
211 return Sensors::ERROR;
212 }
213 flag = voiceFlag;
214 }
215 invalidValues = values;
216 double preUnzero = -1;
217 bool bExist = false;
218 for (size_t j = 0; j < invalidValues.size(); j++) {
219 if (flag[j]) {
220 preUnzero = invalidValues[j];
221 bExist = true;
222 break;
223 }
224 }
225 if (bExist) {
226 for (size_t k = 0; k < invalidValues.size(); k++) {
227 if (!flag[k]) {
228 invalidValues[k] = preUnzero;
229 } else {
230 preUnzero = invalidValues[k];
231 }
232 }
233 } else {
234 SEN_HILOGI("The audio is silence");
235 }
236 return Sensors::SUCCESS;
237 }
238
ObtainAmplitudeEnvelop(const std::vector<double> & data,size_t count,size_t hopLength)239 std::vector<double> ObtainAmplitudeEnvelop(const std::vector<double> &data, size_t count, size_t hopLength)
240 {
241 CALL_LOG_ENTER;
242 if (data.empty() || (data.size() < count)) {
243 SEN_HILOGE("data is empty or data is less than count");
244 return {};
245 }
246 std::vector<double> absData;
247 for (size_t i = 0; i < data.size(); i++) {
248 absData.push_back(fabs(data[i]));
249 }
250 std::vector<double> partAmplitude;
251 std::vector<double> enery;
252 std::vector<double>::iterator it = absData.begin();
253 double accum = 0.0;
254 for (size_t j = 0; j < (data.size() - count);) {
255 partAmplitude.assign(it + j, it + j + count);
256 accum = accumulate(partAmplitude.begin(), partAmplitude.end(), 0);
257 enery.push_back(accum);
258 j += hopLength;
259 }
260 return enery;
261 }
262 } // namespace Sensors
263 } // namespace OHOS