This issue has haunted me, so I came up with the following
AHK function:
; translate a sequence of "dits" and "dahs" into sounds
morse(sequence)
{
; access global variables
global
; split Morse string into single characters
StringSplit, sequenceItems, sequence
; translate characters into sounds
Loop, %sequenceItems0%
{
; if "dit"
If sequenceItems%A_Index% = %dit%
{
SoundBeep, %frequency%, %short%
Sleep, %spacing_symbol%
}
; if "dah"
Else If sequenceItems%A_Index% = %dah%
{
SoundBeep, %frequency%, %long%
Sleep, %spacing_symbol%
}
; if new letter
Else If sequenceItems%A_Index% = %separator_letters%
{
Sleep, %spacing_letter% ; DEBUG: one dit too long due to preceding "Sleep, %spacing_symbol%"?
}
; if new word
Else If sequenceItems%A_Index% = %separator_words%
{
Sleep, %spacing_word% ; DEBUG: one dit too long due to preceding delay after character?
}
Else
{
MsgBox, % "unrecognized character: " . sequenceItems%A_Index%
}
}
}
In order to properly understand how this function works, take a look at the complete script:
/*
[program name] v[version number (e.g. 1.0)]
by [author name]
[short description]
*/
/*
ToDo:
- [...]
*/
/*
change history
¯¯¯¯¯¯¯¯¯¯¯¯¯¯
# v[version number] ([date (yyyy-mm-dd)])
* [...]
*/
/*
settings, variable declarations
*/
#SingleInstance Force
programName = [program name] ; DEBUG: toDo
programVersion = [version number] ; DEBUG: toDo
programFullName = %programName% v%programVersion%
programAuthor = [author name] ; DEBUG: toDo?
dit = s ; symbol for "dit"
dah = l ; symbol for "dah"
separator_letters = , ; symbol for separating letters
separator_words = _ ; symbol for separating words
short = 50 ; duration of "dit"
long = % 3 * short ; duration of "dah"
spacing_symbol = %short% ; duration between symbols
spacing_letter = %long% ; duration between letters
spacing_word = % 7 * short ; duration between words
frequency = 600 ; frequency of "beep" sound produced
; Morse alphabet
char_a = % dit dah
char_b = % dah dit dit dit
char_c = % dah dit dah dit
char_d = % dah dit dit
char_e = % dit
char_f = % dit dit dah dit
char_g = % dah dah dit
char_h = % dit dit dit dit
char_i = % dit dit
char_j = % dit dah dah dah
char_k = % dah dit dah
char_l = % dit dah dit dit
char_m = % dah dah
char_n = % dah dit
char_o = % dah dah dah
char_p = % dit dah dah dit
char_q = % dah dah dit dah
char_r = % dit dah dit
char_s = % dit dit dit
char_t = % dah
char_u = % dit dit dah
char_v = % dit dit dit dah
char_w = % dit dah dah
char_x = % dah dit dit dah
char_y = % dah dit dah dah
char_z = % dah dah dit dit
/*
auto-execute section
*/
; process command line parameters - DEBUG: toDo
;If 0 > 0
;GoSub, commandLineParameters
morse(char_a)
; construct tray menu
GoSub, trayMenu
; end of auto-execute section
GoSub, quit ; DEBUG: shouldn't be necessary!?
Return
/*
hotkeys
*/
; [ALT]+[ESC]: terminate script
!Esc::
Suspend ; exempt from suspension
GoSub, quit
Return
/*
subroutines
*/
; construct tray menu - DEBUG: toDo
trayMenu:
; disable standard menu items
Menu, Tray, NoStandard
; show info message
Menu, Tray, Add, &About, about
; separator
Menu, Tray, Add
; terminate script
Menu, Tray, Add, &Quit, quit
Return
; show info message - DEBUG: toDo
about:
MsgBox, 64, %programFullName%,
( LTrim Join
%programFullName%`n
%A_Space%by %programAuthor%`n
`n
[short description]`n
`n
Use [ALT]+[ESC] to the terminate program.
)
Return
; terminate script
quit:
ExitApp
Return
/*
functions
*/
; translate a sequence of "dits" and "dahs" into sounds
morse(sequence)
{
; access global variables
global
; split string into single characters
StringSplit, sequenceItems, sequence
; translate characters into sounds
Loop, %sequenceItems0%
{
; if "dit"
If sequenceItems%A_Index% = %dit%
{
SoundBeep, %frequency%, %short%
Sleep, %spacing_symbol%
}
; if "dah"
Else If sequenceItems%A_Index% = %dah%
{
SoundBeep, %frequency%, %long%
Sleep, %spacing_symbol%
}
; if new letter
Else If sequenceItems%A_Index% = %separator_letters%
{
Sleep, %spacing_letter% ; DEBUG: one dit too long due to preceding "Sleep, %spacing_symbol%"?
}
; if new word
Else If sequenceItems%A_Index% = %separator_words%
{
Sleep, %spacing_word% ; DEBUG: one dit too long due to preceding delay after character?
}
Else
{
MsgBox, % "unrecognized character: " . sequenceItems%A_Index%
}
}
}
I'd recommend you copy this code to your AHK editor (syntax highlighting!)...
Disclaimer: I didn't properly check this code yet (I'm tired), and a few lines and variables (e.g.
programVersion) are not necessary. That's because I've used my standard template for AHK scripts.