zenilib: zenilib/jni/external/openal-soft/Alc/backends/winmm.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
winmm.c
Go to the documentation of this file.
1
21 #include "config.h"
22
23 #include <stdlib.h>
24 #include <stdio.h>
25 #include <memory.h>
26
27 #include <windows.h>
28 #include <mmsystem.h>
29
30 #include "alMain.h"
31 #include "alu.h"
32
33 #ifndef WAVE_FORMAT_IEEE_FLOAT
34 #define WAVE_FORMAT_IEEE_FLOAT 0x0003
35 #endif
36
37
38 typedef struct {
39 // MMSYSTEM Device
40 volatile ALboolean killNow;
41 HANDLE WaveThreadEvent;
42 HANDLE WaveThread;
43 DWORD WaveThreadID;
44 volatile LONG WaveBuffersCommitted;
45 WAVEHDR WaveBuffer[4];
46
47 union {
48 HWAVEIN In;
49 HWAVEOUT Out;
50 } WaveHandle;
51
52 WAVEFORMATEX Format;
53
54 RingBuffer *Ring;
55 } WinMMData;
56
57
58 static ALCchar **PlaybackDeviceList;
59 static ALuint NumPlaybackDevices;
60 static ALCchar **CaptureDeviceList;
61 static ALuint NumCaptureDevices;
62
63
64 static void ProbePlaybackDevices(void)
65 {
66 ALuint i;
67
68 for(i = 0;i < NumPlaybackDevices;i++)
69 free(PlaybackDeviceList[i]);
70
71 NumPlaybackDevices = waveOutGetNumDevs();
72 PlaybackDeviceList = realloc(PlaybackDeviceList, sizeof(ALCchar*) * NumPlaybackDevices);
73 for(i = 0;i < NumPlaybackDevices;i++)
74 {
75 WAVEOUTCAPS WaveCaps;
76
77 PlaybackDeviceList[i] = NULL;
78 if(waveOutGetDevCaps(i, &WaveCaps, sizeof(WaveCaps)) == MMSYSERR_NOERROR)
79 {
80 char name[1024];
81 ALuint count, j;
82
83 count = 0;
84 do {
85 if(count == 0)
86 snprintf(name, sizeof(name), "%s", WaveCaps.szPname);
87 else
88 snprintf(name, sizeof(name), "%s #%d", WaveCaps.szPname, count+1);
89 count++;
90
91 for(j = 0;j < i;j++)
92 {
93 if(strcmp(name, PlaybackDeviceList[j]) == 0)
94 break;
95 }
96 } while(j != i);
97
98 PlaybackDeviceList[i] = strdup(name);
99 }
100 }
101 }
102
103 static void ProbeCaptureDevices(void)
104 {
105 ALuint i;
106
107 for(i = 0;i < NumCaptureDevices;i++)
108 free(CaptureDeviceList[i]);
109
110 NumCaptureDevices = waveInGetNumDevs();
111 CaptureDeviceList = realloc(CaptureDeviceList, sizeof(ALCchar*) * NumCaptureDevices);
112 for(i = 0;i < NumCaptureDevices;i++)
113 {
114 WAVEINCAPS WaveInCaps;
115
116 CaptureDeviceList[i] = NULL;
117 if(waveInGetDevCaps(i, &WaveInCaps, sizeof(WAVEINCAPS)) == MMSYSERR_NOERROR)
118 {
119 char name[1024];
120 ALuint count, j;
121
122 count = 0;
123 do {
124 if(count == 0)
125 snprintf(name, sizeof(name), "%s", WaveInCaps.szPname);
126 else
127 snprintf(name, sizeof(name), "%s #%d", WaveInCaps.szPname, count+1);
128 count++;
129
130 for(j = 0;j < i;j++)
131 {
132 if(strcmp(name, CaptureDeviceList[j]) == 0)
133 break;
134 }
135 } while(j != i);
136
137 CaptureDeviceList[i] = strdup(name);
138 }
139 }
140 }
141
142
143 /*
144 WaveOutProc
145
146 Posts a message to 'PlaybackThreadProc' everytime a WaveOut Buffer is completed and
147 returns to the application (for more data)
148 */
149 static void CALLBACK WaveOutProc(HWAVEOUT device, UINT msg, DWORD_PTR instance, DWORD_PTR param1, DWORD_PTR param2)
150 {
151 ALCdevice *Device = (ALCdevice*)instance;
152 WinMMData *data = Device->ExtraData;
153
154 (void)device;
155 (void)param2;
156
157 if(msg != WOM_DONE)
158 return;
159
160 InterlockedDecrement(&data->WaveBuffersCommitted);
161 PostThreadMessage(data->WaveThreadID, msg, 0, param1);
162 }
163
164 /*
165 PlaybackThreadProc
166
167 Used by "MMSYSTEM" Device. Called when a WaveOut buffer has used up its
168 audio data.
169 */
170 static DWORD WINAPI PlaybackThreadProc(LPVOID param)
171 {
172 ALCdevice *Device = (ALCdevice*)param;
173 WinMMData *data = Device->ExtraData;
174 LPWAVEHDR WaveHdr;
175 ALuint FrameSize;
176 MSG msg;
177
178 FrameSize = FrameSizeFromDevFmt(Device->FmtChans, Device->FmtType);
179
180 SetRTPriority();
181
182 while(GetMessage(&msg, NULL, 0, 0))
183 {
184 if(msg.message != WOM_DONE)
185 continue;
186
187 if(data->killNow)
188 {
189 if(data->WaveBuffersCommitted == 0)
190 break;
191 continue;
192 }
193
194 WaveHdr = ((LPWAVEHDR)msg.lParam);
195 aluMixData(Device, WaveHdr->lpData, WaveHdr->dwBufferLength/FrameSize);
196
197 // Send buffer back to play more data
198 waveOutWrite(data->WaveHandle.Out, WaveHdr, sizeof(WAVEHDR));
199 InterlockedIncrement(&data->WaveBuffersCommitted);
200 }
201
202 // Signal Wave Thread completed event
203 if(data->WaveThreadEvent)
204 SetEvent(data->WaveThreadEvent);
205
206 ExitThread(0);
207 return 0;
208 }
209
210 /*
211 WaveInProc
212
213 Posts a message to 'CaptureThreadProc' everytime a WaveIn Buffer is completed and
214 returns to the application (with more data)
215 */
216 static void CALLBACK WaveInProc(HWAVEIN device, UINT msg, DWORD_PTR instance, DWORD_PTR param1, DWORD_PTR param2)
217 {
218 ALCdevice *Device = (ALCdevice*)instance;
219 WinMMData *data = Device->ExtraData;
220
221 (void)device;
222 (void)param2;
223
224 if(msg != WIM_DATA)
225 return;
226
227 InterlockedDecrement(&data->WaveBuffersCommitted);
228 PostThreadMessage(data->WaveThreadID, msg, 0, param1);
229 }
230
231 /*
232 CaptureThreadProc
233
234 Used by "MMSYSTEM" Device. Called when a WaveIn buffer had been filled with new
235 audio data.
236 */
237 static DWORD WINAPI CaptureThreadProc(LPVOID param)
238 {
239 ALCdevice *Device = (ALCdevice*)param;
240 WinMMData *data = Device->ExtraData;
241 LPWAVEHDR WaveHdr;
242 ALuint FrameSize;
243 MSG msg;
244
245 FrameSize = FrameSizeFromDevFmt(Device->FmtChans, Device->FmtType);
246
247 while(GetMessage(&msg, NULL, 0, 0))
248 {
249 if(msg.message != WIM_DATA)
250 continue;
251 /* Don't wait for other buffers to finish before quitting. We're
252 * closing so we don't need them. */
253 if(data->killNow)
254 break;
255
256 WaveHdr = ((LPWAVEHDR)msg.lParam);
257 WriteRingBuffer(data->Ring, (ALubyte*)WaveHdr->lpData, WaveHdr->dwBytesRecorded/FrameSize);
258
259 // Send buffer back to capture more data
260 waveInAddBuffer(data->WaveHandle.In, WaveHdr, sizeof(WAVEHDR));
261 InterlockedIncrement(&data->WaveBuffersCommitted);
262 }
263
264 // Signal Wave Thread completed event
265 if(data->WaveThreadEvent)
266 SetEvent(data->WaveThreadEvent);
267
268 ExitThread(0);
269 return 0;
270 }
271
272
273 static ALCenum WinMMOpenPlayback(ALCdevice *Device, const ALCchar *deviceName)
274 {
275 WinMMData *data = NULL;
276 UINT DeviceID = 0;
277 MMRESULT res;
278 ALuint i = 0;
279
280 if(!PlaybackDeviceList)
281 ProbePlaybackDevices();
282
283 // Find the Device ID matching the deviceName if valid
284 for(i = 0;i < NumPlaybackDevices;i++)
285 {
286 if(PlaybackDeviceList[i] &&
287 (!deviceName || strcmp(deviceName, PlaybackDeviceList[i]) == 0))
288 {
289 DeviceID = i;
290 break;
291 }
292 }
293 if(i == NumPlaybackDevices)
294 return ALC_INVALID_VALUE;
295
296 data = calloc(1, sizeof(*data));
297 if(!data)
298 return ALC_OUT_OF_MEMORY;
299 Device->ExtraData = data;
300
301 retry_open:
302 memset(&data->Format, 0, sizeof(WAVEFORMATEX));
303 if(Device->FmtType == DevFmtFloat)
304 {
305 data->Format.wFormatTag = WAVE_FORMAT_IEEE_FLOAT;
306 data->Format.wBitsPerSample = 32;
307 }
308 else
309 {
310 data->Format.wFormatTag = WAVE_FORMAT_PCM;
311 if(Device->FmtType == DevFmtUByte || Device->FmtType == DevFmtByte)
312 data->Format.wBitsPerSample = 8;
313 else
314 data->Format.wBitsPerSample = 16;
315 }
316 data->Format.nChannels = ((Device->FmtChans == DevFmtMono) ? 1 : 2);
317 data->Format.nBlockAlign = data->Format.wBitsPerSample *
318 data->Format.nChannels / 8;
319 data->Format.nSamplesPerSec = Device->Frequency;
320 data->Format.nAvgBytesPerSec = data->Format.nSamplesPerSec *
321 data->Format.nBlockAlign;
322 data->Format.cbSize = 0;
323
324 if((res=waveOutOpen(&data->WaveHandle.Out, DeviceID, &data->Format, (DWORD_PTR)&WaveOutProc, (DWORD_PTR)Device, CALLBACK_FUNCTION)) != MMSYSERR_NOERROR)
325 {
326 if(Device->FmtType == DevFmtFloat)
327 {
328 Device->FmtType = DevFmtShort;
329 goto retry_open;
330 }
331 ERR("waveOutOpen failed: %u\n", res);
332 goto failure;
333 }
334
335 data->WaveThreadEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
336 if(data->WaveThreadEvent == NULL)
337 {
338 ERR("CreateEvent failed: %lu\n", GetLastError());
339 goto failure;
340 }
341
342 Device->DeviceName = strdup(PlaybackDeviceList[DeviceID]);
343 return ALC_NO_ERROR;
344
345 failure:
346 if(data->WaveThreadEvent)
347 CloseHandle(data->WaveThreadEvent);
348
349 if(data->WaveHandle.Out)
350 waveOutClose(data->WaveHandle.Out);
351
352 free(data);
353 Device->ExtraData = NULL;
354 return ALC_INVALID_VALUE;
355 }
356
357 static void WinMMClosePlayback(ALCdevice *device)
358 {
359 WinMMData *data = (WinMMData*)device->ExtraData;
360
361 // Close the Wave device
362 CloseHandle(data->WaveThreadEvent);
363 data->WaveThreadEvent = 0;
364
365 waveOutClose(data->WaveHandle.Out);
366 data->WaveHandle.Out = 0;
367
368 free(data);
369 device->ExtraData = NULL;
370 }
371
372 static ALCboolean WinMMResetPlayback(ALCdevice *device)
373 {
374 WinMMData *data = (WinMMData*)device->ExtraData;
375
376 device->UpdateSize = (ALuint)((ALuint64)device->UpdateSize *
377 data->Format.nSamplesPerSec /
378 device->Frequency);
379 device->UpdateSize = (device->UpdateSize*device->NumUpdates + 3) / 4;
380 device->NumUpdates = 4;
381 device->Frequency = data->Format.nSamplesPerSec;
382
383 if(data->Format.wFormatTag == WAVE_FORMAT_IEEE_FLOAT)
384 {
385 if(data->Format.wBitsPerSample == 32)
386 device->FmtType = DevFmtFloat;
387 else
388 {
389 ERR("Unhandled IEEE float sample depth: %d\n", data->Format.wBitsPerSample);
390 return ALC_FALSE;
391 }
392 }
393 else if(data->Format.wFormatTag == WAVE_FORMAT_PCM)
394 {
395 if(data->Format.wBitsPerSample == 16)
396 device->FmtType = DevFmtShort;
397 else if(data->Format.wBitsPerSample == 8)
398 device->FmtType = DevFmtUByte;
399 else
400 {
401 ERR("Unhandled PCM sample depth: %d\n", data->Format.wBitsPerSample);
402 return ALC_FALSE;
403 }
404 }
405 else
406 {
407 ERR("Unhandled format tag: 0x%04x\n", data->Format.wFormatTag);
408 return ALC_FALSE;
409 }
410
411 if(data->Format.nChannels == 2)
412 device->FmtChans = DevFmtStereo;
413 else if(data->Format.nChannels == 1)
414 device->FmtChans = DevFmtMono;
415 else
416 {
417 ERR("Unhandled channel count: %d\n", data->Format.nChannels);
418 return ALC_FALSE;
419 }
420 SetDefaultWFXChannelOrder(device);
421
422 return ALC_TRUE;
423 }
424
425 static ALCboolean WinMMStartPlayback(ALCdevice *device)
426 {
427 WinMMData *data = (WinMMData*)device->ExtraData;
428 ALbyte *BufferData;
429 ALint BufferSize;
430 ALuint i;
431
432 data->WaveThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)PlaybackThreadProc, (LPVOID)device, 0, &data->WaveThreadID);
433 if(data->WaveThread == NULL)
434 return ALC_FALSE;
435
436 data->WaveBuffersCommitted = 0;
437
438 // Create 4 Buffers
439 BufferSize = device->UpdateSize*device->NumUpdates / 4;
440 BufferSize *= FrameSizeFromDevFmt(device->FmtChans, device->FmtType);
441
442 BufferData = calloc(4, BufferSize);
443 for(i = 0;i < 4;i++)
444 {
445 memset(&data->WaveBuffer[i], 0, sizeof(WAVEHDR));
446 data->WaveBuffer[i].dwBufferLength = BufferSize;
447 data->WaveBuffer[i].lpData = ((i==0) ? (LPSTR)BufferData :
448 (data->WaveBuffer[i-1].lpData +
449 data->WaveBuffer[i-1].dwBufferLength));
450 waveOutPrepareHeader(data->WaveHandle.Out, &data->WaveBuffer[i], sizeof(WAVEHDR));
451 waveOutWrite(data->WaveHandle.Out, &data->WaveBuffer[i], sizeof(WAVEHDR));
452 InterlockedIncrement(&data->WaveBuffersCommitted);
453 }
454
455 return ALC_TRUE;
456 }
457
458 static void WinMMStopPlayback(ALCdevice *device)
459 {
460 WinMMData *data = (WinMMData*)device->ExtraData;
461 void *buffer = NULL;
462 int i;
463
464 if(data->WaveThread == NULL)
465 return;
466
467 // Set flag to stop processing headers
468 data->killNow = AL_TRUE;
469
470 // Wait for signal that Wave Thread has been destroyed
471 WaitForSingleObjectEx(data->WaveThreadEvent, 5000, FALSE);
472
473 CloseHandle(data->WaveThread);
474 data->WaveThread = 0;
475
476 data->killNow = AL_FALSE;
477
478 // Release the wave buffers
479 for(i = 0;i < 4;i++)
480 {
481 waveOutUnprepareHeader(data->WaveHandle.Out, &data->WaveBuffer[i], sizeof(WAVEHDR));
482 if(i == 0) buffer = data->WaveBuffer[i].lpData;
483 data->WaveBuffer[i].lpData = NULL;
484 }
485 free(buffer);
486 }
487
488
489 static ALCenum WinMMOpenCapture(ALCdevice *Device, const ALCchar *deviceName)
490 {
491 ALbyte *BufferData = NULL;
492 DWORD CapturedDataSize;
493 WinMMData *data = NULL;
494 UINT DeviceID = 0;
495 ALint BufferSize;
496 MMRESULT res;
497 ALuint i;
498
499 if(!CaptureDeviceList)
500 ProbeCaptureDevices();
501
502 // Find the Device ID matching the deviceName if valid
503 for(i = 0;i < NumCaptureDevices;i++)
504 {
505 if(CaptureDeviceList[i] &&
506 (!deviceName || strcmp(deviceName, CaptureDeviceList[i]) == 0))
507 {
508 DeviceID = i;
509 break;
510 }
511 }
512 if(i == NumCaptureDevices)
513 return ALC_INVALID_VALUE;
514
515 switch(Device->FmtChans)
516 {
517 case DevFmtMono:
518 case DevFmtStereo:
519 break;
520
521 case DevFmtQuad:
522 case DevFmtX51:
523 case DevFmtX51Side:
524 case DevFmtX61:
525 case DevFmtX71:
526 return ALC_INVALID_ENUM;
527 }
528
529 switch(Device->FmtType)
530 {
531 case DevFmtUByte:
532 case DevFmtShort:
533 case DevFmtInt:
534 case DevFmtFloat:
535 break;
536
537 case DevFmtByte:
538 case DevFmtUShort:
539 case DevFmtUInt:
540 return ALC_INVALID_ENUM;
541 }
542
543 data = calloc(1, sizeof(*data));
544 if(!data)
545 return ALC_OUT_OF_MEMORY;
546 Device->ExtraData = data;
547
548 memset(&data->Format, 0, sizeof(WAVEFORMATEX));
549 data->Format.wFormatTag = ((Device->FmtType == DevFmtFloat) ?
550 WAVE_FORMAT_IEEE_FLOAT : WAVE_FORMAT_PCM);
551 data->Format.nChannels = ChannelsFromDevFmt(Device->FmtChans);
552 data->Format.wBitsPerSample = BytesFromDevFmt(Device->FmtType) * 8;
553 data->Format.nBlockAlign = data->Format.wBitsPerSample *
554 data->Format.nChannels / 8;
555 data->Format.nSamplesPerSec = Device->Frequency;
556 data->Format.nAvgBytesPerSec = data->Format.nSamplesPerSec *
557 data->Format.nBlockAlign;
558 data->Format.cbSize = 0;
559
560 if((res=waveInOpen(&data->WaveHandle.In, DeviceID, &data->Format, (DWORD_PTR)&WaveInProc, (DWORD_PTR)Device, CALLBACK_FUNCTION)) != MMSYSERR_NOERROR)
561 {
562 ERR("waveInOpen failed: %u\n", res);
563 goto failure;
564 }
565
566 data->WaveThreadEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
567 if(data->WaveThreadEvent == NULL)
568 {
569 ERR("CreateEvent failed: %lu\n", GetLastError());
570 goto failure;
571 }
572
573 // Allocate circular memory buffer for the captured audio
574 CapturedDataSize = Device->UpdateSize*Device->NumUpdates;
575
576 // Make sure circular buffer is at least 100ms in size
577 if(CapturedDataSize < (data->Format.nSamplesPerSec / 10))
578 CapturedDataSize = data->Format.nSamplesPerSec / 10;
579
580 data->Ring = CreateRingBuffer(data->Format.nBlockAlign, CapturedDataSize);
581 if(!data->Ring)
582 goto failure;
583
584 data->WaveBuffersCommitted = 0;
585
586 // Create 4 Buffers of 50ms each
587 BufferSize = data->Format.nAvgBytesPerSec / 20;
588 BufferSize -= (BufferSize % data->Format.nBlockAlign);
589
590 BufferData = calloc(4, BufferSize);
591 if(!BufferData)
592 goto failure;
593
594 for(i = 0;i < 4;i++)
595 {
596 memset(&data->WaveBuffer[i], 0, sizeof(WAVEHDR));
597 data->WaveBuffer[i].dwBufferLength = BufferSize;
598 data->WaveBuffer[i].lpData = ((i==0) ? (LPSTR)BufferData :
599 (data->WaveBuffer[i-1].lpData +
600 data->WaveBuffer[i-1].dwBufferLength));
601 data->WaveBuffer[i].dwFlags = 0;
602 data->WaveBuffer[i].dwLoops = 0;
603 waveInPrepareHeader(data->WaveHandle.In, &data->WaveBuffer[i], sizeof(WAVEHDR));
604 waveInAddBuffer(data->WaveHandle.In, &data->WaveBuffer[i], sizeof(WAVEHDR));
605 InterlockedIncrement(&data->WaveBuffersCommitted);
606 }
607
608 data->WaveThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)CaptureThreadProc, (LPVOID)Device, 0, &data->WaveThreadID);
609 if (data->WaveThread == NULL)
610 goto failure;
611
612 Device->DeviceName = strdup(CaptureDeviceList[DeviceID]);
613 return ALC_NO_ERROR;
614
615 failure:
616 if(data->WaveThread)
617 CloseHandle(data->WaveThread);
618
619 if(BufferData)
620 {
621 for(i = 0;i < 4;i++)
622 waveInUnprepareHeader(data->WaveHandle.In, &data->WaveBuffer[i], sizeof(WAVEHDR));
623 free(BufferData);
624 }
625
626 if(data->Ring)
627 DestroyRingBuffer(data->Ring);
628
629 if(data->WaveThreadEvent)
630 CloseHandle(data->WaveThreadEvent);
631
632 if(data->WaveHandle.In)
633 waveInClose(data->WaveHandle.In);
634
635 free(data);
636 Device->ExtraData = NULL;
637 return ALC_INVALID_VALUE;
638 }
639
640 static void WinMMCloseCapture(ALCdevice *Device)
641 {
642 WinMMData *data = (WinMMData*)Device->ExtraData;
643 void *buffer = NULL;
644 int i;
645
646 /* Tell the processing thread to quit and wait for it to do so. */
647 data->killNow = AL_TRUE;
648 PostThreadMessage(data->WaveThreadID, WM_QUIT, 0, 0);
649
650 WaitForSingleObjectEx(data->WaveThreadEvent, 5000, FALSE);
651
652 /* Make sure capture is stopped and all pending buffers are flushed. */
653 waveInReset(data->WaveHandle.In);
654
655 CloseHandle(data->WaveThread);
656 data->WaveThread = 0;
657
658 // Release the wave buffers
659 for(i = 0;i < 4;i++)
660 {
661 waveInUnprepareHeader(data->WaveHandle.In, &data->WaveBuffer[i], sizeof(WAVEHDR));
662 if(i == 0) buffer = data->WaveBuffer[i].lpData;
663 data->WaveBuffer[i].lpData = NULL;
664 }
665 free(buffer);
666
667 DestroyRingBuffer(data->Ring);
668 data->Ring = NULL;
669
670 // Close the Wave device
671 CloseHandle(data->WaveThreadEvent);
672 data->WaveThreadEvent = 0;
673
674 waveInClose(data->WaveHandle.In);
675 data->WaveHandle.In = 0;
676
677 free(data);
678 Device->ExtraData = NULL;
679 }
680
681 static void WinMMStartCapture(ALCdevice *Device)
682 {
683 WinMMData *data = (WinMMData*)Device->ExtraData;
684 waveInStart(data->WaveHandle.In);
685 }
686
687 static void WinMMStopCapture(ALCdevice *Device)
688 {
689 WinMMData *data = (WinMMData*)Device->ExtraData;
690 waveInStop(data->WaveHandle.In);
691 }
692
693 static ALCenum WinMMCaptureSamples(ALCdevice *Device, ALCvoid *Buffer, ALCuint Samples)
694 {
695 WinMMData *data = (WinMMData*)Device->ExtraData;
696 ReadRingBuffer(data->Ring, Buffer, Samples);
697 return ALC_NO_ERROR;
698 }
699
700 static ALCuint WinMMAvailableSamples(ALCdevice *Device)
701 {
702 WinMMData *data = (WinMMData*)Device->ExtraData;
703 return RingBufferSize(data->Ring);
704 }
705
706
707 static const BackendFuncs WinMMFuncs = {
708 WinMMOpenPlayback,
709 WinMMClosePlayback,
710 WinMMResetPlayback,
711 WinMMStartPlayback,
712 WinMMStopPlayback,
713 WinMMOpenCapture,
714 WinMMCloseCapture,
715 WinMMStartCapture,
716 WinMMStopCapture,
717 WinMMCaptureSamples,
718 WinMMAvailableSamples,
719 ALCdevice_LockDefault,
720 ALCdevice_UnlockDefault,
721 ALCdevice_GetLatencyDefault
722 };
723
724 ALCboolean alcWinMMInit(BackendFuncs *FuncList)
725 {
726 *FuncList = WinMMFuncs;
727 return ALC_TRUE;
728 }
729
730 void alcWinMMDeinit()
731 {
732 ALuint i;
733
734 for(i = 0;i < NumPlaybackDevices;i++)
735 free(PlaybackDeviceList[i]);
736 free(PlaybackDeviceList);
737 PlaybackDeviceList = NULL;
738
739 NumPlaybackDevices = 0;
740
741
742 for(i = 0;i < NumCaptureDevices;i++)
743 free(CaptureDeviceList[i]);
744 free(CaptureDeviceList);
745 CaptureDeviceList = NULL;
746
747 NumCaptureDevices = 0;
748 }
749
750 void alcWinMMProbe(enum DevProbe type)
751 {
752 ALuint i;
753
754 switch(type)
755 {
756 case ALL_DEVICE_PROBE:
757 ProbePlaybackDevices();
758 for(i = 0;i < NumPlaybackDevices;i++)
759 {
760 if(PlaybackDeviceList[i])
761 AppendAllDevicesList(PlaybackDeviceList[i]);
762 }
763 break;
764
765 case CAPTURE_DEVICE_PROBE:
766 ProbeCaptureDevices();
767 for(i = 0;i < NumCaptureDevices;i++)
768 {
769 if(CaptureDeviceList[i])
770 AppendCaptureDeviceList(CaptureDeviceList[i]);
771 }
772 break;
773 }
774 }
WaveOutProc
static void CALLBACK WaveOutProc(HWAVEOUT device, UINT msg, DWORD_PTR instance, DWORD_PTR param1, DWORD_PTR param2)
Definition: winmm.c:149
ALubyte
unsigned char ALubyte
Definition: al.h:47
param
GLenum GLint param
Definition: gl2ext.h:1491
WinMMStopCapture
static void WinMMStopCapture(ALCdevice *Device)
Definition: winmm.c:687
ALC_TRUE
#define ALC_TRUE
Definition: alc.h:84
CaptureDeviceList
static ALCchar ** CaptureDeviceList
Definition: winmm.c:60
DevFmtQuad
Definition: alMain.h:510
type
GLint GLenum GLsizei GLsizei GLsizei GLint GLenum GLenum type
Definition: gl2ext.h:845
void
GLvoid **typedef void(GLAPIENTRY *PFNGLGETVERTEXATTRIBDVPROC)(GLuint
Definition: glew.h:1824
BackendFuncs
Definition: alMain.h:388
WinMMAvailableSamples
static ALCuint WinMMAvailableSamples(ALCdevice *Device)
Definition: winmm.c:700
AL_TRUE
#define AL_TRUE
Definition: al.h:86
WinMMOpenPlayback
static ALCenum WinMMOpenPlayback(ALCdevice *Device, const ALCchar *deviceName)
Definition: winmm.c:273
DevFmtUShort
Definition: alMain.h:500
strdup
char * strdup(const char *inStr)
Definition: strdup.c:6
NULL
#define NULL
Definition: ftobjs.h:61
WinMMStopPlayback
static void WinMMStopPlayback(ALCdevice *device)
Definition: winmm.c:458
ALC_INVALID_ENUM
#define ALC_INVALID_ENUM
Definition: alc.h:111
alu.h
free
SDL_EventEntry * free
Definition: SDL_events.c:80
ALCdevice_struct::Frequency
ALuint Frequency
Definition: alMain.h:569
ALCdevice_struct
Definition: alMain.h:560
ALint
int ALint
Definition: al.h:56
j
int32_t j
Definition: e_log.c:102
aluMixData
ALvoid aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size)
Definition: ALu.c:970
memset
#define memset
Definition: SDL_malloc.c:633
AL_FALSE
#define AL_FALSE
Definition: al.h:83
NumCaptureDevices
static ALuint NumCaptureDevices
Definition: winmm.c:61
ALCdevice_GetLatencyDefault
ALint64 ALCdevice_GetLatencyDefault(ALCdevice *device)
Definition: ALc.c:1285
name
EGLImageKHR EGLint * name
Definition: eglext.h:284
WinMMCloseCapture
static void WinMMCloseCapture(ALCdevice *Device)
Definition: winmm.c:640
ProbePlaybackDevices
static void ProbePlaybackDevices(void)
Definition: winmm.c:64
RingBufferSize
ALsizei RingBufferSize(RingBuffer *ring)
Definition: alcRing.c:67
UINT
typedef UINT(WINAPI *PFNWGLGETCONTEXTGPUIDAMDPROC)(HGLRC hglrc)
AppendCaptureDeviceList
void AppendCaptureDeviceList(const ALCchar *name)
ALCuint
unsigned int ALCuint
Definition: alc.h:60
calloc
#define calloc
Definition: SDL_malloc.c:636
ALCchar
char ALCchar
Definition: alc.h:42
ALbyte
signed char ALbyte
Definition: al.h:44
DevFmtByte
Definition: alMain.h:497
PlaybackDeviceList
static ALCchar ** PlaybackDeviceList
Definition: winmm.c:58
DevFmtX51
Definition: alMain.h:511
ALL_DEVICE_PROBE
Definition: alMain.h:384
RingBuffer
struct RingBuffer RingBuffer
Definition: alMain.h:750
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
alcWinMMInit
ALCboolean alcWinMMInit(BackendFuncs *FuncList)
Definition: winmm.c:724
DevFmtInt
Definition: alMain.h:501
HANDLE
typedef HANDLE(WINAPI *PFNWGLCREATEBUFFERREGIONARBPROC)(HDC hDC
SetDefaultWFXChannelOrder
void SetDefaultWFXChannelOrder(ALCdevice *device)
Definition: ALc.c:1295
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
WaveInProc
static void CALLBACK WaveInProc(HWAVEIN device, UINT msg, DWORD_PTR instance, DWORD_PTR param1, DWORD_PTR param2)
Definition: winmm.c:216
count
GLint GLsizei count
Definition: gl2ext.h:1011
tWAVEFORMATEX
Definition: audiodefs.h:40
WinMMResetPlayback
static ALCboolean WinMMResetPlayback(ALCdevice *device)
Definition: winmm.c:372
CaptureThreadProc
static DWORD WINAPI CaptureThreadProc(LPVOID param)
Definition: winmm.c:237
CreateRingBuffer
RingBuffer * CreateRingBuffer(ALsizei frame_size, ALsizei length)
Definition: alcRing.c:41
realloc
#define realloc
Definition: SDL_malloc.c:637
ALuint
unsigned int ALuint
Definition: al.h:59
SetRTPriority
void SetRTPriority(void)
Definition: helpers.c:470
WinMMCaptureSamples
static ALCenum WinMMCaptureSamples(ALCdevice *Device, ALCvoid *Buffer, ALCuint Samples)
Definition: winmm.c:693
FALSE
#define FALSE
Definition: ftobjs.h:57
WAVE_FORMAT_PCM
#define WAVE_FORMAT_PCM
Definition: makehrtf.c:177
ALCdevice_struct::FmtChans
enum DevFmtChannels FmtChans
Definition: alMain.h:572
ProbeCaptureDevices
static void ProbeCaptureDevices(void)
Definition: winmm.c:103
LPVOID
typedef LPVOID(WINAPI *PFNWGLCREATEIMAGEBUFFERI3DPROC)(HDC hDC
DevFmtX51Side
Definition: alMain.h:516
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
NumPlaybackDevices
static ALuint NumPlaybackDevices
Definition: winmm.c:59
WAVE_FORMAT_IEEE_FLOAT
#define WAVE_FORMAT_IEEE_FLOAT
Definition: winmm.c:34
ALCboolean
char ALCboolean
Definition: alc.h:39
DevFmtUInt
Definition: alMain.h:502
DevFmtMono
Definition: alMain.h:508
ALCvoid
void ALCvoid
Definition: alc.h:75
ERR
#define ERR(...)
Definition: alMain.h:816
ALCdevice_struct::UpdateSize
ALuint UpdateSize
Definition: alMain.h:570
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
ALboolean
char ALboolean
Definition: al.h:38
WinMMStartPlayback
static ALCboolean WinMMStartPlayback(ALCdevice *device)
Definition: winmm.c:425
ALC_INVALID_VALUE
#define ALC_INVALID_VALUE
Definition: alc.h:114
ALC_OUT_OF_MEMORY
#define ALC_OUT_OF_MEMORY
Definition: alc.h:117
WinMMStartCapture
static void WinMMStartCapture(ALCdevice *Device)
Definition: winmm.c:681
PlaybackThreadProc
static DWORD WINAPI PlaybackThreadProc(LPVOID param)
Definition: winmm.c:170
WinMMClosePlayback
static void WinMMClosePlayback(ALCdevice *device)
Definition: winmm.c:357
ReadRingBuffer
void ReadRingBuffer(RingBuffer *ring, ALubyte *data, ALsizei len)
Definition: alcRing.c:108
alcWinMMProbe
void alcWinMMProbe(enum DevProbe type)
Definition: winmm.c:750
i
int i
Definition: pngrutil.c:1377
ALCenum
int ALCenum
Definition: alc.h:66
DevFmtUByte
Definition: alMain.h:498
BytesFromDevFmt
ALuint BytesFromDevFmt(enum DevFmtType type)
Definition: ALc.c:1165
alcWinMMDeinit
void alcWinMMDeinit()
Definition: winmm.c:730
DevFmtX71
Definition: alMain.h:513
DestroyRingBuffer
void DestroyRingBuffer(RingBuffer *ring)
Definition: alcRing.c:58
ALCdevice_UnlockDefault
void ALCdevice_UnlockDefault(ALCdevice *device)
Definition: ALc.c:1281
WriteRingBuffer
void WriteRingBuffer(RingBuffer *ring, const ALubyte *data, ALsizei len)
Definition: alcRing.c:78
ChannelsFromDevFmt
ALuint ChannelsFromDevFmt(enum DevFmtChannels chans)
Definition: ALc.c:1179
res
GLuint res
Definition: glew.h:10669
WinMMFuncs
static const BackendFuncs WinMMFuncs
Definition: winmm.c:707
AppendAllDevicesList
void AppendAllDevicesList(const ALCchar *name)
WinMMOpenCapture
static ALCenum WinMMOpenCapture(ALCdevice *Device, const ALCchar *deviceName)
Definition: winmm.c:489
DevProbe
DevProbe
Definition: alMain.h:383
FrameSizeFromDevFmt
static __inline ALuint FrameSizeFromDevFmt(enum DevFmtChannels chans, enum DevFmtType type)
Definition: alMain.h:523