在 XAudio2 中调试音频故障

XAudio2 中可能会出现故障,本主题介绍了如何报告它们以及修复这些故障的一些方法。

本概述涵盖以下主题:

音频输出问题或故障的原因

由于多种原因,XAudio2 输出中可能会出现故障。

  • XAudio2 源语音已耗尽。 客户端提交新音频的速度不够快。 你会保持沉默,因为它没有要播放的数据。
  • XAudio2 作为一个整体是负担过重的。 生成 X 毫秒音频所需的时间比 X 毫秒长。 你会收到辍学,因为 XAudio2 无法像音频设备需要的那样快地生成数据。 你可能一次运行过多的语音或效果、在 XAudio2 回调中执行过多的工作,或过于频繁地调用 XAudio2 API。
  • 音频处理线程停止,因为客户端实现某些 XAudio2 回调会阻止线程。 例如,它可能正在访问磁盘、与其他线程同步,或者调用可能阻止的其他函数。 使用回调可以发出信号的低优先级后台线程来执行此类任务。
  • 整个系统过载。 以与 XAudio2 相同或更高的优先级运行的其他线程执行的工作过多。 它们正在与音频线程争夺 CPU 时间。

XAudio2 如何报告问题

XAudio2 可以通过多种方式传达调试版本中的故障。

  • 如果某个语音被耗尽,XAudio2 将在此窗体中显示一条消息。

    XAudio2: WARNING: Voice at 0xNNNNNNNN starved: no more source buffers are available, but no end-of-stream marker was received
    
  • 如果音频线程运行时间过长,XAudio2 将显示此格式的消息。

    XAudio2: WARNING: Spent Xms in audio thread; XAudio2 possibly overloaded
    

    通常,此消息与下一条消息一起发生。

  • 如果无法按时向音频驱动程序提供新的音频数据,XAudio2 将在此窗体中显示一条消息。

    XAudio2: WARNING: Glitch at output sample X
    
  • 调用 IXAudio2::GetPerformanceData 可提供 XAudio2 性能数据,包括自 XAudio2 引擎启动以来的故障总数。

解决问题的方法

减少音频故障的可能方法包括:

  • 在语音不足的情况下:增加在语音上排队的音频数据量。 可以使用 IXAudio2SourceVoice::GetState 发现随时排队的缓冲区数。 如果仍然看到语音饥饿错误,但听不到任何故障,请确保设置 XAUDIO2_BUFFER在声音 的最终缓冲区上XAUDIO2_END_OF_STREAM标志。 这告诉 XAudio2 不要期望在此缓冲区完成后立即可用。

    在其他情况下:

    • 减少图形中的活动语音和效果的数量,尤其是混响等昂贵效果。
    • 禁用不使用的语音和效果。
    • 尽可能在 IXAudio2::CreateSourceVoice 中使用XAUDIO2_VOICE_NOSRC和XAUDIO2_VOICE_NOPITCH标志。 采样率转换成本高昂。
    • 降低单个语音的采样率。 例如,承载混响效果的子混合语音的采样率可能低于向其发送的源语音。 不需要高保真度的声音(如爆炸和枪声)也可以以较低的采样率进行录制。
    • 确保回调实现尽可能少地执行工作,并且从不阻塞。
    • 减少对 XAudio2 的调用。 通常不需要为每个视频帧更新音频参数。 每 30 毫秒左右就足够了。 应消除冗余调用,例如快速连续多次设置卷。
    • 减少游戏的整体 CPU 使用率。

调试工具

XAudio2 编程参考