If IsAudioPlaying false for 3 minutes Topic is solved

Get help with using AutoHotkey and its commands and hotkeys
HIAC
Posts: 111
Joined: 11 Oct 2017, 17:59
Location: Republic of Serbia

If IsAudioPlaying false for 3 minutes

01 Dec 2017, 14:44

Hello.
Alright so I have this script which detects whether is audio playing and it works fine.
What would be the code if sound is not playing for 3 minutes, then do something?


Code: Select all

IsAudioPlaying() {
    AudioLevel := 0.0
    VA_IAudioMeterInformation_GetPeakValue(VA_GetAudioMeter(), AudioLevel)
    return (Round(AudioLevel, 4) > 0)
}
;---------------------------------------------------------
;VA code credited to Lexikos, I merely cut it down to the minimum I needed.
VA_GetAudioMeter(device_desc="playback")
{
    if ! device := VA_GetDevice(device_desc)
        return 0
    VA_IMMDevice_Activate(device, "{C02216F6-8C67-4B5B-9D00-D008E73E0064}", 7, 0, audioMeter)
    ObjRelease(device)
    return audioMeter
}

VA_GetDevice(device_desc="playback")
{
    static CLSID_MMDeviceEnumerator := "{BCDE0395-E52F-467C-8E3D-C4579291692E}"
        , IID_IMMDeviceEnumerator := "{A95664D2-9614-4F35-A746-DE8DB63617E6}"
    if !(deviceEnumerator := ComObjCreate(CLSID_MMDeviceEnumerator, IID_IMMDeviceEnumerator))
        return 0
    
    device := 0
    
    if VA_IMMDeviceEnumerator_GetDevice(deviceEnumerator, device_desc, device) = 0
        goto VA_GetDevice_Return
    
    if device_desc is integer
    {
        m2 := device_desc
        if m2 >= 4096 ; Probably a device pointer, passed here indirectly via VA_GetAudioMeter or such.
        {
            ObjAddRef(device := m2)
            goto VA_GetDevice_Return
        }
    }
    else
        RegExMatch(device_desc, "(.*?)\s*(?::(\d+))?$", m)
    
    if m1 in playback,p
        m1 := "", flow := 0 ; eRender
    else if m1 in capture,c
        m1 := "", flow := 1 ; eCapture
    else if (m1 . m2) = ""  ; no name or number specified
        m1 := "", flow := 0 ; eRender (default)
    else
        flow := 2 ; eAll
    
    if (m1 . m2) = ""   ; no name or number (maybe "playback" or "capture")
    {
        VA_IMMDeviceEnumerator_GetDefaultAudioEndpoint(deviceEnumerator, flow, 0, device)
        goto VA_GetDevice_Return
    }

    VA_IMMDeviceEnumerator_EnumAudioEndpoints(deviceEnumerator, flow, 1, devices)
    
    if m1 =
    {
        VA_IMMDeviceCollection_Item(devices, m2-1, device)
        goto VA_GetDevice_Return
    }
    
    VA_IMMDeviceCollection_GetCount(devices, count)
    index := 0
    Loop % count
        if VA_IMMDeviceCollection_Item(devices, A_Index-1, device) = 0
            if InStr(VA_GetDeviceName(device), m1) && (m2 = "" || ++index = m2)
                goto VA_GetDevice_Return
            else
                ObjRelease(device), device:=0

VA_GetDevice_Return:
    ObjRelease(deviceEnumerator)
    if (devices)
        ObjRelease(devices)
    
    return device ; may be 0
}

VA_GetDeviceName(device)
{
    static PKEY_Device_FriendlyName
    if !VarSetCapacity(PKEY_Device_FriendlyName)
        VarSetCapacity(PKEY_Device_FriendlyName, 20)
        ,VA_GUID(PKEY_Device_FriendlyName :="{A45C254E-DF1C-4EFD-8020-67D146A850E0}")
        ,NumPut(14, PKEY_Device_FriendlyName, 16)
    VarSetCapacity(prop, 16)
    VA_IMMDevice_OpenPropertyStore(device, 0, store)
    ; store->GetValue(.., [out] prop)
    DllCall(NumGet(NumGet(store+0)+5*A_PtrSize), "ptr", store, "ptr", &PKEY_Device_FriendlyName, "ptr", &prop)
    ObjRelease(store)
    VA_WStrOut(deviceName := NumGet(prop,8))
    return deviceName
}

VA_WStrOut(ByRef str) {
    str := StrGet(ptr := str, "UTF-16")
    DllCall("ole32\CoTaskMemFree", "ptr", ptr)  ; FREES THE STRING.
}
VA_GUID(ByRef guid_out, guid_in="%guid_out%") {
    if (guid_in == "%guid_out%")
        guid_in :=   guid_out
    if  guid_in is integer
        return guid_in
    VarSetCapacity(guid_out, 16, 0)
    DllCall("ole32\CLSIDFromString", "wstr", guid_in, "ptr", &guid_out)
    return &guid_out
}
VA_IMMDevice_OpenPropertyStore(this, Access, ByRef Properties) {
    return DllCall(NumGet(NumGet(this+0)+4*A_PtrSize), "ptr", this, "uint", Access, "ptr*", Properties)
}
VA_IMMDevice_Activate(this, iid, ClsCtx, ActivationParams, ByRef Interface) {
    return DllCall(NumGet(NumGet(this+0)+3*A_PtrSize), "ptr", this, "ptr", VA_GUID(iid), "uint", ClsCtx, "uint", ActivationParams, "ptr*", Interface)
}
VA_IMMDeviceEnumerator_GetDevice(this, id, ByRef Device) {
    return DllCall(NumGet(NumGet(this+0)+5*A_PtrSize), "ptr", this, "wstr", id, "ptr*", Device)
}
VA_IMMDeviceEnumerator_GetDefaultAudioEndpoint(this, DataFlow, Role, ByRef Endpoint) {
    return DllCall(NumGet(NumGet(this+0)+4*A_PtrSize), "ptr", this, "int", DataFlow, "int", Role, "ptr*", Endpoint)
}
VA_IMMDeviceEnumerator_EnumAudioEndpoints(this, DataFlow, StateMask, ByRef Devices) {
    return DllCall(NumGet(NumGet(this+0)+3*A_PtrSize), "ptr", this, "int", DataFlow, "uint", StateMask, "ptr*", Devices)
}
VA_IMMDeviceCollection_GetCount(this, ByRef Count) {
    return DllCall(NumGet(NumGet(this+0)+3*A_PtrSize), "ptr", this, "uint*", Count)
}
VA_IMMDeviceCollection_Item(this, Index, ByRef Device) {
    return DllCall(NumGet(NumGet(this+0)+4*A_PtrSize), "ptr", this, "uint", Index, "ptr*", Device)
}
VA_IAudioMeterInformation_GetPeakValue(this, ByRef Peak) {
    return DllCall(NumGet(NumGet(this+0)+3*A_PtrSize), "ptr", this, "float*", Peak)
}
BoBo
Posts: 2519
Joined: 13 May 2014, 17:15

Re: If IsAudioPlaying false for 3 minutes

01 Dec 2017, 14:49

What would be the code if sound is not playing for 3 minutes, then do something?
To expensive 4 U ? :eh:
HIAC
Posts: 111
Joined: 11 Oct 2017, 17:59
Location: Republic of Serbia

Re: If IsAudioPlaying false for 3 minutes

01 Dec 2017, 15:09

BoBo wrote:
What would be the code if sound is not playing for 3 minutes, then do something?
To expensive 4 U ? :eh:
nothing comes on my mind lol :?
User avatar
jeeswg
Posts: 6904
Joined: 19 Dec 2016, 01:58
Location: UK

Re: If IsAudioPlaying false for 3 minutes

01 Dec 2017, 16:35

- To check that something is never happening, I suppose involves an infinite number of checks? Zeno's paradoxes?
- Are there some AHK commands etc that you know of that can handle doing the same action multiple times and/or delaying actions?
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
HIAC
Posts: 111
Joined: 11 Oct 2017, 17:59
Location: Republic of Serbia

Re: If IsAudioPlaying false for 3 minutes

01 Dec 2017, 16:38

jeeswg wrote:- To check that something is never happening, I suppose involves an infinite number of checks? Zeno's paradoxes?
- Are there some AHK commands etc that you know of that can handle doing the same action multiple times and/or delaying actions?
If I understood you correctly, you might be thinking of Loop or SetTimer?
User avatar
jeeswg
Posts: 6904
Joined: 19 Dec 2016, 01:58
Location: UK

Re: If IsAudioPlaying false for 3 minutes

01 Dec 2017, 16:41

Yeah, just use Loop and Sleep multiple times, or SetTimer. I suppose SetTimer would allow you to do other things at the same time, otherwise with Loop and Sleep you might want a separate script. The question is how many times per minute to check, I suppose I might be happy with 5/10/20 seconds.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
HIAC
Posts: 111
Joined: 11 Oct 2017, 17:59
Location: Republic of Serbia

Re: If IsAudioPlaying false for 3 minutes

01 Dec 2017, 16:58

Code: Select all

#Include SoundDetection.ahk
#Persistent

SetTimer, IfNoMusic
return

IfNoMusic:
{
	while(IsAudioPlaying())
		Sleep, 10
	Sleep, 10000
	MsgBox No music
}
return
Okay I made this, but it does not check whether is audio not playing for 10 seconds. I mean, if I stop audio for these 10ms, and turn it on again, i'll still get the msgbox.
User avatar
jeeswg
Posts: 6904
Joined: 19 Dec 2016, 01:58
Location: UK

Re: If IsAudioPlaying false for 3 minutes

01 Dec 2017, 17:15

Increment a counter, reset it to 0 every time sound is heard. If the counter gets high enough, that's 3 minutes of no audio.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
HIAC
Posts: 111
Joined: 11 Oct 2017, 17:59
Location: Republic of Serbia

Re: If IsAudioPlaying false for 3 minutes

01 Dec 2017, 17:39

jeeswg wrote:Increment a counter, reset it to 0 every time sound is heard. If the counter gets high enough, that's 3 minutes of no audio.
I still can't figure out, its giving me same result. >.> How would your code look like?
User avatar
jeeswg
Posts: 6904
Joined: 19 Dec 2016, 01:58
Location: UK

Re: If IsAudioPlaying false for 3 minutes

01 Dec 2017, 18:00

Here's an example.

Code: Select all

q:: ;notify if Notepad continuously active for 5 seconds
vCount := 0
Loop
{
	vCount := WinActive("ahk_class Notepad") ? vCount+1 : 0
	if (vCount = 50)
		break
	ToolTip, % vCount ? vCount : ""
	Sleep, 100
}
ToolTip
MsgBox, % "Notepad active for 5 seconds"
return
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
HIAC
Posts: 111
Joined: 11 Oct 2017, 17:59
Location: Republic of Serbia

Re: If IsAudioPlaying false for 3 minutes

01 Dec 2017, 18:25

I'm not smart. xD

I must use SetTimer in my script, therefore I can't use Break
and i have no idea how to get these counts..
User avatar
jeeswg
Posts: 6904
Joined: 19 Dec 2016, 01:58
Location: UK

Re: If IsAudioPlaying false for 3 minutes  Topic is solved

01 Dec 2017, 18:59

I hardly ever use SetTimer, I usually use separate scripts that loop, if I want a continuous loop.

Code: Select all

q:: ;notify if Notepad continuously active for 5 seconds
vCount := 0
SetTimer, IsNotepadActive, 100
return

IsNotepadActive:
vCount := WinActive("ahk_class Notepad") ? vCount+1 : 0
if (vCount = 50)
{
	SetTimer, IsNotepadActive, Off
	ToolTip
	MsgBox, % "Notepad active for 5 seconds"
	return
}
ToolTip, % vCount ? vCount : ""
return
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
HIAC
Posts: 111
Joined: 11 Oct 2017, 17:59
Location: Republic of Serbia

Re: If IsAudioPlaying false for 3 minutes

03 Dec 2017, 20:10

Got it to work, thank you very much.

Return to “Ask For Help”

Who is online

Users browsing this forum: asad41163, cmwich, dingbat, dreyk, TAC109, theelf, TLM and 58 guests