HAND_VAD_INITIALIZED_NOTIFY, // VAD初始化完成通知
HAND_BLUETOOTH_CONNECT_NOTIFY, // 蓝牙耳机连接通知
HAND_BLUETOOTH_EARPHONE_CONNECT_STATUS_NOTIFY, // 蓝牙耳机连接状态通知
+ HAND_JUMP_DIALOGUE_SPEAKING_NOTIFY, // 跳转到对话说话界面通知
MAX_NUM_HANDLER,
} UiServiceMsgId;
// 处理对话响应消息的finished标志
void HandleDialogueResponseFinished(bool finished);
+ // 处理跳转到对话说话界面
+ void HandleJumpDialogueSpeaking();
// 减低视频帧率
void LowFrequence();
// 恢复视频帧率
#include <sys/time.h>
#include <service/graphic_service.h>
#include "custom_utils.h"
-#include <string.h>
#include "bluetooth/Ln_Bluetooth_apiC.h"
#include <algorithm>
#include <ctime>
#include "ConfigModelC.h"
#include "ConfigModel.h"
#include "cmsis_os2.h"
+#include "los_task.h"
#include "custom_runtime.h"
#include "ln_api_interface.h"
#ifdef __cplusplus
#endif
#include "imsl_vad.h"
#include "dmp_api.h"
+#include <audio_service.h>
+#include <audio_base_type.h>
#ifdef __cplusplus
}
#endif
m_dialogueModeFinished = true;
}
}
-
+
+ void ThunderBirdModel::HandleJumpDialogueSpeaking()
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ThunderBirdModel::HandleJumpDialogueSpeaking");
+
+ // 1. 停止其他音频服务,避免冲突
+ ln_audio_simple_stop();
+ AI_ForceInterrupt();
+ do_custom_cmd_service_check_msg(CUSTOM_CMD_MSG_AUDIO_DEINIT, NULL, 0);
+
+ // 2. 设置常亮屏
+ ScreenAlwaysOnCtr(OPEN_SCREEN_ALWAYS_ON);
+
+ // 3. 跳转到对话说话界面
+ if (ThunderBirdMainView::GetInstance()) {
+ int currentView = ThunderBirdMainView::GetInstance()->GetCurrentView();
+ ThunderBirdMainView::GetInstance()->ChangeView(currentView, THUNDERBIRD_DIALOGUEVIEW, ThunderBirdDialogueView::THUNDERBIRD_DIALOGUEVIEW_SPEAKING);
+ }
+
+ int32_t uiVolume = get_ui_volume();
+ if (uiVolume <= 0 || uiVolume > 100) {
+ uiVolume = 50; // 默认音量50%
+ }
+ AudioServiceSetVolume(AUDIO_STREAM_ALARM_CLOCK, uiVolume);
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ThunderBirdModel::HandleJumpDialogueSpeaking: Set ALARM_CLOCK volume to %d%%", uiVolume);
+
+ // 5. 循环播放 FactoryMode.mp3(使用 ln_audio_simple_play_loop,支持循环播放,无需线程)
+ const char *factory_mode_file = "/user/res/music/FactoryMode.mp3";
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ThunderBirdModel::HandleJumpDialogueSpeaking: Playing file: %s (will loop)", factory_mode_file);
+
+ // 使用 ln_audio_simple_play_loop 直接循环播放,无需线程
+ int ret = ln_audio_simple_play_loop(factory_mode_file, true);
+ if (ret != 0) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ThunderBirdModel::HandleJumpDialogueSpeaking: Failed to play file: %s, ret=%d", factory_mode_file, ret);
+ } else {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ThunderBirdModel::HandleJumpDialogueSpeaking: Successfully started loop playback");
+ }
+ }
void ThunderBirdModel::HandleBluetoothConnect(const char *bluetoothAddress)
{
auto* mainView = ThunderBirdMainView::GetInstance();
static void HandVadInitializedNotify(Request *request);
static void HandBluetoothConnectNotify(Request *request);
static void HandBluetoothEarphoneConnectStatusNotify(Request *request);
+static void HandJumpDialogueSpeakingNotify(Request *request);
// 消息处理程序项数组(每个消息类型对应一个处理函数,函数名以 Handle 开头)
MsgHandlerEntry msgHandlers[] = {
{HAND_VAD_INITIALIZED_NOTIFY,HandVadInitializedNotify},
{HAND_BLUETOOTH_CONNECT_NOTIFY,HandBluetoothConnectNotify},
{HAND_BLUETOOTH_EARPHONE_CONNECT_STATUS_NOTIFY,HandBluetoothEarphoneConnectStatusNotify},
+ {HAND_JUMP_DIALOGUE_SPEAKING_NOTIFY,HandJumpDialogueSpeakingNotify},
};
/* -------------------------------------------------------------------------- */
void ScreenTurnOn(int32_t timeout)
OHOS::ThunderBirdModel::GetInstance(), connectStatus));
}
}
+
+// 跳转到对话说话界面通知
+void HandJumpDialogueSpeakingNotify(Request *request)
+{
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_UI_SERVICE, "HandJumpDialogueSpeakingNotify msg_id = %d", request->msgId);
+ GraphicService::GetInstance()->PostGraphicEvent(
+ std::bind(&OHOS::ThunderBirdModel::HandleJumpDialogueSpeaking,OHOS::ThunderBirdModel::GetInstance()));
+}
/* -------------------------------------------------------------------------- */
#ifdef __cplusplus
}
#include "errcode.h"
#include "ln_api.h"
#include "ln_api_interface.h"
+#include "ln_audio_simple.h"
#include "cJSON.h"
#include "broadcast_feature.h"
#include "bts_br_gap.h"
return ERRCODE_SUCC;
}
+/* AT^LN_STRESS_TEST_DIALOGUE - 压测模式:跳转到对话说话界面,常亮屏且循环播放FactoryMode.mp3 */
+static uint32_t ln_stress_test_dialogue_at(uint8_t *para, uint32_t paraLen, char *strCommonCmd)
+{
+ LN_UNUSED(para);
+ LN_UNUSED(paraLen);
+ LN_UNUSED(strCommonCmd);
+
+ printf("[LN][STRESS_TEST_DIALOGUE] Starting stress test mode: jump to dialogue speaking view, screen always on and loop play FactoryMode.mp3\n");
+
+ // 发送跳转到对话说话界面的通知
+ push_jump_dialogue_speaking_notification();
+
+ printf("[LN][STRESS_TEST_DIALOGUE] Stress test mode enabled:\n");
+ printf(" - Jump to THUNDERBIRD_DIALOGUEVIEW_SPEAKING\n");
+ printf(" - Screen always on enabled\n");
+ printf(" - Loop playback: /user/res/music/FactoryMode.mp3\n");
+
+ return ERRCODE_SUCC;
+}
+
static const at_cmd_table_t g_ln_api_cmd[] = {
/* ---------------------------------- 雷鸟API --------------------------------- */
{(char *)"AT^LN_GET_TOKEN", ln_get_device_token_at, (char *)"获取雷鸟设备Token: AT^LN_GET_TOKEN[=deviceId,deviceIccid,deviceModel,deviceVersion]"},
{(char *)"AT^LN_DEBUG_POPUP", ln_debug_popup_at, (char *)"debug界面弹窗提示: AT^LN_DEBUG_POPUP[=message]"},
//帧率控制
- {(char *)"AT^LN_SET_FPS", ln_set_fps_at, (char *)"设置帧率: AT^LN_SET_FPS=<fps_value>"},
- {(char *)"AT^LN_GET_FPS", ln_get_fps_at, (char *)"获取当前帧率: AT^LN_GET_FPS"},
+ // {(char *)"AT^LN_SET_FPS", ln_set_fps_at, (char *)"设置帧率: AT^LN_SET_FPS=<fps_value>"},
+ // {(char *)"AT^LN_GET_FPS", ln_get_fps_at, (char *)"获取当前帧率: AT^LN_GET_FPS"},
//WS状态和网络参数显示
{(char *)"AT^LN_SHOW_WS_NET", ln_show_ws_net_at, (char *)"显示WS连接状态和网络参数: AT^LN_SHOW_WS_NET[=-p x,y]"},
{(char *)"AT^LN_BT_DISCONNECT", ln_bt_disconnect_at, (char *)"断开蓝牙设备: AT^LN_BT_DISCONNECT=AA:BB:CC:DD:EE:FF"},
//WebSocket日志等级设置
- {(char *)"AT^LN_WS_LOG_LEVEL", ln_ws_set_log_level_at, (char *)"设置WebSocket日志等级: AT^LN_WS_LOG_LEVEL=0-3"},
+ {(char *)"AT^LN_WS_LOG_LEVEL", ln_ws_set_log_level_at, (char *)"设置WebSocket日志等级: AT^LN_WS_LOG_LEVEL=0-3"},
+ //压测相关
+ {(char *)"AT^LN_STRESS_TEST_DIALOGUE", ln_stress_test_dialogue_at, (char *)"压测模式:跳转到对话说话界面,常亮屏且循环播放FactoryMode.mp3: AT^LN_STRESS_TEST_DIALOGUE"},
};
SendMsgToUIService(HAND_DIALOGUE_RESPONSE_FINISHED_NOTIFY, 0, &finished, sizeof(finished));
}
+//通知跳转到对话说话界面
+void push_jump_dialogue_speaking_notification(void)
+{
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[JUMP_DIALOGUE_SPEAKING] Jump to dialogue speaking view");
+ SendMsgToUIService(HAND_JUMP_DIALOGUE_SPEAKING_NOTIFY, 0, NULL, 0);
+}
+
//通知VAD初始化完成
void push_vad_initialized_notification(void)
{
void push_story_response_finished_notification(bool finished);
//通知对话响应finished
void push_dialogue_response_finished_notification(bool finished);
+//通知跳转到对话说话界面
+void push_jump_dialogue_speaking_notification(void);
//通知VAD初始化完成
void push_vad_initialized_notification(void);
//通知进行蓝牙耳机连接操作
return 0;
}
+int ln_audio_simple_play_loop(const char *file_path, bool loop)
+{
+ if (!file_path || file_path[0] == '\0')
+ {
+ printf("[LN_AUDIO_SIMPLE] invalid file path\n");
+ return -1;
+ }
+
+ if (!AudioInitOnce())
+ return -2;
+
+ // 设置播放器回调
+ g_simple.player->SetPlayerCallback(g_player_callback);
+
+ // 设置音频源
+ g_simple.source = std::make_shared<Source>(file_path, g_simple.header);
+ if (!g_simple.source)
+ {
+ printf("[LN_AUDIO_SIMPLE] create Source failed\n");
+ return -3;
+ }
+
+ int32_t ret;
+ ret = g_simple.player->SetSource(*g_simple.source);
+ if (ret != 0)
+ {
+ printf("[LN_AUDIO_SIMPLE] SetSource failed: %d\n", ret);
+ g_simple.player->Reset();
+ return -4;
+ }
+
+ // 设置循环播放
+ g_simple.player->EnableSingleLooping(loop);
+ g_simple.player->SetAudioStreamType(AUDIO_STREAM_ALARM_CLOCK);
+
+ // 在 Prepare 之前激活音频中断,因为 Prepare 时会创建音频流,需要有效的音频中断会话
+ if (!EnsureAudioInterrupt())
+ {
+ g_simple.player->Reset();
+ return -6;
+ }
+
+ ret = g_simple.player->Prepare();
+ if (ret != 0)
+ {
+ printf("[LN_AUDIO_SIMPLE] Prepare failed: %d\n", ret);
+ g_simple.player->Reset();
+ ClearAudioInterrupt();
+ return -5;
+ }
+
+ ret = g_simple.player->SetAudioSessionId(g_simple.sessionId);
+ if (ret != 0)
+ {
+ printf("[LN_AUDIO_SIMPLE] SetAudioSessionId failed: %d\n", ret);
+ g_simple.player->Reset();
+ ClearAudioInterrupt();
+ return -7;
+ }
+
+ ret = g_simple.player->Play();
+ if (ret != 0)
+ {
+ printf("[LN_AUDIO_SIMPLE] Play failed: %d\n", ret);
+ g_simple.player->Stop();
+ g_simple.player->Reset();
+ ClearAudioInterrupt();
+ return -8;
+ }
+
+ g_simple.is_playing = true;
+ g_simple.is_paused = false;
+ printf("[LN_AUDIO_SIMPLE] started: %s (loop=%s)\n", file_path, loop ? "true" : "false");
+ return 0;
+}
+
int ln_audio_simple_stop(void)
{
if (!g_simple.player)
*/
int ln_audio_simple_play(const char *file_path);
+/*
+ * 播放本地音频文件(支持循环播放)
+ * 参数:
+ * file_path - 音频文件的绝对路径
+ * loop - 是否循环播放
+ * 返回:
+ * 0 成功启动播放(异步)
+ * <0 失败
+ */
+int ln_audio_simple_play_loop(const char *file_path, bool loop);
+
/*
* 主动停止播放(同步停止,确保资源释放)
* 返回:0 成功,<0 失败