C++音量合成器に音量を適用する


まず、スピーカの音量を取得し、スピーカの音量と設定する必要がある音量に基づいて音量値を計算します(例えば、スピーカ50%、現在のプログラムの音量50%を設定する必要がありますので、最終的に音量合成器の数値は50%*50%=25%)
次に、他のプログラムのサイレントを設定し、サイレントを設定する前にボリューム値を保存して現在のプログラムのボリュームを設定する必要があります.
最後に、音声を再生した後、他のプログラムの音量を復元し、このときは第2ステップで保存した音量値を使用します.以下に各ステップコードを示し、以下のコードは本人が有効である.
//        
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);
				}
			}
		}
	}
}