SDL  2.0
SDL_directsound.c
Go to the documentation of this file.
1 /*
2  Simple DirectMedia Layer
3  Copyright (C) 1997-2016 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 // DWORD junk, cursor;
438  HRESULT result;
439 
440  SDL_zero(format);
441  format.dwSize = sizeof (format);
442  format.dwFlags = DSCBCAPS_WAVEMAPPED;
443  format.dwBufferBytes = bufsize;
444  format.lpwfxFormat = wfmt;
445 
446  result = IDirectSoundCapture_CreateCaptureBuffer(capture, &format, capturebuf, NULL);
447  if (result != DS_OK) {
448  return SetDSerror("DirectSound CreateCaptureBuffer", result);
449  }
450 
451  result = IDirectSoundCaptureBuffer_Start(*capturebuf, DSCBSTART_LOOPING);
452  if (result != DS_OK) {
453  IDirectSoundCaptureBuffer_Release(*capturebuf);
454  return SetDSerror("DirectSound Start", result);
455  }
456 
457 #if 0
458  /* presumably this starts at zero, but just in case... */
459  result = IDirectSoundCaptureBuffer_GetCurrentPosition(*capturebuf, &junk, &cursor);
460  if (result != DS_OK) {
461  IDirectSoundCaptureBuffer_Stop(*capturebuf);
462  IDirectSoundCaptureBuffer_Release(*capturebuf);
463  return SetDSerror("DirectSound GetCurrentPosition", result);
464  }
465 
466  this->hidden->lastchunk = cursor / this->spec.size;
467 #endif
468 
469  return 0;
470 }
471 
472 static int
473 DSOUND_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
474 {
475  const DWORD numchunks = 8;
476  HRESULT result;
477  SDL_bool valid_format = SDL_FALSE;
478  SDL_bool tried_format = SDL_FALSE;
479  SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format);
480  LPGUID guid = (LPGUID) handle;
481  DWORD bufsize;
482 
483  /* Initialize all variables that we clean on shutdown */
484  this->hidden = (struct SDL_PrivateAudioData *)
485  SDL_malloc((sizeof *this->hidden));
486  if (this->hidden == NULL) {
487  return SDL_OutOfMemory();
488  }
489  SDL_zerop(this->hidden);
490 
491  /* Open the audio device */
492  if (iscapture) {
493  result = pDirectSoundCaptureCreate8(guid, &this->hidden->capture, NULL);
494  if (result != DS_OK) {
495  return SetDSerror("DirectSoundCaptureCreate8", result);
496  }
497  } else {
498  result = pDirectSoundCreate8(guid, &this->hidden->sound, NULL);
499  if (result != DS_OK) {
500  return SetDSerror("DirectSoundCreate8", result);
501  }
502  result = IDirectSound_SetCooperativeLevel(this->hidden->sound,
503  GetDesktopWindow(),
504  DSSCL_NORMAL);
505  if (result != DS_OK) {
506  return SetDSerror("DirectSound SetCooperativeLevel", result);
507  }
508  }
509 
510  while ((!valid_format) && (test_format)) {
511  switch (test_format) {
512  case AUDIO_U8:
513  case AUDIO_S16:
514  case AUDIO_S32:
515  case AUDIO_F32:
516  tried_format = SDL_TRUE;
517 
518  this->spec.format = test_format;
519 
520  /* Update the fragment size as size in bytes */
522 
523  bufsize = numchunks * this->spec.size;
524  if ((bufsize < DSBSIZE_MIN) || (bufsize > DSBSIZE_MAX)) {
525  SDL_SetError("Sound buffer size must be between %d and %d",
526  (DSBSIZE_MIN < numchunks) ? 1 : DSBSIZE_MIN / numchunks,
527  DSBSIZE_MAX / numchunks);
528  } else {
529  int rc;
530  WAVEFORMATEX wfmt;
531  SDL_zero(wfmt);
532  if (SDL_AUDIO_ISFLOAT(this->spec.format)) {
533  wfmt.wFormatTag = WAVE_FORMAT_IEEE_FLOAT;
534  } else {
535  wfmt.wFormatTag = WAVE_FORMAT_PCM;
536  }
537 
538  wfmt.wBitsPerSample = SDL_AUDIO_BITSIZE(this->spec.format);
539  wfmt.nChannels = this->spec.channels;
540  wfmt.nSamplesPerSec = this->spec.freq;
541  wfmt.nBlockAlign = wfmt.nChannels * (wfmt.wBitsPerSample / 8);
542  wfmt.nAvgBytesPerSec = wfmt.nSamplesPerSec * wfmt.nBlockAlign;
543 
544  rc = iscapture ? CreateCaptureBuffer(this, bufsize, &wfmt) : CreateSecondary(this, bufsize, &wfmt);
545  if (rc == 0) {
546  this->hidden->num_buffers = numchunks;
547  valid_format = SDL_TRUE;
548  }
549  }
550  break;
551  }
552  test_format = SDL_NextAudioFormat();
553  }
554 
555  if (!valid_format) {
556  if (tried_format) {
557  return -1; /* CreateSecondary() should have called SDL_SetError(). */
558  }
559  return SDL_SetError("DirectSound: Unsupported audio format");
560  }
561 
562  /* Playback buffers will auto-start playing in DSOUND_WaitDevice() */
563 
564  return 0; /* good to go. */
565 }
566 
567 
568 static void
569 DSOUND_Deinitialize(void)
570 {
571  DSOUND_Unload();
572 }
573 
574 
575 static int
576 DSOUND_Init(SDL_AudioDriverImpl * impl)
577 {
578  if (!DSOUND_Load()) {
579  return 0;
580  }
581 
582  /* Set the function pointers */
583  impl->DetectDevices = DSOUND_DetectDevices;
584  impl->OpenDevice = DSOUND_OpenDevice;
585  impl->PlayDevice = DSOUND_PlayDevice;
586  impl->WaitDevice = DSOUND_WaitDevice;
587  impl->GetDeviceBuf = DSOUND_GetDeviceBuf;
588  impl->CaptureFromDevice = DSOUND_CaptureFromDevice;
589  impl->FlushCapture = DSOUND_FlushCapture;
590  impl->CloseDevice = DSOUND_CloseDevice;
591  impl->FreeDeviceHandle = DSOUND_FreeDeviceHandle;
592  impl->Deinitialize = DSOUND_Deinitialize;
593 
594  impl->HasCaptureSupport = SDL_TRUE;
595 
596  return 1; /* this audio target is available. */
597 }
598 
600  "directsound", "DirectSound", DSOUND_Init, 0
601 };
602 
603 #endif /* SDL_AUDIO_DRIVER_DSOUND */
604 
605 /* vi: set ts=4 sw=4 expandtab: */
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: SDL_opengl.h:1565
SDL_AudioFormat SDL_FirstAudioFormat(SDL_AudioFormat format)
Definition: SDL_audio.c:1611
GLuint64EXT * result
void(* DetectDevices)(void)
Definition: SDL_sysaudio.h:75
Uint8 silence
Definition: SDL_audio.h:173
LPDIRECTSOUNDCAPTUREBUFFER capturebuf
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: SDL_opengl.h:1967
void(* PlayDevice)(_THIS)
Definition: SDL_sysaudio.h:79
void(* WaitDevice)(_THIS)
Definition: SDL_sysaudio.h:78
Uint16 SDL_AudioFormat
Audio format flags.
Definition: SDL_audio.h:64
AudioBootStrap DSOUND_bootstrap
#define SDL_LoadObject
#define SDL_UnloadObject
#define SDL_zerop(x)
Definition: SDL_stdinc.h:360
SDL_AudioFormat SDL_NextAudioFormat(void)
Definition: SDL_audio.c:1623
GLenum GLuint GLsizei bufsize
#define E_NOINTERFACE
Definition: SDL_directx.h:61
SDL_AudioSpec spec
Definition: loopwave.c:35
#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)
LPDIRECTSOUNDCAPTURE capture
Uint8 channels
Definition: SDL_audio.h:172
#define _THIS
uint8_t Uint8
An unsigned 8-bit integer type.
Definition: SDL_stdinc.h:143
void SDL_free(void *mem)
#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:89
#define SDL_zero(x)
Definition: SDL_stdinc.h:359
void SDL_CalculateAudioSpec(SDL_AudioSpec *spec)
Definition: SDL_audio.c:1632
#define SDL_Delay
SDL_Cursor * cursor
Uint32 size
Definition: SDL_audio.h:176
#define SDL_assert(condition)
Definition: SDL_assert.h:167
int(* OpenDevice)(_THIS, void *handle, const char *devname, int iscapture)
Definition: SDL_sysaudio.h:76
#define NULL
Definition: begin_code.h:143
#define SDL_OutOfMemory()
Definition: SDL_error.h:52
SDL_bool
Definition: SDL_stdinc.h:130
int(* CaptureFromDevice)(_THIS, void *buffer, int buflen)
Definition: SDL_sysaudio.h:82
#define SDL_SetError
void(* CloseDevice)(_THIS)
Definition: SDL_sysaudio.h:85
void(* FreeDeviceHandle)(void *handle)
Definition: SDL_sysaudio.h:88
SDL_AudioFormat format
Definition: SDL_audio.h:171
void(* FlushCapture)(_THIS)
Definition: SDL_sysaudio.h:83
GLuint buffer
#define AUDIO_S16
Definition: SDL_audio.h:96
Uint8 *(* GetDeviceBuf)(_THIS)
Definition: SDL_sysaudio.h:81
#define SDL_AtomicGet
#define SDL_snprintf
#define SDL_arraysize(array)
Definition: SDL_stdinc.h:90
#define SDL_malloc
#define AUDIO_F32
Definition: SDL_audio.h:114
GLfloat GLfloat GLfloat GLfloat h
#define SDL_memset
void SDL_AddAudioDevice(const int iscapture, const char *name, void *handle)
Definition: SDL_audio.c:364