/* ============== SNDDMA_BeginPainting Makes sure dma.buffer is valid =============== */ void SNDDMA_BeginPainting(void) { int reps; DWORD dwSize2; DWORD *pbuf, *pbuf2; HRESULT hresult; DWORD dwStatus; if(!pDSBuf) { return; } // if the buffer was lost or stopped, restore it and/or restart it if(pDSBuf->lpVtbl->GetStatus(pDSBuf, &dwStatus) != DS_OK) { Com_Printf("Couldn't get sound buffer status\n"); } if(dwStatus & DSBSTATUS_BUFFERLOST) { pDSBuf->lpVtbl->Restore(pDSBuf); } if(!(dwStatus & DSBSTATUS_PLAYING)) { pDSBuf->lpVtbl->Play(pDSBuf, 0, 0, DSBPLAY_LOOPING); } // lock the dsound buffer reps = 0; dma.buffer = NULL; while((hresult = pDSBuf->lpVtbl->Lock(pDSBuf, 0, gSndBufSize, &pbuf, &locksize, &pbuf2, &dwSize2, 0)) != DS_OK) { if(hresult != DSERR_BUFFERLOST) { Com_Printf("SNDDMA_BeginPainting: Lock failed with error '%s'\n", DSoundError(hresult)); S_Shutdown(); return; } else { pDSBuf->lpVtbl->Restore(pDSBuf); } if(++reps > 2) { return; } } dma.buffer = (unsigned char *)pbuf; }
void S_ClearBuffer (void) { int clear; #ifdef _WIN32 if (!shm || (!shm->buffer && !pDSBuf)) #else if (!shm || !shm->buffer) #endif return; clear = (shm->format.width == 2) ? 0x80 : 0; #ifdef _WIN32 if (pDSBuf) { DWORD dwSize; DWORD *pData; int reps; HRESULT hresult; reps = 0; while ((hresult = pDSBuf->lpVtbl->Lock(pDSBuf, 0, gSndBufSize, &pData, &dwSize, NULL, NULL, 0)) != DS_OK) { if (hresult != DSERR_BUFFERLOST) { Com_Printf ("S_ClearBuffer: Lock failed with error '%s'\n", DSoundError(hresult)); S_Shutdown (); return; } else { pDSBuf->lpVtbl->Restore (pDSBuf); } if (++reps > 2) return; } memset(pData, clear, shm->bufferlength); pDSBuf->lpVtbl->Unlock(pDSBuf, pData, dwSize, NULL, 0); } else #endif { memset(shm->buffer, clear, shm->bufferlength); } }
/* ============== SNDDMA_BeginPainting Makes sure dma.buffer is valid =============== */ void SNDDMA_BeginPainting( void ) { int reps; DWORD dwSize2; DWORD *pbuf, *pbuf2; HRESULT hr; DWORD dwStatus; if( !pDSBuf ) return; // if the buffer was lost or stopped, restore it and/or restart it if( pDSBuf->lpVtbl->GetStatus( pDSBuf, &dwStatus ) != DS_OK ) MsgDev( D_WARN, "SNDDMA_BeginPainting: couldn't get sound buffer status\n" ); if( dwStatus & DSBSTATUS_BUFFERLOST ) pDSBuf->lpVtbl->Restore( pDSBuf ); if( !( dwStatus & DSBSTATUS_PLAYING )) pDSBuf->lpVtbl->Play( pDSBuf, 0, 0, DSBPLAY_LOOPING ); // lock the dsound buffer dma.buffer = NULL; reps = 0; while(( hr = pDSBuf->lpVtbl->Lock( pDSBuf, 0, gSndBufSize, &pbuf, &locksize, &pbuf2, &dwSize2, 0 )) != DS_OK ) { if( hr != DSERR_BUFFERLOST ) { MsgDev( D_ERROR, "SNDDMA_BeginPainting: lock error '%s'\n", DSoundError( hr )); S_Shutdown (); return; } else pDSBuf->lpVtbl->Restore( pDSBuf ); if( ++reps > 2 ) return; } dma.buffer = (byte *)pbuf; }
void SNDDMA_BeginPainting (void) { int reps; DWORD dwSize2; DWORD *pbuf, *pbuf2; HRESULT hresult; DWORD dwStatus; // if the buffer was lost or stopped, restore it and/or restart it //if (!s_primary->value) //{ if (!pDSBuf) return; #ifdef QDSNDCOMPILERHACK if (pDSBuf->lpVtbl->GetStatus (pDSBuf, &dwStatus) != DS_OK) #else if (pDSBuf->GetStatus (&dwStatus) != DS_OK) #endif Com_Printf ("Couldn't get sound buffer status\n"); if (dwStatus & DSBSTATUS_BUFFERLOST) #ifdef QDSNDCOMPILERHACK pDSBuf->lpVtbl->Restore (pDSBuf); #else pDSBuf->Restore (); #endif if (!(dwStatus & DSBSTATUS_PLAYING)) #ifdef QDSNDCOMPILERHACK pDSBuf->lpVtbl->Play(pDSBuf, 0, 0, DSBPLAY_LOOPING); #else pDSBuf->Play(0, 0, DSBPLAY_LOOPING); #endif /*} else { if (!pDSPBuf) return; if (pDSPBuf->lpVtbl->GetStatus (pDSPBuf, &dwStatus) != DS_OK) Com_Printf ("Couldn't get sound buffer status\n"); if (dwStatus & DSBSTATUS_BUFFERLOST) pDSPBuf->lpVtbl->Restore (pDSPBuf); if (!(dwStatus & DSBSTATUS_PLAYING)) pDSPBuf->lpVtbl->Play(pDSPBuf, 0, 0, DSBPLAY_LOOPING); }*/ // lock the dsound buffer reps = 0; dma.buffer = NULL; //if (!s_primary->value) //{ #ifdef QDSNDCOMPILERHACK while ((hresult = pDSBuf->lpVtbl->Lock(pDSBuf, 0, gSndBufSize, &pbuf, &locksize, &pbuf2, &dwSize2, 0)) != DS_OK) #else while ((hresult = pDSBuf->Lock(0, gSndBufSize, &pbuf, &locksize, &pbuf2, &dwSize2, 0)) != DS_OK) #endif { if (hresult != DSERR_BUFFERLOST) { Com_Printf( "S_TransferStereo16: Lock failed with error '%s'\n", DSoundError( hresult ) ); S_Shutdown (); return; } else { #ifdef QDSNDCOMPILERHACK pDSBuf->lpVtbl->Restore(pDSBuf); #else pDSBuf->Restore(); #endif } if (++reps > 2) return; } /*} else { while ((hresult = pDSPBuf->lpVtbl->Lock(pDSPBuf, 0, gSndBufSize, &pbuf, &locksize, &pbuf2, &dwSize2, 0)) != DS_OK) { if (hresult != DSERR_BUFFERLOST) { Com_Printf( "S_TransferStereo16: Lock failed with error '%s'\n", DSoundError( hresult ) ); S_Shutdown (); return; } else { pDSPBuf->lpVtbl->Restore(pDSPBuf); } if (++reps > 2) return; } }*/ dma.buffer = (unsigned char *)pbuf; }
static int SNDDMA_InitDS () { HRESULT hresult; qboolean pauseTried; DSBUFFERDESC dsbuf; DSBCAPS dsbcaps; WAVEFORMATEX format; Com_Printf( "Initializing DirectSound\n"); if ( !hInstDS ) { Com_DPrintf( "...loading dsound.dll: " ); hInstDS = LoadLibrary("dsound.dll"); if ( hInstDS == NULL ) { Com_Printf ("failed\n"); return 0; } Com_DPrintf ("ok\n"); pDirectSoundCreate = (long (__stdcall *)(struct _GUID *,struct IDirectSound ** ,struct IUnknown *)) GetProcAddress(hInstDS,"DirectSoundCreate"); if ( !pDirectSoundCreate ) { Com_Printf ("*** couldn't get DS proc addr ***\n"); return 0; } } Com_DPrintf( "...creating DS object: " ); pauseTried = qfalse; while ( ( hresult = iDirectSoundCreate( NULL, &pDS, NULL ) ) != DS_OK ) { if ( hresult != DSERR_ALLOCATED ) { Com_Printf( "failed\n" ); return 0; } if ( pauseTried ) { Com_Printf ("failed, hardware already in use\n" ); return 0; } // first try just waiting five seconds and trying again // this will handle the case of a sysyem beep playing when the // game starts Com_DPrintf ("retrying...\n"); Sleep( 3000 ); pauseTried = qtrue; } Com_DPrintf( "ok\n" ); Com_DPrintf("...setting DSSCL_PRIORITY coop level: " ); if ( DS_OK != pDS->SetCooperativeLevel( g_wv.hWnd, DSSCL_PRIORITY ) ) { Com_Printf ("failed\n"); SNDDMA_Shutdown (); return qfalse; } Com_DPrintf("ok\n" ); // create the secondary buffer we'll actually work with dma.channels = 2; dma.samplebits = 16; if (s_khz->integer == 44) dma.speed = 44100; else if (s_khz->integer == 22) dma.speed = 22050; else dma.speed = 11025; memset (&format, 0, sizeof(format)); format.wFormatTag = WAVE_FORMAT_PCM; format.nChannels = dma.channels; format.wBitsPerSample = dma.samplebits; format.nSamplesPerSec = dma.speed; format.nBlockAlign = format.nChannels * format.wBitsPerSample / 8; format.cbSize = 0; format.nAvgBytesPerSec = format.nSamplesPerSec*format.nBlockAlign; memset (&dsbuf, 0, sizeof(dsbuf)); dsbuf.dwSize = sizeof(DSBUFFERDESC); #define idDSBCAPS_GETCURRENTPOSITION2 0x00010000 dsbuf.dwFlags = DSBCAPS_CTRLFREQUENCY | DSBCAPS_LOCHARDWARE | idDSBCAPS_GETCURRENTPOSITION2; dsbuf.dwBufferBytes = SECONDARY_BUFFER_SIZE; dsbuf.lpwfxFormat = &format; Com_DPrintf( "...creating secondary buffer: " ); if (DS_OK != pDS->CreateSoundBuffer(&dsbuf, &pDSBuf, NULL)) { dsbuf.dwFlags = DSBCAPS_CTRLFREQUENCY; hresult = pDS->CreateSoundBuffer(&dsbuf, &pDSBuf, NULL); if (hresult != DS_OK) { Com_Printf( "failed to create secondary buffer - %s\n", DSoundError( hresult ) ); SNDDMA_Shutdown (); return qfalse; } } Com_Printf( "locked hardware. ok\n" ); // Make sure mixer is active if ( DS_OK != pDSBuf->Play(0, 0, DSBPLAY_LOOPING) ) { Com_Printf ("*** Looped sound play failed ***\n"); SNDDMA_Shutdown (); return qfalse; } memset(&dsbcaps, 0, sizeof(dsbcaps)); dsbcaps.dwSize = sizeof(dsbcaps); // get the returned buffer size if ( DS_OK != pDSBuf->GetCaps (&dsbcaps) ) { Com_Printf ("*** GetCaps failed ***\n"); SNDDMA_Shutdown (); return qfalse; } gSndBufSize = dsbcaps.dwBufferBytes; dma.channels = format.nChannels; dma.samplebits = format.wBitsPerSample; dma.speed = format.nSamplesPerSec; dma.samples = gSndBufSize/(dma.samplebits/8); dma.submission_chunk = 1; dma.buffer = NULL; // must be locked first sample16 = (dma.samplebits/8) - 1; SNDDMA_BeginPainting (); if (dma.buffer) memset(dma.buffer, 0, dma.samples * dma.samplebits/8); SNDDMA_Submit (); return 1; }
/* ** DS_CreateBuffers */ static qboolean DS_CreateBuffers( void ) { int ret; DSBUFFERDESC dsbuf; DSBCAPS dsbcaps; WAVEFORMATEX pformat, format; DWORD dwWrite; memset (&format, 0, sizeof(format)); format.wFormatTag = WAVE_FORMAT_PCM; format.nChannels = dma.channels; format.wBitsPerSample = dma.samplebits; format.nSamplesPerSec = dma.speed; format.nBlockAlign = format.nChannels * format.wBitsPerSample / 8; format.cbSize = sizeof(WAVEFORMATEX); format.nAvgBytesPerSec = format.nSamplesPerSec*format.nBlockAlign; Com_DPrintf( "Creating DS buffers\n"); Com_DPrintf("...setting EXCLUSIVE coop level: " ); ret = pDS->lpVtbl->SetCooperativeLevel(pDS, cl_hwnd, DSSCL_EXCLUSIVE); if (ret != DS_OK) { Com_Printf ("failed (%s)\n", LOG_CLIENT, DSoundError(ret)); FreeSound (); return false; } Com_DPrintf("ok\n" ); // get access to the primary buffer, if possible, so we can set the // sound hardware format memset (&dsbuf, 0, sizeof(dsbuf)); dsbuf.dwSize = sizeof(DSBUFFERDESC); dsbuf.dwFlags = DSBCAPS_PRIMARYBUFFER; dsbuf.dwBufferBytes = 0; dsbuf.lpwfxFormat = NULL; memset(&dsbcaps, 0, sizeof(dsbcaps)); dsbcaps.dwSize = sizeof(dsbcaps); primary_format_set = false; Com_DPrintf( "...creating primary buffer: " ); ret = pDS->lpVtbl->CreateSoundBuffer (pDS, &dsbuf, &pDSPBuf, NULL); if (DS_OK == ret) { pformat = format; Com_DPrintf( "ok\n" ); ret = pDSPBuf->lpVtbl->SetFormat (pDSPBuf, &pformat); if (DS_OK != ret) { if (snd_firsttime) { Com_DPrintf ("...setting primary sound format: "); Com_Printf ("failed (%s)\n", LOG_CLIENT, DSoundError(ret)); } } else { if (snd_firsttime) Com_DPrintf ("...setting primary sound format: ok\n"); primary_format_set = true; } } else { Com_Printf ("failed (%s)\n", LOG_CLIENT, DSoundError(ret)); } if ( !primary_format_set || !s_primary->intvalue) { // create the secondary buffer we'll actually work with memset (&dsbuf, 0, sizeof(dsbuf)); dsbuf.dwSize = sizeof(DSBUFFERDESC); dsbuf.dwFlags = DSBCAPS_CTRLFREQUENCY | DSBCAPS_LOCSOFTWARE; dsbuf.dwBufferBytes = SECONDARY_BUFFER_SIZE; dsbuf.lpwfxFormat = &format; memset(&dsbcaps, 0, sizeof(dsbcaps)); dsbcaps.dwSize = sizeof(dsbcaps); Com_DPrintf( "...creating secondary buffer: " ); ret = pDS->lpVtbl->CreateSoundBuffer(pDS, &dsbuf, &pDSBuf, NULL); if (DS_OK != ret) { Com_Printf ("failed (%s)\n", LOG_CLIENT, DSoundError(ret)); FreeSound (); return false; } Com_DPrintf( "ok\n" ); dma.channels = format.nChannels; dma.samplebits = format.wBitsPerSample; dma.speed = format.nSamplesPerSec; if (DS_OK != pDSBuf->lpVtbl->GetCaps (pDSBuf, &dsbcaps)) { Com_Printf ("*** GetCaps failed ***\n", LOG_CLIENT|LOG_ERROR); FreeSound (); return false; } Com_DPrintf ("...using secondary sound buffer\n"); } else { Com_DPrintf( "...using primary buffer\n" ); Com_DPrintf( "...setting WRITEPRIMARY coop level: " ); pDS->lpVtbl->SetCooperativeLevel (pDS, cl_hwnd, DSSCL_WRITEPRIMARY); if (DS_OK != ret) { Com_Printf ("failed (%s)\n", LOG_CLIENT, DSoundError(ret)); FreeSound (); return false; } Com_DPrintf( "ok\n" ); if (DS_OK != pDSPBuf->lpVtbl->GetCaps (pDSPBuf, &dsbcaps)) { Com_Printf ("*** GetCaps failed ***\n", LOG_CLIENT|LOG_ERROR); return false; } pDSBuf = pDSPBuf; } // Make sure mixer is active pDSBuf->lpVtbl->Play(pDSBuf, 0, 0, DSBPLAY_LOOPING); if (snd_firsttime) if (!cl_quietstartup->intvalue || developer->intvalue) Com_Printf(" %d channel(s)\n" " %d bits/sample\n" " %d bytes/sec\n", LOG_CLIENT|LOG_NOTICE, dma.channels, dma.samplebits, dma.speed); gSndBufSize = dsbcaps.dwBufferBytes; /* we don't want anyone to access the buffer directly w/o locking it first. */ lpData = NULL; pDSBuf->lpVtbl->Stop(pDSBuf); pDSBuf->lpVtbl->GetCurrentPosition(pDSBuf, &mmstarttime.u.sample, &dwWrite); pDSBuf->lpVtbl->Play(pDSBuf, 0, 0, DSBPLAY_LOOPING); dma.samples = gSndBufSize/(dma.samplebits/8); dma.samplepos = 0; dma.submission_chunk = 1; dma.buffer = (unsigned char *) lpData; sample16 = (dma.samplebits/8) - 1; return true; }