【CI130x 离在线】语音芯片如何判断TTS音频播放完毕?
这个函数通过以下几个条件来综合判定TTS播放结束:
主要判定逻辑:
1. 缓冲区数据检查
#if NET_AUDIO_PLAY_BY_MP3
if (xStreamBufferBytesAvailable(mp3_player) == 0) // 播放完成
#elif NET_AUDIO_PLAY_BY_PCM || NET_AUDIO_PLAY_BY_OPUS
if (xStreamBufferBytesAvailable(gCiasAiotRunParam.pcm_play_data_stream_buffer) < 512)
#endif
-
MP3模式:缓冲区完全为空
-
PCM/OPUS模式:缓冲区数据少于512字节
2. 结束标志与重试次数组合判断
情况A - 有结束标志时:
if (gCiasAiotRunParam.play_cloud_end_flag)
{
if (gCiasAiotRunParam.request_play_try_count >= 10)
{
ret = true;
}
}
收到云端结束标志后,再重试10次(约1秒)确认真实结束
情况B - 无结束标志时:
else if (gCiasAiotRunParam.request_play_try_count >= 30)
{
ret = true;
}
未收到结束标志时,重试30次(约3秒)后强制结束
3. 播放结束后的清理操作
当判定播放结束后,执行:
-
设置播放状态为闲置(
CI_SS_PLAY_STATE_IDLE) -
开启VOX语音检测
-
重置所有相关标志位
-
停止编解码器
-
等待播放完全停止(最多300ms)
-
发送
PLAY_TTS_END命令
总结:
判定播放结束的核心是缓冲区数据基本耗尽 + 适当的重试等待,通过组合云端结束标志和本地缓冲区状态来确保播放真正完成,避免提前或延迟结束。
完整代码
#if NET_AUDIO_PLAY_BY_MP3
if (xStreamBufferBytesAvailable(mp3_player) == 0) // 播放完成
#elif NET_AUDIO_PLAY_BY_PCM || NET_AUDIO_PLAY_BY_OPUS
if (xStreamBufferBytesAvailable(gCiasAiotRunParam.pcm_play_data_stream_buffer) < 512)
#endif
{
if (gCiasAiotRunParam.play_cloud_end_flag)
{
if (gCiasAiotRunParam.request_play_try_count >= 10)
{
ret = true;
}
}
else if (gCiasAiotRunParam.request_play_try_count >= 30)
{
ret = true;
}
if (ret)
{
mprintf("play stop sync state to wifi ....\r\n");
ret = false;
ciss_set(CI_SS_PLAY_STATE, CI_SS_PLAY_STATE_IDLE); // 设置播放结束
if (!gCiasAiotFuncParam.upload_play_full_duplex)
{
ciss_set(CI_SS_VOX_WORK_STATE, 1); // 开启vox vad计算
}
gCiasAiotRunParam.request_play_try_count = 0;
gCiasAiotRunParam.play_cloud_data_flag = false;
gCiasAiotRunParam.request_play_data_flag = false;
gCiasAiotRunParam.wait_play_end_flag = false;
gCiasAiotRunParam.rcv_cloud_play_data_flag = false;
gCiasAiotRunParam.stop_collect_pcm_flag = false;
#if NET_AUDIO_PLAY_BY_MP3
stop_play(NULL, NULL); // 必须保留,不然下一段播放音频会保留上一段音频数据
#elif NET_AUDIO_PLAY_BY_PCM || NET_AUDIO_PLAY_BY_OPUS
cm_stop_codec(PLAY_CODEC_ID, CODEC_OUTPUT);
cm_set_codec_mute(PLAY_CODEC_ID, CODEC_OUTPUT, 3, DISABLE);
#endif
int try_count = 30;
while(try_count--) //等待播放状态同步完成
{
if(gCiasAiotRunParam.mp3_play_finish_flag)
{
break;
}
else
{
mprintf("===wait audio play over\r\n");
vTaskDelay(pdMS_TO_TICKS(10));
}
}
cias_send_cmd(PLAY_TTS_END, DEF_FILL);
}
gCiasAiotRunParam.request_play_try_count++;
}

浙公网安备 33010602011771号