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