Пример #1
0
static void ShowPropertyValues(const VXIchar *key,
           const VXIValue *value, VXIunsigned PROP_TAG,
           VXIlogInterface *log)
{
  VXIchar subtag[512] = L"Property";
  if( value == 0 ) return;
  VXIvalueType type = VXIValueGetType(value);
  {
    switch( type )
    {
      case VALUE_INTEGER:
        wcscpy(subtag, L"Property:INT");
        Diag(log, PROP_TAG, subtag, 
             L"%s=%d", key, VXIIntegerValue((const VXIInteger*)value));
        break;
      case VALUE_FLOAT:
        wcscpy(subtag, L"Property:FLT");
        Diag(log, PROP_TAG, subtag, 
             L"%s=%f", key, VXIFloatValue((const VXIFloat*)value));
        break;
      case VALUE_BOOLEAN:     
        wcscpy(subtag, L"Property:BOOL");
        Diag(log, PROP_TAG, subtag, 
             L"%s=%d", key, VXIBooleanValue((const VXIBoolean*)value));
        break;
      case VALUE_STRING:
        wcscpy(subtag, L"Property:STR");
        Diag(log, PROP_TAG, subtag, 
             L"%s=%s", key, VXIStringCStr((const VXIString*)value));
        break;
      case VALUE_PTR:
        wcscpy(subtag, L"Property:PTR");
        Diag(log, PROP_TAG, subtag, 
             L"%s(ptr)=0x%p", key, VXIPtrValue((const VXIPtr*)value));
        break;
      case VALUE_CONTENT:
        wcscpy(subtag, L"Property:CNT");
        Diag(log, PROP_TAG, subtag, 
             L"%s(content)=0x%p", key, value);
        break;
      case VALUE_MAP:
        {
          VXIchar endtag[512];
          const VXIchar *mykey = key ? key : L"NULL";
          wcscpy(subtag, L"Property:MAP:BEG");
          wcscpy(endtag, L"Property:MAP:END");
          Diag(log, PROP_TAG, subtag, L"%s", mykey);
          const VXIchar *key = NULL;
          const VXIValue *gvalue = NULL;

          VXIMapIterator *it = VXIMapGetFirstProperty((const VXIMap*)value, &key, &gvalue);
          int ret = 0;
          while( ret == 0 && key && gvalue )
          {
            ShowPropertyValues(key, gvalue, PROP_TAG, log);
            ret = VXIMapGetNextProperty(it, &key, &gvalue);
          }
          VXIMapIteratorDestroy(&it);         
          Diag(log, PROP_TAG, endtag, L"%s", mykey);
        }   
        break;
      case VALUE_VECTOR:
        {
          VXIunsigned vlen = VXIVectorLength((const VXIVector*)value);
          for(VXIunsigned i = 0; i < vlen; ++i)
          {
            const VXIValue *gvalue = VXIVectorGetElement((const VXIVector*)value, i);
            ShowPropertyValues(L"Vector", gvalue, PROP_TAG, log);
          }
        }
        break;
      default:
        Diag(log, PROP_TAG, subtag, L"%s=%s", key, L"UNKOWN");
    }          
  }
  return;
}
Пример #2
0
static VXIrecResult VXIrecLoadGrammarOption(VXIrecInterface * pThis,
                                      const VXIMap    * properties,
                                      const VXIVector * gramChoice,
                                      const VXIVector * gramValue,
                                      const VXIVector * gramAcceptance,
                                      const VXIbool     isDTMF,
                                      VXIrecGrammar  ** gram)
{
  const wchar_t* fnname = L"VXIrecLoadGrammarOption";
  std::ostringstream srgs_version;
  vxistring srgs_wide_version;
  VXIunsigned num_choices;
  VXIvalueType value_type;
  const VXIValue *utterance_value;
  // Check the arguments
  VXIrecData* tp = GetRecData(pThis);
  if (tp == NULL) return VXIrec_RESULT_INVALID_ARGUMENT;
  LogBlock logger(tp->GetLog(), gblDiagLogBase, fnname, VXIREC_MODULE);
    
  if (gram == NULL) {
    logger = VXIrec_RESULT_INVALID_ARGUMENT;
    return VXIrec_RESULT_INVALID_ARGUMENT;
  }

  //  DEBUG
  if (voiceglue_loglevel() >= LOG_DEBUG)
  {
      std::ostringstream logstring;
      logstring << "VXIrecLoadGrammarOption called with type "
		<< (isDTMF ? "DTMF" : "speech")
		<< ", choices "
		<< VXIValue_to_Std_String ((VXIValue *) gramChoice)
		<< ", values "
		<< VXIValue_to_Std_String ((VXIValue *) gramValue)
		<< ", properties "
		<< VXIValue_to_Std_String ((const VXIValue *) properties);
      voiceglue_log ((char) LOG_DEBUG, logstring);
  };

  tp->ShowPropertyValue(properties);

  //  Convert to SRGS grammar
  num_choices = VXIVectorLength (gramChoice);
  srgs_version << "<rule id=\"choice\">\n  <one-of>\n";
  for (VXIunsigned choice_num = 0; choice_num < num_choices; ++choice_num)
  {
      srgs_version << "    <item> ";
      utterance_value = VXIVectorGetElement (gramChoice, choice_num);
      value_type = VXIValueGetType (utterance_value);
      if (value_type == VALUE_INTEGER)
      {
	  srgs_version << VXIIntegerValue ((const VXIInteger*) utterance_value);
      }
      else if (value_type == VALUE_LONG)
      {
	  srgs_version << VXILongValue ((const VXILong*) utterance_value);
      }
      else if (value_type == VALUE_ULONG)
      {
	  srgs_version << VXIULongValue ((const VXIULong*) utterance_value);
      }
      else if (isDTMF)
      {
	  srgs_version << VXIchar_to_Std_String (
	      VXIStringCStr ((VXIString *) utterance_value));
      }
      else
      {
	  srgs_version << (choice_num + 1);
      };
      srgs_version << " <tag>"
		   << VXIchar_to_Std_String (
		       VXIStringCStr (
			   (VXIString *) VXIVectorGetElement
			   (gramValue, choice_num)))
		   << "</tag> </item>\n";
  };
  srgs_version << "  </one-of>\n</rule>\n";
  srgs_wide_version = Std_String_to_vxistring (srgs_version.str());
  return VXIrecLoadGrammarFromString
      (pThis,
       properties,
       L"text/x-grammar-choice-dtmf",
       (const VXIchar *) srgs_wide_version.c_str(),
       gram);
  
  VXIrecGrammar * gp = NULL;
  
  vxistring srgsGram;
  if( !tp->OptionToSRGS(properties, gramChoice, gramValue, 
                       gramAcceptance, isDTMF, srgsGram) )
    return VXIrec_RESULT_FAILURE;

  // Parsing SRGS grammar.
  // NOTES: The parsing is very simple, therefore it may not work
  // for complex grammar.  As you know, this is a simulator!!!
  
  VXIrecGrammar * gramPtr = tp->ParseSRGSGrammar(srgsGram, properties, isDTMF);
  if( gramPtr == NULL ) return VXIrec_RESULT_FAILURE;
  tp->AddGrammar(gramPtr);
  *gram = ToVXIrecGrammar(gramPtr);

  return VXIrec_RESULT_SUCCESS;
}
Пример #3
0
// This function is responsible for calling the VXIrec level Recognize function
// and then mapping the grammar back to the corresponding VXML node.
//
int GrammarManager::Recognize(const VXIMapHolder & properties,
                              RecognitionAnswer & recAnswer,
                              VXMLElement & recNode)
{
  recNode = VXMLElement();
  VXIrecRecognitionResult * answer = NULL;

  // (1) Do VXIrec level Recognitize and process return value.

  // (1.1) Recognize.
  VXIrecResult err = vxirec->Recognize(vxirec, properties.GetValue(),
                                       &answer);
  if (err == VXIrec_RESULT_OUT_OF_MEMORY) {
    log.LogDiagnostic(0,L"GrammarManager::InternalRecognize - Out of memory.");
    return GrammarManager::OutOfMemory;
  }

  if (err == VXIrec_RESULT_DISCONNECT) {
    // Here is the case that the call is being disconnected before the 
    // recognition even starts
    return GrammarManager::Disconnect;
  }

  // (1.2) Anything other than success indicates that recognition failed
  // (badly).  The normal error conditions are returned through the recogntion
  // result structure.
  if (err != VXIrec_RESULT_SUCCESS) {
    log.StartDiagnostic(0) << L"GrammarManager::InternalRecognize - "
      L"VXIrecInterface::Recognize returned " << int (err);
    log.EndDiagnostic();
    log.LogError(420, SimpleLogger::MESSAGE,
                 L"function did not return the expected VXIrecSUCCESS result");
    return GrammarManager::InternalError;
  }

  // (1.3) The answer structure must be defined.
  if (answer == NULL) {
    // Here is the case that the call is being disconnected before the recording even starts
    return GrammarManager::Disconnect;
  }

  // (1.4) Attach the answer structure returned by VXIrec and the waveform to
  // the recAnswer class.
  recAnswer.Bind(answer);
  recAnswer.waveform = answer->waveform;

  // (2) Process all non-Successful results.

  // (2.1) First the status code.

  switch (answer->status) {
  case REC_STATUS_SUCCESS:    // Recognition returned a hypothesis
  case REC_STATUS_DTMFSUCCESS:    // Recognition returned a hypothesis
    break;
  case REC_STATUS_FAILURE:    // Speech detected, no likely hypothesis
    return GrammarManager::Failure;
  case REC_STATUS_TIMEOUT:    // No speech was detected
    return GrammarManager::Timeout;
  case REC_STATUS_DISCONNECT: // Caller has disconnected; no hypothesis
    return GrammarManager::Disconnect;
  case REC_STATUS_ERROR:      // An error aborted recognition
    return GrammarManager::Error;
  default:
    log.StartDiagnostic(0) << L"GrammarManager::InternalRecognize - "
      L"VXIrecInterface::Recognize returned status " << int(answer->status);
    log.EndDiagnostic();
    log.LogError(420, SimpleLogger::MESSAGE,
                 L"function returned an invalid VXIrecStatus code");
    return GrammarManager::InternalError;
  }

  // (2.2) Recognition success. Verify that the input mode was set correctly.

  switch (answer->mode) {
  case REC_INPUT_MODE_DTMF:
  case REC_INPUT_MODE_SPEECH:
    break;
  default:
    log.StartDiagnostic(0) << L"GrammarManager::InternalRecognize - "
      L"VXIrecInterface::Recognize returned mode " << int(answer->mode);
    log.EndDiagnostic();
    log.LogError(420, SimpleLogger::MESSAGE,
                 L"function returned an invalid VXIrecInputMode value");
    return GrammarManager::InternalError;
  }

  // (3) Walk through results array and sanity check the results.

  // (3.1) How many answers are there?

  if (answer->results == NULL) {
    log.LogError(420, SimpleLogger::MESSAGE,
                 L"function returned a null results vector");
    return GrammarManager::InternalError;
  }

  unsigned int NUM_ANSWERS = VXIVectorLength(answer->results);
  if (NUM_ANSWERS == 0) {
    log.LogError(420, SimpleLogger::MESSAGE,
                 L"function returned an empty results vector");
    return GrammarManager::InternalError;
  }

  const VXIMap * bestAnswer = NULL;

  for (unsigned int i = 0; i < NUM_ANSWERS; ++i) {
    // (3.2) Find each element in the result vector.
    
    const VXIValue * temp = VXIVectorGetElement(answer->results, i);
    if (temp == NULL) {
      log.LogError(400, SimpleLogger::MESSAGE,
                   L"VXIVectorGetElement failed to return answer.");
      return GrammarManager::InternalError;
    }
    
    if (VXIValueGetType(temp) != VALUE_MAP) {
      log.LogError(420, SimpleLogger::MESSAGE,
                   L"function returned an invalid results vector");
      return GrammarManager::InternalError;
    }

    const VXIMap * nthAnswer = reinterpret_cast<const VXIMap*>(temp);
    if (i == 0) bestAnswer = nthAnswer;

    // (3.3) Validate types of member keys.

    temp = VXIMapGetProperty(nthAnswer, REC_KEYS);
    if (temp == NULL || VXIValueGetType(temp) != VALUE_VECTOR) {
      log.LogError(420, SimpleLogger::MESSAGE,
                   L"REC_KEYS must be defined with type vector");
      return GrammarManager::InternalError;
    }
    const VXIVector * keys = reinterpret_cast<const VXIVector *>(temp);

    temp = VXIMapGetProperty(nthAnswer, REC_VALUES);
    if (temp == NULL || VXIValueGetType(temp) != VALUE_VECTOR) {
      log.LogError(420, SimpleLogger::MESSAGE,
                   L"REC_VALUES must be defined with type vector");
      return GrammarManager::InternalError;
    }
    const VXIVector * values = reinterpret_cast<const VXIVector *>(temp);

    temp = VXIMapGetProperty(nthAnswer, REC_CONF);
    if (temp == NULL || VXIValueGetType(temp) != VALUE_VECTOR) {
      log.LogError(420, SimpleLogger::MESSAGE,
                   L"REC_CONF must be defined with type vector");
      return GrammarManager::InternalError;
    }
    const VXIVector * scores = reinterpret_cast<const VXIVector *>(temp);

    temp = VXIMapGetProperty(nthAnswer, REC_RAW);
    if (temp == NULL || VXIValueGetType(temp) != VALUE_VECTOR) {
      log.LogError(420, SimpleLogger::MESSAGE,
                   L"REC_RAW must be defined with type vector");
      return GrammarManager::InternalError;
    }
    const VXIVector * utts = reinterpret_cast<const VXIVector *>(temp);

    // (3.4) Validate vector lengths.

    const VXIunsigned length = VXIVectorLength(keys);
    if (length < 1) {
      log.LogError(420, SimpleLogger::MESSAGE,
                   L"result vector must have length of at least one");
      throw VXIException::Fatal();
    }
    if (length != VXIVectorLength(values) ||
        length != VXIVectorLength(scores) ||
        length != VXIVectorLength(utts))
    {
      log.LogError(420, SimpleLogger::MESSAGE,
                   L"result vector length must all match");
      return GrammarManager::InternalError;
    }

    temp = VXIVectorGetElement(keys, 0);
    if (temp == NULL || VXIValueGetType(temp) != VALUE_STRING) {
      log.LogError(420, SimpleLogger::MESSAGE,
                   L"first REC_KEYS must be defined with type string");
      return GrammarManager::InternalError;
    }

    // (3.5) Copy into results class.

    recAnswer.keys.push_back(keys);
    recAnswer.values.push_back(values);
    recAnswer.scores.push_back(scores);
    recAnswer.utts.push_back(utts);
  }

  recAnswer.numAnswers = NUM_ANSWERS;

  // (4) Find the VXML element associated with the matched grammar.

  // (4.1) Find the grammar corresponding to the best answer.

  const VXIValue * temp = VXIMapGetProperty(bestAnswer, REC_GRAMMAR);
  if (temp == NULL || VXIValueGetType(temp) != VALUE_PTR) {
    log.LogError(420, SimpleLogger::MESSAGE,
                 L"unable to obtain grammar key from 'results' #0");
    return GrammarManager::InternalError;
  }

  const VXIPtr * tempptr = reinterpret_cast<const VXIPtr *>(temp);
  const VXIrecGrammar * bestGrammar =
    reinterpret_cast<const VXIrecGrammar*>(VXIPtrValue(tempptr));

  // (4.2) Map the VXIrecGrammar pointer back to the source VXMLElement.

  for (GRAMMARS::iterator j = grammars.begin(); j != grammars.end(); ++j) 
  {
    if ((answer->mode == REC_INPUT_MODE_DTMF && REC_STATUS_DTMFSUCCESS != answer->status) 
      && (*j)->GetRecGrammar() != bestGrammar) continue;

    if (!(*j)->IsEnabled()) 
    {
      if (j == grammars.end()) {
        log.LogError(420, SimpleLogger::MESSAGE,
                     L"function returned an inactive grammar");
        return GrammarManager::InternalError;
      }
      continue;
    }

    (*j)->GetElement(recNode);

    if (answer->mode == REC_INPUT_MODE_DTMF)
      return GrammarManager::SuccessDTMF;

    return GrammarManager::Success;
  }

  log.LogError(420, SimpleLogger::MESSAGE,
               L"function returned a non-existent grammar");
  return GrammarManager::InternalError;
}