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