1e41f4b71Sopenharmony_ci# AI 2e41f4b71Sopenharmony_ci 3e41f4b71Sopenharmony_ci## Introduction 4e41f4b71Sopenharmony_ci 5e41f4b71Sopenharmony_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. 6e41f4b71Sopenharmony_ci 7e41f4b71Sopenharmony_ci**Figure 1** AI engine framework<a name="fig17296164711526"></a> 8e41f4b71Sopenharmony_ci 9e41f4b71Sopenharmony_ci 10e41f4b71Sopenharmony_ci## Directory Structure 11e41f4b71Sopenharmony_ci 12e41f4b71Sopenharmony_ci``` 13e41f4b71Sopenharmony_ci/foundation/ai/engine # Home directory of the AI subsystem 14e41f4b71Sopenharmony_ci├── interfaces 15e41f4b71Sopenharmony_ci│ └── kits # External APIs of the AI subsystem 16e41f4b71Sopenharmony_ci└── services 17e41f4b71Sopenharmony_ci│ ├── client # Client module of the AI subsystem 18e41f4b71Sopenharmony_ci│ │ ├── client_executor # Executor of the client module 19e41f4b71Sopenharmony_ci│ │ └── communication_adapter # Communication adaptation layer for the client module, with extension supported 20e41f4b71Sopenharmony_ci│ ├── common # Common tools and protocol modules of the AI subsystem 21e41f4b71Sopenharmony_ci│ │ ├── platform 22e41f4b71Sopenharmony_ci│ │ ├── protocol 23e41f4b71Sopenharmony_ci│ │ └── utils 24e41f4b71Sopenharmony_ci│ └── server # Server module of the AI subsystem 25e41f4b71Sopenharmony_ci│ │ ├── communication_adapter # Communication adaptation layer for the server module, with extension supported 26e41f4b71Sopenharmony_ci│ │ ├── plugin 27e41f4b71Sopenharmony_ci│ │ ├── asr 28e41f4b71Sopenharmony_ci│ │ └── keyword_spotting # ASR algorithm plug-in reference: keyword spotting 29e41f4b71Sopenharmony_ci│ │ └── cv 30e41f4b71Sopenharmony_ci│ │ └── image_classification # CV algorithm plug-in reference: image classification 31e41f4b71Sopenharmony_ci│ │ ├── plugin_manager 32e41f4b71Sopenharmony_ci│ │ └── server_executor # Executor of the server module 33e41f4b71Sopenharmony_ci``` 34e41f4b71Sopenharmony_ci 35e41f4b71Sopenharmony_ci## Constraints 36e41f4b71Sopenharmony_ci 37e41f4b71Sopenharmony_ci* **Programming language**: C/C++ 38e41f4b71Sopenharmony_ci 39e41f4b71Sopenharmony_ci* **Operating system**: OpenHarmony mini- and small-system 40e41f4b71Sopenharmony_ci 41e41f4b71Sopenharmony_ci* **Others**: The System Ability Manager \(Samgr\) has been started and is running properly. 42e41f4b71Sopenharmony_ci 43e41f4b71Sopenharmony_ci## Usage 44e41f4b71Sopenharmony_ci 45e41f4b71Sopenharmony_ci1. Compile the AI subsystem. 46e41f4b71Sopenharmony_ci 47e41f4b71Sopenharmony_ci The source code for lightweight AI framework is available at **//foundation/ai/engine/services**. 48e41f4b71Sopenharmony_ci 49e41f4b71Sopenharmony_ci The compilation procedure is as follows: 50e41f4b71Sopenharmony_ci 51e41f4b71Sopenharmony_ci 1. Set the compilation path. 52e41f4b71Sopenharmony_ci 53e41f4b71Sopenharmony_ci ``` 54e41f4b71Sopenharmony_ci hb set -root dir (root dir is the root directory of the project code.) 55e41f4b71Sopenharmony_ci ``` 56e41f4b71Sopenharmony_ci 57e41f4b71Sopenharmony_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**.\) 58e41f4b71Sopenharmony_ci 59e41f4b71Sopenharmony_ci ``` 60e41f4b71Sopenharmony_ci hb set -p 61e41f4b71Sopenharmony_ci ``` 62e41f4b71Sopenharmony_ci 63e41f4b71Sopenharmony_ci 3. Start compilation. 64e41f4b71Sopenharmony_ci 65e41f4b71Sopenharmony_ci ``` 66e41f4b71Sopenharmony_ci hb build -f (Use this command if you want to compile the entire repository.) 67e41f4b71Sopenharmony_ci hb build ai_engine (Use this command if you want to compile only the ai_engine module.) 68e41f4b71Sopenharmony_ci ``` 69e41f4b71Sopenharmony_ci 70e41f4b71Sopenharmony_ci >**Note**: For details about the hb configuration, see the readme of the build\_lite subsystem. 71e41f4b71Sopenharmony_ci 72e41f4b71Sopenharmony_ci2. Develop the plug-in, with keyword spotting as an example. 73e41f4b71Sopenharmony_ci 74e41f4b71Sopenharmony_ci Directory: //foundation/ai/engine/services/server/plugin/asr/keyword\_spotting 75e41f4b71Sopenharmony_ci 76e41f4b71Sopenharmony_ci >**Note**: The plug-in must implement the **IPlugin** and **IPluginCallback** APIs provided by the server. 77e41f4b71Sopenharmony_ci 78e41f4b71Sopenharmony_ci ``` 79e41f4b71Sopenharmony_ci #include "plugin/i_plugin.h 80e41f4b71Sopenharmony_ci class KWSPlugin : public IPlugin { // Inherits the public base class of the IPlugin API for Keywords Spotting Plugin (KWSPlugin). 81e41f4b71Sopenharmony_ci KWSPlugin(); 82e41f4b71Sopenharmony_ci ~KWSPlugin(); 83e41f4b71Sopenharmony_ci 84e41f4b71Sopenharmony_ci const long long GetVersion() const override; 85e41f4b71Sopenharmony_ci const char* GetName() const override; 86e41f4b71Sopenharmony_ci const char* GetInferMode() const override; 87e41f4b71Sopenharmony_ci 88e41f4b71Sopenharmony_ci int32_t Prepare(long long transactionId, const DataInfo &amp;inputInfo, DataInfo &amp;outputInfo) override; 89e41f4b71Sopenharmony_ci int32_t SetOption(int optionType, const DataInfo &amp;inputInfo) override; 90e41f4b71Sopenharmony_ci int32_t GetOption(int optionType, const DataInfo &amp;inputInfo, DataInfo &amp;outputInfo) override; 91e41f4b71Sopenharmony_ci int32_t SyncProcess(IRequest *request, IResponse *&amp;response) override; 92e41f4b71Sopenharmony_ci int32_t AsyncProcess(IRequest *request, IPluginCallback*callback) override; 93e41f4b71Sopenharmony_ci int32_t Release(bool isFullUnload, long long transactionId, const DataInfo &amp;inputInfo) override; 94e41f4b71Sopenharmony_ci . 95e41f4b71Sopenharmony_ci . 96e41f4b71Sopenharmony_ci . 97e41f4b71Sopenharmony_ci }; 98e41f4b71Sopenharmony_ci ``` 99e41f4b71Sopenharmony_ci 100e41f4b71Sopenharmony_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. 101e41f4b71Sopenharmony_ci 102e41f4b71Sopenharmony_ci ``` 103e41f4b71Sopenharmony_ci #include "aie_log.h" 104e41f4b71Sopenharmony_ci #include "aie_retcode_inner.h" 105e41f4b71Sopenharmony_ci . 106e41f4b71Sopenharmony_ci . 107e41f4b71Sopenharmony_ci . 108e41f4b71Sopenharmony_ci 109e41f4b71Sopenharmony_ci const long long KWSPlugin::GetVersion() const 110e41f4b71Sopenharmony_ci { 111e41f4b71Sopenharmony_ci return ALGOTYPE_VERSION_KWS; 112e41f4b71Sopenharmony_ci } 113e41f4b71Sopenharmony_ci 114e41f4b71Sopenharmony_ci const char *KWSPlugin::GetName() const 115e41f4b71Sopenharmony_ci { 116e41f4b71Sopenharmony_ci return ALGORITHM_NAME_KWS.c_str(); 117e41f4b71Sopenharmony_ci } 118e41f4b71Sopenharmony_ci 119e41f4b71Sopenharmony_ci const char *KWSPlugin::GetInferMode() const 120e41f4b71Sopenharmony_ci { 121e41f4b71Sopenharmony_ci return DEFAULT_INFER_MODE.c_str(); 122e41f4b71Sopenharmony_ci } 123e41f4b71Sopenharmony_ci . 124e41f4b71Sopenharmony_ci . 125e41f4b71Sopenharmony_ci . 126e41f4b71Sopenharmony_ci int32_t KWSPlugin::AsyncProcess(IRequest *request, IPluginCallback *callback) 127e41f4b71Sopenharmony_ci { 128e41f4b71Sopenharmony_ci return RETCODE_SUCCESS; 129e41f4b71Sopenharmony_ci } 130e41f4b71Sopenharmony_ci ``` 131e41f4b71Sopenharmony_ci 132e41f4b71Sopenharmony_ci3. Develop the SDK, with keyword spotting as an example. 133e41f4b71Sopenharmony_ci 134e41f4b71Sopenharmony_ci Directory: //foundation/ai/engine/services/client/algorithm\_sdk/asr/keyword\_spotting 135e41f4b71Sopenharmony_ci 136e41f4b71Sopenharmony_ci Keyword spotting SDK: 137e41f4b71Sopenharmony_ci 138e41f4b71Sopenharmony_ci ``` 139e41f4b71Sopenharmony_ci class KWSSdk { 140e41f4b71Sopenharmony_ci public: 141e41f4b71Sopenharmony_ci KWSSdk(); 142e41f4b71Sopenharmony_ci virtual ~KWSSdk(); 143e41f4b71Sopenharmony_ci 144e41f4b71Sopenharmony_ci /** 145e41f4b71Sopenharmony_ci * @brief Create a new session with KWS Plugin 146e41f4b71Sopenharmony_ci * 147e41f4b71Sopenharmony_ci * @return Returns KWS_RETCODE_SUCCESS(0) if the operation is successful, 148e41f4b71Sopenharmony_ci * returns a non-zero value otherwise. 149e41f4b71Sopenharmony_ci */ 150e41f4b71Sopenharmony_ci int32_t Create(); 151e41f4b71Sopenharmony_ci 152e41f4b71Sopenharmony_ci /** 153e41f4b71Sopenharmony_ci * @brief Synchronously execute keyword spotting once 154e41f4b71Sopenharmony_ci * 155e41f4b71Sopenharmony_ci * @param audioInput pcm data. 156e41f4b71Sopenharmony_ci * @return Returns KWS_RETCODE_SUCCESS(0) if the operation is successful, 157e41f4b71Sopenharmony_ci * returns a non-zero value otherwise. 158e41f4b71Sopenharmony_ci */ 159e41f4b71Sopenharmony_ci int32_t SyncExecute(const Array<int16_t> &audioInput); 160e41f4b71Sopenharmony_ci 161e41f4b71Sopenharmony_ci /** 162e41f4b71Sopenharmony_ci * @brief Asynchronously execute keyword spotting once 163e41f4b71Sopenharmony_ci * 164e41f4b71Sopenharmony_ci * @param audioInput pcm data. 165e41f4b71Sopenharmony_ci * @return Returns KWS_RETCODE_SUCCESS(0) if the operation is successful, 166e41f4b71Sopenharmony_ci * returns a non-zero value otherwise. 167e41f4b71Sopenharmony_ci */ 168e41f4b71Sopenharmony_ci int32_t AsyncExecute(const Array<int16_t> &audioInput); 169e41f4b71Sopenharmony_ci 170e41f4b71Sopenharmony_ci /** 171e41f4b71Sopenharmony_ci * @brief Set callback 172e41f4b71Sopenharmony_ci * 173e41f4b71Sopenharmony_ci * @param callback Callback function that will be called during the process. 174e41f4b71Sopenharmony_ci * @return Returns KWS_RETCODE_SUCCESS(0) if the operation is successful, 175e41f4b71Sopenharmony_ci * returns a non-zero value otherwise. 176e41f4b71Sopenharmony_ci */ 177e41f4b71Sopenharmony_ci int32_t SetCallback(const std::shared_ptr<KWSCallback> &callback); 178e41f4b71Sopenharmony_ci 179e41f4b71Sopenharmony_ci /** 180e41f4b71Sopenharmony_ci * @brief Destroy the created session with KWS Plugin 181e41f4b71Sopenharmony_ci * 182e41f4b71Sopenharmony_ci * @return Returns KWS_RETCODE_SUCCESS(0) if the operation is successful, 183e41f4b71Sopenharmony_ci * returns a non-zero value otherwise. 184e41f4b71Sopenharmony_ci */ 185e41f4b71Sopenharmony_ci int32_t Destroy(); 186e41f4b71Sopenharmony_ci } 187e41f4b71Sopenharmony_ci ``` 188e41f4b71Sopenharmony_ci 189e41f4b71Sopenharmony_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. 190e41f4b71Sopenharmony_ci 191e41f4b71Sopenharmony_ci ``` 192e41f4b71Sopenharmony_ci int32_t KWSSdk::KWSSdkImpl::Create() 193e41f4b71Sopenharmony_ci { 194e41f4b71Sopenharmony_ci if (kwsHandle_ != INVALID_KWS_HANDLE) { 195e41f4b71Sopenharmony_ci HILOGE("[KWSSdkImpl]The SDK has been created"); 196e41f4b71Sopenharmony_ci return KWS_RETCODE_FAILURE; 197e41f4b71Sopenharmony_ci } 198e41f4b71Sopenharmony_ci if (InitComponents() != RETCODE_SUCCESS) { 199e41f4b71Sopenharmony_ci HILOGE("[KWSSdkImpl]Fail to init sdk components"); 200e41f4b71Sopenharmony_ci return KWS_RETCODE_FAILURE; 201e41f4b71Sopenharmony_ci } 202e41f4b71Sopenharmony_ci int32_t retCode = AieClientInit(configInfo_, clientInfo_, algorithmInfo_, nullptr); 203e41f4b71Sopenharmony_ci if (retCode != RETCODE_SUCCESS) { 204e41f4b71Sopenharmony_ci HILOGE("[KWSSdkImpl]AieClientInit failed. Error code[%d]", retCode); 205e41f4b71Sopenharmony_ci return KWS_RETCODE_FAILURE; 206e41f4b71Sopenharmony_ci } 207e41f4b71Sopenharmony_ci if (clientInfo_.clientId == INVALID_CLIENT_ID) { 208e41f4b71Sopenharmony_ci HILOGE("[KWSSdkImpl]Fail to allocate client id"); 209e41f4b71Sopenharmony_ci return KWS_RETCODE_FAILURE; 210e41f4b71Sopenharmony_ci } 211e41f4b71Sopenharmony_ci DataInfo inputInfo = { 212e41f4b71Sopenharmony_ci .data = nullptr, 213e41f4b71Sopenharmony_ci .length = 0, 214e41f4b71Sopenharmony_ci }; 215e41f4b71Sopenharmony_ci DataInfo outputInfo = { 216e41f4b71Sopenharmony_ci .data = nullptr, 217e41f4b71Sopenharmony_ci .length = 0, 218e41f4b71Sopenharmony_ci }; 219e41f4b71Sopenharmony_ci retCode = AieClientPrepare(clientInfo_, algorithmInfo_, inputInfo, outputInfo, nullptr); 220e41f4b71Sopenharmony_ci if (retCode != RETCODE_SUCCESS) { 221e41f4b71Sopenharmony_ci HILOGE("[KWSSdkImpl]AieclientPrepare failed. Error code[%d]", retCode); 222e41f4b71Sopenharmony_ci return KWS_RETCODE_FAILURE; 223e41f4b71Sopenharmony_ci } 224e41f4b71Sopenharmony_ci if (outputInfo.data == nullptr || outputInfo.length <= 0) { 225e41f4b71Sopenharmony_ci HILOGE("[KWSSdkImpl]The data or length of output info is invalid"); 226e41f4b71Sopenharmony_ci return KWS_RETCODE_FAILURE; 227e41f4b71Sopenharmony_ci } 228e41f4b71Sopenharmony_ci MallocPointerGuard<unsigned char> pointerGuard(outputInfo.data); 229e41f4b71Sopenharmony_ci retCode = PluginHelper::UnSerializeHandle(outputInfo, kwsHandle_); 230e41f4b71Sopenharmony_ci if (retCode != RETCODE_SUCCESS) { 231e41f4b71Sopenharmony_ci HILOGE("[KWSSdkImpl]Get handle from inputInfo failed"); 232e41f4b71Sopenharmony_ci return KWS_RETCODE_FAILURE; 233e41f4b71Sopenharmony_ci } 234e41f4b71Sopenharmony_ci return KWS_RETCODE_SUCCESS; 235e41f4b71Sopenharmony_ci } 236e41f4b71Sopenharmony_ci 237e41f4b71Sopenharmony_ci int32_t KWSSdk::KWSSdkImpl::SyncExecute(const Array<uint16_t> &audioInput) 238e41f4b71Sopenharmony_ci { 239e41f4b71Sopenharmony_ci intptr_t newHandle = 0; 240e41f4b71Sopenharmony_ci Array<int32_t> kwsResult = { 241e41f4b71Sopenharmony_ci .data = nullptr, 242e41f4b71Sopenharmony_ci .size = 0 243e41f4b71Sopenharmony_ci }; 244e41f4b71Sopenharmony_ci DataInfo inputInfo = { 245e41f4b71Sopenharmony_ci .data = nullptr, 246e41f4b71Sopenharmony_ci .length = 0 247e41f4b71Sopenharmony_ci }; 248e41f4b71Sopenharmony_ci DataInfo outputInfo = { 249e41f4b71Sopenharmony_ci .data = nullptr, 250e41f4b71Sopenharmony_ci .length = 0 251e41f4b71Sopenharmony_ci }; 252e41f4b71Sopenharmony_ci int32_t retCode = PluginHelper::SerializeInputData(kwsHandle_, audioInput, inputInfo); 253e41f4b71Sopenharmony_ci if (retCode != RETCODE_SUCCESS) { 254e41f4b71Sopenharmony_ci HILOGE("[KWSSdkImpl]Fail to serialize input data"); 255e41f4b71Sopenharmony_ci callback_->OnError(KWS_RETCODE_SERIALIZATION_ERROR); 256e41f4b71Sopenharmony_ci return RETCODE_FAILURE; 257e41f4b71Sopenharmony_ci } 258e41f4b71Sopenharmony_ci retCode = AieClientSyncProcess(clientInfo_, algorithmInfo_, inputInfo, outputInfo); 259e41f4b71Sopenharmony_ci if (retCode != RETCODE_SUCCESS) { 260e41f4b71Sopenharmony_ci HILOGE("[KWSSdkImpl]AieClientSyncProcess failed. Error code[%d]", retCode); 261e41f4b71Sopenharmony_ci callback_->OnError(KWS_RETCODE_PLUGIN_EXECUTION_ERROR); 262e41f4b71Sopenharmony_ci return RETCODE_FAILURE; 263e41f4b71Sopenharmony_ci } 264e41f4b71Sopenharmony_ci if (outputInfo.data == nullptr || outputInfo.length <= 0) { 265e41f4b71Sopenharmony_ci HILOGE("[KWSSdkImpl] The data or length of outputInfo is invalid. Error code[%d]", retCode); 266e41f4b71Sopenharmony_ci callback_->OnError(KWS_RETCODE_NULL_PARAM); 267e41f4b71Sopenharmony_ci return RETCODE_FAILURE; 268e41f4b71Sopenharmony_ci } 269e41f4b71Sopenharmony_ci MallocPointerGuard<unsigned char> pointerGuard(outputInfo.data); 270e41f4b71Sopenharmony_ci retCode = PluginHelper::UnSerializeOutputData(outputInfo, newHandle, kwsResult); 271e41f4b71Sopenharmony_ci if (retCode != RETCODE_SUCCESS) { 272e41f4b71Sopenharmony_ci HILOGE("[KWSSdkImpl]UnSerializeOutputData failed. Error code[%d]", retCode); 273e41f4b71Sopenharmony_ci callback_->OnError(KWS_RETCODE_UNSERIALIZATION_ERROR); 274e41f4b71Sopenharmony_ci return retCode; 275e41f4b71Sopenharmony_ci } 276e41f4b71Sopenharmony_ci if (kwsHandle_ != newHandle) { 277e41f4b71Sopenharmony_ci HILOGE("[KWSSdkImpl]The handle[%lld] of output data is not equal to the current handle[%lld]", 278e41f4b71Sopenharmony_ci (long long)newHandle, (long long)kwsHandle_); 279e41f4b71Sopenharmony_ci callback_->OnError(KWS_RETCODE_PLUGIN_SESSION_ERROR); 280e41f4b71Sopenharmony_ci return RETCODE_FAILURE; 281e41f4b71Sopenharmony_ci } 282e41f4b71Sopenharmony_ci callback_->OnResult(kwsResult); 283e41f4b71Sopenharmony_ci return RETCODE_SUCCESS; 284e41f4b71Sopenharmony_ci } 285e41f4b71Sopenharmony_ci 286e41f4b71Sopenharmony_ci int32_t KWSSdk::KWSSdkImpl::Destroy() 287e41f4b71Sopenharmony_ci { 288e41f4b71Sopenharmony_ci if (kwsHandle_ == INVALID_KWS_HANDLE) { 289e41f4b71Sopenharmony_ci return KWS_RETCODE_SUCCESS; 290e41f4b71Sopenharmony_ci } 291e41f4b71Sopenharmony_ci DataInfo inputInfo = { 292e41f4b71Sopenharmony_ci .data = nullptr, 293e41f4b71Sopenharmony_ci .length = 0 294e41f4b71Sopenharmony_ci }; 295e41f4b71Sopenharmony_ci int32_t retCode = PluginHelper::SerializeHandle(kwsHandle_, inputInfo); 296e41f4b71Sopenharmony_ci if (retCode != RETCODE_SUCCESS) { 297e41f4b71Sopenharmony_ci HILOGE("[KWSSdkImpl]SerializeHandle failed. Error code[%d]", retCode); 298e41f4b71Sopenharmony_ci return KWS_RETCODE_FAILURE; 299e41f4b71Sopenharmony_ci } 300e41f4b71Sopenharmony_ci retCode = AieClientRelease(clientInfo_, algorithmInfo_, inputInfo); 301e41f4b71Sopenharmony_ci if (retCode != RETCODE_SUCCESS) { 302e41f4b71Sopenharmony_ci HILOGE("[KWSSdkImpl]AieClientRelease failed. Error code[%d]", retCode); 303e41f4b71Sopenharmony_ci return KWS_RETCODE_FAILURE; 304e41f4b71Sopenharmony_ci } 305e41f4b71Sopenharmony_ci retCode = AieClientDestroy(clientInfo_); 306e41f4b71Sopenharmony_ci if (retCode != RETCODE_SUCCESS) { 307e41f4b71Sopenharmony_ci HILOGE("[KWSSdkImpl]AieClientDestroy failed. Error code[%d]", retCode); 308e41f4b71Sopenharmony_ci return KWS_RETCODE_FAILURE; 309e41f4b71Sopenharmony_ci } 310e41f4b71Sopenharmony_ci mfccProcessor_ = nullptr; 311e41f4b71Sopenharmony_ci pcmIterator_ = nullptr; 312e41f4b71Sopenharmony_ci callback_ = nullptr; 313e41f4b71Sopenharmony_ci kwsHandle_ = INVALID_KWS_HANDLE; 314e41f4b71Sopenharmony_ci return KWS_RETCODE_SUCCESS; 315e41f4b71Sopenharmony_ci } 316e41f4b71Sopenharmony_ci ``` 317e41f4b71Sopenharmony_ci 318e41f4b71Sopenharmony_ci4. Develop a sample application. 319e41f4b71Sopenharmony_ci 320e41f4b71Sopenharmony_ci Call the **Create** API. 321e41f4b71Sopenharmony_ci 322e41f4b71Sopenharmony_ci ``` 323e41f4b71Sopenharmony_ci bool KwsManager::PreparedInference() 324e41f4b71Sopenharmony_ci { 325e41f4b71Sopenharmony_ci if (capturer_ == nullptr) { 326e41f4b71Sopenharmony_ci printf("[KwsManager] only load plugin after AudioCapturer ready\n"); 327e41f4b71Sopenharmony_ci return false; 328e41f4b71Sopenharmony_ci } 329e41f4b71Sopenharmony_ci if (plugin_ != nullptr) { 330e41f4b71Sopenharmony_ci printf("[KwsManager] stop created InferencePlugin at first\n"); 331e41f4b71Sopenharmony_ci StopInference(); 332e41f4b71Sopenharmony_ci } 333e41f4b71Sopenharmony_ci plugin_ = std::make_shared<KWSSdk>(); 334e41f4b71Sopenharmony_ci if (plugin_ == nullptr) { 335e41f4b71Sopenharmony_ci printf("[KwsManager] fail to create inferencePlugin\n"); 336e41f4b71Sopenharmony_ci return false; 337e41f4b71Sopenharmony_ci } 338e41f4b71Sopenharmony_ci if (plugin_->Create() != SUCCESS) { 339e41f4b71Sopenharmony_ci printf("[KwsManager] KWSSdk fail to create.\n"); 340e41f4b71Sopenharmony_ci return false; 341e41f4b71Sopenharmony_ci } 342e41f4b71Sopenharmony_ci std::shared_ptr<KWSCallback> callback = std::make_shared<MyKwsCallback>(); 343e41f4b71Sopenharmony_ci if (callback == nullptr) { 344e41f4b71Sopenharmony_ci printf("[KwsManager] new Callback failed.\n"); 345e41f4b71Sopenharmony_ci return false; 346e41f4b71Sopenharmony_ci } 347e41f4b71Sopenharmony_ci plugin_->SetCallback(callback); 348e41f4b71Sopenharmony_ci return true; 349e41f4b71Sopenharmony_ci } 350e41f4b71Sopenharmony_ci ``` 351e41f4b71Sopenharmony_ci 352e41f4b71Sopenharmony_ci Call the **SyncExecute** API. 353e41f4b71Sopenharmony_ci 354e41f4b71Sopenharmony_ci ``` 355e41f4b71Sopenharmony_ci void KwsManager::ConsumeSamples() 356e41f4b71Sopenharmony_ci { 357e41f4b71Sopenharmony_ci uintptr_t sampleAddr = 0; 358e41f4b71Sopenharmony_ci size_t sampleSize = 0; 359e41f4b71Sopenharmony_ci int32_t retCode = SUCCESS; 360e41f4b71Sopenharmony_ci while (status_ == RUNNING) { 361e41f4b71Sopenharmony_ci { 362e41f4b71Sopenharmony_ci std::lock_guard<std::mutex> lock(mutex_); 363e41f4b71Sopenharmony_ci if (cache_ == nullptr) { 364e41f4b71Sopenharmony_ci printf("[KwsManager] cache_ is nullptr.\n"); 365e41f4b71Sopenharmony_ci break; 366e41f4b71Sopenharmony_ci } 367e41f4b71Sopenharmony_ci sampleSize = cache_->GetCapturedBuffer(sampleAddr); 368e41f4b71Sopenharmony_ci } 369e41f4b71Sopenharmony_ci if (sampleSize == 0 || sampleAddr == 0) { 370e41f4b71Sopenharmony_ci continue; 371e41f4b71Sopenharmony_ci } 372e41f4b71Sopenharmony_ci Array<int16_t> input = { 373e41f4b71Sopenharmony_ci .data = (int16_t *)(sampleAddr), 374e41f4b71Sopenharmony_ci .size = sampleSize >> 1 375e41f4b71Sopenharmony_ci }; 376e41f4b71Sopenharmony_ci { 377e41f4b71Sopenharmony_ci std::lock_guard<std::mutex> lock(mutex_); 378e41f4b71Sopenharmony_ci if (plugin_ == nullptr) { 379e41f4b71Sopenharmony_ci printf("[KwsManager] cache_ is nullptr.\n"); 380e41f4b71Sopenharmony_ci break; 381e41f4b71Sopenharmony_ci } 382e41f4b71Sopenharmony_ci if ((retCode = plugin_->SyncExecute(input)) != SUCCESS) { 383e41f4b71Sopenharmony_ci printf("[KwsManager] SyncExecute KWS failed with retCode = [%d]\n", retCode); 384e41f4b71Sopenharmony_ci continue; 385e41f4b71Sopenharmony_ci } 386e41f4b71Sopenharmony_ci } 387e41f4b71Sopenharmony_ci } 388e41f4b71Sopenharmony_ci } 389e41f4b71Sopenharmony_ci ``` 390e41f4b71Sopenharmony_ci 391e41f4b71Sopenharmony_ci Call the **Destroy** API. 392e41f4b71Sopenharmony_ci 393e41f4b71Sopenharmony_ci ``` 394e41f4b71Sopenharmony_ci void KwsManager::StopInference() 395e41f4b71Sopenharmony_ci { 396e41f4b71Sopenharmony_ci printf("[KwsManager] StopInference\n"); 397e41f4b71Sopenharmony_ci if (plugin_ != nullptr) { 398e41f4b71Sopenharmony_ci int ret = plugin_->Destroy(); 399e41f4b71Sopenharmony_ci if (ret != SUCCESS) { 400e41f4b71Sopenharmony_ci printf("[KwsManager] plugin_ destroy failed.\n"); 401e41f4b71Sopenharmony_ci } 402e41f4b71Sopenharmony_ci plugin_ = nullptr; 403e41f4b71Sopenharmony_ci } 404e41f4b71Sopenharmony_ci } 405e41f4b71Sopenharmony_ci ``` 406e41f4b71Sopenharmony_ci 407e41f4b71Sopenharmony_ci 408e41f4b71Sopenharmony_ci## Repositories Involved 409e41f4b71Sopenharmony_ci 410e41f4b71Sopenharmony_ci[AI subsystem](https://gitee.com/openharmony/docs/blob/master/en/readme/ai.md) 411e41f4b71Sopenharmony_ci 412e41f4b71Sopenharmony_ci[ai_engine](https://gitee.com/openharmony/ai_engine) 413e41f4b71Sopenharmony_ci 414e41f4b71Sopenharmony_ci## Dependency Repositories 415e41f4b71Sopenharmony_ci 416e41f4b71Sopenharmony_ci[build\_lite](https://gitee.com/openharmony/build_lite/blob/master/README.md) 417e41f4b71Sopenharmony_ci 418e41f4b71Sopenharmony_ci[systemabilitymgr\_samgr\_lite](https://gitee.com/openharmony/systemabilitymgr_samgr_lite/blob/master/README.md) 419e41f4b71Sopenharmony_ci 420e41f4b71Sopenharmony_ci[startup\_init\_lite](https://gitee.com/openharmony/startup_init_lite/blob/master/README.md) 421e41f4b71Sopenharmony_ci 422e41f4b71Sopenharmony_ci## Reference 423e41f4b71Sopenharmony_ci 424e41f4b71Sopenharmony_ci[AI Framework Development Guide](https://gitee.com/openharmony/docs/blob/master/en/device-dev/subsystems/subsys-ai-aiframework-devguide.md) 425e41f4b71Sopenharmony_ci 426e41f4b71Sopenharmony_ci 427