Vanara/PInvoke/CoreAudio/AudioPolicy.cs

1630 lines
108 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using System;
using System.Runtime.InteropServices;
using Vanara.InteropServices;
namespace Vanara.PInvoke
{
/// <summary>Functions, structures and constants from Windows Core Audio Api.</summary>
public static partial class CoreAudio
{
/// <summary>The reason that the audio session was disconnected.</summary>
[PInvokeData("audiopolicy.h")]
public enum AudioSessionDisconnectReason
{
/// <summary>The user removed the audio endpoint device.</summary>
DisconnectReasonDeviceRemoval = 0,
/// <summary>The Windows audio service has stopped.</summary>
DisconnectReasonServerShutdown = (DisconnectReasonDeviceRemoval + 1),
/// <summary>The stream format changed for the device that the audio session is connected to.</summary>
DisconnectReasonFormatChanged = (DisconnectReasonServerShutdown + 1),
/// <summary>The user logged off the Windows Terminal Services (WTS) session that the audio session was running in.</summary>
DisconnectReasonSessionLogoff = (DisconnectReasonFormatChanged + 1),
/// <summary>The WTS session that the audio session was running in was disconnected.</summary>
DisconnectReasonSessionDisconnected = (DisconnectReasonSessionLogoff + 1),
/// <summary>
/// The (shared-mode) audio session was disconnected to make the audio endpoint device available for an exclusive-mode connection.
/// </summary>
DisconnectReasonExclusiveModeOverride = (DisconnectReasonSessionDisconnected + 1)
}
/// <summary>
/// <para>
/// The <c>IAudioSessionControl</c> interface enables a client to configure the control parameters for an audio session and to
/// monitor events in the session. The IAudioClient::Initialize method initializes a stream object and assigns the stream to an
/// audio session. The client obtains a reference to the <c>IAudioSessionControl</c> interface on a stream object by calling the
/// IAudioClient::GetService method with parameter riid set to <c>REFIID</c> IID_IAudioSessionControl.
/// </para>
/// <para>
/// Alternatively, a client can obtain the <c>IAudioSessionControl</c> interface of an existing session without having to first
/// create a stream object and add the stream to the session. Instead, the client calls the
/// IAudioSessionManager::GetAudioSessionControl method with parameter AudioSessionGuid set to the session GUID.
/// </para>
/// <para>
/// The client can register to receive notification from the session manager when clients change session parameters through the
/// methods in the <c>IAudioSessionControl</c> interface.
/// </para>
/// <para>
/// When releasing an <c>IAudioSessionControl</c> interface instance, the client must call the interface's <c>Release</c> method
/// from the same thread as the call to <c>IAudioClient::GetService</c> that created the object.
/// </para>
/// <para>
/// The <c>IAudioSessionControl</c> interface controls an audio session. An audio session is a collection of shared-mode streams.
/// This interface does not work with exclusive-mode streams.
/// </para>
/// <para>For a code example that uses the <c>IAudioSessionControl</c> interface, see Audio Events for Legacy Audio Applications.</para>
/// </summary>
// https://docs.microsoft.com/en-us/windows/win32/api/audiopolicy/nn-audiopolicy-iaudiosessioncontrol
[PInvokeData("audiopolicy.h", MSDNShortId = "4446140e-2e61-40ed-b0f9-4c1b90e7c2de")]
[ComImport, Guid("F4B1A599-7266-4319-A8CA-E70ACB11E8CD"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IAudioSessionControl
{
/// <summary>The <c>GetState</c> method retrieves the current state of the audio session.</summary>
/// <returns>
/// <para>A variable into which the method writes the current session state.</para>
/// <para>
/// These values indicate that the session state is active, inactive, or expired, respectively. For more information, see Remarks.
/// </para>
/// </returns>
/// <remarks>
/// <para>
/// This method indicates whether the state of the session is active, inactive, or expired. The state is active if the session
/// has one or more streams that are running. The state changes from active to inactive when the last running stream in the
/// session stops. The session state changes to expired when the client destroys the last stream in the session by releasing all
/// references to the stream object.
/// </para>
/// <para>
/// The Sndvol program displays volume and mute controls for sessions that are in the active and inactive states. When a session
/// expires, Sndvol stops displaying the controls for that session. If a session has previously expired, but the session state
/// changes to active (because a stream in the session begins running) or inactive (because a client assigns a new stream to the
/// session), Sndvol resumes displaying the controls for the session.
/// </para>
/// <para>
/// The client creates a stream by calling the IAudioClient::Initialize method. At the time that it creates a stream, the client
/// assigns the stream to a session. A session begins when a client assigns the first stream to the session. Initially, the
/// session is in the inactive state. The session state changes to active when the first stream in the session begins running.
/// The session terminates when a client releases the final reference to the last remaining stream object in the session.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/audiopolicy/nf-audiopolicy-iaudiosessioncontrol-getstate HRESULT GetState(
// AudioSessionState *pRetVal );
AudioSessionState GetState();
/// <summary>The <c>GetDisplayName</c> method retrieves the display name for the audio session.</summary>
/// <returns>A string that contains the display name.</returns>
/// <remarks>
/// If the client has not called IAudioSessionControl::SetDisplayName to set the display name, the string will be empty. Rather
/// than display an empty name string, the Sndvol program uses a default, automatically generated name to label the volume
/// control for the audio session.
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/audiopolicy/nf-audiopolicy-iaudiosessioncontrol-getdisplayname HRESULT
// GetDisplayName( LPWSTR *pRetVal );
SafeCoTaskMemString GetDisplayName();
/// <summary>The <c>SetDisplayName</c> method assigns a display name to the current session.</summary>
/// <param name="Value">Pointer to a null-terminated, wide-character string that contains the display name for the session.</param>
/// <param name="EventContext">
/// Pointer to the event-context GUID. If a call to this method generates a name-change event, the session manager sends
/// notifications to all clients that have registered IAudioSessionEvents interfaces with the session manager. The session
/// manager includes the EventContext pointer value with each notification. Upon receiving a notification, a client can
/// determine whether it or another client is the source of the event by inspecting the EventContext value. This scheme depends
/// on the client selecting a value for this parameter that is unique among all clients in the session. If the caller supplies a
/// <c>NULL</c> pointer for this parameter, the client's notification method receives a <c>NULL</c> context pointer.
/// </param>
/// <remarks>
/// <para>
/// In Windows Vista, the system-supplied program, Sndvol.exe, uses the display name to label the volume control for the
/// session. If the client does not call <c>SetDisplayName</c> to assign a display name to the session, the Sndvol program uses
/// a default, automatically generated name to label the session. The default name incorporates information such as the window
/// title or version resource of the audio application.
/// </para>
/// <para>
/// If a client has more than one active session, client-specified display names are especially helpful for distinguishing among
/// the volume controls for the various sessions.
/// </para>
/// <para>
/// In the case of a cross-process session, the session has no identifying information, such as an application name or process
/// ID, from which to generate a default display name. Thus, the client must call <c>SetDisplayName</c> to avoid displaying a
/// meaningless default display name.
/// </para>
/// <para>
/// The display name does not persist beyond the lifetime of the IAudioSessionControl object. Thus, after all references to the
/// object are released, a subsequently created version of the object (with the same application, same session GUID, and same
/// endpoint device) will once again have a default, automatically generated display name until the client calls <c>SetDisplayName</c>.
/// </para>
/// <para>The client can retrieve the display name for the session by calling the IAudioSessionControl::GetDisplayName method.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/audiopolicy/nf-audiopolicy-iaudiosessioncontrol-setdisplayname HRESULT
// SetDisplayName( LPCWSTR Value, LPCGUID EventContext );
void SetDisplayName([MarshalAs(UnmanagedType.LPWStr)] string Value, in Guid EventContext);
/// <summary>The <c>GetIconPath</c> method retrieves the path for the display icon for the audio session.</summary>
/// <returns>
/// Pointer to a pointer variable into which the method writes the address of a null-terminated, wide-character string that
/// specifies the fully qualified path of an .ico, .dll, or .exe file that contains the icon. The method allocates the storage
/// for the string. The caller is responsible for freeing the storage, when it is no longer needed, by calling the CoTaskMemFree
/// function. For information about icon paths and <c>CoTaskMemFree</c>, see the Windows SDK documentation.
/// </returns>
/// <remarks>
/// If a client has not called IAudioSessionControl::SetIconPath to set the display icon, the string will be empty. If no
/// client-specified icon is available, the Sndvol program uses the icon from the client's application window to label the
/// volume control for the audio session.
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/audiopolicy/nf-audiopolicy-iaudiosessioncontrol-geticonpath HRESULT
// GetIconPath( LPWSTR *pRetVal );
SafeCoTaskMemString GetIconPath();
/// <summary>The <c>SetIconPath</c> method assigns a display icon to the current session.</summary>
/// <param name="Value">
/// Pointer to a null-terminated, wide-character string that specifies the path and file name of an .ico, .dll, or .exe file
/// that contains the icon. For information about icon paths, see the Windows SDK documentation.
/// </param>
/// <param name="EventContext">
/// Pointer to the event-context GUID. If a call to this method generates an icon-change event, the session manager sends
/// notifications to all clients that have registered IAudioSessionEvents interfaces with the session manager. The session
/// manager includes the EventContext pointer value with each notification. Upon receiving a notification, a client can
/// determine whether it or another client is the source of the event by inspecting the EventContext value. This scheme depends
/// on the client selecting a value for this parameter that is unique among all clients in the session. If the caller supplies a
/// <c>NULL</c> pointer for this parameter, the client's notification method receives a <c>NULL</c> context pointer.
/// </param>
/// <remarks>
/// <para>
/// In Windows Vista, the system-supplied program, Sndvol.exe, uses the display icon (along with the display name) to label the
/// volume control for the session. If the client does not call <c>SetIconPath</c> to assign an icon to the session, the Sndvol
/// program uses the icon from the application window as the default icon for the session.
/// </para>
/// <para>
/// In the case of a cross-process session, the session is not associated with a single application process. Thus, Sndvol has no
/// application-specific icon to use by default, and the client must call <c>SetIconPath</c> to avoid displaying a meaningless icon.
/// </para>
/// <para>
/// The display icon does not persist beyond the lifetime of the IAudioSessionControl object. Thus, after all references to the
/// object are released, a subsequently created version of the object (with the same application, same session GUID, and same
/// endpoint device) will once again have a default icon until the client calls <c>SetIconPath</c>.
/// </para>
/// <para>The client can retrieve the display icon for the session by calling the IAudioSessionControl::GetIconPath method.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/audiopolicy/nf-audiopolicy-iaudiosessioncontrol-seticonpath HRESULT
// SetIconPath( LPCWSTR Value, LPCGUID EventContext );
void SetIconPath([MarshalAs(UnmanagedType.LPWStr)] string Value, in Guid EventContext);
/// <summary>The <c>GetGroupingParam</c> method retrieves the grouping parameter of the audio session.</summary>
/// <returns>
/// Output pointer for the grouping-parameter GUID. This parameter must be a valid, non- <c>NULL</c> pointer to a
/// caller-allocated GUID variable. The method writes the grouping parameter into this variable.
/// </returns>
/// <remarks>
/// <para>
/// All of the audio sessions that have the same grouping parameter value are under the control of the same volume-level slider
/// in the system volume-control program, Sndvol. For more information, see Grouping Parameters.
/// </para>
/// <para>A client can call the IAudioSessionControl::SetGroupingParam method to change the grouping parameter of a session.</para>
/// <para>
/// If a client has never called SetGroupingParam to assign a grouping parameter to an audio session, the session's grouping
/// parameter value is GUID_NULL by default and a call to <c>GetGroupingParam</c> retrieves this value. A grouping parameter
/// value of GUID_NULL indicates that the session does not belong to any grouping. In that case, the session has its own
/// volume-level slider in the Sndvol program.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/audiopolicy/nf-audiopolicy-iaudiosessioncontrol-getgroupingparam HRESULT
// GetGroupingParam( GUID *pRetVal );
Guid GetGroupingParam();
/// <summary>The <c>SetGroupingParam</c> method assigns a session to a grouping of sessions.</summary>
/// <param name="Override">
/// The new grouping parameter. This parameter must be a valid, non- <c>NULL</c> pointer to a grouping-parameter GUID. For more
/// information, see Remarks.
/// </param>
/// <param name="EventContext">
/// Pointer to the event-context GUID. If a call to this method generates a grouping-change event, the session manager sends
/// notifications to all clients that have registered IAudioSessionEvents interfaces with the session manager. The session
/// manager includes the EventContext pointer value with each notification. Upon receiving a notification, a client can
/// determine whether it or another client is the source of the event by inspecting the EventContext value. This scheme depends
/// on the client selecting a value for this parameter that is unique among all clients in the session. If the caller supplies a
/// <c>NULL</c> pointer for this parameter, the client's notification method receives a <c>NULL</c> context pointer.
/// </param>
/// <remarks>
/// <para>
/// A client calls this method to change the grouping parameter of a session. All of the audio sessions that have the same
/// grouping parameter value are under the control of the same volume-level slider in the system volume-control program, Sndvol.
/// For more information, see Grouping Parameters.
/// </para>
/// <para>
/// The client can get the current grouping parameter for the session by calling the IAudioSessionControl::GetGroupingParam method.
/// </para>
/// <para>
/// If a client has never called <c>SetGroupingParam</c> to assign a grouping parameter to a session, the session does not
/// belong to any grouping. A session that does not belong to any grouping has its own, dedicated volume-level slider in the
/// Sndvol program.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/audiopolicy/nf-audiopolicy-iaudiosessioncontrol-setgroupingparam HRESULT
// SetGroupingParam( LPCGUID Override, LPCGUID EventContext );
void SetGroupingParam(in Guid Override, in Guid EventContext);
/// <summary>
/// The <c>RegisterAudioSessionNotification</c> method registers the client to receive notifications of session events,
/// including changes in the stream state.
/// </summary>
/// <param name="NewNotifications">
/// Pointer to a client-implemented IAudioSessionEvents interface. If the method succeeds, it calls the AddRef method on the
/// client's <c>IAudioSessionEvents</c> interface.
/// </param>
/// <remarks>
/// <para>
/// This method passes a client-implemented IAudioSessionEvents interface to the session manager. Following a successful call to
/// this method, the session manager calls the methods in the <c>IAudioSessionEvents</c> interface to notify the client of
/// various session events. Through these methods, the client receives notifications of the following session-related events:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>Display name changes</term>
/// </item>
/// <item>
/// <term>Volume level changes</term>
/// </item>
/// <item>
/// <term>Session state changes (inactive to active, or active to inactive)</term>
/// </item>
/// <item>
/// <term>Grouping parameter changes</term>
/// </item>
/// <item>
/// <term>
/// Disconnection of the client from the session (caused by the user removing the audio endpoint device, shutting down the
/// session manager, or changing the stream format)
/// </term>
/// </item>
/// </list>
/// <para>
/// When notifications are no longer needed, the client can call the IAudioSessionControl::UnregisterAudioSessionNotification
/// method to terminate the notifications.
/// </para>
/// <para>
/// Before the client releases its final reference to the IAudioSessionEvents interface, it should call
/// UnregisterAudioSessionNotification to unregister the interface. Otherwise, the application leaks the resources held by the
/// <c>IAudioSessionEvents</c> and IAudioSessionControl objects. Note that <c>RegisterAudioSessionNotification</c> calls the
/// client's IAudioSessionEvents::AddRef method, and <c>UnregisterAudioSessionNotification</c> calls the
/// IAudioSessionEvents::Release method. If the client errs by releasing its reference to the <c>IAudioSessionEvents</c>
/// interface before calling <c>UnregisterAudioSessionNotification</c>, the session manager never releases its reference to the
/// <c>IAudioSessionEvents</c> interface. For example, a poorly designed <c>IAudioSessionEvents</c> implementation might call
/// <c>UnregisterAudioSessionNotification</c> from the destructor for the <c>IAudioSessionEvents</c> object. In this case, the
/// client will not call <c>UnregisterAudioSessionNotification</c> until the session manager releases its reference to the
/// <c>IAudioSessionEvents</c> interface, and the session manager will not release its reference to the
/// <c>IAudioSessionEvents</c> interface until the client calls <c>UnregisterAudioSessionNotification</c>. For more information
/// about the <c>AddRef</c> and <c>Release</c> methods, see the discussion of the IUnknown interface in the Windows SDK documentation.
/// </para>
/// <para>
/// In addition, the client should call UnregisterAudioSessionNotification before releasing all of its references to the
/// IAudioSessionControl and IAudioSessionManager objects. Unless the client retains a reference to at least one of these two
/// objects, the session manager leaks the storage that it allocated to hold the registration information. After registering a
/// notification interface, the client continues to receive notifications for only as long as at least one of these two objects exists.
/// </para>
/// <para>
/// For a code example that calls the <c>RegisterAudioSessionNotification</c> method, see Audio Events for Legacy Audio Applications.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/audiopolicy/nf-audiopolicy-iaudiosessioncontrol-registeraudiosessionnotification
// HRESULT RegisterAudioSessionNotification( IAudioSessionEvents *NewNotifications );
void RegisterAudioSessionNotification([In] IAudioSessionEvents NewNotifications);
/// <summary>
/// The <c>UnregisterAudioSessionNotification</c> method deletes a previous registration by the client to receive notifications.
/// </summary>
/// <param name="NewNotifications">
/// Pointer to a client-implemented IAudioSessionEvents interface. The client passed this same interface pointer to the session
/// manager in a previous call to the IAudioSessionControl::RegisterAudioSessionNotification method. If the
/// <c>UnregisterAudioSessionNotification</c> method succeeds, it calls the Release method on the client's
/// <c>IAudioSessionEvents</c> interface.
/// </param>
/// <remarks>
/// <para>
/// The client calls this method when it no longer needs to receive notifications. The <c>UnregisterAudioSessionNotification</c>
/// method removes the registration of an IAudioSessionEvents interface that the client previously registered with the session
/// manager by calling the IAudioSessionControl::RegisterAudioSessionNotification method.
/// </para>
/// <para>
/// Before the client releases its final reference to the IAudioSessionEvents interface, it should call
/// <c>UnregisterAudioSessionNotification</c> to unregister the interface. Otherwise, the application leaks the resources held
/// by the <c>IAudioSessionEvents</c> and IAudioSessionControl objects. Note that RegisterAudioSessionNotification calls the
/// client's IAudioSessionEvents::AddRef method, and <c>UnregisterAudioSessionNotification</c> calls the
/// IAudioSessionEvents::Release method. If the client errs by releasing its reference to the <c>IAudioSessionEvents</c>
/// interface before calling <c>UnregisterAudioSessionNotification</c>, the session manager never releases its reference to the
/// <c>IAudioSessionEvents</c> interface. For example, a poorly designed <c>IAudioSessionEvents</c> implementation might call
/// <c>UnregisterAudioSessionNotification</c> from the destructor for the <c>IAudioSessionEvents</c> object. In this case, the
/// client will not call <c>UnregisterAudioSessionNotification</c> until the session manager releases its reference to the
/// <c>IAudioSessionEvents</c> interface, and the session manager will not release its reference to the
/// <c>IAudioSessionEvents</c> interface until the client calls <c>UnregisterAudioSessionNotification</c>. For more information
/// about the <c>AddRef</c> and <c>Release</c> methods, see the discussion of the IUnknown interface in the Windows SDK documentation.
/// </para>
/// <para>
/// For a code example that calls the <c>UnregisterAudioSessionNotification</c> method, see Audio Events for Legacy Audio Applications.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/audiopolicy/nf-audiopolicy-iaudiosessioncontrol-unregisteraudiosessionnotification
// HRESULT UnregisterAudioSessionNotification( IAudioSessionEvents *NewNotifications );
void UnregisterAudioSessionNotification([In] IAudioSessionEvents NewNotifications);
}
/// <summary>
/// <para>The <c>IAudioSessionControl2</c> interface can be used by a client to get information about the audio session.</para>
/// <para>
/// To get a reference to the <c>IAudioSessionControl2</c> interface, the application must call
/// <c>IAudioSessionControl::QueryInterface</c> to request the interface pointer from the stream object's IAudioSessionControl
/// interface. There are two ways an application can get a pointer to the <c>IAudioSessionControl</c> interface:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>
/// By calling IAudioClient::GetService on the audio client after opening a stream on the device. The audio client opens a stream
/// for rendering or capturing, and associates it with an audio session by calling IAudioClient::Initialize.
/// </term>
/// </item>
/// <item>
/// <term>By calling IAudioSessionManager::GetAudioSessionControl for an existing audio session without opening the stream.</term>
/// </item>
/// </list>
/// <para>
/// When the application wants to release the <c>IAudioSessionControl2</c> interface instance, the application must call the
/// interface's <c>Release</c> method from the same thread as the call to IAudioClient::GetService that created the object.
/// </para>
/// <para>
/// The application thread that uses this interface must be initialized for COM. For more information about COM initialization, see
/// the description of the <c>CoInitializeEx</c> function in the Windows SDK documentation.
/// </para>
/// </summary>
/// <remarks>
/// <para>
/// This interface supports custom implementations for stream attenuation or ducking, a new feature in Windows 7. An application
/// playing a media stream can make it behave differently when a new communication stream is opened on the default communication
/// device. For example, the original media stream can be paused while the new communication stream is open. For more information
/// about this feature, see Default Ducking Experience.
/// </para>
/// <para>An application can use this interface to perform the following tasks:</para>
/// <list type="bullet">
/// <item>
/// <term>Specify that it wants to opt out of the default stream attenuation experience provided by the system.</term>
/// </item>
/// <item>
/// <term>
/// Get the audio session identifier that is associated with the stream. The identifier is required during the notification
/// registration. The application can register itself to receive ducking notifications from the system.
/// </term>
/// </item>
/// <item>
/// <term>Check whether the stream associated with the audio session is a system sound.</term>
/// </item>
/// </list>
/// <para>Examples</para>
/// <para>
/// The following example code shows how to get a reference to the <c>IAudioSessionControl2</c> interface and call its methods to
/// determine whether the stream associated with the audio session is a system sound.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/audiopolicy/nn-audiopolicy-iaudiosessioncontrol2
[PInvokeData("audiopolicy.h", MSDNShortId = "3bb65edf-103c-4eeb-82b4-7c571cddfcf3")]
[ComImport, Guid("bfb7ff88-7239-4fc9-8fa2-07c950be9c6d"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IAudioSessionControl2 : IAudioSessionControl
{
/// <summary>The <c>GetState</c> method retrieves the current state of the audio session.</summary>
/// <returns>
/// <para>A variable into which the method writes the current session state.</para>
/// <para>
/// These values indicate that the session state is active, inactive, or expired, respectively. For more information, see Remarks.
/// </para>
/// </returns>
/// <remarks>
/// <para>
/// This method indicates whether the state of the session is active, inactive, or expired. The state is active if the session
/// has one or more streams that are running. The state changes from active to inactive when the last running stream in the
/// session stops. The session state changes to expired when the client destroys the last stream in the session by releasing all
/// references to the stream object.
/// </para>
/// <para>
/// The Sndvol program displays volume and mute controls for sessions that are in the active and inactive states. When a session
/// expires, Sndvol stops displaying the controls for that session. If a session has previously expired, but the session state
/// changes to active (because a stream in the session begins running) or inactive (because a client assigns a new stream to the
/// session), Sndvol resumes displaying the controls for the session.
/// </para>
/// <para>
/// The client creates a stream by calling the IAudioClient::Initialize method. At the time that it creates a stream, the client
/// assigns the stream to a session. A session begins when a client assigns the first stream to the session. Initially, the
/// session is in the inactive state. The session state changes to active when the first stream in the session begins running.
/// The session terminates when a client releases the final reference to the last remaining stream object in the session.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/audiopolicy/nf-audiopolicy-iaudiosessioncontrol-getstate HRESULT GetState(
// AudioSessionState *pRetVal );
new AudioSessionState GetState();
/// <summary>The <c>GetDisplayName</c> method retrieves the display name for the audio session.</summary>
/// <returns>A string that contains the display name.</returns>
/// <remarks>
/// If the client has not called IAudioSessionControl::SetDisplayName to set the display name, the string will be empty. Rather
/// than display an empty name string, the Sndvol program uses a default, automatically generated name to label the volume
/// control for the audio session.
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/audiopolicy/nf-audiopolicy-iaudiosessioncontrol-getdisplayname HRESULT
// GetDisplayName( LPWSTR *pRetVal );
new SafeCoTaskMemString GetDisplayName();
/// <summary>The <c>SetDisplayName</c> method assigns a display name to the current session.</summary>
/// <param name="Value">Pointer to a null-terminated, wide-character string that contains the display name for the session.</param>
/// <param name="EventContext">
/// Pointer to the event-context GUID. If a call to this method generates a name-change event, the session manager sends
/// notifications to all clients that have registered IAudioSessionEvents interfaces with the session manager. The session
/// manager includes the EventContext pointer value with each notification. Upon receiving a notification, a client can
/// determine whether it or another client is the source of the event by inspecting the EventContext value. This scheme depends
/// on the client selecting a value for this parameter that is unique among all clients in the session. If the caller supplies a
/// <c>NULL</c> pointer for this parameter, the client's notification method receives a <c>NULL</c> context pointer.
/// </param>
/// <remarks>
/// <para>
/// In Windows Vista, the system-supplied program, Sndvol.exe, uses the display name to label the volume control for the
/// session. If the client does not call <c>SetDisplayName</c> to assign a display name to the session, the Sndvol program uses
/// a default, automatically generated name to label the session. The default name incorporates information such as the window
/// title or version resource of the audio application.
/// </para>
/// <para>
/// If a client has more than one active session, client-specified display names are especially helpful for distinguishing among
/// the volume controls for the various sessions.
/// </para>
/// <para>
/// In the case of a cross-process session, the session has no identifying information, such as an application name or process
/// ID, from which to generate a default display name. Thus, the client must call <c>SetDisplayName</c> to avoid displaying a
/// meaningless default display name.
/// </para>
/// <para>
/// The display name does not persist beyond the lifetime of the IAudioSessionControl object. Thus, after all references to the
/// object are released, a subsequently created version of the object (with the same application, same session GUID, and same
/// endpoint device) will once again have a default, automatically generated display name until the client calls <c>SetDisplayName</c>.
/// </para>
/// <para>The client can retrieve the display name for the session by calling the IAudioSessionControl::GetDisplayName method.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/audiopolicy/nf-audiopolicy-iaudiosessioncontrol-setdisplayname HRESULT
// SetDisplayName( LPCWSTR Value, LPCGUID EventContext );
new void SetDisplayName([MarshalAs(UnmanagedType.LPWStr)] string Value, in Guid EventContext);
/// <summary>The <c>GetIconPath</c> method retrieves the path for the display icon for the audio session.</summary>
/// <returns>
/// Pointer to a pointer variable into which the method writes the address of a null-terminated, wide-character string that
/// specifies the fully qualified path of an .ico, .dll, or .exe file that contains the icon. The method allocates the storage
/// for the string. The caller is responsible for freeing the storage, when it is no longer needed, by calling the CoTaskMemFree
/// function. For information about icon paths and <c>CoTaskMemFree</c>, see the Windows SDK documentation.
/// </returns>
/// <remarks>
/// If a client has not called IAudioSessionControl::SetIconPath to set the display icon, the string will be empty. If no
/// client-specified icon is available, the Sndvol program uses the icon from the client's application window to label the
/// volume control for the audio session.
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/audiopolicy/nf-audiopolicy-iaudiosessioncontrol-geticonpath HRESULT
// GetIconPath( LPWSTR *pRetVal );
new SafeCoTaskMemString GetIconPath();
/// <summary>The <c>SetIconPath</c> method assigns a display icon to the current session.</summary>
/// <param name="Value">
/// Pointer to a null-terminated, wide-character string that specifies the path and file name of an .ico, .dll, or .exe file
/// that contains the icon. For information about icon paths, see the Windows SDK documentation.
/// </param>
/// <param name="EventContext">
/// Pointer to the event-context GUID. If a call to this method generates an icon-change event, the session manager sends
/// notifications to all clients that have registered IAudioSessionEvents interfaces with the session manager. The session
/// manager includes the EventContext pointer value with each notification. Upon receiving a notification, a client can
/// determine whether it or another client is the source of the event by inspecting the EventContext value. This scheme depends
/// on the client selecting a value for this parameter that is unique among all clients in the session. If the caller supplies a
/// <c>NULL</c> pointer for this parameter, the client's notification method receives a <c>NULL</c> context pointer.
/// </param>
/// <remarks>
/// <para>
/// In Windows Vista, the system-supplied program, Sndvol.exe, uses the display icon (along with the display name) to label the
/// volume control for the session. If the client does not call <c>SetIconPath</c> to assign an icon to the session, the Sndvol
/// program uses the icon from the application window as the default icon for the session.
/// </para>
/// <para>
/// In the case of a cross-process session, the session is not associated with a single application process. Thus, Sndvol has no
/// application-specific icon to use by default, and the client must call <c>SetIconPath</c> to avoid displaying a meaningless icon.
/// </para>
/// <para>
/// The display icon does not persist beyond the lifetime of the IAudioSessionControl object. Thus, after all references to the
/// object are released, a subsequently created version of the object (with the same application, same session GUID, and same
/// endpoint device) will once again have a default icon until the client calls <c>SetIconPath</c>.
/// </para>
/// <para>The client can retrieve the display icon for the session by calling the IAudioSessionControl::GetIconPath method.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/audiopolicy/nf-audiopolicy-iaudiosessioncontrol-seticonpath HRESULT
// SetIconPath( LPCWSTR Value, LPCGUID EventContext );
new void SetIconPath([MarshalAs(UnmanagedType.LPWStr)] string Value, in Guid EventContext);
/// <summary>The <c>GetGroupingParam</c> method retrieves the grouping parameter of the audio session.</summary>
/// <returns>
/// Output pointer for the grouping-parameter GUID. This parameter must be a valid, non- <c>NULL</c> pointer to a
/// caller-allocated GUID variable. The method writes the grouping parameter into this variable.
/// </returns>
/// <remarks>
/// <para>
/// All of the audio sessions that have the same grouping parameter value are under the control of the same volume-level slider
/// in the system volume-control program, Sndvol. For more information, see Grouping Parameters.
/// </para>
/// <para>A client can call the IAudioSessionControl::SetGroupingParam method to change the grouping parameter of a session.</para>
/// <para>
/// If a client has never called SetGroupingParam to assign a grouping parameter to an audio session, the session's grouping
/// parameter value is GUID_NULL by default and a call to <c>GetGroupingParam</c> retrieves this value. A grouping parameter
/// value of GUID_NULL indicates that the session does not belong to any grouping. In that case, the session has its own
/// volume-level slider in the Sndvol program.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/audiopolicy/nf-audiopolicy-iaudiosessioncontrol-getgroupingparam HRESULT
// GetGroupingParam( GUID *pRetVal );
new Guid GetGroupingParam();
/// <summary>The <c>SetGroupingParam</c> method assigns a session to a grouping of sessions.</summary>
/// <param name="Override">
/// The new grouping parameter. This parameter must be a valid, non- <c>NULL</c> pointer to a grouping-parameter GUID. For more
/// information, see Remarks.
/// </param>
/// <param name="EventContext">
/// Pointer to the event-context GUID. If a call to this method generates a grouping-change event, the session manager sends
/// notifications to all clients that have registered IAudioSessionEvents interfaces with the session manager. The session
/// manager includes the EventContext pointer value with each notification. Upon receiving a notification, a client can
/// determine whether it or another client is the source of the event by inspecting the EventContext value. This scheme depends
/// on the client selecting a value for this parameter that is unique among all clients in the session. If the caller supplies a
/// <c>NULL</c> pointer for this parameter, the client's notification method receives a <c>NULL</c> context pointer.
/// </param>
/// <remarks>
/// <para>
/// A client calls this method to change the grouping parameter of a session. All of the audio sessions that have the same
/// grouping parameter value are under the control of the same volume-level slider in the system volume-control program, Sndvol.
/// For more information, see Grouping Parameters.
/// </para>
/// <para>
/// The client can get the current grouping parameter for the session by calling the IAudioSessionControl::GetGroupingParam method.
/// </para>
/// <para>
/// If a client has never called <c>SetGroupingParam</c> to assign a grouping parameter to a session, the session does not
/// belong to any grouping. A session that does not belong to any grouping has its own, dedicated volume-level slider in the
/// Sndvol program.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/audiopolicy/nf-audiopolicy-iaudiosessioncontrol-setgroupingparam HRESULT
// SetGroupingParam( LPCGUID Override, LPCGUID EventContext );
new void SetGroupingParam(in Guid Override, in Guid EventContext);
/// <summary>
/// The <c>RegisterAudioSessionNotification</c> method registers the client to receive notifications of session events,
/// including changes in the stream state.
/// </summary>
/// <param name="NewNotifications">
/// Pointer to a client-implemented IAudioSessionEvents interface. If the method succeeds, it calls the AddRef method on the
/// client's <c>IAudioSessionEvents</c> interface.
/// </param>
/// <remarks>
/// <para>
/// This method passes a client-implemented IAudioSessionEvents interface to the session manager. Following a successful call to
/// this method, the session manager calls the methods in the <c>IAudioSessionEvents</c> interface to notify the client of
/// various session events. Through these methods, the client receives notifications of the following session-related events:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>Display name changes</term>
/// </item>
/// <item>
/// <term>Volume level changes</term>
/// </item>
/// <item>
/// <term>Session state changes (inactive to active, or active to inactive)</term>
/// </item>
/// <item>
/// <term>Grouping parameter changes</term>
/// </item>
/// <item>
/// <term>
/// Disconnection of the client from the session (caused by the user removing the audio endpoint device, shutting down the
/// session manager, or changing the stream format)
/// </term>
/// </item>
/// </list>
/// <para>
/// When notifications are no longer needed, the client can call the IAudioSessionControl::UnregisterAudioSessionNotification
/// method to terminate the notifications.
/// </para>
/// <para>
/// Before the client releases its final reference to the IAudioSessionEvents interface, it should call
/// UnregisterAudioSessionNotification to unregister the interface. Otherwise, the application leaks the resources held by the
/// <c>IAudioSessionEvents</c> and IAudioSessionControl objects. Note that <c>RegisterAudioSessionNotification</c> calls the
/// client's IAudioSessionEvents::AddRef method, and <c>UnregisterAudioSessionNotification</c> calls the
/// IAudioSessionEvents::Release method. If the client errs by releasing its reference to the <c>IAudioSessionEvents</c>
/// interface before calling <c>UnregisterAudioSessionNotification</c>, the session manager never releases its reference to the
/// <c>IAudioSessionEvents</c> interface. For example, a poorly designed <c>IAudioSessionEvents</c> implementation might call
/// <c>UnregisterAudioSessionNotification</c> from the destructor for the <c>IAudioSessionEvents</c> object. In this case, the
/// client will not call <c>UnregisterAudioSessionNotification</c> until the session manager releases its reference to the
/// <c>IAudioSessionEvents</c> interface, and the session manager will not release its reference to the
/// <c>IAudioSessionEvents</c> interface until the client calls <c>UnregisterAudioSessionNotification</c>. For more information
/// about the <c>AddRef</c> and <c>Release</c> methods, see the discussion of the IUnknown interface in the Windows SDK documentation.
/// </para>
/// <para>
/// In addition, the client should call UnregisterAudioSessionNotification before releasing all of its references to the
/// IAudioSessionControl and IAudioSessionManager objects. Unless the client retains a reference to at least one of these two
/// objects, the session manager leaks the storage that it allocated to hold the registration information. After registering a
/// notification interface, the client continues to receive notifications for only as long as at least one of these two objects exists.
/// </para>
/// <para>
/// For a code example that calls the <c>RegisterAudioSessionNotification</c> method, see Audio Events for Legacy Audio Applications.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/audiopolicy/nf-audiopolicy-iaudiosessioncontrol-registeraudiosessionnotification
// HRESULT RegisterAudioSessionNotification( IAudioSessionEvents *NewNotifications );
new void RegisterAudioSessionNotification([In] IAudioSessionEvents NewNotifications);
/// <summary>
/// The <c>UnregisterAudioSessionNotification</c> method deletes a previous registration by the client to receive notifications.
/// </summary>
/// <param name="NewNotifications">
/// Pointer to a client-implemented IAudioSessionEvents interface. The client passed this same interface pointer to the session
/// manager in a previous call to the IAudioSessionControl::RegisterAudioSessionNotification method. If the
/// <c>UnregisterAudioSessionNotification</c> method succeeds, it calls the Release method on the client's
/// <c>IAudioSessionEvents</c> interface.
/// </param>
/// <remarks>
/// <para>
/// The client calls this method when it no longer needs to receive notifications. The <c>UnregisterAudioSessionNotification</c>
/// method removes the registration of an IAudioSessionEvents interface that the client previously registered with the session
/// manager by calling the IAudioSessionControl::RegisterAudioSessionNotification method.
/// </para>
/// <para>
/// Before the client releases its final reference to the IAudioSessionEvents interface, it should call
/// <c>UnregisterAudioSessionNotification</c> to unregister the interface. Otherwise, the application leaks the resources held
/// by the <c>IAudioSessionEvents</c> and IAudioSessionControl objects. Note that RegisterAudioSessionNotification calls the
/// client's IAudioSessionEvents::AddRef method, and <c>UnregisterAudioSessionNotification</c> calls the
/// IAudioSessionEvents::Release method. If the client errs by releasing its reference to the <c>IAudioSessionEvents</c>
/// interface before calling <c>UnregisterAudioSessionNotification</c>, the session manager never releases its reference to the
/// <c>IAudioSessionEvents</c> interface. For example, a poorly designed <c>IAudioSessionEvents</c> implementation might call
/// <c>UnregisterAudioSessionNotification</c> from the destructor for the <c>IAudioSessionEvents</c> object. In this case, the
/// client will not call <c>UnregisterAudioSessionNotification</c> until the session manager releases its reference to the
/// <c>IAudioSessionEvents</c> interface, and the session manager will not release its reference to the
/// <c>IAudioSessionEvents</c> interface until the client calls <c>UnregisterAudioSessionNotification</c>. For more information
/// about the <c>AddRef</c> and <c>Release</c> methods, see the discussion of the IUnknown interface in the Windows SDK documentation.
/// </para>
/// <para>
/// For a code example that calls the <c>UnregisterAudioSessionNotification</c> method, see Audio Events for Legacy Audio Applications.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/audiopolicy/nf-audiopolicy-iaudiosessioncontrol-unregisteraudiosessionnotification
// HRESULT UnregisterAudioSessionNotification( IAudioSessionEvents *NewNotifications );
new void UnregisterAudioSessionNotification([In] IAudioSessionEvents NewNotifications);
/// <summary>The <c>GetSessionIdentifier</c> method retrieves the audio session identifier.</summary>
/// <returns>A string that receives the audio session identifier.</returns>
/// <remarks>
/// <para>
/// Each audio session is identified by an identifier string. This session identifier string is not unique across all instances.
/// If there are two instances of the application playing, both instances will have the same session identifier. The identifier
/// retrieved by <c>GetSessionIdentifier</c> is different from the session instance identifier, which is unique across all
/// sessions. To get the session instance identifier, call IAudioSessionControl2::GetSessionInstanceIdentifier.
/// </para>
/// <para>
/// <c>GetSessionIdentifier</c> checks whether the session has been disconnected on the default device. It retrieves the
/// identifier string that is cached by the audio client for the device. If the session identifier is not found, this method
/// retrieves it from the audio engine.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/audiopolicy/nf-audiopolicy-iaudiosessioncontrol2-getsessionidentifier
// HRESULT GetSessionIdentifier( LPWSTR *pRetVal );
SafeCoTaskMemString GetSessionIdentifier();
/// <summary>The <c>GetSessionInstanceIdentifier</c> method retrieves the identifier of the audio session instance.</summary>
/// <returns>A string that receives the identifier of a particular instance of the audio session.</returns>
/// <remarks>
/// <para>
/// Each audio session instance is identified by a unique string. This string represents a particular instance of the audio
/// session and, unlike the session identifier, is unique across all instances. If there are two instances of the application
/// playing, they will have different session instance identifiers. The identifier retrieved by
/// <c>GetSessionInstanceIdentifier</c> is different from the session identifier, which is shared by all session instances. To
/// get the session identifier, call IAudioSessionControl2::GetSessionIdentifier.
/// </para>
/// <para>
/// <c>GetSessionInstanceIdentifier</c> checks whether the session has been disconnected on the default device. It retrieves the
/// identifier string that is cached by the audio client for the device. If the session instance identifier is not found, this
/// method retrieves it from the audio engine. For example code about getting a session instance identifier, see Getting Ducking
/// Events from a Communication Device.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/audiopolicy/nf-audiopolicy-iaudiosessioncontrol2-getsessioninstanceidentifier
// HRESULT GetSessionInstanceIdentifier( LPWSTR *pRetVal );
SafeCoTaskMemString GetSessionInstanceIdentifier();
/// <summary>The <c>GetProcessId</c> method retrieves the process identifier of the audio session.</summary>
/// <returns>A <c>DWORD</c> variable that receives the process identifier of the audio session.</returns>
/// <remarks>
/// <para>This method overwrites the value that was passed by the application in pRetVal.</para>
/// <para>
/// <c>GetProcessId</c> checks whether the audio session has been disconnected on the default device or if the session has
/// switched to another stream. In the case of stream switching, this method transfers state information for the new stream to
/// the session. State information includes volume controls, metadata information (display name, icon path), and the session's
/// property store.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/audiopolicy/nf-audiopolicy-iaudiosessioncontrol2-getprocessid HRESULT
// GetProcessId( DWORD *pRetVal );
uint GetProcessId();
/// <summary>The <c>IsSystemSoundsSession</c> method indicates whether the session is a system sounds session.</summary>
/// <returns>
/// <para>The possible return codes include, but are not limited to, the values shown in the following table.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>S_OK</term>
/// <term>The session is a system sounds session.</term>
/// </item>
/// <item>
/// <term>S_FALSE</term>
/// <term>The session is not a system sounds session.</term>
/// </item>
/// </list>
/// </returns>
// https://docs.microsoft.com/en-us/windows/win32/api/audiopolicy/nf-audiopolicy-iaudiosessioncontrol2-issystemsoundssession
// HRESULT IsSystemSoundsSession();
[PreserveSig]
HRESULT IsSystemSoundsSession();
/// <summary>
/// The <c>SetDuckingPreference</c> method enables or disables the default stream attenuation experience (auto-ducking) provided
/// by the system.
/// </summary>
/// <param name="optOut">A <c>BOOL</c> variable that enables or disables system auto-ducking.</param>
/// <remarks>
/// <para>
/// By default, the system adjusts the volume for all currently playing sounds when the system starts a communication session
/// and receives a new communication stream on the default communication device. For more information about this feature, see
/// Using a Communication Device.
/// </para>
/// <para>
/// If the application passes <c>TRUE</c> in optOut, the system disables the Default Ducking Experience. For more information,
/// see Disabling the Default Ducking Experience.
/// </para>
/// <para>
/// To provide a custom implementation, the application needs to get notifications from the system when it opens or closes the
/// communication stream. To receive the notifications, the application must call this method before registering itself by
/// calling <c>IAudioSessionManager2::RegisterForDuckNotification</c>. For more information and example code, see Getting
/// Ducking Events.
/// </para>
/// <para>
/// If the application passes <c>FALSE</c> in optOut, the application provides the default stream attenuation experience
/// provided by the system.
/// </para>
/// <para>
/// We recommend that the application call <c>SetDuckingPreference</c> during stream creation. However, this method can be
/// called dynamically during the session to change the initial preference.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/audiopolicy/nf-audiopolicy-iaudiosessioncontrol2-setduckingpreference
// HRESULT SetDuckingPreference( BOOL optOut );
void SetDuckingPreference([MarshalAs(UnmanagedType.Bool)] bool optOut);
}
/// <summary>
/// The <c>IAudioSessionEnumerator</c> interface enumerates audio sessions on an audio device. To get a reference to the
/// <c>IAudioSessionEnumerator</c> interface of the session enumerator object, the application must call IAudioSessionManager2::GetSessionEnumerator.
/// </summary>
/// <remarks>
/// <para>
/// If an application wants to be notified when new sessions are created, it must register its implementation of
/// IAudioSessionNotification with the session manager. Upon successful registration, the session manager sends create-session
/// notifications to the application in the form of callbacks. These notifications contain a reference to the IAudioSessionControl
/// pointer of the newly created session.
/// </para>
/// <para>
/// The session enumerator maintains a list of current sessions by holding references to each session's IAudioSessionControl
/// pointer. However, the session enumerator might not be aware of the new sessions that are reported through
/// IAudioSessionNotification. In that case, the application would have access to only a partial list of sessions. This might occur
/// if the <c>IAudioSessionControl</c> pointer (in the callback) is released before the session enumerator is initialized.
/// Therefore, if an application wants a complete set of sessions for the audio endpoint, the application should maintain its own list.
/// </para>
/// <para>The application must perform the following steps to receive session notifications and manage a list of current sessions.</para>
/// <list type="number">
/// <item>
/// <term>
/// Initialize COM with the Multithreaded Apartment (MTA) model by calling in a non-UI thread. If MTA is not initialized, the
/// application does not receive session notifications from the session manager.
/// </term>
/// </item>
/// <item>
/// <term>
/// Activate an IAudioSessionManager2 interface from the audio endpoint device. Call IMMDevice::Activate with parameter iid set to
/// <c>IID_IAudioSessionManager2</c>. This call receives a reference to the session manager's <c>IAudioSessionManager2</c> interface
/// in the ppInterface parameter.
/// </term>
/// </item>
/// <item>
/// <term>Implement the IAudioSessionNotification interface to provide the callback behavior.</term>
/// </item>
/// <item>
/// <term>Call IAudioSessionManager2::RegisterSessionNotification to register the application's implementation of IAudioSessionNotification.</term>
/// </item>
/// <item>
/// <term>
/// Create and initialize the session enumerator object by calling IAudioSessionManager2::GetSessionEnumerator. This method
/// generates a list of current sessions available for the endpoint and adds the IAudioSessionControl pointers for each session in
/// the list, if they are not already present.
/// </term>
/// </item>
/// <item>
/// <term>
/// Use the <c>IAudioSessionEnumerator</c> interface returned in the previous step to retrieve and enumerate the list of sessions.
/// The session control for each session can be retrieved by calling IAudioSessionEnumerator::GetSession. Make sure you call
/// <c>AddRef</c> for each session control to maintain the reference count.
/// </term>
/// </item>
/// <item>
/// <term>
/// When the application gets a create-session notification, add the IAudioSessionControl pointer of the new session (received in
/// IAudioSessionNotification::OnSessionCreated) to the list of existing sessions.
/// </term>
/// </item>
/// </list>
/// <para>
/// Because the application maintains this list of sessions and manages the lifetime of the session based on the application's
/// requirements, there is no expiration mechanism enforced by the audio system on the session control objects.
/// </para>
/// <para>A session control is valid as long as the application has a reference to the session control in the list.</para>
/// <para>Examples</para>
/// <para>The following example code shows how to create the session enumerator object and then enumerate sessions.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/audiopolicy/nn-audiopolicy-iaudiosessionenumerator
[PInvokeData("audiopolicy.h", MSDNShortId = "a7976d13-3391-4747-b83a-cfb9407b34f2")]
[ComImport, Guid("E2F5BB11-0570-40CA-ACDD-3AA01277DEE8"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IAudioSessionEnumerator
{
/// <summary>The <c>GetCount</c> method gets the total number of audio sessions that are open on the audio device.</summary>
/// <returns>Receives the total number of audio sessions.</returns>
// https://docs.microsoft.com/en-us/windows/win32/api/audiopolicy/nf-audiopolicy-iaudiosessionenumerator-getcount HRESULT
// GetCount( int *SessionCount );
int GetCount();
/// <summary>The <c>GetSession</c> method gets the audio session specified by an audio session number.</summary>
/// <param name="SessionCount">
/// The session number. If there are n sessions, the sessions are numbered from 0 to n 1. To get the number of sessions, call
/// the IAudioSessionEnumerator::GetCount method.
/// </param>
/// <returns>
/// Receives a pointer to the IAudioSessionControl interface of the session object in the collection that is maintained by the
/// session enumerator. The caller must release the interface pointer.
/// </returns>
// https://docs.microsoft.com/en-us/windows/win32/api/audiopolicy/nf-audiopolicy-iaudiosessionenumerator-getsession HRESULT
// GetSession( int SessionCount, IAudioSessionControl **Session );
IAudioSessionControl GetSession(int SessionCount);
}
/// <summary>
/// <para>
/// The <c>IAudioSessionEvents</c> interface provides notifications of session-related events such as changes in the volume level,
/// display name, and session state. Unlike the other interfaces in this section, which are implemented by the WASAPI system
/// component, a WASAPI client implements the <c>IAudioSessionEvents</c> interface. To receive event notifications, the client
/// passes a pointer to its <c>IAudioSessionEvents</c> interface to the IAudioSessionControl::RegisterAudioSessionNotification method.
/// </para>
/// <para>
/// After registering its <c>IAudioClientSessionEvents</c> interface, the client receives event notifications in the form of
/// callbacks through the methods in the interface.
/// </para>
/// <para>
/// In implementing the <c>IAudioSessionEvents</c> interface, the client should observe these rules to avoid deadlocks and undefined behavior:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>
/// The methods in the interface must be nonblocking. The client should never wait on a synchronization object during an event callback.
/// </term>
/// </item>
/// <item>
/// <term>The client should never call the IAudioSessionControl::UnregisterAudioSessionNotification method during an event callback.</term>
/// </item>
/// <item>
/// <term>The client should never release the final reference on a WASAPI object during an event callback.</term>
/// </item>
/// </list>
/// <para>
/// For a code example that implements an <c>IAudioSessionEvents</c> interface, see Audio Session Events. For a code example that
/// registers a client's <c>IAudioSessionEvents</c> interface to receive notifications, see Audio Events for Legacy Audio Applications.
/// </para>
/// </summary>
// https://docs.microsoft.com/en-us/windows/win32/api/audiopolicy/nn-audiopolicy-iaudiosessionevents
[PInvokeData("audiopolicy.h", MSDNShortId = "fd287ef7-8a37-4342-b4c2-79b84a56c30e")]
[ComImport, Guid("24918ACC-64B3-37C1-8CA9-74A66E9957A8"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IAudioSessionEvents
{
/// <summary>The <c>OnDisplayNameChanged</c> method notifies the client that the display name for the session has changed.</summary>
/// <param name="NewDisplayName">
/// The new display name for the session. This parameter points to a null-terminated, wide-character string containing the new
/// display name. The string remains valid for the duration of the call.
/// </param>
/// <param name="EventContext">
/// The event context value. This is the same value that the caller passed to IAudioSessionControl::SetDisplayName in the call
/// that changed the display name for the session. For more information, see Remarks.
/// </param>
/// <returns>If the method succeeds, it returns S_OK. If it fails, it returns an error code.</returns>
/// <remarks>
/// <para>
/// The session manager calls this method each time a call to the IAudioSessionControl::SetDisplayName method changes the
/// display name of the session. The Sndvol program uses a session's display name to label the volume slider for the session.
/// </para>
/// <para>
/// The EventContext parameter provides a means for a client to distinguish between a display-name change that it initiated and
/// one that some other client initiated. When calling the IAudioSessionControl::SetDisplayName method, a client passes in an
/// EventContext parameter value that its implementation of the <c>OnDisplayNameChanged</c> method can recognize.
/// </para>
/// <para>For a code example that implements the methods in the IAudioSessionEvents interface, see Audio Session Events.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/audiopolicy/nf-audiopolicy-iaudiosessionevents-ondisplaynamechanged
// HRESULT OnDisplayNameChanged( LPCWSTR NewDisplayName, LPCGUID EventContext );
[PreserveSig]
HRESULT OnDisplayNameChanged([MarshalAs(UnmanagedType.LPWStr)] string NewDisplayName, in Guid EventContext);
/// <summary>The <c>OnIconPathChanged</c> method notifies the client that the display icon for the session has changed.</summary>
/// <param name="NewIconPath">
/// The path for the new display icon for the session. This parameter points to a string that contains the path for the new
/// icon. The string pointer remains valid only for the duration of the call.
/// </param>
/// <param name="EventContext">
/// The event context value. This is the same value that the caller passed to IAudioSessionControl::SetIconPath in the call that
/// changed the display icon for the session. For more information, see Remarks.
/// </param>
/// <returns>If the method succeeds, it returns S_OK. If it fails, it returns an error code.</returns>
/// <remarks>
/// <para>
/// The session manager calls this method each time a call to the IAudioSessionControl::SetIconPath method changes the display
/// icon for the session. The Sndvol program uses a session's display icon to label the volume slider for the session.
/// </para>
/// <para>
/// The EventContext parameter provides a means for a client to distinguish between a display-icon change that it initiated and
/// one that some other client initiated. When calling the IAudioSessionControl::SetIconPath method, a client passes in an
/// EventContext parameter value that its implementation of the <c>OnIconPathChanged</c> method can recognize.
/// </para>
/// <para>For a code example that implements the methods in the IAudioSessionEvents interface, see Audio Session Events.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/audiopolicy/nf-audiopolicy-iaudiosessionevents-oniconpathchanged HRESULT
// OnIconPathChanged( LPCWSTR NewIconPath, LPCGUID EventContext );
[PreserveSig]
HRESULT OnIconPathChanged([MarshalAs(UnmanagedType.LPWStr)] string NewIconPath, in Guid EventContext);
/// <summary>
/// The <c>OnSimpleVolumeChanged</c> method notifies the client that the volume level or muting state of the audio session has changed.
/// </summary>
/// <param name="NewVolume">
/// The new volume level for the audio session. This parameter is a value in the range 0.0 to 1.0, where 0.0 is silence and 1.0
/// is full volume (no attenuation).
/// </param>
/// <param name="NewMute">The new muting state. If <c>TRUE</c>, muting is enabled. If <c>FALSE</c>, muting is disabled.</param>
/// <param name="EventContext">
/// The event context value. This is the same value that the caller passed to ISimpleAudioVolume::SetMasterVolume or
/// ISimpleAudioVolume::SetMute in the call that changed the volume level or muting state of the session. For more information,
/// see Remarks.
/// </param>
/// <returns>If the method succeeds, it returns S_OK. If it fails, it returns an error code.</returns>
/// <remarks>
/// <para>
/// The session manager calls this method each time a call to the ISimpleAudioVolume::SetMasterVolume or
/// ISimpleAudioVolume::SetMute method changes the volume level or muting state of the session.
/// </para>
/// <para>
/// The EventContext parameter provides a means for a client to distinguish between a volume or mute change that it initiated
/// and one that some other client initiated. When calling the ISimpleAudioVolume::SetMasterVolume or
/// ISimpleAudioVolume::SetMute method, a client passes in an EventContext parameter value that its implementation of the
/// <c>OnSimpleVolumeChanged</c> method can recognize.
/// </para>
/// <para>For a code example that implements the methods in the IAudioSessionEvents interface, see Audio Session Events.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/audiopolicy/nf-audiopolicy-iaudiosessionevents-onsimplevolumechanged
// HRESULT OnSimpleVolumeChanged( float NewVolume, BOOL NewMute, LPCGUID EventContext );
[PreserveSig]
HRESULT OnSimpleVolumeChanged([In] float NewVolume, [MarshalAs(UnmanagedType.Bool)] bool NewMute, in Guid EventContext);
/// <summary>
/// The <c>OnChannelVolumeChanged</c> method notifies the client that the volume level of an audio channel in the session submix
/// has changed.
/// </summary>
/// <param name="ChannelCount">The channel count. This parameter specifies the number of audio channels in the session submix.</param>
/// <param name="NewChannelVolumeArray">
/// Pointer to an array of volume levels. Each element is a value of type <c>float</c> that specifies the volume level for a
/// particular channel. Each volume level is a value in the range 0.0 to 1.0, where 0.0 is silence and 1.0 is full volume (no
/// attenuation). The number of elements in the array is specified by the ChannelCount parameter. If an audio stream contains n
/// channels, the channels are numbered from 0 to n 1. The array element whose index matches the channel number, contains the
/// volume level for that channel. Assume that the array remains valid only for the duration of the call.
/// </param>
/// <param name="ChangedChannel">
/// The number of the channel whose volume level changed. Use this value as an index into the NewChannelVolumeArray array. If
/// the session submix contains n channels, the channels are numbered from 0 to n 1. If more than one channel might have
/// changed (for example, as a result of a call to the IChannelAudioVolume::SetAllVolumes method), the value of ChangedChannel
/// is ( <c>DWORD</c>)(1).
/// </param>
/// <param name="EventContext">
/// The event context value. This is the same value that the caller passed to the IChannelAudioVolume::SetChannelVolume or
/// <c>IChannelAudioVolume::SetAllVolumes</c> method in the call that initiated the change in volume level of the channel. For
/// more information, see Remarks.
/// </param>
/// <returns>If the method succeeds, it returns S_OK. If it fails, it returns an error code.</returns>
/// <remarks>
/// <para>
/// The session manager calls this method each time a call to the <c>IChannelAudioVolume::SetChannelVolume</c> or
/// <c>IChannelAudioVolume::SetAllVolumes</c> method successfully updates the volume level of one or more channels in the
/// session submix. Note that the <c>OnChannelVolumeChanged</c> call occurs regardless of whether the new channel volume level
/// or levels differ in value from the previous channel volume level or levels.
/// </para>
/// <para>
/// The EventContext parameter provides a means for a client to distinguish between a channel-volume change that it initiated
/// and one that some other client initiated. When calling the <c>IChannelAudioVolume::SetChannelVolume</c> or
/// <c>IChannelAudioVolume::SetAllVolumes</c> method, a client passes in an EventContext parameter value that its implementation
/// of the <c>OnChannelVolumeChanged</c> method can recognize.
/// </para>
/// <para>For a code example that implements the methods in the <c>IAudioSessionEvents</c> interface, see Audio Session Events.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/audiopolicy/nf-audiopolicy-iaudiosessionevents-onchannelvolumechanged
// HRESULT OnChannelVolumeChanged( DWORD ChannelCount, float [] NewChannelVolumeArray, DWORD ChangedChannel, LPCGUID
// EventContext );
[PreserveSig]
HRESULT OnChannelVolumeChanged(uint ChannelCount, [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] float[] NewChannelVolumeArray, uint ChangedChannel, in Guid EventContext);
/// <summary>
/// The <c>OnGroupingParamChanged</c> method notifies the client that the grouping parameter for the session has changed.
/// </summary>
/// <param name="NewGroupingParam">
/// The new grouping parameter for the session. This parameter points to a grouping-parameter GUID.
/// </param>
/// <param name="EventContext">
/// The event context value. This is the same value that the caller passed to IAudioSessionControl::SetGroupingParam in the call
/// that changed the grouping parameter for the session. For more information, see Remarks.
/// </param>
/// <returns>If the method succeeds, it returns S_OK. If it fails, it returns an error code.</returns>
/// <remarks>
/// <para>
/// The session manager calls this method each time a call to the IAudioSessionControl::SetGroupingParam method changes the
/// grouping parameter for the session.
/// </para>
/// <para>
/// The EventContext parameter provides a means for a client to distinguish between a grouping-parameter change that it
/// initiated and one that some other client initiated. When calling the IAudioSessionControl::SetGroupingParam method, a client
/// passes in an EventContext parameter value that its implementation of the <c>OnGroupingParamChanged</c> method can recognize.
/// </para>
/// <para>For a code example that implements the methods in the IAudioSessionEvents interface, see Audio Session Events.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/audiopolicy/nf-audiopolicy-iaudiosessionevents-ongroupingparamchanged
// HRESULT OnGroupingParamChanged( LPCGUID NewGroupingParam, LPCGUID EventContext );
[PreserveSig]
HRESULT OnGroupingParamChanged(in Guid NewGroupingParam, in Guid EventContext);
/// <summary>The <c>OnStateChanged</c> method notifies the client that the stream-activity state of the session has changed.</summary>
/// <param name="NewState">
/// <para>The new session state. The value of this parameter is one of the following AudioSessionState enumeration values:</para>
/// <para>AudioSessionStateActive</para>
/// <para>AudioSessionStateInactive</para>
/// <para>AudioSessionStateExpired</para>
/// </param>
/// <returns>If the method succeeds, it returns S_OK. If it fails, it returns an error code.</returns>
/// <remarks>
/// <para>
/// A client cannot generate a session-state-change event. The system is always the source of this type of event. Thus, unlike
/// some other IAudioSessionEvents methods, this method does not supply a context parameter.
/// </para>
/// <para>
/// The system changes the state of a session from inactive to active at the time that a client opens the first stream in the
/// session. A client opens a stream by calling the IAudioClient::Initialize method. The system changes the session state from
/// active to inactive at the time that a client closes the last stream in the session. The client that releases the last
/// reference to an IAudioClient object closes the stream that is associated with the object.
/// </para>
/// <para>For a code example that implements the methods in the IAudioSessionEvents interface, see Audio Session Events.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/audiopolicy/nf-audiopolicy-iaudiosessionevents-onstatechanged HRESULT
// OnStateChanged( AudioSessionState NewState );
[PreserveSig]
HRESULT OnStateChanged(AudioSessionState NewState);
/// <summary>The <c>OnSessionDisconnected</c> method notifies the client that the audio session has been disconnected.</summary>
/// <param name="DisconnectReason">
/// <para>
/// The reason that the audio session was disconnected. The caller sets this parameter to one of the
/// <c>AudioSessionDisconnectReason</c> enumeration values shown in the following table.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>DisconnectReasonDeviceRemoval</term>
/// <term>The user removed the audio endpoint device.</term>
/// </item>
/// <item>
/// <term>DisconnectReasonServerShutdown</term>
/// <term>The Windows audio service has stopped.</term>
/// </item>
/// <item>
/// <term>DisconnectReasonFormatChanged</term>
/// <term>The stream format changed for the device that the audio session is connected to.</term>
/// </item>
/// <item>
/// <term>DisconnectReasonSessionLogoff</term>
/// <term>The user logged off the Windows Terminal Services (WTS) session that the audio session was running in.</term>
/// </item>
/// <item>
/// <term>DisconnectReasonSessionDisconnected</term>
/// <term>The WTS session that the audio session was running in was disconnected.</term>
/// </item>
/// <item>
/// <term>DisconnectReasonExclusiveModeOverride</term>
/// <term>
/// The (shared-mode) audio session was disconnected to make the audio endpoint device available for an exclusive-mode connection.
/// </term>
/// </item>
/// </list>
/// <para>For more information about WTS sessions, see the Windows SDK documentation.</para>
/// </param>
/// <returns>If the method succeeds, it returns S_OK. If it fails, it returns an error code.</returns>
/// <remarks>
/// <para>
/// When disconnecting a session, the session manager closes the streams that belong to that session and invalidates all
/// outstanding requests for services on those streams. The client should respond to a disconnection by releasing all of its
/// references to the IAudioClient interface for a closed stream and releasing all references to the service interfaces that it
/// obtained previously through calls to the IAudioClient::GetService method.
/// </para>
/// <para>
/// Following disconnection, many of the methods in the WASAPI interfaces that are tied to closed streams in the disconnected
/// session return error code AUDCLNT_E_DEVICE_INVALIDATED (for example, see IAudioClient::GetCurrentPadding). For information
/// about recovering from this error, see Recovering from an Invalid-Device Error.
/// </para>
/// <para>
/// If the Windows audio service terminates unexpectedly, it does not have an opportunity to notify clients that it is shutting
/// down. In that case, clients learn that the service has stopped when they call a method such as
/// IAudioClient::GetCurrentPadding that discovers that the service is no longer running and fails with error code AUDCLNT_E_SERVICE_NOT_RUNNING.
/// </para>
/// <para>
/// A client cannot generate a session-disconnected event. The system is always the source of this type of event. Thus, unlike
/// some other IAudioSessionEvents methods, this method does not have a context parameter.
/// </para>
/// <para>For a code example that implements the methods in the IAudioSessionEvents interface, see Audio Session Events.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/audiopolicy/nf-audiopolicy-iaudiosessionevents-onsessiondisconnected
// HRESULT OnSessionDisconnected( AudioSessionDisconnectReason DisconnectReason );
[PreserveSig]
HRESULT OnSessionDisconnected([In] AudioSessionDisconnectReason DisconnectReason);
}
/// <summary>
/// <para>
/// The <c>IAudioSessionManager</c> interface enables a client to access the session controls and volume controls for both
/// cross-process and process-specific audio sessions. The client obtains a reference to an <c>IAudioSessionManager</c> interface by
/// calling the IMMDevice::Activate method with parameter iid set to <c>REFIID</c> IID_IAudioSessionManager.
/// </para>
/// <para>
/// This interface enables clients to access the controls for an existing session without first opening a stream. This capability is
/// useful for clients of higher-level APIs that are built on top of WASAPI and use session controls internally but do not give
/// their clients access to session controls.
/// </para>
/// <para>
/// In Windows Vista, the higher-level APIs that use WASAPI include Media Foundation, DirectSound, the Windows multimedia
/// <c>waveInXxx</c>, <c>waveOutXxx</c>, and <c>mciXxx</c> functions, and third-party APIs.
/// </para>
/// <para>
/// When a client creates an audio stream through a higher-level API, that API typically adds the stream to the default audio
/// session for the client's process (the session that is identified by the session GUID value, GUID_NULL), but the same API might
/// not provide a means for the client to access the controls for that session. In that case, the client can access the controls
/// through the <c>IAudioSessionManager</c> interface.
/// </para>
/// <para>For a code example that uses the <c>IAudioSessionManager</c> interface, see Audio Events for Legacy Audio Applications.</para>
/// </summary>
// https://docs.microsoft.com/en-us/windows/win32/api/audiopolicy/nn-audiopolicy-iaudiosessionmanager
[PInvokeData("audiopolicy.h", MSDNShortId = "606b0a42-d1d1-4196-911f-5b095bf56c4e")]
[ComImport, Guid("BFA971F1-4D5E-40BB-935E-967039BFBEE4"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IAudioSessionManager
{
/// <summary>The <c>GetAudioSessionControl</c> method retrieves an audio session control.</summary>
/// <param name="AudioSessionGuid">
/// Pointer to a session GUID. If the GUID does not identify a session that has been previously opened, the call opens a new but
/// empty session. The Sndvol program does not display a volume-level control for a session unless it contains one or more
/// active streams. If this parameter is <c>NULL</c> or points to the value GUID_NULL, the method assigns the stream to the
/// default session.
/// </param>
/// <param name="StreamFlags">Specifies the status of the flags for the audio stream.</param>
/// <returns>
/// A pointer to the IAudioSessionControl interface of the audio session control object. The caller is responsible for releasing
/// the interface, when it is no longer needed, by calling the interface's <c>Release</c> method. If the call fails,
/// *SessionControl is <c>NULL</c>.
/// </returns>
/// <remarks>For a code example that calls this method, see Audio Events for Legacy Audio Applications.</remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/audiopolicy/nf-audiopolicy-iaudiosessionmanager-getaudiosessioncontrol
// HRESULT GetAudioSessionControl( LPCGUID AudioSessionGuid, DWORD StreamFlags, IAudioSessionControl **SessionControl );
IAudioSessionControl GetAudioSessionControl([In, Optional] in Guid AudioSessionGuid, [In] AUDCLNT_STREAMFLAGS StreamFlags);
/// <summary>The <c>GetSimpleAudioVolume</c> method retrieves a simple audio volume control.</summary>
/// <param name="AudioSessionGuid">
/// Pointer to a session GUID. If the GUID does not identify a session that has been previously opened, the call opens a new but
/// empty session. The Sndvol program does not display a volume-level control for a session unless it contains one or more
/// active streams. If this parameter is <c>NULL</c> or points to the value GUID_NULL, the method assigns the stream to the
/// default session.
/// </param>
/// <param name="StreamFlags">
/// Specifies whether the request is for a cross-process session. Set to <c>TRUE</c> if the session is cross-process. Set to
/// <c>FALSE</c> if the session is not cross-process.
/// </param>
/// <returns>
/// Pointer to a pointer variable into which the method writes a pointer to the ISimpleAudioVolume interface of the audio volume
/// control object. This interface represents the simple audio volume control for the current process. The caller is responsible
/// for releasing the interface, when it is no longer needed, by calling the interface's <c>Release</c> method. If the
/// <c>Activate</c> call fails, *AudioVolume is <c>NULL</c>.
/// </returns>
// https://docs.microsoft.com/en-us/windows/win32/api/audiopolicy/nf-audiopolicy-iaudiosessionmanager-getsimpleaudiovolume
// HRESULT GetSimpleAudioVolume( LPCGUID AudioSessionGuid, DWORD StreamFlags, ISimpleAudioVolume **AudioVolume );
ISimpleAudioVolume GetSimpleAudioVolume([In, Optional] in Guid AudioSessionGuid, [In] AUDCLNT_STREAMFLAGS StreamFlags);
}
/// <summary>
/// <para>The <c>IAudioSessionManager2</c> interface enables an application to manage submixes for the audio device.</para>
/// <para>
/// To a get a reference to an <c>IAudioSessionManager2</c> interface, the application must activate it on the audio device by
/// following these steps:
/// </para>
/// <list type="number">
/// <item>
/// <term>
/// Use one of the techniques described on the IMMDevice interface page to obtain a reference to the <c>IMMDevice</c> interface for
/// an audio endpoint device.
/// </term>
/// </item>
/// <item>
/// <term>Call the IMMDevice::Activate method with parameter iid set to IID_IAudioSessionManager2.</term>
/// </item>
/// </list>
/// <para>
/// When the application wants to release the <c>IAudioSessionManager2</c> interface instance, the application must call the
/// interface's <c>Release</c> method.
/// </para>
/// <para>
/// The application thread that uses this interface must be initialized for COM. For more information about COM initialization, see
/// the description of the <c>CoInitializeEx</c> function in the Windows SDK documentation.
/// </para>
/// </summary>
/// <remarks>
/// <para>An application can use this interface to perform the following tasks:</para>
/// <list type="bullet">
/// <item>
/// <term>Register to receive ducking notifications.</term>
/// </item>
/// <item>
/// <term>Register to receive a notification when a session is created.</term>
/// </item>
/// <item>
/// <term>Enumerate sessions on the audio device that was used to get the interface pointer.</term>
/// </item>
/// </list>
/// <para>
/// This interface supports custom implementations for stream attenuation or ducking, a new feature in Windows 7. An application
/// playing a media stream can make the it behave differently when a new communication stream is opened on the default communication
/// device. For example, the original media stream can be paused while the new communication stream is open. For more information
/// about this feature, see Using a Communication Device.
/// </para>
/// <para>
/// An application that manages the media streams and wants to provide a custom ducking implementation, must register to receive
/// notifications when session events occur. For stream attenuation, a session event is raised by the system when a communication
/// stream is opened or closed on the default communication device. For more information, see Providing a Custom Ducking Behavior.
/// </para>
/// <para>Examples</para>
/// <para>The following example code shows how to get a reference to the <c>IAudioSessionManager2</c> interface of the audio device.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/audiopolicy/nn-audiopolicy-iaudiosessionmanager2
[PInvokeData("audiopolicy.h", MSDNShortId = "476dac90-d0c4-499c-973e-33ea55546659")]
[ComImport, Guid("77AA99A0-1BD6-484F-8BC7-2C654C9A9B6F"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IAudioSessionManager2 : IAudioSessionManager
{
/// <summary>The <c>GetAudioSessionControl</c> method retrieves an audio session control.</summary>
/// <param name="AudioSessionGuid">
/// Pointer to a session GUID. If the GUID does not identify a session that has been previously opened, the call opens a new but
/// empty session. The Sndvol program does not display a volume-level control for a session unless it contains one or more
/// active streams. If this parameter is <c>NULL</c> or points to the value GUID_NULL, the method assigns the stream to the
/// default session.
/// </param>
/// <param name="StreamFlags">Specifies the status of the flags for the audio stream.</param>
/// <returns>
/// A pointer to the IAudioSessionControl interface of the audio session control object. The caller is responsible for releasing
/// the interface, when it is no longer needed, by calling the interface's <c>Release</c> method. If the call fails,
/// *SessionControl is <c>NULL</c>.
/// </returns>
/// <remarks>For a code example that calls this method, see Audio Events for Legacy Audio Applications.</remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/audiopolicy/nf-audiopolicy-iaudiosessionmanager-getaudiosessioncontrol
// HRESULT GetAudioSessionControl( LPCGUID AudioSessionGuid, DWORD StreamFlags, IAudioSessionControl **SessionControl );
new IAudioSessionControl GetAudioSessionControl([In, Optional] in Guid AudioSessionGuid, [In] AUDCLNT_STREAMFLAGS StreamFlags);
/// <summary>The <c>GetSimpleAudioVolume</c> method retrieves a simple audio volume control.</summary>
/// <param name="AudioSessionGuid">
/// Pointer to a session GUID. If the GUID does not identify a session that has been previously opened, the call opens a new but
/// empty session. The Sndvol program does not display a volume-level control for a session unless it contains one or more
/// active streams. If this parameter is <c>NULL</c> or points to the value GUID_NULL, the method assigns the stream to the
/// default session.
/// </param>
/// <param name="StreamFlags">
/// Specifies whether the request is for a cross-process session. Set to <c>TRUE</c> if the session is cross-process. Set to
/// <c>FALSE</c> if the session is not cross-process.
/// </param>
/// <returns>
/// Pointer to a pointer variable into which the method writes a pointer to the ISimpleAudioVolume interface of the audio volume
/// control object. This interface represents the simple audio volume control for the current process. The caller is responsible
/// for releasing the interface, when it is no longer needed, by calling the interface's <c>Release</c> method. If the
/// <c>Activate</c> call fails, *AudioVolume is <c>NULL</c>.
/// </returns>
// https://docs.microsoft.com/en-us/windows/win32/api/audiopolicy/nf-audiopolicy-iaudiosessionmanager-getsimpleaudiovolume
// HRESULT GetSimpleAudioVolume( LPCGUID AudioSessionGuid, DWORD StreamFlags, ISimpleAudioVolume **AudioVolume );
new ISimpleAudioVolume GetSimpleAudioVolume([In, Optional] in Guid AudioSessionGuid, [In] AUDCLNT_STREAMFLAGS StreamFlags);
/// <summary>The <c>GetSessionEnumerator</c> method gets a pointer to the audio session enumerator object.</summary>
/// <returns>
/// Receives a pointer to the IAudioSessionEnumerator interface of the session enumerator object that the client can use to
/// enumerate audio sessions on the audio device. Through this method, the caller obtains a counted reference to the interface.
/// The caller is responsible for releasing the interface, when it is no longer needed, by calling the interface's
/// <c>Release</c> method.
/// </returns>
/// <remarks>
/// <para>
/// The session manager maintains a collection of audio sessions that are active on the audio device by querying the audio
/// engine. <c>GetSessionEnumerator</c> creates a session control for each session in the collection. To get a reference to the
/// IAudioSessionControl interface of the session in the enumerated collection, the application must call
/// IAudioSessionEnumerator::GetSession. For a code example, see IAudioSessionEnumerator Interface.
/// </para>
/// <para>
/// The session enumerator might not be aware of the new sessions that are reported through IAudioSessionNotification. So if an
/// application exclusively relies on the session enumerator for getting all the sessions for an audio endpoint, the results
/// might not be accurate. To work around this, the application should manually maintain a list. For more information, see IAudioSessionEnumerator.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/audiopolicy/nf-audiopolicy-iaudiosessionmanager2-getsessionenumerator
// HRESULT GetSessionEnumerator( IAudioSessionEnumerator **SessionEnum );
IAudioSessionEnumerator GetSessionEnumerator();
/// <summary>
/// The <c>RegisterSessionNotification</c> method registers the application to receive a notification when a session is created.
/// </summary>
/// <param name="SessionNotification">
/// A pointer to the application's implementation of the IAudioSessionNotification interface. If the method call succeeds, it
/// calls the <c>AddRef</c> method on the application's <c>IAudioSessionNotification</c> interface.
/// </param>
/// <remarks>
/// <para>
/// The application can register to receive a notification when a session is created, through the methods of the
/// IAudioSessionNotification interface. The application implements the <c>IAudioSessionNotification</c> interface. The methods
/// defined in this interface receive callbacks from the system when a session is created. For example code that shows how to
/// implement this interface, see
/// </para>
/// <para>IAudioSessionNotification Interface.</para>
/// <para>
/// To begin receiving notifications, the application calls the <c>IAudioSessionManager2::RegisterSessionNotification</c> method
/// to register its IAudioSessionNotification interface. When the application no longer requires notifications, it calls the
/// IAudioSessionManager2::UnregisterSessionNotification method to delete the registration.
/// </para>
/// <para>
/// <c>Note</c> Make sure that the application initializes COM with Multithreaded Apartment (MTA) model by calling in a non-UI
/// thread. If MTA is not initialized, the application does not receive session notifications from the session manager. Threads
/// that run the user interface of an application should be initialized apartment threading model.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/audiopolicy/nf-audiopolicy-iaudiosessionmanager2-registersessionnotification
// HRESULT RegisterSessionNotification( IAudioSessionNotification *SessionNotification );
void RegisterSessionNotification(IAudioSessionNotification SessionNotification);
/// <summary>
/// The <c>UnregisterSessionNotification</c> method deletes the registration to receive a notification when a session is created.
/// </summary>
/// <param name="SessionNotification">
/// <para>
/// A pointer to the application's implementation of the IAudioSessionNotification interface. Pass the same interface pointer
/// that was specified to the session manager in a previous call to IAudioSessionManager2::RegisterSessionNotification to
/// register for notification.
/// </para>
/// <para>
/// If the <c>UnregisterSessionNotification</c> method succeeds, it calls the <c>Release</c> method on the application's
/// IAudioSessionNotification interface.
/// </para>
/// </param>
/// <remarks>
/// The application calls this method when it no longer needs to receive notifications. The <c>UnregisterSessionNotification</c>
/// method removes the registration of an IAudioSessionNotification interface that the application previously registered with
/// the session manager by calling the IAudioSessionControl::RegisterAudioSessionNotification method.
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/audiopolicy/nf-audiopolicy-iaudiosessionmanager2-unregistersessionnotification
// HRESULT UnregisterSessionNotification( IAudioSessionNotification *SessionNotification );
void UnregisterSessionNotification(IAudioSessionNotification SessionNotification);
/// <summary>
/// The <c>RegisterDuckNotification</c> method registers the application with the session manager to receive ducking notifications.
/// </summary>
/// <param name="sessionID">
/// <para>
/// Pointer to a null-terminated string that contains a session instance identifier. Applications that are playing a media
/// stream and want to provide custom stream attenuation or ducking behavior, pass their own session instance identifier. For
/// more information, see Remarks.
/// </para>
/// <para>
/// Other applications that do not want to alter their streams but want to get all the ducking notifications must pass <c>NULL</c>.
/// </para>
/// </param>
/// <param name="duckNotification">
/// Pointer to the application's implementation of the IAudioVolumeDuckNotification interface. The implementation is called when
/// ducking events are raised by the audio system and notifications are sent to the registered applications.
/// </param>
/// <remarks>
/// <para>
/// Stream Attenuation or ducking is a new feature in Windows 7. An application playing a media stream can make the stream
/// behave differently when a new communication stream is opened on the default communication device. For example, the original
/// media stream can be paused while the new communication stream is open. To provide this custom implementation for stream
/// attenuation, the application can opt out of the default stream attenuation experience by calling
/// IAudioSessionControl::SetDuckingPreference and then register itself to receive notifications when session events occur. For
/// stream attenuation, a session event is raised by the system when a communication stream is opened or closed on the default
/// communication device. For more information about this feature, see Getting Ducking Events.
/// </para>
/// <para>
/// To begin receiving notifications, the application calls the <c>RegisterDuckNotification</c> method to register its
/// IAudioVolumeDuckNotification interface with the session manager. When the application no longer requires notifications, it
/// calls the IAudioSessionManager2::UnregisterDuckNotification method to delete the registration.
/// </para>
/// <para>
/// The application receives notifications about the ducking events through the methods of the IAudioVolumeDuckNotification
/// interface. The application implements <c>IAudioVolumeDuckNotification</c>. After the registration call has succeeded, the
/// system calls the methods of this interface when session events occur.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/audiopolicy/nf-audiopolicy-iaudiosessionmanager2-registerducknotification
// HRESULT RegisterDuckNotification( LPCWSTR sessionID, IAudioVolumeDuckNotification *duckNotification );
void RegisterDuckNotification([MarshalAs(UnmanagedType.LPWStr)] string sessionID, [In] IAudioVolumeDuckNotification duckNotification);
/// <summary>The <c>UnregisterDuckNotification</c> method deletes a previous registration by the application to receive notifications.</summary>
/// <param name="duckNotification">
/// Pointer to the IAudioVolumeDuckNotification interface that is implemented by the application. Pass the same interface
/// pointer that was specified to the session manager in a previous call to the IAudioSessionManager2::RegisterDuckNotification
/// method. If the <c>UnregisterDuckNotification</c> method succeeds, it calls the <c>Release</c> method on the application's
/// <c>IAudioVolumeDuckNotification</c> interface.
/// </param>
/// <remarks>
/// <para>
/// The application calls this method when it no longer needs to receive notifications. The <c>UnregisterDuckNotification</c>
/// method removes the registration of an IAudioVolumeDuckNotification interface that the application previously registered with
/// the session manager by calling the IAudioSessionManager2::RegisterDuckNotification method.
/// </para>
/// <para>After the application calls <c>UnregisterDuckNotification</c>, any pending events are not reported to the application.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/audiopolicy/nf-audiopolicy-iaudiosessionmanager2-unregisterducknotification
// HRESULT UnregisterDuckNotification( IAudioVolumeDuckNotification *duckNotification );
void UnregisterDuckNotification([In] IAudioVolumeDuckNotification duckNotification);
}
/// <summary>The <c>IAudioSessionNotification</c> interface provides notification when an audio session is created.</summary>
/// <remarks>
/// <para>
/// Unlike the other WASAPI interfaces, which are implemented by the WASAPI system component, the <c>IAudioSessionNotification</c>
/// interface is implemented by the application. To receive event notifications, the application passes to the
/// IAudioSessionManager2::RegisterSessionNotification method a pointer to its <c>IAudioSessionNotification</c> implementation .
/// </para>
/// <para>
/// After registering its <c>IAudioSessionNotification</c> interface, the application receives event notifications in the form of
/// callbacks through the methods in the interface.
/// </para>
/// <para>
/// When the application no longer needs to receive notifications, it calls the IAudioSessionManager2::UnregisterSessionNotification
/// method. This method removes the registration of an <c>IAudioSessionNotification</c> interface that the application previously registered.
/// </para>
/// <para>The application must not register or unregister notification callbacks during an event callback.</para>
/// <para>
/// The session enumerator might not be aware of the new sessions that are reported through <c>IAudioSessionNotification</c>. So if
/// an application exclusively relies on the session enumerator for getting all the sessions for an audio endpoint, the results
/// might not be accurate. To work around this, the application should manually maintain a list. For more information, see IAudioSessionEnumerator.
/// </para>
/// <para>
/// <c>Note</c> Make sure that the application initializes COM with Multithreaded Apartment (MTA) model by calling in a non-UI
/// thread. If MTA is not initialized, the application does not receive session notifications from the session manager. Threads that
/// run the user interface of an application should be initialized apartment threading model.
/// </para>
/// <para>Examples</para>
/// <para>The following code example shows a sample implementation of the <c>IAudioSessionNotification</c> interface.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/audiopolicy/nn-audiopolicy-iaudiosessionnotification
[PInvokeData("audiopolicy.h", MSDNShortId = "69222168-87d7-4f5a-93b1-6d91263a54bd")]
[ComImport, Guid("641DD20B-4D41-49CC-ABA3-174B9477BB08"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IAudioSessionNotification
{
/// <summary>The <c>OnSessionCreated</c> method notifies the registered processes that the audio session has been created.</summary>
/// <param name="NewSession">Pointer to the IAudioSessionControl interface of the audio session that was created.</param>
/// <returns>If the method succeeds, it returns S_OK.</returns>
/// <remarks>
/// <para>
/// After registering its IAudioSessionNotification interface, the application receives event notifications in the form of
/// callbacks through the methods of the interface.
/// </para>
/// <para>
/// The audio engine calls <c>OnSessionCreated</c> when a new session is activated on the device endpoint. This method is called
/// from the session manager thread. This method must take a reference to the session in the NewSession parameter if it wants to
/// keep the reference after this call completes.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/audiopolicy/nf-audiopolicy-iaudiosessionnotification-onsessioncreated
// HRESULT OnSessionCreated( IAudioSessionControl *NewSession );
HRESULT OnSessionCreated(IAudioSessionControl NewSession);
}
/// <summary>
/// The <c>IAudioVolumeDuckNotification</c> interface is used to by the system to send notifications about stream attenuation
/// changes.Stream Attenuation, or ducking, is a feature introduced in Windows 7, where the system adjusts the volume of a
/// non-communication stream when a new communication stream is opened. For more information about this feature, see Default Ducking Experience.
/// </summary>
/// <remarks>
/// <para>
/// If an application needs to opt out of the system attenuation experience provided by the system, it must call
/// IAudioSessionControl2::SetDuckingPreference and specify that preference.
/// </para>
/// <para>
/// Unlike the other WASAPI interfaces, which are implemented by the WASAPI system component, the
/// <c>IAudioVolumeDuckNotification</c> interface is implemented by the application to provide custom stream attenuation behavior.
/// To receive event notifications, the application passes to the IAudioSessionManager2::RegisterDuckNotification method a pointer
/// to the application's implementation of <c>IAudioVolumeDuckNotification</c>.
/// </para>
/// <para>
/// After the application has registered its <c>IAudioVolumeDuckNotification</c> interface, the session manager calls the
/// <c>IAudioVolumeDuckNotification</c> implementation when it needs to send ducking notifications. The application receives event
/// notifications in the form of callbacks through the methods of the interface.
/// </para>
/// <para>
/// When the application no longer needs to receive notifications, it calls the IAudioSessionManager2::UnregisterDuckNotification
/// method. The <c>UnregisterDuckNotification</c> method removes the registration of an <c>IAudioVolumeDuckNotification</c>
/// interface that the application previously registered.
/// </para>
/// <para>The application must not register or unregister notification callbacks during an event callback.</para>
/// <para>For more information, see Implementation Considerations for Ducking Notifications.</para>
/// <para>Examples</para>
/// <para>The following example code shows a sample implementation of the <c>IAudioVolumeDuckNotification</c> interface.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/audiopolicy/nn-audiopolicy-iaudiovolumeducknotification
[PInvokeData("audiopolicy.h", MSDNShortId = "08e90a50-a6ac-4405-ba90-a862b78efaf8")]
[ComImport, Guid("C3B284D4-6D39-4359-B3CF-B56DDB3BB39C"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IAudioVolumeDuckNotification
{
/// <summary>
/// The <c>OnVolumeDuckNotification</c> method sends a notification about a pending system ducking event. For more information,
/// see Implementation Considerations for Ducking Notifications.
/// </summary>
/// <param name="sessionID">
/// A string containing the session instance identifier of the communications session that raises the the auto-ducking event. To
/// get the session instance identifier, call IAudioSessionControl2::GetSessionInstanceIdentifier.
/// </param>
/// <param name="countCommunicationSessions">
/// The number of active communications sessions. If there are n sessions, the sessions are numbered from 0 to 1.
/// </param>
/// <returns>If the method succeeds, it returns S_OK.</returns>
/// <remarks>
/// After the application registers its implementation of the IAudioVolumeDuckNotification interface by calling
/// IAudioSessionManager2::RegisterDuckNotification, the session manager calls <c>OnVolumeDuckNotification</c> when it wants to
/// send a notification about when ducking begins. The application receives the event notifications in the form of callbacks.
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/audiopolicy/nf-audiopolicy-iaudiovolumeducknotification-onvolumeducknotification
// HRESULT OnVolumeDuckNotification( LPCWSTR sessionID, UINT32 countCommunicationSessions );
HRESULT OnVolumeDuckNotification([MarshalAs(UnmanagedType.LPWStr)] string sessionID, uint countCommunicationSessions);
/// <summary>
/// The <c>OnVolumeUnduckNotification</c> method sends a notification about a pending system unducking event. For more
/// information, see Implementation Considerations for Ducking Notifications.
/// </summary>
/// <param name="sessionID">
/// A string containing the session instance identifier of the terminating communications session that intiated the ducking. To
/// get the session instance identifier, call IAudioSessionControl2::GetSessionInstanceIdentifier.
/// </param>
/// <returns>If the method succeeds, it returns S_OK.</returns>
/// <remarks>
/// After the application registers its implementation of the IAudioVolumeDuckNotification interface by calling
/// IAudioSessionManager2::RegisterDuckNotification, the session manager calls <c>OnVolumeUnduckNotification</c> when it wants
/// to send a notification about when ducking ends. The application receives the event notifications in the form of callbacks.
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/audiopolicy/nf-audiopolicy-iaudiovolumeducknotification-onvolumeunducknotification
// HRESULT OnVolumeUnduckNotification( LPCWSTR sessionID );
HRESULT OnVolumeUnduckNotification([MarshalAs(UnmanagedType.LPWStr)] string sessionID);
}
}
}