#Persistent SoundBeep, 300, 250 capsLockOn := false iniFile := "capsLockSounds.ini" SetTimer, CheckCapsLockStatus, 50 if (FileExist(iniFile)) { IniRead, offSound, %iniFile%, SoundFiles, OffSound IniRead, onSound, %iniFile%, SoundFiles, OnSound IniRead, loopSound, %iniFile%, SoundFiles, LoopSound IniRead, timerInterval, %iniFile%, Settings, TimerInterval if (timerInterval < 2000) timerInterval := 2000 } /** * Hotkey to terminate the script with Ctrl + Shift + X */ ^+x:: PlayExitSoundEffect() ExitApp return /** * Play exit sound effect before terminating */ PlayExitSoundEffect() { notes := [500, 550, 600] for _, note in notes { SoundBeep, note, 200 Sleep 150 } } /** * Check the CapsLock status and play sounds */ CheckCapsLockStatus: If (GetKeyState("CapsLock", "T") && !capsLockOn) { capsLockOn := true SetTimer, LoopCapsLockSound, %TimerInterval% SoundPlay, %onSound% } else if (!GetKeyState("CapsLock", "T") && capsLockOn) { capsLockOn := false SetTimer, LoopCapsLockSound, Off SoundPlay, %offSound% } Return /** * Play looping sound when CapsLock is on */ LoopCapsLockSound: If (capsLockOn && loopSound != "") { SoundPlay, %loopSound% } Return /** * Hotkey to show 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 gBrowseOffSoundFile, Browse Gui, Add, Button, x410 y10 w70 gPreviewOffSoundFile, 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 gBrowseOnSoundFile, Browse Gui, Add, Button, x410 y40 w70 gPreviewOnSoundFile, Preview Gui, Add, Text,, Insert the path for the looping sound when CapsLock is on here: Gui, Add, Edit, x10 y70 w300 vLoopSound, %loopSound% Gui, Add, Button, x320 y70 w80 gBrowseLoopSoundFile, Browse Gui, Add, Button, x410 y70 w70 gPreviewLoopSoundFile, Preview Gui, Add, Text,, Type (in ms) your timer for looping your sound here (must be >= 2000 ms): Gui, Add, Edit, x10 y100 w100 vTimerInterval, %timerInterval% Gui, Add, Text, x120 y100, Timer Interval (ms) Gui, Add, Button, x150 y130 w100 h30 gSaveSoundSettings, Save Gui, Add, Button, x100 y130 w100 h30 gCancelSettings, Cancel Gui, Show, , Select Sounds return /** * Browse for the sound file when CapsLock is off */ BrowseOffSoundFile: FileSelectFile, offSound, 1, , Select a sound file when CapsLock is off, Audio Files (*.wav; *.mp3) GuiControl,, OffSound, %offSound% return /** * Browse for the sound file when CapsLock is on */ BrowseOnSoundFile: FileSelectFile, onSound, 1, , Select a sound file when CapsLock is on, Audio Files (*.wav; *.mp3) GuiControl,, OnSound, %onSound% return /** * Browse for the looping sound file */ BrowseLoopSoundFile: FileSelectFile, loopSound, 1, , Select a sound file for looping when CapsLock is on, Audio Files (*.wav; *.mp3) GuiControl,, LoopSound, %loopSound% return /** * Save selected sound files and timer interval to INI file */ SaveSoundSettings: IniWrite, %offSound%, %iniFile%, SoundFiles, OffSound IniWrite, %onSound%, %iniFile%, SoundFiles, OnSound IniWrite, %loopSound%, %iniFile%, SoundFiles, LoopSound GuiControlGet, timerInterval,, TimerInterval if (timerInterval < 2000) { timerInterval := 10000 MsgBox, Timer duration should not be below 2000ms or 2 seconds. Timer set to 10 seconds. } IniWrite, %timerInterval%, %iniFile%, Settings, TimerInterval MsgBox, Configuration saved. Gui, Destroy return /** * Preview the selected off sound */ PreviewOffSoundFile: GuiControlGet, offSound, , OffSound if (offSound = "") { MsgBox, File path is empty. } else if !FileExist(offSound) { MsgBox, Invalid file path. } else { SoundPlay, %offSound% } return /** * Preview the selected on sound */ PreviewOnSoundFile: GuiControlGet, onSound, , OnSound if (onSound = "") { MsgBox, File path is empty. } else if !FileExist(onSound) { MsgBox, Invalid file path. } else { SoundPlay, %onSound% } return /** * Preview the selected looping sound */ PreviewLoopSoundFile: GuiControlGet, loopSound, , LoopSound if (loopSound = "") { MsgBox, File path is empty. } else if !FileExist(loopSound) { MsgBox, Invalid file path. } else { SoundPlay, %loopSound% } return /** * Cancel and close the GUI */ CancelSettings: Gui, Destroy return