blob: 265fae9f941ff506c8f59bc9d8083686d695c462 [file] [log] [blame]
Georg Brandl30fd2bb2009-10-11 08:18:44 +00001#! /usr/bin/env python
2
Guido van Rossum07c96451994-10-03 16:45:35 +00003# DAH should be three DOTs.
4# Space between DOTs and DAHs should be one DOT.
5# Space between two letters should be one DAH.
6# Space between two words should be DOT DAH DAH.
7
8import sys, math, audiodev
9
10DOT = 30
11DAH = 3 * DOT
Tim Peterse6ddc8b2004-07-18 05:56:09 +000012OCTAVE = 2 # 1 == 441 Hz, 2 == 882 Hz, ...
Guido van Rossum07c96451994-10-03 16:45:35 +000013
14morsetab = {
Tim Peterse6ddc8b2004-07-18 05:56:09 +000015 'A': '.-', 'a': '.-',
16 'B': '-...', 'b': '-...',
17 'C': '-.-.', 'c': '-.-.',
18 'D': '-..', 'd': '-..',
19 'E': '.', 'e': '.',
20 'F': '..-.', 'f': '..-.',
21 'G': '--.', 'g': '--.',
22 'H': '....', 'h': '....',
23 'I': '..', 'i': '..',
24 'J': '.---', 'j': '.---',
25 'K': '-.-', 'k': '-.-',
26 'L': '.-..', 'l': '.-..',
27 'M': '--', 'm': '--',
28 'N': '-.', 'n': '-.',
29 'O': '---', 'o': '---',
30 'P': '.--.', 'p': '.--.',
31 'Q': '--.-', 'q': '--.-',
32 'R': '.-.', 'r': '.-.',
33 'S': '...', 's': '...',
34 'T': '-', 't': '-',
35 'U': '..-', 'u': '..-',
36 'V': '...-', 'v': '...-',
37 'W': '.--', 'w': '.--',
38 'X': '-..-', 'x': '-..-',
39 'Y': '-.--', 'y': '-.--',
40 'Z': '--..', 'z': '--..',
Georg Brandl30fd2bb2009-10-11 08:18:44 +000041 '0': '-----', ',': '--..--',
42 '1': '.----', '.': '.-.-.-',
43 '2': '..---', '?': '..--..',
44 '3': '...--', ';': '-.-.-.',
45 '4': '....-', ':': '---...',
46 '5': '.....', "'": '.----.',
47 '6': '-....', '-': '-....-',
48 '7': '--...', '/': '-..-.',
49 '8': '---..', '(': '-.--.-',
50 '9': '----.', ')': '-.--.-',
51 ' ': ' ', '_': '..--.-',
Guido van Rossum07c96451994-10-03 16:45:35 +000052}
53
Georg Brandl30fd2bb2009-10-11 08:18:44 +000054nowave = '\0' * 200
55
Guido van Rossum07c96451994-10-03 16:45:35 +000056# If we play at 44.1 kHz (which we do), then if we produce one sine
57# wave in 100 samples, we get a tone of 441 Hz. If we produce two
58# sine waves in these 100 samples, we get a tone of 882 Hz. 882 Hz
59# appears to be a nice one for playing morse code.
60def mkwave(octave):
Tim Peterse6ddc8b2004-07-18 05:56:09 +000061 sinewave = ''
62 for i in range(100):
Georg Brandl30fd2bb2009-10-11 08:18:44 +000063 val = int(math.sin(math.pi * i * octave / 50.0) * 30000)
Georg Brandl86d38e92009-10-11 08:39:16 +000064 sinewave += chr((val >> 8) & 255) + chr(val & 255)
Georg Brandl30fd2bb2009-10-11 08:18:44 +000065 return sinewave
Guido van Rossum07c96451994-10-03 16:45:35 +000066
Georg Brandl30fd2bb2009-10-11 08:18:44 +000067defaultwave = mkwave(OCTAVE)
Guido van Rossum07c96451994-10-03 16:45:35 +000068
69def main():
Georg Brandl30fd2bb2009-10-11 08:18:44 +000070 import getopt
Tim Peterse6ddc8b2004-07-18 05:56:09 +000071 try:
72 opts, args = getopt.getopt(sys.argv[1:], 'o:p:')
73 except getopt.error:
74 sys.stderr.write('Usage ' + sys.argv[0] +
Georg Brandl30fd2bb2009-10-11 08:18:44 +000075 ' [ -o outfile ] [ -p octave ] [ words ] ...\n')
Tim Peterse6ddc8b2004-07-18 05:56:09 +000076 sys.exit(1)
77 dev = None
Georg Brandl30fd2bb2009-10-11 08:18:44 +000078 wave = defaultwave
Tim Peterse6ddc8b2004-07-18 05:56:09 +000079 for o, a in opts:
80 if o == '-o':
81 import aifc
82 dev = aifc.open(a, 'w')
83 dev.setframerate(44100)
84 dev.setsampwidth(2)
85 dev.setnchannels(1)
86 if o == '-p':
Georg Brandl30fd2bb2009-10-11 08:18:44 +000087 wave = mkwave(int(a))
Tim Peterse6ddc8b2004-07-18 05:56:09 +000088 if not dev:
89 import audiodev
90 dev = audiodev.AudioDev()
91 dev.setoutrate(44100)
92 dev.setsampwidth(2)
93 dev.setnchannels(1)
94 dev.close = dev.stop
95 dev.writeframesraw = dev.writeframes
96 if args:
Georg Brandl30fd2bb2009-10-11 08:18:44 +000097 source = [' '.join(args)]
Tim Peterse6ddc8b2004-07-18 05:56:09 +000098 else:
Georg Brandl30fd2bb2009-10-11 08:18:44 +000099 source = iter(sys.stdin.readline, '')
100 for line in source:
Tim Peterse6ddc8b2004-07-18 05:56:09 +0000101 mline = morse(line)
Georg Brandl30fd2bb2009-10-11 08:18:44 +0000102 play(mline, dev, wave)
Tim Peterse6ddc8b2004-07-18 05:56:09 +0000103 if hasattr(dev, 'wait'):
104 dev.wait()
Tim Peterse6ddc8b2004-07-18 05:56:09 +0000105 dev.close()
Guido van Rossum07c96451994-10-03 16:45:35 +0000106
107# Convert a string to morse code with \001 between the characters in
108# the string.
109def morse(line):
Tim Peterse6ddc8b2004-07-18 05:56:09 +0000110 res = ''
111 for c in line:
112 try:
Georg Brandl30fd2bb2009-10-11 08:18:44 +0000113 res += morsetab[c] + '\001'
Tim Peterse6ddc8b2004-07-18 05:56:09 +0000114 except KeyError:
115 pass
116 return res
Guido van Rossum07c96451994-10-03 16:45:35 +0000117
118# Play a line of morse code.
Georg Brandl30fd2bb2009-10-11 08:18:44 +0000119def play(line, dev, wave):
Tim Peterse6ddc8b2004-07-18 05:56:09 +0000120 for c in line:
121 if c == '.':
Georg Brandl30fd2bb2009-10-11 08:18:44 +0000122 sine(dev, DOT, wave)
Tim Peterse6ddc8b2004-07-18 05:56:09 +0000123 elif c == '-':
Georg Brandl30fd2bb2009-10-11 08:18:44 +0000124 sine(dev, DAH, wave)
Tim Peterse6ddc8b2004-07-18 05:56:09 +0000125 else: # space
126 pause(dev, DAH + DOT)
127 pause(dev, DOT)
Guido van Rossum07c96451994-10-03 16:45:35 +0000128
Georg Brandl30fd2bb2009-10-11 08:18:44 +0000129def sine(dev, length, wave):
Tim Peterse6ddc8b2004-07-18 05:56:09 +0000130 for i in range(length):
Georg Brandl30fd2bb2009-10-11 08:18:44 +0000131 dev.writeframesraw(wave)
Guido van Rossum07c96451994-10-03 16:45:35 +0000132
133def pause(dev, length):
Tim Peterse6ddc8b2004-07-18 05:56:09 +0000134 for i in range(length):
135 dev.writeframesraw(nowave)
Guido van Rossum07c96451994-10-03 16:45:35 +0000136
Georg Brandl30fd2bb2009-10-11 08:18:44 +0000137if __name__ == '__main__':
Tim Peterse6ddc8b2004-07-18 05:56:09 +0000138 main()