Change volume of specific app with CSCore

833 views Asked by At

I would like to change the audio volume of an application with CSCore. The following code is already pretty close to what I want, but it changes the volume of all applications at the same time. Instead, I would like to select one specific app only and change its volume. How could I do that?

class Program
    {
        static void Main(string[] args)
        {
            int pID;

            using (var sessionManager = GetDefaultAudioSessionManager2(DataFlow.Render))
            {
                using (var sessionEnumerator = sessionManager.GetSessionEnumerator())
                {
                    foreach (var session in sessionEnumerator)
                    {
                        using (var simpleVolume = session.QueryInterface<SimpleAudioVolume>())
                        {
                            foreach (var process in Process.GetProcesses())
                            {
                                if (process.ProcessName == "foobar2000" && !String.IsNullOrEmpty(process.MainWindowTitle))
                                {
                                    pID = process.Id;
                                    //Console.WriteLine(pID.ToString());
                                    //simpleVolume.MasterVolume = 0.2f;
                                }
                            }
                        }
                    }
                }
            }
            Console.ReadKey();
        }

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

    }
}
1

There are 1 answers

0
noel On

I know this is a pretty old question but I had a sort of similiar issue and it took me an hour or two to figure out how this works. A look at CSCores unit tests made it a lot easier

The author of the question basically had everything in place except for figuring out which AudioSessionControl belongs to which application (Because it has no PID and the AudioSessionControl.DisplayName is always blank, at least for me).

The trick is to get AudioSessionControl2 from the AudioSessionControl and then get the associated process from its PID.

using CSCore.CoreAudioAPI;
using System.Data;
using System.Diagnostics;

using var device = MMDeviceEnumerator.DefaultAudioEndpoint(
    DataFlow.Render, 
    Role.Multimedia);

using var sessionManager = AudioSessionManager2.FromMMDevice(device);
using var enumerator = sessionManager.GetSessionEnumerator();

//skipping first as it seems to be some default system session
foreach (var sessionControl in enumerator.Skip(1))
{
    using var sessionControl2 = sessionControl.QueryInterface<AudioSessionControl2>();
 
    using var process = Process.GetProcessById(sessionControl2.ProcessID);
    using var volume = sessionControl.QueryInterface<SimpleAudioVolume>();

    Console.WriteLine($"Volume of {process.ProcessName} : {volume.MasterVolume}");
}

enter image description here

To change the volume, just set the value of MasterVolume