I'm wondering how to process the event when I insert (or extract) my headphones or another output device to soundcard jack.
Searching here and on google gives me information about "naudio" library, but it has very poor documentation to examine and also one of coordinators of this project told me he isn't sure than it even possible in their library.
My eventual purpose is automatic controlling volume for different devices, e.g. when headphones are active - set 10% volume, and when speakers are active - set 100%.
You can do it using NAudio's MMDeviceEnumerator and IMMNotificationClient. However you add Implementations for RegisterEndpointNotificationCallback & UnRegisterEndpointNotificationCallback to MMDeviceEnumerator Class
The implementations are
/// <summary>
/// Registers a call back for Device Events
/// </summary>
/// <param name="client">Object implementing IMMNotificationClient type casted as IMMNotificationClient interface</param>
/// <returns></returns>
public int RegisterEndpointNotificationCallback([In] [MarshalAs(UnmanagedType.Interface)] IMMNotificationClient client)
{
//DeviceEnum declared below
return deviceEnum.RegisterEndpointNotificationCallback(client);
}
/// <summary>
/// UnRegisters a call back for Device Events
/// </summary>
/// <param name="client">Object implementing IMMNotificationClient type casted as IMMNotificationClient interface </param>
/// <returns></returns>
public int UnRegisterEndpointNotificationCallback([In] [MarshalAs(UnmanagedType.Interface)] IMMNotificationClient client)
{
//DeviceEnum declared below
return deviceEnum.UnregisterEndpointNotificationCallback(client);
}
Then create a class that implements IMMNotificationClient
sample:
class NotificationClientImplementation : NAudio.CoreAudioApi.Interfaces.IMMNotificationClient
{
public void OnDefaultDeviceChanged(DataFlow dataFlow, Role deviceRole, string defaultDeviceId)
{
//Do some Work
Console.WriteLine("OnDefaultDeviceChanged --> {0}", dataFlow.ToString());
}
public void OnDeviceAdded(string deviceId)
{
//Do some Work
Console.WriteLine("OnDeviceAdded -->");
}
public void OnDeviceRemoved(string deviceId)
{
Console.WriteLine("OnDeviceRemoved -->");
//Do some Work
}
public void OnDeviceStateChanged(string deviceId, DeviceState newState)
{
Console.WriteLine("OnDeviceStateChanged\n Device Id -->{0} : Device State {1}", deviceId, newState);
//Do some Work
}
public NotificationClientImplementation()
{
//_realEnumerator.RegisterEndpointNotificationCallback();
if (System.Environment.OSVersion.Version.Major < 6)
{
throw new NotSupportedException("This functionality is only supported on Windows Vista or newer.");
}
}
public void OnPropertyValueChanged(string deviceId, PropertyKey propertyKey)
{
//Do some Work
//fmtid & pid are changed to formatId and propertyId in the latest version NAudio
Console.WriteLine("OnPropertyValueChanged: formatId --> {0} propertyId --> {1}", propertyKey.formatId.ToString(), propertyKey.propertyId.ToString());
}
}
Then all you have to do is
Sample:
private NAudio.CoreAudioApi.MMDeviceEnumerator deviceEnum = new NAudio.CoreAudioApi.MMDeviceEnumerator();
private NotificationClientImplementation notificationClient;
private NAudio.CoreAudioApi.Interfaces.IMMNotificationClient notifyClient;
Sample:
notificationClient = new NotificationClientImplementation();
notifyClient = (NAudio.CoreAudioApi.Interfaces.IMMNotificationClient)notificationClient;
deviceEnum.RegisterEndpointNotificationCallback(notifyClient);
Hope this helps some body. Thanks to MSDN Forums and particularly Michael Taylor http://msmvps.com/blogs/p3net for helping me with this.
Thanks & Cheers.
You will be able to determine when a device is plugged into the system, you will have to implement the IMMNotificationClient
through COM interop. Basically, you will have to define the implementations of the following methods:
OnDefaultDeviceChanged
OnDeviceAdded
OnDeviceRemoved
OnDeviceStateChanged
OnPropertyValueChanged
Note that of the above, the ones you are mostly interested in are:
OnDefaultDeviceChanged
OnDeviceAdded
OnDeviceStateChanged
However, you should be aware that the underlying hardware has to support this functionality, and that this is only available on Windows Vista and Windows Server 2008 on.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With