Main Page | Class Hierarchy | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

win_snd.c File Reference

#include <float.h>
#include "../client/snd_local.h"
#include "win_local.h"

Include dependency graph for win_snd.c:

Include dependency graph

Go to the source code of this file.

Defines

#define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8)
#define iDirectSoundCreate(a, b, c)   pDirectSoundCreate(a,b,c)
#define SECONDARY_BUFFER_SIZE   0x10000

Functions

 DEFINE_GUID (IID_IDirectSound, 0x279AFA83, 0x4981, 0x11CE, 0xA5, 0x21, 0x00, 0x20, 0xAF, 0x0B, 0xE5, 0x60)
 DEFINE_GUID (IID_IDirectSound8, 0xC50A7E93, 0xF395, 0x4834, 0x9E, 0xF6, 0x7F, 0xA9, 0x9D, 0xE5, 0x09, 0x66)
 DEFINE_GUID (CLSID_DirectSound8, 0x3901cc3f, 0x84b5, 0x4fa4, 0xba, 0x35, 0xaa, 0x81, 0x72, 0xb8, 0xa0, 0x9b)
 DEFINE_GUID (CLSID_DirectSound, 0x47d4d946, 0x62e8, 0x11cf, 0x93, 0xbc, 0x44, 0x45, 0x53, 0x54, 0x0, 0x0)
const char * DSoundError (int error)
 HRESULT (WINAPI *pDirectSoundCreate)(GUID FAR *lpGUID
void SNDDMA_Activate (void)
void SNDDMA_BeginPainting (void)
int SNDDMA_GetDMAPos (void)
qboolean SNDDMA_Init (void)
int SNDDMA_InitDS ()
void SNDDMA_Shutdown (void)
void SNDDMA_Submit (void)

Variables

qboolean dsound_init
DWORD gSndBufSize
HINSTANCE hInstDS
DWORD locksize
LPDIRECTSOUND FAR * lplpDS
LPDIRECTSOUND pDS
LPDIRECTSOUNDBUFFER pDSBuf
LPDIRECTSOUNDBUFFER pDSPBuf
LPDIRECTSOUND FAR IUnknown
FAR * 
pUnkOuter
int sample16


Define Documentation

#define DEFINE_GUID name,
l,
w1,
w2,
b1,
b2,
b3,
b4,
b5,
b6,
b7,
b8   ) 
 

Value:

EXTERN_C const GUID name \
                = { l, w1, w2, { b1, b2,  b3,  b4,  b5,  b6,  b7,  b8 } }

Definition at line 137 of file win_snd.c.

#define iDirectSoundCreate a,
b,
 )     pDirectSoundCreate(a,b,c)
 

Definition at line 28 of file win_snd.c.

#define SECONDARY_BUFFER_SIZE   0x10000
 

Definition at line 30 of file win_snd.c.


Function Documentation

DEFINE_GUID IID_IDirectSound  ,
0x279AFA83  ,
0x4981  ,
0x11CE  ,
0xA5  ,
0x21  ,
0x00  ,
0x20  ,
0xAF  ,
0x0B  ,
0xE5  ,
0x60 
 

DEFINE_GUID IID_IDirectSound8  ,
0xC50A7E93  ,
0xF395  ,
0x4834  ,
0x9E  ,
0xF6  ,
0x7F  ,
0xA9  ,
0x9D  ,
0xE5  ,
0x09  ,
0x66 
 

DEFINE_GUID CLSID_DirectSound8  ,
0x3901cc3f  ,
0x84b5  ,
0x4fa4  ,
0xba  ,
0x35  ,
0xaa  ,
0x81  ,
0x72  ,
0xb8  ,
0xa0  ,
0x9b 
 

DEFINE_GUID CLSID_DirectSound  ,
0x47d4d946  ,
0x62e8  ,
0x11cf  ,
0x93  ,
0xbc  ,
0x44  ,
0x45  ,
0x53  ,
0x54  ,
0x0  ,
0x0 
 

const char* DSoundError int  error  )  [static]
 

Definition at line 42 of file win_snd.c.

Referenced by SNDDMA_BeginPainting().

00042                                             {
00043     switch ( error ) {
00044     case DSERR_BUFFERLOST:
00045         return "DSERR_BUFFERLOST";
00046     case DSERR_INVALIDCALL:
00047         return "DSERR_INVALIDCALLS";
00048     case DSERR_INVALIDPARAM:
00049         return "DSERR_INVALIDPARAM";
00050     case DSERR_PRIOLEVELNEEDED:
00051         return "DSERR_PRIOLEVELNEEDED";
00052     }
00053 
00054     return "unknown";
00055 }

HRESULT WINAPI *  pDirectSoundCreate  ) 
 

void SNDDMA_Activate void   ) 
 

Definition at line 377 of file win_snd.c.

References Com_Printf(), g_wv, WinVars_t::hWnd, pDS, and SNDDMA_Shutdown().

00377                              {
00378     if ( !pDS ) {
00379         return;
00380     }
00381 
00382     if ( DS_OK != pDS->lpVtbl->SetCooperativeLevel( pDS, g_wv.hWnd, DSSCL_PRIORITY ) )  {
00383         Com_Printf ("sound SetCooperativeLevel failed\n");
00384         SNDDMA_Shutdown ();
00385     }
00386 }

Here is the call graph for this function:

void SNDDMA_BeginPainting void   ) 
 

Definition at line 307 of file win_snd.c.

References dma_t::buffer, Com_Printf(), dma, DSoundError(), DWORD, gSndBufSize, HRESULT(), locksize, pDSBuf, and S_Shutdown().

Referenced by S_ClearSoundBuffer(), S_Update_(), and SNDDMA_InitDS().

00307                                   {
00308     int     reps;
00309     DWORD   dwSize2;
00310     DWORD   *pbuf, *pbuf2;
00311     HRESULT hresult;
00312     DWORD   dwStatus;
00313 
00314     if ( !pDSBuf ) {
00315         return;
00316     }
00317 
00318     // if the buffer was lost or stopped, restore it and/or restart it
00319     if ( pDSBuf->lpVtbl->GetStatus (pDSBuf, &dwStatus) != DS_OK ) {
00320         Com_Printf ("Couldn't get sound buffer status\n");
00321     }
00322     
00323     if (dwStatus & DSBSTATUS_BUFFERLOST)
00324         pDSBuf->lpVtbl->Restore (pDSBuf);
00325     
00326     if (!(dwStatus & DSBSTATUS_PLAYING))
00327         pDSBuf->lpVtbl->Play(pDSBuf, 0, 0, DSBPLAY_LOOPING);
00328 
00329     // lock the dsound buffer
00330 
00331     reps = 0;
00332     dma.buffer = NULL;
00333 
00334     while ((hresult = pDSBuf->lpVtbl->Lock(pDSBuf, 0, gSndBufSize, &pbuf, &locksize, 
00335                                    &pbuf2, &dwSize2, 0)) != DS_OK)
00336     {
00337         if (hresult != DSERR_BUFFERLOST)
00338         {
00339             Com_Printf( "SNDDMA_BeginPainting: Lock failed with error '%s'\n", DSoundError( hresult ) );
00340             S_Shutdown ();
00341             return;
00342         }
00343         else
00344         {
00345             pDSBuf->lpVtbl->Restore( pDSBuf );
00346         }
00347 
00348         if (++reps > 2)
00349             return;
00350     }
00351     dma.buffer = (unsigned char *)pbuf;
00352 }

Here is the call graph for this function:

int SNDDMA_GetDMAPos void   ) 
 

Definition at line 279 of file win_snd.c.

References dma, DWORD, pDSBuf, s, and dma_t::samples.

Referenced by S_GetSoundtime().

00279                              {
00280     MMTIME  mmtime;
00281     int     s;
00282     DWORD   dwWrite;
00283 
00284     if ( !dsound_init ) {
00285         return 0;
00286     }
00287 
00288     mmtime.wType = TIME_SAMPLES;
00289     pDSBuf->lpVtbl->GetCurrentPosition(pDSBuf, &mmtime.u.sample, &dwWrite);
00290 
00291     s = mmtime.u.sample;
00292 
00293     s >>= sample16;
00294 
00295     s &= (dma.samples-1);
00296 
00297     return s;
00298 }

qboolean SNDDMA_Init void   ) 
 

Definition at line 117 of file win_snd.c.

References Com_DPrintf(), dma, dsound_init, memset(), NULL, qboolean, and SNDDMA_InitDS().

Referenced by S_Init().

00117                            {
00118 
00119     memset ((void *)&dma, 0, sizeof (dma));
00120     dsound_init = 0;
00121 
00122     CoInitialize(NULL);
00123 
00124     if ( !SNDDMA_InitDS () ) {
00125         return qfalse;
00126     }
00127 
00128     dsound_init = qtrue;
00129 
00130     Com_DPrintf("Completed successfully\n" );
00131 
00132     return qtrue;
00133 }

Here is the call graph for this function:

int SNDDMA_InitDS  ) 
 

Definition at line 151 of file win_snd.c.

References dma_t::buffer, dma_t::channels, Com_DPrintf(), Com_Printf(), dma, format, g_wv, gSndBufSize, HRESULT(), WinVars_t::hWnd, memset(), NULL, pDS, pDSBuf, sample16, dma_t::samplebits, dma_t::samples, SNDDMA_BeginPainting(), SNDDMA_Shutdown(), SNDDMA_Submit(), dma_t::speed, and dma_t::submission_chunk.

Referenced by SNDDMA_Init().

00152 {
00153     HRESULT         hresult;
00154     DSBUFFERDESC    dsbuf;
00155     DSBCAPS         dsbcaps;
00156     WAVEFORMATEX    format;
00157     int             use8;
00158 
00159     Com_Printf( "Initializing DirectSound\n");
00160 
00161     use8 = 1;
00162     // Create IDirectSound using the primary sound device
00163     if( FAILED( hresult = CoCreateInstance(&CLSID_DirectSound8, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectSound8, (void **)&pDS))) {
00164         use8 = 0;
00165         if( FAILED( hresult = CoCreateInstance(&CLSID_DirectSound, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectSound, (void **)&pDS))) {
00166             Com_Printf ("failed\n");
00167             SNDDMA_Shutdown ();
00168             return qfalse;
00169         }
00170     }
00171 
00172     hresult = pDS->lpVtbl->Initialize( pDS, NULL);
00173 
00174     Com_DPrintf( "ok\n" );
00175 
00176     Com_DPrintf("...setting DSSCL_PRIORITY coop level: " );
00177 
00178     if ( DS_OK != pDS->lpVtbl->SetCooperativeLevel( pDS, g_wv.hWnd, DSSCL_PRIORITY ) )  {
00179         Com_Printf ("failed\n");
00180         SNDDMA_Shutdown ();
00181         return qfalse;
00182     }
00183     Com_DPrintf("ok\n" );
00184 
00185 
00186     // create the secondary buffer we'll actually work with
00187     dma.channels = 2;
00188     dma.samplebits = 16;
00189 
00190 //  if (s_khz->integer == 44)
00191 //      dma.speed = 44100;
00192 //  else if (s_khz->integer == 22)
00193 //      dma.speed = 22050;
00194 //  else
00195 //      dma.speed = 11025;
00196 
00197     dma.speed = 22050;
00198     memset (&format, 0, sizeof(format));
00199     format.wFormatTag = WAVE_FORMAT_PCM;
00200     format.nChannels = dma.channels;
00201     format.wBitsPerSample = dma.samplebits;
00202     format.nSamplesPerSec = dma.speed;
00203     format.nBlockAlign = format.nChannels * format.wBitsPerSample / 8;
00204     format.cbSize = 0;
00205     format.nAvgBytesPerSec = format.nSamplesPerSec*format.nBlockAlign; 
00206 
00207     memset (&dsbuf, 0, sizeof(dsbuf));
00208     dsbuf.dwSize = sizeof(DSBUFFERDESC);
00209 
00210     // Micah: take advantage of 2D hardware.if available.
00211     dsbuf.dwFlags = DSBCAPS_LOCHARDWARE;
00212     if (use8) {
00213         dsbuf.dwFlags |= DSBCAPS_GETCURRENTPOSITION2;
00214     }
00215     dsbuf.dwBufferBytes = SECONDARY_BUFFER_SIZE;
00216     dsbuf.lpwfxFormat = &format;
00217     
00218     memset(&dsbcaps, 0, sizeof(dsbcaps));
00219     dsbcaps.dwSize = sizeof(dsbcaps);
00220     
00221     Com_DPrintf( "...creating secondary buffer: " );
00222     if (DS_OK == pDS->lpVtbl->CreateSoundBuffer(pDS, &dsbuf, &pDSBuf, NULL)) {
00223         Com_Printf( "locked hardware.  ok\n" );
00224     }
00225     else {
00226         // Couldn't get hardware, fallback to software.
00227         dsbuf.dwFlags = DSBCAPS_LOCSOFTWARE;
00228         if (use8) {
00229             dsbuf.dwFlags |= DSBCAPS_GETCURRENTPOSITION2;
00230         }
00231         if (DS_OK != pDS->lpVtbl->CreateSoundBuffer(pDS, &dsbuf, &pDSBuf, NULL)) {
00232             Com_Printf( "failed\n" );
00233             SNDDMA_Shutdown ();
00234             return qfalse;
00235         }
00236         Com_DPrintf( "forced to software.  ok\n" );
00237     }
00238         
00239     // Make sure mixer is active
00240     if ( DS_OK != pDSBuf->lpVtbl->Play(pDSBuf, 0, 0, DSBPLAY_LOOPING) ) {
00241         Com_Printf ("*** Looped sound play failed ***\n");
00242         SNDDMA_Shutdown ();
00243         return qfalse;
00244     }
00245 
00246     // get the returned buffer size
00247     if ( DS_OK != pDSBuf->lpVtbl->GetCaps (pDSBuf, &dsbcaps) ) {
00248         Com_Printf ("*** GetCaps failed ***\n");
00249         SNDDMA_Shutdown ();
00250         return qfalse;
00251     }
00252     
00253     gSndBufSize = dsbcaps.dwBufferBytes;
00254 
00255     dma.channels = format.nChannels;
00256     dma.samplebits = format.wBitsPerSample;
00257     dma.speed = format.nSamplesPerSec;
00258     dma.samples = gSndBufSize/(dma.samplebits/8);
00259     dma.submission_chunk = 1;
00260     dma.buffer = NULL;          // must be locked first
00261 
00262     sample16 = (dma.samplebits/8) - 1;
00263 
00264     SNDDMA_BeginPainting ();
00265     if (dma.buffer)
00266         memset(dma.buffer, 0, dma.samples * dma.samplebits/8);
00267     SNDDMA_Submit ();
00268     return 1;
00269 }

Here is the call graph for this function:

void SNDDMA_Shutdown void   ) 
 

Definition at line 62 of file win_snd.c.

References dma_t::buffer, Com_DPrintf(), dma, dsound_init, g_wv, hInstDS, WinVars_t::hWnd, memset(), pDS, pDSBuf, and pDSPBuf.

Referenced by S_Shutdown(), SNDDMA_Activate(), and SNDDMA_InitDS().

00062                              {
00063     Com_DPrintf( "Shutting down sound system\n" );
00064 
00065     if ( pDS ) {
00066         Com_DPrintf( "Destroying DS buffers\n" );
00067         if ( pDS )
00068         {
00069             Com_DPrintf( "...setting NORMAL coop level\n" );
00070             pDS->lpVtbl->SetCooperativeLevel( pDS, g_wv.hWnd, DSSCL_PRIORITY );
00071         }
00072 
00073         if ( pDSBuf )
00074         {
00075             Com_DPrintf( "...stopping and releasing sound buffer\n" );
00076             pDSBuf->lpVtbl->Stop( pDSBuf );
00077             pDSBuf->lpVtbl->Release( pDSBuf );
00078         }
00079 
00080         // only release primary buffer if it's not also the mixing buffer we just released
00081         if ( pDSPBuf && ( pDSBuf != pDSPBuf ) )
00082         {
00083             Com_DPrintf( "...releasing primary buffer\n" );
00084             pDSPBuf->lpVtbl->Release( pDSPBuf );
00085         }
00086         pDSBuf = NULL;
00087         pDSPBuf = NULL;
00088 
00089         dma.buffer = NULL;
00090 
00091         Com_DPrintf( "...releasing DS object\n" );
00092         pDS->lpVtbl->Release( pDS );
00093     }
00094 
00095     if ( hInstDS ) {
00096         Com_DPrintf( "...freeing DSOUND.DLL\n" );
00097         FreeLibrary( hInstDS );
00098         hInstDS = NULL;
00099     }
00100 
00101     pDS = NULL;
00102     pDSBuf = NULL;
00103     pDSPBuf = NULL;
00104     dsound_init = qfalse;
00105     memset ((void *)&dma, 0, sizeof (dma));
00106     CoUninitialize( );
00107 }

Here is the call graph for this function:

void SNDDMA_Submit void   ) 
 

Definition at line 362 of file win_snd.c.

References dma_t::buffer, dma, locksize, NULL, and pDSBuf.

Referenced by S_ClearSoundBuffer(), S_Update_(), and SNDDMA_InitDS().

00362                            {
00363     // unlock the dsound buffer
00364     if ( pDSBuf ) {
00365         pDSBuf->lpVtbl->Unlock(pDSBuf, dma.buffer, locksize, NULL, 0);
00366     }
00367 }


Variable Documentation

qboolean dsound_init [static]
 

Definition at line 33 of file win_snd.c.

Referenced by SNDDMA_Init(), and SNDDMA_Shutdown().

DWORD gSndBufSize [static]
 

Definition at line 35 of file win_snd.c.

Referenced by SNDDMA_BeginPainting(), and SNDDMA_InitDS().

HINSTANCE hInstDS [static]
 

Definition at line 39 of file win_snd.c.

Referenced by SNDDMA_Shutdown().

DWORD locksize [static]
 

Definition at line 36 of file win_snd.c.

Referenced by SNDDMA_BeginPainting(), and SNDDMA_Submit().

LPDIRECTSOUND FAR* lplpDS
 

Definition at line 27 of file win_snd.c.

LPDIRECTSOUND pDS [static]
 

Definition at line 37 of file win_snd.c.

Referenced by SNDDMA_Activate(), SNDDMA_InitDS(), and SNDDMA_Shutdown().

LPDIRECTSOUNDBUFFER pDSBuf [static]
 

Definition at line 38 of file win_snd.c.

Referenced by SNDDMA_BeginPainting(), SNDDMA_GetDMAPos(), SNDDMA_InitDS(), SNDDMA_Shutdown(), and SNDDMA_Submit().

LPDIRECTSOUNDBUFFER pDSPBuf [static]
 

Definition at line 38 of file win_snd.c.

Referenced by SNDDMA_Shutdown().

LPDIRECTSOUND FAR IUnknown FAR* pUnkOuter
 

Definition at line 27 of file win_snd.c.

int sample16 [static]
 

Definition at line 34 of file win_snd.c.

Referenced by SNDDMA_InitDS().


Generated on Thu Aug 25 15:44:34 2005 for Quake III Arena by  doxygen 1.3.9.1