📄 grammarmanager.cpp
字号:
bool GrammarManager::FindMatchedElement(const vxistring & id, VXMLElement & match, 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); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -