1 /*
2 * Copyright (c) 2024 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 #include "engine_util.h"
16 #include <ashmem.h>
17 #include "intell_voice_log.h"
18 #include "string_util.h"
19 #include "scope_guard.h"
20 #include "engine_host_manager.h"
21 #include "engine_callback_message.h"
22 #include "intell_voice_engine_manager.h"
23 #include "history_info_mgr.h"
24 #include "intell_voice_definitions.h"
25 #include "intell_voice_sensibility.h"
26
27 #define LOG_TAG "EngineUtils"
28
29 using namespace OHOS::IntellVoiceUtils;
30 using namespace OHOS::HDI::IntelligentVoice::Engine::V1_0;
31 using namespace OHOS::AudioStandard;
32
33 namespace OHOS {
34 namespace IntellVoiceEngine {
35 static const std::string LANGUAGE_TEXT = "language=";
36 static const std::string AREA_TEXT = "area=";
37 static const int32_t INTELL_VOICE_SERVICE_UID = 1042;
38
EngineUtil()39 EngineUtil::EngineUtil()
40 {
41 desc_.adapterType = ADAPTER_TYPE_BUT;
42 }
43
SetParameter(const std::string & keyValueList)44 int32_t EngineUtil::SetParameter(const std::string &keyValueList)
45 {
46 if (adapter_ == nullptr) {
47 INTELL_VOICE_LOG_ERROR("adapter is nullptr");
48 return -1;
49 }
50 return adapter_->SetParameter(keyValueList);
51 }
52
GetParameter(const std::string & key)53 std::string EngineUtil::GetParameter(const std::string &key)
54 {
55 if (adapter_ == nullptr) {
56 INTELL_VOICE_LOG_ERROR("adapter is nullptr");
57 return "";
58 }
59
60 std::string value;
61 adapter_->GetParameter(key, value);
62 return value;
63 }
64
WriteAudio(const uint8_t * buffer,uint32_t size)65 int32_t EngineUtil::WriteAudio(const uint8_t *buffer, uint32_t size)
66 {
67 if (adapter_ == nullptr) {
68 INTELL_VOICE_LOG_ERROR("adapter is nullptr");
69 return -1;
70 }
71
72 if (buffer == nullptr || size == 0) {
73 INTELL_VOICE_LOG_ERROR("buffer is invalid, size:%{public}u", size);
74 return -1;
75 }
76
77 std::vector<uint8_t> audioBuff(&buffer[0], &buffer[size]);
78 return adapter_->WriteAudio(audioBuff);
79 }
80
Stop()81 int32_t EngineUtil::Stop()
82 {
83 if (adapter_ == nullptr) {
84 INTELL_VOICE_LOG_ERROR("adapter is nullptr");
85 return -1;
86 }
87 return adapter_->Stop();
88 }
89
GetWakeupPcm(std::vector<uint8_t> & data)90 int32_t EngineUtil::GetWakeupPcm(std::vector<uint8_t> &data)
91 {
92 if (adapter_ == nullptr) {
93 INTELL_VOICE_LOG_ERROR("adapter is nullptr");
94 return -1;
95 }
96 return adapter_->GetWakeupPcm(data);
97 }
98
Evaluate(const std::string & word,EvaluationResultInfo & info)99 int32_t EngineUtil::Evaluate(const std::string &word, EvaluationResultInfo &info)
100 {
101 if (adapter_ == nullptr) {
102 INTELL_VOICE_LOG_ERROR("adapter is nullptr");
103 return -1;
104 }
105
106 return adapter_->Evaluate(word, info);
107 }
108
SetDspFeatures()109 bool EngineUtil::SetDspFeatures()
110 {
111 if (adapter_ == nullptr) {
112 INTELL_VOICE_LOG_ERROR("adapter is nullptr");
113 return false;
114 }
115
116 auto ret = EngineCallbackMessage::CallFunc(TRIGGERMGR_GET_PARAMETER, KEY_GET_WAKEUP_FEATURE);
117 std::string features = "";
118 if (ret.has_value()) {
119 try {
120 features = std::any_cast<std::string>(*ret);
121 } catch (const std::bad_any_cast&) {
122 INTELL_VOICE_LOG_ERROR("msg bus bad any cast");
123 return false;
124 }
125 } else {
126 INTELL_VOICE_LOG_ERROR("msg bus return no value");
127 return false;
128 }
129
130 if (features == "") {
131 INTELL_VOICE_LOG_WARN("failed to get wakeup dsp feature");
132 features = HistoryInfoMgr::GetInstance().GetStringKVPair(KEY_WAKEUP_DSP_FEATURE);
133 if (features == "") {
134 INTELL_VOICE_LOG_WARN("no historical wakeup dsp feature");
135 return false;
136 }
137 } else {
138 HistoryInfoMgr::GetInstance().SetStringKVPair(KEY_WAKEUP_DSP_FEATURE, features);
139 }
140
141 std::string kvPair = KEY_GET_WAKEUP_FEATURE + "=" + features;
142 adapter_->SetParameter(kvPair);
143 return true;
144 }
145
WriteBufferFromAshmem(uint8_t * & buffer,uint32_t size,sptr<OHOS::Ashmem> ashmem)146 void EngineUtil::WriteBufferFromAshmem(uint8_t *&buffer, uint32_t size, sptr<OHOS::Ashmem> ashmem)
147 {
148 if (!ashmem->MapReadOnlyAshmem()) {
149 INTELL_VOICE_LOG_ERROR("map ashmem failed");
150 return;
151 }
152
153 const uint8_t *tmpBuffer = static_cast<const uint8_t *>(ashmem->ReadFromAshmem(size, 0));
154 if (tmpBuffer == nullptr) {
155 INTELL_VOICE_LOG_ERROR("read from ashmem failed");
156 return;
157 }
158
159 buffer = new (std::nothrow) uint8_t[size];
160 if (buffer == nullptr) {
161 INTELL_VOICE_LOG_ERROR("allocate buffer failed");
162 return;
163 }
164
165 if (memcpy_s(buffer, size, tmpBuffer, size) != 0) {
166 INTELL_VOICE_LOG_ERROR("memcpy_s failed");
167 return;
168 }
169 }
170
ReadDspModel(OHOS::HDI::IntelligentVoice::Engine::V1_0::ContentType type)171 std::vector<uint8_t> EngineUtil::ReadDspModel(
172 OHOS::HDI::IntelligentVoice::Engine::V1_0::ContentType type)
173 {
174 INTELL_VOICE_LOG_INFO("enter");
175 uint8_t *buffer = nullptr;
176 uint32_t size = 0;
177 sptr<Ashmem> ashmem = nullptr;
178 std::vector<uint8_t> ret;
179
180 if (adapter_ == nullptr) {
181 INTELL_VOICE_LOG_ERROR("adapter is nullptr");
182 return ret;
183 }
184 adapter_->Read(type, ashmem);
185 if (ashmem == nullptr) {
186 INTELL_VOICE_LOG_ERROR("ashmem is nullptr");
187 return ret;
188 }
189
190 ON_SCOPE_EXIT_WITH_NAME(ashmemExit)
191 {
192 INTELL_VOICE_LOG_DEBUG("close ashmem");
193 ashmem->UnmapAshmem();
194 ashmem->CloseAshmem();
195 };
196
197 size = static_cast<uint32_t>(ashmem->GetAshmemSize());
198 if (size == 0) {
199 INTELL_VOICE_LOG_ERROR("size is zero");
200 return ret;
201 }
202
203 WriteBufferFromAshmem(buffer, size, ashmem);
204 if (buffer == nullptr) {
205 INTELL_VOICE_LOG_ERROR("buffer is nullptr");
206 return ret;
207 }
208
209 ON_SCOPE_EXIT_WITH_NAME(bufferExit)
210 {
211 INTELL_VOICE_LOG_DEBUG("now delete buffer");
212 delete[] buffer;
213 buffer = nullptr;
214 };
215 ret.insert(ret.end(), buffer, buffer + size);
216 return ret;
217 }
218
ProcDspModel(const std::vector<uint8_t> & buffer)219 void EngineUtil::ProcDspModel(const std::vector<uint8_t> &buffer)
220 {
221 if (buffer.empty()) {
222 INTELL_VOICE_LOG_ERROR("vector is empty");
223 return;
224 }
225 EngineCallbackMessage::CallFunc(TRIGGERMGR_UPDATE_MODEL, buffer, VOICE_WAKEUP_MODEL_UUID,
226 IntellVoiceTrigger::TriggerModelType::VOICE_WAKEUP_TYPE);
227 }
228
SetLanguage()229 void EngineUtil::SetLanguage()
230 {
231 if (adapter_ == nullptr) {
232 INTELL_VOICE_LOG_ERROR("adapter is nullptr");
233 return;
234 }
235
236 std::string language = HistoryInfoMgr::GetInstance().GetStringKVPair(KEY_LANGUAGE);
237 if (language.empty()) {
238 INTELL_VOICE_LOG_WARN("language is empty");
239 return;
240 }
241 adapter_->SetParameter(LANGUAGE_TEXT + language);
242 }
243
SetWhisperVpr()244 void EngineUtil::SetWhisperVpr()
245 {
246 if (adapter_ == nullptr) {
247 INTELL_VOICE_LOG_ERROR("adapter is nullptr");
248 return;
249 }
250 adapter_->SetParameter("WhisperVpr=" + HistoryInfoMgr::GetInstance().GetStringKVPair(KEY_WHISPER_VPR));
251 }
252
SetArea()253 void EngineUtil::SetArea()
254 {
255 if (adapter_ == nullptr) {
256 INTELL_VOICE_LOG_ERROR("adapter is nullptr");
257 return;
258 }
259
260 std::string area = HistoryInfoMgr::GetInstance().GetStringKVPair(KEY_AREA);
261 if (area.empty()) {
262 INTELL_VOICE_LOG_WARN("area is empty");
263 return;
264 }
265
266 adapter_->SetParameter(AREA_TEXT + area);
267 }
268
SetSensibility()269 void EngineUtil::SetSensibility()
270 {
271 if (adapter_ == nullptr) {
272 INTELL_VOICE_LOG_ERROR("adapter is nullptr");
273 return;
274 }
275
276 std::string sensibility = HistoryInfoMgr::GetInstance().GetStringKVPair(KEY_SENSIBILITY);
277 if (sensibility.empty()) {
278 INTELL_VOICE_LOG_WARN("sensibility is empty");
279 return;
280 }
281
282 auto ret = EngineCallbackMessage::CallFunc(TRIGGERMGR_GET_PARAMETER, KEY_GET_WAKEUP_FEATURE);
283 std::string features = "";
284 if (ret.has_value()) {
285 try {
286 features = std::any_cast<std::string>(*ret);
287 } catch (const std::bad_any_cast&) {
288 INTELL_VOICE_LOG_ERROR("msg bus bad any cast");
289 return;
290 }
291 } else {
292 INTELL_VOICE_LOG_ERROR("msg bus return no value");
293 return;
294 }
295 auto value = IntellVoiceSensibility::GetDspSensibility(sensibility, features, WAKEUP_CONFIG_PATH);
296 if (value.empty()) {
297 INTELL_VOICE_LOG_ERROR("no sensibility value");
298 return;
299 }
300 EngineCallbackMessage::CallFunc(TRIGGERMGR_SET_PARAMETER, "WAKEUP_SENSIBILITY", value);
301 adapter_->SetParameter(SENSIBILITY_TEXT + sensibility);
302 }
303
SelectInputDevice(DeviceType type)304 void EngineUtil::SelectInputDevice(DeviceType type)
305 {
306 INTELL_VOICE_LOG_INFO("enter");
307 sptr<AudioCapturerFilter> audioCapturerFilter = new (std::nothrow) AudioCapturerFilter();
308 if (audioCapturerFilter == nullptr) {
309 INTELL_VOICE_LOG_ERROR("audioCapturerFilter is nullptr");
310 return;
311 }
312 audioCapturerFilter->uid = INTELL_VOICE_SERVICE_UID;
313 audioCapturerFilter->capturerInfo.sourceType = SourceType::SOURCE_TYPE_VOICE_RECOGNITION;
314 std::vector<std::shared_ptr<AudioDeviceDescriptor>> deviceDescriptorVector;
315 auto audioSystemManager = AudioSystemManager::GetInstance();
316 if (audioSystemManager == nullptr) {
317 INTELL_VOICE_LOG_ERROR("audioSystemManager is nullptr");
318 return;
319 }
320 auto audioDeviceDescriptors = audioSystemManager->GetDevices(DeviceFlag::INPUT_DEVICES_FLAG);
321 for (int i = 0; i < audioDeviceDescriptors.size(); i++) {
322 if (audioDeviceDescriptors[i]->deviceType_ == type) {
323 deviceDescriptorVector.push_back(audioDeviceDescriptors[i]);
324 }
325 }
326 audioSystemManager->SelectInputDevice(audioCapturerFilter, deviceDescriptorVector);
327 }
328
SetScreenStatus()329 void EngineUtil::SetScreenStatus()
330 {
331 if (IntellVoiceEngineManager::GetScreenOff()) {
332 SetParameter("screenoff=true");
333 } else {
334 SetParameter("screenoff=false");
335 }
336 }
337
SetImproveParam()338 void EngineUtil::SetImproveParam()
339 {
340 if (adapter_ == nullptr) {
341 INTELL_VOICE_LOG_ERROR("adapter is nullptr");
342 return;
343 }
344
345 adapter_->SetParameter("userImproveOn=true");
346 }
347 }
348 }
349