10485dae0Sopenharmony_ci# AI<a name="EN-US_TOPIC_0000001072614474"></a> 20485dae0Sopenharmony_ci 30485dae0Sopenharmony_ci- [Introduction](#section187321516154516) 40485dae0Sopenharmony_ci- [Directory Structure](#section571610913453) 50485dae0Sopenharmony_ci- [Constraints](#section5748426453) 60485dae0Sopenharmony_ci- [Usage](#section6370123616447) 70485dae0Sopenharmony_ci- [Repositories Involved](#section10492183517430) 80485dae0Sopenharmony_ci- [Reference](#section6808423133718) 90485dae0Sopenharmony_ci 100485dae0Sopenharmony_ci## Introduction<a name="section187321516154516"></a> 110485dae0Sopenharmony_ci 120485dae0Sopenharmony_ciThe AI subsystem is the part of OpenHarmony that provides native distributed AI capabilities. At the heart of the subsystem is a unified AI engine framework, which implements quick integration of AI algorithm plug-ins. The framework consists of the plug-in management, module management, and communication management modules, fulfilling lifecycle management and on-demand deployment of AI algorithms. Under this framework, AI algorithm APIs will be standardized to facilitate distributed calling of AI capabilities. In addition, unified inference APIs will be provided to adapt to different inference framework hierarchies. 130485dae0Sopenharmony_ci 140485dae0Sopenharmony_ci**Figure 1** AI engine framework<a name="fig17296164711526"></a> 150485dae0Sopenharmony_ci 160485dae0Sopenharmony_ci 170485dae0Sopenharmony_ci## Directory Structure<a name="section571610913453"></a> 180485dae0Sopenharmony_ci 190485dae0Sopenharmony_ci``` 200485dae0Sopenharmony_ci/foundation/ai/ai_engine # Home directory of the AI subsystem 210485dae0Sopenharmony_ci├── interfaces 220485dae0Sopenharmony_ci│ └── kits # External APIs of the AI subsystem 230485dae0Sopenharmony_ci└── services 240485dae0Sopenharmony_ci│ ├── client # Client module of the AI subsystem 250485dae0Sopenharmony_ci│ │ ├── client_executor # Executor of the client module 260485dae0Sopenharmony_ci│ │ └── communication_adapter # Communication adaptation layer for the client module, with extension supported 270485dae0Sopenharmony_ci│ ├── common # Common tools and protocol modules of the AI subsystem 280485dae0Sopenharmony_ci│ │ ├── platform 290485dae0Sopenharmony_ci│ │ ├── protocol 300485dae0Sopenharmony_ci│ │ └── utils 310485dae0Sopenharmony_ci│ └── server # Server module of the AI subsystem 320485dae0Sopenharmony_ci│ │ ├── communication_adapter # Communication adaptation layer for the server module, with extension supported 330485dae0Sopenharmony_ci│ │ ├── plugin 340485dae0Sopenharmony_ci│ │ ├── asr 350485dae0Sopenharmony_ci│ │ └── keyword_spotting # ASR algorithm plug-in reference: keyword spotting 360485dae0Sopenharmony_ci│ │ └── cv 370485dae0Sopenharmony_ci│ │ └── image_classification # CV algorithm plug-in reference: image classification 380485dae0Sopenharmony_ci│ │ ├── plugin_manager 390485dae0Sopenharmony_ci│ │ └── server_executor # Executor of the server module 400485dae0Sopenharmony_ci``` 410485dae0Sopenharmony_ci 420485dae0Sopenharmony_ci## Constraints<a name="section5748426453"></a> 430485dae0Sopenharmony_ci 440485dae0Sopenharmony_ci**Programming language**: C/C++ 450485dae0Sopenharmony_ci 460485dae0Sopenharmony_ci**Operating system**: OpenHarmony 470485dae0Sopenharmony_ci 480485dae0Sopenharmony_ci**Others**: The System Ability Manager \(Samgr\) has been started and is running properly. 490485dae0Sopenharmony_ci 500485dae0Sopenharmony_ci## Usage<a name="section6370123616447"></a> 510485dae0Sopenharmony_ci 520485dae0Sopenharmony_ci1. Compile the AI subsystem. 530485dae0Sopenharmony_ci 540485dae0Sopenharmony_ci The source code for lightweight AI framework is available at **//foundation/ai/ai_engine/services**. 550485dae0Sopenharmony_ci 560485dae0Sopenharmony_ci The compilation procedure is as follows: 570485dae0Sopenharmony_ci 580485dae0Sopenharmony_ci 1. Set the compilation path. 590485dae0Sopenharmony_ci 600485dae0Sopenharmony_ci ``` 610485dae0Sopenharmony_ci hb set -root dir (root dir is the root directory of the project code.) 620485dae0Sopenharmony_ci ``` 630485dae0Sopenharmony_ci 640485dae0Sopenharmony_ci 2. Specify the product for compilation. \(After the product list is displayed using the following command, move to the desired product with arrow keys and press **Enter**.\) 650485dae0Sopenharmony_ci 660485dae0Sopenharmony_ci ``` 670485dae0Sopenharmony_ci hb set -p 680485dae0Sopenharmony_ci ``` 690485dae0Sopenharmony_ci 700485dae0Sopenharmony_ci 3. Start compilation. 710485dae0Sopenharmony_ci 720485dae0Sopenharmony_ci ``` 730485dae0Sopenharmony_ci hb build -f (Use this command if you want to compile the entire repository.) 740485dae0Sopenharmony_ci hb build ai_engine (Use this command if you want to compile only the ai_engine module.) 750485dae0Sopenharmony_ci ``` 760485dae0Sopenharmony_ci 770485dae0Sopenharmony_ci **Note**: For details about the hb configuration, see the readme of the build\_lite subsystem. 780485dae0Sopenharmony_ci 790485dae0Sopenharmony_ci2. Develop the plug-in, with keyword spotting as an example. 800485dae0Sopenharmony_ci 810485dae0Sopenharmony_ci Directory: //foundation/ai/ai_engine/services/server/plugin/asr/keyword\_spotting 820485dae0Sopenharmony_ci 830485dae0Sopenharmony_ci **Note**: The plug-in must implement the **IPlugin** and **IPluginCallback** APIs provided by the server. 840485dae0Sopenharmony_ci 850485dae0Sopenharmony_ci ``` 860485dae0Sopenharmony_ci #include "plugin/i_plugin.h 870485dae0Sopenharmony_ci class KWSPlugin : public IPlugin { # Inherits the public base class of the IPlugin API for Keywords Spotting Plugin (KWSPlugin). 880485dae0Sopenharmony_ci KWSPlugin(); 890485dae0Sopenharmony_ci ~KWSPlugin(); 900485dae0Sopenharmony_ci 910485dae0Sopenharmony_ci const long long GetVersion() const override; 920485dae0Sopenharmony_ci const char* GetName() const override; 930485dae0Sopenharmony_ci const char* GetInferMode() const override; 940485dae0Sopenharmony_ci 950485dae0Sopenharmony_ci int32_t Prepare(long long transactionId, const DataInfo &amp;inputInfo, DataInfo &amp;outputInfo) override; 960485dae0Sopenharmony_ci int32_t SetOption(int optionType, const DataInfo &amp;inputInfo) override; 970485dae0Sopenharmony_ci int32_t GetOption(int optionType, const DataInfo &amp;inputInfo, DataInfo &amp;outputInfo) override; 980485dae0Sopenharmony_ci int32_t SyncProcess(IRequest *request, IResponse *&amp;response) override; 990485dae0Sopenharmony_ci int32_t AsyncProcess(IRequest *request, IPluginCallback*callback) override; 1000485dae0Sopenharmony_ci int32_t Release(bool isFullUnload, long long transactionId, const DataInfo &amp;inputInfo) override; 1010485dae0Sopenharmony_ci . 1020485dae0Sopenharmony_ci . 1030485dae0Sopenharmony_ci . 1040485dae0Sopenharmony_ci }; 1050485dae0Sopenharmony_ci ``` 1060485dae0Sopenharmony_ci 1070485dae0Sopenharmony_ci **Note**: Depending on the algorithm in use, you only need to implement the **SyncProcess** or **AsyncProcess** API. Use an empty function as a placeholder for the other API. In this example, the KWS plug-in uses the synchronous algorithm. Therefore, you need to implement **SyncProcess** API and use an empty function as a placeholder for the **SyncProcess** API. 1080485dae0Sopenharmony_ci 1090485dae0Sopenharmony_ci ``` 1100485dae0Sopenharmony_ci #include "aie_log.h" 1110485dae0Sopenharmony_ci #include "aie_retcode_inner.h" 1120485dae0Sopenharmony_ci . 1130485dae0Sopenharmony_ci . 1140485dae0Sopenharmony_ci . 1150485dae0Sopenharmony_ci 1160485dae0Sopenharmony_ci const long long KWSPlugin::GetVersion() const 1170485dae0Sopenharmony_ci { 1180485dae0Sopenharmony_ci return ALGOTYPE_VERSION_KWS; 1190485dae0Sopenharmony_ci } 1200485dae0Sopenharmony_ci 1210485dae0Sopenharmony_ci const char *KWSPlugin::GetName() const 1220485dae0Sopenharmony_ci { 1230485dae0Sopenharmony_ci return ALGORITHM_NAME_KWS.c_str(); 1240485dae0Sopenharmony_ci } 1250485dae0Sopenharmony_ci 1260485dae0Sopenharmony_ci const char *KWSPlugin::GetInferMode() const 1270485dae0Sopenharmony_ci { 1280485dae0Sopenharmony_ci return DEFAULT_INFER_MODE.c_str(); 1290485dae0Sopenharmony_ci } 1300485dae0Sopenharmony_ci . 1310485dae0Sopenharmony_ci . 1320485dae0Sopenharmony_ci . 1330485dae0Sopenharmony_ci int32_t KWSPlugin::AsyncProcess(IRequest *request, IPluginCallback *callback) 1340485dae0Sopenharmony_ci { 1350485dae0Sopenharmony_ci return RETCODE_SUCCESS; 1360485dae0Sopenharmony_ci } 1370485dae0Sopenharmony_ci ``` 1380485dae0Sopenharmony_ci 1390485dae0Sopenharmony_ci3. Develop the SDK, with keyword spotting as an example. 1400485dae0Sopenharmony_ci 1410485dae0Sopenharmony_ci Directory: //foundation/ai/ai_engine/services/client/algorithm\_sdk/asr/keyword\_spotting 1420485dae0Sopenharmony_ci 1430485dae0Sopenharmony_ci Keyword spotting SDK: 1440485dae0Sopenharmony_ci 1450485dae0Sopenharmony_ci ``` 1460485dae0Sopenharmony_ci class KWSSdk { 1470485dae0Sopenharmony_ci public: 1480485dae0Sopenharmony_ci KWSSdk(); 1490485dae0Sopenharmony_ci virtual ~KWSSdk(); 1500485dae0Sopenharmony_ci 1510485dae0Sopenharmony_ci /** 1520485dae0Sopenharmony_ci * @brief Create a new session with KWS Plugin 1530485dae0Sopenharmony_ci * 1540485dae0Sopenharmony_ci * @return Returns KWS_RETCODE_SUCCESS(0) if the operation is successful, 1550485dae0Sopenharmony_ci * returns a non-zero value otherwise. 1560485dae0Sopenharmony_ci */ 1570485dae0Sopenharmony_ci int32_t Create(); 1580485dae0Sopenharmony_ci 1590485dae0Sopenharmony_ci /** 1600485dae0Sopenharmony_ci * @brief Synchronously execute keyword spotting once 1610485dae0Sopenharmony_ci * 1620485dae0Sopenharmony_ci * @param audioInput pcm data. 1630485dae0Sopenharmony_ci * @return Returns KWS_RETCODE_SUCCESS(0) if the operation is successful, 1640485dae0Sopenharmony_ci * returns a non-zero value otherwise. 1650485dae0Sopenharmony_ci */ 1660485dae0Sopenharmony_ci int32_t SyncExecute(const Array<int16_t> &audioInput); 1670485dae0Sopenharmony_ci 1680485dae0Sopenharmony_ci /** 1690485dae0Sopenharmony_ci * @brief Asynchronously execute keyword spotting once 1700485dae0Sopenharmony_ci * 1710485dae0Sopenharmony_ci * @param audioInput pcm data. 1720485dae0Sopenharmony_ci * @return Returns KWS_RETCODE_SUCCESS(0) if the operation is successful, 1730485dae0Sopenharmony_ci * returns a non-zero value otherwise. 1740485dae0Sopenharmony_ci */ 1750485dae0Sopenharmony_ci int32_t AsyncExecute(const Array<int16_t> &audioInput); 1760485dae0Sopenharmony_ci 1770485dae0Sopenharmony_ci /** 1780485dae0Sopenharmony_ci * @brief Set callback 1790485dae0Sopenharmony_ci * 1800485dae0Sopenharmony_ci * @param callback Callback function that will be called during the process. 1810485dae0Sopenharmony_ci * @return Returns KWS_RETCODE_SUCCESS(0) if the operation is successful, 1820485dae0Sopenharmony_ci * returns a non-zero value otherwise. 1830485dae0Sopenharmony_ci */ 1840485dae0Sopenharmony_ci int32_t SetCallback(const std::shared_ptr<KWSCallback> &callback); 1850485dae0Sopenharmony_ci 1860485dae0Sopenharmony_ci /** 1870485dae0Sopenharmony_ci * @brief Destroy the created session with KWS Plugin 1880485dae0Sopenharmony_ci * 1890485dae0Sopenharmony_ci * @return Returns KWS_RETCODE_SUCCESS(0) if the operation is successful, 1900485dae0Sopenharmony_ci * returns a non-zero value otherwise. 1910485dae0Sopenharmony_ci */ 1920485dae0Sopenharmony_ci int32_t Destroy(); 1930485dae0Sopenharmony_ci ``` 1940485dae0Sopenharmony_ci 1950485dae0Sopenharmony_ci **Note**: The sequence for the SDK to call client APIs of the AI engine is as follows: AieClientInit -\> AieClientPrepare -\> AieClientSyncProcess/AieClientAsyncProcess -\> AieClientRelease -\> AieClientDestroy. An exception will be thrown if the call sequence is violated. In addition, all these APIs must be called. Otherwise, a memory leakage may occur. 1960485dae0Sopenharmony_ci 1970485dae0Sopenharmony_ci ``` 1980485dae0Sopenharmony_ci int32_t KWSSdk::KWSSdkImpl::Create() 1990485dae0Sopenharmony_ci { 2000485dae0Sopenharmony_ci if (kwsHandle_ != INVALID_KWS_HANDLE) { 2010485dae0Sopenharmony_ci HILOGE("[KWSSdkImpl]The SDK has been created"); 2020485dae0Sopenharmony_ci return KWS_RETCODE_FAILURE; 2030485dae0Sopenharmony_ci } 2040485dae0Sopenharmony_ci if (InitComponents() != RETCODE_SUCCESS) { 2050485dae0Sopenharmony_ci HILOGE("[KWSSdkImpl]Fail to init sdk components"); 2060485dae0Sopenharmony_ci return KWS_RETCODE_FAILURE; 2070485dae0Sopenharmony_ci } 2080485dae0Sopenharmony_ci int32_t retCode = AieClientInit(configInfo_, clientInfo_, algorithmInfo_, nullptr); 2090485dae0Sopenharmony_ci if (retCode != RETCODE_SUCCESS) { 2100485dae0Sopenharmony_ci HILOGE("[KWSSdkImpl]AieClientInit failed. Error code[%d]", retCode); 2110485dae0Sopenharmony_ci return KWS_RETCODE_FAILURE; 2120485dae0Sopenharmony_ci } 2130485dae0Sopenharmony_ci if (clientInfo_.clientId == INVALID_CLIENT_ID) { 2140485dae0Sopenharmony_ci HILOGE("[KWSSdkImpl]Fail to allocate client id"); 2150485dae0Sopenharmony_ci return KWS_RETCODE_FAILURE; 2160485dae0Sopenharmony_ci } 2170485dae0Sopenharmony_ci DataInfo inputInfo = { 2180485dae0Sopenharmony_ci .data = nullptr, 2190485dae0Sopenharmony_ci .length = 0, 2200485dae0Sopenharmony_ci }; 2210485dae0Sopenharmony_ci DataInfo outputInfo = { 2220485dae0Sopenharmony_ci .data = nullptr, 2230485dae0Sopenharmony_ci .length = 0, 2240485dae0Sopenharmony_ci }; 2250485dae0Sopenharmony_ci retCode = AieClientPrepare(clientInfo_, algorithmInfo_, inputInfo, outputInfo, nullptr); 2260485dae0Sopenharmony_ci if (retCode != RETCODE_SUCCESS) { 2270485dae0Sopenharmony_ci HILOGE("[KWSSdkImpl]AieclientPrepare failed. Error code[%d]", retCode); 2280485dae0Sopenharmony_ci return KWS_RETCODE_FAILURE; 2290485dae0Sopenharmony_ci } 2300485dae0Sopenharmony_ci if (outputInfo.data == nullptr || outputInfo.length <= 0) { 2310485dae0Sopenharmony_ci HILOGE("[KWSSdkImpl]The data or length of output info is invalid"); 2320485dae0Sopenharmony_ci return KWS_RETCODE_FAILURE; 2330485dae0Sopenharmony_ci } 2340485dae0Sopenharmony_ci MallocPointerGuard<unsigned char> pointerGuard(outputInfo.data); 2350485dae0Sopenharmony_ci retCode = PluginHelper::UnSerializeHandle(outputInfo, kwsHandle_); 2360485dae0Sopenharmony_ci if (retCode != RETCODE_SUCCESS) { 2370485dae0Sopenharmony_ci HILOGE("[KWSSdkImpl]Get handle from inputInfo failed"); 2380485dae0Sopenharmony_ci return KWS_RETCODE_FAILURE; 2390485dae0Sopenharmony_ci } 2400485dae0Sopenharmony_ci return KWS_RETCODE_SUCCESS; 2410485dae0Sopenharmony_ci } 2420485dae0Sopenharmony_ci 2430485dae0Sopenharmony_ci int32_t KWSSdk::KWSSdkImpl::SyncExecute(const Array<uint16_t> &audioInput) 2440485dae0Sopenharmony_ci { 2450485dae0Sopenharmony_ci intptr_t newHandle = 0; 2460485dae0Sopenharmony_ci Array<int32_t> kwsResult = { 2470485dae0Sopenharmony_ci .data = nullptr, 2480485dae0Sopenharmony_ci .size = 0 2490485dae0Sopenharmony_ci }; 2500485dae0Sopenharmony_ci DataInfo inputInfo = { 2510485dae0Sopenharmony_ci .data = nullptr, 2520485dae0Sopenharmony_ci .length = 0 2530485dae0Sopenharmony_ci }; 2540485dae0Sopenharmony_ci DataInfo outputInfo = { 2550485dae0Sopenharmony_ci .data = nullptr, 2560485dae0Sopenharmony_ci .length = 0 2570485dae0Sopenharmony_ci }; 2580485dae0Sopenharmony_ci int32_t retCode = PluginHelper::SerializeInputData(kwsHandle_, audioInput, inputInfo); 2590485dae0Sopenharmony_ci if (retCode != RETCODE_SUCCESS) { 2600485dae0Sopenharmony_ci HILOGE("[KWSSdkImpl]Fail to serialize input data"); 2610485dae0Sopenharmony_ci callback_->OnError(KWS_RETCODE_SERIALIZATION_ERROR); 2620485dae0Sopenharmony_ci return RETCODE_FAILURE; 2630485dae0Sopenharmony_ci } 2640485dae0Sopenharmony_ci retCode = AieClientSyncProcess(clientInfo_, algorithmInfo_, inputInfo, outputInfo); 2650485dae0Sopenharmony_ci if (retCode != RETCODE_SUCCESS) { 2660485dae0Sopenharmony_ci HILOGE("[KWSSdkImpl]AieClientSyncProcess failed. Error code[%d]", retCode); 2670485dae0Sopenharmony_ci callback_->OnError(KWS_RETCODE_PLUGIN_EXECUTION_ERROR); 2680485dae0Sopenharmony_ci return RETCODE_FAILURE; 2690485dae0Sopenharmony_ci } 2700485dae0Sopenharmony_ci if (outputInfo.data == nullptr || outputInfo.length <= 0) { 2710485dae0Sopenharmony_ci HILOGE("[KWSSdkImpl] The data or length of outputInfo is invalid. Error code[%d]", retCode); 2720485dae0Sopenharmony_ci callback_->OnError(KWS_RETCODE_NULL_PARAM); 2730485dae0Sopenharmony_ci return RETCODE_FAILURE; 2740485dae0Sopenharmony_ci } 2750485dae0Sopenharmony_ci MallocPointerGuard<unsigned char> pointerGuard(outputInfo.data); 2760485dae0Sopenharmony_ci retCode = PluginHelper::UnSerializeOutputData(outputInfo, newHandle, kwsResult); 2770485dae0Sopenharmony_ci if (retCode != RETCODE_SUCCESS) { 2780485dae0Sopenharmony_ci HILOGE("[KWSSdkImpl]UnSerializeOutputData failed. Error code[%d]", retCode); 2790485dae0Sopenharmony_ci callback_->OnError(KWS_RETCODE_UNSERIALIZATION_ERROR); 2800485dae0Sopenharmony_ci return retCode; 2810485dae0Sopenharmony_ci } 2820485dae0Sopenharmony_ci if (kwsHandle_ != newHandle) { 2830485dae0Sopenharmony_ci HILOGE("[KWSSdkImpl]The handle[%lld] of output data is not equal to the current handle[%lld]", 2840485dae0Sopenharmony_ci (long long)newHandle, (long long)kwsHandle_); 2850485dae0Sopenharmony_ci callback_->OnError(KWS_RETCODE_PLUGIN_SESSION_ERROR); 2860485dae0Sopenharmony_ci return RETCODE_FAILURE; 2870485dae0Sopenharmony_ci } 2880485dae0Sopenharmony_ci callback_->OnResult(kwsResult); 2890485dae0Sopenharmony_ci return RETCODE_SUCCESS; 2900485dae0Sopenharmony_ci } 2910485dae0Sopenharmony_ci 2920485dae0Sopenharmony_ci int32_t KWSSdk::KWSSdkImpl::Destroy() 2930485dae0Sopenharmony_ci { 2940485dae0Sopenharmony_ci if (kwsHandle_ == INVALID_KWS_HANDLE) { 2950485dae0Sopenharmony_ci return KWS_RETCODE_SUCCESS; 2960485dae0Sopenharmony_ci } 2970485dae0Sopenharmony_ci DataInfo inputInfo = { 2980485dae0Sopenharmony_ci .data = nullptr, 2990485dae0Sopenharmony_ci .length = 0 3000485dae0Sopenharmony_ci }; 3010485dae0Sopenharmony_ci int32_t retCode = PluginHelper::SerializeHandle(kwsHandle_, inputInfo); 3020485dae0Sopenharmony_ci if (retCode != RETCODE_SUCCESS) { 3030485dae0Sopenharmony_ci HILOGE("[KWSSdkImpl]SerializeHandle failed. Error code[%d]", retCode); 3040485dae0Sopenharmony_ci return KWS_RETCODE_FAILURE; 3050485dae0Sopenharmony_ci } 3060485dae0Sopenharmony_ci retCode = AieClientRelease(clientInfo_, algorithmInfo_, inputInfo); 3070485dae0Sopenharmony_ci if (retCode != RETCODE_SUCCESS) { 3080485dae0Sopenharmony_ci HILOGE("[KWSSdkImpl]AieClientRelease failed. Error code[%d]", retCode); 3090485dae0Sopenharmony_ci return KWS_RETCODE_FAILURE; 3100485dae0Sopenharmony_ci } 3110485dae0Sopenharmony_ci retCode = AieClientDestroy(clientInfo_); 3120485dae0Sopenharmony_ci if (retCode != RETCODE_SUCCESS) { 3130485dae0Sopenharmony_ci HILOGE("[KWSSdkImpl]AieClientDestroy failed. Error code[%d]", retCode); 3140485dae0Sopenharmony_ci return KWS_RETCODE_FAILURE; 3150485dae0Sopenharmony_ci } 3160485dae0Sopenharmony_ci mfccProcessor_ = nullptr; 3170485dae0Sopenharmony_ci pcmIterator_ = nullptr; 3180485dae0Sopenharmony_ci callback_ = nullptr; 3190485dae0Sopenharmony_ci kwsHandle_ = INVALID_KWS_HANDLE; 3200485dae0Sopenharmony_ci return KWS_RETCODE_SUCCESS; 3210485dae0Sopenharmony_ci } 3220485dae0Sopenharmony_ci ``` 3230485dae0Sopenharmony_ci 3240485dae0Sopenharmony_ci4. **Sample development** \(similar to keyword spotting\) 3250485dae0Sopenharmony_ci 3260485dae0Sopenharmony_ci Directory: //applications/sample/camera/ai/asr/keyword\_spotting 3270485dae0Sopenharmony_ci 3280485dae0Sopenharmony_ci Call the **Create** API. 3290485dae0Sopenharmony_ci 3300485dae0Sopenharmony_ci ``` 3310485dae0Sopenharmony_ci bool KwsManager::PreparedInference() 3320485dae0Sopenharmony_ci { 3330485dae0Sopenharmony_ci if (capturer_ == nullptr) { 3340485dae0Sopenharmony_ci printf("[KwsManager] only load plugin after AudioCapturer ready\n"); 3350485dae0Sopenharmony_ci return false; 3360485dae0Sopenharmony_ci } 3370485dae0Sopenharmony_ci if (plugin_ != nullptr) { 3380485dae0Sopenharmony_ci printf("[KwsManager] stop created InferencePlugin at first\n"); 3390485dae0Sopenharmony_ci StopInference(); 3400485dae0Sopenharmony_ci } 3410485dae0Sopenharmony_ci plugin_ = std::make_shared<KWSSdk>(); 3420485dae0Sopenharmony_ci if (plugin_ == nullptr) { 3430485dae0Sopenharmony_ci printf("[KwsManager] fail to create inferencePlugin\n"); 3440485dae0Sopenharmony_ci return false; 3450485dae0Sopenharmony_ci } 3460485dae0Sopenharmony_ci if (plugin_->Create() != SUCCESS) { 3470485dae0Sopenharmony_ci printf("[KwsManager] KWSSdk fail to create.\n"); 3480485dae0Sopenharmony_ci return false; 3490485dae0Sopenharmony_ci } 3500485dae0Sopenharmony_ci std::shared_ptr<KWSCallback> callback = std::make_shared<MyKwsCallback>(); 3510485dae0Sopenharmony_ci if (callback == nullptr) { 3520485dae0Sopenharmony_ci printf("[KwsManager] new Callback failed.\n"); 3530485dae0Sopenharmony_ci return false; 3540485dae0Sopenharmony_ci } 3550485dae0Sopenharmony_ci plugin_->SetCallback(callback); 3560485dae0Sopenharmony_ci return true; 3570485dae0Sopenharmony_ci } 3580485dae0Sopenharmony_ci ``` 3590485dae0Sopenharmony_ci 3600485dae0Sopenharmony_ci Call the **SyncExecute** API. 3610485dae0Sopenharmony_ci 3620485dae0Sopenharmony_ci ``` 3630485dae0Sopenharmony_ci void KwsManager::ConsumeSamples() 3640485dae0Sopenharmony_ci { 3650485dae0Sopenharmony_ci uintptr_t sampleAddr = 0; 3660485dae0Sopenharmony_ci size_t sampleSize = 0; 3670485dae0Sopenharmony_ci int32_t retCode = SUCCESS; 3680485dae0Sopenharmony_ci while (status_ == RUNNING) { 3690485dae0Sopenharmony_ci { 3700485dae0Sopenharmony_ci std::lock_guard<std::mutex> lock(mutex_); 3710485dae0Sopenharmony_ci if (cache_ == nullptr) { 3720485dae0Sopenharmony_ci printf("[KwsManager] cache_ is nullptr.\n"); 3730485dae0Sopenharmony_ci break; 3740485dae0Sopenharmony_ci } 3750485dae0Sopenharmony_ci sampleSize = cache_->GetCapturedBuffer(sampleAddr); 3760485dae0Sopenharmony_ci } 3770485dae0Sopenharmony_ci if (sampleSize == 0 || sampleAddr == 0) { 3780485dae0Sopenharmony_ci continue; 3790485dae0Sopenharmony_ci } 3800485dae0Sopenharmony_ci Array<int16_t> input = { 3810485dae0Sopenharmony_ci .data = (int16_t *)(sampleAddr), 3820485dae0Sopenharmony_ci .size = sampleSize >> 1 3830485dae0Sopenharmony_ci }; 3840485dae0Sopenharmony_ci { 3850485dae0Sopenharmony_ci std::lock_guard<std::mutex> lock(mutex_); 3860485dae0Sopenharmony_ci if (plugin_ == nullptr) { 3870485dae0Sopenharmony_ci printf("[KwsManager] cache_ is nullptr.\n"); 3880485dae0Sopenharmony_ci break; 3890485dae0Sopenharmony_ci } 3900485dae0Sopenharmony_ci if ((retCode = plugin_->SyncExecute(input)) != SUCCESS) { 3910485dae0Sopenharmony_ci printf("[KwsManager] SyncExecute KWS failed with retCode = [%d]\n", retCode); 3920485dae0Sopenharmony_ci continue; 3930485dae0Sopenharmony_ci } 3940485dae0Sopenharmony_ci } 3950485dae0Sopenharmony_ci } 3960485dae0Sopenharmony_ci } 3970485dae0Sopenharmony_ci ``` 3980485dae0Sopenharmony_ci 3990485dae0Sopenharmony_ci Call the **Destroy** API. 4000485dae0Sopenharmony_ci 4010485dae0Sopenharmony_ci ``` 4020485dae0Sopenharmony_ci void KwsManager::StopInference() 4030485dae0Sopenharmony_ci { 4040485dae0Sopenharmony_ci printf("[KwsManager] StopInference\n"); 4050485dae0Sopenharmony_ci if (plugin_ != nullptr) { 4060485dae0Sopenharmony_ci int ret = plugin_->Destroy(); 4070485dae0Sopenharmony_ci if (ret != SUCCESS) { 4080485dae0Sopenharmony_ci printf("[KwsManager] plugin_ destroy failed.\n"); 4090485dae0Sopenharmony_ci } 4100485dae0Sopenharmony_ci plugin_ = nullptr; 4110485dae0Sopenharmony_ci } 4120485dae0Sopenharmony_ci } 4130485dae0Sopenharmony_ci ``` 4140485dae0Sopenharmony_ci 4150485dae0Sopenharmony_ci 4160485dae0Sopenharmony_ci## Repositories Involved<a name="section10492183517430"></a> 4170485dae0Sopenharmony_ci 4180485dae0Sopenharmony_ci[AI subsystem](https://gitee.com/openharmony/docs/blob/master/en/readme/ai.md) 4190485dae0Sopenharmony_ci 4200485dae0Sopenharmony_ci**ai\_engine** 4210485dae0Sopenharmony_ci 4220485dae0Sopenharmony_ciDependency repositories: 4230485dae0Sopenharmony_ci 4240485dae0Sopenharmony_ci[build\_lite](https://gitee.com/openharmony/build_lite/blob/master/README.md) 4250485dae0Sopenharmony_ci 4260485dae0Sopenharmony_ci[distributedschedule\_samgr\_lite](https://gitee.com/openharmony/distributedschedule_samgr_lite/blob/master/README.md) 4270485dae0Sopenharmony_ci 4280485dae0Sopenharmony_ci[startup\_init\_lite](https://gitee.com/openharmony/startup_init_lite/blob/master/README.md) 4290485dae0Sopenharmony_ci 4300485dae0Sopenharmony_ci## Reference<a name="section6808423133718"></a> 4310485dae0Sopenharmony_ci 4320485dae0Sopenharmony_ci- [AI Engine Framework Development Guide](https://gitee.com/openharmony/docs/blob/master/en/device-dev/subsystems/subsys-ai-aiframework-devguide.md) 433