語(yǔ)音喚醒算是語(yǔ)音識(shí)別領(lǐng)域里最基礎(chǔ)的應(yīng)用,具體的場(chǎng)景如 Android 手機(jī)里的 “OK, Google” 或者蘋(píng)果設(shè)備里的 “Hey, Siri”猜谚。
簡(jiǎn)單來(lái)說(shuō)就是在后臺(tái)靜默地運(yùn)行著一個(gè)占用較少系統(tǒng)資源的服務(wù)(語(yǔ)音識(shí)別組件)败砂,該組件一直處于監(jiān)視麥克風(fēng)輸入的狀態(tài),如果有檢測(cè)到特定的語(yǔ)音輸入(即喚醒詞或“熱詞”)魏铅,則激活與之綁定的某個(gè)程序“開(kāi)關(guān)”昌犹。
相當(dāng)于一個(gè)簡(jiǎn)化版的語(yǔ)音助手吧,只對(duì)某一個(gè)特定的詞匯進(jìn)行響應(yīng)览芳,識(shí)別后也只完成某一件指定的任務(wù)斜姥。如果說(shuō)同語(yǔ)音助手的交互是一段持續(xù)的交流,那么語(yǔ)音喚醒即可作為這種連續(xù)交流的入口(打招呼)沧竟。
snowboy 是一個(gè)開(kāi)源的铸敏、輕量級(jí)語(yǔ)音喚醒引擎,可以通過(guò)它很輕松地創(chuàng)建屬于自己的類似“hey, Siri” 的喚醒詞屯仗。它的主要特性如下:
- 高度可定制性搞坝∩η矗可自由創(chuàng)建和訓(xùn)練屬于自己的喚醒詞
- 始終傾聽(tīng)魁袜。可離線使用,無(wú)需聯(lián)網(wǎng)峰弹,保護(hù)隱私店量。精確度高,低延遲
- 輕量可嵌入鞠呈。耗費(fèi)資源非常低(單核 700MHz 樹(shù)莓派只占用 10% CPU)
- 開(kāi)源跨平臺(tái)融师。開(kāi)放源代碼,支持多種操作系統(tǒng)和硬件平臺(tái)蚁吝,可綁定多種編程語(yǔ)言
詳細(xì)看了官網(wǎng)提供的安裝配置教程(已經(jīng)很久沒(méi)更新旱爆,有點(diǎn)過(guò)于繁瑣了),幾番嘗試之后窘茁,感覺(jué)下面的介紹算是最新也相對(duì)最簡(jiǎn)單的方法了吧娃豹。
PS:只針對(duì) Linux 系統(tǒng)(包含樹(shù)莓派)塑猖,其他平臺(tái)可參考 Github
一、獲取源代碼并編譯
安裝依賴
樹(shù)莓派原生的音頻設(shè)備是不支持語(yǔ)音輸入的(無(wú)法錄音),需要在網(wǎng)上購(gòu)買(mǎi)一支免驅(qū)動(dòng)的USB音頻驅(qū)動(dòng)(便攜式的和 U 盤(pán)差不多)丰嘉,一般插上即可直接使用。
建議安裝下 pulseaudio
軟件毙驯,減少音頻配置的步驟:
$ sudo apt-get install pulseaudio
安裝 sox
軟件測(cè)試錄音與播放功能:
$ sudo apt-get install sox
安裝完成后運(yùn)行 sox -d -d
命令竟坛,對(duì)著麥克風(fēng)說(shuō)話,確認(rèn)可以聽(tīng)到自己的聲音框冀。
安裝其他軟件依賴:
- 安裝 PyAudio:
$ sudo apt-get install python3-pyaudio
- 安裝 SWIG(>3.0.10):
$ sudo apt-get install swig
- 安裝 ATLAS:
$ sudo apt-get install libatlas-base-dev
編譯源代碼
獲取源代碼:$ git clone https://github.com/Kitt-AI/snowboy.git
編譯 Python3 綁定:$ cd snowboy/swig/Python3 && make
測(cè)試:
進(jìn)入官方示例目錄 snowboy/examples/Python3
并運(yùn)行以下命令:
$ python3 demo.py resources/models/snowboy.umdl
( 命令中的 snowboy.umdl
文件即語(yǔ)音識(shí)別模型)
然后對(duì)著麥克風(fēng)清晰地講出“snowboy”流椒,如果可以聽(tīng)到“滴”的聲音,則安裝配置成功明也。命令行輸出如下:
PS:官方源代碼使用 Python3 測(cè)試有報(bào)錯(cuò)镣隶,經(jīng)測(cè)試需修改 snowboy/examples/Python3
目錄下的 snowboydecoder.py
文件。
將第 5 行代碼 from * import snowboydetect
改為 import snowboydetect
即可直接運(yùn)行诡右。
二安岂、設(shè)置自己的喚醒詞
可將包含自定義喚醒詞的音頻文件上傳至 snowboy 官網(wǎng)(需要登錄),以訓(xùn)練生成自己喜歡的語(yǔ)音模型帆吻。
需要上傳的音頻文件數(shù)量為 3 個(gè)域那,wav 格式。我試過(guò)直接在線錄制猜煮,貌似有 Bug 次员。。王带。(也可能是我瀏覽器的問(wèn)題)
訓(xùn)練完成并測(cè)試通過(guò)后淑蔚,即可下載 PMDL 后綴的模型文件了。
測(cè)試
將以下文件復(fù)制到自己的項(xiàng)目目錄下:
- 上一步中下載好的 model.pmdl 模型文件
- 之前
snowboy/swig/Python3
目錄下編譯好的_snowboydetect.so
庫(kù) -
snowboy/examples/Python3
目錄下的demo.py
愕撰、snowboydecoder.py
刹衫、snowboydetect.py
文件以及resources
目錄 - 在項(xiàng)目目錄下執(zhí)行
$ python3 demo.py model.pmdl
并使用自己的喚醒詞進(jìn)行測(cè)試
三醋寝、自定義響應(yīng)
官方提供的示例 demo.py
文件的源代碼如下:
import snowboydecoder
import sys
import signal
interrupted = False
def signal_handler(signal, frame):
global interrupted
interrupted = True
def interrupt_callback():
global interrupted
return interrupted
if len(sys.argv) == 1:
print("Error: need to specify model name")
print("Usage: python demo.py your.model")
sys.exit(-1)
model = sys.argv[1]
# capture SIGINT signal, e.g., Ctrl+C
signal.signal(signal.SIGINT, signal_handler)
detector = snowboydecoder.HotwordDetector(model, sensitivity=0.5)
print('Listening... Press Ctrl+C to exit')
# main loop
detector.start(detected_callback=snowboydecoder.play_audio_file,
interrupt_check=interrupt_callback,
sleep_time=0.03)
detector.terminate()
通過(guò)閱讀代碼,可以看出喚醒詞識(shí)別成功以后带迟,程序響應(yīng)的具體內(nèi)容由程序末尾 detector.start()
函數(shù)的 detected_callback
參數(shù)指定音羞。
即重新綁定 detected_callback
對(duì)應(yīng)的函數(shù),可改變程序最終的響應(yīng)仓犬。如:
import snowboydecoder
import sys
import signal
interrupted = False
def signal_handler(signal, frame):
global interrupted
interrupted = True
def interrupt_callback():
global interrupted
return interrupted
def detected():
print("Great! I have recognized your words.\n")
if len(sys.argv) == 1:
print("Error: need to specify model name")
print("Usage: python demo.py your.model")
sys.exit(-1)
model = sys.argv[1]
# capture SIGINT signal, e.g., Ctrl+C
signal.signal(signal.SIGINT, signal_handler)
detector = snowboydecoder.HotwordDetector(model, sensitivity=0.5)
print('Listening... Press Ctrl+C to exit')
# main loop
detector.start(detected_callback=detected,
interrupt_check=interrupt_callback,
sleep_time=0.03)
detector.terminate()
注意添加的 detected
函數(shù)嗅绰。
更復(fù)雜的應(yīng)用形式(如控制 LED 小燈等)也是基本上一樣的思路,具體示例代碼可參考官方文檔搀继。