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