0

I need some general method to change master audio volume from Windows XP to Windows 8 in C# because my application is going to work on those OS.

I have tried already http://www.geekpedia.com/tutorial176_Get-and-set-the-wave-sound-volume.html but it doesn't work under Windows 8. Perhaps it should work under Windows XP.

Anyway I need some compatible approach to do it. Any clue?

NoWar
  • 36,338
  • 80
  • 323
  • 498
  • 1
    This question describes Windows 7, but it might work for Windows 8 too: [Mute/unmute, Change master volume in Windows 7 x64 with C#](http://stackoverflow.com/questions/2986007/mute-unmute-change-master-volume-in-windows-7-x64-with-c-sharp) – Nolonar Mar 06 '13 at 14:57
  • @Nolonar WOW! I have a looked at the source code of this project and it is f...g code monster :) To change 1 value we need elephant!! That's not good at all... Microsoft has provide some SIMPLE way to change master sound. – NoWar Mar 06 '13 at 15:03
  • @Nolonar Well at least it a solution for MS Windows Vista/7/8! Put it like an answer please. – NoWar Mar 06 '13 at 15:06
  • I don't think it's a good idea to write an answer that contains nothing but a link to another question... – Nolonar Mar 06 '13 at 15:08
  • @Nolonar As u wish man! :) But u have helped me a lots I will just combine this project and http://www.geekpedia.com/tutorial176_Get-and-set-the-wave-sound-volume.html into the one and based on OS will initiate appropriate actions to set audio volume. THANKS MAN! – NoWar Mar 06 '13 at 15:17

2 Answers2

5

So my solutions is to combine 2 projects:

  1. Mute/unmute, Change master volume in Windows 7 x64 with C#

  2. http://www.geekpedia.com/tutorial176_Get-and-set-the-wave-sound-volume.html

    The final code should be like (It uses NAudio framework)

        static class NativeMethods
        {
    
             [DllImport("winmm.dll", EntryPoint = "waveOutSetVolume")]
            public static extern int WaveOutSetVolume(IntPtr hwo, uint dwVolume);
    
    
            [DllImport("winmm.dll", SetLastError = true)]
            public static extern bool PlaySound(string pszSound, IntPtr hmod, uint fdwSound);
        }
    
        public static class MSWindowsFriendlyNames
        {
            public static string WindowsXP { get { return "Windows XP"; } }
            public static string WindowsVista { get { return "Windows Vista"; } }
            public static string Windows7 { get { return "Windows 7"; } }
            public static string Windows8 { get { return "Windows 8"; } }
        }
    
        public static class SistemVolumChanger
        {
            public static void SetVolume(int value)
            {
                if (value < 0) 
                    value = 0;
    
                if (value > 100)
                    value = 100;
    
                var osFriendlyName = GetOSFriendlyName();
    
                if (osFriendlyName.Contains(MSWindowsFriendlyNames.WindowsXP))
                {
                    SetVolumeForWIndowsXP(value);
                }
                else if (osFriendlyName.Contains(MSWindowsFriendlyNames.WindowsVista) || osFriendlyName.Contains(MSWindowsFriendlyNames.Windows7) || osFriendlyName.Contains(MSWindowsFriendlyNames.Windows8))
                {
                    SetVolumeForWIndowsVista78(value);
                }
                else
                {
                    SetVolumeForWIndowsVista78(value);
                }
            }
    
            public static int GetVolume()
            {
                int result = 100;
                try
                {
                    MMDeviceEnumerator DevEnum = new MMDeviceEnumerator();
                    MMDevice device = DevEnum.GetDefaultAudioEndpoint(EDataFlow.eRender, ERole.eMultimedia);
                    result = (int)(device.AudioEndpointVolume.MasterVolumeLevelScalar * 100);
                }
                catch (Exception)
                { 
                }
    
                return result;
            }
    
            private static void SetVolumeForWIndowsVista78(int value)
            {
                try
                {
                    MMDeviceEnumerator DevEnum = new MMDeviceEnumerator();
                    MMDevice device = DevEnum.GetDefaultAudioEndpoint(EDataFlow.eRender, ERole.eMultimedia);
    
                    device.AudioEndpointVolume.MasterVolumeLevelScalar = (float)value / 100.0f;
                }
                catch (Exception)
                {            
                }          
            }
    
            private static void SetVolumeForWIndowsXP(int value)
            {
                try
                {
                    // Calculate the volume that's being set
                    double newVolume = ushort.MaxValue * value / 10.0;
    
                    uint v = ((uint)newVolume) & 0xffff;
                    uint vAll = v | (v << 16);
    
                    // Set the volume
                    int retVal = NativeMethods.WaveOutSetVolume(IntPtr.Zero, vAll);
                }
                catch (Exception)
                { 
                }          
            }
    
            private static string GetOSFriendlyName()
            {
                string result = string.Empty;
                ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT Caption FROM Win32_OperatingSystem");
                foreach (ManagementObject os in searcher.Get())
                {
                    result = os["Caption"].ToString();
                    break;
                }
                return result;
            }
        }
    

Update #1. Year 2015 Basically it uses NAudio framework. So nowdays some methods and properties of NAudio have other names.

For instance

eDataFlow.eRender is now DataFlow.Render

and

eRole.eMultimedia is Role.Multimedia

Community
  • 1
  • 1
NoWar
  • 36,338
  • 80
  • 323
  • 498
  • 1
    **warning** your way of checking the windows version is incredibly fragile. – Daniel A. White Oct 08 '14 at 18:20
  • 1
    Original article was delete. Can you just put on the all of code? like definition of ``MMDeviceEnumerator``, ``MMDevice`` ...etc. – qakmak Apr 01 '15 at 05:41
  • 1
    You should check the state of the device before changing volume or you will get unnecessary exceptions. if( device.state == NAudio.CoreAudioApi.DeviceState.Active) ... – Robert Apr 27 '15 at 08:48
1

For windows 7+:

There are some problems with the accepted answer. Because the codeproject page is deleted it now has no context.

  1. You need to get NAudio from Nuget

  2. Replace the first with the second

    MMDevice device = DevEnum.GetDefaultAudioEndpoint(EDataFlow.eRender, ERole.eMultimedia);

    MMDevice device = DevEnum.GetDefaultAudioEndpoint((DataFlow)0, (Role)1);

Just a quick heads-up if you are lost trying to fix the errors with the accepted-answer code.

Edza
  • 1,364
  • 3
  • 14
  • 24