home *** CD-ROM | disk | FTP | other *** search
/ NEXT Generation 27 / NEXT27.iso / pc / demos / emperor / dx3.exe / SDK / SAMPLES / IKLOWNS / CGSOUND.CPP < prev    next >
C/C++ Source or Header  |  1996-08-28  |  21KB  |  703 lines

  1. /*===========================================================================*\
  2. |
  3. |  File:        cgsound.cpp
  4. |
  5. |  Description: 
  6. |   Sample Immortal Klowns game sound effects routines.
  7. |
  8. |   Sound effects are implemented as an object which are
  9. |   loaded from a wave file (.WAV) and can be mixed with 
  10. |   other sounds as well as being algorithmically altered
  11. |   (panned from left to right, pitch changes, and volume 
  12. |   changes).
  13. |
  14. |   For demonstration purposes, sounds may be played using a
  15. |   variety of methods.
  16. |       1) DirectSound - the preferred method, requires
  17. |           that a supported sound board be present
  18. |           and that the DirectSound drivers be installed.
  19. |           Offers greatest flexibility and lowest latency.
  20. |           Doesn't support compressed wave files.
  21. |       2) waveOut - standard Windows API for low-level sound
  22. |           support.  Hardest to code for and not as flexible
  23. |           as DirectSound nor as low in latency.  Assumes
  24. |           similar format for all waves.  Only allows playing
  25. |           one sound at a time (without using WaveMix).
  26. |       3) sndPlaySound  - the simpliest interface which
  27. |           yields the least flexibility and worst latency.
  28. |           Only one sound may be played at a time!
  29. |
  30. |   If desired, individual sounds may be played using different
  31. |   methods (there's no advantage to this, it's just for demos).
  32. |
  33. |-----------------------------------------------------------------------------
  34. |
  35. |  Copyright (C) 1995-1996 Microsoft Corporation.  All Rights Reserved.
  36. |
  37. |  Written by Moss Bay Engineering, Inc. under contract to Microsoft Corporation
  38. |
  39. \*===========================================================================*/
  40.  
  41. /**************************************************************************
  42.  
  43.     (C) Copyright 1995-1996 Microsoft Corp.  All rights reserved.
  44.  
  45.     You have a royalty-free right to use, modify, reproduce and 
  46.     distribute the Sample Files (and/or any modified version) in 
  47.     any way you find useful, provided that you agree that 
  48.     Microsoft has no warranty obligations or liability for any 
  49.     Sample Application Files which are modified. 
  50.  
  51.     we do not recomend you base your game on IKlowns, start with one of
  52.     the other simpler sample apps in the GDK
  53.  
  54.  **************************************************************************/
  55.  
  56. //** include files **
  57. #include <windows.h>
  58. #include <windowsx.h>
  59. #include <mmsystem.h>
  60. #include "linklist.h"
  61. #include "cgwave.h"
  62. #include "cgsound.h"
  63. #include "cgglobl.h"
  64.  
  65. //** local definitions **
  66. // Default volume and panning values
  67. #define MINFREQ_TB              0
  68. #define MAXFREQ_TB              512
  69. #define MINPAN_TB               0
  70. #define MAXPAN_TB               127
  71. #define MIDPAN_TB               64
  72. #define MINVOL_TB               0
  73. #define MAXVOL_TB               127
  74.  
  75. #define INITVOL_TB              0
  76. #define INITPAN_TB              0
  77.  
  78. //** external functions **
  79. //** external data **
  80. //** public data **
  81. BOOL gbQuiet = FALSE;
  82.  
  83. //** private data **
  84.  
  85. // To prevent having more than one instance of the same
  86. // sound in memory, a list of all sounds is kept.
  87. static CLinkedList  *mpWaveList = NULL;
  88.  
  89. // In order to turn off/on sounds we need a list of actively playing
  90. // sounds.
  91. static CLinkedList  *pNowPlayingList = NULL;
  92.  
  93. // Pointer to DirectSound object.
  94. static LPDIRECTSOUND    gpds = NULL;
  95. static LPDIRECTSOUNDBUFFER  lpDSPrimaryBuffer=NULL;
  96.  
  97. // Handle of WaveOut device.
  98. static HWAVEOUT     hWaveDevice = NULL;
  99.  
  100. // ----------------------------------------------------------
  101. // CreatePrimarySoundBuffer - create a primary sound buffer 
  102. //  for direct sound.  Every DirectSound app needs to have
  103. //  one (and only one) DirectSound buffer.
  104. // ----------------------------------------------------------
  105. BOOL CreatePrimarySoundBuffer()
  106. {
  107.     DSBUFFERDESC   dsbd;        // buffer description struct
  108.     MMRESULT            mmResult;   // result of sound calls
  109.  
  110.     // Check if we already have a primary buffer
  111.     if (gpds != NULL)
  112.     {
  113.         return(TRUE);
  114.     }
  115.  
  116.     // Create the Direct Sound Object
  117.     if (DirectSoundCreate(NULL,&gpds, NULL) != 0)
  118.     {
  119.         return(FALSE);
  120.     }
  121.     if( gpds->SetCooperativeLevel( ghMainWnd, DSSCL_NORMAL ) != DS_OK )
  122.     {
  123.            return(FALSE);
  124.     }
  125.  
  126.     // Set up the primary direct sound buffer. 
  127.     memset(&dsbd, 0, sizeof(DSBUFFERDESC));
  128.     dsbd.dwSize = sizeof(DSBUFFERDESC);
  129.     dsbd.dwFlags = DSBCAPS_PRIMARYBUFFER;
  130.     dsbd.dwBufferBytes = 0;
  131.  
  132.     dsbd.lpwfxFormat = NULL;
  133.  
  134.     if ((mmResult = gpds->CreateSoundBuffer(&dsbd,
  135.         &lpDSPrimaryBuffer,
  136.         NULL)) != 0)
  137.     {
  138.         return(FALSE);
  139.     }
  140.  
  141.     return(TRUE);
  142. }
  143.  
  144. // ----------------------------------------------------------
  145. // InitalizeWaveDevice - be sure wave method is ready for use.
  146. // ----------------------------------------------------------
  147. BOOL InitializeWaveDevice(
  148.     int     WaveMode,   // sndPlaySound, waveOut, or DirectSound
  149.     LPWAVEFORMATEX  pFormat     // default wave format
  150. )
  151. {
  152.     // If we are doing waveOut's then we need a handle to the device
  153.     // driver.
  154.     if (WaveMode == USE_WAVEOUT)
  155.     {
  156.  
  157.         // If there isn't a wave device already open, open one
  158.         // using the given format
  159.         if (hWaveDevice == NULL)
  160.         {
  161.             if (waveOutOpen((LPHWAVEOUT)&hWaveDevice
  162.             , WAVE_MAPPER, pFormat, NULL, 0L, 0))
  163.             {
  164.                 return(FALSE);
  165.             }
  166.         }
  167.  
  168.     // Must be using DirectSound, make sure we have a primary buffer
  169.     } else {
  170.  
  171.         if (pNowPlayingList == NULL)
  172.         {
  173.             pNowPlayingList = new CLinkedList;      
  174.         }
  175.  
  176.         // Create a DirectSound primary buffer
  177.         return (CreatePrimarySoundBuffer());
  178.     }
  179.     return(TRUE);
  180. }
  181.  
  182.  
  183. // ----------------------------------------------------------
  184. // LoadWaveData - read .WAV file information into appropriate
  185. //  memory buffer for playback.
  186. // ----------------------------------------------------------
  187. LPWAVEHDR LoadWaveData(
  188.     CSoundEffect    *pSound,    // sound effect instance
  189.     LPSTR       WaveName,   // .WAV filename
  190.     int     WaveMode    // sndPlaySound, waveOut or DirectSound
  191. )
  192. {
  193.     LPBYTE      lpData = NULL;
  194.     LPWAVEHDR   lpWaveHdr = NULL;
  195.     DWORD       dwDataSize = 0;
  196.     LPDIRECTSOUNDBUFFER lpDirectSoundBuffer = NULL;
  197.     LPWAVEFORMATEX  pwfxInfo = NULL;
  198.  
  199.     // Check to be sure a non-null name was given
  200.     if ((WaveName == NULL) || (*WaveName == '\0'))
  201.     {
  202.         return(NULL);
  203.     }
  204.  
  205.     // For sndPlaySound, we just read the whole file into a buffer
  206.     if (WaveMode == USE_SNDPLAY)
  207.     {
  208.         HANDLE  hFile = CreateFile(WaveName, GENERIC_READ, FILE_SHARE_READ
  209.         , NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  210.         if (hFile == INVALID_HANDLE_VALUE)
  211.         {
  212.             return(NULL);
  213.         }
  214.             
  215.         dwDataSize = GetFileSize(hFile, NULL);
  216.         if ((dwDataSize == 0xFFFFFFFF) || (dwDataSize == 0))
  217.         {
  218.             CloseHandle(hFile);
  219.             return(NULL);
  220.         }
  221.  
  222.         // Allocate and lock memory for the waveform data. The memory
  223.         // for waveform data must be globally allocated with
  224.         // GMEM_MOVEABLE and GMEM_SHARE flags.
  225.         if ((lpData = (LPBYTE) GlobalAllocPtr(GMEM_MOVEABLE | GMEM_SHARE
  226.         , dwDataSize)) == NULL)
  227.         {
  228.             CloseHandle(hFile);
  229.             return(NULL);
  230.         }
  231.  
  232.         // Read the whole wave file in 
  233.         ReadFile(hFile, lpData, dwDataSize, &dwDataSize, NULL);
  234.         CloseHandle(hFile);
  235.  
  236.     // Either DirectSound or WaveOut
  237.     } else {
  238.  
  239.         HMMIO       hmmioIn;    
  240.         MMCKINFO    ckInRiff;
  241.         MMCKINFO    ckIn;
  242.         UINT        cbActualRead;
  243.         UINT        cbSize;
  244.  
  245.         pwfxInfo = NULL;
  246.         cbSize = 0;
  247.  
  248.         // Use routines in CGWAVE to open the sound file and
  249.         // parse the data in it.    
  250.         if (WaveOpenFile(WaveName, &hmmioIn, &pwfxInfo, &ckInRiff) != 0)
  251.         {
  252.             if (pwfxInfo != NULL)
  253.                 GlobalFree(pwfxInfo);
  254.             return(NULL);
  255.         }
  256.  
  257.         // Be sure we have an output device ready to play the sound
  258.         if (!InitializeWaveDevice(WaveMode, pwfxInfo))
  259.         {
  260.             mmioClose(hmmioIn, 0);
  261.             if (pwfxInfo != NULL)
  262.                 GlobalFree(pwfxInfo);
  263.             return(NULL);
  264.         }
  265.  
  266.  
  267.         // Position the wave file for reading the wave data
  268.         if (WaveStartDataRead(&hmmioIn, &ckIn, &ckInRiff) != 0)
  269.         {
  270.             mmioClose(hmmioIn, 0);
  271.             if (pwfxInfo != NULL)
  272.                 GlobalFree(pwfxInfo);
  273.             return(NULL);
  274.         }
  275.  
  276.         // Ok, size of wave data is in ckIn, allocate that buffer.
  277.         dwDataSize = ckIn.cksize;
  278.  
  279.         // waveOut requires that we allocate the data
  280.         if (WaveMode == USE_WAVEOUT)
  281.         {
  282.  
  283.             if ((lpData = (LPBYTE)GlobalAlloc(GMEM_FIXED
  284.             , dwDataSize)) == NULL)
  285.             {
  286.                 mmioClose(hmmioIn, 0);
  287.                 if (pwfxInfo != NULL)
  288.                     GlobalFree(pwfxInfo);
  289.                 return(NULL);
  290.             }
  291.         // For DirectSound, we let it allocate the buffer for us.
  292.         } else {
  293.             DSBUFFERDESC    dsbd;
  294.             DWORD   dwBSize;
  295.             DWORD   dwWrapBSize;
  296.             LPVOID  lpWrapPtr;
  297.             DWORD           dw;     // size place holder
  298.             
  299.             // Set up the secondary direct sound buffer. 
  300.             memset(&dsbd, 0, sizeof(DSBUFFERDESC));
  301.             dsbd.dwSize = sizeof(DSBUFFERDESC);
  302.             dsbd.dwFlags = DSBCAPS_CTRLDEFAULT;
  303.             dsbd.dwBufferBytes = dwDataSize;
  304.             dw = pwfxInfo->cbSize + sizeof(WAVEFORMATEX);
  305.  
  306.             if ((dsbd.lpwfxFormat = (LPWAVEFORMATEX)GlobalAllocPtr(GPTR|GMEM_ZEROINIT, dw)) == NULL)
  307.             {
  308.                 mmioClose(hmmioIn, 0);
  309.                 return NULL;
  310.             }
  311.  
  312.             // Setup the format, frequency, volume, etc.
  313.             memcpy( dsbd.lpwfxFormat, pwfxInfo, dw );
  314.  
  315.             if (gpds->CreateSoundBuffer(&dsbd,
  316.                     &lpDirectSoundBuffer,
  317.                     NULL) != 0)
  318.             {
  319.                 GlobalFreePtr(dsbd.lpwfxFormat);
  320.                 mmioClose(hmmioIn, 0);
  321.                 return NULL;
  322.             }
  323.  
  324.             GlobalFreePtr(dsbd.lpwfxFormat);
  325.  
  326.             // Need to lock the buffer so that we can write to it!
  327.             if (lpDirectSoundBuffer->Lock(
  328.                     0,
  329.                     dwDataSize,
  330.                     (LPLPVOID)&lpData,
  331.                     &dwBSize,
  332.                     &lpWrapPtr,
  333.                     &dwWrapBSize,
  334.                     0L) != 0)
  335.             {
  336.                 mmioClose(hmmioIn, 0);
  337.                 return NULL;
  338.             } else {
  339.                 dwDataSize = dwBSize;
  340.             }
  341.         }
  342.  
  343.         // Now read the actual wave data into the data buffer.
  344.         if (WaveReadFile(hmmioIn, dwDataSize, lpData, &ckIn
  345.         , &cbActualRead) != 0)
  346.         {
  347.             // Data didn't get read for some reason!
  348.             if (pwfxInfo != NULL)
  349.                 GlobalFree(pwfxInfo);
  350.             if (lpData != NULL)
  351.                 GlobalFree(lpData);
  352.         }    
  353.  
  354.         // Save info on size of data and close the wave file    
  355.         cbSize = cbActualRead;
  356.         dwDataSize = cbSize;
  357.         mmioClose(hmmioIn, 0);
  358.  
  359.         // If we have a DirectSound buffer, set format & unlock it.
  360.       if (lpDirectSoundBuffer != NULL)
  361.         {
  362.          lpDirectSoundBuffer->Unlock(lpData, cbActualRead, NULL, 0 );
  363.         }
  364.  
  365.     }
  366.  
  367.     // Allocate and lock memory for the header. This memory must
  368.     // also be globally allocated with GMEM_MOVEABLE and GMEM_SHARE flags.
  369.     if ((lpWaveHdr = (LPWAVEHDR) GlobalAllocPtr(GMEM_MOVEABLE | GMEM_SHARE
  370.     , (DWORD)sizeof(WAVEHDR))) == NULL) {
  371.         GlobalFreePtr(lpData);
  372.         return(NULL);
  373.     }
  374.  
  375.     // After allocation, set up and prepare header.  This struct will be
  376.     // used to play the sounds at the appropriate time.
  377.     lpWaveHdr->lpData = (LPSTR) lpData;
  378.     lpWaveHdr->dwBufferLength = dwDataSize;
  379.     lpWaveHdr->dwFlags = DSBCAPS_CTRLDEFAULT;
  380.     lpWaveHdr->dwLoops = 0L;
  381.  
  382.     pSound->pWaveInfo->lpDirectSoundBuffer = lpDirectSoundBuffer;
  383.     pSound->pWaveInfo->pwfxInfo = pwfxInfo;
  384.  
  385.     return(lpWaveHdr);
  386. }   
  387.  
  388. // ----------------------------------------------------------
  389. // CSoundEffect constructor
  390. // ----------------------------------------------------------
  391. CSoundEffect::CSoundEffect(
  392.     LPSTR   WaveName,   // name of wave file
  393.     DWORD   Id,     // object id to allow one buffer per object
  394.     BOOL    fLoopIt,    // loop the sound when played
  395.     int WaveMode    // sndPlaySound, waveOut or DirectSound 
  396. )
  397. {
  398.     pWaveInfo = NULL;
  399.     fLoop = fLoopIt;
  400.     fPlaying = FALSE;
  401.  
  402.     // Guard against wise-guys (we don't mind)
  403.     if ((WaveName == NULL) || (*WaveName == '\0'))
  404.         return;
  405.  
  406.     CSoundEffect::WaveMode = WaveMode;
  407.     curVolume = MAXVOL_TB;
  408.     fMuted = FALSE;
  409.  
  410.     // initialize wave list if necessary
  411.     if (!mpWaveList)
  412.     {
  413.         mpWaveList = new CLinkedList;
  414.     } else {
  415.         // Need to search wave list to see if we already have this
  416.         // wave data cached.
  417.         WAVE_ENTRY  *pCurBuffer = (WAVE_ENTRY *) mpWaveList->GetFirst();
  418.  
  419.         while (pCurBuffer && !pWaveInfo)
  420.         {
  421.             // Do the name and mode match?
  422.             if ((lstrcmpi( WaveName, pCurBuffer->mpFileName ) == 0 )
  423.             && (pCurBuffer->hObjectId == Id)
  424.             && (pCurBuffer->WaveMode == WaveMode))
  425.             {
  426.                 pCurBuffer->mRefCount++;
  427.                 pWaveInfo = pCurBuffer;
  428.             } else {
  429.                 pCurBuffer = (WAVE_ENTRY *) mpWaveList->GetNext();
  430.             }
  431.         }
  432.     }
  433.  
  434.     // if we didn't find the wave file in our cache, we need to load it
  435.     if (!pWaveInfo)
  436.     {
  437.         LPWAVEHDR   pWaveHdr;
  438.         pWaveInfo = new WAVE_ENTRY;
  439.  
  440.         // Load up the wave data            
  441.         if (pWaveHdr = LoadWaveData(this, WaveName, WaveMode))
  442.         {
  443.             // Add to list of known sounds
  444.             pWaveInfo->mpFileName = new char [lstrlen(WaveName)+1];
  445.             lstrcpy(pWaveInfo->mpFileName, WaveName);
  446.             pWaveInfo->pWaveHdr = pWaveHdr;
  447.             pWaveInfo->WaveMode = WaveMode;
  448.             pWaveInfo->hObjectId = Id;
  449.             pWaveInfo->mRefCount = 1;
  450.             mpWaveList->Append( pWaveInfo );
  451.             lpDirectSoundBuffer = pWaveInfo->lpDirectSoundBuffer;
  452.         } else {
  453.             delete pWaveInfo;
  454.             pWaveInfo = NULL;
  455.         }
  456.     } else  {
  457.         lpDirectSoundBuffer = pWaveInfo->lpDirectSoundBuffer;
  458.     }
  459. }
  460.  
  461. // ----------------------------------------------------------
  462. // CSoundEffect destructor
  463. // ----------------------------------------------------------
  464. CSoundEffect::~CSoundEffect()
  465. {
  466.     Stop();
  467.  
  468.     if ((pWaveInfo != NULL) && (--pWaveInfo->mRefCount == 0))
  469.     {
  470.         mpWaveList->Remove( pWaveInfo );
  471.  
  472.         delete pWaveInfo->mpFileName;
  473.         if (lpDirectSoundBuffer != NULL)
  474.         {
  475.          lpDirectSoundBuffer->Release();
  476.         } else {
  477.             GlobalFreePtr(pWaveInfo->pWaveHdr->lpData);
  478.         }
  479.         GlobalFreePtr(pWaveInfo->pwfxInfo);
  480.         GlobalFreePtr(pWaveInfo->pWaveHdr);
  481.         delete pWaveInfo;       // causes GP fault why?
  482.         pWaveInfo = NULL;
  483.         // !!! should we delete the list if empty?
  484.     }
  485. }
  486.  
  487. // ----------------------------------------------------------
  488. // Play - 
  489. // ----------------------------------------------------------
  490. void CSoundEffect::Play()
  491. {
  492.     if ((pWaveInfo == NULL) || (gbQuiet))
  493.     {
  494.         return;
  495.     }
  496.  
  497.     fPlaying = TRUE;
  498.  
  499.     switch (WaveMode)
  500.     {
  501.     case USE_WAVEOUT:
  502.         if (pWaveInfo->pWaveHdr != NULL)
  503.         {
  504.             pWaveInfo->pWaveHdr->dwLoops = fLoop;
  505.             waveOutPrepareHeader(hWaveDevice, pWaveInfo->pWaveHdr, sizeof(WAVEHDR));
  506.             waveOutWrite(hWaveDevice, pWaveInfo->pWaveHdr, sizeof(WAVEHDR));
  507.             waveOutUnprepareHeader(hWaveDevice, pWaveInfo->pWaveHdr, sizeof(WAVEHDR));
  508.         }
  509.         break;
  510.  
  511.     case USE_DSOUND:
  512.         if (lpDirectSoundBuffer != NULL)
  513.         {
  514.  
  515.             // Add sound to active list if it isn't already there
  516.             CSoundEffect *pTemp = (CSoundEffect *)pNowPlayingList->GetFirst();
  517.             while (pTemp != NULL)
  518.             {
  519.                 if (pTemp == this)
  520.                 {
  521.                     break;
  522.                 }
  523.                 pTemp = (CSoundEffect *)pNowPlayingList->GetNext();
  524.             }
  525.  
  526.             if (pTemp == NULL)
  527.             {
  528.                 pNowPlayingList->Add(this);
  529.             }
  530.  
  531.            if( fLoop )
  532.             {
  533.              lpDirectSoundBuffer->SetCurrentPosition( 0 );
  534.              lpDirectSoundBuffer->Play(0, 0, DSBPLAY_LOOPING);
  535.             }
  536.             else
  537.             {
  538.              lpDirectSoundBuffer->SetCurrentPosition( 0 );
  539.              lpDirectSoundBuffer->Play(0, 0, 0);
  540.             }
  541.         }
  542.         break;
  543.  
  544.     case USE_SNDPLAY:
  545.         if (pWaveInfo->pWaveHdr != NULL)
  546.         {
  547.             UINT    flags = SND_MEMORY | SND_ASYNC;
  548.  
  549.             if (fLoop)
  550.                 flags |= SND_LOOP;
  551.  
  552.             sndPlaySound((LPSTR)(pWaveInfo->pWaveHdr->lpData), flags);
  553.         }
  554.         break;
  555.     }
  556. }
  557.  
  558. // ----------------------------------------------------------
  559. // Stop - 
  560. // ----------------------------------------------------------
  561. void CSoundEffect::Stop()
  562. {
  563.     if ((pWaveInfo == NULL) || (!fPlaying))
  564.     {
  565.         return;
  566.     }
  567.  
  568.     fPlaying = FALSE;
  569.  
  570.     switch (WaveMode)
  571.     {
  572.     case USE_WAVEOUT:
  573.         if (pWaveInfo->pWaveHdr != NULL)
  574.         {
  575.             waveOutReset(hWaveDevice);
  576.         }
  577.         break;
  578.     case USE_DSOUND:
  579.         if (lpDirectSoundBuffer != NULL)
  580.         {
  581.             pNowPlayingList->Remove(this);
  582.             lpDirectSoundBuffer->Stop();
  583.         }
  584.                 break;
  585.  
  586.     case USE_SNDPLAY:
  587.         if (pWaveInfo->pWaveHdr != NULL)
  588.         {
  589.             sndPlaySound(NULL, SND_ASYNC);
  590.         }
  591.         break;
  592.     }
  593. }
  594.  
  595. // ----------------------------------------------------------
  596. // SetPan - 
  597. // ----------------------------------------------------------
  598. void CSoundEffect::SetPan(int PanFactor)
  599. {
  600. //  if ((pWaveInfo == NULL) || (curPan == PanFactor))
  601.     if (pWaveInfo == NULL)
  602.     {
  603.         return;
  604.     }
  605.  
  606.     curPan = PanFactor;
  607.  
  608.     switch (WaveMode)
  609.     {
  610.     case USE_WAVEOUT:
  611.         break;
  612.     case USE_DSOUND:
  613.         if (lpDirectSoundBuffer != NULL)
  614.         {
  615.             // parameter pan is 0-127; dsound's pan is -10000 to +10000
  616.             long    absPan;
  617.             absPan = (10000 * ((curPan-64)>>2)) / 128;
  618.                         lpDirectSoundBuffer->SetPan(absPan);
  619.         }
  620.         break;
  621.     case USE_SNDPLAY:
  622.         break;
  623.     }
  624. }
  625.  
  626.  
  627. // ----------------------------------------------------------
  628. // SetVolume - 
  629. // ----------------------------------------------------------
  630. void CSoundEffect::SetVolume(int Volume)
  631. {
  632.     if ((pWaveInfo == NULL)  || (curVolume == Volume))
  633.     {
  634.         return;
  635.     }
  636.  
  637.     curVolume = Volume;
  638.     switch (WaveMode)
  639.     {
  640.     case USE_WAVEOUT:
  641.         break;
  642.     case USE_DSOUND:
  643.         if (lpDirectSoundBuffer != NULL)
  644.         {
  645.             // parameter volume is 0-127; dsound's volume is -10000 to 0
  646.             long    absVolume;
  647.             absVolume = -((127-curVolume)<<4);
  648.                         lpDirectSoundBuffer->SetVolume(absVolume);
  649.         }
  650.         break;
  651.     case USE_SNDPLAY:
  652.         break;
  653.     }
  654. }
  655.  
  656.  
  657. // ----------------------------------------------------------
  658. // SetMute - 
  659. // ----------------------------------------------------------
  660. void CSoundEffect::SetMute(BOOL fMute)
  661. {
  662.  
  663.     if ((pWaveInfo == NULL) || (fMuted == fMute))
  664.     {
  665.         return;
  666.     }
  667.     
  668.     fMuted = fMute;
  669.  
  670.     if (fMuted)
  671.     {
  672.         Stop();
  673.     } else {
  674.         Play();
  675.     }
  676. }
  677.  
  678. void SetSilence(BOOL fQuiet)
  679. {
  680.     gbQuiet = fQuiet;
  681.     if (lpDSPrimaryBuffer != NULL)
  682.     {
  683.         CSoundEffect *lpSound = (CSoundEffect *)pNowPlayingList->GetFirst();
  684.         while (lpSound != NULL)
  685.         {
  686.  
  687.             if (fQuiet)
  688.             {
  689.                     lpSound->lpDirectSoundBuffer->Stop();
  690.             } else {
  691.                 if (lpSound->fLoop)
  692.                 {
  693.                 lpSound->lpDirectSoundBuffer->Play(0, 0, DSBPLAY_LOOPING);
  694.                 } else {
  695.                 lpSound->lpDirectSoundBuffer->Play(0, 0, 0);
  696.                 }
  697.             }
  698.  
  699.             lpSound = (CSoundEffect *)pNowPlayingList->GetNext();
  700.         }
  701.     }
  702. }
  703.