// ----------------------------------------- // milligan22963 - implemented to work with nAudio // 12/2014 // ----------------------------------------- using System; using System.Runtime.InteropServices; using NAudio.CoreAudioApi.Interfaces; namespace NAudio.CoreAudioApi { /// /// AudioSessionControl object for information /// regarding an audio session /// public class AudioSessionControl : IDisposable { private readonly IAudioSessionControl audioSessionControlInterface; private readonly IAudioSessionControl2 audioSessionControlInterface2; private AudioSessionEventsCallback audioSessionEventCallback; /// /// Constructor. /// /// public AudioSessionControl(IAudioSessionControl audioSessionControl) { audioSessionControlInterface = audioSessionControl; audioSessionControlInterface2 = audioSessionControl as IAudioSessionControl2; if (audioSessionControlInterface is IAudioMeterInformation meters) AudioMeterInformation = new AudioMeterInformation(meters); if (audioSessionControlInterface is ISimpleAudioVolume volume) SimpleAudioVolume = new SimpleAudioVolume(volume); } #region IDisposable Members /// /// Dispose /// public void Dispose() { if (audioSessionEventCallback != null) { Marshal.ThrowExceptionForHR(audioSessionControlInterface.UnregisterAudioSessionNotification(audioSessionEventCallback)); audioSessionEventCallback = null; } GC.SuppressFinalize(this); } /// /// Finalizer /// ~AudioSessionControl() { Dispose(); } #endregion /// /// Audio meter information of the audio session. /// public AudioMeterInformation AudioMeterInformation { get; } /// /// Simple audio volume of the audio session (for volume and mute status). /// public SimpleAudioVolume SimpleAudioVolume { get; } /// /// The current state of the audio session. /// public AudioSessionState State { get { Marshal.ThrowExceptionForHR(audioSessionControlInterface.GetState(out var state)); return state; } } /// /// The name of the audio session. /// public string DisplayName { get { Marshal.ThrowExceptionForHR(audioSessionControlInterface.GetDisplayName(out var displayName)); return displayName; } set { if (value != String.Empty) { Marshal.ThrowExceptionForHR(audioSessionControlInterface.SetDisplayName(value, Guid.Empty)); } } } /// /// the path to the icon shown in the mixer. /// public string IconPath { get { Marshal.ThrowExceptionForHR(audioSessionControlInterface.GetIconPath(out var iconPath)); return iconPath; } set { if (value != String.Empty) { Marshal.ThrowExceptionForHR(audioSessionControlInterface.SetIconPath(value, Guid.Empty)); } } } /// /// The session identifier of the audio session. /// public string GetSessionIdentifier { get { if (audioSessionControlInterface2 == null) throw new InvalidOperationException("Not supported on this version of Windows"); Marshal.ThrowExceptionForHR(audioSessionControlInterface2.GetSessionIdentifier(out var str)); return str; } } /// /// The session instance identifier of the audio session. /// public string GetSessionInstanceIdentifier { get { if (audioSessionControlInterface2 == null) throw new InvalidOperationException("Not supported on this version of Windows"); Marshal.ThrowExceptionForHR(audioSessionControlInterface2.GetSessionInstanceIdentifier(out var str)); return str; } } /// /// The process identifier of the audio session. /// public uint GetProcessID { get { if (audioSessionControlInterface2 == null) throw new InvalidOperationException("Not supported on this version of Windows"); Marshal.ThrowExceptionForHR(audioSessionControlInterface2.GetProcessId(out var pid)); return pid; } } /// /// Is the session a system sounds session. /// public bool IsSystemSoundsSession { get { if (audioSessionControlInterface2 == null) throw new InvalidOperationException("Not supported on this version of Windows"); return (audioSessionControlInterface2.IsSystemSoundsSession() == 0); } } /// /// the grouping param for an audio session grouping /// /// public Guid GetGroupingParam() { Marshal.ThrowExceptionForHR(audioSessionControlInterface.GetGroupingParam(out var groupingId)); return groupingId; } /// /// For chanigng the grouping param and supplying the context of said change /// /// /// public void SetGroupingParam(Guid groupingId, Guid context) { Marshal.ThrowExceptionForHR(audioSessionControlInterface.SetGroupingParam(groupingId, context)); } /// /// Registers an even client for callbacks /// /// public void RegisterEventClient(IAudioSessionEventsHandler eventClient) { // we could have an array or list of listeners if we like audioSessionEventCallback = new AudioSessionEventsCallback(eventClient); Marshal.ThrowExceptionForHR(audioSessionControlInterface.RegisterAudioSessionNotification(audioSessionEventCallback)); } /// /// Unregisters an event client from receiving callbacks /// /// public void UnRegisterEventClient(IAudioSessionEventsHandler eventClient) { // if one is registered, let it go if (audioSessionEventCallback != null) { Marshal.ThrowExceptionForHR(audioSessionControlInterface.UnregisterAudioSessionNotification(audioSessionEventCallback)); audioSessionEventCallback = null; } } } }