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

📄 promptmanager.cpp

📁 Open VXI. This is a open source.
💻 CPP
📖 第 1 页 / 共 2 页
字号:
    if (audioData.GetValue() == NULL) throw VXIException::OutOfMemory();    // (3.2.2) Populate the inner map.    AddParamValue(audioData, PROMPT_AUDIO_REF_SRC, source);    propertyList.GetFetchobjCacheAttrs(elem, PropertyList::Grammar, audioData);    // (3.2.3) Generate a hidden name and place the inner map inside the    // properties.    vxistring hiddenName;    VXMLDocumentModel::CreateHiddenVariable(hiddenName);    VXIMapHolder allRefs(NULL);    // Get existing map (if it exists) or create a new one.    const VXIValue * temp = VXIMapGetProperty(props.GetValue(),                                              PROMPT_AUDIO_REFS);    if (temp != NULL && VXIValueGetType(temp) == VALUE_MAP)      allRefs.Acquire(VXIMapClone(reinterpret_cast<const VXIMap *>(temp)));    else      allRefs.Acquire(VXIMapCreate());    if (allRefs.GetValue() == NULL) throw VXIException::OutOfMemory();    // Place references for this value into the 'all refs' map.    VXIMapSetProperty(allRefs.GetValue(), hiddenName.c_str(),                      reinterpret_cast<VXIValue *>(audioData.Release()));    // And replace the 'all refs' map in the properties.    VXIMapSetProperty(props.GetValue(), PROMPT_AUDIO_REFS,                      reinterpret_cast<VXIValue *>(allRefs.Release()));    // (3.2.4) Create fake 'src' for this audio element.    hiddenName = vxistring(PROMPT_AUDIO_REFS_SCHEME) + hiddenName;    // (3.3) For SSML, simply add a new audio element.    if (isSSML) {      sofar += L"<audio src=\"";      // We need to escape three characters: (",<,&) -> (&quot;, &lt;, &amp;)      vxistring::size_type pos = 0;      while ((pos = hiddenName.find_first_of(L"\"<&", pos)) != vxistring::npos)      {        switch (hiddenName[pos]) {        case '\"':   hiddenName.replace(pos, 1, L"&quot;");    ++pos;  break;        case '<':    hiddenName.replace(pos, 1, L"&lt;");      ++pos;  break;        case '&':    hiddenName.replace(pos, 1, L"&amp;");     ++pos;  break;        }      };      sofar += hiddenName;      sofar += L"\"";      // Deal with alternate text.      if (elem.hasChildren()) {        sofar += L">";        for (VXMLNodeIterator it(elem); it; ++it)          ProcessSegments(*it, item, propertyList, translator,                          bargein, props, sofar, isSSML);        sofar += L"</audio>";      }      else        sofar += L"/>";      return;    }    // (3.4) Handle simple data case.    // (3.4.1) First add any existing text.    if (!sofar.empty()) {      AddSegment(SEGMENT_TEXT, sofar, props, bargein);      sofar.erase();    }    // (3.4.2) Then add the audio segment.    if (!AddSegment(SEGMENT_AUDIO, hiddenName, props, bargein,                    !elem.hasChildren()))    {      // Unable to queue audio segment.  Resort to backup.      for (VXMLNodeIterator it(elem); it; ++it)        ProcessSegments(*it, item, propertyList, translator,                        bargein, props, sofar, isSSML);    }    return;  }  // (4) Handle SSML tags.  case NODE_BREAK:    ConvertToXML(sofar, isSSML);    sofar += L"<break";    AddSSMLAttribute(elem, ATTRIBUTE_SIZE, L"size", sofar);    AddSSMLAttribute(elem, ATTRIBUTE_TIME, L"time", sofar);    sofar += L"/>";    return;  case NODE_EMPHASIS:    ConvertToXML(sofar, isSSML);    sofar += L"<emphasis";    AddSSMLAttribute(elem, ATTRIBUTE_LEVEL, L"level", sofar);    if (elem.hasChildren()) {      sofar += L">";      for (VXMLNodeIterator it(elem); it; ++it)        ProcessSegments(*it, item, propertyList, translator,                        bargein, props, sofar, isSSML);      sofar += L"</emphasis>";    }    else      sofar += L"/>";    return;  case NODE_MARK:    ConvertToXML(sofar, isSSML);    sofar += L"<mark";    AddSSMLAttribute(elem, ATTRIBUTE_NAME, L"name", sofar);    sofar += L"/>";    return;  case NODE_PARAGRAPH:    ConvertToXML(sofar, isSSML);    sofar += L"<p";    AddSSMLAttribute(elem, ATTRIBUTE_XMLLANG, L"xml:lang", sofar);    if (elem.hasChildren()) {      sofar += L">";      for (VXMLNodeIterator it(elem); it; ++it)        ProcessSegments(*it, item, propertyList, translator,                        bargein, props, sofar, isSSML);      sofar += L"</p>";    }    else      sofar += L"/>";    return;  case NODE_PHONEME:    ConvertToXML(sofar, isSSML);    sofar += L"<phoneme";    AddSSMLAttribute(elem, ATTRIBUTE_PH, L"ph", sofar);    AddSSMLAttribute(elem, ATTRIBUTE_ALPHABET, L"alphabet", sofar);    if (elem.hasChildren()) {      sofar += L">";      for (VXMLNodeIterator it(elem); it; ++it)        ProcessSegments(*it, item, propertyList, translator,                        bargein, props, sofar, isSSML);      sofar += L"</phoneme>";    }    else      sofar += L"/>";    return;  case NODE_PROSODY:    ConvertToXML(sofar, isSSML);    sofar += L"<prosody";    AddSSMLAttribute(elem, ATTRIBUTE_PITCH, L"pitch", sofar);    AddSSMLAttribute(elem, ATTRIBUTE_CONTOUR, L"contour", sofar);    AddSSMLAttribute(elem, ATTRIBUTE_RANGE, L"range", sofar);    AddSSMLAttribute(elem, ATTRIBUTE_RATE, L"rate", sofar);    AddSSMLAttribute(elem, ATTRIBUTE_DURATION, L"duration", sofar);    AddSSMLAttribute(elem, ATTRIBUTE_VOLUME, L"volume", sofar);    if (elem.hasChildren()) {      sofar += L">";      for (VXMLNodeIterator it(elem); it; ++it)        ProcessSegments(*it, item, propertyList, translator,                        bargein, props, sofar, isSSML);      sofar += L"</prosody>";    }    else      sofar += L"/>";    return;  case NODE_SAYAS:    ConvertToXML(sofar, isSSML);    sofar += L"<say-as";    AddSSMLAttribute(elem, ATTRIBUTE_TYPE, L"type", sofar);    AddSSMLAttribute(elem, ATTRIBUTE_SUB, L"sub", sofar);    if (elem.hasChildren()) {      sofar += L">";      for (VXMLNodeIterator it(elem); it; ++it)        ProcessSegments(*it, item, propertyList, translator,                        bargein, props, sofar, isSSML);      sofar += L"</say-as>";    }    else      sofar += L"/>";    return;  case NODE_SENTENCE:    ConvertToXML(sofar, isSSML);    sofar += L"<s";    AddSSMLAttribute(elem, ATTRIBUTE_XMLLANG, L"xml:lang", sofar);    if (elem.hasChildren()) {      sofar += L">";      for (VXMLNodeIterator it(elem); it; ++it)        ProcessSegments(*it, item, propertyList, translator,                        bargein, props, sofar, isSSML);      sofar += L"</s>";    }    else      sofar += L"/>";    return;  case NODE_VOICE:    ConvertToXML(sofar, isSSML);    sofar += L"<voice";    AddSSMLAttribute(elem, ATTRIBUTE_GENDER, L"gender", sofar);    AddSSMLAttribute(elem, ATTRIBUTE_AGE, L"age", sofar);    AddSSMLAttribute(elem, ATTRIBUTE_CATEGORY, L"category", sofar);    AddSSMLAttribute(elem, ATTRIBUTE_VARIANT, L"variant", sofar);    AddSSMLAttribute(elem, ATTRIBUTE_NAME, L"name", sofar);    if (elem.hasChildren()) {      sofar += L">";      for (VXMLNodeIterator it(elem); it; ++it)        ProcessSegments(*it, item, propertyList, translator,                        bargein, props, sofar, isSSML);      sofar += L"</voice>";    }    else      sofar += L"/>";    return;  // (5) <value>  case NODE_VALUE:  {    // (5.1) Evaluate the expression.  Can we handle this type?    vxistring expr;    if (elem.GetAttribute(ATTRIBUTE_EXPR, expr) == false || expr.empty())      return;    VXIValue * value = translator.EvaluateExpression(expr);    if (value == NULL) return;    VXIvalueType valueType = VXIValueGetType(value);    switch (valueType) {    case VALUE_INTEGER:    case VALUE_FLOAT:    case VALUE_STRING:    case VALUE_CONTENT:      break;    case VALUE_VECTOR:    case VALUE_MAP:    case VALUE_PTR:    default:      VXIValueDestroy(&value);      log->LogDiagnostic(0, L"PromptManager::ProcessSegments - "                         L"value expr was not a simple type");      throw VXIException::InterpreterEvent(EV_ERROR_SEMANTIC,                                           L"value expr gave invalid type");    }    // (5.2) Handle VXIContent.    if (valueType == VALUE_CONTENT) {      AddContent(elem, item, propertyList, translator, bargein, props,                 sofar, value, isSSML);      return;    }    // (5.3) OTHERWISE this should be played as TTS. Convert value to string.    ConvertValueToString(value, expr);    VXIValueDestroy(&value);    vxistring type;    elem.GetAttribute(ATTRIBUTE_TYPE, type);    // (5.3.1) Is this simple text?    vxistring::size_type pos = expr.find('<');    if (type.empty() &&         (pos == vxistring::npos || expr.find('>', pos) == vxistring::npos))    {      AppendTextSegment(sofar, expr, isSSML);      return;    }    // (5.3.2) Otherwise....    ConvertToXML(sofar, isSSML);    if (!type.empty()) {      sofar += L"<say-as type=\"";      sofar += type;      sofar += L"\">";    }    sofar += expr;    if (!type.empty()) {      sofar += L"</say-as>";    }    return;  }  // (3.4) <enumerate>  case NODE_ENUMERATE:  {    // (3.4.1) Is enumerate valid in this location?    if (item == 0)      throw VXIException::InterpreterEvent(EV_ERROR_SEMANTIC, L"invalid use "                                           L"of enumerate element");    for (VXMLNodeIterator it(item); it; ++it) {      // (3.4.2) Ignore anything which isn't an <option> or <choice> grammar.      if ((*it).GetType() != VXMLNode::Type_VXMLElement) continue;      const VXMLNode & tmp = *it;      const VXMLElement & itemElem = reinterpret_cast<const VXMLElement&>(tmp);      switch (itemElem.GetName()) {      case NODE_CHOICE:      case NODE_OPTION:        break;      default:        continue;      }      // (3.4.3) Convert item into text.      vxistring promptText;      for (VXMLNodeIterator choiceNode(itemElem); choiceNode; ++choiceNode) {        if ((*choiceNode).GetType() == VXMLNode::Type_VXMLContent) {          if (!promptText.empty()) promptText += SPACE;          const VXMLNode & tmp = *choiceNode;          promptText += reinterpret_cast<const VXMLContent &>(tmp).GetValue();        }      }      // (3.4.4) Handle the simple case where enumerate does not specify a      // format string.      if (!elem.hasChildren()) {        ConvertToXML(sofar, isSSML);        AppendTextSegment(sofar, promptText, isSSML);        sofar += L"<break size='small'/>";      }      else {        // (3.4.5) Get the associated dtmf value.        vxistring dtmfText;        itemElem.GetAttribute(ATTRIBUTE_DTMF, dtmfText);        translator.SetVariable(L"_prompt", promptText);        translator.SetVariable(L"_dtmf",   dtmfText);        for (VXMLNodeIterator subNode(elem); subNode; ++subNode)          ProcessSegments(*subNode, item, propertyList, translator,                          bargein, props, sofar, isSSML);      }    }    break;  }  default:    log->LogError(999, SimpleLogger::MESSAGE,                  L"logic error PromptManager::ProcessSegments");    throw VXIException::Fatal();  }}void PromptManager::AddContent(const VXMLElement & elem,                               const VXMLElement & item,                               const PropertyList & propertyList,                               PromptTranslator & translator,                               BargeIn bargein,                               VXIMapHolder & props,                               vxistring & sofar,                               VXIValue * value,                               bool & isSSML){  // (1) Create new audio reference data map.  VXIMapHolder valueData;  if (valueData.GetValue() == NULL) throw VXIException::OutOfMemory();  // (2) Populate the inner map.  VXIMapSetProperty(valueData.GetValue(), PROMPT_AUDIO_REF_DATA, value);  propertyList.GetFetchobjCacheAttrs(elem, PropertyList::Grammar, valueData);  // (3) Generate a hidden name and place the inner map inside the properties.  vxistring hiddenName;  VXMLDocumentModel::CreateHiddenVariable(hiddenName);  VXIMapHolder allRefs(NULL);  // Get existing map (if it exists) or create a new one.  const VXIValue * temp = VXIMapGetProperty(props.GetValue(),                                            PROMPT_AUDIO_REFS);  if (temp != NULL && VXIValueGetType(temp) == VALUE_MAP)    allRefs.Acquire(VXIMapClone(reinterpret_cast<const VXIMap *>(temp)));  else    allRefs.Acquire(VXIMapCreate());  if (allRefs.GetValue() == NULL) throw VXIException::OutOfMemory();  // Place references for this value into the 'all refs' map.  VXIMapSetProperty(allRefs.GetValue(), hiddenName.c_str(),                    reinterpret_cast<VXIValue *>(valueData.Release()));  // And replace the 'all refs' map in the properties.  VXIMapSetProperty(props.GetValue(), PROMPT_AUDIO_REFS,                    reinterpret_cast<VXIValue *>(allRefs.Release()));  // (5.2.4) Create fake 'src' for this audio element.  hiddenName = vxistring(PROMPT_AUDIO_REFS_SCHEME) + hiddenName;  // (5.2.5) Handle the SSML case  if (isSSML) {    sofar += L"<audio src=\"";    sofar += hiddenName;    sofar += L"\"";    if (elem.hasChildren()) {      sofar += L">";      for (VXMLNodeIterator it(elem); it; ++it)        ProcessSegments(*it, item, propertyList, translator,                        bargein, props, sofar, isSSML);      sofar += L"</audio>";    }    else      sofar += L"/>";    return;  }  // (5.2.6) Otherwise, we're dealing simple text & audio.    if (!sofar.empty()) {    AddSegment(SEGMENT_TEXT, sofar, props, bargein);    sofar.erase();  }  AddSegment(SEGMENT_AUDIO, hiddenName, props, bargein);  return;}

⌨️ 快捷键说明

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