windows自从vista后有了一套新的关于操作底层音频的API即Core Audio APIS.通过对这个机制的研究,自己简单写个关于对Windows系统音量的控制,这里包括如何监听系统音量变化、改变系统的音量以及如何设置与解除静音。
具体的源码如下:
/*******************导入的头文件*********************/
#include <stdio.h>
#include <tchar.h>
#include <windows.h>
#include <mmdeviceapi.h>
#include <endpointvolume.h>
#include <Tchar.h>
#include <functiondiscoverykeys.h>
#include <strsafe.h>
/********需要实现监听系统音量变化接口IAudioEndpointVolumeCallback**********/
///
///实现对系统音量的监听必须重现实现音量回调接口IAudioEndpointVolumeCallback
///主要实现接口IAudioEndpointVolumeCallback监听系统音量的函数是OnNotify
///
class CVolumeNotification : public IAudioEndpointVolumeCallback
{
LONG m_RefCount;
~CVolumeNotification(void) {};
public:
CVolumeNotification() : m_RefCount(1)
{
}
//实现IAudioEndpointVolumeCallback接口的AddRef的函数
STDMETHODIMP_(ULONG)AddRef() {
return InterlockedIncrement(&m_RefCount);
}
//实现IAudioEndpointVolumeCallback接口的Release函数
STDMETHODIMP_(ULONG)Release()
{
LONG ref = InterlockedDecrement(&m_RefCount);
if (ref == 0)
delete this;
return ref;
}
//实现IAudioEndpointVolumeCallback接口的QueryInterface函数
STDMETHODIMP QueryInterface(REFIID IID, void **ReturnValue)
{
if (IID == IID_IUnknown || IID== __uuidof(IAudioEndpointVolumeCallback))
{
*ReturnValue = static_cast<IUnknown*>(this);
AddRef();
return S_OK;
}
*ReturnValue = NULL;
return E_NOINTERFACE;
}
///实现IAudioEndpointVolumeCallback接口的通知函数OnNotify
///OnNotify函数不断监听系统音量的变化
STDMETHODIMP OnNotify(PAUDIO_VOLUME_NOTIFICATION_DATA NotificationData)
{
//NotificationData->fMasterVolume
UINT volume = (UINT)((NotificationData->fMasterVolume)*100);
printf_s("volume: %d \n", volume); //打印不断变化的系统的音量
return S_OK;
}
};
/*******************类VolumeListener实现对系统音量的控制*********************/
class VolumeListener
{
public:
static VolumeListener* getInstance();
//初始化工作
bool initVolumeListener();
//清理工作
void clearVolumeListener();
//注册对系统音量的监听
bool RegisterEndpointNotification();
//设置系统音量到最大
void setMaxVolume();
//设置系统音量到最小
void setMinVolume();
//调大音量
void setVolumeUp();
//调小音量
void setVolumeDown();
//设置静音 参数isMute为true表示静音 false解除静音
void setMute(bool isMute);
//获取当前系统音量
UINT getCurrentVloume();
protected:
VolumeListener();
private:
//该类实现单例模式
static VolumeListener* listener;
//控制系统音量和静音的接口IAudioEndpointVolume
IAudioEndpointVolume *endpointVolume;
//监听系统音量变化的回调类变量
CVolumeNotification *volumeNotification;
};
//静态成员
VolumeListener* VolumeListener::listener = NULL;
//单例模式
VolumeListener* VolumeListener::getInstance()
{
if(listener == NULL)
{
listener = new VolumeListener();
}
return listener;
}
//构造器
VolumeListener::VolumeListener():endpointVolume(NULL), volumeNotification(NULL)
{
}
//初始化工作
bool VolumeListener::initVolumeListener()
{
CoInitialize(NULL);
HRESULT hr;
IMMDevice *defaultDevice = NULL;
IMMDeviceEnumerator *deviceEnumerator = NULL;
//Instantiate an endpoint volume object.
hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_INPROC_SERVER, __uuidof(IMMDeviceEnumerator), (LPVOID *)&deviceEnumerator);
if(hr != S_OK)
{
printf_s("Instantiate an endpoint volume object error\n");
return false;
}
//eRender 输出音频设备(放声) eCapture输入音频设备(录声)
hr = deviceEnumerator->GetDefaultAudioEndpoint(eRender, eConsole, &defaultDevice);
if(hr != S_OK)
{
printf_s("GetDefaultAudioEndpoint error\n");
return false;
}
//CVolumeNotification *volumeNotification = new CVolumeNotification();
hr = defaultDevice->Activate(__uuidof(IAudioEndpointVolume), CLSCTX_INPROC_SERVER, NULL, (LPVOID *)&endpointVolume);
if(hr != S_OK)
{
printf_s("get IAudioEndpointVolume error\n");
return false;
}
return true;
}
//清理工作
void VolumeListener::clearVolumeListener()
{
if(endpointVolume)
{
if(volumeNotification){
endpointVolume->UnregisterControlChangeNotify(volumeNotification);
volumeNotification->Release();
}
endpointVolume->Release();
}
CoUninitialize();
if(listener)
delete listener;
listener = NULL;
}
//注册对系统音量的监听
bool VolumeListener::RegisterEndpointNotification()
{
HRESULT hr;
if(endpointVolume)
{
volumeNotification = new CVolumeNotification();
hr = endpointVolume->RegisterControlChangeNotify(volumeNotification);
if(hr != S_OK)
{
printf_s("RegisterEndpointNotification error\n");
return false;
}
}
return true;
}
//设置系统音量到最大
void VolumeListener::setMaxVolume()
{
UINT currentStep, stepCount;
if(endpointVolume)
{
endpointVolume->GetVolumeStepInfo(¤tStep, &stepCount);
this->setMute(false);
for(UINT index = currentStep; index < stepCount; index++)
{
setVolumeUp();
}
}
}
//设置系统音量到最小
void VolumeListener::setMinVolume()
{
UINT currentStep, stepCount;
if(endpointVolume)
{
endpointVolume->GetVolumeStepInfo(¤tStep, &stepCount);
endpointVolume->SetMute(FALSE, NULL);
for(UINT index = currentStep; index > 0; index--)
{
setVolumeDown();
}
}
}
//调大音量
void VolumeListener::setVolumeUp()
{
if(endpointVolume)
{
endpointVolume->VolumeStepUp(NULL);
}
}
//调小音量
void VolumeListener::setVolumeDown()
{
if(endpointVolume)
{
endpointVolume->VolumeStepDown(NULL);
}
}
//设置静音 参数isMute为true表示静音 false解除静音
void VolumeListener::setMute(bool isMute)
{
if(endpointVolume)
{
if(isMute)
endpointVolume->SetMute(TRUE, NULL); //静音
else
endpointVolume->SetMute(FALSE, NULL); //解除静音
}
}
//获取当前系统音量
UINT VolumeListener::getCurrentVloume()
{
UINT currentStep, stepCount, currentVolume;
currentVolume = 0;
if(endpointVolume)
{
endpointVolume->GetVolumeStepInfo(¤tStep, &stepCount);
currentVolume = (UINT)((currentStep*1.0 / stepCount)*100);
}
return currentVolume;
}