Trouble accessing an my DefaultAudioEndpoint.

OPN_Analysis 41 Reputation points
2023-01-08T17:39:29.877+00:00

I'm trying to use WASAPI to sort of make my own volume mixer. Right now I'm trying to start off simple with a main audio mute/unmute & volume control through ISimpleAudioVolume. However, the IMMDevice that I'm accessing doesn't appear to be a real rendering stream because when I set mute, my volume doesn't change. I've also tried to access the display name of the session through IAudioSessionControl and it's NULL. I think my issue is in either CoInitializeEx or CoCreateInstance, as I can't quite tell what they're doing from the docs I was reading.

If this isn't the right forum for this question please let me know. Any help is appreciated. Thanks!

From MainVolumeControl.cpp:

void MainVolumeControl::init()  
{  
     // Get Device  
     //check(CoInitialize(NULL));  
     check(CoInitializeEx(NULL, COINIT_SPEED_OVER_MEMORY));  
     check(CoCreateInstance(__uuidof(MMDeviceEnumerator), nullptr, CLSCTX_INPROC_SERVER, __uuidof(IMMDeviceEnumerator), (LPVOID*)&m_deviceEnumerator));  
     check(m_deviceEnumerator->GetDefaultAudioEndpoint(eRender, eConsole, &m_device));  
  
 check(m_deviceEnumerator->EnumAudioEndpoints(eRender, DEVICE_STATE_ACTIVE, &m_deviceCollection));  
  
 UINT count;  
 m_deviceCollection->GetCount(&count);  
 printf("%d devices:\n", count);  
 for (UINT i = 0; i < count; i++)  
 {  
 IMMDevice* tmpDevice;  
 m_deviceCollection->Item(i, &tmpDevice);  
 DWORD state;  
 tmpDevice->GetState(&state);  
 printf("\tState: %d\n", state);  
  
 LPWSTR id;  
 tmpDevice->GetId(&id);  
 printf("\tID: %ls\n", id);  
  
 tmpDevice->Release();  
 }  
 printf("\n");  
  
 // Get Audio Session Manager  
 m_device->Activate(__uuidof(IAudioSessionManager), CLSCTX_ALL, NULL, (void**)&m_audioSessionManager);  
  
 // Get Audio Sesssion Control  
 check(m_audioSessionManager->GetAudioSessionControl(NULL, 0, &m_sessionControl));  
 if (m_sessionControl != NULL)  
 {  
 LPWSTR name;  
 m_sessionControl->GetDisplayName(&name);  
 printf("Session Name: %ls\n", name);  
  
 AudioSessionState sessState;  
 m_sessionControl->GetState(&sessState);  
 printf("Session state: %d\n", sessState);  
 }  
  
 // Get Audio Client  
 m_device->Activate(__uuidof(IAudioClient), CLSCTX_ALL, NULL, (void**)&m_audioClient);  
  
 // Activate Audio Client & Get Service   
 /*check(m_audioClient->GetMixFormat(&m_pwfx));  
 check(m_audioClient->Initialize(AUDCLNT_SHAREMODE_SHARED, 0, 10000000, 0, m_pwfx, NULL));  
 check(m_audioClient->GetService(__uuidof(ISimpleAudioVolume), (void**)&m_audioVolume));*/  
  
 check(m_audioSessionManager->GetSimpleAudioVolume(NULL, FALSE, (ISimpleAudioVolume**)&m_audioVolume));  
}  
Windows API - Win32
Windows API - Win32
A core set of Windows application programming interfaces (APIs) for desktop and server applications. Previously known as Win32 API.
2,585 questions
C++
C++
A high-level, general-purpose programming language, created as an extension of the C programming language, that has object-oriented, generic, and functional features in addition to facilities for low-level memory manipulation.
3,690 questions
0 comments No comments
{count} votes

Accepted answer
  1. Castorix31 84,471 Reputation points
    2023-01-08T20:33:46.547+00:00

    I did this test where I mute MS Edge =>
    (to be improved, like replacing all if (SUCCEEDED(hr)) by a macro like in MS samples...)

    			HRESULT hr = CoInitialize(NULL);  
    			if (SUCCEEDED(hr))  
    			{  
    				IMMDeviceEnumerator* pDeviceEnumerator = NULL;  
    				hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_ALL, __uuidof(IMMDeviceEnumerator), (void**)&pDeviceEnumerator);  
    				if (SUCCEEDED(hr))  
    				{  
    					IMMDevice* pDevice = NULL;  
    					hr = pDeviceEnumerator->GetDefaultAudioEndpoint(eRender, eConsole, &pDevice);  
    					if (SUCCEEDED(hr))  
    					{  
    						IAudioSessionManager2* pAudioSessionManager2 = NULL;  
    						hr = pDevice->Activate(__uuidof(IAudioSessionManager2), CLSCTX_ALL, NULL, (VOID**)&pAudioSessionManager2);  
    						if (SUCCEEDED(hr))  
    						{  
    							IAudioSessionEnumerator* pAudioSessionEnumerator = NULL;  
    							hr = pAudioSessionManager2->GetSessionEnumerator(&pAudioSessionEnumerator);  
    							if (SUCCEEDED(hr))  
    							{  
    								int nSessionCount;  
    								hr = pAudioSessionEnumerator->GetCount(&nSessionCount);  
    								for (int n = 0; n < nSessionCount; n++)  
    								{  
    									IAudioSessionControl* pAudioSessionControl = NULL;  
    									hr = pAudioSessionEnumerator->GetSession(n, &pAudioSessionControl);  
    									if (SUCCEEDED(hr))  
    									{  
    										IAudioSessionControl2* pAudioSessionControl2 = NULL;  
    										hr = pAudioSessionControl->QueryInterface(__uuidof(IAudioSessionControl2), (void**)&pAudioSessionControl2);  
    										if (SUCCEEDED(hr))  
    										{  
    											/*LPWSTR pDisplayName = NULL;  
    											hr = pAudioSessionControl2->GetDisplayName(&pDisplayName);*/  
    											DWORD nPID = 0;  
    											hr = pAudioSessionControl2->GetProcessId(&nPID);  
    											if (SUCCEEDED(hr))  
    											{  
    												HANDLE hProcess = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, nPID);  
    												if (hProcess != NULL)  
    												{  
    													WCHAR wsImageName[MAX_PATH + 1];  
    													DWORD nSize = MAX_PATH;  
    													if (QueryFullProcessImageNameW(hProcess, NULL, wsImageName, &nSize))  
    													{  
    														if (wcsstr(wsImageName, L"msedge") != NULL)  
    														{  
    															ISimpleAudioVolume* pSimpleAudioVolume;  
    															hr = pAudioSessionControl2->QueryInterface(__uuidof(ISimpleAudioVolume), (void**)&pSimpleAudioVolume);  
    															if (SUCCEEDED(hr))  
    															{  
    																hr = pSimpleAudioVolume->SetMute(TRUE, NULL);																	  
    																pSimpleAudioVolume->Release();  
    															}  
    														}  
    													}  
    													CloseHandle(hProcess);  
    												}												  
    											}												  
    											pAudioSessionControl2->Release();  
    										}  
    										pAudioSessionControl->Release();  
    									}  
    								}  
    								pAudioSessionEnumerator->Release();  
    							}  
    							pAudioSessionManager2->Release();  
    						}  
    						pDevice->Release();  
    					}  
    					pDeviceEnumerator->Release();  
    				}  
    				CoUninitialize();  
    			}  
    
    2 people found this answer helpful.
    0 comments No comments

2 additional answers

Sort by: Most helpful
  1. Castorix31 84,471 Reputation points
    2023-01-08T17:52:15.707+00:00

    See the MSDN sample from Endpoint Volume Controls

    2 people found this answer helpful.
    0 comments No comments

  2. OPN_Analysis 41 Reputation points
    2023-01-08T18:01:54.967+00:00

    Thank you!
    I think my larger question is, why aren't I seeing my audio streams? My understanding is that I would be seeing spotify, firefox, etc. from these streams, but I'm not seeing anything. It looks like the roles aren't actually populated, so Windows created pulled some default ones that aren't actually affecting the audio that I'm hearing.

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.