在 C# 中使用 'DefaultAudioEndpoint' 以外的音频端点
using an Audio Endpoint other than 'DefaultAudioEndpoint' in C#
This program 是 rgb
键盘的音频可视化工具,可收听 windows' 默认音频设备。我的音频设置有点复杂,我使用的不仅仅是默认音频设备。例如,当我从 Winamp
播放音乐时,它会通过设备 Auxillary 1 (Synchronous Audio Router)
而不是我设置为默认值的 Desktop Input (Synchronous Audio Router)
。我希望能够更改程序为可视化监听的设备。
我在声明音频设备的源中找到了; CSCoreAudioInput.cs
中的第 32-36 行:
public void Initialize()
{
MMDevice captureDevice = MMDeviceEnumerator.DefaultAudioEndpoint(DataFlow.Render, Role.Console);
WaveFormat deviceFormat = captureDevice.DeviceFormat;
_audioEndpointVolume = AudioEndpointVolume.FromDevice(captureDevice);
}
我从 documentation 中理解它的方式,MMDeviceEnumerator.DefaultAudioEndpoint(DataFlow.Render, Role.Console)
部分是 Windows 为应用程序提供我的默认 IMMEndpoint "Desktop Input."
的地方
我将如何改变 DefaultAudioEndpoint
?
Further Reading 展示了几种获取 IMMDevice 的方法,DefaultAudioEnpoint
就是其中之一。在我看来,我必须枚举设备,然后使用 PKEY_Device_FriendlyName
分离出 Auxillary 1 (Synchronous Audio Router)
。这对我来说有点多,因为我几乎没有 C#
经验。有没有更简单的方法来选择不同的端点?我在正确的轨道上吗?还是我完全错过了标记?
还有,MMDevice
和IMMDevice
有什么区别?源似乎只使用 MMDevice
而所有 Microsoft 文档引用 IMMDevice
.
谢谢。
我做到了!
我找到了程序使用 MMDevice
而不是 IMMDevice
的原因。开发人员已选择使用 CSCore 库而不是 Windows 自己的核心音频 API。
从继续阅读 CSCore MMDeviceEnumerator Documentation 看来,我必须制作一个单独的程序来输出所有端点及其各自的端点 ID 字符串。然后我可以用 GetDevice(String id)
方法替换 DefaultAudioEndpoint
方法,其中 String id
是我从单独程序中选择的任何端点的 ID。
为了找到我想要的端点,我写了这个简短的程序来找到我想要的所有信息:
static void Main(string[] args)
{
MMDeviceEnumerator enumerator = new MMDeviceEnumerator();
MMDeviceCollection collection = enumerator.EnumAudioEndpoints(DataFlow.Render,DeviceState.Active);
Console.WriteLine($"\nNumber of active Devices: {collection.GetCount()}");
int i = 0;
foreach (MMDevice device in collection){
Console.WriteLine($"\n{i} Friendly name: {device.FriendlyName}");
Console.WriteLine($"Endpoint ID: {device.DeviceID}");
i++;
}
Console.ReadKey();
}
这告诉我我想要的端点是我列表中的项目编号 3(数组中的 2),而不是使用 GetDevice(String id)
我使用 ItemAt(int deviceIndex)
.
MMDeviceEnumerator enumerator = new MMDeviceEnumerator();
MMDeviceCollection collection = enumerator.EnumAudioEndpoints(DataFlow.Render,DeviceState.Active);
MMDevice captureDevice = collection.ItemAt(2);
但是在这种情况下,程序没有使用 captureDevice
来引入音频数据。这些是神奇的台词:
_capture = new WasapiLoopbackCapture(100, new WaveFormat(deviceFormat.SampleRate, deviceFormat.BitsPerSample, i));
_capture.Initialize();
我发现 WasapiLoopbackCapture
使用 Windows' 默认设备除非更改,并且代码使用 DefaultAudioEndpoint
获取默认设备的属性。所以我添加了
_capture.Device = captureDevice;
//before
_capture.Initialize();
现在程序可以正确地从我的非默认音频端点提取音频数据。
本周有人要求我解决类似类型的问题。虽然有一些库可以做到这一点,但我特别要求 "non ish" 程序员做到这一点,所以我在 PowerShell 中开发了它。
Powershell default audio device changer - Github
也许您可以根据需要进行更改。
This program 是 rgb
键盘的音频可视化工具,可收听 windows' 默认音频设备。我的音频设置有点复杂,我使用的不仅仅是默认音频设备。例如,当我从 Winamp
播放音乐时,它会通过设备 Auxillary 1 (Synchronous Audio Router)
而不是我设置为默认值的 Desktop Input (Synchronous Audio Router)
。我希望能够更改程序为可视化监听的设备。
我在声明音频设备的源中找到了; CSCoreAudioInput.cs
中的第 32-36 行:
public void Initialize()
{
MMDevice captureDevice = MMDeviceEnumerator.DefaultAudioEndpoint(DataFlow.Render, Role.Console);
WaveFormat deviceFormat = captureDevice.DeviceFormat;
_audioEndpointVolume = AudioEndpointVolume.FromDevice(captureDevice);
}
我从 documentation 中理解它的方式,MMDeviceEnumerator.DefaultAudioEndpoint(DataFlow.Render, Role.Console)
部分是 Windows 为应用程序提供我的默认 IMMEndpoint "Desktop Input."
我将如何改变 DefaultAudioEndpoint
?
Further Reading 展示了几种获取 IMMDevice 的方法,DefaultAudioEnpoint
就是其中之一。在我看来,我必须枚举设备,然后使用 PKEY_Device_FriendlyName
分离出 Auxillary 1 (Synchronous Audio Router)
。这对我来说有点多,因为我几乎没有 C#
经验。有没有更简单的方法来选择不同的端点?我在正确的轨道上吗?还是我完全错过了标记?
还有,MMDevice
和IMMDevice
有什么区别?源似乎只使用 MMDevice
而所有 Microsoft 文档引用 IMMDevice
.
谢谢。
我做到了!
我找到了程序使用 MMDevice
而不是 IMMDevice
的原因。开发人员已选择使用 CSCore 库而不是 Windows 自己的核心音频 API。
从继续阅读 CSCore MMDeviceEnumerator Documentation 看来,我必须制作一个单独的程序来输出所有端点及其各自的端点 ID 字符串。然后我可以用 GetDevice(String id)
方法替换 DefaultAudioEndpoint
方法,其中 String id
是我从单独程序中选择的任何端点的 ID。
为了找到我想要的端点,我写了这个简短的程序来找到我想要的所有信息:
static void Main(string[] args)
{
MMDeviceEnumerator enumerator = new MMDeviceEnumerator();
MMDeviceCollection collection = enumerator.EnumAudioEndpoints(DataFlow.Render,DeviceState.Active);
Console.WriteLine($"\nNumber of active Devices: {collection.GetCount()}");
int i = 0;
foreach (MMDevice device in collection){
Console.WriteLine($"\n{i} Friendly name: {device.FriendlyName}");
Console.WriteLine($"Endpoint ID: {device.DeviceID}");
i++;
}
Console.ReadKey();
}
这告诉我我想要的端点是我列表中的项目编号 3(数组中的 2),而不是使用 GetDevice(String id)
我使用 ItemAt(int deviceIndex)
.
MMDeviceEnumerator enumerator = new MMDeviceEnumerator();
MMDeviceCollection collection = enumerator.EnumAudioEndpoints(DataFlow.Render,DeviceState.Active);
MMDevice captureDevice = collection.ItemAt(2);
但是在这种情况下,程序没有使用 captureDevice
来引入音频数据。这些是神奇的台词:
_capture = new WasapiLoopbackCapture(100, new WaveFormat(deviceFormat.SampleRate, deviceFormat.BitsPerSample, i));
_capture.Initialize();
我发现 WasapiLoopbackCapture
使用 Windows' 默认设备除非更改,并且代码使用 DefaultAudioEndpoint
获取默认设备的属性。所以我添加了
_capture.Device = captureDevice;
//before
_capture.Initialize();
现在程序可以正确地从我的非默认音频端点提取音频数据。
本周有人要求我解决类似类型的问题。虽然有一些库可以做到这一点,但我特别要求 "non ish" 程序员做到这一点,所以我在 PowerShell 中开发了它。
Powershell default audio device changer - Github
也许您可以根据需要进行更改。