1

私の問題は次のとおりです。Windows 10 の表示言語が英語 (英国) に設定されていると、SAPI インプロセス認識エンジンが文法ファイルの読み込みを拒否します。

システム表示言語が英国に設定されています。音声認識言語は英国です。システム ロケールは UK です。SAPI xml-format Grammar では 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;
}

すべての設定が一致していることを確認しても、表示言語が英語(米国)ではない場合、「文法を読み込めません。言語設定を確認してください」というエラーが表示されます...

私よりも知識のある方からのあらゆる種類の洞察を本当に感謝します.

ファーリー

4

2 に答える 2

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 から 16 進数に変換する必要があります。

于 2015-12-04T00:30:13.143 に答える
0

問題は、LoadCmdFromResource() の「言語」パラメーターの意味を誤解していたことです。あいまいな SAPI ドキュメントのせいにしますが、以前に他の種類のリソースをロードした経験があれば、これを知らされたかもしれません。;) どういうわけか SAPI によって使用され、システムと認識エンジンの言語と一致するはずだと思っていました (ドキュメントではそのように聞こえました)。実際には、文法が含まれる .RC ファイルをコンパイルするために使用される言語を指定するだけです (おそらく、複数の翻訳を別々の .rc に含めることができるようにするためです)。

LoadCmdFromResource() の呼び出しで "GetUserDefaultUI()" を明示的な "0x409" (リソース コンパイラで指定された言語) に置き換える限り、コードは最初に投稿されたとおりに完全に機能します。現在は、米国英語、英国英語、およびおそらくすべての英語の認識エンジンで動作し、表示言語の設定 (英語以外でもかまいません) に関係なく、音声コントロール パネルで選択された認識エンジンを読み込みます。

これを教えてくれたエリック・ブラウンにとても感謝しています。私は正気を失い始めていました。

ファーリー

于 2015-12-05T03:32:55.340 に答える