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; 
  } 
}