Get or Set the Windows System audio volume with a simple method call.
Introduction
Currently, there are no .NET classes that provide methods to retrieve or set the system output volume. Using interfaces to the Windows Multi-Media Device APIs, this article provides a solution.
Background
I got the idea for this article from this web page. I refined it a bit so that it can be dropped into your VB .NET or C# source code and used immediately.
Using the Code
To retrieve the current system audio volume setting value as an integer (0 - 100), call the GetVolume()
function.
Dim currentVolume As Integer = GetVolume()
int currentVolume = SystemAudio.WindowsSystemAudio.GetVolume();
To set the current system audio volume setting to a new value (0 - 100), call the SetVolume()
function.
SetVolume(30)
SystemAudio.WindowsSystemAudio.SetVolume(30);
The following is the source code for the VB.NET and C# methods that call the Windows Multi-Media APIs to either get or set the Windows System audio volume.
Option Strict Off
Imports System
Imports System.Runtime.InteropServices
Module WindowsSystemAudio
<ComImport>
<Guid("A95664D2-9614-4F35-A746-DE8DB63617E6"), _
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)>
Private Interface IMMDeviceEnumerator
#Disable Warning IDE1006
Sub lpVtbl()
#Enable Warning IDE1006
Function GetDefaultAudioEndpoint(ByVal dataFlow As Integer, _
ByVal role As Integer, <Out> ByRef ppDevice As IMMDevice) As Integer
End Interface
Private NotInheritable Class MMDeviceEnumeratorFactory
Public Shared Function CreateInstance() As IMMDeviceEnumerator
Return CType(Activator.CreateInstance_
(Type.GetTypeFromCLSID(New Guid_
("BCDE0395-E52F-467C-8E3D-C4579291692E"))), _
IMMDeviceEnumerator)
End Function
End Class
<Guid("D666063F-1587-4E43-81F1-B948E807363F"), _
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)>
Private Interface IMMDevice
Function Activate(
<MarshalAs(UnmanagedType.LPStruct)> ByVal iid As Guid, _
ByVal dwClsCtx As Integer, ByVal pActivationParams As IntPtr, <Out>
<MarshalAs(UnmanagedType.IUnknown)> ByRef ppInterface As Object) As Integer
End Interface
<Guid("5CDF2C82-841E-4546-9722-0CF74078229A"), _
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)>
Public Interface IAudioEndpointVolume
Function RegisterControlChangeNotify(ByVal pNotify As IntPtr) As Integer
Function UnregisterControlChangeNotify(ByVal pNotify As IntPtr) As Integer
Function GetChannelCount(ByRef pnChannelCount As UInteger) As Integer
Function SetMasterVolumeLevel(ByVal fLevelDB As Single, _
ByVal pguidEventContext As Guid) As Integer
Function SetMasterVolumeLevelScalar_
(ByVal fLevel As Single, ByVal pguidEventContext As Guid) As Integer
Function GetMasterVolumeLevel(ByRef pfLevelDB As Single) As Integer
Function GetMasterVolumeLevelScalar(ByRef pfLevel As Single) As Integer
End Interface
Friend Sub SetVolume(ByVal Level As Integer)
Try
Dim deviceEnumerator As IMMDeviceEnumerator = _
MMDeviceEnumeratorFactory.CreateInstance()
Dim speakers As IMMDevice = Nothing
Dim res As Integer
Const eRender = 0
Const eMultimedia = 1
deviceEnumerator.GetDefaultAudioEndpoint(eRender, eMultimedia, speakers)
Dim Audio_EndPointVolume As IAudioEndpointVolume = Nothing
speakers.Activate(GetType(IAudioEndpointVolume).GUID, 0, _
IntPtr.Zero, Audio_EndPointVolume)
Dim ZeroGuid As New Guid()
res = Audio_EndPointVolume.SetMasterVolumeLevelScalar_
(Level / 100.0F, ZeroGuid)
Catch ex As Exception
End Try
End Sub
Friend Function GetVolume() As Integer
Try
Dim currentLevel As Single = 0
Dim deviceEnumerator As IMMDeviceEnumerator = _
MMDeviceEnumeratorFactory.CreateInstance()
Dim speakers As IMMDevice = Nothing
Dim res As Integer
Const eRender = 0
Const eMultimedia = 1
deviceEnumerator.GetDefaultAudioEndpoint(eRender, eMultimedia, speakers)
Dim Audio_EndPointVolume As IAudioEndpointVolume = Nothing
speakers.Activate(GetType(IAudioEndpointVolume).GUID, _
0, IntPtr.Zero, Audio_EndPointVolume)
res = Audio_EndPointVolume.GetMasterVolumeLevelScalar(currentLevel)
Return CInt(100 * currentLevel)
Catch ex As Exception
Return -1
End Try
End Function
End Module
using System;
using System.Runtime.InteropServices;
namespace SystemAudio
{
internal static class WindowsSystemAudio
{
[ComImport]
[Guid("A95664D2-9614-4F35-A746-DE8DB63617E6"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
private interface IMMDeviceEnumerator
{
void Vtbl();
int GetDefaultAudioEndpoint(int dataFlow, int role, out IMMDevice ppDevice);
}
private static class MMDeviceEnumeratorFactory
{
public static IMMDeviceEnumerator CreateInstance()
{
return (IMMDeviceEnumerator)Activator.CreateInstance
(Type.GetTypeFromCLSID(new Guid
("BCDE0395-E52F-467C-8E3D-C4579291692E")));
}
}
[Guid("D666063F-1587-4E43-81F1-B948E807363F"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
private interface IMMDevice
{
int Activate([MarshalAs(UnmanagedType.LPStruct)] Guid iid,
int dwClsCtx, IntPtr pActivationParams,
[MarshalAs(UnmanagedType.IUnknown)] out object ppInterface);
}
[Guid("5CDF2C82-841E-4546-9722-0CF74078229A"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IAudioEndpointVolume
{
int RegisterControlChangeNotify(IntPtr pNotify);
int UnregisterControlChangeNotify(IntPtr pNotify);
int GetChannelCount(ref uint pnChannelCount);
int SetMasterVolumeLevel(float fLevelDB, Guid pguidEventContext);
int SetMasterVolumeLevelScalar(float fLevel, Guid pguidEventContext);
int GetMasterVolumeLevel(ref float pfLevelDB);
int GetMasterVolumeLevelScalar(ref float pfLevel);
}
internal static void SetVolume(int level)
{
try
{
IMMDeviceEnumerator deviceEnumerator =
MMDeviceEnumeratorFactory.CreateInstance();
IMMDevice speakers;
const int eRender = 0;
const int eMultimedia = 1;
deviceEnumerator.GetDefaultAudioEndpoint
(eRender, eMultimedia, out speakers);
object aepv_obj;
speakers.Activate(typeof(IAudioEndpointVolume).GUID,
0, IntPtr.Zero, out aepv_obj);
IAudioEndpointVolume aepv = (IAudioEndpointVolume)aepv_obj;
Guid ZeroGuid = new();
int res = aepv.SetMasterVolumeLevelScalar(level / 100f, ZeroGuid);
}
catch (Exception ex)
{
}
}
internal static int GetVolume()
{
try
{
float currentLevel = 0f;
IMMDeviceEnumerator deviceEnumerator =
MMDeviceEnumeratorFactory.CreateInstance();
IMMDevice speakers;
const int eRender = 0;
const int eMultimedia = 1;
deviceEnumerator.GetDefaultAudioEndpoint
(eRender, eMultimedia, out speakers);
object aepv_obj;
speakers.Activate(typeof(IAudioEndpointVolume).GUID,
0, IntPtr.Zero, out aepv_obj);
IAudioEndpointVolume aepv = (IAudioEndpointVolume)aepv_obj;
int res = aepv.GetMasterVolumeLevelScalar(ref currentLevel);
return (int)(100 * currentLevel);
}
catch (Exception ex)
{
return -1;
}
}
}
}
Points of Interest
Loads of credit and a big thank you goes to Eske Rahn for the large amount of research that he did to gather the information and produce an example.
History
- 4th April, 2023: Initial version