// -----------------------------------------
// 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;
}
}
}
}