SDL  2.0
SDL_directsound.c
Go to the documentation of this file.
1 /*
2  Simple DirectMedia Layer
3  Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
4 
5  This software is provided 'as-is', without any express or implied
6  warranty. In no event will the authors be held liable for any damages
7  arising from the use of this software.
8 
9  Permission is granted to anyone to use this software for any purpose,
10  including commercial applications, and to alter it and redistribute it
11  freely, subject to the following restrictions:
12 
13  1. The origin of this software must not be misrepresented; you must not
14  claim that you wrote the original software. If you use this software
15  in a product, an acknowledgment in the product documentation would be
16  appreciated but is not required.
17  2. Altered source versions must be plainly marked as such, and must not be
18  misrepresented as being the original software.
19  3. This notice may not be removed or altered from any source distribution.
20 */
21 #include "../../SDL_internal.h"
22 
23 #if SDL_AUDIO_DRIVER_DSOUND
24 
25 /* Allow access to a raw mixing buffer */
26 
27 #include "SDL_timer.h"
28 #include "SDL_loadso.h"
29 #include "SDL_audio.h"
30 #include "../SDL_audio_c.h"
31 #include "SDL_directsound.h"
32 
33 #ifndef WAVE_FORMAT_IEEE_FLOAT
34 #define WAVE_FORMAT_IEEE_FLOAT 0x0003
35 #endif
36 
37 /* DirectX function pointers for audio */
38 static void* DSoundDLL = NULL;
39 typedef HRESULT (WINAPI *fnDirectSoundCreate8)(LPGUID,LPDIRECTSOUND*,LPUNKNOWN);
40 typedef HRESULT (WINAPI *fnDirectSoundEnumerateW)(LPDSENUMCALLBACKW, LPVOID);
41 typedef HRESULT (WINAPI *fnDirectSoundCaptureCreate8)(LPCGUID,LPDIRECTSOUNDCAPTURE8 *,LPUNKNOWN);
42 typedef HRESULT (WINAPI *fnDirectSoundCaptureEnumerateW)(LPDSENUMCALLBACKW,LPVOID);
43 static fnDirectSoundCreate8 pDirectSoundCreate8 = NULL;
44 static fnDirectSoundEnumerateW pDirectSoundEnumerateW = NULL;
45 static fnDirectSoundCaptureCreate8 pDirectSoundCaptureCreate8 = NULL;
46 static fnDirectSoundCaptureEnumerateW pDirectSoundCaptureEnumerateW = NULL;
47 
48 static void
49 DSOUND_Unload(void)
50 {
51  pDirectSoundCreate8 = NULL;
52  pDirectSoundEnumerateW = NULL;
53  pDirectSoundCaptureCreate8 = NULL;
54  pDirectSoundCaptureEnumerateW = NULL;
55 
56  if (DSoundDLL != NULL) {
57  SDL_UnloadObject(DSoundDLL);
58  DSoundDLL = NULL;
59  }
60 }
61 
62 
63 static int
64 DSOUND_Load(void)
65 {
66  int loaded = 0;
67 
68  DSOUND_Unload();
69 
70  DSoundDLL = SDL_LoadObject("DSOUND.DLL");
71  if (DSoundDLL == NULL) {
72  SDL_SetError("DirectSound: failed to load DSOUND.DLL");
73  } else {
74  /* Now make sure we have DirectX 8 or better... */
75  #define DSOUNDLOAD(f) { \
76  p##f = (fn##f) SDL_LoadFunction(DSoundDLL, #f); \
77  if (!p##f) loaded = 0; \
78  }
79  loaded = 1; /* will reset if necessary. */
80  DSOUNDLOAD(DirectSoundCreate8);
81  DSOUNDLOAD(DirectSoundEnumerateW);
82  DSOUNDLOAD(DirectSoundCaptureCreate8);
83  DSOUNDLOAD(DirectSoundCaptureEnumerateW);
84  #undef DSOUNDLOAD
85 
86  if (!loaded) {
87  SDL_SetError("DirectSound: System doesn't appear to have DX8.");
88  }
89  }
90 
91  if (!loaded) {
92  DSOUND_Unload();
93  }
94 
95  return loaded;
96 }
97 
98 static int
99 SetDSerror(const char *function, int code)
100 {
101  static const char *error;
102  static char errbuf[1024];
103 
104  errbuf[0] = 0;
105  switch (code) {
106  case E_NOINTERFACE:
107  error = "Unsupported interface -- Is DirectX 8.0 or later installed?";
108  break;
109  case DSERR_ALLOCATED:
110  error = "Audio device in use";
111  break;
112  case DSERR_BADFORMAT:
113  error = "Unsupported audio format";
114  break;
115  case DSERR_BUFFERLOST:
116  error = "Mixing buffer was lost";
117  break;
118  case DSERR_CONTROLUNAVAIL:
119  error = "Control requested is not available";
120  break;
121  case DSERR_INVALIDCALL:
122  error = "Invalid call for the current state";
123  break;
124  case DSERR_INVALIDPARAM:
125  error = "Invalid parameter";
126  break;
127  case DSERR_NODRIVER:
128  error = "No audio device found";
129  break;
130  case DSERR_OUTOFMEMORY:
131  error = "Out of memory";
132  break;
133  case DSERR_PRIOLEVELNEEDED:
134  error = "Caller doesn't have priority";
135  break;
136  case DSERR_UNSUPPORTED:
137  error = "Function not supported";
138  break;
139  default:
140  SDL_snprintf(errbuf, SDL_arraysize(errbuf),
141  "%s: Unknown DirectSound error: 0x%x", function, code);
142  break;
143  }
144  if (!errbuf[0]) {
145  SDL_snprintf(errbuf, SDL_arraysize(errbuf), "%s: %s", function,
146  error);
147  }
148  return SDL_SetError("%s", errbuf);
149 }
150 
151 static void
152 DSOUND_FreeDeviceHandle(void *handle)
153 {
154  SDL_free(handle);
155 }
156 
157 static BOOL CALLBACK
158 FindAllDevs(LPGUID guid, LPCWSTR desc, LPCWSTR module, LPVOID data)
159 {
160  const int iscapture = (int) ((size_t) data);
161  if (guid != NULL) { /* skip default device */
162  char *str = WIN_LookupAudioDeviceName(desc, guid);
163  if (str != NULL) {
164  LPGUID cpyguid = (LPGUID) SDL_malloc(sizeof (GUID));
165  SDL_memcpy(cpyguid, guid, sizeof (GUID));
166  SDL_AddAudioDevice(iscapture, str, cpyguid);
167  SDL_free(str); /* addfn() makes a copy of this string. */
168  }
169  }
170  return TRUE; /* keep enumerating. */
171 }
172 
173 static void
174 DSOUND_DetectDevices(void)
175 {
176  pDirectSoundCaptureEnumerateW(FindAllDevs, (void *) ((size_t) 1));
177  pDirectSoundEnumerateW(FindAllDevs, (void *) ((size_t) 0));
178 }
179 
180 
181 static void
182 DSOUND_WaitDevice(_THIS)
183 {
184  DWORD status = 0;
185  DWORD cursor = 0;
186  DWORD junk = 0;
187  HRESULT result = DS_OK;
188 
189  /* Semi-busy wait, since we have no way of getting play notification
190  on a primary mixing buffer located in hardware (DirectX 5.0)
191  */
192  result = IDirectSoundBuffer_GetCurrentPosition(this->hidden->mixbuf,
193  &junk, &cursor);
194  if (result != DS_OK) {
195  if (result == DSERR_BUFFERLOST) {
196  IDirectSoundBuffer_Restore(this->hidden->mixbuf);
197  }
198 #ifdef DEBUG_SOUND
199  SetDSerror("DirectSound GetCurrentPosition", result);
200 #endif
201  return;
202  }
203 
204  while ((cursor / this->spec.size) == this->hidden->lastchunk) {
205  /* FIXME: find out how much time is left and sleep that long */
206  SDL_Delay(1);
207 
208  /* Try to restore a lost sound buffer */
209  IDirectSoundBuffer_GetStatus(this->hidden->mixbuf, &status);
210  if ((status & DSBSTATUS_BUFFERLOST)) {
211  IDirectSoundBuffer_Restore(this->hidden->mixbuf);
212  IDirectSoundBuffer_GetStatus(this->hidden->mixbuf, &status);
213  if ((status & DSBSTATUS_BUFFERLOST)) {
214  break;
215  }
216  }
217  if (!(status & DSBSTATUS_PLAYING)) {
218  result = IDirectSoundBuffer_Play(this->hidden->mixbuf, 0, 0,
219  DSBPLAY_LOOPING);
220  if (result == DS_OK) {
221  continue;
222  }
223 #ifdef DEBUG_SOUND
224  SetDSerror("DirectSound Play", result);
225 #endif
226  return;
227  }
228 
229  /* Find out where we are playing */
230  result = IDirectSoundBuffer_GetCurrentPosition(this->hidden->mixbuf,
231  &junk, &cursor);
232  if (result != DS_OK) {
233  SetDSerror("DirectSound GetCurrentPosition", result);
234  return;
235  }
236  }
237 }
238 
239 static void
240 DSOUND_PlayDevice(_THIS)
241 {
242  /* Unlock the buffer, allowing it to play */
243  if (this->hidden->locked_buf) {
244  IDirectSoundBuffer_Unlock(this->hidden->mixbuf,
245  this->hidden->locked_buf,
246  this->spec.size, NULL, 0);
247  }
248 }
249 
250 static Uint8 *
251 DSOUND_GetDeviceBuf(_THIS)
252 {
253  DWORD cursor = 0;
254  DWORD junk = 0;
255  HRESULT result = DS_OK;
256  DWORD rawlen = 0;
257 
258  /* Figure out which blocks to fill next */
259  this->hidden->locked_buf = NULL;
260  result = IDirectSoundBuffer_GetCurrentPosition(this->hidden->mixbuf,
261  &junk, &cursor);
262  if (result == DSERR_BUFFERLOST) {
263  IDirectSoundBuffer_Restore(this->hidden->mixbuf);
264  result = IDirectSoundBuffer_GetCurrentPosition(this->hidden->mixbuf,
265  &junk, &cursor);
266  }
267  if (result != DS_OK) {
268  SetDSerror("DirectSound GetCurrentPosition", result);
269  return (NULL);
270  }
271  cursor /= this->spec.size;
272 #ifdef DEBUG_SOUND
273  /* Detect audio dropouts */
274  {
275  DWORD spot = cursor;
276  if (spot < this->hidden->lastchunk) {
277  spot += this->hidden->num_buffers;
278  }
279  if (spot > this->hidden->lastchunk + 1) {
280  fprintf(stderr, "Audio dropout, missed %d fragments\n",
281  (spot - (this->hidden->lastchunk + 1)));
282  }
283  }
284 #endif
285  this->hidden->lastchunk = cursor;
286  cursor = (cursor + 1) % this->hidden->num_buffers;
287  cursor *= this->spec.size;
288 
289  /* Lock the audio buffer */
290  result = IDirectSoundBuffer_Lock(this->hidden->mixbuf, cursor,
291  this->spec.size,
292  (LPVOID *) & this->hidden->locked_buf,
293  &rawlen, NULL, &junk, 0);
294  if (result == DSERR_BUFFERLOST) {
295  IDirectSoundBuffer_Restore(this->hidden->mixbuf);
296  result = IDirectSoundBuffer_Lock(this->hidden->mixbuf, cursor,
297  this->spec.size,
298  (LPVOID *) & this->
299  hidden->locked_buf, &rawlen, NULL,
300  &junk, 0);
301  }
302  if (result != DS_OK) {
303  SetDSerror("DirectSound Lock", result);
304  return (NULL);
305  }
306  return (this->hidden->locked_buf);
307 }
308 
309 static int
310 DSOUND_CaptureFromDevice(_THIS, void *buffer, int buflen)
311 {
312  struct SDL_PrivateAudioData *h = this->hidden;
313  DWORD junk, cursor, ptr1len, ptr2len;
314  VOID *ptr1, *ptr2;
315 
316  SDL_assert(buflen == this->spec.size);
317 
318  while (SDL_TRUE) {
319  if (SDL_AtomicGet(&this->shutdown)) { /* in case the buffer froze... */
320  SDL_memset(buffer, this->spec.silence, buflen);
321  return buflen;
322  }
323 
324  if (IDirectSoundCaptureBuffer_GetCurrentPosition(h->capturebuf, &junk, &cursor) != DS_OK) {
325  return -1;
326  }
327  if ((cursor / this->spec.size) == h->lastchunk) {
328  SDL_Delay(1); /* FIXME: find out how much time is left and sleep that long */
329  } else {
330  break;
331  }
332  }
333 
334  if (IDirectSoundCaptureBuffer_Lock(h->capturebuf, h->lastchunk * this->spec.size, this->spec.size, &ptr1, &ptr1len, &ptr2, &ptr2len, 0) != DS_OK) {
335  return -1;
336  }
337 
338  SDL_assert(ptr1len == this->spec.size);
339  SDL_assert(ptr2 == NULL);
340  SDL_assert(ptr2len == 0);
341 
342  SDL_memcpy(buffer, ptr1, ptr1len);
343 
344  if (IDirectSoundCaptureBuffer_Unlock(h->capturebuf, ptr1, ptr1len, ptr2, ptr2len) != DS_OK) {
345  return -1;
346  }
347 
348  h->lastchunk = (h->lastchunk + 1) % h->num_buffers;
349 
350  return ptr1len;
351 }
352 
353 static void
354 DSOUND_FlushCapture(_THIS)
355 {
356  struct SDL_PrivateAudioData *h = this->hidden;
357  DWORD junk, cursor;
358  if (IDirectSoundCaptureBuffer_GetCurrentPosition(h->capturebuf, &junk, &cursor) == DS_OK) {
359  h->lastchunk = cursor / this->spec.size;
360  }
361 }
362 
363 static void
364 DSOUND_CloseDevice(_THIS)
365 {
366  if (this->hidden->mixbuf != NULL) {
367  IDirectSoundBuffer_Stop(this->hidden->mixbuf);
368  IDirectSoundBuffer_Release(this->hidden->mixbuf);
369  }
370  if (this->hidden->sound != NULL) {
371  IDirectSound_Release(this->hidden->sound);
372  }
373  if (this->hidden->capturebuf != NULL) {
374  IDirectSoundCaptureBuffer_Stop(this->hidden->capturebuf);
375  IDirectSoundCaptureBuffer_Release(this->hidden->capturebuf);
376  }
377  if (this->hidden->capture != NULL) {
378  IDirectSoundCapture_Release(this->hidden->capture);
379  }
380  SDL_free(this->hidden);
381 }
382 
383 /* This function tries to create a secondary audio buffer, and returns the
384  number of audio chunks available in the created buffer. This is for
385  playback devices, not capture.
386 */
387 static int
388 CreateSecondary(_THIS, const DWORD bufsize, WAVEFORMATEX *wfmt)
389 {
390  LPDIRECTSOUND sndObj = this->hidden->sound;
391  LPDIRECTSOUNDBUFFER *sndbuf = &this->hidden->mixbuf;
392  HRESULT result = DS_OK;
393  DSBUFFERDESC format;
394  LPVOID pvAudioPtr1, pvAudioPtr2;
395  DWORD dwAudioBytes1, dwAudioBytes2;
396 
397  /* Try to create the secondary buffer */
398  SDL_zero(format);
399  format.dwSize = sizeof(format);
400  format.dwFlags = DSBCAPS_GETCURRENTPOSITION2;
401  format.dwFlags |= DSBCAPS_GLOBALFOCUS;
402  format.dwBufferBytes = bufsize;
403  format.lpwfxFormat = wfmt;
404  result = IDirectSound_CreateSoundBuffer(sndObj, &format, sndbuf, NULL);
405  if (result != DS_OK) {
406  return SetDSerror("DirectSound CreateSoundBuffer", result);
407  }
408  IDirectSoundBuffer_SetFormat(*sndbuf, wfmt);
409 
410  /* Silence the initial audio buffer */
411  result = IDirectSoundBuffer_Lock(*sndbuf, 0, format.dwBufferBytes,
412  (LPVOID *) & pvAudioPtr1, &dwAudioBytes1,
413  (LPVOID *) & pvAudioPtr2, &dwAudioBytes2,
414  DSBLOCK_ENTIREBUFFER);
415  if (result == DS_OK) {
416  SDL_memset(pvAudioPtr1, this->spec.silence, dwAudioBytes1);
417  IDirectSoundBuffer_Unlock(*sndbuf,
418  (LPVOID) pvAudioPtr1, dwAudioBytes1,
419  (LPVOID) pvAudioPtr2, dwAudioBytes2);
420  }
421 
422  /* We're ready to go */
423  return 0;
424 }
425 
426 /* This function tries to create a capture buffer, and returns the
427  number of audio chunks available in the created buffer. This is for
428  capture devices, not playback.
429 */
430 static int
431 CreateCaptureBuffer(_THIS, const DWORD bufsize, WAVEFORMATEX *wfmt)
432 {
433  LPDIRECTSOUNDCAPTURE capture = this->hidden->capture;
434  LPDIRECTSOUNDCAPTUREBUFFER *capturebuf = &this->hidden->capturebuf;
435  DSCBUFFERDESC format;
436  HRESULT result;
437 
438  SDL_zero(format);
439  format.dwSize = sizeof (format);
440  format.dwFlags = DSCBCAPS_WAVEMAPPED;
441  format.dwBufferBytes = bufsize;
442  format.lpwfxFormat = wfmt;
443 
444  result = IDirectSoundCapture_CreateCaptureBuffer(capture, &format, capturebuf, NULL);
445  if (result != DS_OK) {
446  return SetDSerror("DirectSound CreateCaptureBuffer", result);
447  }
448 
449  result = IDirectSoundCaptureBuffer_Start(*capturebuf, DSCBSTART_LOOPING);
450  if (result != DS_OK) {
451  IDirectSoundCaptureBuffer_Release(*capturebuf);
452  return SetDSerror("DirectSound Start", result);
453  }
454 
455 #if 0
456  /* presumably this starts at zero, but just in case... */
457  result = IDirectSoundCaptureBuffer_GetCurrentPosition(*capturebuf, &junk, &cursor);
458  if (result != DS_OK) {
459  IDirectSoundCaptureBuffer_Stop(*capturebuf);
460  IDirectSoundCaptureBuffer_Release(*capturebuf);
461  return SetDSerror("DirectSound GetCurrentPosition", result);
462  }
463 
464  this->hidden->lastchunk = cursor / this->spec.size;
465 #endif
466 
467  return 0;
468 }
469 
470 static int
471 DSOUND_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
472 {
473  const DWORD numchunks = 8;
474  HRESULT result;
475  SDL_bool valid_format = SDL_FALSE;
476  SDL_bool tried_format = SDL_FALSE;
477  SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format);
478  LPGUID guid = (LPGUID) handle;
479  DWORD bufsize;
480 
481  /* Initialize all variables that we clean on shutdown */
482  this->hidden = (struct SDL_PrivateAudioData *)
483  SDL_malloc((sizeof *this->hidden));
484  if (this->hidden == NULL) {
485  return SDL_OutOfMemory();
486  }
487  SDL_zerop(this->hidden);
488 
489  /* Open the audio device */
490  if (iscapture) {
491  result = pDirectSoundCaptureCreate8(guid, &this->hidden->capture, NULL);
492  if (result != DS_OK) {
493  return SetDSerror("DirectSoundCaptureCreate8", result);
494  }
495  } else {
496  result = pDirectSoundCreate8(guid, &this->hidden->sound, NULL);
497  if (result != DS_OK) {
498  return SetDSerror("DirectSoundCreate8", result);
499  }
500  result = IDirectSound_SetCooperativeLevel(this->hidden->sound,
501  GetDesktopWindow(),
502  DSSCL_NORMAL);
503  if (result != DS_OK) {
504  return SetDSerror("DirectSound SetCooperativeLevel", result);
505  }
506  }
507 
508  while ((!valid_format) && (test_format)) {
509  switch (test_format) {
510  case AUDIO_U8:
511  case AUDIO_S16:
512  case AUDIO_S32:
513  case AUDIO_F32:
514  tried_format = SDL_TRUE;
515 
516  this->spec.format = test_format;
517 
518  /* Update the fragment size as size in bytes */
520 
521  bufsize = numchunks * this->spec.size;
522  if ((bufsize < DSBSIZE_MIN) || (bufsize > DSBSIZE_MAX)) {
523  SDL_SetError("Sound buffer size must be between %d and %d",
524  (int) ((DSBSIZE_MIN < numchunks) ? 1 : DSBSIZE_MIN / numchunks),
525  (int) (DSBSIZE_MAX / numchunks));
526  } else {
527  int rc;
528  WAVEFORMATEX wfmt;
529  SDL_zero(wfmt);
530  if (SDL_AUDIO_ISFLOAT(this->spec.format)) {
531  wfmt.wFormatTag = WAVE_FORMAT_IEEE_FLOAT;
532  } else {
533  wfmt.wFormatTag = WAVE_FORMAT_PCM;
534  }
535 
536  wfmt.wBitsPerSample = SDL_AUDIO_BITSIZE(this->spec.format);
537  wfmt.nChannels = this->spec.channels;
538  wfmt.nSamplesPerSec = this->spec.freq;
539  wfmt.nBlockAlign = wfmt.nChannels * (wfmt.wBitsPerSample / 8);
540  wfmt.nAvgBytesPerSec = wfmt.nSamplesPerSec * wfmt.nBlockAlign;
541 
542  rc = iscapture ? CreateCaptureBuffer(this, bufsize, &wfmt) : CreateSecondary(this, bufsize, &wfmt);
543  if (rc == 0) {
544  this->hidden->num_buffers = numchunks;
545  valid_format = SDL_TRUE;
546  }
547  }
548  break;
549  }
550  test_format = SDL_NextAudioFormat();
551  }
552 
553  if (!valid_format) {
554  if (tried_format) {
555  return -1; /* CreateSecondary() should have called SDL_SetError(). */
556  }
557  return SDL_SetError("DirectSound: Unsupported audio format");
558  }
559 
560  /* Playback buffers will auto-start playing in DSOUND_WaitDevice() */
561 
562  return 0; /* good to go. */
563 }
564 
565 
566 static void
567 DSOUND_Deinitialize(void)
568 {
569  DSOUND_Unload();
570 }
571 
572 
573 static int
574 DSOUND_Init(SDL_AudioDriverImpl * impl)
575 {
576  if (!DSOUND_Load()) {
577  return 0;
578  }
579 
580  /* Set the function pointers */
581  impl->DetectDevices = DSOUND_DetectDevices;
582  impl->OpenDevice = DSOUND_OpenDevice;
583  impl->PlayDevice = DSOUND_PlayDevice;
584  impl->WaitDevice = DSOUND_WaitDevice;
585  impl->GetDeviceBuf = DSOUND_GetDeviceBuf;
586  impl->CaptureFromDevice = DSOUND_CaptureFromDevice;
587  impl->FlushCapture = DSOUND_FlushCapture;
588  impl->CloseDevice = DSOUND_CloseDevice;
589  impl->FreeDeviceHandle = DSOUND_FreeDeviceHandle;
590  impl->Deinitialize = DSOUND_Deinitialize;
591 
592  impl->HasCaptureSupport = SDL_TRUE;
593 
594  return 1; /* this audio target is available. */
595 }
596 
598  "directsound", "DirectSound", DSOUND_Init, 0
599 };
600 
601 #endif /* SDL_AUDIO_DRIVER_DSOUND */
602 
603 /* vi: set ts=4 sw=4 expandtab: */
#define _THIS
#define SDL_assert(condition)
Definition: SDL_assert.h:171
void SDL_AddAudioDevice(const int iscapture, const char *name, void *handle)
Definition: SDL_audio.c:472
void SDL_CalculateAudioSpec(SDL_AudioSpec *spec)
Definition: SDL_audio.c:1689
SDL_AudioFormat SDL_FirstAudioFormat(SDL_AudioFormat format)
Definition: SDL_audio.c:1650
SDL_AudioFormat SDL_NextAudioFormat(void)
Definition: SDL_audio.c:1662
#define AUDIO_F32
Definition: SDL_audio.h:114
Uint16 SDL_AudioFormat
Audio format flags.
Definition: SDL_audio.h:64
#define AUDIO_S16
Definition: SDL_audio.h:96
#define AUDIO_U8
Definition: SDL_audio.h:89
#define SDL_AUDIO_ISFLOAT(x)
Definition: SDL_audio.h:76
#define AUDIO_S32
Definition: SDL_audio.h:105
#define SDL_AUDIO_BITSIZE(x)
Definition: SDL_audio.h:75
#define E_NOINTERFACE
Definition: SDL_directx.h:61
#define SDL_SetError
#define SDL_memset
#define SDL_LoadObject
#define SDL_UnloadObject
#define SDL_malloc
#define SDL_free
#define SDL_Delay
#define SDL_AtomicGet
#define SDL_memcpy
#define SDL_snprintf
#define SDL_OutOfMemory()
Definition: SDL_error.h:88
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: SDL_opengl.h:1974
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: SDL_opengl.h:1572
GLuint64EXT * result
GLuint buffer
GLenum GLuint GLsizei bufsize
GLfloat GLfloat GLfloat GLfloat h
#define SDL_zero(x)
Definition: SDL_stdinc.h:426
SDL_bool
Definition: SDL_stdinc.h:168
@ SDL_TRUE
Definition: SDL_stdinc.h:170
@ SDL_FALSE
Definition: SDL_stdinc.h:169
#define SDL_arraysize(array)
Definition: SDL_stdinc.h:121
uint8_t Uint8
Definition: SDL_stdinc.h:185
#define SDL_zerop(x)
Definition: SDL_stdinc.h:427
AudioBootStrap DSOUND_bootstrap
char * WIN_LookupAudioDeviceName(const WCHAR *name, const GUID *guid)
#define NULL
Definition: begin_code.h:163
#define TRUE
Definition: edid-parse.c:33
EGLImageKHR EGLint EGLint * handle
Definition: eglext.h:937
SDL_AudioSpec spec
Definition: loopwave.c:31
void(* PlayDevice)(_THIS)
Definition: SDL_sysaudio.h:73
void(* WaitDevice)(_THIS)
Definition: SDL_sysaudio.h:72
void(* CloseDevice)(_THIS)
Definition: SDL_sysaudio.h:78
void(* FlushCapture)(_THIS)
Definition: SDL_sysaudio.h:76
void(* DetectDevices)(void)
Definition: SDL_sysaudio.h:67
Uint8 *(* GetDeviceBuf)(_THIS)
Definition: SDL_sysaudio.h:74
void(* Deinitialize)(void)
Definition: SDL_sysaudio.h:82
int(* CaptureFromDevice)(_THIS, void *buffer, int buflen)
Definition: SDL_sysaudio.h:75
void(* FreeDeviceHandle)(void *handle)
Definition: SDL_sysaudio.h:81
int(* OpenDevice)(_THIS, void *handle, const char *devname, int iscapture)
Definition: SDL_sysaudio.h:68
Uint32 size
Definition: SDL_audio.h:186
Uint8 channels
Definition: SDL_audio.h:182
Uint8 silence
Definition: SDL_audio.h:183
SDL_AudioFormat format
Definition: SDL_audio.h:181
LPDIRECTSOUNDCAPTUREBUFFER capturebuf
SDL_atomic_t shutdown
Definition: SDL_coreaudio.h:57
LPDIRECTSOUNDCAPTURE capture
SDL_Cursor * cursor
Definition: testwm2.c:40
typedef int(__stdcall *FARPROC)()