当前位置: 首页 > news >正文

【CI130x 离在线】语音芯片如何判断TTS音频播放完毕?

这个函数通过以下几个条件来综合判定TTS播放结束:

主要判定逻辑:

1. 缓冲区数据检查

c
#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 - 有结束标志时:

c
if (gCiasAiotRunParam.play_cloud_end_flag)
{if (gCiasAiotRunParam.request_play_try_count >= 10){ret = true;}
}

收到云端结束标志后,再重试10次(约1秒)确认真实结束

情况B - 无结束标志时:

c
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_MP3if (xStreamBufferBytesAvailable(mp3_player) == 0) // 播放完成
#elif NET_AUDIO_PLAY_BY_PCM || NET_AUDIO_PLAY_BY_OPUSif (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_MP3stop_play(NULL, NULL); // 必须保留,不然下一段播放音频会保留上一段音频数据
#elif NET_AUDIO_PLAY_BY_PCM || NET_AUDIO_PLAY_BY_OPUScm_stop_codec(PLAY_CODEC_ID, CODEC_OUTPUT);cm_set_codec_mute(PLAY_CODEC_ID, CODEC_OUTPUT, 3, DISABLE);
#endifint 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++;}

 

http://www.jsqmd.com/news/24515/

相关文章:

  • 完整教程:Qt信号与槽在多线程编程中的应用与注意事项
  • 从 “短期达标” 到 “长期优化”:MyEMS 如何帮企业建立可持续的能源管理体系?
  • 四场比赛(三)
  • 使用DAST发现Android应用API中的AWS凭证泄露漏洞
  • 百航鹿大联训 Pwn篇
  • 开发stm32-配置vscode环境
  • iNeuOS工业互联网操作系统,增加工厂模型配置,继续深入业务
  • C++语法—类的声明和定义
  • 施工用电隐患 “无形侦探”!思通数科 AI 卫士自动排查用电违规
  • 基于C#的停车场管理系统实现
  • 为什么大型网站能“秒回”你的用户名?揭秘毫秒级响应背后的“守门人”艺术
  • 文件同步备份:为什么说“同步盘”是比“普通网盘”更高效、更安全的选择?
  • 连中五标,中电金信国际化服务助力企业出海
  • 1195. 交替打印字符串
  • gdb调试常用命令
  • 企业微信ipad协议实现聚合聊天系统、RPA机器人智能回复
  • 2025年市面上别墅石材品牌与行业内别墅石材源头厂家推荐榜单及口碑好的别墅石材产品分析
  • 最近公共祖先 (LCA)
  • ChatGPT API集成测试自动化框架的实践与成效汇报
  • [题解]【MX-S8】梦熊 CSP-S 2025 模拟赛
  • 2025四川碳晶板品牌
  • 详细介绍:求余运算和数学模运算的知识了解
  • 基于蚁群算法解决车辆路径问题(VRP)的MATLAB实现
  • 2025 年工业除湿机,恒温恒湿机,精密空调,除湿加湿一体机厂家最新推荐,产能、专利、环保三维数据透视
  • 从手动到全自动:我们如何用Dify重构了API回归测试流程
  • 2025 年管道除湿机,中央除湿机,新风除湿机,变频除湿机厂家最新推荐,产能、专利、环保三维数据透视
  • 2025年10月中国管理咨询公司推荐榜:五强数据对比
  • 条码识别插件 quaggaJS - microsoft
  • 2025年10月中国管理咨询公司推荐榜:金蓝盟领衔六强对比评测
  • 基于3GPP LTE标准的信道仿真模型