272 lines
10 KiB
Markdown
272 lines
10 KiB
Markdown
# EonaCat.VolumeMixer
|
|
|
|
The EonaCat.VolumeMixer library provides an interface to interact with individual audio sessions on Windows.
|
|
It allows you to retrieve and modify the volume and mute state of a session, get session metadata, and access information about the associated process.
|
|
|
|
This class uses Windows Core Audio APIs via COM interop to manage audio sessions, making it suitable for applications that need fine-grained control over audio streams per process or session.
|
|
|
|
## Features
|
|
|
|
- Get and set audio session volume asynchronously
|
|
- Get and set mute state asynchronously
|
|
- Retrieve session metadata such as display name, icon path, process ID, and state
|
|
- Get the name of the process owning the session
|
|
- Thread-safe operations with internal synchronization
|
|
- Proper cleanup of COM resources through implementation of IDisposable
|
|
|
|
## Note
|
|
|
|
Volume and mute setters are asynchronous and include retry logic for reliability.
|
|
Volume values must be between 0.0 (silent) and 1.0 (max volume).
|
|
Getting process name returns "Unknown" if the process cannot be found.
|
|
Thread-safe for concurrent use.
|
|
Requires Windows Vista or later with Core Audio APIs.
|
|
|
|
## Dependencies
|
|
|
|
Must be run with permissions that allow access to audio session interfaces.
|
|
|
|
## Accessing session state:
|
|
```csharp
|
|
using EonaCat.VolumeMixer;
|
|
|
|
IAudioSessionControlExtended sessionControl = /* obtained from enumerator */;
|
|
IAudioSessionManager sessionManager = /* obtained from audio device */;
|
|
var audioSession = new AudioSession(sessionControl, sessionManager);
|
|
string displayName = audioSession.DisplayName;
|
|
string iconPath = audioSession.IconPath;
|
|
uint processId = audioSession.ProcessId;
|
|
AudioSessionState state = audioSession.State;
|
|
```
|
|
|
|
## Obtaining current volume and mute state:
|
|
```csharp
|
|
// Get current volume (0.0 to 1.0)
|
|
float volume = audioSession.GetVolume();
|
|
|
|
// Set volume asynchronously
|
|
bool success = await audioSession.SetVolumeAsync(0.75f);
|
|
if (success)
|
|
{
|
|
Console.WriteLine("Volume set successfully");
|
|
}
|
|
else
|
|
{
|
|
Console.WriteLine("Failed to set volume");
|
|
}
|
|
```
|
|
|
|
## Mute control:
|
|
```csharp
|
|
// Get mute status
|
|
bool isMuted = audioSession.GetMute();
|
|
|
|
// Set mute asynchronously
|
|
bool muteSuccess = await audioSession.SetMuteAsync(true);
|
|
if (muteSuccess)
|
|
{
|
|
Console.WriteLine("Muted successfully");
|
|
}
|
|
else
|
|
{
|
|
Console.WriteLine("Failed to mute");
|
|
}
|
|
```
|
|
|
|
## Process Information:
|
|
```csharp
|
|
string processName = audioSession.GetProcessName();
|
|
Console.WriteLine($"Audio session process: {processName}");
|
|
```
|
|
|
|
## Playback management example:
|
|
```csharp
|
|
using EonaCat.VolumeMixer.Managers;
|
|
using EonaCat.VolumeMixer.Models;
|
|
using System;
|
|
using System.Threading.Tasks;
|
|
|
|
class Program
|
|
{
|
|
// This file is part of the EonaCat project(s) which is released under the Apache License.
|
|
// See the LICENSE file or go to https://EonaCat.com/License for full license details.
|
|
[STAThread]
|
|
static async Task Main()
|
|
{
|
|
// Playback management example
|
|
using (var volumeMixer = new VolumeMixerManager())
|
|
{
|
|
try
|
|
{
|
|
// Get all audio PLAYBACK devices
|
|
var devices = await volumeMixer.GetAudioDevicesAsync(DataFlow.Output);
|
|
Console.WriteLine($"Found {devices.Count} playback devices:");
|
|
|
|
foreach (var device in devices)
|
|
{
|
|
Console.WriteLine($"- {device.Name} (Default: {device.IsDefault})");
|
|
Console.WriteLine($" Volume: {await device.GetMasterVolumeAsync():P0}");
|
|
Console.WriteLine($" Muted: {await device.GetMasterMuteAsync()}");
|
|
device.Dispose();
|
|
}
|
|
|
|
// Default playback device
|
|
using (var defaultDevice = await volumeMixer.GetDefaultAudioDeviceAsync(DataFlow.Output))
|
|
{
|
|
if (defaultDevice != null)
|
|
{
|
|
Console.WriteLine($"\nDefault playback device: {defaultDevice.Name}");
|
|
|
|
// Get all audio sessions
|
|
var sessions = await defaultDevice.GetAudioSessionsAsync();
|
|
Console.WriteLine($"Active sessions: {sessions.Count}");
|
|
|
|
foreach (var session in sessions)
|
|
{
|
|
Console.WriteLine($"- {session.DisplayName} ({await session.GetProcessNameAsync()})");
|
|
Console.WriteLine($" Volume: {await session.GetVolumeAsync():P0}");
|
|
Console.WriteLine($" Muted: {await session.GetMuteAsync()}");
|
|
session.Dispose();
|
|
}
|
|
}
|
|
|
|
// Example Set volume of default device
|
|
if (defaultDevice != null)
|
|
{
|
|
// Unmute the device if it is muted
|
|
if (await defaultDevice.GetMasterMuteAsync())
|
|
{
|
|
Console.WriteLine("Unmuting default playback device...");
|
|
await defaultDevice.SetMasterMuteAsync(false);
|
|
}
|
|
|
|
Console.WriteLine($"\nSetting default playback device volume to 1%");
|
|
bool success = await defaultDevice.SetMasterVolumeAsync(0.1f);
|
|
|
|
// Log the current volume
|
|
Console.WriteLine($"Current volume: {await defaultDevice.GetMasterVolumeAsync():P0}");
|
|
|
|
for (int i = 0; i < 50; i++)
|
|
{
|
|
if (await defaultDevice.GetMasterVolumeAsync() >= 1f)
|
|
{
|
|
break;
|
|
}
|
|
|
|
// Increment volume by 2% each step
|
|
success = await defaultDevice.StepUpAsync();
|
|
Console.WriteLine($"Current step volume: {await defaultDevice.GetMasterVolumeAsync():P0}");
|
|
}
|
|
|
|
if (success)
|
|
{
|
|
Console.WriteLine("Volume increased by 95% successfully.");
|
|
}
|
|
else
|
|
{
|
|
Console.WriteLine("Failed to increase volume.");
|
|
}
|
|
|
|
// Toggle mute
|
|
// bool currentMute = await defaultDevice.GetMasterMuteAsync();
|
|
// success = await defaultDevice.SetMasterMuteAsync(!currentMute);
|
|
// Console.WriteLine($"Mute toggled: {success}");
|
|
}
|
|
else
|
|
{
|
|
Console.WriteLine("No default playback device found");
|
|
}
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Console.WriteLine($"Error: {ex.Message}");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
|
|
## Microphone management example:
|
|
```csharp
|
|
using EonaCat.VolumeMixer.Managers;
|
|
using EonaCat.VolumeMixer.Models;
|
|
using System;
|
|
using System.Threading.Tasks;
|
|
|
|
class Program
|
|
{
|
|
// This file is part of the EonaCat project(s) which is released under the Apache License.
|
|
// See the LICENSE file or go to https://EonaCat.com/License for full license details.
|
|
[STAThread]
|
|
static async Task Main()
|
|
{
|
|
// Microphone management example
|
|
using (var micManager = new MicrophoneManager())
|
|
{
|
|
try
|
|
{
|
|
// Get all microphones
|
|
var microphones = await micManager.GetMicrophonesAsync();
|
|
Console.WriteLine($"Found {microphones.Count} microphones:");
|
|
|
|
foreach (var mic in microphones)
|
|
{
|
|
Console.WriteLine($"- {mic.Name} (Default: {mic.IsDefault})");
|
|
Console.WriteLine($" Volume: {await mic.GetMasterVolumeAsync():P0}");
|
|
Console.WriteLine($" Muted: {await mic.GetMasterMuteAsync()}");
|
|
mic.Dispose();
|
|
}
|
|
|
|
// Default microphone
|
|
using (var defaultMic = await micManager.GetDefaultMicrophoneAsync())
|
|
{
|
|
Console.WriteLine($"\nSetting default microphone volume to 1%");
|
|
bool success = await defaultMic.SetMasterVolumeAsync(0.1f);
|
|
|
|
// Log the current volume
|
|
Console.WriteLine($"Current volume: {await defaultMic.GetMasterVolumeAsync():P0}");
|
|
|
|
for (int i = 0; i < 50; i++)
|
|
{
|
|
if (await defaultMic.GetMasterVolumeAsync() >= 1f)
|
|
{
|
|
break;
|
|
}
|
|
|
|
// Increment volume by 2% each step
|
|
success = await defaultMic.StepUpAsync();
|
|
Console.WriteLine($"Current step volume: {await defaultMic.GetMasterVolumeAsync():P0}");
|
|
}
|
|
|
|
if (success)
|
|
{
|
|
Console.WriteLine("Volume increased by 95% successfully.");
|
|
}
|
|
else
|
|
{
|
|
Console.WriteLine("Failed to increase volume.");
|
|
}
|
|
}
|
|
|
|
Console.WriteLine($"Default mic volume: {await micManager.GetMicrophoneVolumeAsync():P0}");
|
|
Console.WriteLine($"Default mic muted: {await micManager.GetMicrophoneMuteAsync()}");
|
|
|
|
// Set microphone volume to 60%
|
|
bool result = await micManager.SetMicrophoneVolumeAsync(0.6f);
|
|
Console.WriteLine($"Set microphone volume to 60%: {result}");
|
|
|
|
// Set specific microphone by name
|
|
result = await micManager.SetMicrophoneVolumeByNameAsync("USB", 0.7f);
|
|
Console.WriteLine($"Set USB microphone volume to 70%: {result}");
|
|
|
|
}
|
|
catch (Exception exception)
|
|
{
|
|
Console.WriteLine($"Error: {exception.Message}");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
``` |