Микрофон и распознавание речи на raspberry pi

Ранее было описано как настроить синтезаторы речи festival и espeak на rasberry pi.
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. Слушаем ответ типа «Босс время в системе ......».

Очень интересно узнать может кто использует другие варианты?
  • 0

Комментарии (14)

0
Говорить с английским акцентом что-ли надо? Гугл нормальную русскую речь не понимает?
0
А если подключить sound sensor напрямую к малинке? думаю проблем не должно возникнуть
0
Sound sensor -- выход аналоговый
0
А если прицепить компаратор и включать запись при каком-то уровне ?
0
Откровенно говоря я не пробовал c компаратором. Время реакции ардуино вполне устраивает, он к тому же передает еще много разных параметров. ADC на ардуино последовательный имеет 10 бит , это дискретность 1024, sound sensor выдает максимальный уровень 650, программно я подобрал срабатывание типа: if(Soundsensor > 550) { system("record.sh"); } Этого достаточно чтобы скрипт срабатывал с расстояния 2-3 метров.
0
С русской речью гугл вроде нормально распознает, только голос сына не хочет понимать.
0
Очень интересный пост! Хочу попробовать прикрутить аналогичное распознование речи. Но в качестве АЦП буду использовать беспроводные приемо-передатчики XRF от Ciseco (дешевый аналог Xbee). Какой sound sensor использовался? И сколько примерно времени уходит от момента произнесения команды до получения строки распознования?
0
Какой сенсор точно сказать не могу ,заказывал через электронщик ., название было Grove - Sound Sensor. Ардуино висит на скорости 115200 ,довольно быстро работает, поэтому после первого слова включается запись, примерно так: "робот , как тебя зовут" -- после слова "робот" включается запись.
0
спасибо за описание! Вопрос: Как проводится распознавание? Команды выполнять на ардуино? зачем конвертирование на гуугле?
0
Последние строчки я бы использовал так if(strstr($fm_google,"время")){system("./time.sh");} if(strstr($fm_google,"вконтакте")){system("opera vk.com");}
0
Доброго времени суток! Я споткнулся в самом начале.
<Откровенно говоря и не надо, у нас есть 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. Хочу записывать через гуглу. И уж затем обрабатывать и распознавать информацию из текстовых файлов.
Помогите!!! Третью неделю сижу с этой проблемкой.
0
напишите мне в лс в вк vk.com/daniilsmirnov163.Я прошел весь этот путь и готовлю статью о голосовом управлении
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.