static void wave_in_tests(void) { WAVEINCAPSA capsA; WAVEINCAPSW capsW; WAVEFORMATEX format; HWAVEIN win; MMRESULT rc; DWORD preferred, status; UINT ndev,d; ndev=waveInGetNumDevs(); trace("found %d WaveIn devices\n",ndev); rc = waveInMessage((HWAVEIN)WAVE_MAPPER, DRVM_MAPPER_PREFERRED_GET, (DWORD_PTR)&preferred, (DWORD_PTR)&status); ok((ndev == 0 && (rc == MMSYSERR_NODRIVER || rc == MMSYSERR_BADDEVICEID)) || rc == MMSYSERR_NOTSUPPORTED || rc == MMSYSERR_NOERROR, "waveInMessage(DRVM_MAPPER_PREFERRED_GET) failed: %u\n", rc); if(rc != MMSYSERR_NOTSUPPORTED) ok((ndev == 0 && (preferred == -1 || broken(preferred != -1))) || preferred < ndev, "Got invalid preferred device: 0x%x\n", preferred); rc=waveInGetDevCapsA(ndev+1,&capsA,sizeof(capsA)); ok(rc==MMSYSERR_BADDEVICEID, "waveInGetDevCapsA(%s): MMSYSERR_BADDEVICEID expected, got %s\n", dev_name(ndev+1),wave_in_error(rc)); rc=waveInGetDevCapsA(WAVE_MAPPER,&capsA,sizeof(capsA)); ok(rc==MMSYSERR_NOERROR || rc==MMSYSERR_NODRIVER || (!ndev && (rc==MMSYSERR_BADDEVICEID)), "waveInGetDevCapsA(%s): got %s\n",dev_name(WAVE_MAPPER),wave_in_error(rc)); rc=waveInGetDevCapsW(ndev+1,&capsW,sizeof(capsW)); ok(rc==MMSYSERR_BADDEVICEID || rc==MMSYSERR_NOTSUPPORTED, "waveInGetDevCapsW(%s): MMSYSERR_BADDEVICEID or MMSYSERR_NOTSUPPORTED " "expected, got %s\n",dev_name(ndev+1),wave_in_error(rc)); rc=waveInGetDevCapsW(WAVE_MAPPER,&capsW,sizeof(capsW)); ok(rc==MMSYSERR_NOERROR || rc==MMSYSERR_NODRIVER || rc==MMSYSERR_NOTSUPPORTED || (!ndev && (rc==MMSYSERR_BADDEVICEID)), "waveInGetDevCapsW(%s): got %s\n", dev_name(ndev+1),wave_in_error(rc)); format.wFormatTag=WAVE_FORMAT_PCM; format.nChannels=2; format.wBitsPerSample=16; format.nSamplesPerSec=44100; format.nBlockAlign=format.nChannels*format.wBitsPerSample/8; format.nAvgBytesPerSec=format.nSamplesPerSec*format.nBlockAlign; format.cbSize=0; rc=waveInOpen(&win,ndev+1,&format,0,0,CALLBACK_NULL); ok(rc==MMSYSERR_BADDEVICEID, "waveInOpen(%s): MMSYSERR_BADDEVICEID expected, got %s\n", dev_name(ndev+1),wave_in_error(rc)); for (d=0;d<ndev;d++) wave_in_test_device(d); if (ndev>0) wave_in_test_device(WAVE_MAPPER); }
static cubeb_device_pref winmm_query_preferred_in_device(UINT devid) { DWORD mmpref = WAVE_MAPPER, compref = WAVE_MAPPER, status; cubeb_device_pref ret = CUBEB_DEVICE_PREF_NONE; if (waveInMessage((HWAVEIN)(size_t)WAVE_MAPPER, DRVM_MAPPER_PREFERRED_GET, (DWORD_PTR)&mmpref, (DWORD_PTR)&status) == MMSYSERR_NOERROR && devid == mmpref) ret |= CUBEB_DEVICE_PREF_MULTIMEDIA | CUBEB_DEVICE_PREF_NOTIFICATION; if (waveInMessage((HWAVEIN)(size_t)WAVE_MAPPER, DRVM_MAPPER_CONSOLEVOICECOM_GET, (DWORD_PTR)&compref, (DWORD_PTR)&status) == MMSYSERR_NOERROR && devid == compref) ret |= CUBEB_DEVICE_PREF_VOICE; return ret; }
OVR_PUBLIC_FUNCTION(ovrResult) ovr_GetAudioDeviceInWaveId(UINT* deviceInId) { if (!deviceInId) return ovrError_InvalidParameter; if (waveInMessage((HWAVEIN)WAVE_MAPPER, DRVM_MAPPER_PREFERRED_GET, (DWORD_PTR)deviceInId, NULL) != 0) return ovrError_RuntimeException; return ovrSuccess; }
OVR_PUBLIC_FUNCTION(ovrResult) ovr_GetAudioDeviceInWaveId(UINT* deviceInId) { REV_TRACE(ovr_GetAudioDeviceInWaveId); if (!deviceInId) return ovrError_InvalidParameter; // Query and cache the result static UINT cachedId = 0; if (!cachedId) { #pragma warning( disable : 4312 ) if (waveInMessage((HWAVEIN)WAVE_MAPPER, DRVM_MAPPER_PREFERRED_GET, (DWORD_PTR)&cachedId, NULL) != 0) return ovrError_AudioDeviceNotFound; #pragma warning( default : 4312 ) } *deviceInId = cachedId; return ovrSuccess; }
static void wave_in_test_device(UINT_PTR device) { WAVEINCAPSA capsA; WAVEINCAPSW capsW; WAVEFORMATEX format; WAVEFORMATEXTENSIBLE wfex; HWAVEIN win; MMRESULT rc; UINT f; WCHAR * nameW; CHAR * nameA; DWORD size; DWORD dwPageSize; BYTE * twoPages; SYSTEM_INFO sSysInfo; DWORD flOldProtect; BOOL res; GetSystemInfo(&sSysInfo); dwPageSize = sSysInfo.dwPageSize; rc=waveInGetDevCapsA(device,&capsA,sizeof(capsA)); ok(rc==MMSYSERR_NOERROR || rc==MMSYSERR_BADDEVICEID || rc==MMSYSERR_NODRIVER, "waveInGetDevCapsA(%s): failed to get capabilities: rc=%s\n", dev_name(device),wave_in_error(rc)); if (rc==MMSYSERR_BADDEVICEID || rc==MMSYSERR_NODRIVER) return; rc=waveInGetDevCapsW(device,&capsW,sizeof(capsW)); ok(rc==MMSYSERR_NOERROR || rc==MMSYSERR_NOTSUPPORTED, "waveInGetDevCapsW(%s): MMSYSERR_NOERROR or MMSYSERR_NOTSUPPORTED " "expected, got %s\n",dev_name(device),wave_in_error(rc)); rc=waveInGetDevCapsA(device,NULL,sizeof(capsA)); ok(rc==MMSYSERR_INVALPARAM, "waveInGetDevCapsA(%s): MMSYSERR_INVALPARAM expected, got %s\n", dev_name(device),wave_in_error(rc)); rc=waveInGetDevCapsW(device,NULL,sizeof(capsW)); ok(rc==MMSYSERR_INVALPARAM || rc==MMSYSERR_NOTSUPPORTED, "waveInGetDevCapsW(%s): MMSYSERR_INVALPARAM or MMSYSERR_NOTSUPPORTED " "expected, got %s\n",dev_name(device),wave_in_error(rc)); if (0) { /* FIXME: this works on windows but crashes wine */ rc=waveInGetDevCapsA(device,(LPWAVEINCAPSA)1,sizeof(capsA)); ok(rc==MMSYSERR_INVALPARAM, "waveInGetDevCapsA(%s): MMSYSERR_INVALPARAM expected, got %s\n", dev_name(device),wave_in_error(rc)); rc=waveInGetDevCapsW(device,(LPWAVEINCAPSW)1,sizeof(capsW)); ok(rc==MMSYSERR_INVALPARAM || rc==MMSYSERR_NOTSUPPORTED, "waveInGetDevCapsW(%s): MMSYSERR_INVALPARAM or MMSYSERR_NOTSUPPORTED " "expected, got %s\n",dev_name(device),wave_in_error(rc)); } rc=waveInGetDevCapsA(device,&capsA,4); ok(rc==MMSYSERR_NOERROR, "waveInGetDevCapsA(%s): MMSYSERR_NOERROR expected, got %s\n", dev_name(device),wave_in_error(rc)); rc=waveInGetDevCapsW(device,&capsW,4); ok(rc==MMSYSERR_NOERROR || rc==MMSYSERR_NOTSUPPORTED || rc==MMSYSERR_INVALPARAM, /* Vista, W2K8 */ "waveInGetDevCapsW(%s): unexpected return value %s\n", dev_name(device),wave_in_error(rc)); nameA=NULL; rc=waveInMessage((HWAVEIN)device, DRV_QUERYDEVICEINTERFACESIZE, (DWORD_PTR)&size, 0); ok(rc==MMSYSERR_NOERROR || rc==MMSYSERR_INVALPARAM || rc==MMSYSERR_NOTSUPPORTED, "waveInMessage(%s): failed to get interface size: rc=%s\n", dev_name(device),wave_in_error(rc)); if (rc==MMSYSERR_NOERROR) { nameW = HeapAlloc(GetProcessHeap(), 0, size); rc=waveInMessage((HWAVEIN)device, DRV_QUERYDEVICEINTERFACE, (DWORD_PTR)nameW, size); ok(rc==MMSYSERR_NOERROR,"waveInMessage(%s): failed to get interface " "name: rc=%s\n",dev_name(device),wave_in_error(rc)); ok(lstrlenW(nameW)+1==size/sizeof(WCHAR), "got an incorrect size %d\n", size); if (rc==MMSYSERR_NOERROR) { nameA = HeapAlloc(GetProcessHeap(), 0, size/sizeof(WCHAR)); WideCharToMultiByte(CP_ACP, 0, nameW, size/sizeof(WCHAR), nameA, size/sizeof(WCHAR), NULL, NULL); } HeapFree(GetProcessHeap(), 0, nameW); } else if (rc==MMSYSERR_NOTSUPPORTED) { nameA=HeapAlloc(GetProcessHeap(), 0, sizeof("not supported")); strcpy(nameA, "not supported"); } trace(" %s: \"%s\" (%s) %d.%d (%d:%d)\n",dev_name(device),capsA.szPname, (nameA?nameA:"failed"),capsA.vDriverVersion >> 8, capsA.vDriverVersion & 0xff,capsA.wMid,capsA.wPid); trace(" channels=%d formats=%05x\n", capsA.wChannels,capsA.dwFormats); HeapFree(GetProcessHeap(), 0, nameA); for (f=0;f<NB_WIN_FORMATS;f++) { format.wFormatTag=WAVE_FORMAT_PCM; format.nChannels=win_formats[f][3]; format.wBitsPerSample=win_formats[f][2]; format.nSamplesPerSec=win_formats[f][1]; format.nBlockAlign=format.nChannels*format.wBitsPerSample/8; format.nAvgBytesPerSec=format.nSamplesPerSec*format.nBlockAlign; format.cbSize=0; wave_in_test_deviceIn(device,&format,win_formats[f][0],0, &capsA); if (device != WAVE_MAPPER) { wave_in_test_deviceIn(device,&format,win_formats[f][0], WAVE_FORMAT_DIRECT, &capsA); wave_in_test_deviceIn(device,&format,win_formats[f][0], WAVE_MAPPED, &capsA); } } /* Try a PCMWAVEFORMAT aligned next to an unaccessible page for bounds * checking */ twoPages = VirtualAlloc(NULL, 2 * dwPageSize, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); ok(twoPages!=NULL,"Failed to allocate 2 pages of memory\n"); if (twoPages) { res = VirtualProtect(twoPages + dwPageSize, dwPageSize, PAGE_NOACCESS, &flOldProtect); ok(res, "Failed to set memory access on second page\n"); if (res) { LPWAVEFORMATEX pwfx = (LPWAVEFORMATEX)(twoPages + dwPageSize - sizeof(PCMWAVEFORMAT)); pwfx->wFormatTag=WAVE_FORMAT_PCM; pwfx->nChannels=1; pwfx->wBitsPerSample=8; pwfx->nSamplesPerSec=22050; pwfx->nBlockAlign=pwfx->nChannels*pwfx->wBitsPerSample/8; pwfx->nAvgBytesPerSec=pwfx->nSamplesPerSec*pwfx->nBlockAlign; wave_in_test_deviceIn(device,pwfx,WAVE_FORMAT_2M08,0, &capsA); if (device != WAVE_MAPPER) { wave_in_test_deviceIn(device,pwfx,WAVE_FORMAT_2M08, WAVE_FORMAT_DIRECT, &capsA); wave_in_test_deviceIn(device,pwfx,WAVE_FORMAT_2M08, WAVE_MAPPED, &capsA); } } VirtualFree(twoPages, 2 * dwPageSize, MEM_RELEASE); } /* test non PCM formats */ format.wFormatTag=WAVE_FORMAT_MULAW; format.nChannels=1; format.wBitsPerSample=8; format.nSamplesPerSec=8000; format.nBlockAlign=format.nChannels*format.wBitsPerSample/8; format.nAvgBytesPerSec=format.nSamplesPerSec*format.nBlockAlign; format.cbSize=0; rc=waveInOpen(&win,device,&format,0,0,CALLBACK_NULL|WAVE_FORMAT_DIRECT); ok(rc==MMSYSERR_NOERROR || rc==WAVERR_BADFORMAT || rc==MMSYSERR_INVALFLAG || rc==MMSYSERR_INVALPARAM, "waveInOpen(%s): returned: %s\n",dev_name(device),wave_in_error(rc)); if (rc==MMSYSERR_NOERROR) { waveInClose(win); wave_in_test_deviceIn(device,&format,0,0,&capsA); } else trace("waveInOpen(%s): WAVE_FORMAT_MULAW not supported\n", dev_name(device)); format.wFormatTag=WAVE_FORMAT_ADPCM; format.nChannels=2; format.wBitsPerSample=4; format.nSamplesPerSec=22050; format.nBlockAlign=format.nChannels*format.wBitsPerSample/8; format.nAvgBytesPerSec=format.nSamplesPerSec*format.nBlockAlign; format.cbSize=0; rc=waveInOpen(&win,device,&format,0,0,CALLBACK_NULL|WAVE_FORMAT_DIRECT); ok(rc==MMSYSERR_NOERROR || rc==WAVERR_BADFORMAT || rc==MMSYSERR_INVALFLAG || rc==MMSYSERR_INVALPARAM, "waveInOpen(%s): returned: %s\n",dev_name(device),wave_in_error(rc)); if (rc==MMSYSERR_NOERROR) { waveInClose(win); wave_in_test_deviceIn(device,&format,0,0,&capsA); } else trace("waveInOpen(%s): WAVE_FORMAT_ADPCM not supported\n", dev_name(device)); /* test if WAVEFORMATEXTENSIBLE supported */ wfex.Format.wFormatTag=WAVE_FORMAT_EXTENSIBLE; wfex.Format.nChannels=2; wfex.Format.wBitsPerSample=16; wfex.Format.nSamplesPerSec=22050; wfex.Format.nBlockAlign=wfex.Format.nChannels*wfex.Format.wBitsPerSample/8; wfex.Format.nAvgBytesPerSec=wfex.Format.nSamplesPerSec* wfex.Format.nBlockAlign; wfex.Format.cbSize=22; wfex.Samples.wValidBitsPerSample=wfex.Format.wBitsPerSample; wfex.dwChannelMask=SPEAKER_ALL; wfex.SubFormat=KSDATAFORMAT_SUBTYPE_PCM; rc=waveInOpen(&win,device,&wfex.Format,0,0, CALLBACK_NULL|WAVE_FORMAT_DIRECT); ok(rc==MMSYSERR_NOERROR || rc==WAVERR_BADFORMAT || rc==MMSYSERR_INVALFLAG || rc==MMSYSERR_INVALPARAM, "waveInOpen(%s): returned: %s\n",dev_name(device),wave_in_error(rc)); if (rc==MMSYSERR_NOERROR) { waveInClose(win); wave_in_test_deviceIn(device,&wfex.Format,0,0,&capsA); } else trace("waveInOpen(%s): WAVE_FORMAT_EXTENSIBLE not supported\n", dev_name(device)); /* test if 4 channels supported */ wfex.Format.wFormatTag=WAVE_FORMAT_EXTENSIBLE; wfex.Format.nChannels=4; wfex.Format.wBitsPerSample=16; wfex.Format.nSamplesPerSec=22050; wfex.Format.nBlockAlign=wfex.Format.nChannels*wfex.Format.wBitsPerSample/8; wfex.Format.nAvgBytesPerSec=wfex.Format.nSamplesPerSec* wfex.Format.nBlockAlign; wfex.Format.cbSize=22; wfex.Samples.wValidBitsPerSample=wfex.Format.wBitsPerSample; wfex.dwChannelMask=SPEAKER_ALL; wfex.SubFormat=KSDATAFORMAT_SUBTYPE_PCM; rc=waveInOpen(&win,device,&wfex.Format,0,0, CALLBACK_NULL|WAVE_FORMAT_DIRECT); ok(rc==MMSYSERR_NOERROR || rc==WAVERR_BADFORMAT || rc==MMSYSERR_INVALFLAG || rc==MMSYSERR_INVALPARAM, "waveInOpen(%s): returned: %s\n",dev_name(device),wave_in_error(rc)); if (rc==MMSYSERR_NOERROR) { waveInClose(win); wave_in_test_deviceIn(device,&wfex.Format,0,0,&capsA); } else trace("waveInOpen(%s): 4 channels not supported\n", dev_name(device)); /* test if 6 channels supported */ wfex.Format.wFormatTag=WAVE_FORMAT_EXTENSIBLE; wfex.Format.nChannels=6; wfex.Format.wBitsPerSample=16; wfex.Format.nSamplesPerSec=22050; wfex.Format.nBlockAlign=wfex.Format.nChannels*wfex.Format.wBitsPerSample/8; wfex.Format.nAvgBytesPerSec=wfex.Format.nSamplesPerSec* wfex.Format.nBlockAlign; wfex.Format.cbSize=22; wfex.Samples.wValidBitsPerSample=wfex.Format.wBitsPerSample; wfex.dwChannelMask=SPEAKER_ALL; wfex.SubFormat=KSDATAFORMAT_SUBTYPE_PCM; rc=waveInOpen(&win,device,&wfex.Format,0,0, CALLBACK_NULL|WAVE_FORMAT_DIRECT); ok(rc==MMSYSERR_NOERROR || rc==WAVERR_BADFORMAT || rc==MMSYSERR_INVALFLAG || rc==MMSYSERR_INVALPARAM, "waveInOpen(%s): returned: %s\n",dev_name(device),wave_in_error(rc)); if (rc==MMSYSERR_NOERROR) { waveInClose(win); wave_in_test_deviceIn(device,&wfex.Format,0,0,&capsA); } else trace("waveInOpen(%s): 6 channels not supported\n", dev_name(device)); if (0) { /* FIXME: ALSA doesn't like this */ /* test if 24 bit samples supported */ wfex.Format.wFormatTag=WAVE_FORMAT_EXTENSIBLE; wfex.Format.nChannels=2; wfex.Format.wBitsPerSample=24; wfex.Format.nSamplesPerSec=22050; wfex.Format.nBlockAlign=wfex.Format.nChannels*wfex.Format.wBitsPerSample/8; wfex.Format.nAvgBytesPerSec=wfex.Format.nSamplesPerSec* wfex.Format.nBlockAlign; wfex.Format.cbSize=22; wfex.Samples.wValidBitsPerSample=wfex.Format.wBitsPerSample; wfex.dwChannelMask=SPEAKER_ALL; wfex.SubFormat=KSDATAFORMAT_SUBTYPE_PCM; rc=waveInOpen(&win,device,&wfex.Format,0,0, CALLBACK_NULL|WAVE_FORMAT_DIRECT); ok(rc==MMSYSERR_NOERROR || rc==WAVERR_BADFORMAT || rc==MMSYSERR_INVALFLAG || rc==MMSYSERR_INVALPARAM, "waveInOpen(%s): returned: %s\n",dev_name(device),wave_in_error(rc)); if (rc==MMSYSERR_NOERROR) { waveInClose(win); wave_in_test_deviceIn(device,&wfex.Format,0,0,&capsA); } else trace("waveInOpen(%s): 24 bit samples not supported\n", dev_name(device)); } /* test if 32 bit samples supported */ wfex.Format.wFormatTag=WAVE_FORMAT_EXTENSIBLE; wfex.Format.nChannels=2; wfex.Format.wBitsPerSample=32; wfex.Format.nSamplesPerSec=22050; wfex.Format.nBlockAlign=wfex.Format.nChannels*wfex.Format.wBitsPerSample/8; wfex.Format.nAvgBytesPerSec=wfex.Format.nSamplesPerSec* wfex.Format.nBlockAlign; wfex.Format.cbSize=22; wfex.Samples.wValidBitsPerSample=wfex.Format.wBitsPerSample; wfex.dwChannelMask=SPEAKER_ALL; wfex.SubFormat=KSDATAFORMAT_SUBTYPE_PCM; rc=waveInOpen(&win,device,&wfex.Format,0,0, CALLBACK_NULL|WAVE_FORMAT_DIRECT); ok(rc==MMSYSERR_NOERROR || rc==WAVERR_BADFORMAT || rc==MMSYSERR_INVALFLAG || rc==MMSYSERR_INVALPARAM, "waveInOpen(%s): returned: %s\n",dev_name(device),wave_in_error(rc)); if (rc==MMSYSERR_NOERROR) { waveInClose(win); wave_in_test_deviceIn(device,&wfex.Format,0,0,&capsA); } else trace("waveInOpen(%s): 32 bit samples not supported\n", dev_name(device)); /* test if 32 bit float samples supported */ wfex.Format.wFormatTag=WAVE_FORMAT_EXTENSIBLE; wfex.Format.nChannels=2; wfex.Format.wBitsPerSample=32; wfex.Format.nSamplesPerSec=22050; wfex.Format.nBlockAlign=wfex.Format.nChannels*wfex.Format.wBitsPerSample/8; wfex.Format.nAvgBytesPerSec=wfex.Format.nSamplesPerSec* wfex.Format.nBlockAlign; wfex.Format.cbSize=22; wfex.Samples.wValidBitsPerSample=wfex.Format.wBitsPerSample; wfex.dwChannelMask=SPEAKER_ALL; wfex.SubFormat=KSDATAFORMAT_SUBTYPE_IEEE_FLOAT; rc=waveInOpen(&win,device,&wfex.Format,0,0, CALLBACK_NULL|WAVE_FORMAT_DIRECT); ok(rc==MMSYSERR_NOERROR || rc==WAVERR_BADFORMAT || rc==MMSYSERR_INVALFLAG || rc==MMSYSERR_INVALPARAM, "waveInOpen(%s): returned: %s\n",dev_name(device),wave_in_error(rc)); if (rc==MMSYSERR_NOERROR) { waveInClose(win); wave_in_test_deviceIn(device,&wfex.Format,0,0,&capsA); } else trace("waveInOpen(%s): 32 bit float samples not supported\n", dev_name(device)); }
int open_ep_mixers(px_mixer *Px, UINT deviceIn, UINT deviceOut) { PxEPInfo *info; IMMDeviceEnumerator *denum = NULL; IMMDevice *device = NULL; HRESULT hr; MMRESULT res; LPWSTR idStr; size_t idLen; if (!initialize(Px)) { goto fail; } info = (PxEPInfo *) Px->info; info->inputEP = NULL; info->outputEP = NULL; // Create an audio endpoint device enumerator. hr = CoCreateInstance(&CLSID_MMDeviceEnumerator, NULL, CLSCTX_ALL, &IID_IMMDeviceEnumerator, &denum); if (FAILED(hr)) { goto fail; } if (deviceIn == WAVE_MAPPER) { hr = IMMDeviceEnumerator_GetDefaultAudioEndpoint(denum, eCapture, eMultimedia, &device); if (SUCCEEDED(hr)) { hr = IMMDevice_Activate(device, &IID_IAudioEndpointVolume, CLSCTX_ALL, NULL, &info->inputEP); IUnknown_Release(device); } if (FAILED(hr)) { goto fail; } } else { res = waveInMessage((HWAVEIN)IntToPtr(deviceIn), DRV_QUERYFUNCTIONINSTANCEIDSIZE, (DWORD_PTR)&idLen, (DWORD_PTR)NULL); if (res != MMSYSERR_NOERROR) { goto fail; } idStr = (WCHAR *) CoTaskMemAlloc(idLen + sizeof(WCHAR)); if (idStr == NULL) { goto fail; } res = waveInMessage((HWAVEIN)IntToPtr(deviceIn), DRV_QUERYFUNCTIONINSTANCEID, (DWORD_PTR)idStr, (DWORD_PTR)idLen); if (res != MMSYSERR_NOERROR) { CoTaskMemFree(idStr); goto fail; } hr = IMMDeviceEnumerator_GetDevice(denum, idStr, &device); if (SUCCEEDED(hr)) { hr = IMMDevice_Activate(device, &IID_IAudioEndpointVolume, CLSCTX_ALL, NULL, &info->inputEP); IUnknown_Release(device); } CoTaskMemFree(idStr); if (FAILED(hr)) { goto fail; } } if (deviceOut == WAVE_MAPPER) { hr = IMMDeviceEnumerator_GetDefaultAudioEndpoint(denum, eRender, eMultimedia, &device); if (SUCCEEDED(hr)) { hr = IMMDevice_Activate(device, &IID_IAudioEndpointVolume, CLSCTX_ALL, NULL, &info->outputEP); IUnknown_Release(device); } if (FAILED(hr)) { goto fail; } } else { res = waveOutMessage((HWAVEOUT)IntToPtr(deviceOut), DRV_QUERYFUNCTIONINSTANCEIDSIZE, (DWORD_PTR)&idLen, (DWORD_PTR)NULL); if (res != MMSYSERR_NOERROR) { goto fail; } idStr = (WCHAR *) CoTaskMemAlloc(idLen + sizeof(WCHAR)); if (idStr == NULL) { goto fail; } res = waveOutMessage((HWAVEOUT)IntToPtr(deviceOut), DRV_QUERYFUNCTIONINSTANCEID, (DWORD_PTR)idStr, (DWORD_PTR)idLen); if (res != MMSYSERR_NOERROR) { CoTaskMemFree(idStr); goto fail; } hr = IMMDeviceEnumerator_GetDevice(denum, idStr, &device); if (SUCCEEDED(hr)) { hr = IMMDevice_Activate(device, &IID_IAudioEndpointVolume, CLSCTX_ALL, NULL, &info->outputEP); IUnknown_Release(device); } CoTaskMemFree(idStr); if (FAILED(hr)) { goto fail; } } if (denum) { IUnknown_Release(denum); } return TRUE; fail: if (denum) { IUnknown_Release(denum); } return cleanup(Px); }
BOOL FindWinMMDeviceIndex( LPFILTERINFO CurInfo, BOOL bRecord) { ULONG DeviceCount, Index; WCHAR Buffer[MAX_PATH]; DWORD Size, dwResult; if (bRecord) DeviceCount = waveInGetNumDevs(); else DeviceCount = waveOutGetNumDevs(); /* sanity check */ //ASSERT(DeviceCount); for(Index = 0; Index < DeviceCount; Index++) { Size = 0; /* query device interface size */ if (bRecord) dwResult = waveInMessage(UlongToHandle(Index), DRV_QUERYDEVICEINTERFACESIZE, (DWORD_PTR)&Size, 0); else dwResult = waveOutMessage(UlongToHandle(Index), DRV_QUERYDEVICEINTERFACESIZE, (DWORD_PTR)&Size, 0); if (dwResult != MMSYSERR_NOERROR) { DPRINT("Failed DRV_QUERYDEVICEINTERFACESIZE with %lx bRecord %u Index %u\n", dwResult, bRecord, Index); continue; } /* sanity check */ ASSERT(Size < MAX_PATH); /* now get the device interface string */ if (bRecord) dwResult = waveInMessage(UlongToHandle(Index), DRV_QUERYDEVICEINTERFACE, (DWORD_PTR)Buffer, MAX_PATH); else dwResult = waveOutMessage(UlongToHandle(Index), DRV_QUERYDEVICEINTERFACE, (DWORD_PTR)Buffer, MAX_PATH); if (dwResult != MMSYSERR_NOERROR) { DPRINT("Failed DRV_QUERYDEVICEINTERFACE with %lx bRecord %u Index %u\n", dwResult, bRecord, Index); continue; } if (!wcsicmp(CurInfo->DevicePath, Buffer)) { if (bRecord) CurInfo->MappedId[0] = Index; else CurInfo->MappedId[1] = Index; return TRUE; } } DPRINT1("Failed to find device %ws bRecord %u Count %u\n", CurInfo->DevicePath, bRecord, DeviceCount); // HACK if (bRecord) CurInfo->MappedId[0] = 0; else CurInfo->MappedId[1] = 0; return TRUE; }
/*************************************************************************** * DirectSoundCaptureEnumerateW [DSOUND.8] * * Enumerate all DirectSound drivers installed in the system. * * PARAMS * lpDSEnumCallback [I] Address of callback function. * lpContext [I] Address of user defined context passed to callback function. * * RETURNS * Success: DS_OK * Failure: DSERR_INVALIDPARAM */ HRESULT WINAPI DirectSoundCaptureEnumerateW( LPDSENUMCALLBACKW lpDSEnumCallback, LPVOID lpContext) { unsigned devs, wid; DSDRIVERDESC desc; GUID guid; int err; WCHAR wDesc[MAXPNAMELEN]; WCHAR wName[MAXPNAMELEN]; TRACE("(%p,%p)\n", lpDSEnumCallback, lpContext ); if (lpDSEnumCallback == NULL) { WARN("invalid parameter: lpDSEnumCallback == NULL\n"); return DSERR_INVALIDPARAM; } setup_dsound_options(); devs = waveInGetNumDevs(); if (devs > 0) { if (GetDeviceID(&DSDEVID_DefaultCapture, &guid) == DS_OK) { for (wid = 0; wid < devs; ++wid) { if (IsEqualGUID( &guid, &DSOUND_capture_guids[wid] ) ) { err = mmErr(waveInMessage(UlongToHandle(wid),DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,ds_hw_accel)); if (err == DS_OK) { TRACE("calling lpDSEnumCallback(NULL,\"%s\",\"%s\",%p)\n", "Primary Sound Capture Driver",desc.szDrvname,lpContext); MultiByteToWideChar( CP_ACP, 0, "Primary Sound Capture Driver", -1, wDesc, sizeof(wDesc)/sizeof(WCHAR) ); MultiByteToWideChar( CP_ACP, 0, desc.szDrvname, -1, wName, sizeof(wName)/sizeof(WCHAR) ); wName[(sizeof(wName)/sizeof(WCHAR)) - 1] = '\0'; if (lpDSEnumCallback(NULL, wDesc, wName, lpContext) == FALSE) return DS_OK; } } } } } for (wid = 0; wid < devs; ++wid) { err = mmErr(waveInMessage(UlongToHandle(wid),DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,ds_hw_accel)); if (err == DS_OK) { TRACE("calling lpDSEnumCallback(%s,\"%s\",\"%s\",%p)\n", debugstr_guid(&DSOUND_capture_guids[wid]),desc.szDesc,desc.szDrvname,lpContext); MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1, wDesc, sizeof(wDesc)/sizeof(WCHAR) ); wDesc[(sizeof(wDesc)/sizeof(WCHAR)) - 1] = '\0'; MultiByteToWideChar( CP_ACP, 0, desc.szDrvname, -1, wName, sizeof(wName)/sizeof(WCHAR) ); wName[(sizeof(wName)/sizeof(WCHAR)) - 1] = '\0'; if (lpDSEnumCallback(&DSOUND_capture_guids[wid], wDesc, wName, lpContext) == FALSE) return DS_OK; } } return DS_OK; }
static HRESULT DSPROPERTY_DescriptionW( LPVOID pPropData, ULONG cbPropData, PULONG pcbReturned ) { PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA ppd = pPropData; HRESULT err; GUID dev_guid; ULONG wod, wid, wodn, widn; DSDRIVERDESC desc; TRACE("pPropData=%p,cbPropData=%d,pcbReturned=%p)\n", pPropData,cbPropData,pcbReturned); TRACE("DeviceId=%s\n",debugstr_guid(&ppd->DeviceId)); if ( IsEqualGUID( &ppd->DeviceId , &GUID_NULL) ) { /* default device of type specified by ppd->DataFlow */ if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE) { TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE\n"); ppd->DeviceId = DSDEVID_DefaultCapture; } else if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_RENDER) { TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_RENDER\n"); ppd->DeviceId = DSDEVID_DefaultPlayback; } else { WARN("DataFlow=Unknown(%d)\n", ppd->DataFlow); return E_PROP_ID_UNSUPPORTED; } } setup_dsound_options(); GetDeviceID(&ppd->DeviceId, &dev_guid); wodn = waveOutGetNumDevs(); widn = waveInGetNumDevs(); wid = wod = dev_guid.Data4[7]; if (!memcmp(&dev_guid, &DSOUND_renderer_guids[0], sizeof(GUID)-1) && wod < wodn) { ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_RENDER; ppd->WaveDeviceId = wod; } else if (!memcmp(&dev_guid, &DSOUND_capture_guids[0], sizeof(GUID)-1) && wid < widn) { ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE; ppd->WaveDeviceId = wid; } else { WARN("Device not found\n"); return E_PROP_ID_UNSUPPORTED; } if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_RENDER) err = waveOutMessage(UlongToHandle(wod),DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,ds_hw_accel); else err = waveInMessage(UlongToHandle(wod),DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,ds_hw_accel); if (err != MMSYSERR_NOERROR) { WARN("waveMessage(DRV_QUERYDSOUNDDESC) failed!\n"); return E_PROP_ID_UNSUPPORTED; } else { /* FIXME: Still a memory leak.. */ int desclen, modlen; static WCHAR wInterface[] = { 'I','n','t','e','r','f','a','c','e',0 }; modlen = MultiByteToWideChar( CP_ACP, 0, desc.szDrvname, -1, NULL, 0 ); desclen = MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1, NULL, 0 ); ppd->Module = HeapAlloc(GetProcessHeap(),0,modlen*sizeof(WCHAR)); ppd->Description = HeapAlloc(GetProcessHeap(),0,desclen*sizeof(WCHAR)); ppd->Interface = wInterface; if (!ppd->Description || !ppd->Module) { WARN("Out of memory\n"); HeapFree(GetProcessHeap(), 0, ppd->Description); HeapFree(GetProcessHeap(), 0, ppd->Module); ppd->Description = ppd->Module = NULL; return E_OUTOFMEMORY; } MultiByteToWideChar( CP_ACP, 0, desc.szDrvname, -1, ppd->Module, modlen ); MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1, ppd->Description, desclen ); } ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD; if (pcbReturned) { *pcbReturned = sizeof(*ppd); TRACE("*pcbReturned=%d\n", *pcbReturned); } return S_OK; }
HRESULT WINAPI GetDeviceID(LPCGUID pGuidSrc, LPGUID pGuidDest) { ULONG DeviceID = ULONG_MAX, Flags; MMRESULT Result; LPFILTERINFO Filter; if (!pGuidSrc || !pGuidDest) { /* invalid param */ return DSERR_INVALIDPARAM; } /* sanity check */ ASSERT(!IsEqualGUID(pGuidSrc, &GUID_NULL)); if (IsEqualGUID(&DSDEVID_DefaultPlayback, pGuidSrc) || IsEqualGUID(&DSDEVID_DefaultVoicePlayback, pGuidSrc)) { Result = waveOutMessage(UlongToHandle(WAVE_MAPPER), DRVM_MAPPER_PREFERRED_GET, (DWORD_PTR)&DeviceID, (DWORD_PTR)&Flags); if (Result != MMSYSERR_NOERROR || DeviceID == ULONG_MAX) { /* hack */ DPRINT1("Failed to get DRVM_MAPPER_PREFERRED_GET, using device 0\n"); DeviceID = 0; } if (!FindDeviceByMappedId(DeviceID, &Filter, TRUE)) { /* device not found */ return DSERR_INVALIDPARAM; } /* copy device guid */ RtlMoveMemory(pGuidDest, &Filter->DeviceGuid[1], sizeof(GUID)); return DS_OK; } else if (IsEqualGUID(&DSDEVID_DefaultCapture, pGuidSrc) || IsEqualGUID(&DSDEVID_DefaultVoiceCapture, pGuidSrc)) { Result = waveInMessage(UlongToHandle(WAVE_MAPPER), DRVM_MAPPER_PREFERRED_GET, (DWORD_PTR)&DeviceID, (DWORD_PTR)&Flags); if (Result != MMSYSERR_NOERROR || DeviceID == ULONG_MAX) { /* hack */ DPRINT1("Failed to get DRVM_MAPPER_PREFERRED_GET, for record using device 0\n"); DeviceID = 0; } if (!FindDeviceByMappedId(DeviceID, &Filter, FALSE)) { /* device not found */ return DSERR_INVALIDPARAM; } /* copy device guid */ RtlMoveMemory(pGuidDest, &Filter->DeviceGuid[0], sizeof(GUID)); return DS_OK; } if (!FindDeviceByGuid(pGuidSrc, &Filter)) { /* unknown guid */ return DSERR_INVALIDPARAM; } /* done */ return DS_OK; }