Windows Microsoft SAPI子语言问题
我的问题是:当windows 10显示语言设置为英语(英国)时,我的SAPI inproc识别器拒绝加载我的语法文件 系统显示语言设置为UK。语音识别语言是英国的。系统区域设置为英国。SAPI xml格式语法甚至指定LANGID=809——据我所知,所有内容都设置为EN-GB,但语法仍然无法加载 但当显示语言设置为English(美国)时,它可以加载并正常工作 有人知道这是怎么回事吗?这是非常令人沮丧的。。。希望我只是错过了一些简单的东西 SAPI初始化代码:Windows Microsoft SAPI子语言问题,windows,speech-recognition,speech,sapi,microsoft-speech-api,Windows,Speech Recognition,Speech,Sapi,Microsoft Speech Api,我的问题是:当windows 10显示语言设置为英语(英国)时,我的SAPI inproc识别器拒绝加载我的语法文件 系统显示语言设置为UK。语音识别语言是英国的。系统区域设置为英国。SAPI xml格式语法甚至指定LANGID=809——据我所知,所有内容都设置为EN-GB,但语法仍然无法加载 但当显示语言设置为English(美国)时,它可以加载并正常工作 有人知道这是怎么回事吗?这是非常令人沮丧的。。。希望我只是错过了一些简单的东西 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;
}
每当显示语言不是英语(美国)时,即使我确认所有设置都匹配,我也会收到“无法加载语法。请检查语言设置”错误
我真的很感激那些比我更有见识的人的任何见解
Farley您需要显式加载首选语言的识别器。特别是,这:
//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);
CComPtr cpEngineToken;
hr=SpFindBestToken(SPCAT_识别器,L“Language=,NULL,&cpEngineToken);
//检查人力资源
hr=cpEngine->SetRecognizer(cpEngineToken);
您需要将LCID从GetUserDefaultUILanguage转换为十六进制数。您需要显式加载首选语言的识别器。特别是,这:
//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);
CComPtr cpEngineToken;
hr=SpFindBestToken(SPCAT_识别器,L“Language=,NULL,&cpEngineToken);
//检查人力资源
hr=cpEngine->SetRecognizer(cpEngineToken);
您需要将LCID从GetUserDefaultUILanguage转换为十六进制数。问题在于我误解了LoadCmdFromResource()中“language”参数的含义。我会把这归咎于含糊不清的SAPI文档,不过如果我在收到这方面的消息之前有加载其他类型资源的经验的话我原以为它被SAPI以某种方式使用,并且应该与系统和识别器的语言相匹配(这就是它在文档中听起来的样子)。事实证明,它实际上只是指定用于编译包含语法的.RC文件的语言(可能是为了允许在单独的.RC文件中包含多个翻译) 只要我在调用LoadCmdFromResource()时用显式的“0x409”(资源编译器中指定的语言)替换“GetUserDefaultUI()”,代码就可以像最初发布的一样完美地工作。现在,它可以与美国英语、英国英语和可能的所有英语识别器一起工作,并加载在语音控制面板中选择的识别器,而不考虑显示语言设置(甚至可以是非英语) 非常非常感谢埃里克·布朗给我的消息,我开始失去理智了
Farley问题在于我误解了LoadCmdFromResource()中“language”参数的含义。我会把这归咎于含糊不清的SAPI文档,不过如果我在收到这方面的消息之前有加载其他类型资源的经验的话我原以为它被SAPI以某种方式使用,并且应该与系统和识别器的语言相匹配(这就是它在文档中听起来的样子)。事实证明,它实际上只是指定用于编译包含语法的.RC文件的语言(可能是为了允许在单独的.RC文件中包含多个翻译) 只要我在调用LoadCmdFromResource()时用显式的“0x409”(资源编译器中指定的语言)替换“GetUserDefaultUI()”,代码就可以像最初发布的一样完美地工作。现在,它可以与美国英语、英国英语和可能的所有英语识别器一起工作,并加载在语音控制面板中选择的识别器,而不考虑显示语言设置(甚至可以是非英语) 非常非常感谢埃里克·布朗给我的消息,我开始失去理智了
法利不幸的是,这似乎不起作用。事实上,考虑到语音控制面板中的设置已经与显示语言相匹配,如果真是这样的话,我会非常惊讶。所有设置都匹配。不过,我真的很感谢你的帮助,我也很想听听其他的想法!适用于显示语言409(美国),但不适用于809(英国)。SpFindBestToken()和SetRecognizer()均未失败。换句话说,我仍然有完全相同的问题。事实上,您是否为英国安装了识别器引擎?例如,我的Win10机器就没有。是的,先生。我自己安装了它,当我尝试将不同的语言代码传递给SpFindBestToken()时,除了我安装的两个引擎“language=409”和“language=809”,所有调用都返回“failed”。使用inproc识别器时,语音控制面板中的设置或多或少是不相关的。你负责安排一切。此时,我将切换到LoadGrammarFromFile或LoadGrammarFromMemory,这样您就可以将“完全加载语法”与“从资源文件加载语法”分开,因为LoadCmdFromResource文件的langid是资源文件的langid,而不是语法的langid。不幸的是,这似乎不起作用。事实上,考虑到语音控制面板中的设置已经与显示语言相匹配,如果真是这样的话,我会非常惊讶。所有设置都匹配。不过,我真的很感谢你的帮助,我也很想听听其他的想法!适用于显示语言409(美国),但不适用于809(英国)。SpFindBestToken()和SetRecognizer()均未失败。换句话说,我仍然有完全相同的问题。事实上,您是否为英国安装了识别器引擎?例如,我的Win10机器没有