2016-01-24 05:06:18 chip
Page 1536
📢 PUBLIC
Sound.cpp using XAudio2.
Sound.cpp:
#undef _DEBUG
#include <Windows.h>
#include <xaudio2.h>
#include "Util.h"
#include "Globals.h"
#include "Wave.h"
#pragma message(__FILE__": Optimizer disabled.")
#pragma optimize("",off)
#define SOUND_MAX 32
class SoundMgr {
public:
static SoundMgr *Ptr(HSOUNDMGR hMgr);
static int Create(HSOUNDMGR *phMgr);
int Destroy(void);
int SoundCreate(HSOUND *phSound, const char *Name);
int SoundDestroy(HSOUND hSound);
int Play(HSOUND hSound, UINT Flags);
int Stop(HSOUND hSound);
//Data
UINT Signature;
private:
SoundMgr(void);
~SoundMgr(void);
int Create2(void);
//Data
IXAudio2 *pEngine;
IXAudio2MasteringVoice *pMaster;
HSOUND SoundList[SOUND_MAX];
};
class Sound {
public:
static Sound *Ptr(HSOUND hSound);
static int Create(HSOUND *phSound,const char *Name,IXAudio2 *pEngine);
int Destroy(void);
int Play(UINT Flags);
int Stop(void);
//Data
UINT Signature;
private:
Sound(void);
~Sound(void);
int Create2(const char *Name,IXAudio2 *pEngine);
//Data
Wave Src;
IXAudio2SourceVoice *pVoice;
bool IsPlaying;
};
HSOUNDMGR ghSoundMgr;
/*************************************************************************/
/** Public interface **/
/*************************************************************************/
int SoundMgrCreate(void) {
return(SoundMgr::Create(&ghSoundMgr));
}
int SoundMgrDestroy(void) {
int Err= ERR_OK;
SoundMgr *pMgr= SoundMgr::Ptr(ghSoundMgr);
if(!pMgr)
return(ERR_BADHANDLE);
if(!IsErr(Err= pMgr->Destroy()))
ghSoundMgr= 0;
return(Err);
}
int SoundCreate(HSOUND *phSound, const char *Name) {
int Err= ERR_OK;
SoundMgr *pMgr= SoundMgr::Ptr(ghSoundMgr);
if(!pMgr) {
Err= ERR_NOINIT;
} else {
Err= pMgr->SoundCreate(phSound,Name);
}
return(Err);
}
int SoundDestroy(HSOUND hSound) {
int Err= ERR_OK;
SoundMgr *pMgr= SoundMgr::Ptr(ghSoundMgr);
if(!pMgr) {
Err= ERR_NOINIT;
} else {
Err= pMgr->SoundDestroy(hSound);
}
return(Err);
}
int SoundPlay(HSOUND hSound, UINT Flags) {
int Err= ERR_OK;
SoundMgr *pMgr= SoundMgr::Ptr(ghSoundMgr);
if(!pMgr) {
Err= ERR_NOINIT;
} else {
Err= pMgr->Play(hSound,Flags);
}
return(Err);
}
int SoundStop(HSOUND hSound) {
int Err= ERR_OK;
SoundMgr *pMgr= SoundMgr::Ptr(ghSoundMgr);
if(!pMgr) {
Err= ERR_NOINIT;
} else {
Err= pMgr->Stop(hSound);
}
return(Err);
}
/*************************************************************************/
/** Public internals **/
/*************************************************************************/
SoundMgr *SoundMgr::Ptr(HSOUNDMGR hMgr) {
SoundMgr *pMgr= (SoundMgr*)hMgr;
if(!hMgr || IsBadPtr(pMgr,sizeof(*pMgr),BADPTR_RW) || pMgr->Signature!=SIGNATURE_SOUNDMGR)
pMgr= 0;
return(pMgr);
}
int SoundMgr::Create(HSOUNDMGR *phMgr) {
int Err= ERR_OK;
SoundMgr *pMgr= new SoundMgr();
if(!pMgr) {
Err= Error(ERR_NOMEM,"SoundMgr:Create: NoMem");
} else if(IsErr(Err= pMgr->Create2())) {
delete pMgr;
} else {
*phMgr= (HSOUNDMGR)pMgr;
}
return(Err);
}
int SoundMgr::Destroy(void) {
int Err= ERR_OK;
if(pEngine)
pEngine->Release();
delete this;
return(Err);
}
int SoundMgr::SoundCreate(HSOUND *phSound, const char *Name) {
int Err= ERR_OK;
UINT n1;
for(n1=0;n1<SOUND_MAX && SoundList[n1];n1++);
if(n1>=SOUND_MAX) {
Err= Warn(ERR_TOO_MANY,"SoundMgr:SoundCreate(%s): Too many sounds [%d]",Name,n1);
} else if(IsErr(Err= Sound::Create(&SoundList[n1],Name,pEngine))) {
Err= Warn(Err,"SoundMgr:SoundCreate(%s): Unable to create sound.",Name);
} else {
*phSound= SoundList[n1];
}
return(Err);
}
int SoundMgr::SoundDestroy(HSOUND hSound) {
int Err= ERR_OK;
UINT n1;
Sound *pSound= Sound::Ptr(hSound);
if(!pSound) {
Err= ERR_BADHANDLE;
} else {
Err= pSound->Destroy();
for(n1=0;n1<SOUND_MAX && SoundList[n1]!=hSound;n1++);
if(n1<SOUND_MAX)
SoundList[n1]= 0;
}
return(Err);
}
int SoundMgr::Play(HSOUND hSound, UINT Flags) {
int Err= ERR_OK;
Sound *pSnd= Sound::Ptr(hSound);
if(!pSnd) {
Err= ERR_BADHANDLE;
} else {
Err= pSnd->Play(Flags);
}
return(Err);
}
int SoundMgr::Stop(HSOUND hSound) {
int Err= ERR_OK;
Sound *pSnd= Sound::Ptr(hSound);
if(!pSnd) {
Err= ERR_BADHANDLE;
} else {
Err= pSnd->Stop();
}
return(Err);
}
/*************************************************************************/
/** Private internals **/
/*************************************************************************/
SoundMgr::SoundMgr(void) {
Signature= SIGNATURE_SOUNDMGR;
}
SoundMgr::~SoundMgr(void) {
Signature|= SIGNATURE_INVALID;
}
int SoundMgr::Create2(void) {
int Err= ERR_OK;
HRESULT hErr;
if(!SUCCEEDED(hErr= XAudio2Create(&pEngine))) {
Err= Error(ERR_SYSCREATE,"SoundMgr:Create2: Unable to create XAudio2 engine. [%X]",hErr);
} else if(!SUCCEEDED(hErr= pEngine->CreateMasteringVoice(&pMaster))) {
Err= Error(ERR_SYSCREATE,"SoundMgr:Create2: Unable to create mastering voice. [%X]",hErr);
} else {
//OK
}
return(Err);
}
/*************************************************************************/
/** Individual sounds **/
/*************************************************************************/
Sound *Sound::Ptr(HSOUND hSnd) {
Sound *pSnd= (Sound*)hSnd;
if(!hSnd || IsBadPtr(pSnd,sizeof(*pSnd),BADPTR_RW) || pSnd->Signature!=SIGNATURE_SOUND)
pSnd= 0;
return(pSnd);
}
int Sound::Create(HSOUND *phSound, const char *Name, IXAudio2 *pEngine) {
int Err= ERR_OK;
Sound *pSound= new Sound();
if(!pSound) {
Err= ERR_NOMEM;
} else if(IsErr(Err= pSound->Create2(Name,pEngine))) {
delete pSound;
} else {
*phSound= (HSOUND)pSound;
}
return(Err);
}
int Sound::Destroy(void) {
int Err= ERR_OK;
delete this;
return(Err);
}
Sound::Sound(void) {
Signature= SIGNATURE_SOUND;
}
Sound::~Sound(void) {
Signature|= SIGNATURE_INVALID;
}
int Sound::Create2(const char *Name, IXAudio2 *pEngine) {
int Err= ERR_OK;
HRESULT hErr;
if(!Src.load(Name)) {
Err= Warn(ERR_SYSCREATE,"Sound:Create(%s): Unable to load WAV data.",Name);
} else if(!SUCCEEDED(hErr= pEngine->CreateSourceVoice(&pVoice,Src.wf()))) {
Err= Warn(ERR_SYSCREATE,"Sound:Create(%s): Unable to create voice. [%X]",Name,hErr);
} else {
//OK
}
return(Err);
}
int Sound::Play(UINT Flags) {
int Err= ERR_OK;
HRESULT hErr;
XAUDIO2_VOICE_STATE State;
pVoice->GetState(&State);
if(IsPlaying && State.BuffersQueued>0) {
Err= 1;
} else {
if(IsPlaying) {
pVoice->Stop();
IsPlaying= false;
}
XAUDIO2_BUFFER Buf= *Src.xaBuffer();
if(Flags & SNDPLAY_LOOP) {
Buf.LoopBegin= Buf.PlayBegin;
Buf.LoopLength= Buf.PlayLength;
Buf.LoopCount= XAUDIO2_LOOP_INFINITE;
}
if(!SUCCEEDED(hErr= pVoice->Start())) {
Err= Warn(ERR_SYSCREATE,"Sound:Play: Unable to start voice. [%X]",hErr);
} else if(!SUCCEEDED(hErr= pVoice->SubmitSourceBuffer(&Buf))) {
Err= Warn(ERR_SYSCREATE,"Sound:Play: Failed [%X]",hErr);
} else {
IsPlaying= true;
}
}
return(Err);
}
int Sound::Stop(void) {
int Err= ERR_OK;
if(IsPlaying) {
pVoice->Stop();
IsPlaying= false;
}
return(Err);
}
WebV7 (C)2018 nlited | Rendered by tikope in 37.131ms | 3.128.197.61