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