1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
|
#!/usr/bin/python
"""
play a rtttl file by sending the tone lengths to the arduino
"""
from __future__ import division
import re
import serial
import struct
import sys
import time
BAUDRATE = 9600
PAUSE = .001
_rtttl_re = re.compile('([0-9]+)?([a-hp]#?)(\.?)([0-9]?)(?:(?:,[ \n]*|$))')
_rtttl_prefix_re = re.compile('d=([0-9]+),o=([1-5]),b=([0-9]+)')
freqs = {
'a': 440.000,
'a#': 466.164,
'b': 493.883,
'h': 493.883,
'c': 523.251,
'c#': 554.365,
'd': 587.330,
'd#': 622.254,
'e': 659.255,
'f': 698.456,
'f#': 739.989,
'g': 783.991,
'g#': 830.609,
'p': 0,
}
def parse(s):
name, prefix, music = s.split(':')
pm = _rtttl_prefix_re.match(prefix)
d, o, b = pm.groups()
defaultlength = int(d)
octave = int(o)
timefactor = int(b)/60
for m in _rtttl_re.finditer(music):
l, t, ld, o = m.groups()
if l:
length = 1/int(l)
else:
length = 1/defaultlength
if ld:
length = length * 1.5
length = length*timefactor
tone = freqs[t.lower()]
if o:
octave = o
tone = tone * 2**(int(octave) - 4)
yield (length, tone)
def send(sounds, device):
with serial.Serial(device, BAUDRATE) as ser:
for length, freq in sounds:
sys.stderr.write('len: %.3f, ton: %9.3f, send: %d' % (length, freq, freq2t(freq)))
ser.write(struct.pack('>H', freq2t(freq)))
time.sleep(length)
sys.stderr.write('\n')
ser.write('\0\0')
time.sleep(PAUSE)
ser.write('\0\0')
def freq2t(freq):
if freq == 0:
return 0
return 2000000/freq
if __name__ == '__main__':
if len(sys.argv) > 1:
if sys.argv[1] == '-d':
for length, freq in parse(sys.stdin.read()):
print 'len: %.3f, ton: %9.3f' % (length, freq)
else:
send(parse(sys.stdin.read()), sys.argv[1])
else:
print >>sys.stderr, "Usage: %s -d|/dev/ttyUSBx" % sys.argv[0]
|