CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 13 of 13
  1. #1
    John E is offline Elite Member Power Poster
    Join Date
    Apr 2001
    Location
    Manchester, England
    Posts
    4,867

    Getting basic device information

    I need to find out (programmatically) whether the installed sound card supports duplex operation (i.e. recording and playing back simultaneously). I realise that most modern cards do support this but I still need to check.

    I've discovered that waveInGetDevCaps() and waveOutGetDevCaps() will give me information about individual inputs & outputs but I can't find anything to tell me if the card supports duplex operation. In fact I can't even find anything to tell me the name of the sound card (although the above functions do tell me the names of the various inputs & outputs). I thought this would be supported in mmsystem.h and winmm.dll but I guess I must be looking in the wrong place. Can anyone point me in the right direction?
    "A problem well stated is a problem half solved.” - Charles F. Kettering

  2. #2
    John E is offline Elite Member Power Poster
    Join Date
    Apr 2001
    Location
    Manchester, England
    Posts
    4,867

    Re: Getting basic device information

    I received a PM telling me that the answer could be found here:-

    news://comp.os.ms-windows.programmer.win32

    but although my email client (Outlook Express) looks like it can join me to news groups, I can't seem to join this particular one (Outlook Express keeps saying that it can't connect to the server). Is there something wrong with that URL or do I need to use a different kind of app to connect to a news service?
    "A problem well stated is a problem half solved.” - Charles F. Kettering

  3. #3
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    Re: Getting basic device information

    Check out WMI and the Win32_SoundDevice class.

    As far as the newsgroup link, consider it spam.

  4. #4
    Join Date
    May 2000
    Location
    KY, USA
    Posts
    18,652

    Re: Getting basic device information

    Quote Originally Posted by John E View Post
    I received a PM telling me that the answer could be found here:-

    news://comp.os.ms-windows.programmer.win32

    but although my email client (Outlook Express) looks like it can join me to news groups, I can't seem to join this particular one (Outlook Express keeps saying that it can't connect to the server). Is there something wrong with that URL or do I need to use a different kind of app to connect to a news service?
    You can browse the newsgroup with you web browser by going to the following address:

    http://groups.google.com/group/comp....r.win32/topics

  5. #5
    Join Date
    Jan 2008
    Posts
    48

    Re: Getting basic device information

    Configure Usenet with Windows Mail :
    http://support.cox.com/sdccommon/asp...b-9ad40513af96

    The answer had indeed been given several years ago on Win32 api newsgroup
    It's the reference for Win32 api, in particular undocumented ones never seen elsewhere and for source code for all the Win32 80 000 apis (from Wine and other...),
    like Codeguru is the reference for MFC.
    MS newsgroups are not bad also, for Kernel and DDK, but newer, then archives are not huge like for Usenet....
    Last edited by Laurentis; January 13th, 2009 at 05:48 AM.

  6. #6
    John E is offline Elite Member Power Poster
    Join Date
    Apr 2001
    Location
    Manchester, England
    Posts
    4,867

    Re: Getting basic device information

    Thanks for persevering guys. I must admit, I'm struggling to find an API that will just give me the name of the installed sound card(s). Arjay's WMI SoundDevice class looked promising but I couldn't find a clear example of using it.

    Any more ideas ?
    "A problem well stated is a problem half solved.” - Charles F. Kettering

  7. #7
    Join Date
    Nov 2003
    Posts
    1,902

    Re: Getting basic device information

    >> The answer had ... been given ... on Win32 api newsgroup
    That's about as helpful as "the answer is on the internet". Spam indeed.

    >> API that will just give me the name of the installed sound card(s)
    I can help with that at least (non WMI version)
    http://www.codeguru.com/forum/showthread.php?t=453421

    For duplex detection, have you dug around the DirectX api's?
    http://www.codeguru.com/forum/showthread.php?t=424415

    gg

  8. #8
    John E is offline Elite Member Power Poster
    Join Date
    Apr 2001
    Location
    Manchester, England
    Posts
    4,867

    Re: Getting basic device information

    Thanks Codeplug. I haven't tried your second link yet but I copied the code from your first link and it kinda worked. I ran the full program and it produced the output [MPU-401 Compatible MIDI Device] which is indeed listed by Device Manager under Sound,Video and Game Controllers. Strangely though, it didn't list my actual sound card which is shown in Device manager as RME HDSP 9632.

    I've tried a few variations on the same theme (i.e. sending different GUID's to your function ListDeviceClassData(..) but I can't find anything that lists my actual sound card. Any ideas?
    "A problem well stated is a problem half solved.” - Charles F. Kettering

  9. #9
    Join Date
    Nov 2003
    Posts
    1,902

    Re: Getting basic device information

    Here's the list of "device interface class" GUIDs: http://msdn.microsoft.com/en-us/library/bb663138.aspx

    Here are the relevant device interface class's for audio devices: http://msdn.microsoft.com/en-us/library/ms790578.aspx

    KSCATEGORY_AUDIO would probably be better, but you may have to filter out "ROOT\SYSTEM\0000", which shows up on my systems.
    Code:
        const GUID KSAudioDevIntGuid = // KSCATEGORY_AUDIO
            {0x6994AD04, 0x93EF, 0x11D0,
                {0xA3, 0xCC, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}};
    
        const GUID KSCaptureDevIntGuid = // KSCATEGORY_CAPTURE
            {0x65E8773D, 0x8F56, 0x11D0,
                {0xA3, 0xB9, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}};
    gg

  10. #10
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    Re: Getting basic device information

    Here's a WMI C++ example (see the attached file for complete source). The sample retrieves processor, sound card and memory information.

    FYI: One of the hardest things with using WMI is to determine which class and properties are available. To help with this, download the WMI Administrative Tools and use the WMI CIM Studio Tool to view the class and property information.

    Code:
    int _tmain(int argc, _TCHAR* argv[])
    {
    	HRESULT hr = CoInitialize( NULL );
    
    	{	// Scope all smart pointers (so they release before CoUninitialize is called)
    
    		IWbemServicesPtr spServicesPtr;
    		IWbemClassObjectPtr spProcessor;
    		IEnumWbemClassObjectPtr spSoundDeviceEnum;
    		IWbemClassObjectPtr spSoundDevice;
    		IEnumWbemClassObjectPtr spPhysicalMemoryEnum;
    		IWbemClassObjectPtr spPhysicalMemory;
    
    		try
    		{
    			CWMIHelper wmiHelper;
    
    			wmiHelper.Connect( );
    
    			wmiHelper.GetWMIClassObject( L"Win32_Processor.DeviceID=\"CPU0\"", spProcessor );	
    
    			tcout << _T("Processor:") << std::endl;
    
    			PrintProperty( _T("Description\t\t" ), wmiHelper.GetPropertyString( spProcessor, _T("Description") ) );
    			PrintProperty( _T("Manufacturer\t\t" ), wmiHelper.GetPropertyString( spProcessor, _T("Manufacturer") ) );
    			PrintProperty( _T("ProcessorId\t\t" ), wmiHelper.GetPropertyString( spProcessor, _T("ProcessorId") ) );
    			PrintProperty( _T("Current Clock Speed\t" ), wmiHelper.GetPropertyLong( spProcessor, _T("CurrentClockSpeed") ) );
    			PrintProperty( _T("Max Clock Speed\t\t" ), wmiHelper.GetPropertyLong( spProcessor, _T("MaxClockSpeed") ) );
    			PrintProperty( _T("L2 Cache Size\t\t" ), wmiHelper.GetPropertyLong( spProcessor, _T("L2CacheSize") ) );
    
    			tcout << std::endl << _T("Sound Devices:") << std::endl;
    
    			wmiHelper.GetWMIClassObjectEnum(_T("Win32_SoundDevice"), spSoundDeviceEnum );
    
    			ULONG uReturned = 1;
    
    			while((SUCCEEDED(hr = spSoundDeviceEnum->Next(-1, 1, &spSoundDevice, &uReturned))) && (uReturned != 0))
    			{
    				PrintProperty( _T("Description\t\t" ), wmiHelper.GetPropertyString( spSoundDevice, _T("Description") ) );
    				PrintProperty( _T("Manufacturer\t\t" ), wmiHelper.GetPropertyString( spSoundDevice, _T("Manufacturer") ) );
    				PrintProperty( _T("DeviceId\t\t" ), wmiHelper.GetPropertyString( spSoundDevice, _T("DeviceId") ) );
    
    				tcout << std::endl;
    			}
    
    			tcout << std::endl << _T("Physical Memory:") << std::endl;
    
    			wmiHelper.GetWMIClassObjectEnum(_T("Win32_PhysicalMemory"), spPhysicalMemoryEnum );
    
    			while((SUCCEEDED(hr = spPhysicalMemoryEnum->Next(-1, 1, &spPhysicalMemory, &uReturned))) && (uReturned != 0))
    			{
    				PrintProperty( _T("Tag\t\t" ), wmiHelper.GetPropertyString( spPhysicalMemory, _T("Tag") ) );
    				PrintProperty( _T("Device Locator\t" ), wmiHelper.GetPropertyString( spPhysicalMemory, _T("DeviceLocator") ) );
    				PrintProperty( _T("Capacity\t" ), wmiHelper.GetPropertyLong( spPhysicalMemory, _T("Capacity") ) );
    				PrintProperty( _T("Form Factor\t" ), wmiHelper.GetPropertyLong( spPhysicalMemory, _T("FormFactor") ) );
    				PrintProperty( _T("Memory Type\t" ), wmiHelper.GetPropertyLong( spPhysicalMemory, _T("MemoryType") ) );
    				PrintProperty( _T("Speed\t\t" ), wmiHelper.GetPropertyLong( spPhysicalMemory, _T("Speed") ) );
    				PrintProperty( _T("Total Width\t" ), wmiHelper.GetPropertyLong( spPhysicalMemory, _T("TotalWidth") ) );
    				PrintProperty( _T("Type Detail\t" ), wmiHelper.GetPropertyLong( spPhysicalMemory, _T("TypeDetail") ) );
    
    				tcout << std::endl;
    			}
    		}
    		catch(_com_error& e)
    		{
    			tcout << e.ErrorMessage( ) << std::endl;
    		}
    	}
    
    	CoUninitialize( );
    
    	return 0;
    }
    Output:
    Processor:
    Description x86 Family 6 Model 14 Stepping 8
    Manufacturer GenuineIntel
    ProcessorId BFE9FBFF000006E8
    Current Clock Speed 1830
    Max Clock Speed 1830
    L2 Cache Size 2048

    Sound Devices:
    Description SigmaTel High Definition Audio CODEC
    Manufacturer SigmaTel
    DeviceId HDAUDIO\FUNC_01&VEN_8384&DEV_7690&SUBSYS_102801CD&REV_10
    22\4&350F0B83&0&0001

    Description Bluetooth AV Audio
    Manufacturer IVT Corporation
    DeviceId ROOT\MEDIA\0000

    Description Bluetooth SCO Audio
    Manufacturer IVT Corporation
    DeviceId ROOT\MEDIA\0001


    Physical Memory:
    Tag Physical Memory 0
    Device Locator DIMM_A
    Capacity 1073741824
    Form Factor 8
    Memory Type 0
    Speed 667
    Total Width 64
    Type Detail 128

    Tag Physical Memory 1
    Device Locator DIMM_B
    Capacity 1073741824
    Form Factor 8
    Memory Type 0
    Speed 667
    Total Width 64
    Type Detail 128
    Attached Files Attached Files

  11. #11
    John E is offline Elite Member Power Poster
    Join Date
    Apr 2001
    Location
    Manchester, England
    Posts
    4,867

    Re: Getting basic device information

    Thanks very much for the ideas guys. Codeplug - your suggestion works perfectly on my laptop machine but for reasons I can't understand, it doesn't find the sound card on my desktop machine The only thing I can think is that the sound card might be registered as a different kind of device (i.e. something other than an audio device). Is there a GUID that will simply list all the devices, regardless of their type?

    Arjay - your code definitely looks promising. After commenting out a few lines (see below) I've been able to run it in my debugger and it successfully lists RME HDSP 9632 which is my sound card !!!

    But there's a problem.... I'm compiling under VC++6. Your file WMIHelper.h contains a couple of functions that look something like this:-

    Code:
    	LPCTSTR GetPropertyDate( IWbemClassObjectPtr& rspObject, CComBSTR cbstrPropName )
    	{
    		HRESULT hr = S_OK;
    		CIMTYPE		vtType; 
    
    		CComVariant cvpVal;
    
    		m_sTempValue = _T("");
    
    		if( FAILED( hr = rspObject->Get( cbstrPropName, 0L, &cvpVal, &vtType, NULL ) ) )
    		{
    			throw _com_error( hr );
    		}
    
    		if( ( VT_BSTR == cvpVal.vt ) && ( CIM_DATETIME == vtType ) )
    		{
    			m_sTempValue = CString( cvpVal );
    		}
    		else
    		{
    			m_sTempValue = _T("");
    		}
    
    		return m_sTempValue;
    	}
    VC++ 6 won't let me convert an object of CComVariant into a CString. Can you think of a way to convert it to some other kind of string (e.g. std::string) ?
    "A problem well stated is a problem half solved.” - Charles F. Kettering

  12. #12
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    Re: Getting basic device information

    John, I answered your pm before I saw this post. Just use the string conversion macros.

    If you are going to use std::string, I'd recommend defining it as 'Tstring' so if you compile for ANSI now and decide to port the code to UNICODE later, the code will continue to work.

    Code:
    #ifndef _TSTRING  
    #ifdef _UNICODE 
    #define Tstring std::wstring 
    #define Tstringstream std::wstringstream 
    #define Tfstream std::wfstream 
    #define Tiostream std::wiostream 
    #else // #ifdef _UNICODE 
    #define Tstring std::string 
    #define Tstringstream std::stringstream 
    #define Tfstream std::fstream 
    #define Tiostream std::iostream 
    #endif // #ifdef _UNICODE 
    #define _TSTRING
    #endif // #ifndef _TSTRING
    Given that, the m_sTempValue variable is declared as a Tstring.

    Code:
    LPCTSTR GetPropertyDate( IWbemClassObjectPtr& rspObject, CComBSTR cbstrPropName )
    {
    	HRESULT hr = S_OK;
    	CIMTYPE		vtType; 
    
    	CComVariant cvpVal;
    
    	m_sTempValue = _T("");
    
    	if( FAILED( hr = rspObject->Get( cbstrPropName, 0L, &cvpVal, &vtType, NULL ) ) )
    	{
    		throw _com_error( hr );
    	}
    
    	if( ( VT_BSTR == cvpVal.vt ) && ( CIM_DATETIME == vtType ) )
    	{
    		// Use the conversion macro to convert the BSTR into a TCHAR
    		USES_CONVERSION;
    		m_sTempValue = OLE2T( cvpVal );
    	}
    	else
    	{
    		m_sTempValue = _T("");
    	}
    
    	return m_sTempValue;
    }

  13. #13
    John E is offline Elite Member Power Poster
    Join Date
    Apr 2001
    Location
    Manchester, England
    Posts
    4,867

    Re: Getting basic device information

    Thanks so much for persevering with this Arjay. I eventually managed to solve the problem using this line (where m_sTempValue is a Tstring).

    Code:
    m_sTempValue = OLE2T((unsigned short*)cvpVal.pbstrVal);
    I guess this must be something that changed very subtlely sometime after VC++6 since most of my other attempts resulted in C2440: 'type cast' : cannot convert from 'class ATL::CComVariant' to 'unsigned short *'. Still, I got there in the end.
    "A problem well stated is a problem half solved.” - Charles F. Kettering

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured