3DSound.cpp
上传用户:garry_shen
上传日期:2015-04-15
资源大小:45647k
文件大小:10k
源码类别:

游戏引擎

开发平台:

Visual C++

  1. #include "stdafx.h"
  2. #include "XMudClient.h"
  3. #include "3DSound.h"
  4. #include "MyMusic.h"
  5. extern rmfullglobals myglobs;
  6. extern char g_tszPathName[256];
  7. WaveHeader wavHdr;
  8. char g_szErrorMsg[256];
  9. BOOL g_bInitSound;
  10. BOOL g_bErrorOccured;
  11. BOOL g_bSoundPaused=FALSE;
  12. BOOL g_bSoundPresent=FALSE;
  13. LPDIRECTSOUND g_lpDS;
  14. LPDIRECTSOUND3DLISTENER g_lpDs3dListener;
  15. LPDIRECTSOUNDBUFFER g_3DSoundBuffer=NULL;
  16. LPDIRECTSOUND3DBUFFER g_lp3dSounds[NUM_SOUNDS];
  17. LPDIRECTSOUNDBUFFER g_lpSounds[NUM_SOUNDS];
  18. LPDIRECTSOUND3DBUFFER g_lp3dSurroundSounds[NUM_SURROUND_SOUND];
  19. LPDIRECTSOUNDBUFFER g_lpSurroundSounds[NUM_SURROUND_SOUND];
  20. BOOL InitSound()
  21. {
  22.   HRESULT     rval;
  23.   rval = DirectSoundCreate(NULL, &g_lpDS, NULL);
  24.   
  25.   g_bSoundPresent = rval == DS_OK ? TRUE : FALSE;
  26.   
  27.   if (g_bSoundPresent){
  28.     TRY_DS(g_lpDS->SetCooperativeLevel(myglobs.hWndMain, DSSCL_PRIORITY))
  29.     g_3DSoundBuffer = CreateSoundBuffer3D();
  30.     if(g_3DSoundBuffer == NULL){
  31.       RegError("Not able to create Direct 3D Sound Buffer");
  32.       return FALSE;
  33.     }
  34.     if(DS_OK != g_3DSoundBuffer->QueryInterface(IID_IDirectSound3DListener, (void**)&g_lpDs3dListener))
  35.     {
  36.       RegError("Not able to create Direct 3D Sound Listener object");
  37.       return FALSE;
  38.     }
  39.     g_lpDs3dListener->SetRolloffFactor((FLOAT).01,DS3D_DEFERRED);
  40.     g_lpDs3dListener->SetOrientation(-D3DVAL(1), D3DVAL(0), D3DVAL(0), D3DVAL(0), D3DVAL(1), D3DVAL(0),DS3D_DEFERRED);
  41.     g_lpDs3dListener->CommitDeferredSettings();
  42.     for (int i = 0; i < NUM_SOUNDS; i ++){
  43.       g_lpSounds[i] = NULL;
  44.     }
  45.     if (!CreateBufferFromWaveFile("openmenu.wav", OPENMENU)){
  46.       RegError("Couldn't load wave\openmenu.wav!");
  47.       return FALSE;
  48.     }
  49.     if (!CreateBufferFromWaveFile("closemenu.wav", CLOSEMENU)){
  50.       RegError("Couldn't load wave\closemenu.wav!");
  51.       return FALSE;
  52.     }
  53.     if (!CreateBufferFromWaveFile("pressbutton.wav", PRESSBUTTON)){
  54.       RegError("Couldn't load wave\pressbutton.wav!");
  55.       return FALSE;
  56.     }
  57.     if (!CreateBufferFromWaveFile("random1.wav", RANDOM1)){
  58.       RegError("Couldn't load wave\random1.wav!");
  59.       return FALSE;
  60.     }
  61.     if (!CreateBufferFromWaveFile("random2.wav", RANDOM2))
  62.     {
  63.       RegError("Couldn't load wave\random2.wav!");
  64.       return FALSE;
  65.     }
  66.     if (!CreateBufferFromWaveFile("random3.wav", RANDOM3))
  67.     {
  68.       RegError("Couldn't load wave\random3.wav!");
  69.       return FALSE;
  70.     }
  71.     if (!CreateBufferFromWaveFile("random4.wav", RANDOM4))
  72.     {
  73.       RegError("Couldn't load wave\random4.wav!");
  74.       return FALSE;
  75.     }
  76.     if (!CreateBufferFromWaveFile("random5.wav", RANDOM5))
  77.     {
  78.       RegError("Couldn't load wave\random5.wav!");
  79.       return FALSE;
  80.     }
  81.     if (!CreateBufferFromWaveFile("random6.wav", RANDOM6))
  82.     {
  83.       RegError("Couldn't load wave\random6.wav!");
  84.       return FALSE;
  85.     }
  86.     if (!CreateBufferFromWaveFile("message.wav", MESSAGE))
  87.     {
  88.       RegError("Couldn't load wave\message.wav!");
  89.       return FALSE;
  90.     }
  91.     InitDirectMusic(myglobs.hWndMain, g_lpDS);
  92.   }
  93.   return TRUE;
  94. }
  95. void RegError(char * sErr)
  96. {
  97.   sprintf(g_szErrorMsg, "%srn", sErr);
  98.   OutputDebugString(g_szErrorMsg);
  99.   g_bErrorOccured = TRUE;
  100. }
  101. void TraceErrorDS(HRESULT hErr, char * sFile, int nLine)
  102. {
  103.   char dserr[256];
  104.   char err[256];
  105.   
  106.   switch (hErr)
  107.   {
  108. case DSERR_ALLOCATED : sprintf(dserr, "DSERR_ALLOCATED"); break;
  109.     case DSERR_CONTROLUNAVAIL : sprintf(dserr, "DSERR_CONTROLUNAVAIL"); break;
  110.     case DSERR_INVALIDPARAM : sprintf(dserr, "DSERR_INVALIDPARAM"); break;
  111.     case DSERR_INVALIDCALL : sprintf(dserr, "DSERR_INVALIDCALL"); break;
  112.     case DSERR_GENERIC : sprintf(dserr, "DSERR_GENERIC"); break;
  113.     case DSERR_PRIOLEVELNEEDED : sprintf(dserr, "DSERR_PRIOLEVELNEEDED"); break;
  114.     case DSERR_OUTOFMEMORY : sprintf(dserr, "DSERR_OUTOFMEMORY"); break;
  115.     case DSERR_BADFORMAT : sprintf(dserr, "DSERR_BADFORMAT"); break;
  116.     case DSERR_UNSUPPORTED : sprintf(dserr, "DSERR_UNSUPPORTED"); break;
  117.     case DSERR_NODRIVER : sprintf(dserr, "DSERR_NODRIVER"); break;
  118.     case DSERR_ALREADYINITIALIZED : sprintf(dserr, "DSERR_ALREADYINITIALIZED"); break;
  119.     case DSERR_NOAGGREGATION : sprintf(dserr, "DSERR_NOAGGREGATION"); break;
  120.     case DSERR_BUFFERLOST : sprintf(dserr, "DSERR_BUFFERLOST"); break;
  121.     case DSERR_OTHERAPPHASPRIO : sprintf(dserr, "DSERR_OTHERAPPHASPRIO"); break;
  122.     case DSERR_UNINITIALIZED : sprintf(dserr, "DSERR_UNINITIALIZED"); break;
  123.       
  124.     default : sprintf(dserr, "Unknown Error"); break;
  125.   }
  126.   sprintf(err, "DirectSound Error %snin file %s at line %d", dserr, sFile, nLine);
  127.   RegError(err);
  128. }
  129. IDirectSoundBuffer* CreateSoundBuffer3D()
  130. {
  131.   WAVEFORMATEX WFEx;
  132.   IDirectSoundBuffer *pDSB = NULL;
  133.   DSBUFFERDESC dsBD = {0};
  134.   
  135.   ZeroMemory( &dsBD, sizeof(DSBUFFERDESC));
  136.   dsBD.dwSize = sizeof(dsBD);
  137.   dsBD.dwFlags = DSBCAPS_CTRL3D | DSBCAPS_PRIMARYBUFFER;
  138.   dsBD.dwBufferBytes = 0;  //must be zero for primary buffer..
  139.   if(g_lpDS->CreateSoundBuffer(&dsBD,&pDSB,NULL)!=DS_OK) pDSB = NULL;
  140.   memset(&WFEx, 0, sizeof(WAVEFORMATEX));
  141.   WFEx.wFormatTag      = WAVE_FORMAT_PCM;
  142.   WFEx.nSamplesPerSec  = 22050;
  143.   WFEx.wBitsPerSample  = 16;
  144.   WFEx.nChannels       =  2;
  145.   WFEx.nBlockAlign     = (WFEx.wBitsPerSample/8)*WFEx.nChannels;
  146.   WFEx.nAvgBytesPerSec = WFEx.nSamplesPerSec*WFEx.nBlockAlign;
  147.   if(pDSB->SetFormat(&WFEx)!=DS_OK)
  148.   {
  149.     pDSB->Release();
  150.     pDSB=NULL;
  151.     return pDSB;
  152.   }
  153.   pDSB->Play(NULL,NULL,DSBPLAY_LOOPING);
  154.   return pDSB;
  155. }
  156. BOOL CreateBufferFromWaveFile(char * FileName, DWORD dwBuf)
  157. {
  158.   char string[256];
  159.   lstrcpy( string, g_tszPathName );
  160.   lstrcat( string, "\WAVE\" );
  161.   strcat( string, FileName);
  162.   
  163.   FILE* pFile = fopen(string,"rb");
  164.   if (pFile == NULL) return FALSE;
  165.   if (fread(&wavHdr, sizeof(wavHdr), 1, pFile) != 1){
  166.     fclose(pFile);
  167.     return NULL;
  168.   }
  169.   DWORD dwSize = wavHdr.dwDSize;
  170.   BOOL bStereo = wavHdr.wChnls > 1 ? TRUE : FALSE;
  171.   if (!CreateSoundBuffer(dwBuf, dwSize, wavHdr.dwSRate, wavHdr.BitsPerSample, wavHdr.wBlkAlign, bStereo))
  172.   {
  173.     fclose(pFile);
  174.     return FALSE;
  175.   }
  176.   if (!ReadData(g_lpSounds[dwBuf], pFile, dwSize, sizeof(wavHdr))){
  177.     fclose(pFile);
  178.     return FALSE;
  179.   }
  180.   fclose(pFile);
  181.   
  182.   return TRUE;
  183. }
  184. BOOL CreateSoundBuffer(DWORD dwBuf, DWORD dwBufSize, DWORD dwFreq, DWORD dwBitsPerSample, DWORD dwBlkAlign, BOOL bStereo)
  185. {
  186.   PCMWAVEFORMAT pcmwf;
  187.   DSBUFFERDESC dsbdesc;
  188.   memset( &pcmwf, 0, sizeof(PCMWAVEFORMAT) );
  189.   pcmwf.wf.wFormatTag         = WAVE_FORMAT_PCM;      
  190.   pcmwf.wf.nChannels          = bStereo ? 2 : 1;
  191.   pcmwf.wf.nSamplesPerSec     = dwFreq;
  192.   pcmwf.wf.nBlockAlign        = (WORD)dwBlkAlign;
  193.   pcmwf.wf.nAvgBytesPerSec    = pcmwf.wf.nSamplesPerSec * pcmwf.wf.nBlockAlign;
  194.   pcmwf.wBitsPerSample        = (WORD)dwBitsPerSample;
  195.   memset(&dsbdesc, 0, sizeof(DSBUFFERDESC));
  196.   dsbdesc.dwSize              = sizeof(DSBUFFERDESC);
  197.   dsbdesc.dwFlags             = DSBCAPS_CTRL3D;
  198.   dsbdesc.dwBufferBytes       = dwBufSize; 
  199.   dsbdesc.lpwfxFormat         = (LPWAVEFORMATEX)&pcmwf;
  200.   
  201.   TRY_DS(g_lpDS->CreateSoundBuffer(&dsbdesc, &g_lpSounds[dwBuf], NULL))
  202.   TRY_DS(g_lpSounds[dwBuf]->QueryInterface(IID_IDirectSound3DBuffer, (void**) &g_lp3dSounds[dwBuf]));
  203.   
  204.   return TRUE;
  205. }
  206. BOOL ReadData(LPDIRECTSOUNDBUFFER lpDSB, FILE * pFile, DWORD dwSize, DWORD dwPos)
  207. {
  208.   if (dwPos != 0xffffffff){
  209.     if (fseek(pFile, dwPos, SEEK_SET) != 0){
  210.       return FALSE;
  211.     }
  212.   }
  213.   LPVOID pData1;
  214.   DWORD  dwData1Size;
  215.   LPVOID pData2;
  216.   DWORD  dwData2Size;
  217.   HRESULT rval;
  218.   
  219.   rval = lpDSB->Lock(0, dwSize, &pData1, &dwData1Size, &pData2, &dwData2Size, DSBLOCK_FROMWRITECURSOR);
  220.   if (rval != DS_OK){
  221.     return FALSE;
  222.   }
  223.   if (dwData1Size > 0){
  224.     if (fread(pData1, dwData1Size, 1, pFile) != 1) 
  225.     {
  226.       char holder[256];
  227.       wsprintf(holder,"Data1 : %d, dwdata: %d, pFile: %d",pData1,dwData1Size,pFile);
  228.       OutputDebugString(holder);
  229.       return FALSE;
  230.     }
  231.   }
  232.   if (dwData2Size > 0){
  233.     if (fread(pData2, dwData2Size, 1, pFile) != 1){
  234.       return FALSE;
  235.     }
  236.   }
  237.   rval = lpDSB->Unlock(pData1, dwData1Size, pData2, dwData2Size);
  238.   if (rval != DS_OK){
  239.     return FALSE;
  240.   }
  241.   
  242.   return TRUE;
  243. }
  244. BOOL PlaySoundDS(DWORD dwSound, D3DVECTOR d3dvPos, DWORD dwFlags)
  245. {
  246.   if (g_bSoundPaused) return TRUE;
  247.   
  248.   if (!g_bSoundPresent) return TRUE;
  249.   if (dwSound >= NUM_SOUNDS) return FALSE;    
  250.   if (g_lpSounds[dwSound]){
  251.     DWORD dwStatus;
  252.     TRY_DS(g_lpSounds[dwSound]->GetStatus(&dwStatus));
  253.     
  254.     if ((dwStatus & DSBSTATUS_PLAYING) != DSBSTATUS_PLAYING){
  255.       TRY_DS(g_lp3dSounds[dwSound]->SetPosition(d3dvPos.x, d3dvPos.y, d3dvPos.z, DS3D_IMMEDIATE));
  256.       TRY_DS(g_lpSounds[dwSound]->Play(0, 0, dwFlags));
  257.     }
  258.   }
  259.   return TRUE;
  260. }
  261. BOOL StopAllSounds()
  262. {
  263.   for (int i = 0; i < NUM_SOUNDS; i ++){
  264.     if (g_lpSounds[i]){
  265. DWORD dwStatus;
  266.       TRY_DS(g_lpSounds[i]->GetStatus(&dwStatus));
  267.       
  268.       if ((dwStatus & DSBSTATUS_PLAYING) == DSBSTATUS_PLAYING){
  269.         TRY_DS(g_lpSounds[i]->Stop())
  270.       }
  271.     }
  272.   }
  273.   
  274.   return TRUE;
  275. }
  276. void PlayRandomWave()
  277. {
  278.   D3DVECTOR       d3dPosition = D3DVECTOR(0.0f,0.0f,0.0f);
  279.   int RandomWave[]={RANDOM1,RANDOM2,RANDOM3,RANDOM4,RANDOM5,RANDOM6};
  280.   
  281.   d3dPosition.x += (rand() % 2 == 0 ? (rand() % 250) : -(rand() % 250));
  282.   d3dPosition.z += (rand() % 2 == 0 ? (rand() % 250) : -(rand() % 250));
  283.   
  284.   PlaySoundDS(RandomWave[rand() % (sizeof(RandomWave) / sizeof(RandomWave[0]))],d3dPosition,0);
  285.   return;
  286. }
  287. void D3DSoundRelease()
  288. {
  289.   int i;
  290.   for (i = 0; i < NUM_SOUNDS; i ++){
  291.     if (g_lpSounds[i]){       
  292.       g_lpSounds[i]->Release();
  293.       g_lpSounds[i] = NULL;
  294.     }
  295.   }
  296.   for (i = 0; i < NUM_SOUNDS; i ++){
  297.     if (g_lp3dSounds[i]){       
  298.       g_lp3dSounds[i]->Release();
  299.       g_lp3dSounds[i] = NULL;
  300.     }
  301.   }
  302.   if(g_3DSoundBuffer){
  303.     g_3DSoundBuffer->Release();
  304.     g_3DSoundBuffer = NULL;
  305.   }
  306. }