So I'm preparing to expand my typelib project by bringing in all of the CoreAudio interfaces. Some of the interfaces are easy to deal with-- I've already got working demos to list all devices with MMDeviceEnumerator, and using IMMDevice to get display names, and activate for IAudioEndpointVolume to adjust volume/mute/etc.
But some of the interfaces present challenges regarding how to convert to data types and pass parameters from the interface definition to VB.
Here's some of my outstanding questions I'd rather try to get an answer on instead of going the trial and error route:
1) There's lots of places where variable-length arrays are passed back to VB. An example is IChannelAudioVolume:
long GetAllVolumes([in] UINT32 dwCount,[out] float *pfVolumes);
is the official declaration from the SDK IDL. The count is known from an earlier call, so I can ReDim the array (of Single's right?) to the number of elements... but if I use sngArr(0) as pfVolumes, would it populate the other members? Or what about, would changing it to a Long give me a pointer from which I could use
CopyMemory sngArr(0), ByVal pfVolumes, LenB(sngArr(0)) * dwCount ? Something else?
2) No idea how the first argument should really be passed; it's not a single byte for sure... should be equal to a return from GetNextPacketSize.. but it's the array issue again:
long GetBuffer(
[out] BYTE **ppData,
[out] UINT32 *pNumFramesToRead,
[out] DWORD *pdwFlags,
[out] UINT64 *pu64DevicePosition,
[out] UINT64 *pu64QPCPosition);
(example from IAudioCaptureClient)
3) Haven't really had to worry about it before... but UINT32 is all over the place; what happens if it exceeds the value of VB's (signed) Long when it's passed to a function?
..will post more questions as I expand the demos, but it's coming along... right now all the buttons pictured work as indicated:
and all the interfaces have been added as vb-addressable (so just minor adjustments if any still need to be done) to the TLB, all PKEYs, IIDs, GUIDs and consts are in a module
example:
Code:
Dim sOut As String
Dim i As Long
Dim pDvEnum As MMDeviceEnumerator
Set pDvEnum = New MMDeviceEnumerator
Dim pDvCol As IMMDeviceCollection
pDvEnum.EnumAudioEndpoints eAll, DEVICE_STATEMASK_ALL, pDvCol
If (pDvCol Is Nothing) = False Then
Dim nCount As Long
Dim pDev As IMMDevice
Dim sStatus As String
Dim nStatus As DEVICE_STATE
If pDvCol.GetCount(nCount) = S_OK Then
For i = 0 To (nCount - 1)
pDvCol.Item i, pDev
If (pDev Is Nothing) = False Then
pDev.GetState nStatus
sStatus = GetStatusStr(nStatus)
sOut = sOut & "(" & sStatus & ") "
End If
sOut = sOut & "Device " & i & ": " & GetDeviceName(pDvCol, i) & vbCrLf
Next
Text1.Text = sOut
Else
Debug.Print "Failed to get device count."
End If
Else
Debug.Print "Failed to enum endpoints."
End If