Created
November 24, 2017 15:55
-
-
Save OverlordEx3/206764d32407a12564e25eb87e53b07b to your computer and use it in GitHub Desktop.
Audio controller using Windows Core Audio library.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Runtime.InteropServices; | |
using System.Collections.Generic; | |
namespace SetAppVolumne | |
{ | |
class Program | |
{ | |
static void Main(string[] args) | |
{ | |
const string app = "Mozilla Firefox"; | |
foreach (string name in EnumerateApplications()) | |
{ | |
Console.WriteLine("name:" + name); | |
if (name == app) | |
{ | |
// display mute state & volume level (% of master) | |
Console.WriteLine("Mute:" + GetApplicationMute(app)); | |
Console.WriteLine("Volume:" + GetApplicationVolume(app)); | |
// mute the application | |
SetApplicationMute(app, true); | |
// set the volume to half of master volume (50%) | |
SetApplicationVolume(app, 50); | |
} | |
} | |
} | |
public static float? GetApplicationVolume(string name) | |
{ | |
ISimpleAudioVolume volume = GetVolumeObject(name); | |
if (volume == null) | |
return null; | |
float level; | |
volume.GetMasterVolume(out level); | |
return level * 100; | |
} | |
public static bool? GetApplicationMute(string name) | |
{ | |
ISimpleAudioVolume volume = GetVolumeObject(name); | |
if (volume == null) | |
return null; | |
bool mute; | |
volume.GetMute(out mute); | |
return mute; | |
} | |
public static void SetApplicationVolume(string name, float level) | |
{ | |
ISimpleAudioVolume volume = GetVolumeObject(name); | |
if (volume == null) | |
return; | |
Guid guid = Guid.Empty; | |
volume.SetMasterVolume(level / 100, ref guid); | |
} | |
public static void SetApplicationMute(string name, bool mute) | |
{ | |
ISimpleAudioVolume volume = GetVolumeObject(name); | |
if (volume == null) | |
return; | |
Guid guid = Guid.Empty; | |
volume.SetMute(mute, ref guid); | |
} | |
public static IEnumerable<string> EnumerateApplications() | |
{ | |
// get the speakers (1st render + multimedia) device | |
IMMDeviceEnumerator deviceEnumerator = (IMMDeviceEnumerator)(new MMDeviceEnumerator()); | |
IMMDevice speakers; | |
deviceEnumerator.GetDefaultAudioEndpoint(EDataFlow.eRender, ERole.eMultimedia, out speakers); | |
// activate the session manager. we need the enumerator | |
Guid IID_IAudioSessionManager2 = typeof(IAudioSessionManager2).GUID; | |
object o; | |
speakers.Activate(ref IID_IAudioSessionManager2, 0, IntPtr.Zero, out o); | |
IAudioSessionManager2 mgr = (IAudioSessionManager2)o; | |
// enumerate sessions for on this device | |
IAudioSessionEnumerator sessionEnumerator; | |
mgr.GetSessionEnumerator(out sessionEnumerator); | |
int count; | |
sessionEnumerator.GetCount(out count); | |
for (int i = 0; i < count; i++) | |
{ | |
IAudioSessionControl ctl; | |
sessionEnumerator.GetSession(i, out ctl); | |
string dn; | |
ctl.GetDisplayName(out dn); | |
yield return dn; | |
Marshal.ReleaseComObject(ctl); | |
} | |
Marshal.ReleaseComObject(sessionEnumerator); | |
Marshal.ReleaseComObject(mgr); | |
Marshal.ReleaseComObject(speakers); | |
Marshal.ReleaseComObject(deviceEnumerator); | |
} | |
private static ISimpleAudioVolume GetVolumeObject(string name) | |
{ | |
// get the speakers (1st render + multimedia) device | |
IMMDeviceEnumerator deviceEnumerator = (IMMDeviceEnumerator)(new MMDeviceEnumerator()); | |
IMMDevice speakers; | |
deviceEnumerator.GetDefaultAudioEndpoint(EDataFlow.eRender, ERole.eMultimedia, out speakers); | |
// activate the session manager. we need the enumerator | |
Guid IID_IAudioSessionManager2 = typeof(IAudioSessionManager2).GUID; | |
object o; | |
speakers.Activate(ref IID_IAudioSessionManager2, 0, IntPtr.Zero, out o); | |
IAudioSessionManager2 mgr = (IAudioSessionManager2)o; | |
// enumerate sessions for on this device | |
IAudioSessionEnumerator sessionEnumerator; | |
mgr.GetSessionEnumerator(out sessionEnumerator); | |
int count; | |
sessionEnumerator.GetCount(out count); | |
// search for an audio session with the required name | |
// NOTE: we could also use the process id instead of the app name (with IAudioSessionControl2) | |
ISimpleAudioVolume volumeControl = null; | |
for (int i = 0; i < count; i++) | |
{ | |
IAudioSessionControl ctl; | |
sessionEnumerator.GetSession(i, out ctl); | |
string dn; | |
ctl.GetDisplayName(out dn); | |
if (string.Compare(name, dn, StringComparison.OrdinalIgnoreCase) == 0) | |
{ | |
volumeControl = ctl as ISimpleAudioVolume; | |
break; | |
} | |
Marshal.ReleaseComObject(ctl); | |
} | |
Marshal.ReleaseComObject(sessionEnumerator); | |
Marshal.ReleaseComObject(mgr); | |
Marshal.ReleaseComObject(speakers); | |
Marshal.ReleaseComObject(deviceEnumerator); | |
return volumeControl; | |
} | |
} | |
[ComImport] | |
[Guid("BCDE0395-E52F-467C-8E3D-C4579291692E")] | |
internal class MMDeviceEnumerator | |
{ | |
} | |
internal enum EDataFlow | |
{ | |
eRender, | |
eCapture, | |
eAll, | |
EDataFlow_enum_count | |
} | |
internal enum ERole | |
{ | |
eConsole, | |
eMultimedia, | |
eCommunications, | |
ERole_enum_count | |
} | |
[Guid("A95664D2-9614-4F35-A746-DE8DB63617E6"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] | |
internal interface IMMDeviceEnumerator | |
{ | |
int NotImpl1(); | |
[PreserveSig] | |
int GetDefaultAudioEndpoint(EDataFlow dataFlow, ERole role, out IMMDevice ppDevice); | |
// the rest is not implemented | |
} | |
[Guid("D666063F-1587-4E43-81F1-B948E807363F"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] | |
internal interface IMMDevice | |
{ | |
[PreserveSig] | |
int Activate(ref Guid iid, int dwClsCtx, IntPtr pActivationParams, [MarshalAs(UnmanagedType.IUnknown)] out object ppInterface); | |
// the rest is not implemented | |
} | |
[Guid("77AA99A0-1BD6-484F-8BC7-2C654C9A9B6F"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] | |
internal interface IAudioSessionManager2 | |
{ | |
int NotImpl1(); | |
int NotImpl2(); | |
[PreserveSig] | |
int GetSessionEnumerator(out IAudioSessionEnumerator SessionEnum); | |
// the rest is not implemented | |
} | |
[Guid("E2F5BB11-0570-40CA-ACDD-3AA01277DEE8"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] | |
internal interface IAudioSessionEnumerator | |
{ | |
[PreserveSig] | |
int GetCount(out int SessionCount); | |
[PreserveSig] | |
int GetSession(int SessionCount, out IAudioSessionControl Session); | |
} | |
[Guid("F4B1A599-7266-4319-A8CA-E70ACB11E8CD"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] | |
internal interface IAudioSessionControl | |
{ | |
int NotImpl1(); | |
[PreserveSig] | |
int GetDisplayName([MarshalAs(UnmanagedType.LPWStr)] out string pRetVal); | |
// the rest is not implemented | |
} | |
[Guid("87CE5498-68D6-44E5-9215-6DA47EF883D8"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] | |
internal interface ISimpleAudioVolume | |
{ | |
[PreserveSig] | |
int SetMasterVolume(float fLevel, ref Guid EventContext); | |
[PreserveSig] | |
int GetMasterVolume(out float pfLevel); | |
[PreserveSig] | |
int SetMute(bool bMute, ref Guid EventContext); | |
[PreserveSig] | |
int GetMute(out bool pbMute); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I tried this, and what I got was
I did add the quote marks around the name, but that was the only change I made. I am using VS 2019 Community Edition and Windows 10. I have eight apps running, including Chrome, Character Map, Visual Studio 2019, Skype, Outlo.ok and Word