From: luozheng <1732036298@qq.com> Date: Sat, 5 Jul 2025 10:00:51 +0000 (+0800) Subject: 1.ai界面优化4g调节音量,500ms内调节一次 X-Git-Url: http://git.snicker.com.cn/css/static/gitweb.css?a=commitdiff_plain;h=b129608f7a3cccc12149d1bce4f555df4fb7fcf7;p=mirrors%2FFD230.git 1.ai界面优化4g调节音量,500ms内调节一次 2.解决来电铃声会使4g录音挂掉问题 3.tts播放采用根据符号一句一句播放 4.添加TTS_TEST宏保留测试“回声抑制”环境 --- diff --git a/code/sdk/application/wearable/fd230app/nativeui/aivoice/include/AiVoiceModel.h b/code/sdk/application/wearable/fd230app/nativeui/aivoice/include/AiVoiceModel.h index f8b3915fe..951c09f54 100644 --- a/code/sdk/application/wearable/fd230app/nativeui/aivoice/include/AiVoiceModel.h +++ b/code/sdk/application/wearable/fd230app/nativeui/aivoice/include/AiVoiceModel.h @@ -146,6 +146,10 @@ namespace OHOS void cancel_tts_play(void); + void ProcessTextByPunctuation(); + std::string GetAccumulatedText(void); + void sendSegment(const std::string &text, size_t pos); + private: AiVoiceModel(); ~AiVoiceModel(); @@ -162,6 +166,7 @@ namespace OHOS #endif std::string userQuestionStr; // 用户提出的问题 std::string aiAnswerStr; // AI回答的问题 + std::string accumulatedText; // tts播放文本 uint8_t ChatContentListCount{0}; // 列表数量 static const uint16_t MaxChatContentListCount = 2; // 对话列表最大数量 ChatContentItem chatTtems[MaxChatContentListCount] = {0, "", false}; // 对话项数组 diff --git a/code/sdk/application/wearable/fd230app/nativeui/aivoice/src/AiVoiceModel.cpp b/code/sdk/application/wearable/fd230app/nativeui/aivoice/src/AiVoiceModel.cpp index 200e39739..11585bc1d 100644 --- a/code/sdk/application/wearable/fd230app/nativeui/aivoice/src/AiVoiceModel.cpp +++ b/code/sdk/application/wearable/fd230app/nativeui/aivoice/src/AiVoiceModel.cpp @@ -546,6 +546,319 @@ namespace OHOS SendMsgToUIService(UI_UPDATE_AI_ANSWER_STR, 0, nullptr, 0); } + // 安全替换 UTF-8 字符串中的字符 + static void safe_replace_utf8(std::string &str, const std::string &from_chars, char replacement) + { + std::string result; + result.reserve(str.length()); // 预分配足够空间 + + const char *p = str.c_str(); + const char *end = p + str.length(); + + while (p < end) + { + unsigned char c = *p; + size_t char_size = 1; + + // 判断 UTF-8 字符的字节数 + if ((c & 0x80) == 0) + { + // 1字节字符 (ASCII) + char_size = 1; + } + else if ((c & 0xE0) == 0xC0) + { + // 2字节字符 + char_size = 2; + } + else if ((c & 0xF0) == 0xE0) + { + // 3字节字符 (常见中文) + char_size = 3; + } + else if ((c & 0xF8) == 0xF0) + { + // 4字节字符 (如 Emoji) + char_size = 4; + } + else + { + // 无效字符,按单字节处理 + char_size = 1; + } + + // 检查字符是否在要替换的集合中 + bool replace = false; + if (char_size == 1) + { + // 单字节字符直接检查 + replace = (from_chars.find(c) != std::string::npos); + } + else + { + // 多字节字符,提取完整字符并检查 + std::string utf8_char(p, char_size); + for (size_t i = 0; i < from_chars.length();) + { + // 提取 from_chars 中的下一个 UTF-8 字符 + unsigned char fc = from_chars[i]; + size_t fc_size = 1; + + if ((fc & 0x80) == 0) + { + fc_size = 1; + } + else if ((fc & 0xE0) == 0xC0) + { + fc_size = 2; + } + else if ((fc & 0xF0) == 0xE0) + { + fc_size = 3; + } + else if ((fc & 0xF8) == 0xF0) + { + fc_size = 4; + } + + if (i + fc_size <= from_chars.length()) + { + std::string fc_str = from_chars.substr(i, fc_size); + if (fc_str == utf8_char) + { + replace = true; + break; + } + } + + i += fc_size; + } + } + + // 添加到结果字符串 + if (replace) + { + result += replacement; + } + else + { + result.append(p, char_size); + } + + p += char_size; + } + + // 替换原字符串 + str.swap(result); + } + +#if 0 + void AiVoiceModel::ProcessTextByPunctuation() + { + const std::string punctuation = ",。!?;:))”、"; // 要替换的中文标点 + const char replacement = ','; // 替换为英文逗号 + const size_t MAX_SEGMENT_LENGTH = 120; // 最大分段长度 + + if (accumulatedText.empty()) + return; + + // 安全替换中文标点为英文逗号 + std::string processedText = accumulatedText; + safe_replace_utf8(processedText, punctuation, replacement); + + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "processedText:%s", processedText.c_str()); + + accumulatedText = processedText; + size_t commaPos = accumulatedText.find_last_of(','); + + // 处理长度限制,若超过最大长度则强制分段 + if (accumulatedText.length() >= MAX_SEGMENT_LENGTH) + { + commaPos = MAX_SEGMENT_LENGTH - 1; + // 查找最大长度内最近的逗号 + size_t lastCommaInRange = accumulatedText.find_last_of(',', commaPos); + if (lastCommaInRange != std::string::npos) + { + commaPos = lastCommaInRange; + } + } + + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "commaPos:%d", commaPos); + + if (commaPos != std::string::npos) + { + // 提取分段(包含英文逗号) + std::string segment = accumulatedText.substr(0, commaPos + 1); + + // 清理文本 + segment.erase( + std::remove(segment.begin(), segment.end(), '\n'), + segment.end()); + segment.erase( + std::remove(segment.begin(), segment.end(), '\r'), + segment.end()); + + // 发送到TTS播放 + if (!segment.empty()) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "播放分段文本: %s (长度: %zu)", + segment.c_str(), segment.length()); + uapi_start_tts_single_txt((char *)segment.c_str()); + LOS_Msleep(50); + } + + // 更新累积文本 + if (commaPos + 1 < accumulatedText.length()) + { + accumulatedText = accumulatedText.substr(commaPos + 1); + } + else + { + accumulatedText.clear(); + } + } + else + { + // 无逗号时继续累积或强制分段 + if (accumulatedText.length() > MAX_SEGMENT_LENGTH) + { + // 强制截断(确保在字符边界) + std::string segment = accumulatedText.substr(0, MAX_SEGMENT_LENGTH); + // 清理文本 + segment.erase( + std::remove(segment.begin(), segment.end(), '\n'), + segment.end()); + segment.erase( + std::remove(segment.begin(), segment.end(), '\r'), + segment.end()); + // 发送分段 + if (!segment.empty()) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "强制分段: %s (长度: %zu)", + segment.c_str(), segment.length()); + uapi_start_tts_single_txt((char *)segment.c_str()); + LOS_Msleep(50); + } + // 更新累积文本 + accumulatedText = accumulatedText.substr(MAX_SEGMENT_LENGTH); + } + else + { + // 无逗号且长度不足时继续累积 + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "累积文本(未触发): %s", accumulatedText.c_str()); + } + } + } +#endif + + void AiVoiceModel::ProcessTextByPunctuation() + { + const std::string punctuation = ",。!?;:))”、"; // 要替换的中文标点 + const char replacement = ','; // 替换为英文逗号 + const size_t MAX_SEGMENT_LENGTH = 120; // 最大分段长度 + const size_t MIN_SEGMENT_LENGTH = 1; // 最小发送长度(可调整) + + if (accumulatedText.empty()) + return; + + // 安全替换中文标点为英文逗号 + std::string processedText = accumulatedText; + safe_replace_utf8(processedText, punctuation, replacement); + + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "processedText:%s", processedText.c_str()); + + accumulatedText = processedText; + size_t commaPos = accumulatedText.find_last_of(','); + + // 处理长度限制,若超过最大长度则强制分段 + if (accumulatedText.length() >= MAX_SEGMENT_LENGTH) + { + commaPos = MAX_SEGMENT_LENGTH - 1; + // 查找最大长度内最近的逗号 + size_t lastCommaInRange = accumulatedText.find_last_of(',', commaPos); + if (lastCommaInRange != std::string::npos) + { + commaPos = lastCommaInRange; + } + } + + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "commaPos:%d", commaPos); + + if (commaPos != std::string::npos) + { + // 按标点分段发送 + sendSegment(accumulatedText, commaPos); + } + else + { + // 无逗号时的处理逻辑 + if (accumulatedText.length() >= MIN_SEGMENT_LENGTH) + { + // 强制发送完整文本(无论是否有标点) + std::string segment = accumulatedText; + segment.erase( + std::remove(segment.begin(), segment.end(), '\n'), + segment.end()); + segment.erase( + std::remove(segment.begin(), segment.end(), '\r'), + segment.end()); + + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "强制发送文本: %s (长度: %zu)", + segment.c_str(), segment.length()); + uapi_start_tts_single_txt((char *)segment.c_str()); + LOS_Msleep(50); + + // 发送后清空累积文本 + accumulatedText.clear(); + } + else + { + // 文本过短,继续累积 + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "累积文本过短(长度: %zu), 继续累积", + accumulatedText.length()); + } + } + } + + // 辅助函数:按标点分段发送 + void AiVoiceModel::sendSegment(const std::string &text, size_t pos) + { + // 提取分段(包含英文逗号) + std::string segment = text.substr(0, pos + 1); + + // 清理文本 + segment.erase( + std::remove(segment.begin(), segment.end(), '\n'), + segment.end()); + segment.erase( + std::remove(segment.begin(), segment.end(), '\r'), + segment.end()); + + // 发送到TTS播放 + if (!segment.empty()) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "按标点发送分段: %s (长度: %zu)", + segment.c_str(), segment.length()); + uapi_start_tts_single_txt((char *)segment.c_str()); + LOS_Msleep(50); + } + + // 更新累积文本 + if (pos + 1 < text.length()) + { + accumulatedText = text.substr(pos + 1); + } + else + { + accumulatedText.clear(); + } + } + + std::string AiVoiceModel::GetAccumulatedText(void) + { + return accumulatedText; + } + void AiVoiceModel::SetAiAnswerStrStr(std::string str, uint8_t type) { AIResponseType = type; @@ -561,6 +874,10 @@ namespace OHOS if (!OHOS::AiVoiceModel::GetInstance().GetIsLimitDisplayed()) // 如果ai答案没有显示到极限了,就更新ai答案字符串 { aiAnswerStr += str; + /* -------------------------------------------------------------------------- */ + // 累积接收到的文本 + accumulatedText += str; + /* -------------------------------------------------------------------------- */ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "接受字的符串:%s", aiAnswerStr.c_str()); SendMsgToUIService(UI_UPDATE_AI_ANSWER_STR, 0, nullptr, 0); } @@ -608,6 +925,7 @@ namespace OHOS WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "清空上次用户问题和Ai回答字符串"); userQuestionStr = ""; aiAnswerStr = ""; + accumulatedText = ""; } /*获取AI音频路径*/ @@ -1237,28 +1555,36 @@ namespace OHOS /* -------------------------------- tts播放定时器 -------------------------------- */ static osTimerId_t g_ai4g_is_start_tts_play_Handle = nullptr; - static uint8_t AI4G_IS_START_TTS_PLAY_TIME = 1; - + static constexpr const int8_t NUMBER_TEN = 15; + static int8_t AI4G_IS_START_TTS_PLAY_CNT = NUMBER_TEN; + static uint8_t tts_record_flag = 0; static void AI4G_IS_START_TTS_CallbackProc(int data) { - if (AI4G_IS_START_TTS_PLAY_TIME <= 0) + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AI4G_IS_START_TTS_CallbackProc:%s", AiVoiceModel::GetInstance().GetAccumulatedText().c_str()); + // 用来判断是否需要停止发送文本 + if (AiVoiceModel::GetInstance().GetAccumulatedText().empty()) { AiVoiceModel::GetInstance().stop_ai4g_tts_play_timer(); - std::string str = AiVoiceModel::GetInstance().GetAiAnswerStr(); - // 移除所有换行符(包括 '\n' 和 '\r') - str.erase( - std::remove(str.begin(), str.end(), '\n'), - str.end()); - str.erase( - std::remove(str.begin(), str.end(), '\r'), - str.end()); - uapi_start_tts_single_txt((char *)str.c_str()); } + if (get_bk_websocket_tts_tick() == 0) // 代表可以发录音文本 + { + AiVoiceModel::GetInstance().ProcessTextByPunctuation(); + } + else + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "get_bk_websocket_tts_tick:%d", get_bk_websocket_tts_tick()); + } +#if TTS_TEST + if (!tts_record_flag) + { + tts_record_flag = 1; + startAudioCaptureTask(); // 测试汇声抑制的 + } +#endif } static void AI4G_IS_START_TTS_Callback(int data) { - AI4G_IS_START_TTS_PLAY_TIME--; AI4G_IS_START_TTS_CallbackProc(data); // GraphicService::GetInstance()->PostGraphicEvent(std::bind(AI4G_IS_START_TTS_CallbackProc, data)); } @@ -1266,7 +1592,7 @@ namespace OHOS void AiVoiceModel::start_ai4g_tts_play_timer(uint32_t interval) { WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AiVoiceModel::start_ai_isready_timer"); - AI4G_IS_START_TTS_PLAY_TIME = 3; + // AI4G_IS_START_TTS_PLAY_CNT = NUMBER_TEN; /* -------------------------- 1.检查定时器是否已经存在,如果存在则返回 ------------------------- */ if (g_ai4g_is_start_tts_play_Handle != nullptr) { @@ -1304,7 +1630,7 @@ namespace OHOS // 检查定时器是否存在 if (g_ai4g_is_start_tts_play_Handle != nullptr) { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AiVoiceModel::stop_ai_isready_timer"); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "stop_ai4g_tts_play_timer"); osTimerStop(g_ai4g_is_start_tts_play_Handle); // 删除定时器并置为 nullptr osStatus_t ret = osTimerDelete(g_ai4g_is_start_tts_play_Handle); @@ -1313,7 +1639,17 @@ namespace OHOS WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "osTimerDelete failed, ret = %lx!!", ret); } g_ai4g_is_start_tts_play_Handle = nullptr; - AI4G_IS_START_TTS_PLAY_TIME = 1; + AI4G_IS_START_TTS_PLAY_CNT = NUMBER_TEN; +#if TTS_TEST + tts_record_flag = 0; + std::string filePath = "/user/aiRecord456.mp3"; + // 删除filePath文件 + if (remove(filePath.c_str()) != 0) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "remove failed, path: %s", filePath.c_str()); + } + StopListenAndRecordingUserQuestion(); +#endif } } diff --git a/code/sdk/application/wearable/fd230app/nativeui/aivoice/src/AiVoicePresenter.cpp b/code/sdk/application/wearable/fd230app/nativeui/aivoice/src/AiVoicePresenter.cpp index a164a4b47..27c3b0c45 100644 --- a/code/sdk/application/wearable/fd230app/nativeui/aivoice/src/AiVoicePresenter.cpp +++ b/code/sdk/application/wearable/fd230app/nativeui/aivoice/src/AiVoicePresenter.cpp @@ -97,6 +97,7 @@ namespace OHOS add_4GAI_vote(); // 4g投票 uapi_ble_connect_param_update(BLE_CONNECT_INTERVAL_HIGH_AI); + Audio::AudioManager::GetInstance().SetVolume(AUDIO_STREAM_VOICE_ASSISTANT, 100); } // 页面已经展示后的调用逻辑 @@ -321,6 +322,7 @@ namespace OHOS AiVoiceModel::GetInstance().ClearQuestionAndAiAnswerStr(); // 清空上次用户问题和Ai回答字符串 AiVoiceModel::GetInstance().SetIsClickable(false); AiVoiceModel::GetInstance().SetIsLimitDisplayed(false); + AiVoiceModel::GetInstance().stop_ai4g_tts_play_timer(); break; default: // Handle other cases if needed @@ -402,6 +404,7 @@ namespace OHOS PlayersModel::GetInstance()->PlayerPause(); // 暂停手机音乐 if (model->GetSelect4gorbt() == AI_SELECT_4G) { + AiVoiceModel::GetInstance().stop_ai4g_tts_play_timer(); uapi_UI_start_asr(); usleep(50000); ChangeViewAndLogicOperator(AIVOICE_RETURN_RESULT_TEXT_VIEWID, AIVOICE_AIMODE_CONNECTING); @@ -417,6 +420,7 @@ namespace OHOS { if (model->GetSelect4gorbt() == AI_SELECT_4G) { + AiVoiceModel::GetInstance().stop_ai4g_tts_play_timer(); // model->cancel_tts_play(); dinit_ai_task(); usleep(50000); @@ -749,8 +753,8 @@ namespace OHOS if (slider) { int value = slider->GetValue(); - WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "volume:%d front", value); - if (event.GetRotate() > 0) + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "volume:%d front", value); + if (event.GetRotate() <= 0) { WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "222"); value += 20; @@ -768,7 +772,7 @@ namespace OHOS value = 0; } } - WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "volume:%d end", value); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "volume:%d end", value); do_custom_cmd_service_check_msg(CUSTOM_CMD_MSG_TYPE_CHANGE_SYSTEM_VOLUME, (void *)(&value), sizeof(value)); } } @@ -776,7 +780,27 @@ namespace OHOS bool AiVoicePresenter::OnRotate(UIView &view, const RotateEvent &event) { - WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoicePresenter::OnRotateEnd"); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoicePresenter::OnRotate"); + static uint32_t lastCallTime = 0; + const uint32_t MIN_INTERVAL = 500; // 最小间隔500ms + + uint32_t currentTime = event.GetTimeStamp(); + + // 计算时间间隔 + uint32_t interval = currentTime - lastCallTime; + + // 仅当间隔大于500ms时才调用ChangeVolume + if (interval >= MIN_INTERVAL) + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoicePresenter::OnRotate: 允许调用ChangeVolume, 间隔: %ums", interval); + ChangeVolume(view, event); + lastCallTime = currentTime; + } + else + { + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoicePresenter::OnRotate: 忽略调用ChangeVolume, 间隔: %ums (需要>500ms)", interval); + } + return true; } diff --git a/code/sdk/application/wearable/fd230app/nativeui/aivoice/src/AiVoiceView.cpp b/code/sdk/application/wearable/fd230app/nativeui/aivoice/src/AiVoiceView.cpp index 2013239e8..37fcc1ef7 100644 --- a/code/sdk/application/wearable/fd230app/nativeui/aivoice/src/AiVoiceView.cpp +++ b/code/sdk/application/wearable/fd230app/nativeui/aivoice/src/AiVoiceView.cpp @@ -497,7 +497,7 @@ namespace OHOS VolumeProcess->SetForegroundStyle(STYLE_BACKGROUND_OPA, 0xff); VolumeProcess->SetKnobStyle(StyleDefault::GetSliderKnobStyle()); VolumeProcess->RequestFocus(); - VolumeProcess->SetRotateFactor(1.0); + VolumeProcess->SetRotateFactor(5.0); // VolumeProcess->SetVisible(false); VolumeProcess->SetOnRotateListener(presenter_); container_->Add(VolumeProcess); diff --git a/code/sdk/application/wearable/fd230app/nativeui/phoneservice/src/PhoneService.cpp b/code/sdk/application/wearable/fd230app/nativeui/phoneservice/src/PhoneService.cpp index 0c90da918..f82c016f8 100644 --- a/code/sdk/application/wearable/fd230app/nativeui/phoneservice/src/PhoneService.cpp +++ b/code/sdk/application/wearable/fd230app/nativeui/phoneservice/src/PhoneService.cpp @@ -51,6 +51,8 @@ extern "C" { #define CALL_TMP_LOG_PATH "/user/userdata/calltmplog.bin" #define CALL_LOG_DIR "/user/userdata" +#include "cat1_ws.h" + #ifndef UNUSED #define UNUSED(x) ((void)(x)) #endif @@ -1510,6 +1512,8 @@ static void PlayWatchRing(void) if(true != OHOS::ConfigModel::GetInstance()->GetDnotdisturb() && (!uapi_sleep_mode_flag_get()) && true != OHOS::ConfigModel::GetInstance()->GetSilentMode()) { + dinit_ai_task(); + LOS_Msleep(50); OHOS::AlarmClockModel::GetInstance()->testPlayerStart(RING_MUSIC); //g_audioState = AUDIO_ACT_INTERRUPT_WATCH_RING; diff --git a/code/sdk/application/wearable/service/msg_center/src/msg_center_customer.cpp b/code/sdk/application/wearable/service/msg_center/src/msg_center_customer.cpp index 7921b8b40..2896f263d 100644 --- a/code/sdk/application/wearable/service/msg_center/src/msg_center_customer.cpp +++ b/code/sdk/application/wearable/service/msg_center/src/msg_center_customer.cpp @@ -94,6 +94,7 @@ #include "PhoneAGService.h" #include #include "PhoneServiceC.h" +#include "cat1_ws.h" #define DIALDATASET 1 //#include "Systemupgrade.h" @@ -1091,6 +1092,8 @@ void MsgCenterNotifyCatIncomingCallProc(const Topic topic, Request* req) if(true != ConfigModel::GetInstance()->GetDnotdisturb() && (!uapi_sleep_mode_flag_get()) && true != ConfigModel::GetInstance()->GetSilentMode()) { + dinit_ai_task(); + LOS_Msleep(50); AlarmClockModel::GetInstance()->testPlayerStart(RING_MUSIC); } diff --git a/code/sdk/drivers/peripheral/slip/cat1Service/cat1_ws.cpp b/code/sdk/drivers/peripheral/slip/cat1Service/cat1_ws.cpp index 5a489512d..869db83e4 100644 --- a/code/sdk/drivers/peripheral/slip/cat1Service/cat1_ws.cpp +++ b/code/sdk/drivers/peripheral/slip/cat1Service/cat1_ws.cpp @@ -1126,6 +1126,11 @@ void set_ai_tts_server_init_flag(uint8_t flag) ai_tts_server_init_flag = flag; } +uint8_t get_bk_websocket_tts_tick(void) +{ + return bk_websocket_tts_tick; +} + void bk_websocket_demo(void *data) { // while (1) diff --git a/code/sdk/drivers/peripheral/slip/cat1Service/cat1_ws.h b/code/sdk/drivers/peripheral/slip/cat1Service/cat1_ws.h index a6f7717c9..003903174 100644 --- a/code/sdk/drivers/peripheral/slip/cat1Service/cat1_ws.h +++ b/code/sdk/drivers/peripheral/slip/cat1Service/cat1_ws.h @@ -34,6 +34,7 @@ uint8_t get_ai_chat_service_init_flag(void); void set_ai_chat_service_init_flag(uint8_t flag); uint8_t get_ai_tts_server_init_flag(void); void set_ai_tts_server_init_flag(uint8_t flag); +uint8_t get_bk_websocket_tts_tick(void); void uapi_start_asr_task(void); diff --git a/code/sdk/middleware/services/media/foundation/sample/wrapper/voice_call_volte_sample_wrapper.cpp b/code/sdk/middleware/services/media/foundation/sample/wrapper/voice_call_volte_sample_wrapper.cpp index 98211d218..a87b229bd 100755 --- a/code/sdk/middleware/services/media/foundation/sample/wrapper/voice_call_volte_sample_wrapper.cpp +++ b/code/sdk/middleware/services/media/foundation/sample/wrapper/voice_call_volte_sample_wrapper.cpp @@ -1285,7 +1285,12 @@ static void AudioCaptureProcess_AI(void* arg) } MEDIA_ERR_LOG("g_stream_in_uplink->Start"); - uint8_t* data_buf=(uint8_t *)malloc(1024); + #if TTS_TEST + int ai_size = 2048; + #else + int ai_size = 1024; + #endif + uint8_t* data_buf=(uint8_t *)malloc(ai_size); if(data_buf == NULL) { MEDIA_ERR_LOG("malloc"); @@ -1294,7 +1299,7 @@ static void AudioCaptureProcess_AI(void* arg) AudioCaptureTask_is_run=1; - FILE *fp= fopen("/user/aiRecord.bin","wb+"); + FILE *fp= fopen("/user/aiRecord123.mp3","wb+"); uint32_t record_size=0; @@ -1303,7 +1308,7 @@ static void AudioCaptureProcess_AI(void* arg) LOS_Msleep(10); CapturerBuffer capBuf = {}; capBuf.data = data_buf; - capBuf.size = 1024; + capBuf.size = ai_size; capBuf.frameCount = 1; int32_t readlen = g_stream_in_uplink->ObtainBuffer(capBuf, true); if(readlen>0) @@ -1314,11 +1319,18 @@ static void AudioCaptureProcess_AI(void* arg) record_size+=readlen; fwrite(data_buf,1,readlen,fp); + #if TTS_TEST + if(record_size>=1024*80) + { + g_sample_needStop=1; + } + #else if(record_size>=1024*40) { g_sample_needStop=1; } - memset_s(data_buf,1024,0,1024); + #endif + memset_s(data_buf,ai_size,0,ai_size); } // 蓝牙接口发送实时录音数据 @@ -1402,6 +1414,32 @@ void set_AIStreamend(uint8_t data) int32_t AIStreamWrite(uint8_t *buf, uint32_t size) { + + //保存音频流数据 + #if TTS_TEST + int32_t r = 0; + // 文件保存逻辑 + std::string filePath = "/user/aiRecord456.mp3"; + FILE *pfd = fopen(filePath.c_str(), "ab+"); // 以追加模式打开文件 + if (pfd == NULL) { + MEDIA_ERR_LOG("fopen failed, path: %s", filePath.c_str()); + return r; // 保留原有流写入的返回值 + } + + // 写入音频数据到文件 + size_t written = fwrite(buf, 1, size, pfd); + if (written != size) { + MEDIA_ERR_LOG("fwrite failed, expected: %u, actual: %zu", size, written); + } else { + MEDIA_INFO_LOG("Successfully saved %u bytes to file", size); + } + + // 关闭文件 + if (fclose(pfd) != 0) { + MEDIA_ERR_LOG("fclose failed"); + } + #endif + int32_t ret = 0; if(buf==NULL && size==1) { diff --git a/code/sdk/middleware/services/media/foundation/sample/wrapper/voice_call_volte_sample_wrapper.h b/code/sdk/middleware/services/media/foundation/sample/wrapper/voice_call_volte_sample_wrapper.h index a9173e787..4d3998551 100755 --- a/code/sdk/middleware/services/media/foundation/sample/wrapper/voice_call_volte_sample_wrapper.h +++ b/code/sdk/middleware/services/media/foundation/sample/wrapper/voice_call_volte_sample_wrapper.h @@ -15,6 +15,8 @@ extern "C" { #endif +#define TTS_TEST 0 + int32_t VoiceCallVolteSample(int32_t argc, const char *argv[]); void updata_Audio_code_hfp(uint32_t type);