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

📄 vxml.cxx

📁 pwlib源码库
💻 CXX
📖 第 1 页 / 共 5 页
字号:
  PTRACE(3, "PVXML\tDocument: " << str << " = \"" << val << "\"");  // assume any other scope is actually document or application  documentVars.SetAt(str, val);}BOOL PVXMLSession::PlayFile(const PString & fn, PINDEX repeat, PINDEX delay, BOOL autoDelete){  if (vxmlChannel == NULL || !vxmlChannel->QueueFile(fn, repeat, delay, autoDelete))    return FALSE;  AllowClearCall();  return TRUE;}BOOL PVXMLSession::PlayCommand(const PString & cmd, PINDEX repeat, PINDEX delay){  if (vxmlChannel == NULL || !vxmlChannel->QueueCommand(cmd, repeat, delay))    return FALSE;  AllowClearCall();  return TRUE;}BOOL PVXMLSession::PlayData(const PBYTEArray & data, PINDEX repeat, PINDEX delay){  if (vxmlChannel == NULL || !vxmlChannel->QueueData(data, repeat, delay))    return FALSE;  AllowClearCall();  return TRUE;}void PVXMLSession::GetBeepData(PBYTEArray & data, unsigned ms){  if (vxmlChannel != NULL)    vxmlChannel->GetBeepData(data, ms);}BOOL PVXMLSession::PlaySilence(const PTimeInterval & timeout){  return PlaySilence((PINDEX)timeout.GetMilliSeconds());}BOOL PVXMLSession::PlaySilence(PINDEX msecs){  PBYTEArray nothing;  if (vxmlChannel == NULL || !vxmlChannel->QueueData(nothing, 1, msecs))    return FALSE;  AllowClearCall();  return TRUE;}BOOL PVXMLSession::PlayResource(const PURL & url, PINDEX repeat, PINDEX delay){  if (vxmlChannel == NULL || !vxmlChannel->QueueResource(url, repeat, delay))    return FALSE;  AllowClearCall();  return TRUE;}BOOL PVXMLSession::LoadGrammar(PVXMLGrammar * grammar){  if (activeGrammar != NULL) {    delete activeGrammar;    activeGrammar = FALSE;  }  activeGrammar = grammar;  return TRUE;}BOOL PVXMLSession::PlayText(const PString & _text,                     PTextToSpeech::TextType type,                                      PINDEX repeat,                                      PINDEX delay){  PStringArray list;  BOOL useCache = !(GetVar("caching") *= "safe");  if (!ConvertTextToFilenameList(_text, type, list, useCache) || (list.GetSize() == 0)) {    PTRACE(1, "PVXML\tCannot convert text to speech");    return FALSE;  }  PVXMLPlayableFilenameList * playable = new PVXMLPlayableFilenameList;  if (!playable->Open(*vxmlChannel, list, delay, repeat, !useCache)) {    delete playable;    PTRACE(1, "PVXML\tCannot create playable for filename list");    return FALSE;  }  return vxmlChannel->QueuePlayable(playable);}BOOL PVXMLSession::ConvertTextToFilenameList(const PString & _text, PTextToSpeech::TextType type, PStringArray & filenameList, BOOL useCache){  PString prefix = psprintf("tts%i", type);  PStringArray lines = _text.Trim().Lines();  for (PINDEX i = 0; i < lines.GetSize(); i++) {    PString text = lines[i].Trim();    if (text.IsEmpty())      continue;    BOOL spoken = FALSE;    PFilePath dataFn;    // see if we have converted this text before    PString contentType;    if (useCache)      spoken = PVXMLCache::GetResourceCache().Get(prefix, text, "wav", contentType, dataFn);    // if not cached, then use the text to speech converter    if (!spoken) {      PFilePath tmpfname;      if (textToSpeech != NULL) {        tmpfname = PVXMLCache::GetResourceCache().GetRandomFilename("tts", "wav");        if (!textToSpeech->OpenFile(tmpfname)) {          PTRACE(2, "PVXML\tcannot open file " << tmpfname);        } else {          spoken = textToSpeech->Speak(text, type);          if (!textToSpeech->Close()) {            PTRACE(2, "PVXML\tcannot close TTS engine");          }        }        textToSpeech->Close();        if (useCache)          PVXMLCache::GetResourceCache().Put(prefix, text, "wav", contentType, tmpfname, dataFn);        else          dataFn = tmpfname;      }    }    if (!spoken) {      PTRACE(2, "PVXML\tcannot speak text using TTS engine");    } else       filenameList.AppendString(dataFn);  }  return filenameList.GetSize() > 0;}void PVXMLSession::SetPause(BOOL _pause){  if (vxmlChannel != NULL)    vxmlChannel->SetPause(_pause);}BOOL PVXMLSession::IsPlaying() const{  return (vxmlChannel != NULL) && vxmlChannel->IsPlaying();}BOOL PVXMLSession::StartRecording(const PFilePath & /*_recordFn*/,                                                BOOL /*_recordDTMFTerm*/,                               const PTimeInterval & /*_recordMaxTime*/,                               const PTimeInterval & /*_recordFinalSilence*/){  /*  recording          = TRUE;  recordFn           = _recordFn;  recordDTMFTerm     = _recordDTMFTerm;  recordMaxTime      = _recordMaxTime;  recordFinalSilence = _recordFinalSilence;  if (incomingChannel != NULL) {    PXMLElement* element = (PXMLElement*) currentNode;    if ( element->HasAttribute("name")) {      PString chanName = element->GetAttribute("name");      incomingChannel->SetName(chanName);    }    return incomingChannel->StartRecording(recordFn, (unsigned )recordFinalSilence.GetMilliSeconds());  }  */  return FALSE;}void PVXMLSession::RecordEnd(){  if (recording)    recordSync.Signal();}BOOL PVXMLSession::EndRecording(){  if (recording) {	  recording = FALSE;    if (vxmlChannel != NULL)      return vxmlChannel->EndRecording();  }  return FALSE;}BOOL PVXMLSession::IsRecording() const{  return (vxmlChannel != NULL) && vxmlChannel->IsRecording();}PWAVFile * PVXMLSession::CreateWAVFile(const PFilePath & fn, PFile::OpenMode mode, int opts, unsigned fmt){   if (!fn.IsEmpty())    return new PWAVFile(fn, mode, opts, fmt);  return new PWAVFile(mode, opts, fmt); }void PVXMLSession::AllowClearCall(){  allowFinish = TRUE;}BOOL PVXMLSession::TraverseAudio(){  if (!currentNode->IsElement()) {    PlayText(((PXMLData *)currentNode)->GetString());  }  else {    PXMLElement * element = (PXMLElement *)currentNode;    if (element->GetName() *= "value") {      PString className = element->GetAttribute("class");      PString value = EvaluateExpr(element->GetAttribute("expr"));      SayAs(className, value);    }    else if (element->GetName() *= "sayas") {      PString className = element->GetAttribute("class");      PXMLObject * object = element->GetElement();      if (!object->IsElement()) {        PString text = ((PXMLData *)object)->GetString();        SayAs(className, text);      }    }    else if (element->GetName() *= "break") {      // msecs is VXML 1.0      if (element->HasAttribute("msecs"))        PlaySilence(element->GetAttribute("msecs").AsInteger());      // time is VXML 2.0      else if (element->HasAttribute("time")) {        PTimeInterval time = StringToTime(element->GetAttribute("time"));        PlaySilence(time);      }            else if (element->HasAttribute("size")) {        PString size = element->GetAttribute("size");        if (size *= "none")          ;        else if (size *= "small")          PlaySilence(SMALL_BREAK_MSECS);        else if (size *= "large")          PlaySilence(LARGE_BREAK_MSECS);        else           PlaySilence(MEDIUM_BREAK_MSECS);      }             // default to medium pause      else {        PlaySilence(MEDIUM_BREAK_MSECS);      }    }    else if (element->GetName() *= "audio") {      BOOL loaded = FALSE;      if (element->HasAttribute("src")) {        PString str = element->GetAttribute("src").Trim();        if (!str.IsEmpty() && (str[0] == '|')) {          loaded = TRUE;          PlayCommand(str.Mid(1));        }                 else {          // get a normalised name for the resource          PFilePath fn;           PURL url = NormaliseResourceName(str);          // load the resource from the cache          PString contentType;          BOOL useCache = !(GetVar("caching") *= "safe") && !(element->GetAttribute("caching") *= "safe");          if (RetreiveResource(url, contentType, fn, useCache)) {            PWAVFile * wavFile = vxmlChannel->CreateWAVFile(fn);            if (wavFile == NULL)              PTRACE(3, "PVXML\tCannot create audio file " + fn);            else if (!wavFile->IsOpen())              delete wavFile;            else {              loaded = TRUE;              PlayFile(fn, 0, 0, !useCache);   // make sure we delete the file if not cacheing            }          }        }        if (loaded) {          // skip to the next node          if (element->HasSubObjects())					  currentNode = element->GetElement(element->GetSize() - 1);        }      }    }    else       PTRACE(3, "PVXML\tUnknown audio tag " << element->GetName() << " encountered");  }  return TRUE;}BOOL PVXMLSession::TraverseGoto()		// <goto>{  PAssert(currentNode != NULL, "ProcessGotoElement(): Expected valid node");  if (currentNode == NULL)    return FALSE;    // LATER: handle expr, expritem, fetchaudio, fetchhint, fetchtimeout, maxage, maxstale    PAssert(currentNode->IsElement(), "ProcessGotoElement(): Expected element");    // nextitem  PString nextitem = ((PXMLElement*)currentNode)->GetAttribute("nextitem");  if (!nextitem.IsEmpty()) {    // LATER: Take out the optional #    currentForm = FindForm(nextitem);    currentNode = currentForm;    if (currentForm == NULL) {      // LATER: throw "error.semantic" or "error.badfetch" -- lookup which      return FALSE;    }    return TRUE;  }    // next  PString next = ((PXMLElement*)currentNode)->GetAttribute("next");  // LATER: fixup filename to prepend path  if (!next.IsEmpty()) {     if (next[0] == '#') {      next = next.Right( next.GetLength() -1 );      currentForm = FindForm(next);      currentNode = currentForm;      // LATER: throw "error.semantic" or "error.badfetch" -- lookup which      return currentForm != NULL;    }    else {      PURL url = NormaliseResourceName(next);      return LoadURL(url) && (currentForm != NULL);    }  }  return FALSE;}BOOL PVXMLSession::TraverseGrammar()		// <grammar>{  // LATER: A bunch of work to do here!  // For now we only support the builtin digits type and do not parse any grammars.  // NOTE: For now we will process both <grammar> and <field> here.  // NOTE: Later there needs to be a check for <grammar> which will pull  //       out the text and process a grammar like '1 | 2'  // Right now we only support one active grammar.  if (activeGrammar != NULL) {    PTRACE(2, "PVXML\tWarning: can only process one grammar at a time, ignoring previous grammar");    delete activeGrammar;    activeGrammar = NULL;  }  PVXMLGrammar * newGrammar = NULL;  // Is this a built-in type?  PString type = ((PXMLElement*)currentNode)->GetAttribute("type");  if (!type.IsEmpty()) {    PStringArray tokens = type.Tokenise("?;", TRUE);    PString builtintype;    if (tokens.GetSize() > 0)      builtintype = tokens[0];    if (builtintype *= "digits") {      PINDEX minDigits(1);      PINDEX maxDigits(100);      // look at each parameter      for (PINDEX i(1); i < tokens.GetSize(); i++) {        PStringArray params = tokens[i].Tokenise("=", TRUE);        if (params.GetSize() == 2) {          if (params[0] *= "minlength") {            minDigits = params[1].AsInteger();          }          else if (params[0] *= "maxlength") {            maxDigits = params[1].AsInteger();          }          else if (params[0] *= "length") {            minDigits = maxDigits = params[1].AsInteger();          }        }        else {          // Invalid parameter skipped          // LATER: throw 'error.semantic'        }      }      newGrammar = new PVXMLDigitsGrammar((PXMLElement*)currentNode, minDigits, maxDigits, "");    }    else {      // LATER: throw 'error.unsupported'      return FALSE;    }  }  if (newGrammar != NULL)    return LoadGrammar(newGrammar);  return TRUE;}// Finds the proper event hander for 'noinput', 'filled', 'nomatch' and 'error'// by searching the scope hiearchy from the current fromPXMLElement * PVXMLSession::FindHandler(const PString & event){  PAssert(currentNode->IsElement(), "Expected 'PXMLElement' in PVXMLSession::FindHandler");  PXMLElement * tmp = (PXMLElement *)currentNode;  PXMLElement * handler = NULL;  // Look in all the way up the tree for a handler either explicitly or in a catch  while (tmp != NULL) {    // Check for an explicit hander - i.e. <error>, <filled>, <noinput>, <nomatch>, <help>    if ((handler = tmp->GetElement(event)) != NULL)      return handler;    // Check for a <catch>    if ((handler = tmp->GetElement("catch")) != NULL) {      PString strCond = handler->GetAttribute("cond");      if (strCond.Find(event))        return handler;    }    tmp = tmp->GetParent();  }  return NULL;}void PVXMLSession::SayAs(const PString & className, const PString & _text){  PString text = _text.Trim();  if (!text.IsEmpty()) {    PTextToSpeech::TextType type = PTextToSpeech::Literal;    if (className *= "digits")      type = PTextToSpeech::Digits;    else if (className *= "literal")      type = PTextToSpeech::Literal;    else if (className *= "number")      type = PTextToSpeech::Number;    else if (className *= "currency")      type = PTextToSpeech::Currency;    else if (className *= "time")      type = PTextToSpeech::Time;    else if (className *= "date")      type = PTextToSpeech::Date;

⌨️ 快捷键说明

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