diff --git a/ql-application/threadx/interface/custom_app/ws_talkingq.c b/ql-application/threadx/interface/custom_app/ws_talkingq.c index 6eb3f15..a1f0e4f 100644 --- a/ql-application/threadx/interface/custom_app/ws_talkingq.c +++ b/ql-application/threadx/interface/custom_app/ws_talkingq.c @@ -49,11 +49,14 @@ static uint8_t sender_buf[PCM_FRAME_LENGTH]={0}; static int16 mp3_buff[2*PCM_FRAME_LENGTH]; static int16 *ppbuff=mp3_buff; -static int onmessage_status = -1; -volatile int tts_playing = 0; -unsigned char wss_connect_start = 0; +static int onmessage_status = -1; +volatile int tts_playing = 0; +unsigned char wss_connect_start = 0; static volatile int player_mq_couter = 0; -static unsigned char audio_in_task_cancel = 0; +/* Set while a barge-in prompt bridges the old and new sessions. The old + * server response can still deliver URLs after its player queue was cleared. */ +static volatile int barge_in_transition = 0; +static unsigned char audio_in_task_cancel = 0; static unsigned char xiaoice_wss_connect_status = 0; static unsigned char wss_connect_counter = 0; @@ -299,6 +302,14 @@ static void onmessage_text(rws_socket socket, const char *text, const unsigned i return; } + /* The new session id is generated only when recording starts. Until + * then, every TTS message on this socket belongs to the interrupted + * session and must not be allowed to refill the cleared player queue. */ + if (barge_in_transition) { + printf("drop stale websocket message during barge-in\r\n"); + return; + } + // printf("message(txt), %d(byte): %s ", len, text); char url_buff[128]={0x00}; @@ -743,9 +754,12 @@ void generateSessionId(void) #if 1 -void sendStartPacket(void) { - generateSessionId(); - generateDeviceId(); +void sendStartPacket(void) { + generateSessionId(); + /* sessionId now identifies the new conversation. Late URLs from the old + * conversation will fail the existing session-id check below. */ + barge_in_transition = 0; + generateDeviceId(); gSequenceNumber = 0; AudioPacket startPacket = {0}; @@ -1021,7 +1035,8 @@ int tts_play_interrupt_func(void) * is only a cancellation signal for the old player; it must not leak into * the next conversation, otherwise prompts and error audio are discarded. */ playback_interrupted = (tts_playing != 0 || player_mq_couter > 0); - xiaoice_close_all_audio(); + barge_in_transition = playback_interrupted; + xiaoice_close_all_audio(); talkingq_ws_connect(); @@ -1029,6 +1044,7 @@ int tts_play_interrupt_func(void) /* Let the caller play its local network-error prompt. */ tts_play_status = 0; tts_playing = 0; + barge_in_transition = 0; g_mic_working = 0; return -2; }