using System; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.IO; using System.Runtime.InteropServices; namespace TweetLib.Audio.Utils{ static class NativeCoreAudio{ private const int EDATAFLOW_RENDER = 0; private const int EROLE_MULTIMEDIA = 1; [ComImport] [Guid("BCDE0395-E52F-467C-8E3D-C4579291692E")] private class MMDeviceEnumerator{} [Guid("A95664D2-9614-4F35-A746-DE8DB63617E6")] [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] private interface IMMDeviceEnumerator{ int Unimpl_EnumAudioEndpoints(); IMMDevice GetDefaultAudioEndpoint(int dataFlow, int role); } [Guid("D666063F-1587-4E43-81F1-B948E807363F")] [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] private interface IMMDevice{ [return:MarshalAs(UnmanagedType.IUnknown)] object Activate(ref Guid id, int clsCtx, IntPtr activationParams); } [Guid("77AA99A0-1BD6-484F-8BC7-2C654C9A9B6F")] [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] private interface IAudioSessionManager2{ int Unimpl_FindWillToLive(); int Unimpl_HelloDarknessMyOldFriend(); IAudioSessionEnumerator GetSessionEnumerator(); } [Guid("E2F5BB11-0570-40CA-ACDD-3AA01277DEE8")] [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] private interface IAudioSessionEnumerator{ int GetCount(); IAudioSessionControl GetSession(int sessionIndex); } [Guid("F4B1A599-7266-4319-A8CA-E70ACB11E8CD")] [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] private interface IAudioSessionControl{} [Guid("BFB7FF88-7239-4FC9-8FA2-07C950BE9C6D")] [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] private interface IAudioSessionControl2{ int Unimpl_GetState(); int Unimpl_GetDisplayName(); int Unimpl_SetDisplayName(); int Unimpl_GetIconPath(); int Unimpl_SetIconPath(); int Unimpl_GetGroupingParam(); int Unimpl_SetGroupingParam(); int Unimpl_RegisterAudioSessionNotification(); int Unimpl_UnregisterAudioSessionNotification(); [return:MarshalAs(UnmanagedType.LPWStr)] string GetSessionIdentifier(); } [Guid("87CE5498-68D6-44E5-9215-6DA47EF883D8")] [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] private interface ISimpleAudioVolume{ void SetMasterVolume(float level, ref Guid eventContext); float GetMasterVolume(); } [SuppressMessage("ReSharper", "SuspiciousTypeConversion.Global")] private static ISimpleAudioVolume GetVolumeObject(string name){ IMMDeviceEnumerator devices = (IMMDeviceEnumerator)new MMDeviceEnumerator(); IMMDevice device = devices.GetDefaultAudioEndpoint(EDATAFLOW_RENDER, EROLE_MULTIMEDIA); Guid sessionManagerGUID = typeof(IAudioSessionManager2).GUID; IAudioSessionManager2 manager = (IAudioSessionManager2)device.Activate(ref sessionManagerGUID, 0, IntPtr.Zero); IAudioSessionEnumerator sessions = manager.GetSessionEnumerator(); ISimpleAudioVolume volumeObj = null; for(int index = sessions.GetCount()-1; index >= 0; index--){ if (sessions.GetSession(index) is IAudioSessionControl2 ctl){ string identifier = ctl.GetSessionIdentifier(); if (identifier != null && identifier.Contains(name)){ volumeObj = ctl as ISimpleAudioVolume; break; } Marshal.ReleaseComObject(ctl); } } Marshal.ReleaseComObject(devices); Marshal.ReleaseComObject(device); Marshal.ReleaseComObject(manager); Marshal.ReleaseComObject(sessions); return volumeObj; } public static double GetMixerVolume(string appPath){ ISimpleAudioVolume obj = GetVolumeObject(appPath); float level = 1F; if (obj != null){ level = obj.GetMasterVolume(); Marshal.ReleaseComObject(obj); } return Math.Round(level, 2); } public static double GetMixerVolumeForCurrentProcess(){ string path; using(Process process = Process.GetCurrentProcess()){ path = process.MainModule.FileName; path = path.Substring(Path.GetPathRoot(path).Length); } return GetMixerVolume(path); } } }