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 "wakeup_engine_impl.h"
16 #include "audio_asr.h"
17 #include "audio_system_manager.h"
18 #include "v1_2/intell_voice_engine_types.h"
19 #include "adapter_callback_service.h"
20 #include "intell_voice_log.h"
21 #include "history_info_mgr.h"
22 #include "intell_voice_util.h"
23 #include "intell_voice_service_manager.h"
24 #include "trigger_manager.h"
25 #include "engine_host_manager.h"
26
27 #define LOG_TAG "WakeupEngineImpl"
28
29 using namespace OHOS::AudioStandard;
30 using namespace OHOS::HDI::IntelligentVoice::Engine::V1_0;
31 using namespace OHOS::IntellVoiceUtils;
32 using namespace OHOS::IntellVoiceTrigger;
33
34 namespace OHOS {
35 namespace IntellVoiceEngine {
36 static constexpr uint32_t MIN_BUFFER_SIZE = 640;
37 static constexpr uint32_t INTERVAL = 100;
38 static constexpr int32_t CHANNEL_CNT = 1;
39 static constexpr int32_t BITS_PER_SAMPLE = 16;
40 static constexpr int32_t SAMPLE_RATE = 16000;
41 static const std::string WAKEUP_SOURCE_CHANNEL = "wakeup_source_channel";
42 static constexpr std::string_view DEFAULT_WAKEUP_PHRASE = "\xE5\xB0\x8F\xE8\x89\xBA\xE5\xB0\x8F\xE8\x89\xBA";
43 static constexpr int64_t RECOGNIZING_TIMEOUT_US = 10 * 1000 * 1000; //10s
44 static constexpr int64_t RECOGNIZE_COMPLETE_TIMEOUT_US = 2 * 1000 * 1000; //2s
45 static constexpr int64_t READ_CAPTURER_TIMEOUT_US = 10 * 1000 * 1000; //10s
46
WakeupEngineImpl()47 WakeupEngineImpl::WakeupEngineImpl() : ModuleStates(State(IDLE), "WakeupEngineImpl", "WakeupThread")
48 {
49 InitStates();
50 capturerOptions_.streamInfo.samplingRate = AudioSamplingRate::SAMPLE_RATE_16000;
51 capturerOptions_.streamInfo.encoding = AudioEncodingType::ENCODING_PCM;
52 capturerOptions_.streamInfo.format = AudioSampleFormat::SAMPLE_S16LE;
53 capturerOptions_.capturerInfo.sourceType = SourceType::SOURCE_TYPE_WAKEUP;
54 capturerOptions_.capturerInfo.capturerFlags = 0;
55 adapterListener_ = std::make_shared<WakeupAdapterListener>(
56 std::bind(&WakeupEngineImpl::OnWakeupEvent, this, std::placeholders::_1));
57 if (adapterListener_ == nullptr) {
58 INTELL_VOICE_LOG_ERROR("adapterListener_ is nullptr");
59 }
60 }
61
~WakeupEngineImpl()62 WakeupEngineImpl::~WakeupEngineImpl()
63 {
64 }
65
InitStates()66 bool WakeupEngineImpl::InitStates()
67 {
68 for (int i = IDLE; i <= READ_CAPTURER; i++) {
69 ForState(State(i))
70 .ACT(SET_LISTENER, HandleSetListener)
71 .ACT(SET_PARAM, HandleSetParam)
72 .ACT(GET_PARAM, HandleGetParam);
73 }
74
75 ForState(IDLE)
76 .ACT(INIT, HandleInit)
77 .ACT(RESET_ADAPTER, HandleResetAdapter);
78
79 ForState(INITIALIZING)
80 .ACT(INIT_DONE, HandleInitDone);
81
82 ForState(INITIALIZED)
83 .ACT(START_RECOGNIZE, HandleStart);
84
85 ForState(RECOGNIZING)
86 .WaitUntil(RECOGNIZING_TIMEOUT,
87 std::bind(&WakeupEngineImpl::HandleRecognizingTimeout, this, std::placeholders::_1, std::placeholders::_2),
88 RECOGNIZING_TIMEOUT_US)
89 .ACT(STOP_RECOGNIZE, HandleStop)
90 .ACT(RECOGNIZE_COMPLETE, HandleRecognizeComplete);
91
92 ForState(RECOGNIZED)
93 .WaitUntil(RECOGNIZE_COMPLETE_TIMEOUT,
94 std::bind(&WakeupEngineImpl::HandleStopCapturer, this, std::placeholders::_1, std::placeholders::_2),
95 RECOGNIZE_COMPLETE_TIMEOUT_US)
96 .ACT(GET_WAKEUP_PCM, HandleGetWakeupPcm)
97 .ACT(START_CAPTURER, HandleStartCapturer);
98
99 ForState(READ_CAPTURER)
100 .WaitUntil(READ_CAPTURER_TIMEOUT,
101 std::bind(&WakeupEngineImpl::HandleStopCapturer, this, std::placeholders::_1, std::placeholders::_2),
102 READ_CAPTURER_TIMEOUT_US)
103 .ACT(READ, HandleRead)
104 .ACT(STOP_CAPTURER, HandleStopCapturer);
105
106 FromState(INITIALIZING, READ_CAPTURER)
107 .ACT(RELEASE_ADAPTER, HandleRelease)
108 .ACT(RELEASE, HandleRelease);
109
110 return IsStatesInitSucc();
111 }
112
Handle(const StateMsg & msg)113 int32_t WakeupEngineImpl::Handle(const StateMsg &msg)
114 {
115 if (!IsStatesInitSucc()) {
116 INTELL_VOICE_LOG_ERROR("failed to init state");
117 return -1;
118 }
119
120 return ModuleStates::HandleMsg(msg);
121 }
122
GetWakeupSourceChannel()123 OHOS::AudioStandard::AudioChannel WakeupEngineImpl::GetWakeupSourceChannel()
124 {
125 auto triggerMgr = TriggerManager::GetInstance();
126 if (triggerMgr == nullptr) {
127 INTELL_VOICE_LOG_ERROR("trigger manager is nullptr");
128 return AudioChannel::MONO;
129 }
130
131 std::string channel = triggerMgr->GetParameter(WAKEUP_SOURCE_CHANNEL);
132 if (channel == "") {
133 INTELL_VOICE_LOG_INFO("no channle info");
134 return AudioChannel::MONO;
135 }
136
137 auto ret = static_cast<OHOS::AudioStandard::AudioChannel>(std::stoi(channel));
138 if (ret > AudioChannel::CHANNEL_4) {
139 INTELL_VOICE_LOG_INFO("invalid channel, ret:%{public}d", ret);
140 return AudioChannel::MONO;
141 }
142 INTELL_VOICE_LOG_INFO("channle:%{public}d", static_cast<int32_t>(ret));
143 return ret;
144 }
145
SetCallbackInner()146 bool WakeupEngineImpl::SetCallbackInner()
147 {
148 INTELL_VOICE_LOG_INFO("enter");
149 if (adapter_ == nullptr) {
150 INTELL_VOICE_LOG_ERROR("adapter is nullptr");
151 return false;
152 }
153
154 if (adapterListener_ == nullptr) {
155 INTELL_VOICE_LOG_ERROR("adapter listener is nullptr");
156 return false;
157 }
158
159 callback_ = sptr<IIntellVoiceEngineCallback>(new (std::nothrow) AdapterCallbackService(adapterListener_));
160 if (callback_ == nullptr) {
161 INTELL_VOICE_LOG_ERROR("callback_ is nullptr");
162 return false;
163 }
164
165 adapter_->SetCallback(callback_);
166 return true;
167 }
168
AttachInner(const IntellVoiceEngineInfo & info)169 int32_t WakeupEngineImpl::AttachInner(const IntellVoiceEngineInfo &info)
170 {
171 INTELL_VOICE_LOG_INFO("enter");
172 if (adapter_ == nullptr) {
173 INTELL_VOICE_LOG_ERROR("adapter is nullptr");
174 return -1;
175 }
176
177 isPcmFromExternal_ = info.isPcmFromExternal;
178
179 IntellVoiceEngineAdapterInfo adapterInfo = {
180 .wakeupPhrase = info.wakeupPhrase,
181 .minBufSize = info.minBufSize,
182 .sampleChannels = info.sampleChannels,
183 .bitsPerSample = info.bitsPerSample,
184 .sampleRate = info.sampleRate,
185 };
186 return adapter_->Attach(adapterInfo);
187 }
188
SetParamOnAudioStart(int32_t uuid)189 void WakeupEngineImpl::SetParamOnAudioStart(int32_t uuid)
190 {
191 INTELL_VOICE_LOG_INFO("enter");
192 auto audioSystemManager = AudioSystemManager::GetInstance();
193 if (audioSystemManager == nullptr) {
194 INTELL_VOICE_LOG_ERROR("audioSystemManager is nullptr");
195 return;
196 }
197
198 audioSystemManager->SetAsrAecMode(AsrAecMode::STANDARD);
199 if (uuid == PROXIMAL_WAKEUP_MODEL_UUID) {
200 audioSystemManager->SetAsrNoiseSuppressionMode(AsrNoiseSuppressionMode::NEAR_FIELD);
201 } else {
202 audioSystemManager->SetAsrNoiseSuppressionMode(AsrNoiseSuppressionMode::STANDARD);
203 }
204 }
205
SetParamOnAudioStop()206 void WakeupEngineImpl::SetParamOnAudioStop()
207 {
208 INTELL_VOICE_LOG_INFO("enter");
209 auto audioSystemManager = AudioSystemManager::GetInstance();
210 if (audioSystemManager == nullptr) {
211 INTELL_VOICE_LOG_ERROR("audioSystemManager is nullptr");
212 return;
213 }
214 audioSystemManager->SetAsrAecMode(AsrAecMode::BYPASS);
215 audioSystemManager->SetAsrNoiseSuppressionMode(AsrNoiseSuppressionMode::BYPASS);
216 }
217
CreateWakeupSourceStopCallback()218 bool WakeupEngineImpl::CreateWakeupSourceStopCallback()
219 {
220 if (wakeupSourceStopCallback_ != nullptr) {
221 INTELL_VOICE_LOG_INFO("wakeup close cb is already created");
222 return true;
223 }
224
225 auto audioSystemManager = AudioSystemManager::GetInstance();
226 if (audioSystemManager == nullptr) {
227 INTELL_VOICE_LOG_ERROR("audioSystemManager is nullptr");
228 return false;
229 }
230
231 wakeupSourceStopCallback_ = std::make_shared<WakeupSourceStopCallback>();
232 if (wakeupSourceStopCallback_ == nullptr) {
233 INTELL_VOICE_LOG_ERROR("wakeup source stop callback is nullptr");
234 return false;
235 }
236
237 audioSystemManager->SetWakeUpSourceCloseCallback(wakeupSourceStopCallback_);
238 return true;
239 }
240
DestroyWakeupSourceStopCallback()241 void WakeupEngineImpl::DestroyWakeupSourceStopCallback()
242 {
243 if (wakeupSourceStopCallback_ == nullptr) {
244 INTELL_VOICE_LOG_INFO("wakeup close cb is already destroyed");
245 return;
246 }
247
248 auto audioSystemManager = AudioSystemManager::GetInstance();
249 if (audioSystemManager == nullptr) {
250 INTELL_VOICE_LOG_ERROR("audioSystemManager is nullptr");
251 return;
252 }
253
254 audioSystemManager->SetWakeUpSourceCloseCallback(nullptr);
255 wakeupSourceStopCallback_ = nullptr;
256 }
257
StartAudioSource()258 bool WakeupEngineImpl::StartAudioSource()
259 {
260 capturerOptions_.streamInfo.channels = GetWakeupSourceChannel();
261 auto listener = std::make_unique<AudioSourceListener>(
262 [&](uint8_t *buffer, uint32_t size, bool isEnd) {
263 std::vector<std::vector<uint8_t>> audioData;
264 auto ret = IntellVoiceUtil::DeinterleaveAudioData(reinterpret_cast<int16_t *>(buffer),
265 size / sizeof(int16_t), static_cast<int32_t>(capturerOptions_.streamInfo.channels), audioData);
266 if ((!ret) || ((audioData.size() != static_cast<uint32_t>(capturerOptions_.streamInfo.channels))) ||
267 (channelId_ >= audioData.size())) {
268 INTELL_VOICE_LOG_ERROR("failed to deinterleave, ret:%{public}d, id:%{public}d", ret, channelId_);
269 return;
270 }
271 if ((adapter_ != nullptr) && !isEnd) {
272 adapter_->WriteAudio(audioData[channelId_]);
273 }
274 WakeupSourceProcess::Write(audioData);
275 },
276 [&]() {
277 INTELL_VOICE_LOG_INFO("end of pcm");
278 if (adapter_ != nullptr) {
279 adapter_->SetParameter("end_of_pcm=true");
280 }
281 });
282 if (listener == nullptr) {
283 INTELL_VOICE_LOG_ERROR("create listener failed");
284 return false;
285 }
286
287 WakeupSourceProcess::Init(capturerOptions_.streamInfo.channels);
288
289 audioSource_ = std::make_unique<AudioSource>(MIN_BUFFER_SIZE * static_cast<uint32_t>(
290 capturerOptions_.streamInfo.channels), INTERVAL, std::move(listener), capturerOptions_);
291 if (audioSource_ == nullptr) {
292 INTELL_VOICE_LOG_ERROR("create audio source failed");
293 WakeupSourceProcess::Release();
294 return false;
295 }
296
297 if (!audioSource_->Start()) {
298 INTELL_VOICE_LOG_ERROR("start capturer failed");
299 audioSource_ = nullptr;
300 WakeupSourceProcess::Release();
301 return false;
302 }
303
304 return true;
305 }
306
StopAudioSource()307 void WakeupEngineImpl::StopAudioSource()
308 {
309 INTELL_VOICE_LOG_INFO("enter");
310 if (audioSource_ == nullptr) {
311 INTELL_VOICE_LOG_INFO("audio source is nullptr, no need to stop");
312 return;
313 }
314 SetParamOnAudioStop();
315 audioSource_->Stop();
316 audioSource_ = nullptr;
317 WakeupSourceProcess::Release();
318 }
319
OnWakeupEvent(const OHOS::HDI::IntelligentVoice::Engine::V1_0::IntellVoiceEngineCallBackEvent & event)320 void WakeupEngineImpl::OnWakeupEvent(
321 const OHOS::HDI::IntelligentVoice::Engine::V1_0::IntellVoiceEngineCallBackEvent &event)
322 {
323 if (event.msgId == INTELL_VOICE_ENGINE_MSG_INIT_DONE) {
324 std::thread(&WakeupEngineImpl::OnInitDone, this, event.result).detach();
325 } else if (event.msgId == INTELL_VOICE_ENGINE_MSG_RECOGNIZE_COMPLETE) {
326 std::thread(&WakeupEngineImpl::OnWakeupRecognition, this, event.result, event.info).detach();
327 } else {
328 INTELL_VOICE_LOG_WARN("invalid msg id:%{public}d", event.msgId);
329 }
330 }
331
OnInitDone(int32_t result)332 void WakeupEngineImpl::OnInitDone(int32_t result)
333 {
334 INTELL_VOICE_LOG_INFO("on Init Done, result:%{public}d", result);
335 StateMsg msg(INIT_DONE, &result, sizeof(int32_t));
336 Handle(msg);
337 }
338
OnWakeupRecognition(int32_t result,const std::string & info)339 void WakeupEngineImpl::OnWakeupRecognition(int32_t result, const std::string &info)
340 {
341 INTELL_VOICE_LOG_INFO("on wakeup recognition, result:%{public}d", result);
342 OHOS::HDI::IntelligentVoice::Engine::V1_0::IntellVoiceEngineCallBackEvent event;
343 event.msgId = INTELL_VOICE_ENGINE_MSG_RECOGNIZE_COMPLETE;
344 event.result = static_cast<OHOS::HDI::IntelligentVoice::Engine::V1_0::IntellVoiceEngineErrors>(result);
345 event.info = info;
346 StateMsg msg(RECOGNIZE_COMPLETE, reinterpret_cast<void *>(&event),
347 sizeof(OHOS::HDI::IntelligentVoice::Engine::V1_0::IntellVoiceEngineCallBackEvent));
348 Handle(msg);
349 }
350
HandleSetParam(const StateMsg & msg,State &)351 int32_t WakeupEngineImpl::HandleSetParam(const StateMsg &msg, State & /* nextState */)
352 {
353 StringParam *param = reinterpret_cast<StringParam *>(msg.inMsg);
354 if (param == nullptr) {
355 INTELL_VOICE_LOG_INFO("param is nullptr");
356 return -1;
357 }
358
359 return EngineUtil::SetParameter(param->strParam);
360 }
361
HandleGetParam(const StateMsg & msg,State &)362 int32_t WakeupEngineImpl::HandleGetParam(const StateMsg &msg, State & /* nextState */)
363 {
364 StringParam *key = reinterpret_cast<StringParam *>(msg.inMsg);
365 StringParam *value = reinterpret_cast<StringParam *>(msg.inMsg);
366 if ((key == nullptr) || (value == nullptr)) {
367 INTELL_VOICE_LOG_INFO("key or value is nullptr");
368 return -1;
369 }
370
371 value->strParam = EngineUtil::GetParameter(key->strParam);
372 return 0;
373 }
374
HandleInit(const StateMsg &,State & nextState)375 int32_t WakeupEngineImpl::HandleInit(const StateMsg & /* msg */, State &nextState)
376 {
377 INTELL_VOICE_LOG_INFO("enter");
378 if (!EngineUtil::CreateAdapterInner(EngineHostManager::GetInstance(), WAKEUP_ADAPTER_TYPE)) {
379 INTELL_VOICE_LOG_ERROR("failed to create adapter");
380 return -1;
381 }
382
383 if (!SetCallbackInner()) {
384 INTELL_VOICE_LOG_ERROR("failed to set callback");
385 return -1;
386 }
387 UpdateDspModel();
388 EngineUtil::SetLanguage();
389 EngineUtil::SetArea();
390 EngineUtil::SetSensibility();
391 SetDspFeatures();
392
393 IntellVoiceEngineInfo info = {
394 .wakeupPhrase = GetWakeupPhrase(),
395 .isPcmFromExternal = false,
396 .minBufSize = MIN_BUFFER_SIZE,
397 .sampleChannels = CHANNEL_CNT,
398 .bitsPerSample = BITS_PER_SAMPLE,
399 .sampleRate = SAMPLE_RATE,
400 };
401 if (AttachInner(info) != 0) {
402 INTELL_VOICE_LOG_ERROR("failed to attach");
403 return -1;
404 }
405
406 nextState = State(INITIALIZING);
407 return 0;
408 }
409
HandleInitDone(const StateMsg & msg,State & nextState)410 int32_t WakeupEngineImpl::HandleInitDone(const StateMsg &msg, State &nextState)
411 {
412 INTELL_VOICE_LOG_INFO("enter");
413 int32_t *result = reinterpret_cast<int32_t *>(msg.inMsg);
414 if ((result == nullptr) || (*result != 0)) {
415 INTELL_VOICE_LOG_ERROR("init done failed");
416 return -1;
417 }
418
419 nextState = State(INITIALIZED);
420 return 0;
421 }
422
HandleSetListener(const StateMsg & msg,State &)423 int32_t WakeupEngineImpl::HandleSetListener(const StateMsg &msg, State & /* nextState */)
424 {
425 SetListenerMsg *listenerMsg = reinterpret_cast<SetListenerMsg *>(msg.inMsg);
426 if (listenerMsg == nullptr || adapterListener_ == nullptr) {
427 INTELL_VOICE_LOG_ERROR("listenerMsg or adapter listener is nullptr");
428 return -1;
429 }
430
431 adapterListener_->SetCallback(listenerMsg->callback);
432 return 0;
433 }
434
HandleStart(const StateMsg & msg,State & nextState)435 int32_t WakeupEngineImpl::HandleStart(const StateMsg &msg, State &nextState)
436 {
437 int32_t *msgBody = reinterpret_cast<int32_t *>(msg.inMsg);
438 if (msgBody == nullptr) {
439 INTELL_VOICE_LOG_ERROR("msgBody is nullptr");
440 return -1;
441 }
442
443 if (*msgBody == PROXIMAL_WAKEUP_MODEL_UUID) {
444 channelId_ = CHANNEL_ID_1;
445 EngineUtil::SetParameter("WakeupType=3");
446 } else {
447 channelId_ = CHANNEL_ID_0;
448 EngineUtil::SetParameter("WakeupType=0");
449 }
450 INTELL_VOICE_LOG_INFO("enter, channel id is %{public}d", channelId_);
451
452 EngineUtil::SetParameter("VprTrdType=0;WakeupScene=0");
453
454 if (adapter_ == nullptr) {
455 INTELL_VOICE_LOG_ERROR("adapter is nullptr");
456 return -1;
457 }
458
459 StartInfo info = {
460 .isLast = true,
461 };
462 if (adapter_->Start(info)) {
463 INTELL_VOICE_LOG_ERROR("start adapter failed");
464 return -1;
465 }
466
467 if (!CreateWakeupSourceStopCallback()) {
468 INTELL_VOICE_LOG_ERROR("create wakeup source stop callback failed");
469 adapter_->Stop();
470 return -1;
471 }
472
473 SetParamOnAudioStart(*msgBody);
474
475 if (!StartAudioSource()) {
476 INTELL_VOICE_LOG_ERROR("start audio source failed");
477 SetParamOnAudioStop();
478 adapter_->Stop();
479 return -1;
480 }
481
482 INTELL_VOICE_LOG_INFO("exit");
483 nextState = State(RECOGNIZING);
484 return 0;
485 }
486
HandleStop(const StateMsg &,State & nextState)487 int32_t WakeupEngineImpl::HandleStop(const StateMsg & /* msg */, State &nextState)
488 {
489 StopAudioSource();
490 EngineUtil::Stop();
491 nextState = State(INITIALIZED);
492 return 0;
493 }
494
HandleRecognizeComplete(const StateMsg & msg,State & nextState)495 int32_t WakeupEngineImpl::HandleRecognizeComplete(const StateMsg &msg, State &nextState)
496 {
497 OHOS::HDI::IntelligentVoice::Engine::V1_0::IntellVoiceEngineCallBackEvent *event =
498 reinterpret_cast<OHOS::HDI::IntelligentVoice::Engine::V1_0::IntellVoiceEngineCallBackEvent *>(msg.inMsg);
499 if (event == nullptr) {
500 INTELL_VOICE_LOG_ERROR("result is nullptr");
501 return -1;
502 }
503
504 if (adapterListener_ != nullptr) {
505 adapterListener_->Notify(*event);
506 }
507
508 if (event->result != 0) {
509 INTELL_VOICE_LOG_ERROR("wakeup failed");
510 StopAudioSource();
511 nextState = State(INITIALIZED);
512 } else {
513 nextState = State(RECOGNIZED);
514 }
515 EngineUtil::Stop();
516 return 0;
517 }
518
HandleStartCapturer(const StateMsg & msg,State & nextState)519 int32_t WakeupEngineImpl::HandleStartCapturer(const StateMsg &msg, State &nextState)
520 {
521 INTELL_VOICE_LOG_INFO("enter");
522 int32_t *msgBody = reinterpret_cast<int32_t *>(msg.inMsg);
523 if (msgBody == nullptr) {
524 INTELL_VOICE_LOG_ERROR("msgBody is nullptr");
525 return -1;
526 }
527 channels_ = *msgBody;
528 nextState = State(READ_CAPTURER);
529 return 0;
530 }
531
HandleRead(const StateMsg & msg,State &)532 int32_t WakeupEngineImpl::HandleRead(const StateMsg &msg, State & /* nextState */)
533 {
534 CapturerData *capturerData = reinterpret_cast<CapturerData *>(msg.outMsg);
535 if (capturerData == nullptr) {
536 INTELL_VOICE_LOG_ERROR("capturer data is nullptr");
537 return -1;
538 }
539
540 auto ret = WakeupSourceProcess::Read(capturerData->data, channels_);
541 if (ret != 0) {
542 INTELL_VOICE_LOG_ERROR("read capturer data failed");
543 return ret;
544 }
545
546 ResetTimerDelay();
547 return 0;
548 }
549
HandleStopCapturer(const StateMsg &,State & nextState)550 int32_t WakeupEngineImpl::HandleStopCapturer(const StateMsg & /* msg */, State &nextState)
551 {
552 INTELL_VOICE_LOG_INFO("enter");
553 StopAudioSource();
554 EngineUtil::Stop();
555 nextState = State(INITIALIZED);
556 return 0;
557 }
558
HandleRecognizingTimeout(const StateMsg &,State & nextState)559 int32_t WakeupEngineImpl::HandleRecognizingTimeout(const StateMsg & /* msg */, State &nextState)
560 {
561 INTELL_VOICE_LOG_INFO("enter");
562 StopAudioSource();
563 EngineUtil::Stop();
564 nextState = State(INITIALIZED);
565 return 0;
566 }
567
HandleGetWakeupPcm(const StateMsg & msg,State &)568 int32_t WakeupEngineImpl::HandleGetWakeupPcm(const StateMsg &msg, State & /* nextState */)
569 {
570 CapturerData *capturerData = reinterpret_cast<CapturerData *>(msg.outMsg);
571 if (capturerData == nullptr) {
572 INTELL_VOICE_LOG_ERROR("capturer data is nullptr");
573 return -1;
574 }
575 auto ret = EngineUtil::GetWakeupPcm(capturerData->data);
576 if (ret != 0) {
577 INTELL_VOICE_LOG_ERROR("get wakeup pcm failed");
578 return ret;
579 }
580 return 0;
581 }
582
HandleResetAdapter(const StateMsg &,State & nextState)583 int32_t WakeupEngineImpl::HandleResetAdapter(const StateMsg & /* msg */, State &nextState)
584 {
585 INTELL_VOICE_LOG_INFO("enter");
586 if (!EngineUtil::CreateAdapterInner(EngineHostManager::GetInstance(), WAKEUP_ADAPTER_TYPE)) {
587 INTELL_VOICE_LOG_ERROR("failed to create adapter");
588 return -1;
589 }
590 adapter_->SetCallback(callback_);
591 UpdateDspModel();
592 EngineUtil::SetLanguage();
593 EngineUtil::SetArea();
594 SetDspFeatures();
595
596 IntellVoiceEngineAdapterInfo adapterInfo = {
597 .wakeupPhrase = GetWakeupPhrase(),
598 .minBufSize = MIN_BUFFER_SIZE,
599 .sampleChannels = CHANNEL_CNT,
600 .bitsPerSample = BITS_PER_SAMPLE,
601 .sampleRate = SAMPLE_RATE,
602 };
603 if (adapter_->Attach(adapterInfo) != 0) {
604 INTELL_VOICE_LOG_ERROR("failed to attach");
605 EngineUtil::ReleaseAdapterInner(EngineHostManager::GetInstance());
606 return -1;
607 }
608
609 nextState = State(INITIALIZING);
610 return 0;
611 }
612
HandleRelease(const StateMsg &,State & nextState)613 int32_t WakeupEngineImpl::HandleRelease(const StateMsg & /* msg */, State &nextState)
614 {
615 DestroyWakeupSourceStopCallback();
616 StopAudioSource();
617 if (adapter_ != nullptr) {
618 adapter_->Detach();
619 ReleaseAdapterInner(EngineHostManager::GetInstance());
620 }
621 nextState = State(IDLE);
622 return 0;
623 }
624
UpdateDspModel()625 void WakeupEngineImpl::UpdateDspModel()
626 {
627 auto &mgr = IntellVoiceServiceManager::GetInstance();
628 if (mgr == nullptr) {
629 INTELL_VOICE_LOG_ERROR("mgr is nullptr");
630 return;
631 }
632 if (mgr->QuerySwitchStatus(SHORTWORD_KEY)) {
633 adapter_->SetParameter("WakeupMode=1");
634 ProcDspModel(static_cast<OHOS::HDI::IntelligentVoice::Engine::V1_0::ContentType>(
635 OHOS::HDI::IntelligentVoice::Engine::V1_2::SHORT_WORD_DSP_MODEL));
636 } else {
637 adapter_->SetParameter("WakeupMode=0");
638 ProcDspModel(OHOS::HDI::IntelligentVoice::Engine::V1_0::DSP_MODLE);
639 }
640 }
641
GetWakeupPhrase()642 std::string WakeupEngineImpl::GetWakeupPhrase()
643 {
644 std::string wakeupPhrase = HistoryInfoMgr::GetInstance().GetWakeupPhrase();
645 if (wakeupPhrase.empty()) {
646 INTELL_VOICE_LOG_WARN("no phrase, use default phrase");
647 return std::string(DEFAULT_WAKEUP_PHRASE);
648 }
649
650 return wakeupPhrase;
651 }
652 }
653 }
654