This demo is in a response to a question by Peterd51, asking if there was a way to detect if audio was playing. CoreAudio provides an easy way to watch peaks for a peak meter, so obviously if that's 0 no audio is playing, and non-zero if audio is playing.
Here we display a Audio detected/No audio label for the yes/no answer, then also a peak meter using a ProgressBar, and a list of the raw values the program is receiving. This is basically a VB version of Microsoft's Peak Meter Example.
The code is pretty simple,
Code:
Option Explicit
Private pDevice As IMMDevice
Private pEnum As MMDeviceEnumerator
Private pMeterInfo As IAudioMeterInformation
Private nCount As Long
Private Sub Command1_Click()
Timer1.Interval = CLng(Text1.Text)
If (pDevice Is Nothing) Then
Set pEnum = New MMDeviceEnumerator
pEnum.GetDefaultAudioEndpoint eRender, eConsole, pDevice
If (pDevice Is Nothing) = False Then
pDevice.Activate IID_IAudioMeterInformation, CLSCTX_INPROC_SERVER Or CLSCTX_INPROC_HANDLER Or CLSCTX_LOCAL_SERVER Or CLSCTX_REMOTE_SERVER, 0&, pMeterInfo
If (pMeterInfo Is Nothing) = False Then
Timer1.Enabled = True
Else
Debug.Print "Failed to activate meter."
End If
Else
Debug.Print "Failed to get default endpoint."
End If
Else
Timer1.Enabled = True
End If
End Sub
Private Sub Timer1_Timer()
Dim snValue As Single
If (pMeterInfo Is Nothing) = False Then
pMeterInfo.GetPeakValue snValue
List1.AddItem CStr(snValue * 100), 0
ProgressBar1.Value = snValue * 100
If snValue = 0 Then
Label4.Caption = "No audio."
nCount = nCount + 1
If nCount > 5 Then
'definitely not playing
End If
Else
nCount = 0
Label4.Caption = "Audio detected"
End If
End If
End Sub
Private Sub Command2_Click()
Timer1.Enabled = False
End Sub
Private Sub Form_Unload(Cancel As Integer)
Set pMeterInfo = Nothing
Set pDevice = Nothing
Set pEnum = Nothing
End Sub
Requirements
-Core Audio is only available on Windows Vista and newer.
-oleexp.tlb v4.7 or higher
-oleexp addon modules mIID.bas and mCoreAudio.bas (included in the oleexp download)
As an addition this one here for the capture (recording) device...
MS states, that getting the AudioMeter for the capture device just requires to change the Endpoint device from eRender to eCapture. Ok, that works, but you won't get any values...
They missed to note that you have also to activate the corresponding IAudioClient on the device before you request the meter.
The attached demo shows how to achieve this (actual oleexp.tlb required!).
@Fafalone:
As you can see I directly use WAVEFORMATEXTENSIBLE for the FormatSupported and Initialize methods. Because to my observations FormatTag is always -2 (WAVE_FORMAT_EXTENSIBLE) and cbSize is 22. This has to be changed to WAVE_FORMAT_PCM (1) and cbSize = 0 before setting it in Initialize. Otherwise you get the "not supported format" error.
(PS - So every time you need an IID, you need to declare a local variable and call CLSIDFromString? Yeah, I'd much rather just autogenerate my iids and include mIID lol )
Skillset: VMS,DOS,Windows Sysadmin from 1985, fault-tolerance, VaxCluster, Alpha,Sparc. DCL,QB,VBDOS- VB6,.NET, PHP,NODE.JS, Graphic Design, Project Manager, CMS, Quad Electronics. classic cars & m'bikes. Artist in water & oils. Historian.
By the power invested in me, all the threads I start are battle free zones - no arguing about the benefits of VB6 over .NET here please. Happiness must reign.
[Well, I am sure I have that installed and registered, it is certainly within WoW64 already. How can we ascertain which version we currently have installed? Isn't that just a type library? mCoreAudio.bas looks like a file containing code rather than just enums and type definitions.] - all sorted.
Last edited by yereverluvinuncleber; Aug 15th, 2023 at 07:12 PM.
Skillset: VMS,DOS,Windows Sysadmin from 1985, fault-tolerance, VaxCluster, Alpha,Sparc. DCL,QB,VBDOS- VB6,.NET, PHP,NODE.JS, Graphic Design, Project Manager, CMS, Quad Electronics. classic cars & m'bikes. Artist in water & oils. Historian.
By the power invested in me, all the threads I start are battle free zones - no arguing about the benefits of VB6 over .NET here please. Happiness must reign.
Skillset: VMS,DOS,Windows Sysadmin from 1985, fault-tolerance, VaxCluster, Alpha,Sparc. DCL,QB,VBDOS- VB6,.NET, PHP,NODE.JS, Graphic Design, Project Manager, CMS, Quad Electronics. classic cars & m'bikes. Artist in water & oils. Historian.
By the power invested in me, all the threads I start are battle free zones - no arguing about the benefits of VB6 over .NET here please. Happiness must reign.
Yes unfortunately a TLB can't contain GUIDs (besides as strings) or functions, so there's addon modules for those things, with separate ones for particular feature sets.
A good thing about the twinBASIC package format is that it can include those, so tbShellLib (the x64-compatible successor to oleexp) is just a single package without additional modules.
(PS - So every time you need an IID, you need to declare a local variable and call CLSIDFromString? Yeah, I'd much rather just autogenerate my iids and include mIID lol )
No. You see the reason I did it here in the above posts. I want a demo to be as minimalistic as possible.
I attached one of my solutions there.
Otherwise I store the IID strings in a resource file. Loading and immediately converting them to an UUID array on Initialize()/Form_Load. (Over the years I assembled an Access database containing >60.000 GUIDs, 70% of them MS GUIDs. I filter the table e.g. by column "source=mmreg.h" and export this to a text file that I'll include in the resource.)