英语语音训练机
我使用谷歌语音 api 制作了语音训练机, 因为日本人很难区分 “l” 和 “r” 发音。
目次
概述
如果您通过对 “右” 或 “光” 说话来与连接到 raspberry pi 的 usb 麦克风对话并正确识别它, 则伺服马达在 “右” 时指向右侧, 如果是 “光”, 则 led 指示灯。
部分
-
-
- 迈克使用相机在星期三
- 树莓派 3
- 微电脑 arduino uno
- neopixelpole–12连续的全彩连续 led
- 伺服马达 sg90
- 迈克使用相机在星期三
-
拉斯皮设置
安装语音处理库 sox。
1 |
$ sudo apt-get install alsa-utils sox libsox-fmt-all |
python 程序
录制时, 请点亮红色指示灯。当它识别 “正确” 和 “光” 时, 它就会向 arduino (gpio) 发送一个信号。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 |
#!/usr/bin/env python # -*- coding: utf-8 -*- import requests import json import os import commands import time import RPi.GPIO as GPIO GOOGLE_APIKEY = 'Google Speech API key' LISTEN_SECONDS = 3 #3 seconds recording VOICE_IN_PATH = '/home/pi/tmp.flac' #GPIO settings GPIO.setmode(GPIO.BCM) GPIO.setup(2, GPIO.OUT) GPIO.setup(3, GPIO.OUT) GPIO.setup(4, GPIO.OUT) GPIO.output(2, 0) GPIO.output(3, 0) GPIO.output(4, 0) #Audio input (voice -> sound data) def listen(seconds): print 'lestening...' cmdline = 'AUDIODEV=hw:1 rec -c 1 -r 17000 ' + VOICE_IN_PATH + \ ' trim 0 ' + str(seconds) os.system(cmdline) return os.path.getsize(VOICE_IN_PATH) #Voice recognition (sound data -> text) def recognize(): print('recognizing...') f = open(VOICE_IN_PATH, 'rb') voice = f.read() f.close() #English lang=en-US url = 'https://www.google.com/speech-api/v2/recognize?xjerr=1&client=chromium&'\ 'lang=en-US&maxresults=10&pfilter=0&xjerr=1&key=' + GOOGLE_APIKEY hds = {'Content-type': 'audio/x-flac; rate=17000'} try: reply = requests.post(url, data=voice, headers=hds).text except IOError: return '#CONN_ERR' except: return '#ERROR' objs = reply.split(os.linesep) for obj in objs: if not obj: continue alternatives = json.loads(obj)['result'] if len(alternatives) == 0: continue return alternatives[0]['alternative'][0]['transcript'] return "" def current_milli_time(): return int(round(time.time() * 1000)) if __name__ == '__main__': #first time record will be failed. listen(1) no_word = 0 wifi_err = 0 try: while True: #Audio input t0 = current_milli_time() GPIO.output(2, 1) #Rec LED on size = listen(LISTEN_SECONDS) GPIO.output(2, 0) #Rec LED off t = current_milli_time() - t0 if (t < 2000): print 'USB microphone not available' time.sleep(10) continue print 'listened:' + str(t) + 'ms' print 'voice data size=' + str(size) #Voice recognition t0 = current_milli_time() message = recognize().encode('utf-8') print 'recognized:' + str(current_milli_time() - t0) + 'ms' if (message == '#CONN_ERR'): print 'internet not available' time.sleep(10) continue elif (message == '#ERROR'): print 'voice recognize failed' time.sleep(10) continue print 'Result: ' + message #Discrimination Discrimination between "right" and "light" if 'right' in message: print 'right' GPIO.output(3, 1) #Servo turns the right GPIO.output(4, 0) #Neopixel LED off time.sleep(3) elif 'light' in message: print 'light' GPIO.output(3, 0) #Servo turns to the orignal GPIO.output(4, 1) #Neopixel LED on time.sleep(3) else: print 'non' except KeyboardInterrupt: GPIO.cleanup() pass |
arduino ide 程序
新像素的库在下面。
https://github.com/adafruit/Adafruit_NeoPixel
代码接收来自树莓派的信号, 并控制伺服和新像素环。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
#include <Servo.h> #include <Adafruit_NeoPixel.h> int GPIO3 = 3; int GPIO4 = 4; int servo, LED; Servo myservo; Adafruit_NeoPixel strip = Adafruit_NeoPixel(12, 6, NEO_GRB + NEO_KHZ800); void setup() { Serial.begin(9600); // make the pushbutton's pin an input: pinMode(GPIO3, INPUT); pinMode(GPIO4, INPUT); myservo.attach(9); myservo.write(0); myservo.detach(); strip.begin(); strip.show(); // Initialize all pixels to 'off' } void loop() { //Read GPIO servo = digitalRead(GPIO3); LED = digitalRead(GPIO4); Serial.print(servo); Serial.print("\t"); Serial.println(LED); //Servo myservo.attach(9); delay(100); if(servo == 1){ myservo.write(0); }else{ myservo.write(90); } myservo.detach(); delay(100); //LED int bright = 20; if(LED == 1){ for(uint16_t i=0; i<strip.numPixels(); i++) { strip.setPixelColor(i, strip.Color(bright, bright, bright)); } strip.show(); }else{ strip.clear(); strip.show(); } |