From the device pointer (
IMMDevice Interface), you need to create and initialize an audio client (
IAudioClient Interface). It can be tricky to call the interface functions correctly, so I've written a complete example:
COM_Init()
; Get the device which we'll be monitoring.
device := VA_GetDevice("capture")
; Get IAudioClient interface.
VA_IMMDevice_Activate(device, IID_IAudioClient:="{1CB9AD4C-DBFA-4c32-B178-C2F568A703B2}", 7, 0, audioClient)
; Get mixer format to pass to Initialize.
VA_IAudioClient_GetMixFormat(audioClient, format)
; Initialize audio client to ensure peak meter is active.
VA_IAudioClient_Initialize(audioClient, 0, 0, 0, 0, format, 0)
; Get IAudioMeterInformation interface.
audioMeter := VA_GetAudioMeter(device)
; No longer needed, so free it:
COM_Release(device)
MeterLength = 30
; "The peak value for each channel is recorded over one device
; period and made available during the subsequent device period."
VA_GetDevicePeriod("capture", devicePeriod)
Loop
{
VA_IAudioMeterInformation_GetPeakValue(audioMeter, peakValue)
meter =
; Make the meter.
Loop % peakValue*MeterLength
meter .= "|"
Loop % (1-peakValue)*MeterLength
meter .= "."
meter .= " " peakValue
ToolTip, %meter%
Sleep, %devicePeriod%
}
/* To clean up:
COM_Release(audioMeter)
COM_Release(audioClient)
*/
;
; IAudioClient
;
VA_IAudioClient_Initialize(this, ShareMode, StreamFlags, BufferDuration, Periodicity, Format, AudioSessionGuid) {
return DllCall(NumGet(NumGet(this+0)+12), "uint", this, "int", ShareMode, "uint", StreamFlags, "int64", BufferDuration, "int64", Periodicity, "uint", Format, "uint", SubStr(AudioSessionGuid,1,1)="{" ? COM_GUID4String(AudioSessionGuid,AudioSessionGuid) : AudioSessionGuid)
}
VA_IAudioClient_GetBufferSize(this, ByRef NumBufferFrames) {
return DllCall(NumGet(NumGet(this+0)+16), "uint", this, "uint*", NumBufferFrames)
}
VA_IAudioClient_GetStreamLatency(this, ByRef Latency) {
return DllCall(NumGet(NumGet(this+0)+20), "uint", this, "int64*", Latency)
}
VA_IAudioClient_GetCurrentPadding(this, ByRef NumPaddingFrames) {
return DllCall(NumGet(NumGet(this+0)+24), "uint", this, "uint*", NumPaddingFrames)
}
VA_IAudioClient_IsFormatSupported(this, ShareMode, Format, ByRef ClosestMatch) {
return DllCall(NumGet(NumGet(this+0)+28), "uint", this, "int", ShareMode, "uint", Format, "uint*", ClosestMatch)
}
VA_IAudioClient_GetMixFormat(this, ByRef Format) {
return DllCall(NumGet(NumGet(this+0)+32), "uint", this, "uint*", Format)
}
VA_IAudioClient_GetDevicePeriod(this, ByRef DefaultDevicePeriod, ByRef MinimumDevicePeriod) {
return DllCall(NumGet(NumGet(this+0)+36), "uint", this, "int64*", DefaultDevicePeriod, "int64*", MinimumDevicePeriod)
}
VA_IAudioClient_Start(this) {
return DllCall(NumGet(NumGet(this+0)+40), "uint", this)
}
VA_IAudioClient_Stop(this) {
return DllCall(NumGet(NumGet(this+0)+44), "uint", this)
}
VA_IAudioClient_Reset(this) {
return DllCall(NumGet(NumGet(this+0)+48), "uint", this)
}
VA_IAudioClient_SetEventHandle(this, eventHandle) {
return DllCall(NumGet(NumGet(this+0)+52), "uint", this, "uint", eventHandle)
}
VA_IAudioClient_GetService(this, iid, ByRef Service) {
return DllCall(NumGet(NumGet(this+0)+56), "uint", this, "uint", COM_GUID4String(iid,iid), "uint*", Service)
}
I had attempted this previously but had overlooked IAudioClient::GetMixFormat, which is needed to get the stream format to pass to IAudioClient::Initialize.