|
1 """Translate text strings to Morse code""" |
|
2 |
|
3 FRAMERATE = 22050 |
|
4 SAMPWIDTH = 2 |
|
5 |
|
6 BASEFREQ = 441 |
|
7 OCTAVE = 2 |
|
8 |
|
9 DOT = 30 |
|
10 DAH = 80 |
|
11 |
|
12 morsetab = { |
|
13 'a': '.-', |
|
14 'b': '-...', |
|
15 'c': '-.-.', |
|
16 'd': '-..', |
|
17 'e': '.', |
|
18 'f': '..-.', |
|
19 'g': '--.', |
|
20 'h': '....', |
|
21 'i': '..', |
|
22 'j': '.---', |
|
23 'k': '-.-', |
|
24 'l': '.-..', |
|
25 'm': '--', |
|
26 'n': '-.', |
|
27 'o': '---', |
|
28 'p': '.--.', |
|
29 'q': '--.-', |
|
30 'r': '.-.', |
|
31 's': '...', |
|
32 't': '-', |
|
33 'u': '..-', |
|
34 'v': '...-', |
|
35 'w': '.--', |
|
36 'x': '-..-', |
|
37 'y': '-.--', |
|
38 '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 ')': '-.--.-', # XXX same as code for '(' ??? |
|
59 '_': '..--.-', |
|
60 ' ': ' ' |
|
61 } |
|
62 |
|
63 def morsecode(s): |
|
64 from string import lower |
|
65 m = '' |
|
66 for c in s: |
|
67 c = lower(c) |
|
68 if morsetab.has_key(c): |
|
69 c = morsetab[c] + ' ' |
|
70 else: |
|
71 c = '? ' |
|
72 m = m + c |
|
73 return m |
|
74 |
|
75 |
|
76 class BaseMorse: |
|
77 "base class for morse transmissions" |
|
78 |
|
79 def __init__(self): |
|
80 "constructor" |
|
81 self.dots = DOT |
|
82 self.dahs = DAH |
|
83 |
|
84 def noise(self, duration): |
|
85 "beep for given duration" |
|
86 pass |
|
87 |
|
88 def pause(self, duration): |
|
89 "pause for given duration" |
|
90 pass |
|
91 |
|
92 def dot(self): |
|
93 "short beep" |
|
94 self.noise(self.dots) |
|
95 |
|
96 def dah(self): |
|
97 "long beep" |
|
98 self.noise(self.dahs) |
|
99 |
|
100 def pdot(self): |
|
101 "pause as long as a dot" |
|
102 self.pause(self.dots) |
|
103 |
|
104 def pdah(self): |
|
105 "pause as long as a dah" |
|
106 self.pause(self.dahs) |
|
107 |
|
108 def sendmorse(self, s): |
|
109 for c in s: |
|
110 if c == '.': self.dot() |
|
111 elif c == '-': self.dah() |
|
112 else: self.pdah() |
|
113 self.pdot() |
|
114 |
|
115 def sendascii(self, s): |
|
116 self.sendmorse(morsecode(s)) |
|
117 |
|
118 def send(self, s): |
|
119 self.sendascii(s) |
|
120 |
|
121 |
|
122 import Audio_mac |
|
123 class MyAudio(Audio_mac.Play_Audio_mac): |
|
124 def _callback(self, *args): |
|
125 if hasattr(self, 'usercallback'): self.usercallback() |
|
126 apply(Audio_mac.Play_Audio_mac._callback, (self,) + args) |
|
127 |
|
128 |
|
129 class MacMorse(BaseMorse): |
|
130 "Mac specific class to play Morse code" |
|
131 |
|
132 def __init__(self): |
|
133 BaseMorse.__init__(self) |
|
134 self.dev = MyAudio() |
|
135 self.dev.setoutrate(FRAMERATE) |
|
136 self.dev.setsampwidth(SAMPWIDTH) |
|
137 self.dev.setnchannels(1) |
|
138 self.dev.usercallback = self.usercallback |
|
139 sinewave = '' |
|
140 n = int(FRAMERATE / BASEFREQ) |
|
141 octave = OCTAVE |
|
142 from math import sin, pi |
|
143 for i in range(n): |
|
144 val = int(sin(2 * pi * i * octave / n) * 0x7fff) |
|
145 sample = chr((val >> 8) & 255) + chr(val & 255) |
|
146 sinewave = sinewave + sample[:SAMPWIDTH] |
|
147 self.sinewave = sinewave |
|
148 self.silence = '\0' * (n*SAMPWIDTH) |
|
149 self.morsequeue = '' |
|
150 |
|
151 def __del__(self): |
|
152 self.close() |
|
153 |
|
154 def close(self): |
|
155 self.dev = None |
|
156 |
|
157 def pause(self, duration): |
|
158 self.dev.writeframes(self.silence * duration) |
|
159 |
|
160 def noise(self, duration): |
|
161 self.dev.writeframes(self.sinewave * duration) |
|
162 |
|
163 def sendmorse(self, s): |
|
164 self.morsequeue = self.morsequeue + s |
|
165 self.dev.usercallback() |
|
166 self.dev.usercallback() |
|
167 self.dev.usercallback() |
|
168 |
|
169 def usercallback(self): |
|
170 if self.morsequeue: |
|
171 c, self.morsequeue = self.morsequeue[0], self.morsequeue[1:] |
|
172 if c == '.': self.dot() |
|
173 elif c == '-': self.dah() |
|
174 else: self.pdah() |
|
175 self.pdot() |
|
176 |
|
177 |
|
178 def test(): |
|
179 m = MacMorse() |
|
180 while 1: |
|
181 try: |
|
182 line = raw_input('Morse line: ') |
|
183 except (EOFError, KeyboardInterrupt): |
|
184 break |
|
185 m.send(line) |
|
186 while m.morsequeue: pass |
|
187 |
|
188 test() |