1

我的問題是這樣的:當Windows 10顯示語言設置爲英語(英國)時,我的SAPI inproc識別器拒絕加載我的語法文件。微軟SAPI子語言問題

系統顯示語言設置爲英國。語音識別語言是英國。系統區域設置是英國。 SAPI xml格式語法甚至指定LANGID = 809 - 據我所知,EVERYTHING設置爲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; 
} 

我得到「無法加載語法請檢查語言設置。」的錯誤任何時候顯示語言不是英語(美國),即使我確認所有的設置比賽...

會很感激的任何一種從人的見解比我

更瞭解法利

回答

0

問題是我錯誤地解釋了LoadCmdFromResource()中的「language」參數的含義。我會把它歸咎於不明確的SAPI文檔,儘管如果我有經驗加載一些其他類型的資源之前,我可能已被告知這一點。 ;)我以爲它是由SAPI以某種方式使用的,並且應該匹配系統和識別器的語言(這就是它在文檔中聽起來的樣子)。事實上,它實際上只是指定了用於編譯語法所包含的.RC文件的語言(大概是爲了允許將多個翻譯包含在單獨的.rc文件中)。

只要我在LoadCmdFromResource()的調用中用顯式的「0x409」(在資源編譯器中指定的語言)替換「GetUserDefaultUI()」,代碼就可以像原始發佈一樣完美工作。現在它可以與美國英語,英國英語以及大概所有的英語識別器一起工作,並且無論顯示語言設置如何(甚至可以是非英語),都會在語音控制面板中加載選擇的識別器。

很多非常感謝埃裏克布朗給我提出這個問題,我開始失去了我的想法。

法利

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轉換爲十六進制數。

+0

不幸的是,這似乎並不奏效。事實上,如果考慮到語音控制面板中的設置已經與顯示語言相匹配,我會感到非常驚訝。所有設置匹配。 雖然我很欣賞你的幫助,但我渴望聽到其他的想法! – lequinne

+0

適用於顯示語言409(美國),但不適用於809(英國)。 SpFindBestToken()和SetRecognizer()都不會失敗。換句話說,我仍然有完全相同的問題。 – lequinne

+0

事實上,你是否已經爲en-UK安裝了識別器引擎?例如,我的Win10機器沒有。 –