我一直致力于开发一个类似于Siri或Amazon Echo的小型语音识别程序,这样可以简化我家周围的几项小任务。我对bash非常陌生,所以我希望得到一些帮助,减少连续数据流到Google Speech To Text服务器的必要性。目前,我每隔三秒钟录制一个新的音频文件并将其发送到要翻译的Google服务器。这种方法似乎非常低效。这部分代码如下所示。
while :
do
trap CTRLc INT
echo "[speech-recog]: Recording"
(arecord -D $hardware -q -f S16_LE -d $duration -r 16000 | flac - -f --best --sample-rate 16000 -o /dev/shm/out.flac 1>/dev/shm/voice.log 2>/dev/shm/voice.log; curl -s -X POST$
sleep $sleepduration
echo "[speech-recog]: Recording"
(arecord -D $hardware -q -f S16_LE -d $duration -r 16000 | flac - -f --best --sample-rate 16000 -o /dev/shm/out.flac 1>/dev/shm/voice.log 2>/dev/shm/voice.log; curl -s -X POST$
sleep $sleepduration
done
相反,我假设将此脚本语音触发将大大减少网络上的互联网流量。通过语音触发,我的意思是它开始录制音频,以便在听到特定音量或更高音量时发送给Google。如果有人能够提供关于我应该如何创建这个声音触发器或仅仅减少对这些服务器的请求量的建议,那将是非常有帮助的。
此外,当前方法导致一些音频被分成两个或更多个文件,因为录音可能在扬声器开始之前的任何时间开始。听到声音后触发录音也可以解决这个问题。
欢迎任何与我的代码相关的建议。如果需要任何进一步的信息,请在评论中提出要求,我很乐意为您提供您需要了解的任何信息。如果您对我的问题有任何疑问,请发表评论,以便我知道将来不会犯这个错误。 bash脚本如下所示。
注意:此脚本的目的是将Google语音到文本服务器的响应写入名为" SpeechLog.txt"
的文件speech-recog.sh
#!/bin/bash
hardware="plughw:1,0"
duration="3"
sleepduration="3.05"
lang="en"
hw_bool=0
dur_bool=0
lang_bool=0
CTRLc() {
echo "[speech-recog]: Terminating Faide master script. Are you sure (yes/no)?"
read ShouldQuit
if [ ${ShouldQuit^^} = "YES" ]
then
echo "[speech-recog]: Confirmation accepted, terminating script"
sudo python3 Cleanup.py
kill $$
else
echo "[speech-recog]: Denial accepted. Exiting confirmation request"
clear
echo "[speech-recog]: Listening..."
fi
}
for var in "$@"
do
if [ "$var" == "-D" ] ; then
hw_bool=1
elif [ "$var" == "-d" ] ; then
dur_bool=1
elif [ "$var" == "-l" ] ; then
lang_bool=1
elif [ $hw_bool == 1 ] ; then
hw_bool=0
hardware="$var"
elif [ $dur_bool == 1 ] ; then
dur_bool=0
duration="$var"
elif [ $lang_bool == 1 ] ; then
lang_bool=0
lang="$var"
else
echo "[speech-recog]: Invalid option, valid options are -D for hardware and -d for duration"
fi
done
CheckFile() {
LineCount=`cat SpeechLog.txt | wc -l`
if [ $LineCount -gt 1 ]
then
sudo rm /dev/shm/out.flac
sudo python3 VoiceMain.py
fi
}
clear
echo "[speech-recog]: Speech recognition initialized"
echo "[speech-recog]: Listening..."
while :
do
trap CTRLc INT
echo "[speech-recog]: Recording"
(arecord -D $hardware -q -f S16_LE -d $duration -r 16000 | flac - -f --best --sample-rate 16000 -o /dev/shm/out.flac 1>/dev/shm/voice.log 2>/dev/shm/voice.log; curl -s -X POST$
sleep $sleepduration
echo "[speech-recog]: Recording"
(arecord -D $hardware -q -f S16_LE -d $duration -r 16000 | flac - -f --best --sample-rate 16000 -o /dev/shm/out.flac 1>/dev/shm/voice.log 2>/dev/shm/voice.log; curl -s -X POST$
sleep $sleepduration
done
答案 0 :(得分:0)
这是一个广泛的问题,所以我只会在没有实施的情况下提出一个策略。
首先,您需要连续录制以避免丢失任何音频。你可以用
完成这个nohup arecord --max-file-time 1 out.wav &
这应该连续记录,创建许多名为out-01.wav
,out-02.wav
等的1秒wav文件...(我想知道在out-99.wav
之后会发生什么?)1秒似乎是尽可能小。 nohup ... &
使其在后台永远运行。
接下来,您需要一个脚本来按顺序连续检查任何新的完整wav文件。例如,每次下一个wav文件存在时,必须完成当前的文件,因此处理当前文件。
安装sox
并使用
sox out-01.wav -n stats 2>&1 | grep 'RMS lev dB\|RMS Pk dB' | awk '{print $4}'
获取当前wav的平均和峰值音量。如果峰值< -15 dB和lev&lt; -15 dB,可能没有语音,所以删除wav并移动到下一个。 (使用麦克风设置进行测试,以选择峰值和列弗的特定阈值。)
如果音量高于阈值,则不要删除此wav。相反,将其重命名为maybespeech.wav
,然后转到下一个。
如果你连续发现两个超过阈值的wavs(即,当maybespeech.wav
已经存在时你发现一个超过阈值的wav),使用sox
将它们合并到一个新的wav中并替换{ {1}}与合并的wav。然后转到下一个。
如果您在maybespeech.wav
存在时发现低于阈值的wav,那么您已准备好进行语音识别。将其重命名为maybespeech.wav
,maybespeech.done.wav
,将其删除,然后将flac
flac重命名为google speech api。也许唯一地命名flac并在后台进行卷曲,这样就不会阻止下一个wav的处理。