Микрофон и распознавание речи на raspberry pi
-
Ранее было описано как настроить синтезаторы речи 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. Происходит все так:
-
Говорю медленно "Артур" (типа R2 по англиски) , запускается скрипт записи и загорается лампочка.
-
Говорю "сколько время" или "который час" (в базе прописаны все подобные варианты)
-
После этого начинается обработка, делаем скидку на плохой интернет (очень тупой 3Г) , медленная реакция файловой системы (может СД карта такая , пока не знаю)
-
Слушаем ответ типа "Босс время в системе ......".
Очень интересно узнать может кто использует другие варианты ?