33 #ifndef WAVE_FORMAT_IEEE_FLOAT
34 #define WAVE_FORMAT_IEEE_FLOAT 0x0003
44 volatile LONG WaveBuffersCommitted;
45 WAVEHDR WaveBuffer[4];
71 NumPlaybackDevices = waveOutGetNumDevs();
78 if(waveOutGetDevCaps(i, &WaveCaps,
sizeof(WaveCaps)) == MMSYSERR_NOERROR)
86 snprintf(name,
sizeof(name),
"%s", WaveCaps.szPname);
88 snprintf(name,
sizeof(name),
"%s #%d", WaveCaps.szPname, count+1);
110 NumCaptureDevices = waveInGetNumDevs();
114 WAVEINCAPS WaveInCaps;
117 if(waveInGetDevCaps(i, &WaveInCaps,
sizeof(WAVEINCAPS)) == MMSYSERR_NOERROR)
125 snprintf(name,
sizeof(name),
"%s", WaveInCaps.szPname);
127 snprintf(name,
sizeof(name),
"%s #%d", WaveInCaps.szPname, count+1);
149 static void CALLBACK
WaveOutProc(HWAVEOUT device,
UINT msg, DWORD_PTR instance, DWORD_PTR param1, DWORD_PTR param2)
160 InterlockedDecrement(&data->WaveBuffersCommitted);
161 PostThreadMessage(data->WaveThreadID, msg, 0, param1);
182 while(GetMessage(&msg,
NULL, 0, 0))
184 if(msg.message != WOM_DONE)
189 if(data->WaveBuffersCommitted == 0)
194 WaveHdr = ((LPWAVEHDR)msg.lParam);
195 aluMixData(Device, WaveHdr->lpData, WaveHdr->dwBufferLength/FrameSize);
198 waveOutWrite(data->WaveHandle.Out, WaveHdr,
sizeof(WAVEHDR));
199 InterlockedIncrement(&data->WaveBuffersCommitted);
203 if(data->WaveThreadEvent)
204 SetEvent(data->WaveThreadEvent);
216 static void CALLBACK
WaveInProc(HWAVEIN device,
UINT msg, DWORD_PTR instance, DWORD_PTR param1, DWORD_PTR param2)
227 InterlockedDecrement(&data->WaveBuffersCommitted);
228 PostThreadMessage(data->WaveThreadID, msg, 0, param1);
247 while(GetMessage(&msg,
NULL, 0, 0))
249 if(msg.message != WIM_DATA)
256 WaveHdr = ((LPWAVEHDR)msg.lParam);
260 waveInAddBuffer(data->WaveHandle.In, WaveHdr,
sizeof(WAVEHDR));
261 InterlockedIncrement(&data->WaveBuffersCommitted);
265 if(data->WaveThreadEvent)
266 SetEvent(data->WaveThreadEvent);
293 if(i == NumPlaybackDevices)
296 data =
calloc(1,
sizeof(*data));
306 data->Format.wBitsPerSample = 32;
312 data->Format.wBitsPerSample = 8;
314 data->Format.wBitsPerSample = 16;
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;
324 if((res=waveOutOpen(&data->WaveHandle.Out, DeviceID, &data->Format, (DWORD_PTR)&
WaveOutProc, (DWORD_PTR)Device, CALLBACK_FUNCTION)) != MMSYSERR_NOERROR)
331 ERR(
"waveOutOpen failed: %u\n", res);
336 if(data->WaveThreadEvent ==
NULL)
338 ERR(
"CreateEvent failed: %lu\n", GetLastError());
346 if(data->WaveThreadEvent)
347 CloseHandle(data->WaveThreadEvent);
349 if(data->WaveHandle.Out)
350 waveOutClose(data->WaveHandle.Out);
353 Device->ExtraData =
NULL;
362 CloseHandle(data->WaveThreadEvent);
363 data->WaveThreadEvent = 0;
365 waveOutClose(data->WaveHandle.Out);
366 data->WaveHandle.Out = 0;
377 data->Format.nSamplesPerSec /
381 device->
Frequency = data->Format.nSamplesPerSec;
385 if(data->Format.wBitsPerSample == 32)
389 ERR(
"Unhandled IEEE float sample depth: %d\n", data->Format.wBitsPerSample);
395 if(data->Format.wBitsPerSample == 16)
397 else if(data->Format.wBitsPerSample == 8)
401 ERR(
"Unhandled PCM sample depth: %d\n", data->Format.wBitsPerSample);
407 ERR(
"Unhandled format tag: 0x%04x\n", data->Format.wFormatTag);
411 if(data->Format.nChannels == 2)
413 else if(data->Format.nChannels == 1)
417 ERR(
"Unhandled channel count: %d\n", data->Format.nChannels);
433 if(data->WaveThread ==
NULL)
436 data->WaveBuffersCommitted = 0;
442 BufferData =
calloc(4, BufferSize);
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);
464 if(data->WaveThread ==
NULL)
471 WaitForSingleObjectEx(data->WaveThreadEvent, 5000,
FALSE);
473 CloseHandle(data->WaveThread);
474 data->WaveThread = 0;
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;
492 DWORD CapturedDataSize;
512 if(i == NumCaptureDevices)
543 data =
calloc(1,
sizeof(*data));
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;
560 if((res=waveInOpen(&data->WaveHandle.In, DeviceID, &data->Format, (DWORD_PTR)&
WaveInProc, (DWORD_PTR)Device, CALLBACK_FUNCTION)) != MMSYSERR_NOERROR)
562 ERR(
"waveInOpen failed: %u\n", res);
567 if(data->WaveThreadEvent ==
NULL)
569 ERR(
"CreateEvent failed: %lu\n", GetLastError());
574 CapturedDataSize = Device->UpdateSize*Device->NumUpdates;
577 if(CapturedDataSize < (data->Format.nSamplesPerSec / 10))
578 CapturedDataSize = data->Format.nSamplesPerSec / 10;
584 data->WaveBuffersCommitted = 0;
587 BufferSize = data->Format.nAvgBytesPerSec / 20;
588 BufferSize -= (BufferSize % data->Format.nBlockAlign);
590 BufferData =
calloc(4, BufferSize);
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);
609 if (data->WaveThread ==
NULL)
617 CloseHandle(data->WaveThread);
622 waveInUnprepareHeader(data->WaveHandle.In, &data->WaveBuffer[i],
sizeof(WAVEHDR));
629 if(data->WaveThreadEvent)
630 CloseHandle(data->WaveThreadEvent);
632 if(data->WaveHandle.In)
633 waveInClose(data->WaveHandle.In);
636 Device->ExtraData =
NULL;
648 PostThreadMessage(data->WaveThreadID, WM_QUIT, 0, 0);
650 WaitForSingleObjectEx(data->WaveThreadEvent, 5000,
FALSE);
653 waveInReset(data->WaveHandle.In);
655 CloseHandle(data->WaveThread);
656 data->WaveThread = 0;
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;
671 CloseHandle(data->WaveThreadEvent);
672 data->WaveThreadEvent = 0;
674 waveInClose(data->WaveHandle.In);
675 data->WaveHandle.In = 0;
684 waveInStart(data->WaveHandle.In);
690 waveInStop(data->WaveHandle.In);
739 NumPlaybackDevices = 0;
747 NumCaptureDevices = 0;
static void CALLBACK WaveOutProc(HWAVEOUT device, UINT msg, DWORD_PTR instance, DWORD_PTR param1, DWORD_PTR param2)
static void WinMMStopCapture(ALCdevice *Device)
static ALCchar ** CaptureDeviceList
GLint GLenum GLsizei GLsizei GLsizei GLint GLenum GLenum type
GLvoid **typedef void(GLAPIENTRY *PFNGLGETVERTEXATTRIBDVPROC)(GLuint
static ALCuint WinMMAvailableSamples(ALCdevice *Device)
static ALCenum WinMMOpenPlayback(ALCdevice *Device, const ALCchar *deviceName)
char * strdup(const char *inStr)
static void WinMMStopPlayback(ALCdevice *device)
ALvoid aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size)
static ALuint NumCaptureDevices
ALint64 ALCdevice_GetLatencyDefault(ALCdevice *device)
EGLImageKHR EGLint * name
static void WinMMCloseCapture(ALCdevice *Device)
static void ProbePlaybackDevices(void)
ALsizei RingBufferSize(RingBuffer *ring)
typedef UINT(WINAPI *PFNWGLGETCONTEXTGPUIDAMDPROC)(HGLRC hglrc)
void AppendCaptureDeviceList(const ALCchar *name)
static ALCchar ** PlaybackDeviceList
struct RingBuffer RingBuffer
EGLContext EGLenum EGLClientBuffer buffer
ALCboolean alcWinMMInit(BackendFuncs *FuncList)
typedef HANDLE(WINAPI *PFNWGLCREATEBUFFERREGIONARBPROC)(HDC hDC
void SetDefaultWFXChannelOrder(ALCdevice *device)
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
static void CALLBACK WaveInProc(HWAVEIN device, UINT msg, DWORD_PTR instance, DWORD_PTR param1, DWORD_PTR param2)
static ALCboolean WinMMResetPlayback(ALCdevice *device)
static DWORD WINAPI CaptureThreadProc(LPVOID param)
RingBuffer * CreateRingBuffer(ALsizei frame_size, ALsizei length)
static ALCenum WinMMCaptureSamples(ALCdevice *Device, ALCvoid *Buffer, ALCuint Samples)
enum DevFmtChannels FmtChans
static void ProbeCaptureDevices(void)
typedef LPVOID(WINAPI *PFNWGLCREATEIMAGEBUFFERI3DPROC)(HDC hDC
void ALCdevice_LockDefault(ALCdevice *device)
static ALuint NumPlaybackDevices
#define WAVE_FORMAT_IEEE_FLOAT
typedef DWORD(WINAPI *XInputGetState_t)(DWORD dwUserIndex
static ALCboolean WinMMStartPlayback(ALCdevice *device)
#define ALC_INVALID_VALUE
#define ALC_OUT_OF_MEMORY
static void WinMMStartCapture(ALCdevice *Device)
static DWORD WINAPI PlaybackThreadProc(LPVOID param)
static void WinMMClosePlayback(ALCdevice *device)
void ReadRingBuffer(RingBuffer *ring, ALubyte *data, ALsizei len)
void alcWinMMProbe(enum DevProbe type)
ALuint BytesFromDevFmt(enum DevFmtType type)
void DestroyRingBuffer(RingBuffer *ring)
void ALCdevice_UnlockDefault(ALCdevice *device)
void WriteRingBuffer(RingBuffer *ring, const ALubyte *data, ALsizei len)
ALuint ChannelsFromDevFmt(enum DevFmtChannels chans)
static const BackendFuncs WinMMFuncs
void AppendAllDevicesList(const ALCchar *name)
static ALCenum WinMMOpenCapture(ALCdevice *Device, const ALCchar *deviceName)
static __inline ALuint FrameSizeFromDevFmt(enum DevFmtChannels chans, enum DevFmtType type)