用樹莓派打造自己的對話式智能家居控制中心——Hi,Messy(二)

日常前言

項目教程目錄:https://blog.csdn.net/qq_41082014/article/details/86605663

第一篇的喚醒相信度娘搜一下關鍵詞snowboy都能出現與之相似的內容,但是能度娘到的關於snowboy的信息也僅限與此,相信很多人和我當初一樣,雖然能喚醒了,但是做不了更多的事情,比如喚醒之後想錄個音,或者用pygame、mplayer這樣的工具放首歌,snowboy都會直接終止進程,報錯無設備,必須要重啓才能解決。
                      在這裏插入圖片描述
  So,作爲Hi,Messy的第二篇文章,便來出手解決這個問題

先找官方

官方文檔

官方文檔地址,一圈蒐羅後,官方文檔只介紹瞭如何進行單次喚醒和怎麼使用它們的webapi,沒什麼用。

官方demo

那官方文檔裏找不到,記得官方的資源裏面好像有幾個demo,去看看呢。誒,果真就在demo裏面發現了官方寫的錄音的代碼,下圖是官方介紹
在這裏插入圖片描述
  核心代碼如下,官方是使用的speech_recognition這麼一個庫,然後用內置的谷歌的語音識別api進行識別。親自上手後發現,這個庫錄音的數據類型是庫自己定義的<class 'speech_recognition.AudioData'>目前找不到方法存儲爲文件,而且谷歌嘛,我也出不去,只好放棄官方的方案。
在這裏插入圖片描述在這裏插入圖片描述
  detector.start的參數audio_recorder_callback的官方定義是當觸發喚醒詞後,保存後續的短語,偶然間發現,他是能保存錄音文件,再看看官方demo,發現官方的demo是在使用speech_recognition後又把這個文件給刪除了,醉了。本來以爲到這裏就可以結束了,但後面又發現,只能指定一個時間進行錄音,功能太侷限,所以,直接放棄官方,自尋出路!
                      在這裏插入圖片描述

定製開始

好了,前面寫了那麼多,我只是想把過程給記錄下來,讓童鞋們少走彎路。接下來,正片開始。
  
  先把我們需要的文件從官方里拷出來,一共5個文件,一個文件夾。拷完之後,git下來的snowboy這個文件夾就可以刪除了。

cp yuyin/snowboy/examples/Python3/snowboydetect.py yuyin/alexa/
cp yuyin/snowboy/resources/alexa/alexa-avs-sample-app/alexa.umdl yuyin/alexa/
cp yuyin/snowboy/examples/Python3/demo.py yuyin/alexa/alexa.py

cp -r yuyin/snowboy/resources yuyin/alexa/func_alexa
cp yuyin/snowboy/swig/Python3/_snowboydetect.so yuyin/alexa/func_alexa
cp yuyin/snowboy/swig/Python3/snowboydecoder.py yuyin/alexa/func_alexa

先把目錄結構建起來,最終效果如下圖(如有不知道的目錄,手動建一下,後續需要使用)

  • 根目錄
    在這裏插入圖片描述
  • music_messy
    在這裏插入圖片描述

定製靈魂功能

鋪墊了這麼多,終於來到了最關鍵的步驟,喚醒後,錄製一段音頻。前面說過了,只錄音的功能太過侷限,所以接下來,我們要做的是可不止錄音這麼簡單

  • 代碼結構闡述
    • 進入第一個循環,根據當前環境的音量是否高於閾值(判斷是否有聲音輸入)
    • 若有,進入第二個循環,判斷當前環境的音量是否低於閾值(判斷錄入是否結束),若低於,則兩個循環都結束
    • 若第一個循環進行5s後,依然無聲音輸入,則循環結束(判斷超時)

開錘代碼

核心功能:判斷聲音大小

# func_messy/volume.py

import pyaudio
import numpy as np

# 定義錄製聲音的參數
CHUNK = 180
FORMAT = pyaudio.paInt16
CHANNELS = 1
RATE = 16000
RECORD_SECONDS = 5

def volume():
    p = pyaudio.PyAudio()
    stream = p.open(format=FORMAT,
                channels=CHANNELS,
                rate=RATE,
                input=True,
                frames_per_buffer=CHUNK)
    while 1:
        for i in range(0, 100):
            data = stream.read(CHUNK)
        audio_data = np.fromstring(data, dtype=np.short)
        temp = np.max(audio_data)
        print(temp)

volume_detection()

這個可以直接在本地pc跑下試試,一般來說 0-500 就是正常的環境聲音數值,500-1w 就是有人說話的數值了,1w以上基本就是和麥克風嘴對嘴講話了在這裏插入圖片描述(錄音文件的完整代碼查看GIT [ 完整功能:代碼結構闡述最終保存錄音文件]
在這裏插入圖片描述

調用錄音功能,重頭戲來了!!!

我們複製過來的demo中有這樣一段代碼,我們在這裏調用方法進行替換
在這裏插入圖片描述

# alexa.py
import volume
detector = snowboydecoder.HotwordDetector(model, sensitivity=0.5)

def main():
	detector.terminate()
	volume.volume()
	
detector.start(detected_callback=main,
               interrupt_check=interrupt_callback,
               sleep_time=0.03)
detector.terminate()

注意到第五行的detector.terminate()了嗎,這是snowboy官方定義的結束喚醒程序的函數(snowboydecoder.py的最後),該條代碼很重要,因爲snowboy已經在內部使用pyaudio庫,如果這時在手動調用pyaudio,會造成三種情況:

  • 一:錄下來的文件沒有聲音
  • 二:系統直接提示未知的媒體設備(Device unavailable)
  • 三:snowboy程序被擠掉,系統提示無媒體設備(No available audio device)

當detector.start的循環被終止的時候,可以看到,接下去的一句就是使用這個函數來終止整個程序。但是,這麼重要的一個函數,度娘完全沒有搜到過,就連官方自己都沒說,還是最後查閱源碼文件才知道的…

再次喚醒

python3 alexa.py alexa.umdl
如果直接用的我的GIT上的項目代碼的話,應該是可以看到在music_messy/said/看到i_said.wav這個文件,打開即可聽到自己的聲音咯

最後

在碼代碼的過程中還是會經常出現Device unavailable的錯誤,只好把需要用到媒體設備的代碼全部放到不報錯的地方。後來知道是pulseaudio沒有啓動的問題,但我一直啓動不了這個東西
在這裏插入圖片描述

如果有大佬知道,可以評論一下或者加q羣q我(576072252),謝謝

本文作者: Messy
原文鏈接:https://www.messys.top/detail/24
版權聲明: 本博客所有文章除特別聲明外, 均採用 CC BY-NC-SA 4.0 許可協議. 轉載請註明出處!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章