Function to change the volume of an application. Returns the previous sound volume.
Last active
April 27, 2025 11:43
-
-
Save anonymous1184/b251cd8407a379d4965791585887cfce to your computer and use it in GitHub Desktop.
AppVol()
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#Requires AutoHotkey v2.0 | |
AppVol(Target := "A", Level := 0) { | |
if (Target ~= "^[-+]?\d+$") { | |
Level := Target | |
Target := "A" | |
} else if (SubStr(Target, -4) = ".exe") { | |
Target := "ahk_exe " Target | |
} | |
try { | |
hw := DetectHiddenWindows(true) | |
appName := WinGetProcessName(Target) | |
DetectHiddenWindows(hw) | |
} catch { | |
throw TargetError("Target not found.", -1, Target) | |
} | |
GUID := Buffer(16) | |
DllCall("ole32\CLSIDFromString", "Str", "{77AA99A0-1BD6-484F-8BC7-2C654C9A9B6F}", "Ptr", GUID) | |
IMMDeviceEnumerator := ComObject("{BCDE0395-E52F-467C-8E3D-C4579291692E}", "{A95664D2-9614-4F35-A746-DE8DB63617E6}") | |
ComCall(4, IMMDeviceEnumerator, "UInt", 0, "UInt", 1, "Ptr*", &IMMDevice := 0) | |
ObjRelease(IMMDeviceEnumerator.Ptr) | |
ComCall(3, IMMDevice, "Ptr", GUID, "UInt", 23, "Ptr", 0, "Ptr*", &IAudioSessionManager2 := 0) | |
ObjRelease(IMMDevice) | |
ComCall(5, IAudioSessionManager2, "Ptr*", &IAudioSessionEnumerator := 0) || DllCall("SetLastError", "UInt", 0) | |
ObjRelease(IAudioSessionManager2) | |
ComCall(3, IAudioSessionEnumerator, "UInt*", &cSessions := 0) | |
loop cSessions { | |
ComCall(4, IAudioSessionEnumerator, "Int", A_Index - 1, "Ptr*", &IAudioSessionControl := 0) | |
IAudioSessionControl2 := ComObjQuery(IAudioSessionControl, "{BFB7FF88-7239-4FC9-8FA2-07C950BE9C6D}") | |
ObjRelease(IAudioSessionControl) | |
ComCall(14, IAudioSessionControl2, "UInt*", &pid := 0) | |
if (ProcessGetName(pid) != appName) { | |
continue | |
} | |
ISimpleAudioVolume := ComObjQuery(IAudioSessionControl2, "{87CE5498-68D6-44E5-9215-6DA47EF883D8}") | |
ComCall(6, ISimpleAudioVolume, "Int*", &isMuted := 0) | |
if (isMuted || !Level) { | |
ComCall(5, ISimpleAudioVolume, "Int", !isMuted, "Ptr", 0) | |
} | |
if (Level) { | |
ComCall(4, ISimpleAudioVolume, "Float*", &levelOld := 0) | |
if (Level ~= "^[-+]") { | |
levelNew := Max(0.0, Min(1.0, levelOld + (Level / 100))) | |
} else { | |
levelNew := Level / 100 | |
} | |
if (levelNew != levelOld) { | |
ComCall(3, ISimpleAudioVolume, "Float", levelNew, "Ptr", 0) | |
} | |
} | |
ObjRelease(ISimpleAudioVolume.Ptr) | |
} | |
return (IsSet(levelOld) ? Round(levelOld * 100) : -1) | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#Requires AutoHotkey v1.1 | |
AppVol(Target := "A", Level := 0) { | |
if (Target ~= "^[-+]?\d+$") { | |
Level := Target | |
Target := "A" | |
} else if (SubStr(Target, -3) = ".exe") { | |
Target := "ahk_exe " Target | |
} | |
hw := A_DetectHiddenWindows | |
DetectHiddenWindows On | |
WinGet appName, ProcessName, % Target | |
DetectHiddenWindows % hw | |
if (appName = "") { | |
throw Exception("Target not found.", -1, Target) | |
} | |
VarSetCapacity(GUID, 16, 0) | |
DllCall("ole32\CLSIDFromString", "Str", "{77AA99A0-1BD6-484F-8BC7-2C654C9A9B6F}", "Ptr", &GUID) | |
IMMDeviceEnumerator := ComObjCreate("{BCDE0395-E52F-467C-8E3D-C4579291692E}", "{A95664D2-9614-4F35-A746-DE8DB63617E6}") | |
DllCall(NumGet(NumGet(IMMDeviceEnumerator + 0) + 4 * A_PtrSize), "Ptr", IMMDeviceEnumerator, "UInt", 0, "UInt", 1, "Ptr*", IMMDevice := 0) | |
ObjRelease(IMMDeviceEnumerator) | |
DllCall(NumGet(NumGet(IMMDevice + 0) + 3 * A_PtrSize), "Ptr", IMMDevice, "Ptr", &GUID, "UInt", 23, "Ptr", 0, "Ptr*", IAudioSessionManager2 := 0) | |
ObjRelease(IMMDevice) | |
DllCall(NumGet(NumGet(IAudioSessionManager2 + 0) + 5 * A_PtrSize), "Ptr", IAudioSessionManager2, "Ptr*", IAudioSessionEnumerator := 0) || DllCall("SetLastError", "UInt", 0) | |
ObjRelease(IAudioSessionManager2) | |
DllCall(NumGet(NumGet(IAudioSessionEnumerator + 0) + 3 * A_PtrSize), "Ptr", IAudioSessionEnumerator, "UInt*", cSessions := 0) | |
loop % cSessions { | |
DllCall(NumGet(NumGet(IAudioSessionEnumerator + 0) + 4 * A_PtrSize), "Ptr", IAudioSessionEnumerator, "Int", A_Index - 1, "Ptr*", IAudioSessionControl := 0) | |
IAudioSessionControl2 := ComObjQuery(IAudioSessionControl, "{BFB7FF88-7239-4FC9-8FA2-07C950BE9C6D}") | |
ObjRelease(IAudioSessionControl) | |
DllCall(NumGet(NumGet(IAudioSessionControl2 + 0) + 14 * A_PtrSize), "Ptr", IAudioSessionControl2, "UInt*", pid := 0) | |
if (ProcessGetName(pid) != appName) { | |
continue | |
} | |
ISimpleAudioVolume := ComObjQuery(IAudioSessionControl2, "{87CE5498-68D6-44E5-9215-6DA47EF883D8}") | |
DllCall(NumGet(NumGet(ISimpleAudioVolume + 0) + 6 * A_PtrSize), "Ptr", ISimpleAudioVolume, "Int*", isMuted := 0) | |
if (isMuted || !Level) { | |
DllCall(NumGet(NumGet(ISimpleAudioVolume + 0) + 5 * A_PtrSize), "Ptr", ISimpleAudioVolume, "Int", !isMuted, "Ptr", 0) | |
} | |
if (Level) { | |
DllCall(NumGet(NumGet(ISimpleAudioVolume + 0) + 4 * A_PtrSize), "Ptr", ISimpleAudioVolume, "Float*", levelOld := 0) | |
if (Level ~= "^[-+]") { | |
levelNew := Max(0.0, Min(1.0, levelOld + (Level / 100))) | |
} else { | |
levelNew := Level / 100 | |
} | |
if (levelNew != levelOld) { | |
DllCall(NumGet(NumGet(ISimpleAudioVolume + 0) + 3 * A_PtrSize), "Ptr", ISimpleAudioVolume, "Float", levelNew, "Ptr", 0) | |
} | |
} | |
ObjRelease(ISimpleAudioVolume) | |
} | |
return (IsSet(levelOld) ? Round(levelOld * 100) : -1) | |
} | |
ProcessGetName(Pid) { | |
sz := VarSetCapacity(name, 1024, 0) | |
hProc := DllCall("OpenProcess", "UInt", 0x0410, "Int", false, "UInt", Pid, "Ptr") | |
if (hProc != 0) { | |
DllCall("psapi\GetModuleBaseName", "Ptr", hProc, "Ptr", 0, "Str", name, "UInt", sz) | |
DllCall("CloseHandle", "Ptr", hProc) | |
} | |
VarSetCapacity(name, -1) | |
return name | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--- Volume.ahk | |
+++ Volume1.ahk | |
@@ -1 +1 @@ | |
-#Requires AutoHotkey v2.0 | |
+#Requires AutoHotkey v1.1 | |
@@ -7 +7 @@ | |
- } else if (SubStr(Target, -4) = ".exe") { | |
+ } else if (SubStr(Target, -3) = ".exe") { | |
@@ -10,6 +10,6 @@ | |
- try { | |
- hw := DetectHiddenWindows(true) | |
- appName := WinGetProcessName(Target) | |
- DetectHiddenWindows(hw) | |
- } catch { | |
- throw TargetError("Target not found.", -1, Target) | |
+ hw := A_DetectHiddenWindows | |
+ DetectHiddenWindows On | |
+ WinGet appName, ProcessName, % Target | |
+ DetectHiddenWindows % hw | |
+ if (appName = "") { | |
+ throw Exception("Target not found.", -1, Target) | |
@@ -17,6 +17,6 @@ | |
- GUID := Buffer(16) | |
- DllCall("ole32\CLSIDFromString", "Str", "{77AA99A0-1BD6-484F-8BC7-2C654C9A9B6F}", "Ptr", GUID) | |
- IMMDeviceEnumerator := ComObject("{BCDE0395-E52F-467C-8E3D-C4579291692E}", "{A95664D2-9614-4F35-A746-DE8DB63617E6}") | |
- ComCall(4, IMMDeviceEnumerator, "UInt", 0, "UInt", 1, "Ptr*", &IMMDevice := 0) | |
- ObjRelease(IMMDeviceEnumerator.Ptr) | |
- ComCall(3, IMMDevice, "Ptr", GUID, "UInt", 23, "Ptr", 0, "Ptr*", &IAudioSessionManager2 := 0) | |
+ VarSetCapacity(GUID, 16, 0) | |
+ DllCall("ole32\CLSIDFromString", "Str", "{77AA99A0-1BD6-484F-8BC7-2C654C9A9B6F}", "Ptr", &GUID) | |
+ IMMDeviceEnumerator := ComObjCreate("{BCDE0395-E52F-467C-8E3D-C4579291692E}", "{A95664D2-9614-4F35-A746-DE8DB63617E6}") | |
+ DllCall(NumGet(NumGet(IMMDeviceEnumerator + 0) + 4 * A_PtrSize), "Ptr", IMMDeviceEnumerator, "UInt", 0, "UInt", 1, "Ptr*", IMMDevice := 0) | |
+ ObjRelease(IMMDeviceEnumerator) | |
+ DllCall(NumGet(NumGet(IMMDevice + 0) + 3 * A_PtrSize), "Ptr", IMMDevice, "Ptr", &GUID, "UInt", 23, "Ptr", 0, "Ptr*", IAudioSessionManager2 := 0) | |
@@ -24 +24 @@ | |
- ComCall(5, IAudioSessionManager2, "Ptr*", &IAudioSessionEnumerator := 0) || DllCall("SetLastError", "UInt", 0) | |
+ DllCall(NumGet(NumGet(IAudioSessionManager2 + 0) + 5 * A_PtrSize), "Ptr", IAudioSessionManager2, "Ptr*", IAudioSessionEnumerator := 0) || DllCall("SetLastError", "UInt", 0) | |
@@ -26,3 +26,3 @@ | |
- ComCall(3, IAudioSessionEnumerator, "UInt*", &cSessions := 0) | |
- loop cSessions { | |
- ComCall(4, IAudioSessionEnumerator, "Int", A_Index - 1, "Ptr*", &IAudioSessionControl := 0) | |
+ DllCall(NumGet(NumGet(IAudioSessionEnumerator + 0) + 3 * A_PtrSize), "Ptr", IAudioSessionEnumerator, "UInt*", cSessions := 0) | |
+ loop % cSessions { | |
+ DllCall(NumGet(NumGet(IAudioSessionEnumerator + 0) + 4 * A_PtrSize), "Ptr", IAudioSessionEnumerator, "Int", A_Index - 1, "Ptr*", IAudioSessionControl := 0) | |
@@ -31 +31 @@ | |
- ComCall(14, IAudioSessionControl2, "UInt*", &pid := 0) | |
+ DllCall(NumGet(NumGet(IAudioSessionControl2 + 0) + 14 * A_PtrSize), "Ptr", IAudioSessionControl2, "UInt*", pid := 0) | |
@@ -36 +36 @@ | |
- ComCall(6, ISimpleAudioVolume, "Int*", &isMuted := 0) | |
+ DllCall(NumGet(NumGet(ISimpleAudioVolume + 0) + 6 * A_PtrSize), "Ptr", ISimpleAudioVolume, "Int*", isMuted := 0) | |
@@ -38 +38 @@ | |
- ComCall(5, ISimpleAudioVolume, "Int", !isMuted, "Ptr", 0) | |
+ DllCall(NumGet(NumGet(ISimpleAudioVolume + 0) + 5 * A_PtrSize), "Ptr", ISimpleAudioVolume, "Int", !isMuted, "Ptr", 0) | |
@@ -41 +41 @@ | |
- ComCall(4, ISimpleAudioVolume, "Float*", &levelOld := 0) | |
+ DllCall(NumGet(NumGet(ISimpleAudioVolume + 0) + 4 * A_PtrSize), "Ptr", ISimpleAudioVolume, "Float*", levelOld := 0) | |
@@ -48 +48 @@ | |
- ComCall(3, ISimpleAudioVolume, "Float", levelNew, "Ptr", 0) | |
+ DllCall(NumGet(NumGet(ISimpleAudioVolume + 0) + 3 * A_PtrSize), "Ptr", ISimpleAudioVolume, "Float", levelNew, "Ptr", 0) | |
@@ -51 +51 @@ | |
- ObjRelease(ISimpleAudioVolume.Ptr) | |
+ ObjRelease(ISimpleAudioVolume) | |
@@ -53,0 +54,11 @@ | |
+ | |
+ProcessGetName(Pid) { | |
+ sz := VarSetCapacity(name, 1024, 0) | |
+ hProc := DllCall("OpenProcess", "UInt", 0x0410, "Int", false, "UInt", Pid, "Ptr") | |
+ if (hProc != 0) { | |
+ DllCall("psapi\GetModuleBaseName", "Ptr", hProc, "Ptr", 0, "Str", name, "UInt", sz) | |
+ DllCall("CloseHandle", "Ptr", hProc) | |
+ } | |
+ VarSetCapacity(name, -1) | |
+ return name | |
+} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#Requires AutoHotkey v2.0 | |
#Include %A_LineFile%\..\AppVol.ahk | |
Exit() ; End of auto-execute | |
; Active Window | |
1::AppVol() ; Toggle Mute | |
2::AppVol("-2") ; Decrease volume 2% | |
3::AppVol("+2") ; Increase volume 2% | |
4::AppVol( 50) ; Set volume to 50% | |
5::AppVol( 100) ; Set volume to 100% | |
; By executable name | |
+1::AppVol("firefox.exe") ; Toggle Mute | |
+2::AppVol("firefox.exe", "-2") ; Decrease volume 2% | |
+3::AppVol("firefox.exe", "+2") ; Increase volume 2% | |
+4::AppVol("firefox.exe", 50) ; Set volume to 50% | |
+5::AppVol("firefox.exe", 100) ; Set volume to 100% | |
; By window title | |
^1::AppVol("Picture-in-Picture") ; Toggle Mute | |
^2::AppVol("Picture-in-Picture", "-2") ; Decrease volume 2% | |
^3::AppVol("Picture-in-Picture", "+2") ; Increase volume 2% | |
^4::AppVol("Picture-in-Picture", 50) ; Set volume to 50% | |
^5::AppVol("Picture-in-Picture", 100) ; Set volume to 100% |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#Requires AutoHotkey v1.1 | |
#Warn | |
#NoEnv | |
#Include %A_LineFile%\..\AppVol1.ahk | |
SetBatchLines -1 | |
return ; End of auto-execute | |
; Active Window | |
1::AppVol() ; Toggle Mute | |
2::AppVol("-2") ; Decrease volume 2% | |
3::AppVol("+2") ; Increase volume 2% | |
4::AppVol( 50) ; Set volume to 50% | |
5::AppVol( 100) ; Set volume to 100% | |
; By executable name | |
+1::AppVol("firefox.exe") ; Toggle Mute | |
+2::AppVol("firefox.exe", "-2") ; Decrease volume 2% | |
+3::AppVol("firefox.exe", "+2") ; Increase volume 2% | |
+4::AppVol("firefox.exe", 50) ; Set volume to 50% | |
+5::AppVol("firefox.exe", 100) ; Set volume to 100% | |
; By window title | |
^1::AppVol("Picture-in-Picture") ; Toggle Mute | |
^2::AppVol("Picture-in-Picture", "-2") ; Decrease volume 2% | |
^3::AppVol("Picture-in-Picture", "+2") ; Increase volume 2% | |
^4::AppVol("Picture-in-Picture", 50) ; Set volume to 50% | |
^5::AppVol("Picture-in-Picture", 100) ; Set volume to 100% |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hi, great function! But I had to make this edit to line 32 for it to not throw errors:
Also, I would like to ask: shouldn't the loop break if it finds the process? That is: should we add
break
at the end of the loop? Because I think there is no point in searching if we have found the correct process.I have tested it an it works fine.