Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Getting information form audio devices
#1
Gintaras, i want to extend the setaudiovolume function of QM.

I want to get all available devices, but i can't do the last step (get the name).

If you could help, thanks

Macro Macro1
Code:
Copy      Help
#opt nowarnings 1
IMMDeviceCollection ppDevices
int dwStateMask
def DEVICE_STATE_ACTIVE      0x00000001
def DEVICE_STATE_DISABLED    0x00000002
def DEVICE_STATE_NOTPRESENT  0x00000004
def DEVICE_STATE_UNPLUGGED   0x00000008
def DEVICE_STATEMASK_ALL     0x0000000F
int stgmAccess
PROPERTYKEY pk
pk.pid=6
GUID t=pk.fmtid
IMMDeviceEnumerator en
IPropertyStore pProps
word w
VARIANT v

PROPVARIANT pActivationParams
IMMDevice de
IAudioEndpointVolume av
en._create(CLSID_MMDeviceEnumerator)
en.GetDefaultAudioEndpoint(eRender eMultimedia &de)
en.EnumAudioEndpoints(eRender DEVICE_STATEMASK_ALL &ppDevices)
ppDevices.GetCount(_i)
for int'u 0 _i
,ppDevices.Item(u &de)
,de.OpenPropertyStore(stgmAccess &pProps)
,pProps.GetAt(u &pk)
,pProps.GetValue(&pk +&v)
,pProps.Commit
,_s.FromGUID(pk.fmtid)
,;out _s
,;out pk.pid
,out pActivationParams.pbstrVal


i don't get the device name as expected, and get this in QM outpu:


why?

PS: trying to adapt from this
https://msdn.microsoft.com/en-us/librar ... 12(v=vs.85).aspx
#2
Converted from the MSDN code example.

Macro enum audio devices
Code:
Copy      Help
out

;PKEY_Device_FriendlyName does not exist in Windows SDK headers. Exists DEVPKEY_Device_FriendlyName, and it works.
;C++ definition from SDK devpkey.h:
;DEFINE_DEVPROPKEY(DEVPKEY_Device_FriendlyName, 0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 14);
PROPERTYKEY pk.pid=14; memcpy &pk.fmtid uuidof("{a45c254e-df1c-4efd-8020-67d146a850e0}") sizeof(GUID)

IMMDeviceEnumerator pEnumerator
IMMDeviceCollection pCollection
IMMDevice pEndpoint
IPropertyStore pProps
word* pwszID

pEnumerator._create(CLSID_MMDeviceEnumerator)
pEnumerator.EnumAudioEndpoints(eRender DEVICE_STATE_ACTIVE &pCollection)
int count
pCollection.GetCount(&count)
int i
for i 0 count
,pCollection.Item(i &pEndpoint)
,pEndpoint.GetId(&pwszID)
,pEndpoint.OpenPropertyStore(STGM_READ, &pProps)
,PROPVARIANT varName
,pProps.GetValue(pk, &varName)
,str s1.ansi(varName.pwszVal) s2.ansi(pwszID)
,CoTaskMemFree(pwszID); pwszID=0; PropVariantClear &varName; pProps=0; pEndpoint=0
,out F"Endpoint {i}: ''{s1}'' ({s2})"
#3
Perfect, but some question to understand, and do better by myself later.

1. Tried to findout that, but missed it, know will know

DEFINE_DEVPROPKEY(DEVPKEY_Device_FriendlyName, 0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 14);
PROPERTYKEY pk.pid=14; memcpy &pk.fmtid uuidof("{a45c254e-df1c-4efd-8020-67d146a850e0}") sizeof(GUID)

2.
IMMDeviceEnumerator pEnumerator
IMMDeviceCollection pCollection

Why use create with pEnumerator and not with pCollection????

3. in MSDN,

pEndpoint.GetId waitsq for LPWSTR *ppstrId
Here, word*, why?

4. why this?

str s1.ansi(varName.pwszVal) s2.ansi(pwszID)
CoTaskMemFree(pwszID); pwszID=0; PropVariantClear &varName; pProps=0; pEndpoint=0

from MSDN example, there are no such variable casts, is it QM handling that impose such tricky ways?
#4
1. In C++ need only #include <devpkey.h> and maybe add some library. And install Windows SDK. In QM need to find DEVPKEY_Device_FriendlyName definition in devpkey.h and convert to QM. Attached devpkey.h from Win10 SDK. In PROPERTYKEY definition we see that it consists of GUID and int. One of ways to fill a GUID is memcpy uuidof.

2. QM _create is a shorter way to call CoCreateInstance. The MSDN example uses CoCreateInstance only for pEnumerator.

3. C++ LPWSTR in QM is word*. It is a raw Unicode string (just pointer).

4. Converts from Unicode UTF16 to QM string format, probably UTF8.


Attached Files
.h   devpkey.h (Size: 34.63 KB / Downloads: 33)
#5
1. In C++ need only #include <devpkey.h> and maybe add some library. And install Windows SDK. In QM need to find DEVPKEY_Device_FriendlyName definition in devpkey.h and convert to QM. Attached devpkey.h from Win10 SDK. In PROPERTYKEY definition we see that it consists of GUID and int. One of ways to fill a GUID is memcpy uuidof.

yes, i messed to format properly in GUID format

2. QM _create is a shorter way to call CoCreateInstance. The MSDN example uses CoCreateInstance only for pEnumerator.

OK

3. C++ LPWSTR in QM is word*. It is a raw Unicode string (just pointer).

Hmm, how was I to know..i lost an incredible time with this.....read 10x times documentation.

4. Converts from Unicode UTF16 to QM string format, probably UTF8.

in MSDN

IPropertyStore::GetValue method
Gets data for a specific property.
Syntax

C++

HRESULT GetValue(
[in] REFPROPERTYKEY key,
[out] PROPVARIANT *pv
);

how did you find that pwszVal was the one to pickup? (aside the fact you're az master in programming)

5. STGM_READ is not declared, but valid in macro. But I must declare
def DEVICE_STATE_ACTIVE 0x00000001
def DEVICE_STATE_DISABLED 0x00000002
def DEVICE_STATE_NOTPRESENT 0x00000004
def DEVICE_STATE_UNPLUGGED 0x00000008
def DEVICE_STATEMASK_ALL 0x0000000F
to have function working, and don't understand why.
#6
3. To understand MSDN code examples need to have some C/C++ and Windows API knowledge and experience. Then you know what is LPWSTR, or can find in SDK headers, where it is defined as pointer to unsigned short, which is a 2-byte integer, in QM it is word.

4. I just looked in the example, not in function reference. pwszVal was there. In PROPVARIANT its type is word*, which implies that it probably is a UTF16 string. QM string format is not UTF16, need to convert.

5. Part of Windows API in QM is declared through WINAPI, and it includes STGM_READ. Read more in QM help topic "Declare reference file or macro".
#7
5. These are in winapi2:
More Windows API declarations for QM
#8
yes, declared in init2 function, but sometimes colored macro (wintype recognized) sometime not..
#9
Gintaras Wrote:can find in SDK headers

hmm i think i should get these then..........

I can read c++ code quite good, but managing to get some snippets to be translated in QM needs more knowledge of QM internals than C++
IMHO
#10
ldarrambide Wrote:yes, declared in init2 function, but sometimes colored macro (wintype recognized) sometime not..

WINAPI2.DEVICE_STATE_ACTIVE

or

ref WINAPI2 "$qm$\winapi2.txt" 7 ;;includes flag 2 - global scope, then don't need "WINAPI2." in macros.
#11
Quote:hmm i think i should get these then..........
Often Google can find these declarations somewhere. Others are in WINAPI or WINAPI2. Very rarely need to search in SDK.
#12
yes, i understand...........Your converted function is invaluable for understanding things,
but, winapi is so heavy, i think i can try to only use declarations i need,..........but still, some C++ -> QM translation are hard to
find..

Example, what is QM for

type REFERENCE_TIME = %


i did find those ..
#define REFTIMES_PER_SEC 10000000
QM= def REFTIMES_PER_SEC 10000000


HRESULT RecordAudioStream()
{
HRESULT hr;
REFERENCE_TIME hnsRequestedDuration = REFTIMES_PER_SEC;

i cant get this one, error in QM IDE about some missing characters in Winapi2 or something like that.

Any help??
#13
WINAPI contains this invalid declaration for C typedef. It is like comments, for your information. Cannot convert to a valid QM declaration because QM does not have typedef. In this case it means that it is the same as type 'long'. Here % is long type character, look in QM help topic "Variables".
If in C code you see REFERENCE_TIME x, in QM it is long x.


Forum Jump:


Users browsing this thread: 4 Guest(s)