아마존에서 제공하는 Alexa를 raspberry pi에 올려보자

https://github.com/ewenchou/alexa-client

위 URL을 따라가서 지시에 따라 alexa client를 사용해보도록 한다.


test_ask.py 파일은 영어로 된 wav파일을 요청하면 그에 맞는 alexa의 대답을 영어로된 wav파일로 반환해준다.

여기서 입력과 출력을 한글로 변경해보도록 하자.


먼저 한글 음성, 영어 음성을 각각 text로 변환시켜줄 STT와 텍스트를 음성으로 변환 시켜줄 TTS 그리고 번역이 필요하다.

각 부분에 대해 사용할 것은 다음과 같다.

STT : Google Cloud Speech API

TTS : Naver 음성합성 API

번역 : Naver 기계번역 API


Google Cloud Speech API

위 주소의 지시를 따라 debian에서 Google Cloud SDK 환경을 설치한다. 환경이 준비 되었다면 다음 URL을 따라서 Google Cloud Speech API를 사용하는 법에 대해 배워 보고, 제대로 작동되는지 예제를 다뤄보라.

https://cloud.google.com/speech/docs/getting-started


Naver API

TTS 설명 및 예시


Translation 설명 및 예시

https://developers.naver.com/docs/labs/translator/


이제 준비가 다 되었다. 한글로 말하면 한글로 대답해주는 나만의 korean Alexa를 python 코드로 구현해 보자.


korean Alexa

def transcribe_file_kor(speech_file):
    """Transcribe the given audio file."""
    
    speech_client = speech.Client()

    with io.open(speech_file, 'rb') as audio_file:
        content = audio_file.read()
        audio_sample = speech_client.sample(
            content=content,
            source_uri=None,
            encoding='LINEAR16',
            sample_rate_hertz=16000)

    alternatives = audio_sample.recognize('ko-KR')
    for alternative in alternatives:
		return alternative.transcript
		
def transcribe_file_eng(speech_file):
    """Transcribe the given audio file."""
    
    speech_client = speech.Client()

    with io.open(speech_file, 'rb') as audio_file:
        content = audio_file.read()
        audio_sample = speech_client.sample(
            content=content,
            source_uri=None,
            encoding='LINEAR16',
            sample_rate_hertz=16000)

    alternatives = audio_sample.recognize('en-US')
    for alternative in alternatives:
		return alternative.transcript

 이 코드는 Google Cloud Speech API를 사용하여 각각 한글로 된 음성파일을 한글 텍스트로, 영어로 된 음성파일을 영어 텍스트로 변환 시켜주는 코드이다. 



def translateKorToEng(korean_string):
	client_id = "YOUR_CLIENT_ID"
	client_secret = "YOUR_CLIENT_SECRET"
	encText = urllib.parse.quote(korean_string.encode("utf-8"))
	data = "source=ko&target=en&text=" + encText
	url = "https://openapi.naver.com/v1/language/translate"
	request = urllib.request.Request(url)
	request.add_header("X-Naver-Client-Id",client_id)
	request.add_header("X-Naver-Client-Secret",client_secret)
	response = urllib.request.urlopen(request, data=data.encode("utf-8"))
	rescode = response.getcode()
	if(rescode==200):
		response_body = json.loads(response.read().decode('utf-8'))
		translated_eng_str = response_body["message"]["result"]["translatedText"]
		return translated_eng_str
	else:
		print("Error Code:" + rescode)
		

def translateEngToKor(english_string):
	client_id = "YOUR_CLIENT_ID"
	client_secret = "YOUR_CLIENT_SECRET"
	encText = urllib.parse.quote(english_string.encode("utf-8"))
	data = "source=en&target=ko&text=" + encText
	url = "https://openapi.naver.com/v1/language/translate"
	request = urllib.request.Request(url)
	request.add_header("X-Naver-Client-Id",client_id)
	request.add_header("X-Naver-Client-Secret",client_secret)
	response = urllib.request.urlopen(request, data=data.encode("utf-8"))
	rescode = response.getcode()
	if(rescode==200):
		response_body = json.loads(response.read().decode('utf-8'))
		translated_kor_str = response_body["message"]["result"]["translatedText"]
		return translated_kor_str
	else:
		print("Error Code:" + rescode) 

 위 코드는 Naver 기계번역 API를 이용하여 한글을 영어로, 영어를 한글로 번역해주는 코드이다. client_id, client_secret 변수에는 자신이 할당 받은 id 와 secret을 적어 넣으면 된다.



def koreanTextToSpeech(korean_string):
	client_id = "YOUR_CLIENT_ID"
	client_secret = "YOUR_CLIENT_SECRET"
	encText = urllib.parse.quote(korean_string.encode("utf-8"))
	data = "speaker=mijin&speed=0&text=" + encText;
	url = "https://openapi.naver.com/v1/voice/tts.bin"
	request = urllib.request.Request(url)
	request.add_header("X-Naver-Client-Id",client_id)
	request.add_header("X-Naver-Client-Secret",client_secret)
	response = urllib.request.urlopen(request, data=data.encode('utf-8'))
	rescode = response.getcode()
	if(rescode==200):
		print("TTS mp3")
		response_body = response.read()
		with open('response_audio_file_path.mp3', 'wb') as f:
			f.write(response_body)
	else:
		print("Error Code:" + rescode)

 위 코드는 한국어 TTS코드로 Naver 음성합성 API를 이용하여 한글 텍스트 파일을 요청하면 한국어 음성파일을 반환하는 코드이다. 마찬가지로 자신의 client_id 와 client_secret을 넣어주면 된다. "output_audio_file_path.mp3" 에는 음성파일을 반환받기 원하는 경로와 파일명을 정해주면 된다.



def askToAlexa():
    alexa = AlexaClient()
    input = 'your_request_audio_path.wav'
    save_to = 'your_response_audio_path.mp3'
    alexa.ask(input, save_to=save_to)
    print "Response from Alexa saved to {}".format(save_to) 

 마지막으로 영어 음성파일을 Alexa에게 전달하고 그에 대한 답변을 음성파일로 받는 함수이다.  input과 save_to에 각각 자신의 요청파일과 반환받기 원하는 파일의 경로와 파일명을 넣으면 된다. 


이제 조각 들을 모두 모았으니 하나로 합쳐보자!


# -*- coding: utf-8 -*-
import io
import sys
import os
import json
from six.moves import urllib
from alexa_client import AlexaClient
from google.cloud import speech

def transcribe_file_kor(speech_file):
    """Transcribe the given audio file."""
    
    speech_client = speech.Client()

    with io.open(speech_file, 'rb') as audio_file:
        content = audio_file.read()
        audio_sample = speech_client.sample(
            content=content,
            source_uri=None,
            encoding='LINEAR16',
            sample_rate_hertz=16000)

    alternatives = audio_sample.recognize('ko-KR')
    for alternative in alternatives:
		return alternative.transcript
		
def transcribe_file_eng(speech_file):
    """Transcribe the given audio file."""
    
    speech_client = speech.Client()

    with io.open(speech_file, 'rb') as audio_file:
        content = audio_file.read()
        audio_sample = speech_client.sample(
            content=content,
            source_uri=None,
            encoding='LINEAR16',
            sample_rate_hertz=16000)

    alternatives = audio_sample.recognize('en-US')
    for alternative in alternatives:
		return alternative.transcript
		
		
def translateKorToEng(korean_string):
	client_id = "YOUR_CLIENT_ID"
	client_secret = "YOUR_CLIENT_SECRET"
	encText = urllib.parse.quote(korean_string.encode("utf-8"))
	data = "source=ko&target=en&text=" + encText
	url = "https://openapi.naver.com/v1/language/translate"
	request = urllib.request.Request(url)
	request.add_header("X-Naver-Client-Id",client_id)
	request.add_header("X-Naver-Client-Secret",client_secret)
	response = urllib.request.urlopen(request, data=data.encode("utf-8"))
	rescode = response.getcode()
	if(rescode==200):
		response_body = json.loads(response.read().decode('utf-8'))
		translated_eng_str = response_body["message"]["result"]["translatedText"]
		return translated_eng_str
	else:
		print("Error Code:" + rescode)
		

def translateEngToKor(english_string):
	client_id = "YOUR_CLIENT_ID"
	client_secret = "YOUR_CLIENT_SECRET"
	encText = urllib.parse.quote(english_string.encode("utf-8"))
	data = "source=en&target=ko&text=" + encText
	url = "https://openapi.naver.com/v1/language/translate"
	request = urllib.request.Request(url)
	request.add_header("X-Naver-Client-Id",client_id)
	request.add_header("X-Naver-Client-Secret",client_secret)
	response = urllib.request.urlopen(request, data=data.encode("utf-8"))
	rescode = response.getcode()
	if(rescode==200):
		response_body = json.loads(response.read().decode('utf-8'))
		translated_kor_str = response_body["message"]["result"]["translatedText"]
		return translated_kor_str
	else:
		print("Error Code:" + rescode)
	
	
	
def koreanTextToSpeech(korean_string):
	client_id = "YOUR_CLIENT_ID"
	client_secret = "YOUR_CLIENT_SECRET"
	encText = urllib.parse.quote(korean_string.encode("utf-8"))
	data = "speaker=mijin&speed=0&text=" + encText;
	url = "https://openapi.naver.com/v1/voice/tts.bin"
	request = urllib.request.Request(url)
	request.add_header("X-Naver-Client-Id",client_id)
	request.add_header("X-Naver-Client-Secret",client_secret)
	response = urllib.request.urlopen(request, data=data.encode('utf-8'))
	rescode = response.getcode()
	if(rescode==200):
		print("TTS mp3")
		response_body = response.read()
		with open('korean_alexa.mp3', 'wb') as f:
			f.write(response_body)
	else:
		print("Error Code:" + rescode)
	
	
"""This test will send a pre-generated audio file in the `tests` directory
to AVS, and saves it as `/tmp/test1.mp3`."""
def askToAlexa():
    alexa = AlexaClient()
    input = 'after_srate_conv.wav'  #'{}/1.wav'.format(TESTS_PATH)
    save_to = 'response_alexa.mp3'
    alexa.ask(input, save_to=save_to)
    print "Response from Alexa saved to {}".format(save_to)


if __name__ == '__main__':

	# 환경 변수 설정
	os.system("export GOOGLE_APPLICATION_CREDENTIALS=\"Your_Google_Service_Account_Key_Path.json\"")
	
	# 인코딩 설정
	reload(sys)
	sys.setdefaultencoding('utf-8')
	
	# 녹음
	os.system("arecord -D plughw:1,0 -f S16_LE -c1 -r16000 -d 3 input.wav")
	print("recording complete!")
	
	# STT 한글
	input_kor_str = transcribe_file_kor('input.wav')
	print(input_kor_str)
	
	# 한글을 영어로 번역
	input_eng_str = translateKorToEng(unicode(input_kor_str))
	print(input_eng_str)
	
	# 영어 TTS
	os.system("espeak -w before_srate_conv.wav \""+input_eng_str+"\"")
	os.system("sox before_srate_conv.wav -r 16000 after_srate_conv.wav")
	print("TTS and srate convert completed")
	
        # alexa
	askToAlexa()
	
	# 영어음성 STT
	os.system("sox response_alexa.mp3 -r 16000 response_alexa_converted.wav")
	output_eng_str = transcribe_file_eng('response_alexa_converted.wav')
	print(output_eng_str)
	
	# 영어문장을 한글로 번역
	output_kor_str = translateEngToKor(output_eng_str).encode("utf-8")
	print(output_kor_str)
	
	# 한글 TTS
	koreanTextToSpeech(unicode(output_kor_str))
	
	# 한글 음성 출력
	os.system("mpg321 korean_alexa.mp3") 

자 이제 한글로 얘기하면 한글로 대답해주는 코드가 완성되었다. 미국 대통령이 누군지 물어보자.







+ Recent posts