diff --git a/EonaCat.VolumeMixer.Tester.WPF/MainWindow.xaml.cs b/EonaCat.VolumeMixer.Tester.WPF/MainWindow.xaml.cs
index 17291eb..94f5edf 100644
--- a/EonaCat.VolumeMixer.Tester.WPF/MainWindow.xaml.cs
+++ b/EonaCat.VolumeMixer.Tester.WPF/MainWindow.xaml.cs
@@ -70,6 +70,7 @@ namespace EonaCat.VolumeMixer.Tester.WPF
await RefreshSessions();
_refreshTimer.Start();
_pollTimer.Start();
+ _currentDevice.SetDefaultDevice();
}
private async Task RefreshSessions()
diff --git a/EonaCat.VolumeMixer.Tester/Program.cs b/EonaCat.VolumeMixer.Tester/Program.cs
index c378f03..9f3ab13 100644
--- a/EonaCat.VolumeMixer.Tester/Program.cs
+++ b/EonaCat.VolumeMixer.Tester/Program.cs
@@ -1,6 +1,7 @@
using EonaCat.VolumeMixer.Managers;
using EonaCat.VolumeMixer.Models;
using System;
+using System.Collections.Generic;
using System.Threading.Tasks;
class Program
@@ -15,16 +16,6 @@ class Program
{
try
{
- while (true)
- {
- var devicesTest = await volumeMixer.GetAudioDevicesAsync(DataFlow.Output);
- var micrphonesTest = await volumeMixer.GetMicrophonesAsync();
- Console.WriteLine($"Found {devicesTest.Count} playback devices");
- Console.WriteLine($"Found {micrphonesTest.Count} microphones");
- await Task.Delay(100);
- }
-
-
// Get all audio PLAYBACK devices
var devices = await volumeMixer.GetAudioDevicesAsync(DataFlow.Output);
Console.WriteLine($"Found {devices.Count} playback devices:");
diff --git a/EonaCat.VolumeMixer/EonaCat.VolumeMixer.csproj b/EonaCat.VolumeMixer/EonaCat.VolumeMixer.csproj
index 6180a9a..19773ad 100644
--- a/EonaCat.VolumeMixer/EonaCat.VolumeMixer.csproj
+++ b/EonaCat.VolumeMixer/EonaCat.VolumeMixer.csproj
@@ -18,9 +18,9 @@
EonaCat, Audio, Volume, Mixer .NET Standard, Jeroen, Saey
EonaCat VolumeMixer
- 1.0.6
- 1.0.0.6
- 1.0.0.6
+ 1.0.7
+ 1.0.0.7
+ 1.0.0.7
icon.png
https://git.saey.me/EonaCat/EonaCat.VolumeMixer
git
@@ -51,4 +51,8 @@
\
+
+
+
+
diff --git a/EonaCat.VolumeMixer/Helpers/ComHelper.cs b/EonaCat.VolumeMixer/Helpers/ComHelper.cs
deleted file mode 100644
index 16ee5a2..0000000
--- a/EonaCat.VolumeMixer/Helpers/ComHelper.cs
+++ /dev/null
@@ -1,62 +0,0 @@
-using System;
-using System.Runtime.InteropServices;
-
-namespace EonaCat.VolumeMixer.Helpers
-{
- // 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.
- internal static class ComHelper
- {
- public static T GetInterface(IntPtr ptr) where T : class
- {
- if (ptr == IntPtr.Zero)
- {
- return null;
- }
-
- try
- {
- return Marshal.GetObjectForIUnknown(ptr) as T;
- }
- catch
- {
- return null;
- }
- finally
- {
- if (ptr != IntPtr.Zero)
- {
- Marshal.Release(ptr);
- }
- }
- }
-
- public static void ReleaseComObject(object comObj)
- {
- if (comObj == null)
- {
- return;
- }
-
- try
- {
- while (Marshal.ReleaseComObject(comObj) > 0)
- {
- // Do nothing
- }
- }
- catch
- {
- try
- {
- Marshal.FinalReleaseComObject(comObj);
- }
- catch
- {
- // Do nothing
- }
- }
- }
-
- }
-}
\ No newline at end of file
diff --git a/EonaCat.VolumeMixer/Managers/VolumeMixerManager.cs b/EonaCat.VolumeMixer/Managers/VolumeMixerManager.cs
index 23b6b7c..0e8ab0c 100644
--- a/EonaCat.VolumeMixer/Managers/VolumeMixerManager.cs
+++ b/EonaCat.VolumeMixer/Managers/VolumeMixerManager.cs
@@ -41,7 +41,10 @@ namespace EonaCat.VolumeMixer.Managers
return await Task.Run(() =>
{
var devices = new List();
- if (_isDisposed || _deviceEnumerator == null) return devices;
+ if (_isDisposed || _deviceEnumerator == null)
+ {
+ return devices;
+ }
lock (_syncLock)
{
@@ -51,10 +54,16 @@ namespace EonaCat.VolumeMixer.Managers
try
{
int hr = _deviceEnumerator.EnumAudioEndpoints(dataFlow, DeviceState.Active, out collection);
- if (hr != 0 || collection == null) return devices;
+ if (hr != 0 || collection == null)
+ {
+ return devices;
+ }
hr = collection.GetCount(out var count);
- if (hr != 0) return devices;
+ if (hr != 0)
+ {
+ return devices;
+ }
// Get default device
string defaultId = string.Empty;
@@ -77,9 +86,15 @@ namespace EonaCat.VolumeMixer.Managers
IMultiMediaDevice device = null;
try
{
- if (collection.Item(i, out device) != 0 || device == null) continue;
+ if (collection.Item(i, out device) != 0 || device == null)
+ {
+ continue;
+ }
- if (device.GetId(out var id) != 0 || string.IsNullOrEmpty(id)) continue;
+ if (device.GetId(out var id) != 0 || string.IsNullOrEmpty(id))
+ {
+ continue;
+ }
string name = GetDeviceName(device);
DeviceType type = GetDeviceType(device);
@@ -131,7 +146,10 @@ namespace EonaCat.VolumeMixer.Managers
public async Task GetDefaultAudioDeviceAsync(DataFlow dataFlow = DataFlow.Output)
{
- if (_isDisposed || _deviceEnumerator == null) return null;
+ if (_isDisposed || _deviceEnumerator == null)
+ {
+ return null;
+ }
return await Task.Run(() =>
{
@@ -165,7 +183,11 @@ namespace EonaCat.VolumeMixer.Managers
try
{
- if (device.OpenPropertyStore(0, out store) != 0 || store == null) return "Unknown Device";
+ if (device.OpenPropertyStore(0, out store) != 0 || store == null)
+ {
+ return "Unknown Device";
+ }
+
if (store.GetValue(ref PKEY_Device_FriendlyName, out prop) == 0 &&
prop.vt == VarEnumConstants.VT_LPWSTR && prop.pointerValue != IntPtr.Zero)
{
@@ -190,7 +212,11 @@ namespace EonaCat.VolumeMixer.Managers
try
{
- if (device.OpenPropertyStore(0, out store) != 0 || store == null) return DeviceType.Unknown;
+ if (device.OpenPropertyStore(0, out store) != 0 || store == null)
+ {
+ return DeviceType.Unknown;
+ }
+
if (store.GetValue(ref PKEY_AudioEndpoint_FormFactor, out prop) == 0 && prop.vt == VarEnumConstants.VT_UI4)
{
return prop.uintValue switch
@@ -425,7 +451,11 @@ namespace EonaCat.VolumeMixer.Managers
{
lock (_syncLock)
{
- if (_isDisposed) return;
+ if (_isDisposed)
+ {
+ return;
+ }
+
_isDisposed = true;
SafeRelease(ref _deviceEnumerator);
}
diff --git a/EonaCat.VolumeMixer/Models/AudioDevice.cs b/EonaCat.VolumeMixer/Models/AudioDevice.cs
index 85a0d3b..fb53e88 100644
--- a/EonaCat.VolumeMixer/Models/AudioDevice.cs
+++ b/EonaCat.VolumeMixer/Models/AudioDevice.cs
@@ -110,7 +110,10 @@ namespace EonaCat.VolumeMixer.Models
public async Task SetMasterVolumeAsync(float volume)
{
- if (_isDisposed || _endpointVolume == null || volume < 0f || volume > 1f) return false;
+ if (_isDisposed || _endpointVolume == null || volume < 0f || volume > 1f)
+ {
+ return false;
+ }
var guid = Guid.Empty;
lock (_syncLock)
@@ -123,7 +126,11 @@ namespace EonaCat.VolumeMixer.Models
{
lock (_syncLock)
{
- if (_isDisposed || _endpointVolume == null) return Task.FromResult(false);
+ if (_isDisposed || _endpointVolume == null)
+ {
+ return Task.FromResult(false);
+ }
+
try
{
int hr = _endpointVolume.GetMute(out bool mute);
@@ -135,7 +142,10 @@ namespace EonaCat.VolumeMixer.Models
public Task SetMasterMuteAsync(bool mute)
{
- if (_isDisposed || _endpointVolume == null) return Task.FromResult(false);
+ if (_isDisposed || _endpointVolume == null)
+ {
+ return Task.FromResult(false);
+ }
var guid = Guid.Empty;
lock (_syncLock)
@@ -147,19 +157,28 @@ namespace EonaCat.VolumeMixer.Models
public async Task> GetAudioSessionsAsync()
{
var sessions = new List();
- if (_isDisposed || _sessionManager == null) return sessions;
+ if (_isDisposed || _sessionManager == null)
+ {
+ return sessions;
+ }
lock (_syncLock)
{
try
{
int hr = _sessionManager.GetSessionEnumerator(out var sessionEnum);
- if (hr != 0 || sessionEnum == null) return sessions;
+ if (hr != 0 || sessionEnum == null)
+ {
+ return sessions;
+ }
try
{
hr = sessionEnum.GetCount(out int count);
- if (hr != 0) return sessions;
+ if (hr != 0)
+ {
+ return sessions;
+ }
for (int i = 0; i < count; i++)
{
@@ -195,7 +214,10 @@ namespace EonaCat.VolumeMixer.Models
private IAudioSessionControlExtended GetSessionControl2(object sessionControl)
{
- if (sessionControl == null) return null;
+ if (sessionControl == null)
+ {
+ return null;
+ }
IntPtr unknownPtr = IntPtr.Zero;
IntPtr sessionControl2Ptr = IntPtr.Zero;
@@ -211,8 +233,15 @@ namespace EonaCat.VolumeMixer.Models
catch (Exception ex) { Debug.WriteLine($"GetSessionControl2 failed: {ex}"); }
finally
{
- if (sessionControl2Ptr != IntPtr.Zero) Marshal.Release(sessionControl2Ptr);
- if (unknownPtr != IntPtr.Zero) Marshal.Release(unknownPtr);
+ if (sessionControl2Ptr != IntPtr.Zero)
+ {
+ Marshal.Release(sessionControl2Ptr);
+ }
+
+ if (unknownPtr != IntPtr.Zero)
+ {
+ Marshal.Release(unknownPtr);
+ }
}
return null;
}
@@ -273,7 +302,11 @@ namespace EonaCat.VolumeMixer.Models
{
lock (_syncLock)
{
- if (_isDisposed) return;
+ if (_isDisposed)
+ {
+ return;
+ }
+
_isDisposed = true;
SafeRelease(ref _endpointVolume);
@@ -282,6 +315,28 @@ namespace EonaCat.VolumeMixer.Models
}
}
+ public bool SetDefaultDevice()
+ {
+ try
+ {
+ var policyConfig = new PolicyConfigClient();
+ policyConfig.SetDefaultEndpoint(Id, Role.Multimedia);
+ policyConfig.SetDefaultEndpoint(Id, Role.Console);
+
+ if (DeviceType == DeviceType.Microphone)
+ {
+ policyConfig.SetDefaultEndpoint(Id, Role.Communications);
+ }
+
+ return true;
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine($"Error setting default device: {ex.Message}");
+ return false;
+ }
+ }
+
private static void SafeRelease(ref T comObj) where T : class
{
if (comObj != null)
@@ -290,5 +345,66 @@ namespace EonaCat.VolumeMixer.Models
comObj = null;
}
}
+
+ internal void SendException(Exception exception)
+ {
+ OnException?.Invoke(this, exception);
+ }
+
+ [InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("F8679F50-850A-41CF-9C72-430F290290C8")]
+ internal interface IPolicyConfig
+ {
+ [PreserveSig]
+ int GetMixFormat(string pstrDeviceName, IntPtr ppFormat);
+
+ [PreserveSig]
+ int GetDeviceFormat(string pstrDeviceName, bool bDefault, IntPtr ppFormat);
+
+ [PreserveSig]
+ int ResetDeviceFormat(string pstrDeviceName);
+
+ [PreserveSig]
+ int SetDeviceFormat(string pstrDeviceName, IntPtr pEndpointFormat, IntPtr MixFormat);
+
+ [PreserveSig]
+ int GetProcessingPeriod(string pstrDeviceName, bool bDefault, IntPtr pmftDefaultPeriod, IntPtr pmftMinimumPeriod);
+
+ [PreserveSig]
+ int SetProcessingPeriod(string pstrDeviceName, IntPtr pmftPeriod);
+
+ [PreserveSig]
+ int GetShareMode(string pstrDeviceName, IntPtr pMode);
+
+ [PreserveSig]
+ int SetShareMode(string pstrDeviceName, IntPtr mode);
+
+ [PreserveSig]
+ int GetPropertyValue(string pstrDeviceName, bool bFxStore, ref PropertyKey key, IntPtr pv);
+
+ [PreserveSig]
+ int SetPropertyValue(string pstrDeviceName, bool bFxStore, ref PropertyKey key, IntPtr pv);
+
+ [PreserveSig]
+ int SetDefaultEndpoint(string pstrDeviceName, Role role);
+
+ [PreserveSig]
+ int SetEndpointVisibility(string pstrDeviceName, bool bVisible);
+ }
+
+ //[ComImport, Guid("870AF99C-171D-4F9E-AF0D-E63DF40C2BC9")]
+ internal class PolicyConfigClient
+ {
+ private readonly IPolicyConfig policyConfig;
+
+ public PolicyConfigClient()
+ {
+ policyConfig = (IPolicyConfig)Activator.CreateInstance(Type.GetTypeFromCLSID(new Guid("870AF99C-171D-4F9E-AF0D-E63DF40C2BC9")));
+ }
+
+ public void SetDefaultEndpoint(string deviceId, Role role)
+ {
+ policyConfig.SetDefaultEndpoint(deviceId, role);
+ }
+ }
}
}
diff --git a/EonaCat.VolumeMixer/Models/AudioSession.cs b/EonaCat.VolumeMixer/Models/AudioSession.cs
index 7449868..751a540 100644
--- a/EonaCat.VolumeMixer/Models/AudioSession.cs
+++ b/EonaCat.VolumeMixer/Models/AudioSession.cs
@@ -30,7 +30,10 @@ namespace EonaCat.VolumeMixer.Models
{
lock (_syncLock)
{
- if (_sessionControl == null) return;
+ if (_sessionControl == null)
+ {
+ return;
+ }
IntPtr unknownPtr = IntPtr.Zero;
try
@@ -48,7 +51,10 @@ namespace EonaCat.VolumeMixer.Models
catch { _audioVolume = null; }
finally
{
- if (unknownPtr != IntPtr.Zero) Marshal.Release(unknownPtr);
+ if (unknownPtr != IntPtr.Zero)
+ {
+ Marshal.Release(unknownPtr);
+ }
}
}
}
@@ -255,7 +261,11 @@ namespace EonaCat.VolumeMixer.Models
{
lock (_syncLock)
{
- if (_isDisposed) return;
+ if (_isDisposed)
+ {
+ return;
+ }
+
_isDisposed = true;
SafeRelease(ref _audioVolume);