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
18 #include "intell_voice_log.h"
19 #include "string_util.h"
20 #include "scope_guard.h"
21 #include "engine_host_manager.h"
22 #include "trigger_manager.h"
23 #include "intell_voice_service_manager.h"
24
25 #define LOG_TAG "EngineUtils"
26
27 using namespace OHOS::IntellVoiceUtils;
28 using namespace OHOS::HDI::IntelligentVoice::Engine::V1_0;
29 using namespace OHOS::IntellVoiceTrigger;
30
31 namespace OHOS {
32 namespace IntellVoiceEngine {
33 static const std::string KEY_GET_WAKEUP_FEATURE = "wakeup_features";
34 static const std::string LANGUAGE_TEXT = "language=";
35 static const std::string AREA_TEXT = "area=";
36 static const std::string SENSIBILITY_TEXT = "sensibility=";
37
EngineUtil()38 EngineUtil::EngineUtil()
39 {
40 desc_.adapterType = ADAPTER_TYPE_BUT;
41 }
42
SetParameter(const std::string & keyValueList)43 int32_t EngineUtil::SetParameter(const std::string &keyValueList)
44 {
45 if (adapter_ == nullptr) {
46 INTELL_VOICE_LOG_ERROR("adapter is nullptr");
47 return -1;
48 }
49 return adapter_->SetParameter(keyValueList);
50 }
51
GetParameter(const std::string & key)52 std::string EngineUtil::GetParameter(const std::string &key)
53 {
54 if (adapter_ == nullptr) {
55 INTELL_VOICE_LOG_ERROR("adapter is nullptr");
56 return "";
57 }
58
59 std::string value;
60 adapter_->GetParameter(key, value);
61 return value;
62 }
63
WriteAudio(const uint8_t * buffer,uint32_t size)64 int32_t EngineUtil::WriteAudio(const uint8_t *buffer, uint32_t size)
65 {
66 if (adapter_ == nullptr) {
67 INTELL_VOICE_LOG_ERROR("adapter is nullptr");
68 return -1;
69 }
70
71 if (buffer == nullptr || size == 0) {
72 INTELL_VOICE_LOG_ERROR("buffer is invalid, size:%{public}u", size);
73 return -1;
74 }
75
76 std::vector<uint8_t> audioBuff(&buffer[0], &buffer[size]);
77 return adapter_->WriteAudio(audioBuff);
78 }
79
Stop()80 int32_t EngineUtil::Stop()
81 {
82 if (adapter_ == nullptr) {
83 INTELL_VOICE_LOG_ERROR("adapter is nullptr");
84 return -1;
85 }
86 return adapter_->Stop();
87 }
88
GetWakeupPcm(std::vector<uint8_t> & data)89 int32_t EngineUtil::GetWakeupPcm(std::vector<uint8_t> &data)
90 {
91 if (adapter_ == nullptr) {
92 INTELL_VOICE_LOG_ERROR("adapter is nullptr");
93 return -1;
94 }
95 return adapter_->GetWakeupPcm(data);
96 }
97
Evaluate(const std::string & word,EvaluationResultInfo & info)98 int32_t EngineUtil::Evaluate(const std::string &word, EvaluationResultInfo &info)
99 {
100 if (adapter_ == nullptr) {
101 INTELL_VOICE_LOG_ERROR("adapter is nullptr");
102 return -1;
103 }
104
105 return adapter_->Evaluate(word, info);
106 }
107
SetDspFeatures()108 bool EngineUtil::SetDspFeatures()
109 {
110 if (adapter_ == nullptr) {
111 INTELL_VOICE_LOG_ERROR("adapter is nullptr");
112 return false;
113 }
114
115 auto triggerMgr = TriggerManager::GetInstance();
116 if (triggerMgr == nullptr) {
117 INTELL_VOICE_LOG_ERROR("trigger manager is nullptr");
118 return false;
119 }
120
121 std::string features = triggerMgr->GetParameter(KEY_GET_WAKEUP_FEATURE);
122 if (features == "") {
123 INTELL_VOICE_LOG_WARN("failed to get wakeup dsp feature");
124 features = HistoryInfoMgr::GetInstance().GetWakeupDspFeature();
125 if (features == "") {
126 INTELL_VOICE_LOG_WARN("no historical wakeup dsp feature");
127 return false;
128 }
129 } else {
130 HistoryInfoMgr::GetInstance().SetWakeupDspFeature(features);
131 }
132
133 std::string kvPair = KEY_GET_WAKEUP_FEATURE + "=" + features;
134 adapter_->SetParameter(kvPair);
135 return true;
136 }
137
WriteBufferFromAshmem(uint8_t * & buffer,uint32_t size,sptr<OHOS::Ashmem> ashmem)138 void EngineUtil::WriteBufferFromAshmem(uint8_t *&buffer, uint32_t size, sptr<OHOS::Ashmem> ashmem)
139 {
140 if (!ashmem->MapReadOnlyAshmem()) {
141 INTELL_VOICE_LOG_ERROR("map ashmem failed");
142 return;
143 }
144
145 const uint8_t *tmpBuffer = static_cast<const uint8_t *>(ashmem->ReadFromAshmem(size, 0));
146 if (tmpBuffer == nullptr) {
147 INTELL_VOICE_LOG_ERROR("read from ashmem failed");
148 return;
149 }
150
151 buffer = new (std::nothrow) uint8_t[size];
152 if (buffer == nullptr) {
153 INTELL_VOICE_LOG_ERROR("allocate buffer failed");
154 return;
155 }
156
157 if (memcpy_s(buffer, size, tmpBuffer, size) != 0) {
158 INTELL_VOICE_LOG_ERROR("memcpy_s failed");
159 return;
160 }
161 }
162
ProcDspModel(OHOS::HDI::IntelligentVoice::Engine::V1_0::ContentType type)163 void EngineUtil::ProcDspModel(OHOS::HDI::IntelligentVoice::Engine::V1_0::ContentType type)
164 {
165 INTELL_VOICE_LOG_INFO("enter");
166 uint8_t *buffer = nullptr;
167 uint32_t size = 0;
168 sptr<Ashmem> ashmem;
169 adapter_->Read(type, ashmem);
170 if (ashmem == nullptr) {
171 INTELL_VOICE_LOG_ERROR("ashmem is nullptr");
172 return;
173 }
174
175 ON_SCOPE_EXIT_WITH_NAME(ashmemExit)
176 {
177 INTELL_VOICE_LOG_DEBUG("close ashmem");
178 ashmem->UnmapAshmem();
179 ashmem->CloseAshmem();
180 };
181
182 size = static_cast<uint32_t>(ashmem->GetAshmemSize());
183 if (size == 0) {
184 INTELL_VOICE_LOG_ERROR("size is zero");
185 return;
186 }
187
188 WriteBufferFromAshmem(buffer, size, ashmem);
189 if (buffer == nullptr) {
190 INTELL_VOICE_LOG_ERROR("buffer is nullptr");
191 return;
192 }
193
194 ON_SCOPE_EXIT_WITH_NAME(bufferExit)
195 {
196 INTELL_VOICE_LOG_DEBUG("now delete buffer");
197 delete[] buffer;
198 buffer = nullptr;
199 };
200
201 std::shared_ptr<GenericTriggerModel> model = std::make_shared<GenericTriggerModel>(VOICE_WAKEUP_MODEL_UUID,
202 TriggerModel::TriggerModelVersion::MODLE_VERSION_2, TriggerModel::TriggerModelType::VOICE_WAKEUP_TYPE);
203 if (model == nullptr) {
204 INTELL_VOICE_LOG_ERROR("model is null");
205 return;
206 }
207 model->SetData(buffer, size);
208 auto triggerMgr = TriggerManager::GetInstance();
209 if (triggerMgr == nullptr) {
210 INTELL_VOICE_LOG_ERROR("trigger manager is nullptr");
211 return;
212 }
213 triggerMgr->UpdateModel(model);
214 }
215
SetLanguage()216 void EngineUtil::SetLanguage()
217 {
218 if (adapter_ == nullptr) {
219 INTELL_VOICE_LOG_ERROR("adapter is nullptr");
220 return;
221 }
222
223 std::string language = HistoryInfoMgr::GetInstance().GetLanguage();
224 if (language.empty()) {
225 INTELL_VOICE_LOG_WARN("language is empty");
226 return;
227 }
228 adapter_->SetParameter(LANGUAGE_TEXT + language);
229 }
230
SetArea()231 void EngineUtil::SetArea()
232 {
233 if (adapter_ == nullptr) {
234 INTELL_VOICE_LOG_ERROR("adapter is nullptr");
235 return;
236 }
237
238 std::string area = HistoryInfoMgr::GetInstance().GetArea();
239 if (area.empty()) {
240 INTELL_VOICE_LOG_WARN("area is empty");
241 return;
242 }
243
244 adapter_->SetParameter(AREA_TEXT + area);
245 }
246
SetSensibility()247 void EngineUtil::SetSensibility()
248 {
249 if (adapter_ == nullptr) {
250 INTELL_VOICE_LOG_ERROR("adapter is nullptr");
251 return;
252 }
253
254 std::string sensibility = HistoryInfoMgr::GetInstance().GetSensibility();
255 if (sensibility.empty()) {
256 INTELL_VOICE_LOG_WARN("sensibility is empty");
257 return;
258 }
259
260 auto &mgr = IntellVoiceServiceManager::GetInstance();
261 if (mgr != nullptr) {
262 mgr->SetDspSensibility(sensibility);
263 }
264
265 adapter_->SetParameter(SENSIBILITY_TEXT + sensibility);
266 }
267 }
268 }
269