Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PolicyConfig class to manipulate Windows audio devices #398

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
347 changes: 347 additions & 0 deletions CSCore/CoreAudioAPI/PolicyConfig.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,347 @@
using System;
using System.Runtime.InteropServices;

namespace CSCore.CoreAudioAPI
{
internal static class ComInterfaceIds
{
internal const string UNKNOWN_IID = "00000000-0000-0000-C000-000000000046";

internal const string POLICY_CONFIG_CID = "870AF99C-171D-4F9E-AF0D-E63DF40C2BC9";

internal const string POLICY_CONFIG_VISTA_IID = "568B9108-44BF-40B4-9006-86AFE5B5A620";
internal const string POLICY_CONFIG_7_IID = "F8679F50-850A-41CF-9C72-430F290290C8";
internal const string POLICY_CONFIG_X_IID = "CA286FC3-91FD-42C3-8E9B-CAAFA66242E3";
internal const string POLICY_CONFIG_X_RS_IID = "00632A31-4D49-4167-8AE1-27F82CE135B1";
internal const string POLICY_CONFIG_X_RS2_IID = "098FF37B-1062-4B1A-AD73-2A2D530FEAB6";
internal const string POLICY_CONFIG_X_RS3_IID = "5731289F-3E89-4209-86BE-6599A8E05E67";
}

[ComImport, Guid(ComInterfaceIds.POLICY_CONFIG_VISTA_IID),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
internal interface IPolicyConfig
{
[PreserveSig]
int GetMixFormat(string pszDeviceName, IntPtr ppFormat);

[PreserveSig]
int GetDeviceFormat(string pszDeviceName, bool bDefault, IntPtr ppFormat);

[PreserveSig]
int ResetDeviceFormat(string pszDeviceName);

[PreserveSig]
int SetDeviceFormat(string pszDeviceName, IntPtr pEndpointFormat, IntPtr MixFormat);

[PreserveSig]
int GetProcessingPeriod(string pszDeviceName, bool bDefault, IntPtr pmftDefaultPeriod, IntPtr pmftMinimumPeriod);

[PreserveSig]
int SetProcessingPeriod(string pszDeviceName, IntPtr pmftPeriod);

[PreserveSig]
int GetShareMode(string pszDeviceName, IntPtr pMode);

[PreserveSig]
int SetShareMode(string pszDeviceName, IntPtr mode);

[PreserveSig]
int GetPropertyValue(string pszDeviceName, bool bFxStore, IntPtr key, IntPtr pv);

[PreserveSig]
int SetPropertyValue(string pszDeviceName, bool bFxStore, IntPtr key, IntPtr pv);

[PreserveSig]
int SetDefaultEndpoint(string pszDeviceName, Role role);

[PreserveSig]
int SetEndpointVisibility(string pszDeviceName, bool bVisible);
}

[ComImport, Guid(ComInterfaceIds.POLICY_CONFIG_7_IID),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
internal interface IPolicyConfig1
{
[PreserveSig]
int GetMixFormat(string pszDeviceName, IntPtr ppFormat);

[PreserveSig]
int GetDeviceFormat(string pszDeviceName, bool bDefault, IntPtr ppFormat);

[PreserveSig]
int ResetDeviceFormat(string pszDeviceName);

[PreserveSig]
int SetDeviceFormat(string pszDeviceName, IntPtr pEndpointFormat, IntPtr MixFormat);

[PreserveSig]
int GetProcessingPeriod(string pszDeviceName, bool bDefault, IntPtr pmftDefaultPeriod, IntPtr pmftMinimumPeriod);

[PreserveSig]
int SetProcessingPeriod(string pszDeviceName, IntPtr pmftPeriod);

[PreserveSig]
int GetShareMode(string pszDeviceName, IntPtr pMode);

[PreserveSig]
int SetShareMode(string pszDeviceName, IntPtr mode);

[PreserveSig]
int GetPropertyValue(string pszDeviceName, bool bFxStore, IntPtr key, IntPtr pv);

[PreserveSig]
int SetPropertyValue(string pszDeviceName, bool bFxStore, IntPtr key, IntPtr pv);

[PreserveSig]
int SetDefaultEndpoint(string pszDeviceName, Role role);

[PreserveSig]
int SetEndpointVisibility(string pszDeviceName, bool bVisible);
}

[ComImport, Guid(ComInterfaceIds.POLICY_CONFIG_X_IID),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
internal interface IPolicyConfig2
{
[PreserveSig]
int GetMixFormat(string pszDeviceName, IntPtr ppFormat);

[PreserveSig]
int GetDeviceFormat(string pszDeviceName, bool bDefault, IntPtr ppFormat);

[PreserveSig]
int ResetDeviceFormat(string pszDeviceName);

[PreserveSig]
int SetDeviceFormat(string pszDeviceName, IntPtr pEndpointFormat, IntPtr MixFormat);

[PreserveSig]
int GetProcessingPeriod(string pszDeviceName, bool bDefault, IntPtr pmftDefaultPeriod, IntPtr pmftMinimumPeriod);

[PreserveSig]
int SetProcessingPeriod(string pszDeviceName, IntPtr pmftPeriod);

[PreserveSig]
int GetShareMode(string pszDeviceName, IntPtr pMode);

[PreserveSig]
int SetShareMode(string pszDeviceName, IntPtr mode);

[PreserveSig]
int GetPropertyValue(string pszDeviceName, bool bFxStore, IntPtr key, IntPtr pv);

[PreserveSig]
int SetPropertyValue(string pszDeviceName, bool bFxStore, IntPtr key, IntPtr pv);

[PreserveSig]
int SetDefaultEndpoint(string pszDeviceName, Role role);

[PreserveSig]
int SetEndpointVisibility(string pszDeviceName, bool bVisible);
}

[ComImport, Guid(ComInterfaceIds.POLICY_CONFIG_X_RS_IID),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
internal interface IPolicyConfig3
{
[PreserveSig]
int GetMixFormat(string pszDeviceName, IntPtr ppFormat);

[PreserveSig]
int GetDeviceFormat(string pszDeviceName, bool bDefault, IntPtr ppFormat);

[PreserveSig]
int ResetDeviceFormat(string pszDeviceName);

[PreserveSig]
int SetDeviceFormat(string pszDeviceName, IntPtr pEndpointFormat, IntPtr MixFormat);

[PreserveSig]
int GetProcessingPeriod(string pszDeviceName, bool bDefault, IntPtr pmftDefaultPeriod, IntPtr pmftMinimumPeriod);

[PreserveSig]
int SetProcessingPeriod(string pszDeviceName, IntPtr pmftPeriod);

[PreserveSig]
int GetShareMode(string pszDeviceName, IntPtr pMode);

[PreserveSig]
int SetShareMode(string pszDeviceName, IntPtr mode);

[PreserveSig]
int GetPropertyValue(string pszDeviceName, bool bFxStore, IntPtr key, IntPtr pv);

[PreserveSig]
int SetPropertyValue(string pszDeviceName, bool bFxStore, IntPtr key, IntPtr pv);

[PreserveSig]
int SetDefaultEndpoint(string pszDeviceName, Role role);

[PreserveSig]
int SetEndpointVisibility(string pszDeviceName, bool bVisible);
}

[ComImport, Guid(ComInterfaceIds.POLICY_CONFIG_X_RS2_IID),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
internal interface IPolicyConfig4
{
[PreserveSig]
int GetMixFormat(string pszDeviceName, IntPtr ppFormat);

[PreserveSig]
int GetDeviceFormat(string pszDeviceName, bool bDefault, IntPtr ppFormat);

[PreserveSig]
int ResetDeviceFormat(string pszDeviceName);

[PreserveSig]
int SetDeviceFormat(string pszDeviceName, IntPtr pEndpointFormat, IntPtr MixFormat);

[PreserveSig]
int GetProcessingPeriod(string pszDeviceName, bool bDefault, IntPtr pmftDefaultPeriod, IntPtr pmftMinimumPeriod);

[PreserveSig]
int SetProcessingPeriod(string pszDeviceName, IntPtr pmftPeriod);

[PreserveSig]
int GetShareMode(string pszDeviceName, IntPtr pMode);

[PreserveSig]
int SetShareMode(string pszDeviceName, IntPtr mode);

[PreserveSig]
int GetPropertyValue(string pszDeviceName, bool bFxStore, IntPtr key, IntPtr pv);

[PreserveSig]
int SetPropertyValue(string pszDeviceName, bool bFxStore, IntPtr key, IntPtr pv);

[PreserveSig]
int SetDefaultEndpoint(string pszDeviceName, Role role);

[PreserveSig]
int SetEndpointVisibility(string pszDeviceName, bool bVisible);
}

[ComImport, Guid(ComInterfaceIds.POLICY_CONFIG_X_RS3_IID),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
internal interface IPolicyConfig5
{
[PreserveSig]
int GetMixFormat(string pszDeviceName, IntPtr ppFormat);

[PreserveSig]
int GetDeviceFormat(string pszDeviceName, bool bDefault, IntPtr ppFormat);

[PreserveSig]
int ResetDeviceFormat(string pszDeviceName);

[PreserveSig]
int SetDeviceFormat(string pszDeviceName, IntPtr pEndpointFormat, IntPtr MixFormat);

[PreserveSig]
int GetProcessingPeriod(string pszDeviceName, bool bDefault, IntPtr pmftDefaultPeriod, IntPtr pmftMinimumPeriod);

[PreserveSig]
int SetProcessingPeriod(string pszDeviceName, IntPtr pmftPeriod);

[PreserveSig]
int GetShareMode(string pszDeviceName, IntPtr pMode);

[PreserveSig]
int SetShareMode(string pszDeviceName, IntPtr mode);

[PreserveSig]
int GetPropertyValue(string pszDeviceName, bool bFxStore, IntPtr key, IntPtr pv);

[PreserveSig]
int SetPropertyValue(string pszDeviceName, bool bFxStore, IntPtr key, IntPtr pv);

[PreserveSig]
int SetDefaultEndpoint(string pszDeviceName, Role role);

[PreserveSig]
int SetEndpointVisibility(string pszDeviceName, bool bVisible);
}

[ComImport, Guid(ComInterfaceIds.UNKNOWN_IID),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
internal interface IPolicyConfigX
{
[PreserveSig]
int GetMixFormat(string pszDeviceName, IntPtr ppFormat);

[PreserveSig]
int GetDeviceFormat(string pszDeviceName, bool bDefault, IntPtr ppFormat);

[PreserveSig]
int ResetDeviceFormat(string pszDeviceName);

[PreserveSig]
int SetDeviceFormat(string pszDeviceName, IntPtr pEndpointFormat, IntPtr MixFormat);

[PreserveSig]
int GetProcessingPeriod(string pszDeviceName, bool bDefault, IntPtr pmftDefaultPeriod, IntPtr pmftMinimumPeriod);

[PreserveSig]
int SetProcessingPeriod(string pszDeviceName, IntPtr pmftPeriod);

[PreserveSig]
int GetShareMode(string pszDeviceName, IntPtr pMode);

[PreserveSig]
int SetShareMode(string pszDeviceName, IntPtr mode);

[PreserveSig]
int GetPropertyValue(string pszDeviceName, bool bFxStore, IntPtr key, IntPtr pv);

[PreserveSig]
int SetPropertyValue(string pszDeviceName, bool bFxStore, IntPtr key, IntPtr pv);

[PreserveSig]
int SetDefaultEndpoint(string pszDeviceName, Role role);

[PreserveSig]
int SetEndpointVisibility(string pszDeviceName, bool bVisible);
}

[ComImport, Guid(ComInterfaceIds.POLICY_CONFIG_CID)]
internal class PolicyConfigClient { }

static class PolicyConfig
{
/// <summary>
/// The SetDefaultDevice method sets an audio device as the default device for the role.
/// </summary>
/// <param name="deviceId">The device id that identifies the audio endpoint device.</param>
/// <param name="role">The device role of the audio endpoint device.</param>
public static void SetDefaultDevice(string deviceId, Role role)
{
PolicyConfigClient policyConfigClient = new PolicyConfigClient();

switch (policyConfigClient)
{
case IPolicyConfig config:
Marshal.ThrowExceptionForHR(config.SetDefaultEndpoint(deviceId, role));
break;
case IPolicyConfig1 config:
Marshal.ThrowExceptionForHR(config.SetDefaultEndpoint(deviceId, role));
break;
case IPolicyConfig2 config:
Marshal.ThrowExceptionForHR(config.SetDefaultEndpoint(deviceId, role));
break;
case IPolicyConfig3 config:
Marshal.ThrowExceptionForHR(config.SetDefaultEndpoint(deviceId, role));
break;
case IPolicyConfig4 config:
Marshal.ThrowExceptionForHR(config.SetDefaultEndpoint(deviceId, role));
break;
case IPolicyConfig5 config:
Marshal.ThrowExceptionForHR(config.SetDefaultEndpoint(deviceId, role));
break;
case IPolicyConfigX config:
Marshal.ThrowExceptionForHR(config.SetDefaultEndpoint(deviceId, role));
break;
}
}
}
}