json_buf[n] = '\0';
ParseCharacterConfigData(json_buf);
fclose(file);
- printf("[DEVICE_CHARACTER] read character config success\n");
+ // hasScreenImage_ 非服务端字段,由角色配置变更时写入 KV,此处从 KV 恢复
+ // UtilsGetValue 成功时:从文件返回 value 长度(如 "1" 返回 1),从缓存返回 0;失败返回负数
+ char temp[16] = {0};
+ int kvRet = UtilsGetValue("character_has_screen_image", temp, sizeof(temp));
+ if (kvRet >= 0 && temp[0] == '1') {
+ hasScreenImage_ = 1;
+ } else {
+ hasScreenImage_ = 0;
+ }
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[DEVICE_CHARACTER] read character config success (hasScreenImage_=%d from KV, kvRet=%d)", hasScreenImage_, kvRet);
}
// 解析JSON中的data数据
last_hairColor_ = hairColor_;
last_eyesColor_ = eyesColor_;
last_hairStyle_ = hairStyle_;
+ last_hasScreenImage_ = hasScreenImage_;
last_screenImageAsEmoji_ = screenImageAsEmoji_;
return;
}
last_screenImageAsEmoji_ = screenImageAsEmoji;
last_hasScreenImage_ = hasScreenImage;
WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ThunderBirdModel::HandleCharacterConfigChange: 角色配置已更新");
-
+ // hasScreenImage 非服务端字段,仅本地使用;写入 KV 以便重启后恢复
+ (void)UtilsSetValue("character_has_screen_image", hasScreenImage ? "1" : "0");
+ // printf("character_has_screen_image: %s\n", hasScreenImage ? "1" : "0");
+ // printf("hasScreenImage_: %d\n", hasScreenImage_);
+
// 角色切换完成后,上报蓝牙连接状态
ln_bt_report_earphone_connection_status(false); // 不需要弹窗
WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ThunderBirdModel::HandleCharacterConfigChange: 角色切换完成,已上报蓝牙连接状态");
m_alwaysOnRefreshActive = false;
m_alwaysOnRefreshTime = 0;
}
+
+ //测试BGM开始函数
+ void ThunderBirdModel::StartDialogueBgm()
+ {
+ static const char *kDialogueBgmPath = "/user/res/music/BGM.mp3";
+ int ret = ln_audio_simple_play_loop(kDialogueBgmPath, true);
+ if (ret != 0) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "StartDialogueBgm: play_loop %s failed, ret=%d", kDialogueBgmPath, ret);
+ } else {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "StartDialogueBgm: BGM mix started: %s", kDialogueBgmPath);
+ }
+ }
+ //测试BGM停止函数
+ void ThunderBirdModel::StopDialogueBgm()
+ {
+ ln_audio_simple_stop();
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "StopDialogueBgm: BGM stopped");
+ }
void ThunderBirdModel::HandleBluetoothConnect(const char *bluetoothAddress)
{
if(ThunderBirdMainView::GetInstance()){
uapi_set_screen_on_api(); // 亮屏
int currentView = ThunderBirdMainView::GetInstance()->GetCurrentView(); //获取当前视图
+ int currentSubView = ThunderBirdMainView::GetInstance()->GetCurrentSubView();
+ // 如果是从对话模式(说话/聆听)跳转到绑定成功界面,则先退出对话模式再跳转
+ if (currentView == THUNDERBIRD_DIALOGUEVIEW &&
+ (currentSubView == ThunderBirdDialogueView::THUNDERBIRD_DIALOGUEVIEW_LISTENING ||
+ currentSubView == ThunderBirdDialogueView::THUNDERBIRD_DIALOGUEVIEW_SPEAKING)) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ThunderBirdModel::HandleBindAndUnbind: 从对话模式跳转绑定成功,先退出对话模式");
+ StopCountUpTimer();
+ ThunderBirdPresenter::GetInstance()->SetDialogueing(false);
+ ln_ws_end_audio_chat();//结束对话
+ AI_ForceInterrupt();
+ ln_ws_send_voice_chat_interrupt("退出对话");
+ OnExitDialogueMode();
+ do_custom_cmd_service_check_msg(CUSTOM_CMD_MSG_AUDIO_DEINIT, NULL, 0);
+ }
ThunderBirdMainView::GetInstance()->ChangeView(currentView, THUNDERBIRD_ADJUSTVIEW, ThunderBirdAdjustView::THUNDERBIRD_ADJUSTVIEW_BIND_SUCCESS);
}
int volume = AudioManager::GetInstance().SetVolume(AUDIO_STREAM_VOICE_ASSISTANT, 50);
{
//增加设备解绑提示
int currentView = ThunderBirdMainView::GetInstance()->GetCurrentView(); //获取当前视图
+ int currentSubView = ThunderBirdMainView::GetInstance()->GetCurrentSubView();
WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ThunderBirdModel::HandleBindAndUnbind: 设备已解绑,显示解绑警告");
uapi_set_screen_on_api();
bind_status = false;//解绑标志值位,用于界面跳转真正解绑放到出厂设置里面
m_pending_factory_reset = true;
ThunderBirdModel::GetInstance()->StartFactoryResetTimer(1); // 2秒后恢复出厂设置
+ // 如果是从对话模式(说话/聆听)跳转到解绑警告/绑定成功界面,则先退出对话模式
+ if (currentView == THUNDERBIRD_DIALOGUEVIEW &&
+ (currentSubView == ThunderBirdDialogueView::THUNDERBIRD_DIALOGUEVIEW_LISTENING ||
+ currentSubView == ThunderBirdDialogueView::THUNDERBIRD_DIALOGUEVIEW_SPEAKING)) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ThunderBirdModel::HandleBindAndUnbind: 从对话模式跳转解绑警告/绑定成功,先退出对话模式");
+ StopCountUpTimer();
+ ThunderBirdPresenter::GetInstance()->SetDialogueing(false);
+ ln_ws_end_audio_chat();//结束对话
+ AI_ForceInterrupt();
+ ln_ws_send_voice_chat_interrupt("退出对话");
+ OnExitDialogueMode();
+ do_custom_cmd_service_check_msg(CUSTOM_CMD_MSG_AUDIO_DEINIT, NULL, 0);
+ }
+
ThunderBirdMainView::GetInstance()->ChangeView(currentView, THUNDERBIRD_ADJUSTVIEW, ThunderBirdAdjustView::THUNDERBIRD_ADJUSTVIEW_BIND_SUCCESS);
if(ThunderBirdAdjustView::GetInstance())
{
if (ThunderBirdMainView::GetInstance() && ThunderBirdMainView::GetInstance()->listenIcon) {
ThunderBirdMainView::GetInstance()->listenIcon->SetVisible(true);
}
+ // 播放结束进入聆听前状态,打开 VAD 识别
+ ln_ws_set_vad_recognition_enabled(true);
// 启动20秒定时器,时间到就退出对话
StartCountUpTimer(20);
WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ThunderBirdModel::HandleAudioPlaybackEnd: 启动20秒定时器,时间到就退出对话");
WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ThunderBirdModel::HandleAudioRecordingStart: 在哄睡界面(故事模式),忽略录音开始事件");
return;
}
- if ((currentView == THUNDERBIRD_DIALOGUEVIEW &&
- currentSubView == ThunderBirdDialogueView::THUNDERBIRD_DIALOGUEVIEW_SPEAKING) ) {
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "录音开始,跳转到聆听状态");
- view->ChangeView(currentView, THUNDERBIRD_DIALOGUEVIEW, ThunderBirdDialogueView::THUNDERBIRD_DIALOGUEVIEW_LISTENING);
- // ThunderBirdDialogueView::GetInstance()->IsNormalEnd = false;
- }
- // 如果当前在哄睡界面,且不在故事选择状态,则跳转到故事选择状态
- else {
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ThunderBirdModel::HandleAudioRecordingStart: 不满足推送条件");
+ if (currentView == THUNDERBIRD_DIALOGUEVIEW) {
+ if (currentSubView == ThunderBirdDialogueView::THUNDERBIRD_DIALOGUEVIEW_SPEAKING) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+ "ThunderBirdModel::HandleAudioRecordingStart: speaking 中收到录音开始,交由 VAD 流程处理,只切换到聆听界面");
+ auto* mainView = ThunderBirdMainView::GetInstance();
+ if (mainView && mainView->listenIcon) {
+ mainView->listenIcon->SetVisible(true);
+ }
+ view->ChangeView(currentView, THUNDERBIRD_DIALOGUEVIEW,
+ ThunderBirdDialogueView::THUNDERBIRD_DIALOGUEVIEW_LISTENING);
+ return;
+ } else if (currentSubView == ThunderBirdDialogueView::THUNDERBIRD_DIALOGUEVIEW_LISTENING) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+ "ThunderBirdModel::HandleAudioRecordingStart: 已在聆听界面,忽略重复的录音开始事件");
+ return;
+ }
}
+
+ // 其它界面当前不处理录音开始
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ThunderBirdModel::HandleAudioRecordingStart: 不满足推送条件");
}
}
WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ThunderBirdModel::OnEnterDialogueMode: 眨眼表情文件不存在: %s", winkingExpressionPath.c_str());
}
}
+ // 进入对话且为聆听界面时打开 VAD 识别(仅在此处与播放结束、按键进入聆听时打开)
+ ln_ws_set_vad_recognition_enabled(true);
}
// 退出对话模式时恢复表情
void ThunderBirdModel::OnExitDialogueMode()
{
WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ThunderBirdModel::OnExitDialogueMode: 开始退出对话模式");
+ ln_ws_set_vad_recognition_enabled(false);
#ifdef SUPPORT_CAT1_SERVICE
// 退出对话模式时恢复AT+CESQ命令,恢复获取4G信号