在iOS上一次可以播放多少个声音 - AVAudioPlayer vs. AVAudioEngine & AVAudioPlayerNode。

问题描述 投票:0回答:1

我有一个应用程序,其中有一组约50个声音,长度范围从约300毫秒到约4秒。各种声音的组合需要在精确的时间播放(最多可以一次触发10个)。一些声音需要重复的时间间隔短至100毫秒。

我已经实现了这是一个二维的AVAudioPlayers数组,所有的声音都在应用程序启动时加载。每个声音有几个播放器,以适应快速重复的声音。一个特定的声音的播放器是严格轮流重复使用的。当一个新的声音被调度时,该声音的最老的播放器被停止,它的当前时间被设置为0,所以声音将从开始重复,下一次它的调度使用player.play(atTime:)。有一个线程,调度新的声音集约300毫秒之前,他们要播放。

这一切都很好,直到一个点,随着设备的变化。最终,由于声音播放更快,或更多的同时声音被安排,一些声音将拒绝播放。

我正在考虑切换到AVAudioEngine和AVAudioPlayerNodes,使用混音器节点。有谁知道这种方法是否可能处理更多的同时声音?我的猜测是,这两种方法都转化为一套相当相似的CoreAudio函数,但我还没有真正写出代码来测试这个假设--在我这样做之前,我希望有人可能在我之前探讨过这个问题。我之前一直在深入研究CoreAudio,我希望能够使用这些方便的高级函数来代替!我希望能够在这个问题上有所突破。

另外,有谁知道当一个声音启动时触发闭合的方法吗?文档中的功能允许回调关闭,但我能够在声音启动时触发事件的唯一方法是为DispatchQueue创建一个高质量的服务队列。遗憾的是,根据系统负载,排队事件的执行时间可能会与计划时间相差50毫秒左右,这并不像我所希望的那样精确。

ios swift avaudioplayer avaudioplayernode
1个回答
0
投票

使用AVAudioEngine与AVAudioPlayersNodes提供了更好的性能,尽管代价是代码有点复杂。我能够轻松地将播放速率提高五倍,并且有更好的缓冲区控制。

改用这种方法的主要缺点是苹果的文档不那么优秀。苹果的文档中增加一些内容,会让这个任务变得更加简单。

混音器节点被记录为可以转换采样率和通道数,所以我尝试配置audioEngine.mainMixerNode来转换单声道缓冲区到输出节点的设置。将主混音器节点的输出设置为输出节点的格式似乎被接受,但在运行时抛出不透明的错误,抱怨通道数不匹配。

看来,主混音器节点实际上并不是一个功能齐全的混音器节点。为了让它工作,我不得不插入另一个执行通道转换的混音器节点,并将其连接到主混音器节点。如果苹果的文档中真的提到了这一点,那我就可以省去很多实验了。

另外,仅仅调度一个缓冲区并不会导致任何播放。你需要在播放器节点上调用play()才会发生任何事情。苹果的文档在这里很混乱--它说在没有参数的情况下调用play()会导致播放立即发生,这不是我想要的。经过一些实验,才确定play()只是告诉播放器节点唤醒,而预定的缓冲区实际上会在预定的时间播放,而不是立即播放。

如果Apple能提供比自动生成的类文档更多的信息,那将会有很大的帮助。人工生成的文档会让我省去很多令人沮丧的实验。

Chris Adamson写得很好的 "学习核心音频 "在我使用核心音频时非常有帮助--很遗憾,新的AVAudioEngine功能没有被记录得那么好。

© www.soinside.com 2019 - 2024. All rights reserved.