«Умный дом» собственными руками. Часть 3. Синтез и распознавание голоса с помощью Google

    В прошлой статье мы смогли добиться получения изображения с наших веб-камер в виде снимков раз в секунду. Теперь пришла пора взяться за обещанное — распознавание и синтез голоса.

    Небольшое отступление


    Начиная с этой статьи я начну описывать свое ПО, которое занимается координированием всех подсистем «умного дома». Считаю необходимым отметить, что уже ушел достаточно далеко от описываемого в этой статье кода, с более новыми и функциональными версиями можно ознакомиться через trac — ссылка. Распространение осуществляется под лицензией GNU GPLv3. Если кто-то пожелает присоединиться к разработке — милости прошу ;)

    Немного информации



    Распознавание речи

    Как я уже писал в первой статье, для синтеза и распознавания голоса мы воспользуемся сервисами компании Google. Я думаю, многие сталкивались на мобильных устройствах под управлением ОС Android с голосовым поиском. Как дополнительная функцию, этот самый голосовой поиск был добавлен в браузер Google Chrome. Следует заметить, что официального API для этого сервиса компания еще не анонсировала, но благодаря открытым исходникам Chrome, народные умельцы нашли, что и куда посылается и что и как отдается в ответ. Выглядит это так:

    1. Записываем wav-файл с частотой дискретизации звука 16000 Гц, моно
    2. Перекодируем получившийся файл в формат flac
    3. Отсылаем файл по адресу https://www.google.com/speech-api/v1/recognize?xjerr=1&client=chromium&lang=ru-RU, представлясь гуглу клиентом Chrome
    4. Получаем ответ в формате JSON


    Ответ представляет собой нечто вида:

    {"status":0,"id":"84e03bf4efe17fa7856333560d6faba4-1","hypotheses":[{"utterance":"раз два три","confidence":0.85437811}]}

    Нас интересуют в ответе лишь два последних поля — utterance и confidence. Первое является искомой распознанной словом/фразой, второе — достоверностью распознавания. Если confidence будет более 0.5, можно считать, что распознавание достоверно.

    Синтез речи

    Синтез речи будет так же осуществляться через сервис Google и к нему так же, насколько я знаю, не анонсировано официального API. Чтобы получить звуковую фразу из текста нужно произвести совсем не сложную комбинацию действий:

    1. Отправить запрос вида: http://translate.google.com/translate_tts?tl=ru&q=текст, представлясь браузером Google Chrome в заголовках
    2. Получить ответом поток в MP3-кодировании


    Как видите, тут все совсем не сложно. Теперь реализуем эту информацию программно.

    Немного кода


    Как я уже писал, заниматься централизованным управлением нашего «умного дома» будет специально написанный демон на perl. Заранее прошу за качество кода не бить ногами, ибо ваш покорный слуга всего лишь сисадмин :)
    Итак, определимся с кругом задач, которое должно выполнять данное ПО:

    1. Принимать запросы на распознавание звуковых файлов
    2. Определять состояния устройств, подавать им команды
    3. Выполнять какие-то действия, если обнаружена командная последовательность
    4. Реагировать заданным образом на данные с датчиков и камер
    5. Вести статистику, учет и логи
    6. Иметь удобный web-интерфейс для просмотра состояния, камер, дачи команд и пр.


    Возможно, я что-то забыл или пропустил, но, как мне кажется, это основные задачи ПО «умный дом». Теперь начнем реализовывать все это.

    Для создания на perl TCP/IP-демона воспользуемся модулем Net::Server::Fork. Я буду исходить из предположения, что язык perl вам уже знаком.
    #!/usr/bin/perl -w
    
    package iON;
    
    use strict;
    use utf8;
    
    use base qw(Net::Server::Fork);
    
    sub process_request
    {
    	my $self = shift;
    
    	while (<STDIN>)
    	{
    		if (/text (\d+)/) { toText($1); next; }
    		if (/quit/i) { print "+OK - Bye-bye ;)\n\n"; last; }
    
    		print "-ERR - Command not found\n";
    		logSystem("Неизвестная команда: $_", 0);
    	}
    }
    
    iON->run(port => 16000, background => undef, log_level => 4, host => 'localhost');
    
    1;
    
    Кратко пробежимся, по тому, что тут написано. Мы объявляем себя модулем с именем iON на базе модуля Net::Server::Fork и запускаем сервер на порту 16000 на localhost с максимальным уровнем детализации логов и без режима «демон». Далее, перегружаем функцию process_request(). Она отвечает за обработку полученных данных от клиента. В нашем случае, если сервер видит текст формата text число — выполняется функция toText c параметрами в виде числа, которое послал нам клиент. С командой quit, думаю все ясно.

    Чем же занимается функция toText()? Да собственно, распознаванием речи!
    sub toText
    {
    	my $num = shift;
    
    	print "+OK - Trying recognize text\n";
    
            my $curl = WWW::Curl::Easy->new;
    
            $curl->setopt(CURLOPT_HEADER,1);
    	$curl->setopt(CURLOPT_POST,1);
    	#$curl->setopt(CURLOPT_VERBOSE, 1);
    
    	my @myheaders=();
    	$myheaders[0] = "Content-Type: audio/x-flac; rate=16000";
    
    	$curl->setopt(CURLOPT_HTTPHEADER, \@myheaders);
            $curl->setopt(CURLOPT_URL, 'https://www.google.com/speech-api/v1/recognize?xjerr=1&client=chromium&lang=ru-RU');
    
        	my $curlf = WWW::Curl::Form->new;
        	$curlf->formaddfile("data/input-$num.flac", 'myfile', "audio/x-flac");
        	$curl->setopt(CURLOPT_HTTPPOST, $curlf);
    
            my $response_body;
            $curl->setopt(CURLOPT_WRITEDATA,\$response_body);
    
            # Starts the actual request
            my $retcode = $curl->perform;
    
            # Looking at the results...
            if ($retcode == 0) {
    
                    $response_body =~ /\n\r\n(.*)/g;
    		my $json = $1;
    
    		my $json_xs = JSON::XS->new();
    		$json_xs->utf8(1);
    		my @hypo = $json_xs->decode($json)->{'hypotheses'};
    
    		my $dost = $hypo[0][0]{'confidence'};
    		my $text = $hypo[0][0]{'utterance'};
    
    		$dost = 0.0 if !defined $dost;
    		$text = "" if !defined $text;
    
    	print "+OK - Text is: \"$text\", confidence is: $dost\n";
    
    	if($dost > 0.5)
    	{
    		checkcmd($text);
    	}
    	{
    		print "+ERR - Confidence is lower, then 0.5\n";
    		#sayText("Комманда не распознана!");
    	}
    
            } else {
                    # Error code, type of error, error message
                    print("+ERR - $retcode ".$curl->strerror($retcode)." ".$curl->errbuf);
            }
    
    	system("rm data/input-$num.flac");
    
    }
    
    В деталях описывать не буду — тут реализуется именно те действия, которые нужны для распознавания текста. Гуглу скармливается файл из субдиректории data с именем input-число.flac. Как он там образуется, чуть позже. После — читается ответ, и если его достоверность выше 0.5, распознанный текст передается в качестве параметра функции checkcmd(). В конец всего, звуковой файл удаляется. Отмечу, что необходимо будет установить программу curl и добавить еще модули в начало нашего скрипта:
    use WWW::Curl::Easy;
    use WWW::Curl::Form;
    use JSON::XS;
    
    Теперь о синтезе речи. Этим будет заниматься функция под названием sayText() в качетстве параметра, принимающая собственно тот текст, который необходимо будет озвучить. Но для начала добавим некоторые недостающие модули и глобальные переменные:
    require Encode;
    
    use URI::Escape;
    use LWP::UserAgent;
    
    our $mp3_data;
    
    
    Теперь сам код:
    sub sayText
    {
    	my $text = shift;
    
    	print "+OK - Speaking \"$text\"\n";
    
    	my $url = "http://translate.google.com/translate_tts?tl=ru&q=".uri_escape_utf8($text);
    	my $ua = LWP::UserAgent->new(
    		agent => "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/535.2 (KHTML, like Gecko) Chrome/15.0.872.0 Safari/535.2");
    
    	$ua->get($url, ':content_cb' => \&callback);
    
    	open (MP3, "|padsp splay -M") or die "[err] Can't save: $!\n";
    		print MP3 $mp3_data;
    	close(MP3);
    
    	$mp3_data = undef;
    
    	print "+OK - Done!\n";
    	return;
    }
    
    sub callback {
       my ($data, $response, $protocol) = @_;
       $mp3_data .= $data; #
    }
    
    Как видно, ответ сервера в виде потока обрабатывается функцией callback(), которая добавляет данные в переменную $mp3_data. Данные передаются через пайп на программу splay которая запущена через программу padsp, отвечающую за эмулирование OSS (в Ubuntu OSS был выпилен). Ключ -M заставляет программу проигрывать данные со стандартного входа.

    Теперь поговорим, откуда же появляются загадочные файлы в flac в директории data. Тут все просто — этим занимается отдельный скрипт:
    #!/usr/bin/perl
    
    use strict;
    use IO::Socket;
    
    while (1)
    {
    my $rnd = int(rand(1000));
    
    `rec -q -c 1 -r 16000 ./data/input-$rnd.wav trim 0 4`;
    `flac -f -s ./data/input-$rnd.wav -o ./data/input-$rnd.flac`;
    `rm ./data/input-$rnd.wav`;
    
    my $sock = new IO::Socket::INET(
            PeerAddr => "localhost",
            PeerPort => 16000,
            Proto => 'tcp') || next;
    
    print $sock "text ".$rnd;
    undef $rnd;
    }
    
    Как мы можем видеть, запись и преобразование форматов выполняют несколько вызываемых из скрипта программ:

    1. rec (из дистрибутива программы sox)
    2. flac


    Команда rec делает короткие 4х секундные записи с рандомным числом в имени, которые пережимаются программой flac. После этого происходит соединение к нашему главному демону и передается команда text тот_самый_рандомный_номер. Для чего же я пишу 4х секундные короткие записи? Все дело в том, как компьютер будет записывать наш голос. Тут возможны два решения:

    1. Постоянная запись
    2. Запись файла при превышении определенной громкости


    Второй вариант мне не подошел по разным причинам, в том числе из-за плохих микрофонов ;) Разберем подробнее первый вариант с постоянной записью. Мы разбиваем нашу запись на множество мелких кусков, которые постоянно отправляем на сервер гугла для распознавания. Я нашел, что все мои команды пока входят максимум в 3-4 секунды. Если мы запустим несколько (предположим, 5) копий скрипта с интервалом в 1 секунду, получим непрерывное распознавание голоса. Добавим этот функционал к нашей основной программе:
    for(1..5)
    {
      system("perl mic.pl &>/dev/null");
      sleep 1;
    }
    
    Теперь нам осталось только реализовать функцию checkcmd() для того чтобы проверить работу всего комплекса. Нам нужно также адресное обращение, чтобы исключить ложные срабатывания.
    sub checkcmd
    {
    	my $text = shift;
    
    	if($text =~ /система/)
    	{
    	    sayText("Ваша команда - $text"); # if $text eq "раз два три";
            }
    }
    
    Теперь, соберем это все в одну кучу. У нас получилось два скрипта, назовем их srv.pl и mic.pl, а так же субдиректория data для хранения наших звуковых файлов.

    srv.pl

    #!/usr/bin/perl -w
    
    package iON;
    
    use strict;
    use utf8;
    
    use WWW::Curl::Easy;
    use WWW::Curl::Form;
    use JSON::XS;
    use URI::Escape;
    use LWP::UserAgent;
    
    require Encode;
    
    use base qw(Net::Server::Fork);
    
    ## Инициализация
    ################################
    
    $|=1;
    our $parent = $$;
    our $mp3_data;
    
    ################################
    
    for(1..5)
    {
      system("perl mic.pl &>/dev/null");
      sleep 1;
    }
    
    
    ## Параметры запуска сервера
    ###############################
    
    iON->run(port => 16000, background => undef, log_level => 4, host => 'localhost');
    
    ################################
    ################################
    
    sub DESTROY
    {
     if($$ == $parent)
     {
      system("killall perl");
      system("rm data/*.flac && rm data/*.wav");
     }
    }
    
    ## Процесс обработки команды
    ################################
    
    sub process_request
    {
    	my $self = shift;
    
    	while (<STDIN>)
    	{
    		if (/text (\d+)/) { toText($1); next; }
    		if (/quit/i) { print "+OK - Bye-bye ;)\n\n"; last; }
    
    		print "-ERR - Command not found\n";
    	}
    }
    
    ###############################
    ###############################
    
    sub toText
    {
    	my $num = shift;
    
    	print "+OK - Trying recognize text\n";
    
            my $curl = WWW::Curl::Easy->new;
    
            $curl->setopt(CURLOPT_HEADER,1);
    	$curl->setopt(CURLOPT_POST,1);
    	#$curl->setopt(CURLOPT_VERBOSE, 1);
    
    	my @myheaders=();
    	$myheaders[0] = "Content-Type: audio/x-flac; rate=16000";
    
    	$curl->setopt(CURLOPT_HTTPHEADER, \@myheaders);
            $curl->setopt(CURLOPT_URL, 'https://www.google.com/speech-api/v1/recognize?xjerr=1&client=chromium&lang=ru-RU');
    
        	my $curlf = WWW::Curl::Form->new;
        	$curlf->formaddfile("data/input-$num.flac", 'myfile', "audio/x-flac");
        	$curl->setopt(CURLOPT_HTTPPOST, $curlf);
    
            my $response_body;
            $curl->setopt(CURLOPT_WRITEDATA,\$response_body);
    
            # Starts the actual request
            my $retcode = $curl->perform;
    
            # Looking at the results...
            if ($retcode == 0) {
    
                    $response_body =~ /\n\r\n(.*)/g;
    		my $json = $1;
    
    		my $json_xs = JSON::XS->new();
    		$json_xs->utf8(1);
    		my @hypo = $json_xs->decode($json)->{'hypotheses'};
    
    		my $dost = $hypo[0][0]{'confidence'};
    		my $text = $hypo[0][0]{'utterance'};
    
    		$dost = 0.0 if !defined $dost;
    		$text = "" if !defined $text;
    
    	print "+OK - Text is: \"$text\", confidence is: $dost\n";
    
    	if($dost > 0.5)
    	{
    		checkcmd($text);
    	}
    	{
    		print "+ERR - Confidence is lower, then 0.5\n";
    	}
    
            } else {
                    # Error code, type of error, error message
                    print("+ERR - $retcode ".$curl->strerror($retcode)." ".$curl->errbuf);
            }
    
    	system("rm data/input-$num.flac");
    
    }
    
    ###############################
    
    ## Проверка на комманды
    ###############################
    
    sub checkcmd
    {
    	my $text = shift;
    	chomp $text;
    	$text =~ s/ $//g;
    
    	print "+OK - Got command \"$text\" (Length: ".length($text).")\n";
    
    	if($text =~ /система/)
    	{
    	   sayText("Ваша команда - $text");
             }
    
    	return;
    }
    
    
    ## Озвучивание
    ###############################
    
    sub sayText
    {
    	my $text = shift;
    
    	print "+OK - Speaking \"$text\"\n";
    
    	my $url = "http://translate.google.com/translate_tts?tl=ru&q=".uri_escape_utf8($text);
    	my $ua = LWP::UserAgent->new(
    		agent => "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/535.2 (KHTML, like Gecko) Chrome/15.0.872.0 Safari/535.2");
    
    	$ua->get($url, ':content_cb' => \&callback);
    
    	open (MP3, "|padsp splay -M") or die "[err] Can't save: $!\n";
    		print MP3 $mp3_data;
    	close(MP3);
    
    	$mp3_data = undef;
    
    	print "+OK - Done!\n";
    	return;
    }
    
    sub callback {
       my ($data, $response, $protocol) = @_;
       $mp3_data .= $data; #
    }
    
    ########################################
    ########################################
    
    1;
    

    mic.pl

    #!/usr/bin/perl
    
    use strict;
    use IO::Socket;
    
    while (1)
    {
    my $rnd = int(rand(1000));
    
    `rec -q -c 1 -r 16000 ./data/input-$rnd.wav trim 0 3`;
    `flac -f -s ./data/input-$rnd.wav -o ./data/input-$rnd.flac`;
    `rm ./data/input-$rnd.wav`;
    
    my $sock = new IO::Socket::INET(
            PeerAddr => "localhost",
            PeerPort => 16000,
            Proto => 'tcp') || next;
    
    print $sock "text ".$rnd;
    undef $rnd;
    }
    

    Что получилось


    Дадим права на запуск нашим скриптам:

    chmod 755 srv.pl mic.pl

    Запускаем скрипт srv.pl, ожидаем запуска всех процессов, произносим, скажем, фразу: «Система! Раз два три!». Слышим через несколько секунд: «Ваша команда — раз два три». Нужно заметить, что наша команда будет попадать в несколько звуковых файлов и, соответственно, несколько раз исполняться. Чтобы этого избежать, нужно ввести проверку на последнюю команду. Добавим этот функционал в следующей части.

    Итого


    В этой статье мы реализовали базу нашего ПО для управления системой «умный дом». Пока оно почти ничего не умеет, кроме распознавания и синтеза речи, но это временно ;)

    В следующей статье я расскажу, как прикрутить к этому всему web-интерфейс с некоторыми вкусными плюшками и просмотром камер.

    UPD: Часть 4

    Поделиться публикацией
    Реклама помогает поддерживать и развивать наши сервисы

    Подробнее
    Реклама
    Комментарии 47
    • +7
      Позже это планируется сделать опенсурс проектом? Что-бы каждый человек при должно умение и хорошей документации смог сделать это сам?
      • +5
        Он изначально позиционируется как Open Source. Ссылка на trac есть в статье.
        • 0
          а как логин получить к этому trac'у?
          • 0
            Регистрация по OpenID на opensvn.ru
            • +1
              Залогинился в opensvn.ru по openid.
              Выставил пароль для trac.
              Прошёл по вашей ссылке для trac с выставленным логином.
              Теперь везде ошибка:
              Error: Forbidden
              TIMELINE_VIEW privileges are required to perform this operation

              По ссылке на вики:
              Error: Forbidden
              WIKI_VIEW privileges are required to perform this operation on TracGuide

              По trac.opensvn.ru/ion/ тоже самое.

              ?
              • 0
                Поправил права.
                • 0
                  спасибо.

                  я уже потестировал его с помощью:
                  #!/bin/bash
                  # installation:
                  # sudo apt-get install sox curl perl
                  # sudo sh -c "curl -s -L cpanmin.us | perl - JSON::XS"
                  while [ true ]; do
                  echo "recording..."
                  rec -q -c 1 -r 16000 current.wav silence 1 0.3 2% 1 0.3 2%
                  if [ -z current.wav ]; then
                  echo "nothing was recorded (check mic setting, silence level)"
                  continue
                  fi
                  echo "recognizing..."
                  sox current.wav current.flac
                  text=`curl -s -H 'Content-Type: audio/x-flac; rate=16000' --data-binary '@current.flac' 'https://www.google.com/speech-api/v1/recognize?xjerr=1&client=chromium&lang=ru-RU'| perl -MJSON::XS -CO -nE'say decode_json($_)->{hypotheses}->[0]->{utterance}'`
                  echo "recognized text: '$text'"
                  # wrapper around festival for Russian language
                  # festival installation/configuration is needed for this
                  #saytext-ru.sh "$text"
                  done


                  После настройки микрофона показывал сносные результаты. Но и ошибок было достаточно.
                  Относительно синтеза звука правильно подсказывают внизу: festival
                  И в приведённой вами в прошлый раз ссылке: ab-log.ru/smart-house/speech/voice-synthesis
                  он тоже есть.
                  Впрочем как и распознавание:
                  ab-log.ru/smart-house/speech/speech-recognition
        • +2
          > Если мы запустим несколько (предположим, 5) копий скрипта с интервалом в 1 секунду, получим непрерывное распознавание голоса.

          То есть система непрерывно шлёт на сервер Гугла аудио для распознавания, да еще в несколько потоков. Какой при этом трафик генерируется?
          • –1
            Моих скромных 5 мбит хватает за глаза.
            • +3
              Для ADSL-щиков это может оказаться критично, у них исходящий канал — больное место :)
              • +1
                Да и не только исходящий канал. Задержки могут сыграть тоже весьма важную роль. Если реакция на команды будет с ощутимой задержкой — это будет раздражать.
              • +2
                Ну у кого-то с глубинки нет такой скорости. Правда с моими 2 мбитами тоже можно разгулятся, но у нас я чуть ли не буржуй с такой скоростью.
                • +2
                  А Гугл не ограничивает кол-во запросов к API? Все-таки постоянно отправлять аудио нa распознавание, имхо, не лучшая идея.
                  • 0
                    У меня проходят без проблем все запросы на распознавание. А по поводу, как распознавать — предлагайте, если будет хорошая идея, почему бы и не реализовать :)
                    • +5
                      Вот еще какая идея родилась… Каждая команда начинается с ключевого слова, обозначающего, что вы обращаетесь именно к системе. Можно распознавать это ключевое слово локально, и только если оно обнаружено, слать последующие 5 секунд (саму команду) в гугл. Плюсы очевидны:
                      1) не пересылаем аудиопоток вхолостую, не забиваем канал
                      2) настроить движок на распознавание одного слова, имхо, легче, чем научить отличать одну команду от другой.
                      • +3
                        Неплохая идея. Спасибо!
                        • 0
                          В сериале StarTrek персонажи обращаются к компьютеру ключевой фразой «компьютер»
                          Например:
                          -Компьютер, где находится Тувок?
                          -Тувок находится у себя в каюте.

                          Причем, я бы не отказался от тех писков, которые выдает компьютер (после обращения «компьютер» раздается серия звуков, подтверждающая готовность к приему команды)
                          • 0
                            Есть идея реализовать такую схему:

                            1. Ключевое слово, после которого включается прием команды (например, «компьютер»)
                            2. ПК подтверждает пререход к готовности принимать команды (например говорит: «слушаю»)
                            3. Запись 5-10 секундного файла, который уже и отправляется гуглу.

                            Комментирующие советуют отлавливать ключевое слово средствами не гугла. Порывшись в сети, ничего лучше CMU sphinx не нашел… Но с настройкой его вышел затык. Информации крайне мало и она скудна. Может кто подскажет, как вообще прикрутить к нему русский язык и заставить слушать микрофон?
                          • 0
                            Вместо писка можно вибрацию лёгкую пускать. Таким образом не пугая людей или детей.
                          • 0
                            Вот. Вероятно, это не единственное. И всяко лучше, чем доверять всё, что происходит в вашем доме большому брату-поисковику.
                        • 0
                          А чет так слабо — шлете все, что происходит в вашем доме только в Google? Шлите сразу путену, милиции, ну и в организацию воров-домушников. Это ж верх патриотизма — гражданин не только не против, чтоб его прослушивали, он сам устанавливает у себя жучки и выдает наружу.
                          • 0
                            У вас параноя. Никому не интересно, как вы разговариваете с женой и собакой.
                            • 0
                              Да вот как раз в Google слать безопаснее :)
                        • +1
                          Гугл, вроде, переводит translate-API на платные рельсы. Не отвалится ли озвучивание текста после этого?
                          • 0
                            Вряд ли… Но если отвалится, найду другое решение
                          • 0
                            Все-таки решение с гуглом не очень. Передача команды по сети, ожидание обработки и результата — это не очень хорошее решение. Нет, скажем, движка, который можно было бы обучить командам со своего голоса? Ведь гугл — вещь универсальная, а команды распознавать система должна только от определенного круга пользователей.
                            • 0
                              Посматриваю в сторону CMU Sphinx. Но по отзывам, там с распознаванием все не так гладко.
                              • 0
                                Обучить его нельзя? Пользователь говорит команду, он разбирает ее по своему алгоритму и я присваиваю результату разборки свой текст, если есть отклонения (к примеру).
                                • 0
                                  Виноват, лишний комментарий.
                                • +4
                                  Так используйте его как запасной вариант. Есть интернет — распознает через гугль, нет интернета — все равно распознает, через сфинкс, пусть и хуже.
                                  • +4
                                    Хорошая идея. Думаю, реализую.
                              • +1
                                Интересно. Мы разрабатываем из этой же области проект. Вот снял чуток:
                                www.youtube.com/watch?feature=player_detailpage&v=LV3Dq-DtISE#t=15s
                                • 0
                                  Давно на хабре не был, а тут зашел и будущее.
                                  Также критичен по поводу выбора гугла и многих скриптов, многим нужно какое-то решение под ключ без знаний шелскриптинга и интернета. Но как вариант с микробюджетом то!
                                  • +1
                                    Идейка с распознанием голоса хорошая. Но нужно учесть, что человек может слушать громкую музыку, и в словах, к примеру, песен могут быть команды + человека может быть не слышно. По этому, как совет, добавьте еще и обработку голоса. Такое добавление поможет решить некоторые проблемы, к примеру с интернетом.
                                    • 0
                                      меня все мучает вопрос и ситуацией когда нет инета:
                                      сколько не говори тогда «Дом, включи свет» — ничего же и не дождешься.
                                      Вариант как предложил Ocelot вообще предусмотрен?

                                      Что-то я не доверяю такому управлению.
                                      У меня тут, недавно, без всякого лишнего управления микроволновка играла в «восстание роботов» и сама включалась — хорошо что еще уснуть не успел.
                                      • 0
                                        А вы не рассматривали festival для синтеза голоса, чем он плох? На том же сайте есть упоминание о нём: ab-log.ru/smart-house/speech/voice-synthesis
                                        • 0
                                          Спасибо за статью. Вот бы еще код на Java/C# бы. С перлом не работал никогда. Код тяжело воспринимается.
                                          • +1
                                            Попробуйте Iris (An interactive desktop assistant — uses voice commands to answer and automate simple lookup and playing tasks For simple tasks like checking the weather and brief wikipedia queries.)

                                            github.com/samirahmed/Iris-Voice-Automation
                                          • 0
                                            Вспоминается из Шумилова отрывок…
                                            — А почему Дик всё время туда-сюда очки дёргает?
                                            — А он их надевает, когда голосовые команды отдаёт. А то скажет он тебе «Отвяжись!», а комп примет на свой счёт. И что-нибудь отвяжет. Будет обидно.
                                            Как-то так =)
                                            Собственно, всё это весьма прикольно. Но — постоянно слать куски аудио в корпорацию добра? Во-первых, куски — попадание текста на разрыв уже заставит повторить команду. Во-вторых, такой объём траффика… И в-третьих, слить полностью аудио-запись своей жизни в гугль — весьма смелое решение =)
                                            Имхо, лучше всё-таки делать запись только при опредлённых условиях. Лучше всего реагировать при этом не на голос, а на какой-нить редкий звук — хлопок, свист… Для эстетов можно носить с собой колокольчик и настроить программу реагировать на издаваемый им звон =) Хлопок, теоретически, даже можно использовать как триггер для записи по уровню звука.
                                            • 0
                                              Проблемы не будет. Вы же знаете, что Гугл закрывает translate API? Все потому, что это «Корпорация добра», а не халявы.

                                              А от статьи двоякое ощущение — техническая сторона хороша для перл-кодера, например, иногда похвастаться голосовым управлением сервером (перед начальством) полезно.

                                              Но вот отношение к доступным ресурсам, в частности, того же Гугла — как у пацанов, включающих громкий БУМЦ_БУМЦ ночью во дворе — мне хорошо, а на остальных — … (сами догадываетесь)
                                              А представьте, что приедут братки, у которых и машина побольше и музыка погромче…

                                              Почему бы не взять SpeechAPI (под Win) или просто записать звуковые файлы, а потом собрать нужную фразу?
                                              • 0
                                                Будет закрыто синтезерование голоса — значит будут другие ресурсы. Благо синтез не такая большая проблема, как распознавание. О каком начальстве вы говорите? Моя сфера работы несколько в стороне от программирования. А насчет отношения к ресурсам считаю так — если гугл не ограничивает кол-во запросов к своим сервисам, значит для него это приемлемо.
                                                • 0
                                                  Синтез, действительно, не такая проблема как распознавание — существуют готовые библиотеки, с помощью которых это реализуется.
                                                  А насчет распознавания — а нужно ли оно, на самом деле, в этом проекте? Я имею в виду, что требуется то не распознавание речи, чтобы получить сказанное в виде текста, а только отделение команд от других звуков — голосовое управление. А в этом случае можно использовать опять же готовые библиотеки, для которых можно «нарезать» образцы команд, а затем использовать их для применения действий. Как при голосовом наборе номера в сотовом — он же не распознает сказанное, а просто сравнивает спектрограммы или сигналограммы.
                                            • +2
                                              а гугл не забанит за большое кол-во запросов? ;)
                                              • 0
                                                Может уже существует готовый вариант распознователя голоса google под Win? Пока устраивает андроид на виртуалке, но может уже есть решения.
                                                • 0
                                                  А чем Вас подход автора не устраивает? Нарезать звуковой поток и отослать файлы прикинувшись андроидом?
                                                • 0
                                                  Нет, только не это — мечта становится реальностью!
                                                  Спасибо вам огромное за STT и TTS ссылки. Пойду через AutoIt прикручивать их. Уже есть даже готовые скрипты

                                                  Прощай работа =( — Привет отлаживание сутками на пролет умного дома =)
                                                  • 0
                                                    На моем андроиде 4.4.4 в настройках голосового поиска есть пункт «распознавание речи оффлайн», в котором я указал, что хочу использовать дополнительно к предустановленному английскому словарю еще русский и немецкий. Каждый хранится локально и весит около 20 мегабайт. Вроде бы, распознавание при этом должно делаться без интернета. Может, как-то к подобному прикрутиться? Андроидофон или планшет в систему ввести…

                                                    Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.