Подписка

добавить на Яндекс

Наши проекты

Delphi+Google

Google API

Google API в Delphi - проект с открытым исходным кодом.

Chrono

Chrono

Хронометр - программа для ведения списка задач.

ODFProc

ODFProc

ODFProc - работа с документами OpenOffice в Lazarus и FreePascal.

Поддержка блога

А тут я коплю на лицензию Delphi XE на iPad =).
Сумма пожертвования не фиксирована.

Публикации

Год назад

Случайный пост

Последние

Сообщения форума

Комментарии

Социальные сети

Google

Facebook

Twitter

Опрос

Вы сейчас или в ближайшем обозримом будущем планируете разрабатывать кроссплатформенное приложение с использованием Firemonkey?



Loading ... Loading ...

Блоги и сообщества

Статьи по Delphi DelphiFeeds.ru - Все Delphi-блоги Рунета Сообщество умных людей VR-Online.RU Бесплатный журнал для программистов и всех, кто интересуется IT Статьи и уроки по Delphi Новостной блог о высоких технологиях
Система Orphus
Опубликовал Vlad 4 мая 2010 в 15:05.
Категории: MS Agent в Delphi.


Не так давно (26 марта 2010 года) я рассказывал Вам о том, как применить технологию Text-To-Speech (чтение текста голосом) в Delphi 2010 с использованием Speech API (SAPI) Windows. И всё бы было хорошо, если б не одно маленькое, но суровое "НО". Дело в том, что при запуске проекта не из IDE Delphi вызов метода Speak у интерфейсов IspVoice и ISpeechVoice вызывал ошибку "Floating Point Division By Zero" (деление на ноль). При этом в Windows XP программа работала без проблем. Ошибку эту обнаружил читатель с ником ziz.
В поисках решения проблемы я решил немного расширить статью и рассмотреть ещё несколько моментов по работе с технологией Text-To-Speech в Delphi. Сегодня рассмотрим работу SAPI 5.4. с использованием объекта TspVoice. Так что импортируйте библиотеку SAPI 5.4. для Windows 7, генерируйте модуль SpeechLib_TLB.pas, как это рассказано в предыдущем посте и начнем.

Вначале реализуем чтение голосом какого-либо отрывка текста с использованием класса TspVoice.

var gpIVTxt: TSpVoice;
begin
  gpIVTxt:=TSpVoice.Create(nil);
  gpIVTxt.Speak('Hello',SVSFlagsAsync);
end;

Здесь мы используем асинхронный вывод. К слову сказать, синхронный вывод от асинхронного отличается тем, что асинхронный вывод используется в случае, когда в процессе синтеза речи программа должна выполнять какие-то дополнительные действия (подсвечивать синтаксис, обрабатывать данные в потоке и т.д.). В Windows 7 мне так и не удалось реализовать синхронный вывод (флаг SVSFDefoult) и с чем это связано пока сказать не могу. У кого-нибудь есть идеи на этот счёт?
Так что пока будем использовать везде асинхронный вывод.
Двигаемся дальше и попробуем изменить свойства голосового движка.

Характеристики голоса

Любой голосовой движок, использующий SAPI имеет следующие характеристики:
Volume - громкость голоса. Целочисленное значение. Изменяется линейно в диапазоне от 0 до 100. То есть значение 50 будет соответствовать половине предельной громкости используемого голоса.
Rate - скорость воспроизведения текста голосом. Может принимать значения от -10 до 10. Значение по умолчанию 0. Соответственно отрицательные значение характеристики замедляют произношение, положительные - ускоряют. SAPI 5-х версий не поддерживают значения Rate больше 10 или меньше -10, т.е. если Вы устанавливаете значение Rate=11, то голос будет воспроизводиться на скорости 10.
Попробуем реализовать изменение характеристик голоса в нашей программе. Разместим на форме два компонента TrackBar и 2 Label как показано на рисунке:

Соответственно первый TrackBar будет изменять громкость от 0 до 10, а второй - скорость от -10 до 10.
Теперь перенесем переменную gpIVTxt: TSpVoice в секцию public класса TForm1 и будем создавать класс TspVoice в момент создания формы, т.е.:

procedure TForm1.FormCreate(Sender: TObject);
begin
  gpIVTxt:=TSpVoice.Create(nil);
end;

Обработчики OnChange у TrackBar'ов будут следующими:

procedure TForm1.TrackBar1Change(Sender: TObject);
begin
  VolumeLabel.Caption:=IntToStr(TrackBar1.Position);
  gpIVTxt.Volume:=TrackBar1.Position;
end;
 
procedure TForm1.TrackBar2Change(Sender: TObject);
begin
  RateLabel.Caption:=IntToStr(TrackBar2.Position);
  gpIVTxt.Rate:=TrackBar2.Position;
end;

Теперь запустите приложение и попробуйте изменять значение Rate и Volume во время произношения фразы. Т.к. используется асинхронный вывод, то характеристики голоса изменяются "на лету".
Английский голос - это конечно здорово, но как быть с русскими голосами в SAPI? Посмотрим как можно использовать русскоязычные движки в своей программе.

SAPI и русские голоса.

В качестве русскоязычного движка я выбрал движок от Acapela Group c названием "Алёна". Неплохой движок с пробным периодом в 30 дней. Какой движок выберите Вы - значения не имеет, т.к. работать мы будем с SAPI не влезая в особенности каждого движка, т.е., следуя схеме:

Будем использовать два верхних уровня.
Итак, для того, чтобы получить сведения о всех голосовых движках, установленных в системе, нам понадобится воспользоваться интерфейсом ISpeechObjectTokens, который имеет всего одно свойство Count - количество голосовых движков, установленных в системе. И один метод:

Item(i:index):ISpObjectToken

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

public
  ...
  Voices:ISpeechObjectTokens;
...
 
procedure TForm1.GetMyVoices(List: TListBox);
var i:integer;
begin
  List.Clear;
  Voices:=gpIVTxt.GetVoices('','');
  for i:=0 to Voices.Count - 1 do
    List.Items.Add(Voices.Item(i).GetDescription(0));
end;

Здесь мы вначале запрашиваем методом GetVoices все голоса поддерживаемые объектом TspVoice. И затем выводим в ListBox описания голосов. Результат будет выглядеть следующим образом:

Теперь мы можем назначить нашему объекту голос, например так:

gpIVTxt.Voice:=Voices.Item(0);

В этом случае будет использоваться голос "Anna (English)". А так:

gpIVTxt.Voice:=Voices.Item(1);

Голос "Alyona (Ruusian)".
При этом для нас нет разницы какой из голосов мы используем - русский или английский, встроенный в систему или скачаный с какого-нибудь варезника и установленный вручную - подход к управлению один и тот же (см. схему).
Для того, чтобы вывести сведения о голосов ListBox мы использовали в качестве данных - описание голоса. Кроме этого, каждый голос в системе может содержать следующие полезные атрибуты:

  1. Name - имя;
  2. Gender - пол;
  3. Age - возраст;
  4. Language - язык;
  5. Vendor - создатель;

Для того, чтобы получить значения какого-либо атрибута необходимо воспользоваться методом ISpeechObjectToken:

function GetAttribute(const AttributeName: WideString): WideString;

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

procedure TForm1.ListBox1Click(Sender: TObject);
begin
Label7.Caption:=Voices.Item(ListBox1.ItemIndex).GetAttribute('Name');
Label8.Caption:=Voices.Item(ListBox1.ItemIndex).GetAttribute('Age');
Label9.Caption:=Voices.Item(ListBox1.ItemIndex).GetAttribute('Gender');
Label12.Caption:=Voices.Item(ListBox1.ItemIndex).GetAttribute('Language');
Label13.Caption:=Voices.Item(ListBox1.ItemIndex).GetAttribute('Vendor');
end;

А в запущенном приложении так:

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

  AttributeName=Value
  AttributeName!=Value

Следующие два вызова метода GetVoices абсолютно идентичны и в результате вернут 2 установленных в моей системе голоса:

  Voices:=gpIVTxt.GetVoices('Gender=female','');
  Voices:=gpIVTxt.GetVoices('Gender!=male','');

Ну и в заключение, выкладываю исходники, рассмотренного в статье приложения. Качайте:
Исходник программы

-----------------------
Обзор Интернет-магазинов Рунета
Сегодня Интернет представляет собой не только какую-то виртуальную реальность, но и вполне удобный рынок товаров и услуг самого широкого спектра. ас уже не удивляют такие вещи как Интернет-аукционы или интернет-магазины, где можно купить или продать абсолютно всё - от шариковой ручки до загородного дома. Кстати, о домах и интернет-магазинах, недавно обнаружил специализированный интернет-магазин Ceramica-Classic, занимающийся продажей керамической плитки и отделочных материалов в Интернет. Так что, если Вас интересует, например, итальянская керамическая плитка, то не стоит бежать сразу в магазин - достаточно обратиться к ceramica-classic.ru и оформить заказ.
-----------------------
Понравилась статья? Тогда:
Делись! Загружай! Плюсуй!
   Отправить PDF на   
Читай ещё статьи на WebDelphi.ru

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

WP_Cloudy
  • ziz пишет:

    спасибо что помог)
    офигенная статья, блог, и знания delphi)

  • ziz пишет:

    http://ancher.ru/content/19-02-2009/audioknigi-delaem-sami
    мануал по установке алёны)

  • Kanzaki пишет:

    Спасибо за метериал. Очень помог!

  • Suvlehim пишет:

    А у меня наоборот,
    gpIVTxt.Speak(‘Hello’,SVSFlagsAsync);
    с ассинхроном на 7 проблемы, а с Default все отлично работает

  • Xatrix пишет:

    Почему-то при компиляции вашего исходника у меня вылезает сообщение об отсутствии SAPIEngineLib_TLB.dcu   Обыскал весь компьютер! Нету у меня не SAPIEngineLib_TLB.dcu не SAPIEngineLib_TLB.pas
    p.s Есть только SpeechLib_TLB.pas и SpeechLib_TLB.dcu

  • Xatrix пишет:

    Да, забыл сказать, у меня Win7 и Delphi 2010

  • Vlad пишет:

    Импортировать его надо.

  • Xatrix пишет:

    А как его импортировать?

  • Vlad пишет:

    Как обычную библиотеку типов. Через меню «Component — Import Component»

  • Xatrix пишет:

    Так я ее имопортировал, но у меня появляется только SpeechLib_TLB, а он требует еще SAPIEngineLib_TLB. Скиньте мне пожалуйста его на wlad-mozg@yandex.ru если вас не затруднит.

  • Oleg пишет:

    Какую именно библиотеку импортировать? Speech 5.4 импортировал, но у меня тоже самое, как и у Xatrix нет SAPIEngineLib_TLB.

  • Vlad пишет:

    Oleg, у меня только Speech 5.4 и *_tlb.pas тоже есть. При импорте библиотеки галку ставите на создание обертки для библиотеки? А созданный файл сохраняете куда-то?

  • Oleg пишет:

    И галку ставлю и сохраняю.

Ваш ответ

Внимание: Все комментарии модерируются, и это может вызвать задержку их публикации. Отправлять комментарий заново не требуется.

Пожалуйста, заключайте исходный код в тэги [code][/code].
Если код большой, то воспользуйтесь Вставкой кода на отдельной странице и оставьте в комментарии ссылку на исходник

   


Газель бизнес купить. Новая газель бизнес класс. Газель бизнес. --|--. скачать skype