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

📄 vxirec.cpp

📁 openvxi3.4是一个voicexml对话脚本语言的解释器源码.可用VC6.0编译.
💻 CPP
📖 第 1 页 / 共 2 页
字号:

/****************License************************************************
 * Vocalocity OpenVXI
 * Copyright (C) 2004-2005 by Vocalocity, Inc. All Rights Reserved.
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *  
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 * Vocalocity, the Vocalocity logo, and VocalOS are trademarks or 
 * registered trademarks of Vocalocity, Inc. 
 * OpenVXI is a trademark of Scansoft, Inc. and used under license 
 * by Vocalocity.
 ***********************************************************************/

#define VXIREC_EXPORTS
#include "VXIrecAPI.h"
#include "VXIrec_utils.h"
#include "LogBlock.hpp"

#include <cstdio>
#include <cstring>
#include <sstream>

// ------*---------*---------*---------*---------*---------*---------*---------

static void ResultContentDestroy(VXIbyte **content, void *userData)
{
  if (content && *content)
    delete [] *content;
  *content = NULL;
}

class VXIVectorHolder {
public:
  VXIVectorHolder() : _vector(NULL)  { _vector = VXIVectorCreate(); }
  VXIVectorHolder(VXIVector * m) : _vector(m) { }
  ~VXIVectorHolder()        { if (_vector != NULL) VXIVectorDestroy(&_vector);}

  VXIVectorHolder & operator=(const VXIVectorHolder & x)
  { if (this != &x) {
      if (_vector != NULL) VXIVectorDestroy(&_vector);
      _vector = VXIVectorClone(x._vector); }
    return *this; }

  // GetValue returns the internal vector.  The standard vector manipulation
  // functions may then be used.

  VXIVector * GetValue() const       { return _vector; }

  // These functions allow the holder to take ownership of an existing vector
  // or to release the internal one.

  VXIVector * Release()  
  { VXIVector * m = _vector; _vector = NULL; return m; }

  void Acquire(VXIVector * m)
  { if (_vector != NULL) VXIVectorDestroy(&_vector); else _vector = m; }

private:
  VXIVectorHolder(const VXIVectorHolder &);   // intentionally not defined.

  VXIVector * _vector;
};

// ------*---------*---------*---------*---------*---------*---------*---------

// Global for the base diagnostic tag ID, see osbrec_utils.h for tags
//
static VXIunsigned gblDiagLogBase = 0;


// VXIrec implementation of the VXIrec interface
//
extern "C" {
  struct VXIrecImpl {
    // Base interface, must be first
    VXIrecInterface intf;

    // Class for managing grammars
    VXIrecData *recData;
  };
}


// A few conversion functions...

static inline VXIrecGrammar * ToVXIrecGrammar(VXIrecGrammar * i)
{ return reinterpret_cast<VXIrecGrammar *>(i); }

static inline VXIrecGrammar * FromVXIrecGrammar(VXIrecGrammar * i)
{ return reinterpret_cast<VXIrecGrammar *>(i); }

static inline VXIrecData * GetRecData(VXIrecInterface * i)
{
  if (i == NULL) return NULL;
  return reinterpret_cast<VXIrecImpl *>(i)->recData;
}

/*******************************************************
 * Method routines for VXIrecInterface structure
 *******************************************************/ 

// Get the VXIrec interface version supported
//
static VXIint32 VXIrecGetVersion(void)
{
  return VXI_CURRENT_VERSION;
}


// Get the implementation name
//
static const VXIchar* VXIrecGetImplementationName(void)
{
  static const VXIchar IMPLEMENTATION_NAME[] = COMPANY_DOMAIN L".VXIrec";
  return IMPLEMENTATION_NAME;
}

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


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

  tp->Clear();
  return VXIrec_RESULT_SUCCESS;
}


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

  // Check the arguments
  if (str == NULL) {
    logger = VXIrec_RESULT_INVALID_ARGUMENT;
    return VXIrec_RESULT_INVALID_ARGUMENT;
  }
  if (type == NULL) {
    logger = VXIrec_RESULT_UNSUPPORTED;
    return VXIrec_RESULT_UNSUPPORTED;
  }
  
  VXIrecGrammar * gp = NULL;
  vxistring srgsGram, mtype(type);
  
  logger.logDiag(DIAG_TAG_GRAMMARS, L"%s%s", L"TYPE: ", mtype.c_str());
  tp->ShowPropertyValue(prop);
  
  if( mtype == L"application/x-jsgf" || mtype == REC_MIME_CHOICE || mtype == REC_MIME_CHOICE_DTMF)
  {
    // first crack the srgs grammar
    JSGFInfo info;
    tp->ConvertJSGFType(str, info);
    // then try to convert to SRGS format 
    if( !tp->JSGFToSRGS(info.contentStr, srgsGram, prop) ) return  VXIrec_RESULT_FAILURE;
    mtype = VXI_MIME_SRGS; // reset mime type
    logger.logDiag(DIAG_TAG_GRAMMARS, L"%s%s", L"Converted GRAMMAR: ", srgsGram.c_str());   
  }
  else if( mtype == VXI_MIME_SRGS ) {
    // processing below  
    srgsGram = str;
  }
  else {
    // Handle your own type here, return unsupported for now
    logger = VXIrec_RESULT_UNSUPPORTED;
    return VXIrec_RESULT_UNSUPPORTED;
  }
  
  // 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, prop);
  if( gramPtr == NULL ) return VXIrec_RESULT_FAILURE;
  tp->AddGrammar(gramPtr);
  *gram = ToVXIrecGrammar(gramPtr);
  return VXIrec_RESULT_SUCCESS;
}

static VXIrecResult VXIrecLoadGrammarFromURI(struct VXIrecInterface *pThis,
                                             const VXIMap *properties,
                                             const VXIchar *type, 
                                             const VXIchar *uri,
                                             const VXIMap *uriArgs,
                                             VXIrecGrammar **gram)
{
  VXIrecData* tp = GetRecData(pThis);
  if (tp == NULL) return VXIrec_RESULT_INVALID_ARGUMENT;
  const wchar_t* fnname = L"VXIrecLoadGrammarFromURI";
  LogBlock logger(tp->GetLog(), gblDiagLogBase, fnname, VXIREC_MODULE);
  tp->ShowPropertyValue(properties);

  if (wcsncmp(uri, L"builtin", 7) == 0 ){
    logger.logDiag(DIAG_TAG_GRAMMARS, L"%s", L"built-in not supported");
    return VXIrec_RESULT_UNSUPPORTED;
  }

  VXIbyte *buffer = NULL;
  VXIulong read = 0;
  if (!tp->FetchContent(uri, uriArgs, &buffer, read))
    return VXIrec_RESULT_FAILURE;

  // NOTE:  this code assumes the retieved buffer is
  // composed of single byte chars.  in the real world,
  // that can't be assumed.
  buffer[read] = 0;
  VXIchar *charbuff = new VXIchar[read+1];
  mbstowcs(charbuff, (char*)buffer, read+1);

  VXIrecResult rc = VXIrecLoadGrammarFromString(pThis, properties,
    type, charbuff, gram);

  delete[] buffer;
  delete[] charbuff;

  return rc;
}


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";
  // 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;
  }

  tp->ShowPropertyValue(properties);
  
  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;
}

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

  // If the grammar pointer is null, there is nothing to free.
  if (gram == NULL || *gram == NULL) VXIrec_RESULT_SUCCESS;

  tp->FreeGrammar(FromVXIrecGrammar(*gram));
  *gram = NULL;
  return VXIrec_RESULT_SUCCESS;
}


static VXIrecResult VXIrecActivateGrammar(VXIrecInterface *pThis,
                                          const VXIMap *properties,
                                          VXIrecGrammar *gram)
{
  const wchar_t* fnname = L"VXIrecActivateGrammar";
  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;
  }

  tp->ActivateGrammar(FromVXIrecGrammar(gram));
  return VXIrec_RESULT_SUCCESS;
}


static VXIrecResult VXIrecDeactivateGrammar(VXIrecInterface *pThis,
                                            VXIrecGrammar *gram)
{
  const wchar_t* fnname = L"VXIrecDeactivateGrammar";
  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;
  }

  tp->DeactivateGrammar(FromVXIrecGrammar(gram));
  return VXIrec_RESULT_SUCCESS;
}

/*******************************************************
 * Recognize related
 *******************************************************/ 

static void RecognitionResultDestroy(VXIrecRecognitionResult **Result)
{
  if (Result == NULL || *Result == NULL) return;

  VXIrecRecognitionResult * result = *Result;

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

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

  if (result->markname != NULL)
    VXIStringDestroy(&result->markname);

  delete result;
  *Result = NULL;
}

static void TransferResultDestroy(VXIrecTransferResult **Result)
{
  if (Result == NULL || *Result == NULL) return;

  VXIrecTransferResult * result = *Result;

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

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

  if (result->markname != NULL)
    VXIStringDestroy(&result->markname);

  delete result;
  *Result = NULL;
}

static const unsigned int NLSML_NOINPUT_SIZE = 109;
static const VXIchar NLSML_NOINPUT[NLSML_NOINPUT_SIZE] =
  L"<?xml version='1.0'?>"
  L"<result>"
    L"<interpretation>"
      L"<instance/>"
      L"<input><noinput/></input>"
    L"</interpretation>"
  L"</result>\0";

static const unsigned int NLSML_NOMATCH_SIZE = 109;
static const VXIchar NLSML_NOMATCH[NLSML_NOMATCH_SIZE] =
  L"<?xml version='1.0'?>"
  L"<result>"
    L"<interpretation>"
      L"<instance/>"
      L"<input><nomatch/></input>"
    L"</interpretation>"
  L"</result>\0";

void DestroyNLSMLBuffer(VXIbyte ** buffer, void * ok)
{
  // Return immediate if we know the buffer is static memory, 
  // i.e: noinput, nomatch as defined above
  if (ok == NULL || buffer == NULL) return;
  // otherwise reclaim the memory
  delete[] (*buffer);
  *buffer = NULL;
}


static VXIrecResult VXIrecRecognize(VXIrecInterface *pThis,
                                    const VXIMap *properties,
                                    VXIrecRecognitionResult **recogResult)
{
  const wchar_t* fnname = L"VXIrecRecognize";
  VXIrecData* tp = GetRecData(pThis);
  if (tp == NULL) return VXIrec_RESULT_INVALID_ARGUMENT;
  LogBlock logger(tp->GetLog(), gblDiagLogBase, fnname, VXIREC_MODULE);

  VXIchar* input = NULL;
  VXIMap*  res  = NULL;
  VXIchar* str  = NULL;
  VXIchar console[512];
  bool recordUtterance = false;
  bool haveUtterance = true;
    
  if (properties != NULL) {
    const VXIValue * ru = VXIMapGetProperty(properties, REC_RECORDUTTERANCE);
    if (ru)
      recordUtterance = wcscmp(VXIStringCStr((const VXIString*)ru), L"true") == 0;

    const VXIValue * val = VXIMapGetProperty(properties, L"SpeechInput");
    if( val ) {
       logger.logDiag(DIAG_TAG_RECOGNITION, L"%s%s", L"SpeechInput: ",
                      VXIStringCStr((const VXIString*)val));
    }
    if (val == NULL || VXIValueGetType(val) != VALUE_STRING) {
      val = VXIMapGetProperty(properties, L"DTMFInput");
      if( val ) {

⌨️ 快捷键说明

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