iPhoneでOpenALを使用して、複数のオーディオサンプルを同時に再生しています。
単一のサンプルの再生が完了したときに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];
これが必要でない場合は、おそらくタイマーを使用することをお勧めします。値をハードコーディングする必要はありません。バッファにデータを入力しているときに、再生時間を決定できます。
質問の「理由」について少し洞察することで、いくつかの追加の選択肢が提供される場合があります。
performSelector:afterDelay:
クラスに抽象化された OpenAL ソースがある場合は、サウンドを開始するときに単純に呼び出すことができると思います。
- (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' 関数は、ストリームの再生が終了したかどうかも教えてくれます。
...そして、使用法を説明するサンプル ソース コードを提供します。
ちょっと待って、1 つのサンプル(たとえば、44.1 KHz オーディオの場合は 1/44100 秒) を終了したということですか? それとも、ソースがバッファを介して再生され、再生するオーディオがなくなったことを知っているということですか?
後者については、バッファをソースにストリーミングするときに AL_BUFFERS_PROCESSED プロパティのソースをポーリングすると、良い結果が得られました。単一バッファの場合、このプロパティのゼロ以外の値を探すことがうまくいくかもしれません。