SDL 2.0
SDL_directsound.c
Go to the documentation of this file.
1/*
2 Simple DirectMedia Layer
3 Copyright (C) 1997-2019 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 */
39static void* DSoundDLL = NULL;
40typedef HRESULT (WINAPI *fnDirectSoundCreate8)(LPGUID,LPDIRECTSOUND*,LPUNKNOWN);
41typedef HRESULT (WINAPI *fnDirectSoundEnumerateW)(LPDSENUMCALLBACKW, LPVOID);
42typedef HRESULT (WINAPI *fnDirectSoundCaptureCreate8)(LPCGUID,LPDIRECTSOUNDCAPTURE8 *,LPUNKNOWN);
43typedef HRESULT (WINAPI *fnDirectSoundCaptureEnumerateW)(LPDSENUMCALLBACKW,LPVOID);
44static fnDirectSoundCreate8 pDirectSoundCreate8 = NULL;
45static fnDirectSoundEnumerateW pDirectSoundEnumerateW = NULL;
46static fnDirectSoundCaptureCreate8 pDirectSoundCaptureCreate8 = NULL;
47static fnDirectSoundCaptureEnumerateW pDirectSoundCaptureEnumerateW = NULL;
48
49static void
50DSOUND_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
64static int
65DSOUND_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
99static int
100SetDSerror(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
152static void
153DSOUND_FreeDeviceHandle(void *handle)
154{
156}
157
158static BOOL CALLBACK
159FindAllDevs(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
174static void
175DSOUND_DetectDevices(void)
176{
177 pDirectSoundCaptureEnumerateW(FindAllDevs, (void *) ((size_t) 1));
178 pDirectSoundEnumerateW(FindAllDevs, (void *) ((size_t) 0));
179}
180
181
182static void
183DSOUND_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
240static void
241DSOUND_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
251static Uint8 *
252DSOUND_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
310static int
311DSOUND_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
354static void
355DSOUND_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
364static void
365DSOUND_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*/
388static int
389CreateSecondary(_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 */
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*/
431static int
432CreateCaptureBuffer(_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
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
471static int
472DSOUND_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
567static void
568DSOUND_Deinitialize(void)
569{
570 DSOUND_Unload();
571}
572
573
574static int
575DSOUND_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
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: */
#define _THIS
#define SDL_assert(condition)
Definition: SDL_assert.h:169
void SDL_AddAudioDevice(const int iscapture, const char *name, void *handle)
Definition: SDL_audio.c:469
void SDL_CalculateAudioSpec(SDL_AudioSpec *spec)
Definition: SDL_audio.c:1668
SDL_AudioFormat SDL_FirstAudioFormat(SDL_AudioFormat format)
Definition: SDL_audio.c:1647
SDL_AudioFormat SDL_NextAudioFormat(void)
Definition: SDL_audio.c:1659
#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:52
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:416
SDL_bool
Definition: SDL_stdinc.h:162
@ SDL_TRUE
Definition: SDL_stdinc.h:164
@ SDL_FALSE
Definition: SDL_stdinc.h:163
#define SDL_arraysize(array)
Definition: SDL_stdinc.h:115
#define SDL_zerop(x)
Definition: SDL_stdinc.h:417
uint8_t Uint8
Definition: SDL_stdinc.h:179
AudioBootStrap DSOUND_bootstrap
char * WIN_LookupAudioDeviceName(const WCHAR *name, const GUID *guid)
#define NULL
Definition: begin_code.h:167
#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
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
Uint8 *(* GetDeviceBuf)(_THIS)
Definition: SDL_sysaudio.h:74
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