简体   繁体   English

如何在iPhone上的精确时刻播放声音?

[英]How to play sound at precise moments on iPhone?

I'm working on creating a simple metronome on the iPhone. 我正在努力在iPhone上创建一个简单的节拍器。 What the app does right now is to run a timer, entering the timer's function every 1/1000th of second. 该应用程序现在所做的是运行计时器,每 1/1000 秒输入计时器的功能。 Then it checks the current time vs time of starting the app (I'm using CACurrentMediaTime() function). 然后它检查当前时间与启动应用程序的时间(我正在使用CACurrentMediaTime()函数)。

CFTimeInterval currentTime = CACurrentMediaTime();
if (self.beatingStartTime == 0) {
    self.beatingStartTime = currentTime;
}
if ( (currentTime - self.beatingStartTime) >= self.timeIntevalBetweenTicks * self.internalTimerCounter ) {
    self.internalTimerCounter ++;
    // ...
}

If there is a good moment to play audio, the code using OpenAL to play it gets fired. 如果有一个播放音频的好时机,使用OpenAL播放它的代码会被触发。

Basicly that's it. 基本就是这样。 I checked the sounds played when running both in simulator as well as on 2 devices (iPad and jailbroken iPhone 3GS) and there is a problem - when I recorded the sound and reviewed the waveform in Reaper software, some sounds play a bit too late, and some of them - bit too early (even I could understand the "too late" part, I don't really get how it can play earlier then it should - since the app checks the number of seconds every time, it basicly can't be ealier then specified time - yet it is, according to my recods). 我检查了在模拟器和2个设备(iPad和越狱的iPhone 3GS)上运行时播放的声音,并且有一个问题 - 当我录制声音并查看Reaper软件中的波形时,有些声音播放时间太晚了,还有一些 - 有点太早了(即使我能理解“太晚了”的部分,我真的不知道它应该如何才能发挥它应该 - 因为应用程序每次检查秒数,它基本上可以'然后指定的时间更早 - 但根据我的记录,它是。

At the same time there are some metronome apps that are known for being "rock-solid" when it comes to timing, so I guess there is a way. 与此同时,有一些节拍器应用程序在定时方面以“坚如磐石”着称,所以我猜有一种方法。 I just wonder what I'm missing... 我只是想知道我错过了什么......


edit : Changing timer call from 1/1000th second to, for example 1/100th doesn't help. 编辑 :将定时器调用从1/1000秒更改为例如1/100并没有帮助。

edit 2 : When I switched from timer to threads (and I put the thread to sleep for specified time) I still get a strange behavior. 编辑2 :当我从计时器切换到线程(并且我让线程在指定时间内休眠)时,我仍然会遇到奇怪的行为。 The tempo moves around and while I could understand a little lag and playing some sounds too late, the problem is some of them do play too early - it means time distance between 2 beats is less then the time that should pass. 节奏四处移动,虽然我可以理解一点滞后并且播放一些声音太晚,问题是它们中的一些确实发挥得太早 - 这意味着2节拍之间的时间距离应该超过应该通过的时间。

The diffrence is about 3%, which translates to about 10-15 miliseconds, which is quite a lot for me. 差异大约是3%,相当于大约10-15毫秒,这对我来说非常重要。 Anyone got an idea why the sound can play earlier? 任何人都知道为什么声音可以更早播放? I tried it both on iPhone simulator and on iPad actual device, and my only guess is there's something wrong with the timer - CACurrentMediaTime() returning more seconds that it should. 我在iPhone模拟器和iPad实际设备上都试过了,我唯一的猜测是计时器有问题CACurrentMediaTime()返回它应该的秒数。 Is it even possible? 它甚至可能吗?

Try using an NSSound, and load it up as an instance variable and don't release it unless your metronome isn't running. 尝试使用NSSound,并将其作为实例变量加载,除非您的节拍器没有运行,否则不要释放它。 Delays can be caused by loading the file into memory on the loop. 通过将文件加载到循环内存中可能导致延迟。 The other thing to consider is that a metronome probably doesn't need to poll every 1/1000th of a second. 另一件需要考虑的事情是节拍器可能不需要每1/1000秒轮询一次。 If you do it less often, you're less likely to saturate the CPU and you might get more consistent results. 如果你不经常这样做,你就不太可能让CPU饱和,你可能会得到更一致的结果。

Lastly, check out how Apple's demo works: http://developer.apple.com/library/ios/#samplecode/Metronome/Introduction/Intro.html 最后,看看Apple的演示如何工作: http//developer.apple.com/library/ios/#samplecode/Metronome/Introduction/Intro.html

Might give you a better idea how to accomplish what you're trying to do :) 可能会让你更好地了解如何完成你想要做的事:)

What you want is COCOS DENSHION which is a simple reliable easy to use sound library, that we have found solves all problems. 你想要的是COCOS DENSHION ,它是一个简单可靠易用的声音库,我们发现它解决了所有问题。

I (just personally) don't like "Cocos2D" but you can just take and use CocosDenshion. 我(只是个人)不喜欢“Cocos2D”,但你可以采取和使用CocosDenshion。

Secondly -- 1000th of a second is ridiculous for a timer. 其次 - 1000秒钟对计时器来说是荒谬的。 Just totally forget it. 完全忘了它。

Thirdly -- AVAudioPlayer is worthless as you found. 第三,你发现AVAudioPlayer毫无价值。

Note - "ObjectAL" is a new, perhaps better, alternative 注 - “ObjectAL”是一种新的,可能更好的选择

to CocosDenshion. 到CocosDenshion。 Check it out. 看看这个。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM