SoundManager.cpp
上传用户:royluo
上传日期:2007-01-05
资源大小:1584k
文件大小:12k
源码类别:

游戏

开发平台:

Visual C++

  1. /*****************************************************************************
  2. *                                                                             
  3. *   SoundManager.cpp
  4. *                                                                             
  5. *   Electrical Engineering Faculty - Software Lab                             
  6. *   Spring semester 1998                                                      
  7. *                                                                             
  8. *   Tanks game                                                                
  9. *                                                                             
  10. *   Module description: Manages the DirectSound objects.
  11. *                       
  12. *                                                                             
  13. *   Authors: Eran Yariv - 28484475                                           
  14. *            Moshe Zur  - 24070856                                           
  15. *                                                                            
  16. *                                                                            
  17. *   Date: 23/09/98                                                           
  18. *                                                                            
  19. ******************************************************************************/
  20. #include "stdafx.h"
  21. #include "mmsystem.h"
  22. #include "SoundManager.h"
  23. LPCSTR CSoundManager::m_aszSoundFileNames[] =
  24. {
  25.     "FIRE_BULLET", 
  26.     "FIRE_SHELL", 
  27.     "SHELL_EXPLODE",
  28.     "MINE_EXPLODE",
  29.     "TANK_EXPLODE",
  30.     "DROP_BOMB",
  31.     "PICK_BONUS",
  32.     "GAME_OVER"
  33. };
  34. CSoundManager::CSoundManager() :
  35. m_pDirectSound(NULL),
  36. m_bMuteMode(FALSE)
  37. {}
  38. /*------------------------------------------------------------------------------
  39.   Function: Init
  40.   Purpose:  Initialize DirectSound objects.
  41.   Input:    hWnd - Handle to main window
  42.   Output:   Return TRUE if initializtion succeeded.
  43.   Remarks:  
  44. ------------------------------------------------------------------------------*/
  45. BOOL
  46. CSoundManager::Init(HWND hWnd)
  47. {
  48.     ASSERT (! m_pDirectSound);
  49.     if (m_pDirectSound)
  50.         m_pDirectSound->Release();
  51.     // Create DirectSound object
  52.     if (DirectSoundCreate (NULL, &m_pDirectSound, NULL) == DS_OK)
  53.     {
  54.         // Set cooperative level for DirectSound. Normal means our
  55.         // sounds will be silenced when our window loses input focus.
  56.         if (m_pDirectSound->SetCooperativeLevel (hWnd, //AfxGetMainWnd()->m_hWnd,
  57.                 DSSCL_NORMAL) != DS_OK)
  58.         {
  59.             m_pDirectSound->Release();
  60.             m_pDirectSound = NULL;
  61.             return FALSE;
  62.         }
  63.     } else
  64.     {
  65.         m_pDirectSound = NULL;
  66.         return FALSE;
  67.     }
  68.     // Load each wav files into DirectSound buffers:
  69.     for (UINT i = 0; i < LAST_SOUND_TYPE; i++)
  70.     {
  71.         LoadWavToBuffer((SoundType)i);
  72.     }
  73.     return TRUE;
  74. }
  75. CSoundManager::~CSoundManager()
  76. {
  77.     // Release DirectSound interface (auto. release the sec. buffers):
  78.     if (m_pDirectSound)
  79.         m_pDirectSound->Release();
  80. }
  81. /*------------------------------------------------------------------------------
  82.   Function: Play
  83.   Purpose:  Play the 2nd buffer specified.
  84.   Input:    ind - Index to 2nd buffer.
  85.   Output:   None.
  86.   Remarks:  Restarts to play buffer if called while buffer is playing.
  87. ------------------------------------------------------------------------------*/
  88. void
  89. CSoundManager::Play(CSoundManager::SoundType ind)
  90. {
  91.     // Check if play is anabled:
  92.     if (m_bMuteMode || !m_pDirectSound)
  93.         return;
  94.     ASSERT (ind < LAST_SOUND_TYPE);
  95.     if (ind >= LAST_SOUND_TYPE)
  96.         return;
  97.     // Play buffer(ind):
  98.     if (m_aSoundBuffers[ind])
  99.     {
  100. //        m_aSoundBuffers[ind]->Stop();
  101.         m_aSoundBuffers[ind]->SetCurrentPosition(0);
  102.         m_aSoundBuffers[ind]->Play(0, 0, 0);
  103.     }
  104. }
  105. /*------------------------------------------------------------------------------
  106.   Function: LoadWavToBuffer
  107.   Purpose:  Do all the dirty job - open the wav file and load it into its buffer.
  108.   Input:    ind - Index to 2nd buffer.
  109.   Output:   None.
  110.   Remarks:  
  111. ------------------------------------------------------------------------------*/
  112. void
  113. CSoundManager::LoadWavToBuffer(CSoundManager::SoundType ind)
  114. {
  115.     HMMIO           hmmio       = NULL;
  116.     MMCKINFO        mmckinfoParent;
  117.     MMCKINFO        mmckinfoSubchunk;
  118.     DWORD           dwFmtSize;
  119.     LPCSTR          szFileName;
  120.     HANDLE          hFormat     = NULL;
  121.     WAVEFORMATEX   *pFormat     = NULL;
  122.     HANDLE          hData       = NULL;
  123.     HPSTR           lpData      = NULL;
  124.     BYTE           *pbData      = NULL;
  125.     BYTE           *pbData2     = NULL;
  126.     DWORD           dwDataSize;
  127.     WORD            wBlockSize;
  128.     DWORD           dwLength;
  129.     DWORD           dwLength2;
  130.     m_aSoundBuffers[ind] = NULL;
  131.     szFileName = m_aszSoundFileNames[ind];
  132.     //
  133.     //  Load WAVE files from resource
  134.     //
  135.     HANDLE      hRes    = NULL;
  136.     HANDLE      hBuffer = NULL;
  137.     LPSTR       lpRes   = NULL;
  138.     HRSRC       hResInfo;
  139.     HINSTANCE   hInst   = AfxGetInstanceHandle();
  140.     MMIOINFO    mmioInfo;
  141.     // Find the wav resource
  142.     hResInfo = FindResource(hInst, (LPSTR)szFileName, "WAVE");
  143.     if (!hResInfo)
  144.     {
  145.         TRACE("SoundManager: Failed to find resource file %s.n", szFileName);
  146.         return;
  147.     }
  148.     // Load the wav resource
  149.     hRes = LoadResource(hInst, hResInfo);
  150.     if (!hRes)
  151.     {
  152.         TRACE("SoundManager: Failed to load resource file %s.n", szFileName);
  153.         return;
  154.     }
  155.     // Lock the wav resource
  156.     lpRes = (LPSTR)LockResource(hRes);
  157.     if (!lpRes)
  158.     {
  159.         TRACE("SoundManager: Failed to lock resource.n");
  160.         goto CLEANUP;
  161.     }
  162.     //
  163.     //  Read the wav file into memory:
  164.     //
  165.     // Prepare memory for reading using buffered I/O:
  166.     ZeroMemory (&mmioInfo, sizeof(mmioInfo));
  167.     mmioInfo.fccIOProc = FOURCC_MEM;
  168.     mmioInfo.pchBuffer = (LPSTR)lpRes;
  169.     mmioInfo.cchBuffer = SizeofResource(hInst, hResInfo);
  170.     hBuffer = GlobalAlloc (LMEM_MOVEABLE, mmioInfo.cchBuffer);
  171.     if (!hBuffer)
  172.     {
  173.         TRACE("SoundManager: Out of memory.n");
  174.         goto CLEANUP;
  175.     }
  176.     mmioInfo.pchBuffer = (LPSTR) GlobalLock(hBuffer);
  177.     if (!mmioInfo.pchBuffer)
  178.     {
  179.         TRACE("SoundManager: Failed to lock memory for buffer.n");
  180.         goto CLEANUP;
  181.     }
  182.     memcpy (mmioInfo.pchBuffer, lpRes, mmioInfo.cchBuffer);
  183.     if (!mmioInfo.cchBuffer)
  184.     {
  185.         TRACE("SoundManager: Failed to get resource size (Error=%d).n", 
  186.             GetLastError());
  187.         goto CLEANUP;
  188.     }
  189.     hmmio = mmioOpen(NULL, &mmioInfo, MMIO_READWRITE /*| MMIO_ALLOCBUF*/);
  190.     if(!hmmio)
  191.     {
  192.         TRACE("SoundManager: Failed to open file %s.n", szFileName);
  193.         return;
  194.     }
  195.     // Locate a 'RIFF' chunk with a 'WAVE' form type
  196.     // to make sure it's a WAVE file.
  197.     mmckinfoParent.fccType = mmioFOURCC('W', 'A', 'V', 'E');
  198.     if (mmioDescend(hmmio, (LPMMCKINFO) &mmckinfoParent, NULL, MMIO_FINDRIFF))
  199.     {
  200.         TRACE("SoundManager: This is not a WAVE file.n");
  201.         goto CLEANUP;
  202.     }
  203.     // Now, find the format chunk (form type 'fmt '). It should be
  204.     // a subchunk of the 'RIFF' parent chunk.
  205.     mmckinfoSubchunk.ckid = mmioFOURCC('f', 'm', 't', ' ');
  206.     if (mmioDescend(hmmio, &mmckinfoSubchunk, &mmckinfoParent,
  207.         MMIO_FINDCHUNK))
  208.     {
  209.         TRACE("SoundManager: WAVE file is corrupted.n");
  210.         goto CLEANUP;
  211.     }
  212.     // Get the size of the format chunk, allocate and lock memory for it.
  213.     dwFmtSize = mmckinfoSubchunk.cksize;
  214.     hFormat = GlobalAlloc(LMEM_MOVEABLE, LOWORD(dwFmtSize));
  215.     if (!hFormat)
  216.     {
  217.         TRACE("SoundManager: Out of memory.n");
  218.         goto CLEANUP;
  219.     }
  220.     pFormat = (WAVEFORMATEX *) GlobalLock(hFormat);
  221.     if (!pFormat)
  222.     {
  223.         TRACE("SoundManager: Failed to lock memory for format chunk.n");
  224.         goto CLEANUP;
  225.     }
  226.     // Read the format chunk.
  227.     if (mmioRead(hmmio, (HPSTR) pFormat, dwFmtSize) != (LONG) dwFmtSize)
  228.     {
  229.         TRACE("SoundManager: Failed to read format chunk.n");
  230.         goto CLEANUP;
  231.     }
  232.     // Make sure it's a PCM file.
  233.     if (pFormat->wFormatTag != WAVE_FORMAT_PCM)
  234.     {
  235.         TRACE("SoundManager: The file is not a PCM file.n");
  236.         goto CLEANUP;
  237.     }
  238.     // Ascend out of the format subchunk.
  239.     mmioAscend(hmmio, &mmckinfoSubchunk, 0);
  240.     // Find the data subchunk.
  241.     mmckinfoSubchunk.ckid = mmioFOURCC('d', 'a', 't', 'a');
  242.     if (mmioDescend(hmmio, &mmckinfoSubchunk, &mmckinfoParent,
  243.         MMIO_FINDCHUNK))
  244.     {
  245.         TRACE("SoundManager: WAVE file has no data chunk.n");
  246.         goto CLEANUP;
  247.     }
  248.     // Get the size of the data subchunk.
  249.     dwDataSize = mmckinfoSubchunk.cksize;
  250.     if (dwDataSize == 0L)
  251.     {
  252.         TRACE("SoundManager: The data chunk has no data.n");
  253.         goto CLEANUP;
  254.     }
  255.     // Save block alignment info for later use.
  256.     wBlockSize = pFormat->nBlockAlign;
  257.     // Allocate and lock memory for the waveform data.
  258.     hData = GlobalAlloc(GMEM_MOVEABLE , dwDataSize );
  259.                        // GMEM_SHARE is not needed on 32 bits
  260.     if (!hData)
  261.     {
  262.         TRACE("SoundManager: Out of memory.n");
  263.         goto CLEANUP;
  264.     }
  265.     lpData = (char *)GlobalLock(hData);
  266.     if (!lpData)
  267.     {
  268.         TRACE("SoundManager: Failed to lock memory for data chunk.n");
  269.         goto CLEANUP;
  270.     }
  271.     // Read the waveform data subchunk.
  272.     if(mmioRead(hmmio, (HPSTR) lpData, dwDataSize) != (LONG) dwDataSize)
  273.     {
  274.         TRACE("SoundManager: Failed to read data chunk.n");
  275.         goto CLEANUP;
  276.     }
  277.     //
  278.     //  Create DirectSoundBuffer:
  279.     //
  280.     DSBUFFERDESC dsbd;
  281.     
  282.     //DS Now create the secondary buffer
  283.     memset(&dsbd, 0, sizeof(DSBUFFERDESC));
  284.     dsbd.dwSize       = sizeof(DSBUFFERDESC);
  285.     dsbd.dwFlags      = DSBCAPS_CTRLDEFAULT ;
  286.     dsbd.dwBufferBytes= dwDataSize; // size of the audio data in bytes
  287.     dsbd.lpwfxFormat  = pFormat;    
  288.     if (m_pDirectSound->CreateSoundBuffer(
  289.         &dsbd, 
  290.         &m_aSoundBuffers[ind],
  291.         NULL) != 0)
  292.     {
  293.         TRACE("SoundManager: Direct Sound Buffer Creation Failedn");
  294.         goto CLEANUP;
  295.     }
  296.     ASSERT (m_aSoundBuffers[ind]);    
  297.     //
  298.     //  Copy data to buffer:
  299.     //
  300.     if (m_aSoundBuffers[ind]->Lock
  301.                   ( 0,                      // the position to start to lock
  302.                     dwDataSize,             // number of bytes to lock
  303.                     (PVOID *)&pbData,       // pbData will point to the memory area
  304.                     &dwLength,              // number of bytes to use under pbData
  305.                     (PVOID *)&pbData2,      // not used since no wrap around
  306.                     &dwLength2,             // not used since no wrap around
  307.                     0L) != DS_OK)
  308.     {
  309.         TRACE("SoundManager: Sound buffer Lock Failed.n");
  310.         goto CLEANUP;
  311.     }
  312.     // Now we can copy data into the area by, say, memcpy function
  313.     memcpy(pbData, lpData, dwLength);
  314.     // Unlock it
  315.     if (m_aSoundBuffers[ind]->Unlock(pbData, dwLength, NULL, 0) != DS_OK)
  316.     {
  317.         TRACE("SoundManager: Sound buffer Unlock Failed.n");
  318.     }
  319. CLEANUP:
  320.     if (hRes)
  321.         FreeResource(hRes);
  322.     if (hFormat)
  323.     {
  324.         LocalUnlock( hFormat );
  325.         LocalFree( hFormat );
  326.     }
  327.     if (hData)
  328.     {
  329.         GlobalUnlock( hData );
  330.         GlobalFree( hData );
  331.     }
  332.     if (hBuffer)
  333.     {
  334.         GlobalUnlock( hBuffer );
  335.         GlobalFree( hBuffer );
  336.     }
  337.     if (hmmio)
  338.         mmioClose(hmmio, 0);
  339.     return;
  340. }