📄 grammarmanager.cpp
字号:
unsigned long & grammarInfo) const
{
const VXIrecGrammar * bestGrammar = NULL;
if (id.empty()) return false;
VXIrecResult err = vxirec->GetMatchedGrammar(vxirec, id.c_str(),
&bestGrammar);
if (err != VXIrec_RESULT_SUCCESS) {
log.LogError(420, SimpleLogger::MESSAGE,
L"function failed to return a grammar match");
return false;
}
for (GRAMMARS::const_iterator i = grammars.begin(); i!=grammars.end(); ++i) {
if ((*i)->GetRecGrammar() != bestGrammar) continue;
if (!(*i)->IsEnabled()) {
log.LogError(420, SimpleLogger::MESSAGE,
L"function returned an inactive grammar");
return false;
}
(*i)->GetElement(match);
grammarInfo = (*i)->GetSequence();
return true;
}
for (UNIVERSALS::const_iterator j = universals.begin();
j != universals.end(); ++j)
{
if ((*j)->GetRecGrammar() != bestGrammar) continue;
if (!(*j)->IsEnabled()) {
log.LogError(420, SimpleLogger::MESSAGE,
L"function returned an inactive grammar");
return false;
}
(*j)->GetElement(match);
grammarInfo = (*j)->GetSequence();
return true;
}
log.LogError(420, SimpleLogger::MESSAGE,
L"function returned a non-existent grammar");
return false;
}
// compare the precedence of info1 against info2, return 1 if info1 has
// higher precedence than info2, -1 otherwise, 0 if both has the same precedence
int GrammarManager::CompareGrammar(const unsigned long grammar1,
const unsigned long grammar2)
{
// Is either grammar an universal?
bool firstIsUniversal = false;
bool secondIsUniversal = false;
for (UNIVERSALS::const_iterator j = universals.begin();
j != universals.end(); ++j)
{
unsigned long temp = (*j)->GetSequence();
if (temp == grammar1) firstIsUniversal = true;
if (temp == grammar2) secondIsUniversal = true;
}
if (firstIsUniversal && secondIsUniversal) {
if (grammar1 < grammar2) return 1;
if (grammar1 > grammar2) return -1;
return 0;
}
if (firstIsUniversal) return 1;
if (secondIsUniversal) return -1;
// The remaining grammars are not universals.
const GrammarInfo * info1 = NULL;
const GrammarInfo * info2 = NULL;
for (GRAMMARS::const_iterator i = grammars.begin(); i!=grammars.end(); ++i) {
unsigned long temp = (*i)->GetSequence();
if (temp == grammar1) info1 = *i;
if (temp == grammar2) info2 = *i;
}
if (info1 && info2) {
GrammarScope s1 = info1->GetScope();
GrammarScope s2 = info2->GetScope();
if( info1 == info2 ) return 0;
if( s1 == GRS_NONE || s2 == GRS_NONE ) return 0; // unable to determine
if( s1 < s2 ) return 1;
if( s1 > s2 ) return -1;
if( s1 == s2 ) {
// if both have the same precedence, use document order
// to determine
if( info1->GetSequence() < info2->GetSequence() )
return 1;
else if(info1->GetSequence() > info2->GetSequence())
return -1;
else return 0;
}
}
return 0; // unable to determine
}
int GrammarManager::Record(const VXIMapHolder & properties,
bool flushBeforeRecord,
VXIrecRecordResult * & resultStruct)
{
const VXIMap *finalProp = NULL;
VXIMapHolder addlProp(NULL);
if (flushBeforeRecord) {
addlProp = properties;
AddParamValue(addlProp, REC_DTMF_FLUSH_QUEUE, true);
finalProp = addlProp.GetValue();
} else {
finalProp = properties.GetValue();
}
VXIrecResult err = vxirec->Record(vxirec, finalProp, &resultStruct);
if (err != VXIrec_RESULT_SUCCESS) {
// try to throw a specific event for the error before bailing out
ThrowSpecificEventError(err, RECORD);
// throw an internal error if specific event cannot be thrown
log.StartDiagnostic(0) << L"GrammarManager::Record - "
L"VXIrecInterface::Record returned " << int (err);
log.EndDiagnostic();
log.LogError(421, SimpleLogger::MESSAGE,
L"function did not return the expected VXIrecSUCCESS result");
if (resultStruct) resultStruct->Destroy(&resultStruct);
return GrammarManager::InternalError;
}
if (resultStruct == NULL) {
log.LogError(421, SimpleLogger::MESSAGE,
L"function returned VXIrecSUCCESS but did not allocate "
L"an answer structure");
return GrammarManager::InternalError;
}
if (resultStruct->waveform == NULL && resultStruct->xmlresult == NULL) {
log.LogError(421, SimpleLogger::MESSAGE,
L"function did not produce a recording or XML result");
return GrammarManager::InternalError;
}
if (resultStruct->waveform != NULL && resultStruct->duration == 0) {
log.LogError(421, SimpleLogger::MESSAGE,
L"function returned invalid recording duration");
return GrammarManager::InternalError;
}
return GrammarManager::Success;
}
VXIMap * GrammarManager::GetRecProperties(const PropertyList & props,
int timeout) const
{
VXIMapHolder m;
if (m.GetValue() == NULL) throw VXIException::OutOfMemory();
// (1) Retrieve flattened property list.
props.GetProperties(m);
// (2) Convert & manipulate the properties.
//#pragma message ("GrammarManager::GetRecProperties - handle REC_RESULT_SAVE_WAVEFORM ???")
const VXIchar * j;
VXIint time;
VXIflt32 fraction;
// (2.1) Language
j = props.GetProperty(PropertyList::Language);
if (j != NULL)
AddParamValue(m, REC_LANGUAGE, j);
// (2.2) Completion timeout
j = props.GetProperty(PROP_COMPLETETIME);
if (j != NULL && props.ConvertTimeToMilliseconds(log, j, time))
AddParamValue(m, REC_TIMEOUT_COMPLETE, time);
// (2.3) Incompletion timeout
j = props.GetProperty(PROP_INCOMPLETETIME);
if (j != NULL && props.ConvertTimeToMilliseconds(log, j, time))
AddParamValue(m, REC_TIMEOUT_INCOMPLETE, time);
// (2.4) Inter-Digit timeout
j = props.GetProperty(PROP_INTERDIGITTIME);
if (j != NULL && props.ConvertTimeToMilliseconds(log, j, time))
AddParamValue(m, REC_DTMF_TIMEOUT_INTERDIGIT, time);
// (2.5) Inter-Digit timeout
j = props.GetProperty(PROP_TERMTIME);
if (j != NULL && props.ConvertTimeToMilliseconds(log, j, time))
AddParamValue(m, REC_DTMF_TIMEOUT_TERMINATOR, time);
// (2.6) Confidence level
j = props.GetProperty(PROP_CONFIDENCE);
if (j != NULL && props.ConvertValueToFraction(log, j, fraction))
AddParamValue(m, REC_CONFIDENCE_LEVEL, fraction);
// (2.7) Barge-in sensitivity level
j = props.GetProperty(PROP_SENSITIVITY);
if (j != NULL && props.ConvertValueToFraction(log, j, fraction))
AddParamValue(m, REC_SENSITIVITY, fraction);
// (2.8) Performance tradeoff - speed vs. accuracy
j = props.GetProperty(PROP_SPEEDVSACC);
if (j != NULL && props.ConvertValueToFraction(log, j, fraction))
AddParamValue(m, REC_SPEED_VS_ACCURACY, fraction);
// (2.9) DTMF terminator character
j = props.GetProperty(PROP_TERMCHAR);
if (j != NULL) {
if (wcslen(j) < 2)
AddParamValue(m, REC_DTMF_TERMINATOR_CHAR, j);
else {
log.StartDiagnostic(0) << L"GrammarManager::GetRecProperties - "
L"Unable to set " << REC_DTMF_TERMINATOR_CHAR << L" from value \"" <<
j << L"\". Defaulting to '#'.";
log.EndDiagnostic();
// Should we use the default, or rather not set anything ?
AddParamValue(m, REC_DTMF_TERMINATOR_CHAR, L"#");
}
}
// (2.10) Input modes
int mode = REC_INPUT_MODE_DTMF_SPEECH;
j = props.GetProperty(PROP_INPUTMODES);
if (j != NULL) {
vxistring value(j);
if (value == L"voice dtmf" || value == L"dtmf voice")
mode = REC_INPUT_MODE_DTMF_SPEECH;
else if (value == L"voice")
mode = REC_INPUT_MODE_SPEECH;
else if (value == L"dtmf")
mode = REC_INPUT_MODE_DTMF;
else {
log.StartDiagnostic(0) << L"GrammarManager::GetRecProperties - "
L"Unable to set " << REC_INPUT_MODES << L" from value \"" << value <<
L"\".";
log.EndDiagnostic();
}
}
AddParamValue(m, REC_INPUT_MODES, mode);
// (2.11) Timeout settings
if (timeout == -1) {
j = props.GetProperty(PROP_TIMEOUT);
if (j != NULL)
PropertyList::ConvertTimeToMilliseconds(log, j, timeout);
}
if (timeout != -1) {
AddParamValue(m, REC_DTMF_TIMEOUT, timeout);
AddParamValue(m, REC_TIMEOUT, timeout);
}
// (2.12) Bargein type
int bargintype = REC_BARGEIN_SPEECH;
j = props.GetProperty(PROP_BARGEINTYPE);
if (j != NULL) {
vxistring value(j);
if (value == L"hotword")
bargintype = REC_BARGEIN_HOTWORD;
else if (value == L"speech")
bargintype = REC_BARGEIN_SPEECH;
else {
log.StartDiagnostic(0) << L"GrammarManager::GetRecProperties - "
L"Unable to set " << REC_BARGEIN_TYPE << L" from value \"" << value <<
L"\".";
log.EndDiagnostic();
}
}
AddParamValue(m, REC_BARGEIN_TYPE, bargintype);
// (2.13) maxnbest property
j = props.GetProperty(PROP_MAXNBEST);
if (j != NULL) {
VXIint nbest = 1;
std::basic_stringstream<VXIchar> nbestStream(j);
nbestStream >> nbest;
AddParamValue(m, REC_RESULT_NBEST_SIZE, nbest);
}
// (3) Done
return m.Release();
}
VXIMap * GrammarManager::GetRecordProperties(const PropertyList & props,
int timeout) const
{
VXIMapHolder m;
if (m.GetValue() == NULL) throw VXIException::OutOfMemory();
// (1) Retrieve flattened property list.
props.GetProperties(m);
// (2) Convert & manipulate the properties.
const VXIchar * j;
VXIint time;
// (2.1) Completion timeout
j = props.GetProperty(GrammarManager::MaxTime);
if (j != NULL && props.ConvertTimeToMilliseconds(log, j, time))
AddParamValue(m, REC_MAX_RECORDING_TIME, time);
// (2.2) Final silence
j = props.GetProperty(GrammarManager::FinalSilence);
if (j != NULL && props.ConvertTimeToMilliseconds(log, j, time))
AddParamValue(m, REC_TIMEOUT_COMPLETE, time);
// (2.3) Type
j = props.GetProperty(GrammarManager::RecordingType);
if (j != NULL)
AddParamValue(m, REC_RECORD_MIME_TYPE, j);
// (2.4) DTMF terminates record?
j = props.GetProperty(GrammarManager::DTMFTerm);
if (j != NULL) {
int dtmfterm;
if (vxistring(j) == L"false")
dtmfterm = 0;
else
dtmfterm = 1;
AddParamValue(m, REC_TERMINATED_ON_DTMF, dtmfterm);
}
// (2.5) Timeout settings
if (timeout == -1) {
j = props.GetProperty(PROP_TIMEOUT);
if (j != NULL)
PropertyList::ConvertTimeToMilliseconds(log, j, timeout);
}
if (timeout != -1) {
AddParamValue(m, REC_DTMF_TIMEOUT, timeout);
AddParamValue(m, REC_TIMEOUT, timeout);
}
// (3) Done
return m.Release();
}
void GrammarManager::SetGrammarLoadProperties(const VXMLElement & element,
VXIMapHolder & properties) const
{
vxistring attr;
// (1) Set weight
VXIflt32 val;
if (element.GetAttribute(ATTRIBUTE_WEIGHT, attr) == true &&
PropertyList::ConvertValueToFraction(log, attr, val))
{
AddParamValue(properties, REC_GRAMMAR_WEIGHT, val);
}
else
AddParamValue(properties, REC_GRAMMAR_WEIGHT, 1.0f);
// (2) Set language; parsing should ensure that this value is always defined
attr = L"";
if (!element.GetAttribute(ATTRIBUTE_XMLLANG, attr)) {
log.LogError(999, SimpleLogger::MESSAGE,
L"GrammarManager::SetGrammarLoadProperties did not "
L"find a language");
}
AddParamValue(properties, REC_LANGUAGE, attr);
// (3) Set prefetch status
attr = L"";
if (element.GetAttribute(ATTRIBUTE_FETCHHINT, attr) != true) {
const VXIValue * v = VXIMapGetProperty(properties.GetValue(),
L"grammarfetchhint");
if (VXIValueGetType(v) == VALUE_STRING)
attr = VXIStringCStr(reinterpret_cast<const VXIString *>(v));
}
if (attr == L"prefetch")
AddParamValue(properties, REC_PREFETCH_REQUEST, 1);
else
AddParamValue(properties, REC_PREFETCH_REQUEST, 0);
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -