0

このSAPI文法は、単語名が文の途中にあることを示しています。

<GRAMMAR LANGID="409">
    <RULE NAME="SOUNDLOG" TOPLEVEL="ACTIVE">
        <OPT>
            <DICTATION MAX="INF"/>
        </OPT>
        <L>
            <P>name</P>
        </L>
        <OPT>
            <DICTATION MAX="INF"/>
        </OPT>
    </RULE>
</GRAMMAR>

したがって、「私の名前はアンドレ」と言うと、「名前」という単語が識別されます。これを行うためのより良い方法はありますか?

4

1 に答える 1

2

認識を取得すると、認識に関連付けられた SPPHRASE データには、サブルールとプロパティ データ、およびそれらが認識内で発生する場所が含まれます。

そのため、「名前」のルールまたはプロパティ タグがあれば、「名前」に関連付けられた単語を見つけることができます。

たとえば、あなたの文法を考えると

<GRAMMAR LANGID="409"> 
    <RULE NAME="SOUNDLOG" TOPLEVEL="ACTIVE"> 
        <OPT> 
            <DICTATION MAX="INF"/> 
        </OPT> 
        <L> 
            <P>name</P> 
        </L> 
        <OPT> 
            <DICTATION MAX="INF"/> 
        </OPT> 
    </RULE> 
</GRAMMAR> 

に変更すると

<GRAMMAR LANGID="409"> 
    <RULE NAME="SOUNDLOG" TOPLEVEL="ACTIVE"> 
        <OPT> 
            <DICTATION MAX="INF"/> 
        </OPT> 
        <L PROPNAME='name'> 
            <P VAL='name'>name</P> 
        </L> 
        <OPT> 
            <DICTATION MAX="INF"/> 
        </OPT> 
    </RULE> 
</GRAMMAR> 

次のように「名前」に対応する単語を見つけることができます。

HRESULT OnRecognition(ISpRecoResult* pResult)
{
    SPPHRASE *pPhrase;
    HRESULT hr = pResult->GetPhrase(&pPhrase);
    if (SUCCEEDED(hr))
    {
         const SPPHRASEPROPERTY pProp = FindProperty(pPhrase->pProperty, L"name");
         if (pRule)
         {
             LPWSTR text(NULL);
             hr = pResult->GetText(pProp->ulFirstElement, pProp->ulCountOfElements, TRUE, &text, NULL);
             if (SUCCEEDED(hr))
             {
                 // do something with text
                 ::CoTaskMemFree(text);
             }
         }
    }
    return hr;
}
const SPPHRASEPROPERTY* FindProperty(const SPPHRASEPROPERTY* pProp, LPCWSTR what) const
{
    while (pProp!=NULL)
    {
        if (pProp->pFirstChild != NULL)
        {
            const SPPHRASEPROPERTY* pFoundProp = FindRule(pProp->pFirstChild, what);
            if (pFoundProp)
            {
                return pFoundProp;
            }
        }
        if (pProp->pszName != NULL && wcsstr(pProp->pszName, what) != NULL)
        {
            return pProp;
        }
        pProp = pProp->pNextSibling;
    }
    return NULL;
}

このコードは、プロパティの対象となるテキストを特に探します。ただし、多くの場合、コードを文法に明示的にバインドせずに、val 属性を使用して項目を識別したほうがよいでしょう。これにより、コードを変更せずに文法を微調整 (または同等の値を追加) できます。値を使用するには、プロパティをフェッチした後に SPPHRASEPROPERTY.pszValue または vValue フィールドを使用します (ISpPhrase::GetText を使用する代わりに)。

于 2010-02-05T21:21:43.237 に答える