⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 promptmanager.cpp

📁 OSB-PIK-OpenVXI-3.0.0源代码 “中国XML论坛 - 专业的XML技术讨论区--XML在语音技术中的应用”
💻 CPP
📖 第 1 页 / 共 2 页
字号:
 /****************License************************************************  *  * Copyright 2000-2003.  ScanSoft, Inc.      *  * Use of this software is subject to notices and obligations set forth   * in the SpeechWorks Public License - Software Version 1.2 which is   * included with this software.   *  * ScanSoft is a registered trademark of ScanSoft, Inc., and OpenSpeech,   * SpeechWorks and the SpeechWorks logo are registered trademarks or   * trademarks of SpeechWorks International, Inc. in the United States   * and other countries.  *  ***********************************************************************/  #include "PromptManager.hpp" #include "SimpleLogger.hpp"            // for SimpleLogger #include "VXIprompt.h"                 // for VXIpromptInterface #include "VXML.h"                      // for node names #include "DocumentModel.hpp"           // for VXMLNode, VXMLElement #include "CommonExceptions.hpp"        // for InterpreterEvent, OutOfMemory #include "PropertyList.hpp"            // for PropertyList #include <sstream> #include <iostream>  static VXIchar SPACE = ' ';  //#############################################################################  bool static ConvertValueToString(const VXIValue * value, vxistring & source) {   if (value == NULL) return false;    switch (VXIValueGetType(value)) {   case VALUE_BOOLEAN:   {     std::basic_stringstream<VXIchar> attrStream;     if(VXIBooleanValue(reinterpret_cast<const VXIBoolean *>(value)) == TRUE)       attrStream << L"true";     else       attrStream << L"false";     source = attrStream.str();     return true;   }   case VALUE_INTEGER:   {     std::basic_stringstream<VXIchar> attrStream;     attrStream << VXIIntegerValue(reinterpret_cast<const VXIInteger *>(value));     source = attrStream.str();     return true;   }   case VALUE_FLOAT:   {     std::basic_stringstream<VXIchar> attrStream;     attrStream << VXIFloatValue(reinterpret_cast<const VXIFloat *>(value));     source = attrStream.str();     return true;   }   case VALUE_STRING:     source = VXIStringCStr(reinterpret_cast<const VXIString *>(value));     return true;   default:     return false;   } }   inline void AddSSMLAttribute(const VXMLElement & elem, VXMLAttributeType attr,                              const VXIchar * const defaultVal,                              const VXIchar * const name, vxistring & sofar) {   // Get attribute or use the default value.   vxistring attrString;   if (!elem.GetAttribute(attr, attrString) || attrString.empty()) {     if (defaultVal == NULL) return;     attrString = defaultVal;   }    sofar += SPACE;   sofar += name;   sofar += L"=\"";    // We need to escape three characters: (",<,&) -> (&quot;, &lt;, &amp;)   vxistring::size_type pos = 0;   while ((pos = attrString.find_first_of(L"\"<&", pos)) != vxistring::npos) {     switch (attrString[pos]) {     case '\"':   attrString.replace(pos, 1, L"&quot;");    ++pos;  break;     case '<':    attrString.replace(pos, 1, L"&lt;");      ++pos;  break;     case '&':    attrString.replace(pos, 1, L"&amp;");     ++pos;  break;     }   };    sofar += attrString;   sofar += L"\""; }   inline void AppendTextSegment(vxistring & sofar, const vxistring & addition) {   if (addition.empty()) return;    vxistring::size_type pos = sofar.length();    sofar += addition;    // We need to escape two characters: (<,&) -> (&lt;, &amp;)   // NOTE: It starts from the old length and operates only on the addition.   while ((pos = sofar.find_first_of(L"<&", pos)) != vxistring::npos) {     switch (sofar[pos]) {     case '<':    sofar.replace(pos, 1, L"&lt;");      ++pos;  break;     case '&':    sofar.replace(pos, 1, L"&amp;");     ++pos;  break;     }   } }  //#############################################################################  //////// // About prompts: // // Prompts may be defined in two places within VXML documents. // 1) form items - menu, field, initial, record, transfer, subdialog, object // 2) executable content - block, catch, filled // // The <enumerate> element only is valid with parent menu or fields having one // or more option elements.  Otherwise an error.semantic results. // // From the VXML working drafts, barge-in may be controlled on a prompt by // prompt basis.  There are several unresolved issues with this request. // Instead this implements a different tactic.  void PromptManager::ThrowEventIfError(VXIpromptResult rc) {   switch( rc )   {     case VXIprompt_RESULT_SUCCESS:       break;     case VXIprompt_RESULT_TTS_BAD_LANGUAGE:       throw VXIException::InterpreterEvent(EV_UNSUPPORT_LANGUAGE);     case VXIprompt_RESULT_FETCH_TIMEOUT:     case VXIprompt_RESULT_FETCH_ERROR:     case VXIprompt_RESULT_NON_FATAL_ERROR:       throw VXIException::InterpreterEvent(EV_ERROR_BADFETCH);     case VXIprompt_RESULT_HW_BAD_TYPE:       throw VXIException::InterpreterEvent(EV_UNSUPPORT_FORMAT);     case VXIprompt_RESULT_TTS_ACCESS_ERROR:     case VXIprompt_RESULT_NO_RESOURCE:       throw VXIException::InterpreterEvent(EV_ERROR_NORESOURCE);     case VXIprompt_RESULT_NO_AUTHORIZATION:       throw VXIException::InterpreterEvent(EV_ERROR_NOAUTHORIZ);     case VXIprompt_RESULT_BAD_SAYAS_CLASS:     case VXIprompt_RESULT_TTS_BAD_DOCUMENT:     case VXIprompt_RESULT_TTS_SYNTAX_ERROR:     case VXIprompt_RESULT_TTS_ERROR:     default:       throw VXIException::InterpreterEvent(EV_ERROR_SEMANTIC);   }    }  void PromptManager::WaitAndCheckError() {   VXIpromptResult rc;   prompt->Wait(prompt, &rc);   ThrowEventIfError(rc); }  bool PromptManager::ConnectResources(SimpleLogger * l, VXIpromptInterface * p) {   if (l == NULL || p == NULL) return false;   log = l;   prompt = p;   enabledSegmentInQueue = false;   playedBargeinDisabledPrompt = false;   timeout = -1;   return true; }   void PromptManager::PlayFiller(const vxistring & src,                                 const VXIMapHolder & properties) {   log->LogDiagnostic(2, L"PromptManager::PlayFiller()");    if (src.empty()) return;    const VXIMap * propMap = properties.GetValue();   // Get fetchaudiominimum value   VXIint minPlayMsec = 0;   const VXIValue * val = (VXIMapGetProperty(propMap, L"fetchaudiominimum"));   if( val &&  VXIValueGetType(val) == VALUE_STRING ) {     const VXIchar* fmin =            VXIStringCStr(reinterpret_cast<const VXIString*>(val));     if( fmin )       PropertyList::ConvertTimeToMilliseconds(*log, fmin, minPlayMsec);   }      prompt->PlayFiller(prompt, NULL, src.c_str(), NULL, propMap, minPlayMsec); }   void PromptManager::Play(bool *playedBDPrompt) {   log->LogDiagnostic(2, L"PromptManager::Play()");    *playedBDPrompt = playedBargeinDisabledPrompt;    //VXIpromptResult temp;   //prompt->Wait(prompt, &temp);   WaitAndCheckError();   prompt->Play(prompt);   enabledSegmentInQueue = false;   playedBargeinDisabledPrompt = false;   timeout = -1; }   void PromptManager::PlayAll() {   log->LogDiagnostic(2, L"PromptManager::PlayAll()");    prompt->Play(prompt);   //VXIpromptResult temp;   //prompt->Wait(prompt, &temp);   WaitAndCheckError();   enabledSegmentInQueue = false;   playedBargeinDisabledPrompt = false;   timeout = -1; }   int PromptManager::GetMillisecondTimeout() const {   return timeout; }  void PromptManager::Queue(const VXMLElement & elem, const VXMLElement & ref,                           const PropertyList & propertyList,                           PromptTranslator & translator) {   log->LogDiagnostic(2, L"PromptManager::Queue()");    // (1) Find <field> or <menu> associated with this prompt, if any.  This is   // used by the <enumerate> element.   VXMLElement item = ref;   while (item != 0) {     VXMLElementType type = item.GetName();     if (type == NODE_FIELD || type == NODE_MENU) break;     item = item.GetParent();   }    // (2) Get properties.   VXIMapHolder properties;   if (properties.GetValue() == NULL) throw VXIException::OutOfMemory();    // (2.1) Flatten the property list.   propertyList.GetProperties(properties);    // (2.2) Add the URI information.   propertyList.GetFetchobjBase(properties);    // (3) Handle <prompt> elements    // (3.1) Update timeout if specified.   vxistring timeoutString;   if (elem.GetAttribute(ATTRIBUTE_TIMEOUT, timeoutString) == true)     PropertyList::ConvertTimeToMilliseconds(*log, timeoutString, timeout);    // (3.2) Get bargein setting.    PromptManager::BargeIn bargein = PromptManager::ENABLED;   const VXIchar * j = propertyList.GetProperty(PROP_BARGEIN);   if (j != NULL && vxistring(L"false") == j)     bargein = PromptManager::DISABLED;    vxistring bargeinAttr;   if (elem.GetAttribute(ATTRIBUTE_BARGEIN, bargeinAttr) == true) {     bargein = PromptManager::ENABLED;     if (bargeinAttr == L"false") bargein = PromptManager::DISABLED;     // override default bargein attribute     VXIMapSetProperty(properties.GetValue(), PROP_BARGEIN,                       (VXIValue*)VXIStringCreate(bargeinAttr.c_str()));    }      vxistring bargeinType;   if (elem.GetAttribute(ATTRIBUTE_BARGEINTYPE, bargeinType) == true) {     // override default bargeintype attribute     VXIMapSetProperty(properties.GetValue(), PROP_BARGEINTYPE,                       (VXIValue*)VXIStringCreate(bargeinType.c_str()));    }       // (4) Build prompt, recursively handling the contents.   vxistring content;   for (VXMLNodeIterator it(elem); it; ++it)     ProcessSegments(*it, item, propertyList, translator,                     bargein, properties, content);   if (content.empty()) return;    // (5) Add a new segment.   AddSegment(SEGMENT_SSML, content, properties, bargein); }   void PromptManager::Queue(const vxistring & uri) {   if (uri.empty()) return;    AddSegment(PromptManager::SEGMENT_AUDIO, uri, VXIMapHolder(),              PromptManager::UNSPECIFIED); }   bool PromptManager::AddSegment(PromptManager::SegmentType type,                                const vxistring & data,                                const VXIMapHolder & properties,                                PromptManager::BargeIn bargein,                                bool throwExceptions) {   const VXIMap * propMap = properties.GetValue();    VXIpromptResult result;    // Handle the easy case.   switch (type) {   case PromptManager::SEGMENT_AUDIO:     result = prompt->Queue(prompt, NULL, data.c_str(), NULL, propMap);     break;   case PromptManager::SEGMENT_SSML:     result = prompt->Queue(prompt, VXI_MIME_SSML, NULL, data.c_str(), propMap);     break;   }    if (throwExceptions) {     ThrowEventIfError(result);   }    switch (bargein) {   case PromptManager::DISABLED:     if (!enabledSegmentInQueue) {       prompt->Play(prompt);       playedBargeinDisabledPrompt = true;     }     break;   case PromptManager::ENABLED:     enabledSegmentInQueue = true;     break;   case PromptManager::UNSPECIFIED:     break;   }    return result == VXIprompt_RESULT_SUCCESS; }  void PromptManager::ProcessSegments(const VXMLNode & node,                                     const VXMLElement & item,                                     const PropertyList & propertyList,                                     PromptTranslator & translator,                                     PromptManager::BargeIn bargein,                                     VXIMapHolder & props,                                     vxistring & sofar) {   // (1) Handle bare content.   switch (node.GetType()) {   case VXMLNode::Type_VXMLContent:   {     const VXMLContent & content = reinterpret_cast<const VXMLContent &>(node);     sofar += content.GetValue();     return;   }   case VXMLNode::Type_VXMLElement:     break;   default: // This should never happen.     log->LogError(999, SimpleLogger::MESSAGE,                   L"unexpected type in PromptManager::ProcessSegments");     throw VXIException::Fatal();   }    // (2) Retrieve fetch properties (if we haven't already)   const VXMLElement & elem = reinterpret_cast<const VXMLElement &>(node);   vxistring attr;    switch (elem.GetName()) {    // (3) audio

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -