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