Skip to content

Commit 576612d

Browse files
committed
修复小智唤醒后没有进入聆听状态问题
1 parent 4dd3da2 commit 576612d

File tree

2 files changed

+144
-25
lines changed

2 files changed

+144
-25
lines changed

projects/Edgi_Talk_M55_XiaoZhi/applications/xiaozhi/xiaozhi.cpp

Lines changed: 142 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
#define MAX_CLIENT_ID_LEN 40
2626
#define MAX_MAC_ADDR_LEN 20
2727
#define WEBSOCKET_RECONNECT_DELAY_MS 5000
28-
#define WEBSOCKET_CONNECTION_TIMEOUT_MS 50000
28+
#define WEBSOCKET_CONNECTION_TIMEOUT_MS 5000
2929
#define NETWORK_CHECK_DELAY_MS 500
3030
#define RETRY_DELAY_BASE_MS 1000
3131
#define RETRY_DELAY_INCREMENT_MS 200
@@ -50,7 +50,9 @@ xiaozhi_app_t g_app =
5050
.wakeword_initialized_session = 0,
5151
.multi_turn_conversation_enabled = RT_TRUE,
5252
.tts_sentence_end_timer = RT_NULL,
53-
.tts_stop_workqueue = RT_NULL};
53+
.tts_stop_workqueue = RT_NULL,
54+
.pending_listen_start = RT_FALSE,
55+
.pending_play_wake_sound = RT_FALSE};
5456

5557
#include "ui/xiaozhi_ui.h"
5658
#include "iot/iot_c_api.h"
@@ -73,7 +75,11 @@ void xz_wakeword_detected_callback(const char *wake_word, float confidence)
7375
{
7476
LOG_D("Wake word detected during speaking - interrupting");
7577
xz_speaker(0);
76-
g_app.state = kDeviceStateIdle;
78+
rt_bool_t in_listening = (g_app.state == kDeviceStateListening) || xz_mic_is_enabled();
79+
if (!in_listening && g_app.state != kDeviceStateSpeaking)
80+
{
81+
g_app.state = kDeviceStateIdle;
82+
}
7783
}
7884
else if (g_app.state == kDeviceStateListening)
7985
{
@@ -90,6 +96,8 @@ void xz_wakeword_detected_callback(const char *wake_word, float confidence)
9096
LOG_D("Wake word detected but not connected, initiating connection...");
9197
xiaozhi_ui_chat_status(" 连接中");
9298
xiaozhi_ui_chat_output("正在连接...");
99+
g_app.pending_listen_start = RT_TRUE;
100+
g_app.pending_play_wake_sound = RT_FALSE;
93101
reconnect_websocket();
94102

95103
/* Use a shorter wait time with periodic checks for better responsiveness */
@@ -109,9 +117,24 @@ void xz_wakeword_detected_callback(const char *wake_word, float confidence)
109117
}
110118
}
111119

120+
/* Ensure session is ready before starting listening */
121+
if (g_app.ws.session_id[0] == '\0')
122+
{
123+
LOG_D("Session not ready after wake word detection, deferring listen start");
124+
g_app.pending_listen_start = RT_TRUE;
125+
g_app.pending_play_wake_sound = RT_FALSE;
126+
if (xz_wakeword_is_enabled())
127+
{
128+
xz_wakeword_stop();
129+
}
130+
return;
131+
}
132+
112133
/* Start listening mode */
113134
LOG_D("Starting conversation after wake word detection");
114135
g_app.state = kDeviceStateListening;
136+
g_app.pending_listen_start = RT_FALSE;
137+
g_app.pending_play_wake_sound = RT_FALSE;
115138

116139
/* Completely stop wake word detection during conversation to avoid mic0 conflict */
117140
if (xz_wakeword_is_enabled())
@@ -124,11 +147,24 @@ void xz_wakeword_detected_callback(const char *wake_word, float confidence)
124147
xz_mic(1);
125148

126149
/* Send listen start message to server */
127-
ws_send_listen_start(&g_app.ws.clnt, g_app.ws.session_id, kListeningModeAutoStop);
128-
129-
/* Update UI */
130-
xiaozhi_ui_chat_status(" 聆听中");
131-
xiaozhi_ui_chat_output("聆听中...");
150+
if (ws_send_listen_start(&g_app.ws.clnt, g_app.ws.session_id, kListeningModeAutoStop))
151+
{
152+
/* Update UI */
153+
xiaozhi_ui_chat_status(" 聆听中");
154+
xiaozhi_ui_chat_output("聆听中...");
155+
}
156+
else
157+
{
158+
LOG_W("Listen start failed after wake word detection");
159+
g_app.state = kDeviceStateIdle;
160+
xz_mic(0);
161+
xiaozhi_ui_chat_status(" 就绪");
162+
xiaozhi_ui_chat_output("就绪");
163+
if (!xz_wakeword_is_enabled())
164+
{
165+
xz_wakeword_start();
166+
}
167+
}
132168
}
133169

134170
/* TTS sentence end timeout handler */
@@ -349,6 +385,9 @@ void xz_event_thread_entry(void *param)
349385
{
350386
if (!g_app.ws.is_connected)
351387
{
388+
g_app.pending_listen_start = RT_TRUE;
389+
g_app.pending_play_wake_sound = RT_TRUE;
390+
352391
/* Check if reconnecting */
353392
if (g_app.websocket_reconnect_flag == 1)
354393
{
@@ -378,6 +417,9 @@ void xz_event_thread_entry(void *param)
378417
{
379418
LOG_D("Starting listening mode - press once to talk\n");
380419

420+
g_app.pending_listen_start = RT_FALSE;
421+
g_app.pending_play_wake_sound = RT_FALSE;
422+
381423
/* Play wake sound for button wake-up */
382424
xz_play_wake_sound();
383425

@@ -678,6 +720,9 @@ err_t my_wsapp_fn(int code, char *buf, size_t len)
678720
LOG_D("Stopped speaker due to disconnection\n");
679721
}
680722

723+
/* Ensure mic is closed when entering sleep */
724+
xz_mic(0);
725+
681726
/* Stop TTS sentence end timer if running */
682727
if (g_app.tts_sentence_end_timer)
683728
{
@@ -1032,7 +1077,11 @@ void Message_handle(const uint8_t *data, uint16_t len)
10321077
g_app.ws.sample_rate = cJSON_GetObjectItem(audio_param, "sample_rate")->valueint;
10331078
g_app.ws.frame_duration = cJSON_GetObjectItem(audio_param, "frame_duration")->valueint;
10341079
strncpy(g_app.ws.session_id, session_id, 9);
1035-
g_app.state = kDeviceStateIdle;
1080+
rt_bool_t in_listening = (g_app.state == kDeviceStateListening) || xz_mic_is_enabled();
1081+
if (!in_listening && g_app.state != kDeviceStateSpeaking)
1082+
{
1083+
g_app.state = kDeviceStateIdle;
1084+
}
10361085
xz_ws_audio_init();
10371086

10381087
/* Initialize only on first connection */
@@ -1051,26 +1100,38 @@ void Message_handle(const uint8_t *data, uint16_t len)
10511100
/* Resend device info after each reconnect */
10521101
send_iot_descriptors();
10531102
send_iot_states();
1054-
xiaozhi_ui_chat_status(" 待命中");
1055-
xiaozhi_ui_chat_output(" ");
1056-
xiaozhi_ui_update_emoji("neutral");
1057-
LOG_I("Waiting...\n");
1103+
rt_bool_t pending_listen = g_app.pending_listen_start;
1104+
if (!pending_listen && !in_listening)
1105+
{
1106+
xiaozhi_ui_chat_status(" 待命中");
1107+
xiaozhi_ui_chat_output(" ");
1108+
xiaozhi_ui_update_emoji("neutral");
1109+
LOG_I("Waiting...\n");
1110+
}
1111+
else
1112+
{
1113+
LOG_I("Pending wake-up detected on hello, preparing to listen\n");
1114+
}
10581115

10591116
/* Initialize wake word detection once */
10601117
if (!g_app.wakeword_initialized_session)
10611118
{
10621119
LOG_I("Initializing wake word detection...");
10631120
if (xz_wakeword_init() == 0)
10641121
{
1065-
/* Start detection after initialization - it should run continuously */
1066-
if (xz_wakeword_start() == 0)
1067-
{
1068-
LOG_D("Wake word detection started successfully");
1069-
g_app.wakeword_initialized_session = 1;
1070-
}
1071-
else
1122+
g_app.wakeword_initialized_session = 1;
1123+
1124+
/* Start detection only if no pending listen */
1125+
if (!pending_listen && !in_listening)
10721126
{
1073-
LOG_E("Failed to start wake word detection");
1127+
if (xz_wakeword_start() == 0)
1128+
{
1129+
LOG_D("Wake word detection started successfully");
1130+
}
1131+
else
1132+
{
1133+
LOG_E("Failed to start wake word detection");
1134+
}
10741135
}
10751136
}
10761137
else
@@ -1080,16 +1141,72 @@ void Message_handle(const uint8_t *data, uint16_t len)
10801141
}
10811142
else
10821143
{
1083-
/* Just ensure wake word is running */
1084-
if (!xz_wakeword_is_enabled())
1144+
if (pending_listen)
10851145
{
1086-
LOG_D("Restarting wake word detection");
1087-
xz_wakeword_start();
1146+
if (xz_wakeword_is_enabled())
1147+
{
1148+
LOG_D("Stopping wake word detection before pending listen start");
1149+
xz_wakeword_stop();
1150+
}
1151+
}
1152+
else
1153+
{
1154+
/* Just ensure wake word is running */
1155+
if (!xz_wakeword_is_enabled() && !in_listening)
1156+
{
1157+
LOG_D("Restarting wake word detection");
1158+
xz_wakeword_start();
1159+
}
1160+
}
1161+
}
1162+
1163+
if (pending_listen)
1164+
{
1165+
if (g_app.state == kDeviceStateListening || g_app.state == kDeviceStateSpeaking)
1166+
{
1167+
g_app.pending_listen_start = RT_FALSE;
1168+
g_app.pending_play_wake_sound = RT_FALSE;
1169+
return;
1170+
}
1171+
1172+
g_app.pending_listen_start = RT_FALSE;
1173+
1174+
if (g_app.pending_play_wake_sound)
1175+
{
1176+
xz_play_wake_sound();
1177+
}
1178+
g_app.pending_play_wake_sound = RT_FALSE;
1179+
1180+
if (xz_wakeword_is_enabled())
1181+
{
1182+
xz_wakeword_stop();
1183+
}
1184+
1185+
g_app.state = kDeviceStateListening;
1186+
xz_mic(1);
1187+
if (ws_send_listen_start(&g_app.ws.clnt, g_app.ws.session_id, kListeningModeAutoStop))
1188+
{
1189+
xiaozhi_ui_chat_status(" 聆听中");
1190+
xiaozhi_ui_chat_output("聆听中...");
1191+
}
1192+
else
1193+
{
1194+
LOG_W("Listen start failed after hello, falling back to idle");
1195+
g_app.state = kDeviceStateIdle;
1196+
xz_mic(0);
1197+
xiaozhi_ui_chat_status(" 就绪");
1198+
xiaozhi_ui_chat_output("就绪");
1199+
if (!xz_wakeword_is_enabled())
1200+
{
1201+
xz_wakeword_start();
1202+
}
10881203
}
10891204
}
10901205
}
10911206
else if (strcmp(type, "goodbye") == 0)
10921207
{
1208+
/* Ensure mic is closed when entering sleep */
1209+
xz_mic(0);
10931210
xiaozhi_ui_chat_status(" 休眠中");
10941211
xiaozhi_ui_chat_output("等待唤醒");
10951212
xiaozhi_ui_update_emoji("sleepy");

projects/Edgi_Talk_M55_XiaoZhi/applications/xiaozhi/xiaozhi.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,8 @@ typedef struct
126126
rt_bool_t multi_turn_conversation_enabled; /* 多轮对话开关 */
127127
rt_timer_t tts_sentence_end_timer; /* TTS句子结束定时器 */
128128
struct rt_workqueue *tts_stop_workqueue; /* TTS停止工作队列 */
129+
rt_bool_t pending_listen_start; /* 连接完成后自动进入聆听 */
130+
rt_bool_t pending_play_wake_sound; /* 连接完成后是否播放唤醒音 */
129131
} xiaozhi_app_t;
130132

131133
extern enum DeviceState g_state;

0 commit comments

Comments
 (0)