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

📄 promptmanager.cpp

📁 Open VXI. This is a open source.
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/****************License************************************************ * * Copyright 2000-2001.  SpeechWorks International, Inc.     * * Use of this software is subject to notices and obligations set forth * in the SpeechWorks Public License - Software Version 1.1 which is * included with this software. * * SpeechWorks is a registered trademark, and SpeechWorks Here, * DialogModules and the SpeechWorks logo are 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>VXIchar SPACE = ' ';//#############################################################################bool static ConvertValueToString(const VXIValue * value, vxistring & source){  if (value == NULL) return false;  switch (VXIValueGetType(value)) {  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;  case VALUE_VECTOR:  case VALUE_MAP:  case VALUE_PTR:  case VALUE_CONTENT:  default:    return false;  }}inline void AddSSMLAttribute(const VXMLElement & elem, VXMLAttributeType attr,                             const VXIchar * const name, vxistring & sofar){  vxistring attrString;  if (!elem.GetAttribute(attr, attrString)) return;  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,                              bool isSSML){  if (addition.empty()) return;  vxistring::size_type pos = sofar.length();  if (!sofar.empty()) sofar += SPACE;  sofar += addition;  if (isSSML) {    // We need to escape two characters: (<,&) -> (&lt;, &amp;)    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;      }    }  }}inline void ConvertToXML(vxistring & sofar, bool & isSSML){  if (isSSML) return;  vxistring temp;  AppendTextSegment(temp, sofar, true);  sofar = temp;  isSSML = true;}//#############################################################################////////// 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.bool PromptManager::ConnectResources(SimpleLogger * l, VXIpromptInterface * p){  if (l == NULL || p == NULL) return false;  log = l;  prompt = p;  enabledSegmentInQueue = false;  timeout = -1;  return true;}void PromptManager::PlayFiller(const vxistring & src){  log->LogDiagnostic(2, L"PromptManager::PlayFiller()");  if (src.empty()) return;  prompt->PlayFiller(prompt, NULL, src.c_str(), NULL, NULL, 0);}void PromptManager::Play(){  log->LogDiagnostic(2, L"PromptManager::Play()");  VXIpromptResult temp;  prompt->Wait(prompt, &temp);  prompt->Play(prompt);  enabledSegmentInQueue = false;  timeout = -1;}void PromptManager::PlayAll(){  log->LogDiagnostic(2, L"PromptManager::PlayAll()");  VXIpromptResult temp;  prompt->Play(prompt);  prompt->Wait(prompt, &temp);  enabledSegmentInQueue = false;  timeout = -1;}int PromptManager::GetMillisecondTimeout() const{  return timeout;}void PromptManager::Queue(const VXMLNode & node, 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  vxistring language;  vxistring sofar;  bool isSSML = false;  PromptManager::BargeIn bargein = PromptManager::ENABLED;  const VXIchar * j = propertyList.GetProperty(PROP_BARGEIN);  if (j != NULL && vxistring(L"false") == j)    bargein = PromptManager::DISABLED;  if (node.GetType() == VXMLNode::Type_VXMLElement &&      reinterpret_cast<const VXMLElement &>(node).GetName() == NODE_PROMPT)  {    const VXMLElement & elem = reinterpret_cast<const VXMLElement &>(node);    // (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.    vxistring bargeinAttr;    if (elem.GetAttribute(ATTRIBUTE_BARGEIN, bargeinAttr) == true) {      bargein = PromptManager::ENABLED;      if (bargeinAttr == L"false") bargein = PromptManager::DISABLED;    }    // (3.3) Update language.    if (elem.GetAttribute(ATTRIBUTE_XMLLANG, language) == true)      AddParamValue(properties, PROMPT_LANGUAGE, language);    // (3.4) Recursively handle contents of the prompt.    for (VXMLNodeIterator it(elem); it; ++it)      ProcessSegments(*it, item, propertyList, translator,                      bargein, properties, sofar, isSSML);  }  // (4) Otherwise, this is simple content or an audio / tts element.  else    ProcessSegments(node, item, propertyList, translator,                    bargein, properties, sofar, isSSML);  // (5) Add a new segment.  if (!sofar.empty()) {    if (!isSSML) AddSegment(SEGMENT_TEXT, sofar, properties, bargein);    else {      // Retrieve language from properties, if not specified on <prompt>      if (language.empty()) {        const VXIchar * j = propertyList.GetProperty(PropertyList::Language);        if (j != NULL) {          language = j;          AddParamValue(properties, PROMPT_LANGUAGE, j);        }      }          vxistring prompt(L"<?xml version='1.0'?>");      if (!language.empty()) {        prompt += L"<speak xml:lang='";        prompt += language;        prompt += L"'>";      } else         prompt += L"<speak>";      prompt += sofar;      prompt += L"</speak>";      AddSegment(SEGMENT_SSML, prompt, 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;  case PromptManager::SEGMENT_TEXT:    result = prompt->Queue(prompt, VXI_MIME_UNICODE_TEXT, NULL, data.c_str(),                           propMap);    break;  }  if (throwExceptions) {    switch (result) {    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_BAD_SAYAS_CLASS:    case VXIprompt_RESULT_TTS_ACCESS_ERROR:    case VXIprompt_RESULT_TTS_BAD_DOCUMENT:    case VXIprompt_RESULT_TTS_SYNTAX_ERROR:    case VXIprompt_RESULT_TTS_ERROR:    default:      throw VXIException::InterpreterEvent(EV_ERROR_SEMANTIC);    }  }  switch (bargein) {  case PromptManager::DISABLED:    if (!enabledSegmentInQueue) prompt->Play(prompt);    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,                                    bool & isSSML){  // (1) Handle bare content.  switch (node.GetType()) {  case VXMLNode::Type_VXMLContent:  {    const VXMLContent & content = reinterpret_cast<const VXMLContent &>(node);    AppendTextSegment(sofar, content.GetValue(), isSSML);    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  case NODE_AUDIO:  {    // (3.1) Determine the source of the audio.    vxistring source;    // (3.1.1) src has priority over expr.    elem.GetAttribute(ATTRIBUTE_SRC, source);    if (source.empty()) {      elem.GetAttribute(ATTRIBUTE_EXPR, source);      VXIValue * value = translator.EvaluateExpression(source);      if (value != NULL) {        // (3.1.2) Handle audio content from <record> elements.        if (VXIValueGetType(value) == VALUE_CONTENT) {          AddContent(elem, item, propertyList, translator, bargein, props,                     sofar, value, isSSML);          return;        }        // (3.1.3) Otherwise, try to convert the type into a string.        bool conversionFailed = !ConvertValueToString(value, source);        VXIValueDestroy(&value);        if (conversionFailed) {          log->LogDiagnostic(0, L"PromptManager::ProcessSegments - "                             L"audio src evaluation failed");          throw VXIException::InterpreterEvent(EV_ERROR_SEMANTIC,                                               L"audio src evaluation failed");        }      }    }    // (3.1.4) Empty audio elements should be ignored.    if (source.empty()) return;    // (3.2) Get fetch properties.    // (3.2.1) Create new audio reference data map.    VXIMapHolder audioData;

⌨️ 快捷键说明

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