annotate service/speechMusic/speechMusic.py @ 215:1e94d074f642

ipv6 support Ignore-this: b6fe9c1fe232302cdd1b6469cbc8ac24
author drewp@bigasterisk.com
date Sun, 03 Jan 2016 02:27:37 -0800
parents 1132ab1ade80
children b3959142d7d8
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
4
be855a111619 move a bunch of services into this tree, give them all web status pages
drewp@bigasterisk.com
parents:
diff changeset
1 #!bin/python
75
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
2 """
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
3 play sounds according to POST requests.
4
be855a111619 move a bunch of services into this tree, give them all web status pages
drewp@bigasterisk.com
parents:
diff changeset
4 """
75
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
5 from __future__ import division
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
6 import sys, tempfile, logging, pyjade
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
7 from pyjade.ext.mako import preprocessor as mako_preprocessor
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
8 from mako.template import Template
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
9 from mako.lookup import TemplateLookup
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
10 sys.path.append("python-openal")
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
11 import openal
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
12 from twisted.internet import reactor
4
be855a111619 move a bunch of services into this tree, give them all web status pages
drewp@bigasterisk.com
parents:
diff changeset
13 sys.path.append("/my/proj/csigen")
be855a111619 move a bunch of services into this tree, give them all web status pages
drewp@bigasterisk.com
parents:
diff changeset
14 from generator import tts
be855a111619 move a bunch of services into this tree, give them all web status pages
drewp@bigasterisk.com
parents:
diff changeset
15 import xml.etree.ElementTree as ET
75
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
16 from klein import Klein
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
17 from twisted.web.static import File
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
18 logging.basicConfig(level=logging.INFO,
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
19 format="%(created)f %(asctime)s %(levelname)s %(message)s")
4
be855a111619 move a bunch of services into this tree, give them all web status pages
drewp@bigasterisk.com
parents:
diff changeset
20 log = logging.getLogger()
be855a111619 move a bunch of services into this tree, give them all web status pages
drewp@bigasterisk.com
parents:
diff changeset
21
75
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
22 templates = TemplateLookup(directories=['.'],
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
23 preprocessor=mako_preprocessor,
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
24 filesystem_checks=True)
4
be855a111619 move a bunch of services into this tree, give them all web status pages
drewp@bigasterisk.com
parents:
diff changeset
25
75
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
26 def makeSpeech(speech, fast=False):
4
be855a111619 move a bunch of services into this tree, give them all web status pages
drewp@bigasterisk.com
parents:
diff changeset
27 speechWav = tempfile.NamedTemporaryFile(suffix='.wav')
be855a111619 move a bunch of services into this tree, give them all web status pages
drewp@bigasterisk.com
parents:
diff changeset
28
be855a111619 move a bunch of services into this tree, give them all web status pages
drewp@bigasterisk.com
parents:
diff changeset
29 root = ET.Element("SABLE")
be855a111619 move a bunch of services into this tree, give them all web status pages
drewp@bigasterisk.com
parents:
diff changeset
30 r = ET.SubElement(root, "RATE",
be855a111619 move a bunch of services into this tree, give them all web status pages
drewp@bigasterisk.com
parents:
diff changeset
31 attrib=dict(SPEED="+50%" if fast else "+0%"))
be855a111619 move a bunch of services into this tree, give them all web status pages
drewp@bigasterisk.com
parents:
diff changeset
32 for sentence in speech.split('.'):
be855a111619 move a bunch of services into this tree, give them all web status pages
drewp@bigasterisk.com
parents:
diff changeset
33 div = ET.SubElement(r, "DIV")
be855a111619 move a bunch of services into this tree, give them all web status pages
drewp@bigasterisk.com
parents:
diff changeset
34 div.set("TYPE", "sentence")
be855a111619 move a bunch of services into this tree, give them all web status pages
drewp@bigasterisk.com
parents:
diff changeset
35 div.text = sentence
be855a111619 move a bunch of services into this tree, give them all web status pages
drewp@bigasterisk.com
parents:
diff changeset
36
75
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
37 speechSecs = tts(root, speechWav.name)
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
38 return openal.Buffer(speechWav.name), speechSecs
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
39
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
40 class SoundEffects(object):
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
41 def __init__(self):
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
42 # for names to pass to this, see alcGetString with ALC_ALL_DEVICES_SPECIFIER
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
43 device = openal.Device()
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
44 self.contextlistener = device.ContextListener()
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
45
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
46 # also '/my/music/entrance/%s.wav' then speak "Neew %s. %s" % (sensorWords[data['sensor']], data['name']),
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
47
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
48 print "loading"
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
49 self.buffers = {
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
50 'leave': openal.Buffer('/my/music/entrance/leave.wav'),
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
51 'highlight' : openal.Buffer('/my/music/snd/Oxygen/KDE-Im-Highlight-Msg-44100.wav'),
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
52 'question' : openal.Buffer('/my/music/snd/angel_ogg/angel_question.wav'),
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
53 'jazztrumpet': openal.Buffer('/my/music/snd/sampleswap/MELODIC SAMPLES and LOOPS/Acid Jazz Trumpet Lines/acid-jazz-trumpet-11.wav'),
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
54 'beep1': openal.Buffer('/my/music/snd/bxfr/beep1.wav'),
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
55 'beep2': openal.Buffer('/my/music/snd/bxfr/beep2.wav'),
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
56 }
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
57 print "loaded sounds"
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
58 self.playingSources = []
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
59 self.queued = []
4
be855a111619 move a bunch of services into this tree, give them all web status pages
drewp@bigasterisk.com
parents:
diff changeset
60
75
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
61 def playEffect(self, name):
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
62 return self.playBuffer(self.buffers[name])
4
be855a111619 move a bunch of services into this tree, give them all web status pages
drewp@bigasterisk.com
parents:
diff changeset
63
75
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
64 def playSpeech(self, txt, preEffect=None, postEffect=None, preEffectOverlap=0):
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
65 buf, secs = makeSpeech(txt)
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
66 t = 0
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
67 if preEffect:
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
68 t += self.playEffect(preEffect)
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
69 t -= preEffectOverlap
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
70
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
71 reactor.callLater(t, self.playBuffer, buf)
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
72 t += secs
4
be855a111619 move a bunch of services into this tree, give them all web status pages
drewp@bigasterisk.com
parents:
diff changeset
73
75
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
74 if postEffect:
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
75 self.playBufferLater(t, self.buffers[postEffect])
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
76
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
77 def playBufferLater(self, t, buf):
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
78 self.queued.append(reactor.callLater(t, self.playBuffer, buf))
8
5ed239235b69 speechMusic: don't fail on missing 'name' attr
drewp@bigasterisk.com
parents: 4
diff changeset
79
75
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
80 def playBuffer(self, buf):
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
81 src = self.contextlistener.get_source()
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
82 src.buffer = buf
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
83 src.play()
4
be855a111619 move a bunch of services into this tree, give them all web status pages
drewp@bigasterisk.com
parents:
diff changeset
84
75
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
85 secs = buf.size / (buf.frequency * buf.channels * buf.bits / 8)
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
86 self.playingSources.append(src)
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
87 reactor.callLater(secs + .1, self.done, src)
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
88 return secs
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
89
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
90 def done(self, src):
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
91 try:
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
92 self.playingSources.remove(src)
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
93 except ValueError:
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
94 pass
4
be855a111619 move a bunch of services into this tree, give them all web status pages
drewp@bigasterisk.com
parents:
diff changeset
95
75
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
96 def stopAll(self):
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
97 while self.playingSources:
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
98 self.playingSources.pop().stop()
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
99 for q in self.queued:
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
100 q.cancel()
4
be855a111619 move a bunch of services into this tree, give them all web status pages
drewp@bigasterisk.com
parents:
diff changeset
101
75
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
102 class Server(object):
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
103 app = Klein()
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
104 def __init__(self, sfx):
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
105 self.sfx = sfx
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
106
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
107 @app.route('/static/', branch=True)
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
108 def static(self, request):
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
109 return File("./static")
4
be855a111619 move a bunch of services into this tree, give them all web status pages
drewp@bigasterisk.com
parents:
diff changeset
110
75
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
111 @app.route('/', methods=['GET'])
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
112 def index(self, request):
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
113 t = templates.get_template("index.jade")
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
114 return t.render(effectNames=[
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
115 dict(name=k, postUri='effects/%s' % k)
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
116 for k in self.sfx.buffers.keys()])
4
be855a111619 move a bunch of services into this tree, give them all web status pages
drewp@bigasterisk.com
parents:
diff changeset
117
75
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
118 @app.route('/speak', methods=['POST'])
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
119 def speak(self, request):
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
120 self.sfx.playSpeech(request.args['msg'][0])
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
121 return "ok"
4
be855a111619 move a bunch of services into this tree, give them all web status pages
drewp@bigasterisk.com
parents:
diff changeset
122
75
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
123 @app.route('/effects/<string:name>', methods=['POST'])
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
124 def effect(self, request, name):
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
125 self.sfx.playEffect(name)
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
126 return "ok"
4
be855a111619 move a bunch of services into this tree, give them all web status pages
drewp@bigasterisk.com
parents:
diff changeset
127
75
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
128 @app.route('/stopAll', methods=['POST'])
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
129 def stopAll(self, request):
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
130 self.sfx.stopAll()
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
131 return "ok"
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
132
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
133 sfx = SoundEffects()
4
be855a111619 move a bunch of services into this tree, give them all web status pages
drewp@bigasterisk.com
parents:
diff changeset
134
75
1132ab1ade80 big rewrite of speechMusic to use klein and openal
drewp@bigasterisk.com
parents: 36
diff changeset
135 server = Server(sfx)
215
1e94d074f642 ipv6 support
drewp@bigasterisk.com
parents: 75
diff changeset
136 server.app.run("::", 9049)