Mercurial > code > home > repos > homeauto
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 |
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 | 136 server.app.run("::", 9049) |