Высокий микрофонный вход срабатывает Bash

Я работал над созданием небольшой программы распознавания голоса, похожей на 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 Speech на текстовые серверы в файл с именем "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

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. если пик <-15 дБ и lev <-15 дБ, вероятно, нет речи, поэтому удалите wav и переходите к следующему. (проверьте с настройкой вашего микрофона, чтобы выбрать конкретные пороговые значения для пика и лев.)

если громкость выше порога, то не удаляйте этот wav. вместо этого переименуйте его в maybespeech.wav, затем перейдите к следующему.

если вы найдете два выше пороговых wav подряд (т.е. вы найдете выше порогового wav, когда maybespeech.wav уже существует), используйте sox объединить их в новый WAV и заменить maybespeech.wav с объединенным WAV. затем перейдите к следующему.

если вы найдете WAV ниже порога, когда maybespeech.wav существует, тогда вы готовы сделать некоторое распознавание речи. переименуйте его в maybespeech.done.wav, flac это, удалить его, и curl Flac для Google речи API. возможно, уникально назовите flac и сделайте скручивание в фоновом режиме, чтобы это не блокировало обработку следующего wav.

удачи!

Другие вопросы по тегам