Core Audio APIs (Win Vista , Win7) 获取一个指定设备的音量

MSDN 关于 Core Audio APIs 的索引:

This guide section explains the concepts and features of the core audio APIs of Windows Vista, and describes how to use them in application programming.

This section contains the following topics.

Topic
Description

User-Mode Audio Components
Through the low-level interfaces in the core audio APIs, a client can access the system components that manage and mix audio streams.

Protected User Mode Audio (PUMA)
Describes the updates to Protected User Mode Audio (PUMA), the user-mode audio engine in the Protected Environment (PE), which provides a safer environment for audio processing and rendering.

Audio Endpoint Devices
An audio endpoint device is a software abstraction that enables user-friendly interactions with audio devices such as microphones and speakers.

Audio Sessions
An audio session is a software abstraction that enables a client to manage a collection of related audio streams as a single unit.

Volume Controls
The system integrates its policy-based volume settings with the user's volume settings in a logical and consistent way.

Stream Management
The Windows Audio Session API (WASAPI) provides a client with a complete set of methods for creating and managing audio streams.

Device Topologies
The DeviceTopology API enables a client to discover the audio controls that lie along the various data paths in the audio hardware.

Using the IKsControl Interface to Access Audio Properties
A specialized audio application might need to use the IKsControl interface to access the properties of an audio adapter.

Interoperability with Legacy Audio APIs
Key features of the core audio APIs in Windows Vista can be incorporated into existing applications that use DirectSound, DirectShow, and the Windows multimedia waveOutXxx and waveInXxx functions.

 

用一张图来了解下 Core Audio APIs 各接口之间的关系

Dd316780_fig1(en-us,VS_85)

 

 

#include "stdafx.h"
#include "mmdeviceapi.h"
#include "Endpointvolume.h"
//#include "Audioclient.h"
//#include "Audiopolicy.h"


#define SAFE_RELEASE(punk)  \
              if ((punk) != NULL)  \
                { (punk)->Release(); (punk) = NULL; }

//得到设备硬件ID (设备管理器可以看到的硬件ID)
bool GetDeviceDsc(IMMDevice *pDevice,wchar_t* DeviceDsc)  
{
    HRESULT hr;
    IPropertyStore *pStore;
    hr = pDevice->OpenPropertyStore(STGM_READ, &pStore);
    if (SUCCEEDED(hr))
    {
        PROPERTYKEY Drvidkey ={0xb3f8fa53, 0x0004, 0x438e, 0x90, 0x03, 0x51, 0xa4, 0x6e, 0x13, 0x9b, 0xfc, 2};
        PROPVARIANT pDrvidkey;
        PropVariantInit(&pDrvidkey);
        hr = pStore->GetValue(Drvidkey , &pDrvidkey);  
        if (SUCCEEDED(hr))
        {
            wcscpy(DeviceDsc,pDrvidkey.pwszVal);
            PropVariantClear(&pDrvidkey);
            pStore->Release();
            return true;
        }
        pStore->Release();
    }
    return false;
}

// 验证设备是否指定设备
bool VerifyDev(IMMDevice *pDevice,EDataFlow dataFlow)
{
    wchar_t DeviceDsc[255]; 
    if (GetDeviceDsc(pDevice,DeviceDsc)) 
    {
        // 这里省略判断具体设备的 匹配硬件 如 HDAUDIO\FUNC_01&VEN_10EC&DEV_0888&SUBSYS_14627514&REV_1000
        return true;
    }
    return false;
}

// 获取设备音量
int GetDevicePlayVol(void)
{   
    IMMDeviceEnumerator* pEnumerator;  
    IMMDeviceCollection* pCollection = NULL;  
    IMMDevice *pDevice = NULL;  
    IAudioEndpointVolume *pVolumeAPI=NULL;    
    UINT deviceCount = 0;  
    HRESULT hr;
    float fVolume = -1;  
    
    CoInitializeEx( NULL , COINIT_MULTITHREADED );  
    //实例化 MMDeviceEnumerator 枚举器
    hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL,CLSCTX_ALL, __uuidof(IMMDeviceEnumerator),(void**)&pEnumerator);  
    if (hr != S_OK)    
    {    
        goto FreeEnumerator;
    }    
    // 枚举 设备到设备容器 eRander:放音设备,DEVICE_STATE_ACTIVE 为当前已激活的设备,禁用和无连接的用其他状态参数
    hr = pEnumerator->EnumAudioEndpoints( eRender , DEVICE_STATE_ACTIVE , &pCollection );  
    if (hr != S_OK)    
    {       
        goto FreeCollection; 
    }    
    // 设备容器里的总数
    hr = pCollection->GetCount(&deviceCount);    
    if (hr != S_OK)    
    {    
        goto FreeCollection;
    }    

    for (UINT dev=0; dev<deviceCount; dev++)    
    {    
        pDevice = NULL;    
        hr = pCollection->Item(dev,&pDevice);    
        if (hr == S_OK)    
        {
            if (VerifyDev(pDevice,eRender)) 
            {    // 用 pDevice 的 Activate 方法初始一个 IAudioEndpointVolume 接口
                hr = pDevice->Activate(__uuidof(IAudioEndpointVolume),CLSCTX_ALL,NULL,(void **)(&pVolumeAPI));    
                // 使用 IAudioEndpintVolume 的方法获取音量,设置音量,设置静音等 
                hr = pVolumeAPI->GetMasterVolumeLevelScalar(&fVolume);
                break;
            }
        }    
    }  

FreeCollection:
    SAFE_RELEASE(pCollection);
FreeEnumerator:
    SAFE_RELEASE(pEnumerator);
    CoUninitialize();
    if (fVolume > 0) 
      return fVolume*100; 
    else
      return fVolume;
}

posted on 2011-12-13 23:54  zhongtaifeng  阅读(1048)  评论(0编辑  收藏  举报

导航