1

I am developing a screen recording software and it has volume control. The code I pasted below is how I am controlling the volume.

static class NativeMethods
    {
        [DllImport("winmm.dll")]
        public static extern int waveOutGetVolume(IntPtr hwo, out uint dwVolume);

        [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);
    }


//Event for handling volume control
    private void VolumeSlider(object sender, RoutedPropertyChangedEventArgs<double> e)
    {
        // Calculate the volume that's being set
     int NewVolume = ((ushort.MaxValue / 10) * (int)slider.Value);
        // Set the same volume for both the left and the right channels
        uint NewVolumeAllChannels = (((uint)NewVolume & 0x0000ffff) | ((uint)NewVolume << 16));
        // Set the volume
        NativeMethods.WaveOutSetVolume(IntPtr.Zero, NewVolumeAllChannels);
    }

By viewing the Volume Mixer on Windows I can see this sets the application's volume and not the device. This is great because only changing the application's volume will change the volume of the video it's recording.

enter image description here

Now I want to know if it is possible to create a VU Meter for the application's volume like the one in Windows Volume Mixer. I have tried to achieve this effect using NAudio, but I'm not sure how or if it can. I am open to other APIs.

EDIT: I am not asking how to change the volume...I just need a functioning VU Meter like the on in the Mixer.

Asix Jin
  • 99
  • 1
  • 1
  • 14
  • Its just a slider with a vertical progress bar overlay, should be simple to make... Are you talking about making the control, or making it appear in the sound tray? – Ron Beyer Dec 11 '15 at 20:13
  • Yes but how to I get the values for the VU Meter from the application (not the device) – Asix Jin Dec 11 '15 at 20:14
  • Not sure what the question is. Are you wanting to add it to the Windows Volume Mixer or are you trying to create your own control? I'd assume you'd just add a `Slider` to your UI, hook into the `ValueChanged` event to call `VolumeSlider` – Kcvin Dec 11 '15 at 20:15
  • You set the application's volume at app startup so you know the initial value, you save it when the application is closed. When opened again you load the previous volume and set the volume using the saved value. And you set Min and Max values on your Slider – Kcvin Dec 11 '15 at 20:17
  • So the question is how to get the currently output sound *level* from the application? – Ron Beyer Dec 11 '15 at 20:18
  • Yes @RonBeyer The topic is confusing so I tried my best to explain – Asix Jin Dec 11 '15 at 20:22
  • This is done through data binding. We can't write the control for you. If you're setting the application's sound, you will always know the volume before it gets set and will have to adjust your control appropriately. This question is receiving votes to close since you'd asking how to write a control that looks like a VU. Look on Google/Github for Gauge controls. – Kcvin Dec 11 '15 at 20:26
  • This may be answered here: http://stackoverflow.com/questions/21200825/getting-individual-windows-application-current-volume-output-level-as-visualized – Rick Liddle Dec 11 '15 at 20:30
  • @NETscape I am not asking how to write a control that looks like a VU meter...that is simple....What I needed was basically whatever values the Windows Volume Mixer gets to make its VU Meter move up and down...I should not be receiving votes to close because my question was misunderstood – Asix Jin Dec 15 '15 at 16:49

1 Answers1

2

Didn't want to leave this question unanswered in case someone else stumbles upon this. Basically @RickLiddle comment had the answer. I'll post my modified code from said answer and try to explain. Trying to learn this I have gotten a quite familiar with NAudio & CSCore so if you need further help don't hesitate to ask.

class PeakClass
{
    static int CurrentProcessID = 0000;

    private static void Main(string[] args)
    {
        //Basically gets your default audio device and session attached to it
        using (var sessionManager = GetDefaultAudioSessionManager2(DataFlow.Render))
        {
            using (var sessionEnumerator = sessionManager.GetSessionEnumerator())
            {
                //This will go through a list of all processes uses the device
                //the code got two line above.
                foreach (var session in sessionEnumerator)
                {
                    //This block of code will get the peak value(value needed for VU Meter)
                    //For whatever process you need it for (I believe you can also check by name
                    //but I found that less reliable)
                    using (var session2 = session.QueryInterface<AudioSessionControl2>())
                    {
                        if(session2.ProcessID == CurrentProcessID)
                        {
                            using (var audioMeterInformation = session.QueryInterface<AudioMeterInformation>())
                            {
                                Console.WriteLine(audioMeterInformation.GetPeakValue());
                            }
                        }
                    }

                   //Uncomment this block of code if you need the peak values 
                   //of all the processes
                   //
                    //using (var audioMeterInformation = session.QueryInterface<AudioMeterInformation>())
                    //{
                    //    Console.WriteLine(audioMeterInformation.GetPeakValue());
                    //}
                }
            }
        }
    }

    private static AudioSessionManager2 GetDefaultAudioSessionManager2(DataFlow dataFlow)
    {
        using (var enumerator = new MMDeviceEnumerator())
        {
            using (var device = enumerator.GetDefaultAudioEndpoint(dataFlow, Role.Multimedia))
            {
                Console.WriteLine("DefaultDevice: " + device.FriendlyName);
                var sessionManager = AudioSessionManager2.FromMMDevice(device);
                return sessionManager;
            }
        }
    }
}
Asix Jin
  • 99
  • 1
  • 1
  • 14