如何在 C# 中更改 Windows 中的扬声器配置?

How to Change Speaker Configuration in Windows in C#?

我知道这个旧线程:What APIs exist?,但它确实没有回答问题。而且已经好几年了。是的,我正在使用 NAudio.CoreAudioApi 但我没有找到任何有用的信息。

MMDevice.Properties 是只读的。有没有办法在 C# 中以编程方式执行此操作?我不确定了。

您还可以通过以下方式查找频道: AudioEndpointVolumeChannels,但它只允许 Channels.count.

我想到的另一种解决方案是使用某种 'Macro' 随着鼠标单击移动而改变的解决方案,但这非常难看。

NAudio API 应该有正确的东西,但我没有找到任何关于如何做的文档。我在谷歌上搜索了一整天,但一无所获。旧的 CoreAPIs 被移到了那里。

using NAudio.Wave;
using NAudio.CoreAudioApi;

        //Can't do anything with these Devices, but change the volume????!!!
        var deviceEnum = new MMDeviceEnumerator();
        var devices = deviceEnum.EnumerateAudioEndPoints(DataFlow.All, DeviceState.Active).ToList();
        foreach (MMDevice device in devices)
        {
            Console.WriteLine(device.FriendlyName);

        }

Windows API 支持修改属性,但是NAudio不知为何没有公开这个能力。通过修改 NAudio 源来添加它非常容易。

NAudio\CoreAudioApi\PropVariant.cs中添加

    /// <summary>
    /// Creates a new PropVariant containing a uint value
    /// </summary>
    public static PropVariant FromUInt(uint value)
    {
        return new PropVariant() { vt = (short)VarEnum.VT_UI4, ulVal = value };
    }

NAudio\CoreAudioApi\PropertyStore.cs中添加以下方法

    /// <summary>
    /// Sets property value at specified key
    /// </summary>
    /// <param name="key">Index</param>
    /// <param name="value">Value</param>
    public void SetValue(PropertyKey key, PropVariant value)
    {
        Marshal.ThrowExceptionForHR(storeInterface.SetValue(ref key, ref value));
    }

NAudio\CoreAudioApi\MMDevice.cs

修改以下行

        Marshal.ThrowExceptionForHR(deviceInterface.OpenPropertyStore(StorageAccessMode.Read, out propstore));

成为

        Marshal.ThrowExceptionForHR(deviceInterface.OpenPropertyStore(StorageAccessMode.ReadWrite, out propstore));

现在,如果您使用这些更改重建 NAudio.dll,您的示例可能看起来像这样将播放设备更改为 5.1(您必须 运行 它作为管理员,否则它将失败)

        var deviceEnum = new MMDeviceEnumerator();
        var devices = deviceEnum.EnumerateAudioEndPoints(DataFlow.All, DeviceState.Active).ToList();
        foreach (MMDevice device in devices)
        {
            Console.WriteLine(device.FriendlyName);
            if (device.Properties.Contains(PropertyKeys.PKEY_AudioEndpoint_PhysicalSpeakers))
            {
                var value = device.Properties[PropertyKeys.PKEY_AudioEndpoint_PhysicalSpeakers];
                Console.WriteLine("Current value: " + value.Value.ToString());
                // set configuration to 5.1, value is taken from ksmedia.h from Windows Driver Kit
                PropVariant newvalue = PropVariant.FromUInt(63);
                device.Properties.SetValue(PropertyKeys.PKEY_AudioEndpoint_PhysicalSpeakers, newvalue);
            }
        }

尤金和我发现的有效方法是找到播放设备注册表 -- 'Render' 即: HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\MMDevices\Aud‌ io\Render 然后正斜杠 {Guid}... 您的播放设备。确保您的设备处于 5.1 或更高版本。

然后'Export'那个文件。当您需要恢复到 5.1 或更高版本时,这也包括 'Sample Rate'。然后在代码中使用导出文件中的以下内容:

Process regeditProcess = Process.Start("regedit.exe", "/s playback.reg");
regeditProcess.WaitForExit();

这将确保正确恢复密钥。 这仍然不是我希望看到的最佳方式。但它确实有效。