Solution: I reference the pointer of a variable instead of the variable itself. Thank you @RomanR.
I'm trying to use GetMute/SetMute through ISimpleAudioVolume, and I'm having trouble with what I'm seeing. When I run GetMute I can see that it's not muted (which is good), but when I mute my audio output, or run SetMute(false)
it fails to update anything. I'm not sure if I'm setting up AudioClient correctly, but don't know how to check it.
Thanks!
Edit: I think my issue is somewhere near the top of the initialization chain. When I run check the volume it says it's 100% which isn't true. When I check the device IDs & states, the beginning of the two IDs are a bunch of 0s, and the state says they're both inactive. If I check the AudioSessionControl, there's no name, but it says the session is also inactive.
My guess is that it's somewhere in this stack of init():
check(CoInitialize(NULL));
check(CoCreateInstance(__uuidof(MMDeviceEnumerator), nullptr, CLSCTX_INPROC_SERVER, __uuidof(IMMDeviceEnumerator), (LPVOID*)&m_deviceEnumerator));
check(m_deviceEnumerator->GetDefaultAudioEndpoint(eRender, eConsole, &m_device));
MainVolumeControl.h
#pragma once
#include <cstdio>
#include <windows.h>
#include <audioclient.h>
#include <audiopolicy.h>
#include <Mmdeviceapi.h>
class MainVolumeControl
{
public:
MainVolumeControl();
void init();
void destroy();
void toggleMute();
void GetMute(BOOL* o_mute);
IMMDeviceEnumerator* m_deviceEnumerator;
IMMDevice* m_device;
IAudioClient* m_audioClient;
ISimpleAudioVolume* m_audioVolume;
WAVEFORMATEX* m_pwfx;
};
MainVolumeControl.cpp
MainVolumeControl::MainVolumeControl()
{
m_deviceEnumerator = nullptr;
m_device = nullptr;
m_audioClient = nullptr;
m_audioVolume = nullptr;
m_pwfx = nullptr;
}
void MainVolumeControl::init()
{
// Get Device
check(CoInitialize(NULL));
check(CoCreateInstance(__uuidof(MMDeviceEnumerator), nullptr, CLSCTX_INPROC_SERVER, __uuidof(IMMDeviceEnumerator), (LPVOID*)&m_deviceEnumerator));
check(m_deviceEnumerator->GetDefaultAudioEndpoint(eRender, eConsole, &m_device));
// 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));
}
void MainVolumeControl::destroy()
{
// Release the resources
m_audioVolume->Release();
m_audioClient->Release();
m_device->Release();
m_deviceEnumerator->Release();
CoUninitialize();
}
void MainVolumeControl::toggleMute()
{
BOOL mute = 0;
// Getting the mute value
check(m_audioVolume->GetMute(&mute));
check(m_audioVolume->SetMute(!&mute, NULL));
}
void MainVolumeControl::GetMute(BOOL* o_mute)
{
// Finally getting the mute value
check(m_audioVolume->GetMute(o_mute));
}
Main.cpp
int main(int argc, CHAR* argv[])
{
MainVolumeControl mvc;
BOOL mute = 1;
mvc.init();
mvc.GetMute(&mute);
printf("Mute state: %d\n", mute);
printf("Toggling mute\n");
mvc.toggleMute();
mvc.GetMute(&mute);
printf("Mute state: %d\n", mute);
mvc.destroy();
return 0;
}
Output
Mute state: 0
Toggling mute
Mute state: 0
I reference the pointer of a variable instead of the variable itself. Thank you @RomanR.
Should be:
void MainVolumeControl::toggleMute()
{
BOOL mute = 0;
// Getting the mute value
check(m_audioVolume->GetMute(&mute));
check(m_audioVolume->SetMute(!mute, NULL));
}