mirror of
https://github.com/openharmony/ai_intelligent_voice_framework.git
synced 2026-07-01 20:24:01 -04:00
+2
-1
@@ -52,7 +52,8 @@
|
||||
"intelligent_voice_framework_only_first_stage",
|
||||
"intelligent_voice_framework_only_second_stage",
|
||||
"intelligent_voice_framework_window_manager_enable",
|
||||
"intelligent_voice_framework_power_manager_enable"
|
||||
"intelligent_voice_framework_power_manager_enable",
|
||||
"intelligent_voice_framework_first_stage_oneshot_enable"
|
||||
],
|
||||
"build": {
|
||||
"sub_component": [
|
||||
|
||||
@@ -19,6 +19,7 @@ declare_args() {
|
||||
intelligent_voice_framework_only_second_stage = false
|
||||
intelligent_voice_framework_window_manager_enable = false
|
||||
intelligent_voice_framework_power_manager_enable = false
|
||||
intelligent_voice_framework_first_stage_oneshot_enable = false
|
||||
if (defined(global_parts_info) &&
|
||||
defined(global_parts_info.telephony_state_registry) &&
|
||||
defined(global_parts_info.telephony_core_service) &&
|
||||
|
||||
@@ -102,6 +102,44 @@ ohos_source_set("engine_source") {
|
||||
"safwk:system_ability_fwk",
|
||||
"samgr:samgr_proxy",
|
||||
]
|
||||
} else if (intelligent_voice_framework_first_stage_oneshot_enable) {
|
||||
sources = [
|
||||
"server/base/audio_debug.cpp",
|
||||
"server/base/audio_source.cpp",
|
||||
"server/base/engine_base.cpp",
|
||||
"server/base/file_source.cpp",
|
||||
"server/base/intell_voice_engine_stub.cpp",
|
||||
"server/manager/engine_callback_message.cpp",
|
||||
"server/manager/only_first_engine_manager.cpp",
|
||||
"server/wakeup/only_first/only_first_wakeup_engine.cpp",
|
||||
"server/wakeup/only_first/only_first_wakeup_engine_impl.cpp",
|
||||
"server/wakeup/wakeup_source_process.cpp",
|
||||
"server/wakeup/wakeup_source_stop_callback.cpp",
|
||||
]
|
||||
|
||||
include_dirs = [
|
||||
"inc",
|
||||
"../../../../ai/intelligent_voice_framework/utils",
|
||||
"../../../../ai/intelligent_voice_framework/interfaces/inner_api/native",
|
||||
"../intell_voice_service/inc",
|
||||
"intell_voice_engine",
|
||||
"server/base",
|
||||
"server/utils",
|
||||
"server/wakeup",
|
||||
"server/wakeup/only_first",
|
||||
]
|
||||
|
||||
external_deps = [
|
||||
"audio_framework:audio_capturer",
|
||||
"audio_framework:audio_client",
|
||||
"audio_framework:audio_foundation",
|
||||
"c_utils:utils",
|
||||
"eventhandler:libeventhandler",
|
||||
"ffrt:libffrt",
|
||||
"hilog:libhilog",
|
||||
"image_framework:image_native",
|
||||
"ipc:ipc_core",
|
||||
]
|
||||
} else {
|
||||
sources = [
|
||||
"server/manager/dummy_engine_manager.cpp",
|
||||
@@ -126,6 +164,13 @@ ohos_source_set("engine_source") {
|
||||
cflags_cc += [ "-DONLY_SECOND_STAGE" ]
|
||||
}
|
||||
|
||||
if (intelligent_voice_framework_only_first_stage) {
|
||||
cflags_cc += [ "-DONLY_FIRST_STAGE" ]
|
||||
if (intelligent_voice_framework_first_stage_oneshot_enable) {
|
||||
cflags_cc += [ "-DFIRST_STAGE_ONESHOT_ENABLE" ]
|
||||
}
|
||||
}
|
||||
|
||||
defines = []
|
||||
if (build_variant == "root") {
|
||||
defines += [ "INTELL_VOICE_BUILD_VARIANT_ROOT" ]
|
||||
@@ -150,6 +195,8 @@ ohos_shared_library("intelligentvoice_engine") {
|
||||
external_deps = [ "hilog:libhilog" ]
|
||||
if (intelligent_voice_framework_engine_enable) {
|
||||
version_script = "libintelligentvoice_engine.versionscript"
|
||||
} else if (intelligent_voice_framework_first_stage_oneshot_enable) {
|
||||
version_script = "libintelligentvoice_only_first_engine.versionscript"
|
||||
} else {
|
||||
version_script = "libintelligentvoice_dummy_engine.versionscript"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef ONLY_FIRST_ENGINE_MANAGER_H
|
||||
#define ONLY_FIRST_ENGINE_MANAGER_H
|
||||
|
||||
#include <mutex>
|
||||
#include "engine_base.h"
|
||||
#include "i_intell_voice_engine.h"
|
||||
#include "i_intell_voice_service.h"
|
||||
#include "intell_voice_definitions.h"
|
||||
#include "intell_voice_death_recipient.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace IntellVoiceEngine {
|
||||
class OnlyFirstEngineManager {
|
||||
public:
|
||||
OnlyFirstEngineManager();
|
||||
~OnlyFirstEngineManager();
|
||||
void SetScreenOff(bool value) {};
|
||||
static bool GetEnrollResult(IntellVoiceEngineType type) { return false; };
|
||||
int32_t GetWakeupSourceFilesList(std::vector<std::string> &cloneFiles) { return 0; };
|
||||
int32_t GetWakeupSourceFile(const std::string &filePath, std::vector<uint8_t> &buffer) { return 0; };
|
||||
int32_t SendWakeupFile(const std::string &filePath, const std::vector<uint8_t> &buffer) { return 0; };
|
||||
int32_t GetUploadFiles(int numMax, std::vector<UploadFilesFromHdi> &files) { return 0; };
|
||||
void ClearUserDataInner() {};
|
||||
void HeadsetHostDie() {};
|
||||
bool IsNeedUpdateComplete(int32_t result, const std::string ¶m) { return false; };
|
||||
bool IsNeedUpdateRetry() { return false; };
|
||||
int32_t SilenceUpdate() { return 0; };
|
||||
int32_t WhisperVprUpdate(bool reEnroll = false) { return 0; };
|
||||
int32_t CloneUpdate(const std::string &wakeupInfo, const sptr<IRemoteObject> &object) { return 0; };
|
||||
void SetDspSensibility(const std::string &sensibility) {};
|
||||
void OnServiceStart() {};
|
||||
void OnServiceStop() {};
|
||||
void ClearWakeupEngineCb() {};
|
||||
|
||||
bool IsEngineExist(IntellVoiceEngineType type);
|
||||
bool AnyEngineExist(const std::vector<IntellVoiceEngineType>& types);
|
||||
bool RegisterProxyDeathRecipient(IntellVoiceEngineType type, const sptr<IRemoteObject> &object);
|
||||
bool DeregisterProxyDeathRecipient(IntellVoiceEngineType type);
|
||||
|
||||
int32_t SetParameter(const std::string &keyValueList);
|
||||
std::string GetParameter(const std::string &key);
|
||||
void EngineOnDetected(int32_t uuid);
|
||||
sptr<IIntellVoiceEngine> CreateEngine(IntellVoiceEngineType type, const std::string ¶m = "");
|
||||
int32_t ReleaseEngineInner(IntellVoiceEngineType type);
|
||||
bool CreateOrResetWakeupEngine();
|
||||
int32_t ServiceStopProc();
|
||||
|
||||
private:
|
||||
sptr<IIntellVoiceEngine> CreateEngineInner(IntellVoiceEngineType type);
|
||||
|
||||
private:
|
||||
std::mutex deathMutex_;
|
||||
sptr<EngineBase> wakeupEngine_ = nullptr;
|
||||
sptr<IntellVoiceUtils::IntellVoiceDeathRecipient> proxyDeathRecipient_ = nullptr;
|
||||
sptr<IRemoteObject> deathRecipientObj_ = nullptr;
|
||||
};
|
||||
} // namespace IntellVoiceEngine
|
||||
} // namespace OHOS
|
||||
#endif
|
||||
@@ -0,0 +1,23 @@
|
||||
# Copyright (c) 2025 Huawei Device Co., Ltd.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
1.0 {
|
||||
global:
|
||||
extern "C++" {
|
||||
OHOS::IntellVoiceEngine::OnlyFirstEngineManager::*;
|
||||
OHOS::IntellVoiceEngine::EngineCallbackMessage::EngineFuncMap;
|
||||
std::__h::__any_imp::*;
|
||||
};
|
||||
local:
|
||||
*;
|
||||
};
|
||||
@@ -79,12 +79,20 @@ bool AudioSource::Start()
|
||||
|
||||
isReading_.store(true);
|
||||
CreateAudioDebugFile("_audio_source");
|
||||
std::thread t1(std::bind(&AudioSource::ReadThread, this));
|
||||
|
||||
#ifdef FIRST_STAGE_ONESHOT_ENABLE
|
||||
if (!ThreadWrapper::Start("WakeUpAudioSource")) {
|
||||
INTELL_VOICE_LOG_ERROR("failed to start wakeup source");
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
std::thread t1(std::bind(&AudioSource::Run, this));
|
||||
readThread_ = std::move(t1);
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
void AudioSource::ReadThread()
|
||||
void AudioSource::Run()
|
||||
{
|
||||
INTELL_VOICE_LOG_INFO("enter");
|
||||
uint32_t readCnt = 0;
|
||||
@@ -133,7 +141,11 @@ void AudioSource::Stop()
|
||||
MemoryGuard memoryGuard;
|
||||
|
||||
isReading_.store(false);
|
||||
#ifdef FIRST_STAGE_ONESHOT_ENABLE
|
||||
ThreadWrapper::Join();
|
||||
#else
|
||||
readThread_.join();
|
||||
#endif
|
||||
|
||||
DestroyAudioDebugFile();
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include "audio_capturer.h"
|
||||
#include "audio_info.h"
|
||||
#include "audio_debug.h"
|
||||
#include "thread_wrapper.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace IntellVoiceEngine {
|
||||
@@ -35,7 +36,11 @@ struct AudioSourceListener {
|
||||
OnBufferEndCb bufferEndCb_;
|
||||
};
|
||||
|
||||
#ifdef FIRST_STAGE_ONESHOT_ENABLE
|
||||
class AudioSource : public IntellVoiceUtils::ThreadWrapper, private AudioDebug {
|
||||
#else
|
||||
class AudioSource : private AudioDebug {
|
||||
#endif
|
||||
public:
|
||||
AudioSource(uint32_t minBufferSize, uint32_t bufferCnt, std::unique_ptr<AudioSourceListener> listener,
|
||||
const OHOS::AudioStandard::AudioCapturerOptions &capturerOptions);
|
||||
@@ -44,7 +49,7 @@ public:
|
||||
void Stop();
|
||||
|
||||
private:
|
||||
void ReadThread();
|
||||
void Run();
|
||||
bool Read();
|
||||
|
||||
private:
|
||||
|
||||
@@ -0,0 +1,227 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "only_first_engine_manager.h"
|
||||
|
||||
#include <vector>
|
||||
#include <fstream>
|
||||
#include <cstdio>
|
||||
#include "intell_voice_log.h"
|
||||
#include "intell_voice_util.h"
|
||||
#include "string_util.h"
|
||||
#include "iservice_registry.h"
|
||||
#include "intell_voice_generic_factory.h"
|
||||
#include "memory_guard.h"
|
||||
#include "engine_callback_message.h"
|
||||
#include "intell_voice_definitions.h"
|
||||
#include "only_first_wakeup_engine_obj.h"
|
||||
|
||||
#define LOG_TAG "OnlyFirstEngineManager"
|
||||
|
||||
using namespace OHOS::IntellVoiceUtils;
|
||||
|
||||
namespace OHOS {
|
||||
namespace IntellVoiceEngine {
|
||||
|
||||
OnlyFirstEngineManager::OnlyFirstEngineManager()
|
||||
{
|
||||
}
|
||||
|
||||
OnlyFirstEngineManager::~OnlyFirstEngineManager()
|
||||
{
|
||||
}
|
||||
|
||||
bool OnlyFirstEngineManager::IsEngineExist(IntellVoiceEngineType type)
|
||||
{
|
||||
if(type == INTELL_VOICE_WAKEUP) {
|
||||
if(wakeupEngine_ != nullptr) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool OnlyFirstEngineManager::AnyEngineExist(const std::vector<IntellVoiceEngineType>& types)
|
||||
{
|
||||
for (const auto &type : types) {
|
||||
if (IsEngineExist(type)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool OnlyFirstEngineManager::RegisterProxyDeathRecipient(IntellVoiceEngineType type, const sptr<IRemoteObject> &object)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(deathMutex_);
|
||||
INTELL_VOICE_LOG_INFO("enter, type:%{public}d", type);
|
||||
|
||||
if (type != INTELL_VOICE_WAKEUP) {
|
||||
INTELL_VOICE_LOG_ERROR("invalid type:%{public}d", type);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(proxyDeathRecipient_ != nullptr) {
|
||||
INTELL_VOICE_LOG_ERROR("death recipient is not nullptr, type:%{public}d", type);
|
||||
return false;
|
||||
}
|
||||
|
||||
deathRecipientObj_ = object;
|
||||
proxyDeathRecipient_ = new (std::nothrow) IntellVoiceDeathRecipient([&]() {
|
||||
INTELL_VOICE_LOG_INFO("receive wakeup proxy death recipient, clear wakeup engine callback");
|
||||
EngineCallbackMessage::CallFunc(HANDLE_CLEAR_WAKEUP_ENGINE_CB);
|
||||
});
|
||||
|
||||
if (proxyDeathRecipient_ == nullptr) {
|
||||
INTELL_VOICE_LOG_ERROR("create death recipient failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
return deathRecipientObj_->AddDeathRecipient(proxyDeathRecipient_);
|
||||
}
|
||||
|
||||
bool OnlyFirstEngineManager::DeregisterProxyDeathRecipient(IntellVoiceEngineType type)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(deathMutex_);
|
||||
INTELL_VOICE_LOG_INFO("enter, type:%{public}d", type);
|
||||
if (type != INTELL_VOICE_WAKEUP) {
|
||||
INTELL_VOICE_LOG_ERROR("invalid type:%{public}d", type);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (deathRecipientObj_ == nullptr) {
|
||||
INTELL_VOICE_LOG_ERROR("death obj is nullptr, type:%{public}d", type);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (proxyDeathRecipient_ == nullptr) {
|
||||
INTELL_VOICE_LOG_ERROR("death recipient is nullptr, type:%{public}d", type);
|
||||
deathRecipientObj_ = nullptr;
|
||||
return false;
|
||||
}
|
||||
|
||||
auto ret = deathRecipientObj_->RemoveDeathRecipient(proxyDeathRecipient_);
|
||||
deathRecipientObj_ = nullptr;
|
||||
proxyDeathRecipient_ = nullptr;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32_t OnlyFirstEngineManager::SetParameter(const std::string &keyValueList)
|
||||
{
|
||||
if (wakeupEngine_ != nullptr) {
|
||||
wakeupEngine_->SetParameter(keyValueList);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string OnlyFirstEngineManager::GetParameter(const std::string &key)
|
||||
{
|
||||
std::string val = "";
|
||||
|
||||
if (wakeupEngine_ != nullptr) {
|
||||
val = wakeupEngine_->GetParameter(key);
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
void OnlyFirstEngineManager::EngineOnDetected(int32_t uuid)
|
||||
{
|
||||
if (wakeupEngine_ != nullptr) {
|
||||
INTELL_VOICE_LOG_INFO("on engine detected, uuid:%{public}d", uuid);
|
||||
wakeupEngine_->OnDetected(uuid);
|
||||
}
|
||||
}
|
||||
|
||||
sptr<IIntellVoiceEngine> OnlyFirstEngineManager::CreateEngineInner(IntellVoiceEngineType type)
|
||||
{
|
||||
INTELL_VOICE_LOG_INFO("create engine enter, type: %{public}d", type);
|
||||
OHOS::IntellVoiceUtils::MemoryGuard memoryGuard;
|
||||
if (wakeupEngine_ != nullptr) {
|
||||
return wakeupEngine_;
|
||||
}
|
||||
|
||||
wakeupEngine_ = SptrFactory<EngineBase, OnlyFirstWakeupEngineObj>::CreateInstance();
|
||||
if (wakeupEngine_ == nullptr) {
|
||||
INTELL_VOICE_LOG_ERROR("create engine failed, type:%{public}d", type);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
INTELL_VOICE_LOG_INFO("create engine ok");
|
||||
return wakeupEngine_;
|
||||
}
|
||||
|
||||
sptr<IIntellVoiceEngine> OnlyFirstEngineManager::CreateEngine(IntellVoiceEngineType type, const std::string ¶m)
|
||||
{
|
||||
INTELL_VOICE_LOG_INFO("enter, type:%{public}d", type);
|
||||
if (type != INTELL_VOICE_WAKEUP) {
|
||||
INTELL_VOICE_LOG_ERROR("invalid type:%{public}d", type);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return CreateEngineInner(type);
|
||||
}
|
||||
|
||||
bool OnlyFirstEngineManager::CreateOrResetWakeupEngine()
|
||||
{
|
||||
if (wakeupEngine_ != nullptr) {
|
||||
INTELL_VOICE_LOG_INFO("wakeup engine is existed");
|
||||
wakeupEngine_->ReleaseAdapter();
|
||||
if (!wakeupEngine_->ResetAdapter()) {
|
||||
INTELL_VOICE_LOG_ERROR("failed to reset adapter");
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (CreateEngineInner(INTELL_VOICE_WAKEUP) == nullptr) {
|
||||
INTELL_VOICE_LOG_ERROR("failed to create wakeup engine");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int32_t OnlyFirstEngineManager::ReleaseEngineInner(IntellVoiceEngineType type)
|
||||
{
|
||||
INTELL_VOICE_LOG_INFO("enter, type:%{public}d", type);
|
||||
if (type != INTELL_VOICE_WAKEUP) {
|
||||
INTELL_VOICE_LOG_ERROR("invalid type:%{public}d", type);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//hap only releases Napi, and does not release sa resources
|
||||
OHOS::IntellVoiceUtils::MemoryGuard memoryGuard;
|
||||
if (wakeupEngine_ != nullptr) {
|
||||
wakeupEngine_->Detach();
|
||||
wakeupEngine_ = nullptr;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t OnlyFirstEngineManager::ServiceStopProc()
|
||||
{
|
||||
INTELL_VOICE_LOG_INFO("enter");
|
||||
if (wakeupEngine_ != nullptr) {
|
||||
INTELL_VOICE_LOG_INFO("clear wakeup engine callback");
|
||||
wakeupEngine_->Detach();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
} // namespace IntellVoiceEngine
|
||||
} // namespace OHOS
|
||||
@@ -0,0 +1,146 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "only_first_wakeup_engine.h"
|
||||
#include "only_first_engine_manager.h"
|
||||
#include "only_first_wakeup_engine_impl.h"
|
||||
#include "intell_voice_log.h"
|
||||
#include "engine_callback_message.h"
|
||||
#include "intell_voice_util.h"
|
||||
|
||||
#define LOG_TAG "OnlyFirstWakeupEngine"
|
||||
|
||||
using namespace OHOS::IntellVoiceUtils;
|
||||
|
||||
namespace OHOS {
|
||||
namespace IntellVoiceEngine {
|
||||
static const std::string SINGLE_WAKEUP_RECORD_START = "record_start";
|
||||
|
||||
OnlyFirstWakeupEngine::OnlyFirstWakeupEngine()
|
||||
{
|
||||
INTELL_VOICE_LOG_INFO("enter");
|
||||
}
|
||||
|
||||
OnlyFirstWakeupEngine::~OnlyFirstWakeupEngine()
|
||||
{
|
||||
INTELL_VOICE_LOG_INFO("enter");
|
||||
}
|
||||
|
||||
int32_t OnlyFirstWakeupEngine::HandleCapturerMsg(StateMsg &msg)
|
||||
{
|
||||
|
||||
return ROLE(OnlyFirstWakeupEngineImpl).Handle(msg);
|
||||
}
|
||||
|
||||
void OnlyFirstWakeupEngine::OnDetected(int32_t uuid)
|
||||
{
|
||||
INTELL_VOICE_LOG_INFO("enter, uuid is %{public}d", uuid);
|
||||
StateMsg msg(START_RECOGNIZE, &uuid, sizeof(int32_t));
|
||||
if (HandleCapturerMsg(msg) != 0) {
|
||||
INTELL_VOICE_LOG_WARN("start failed");
|
||||
EngineCallbackMessage::CallFunc(HANDLE_CLOSE_WAKEUP_SOURCE, true);
|
||||
}
|
||||
}
|
||||
|
||||
bool OnlyFirstWakeupEngine::Init(const std::string & /* param */, bool reEnroll)
|
||||
{
|
||||
StateMsg msg(INIT);
|
||||
if (HandleCapturerMsg(msg) != 0) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int32_t OnlyFirstWakeupEngine::StartCapturer(int32_t channels)
|
||||
{
|
||||
StateMsg msg(START_CAPTURER, &channels, sizeof(int32_t));
|
||||
return HandleCapturerMsg(msg);
|
||||
}
|
||||
|
||||
int32_t OnlyFirstWakeupEngine::Read(std::vector<uint8_t> &data)
|
||||
{
|
||||
CapturerData capturerData;
|
||||
StateMsg msg(READ, nullptr, 0, reinterpret_cast<void *>(&capturerData));
|
||||
int32_t ret = HandleCapturerMsg(msg);
|
||||
if (ret != 0) {
|
||||
INTELL_VOICE_LOG_ERROR("read failed, ret:%{public}d", ret);
|
||||
return -1;
|
||||
}
|
||||
|
||||
data.swap(capturerData.data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t OnlyFirstWakeupEngine::StopCapturer()
|
||||
{
|
||||
StateMsg msg(STOP_CAPTURER);
|
||||
return HandleCapturerMsg(msg);
|
||||
}
|
||||
|
||||
int32_t OnlyFirstWakeupEngine::Detach(void)
|
||||
{
|
||||
StateMsg msg(RELEASE);
|
||||
return HandleCapturerMsg(msg);
|
||||
}
|
||||
|
||||
int32_t OnlyFirstWakeupEngine::SetParameter(const std::string &keyValueList)
|
||||
{
|
||||
std::map<std::string, std::string> kvpairs;
|
||||
|
||||
IntellVoiceUtil::SplitStringToKVPair(keyValueList, kvpairs);
|
||||
for (auto it : kvpairs) {
|
||||
if (it.first == SINGLE_WAKEUP_RECORD_START) {
|
||||
ResetSingleLevelWakeup(it.second);
|
||||
} else {
|
||||
INTELL_VOICE_LOG_INFO("no need to process, key:%{public}s, value:%{public}s",
|
||||
it.first.c_str(), it.second.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string OnlyFirstWakeupEngine::GetParameter(const std::string &key)
|
||||
{
|
||||
StringParam keyParam(key);
|
||||
StringParam valueParam;
|
||||
StateMsg msg(GET_PARAM, &keyParam, sizeof(keyParam), &valueParam);
|
||||
if (HandleCapturerMsg(msg) != 0) {
|
||||
INTELL_VOICE_LOG_ERROR("failed to get parameter, key:%{public}s", key.c_str());
|
||||
return "";
|
||||
}
|
||||
|
||||
return valueParam.strParam;
|
||||
}
|
||||
|
||||
void OnlyFirstWakeupEngine::ReleaseAdapter()
|
||||
{
|
||||
StateMsg msg(RELEASE);
|
||||
HandleCapturerMsg(msg);
|
||||
}
|
||||
|
||||
void OnlyFirstWakeupEngine::ResetSingleLevelWakeup(const std::string &value)
|
||||
{
|
||||
int32_t recordStart = -1;
|
||||
INTELL_VOICE_LOG_INFO("record_start:%{public}s", value.c_str());
|
||||
if (value != std::string("true") && value != std::string("false")) {
|
||||
return;
|
||||
}
|
||||
|
||||
recordStart = (value == std::string("true")) ? 1 : 0;
|
||||
StateMsg msg(RECORD_START, &recordStart, sizeof(int32_t));
|
||||
HandleCapturerMsg(msg);
|
||||
}
|
||||
} // namespace IntellVoiceEngine
|
||||
} // namespace OHOS
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef ONLY_FIRST_WAKEUP_ENGINE_H
|
||||
#define ONLY_FIRST_WAKEUP_ENGINE_H
|
||||
|
||||
#include <string>
|
||||
#include "base_macros.h"
|
||||
#include "engine_base.h"
|
||||
#include "only_first_wakeup_engine_impl.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace IntellVoiceEngine {
|
||||
|
||||
class OnlyFirstWakeupEngine : public EngineBase {
|
||||
public:
|
||||
OnlyFirstWakeupEngine();
|
||||
~OnlyFirstWakeupEngine();
|
||||
bool Init(const std::string ¶m, bool reEnroll = false) override;
|
||||
void SetCallback(sptr<IRemoteObject> object) override {};
|
||||
int32_t Attach(const IntellVoiceEngineInfo &info) override {return 0;};
|
||||
int32_t Detach(void) override;
|
||||
int32_t Start(bool isLast) override { return 0; };
|
||||
int32_t SetParameter(const std::string &keyValueList) override;
|
||||
std::string GetParameter(const std::string &key) override;
|
||||
int32_t Stop() override { return 0; };
|
||||
int32_t GetWakeupPcm(std::vector<uint8_t> &data) override { return 0; };
|
||||
|
||||
void OnDetected(int32_t uuid) override;
|
||||
void ReleaseAdapter() override;
|
||||
|
||||
int32_t StartCapturer(int32_t channels) override;
|
||||
int32_t Read(std::vector<uint8_t> &data) override;
|
||||
int32_t StopCapturer() override;
|
||||
int32_t NotifyHeadsetWakeEvent() override { return 0; };
|
||||
int32_t NotifyHeadsetHostEvent(HeadsetHostEventType event) override { return 0; };
|
||||
|
||||
private:
|
||||
void ResetSingleLevelWakeup(const std::string &value);
|
||||
int32_t HandleCapturerMsg(StateMsg &msg);
|
||||
USE_ROLE(OnlyFirstWakeupEngineImpl);
|
||||
};
|
||||
}
|
||||
}
|
||||
#endif
|
||||
+332
@@ -0,0 +1,332 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "only_first_wakeup_engine_impl.h"
|
||||
|
||||
#include "audio_system_manager.h"
|
||||
#include "intell_voice_info.h"
|
||||
#include "intell_voice_log.h"
|
||||
#include "intell_voice_util.h"
|
||||
#include "string_util.h"
|
||||
#include "engine_callback_message.h"
|
||||
|
||||
#define LOG_TAG "OnlyFirstWakeupEngineImpl"
|
||||
|
||||
using namespace OHOS::IntellVoice;
|
||||
using namespace OHOS::AudioStandard;
|
||||
using namespace OHOS::IntellVoiceUtils;
|
||||
|
||||
namespace OHOS {
|
||||
namespace IntellVoiceEngine {
|
||||
static constexpr uint32_t MIN_BUFFER_SIZE = 640;
|
||||
static constexpr uint32_t INTERVAL = 96;
|
||||
static const std::string WAKEUP_SOURCE_CHANNEL = "wakeup_source_channel";
|
||||
static constexpr int64_t RECOGNIZE_COMPLETE_TIMEOUT_US = 2 * 1000 * 1000; //2s
|
||||
static constexpr int64_t READ_CAPTURER_TIMEOUT_US = 10 * 1000 * 1000; //10s
|
||||
|
||||
OnlyFirstWakeupEngineImpl::OnlyFirstWakeupEngineImpl()
|
||||
: ModuleStates(State(IDLE), "OnlyFirstWakeupEngineImpl", "WakeupThread")
|
||||
{
|
||||
InitStates();
|
||||
capturerOptions_.streamInfo.samplingRate = AudioSamplingRate::SAMPLE_RATE_16000;
|
||||
capturerOptions_.streamInfo.encoding = AudioEncodingType::ENCODING_PCM;
|
||||
capturerOptions_.streamInfo.format = AudioSampleFormat::SAMPLE_S16LE;
|
||||
capturerOptions_.streamInfo.channels = AudioChannel::MONO;
|
||||
capturerOptions_.capturerInfo.sourceType = SourceType::SOURCE_TYPE_WAKEUP;
|
||||
capturerOptions_.capturerInfo.capturerFlags = 0;
|
||||
}
|
||||
|
||||
OnlyFirstWakeupEngineImpl::~OnlyFirstWakeupEngineImpl()
|
||||
{
|
||||
}
|
||||
|
||||
bool OnlyFirstWakeupEngineImpl::InitStates()
|
||||
{
|
||||
FromState(IDLE, READ_CAPTURER)
|
||||
.ACT(GET_PARAM, HandleGetParam);
|
||||
|
||||
ForState(IDLE)
|
||||
.ACT(INIT, HandleInit);
|
||||
|
||||
ForState(INITIALIZED)
|
||||
.ACT(START_RECOGNIZE, HandleStart);
|
||||
|
||||
ForState(RECOGNIZED)
|
||||
.WaitUntil(RECOGNIZE_COMPLETE_TIMEOUT, std::bind(&OnlyFirstWakeupEngineImpl::HandleStopCapturer, this,
|
||||
std::placeholders::_1, std::placeholders::_2), RECOGNIZE_COMPLETE_TIMEOUT_US)
|
||||
.ACT(START_CAPTURER, HandleStartCapturer)
|
||||
.ACT(STOP_CAPTURER, HandleStopCapturer)
|
||||
.ACT(RECORD_START, HandleRecordStart);
|
||||
|
||||
ForState(READ_CAPTURER)
|
||||
.WaitUntil(READ_CAPTURER_TIMEOUT, std::bind(&OnlyFirstWakeupEngineImpl::HandleStopCapturer, this,
|
||||
std::placeholders::_1, std::placeholders::_2), READ_CAPTURER_TIMEOUT_US)
|
||||
.ACT(READ, HandleRead)
|
||||
.ACT(STOP_CAPTURER, HandleStopCapturer);
|
||||
|
||||
FromState(INITIALIZED, READ_CAPTURER)
|
||||
.ACT(RELEASE, HandleRelease);
|
||||
|
||||
return IsStatesInitSucc();
|
||||
}
|
||||
|
||||
int32_t OnlyFirstWakeupEngineImpl::Handle(const StateMsg &msg)
|
||||
{
|
||||
if (!IsStatesInitSucc()) {
|
||||
INTELL_VOICE_LOG_ERROR("failed to init state");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return ModuleStates::HandleMsg(msg);
|
||||
}
|
||||
|
||||
bool OnlyFirstWakeupEngineImpl::CreateWakeupSourceStopCallback()
|
||||
{
|
||||
if (wakeupSourceStopCallback_ != nullptr) {
|
||||
INTELL_VOICE_LOG_INFO("wakeup close cb is already created");
|
||||
return true;
|
||||
}
|
||||
|
||||
auto audioSystemManager = AudioSystemManager::GetInstance();
|
||||
if (audioSystemManager == nullptr) {
|
||||
INTELL_VOICE_LOG_ERROR("audioSystemManager is nullptr");
|
||||
return false;
|
||||
}
|
||||
|
||||
wakeupSourceStopCallback_ = std::make_shared<WakeupSourceStopCallback>();
|
||||
if (wakeupSourceStopCallback_ == nullptr) {
|
||||
INTELL_VOICE_LOG_ERROR("wakeup source stop callback is nullptr");
|
||||
return false;
|
||||
}
|
||||
|
||||
audioSystemManager->SetWakeUpSourceCloseCallback(wakeupSourceStopCallback_);
|
||||
return true;
|
||||
}
|
||||
|
||||
void OnlyFirstWakeupEngineImpl::DestroyWakeupSourceStopCallback()
|
||||
{
|
||||
if (wakeupSourceStopCallback_ == nullptr) {
|
||||
INTELL_VOICE_LOG_INFO("wakeup close cb is already destroyed");
|
||||
return;
|
||||
}
|
||||
|
||||
auto audioSystemManager = AudioSystemManager::GetInstance();
|
||||
if (audioSystemManager == nullptr) {
|
||||
INTELL_VOICE_LOG_ERROR("audioSystemManager is nullptr");
|
||||
return;
|
||||
}
|
||||
|
||||
audioSystemManager->SetWakeUpSourceCloseCallback(nullptr);
|
||||
wakeupSourceStopCallback_ = nullptr;
|
||||
}
|
||||
|
||||
bool OnlyFirstWakeupEngineImpl::StartAudioSource()
|
||||
{
|
||||
auto listener = std::make_unique<AudioSourceListener>(
|
||||
[&](uint8_t *buffer, uint32_t size, bool isEnd) {
|
||||
ReadBufferCallback(buffer, size, isEnd);
|
||||
},
|
||||
[&]() {
|
||||
IntellVoiceUtil::StartAbility("single_level_event");
|
||||
INTELL_VOICE_LOG_INFO("single_level_event");
|
||||
});
|
||||
if (listener == nullptr) {
|
||||
INTELL_VOICE_LOG_ERROR("create listener failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
WakeupSourceProcess::Init(capturerOptions_.streamInfo.channels);
|
||||
|
||||
audioSource_ = std::make_unique<AudioSource>(MIN_BUFFER_SIZE * static_cast<uint32_t>(
|
||||
capturerOptions_.streamInfo.channels), INTERVAL, std::move(listener), capturerOptions_);
|
||||
if (audioSource_ == nullptr) {
|
||||
INTELL_VOICE_LOG_ERROR("create audio source failed");
|
||||
WakeupSourceProcess::Release();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!audioSource_->Start()) {
|
||||
INTELL_VOICE_LOG_ERROR("start capturer failed");
|
||||
audioSource_ = nullptr;
|
||||
WakeupSourceProcess::Release();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void OnlyFirstWakeupEngineImpl::StopAudioSource()
|
||||
{
|
||||
INTELL_VOICE_LOG_INFO("enter");
|
||||
if (audioSource_ == nullptr) {
|
||||
INTELL_VOICE_LOG_INFO("audio source is nullptr, no need to stop");
|
||||
return;
|
||||
}
|
||||
audioSource_->Stop();
|
||||
audioSource_ = nullptr;
|
||||
WakeupSourceProcess::Release();
|
||||
}
|
||||
|
||||
void OnlyFirstWakeupEngineImpl::OnInitDone(int32_t result)
|
||||
{
|
||||
INTELL_VOICE_LOG_INFO("on Init Done, result:%{public}d", result);
|
||||
StateMsg msg(INIT_DONE, &result, sizeof(int32_t));
|
||||
Handle(msg);
|
||||
}
|
||||
|
||||
int32_t OnlyFirstWakeupEngineImpl::HandleGetParam(const StateMsg &msg, State & /* nextState */)
|
||||
{
|
||||
StringParam *key = reinterpret_cast<StringParam *>(msg.inMsg);
|
||||
StringParam *value = reinterpret_cast<StringParam *>(msg.outMsg);
|
||||
if ((key == nullptr) || (value == nullptr)) {
|
||||
INTELL_VOICE_LOG_INFO("key or value is nullptr");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (key->strParam == WAKEUP_SOURCE_CHANNEL) {
|
||||
value->strParam = std::to_string(static_cast<uint32_t>(capturerOptions_.streamInfo.channels));
|
||||
} else {
|
||||
value->strParam = "";
|
||||
}
|
||||
|
||||
INTELL_VOICE_LOG_INFO("key:%{public}s, value:%{public}s", key->strParam.c_str(), value->strParam.c_str());
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t OnlyFirstWakeupEngineImpl::HandleInit(const StateMsg & /* msg */, State &nextState)
|
||||
{
|
||||
INTELL_VOICE_LOG_INFO("enter");
|
||||
|
||||
nextState = State(INITIALIZED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t OnlyFirstWakeupEngineImpl::HandleStart(const StateMsg &msg, State &nextState)
|
||||
{
|
||||
int32_t *msgBody = reinterpret_cast<int32_t *>(msg.inMsg);
|
||||
if (msgBody == nullptr) {
|
||||
INTELL_VOICE_LOG_ERROR("msgBody is nullptr");
|
||||
return -1;
|
||||
}
|
||||
|
||||
channelId_ = CHANNEL_ID_0;
|
||||
INTELL_VOICE_LOG_INFO("enter, channel id is %{public}d", channelId_);
|
||||
|
||||
if (!CreateWakeupSourceStopCallback()) {
|
||||
INTELL_VOICE_LOG_ERROR("create wakeup source stop callback failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!StartAudioSource()) {
|
||||
INTELL_VOICE_LOG_ERROR("start audio source failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
INTELL_VOICE_LOG_INFO("exit");
|
||||
nextState = State(RECOGNIZED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t OnlyFirstWakeupEngineImpl::HandleStartCapturer(const StateMsg &msg, State &nextState)
|
||||
{
|
||||
INTELL_VOICE_LOG_INFO("enter");
|
||||
auto ret = IntellVoiceUtil::VerifySystemPermission(OHOS_MICROPHONE_PERMISSION);
|
||||
if (ret != INTELLIGENT_VOICE_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32_t *msgBody = reinterpret_cast<int32_t *>(msg.inMsg);
|
||||
if (msgBody == nullptr) {
|
||||
INTELL_VOICE_LOG_ERROR("msgBody is nullptr");
|
||||
return INTELLIGENT_VOICE_START_CAPTURER_FAILED;
|
||||
}
|
||||
channels_ = *msgBody;
|
||||
|
||||
nextState = State(READ_CAPTURER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t OnlyFirstWakeupEngineImpl::HandleRead(const StateMsg &msg, State & /* nextState */)
|
||||
{
|
||||
CapturerData *capturerData = reinterpret_cast<CapturerData *>(msg.outMsg);
|
||||
if (capturerData == nullptr) {
|
||||
INTELL_VOICE_LOG_ERROR("capturer data is nullptr");
|
||||
return -1;
|
||||
}
|
||||
|
||||
auto ret = WakeupSourceProcess::Read(capturerData->data, channels_);
|
||||
if (ret != 0) {
|
||||
INTELL_VOICE_LOG_ERROR("read capturer data failed");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ResetTimerDelay();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t OnlyFirstWakeupEngineImpl::HandleStopCapturer(const StateMsg & /* msg */, State &nextState)
|
||||
{
|
||||
INTELL_VOICE_LOG_INFO("enter");
|
||||
StopAudioSource();
|
||||
nextState = State(INITIALIZED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t OnlyFirstWakeupEngineImpl::HandleRelease(const StateMsg & /* msg */, State &nextState)
|
||||
{
|
||||
INTELL_VOICE_LOG_INFO("enter");
|
||||
DestroyWakeupSourceStopCallback();
|
||||
StopAudioSource();
|
||||
nextState = State(IDLE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void OnlyFirstWakeupEngineImpl::ReadBufferCallback(uint8_t *buffer, uint32_t size, bool isEnd)
|
||||
{
|
||||
std::vector<std::vector<uint8_t>> audioData;
|
||||
auto ret = IntellVoiceUtil::DeinterleaveAudioData(reinterpret_cast<int16_t *>(buffer),
|
||||
size / sizeof(int16_t), static_cast<int32_t>(capturerOptions_.streamInfo.channels), audioData);
|
||||
if ((!ret) || ((audioData.size() != static_cast<uint32_t>(capturerOptions_.streamInfo.channels))) ||
|
||||
(channelId_ >= audioData.size())) {
|
||||
INTELL_VOICE_LOG_ERROR("failed to deinterleave, ret:%{public}d, id:%{public}d", ret, channelId_);
|
||||
return;
|
||||
}
|
||||
|
||||
WakeupSourceProcess::Write(audioData);
|
||||
}
|
||||
|
||||
int32_t OnlyFirstWakeupEngineImpl::HandleRecordStart(const StateMsg &msg, State &nextState)
|
||||
{
|
||||
INTELL_VOICE_LOG_INFO("enter");
|
||||
int32_t *value = reinterpret_cast<int32_t *>(msg.inMsg);
|
||||
if (value == nullptr) {
|
||||
INTELL_VOICE_LOG_ERROR("invaid value");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((*value != 0) && (*value != 1)) {
|
||||
INTELL_VOICE_LOG_ERROR("invaid value %d", *value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
recordStart_ = *value;
|
||||
if (recordStart_ == 0) {
|
||||
StopAudioSource();
|
||||
}
|
||||
|
||||
nextState = State(INITIALIZED);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef ONLY_FIRST_WAKEUP_ENGINE_IMPL_H
|
||||
#define ONLY_FIRST_WAKEUP_ENGINE_IMPL_H
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include "i_intell_voice_engine.h"
|
||||
#include "state_manager.h"
|
||||
#include "wakeup_source_stop_callback.h"
|
||||
#include "audio_source.h"
|
||||
#include "wakeup_source_process.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace IntellVoiceEngine {
|
||||
using OHOS::IntellVoiceUtils::StateMsg;
|
||||
using OHOS::IntellVoiceUtils::State;
|
||||
|
||||
enum EngineEvent {
|
||||
INIT = 0,
|
||||
INIT_DONE,
|
||||
START_RECOGNIZE,
|
||||
START_CAPTURER,
|
||||
READ,
|
||||
STOP_CAPTURER,
|
||||
READ_CAPTURER_TIMEOUT,
|
||||
GET_PARAM,
|
||||
RELEASE,
|
||||
RECOGNIZE_COMPLETE_TIMEOUT,
|
||||
RECORD_START,
|
||||
};
|
||||
|
||||
struct CapturerData {
|
||||
std::vector<uint8_t> data;
|
||||
};
|
||||
|
||||
struct StringParam {
|
||||
explicit StringParam(const std::string &str = "") : strParam(str) {}
|
||||
std::string strParam;
|
||||
};
|
||||
|
||||
class OnlyFirstWakeupEngineImpl : private OHOS::IntellVoiceUtils::ModuleStates, private WakeupSourceProcess {
|
||||
public:
|
||||
OnlyFirstWakeupEngineImpl();
|
||||
~OnlyFirstWakeupEngineImpl();
|
||||
int32_t Handle(const StateMsg &msg);
|
||||
|
||||
private:
|
||||
enum EngineState {
|
||||
IDLE = 0,
|
||||
INITIALIZED,
|
||||
RECOGNIZED,
|
||||
READ_CAPTURER,
|
||||
};
|
||||
|
||||
private:
|
||||
bool StartAudioSource();
|
||||
void StopAudioSource();
|
||||
bool CreateWakeupSourceStopCallback();
|
||||
void DestroyWakeupSourceStopCallback();
|
||||
void OnInitDone(int32_t result);
|
||||
|
||||
private:
|
||||
bool InitStates();
|
||||
int32_t HandleGetParam(const StateMsg &msg, State &nextState);
|
||||
int32_t HandleInit(const StateMsg &msg, State &nextState);
|
||||
int32_t HandleStart(const StateMsg &msg, State &nextState);
|
||||
int32_t HandleStartCapturer(const StateMsg &msg, State &nextState);
|
||||
int32_t HandleRead(const StateMsg &msg, State &nextState);
|
||||
int32_t HandleStopCapturer(const StateMsg &msg, State &nextState);
|
||||
int32_t HandleRelease(const StateMsg &msg, State &nextState);
|
||||
void ReadBufferCallback(uint8_t *buffer, uint32_t size, bool isEnd);
|
||||
int32_t HandleRecordStart(const StateMsg &msg, State &nextState);
|
||||
|
||||
private:
|
||||
int32_t channels_ = 0;
|
||||
uint32_t channelId_ = 0;
|
||||
std::shared_ptr<WakeupSourceStopCallback> wakeupSourceStopCallback_ = nullptr;
|
||||
std::unique_ptr<AudioSource> audioSource_ = nullptr;
|
||||
OHOS::AudioStandard::AudioCapturerOptions capturerOptions_;
|
||||
int32_t recordStart_ = -1;
|
||||
};
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef ONLY_FIRST_WAKEUP_ENGINE_OBJ_H
|
||||
#define ONLY_FIRST_WAKEUP_ENGINE_OBJ_H
|
||||
|
||||
#include "base_macros.h"
|
||||
#include "intell_voice_generic_factory.h"
|
||||
#include "only_first_wakeup_engine.h"
|
||||
#include "only_first_wakeup_engine_impl.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace IntellVoiceEngine {
|
||||
class OnlyFirstWakeupEngineObj : public OnlyFirstWakeupEngine, public OnlyFirstWakeupEngineImpl {
|
||||
public:
|
||||
~OnlyFirstWakeupEngineObj() {}
|
||||
|
||||
private:
|
||||
OnlyFirstWakeupEngineObj() {}
|
||||
IMPL_ROLE(OnlyFirstWakeupEngineImpl);
|
||||
friend class IntellVoiceUtils::SptrFactory<EngineBase, OnlyFirstWakeupEngineObj>;
|
||||
};
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -20,6 +20,8 @@
|
||||
#include "headset_wakeup_wrapper.h"
|
||||
#include "engine_callback_message.h"
|
||||
#include "intell_voice_util.h"
|
||||
#include "ability_manager_client.h"
|
||||
#include "history_info_mgr.h"
|
||||
|
||||
#define LOG_TAG "WakeupEngine"
|
||||
|
||||
@@ -142,13 +144,38 @@ int32_t WakeupEngine::NotifyHeadsetWakeEvent()
|
||||
return -1;
|
||||
}
|
||||
|
||||
std::thread([]() { IntellVoiceUtil::StartAbility("headset_event"); }).detach();
|
||||
std::thread([]() { StartAbility("headset_event"); }).detach();
|
||||
detectDeviceType_.store(DETECT_TYPE_HEADSET);
|
||||
|
||||
StateMsg msg(START_RECOGNIZE);
|
||||
return headsetImpl_->Handle(msg);
|
||||
}
|
||||
|
||||
void WakeupEngine::StartAbility(const std::string &event)
|
||||
{
|
||||
AAFwk::Want want;
|
||||
HistoryInfoMgr &historyInfoMgr = HistoryInfoMgr::GetInstance();
|
||||
|
||||
std::string bundleName = historyInfoMgr.GetStringKVPair(KEY_WAKEUP_ENGINE_BUNDLE_NAME);
|
||||
std::string abilityName = historyInfoMgr.GetStringKVPair(KEY_WAKEUP_ENGINE_ABILITY_NAME);
|
||||
INTELL_VOICE_LOG_INFO("bundleName:%{public}s, abilityName:%{public}s", bundleName.c_str(), abilityName.c_str());
|
||||
if (bundleName.empty() || abilityName.empty()) {
|
||||
INTELL_VOICE_LOG_ERROR("bundle name is empty or ability name is empty");
|
||||
return;
|
||||
}
|
||||
want.SetElementName(bundleName, abilityName);
|
||||
want.SetParam("serviceName", std::string("intell_voice"));
|
||||
want.SetParam("servicePid", getpid());
|
||||
want.SetParam("eventType", event);
|
||||
want.SetParam("supportOneShot", true);
|
||||
auto abilityManagerClient = AAFwk::AbilityManagerClient::GetInstance();
|
||||
if (abilityManagerClient == nullptr) {
|
||||
INTELL_VOICE_LOG_ERROR("abilityManagerClient is nullptr");
|
||||
return;
|
||||
}
|
||||
abilityManagerClient->StartAbility(want);
|
||||
}
|
||||
|
||||
int32_t WakeupEngine::HandleHeadsetOff()
|
||||
{
|
||||
{
|
||||
|
||||
@@ -58,6 +58,7 @@ private:
|
||||
int32_t HandleHeadsetOff();
|
||||
int32_t HandleHeadsetOn();
|
||||
int32_t HandleCapturerMsg(StateMsg &msg);
|
||||
static void StartAbility(const std::string &event);
|
||||
USE_ROLE(WakeupEngineImpl);
|
||||
|
||||
private:
|
||||
|
||||
@@ -65,7 +65,7 @@ ohos_source_set("server_source") {
|
||||
"ipc:ipc_core",
|
||||
"kv_store:distributeddata_inner",
|
||||
"safwk:system_ability_fwk",
|
||||
"samgr:samgr_proxy",
|
||||
"samgr:samgr_proxy"
|
||||
]
|
||||
|
||||
sanitize = {
|
||||
@@ -91,6 +91,9 @@ ohos_source_set("server_source") {
|
||||
|
||||
if (intelligent_voice_framework_only_first_stage) {
|
||||
cflags_cc += [ "-DONLY_FIRST_STAGE" ]
|
||||
if (intelligent_voice_framework_first_stage_oneshot_enable) {
|
||||
cflags_cc += [ "-DFIRST_STAGE_ONESHOT_ENABLE" ]
|
||||
}
|
||||
}
|
||||
|
||||
subsystem_name = "ai"
|
||||
|
||||
@@ -45,7 +45,7 @@ template<typename T, typename E>
|
||||
IntellVoiceServiceManager<T, E>::IntellVoiceServiceManager() : TaskExecutor("ServMgrThread", MAX_TASK_NUM)
|
||||
{
|
||||
TaskExecutor::StartThread();
|
||||
#ifdef ENGINE_ENABLE
|
||||
#if defined(ENGINE_ENABLE) || defined(FIRST_STAGE_ONESHOT_ENABLE)
|
||||
RegisterEngineCallbacks();
|
||||
#endif
|
||||
#ifdef TRIGGER_ENABLE
|
||||
@@ -444,7 +444,7 @@ void IntellVoiceServiceManager<T, E>::CreateAndStartServiceObject(int32_t uuid,
|
||||
return;
|
||||
}
|
||||
|
||||
#ifndef ONLY_FIRST_STAGE
|
||||
#if defined(ENGINE_ENABLE) || defined(FIRST_STAGE_ONESHOT_ENABLE)
|
||||
INTELL_VOICE_LOG_INFO("is not single wakeup level");
|
||||
if (!needResetAdapter) {
|
||||
E::CreateEngine(INTELL_VOICE_WAKEUP);
|
||||
@@ -800,7 +800,13 @@ int32_t IntellVoiceServiceManager<T, E>::EngineSetParameter(const std::string &k
|
||||
historyInfoMgr.SetStringKVPair(KEY_WAKEUP_ENGINE_ABILITY_NAME, it.second);
|
||||
#ifdef ONLY_FIRST_STAGE
|
||||
} else if (it.first == std::string("record_start")) {
|
||||
#ifndef FIRST_STAGE_ONESHOT_ENABLE
|
||||
ResetSingleLevelWakeup(it.second);
|
||||
#else
|
||||
std::string keyValue = it.first;
|
||||
keyValue.append("=").append(it.second);
|
||||
E::SetParameter(keyValue);
|
||||
#endif
|
||||
#endif
|
||||
} else {
|
||||
INTELL_VOICE_LOG_INFO("no need to process, key:%{public}s", it.first.c_str());
|
||||
|
||||
@@ -23,11 +23,14 @@
|
||||
|
||||
#ifdef ENGINE_ENABLE
|
||||
#include "intell_voice_engine_manager.h"
|
||||
#elif defined(FIRST_STAGE_ONESHOT_ENABLE)
|
||||
#include "only_first_engine_manager.h"
|
||||
#else
|
||||
#include "dummy_engine_manager.h"
|
||||
#include "ffrt_api.h"
|
||||
#endif
|
||||
|
||||
#include "ffrt_api.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace IntellVoiceEngine {
|
||||
template<typename T, typename E>
|
||||
@@ -39,6 +42,8 @@ using TriggerManagerType = OHOS::IntellVoiceTrigger::DummyTriggerManager;
|
||||
#endif
|
||||
#ifdef ENGINE_ENABLE
|
||||
using EngineManagerType = IntellVoiceEngineManager;
|
||||
#elif defined(FIRST_STAGE_ONESHOT_ENABLE)
|
||||
using EngineManagerType = OnlyFirstEngineManager;
|
||||
#else
|
||||
using EngineManagerType = DummyEngineManager;
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user