locked
KsProperty function behavior RRS feed

  • Question

  • Hello all, 

    (Note: I tried to post here with links and pictures to make it easy communicate, but i got a message of "Body text cannot contain images or links until we are able to verify your account". I have no idea when this verification will happen, so i will change the pictures and links with a [Replace] followed by text to represent it for now. When my account be verified i will try to adjust it later. I am sorry for that, and thank you for the understanding. ) 

    I am trying to use KsProperty function and it is returning a kind of error that i cant find in HRESULT codes documentation. 
    Basically, i am following the instructions stated at the guidelines below: 

    1 - [REPLACE]:  MSDN Guideline entitled  "Device Topologies"
    2 - [REPLACE]:  MSDN Guideline entitled  "Using the IKSControl interface to Access Audio Properties"

    My primary goal is to control KSPROPERTY_AUDIO_SAMPLING_RATE at KSNODETYPE_ADC node. I can easily discovery the topology elements, as well its subtypes, what can be seen in the next picture (first array element pointing to the beginning of data path). 

    [REPLACE]: A picture here showed array contents. The values are (in order) showed below:

    PartName Array: { Connector - Physical External - Out; Subunit - Mic Volume; Subunit - Mic Mute; Subunit - Microphone Boost; Connector - Physical External - Out; Connector - Software Fixed - Out; Subunit - ""; Connector - Software Fixed - Out}    

    PartNameSubType Array: { ""; KSNODETYPE_VOLUME; KSNODETYPE_MUTE; KSNODETYPE_VOLUME; KSCATEGORY_AUDIO; ""; KSNODETYPE_ADC; ""}

    Each time that i reach some specific IPart subtype, i create a KsNodeProperty structure, as can be seen in the following pictures. Thus, i guarantee that each KsProperty request is being solicited in the right subtype. Also each time that i change this node, i also change the corresponding property Id (i.e for a KSNODETYPE_VOLUME i would be using KSPROPERTY_AUDIO_VOLUMELEVEL instead of KSPROPERTY_AUDIO_SAMPLING_RATE).

    [REPLACE] A picture here showed the code below

    //All NodeTypes must use KSNODEPROPERTY... if the NodeId not be specified will fail.  
    			//if (FALSE)
    			//if (PartSubType == KSNODETYPE_ADC) // NoK
    			if (PartSubType == KSNODETYPE_MUTE) // Ok, only one that i could get-set-get-set and see real changes
    				//if (PartSubType == KSNODETYPE_VOLUME) // Nok
    				//if (PartSubType == KSCATEGORY_AUDIO)
    			{
    				KSNODEPROPERTY_AUDIO_CHANNEL ksprop;
    				IKsControl *pKsControl = nullptr;
    				IMMDevice *pDeviceAux = nullptr;
    				IMMDeviceEnumerator *pEnumeratorAux = nullptr;
    				IDeviceTopology *pTopCurrentAux = nullptr;
    				LPWSTR DeviceIDAux = NULL;
    				ULONG intVal = 0;
    				LPVOID AuxData = nullptr;
    				ULONG *pVal = nullptr;
    				ULONG valueSize;
    				ULONG KsSupportData = 0;
    				IPropertyStore * pDeviceAuxInfo;
    				PROPVARIANT DeviceAuxName;
    				DWORD DeviceStatus;
    				String ^ strDeviceStatus;
    
    				hrMsg = pPartNext->GetLocalId(&IdAdapter);
    				ZeroMemory(&ksprop, sizeof(ksprop));
    				ksprop.NodeProperty.Property.Set = KSPROPSETID_Audio;
    				//KSPROPERTY_AUDIO_SAMPLING_RATE; //KSPROPERTY_AUDIO_MUTE; // KSPROPERTY_AUDIO_VOLUMELEVEL; // KSPROPERTY_AUDIO_SAMPLING_RATE;
    				ksprop.NodeProperty.Property.Id = KSPROPERTY_AUDIO_MUTE;
    				ksprop.NodeProperty.Property.Flags = KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_TOPOLOGY;
    				//ksprop.NodeProperty.Property.Flags = KSPROPERTY_TYPE_SETSUPPORT;
    				ksprop.NodeProperty.NodeId = IdAdapter & PARTID_MASK;
    				//ksprop.NodeProperty.NodeId = IdAdapter;
    				ksprop.Channel = 0;
    
    				// Property struct not node 
    				//KSPROPERTY ksPropTest;
    				//ZeroMemory(&ksPropTest, sizeof(ksPropTest));
    				//ksPropTest.Set = KSPROPSETID_Audio;
    				//ksPropTest.Id = KSPROPERTY_AUDIO_VOLUMELEVEL; //KSPROPERTY_AUDIO_SAMPLING_RATE; 
    				//ksPropTest.Flags = KSPROPERTY_TYPE_GET;
    				// KSPROPERTY_TYPE_BASICSUPPORT ; KSPROPERTY_TYPE_SETSUPPORT ; KSPROPERTY_TYPE_GET; KSPROPERTY_TYPE_TOPOLOGY;
    
    				// Presteps to find the right device that contains the part. 
    				hrMsg = pPartNext->GetTopologyObject(&pTopCurrentAux);
    				hrMsg = pTopCurrentAux->GetDeviceId(&DeviceIDAux);
    				hrMsg = CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_ALL, _uuidof(IMMDeviceEnumerator), (void**)&pEnumeratorAux);
    				hrMsg = pEnumeratorAux->GetDevice(DeviceIDAux, (IMMDevice**)&pDeviceAux);
    				hrMsg = pDeviceAux->OpenPropertyStore(STGM_READ, &pDeviceAuxInfo);
    				hrMsg = pDeviceAuxInfo->GetValue(PKEY_DeviceInterface_FriendlyName, &DeviceAuxName); // lets use like that DeviceName.pwszVal
    				String ^ strDeviceAuxName = gcnew String(classMTools::LPWSTRToStr((LPWSTR)DeviceAuxName.pszVal));
    				hrMsg = pDeviceAux->GetState(&DeviceStatus); if (DeviceStatus == DEVICE_STATE_ACTIVE) { strDeviceStatus = "DEVICE_STATE_ACTIVE"; }
    				else if (DeviceStatus == DEVICE_STATE_DISABLED) { strDeviceStatus = "DEVICE_STATE_DISABLED"; }
    				else if (DeviceStatus == DEVICE_STATE_NOTPRESENT) { strDeviceStatus = "DEVICE_STATE_NOTPRESENT"; }
    				else if (DeviceStatus == DEVICE_STATE_UNPLUGGED) { strDeviceStatus = "DEVICE_STATE_UNPLUGGED"; }
    				hrMsg = pDeviceAux->Activate(__uuidof(IKsControl), CLSCTX_ALL, NULL, (void**)&pKsControl);
    
    				// Inquiry for Get or Set or both avaibility
    				ksprop.NodeProperty.Property.Flags = KSPROPERTY_TYPE_BASICSUPPORT | KSPROPERTY_TYPE_TOPOLOGY;
    				hrMsg = pKsControl->KsProperty(&ksprop.NodeProperty.Property, sizeof(ksprop), &KsSupportData, sizeof(KsSupportData), &valueSize);
    				String^ strKsSupport = classTools::KsSupportSelector(KsSupportData);
    
    				// Series of Get and Set for test
    				ksprop.NodeProperty.Property.Flags = KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_TOPOLOGY;
    				hrMsg = pKsControl->KsProperty(&ksprop.NodeProperty.Property, sizeof(ksprop), &intVal, sizeof(intVal), &valueSize);
    				ULONG intValInitial = intVal;
    				//ULONG intValMod = intVal / 100;
    				ULONG intValMod = (intVal ? 0 : 1);
    				//ULONG intValMod = 96000;
    				ksprop.NodeProperty.Property.Flags = KSPROPERTY_TYPE_SET | KSPROPERTY_TYPE_TOPOLOGY;
    				hrMsg = pKsControl->KsProperty(&ksprop.NodeProperty.Property, sizeof(ksprop), &intValMod, sizeof(intValMod), &valueSize);
    				ksprop.NodeProperty.Property.Flags = KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_TOPOLOGY;
    				hrMsg = pKsControl->KsProperty(&ksprop.NodeProperty.Property, sizeof(ksprop), &intVal, sizeof(intVal), &valueSize);
    				ULONG intValMid = intVal;
    				intValMod = (intVal ? 0 : 1);
    				ksprop.NodeProperty.Property.Flags = KSPROPERTY_TYPE_SET | KSPROPERTY_TYPE_TOPOLOGY;
    				hrMsg = pKsControl->KsProperty(&ksprop.NodeProperty.Property, sizeof(ksprop), &intValMod, sizeof(intValMod), &valueSize);
    				ksprop.NodeProperty.Property.Flags = KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_TOPOLOGY;
    				hrMsg = pKsControl->KsProperty(&ksprop.NodeProperty.Property, sizeof(ksprop), &intVal, sizeof(intVal), &valueSize);
    				ULONG intValFinal = intVal;
    
    
    				CoTaskMemFree(DeviceIDAux);
    				SAFE_RELEASE(pDeviceAuxInfo)
    					SAFE_RELEASE(pTopCurrentAux)
    					SAFE_RELEASE(pDeviceAux)
    					SAFE_RELEASE(pKsControl)
    					SAFE_RELEASE(pEnumeratorAux)
    			}


    However, as a try-out procedure, i did basic KsProperty requests using flags such as: KSPROPERTY_TYPE_BASICSUPPORT, KSPROPERTY_TYPE_GET and KSPROPERTY_TYPE_SET, over the nodes KSNODETYPE_ADC, KSNODETYPE_VOLUME, KSNODETYPE_MUTE, being the late the only one that i could  successfully complete the try-out. The next pictures shows the HRESULT (hrMsg variable in the code) values for requisitions at KSNODETYPE_ADC, something pretty similar also happens with KSNODETYPE_VOLUME. 

    [REPLACE] Here it showed HRESULT values of -2147023726 for differents requisitions using differents flags. 

    In the other hand, KSNODETYPE_MUTE requisitions using KSPROPERTY_TYPE_BASICSUPPORT works just fine, and return as data the value 515 (this value was supposed to indicate a support for SET/GET requests, however this 515 value i didnt find any information about what means). The following picture point it out, showing also a Ks.h library snippet containing the defined KSPROPERTY_TYPE values. 

    [REPLACE] Here it showed HRESULT value of 0 and a requested data value of 515. Also showed the code snippet below 

    #define KSPROPERTY_TYPE_GET 0x00000001 #define KSPROPERTY_TYPE_SET 0x00000002 #define KSPROPERTY_TYPE_SETSUPPORT 0x00000100 #define KSPROPERTY_TYPE_BASICSUPPORT 0x00000200 #define KSPROPERTY_TYPE_RELATIONS 0x00000400 #define KSPROPERTY_TYPE_SERIALIZESET 0x00000800 #define KSPROPERTY_TYPE_UNSERIALIZESET 0x00001000 #define KSPROPERTY_TYPE_SERIALIZERAW 0x00002000 #define KSPROPERTY_TYPE_UNSERIALIZERAW 0x00004000 #define KSPROPERTY_TYPE_SERIALIZESIZE 0x00008000 #define KSPROPERTY_TYPE_DEFAULTVALUES 0x00010000 #define KSPROPERTY_TYPE_TOPOLOGY 0x10000000 #define KSPROPERTY_TYPE_HIGHPRIORITY 0x08000000 #define KSPROPERTY_TYPE_COPYPAYLOAD 0x80000000


    Even so, i know that this request worked cause i did a serie of GET/SET/GET requistions, comparing after that the returned values. As result, the next pictures shows the first GET value, followed for matches between GET and SET values.

    [REPLACE] Here it showed a sequence of values. First value was 0, got directly from a GET request. After it, it was setted a value of 1, what returned the respective 1 in the following GET request. Finally it was setted a 0 value, and another GET request returned the same 0 value, showing that the request was working. 

    With that in mind, i kindly ask some clue in why the KsProperty requisitions didnt work for the other KSNODETYPES.

    Thank you in advance! 
    Ricardo Rios. 

     
    [REPLACE] Here it shows HRESULT value of 0 and a requested data value of 515. Also shows the code snippet below 
    Thursday, March 16, 2017 4:24 PM