home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 98 / Skunkware 98.iso / osr5 / sco / scripts / cmorse < prev    next >
Encoding:
Text File  |  1997-08-26  |  6.5 KB  |  188 lines

  1. :
  2. # Morse to console-tone translator
  3. # Designed for XENIX console; depends on SYSV tty modes (cr2 and bs1)
  4. # and SCO ANSI set-beep-length escape code
  5. # Stuck at max 12 wpm by shortest console beep (0.1s)
  6. # @(#) cmorse.sh 92/11/10
  7. # 90/11/01 john h. dubois iii (john@armory.com)
  8. # 91/01/27 modified to use &1 instead of /dev/tty for sttys so that
  9. #       output can be redirected;
  10. #       added ability to read text from command line.
  11. # 92/04/12 Added alternate timing for UNIX.
  12. # 92/09/19 Added -<wpm> option; made timing more accurate.
  13. # 92/11/10 Make nonchars into spaces & squeeze multiple spaces.
  14. # 93/12/21 Changed name to 'cmorse'
  15.  
  16. name=$0
  17.  
  18. if [ "$1" = -o ]; then
  19.     shift
  20. else
  21.     case "$TERM" in
  22.     *ansi*) ;;
  23.     *) echo \
  24. "This program only works on terminals that understand
  25. the SCO ANSI set-beep-length escape code."; exit;;
  26.     esac
  27. fi
  28.  
  29. if [ "$1" = -h ]; then
  30.     echo \
  31. "$name: translate ASCII characters to Morse code.
  32. Usage: $name [-ho] [-<wpm>] [word ...]
  33. $name takes its command line arguments, if any, or characters sent to its
  34. standard input, and translates them into Morse code.  The Morse code is
  35. output as beeps.  The bell is set to 1/10 second so that a short beep can
  36. be produced; since it is not possible to determine what the bell was
  37. previously set to, it is not reset when the program is done.  This program
  38. will only work on terminals that understand the SCO ANSI set-beep-length
  39. escape code.
  40. Options:
  41. -h prints this help.
  42. -o overrides the check that ensures that $name is running on some sort of
  43. ANSI-type terminal (though just being an ANSI terminal does not guarantee
  44. that $name will work on it).
  45. -<wpm> sets the transmission rate to approximately <wpm> words per minute.
  46. The default and maximum is approximately 12 words per minute.  The rate is
  47. reduced by lengthening the pause period between characters and words
  48. (Farnsworth method).  The length of the tones used to transmit each character
  49. and the pauses between them are left at what they would be for 12 wpm."
  50.     exit
  51. fi
  52.  
  53. # We use HZ to determine what the beep length will be.
  54. # If HZ not set, set it according to uname.
  55. if [ -z "$HZ" ]; then
  56.     "/bin/uname -r" | getline Sys
  57.     case $Sys in
  58.     2*) HZ=50;;
  59.     *) HZ=100;;    # Wrong for 3.2v0 (should be 60), but not actually used.
  60.     esac
  61. fi
  62.  
  63. # make unit 3 available for commands which have output redirected
  64. exec 3<&1
  65. # save tty mode so it can be reset
  66. ttymode=`stty -g <&3`
  67. # reset tty mode if program aborted by int or quit
  68. trap "stty $ttymode <&1" 2 3
  69. # set cr2 and bs1 so that cr and bs delays can be used for timing
  70. stty cr2 bs1 -onlret -ofill <&1
  71.  
  72. # Nuke some common env vars to make sure there's enough arg space for prog
  73. PATH= CDPATH= TERMCAP= /usr/bin/awk "
  74. BEGIN {
  75.     HZ=$HZ"'
  76.     WPM = 12
  77.     ARGp = 1
  78.     if (ARGC > 1 && ARGV[ARGp] ~ "^-[0-9]+$") {
  79.     WPM = substr(ARGV[ARGp++],2) + 0
  80.     if (!(1 <= WPM && WPM <= 12)) {
  81.         printf "%s: bad WPM value.\n",WPM
  82.         exit
  83.     }
  84.     }
  85.     # ideal: 
  86.     # element pause = dot pause = 1 unit
  87.     # dash pause = interchar pause = 3 units
  88.     # interword pause = 7 units
  89.     # 1 word-length including interchar and interword pause is 50 units (avg.)
  90.     # and contains 5 characters.
  91.     # In non-Farnsworth transmission, there are a total of 14 non-element
  92.     # pause units per word: 2 extra after each char of a 5-char word (1 unit
  93.     # of the 3-unit pause is added for the last element), and 4 extra between
  94.     # words (1 unit of the 7-unit pause is added for the last element, and 2
  95.     # are added for the last char).
  96.     # Therefore, 5/7 (10/14) of the pause units go to chars, and the word
  97.     # pause is twice the char pause.
  98.     # This program runs at 600 units/minute.
  99.     # Cancelled 5/5 (numerator of 5/7 and # of chars/word)
  100.     PauseUnitsPerChar = int((600 - WPM * 36) / (7 * WPM) + 0.5)
  101.     CharPause = PauseUnits(PauseUnitsPerChar)
  102.     WordPause = PauseUnits(PauseUnitsPerChar * 2)
  103.  
  104.     Beep = "\07"
  105.     # ; represents . and _ represents - so they will not be subbed
  106.     A2Morse = "A.- B-... C-.-. D-.. E. F..-. G--. H.... I.. J.--- K-.- L.-.."\
  107. " M-- N-. O--- P.--. Q--.- R.-. S... T- U..- V...- W.-- X-..- Y-.-- Z--.."\
  108. " a.- b-... c-.-. d-.. e. f..-. g--. h.... i.. j.--- k-.- l.-.."\
  109. " m-- n-. o--- p.--. q--.- r.-. s... t- u..- v...- w.-- x-..- y-.-- z--.."\
  110. " ,--..-- ;.-.-.- _-...- =-...- /-..-. ?..--.. $.-.-."\
  111. " 0----- 1.---- 2..--- 3...-- 4....- 5..... 6-.... 7--... 8---.. 9----."
  112.     gsub("\\.",Beep PauseUnits(2),A2Morse)
  113.     gsub("-",Beep Beep Beep PauseUnits(4),A2Morse)
  114.     sub("_","-",A2Morse)
  115.     sub(";",".",A2Morse)
  116.     split(A2Morse,Data," ")
  117.     for (i in Data)
  118.     Symbol2Code[substr(Data[i],1,1)] = substr(Data[i],2)
  119.     Symbol2Code[" "] = WordPause
  120.     # set bell to 1/(1487*840.3ns) Hz (800 Hz), 100 mS duration
  121.     # note: bell is *not* reset at end of script, 
  122.     # since there is no way to tell what it was set to from a script
  123.     printf "\033[=1487;1B"
  124.     if (ARGp < ARGC) {
  125.     Args = ARGV[ARGp++]
  126.     for (; ARGp < ARGC; ARGp++)
  127.         Args = Args " " ARGV[ARGp]
  128.     TranslateLine(Args)
  129.     }
  130.     else {
  131.     # UNIX awk lets you read from "/dev/std...", XENIX awk does not.
  132.     # Neither pays attention to changes to ARGC/ARGV.
  133.     if (Sys ~ "^2")
  134.         while (("cat" | getline) == 1)
  135.         TranslateLine($0)
  136.     else
  137.         while ((getline < "/dev/stdin") == 1)
  138.         TranslateLine($0)
  139.     }
  140.     printf Symbol2Code["$"]
  141. }
  142.  
  143. # Uses globals ExactPause, RPause, and ExactDiv as static vars
  144. # Sets global Sys to system release.
  145. function PauseUnits(Units,  Pause) {
  146.     # cr (015) is supposed to be ~0.10s; it is 0.11s under 3.2v4
  147.     # bs (010) is supposed to be ~0.05s; it is 0.08s under 3.2v4
  148.     # Both are exactly twice as long under XENIX,
  149.     # perhaps due to halved tick rate.
  150.     if (ExactDiv == "") {
  151.     if (HZ == 50) {    # XENIX
  152.         ExactDiv = 6
  153.         RPause[1] = ""
  154.         RPause[2] = "\010"
  155.         RPause[3] = "\015"
  156.         RPause[4] = "\015\010"
  157.         RPause[5] = "\010\010\010"
  158.     }
  159.     else {            # UNIX
  160.         ExactDiv = 3
  161.         RPause[1] = "\010"
  162.         RPause[2] = "\015\010"
  163.     }
  164.     ExactPause = "\015\015\010"
  165.     }
  166.  
  167.     Pause = RPause[Units % ExactDiv]
  168.     
  169.     for (Units = int(Units / ExactDiv); Units; Units--)
  170.     Pause = Pause ExactPause
  171.     return Pause
  172. }
  173.  
  174. function TranslateLine(Line,  Code) {
  175.     # Convert multiple nonchars/spaces into single spaces
  176.     # because there really is no such thing as multiple space in Morse
  177.     gsub("([^-A-Za-z,.=/?$0-9]| )+"," ",Line)
  178.     sub("^ ","",Line) # Get rid of space at the start of a line
  179.     # Translate entire line before output to minimize effect of load on timing
  180.     len = length(Line);
  181.     for (i = 1; i <= len; i++)
  182.     Code = Code Symbol2Code[substr(Line,i,1)] CharPause
  183.     Code = Code WordPause
  184.     printf("%s",Code);
  185. }
  186. ' "$@"
  187. stty "$ttymode" <&1
  188.