0

我有一个代码可以枚举系统上的所有音频端点,但我不知道如何找到哪个端点是默认端点。

 int _tmain(int argc, _TCHAR* argv[])
 {

    HRESULT hr = S_OK;
    IMMDeviceEnumerator *pEnumerator = NULL;
    IMMDeviceCollection *pCollection = NULL;
    IMMDevice *pEndpoint = NULL;
    IPropertyStore *pProps = NULL;
    LPWSTR pwszID = NULL;

     system("pause");


    CoInitialize(NULL);

    hr = CoCreateInstance(
        CLSID_MMDeviceEnumerator, NULL,
        CLSCTX_ALL, IID_IMMDeviceEnumerator,
        (void**) &pEnumerator);
    EXIT_ON_ERROR(hr)

    hr = pEnumerator->EnumAudioEndpoints(
    eRender, DEVICE_STATE_ACTIVE,
    &pCollection);
    EXIT_ON_ERROR(hr)

    UINT  count;
    hr = pCollection->GetCount(&count);
    EXIT_ON_ERROR(hr)

    if (count == 0)
    {
        printf("No endpoints found.\n");
    }

    // Each loop prints the name of an endpoint device.
    for (ULONG i = 0; i < count; i++)
    {
        // Get pointer to endpoint number i.
        hr = pCollection->Item(i, &pEndpoint);
        EXIT_ON_ERROR(hr)

            // Get the endpoint ID string.
            hr = pEndpoint->GetId(&pwszID);
        EXIT_ON_ERROR(hr)

            hr = pEndpoint->OpenPropertyStore(
            STGM_READ, &pProps);
        EXIT_ON_ERROR(hr)

            PROPVARIANT varName;
        // Initialize container for property value.
        PropVariantInit(&varName);

        // Get the endpoint's friendly-name property.
        hr = pProps->GetValue(
            PKEY_Device_FriendlyName, &varName);
        EXIT_ON_ERROR(hr)

        hr = pProps->GetValue(PKEY_Device_DeviceDesc, &varName );
        EXIT_ON_ERROR(hr)

        // Print endpoint friendly name and endpoint ID.
        printf("Endpoint %d: \"%S\" (%S)\n",i, varName.pwszVal, pwszID);
        //printf("Endpoint %d: \"%S\" (%S)\n",i, varName.pwszVal, pwszID);

        CoTaskMemFree(pwszID);
        pwszID = NULL;
        PropVariantClear(&varName);
        SAFE_RELEASE(pProps)
        SAFE_RELEASE(pEndpoint)
    }
    SAFE_RELEASE(pEnumerator)
        SAFE_RELEASE(pCollection)

        system("pause");
        return 0;

Exit:
    printf("Error!\n");
    CoTaskMemFree(pwszID);
    SAFE_RELEASE(pEnumerator)
        SAFE_RELEASE(pCollection)
        SAFE_RELEASE(pEndpoint)
        SAFE_RELEASE(pProps)


 }
4

2 回答 2

1

首先,您应该获得默认驱动程序:

使用 C#

const uint DRVM_MAPPER_PREFERRED_GET = 0x2015;
const uint DRVM_MAPPER_PREFERRED_SET = 0x2016;

uint ret = waveOutMessage(
    WAVE_MAPPER, 
    DRVM_MAPPER_PREFERRED_GET, 
    ref defaultDeviceId, 
    ref param1);

所以defaultDeviceId变量将包含正确的索引,然后你应该从系统查询defaultdriverNamewaveOutGetDevCapsLPWAVEOUTCAPS包含一个有效的szPname成员。

最后,您应该将其string(szPname)PKEY_Device_FriendlyName财产价值进行比较:

使用 C++

PROPVARIANT friendlyName;
PropVariantInit(&friendlyName);
hr = propertyStore->GetValue(PKEY_Device_FriendlyName, &friendlyName);
bstr_friendlyName = ::SysAllocString(friendlyName.pwszVal);

if (NULL != wcsstr(friendlyName.pwszVal, woc.szPname))//WAVEOUTCAPS szPname
    //def device
于 2014-06-26T18:52:15.633 回答
-1
                uint ret = waveOutMessage(WAVE_MAPPER, DRVM_MAPPER_PREFERRED_GET, ref defaultDeviceId, ref param1);
                if (ret == MMSYSERR_NOERROR)
                {
                    int waveOutDevicesCount = waveOutGetNumDevs(); //get total
                    if (waveOutDevicesCount > defaultDeviceId)
                    {
                        WaveOutCaps waveOutCaps = new WaveOutCaps();
                        waveOutGetDevCapsA((int)defaultDeviceId, ref waveOutCaps,
                                                    Marshal.SizeOf(typeof(WaveOutCaps)));
                        string defaultDeviceName = (new string(waveOutCaps.szPname).Remove(
                                          new string(waveOutCaps.szPname).IndexOf('\0')).Trim());
于 2014-06-26T17:52:27.960 回答