Mercurial > code > home > repos > homeauto
view service/speechMusic/speechMusic.py @ 1164:1fe67fedf5ac
move speech_music into docker and into pygame
Ignore-this: 15260aecbf7fddb75e641b7a853b0281
darcs-hash:de903a34368d5a71f8b0712de3885e2d91c4df5d
author | drewp <drewp@bigasterisk.com> |
---|---|
date | Sun, 09 Sep 2018 04:00:09 -0700 |
parents | 5a5badf59503 |
children | 9fd92202c886 |
line wrap: on
line source
#!bin/python """ play sounds according to POST requests. """ from __future__ import division import sys, tempfile from pyjade.ext.mako import preprocessor as mako_preprocessor from mako.lookup import TemplateLookup from twisted.internet import reactor sys.path.append("/opt") from generator import tts import xml.etree.ElementTree as ET from klein import Klein from twisted.web.static import File from logsetup import log import pygame.mixer templates = TemplateLookup(directories=['.'], preprocessor=mako_preprocessor, filesystem_checks=True) def makeSpeech(speech, fast=False): speechWav = tempfile.NamedTemporaryFile(suffix='.wav') root = ET.Element("SABLE") r = ET.SubElement(root, "RATE", attrib=dict(SPEED="+50%" if fast else "+0%")) for sentence in speech.split('.'): div = ET.SubElement(r, "DIV") div.set("TYPE", "sentence") div.text = sentence speechSecs = tts(root, speechWav.name) return pygame.mixer.Sound(speechWav.name), speechSecs class SoundEffects(object): def __init__(self): # also '/my/music/entrance/%s.wav' then speak "Neew %s. %s" % (sensorWords[data['sensor']], data['name']), log.info("loading") self.buffers = { 'leave': pygame.mixer.Sound('sound/leave.wav'), 'highlight' : pygame.mixer.Sound('sound/KDE-Im-Highlight-Msg-44100.wav'), 'question' : pygame.mixer.Sound('sound/angel_question.wav'), 'jazztrumpet': pygame.mixer.Sound('sound/acid-jazz-trumpet-11.wav'), 'troyandabed': pygame.mixer.Sound('sound/troy_and_abed_in_the_morning.wav'), 'beep1': pygame.mixer.Sound('sound/beep1.wav'), 'beep2': pygame.mixer.Sound('sound/beep2.wav'), } log.info("loaded sounds") self.playingSources = [] self.queued = [] def playEffect(self, name): return self.playBuffer(self.buffers[name]) def playSpeech(self, txt, preEffect=None, postEffect=None, preEffectOverlap=0): buf, secs = makeSpeech(txt) t = 0 if preEffect: t += self.playEffect(preEffect) t -= preEffectOverlap reactor.callLater(t, self.playBuffer, buf) t += secs if postEffect: self.playBufferLater(t, self.buffers[postEffect]) def playBufferLater(self, t, buf): self.queued.append(reactor.callLater(t, self.playBuffer, buf)) def playBuffer(self, buf): buf.play() secs = buf.get_length() self.playingSources.append(buf) reactor.callLater(secs + .1, self.done, buf) return secs def done(self, src): try: self.playingSources.remove(src) except ValueError: pass def stopAll(self): while self.playingSources: self.playingSources.pop().stop() for q in self.queued: q.cancel() class Server(object): app = Klein() def __init__(self, sfx): self.sfx = sfx @app.route('/static/', branch=True) def static(self, request): return File("./static") @app.route('/', methods=['GET']) def index(self, request): t = templates.get_template("index.jade") return t.render(effectNames=[ dict(name=k, postUri='effects/%s' % k) for k in self.sfx.buffers.keys()]) @app.route('/speak', methods=['POST']) def speak(self, request): self.sfx.playSpeech(request.args['msg'][0]) return "ok" @app.route('/effects/<string:name>', methods=['POST']) def effect(self, request, name): self.sfx.playEffect(name) return "ok" @app.route('/stopAll', methods=['POST']) def stopAll(self, request): self.sfx.stopAll() return "ok" pygame.mixer.init() sfx = SoundEffects() server = Server(sfx) server.app.run(endpoint_description=r"tcp6:port=9049:interface=\:\:")