Browse Source

新增科大讯飞离线命令词识别示例代码

corvin 5 years ago
parent
commit
019eaf45b8
27 changed files with 3322 additions and 0 deletions
  1. 40 0
      example/xf_aitalk/README
  2. 20 0
      example/xf_aitalk/bin/call.bnf
  3. 9 0
      example/xf_aitalk/bin/control.bnf
  4. 17 0
      example/xf_aitalk/bin/msc/msc.cfg
  5. BIN
      example/xf_aitalk/bin/msc/res/asr/common.jet
  6. BIN
      example/xf_aitalk/bin/wav/ddhgdw.pcm
  7. BIN
      example/xf_aitalk/bin/wav/ddhghlj.pcm
  8. BIN
      example/xf_aitalk/doc/BNF Grammar Development Manual.pdf
  9. 2 0
      example/xf_aitalk/doc/readme.txt
  10. 282 0
      example/xf_aitalk/include/msp_cmn.h
  11. 563 0
      example/xf_aitalk/include/msp_errors.h
  12. 123 0
      example/xf_aitalk/include/msp_types.h
  13. 203 0
      example/xf_aitalk/include/qisr.h
  14. 0 0
      example/xf_aitalk/libs/.gitkeep
  15. 2 0
      example/xf_aitalk/release.txt
  16. 28 0
      example/xf_aitalk/samples/asr_offline_record_sample/Makefile
  17. 342 0
      example/xf_aitalk/samples/asr_offline_record_sample/asr_offline_record_sample.c
  18. 17 0
      example/xf_aitalk/samples/asr_offline_record_sample/formats.h
  19. 707 0
      example/xf_aitalk/samples/asr_offline_record_sample/linuxrec.c
  20. 156 0
      example/xf_aitalk/samples/asr_offline_record_sample/linuxrec.h
  21. 4 0
      example/xf_aitalk/samples/asr_offline_record_sample/make.sh
  22. 374 0
      example/xf_aitalk/samples/asr_offline_record_sample/speech_recognizer.c
  23. 63 0
      example/xf_aitalk/samples/asr_offline_record_sample/speech_recognizer.h
  24. 4 0
      example/xf_aitalk/samples/asr_offline_sample/32bit_make.sh
  25. 4 0
      example/xf_aitalk/samples/asr_offline_sample/64bit_make.sh
  26. 32 0
      example/xf_aitalk/samples/asr_offline_sample/Makefile
  27. 330 0
      example/xf_aitalk/samples/asr_offline_sample/asr_offline_sample.c

+ 40 - 0
example/xf_aitalk/README

@@ -0,0 +1,40 @@
+README for Linux_aitalk
+-----------------------
+
+bin:
+|-- msc
+    |-- msc.cfg(作用:msc调试、生成msc日志)
+	|-- res
+		|-- asr(资源文件)
+	|-- wav
+		|-- ddhghlj.pcm
+		|-- ddhgdw.pcm
+	|-- call.bnf
+		
+doc:
+|-- readme.txt
+
+include:调用SDK所需头文件
+
+libs:
+|-- x86
+	|-- libmsc.so(32位动态库)
+|-- x64
+	|-- libmsc.so(64位动态库)
+
+samples:
+|-- asr_sample
+	|-- asr_sample.c
+	|-- Makefile
+	|-- 32bit_make.sh
+	|-- 64bit_make.sh
+|-- asr_record_sample
+	|-- formats.h
+	|-- linuxrec.h
+	|-- linuxrec.c
+	|-- speech_recognizer.h
+	|-- speech_recognizer.c
+	|-- asr_record_sample.c
+	|-- Makefile
+	|-- 32bit_make.sh
+	|-- 64bit_make.sh	

+ 20 - 0
example/xf_aitalk/bin/call.bnf

@@ -0,0 +1,20 @@
+#BNF+IAT 1.0 UTF-8;
+!grammar call;
+!slot <want>;
+!slot <dialpre>;
+!slot <dialsuf>;
+!slot <contact>;
+
+!start <callstart>;
+<callstart>:[<want>]<dial>;
+<want>:我想|我要|请|帮我|我想要|请帮我;
+<dial>:<dialpre><contact>[<dialsuf>];
+<dialpre>:打电话给!id(10001)|打给!id(10001)|拨打!id(10001)|拨打电话给!id(10001)|呼叫!id(10001)|
+打一个电话给!id(10001)|打个电话给!id(10001)|给|拨通!id(10001)|
+接通!id(10001)|呼叫!id(10001)|呼叫给!id(10001)|打!id(10001);
+<dialsuf>:打电话!id(10001)|打个电话!id(10001)|打一个电话!id(10001)|
+拨打电话!id(10001)|拨电话!id(10001)|拨个电话!id(10001)|呼个电话!id(10001)|
+的电话!id(10001)|的号码!id(10001)|的手机!id(10001)|
+的办公电话!id(10001)|的移动号码!id(10001)|的联通号码!id(10001)|
+的电信号码!id(10001)|客服电话!id(10001);
+<contact>:丁伟;

+ 9 - 0
example/xf_aitalk/bin/control.bnf

@@ -0,0 +1,9 @@
+#BNF+IAT 1.0 UTF-8;
+!grammar control;
+!slot <devices>;
+!slot <operate>;
+
+!start <cmdstart>;
+<cmdstart>:<operate><devices>;
+<operate>:打开!id(1)|关闭!id(2);
+<devices>:灯!id(3)|风扇!id(4);

+ 17 - 0
example/xf_aitalk/bin/msc/msc.cfg

@@ -0,0 +1,17 @@
+## Copyright (C) 2010-2015 iFLYTEK.
+## Use ';' and '#' character for notation
+## Note: Commands in this cfg file is case sensitive
+
+[logger]
+##如果用户指定的日志文件路径无效,那么MSC在运行中将不会记录日志信息
+file                             = msc.log
+title                            = Mobile Speech Client
+level                            = -1
+output                           = 1
+filter                           = -1
+style                            = -1
+flush                            = 0
+maxsize                          =
+overwrite                        = 1
+maxfile                          =
+cache                            =

BIN
example/xf_aitalk/bin/msc/res/asr/common.jet


BIN
example/xf_aitalk/bin/wav/ddhgdw.pcm


BIN
example/xf_aitalk/bin/wav/ddhghlj.pcm


BIN
example/xf_aitalk/doc/BNF Grammar Development Manual.pdf


+ 2 - 0
example/xf_aitalk/doc/readme.txt

@@ -0,0 +1,2 @@
+开发指南文档请参考:http://doc.xfyun.cn/msc_windows
+API接口文档请参考:http://mscdoc.xfyun.cn/windows/api

+ 282 - 0
example/xf_aitalk/include/msp_cmn.h

@@ -0,0 +1,282 @@
+/**
+ * @file    msp_cmn.h
+ * @brief   Mobile Speech Platform Common Interface Header File
+ * 
+ *  This file contains the quick common programming interface (API) declarations 
+ *  of MSP. Developer can include this file in your project to build applications.
+ *  For more information, please read the developer guide.
+ 
+ *  Use of this software is subject to certain restrictions and limitations set
+ *  forth in a license agreement entered into between iFLYTEK, Co,LTD.
+ *  and the licensee of this software.  Please refer to the license
+ *  agreement for license use rights and restrictions.
+ *
+ *  Copyright (C)    1999 - 2012 by ANHUI USTC iFLYTEK, Co,LTD.
+ *                   All rights reserved.
+ * 
+ * @author  Speech Dept. iFLYTEK.
+ * @version 1.0
+ * @date    2012/09/01
+ * 
+ * @see        
+ * 
+ * History:
+ * index    version        date            author        notes
+ * 0        1.0            2012/09/01      MSC40        Create this file
+ */
+
+#ifndef __MSP_CMN_H__
+#define __MSP_CMN_H__
+
+#include "msp_types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+//#ifdef MSP_WCHAR_SUPPORT
+/** 
+ * @fn		Wchar2Mbytes
+ * @brief	wchar to mbytes
+ * 
+ *  User login.
+ * 
+ * @return	int MSPAPI				- Return 0 in success, otherwise return error code.
+ * @param	const wchar_t* wcstr	- [in] Null-terminated source string(wchar_t *).
+ * @param	char* mbstr				- [in] Destination string(char *).
+ * @param   int len					- [in] The maximum number of bytes that can be stored in the multibyte output string.
+ * @see		
+ */
+
+char *Wchar2Mbytes(const wchar_t* wcstr);
+
+/** 
+ * @fn		Mbytes2Wchar
+ * @brief	mbytes to wchar
+ * 
+ *  User login.
+ * 
+ * @return	int MSPAPI				- Return 0 in success, otherwise return error code.
+ * @param	const char* mbstr		- [in] Null-terminated source string(char *).
+ * @param	wchar_t* wcstr			- [in] Destination string(wchar_t *).
+ * @param   int wlen				- [in] The maximum number of multibyte characters to convert.
+ * @see		
+ */
+wchar_t *Mbytes2Wchar(const char *mbstr);
+
+//#endif /*MSP_WCHAR_SUPPORT*/
+
+/** 
+ * @fn		MSPLogin
+ * @brief	user login interface
+ * 
+ *  User login.
+ * 
+ * @return	int MSPAPI			- Return 0 in success, otherwise return error code.
+ * @param	const char* usr		- [in] user name.
+ * @param	const char* pwd		- [in] password.
+ * @param	const char* params	- [in] parameters when user login.
+ * @see		
+ */
+int MSPAPI MSPLogin(const char* usr, const char* pwd, const char* params);
+typedef int (MSPAPI *Proc_MSPLogin)(const char* usr, const char* pwd, const char* params);
+//#ifdef MSP_WCHAR_SUPPORT
+int MSPAPI MSPLoginW(const wchar_t* usr, const wchar_t* pwd, const wchar_t* params);
+typedef int (MSPAPI *Proc_MSPLoginW)(const wchar_t* usr, const wchar_t* pwd, const wchar_t* params);
+//#endif/*MSP_WCHAR_SUPPORT*/
+/** 
+ * @fn		MSPLogout
+ * @brief	user logout interface
+ * 
+ *  User logout
+ * 
+ * @return	int MSPAPI			- Return 0 in success, otherwise return error code.
+ * @see		
+ */
+int MSPAPI MSPLogout();
+typedef int (MSPAPI *Proc_MSPLogout)();
+//#ifdef MSP_WCHAR_SUPPORT
+int MSPAPI MSPLogoutW();
+typedef int (MSPAPI *Proc_MSPLogoutW)();
+//#endif/*MSP_WCHAR_SUPPORT*/
+/** 
+ * @fn		MSPUpload
+ * @brief	Upload User Specific Data
+ * 
+ *  Upload data such as user config, custom grammar, etc.
+ * 
+ * @return	int MSPAPI				- Return 0 in success, otherwise return error code.
+ * @param	const char* dataName	- [in] data name, should be unique to diff other data.
+ * @param	const char* params		- [in] parameters about uploading data.
+ * @param	const char* dataID		- [in] id of the data to be operated.
+ * @see		
+ */
+int MSPAPI MSPUpload( const char* dataName, const char* params, const char* dataID);
+typedef int (MSPAPI* Proc_MSPUpload)( const char* dataName, const char* params, const char* dataID);
+
+/** 
+ * @fn		MSPDownload
+ * @brief	Download User Specific Data
+ * 
+ *  Download data such as user config, etc.
+ * 
+ * @return	int MSPAPI				- Return 0 in success, otherwise return error code.
+ * @param	const char* params		- [in] parameters about data to be downloaded.
+ * @see		
+ */
+typedef int (*DownloadStatusCB)(int errorCode, long param1, const void *param2, void *userData);
+typedef int (*DownloadResultCB)(const void *data, long dataLen, void *userData);
+int MSPAPI MSPDownload(const char* dataName, const char* params, DownloadStatusCB statusCb, DownloadResultCB resultCb, void*userData);
+typedef int (MSPAPI* Proc_MSPDownload)(const char* dataName, const char* params, DownloadStatusCB statusCb, DownloadResultCB resultCb, void*userData);
+int MSPAPI MSPDownloadW(const wchar_t* wdataName, const wchar_t* wparams, DownloadStatusCB statusCb, DownloadResultCB resultCb, void*userData);
+typedef int (MSPAPI* Proc_MSPDownloadW) (const wchar_t* wdataName, const wchar_t* wparams, DownloadStatusCB statusCb, DownloadResultCB resultCb, void*userData);
+
+/** 
+ * @fn		MSPAppendData
+ * @brief	Append Data.
+ * 
+ *  Write data to msc, such as data to be uploaded, searching text, etc.
+ * 
+ * @return	int MSPAPI					- Return 0 in success, otherwise return error code.
+ * @param	void* data					- [in] the data buffer pointer, data could be binary.
+ * @param	unsigned int dataLen		- [in] length of data.
+ * @param	unsigned int dataStatus		- [in] data status, 2: first or continuous, 4: last.
+ * @see		
+ */
+int MSPAPI MSPAppendData(void* data, unsigned int dataLen, unsigned int dataStatus);
+typedef int (MSPAPI* Proc_MSPAppendData)(void* data, unsigned int dataLen, unsigned int dataStatus);
+
+/** 
+ * @fn		MSPGetResult
+ * @brief	Get Result
+ * 
+ *  Get result of uploading, downloading or searching, etc.
+ * 
+ * @return	const char* MSPAPI		- Return result of uploading, downloading or searching, etc.
+ * @param	int* rsltLen			- [out] Length of result returned.
+ * @param	int* rsltStatus			- [out] Status of result returned.
+ * @param	int* errorCode			- [out] Return 0 in success, otherwise return error code.
+ * @see		
+ */
+const char* MSPAPI MSPGetResult(unsigned int* rsltLen, int* rsltStatus, int *errorCode);
+typedef const char * (MSPAPI *Proc_MSPGetResult)(unsigned int* rsltLen, int* rsltStatus, int *errorCode);
+
+/** 
+ * @fn		MSPSetParam
+ * @brief	set params of msc
+ * 
+ *  set param of msc
+ * 
+ * @return	int	- Return 0 if success, otherwise return errcode.
+ * @param	const char* paramName	- [in] param name.
+ * @param	const char* paramValue	- [in] param value
+ * @see		
+ */
+int MSPAPI MSPSetParam( const char* paramName, const char* paramValue );
+typedef int (MSPAPI *Proc_MSPSetParam)(const char* paramName, const char* paramValue);
+
+/** 
+ * @fn		MSPGetParam
+ * @brief	get params of msc
+ * 
+ *  get param of msc
+ * 
+ * @return	int	- Return 0 if success, otherwise return errcode.
+ * @param	const char* paramName	- [in] param name.
+ * @param	const char* paramValue	- [out] param value
+ * @param	const char* valueLen	- [in/out] param value (buffer) length
+ * @see		
+ */
+int MSPAPI MSPGetParam( const char *paramName, char *paramValue, unsigned int *valueLen );
+typedef int (MSPAPI *Proc_MSPGetParam)( const char *paramName, char *paramValue, unsigned int *valueLen );
+
+/** 
+ * @fn		MSPUploadData
+ * @brief	Upload User Specific Data
+ * 
+ *  Upload data such as user config, custom grammar, etc.
+ * 
+ * @return	const char* MSPAPI		- data id returned by Server, used for special command.
+ * @param	const char* dataName	- [in] data name, should be unique to diff other data.
+ * @param	void* data				- [in] the data buffer pointer, data could be binary.
+ * @param	unsigned int dataLen	- [in] length of data.
+ * @param	const char* params		- [in] parameters about uploading data.
+ * @param	int* errorCode			- [out] Return 0 in success, otherwise return error code.
+ * @see		
+ */
+const char* MSPAPI MSPUploadData(const char* dataName, void* data, unsigned int dataLen, const char* params, int* errorCode);
+typedef const char* (MSPAPI* Proc_MSPUploadData)(const char* dataName, void* data, unsigned int dataLen, const char* params, int* errorCode);
+
+/** 
+ * @fn		MSPDownloadData
+ * @brief	Download User Specific Data
+ * 
+ *  Download data such as user config, etc.
+ * 
+ * @return	const void*	MSPAPI		- received data buffer pointer, data could be binary, NULL if failed or data does not exsit.
+ * @param	const char* params		- [in] parameters about data to be downloaded.
+ * @param	unsigned int* dataLen	- [out] length of received data.
+ * @param	int* errorCode			- [out] Return 0 in success, otherwise return error code.
+ * @see		
+ */
+const void* MSPAPI MSPDownloadData(const char* params, unsigned int* dataLen, int* errorCode);
+typedef const void* (MSPAPI* Proc_MSPDownloadData)(const char* params, unsigned int* dataLen, int* errorCode);
+//#ifdef MSP_WCHAR_SUPPORT
+const void* MSPAPI MSPDownloadDataW(const wchar_t* params, unsigned int* dataLen, int* errorCode);
+typedef const void* (MSPAPI* Proc_MSPDownloadDataW)(const wchar_t* params, unsigned int* dataLen, int* errorCode);
+//#endif/*MSP_WCHAR_SUPPORT*/
+/** 
+ * @fn		MSPSearch
+ * @brief	Search text for result
+ * 
+ *  Search text content, and got text result
+ * 
+ * @return	const void*	MSPAPI		- received data buffer pointer, data could be binary, NULL if failed or data does not exsit.
+ * @param	const char* params		- [in] parameters about data to be downloaded.
+ * @param	unsigned int* dataLen	- [out] length of received data.
+ * @param	int* errorCode			- [out] Return 0 in success, otherwise return error code.
+ * @see		
+ */
+const char* MSPAPI MSPSearch(const char* params, const char* text, unsigned int* dataLen, int* errorCode);
+typedef const char* (MSPAPI* Proc_MSPSearch)(const char* params, const char* text, unsigned int* dataLen, int* errorCode);
+
+
+
+typedef int (*NLPSearchCB)(const char *sessionID, int errorCode, int status, const void* result, long rsltLen, void *userData);
+const char* MSPAPI MSPNlpSearch(const char* params, const char* text, unsigned int textLen, int *errorCode, NLPSearchCB callback, void *userData);
+typedef const char* (MSPAPI* Proc_MSPNlpSearch)(const char* params, const char* text, unsigned int textLen, int *errorCode, NLPSearchCB callback, void *userData);
+int MSPAPI MSPNlpSchCancel(const char *sessionID, const char *hints);
+
+/** 
+ * @fn		MSPRegisterNotify
+ * @brief	Register a Callback
+ * 
+ *  Register a Callback
+ * 
+ * @return	int                     -
+ * @param	msp_status_ntf_handler statusCb		- [in] notify handler
+ * @param	void *userData                   	- [in] userData
+ * @see		
+ */
+typedef void ( *msp_status_ntf_handler)( int type, int status, int param1, const void *param2, void *userData );
+int MSPAPI MSPRegisterNotify( msp_status_ntf_handler statusCb, void *userData );
+typedef const char* (MSPAPI* Proc_MSPRegisterNotify)( msp_status_ntf_handler statusCb, void *userData );
+
+/**
+ * @fn		MSPGetVersion
+ * @brief	Get version of MSC or Local Engine
+ *
+ * Get version of MSC or Local Engine
+ * 
+ * @return	const char * MSPAPI		- Return version value if success, NULL if fail.
+ * @param	const char *verName		- [in] version name, could be "msc", "aitalk", "aisound", "ivw".
+ * @param	int *errorCode			- [out] Return 0 in success, otherwise return error code.
+ * @see
+ */
+const char* MSPAPI MSPGetVersion(const char *verName, int *errorCode);
+typedef const char* (MSPAPI * Proc_MSPGetVersion)(const char *verName, int *errorCode);
+
+#ifdef __cplusplus
+} /* extern "C" */	
+#endif /* C++ */
+
+#endif /* __MSP_CMN_H__ */

+ 563 - 0
example/xf_aitalk/include/msp_errors.h

@@ -0,0 +1,563 @@
+#ifndef __MSP_ERRORS_H__
+#define __MSP_ERRORS_H__
+
+#define MSP_HTTP_ERROR(x) ((x) + MSP_ERROR_HTTP_BASE )
+
+enum
+{
+	MSP_SUCCESS								= 0,
+	MSP_ERROR_FAIL							= -1,
+	MSP_ERROR_EXCEPTION						= -2,
+
+	/* General errors 10100(0x2774) */
+	MSP_ERROR_GENERAL						= 10100, 	/* 0x2774 */
+	MSP_ERROR_OUT_OF_MEMORY					= 10101, 	/* 0x2775 */
+	MSP_ERROR_FILE_NOT_FOUND				= 10102, 	/* 0x2776 */
+	MSP_ERROR_NOT_SUPPORT					= 10103, 	/* 0x2777 */
+	MSP_ERROR_NOT_IMPLEMENT					= 10104, 	/* 0x2778 */
+	MSP_ERROR_ACCESS						= 10105, 	/* 0x2779 */
+	MSP_ERROR_INVALID_PARA					= 10106, 	/* 0x277A */  /* 缺少参数 */
+	MSP_ERROR_INVALID_PARA_VALUE			= 10107, 	/* 0x277B */  /* 无效参数值 */
+	MSP_ERROR_INVALID_HANDLE				= 10108, 	/* 0x277C */
+	MSP_ERROR_INVALID_DATA					= 10109, 	/* 0x277D */
+	MSP_ERROR_NO_LICENSE					= 10110, 	/* 0x277E */  /* 引擎授权不足 */
+	MSP_ERROR_NOT_INIT						= 10111, 	/* 0x277F */  /* 引擎未初始化,可能是引擎崩溃 */
+	MSP_ERROR_NULL_HANDLE					= 10112, 	/* 0x2780 */
+    MSP_ERROR_OVERFLOW						= 10113, 	/* 0x2781 */  /* 单用户下模型数超上限(10个), */
+                                                                      /* 只出现在测试时对一个用户进行并发注册 */
+	MSP_ERROR_TIME_OUT						= 10114, 	/* 0x2782 */  /* 超时 */
+	MSP_ERROR_OPEN_FILE						= 10115, 	/* 0x2783 */
+	MSP_ERROR_NOT_FOUND						= 10116, 	/* 0x2784 */  /* 数据库中模型不存在 */
+	MSP_ERROR_NO_ENOUGH_BUFFER				= 10117, 	/* 0x2785 */
+	MSP_ERROR_NO_DATA						= 10118, 	/* 0x2786 */  /* 从客户端读音频或从引擎段获取结果时无数据 */
+	MSP_ERROR_NO_MORE_DATA					= 10119, 	/* 0x2787 */
+	MSP_ERROR_NO_RESPONSE_DATA				= 10120, 	/* 0x2788 */
+	MSP_ERROR_ALREADY_EXIST					= 10121, 	/* 0x2789 */  /* 数据库中模型已存在 */
+	MSP_ERROR_LOAD_MODULE					= 10122, 	/* 0x278A */
+	MSP_ERROR_BUSY							= 10123, 	/* 0x278B */
+	MSP_ERROR_INVALID_CONFIG				= 10124, 	/* 0x278C */
+	MSP_ERROR_VERSION_CHECK                 = 10125, 	/* 0x278D */
+	MSP_ERROR_CANCELED						= 10126, 	/* 0x278E */
+	MSP_ERROR_INVALID_MEDIA_TYPE			= 10127, 	/* 0x278F */
+	MSP_ERROR_CONFIG_INITIALIZE				= 10128, 	/* 0x2790 */
+	MSP_ERROR_CREATE_HANDLE					= 10129, 	/* 0x2791 */
+	MSP_ERROR_CODING_LIB_NOT_LOAD			= 10130, 	/* 0x2792 */
+	MSP_ERROR_USER_CANCELLED				= 10131, 	/* 0x2793 */
+	MSP_ERROR_INVALID_OPERATION				= 10132, 	/* 0x2794 */
+	MSP_ERROR_MESSAGE_NOT_COMPLETE			= 10133,	/* 0x2795 */   /* flash */
+	MSP_ERROR_NO_EID						= 10134,	/* 0x2795 */
+	MSP_ERROE_OVER_REQ                      = 10135,    /* 0x2797 */   /* client Redundancy request */
+	MSP_ERROR_USER_ACTIVE_ABORT             = 10136,    /* 0x2798 */   /* user abort */
+	MSP_ERROR_BUSY_GRMBUILDING              = 10137,    /* 0x2799 */
+	MSP_ERROR_BUSY_LEXUPDATING              = 10138,    /* 0x279A */
+	MSP_ERROR_SESSION_RESET	                = 10139,    /* 0x279B */   /* msc主动终止会话,准备重传 */
+	MSP_ERROR_BOS_TIMEOUT                   = 10140,    /* 0x279C */   /* VAD前端点超时 */
+	MSP_ERROR_STREAM_FILTER					= 10141,	/* 0X279D */   /* AIUI当前Stream被过滤 */
+	MSP_ERROR_STREAM_CLEAR				    = 10142,    /* 0X279E */   /* AIUI当前Stream被清理 */
+
+	/* Error codes of network 10200(0x27D8)*/
+	MSP_ERROR_NET_GENERAL					= 10200, 	/* 0x27D8 */
+	MSP_ERROR_NET_OPENSOCK         			= 10201, 	/* 0x27D9 */   /* Open socket */
+	MSP_ERROR_NET_CONNECTSOCK      			= 10202, 	/* 0x27DA */   /* Connect socket */
+	MSP_ERROR_NET_ACCEPTSOCK       			= 10203, 	/* 0x27DB */   /* Accept socket */
+	MSP_ERROR_NET_SENDSOCK         			= 10204, 	/* 0x27DC */   /* Send socket data */
+	MSP_ERROR_NET_RECVSOCK         			= 10205, 	/* 0x27DD */   /* Recv socket data */
+	MSP_ERROR_NET_INVALIDSOCK      			= 10206, 	/* 0x27DE */   /* Invalid socket handle */
+	MSP_ERROR_NET_BADADDRESS       			= 10207, 	/* 0x27EF */   /* Bad network address */
+	MSP_ERROR_NET_BINDSEQUENCE     			= 10208, 	/* 0x27E0 */   /* Bind after listen/connect */
+	MSP_ERROR_NET_NOTOPENSOCK      			= 10209, 	/* 0x27E1 */   /* Socket is not opened */
+	MSP_ERROR_NET_NOTBIND         			= 10210, 	/* 0x27E2 */   /* Socket is not bind to an address */
+	MSP_ERROR_NET_NOTLISTEN        			= 10211, 	/* 0x27E3 */   /* Socket is not listening */
+	MSP_ERROR_NET_CONNECTCLOSE     			= 10212, 	/* 0x27E4 */   /* The other side of connection is closed */
+	MSP_ERROR_NET_NOTDGRAMSOCK     			= 10213, 	/* 0x27E5 */   /* The socket is not datagram type */
+	MSP_ERROR_NET_DNS     					= 10214, 	/* 0x27E6 */   /* domain name is invalid or dns server does not function well */
+	MSP_ERROR_NET_INIT     					= 10215, 	/* 0x27E7 */   /* ssl ctx create failed */
+
+	/*nfl error*/
+	MSP_ERROR_NFL_INNER_ERROR               = 10216,    /* NFL inner error */
+	MSP_ERROR_MSS_TIME_OUT                  = 10217,    /* MSS TIMEOUT */
+	MSP_ERROT_CLIENT_TIME_OUT               = 10218,    /* CLIENT TIMEOUT */
+	MSP_ERROR_CLIENT_CLOSE                  = 10219,    /* CLIENT CLOSED CONNECTION */
+	
+	MSP_ERROR_CLIENT_AREA_CHANGE			= 10220,
+	MSP_ERROR_NET_SSL_HANDSHAKE				= 10221,
+	MSP_ERROR_NET_INVALID_ROOT_CERT			= 10222,
+	MSP_ERROR_NET_INVALID_CLIENT_CERT		= 10223,
+	MSP_ERROR_NET_INVALID_SERVER_CERT		= 10224,
+	MSP_ERROR_NET_INVALID_KEY				= 10225,
+	MSP_ERROR_NET_CERT_VERIFY_FAILED		= 10226,
+	MSP_ERROR_NET_WOULDBLOCK				= 10227,
+	MSP_ERROR_NET_NOTBLOCK					= 10228,
+	
+	/* Error codes of mssp message 10300(0x283C) */
+	MSP_ERROR_MSG_GENERAL					= 10300, 	/* 0x283C */
+	MSP_ERROR_MSG_PARSE_ERROR				= 10301, 	/* 0x283D */
+	MSP_ERROR_MSG_BUILD_ERROR				= 10302, 	/* 0x283E */
+	MSP_ERROR_MSG_PARAM_ERROR				= 10303, 	/* 0x283F */
+	MSP_ERROR_MSG_CONTENT_EMPTY				= 10304, 	/* 0x2840 */
+	MSP_ERROR_MSG_INVALID_CONTENT_TYPE		= 10305, 	/* 0x2841 */
+	MSP_ERROR_MSG_INVALID_CONTENT_LENGTH	= 10306, 	/* 0x2842 */
+	MSP_ERROR_MSG_INVALID_CONTENT_ENCODE	= 10307, 	/* 0x2843 */
+	MSP_ERROR_MSG_INVALID_KEY				= 10308, 	/* 0x2844 */
+	MSP_ERROR_MSG_KEY_EMPTY					= 10309, 	/* 0x2845 */
+	MSP_ERROR_MSG_SESSION_ID_EMPTY			= 10310, 	/* 0x2846 */   /* 会话ID为空 */
+	MSP_ERROR_MSG_LOGIN_ID_EMPTY			= 10311, 	/* 0x2847 */   /* 音频序列ID为空 */
+	MSP_ERROR_MSG_SYNC_ID_EMPTY				= 10312, 	/* 0x2848 */
+	MSP_ERROR_MSG_APP_ID_EMPTY				= 10313, 	/* 0x2849 */
+	MSP_ERROR_MSG_EXTERN_ID_EMPTY			= 10314, 	/* 0x284A */
+	MSP_ERROR_MSG_INVALID_CMD				= 10315, 	/* 0x284B */
+	MSP_ERROR_MSG_INVALID_SUBJECT			= 10316, 	/* 0x284C */
+	MSP_ERROR_MSG_INVALID_VERSION			= 10317, 	/* 0x284D */
+	MSP_ERROR_MSG_NO_CMD					= 10318, 	/* 0x284E */
+	MSP_ERROR_MSG_NO_SUBJECT				= 10319, 	/* 0x284F */
+	MSP_ERROR_MSG_NO_VERSION				= 10320, 	/* 0x2850 */
+	MSP_ERROR_MSG_MSSP_EMPTY				= 10321, 	/* 0x2851 */
+	MSP_ERROR_MSG_NEW_RESPONSE				= 10322, 	/* 0x2852 */
+	MSP_ERROR_MSG_NEW_CONTENT				= 10323, 	/* 0x2853 */
+	MSP_ERROR_MSG_INVALID_SESSION_ID		= 10324, 	/* 0x2854 */   /* 无效的会话ID(sid) */
+	MSP_ERROR_MSG_INVALID_CONTENT			= 10325, 	/* 0x2855 */
+
+	/* Error codes of DataBase 10400(0x28A0)*/
+	MSP_ERROR_DB_GENERAL					= 10400, 	/* 0x28A0 */   /* 数据库异常 */
+	MSP_ERROR_DB_EXCEPTION					= 10401, 	/* 0x28A1 */
+	MSP_ERROR_DB_NO_RESULT					= 10402, 	/* 0x28A2 */   /* redis中没有找到会话ID(sid) */
+	MSP_ERROR_DB_INVALID_USER				= 10403, 	/* 0x28A3 */
+	MSP_ERROR_DB_INVALID_PWD				= 10404, 	/* 0x28A4 */
+	MSP_ERROR_DB_CONNECT					= 10405, 	/* 0x28A5 */
+	MSP_ERROR_DB_INVALID_SQL				= 10406, 	/* 0x28A6 */
+	MSP_ERROR_DB_INVALID_APPID				= 10407,	/* 0x28A7 */
+	MSP_ERROR_DB_NO_UID						= 10408,
+
+	/* Error codes of Resource 10500(0x2904)*/
+	MSP_ERROR_RES_GENERAL					= 10500, 	/* 0x2904 */
+	MSP_ERROR_RES_LOAD          			= 10501, 	/* 0x2905 */   /* Load resource */
+	MSP_ERROR_RES_FREE          			= 10502, 	/* 0x2906 */   /* Free resource */
+	MSP_ERROR_RES_MISSING       			= 10503, 	/* 0x2907 */   /* Resource File Missing */
+	MSP_ERROR_RES_INVALID_NAME  			= 10504, 	/* 0x2908 */   /* Invalid resource file name */
+	MSP_ERROR_RES_INVALID_ID    			= 10505, 	/* 0x2909 */   /* Invalid resource ID */
+	MSP_ERROR_RES_INVALID_IMG   			= 10506, 	/* 0x290A */   /* Invalid resource image pointer */
+	MSP_ERROR_RES_WRITE         			= 10507, 	/* 0x290B */   /* Write read-only resource */
+	MSP_ERROR_RES_LEAK          			= 10508, 	/* 0x290C */   /* Resource leak out */
+	MSP_ERROR_RES_HEAD          			= 10509, 	/* 0x290D */   /* Resource head currupt */
+	MSP_ERROR_RES_DATA          			= 10510, 	/* 0x290E */   /* Resource data currupt */
+	MSP_ERROR_RES_SKIP          			= 10511, 	/* 0x290F */   /* Resource file skipped */
+
+	/* Error codes of TTS 10600(0x2968)*/
+	MSP_ERROR_TTS_GENERAL					= 10600, 	/* 0x2968 */
+	MSP_ERROR_TTS_TEXTEND          			= 10601, 	/* 0x2969 */  /* Meet text end */
+	MSP_ERROR_TTS_TEXT_EMPTY				= 10602, 	/* 0x296A */  /* no synth text */
+	MSP_ERROR_TTS_LTTS_ERROR				= 10603, 	/* 0x296B */
+
+	/* Error codes of Recognizer 10700(0x29CC) */
+	MSP_ERROR_REC_GENERAL					= 10700, 	/* 0x29CC */  /* 引擎异常 */
+	MSP_ERROR_REC_INACTIVE					= 10701, 	/* 0x29CD */
+	MSP_ERROR_REC_GRAMMAR_ERROR				= 10702, 	/* 0x29CE */
+	MSP_ERROR_REC_NO_ACTIVE_GRAMMARS		= 10703, 	/* 0x29CF */
+	MSP_ERROR_REC_DUPLICATE_GRAMMAR			= 10704, 	/* 0x29D0 */
+	MSP_ERROR_REC_INVALID_MEDIA_TYPE		= 10705, 	/* 0x29D1 */
+	MSP_ERROR_REC_INVALID_LANGUAGE			= 10706, 	/* 0x29D2 */
+	MSP_ERROR_REC_URI_NOT_FOUND				= 10707, 	/* 0x29D3 */
+	MSP_ERROR_REC_URI_TIMEOUT				= 10708, 	/* 0x29D4 */
+	MSP_ERROR_REC_URI_FETCH_ERROR			= 10709, 	/* 0x29D5 */
+	MSP_ERROR_REC_PROC_MOD					= 10710,	/* 0x29D6 */
+
+
+	/* Error codes of Speech Detector 10800(0x2A30) */
+	MSP_ERROR_EP_GENERAL					= 10800, 	/* 0x2A30 */
+	MSP_ERROR_EP_NO_SESSION_NAME            = 10801, 	/* 0x2A31 */
+	MSP_ERROR_EP_INACTIVE                   = 10802, 	/* 0x2A32 */
+	MSP_ERROR_EP_INITIALIZED                = 10803, 	/* 0x2A33 */
+
+	/* Error codes of TUV */  
+	MSP_ERROR_TUV_GENERAL					= 10900, 	/* 0x2A94 */
+	MSP_ERROR_TUV_GETHIDPARAM        		= 10901, 	/* 0x2A95 */   /* Get Busin Param huanid*/
+	MSP_ERROR_TUV_TOKEN      				= 10902, 	/* 0x2A96 */   /* Get Token */
+	MSP_ERROR_TUV_CFGFILE					= 10903, 	/* 0x2A97 */   /* Open cfg file */ 
+	MSP_ERROR_TUV_RECV_CONTENT              = 10904, 	/* 0x2A98 */   /* received content is error */
+	MSP_ERROR_TUV_VERFAIL      			    = 10905, 	/* 0x2A99 */   /* Verify failure */
+
+	/* Error codes of IMTV */
+	MSP_ERROR_LOGIN_SUCCESS					= 11000, 	/* 0x2AF8 */   /* 成功 */
+	MSP_ERROR_LOGIN_NO_LICENSE        	    = 11001, 	/* 0x2AF9 */   /* 试用次数结束,用户需要付费 */
+	MSP_ERROR_LOGIN_SESSIONID_INVALID		= 11002, 	/* 0x2AFA */   /* SessionId失效,需要重新登录通行证 */ 
+	MSP_ERROR_LOGIN_SESSIONID_ERROR			= 11003, 	/* 0x2AFB */   /* SessionId为空,或者非法 */
+	MSP_ERROR_LOGIN_UNLOGIN		  			= 11004, 	/* 0x2AFC */   /* 未登录通行证 */
+	MSP_ERROR_LOGIN_INVALID_USER	  		= 11005, 	/* 0x2AFD */   /* 用户ID无效 */
+	MSP_ERROR_LOGIN_INVALID_PWD		  		= 11006, 	/* 0x2AFE */   /* 用户密码无效 */
+	MSP_ERROR_LOGIN_SYSTEM_ERROR            = 11099, 	/* 0x2B5B */   /* 系统错误 */
+
+	/* Error codes of HCR */
+	MSP_ERROR_HCR_GENERAL					= 11100,
+	MSP_ERROR_HCR_RESOURCE_NOT_EXIST		= 11101,
+	MSP_ERROR_HCR_CREATE					= 11102,
+	MSP_ERROR_HCR_DESTROY					= 11103,
+	MSP_ERROR_HCR_START						= 11104,
+	MSP_ERROR_HCR_APPEND_STROKES			= 11105,
+	MSP_ERROR_HCR_INIT                      = 11106,
+	MSP_ERROR_HCR_POINT_DECODE              = 11107,
+	MSP_ERROR_HCR_DISPATCH                  = 11108,
+	MSP_ERROR_HCR_GETRESULT                 = 11109,
+	MSP_ERROR_HCR_RESOURCE		            = 11110,
+	
+	/* Error Codes using in local engine */
+	MSP_ERROR_AUTH_NO_LICENSE				= 11200,	/* 0x2BC0 */   /* 无授权 */
+	MSP_ERROR_AUTH_NO_ENOUGH_LICENSE		= 11201,	/* 0x2BC1 */   /* 授权不足 */
+	MSP_ERROR_AUTH_INVALID_LICENSE		    = 11202,	/* 0x2BC2 */   /* 无效的授权 */
+	MSP_ERROR_AUTH_LICENSE_EXPIRED			= 11203,	/* 0x2BC3 */   /* 授权过期 */
+	MSP_ERROR_AUTH_NEED_MORE_DATA           = 11204,    /* 0x2BC4 */   /* 无设备信息 */
+	MSP_ERROR_AUTH_LICENSE_TO_BE_EXPIRED	= 11205,	/* 0x2BC5 */   /* 授权即将过期,警告性错误码 */
+	MSP_ERROR_AUTH_INVALID_MACHINE_ID       = 11206,    /* 0x2BC6 */   /* 无效的机器码 */
+	MSP_ERROR_AUTH_LOCAL_ASR_FORBIDDEN 	    = 11207,    /* 0x2BC7 */   /* 禁止使用本地识别引擎 */
+	MSP_ERROR_AUTH_LOCAL_TTS_FORBIDDEN      = 11208,    /* 0x2BC8 */   /* 禁止使用本地合成引擎 */
+	MSP_ERROR_AUTH_LOCAL_IVW_FORBIDDEN      = 11209,    /* 0x2BC9 */   /* 禁止使用本地唤醒引擎 */
+	MSP_ERROR_AUTH_APPID_NOT_MATCH			= 11210,	/* 0x2BCA */   /* 资源appid和应用appid不匹配 */
+	MSP_ERROR_AUTH_UID_NOT_MATCH			= 11211,	/* 0x2BCB */   /* 资源uid和登录用户uid不匹配 */
+	MSP_ERROR_AUTH_TRIAL_EXPIRED			= 11212,	/* 0x2BCC */   /* 试用资源过期 */
+	MSP_ERROR_AUTH_LOCAL_IFD_FORBIDDEN      = 11213,    /* 0x2BC9 */   /* 禁止使用本地人脸引擎 */
+
+	MSP_ERROR_AIUI_NO_ENOUGH_LICENSE		= 11216,	/* 0x2BD0 */   /* AIUI授权不足 */
+	/*Error Codes of Authorization*/
+	MSP_ERROR_AUTH_DVC_NO_LICENSE				= 11300,
+	MSP_ERROR_AUTH_DVC_NO_ENOUGH_LICENSE		= 11301,
+	MSP_ERROR_AUTH_DVC_INVALID_LICENSE		    = 11302,
+	MSP_ERROR_AUTH_DVC_LICENSE_EXPIRED			= 11303,
+	MSP_ERROR_AUTH_DVC_NEED_MORE_DATA           = 11304,
+	MSP_ERROR_AUTH_DVC_LICENSE_TO_BE_EXPIRED	= 11305,
+	MSP_ERROR_AUTH_DVC_EXCEED_LICENSE			= 11306,				   
+
+	/* Error codes of Ise */
+     
+	MSP_ERROR_ASE_EXCEP_SILENCE  		        = 11401,             
+	MSP_ERROR_ASE_EXCEP_SNRATIO  		        = 11402,             
+	MSP_ERROR_ASE_EXCEP_PAPERDATA  	            = 11403,           
+	MSP_ERROR_ASE_EXCEP_PAPERCONTENTS 	        = 11404,        
+	MSP_ERROR_ASE_EXCEP_NOTMONO    	            = 11405,           
+	MSP_ERROR_ASE_EXCEP_OTHERS  		        = 11406,              
+	MSP_ERROR_ASE_EXCEP_PAPERFMT 		        = 11407,             
+	MSP_ERROR_ASE_EXCEP_ULISTWORD  	            = 11408,
+	
+	/* Error codes of Iot */
+	MSP_ERROR_IOT_BASE							= 11500,
+	MSP_ERROR_IOT_PARAM_ERROR					= 11501,		// param error
+	MSP_ERROR_IOT_INVALID_SERVICE				= 11502,		// invalid service for iot ProTranServer
+	MSP_ERROR_IOT_INVALID_PRODUCTID				= 11503,		// invalid productid for ProTranServer
+	MSP_EEROR_IOT_INVALID_ATTR					= 11504,		// invalid attr value for one product in ProTranServer
+	MSP_ERROR_IOT_INVALID_PLATFORM				= 11505,		// invalid platform for ProTranServer
+	MSP_ERROR_IOT_DID_NOT_FOUND					= 11506,		// not found device id in semantic
+
+    /* Error codes of IVP */
+    MSP_ERROR_IVP_GENERAL                   = 11600,            //  内核异常
+    MSP_ERROR_IVP_EXTRA_RGN_SOPPORT         = 11601,            //  注册时向引擎所写音频条数超过上限(9次)
+    MSP_ERROR_IVP_TRUNCATED                 = 11602,            //  音频截幅(因信号波形的幅度太大,而超出系统的线性范围),如记录尖叫声的音频
+    MSP_ERROR_IVP_MUCH_NOISE                = 11603,            //  音频信噪比过低
+    MSP_ERROR_IVP_TOO_LOW                   = 11604,            //  音频能量过低
+    MSP_ERROR_IVP_ZERO_AUDIO                = 11605,            //  无音频
+    MSP_ERROR_IVP_UTTER_TOO_SHORT           = 11606,            //  音频太短
+    MSP_ERROR_IVP_TEXT_NOT_MATCH            = 11607,            //  1.音频和文本不匹配,常见原因1.抢读(在按下录音键之前读)
+                                                                //  2.录音机的启动电流被录入表现在音频上是在音频首有冲击电流 3.确实不匹配"
+    MSP_ERROR_IVP_NO_ENOUGH_AUDIO           = 11608,            //  音频不够,注册自由说,而写入的音频又不够长时会报,告诉调用者继续传音频
+    MSP_ERROR_IVP_MODEL_NOT_FOUND_IN_HBASE  = 11610,            //  模型在hbase中没找到
+    
+    /* Error codes of Face */
+    
+	MSP_ERROR_IFR_NOT_FACE_IMAGE			= 11700,			//	【无人脸,对应的引擎错误码是20200 】      
+	MSP_ERROR_FACE_IMAGE_FULL_LEFT			= 11701,			//	【人脸向左,对应的引擎错误码是20201】
+	MSP_ERROR_FACE_IMAGE_FULL_RIGHT			= 11702,			//	【人脸向右,对应的引擎错误码是20202】
+	MSP_ERROR_IMAGE_CLOCKWISE_WHIRL			= 11703,			//	【顺时针旋转,对应的引擎错误码是20203】
+	MSP_ERROR_IMAGE_COUNTET_CLOCKWISE_WHIRL	= 11704,			//	【逆时针旋转,对应的引擎错误码是20204】
+	MSP_ERROR_VALID_IMAGE_SIZE				= 11705,			//	【图片大小异常 ,对应的引擎错误码是20205】
+	MSP_ERROR_ILLUMINATION					= 11706,			//	【光照异常,对应的引擎错误码是20206】
+	MSP_ERROR_FACE_OCCULTATION				= 11707,		    //	【人脸被遮挡,对应的引擎错误码是20207】
+	MSP_ERROR_FACE_INVALID_MODEL			= 11708,			//	【非法模型数据,对应的引擎错误码是20208】
+	MSP_ERROR_FUSION_INVALID_INPUT_TYPE		= 11709,			//	【输入数据类型非法,对应的引擎错误码是20300】
+	MSP_ERROR_FUSION_NO_ENOUGH_DATA			= 11710,			//	【输入的数据不完整,对应的引擎错误码是20301】
+	MSP_ERROR_FUSION_ENOUGH_DATA			= 11711,			//	【输入的数据过多,对应的引擎错误码是20302】
+
+	/*Error Codes of AIUI*/	
+	MSP_ERROR_AIUI_CID_EXPIRED				= 11800,
+
+	/*Error Codes of Encoder*/	
+	MSP_ERROR_ICT_ENCODER				= 11900,
+
+	/* Error codes of http 12000(0x2EE0) */
+	MSP_ERROR_HTTP_BASE						= 12000,	/* 0x2EE0 */
+	MSP_ERROR_HTTP_400						= 12400,
+	MSP_ERROR_HTTP_401						= 12401,
+	MSP_ERROR_HTTP_402						= 12402,
+	MSP_ERROR_HTTP_403						= 12403,
+	MSP_ERROR_HTTP_404						= 12404,
+	MSP_ERROR_HTTP_405						= 12405,
+	MSP_ERROR_HTTP_406						= 12406,
+	MSP_ERROR_HTTP_407						= 12407,
+	MSP_ERROR_HTTP_408						= 12408,
+	MSP_ERROR_HTTP_409						= 12409,
+	MSP_ERROR_HTTP_410						= 12410,
+	MSP_ERROR_HTTP_411						= 12411,
+	MSP_ERROR_HTTP_412						= 12412,
+	MSP_ERROR_HTTP_413						= 12413,
+	MSP_ERROR_HTTP_414						= 12414,
+	MSP_ERROR_HTTP_415						= 12415,
+	MSP_ERROR_HTTP_416						= 12416,
+	MSP_ERROR_HTTP_417						= 12417,
+	MSP_ERROR_HTTP_500						= 12500,
+	MSP_ERROR_HTTP_501						= 12501,
+	MSP_ERROR_HTTP_502						= 12502,
+	MSP_ERROR_HTTP_503						= 12503,
+	MSP_ERROR_HTTP_504						= 12504,
+	MSP_ERROR_HTTP_505						= 12505,
+	/*Error codes of ISV */
+	MSP_ERROR_ISV_NO_USER                   = 13000,	/* 32C8 */    /* the user doesn't exist */
+
+	/* Error codes of Lua scripts */
+	MSP_ERROR_LUA_BASE						= 14000,    /* 0x36B0 */
+	MSP_ERROR_LUA_YIELD						= 14001,	/* 0x36B1 */
+	MSP_ERROR_LUA_ERRRUN					= 14002,	/* 0x36B2 */
+	MSP_ERROR_LUA_ERRSYNTAX					= 14003,	/* 0x36B3 */
+	MSP_ERROR_LUA_ERRMEM					= 14004,	/* 0x36B4 */
+	MSP_ERROR_LUA_ERRERR					= 14005,	/* 0x36B5 */
+	MSP_ERROR_LUA_INVALID_PARAM				= 14006,	/* 0x36B6 */
+
+	/* Error codes of MMP */
+	MSP_ERROR_MMP_BASE						= 15000,    /* 0x3A98 */
+	MSP_ERROR_MMP_MYSQL_INITFAIL			= 15001,	/* 0x3A99 */
+	MSP_ERROR_MMP_REDIS_INITFAIL			= 15002,	/* 0x3A9A */
+	MSP_ERROR_MMP_NETDSS_INITFAIL			= 15003,	/* 0x3A9B */
+	MSP_ERROR_MMP_TAIR_INITFAIL				= 15004,	/* 0x3A9C */	
+	MSP_ERROR_MMP_MAIL_SESSION_FAIL			= 15006,	/* 0x3A9E */	/* 邮件登陆服务器时,会话错误。*/
+	MSP_ERROR_MMP_MAIL_LOGON_FAIL			= 15007,	/* 0x3A9F */	/* 邮件登陆服务器时,拒绝登陆。*/
+	MSP_ERROR_MMP_MAIL_USER_ILLEGAL			= 15008,	/* 0x3AA0 */	/* 邮件登陆服务器时,用户名非法。*/
+	MSP_ERROR_MMP_MAIL_PWD_ERR				= 15009,	/* 0x3AA1 */	/* 邮件登陆服务器时,密码错误。*/
+	MSP_ERROR_MMP_MAIL_SOCKET_ERR			= 15010,	/* 0x3AA2 */	/* 邮件发送过程中套接字错误*/
+	MSP_ERROR_MMP_MAIL_INIT_FAIL			= 15011,	/* 0x3AA3 */	/* 邮件初始化错误*/
+	MSP_ERROR_MMP_STORE_MNR_NO_INIT			= 15012,	/* 0x3AA4 */	/* store_manager未初始化,或初始化失败*/
+	MSP_ERROR_MMP_STORE_MNR_POOL_FULL		= 15013,	/* 0x3AA5 */	/* store_manager的连接池满了*/
+	MSP_ERROR_MMP_STRATGY_PARAM_ILLEGAL		= 15014,	/* 0x3AA6 */	/* 报警策略表达式非法*/
+	MSP_ERROR_MMP_STRATGY_PARAM_TOOLOOG		= 15015,	/* 0x3AA7 */	/* 报警策略表达式太长*/
+	MSP_ERROR_MMP_PARAM_NULL				= 15016,	/* 0x3AA8 */	/* 函数参数为空*/
+	MSP_ERROR_MMP_ERR_MORE_TOTAL			= 15017,	/* 0x3AA9 */	/* pms插入数据库中错误汇总表的数据,错误次数 > 总次数。*/
+	MSP_ERROR_MMP_PROC_THRESHOLD			= 15018,	/* 0x3AAA */	/* 进程监控阀值设置错误*/
+	MSP_ERROR_MMP_SERVER_THRESHOLD			= 15019,	/* 0x3AAB */	/* 服务器监控阀值设置错误*/
+	MSP_ERROR_MMP_PYTHON_NO_EXIST			= 15020,    /* 0x3AAC */	/* python脚本文件不存在 */
+	MSP_ERROR_MMP_PYTHON_IMPORT_FAILED		= 15021,	/* 0x3AAD */	/* python脚本导入出错 */
+	MSP_ERROR_MMP_PYTHON_BAD_FUNC			= 15022,	/* 0x3AAE */	/* python脚本函数格式错误 */
+	MSP_ERROR_MMP_DB_DATA_ILLEGAL			= 15023,	/* 0x3AAF */	/* 插入数据库中的数据格式有误 */
+	MSP_ERROR_MMP_REDIS_NOT_CONN			= 15024,	/* 0x3AB0 */	/* redis没有连接到服务端 */
+	MSP_ERROR_MMP_PMA_NOT_FOUND_STRATEGY	= 15025,	/* 0x3AB1 */	/* 没有找到报警策略 */
+	MSP_ERROR_MMP_TAIR_CONNECT				= 15026,	/* 0x3AB2 */	/* 连接tair集群失败 */
+	MSP_ERROR_MMP_PMC_SERVINFO_INVALID		= 15027,	/* Ox3AB3 */	/* 此pmc的服务器信息已经无效 */
+	MSP_ERROR_MMP_ALARM_GROUP_NULL			= 15028,	/* Ox3AB4 */	/* 服务器报警的短信报警组与邮件报警组均为空 */
+	MSP_ERROR_MMP_ALARM_CONTXT_NULL			= 15029,	/* Ox3AB5 */	/* 服务器报警的报警内容为空 */	
+
+	/* Error codes of MSC(lmod loader) */
+	MSP_ERROR_LMOD_BASE						= 16000,	/* 0x3E80 */
+	MSP_ERROR_LMOD_NOT_FOUND				= 16001,	/* 0x3E81 */	/* 没找到lmod文件 */
+	MSP_ERROR_LMOD_UNEXPECTED_BIN			= 16002,	/* 0x3E82 */	/* 无效的lmod */
+	MSP_ERROR_LMOD_LOADCODE					= 16003,	/* 0x3E83 */	/* 加载lmod指令失败 */
+	MSP_ERROR_LMOD_PRECALL					= 16004,	/* 0x3E84 */	/* 初始化lmod失败 */
+	MSP_ERROR_LMOD_RUNTIME_EXCEPTION		= 16005,	/* 0x3E85 */	/* lmod运行时异常 */
+	MSP_ERROR_LMOD_ALREADY_LOADED			= 16006,	/* 0x3E86 */	/* lmod重复加载 */
+
+	// Error code of Third Business
+	MSP_ERROR_BIZ_BASE						 = 17000,	/* 0x4268 */	/* 三方业务错误码 */
+	
+	//Error of Nginx errlog file increase exception
+	MSP_ERROR_NGX_LOG_MORE_TOTEL_SIZE        = 18000,				    /*nginx错误日志大小异常*/
+	
+	//Error of Flash client when network checking
+	MSP_ERROR_FLASH_NETWORK_CONNECT_FIALED   = 19000,					/*flash服务端网络连接失败*/
+	MSP_ERROR_FLASH_NETWORK_CHECK_FIALED     = 19001,					/*flash服务端响应了异常消息*/
+	MSP_ERROR_FLASH_NETWORK_CHECK_TIMEOUT    = 19002,				    /*flash服务端网络超时*/
+	MSP_ERROR_FLASH_NETWORK_CLOSED_EXCEPTION = 19003,                   /*flash服务端网络异常关闭*/
+	
+	/*Error Code Of Speech plus*/
+	
+	SPEECH_ERROR_NO_NETWORK 				               = 20001, /* 无有效的网络连接*/
+	SPEECH_ERROR_NETWORK_TIMEOUT 			               = 20002, /* 网络连接超时*/
+	SPEECH_ERROR_NET_EXPECTION				               = 20003, /* 网络异常*/
+	SPEECH_ERROR_INVALID_RESULT			                   = 20004, /* 无有效的结果*/
+	SPEECH_ERROR_NO_MATCH 					               = 20005, /* 无匹配结果 */
+	SPEECH_ERROR_AUDIO_RECORD 				               = 20006, /* 录音失败 */
+	SPEECH_ERROR_NO_SPPECH 				                   = 20007, /* 未检测到语音*/
+                                                           
+	SPEECH_ERROR_SPEECH_TIMEOUT 			               = 20008, /* 音频输入超时*/
+	SPEECH_ERROR_EMPTY_UTTERANCE 			               = 20009, /* 无效的文本输入 */
+	SPEECH_ERROR_FILE_ACCESS 				               = 20010, /* 文件读写失败 */
+	SPEECH_ERROR_PLAY_MEDIA 				               = 20011, /* 音频播放失败 */
+                                                           
+	SPEECH_ERROR_INVALID_PARAM 			                   = 20012, /* 无效的参数*/
+	SPEECH_ERROR_TEXT_OVERFLOW				               = 20013, /* 文本溢出 */
+	SPEECH_ERROR_INVALID_DATA 				               = 20014, /* 无效数据 */
+	SPEECH_ERROR_LOGIN						               = 20015, /* 用户未登陆*/
+	SPEECH_ERROR_PERMISSION_DENIED 		                   = 20016, /* 无效授权 */
+	SPEECH_ERROR_INTERRUPT 				                   = 20017, /* 被异常打断 */
+                                                           
+    SPEECH_ERROR_VERSION_LOWER                             = 20018, /* 版本过低 */
+	SPEECH_CLIENT_ERROR_ISUSING							   = 20019, /* 录音机被占用(iOS平台) */
+	SPEECH_ERROR_SYSTEM_PREINSTALL                         = 20020, /* 系统预置版本 */
+	SPEECH_ERROR_UNSATISFIED_LINK 						   = 20021, /* 未实现的Native函数引用 */
+   	SPEECH_ERROR_UNKNOWN                                   = 20999, /* 未知错误 */
+                                                           
+	                                                       
+	SPEECH_ERROR_COMPONENT_NOT_INSTALLED                   = 21001, /* 没有安装语音组件 */
+	SPEECH_ERROR_ENGINE_NOT_SUPPORTED                      = 21002, /* 引擎不支持 */
+	SPEECH_ERROR_ENGINE_INIT_FAIL                          = 21003, /* 初始化失败 */
+	SPEECH_ERROR_ENGINE_CALL_FAIL                          = 21004, /* 调用失败 */
+	SPEECH_ERROR_ENGINE_BUSY	                           = 21005, /* 引擎繁忙 */ 
+                                                           
+	SPEECH_ERROR_LOCAL_NO_INIT                             = 22001, /* 本地引擎未初始化 */              
+	SPEECH_ERROR_LOCAL_RESOURCE                            = 22002, /* 本地引擎无资源 */   	              
+	SPEECH_ERROR_LOCAL_ENGINE                              = 22003, /* 本地引擎内部错误 */   	       
+	SPEECH_ERROR_IVW_INTERRUPT 			                   = 22004, /* 本地唤醒引擎被异常打断 */ 
+	
+	
+	/*Error Code Of Local iflytek Engines*/
+
+	/*Error Code Of AiTalk*/
+	
+	/*Error Code Of AiTalk Operation*/
+	SPEECH_SUCCESS                                         = 0    , // ivErr_OK                  = 0 /*成功状态*/ 
+
+	SPEECH_ERROR_ASR_CLIENT                                = 23000, /*客户端应用程序错误*///?????????
+	SPEECH_ERROR_ASR_INVALID_PARA                          = 23001, /*无效的参数*/
+	SPEECH_ERROR_ASR_INVALID_PARA_VALUE                    = 23002, /*无效的参数值*/
+	SPEECH_ERROR_ASR_OUT_OF_MEMORY                         = 23003, /*内存耗尽*/
+	SPEECH_ERROR_ASR_CREATE_HANDLE_FAILED                  = 23004, /*创建句柄失败*/
+	SPEECH_ERROR_ASR_ENGINE_INIT_FAILED                    = 23005, /*引擎初始化失败*/
+	SPEECH_ERROR_ASR_ENGINE_STARTED                        = 23006, /*引擎已经启动*/
+	SPEECH_ERROR_ASR_ENGINE_UNINIT                         = 23007, /*引擎未初始化*/
+	SPEECH_ERROR_ASR_SPEECH_TIMEOUT                        = 23008, /*识别超时(VAD没开启或没有检测到后端点)*/
+	SPEECH_ERROR_ASR_NO_RECOGNIZED_RESULT                  = 23009, /*无识别结果*/
+	SPEECH_ERROR_ASR_INVALID_HANDLE                        = 23010, /*无效的句柄*/
+	SPEECH_ERROR_ASR_FILE_ACCESS                           = 23011, /*打开文件失败*/
+	
+	/*Error Code Of AiTalk Engine*/                                      
+	SPEECH_ERROR_AITALK_FALSE                              = 23100, // ivErr_FALSE               = 1                                                                                                              
+                                                                                                 
+	/* For license check */                                                                      
+	SPEECH_ERROR_AITALK_PERMISSION_DENIED                  = 23101, // ivErr_InvSN               = 2
+                                                                                                 
+	/* General */                                                                                
+	SPEECH_ERROR_AITALK_INVALID_PARA                       = 23102, // ivErr_InvArg              = 3
+	SPEECH_ERROR_AITALK_BUFFER_OVERFLOW                    = 23103, // ivErr_BufferFull          = 4  /*音频数据缓冲区已满*/
+	SPEECH_ERROR_AITALK_FAILED                             = 23104, // ivErr_Failed              = 5
+	SPEECH_ERROR_AITALK_NOT_SUPPORTED                      = 23105, // ivErr_NotSupport          = 6  /*引擎不支持*/
+	SPEECH_ERROR_AITALK_OUT_OF_MEMORY                      = 23106, // ivErr_OutOfMemory         = 7
+	SPEECH_ERROR_AITALK_INVALID_RESOURCE                   = 23107, // ivErr_InvResource         = 8  /*资源无效*/
+	SPEECH_ERROR_AITALK_NOT_FOUND                          = 23108, // ivErr_NotFound            = 9  /*打开文件失败*/
+	SPEECH_ERROR_AITALK_INVALID_GRAMMAR                    = 23109, // ivErr_InvGrmr             = 10 /*识别语法错误*/
+                                                                                                 
+	/* For object status */                                                                      
+	SPEECH_ERROR_AITALK_INVALID_CALL                       = 23110, // ivErr_InvCall             = 11 /*无效调用*/
+                                                                                                 
+	/* For ASR Input */                                                                          
+	SPEECH_ERROR_AITALK_SYNTAX_ERROR                       = 23111, // ivErr_InvCall             = 12
+                                                                                                 
+	/* For Message Call Back */                                                                  
+	SPEECH_ERROR_AITALK_RESET                              = 23112, // ivErr_Reset               = 13                                                                       
+	SPEECH_ERROR_AITALK_ENDED                              = 23113, // ivErr_Ended               = 14
+	SPEECH_ERROR_AITALK_IDLE                               = 23114, // ivErr_Idle                = 15                                                                       
+	SPEECH_ERROR_AITALK_CANNOT_SAVE_FILE                   = 23115, // ivErr_CanNotSaveFile      = 16
+                                                                                                 
+	/* For Lexicon name */                                                                       
+	SPEECH_ERROR_AITALK_INVALID_GRAMMAR_NAME               = 23116, // ivErr_InvName             = 17 /*文法或词典名称非法*/
+                                                                                                 
+	SPEECH_ERROR_AITALK_BUFFER_EMPTY                       = 23117, // ivErr_BufferEmpty         = 18
+                                                                                                 
+	SPEECH_ERROR_AITALK_GET_RESULT                         = 23118, // ivErr_GetResult           = 19
+                                                                                                 
+	SPEECH_ERROR_AITALK_REACT_OUT_TIME                     = 23119, // ivErr_ReactOutTime        = 20 /*反应超时*/
+	SPEECH_ERROR_AITALK_SPEECH_OUT_TIME                    = 23120, // ivErr_SpeechOutTime       = 21 /*语音超时*/
+                                                                                                 
+	SPEECH_ERROR_AITALK_AUDIO_CUT                          = 23121, // ivErr_CUT                 = 22 /*录音质量过高*/
+	SPEECH_ERROR_AITALK_AUDIO_LOWER                        = 23122, // ivErr_LOWER               = 23 /*录音质量过低*/
+                                                                                                 
+	SPEECH_ERROR_AITALK_INSUFFICIENT_PERMISSIONS           = 23123, // ivErr_Limitted            = 24 /*授权不够*/
+	SPEECH_ERROR_AITALK_RESULT_ERROR                       = 23124, // ivErr_ResultError         = 25 /*解码器Wfst输出后,依然有cmd输出*/
+	SPEECH_ERROR_AITALK_SHORT_PAUSE                        = 23125, // ivErr_ShortPause          = 26
+	SPEECH_ERROR_AITALK_BUSY                               = 23126, // ivErr_Busy                = 27
+	SPEECH_ERROR_AITALK_GRM_NOT_UPDATE                     = 23127, // ivErr_GrmNotUpdate        = 28 /*语法未更新*/
+	SPEECH_ERROR_AITALK_STARTED                            = 23128, // ivErr_Started             = 29
+	SPEECH_ERROR_AITALK_STOPPED                            = 23129, // ivErr_Stopped             = 30
+	SPEECH_ERROR_AITALK_ALREADY_STARTED                    = 23130, // ivErr_AlreadyStarted      = 31
+	SPEECH_ERROR_AITALK_ALREADY_STOPPED                    = 23131, // ivErr_AlreadyStopped      = 32
+	SPEECH_ERROR_AITALK_TOO_MANY_COMMAND                   = 23132, // ivErr_TooManyCmd          = 33
+	SPEECH_ERROR_AITALK_WAIT                               = 23133, // ivErr_Wait                = 34 /*程序可能在做一些操作,主线程需要等待*/
+	SPEECH_ERROR_AITALK_MAE_RIGHT                          = 23134, // ivErr_MAERight            = 35 
+	SPEECH_ERROR_AITALK_MAE_WRONG                          = 23135, // ivErr_MAEWrong            = 36
+    
+	SPEECH_ERROR_AITALK_GRM_ERR                            = 23300,  // 语法错误
+	
+	
+	
+	/*Error Code Of AiSound*/
+	
+	/*Error Code Of AiSound Operation*/
+	SPEECH_ERROR_TTS_INVALID_PARA                          = 24000, /* 错误参数 */
+	SPEECH_ERROR_TTS_INVALID_PARA_VALUE                    = 24001, /* 无效的参数值*/
+	SPEECH_ERROR_TTS_OUT_OF_MEMORY	                       = 24002, /* 内存不足*/
+	SPEECH_ERROR_TTS_INVALID_HANDLE                        = 24003, /* 无效的句柄*/
+	SPEECH_ERROR_TTS_CREATE_HANDLE_FAILED			       = 24004, /* 创建句柄失败*/
+	SPEECH_ERROR_TTS_INVALID_RESOURCE	                   = 24005,	/* 无效资源 */
+	SPEECH_ERROR_TTS_INVALID_VOICE_NAME	                   = 24006,	/* 无效发言人*/
+	SPEECH_ERROR_TTS_ENGINE_UNINIT			               = 24007, /* 引擎未初始化 */
+	SPEECH_ERROR_TTS_ENGINE_INIT_FAILED	                   = 24008,	/* 引擎初始化失败 */
+	SPEECH_ERROR_TTS_ENGINE_BUSY			               = 24009, /* 引擎忙 */
+
+                                                             
+	/*Error Code Of AiSound Engine*/                         
+	SPEECH_ERROR_AISOUND_BASE					           = 24100,	
+	SPEECH_ERROR_AISOUND_UNIMPEMENTED				       = 24100,  /* unimplemented function */
+	SPEECH_ERROR_AISOUND_UNSUPPORTED				       = 24101,  /* unsupported on this platform */
+	SPEECH_ERROR_AISOUND_INVALID_HANDLE			           = 24102,  /* invalid handle */
+	SPEECH_ERROR_AISOUND_INVALID_PARA			           = 24103,  /* invalid parameter(s) */
+	SPEECH_ERROR_AISOUND_INSUFFICIENT_HEAP			       = 24104,  /* insufficient heap size  */
+	SPEECH_ERROR_AISOUND_STATE_REFUSE				       = 24105,  /* refuse to do in current state  */
+	SPEECH_ERROR_AISOUND_INVALID_PARA_ID			       = 24106,  /* invalid parameter ID */
+	SPEECH_ERROR_AISOUND_INVALID_PARA_VALUE		           = 24107,  /* invalid parameter value */
+	SPEECH_ERROR_AISOUND_RESOURCE					       = 24108,  /* Resource is error */
+	SPEECH_ERROR_AISOUND_RESOURCE_READ				       = 24109,  /* read resource error */
+	SPEECH_ERROR_AISOUND_LBENDIAN					       = 24110,  /* the Endian of SDK  is error */
+	SPEECH_ERROR_AISOUND_HEADFILE					       = 24111,  /* the HeadFile is different of the SDK */
+	SPEECH_ERROR_AISOUND_BUFFER_OVERFLOW		           = 24112,  /* get data size exceed the data buffer */
+	SPEECH_ERROR_AISOUND_INVALID_ISAMPA			           = 24113,  /* !Invalid iSampa format or input iSampa text contain invalid alphabet*/
+	SPEECH_ERROR_AISOUND_INVALID_CSSML     	               = 24114,   /* !Invalid cssml format */
+
+
+	/*Error Code Of ivw*/
+
+	/*Error Code Of ivw Operation*/
+	SPEECH_ERROR_IVW_ENGINE_UNINI             = 25000,  /* 引擎未初始化 */
+	SPEECH_ERROR_IVW_RESVER_NOMATCH           = 25001,  /* 资源版本不匹配 */
+	SPEECH_ERROR_IVW_BUFFERED_AUDIOD_LITTLE   = 25002,  /* 唤醒加识别缓存音频过少 */
+	SPEECH_ERROR_IVW_INVALID_RESTYPE          = 25003,  /* 不合法的资源类型 */
+	SPEECH_ERROR_IVW_INVALID_RESHEADVER       = 25004,  /* 不合法的资源头部版本号 */
+
+	/*Error Code Of ivw Engine*/
+	SPEECH_ERROR_IVW_INVALID_CALL             = 25101,   // IvwErr_InvCal       = 1					   
+    SPEECH_ERROR_IVW_INVALID_ARG              = 25102,   // IvwErr_InvArg	    = 2				    
+    SPEECH_ERROR_IVW_TELL_SIZE                = 25103,   // IvwErr_TellSize     = 3
+    SPEECH_ERROR_IVW_OUT_OF_MEMORY            = 25104,   // IvwErr_OutOfMemory  = 4			   
+    SPEECH_ERROR_IVW_OUT_BUFFER_FULL          = 25105,   // IvwErr_BufferFull	= 5
+    SPEECH_ERROR_IVW_OUT_BUFFER_EMPTY         = 25106,   // IvwErr_BufferEmpty	= 6			    
+	SPEECH_ERROR_IVW_INVALID_RESOURCE         = 25107,   // IvwErr_InvRes		= 7			  
+    SPEECH_ERROR_IVW_REPETITIOPN_ENTER        = 25108,   // IvwErr_ReEnter		= 8
+    SPEECH_ERROR_IVW_NOT_SUPPORT              = 25109,   // IvwErr_NotSupport	= 9			  
+    SPEECH_ERROR_IVW_NOT_FOUND                = 25110,   // IvwErr_NotFound		= 10		         
+    SPEECH_ERROR_IVW_INVALID_SN               = 25111,   // IvwErr_InvSN		= 11			    
+    SPEECH_ERROR_IVW_LIMITTED                 = 25112,   // IvwErr_Limitted		= 12			    
+    SPEECH_ERROR_IVW_TIME_OUT                 = 25113,   // IvwErr_TimeOut		= 13		         
+
+    SPEECH_ERROR_IVW_ENROLL1_SUCESS           = 25114,   // IvwErr_Enroll1_Success = 14             
+    SPEECH_ERROR_IVW_ENROLL1_FAILED           = 25115,   // IvwErr_Enroll1_Failed  = 15               
+    SPEECH_ERROR_IVW_ENROLL2_SUCESS           = 25116,   // IvwErr_Enroll2_Success = 16               
+    SPEECH_ERROR_IVW_ENROLL2_FAILED           = 25117,   // IvwErr_Enroll2_Failed  = 17              
+    SPEECH_ERROR_IVW_ENROLL3_SUCESS           = 25118,   // IvwErr_Enroll3_Success = 18             
+    SPEECH_ERROR_IVW_ENROLL3_FAILED           = 25119,   // IvwErr_Enroll3_Failed  = 19             
+    SPEECH_ERROR_IVW_SPEECH_TOO_SHORT         = 25120,   // IvwErr_SpeechTooShort  = 20            
+    SPEECH_ERROR_IVW_SPEECH_STOP              = 25121,   // IvwErr_SpeechStop      = 21             
+
+	/* 非实时转写错误码:26000~26999 */
+	SPEECH_ERROR_LFASR_BASE					  = 26000,	/* 非实时转写错误码基码 */
+};
+
+#endif /* __MSP_ERRORS_H__ */

+ 123 - 0
example/xf_aitalk/include/msp_types.h

@@ -0,0 +1,123 @@
+#ifndef __MSP_TYPES_H__
+#define __MSP_TYPES_H__
+
+#if !defined(MSPAPI)
+#if defined(WIN32) || defined(WINPHONE8) || defined(WIN8)
+	#define MSPAPI __stdcall
+#else
+	#define MSPAPI
+#endif /* WIN32 */
+#endif /* MSPAPI */
+
+
+/**
+ *  MSPSampleStatus indicates how the sample buffer should be handled
+ *  MSP_AUDIO_SAMPLE_FIRST		- The sample buffer is the start of audio
+ *								  If recognizer was already recognizing, it will discard
+ *								  audio received to date and re-start the recognition
+ *  MSP_AUDIO_SAMPLE_CONTINUE	- The sample buffer is continuing audio
+ *  MSP_AUDIO_SAMPLE_LAST		- The sample buffer is the end of audio
+ *								  The recognizer will cease processing audio and
+ *								  return results
+ *  Note that sample statii can be combined; for example, for file-based input
+ *  the entire file can be written with SAMPLE_FIRST | SAMPLE_LAST as the
+ *  status.
+ *  Other flags may be added in future to indicate other special audio
+ *  conditions such as the presence of AGC
+ */
+enum
+{
+	MSP_AUDIO_SAMPLE_INIT           = 0x00,
+    MSP_AUDIO_SAMPLE_FIRST          = 0x01,
+    MSP_AUDIO_SAMPLE_CONTINUE       = 0x02,
+    MSP_AUDIO_SAMPLE_LAST           = 0x04,
+};
+
+/*
+ *  The enumeration MSPRecognizerStatus contains the recognition status
+ *  MSP_REC_STATUS_SUCCESS				- successful recognition with partial results
+ *  MSP_REC_STATUS_NO_MATCH				- recognition rejected
+ *  MSP_REC_STATUS_INCOMPLETE			- recognizer needs more time to compute results
+ *  MSP_REC_STATUS_NON_SPEECH_DETECTED	- discard status, no more in use
+ *  MSP_REC_STATUS_SPEECH_DETECTED		- recognizer has detected audio, this is delayed status
+ *  MSP_REC_STATUS_COMPLETE				- recognizer has return all result
+ *  MSP_REC_STATUS_MAX_CPU_TIME			- CPU time limit exceeded
+ *  MSP_REC_STATUS_MAX_SPEECH			- maximum speech length exceeded, partial results may be returned
+ *  MSP_REC_STATUS_STOPPED				- recognition was stopped
+ *  MSP_REC_STATUS_REJECTED				- recognizer rejected due to low confidence
+ *  MSP_REC_STATUS_NO_SPEECH_FOUND		- recognizer still found no audio, this is delayed status
+ */
+enum
+{
+	MSP_REC_STATUS_SUCCESS              = 0,
+	MSP_REC_STATUS_NO_MATCH             = 1,
+	MSP_REC_STATUS_INCOMPLETE			= 2,
+	MSP_REC_STATUS_NON_SPEECH_DETECTED  = 3,
+	MSP_REC_STATUS_SPEECH_DETECTED      = 4,
+	MSP_REC_STATUS_COMPLETE				= 5,
+	MSP_REC_STATUS_MAX_CPU_TIME         = 6,
+	MSP_REC_STATUS_MAX_SPEECH           = 7,
+	MSP_REC_STATUS_STOPPED              = 8,
+	MSP_REC_STATUS_REJECTED             = 9,
+	MSP_REC_STATUS_NO_SPEECH_FOUND      = 10,
+	MSP_REC_STATUS_FAILURE = MSP_REC_STATUS_NO_MATCH,
+};
+
+/**
+ * The enumeration MSPepState contains the current endpointer state
+ *  MSP_EP_LOOKING_FOR_SPEECH	- Have not yet found the beginning of speech
+ *  MSP_EP_IN_SPEECH			- Have found the beginning, but not the end of speech
+ *  MSP_EP_AFTER_SPEECH			- Have found the beginning and end of speech
+ *  MSP_EP_TIMEOUT				- Have not found any audio till timeout
+ *  MSP_EP_ERROR				- The endpointer has encountered a serious error
+ *  MSP_EP_MAX_SPEECH			- Have arrive the max size of speech
+ */
+enum
+{
+	MSP_EP_LOOKING_FOR_SPEECH   = 0,
+	MSP_EP_IN_SPEECH            = 1,
+	MSP_EP_AFTER_SPEECH         = 3,
+	MSP_EP_TIMEOUT              = 4,
+	MSP_EP_ERROR                = 5,
+	MSP_EP_MAX_SPEECH           = 6,
+	MSP_EP_IDLE                 = 7  // internal state after stop and before start
+};
+
+/* Synthesizing process flags */
+enum
+{
+    MSP_TTS_FLAG_STILL_HAVE_DATA        = 1,
+    MSP_TTS_FLAG_DATA_END               = 2,
+    MSP_TTS_FLAG_CMD_CANCELED           = 4,
+};
+
+/* Handwriting process flags */
+enum
+{
+	MSP_HCR_DATA_FIRST           = 1,
+	MSP_HCR_DATA_CONTINUE        = 2,
+	MSP_HCR_DATA_END             = 4,
+};
+
+/*ivw message type */
+enum
+{
+	MSP_IVW_MSG_WAKEUP       = 1,
+	MSP_IVW_MSG_ERROR        = 2,
+	MSP_IVW_MSG_ISR_RESULT   = 3,
+	MSP_IVW_MSG_ISR_EPS      = 4,
+	MSP_IVW_MSG_VOLUME       = 5,
+	MSP_IVW_MSG_ENROLL       = 6,
+	MSP_IVW_MSG_RESET        = 7
+};
+
+/* Upload data process flags */
+enum
+{
+	MSP_DATA_SAMPLE_INIT           = 0x00,
+	MSP_DATA_SAMPLE_FIRST          = 0x01,
+	MSP_DATA_SAMPLE_CONTINUE       = 0x02,
+	MSP_DATA_SAMPLE_LAST           = 0x04,
+};
+
+#endif /* __MSP_TYPES_H__ */

+ 203 - 0
example/xf_aitalk/include/qisr.h

@@ -0,0 +1,203 @@
+/**
+ * @file    qisr.h
+ * @brief   iFLY Speech Recognizer Header File
+ * 
+ *  This file contains the quick application programming interface (API) declarations 
+ *  of ISR. Developer can include this file in your project to build applications.
+ *  For more information, please read the developer guide.
+ 
+ *  Use of this software is subject to certain restrictions and limitations set
+ *  forth in a license agreement entered into between iFLYTEK, Co,LTD.
+ *  and the licensee of this software.  Please refer to the license
+ *  agreement for license use rights and restrictions.
+ *
+ *  Copyright (C)    1999 - 2007 by ANHUI USTC iFLYTEK, Co,LTD.
+ *                   All rights reserved.
+ * 
+ * @author  Speech Dept. iFLYTEK.
+ * @version 1.0
+ * @date    2008/12/12
+ * 
+ * @see        
+ * 
+ * History:
+ * index    version        date            author        notes
+ * 0        1.0            2008/12/12      Speech        Create this file
+ */
+
+#ifndef __QISR_H__
+#define __QISR_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+
+#include "msp_types.h"
+
+/** 
+ * @fn		QISRSessionBegin
+ * @brief	Begin a Recognizer Session
+ * 
+ *  Create a recognizer session to recognize audio data
+ * 
+ * @return	return sessionID of current session, NULL is failed.
+ * @param	const char* grammarList		- [in] grammars list, inline grammar support only one.
+ * @param	const char* params			- [in] parameters when the session created.
+ * @param	int *errorCode				- [out] return 0 on success, otherwise return error code.
+ * @see		
+ */
+const char* MSPAPI QISRSessionBegin(const char* grammarList, const char* params, int* errorCode);
+typedef const char* (MSPAPI *Proc_QISRSessionBegin)(const char* grammarList, const char* params, int *result);
+#ifdef MSP_WCHAR_SUPPORT
+const wchar_t* MSPAPI QISRSessionBeginW(const wchar_t* grammarList, const wchar_t* params, int *result);
+typedef const wchar_t* (MSPAPI *Proc_QISRSessionBeginW)(const wchar_t* grammarList, const wchar_t* params, int *result);
+#endif
+
+
+/** 
+ * @fn		QISRAudioWrite
+ * @brief	Write Audio Data to Recognizer Session
+ * 
+ *  Writing binary audio data to recognizer.
+ * 
+ * @return	int MSPAPI	- Return 0 in success, otherwise return error code.
+ * @param	const char* sessionID	- [in] The session id returned by recog_begin
+ * @param	const void* waveData	- [in] Binary data of waveform
+ * @param	unsigned int waveLen	- [in] Waveform data size in bytes
+ * @param	int audioStatus			- [in] Audio status, can be 
+ * @param	int *epStatus			- [out] ISRepState
+ * @param	int *recogStatus		- [out] ISRrecRecognizerStatus, see isr_rec.h
+ * @see		
+ */
+int MSPAPI QISRAudioWrite(const char* sessionID, const void* waveData, unsigned int waveLen, int audioStatus, int *epStatus, int *recogStatus);
+typedef int (MSPAPI *Proc_QISRAudioWrite)(const char* sessionID, const void* waveData, unsigned int waveLen, int audioStatus, int *epStatus, int *recogStatus);
+#ifdef MSP_WCHAR_SUPPORT
+int MSPAPI QISRAudioWriteW(const wchar_t* sessionID, const void* waveData, unsigned int waveLen, int audioStatus, int *epStatus, int *recogStatus);
+typedef int (MSPAPI *Proc_QISRAudioWriteW)(const wchar_t* sessionID, const void* waveData, unsigned int waveLen, int audioStatus, int *epStatus, int *recogStatus);
+#endif
+
+/** 
+ * @fn		QISRGetResult
+ * @brief	Get Recognize Result in Specified Format
+ * 
+ *  Get recognize result in Specified format.
+ * 
+ * @return	int MSPAPI	- Return 0 in success, otherwise return error code.
+ * @param	const char* sessionID	- [in] session id returned by session begin
+ * @param	int* rsltStatus			- [out] status of recognition result, 0: success, 1: no match, 2: incomplete, 5:speech complete
+ * @param	int *errorCode			- [out] return 0 on success, otherwise return error code.
+ * @see		
+ */
+const char * MSPAPI QISRGetResult(const char* sessionID, int* rsltStatus, int waitTime, int *errorCode);
+typedef const char * (MSPAPI *Proc_QISRGetResult)(const char* sessionID, int* rsltStatus, int waitTime, int *errorCode);
+#ifdef MSP_WCHAR_SUPPORT
+const wchar_t* MSPAPI QISRGetResultW(const wchar_t* sessionID, int* rsltStatus, int waitTime, int *errorCode);
+typedef const wchar_t* (MSPAPI *Proc_QISRGetResultW)(const wchar_t* sessionID, int* rsltStatus, int waitTime, int *errorCode);
+#endif
+
+/** 
+ * @fn		QISRGetBinaryResult
+ * @brief	Get Recognize Result in Specified Format
+ * 
+ *  Get recognize result in Specified format.
+ * 
+ * @return	int MSPAPI	- Return 0 in success, otherwise return error code.
+ * @param	const char* sessionID	- [in] session id returned by session begin
+ * @param	int* rsltStatus			- [out] status of recognition result, 0: success, 1: no match, 2: incomplete, 5:speech complete
+ * @param	int *errorCode			- [out] return 0 on success, otherwise return error code.
+ * @see		
+ */
+const char * MSPAPI QISRGetBinaryResult(const char* sessionID, unsigned int* rsltLen,int* rsltStatus, int waitTime, int *errorCode);
+typedef const char * (MSPAPI *Proc_QISRGetBinaryResult)(const char* sessionID, unsigned int* rsltLen, int* rsltStatus, int waitTime, int *errorCode);
+#ifdef MSP_WCHAR_SUPPORT
+const wchar_t* MSPAPI QISRGetBinaryResultW(const wchar_t* sessionID, unsigned int* rsltLen, int* rsltStatus, int waitTime, int *errorCode);
+typedef const wchar_t* (MSPAPI *Proc_QISRGetBinaryResultW)(const wchar_t* sessionID, unsigned int* rsltLen, int* rsltStatus, int waitTime, int *errorCode);
+#endif
+
+
+/** 
+ * @fn		QISRSessionEnd
+ * @brief	End a Recognizer Session
+ * 
+ *  End the recognizer session, release all resource.
+ * 
+ * @return	int MSPAPI	- Return 0 in success, otherwise return error code.
+ * @param	const char* sessionID	- [in] session id string to end
+ * @param	const char* hints	- [in] user hints to end session, hints will be logged to CallLog
+ * @see		
+ */
+int MSPAPI QISRSessionEnd(const char* sessionID, const char* hints);
+typedef int (MSPAPI *Proc_QISRSessionEnd)(const char* sessionID, const char* hints);
+#ifdef MSP_WCHAR_SUPPORT
+int MSPAPI QISRSessionEndW(const wchar_t* sessionID, const wchar_t* hints);
+typedef int (MSPAPI *Proc_QISRSessionEndW)(const wchar_t* sessionID, const wchar_t* hints);
+#endif
+
+/** 
+ * @fn		QISRGetParam
+ * @brief	get params related with msc
+ * 
+ *  the params could be local or server param, we only support netflow params "upflow" & "downflow" now
+ * 
+ * @return	int	- Return 0 if success, otherwise return errcode.
+ * @param	const char* sessionID	- [in] session id of related param, set NULL to got global param
+ * @param	const char* paramName	- [in] param name,could pass more than one param split by ','';'or'\n'
+ * @param	const char* paramValue	- [in] param value buffer, malloced by user
+ * @param	int *valueLen			- [in, out] pass in length of value buffer, and return length of value string
+ * @see		
+ */
+int MSPAPI QISRGetParam(const char* sessionID, const char* paramName, char* paramValue, unsigned int* valueLen);
+typedef int (MSPAPI *Proc_QISRGetParam)(const char* sessionID, const char* paramName, char* paramValue, unsigned int* valueLen);
+#ifdef MSP_WCHAR_SUPPORT
+int MSPAPI QISRGetParamW(const wchar_t* sessionID, const wchar_t* paramName, wchar_t* paramValue, unsigned int* valueLen);
+typedef int (MSPAPI *Proc_QISRGetParamW)(const wchar_t* sessionID, const wchar_t* paramName, wchar_t* paramValue, unsigned int* valueLen);
+#endif
+
+/** 
+ * @fn		QISRSetParam
+ * @brief	get params related with msc
+ * 
+ *  the params could be local or server param, we only support netflow params "upflow" & "downflow" now
+ * 
+ * @return	int	- Return 0 if success, otherwise return errcode.
+ * @param	const char* sessionID	- [in] session id of related param, set NULL to got global param
+ * @param	const char* paramName	- [in] param name,could pass more than one param split by ','';'or'\n'
+ * @param	const char* paramValue	- [in] param value buffer, malloced by user
+ * @param	int *valueLen			- [in, out] pass in length of value buffer, and return length of value string
+ * @see		
+ */
+int MSPAPI QISRSetParam(const char* sessionID, const char* paramName, const char* paramValue);
+typedef int (MSPAPI *Proc_QISRSetParam)(const char* sessionID, const char* paramName, const char* paramValue);
+#ifdef MSP_WCHAR_SUPPORT
+int MSPAPI QISRSetParamW(const wchar_t* sessionID, const wchar_t* paramName, const wchar_t* paramValue);
+typedef int (MSPAPI *Proc_QISRSetParamW)(const wchar_t* sessionID, const wchar_t* paramName, const wchar_t* paramValue);
+#endif
+
+
+typedef void ( *recog_result_ntf_handler)( const char *sessionID, const char *result, int resultLen, int resultStatus, void *userData ); 
+typedef void ( *recog_status_ntf_handler)( const char *sessionID, int type, int status, int param1, const void *param2, void *userData);
+typedef void ( *recog_error_ntf_handler)(const char *sessionID, int errorCode,	const char *detail, void *userData);
+int MSPAPI QISRRegisterNotify(const char *sessionID, recog_result_ntf_handler rsltCb, recog_status_ntf_handler statusCb, recog_error_ntf_handler errCb, void *userData);
+
+typedef int ( *UserCallBack)( int, const char*, void*);
+typedef int ( *GrammarCallBack)( int, const char*, void*);
+typedef int ( *LexiconCallBack)( int, const char*, void*);
+
+int MSPAPI QISRBuildGrammar(const char *grammarType, const char *grammarContent, unsigned int grammarLength, const char *params, GrammarCallBack callback, void *userData);
+typedef int (MSPAPI *Proc_QISRBuildGrammar)(const char *grammarType, const char *grammarContent, unsigned int grammarLength, const char *params, GrammarCallBack callback, void *userData);
+#ifdef MSP_WCHAR_SUPPORT
+int MSPAPI QISRBuildGrammarW(const wchar_t *grmmarType, const wchar_t *grammarContent, unsigned int grammarLength, const wchar_t *params, GrammarCallBack callback, void *userData);
+typedef int (MSPAPI *Proc_QISRBuildGrammarW)(const wchar_t *grmmarType, const wchar_t *grammarContent, unsigned int grammarLength, const wchar_t *params, GrammarCallBack callback, void *userData);
+#endif
+
+int MSPAPI QISRUpdateLexicon(const char *lexiconName, const char *lexiconContent, unsigned int lexiconLength, const char *params, LexiconCallBack callback, void *userData);
+typedef int (MSPAPI *Proc_QISRUpdataLexicon)(const char *lexiconName, const char *lexiconContent, unsigned int lexiconLength, const char *params, LexiconCallBack callback, void *userData);
+#ifdef MSP_WCHAR_SUPPORT
+int MSPAPI QISRUpdateLexiconW(const wchar_t *lexiconName, const wchar_t *lexiconContent, unsigned int lexiconLength, const wchar_t *params, LexiconCallBack callback, void *userData);
+typedef int (MSPAPI Proc_QISRUpdateLexiconW)(const wchar_t *lexiconName, const wchar_t *lexiconContent, unsigned int lexiconLength, const wchar_t *params, LexiconCallBack callback, void *userData);
+#endif
+#ifdef __cplusplus
+} /* extern "C" */	
+#endif /* C++ */
+
+#endif /* __QISR_H__ */

+ 0 - 0
example/xf_aitalk/libs/.gitkeep


+ 2 - 0
example/xf_aitalk/release.txt

@@ -0,0 +1,2 @@
+1.1218版本更新信息
+	1.增加唤醒闭环上传控制功能;

+ 28 - 0
example/xf_aitalk/samples/asr_offline_record_sample/Makefile

@@ -0,0 +1,28 @@
+#common makefile header
+
+DIR_INC = ../../include
+DIR_BIN = ../../bin
+DIR_LIB = ../../libs
+
+TARGET	= asr_offline_record_sample
+BIN_TARGET = $(DIR_BIN)/$(TARGET)
+
+CROSS_COMPILE = 
+CFLAGS = -g -Wall -I$(DIR_INC)
+
+LDFLAGS := -L$(DIR_LIB)/
+LDFLAGS += -lmsc -lrt -ldl -lpthread -lasound -lstdc++ -lwiringPi
+
+OBJECTS := $(patsubst %.c,%.o,$(wildcard *.c))
+
+$(BIN_TARGET) : $(OBJECTS)
+	$(CROSS_COMPILE)gcc $(CFLAGS) $^ -o $@ $(LDFLAGS)
+
+%.o : %.c
+	$(CROSS_COMPILE)gcc -c $(CFLAGS) $< -o $@
+clean:
+	@rm -f *.o $(BIN_TARGET)
+
+.PHONY:clean
+
+#common makefile foot

+ 342 - 0
example/xf_aitalk/samples/asr_offline_record_sample/asr_offline_record_sample.c

@@ -0,0 +1,342 @@
+/*
+* 语音听写(iFly Auto Transform)技术能够实时地将语音转换成对应的文字。
+*/
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <wiringPi.h>
+
+#include "../../include/qisr.h"
+#include "../../include/msp_cmn.h"
+#include "../../include/msp_errors.h"
+#include "speech_recognizer.h"
+
+
+#define FRAME_LEN	640
+#define	BUFFER_SIZE	4096
+#define SAMPLE_RATE_16K     (16000)
+#define SAMPLE_RATE_8K      (8000)
+#define MAX_GRAMMARID_LEN   (32)
+#define MAX_PARAMS_LEN      (1024)
+
+#define LED_PIN 26
+#define FAN_PIN 25
+
+#define ON         1
+#define OFF        2
+#define LED_DEVICE 3
+#define FAN_DEVICE 4
+
+static int recEndFlag = 0; //是否识别出结果的标志
+
+const char * ASR_RES_PATH        = "fo|res/asr/common.jet"; //离线语法识别资源路径
+const char * GRM_BUILD_PATH      = "res/asr/GrmBuilld"; //构建离线语法识别网络生成数据保存路径
+const char * GRM_FILE            = "control.bnf"; //构建离线识别语法网络所用的语法文件
+const char * LEX_NAME            = "contact"; //更新离线识别语法的contact槽(语法文件为此示例中使用的call.bnf)
+const char * led_str             = "灯";
+const char * fan_str             = "风扇";
+const char * open_str            = "打开";
+const char * close_str           = "关闭";
+
+typedef struct _UserData {
+	int     build_fini; //标识语法构建是否完成
+	int     update_fini; //标识更新词典是否完成
+	int     errcode; //记录语法构建或更新词典回调错误码
+	char    grammar_id[MAX_GRAMMARID_LEN]; //保存语法构建返回的语法ID
+}UserData;
+
+int build_grammar(UserData *udata); //构建离线识别语法网络
+int run_asr(UserData *udata); //进行离线语法识别
+
+void controlDevice(int deviceID, int flag)
+{
+    if(LED_DEVICE == deviceID) //control led light
+    {
+        if(ON == flag) //light on
+        {
+            digitalWrite(LED_PIN, LOW);
+        }
+        else //light off
+        {
+            digitalWrite(LED_PIN, HIGH);
+        }
+    }
+    else //control fan device
+    {
+        if(ON == flag) //fan on
+        {
+            digitalWrite(FAN_PIN, HIGH);
+        }
+        else //fan off
+        {
+            digitalWrite(FAN_PIN, LOW);
+        }
+    }
+}
+
+int build_grm_cb(int ecode, const char *info, void *udata)
+{
+	UserData *grm_data = (UserData *)udata;
+
+	if (NULL != grm_data) {
+		grm_data->build_fini = 1;
+		grm_data->errcode = ecode;
+	}
+
+	if (MSP_SUCCESS == ecode && NULL != info) {
+		printf("构建语法成功! 语法ID:%s\n", info);
+		if (NULL != grm_data)
+			snprintf(grm_data->grammar_id, MAX_GRAMMARID_LEN - 1, info);
+	}
+	else
+		printf("构建语法失败!%d\n", ecode);
+
+	return 0;
+}
+
+int build_grammar(UserData *udata)
+{
+	FILE *grm_file                           = NULL;
+	char *grm_content                        = NULL;
+	unsigned int grm_cnt_len                 = 0;
+	char grm_build_params[MAX_PARAMS_LEN]    = {NULL};
+	int ret                                  = 0;
+
+	grm_file = fopen(GRM_FILE, "rb");
+	if(NULL == grm_file) {
+		printf("打开\"%s\"文件失败![%s]\n", GRM_FILE, strerror(errno));
+		return -1;
+	}
+
+	fseek(grm_file, 0, SEEK_END);
+	grm_cnt_len = ftell(grm_file);
+	fseek(grm_file, 0, SEEK_SET);
+
+	grm_content = (char *)malloc(grm_cnt_len + 1);
+	if (NULL == grm_content)
+	{
+		printf("内存分配失败!\n");
+		fclose(grm_file);
+		grm_file = NULL;
+		return -1;
+	}
+	fread((void*)grm_content, 1, grm_cnt_len, grm_file);
+	grm_content[grm_cnt_len] = '\0';
+	fclose(grm_file);
+	grm_file = NULL;
+
+	snprintf(grm_build_params, MAX_PARAMS_LEN - 1,
+		"engine_type = local, \
+		asr_res_path = %s, sample_rate = %d, \
+		grm_build_path = %s, ",
+		ASR_RES_PATH,
+		SAMPLE_RATE_16K,
+		GRM_BUILD_PATH
+		);
+	ret = QISRBuildGrammar("bnf", grm_content, grm_cnt_len, grm_build_params, build_grm_cb, udata);
+
+	free(grm_content);
+	grm_content = NULL;
+
+	return ret;
+}
+
+static void show_result(char *string, char is_over)
+{
+    char *check = NULL;
+    int device_id = 0;
+    int operate_id = 0;
+
+	printf("\rResult: [ %s ]", string);
+	if(is_over)
+		putchar('\n');
+
+    check = strstr(string, led_str);
+    if(check != NULL)
+    {
+        device_id = 3;
+    }
+    check = strstr(string, fan_str);
+    if(check != NULL)
+    {
+        device_id = 4;
+    }
+    check = strstr(string, open_str);
+    if(check != NULL)
+    {
+       operate_id = 1;
+    }
+    check = strstr(string, close_str);
+    if(check != NULL)
+    {
+        operate_id = 2;
+    }
+
+    if((device_id != 0) && (operate_id != 0))
+    {
+        controlDevice(device_id, operate_id);
+    }
+}
+
+static char *g_result = NULL;
+static unsigned int g_buffersize = BUFFER_SIZE;
+
+void on_result(const char *result, char is_last)
+{
+	if (result) {
+		size_t left = g_buffersize - 1 - strlen(g_result);
+		size_t size = strlen(result);
+		if (left < size) {
+			g_result = (char*)realloc(g_result, g_buffersize + BUFFER_SIZE);
+			if (g_result)
+				g_buffersize += BUFFER_SIZE;
+			else {
+				printf("mem alloc failed\n");
+				return;
+			}
+		}
+		strncat(g_result, result, size);
+		show_result(g_result, is_last);
+	}
+}
+void on_speech_begin()
+{
+	if (g_result)
+	{
+		free(g_result);
+	}
+	g_result = (char*)malloc(BUFFER_SIZE);
+	g_buffersize = BUFFER_SIZE;
+	memset(g_result, 0, g_buffersize);
+
+	printf("Start Listening...\n");
+}
+void on_speech_end(int reason)
+{
+    recEndFlag = 1;
+	if (reason == END_REASON_VAD_DETECT)
+		printf("\nSpeaking done \n");
+	else
+		printf("\nRecognizer error %d\n", reason);
+}
+
+/* demo recognize the audio from microphone */
+static void demo_mic(const char* session_begin_params)
+{
+	int errcode;
+	struct speech_rec iat;
+	struct speech_rec_notifier recnotifier = {
+		on_result,
+		on_speech_begin,
+		on_speech_end
+	};
+
+    recEndFlag = 0;
+	errcode = sr_init(&iat, session_begin_params, SR_MIC, &recnotifier);
+	if (errcode) {
+		printf("speech recognizer init failed\n");
+		return;
+	}
+	errcode = sr_start_listening(&iat);
+	if (errcode) {
+		printf("start listen failed %d\n", errcode);
+	}
+
+	/*mic always recording */
+	while(1)
+    {
+        printf("listening ...\n");
+        if(recEndFlag)
+        {
+            break;
+        }
+		sleep(1);
+    }
+	errcode = sr_stop_listening(&iat);
+	if (errcode) {
+		printf("stop listening failed %d\n", errcode);
+	}
+
+	sr_uninit(&iat);
+}
+
+int run_asr(UserData *udata)
+{
+	char asr_params[MAX_PARAMS_LEN]    = {NULL};
+	const char *rec_rslt               = NULL;
+	const char *session_id             = NULL;
+	const char *asr_audiof             = NULL;
+	FILE *f_pcm                        = NULL;
+	char *pcm_data                     = NULL;
+	long pcm_count                     = 0;
+	long pcm_size                      = 0;
+	int last_audio                     = 0;
+
+	int aud_stat                       = MSP_AUDIO_SAMPLE_CONTINUE;
+	int ep_status                      = MSP_EP_LOOKING_FOR_SPEECH;
+	int rec_status                     = MSP_REC_STATUS_INCOMPLETE;
+	int rss_status                     = MSP_REC_STATUS_INCOMPLETE;
+	int errcode                        = -1;
+	int aud_src                        = 0;
+
+	//离线语法识别参数设置
+	snprintf(asr_params, MAX_PARAMS_LEN - 1,
+		"engine_type = local, \
+		asr_res_path = %s, sample_rate = %d, \
+		grm_build_path = %s, local_grammar = %s, \
+		result_type = xml, result_encoding = UTF-8, ",
+		ASR_RES_PATH,
+		SAMPLE_RATE_16K,
+		GRM_BUILD_PATH,
+		udata->grammar_id
+		);
+
+	demo_mic(asr_params);
+	return 0;
+}
+
+int main(int argc, char* argv[])
+{
+	const char *login_config    = "appid = 5d5b9efd"; //登录参数
+	UserData asr_data;
+	int ret                     = 0 ;
+
+    wiringPiSetup();
+    pinMode(LED_PIN, OUTPUT);
+    pinMode(FAN_PIN, OUTPUT);
+
+	ret = MSPLogin(NULL, NULL, login_config); //第一个参数为用户名,第二个参数为密码,传NULL即可,第三个参数是登录参数
+	if (MSP_SUCCESS != ret) {
+		printf("登录失败:%d\n", ret);
+		goto exit;
+	}
+
+	memset(&asr_data, 0, sizeof(UserData));
+	printf("构建离线识别语法网络...\n");
+	ret = build_grammar(&asr_data);  //第一次使用某语法进行识别,需要先构建语法网络,获取语法ID,之后使用此语法进行识别,无需再次构建
+	if (MSP_SUCCESS != ret) {
+		printf("构建语法调用失败!\n");
+		goto exit;
+	}
+	while (1 != asr_data.build_fini)
+		usleep(300 * 1000);
+	if (MSP_SUCCESS != asr_data.errcode)
+		goto exit;
+	printf("离线识别语法网络构建完成,开始识别...\n");
+    while(1)
+    {
+        ret = run_asr(&asr_data);
+        if (MSP_SUCCESS != ret) {
+            printf("离线语法识别出错: %d \n", ret);
+            goto exit;
+        }
+    }
+
+exit:
+	MSPLogout();
+	printf("请按任意键退出...\n");
+	getchar();
+	return 0;
+}

+ 17 - 0
example/xf_aitalk/samples/asr_offline_record_sample/formats.h

@@ -0,0 +1,17 @@
+#ifndef FORMATS_H_160601_TT
+#define FORMATS_H_160601_TT		1
+
+#ifndef WAVE_FORMAT_PCM  
+#define WAVE_FORMAT_PCM  1
+typedef struct tWAVEFORMATEX {
+	unsigned short	  wFormatTag;
+	unsigned short    nChannels;
+	unsigned int      nSamplesPerSec;
+	unsigned int      nAvgBytesPerSec;
+	unsigned short	  nBlockAlign;
+	unsigned short    wBitsPerSample;
+	unsigned short    cbSize;
+} WAVEFORMATEX;
+#endif
+
+#endif

+ 707 - 0
example/xf_aitalk/samples/asr_offline_record_sample/linuxrec.c

@@ -0,0 +1,707 @@
+/*
+@file
+@brief  record demo for linux
+
+@author		taozhang9
+@date		2016/05/27
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <alsa/asoundlib.h>
+#include <signal.h>
+#include <sys/stat.h>
+#include <pthread.h>
+#include "formats.h"
+#include "linuxrec.h"
+
+#define DBG_ON 1
+
+#if DBG_ON
+#define dbg  printf
+#else
+#define dbg
+#endif
+
+
+/* Do not change the sequence */
+enum {
+	RECORD_STATE_CREATED,	/* Init		*/
+	RECORD_STATE_CLOSING,
+	RECORD_STATE_READY,		/* Opened	*/
+	RECORD_STATE_STOPPING,	/* During Stop	*/
+	RECORD_STATE_RECORDING,	/* Started	*/
+};
+
+#define SAMPLE_RATE  16000
+#define SAMPLE_BIT_SIZE 16
+#define FRAME_CNT   10
+//#define BUF_COUNT   1
+#define DEF_BUFF_TIME  500000
+#define DEF_PERIOD_TIME 100000
+
+#define DEFAULT_FORMAT		\
+{\
+	WAVE_FORMAT_PCM,	\
+	1,			\
+	16000,			\
+	32000,			\
+	2,			\
+	16,			\
+	sizeof(WAVEFORMATEX)	\
+}
+#if 0
+struct bufinfo {
+	char *data;
+	unsigned int bufsize;
+};
+#endif
+
+
+static int show_xrun = 1;
+static int start_record_internal(snd_pcm_t *pcm)
+{
+	return snd_pcm_start(pcm);
+}
+
+static int stop_record_internal(snd_pcm_t *pcm)
+{
+	return snd_pcm_drop(pcm);
+}
+
+
+static int is_stopped_internal(struct recorder *rec)
+{
+	snd_pcm_state_t state;
+
+	state =  snd_pcm_state((snd_pcm_t *)rec->wavein_hdl);
+	switch (state) {
+	case SND_PCM_STATE_RUNNING:
+	case SND_PCM_STATE_DRAINING:
+		return 0;
+	default: break;
+	}
+	return 1;
+	
+}
+
+static int format_ms_to_alsa(const WAVEFORMATEX * wavfmt, 
+						snd_pcm_format_t * format)
+{
+	snd_pcm_format_t tmp;
+	tmp = snd_pcm_build_linear_format(wavfmt->wBitsPerSample, 
+			wavfmt->wBitsPerSample, wavfmt->wBitsPerSample == 8 ? 1 : 0, 0);
+	if ( tmp == SND_PCM_FORMAT_UNKNOWN )
+		return -EINVAL;
+	*format = tmp;
+	return 0;
+}
+
+/* set hardware and software params */
+static int set_hwparams(struct recorder * rec,  const WAVEFORMATEX *wavfmt,
+			unsigned int buffertime, unsigned int periodtime)
+{
+	snd_pcm_hw_params_t *params;
+	int err;
+	unsigned int rate;
+	snd_pcm_format_t format;
+	snd_pcm_uframes_t size;
+	snd_pcm_t *handle = (snd_pcm_t *)rec->wavein_hdl;
+
+	rec->buffer_time = buffertime;
+	rec->period_time = periodtime;
+
+	snd_pcm_hw_params_alloca(&params);
+	err = snd_pcm_hw_params_any(handle, params);
+	if (err < 0) {
+		dbg("Broken configuration for this PCM");
+		return err;
+	}
+	err = snd_pcm_hw_params_set_access(handle, params,
+					   SND_PCM_ACCESS_RW_INTERLEAVED);
+	if (err < 0) {
+		dbg("Access type not available");
+		return err;
+	}
+	err = format_ms_to_alsa(wavfmt, &format);
+	if (err) {
+		dbg("Invalid format");
+		return - EINVAL;
+	}
+	err = snd_pcm_hw_params_set_format(handle, params, format);
+	if (err < 0) {
+		dbg("Sample format non available");
+		return err;
+	}
+	err = snd_pcm_hw_params_set_channels(handle, params, wavfmt->nChannels);
+	if (err < 0) {
+		dbg("Channels count non available");
+		return err;
+	}
+
+	rate = wavfmt->nSamplesPerSec;
+	err = snd_pcm_hw_params_set_rate_near(handle, params, &rate, 0);
+	if (err < 0) {
+		dbg("Set rate failed");
+		return err;
+	}
+	if(rate != wavfmt->nSamplesPerSec) {
+		dbg("Rate mismatch");
+		return -EINVAL;
+	}
+	if (rec->buffer_time == 0 || rec->period_time == 0) {
+		err = snd_pcm_hw_params_get_buffer_time_max(params,
+						    &rec->buffer_time, 0);
+		assert(err >= 0);
+		if (rec->buffer_time > 500000)
+			rec->buffer_time = 500000;
+		rec->period_time = rec->buffer_time / 4;
+	}
+	err = snd_pcm_hw_params_set_period_time_near(handle, params,
+					     &rec->period_time, 0);
+	if (err < 0) {
+		dbg("set period time fail");
+		return err;
+	}
+	err = snd_pcm_hw_params_set_buffer_time_near(handle, params,
+					     &rec->buffer_time, 0);
+	if (err < 0) {
+		dbg("set buffer time failed");
+		return err;
+	}
+	err = snd_pcm_hw_params_get_period_size(params, &size, 0);
+	if (err < 0) {
+		dbg("get period size fail");
+		return err;
+	}
+	rec->period_frames = size; 
+	err = snd_pcm_hw_params_get_buffer_size(params, &size);
+	if (size == rec->period_frames) {
+		dbg("Can't use period equal to buffer size (%lu == %lu)",
+				      size, rec->period_frames);
+		return -EINVAL;
+	}
+	rec->buffer_frames = size;
+	rec->bits_per_frame = wavfmt->wBitsPerSample;
+
+	/* set to driver */
+	err = snd_pcm_hw_params(handle, params);
+	if (err < 0) {
+		dbg("Unable to install hw params:");
+		return err;
+	}
+	return 0;
+}
+static int set_swparams(struct recorder * rec)
+{
+	int err;
+	snd_pcm_sw_params_t *swparams;
+	snd_pcm_t * handle = (snd_pcm_t*)(rec->wavein_hdl);
+	/* sw para */
+	snd_pcm_sw_params_alloca(&swparams);
+	err = snd_pcm_sw_params_current(handle, swparams);
+	if (err < 0) {
+		dbg("get current sw para fail");
+		return err;
+	}
+
+	err = snd_pcm_sw_params_set_avail_min(handle, swparams, 
+						rec->period_frames);
+	if (err < 0) {
+		dbg("set avail min failed");
+		return err;
+	}
+	/* set a value bigger than the buffer frames to prevent the auto start.
+	 * we use the snd_pcm_start to explicit start the pcm */
+	err = snd_pcm_sw_params_set_start_threshold(handle, swparams, 
+			rec->buffer_frames * 2);
+	if (err < 0) {
+		dbg("set start threshold fail");
+		return err;
+	}
+
+	if ( (err = snd_pcm_sw_params(handle, swparams)) < 0) {
+		dbg("unable to install sw params:");
+		return err;
+	}
+	return 0;
+}
+
+static int set_params(struct recorder *rec, WAVEFORMATEX *fmt,
+		unsigned int buffertime, unsigned int periodtime)
+{
+	int err;
+	WAVEFORMATEX defmt = DEFAULT_FORMAT;
+	
+	if (fmt == NULL) {
+		fmt = &defmt;
+	}
+	err = set_hwparams(rec, fmt, buffertime, periodtime);
+	if (err)
+		return err;
+	err = set_swparams(rec);
+	if (err)
+		return err;
+	return 0;
+}
+
+/*
+ *   Underrun and suspend recovery
+ */
+ 
+static int xrun_recovery(snd_pcm_t *handle, int err)
+{
+	if (err == -EPIPE) {	/* over-run */
+		if (show_xrun)
+			printf("!!!!!!overrun happend!!!!!!");
+
+		err = snd_pcm_prepare(handle);
+		if (err < 0) {
+			if (show_xrun)
+				printf("Can't recovery from overrun,"
+				"prepare failed: %s\n", snd_strerror(err));
+			return err;
+		}
+		return 0;
+	} else if (err == -ESTRPIPE) {
+		while ((err = snd_pcm_resume(handle)) == -EAGAIN)
+			usleep(200000);	/* wait until the suspend flag is released */
+		if (err < 0) {
+			err = snd_pcm_prepare(handle);
+			if (err < 0) {
+				if (show_xrun)
+					printf("Can't recovery from suspend,"
+					"prepare failed: %s\n", snd_strerror(err));
+				return err;
+			}
+		}
+		return 0;
+	}
+	return err;
+}
+static ssize_t pcm_read(struct recorder *rec, size_t rcount)
+{
+	ssize_t r;
+	size_t count = rcount;
+	char *data;
+	snd_pcm_t *handle = (snd_pcm_t *)rec->wavein_hdl;
+	if(!handle)
+		return -EINVAL;
+
+	data = rec->audiobuf;
+	while (count > 0) {
+		r = snd_pcm_readi(handle, data, count);
+		if (r == -EAGAIN || (r >= 0 && (size_t)r < count)) {
+			snd_pcm_wait(handle, 100);
+		} else if (r < 0) {
+			if(xrun_recovery(handle, r) < 0) {
+				return -1;
+			}
+		} 
+
+		if (r > 0) {
+			count -= r;
+			data += r * rec->bits_per_frame / 8;
+		}
+	}
+	return rcount;
+}
+
+static void * record_thread_proc(void * para)
+{
+	struct recorder * rec = (struct recorder *) para;
+	size_t frames, bytes;
+	sigset_t mask, oldmask;
+
+
+	sigemptyset(&mask);
+	sigaddset(&mask, SIGINT);
+	sigaddset(&mask, SIGTERM);
+	pthread_sigmask(SIG_BLOCK, &mask, &oldmask);
+
+	while(1) {
+		frames = rec->period_frames;
+		bytes = frames * rec->bits_per_frame / 8; 
+
+		/* closing, exit the thread */
+		if (rec->state == RECORD_STATE_CLOSING)
+			break;
+
+		if(rec->state < RECORD_STATE_RECORDING)
+			usleep(100000);
+
+		if (pcm_read(rec, frames) != frames) {
+			return NULL;
+		}
+
+		if (rec->on_data_ind)
+			rec->on_data_ind(rec->audiobuf, bytes, 
+					rec->user_cb_para);
+	}
+	return rec;
+
+}
+static int create_record_thread(void * para, pthread_t * tidp)
+{
+	int err;
+	err = pthread_create(tidp, NULL, record_thread_proc, (void *)para);
+	if (err != 0)
+		return err;
+
+	return 0;
+}
+
+#if 0 /* don't use it now... cuz only one buffer supported */
+static void free_rec_buffer(struct recorder * rec)
+{
+	if (rec->bufheader) {
+		unsigned int i;
+		struct bufinfo *info = (struct bufinfo *) rec->bufheader;
+
+		assert(rec->bufcount > 0);
+		for (i = 0; i < rec->bufcount; ++i) {
+			if (info->data) {
+				free(info->data);
+				info->data = NULL;
+				info->bufsize = 0;
+				info->audio_bytes = 0;
+			}
+			info++;
+		}
+		free(rec->bufheader);
+		rec->bufheader = NULL;
+	}
+	rec->bufcount = 0;
+}
+
+static int prepare_rec_buffer(struct recorder * rec )
+{
+	struct bufinfo *buffers;
+	unsigned int i;
+	int err;
+	size_t sz;
+
+	/* the read and QISRWrite is blocked, currently only support one buffer,
+	 * if overrun too much, need more buffer and another new thread
+	 * to write the audio to network */
+	rec->bufcount = 1;
+	sz = sizeof(struct bufinfo)*rec->bufcount;
+	buffers=(struct bufinfo*)malloc(sz);
+	if (!buffers) {
+		rec->bufcount = 0;
+		goto fail;
+	}
+	memset(buffers, 0, sz);
+	rec->bufheader = buffers;
+
+	for (i = 0; i < rec->bufcount; ++i) {
+		buffers[i].bufsize = 
+			(rec->period_frames * rec->bits_per_frame / 8);
+		buffers[i].data = (char *)malloc(buffers[i].bufsize);
+		if (!buffers[i].data) {
+			buffers[i].bufsize = 0;
+			goto fail;
+		}
+		buffers[i].audio_bytes = 0;
+	}
+	return 0;
+fail:
+	free_rec_buffer(rec);
+	return -ENOMEM;
+}
+#else
+static void free_rec_buffer(struct recorder * rec)
+{
+	if (rec->audiobuf) {
+		free(rec->audiobuf);
+		rec->audiobuf = NULL;
+	}
+}
+
+static int prepare_rec_buffer(struct recorder * rec )
+{
+	/* the read and QISRWrite is blocked, currently only support one buffer,
+	 * if overrun too much, need more buffer and another new thread
+	 * to write the audio to network */
+	size_t sz = (rec->period_frames * rec->bits_per_frame / 8);
+	rec->audiobuf = (char *)malloc(sz);
+	if(!rec->audiobuf)
+		return -ENOMEM;
+	return 0;
+}
+#endif
+
+static int open_recorder_internal(struct recorder * rec, 
+		record_dev_id dev, WAVEFORMATEX * fmt)
+{
+	int err = 0;
+
+	err = snd_pcm_open((snd_pcm_t **)&rec->wavein_hdl, dev.u.name, 
+			SND_PCM_STREAM_CAPTURE, 0);
+	if(err < 0)
+		goto fail;
+
+	err = set_params(rec, fmt, DEF_BUFF_TIME, DEF_PERIOD_TIME);
+	if(err)
+		goto fail;
+
+	assert(rec->bufheader == NULL);
+	err = prepare_rec_buffer(rec);
+	if(err)
+		goto fail;
+
+	err = create_record_thread((void*)rec, 
+			&rec->rec_thread);
+	if(err)
+		goto fail;
+	
+
+	return 0;
+fail:
+	if(rec->wavein_hdl)
+		snd_pcm_close((snd_pcm_t *) rec->wavein_hdl);
+	rec->wavein_hdl = NULL;
+	free_rec_buffer(rec);
+	return err;
+}
+
+static void close_recorder_internal(struct recorder *rec)
+{
+	snd_pcm_t * handle;
+
+	handle = (snd_pcm_t *) rec->wavein_hdl;
+
+	/* may be the thread is blocked at read, cancel it */
+	pthread_cancel(rec->rec_thread);
+	
+	/* wait for the pcm thread quit first */
+	pthread_join(rec->rec_thread, NULL);
+
+	if(handle) {
+		snd_pcm_close(handle);
+		rec->wavein_hdl = NULL;
+	}
+	free_rec_buffer(rec);
+}
+/* return the count of pcm device */
+/* list all cards */
+static int get_pcm_device_cnt(snd_pcm_stream_t stream)
+{
+	void **hints, **n;
+	char *io, *filter, *name;
+	int cnt = 0;
+
+	if (snd_device_name_hint(-1, "pcm", &hints) < 0)
+		return 0;
+	n = hints;
+	filter = stream == SND_PCM_STREAM_CAPTURE ? "Input" : "Output";
+	while (*n != NULL) {
+		io = snd_device_name_get_hint(*n, "IOID");
+		name = snd_device_name_get_hint(*n, "NAME");
+		if (name && (io == NULL || strcmp(io, filter) == 0))
+			cnt ++;
+		if (io != NULL)
+			free(io);
+		if (name != NULL)
+			free(name);
+		n++;
+	}
+	snd_device_name_free_hint(hints);
+	return cnt;
+}
+
+static void free_name_desc(char **name_or_desc) 
+{
+	char **ss;
+	ss = name_or_desc;
+	if(NULL == name_or_desc)
+		return;
+	while(*name_or_desc) {
+		free(*name_or_desc);
+		*name_or_desc = NULL;
+		name_or_desc++;
+	}
+	free(ss);
+}
+/* return success: total count, need free the name and desc buffer 
+ * fail: -1 , *name_out and *desc_out will be NULL */
+static int list_pcm(snd_pcm_stream_t stream, char**name_out, 
+						char ** desc_out)
+{
+	void **hints, **n;
+	char **name, **descr;
+	char *io;
+	const char *filter;
+	int cnt = 0;
+	int i = 0;
+
+	if (snd_device_name_hint(-1, "pcm", &hints) < 0)
+		return 0;
+	n = hints;
+	cnt = get_pcm_device_cnt(stream);
+	if(!cnt) {
+		goto fail; 
+	}
+
+	*name_out = calloc(sizeof(char *) , (1+cnt));
+	if (*name_out == NULL)
+		goto fail;
+	*desc_out = calloc(sizeof(char *) , (1 + cnt));
+	if (*desc_out == NULL)
+		goto fail;
+
+	/* the last one is a flag, NULL */
+	name_out[cnt] = NULL;
+	desc_out[cnt] = NULL;
+	name = name_out;
+	descr = desc_out;
+
+	filter = stream == SND_PCM_STREAM_CAPTURE ? "Input" : "Output";
+	while (*n != NULL && i < cnt) {
+		*name = snd_device_name_get_hint(*n, "NAME");
+		*descr = snd_device_name_get_hint(*n, "DESC");
+		io = snd_device_name_get_hint(*n, "IOID");
+		if (name == NULL || 
+			(io != NULL && strcmp(io, filter) != 0) ){
+			if (*name) free(*name);
+			if (*descr) free(*descr);
+		} else {
+			if (*descr == NULL) {
+				*descr = malloc(4);
+				memset(*descr, 0, 4);
+			}
+			name++;
+			descr++;
+			i++;
+		}
+		if (io != NULL)
+			free(io);
+		n++;
+	}
+	snd_device_name_free_hint(hints);
+	return cnt;
+fail:
+	free_name_desc(name_out);
+	free_name_desc(desc_out);
+	snd_device_name_free_hint(hints);
+	return -1;
+}
+/* -------------------------------------
+ * Interfaces 
+ --------------------------------------*/ 
+/* the device id is a pcm string name in linux */
+record_dev_id  get_default_input_dev()
+{
+	record_dev_id id; 
+	id.u.name = "default";
+	return id;
+}
+
+record_dev_id * list_input_device() 
+{
+	// TODO: unimplemented
+	return NULL;
+}
+
+int get_input_dev_num()
+{
+	return get_pcm_device_cnt(SND_PCM_STREAM_CAPTURE);
+}
+
+
+/* callback will be run on a new thread */
+int create_recorder(struct recorder ** out_rec, 
+				void (*on_data_ind)(char *data, unsigned long len, void *user_cb_para), 
+				void* user_cb_para)
+{
+	struct recorder * myrec;
+	myrec = (struct recorder *)malloc(sizeof(struct recorder));
+	if(!myrec)
+		return -RECORD_ERR_MEMFAIL;
+
+	memset(myrec, 0, sizeof(struct recorder));
+	myrec->on_data_ind = on_data_ind;
+	myrec->user_cb_para = user_cb_para;
+	myrec->state = RECORD_STATE_CREATED;
+
+	*out_rec = myrec;
+	return 0;
+}
+
+void destroy_recorder(struct recorder *rec)
+{
+	if(!rec)
+		return;
+
+	free(rec);
+}
+
+int open_recorder(struct recorder * rec, record_dev_id dev, WAVEFORMATEX * fmt)
+{
+	int ret = 0;
+	if(!rec )
+		return -RECORD_ERR_INVAL;
+	if(rec->state >= RECORD_STATE_READY)
+		return 0;
+
+	ret = open_recorder_internal(rec, dev, fmt);
+	if(ret == 0)
+		rec->state = RECORD_STATE_READY;
+	return 0;
+
+}
+
+void close_recorder(struct recorder *rec)
+{
+	if(rec == NULL || rec->state < RECORD_STATE_READY)
+		return;
+	if(rec->state == RECORD_STATE_RECORDING)
+		stop_record(rec);
+
+	rec->state = RECORD_STATE_CLOSING;
+
+	close_recorder_internal(rec);
+
+	rec->state = RECORD_STATE_CREATED;	
+}
+
+int start_record(struct recorder * rec)
+{
+	int ret;
+	if(rec == NULL)
+		return -RECORD_ERR_INVAL;
+	if( rec->state < RECORD_STATE_READY)
+		return -RECORD_ERR_NOT_READY;
+	if( rec->state == RECORD_STATE_RECORDING)
+		return 0;
+
+	ret = start_record_internal((snd_pcm_t *)rec->wavein_hdl);
+	if(ret == 0)
+		rec->state = RECORD_STATE_RECORDING;
+	return ret;
+}
+
+int stop_record(struct recorder * rec)
+{
+	int ret;
+	if(rec == NULL)
+		return -RECORD_ERR_INVAL;
+	if( rec->state < RECORD_STATE_RECORDING)
+		return 0;
+
+	rec->state = RECORD_STATE_STOPPING;
+	ret = stop_record_internal((snd_pcm_t *)rec->wavein_hdl);
+	if(ret == 0) {		
+		rec->state = RECORD_STATE_READY;
+	}
+	return ret;
+}
+
+int is_record_stopped(struct recorder *rec)
+{
+	if(rec->state == RECORD_STATE_RECORDING)
+		return 0;
+
+	return is_stopped_internal(rec);
+}

+ 156 - 0
example/xf_aitalk/samples/asr_offline_record_sample/linuxrec.h

@@ -0,0 +1,156 @@
+/*
+ * @file
+ * @brief a record demo in linux
+ *
+ * a simple record code. using alsa-lib APIs.
+ * keep the function same as winrec.h
+ *
+ * Common steps:
+ *	create_recorder,
+ *	open_recorder, 
+ *	start_record, 
+ *	stop_record, 
+ *	close_recorder,
+ *	destroy_recorder
+ *
+ * @author		taozhang9
+ * @date		2016/06/01
+ */
+
+#ifndef __IFLY_WINREC_H__
+#define __IFLY_WINREC_H__
+
+#include "formats.h"
+/* error code */
+enum {
+	RECORD_ERR_BASE = 0,
+	RECORD_ERR_GENERAL,
+	RECORD_ERR_MEMFAIL,
+	RECORD_ERR_INVAL,
+	RECORD_ERR_NOT_READY
+};
+
+typedef struct {
+	union {
+		char *	name;
+		int	index;
+		void *	resv;
+	}u;
+}record_dev_id;
+
+/* recorder object. */
+struct recorder {
+	void (*on_data_ind)(char *data, unsigned long len, void *user_para);
+	void * user_cb_para;
+	volatile int state;		/* internal record state */
+
+	void * wavein_hdl;
+	/* thread id may be a struct. by implementation 
+	 * void * will not be ported!! */
+	pthread_t rec_thread; 
+	/*void * rec_thread_hdl;*/
+
+	void * bufheader;
+	unsigned int bufcount; 
+	
+	char *audiobuf;
+	int bits_per_frame;
+	unsigned int buffer_time;
+	unsigned int period_time;
+	size_t period_frames;
+	size_t buffer_frames;
+};
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+
+/** 
+ * @fn
+ * @brief	Get the default input device ID
+ *
+ * @return	returns "default" in linux.
+ *
+ */
+record_dev_id get_default_input_dev();
+
+/**
+ * @fn 
+ * @brief	Get the total number of active input devices.
+ * @return	
+ */
+int get_input_dev_num();
+
+/**
+ * @fn 
+ * @brief	Create a recorder object.
+ *
+ * Never call the close_recorder in the callback function. as close
+ * action will wait for the callback thread to quit. 
+ *
+ * @return	int			- Return 0 in success, otherwise return error code.
+ * @param	out_rec		- [out] recorder object holder
+ * @param	on_data_ind	- [in]	callback. called when data coming.
+ * @param	user_cb_para	- [in] user params for the callback.
+ * @see
+ */
+int create_recorder(struct recorder ** out_rec, 
+				void (*on_data_ind)(char *data, unsigned long len, void *user_para), 
+				void* user_cb_para);
+
+/**
+ * @fn 
+ * @brief	Destroy recorder object. free memory. 
+ * @param	rec	- [in]recorder object
+ */
+void destroy_recorder(struct recorder *rec);
+
+/**
+ * @fn 
+ * @brief	open the device.
+ * @return	int			- Return 0 in success, otherwise return error code.
+ * @param	rec			- [in] recorder object
+ * @param	dev			- [in] device id, from 0.
+ * @param	fmt			- [in] record format.
+ * @see
+ * 	get_default_input_dev()
+ */
+int open_recorder(struct recorder * rec, record_dev_id dev, WAVEFORMATEX * fmt);
+
+/**
+ * @fn
+ * @brief	close the device.
+ * @param	rec			- [in] recorder object
+ */
+
+void close_recorder(struct recorder *rec);
+
+/**
+ * @fn
+ * @brief	start record.
+ * @return	int			- Return 0 in success, otherwise return error code.
+ * @param	rec			- [in] recorder object
+ */
+int start_record(struct recorder * rec);
+
+/**
+ * @fn
+ * @brief	stop record.
+ * @return	int			- Return 0 in success, otherwise return error code.
+ * @param	rec			- [in] recorder object
+ */
+int stop_record(struct recorder * rec);
+
+/**
+ * @fn
+ * @brief	test if the recording has been stopped.
+ * @return	int			- 1: stopped. 0 : recording.
+ * @param	rec			- [in] recorder object
+ */
+int is_record_stopped(struct recorder *rec);
+
+#ifdef __cplusplus
+} /* extern "C" */	
+#endif /* C++ */
+
+#endif

+ 4 - 0
example/xf_aitalk/samples/asr_offline_record_sample/make.sh

@@ -0,0 +1,4 @@
+#编译32位可执行文件
+make clean;make
+#设置libmsc.so库搜索路径
+export LD_LIBRARY_PATH=$(pwd)/../../libs/

+ 374 - 0
example/xf_aitalk/samples/asr_offline_record_sample/speech_recognizer.c

@@ -0,0 +1,374 @@
+/*
+@file
+@brief a simple demo to recognize speech from microphone
+
+@author		taozhang9
+@date		2016/05/27
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include "speech_recognizer.h"
+#include "../../include/qisr.h"
+#include "../../include/msp_cmn.h"
+#include "../../include/msp_errors.h"
+#include "linuxrec.h"
+
+
+#define SR_DBGON 1
+#if SR_DBGON == 1
+#	define sr_dbg printf
+#else
+#	define sr_dbg
+#endif
+
+#define DEFAULT_SESSION_PARA \
+	 "sub = iat, domain = iat, language = zh_cn, accent = mandarin, sample_rate = 16000, result_type = plain, result_encoding = UTF-8"
+
+#define DEFAULT_FORMAT		\
+{\
+	WAVE_FORMAT_PCM,	\
+	1,			\
+	16000,			\
+	32000,			\
+	2,			\
+	16,			\
+	sizeof(WAVEFORMATEX)	\
+}
+
+/* internal state */
+enum {
+	SR_STATE_INIT,
+	SR_STATE_STARTED
+};
+
+
+#define SR_MALLOC malloc
+#define SR_MFREE  free
+#define SR_MEMSET	memset
+
+
+static void Sleep(size_t ms)
+{
+	usleep(ms*1000);
+}
+
+
+static void end_sr_on_error(struct speech_rec *sr, int errcode)
+{
+	if(sr->aud_src == SR_MIC)
+		stop_record(sr->recorder);
+	
+	if (sr->session_id) {
+		if (sr->notif.on_speech_end)
+			sr->notif.on_speech_end(errcode);
+
+		QISRSessionEnd(sr->session_id, "err");
+		sr->session_id = NULL;
+	}
+	sr->state = SR_STATE_INIT;
+}
+
+static void end_sr_on_vad(struct speech_rec *sr)
+{
+	int errcode;
+	const char *rslt;
+
+	if (sr->aud_src == SR_MIC)
+		stop_record(sr->recorder);	
+	sr->rec_stat = MSP_AUDIO_SAMPLE_CONTINUE;
+	while(sr->rec_stat != MSP_REC_STATUS_COMPLETE ){
+		rslt = QISRGetResult(sr->session_id, &sr->rec_stat, 0, &errcode);
+		if (rslt && sr->notif.on_result)
+			sr->notif.on_result(rslt, sr->rec_stat == MSP_REC_STATUS_COMPLETE ? 1 : 0);
+
+		Sleep(100); /* for cpu occupy, should sleep here */
+	}
+
+	if (sr->session_id) {
+		if (sr->notif.on_speech_end)
+			sr->notif.on_speech_end(END_REASON_VAD_DETECT);
+		QISRSessionEnd(sr->session_id, "VAD Normal");
+		sr->session_id = NULL;
+	}
+	sr->state = SR_STATE_INIT;
+}
+
+/* the record call back */
+static void iat_cb(char *data, unsigned long len, void *user_para)
+{
+	int errcode;
+	struct speech_rec *sr;
+
+	if(len == 0 || data == NULL)
+		return;
+
+	sr = (struct speech_rec *)user_para;
+
+	if(sr == NULL || sr->ep_stat >= MSP_EP_AFTER_SPEECH)
+		return;
+	if (sr->state < SR_STATE_STARTED)
+		return; /* ignore the data if error/vad happened */
+	
+	errcode = sr_write_audio_data(sr, data, len);
+	if (errcode) {
+		end_sr_on_error(sr, errcode);
+		return;
+	}
+}
+
+static char * skip_space(char *s)
+{
+	while (s && *s != ' ' && *s != '\0')
+		s++;
+	return s;
+}
+static int update_format_from_sessionparam(const char * session_para, WAVEFORMATEX *wavefmt)
+{
+	char *s;
+	if ((s = strstr(session_para, "sample_rate"))) {
+		s = strstr(s, "=");
+		if (s && *s) {
+			s = skip_space(s);
+			if (s && *s) {
+				wavefmt->nSamplesPerSec = atoi(s);
+				wavefmt->nAvgBytesPerSec = wavefmt->nBlockAlign * wavefmt->nSamplesPerSec;
+			}
+		}
+		else
+			return -1;
+	}
+	else {
+		return -1;
+	}
+
+	return 0;
+}
+
+/* devid will be ignored if aud_src is not SR_MIC ; use get_default_dev_id
+ * to use the default input device. Currently the device list function is
+ * not provided yet. 
+ */
+
+int sr_init_ex(struct speech_rec * sr, const char * session_begin_params, 
+			enum sr_audsrc aud_src, record_dev_id devid, 
+				struct speech_rec_notifier * notify)
+{
+	int errcode;
+	size_t param_size;
+	WAVEFORMATEX wavfmt = DEFAULT_FORMAT;
+
+	if (aud_src == SR_MIC && get_input_dev_num() == 0) {
+		return -E_SR_NOACTIVEDEVICE;
+	}
+
+	if (!sr)
+		return -E_SR_INVAL;
+
+	if (session_begin_params == NULL) {
+		session_begin_params = DEFAULT_SESSION_PARA;
+	}
+
+	SR_MEMSET(sr, 0, sizeof(struct speech_rec));
+	sr->state = SR_STATE_INIT;
+	sr->aud_src = aud_src;
+	sr->ep_stat = MSP_EP_LOOKING_FOR_SPEECH;
+	sr->rec_stat = MSP_REC_STATUS_SUCCESS;
+	sr->audio_status = MSP_AUDIO_SAMPLE_FIRST;
+
+	param_size = strlen(session_begin_params) + 1;
+	sr->session_begin_params = (char*)SR_MALLOC(param_size);
+	if (sr->session_begin_params == NULL) {
+		sr_dbg("mem alloc failed\n");
+		return -E_SR_NOMEM;
+	}
+	strncpy(sr->session_begin_params, session_begin_params, param_size);
+
+	sr->notif = *notify;
+	
+	if (aud_src == SR_MIC) {
+		errcode = create_recorder(&sr->recorder, iat_cb, (void*)sr);
+		if (sr->recorder == NULL || errcode != 0) {
+			sr_dbg("create recorder failed: %d\n", errcode);
+			errcode = -E_SR_RECORDFAIL;
+			goto fail;
+		}
+		update_format_from_sessionparam(session_begin_params, &wavfmt);
+	
+		errcode = open_recorder(sr->recorder, devid, &wavfmt);
+		if (errcode != 0) {
+			sr_dbg("recorder open failed: %d\n", errcode);
+			errcode = -E_SR_RECORDFAIL;
+			goto fail;
+		}
+	}
+
+	return 0;
+
+fail:
+	if (sr->recorder) {
+		destroy_recorder(sr->recorder);
+		sr->recorder = NULL;
+	}
+
+	if (sr->session_begin_params) {
+		SR_MFREE(sr->session_begin_params);
+		sr->session_begin_params = NULL;
+	}
+	SR_MEMSET(&sr->notif, 0, sizeof(sr->notif));
+
+	return errcode;
+}
+
+/* use the default input device to capture the audio. see sr_init_ex */
+int sr_init(struct speech_rec * sr, const char * session_begin_params, 
+		enum sr_audsrc aud_src, struct speech_rec_notifier * notify)
+{
+	return sr_init_ex(sr, session_begin_params, aud_src, 
+			get_default_input_dev(), notify);
+}
+
+int sr_start_listening(struct speech_rec *sr)
+{
+	int ret;
+	const char*		session_id = NULL;
+	int				errcode = MSP_SUCCESS;
+
+	if (sr->state >= SR_STATE_STARTED) {
+		sr_dbg("already STARTED.\n");
+		return -E_SR_ALREADY;
+	}
+
+	session_id = QISRSessionBegin(NULL, sr->session_begin_params, &errcode); //听写不需要语法,第一个参数为NULL
+	if (MSP_SUCCESS != errcode)
+	{
+		sr_dbg("\nQISRSessionBegin failed! error code:%d\n", errcode);
+		return errcode;
+	}
+	sr->session_id = session_id;
+	sr->ep_stat = MSP_EP_LOOKING_FOR_SPEECH;
+	sr->rec_stat = MSP_REC_STATUS_SUCCESS;
+	sr->audio_status = MSP_AUDIO_SAMPLE_FIRST;
+
+	if (sr->aud_src == SR_MIC) {
+		ret = start_record(sr->recorder);
+		if (ret != 0) {
+			sr_dbg("start record failed: %d\n", ret);
+			QISRSessionEnd(session_id, "start record fail");
+			sr->session_id = NULL;
+			return -E_SR_RECORDFAIL;
+		}
+	}
+
+	sr->state = SR_STATE_STARTED;
+
+	if (sr->notif.on_speech_begin)
+		sr->notif.on_speech_begin();
+
+	return 0;
+}
+
+/* after stop_record, there are still some data callbacks */
+static void wait_for_rec_stop(struct recorder *rec, unsigned int timeout_ms)
+{
+	while (!is_record_stopped(rec)) {
+		Sleep(1);
+		if (timeout_ms != (unsigned int)-1)
+			if (0 == timeout_ms--)
+				break;
+	}
+}
+
+int sr_stop_listening(struct speech_rec *sr)
+{
+	int ret = 0;
+	const char * rslt = NULL;
+
+	if (sr->state < SR_STATE_STARTED) {
+		sr_dbg("Not started or already stopped.\n");
+		return 0;
+	}
+
+	if (sr->aud_src == SR_MIC) {
+		ret = stop_record(sr->recorder);
+		if (ret != 0) {
+			sr_dbg("Stop failed! \n");
+			return -E_SR_RECORDFAIL;
+		}
+		wait_for_rec_stop(sr->recorder, (unsigned int)-1);
+	}
+	sr->state = SR_STATE_INIT;
+	ret = QISRAudioWrite(sr->session_id, NULL, 0, MSP_AUDIO_SAMPLE_LAST, &sr->ep_stat, &sr->rec_stat);
+	if (ret != 0) {
+		sr_dbg("write LAST_SAMPLE failed: %d\n", ret);
+		QISRSessionEnd(sr->session_id, "write err");
+		return ret;
+	}
+	sr->rec_stat = 2;
+	while (sr->rec_stat != MSP_REC_STATUS_COMPLETE) {
+		rslt = QISRGetResult(sr->session_id, &sr->rec_stat, 0, &ret);
+		if (MSP_SUCCESS != ret)	{
+			sr_dbg("\nQISRGetResult failed! error code: %d\n", ret);
+			end_sr_on_error(sr, ret);
+			return ret;
+		}
+		if (NULL != rslt && sr->notif.on_result)
+			sr->notif.on_result(rslt, sr->rec_stat == MSP_REC_STATUS_COMPLETE ? 1 : 0);
+		Sleep(100);
+	}
+
+	QISRSessionEnd(sr->session_id, "normal");
+	sr->session_id = NULL;
+	return 0;
+}
+
+int sr_write_audio_data(struct speech_rec *sr, char *data, unsigned int len)
+{
+	const char *rslt = NULL;
+	int ret = 0;
+	if (!sr )
+		return -E_SR_INVAL;
+	if (!data || !len)
+		return 0;
+
+	ret = QISRAudioWrite(sr->session_id, data, len, sr->audio_status, &sr->ep_stat, &sr->rec_stat);
+	if (ret) {
+		end_sr_on_error(sr, ret);
+		return ret;
+	}
+	sr->audio_status = MSP_AUDIO_SAMPLE_CONTINUE;
+
+	if (MSP_REC_STATUS_SUCCESS == sr->rec_stat) { //已经有部分听写结果
+		rslt = QISRGetResult(sr->session_id, &sr->rec_stat, 0, &ret);
+		if (MSP_SUCCESS != ret)	{
+			sr_dbg("\nQISRGetResult failed! error code: %d\n", ret);
+			end_sr_on_error(sr, ret);
+			return ret;
+		}
+		if (NULL != rslt && sr->notif.on_result)
+			sr->notif.on_result(rslt, sr->rec_stat == MSP_REC_STATUS_COMPLETE ? 1 : 0);
+	}
+
+	if (MSP_EP_AFTER_SPEECH == sr->ep_stat)
+		end_sr_on_vad(sr);
+
+	return 0;
+}
+
+void sr_uninit(struct speech_rec * sr)
+{
+	if (sr->recorder) {
+		if(!is_record_stopped(sr->recorder))
+			stop_record(sr->recorder);
+		close_recorder(sr->recorder);
+		destroy_recorder(sr->recorder);
+		sr->recorder = NULL;
+	}
+
+	if (sr->session_begin_params) {
+		SR_MFREE(sr->session_begin_params);
+		sr->session_begin_params = NULL;
+	}
+}

+ 63 - 0
example/xf_aitalk/samples/asr_offline_record_sample/speech_recognizer.h

@@ -0,0 +1,63 @@
+/*
+@file
+@brief 基于录音接口和讯飞MSC接口封装一个MIC录音识别的模块
+
+@author		taozhang9
+@date		2016/05/27
+*/
+
+
+enum sr_audsrc
+{
+	SR_MIC,	/* write data from mic */
+	SR_USER	/* write data from user by calling API */
+};
+
+//#define DEFAULT_INPUT_DEVID     (-1)
+
+
+#define E_SR_NOACTIVEDEVICE		1
+#define E_SR_NOMEM				2
+#define E_SR_INVAL				3
+#define E_SR_RECORDFAIL			4
+#define E_SR_ALREADY			5
+
+
+struct speech_rec_notifier {
+	void (*on_result)(const char *result, char is_last);
+	void (*on_speech_begin)();
+	void (*on_speech_end)(int reason);	/* 0 if VAD.  others, error : see E_SR_xxx and msp_errors.h  */
+};
+
+#define END_REASON_VAD_DETECT	0	/* detected speech done  */
+
+struct speech_rec {
+	enum sr_audsrc aud_src;  /* from mic or manual  stream write */
+	struct speech_rec_notifier notif;
+	const char * session_id;
+	int ep_stat;
+	int rec_stat;
+	int audio_status;
+	struct recorder *recorder;
+	volatile int state;
+	char * session_begin_params;
+};
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* must init before start . is aud_src is SR_MIC, the default capture device
+ * will be used. see sr_init_ex */
+int sr_init(struct speech_rec * sr, const char * session_begin_params, enum sr_audsrc aud_src, struct speech_rec_notifier * notifier);
+int sr_start_listening(struct speech_rec *sr);
+int sr_stop_listening(struct speech_rec *sr);
+/* only used for the manual write way. */
+int sr_write_audio_data(struct speech_rec *sr, char *data, unsigned int len);
+/* must call uninit after you don't use it */
+void sr_uninit(struct speech_rec * sr);
+
+#ifdef __cplusplus
+} /* extern "C" */	
+#endif /* C++ */

+ 4 - 0
example/xf_aitalk/samples/asr_offline_sample/32bit_make.sh

@@ -0,0 +1,4 @@
+#编译32位可执行文件
+make clean;make
+#设置libmsc.so库搜索路径
+export LD_LIBRARY_PATH=$(pwd)/../../libs/x86/

+ 4 - 0
example/xf_aitalk/samples/asr_offline_sample/64bit_make.sh

@@ -0,0 +1,4 @@
+#编译64位可执行文件
+make clean;make LINUX64=1
+#设置libmsc.so库搜索路径
+export LD_LIBRARY_PATH=$(pwd)/../../libs/x64/

+ 32 - 0
example/xf_aitalk/samples/asr_offline_sample/Makefile

@@ -0,0 +1,32 @@
+#common makefile header
+
+DIR_INC = ../../include
+DIR_BIN = ../../bin
+DIR_LIB = ../../libs
+
+TARGET	= asr_offline_sample
+BIN_TARGET = $(DIR_BIN)/$(TARGET)
+
+CROSS_COMPILE = 
+CFLAGS = -g -Wall -I$(DIR_INC)
+
+ifdef LINUX64
+LDFLAGS := -L$(DIR_LIB)/x64
+else
+LDFLAGS := -L$(DIR_LIB)/x86 
+endif
+LDFLAGS += -lmsc -lrt -ldl -lpthread  -lstdc++
+
+OBJECTS := $(patsubst %.c,%.o,$(wildcard *.c))
+
+$(BIN_TARGET) : $(OBJECTS)
+	$(CROSS_COMPILE)gcc $(CFLAGS) $^ -o $@ $(LDFLAGS)
+
+%.o : %.c
+	$(CROSS_COMPILE)gcc -c $(CFLAGS) $< -o $@
+clean:
+	@rm -f *.o $(BIN_TARGET)
+
+.PHONY:clean
+
+#common makefile foot

+ 330 - 0
example/xf_aitalk/samples/asr_offline_sample/asr_offline_sample.c

@@ -0,0 +1,330 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+
+#include "../../include/qisr.h"
+#include "../../include/msp_cmn.h"
+#include "../../include/msp_errors.h"
+
+#define SAMPLE_RATE_16K     (16000)
+#define SAMPLE_RATE_8K      (8000)
+#define MAX_GRAMMARID_LEN   (32)
+#define MAX_PARAMS_LEN      (1024)
+
+const char * ASR_RES_PATH        = "fo|res/asr/common.jet"; //离线语法识别资源路径
+const char * GRM_BUILD_PATH      = "res/asr/GrmBuilld"; //构建离线语法识别网络生成数据保存路径
+const char * GRM_FILE            = "call.bnf"; //构建离线识别语法网络所用的语法文件
+const char * LEX_NAME            = "contact"; //更新离线识别语法的contact槽(语法文件为此示例中使用的call.bnf)
+
+typedef struct _UserData {
+	int     build_fini; //标识语法构建是否完成
+	int     update_fini; //标识更新词典是否完成
+	int     errcode; //记录语法构建或更新词典回调错误码
+	char    grammar_id[MAX_GRAMMARID_LEN]; //保存语法构建返回的语法ID
+}UserData;
+
+
+const char *get_audio_file(void); //选择进行离线语法识别的语音文件
+int build_grammar(UserData *udata); //构建离线识别语法网络
+int update_lexicon(UserData *udata); //更新离线识别语法词典
+int run_asr(UserData *udata); //进行离线语法识别
+
+const char* get_audio_file(void)
+{
+	char key = 0;
+	while(key != 27) //按Esc则退出
+	{
+		printf("请选择音频文件:\n");
+		printf("1.打电话给丁伟\n");
+		printf("2.打电话给黄辣椒\n");
+		key = getchar();
+		getchar();
+		switch(key)
+		{
+		case '1':
+			printf("\n1.打电话给丁伟\n");
+			return "wav/ddhgdw.pcm";
+		case '2':
+			printf("\n2.打电话给黄辣椒\n");
+			return "wav/ddhghlj.pcm";
+		default:
+			continue;
+		}
+	}
+	exit(0);
+	return NULL;
+}
+
+int build_grm_cb(int ecode, const char *info, void *udata)
+{
+	UserData *grm_data = (UserData *)udata;
+
+	if (NULL != grm_data) {
+		grm_data->build_fini = 1;
+		grm_data->errcode = ecode;
+	}
+
+	if (MSP_SUCCESS == ecode && NULL != info) {
+		printf("构建语法成功! 语法ID:%s\n", info);
+		if (NULL != grm_data)
+			snprintf(grm_data->grammar_id, MAX_GRAMMARID_LEN - 1, info);
+	}
+	else
+		printf("构建语法失败!%d\n", ecode);
+
+	return 0;
+}
+
+int build_grammar(UserData *udata)
+{
+	FILE *grm_file                           = NULL;
+	char *grm_content                        = NULL;
+	unsigned int grm_cnt_len                 = 0;
+	char grm_build_params[MAX_PARAMS_LEN]    = {NULL};
+	int ret                                  = 0;
+
+	grm_file = fopen(GRM_FILE, "rb");	
+	if(NULL == grm_file) {
+		printf("打开\"%s\"文件失败![%s]\n", GRM_FILE, strerror(errno));
+		return -1; 
+	}
+
+	fseek(grm_file, 0, SEEK_END);
+	grm_cnt_len = ftell(grm_file);
+	fseek(grm_file, 0, SEEK_SET);
+
+	grm_content = (char *)malloc(grm_cnt_len + 1);
+	if (NULL == grm_content)
+	{
+		printf("内存分配失败!\n");
+		fclose(grm_file);
+		grm_file = NULL;
+		return -1;
+	}
+	fread((void*)grm_content, 1, grm_cnt_len, grm_file);
+	grm_content[grm_cnt_len] = '\0';
+	fclose(grm_file);
+	grm_file = NULL;
+
+	snprintf(grm_build_params, MAX_PARAMS_LEN - 1, 
+		"engine_type = local, \
+		asr_res_path = %s, sample_rate = %d, \
+		grm_build_path = %s, ",
+		ASR_RES_PATH,
+		SAMPLE_RATE_16K,
+		GRM_BUILD_PATH
+		);
+	ret = QISRBuildGrammar("bnf", grm_content, grm_cnt_len, grm_build_params, build_grm_cb, udata);
+
+	free(grm_content);
+	grm_content = NULL;
+
+	return ret;
+}
+
+int update_lex_cb(int ecode, const char *info, void *udata)
+{
+	UserData *lex_data = (UserData *)udata;
+
+	if (NULL != lex_data) {
+		lex_data->update_fini = 1;
+		lex_data->errcode = ecode;
+	}
+
+	if (MSP_SUCCESS == ecode)
+		printf("更新词典成功!\n");
+	else
+		printf("更新词典失败!%d\n", ecode);
+
+	return 0;
+}
+
+int update_lexicon(UserData *udata)
+{
+	const char *lex_content                   = "丁伟\n黄辣椒";
+	unsigned int lex_cnt_len                  = strlen(lex_content);
+	char update_lex_params[MAX_PARAMS_LEN]    = {NULL}; 
+
+	snprintf(update_lex_params, MAX_PARAMS_LEN - 1, 
+		"engine_type = local, text_encoding = UTF-8, \
+		asr_res_path = %s, sample_rate = %d, \
+		grm_build_path = %s, grammar_list = %s, ",
+		ASR_RES_PATH,
+		SAMPLE_RATE_16K,
+		GRM_BUILD_PATH,
+		udata->grammar_id);
+	return QISRUpdateLexicon(LEX_NAME, lex_content, lex_cnt_len, update_lex_params, update_lex_cb, udata);
+}
+
+int run_asr(UserData *udata)
+{
+	char asr_params[MAX_PARAMS_LEN]    = {NULL};
+	const char *rec_rslt               = NULL;
+	const char *session_id             = NULL;
+	const char *asr_audiof             = NULL;
+	FILE *f_pcm                        = NULL;
+	char *pcm_data                     = NULL;
+	long pcm_count                     = 0;
+	long pcm_size                      = 0;
+	int last_audio                     = 0;
+	int aud_stat                       = MSP_AUDIO_SAMPLE_CONTINUE;
+	int ep_status                      = MSP_EP_LOOKING_FOR_SPEECH;
+	int rec_status                     = MSP_REC_STATUS_INCOMPLETE;
+	int rss_status                     = MSP_REC_STATUS_INCOMPLETE;
+	int errcode                        = -1;
+
+	asr_audiof = get_audio_file();
+	f_pcm = fopen(asr_audiof, "rb");
+	if (NULL == f_pcm) {
+		printf("打开\"%s\"失败![%s]\n", f_pcm, strerror(errno));
+		goto run_error;
+	}
+	fseek(f_pcm, 0, SEEK_END);
+	pcm_size = ftell(f_pcm);
+	fseek(f_pcm, 0, SEEK_SET);
+	pcm_data = (char *)malloc(pcm_size);
+	if (NULL == pcm_data)
+		goto run_error;
+	fread((void *)pcm_data, pcm_size, 1, f_pcm);
+	fclose(f_pcm);
+	f_pcm = NULL;
+
+	//离线语法识别参数设置
+	snprintf(asr_params, MAX_PARAMS_LEN - 1, 
+		"engine_type = local, \
+		asr_res_path = %s, sample_rate = %d, \
+		grm_build_path = %s, local_grammar = %s, \
+		result_type = xml, result_encoding = UTF-8, ",
+		ASR_RES_PATH,
+		SAMPLE_RATE_16K,
+		GRM_BUILD_PATH,
+		udata->grammar_id
+		);
+	session_id = QISRSessionBegin(NULL, asr_params, &errcode);
+	if (NULL == session_id)
+		goto run_error;
+	printf("开始识别...\n");
+
+	while (1) {
+		unsigned int len = 6400;
+
+		if (pcm_size < 12800) {
+			len = pcm_size;
+			last_audio = 1;
+		}
+
+		aud_stat = MSP_AUDIO_SAMPLE_CONTINUE;
+
+		if (0 == pcm_count)
+			aud_stat = MSP_AUDIO_SAMPLE_FIRST;
+
+		if (len <= 0)
+			break;
+
+		printf(">");
+		fflush(stdout);
+		errcode = QISRAudioWrite(session_id, (const void *)&pcm_data[pcm_count], len, aud_stat, &ep_status, &rec_status);
+		if (MSP_SUCCESS != errcode)
+			goto run_error;
+
+		pcm_count += (long)len;
+		pcm_size -= (long)len;
+
+		//检测到音频结束
+		if (MSP_EP_AFTER_SPEECH == ep_status)
+			break;
+
+		usleep(150 * 1000); //模拟人说话时间间隙
+	}
+	//主动点击音频结束
+	QISRAudioWrite(session_id, (const void *)NULL, 0, MSP_AUDIO_SAMPLE_LAST, &ep_status, &rec_status);
+
+	free(pcm_data);
+	pcm_data = NULL;
+
+	//获取识别结果
+	while (MSP_REC_STATUS_COMPLETE != rss_status && MSP_SUCCESS == errcode) {
+		rec_rslt = QISRGetResult(session_id, &rss_status, 0, &errcode);
+		usleep(150 * 1000);
+	}
+	printf("\n识别结束:\n");
+	printf("=============================================================\n");
+	if (NULL != rec_rslt)
+		printf("%s\n", rec_rslt);
+	else
+		printf("没有识别结果!\n");
+	printf("=============================================================\n");
+
+	goto run_exit;
+
+run_error:
+	if (NULL != pcm_data) {
+		free(pcm_data);
+		pcm_data = NULL;
+	}
+	if (NULL != f_pcm) {
+		fclose(f_pcm);
+		f_pcm = NULL;
+	}
+run_exit:
+	QISRSessionEnd(session_id, NULL);
+	return errcode;
+}
+
+int main(int argc, char* argv[])
+{
+	const char *login_config    = "appid = 5d5b9efd"; //登录参数
+	UserData asr_data; 
+	int ret                     = 0 ;
+	char c;
+
+	ret = MSPLogin(NULL, NULL, login_config); //第一个参数为用户名,第二个参数为密码,传NULL即可,第三个参数是登录参数
+	if (MSP_SUCCESS != ret) {
+		printf("登录失败:%d\n", ret);
+		goto exit;
+	}
+
+	memset(&asr_data, 0, sizeof(UserData));
+	printf("构建离线识别语法网络...\n");
+	ret = build_grammar(&asr_data);  //第一次使用某语法进行识别,需要先构建语法网络,获取语法ID,之后使用此语法进行识别,无需再次构建
+	if (MSP_SUCCESS != ret) {
+		printf("构建语法调用失败!\n");
+		goto exit;
+	}
+	while (1 != asr_data.build_fini)
+		usleep(300 * 1000);
+	if (MSP_SUCCESS != asr_data.errcode)
+		goto exit;
+	printf("离线识别语法网络构建完成,开始识别...\n");	
+	ret = run_asr(&asr_data);
+	if (MSP_SUCCESS != ret) {
+		printf("离线语法识别出错: %d \n", ret);
+		goto exit;
+	}
+
+	printf("更新离线语法词典...\n");
+	ret = update_lexicon(&asr_data);  //当语法词典槽中的词条需要更新时,调用QISRUpdateLexicon接口完成更新
+	if (MSP_SUCCESS != ret) {
+		printf("更新词典调用失败!\n");
+		goto exit;
+	}
+	while (1 != asr_data.update_fini)
+		usleep(300 * 1000);
+	if (MSP_SUCCESS != asr_data.errcode)
+		goto exit;
+	printf("更新离线语法词典完成,开始识别...\n");
+	ret = run_asr(&asr_data);
+	if (MSP_SUCCESS != ret) {
+		printf("离线语法识别出错: %d \n", ret);
+		goto exit;
+	}
+
+exit:
+	MSPLogout();
+	printf("请按任意键退出...\n");
+	getchar();
+	return 0;
+}
+