好的,我尝试了各种各样的游戏,但都失败了(所以如果有人想出一个更好的游戏,请随时编辑:P)
我遇到以下问题:我使用API来访问我没有编码的硬件,将库添加到我需要从API接口继承的API,并且API可以完成所有操作。
我输入了那个API,一个音乐生成器库,问题是所提到的API只在缓冲区为空时调用音乐库,并要求提供硬编码的数据量(正好是1024 * 16个样本... dunno原因)。
这意味着音乐生成器库,不能使用所有的CPU潜力,在播放音乐时,即使音乐库没有跟上,CPU的使用率仍然很低(如3%),所以在部分音乐中有太复杂的东西,缓冲区欠载(即:声卡播放缓冲区中为空的区域,因为音乐库功能尚未返回)。
调整硬编码的数字只会使软件在某些机器上运行,而在其他机器上不起作用,这取决于几个因素......
所以我提出了两个解决方案:使用一些新的缓冲逻辑来破解API,但我没有想到该领域的任何内容。
或者我实际想出逻辑的那个:让音乐库有自己的线程,当API调用音乐库获取更多数据时,它会有自己独立的缓冲区,而不是生成时,它会将数据从单独的缓冲区中明确地复制到声卡缓冲区,然后继续生成音乐。
我的问题是虽然我有几年的编程经验,但我总是避免使用多线程,我甚至不知道从哪里开始......
问题是:有人可以找到另一个解决方案吗,或者将我指向一个可以提供有关如何实施我的线程解决方案的信息的地方?
编辑:
我没有阅读文件,我正在生成或计算音乐,得到了它?这不是.wav或.ogg库。这就是为什么我提到CPU时间,如果我可以使用100%CPU,我永远不会得到一个欠载,但我只能在程序之间的短时间内使用CPU实现缓冲区到达结束,并且实际结束缓冲区,这个时间有时小于程序计算音乐所用的时间。
答案 0 :(得分:2)
我相信具有单独线程的解决方案将为库准备数据,以便在请求时就绪,这是减少延迟并解决此问题的最佳方法。一个线程生成音乐数据并将其存储在缓冲区中,API线程在需要时从该缓冲区获取数据。在这种情况下,您需要同步访问缓冲区,无论您是在读还是写,并确保在API太慢的情况下没有太大的缓冲区。要实现这一点,您需要来自线程库的线程,互斥和条件原语以及两个标志 - 一个用于指示何时请求停止,另一个用于请求线程暂停填充缓冲区(如果API无法跟上并且它变得太大)。我建议在C ++中使用Boost Thread库,这里有一些有用的文章可以想到:
答案 1 :(得分:0)
您不一定需要新线程来解决此问题。您的操作系统可能提供异步读取操作;例如,在Windows上,您将使用FILE_FLAG_OVERLAPPED打开该文件,以使其上的任何操作异步。
如果您的操作系统支持此功能,您可以创建一个可以容纳少量数据调用的大缓冲区。当应用程序启动时,您填充缓冲区,然后填充后,您可以将缓冲区的第一部分传递给API。当API返回时,您可以读入更多数据来覆盖上次API调用所消耗的缓冲区部分。因为读取是异步的,所以它将在API播放音乐时填充缓冲区。
实现可能比这更复杂,即使用循环缓冲区或等待几个部分被消耗,然后一次读取多个部分,而不是一次读取一个部分。