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

📄 vxirec.cpp

📁 openvxi3.4是一个voicexml对话脚本语言的解释器源码.可用VC6.0编译.
💻 CPP
📖 第 1 页 / 共 2 页
字号:
        logger.logDiag(DIAG_TAG_RECOGNITION, L"%s%s", L"DTMFInput: ",
                       VXIStringCStr((const VXIString*)val));      
      }
    }
    VXIString* vect = (VXIString*) val;
    if (vect != NULL) input = (VXIchar*) VXIStringCStr(vect);

    if (input && wcscmp(input, L"-") == 0) {
      unsigned int i;
      VXIchar* cp = console;
      char lbuf[512];
      printf("Console: ");
      fgets(lbuf, 511, stdin);
      // copy to VXIchar
      for(i = 0; i < strlen(lbuf); ++i) {
        if (lbuf[i] == '\r' || lbuf[i] == '\n') continue;
        *cp++ = lbuf[i] & 0x7f;
      }
      *cp++ = 0;
      input = console;
      logger.logDiag(DIAG_TAG_RECOGNITION, L"%s%s", L"Input: ", 
                     (input ? input : L"NULL"));
    }
  }

  // Create a new results structure.
  const unsigned int CHARSIZE = sizeof(VXIchar) / sizeof(VXIbyte);
  VXIContent * xmlresult = NULL;

  // Looking for matched phrase, if not act appropriately
  vxistring nlsmlresult;
  bool found = tp->ConstructNLSMLForInput(input, nlsmlresult);  
  if( !found ) {
    if( !input || input[0] == L'\0' ) {
      // No input case
      haveUtterance = false;
      logger.logDiag(DIAG_TAG_RECOGNITION, L"%s", L"-- NO_INPUT RESULT --");
      xmlresult = VXIContentCreate(VXIREC_MIMETYPE_XMLRESULT,
                                   (VXIbyte *) NLSML_NOINPUT,
                                   NLSML_NOINPUT_SIZE * CHARSIZE,
                                   DestroyNLSMLBuffer, NULL);    
    } else {
      // No match case
      logger.logDiag(DIAG_TAG_RECOGNITION, L"%s", L"-- NO_MATCH RESULT --");
      xmlresult = VXIContentCreate(VXIREC_MIMETYPE_XMLRESULT,
                                   (VXIbyte *) NLSML_NOMATCH,
                                   NLSML_NOMATCH_SIZE * CHARSIZE,
                                   DestroyNLSMLBuffer, NULL);      
    }
  }
  else {
    // Found matched grammar  
    logger.logDiag(DIAG_TAG_RECOGNITION, L"%s%s", L"NLSML_RESULT: ", 
                   nlsmlresult.c_str());
    
    unsigned int BUFFERSIZE = (nlsmlresult.length() + 1) * CHARSIZE;
    VXIbyte * buffer = new VXIbyte[BUFFERSIZE];
    if (buffer == NULL) return VXIrec_RESULT_OUT_OF_MEMORY;
    memcpy(buffer, nlsmlresult.c_str(), BUFFERSIZE);

    xmlresult = VXIContentCreate(VXIREC_MIMETYPE_XMLRESULT,
                                 buffer, BUFFERSIZE,
                                 DestroyNLSMLBuffer, buffer);

    if (xmlresult == NULL) {
      delete [] buffer;
      return VXIrec_RESULT_OUT_OF_MEMORY;
    }
  }

  VXIrecRecognitionResult * result = new VXIrecRecognitionResult();
  if (result == NULL) {
    VXIContentDestroy(&xmlresult);
    return VXIrec_RESULT_OUT_OF_MEMORY;
  }

  result->Destroy = RecognitionResultDestroy;
  result->markname = NULL;
  result->marktime = 0;
  result->xmlresult = xmlresult;

  if (!haveUtterance ||!recordUtterance) {
    result->utterance = NULL;
    result->utteranceDuration = 0;
  }
  else {
    result->utteranceDuration = 5000; // 5sec
    unsigned int waveformSizeBytes = (result->utteranceDuration / 1000 ) * 8000 * sizeof(unsigned char);
    unsigned char * c_waveform = new unsigned char[waveformSizeBytes];
    if (c_waveform == NULL) {
      result->utterance = NULL;
      result->utteranceDuration = 0;
    }
    else {
      for (unsigned int i = 0; i < waveformSizeBytes; ++i)
        c_waveform[i] = i & 0x00ff;

      result->utterance = VXIContentCreate(VXIREC_MIMETYPE_ULAW,
                                           c_waveform, waveformSizeBytes,
                                           ResultContentDestroy, NULL);  
    }
  }

  *recogResult = result;

  return VXIrec_RESULT_SUCCESS;
}


static VXIrecResult VXIrecGetMatchedGrammar(VXIrecInterface *pThis,
                                            const VXIchar *grammarID,
                                            const VXIrecGrammar **gram)
{
  const wchar_t* fnname = L"VXIrecGetMatchedGrammar";
  VXIrecData* tp = GetRecData(pThis);
  if (tp == NULL) return VXIrec_RESULT_INVALID_ARGUMENT;
  LogBlock logger(tp->GetLog(), gblDiagLogBase, fnname, VXIREC_MODULE);

  if (grammarID == NULL || gram == NULL)
    return VXIrec_RESULT_INVALID_ARGUMENT;

  VXIrecGrammar * mgram = NULL;
  SWIswscanf(grammarID, L"%p", &mgram);

  *gram = mgram;
  logger.logDiag(DIAG_TAG_RECOGNITION, L"%s%p", L"Got Matched grammar: ", mgram); 
  return VXIrec_RESULT_SUCCESS;
}

static void RecordResultDestroy(VXIrecRecordResult **Result)
{
  if (Result == NULL || *Result == NULL) return;

  VXIrecRecordResult * result = *Result;

  if (result->waveform != NULL)
    VXIContentDestroy(&result->waveform);

  if (result->xmlresult != NULL)
    VXIContentDestroy(&result->xmlresult);

  delete result;
  *Result = NULL;
}

static VXIrecResult VXIrecRecord(VXIrecInterface *pThis,
                                 const VXIMap *props,
                                 VXIrecRecordResult **recordResult)
{
  const wchar_t* fnname = L"VXIrecRecord";
  VXIrecData* tp = GetRecData(pThis);
  if (tp == NULL) return VXIrec_RESULT_INVALID_ARGUMENT;
  LogBlock logger(tp->GetLog(), gblDiagLogBase, fnname, VXIREC_MODULE);

  if (recordResult == NULL) {
    logger = VXIrec_RESULT_INVALID_ARGUMENT;
    return VXIrec_RESULT_INVALID_ARGUMENT;
  }
  // (1) Create record structure
  VXIrecRecordResult *result = new VXIrecRecordResult();
  if (result == NULL) {
    logger = VXIrec_RESULT_OUT_OF_MEMORY;
    return VXIrec_RESULT_OUT_OF_MEMORY;
  }
  result->Destroy = RecordResultDestroy;
  result->waveform = NULL;
  result->xmlresult = NULL;
  result->duration = 0;
  result->termchar = 0;
  result->maxtime = FALSE;
  result->markname = NULL;
  result->marktime = 0;
  *recordResult = result;

  VXIlong duration = -1;
  VXIlong maxtime = 0;
  VXIlong finalsilence = 0;

  // (2) Get maxtime
  const VXIValue* val = VXIMapGetProperty(props, REC_MAX_RECORDING_TIME);
  if (val != NULL && VXIValueGetType(val) == VALUE_INTEGER )
    maxtime = VXIIntegerValue(reinterpret_cast<const VXIInteger *>(val));
  else
    maxtime = 1000 * 20; // in milliseconds (default to 20 secs)

  // (2.1) adjust duration for simulator
  if( duration < 0 ) duration = maxtime;
  (*recordResult)->duration = duration;
  if( duration == maxtime ) (*recordResult)->maxtime = TRUE;

  // TODO: this should use the media type.  For now just construct
  // raw ulaw audio with silence
  unsigned int waveformSizeBytes = (duration / 1000 ) * 8000 * sizeof(unsigned char);
  unsigned char * c_waveform = new unsigned char[waveformSizeBytes];
  if (c_waveform == NULL) {
    (*recordResult)->Destroy(recordResult);    
    tp->LogError(400, L"%s%s", L"Error", L"out of memory");
    return VXIrec_RESULT_OUT_OF_MEMORY;
  }
  for (unsigned int i = 0; i < waveformSizeBytes; ++i)
    c_waveform[i] = i & 0x00ff;

  (*recordResult)->waveform = VXIContentCreate(VXIREC_MIMETYPE_ULAW,
                                            c_waveform, waveformSizeBytes,
                                            ResultContentDestroy, NULL);  
  if( (*recordResult)->waveform == NULL ) {
    (*recordResult)->Destroy(recordResult);    
    tp->LogError(400, L"%s%s", L"Error", L"out of memory");
    return VXIrec_RESULT_OUT_OF_MEMORY;    
  }

  return VXIrec_RESULT_SUCCESS;
}

static VXIbool VXIrecSupportsHotwordTransfer(
  struct VXIrecInterface * pThis,
  const VXIMap  * properties,
  const VXIchar * transferDest)
{
  VXIbool result = FALSE;

  // this is really just to demonstrate how the platform could
  // support hotword for some type of transfers, but not others.
  // this could just as easily been based on other properties of
  // the transfer. i.e., destination type, required line type, etc...
  const VXIValue* dval = VXIMapGetProperty(properties, TEL_TRANSFER_TYPE);
  if( dval && VXIValueGetType(dval) == VALUE_STRING ){
    const wchar_t* hid = VXIStringCStr(reinterpret_cast<const VXIString *>(dval));
	if (wcscmp(hid, L"consultation") == 0)
      return FALSE;
  }

  dval = VXIMapGetProperty(properties, L"SupportsHotwordTransfer");
  if( dval && VXIValueGetType(dval) == VALUE_STRING ){
    const wchar_t* hid = VXIStringCStr(reinterpret_cast<const VXIString *>(dval));
	result = (wcscmp(hid, L"true") == 0) ? TRUE : FALSE;
  }

  return result;
}

static VXIrecResult VXIrecHotwordTransfer
(
  struct VXIrecInterface * pThis,
  struct VXItelInterface * tel,
  const VXIMap *properties,
  const VXIchar* transferDest,
  VXIrecTransferResult  ** transferResult
)
{
  const wchar_t* fnname = L"VXIrecHotwordTransfer";
  VXIrecData* tp = GetRecData(pThis);
  if (tp == NULL) return VXIrec_RESULT_INVALID_ARGUMENT;
  LogBlock logger(tp->GetLog(), gblDiagLogBase, fnname, VXIREC_MODULE);
  
  VXIrecResult res = VXIrec_RESULT_SUCCESS;

  // this is probably not how it would be done in real life...but for this
  // sample app it will suffice:
  // Do the transfer
  int activeGrammars = tp->GetActiveCount();

  VXIMap *xferResp = NULL;
  VXItelResult xferResult = tel->TransferBridge(tel, properties, transferDest, &xferResp);
  if (xferResult != VXItel_RESULT_SUCCESS) {
    res = VXIrec_RESULT_FAILURE;
  }
  else if (activeGrammars == 0) {
    *transferResult = new VXIrecTransferResult();
    (*transferResult)->Destroy = TransferResultDestroy;
    (*transferResult)->utterance = NULL;
    (*transferResult)->markname = NULL;
    (*transferResult)->marktime = 0;
    (*transferResult)->xmlresult = NULL;

    const VXIValue * v = VXIMapGetProperty(xferResp, TEL_TRANSFER_DURATION);
    if (v != NULL && VXIValueGetType(v) == VALUE_INTEGER)
      (*transferResult)->duration = VXIIntegerValue(reinterpret_cast<const VXIInteger*>(v));

    v = VXIMapGetProperty(xferResp, TEL_TRANSFER_STATUS);
    if (v != NULL && VXIValueGetType(v) == VALUE_INTEGER) {
      long temp = VXIIntegerValue(reinterpret_cast<const VXIInteger *>(v));
      (*transferResult)->status = VXItelTransferStatus(temp);
    }

	VXIMapDestroy(&xferResp);
  }
  else {
    // get input from the user.
    VXIrecRecognitionResult *recResult = NULL;
    VXIrecResult localRes = pThis->Recognize(pThis, properties, &recResult);
	if (localRes == VXIrec_RESULT_SUCCESS){
      *transferResult = new VXIrecTransferResult();
	  if ((*transferResult) == NULL) {
        recResult->Destroy(&recResult);
        VXIMapDestroy(&xferResp);
        return VXIrec_RESULT_OUT_OF_MEMORY;
	  }

      // setup the transfer result by first copying the 
	  // RecResult.
      (*transferResult)->Destroy = TransferResultDestroy;
      (*transferResult)->utterance = recResult->utterance;
      (*transferResult)->markname = recResult->markname;
	  (*transferResult)->marktime = recResult->marktime;
      (*transferResult)->xmlresult = recResult->xmlresult;
	  (*transferResult)->duration = 0;
	  (*transferResult)->status = VXItel_TRANSFER_FAR_END_DISCONNECT;

      // we no long need the rec result (but we don't want the VXIContent
	  // fields destroyed).
	  recResult->utterance = NULL;
	  recResult->xmlresult = NULL;
	  recResult->Destroy(&recResult);

      // translate the status and duration to the transfer result fields.
	  // since this code is simply so that Hotword transfers work, any
	  // valid recognition (ignoring noinput and nomatch) will set the
	  // transfer to "near_end_disconnect".  Otherwise, we pretend that
	  // the other end terminated the transfer.
	  if((*transferResult)->xmlresult){
	    // we're going to ignore noinput and nomatch results.
        const VXIchar * contentType;
        const VXIbyte * content;
        VXIulong contentSize = 0; 
        VXIContentValue((*transferResult)->xmlresult, &contentType, &content, &contentSize);

	    // we're going to ignore noinput and nomatch results.
        if (   !wcsstr((VXIchar*)content, L"<noinput/>")
			&& !wcsstr((VXIchar*)content, L"<nomatch/>")){
          (*transferResult)->status = VXItel_TRANSFER_NEAR_END_DISCONNECT;
        }
      }

	  const VXIValue * v = VXIMapGetProperty(xferResp, TEL_TRANSFER_DURATION);
	  if (v != NULL && VXIValueGetType(v) == VALUE_INTEGER)
	    (*transferResult)->duration = VXIIntegerValue(reinterpret_cast<const VXIInteger*>(v));

	  VXIMapDestroy(&xferResp);
	}
  }

  return res; 
}

/*******************************************************
 * Init and factory routines
 *******************************************************/ 

static inline VXIrecImpl * ToVXIrecImpl(VXIrecInterface * i)
{ return reinterpret_cast<VXIrecImpl *>(i); }

// Global init - Don't need to do much here
//
VXIREC_API VXIrecResult VXIrecInit(VXIlogInterface *log,
				   VXIunsigned      diagLogBase,
				   VXIMap           *args)
{
  if (!log) return VXIrec_RESULT_INVALID_ARGUMENT;
  gblDiagLogBase = diagLogBase;
  const wchar_t* fnname = L"VXIrecInit";
  LogBlock logger(log, gblDiagLogBase, fnname, VXIREC_MODULE);

  logger = VXIrecData::Initialize(log, diagLogBase);
  return VXIrec_RESULT_SUCCESS;
}

// Global shutdown
//
VXIREC_API VXIrecResult VXIrecShutDown(VXIlogInterface *log)
{
  if (!log) return VXIrec_RESULT_INVALID_ARGUMENT;
  const wchar_t* fnname = L"VXIrecShutDown";
  LogBlock logger(log, gblDiagLogBase, fnname, VXIREC_MODULE);
  logger = VXIrecData::ShutDown();
  return VXIrec_RESULT_SUCCESS;
}

// Create an VXIrecInterface object and return.
//
VXIREC_API VXIrecResult VXIrecCreateResource(VXIlogInterface   *log,
					     VXIinetInterface  *inet,
  					   VXIcacheInterface *cache,
	  				   VXIpromptInterface *prompt,
		  			   VXItelInterface *tel,
					     VXIrecInterface  **rec)
{
  if (!log) return VXIrec_RESULT_INVALID_ARGUMENT;
  const wchar_t* fnname = L"VXIrecCreateResource";
  LogBlock logger(log, gblDiagLogBase, fnname, VXIREC_MODULE);

  VXIrecImpl* pp = new VXIrecImpl();
  if (pp == NULL) {
    logger = VXIrec_RESULT_OUT_OF_MEMORY;
    return VXIrec_RESULT_OUT_OF_MEMORY;
  }

  VXIrecData* tp = new VXIrecData(log, inet);
  if (tp == NULL) {
    logger = VXIrec_RESULT_OUT_OF_MEMORY;
    return VXIrec_RESULT_OUT_OF_MEMORY;
  }
  
  pp->recData = tp;
  pp->intf.GetVersion = VXIrecGetVersion;
  pp->intf.GetImplementationName = VXIrecGetImplementationName;
  pp->intf.BeginSession = VXIrecBeginSession;
  pp->intf.EndSession = VXIrecEndSession;
  pp->intf.LoadGrammarURI = VXIrecLoadGrammarFromURI;  
  pp->intf.LoadGrammarString = VXIrecLoadGrammarFromString;
  pp->intf.LoadGrammarOption = VXIrecLoadGrammarOption;
  pp->intf.ActivateGrammar = VXIrecActivateGrammar;
  pp->intf.DeactivateGrammar = VXIrecDeactivateGrammar;
  pp->intf.FreeGrammar = VXIrecFreeGrammar;
  pp->intf.Recognize = VXIrecRecognize;
  pp->intf.Record = VXIrecRecord;
  pp->intf.HotwordTransfer = VXIrecHotwordTransfer;
  pp->intf.SupportsHotwordTransfer = VXIrecSupportsHotwordTransfer;
  pp->intf.GetMatchedGrammar = VXIrecGetMatchedGrammar;

  *rec = &pp->intf;
  return VXIrec_RESULT_SUCCESS;
}


// Free VXIrec structure allocated in VXIrecCreateResource.
//
VXIREC_API VXIrecResult VXIrecDestroyResource(VXIrecInterface **rec)
{
  if (rec == NULL || *rec == NULL) return VXIrec_RESULT_INVALID_ARGUMENT;
  VXIrecImpl* recImpl = reinterpret_cast<VXIrecImpl*>(*rec);

  VXIrecData * tp = recImpl->recData;
  if ( tp ) {
    const wchar_t* fnname = L"VXIrecDestroyResource";
    LogBlock logger(tp->GetLog(), gblDiagLogBase, fnname, VXIREC_MODULE);
    delete tp;
  }
  
  delete recImpl;
  *rec = NULL;

  return VXIrec_RESULT_SUCCESS;
}

⌨️ 快捷键说明

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