我在iPhone上使用OpenAL同时播放多个音频样本。
单个样本完成播放后,我可以让OpenAL通知我吗?
我想避免硬编码样本长度并设置计时器。
答案 0 :(得分:4)
我对OpenAL中的回调没有太多运气。在我的状态机中,我只是轮询源并延迟转换,直到完成。
- (BOOL)playing {
ALint sourceState;
alGetSourcei(sourceID, AL_SOURCE_STATE, &sourceState);
return sourceState == AL_PLAYING;
}
// ... //
case QSTATE_DYING:
if (![audioSource playing])
[self transitionTo:QSTATE_DEAD];
如果这不是您所需要的,那么您最好的选择可能是计时器。您不需要对任何值进行硬编码。您可以在填充缓冲区时确定播放时间。
对问题“原因”的一些了解可能会提供一些额外的选择。
答案 1 :(得分:3)
如果您将OpenAL源抽象化为一个类,我想您可以在启动声音时简单地调用performSelector:afterDelay:
:
- (void) play
{
[delegate performSelector:@selector(soundHasFinishedPlaying)
afterDelay:self.length];
…
}
(如果您在此期间手动停止声音,可以取消回调,请参阅NSObject Class Reference。)或者您可以轮询AL_SOURCE_STATE
:
- (void) checkStatus
{
ALint state;
alGetSourcei(source, AL_SOURCE_STATE, &state);
if (state == AL_PLAYING)
return;
[timer invalidate];
[delegate soundHasFinishedPlaying];
}
我不知道如何让OpenAL给你回电话。你究竟想要回调的是什么?如果没有回调,有些事情可以更好地解决。
答案 2 :(得分:1)
答案 3 :(得分:1)
等等,你在谈论完成一个样本(例如,44.1 KHz音频的1/44100秒)?或者你在谈论知道一个源已经通过其缓冲区播放并且没有更多的音频可以播放?
对于后者,当我将缓冲区流式传输到源时,我已经有很好的结果轮询AL_BUFFERS_PROCESSED属性的源;它可能适用于单缓冲区的情况,以查找此属性的非零值。