Skip to content

Commit dc7c1ad

Browse files
committed
Migrate from NAudio.CoreAudioApi to AudioSwitcher.AudioApi.CoreAudio. Requires modified library until xenolightning/AudioSwitcher#70 is merged.
1 parent 136e288 commit dc7c1ad

File tree

8 files changed

+87
-71
lines changed

8 files changed

+87
-71
lines changed

WinAudioAssistant/App.xaml.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using System.Data;
33
using System.Windows;
44
using WinAudioAssistant.Models;
5+
using AudioSwitcher.AudioApi.CoreAudio;
56

67
namespace WinAudioAssistant
78
{
@@ -10,6 +11,7 @@ namespace WinAudioAssistant
1011
/// </summary>
1112
public partial class App : Application
1213
{
14+
public static CoreAudioController CoreAudioController { get; private set; } = new();
1315
public static UserSettings UserSettings { get; private set; } = new();
1416
public static AudioEndpointManager AudioEndpointManager { get; private set; } = new();
1517

WinAudioAssistant/Models/AudioEndpointInfo.cs

Lines changed: 22 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
using NAudio.CoreAudioApi;
2-
using System;
1+
using System;
32
using System.Collections.Generic;
43
using System.Diagnostics;
54
using System.Linq;
65
using System.Text;
76
using System.Threading.Tasks;
7+
using AudioSwitcher.AudioApi;
8+
using AudioSwitcher.AudioApi.CoreAudio;
89

910
namespace WinAudioAssistant.Models
1011
{
@@ -25,7 +26,7 @@ public enum EndpointFormFactor
2526

2627
public struct AudioEndpointInfo
2728
{
28-
public readonly DataFlow DataFlow { get; }
29+
public readonly DeviceType DataFlow { get; }
2930
public readonly Guid AudioEndpoint_GUID { get; } // Globally unique to this endpoint
3031
public DeviceState? DeviceState { get; private set;}
3132
public EndpointFormFactor? AudioEndpoint_FormFactor { get; private set; } // Speakers, headphones, headset, SPDIF, etc.
@@ -34,15 +35,15 @@ public struct AudioEndpointInfo
3435
public string? Device_DeviceDesc { get; private set; } // The endpoint's name, which can be changed in the control panel
3536
public string? DeviceClass_IconPath { get; private set; }
3637
public string? DeviceInterface_FriendlyName { get; private set; } // Set by the driver, but may have a different value if there are duplicate devices
37-
public string? HostDeviceDesc { get; private set; } // (Actual property name unkown) Appears to be the name of the host device. Usually same as DeviceInterface_FriendlyName.
38+
public string? HostDeviceDesc { get; private set; } // (Actual property name unkown) Appears to be the name of the host device. Usually same as DeviceInterface_FriendlyName, but more consistent.
3839

39-
public readonly string ID => (DataFlow == DataFlow.Render ? "{0.0.0.00000000}.{" : "{0.0.1.00000000}.{") + AudioEndpoint_GUID.ToString() + "}";
40+
public readonly string ID => (DataFlow == DeviceType.Playback ? "{0.0.0.00000000}.{" : "{0.0.1.00000000}.{") + AudioEndpoint_GUID.ToString() + "}";
4041

4142
/// <summary>
4243
/// Use named arguments for optional parameters. The order of arguments may change in the future.
4344
/// </summary>
4445
/// <remarks>Test remark.</remarks>
45-
public AudioEndpointInfo(DataFlow dataFlow,
46+
public AudioEndpointInfo(DeviceType dataFlow,
4647
Guid audioEndpoint_GUID,
4748
EndpointFormFactor? audioEndpoint_FormFactor = null,
4849
Guid? audioEndpoint_JackSubType = null,
@@ -52,7 +53,7 @@ public AudioEndpointInfo(DataFlow dataFlow,
5253
string? deviceInterface_FriendlyName = null,
5354
string? hostDeviceDesc = null)
5455
{
55-
Trace.Assert(dataFlow != DataFlow.All, "AudioEndpointInfo created with DataFlow.All");
56+
Trace.Assert(dataFlow != DeviceType.All, "AudioEndpointInfo created with DeviceType.All");
5657
DataFlow = dataFlow;
5758
AudioEndpoint_GUID = audioEndpoint_GUID;
5859
AudioEndpoint_FormFactor = audioEndpoint_FormFactor;
@@ -63,18 +64,11 @@ public AudioEndpointInfo(DataFlow dataFlow,
6364
DeviceInterface_FriendlyName = deviceInterface_FriendlyName;
6465
HostDeviceDesc = hostDeviceDesc;
6566
}
66-
public AudioEndpointInfo(MMDevice device)
67+
public AudioEndpointInfo(CoreAudioDevice device)
6768
{
68-
Trace.Assert(device.DataFlow != DataFlow.All, "AudioEndpointInfo created with DataFlow.All");
69-
DataFlow = device.DataFlow;
70-
if (Guid.TryParse(device.Properties[propertyKeys.AudioEndpoint_GUID]?.Value as string, out var guid))
71-
{
72-
AudioEndpoint_GUID = guid;
73-
}
74-
else
75-
{
76-
AudioEndpoint_GUID = Guid.Empty;
77-
}
69+
Trace.Assert(device.DeviceType != DeviceType.All, "AudioEndpointInfo created with DeviceType.All");
70+
DataFlow = device.DeviceType;
71+
AudioEndpoint_GUID = device.Id;
7872
Debug.Assert(AudioEndpoint_GUID != Guid.Empty, "AudioEndpointInfo created with empty GUID");
7973
UpdateFromDevice(device);
8074
}
@@ -85,8 +79,8 @@ public AudioEndpointInfo(MMDevice device)
8579
/// <returns>True if a matching endpoint was found in the system.</returns>
8680
public bool UpdateFromSystem()
8781
{
88-
var device = new MMDeviceEnumerator().GetDevice(ID);
89-
if (device?.Properties[propertyKeys.AudioEndpoint_GUID]?.Value is Guid guid && guid == AudioEndpoint_GUID)
82+
var device = App.CoreAudioController.GetDevice(AudioEndpoint_GUID);
83+
if (device?.Properties[propertyKeys.AudioEndpoint_GUID] is Guid guid && guid == AudioEndpoint_GUID)
9084
{
9185
UpdateFromDevice(device);
9286
return true;
@@ -97,23 +91,23 @@ public bool UpdateFromSystem()
9791
}
9892
}
9993

100-
public void UpdateFromDevice(MMDevice device)
94+
public void UpdateFromDevice(CoreAudioDevice device)
10195
{
10296
DeviceState = device.State;
103-
if (device.Properties[propertyKeys.AudioEndpoint_FormFactor]?.Value is uint formFactor)
97+
if (device.Properties[propertyKeys.AudioEndpoint_FormFactor] is uint formFactor)
10498
AudioEndpoint_FormFactor = (EndpointFormFactor)formFactor;
105-
if (Guid.TryParse(device.Properties[propertyKeys.AudioEndpoint_JackSubType]?.Value as string, out var jackSubType))
99+
if (Guid.TryParse(device.Properties[propertyKeys.AudioEndpoint_JackSubType] as string, out var jackSubType))
106100
AudioEndpoint_JackSubType = jackSubType;
107-
if (device.Properties[propertyKeys.Device_ContainerId]?.Value is Guid containerId &&
101+
if (device.Properties[propertyKeys.Device_ContainerId] is Guid containerId &&
108102
containerId != new Guid(0x0, 0x0, 0x0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff))
109103
Device_ContainerId = containerId;
110-
if (device.Properties[propertyKeys.Device_DeviceDesc]?.Value is string deviceDesc)
104+
if (device.Properties[propertyKeys.Device_DeviceDesc] is string deviceDesc)
111105
Device_DeviceDesc = deviceDesc;
112-
if (device.Properties[propertyKeys.DeviceClass_IconPath]?.Value is string iconPath)
106+
if (device.Properties[propertyKeys.DeviceClass_IconPath] is string iconPath)
113107
DeviceClass_IconPath = iconPath;
114-
if (device.Properties[propertyKeys.DeviceInterface_FriendlyName]?.Value is string friendlyName)
108+
if (device.Properties[propertyKeys.DeviceInterface_FriendlyName] is string friendlyName)
115109
DeviceInterface_FriendlyName = friendlyName;
116-
if (device.Properties[propertyKeys.Device_DeviceDesc]?.Value is string hostDeviceDesc)
110+
if (device.Properties[propertyKeys.Device_DeviceDesc] is string hostDeviceDesc)
117111
HostDeviceDesc = hostDeviceDesc;
118112
}
119113

WinAudioAssistant/Models/AudioEndpointManager.cs

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
using NAudio.CoreAudioApi;
2-
using System;
1+
using System;
32
using System.Collections.Generic;
43
using System.Collections.ObjectModel;
54
using System.IO;
@@ -25,8 +24,7 @@ public AudioEndpointManager()
2524
public void UpdateCachedEndpoints()
2625
{
2726
_cachedEndpoints.Clear();
28-
var enumerator = new MMDeviceEnumerator();
29-
foreach (var device in enumerator.EnumerateAudioEndPoints(DataFlow.All, DeviceState.All))
27+
foreach (var device in App.CoreAudioController.GetDevices())
3028
{
3129
_cachedEndpoints.Add(new AudioEndpointInfo(device));
3230
}
@@ -38,32 +36,36 @@ public void UpdateCachedEndpoints()
3836
public static void ListAllEndpoints()
3937
{
4038
using StreamWriter writer = new("endpoints.txt", append: false);
41-
var enumerator = new MMDeviceEnumerator();
42-
foreach (var device in enumerator.EnumerateAudioEndPoints(DataFlow.All, DeviceState.All))
39+
foreach (var device in App.CoreAudioController.GetDevices())
4340
{
4441
writer.WriteLine("");
4542
writer.WriteLine("AudioEndpoint:");
46-
writer.WriteLine($" ID={device.ID}");
47-
writer.WriteLine($" DataFlow={device.DataFlow}");
43+
writer.WriteLine($" DeviceType={device.DeviceType}");
44+
writer.WriteLine($" FullName={device.FullName}");
45+
writer.WriteLine($" GetHashCode={device.GetHashCode()}");
46+
writer.WriteLine($" Icon={device.Icon}");
47+
writer.WriteLine($" IconPath={device.IconPath}");
48+
writer.WriteLine($" Id={device.Id}");
49+
writer.WriteLine($" InterfaceName={device.InterfaceName}");
50+
writer.WriteLine($" IsDefaultDevice={device.IsDefaultDevice}");
51+
writer.WriteLine($" IsDefaultCommunicationsDevice={device.IsDefaultCommunicationsDevice}");
52+
writer.WriteLine($" Name={device.Name}");
53+
writer.WriteLine($" RealId={device.RealId}");
4854
writer.WriteLine($" State={device.State}");
49-
writer.WriteLine($" FriendlyName={device.FriendlyName}");
50-
writer.WriteLine($" DeviceFriendlyName={device.DeviceFriendlyName}");
51-
writer.WriteLine($" InstanceID={device.InstanceId}");
52-
writer.WriteLine($" DeviceTopology.DeviceId={device.DeviceTopology.DeviceId}");
53-
writer.WriteLine($" DeviceTopology.ConnectorCount={device.DeviceTopology.ConnectorCount}");
55+
5456
writer.WriteLine(" Properties:");
55-
for (int i = 0; i < device.Properties.Count; i++)
57+
foreach (var property in device.Properties)
5658
{
57-
var formatId = device.Properties[i].Key.formatId;
58-
var propertyId = device.Properties[i].Key.propertyId;
59+
var formatId = property.Key.FormatId;
60+
var propertyId = property.Key.PropertyId;
5961
string valueType;
6062
string? value;
6163
var propertyKeyDef = PropertyKeyDefLookup.Lookup(formatId, propertyId);
6264

6365
try
6466
{
65-
valueType = device.Properties[i].Value.GetType().ToString();
66-
value = device.Properties[i].Value.ToString();
67+
valueType = property.Value.GetType().ToString();
68+
value = property.Value.ToString();
6769
}
6870
catch (NotImplementedException)
6971
{

WinAudioAssistant/Models/ManagedDevice.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
using NAudio.CoreAudioApi;
2-
using System;
1+
using System;
32
using System.Collections.Generic;
43
using System.Diagnostics;
54
using System.Linq;
65
using System.Text;
76
using System.Threading.Tasks;
7+
using AudioSwitcher.AudioApi;
88

99
namespace WinAudioAssistant.Models
1010
{
@@ -13,7 +13,7 @@ public abstract class ManagedDevice
1313
public string Name { get; set; } = "";
1414
public AudioEndpointInfo EndpointInfo { get; protected set; }
1515

16-
public abstract DataFlow DataFlow();
16+
public abstract DeviceType DataFlow();
1717
public abstract void SetEndpoint(AudioEndpointInfo endpointInfo);
1818
}
1919

@@ -25,7 +25,7 @@ public ManagedInputDevice(AudioEndpointInfo endpointInfo)
2525
EndpointInfo = endpointInfo;
2626
}
2727

28-
public override DataFlow DataFlow() => NAudio.CoreAudioApi.DataFlow.Capture;
28+
public override DeviceType DataFlow() => DeviceType.Capture;
2929

3030
public override void SetEndpoint(AudioEndpointInfo endpointInfo)
3131
{
@@ -42,7 +42,7 @@ public ManagedOutputDevice(AudioEndpointInfo endpointInfo)
4242
EndpointInfo = endpointInfo;
4343
}
4444

45-
public override DataFlow DataFlow() => NAudio.CoreAudioApi.DataFlow.Render;
45+
public override DeviceType DataFlow() => DeviceType.Playback;
4646

4747
public override void SetEndpoint(AudioEndpointInfo endpointInfo)
4848
{

WinAudioAssistant/ViewModels/DevicePriorityViewModel.cs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
1-
using GongSolutions.Wpf.DragDrop;
2-
using Microsoft.VisualBasic;
3-
using NAudio.CoreAudioApi;
4-
using System;
1+
using System;
52
using System.Collections.Generic;
63
using System.Collections.ObjectModel;
74
using System.ComponentModel;
@@ -10,6 +7,8 @@
107
using System.Text;
118
using System.Threading.Tasks;
129
using System.Windows.Controls;
10+
using GongSolutions.Wpf.DragDrop;
11+
using AudioSwitcher.AudioApi;
1312
using WinAudioAssistant.Models;
1413
using WinAudioAssistant.Views;
1514

@@ -18,7 +17,7 @@ namespace WinAudioAssistant.ViewModels
1817
// Assigned to each ListBox in the view code-behind
1918
public struct ListBoxTag
2019
{
21-
public DataFlow DataFlow;
20+
public DeviceType DataFlow;
2221
public bool IsComms;
2322
}
2423

WinAudioAssistant/ViewModels/EditDeviceViewModel.cs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
using NAudio.CoreAudioApi;
2-
using System;
1+
using System;
32
using System.Collections.Generic;
43
using System.Collections.ObjectModel;
54
using System.ComponentModel;
@@ -8,6 +7,7 @@
87
using System.Text;
98
using System.Threading.Tasks;
109
using System.Windows;
10+
using AudioSwitcher.AudioApi;
1111
using WinAudioAssistant.Models;
1212

1313
namespace WinAudioAssistant.ViewModels
@@ -24,7 +24,7 @@ protected virtual void OnPropertyChanged(string propertyName)
2424
private bool _initialized = false;
2525
private ManagedDevice? _managedDevice; // Original managed device reference. Null if creating a new one
2626
public ManagedDevice? ManagedDevice { get => _managedDevice;}
27-
public DataFlow DataFlow { get; private set; }
27+
public DeviceType DataFlow { get; private set; }
2828
public bool IsComms { get; private set; } = false;
2929

3030
// Managed device properties, stored here until changes are applied
@@ -111,7 +111,7 @@ public void Initialize(ManagedDevice device, bool isComms)
111111
_managedDevice = device;
112112
DataFlow = device.DataFlow();
113113
IsComms = isComms;
114-
WindowTitle = "Edit " + (DataFlow == DataFlow.Capture ? "Input" : "Output") + (isComms ? "Comms " : "") + " Managed Device";
114+
WindowTitle = "Edit " + (DataFlow == DeviceType.Capture ? "Input" : "Output") + (isComms ? "Comms " : "") + " Managed Device";
115115

116116
ManagedDeviceName = device.Name;
117117
ManagedDeviceEndpoint = device.EndpointInfo;
@@ -121,14 +121,14 @@ public void Initialize(ManagedDevice device, bool isComms)
121121
OnPropertyChanged(string.Empty); // Refreshes all properties
122122
}
123123

124-
public void Initialize(DataFlow dataFlow, bool isComms)
124+
public void Initialize(DeviceType dataFlow, bool isComms)
125125
{
126126
//Creating a new managed device
127127
Debug.Assert(!_initialized);
128128
if (_initialized) return;
129129
DataFlow = dataFlow;
130130
IsComms = isComms;
131-
WindowTitle = "New " + (DataFlow == DataFlow.Capture ? "Input" : "Output") + (isComms ? "Comms " : "") + " Managed Device";
131+
WindowTitle = "New " + (DataFlow == DeviceType.Capture ? "Input" : "Output") + (isComms ? "Comms " : "") + " Managed Device";
132132

133133
_initialized = true;
134134
UpdateFilteredEndpoints();
@@ -185,8 +185,8 @@ public bool Apply()
185185
// Creating a new managed device
186186
_managedDevice = DataFlow switch
187187
{
188-
DataFlow.Capture => new ManagedInputDevice(ManagedDeviceEndpoint.Value),
189-
DataFlow.Render => new ManagedOutputDevice(ManagedDeviceEndpoint.Value),
188+
DeviceType.Capture => new ManagedInputDevice(ManagedDeviceEndpoint.Value),
189+
DeviceType.Playback => new ManagedOutputDevice(ManagedDeviceEndpoint.Value),
190190
_ => throw new NotImplementedException()
191191
};
192192
_managedDevice.Name = ManagedDeviceName;

WinAudioAssistant/Views/DevicePriorityView.xaml.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
using NAudio.CoreAudioApi;
2-
using System.Text;
1+
using System.Text;
32
using System.Windows;
43
using System.Windows.Controls;
54
using System.Windows.Data;
@@ -9,6 +8,7 @@
98
using System.Windows.Media.Imaging;
109
using System.Windows.Navigation;
1110
using System.Windows.Shapes;
11+
using AudioSwitcher.AudioApi;
1212
using WinAudioAssistant.Models;
1313
using WinAudioAssistant.ViewModels;
1414

@@ -23,10 +23,10 @@ public partial class DevicePriorityView : Window
2323
public DevicePriorityView()
2424
{
2525
InitializeComponent();
26-
OutputPriorityListBox.Tag = new ListBoxTag { DataFlow = DataFlow.Render, IsComms = false };
27-
CommsOutputPriorityListBox.Tag = new ListBoxTag { DataFlow = DataFlow.Render, IsComms = true };
28-
InputPriorityListBox.Tag = new ListBoxTag { DataFlow = DataFlow.Capture, IsComms = false };
29-
CommsInputPriorityListBox.Tag = new ListBoxTag { DataFlow = DataFlow.Capture, IsComms = true };
26+
OutputPriorityListBox.Tag = new ListBoxTag { DataFlow = DeviceType.Playback, IsComms = false };
27+
CommsOutputPriorityListBox.Tag = new ListBoxTag { DataFlow = DeviceType.Playback, IsComms = true };
28+
InputPriorityListBox.Tag = new ListBoxTag { DataFlow = DeviceType.Capture, IsComms = false };
29+
CommsInputPriorityListBox.Tag = new ListBoxTag { DataFlow = DeviceType.Capture, IsComms = true };
3030

3131
}
3232

WinAudioAssistant/WinAudioAssistant.csproj

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,26 @@
1010

1111
<ItemGroup>
1212
<PackageReference Include="gong-wpf-dragdrop" Version="3.2.1" />
13-
<PackageReference Include="NAudio.Wasapi" Version="2.2.1" />
13+
</ItemGroup>
14+
<ItemGroup Condition=" '$(Configuration)' == 'Debug' ">
15+
<Reference Include="AudioSwitcher.AudioApi">
16+
<HintPath>.\Libs\Debug\AudioSwitcher.AudioApi.dll</HintPath>
17+
</Reference>
18+
</ItemGroup>
19+
<ItemGroup Condition=" '$(Configuration)' == 'Release' ">
20+
<Reference Include="AudioSwitcher.AudioApi">
21+
<HintPath>.\Libs\Release\AudioSwitcher.AudioApi.dll</HintPath>
22+
</Reference>
23+
</ItemGroup>
24+
<ItemGroup Condition=" '$(Configuration)' == 'Debug' ">
25+
<Reference Include="AudioSwitcher.AudioApi.CoreAudio">
26+
<HintPath>.\Libs\Debug\AudioSwitcher.AudioApi.CoreAudio.dll</HintPath>
27+
</Reference>
28+
</ItemGroup>
29+
<ItemGroup Condition=" '$(Configuration)' == 'Release' ">
30+
<Reference Include="AudioSwitcher.AudioApi.CoreAudio">
31+
<HintPath>.\Libs\Release\AudioSwitcher.AudioApi.CoreAudio.dll</HintPath>
32+
</Reference>
1433
</ItemGroup>
1534

1635
</Project>

0 commit comments

Comments
 (0)