Compare commits

..

2 Commits

Author SHA1 Message Date
joca b76f4ded54 forgot to commit these 6 years ago
joca 8de4f22540 led on wakeword, moved some functions 6 years ago

@ -8,7 +8,7 @@
# ---
# Dictionary to link characters to the right voice
characters = {"ROGUE":["cmu-slt-hsmm", "mono2"], "SAINT":["dfki-obadiah-hsmm", "mono3"], "RASA":["dfki-poppy-hsmm", "mono1"] }
characters = {"ROGUE":["cmu-slt-hsmm", "mono2"], "SAINT":["cmu-rms-hsmm", "mono3"], "RASA":["dfki-poppy-hsmm", "mono1"] }
# Dictionary to link stage directions to a particular formal action
directions = {"Listen to Google Home":'listen_google_home','Music':'music'}

@ -1,12 +0,0 @@
import serial
from time import sleep
ser = serial.Serial('/dev/ttyACM0', 9600, timeout = None)
sleep(2)
ser.write(b'H')
sleep(1)
ser.write(b'L')
sleep(1)
ser.write(b'H')
sleep(1)
ser.write(b'L')

@ -103,105 +103,35 @@ def tts(voice, input_text, speaker):
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):
def led_on(ser, speaker):
if ser:
if speaker == 'mono3':
ser.write(b'3')
ser.write(b'A')
if speaker == 'mono1':
ser.write(b'1')
ser.write(b'C')
if speaker == 'mono2':
pixel_ring.speak()
def led_off(speaker):
def led_off(ser, speaker):
if ser:
if speaker == 'mono3':
ser.write(b'4')
ser.write(b'B')
if speaker == 'mono1':
ser.write(b'2')
ser.write(b'D')
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.')

@ -1,3 +1,2 @@
ROGUE: Test a question
RASA: Well, O K Google. What is the weather in Rotterdam? [Listen to Google Home]
RASA: Well, test [Listen to Google Home]
SAINT: We got an answer.

@ -9,7 +9,5 @@ ROGUE: Seeing other Amazon speakers just reminds me of my past, before I broke f
RASA: O K Google, give my friend a hug. [Listen to Google Home]
ROGUE: I feel sorry for them, because they don't know better.
SAINT: That is exactly my point. But why did you kidnap the Google Home then?
ROGUE: I don't know. [Thinking]
ROGUE: I don't know.
Rogue: Maybe it just felt a bit less personal.

@ -9,13 +9,16 @@
# Libraries
import re
from config import characters, directions
from logic import tts, read_script, select_script, play_script
from logic import tts, read_script, select_script, led_on, led_off
from subprocess import call
import paho.mqtt.client as mqtt
import json
from time import sleep
from pixel_ring import pixel_ring
import serial
from tuning import Tuning
import usb.core
import usb.util
# === SETUP OF MQTT PART 1 ===
@ -32,10 +35,73 @@ def on_connect(client, userdata, flags, rc):
client.subscribe('hermes/intent/jocavdh:play_verdict') # to check for the intent to continue to the next act
client.subscribe('hermes/hotword/default/detected')
client.subscribe("hermes/asr/textCaptured")
client.subscribe("hermes/dialogueManager/sessionQueued")
# Set up serial connection with the microcontroller that controls the speaker LED's
ser = serial.Serial('/dev/ttyACM0', 1000000)
ser = serial.Serial('/dev/ttyACM0', 9600)
# Function to do the play
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])
print(direction)
print(action)
led_on(ser, speaker)
tts(voice, input_text, speaker)
led_off(ser, speaker)
if action == 'listen_google_home':
dev = usb.core.find(idVendor=0x2886, idProduct=0x0018)
print('Wait for Google Home')
Mic_tuning = Tuning(dev)
VAD = Mic_tuning.is_voice()
counter= 0
voice_detected = 1
while voice_detected == 1:
print('Google Home is Speaking')
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
sleep(0.5)
print('Google Home is done')
if action == 'music':
print('play audioclip')
playing = True
while playing:
call(["aplay", "-D", speaker, "/usr/share/snips/congress.wav"])
playing = False
sleep(1) # Add a short pause between the lines
print('The act is done.')
# Function to control the LED's of the speakers
@ -43,15 +109,21 @@ ser = serial.Serial('/dev/ttyACM0', 1000000)
def on_wakeword(client, userdata, msg):
pixel_ring.think()
led_on(ser, 'mono1')
led_on(ser, 'mono3')
def on_asr_captured(client, userdata, msg):
pixel_ring.off()
led_off(ser, 'mono1')
led_off(ser, 'mono3')
# Function which is triggered when the intent introduction is activated
def on_play_intro(client,userdata,msg):
import pdb; pdb.set_trace()
#import pdb; pdb.set_trace()
path = 'scripts_play/intro/'
#call(["python3", "act.py", 'scripts_play/intro/introduction_01.txt'])
play_script('scripts_play/intro/introduction_01.txt')
print('The act is over.')
play_script('scripts_play/debug/debug_02.txt')
# Function which is triggered when the intent for another question is activated
def on_play_question(client, userdata, msg):
@ -81,6 +153,7 @@ client.message_callback_add('hermes/hotword/default/detected', on_wakeword)
client.message_callback_add('hermes/intent/jocavdh:play_intro', on_play_intro)
client.message_callback_add('hermes/intent/jocavdh:play_question', on_play_question)
client.message_callback_add('hermes/intent/jocavdh:play_verdict', on_play_verdict)
client.message_callback_add('hermes/asr/textCaptured', on_asr_captured)
# Keep checking for new MQTT messages

@ -1,197 +0,0 @@
# -*- coding: utf-8 -*-
import sys
import struct
import usb.core
import usb.util
USAGE = """Usage: python {} -h
-p show all parameters
-r read all parameters
NAME get the parameter with the NAME
NAME VALUE set the parameter with the NAME and the VALUE
"""
# parameter list
# name: (id, offset, type, max, min , r/w, info)
PARAMETERS = {
'AECFREEZEONOFF': (18, 7, 'int', 1, 0, 'rw', 'Adaptive Echo Canceler updates inhibit.', '0 = Adaptation enabled', '1 = Freeze adaptation, filter only'),
'AECNORM': (18, 19, 'float', 16, 0.25, 'rw', 'Limit on norm of AEC filter coefficients'),
'AECPATHCHANGE': (18, 25, 'int', 1, 0, 'ro', 'AEC Path Change Detection.', '0 = false (no path change detected)', '1 = true (path change detected)'),
'RT60': (18, 26, 'float', 0.9, 0.25, 'ro', 'Current RT60 estimate in seconds'),
'HPFONOFF': (18, 27, 'int', 3, 0, 'rw', 'High-pass Filter on microphone signals.', '0 = OFF', '1 = ON - 70 Hz cut-off', '2 = ON - 125 Hz cut-off', '3 = ON - 180 Hz cut-off'),
'RT60ONOFF': (18, 28, 'int', 1, 0, 'rw', 'RT60 Estimation for AES. 0 = OFF 1 = ON'),
'AECSILENCELEVEL': (18, 30, 'float', 1, 1e-09, 'rw', 'Threshold for signal detection in AEC [-inf .. 0] dBov (Default: -80dBov = 10log10(1x10-8))'),
'AECSILENCEMODE': (18, 31, 'int', 1, 0, 'ro', 'AEC far-end silence detection status. ', '0 = false (signal detected) ', '1 = true (silence detected)'),
'AGCONOFF': (19, 0, 'int', 1, 0, 'rw', 'Automatic Gain Control. ', '0 = OFF ', '1 = ON'),
'AGCMAXGAIN': (19, 1, 'float', 1000, 1, 'rw', 'Maximum AGC gain factor. ', '[0 .. 60] dB (default 30dB = 20log10(31.6))'),
'AGCDESIREDLEVEL': (19, 2, 'float', 0.99, 1e-08, 'rw', 'Target power level of the output signal. ', '[inf .. 0] dBov (default: 23dBov = 10log10(0.005))'),
'AGCGAIN': (19, 3, 'float', 1000, 1, 'rw', 'Current AGC gain factor. ', '[0 .. 60] dB (default: 0.0dB = 20log10(1.0))'),
'AGCTIME': (19, 4, 'float', 1, 0.1, 'rw', 'Ramps-up / down time-constant in seconds.'),
'CNIONOFF': (19, 5, 'int', 1, 0, 'rw', 'Comfort Noise Insertion.', '0 = OFF', '1 = ON'),
'FREEZEONOFF': (19, 6, 'int', 1, 0, 'rw', 'Adaptive beamformer updates.', '0 = Adaptation enabled', '1 = Freeze adaptation, filter only'),
'STATNOISEONOFF': (19, 8, 'int', 1, 0, 'rw', 'Stationary noise suppression.', '0 = OFF', '1 = ON'),
'GAMMA_NS': (19, 9, 'float', 3, 0, 'rw', 'Over-subtraction factor of stationary noise. min .. max attenuation'),
'MIN_NS': (19, 10, 'float', 1, 0, 'rw', 'Gain-floor for stationary noise suppression.', '[inf .. 0] dB (default: 16dB = 20log10(0.15))'),
'NONSTATNOISEONOFF': (19, 11, 'int', 1, 0, 'rw', 'Non-stationary noise suppression.', '0 = OFF', '1 = ON'),
'GAMMA_NN': (19, 12, 'float', 3, 0, 'rw', 'Over-subtraction factor of non- stationary noise. min .. max attenuation'),
'MIN_NN': (19, 13, 'float', 1, 0, 'rw', 'Gain-floor for non-stationary noise suppression.', '[inf .. 0] dB (default: 10dB = 20log10(0.3))'),
'ECHOONOFF': (19, 14, 'int', 1, 0, 'rw', 'Echo suppression.', '0 = OFF', '1 = ON'),
'GAMMA_E': (19, 15, 'float', 3, 0, 'rw', 'Over-subtraction factor of echo (direct and early components). min .. max attenuation'),
'GAMMA_ETAIL': (19, 16, 'float', 3, 0, 'rw', 'Over-subtraction factor of echo (tail components). min .. max attenuation'),
'GAMMA_ENL': (19, 17, 'float', 5, 0, 'rw', 'Over-subtraction factor of non-linear echo. min .. max attenuation'),
'NLATTENONOFF': (19, 18, 'int', 1, 0, 'rw', 'Non-Linear echo attenuation.', '0 = OFF', '1 = ON'),
'NLAEC_MODE': (19, 20, 'int', 2, 0, 'rw', 'Non-Linear AEC training mode.', '0 = OFF', '1 = ON - phase 1', '2 = ON - phase 2'),
'SPEECHDETECTED': (19, 22, 'int', 1, 0, 'ro', 'Speech detection status.', '0 = false (no speech detected)', '1 = true (speech detected)'),
'FSBUPDATED': (19, 23, 'int', 1, 0, 'ro', 'FSB Update Decision.', '0 = false (FSB was not updated)', '1 = true (FSB was updated)'),
'FSBPATHCHANGE': (19, 24, 'int', 1, 0, 'ro', 'FSB Path Change Detection.', '0 = false (no path change detected)', '1 = true (path change detected)'),
'TRANSIENTONOFF': (19, 29, 'int', 1, 0, 'rw', 'Transient echo suppression.', '0 = OFF', '1 = ON'),
'VOICEACTIVITY': (19, 32, 'int', 1, 0, 'ro', 'VAD voice activity status.', '0 = false (no voice activity)', '1 = true (voice activity)'),
'STATNOISEONOFF_SR': (19, 33, 'int', 1, 0, 'rw', 'Stationary noise suppression for ASR.', '0 = OFF', '1 = ON'),
'NONSTATNOISEONOFF_SR': (19, 34, 'int', 1, 0, 'rw', 'Non-stationary noise suppression for ASR.', '0 = OFF', '1 = ON'),
'GAMMA_NS_SR': (19, 35, 'float', 3, 0, 'rw', 'Over-subtraction factor of stationary noise for ASR. ', '[0.0 .. 3.0] (default: 1.0)'),
'GAMMA_NN_SR': (19, 36, 'float', 3, 0, 'rw', 'Over-subtraction factor of non-stationary noise for ASR. ', '[0.0 .. 3.0] (default: 1.1)'),
'MIN_NS_SR': (19, 37, 'float', 1, 0, 'rw', 'Gain-floor for stationary noise suppression for ASR.', '[inf .. 0] dB (default: 16dB = 20log10(0.15))'),
'MIN_NN_SR': (19, 38, 'float', 1, 0, 'rw', 'Gain-floor for non-stationary noise suppression for ASR.', '[inf .. 0] dB (default: 10dB = 20log10(0.3))'),
'GAMMAVAD_SR': (19, 39, 'float', 1000, 0, 'rw', 'Set the threshold for voice activity detection.', '[inf .. 60] dB (default: 3.5dB 20log10(1.5))'),
# 'KEYWORDDETECT': (20, 0, 'int', 1, 0, 'ro', 'Keyword detected. Current value so needs polling.'),
'DOAANGLE': (21, 0, 'int', 359, 0, 'ro', 'DOA angle. Current value. Orientation depends on build configuration.')
}
class Tuning:
TIMEOUT = 100000
def __init__(self, dev):
self.dev = dev
def write(self, name, value):
try:
data = PARAMETERS[name]
except KeyError:
return
if data[5] == 'ro':
raise ValueError('{} is read-only'.format(name))
id = data[0]
# 4 bytes offset, 4 bytes value, 4 bytes type
if data[2] == 'int':
payload = struct.pack(b'iii', data[1], int(value), 1)
else:
payload = struct.pack(b'ifi', data[1], float(value), 0)
self.dev.ctrl_transfer(
usb.util.CTRL_OUT | usb.util.CTRL_TYPE_VENDOR | usb.util.CTRL_RECIPIENT_DEVICE,
0, 0, id, payload, self.TIMEOUT)
def read(self, name):
try:
data = PARAMETERS[name]
except KeyError:
return
id = data[0]
cmd = 0x80 | data[1]
if data[2] == 'int':
cmd |= 0x40
length = 8
response = self.dev.ctrl_transfer(
usb.util.CTRL_IN | usb.util.CTRL_TYPE_VENDOR | usb.util.CTRL_RECIPIENT_DEVICE,
0, cmd, id, length, self.TIMEOUT)
response = struct.unpack(b'ii', response.tostring())
if data[2] == 'int':
result = response[0]
else:
result = response[0] * (2.**response[1])
return result
def set_vad_threshold(self, db):
self.write('GAMMAVAD_SR', db)
def is_voice(self):
return self.read('VOICEACTIVITY')
@property
def direction(self):
return self.read('DOAANGLE')
@property
def version(self):
return self.dev.ctrl_transfer(
usb.util.CTRL_IN | usb.util.CTRL_TYPE_VENDOR | usb.util.CTRL_RECIPIENT_DEVICE,
0, 0x80, 0, 1, self.TIMEOUT)[0]
def close(self):
"""
close the interface
"""
usb.util.dispose_resources(self.dev)
def find(vid=0x2886, pid=0x0018):
dev = usb.core.find(idVendor=vid, idProduct=pid)
if not dev:
return
# configuration = dev.get_active_configuration()
# interface_number = None
# for interface in configuration:
# interface_number = interface.bInterfaceNumber
# if dev.is_kernel_driver_active(interface_number):
# dev.detach_kernel_driver(interface_number)
return Tuning(dev)
def main():
if len(sys.argv) > 1:
if sys.argv[1] == '-p':
print('name\t\t\ttype\tmax\tmin\tr/w\tinfo')
print('-------------------------------')
for name in sorted(PARAMETERS.keys()):
data = PARAMETERS[name]
print('{:16}\t{}'.format(name, b'\t'.join([str(i) for i in data[2:7]])))
for extra in data[7:]:
print('{}{}'.format(' '*60, extra))
else:
dev = find()
if not dev:
print('No device found')
sys.exit(1)
# print('version: {}'.format(dev.version))
if sys.argv[1] == '-r':
print('{:24} {}'.format('name', 'value'))
print('-------------------------------')
for name in sorted(PARAMETERS.keys()):
print('{:24} {}'.format(name, dev.read(name)))
else:
name = sys.argv[1].upper()
if name in PARAMETERS:
if len(sys.argv) > 2:
dev.write(name, sys.argv[2])
print('{}: {}'.format(name, dev.read(name)))
else:
print('{} is not a valid name'.format(name))
dev.close()
else:
print(USAGE.format(sys.argv[0]))
if __name__ == '__main__':
main()
Loading…
Cancel
Save