Skip to content

Commit 641f7f9

Browse files
authored
Merge pull request antonpup#2195 from valarion/fix/default-audio-device
Handled default audio device changed
2 parents 7ec6bda + 7cbbdd6 commit 641f7f9

File tree

1 file changed

+22
-2
lines changed

1 file changed

+22
-2
lines changed

Project-Aurora/Project-Aurora/Utils/AudioDeviceProxy.cs

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)