一、简单说点
因为手头有一个项目,该项目需要在香橙派上实现语音控制,并且带有语音唤醒功能。简单来说,就是通过唤醒词唤醒香橙派,然后说出相关指令,香橙派去执行指令。
但是,在弄香橙派的时候,自带的麦克风不好使了,单独进行麦克风测试的时候是好使的,但是程序跑起来怎么说话都没反应了。买了个USB接口的麦克风,还没到,就先在ubuntu系统上先试试流程,跑通下,到时在香橙派上弄的时候心里也有个数了。
这是这篇记录博客的由来了。开发语言使用的Python,不得不说,使用Python来进行语音识别,是真的方便,第三方库太强大了。基本上是把环境配置好,剩下简单写点流程逻辑代码就完成了。
emmm,对了,为了防止在复现过程中出现一些莫名其妙的bug,每一个环境的配置,还有Python包我都会附上相应的版本号,理论上来说按照流程来走应该是没什么问题,中间的坑我都踩的差不多了。好了,闲话说到这,进入正文。
Ubuntu: 20.04 Python: 3.8
二、相关技术介绍
语音唤醒使用的是Snowboy,这个官方已经不维护了,最后一个版本是1.3.0,官方的自定义语音唤醒词训练的网站已经停掉了,不过还有第三方的网站可以用。语音转文字使用的Speechbrain,这个可以自己训练自己的相关模型,为了提高自己指令识别精度可以这么做。要省事可以使用官方提供预先训练好的模型。文字转语音使用的Pyttsx3,这个怎么说,用来做demo程序是绝对够用了,但如果想要更好体验,需要解决下音色的问题。三、语音唤醒
版本号:1.3.0
Snowboy的GitHub地址:
/Kitt-AI/snowboy
如果在GitHub上下载压缩包的源码,那么我们需要先进行解压:
tar xvf snowboy-1.3.0.tar.gz
当然,我们也能直接使用git命令进行下载源码:
git clone /Kitt-AI/snowboy.git
代码下载完成后,先留着备用,接下来我们配置代码所需要的环境,snowboy需要swig,alsa等等,直接看配置:
sudo apt-get install swig 版本号:4.0.1sudo apt-get install libatlas-base-devsudo apt-get install sox 版本号:14.4.2sudo apt-get install libasound2-dev
这个里面,sox少了会怎么样,我没测试过,不知道sox会不会对snowboy的编译造成直接影响,起码可以通过 sox -d -d 命令来测试你的麦克风跟外放,执行命令之后,对着麦克风说话,你可以听到自己的声音。
libasound2少了会出问题,这个我一开忘了安装,结果报错了。这个是snowboy的C++编译中下载portaudio这个库的时候会用到,如果执行下载portaudio的操作前没有安装libasound2,会报下面错误:"Fail to open PortAudio stream, error message is “Device unavailable”。
还有,需要注意的是,swig的版本号要大于3.10(没记错的话,不然就是3.12 <-_<- )
环境弄好之后,我们进入下载好的snowboy文件中,就可以进行相关编译工作了。
这里先说下,Snowboy的C++编译操作。
进入下面目录:
cd examples/C++/
然后,进行安装portaudio,还是当前路径下:
./install_portaudio.sh
安装完成之后,进行编译操作:
make
如果是在Ubuntu20.04的环境下,是没什么问题的。其他环境,可能会报一个如下错误:/usr/bin/ld: …/…//lib/ubuntu64/libsnowboy-detect.a:error adding symbols:file in wrong format
这个时候,我们只需找到当前目录下的demo.mk文件,修改如下内容(第37行):
修改前:SNOWBOYDETECTLIBFIE := $(TOPDIR)/lib/ubuntu64/libsnowboy-detect.a修改后:SNOWBOYDETECTLIBFIE := $(TOPDIR)/lib/aarche64-ubuntu1604/libsnowboy-detect.a
修改完成后,在执行make。(可以在make之前,执行下make clean,清楚下上次编译文件)
编译完成之后,我们就行执行demo程序了:
./demo
demo程序默认的唤醒词是snowboy。唤醒之后控制台会输出:Hotword 1 detected!。我们也可以对demo程序进行修改:在代码中打印前加上一句system(“play resources/ding.wav”),这样在识别到唤醒词时会自动播放一个叮的声音。
demo程序运行完之后,我们可以仿照demo程序,进行自己的二次开发,加入唤醒之后需要进行的操作。因为我用的Python语言,后面我会给出Python的相关需要修改得部分,这里的修改也可以参考Python部分的。
Snowboy的Python编译:
安装相关环境:
sudo apt-get install swig 版本:4.0.1sudo apt-get install libatlas-base-dev
注意:这两个包如果在C++编译那里安装了,这里就不用重复安装了。
接下来安装pyaudio
sudo apt-get install portaudio19-dev python-all-dev python3-all-dev jackd1 portaudio19-doc jack-tools meterbridge liblo-devsudo apt-get install pyaudio
这里需要注意一个点,安装pyaudio之前一定要先安装前面那部分环境,因为pyaudio需要依赖portaudio,这里如果报错了,注意一下吧,亲身经历。
如果还报什么依赖问题,把下面这个执行一下(这里跟上面有些是重复的,删除重复的就行):
sudo apt-get install libasound-dev portaudio19-dev libportaudio2 libportaudiocpp0
环境备好之后,进入:
cd swig/Python3
进入之后,编译:
./make
这里如果出现错误:/usr/bin/ld: …/…//lib/ubuntu64/libsnowboy-detect.a:error adding symbols:file in wrong format
我们打开当前路径下的makefile文件,进行如下修改:
修改前:SNOWBOYDETECTLIBFIE := $(TOPDIR)/lib/ubuntu64/libsnowboy-detect.a修改后:SNOWBOYDETECTLIBFIE := $(TOPDIR)/lib/aarche64-ubuntu1604/libsnowboy-detect.a
如果没错误,就不用管了。编译完成之后,我们就可以进入目录:
cd examples/Python3
来运行官方demo了,不过运行之前,我们需要该一个文件:
打开当前路径snowboydecoder.py文件,将:
from * import snowboydetect 修改为import snowboydetect
修改完之后,我们运行:
python3 demo.py resources/models/snowboy.umdl
唤醒词为snowboy,唤醒之后会有叮的一声。
根据demo程序,来进行二次开发
接下来,创建一个python虚拟环境(最好这样,后面在安装一些python包的时候防止跟本地的一些包冲突)。我们snowboy编译之后的如下文件:
resources文件夹;demo.py ; snowboydecoder.py ;snowboydetect.py;_snowboydetect.so (_snowboydetect.so 在swig/Python3的目录下)
将上面文件都放到我们新创建的目录下,运行demo.py没问题后,我们在来对创建自己的语音唤醒代码:
import snowboydecoderimport signalinterrupted = Falsedef signal_handler(signal, frame):global interruptedinterrupted = Truedef interrupt_callback():global interruptedreturn interrupted# 语音唤醒之后播放的应答model = 'resources/models/snowboy.umdl'# 终止方法为ctrl+csignal.signal(signal.SIGINT, signal_handler)# 这里可以设置识别灵敏度detector = snowboydecoder.HotwordDetector(model, sensitivity=0.5)print('Listening... Press Ctrl+C to exit')def callback():print("唤醒之后的回调函数")print("在这里实现唤醒之后需要进行的操作")detector.start(detected_callback=callback, # 自定义回调函数interrupt_check=interrupt_callback,sleep_time=0.03)# 释放资源detector.terminate()
好了,这样就能把语音唤醒给运用起来了。snowboy的相关说明到这就结束。
哦,不对,差点忘了,如果想训练自己的唤醒词,可以在下面这个网站训练,上传三段自己录制的唤醒词语音就行,唤醒识别精度跟你上传的语音有很大关系:
/
四、语音转文字
获取语音
想要实现语音转文字,首先,我们得获取用户的语音输入。这里使用Python的speech_recognition包来进行语音获取,使用这个的好处是,他会在用户说话结束时,自动停止语音获取,这里我们就不用自己去写该什么停止语音获取的逻辑了,这点我认识是相当爽。
speech_recognition包的版本号:3.8.1
在安装speech_recognition包前我们还需要安装相应的依赖资源库:
PS. Python版本需为2.6或2.7或3.3+
pip install PyAudio 版本号:0.2.11ps.这里跟上面使用apt-get安装的pyaudio是不一样的,这个安装是当前项目下PS. PocketSphinx这个包可以暂时不安装,先看看能不能跑通,我安装这个是我一开始也试了使用里面的recognition_sphinx()来进行语音识别,结果发现效果不太好,就放弃了。但我现在不清楚这个有没有对后面安装产生什么影响,这个包我记得蛮大,可以暂时不安装,先试试后面流程再说。pip install PocketSphinx 版本号:0.1.15如果安装失败,那就是少了下面的一些依赖:apt-get install libasound2-dev bisonsudo apt-get install pulseaudiosudo apt-get install libpulse-devsudo apt-get install osspd
上面完成之后,安装:
pip install SpeechRecognition 版本号:3.8.1
然后,我们可以通过下面代码来验证语音的获取:
import speech_recognition as sr#从系统麦克风拾取音频数据,采样率为 16000def rec(rate=16000):r = sr.Recognizer()with sr.Microphone(sample_rate=rate) as source:print('正在获取声音中...')audio = r.listen(source)with open("recording.wav", "wb") as f:f.write(audio.get_wav_data())print('声音获取完成.')return 1if __name__ == '__main__':rec()
如果在当前项目目录下得到了recording.wav文件,并且播放正常的话,那就没问题了。
语音转文字
语音转文字使用speechbrain
安装:
pip install speechbrain 版本号:0.5.11pip install SoundFile 版本号:0.10.3.post1pip install sox 版本号:1.4.1
这个识别默认是英文识别,我们可以使用官方的预先训练好的中文模型,官网地址:
官网地址:https://speechbrain.github.io/GitHub仓库地址:/speechbrain/speechbrain
我这里下载好了:
下载地址:/download/qq_44323019/85399454
原来上传资源可以关闭自动调整积分。。。上面链接我设置的0积分,免费下载。
下载解压之后,会得到一个pretrained_models文件夹,把这个文件夹放到当前目录的根目录即可。
测试代码:
from speechbrain.pretrained import EncoderDecoderASRimport torchimport torchaudiodef voice_into_word():asr_model = EncoderDecoderASR.from_hparams(source="speechbrain/asr-transformer-aishell",savedir="pretrained_models/asr-transformer-aishell")audio_1 = r"./test.wav"ddd = torchaudio.list_audio_backends()print('start...')snt_1, fs = torchaudio.load(audio_1)wav_lens = torch.tensor([1.0])res = asr_model.transcribe_batch(snt_1, wav_lens)word = res[0][0].replace(' ', '')print(word)return wordif __name__ == '__main__':voice_into_word()
ok,到这里我们能将语音转文字,得到文字之后,那我们能操作的空间就大。
五、指令识别
这一部分其实没什么可说的,如果只是简单的指令识别,只要判断上一步我们得到的语音转成的文字部分有没有我们指令的关键字,然后再向用户确定一下就ok了。
其实这里我们还行实现语音聊天机器人功能。我们上一步不是得到了文字吗,这里只要我们能接一个聊天机器人接口就行了,比如图灵机器人。这里我没这个需求,有需求的可以自己去搜索,直接调用就行了。
六、文字转语音
要完成一个完整对话,当然少不了我们的终端也需要“说”了。这里我们使用pyttsx3来实现说的功能。
先安装:
sudo apt install libespeak1pip install pyttsx3
PS.这里说一句,单纯安装pyttsx3大概率是不行的,我当时是莫名其妙报了一大堆错,都蒙了,后面是在一个论坛上面看到需要libspeak这个。
安装完成之后,测试代码:
import pyttsx3def speakout(workText):engine = pyttsx3.init()# 获取发音人voices = engine.getProperty('voices') #这里可以获取你设备当前支持的发音,可以配置下面代码使用,我这里使用zh偷懒了engine.setProperty('voice', 'zh') # 开启支持中文rate = engine.getProperty('rate')engine.setProperty('rate', rate-40) #控制发音语速,可以自己调# 设置音量 范围为0.0-1.0 默认值为1.0engine.setProperty('volume', 0.7)engine.say(workText)engine.runAndWait()speakout('你好哇')
七、其他一些
到这里应该是结束了,语音唤醒,语音识别,文字转语音都有了,整套流程是通了,更深入的就需要自己慢慢去琢磨了。我这里给出我整个项目安装过的包,防止上面我有漏写了的。其中一些包肯定是用不到的,因为中间我尝试了好几种方案,所以安装过其他一些包。只做参考。
Package Version------------------ ------------certifi .10.8cffi1.15.0charset-normalizer 2.0.12filelock 3.7.0huggingface-hub 0.6.0HyperPyYAML 1.0.1idna3.3joblib 1.1.0numpy 1.22.3packaging21.3pip22.1pocketsphinx 0.1.15PyAudio 0.2.11pycparser2.21pyparsing3.0.9pyttsx3 2.71PyYAML 6.0requests 2.27.1ruamel.yaml 0.17.21ruamel.yaml.clib 0.2.6scipy 1.8.0sentencepiece0.1.96setuptools 62.2.0SoundFile0.10.3.post1sox1.4.1speechbrain 0.5.11SpeechRecognition 3.8.1torch 1.11.0torchaudio 0.11.0tqdm4.64.0typing_extensions 4.2.0urllib3 1.26.9wheel 0.37.1
到这里了,如果对你有帮助,点个小小的赞吧。头一次一篇博客分了两天来写。
->_<-
Ubuntu20.04 使用Python实现全过程离线语音识别(包含语音唤醒 语音转文字 指令识别 文字转语音)