Попытка использовать MS Speech API v11 с японским движком (MS Haruka) в Delphi 10.3.
У меня есть пример приложения с формой и кнопкой. Обработчик щелчков выглядит так:
uses SpeechLib11_TLB; // Imported from "Microsoft Speech Object Library" v.B.0
procedure TForm1.Button1Click(Sender: TObject);
var
v: ISpeechVoice;
begin
v := CoSpVoice.Create();
//5.4 only but won't hurt
v.Voice := v.GetVoices('language=411', '').Item(0);
v.Speak('時間', SVSFDefault);
end;
Это приводит к ошибке «Ошибка Catastrophi c» (HRESULT 0x8000FFFF, E_UNEXPECTED). Код, который я думаю, должен быть эквивалентным, работает в проекте C ++:
#include <windows.h>
#import "libid:d3c4a7f2-7d27-4332-b41f-593d71e16db1" rename_namespace("SAPI") //v11
//#import "libid:C866CA3A-32F7-11D2-9602-00C04F8EE628" rename_namespace("SAPI") //v5.4
int wmain()
{
CoInitializeEx(0, COINIT_APARTMENTTHREADED);
{
SAPI::ISpeechVoicePtr v;
v.CreateInstance(__uuidof(SAPI::SpVoice));
//Needed for 5.4 only, but won't hurt
SAPI::ISpeechObjectTokensPtr voices(v->GetVoices(L"language=411", L""));
v->Voice = voices->Item(0);
v->Speak(L"時間", SAPI::SVSFDefault);
}
CoUninitialize();
return 0;
}
Это работает и говорит. Таким образом, SAPI per se не сломан на машине. Платформа Win32 в обоих проектах, а не Win64. Японский голос является голосом по умолчанию (нет необходимости устанавливать его явно).
Тот же результат с собственно SAPI 5.4 (не OneCore), хотя японский голос не является голосом по умолчанию, и мне пришлось добавить пару строк, чтобы установить его как значение по умолчанию.
Дальнейшая отладка показывает, что на стороне Delphi столько, сколько вызов метода получения свойства v.Voice
сразу после первой строки вызывает ту же ошибку E_UNEXPECTED. Между тем, Voice
setter работает, если вы передаете ему действительный объект голосового токена из GetVoices()
. Похоже, что голосовой объект правильно инициализирует себя в C ++ по умолчанию, но каким-то образом пропускает это в проекте Delphi.
Запрос v.Voice
сразу после выполнения работ, хотя в Delphi с SAPI 5.4. Вызов Speak()
по-прежнему выдает E_UNEXPECTED.
В чем может быть разница в контексте выполнения процесса / потока между C ++ и Delphi? Это не локаль потока. Модель COM-потока - квартира в обоих.
Тот же самый код Delphi работает с фразой Engli sh и голосом Engli sh (MS Helen). Так что, какой бы ни был сбой инициализации, он, вероятно, указывает c на Харуку.
Время выполнения SAPI 11 доступно здесь . Данные языка для TTS здесь .
Другая точка данных. Я переписал логи SAPI c в Delphi, чтобы вместо них использовать SAPI 5.4 OneCore (а не SAPI 5.4). В отличие от 5.4 и 11, он не предоставляет интерфейс на основе IDispatch, и он несколько неуклюже, особенно в Delphi, но японский TTS работает. Вопрос в том виде, в котором он изначально поставлен , до сих пор остается без ответа, но, по крайней мере, есть обходной путь. Я напишу ответ, но я не приму его.
Однако виноваты не обычные различия, а двойные. Я изменил логи c для использования пользовательских интерфейсов вместо с SAPI 5.4 собственно (typelib определяет оба), по-прежнему получая E_UNEXPECTED
из Speak()
. Нет информации об ошибках.
Вот еще один прекрасный момент для данных: SAPI 5.4 TTS с API-интерфейсом, основанным на автоматизации, работает и разговаривает, как и ожидалось, в Delphi консольном приложении . Так что это даже не Delphi специфика c, это как-то спецификация VCL c. Что это с Delphi GUI? Само собой разумеется, я немедленно перепроверил фрагмент кода C ++ в приложении C ++ GUI с формой и кнопкой. С ++ говорит.