31 мая 2009 в 14:54

Учим PowerShell разговаривать

Во многих фантастических фильмах люди взаимодействуют с компьютерами, используя голосовые команды. Например, заходит человек в комнату, а там темно. «Компьютер, свет 50%!» — говорит он. «Есть свет 50%!» — отзывается приятным женским контральто компьютер и берет под козырек, включая неяркий свет. Кому такого не хотелось? Но если сама мысль такого взаимодействия родилась на свет очень давно, странствуя с тех пор по страницам фантастических книг и кадрам кинолент, то сейчас всё изменилось: доступность под рукой высоких технологий сделала многое возможным. В романе Роберта Хайнлайна «Луна — суровая хозяйка» (1966г.) суперкомпьютер Майк мог говорить свободно, но он занимал огромное количество места и, уж конечно, не был мобильным. Герой моего рассказа не может похвастаться идеальным произношением или возможностью поддерживать диалог, но, для своих габаритов он очень способный. Разумеется, я говорю о нетбуке Asus EeePC 1000.

Не так давно я установил на него новую операционную систему MS Windows 7 RC и не мог не ознакомиться с тем, что предлагалось в комплекте. Наибольший мой интерес вызвала командная строка PowerShell и среда PowerShell ISE. Где-то на просторах интернета существуют самые разные командлеты для осуществления почти любых задач, в том числе и для воспроизведения речи. Но мне хотелось реализовать все через обычную функцию, чтобы не быть зависимым от установленных командлетов. Их же, в конце концов, может и не быть на определенном компьютере, а профиль скопировать — дело минуты. Кроме того, недавняя история с исчезновением в новой сборке, например, командлета Get-Clipboard для работы с буфером обмена, настораживает относительно чрезмерного использования редких командлетов. А вот классы .NET никуда не денутся, хотя доступ к ним может быть тоже не самым простым: в данном случае приходится запускать консоль в режиме -sta чтобы иметь возможность работать с буфером обмена.

Префикс названия функции я использую от одного из своих ников, чтобы иметь возможность по автодополнению быстро попасть на самописные функции, введя всего три символа: они больше нигде в командах PowerShell не встречаются.

Ну а вот, собственно, сама реализация:

function astSpeak([string]$inputString, [int]$speed = -2,
         [int]$engine = 0, [switch]$file,
         [switch]$list, [switch]$buffer,
         [int]$volume = 85)
{
  # Создаем объект
  $oVoice = New-Object -com "SAPI.spvoice"

  # Если требуется вывести список голосов
  if($list)
  {
    Write-Output "Установленные в системе голоса: "
    $i = 0
    Foreach ($Token in $oVoice.getvoices())
    {
      Write-Host $i - $Token.getdescription()
      $i++
    }    
  }
  # Если требуется проговорить
  else
  {
    # Получаем текст из файла, если задан переключатель
    if($file){ $toSpeechText = Get-Content $inputString}
    # Проговариваем текст из буфера обмена (требует режима sta)
    elseif($buffer){
     $null = [reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
     $toSpeechText = [Windows.Forms.Clipboard]::GetText() }
    # Используем полученную строку, если переключатель не задан
    else{ $toSpeechText = $inputString}
    
    # Воспроизводим
    $oVoice.rate = $speed
    $oVoice.volume = $volume
    $oVoice.voice = $oVoice.getvoices().item($engine)    
    $oVoice.Speak($toSpeechText)
  }
}


* This source code was highlighted with Source Code Highlighter.

Что умеет функция?

Можно вывести список установленных в системе голосов. Существует достаточно большое количество самых разных голосов, в том числе умеющих читать русский текст. У меня как основной установлен голос Алёна, который вполне успешно прошел проверку чтением статей из википедии и художественной литературы. В качестве последней использовался короткий ироничный рассказ Гарри Гаррисона «Абсолютное Оружие», взятый в Библиотеке Мошкова. Благодаря голосу сразу удалось найти несколько опечаток в тексте и понять необходимость расстановки буквы «ё», в остальном же, чтение было впечатляющим. Итак, чтобы получить список голосовых движков, нужно вызвать:

astSpeak -l

image

Можно прочитать любой заданный текст, ну это самое простое.

astSpeak «Привет! Меня зовут Алёна, я голос твоего компьютера!»

Можно прочитать текстовый файл. Для этого следует указать соответствующий ключ и путь к нужному файлу. Например, так:

astSpeak -f «D:\Библиотека\Редъярд Киплинг\Заповедь.txt»

Да… пожалуй, доверять Алёне стихи больше не будем :)

Можно прочитать текст, содержащийся в буфере обмена. С реализацией этого существуют некоторые сложности, так как специальный командлет был исключен из пакета поставки PowerShell, а получить доступ к буферу средствами .NET можно только в режиме sta (Single Threading Apartment), а консоль PowerShell запускается в режиме mta по-умолчанию. В режиме mta работает по-умолчанию ISE. Но это не проблема, достаточно в свойствах ярлыка консоли прописать соответствующий ключ:

image

Итак, если позволяет режим консоли, выглядеть это будет так:

astSpeak -b

Самое страшное — если там был URL.

При вызове любого режима, предполагающего воспроизведение речи (ну, то есть кроме перечисления голосовых движков), можно также задать скорость речи, громкость голоса и номер звукового движка. Чтобы, например, услышать слово «привет» в исполнении Катерины (движок номер 1), громкостью, установленной на 85/100 и со слегка увеличенной скоростью, нужно ввести следующую команду.

astSpeak -e 1 -v 85 -s 3 «Привет»

В общем, все действительно просто! Если у вас есть какие-то комментарии, советы или вы знаете как можно все это улучшить, буду очень рад вас услышать. И… с первым топиком на хабре меня! :)
Дмитрий Синёв @Ikarr
карма
–0,4
рейтинг 0,0
Похожие публикации
Самое читаемое Администрирование

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

  • НЛО прилетело и опубликовало эту надпись здесь
    • 0
      Расскажите, пожалуйста, подробнее. Как вы вызывали?
      • НЛО прилетело и опубликовало эту надпись здесь
        • 0
          В функции стоял по-умолчанию голосовой движок 2, так как он самый приличный из установленных у меня. Спасибо, что заметили — я исправил значение по-умолчанию на 0, тоже поправьте в заголовке функции значение $engine и всё должно заработать. Голосовые движки можно поискать в гугле по запросу «sapi голосовые движки», их там достаточно много, я все даже не пробовал.
        • +1
          PS C:\Users\ZhenO> astSpeak -list
          Установленные в системе голоса:
          0 — Microsoft Anna — English (United States)
          PS C:\Users\ZhenO>

          у меня тоже один… автор подскажите пожалуйста где можно скачать остальные или хотябы туже «Алену»
          • 0
            torrents.ru/forum/viewtopic.php?t=1014114 — Голосовой движок Acapela Alyona (русский)
            • 0
              Там же есть и Катерина.
              • +2
                "«Алена» по мнению пользователей приятней чем у движка «Катерина» от ScanSoft RealSpeak." там так написано, положусь на мнение большинства, да и девушку мою Катя зовут, думаю конфликты будут если к компу буду обащаться типа: «Катенька, сделай как то что я хочу»
                • 0
                  Разумно! Но было интересно поставить движки разного времени разработки и сравнить прогресс в отрасли. Когда-то мучал бедного Microsoft Сэма, который и по-английски-то говорить едва умел, а сейчас — Microsoft Анна совсем другое дело, плюс новые русские движки.
  • НЛО прилетело и опубликовало эту надпись здесь
    • +1
      А мотивирует чем?
      • НЛО прилетело и опубликовало эту надпись здесь
        • 0
          А стандартный работает? Который в «Панели управления» запускается?
          • НЛО прилетело и опубликовало эту надпись здесь
            • 0
              Попробуйте задать громкость.
              • НЛО прилетело и опубликовало эту надпись здесь
    • +1
      Попробуйте так — [int]$volume = 100
  • +9
    вот сейчас народ, глумится начнет, приказывая компу скать то что он хотел услышать от девушки:
    «Да, мой господин! Операция завершена. Хотите я закажу пива и девочек, у вас был сегодня тяжелый день».
  • +3
    если бы он еще и голос распознавал с такой же легкостью :)
    • 0
      Вот и я прочитал в начале:
      «Например, заходит человек в комнату, а там темно. «Компьютер, свет 50%!» — говорит он. «Есть свет 50%!» — отзывается приятным женским контральто компьютер и берет под козырек, включая неяркий свет. Кому такого не хотелось?»
      И подумал — опа, голосовое управление! неужели PowerShell такое может? А оказалось наоборот :)
      • 0
        Справедливости ради, ничего такого пока не оказалось. Из PS можно работать с объектами, в том числе SAPI, так что вполне можно написать и управление голосом. Пока мои эксперименты до этого не дошли :)
  • 0
    у меня такое ощещение сложилось что «Алена» в каком то приказном тоне все говорит, напрягает как то
    • +1
      А кто-то про неё писал, помню, что в капризном, лол :)
      • 0
        попробуйте: «Дима, помой посуду!».
        даа… и с именами она плохо справляется, ужастно звучат имена: Женя, Евгений, Дима и т.д. ударение на последний слог ставит
        • 0
          Её можно обучать посредством словарей. Например, научил её говорить правильно слово «сенсорных», по-умолчанию ударение ставилось на букве «о».
          • –1
            Правильно именно на «о», извините :)
            • НЛО прилетело и опубликовало эту надпись здесь
              • НЛО прилетело и опубликовало эту надпись здесь
            • 0
              Так это «сенсОр», а не «сЕнсор»? о_О
              Век живи, век учись :)
            • 0
              Пруфлинк, пожалуйста! Всегда везде слышал именно «сЕнсорные панели».
              • 0
                • +1
                  А, ну мы же не о медицине говорим. Значит, все верно.
  • +2
    Все, сейчас напишу программу которая будет будить меня по утрам, зачитывать список дел из органайзера и погоду на день, заряд бодрости с утра обеспечен))
    • +3
      Ага, а еще напоминать о делах, когда отвлекаешься. Предлагаю назвать голос для такой программы Ксантиппой ;)
  • 0
    А еще можно сделать читалку RSS
    • 0
      Можно даже средствами PowerShell. Ну, например, так:

      ([xml](New-Object Net.WebClient).DownloadString(«habrahabr.ru/rss»)).rss.channel.item | format-table author, link

      С названиями сложнее, я пока не придумал как расшифровать область CDATA средствами PS.
  • +1
    Откопал пример голоса Алены. Круто.
    http://nsis.ucoz.ru/temp/primer.mp3
    • 0
      Вы можете попробовать любой текст в онлайн-демо, вот только что нашел:
      www.acapela-group.com/text-to-speech-interactive-demo.html
    • 0
      Дамс, качество речи festival отдыхает, даже обидно как то :(
  • +1
    а если на ХР установить PowerShell, то можно тоже самое сделать, или это только на win 7?
    • +1
      у меня работает и на ХР
    • 0
      Можно, только что проверил.
  • +1
    А как же управление? «Сим-сим, откройся!» =)
    • 0
      «Компьютер! Контрол, альт, делит!»
  • 0
    Не хватает видео с демонстрацией :)
    • +1
      Это потому что не хватает камеры, чтобы снять видео с демонстрацией :)
      • 0
        м, правда думаете что скринкасты на камеру снимают?
        • 0
          По-моему, это бы не смотрелось. Вот другое дело, если сидит некий Вася, набирает команду, а компьютер ему человеческим голосом отвечает. Вот это понятно, «до чего прогресс дошел»!
  • +1
    Расскажите, как вы добились растроения вашего поста на главной? =)
    • 0
      Я только один вижу.
      • 0
        А у меня их три)
        • 0
          И все идентичные, вплоть до числа комментариев.
          • 0
            Покажите скриншот, дайте насладиться единением в трех сущностях :)
            • 0
              img46.imageshack.us/img46/11/powershellx3.png
              Все три и даже две целиком, к сожалению, не влезают, у меня тоже нетбук :)
              • 0
                Может быть, у вас что-то? Если вас не плюсуют, значит никто такого больше не наблюдает. А у меня оно выглядит вот так: gyazo.com/068e1cf9731dff9813ca95f031cf0f0d.png (это с рабочей станции)
                • 0
                  Ну даже не знаю :) у меня целиком дублируется — и число новых комментариев, и ссылки, и статус наличия в избранном, и всё на свете. Причём только ваш пост. Во, сделал скрин в полноэкранном режиме с масштабированием: img269.imageshack.us/img269/4863/powershellx3v2.png
                  Может меня любит НЛО?)
                  • 0
                    Отпишитесь в саппорт ТМ. У меня такое тоже с какими-то постами было в избранном. Скорее всего это баг
  • 0
    По-моему, Алёна надо мной прикалывается. Во фразе «Господа, не хотите ли пива с раками выпить?» у нее явно звучат издевательские интонации :)
    А еще плохо, что она, к сожалению, не различает, когда надо говорить «дЕла», а когда — «делА».
    • 0
      Ну человеческий язык такая штука, его нельзя однозначно интерпретировать только по строке символов. Чтобы правильно расставить все ударения, использовать правильное произношение, нужно как-то осмыслять то, что говоришь. Мы, конечно, живем в XXI веке, но пока «как же пусто в черепах черепах» =)
  • 0
    Забавно, но у меня не произносятся предложения т.е. не произносится больше одного слова, пишет ошибку

    PS C:\Admin> astSpeak <Привет! Меня зовут Алёна, я голос твоего компьютера!>
    astSpeak: Не удается преобразовать значение «Меня» в тип «System.Int32». Ошибка: «Входная строка имела неверный формат

    В строка:1 знак:9
    + astSpeak <<<< <Привет! Меня зовут Алёна, я голос твоего компьютера!>
    • 0
      В обычные кавычки заключите.
      • 0
        PS C:\Documents and Settings\torkvemada> astSpeak -e 1 "Господа, не хотите ли пива с раками выпить?"
      • 0
        Спасибо
    • 0
      Он трактует пробел в предложении как переход к следующей переменной и пытается сделать из строки «Меня» целочисленное. Не вижу такого способо даже после пива (с раками), он, видимо, тоже :) Нужно заключать всю строку в кавычки, чтобы он воспринимал её как единое целое.
  • 0
    Вы уж простите мою непроходимую тупость, но куда все-таки нужно переписать код функции astSpeak? В PowerShell ISE?
    • 0
      можно просто в консоль PS, тогда она будет действовать только в течение данного сеанса.
      Я положил в %USERPROFILE%\Мои Документы\WindowsPowerShell\profile.ps1, чтобы она загружалась вместе с сеансом. Только файлик пришлось подписать.
      • 0
        Добавлю, что путь к этому файлику лежит в $profile
  • –2
    господа, кто-нибудь залейте Алёну на яндекс-диск, не могу слить её с торрентов. заранее спасибо
  • +2
    Может быть кому-то будет интересен вариант без использования PowerShell, а на старом добром Javascript под WSH. Этот вариант пылится здесь.
  • +1
    Кхе-кхе. Голосовые функции компьютера я использовал еще в конце прошлого века. И не баловства ради. Водитель-экспедитор сканером штрих-кодов приходовал накладные. Документов много, очень много, а кодировка, кажется Code39. То есть на самая надежная. Компьютер голосом зачитывал последние три цифры номера накладной, тем самым позволяя пользователю удостовериться в том, что накладная идентифицирована корректно. Приложение работало под Windows NT 4.0.
  • 0
    2010 год, заходит начальник в серверную, отвечает ему сервер утробным голосом, «начальника шехельде бехельде аптайма ого какой, насяльнка… упс...»
  • 0
    Как сделать свет 50% я так и не понял:)
    • 0
      Отвечать человеческим голосом научили, а вот распознавать приказы — ещё нет. Работы, конечно, ведутся (например, вот есть хороший ролик: www.youtube.com/watch?v=KyLqUf4cdwc ), но скажу Вам честно, я лучше руками свет убавлю, чем так мучиться :D
  • 0
    А нет таких голосовых движков которые по записи настоящей человеческой речи могу подогнать тембр, высоту и проичие параметры электронной говорилки, чтоб было похоже на заданный голос?
    • 0
      Вряд ли. Я как понял, там очень многое завязано на произношении, поэтому движков так мало.
  • 0
    До чего прикольно Алена читает английский текст!
    Сразу вспоминаются уроки английского в школе ))
    www.acapela-group.com/text-to-speech-interactive-demo.html
  • 0
    ну прошло 6 лет — что-то изменилось? есть в линуксе хоть какая-то вменяемая говорилка? ладно festival уже нормально говорит, но на незнакомых словах вылетает в ошибку LTS_Ruleset russian_downcase: no rule matches и к нему нет графического интерфейса, типа из офиса выделение говорить

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