C++设置音量合成器应用音量

先说一下大概思路,然后再贴出代码:
首先,获取扬声器音量,根据扬声器音量和需要设置的音量计算一个音量值(例如,扬声器50%,需要设置当前程序音量为50%,所以最终设置音量合成器中的数值为50% * 50% = 25%)

然后,设置其他程序静音,在设置静音之前需要保存音量值
设置当前程序音量

最后,在播放完声音之后,还原其他程序音量,这个时候要用到第二步保存的音量值。
下面给出每个步骤代码,以下代码本人亲测有效

// 获取扬声器音量
void GetSpeakerAudio()
{
	 CComPtr<IMMDeviceEnumerator> pIMMEnumerator = NULL;
	 CComPtr<IMMDevice> pIMMDeivce = NULL;
	 CComPtr<IAudioEndpointVolume> pIAudioEndpointVolume = NULL;

	 HRESULT hr = S_OK;
	 hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_INPROC_SERVER, __uuidof(IMMDeviceEnumerator), (void**)&pIMMEnumerator);
	 if(SUCCEEDED(hr))
	 {
		 hr = pIMMEnumerator->GetDefaultAudioEndpoint(eRender, eConsole, &pIMMDeivce);
		 if(SUCCEEDED(hr))
		 {
			 hr = pIMMDeivce->Activate(__uuidof(IAudioEndpointVolume), CLSCTX_ALL, NULL, (void**)&pIAudioEndpointVolume);
			 if(SUCCEEDED(hr))
			 {
				 hr = pIAudioEndpointVolume->GetMasterVolumeLevelScalar(&m_fVolum);
			 }
		 }
	 }
}

//dwVolume:可以忽略,IsRecover:true恢复其他程序音量,false是设置当前程序音量
BOOL SetCurrentProcessVolume(DWORD dwVolume,BOOL IsRecover)  
{  
	if(!IsRecover)
		m_mapAppVolum.clear();

	HRESULT hr = S_OK;  
	IMMDeviceCollection *pMultiDevice       = NULL;  
	IMMDevice *pDevice              = NULL;  
	IAudioSessionEnumerator *pSessionEnum       = NULL;  
	IAudioSessionManager2 *pASManager       = NULL;  
	IMMDeviceEnumerator *m_pEnumerator      = NULL;  
	const IID IID_ISimpleAudioVolume        = __uuidof(ISimpleAudioVolume);  
	const IID IID_IAudioSessionControl2     = __uuidof(IAudioSessionControl2);  
	GUID m_guidMyContext;
	CoInitialize(NULL);  
	hr = CoCreateGuid(&m_guidMyContext);  
	if(FAILED(hr))  
		return FALSE;  
	// Get enumerator for audio endpoint devices.  
	hr = CoCreateInstance(__uuidof(MMDeviceEnumerator),  
		NULL, CLSCTX_ALL,  
		__uuidof(IMMDeviceEnumerator),  
		(void**)&m_pEnumerator);  
	if(FAILED(hr))  
		return FALSE;  

	/*if (IsMixer)  
	{  
		hr = m_pEnumerator->EnumAudioEndpoints(eRender,DEVICE_STATE_ACTIVE, &pMultiDevice);  
	}   
	else  
	{  
		hr = m_pEnumerator->EnumAudioEndpoints(eCapture,DEVICE_STATE_ACTIVE, &pMultiDevice);  
	} */ 
	hr = m_pEnumerator->EnumAudioEndpoints(eRender,DEVICE_STATE_ACTIVE, &pMultiDevice);  
	if(FAILED(hr))  
		return FALSE; 

	UINT deviceCount = 0;  
	hr = pMultiDevice->GetCount(&deviceCount);        
	if(FAILED(hr))  
		return FALSE;    

	if((int)dwVolume < 0)  
		dwVolume = 0;  
	if((int)dwVolume > 100)  
		dwVolume = 100;  
	for (UINT ii=0; ii<deviceCount; ii++)  
	{  
		pDevice = NULL;        
		hr = pMultiDevice->Item(ii,&pDevice);      
		if(FAILED(hr))  
			return FALSE;   
		hr = pDevice->Activate(__uuidof(IAudioSessionManager),CLSCTX_ALL, NULL,(void**)&pASManager);  

		if(FAILED(hr))  
			return FALSE;   
		hr = pASManager->GetSessionEnumerator(&pSessionEnum);  
		if(FAILED(hr))  
			return FALSE;   
		int nCount;  
		hr = pSessionEnum->GetCount(&nCount);  
		for (int i = 0; i < nCount; i++)   
		{  
			IAudioSessionControl *pSessionCtrl;  
			hr = pSessionEnum->GetSession(i, &pSessionCtrl);  
			if (FAILED(hr))   
				continue;  
			IAudioSessionControl2 *pSessionCtrl2;  
			hr = pSessionCtrl->QueryInterface(IID_IAudioSessionControl2, (void **)&pSessionCtrl2);  
			if(FAILED(hr))  
				continue;  
			ULONG pid;  
			hr = pSessionCtrl2->GetProcessId(&pid);  
			if (FAILED(hr))  
				continue;  

			ISimpleAudioVolume *pSimplevol;  
			hr = pSessionCtrl2->QueryInterface(IID_ISimpleAudioVolume, (void **)&pSimplevol);  
			if (FAILED(hr))   
				continue;
			ULONG currentId = GetCurrentProcessId();
			if (pid == currentId)  
			{                 
				//pSimplevol->SetMasterVolume((float)dwVolume/100, NULL);  
			}  
			else  
			{  
				if(IsRecover)
				{
					auto iter = m_mapAppVolum.find(currentId);
					if(iter != m_mapAppVolum.end())
					{
						pSimplevol->SetMasterVolume(iter->second,NULL);
					}
				}
				else
				{
					float fLevel;
					pSimplevol->GetMasterVolume(&fLevel);
					m_mapAppVolum.insert(make_pair(currentId, fLevel));
					pSimplevol->SetMasterVolume((float)0/100, NULL); 
				}
			}  

		}         
	}    
	m_pEnumerator->Release();
	return TRUE;  
} 
//设置当前程序音量
void SetApplicationVolume(int size)
{
	CComPtr<IMMDeviceEnumerator >	pIMMEnumerator = NULL;	//主要用于枚举设备接口
	CComPtr<ISimpleAudioVolume>	pRenderSimpleVol = NULL;	//扬声器的会话音量控制接口
	HRESULT hr = S_OK;
	hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_INPROC_SERVER, __uuidof(IMMDeviceEnumerator), (void**)&pIMMEnumerator); 
	if(SUCCEEDED(hr))
	{
		CComPtr<IMMDevice> pIMMDeivce = NULL;
		hr = pIMMEnumerator->GetDefaultAudioEndpoint(eRender,eConsole,&pIMMDeivce);
		if(SUCCEEDED(hr))
		{
			CComPtr<IAudioSessionManager> pSessionManager = NULL;
			hr = pIMMDeivce->Activate(__uuidof(IAudioSessionManager), CLSCTX_INPROC_SERVER, NULL, (void **)(&pSessionManager));
			if(SUCCEEDED(hr))
			{
				hr = pSessionManager->GetSimpleAudioVolume(NULL, FALSE, &pRenderSimpleVol);
				if(SUCCEEDED(hr))
				{
					float fLevel = (float)size/100;
					fLevel += 0.000001;
					if(fLevel >= 1.000)
						fLevel = 1.000;
					hr = pRenderSimpleVol->SetMasterVolume(fLevel, NULL);
				}
			}
		}
	}
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值