Code review from 胡传军
* refs/changes/2844/head: (15 commits squashed)
- 屏蔽VAD认证
- Merge branch 'sdk650pathc0423' of https://codeup.aliyun.com/
64191456b9581d62e8f81ac0/FD230 into sdk650pathc0423
- 增加文件保存测试开关
- Merge branch 'sdk650pathc0423' of https://codeup.aliyun.com/
64191456b9581d62e8f81ac0/FD230 into sdk650pathc0423
- Merge branch 'sdk650pathc0423' of https://codeup.aliyun.com/
64191456b9581d62e8f81ac0/FD230 into sdk650pathc0423
- 修改ai宏开关不生效的问题
- Merge branch 'sdk650pathc0423' of https://codeup.aliyun.com/
64191456b9581d62e8f81ac0/FD230 into sdk650pathc0423
- cat1升级启动换位置
- Merge branch 'sdk650pathc0423' of https://codeup.aliyun.com/
64191456b9581d62e8f81ac0/FD230 into sdk650pathc0423
- Merge branch 'sdk650pathc0423' of https://codeup.aliyun.com/
64191456b9581d62e8f81ac0/FD230 into sdk650pathc0423
- Merge branch 'sdk650pathc0423' of https://codeup.aliyun.com/
64191456b9581d62e8f81ac0/FD230 into sdk650pathc0423
- vad参数调整
- Merge branch 'sdk650pathc0423' of https://codeup.aliyun.com/
64191456b9581d62e8f81ac0/FD230 into sdk650pathc0423
- 修改ln 蓝牙耳机相关
- Merge branch 'sdk650pathc0423' of https://codeup.aliyun.com/
64191456b9581d62e8f81ac0/FD230 into sdk650pathc0423
Signed-off-by: aliyun8003852482 <1224667075@qq.com>
Reviewed-by: snickersun@163.com <accounts_62b90f7fcf51ade33b6f628e@mail.teambition.com>
Merged-by: snickersun@163.com <accounts_62b90f7fcf51ade33b6f628e@mail.teambition.com>
link: https://codeup.aliyun.com/64191456b9581d62e8f81ac0/FD230/change/2844
#include "thunderbird/include/ThunderBirdMainView.h"\r
#include "thunderbird/include/ThunderBirdBlueView.h"\r
#include <custom_utils.h>\r
+#include "ai_media.h"\r
+\r
namespace OHOS {\r
\r
#define BT_SPP_TASK_STACK_SIZE 2048\r
if (connState == PROFILE_STATE_CONNECTED) {\r
uint32_t ret = avrcp_ct_connect(bdAddr);\r
WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "avrcp_ct_connect ret = 0x%x", ret);\r
+\r
+ if(AI_IsVoiceServiceRunning()){\r
+ ln_ws_audio_deinit();\r
+ }\r
+ \r
+ set_a2dp_is_connect(true);\r
PhoneAudioManagerSetDeviceConnState(OUT_BLUETOOTH_A2DP, AUDIO_DEVICE_CONNECTED);\r
GraphicService::GetInstance()->PostGraphicEvent(std::bind(ACLConnectionSuss, *bdAddr));\r
int earphoneConnectStatus = 1;\r
}\r
\r
if (connState == PROFILE_STATE_DISCONNECTED) {\r
+ if(AI_IsVoiceServiceRunning()){\r
+ ln_ws_audio_deinit();\r
+ }\r
+\r
+\r
PhoneAudioManagerSetDeviceConnState(OUT_BLUETOOTH_A2DP, AUDIO_DEVICE_DISCONNECTED);\r
+ set_a2dp_is_connect(false);\r
+\r
+ \r
GraphicService::GetInstance()->PostGraphicEvent(std::bind(ACLConnectionFail, *bdAddr));\r
int earphoneConnectStatus = 0;\r
SendMsgToUIService(HAND_BLUETOOTH_EARPHONE_CONNECT_STATUS_NOTIFY, 0, &earphoneConnectStatus, sizeof(earphoneConnectStatus));\r
} AIVoiceAudioParams;
+
int32_t old_Start_AIVoice(AIVoiceDataCallback dataCallback, void* userData,
const AIVoiceAudioParams* inputAudioParams,
const AIVoiceAudioParams* outputAudioParams,
*/
bool AI_IsSecondStreamInEnabled(void);
+/*
+ * @brief 开启第二个音频上行流(初始化并启动)
+ * @return 0 成功,-1 失败
+ */
+int32_t AI_StartSecondStreamIn(void);
+
+/*
+ * @brief 关闭第二个音频上行流(停止并反初始化)
+ * @return 0 成功,-1 失败
+ */
+int32_t AI_StopSecondStreamIn(void);
+
+/*
+ * @brief 获取第二个音频上行流状态
+ * @return true 正在运行,false 未运行或未启用
+ */
+bool AI_GetSecondStreamInStatus(void);
+
/*
* @brief 从第二个音频上行流获取音频数据缓冲区
* @param data 音频数据缓冲区指针
*/
int32_t AI_SecondStreamInObtainBuffer(uint8_t *data, uint32_t *size);
+/*
+ * @brief 设置连接状态
+ * @param state 设置状态
+ */
+void set_a2dp_is_connect(bool state);
+
#ifdef __cplusplus
};
#endif
return ret;
}
+/**
+ * @brief 初始化第二个音频上行流(线程安全版本,使用全局上下文)
+ * @return 0 成功,-1 失败
+ */
+static int32_t InitSecondAudioStreamInSafe(void)
+{
+ int32_t ret = 0;
+ MediaMutexHandle mutex = GetGlobalMutex();
+ if (mutex == nullptr) {
+ return -1;
+ }
+
+ MediaMutexLock(mutex);
+ if (g_aiVoiceContext == nullptr) {
+ MEDIA_ERR_LOG("AI voice context is null, please start AI voice first");
+ MediaMutexUnLock(mutex);
+ return -1;
+ }
+
+ if (!g_aiVoiceContext->useSecondStreamIn) {
+ MEDIA_ERR_LOG("Second audio stream in is not enabled");
+ MediaMutexUnLock(mutex);
+ return -1;
+ }
+
+ ret = InitSecondAudioStreamIn(g_aiVoiceContext);
+ if (ret != 0) {
+ MEDIA_ERR_LOG("second audio stream in init failed");
+ }
+
+ MediaMutexUnLock(mutex);
+ return ret;
+}
+
+/**
+ * @brief 启动第二个音频上行流(线程安全版本,使用全局上下文)
+ * @return 0 成功,-1 失败
+ */
+static int32_t StartSecondAudioStreamInSafe(void)
+{
+ int32_t ret = 0;
+ MediaMutexHandle mutex = GetGlobalMutex();
+ if (mutex == nullptr) {
+ return -1;
+ }
+
+ MediaMutexLock(mutex);
+ if (g_aiVoiceContext == nullptr) {
+ MEDIA_ERR_LOG("AI voice context is null, please start AI voice first");
+ MediaMutexUnLock(mutex);
+ return -1;
+ }
+
+ ret = StartSecondAudioStreamIn(g_aiVoiceContext);
+ if (ret != 0) {
+ MEDIA_ERR_LOG("second audio stream in start failed");
+ }
+
+ MediaMutexUnLock(mutex);
+ return ret;
+}
+
// 注意:g_aiVoiceContext 已在上方定义,这里不需要重复定义
context->bufferSize = AI_VOICE_BUFFER_SIZE;
return true;
}
+bool a2dp_is_connect=false;
+
+void set_a2dp_is_connect(bool state)
+{
+ a2dp_is_connect=state;
+}
static int32_t LocalAIVoiceStart(AIVoiceContext *context)
{
}
// 初始化第二个上行流(如果启用)
- if (context->useSecondStreamIn) {
+ if (context->useSecondStreamIn && a2dp_is_connect==false) {
ret = InitSecondAudioStreamIn(context);
if (ret != 0) {
MEDIA_ERR_LOG("Failed to init second audio stream in");
return enabled;
}
+/**
+ * @brief 开启第二个音频上行流(初始化并启动)
+ * @return 0 成功,-1 失败
+ */
+int32_t AI_StartSecondStreamIn(void)
+{
+ // 检查音频主服务是否已开启
+ MEDIA_ERR_LOG("AI_StartSecondStreamIn");
+
+ if (!AI_IsVoiceServiceRunning()) {
+ MEDIA_ERR_LOG("Audio main service is not running, please start AI voice service first");
+ return -1;
+ }
+
+ // 先初始化
+ int32_t ret = InitSecondAudioStreamInSafe();
+ if (ret != 0) {
+ MEDIA_ERR_LOG("Failed to init second audio stream in");
+ return -1;
+ }
+
+ // 再启动
+ ret = StartSecondAudioStreamInSafe();
+ if (ret != 0) {
+ MEDIA_ERR_LOG("Failed to start second audio stream in");
+ // 如果启动失败,尝试清理已初始化的资源
+ DeinitSecondAudioStreamInSafe();
+ return -1;
+ }
+
+ MEDIA_INFO_LOG("Second audio stream in started successfully");
+ return 0;
+}
+
+/**
+ * @brief 关闭第二个音频上行流(停止并反初始化)
+ * @return 0 成功,-1 失败
+ */
+int32_t AI_StopSecondStreamIn(void)
+{
+ int32_t ret = 0;
+
+ // 先停止
+ ret = StopSecondAudioStreamInSafe();
+ if (ret != 0) {
+ MEDIA_ERR_LOG("Failed to stop second audio stream in");
+ // 继续执行反初始化,即使停止失败
+ }
+
+ // 再反初始化
+ ret = DeinitSecondAudioStreamInSafe();
+ if (ret != 0) {
+ MEDIA_ERR_LOG("Failed to deinit second audio stream in");
+ return -1;
+ }
+
+ MEDIA_INFO_LOG("Second audio stream in stopped successfully");
+ return 0;
+}
+
+/**
+ * @brief 获取第二个音频上行流状态
+ * @return true 正在运行,false 未运行或未启用
+ */
+bool AI_GetSecondStreamInStatus(void)
+{
+ bool isRunning = false;
+
+ MediaMutexHandle mutex = GetGlobalMutex();
+ if (mutex == nullptr) {
+ return false;
+ }
+
+ MediaMutexLock(mutex);
+ if (g_aiVoiceContext != nullptr &&
+ g_aiVoiceContext->useSecondStreamIn &&
+ g_aiVoiceContext->secondStreamIn != nullptr) {
+ isRunning = true;
+ }
+ MediaMutexUnLock(mutex);
+
+ return isRunning;
+}
+
/**
* @brief 从第二个音频上行流获取音频数据缓冲区
* @param data 音频数据缓冲区指针
return 0;
}
+
+
+
+
#ifdef __cplusplus
};
#endif
#if ENABLE_VAD_SERVER
if (g_vad_server_enabled && g_vad_server_initialized && vad_server_is_running()) {
- #ifdef VAD_LOCAL_PM
- vad_audio_format_t format = VAD_AUDIO_FORMAT_MP3; // 默认 MP3
+
+ if(AI_GetSecondStreamInStatus()==false){
+ vad_audio_format_t format = VAD_AUDIO_FORMAT_MP3; // 默认 MP3
-errcode_t ret = vad_server_send_audio(format, data, size, false);
-
- #else
- vad_audio_format_t format = VAD_AUDIO_FORMAT_PCM; // 默认 MP3
-
- if (data && size > 0) {
-
- uint8_t *pcm_data=(uint8_t *) malloc(1024*3);
- uint32_t len=1024*3;
-
- errcode_t ret= AI_SecondStreamInObtainBuffer(pcm_data,&len);
-
- if(ret==0 && len>0)
- {
- ret = vad_server_send_audio(format, pcm_data, len, false);
-// AI_SendAudioDataToQueue(pcm_data, len);
+ errcode_t ret = vad_server_send_audio(format, data, size, false);
if (ret != ERRCODE_SUCC) {
/* 静默失败,避免过多日志 */
// LN_WS_DEBUG("VAD: Sent %u bytes (format=%d, is_last=%d)\n",
// size, format, false);
}
-
}
- free(pcm_data);
-
+ else{
+ vad_audio_format_t format = VAD_AUDIO_FORMAT_PCM; // 默认 MP3
+
+ uint8_t *pcm_data=(uint8_t *) malloc(1024*3);
+ uint32_t len=1024*3;
+
+ errcode_t ret= AI_SecondStreamInObtainBuffer(pcm_data,&len);
+
+ if(ret==0 && len>0)
+ {
+ ret = vad_server_send_audio(format, pcm_data, len, false);
+ if (ret != ERRCODE_SUCC) {
+ /* 静默失败,避免过多日志 */
+ } else {
+ // LN_WS_DEBUG("VAD: Sent %u bytes (format=%d, is_last=%d)\n",
+ // size, format, false);
+ }
+ }
+ free(pcm_data);
}
- #endif
-
// 如果是结束标志,打印日志
if (false) {
LN_WS_INFO("VAD: Audio recording ended\n");
void vad_status_callback_ln_ws(int status)
{
LN_WS_INFO("Audio vad_status_callback_ln_ws %d\n",status);
-
+
// 检查VAD服务器是否被禁用(例如在哄睡模式下)
if (!ln_ws_is_vad_server_enabled()) {
LN_WS_INFO("VAD server is disabled, ignoring callback (status=%d)\n", status);
#ifdef SUPPORT_AI_SERVICE
#include "websocket_server_manager.h"
+#include "ai_media.h"
#endif
#ifdef FD230_650
PRINT("VAD auth via custom cmd\n");
ln_ws_vad_auth();
break;
+ case CUSTOM_CMD_MSG_START_SECOND_STREAM_IN:
+#ifdef SUPPORT_AI_SERVICE
+ {
+ int32_t ret = AI_StartSecondStreamIn();
+ if (ret == 0) {
+ PRINT("Second audio stream in started via custom cmd\n");
+ } else {
+ PRINT("Failed to start second audio stream in via custom cmd, ret=%d\n", ret);
+ }
+ }
+#else
+ PRINT("AI service not supported\n");
+#endif
+ break;
+ case CUSTOM_CMD_MSG_STOP_SECOND_STREAM_IN:
+#ifdef SUPPORT_AI_SERVICE
+ {
+ int32_t ret = AI_StopSecondStreamIn();
+ if (ret == 0) {
+ PRINT("Second audio stream in stopped via custom cmd\n");
+ } else {
+ PRINT("Failed to stop second audio stream in via custom cmd, ret=%d\n", ret);
+ }
+ }
+#else
+ PRINT("AI service not supported\n");
+#endif
+ break;
#endif
break;
case CUSTOM_CMD_MSG_ROTARY_OPEN:
{
set_chat_ai_type(ai_type);
}
+
+/**
+ * @brief 启动第二个音频上行流
+ */
+void uapi_start_second_stream_in(void)
+{
+ do_custom_cmd_service_check_msg(CUSTOM_CMD_MSG_START_SECOND_STREAM_IN, NULL, 0);
+}
+
+/**
+ * @brief 停止第二个音频上行流
+ */
+void uapi_stop_second_stream_in(void)
+{
+ do_custom_cmd_service_check_msg(CUSTOM_CMD_MSG_STOP_SECOND_STREAM_IN, NULL, 0);
+}
#endif
#endif
\ No newline at end of file
#define CUSTOM_CMD_MSG_ROTARY_OPEN 0x29
+#define CUSTOM_CMD_MSG_START_SECOND_STREAM_IN 0x30
+
+#define CUSTOM_CMD_MSG_STOP_SECOND_STREAM_IN 0x31
+
+
typedef enum {
BR_HFP_CONNECT=1,
BR_HFP_DISCONNECT,
#ifdef SUPPORT_AI_SERVICE
void uapi_start_AI_asr(void);
void uapi_stop_AI_asr(void);
+void uapi_start_second_stream_in(void);
+void uapi_stop_second_stream_in(void);
#endif
#ifdef SUPPORT_AI_SERVICE