Введение
Многим из вас, наверное, уже приглянулся один из персонажей Microsoft Agent. Agent, на мой взгляд - это достаточно любопытное нововведение фирмы Microsoft, а стандартная поставка ядра Agent с Windows 2000, Me и XP делает использование этой технологии в ваших программах перспективным. На сайте Microsoft доступен бесплатный редактор для создания новых персонажей Agent, а в интернете появляются сайты, на которых представлены большие коллекции персонажей. Что же мешает программистам более активно использовать Agent в своих разработках? Скорее всего, незнание этого замечательного компонента. В этой статье я попытаюсь рассказать о работе с ним.
Обзор возможностей Agent
Для чего нужен Microsoft Agent? Во-первых, с его помощью вы сможете "оживить" свои программы; в них будет жить маленький "персонаж". Он может грустить, веселиться, перемещаться по экрану в зависимости от действий пользователя, а если к приложению долго не обращаться, то даже может засыпать. Во-вторых, как вы относитесь к тому, что Agent будет говорить, да еще и по-русски? В-третьих, Agent позволяет ввести в программы поддержку голосовых команд, которые пользователь будет давать через микрофон. Думаю, эти доводы убедили вас написать нескольких дополнительных строк кода, необходимых для включения Agent в ваши программы. Если нет, то вспомните, в каких программных продуктах Вы уже встречались с Agent. Наиболее значимый из них - Microsoft Office, который не просто использует технологию Agent, но и имеет в своем составе несколько собственных персонажей. Кроме Office, хотелось бы отметить и один из Российских программных продуктов - переводчик Magic
Gooddy.
Структура Agent и иерархия объектов
Для начала работы с Agent, мы немного рассмотрим его внутреннюю структуру. Microsoft Agent представляет собой ActiveX приложение, поэтому его можно использовать в любом современном языке программирования, например Microsoft Visual
Basic, Visual C++ и других. Вы можете использовать его в своих Web приложениях, включая в HTML код скрипты, написанные на Visual Basic Scripting Edition (VBScript) или
JScript. И, наконец, Agent доступен в приложениях Microsoft Office и других программных продуктах, использующих Visual Basic for Applications (VBA). Хотелось бы еще отметить, что Agent является бесплатным компонентом, вы можете использовать его в любых своих программах абсолютно свободно.
Для использования технологии Microsoft Agent компьютер вашего клиента должен иметь:
- операционную систему семейства Microsoft Windows, кроме Windows
NT версии ниже 4.0
- Internet Explorer 3.02 или выше
- процессор Pentium 100 MHz или лучше
- более 16 MB оперативной памяти
- Microsoft Windows(r) совместимую звуковую карту и, конечно же, микрофон.
Установка Agent потребует свободного места на жестком диске: для ядра Agent около 1 MB, для каждого устанавливаемого персонажа от 2 до 4 MB, для поддержки синтеза речи 1,6 МВ и для системы распознавания речи около 22 МВ.
Внутренняя структура Agent выглядит не очень сложной, восемь объектов (Request, Character, Command, Balloon, SpeechInput, AudioOutput, CommandsWindow и PropertySheet) и три коллекции (Characters, AnimationNames, Commands). Некоторые из этих объектов, например Character будут рассмотрены подробно, а другие, например Balloon, вам придется изучать самим.
Начиная рассматривать Agent, стоит упомянуть, что все примеры работы с Agent, я буду приводить на языке Visual Basic. Кроме того, я написал для вас небольшой пример, изучив который вы лучше сможете понять принципы работы с этим замечательным компонентом.
Ссылка на объект "Персонаж"
Для начала на компьютер следует установить ядро Microsoft Agent и хотя бы одного персонажа. В составе новейших операционных систем Windows 2000, Millennium, а также XP уже есть ядро Agent и один из персонажей - "Маг". Для других версий Windows ядро можно загрузить по адресу
http://activex.microsoft.com/activex/controls/agent2/MSagent.exe. Кстати, массу информации по Agent можно найти на
http://www.microsoft.com/msagent/.
Итак, для работы с Agent потребуется ссылка на объект типа IAgentCtlCharacter или IAgentCtlCharacterEx. В принципе, можно использовать любой из этих типов, но IAgentCtlCharacterEx предпочтительнее, так как IAgentCtlCharacter устарел и оставлен из соображений совместимости. Получив ссылку, мы сможем работать с персонажем. Ссылку можно получить двумя способами. Первый из них проще, но он менее гибок, второй обладает хорошей переносимостью, но он сложнее.
Первый способ использует для получения ссылки раннее связывание. Делается все очень просто. Помещаем на форму объект Agent, предварительно добавив его на панель компонентов с помощью диалогового окна "Components" (нажмите Ctrl+T для его вызова). Теперь в событие Form_Load впишите:
'переменная для ссылки
Dim AgentChar As IAgentCtlCharacter
'загружаем персонаж
Agent1.Characters.Load "my character", "genie.acs"
'ссылка на персонаж
Set AgentChar = Agent1.Characters ("my character")
Или так:
'переменная для ссылки
Dim AgentChar As IAgentCtlCharacterEx
'загружаем стандартного персонажа
Me.Agent1.Characters.Load "Default"
'ссылка на персонаж
Set AgentChar = Me. Agent1.Characters.Character("Default")
Первый вариант загружает указанный персонаж (в данном случае "Джин") из папки windows_dir\msagent\chars, второй загружает персонаж "по умолчанию". В любом случае ссылка на объект в нашем распоряжении.
Важно: Работая с Agent, я заметил, что на некоторых компьютерах загрузка персонажа "по умолчанию" приводит к ошибке 0x80042017 (отсутствуют установленные стандартные персонажи). Это связано с тем, что на компьютере установлено только ядро Agent, а установка персонажей не произведена, хотя файл одного из персонажей (с расширением acs) может находиться в папке windows_dir\msagent\chars. Учитывайте такие ситуации и корректно обрабатывайте подобные
ошибки.
Второй способ. Используем позднее связывание, этот метод хорош в случае, если вы не знаете, будет ли у пользователя установлен Agent. Здесь, в отличие от первого способа, можно предусмотреть такую ситуацию и продолжить работу без использования Agent.
'переменные для ссылок
Private MSAgent As Object
Private AgentChar As Object
'включаем обработчик ошибок
On Error Resume Next
'создаем объект
Set MSAgent = CreateObject("Agent.Control.2")
'отключаем обработчик ошибок
On Error Goto 0
'здесь можно проверить, установлен ли Agent на компьютере
If Err.Number Then
MsgBox "Agent не найден на этом компьютере!"
Else
'подключаемся к серверу Agent
MSAgent.Connected = True
'загружаем стандартного персонажа
MSAgent.Characters.Load "Default"
'ссылка на персонаж
Set AgentChar = MSAgent.Characters("Default")
End If
Естественно, здесь тоже можно загрузить любого персонажа, указав в методе Load соответствующий файл.
Важно: При завершении программы не забудьте удалить ссылки на все созданные объекты, иначе после завершения в памяти могут остаться
не освобожденные участки памяти, которые будут недоступны для других программ. Это, впрочем, касается не только
Agent.
Если загрузка персонажа прошла нормально и в его файле имеется значок, то он появится в Taskbar'е, и через него можно будет давать персонажу некоторые команды, например, "Показать" и "Скрыть". Кстати, состояние персонажа необходимо отслеживать, потому, что некоторые его методы и свойства, например Speak, доступны, только если персонаж виден на экране.
Обратите внимание, что дальше по тексту я буду использовать AgentChar, подразумевая, что это ссылка на Ваш персонаж.
Стандартные персонажи
В настоящее время на сайте Microsoft доступны четыре стандартных персонажа. Это джин Genie, маг Merlin, попугай Peedy и робот Robby. Кроме стандартных, мне известно более 40 различных персонажей на любой вкус. Большая коллекция персонажей собрана на сайте "Все о MS Agent" (http://allcharacters.chat.ru). А с помощью бесплатного редактора (http://agent.microsoft.com/agent2/sdk/ace.exe) можно создавать своих неповторимых персонажей. Работая со стандартным персонажем, следует помнить, какие анимационные эффекты он поддерживает или проверять наличие анимации с помощью коллекции AnimationNames, которая имеется у каждого персонажа. Выяснив, что нужная анимация поддерживается, можно заставить персонаж воспроизвести ее с помощью метода
Play:
AgentChar.Play "Greet" 'воспроизведем анимацию "Приветствие"
'пробежимся по всей анимации
For Each Animation In AgentChar.AnimationNames
AgentChar.Play Animation
Next
Важно: Некоторые типы анимации, например Hearing являются циклическими (более точную информацию можно получить из описания конкретного персонажа) и об остановке анимации придется позаботиться программисту. Это можно сделать с помощью метода Stop или
StopAll:
Dim MyRequest as Object
'запуск анимации
Set MyRequest = AgentChar.Play ("Hearing_1")
'что-нибудь делать
...
'остановить анимацию
AgentChar.Stop MyRequest
Может возникнуть вопрос: как узнать, что анимация завершена? Для этого можно использовать такой код:
Dim MyRequest as Object
...
MyRequest = AgentChar.Play ("GestureRight")
...
Sub AgentChar _RequestComplete (ByVal RequestID as Object)
If RequestID = MyRequest Then
MsgBox = "Анимация завершена!"
End If
End Sub
У стандартных персонажей есть одна очень интересная особенность, они могут загружать анимацию с web-сервера Microsoft с помощью метода Get. Более того, ваша программа может даже загрузить всего персонажа с сервера, если, конечно, у пользователя будет достаточно быстрое подключение к интернету.
Об анимации мы поговорили, теперь давайте рассмотрим, как можно управлять размерами персонажа, перемещать его по экрану, показывать и прятать.
Для отображения и скрытия персонажа существуют методы Show и
Hide.
AgentChar.Show
...
AgentChar.Hide
Эти методы имеет всего по одному, необязательному, параметру типа Boolean, он указывает, что нужно пропустить анимацию при появлении или скрытии персонажа. По умолчанию параметр равен False, если его значение True, то персонаж появится или спрячется немного быстрее.
В реальной программе вам недостаточно просто показать персонаж, скорее всего его нужно разместить в определенном месте окна, кроме того, иногда персонаж может закрывать собой важные элементы интерфейса вашей программы или введенные пользователем данные, вот тогда вам нужно будет переместить его в другое место. Для перемещения персонажа можно воспользоваться свойствами Top и Left или, лучше всего, методом MoveTo. Здесь нужно сказать, что если Top/Left мгновенно изменяют местоположение персонажа, то MoveTo может делать это с анимацией, персонаж как бы перелетает на новое место. У метода MoveTo есть необязательный параметр, показывающий скорость смены кадров анимации, т.е. скорость его передвижения по экрану, по умолчанию он равен 1000. Если Вам нужно быстро переместить персонаж, то вызовите этот метод с параметром скорости равным 0. Это заставит пропустить анимацию и персонаж переместиться мгновенно.
Говоря об основах управления персонажами, хотелось бы упомянуть одну очень полезную возможность. Это изменяемые размеры персонажей. Изменить их очень просто, для этого существуют два свойства Height и Width, ширина и высота соответственно. Уменьшить персонаж в полтора раза можно так:
AgentChar.Height = AgentChar.Height / 1.5
AgentChar.Width = AgentChar.Width / 1.5
Для того чтобы узнать настоящие размеры, которые были заданы разработчиком персонажа, необходимо обратиться к свойствам OriginalHeight и
OriginalWidth.
Русская речь с английским акцентом
В настоящее время Agent может разговаривать на 11 языках, в числе которых есть и русский. Я уже говорил о том, что ядро Agent должно быть установлено на компьютере, где программа будет выполняться. А для использования персонажа, который будет говорить, нужен ещё и Text-to-speech engine для соответствующего языка. Так, для русского языка это модуль http://activex.microsoft.com/activex/controls/agent2/lhttsrur.exe. Только после его установки ваш персонаж заговорит по-русски.
Чтобы заставить персонажа произнести фразу, существует метод Speak. Перед использованием Speak нужно указать язык, на котором Agent должен говорить, иначе он попытается говорить на языке по умолчанию. Русский язык в Microsoft обычно числится под номером &H0419, и здесь исключения не сделали. Итак:
AgentChar.LanguageID = &H0419
'вот теперь всё готово к "разговорам"!
AgentChar.Speak "Я могу говорить!"
Если вы сделали всё правильно, то Agent произнесет эту фразу. И не только услышите, но и увидите фразу в Balloon, появившемся возле персонажа.
Важно: Обратите внимание, что метод Speak выполняется асинхронно. Если, например, нужно сделать так, чтобы MsgBox появился после произнесения Agent нужного слова, то нужно приложить ещё некоторые усилия и вставить закладку:
AgentChar.Speak "Вы хотите сохранить\mrk=100\ этот файл?"
...
Sub AgentChar _Bookmark (ByVal Bookmark as Long)
'как только Agent дойдет до закладки,
'то мы попадем сюда
'проверим номер закладки
If Bookmark = 100 Then
MsgBox = "Сохранить файл?"
End If
End Sub
Вы уже, наверное, догадались, что для определения закладок существует ключевое слово \mrk=XXX\, где XXX - номер закладки.
Управление речью
Неестественное произношение Agent можно улучшить. Чтобы оживить звучание, заставить Agent сделать правильную интонацию или громче произнести какое-нибудь слово, существуют специальные управляющие коды, которые вставляются непосредственно в текст. Давайте рассмотрим их подробнее.
Код |
Описание |
\Chr=string\ |
Тип голоса:
Normal - нормальный (Default)
Monotone - монотонный
Whisper - шепчущий |
\Ctx=string\ |
Тип произносимого текста:
Address - адрес или телефонный номер
E-mail - электронная почта
Unknown - неизвестный (Default) |
\Emp\ |
Выделяет следующее слово |
\Lst\ |
Повторить предыдущую инструкцию |
\Map="spokentext"="balloontext"\ |
Позволяет отображать один текст, а
произносить другой:
Spokentext - текст для произношения
Balloontext - текст для отображения |
\Mrk=number\ |
Вставляет закладку (было описано выше) |
\Pau=number\ |
Вставляет паузу, в миллисекундах |
\Pit=number\ |
Устанавливает частоту голоса в Гц |
\Rst\ |
Сбрасывает все установки к установкам
по умолчанию |
\Spd=number\ |
Устанавливает скорость вывода речи |
\Vol=number\ |
Громкость речи: от 0 до 65535 |
Давайте посмотрим, как можно вставлять эти коды в текст. Посмотрите на следующий текст:
"Привет читатель журнала "Программист". Этот пример, написанный специально для тебя, показывает некоторые мои возможности. Скажу по секрету: мне очень нравится этот журнал!"
Когда Agent произнесет эту фразу, вы будете разочарованы возможностями голосового синтеза, а если сделаете элементарное форматирование этого текста, то вам даже понравится его речь. Я предлагаю такое форматирование:
"Привет \pau=200\ читатель журнала "Программист". \pau=500\ Этот \Emp\ пример, \pau=200\ \spd=150\ написанный специально для тебя, \Rst\ \pau=200\ показывает некоторые мои возможности. Скажу по секрету: \pau=500\ мне очень нравится этот журнал!"
Честно говоря, голосовой синтезатор пока еще несовершенен и форматирование текста приходится подбирать экспериментальным путем. Но поверьте, эти мучения того стоят.
Важно: Не все синтезаторы поддерживают полный набор управляющих кодов. Мне, например, не удалось заставить Agent изменить тип голоса на более высокий, похожий на женский, а также прошептать русский текст. Хотя некоторые синтезаторы английского текста это позволяют.
Поговорим?
Забавные персонажи Agent, оказывается, умеют еще и слушать! Увы, пока эта возможность реализована только для английского языка. Итак, что же нам предстоит сделать, чтобы программе можно было давать команды голосом. Для начала - загрузить с сервера Microsoft файл (http://activex.microsoft.com/activex/controls/agent2/actcnc.exe), содержащий модуль распознавания речи и установить его. После этого можно работать.
У персонажа существует коллекция Commands, в нее нужно добавить те команды, на которые персонаж должен откликаться. Это можно сделать так:
With AgentChar.Commands
.Caption = "MSAgent Commands"
.Visible = True
.Voice = "MSAgent Commands"
.Add "Bye bye", "Bye bye", "... bye bye ...", True, True
.Add "Hello", "Hello", "... Hello ...", True, True
'другие команды
...
End With
Свойством Caption мы управляем заголовком специального окна Command. Метод Add добавляет новую команду в коллекцию и имеет следующие параметры (по порядку): название, отображаемое в окне название, текст для распознавания, доступность команды и видимость ее в окне команд. Для включения распознавания речи служит метод
Listen.
AgentChar.LanguageID = &H409
AgentChar.Listen True
Важно: Так как распознавание речи доступно только для английского языка, то перед распознаванием надо переключить язык персонажа на английский (&H409), либо явно указать доступный модуль распознавания SRModeID (GUID модуля распознавания).
После включения распознавания Agent начнет слушать, и, как только он распознает любую из команд, генерируется событие Command, параметр UserInput которого содержит объект типа IAgentCtlUserInput. Теперь осталось проверить свойство Name этого объекта, содержащее имя распознанной команды. Обработчик события Command примерно такой:
Dim s As String
s = LCase(CStr(UserInput.Name))
Select Case s
Case "bye bye"
AgentChar.Think "Понял, исчезаю!"
AgentChar.Play "Wave"
AgentChar.Hide
Case "hello"
AgentChar.Think "Привет!"
AgentChar.Play "Greet"
'другие команды
End Select
Есть еще одна полезная возможность в распознавании речи. Объект UserInput имеет свойство Confidence, которое показывает, насколько хорошо распознана команда. Таким образом,[А2] можно игнорировать плохо распознанные команды. Confidence принимает значения от 100 до -100. Минимальное значение Confidence можно задавать для каждой команды отдельно. Кроме того, если проверять свойства Alt1Name и Alt2Name объекта UserInput, то можно увидеть другие команды, на которые Agent счел похожим сказанное пользователем, а в свойствах Alt1Confidence и Alt2Confidence содержится уровень доверия к ним.
Хотелось бы отметить, что распознавание речи пока еще не очень качественное и Agent, иногда ошибается, но, может быть, у меня плохое произношение...
Заключение
Я описал только основные возможности этого замечательного компонента и в заключении хочу подсказать пути для более эффективного его использования. Например, Вы можете загрузить сразу несколько персонажей в коллекцию Characrers и предоставить пользователю выбор между ними, как это сделано в Microsoft Office. Для управления размерами персонажа Вы можете воспользоваться его свойствами Height и Width, а для перемещения персонажа по экрану методом
MoveTo. Вы, также, можете предложить пользователю изменить некоторые настройки персонажа (скорость речи, шрифт для вывода текста, HotKey для активизации ввода голосовых команд и т.д.) показав одно из окон дополнительных параметров объекта PropertySheet, или сделать это самим, воспользовавшись соответствующими свойствами.
Взять пример к статье.
Перепечатка этой статьи в любой форме запрещена. Все права на нее принадлежат журналу "Программист"
Статья опубликована в журнале в январе 2002
http://www.programme.ru