/Demo/scripts/morse.py

http://unladen-swallow.googlecode.com/ · Python · 149 lines · 127 code · 11 blank · 11 comment · 24 complexity · 4c01a8649d3bcb17a39e571a9568b3a6 MD5 · raw file

  1. # 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. import sys, math, audiodev
  6. DOT = 30
  7. DAH = 3 * DOT
  8. OCTAVE = 2 # 1 == 441 Hz, 2 == 882 Hz, ...
  9. morsetab = {
  10. 'A': '.-', 'a': '.-',
  11. 'B': '-...', 'b': '-...',
  12. 'C': '-.-.', 'c': '-.-.',
  13. 'D': '-..', 'd': '-..',
  14. 'E': '.', 'e': '.',
  15. 'F': '..-.', 'f': '..-.',
  16. 'G': '--.', 'g': '--.',
  17. 'H': '....', 'h': '....',
  18. 'I': '..', 'i': '..',
  19. 'J': '.---', 'j': '.---',
  20. 'K': '-.-', 'k': '-.-',
  21. 'L': '.-..', 'l': '.-..',
  22. 'M': '--', 'm': '--',
  23. 'N': '-.', 'n': '-.',
  24. 'O': '---', 'o': '---',
  25. 'P': '.--.', 'p': '.--.',
  26. 'Q': '--.-', 'q': '--.-',
  27. 'R': '.-.', 'r': '.-.',
  28. 'S': '...', 's': '...',
  29. 'T': '-', 't': '-',
  30. 'U': '..-', 'u': '..-',
  31. 'V': '...-', 'v': '...-',
  32. 'W': '.--', 'w': '.--',
  33. 'X': '-..-', 'x': '-..-',
  34. 'Y': '-.--', 'y': '-.--',
  35. 'Z': '--..', 'z': '--..',
  36. '0': '-----',
  37. '1': '.----',
  38. '2': '..---',
  39. '3': '...--',
  40. '4': '....-',
  41. '5': '.....',
  42. '6': '-....',
  43. '7': '--...',
  44. '8': '---..',
  45. '9': '----.',
  46. ',': '--..--',
  47. '.': '.-.-.-',
  48. '?': '..--..',
  49. ';': '-.-.-.',
  50. ':': '---...',
  51. "'": '.----.',
  52. '-': '-....-',
  53. '/': '-..-.',
  54. '(': '-.--.-',
  55. ')': '-.--.-',
  56. '_': '..--.-',
  57. ' ': ' '
  58. }
  59. # If we play at 44.1 kHz (which we do), then if we produce one sine
  60. # wave in 100 samples, we get a tone of 441 Hz. If we produce two
  61. # sine waves in these 100 samples, we get a tone of 882 Hz. 882 Hz
  62. # appears to be a nice one for playing morse code.
  63. def mkwave(octave):
  64. global sinewave, nowave
  65. sinewave = ''
  66. for i in range(100):
  67. val = int(math.sin(math.pi * float(i) * octave / 50.0) * 30000)
  68. sinewave = sinewave + chr((val >> 8) & 255) + chr(val & 255)
  69. nowave = '\0' * 200
  70. mkwave(OCTAVE)
  71. def main():
  72. import getopt, string
  73. try:
  74. opts, args = getopt.getopt(sys.argv[1:], 'o:p:')
  75. except getopt.error:
  76. sys.stderr.write('Usage ' + sys.argv[0] +
  77. ' [ -o outfile ] [ args ] ...\n')
  78. sys.exit(1)
  79. dev = None
  80. for o, a in opts:
  81. if o == '-o':
  82. import aifc
  83. dev = aifc.open(a, 'w')
  84. dev.setframerate(44100)
  85. dev.setsampwidth(2)
  86. dev.setnchannels(1)
  87. if o == '-p':
  88. mkwave(string.atoi(a))
  89. if not dev:
  90. import audiodev
  91. dev = audiodev.AudioDev()
  92. dev.setoutrate(44100)
  93. dev.setsampwidth(2)
  94. dev.setnchannels(1)
  95. dev.close = dev.stop
  96. dev.writeframesraw = dev.writeframes
  97. if args:
  98. line = string.join(args)
  99. else:
  100. line = sys.stdin.readline()
  101. while line:
  102. mline = morse(line)
  103. play(mline, dev)
  104. if hasattr(dev, 'wait'):
  105. dev.wait()
  106. if not args:
  107. line = sys.stdin.readline()
  108. else:
  109. line = ''
  110. dev.close()
  111. # Convert a string to morse code with \001 between the characters in
  112. # the string.
  113. def morse(line):
  114. res = ''
  115. for c in line:
  116. try:
  117. res = res + morsetab[c] + '\001'
  118. except KeyError:
  119. pass
  120. return res
  121. # Play a line of morse code.
  122. def play(line, dev):
  123. for c in line:
  124. if c == '.':
  125. sine(dev, DOT)
  126. elif c == '-':
  127. sine(dev, DAH)
  128. else: # space
  129. pause(dev, DAH + DOT)
  130. pause(dev, DOT)
  131. def sine(dev, length):
  132. for i in range(length):
  133. dev.writeframesraw(sinewave)
  134. def pause(dev, length):
  135. for i in range(length):
  136. dev.writeframesraw(nowave)
  137. if __name__ == '__main__' or sys.argv[0] == __name__:
  138. main()