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