From cc125278c6cf4e43d8fb2e6dbddd3c04660fb3ca Mon Sep 17 00:00:00 2001 From: baali Date: Wed, 22 Mar 2017 00:22:39 +0530 Subject: [PATCH 1/6] Changes to make script Python3.x compatible. --- alexa.py | 6 +++--- auth_web.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/alexa.py b/alexa.py index 9598865..1fd4fc6 100644 --- a/alexa.py +++ b/alexa.py @@ -174,8 +174,8 @@ def process_response(self, response): logger.debug("Processing Request Response...") if response.status_code == 200: - data = "Content-Type: " + response.headers['content-type'] + '\r\n\r\n' + response.content - msg = email.message_from_string(data) + data = b"Content-Type: " + response.headers['content-type'].encode('utf-8') + b'\r\n\r\n' + response.content + msg = email.message_from_bytes(data) for payload in msg.get_payload(): if payload.get_content_type() == "application/json": j = json.loads(payload.get_payload()) @@ -184,7 +184,7 @@ def process_response(self, response): logger.debug('Play ' + payload.get('Content-ID').strip("<>")) p = subprocess.Popen(mp3_player, stdin=subprocess.PIPE, shell=True) - p.stdin.write(payload.get_payload()) + p.stdin.write(payload.get_payload().encode('utf-8')) p.stdin.close() p.wait() else: diff --git a/auth_web.py b/auth_web.py index 3e6f485..b6a744e 100644 --- a/auth_web.py +++ b/auth_web.py @@ -30,7 +30,7 @@ def index(self): raise cherrypy.HTTPRedirect(p.url) def authresponse(self, var=None, **params): - code = urllib.quote(cherrypy.request.params['code']) + code = urllib.parse.quote(cherrypy.request.params['code']) callback = cherrypy.url() payload = {"client_id": Client_ID, "client_secret": Client_Secret, "code": code, "grant_type": "authorization_code", "redirect_uri": callback} From f7a2a1a92c7dbf9a6008861fa5484695133bfb90 Mon Sep 17 00:00:00 2001 From: baali Date: Fri, 24 Mar 2017 00:12:06 +0530 Subject: [PATCH 2/6] Fixes to play audio response from AVS. --- alexa.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/alexa.py b/alexa.py index 1fd4fc6..b05a8d9 100644 --- a/alexa.py +++ b/alexa.py @@ -183,8 +183,11 @@ def process_response(self, response): elif payload.get_content_type() == "audio/mpeg": logger.debug('Play ' + payload.get('Content-ID').strip("<>")) + f = open(payload.get('Content-ID').strip("<>")+'.wav', 'wb') + f.write(payload.get_payload(decode=True)) + f.close() p = subprocess.Popen(mp3_player, stdin=subprocess.PIPE, shell=True) - p.stdin.write(payload.get_payload().encode('utf-8')) + p.stdin.write(payload.get_payload(decode=True)) p.stdin.close() p.wait() else: From 9df2053d70d0a041bbc8e4c208364e11f39efbd3 Mon Sep 17 00:00:00 2001 From: baali Date: Sun, 26 Mar 2017 23:03:42 +0530 Subject: [PATCH 3/6] Fix to handle str and buffer interface error in py3.4. --- alexa.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/alexa.py b/alexa.py index b05a8d9..f776e68 100644 --- a/alexa.py +++ b/alexa.py @@ -92,24 +92,25 @@ def generate(audio, boundary): } } - yield chunk + json.dumps(d) + '\r\n' + yield (chunk + json.dumps(d) + '\r\n').encode() - chunk = '--%s\r\n' % boundary + chunk = ('--%s\r\n' % boundary).encode() chunk += ( 'Content-Disposition: form-data; name="audio"\r\n' 'Content-Type: audio/L16; rate=16000; channels=1\r\n\r\n' ) - yield chunk + yield chunk.encode() for a in audio: yield a - yield '--%s--\r\n' % boundary + yield ('--%s--\r\n' % boundary).encode() logger.debug('Finished sending speech to Alexa Voice Service') @staticmethod def pack(audio, boundary): + print('Start sending speech to Alexa Voice Service') logger.debug('Start sending speech to Alexa Voice Service') body = '--%s\r\n' % boundary body += ( From 95db11cd18e8bed922a22e68ef95737416e7cee7 Mon Sep 17 00:00:00 2001 From: baali Date: Tue, 28 Mar 2017 11:26:32 +0530 Subject: [PATCH 4/6] Using mplayer as player, as debian uses libav instead of ffmpeg. --- alexa.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/alexa.py b/alexa.py index f776e68..bab47ca 100644 --- a/alexa.py +++ b/alexa.py @@ -19,8 +19,8 @@ if platform.machine() == 'mips': mp3_player = 'madplay -o wave:- - | aplay -M' else: - mp3_player = 'ffplay -autoexit -nodisp -loglevel quiet -' - + # mp3_player = 'ffplay -autoexit -nodisp -loglevel quiet -' + mp3_player = 'mplayer -' class Alexa: """ From fe201cd3af82fcc4f4df176c30ea10453148af05 Mon Sep 17 00:00:00 2001 From: baali Date: Wed, 5 Apr 2017 20:13:52 +0530 Subject: [PATCH 5/6] Fixes to trigger audio recording with GPIO pin 3. --- alexa.py | 44 +++++++++++++++++++++++++++++--------------- 1 file changed, 29 insertions(+), 15 deletions(-) diff --git a/alexa.py b/alexa.py index bab47ca..aa5182c 100644 --- a/alexa.py +++ b/alexa.py @@ -12,6 +12,13 @@ from respeaker import Microphone from creds import Client_ID, Client_Secret, refresh_token +from respeaker.vad import vad +import time + +import contextlib +import wave +from gpiozero import LED, Button +from signal import pause logging.basicConfig(level=logging.DEBUG) logger = logging.getLogger(__file__) @@ -66,6 +73,7 @@ def generate(audio, boundary): Returns: """ + start_time = time.time() logger.debug('Start sending speech to Alexa Voice Service') chunk = '--%s\r\n' % boundary chunk += ( @@ -94,7 +102,7 @@ def generate(audio, boundary): yield (chunk + json.dumps(d) + '\r\n').encode() - chunk = ('--%s\r\n' % boundary).encode() + chunk = '--%s\r\n' % boundary chunk += ( 'Content-Disposition: form-data; name="audio"\r\n' 'Content-Type: audio/L16; rate=16000; channels=1\r\n\r\n' @@ -102,10 +110,17 @@ def generate(audio, boundary): yield chunk.encode() - for a in audio: - yield a + with contextlib.closing(wave.open('recording.wav', 'wb')) as wf: + wf.setnchannels(1) + wf.setsampwidth(2) + wf.setframerate(16000) + for a in audio: + wf.writeframes(a) + yield a yield ('--%s--\r\n' % boundary).encode() + print("Finished sending data to AVS") + print("Time spent recording audio: " + str(time.time() - start_time)) logger.debug('Finished sending speech to Alexa Voice Service') @staticmethod @@ -151,7 +166,9 @@ def pack(audio, boundary): return body - def recognize(self, audio): + def recognize(self): + print('Button pressed!') + audio = self.mic.listen(duration=3) url = 'https://access-alexa-na.amazon.com/v1/avs/speechrecognizer/recognize' boundary = 'this-is-a-boundary' if isinstance(audio, types.GeneratorType): @@ -168,11 +185,15 @@ def recognize(self, audio): } data = self.pack(audio, boundary) + start_time = time.time() r = self.session.post(url, headers=headers, data=data, timeout=20) + response_waiting_time = time.time() - start_time + print("Time Alexa request took: " + str(response_waiting_time)) self.process_response(r) def process_response(self, response): logger.debug("Processing Request Response...") + print("Processing Request Response...") if response.status_code == 200: data = b"Content-Type: " + response.headers['content-type'].encode('utf-8') + b'\r\n\r\n' + response.content @@ -202,6 +223,7 @@ def process_response(self, response): for directive in j['messageBody']['directives']: if directive['namespace'] == 'SpeechSynthesizer': if directive['name'] == 'speak': + print("SpeechSynthesizer audio: " + directive['payload']['audioContent'].lstrip('cid:')) logger.debug( "SpeechSynthesizer audio: " + directive['payload']['audioContent'].lstrip('cid:')) elif directive['namespace'] == 'SpeechRecognizer': @@ -245,19 +267,11 @@ def on_quit(signum, frame): quit_event.set() signal.signal(signal.SIGINT, on_quit) - - while not quit_event.is_set(): - if mic.wakeup(keyword='alexa'): - logging.debug('wakeup') - data = mic.listen() - try: - alexa.recognize(data) - except Exception as e: - logging.warn(e.message) - + right_button = Button(3) + right_button.when_pressed = alexa.recognize + pause() mic.close() logging.debug('Mission completed') - if __name__ == '__main__': main() From 8dfc81511b90b3615db31b05e7c0103e30b9d472 Mon Sep 17 00:00:00 2001 From: baali Date: Wed, 5 Apr 2017 20:16:58 +0530 Subject: [PATCH 6/6] Added gpizero dependency. --- requirements.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 2ca4d86..cb665f3 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,4 +2,5 @@ requests>=2.4.3 CherryPy>=4.0.0 webrtcvad pocketsphinx -respeaker>=0.4.0 \ No newline at end of file +respeaker>=0.4.0 +gpiozero==1.3.2