2

我有一个浮点数组,它们表示基于一段时间内触发事件的时间值。

0: time stored: 1.68
1: time stored: 2.33
2: time stored: 2.47
3: time stored: 2.57
4: time stored: 2.68
5: time stored: 2.73
6: time stored: 2.83
7: time stored: 2.92
8: time stored: 2.98
9: time stored: 3.05

我现在想启动一个计时器,当计时器达到 1 秒 687 毫秒(数组中的第一个位置)时,触发事件/方法执行。并且当计时器达到 2 秒和 337 毫秒以触发第二个方法执行时,直到数组中的最后一个元素在 3 秒和 56 毫秒时触发最后一个事件。

我怎么能模仿这样的东西?我需要高精度的东西

我想我本质上要问的是如何创建一个具有高精度方法调用的节拍器来按时播放声音?

4

3 回答 3

4

…如何创建具有高精度方法调用的节拍器以按时播放声音?

您将使用音频时钟,它具有您通常想要的所有精度(音频播放的采样率 - 例如 44.1kHz) - 而不是NSTimer.

具体来说,您可以使用采样器(例如 AudioUnit)并安排 MIDI 事件,或者您可以在由节奏确定的样本位置处的音频流回调中使用(预加载的)点击声音的样本数据填充缓冲区。

为了保持 1 毫秒或更好,您需要始终将您的时间设置为基于音频时钟。这真的很容易,因为您的速度将决定帧的间隔。

如果您以前没有在该领域工作过,那么困难的部分(对于大多数人来说)是习惯于在实时环境中工作并使用音频框架。

于 2012-04-21T07:17:29.917 回答
2

调查dispatch_after()。你可以使用类似的东西为它创建一个目标时间dispatch_time(DISPATCH_TIME_NOW, 1.687000 * NSEC_PER_SEC)


更新:如果您只想在特定时间播放声音,而不是做任意工作,那么您应该使用允许您在特定时间安排播放的音频 API。我最熟悉Audio Queue API。您将创建一个队列并创建 2 或 3 个缓冲区。(如果音频始终相同,则为 2。如果您动态加载或计算它,则为 3。)然后,您将使用AudioQueueEnqueueBufferWithParameters()特定的开始时间对每个缓冲区进行排队。然后,音频队列将负责播放尽可能接近请求的开始时间。我怀疑您是否会通过手动编写替代方案来超越其精度。当队列将处理过的缓冲区返回给您时,您可以在必要时重新填充它并在下一次将其排队。

我确信AVFoundation必须有类似的工具来安排在特定时间播放,但我不熟悉它。

于 2012-04-21T11:10:11.613 回答
2

要获得高精度的时序,您必须跳下一两个编程级别并使用诸如Core Audio Unit框架之类的东西,它提供样本精确的时序(在 44100kHz 时,样本应该每 0.02 毫秒左右发生一次)。

这种方法的缺点是为了获得这样的计时性能,Core Audio Unit 编程避开了 Objective-C 的 C/C++ 方法,在我看来,这比 Objective-C 更难编码。除此之外,Core Audio Units 的工作方式也很令人困惑,尤其是如果您没有音频 DSP 方面的背景。

留在 Objective-C 中,你可能知道 NSTimers 在这里不是一个选项。为什么不检查AVFoundation 框架?它可用于精确的媒体排序,并具有一些创造性的侧面思考,以及AVURLAssetAVURLAssetPreferPreciseDurationAndTimingKey的选项 ,您可能无需使用 Core Audio Units 即可实现您想要的。


只是为了填写更多 about AVFoundation,您可以将 的实例AVAsset放入AVMutableComposition(通过AVMutableCompositionTrack对象),然后使用AVPlayerItem带有AVPlayer实例的对象来控制结果。AVPlayerItem 通知AVPlayerItemDidPlayToEndTimeNotificationdocs)可用于确定单个资产何时完成,而 AVPlayer 方法addBoundaryTimeObserverForTimes:queue:usingBlock:可以addPeriodicTimeObserverForInterval:queue:usingBlock:在任意时间提供通知。

对于 iOS,如果您的应用程序将播放音频,您还可以让这一切在后台线程上运行,这意味着您可以在应用程序处于后台时保持时间(尽管警告,如果它不播放音频,Apple 可能会不接受您的应用使用此后台模式)。查看UIBackgroundModes 文档了解更多信息。

于 2012-04-21T07:34:54.737 回答