| # DAH should be three DOTs. | 
 | # Space between DOTs and DAHs should be one DOT. | 
 | # Space between two letters should be one DAH. | 
 | # Space between two words should be DOT DAH DAH. | 
 |  | 
 | import sys, math, audiodev | 
 |  | 
 | DOT = 30 | 
 | DAH = 3 * DOT | 
 | OCTAVE = 2				# 1 == 441 Hz, 2 == 882 Hz, ... | 
 |  | 
 | morsetab = { | 
 | 	'A': '.-',		'a': '.-', | 
 | 	'B': '-...',		'b': '-...', | 
 | 	'C': '-.-.',		'c': '-.-.', | 
 | 	'D': '-..',		'd': '-..', | 
 | 	'E': '.',		'e': '.', | 
 | 	'F': '..-.',		'f': '..-.', | 
 | 	'G': '--.',		'g': '--.', | 
 | 	'H': '....',		'h': '....', | 
 | 	'I': '..',		'i': '..', | 
 | 	'J': '.---',		'j': '.---', | 
 | 	'K': '-.-',		'k': '-.-', | 
 | 	'L': '.-..',		'l': '.-..', | 
 | 	'M': '--',		'm': '--', | 
 | 	'N': '-.',		'n': '-.', | 
 | 	'O': '---',		'o': '---', | 
 | 	'P': '.--.',		'p': '.--.', | 
 | 	'Q': '--.-',		'q': '--.-', | 
 | 	'R': '.-.',		'r': '.-.', | 
 | 	'S': '...',		's': '...', | 
 | 	'T': '-',		't': '-', | 
 | 	'U': '..-',		'u': '..-', | 
 | 	'V': '...-',		'v': '...-', | 
 | 	'W': '.--',		'w': '.--', | 
 | 	'X': '-..-',		'x': '-..-', | 
 | 	'Y': '-.--',		'y': '-.--', | 
 | 	'Z': '--..',		'z': '--..', | 
 | 	'0': '-----', | 
 | 	'1': '.----', | 
 | 	'2': '..---', | 
 | 	'3': '...--', | 
 | 	'4': '....-', | 
 | 	'5': '.....', | 
 | 	'6': '-....', | 
 | 	'7': '--...', | 
 | 	'8': '---..', | 
 | 	'9': '----.', | 
 | 	',': '--..--', | 
 | 	'.': '.-.-.-', | 
 | 	'?': '..--..', | 
 | 	';': '-.-.-.', | 
 | 	':': '---...', | 
 | 	"'": '.----.', | 
 | 	'-': '-....-', | 
 | 	'/': '-..-.', | 
 | 	'(': '-.--.-', | 
 | 	')': '-.--.-', | 
 | 	'_': '..--.-', | 
 | 	' ': ' ' | 
 | } | 
 |  | 
 | # If we play at 44.1 kHz (which we do), then if we produce one sine | 
 | # wave in 100 samples, we get a tone of 441 Hz.  If we produce two | 
 | # sine waves in these 100 samples, we get a tone of 882 Hz.  882 Hz | 
 | # appears to be a nice one for playing morse code. | 
 | def mkwave(octave): | 
 | 	global sinewave, nowave | 
 | 	sinewave = '' | 
 | 	for i in range(100): | 
 | 		val = int(math.sin(math.pi * float(i) * octave / 50.0) * 30000) | 
 | 		sinewave = sinewave + chr((val >> 8) & 255) + chr(val & 255) | 
 | 	nowave = '\0' * 200 | 
 |  | 
 | mkwave(OCTAVE) | 
 |  | 
 | def main(): | 
 | 	import getopt, string | 
 | 	try: | 
 | 		opts, args = getopt.getopt(sys.argv[1:], 'o:p:') | 
 | 	except getopt.error: | 
 | 		sys.stderr.write('Usage ' + sys.argv[0] + | 
 | 				 ' [ -o outfile ] [ args ] ...\n') | 
 | 		sys.exit(1) | 
 | 	dev = None | 
 | 	for o, a in opts: | 
 | 		if o == '-o': | 
 | 			import aifc | 
 | 			dev = aifc.open(a, 'w') | 
 | 			dev.setframerate(44100) | 
 | 			dev.setsampwidth(2) | 
 | 			dev.setnchannels(1) | 
 | 		if o == '-p': | 
 | 			mkwave(string.atoi(a)) | 
 | 	if not dev: | 
 | 		import audiodev | 
 | 		dev = audiodev.AudioDev() | 
 | 		dev.setoutrate(44100) | 
 | 		dev.setsampwidth(2) | 
 | 		dev.setnchannels(1) | 
 | 		dev.close = dev.stop | 
 | 		dev.writeframesraw = dev.writeframes | 
 | 	if args: | 
 | 		line = string.join(args) | 
 | 	else: | 
 | 		line = sys.stdin.readline() | 
 | 	while line: | 
 | 		mline = morse(line) | 
 | 		play(mline, dev) | 
 | 		if hasattr(dev, 'wait'): | 
 | 			dev.wait() | 
 | 		if not args: | 
 | 			line = sys.stdin.readline() | 
 | 		else: | 
 | 			line = '' | 
 | 	dev.close() | 
 |  | 
 | # Convert a string to morse code with \001 between the characters in | 
 | # the string. | 
 | def morse(line): | 
 | 	res = '' | 
 | 	for c in line: | 
 | 		try: | 
 | 			res = res + morsetab[c] + '\001' | 
 | 		except KeyError: | 
 | 			pass | 
 | 	return res | 
 |  | 
 | # Play a line of morse code. | 
 | def play(line, dev): | 
 | 	for c in line: | 
 | 		if c == '.': | 
 | 			sine(dev, DOT) | 
 | 		elif c == '-': | 
 | 			sine(dev, DAH) | 
 | 		else:			# space | 
 | 			pause(dev, DAH + DOT) | 
 | 		pause(dev, DOT) | 
 |  | 
 | def sine(dev, length): | 
 | 	for i in range(length): | 
 | 		dev.writeframesraw(sinewave) | 
 |  | 
 | def pause(dev, length): | 
 | 	for i in range(length): | 
 | 		dev.writeframesraw(nowave) | 
 |  | 
 | if __name__ == '__main__' or sys.argv[0] == __name__: | 
 | 	main() |