В этой статье я хочу рассказать о своем опыте изготовления голосового ассистента на RasPI.Всем кому интересно,прошу под кат.

Предисловие

В не столь далеком детстве во время просмотра фильма "Железный человек" у меня появилась маленькая мечта,сделать свой Джарвис с блекджеком и скриптами.И вот спустя 4 года я снова загорелся желанием,а наличие дома RasPI 3 выигранной в майском конкурсе только подстегнуло интерес и желание.

Начинаем

Дисклеймер.Все что вы делаете,делается вами на ваш страх и риск.Я лишь описываю вам свой опыт и впечатления.

Нам понадобиться:

  • Звуковая карта с чипом от C-Media
  • Колонка
  • Микрофон
  • Raspberry Pi
  • Интернет соединение

и много,очень много свободного времени.

Шаг 1.Подготовим систему,установим софт

Подключаем звуковую карту со всей периферией

Логинимся в систему

У меня не получилось по хорошему заставить работать звуковую карту как нужно(Может я криворукий,может гайды в интернете старые) потому я наглым способом вырубил встроенный аудиочип

cd /etc/modprobe.d
sudo nano alsa-blacklist.conf

и добавляем строку

blacklist snd_bcm2835

и перезагружаемся

sudo reboot

После этих махинаций запускаем команду

aplay -l

На экране должны увидит,что-то похожее на то,что на скрине с моей системы

Также можно через GUI убедиться,что звуковая карта назначена по умолчанию

Для регулировки звука можно воспользоваться

alsamixer

Установим синтезатор речи

sudo apt install festival festvox-ru

Перейдем в домашнюю директорию

cd ~/

Создадим конфиг Festival

sudo nano .festivalrc

и внесем в него эти строки

 (Parameter.set 'Audio_Command "aplay -Dplug:default -q -c 1 -t raw -f s16 -r $SR $FILE")
(Parameter.set 'Audio_Method 'Audio_Command)

А теперь попробуем что нибудь сказать

echo "Проверка" | festival --tts --language russian

От ввода команды до произношения обычно проходит от 5 до 30 секунд.Медленно,но довольно качественно.

Если услышали мужской голос из динамика,значит у нас все получилось

Установим Python3

 sudo apt-get install python3

И модули для него

pip3 install SpeechRecognition
pip3 install pocketsphinx

Шаг 2.Скриптовая часть

Для начала проверим,а работает ли у нас микрофон то вообще?

arecord -B --buffer-time=1000000 -f dat -r 16000 -d 4 -D plug:default voice.wav

Говорим что нибудь 4 секунды.

aplay voice.wav -Dplug:default

Слышим себя?Если да,то все прекрасно.

Рекомендую создать отдельную директорию под проект.Я использовал имя '0' (ноль)

cd 0

Запишем основной и самый главный скрипт

sudo nano 0.py
#! /usr/bin/env python
#-*-coding:utf-8-*-
import os
import speech_recognition as sr
r = sr.Recognizer()
with sr.WavFile("voice.wav") as source:              # use "test.wav" as the audio source
    audio = r.record(source)                        # extract audio data from the file

try:
    t = r.recognize_google(audio,language = "ru-RU", key = "AIzaSyBOti4mM-6x9WDnZIjIeyEU21OpBXqWBgw")
    print(t)   # recognize speech using Google Speech Recognition
except LookupError:                                 # speech is unintelligible
    print("Could not understand audio")
if t  == 0:
     print("Error")
elif t==("Привет"): #Hi
    os.system('echo Привет | festival --tts --language russian')

Далее используя аудиозапись из прошлых шагов попробуем что либо распознать

python3 0.py

Если на выводе уводили тот текст,что содержится в записи,то все успешно распозналось(У меня распознает все точно в 99% случаев)

и запускалку для этого скрипта

sudo nano launcher
#!/bin/bash
echo "Ассист+ент зап+ущен" |festival --tts --language russian
while [ true ]
do
arecord -B --buffer-time=1000000 -f dat -r 16000 -d 4 -D plug:default voice.wav
filesize=$(stat -c%s "voice.wav")
echo $filesize
python3 0.py
rm voice.wav
echo completed
done
sudo chmod +x launcher

и запустим

./launcher

Прервать адский круг можно долгим зажатием CTRL+C

Шаг 3.Запускалка запускалки

Для удобства я сделал запускалку запускалки

sudo nano launcher
#!/bin/bash
while [ true ]
do
arecord -B --buffer-time=1000000 -f dat -r 16000 -d 4 -D plug:default voice.wav
filesize=$(stat -c%s "voice.wav")
echo $filesize
python3 z.py
rm voice.wav
echo completed
done
sudo chmod +x launcher
sudo nano z.py

import os
import speech_recognition as sr
#Recognizer(language = "ru-RU", key = "AIzaSyBOti4mM-6x9WDnZIjIeyEU21OpBXqWBgw")
r = sr.Recognizer()
with sr.WavFile("voice.wav") as source:              # use "test.wav" as the audio source
    audio = r.record(source)                        # extract audio data from the file

try:
    t = r.recognize_sphinx(audio)
    print(t)   # recognize speech using Google Speech Recognition
except LookupError:                                 # speech is unintelligible
    print("Could not understand audio")
if t==("hi"):
   os.system('~/0/assistant')

Как можно понять из скриптов,то запускать основной наш скрипт будут только после "hi".Но вот беда,распознает оффлайн утилита очень-очень плохо.Я частично исправил положение наглым выпиливанием половины словаря программы.

cd /usr/local/lib/python3.4/dist-packages/speech_recognition/pocketsphinx-data/en-US
sudo nano pronounciation-dictionary.dict 

А теперь нам придется попотеть.Удалим из словаря все не нужное.Кому лень это делать,может написать мне в лс,я скину файлик.

И вот после всего этого запускалка начала более менее по божески работать

cd ~/0
sudo nano 0.py

В конец файла добавим

elif t==("сон"): #Sleep
    os.system('~/0/launcher')

Сохраним

Шаг3.А вы верите в скрипты?

в директории 0 создадим еще одну

mkdir scripts
cd scripts

и создадим скриптик для того,чтобы нам по запросу говорили,какова погода на улице

sudo nano forecast
#!/bin/sh

URL='http://www.accuweather.com/en/ru/tolyatti/295302/weather-forecast/295302'

wget -q -O- "$URL" | awk -F\' '/acm_RecentLocationsCarousel\.push/{print "сейчас на улице ",$12, "градусов"}'| head -1

Содержимое строки URL меняем на нужное вам местоположение с этого же сайта

Сделаем говорилку для этого скрипта

sudo nano weather
#!/bin/sh
~/0/scripts/forecast | festival --tts --language russian

и наконец в скрипт 0.py добавим еще одно ветвление для IF

cd ~/0
sudo nano 0.py
elif t==("Какая сейчас погода"): #weather
    os.system('~/0/scripts/weather')
elif t==("погода"):
    os.system('~/0/scripts/weather')
elif t==("Какая погода"):
    os.system('~/0/scripts/weather')

Вооот собственно и все пожалуй.Вопросы и пожелания можете написать в комментарии или личные сообщения,а также в вк(указано в профиле).Если напишите какой либо скриптик для этого управления,то тоже пишите,добавлю в статью с подписью вашего авторства.

Благодарности

Спасибо администрации Raspberrypi.ru

Михаилу

Андрею

За помощь в создании проекта

Фото устройства в собранном виде

В дырочке спрятался микрофон :)

Статья будет обновляться,обязательно будет,так как я не считаю это проект завершеным.

Тэги:

 

Автор:

Комментариев: 15

  • raspiman
    07.07.2016 в 20:08 ответ

    Корпус зачётный! Копите на 3D-принтер, полезная в творчестве штука :) P.S — а можете проверить, есть ли звук с этой звуковой карты при проигрывании видео через VLC, который собирался в этой статье — raspberrypi.ru/blog/632.html

    • Canabalt
      07.07.2016 в 23:38 ответ

      Проверил, работает.Проверял .flac аудиозаписью. Корпус — это шедевр!)

      • m
        08.07.2016 в 04:27 ответ

        Аудио понятное дело, что будет работать. Интересует именно момент с видео.

      • m
        08.07.2016 в 06:56 ответ

        Аудио понятное дело, что будет работать. Меня тоже интересует именно момент воспроизведения звука в видео.

        • Canabalt
          08.07.2016 в 11:34 ответ

          Разве есть разница? Аудио то он похоже через Alsa выводит. Буду снова собирать себе vlc и проверять.Отпишусь после проверки

        • Canabalt
          08.07.2016 в 16:57 ответ

          Звук есть

  • sonoleo
    13.07.2016 в 23:09 ответ

    Доброго времени суток. У меня проблемы с созданием файла .WAV через микрофон. Микрофон подключается через внешнюю ауди карту (специально для Raspberry). По команде arecord -l выдает pi@raspberrypi ~ $ arecord -l **** List of CAPTURE Hardware Devices **** card 0: Device [USB PnP Sound Device], device 0: USB Audio [USB Audio] Subdevices: 1/1 Subdevice #0: subdevice #0 А по команде: #arecord -B --buffer-time=1000000 -f dat -r 16000 -d 4 -D plughw:1,0 test.wav или #arecord -B --buffer-time=1000000 -f dat -r 16000 -d 4 -D plug:default test.wav Выдает ошибку: arecord: main:682: audio open error: No such file or directory. Файл test.wav создан заранее пустой. Была попытка указать имя не существующего файла — результат такой же. Предварительно я перешел в каталог: cd /home/pi/Voice тут сидят мои файлы. В чем может быть проблема?

  • Accente
    09.12.2016 в 15:10 ответ

    Так. А вот эту канитель надо испробовать на Cubieboard.

  • ivan
    22.02.2017 в 19:41 ответ

    Всем привет. У меня такой вопрос. Может Raspberry, при загрузке необходимых программ, работая автономно без компьютера, интернета, wi-fi, работать как голосовое общение с Raspberry еще и подключить какие нибудь выходные устройства, да и чтобы общение было на русском языке.

  • cccp812
    14.06.2017 в 13:52 ответ

    Здравствуйте, у меня возникла вот такая проблема:pi@raspberrypi:~/0 $ ./launcherarecord: main:722: audio open error: Нет такого файла или каталога184044Traceback (most recent call last):  File "/usr/local/lib/python3.4/dist-packages/speech_recognition/__init__.py", line 651, in recognize_sphinx    from pocketsphinx import pocketsphinxImportError: No module named 'pocketsphinx'During handling of the above exception, another exception occurred:Traceback (most recent call last):  File "z.py", line 17, in <module>    t = r.recognize_sphinx(audio)  File "/usr/local/lib/python3.4/dist-packages/speech_recognition/__init__.py", line 653, in recognize_sphinx    raise RequestError("missing PocketSphinx module: ensure that PocketSphinx is set up correctly.")speech_recognition.RequestError: missing PocketSphinx module: ensure that PocketSphinx is set up correctly.completedarecord: main:722: audio open error: Нет такого файла или каталогаstat: не удалось выполнить stat для «voice.wav»: Нет такого файла или каталогаподскажите пожалуйста, как решить?Спасибо.

  • cccp812
    14.06.2017 в 13:56 ответ

    Здравствуйте, у меня возникла вот такая проблема:pi@raspberrypi:~/0 $ ./launcherarecord: main:722: audio open error: Нет такого файла или каталога184044Traceback (most recent call last):  File "/usr/local/lib/python3.4/dist-packages/speech_recognition/__init__.py", line 651, in recognize_sphinx    from pocketsphinx import pocketsphinxImportError: No module named 'pocketsphinx'During handling of the above exception, another exception occurred:Traceback (most recent call last):  File "z.py", line 17, in <module>    t = r.recognize_sphinx(audio)  File "/usr/local/lib/python3.4/dist-packages/speech_recognition/__init__.py", line 653, in recognize_sphinx   raise RequestError("missing PocketSphinx module: ensure that PocketSphinx is set up correctly.")speech_recognition.RequestError: missing PocketSphinx module: ensure that PocketSphinx is set up correctly.completedarecord: main:722: audio open error: Нет такого файла или каталогаstat: не удалось выполнить stat для «voice.wav»: Нет такого файла или каталогаподскажите пожалуйста, как решить?Спасибо.

    • valway
      26.06.2017 в 22:27 ответ

      Попробуйте так: arecord -B --buffer-time=1000000 -f dat -r 16000 -d 4 -D plughw:0,0 voice.wav поиграйте с plughw:1,0

  • DB
    17.10.2017 в 12:31 ответ

    Добрый день. У меня Raspberry Pi 2, внешней звуковой карты нет. Установил festival, пробую тестовую команду  echo "test" | festival --tts , получаю ошибку pipe_open: fork failed. После перезагрузки все-таки команда сработала, слово "test" я услышал). Но при попытке выполнить команду снова - та же ошибка ((. Что это может значить? Поверхностно "погуглив" толкового ответа не нашел. ps подскажите, почему такая пауза большая между вводом команды и произношением? Спасибо

  • ivan
    03.03.2019 в 09:37 ответ

    Всем привет. Можете сказать сколько времени уходит после произношения команды до ее выполнения.

  • Hakim
    08.04.2020 в 08:52 ответ

    arecord -B --buffer-time=1000000 -f dat -r 16000 -d 4 -D plug:default voice.wav - не пошел. потому что 0.py ругнулся на audio samples must be 16-bit поправил на arecord --buffer-time=1000000 -f cd dat -r 16000 -d 4 -D plug:default voice.wav

Ваш комментарий

Авторизуйтесь для отправки комментария

© Сообщество пользователей RaspberryPi 2021