#NoEnv COM_CoInitialize() pIPart := VA_GetSpeakersIPart() text1 := VA_EnumerateSubParts_List(pIPart) text2 := VA_EnumerateSubParts_Tree(pIPart) COM_Release(pIPart) Gui, Font,, Lucida Console Gui, Add, Edit, H550 W140, %text1% Gui, Font, s10 Gui, Add, Edit, H550 W620 YM -Wrap +0x100000, %text2% Gui, Show,, Vista Audio Device Topology Gui, +LastFound WinWaitActive Send ^{Home} return GuiClose: ExitApp ; Shows a list of mute/volume components. VA_EnumerateSubParts_List(part) { iid_vol := "{7FB7B48F-531D-44A2-BCB3-5AD5A134B3DC}", COM_GUID4String(iid_vol,iid_vol) iid_mute := "{DF45AEEA-B74A-4B6B-AFAD-2366B6AA012E}", COM_GUID4String(iid_mute,iid_mute) VA_EnumerateSubParts_List_(part, list_vol, list_mute, &iid_vol, &iid_mute) return "VOLUME SUBUNITS`n`n" list_vol "`n`nMUTE SUBUNITS`n`n" list_mute } VA_EnumerateSubParts_List_(part, ByRef list_vol, ByRef list_mute, piid_vol, piid_mute) { static S_OK=0 ; part->GetPartType() DllCall(NumGet(NumGet(part+0)+24), "uint",part, "uint*",type) if (type = 1) ; Subunit { ; part->GetName(...) ; [out] LPWSTR* pwname -- (pointer to Unicode string) DllCall(NumGet(NumGet(part+0)+12), "uint",part, "uint*",pwname) name := COM_Ansi4Unicode(pwname), COM_CoTaskMemFree(pwname) ; part->Activate(...) ; [out] IAudioVolumeLevel iface if (S_OK = DllCall(NumGet(NumGet(part+0)+52), "uint",part, "uint",1, "uint",piid_vol, "uint*",iface)) COM_Release(iface), list_vol .= name "`n" ; [out] IAudioMute iface if (S_OK = DllCall(NumGet(NumGet(part+0)+52), "uint",part, "uint",1, "uint",piid_mute, "uint*",iface)) COM_Release(iface), list_mute .= name "`n" } ; part->EnumPartsIncoming(...) ; [out] IPartsList parts DllCall(NumGet(NumGet(part+0)+40), "uint",part, "uint*",parts) ; parts->GetCount() DllCall(NumGet(NumGet(parts+0)+12), "uint",parts, "uint*",count) Loop, %count% { ; parts->GetPart(A_Index-1, [out] subpart) DllCall(NumGet(NumGet(parts+0)+16), "uint",parts, "uint",A_Index-1, "uint*",subpart) ; RECURSE VA_EnumerateSubParts_List_(subpart, list_vol, list_mute, piid_vol, piid_mute) COM_Release(subpart) } } ; Shows the device topology in tree form. VA_EnumerateSubParts_Tree(part) { static indent, indent_size=3 ; Friendly names for common interfaces. static iid_DF45AEEA_B74A_4B6B_AFAD_2366B6AA012E="IAudioMute" , iid_7FB7B48F_531D_44A2_BCB3_5AD5A134B3DC="IAudioVolumeLevel" , iid_85401FD4_6DE4_4B9D_9869_2D6753A82F3C="IAudioAutoGainControl" ; part->GetName(...) ; [out] LPWSTR* pwname -- (pointer to Unicode string) DllCall(NumGet(NumGet(part+0)+12), "uint",part, "uint*",pwname) ; part->GetPartType() DllCall(NumGet(NumGet(part+0)+24), "uint",part, "uint*",type) name := COM_Ansi4Unicode(pwname), COM_CoTaskMemFree(pwname) text .= indent "+ " if (type != 1) ; not a subunit text .= type=0 ? "(CONNECTOR) " : "(UNKNOWN) " text .= name ; connPart->GetControlInterfaceCount(count) DllCall(NumGet(NumGet(part+0)+32), "uint",part, "uint*",count) Loop, %count% { ; connPart->GetControlInterface(...) ; [out] IControlInterface idesc DllCall(NumGet(NumGet(part+0)+36), "uint",part, "uint",A_Index-1, "uint*",idesc) ; idesc->GetIID(...) ; [out] GUID iid VarSetCapacity(iid, 16) DllCall(NumGet(NumGet(idesc+0)+16), "uint",idesc, "uint",&iid) iid := COM_String4GUID(&iid) StringReplace, iids, iid, -, _, All StringTrimLeft, iids, iids, 1 StringTrimRight, iids, iids, 1 if iid_%iids% iids := iid_%iids% else iids := iid text .= A_Index>1 ? ", " iids : " : " iids COM_Release(idesc), idesc=0 } text .= "`n" Loop, %indent_size% indent .= A_Space ; part->EnumPartsIncoming(...) ; [out] IPartsList parts DllCall(NumGet(NumGet(part+0)+40), "uint",part, "uint*",parts) ; parts->GetCount() DllCall(NumGet(NumGet(parts+0)+12), "uint",parts, "uint*",count) Loop, %count% { ; parts->GetPart(A_Index-1) DllCall(NumGet(NumGet(parts+0)+16), "uint",parts, "uint",A_Index-1, "uint*",subpart) text .= VA_EnumerateSubParts_Tree(subpart) COM_Release(subpart) } indent := SubStr(indent,1,-indent_size) return text } ; Gets a pointer to an IPart interface that represents the Speakers. VA_GetSpeakersIPart() { defaultDevice := VA_GetDevice() ; defaultDevice->Activate(...) ; [out] IDeviceTopology deviceTopology iid := "{2A07407E-6497-4A18-9787-32F79BD0D98F}" DllCall(NumGet(NumGet(defaultDevice+0)+12), "uint",defaultDevice, "uint",COM_GUID4String(iid,iid), "uint",1, "uint",0, "uint*",deviceTopology) COM_Release(defaultDevice), defaultDevice=0 ; deviceTopology->GetConnector(0,...) ; [out] IConnector endptConnector DllCall(NumGet(NumGet(deviceTopology+0)+16), "uint",deviceTopology, "uint",0, "uint*",endptConnector) COM_Release(deviceTopology), deviceTopology=0 ; endptConnector->GetConnectedTo(...) ; [out] IConnector hwdevConnector DllCall(NumGet(NumGet(endptConnector+0)+32), "uint",endptConnector, "uint*",hwdevConnector) COM_Release(endptConnector), endptConnector=0 ; hwdevConnector->QueryInterface(...) ; [out] IPart connPart iid := "{AE2DE0E4-5BCA-4F2D-AA46-5D13F8FDB3A9}" connPart := COM_QueryInterface(hwdevConnector, iid) COM_Release(hwdevConnector), hwdevConnector=0 return connPart }