Home | History | Annotate | Download | only in sound
      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()
    189