blob: 2cea83e4025138e8d29b797811956344184332bb [file] [log] [blame]
Guido van Rossum07c96451994-10-03 16:45:35 +00001# 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
6import sys, math, audiodev
7
8DOT = 30
9DAH = 3 * DOT
10OCTAVE = 2 # 1 == 441 Hz, 2 == 882 Hz, ...
11
12morsetab = {
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.
67def 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
75mkwave(OCTAVE)
76
77def 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.
120def 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.
130def 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
140def sine(dev, length):
141 for i in range(length):
142 dev.writeframesraw(sinewave)
143
144def pause(dev, length):
145 for i in range(length):
146 dev.writeframesraw(nowave)
147
148if __name__ == '__main__' or sys.argv[0] == __name__:
149 main()