fix(audio): recover cleanly after barge-in

This commit is contained in:
chenjintao
2026-09-22 17:50:42 +08:00
parent 1c9f16da39
commit 8b01debe4d
2 changed files with 34 additions and 9 deletions
@@ -187,6 +187,9 @@ static void key_thread_entry(void *parameter)
if(ql_rtos_get_systicks() - key_press_mic_time > KEY_LONG_PRESS_3S && power_down_status==0){
nfc_tx_click_count = 0;
power_down_status = 1;
/* Shutdown audio must own the codec. Stop VAD and any
* interrupted TTS before queueing the power-off prompt. */
stop_player_func();
app_play_tips_file(10);
power_down_status = 2;
//ql_rtos_task_sleep_s(3);
@@ -1001,26 +1001,40 @@ void app_player_thread(void *arvg)
int tts_play_interrupt_func(void)
{
int playback_interrupted = 0;
//如果在vad状态,则直接返回
if(vad_audio_is_recording()||g_mic_working) return -1;
g_mic_working = 1;//等待转为vad状态就清0 或者拾音超时 或者ws没有正常
/* Remember whether this key press is interrupting TTS. tts_playing == 2
* 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();
talkingq_ws_connect();
if(get_xiaoice_connected_status()!=2) {
g_mic_working = 0;
return -2;
}
if(tts_playing==2){
if(get_xiaoice_connected_status()!=2) {
/* Let the caller play its local network-error prompt. */
tts_play_status = 0;
tts_playing = 0;
g_mic_working = 0;
return -2;
}
if(playback_interrupted){
printf("vad_start_func0\n");
/* The old player has finished consuming the cancellation state. */
tts_play_status = 0;
tts_playing = 0;
vad_start_func();//如果是打断就不播报
}else{
app_play_tips_file(18);
}
return 0;
}
void stop_player_func(void)
@@ -1028,6 +1042,7 @@ void stop_player_func(void)
vad_audio_stop_record();
xiaoice_close_all_audio();
tts_play_status = 0;
tts_playing = 0;
}
@@ -1194,9 +1209,16 @@ void xiaoice_close_all_audio(void)
timeout = hal_os_up_time_ms();
while(tts_play_status&&tts_playing!=2){
/* The queue counter also includes the item currently owned by the
* player task. Wait for that item to observe tts_playing == 2 and
* finish cleanup before the cancellation state is reused/reset. */
while(player_mq_couter>0){
ql_rtos_task_sleep_ms(20);
if(hal_os_up_time_ms()-timeout>10000) break;
if(hal_os_up_time_ms()-timeout>OTA_AUDIO_STOP_TIMEOUT_MS){
printf("wait player stop timeout, counter:%d\r\n",
player_mq_couter);
break;
}
}
}
#endif