0

好的,我尝试了各种标题,但都失败了(所以如果有人想出更好的标题,请随时编辑:P)

我有以下问题:我正在使用 API 来访问我没有编码的硬件,将库添加到我需要从 API 接口继承的 API 中,并且 API 可以完成所有工作。

我输入了那个 API,一个音乐生成器库,问题是提到的 API 只在缓冲区为空时调用音乐库,并要求硬编码的数据量(正好 1024*16 个样本......不知道为什么)。

这意味着音乐生成器库,无法使用所有 CPU 潜力,在播放音乐时,即使音乐库跟不上,CPU 使用率仍然很低(如 3%),因此在部分音乐中也有复杂的东西,缓冲区不足(即:声卡播放缓冲区中空的区域,因为音乐库函数尚未返回)。

调整硬编码的数字,只会使软件在某些机器上工作,而不是在其他机器上工作,这取决于几个因素......

所以我想出了两个解决方案: 用一些新的缓冲区逻辑来破解 API,但我在这方面没有想到任何东西。

或者是我真正想到的逻辑:让音乐库有自己的线程,它将有自己的独立缓冲区,它会一直填充,当 API 调用音乐库获取更多数据时,而不是生成,它会将数据从那个单独的缓冲区复制到声卡缓冲区,然后继续生成音乐。

我的问题是,虽然我有几年的编程经验,但我总是避免多线程,我什至不知道从哪里开始......

问题是:有人可以找到另一种解决方案,或者将我指向一个可以为我提供有关如何实施我的线程解决方案的信息的地方吗?

编辑:

我不是在阅读文件,而是在生成或计算音乐,明白吗?这不是 .wav 或 .ogg 库。这就是为什么我提到 CPU 时间,如果我可以使用 100% CPU,我将永远不会出现欠载,但我只能在程序意识到缓冲区即将结束和实际结束之间的短时间内使用 CPU缓冲区,这个时间有时小于程序计算音乐所用的时间。

4

2 回答 2

2

我相信具有单独线程的解决方案将为库准备数据以便在请求时准备好它是减少延迟和解决此问题的最佳方法。一个线程生成音乐数据并将其存储在缓冲区中,API 线程在需要时从该缓冲区获取数据。在这种情况下,无论您是读取还是写入,您都需要同步对缓冲区的访问,并确保在 API 太慢的情况下您没有太大的缓冲区。要实现这一点,您需要线程库中的一个线程、互斥体和条件原语以及两个标志 - 一个指示何时请求停止,另一个指示如果 API 无法跟上并且它变得太大,则要求线程暂停填充缓冲区。我建议使用 C++ 的 Boost Thread 库,

于 2010-08-05T20:42:11.593 回答
0

你不一定需要一个新线程来解决这个问题。您的操作系统可能会提供异步读取操作;例如,在 Windows 上,您将使用 FILE_FLAG_OVERLAPPED 打开文件以对其进行异步操作。

如果您的操作系统确实支持此功能,您可以创建一个可以容纳几个调用数据的大缓冲区。当应用程序启动时,您填充缓冲区,然后一旦它被填充,您就可以将缓冲区的第一部分传递给 API。当 API 返回时,您可以读入更多数据以覆盖上次 API 调用使用的缓冲区部分。因为读取是异步的,所以它会在 API 播放音乐时填充缓冲区。

实现可能比这更复杂,即使用循环缓冲区或等到几个部分已被消耗,然后一次读取多个部分,而不是一次读取一个部分。

于 2010-08-05T21:38:08.970 回答