[sci.electronics] Morse code program for PC .. here is

kinsman@ssd.kodak.com (Andy Kinsman (253-XXXX)) (12/14/90)

From kodak!rochester!rutgers!bellcore!faline!thumper!ulysses!gamma!pyuxp!pyuxe!pyuxf!ral Fri Jun 10 15:34:37 EDT 1988

Here's a BASICA Morse code practice program.
Ron Levenberg

10    ' Morse Code Practice Program. Elwood Downey, WB0OEW, August, 1983.
20    ' Written for the IBM PC in Microsoft Basica, V1.1, for PC-DOS V1.1.
30    ' This program may be freely used, traded or copied but the author's
40    ' name and this stipulation shall remain as comments and the program
50    ' shall never be sold for profit.
60    '
80    KEY OFF
90    '
100   ' select input source: either from a file, the keyboard or random.
101 PRINT:PRINT "   ALL entries are to be in LOWER case letters":PRINT
104   ' check for color or monochrome
105   INPUT "Do you have a color monitor";ZZZ$
106   IF LEFT$(ZZZ$,1)="Y" OR LEFT$(ZZZ$,1)="y" THEN COLOR 7,1
107   CLS
110   INPUT "Name of input file? (or `random' or `con:' or file name) ",F$
120   IF F$="random" THEN RANFILE=1 ELSE RANFILE=0
130   IF RANFILE=1 THEN RANDOMIZE VAL(RIGHT$(TIME$,2)): NCHRS=0: NGRPS=0
140   IF RANFILE=0 THEN OPEN F$ FOR INPUT AS #1
150   '
160   ' select speed
170   INPUT "wpm? ", WPM
180   '
190   ' initialize code strings
200   ' to add more characters, such as apostrophe, increase numcodes,
210   ' add code string and character at end of current lists and add case
220   ' to main loop, below.
230   NUMCODES = 41  ' . , / ? - plus 26 + 10
240   DIM CODES$(NUMCODES-1)
250   DIM CHARS$(NUMCODES-1)
260   FOR I=0 TO NUMCODES-1
270     READ CODES$(I)
280   NEXT
290  FOR I=0 TO NUMCODES-1
300    READ CHARS$(I)
310  NEXT
320  ' code strings. in one-to-one correspondence with characters, below.
330  DATA ".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "...."
340  DATA "..", ".---", "-.-", ".-..", "--"
350  DATA "-.", "---", ".--.", "--.-", ".-.", "...", "-"
360  DATA "..-", "...-", ".--", "-..-", "-.--", "--.."
370  DATA "-----", ".----", "..---", "...--", "....-", "....."
380  DATA "-....", "--...", "---..", "----."
390  DATA ".-.-.-", "--..--", "-..-.", "..--..", "-...-"
400  ' characters.
410  DATA "A", "B", "C", "D", "E", "F", "G", "H"
420  DATA "I", "J", "K", "L", "M"
430  DATA "N", "O", "P", "Q", "R", "S", "T"
440  DATA "U", "V", "W", "X", "Y", "Z"
450  DATA "0", "1", "2", "3", "4", "5"
460  DATA "6", "7", "8", "9"
470  DATA ".", ",", "/", "?", "-"
480 '
490 ' set up arrow keys to change speed and frequency.
500 PRINT
510 PRINT CHR$(24); " "; CHR$(25); " to raise or lower tone,   ";
520 PRINT CHR$(27); " "; CHR$(26); " for slower or faster code."
530 PRINT "Ctrl-Break to quit, F9 to pause."
540 PRINT
550 ON KEY(11) GOSUB 1040: KEY(11) ON
560 ON KEY(14) GOSUB 1050: KEY(14) ON
570 ON KEY(12) GOSUB 1090: KEY(12) ON
580 ON KEY(13) GOSUB 1080: KEY(13) ON
590 ON KEY(9) GOSUB 1330: KEY(9) ON
600 '
610 ' set defaults, init screen.
620 F = 600             ' initial tone frequency
630 SIL = 32767         ' special code for no tone
640 GOSUB 1120   ' calculate dit, dah and space lengths.
650 GOSUB 1180   ' display wpm and freq
660 '
670 ' define character type checking functions
680  DEF FNLOWER(C$) = "a"<=C$ AND C$<="z"
690  DEF FNUPPER(C$) = "A"<=C$ AND C$<="Z"
700  DEF FNDIGIT(C$) = "0"<=C$ AND C$<="9"
710 '
720 ' main loop. read (or generate) each character, sound it and print it.
730  IF RANFILE THEN GOSUB 1240: GOSUB 900: PRINT CHARS$(MORSE);: GOTO 870
740  C$ = INPUT$(1,#1)
750  IF " "=C$ OR C$=CHR$(13) THEN GOSUB 990: GOTO 860
760  IF "."=C$ THEN MORSE=36: GOTO 850  ' morse <- codes$ array index
770  IF ","=C$ THEN MORSE=37: GOTO 850
780  IF "/"=C$ THEN MORSE=38: GOTO 850
790  IF "?"=C$ THEN MORSE=39: GOTO 850
800  IF "-"=C$ THEN MORSE=40: GOTO 850
810  IF FNLOWER(C$) THEN C$ = CHR$(ASC(C$)-32)
820  IF FNUPPER(C$) THEN MORSE=ASC(C$)-ASC("A"):  GOTO 850
830  IF FNDIGIT(C$) THEN MORSE=ASC(C$)-ASC("0")+26: GOTO 850
840  GOTO 870
850 GOSUB 900
860 PRINT C$;
870 GOTO 730
880 '
890 ' sound dit for each ".", dah for each "-" in string codes$(morse)
900 FOR I=1 TO LEN(CODES$(MORSE))
910   IF MID$(CODES$(MORSE),I,1) = "." THEN GOSUB 1000 ELSE GOSUB 1010
920 NEXT
930 GOSUB 980
940 RETURN
950 '
960 ' produce elemental sounds, or silences.
970  SOUND SIL,DIT: RETURN      ' element space
980 SOUND SIL,ELE*2: RETURN     ' character space, allow for previous trailing
990 SOUND SIL,ELE*6: RETURN   ' word space, allow for trailing.
1000 SOUND F,DIT: GOSUB 970: RETURN        ' dit
1010 SOUND F,DAH: GOSUB 970: RETURN        ' dah
1020 '
1030 ' change frequency of tone
1040 F = F*1.104: GOSUB 1180: RETURN
1050 F = F/1.104: GOSUB 1180: RETURN
1060 '
1070 ' change speed; update element timings.
1080 WPM = WPM+1: GOSUB 1120: GOSUB 1180: RETURN
1090 WPM = WPM-1: GOSUB 1120: GOSUB 1180: RETURN
1100 '
1110 ' calculate element timings. units are clock ticks, which are at 18.2hz.
1120 IF WPM<13 THEN CWPM=13 ELSE CWPM=WPM
1130 DIT = 21.84/CWPM: DAH = 3*DIT
1140 IF WPM>=13 THEN ELE=DIT ELSE ELE=DIT*((CWPM/WPM-1)*13+2)/2
1150 RETURN
1160 '
1170 ' display current speed and frequency. return cursor where it was.
1180 COL=POS(0): ROW=CSRLIN: LOCATE 1,60
1190 PRINT " wpm: "; WPM: LOCATE 2,60: PRINT "freq: "; F; "     "
1200 LOCATE 2,5: PRINT WPM; "   "
1210 LOCATE ROW,COL
1220 RETURN
1230 '
1240 ' set MORSE to random value from 0 up to numcodes to select random char.
1250 ' force a space character after every fifth time we are called
1260 ' and a newline before every 13 groups.
1270 IF NCHRS=5 THEN PRINT " ";: GOSUB 990: NCHRS=0: NGRPS=NGRPS+1
1280 IF NCHRS=0 AND NGRPS=13 THEN PRINT: NGRPS=0
1290 MORSE = INT(RND*NUMCODES)
1300 NCHRS=NCHRS+1: RETURN
1310 '
1320 ' handle F9, the pause control.
1330 COL9=POS(0): ROW9=CSRLIN
1340 LOCATE 24,30: COLOR 16,7: PRINT " Press any key to continue ";
1350 X$=INKEY$: IF X$="" THEN 1350
1360 LOCATE 24,30: COLOR 7,1:  PRINT "                           ";
1370 LOCATE ROW9,COL9: RETURN
-- 
kinsman@ssd.kodak.com ( Andy Kinsman )  phone (716) 253-7794

spcecdt@deeptht.UUCP (John DuBois) (12/25/90)

     Here's an awk text-to-Morse translator that will work on SCO consoles...

	John DuBois
	spcecdt@deeptht.santa-cruz.ca.us

:
# Morse to ascii translator
# John H. DuBois III    11/90
# Written for XENIX console; depends on SYSV tty modes (cr2)
# and SCO ANSI set-beep-length escape code
# Stuck at max ~8 wpm by shortest console beep & length of cr2 delay

# save tty mode so it can be reset
ttymode=`stty -g < /dev/tty`
# reset tty mode if program aborted
trap "stty $ttymode < /dev/tty" INT QUIT
# set cr2 so that cr delays can be used for timing
stty cr2 < /dev/tty
# set bell to 1/(1487*840.3ns) Hz (800 Hz), 100 mS duration
# note: bell is *not* reset at end of script, 
# since there's no way to tell what it was set to from a script
echo -n "\033[=1487;1B"

tr '[A-Z]' '[a-z]' | awk '
BEGIN {
	split("a.- b-... c-.-. d-.. e. f..-. g--. h.... i.. j.--- k-.- l.-.."\
" m-- n-. o--- p.--. q--.- r.-. s... t- u..- v...- w.-- x-..- y-.-- z--.."\
" ,--..-- ..-.-.- --...- =-...- /-..-. E.-.-."\
" 0----- 1.---- 2..--- 3...-- 4....- 5..... 6-.... 7--... 8---.. 9----.",
	Data," ")
	Delay = "\015"
	S["."] = "\07" Delay
	S["-"] = "\07\07\07" Delay Delay
	Char = Delay Delay
	Word = Char Char Char
	for (i in Data) {
		Letter = substr(Data[i],1,1)
		Morse = substr(Data[i],2)
		len = length(Morse);
		for (j = 1; j <= len; j++)
			L[Letter] = L[Letter] S[substr(Morse,j,1)]
	}
	L[" "] = Word
	L["\t"] = Word
}

{
	# translate entire line before outputting to minimize effects of
	# load on timing
	Line = ""
	len = length($0);
	for (i = 1; i <= len; i++)
		Line = Line L[substr($0,i,1)] Char
	Line = Line Word
	printf("%s",Line);
}

END {
	printf L["E"]
}
'

stty $ttymode < /dev/tty