繁体   English   中英

在OpenAL中播放声音时收到通知

[英]Getting notified when a sound is done playing in OpenAL

我在iPhone上使用OpenAL同时播放多个音频样本。

我可以让OpenAL在单个样本播放时通知我吗?

我想避免硬编码样本长度和设置计时器。

我在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];

如果这不是你需要的,那么你最好的选择可能是计时器。 您不需要对任何值进行硬编码。 您可以在填充缓冲区时确定播放时间。

对问题“原因”的一些了解可能会提供一些额外的选择。

如果你把OpenAL源抽象成一个类,我猜你可以简单地调用performSelector:afterDelay:当你启动声音时:

- (void) play
{
    [delegate performSelector:@selector(soundHasFinishedPlaying)
        afterDelay:self.length];
    …
}

(如果在此期间手动停止声音,可以取消回调,请参阅NSObject类参考 。)或者您可以轮询AL_SOURCE_STATE

- (void) checkStatus
{
    ALint state;
    alGetSourcei(source, AL_SOURCE_STATE, &state);
    if (state == AL_PLAYING)
        return;
    [timer invalidate];
    [delegate soundHasFinishedPlaying];
}

我不知道如何让OpenAL给你回电话。 你究竟想要回调的是什么? 如果没有回调,有些事情可以更好地解决。

本OpenAL指南提出了一个可能的解决方案:

'stream'函数还告诉我们流是否已完成播放。

...并提供示例源代码以说明用法。

等等,你在谈论完成一个样本 (例如,44.1 KHz音频的1/44100秒)? 或者你在谈论知道一个源已经通过其缓冲区播放并且没有更多的音频播放?

对于后者,当我将缓冲区传输到源时,我已经有很好的结果轮询AL_BUFFERS_PROCESSED属性的源; 它可能适用于单缓冲区情况,以查找此属性的非零值。

暂无
暂无

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

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