为了账号安全,请及时绑定邮箱和手机立即绑定

为什么 IAudioEndpointVolume::SetMute 不适用于 C# Interop?

为什么 IAudioEndpointVolume::SetMute 不适用于 C# Interop?

C#
慕丝7291255 2021-11-28 19:52:39
我正在尝试IAudioEndpointVolume::SetMute使用 Interop 从 C#调用 Windows Core Audio 。使用 C++ 实现,它工作正常。但是当我尝试从 C# 应用程序执行相同的调用时,没有任何变化。C# 应用程序的奇怪之处在于,如果我调用SetMute什么都不会发生,但是如果我调用SetMasterVolumeLevelScalar,它会有效地改变音量。我的实现是这样的:using System;using System.Runtime.InteropServices;namespace App{    [ComImport]    [Guid("A95664D2-9614-4F35-A746-DE8DB63617E6"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]    interface IMMDeviceEnumerator    {        void _VtblGap1_1();        int GetDefaultAudioEndpoint(int dataFlow, int role, out IMMDevice ppDevice);    }    [Guid("D666063F-1587-4E43-81F1-B948E807363F"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]    interface IMMDevice    {        int Activate([MarshalAs(UnmanagedType.LPStruct)] Guid iid, int dwClsCtx, IntPtr pActivationParams, [MarshalAs(UnmanagedType.IUnknown)] out object ppInterface);        int OpenPropertyStore([MarshalAs(UnmanagedType.U4)] UInt32 accessMode, [MarshalAs(UnmanagedType.Interface)] out object properties);        int GetId([MarshalAs(UnmanagedType.LPWStr)] out string strId);    }Interop 实现有什么问题吗?
查看完整描述

1 回答

?
慕村9548890

TA贡献1884条经验 获得超4个赞

我努力尝试并最终成功,这些“_VtblGaps_”是关键......只需将所有内容复制粘贴到一个新的 C# 脚本中并从您的程序脚本中使用:


using System;

using System.Runtime.InteropServices;

using System.Windows.Forms;


namespace MMDeviceAPI

{

public class MMDeviceController

{

    [ComImport]

    [Guid("BCDE0395-E52F-467C-8E3D-C4579291692E")]

    private class MMDeviceEnumerator

    {

    }


    [Guid("A95664D2-9614-4F35-A746-DE8DB63617E6"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]

    private interface IMMDeviceEnumerator

    {

        void _VtblGap1_1();

        //void _VtblGap1_5(); /// (Alternative)

        [PreserveSig]

        int GetDefaultAudioEndpoint(EDataFlow dataFlow, ERole role, out IMMDevice ppDevice);

    }

    [Guid("D666063F-1587-4E43-81F1-B948E807363F"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]

    private interface IMMDevice

    {

        [PreserveSig]

        int Activate([MarshalAs(UnmanagedType.LPStruct)] Guid iid, int dwClsCtx, IntPtr pActivationParams, [MarshalAs(UnmanagedType.IUnknown)] out object ppInterface);

        void _VtblGap1_1();

        int GetId([MarshalAs(UnmanagedType.LPWStr)] out string strId);

    }

    [Guid("5CDF2C82-841E-4546-9722-0CF74078229A"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]

    private interface IAudioEndpointVolume

    {

    }

    [Guid("5CDF2C82-841E-4546-9722-0CF74078229A"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]

    private interface IGetChannelCount : IAudioEndpointVolume

    {

        void _VtblGap1_2();

        int GetChannelCount(ref uint pnChannelCount);

    }

    [Guid("5CDF2C82-841E-4546-9722-0CF74078229A"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]

    private interface IGetChannelVolumeLevelScalar : IAudioEndpointVolume

    {

        void _VtblGap1_10();

        int GetChannelVolumeLevelScalar(uint nChannel, ref float pfLevel);

    }

    [Guid("5CDF2C82-841E-4546-9722-0CF74078229A"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]

    private interface IGetMasterVolumeLevelScalar : IAudioEndpointVolume

    {

        void _VtblGap1_6();

        int GetMasterVolumeLevelScalar(ref float pfLevel);

    }

    [Guid("5CDF2C82-841E-4546-9722-0CF74078229A"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]

    private interface IGetMute : IAudioEndpointVolume

    {

        void _VtblGap1_12();

        int GetMute([MarshalAs(UnmanagedType.Bool)] ref bool pbMute);

    }

    [Guid("5CDF2C82-841E-4546-9722-0CF74078229A"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]

    private interface ISetChannelVolumeLevelScalar : IAudioEndpointVolume

    {

        void _VtblGap1_8();

        int SetChannelVolumeLevelScalar(uint nChannel, float fLevel, [MarshalAs(UnmanagedType.LPStruct)] Guid pguidEventContext);

    }

    [Guid("5CDF2C82-841E-4546-9722-0CF74078229A"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]

    private interface ISetMasterVolumeLevelScalar : IAudioEndpointVolume

    {

        void _VtblGap1_4();

        int SetMasterVolumeLevelScalar(float fLevel, [MarshalAs(UnmanagedType.LPStruct)] Guid pguidEventContext);

    }

    [Guid("5CDF2C82-841E-4546-9722-0CF74078229A"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]

    private interface ISetMute : IAudioEndpointVolume

    {

        void _VtblGap1_11();

        int SetMute([MarshalAs(UnmanagedType.Bool)] bool bMute, [MarshalAs(UnmanagedType.LPStruct)] Guid pguidEventContext);

    }


    public enum EDataFlow { eRender, eCapture, eAll };

    public enum ERole { eConsole, eMultimedia, eCommunications };


    ///====================================================================================================


    private static IAudioEndpointVolume GetMMDeviceAudioEndpointVolume(EDataFlow dataFlow, ERole role)

    {

        IMMDeviceEnumerator MMDeviceEnumerator = (IMMDeviceEnumerator)(new MMDeviceEnumerator());

        MMDeviceEnumerator.GetDefaultAudioEndpoint(dataFlow, role, out IMMDevice MMDevice);

        MMDevice.Activate(typeof(IAudioEndpointVolume).GUID, 0, IntPtr.Zero, out object o);

        IAudioEndpointVolume AudioEndpointVolume = (IAudioEndpointVolume)o;


        Marshal.ReleaseComObject(MMDevice);

        Marshal.ReleaseComObject(MMDeviceEnumerator);


        return AudioEndpointVolume;

    }


    public static uint GetChannelCount(EDataFlow dataFlow, ERole role)

    {

        IGetChannelCount AudioEndpointVolume = (IGetChannelCount)GetMMDeviceAudioEndpointVolume(dataFlow, role);


        uint returnValue = 0;

        AudioEndpointVolume.GetChannelCount(ref returnValue);


        Marshal.ReleaseComObject(AudioEndpointVolume);

        return returnValue;

    }


    public static float GetChannelVolumeLevelScalar(EDataFlow dataFlow, ERole role, uint channel)

    {

        IGetChannelVolumeLevelScalar AudioEndpointVolume = (IGetChannelVolumeLevelScalar)GetMMDeviceAudioEndpointVolume(dataFlow, role);


        float returnValue = 0;

        AudioEndpointVolume.GetChannelVolumeLevelScalar(channel, ref returnValue);


        Marshal.ReleaseComObject(AudioEndpointVolume);

        return returnValue;

    }


    public static float GetMasterVolumeLevelScalar(EDataFlow dataFlow, ERole role)

    {

        IGetMasterVolumeLevelScalar AudioEndpointVolume = (IGetMasterVolumeLevelScalar)GetMMDeviceAudioEndpointVolume(dataFlow, role);


        float returnValue = 0f;

        AudioEndpointVolume.GetMasterVolumeLevelScalar(ref returnValue);


        Marshal.ReleaseComObject(AudioEndpointVolume);

        return returnValue;

    }


    public static bool GetMute(EDataFlow dataFlow, ERole role)

    {

        IGetMute AudioEndpointVolume = (IGetMute)GetMMDeviceAudioEndpointVolume(dataFlow, role);


        bool returnValue = false;

        AudioEndpointVolume.GetMute(ref returnValue);


        Marshal.ReleaseComObject(AudioEndpointVolume);

        return returnValue;

    }


    public static void SetChannelVolumeLevelScalar(EDataFlow dataFlow, ERole role, uint channel, float volume)

    {

        ISetChannelVolumeLevelScalar AudioEndpointVolume = (ISetChannelVolumeLevelScalar)GetMMDeviceAudioEndpointVolume(dataFlow, role);


        AudioEndpointVolume.SetChannelVolumeLevelScalar(channel, volume, Guid.Empty);


        Marshal.ReleaseComObject(AudioEndpointVolume);

    }


    public static void SetMasterVolumeLevelScalar(EDataFlow dataFlow, ERole role, float volume)

    {

        ISetMasterVolumeLevelScalar AudioEndpointVolume = (ISetMasterVolumeLevelScalar)GetMMDeviceAudioEndpointVolume(dataFlow, role);


        AudioEndpointVolume.SetMasterVolumeLevelScalar(volume, Guid.Empty);


        Marshal.ReleaseComObject(AudioEndpointVolume);

    }


    public static void SetMute(EDataFlow dataFlow, ERole role, bool mute)

    {

        ISetMute AudioEndpointVolume = (ISetMute)GetMMDeviceAudioEndpointVolume(dataFlow, role);


        AudioEndpointVolume.SetMute(mute, Guid.Empty);


        Marshal.ReleaseComObject(AudioEndpointVolume);

    }


    ///====================================================================================================


    public static void TestFunctionality()

    {

        int device = 0;

        EDataFlow dataFlow;

        ERole eRole;


        while (true)

        {

            device++;


            switch (device)

            {

                case 1:

                dataFlow = EDataFlow.eRender;

                eRole = ERole.eMultimedia;

                break;

                case 2:

                dataFlow = EDataFlow.eCapture;

                eRole = ERole.eMultimedia;

                break;

                default:

                return;

            }


            MessageBox.Show($"[EDataFlow & ERole]:  {dataFlow.ToString()}_{eRole.ToString()}");

            uint channels = GetChannelCount(dataFlow, eRole); MessageBox.Show("[GetChannelCount]:  " + channels);

            MessageBox.Show("[GetChannelVolumeLevelScalar #0]:  " + GetChannelVolumeLevelScalar(dataFlow, eRole, 0).ToString());

            if (channels > 1) { MessageBox.Show("[GetChannelVolumeLevelScalar #1]:  " + GetChannelVolumeLevelScalar(dataFlow, eRole, 1).ToString()); }

            MessageBox.Show("[GetMasterVolumeLevelScalar]:  " + GetMasterVolumeLevelScalar(dataFlow, eRole).ToString());

            MessageBox.Show("[GetMute]:  " + GetMute(dataFlow, eRole).ToString());

            MessageBox.Show("[SetChannelVolumeLevelScalar #0]:  0.44"); SetChannelVolumeLevelScalar(dataFlow, eRole, 0, 0.44f);

            if (channels > 1) { MessageBox.Show("[SetChannelVolumeLevelScalar #1]:  0.88"); SetChannelVolumeLevelScalar(dataFlow, eRole, 1, 0.88f); }

            MessageBox.Show("[SetMasterVolumeLevelScalar]:  0.55"); SetMasterVolumeLevelScalar(dataFlow, eRole, 0.55f);

            MessageBox.Show("[SetMute]:  false"); SetMute(dataFlow, eRole, false);

        }

    }


    ///====================================================================================================

}

}



查看完整回答
反对 回复 2021-11-28
  • 1 回答
  • 0 关注
  • 279 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信