树莓派python3.7语音助手开发笔记(4)
接下来我们要去做主体的语音识别部分了。(传送门)
新建一个Xiaobai.py
首先要想的是录音,因为要做识别的话肯定是要音频文件的,拜大佬所赐,有两种方法进行录音(但后期移植到树莓派的时候,因为是比赛需要,第一种方法对嘈杂环境不太友好,第二种方法,在树莓派上我不知道为啥装不上paInt16这个库,所以也就没有使用)
第一种录音方式:使用speech_recognition包进行录音,这个录音出来的效果比较好,而且代码量非常少。
import speech_recognition as sr
# Use SpeechRecognition to record 使用语音识别包录制音频
def my_record(rate=16000):
r = sr.Recognizer()
with sr.Microphone(sample_rate=rate) as source:
print("please say something")
audio = r.listen(source)
with open("voices/myvoices.wav", "wb") as f:
f.write(audio.get_wav_data())
print("录音完成!")
my_record()
第二种录音方式:使用wave和pyaudio包进行录音,在python中直接使用pip install即可。
import wave
from pyaudio import PyAudio, paInt16
framerate = 16000 # 采样率
num_samples = 2000 # 采样点
channels = 1 # 声道
sampwidth = 2 # 采样宽度2bytes
FILEPATH = 'voices/myvoices.wav'
def save_wave_file(filepath, data):
wf = wave.open(filepath, 'wb')
wf.setnchannels(channels)
wf.setsampwidth(sampwidth)
wf.setframerate(framerate)
wf.writeframes(b''.join(data))
wf.close()
#录音
def my_record():
pa = PyAudio()
#打开一个新的音频stream
stream = pa.open(format=paInt16, channels=channels,
rate=framerate, input=True, frames_per_buffer=num_samples)
my_buf = [] #存放录音数据
t = time.time()
print('正在录音...')
while time.time() < t + 10: # 设置录音时间(秒)
#循环read,每次read 2000frames
string_audio_data = stream.read(num_samples)
my_buf.append(string_audio_data)
print('录音结束.')
save_wave_file(FILEPATH, my_buf)
stream.close()
而我直接使用ALSA进行录音
import os
def record_voice():
os.system("aplay resources/ding.wav") #在后期启动小白的时候有一定延迟,这个时候说话是录不进去的,所以加了个提示音
os.system("arecord -d 3 -f cd -r 16000 -c 1 -t wav /voices/myvoices.wav")
#因为是比赛需要所以录音时间很短
录完音之后就是语音识别了。
APP_IP = '你的APP_IP'
API_KEY = '你的API_KEY'
SECRET_KEY = '你的秘钥'
client = AipSpeech(APP_IP, API_KEY, SECRET_KEY)
def listen():
with open('/voices/myvoices.wav', 'rb') as fp:
voices = fp.read()
try:
result = client.asr(voices, 'wav', 16000, {'dev_pid': 1536, }) #向百度API发送参数并进行识别
result_text = result["result"][0]
print("you said: ", result_text)
return result_text
except KeyError:
print("KeyError")
但在比赛会场上这种方式极度依赖于网络,在正常家里网络下速度很快,但在我开着4G进行测试的时候反应速度为15秒左右,时间太长了,于是我选择了科大讯飞的语音识别离线SDK。
还是一样的去科大讯飞平台注册申请下载Linux的离线SDK
如果是Linux电脑上开发需自行注册!!!!!!!!!!!树莓派有其他方法
(树莓派已被移除这里要用老版本的,传送门)
Linux安装方法详见科大讯飞的技术文档
树莓派安装需要改动sh文件,Linux和树莓派都要改下c文件,先进入SDK的samples的iat_sample文件夹,将
export LD_LIBRARY_PATH=$(pwd)/…/…/libs/x86/
改为
export LD_LIBRARY_PATH=$(pwd)/…/…/libs/RaspberryPi/
然后在c文件最后把
run_iat(“wav/iflytek02.wav”, session_begin_params);
里面的文件路径改成我们的
run_iat("/voices/myvoices.wav", session_begin_params);
再将上面的
printf("\n########################################################################\n");
printf("## 语音听写(iFly Auto Transform)技术能够实时地将语音转换成对应的文字。##\n");
printf("########################################################################\n\n");
printf("演示示例选择:是否上传用户词表?\n0:不使用\n1:使用\n");
scanf("%d", &upload_on);
if (upload_on)
{
printf("上传用户词表 ...\n");
ret = upload_userwords();
if (MSP_SUCCESS != ret)
goto exit;
printf("上传用户词表成功\n");
}
这些全部注释掉
在run_iat函数的最下面加上
FILE *fp=fopen("/voices/text.txt","w");
fputs(rec_result,fp);
fclose(fp);
树莓派还需要将234行的 appid 改为 56ee43d0
(这里感谢大佬提供的SDK ID)
树莓派还需要更改Makefile
#vim Makefile
在下面
ifdef LINUX64
LDFLAGS := -L$(DIR_LIB)/RaspberryPi #将这里的x64和x86改成RaspberryPi
else
LDFLAGS := -L$(DIR_LIB)/RaspberryPi
endif
保存退出后在该目录直接,
#source 32bit_make.sh
编译完成后到bin目录下会有个iat_sample可执行文件,这个就是我们用于识别的东西,同样的环境下差不多要4秒时间就可以识别成功了,速度提升了不少。
def listen():
os.system("cd /root/python/Linux_iat1227_5e34eae9/bin/ && ./iat_online_sample ")
try:
with open("/voices/text.txt", "r") as file:
result_text = file.read()
print("you said: ", result_text)
return result_text
except KeyError:
print("KeyError")
这就是改进之后的代码了,如果有高手也可以用python里面的c语言支持库,将这些以python写出来,这样运行速度也能提升不少。
接着将我们第三篇笔记里的语音合成加进来,主体就完成了不少了。