void alcWinMMProbe(enum DevProbe type) { ALuint i; switch(type) { case ALL_DEVICE_PROBE: ProbePlaybackDevices(); for(i = 0;i < NumPlaybackDevices;i++) { if(PlaybackDeviceList[i]) AppendAllDeviceList(PlaybackDeviceList[i]); } break; case CAPTURE_DEVICE_PROBE: ProbeCaptureDevices(); for(i = 0;i < NumCaptureDevices;i++) { if(CaptureDeviceList[i]) AppendCaptureDeviceList(CaptureDeviceList[i]); } break; } }
void alcWinMMProbe(int type) { ALuint i; if(type == DEVICE_PROBE) { ProbePlaybackDevices(); if(NumPlaybackDevices > 0) AppendDeviceList(woDefault); } else if(type == ALL_DEVICE_PROBE) { ProbePlaybackDevices(); if(NumPlaybackDevices > 0) AppendAllDeviceList(woDefault); for(i = 0;i < NumPlaybackDevices;i++) { if(PlaybackDeviceList[i]) AppendAllDeviceList(PlaybackDeviceList[i]); } } else if(type == CAPTURE_DEVICE_PROBE) { ProbeCaptureDevices(); for(i = 0;i < NumCaptureDevices;i++) { if(CaptureDeviceList[i]) AppendCaptureDeviceList(CaptureDeviceList[i]); } } }
void alcWinMMProbe(enum DevProbe type) { switch(type) { case ALL_DEVICE_PROBE: ProbePlaybackDevices(); VECTOR_FOR_EACH(const al_string, PlaybackDevices, AppendAllDevicesList2); break; case CAPTURE_DEVICE_PROBE: ProbeCaptureDevices(); VECTOR_FOR_EACH(const al_string, CaptureDevices, AppendCaptureDeviceList2); break; } }
static void ALCwinmmBackendFactory_probe(ALCwinmmBackendFactory* UNUSED(self), enum DevProbe type, al_string *outnames) { switch(type) { #define APPEND_OUTNAME(n) do { \ if(!alstr_empty(*(n))) \ alstr_append_range(outnames, VECTOR_BEGIN(*(n)), VECTOR_END(*(n))+1); \ } while(0) case ALL_DEVICE_PROBE: ProbePlaybackDevices(); VECTOR_FOR_EACH(const al_string, PlaybackDevices, APPEND_OUTNAME); break; case CAPTURE_DEVICE_PROBE: ProbeCaptureDevices(); VECTOR_FOR_EACH(const al_string, CaptureDevices, APPEND_OUTNAME); break; #undef APPEND_OUTNAME } }
static ALCenum WinMMOpenCapture(ALCdevice *Device, const ALCchar *deviceName) { const al_string *iter, *end; ALbyte *BufferData = NULL; DWORD CapturedDataSize; WinMMData *data = NULL; ALint BufferSize; UINT DeviceID; MMRESULT res; ALuint i; if(VECTOR_SIZE(CaptureDevices) == 0) ProbeCaptureDevices(); // Find the Device ID matching the deviceName if valid iter = VECTOR_ITER_BEGIN(CaptureDevices); end = VECTOR_ITER_END(CaptureDevices); for(; iter != end; iter++) { if(!al_string_empty(*iter) && (!deviceName || al_string_cmp_cstr(*iter, deviceName) == 0)) { DeviceID = (UINT)(iter - VECTOR_ITER_BEGIN(CaptureDevices)); break; } } if(iter == end) return ALC_INVALID_VALUE; switch(Device->FmtChans) { case DevFmtMono: case DevFmtStereo: break; case DevFmtQuad: case DevFmtX51: case DevFmtX51Side: case DevFmtX61: case DevFmtX71: return ALC_INVALID_ENUM; } switch(Device->FmtType) { case DevFmtUByte: case DevFmtShort: case DevFmtInt: case DevFmtFloat: break; case DevFmtByte: case DevFmtUShort: case DevFmtUInt: return ALC_INVALID_ENUM; } data = calloc(1, sizeof(*data)); if(!data) return ALC_OUT_OF_MEMORY; Device->ExtraData = data; memset(&data->Format, 0, sizeof(WAVEFORMATEX)); data->Format.wFormatTag = ((Device->FmtType == DevFmtFloat) ? WAVE_FORMAT_IEEE_FLOAT : WAVE_FORMAT_PCM); data->Format.nChannels = ChannelsFromDevFmt(Device->FmtChans); data->Format.wBitsPerSample = BytesFromDevFmt(Device->FmtType) * 8; data->Format.nBlockAlign = data->Format.wBitsPerSample * data->Format.nChannels / 8; data->Format.nSamplesPerSec = Device->Frequency; data->Format.nAvgBytesPerSec = data->Format.nSamplesPerSec * data->Format.nBlockAlign; data->Format.cbSize = 0; if((res=waveInOpen(&data->WaveHandle.In, DeviceID, &data->Format, (DWORD_PTR)&WaveInProc, (DWORD_PTR)Device, CALLBACK_FUNCTION)) != MMSYSERR_NOERROR) { ERR("waveInOpen failed: %u\n", res); goto failure; } // Allocate circular memory buffer for the captured audio CapturedDataSize = Device->UpdateSize*Device->NumUpdates; // Make sure circular buffer is at least 100ms in size if(CapturedDataSize < (data->Format.nSamplesPerSec / 10)) CapturedDataSize = data->Format.nSamplesPerSec / 10; data->Ring = CreateRingBuffer(data->Format.nBlockAlign, CapturedDataSize); if(!data->Ring) goto failure; InitRef(&data->WaveBuffersCommitted, 0); // Create 4 Buffers of 50ms each BufferSize = data->Format.nAvgBytesPerSec / 20; BufferSize -= (BufferSize % data->Format.nBlockAlign); BufferData = calloc(4, BufferSize); if(!BufferData) goto failure; for(i = 0; i < 4; i++) { memset(&data->WaveBuffer[i], 0, sizeof(WAVEHDR)); data->WaveBuffer[i].dwBufferLength = BufferSize; data->WaveBuffer[i].lpData = ((i==0) ? (CHAR*)BufferData : (data->WaveBuffer[i-1].lpData + data->WaveBuffer[i-1].dwBufferLength)); data->WaveBuffer[i].dwFlags = 0; data->WaveBuffer[i].dwLoops = 0; waveInPrepareHeader(data->WaveHandle.In, &data->WaveBuffer[i], sizeof(WAVEHDR)); waveInAddBuffer(data->WaveHandle.In, &data->WaveBuffer[i], sizeof(WAVEHDR)); IncrementRef(&data->WaveBuffersCommitted); } if(althrd_create(&data->thread, CaptureThreadProc, Device) != althrd_success) goto failure; al_string_copy(&Device->DeviceName, VECTOR_ELEM(CaptureDevices, DeviceID)); return ALC_NO_ERROR; failure: if(BufferData) { for(i = 0; i < 4; i++) waveInUnprepareHeader(data->WaveHandle.In, &data->WaveBuffer[i], sizeof(WAVEHDR)); free(BufferData); } if(data->Ring) DestroyRingBuffer(data->Ring); if(data->WaveHandle.In) waveInClose(data->WaveHandle.In); free(data); Device->ExtraData = NULL; return ALC_INVALID_VALUE; }
static ALCenum WinMMOpenCapture(ALCdevice *pDevice, const ALCchar *deviceName) { ALbyte *BufferData = NULL; DWORD ulCapturedDataSize; WinMMData *pData = NULL; UINT lDeviceID = 0; ALint lBufferSize; MMRESULT res; ALuint i; if(!CaptureDeviceList) ProbeCaptureDevices(); // Find the Device ID matching the deviceName if valid for(i = 0;i < NumCaptureDevices;i++) { if(CaptureDeviceList[i] && (!deviceName || strcmp(deviceName, CaptureDeviceList[i]) == 0)) { lDeviceID = i; break; } } if(i == NumCaptureDevices) return ALC_INVALID_VALUE; switch(pDevice->FmtChans) { case DevFmtMono: case DevFmtStereo: break; case DevFmtQuad: case DevFmtX51: case DevFmtX51Side: case DevFmtX61: case DevFmtX71: return ALC_INVALID_ENUM; } switch(pDevice->FmtType) { case DevFmtUByte: case DevFmtShort: case DevFmtInt: case DevFmtFloat: break; case DevFmtByte: case DevFmtUShort: case DevFmtUInt: return ALC_INVALID_ENUM; } pData = calloc(1, sizeof(*pData)); if(!pData) return ALC_OUT_OF_MEMORY; pDevice->ExtraData = pData; memset(&pData->wfexFormat, 0, sizeof(WAVEFORMATEX)); pData->wfexFormat.wFormatTag = ((pDevice->FmtType == DevFmtFloat) ? WAVE_FORMAT_IEEE_FLOAT : WAVE_FORMAT_PCM); pData->wfexFormat.nChannels = ChannelsFromDevFmt(pDevice->FmtChans); pData->wfexFormat.wBitsPerSample = BytesFromDevFmt(pDevice->FmtType) * 8; pData->wfexFormat.nBlockAlign = pData->wfexFormat.wBitsPerSample * pData->wfexFormat.nChannels / 8; pData->wfexFormat.nSamplesPerSec = pDevice->Frequency; pData->wfexFormat.nAvgBytesPerSec = pData->wfexFormat.nSamplesPerSec * pData->wfexFormat.nBlockAlign; pData->wfexFormat.cbSize = 0; if((res=waveInOpen(&pData->hWaveHandle.In, lDeviceID, &pData->wfexFormat, (DWORD_PTR)&WaveInProc, (DWORD_PTR)pDevice, CALLBACK_FUNCTION)) != MMSYSERR_NOERROR) { ERR("waveInOpen failed: %u\n", res); goto failure; } pData->hWaveThreadEvent = CreateEvent(NULL, FALSE, FALSE, NULL); if(pData->hWaveThreadEvent == NULL) { ERR("CreateEvent failed: %lu\n", GetLastError()); goto failure; } // Allocate circular memory buffer for the captured audio ulCapturedDataSize = pDevice->UpdateSize*pDevice->NumUpdates; // Make sure circular buffer is at least 100ms in size if(ulCapturedDataSize < (pData->wfexFormat.nSamplesPerSec / 10)) ulCapturedDataSize = pData->wfexFormat.nSamplesPerSec / 10; pData->pRing = CreateRingBuffer(pData->wfexFormat.nBlockAlign, ulCapturedDataSize); if(!pData->pRing) goto failure; pData->lWaveBuffersCommitted = 0; // Create 4 Buffers of 50ms each lBufferSize = pData->wfexFormat.nAvgBytesPerSec / 20; lBufferSize -= (lBufferSize % pData->wfexFormat.nBlockAlign); BufferData = calloc(4, lBufferSize); if(!BufferData) goto failure; for(i = 0;i < 4;i++) { memset(&pData->WaveBuffer[i], 0, sizeof(WAVEHDR)); pData->WaveBuffer[i].dwBufferLength = lBufferSize; pData->WaveBuffer[i].lpData = ((i==0) ? (LPSTR)BufferData : (pData->WaveBuffer[i-1].lpData + pData->WaveBuffer[i-1].dwBufferLength)); pData->WaveBuffer[i].dwFlags = 0; pData->WaveBuffer[i].dwLoops = 0; waveInPrepareHeader(pData->hWaveHandle.In, &pData->WaveBuffer[i], sizeof(WAVEHDR)); waveInAddBuffer(pData->hWaveHandle.In, &pData->WaveBuffer[i], sizeof(WAVEHDR)); InterlockedIncrement(&pData->lWaveBuffersCommitted); } pData->hWaveThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)CaptureThreadProc, (LPVOID)pDevice, 0, &pData->ulWaveThreadID); if (pData->hWaveThread == NULL) goto failure; pDevice->szDeviceName = strdup(CaptureDeviceList[lDeviceID]); return ALC_NO_ERROR; failure: if(pData->hWaveThread) CloseHandle(pData->hWaveThread); if(BufferData) { for(i = 0;i < 4;i++) waveInUnprepareHeader(pData->hWaveHandle.In, &pData->WaveBuffer[i], sizeof(WAVEHDR)); free(BufferData); } if(pData->pRing) DestroyRingBuffer(pData->pRing); if(pData->hWaveThreadEvent) CloseHandle(pData->hWaveThreadEvent); if(pData->hWaveHandle.In) waveInClose(pData->hWaveHandle.In); free(pData); pDevice->ExtraData = NULL; return ALC_INVALID_VALUE; }
static ALCboolean WinMMOpenCapture(ALCdevice *pDevice, const ALCchar *deviceName) { WAVEFORMATEX wfexCaptureFormat; DWORD ulCapturedDataSize; WinMMData *pData = NULL; UINT lDeviceID = 0; ALbyte *BufferData; ALint lBufferSize; MMRESULT res; ALuint i; if(!CaptureDeviceList) ProbeCaptureDevices(); // Find the Device ID matching the deviceName if valid if(deviceName) { for(i = 0;i < NumCaptureDevices;i++) { if(CaptureDeviceList[i] && strcmp(deviceName, CaptureDeviceList[i]) == 0) { lDeviceID = i; break; } } } else { for(i = 0;i < NumCaptureDevices;i++) { if(CaptureDeviceList[i]) { lDeviceID = i; break; } } } if(i == NumCaptureDevices) return ALC_FALSE; pData = calloc(1, sizeof(*pData)); if(!pData) { alcSetError(pDevice, ALC_OUT_OF_MEMORY); return ALC_FALSE; } pDevice->ExtraData = pData; if((pDevice->FmtChans != DevFmtMono && pDevice->FmtChans != DevFmtStereo) || (pDevice->FmtType != DevFmtUByte && pDevice->FmtType != DevFmtShort)) { alcSetError(pDevice, ALC_INVALID_ENUM); goto failure; } memset(&wfexCaptureFormat, 0, sizeof(WAVEFORMATEX)); wfexCaptureFormat.wFormatTag = WAVE_FORMAT_PCM; wfexCaptureFormat.nChannels = ChannelsFromDevFmt(pDevice->FmtChans); wfexCaptureFormat.wBitsPerSample = BytesFromDevFmt(pDevice->FmtType) * 8; wfexCaptureFormat.nBlockAlign = wfexCaptureFormat.wBitsPerSample * wfexCaptureFormat.nChannels / 8; wfexCaptureFormat.nSamplesPerSec = pDevice->Frequency; wfexCaptureFormat.nAvgBytesPerSec = wfexCaptureFormat.nSamplesPerSec * wfexCaptureFormat.nBlockAlign; wfexCaptureFormat.cbSize = 0; if((res=waveInOpen(&pData->hWaveHandle.In, lDeviceID, &wfexCaptureFormat, (DWORD_PTR)&WaveInProc, (DWORD_PTR)pDevice, CALLBACK_FUNCTION)) != MMSYSERR_NOERROR) { AL_PRINT("waveInOpen failed: %u\n", res); goto failure; } pData->hWaveHdrEvent = CreateEvent(NULL, AL_TRUE, AL_FALSE, "WaveInAllHeadersReturned"); pData->hWaveThreadEvent = CreateEvent(NULL, AL_TRUE, AL_FALSE, "WaveInThreadDestroyed"); if(pData->hWaveHdrEvent == NULL || pData->hWaveThreadEvent == NULL) { AL_PRINT("CreateEvent failed: %lu\n", GetLastError()); goto failure; } pData->Frequency = pDevice->Frequency; // Allocate circular memory buffer for the captured audio ulCapturedDataSize = pDevice->UpdateSize*pDevice->NumUpdates; // Make sure circular buffer is at least 100ms in size if(ulCapturedDataSize < (wfexCaptureFormat.nSamplesPerSec / 10)) ulCapturedDataSize = wfexCaptureFormat.nSamplesPerSec / 10; pData->pRing = CreateRingBuffer(wfexCaptureFormat.nBlockAlign, ulCapturedDataSize); if(!pData->pRing) goto failure; pData->lWaveBuffersCommitted = 0; // Create 4 Buffers of 50ms each lBufferSize = wfexCaptureFormat.nAvgBytesPerSec / 20; lBufferSize -= (lBufferSize % wfexCaptureFormat.nBlockAlign); BufferData = calloc(4, lBufferSize); if(!BufferData) goto failure; for(i = 0;i < 4;i++) { memset(&pData->WaveBuffer[i], 0, sizeof(WAVEHDR)); pData->WaveBuffer[i].dwBufferLength = lBufferSize; pData->WaveBuffer[i].lpData = ((i==0) ? (LPSTR)BufferData : (pData->WaveBuffer[i-1].lpData + pData->WaveBuffer[i-1].dwBufferLength)); pData->WaveBuffer[i].dwFlags = 0; pData->WaveBuffer[i].dwLoops = 0; waveInPrepareHeader(pData->hWaveHandle.In, &pData->WaveBuffer[i], sizeof(WAVEHDR)); waveInAddBuffer(pData->hWaveHandle.In, &pData->WaveBuffer[i], sizeof(WAVEHDR)); InterlockedIncrement(&pData->lWaveBuffersCommitted); } pData->hWaveThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)CaptureThreadProc, (LPVOID)pDevice, 0, &pData->ulWaveThreadID); if (pData->hWaveThread == NULL) goto failure; pDevice->szDeviceName = strdup(CaptureDeviceList[lDeviceID]); return ALC_TRUE; failure: if(pData->hWaveThread) CloseHandle(pData->hWaveThread); for(i = 0;i < 4;i++) { if(pData->WaveBuffer[i].lpData) { waveInUnprepareHeader(pData->hWaveHandle.In, &pData->WaveBuffer[i], sizeof(WAVEHDR)); if(i == 0) free(pData->WaveBuffer[i].lpData); } } if(pData->pRing) DestroyRingBuffer(pData->pRing); if(pData->hWaveThreadEvent) CloseHandle(pData->hWaveThreadEvent); if(pData->hWaveHdrEvent) CloseHandle(pData->hWaveHdrEvent); if(pData->hWaveHandle.In) waveInClose(pData->hWaveHandle.In); free(pData); pDevice->ExtraData = NULL; return ALC_FALSE; }
static ALCenum ALCwinmmCapture_open(ALCwinmmCapture *self, const ALCchar *name) { ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice; const al_string *iter; ALbyte *BufferData = NULL; DWORD CapturedDataSize; ALint BufferSize; UINT DeviceID; MMRESULT res; ALuint i; if(VECTOR_SIZE(CaptureDevices) == 0) ProbeCaptureDevices(); // Find the Device ID matching the deviceName if valid #define MATCH_DEVNAME(iter) (!alstr_empty(*(iter)) && (!name || alstr_cmp_cstr(*iter, name) == 0)) VECTOR_FIND_IF(iter, const al_string, CaptureDevices, MATCH_DEVNAME); if(iter == VECTOR_END(CaptureDevices)) return ALC_INVALID_VALUE; #undef MATCH_DEVNAME DeviceID = (UINT)(iter - VECTOR_BEGIN(CaptureDevices)); switch(device->FmtChans) { case DevFmtMono: case DevFmtStereo: break; case DevFmtQuad: case DevFmtX51: case DevFmtX51Rear: case DevFmtX61: case DevFmtX71: case DevFmtAmbi3D: return ALC_INVALID_ENUM; } switch(device->FmtType) { case DevFmtUByte: case DevFmtShort: case DevFmtInt: case DevFmtFloat: break; case DevFmtByte: case DevFmtUShort: case DevFmtUInt: return ALC_INVALID_ENUM; } memset(&self->Format, 0, sizeof(WAVEFORMATEX)); self->Format.wFormatTag = ((device->FmtType == DevFmtFloat) ? WAVE_FORMAT_IEEE_FLOAT : WAVE_FORMAT_PCM); self->Format.nChannels = ChannelsFromDevFmt(device->FmtChans, device->AmbiOrder); self->Format.wBitsPerSample = BytesFromDevFmt(device->FmtType) * 8; self->Format.nBlockAlign = self->Format.wBitsPerSample * self->Format.nChannels / 8; self->Format.nSamplesPerSec = device->Frequency; self->Format.nAvgBytesPerSec = self->Format.nSamplesPerSec * self->Format.nBlockAlign; self->Format.cbSize = 0; if((res=waveInOpen(&self->InHdl, DeviceID, &self->Format, (DWORD_PTR)&ALCwinmmCapture_waveInProc, (DWORD_PTR)self, CALLBACK_FUNCTION)) != MMSYSERR_NOERROR) { ERR("waveInOpen failed: %u\n", res); goto failure; } // Allocate circular memory buffer for the captured audio CapturedDataSize = device->UpdateSize*device->NumUpdates; // Make sure circular buffer is at least 100ms in size if(CapturedDataSize < (self->Format.nSamplesPerSec / 10)) CapturedDataSize = self->Format.nSamplesPerSec / 10; self->Ring = ll_ringbuffer_create(CapturedDataSize, self->Format.nBlockAlign, false); if(!self->Ring) goto failure; InitRef(&self->WaveBuffersCommitted, 0); // Create 4 Buffers of 50ms each BufferSize = self->Format.nAvgBytesPerSec / 20; BufferSize -= (BufferSize % self->Format.nBlockAlign); BufferData = calloc(4, BufferSize); if(!BufferData) goto failure; for(i = 0;i < 4;i++) { memset(&self->WaveBuffer[i], 0, sizeof(WAVEHDR)); self->WaveBuffer[i].dwBufferLength = BufferSize; self->WaveBuffer[i].lpData = ((i==0) ? (CHAR*)BufferData : (self->WaveBuffer[i-1].lpData + self->WaveBuffer[i-1].dwBufferLength)); self->WaveBuffer[i].dwFlags = 0; self->WaveBuffer[i].dwLoops = 0; waveInPrepareHeader(self->InHdl, &self->WaveBuffer[i], sizeof(WAVEHDR)); waveInAddBuffer(self->InHdl, &self->WaveBuffer[i], sizeof(WAVEHDR)); IncrementRef(&self->WaveBuffersCommitted); } ATOMIC_STORE(&self->killNow, AL_FALSE, almemory_order_release); if(althrd_create(&self->thread, ALCwinmmCapture_captureProc, self) != althrd_success) goto failure; alstr_copy(&device->DeviceName, VECTOR_ELEM(CaptureDevices, DeviceID)); return ALC_NO_ERROR; failure: if(BufferData) { for(i = 0;i < 4;i++) waveInUnprepareHeader(self->InHdl, &self->WaveBuffer[i], sizeof(WAVEHDR)); free(BufferData); } ll_ringbuffer_free(self->Ring); self->Ring = NULL; if(self->InHdl) waveInClose(self->InHdl); self->InHdl = NULL; return ALC_INVALID_VALUE; }