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

当单个样本播放完毕时,我可以让 OpenAL 通知我吗?

我想避免对样本长度进行硬编码并设置计时器。

有帮助吗?

解决方案

如果您将 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的回调多少运气。在我的国家机器,我只是轮询源,直到它完成延迟的转变。


    - (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的指南提出了一种可能的解决方案:

  

在“流”功能也告诉我们,如果流被播放完毕。

...并提供示例源代码来说明使用。

等待,你谈论已经完成的一个样品(例如,对于44.1千赫的音频四万四千百分之一第二)?或者是你在谈论知道源通过其缓冲发挥,并没有更多的音频播放?

有关后者,我有良好的结果轮询时我流缓冲区的一个源AL_BUFFERS_PROCESSED属性的源;它可能为单缓冲器的情况下工作,以寻找该属性的一个非零值。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top