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