zenilib  0.5.3.0
 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 
62 
63 
64 static void ProbePlaybackDevices(void)
65 {
66  ALuint i;
67 
68  for(i = 0;i < NumPlaybackDevices;i++)
70 
71  NumPlaybackDevices = waveOutGetNumDevs();
72  PlaybackDeviceList = realloc(PlaybackDeviceList, sizeof(ALCchar*) * NumPlaybackDevices);
73  for(i = 0;i < NumPlaybackDevices;i++)
74  {
75  WAVEOUTCAPS WaveCaps;
76 
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++)
109 
110  NumCaptureDevices = waveInGetNumDevs();
111  CaptureDeviceList = realloc(CaptureDeviceList, sizeof(ALCchar*) * NumCaptureDevices);
112  for(i = 0;i < NumCaptureDevices;i++)
113  {
114  WAVEINCAPS WaveInCaps;
115 
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 */
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 */
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)
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 
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  }
421 
422  return ALC_TRUE;
423 }
424 
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)
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) ?
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 
701 {
702  WinMMData *data = (WinMMData*)Device->ExtraData;
703  return RingBufferSize(data->Ring);
704 }
705 
706 
707 static const BackendFuncs WinMMFuncs = {
722 };
723 
725 {
726  *FuncList = WinMMFuncs;
727  return ALC_TRUE;
728 }
729 
731 {
732  ALuint i;
733 
734  for(i = 0;i < NumPlaybackDevices;i++)
738 
739  NumPlaybackDevices = 0;
740 
741 
742  for(i = 0;i < NumCaptureDevices;i++)
746 
747  NumCaptureDevices = 0;
748 }
749 
751 {
752  ALuint i;
753 
754  switch(type)
755  {
756  case ALL_DEVICE_PROBE:
758  for(i = 0;i < NumPlaybackDevices;i++)
759  {
760  if(PlaybackDeviceList[i])
762  }
763  break;
764 
767  for(i = 0;i < NumCaptureDevices;i++)
768  {
769  if(CaptureDeviceList[i])
771  }
772  break;
773  }
774 }
static void CALLBACK WaveOutProc(HWAVEOUT device, UINT msg, DWORD_PTR instance, DWORD_PTR param1, DWORD_PTR param2)
Definition: winmm.c:149
unsigned char ALubyte
Definition: al.h:47
GLenum GLint param
Definition: gl2ext.h:1491
static void WinMMStopCapture(ALCdevice *Device)
Definition: winmm.c:687
#define ALC_TRUE
Definition: alc.h:84
static ALCchar ** CaptureDeviceList
Definition: winmm.c:60
GLint GLenum GLsizei GLsizei GLsizei GLint GLenum GLenum type
Definition: gl2ext.h:845
GLvoid **typedef void(GLAPIENTRY *PFNGLGETVERTEXATTRIBDVPROC)(GLuint
Definition: glew.h:1824
static ALCuint WinMMAvailableSamples(ALCdevice *Device)
Definition: winmm.c:700
#define AL_TRUE
Definition: al.h:86
static ALCenum WinMMOpenPlayback(ALCdevice *Device, const ALCchar *deviceName)
Definition: winmm.c:273
char * strdup(const char *inStr)
Definition: strdup.c:6
#define NULL
Definition: ftobjs.h:61
static void WinMMStopPlayback(ALCdevice *device)
Definition: winmm.c:458
#define ALC_INVALID_ENUM
Definition: alc.h:111
SDL_EventEntry * free
Definition: SDL_events.c:80
ALuint Frequency
Definition: alMain.h:569
int ALint
Definition: al.h:56
int32_t j
Definition: e_log.c:102
ALvoid aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size)
Definition: ALu.c:970
#define memset
Definition: SDL_malloc.c:633
#define AL_FALSE
Definition: al.h:83
static ALuint NumCaptureDevices
Definition: winmm.c:61
ALint64 ALCdevice_GetLatencyDefault(ALCdevice *device)
Definition: ALc.c:1285
EGLImageKHR EGLint * name
Definition: eglext.h:284
static void WinMMCloseCapture(ALCdevice *Device)
Definition: winmm.c:640
static void ProbePlaybackDevices(void)
Definition: winmm.c:64
ALsizei RingBufferSize(RingBuffer *ring)
Definition: alcRing.c:67
typedef UINT(WINAPI *PFNWGLGETCONTEXTGPUIDAMDPROC)(HGLRC hglrc)
void AppendCaptureDeviceList(const ALCchar *name)
unsigned int ALCuint
Definition: alc.h:60
#define calloc
Definition: SDL_malloc.c:636
char ALCchar
Definition: alc.h:42
signed char ALbyte
Definition: al.h:44
static ALCchar ** PlaybackDeviceList
Definition: winmm.c:58
struct RingBuffer RingBuffer
Definition: alMain.h:750
EGLContext EGLenum EGLClientBuffer buffer
Definition: eglext.h:87
void * ExtraData
Definition: alMain.h:630
#define ALC_FALSE
Definition: alc.h:81
ALCboolean alcWinMMInit(BackendFuncs *FuncList)
Definition: winmm.c:724
typedef HANDLE(WINAPI *PFNWGLCREATEBUFFERREGIONARBPROC)(HDC hDC
void SetDefaultWFXChannelOrder(ALCdevice *device)
Definition: ALc.c:1295
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl2ext.h:848
static void CALLBACK WaveInProc(HWAVEIN device, UINT msg, DWORD_PTR instance, DWORD_PTR param1, DWORD_PTR param2)
Definition: winmm.c:216
GLint GLsizei count
Definition: gl2ext.h:1011
static ALCboolean WinMMResetPlayback(ALCdevice *device)
Definition: winmm.c:372
static DWORD WINAPI CaptureThreadProc(LPVOID param)
Definition: winmm.c:237
RingBuffer * CreateRingBuffer(ALsizei frame_size, ALsizei length)
Definition: alcRing.c:41
#define realloc
Definition: SDL_malloc.c:637
unsigned int ALuint
Definition: al.h:59
void SetRTPriority(void)
Definition: helpers.c:470
static ALCenum WinMMCaptureSamples(ALCdevice *Device, ALCvoid *Buffer, ALCuint Samples)
Definition: winmm.c:693
#define FALSE
Definition: ftobjs.h:57
#define WAVE_FORMAT_PCM
Definition: makehrtf.c:177
enum DevFmtChannels FmtChans
Definition: alMain.h:572
static void ProbeCaptureDevices(void)
Definition: winmm.c:103
typedef LPVOID(WINAPI *PFNWGLCREATEIMAGEBUFFERI3DPROC)(HDC hDC
#define ALC_NO_ERROR
Definition: alc.h:102
void ALCdevice_LockDefault(ALCdevice *device)
Definition: ALc.c:1277
static ALuint NumPlaybackDevices
Definition: winmm.c:59
#define WAVE_FORMAT_IEEE_FLOAT
Definition: winmm.c:34
char ALCboolean
Definition: alc.h:39
void ALCvoid
Definition: alc.h:75
#define ERR(...)
Definition: alMain.h:816
ALuint UpdateSize
Definition: alMain.h:570
ALuint NumUpdates
Definition: alMain.h:571
typedef DWORD(WINAPI *XInputGetState_t)(DWORD dwUserIndex
enum DevFmtType FmtType
Definition: alMain.h:573
char ALboolean
Definition: al.h:38
static ALCboolean WinMMStartPlayback(ALCdevice *device)
Definition: winmm.c:425
#define ALC_INVALID_VALUE
Definition: alc.h:114
#define ALC_OUT_OF_MEMORY
Definition: alc.h:117
static void WinMMStartCapture(ALCdevice *Device)
Definition: winmm.c:681
static DWORD WINAPI PlaybackThreadProc(LPVOID param)
Definition: winmm.c:170
static void WinMMClosePlayback(ALCdevice *device)
Definition: winmm.c:357
void ReadRingBuffer(RingBuffer *ring, ALubyte *data, ALsizei len)
Definition: alcRing.c:108
void alcWinMMProbe(enum DevProbe type)
Definition: winmm.c:750
int i
Definition: pngrutil.c:1377
int ALCenum
Definition: alc.h:66
ALuint BytesFromDevFmt(enum DevFmtType type)
Definition: ALc.c:1165
void alcWinMMDeinit()
Definition: winmm.c:730
void DestroyRingBuffer(RingBuffer *ring)
Definition: alcRing.c:58
void ALCdevice_UnlockDefault(ALCdevice *device)
Definition: ALc.c:1281
void WriteRingBuffer(RingBuffer *ring, const ALubyte *data, ALsizei len)
Definition: alcRing.c:78
ALuint ChannelsFromDevFmt(enum DevFmtChannels chans)
Definition: ALc.c:1179
GLuint res
Definition: glew.h:10669
static const BackendFuncs WinMMFuncs
Definition: winmm.c:707
void AppendAllDevicesList(const ALCchar *name)
static ALCenum WinMMOpenCapture(ALCdevice *Device, const ALCchar *deviceName)
Definition: winmm.c:489
DevProbe
Definition: alMain.h:383
static __inline ALuint FrameSizeFromDevFmt(enum DevFmtChannels chans, enum DevFmtType type)
Definition: alMain.h:523