I made a program to mute microphone using WinAPI and it seems to work perfectly in Windows XP but doesn't do a thing in Windows 7. Is it possible to control microphone volume or mute with WinAPI in Windows 7?
void setVolume(DWORD volume) {
HMIXER mixer;
if (mixerOpen(&mixer, 0, 0, 0, 0) != MMSYSERR_NOERROR) {
MessageBoxW(NULL, L"Error: mixerOpen()", NULL, MB_ICONHAND);
return;
}
// Get the line info
MIXERCAPS mixcaps;
MIXERLINE mixerLine;
mixerGetDevCaps(0, &mixcaps, sizeof(MIXERCAPS));
mixerLine.cbStruct = sizeof(MIXERLINE);
mixerLine.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_WAVEIN;
mixerLine.dwSource = 0;
mixerLine.dwDestination = 0;
if (mixerGetLineInfo(reinterpret_cast<HMIXEROBJ>(mixer), &mixerLine, MIXER_GETLINEINFOF_SOURCE)
!= MMSYSERR_NOERROR) {
MessageBoxW(NULL, L"Error: mixerGetLineInfo()", NULL, MB_ICONHAND);
return;
}
// Get control for mixerline
MIXERCONTROL mixerCtrl;
MIXERLINECONTROLS mixerLineCtrl;
mixerLineCtrl.cbStruct = sizeof(MIXERLINECONTROLS);
mixerLineCtrl.dwLineID = mixerLine.dwLineID;
mixerLineCtrl.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME;
mixerLineCtrl.cControls = 1;
mixerLineCtrl.pamxctrl = &mixerCtrl;
mixerLineCtrl.cbmxctrl = sizeof(MIXERCONTROL);
mixerLineCtrl.cControls = 5;
if (mixerGetLineControls(reinterpret_cast<HMIXEROBJ>(mixer), &mixerLineCtrl, MIXER_GETLINECONTROLSF_ONEBYTYPE)
!= MMSYSERR_NOERROR) {
MessageBoxW(NULL, L"Error: mixerGetLineControls()", NULL, MB_ICONHAND);
return;
}
// Volume..
MIXERCONTROLDETAILS mixerCtrlDetails;
MIXERCONTROLDETAILS_UNSIGNED mixerCtrlDetailsUnsigned;
mixerCtrlDetailsUnsigned.dwValue = volume;
mixerCtrlDetails.dwControlID = mixerCtrl.dwControlID;
mixerCtrlDetails.cbStruct = sizeof(MIXERCONTROLDETAILS);
mixerCtrlDetails.cMultipleItems = 0;
mixerCtrlDetails.paDetails = &mixerCtrlDetailsUnsigned;
mixerCtrlDetails.cbDetails = sizeof(MIXERCONTROLDETAILS_UNSIGNED);
mixerCtrlDetails.cChannels = 1;
if (mixerSetControlDetails(reinterpret_cast<HMIXEROBJ>(mixer), &mixerCtrlDetails, MIXER_OBJECTF_HMIXER | MIXER_GETCONTROLDETAILSF_VALUE)
!= MMSYSERR_NOERROR) {
MessageBoxW(NULL, L"Error: mixerSetControlDetails()", NULL, MB_ICONHAND);
return;
}
mixerClose(mixer);
}
You need to use the new audio APIs introduced by Windows Vista.
*EDIT: Visual Studio 2015 (C++):
Usange:
// To 100%
ConsoleApplication3.exe -f 1
// To 0%
ConsoleApplication3.exe -f 0
// To 50%
ConsoleApplication3.exe -f 0.50
Code:
#include "stdafx.h"
#include <stdio.h>
#include <windows.h>
#include <mmdeviceapi.h>
#include <endpointvolume.h>
void Usage()
{
printf("Usage: \n");
printf(" SetVolume [Reports the current volume]\n");
printf(" SetVolume -d <new volume in decibels> [Sets the current default render device volume to the new volume]\n");
printf(" SetVolume -f <new volume as an amplitude scalar> [Sets the current default render device volume to the new volume]\n");
}
int _tmain(int argc, _TCHAR* argv[])
{
HRESULT hr;
bool decibels = false;
bool scalar = false;
double newVolume;
if (argc != 3 && argc != 1)
{
Usage();
return -1;
}
if (argc == 3)
{
if (argv[1][0] == '-')
{
if (argv[1][1] == 'f')
{
scalar = true;
}
else if (argv[1][1] == 'd')
{
decibels = true;
}
}
else
{
Usage();
return -1;
}
newVolume = _tstof(argv[2]);
}
// -------------------------
CoInitialize(NULL);
IMMDeviceEnumerator *deviceEnumerator = NULL;
hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_INPROC_SERVER, __uuidof(IMMDeviceEnumerator), (LPVOID *)&deviceEnumerator);
IMMDevice *defaultDevice = NULL;
hr = deviceEnumerator->GetDefaultAudioEndpoint(eRender, eConsole, &defaultDevice);
deviceEnumerator->Release();
deviceEnumerator = NULL;
IAudioEndpointVolume *endpointVolume = NULL;
hr = defaultDevice->Activate(__uuidof(IAudioEndpointVolume), CLSCTX_INPROC_SERVER, NULL, (LPVOID *)&endpointVolume);
defaultDevice->Release();
defaultDevice = NULL;
// -------------------------
float currentVolume = 0;
endpointVolume->GetMasterVolumeLevel(¤tVolume);
printf("Current volume in dB is: %f\n", currentVolume);
hr = endpointVolume->GetMasterVolumeLevelScalar(¤tVolume);
printf("Current volume as a scalar is: %f\n", currentVolume);
if (decibels)
{
hr = endpointVolume->SetMasterVolumeLevel((float)newVolume, NULL);
}
else if (scalar)
{
hr = endpointVolume->SetMasterVolumeLevelScalar((float)newVolume, NULL);
}
endpointVolume->Release();
CoUninitialize();
return 0;
}