4G ai 发送文本优化,解决发送双引号导致tts断开问题 2104/1 2104/head 2105/target/1
authorluozheng <1732036298@qq.com>
Tue, 19 Aug 2025 12:20:37 +0000 (20:20 +0800)
committerluozheng <1732036298@qq.com>
Tue, 19 Aug 2025 12:20:37 +0000 (20:20 +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/application/wearable/fd230app/nativeui/aivoice/src/AiVoiceView.cpp
code/sdk/drivers/peripheral/slip/cat1Service/cat1_ai_server.cpp
code/sdk/drivers/peripheral/slip/cat1Service/cat1_ws.h
code/sdk/drivers/peripheral/slip/tcpmanager/tcp_simple_manager.c

index 7142de8..e8591aa 100644 (file)
@@ -123,12 +123,15 @@ namespace OHOS
         void start_ai4g_connect_timer(uint32_t interval = 1000);
         void stop_ai4g_connect_timer(void);
 
-        void start_ai4g_tts_play_timer(uint32_t interval = 800);
+        void start_ai4g_tts_play_timer(uint32_t interval = 600);
         void stop_ai4g_tts_play_timer(void);
 
         void start_update_ai_answer_timer(uint32_t interval = 300);
         void stop_update_ai_answer_timer(void);
 
+        void start_uapi_stop_tts_timer(uint32_t interval = 1500);
+        void stop_uapi_stop_tts_timer(void);
+
         void SetSelectAiModel(int index);
         int GetSelectAiModel(void);
         int GetAiModelTextId(void);
index 49750f3..83c078e 100644 (file)
@@ -683,9 +683,10 @@ namespace OHOS
         str.swap(result);
     }
 
+    static int fouce_count = 0;         //
     void AiVoiceModel::ProcessTextByPunctuation()
     {
-        const std::string punctuation = "ï¼\8cã\80\82ï¼\81ï¼\9fï¼\9bï¼\9aï¼\89)â\80\9dã\80\81"; // 要替换的中文标点
+        const std::string punctuation = "ï¼\8cã\80\82ï¼\81ï¼\9fï¼\9bï¼\9aï¼\89)â\80\9câ\80\9dã\80\81\"\""; // 要替换的中文标点
         const char replacement = ',';                         // 替换为英文逗号
         const size_t MAX_SEGMENT_LENGTH = 120;                // 最大分段长度
         const size_t MIN_SEGMENT_LENGTH = 1;                  // 最小发送长度(可调整)
@@ -743,11 +744,18 @@ namespace OHOS
                 {
                     // 发送后清空累积文本
                     accumulatedText.clear();
+                    fouce_count = 0;
                 }
                 else
                 {
                     // 发送失败,等待下次发送
                     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "发送失败,等待下次发送");
+                    fouce_count++;
+                    if(fouce_count >= 3)
+                    {
+                        uapi_start_tts();
+                        fouce_count = 0;
+                    }
                 }
             }
             else
@@ -1229,7 +1237,7 @@ namespace OHOS
     void AiVoiceModel::reset_ai_screen60s_timer_time()
     {
         SCREEN_60S_TIME = 60;
-        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "reset_ai_screen60s_timer_time %d", SCREEN_60S_TIME);
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "reset_ai_screen60s_timer_time %d", SCREEN_60S_TIME);
         if (nullptr == g_screen60s_timer)
         {
             ScreenAlwaysOnCtr(OPEN_SCREEN_ALWAYS_ON); // 重新常亮屏
@@ -1252,7 +1260,7 @@ namespace OHOS
         LISTENING_TIMEOUT--;
         if (LISTENING_TIMEOUT <= 0)
         {
-            AiVoiceModel::GetInstance().StopListenAndRecordingUserQuestion(); // 停止聆听用户问题
+            // AiVoiceModel::GetInstance().StopListenAndRecordingUserQuestion(); // 停止聆听用户问题
             AiVoiceModel::GetInstance().stop_listening_timer();               // 停止聆听定时器
             AiVoicePresenter *p_AiVoicePresenter = AiVoicePresenter::GetInstance();
             if (AiVoicePresenter::GetInstance() && AivoiceListeningView::GetInstance())
@@ -1546,10 +1554,9 @@ namespace OHOS
     // 添加一个静态变量用于跟踪连续出现0的次数
     static int s_tts_tick_zero_count = 0;
     static int continue_zero_count = 0; // 静态变量:记录连续为0的次数(初始化为0)
-    static int fouce_count = 0;         //
     static void AI4G_IS_START_TTS_CallbackProc(int data)
     {
-        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AI4G_IS_START_TTS_CallbackProc:%s", AiVoiceModel::GetInstance().GetAccumulatedText().c_str());
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AI4G_IS_START_TTS_CallbackProc:%s", AiVoiceModel::GetInstance().GetAccumulatedText().c_str());
         AiVoiceModel::GetInstance().GetInit_4gai_task(); // 获取4gai服务状态
         if (get_ai_tts_server_init_flag() == 0)          // tts服务如果断开了,就停止定时器
         {
@@ -1570,6 +1577,12 @@ namespace OHOS
             return;
         }
 
+        if (!get_ai_osal_msg_queue_is_full())
+        {
+            AiVoiceModel::GetInstance().ProcessTextByPunctuation();
+        }
+
+        #if 0
         // 当前回调中get_bk_websocket_tts_tick()是否为0
         bool current_tick_zero = (get_bk_websocket_tts_tick() == 0);
 
@@ -1614,6 +1627,7 @@ namespace OHOS
                 }
             }
         }
+        #endif
         return;
     }
 
@@ -1677,6 +1691,8 @@ namespace OHOS
             s_tts_tick_zero_count = 0; // 重置计数器
             continue_zero_count = 0;   // 重置静态变量
             fouce_count = 0;
+
+            start_uapi_stop_tts_timer();
         }
     }
 
@@ -1755,6 +1771,70 @@ namespace OHOS
         }
     }
 
+
+    static osTimerId_t g_uapi_stop_tts_Handle = nullptr;
+    static void AI4G_UAPI_STOP_TTS_CallbackProc(int data)
+    {
+        uapi_stop_tts();
+        AiVoiceModel::GetInstance().stop_uapi_stop_tts_timer();
+    }
+
+    static void AI4G_UAPI_STOP_TTS_Callback(int data)
+    {
+        GraphicService::GetInstance()->PostGraphicEvent(std::bind(AI4G_UAPI_STOP_TTS_CallbackProc, data));
+    }
+
+    void AiVoiceModel::start_uapi_stop_tts_timer(uint32_t interval)
+    {
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoiceModel::start_uapi_stop_tts_timer");
+        /* -------------------------- 1.检查定时器是否已经存在,如果存在则返回 ------------------------- */
+        if (g_uapi_stop_tts_Handle != nullptr)
+        {
+            // WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Timer already exists!!");
+            return;
+        }
+        /* --------------------------------- 2.创建定时器 -------------------------------- */
+        g_uapi_stop_tts_Handle = osTimerNew((osTimerFunc_t)AI4G_UAPI_STOP_TTS_Callback, osTimerPeriodic, nullptr, nullptr);
+        // 检查定时器创建是否成功
+        if (g_uapi_stop_tts_Handle == nullptr)
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Timer create failed!!");
+            return;
+        }
+        /* ----------------------------- 3.将毫秒转换为系统时钟节拍数 ---------------------------- */
+        int tick = osMs2Tick(interval);
+        /* --------------------------------- 4.启动定时器 -------------------------------- */
+        osStatus_t ret = osTimerStart(g_uapi_stop_tts_Handle, tick);
+        /* -------------------- 5.检查定时器启动是否成功,如果启动失败,删除定时器并置为 nullptr -------------------- */
+        if (ret != osOK)
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "osTimerDelete failed, ret = %lx!!", ret);
+            if (g_uapi_stop_tts_Handle != nullptr)
+            {
+                ret = osTimerDelete(g_uapi_stop_tts_Handle);
+            }
+            g_uapi_stop_tts_Handle = nullptr;
+            return;
+        }
+    }
+    
+    void AiVoiceModel::stop_uapi_stop_tts_timer(void)
+    {
+        // 检查定时器是否存在
+        if (g_uapi_stop_tts_Handle != nullptr)
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "stop_uapi_stop_tts_timer");
+            osTimerStop(g_uapi_stop_tts_Handle);
+            // 删除定时器并置为 nullptr
+            osStatus_t ret = osTimerDelete(g_uapi_stop_tts_Handle);
+            if (ret != osOK)
+            {
+                WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "osTimerDelete failed, ret = %lx!!", ret);
+            }
+            g_uapi_stop_tts_Handle = nullptr;
+        }
+    }
+
     // 设置选择的ai模型
     void AiVoiceModel::SetSelectAiModel(int index)
     {
@@ -1795,8 +1875,8 @@ namespace OHOS
         uint8_t asr_state = 0;
         uint8_t chat_state = 0;
         uint8_t tts_state = 0;
-        // asr_state = get_ai_asr_service_init_flag();
-        asr_state = 1;
+        asr_state = get_ai_asr_service_init_flag();
+        // asr_state = 1;
         chat_state = get_ai_chat_service_init_flag();
         tts_state = get_ai_tts_server_init_flag();
         WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "asr_state:%d,chat_state:%d,tts_state:%d", asr_state, chat_state, tts_state);
index e35d3f6..b5c3d97 100644 (file)
@@ -134,6 +134,7 @@ namespace OHOS
         model->stop_ai4g_connect_timer();
         model->stop_ai4g_tts_play_timer();
         model->stop_update_ai_answer_timer();
+        model->stop_uapi_stop_tts_timer();
         remove_4GAI_vote(); // 移除4g投票
         dinit_ai_task();
 
@@ -153,7 +154,6 @@ namespace OHOS
             {
                 if (view_->GetAiVoiceScrollView(AIVOICE_LISTENING_VIEWID) || view_->GetAiVoiceScrollView(AIVOICE_THINKING_VIEWID))
                 {
-                    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "JumpToReturnResultTextView");
                     ChangeViewAndLogicOperator(model->GetCurView(), AIVOICE_RETURN_RESULT_TEXT_VIEWID);
                 }
                 else
@@ -350,6 +350,9 @@ namespace OHOS
             AiVoiceModel::GetInstance().stop_update_ai_answer_timer();
             break;
             
+        case AIVOICE_4GSERVICECON_VIEW:
+            model->stop_ai4g_connect_timer();
+            break;
         default:
             // Handle other cases if needed
             break;
@@ -418,7 +421,7 @@ namespace OHOS
     {
         UNUSED(event);
         std::string viewId = view.GetViewId();
-        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AiVoicePresenter::OnPress %s", viewId.c_str());
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoicePresenter::OnPress %s", viewId.c_str());
         /* ----------------------------- 重置60s取消常亮屏timer ---------------------------- */
         model->reset_ai_screen60s_timer_time();
         /* -------------------------------------------------------------------------- */
index b48036d..e31a6e8 100644 (file)
@@ -1020,7 +1020,7 @@ namespace OHOS
 
     void AiVoiceView::DestroyTempView(int16_t hideView)
     {
-        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AiVoiceView::DestroyTempView:%d", hideView);
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoiceView::DestroyTempView:%d", hideView);
         int viewSize = sizeof(AiVoiceDestroyMapper) / sizeof(AiVoiceDestroyMapper[0]);
         for (int i = 0; i < viewSize; i++)
         {
@@ -1121,7 +1121,7 @@ namespace OHOS
 
     void AiVoiceView::ChangeView(int16_t hideView, int16_t showView)
     {
-        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AiVoiceView::ChangeView hideView:%d, showView:%d", hideView, showView);
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoiceView::ChangeView hideView:%d, showView:%d", hideView, showView);
         if (!CheckViewParam(hideView, showView))
         {
             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AiVoiceView::CheckViewParam failed.");
index d581c4e..d022000 100644 (file)
@@ -1819,17 +1819,22 @@ void uapi_start_tts(void)
 
 
     if (send_websocket_message(tts_client,( uint8_t *)jsonString,strlen(jsonString),WS_TEXT)==0)
-{
+    {
         memset_s(tts_task_id_buf,128,0,128);
         tts_is_ready=0;
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"send_websocket_message succ 0\n");
-}
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"send_websocket_message succ 0\n");
+    }
     
 }
 
 
 void uapi_stop_tts(void)
 {
+    if (tts_is_ready!=1)
+    {
+        return;
+    }
+    
     char *jsonString =
    " { \
      \"header\": { \
@@ -1841,10 +1846,10 @@ void uapi_stop_tts(void)
      printf("uapi_start_tts : %s\r\n",jsonString);
 
     if (send_websocket_message(tts_client,( uint8_t *)jsonString,strlen(jsonString),WS_TEXT)==0)
-{
+    {
         tts_is_ready=0;
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"send_websocket_message succ 0\n");
-}
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"send_websocket_message succ 0\n");
+    }
    
 }
 
@@ -1875,15 +1880,15 @@ void uapi_start_tts_single(void)
 }
 
  
-void uapi_start_tts_single_txt(char *buf)
+bool uapi_start_tts_single_txt(char *buf)
 {
-
-     if(tts_is_ready!=1)
+    
+    if(tts_is_ready!=1)
     {
         WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"uapi_start_tts_single_txt no tts_is_ready \n");
-        return;
+        return false;
     }
-    
+
 
     char *jsonString = (char *)malloc(strlen(buf)+300);// [512] ={0};
  
@@ -1912,7 +1917,7 @@ void uapi_start_tts_single_txt(char *buf)
      
      ,tts_task_id_buf,buf);
 
-     printf("uapi_start_tts_single_txt :%s\r\n",jsonString);
+    printf("uapi_start_tts_single_txt :%s\r\n",jsonString);
 
     if (send_websocket_message(tts_client,( uint8_t *)jsonString,strlen(jsonString),WS_TEXT)==0)
     {
index ed1a697..12acb3e 100644 (file)
@@ -14,6 +14,10 @@ void uapi_UI_start_asr(uint8_t type);
 
 void uapi_UI_stop_asr(void);
 
+void uapi_start_tts(void);
+
+void uapi_stop_tts(void);
+
 bool uapi_start_tts_single_txt(char *buf);
 
 void uapi_UI_stop_start_asr_timeout(void);
index c028360..0602f75 100644 (file)
@@ -819,6 +819,7 @@ static void tcp_manager_io_thread(void* arg)
                 ssize_t recv_len = recv(conn->sockfd, recv_buffer, sizeof(recv_buffer), MSG_DONTWAIT);
                 
                 if (recv_len > 0) {
+                    recv_buffer[recv_len] = '\0';
                     /* 数据接收成功 */
                     conn->last_activity = sys_now();
                     g_stats.bytes_received += recv_len;
@@ -1623,6 +1624,7 @@ if (errno == EAGAIN || errno == EWOULDBLOCK) {
                 return -1;
             } else {
                 printf("tcp_send_and_wait_response: 接收到 %d 字节响应\n", recv_ret);
+                recv_buffer[recv_ret] = '\0';
                 return recv_ret;
             }
     }