树莓派python3.7语音助手开发笔记(4)

树莓派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写出来,这样运行速度也能提升不少。

接着将我们第三篇笔记里的语音合成加进来,主体就完成了不少了。

你可能感兴趣的:(树莓派python3.7语音助手开发笔记(4))