#Persistent ; Keep the script running SoundBeep, 300, 250 capsLockOn := false iniFile := "capsLockSounds.ini" SetTimer, CheckCapsLock, 50 ; Check the CapsLock status every 50 milliseconds if (FileExist(iniFile)) { IniRead, offSound, %iniFile%, SoundFiles, OffSound IniRead, onSound, %iniFile%, SoundFiles, OnSound IniRead, loopSound, %iniFile%, SoundFiles, LoopSound IniRead, timerInterval, %iniFile%, Settings, TimerInterval ; Ensure timer interval is not below 2 seconds if (timerInterval < 2000) timerInterval := 2000 } ; Hotkey to terminate the script with Ctrl + Shift + X ^+x:: PlayExitSound() ExitApp return PlayExitSound() { notes := [500, 550, 600] for _, note in notes { SoundBeep, note, 200 Sleep 150 } } CheckCapsLock: If (GetKeyState("CapsLock", "T") && !capsLockOn) { capsLockOn := true SetTimer, BeepEvery10Seconds, %TimerInterval% SoundPlay, %onSound% } else if (!GetKeyState("CapsLock", "T") && capsLockOn) { capsLockOn := false SetTimer, BeepEvery10Seconds, Off SoundPlay, %offSound% } Return BeepEvery10Seconds: If (capsLockOn && loopSound != "") { SoundPlay, %loopSound% } Return ; Hotkey to display the GUI for selecting sound files ^!+s:: Gui, Add, Text,, Insert the path for the sound when you turn your CapsLock off here: Gui, Add, Edit, x10 y10 w300 vOffSound, %offSound% Gui, Add, Button, x320 y10 w80 gBrowseOffSound, Browse Gui, Add, Button, x410 y10 w70 gPreviewOffSound, Preview Gui, Add, Text,, Insert the path for the sound when you turn your CapsLock on here: Gui, Add, Edit, x10 y40 w300 vOnSound, %onSound% Gui, Add, Button, x320 y40 w80 gBrowseOnSound, Browse Gui, Add, Button, x410 y40 w70 gPreviewOnSound, Preview Gui, Add, Text,, Insert the path for the sound when the CapsLock is on here: Gui, Add, Edit, x10 y70 w300 vLoopSound, %loopSound% Gui, Add, Button, x320 y70 w80 gBrowseLoopSound, Browse Gui, Add, Button, x410 y70 w70 gPreviewLoopSound, Preview Gui, Add, Text,, type (In Ms) your timer for looping your sound here: noted it should be not less than 2000ms or 2sec Gui, Add, Edit, x10 y100 w100 vTimerInterval, %timerInterval% Gui, Add, Text, x120 y100, Timer Interval (ms) Gui, Add, Button, x150 y130 w100 h30 gSaveSounds, Save Gui, Add, Button, x100 y130 w100 h30 gCancel, Cancel Gui, Show, , Select Sounds return ; Browse button for selecting the sound file when CapsLock is off BrowseOffSound: FileSelectFile, offSound, 1, , Select a sound file when CapsLock is off, Audio Files (*.wav; *.mp3) GuiControl,, OffSound, %offSound% return ; Browse button for selecting the sound file when CapsLock is on BrowseOnSound: FileSelectFile, onSound, 1, , Select a sound file when CapsLock is on, Audio Files (*.wav; *.mp3) GuiControl,, OnSound, %onSound% return ; Browse button for selecting the sound file for looping when CapsLock is on BrowseLoopSound: FileSelectFile, loopSound, 1, , Select a sound file for looping when CapsLock is on, Audio Files (*.wav; *.mp3) GuiControl,, LoopSound, %loopSound% return ; Save button to save the selected sound files and timer interval SaveSounds: ; Save the selected sound file paths and timer interval to the INI file IniWrite, %offSound%, %iniFile%, SoundFiles, OffSound IniWrite, %onSound%, %iniFile%, SoundFiles, OnSound IniWrite, %loopSound%, %iniFile%, SoundFiles, LoopSound GuiControlGet, timerInterval,, TimerInterval ; Ensure timer interval is not below 2 seconds if (timerInterval < 2000) { timerInterval := 10000 MsgBox, Timer duration should not be below 2000ms or 2 seconds. Timer set to 10seconds. } IniWrite, %timerInterval%, %iniFile%, Settings, TimerInterval MsgBox, configuration saved.. Gui, Destroy return ; Preview button functionality PreviewOffSound: GuiControlGet, offSound, , OffSound if (offSound = "") { MsgBox, File path is empty. } else if !FileExist(offSound) { MsgBox, Invalid file path. } else { SoundPlay, %offSound% } return PreviewOnSound: GuiControlGet, onSound, , OnSound if (onSound = "") { MsgBox, File path is empty. } else if !FileExist(onSound) { MsgBox, Invalid file path. } else { SoundPlay, %onSound% } return PreviewLoopSound: GuiControlGet, loopSound, , LoopSound if (loopSound = "") { MsgBox, File path is empty. } else if !FileExist(loopSound) { MsgBox, Invalid file path. } else { SoundPlay, %loopSound% } return Cancel: Gui, Destroy return