icculus quake2 doxygen  1.0 dev
snd_win.c File Reference
#include <float.h>
#include "../client/client.h"
#include "../client/snd_loc.h"
#include "winquake.h"

Go to the source code of this file.

Macros

#define iDirectSoundCreate(a, b, c)   pDirectSoundCreate(a,b,c)
 
#define WAV_BUFFERS   64
 
#define WAV_MASK   0x3F
 
#define WAV_BUFFER_SIZE   0x0400
 
#define SECONDARY_BUFFER_SIZE   0x10000
 

Enumerations

enum  sndinitstat { SIS_SUCCESS, SIS_FAILURE, SIS_NOTAVAIL }
 

Functions

 HRESULT (WINAPI *pDirectSoundCreate)(GUID FAR *lpGUID
 
qboolean SNDDMA_InitDirect (void)
 
qboolean SNDDMA_InitWav (void)
 
void FreeSound (void)
 
static const char * DSoundError (int error)
 
static qboolean DS_CreateBuffers (void)
 
static void DS_DestroyBuffers (void)
 
int SNDDMA_Init (void)
 
int SNDDMA_GetDMAPos (void)
 
void SNDDMA_BeginPainting (void)
 
void SNDDMA_Submit (void)
 
void SNDDMA_Shutdown (void)
 
void S_Activate (qboolean active)
 

Variables

LPDIRECTSOUND FAR * lplpDS
 
LPDIRECTSOUND FAR IUnknown FAR * pUnkOuter
 
cvar_ts_wavonly
 
static qboolean dsound_init
 
static qboolean wav_init
 
static qboolean snd_firsttime = true
 
static qboolean snd_isdirect
 
static qboolean snd_iswave
 
static qboolean primary_format_set
 
static int snd_buffer_count = 0
 
static int sample16
 
static int snd_sent
 
static int snd_completed
 
HANDLE hData
 
HPSTR lpData
 
HPSTR lpData2
 
HGLOBAL hWaveHdr
 
LPWAVEHDR lpWaveHdr
 
HWAVEOUT hWaveOut
 
WAVEOUTCAPS wavecaps
 
DWORD gSndBufSize
 
MMTIME mmstarttime
 
LPDIRECTSOUND pDS
 
LPDIRECTSOUNDBUFFER pDSBuf
 
LPDIRECTSOUNDBUFFER pDSPBuf
 
HINSTANCE hInstDS
 
DWORD locksize
 

Macro Definition Documentation

◆ iDirectSoundCreate

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

Definition at line 26 of file snd_win.c.

◆ SECONDARY_BUFFER_SIZE

#define SECONDARY_BUFFER_SIZE   0x10000

Definition at line 34 of file snd_win.c.

◆ WAV_BUFFER_SIZE

#define WAV_BUFFER_SIZE   0x0400

Definition at line 33 of file snd_win.c.

◆ WAV_BUFFERS

#define WAV_BUFFERS   64

Definition at line 31 of file snd_win.c.

◆ WAV_MASK

#define WAV_MASK   0x3F

Definition at line 32 of file snd_win.c.

Enumeration Type Documentation

◆ sndinitstat

Enumerator
SIS_SUCCESS 
SIS_FAILURE 
SIS_NOTAVAIL 

Definition at line 36 of file snd_win.c.

Function Documentation

◆ DS_CreateBuffers()

static qboolean DS_CreateBuffers ( void  )
static

Definition at line 100 of file snd_win.c.

101 {
102  DSBUFFERDESC dsbuf;
103  DSBCAPS dsbcaps;
104  WAVEFORMATEX pformat, format;
105  DWORD dwWrite;
106 
107  memset (&format, 0, sizeof(format));
108  format.wFormatTag = WAVE_FORMAT_PCM;
109  format.nChannels = dma.channels;
110  format.wBitsPerSample = dma.samplebits;
111  format.nSamplesPerSec = dma.speed;
112  format.nBlockAlign = format.nChannels * format.wBitsPerSample / 8;
113  format.cbSize = 0;
114  format.nAvgBytesPerSec = format.nSamplesPerSec*format.nBlockAlign;
115 
116  Com_Printf( "Creating DS buffers\n" );
117 
118  Com_DPrintf("...setting EXCLUSIVE coop level: " );
119  if ( DS_OK != pDS->lpVtbl->SetCooperativeLevel( pDS, cl_hwnd, DSSCL_EXCLUSIVE ) )
120  {
121  Com_Printf ("failed\n");
122  FreeSound ();
123  return false;
124  }
125  Com_DPrintf("ok\n" );
126 
127 // get access to the primary buffer, if possible, so we can set the
128 // sound hardware format
129  memset (&dsbuf, 0, sizeof(dsbuf));
130  dsbuf.dwSize = sizeof(DSBUFFERDESC);
131  dsbuf.dwFlags = DSBCAPS_PRIMARYBUFFER;
132  dsbuf.dwBufferBytes = 0;
133  dsbuf.lpwfxFormat = NULL;
134 
135  memset(&dsbcaps, 0, sizeof(dsbcaps));
136  dsbcaps.dwSize = sizeof(dsbcaps);
137  primary_format_set = false;
138 
139  Com_DPrintf( "...creating primary buffer: " );
140  if (DS_OK == pDS->lpVtbl->CreateSoundBuffer(pDS, &dsbuf, &pDSPBuf, NULL))
141  {
142  pformat = format;
143 
144  Com_DPrintf( "ok\n" );
145  if (DS_OK != pDSPBuf->lpVtbl->SetFormat (pDSPBuf, &pformat))
146  {
147  if (snd_firsttime)
148  Com_DPrintf ("...setting primary sound format: failed\n");
149  }
150  else
151  {
152  if (snd_firsttime)
153  Com_DPrintf ("...setting primary sound format: ok\n");
154 
155  primary_format_set = true;
156  }
157  }
158  else
159  Com_Printf( "failed\n" );
160 
162  {
163  // create the secondary buffer we'll actually work with
164  memset (&dsbuf, 0, sizeof(dsbuf));
165  dsbuf.dwSize = sizeof(DSBUFFERDESC);
166  dsbuf.dwFlags = DSBCAPS_CTRLFREQUENCY | DSBCAPS_LOCSOFTWARE;
167  dsbuf.dwBufferBytes = SECONDARY_BUFFER_SIZE;
168  dsbuf.lpwfxFormat = &format;
169 
170  memset(&dsbcaps, 0, sizeof(dsbcaps));
171  dsbcaps.dwSize = sizeof(dsbcaps);
172 
173  Com_DPrintf( "...creating secondary buffer: " );
174  if (DS_OK != pDS->lpVtbl->CreateSoundBuffer(pDS, &dsbuf, &pDSBuf, NULL))
175  {
176  Com_Printf( "failed\n" );
177  FreeSound ();
178  return false;
179  }
180  Com_DPrintf( "ok\n" );
181 
182  dma.channels = format.nChannels;
183  dma.samplebits = format.wBitsPerSample;
184  dma.speed = format.nSamplesPerSec;
185 
186  if (DS_OK != pDSBuf->lpVtbl->GetCaps (pDSBuf, &dsbcaps))
187  {
188  Com_Printf ("*** GetCaps failed ***\n");
189  FreeSound ();
190  return false;
191  }
192 
193  Com_Printf ("...using secondary sound buffer\n");
194  }
195  else
196  {
197  Com_Printf( "...using primary buffer\n" );
198 
199  Com_DPrintf( "...setting WRITEPRIMARY coop level: " );
200  if (DS_OK != pDS->lpVtbl->SetCooperativeLevel (pDS, cl_hwnd, DSSCL_WRITEPRIMARY))
201  {
202  Com_Printf( "failed\n" );
203  FreeSound ();
204  return false;
205  }
206  Com_DPrintf( "ok\n" );
207 
208  if (DS_OK != pDSPBuf->lpVtbl->GetCaps (pDSPBuf, &dsbcaps))
209  {
210  Com_Printf ("*** GetCaps failed ***\n");
211  return false;
212  }
213 
214  pDSBuf = pDSPBuf;
215  }
216 
217  // Make sure mixer is active
218  pDSBuf->lpVtbl->Play(pDSBuf, 0, 0, DSBPLAY_LOOPING);
219 
220  if (snd_firsttime)
221  Com_Printf(" %d channel(s)\n"
222  " %d bits/sample\n"
223  " %d bytes/sec\n",
225 
226  gSndBufSize = dsbcaps.dwBufferBytes;
227 
228  /* we don't want anyone to access the buffer directly w/o locking it first. */
229  lpData = NULL;
230 
231  pDSBuf->lpVtbl->Stop(pDSBuf);
232  pDSBuf->lpVtbl->GetCurrentPosition(pDSBuf, &mmstarttime.u.sample, &dwWrite);
233  pDSBuf->lpVtbl->Play(pDSBuf, 0, 0, DSBPLAY_LOOPING);
234 
236  dma.samplepos = 0;
237  dma.submission_chunk = 1;
238  dma.buffer = (unsigned char *) lpData;
239  sample16 = (dma.samplebits/8) - 1;
240 
241  return true;
242 }

Referenced by S_Activate(), and SNDDMA_InitDirect().

◆ DS_DestroyBuffers()

static void DS_DestroyBuffers ( void  )
static

Definition at line 247 of file snd_win.c.

248 {
249  Com_DPrintf( "Destroying DS buffers\n" );
250  if ( pDS )
251  {
252  Com_DPrintf( "...setting NORMAL coop level\n" );
253  pDS->lpVtbl->SetCooperativeLevel( pDS, cl_hwnd, DSSCL_NORMAL );
254  }
255 
256  if ( pDSBuf )
257  {
258  Com_DPrintf( "...stopping and releasing sound buffer\n" );
259  pDSBuf->lpVtbl->Stop( pDSBuf );
260  pDSBuf->lpVtbl->Release( pDSBuf );
261  }
262 
263  // only release primary buffer if it's not also the mixing buffer we just released
264  if ( pDSPBuf && ( pDSBuf != pDSPBuf ) )
265  {
266  Com_DPrintf( "...releasing primary buffer\n" );
267  pDSPBuf->lpVtbl->Release( pDSPBuf );
268  }
269  pDSBuf = NULL;
270  pDSPBuf = NULL;
271 
272  dma.buffer = NULL;
273 }

Referenced by FreeSound(), and S_Activate().

◆ DSoundError()

static const char* DSoundError ( int  error)
static

Definition at line 80 of file snd_win.c.

81 {
82  switch ( error )
83  {
84  case DSERR_BUFFERLOST:
85  return "DSERR_BUFFERLOST";
86  case DSERR_INVALIDCALL:
87  return "DSERR_INVALIDCALLS";
88  case DSERR_INVALIDPARAM:
89  return "DSERR_INVALIDPARAM";
90  case DSERR_PRIOLEVELNEEDED:
91  return "DSERR_PRIOLEVELNEEDED";
92  }
93 
94  return "unknown";
95 }

Referenced by SNDDMA_BeginPainting().

◆ FreeSound()

void FreeSound ( void  )

Definition at line 280 of file snd_win.c.

281 {
282  int i;
283 
284  Com_DPrintf( "Shutting down sound system\n" );
285 
286  if ( pDS )
288 
289  if ( hWaveOut )
290  {
291  Com_DPrintf( "...resetting waveOut\n" );
292  waveOutReset (hWaveOut);
293 
294  if (lpWaveHdr)
295  {
296  Com_DPrintf( "...unpreparing headers\n" );
297  for (i=0 ; i< WAV_BUFFERS ; i++)
298  waveOutUnprepareHeader (hWaveOut, lpWaveHdr+i, sizeof(WAVEHDR));
299  }
300 
301  Com_DPrintf( "...closing waveOut\n" );
302  waveOutClose (hWaveOut);
303 
304  if (hWaveHdr)
305  {
306  Com_DPrintf( "...freeing WAV header\n" );
307  GlobalUnlock(hWaveHdr);
308  GlobalFree(hWaveHdr);
309  }
310 
311  if (hData)
312  {
313  Com_DPrintf( "...freeing WAV buffer\n" );
314  GlobalUnlock(hData);
315  GlobalFree(hData);
316  }
317 
318  }
319 
320  if ( pDS )
321  {
322  Com_DPrintf( "...releasing DS object\n" );
323  pDS->lpVtbl->Release( pDS );
324  }
325 
326  if ( hInstDS )
327  {
328  Com_DPrintf( "...freeing DSOUND.DLL\n" );
329  FreeLibrary( hInstDS );
330  hInstDS = NULL;
331  }
332 
333  pDS = NULL;
334  pDSBuf = NULL;
335  pDSPBuf = NULL;
336  hWaveOut = 0;
337  hData = 0;
338  hWaveHdr = 0;
339  lpData = NULL;
340  lpWaveHdr = NULL;
341  dsound_init = false;
342  wav_init = false;
343 }

Referenced by DS_CreateBuffers(), SNDDMA_InitDirect(), SNDDMA_InitWav(), SNDDMA_Shutdown(), and SNDDMA_Submit().

◆ HRESULT()

HRESULT ( WINAPI *  pDirectSoundCreate)

◆ S_Activate()

void S_Activate ( qboolean  active)

Definition at line 844 of file snd_win.c.

845 {
846  if ( active )
847  {
848  if ( pDS && cl_hwnd && snd_isdirect )
849  {
851  }
852  }
853  else
854  {
855  if ( pDS && cl_hwnd && snd_isdirect )
856  {
858  }
859  }
860 }

Referenced by AppActivate().

◆ SNDDMA_BeginPainting()

void SNDDMA_BeginPainting ( void  )

Definition at line 707 of file snd_win.c.

708 {
709  int reps;
710  DWORD dwSize2;
711  DWORD *pbuf, *pbuf2;
712  HRESULT hresult;
713  DWORD dwStatus;
714 
715  if (!pDSBuf)
716  return;
717 
718  // if the buffer was lost or stopped, restore it and/or restart it
719  if (pDSBuf->lpVtbl->GetStatus (pDSBuf, &dwStatus) != DS_OK)
720  Com_Printf ("Couldn't get sound buffer status\n");
721 
722  if (dwStatus & DSBSTATUS_BUFFERLOST)
723  pDSBuf->lpVtbl->Restore (pDSBuf);
724 
725  if (!(dwStatus & DSBSTATUS_PLAYING))
726  pDSBuf->lpVtbl->Play(pDSBuf, 0, 0, DSBPLAY_LOOPING);
727 
728  // lock the dsound buffer
729 
730  reps = 0;
731  dma.buffer = NULL;
732 
733  while ((hresult = pDSBuf->lpVtbl->Lock(pDSBuf, 0, gSndBufSize, &pbuf, &locksize,
734  &pbuf2, &dwSize2, 0)) != DS_OK)
735  {
736  if (hresult != DSERR_BUFFERLOST)
737  {
738  Com_Printf( "S_TransferStereo16: Lock failed with error '%s'\n", DSoundError( hresult ) );
739  S_Shutdown ();
740  return;
741  }
742  else
743  {
744  pDSBuf->lpVtbl->Restore( pDSBuf );
745  }
746 
747  if (++reps > 2)
748  return;
749  }
750  dma.buffer = (unsigned char *)pbuf;
751 }

Referenced by S_ClearBuffer(), and S_Update_().

◆ SNDDMA_GetDMAPos()

int SNDDMA_GetDMAPos ( void  )

Definition at line 674 of file snd_win.c.

675 {
676  MMTIME mmtime;
677  int s;
678  DWORD dwWrite;
679 
680  if (dsound_init)
681  {
682  mmtime.wType = TIME_SAMPLES;
683  pDSBuf->lpVtbl->GetCurrentPosition(pDSBuf, &mmtime.u.sample, &dwWrite);
684  s = mmtime.u.sample - mmstarttime.u.sample;
685  }
686  else if (wav_init)
687  {
689  }
690 
691 
692  s >>= sample16;
693 
694  s &= (dma.samples-1);
695 
696  return s;
697 }

Referenced by GetSoundtime().

◆ SNDDMA_Init()

int SNDDMA_Init ( void  )

Definition at line 593 of file snd_win.c.

594 {
595  sndinitstat stat;
596 
597  memset ((void *)&dma, 0, sizeof (dma));
598 
599  s_wavonly = Cvar_Get ("s_wavonly", "0", 0);
600 
601  dsound_init = wav_init = 0;
602 
603  stat = SIS_FAILURE; // assume DirectSound won't initialize
604 
605  /* Init DirectSound */
606  if (!s_wavonly->value)
607  {
609  {
610  stat = SNDDMA_InitDirect ();
611 
612  if (stat == SIS_SUCCESS)
613  {
614  snd_isdirect = true;
615 
616  if (snd_firsttime)
617  Com_Printf ("dsound init succeeded\n" );
618  }
619  else
620  {
621  snd_isdirect = false;
622  Com_Printf ("*** dsound init failed ***\n");
623  }
624  }
625  }
626 
627 // if DirectSound didn't succeed in initializing, try to initialize
628 // waveOut sound, unless DirectSound failed because the hardware is
629 // already allocated (in which case the user has already chosen not
630 // to have sound)
631  if (!dsound_init && (stat != SIS_NOTAVAIL))
632  {
633  if (snd_firsttime || snd_iswave)
634  {
635 
637 
638  if (snd_iswave)
639  {
640  if (snd_firsttime)
641  Com_Printf ("Wave sound init succeeded\n");
642  }
643  else
644  {
645  Com_Printf ("Wave sound init failed\n");
646  }
647  }
648  }
649 
650  snd_firsttime = false;
651 
652  snd_buffer_count = 1;
653 
654  if (!dsound_init && !wav_init)
655  {
656  if (snd_firsttime)
657  Com_Printf ("*** No sound device initialized ***\n");
658 
659  return 0;
660  }
661 
662  return 1;
663 }

Referenced by S_Init().

◆ SNDDMA_InitDirect()

sndinitstat SNDDMA_InitDirect ( void  )

Definition at line 352 of file snd_win.c.

353 {
354  DSCAPS dscaps;
355  HRESULT hresult;
356 
357  dma.channels = 2;
358  dma.samplebits = 16;
359 
360  if (s_khz->value == 44)
361  dma.speed = 44100;
362  if (s_khz->value == 22)
363  dma.speed = 22050;
364  else
365  dma.speed = 11025;
366 
367  Com_Printf( "Initializing DirectSound\n");
368 
369  if ( !hInstDS )
370  {
371  Com_DPrintf( "...loading dsound.dll: " );
372 
373  hInstDS = LoadLibrary("dsound.dll");
374 
375  if (hInstDS == NULL)
376  {
377  Com_Printf ("failed\n");
378  return SIS_FAILURE;
379  }
380 
381  Com_DPrintf ("ok\n");
382  pDirectSoundCreate = (void *)GetProcAddress(hInstDS,"DirectSoundCreate");
383 
384  if (!pDirectSoundCreate)
385  {
386  Com_Printf ("*** couldn't get DS proc addr ***\n");
387  return SIS_FAILURE;
388  }
389  }
390 
391  Com_DPrintf( "...creating DS object: " );
392  while ( ( hresult = iDirectSoundCreate( NULL, &pDS, NULL ) ) != DS_OK )
393  {
394  if (hresult != DSERR_ALLOCATED)
395  {
396  Com_Printf( "failed\n" );
397  return SIS_FAILURE;
398  }
399 
400  if (MessageBox (NULL,
401  "The sound hardware is in use by another app.\n\n"
402  "Select Retry to try to start sound again or Cancel to run Quake with no sound.",
403  "Sound not available",
404  MB_RETRYCANCEL | MB_SETFOREGROUND | MB_ICONEXCLAMATION) != IDRETRY)
405  {
406  Com_Printf ("failed, hardware already in use\n" );
407  return SIS_NOTAVAIL;
408  }
409  }
410  Com_DPrintf( "ok\n" );
411 
412  dscaps.dwSize = sizeof(dscaps);
413 
414  if ( DS_OK != pDS->lpVtbl->GetCaps( pDS, &dscaps ) )
415  {
416  Com_Printf ("*** couldn't get DS caps ***\n");
417  }
418 
419  if ( dscaps.dwFlags & DSCAPS_EMULDRIVER )
420  {
421  Com_DPrintf ("...no DSound driver found\n" );
422  FreeSound();
423  return SIS_FAILURE;
424  }
425 
426  if ( !DS_CreateBuffers() )
427  return SIS_FAILURE;
428 
429  dsound_init = true;
430 
431  Com_DPrintf("...completed successfully\n" );
432 
433  return SIS_SUCCESS;
434 }

Referenced by SNDDMA_Init().

◆ SNDDMA_InitWav()

qboolean SNDDMA_InitWav ( void  )

Definition at line 444 of file snd_win.c.

445 {
446  WAVEFORMATEX format;
447  int i;
448  HRESULT hr;
449 
450  Com_Printf( "Initializing wave sound\n" );
451 
452  snd_sent = 0;
453  snd_completed = 0;
454 
455  dma.channels = 2;
456  dma.samplebits = 16;
457 
458  if (s_khz->value == 44)
459  dma.speed = 44100;
460  if (s_khz->value == 22)
461  dma.speed = 22050;
462  else
463  dma.speed = 11025;
464 
465  memset (&format, 0, sizeof(format));
466  format.wFormatTag = WAVE_FORMAT_PCM;
467  format.nChannels = dma.channels;
468  format.wBitsPerSample = dma.samplebits;
469  format.nSamplesPerSec = dma.speed;
470  format.nBlockAlign = format.nChannels
471  *format.wBitsPerSample / 8;
472  format.cbSize = 0;
473  format.nAvgBytesPerSec = format.nSamplesPerSec
474  *format.nBlockAlign;
475 
476  /* Open a waveform device for output using window callback. */
477  Com_DPrintf ("...opening waveform device: ");
478  while ((hr = waveOutOpen((LPHWAVEOUT)&hWaveOut, WAVE_MAPPER,
479  &format,
480  0, 0L, CALLBACK_NULL)) != MMSYSERR_NOERROR)
481  {
482  if (hr != MMSYSERR_ALLOCATED)
483  {
484  Com_Printf ("failed\n");
485  return false;
486  }
487 
488  if (MessageBox (NULL,
489  "The sound hardware is in use by another app.\n\n"
490  "Select Retry to try to start sound again or Cancel to run Quake 2 with no sound.",
491  "Sound not available",
492  MB_RETRYCANCEL | MB_SETFOREGROUND | MB_ICONEXCLAMATION) != IDRETRY)
493  {
494  Com_Printf ("hw in use\n" );
495  return false;
496  }
497  }
498  Com_DPrintf( "ok\n" );
499 
500  /*
501  * Allocate and lock memory for the waveform data. The memory
502  * for waveform data must be globally allocated with
503  * GMEM_MOVEABLE and GMEM_SHARE flags.
504 
505  */
506  Com_DPrintf ("...allocating waveform buffer: ");
508  hData = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE, gSndBufSize);
509  if (!hData)
510  {
511  Com_Printf( " failed\n" );
512  FreeSound ();
513  return false;
514  }
515  Com_DPrintf( "ok\n" );
516 
517  Com_DPrintf ("...locking waveform buffer: ");
518  lpData = GlobalLock(hData);
519  if (!lpData)
520  {
521  Com_Printf( " failed\n" );
522  FreeSound ();
523  return false;
524  }
525  memset (lpData, 0, gSndBufSize);
526  Com_DPrintf( "ok\n" );
527 
528  /*
529  * Allocate and lock memory for the header. This memory must
530  * also be globally allocated with GMEM_MOVEABLE and
531  * GMEM_SHARE flags.
532  */
533  Com_DPrintf ("...allocating waveform header: ");
534  hWaveHdr = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE,
535  (DWORD) sizeof(WAVEHDR) * WAV_BUFFERS);
536 
537  if (hWaveHdr == NULL)
538  {
539  Com_Printf( "failed\n" );
540  FreeSound ();
541  return false;
542  }
543  Com_DPrintf( "ok\n" );
544 
545  Com_DPrintf ("...locking waveform header: ");
546  lpWaveHdr = (LPWAVEHDR) GlobalLock(hWaveHdr);
547 
548  if (lpWaveHdr == NULL)
549  {
550  Com_Printf( "failed\n" );
551  FreeSound ();
552  return false;
553  }
554  memset (lpWaveHdr, 0, sizeof(WAVEHDR) * WAV_BUFFERS);
555  Com_DPrintf( "ok\n" );
556 
557  /* After allocation, set up and prepare headers. */
558  Com_DPrintf ("...preparing headers: ");
559  for (i=0 ; i<WAV_BUFFERS ; i++)
560  {
561  lpWaveHdr[i].dwBufferLength = WAV_BUFFER_SIZE;
562  lpWaveHdr[i].lpData = lpData + i*WAV_BUFFER_SIZE;
563 
564  if (waveOutPrepareHeader(hWaveOut, lpWaveHdr+i, sizeof(WAVEHDR)) !=
565  MMSYSERR_NOERROR)
566  {
567  Com_Printf ("failed\n");
568  FreeSound ();
569  return false;
570  }
571  }
572  Com_DPrintf ("ok\n");
573 
575  dma.samplepos = 0;
576  dma.submission_chunk = 512;
577  dma.buffer = (unsigned char *) lpData;
578  sample16 = (dma.samplebits/8) - 1;
579 
580  wav_init = true;
581 
582  return true;
583 }

Referenced by SNDDMA_Init().

◆ SNDDMA_Shutdown()

void SNDDMA_Shutdown ( void  )

Definition at line 829 of file snd_win.c.

830 {
831  FreeSound ();
832 }

Referenced by S_Shutdown().

◆ SNDDMA_Submit()

void SNDDMA_Submit ( void  )

Definition at line 761 of file snd_win.c.

762 {
763  LPWAVEHDR h;
764  int wResult;
765 
766  if (!dma.buffer)
767  return;
768 
769  // unlock the dsound buffer
770  if (pDSBuf)
771  pDSBuf->lpVtbl->Unlock(pDSBuf, dma.buffer, locksize, NULL, 0);
772 
773  if (!wav_init)
774  return;
775 
776  //
777  // find which sound blocks have completed
778  //
779  while (1)
780  {
781  if ( snd_completed == snd_sent )
782  {
783  Com_DPrintf ("Sound overrun\n");
784  break;
785  }
786 
787  if ( ! (lpWaveHdr[ snd_completed & WAV_MASK].dwFlags & WHDR_DONE) )
788  {
789  break;
790  }
791 
792  snd_completed++; // this buffer has been played
793  }
794 
795 //Com_Printf ("completed %i\n", snd_completed);
796  //
797  // submit a few new sound blocks
798  //
799  while (((snd_sent - snd_completed) >> sample16) < 8)
800  {
801  h = lpWaveHdr + ( snd_sent&WAV_MASK );
802  if (paintedtime/256 <= snd_sent)
803  break; // Com_Printf ("submit overrun\n");
804 //Com_Printf ("send %i\n", snd_sent);
805  snd_sent++;
806  /*
807  * Now the data block can be sent to the output device. The
808  * waveOutWrite function returns immediately and waveform
809  * data is sent to the output device in the background.
810  */
811  wResult = waveOutWrite(hWaveOut, h, sizeof(WAVEHDR));
812 
813  if (wResult != MMSYSERR_NOERROR)
814  {
815  Com_Printf ("Failed to write block to device\n");
816  FreeSound ();
817  return;
818  }
819  }
820 }

Referenced by S_ClearBuffer(), and S_Update_().

Variable Documentation

◆ dsound_init

qboolean dsound_init
static

Definition at line 40 of file snd_win.c.

Referenced by FreeSound(), SNDDMA_GetDMAPos(), SNDDMA_Init(), and SNDDMA_InitDirect().

◆ gSndBufSize

DWORD gSndBufSize

Definition at line 66 of file snd_win.c.

Referenced by DS_CreateBuffers(), SNDDMA_BeginPainting(), and SNDDMA_InitWav().

◆ hData

HANDLE hData

Definition at line 56 of file snd_win.c.

Referenced by FreeSound(), and SNDDMA_InitWav().

◆ hInstDS

HINSTANCE hInstDS

Definition at line 73 of file snd_win.c.

Referenced by FreeSound(), and SNDDMA_InitDirect().

◆ hWaveHdr

HGLOBAL hWaveHdr

Definition at line 59 of file snd_win.c.

Referenced by FreeSound(), and SNDDMA_InitWav().

◆ hWaveOut

HWAVEOUT hWaveOut

Definition at line 62 of file snd_win.c.

Referenced by FreeSound(), SNDDMA_InitWav(), and SNDDMA_Submit().

◆ locksize

DWORD locksize

Definition at line 706 of file snd_win.c.

Referenced by SNDDMA_BeginPainting(), and SNDDMA_Submit().

◆ lpData

HPSTR lpData

Definition at line 57 of file snd_win.c.

Referenced by DS_CreateBuffers(), FreeSound(), and SNDDMA_InitWav().

◆ lpData2

HPSTR lpData2

Definition at line 57 of file snd_win.c.

◆ lplpDS

LPDIRECTSOUND FAR* lplpDS

Definition at line 28 of file snd_win.c.

◆ lpWaveHdr

LPWAVEHDR lpWaveHdr

Definition at line 60 of file snd_win.c.

Referenced by FreeSound(), SNDDMA_InitWav(), and SNDDMA_Submit().

◆ mmstarttime

MMTIME mmstarttime

Definition at line 68 of file snd_win.c.

Referenced by DS_CreateBuffers(), and SNDDMA_GetDMAPos().

◆ pDS

LPDIRECTSOUND pDS

◆ pDSBuf

LPDIRECTSOUNDBUFFER pDSBuf

◆ pDSPBuf

LPDIRECTSOUNDBUFFER pDSPBuf

Definition at line 71 of file snd_win.c.

Referenced by DS_CreateBuffers(), DS_DestroyBuffers(), and FreeSound().

◆ primary_format_set

qboolean primary_format_set
static

Definition at line 43 of file snd_win.c.

Referenced by DS_CreateBuffers().

◆ pUnkOuter

LPDIRECTSOUND FAR IUnknown FAR* pUnkOuter

Definition at line 28 of file snd_win.c.

Referenced by DDRAW_Init().

◆ s_wavonly

cvar_t* s_wavonly

Definition at line 38 of file snd_win.c.

Referenced by SNDDMA_Init().

◆ sample16

int sample16
static

Definition at line 47 of file snd_win.c.

Referenced by DS_CreateBuffers(), SNDDMA_GetDMAPos(), SNDDMA_InitWav(), and SNDDMA_Submit().

◆ snd_buffer_count

int snd_buffer_count = 0
static

Definition at line 46 of file snd_win.c.

Referenced by SNDDMA_Init().

◆ snd_completed

int snd_completed
static

Definition at line 48 of file snd_win.c.

Referenced by SNDDMA_InitWav(), and SNDDMA_Submit().

◆ snd_firsttime

qboolean snd_firsttime = true
static

Definition at line 42 of file snd_win.c.

Referenced by DS_CreateBuffers(), and SNDDMA_Init().

◆ snd_isdirect

qboolean snd_isdirect
static

Definition at line 42 of file snd_win.c.

Referenced by S_Activate(), and SNDDMA_Init().

◆ snd_iswave

qboolean snd_iswave
static

Definition at line 42 of file snd_win.c.

Referenced by SNDDMA_Init().

◆ snd_sent

int snd_sent
static

Definition at line 48 of file snd_win.c.

Referenced by SNDDMA_GetDMAPos(), SNDDMA_InitWav(), and SNDDMA_Submit().

◆ wav_init

qboolean wav_init
static

Definition at line 41 of file snd_win.c.

Referenced by FreeSound(), SNDDMA_GetDMAPos(), SNDDMA_Init(), SNDDMA_InitWav(), and SNDDMA_Submit().

◆ wavecaps

WAVEOUTCAPS wavecaps

Definition at line 64 of file snd_win.c.

hInstDS
HINSTANCE hInstDS
Definition: snd_win.c:73
snd_firsttime
static qboolean snd_firsttime
Definition: snd_win.c:42
WAV_BUFFERS
#define WAV_BUFFERS
Definition: snd_win.c:31
SNDDMA_InitDirect
qboolean SNDDMA_InitDirect(void)
Definition: snd_win.c:352
lpData
HPSTR lpData
Definition: snd_win.c:57
SIS_SUCCESS
@ SIS_SUCCESS
Definition: snd_win.c:36
lpWaveHdr
LPWAVEHDR lpWaveHdr
Definition: snd_win.c:60
WAV_MASK
#define WAV_MASK
Definition: snd_win.c:32
pDS
LPDIRECTSOUND pDS
Definition: snd_win.c:70
sample16
static int sample16
Definition: snd_win.c:47
i
int i
Definition: q_shared.c:305
snd_iswave
static qboolean snd_iswave
Definition: snd_win.c:42
dma_t::submission_chunk
int submission_chunk
Definition: snd_loc.h:67
primary_format_set
static qboolean primary_format_set
Definition: snd_win.c:43
dma_t::samples
int samples
Definition: snd_loc.h:66
DS_CreateBuffers
static qboolean DS_CreateBuffers(void)
Definition: snd_win.c:100
Cvar_Get
cvar_t * Cvar_Get(char *var_name, char *var_value, int flags)
Definition: cvar.c:127
s_primary
cvar_t * s_primary
Definition: snd_dma.c:80
snd_buffer_count
static int snd_buffer_count
Definition: snd_win.c:46
DSoundError
static const char * DSoundError(int error)
Definition: snd_win.c:80
dma_t::buffer
byte * buffer
Definition: snd_loc.h:71
dma_t::channels
int channels
Definition: snd_loc.h:65
hData
HANDLE hData
Definition: snd_win.c:56
paintedtime
int paintedtime
Definition: snd_dma.c:57
SNDDMA_InitWav
qboolean SNDDMA_InitWav(void)
Definition: snd_win.c:444
locksize
DWORD locksize
Definition: snd_win.c:706
pDSBuf
LPDIRECTSOUNDBUFFER pDSBuf
Definition: snd_win.c:71
snd_sent
static int snd_sent
Definition: snd_win.c:48
snd_isdirect
static qboolean snd_isdirect
Definition: snd_win.c:42
cl_hwnd
HWND cl_hwnd
Definition: vid_dll.c:53
S_Shutdown
void S_Shutdown(void)
Definition: snd_dma.c:164
cvar_s::value
float value
Definition: q_shared.h:324
dma_t::speed
int speed
Definition: snd_loc.h:70
hWaveOut
HWAVEOUT hWaveOut
Definition: snd_win.c:62
wav_init
static qboolean wav_init
Definition: snd_win.c:41
SECONDARY_BUFFER_SIZE
#define SECONDARY_BUFFER_SIZE
Definition: snd_win.c:34
NULL
#define NULL
Definition: q_shared.h:60
dsound_init
static qboolean dsound_init
Definition: snd_win.c:40
dma
dma_t dma
Definition: snd_dma.c:47
snd_completed
static int snd_completed
Definition: snd_win.c:48
s_wavonly
cvar_t * s_wavonly
Definition: snd_win.c:38
SIS_FAILURE
@ SIS_FAILURE
Definition: snd_win.c:36
pDSPBuf
LPDIRECTSOUNDBUFFER pDSPBuf
Definition: snd_win.c:71
dma_t::samplepos
int samplepos
Definition: snd_loc.h:68
SIS_NOTAVAIL
@ SIS_NOTAVAIL
Definition: snd_win.c:36
format
GLsizei GLenum format
Definition: qgl_win.c:131
Com_DPrintf
void Com_DPrintf(char *fmt,...)
Definition: common.c:155
DWORD
DWORD
Definition: qgl_win.c:49
mmstarttime
MMTIME mmstarttime
Definition: snd_win.c:68
Com_Printf
void Com_Printf(char *fmt,...)
Definition: common.c:102
dma_t::samplebits
int samplebits
Definition: snd_loc.h:69
sndinitstat
sndinitstat
Definition: snd_win.c:36
FreeSound
void FreeSound(void)
Definition: snd_win.c:280
hWaveHdr
HGLOBAL hWaveHdr
Definition: snd_win.c:59
iDirectSoundCreate
#define iDirectSoundCreate(a, b, c)
Definition: snd_win.c:26
WAV_BUFFER_SIZE
#define WAV_BUFFER_SIZE
Definition: snd_win.c:33
DS_DestroyBuffers
static void DS_DestroyBuffers(void)
Definition: snd_win.c:247
HRESULT
HRESULT(WINAPI *pDirectSoundCreate)(GUID FAR *lpGUID
gSndBufSize
DWORD gSndBufSize
Definition: snd_win.c:66
s_khz
cvar_t * s_khz
Definition: snd_dma.c:77