最近开源了硕士论文中语音控制LED灯、直流电机以及语音陪护实验的源码,需要硕士论文原文的同学可以发邮件到我的邮箱(18261593885@163.com)或者直接在微信语音识别解码群私聊我,其主要实验内容如下:
1) 实验的具体源码链接:https://download.csdn.net/download/Xwei1226/12740275
2) 语音控制实验(语音控制LED灯以及语音控制直流电机)
3)语音陪护实验
以下内容为实验的具体方法与理论
研究接近两年的语音识别,最近一个月开始准备将自己的研究应用于实践中。从今年5月初开始研究语音控制,到今天才出一个简单的demo,最后演示结果如下:
(https://v.youku.com/v_show/id_XNDIyNDY2MjcxMg==.html?spm=a2h3j.8428770.3416059.1)
整体语音控制架构如下所示:
如果是调用科大讯飞、百度等企业的语音识别API则可以直接忽略服务端的一些操作,按照企业的要求以及通信协议进行文件传输,本文主要涉及客户端、硬件端以及控制端进行详细的阐述,服务器端如果有问题可以直接留言给作者。
一、客户端
客户端即为你所需要接收服务器响应的设备,本文使用的客户端为树莓派3b+(made in japan),通过WIFI与服务器端进行通信,硬件在第二节讲解,下面贴出一张笔者觉得不错的树莓派GPIO口的示意图:
树莓派基本的操作以及设备连接可以参考如下连接:http://shumeipai.nxez.com/
本文使用的GPIO口为11与6号口。
二、硬件端
本文涉及的硬件包括:
2.1 树莓派3b+;
2.2 麦克风(免驱动);
2.3 树莓派杜邦线若干;
2.4 LED灯;
2.5 电源;
2.6 串口连接;
2.7 树莓派扩展板等硬件设备。
三、控制端
前面的准备工作完成,则需要进行核心部分进行梳理。首先本文采用的是HTTP协议下的TCP/IP通信协议,为了防止服务端被攻击,笔者设计服务端为动态IP以防上述问题。
3.1 初始方案
首先对自己的树莓派进行声卡的检查以及声卡设备的录音、播放等问题进行排查,此为前提条件,由于之前对于树莓派不熟悉,或由于设备问题,作者在此卡了三天,下面整理一下初始方案:
本文使用的语音识别系统是基于DCNN-CTC构建的系统,如果对端到端感兴趣的朋友不妨关注一下个人博客以及个人github主页,内部有多种语音识别系统构建方法,笔者使用的是音节为建模单元构建的识别系统,具体可以参靠如下连接:(https://github.com/zw76859420)
由于训练语料均采用16khz、16bit的单通道WAV格式的语音文件。我曾在kaldi平台下做过在线语音识别,故而准备参考kaldi的方案移植到树莓派平台下构建在线语音识别系统,初始方案如下:
录音:pyaudio
播放:omxplayer
但是作者不得不觉得很坑爹,树莓派官方是不允许录制16khz 的语料的,但是中文下写了一大堆关于在树莓派平台下使用pyaudio录制16khz 的语音,笔者信以为真,奈何三天,调了无数次的bug,一次次的安装、卸载pyaudio,均有错误产生,最后笔者不得不越墙而过,终于找到了一个替代方案,为了防止国人在此方向上进一步受挫,故而准备开源,调整方案如下:
录音:arecord
播放:omxplayer
故而最后的问题均解决,录音与播放均解决,所以不得不说,车到山前必有路!
四、代码
4.1 首先测试本地的声卡的录音与播放设备的可用性
4.1.1 使用arecord录制16khz、16bit语音,测试是否在pi目录下有语料生成
arecord -D "plughw:1,0" -f S16_LE -d 2 -r 16000 /home/pi/test.wav
4.1.2 测试播放语音功能
omxplayer -o local /home/pi/test.wav
若上述没有问题,则说明声卡可以正常使用,若有问题,一般是可以在pi目录下新建 .asoundrc 的隐藏文件,对其进行配置:
配置的结果如下:
pcm.!default {
type asym
capture.pcm "mic"
playback.pcm "speaker"
}
pcm.mic {
type plug
slave {
pcm "hw:1,0"
}
}
一般是这里的原因,如果有问题,直接在博主文章下留言,切忌使用pyaudio进行录音。
4.1.3 服务器端测试
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
'''
@author1: zhangwei Jiangnan University
@author2: nielei Xidian University
asrserver测试专用客户端
'''
import requests
import wave
import numpy as np
# requests.DEFAULT_RETRIES = 5
# s = requests.session()
def read_wav_data(filename):
'''
获取文件数据以及采样频率;
输入为文件位置,输出为wav文件数学表示和采样频率;
'''
wav = wave.open(filename, 'rb')
num_frames = wav.getnframes()
num_channels = wav.getnchannels()
framerate = wav.getframerate()
str_data = wav.readframes(num_frames)
wav.close()
wave_data = np.fromstring(str_data, dtype=np.short)
wave_data.shape = -1, num_channels
wave_data = wave_data.T
return wave_data, framerate
url = 'http://10.25.158.143:20000/'
wavsignal, fs = read_wav_data('/home/pi/test_01.wav')
# print(wavsignal)
datas={'token': token, 'fs': fs, 'wavs': wavsignal}
r = requests.post(url, datas)
r.encoding = 'utf-8'
print(r.text)
上述代码是在客户端访问服务器进行通信的代码,对服务器与客户端之间的通信进行处理,在此感谢西安电子科大的某位大牛师弟对此代码进行优化。
4.1.4 语音控制代码
对树莓派的11号引脚进行电压控制,其主要代码如下:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
'''
@author1: zhangwei Jiangnan University
@author2: nielei Xidian University
asrserver测试专用客户端
'''
import requests
import wave
import numpy as np
# requests.DEFAULT_RETRIES = 5
# s = requests.session()
def read_wav_data(filename):
'''
获取文件数据以及采样频率;
输入为文件位置,输出为wav文件数学表示和采样频率;
'''
wav = wave.open(filename, 'rb')
num_frames = wav.getnframes()
num_channels = wav.getnchannels()
framerate = wav.getframerate()
str_data = wav.readframes(num_frames)
wav.close()
wave_data = np.fromstring(str_data, dtype=np.short)
wave_data.shape = -1, num_channels
wave_data = wave_data.T
return wave_data, framerate
url = 'http://10.25.158.143:20000/'
wavsignal, fs = read_wav_data('/home/pi/test_01.wav')
# print(wavsignal)
datas={'token': token, 'fs': fs, 'wavs': wavsignal}
r = requests.post(url, datas)
r.encoding = 'utf-8'
print(r.text)
if __name__ == '__main__':
# audio_record(out_file=out_file, rec_time=rec_time)
# print(get_api_result())
GPIO.setmode(GPIO.BOARD)
GPIO.setup(11, GPIO.OUT)
while(True):
print("=================JNU ASR DEMO==================")
print("Please tell me the command(limits within 3 seconds)")
# audio_record(out_file='/home/pi/test_python/wav/01.wav')
os.system('arecord -D "plughw:1,0" -f S16_LE -d 2 -r 16000 /home/pi/test.wav')
asr_results = get_api_result()
print(asr_results)
# if len(asr_results) != 0:
# print(asr_results)
# print("=================Start Control====================")
re_asr_results = "".join(asr_results)
if len(re_asr_results) != 0:
if 'k' in re_asr_results:
print("==================开灯======================")
GPIO.output(11, GPIO.HIGH)
pass
if 'gu' in re_asr_results:
print("==================关灯======================")
GPIO.output(11, GPIO.LOW)
pass
if 'c' in re_asr_results:
GPIO.output(11, GPIO.LOW)
break
else:
pass
至此,基于DCNN-CTC语音识别系统以及基于树莓派的在线语音识别系统构建完毕,如果对本文的代码有问题,可以直接在下面留言。