一次播放15个音轨,延迟<50毫秒?

时间:2015-08-13 15:24:13

标签: c audio mp3 opus vorbis

总结一下,我的问题是:是否可以同时解码和播放15个有损耗压缩的音轨,延迟时间不到50毫秒且没有卡顿?

背景

我在简单的C中为我正在制作的游戏编写声音库。我希望一次播放多达15个音轨,延迟时间不到50毫秒。

截至目前,该库能够播放原始PCM文件(48000Hz打包的16位样本),并且可以在45ms延迟时轻松播放15种声音而不会出现断断续续且CPU使用率最低。这是我相对较旧的英特尔Q9300 + SSD机器。

由于原始音频文件很大,我扩充了我的库以支持使用opusfile(https://mf4.xiph.org/jenkins/view/opus/job/opusfile-unix/ws/doc/html/index.html)播放OPUS文件。我希望我能够一次播放15个声音,而音频文件不会占用200MB +。我有多错 - 在我听到口吃和其他缓冲区欠载症状之前,我只能一次播放3或4个OPUS音轨。与原始PCM播放相比,CPU使用量也大幅增加。

我还尝试使用vorbisfile(http://www.xiph.org/vorbis/doc/vorbisfile/)来支持VORBIS支持。我想也许在运行中解码VORBIS不会像CPU一样密集。 VORBIS比OPUS好一点 - 我可以在口吃变得可听之前一次播放5或6个声音(我猜VORBIS确实更容易解码) - 但这仍然远不如播放原始PCM文件那么好。

在深入研究低级libvorbis / libopus API并研究其他音频压缩格式之前,实际上是否可以在50ms延迟时间内同时解码和播放15个有损耗压缩的音轨在中低端桌面计算机上没有卡顿?

如果有帮助,我的声音库目前大约每15ms调用一次函数,基本上会执行以下操作(为清晰起见,省略了错误处理和后处理):

void onBufferUpdateNeeded(int numSounds, struct Sound *sounds,
    uint16_t *bufferToUpdate, int numSamplesNeeded, uint16_t *tmpBuffer) {
    int i, j;
    memset(bufferToUpdate, 0, numSamplesNeeded * sizeof(uint16_t));
    for (i = 0; i < numSounds; ++i) {
        /* Seek to the specified sample number in the already-opened
        file handle. The implementation of this depends on the file
        type (vorbis, opus, raw PCM). */
        seekToSample(sounds[i].fileHandle, sounds[i].currentSample);

        /* Read numSamplesNeeded samples from the file handle into
        tmpBuffer. */
        readSamples(tmpBuffer, sounds[i].fileHandle, numSamplesNeeded);

        /* Add the samples into the buffer. */
        for (j = 0; j < numSamplesNeeded; ++j) {
            bufferToUpdate[j] += tmpBuffer[j];
        }
    }
}

提前感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

听起来你已经知道了自己问题的答案: NO。通常情况下,我对这些问题(特别是与性能相关的查询)提出的唯一建议是尝试并查找如果可能的话。但是你已经收集了这些数据。

对于解码而言,感知/有损音频编解码器往往是计算密集型的。听起来你想避免原始PCM的存储开销。在这种情况下,如果您可以安全地假设您已为应用程序保留了足够的内存,则可以提前解码音频流,或使用一些缓存机制来处理内存限制。也许这可以卸载到不同的线程(因为你问题中提到的Q9300 CPU是双核的)。

否则,您将需要寻找具有较低计算要求的压缩器。您可能对FLAC感兴趣,由与Vorbis和Opus相同的组织赞助。它没有损失,所以它不会像有损算法一样压缩,但解码速度应该快得多。

如果仍然不合适,请浏览this big list of ~150 audio codecs,直到找到符合您标准的标准。由于您控制客户端软件,因此您有很多选择(例如,流式传输到Web浏览器)。