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

时间:2016-12-30 05:21:43

标签: c# winapi audio audio-recording

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

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

您还可以找到以下频道: AudioEndpointVolumeChannels,但它只允许使用Channels.count。

我想到的另一个解决方案是使用某种“宏”'随着鼠标点击动作而变化,但这非常难看。

NAudio API应该有正确的东西,但我没有找到任何关于如何做的文档。我用Google搜索了一整天而一无所获。旧的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);

        }

2 个答案:

答案 0 :(得分: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);
            }
        }

答案 1 :(得分:1)

尤金和我发现的方法是找到播放设备注册表 - &#39;渲染&#39;那是: HKLM \ SOFTWARE \微软\的Windows \ CurrentVersion \ MMDevices \澳元IO \渲染 然后转发斜线{Guid} ...你的播放设备。确保您的设备处于5.1或更高模式。

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

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

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