总而言之,我的问题是:是否可以同时解码和播放 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];
}
}
}
提前感谢您的帮助!