3

简短版本:我正在开发一个合成器应用程序并使用低延迟的 Opensl。我在 Opensl 回调函数中进行所有音频计算(我知道我不应该,但我还是做了)。现在计算在我的 nexus 4 上花费了大约 75% 的 cpu 时间,所以下一步是在多个线程中进行所有计算。

我遇到的问题是音频开始结巴,因为回调线程显然以高优先级运行,而我的新线程却没有。如果我使用更多/更大的缓冲区,问题就会消失,但实时也是如此。在新线程上设置更高的优先级似乎不起作用。那么,甚至有可能做线程化的低延迟音频,还是我必须在回调中做所有事情才能让它工作?

我有一个包含 256 个样本的缓冲区,大约需要 5 毫秒,这应该是线程调度程序运行我的计算线程的时间。

4

1 回答 1

2

我认为根本问题在于合成引擎的性能。使用 Cortex-A8 或 -A9 CPU 可以通过单核实现不错的通道数。你用什么语言实现的?如果它恰好是 Java,我建议将它移植到 C++。

使用多线程进行合成当然是可能的,但也带来了新的问题——即每个线程必须在生成的音频可以混合之前同步。

除非您因异步运行合成线程而受到额外的延迟影响,否则可能的设置是,在您的渲染回调中,您会向其他合成线程发出信号,然后等待它们完成,然后再混合来自他们都在一起。

(一个明显的优化是渲染回调运行一些处理本身,因为它已经在 CPU 上运行,否则什么都不做)。

问题就在这里。除非您可以确定您的合成器渲染线程以实时优先级运行,否则您可能会在每次渲染回调运行时受到调度命中,如果您阻塞回调线程等待合成渲染线程赶上,则可能会再次受到调度命中。

上次我在 Android 上查看音频时,Bionic 缺乏设置实时线程优先级的方法(例如SCHED_FIFO)。无论如何,这是否被允许是操作系统策略的问题:在桌面 Linux 系统上,您要么需要是 root,要么已经调整了适当的ulimit(作为 root) - 我不确定 Android 在这里做了什么,但我非常很多人怀疑下载的应用程序默认情况下没有获得此权限。mlock()代码及其可能的堆栈需要进入物理内存的其他有用权限也不是。

于 2013-06-07T16:53:52.423 回答