zenilib: zenilib/jni/external/openal-soft/Alc/backends/mmdevapi.c Source File

zenilib 0.5.3.0

- Main Page
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
mmdevapi.c
Go to the documentation of this file.
1
21 #include "config.h"
22
23 #define COBJMACROS
24 #include <stdlib.h>
25 #include <stdio.h>
26 #include <memory.h>
27
28 #include <mmdeviceapi.h>
29 #include <audioclient.h>
30 #include <cguid.h>
31 #include <devpropdef.h>
32 #include <mmreg.h>
33 #include <propsys.h>
34 #include <propkey.h>
35 #include <devpkey.h>
36 #ifndef _WAVEFORMATEXTENSIBLE_
37 #include <ks.h>
38 #include <ksmedia.h>
39 #endif
40
41 #include "alMain.h"
42 #include "alu.h"
43
44
45 DEFINE_GUID(KSDATAFORMAT_SUBTYPE_PCM, 0x00000001, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
46 DEFINE_GUID(KSDATAFORMAT_SUBTYPE_IEEE_FLOAT, 0x00000003, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
47
48 DEFINE_DEVPROPKEY(DEVPKEY_Device_FriendlyName, 0xa45c254e, 0xdf1c, 0x4efd, 0x80,0x20, 0x67,0xd1,0x46,0xa8,0x50,0xe0, 14);
49
50 #define MONO SPEAKER_FRONT_CENTER
51 #define STEREO (SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT)
52 #define QUAD (SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT|SPEAKER_BACK_LEFT|SPEAKER_BACK_RIGHT)
53 #define X5DOT1 (SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT|SPEAKER_FRONT_CENTER|SPEAKER_LOW_FREQUENCY|SPEAKER_BACK_LEFT|SPEAKER_BACK_RIGHT)
54 #define X5DOT1SIDE (SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT|SPEAKER_FRONT_CENTER|SPEAKER_LOW_FREQUENCY|SPEAKER_SIDE_LEFT|SPEAKER_SIDE_RIGHT)
55 #define X6DOT1 (SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT|SPEAKER_FRONT_CENTER|SPEAKER_LOW_FREQUENCY|SPEAKER_BACK_CENTER|SPEAKER_SIDE_LEFT|SPEAKER_SIDE_RIGHT)
56 #define X7DOT1 (SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT|SPEAKER_FRONT_CENTER|SPEAKER_LOW_FREQUENCY|SPEAKER_BACK_LEFT|SPEAKER_BACK_RIGHT|SPEAKER_SIDE_LEFT|SPEAKER_SIDE_RIGHT)
57
58
59 typedef struct {
60 WCHAR *devid;
61
62 IMMDevice *mmdev;
63 IAudioClient *client;
64 IAudioRenderClient *render;
65 HANDLE NotifyEvent;
66
67 HANDLE MsgEvent;
68
69 volatile UINT32 Padding;
70
71 volatile int killNow;
72 ALvoid *thread;
73 } MMDevApiData;
74
75
76 typedef struct {
77 ALCchar *name;
78 WCHAR *devid;
79 } DevMap;
80
81 static DevMap *PlaybackDeviceList;
82 static ALuint NumPlaybackDevices;
83 static DevMap *CaptureDeviceList;
84 static ALuint NumCaptureDevices;
85
86
87 static HANDLE ThreadHdl;
88 static DWORD ThreadID;
89
90 typedef struct {
91 HANDLE FinishedEvt;
92 HRESULT result;
93 } ThreadRequest;
94
95 #define WM_USER_OpenDevice (WM_USER+0)
96 #define WM_USER_ResetDevice (WM_USER+1)
97 #define WM_USER_StartDevice (WM_USER+2)
98 #define WM_USER_StopDevice (WM_USER+3)
99 #define WM_USER_CloseDevice (WM_USER+4)
100 #define WM_USER_Enumerate (WM_USER+5)
101
102 static HRESULT WaitForResponse(ThreadRequest *req)
103 {
104 if(WaitForSingleObject(req->FinishedEvt, INFINITE) == WAIT_OBJECT_0)
105 return req->result;
106 ERR("Message response error: %lu\n", GetLastError());
107 return E_FAIL;
108 }
109
110
111 static ALCchar *get_device_name(IMMDevice *device)
112 {
113 ALCchar *name = NULL;
114 IPropertyStore *ps;
115 PROPVARIANT pvname;
116 HRESULT hr;
117 int len;
118
119 hr = IMMDevice_OpenPropertyStore(device, STGM_READ, &ps);
120 if(FAILED(hr))
121 {
122 WARN("OpenPropertyStore failed: 0x%08lx\n", hr);
123 return calloc(1, 1);
124 }
125
126 PropVariantInit(&pvname);
127
128 hr = IPropertyStore_GetValue(ps, (const PROPERTYKEY*)&DEVPKEY_Device_FriendlyName, &pvname);
129 if(FAILED(hr))
130 {
131 WARN("GetValue failed: 0x%08lx\n", hr);
132 name = calloc(1, 1);
133 }
134 else
135 {
136 if((len=WideCharToMultiByte(CP_ACP, 0, pvname.pwszVal, -1, NULL, 0, NULL, NULL)) > 0)
137 {
138 name = calloc(1, len);
139 WideCharToMultiByte(CP_ACP, 0, pvname.pwszVal, -1, name, len, NULL, NULL);
140 }
141 }
142
143 PropVariantClear(&pvname);
144 IPropertyStore_Release(ps);
145
146 return name;
147 }
148
149 static void add_device(IMMDevice *device, DevMap *devmap)
150 {
151 LPWSTR devid;
152 HRESULT hr;
153
154 hr = IMMDevice_GetId(device, &devid);
155 if(SUCCEEDED(hr))
156 {
157 devmap->devid = strdupW(devid);
158 devmap->name = get_device_name(device);
159 TRACE("Got device \"%s\", \"%ls\"\n", devmap->name, devmap->devid);
160 CoTaskMemFree(devid);
161 }
162 }
163
164 static DevMap *ProbeDevices(IMMDeviceEnumerator *devenum, EDataFlow flowdir, ALuint *numdevs)
165 {
166 IMMDeviceCollection *coll;
167 IMMDevice *defdev = NULL;
168 DevMap *devlist = NULL;
169 HRESULT hr;
170 UINT count;
171 UINT idx;
172 UINT i;
173
174 hr = IMMDeviceEnumerator_EnumAudioEndpoints(devenum, flowdir, DEVICE_STATE_ACTIVE, &coll);
175 if(FAILED(hr))
176 {
177 ERR("Failed to enumerate audio endpoints: 0x%08lx\n", hr);
178 return NULL;
179 }
180
181 idx = count = 0;
182 hr = IMMDeviceCollection_GetCount(coll, &count);
183 if(SUCCEEDED(hr) && count > 0)
184 {
185 devlist = calloc(count, sizeof(*devlist));
186 if(!devlist)
187 {
188 IMMDeviceCollection_Release(coll);
189 return NULL;
190 }
191
192 hr = IMMDeviceEnumerator_GetDefaultAudioEndpoint(devenum, flowdir,
193 eMultimedia, &defdev);
194 }
195 if(SUCCEEDED(hr) && defdev != NULL)
196 add_device(defdev, &devlist[idx++]);
197
198 for(i = 0;i < count && idx < count;++i)
199 {
200 IMMDevice *device;
201
202 if(FAILED(IMMDeviceCollection_Item(coll, i, &device)))
203 continue;
204
205 if(device != defdev)
206 add_device(device, &devlist[idx++]);
207
208 IMMDevice_Release(device);
209 }
210
211 if(defdev) IMMDevice_Release(defdev);
212 IMMDeviceCollection_Release(coll);
213
214 *numdevs = idx;
215 return devlist;
216 }
217
218
219 static ALuint MMDevApiProc(ALvoid *ptr)
220 {
221 ALCdevice *device = ptr;
222 MMDevApiData *data = device->ExtraData;
223 UINT32 buffer_len, written;
224 ALuint update_size, len;
225 BYTE *buffer;
226 HRESULT hr;
227
228 hr = CoInitialize(NULL);
229 if(FAILED(hr))
230 {
231 ERR("CoInitialize(NULL) failed: 0x%08lx\n", hr);
232 ALCdevice_Lock(device);
233 aluHandleDisconnect(device);
234 ALCdevice_Unlock(device);
235 return 0;
236 }
237
238 SetRTPriority();
239
240 update_size = device->UpdateSize;
241 buffer_len = update_size * device->NumUpdates;
242 while(!data->killNow)
243 {
244 hr = IAudioClient_GetCurrentPadding(data->client, &written);
245 if(FAILED(hr))
246 {
247 ERR("Failed to get padding: 0x%08lx\n", hr);
248 ALCdevice_Lock(device);
249 aluHandleDisconnect(device);
250 ALCdevice_Unlock(device);
251 break;
252 }
253 data->Padding = written;
254
255 len = buffer_len - written;
256 if(len < update_size)
257 {
258 DWORD res;
259 res = WaitForSingleObjectEx(data->NotifyEvent, 2000, FALSE);
260 if(res != WAIT_OBJECT_0)
261 ERR("WaitForSingleObjectEx error: 0x%lx\n", res);
262 continue;
263 }
264 len -= len%update_size;
265
266 hr = IAudioRenderClient_GetBuffer(data->render, len, &buffer);
267 if(SUCCEEDED(hr))
268 {
269 ALCdevice_Lock(device);
270 aluMixData(device, buffer, len);
271 data->Padding = written + len;
272 ALCdevice_Unlock(device);
273 hr = IAudioRenderClient_ReleaseBuffer(data->render, len, 0);
274 }
275 if(FAILED(hr))
276 {
277 ERR("Failed to buffer data: 0x%08lx\n", hr);
278 ALCdevice_Lock(device);
279 aluHandleDisconnect(device);
280 ALCdevice_Unlock(device);
281 break;
282 }
283 }
284 data->Padding = 0;
285
286 CoUninitialize();
287 return 0;
288 }
289
290
291 static ALCboolean MakeExtensible(WAVEFORMATEXTENSIBLE *out, const WAVEFORMATEX *in)
292 {
293 memset(out, 0, sizeof(*out));
294 if(in->wFormatTag == WAVE_FORMAT_EXTENSIBLE)
295 *out = *(const WAVEFORMATEXTENSIBLE*)in;
296 else if(in->wFormatTag == WAVE_FORMAT_PCM)
297 {
298 out->Format = *in;
299 out->Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
300 out->Format.cbSize = sizeof(*out) - sizeof(*in);
301 if(out->Format.nChannels == 1)
302 out->dwChannelMask = MONO;
303 else if(out->Format.nChannels == 2)
304 out->dwChannelMask = STEREO;
305 else
306 ERR("Unhandled PCM channel count: %d\n", out->Format.nChannels);
307 out->SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
308 }
309 else if(in->wFormatTag == WAVE_FORMAT_IEEE_FLOAT)
310 {
311 out->Format = *in;
312 out->Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
313 out->Format.cbSize = sizeof(*out) - sizeof(*in);
314 if(out->Format.nChannels == 1)
315 out->dwChannelMask = MONO;
316 else if(out->Format.nChannels == 2)
317 out->dwChannelMask = STEREO;
318 else
319 ERR("Unhandled IEEE float channel count: %d\n", out->Format.nChannels);
320 out->SubFormat = KSDATAFORMAT_SUBTYPE_IEEE_FLOAT;
321 }
322 else
323 {
324 ERR("Unhandled format tag: 0x%04x\n", in->wFormatTag);
325 return ALC_FALSE;
326 }
327 return ALC_TRUE;
328 }
329
330 static HRESULT DoReset(ALCdevice *device)
331 {
332 MMDevApiData *data = device->ExtraData;
333 WAVEFORMATEXTENSIBLE OutputType;
334 WAVEFORMATEX *wfx = NULL;
335 REFERENCE_TIME min_per, buf_time;
336 UINT32 buffer_len, min_len;
337 HRESULT hr;
338
339 hr = IAudioClient_GetMixFormat(data->client, &wfx);
340 if(FAILED(hr))
341 {
342 ERR("Failed to get mix format: 0x%08lx\n", hr);
343 return hr;
344 }
345
346 if(!MakeExtensible(&OutputType, wfx))
347 {
348 CoTaskMemFree(wfx);
349 return E_FAIL;
350 }
351 CoTaskMemFree(wfx);
352 wfx = NULL;
353
354 buf_time = ((REFERENCE_TIME)device->UpdateSize*device->NumUpdates*10000000 +
355 device->Frequency-1) / device->Frequency;
356
357 if(!(device->Flags&DEVICE_FREQUENCY_REQUEST))
358 device->Frequency = OutputType.Format.nSamplesPerSec;
359 if(!(device->Flags&DEVICE_CHANNELS_REQUEST))
360 {
361 if(OutputType.Format.nChannels == 1 && OutputType.dwChannelMask == MONO)
362 device->FmtChans = DevFmtMono;
363 else if(OutputType.Format.nChannels == 2 && OutputType.dwChannelMask == STEREO)
364 device->FmtChans = DevFmtStereo;
365 else if(OutputType.Format.nChannels == 4 && OutputType.dwChannelMask == QUAD)
366 device->FmtChans = DevFmtQuad;
367 else if(OutputType.Format.nChannels == 6 && OutputType.dwChannelMask == X5DOT1)
368 device->FmtChans = DevFmtX51;
369 else if(OutputType.Format.nChannels == 6 && OutputType.dwChannelMask == X5DOT1SIDE)
370 device->FmtChans = DevFmtX51Side;
371 else if(OutputType.Format.nChannels == 7 && OutputType.dwChannelMask == X6DOT1)
372 device->FmtChans = DevFmtX61;
373 else if(OutputType.Format.nChannels == 8 && OutputType.dwChannelMask == X7DOT1)
374 device->FmtChans = DevFmtX71;
375 else
376 ERR("Unhandled channel config: %d -- 0x%08lx\n", OutputType.Format.nChannels, OutputType.dwChannelMask);
377 }
378
379 switch(device->FmtChans)
380 {
381 case DevFmtMono:
382 OutputType.Format.nChannels = 1;
383 OutputType.dwChannelMask = MONO;
384 break;
385 case DevFmtStereo:
386 OutputType.Format.nChannels = 2;
387 OutputType.dwChannelMask = STEREO;
388 break;
389 case DevFmtQuad:
390 OutputType.Format.nChannels = 4;
391 OutputType.dwChannelMask = QUAD;
392 break;
393 case DevFmtX51:
394 OutputType.Format.nChannels = 6;
395 OutputType.dwChannelMask = X5DOT1;
396 break;
397 case DevFmtX51Side:
398 OutputType.Format.nChannels = 6;
399 OutputType.dwChannelMask = X5DOT1SIDE;
400 break;
401 case DevFmtX61:
402 OutputType.Format.nChannels = 7;
403 OutputType.dwChannelMask = X6DOT1;
404 break;
405 case DevFmtX71:
406 OutputType.Format.nChannels = 8;
407 OutputType.dwChannelMask = X7DOT1;
408 break;
409 }
410 switch(device->FmtType)
411 {
412 case DevFmtByte:
413 device->FmtType = DevFmtUByte;
414 /* fall-through */
415 case DevFmtUByte:
416 OutputType.Format.wBitsPerSample = 8;
417 OutputType.Samples.wValidBitsPerSample = 8;
418 OutputType.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
419 break;
420 case DevFmtUShort:
421 device->FmtType = DevFmtShort;
422 /* fall-through */
423 case DevFmtShort:
424 OutputType.Format.wBitsPerSample = 16;
425 OutputType.Samples.wValidBitsPerSample = 16;
426 OutputType.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
427 break;
428 case DevFmtUInt:
429 device->FmtType = DevFmtInt;
430 /* fall-through */
431 case DevFmtInt:
432 OutputType.Format.wBitsPerSample = 32;
433 OutputType.Samples.wValidBitsPerSample = 32;
434 OutputType.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
435 break;
436 case DevFmtFloat:
437 OutputType.Format.wBitsPerSample = 32;
438 OutputType.Samples.wValidBitsPerSample = 32;
439 OutputType.SubFormat = KSDATAFORMAT_SUBTYPE_IEEE_FLOAT;
440 break;
441 }
442 OutputType.Format.nSamplesPerSec = device->Frequency;
443
444 OutputType.Format.nBlockAlign = OutputType.Format.nChannels *
445 OutputType.Format.wBitsPerSample / 8;
446 OutputType.Format.nAvgBytesPerSec = OutputType.Format.nSamplesPerSec *
447 OutputType.Format.nBlockAlign;
448
449 hr = IAudioClient_IsFormatSupported(data->client, AUDCLNT_SHAREMODE_SHARED, &OutputType.Format, &wfx);
450 if(FAILED(hr))
451 {
452 ERR("Failed to check format support: 0x%08lx\n", hr);
453 hr = IAudioClient_GetMixFormat(data->client, &wfx);
454 }
455 if(FAILED(hr))
456 {
457 ERR("Failed to find a supported format: 0x%08lx\n", hr);
458 return hr;
459 }
460
461 if(wfx != NULL)
462 {
463 if(!MakeExtensible(&OutputType, wfx))
464 {
465 CoTaskMemFree(wfx);
466 return E_FAIL;
467 }
468 CoTaskMemFree(wfx);
469 wfx = NULL;
470
471 device->Frequency = OutputType.Format.nSamplesPerSec;
472 if(OutputType.Format.nChannels == 1 && OutputType.dwChannelMask == MONO)
473 device->FmtChans = DevFmtMono;
474 else if(OutputType.Format.nChannels == 2 && OutputType.dwChannelMask == STEREO)
475 device->FmtChans = DevFmtStereo;
476 else if(OutputType.Format.nChannels == 4 && OutputType.dwChannelMask == QUAD)
477 device->FmtChans = DevFmtQuad;
478 else if(OutputType.Format.nChannels == 6 && OutputType.dwChannelMask == X5DOT1)
479 device->FmtChans = DevFmtX51;
480 else if(OutputType.Format.nChannels == 6 && OutputType.dwChannelMask == X5DOT1SIDE)
481 device->FmtChans = DevFmtX51Side;
482 else if(OutputType.Format.nChannels == 7 && OutputType.dwChannelMask == X6DOT1)
483 device->FmtChans = DevFmtX61;
484 else if(OutputType.Format.nChannels == 8 && OutputType.dwChannelMask == X7DOT1)
485 device->FmtChans = DevFmtX71;
486 else
487 {
488 ERR("Unhandled extensible channels: %d -- 0x%08lx\n", OutputType.Format.nChannels, OutputType.dwChannelMask);
489 device->FmtChans = DevFmtStereo;
490 OutputType.Format.nChannels = 2;
491 OutputType.dwChannelMask = STEREO;
492 }
493
494 if(IsEqualGUID(&OutputType.SubFormat, &KSDATAFORMAT_SUBTYPE_PCM))
495 {
496 if(OutputType.Format.wBitsPerSample == 8)
497 device->FmtType = DevFmtUByte;
498 else if(OutputType.Format.wBitsPerSample == 16)
499 device->FmtType = DevFmtShort;
500 else if(OutputType.Format.wBitsPerSample == 32)
501 device->FmtType = DevFmtInt;
502 else
503 {
504 device->FmtType = DevFmtShort;
505 OutputType.Format.wBitsPerSample = 16;
506 }
507 }
508 else if(IsEqualGUID(&OutputType.SubFormat, &KSDATAFORMAT_SUBTYPE_IEEE_FLOAT))
509 {
510 device->FmtType = DevFmtFloat;
511 OutputType.Format.wBitsPerSample = 32;
512 }
513 else
514 {
515 ERR("Unhandled format sub-type\n");
516 device->FmtType = DevFmtShort;
517 OutputType.Format.wBitsPerSample = 16;
518 OutputType.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
519 }
520 OutputType.Samples.wValidBitsPerSample = OutputType.Format.wBitsPerSample;
521 }
522
523 SetDefaultWFXChannelOrder(device);
524
525 hr = IAudioClient_Initialize(data->client, AUDCLNT_SHAREMODE_SHARED,
526 AUDCLNT_STREAMFLAGS_EVENTCALLBACK,
527 buf_time, 0, &OutputType.Format, NULL);
528 if(FAILED(hr))
529 {
530 ERR("Failed to initialize audio client: 0x%08lx\n", hr);
531 return hr;
532 }
533
534 hr = IAudioClient_GetDevicePeriod(data->client, &min_per, NULL);
535 if(SUCCEEDED(hr))
536 {
537 min_len = (UINT32)((min_per*device->Frequency + 10000000-1) / 10000000);
538 /* Find the nearest multiple of the period size to the update size */
539 if(min_len < device->UpdateSize)
540 min_len *= (device->UpdateSize + min_len/2)/min_len;
541 hr = IAudioClient_GetBufferSize(data->client, &buffer_len);
542 }
543 if(FAILED(hr))
544 {
545 ERR("Failed to get audio buffer info: 0x%08lx\n", hr);
546 return hr;
547 }
548
549 device->UpdateSize = min_len;
550 device->NumUpdates = buffer_len / device->UpdateSize;
551 if(device->NumUpdates <= 1)
552 {
553 ERR("Audio client returned buffer_len < period*2; expect break up\n");
554 device->NumUpdates = 2;
555 device->UpdateSize = buffer_len / device->NumUpdates;
556 }
557
558 return hr;
559 }
560
561
562 static DWORD CALLBACK MMDevApiMsgProc(void *ptr)
563 {
564 ThreadRequest *req = ptr;
565 IMMDeviceEnumerator *Enumerator;
566 ALuint deviceCount = 0;
567 MMDevApiData *data;
568 ALCdevice *device;
569 HRESULT hr, cohr;
570 MSG msg;
571
572 TRACE("Starting message thread\n");
573
574 cohr = CoInitialize(NULL);
575 if(FAILED(cohr))
576 {
577 WARN("Failed to initialize COM: 0x%08lx\n", cohr);
578 req->result = cohr;
579 SetEvent(req->FinishedEvt);
580 return 0;
581 }
582
583 hr = CoCreateInstance(&CLSID_MMDeviceEnumerator, NULL, CLSCTX_INPROC_SERVER, &IID_IMMDeviceEnumerator, &ptr);
584 if(FAILED(hr))
585 {
586 WARN("Failed to create IMMDeviceEnumerator instance: 0x%08lx\n", hr);
587 CoUninitialize();
588 req->result = hr;
589 SetEvent(req->FinishedEvt);
590 return 0;
591 }
592 Enumerator = ptr;
593 IMMDeviceEnumerator_Release(Enumerator);
594 Enumerator = NULL;
595
596 CoUninitialize();
597
598 req->result = S_OK;
599 SetEvent(req->FinishedEvt);
600
601 TRACE("Starting message loop\n");
602 while(GetMessage(&msg, NULL, 0, 0))
603 {
604 TRACE("Got message %u\n", msg.message);
605 switch(msg.message)
606 {
607 case WM_USER_OpenDevice:
608 req = (ThreadRequest*)msg.wParam;
609 device = (ALCdevice*)msg.lParam;
610 data = device->ExtraData;
611
612 hr = cohr = S_OK;
613 if(++deviceCount == 1)
614 hr = cohr = CoInitialize(NULL);
615 if(SUCCEEDED(hr))
616 hr = CoCreateInstance(&CLSID_MMDeviceEnumerator, NULL, CLSCTX_INPROC_SERVER, &IID_IMMDeviceEnumerator, &ptr);
617 if(SUCCEEDED(hr))
618 {
619 Enumerator = ptr;
620 if(!data->devid)
621 hr = IMMDeviceEnumerator_GetDefaultAudioEndpoint(Enumerator, eRender, eMultimedia, &data->mmdev);
622 else
623 hr = IMMDeviceEnumerator_GetDevice(Enumerator, data->devid, &data->mmdev);
624 IMMDeviceEnumerator_Release(Enumerator);
625 Enumerator = NULL;
626 }
627 if(SUCCEEDED(hr))
628 hr = IMMDevice_Activate(data->mmdev, &IID_IAudioClient, CLSCTX_INPROC_SERVER, NULL, &ptr);
629 if(SUCCEEDED(hr))
630 {
631 data->client = ptr;
632 device->DeviceName = get_device_name(data->mmdev);
633 }
634
635 if(FAILED(hr))
636 {
637 if(data->mmdev)
638 IMMDevice_Release(data->mmdev);
639 data->mmdev = NULL;
640 if(--deviceCount == 0 && SUCCEEDED(cohr))
641 CoUninitialize();
642 }
643
644 req->result = hr;
645 SetEvent(req->FinishedEvt);
646 continue;
647
648 case WM_USER_ResetDevice:
649 req = (ThreadRequest*)msg.wParam;
650 device = (ALCdevice*)msg.lParam;
651
652 req->result = DoReset(device);
653 SetEvent(req->FinishedEvt);
654 continue;
655
656 case WM_USER_StartDevice:
657 req = (ThreadRequest*)msg.wParam;
658 device = (ALCdevice*)msg.lParam;
659 data = device->ExtraData;
660
661 ResetEvent(data->NotifyEvent);
662 hr = IAudioClient_SetEventHandle(data->client, data->NotifyEvent);
663 if(FAILED(hr))
664 ERR("Failed to set event handle: 0x%08lx\n", hr);
665 else
666 {
667 hr = IAudioClient_Start(data->client);
668 if(FAILED(hr))
669 ERR("Failed to start audio client: 0x%08lx\n", hr);
670 }
671
672 if(SUCCEEDED(hr))
673 hr = IAudioClient_GetService(data->client, &IID_IAudioRenderClient, &ptr);
674 if(SUCCEEDED(hr))
675 {
676 data->render = ptr;
677 data->thread = StartThread(MMDevApiProc, device);
678 if(!data->thread)
679 {
680 if(data->render)
681 IAudioRenderClient_Release(data->render);
682 data->render = NULL;
683 IAudioClient_Stop(data->client);
684 ERR("Failed to start thread\n");
685 hr = E_FAIL;
686 }
687 }
688
689 req->result = hr;
690 SetEvent(req->FinishedEvt);
691 continue;
692
693 case WM_USER_StopDevice:
694 req = (ThreadRequest*)msg.wParam;
695 device = (ALCdevice*)msg.lParam;
696 data = device->ExtraData;
697
698 if(data->thread)
699 {
700 data->killNow = 1;
701 StopThread(data->thread);
702 data->thread = NULL;
703
704 data->killNow = 0;
705
706 IAudioRenderClient_Release(data->render);
707 data->render = NULL;
708 IAudioClient_Stop(data->client);
709 }
710
711 req->result = S_OK;
712 SetEvent(req->FinishedEvt);
713 continue;
714
715 case WM_USER_CloseDevice:
716 req = (ThreadRequest*)msg.wParam;
717 device = (ALCdevice*)msg.lParam;
718 data = device->ExtraData;
719
720 IAudioClient_Release(data->client);
721 data->client = NULL;
722
723 IMMDevice_Release(data->mmdev);
724 data->mmdev = NULL;
725
726 if(--deviceCount == 0)
727 CoUninitialize();
728
729 req->result = S_OK;
730 SetEvent(req->FinishedEvt);
731 continue;
732
733 case WM_USER_Enumerate:
734 req = (ThreadRequest*)msg.wParam;
735
736 hr = cohr = S_OK;
737 if(++deviceCount == 1)
738 hr = cohr = CoInitialize(NULL);
739 if(SUCCEEDED(hr))
740 hr = CoCreateInstance(&CLSID_MMDeviceEnumerator, NULL, CLSCTX_INPROC_SERVER, &IID_IMMDeviceEnumerator, &ptr);
741 if(SUCCEEDED(hr))
742 {
743 EDataFlow flowdir;
744 DevMap **devlist;
745 ALuint *numdevs;
746 ALuint i;
747
748 Enumerator = ptr;
749 if(msg.lParam == CAPTURE_DEVICE_PROBE)
750 {
751 flowdir = eCapture;
752 devlist = &CaptureDeviceList;
753 numdevs = &NumCaptureDevices;
754 }
755 else
756 {
757 flowdir = eRender;
758 devlist = &PlaybackDeviceList;
759 numdevs = &NumPlaybackDevices;
760 }
761
762 for(i = 0;i < *numdevs;i++)
763 {
764 free((*devlist)[i].name);
765 free((*devlist)[i].devid);
766 }
767 free(*devlist);
768 *devlist = NULL;
769 *numdevs = 0;
770
771 *devlist = ProbeDevices(Enumerator, flowdir, numdevs);
772
773 IMMDeviceEnumerator_Release(Enumerator);
774 Enumerator = NULL;
775 }
776
777 if(--deviceCount == 0 && SUCCEEDED(cohr))
778 CoUninitialize();
779
780 req->result = S_OK;
781 SetEvent(req->FinishedEvt);
782 continue;
783
784 default:
785 ERR("Unexpected message: %u\n", msg.message);
786 continue;
787 }
788 }
789 TRACE("Message loop finished\n");
790
791 return 0;
792 }
793
794
795 static BOOL MMDevApiLoad(void)
796 {
797 static HRESULT InitResult;
798 if(!ThreadHdl)
799 {
800 ThreadRequest req;
801 InitResult = E_FAIL;
802
803 req.FinishedEvt = CreateEvent(NULL, FALSE, FALSE, NULL);
804 if(req.FinishedEvt == NULL)
805 ERR("Failed to create event: %lu\n", GetLastError());
806 else
807 {
808 ThreadHdl = CreateThread(NULL, 0, MMDevApiMsgProc, &req, 0, &ThreadID);
809 if(ThreadHdl != NULL)
810 InitResult = WaitForResponse(&req);
811 CloseHandle(req.FinishedEvt);
812 }
813 }
814 return SUCCEEDED(InitResult);
815 }
816
817
818 static ALCenum MMDevApiOpenPlayback(ALCdevice *device, const ALCchar *deviceName)
819 {
820 MMDevApiData *data = NULL;
821 HRESULT hr;
822
823 //Initialise requested device
824 data = calloc(1, sizeof(MMDevApiData));
825 if(!data)
826 return ALC_OUT_OF_MEMORY;
827 device->ExtraData = data;
828
829 hr = S_OK;
830 data->NotifyEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
831 data->MsgEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
832 if(data->NotifyEvent == NULL || data->MsgEvent == NULL)
833 hr = E_FAIL;
834
835 if(SUCCEEDED(hr))
836 {
837 if(deviceName)
838 {
839 ALuint i;
840
841 if(!PlaybackDeviceList)
842 {
843 ThreadRequest req = { data->MsgEvent, 0 };
844 if(PostThreadMessage(ThreadID, WM_USER_Enumerate, (WPARAM)&req, ALL_DEVICE_PROBE))
845 (void)WaitForResponse(&req);
846 }
847
848 hr = E_FAIL;
849 for(i = 0;i < NumPlaybackDevices;i++)
850 {
851 if(strcmp(deviceName, PlaybackDeviceList[i].name) == 0)
852 {
853 data->devid = strdupW(PlaybackDeviceList[i].devid);
854 hr = S_OK;
855 break;
856 }
857 }
858 }
859 }
860
861 if(SUCCEEDED(hr))
862 {
863 ThreadRequest req = { data->MsgEvent, 0 };
864
865 hr = E_FAIL;
866 if(PostThreadMessage(ThreadID, WM_USER_OpenDevice, (WPARAM)&req, (LPARAM)device))
867 hr = WaitForResponse(&req);
868 }
869
870 if(FAILED(hr))
871 {
872 if(data->NotifyEvent != NULL)
873 CloseHandle(data->NotifyEvent);
874 data->NotifyEvent = NULL;
875 if(data->MsgEvent != NULL)
876 CloseHandle(data->MsgEvent);
877 data->MsgEvent = NULL;
878
879 free(data);
880 device->ExtraData = NULL;
881
882 ERR("Device init failed: 0x%08lx\n", hr);
883 return ALC_INVALID_VALUE;
884 }
885
886 return ALC_NO_ERROR;
887 }
888
889 static void MMDevApiClosePlayback(ALCdevice *device)
890 {
891 MMDevApiData *data = device->ExtraData;
892 ThreadRequest req = { data->MsgEvent, 0 };
893
894 if(PostThreadMessage(ThreadID, WM_USER_CloseDevice, (WPARAM)&req, (LPARAM)device))
895 (void)WaitForResponse(&req);
896
897 CloseHandle(data->MsgEvent);
898 data->MsgEvent = NULL;
899
900 CloseHandle(data->NotifyEvent);
901 data->NotifyEvent = NULL;
902
903 free(data->devid);
904 data->devid = NULL;
905
906 free(data);
907 device->ExtraData = NULL;
908 }
909
910 static ALCboolean MMDevApiResetPlayback(ALCdevice *device)
911 {
912 MMDevApiData *data = device->ExtraData;
913 ThreadRequest req = { data->MsgEvent, 0 };
914 HRESULT hr = E_FAIL;
915
916 if(PostThreadMessage(ThreadID, WM_USER_ResetDevice, (WPARAM)&req, (LPARAM)device))
917 hr = WaitForResponse(&req);
918
919 return SUCCEEDED(hr) ? ALC_TRUE : ALC_FALSE;
920 }
921
922 static ALCboolean MMDevApiStartPlayback(ALCdevice *device)
923 {
924 MMDevApiData *data = device->ExtraData;
925 ThreadRequest req = { data->MsgEvent, 0 };
926 HRESULT hr = E_FAIL;
927
928 if(PostThreadMessage(ThreadID, WM_USER_StartDevice, (WPARAM)&req, (LPARAM)device))
929 hr = WaitForResponse(&req);
930
931 return SUCCEEDED(hr) ? ALC_TRUE : ALC_FALSE;
932 }
933
934 static void MMDevApiStopPlayback(ALCdevice *device)
935 {
936 MMDevApiData *data = device->ExtraData;
937 ThreadRequest req = { data->MsgEvent, 0 };
938
939 if(PostThreadMessage(ThreadID, WM_USER_StopDevice, (WPARAM)&req, (LPARAM)device))
940 (void)WaitForResponse(&req);
941 }
942
943
944 static ALint64 MMDevApiGetLatency(ALCdevice *device)
945 {
946 MMDevApiData *data = device->ExtraData;
947
948 return (ALint64)data->Padding * 1000000000 / device->Frequency;
949 }
950
951
952 static const BackendFuncs MMDevApiFuncs = {
953 MMDevApiOpenPlayback,
954 MMDevApiClosePlayback,
955 MMDevApiResetPlayback,
956 MMDevApiStartPlayback,
957 MMDevApiStopPlayback,
958 NULL,
959 NULL,
960 NULL,
961 NULL,
962 NULL,
963 NULL,
964 ALCdevice_LockDefault,
965 ALCdevice_UnlockDefault,
966 MMDevApiGetLatency
967 };
968
969
970 ALCboolean alcMMDevApiInit(BackendFuncs *FuncList)
971 {
972 if(!MMDevApiLoad())
973 return ALC_FALSE;
974 *FuncList = MMDevApiFuncs;
975 return ALC_TRUE;
976 }
977
978 void alcMMDevApiDeinit(void)
979 {
980 ALuint i;
981
982 for(i = 0;i < NumPlaybackDevices;i++)
983 {
984 free(PlaybackDeviceList[i].name);
985 free(PlaybackDeviceList[i].devid);
986 }
987 free(PlaybackDeviceList);
988 PlaybackDeviceList = NULL;
989 NumPlaybackDevices = 0;
990
991 for(i = 0;i < NumCaptureDevices;i++)
992 {
993 free(CaptureDeviceList[i].name);
994 free(CaptureDeviceList[i].devid);
995 }
996 free(CaptureDeviceList);
997 CaptureDeviceList = NULL;
998 NumCaptureDevices = 0;
999
1000 if(ThreadHdl)
1001 {
1002 TRACE("Sending WM_QUIT to Thread %04lx\n", ThreadID);
1003 PostThreadMessage(ThreadID, WM_QUIT, 0, 0);
1004 CloseHandle(ThreadHdl);
1005 ThreadHdl = NULL;
1006 }
1007 }
1008
1009 void alcMMDevApiProbe(enum DevProbe type)
1010 {
1011 ThreadRequest req = { NULL, 0 };
1012 HRESULT hr = E_FAIL;
1013
1014 switch(type)
1015 {
1016 case ALL_DEVICE_PROBE:
1017 req.FinishedEvt = CreateEvent(NULL, FALSE, FALSE, NULL);
1018 if(req.FinishedEvt == NULL)
1019 ERR("Failed to create event: %lu\n", GetLastError());
1020 else if(PostThreadMessage(ThreadID, WM_USER_Enumerate, (WPARAM)&req, type))
1021 hr = WaitForResponse(&req);
1022 if(SUCCEEDED(hr))
1023 {
1024 ALuint i;
1025 for(i = 0;i < NumPlaybackDevices;i++)
1026 {
1027 if(PlaybackDeviceList[i].name)
1028 AppendAllDevicesList(PlaybackDeviceList[i].name);
1029 }
1030 }
1031 break;
1032
1033 case CAPTURE_DEVICE_PROBE:
1034 break;
1035 }
1036 if(req.FinishedEvt != NULL)
1037 CloseHandle(req.FinishedEvt);
1038 req.FinishedEvt = NULL;
1039 }
ALvoid
void ALvoid
Definition: al.h:74
DEVICE_FREQUENCY_REQUEST
#define DEVICE_FREQUENCY_REQUEST
Definition: alMain.h:651
ALC_TRUE
#define ALC_TRUE
Definition: alc.h:84
DevFmtQuad
Definition: alMain.h:510
type
GLint GLenum GLsizei GLsizei GLsizei GLint GLenum GLenum type
Definition: gl2ext.h:845
tWAVEFORMATEX::nChannels
WORD nChannels
Definition: audiodefs.h:43
void
GLvoid **typedef void(GLAPIENTRY *PFNGLGETVERTEXATTRIBDVPROC)(GLuint
Definition: glew.h:1824
BackendFuncs
Definition: alMain.h:388
DevFmtUShort
Definition: alMain.h:500
NULL
#define NULL
Definition: ftobjs.h:61
TRACE
#define TRACE(...)
Definition: alMain.h:806
HRESULT
typedef HRESULT(WINAPI *LPD3DXIMTSIGNALCALLBACK)(CONST D3DXVECTOR2 *uv
MMDevApiClosePlayback
static void MMDevApiClosePlayback(ALCdevice *device)
Definition: mmdevapi.c:889
tWAVEFORMATEX::nAvgBytesPerSec
DWORD nAvgBytesPerSec
Definition: audiodefs.h:45
alu.h
free
SDL_EventEntry * free
Definition: SDL_events.c:80
ALCdevice_struct::Frequency
ALuint Frequency
Definition: alMain.h:569
alcMMDevApiDeinit
void alcMMDevApiDeinit(void)
Definition: mmdevapi.c:978
in
GLuint in
Definition: glew.h:10672
WAVEFORMATEXTENSIBLE::wValidBitsPerSample
WORD wValidBitsPerSample
Definition: audiodefs.h:79
Zeni::render
static void render(const Vertex_Buffer_Macrorenderer &macrorenderer, std::vector< Vertex_Buffer::Vertex_Buffer_Range * > &descriptors)
Definition: Vertex_Buffer.cpp:581
ALCdevice_struct
Definition: alMain.h:560
aluMixData
ALvoid aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size)
Definition: ALu.c:970
memset
#define memset
Definition: SDL_malloc.c:633
name
EGLImageKHR EGLint * name
Definition: eglext.h:284
ALCdevice_struct::Flags
ALuint Flags
Definition: alMain.h:605
len
GLenum GLsizei len
Definition: glew.h:7035
MakeExtensible
static ALCboolean MakeExtensible(WAVEFORMATEXTENSIBLE *out, const WAVEFORMATEX *in)
Definition: mmdevapi.c:291
UINT
typedef UINT(WINAPI *PFNWGLGETCONTEXTGPUIDAMDPROC)(HGLRC hglrc)
DoReset
static HRESULT DoReset(ALCdevice *device)
Definition: mmdevapi.c:330
calloc
#define calloc
Definition: SDL_malloc.c:636
MMDevApiMsgProc
static DWORD CALLBACK MMDevApiMsgProc(void *ptr)
Definition: mmdevapi.c:562
aluHandleDisconnect
ALvoid aluHandleDisconnect(ALCdevice *device)
Definition: ALu.c:1176
ALCchar
char ALCchar
Definition: alc.h:42
CaptureDeviceList
static DevMap * CaptureDeviceList
Definition: mmdevapi.c:83
DevFmtByte
Definition: alMain.h:497
NumCaptureDevices
static ALuint NumCaptureDevices
Definition: mmdevapi.c:84
DevFmtX51
Definition: alMain.h:511
MMDevApiLoad
static BOOL MMDevApiLoad(void)
Definition: mmdevapi.c:795
WaitForResponse
static HRESULT WaitForResponse(ThreadRequest *req)
Definition: mmdevapi.c:102
X6DOT1
#define X6DOT1
Definition: mmdevapi.c:55
ALCdevice_Unlock
#define ALCdevice_Unlock(a)
Definition: alMain.h:647
ALL_DEVICE_PROBE
Definition: alMain.h:384
WAVE_FORMAT_EXTENSIBLE
#define WAVE_FORMAT_EXTENSIBLE
Definition: makehrtf.c:179
alcMMDevApiProbe
void alcMMDevApiProbe(enum DevProbe type)
Definition: mmdevapi.c:1009
buffer
EGLContext EGLenum EGLClientBuffer buffer
Definition: eglext.h:87
DevFmtStereo
Definition: alMain.h:509
ALCdevice_struct::ExtraData
void * ExtraData
Definition: alMain.h:630
ALC_FALSE
#define ALC_FALSE
Definition: alc.h:81
DevFmtFloat
Definition: alMain.h:503
DevFmtInt
Definition: alMain.h:501
result
GLuint64EXT * result
Definition: glew.h:12708
HANDLE
typedef HANDLE(WINAPI *PFNWGLCREATEBUFFERREGIONARBPROC)(HDC hDC
StopThread
ALuint StopThread(ALvoid *thread)
Definition: alcThread.c:131
ThreadHdl
static HANDLE ThreadHdl
Definition: mmdevapi.c:87
get_device_name
static ALCchar * get_device_name(IMMDevice *device)
Definition: mmdevapi.c:111
SetDefaultWFXChannelOrder
void SetDefaultWFXChannelOrder(ALCdevice *device)
Definition: ALc.c:1295
idx
FT_UInt idx
Definition: cffcmap.c:125
alMain.h
DevFmtShort
Definition: alMain.h:499
data
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl2ext.h:848
DevFmtX61
Definition: alMain.h:512
NumPlaybackDevices
static ALuint NumPlaybackDevices
Definition: mmdevapi.c:82
MONO
#define MONO
Definition: mmdevapi.c:50
MMDevApiOpenPlayback
static ALCenum MMDevApiOpenPlayback(ALCdevice *device, const ALCchar *deviceName)
Definition: mmdevapi.c:818
count
GLint GLsizei count
Definition: gl2ext.h:1011
tWAVEFORMATEX
Definition: audiodefs.h:40
MMDevApiStartPlayback
static ALCboolean MMDevApiStartPlayback(ALCdevice *device)
Definition: mmdevapi.c:922
MMDevApiGetLatency
static ALint64 MMDevApiGetLatency(ALCdevice *device)
Definition: mmdevapi.c:944
WM_USER_StopDevice
#define WM_USER_StopDevice
Definition: mmdevapi.c:98
alcMMDevApiInit
ALCboolean alcMMDevApiInit(BackendFuncs *FuncList)
Definition: mmdevapi.c:970
DEFINE_GUID
DEFINE_GUID(KSDATAFORMAT_SUBTYPE_PCM, 0x00000001, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71)
tWAVEFORMATEX::nBlockAlign
WORD nBlockAlign
Definition: audiodefs.h:46
X5DOT1SIDE
#define X5DOT1SIDE
Definition: mmdevapi.c:54
WM_USER_StartDevice
#define WM_USER_StartDevice
Definition: mmdevapi.c:97
ALuint
unsigned int ALuint
Definition: al.h:59
SetRTPriority
void SetRTPriority(void)
Definition: helpers.c:470
MMDevApiFuncs
static const BackendFuncs MMDevApiFuncs
Definition: mmdevapi.c:952
WARN
#define WARN(...)
Definition: alMain.h:811
FALSE
#define FALSE
Definition: ftobjs.h:57
WAVEFORMATEXTENSIBLE::Samples
union WAVEFORMATEXTENSIBLE::@63 Samples
WAVE_FORMAT_PCM
#define WAVE_FORMAT_PCM
Definition: makehrtf.c:177
PlaybackDeviceList
static DevMap * PlaybackDeviceList
Definition: mmdevapi.c:81
QUAD
#define QUAD
Definition: mmdevapi.c:52
ALCdevice_struct::FmtChans
enum DevFmtChannels FmtChans
Definition: alMain.h:572
tWAVEFORMATEX::nSamplesPerSec
DWORD nSamplesPerSec
Definition: audiodefs.h:44
DEVICE_CHANNELS_REQUEST
#define DEVICE_CHANNELS_REQUEST
Definition: alMain.h:653
DevFmtX51Side
Definition: alMain.h:516
thread
static SDL_Thread * thread
Definition: SDL_sysjoystick.c:41
MMDevApiProc
static ALuint MMDevApiProc(ALvoid *ptr)
Definition: mmdevapi.c:219
STEREO
#define STEREO
Definition: mmdevapi.c:51
CAPTURE_DEVICE_PROBE
Definition: alMain.h:385
ALC_NO_ERROR
#define ALC_NO_ERROR
Definition: alc.h:102
ALCdevice_LockDefault
void ALCdevice_LockDefault(ALCdevice *device)
Definition: ALc.c:1277
WAVE_FORMAT_IEEE_FLOAT
#define WAVE_FORMAT_IEEE_FLOAT
Definition: winmm.c:34
WM_USER_Enumerate
#define WM_USER_Enumerate
Definition: mmdevapi.c:100
X7DOT1
#define X7DOT1
Definition: mmdevapi.c:56
ALCboolean
char ALCboolean
Definition: alc.h:39
tWAVEFORMATEX::wBitsPerSample
WORD wBitsPerSample
Definition: audiodefs.h:47
DevFmtUInt
Definition: alMain.h:502
DevFmtMono
Definition: alMain.h:508
WM_USER_OpenDevice
#define WM_USER_OpenDevice
Definition: mmdevapi.c:95
ERR
#define ERR(...)
Definition: alMain.h:816
ALCdevice_struct::UpdateSize
ALuint UpdateSize
Definition: alMain.h:570
tWAVEFORMATEX::wFormatTag
WORD wFormatTag
Definition: audiodefs.h:42
ALCdevice_struct::NumUpdates
ALuint NumUpdates
Definition: alMain.h:571
DWORD
typedef DWORD(WINAPI *XInputGetState_t)(DWORD dwUserIndex
ALCdevice_struct::FmtType
enum DevFmtType FmtType
Definition: alMain.h:573
WAVEFORMATEXTENSIBLE::Format
WAVEFORMATEX Format
Definition: audiodefs.h:76
add_device
static void add_device(IMMDevice *device, DevMap *devmap)
Definition: mmdevapi.c:149
ALCdevice_struct::DeviceName
ALCchar * DeviceName
Definition: alMain.h:575
MMDevApiStopPlayback
static void MMDevApiStopPlayback(ALCdevice *device)
Definition: mmdevapi.c:934
ALC_INVALID_VALUE
#define ALC_INVALID_VALUE
Definition: alc.h:114
ALC_OUT_OF_MEMORY
#define ALC_OUT_OF_MEMORY
Definition: alc.h:117
WM_USER_ResetDevice
#define WM_USER_ResetDevice
Definition: mmdevapi.c:96
WAVEFORMATEXTENSIBLE::dwChannelMask
DWORD dwChannelMask
Definition: audiodefs.h:84
ThreadID
static DWORD ThreadID
Definition: mmdevapi.c:88
MMDevApiResetPlayback
static ALCboolean MMDevApiResetPlayback(ALCdevice *device)
Definition: mmdevapi.c:910
tWAVEFORMATEX::cbSize
WORD cbSize
Definition: audiodefs.h:48
WAVEFORMATEXTENSIBLE
Definition: audiodefs.h:74
WM_USER_CloseDevice
#define WM_USER_CloseDevice
Definition: mmdevapi.c:99
i
int i
Definition: pngrutil.c:1377
ALCenum
int ALCenum
Definition: alc.h:66
WAVEFORMATEXTENSIBLE::SubFormat
GUID SubFormat
Definition: audiodefs.h:85
DevFmtUByte
Definition: alMain.h:498
DEFINE_DEVPROPKEY
DEFINE_DEVPROPKEY(DEVPKEY_Device_FriendlyName, 0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 14)
DevFmtX71
Definition: alMain.h:513
X5DOT1
#define X5DOT1
Definition: mmdevapi.c:53
ALCdevice_UnlockDefault
void ALCdevice_UnlockDefault(ALCdevice *device)
Definition: ALc.c:1281
ProbeDevices
static DevMap * ProbeDevices(IMMDeviceEnumerator *devenum, EDataFlow flowdir, ALuint *numdevs)
Definition: mmdevapi.c:164
ALCdevice_Lock
#define ALCdevice_Lock(a)
Definition: alMain.h:646
res
GLuint res
Definition: glew.h:10669
AppendAllDevicesList
void AppendAllDevicesList(const ALCchar *name)
StartThread
ALvoid * StartThread(ALuint(*func)(ALvoid *), ALvoid *ptr)
Definition: alcThread.c:100
DevProbe
DevProbe
Definition: alMain.h:383
BOOL
typedef BOOL(WINAPI *PFNWGLSETSTEREOEMITTERSTATE3DLPROC)(HDC hDC