代码之家  ›  专栏  ›  技术社区  ›  Mel

在Openal中播放完声音后收到通知

  •  6
  • Mel  · 技术社区  · 16 年前

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

    我能让Openal通知我一个样本什么时候播放完吗?

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

    4 回复  |  直到 15 年前
        1
  •  3
  •   zoul    16 年前

    如果将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
  •  4
  •   pestilence669    15 年前

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

    深入了解这个问题的“为什么”可能会提供一些额外的选择。

        3
  •  1
  •   Nathan de Vries    16 年前

    This OpenAL guide 建议一个可能的解决方案:

    “stream”函数还告诉我们流是否已播放完毕。

    …并提供示例源代码来说明用法。

        4
  •  1
  •   invalidname    16 年前

    等等,你是在说完成了吗? 一样本 (例如,44.1 kHz音频为1/44100秒)?或者你说的是知道一个源已经通过它的缓冲区播放了,并且没有更多的音频可以播放?

    对于后者,当我将缓冲流传输到某个源时,我已经取得了很好的结果,在该源中轮询al-buffers-processed属性的源;对于单个缓冲区情况,查找该属性的非零值可能是有效的。

    推荐文章