views:

671

answers:

3

Hello, Happy new year! My question is how to check if a microphone and a speaker are from the same sound card on Windows platform. If they are from different cards, then the logic to handling timing will be different. I'm using both DSound and WMME API. Thanks in advance.

regards, Yun

+1  A: 

WMI does give some information about sound cards. What I haven't been able to find out yet is whether its giving enough. Using "WMI Code Creator" the following script lists everything that the Win32_SoundDevice object stores:

strComputer = "." 
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\CIMV2") 
Set colItems = objWMIService.ExecQuery( _
    "SELECT * FROM Win32_SoundDevice",,48) 
For Each objItem in colItems 
    Wscript.Echo "-----------------------------------"
    Wscript.Echo "Win32_SoundDevice instance"
    Wscript.Echo "-----------------------------------"
    Wscript.Echo "Availability: " & objItem.Availability
    Wscript.Echo "Caption: " & objItem.Caption
    Wscript.Echo "ConfigManagerErrorCode: " & objItem.ConfigManagerErrorCode
    Wscript.Echo "ConfigManagerUserConfig: " & objItem.ConfigManagerUserConfig
    Wscript.Echo "CreationClassName: " & objItem.CreationClassName
    Wscript.Echo "Description: " & objItem.Description
    Wscript.Echo "DeviceID: " & objItem.DeviceID
    Wscript.Echo "DMABufferSize: " & objItem.DMABufferSize
    Wscript.Echo "ErrorCleared: " & objItem.ErrorCleared
    Wscript.Echo "ErrorDescription: " & objItem.ErrorDescription
    Wscript.Echo "InstallDate: " & objItem.InstallDate
    Wscript.Echo "LastErrorCode: " & objItem.LastErrorCode
    Wscript.Echo "Manufacturer: " & objItem.Manufacturer
    Wscript.Echo "MPU401Address: " & objItem.MPU401Address
    Wscript.Echo "Name: " & objItem.Name
    Wscript.Echo "PNPDeviceID: " & objItem.PNPDeviceID
    If isNull(objItem.PowerManagementCapabilities) Then
 Wscript.Echo "PowerManagementCapabilities: "
    Else
 Wscript.Echo "PowerManagementCapabilities: " & Join(objItem.PowerManagementCapabilities, ",")
    End If
    Wscript.Echo "PowerManagementSupported: " & objItem.PowerManagementSupported
    Wscript.Echo "ProductName: " & objItem.ProductName
    Wscript.Echo "Status: " & objItem.Status
    Wscript.Echo "StatusInfo: " & objItem.StatusInfo
    Wscript.Echo "SystemCreationClassName: " & objItem.SystemCreationClassName
    Wscript.Echo "SystemName: " & objItem.SystemName
Next

Running that on my laptop gives

-----------------------------------
Win32_SoundDevice instance
-----------------------------------
Availability: 
Caption: ATI Function Driver for High Definition Audio - ATI AA01
ConfigManagerErrorCode: 0
ConfigManagerUserConfig: False
CreationClassName: Win32_SoundDevice
Description: ATI Function Driver for High Definition Audio - ATI AA01
DeviceID: HDAUDIO\FUNC_01&VEN_1002&DEV_AA01&SUBSYS_00AA0100&REV_1000\5&BB7E0F3&0&0001
DMABufferSize: 
ErrorCleared: 
ErrorDescription: 
InstallDate: 
LastErrorCode: 
Manufacturer: ATI
MPU401Address: 
Name: ATI Function Driver for High Definition Audio - ATI AA01
PNPDeviceID: HDAUDIO\FUNC_01&VEN_1002&DEV_AA01&SUBSYS_00AA0100&REV_1000\5&BB7E0F3&0&0001
PowerManagementCapabilities: 
PowerManagementSupported: False
ProductName: ATI Function Driver for High Definition Audio - ATI AA01
Status: OK
StatusInfo: 3
SystemCreationClassName: Win32_ComputerSystem
SystemName: BABEL
-----------------------------------
Win32_SoundDevice instance
-----------------------------------
Availability: 
Caption: Conexant High Definition SmartAudio 221
ConfigManagerErrorCode: 0
ConfigManagerUserConfig: False
CreationClassName: Win32_SoundDevice
Description: Conexant High Definition SmartAudio 221
DeviceID: HDAUDIO\FUNC_01&VEN_14F1&DEV_5051&SUBSYS_1179FF5B&REV_1000\4&2DBDAC14&0&0001
DMABufferSize: 
ErrorCleared: 
ErrorDescription: 
InstallDate: 
LastErrorCode: 
Manufacturer: Conexant
MPU401Address: 
Name: Conexant High Definition SmartAudio 221
PNPDeviceID: HDAUDIO\FUNC_01&VEN_14F1&DEV_5051&SUBSYS_1179FF5B&REV_1000\4&2DBDAC14&0&0001
PowerManagementCapabilities: 
PowerManagementSupported: False
ProductName: Conexant High Definition SmartAudio 221
Status: OK
StatusInfo: 3
SystemCreationClassName: Win32_ComputerSystem
SystemName: BABEL

I don't know if there's anything in there that helps. It's a tough question.

boost
A: 

Never use WMI (nothing to do here) Use MM apis.

+1  A: 

Assuming you have the ID of the input and output devices, you could use something like the following to get the corresponding mixer IDs. If both are the same, both are attached to the same mixer, and most likely part of the same physical hardware.

    /// <summary>
    /// Get the ID of the mixer associated with the given input device ID
    /// Returns -1 if no such mixer can be found
    /// </summary>
    static public int GetMixerIdInput(int inputId)
    {
        int mixerId = -1;
        int result = MmeMixerApi.mixerGetID(inputId, ref mixerId, MIXER_OBJECTFLAG.WAVEIN);
        if (((MMError)result != MMError.MMSYSERR_NOERROR) &&
            ((MMError)result != MMError.MMSYSERR_NODRIVER))
        {
            throw new MmeException((MMError)result);
        }
        return mixerId;
    }

    /// <summary>
    /// Get the ID of the mixer associated with the given output device ID
    /// Returns -1 if no such mixer can be found
    /// </summary>
    static public int GetMixerIdOutput(int outputId)
    {
        int mixerId = -1;
        int result = MmeMixerApi.mixerGetID(outputId, ref mixerId, MIXER_OBJECTFLAG.WAVEOUT);
        if (((MMError)result != MMError.MMSYSERR_NOERROR) &&
            ((MMError)result != MMError.MMSYSERR_NODRIVER))
        {
            throw new MmeException((MMError)result);
        }
        return mixerId;
    }

If you only have the name for the input device, you can use something like the following to find the device ID:

    /// <summary>
    /// Find the ID of the input device given a name
    /// </summary>
    static public int GetWaveInputId(string name)
    {
        int id = MmeWaveApi.WAVE_MAPPER;
        int devCount = MmeWaveApi.waveInGetNumDevs();
        WAVEINCAPS caps = new WAVEINCAPS();
        for (int dev = 0; (dev < devCount) && (id == MmeWaveApi.WAVE_MAPPER); dev++)
        {
            int result = MmeWaveApi.waveInGetDevCaps(dev, ref caps, Marshal.SizeOf(caps));
            if ((MMError)result == MMError.MMSYSERR_NOERROR)
            {
                if (string.Compare(name, 0, caps.szPname, 0, Math.Min(name.Length, caps.szPname.Length)) == 0)
                {
                    id = dev;
                }
            }
        }
        return id;
    }
Han