SDL 音频在 Linux 上随机失真

Posted

技术标签:

【中文标题】SDL 音频在 Linux 上随机失真【英文标题】:SDL audio randomly becomes distorted on Linux 【发布时间】:2019-09-08 00:17:04 【问题描述】:

我对 SDL 音频有一个奇怪的问题。它会随机变形。它完全是随机的,我根本无法可靠地复制它。有时它会在程序启动几秒钟后开始失真,有时我玩过该软件,让它运行一夜,它仍然会在早上工作。

这可能与 SDL 有关,因为我可以用Mix_CloseAudio() 关闭混音器,然后用Mix_OpenAudio() 重新打开它,它会修复声音......一段时间,有时很长一段时间,其他时候它很快就会搞砸。 (正如 Brad 在 cmets 中指出的那样,这并不一定意味着这是一个 SDL 问题。

关于系统的更多信息:

剥离了内核 2.6.27.5-117.fc10.i686 的 linux 系统。 libSDL_mixer-1.2.so.0.2.6.

这是一个在过去一直有效的旧系统,我对软件的音频系统部分没有做任何更改。该系统过去使用 CD-rom 运行,所有游戏资产都加载到文件系统覆盖层上的 ram 中,但我已将其切换为使用 CF 卡运行,而没有所有声音一直在 ram 中。我也没有对声音驱动程序进行任何更改。

这是一个声音失真的例子https://www.youtube.com/watch?v=zEneMi5mtt0 以下是相同声音正常运行的示例https://www.youtube.com/watch?v=nyPZLJ-9gsI

【问题讨论】:

你能发布一个失真声音的音频样本吗? 有没有办法用 SO 做到这一点?我不得不玩一会儿,直到它搞砸了,然后用我的手机记录下来。我想我总是可以把它放在 youtube 上。不过我很好奇,失真的类型能说明什么? 我不认为 Stack Overflow 对此有任何规定,但您始终可以链接到 Dropbox 或 Google Drive 链接或其他东西。失真的类型可以帮助区分许多不同的问题。例如,如果它恰好是规则的,则通常是采样率差异或缓冲区偏移问题。如果它是随机的,则通常是缓冲区不足的问题。位深度差异也有特征声音(如果播放模式发生变化,可能会发生这种情况)。各种东西。 谢谢,我会努力获取样本。你提到缓冲区不足,这就是为什么我提到关于内存中的所有内容与现在必须先从 cf 卡中加载它的原因。 声卡可能配置了非常小的缓冲区大小,因此即使平均 CPU 使用率很低,也很难跟上。另外,我不确定您关于它肯定与 SDL 相关的评论是否严格正确。我不知道您的系统是否是这种情况,但如果没有人使用它,声卡通常会停止。重新打开它可能实际上是在重新初始化硬件。 【参考方案1】:

根据您的声音得出的一些观察结果可用于调试问题:

您听到的失真是基于您的声音,是一系列有规律的咔嗒声。 如果音频很安静,则失真/咔嗒声很安静。同样,随着音频​​的响亮,问题会变得更糟。 音高正确,因此不是采样率问题。 一旦问题开始,它就是一致的。

基本上,发生的事情是声卡从循环缓冲区中读取的位置与写入它的软件认为的位置不同。在某些时候,缓冲区欠载导致播放磁头位于读取磁头前面。

应该发生的是,播放应该重置,导致音频暂时丢失,直到缓冲区再次满。似乎发生的事情是播放继续。因此,播放头不断在旧缓冲区数据和新缓冲区数据之间运行,从而导致点击。这也是为什么当声音更安静时,点击/失真更安静……两个 PCM 样本之间的差异更小。

我已经看到这种情况发生在有问题的声卡驱动程序和有问题的声卡上。要解决此问题,请找到增加缓冲区大小的方法。这会增加延迟,但可能有助于从一开始就防止问题发生。

【讨论】:

这是有道理的。 SDL 中的缓冲区大小是 1024,所以我会尝试将其增加到 2048。所以这可能与不总是在内存中的事情有关。这是一个具有较慢 1.5 GHz 处理器的旧系统(但它仍然赚钱)。它还在更新更快的主板上运行,虽然它使用不同的驱动程序,但我还没有看到它的声音混乱,但只是更快可能会奏效。 另请参阅 memcpy acts randomly (and differently) with overlapping areas 和 Strange sound on mp3 flash website 等错误报告,其中 Adob​​e 使用重叠缓冲区和 memcpy 而不是 memmove 正常运行程序时声音缓冲区加倍后,我没有任何声音失真。但是在启动时通过 GDB 运行时会失真。而且失真听起来不同,所以我认为你对缓冲区问题是正确的(因为 pcm 电平不匹配发生的频率是一半)。既然我知道了这个问题,我已经做了一些谷歌搜索,我已经看到建议将 SDL_Delay(1) 放在主循环中。这会让系统更加关注音频,避免潜在的缓冲区欠载吗?

以上是关于SDL 音频在 Linux 上随机失真的主要内容,如果未能解决你的问题,请参考以下文章

屏幕上带有标题的随机音频

如何在音频上添加随机 src

C++ 随机种子、全局对象和 SDL_Threads

在 Mac 上使用 OpenAL 播放音频时出现随机噪音

调用时不播放随机音频列表

创建新的随机音频文件时,播放随机音频 onClick 不会重置 - Android