Ранее было описано как настроить синтезаторы речи festival и espeak на rasberry pi. http://raspberrypi.ru/blog/readblog/153.html
Сейчас я хочу описать, как преобразовать речь человека , а затем обработать полученные данные.
Хочу сразу заметить , что ни одно готовое решение для Linux найденное в интернете у меня сразу не заработало, все настраивалось экспериментально. Как известно, raspberry pi не имеет входа для микрофона, но это не проблема поскольку можно подключить usb микрофон. Как всегда в магазине микрофона не оказалось и я взял usb камеру со встроенным микрофоном Microsoft VX-800, которая входит в список поддерживаемых устройств на сайте производителя. Начинаем подключать. Для начала надо установить некоторые пакеты, делаем:
#apt-get install v4l-utils sox alsa-tools alsa-oss flac
Запускаем :
#lsusb
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 002: ID 0424:9512 Standard Microsystems Corp.
Bus 001 Device 003: ID 0424:ec00 Standard Microsystems Corp.
Bus 001 Device 004: ID 045e:0766 Microsoft Corp.
Bus 001 Device 005: ID 2341:0043 Arduino SA Uno R3 (CDC ACM)
Наша камера: Bus 001 Device 004: ID 045e:0766 Microsoft Corp.
Камеру увидели, хорошо.
#v4l2-ctl --all
Driver Info (not using libv4l2):
Driver name : uvcvideo
Card type : Microsoft LifeCam VX-800
Bus info : usb-bcm2708_usb-1.2
Driver version: 3.2.27
Capabilities : 0x04000001
Width/Height : 640/480
Pixel Format : 'YUYV'
Field : None
Bytes per Line: 1280
Size Image : 614400
Colorspace : Unknown (00000000)
Crop Capability Video Capture:
Bounds : Left 0, Top 0, Width 640, Height 480
Default : Left 0, Top 0, Width 640, Height 480
Pixel Aspect: 1/1
Video input : 0 (Camera 1: ok)
Streaming Parameters Video Capture:
Capabilities : timeperframe
Frames per second: 30.000 (30/1)
Read buffers : 0
Ну здесь вроде бы все про видео камеру, много всякой информации. Проверяю номер устройства для записи.
#arecord -l
**** List of CAPTURE Hardware Devices ****
card 1: VX800 [Microsoft LifeCam VX-800], device 0: USB Audio [USB Audio]
Subdevices: 1/1 Subdevice #0: subdevice #0 Ну вроде наш микрофон 1,0
Еще можно посмотреть #cat /proc/asound/cards 0 [ALSA ]:
BRCM bcm2835 ALSbcm2835 ALSA - bcm2835 ALSA
bcm2835 ALSA 1 [VX800 ]: USB-Audio - Microsoft LifeCam VX-800
Microsoft Microsoft LifeCam VX-800 at usb-bcm2708_usb-1.2, high speed
И вот теперь начинаются грабли, что хорошо работало в других версиях Linux на РС здесь никак не хочет.
В пакет Sox входять утилиты sox, play и rec, так вот если sox и play запустить получилось, то rec ни в какую микрофон видеть не хочет. Запуск play.
#export AUDIODEV="hw:0"
#play test.wav
вот так работает.
Откровенно говоря и не надо , у нас есть arecord. Делаем запись с указанными параметрами, почему именно так - не знаю , но так любит googl.
#arecord -B --buffer-time=1000000 -f dat -r 16000 -d 4 -D plughw:1,0 send.wav
Теперь расшифрую:
-B --buffer-time=1000000 - какой то буфер , о нем описано в --help, если его не ставить то будет ошибка overrun!!!(...) и google не распознает, причем это происходит не всегда, но хочется иметь какую то стабильность.
-f dat - без этой команды пишет 8 бит запись ,а с этой 16 бит
-r -- sample rate 16000 опять же google любит -d 4 -- длительность записи 4 сек , мне хватает чтобы сказать фразу из двух трех слов -D plughw:1,0 -- а это , что называется за что боролись, наш микрофон.
send.wav - файл куда пишем.
Если все правильно , то при запуске на камере загорается светодиод на 4 сек и в этот момент надо что то сказать.
Проверка: #aplay send.wav
Теперь надо преобразовать в формат flac , так любит google, делаем:
#flac -f -s send.wav -o send.flac
Вот теперь у нас два файла send.flac и send.wav , .wav можно удалить.
Теперь с помощью PHP надо отослать этот файл на сервер google для расшифровки. Просто я больше PHP предпочитаю.
$file_to_upload = array('myfile'=>'@./send.flac');
$ch = curl_init();
// в конце строки надо указать lang=ru-RU или en-US для английского
curl_setopt($ch, CURLOPT_URL,"https://www.google.com/speech-api/v1/recognize?xjerr=1&client=chromium&lang=ru-RU");
curl_setopt($ch, CURLOPT_POST,1);
curl_setopt($ch, CURLOPT_TIMEOUT,15);
curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-Type: audio/x-flac; rate=16000"));
curl_setopt($ch, CURLOPT_POSTFIELDS, $file_to_upload);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
$result=curl_exec ($ch);
echo $result."\n";
В ответ получим много всякой информации, в том числе и необходимую нам расшифровку. Ниже метод как пропарсить строку:
if(strlen($result) > 3 )
// if coonect and get response
{
$fm_google=substr($result,strpos($result,"utterance")+12,strpos($result,"confidence")-27 - strpos($result,"utterance")+12);
}
кто-то может использовать другой метод ,более эффективный, я буду только рад за подсказку. Теперь полученный ответ кажды может использовать на свое усмотрение , я например использую базу MySQL с набором вопросов и ответов.
Самый простой вариант в РНР:
system("espeak -ven -s 160 -g 5 \"".$fm_google."\" 2> /dev/null &");
а можно какой то скрипт запустить. Пример. Запускаем скрипт и говорим "сколько время".
#!/usr/bin/php5
system("arecord -B --buffer-time=1000000 -f dat -r 16000 -d 4 -D plughw:1,0 send.wav");
system("flac -f -s send.wav -o send.flac");
$file_to_upload = array('myfile'=>'@./send.flac');
$ch = curl_init();
// в конце строки надо указать lang=ru-RU или en-US для английского
curl_setopt($ch, CURLOPT_URL,"https://www.google.com/speech-api/v1/recognize?xjerr=1&client=chromium&lang=ru-RU");
curl_setopt($ch, CURLOPT_POST,1);
curl_setopt($ch, CURLOPT_TIMEOUT,15);
curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-Type: audio/x-flac; rate=16000"));
curl_setopt($ch, CURLOPT_POSTFIELDS, $file_to_upload);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
$result=curl_exec ($ch);
if(strlen($result) > 3 )
// if coonect and get response
{
$fm_google=substr($result,strpos($result,"utterance")+12,strpos($result,"confidence")-27 - strpos($result,"utterance")+12); }
if($fm_google=="сколько время")
{
// указываем скрипт , сообщающий время
system("./gettime.sh");
}
У меня эта связка работает совместно с Arduino UNO и подключенным к нему sound sensor. Происходит все так:
1. Говорю медленно "Артур" (типа R2 по англиски) , запускается скрипт записи и загорается лампочка.
2. Говорю "сколько время" или "который час" (в базе прописаны все подобные варианты)
3. После этого начинается обработка, делаем скидку на плохой интернет (очень тупой 3Г) , медленная реакция файловой системы (может СД карта такая , пока не знаю)
4. Слушаем ответ типа "Босс время в системе ......".
Очень интересно узнать может кто использует другие варианты ?
Комментариев: 12
m
13.03.2013 в 22:30 ответГоворить с английским акцентом что-ли надо? Гугл нормальную русскую речь не понимает?
foxter6
14.03.2013 в 09:11 ответА если подключить sound sensor напрямую к малинке? думаю проблем не должно возникнуть
JackM10
14.03.2013 в 12:02 ответSound sensor -- выход аналоговый
foxter6
14.03.2013 в 15:11 ответА если прицепить компаратор и включать запись при каком-то уровне ?
JackM10
14.03.2013 в 18:56 ответОткровенно говоря я не пробовал c компаратором. Время реакции ардуино вполне устраивает, он к тому же передает еще много разных параметров. ADC на ардуино последовательный имеет 10 бит , это дискретность 1024, sound sensor выдает максимальный уровень 650, программно я подобрал срабатывание типа: if(Soundsensor > 550) { system("record.sh"); } Этого достаточно чтобы скрипт срабатывал с расстояния 2-3 метров.
JackM10
14.03.2013 в 12:03 ответС русской речью гугл вроде нормально распознает, только голос сына не хочет понимать.
alex.spb11
18.03.2013 в 12:07 ответОчень интересный пост! Хочу попробовать прикрутить аналогичное распознование речи. Но в качестве АЦП буду использовать беспроводные приемо-передатчики XRF от Ciseco (дешевый аналог Xbee). Какой sound sensor использовался? И сколько примерно времени уходит от момента произнесения команды до получения строки распознования?
JackM10
19.03.2013 в 20:50 ответКакой сенсор точно сказать не могу ,заказывал через электронщик ., название было Grove - Sound Sensor. Ардуино висит на скорости 115200 ,довольно быстро работает, поэтому после первого слова включается запись, примерно так: "робот , как тебя зовут" -- после слова "робот" включается запись.
tubsids3
23.03.2013 в 21:55 ответспасибо за описание! Вопрос: Как проводится распознавание? Команды выполнять на ардуино? зачем конвертирование на гуугле?
crazysova7
20.09.2013 в 18:33 ответПоследние строчки я бы использовал так if(strstr($fm_google,"время")){system("./time.sh");} if(strstr($fm_google,"вконтакте")){system("opera vk.com");}
sonoleo
06.07.2016 в 23:53 ответДоброго времени суток! Я споткнулся в самом начале. <Откровенно говоря и не надо, у нас есть arecord. Делаем запись с указанными параметрами, почему именно так — не знаю, но так любит googl. #arecord -B --buffer-time=1000000 -f dat -r 16000 -d 4 -D plughw:1,0 send.wav> Эта команда выдает ошибку main:682 нет такого файла или директории. У меня Raspberry Pi 2. Операционка rasbian. Хочу записывать через гуглу. И уж затем обрабатывать и распознавать информацию из текстовых файлов. Помогите!!! Третью неделю сижу с этой проблемкой.
Canabalt
07.07.2016 в 18:15 ответнапишите мне в лс в вк vk.com/daniilsmirnov163.Я прошел весь этот путь и готовлю статью о голосовом управлении