www.pudn.com > 3D_OnlineGame_Humen.rar > 3DSound.cpp
#include "stdafx.h"
#include "XMudClient.h"
#include "3DSound.h"
#include "MyMusic.h"
extern rmfullglobals myglobs;
extern char g_tszPathName[256];
WaveHeader wavHdr;
char g_szErrorMsg[256];
BOOL g_bInitSound;
BOOL g_bErrorOccured;
BOOL g_bSoundPaused=FALSE;
BOOL g_bSoundPresent=FALSE;
LPDIRECTSOUND g_lpDS;
LPDIRECTSOUND3DLISTENER g_lpDs3dListener;
LPDIRECTSOUNDBUFFER g_3DSoundBuffer=NULL;
LPDIRECTSOUND3DBUFFER g_lp3dSounds[NUM_SOUNDS];
LPDIRECTSOUNDBUFFER g_lpSounds[NUM_SOUNDS];
LPDIRECTSOUND3DBUFFER g_lp3dSurroundSounds[NUM_SURROUND_SOUND];
LPDIRECTSOUNDBUFFER g_lpSurroundSounds[NUM_SURROUND_SOUND];
BOOL InitSound()
{
HRESULT rval;
rval = DirectSoundCreate(NULL, &g_lpDS, NULL);
g_bSoundPresent = rval == DS_OK ? TRUE : FALSE;
if (g_bSoundPresent){
TRY_DS(g_lpDS->SetCooperativeLevel(myglobs.hWndMain, DSSCL_PRIORITY))
g_3DSoundBuffer = CreateSoundBuffer3D();
if(g_3DSoundBuffer == NULL){
RegError("Not able to create Direct 3D Sound Buffer");
return FALSE;
}
if(DS_OK != g_3DSoundBuffer->QueryInterface(IID_IDirectSound3DListener, (void**)&g_lpDs3dListener))
{
RegError("Not able to create Direct 3D Sound Listener object");
return FALSE;
}
g_lpDs3dListener->SetRolloffFactor((FLOAT).01,DS3D_DEFERRED);
g_lpDs3dListener->SetOrientation(-D3DVAL(1), D3DVAL(0), D3DVAL(0), D3DVAL(0), D3DVAL(1), D3DVAL(0),DS3D_DEFERRED);
g_lpDs3dListener->CommitDeferredSettings();
for (int i = 0; i < NUM_SOUNDS; i ++){
g_lpSounds[i] = NULL;
}
if (!CreateBufferFromWaveFile("openmenu.wav", OPENMENU)){
RegError("Couldn't load wave\\openmenu.wav!");
return FALSE;
}
if (!CreateBufferFromWaveFile("closemenu.wav", CLOSEMENU)){
RegError("Couldn't load wave\\closemenu.wav!");
return FALSE;
}
if (!CreateBufferFromWaveFile("pressbutton.wav", PRESSBUTTON)){
RegError("Couldn't load wave\\pressbutton.wav!");
return FALSE;
}
if (!CreateBufferFromWaveFile("random1.wav", RANDOM1)){
RegError("Couldn't load wave\\random1.wav!");
return FALSE;
}
if (!CreateBufferFromWaveFile("random2.wav", RANDOM2))
{
RegError("Couldn't load wave\\random2.wav!");
return FALSE;
}
if (!CreateBufferFromWaveFile("random3.wav", RANDOM3))
{
RegError("Couldn't load wave\\random3.wav!");
return FALSE;
}
if (!CreateBufferFromWaveFile("random4.wav", RANDOM4))
{
RegError("Couldn't load wave\\random4.wav!");
return FALSE;
}
if (!CreateBufferFromWaveFile("random5.wav", RANDOM5))
{
RegError("Couldn't load wave\\random5.wav!");
return FALSE;
}
if (!CreateBufferFromWaveFile("random6.wav", RANDOM6))
{
RegError("Couldn't load wave\\random6.wav!");
return FALSE;
}
if (!CreateBufferFromWaveFile("message.wav", MESSAGE))
{
RegError("Couldn't load wave\\message.wav!");
return FALSE;
}
InitDirectMusic(myglobs.hWndMain, g_lpDS);
}
return TRUE;
}
void RegError(char * sErr)
{
sprintf(g_szErrorMsg, "%s\r\n", sErr);
OutputDebugString(g_szErrorMsg);
g_bErrorOccured = TRUE;
}
void TraceErrorDS(HRESULT hErr, char * sFile, int nLine)
{
char dserr[256];
char err[256];
switch (hErr)
{
case DSERR_ALLOCATED : sprintf(dserr, "DSERR_ALLOCATED"); break;
case DSERR_CONTROLUNAVAIL : sprintf(dserr, "DSERR_CONTROLUNAVAIL"); break;
case DSERR_INVALIDPARAM : sprintf(dserr, "DSERR_INVALIDPARAM"); break;
case DSERR_INVALIDCALL : sprintf(dserr, "DSERR_INVALIDCALL"); break;
case DSERR_GENERIC : sprintf(dserr, "DSERR_GENERIC"); break;
case DSERR_PRIOLEVELNEEDED : sprintf(dserr, "DSERR_PRIOLEVELNEEDED"); break;
case DSERR_OUTOFMEMORY : sprintf(dserr, "DSERR_OUTOFMEMORY"); break;
case DSERR_BADFORMAT : sprintf(dserr, "DSERR_BADFORMAT"); break;
case DSERR_UNSUPPORTED : sprintf(dserr, "DSERR_UNSUPPORTED"); break;
case DSERR_NODRIVER : sprintf(dserr, "DSERR_NODRIVER"); break;
case DSERR_ALREADYINITIALIZED : sprintf(dserr, "DSERR_ALREADYINITIALIZED"); break;
case DSERR_NOAGGREGATION : sprintf(dserr, "DSERR_NOAGGREGATION"); break;
case DSERR_BUFFERLOST : sprintf(dserr, "DSERR_BUFFERLOST"); break;
case DSERR_OTHERAPPHASPRIO : sprintf(dserr, "DSERR_OTHERAPPHASPRIO"); break;
case DSERR_UNINITIALIZED : sprintf(dserr, "DSERR_UNINITIALIZED"); break;
default : sprintf(dserr, "Unknown Error"); break;
}
sprintf(err, "DirectSound Error %s\nin file %s at line %d", dserr, sFile, nLine);
RegError(err);
}
IDirectSoundBuffer* CreateSoundBuffer3D()
{
WAVEFORMATEX WFEx;
IDirectSoundBuffer *pDSB = NULL;
DSBUFFERDESC dsBD = {0};
ZeroMemory( &dsBD, sizeof(DSBUFFERDESC));
dsBD.dwSize = sizeof(dsBD);
dsBD.dwFlags = DSBCAPS_CTRL3D | DSBCAPS_PRIMARYBUFFER;
dsBD.dwBufferBytes = 0; //must be zero for primary buffer..
if(g_lpDS->CreateSoundBuffer(&dsBD,&pDSB,NULL)!=DS_OK) pDSB = NULL;
memset(&WFEx, 0, sizeof(WAVEFORMATEX));
WFEx.wFormatTag = WAVE_FORMAT_PCM;
WFEx.nSamplesPerSec = 22050;
WFEx.wBitsPerSample = 16;
WFEx.nChannels = 2;
WFEx.nBlockAlign = (WFEx.wBitsPerSample/8)*WFEx.nChannels;
WFEx.nAvgBytesPerSec = WFEx.nSamplesPerSec*WFEx.nBlockAlign;
if(pDSB->SetFormat(&WFEx)!=DS_OK)
{
pDSB->Release();
pDSB=NULL;
return pDSB;
}
pDSB->Play(NULL,NULL,DSBPLAY_LOOPING);
return pDSB;
}
BOOL CreateBufferFromWaveFile(char * FileName, DWORD dwBuf)
{
char string[256];
lstrcpy( string, g_tszPathName );
lstrcat( string, "\\WAVE\\" );
strcat( string, FileName);
FILE* pFile = fopen(string,"rb");
if (pFile == NULL) return FALSE;
if (fread(&wavHdr, sizeof(wavHdr), 1, pFile) != 1){
fclose(pFile);
return NULL;
}
DWORD dwSize = wavHdr.dwDSize;
BOOL bStereo = wavHdr.wChnls > 1 ? TRUE : FALSE;
if (!CreateSoundBuffer(dwBuf, dwSize, wavHdr.dwSRate, wavHdr.BitsPerSample, wavHdr.wBlkAlign, bStereo))
{
fclose(pFile);
return FALSE;
}
if (!ReadData(g_lpSounds[dwBuf], pFile, dwSize, sizeof(wavHdr))){
fclose(pFile);
return FALSE;
}
fclose(pFile);
return TRUE;
}
BOOL CreateSoundBuffer(DWORD dwBuf, DWORD dwBufSize, DWORD dwFreq, DWORD dwBitsPerSample, DWORD dwBlkAlign, BOOL bStereo)
{
PCMWAVEFORMAT pcmwf;
DSBUFFERDESC dsbdesc;
memset( &pcmwf, 0, sizeof(PCMWAVEFORMAT) );
pcmwf.wf.wFormatTag = WAVE_FORMAT_PCM;
pcmwf.wf.nChannels = bStereo ? 2 : 1;
pcmwf.wf.nSamplesPerSec = dwFreq;
pcmwf.wf.nBlockAlign = (WORD)dwBlkAlign;
pcmwf.wf.nAvgBytesPerSec = pcmwf.wf.nSamplesPerSec * pcmwf.wf.nBlockAlign;
pcmwf.wBitsPerSample = (WORD)dwBitsPerSample;
memset(&dsbdesc, 0, sizeof(DSBUFFERDESC));
dsbdesc.dwSize = sizeof(DSBUFFERDESC);
dsbdesc.dwFlags = DSBCAPS_CTRL3D;
dsbdesc.dwBufferBytes = dwBufSize;
dsbdesc.lpwfxFormat = (LPWAVEFORMATEX)&pcmwf;
TRY_DS(g_lpDS->CreateSoundBuffer(&dsbdesc, &g_lpSounds[dwBuf], NULL))
TRY_DS(g_lpSounds[dwBuf]->QueryInterface(IID_IDirectSound3DBuffer, (void**) &g_lp3dSounds[dwBuf]));
return TRUE;
}
BOOL ReadData(LPDIRECTSOUNDBUFFER lpDSB, FILE * pFile, DWORD dwSize, DWORD dwPos)
{
if (dwPos != 0xffffffff){
if (fseek(pFile, dwPos, SEEK_SET) != 0){
return FALSE;
}
}
LPVOID pData1;
DWORD dwData1Size;
LPVOID pData2;
DWORD dwData2Size;
HRESULT rval;
rval = lpDSB->Lock(0, dwSize, &pData1, &dwData1Size, &pData2, &dwData2Size, DSBLOCK_FROMWRITECURSOR);
if (rval != DS_OK){
return FALSE;
}
if (dwData1Size > 0){
if (fread(pData1, dwData1Size, 1, pFile) != 1)
{
char holder[256];
wsprintf(holder,"Data1 : %d, dwdata: %d, pFile: %d",pData1,dwData1Size,pFile);
OutputDebugString(holder);
return FALSE;
}
}
if (dwData2Size > 0){
if (fread(pData2, dwData2Size, 1, pFile) != 1){
return FALSE;
}
}
rval = lpDSB->Unlock(pData1, dwData1Size, pData2, dwData2Size);
if (rval != DS_OK){
return FALSE;
}
return TRUE;
}
BOOL PlaySoundDS(DWORD dwSound, D3DVECTOR d3dvPos, DWORD dwFlags)
{
if (g_bSoundPaused) return TRUE;
if (!g_bSoundPresent) return TRUE;
if (dwSound >= NUM_SOUNDS) return FALSE;
if (g_lpSounds[dwSound]){
DWORD dwStatus;
TRY_DS(g_lpSounds[dwSound]->GetStatus(&dwStatus));
if ((dwStatus & DSBSTATUS_PLAYING) != DSBSTATUS_PLAYING){
TRY_DS(g_lp3dSounds[dwSound]->SetPosition(d3dvPos.x, d3dvPos.y, d3dvPos.z, DS3D_IMMEDIATE));
TRY_DS(g_lpSounds[dwSound]->Play(0, 0, dwFlags));
}
}
return TRUE;
}
BOOL StopAllSounds()
{
for (int i = 0; i < NUM_SOUNDS; i ++){
if (g_lpSounds[i]){
DWORD dwStatus;
TRY_DS(g_lpSounds[i]->GetStatus(&dwStatus));
if ((dwStatus & DSBSTATUS_PLAYING) == DSBSTATUS_PLAYING){
TRY_DS(g_lpSounds[i]->Stop())
}
}
}
return TRUE;
}
void PlayRandomWave()
{
D3DVECTOR d3dPosition = D3DVECTOR(0.0f,0.0f,0.0f);
int RandomWave[]={RANDOM1,RANDOM2,RANDOM3,RANDOM4,RANDOM5,RANDOM6};
d3dPosition.x += (rand() % 2 == 0 ? (rand() % 250) : -(rand() % 250));
d3dPosition.z += (rand() % 2 == 0 ? (rand() % 250) : -(rand() % 250));
PlaySoundDS(RandomWave[rand() % (sizeof(RandomWave) / sizeof(RandomWave[0]))],d3dPosition,0);
return;
}
void D3DSoundRelease()
{
int i;
for (i = 0; i < NUM_SOUNDS; i ++){
if (g_lpSounds[i]){
g_lpSounds[i]->Release();
g_lpSounds[i] = NULL;
}
}
for (i = 0; i < NUM_SOUNDS; i ++){
if (g_lp3dSounds[i]){
g_lp3dSounds[i]->Release();
g_lp3dSounds[i] = NULL;
}
}
if(g_3DSoundBuffer){
g_3DSoundBuffer->Release();
g_3DSoundBuffer = NULL;
}
}