这个SAPI语法捕捉到单词name是句子的中间部分。
<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>所以,如果我说“我的名字是André",单词" name”就会被识别出来。有没有更好的方法来做这件事?
发布于 2010-02-06 05:21:43
获得识别后,与识别关联的SPPHRASE数据将包含子规则和特性数据以及它们在识别中出现的位置。
因此,如果您为'Name‘设置了规则或属性标签,则可以找到与'Name’相关联的单词。
例如,给定您的语法
<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> 你可以像这样找到与“name”相对应的单词:
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)。
https://stackoverflow.com/questions/2199616
复制相似问题