| 1 | # DAH should be three DOTs.
|
|---|
| 2 | # Space between DOTs and DAHs should be one DOT.
|
|---|
| 3 | # Space between two letters should be one DAH.
|
|---|
| 4 | # Space between two words should be DOT DAH DAH.
|
|---|
| 5 |
|
|---|
| 6 | import sys, math, audiodev
|
|---|
| 7 |
|
|---|
| 8 | DOT = 30
|
|---|
| 9 | DAH = 3 * DOT
|
|---|
| 10 | OCTAVE = 2 # 1 == 441 Hz, 2 == 882 Hz, ...
|
|---|
| 11 |
|
|---|
| 12 | morsetab = {
|
|---|
| 13 | 'A': '.-', 'a': '.-',
|
|---|
| 14 | 'B': '-...', 'b': '-...',
|
|---|
| 15 | 'C': '-.-.', 'c': '-.-.',
|
|---|
| 16 | 'D': '-..', 'd': '-..',
|
|---|
| 17 | 'E': '.', 'e': '.',
|
|---|
| 18 | 'F': '..-.', 'f': '..-.',
|
|---|
| 19 | 'G': '--.', 'g': '--.',
|
|---|
| 20 | 'H': '....', 'h': '....',
|
|---|
| 21 | 'I': '..', 'i': '..',
|
|---|
| 22 | 'J': '.---', 'j': '.---',
|
|---|
| 23 | 'K': '-.-', 'k': '-.-',
|
|---|
| 24 | 'L': '.-..', 'l': '.-..',
|
|---|
| 25 | 'M': '--', 'm': '--',
|
|---|
| 26 | 'N': '-.', 'n': '-.',
|
|---|
| 27 | 'O': '---', 'o': '---',
|
|---|
| 28 | 'P': '.--.', 'p': '.--.',
|
|---|
| 29 | 'Q': '--.-', 'q': '--.-',
|
|---|
| 30 | 'R': '.-.', 'r': '.-.',
|
|---|
| 31 | 'S': '...', 's': '...',
|
|---|
| 32 | 'T': '-', 't': '-',
|
|---|
| 33 | 'U': '..-', 'u': '..-',
|
|---|
| 34 | 'V': '...-', 'v': '...-',
|
|---|
| 35 | 'W': '.--', 'w': '.--',
|
|---|
| 36 | 'X': '-..-', 'x': '-..-',
|
|---|
| 37 | 'Y': '-.--', 'y': '-.--',
|
|---|
| 38 | 'Z': '--..', 'z': '--..',
|
|---|
| 39 | '0': '-----',
|
|---|
| 40 | '1': '.----',
|
|---|
| 41 | '2': '..---',
|
|---|
| 42 | '3': '...--',
|
|---|
| 43 | '4': '....-',
|
|---|
| 44 | '5': '.....',
|
|---|
| 45 | '6': '-....',
|
|---|
| 46 | '7': '--...',
|
|---|
| 47 | '8': '---..',
|
|---|
| 48 | '9': '----.',
|
|---|
| 49 | ',': '--..--',
|
|---|
| 50 | '.': '.-.-.-',
|
|---|
| 51 | '?': '..--..',
|
|---|
| 52 | ';': '-.-.-.',
|
|---|
| 53 | ':': '---...',
|
|---|
| 54 | "'": '.----.',
|
|---|
| 55 | '-': '-....-',
|
|---|
| 56 | '/': '-..-.',
|
|---|
| 57 | '(': '-.--.-',
|
|---|
| 58 | ')': '-.--.-',
|
|---|
| 59 | '_': '..--.-',
|
|---|
| 60 | ' ': ' '
|
|---|
| 61 | }
|
|---|
| 62 |
|
|---|
| 63 | # If we play at 44.1 kHz (which we do), then if we produce one sine
|
|---|
| 64 | # wave in 100 samples, we get a tone of 441 Hz. If we produce two
|
|---|
| 65 | # sine waves in these 100 samples, we get a tone of 882 Hz. 882 Hz
|
|---|
| 66 | # appears to be a nice one for playing morse code.
|
|---|
| 67 | def mkwave(octave):
|
|---|
| 68 | global sinewave, nowave
|
|---|
| 69 | sinewave = ''
|
|---|
| 70 | for i in range(100):
|
|---|
| 71 | val = int(math.sin(math.pi * float(i) * octave / 50.0) * 30000)
|
|---|
| 72 | sinewave = sinewave + chr((val >> 8) & 255) + chr(val & 255)
|
|---|
| 73 | nowave = '\0' * 200
|
|---|
| 74 |
|
|---|
| 75 | mkwave(OCTAVE)
|
|---|
| 76 |
|
|---|
| 77 | def main():
|
|---|
| 78 | import getopt, string
|
|---|
| 79 | try:
|
|---|
| 80 | opts, args = getopt.getopt(sys.argv[1:], 'o:p:')
|
|---|
| 81 | except getopt.error:
|
|---|
| 82 | sys.stderr.write('Usage ' + sys.argv[0] +
|
|---|
| 83 | ' [ -o outfile ] [ args ] ...\n')
|
|---|
| 84 | sys.exit(1)
|
|---|
| 85 | dev = None
|
|---|
| 86 | for o, a in opts:
|
|---|
| 87 | if o == '-o':
|
|---|
| 88 | import aifc
|
|---|
| 89 | dev = aifc.open(a, 'w')
|
|---|
| 90 | dev.setframerate(44100)
|
|---|
| 91 | dev.setsampwidth(2)
|
|---|
| 92 | dev.setnchannels(1)
|
|---|
| 93 | if o == '-p':
|
|---|
| 94 | mkwave(string.atoi(a))
|
|---|
| 95 | if not dev:
|
|---|
| 96 | import audiodev
|
|---|
| 97 | dev = audiodev.AudioDev()
|
|---|
| 98 | dev.setoutrate(44100)
|
|---|
| 99 | dev.setsampwidth(2)
|
|---|
| 100 | dev.setnchannels(1)
|
|---|
| 101 | dev.close = dev.stop
|
|---|
| 102 | dev.writeframesraw = dev.writeframes
|
|---|
| 103 | if args:
|
|---|
| 104 | line = string.join(args)
|
|---|
| 105 | else:
|
|---|
| 106 | line = sys.stdin.readline()
|
|---|
| 107 | while line:
|
|---|
| 108 | mline = morse(line)
|
|---|
| 109 | play(mline, dev)
|
|---|
| 110 | if hasattr(dev, 'wait'):
|
|---|
| 111 | dev.wait()
|
|---|
| 112 | if not args:
|
|---|
| 113 | line = sys.stdin.readline()
|
|---|
| 114 | else:
|
|---|
| 115 | line = ''
|
|---|
| 116 | dev.close()
|
|---|
| 117 |
|
|---|
| 118 | # Convert a string to morse code with \001 between the characters in
|
|---|
| 119 | # the string.
|
|---|
| 120 | def morse(line):
|
|---|
| 121 | res = ''
|
|---|
| 122 | for c in line:
|
|---|
| 123 | try:
|
|---|
| 124 | res = res + morsetab[c] + '\001'
|
|---|
| 125 | except KeyError:
|
|---|
| 126 | pass
|
|---|
| 127 | return res
|
|---|
| 128 |
|
|---|
| 129 | # Play a line of morse code.
|
|---|
| 130 | def play(line, dev):
|
|---|
| 131 | for c in line:
|
|---|
| 132 | if c == '.':
|
|---|
| 133 | sine(dev, DOT)
|
|---|
| 134 | elif c == '-':
|
|---|
| 135 | sine(dev, DAH)
|
|---|
| 136 | else: # space
|
|---|
| 137 | pause(dev, DAH + DOT)
|
|---|
| 138 | pause(dev, DOT)
|
|---|
| 139 |
|
|---|
| 140 | def sine(dev, length):
|
|---|
| 141 | for i in range(length):
|
|---|
| 142 | dev.writeframesraw(sinewave)
|
|---|
| 143 |
|
|---|
| 144 | def pause(dev, length):
|
|---|
| 145 | for i in range(length):
|
|---|
| 146 | dev.writeframesraw(nowave)
|
|---|
| 147 |
|
|---|
| 148 | if __name__ == '__main__' or sys.argv[0] == __name__:
|
|---|
| 149 | main()
|
|---|