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![](figures/ai-engine-framework.png "ai-engine-framework")
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;amp;inputInfo, DataInfo &amp;amp;outputInfo) override;
960485dae0Sopenharmony_ci        int32_t SetOption(int optionType, const DataInfo &amp;amp;inputInfo) override;
970485dae0Sopenharmony_ci        int32_t GetOption(int optionType, const DataInfo &amp;amp;inputInfo, DataInfo &amp;amp;outputInfo) override;
980485dae0Sopenharmony_ci        int32_t SyncProcess(IRequest *request, IResponse *&amp;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;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