如何插入或拔出扬声器

时间:2016-12-12 09:18:13

标签: vb.net audio hardware

我使用Visual Studio 2013 for Visual Basic,我希望能够测试扬声器是插入扬声器插头还是从扬声器插孔中拔出。有可能吗?

1 个答案:

答案 0 :(得分:0)

可以使用Device Topology API完成。 MACOSX_DEPLOYMENT_TARGET接口可用于获取IKsJackDescription结构,其中包含KSJACK_DESCRIPTION成员。但是,并非每个设备都支持电缆存在检测,如果它没有,API将始终报告它已连接。

COM对象声明

IsConnected

示例如何获取有关当前默认设备的插孔信息的信息

Imports System
Imports System.Collections.Generic
Imports System.Text
Imports System.Runtime.InteropServices
Imports System.IO
Imports System.Runtime.CompilerServices

Namespace com_test

    Class Native


        <DllImport("ole32.Dll")> _
        Public Shared Function CoCreateInstance(ByRef clsid As Guid, <MarshalAs(UnmanagedType.IUnknown)> inner As Object, context As UInteger, ByRef uuid As Guid, <MarshalAs(UnmanagedType.IUnknown)> ByRef rReturnedComObject As Object) As UInteger
        End Function

        '************************************************************************

        <DllImport("ole32.dll")> _
        Private Shared Function PropVariantClear(ByRef pvar As PropVariant) As Integer
        End Function



        Public Const DEVICE_STATE_ACTIVE As Integer = &H1

        Public Const DEVICE_STATE_DISABLE As Integer = &H2

        Public Const DEVICE_STATE_NOTPRESENT As Integer = &H4

        Public Const DEVICE_STATE_UNPLUGGED As Integer = &H8

        Public Const DEVICE_STATEMASK_ALL As Integer = &Hf


        Public Shared PKEY_Device_FriendlyName As New PROPERTYKEY(&Ha45c254eUI, &Hdf1c, &H4efd, &H80, &H20, &H67, _
            &Hd1, &H46, &Ha8, &H50, &He0, 14)




        Public Shared PKEY_AudioEndpoint_FormFactor As New PROPERTYKEY(&H1da5d803, &Hd492, &H4edd, &H8c, &H23, &He0, _
            &Hc0, &Hff, &Hee, &H7f, &He, 0)



    End Class



    Enum EndpointFormFactor


        RemoteNetworkDevice = 0

        Speakers = (RemoteNetworkDevice + 1)

        LineLevel = (Speakers + 1)

        Headphones = (LineLevel + 1)

        Microphone = (Headphones + 1)

        Headset = (Microphone + 1)

        Handset = (Headset + 1)

        UnknownDigitalPassthrough = (Handset + 1)

        SPDIF = (UnknownDigitalPassthrough + 1)

        DigitalAudioDisplayDevice = (SPDIF + 1)

        UnknownFormFactor = (DigitalAudioDisplayDevice + 1)

        EndpointFormFactor_enum_count = (UnknownFormFactor + 1)

    End Enum



    Enum EPcxConnectionType


        eConnTypeUnknown = 0

        eConnType3Point5mm

        eConnTypeQuarter

        eConnTypeAtapiInternal

        eConnTypeRCA

        eConnTypeOptical

        eConnTypeOtherDigital

        eConnTypeOtherAnalog

        eConnTypeMultichannelAnalogDIN

        eConnTypeXlrProfessional

        eConnTypeRJ11Modem

        eConnTypeCombination

    End Enum



    Enum EPcxGeoLocation


        eGeoLocRear = &H1

        eGeoLocFront

        eGeoLocLeft

        eGeoLocRight

        eGeoLocTop

        eGeoLocBottom

        eGeoLocRearPanel

        eGeoLocRiser

        eGeoLocInsideMobileLid

        eGeoLocDrivebay

        eGeoLocHDMI

        eGeoLocOutsideMobileLid

        eGeoLocATAPI

        eGeoLocNotApplicable

        eGeoLocReserved6

        EPcxGeoLocation_enum_count

    End Enum



    Public Enum EDataFlow


        eRender

        eCapture

        eAll

        EDataFlow_enum_count

    End Enum



    Public Enum ERole


        eConsole

        eMultimedia

        eCommunications

        ERole_enum_count

    End Enum



    Public Enum CLSCTX


        CLSCTX_INPROC_SERVER = &H1

        CLSCTX_INPROC_HANDLER = &H2

        CLSCTX_LOCAL_SERVER = &H4

        CLSCTX_REMOTE_SERVER = &H10


        CLSCTX_SERVER = (CLSCTX_INPROC_SERVER Or CLSCTX_LOCAL_SERVER Or CLSCTX_REMOTE_SERVER)

        CLSCTX_ALL = (CLSCTX_INPROC_HANDLER Or CLSCTX_SERVER)

    End Enum



    'Windows Core Audio API declarations

    'http://www.java2s.com/Code/CSharp/Windows/SoundUtils.htm





    <Guid("0BD7A1BE-7A1A-44DB-8397-CC5392387B5E"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)> _
    Public Interface IMMDeviceCollection


        Function GetCount(ByRef pcDevices As UInteger) As Integer

        Function Item(nDevice As UInteger, <Out, MarshalAs(UnmanagedType.[Interface])> ByRef ppDevice As Object) As Integer

    End Interface





    <Guid("D666063F-1587-4E43-81F1-B948E807363F"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)> _
    Public Interface IMMDevice



        Function Activate(ByRef iid As Guid, dwClsCtx As UInteger, pActivationParams As IntPtr, <Out, MarshalAs(UnmanagedType.[Interface])> ByRef ppInterface As Object) As Integer



        Function OpenPropertyStore(stgmAccess As Integer, <Out, MarshalAs(UnmanagedType.[Interface])> ByRef ppProperties As Object) As Integer



        Function GetId(ByRef ppstrId As StringBuilder) As Integer



        Function GetState(ByRef pdwState As Integer) As Integer

    End Interface




    <ComImport, Guid("BCDE0395-E52F-467C-8E3D-C4579291692E")> _
    Class MMDeviceEnumerator


    End Class





    <Guid("A95664D2-9614-4F35-A746-DE8DB63617E6"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)> _
    Public Interface IMMDeviceEnumerator





        Function EnumAudioEndpoints(dataFlow As EDataFlow, dwStateMask As Integer, <Out, MarshalAs(UnmanagedType.[Interface])> ByRef ppDevices As Object) As Integer




        Function GetDefaultAudioEndpoint(dataFlow As EDataFlow, role As ERole, <Out, MarshalAs(UnmanagedType.[Interface])> ByRef ppEndpoint As Object) As Integer



        Function GetDevice(pwstrId As String, ByRef ppDevice As IntPtr) As Integer



        Function RegisterEndpointNotificationCallback(pClient As IntPtr) As Integer



        Function UnregisterEndpointNotificationCallback(pClient As IntPtr) As Integer

    End Interface





    '*********** Property store *****************************



    ' https://blogs.msdn.microsoft.com/adamroot/2008/04/11/interop-with-propvariants-in-net/




    <ComImport, Guid("886D8EEB-8CF2-4446-8D02-CDBA1DBDCF99"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)> _
    Interface IPropertyStore



        <MethodImpl(MethodImplOptions.InternalCall, MethodCodeType := MethodCodeType.Runtime)> _
        Sub GetCount(<Out> ByRef cProps As UInteger)




        <MethodImpl(MethodImplOptions.InternalCall, MethodCodeType := MethodCodeType.Runtime)> _
        Sub GetAt(<[In]> iProp As UInteger, ByRef pkey As PROPERTYKEY)




        <MethodImpl(MethodImplOptions.InternalCall, MethodCodeType := MethodCodeType.Runtime)> _
        Function GetValue(<[In]> ByRef key As PROPERTYKEY, ByRef pv As PropVariant) As Integer




        <MethodImpl(MethodImplOptions.InternalCall, MethodCodeType := MethodCodeType.Runtime)> _
        Sub SetValue(<[In]> ByRef key As PROPERTYKEY, <[In]> ByRef pv As Object)




        <MethodImpl(MethodImplOptions.InternalCall, MethodCodeType := MethodCodeType.Runtime)> _
        Sub Commit()

    End Interface




    <StructLayout(LayoutKind.Sequential, Pack := 4)> _
    Structure PROPERTYKEY


        Public fmtid As Guid

        Public pid As UInteger



        Public Sub New(guid As Guid, propertyId As Integer)


            Me.fmtid = guid


            Me.pid = CUInt(propertyId)
        End Sub

        Public Sub New(formatId As String, propertyId As Integer)

            Me.New(New Guid(formatId), propertyId)


        End Sub


        Public Sub New(a As UInteger, b As UInteger, c As UInteger, d As UInteger, e As UInteger, f As UInteger, _
            g As UInteger, h As UInteger, i As UInteger, j As UInteger, k As UInteger, propertyId As Integer)


            Me.New(New Guid(CUInt(a), CUShort(b), CUShort(c), CByte(d), CByte(e), CByte(f), _
                CByte(g), CByte(h), CByte(i), CByte(j), CByte(k)), propertyId)


        End Sub

    End Structure




    <StructLayout(LayoutKind.Sequential)> _
    Public Structure PropVariant


        Private vt As UShort

        Private wReserved1 As UShort

        Private wReserved2 As UShort

        Private wReserved3 As UShort

        Private p As IntPtr

        Private p2 As Integer



        Private Function GetDataBytes() As Byte()


            Dim ret As Byte() = New Byte(IntPtr.Size + (4 - 1)) {}

            If IntPtr.Size = 4 Then

                BitConverter.GetBytes(p.ToInt32()).CopyTo(ret, 0)

            ElseIf IntPtr.Size = 8 Then

                BitConverter.GetBytes(p.ToInt64()).CopyTo(ret, 0)
            End If

            BitConverter.GetBytes(p2).CopyTo(ret, IntPtr.Size)

            Return ret

        End Function



        Private ReadOnly Property cVal() As SByte
            ' CHAR cVal;

            Get
                Return CSByte(GetDataBytes()(0))
            End Get
        End Property




        Private ReadOnly Property iVal() As Short
            ' SHORT iVal;

            Get
                Return BitConverter.ToInt16(GetDataBytes(), 0)
            End Get
        End Property




        Private ReadOnly Property lVal() As Integer
            ' LONG lVal;

            Get
                Return BitConverter.ToInt32(GetDataBytes(), 0)
            End Get
        End Property




        Private ReadOnly Property hVal() As Long
            ' LARGE_INTEGER hVal;

            Get
                Return BitConverter.ToInt64(GetDataBytes(), 0)
            End Get
        End Property




        Private ReadOnly Property fltVal() As Single
            ' FLOAT fltVal;

            Get
                Return BitConverter.ToSingle(GetDataBytes(), 0)
            End Get
        End Property




        Public ReadOnly Property Value() As Object


            Get


                Select Case CType(vt, VarEnum)


                    Case VarEnum.VT_I1

                        Return cVal

                    Case VarEnum.VT_I2

                        Return iVal


                    Case VarEnum.VT_I4, VarEnum.VT_INT

                        Return lVal


                    Case VarEnum.VT_UI4, VarEnum.VT_I8

                        Return hVal

                    Case VarEnum.VT_R4

                        Return fltVal

                    Case VarEnum.VT_FILETIME
                        Return DateTime.FromFileTime(hVal)

                    Case VarEnum.VT_BSTR

                        Return Marshal.PtrToStringBSTR(p)

                    Case VarEnum.VT_BLOB

                        Dim blobData As Byte() = New Byte(lVal - 1) {}

                        Dim pBlobData As IntPtr

                        If IntPtr.Size = 4 Then



                            pBlobData = New IntPtr(p2)

                        ElseIf IntPtr.Size = 8 Then



                            pBlobData = New IntPtr(BitConverter.ToInt64(GetDataBytes(), 4))
                        Else


                            Throw New NotSupportedException()
                        End If

                        Marshal.Copy(pBlobData, blobData, 0, lVal)

                        Return blobData

                    Case VarEnum.VT_LPSTR

                        Return Marshal.PtrToStringAnsi(p)

                    Case VarEnum.VT_LPWSTR

                        Return Marshal.PtrToStringUni(p)

                    Case VarEnum.VT_UNKNOWN

                        Return Marshal.GetObjectForIUnknown(p)

                    Case VarEnum.VT_DISPATCH

                        Return p
                    Case Else


                        Throw New NotSupportedException("0x" + vt.ToString("X4") + " type not supported")


                End Select
            End Get
        End Property




    End Structure

    '*****************************************************



    'Device Topology declarations





    <Guid("2A07407E-6497-4A18-9787-32F79BD0D98F"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)> _
    Public Interface IDeviceTopology


        Function GetConnectorCount(<Out> ByRef pConnectorCount As Integer) As Integer

        Function GetConnector(nIndex As Integer, ByRef ppConnector As IConnector) As Integer

        Function GetSubunitCount(<Out> ByRef pCount As Integer) As Integer

        'ISubunit
        Function GetSubunit(nIndex As Integer, ByRef ppSubunit As Object) As Integer

        Function GetPartById(nId As Integer, ByRef ppPart As IPart) As Integer

        Function GetDeviceId(<Out, MarshalAs(UnmanagedType.LPWStr)> ByRef ppwstrDeviceId As String) As Integer

        'IPartsList
        Function GetSignalPath(pIPartFrom As IPart, pIPartTo As IPart, bRejectMixedPaths As Boolean, ppParts As Object) As Integer

    End Interface







    <InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("9c2c4058-23f5-41de-877a-df3af236a09e")> _
    Public Interface IConnector


        Function [GetType](ByRef pType As Integer) As Integer

        Function GetDataFlow(ByRef dataFlow As EDataFlow) As Integer

        Function ConnectTo(<[In]> connector As IConnector) As Integer

        Function Disconnect() As Integer

        Function IsConnected(ByRef pbConnected As Boolean) As Integer

        Function GetConnectedTo(<MarshalAs(UnmanagedType.[Interface])> ByRef ppConTo As Object) As Integer

        Function GetConnectorIdConnectedTo(ByRef ppwstrConnectorId As String) As Integer

        Function GetDeviceIdConnectedTo(ByRef ppwstrDeviceId As String) As Integer

    End Interface





    <Guid("AE2DE0E4-5BCA-4F2D-AA46-5D13F8FDB3A9"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)> _
    Public Interface IPart


        Function GetName(ByRef ppwstrName As StringBuilder) As Integer

        Function GetLocalId(ByRef pnId As Integer) As Integer

        Function GetGlobalId(ByRef ppwstrGlobalId As StringBuilder) As Integer

        Function GetPartType(ByRef pPartType As Integer) As Integer

        Function GetSubType(ByRef pSubType As Guid) As Integer

        Function GetControlInterfaceCount(ByRef pCount As UInteger) As Integer



        'IControlInterface
        Function GetControlInterface(nIndex As Integer, ByRef ppFunction As Object) As Integer

        'IPartsList[]
        Function EnumPartsIncoming(ByRef ppParts As Object) As Integer

        'IPartsList[]
        Function EnumPartsOutgoing(ByRef ppParts As Object) As Integer



        Function GetTopologyObject(<Out, MarshalAs(UnmanagedType.[Interface])> ByRef ppTopology As Object) As Integer






        Function Activate(dwClsContext As UInteger, ByRef refiid As Guid, <MarshalAs(UnmanagedType.[Interface])> ByRef interfacePointer As Object) As Integer

        'IControlChangeNotify
        Function RegisterControlChangeCallback(ByRef riid As Guid, pNofity As Object) As Integer

        'IControlChangeNotify
        Function UnregisterControlChangeCallback(pNotify As Object) As Integer

    End Interface



    <ComVisible(False)> _
    <ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("4509F757-2D46-4637-8E62-CE7DB944F57B")> _
    Public Interface IKsJackDescription


        Function GetJackCount(ByRef jacks As UInteger) As Integer

        Function GetJackDescription(jack As UInteger, ByRef pDescription As KSJACK_DESCRIPTION) As Integer

    End Interface




    <StructLayout(LayoutKind.Sequential)> _
    Public Structure KSJACK_DESCRIPTION


        Public ChannelMapping As UInteger

        Public Color As UInteger

        Public ConnectionType As UInteger

        Public GeoLocation As UInteger

        Public GenLocation As UInteger

        Public PortConnection As UInteger

        Public IsConnected As UInteger

    End Structure


End Namespace