Delphi синтез речи по тексту SAPI

В первую очередь: это не дубликат Delphi и SAPI. У меня есть определенная проблема с "SAPI в Delphi" предмет.

Я использовал превосходное руководство Библиотеки типов Импорта в Delphi 2009 для получения компонента TSpVoice в палитре элементов. Это работает отлично. С

var
  SpVoice: TSpVoice;

Я могу записать

SpVoice.Speak('This is an example.', 1);

получить асинхронный аудиовыход.

Первый вопрос

Согласно документации, я смог бы записать

SpVoice.Speak('This is an example.', 0);

для получения синхронного аудиовыхода но вместо этого я получаю исключение EZeroDivide. Почему это?

Второй вопрос

Но что еще более важно, я хотел бы смочь создать объект SpVoice динамично (я думаю, что это называют к "позднему - связывают" объект SpVoice), частично потому что только очень небольшая часть всех сессий моего приложения будет использовать его, и частично потому что я не хочу принимать существование сервера SAPI в системе конечного пользователя.

С этой целью я попробовал

procedure TForm1.FormClick(Sender: TObject);
var
  SpVoice: Variant;
begin
  SpVoice := CreateOleObject('SAPI.SpVoice');
  SpVoice.Speak('this is a test', 0);
end;

который, по-видимому, не делает ничего вообще! (Замена 0 с 1 дает мне исключение EZeroDivide.)

Отказ от ответственности

Я довольно плохо знаком с автоматизацией COM/OLE. Я сожалею о любом незнании или глупости, показанной мной в этом сообщении...

Обновление

В пользу всех встречающихся с той же проблемой, как я сделал, видео François объяснило, что существует ошибка в SAPI/Windows (некоторая несовместимость где-нибудь), который заставляет следующий код повысить исключение EZeroDivide:

procedure TForm1.FormClick(Sender: TObject);
var
  SpVoice: variant;
begin
  SpVoice := CreateOleObject('SAPI.SpVoice');
  SpVoice.Speak('This is a text.');
end;

Решение, как представлено видео, состоит в том, чтобы изменить управляющее слово FPU:

procedure TForm1.FormClick(Sender: TObject);
var
  SpVoice: variant;
  SavedCW: Word;
begin
  SpVoice := CreateOleObject('SAPI.SpVoice');
  SavedCW := Get8087CW;
  Set8087CW(SavedCW or $4);
  SpVoice.Speak('This is a text.');
  Set8087CW(SavedCW);
end;

И, кроме того, если Вы хотите играть звук асинхронно, затем необходимо удостовериться, что плеер не выходит из объема!

10
задан Community 23 May 2017 в 10:30
поделиться

1 ответ

Возможно, вам будет интересно увидеть этот сеанс CodeRage 4 на «Включение речи в приложениях Delphi (zip)» Вы получите инструкции, которые ищете ... (и я предполагаю, что вы используете Vista или +, так как нулевое деление не происходило в XP)

4
ответ дан 4 December 2019 в 03:38
поделиться
Другие вопросы по тегам:

Похожие вопросы: