Ai语音添加录音功能
authorluozheng <1732036298@qq.com>
Wed, 26 Jun 2024 09:36:48 +0000 (17:36 +0800)
committerluozheng <1732036298@qq.com>
Wed, 26 Jun 2024 09:36:48 +0000 (17:36 +0800)
code/sdk/application/wearable/fd230app/nativeui/aivoice/include/AiVoiceModel.h
code/sdk/application/wearable/fd230app/nativeui/aivoice/src/AiVoiceModel.cpp
code/sdk/application/wearable/fd230app/nativeui/aivoice/src/AiVoicePresenter.cpp
code/sdk/build/config/target_config/brandy/mk_fs_image/fd230/fs/user/userdata/AiRecording/AIAudio.pcm [new file with mode: 0644]

index d5c14a6..51971c8 100644 (file)
@@ -2,7 +2,7 @@
  * @Author: luozheng 1732036298@qq.com
  * @Date: 2024-06-20 15:14:43
  * @LastEditors: luozheng 1732036298@qq.com
- * @LastEditTime: 2024-06-25 17:50:45
+ * @LastEditTime: 2024-06-26 17:08:39
  * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/aivoice/include/AiVoiceModel.h
  */
 #ifndef AI_VOICE_MODEL_H
@@ -17,6 +17,7 @@ namespace OHOS
     public:
         static AiVoiceModel &GetInstance(void);
         bool ChangeToReturnResultTextView(void);
+        bool CreateIfNotExists();
 
         bool GetBluetoothIsOpen(void);
         bool GetMobileDataIsOpen(void);
@@ -30,6 +31,12 @@ namespace OHOS
 
         std::string GetAIAudioPath(void);
 
+        void StartListenAndRecordingUserQuestion(void);
+        void StopListenAndRecordingUserQuestion(void);
+
+        void AIVoice_StartTimer(uint32_t interval = 1000);
+        void AIVoice_StopTimer(void);
+
     private:
         AiVoiceModel();
         ~AiVoiceModel();
index 0a6cb1f..4a9accb 100644 (file)
@@ -2,13 +2,21 @@
  * @Author: luozheng 1732036298@qq.com
  * @Date: 2024-06-20 15:14:50
  * @LastEditors: luozheng 1732036298@qq.com
- * @LastEditTime: 2024-06-25 17:50:59
+ * @LastEditTime: 2024-06-26 17:35:48
  * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/aivoice/src/AiVoiceModel.cpp
  */
 #include "aivoice/include/AiVoiceModel.h"
 #include "aivoice/include/AiVoicePresenter.h"
+#include "aivoice/include/AiVoiceView.h"
 #include "wearable_log.h"
-
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <cmsis_os2.h>
+#include <cmsis_os.h>
+#include <ohos_types.h>
+#include <service/graphic_service.h>
+#include <iostream>
 namespace OHOS
 {
     AiVoiceModel::AiVoiceModel() {}
@@ -34,6 +42,32 @@ namespace OHOS
         return true;
     }
 
+    bool AiVoiceModel::CreateIfNotExists()
+    {
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoiceModel::CreateIfNotExists");
+        const std::string filePath = "/user/userdata/AiRecording/AIAudio.pcm";
+        // Check if file exists
+        FILE *file = fopen(filePath.c_str(), "r");
+        if (file != NULL)
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "File already exists: %s", filePath.c_str());
+            fclose(file);
+            return false;
+        }
+
+        // File does not exist, create it
+        file = fopen(filePath.c_str(), "w");
+        if (file == NULL)
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to create file: %s", filePath.c_str());
+            return false;
+        }
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "File created: %s", filePath.c_str());
+        fclose(file);
+
+        return true;
+    }
+
     // 获取蓝牙是否打开
     bool AiVoiceModel::GetBluetoothIsOpen(void)
     {
@@ -54,7 +88,8 @@ namespace OHOS
 
     std::string AiVoiceModel::GetUserQuestionStr(void)
     {
-        userQuestionStr = "写一篇100字文章";
+        // userQuestionStr = "写一篇100字文章";
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "userQuestionStr:\n", userQuestionStr.c_str());
         return userQuestionStr;
     }
 
@@ -65,7 +100,8 @@ namespace OHOS
 
     std::string AiVoiceModel::GetAiAnswerStrStr(void)
     {
-        aiAnswerStr = "春风化雨,时光荏苒。百年之内,生命如白驹过隙,转瞬即逝。唯有心存善念,用爱化解芥蒂,用智慧建构未来,才是人生的真正意义。让我们携手共进,用每一分时光去关爱他人,用每一滴汗水去创造奇迹,用每一个眼神去传递温暖。让这个世界因我们的存在而变得更加美好。生命短暂,但只要我们怀着虔诚的心,坚韧前行,我们就一定能在有限的时光里留下无限的可能。";
+        // aiAnswerStr = "春风化雨,时光荏苒。百年之内,生命如白驹过隙,转瞬即逝。唯有心存善念,用爱化解芥蒂,用智慧建构未来,才是人生的真正意义。让我们携手共进,用每一分时光去关爱他人,用每一滴汗水去创造奇迹,用每一个眼神去传递温暖。让这个世界因我们的存在而变得更加美好。生命短暂,但只要我们怀着虔诚的心,坚韧前行,我们就一定能在有限的时光里留下无限的可能。";
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "aiAnswerStr:\n", aiAnswerStr.c_str());
         return aiAnswerStr;
     }
 
@@ -76,6 +112,149 @@ namespace OHOS
 
     std::string AiVoiceModel::GetAIAudioPath(void)
     {
+        CreateIfNotExists();
         return AIAIAudioPath;
     }
+
+#ifdef __cplusplus
+    extern "C"
+    {
+#endif
+        int32_t AudioCaptureSample(int32_t argc, const char *argv[]);
+
+#ifdef __cplusplus
+    };
+#endif
+
+    // 开始聆听并录取用户问题
+    void AiVoiceModel::StartListenAndRecordingUserQuestion(void)
+    {
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoiceModel::RecordingUserQuestion");
+        AiVoiceView *view_ = AiVoiceView::GetInstance();
+        if (view_ == nullptr)
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AiVoiceView::GetInstance fail!!");
+            return;
+        }
+        if ((view_->GetAiVoiceScrollView(AIVOICE_LISTENING_VIEWID) != nullptr) &&
+            (view_->GetAiVoiceScrollView(AIVOICE_LISTENING_VIEWID)->IsVisible()))
+        {
+            const char *defaultArgs[6] = {"01", "pcm", "16000", "1", "16", AiVoiceModel::GetInstance().GetAIAudioPath().c_str()};
+            AudioCaptureSample(6, (const char **)defaultArgs);
+        }
+        // 开启定时器
+        AIVoice_StartTimer();
+
+        return;
+    }
+
+    // 停止聆听用户问题
+    void AiVoiceModel::StopListenAndRecordingUserQuestion(void)
+    {
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoiceModel::StopListenAndRecordingUserQuestion");
+        int32_t argc = 1;
+        uint8_t *argv = (uint8_t *)"stop";
+        AudioCaptureSample(argc, (const char **)&argv);
+    }
+
+    /* -------------------------------------------------------------------------- */
+    // 声明定时器变量
+    static osTimerId_t g_timer = NULL;
+    static int Time = 15;
+    static constexpr int ONE_MINUTE = 60; // 一分钟
+    static bool START_FLAG = false;
+    /*定时器到期时的处理*/
+    static void AIVoice_TimerCallbackProc(int data)
+    {
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AIVoice_TimerCallbackProc,Time = %d", Time);
+        Time--;
+        AiVoiceView *view_ = AiVoiceView::GetInstance();
+        if (view_ == nullptr)
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AiVoiceView::GetInstance fail!!");
+            return;
+        }
+        if (Time <= 0)
+        {
+            if ((view_->GetAiVoiceScrollView(AIVOICE_LISTENING_VIEWID) != nullptr) &&
+                (view_->GetAiVoiceScrollView(AIVOICE_LISTENING_VIEWID)->IsVisible()))
+            {
+                if (AiVoiceModel::GetInstance().GetAiVoiceConnectStatus() == true)
+                    view_->ChangeView(AIVOICE_LISTENING_VIEWID, AIVOICE_THINKING_VIEWID);
+                else
+                    view_->ChangeView(AIVOICE_LISTENING_VIEWID, AIVOICE_CONNECT_TIMEOUT_VIEWID);
+            }
+            AiVoiceModel::GetInstance().AIVoice_StopTimer();
+        }
+
+        return;
+    }
+
+    /*
+     * @brief 回调函数
+     */
+    static void AIVoice_TimerCallback(int data)
+    {
+        GraphicService::GetInstance()->PostGraphicEvent(std::bind(AIVoice_TimerCallbackProc, data));
+    }
+
+    /*
+     *  @brief 开启定时器函数
+     *  @param interval 时间间隔,单位ms
+     */
+    void AiVoiceModel::AIVoice_StartTimer(uint32_t interval)
+    {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AiVoiceModel::AIVoice_StartTimer");
+        /* -------------------------- 1.检查定时器是否已经存在,如果存在则返回 ------------------------- */
+        if (g_timer != NULL)
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Timer already exists!!");
+            return;
+        }
+
+        /* --------------------------------- 2.创建定时器 -------------------------------- */
+        g_timer = osTimerNew((osTimerFunc_t)AIVoice_TimerCallback, osTimerPeriodic, NULL, NULL);
+        // 检查定时器创建是否成功
+        if (g_timer == NULL)
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Timer create failed!!");
+            return;
+        }
+
+        /* ----------------------------- 3.将毫秒转换为系统时钟节拍数 ---------------------------- */
+        int tick = osMs2Tick(interval);
+
+        /* --------------------------------- 4.启动定时器 -------------------------------- */
+        osStatus_t ret = osTimerStart(g_timer, tick);
+        /* -------------------- 5.检查定时器启动是否成功,如果启动失败,删除定时器并置为 NULL -------------------- */
+        if (ret != osOK)
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "osTimerDelete failed, ret = %lx!!", ret);
+            if (g_timer != NULL)
+            {
+                ret = osTimerDelete(g_timer);
+            }
+            g_timer = NULL;
+            return;
+        }
+    }
+
+    /*
+     * @brief 停止定时器
+     */
+    void AiVoiceModel::AIVoice_StopTimer(void)
+    {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AiVoiceModel::AIVoice_StopTimer");
+        // 检查定时器是否存在
+        if (g_timer != NULL)
+        {
+            // 删除定时器并置为 NULL
+            osStatus_t ret = osTimerDelete(g_timer);
+            if (ret != osOK)
+            {
+                WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "osTimerDelete failed, ret = %lx!!", ret);
+            }
+            g_timer = NULL;
+        }
+    }
 }
index be7a87a..2ceeb66 100644 (file)
@@ -2,7 +2,7 @@
  * @Author: luozheng 1732036298@qq.com
  * @Date: 2024-06-20 15:11:17
  * @LastEditors: luozheng 1732036298@qq.com
- * @LastEditTime: 2024-06-25 17:39:51
+ * @LastEditTime: 2024-06-26 17:34:11
  * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/aivoice/src/AiVoicePresenter.cpp
  */
 #include "AppViewIDs.h"
@@ -71,6 +71,7 @@ namespace OHOS
         WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoicePresenter::OnStop");
         Presenter<AiVoiceView>::OnStop();
         ScreenAlwaysOnCtr(CANCEL_SCREEN_ALWAYS_ON);
+        AiVoiceModel::GetInstance().AIVoice_StopTimer();
     }
 
     bool AiVoicePresenter::JumpToReturnResultTextView(void)
@@ -108,6 +109,7 @@ namespace OHOS
             else
             {
                 view_->ChangeView(AIVOICE_STARTCHAT_VIEWID, AIVOICE_LISTENING_VIEWID); // 开始对话->聆听中界面
+                model->StartListenAndRecordingUserQuestion();
             }
             return true;
         }
@@ -121,6 +123,7 @@ namespace OHOS
             else
             {
                 view_->ChangeView(AIVOICE_LISTENING_VIEWID, AIVOICE_THINKING_VIEWID); // 聆听中->思考中界面
+                model->StopListenAndRecordingUserQuestion();
             }
             return true;
         }
diff --git a/code/sdk/build/config/target_config/brandy/mk_fs_image/fd230/fs/user/userdata/AiRecording/AIAudio.pcm b/code/sdk/build/config/target_config/brandy/mk_fs_image/fd230/fs/user/userdata/AiRecording/AIAudio.pcm
new file mode 100644 (file)
index 0000000..e69de29