|
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() |