@@ -12,7 +12,7 @@ namespace Aurora.Utils {
1212 /// Will handle the creation of devices if required. If another AudioDevice is using that device, they will share the same reference.
1313 /// Can be hot-swapped to a different device, moving all events to the newly selected device.
1414 /// </summary>
15- public sealed class AudioDeviceProxy : IDisposable {
15+ public sealed class AudioDeviceProxy : IDisposable , NAudio . CoreAudioApi . Interfaces . IMMNotificationClient {
1616
1717 public const string DEFAULT_DEVICE_ID = "" ; // special ID to indicate the default device
1818
@@ -24,6 +24,7 @@ public sealed class AudioDeviceProxy : IDisposable {
2424
2525 // ID of currently selected device.
2626 private string deviceId ;
27+ private bool defaultDeviceChanged = false ;
2728
2829 static AudioDeviceProxy ( ) {
2930 // Tried using a static class to update the device lists when they changed, but it caused an AccessViolation. Will try look into this again in future
@@ -38,6 +39,7 @@ public AudioDeviceProxy(DataFlow flow) : this(DEFAULT_DEVICE_ID, flow) { }
3839 public AudioDeviceProxy ( string deviceId , DataFlow flow ) {
3940 Flow = flow ;
4041 DeviceId = deviceId ?? DEFAULT_DEVICE_ID ;
42+ deviceEnumerator . RegisterEndpointNotificationCallback ( this ) ;
4143 }
4244
4345 /// <summary>Indicates recorded data is available on the selected device.</summary>
@@ -64,7 +66,8 @@ public string DeviceId {
6466 get => deviceId ;
6567 set {
6668 value ??= DEFAULT_DEVICE_ID ; // Ensure not-null (if null, assume default device)
67- if ( deviceId == value ) return ;
69+ if ( deviceId == value && ! ( defaultDeviceChanged && deviceId == DEFAULT_DEVICE_ID ) ) return ;
70+ defaultDeviceChanged = false ;
6871 deviceId = value ;
6972 UpdateDevice ( ) ;
7073 }
@@ -120,13 +123,30 @@ private static void RefreshDeviceLists() {
120123 }
121124 #endregion
122125
126+ #region IMMNotificationClient Implementation
127+
128+ /// <summary>
129+ /// Update the device when changed by the system.
130+ /// </summary>
131+ public void OnDefaultDeviceChanged ( DataFlow flow , Role role , string defaultDeviceId )
132+ => defaultDeviceChanged = true ;
133+
134+ // Methods from interface not used
135+ public void OnDeviceAdded ( string pwstrDeviceId ) { }
136+ public void OnDeviceRemoved ( string deviceId ) { }
137+ public void OnDeviceStateChanged ( string deviceId , DeviceState newState ) { }
138+ public void OnPropertyValueChanged ( string pwstrDeviceId , PropertyKey key ) { }
139+
140+ #endregion
141+
123142 #region IDisposable Implementation
124143 private bool disposedValue = false ;
125144 public void Dispose ( ) => Dispose ( true ) ;
126145 void Dispose ( bool disposing ) {
127146 if ( ! disposedValue ) {
128147 if ( disposing )
129148 DisposeCurrentDevice ( ) ;
149+ deviceEnumerator . UnregisterEndpointNotificationCallback ( this ) ;
130150 disposedValue = true ;
131151 }
132152 }
0 commit comments