OpenALバッファーのバインドを解除して削除するにはどうすればよいですか?


12

OpenALを使用してサウンドを再生しています。私は、バッファIDを取得し、以前に割り当てたプールからソースに割り当てて再生する、ファイアアンドフォーゲットプレイ機能を実装しようとしています。ただし、オブジェクトの有効期間には問題があります。

OpenGLでは、削除関数は自動的にバインドを解除する(テクスチャなど)か、最終的にバインドされなくなったときに自動的に削除する(シェーダーなど)ため、通常、削除の管理は簡単です。ただし、alDeleteBuffers代わりにAL_INVALID_OPERATION、バッファがまだソースにバインドされている場合、単に失敗します。

OpenALバッファーの再生を終了し、自動的にバインドを解除して実際にそれらを許可する慣用的な方法はありますか?バッファ管理をソースプールにより深く関連付ける必要がありますか(たとえば、バッファを削除するには、割り当てられているすべてのソースもチェックする必要があります)。

同様に、バッファの再生が終了したときに、バッファをアンバインドする(削除はしない)慣用的な方法はありますか?無料のソースを探していたときに、バッファがまったく接続されているかどうかを確認するだけで、ソースの状態を確認する必要がなければいいのですが。

(私はC ++を使用していますが、Cのアプローチも問題ありません。GCd言語を想定し、ファイナライザを使用するアプローチはおそらく適用されません。)

openal 

それでも答えが必要な場合は、Gorgonエンジンでガベージコレクションメソッドを使用しました:sf.net/p/gorgon-ge
Cem Kalyoncu

回答:


8

バッファを削除する前に、それを使用する各ソースからアンバインドする必要あります(例:alSourcei(mSourceId, AL_BUFFER, NULL);または、バッファにバインドされているすべてのソースを削除します。

完了時にサウンドをリリースするには、各サウンドの長さを追跡する必要があります。各ソースの構造を使用してこれを実行し、サウンドの長さと再生時間を維持できます(各ゲームティックを更新)。例:

struct AudioVoice
{
    ALuint          mSourceId;
    ALuint          mMsDuration;
    ALuint          mMsPlayed;
};

コンポーネントベースのシステムを使用する場合、実行中のすべてのソースの完了を定期的に確認し、そこでアンバインド/ソース削除を実行できます。

コードの再生/一時停止の変更を追跡しない場合は、再生時間を増やす前にソースが再生されているかどうかも確認する必要があります。

ALint sourceState;
alGetSourcei(mSourceId, AL_SOURCE_STATE, &sourceState);
if (sourceState == AL_PLAYING) { /* increase played time */  }

バッファにバインドされたソースを追跡したい場合は、バッファのIDを持つ構造体とソース構造体にリンクしているベクトルを使用して、解放する必要があるバッファにバインドされているすべてのソースを中断することもできますできるだけ速くに。例:

struct AudioData
{
    RKuint                      mMsDuration;
    ALuint                      mSourceId;
    std::vector<AudioVoice*>    mVoices;
};

これで正しい軌道に乗れます。私のプロジェクトはマクロと手作りのRTTIメカニズムに大きく依存しているため、これ以上詳細なコードを提供することはできません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.