31:効果音の同時再生(1)
ミサイルの発射など、短い効果音では特に気にならないのですが、同じ長めの効果音を連続して再生しようとすると、そのたびにはじめから再生され、同時に再生することができません。だからといって、再生する効果音の分だけIDirectSoundBufferを作成して領域を確保するのも無駄なような気がします。DirectXはいろいろと考えられているようで、音楽データだけは同じだけど、再生制御は個別に行う機能が用意されています。それがIDirectSound8::DuplicateSoundBuffer()です。これを利用すると、無駄にメモリを消費せずに、同じ効果音を同時に再生することができるようになります。複製されたデータをRelease()で解放しても、最後のひとつが解放されるまでデータは保持されるので、何回データをロードして、何回削除したかなんてことをプログラムで考える必要はありません。
CSound sound(_T("sample.wav"));
CSound sound2 = sound;
今回はCSoundクラス内で宣言を行うので、CSoundクラス内には[クラス名]&operator=(const[クラス名]&);
と記述することになります。一方、処理の実行部分ではCSound&operator=(constCSound&);
CSound& CSound::operator =(const CSound &s)
{
RELEASE(pDSBuffer);
if(pDSound) pDSound->DuplicateSoundBuffer(s.pDSBuffer, &pDSBuffer);
return *this;
}
CSound sound2 = sound(_T("sample.wav"));
上記のように代入を行った場合、operator
=による代入演算の関数は呼び出されず、コピーコンストラクタという独特の関数が呼び出されます。コピーコンストラクタと代入演算は似て非なるもので、コピーコンストラクタ用の宣言と処理は個別に記述する必要があります。その宣言と処理は以下の通りとなります。
// コピーコンストラクタの宣言
class CSound : public CGameObject
{
public:
CSound(const CSound&);
}
// コピーコンストラクタの処理
CSound::CSound(const CSound &s)
{
RELEASE(pDSBuffer);
if(pDSound) pDSound->DuplicateSoundBuffer(s.pDSBuffer, &pDSBuffer);
}
class CSound : public CGameObject
{
private:
/* 省略 */
public:
/* 省略 */
CSound(const CSound&);
CSound& operator=(const CSound&);
/* 省略 */
};
CSound::CSound(const CSound &s)
{
RELEASE(pDSBuffer);
if(pDSound) pDSound->DuplicateSoundBuffer(s.pDSBuffer, &pDSBuffer);
}
CSound& CSound::operator =(const CSound &s)
{
RELEASE(pDSBuffer);
if(pDSound) pDSound->DuplicateSoundBuffer(s.pDSBuffer, &pDSBuffer);
return *this;
}
// 効果音の再生
shootsound = *(CSound*)FindObject("tama");
shootsound.Play();