我的问题是:当Windows 10显示语言设置为英语(英国)时,我的SAPI inproc识别器拒绝加载我的语法文件。
系统显示语言设置为英国。语音识别语言是英国。系统区域设置是英国。 SAPI xml格式语法甚至指定LANGID = 809 - 据我所知,一切都设置为EN-GB,但语法仍然无法加载。
但它在显示语言时加载并正常工作,并设置为英语(美国)。
有谁知道这有什么用?这非常令人沮丧......希望我只是遗漏了一些简单的东西。
SAPI初始化代码:
//////////////INITIALIZE SAPI ENGINE AND GRAMMAR//////////////////////////////
HRESULT SpeechObject::Initialize(){
//INITIALIZE SR ENGINE
if (FAILED(test=::CoInitialize(NULL)))
SRError(L"COM Initialization Fail");
//Create recognizer instance
if (FAILED(test=cpEngine.CoCreateInstance(CLSID_SpInprocRecognizer))){
SRError(L"Can't Load Reco Engine");
return test;
}
//Load the audio Input (in seperate function to facilitate reload)
LoadAudio(); //should I check this?
//load Default recognizer settings
cpEngine->SetRecognizer(NULL);
//get and load default reco profile
if (FAILED(SpGetDefaultTokenFromCategoryId(SPCAT_RECOPROFILES, &cpObjectToken)))
SRError(L"Can't Find Recognition Profile");
if (FAILED(cpEngine->SetRecoProfile(cpObjectToken)))
SRError(L"Can't Load Recognition Profile");
//create reco context
if (FAILED(test=cpEngine->CreateRecoContext(&cpContext))){
SRError(L"Can't Create Reco Context");
return test;
}
//send pSpeechObject to global callback function
cpContext->SetNotifyCallbackFunction(
(SPNOTIFYCALLBACK*)SpeechCallBack,
NULL, (LPARAM)this);
if(FAILED(cpContext->CreateGrammar(NULL, &cpGrammar)))
SRError(L"Can't Create context");
char str[80]; ////TEST
sprintf(str, "LANGID: %X", GetUserDefaultUILanguage());
MessageBoxA(GetActiveWindow(), str,0,0);
//load grammar from compiled grammar resource
if (FAILED(test = cpGrammar->LoadCmdFromResource(
hModule, MAKEINTRESOURCE(GRAMMARCFG),
L"FILE", GetUserDefaultUILanguage(), SPLO_STATIC))){
SRError(L"Can't Load Grammar. Please check language settings");
return test;
}
//(comment above and uncomment following to load from raw xml file for testing)
//cpGrammar->LoadCmdFromFile(L"Grammar.xml", SPLO_STATIC);
//Enable Engine and Reco Context
cpEngine->SetRecoState(SPRST_ACTIVE);
cpContext->SetContextState(SPCS_ENABLED);
//enable ALWAYS ACTIVE and GROUND ENGINES ON commands
return(cpGrammar->SetRuleState(NULL, NULL, SPRS_ACTIVE));
}
////////////LOAD (AND RELOAD) AUDIO INPUT//////////////////////
HRESULT SpeechObject::LoadAudio(bool dlgFlag){
if (FAILED(test = SpCreateDefaultObjectFromCategoryId(SPCAT_AUDIOIN, &cpAudioIn))){
SRError(L"Can't Find Default Audio Input");
return test;
}
if (FAILED(test = cpEngine->SetInput(cpAudioIn, TRUE))){
if (!dlgFlag)
SRError(L"Can't Set Audio Input");
return test;
}
if (pSRDisplay)
pSRDisplay->DisplayText("Audio Reloaded");
if (pDLog)
pDLog->LogEvent("Audio Reloaded");
//RecoState must be reenabled after audio reset
cpEngine->SetRecoState(SPRST_ACTIVE);
if (pDLog)
pDLog->LogEvent("SR ENABLED");
return test;
}
我得到了#34;无法加载语法。请检查语言设置"如果显示语言不是英语(美国),即使我确认所有设置都匹配...
,也会出现错误非常感谢比我更有知识的人的任何见解。
法利
答案 0 :(得分:0)
您需要为首选语言显式加载识别器。特别是:
//load Default recognizer settings
cpEngine->SetRecognizer(NULL);
始终加载语音控制面板中指定的识别器。你可能想要这样的东西:
CComPtr<ISpObjectToken> cpEngineToken;
hr = SpFindBestToken(SPCAT_RECOGNIZERS, L"Language=<hex language id>", NULL, &cpEngineToken);
// check hr
hr = cpEngine->SetRecognizer(cpEngineToken);
您需要将LCID从GetUserDefaultUILanguage转换为十六进制数字。
答案 1 :(得分:0)
问题在于我误解了&#34;语言的含义&#34; LoadCmdFromResource()中的参数。我会把它归咎于模棱两可的SAPI文档,不过如果我有经验加载其他类型的资源之前我可能会被告知这一点。 ;)我以为它是由SAPI以某种方式使用的,应该与系统和识别器的语言相匹配(这就像在文档中听起来的那样)。事实证明,它实际上只是指定了用于编译.RC文件的语言,该文件包含在语法中(可能是为了允许多个翻译包含在单独的.rc中)。
代码与最初发布的完美匹配,只要我替换&#34; GetUserDefaultUI()&#34;用一个明确的&#34; 0x409&#34; (在资源编译器中指定的语言)在对LoadCmdFromResource()的调用中。现在它适用于美国英语,英国英语和大概所有英语识别器,并加载在语音控制面板中选择的识别器,无论显示语言设置如何(甚至可以是非英语)。
很多,非常感谢埃里克·布朗让我这么做,我开始失去理智。
法利