-2

我一直在开发一个类似于 Siri 或 Amazon Echo 的小型语音识别程序,它可以让我简化家中的一些小任务。我对 bash 非常陌生,因此我需要一些帮助,以减少将连续数据流向 Google Speech To Text 服务器的必要性。目前,我每三秒录制一个新的音频文件并将其发送到谷歌服务器进行翻译。这种方法似乎效率很低。这部分代码如下所示。

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 Speech to Text 服务器的响应写入名为“SpeechLog.txt”的文件中

语音识别.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
4

1 回答 1

1

这是一个广泛的问题,所以我只会提出一个战略而不实施它。

首先,您需要连续录制以避免丢失任何音频。你可以用

nohup arecord --max-file-time 1 out.wav &

这应该连续记录,创建许多 1 秒的 wav 文件,命名为out-01.wav,out-02.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 的平均和峰值音量。如果 peak < -15 dB 且 lev < -15 dB,则可能没有语音,因此删除 wav 并移至下一个。(使用您的麦克风设置进行测试,以选择峰值和 lev 的特定阈值。)

如果音量高于阈值,则不要删除此 wav。相反,将其重命名为maybespeech.wav,然后继续下一个。

如果您连续找到两个高于阈值的 wav(即,如果maybespeech.wav已经存在一个高于阈值的 wav),请使用sox将它们合并为新的 wav 并替换maybespeech.wav为合并的 wav。然后移动到下一个。

如果您发现存在低于阈值的 wav maybespeech.wav,那么您就可以进行一些语音识别了。将其重命名为maybespeech.done.wav, flacit, delete it, 并将curlflac 重命名为 google speech api。也许可以唯一地命名flac并在后台进行curl,这样就不会阻止下一个wav的处理。

祝你好运!

于 2016-06-29T08:56:10.593 回答