|
|
|
#!/usr/bin/env python3
|
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
|
|
|
|
|
|
|
|
# logic.py
|
|
|
|
# This script contains the logic to turn the play_script into instructions for the hardware
|
|
|
|
# ---
|
|
|
|
|
|
|
|
# 01 FUNCTION TO SELECT RANDOM ACT IN DIRECTORY
|
|
|
|
import random
|
|
|
|
import os
|
|
|
|
|
|
|
|
def select_script(path):
|
|
|
|
# Returns a random filename, chosen among the files of the given path.
|
|
|
|
files = os.listdir(path)
|
|
|
|
index = random.randrange(0, len(files))
|
|
|
|
selected_file = path + files[index]
|
|
|
|
return selected_file
|
|
|
|
|
|
|
|
# 02 FUNTION TO PROCESS THEATRE SCRIPT
|
|
|
|
import re
|
|
|
|
from config import characters, directions
|
|
|
|
|
|
|
|
|
|
|
|
def read_script(filename):
|
|
|
|
lines = []
|
|
|
|
|
|
|
|
with open(filename, 'r') as f:
|
|
|
|
for line in f.readlines():
|
|
|
|
#print(line)
|
|
|
|
parts = re.match(r'(?P<character>^.+?){1}:\s?(?P<text>[^\n\r\[\]]*)\s?(\[(?P<stage_directions>[^]]+)\])?', line)
|
|
|
|
parts_character = parts.group('character')
|
|
|
|
parts_text = parts.group('text')
|
|
|
|
parts_directions = str(parts.group('stage_directions')).split(".")
|
|
|
|
|
|
|
|
lines.append((parts_character,parts_text,parts_directions))
|
|
|
|
|
|
|
|
#print(lines)
|
|
|
|
return lines;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# 03 FUNCTION TO SYNTHESIZE TEXT
|
|
|
|
# based on https://github.com/marytts/marytts-txt2wav/tree/python
|
|
|
|
|
|
|
|
# To play wave files
|
|
|
|
from subprocess import call
|
|
|
|
from time import sleep
|
|
|
|
|
|
|
|
# Mary server informations
|
|
|
|
mary_host = "localhost"
|
|
|
|
mary_port = "59125"
|
|
|
|
|
|
|
|
# HTTP + URL packages
|
|
|
|
import httplib2
|
|
|
|
import os
|
|
|
|
from urllib.parse import urlencode, quote # For URL creation
|
|
|
|
|
|
|
|
def tts(voice, input_text, speaker):
|
|
|
|
|
|
|
|
if speaker =="mono1":
|
|
|
|
volume_level = "amount:1.0"
|
|
|
|
|
|
|
|
if speaker == "mono2":
|
|
|
|
volume_level = "amount:0.7"
|
|
|
|
|
|
|
|
if speaker == "mono3":
|
|
|
|
volume_level = "amount:0.8"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Build the query
|
|
|
|
query_hash = {"INPUT_TEXT": input_text,
|
|
|
|
"INPUT_TYPE":"TEXT", # Input text
|
|
|
|
"LOCALE":"en_GB",
|
|
|
|
"effect_VOLUME_selected":"on",
|
|
|
|
"effect_VOLUME_parameters":volume_level,
|
|
|
|
"VOICE": voice, # Voice informations (need to be compatible)
|
|
|
|
"OUTPUT_TYPE":"AUDIO",
|
|
|
|
"AUDIO":"WAVE", # Audio informations (need both)
|
|
|
|
}
|
|
|
|
query = urlencode(query_hash)
|
|
|
|
print("query = \"http://%s:%s/process?%s\"" % (mary_host, mary_port, query))
|
|
|
|
|
|
|
|
# Run the query to mary http server
|
|
|
|
h_mary = httplib2.Http()
|
|
|
|
resp, content = h_mary.request("http://%s:%s/process?" % (mary_host, mary_port), "POST", query)
|
|
|
|
|
|
|
|
# Decode the wav file or raise an exception if no wav files
|
|
|
|
if (resp["content-type"] == "audio/x-wav"):
|
|
|
|
|
|
|
|
# Write the wav file
|
|
|
|
fpath = os.path.join(os.path.dirname(__file__), '/tmp/output_wav.wav')
|
|
|
|
f = open(fpath, "wb")
|
|
|
|
f.write(content)
|
|
|
|
f.close()
|
|
|
|
|
|
|
|
call(["aplay", "-D", speaker, "/tmp/output_wav.wav"])
|
|
|
|
#call(["aplay", "/tmp/output_wav.wav"])
|
|
|
|
|
|
|
|
|
|
|
|
else:
|
|
|
|
raise Exception(content)
|
|
|
|
|
|
|
|
# 04 Listen to Google Home
|
|
|
|
from tuning import Tuning
|
|
|
|
import usb.core
|
|
|
|
import usb.util
|
|
|
|
import time
|
|
|
|
|
|
|
|
def listen():
|
|
|
|
dev = usb.core.find(idVendor=0x2886, idProduct=0x0018)
|
|
|
|
|
|
|
|
if dev:
|
|
|
|
Mic_tuning = Tuning(dev)
|
|
|
|
VAD = Mic_tuning.is_voice()
|
|
|
|
counter=0
|
|
|
|
|
|
|
|
time.sleep(2)
|
|
|
|
|
|
|
|
voice_detected = 1
|
|
|
|
|
|
|
|
|
|
|
|
while voice_detected == 1:
|
|
|
|
print('Google Home is Speaking')
|
|
|
|
time.sleep(4)
|
|
|
|
print(VAD)
|
|
|
|
|
|
|
|
VAD = Mic_tuning.is_voice()
|
|
|
|
|
|
|
|
if VAD == 1:
|
|
|
|
counter = 0
|
|
|
|
print('still speaking')
|
|
|
|
|
|
|
|
if VAD == 0:
|
|
|
|
counter+=1
|
|
|
|
print('silence detected')
|
|
|
|
|
|
|
|
if counter == 2:
|
|
|
|
print('no voice detected')
|
|
|
|
voice_detected = 0
|
|
|
|
|
|
|
|
time.sleep(1)
|
|
|
|
|
|
|
|
|
|
|
|
print('Google Home is done')
|
|
|
|
|
|
|
|
# 05 CONTROL THE LED OF THE SPEAKERS
|
|
|
|
import serial
|
|
|
|
from pixel_ring import pixel_ring
|
|
|
|
ser = serial.Serial('/dev/ttyACM0', 1000000) # Establish the connection on a specific port
|
|
|
|
|
|
|
|
def led_on(speaker):
|
|
|
|
|
|
|
|
if speaker == 'mono3':
|
|
|
|
ser.write(b'3')
|
|
|
|
|
|
|
|
if speaker == 'mono1':
|
|
|
|
ser.write(b'1')
|
|
|
|
|
|
|
|
if speaker == 'mono2':
|
|
|
|
pixel_ring.speak()
|
|
|
|
|
|
|
|
def led_off(speaker):
|
|
|
|
|
|
|
|
if speaker == 'mono3':
|
|
|
|
ser.write(b'4')
|
|
|
|
|
|
|
|
if speaker == 'mono1':
|
|
|
|
ser.write(b'2')
|
|
|
|
|
|
|
|
if speaker == 'mono2':
|
|
|
|
pixel_ring.off()
|
|
|
|
|