MS Agent и Delphi

Автор: Denis Butorin

Источник: http://subritto.h1.ru

Теперь давайте заставим MS Agent говорить, используя движки синтеза речи. Это намного легче , чем просто предложить поболтать Delphi.

Как вы уже знаете, для того чтобы персонаж MS Agent прочитал текст, нужно применить к нему метод speak . Чтение текста будет производиться через движок, установленный по умолчанию. Для того чтобы изменить речевой синтезатор на тот, через который вы желаете осуществить чтение, надо изменить всего один "проперти" у персонажа. Это TTSModeID, а меняется он методом Set_TTSModeID. Поэтому в разделе private нужна всего лишь одна новая переменная, та с помощью которой мы станем перебирать речевые движки и узнавать их параметры:

private
 ...
 {Интерфейс для перебора движков}
 aTTSEnum: ITTSEnum;

В обработке события создания формы добавим код сканирования речевых синтезаторов. Конечная процедура примет вид:

procedure TForm1.FormCreate(Sender: TObject);
var
 NumFound : DWord;
 ModeInfo : TTSModeInfo;
begin
 Agent1.Characters.Load('MyAgent', 'Genie.acs');
 Chars:= Agent1.Characters.Character('MyAgent') as IAgentCtlCharacterEx;
 ShowAgentAnim; //Создание списка анимаций персонажа
 Req:=Chars.Show(0);
 CoCreateInstance(CLSID_TTSEnumerator, Nil, CLSCTX_ALL,IID_ITTSEnum, aTTSEnum);
 aTTSEnum.Reset;
 aTTSEnum.Next(1, ModeInfo, @NumFound);
 While NumFound > 0 do
 begin
 ComboBox1.Items.Add(String(ModeInfo.szModeName));
 aTTSEnum.Next(1, ModeInfo, @NumFound);
 end;
end;

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

procedure TForm1.ComboBox1Change(Sender: TObject);<
var
NumFound: DWord;

{Для хранения информации о текущем движке}
ModeInfo: TTSModeInfo;

begin
try
CoCreateInstance(CLSID_TTSEnumerator, Nil, CLSCTX_ALL, 
  IID_ITTSEnum, aTTSEnum);
aTTSEnum.Reset;
{Перескакиваем на нужный движок}
Form1.aTTSEnum.skip(ComboBox1.ItemIndex);
 aTTSEnum.Next(1, ModeInfo, @NumFound);
{Изменяем речевой синтезатор у персонажа}
 Chars.Set_TTSModeID(GUIDToString(ModeInfo.gModeID));
 except
 end;
end;

В последней строчке используется еще одна интересная функция GUIDToString ! Дело в том, что в метод Set_TTSModeID нужно передать идентификатор интерфейса движка, то есть GUID(Globally Unique IDentifier). Но его надо передавать не в родном его типе(т.е. в TGUID), а в WideString. Поэтому приходится пользоваться функцией из ComObj.pas. Кстати есть и обратная функция StringToGUID(const S: string): TGUID; это я так, на всякий случай...

Вот и все! Теперь персонаж будет читать текст методом speak через выбранный движок!

Полный текст программы можно взять здесь (~216 Кб)



Распространение материалов сайта означает, что распространитель принял условия лицензионного соглашения.
Идея и реализация: © Владимир Довыденков и Анатолий Камынин,  2004-2024