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

Posted

技术标签:

【中文标题】如何在 C# 中更改 Windows 中的扬声器配置?【英文标题】:How to Change Speaker Configuration in Windows in C#? 【发布时间】:2016-12-30 05:21:42 【问题描述】:

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

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

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

我想到的另一个解决方案是使用某种“宏”,它会随着鼠标点击动作而改变,但这很丑。

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

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);

        

【问题讨论】:

你到底想配置什么?你能说得更具体些吗 我想将播放设备从 2CH 更改为 5.1。或将采样率从默认设置为 24 位、48000。我不确定上面引用的 NAudio 是否有工具。我尝试了其他几个 API,但文档很少,或者功能不存在。 【参考方案1】:

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);
            
        

【讨论】:

您的答案看起来不错。但是在下载他们的源代码时。我得到一百万个无法解决的错误。就像它带有错误的框架或缺少依赖项一样。具体来说,我在'=>'和'预期标识符......'之类的东西上得到“无效令牌';'”。 127 个错误。 你用的是哪个版本的?我从这里得到了最新的github.com/naudio/NAudio,它在 VS 2015 中编译没有错误 OK 忽略上面的 cmets。我已经在 VS2015 中构建了它。下一个问题是它不起作用。在调试中,我看到它以正确的值命中设置器,但播放设备从未从 2CH 更改为 5.1。 也可以尝试不同的键,你可以使用SysInternals ProcessMonitor检查手动更改配置时HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\MMDevices\Audio\Render中哪些值发生了变化 为了减少事件数量添加过滤器只显示 ProcessName = svchost.exe 和 Operation=RegSetValue【参考方案2】:

Eugene 和我发现有效的方法是找到播放设备注册表——“渲染”,即: HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\MMDevices\Aud‌​io\​​Render 然后正斜杠 Guid... 您的播放设备。确保您的设备处于 5.1 或更高版本的模式。

然后将其“导出”到文件中。当您需要恢复到 5.1 或更高版本时,其中还包括“采样率”。然后在代码中使用导出文件中的以下内容:

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

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

【讨论】:

以上是关于如何在 C# 中更改 Windows 中的扬声器配置?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Windows 中更改默认播放和录制设备名称?

C# 中的麦克风到扬声器音频流

使用 C# 在 Windows 10 上控制左右扬声器平衡级别

如何通过在 C# windows 窗体中的文本框中输入来更改图像的大小?

如何获得扬声器音量级别? [复制]

如何在 Windows 中以编程方式强制重启/重新加载 Playback 设备?