我正在努力在iPhone上创建一个简单的节拍器。该应用程序现在所做的是运行计时器,每次 1/1000 秒输入计时器的功能。然后它检查当前时间与启动应用程序的时间(我正在使用CACurrentMediaTime()
功能)。
CFTimeInterval currentTime = CACurrentMediaTime();
if (self.beatingStartTime == 0) {
self.beatingStartTime = currentTime;
}
if ( (currentTime - self.beatingStartTime) >= self.timeIntevalBetweenTicks * self.internalTimerCounter ) {
self.internalTimerCounter ++;
// ...
}
如果有一个播放音频的好时机,使用OpenAL播放它的代码会被触发。
基本就是这样。我检查了在模拟器和2个设备(iPad和越狱iPhone 3GS)上运行时播放的声音,并且存在问题 - 当我录制声音并在Reaper
软件中查看波形时,有些声音播放有点太晚了,其中一些 - 有点太早了(即使我能理解“太晚了”的部分,我真的不知道它应该如何才能更早发挥它应该 - 因为应用程序每次检查秒数,它基本上不能比指定时间更早 - 但根据我的反馈,它是。
与此同时,有一些节拍器应用程序在定时方面被称为“坚如磐石”,所以我猜有一种方法。我只是想知道我错过了什么......
编辑:将定时器调用从1/1000秒更改为例如1/100并没有帮助。
编辑2 :当我从计时器切换到线程时(我让线程在指定的时间内进入休眠状态)我仍然会遇到一个奇怪的行为。节奏移动,虽然我可以理解一点延迟并且播放一些声音太晚,问题是它们中的一些确实发挥太早 - 这意味着2节拍之间的时间距离小于时间应该通过。
差异大约是3%,相当于大约10-15毫秒,这对我来说非常重要。任何人都知道为什么声音可以更早播放?我在iPhone模拟器和iPad实际设备上都试过了,我唯一的猜测是计时器有问题 - CACurrentMediaTime()
返回它应该的秒数。它甚至可能吗?
答案 0 :(得分:5)
尝试使用NSSound,并将其作为实例变量加载,除非您的节拍器未运行,否则不要将其释放。通过将文件加载到循环内存中可能导致延迟。另一件需要考虑的事情是节拍器可能不需要每1/1000秒轮询一次。如果你不经常这样做,你就不太可能使CPU饱和,你可能会得到更一致的结果。
最后,查看Apple的演示工作原理:http://developer.apple.com/library/ios/#samplecode/Metronome/Introduction/Intro.html
可能会让你更好地了解如何完成你想要做的事情:)
答案 1 :(得分:2)
你想要的是 COCOS DENSHION 这是一个简单易用的简单声音库,我们发现它可以解决所有问题。
我(只是个人)不喜欢“Cocos2D”,但你可以采取和使用CocosDenshion。
其次 - 千分之一秒对于计时器来说是荒谬的。完全忘了它。
第三,你发现AVAudioPlayer毫无价值。
到CocosDenshion。看看吧。