2

总而言之,我的问题是:是否可以同时解码和播放 15 个有损压缩的音轨,延迟时间低于 50 毫秒且没有卡顿?

背景

我正在为我正在创建的游戏用纯 C 语言编写声音库。我希望一次播放多达 15 个音轨,延迟小于 50 毫秒。

截至目前,该库能够播放原始 PCM 文件(48000Hz 压缩的 16 位样本),并且可以轻松地以 45 毫秒的延迟一次播放 15 种声音,而不会出现卡顿且 CPU 使用率最低。这是在我相对较旧的 Intel Q9300 + SSD 机器上。

由于原始音频文件很大,我扩充了我的库以支持使用 opusfile 播放 OPUS 文件(https://mf4.xiph.org/jenkins/view/opus/job/opusfile-unix/ws/doc/html/index .html)。我希望我仍然能够一次播放 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 并研究其他音频压缩格式之前,是否可以同时解码和播放 15 个有损压缩的音轨,延迟低于 50 毫秒且没有卡顿在中低端台式电脑上?

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

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];
        }
    }
}

提前感谢您的帮助!

4

1 回答 1

0

听起来您已经知道自己问题的答案:不。通常,我对此类问题(尤其是与性能相关的查询)的唯一建议是尝试一下,看看是否可行。但是您已经收集了这些数据。

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

否则,您将需要寻找计算要求较低的压缩器。您可能对由与 Vorbis 和 Opus 相同的组织赞助的FLAC感兴趣。它是无损的,因此它的压缩效果不如有损算法,但解码速度应该快得多。

如果这仍然不合适,请浏览这个大约 150 个音频编解码器的大列表,直到找到符合您标准的一个。由于您控制客户端软件,因此您有很多选择(与例如流式传输到 Web 浏览器相比)。

于 2015-08-14T21:11:55.233 回答