SAPI识别多于2个属性 [英] SAPI identifying more than 2 properties

查看:154
本文介绍了SAPI识别多于2个属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在google上找到这个搜索关于SAPI识别短语的一些信息。此示例显示规则中是否只有一个属性。那么如果规则中有2个或更多的属性呢?如何去写这段代码?我仍然困惑于SAPI,并试图理解它。欢迎任何帮助,谢谢!

I found this on google while searching on some information on SAPI identifying phrases. This example shows if there is only one property in the rule. So what if there are 2 or more properties in that rule? How would one go about writing the code for this? I am still confused about SAPI and trying to understand it. Any help is welcome, thanks!

The alternate method is add a property to your list tag/items [you appear to
 be familiar with properties], iterate through the property tree to find the
property, and then retrieve the associated item from the property. Note if
this is the only property in your recognized rule, then it is fairly easy to
retrieve the property [no need to navigate the property tree].
For example, you could change your rule to be the following:

<RULE ID="VID_Vcs">
<L PROPNAME="NAME_LIST">
   <P VAL="1">Mike </P>
   <P VAL="2">Davor </P>
   <P VAL="3">Kurt </P>
   <P VAL="4">Steve </P>
</L>
</RULE>


Use the following code to retrieve the list item value/phrase text
SPPHRASE* pPhrase = NULL;
hr = cpRecoResult->GetPhrase(&pPhrase);
// Check hr

// Let's assume that you only have one property in your rule, so there is only one property in the property tree.
// ASSERT: NULL == pPhrase->pProperties->pNextSibling && NULL == pPhrase->pProperties->pFirstChild
// ASSERT: NULL != pPhrase->pProperties->pszName && 0 == wcscmp(pPhrase->pProperties->pszName, L"NAME_LIST")

// retrieve the list item index [e.g. 1-4], see VAL XML tags in aforementioned grammar
long lRecognizedListItemIndex = pPhrase->pProperties->vValue.lVal;

// retrieve the phrase text
hr = cpRecoResult->GetText(pPhrase->pProperties->ulFirstElement, pPhrase->pProperties->ulCOuntOfElements, FALSE, &pwszListItem, NULL);
// Check hr

// pwszListItem now contains the recognized list item


//compared to the phrase tag of the dictionary (XML)
if(SUCCEEDED (hResult)) {
    if ((pPhrase->pProperties != nullptr) &&         (pPhrase->pProperties->pFirstChild != nullptr)){
        const SPPHRASEPROPERTY* pRule = pPhrase->pProperties->pFirstChild ;
        if (pRule->SREngineConfidence->confidence Threshold) {
            if ( wcscmp ( L"word one", pRule->pszValue) == 0 ) {
                //do stuff here
            }
            else if ( wcscmp ( L"word two", pRule->pszValue) == 0 ) {
                //do stuff here
            }
            else if ( wcscmp ( L"word three", pRule->pszValue) == 0 ) {
                //do stuff here
            }
            else if ( wcscmp ( L"word four", pRule->pszValue ) == 0) {
                //do stuff
            }
        }
    }
}


推荐答案

很好,我打开了一个简单的程序,可以帮助你找出你想要做什么。

Alright, so sorry for the wait. I whipped up a simple program that may help you figure out what you're trying to do.

这里是我的语法文件:

<GRAMMAR LANGID="409">
    <DEFINE>
        <ID NAME="LIKE_VAL" VAL="1"/>
        <ID NAME="SUBJECT_VAL" VAL="2"/>
        <ID NAME="COMBINED_VAL" VAL="3"/>
        <ID NAME="EXIT_VAL" VAL="4"/>
    </DEFINE>
    <RULE NAME="LIKE_VAL" TOPLEVEL="ACTIVE">
        <L>
            <P>I <O>really</O> like</P>
            <P>I <O>really</O> do not like</P>
        </L>
    </RULE>
    <RULE NAME="SUBJECT_VAL" TOPLEVEL="ACTIVE">
        <P>ponies.</P>
    </RULE>
    <RULE NAME="COMBINED_VAL" TOPLEVEL="ACTIVE">
        <RULEREF NAME="LIKE_VAL"/>
        <RULEREF NAME="SUBJECT_VAL"/>
    </RULE>
    <RULE NAME="EXIT_VAL" TOPLEVEL="ACTIVE">
        <L>
            <P>Exit</P>
            <P>Quit</P>
            <P>Terminate</P>
            <P>Deluminate</P>
        </L>
    </RULE>
</GRAMMAR>

下面是一个使用它的完整程序:

And here's a full program that uses it:

#include "sphelper.h"
#include <Windows.h>
#include <string>

int main(int argc, char* argv[])
{
    CComPtr<ISpRecognizer> cpReco;
    CComPtr<ISpRecoContext> cpRecoCtx;
    CComPtr<ISpRecoGrammar>  cpRecoGram;

    ULONGLONG ullEvents = SPFEI(SPEI_RECOGNITION)|
       SPFEI(SPEI_FALSE_RECOGNITION);

    ISpObjectToken* pInputToken;
    ISpRecoResult* cpRecoRslt;
    HRESULT hr = S_OK;

    hr = ::CoInitialize(NULL);
    hr = cpReco.CoCreateInstance(CLSID_SpInprocRecognizer);
    hr = cpReco->CreateRecoContext(&cpRecoCtx);
    hr = cpRecoCtx->CreateGrammar(0, &cpRecoGram);
    hr = cpRecoCtx->SetNotifyWin32Event();

    hr = cpRecoCtx->SetInterest(ullEvents, ullEvents);
    hr = SpGetDefaultTokenFromCategoryId(SPCAT_AUDIOIN, &pInputToken);
    hr = cpReco->SetInput(pInputToken, FALSE);
    hr = cpRecoGram->LoadCmdFromFile(L"Your_Test_File.cfg",SPLO_STATIC);
    hr = cpReco->SetRecoState(SPRST_ACTIVE);
    hr = cpRecoCtx->SetContextState(SPCS_ENABLED);
    hr = cpRecoGram->SetGrammarState(SPGS_ENABLED);
    hr = cpRecoGram->SetRuleState(NULL, NULL, SPRS_ACTIVE);
    std::wstring strExit = L"Exit";
    std::wstring strExitRuleName = L"EXIT_VAL";
    CSpEvent spEvent;
    bool isListening = true;
    do{
        hr = cpRecoCtx->WaitForNotifyEvent(INFINITE);
        if(spEvent.GetFrom(cpRecoCtx) == S_OK)
        {
            switch(spEvent.eEventId){
                case SPEI_RECOGNITION:{

                    WCHAR* strReco = 0;
                    cpRecoRslt = spEvent.RecoResult();
                    cpRecoRslt->GetText(SP_GETWHOLEPHRASE, SP_GETWHOLEPHRASE, TRUE, &strReco, NULL);
                    printf("%ls\n",strReco);

                    SPPHRASE *phrase = NULL;
                    cpRecoRslt->GetPhrase(&phrase);
                    if(phrase){
                        std::wstring ruleName = phrase->Rule.pszName;
                        if(strExitRuleName.compare(strExit)==0){
                            isListening = false;
                        }
                    }
                    break;
                }
                case SPEI_FALSE_RECOGNITION:{
                    printf("False Recognition\n");
                    break;
                }
            }
        }
    }while(isListening);

    cpRecoGram.Release();
    cpRecoCtx.Release();
    cpReco.Release();

    ::CoUninitialize();
    printf("Press any key to continue...");
    getchar();

    return 0;
}

您必须更改加载语法调用加载的路径从。从我明白你想要做的是在一个上下文自由语法文件中创建语法,并尝试这样做编程。通常,你需要从一个语法文件开始,并在需要时进行修改。

You'll have to change the path of where the load grammar call is loading from. From what I understand what you're attempting to do is create grammar in a context free grammar file AND try to do this programmatically as well. Typically you start with a grammar file and modify when you need to.

但是,如果你真的需要以编程方式添加新的语法,语法被识别,那么你会偶尔SPLO_STATIC到SPLO_DYNAMIC,并开始实现你看到的MSDN后半部分你看到的代码。

If, however, you REALLY REALLY need to add new grammars programmatically, such as when someone's typing in new grammar to be recognized, THEN you'd chance SPLO_STATIC to SPLO_DYNAMIC and start implementing the code you see in the later half of the MSDN post you saw.

我完全放弃任何错误检查。如果您需要访问您正在查看的规则的其他属性,请使用pPhrase-> GetPhrase(& phrase)区域。除了规则的名称,您还可以获取其ID。

I completely left out any error checking. If you need to access other properties of the rule you're looking at, use the pPhrase->GetPhrase(&phrase) area. Other than just the rule's name you can also get it's ID.

这篇关于SAPI识别多于2个属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆