首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >识别2个以上属性的SAPI

识别2个以上属性的SAPI
EN

Stack Overflow用户
提问于 2015-12-18 23:22:39
回答 1查看 549关注 0票数 1

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

代码语言:javascript
复制
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
            }
        }
    }
}
EN

回答 1

Stack Overflow用户

发布于 2015-12-19 02:49:29

好吧,很抱歉让你久等了。我做了一个简单的程序,它可能会帮助你弄清楚你想要做什么。

下面是我的语法文件:

代码语言:javascript
复制
<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>

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

代码语言:javascript
复制
#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;
}

您必须更改加载语法调用的路径。据我所知,你正在尝试做的是在一个上下文无关的语法文件中创建语法,并尝试通过编程来实现这一点。通常,您从语法文件开始,并在需要时进行修改。

然而,如果你真的需要通过编程添加新的语法,比如当有人输入新的语法来识别时,那么你可以尝试SPLO_STATIC到SPLO_DYNAMIC,并开始实现你在MSDN post的后半部分中看到的代码。

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

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34358823

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档