You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

208 lines
5.0 KiB
Python

#!/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(0.5)
print('Google Home is done')
# 05 CONTROL THE LED OF THE SPEAKERS
import serial
from pixel_ring import pixel_ring
def led_on(speaker):
if ser:
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 ser:
if speaker == 'mono3':
ser.write(b'4')
if speaker == 'mono1':
ser.write(b'2')
if speaker == 'mono2':
pixel_ring.off()
# Play the theatre acts
def play_script(file):
for character, line, direction in read_script(file):
input_text = line
voice = characters.get(character)[0]
speaker = characters.get(character)[1]
action = directions.get(direction[0])
led_on(speaker)
tts(voice, input_text, speaker)
if action == 'listen_google_home':
listen()
if action == 'music':
print('play audioclip')
playing = True
while playing:
call(["aplay", "-D", speaker, "/usr/share/snips/congress.wav"])
playing = False
led_off(speaker)
sleep(0.2) # Add a short pause between the lines
print('The act is done.')