Skip to content

Commit bb5077c

Browse files
committed
add pyttsx and return wav
1 parent abee2e8 commit bb5077c

File tree

4 files changed

+50
-4
lines changed

4 files changed

+50
-4
lines changed

Dockerfile

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
# single application.
33
FROM google/appengine-python27
44

5-
RUN apt-get update && apt-get install -y fortunes
5+
RUN apt-get update && apt-get install -y fortunes libespeak-dev
66
ADD requirements.txt /home/vmagent/app/
77
RUN pip install -r requirements.txt
88

main.py

+11-3
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,24 @@
11
from flask import Flask, helpers
22
import subprocess
3+
import tempfile
34

4-
app = Flask(__name__)
5+
from synth import Synth
6+
7+
app= Flask(__name__)
8+
app.debug = True
9+
10+
synth = Synth()
511

612
MESSAGES = '/tmp/messages.txt'
713

814
@app.route("/")
915
def fortune():
1016
msg = subprocess.check_output('/usr/games/fortune')
1117
with open(MESSAGES, 'a') as f: f.write(msg)
12-
return msg
18+
with tempfile.NamedTemporaryFile() as f:
19+
synth.say(msg, out=f)
20+
return helpers.send_file(f.name, mimetype="audio/wav", as_attachment=False)
1321

1422
@app.route("/messages")
1523
def messages():
16-
return helpers.send_file(MESSAGES)
24+
return helpers.send_file(MESSAGES)

requirements.txt

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Flask==0.10.1
2+
pyttsx==1.1

synth.py

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
from pyttsx.drivers import _espeak
2+
import ctypes
3+
import wave
4+
import time
5+
import threading
6+
import StringIO
7+
8+
class Synth(object):
9+
_done = False
10+
def __init__(self):
11+
self.rate = _espeak.Initialize(_espeak.AUDIO_OUTPUT_RETRIEVAL, 1000)
12+
assert self.rate != -1, 'could not initialize espeak'
13+
_espeak.SetSynthCallback(self)
14+
self.lock = threading.Lock()
15+
16+
def __call__(self, wav, numsamples, events):
17+
if self._done:
18+
return 0
19+
data = ctypes.string_at(wav, numsamples*2)
20+
if len(data) == 0:
21+
self._done = True
22+
return 0
23+
self.wav.writeframes(data)
24+
return 0
25+
26+
def say(self, say, out):
27+
with self.lock:
28+
self.wav = wave.open(out, 'w')
29+
self.wav.setnchannels(1)
30+
self.wav.setsampwidth(2)
31+
self.wav.setframerate(self.rate)
32+
self._done = False
33+
_espeak.Synth(say)
34+
while not self._done:
35+
time.sleep(0)
36+
self.wav.close()

0 commit comments

Comments
 (0)