Как поймать слова в середине предложений с помощью Microsoft SAPI? - PullRequest
0 голосов
/ 04 февраля 2010

эта грамматика 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>

Итак, если я скажу «Меня зовут Андре», слово «имя» будет идентифицировано. Есть ли лучший способ сделать это?

1 Ответ

2 голосов
/ 06 февраля 2010

Когда вы получаете распознавание, данные 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).

...