全部产品
阿里云办公

C++ SDK

更新时间:2018-08-21 15:20:46

一、SDK 使用说明

功能介绍

C++ SDK提供将文字转为语音的功能。

SDK下载地址

文字转语音C++ SDK

demo 编译,运行步骤

  1. Linuxdemo编译过程:
  2. 准备工作:
  3. 1: cd path/to/sdk/lib
  4. 2: tar -zxvpf linux.tar.gz
  5. cmake编译:
  6. 1: 请确认本地系统以安装Cmake,最低版本2.6
  7. 2: 执行[cd path/to/sdk/ && ./build.sh]编译demo
  8. 3: 编译完毕,进入path/to/sdk/demo目录,执行[./demo config-XXX.txt your-id your-scret]
  9. 如果不支持cmake,可尝试手动编译:
  10. 1: g++ -o demo/ttsDemo demo/tts-demo.cpp -I./include -L./lib/linux -lrealTimeUnity -lssl -lcrypto -lopus -lpthread -D_GLIBCXX_USE_CXX11_ABI=0
  11. 2: export LD_LIBRARY_PATH=./lib/linux/
  12. 3: ./demo/ttsDemo config-xxx.txt your-id your-scret
  13. Windowsdemo编译工程:
  14. Windows下需要用户自己搭建VS工程。
  15. 准备工作:
  16. 1: 进入 path/to/sdk/lib
  17. 2: 解压windows.zip

SDK调用顺序

  1. 创建一个的NlsSpeechCallback实例callbck,并分别设置结果返回、操作错误和通道关闭的回调函数.

  2. 创建一个NlsClient的对象nlc,该对象只需创建一次并且可以重复使用。

  3. 准备好config.txt配置文件,其内包含app-key、url等参数,详细见本文末尾的示例。

  4. 通过调用2步中的nlc对象的createAsrRequest方法获得一个NlsRequest 对象的指针(用完记得释放),该NlsRequest对象不能重复使用,但是可以重复创建。

  5. 调用4中返回的NlsRequest对象的Authorize方法进行设置用户id和scret。

  6. 调用4中 NlsRequest对象的start方法.

  7. start返回之后,调用4中NlsRequest对象的stop方法

  • 注意:Request的create()——>start()——>stop()——>delete操作,请在一个线程内部完成。不要夸线程。否则会有异常。Demo.cpp内部实现亦是在一个线程内部完成。

SDK调用注意事项

  1. sdk采用ISO 标准c++编写,运行环境最低要求:glibc:2.5 gcc 版本:4.1.2.

  2. 针对linux环境,sdk提供的库文件为librealTimeUnity.so 和librealTimeUnity-32.so,分别对应64位运行环境和32位运行环境.

  3. 针对windows环境,sdk提供的库文件为 windows版本x86/64位realTimeSdk.dll(VS2013、VS2015)

  4. SDK 依赖openssl(l-1.0.2j),opus(1.2.1),pthread(2.9.1, windows下使用。linux下系统自带pthread)。依赖库放置在path/to/sdk/lib 下。

    注意:path/to/sdk/lib/windwos/1x.0/pthread仅在windows下使用。

  5. sdk提供的第三方库均为64位,如需32位,请根据如上版本自行下载源码进行编译.


重要接口说明

NlsClient:语音SDK的Client,相当于所有语音相关处理类的factory,全局创建一个实例即可。线程安全。可通过NlsClient创建语音识别request对象。


  1. /**
  2. * @brief 设置日志文件与存储路径
  3. * @param logOutputFile 日志文件
  4. * @param logLevel 日志级别,默认1(LogError : 1, LogWarning : 2, LogInfo : 3, LogDebug : 4)
  5. * @param logFileSize 日志文件的大小,以MB为单位,默认为10MB;
  6. * 如果日志文件内容的大小超过这个值,SDK会自动备份当前的日志文件,最多可备份5个文件,超过后会循环覆盖已有文件
  7. * @return 成功则返回0,失败返回-1
  8. */
  9. int setLogConfig(const char* logOutputFile, LogLevel logLevel, unsigned int logFileSize = 10);
  10. /**
  11. * @brief 创建实时语音识别Request对象
  12. * @param onResultReceivedEvent 事件回调接口
  13. * @param config 配置文件
  14. * @return 成功返回NlsRequest对象,否则返回NULL
  15. */
  16. NlsRequest* createRealTimeRequest(NlsSpeechCallback* onResultReceivedEvent, const char* config);
  17. /**
  18. * @brief 创建一句话识别Request对象
  19. * @param onResultReceivedEvent 事件回调接口
  20. * @param config 配置文件
  21. * @return 成功返回NlsRequest对象,否则返回NULL
  22. */
  23. NlsRequest* createAsrRequest(NlsSpeechCallback* onResultReceivedEvent, const char* config);
  24. /**
  25. * @brief 创建语音合成Request对象
  26. * @param onResultReceivedEvent 事件回调接口
  27. * @param config 配置文件
  28. * @return 成功返回NlsRequest对象,否则返回NULL
  29. */
  30. NlsRequest* createTtsRequest(NlsSpeechCallback* onResultReceivedEvent, const char* config);
  31. /**
  32. * @brief 创建NLu Request对象
  33. * @param onResultReceivedEvent 事件回调接口
  34. * @param config 配置文件
  35. * @return 成功返回NlsRequest对象,否则返回NULL
  36. */
  37. NlsRequest* createNluRequest(NlsSpeechCallback* onResultReceivedEvent, const char* config);
  38. /**
  39. * @brief 销毁NlsRequest
  40. * @param request createXXXXRequest所建立的NlsRequest对象
  41. * @return
  42. */
  43. void releaseNlsRequest(NlsRequest* request);
  44. /**
  45. * @brief NlsClient对象实例
  46. * @param sslInitial 是否初始化openssl 线程安全,默认为true
  47. * @return NlsClient对象
  48. */
  49. static NlsClient* getInstance(bool sslInitial = true);
  50. /**
  51. * @brief 销毁NlsClient对象实例
  52. * @note releaseInstance()非线程安全.
  53. * @return
  54. */
  55. static void releaseInstance();

NlsRequest:语音识别请求对象,通过调用该类的start()、stop()、sendAudio()等方法来打开、关闭或发送语音数据。。


  1. /**
  2. * @brief 参数设置
  3. * @param value appKey字符串
  4. * @return 成功则返回0,否则返回-1
  5. */
  6. int SetParam(const char* str_key, const char* str_value); // add format
  7. /**
  8. * @brief 启动Request
  9. * @note 阻塞操作,等待服务端响应、或10秒超时才会返回
  10. * @return 成功则返回0,否则返回-1
  11. */
  12. int Start();
  13. /**
  14. * @brief 会与服务端确认关闭,正常停止SpeechRecognizerRequest链接操作
  15. * @note 阻塞操作,等待服务端响应才会返回
  16. * @return 成功则返回0,否则返回-1
  17. */
  18. int Stop();
  19. /**
  20. * @brief 不会与服务端确认关闭,直接关闭SpeechRecognizerRequest链接
  21. * @note 正常情况下,建议使用stop结束操作
  22. * @return 成功则返回0,否则返回-1
  23. */
  24. int Cancel();
  25. /**
  26. * @brief 授权校验
  27. * @param id
  28. * @param scret
  29. * @return 成功则返回实际发送长度,失败返回-1
  30. */
  31. int Authorize(const char* id, const char* scret);
  32. /**
  33. * @brief 发送语音数据
  34. * @param data 语音数据
  35. * @param dataSize 语音数据长度
  36. * @return 成功则返回实际发送长度,失败返回-1
  37. */
  38. int SendAudio(char* data, size_t num_byte);

NlsSpeechCallback:回调函数集合的对象,语音结果、异常等回调的统一入口。


  1. /**
  2. * @brief 设置结果消息接受回调函数
  3. * @param _event 回调方法
  4. * @param para 用户传入参数, 默认为NULL
  5. * @return void
  6. */
  7. void setOnMessageReceiced(NlsCallbackMethod onMessageReceived,void*para=NULL);
  8. /**
  9. * @brief 设置错误回调函数
  10. * @note 在请求过程中出现错误时,触发该回调。用户可以在事件的消息头中检查状态码和状态消息,以确认失败的具体原因。
  11. * @param _event 回调方法
  12. * @param para 用户传入参数, 默认为NULL
  13. * @return void
  14. */
  15. void setOnOperationFailed(NlsCallbackMethod _event, void*para=NULL);
  16. /**
  17. * @brief 设置通道关闭回调函数
  18. * @note 在请求过程中通道关闭时,触发该回调.
  19. * @param _event 回调方法
  20. * @param para 用户传入参数, 默认为NULL
  21. * @return void
  22. */
  23. void setOnChannelClosed(NlsCallbackMethod _event, void*para=NULL);
  24. /**
  25. * @brief 二进制音频数据接收回调函数
  26. * @note 仅在tts语音合成中触发该回调
  27. * @param _event 回调方法
  28. * @param para 用户传入参数, 默认为NULL
  29. * @return void
  30. */
  31. void setOnBinaryDataReceived(NlsCallbackMethod _event, void*para=NULL);

NlsEvent:回调事件对象,用户可以从中获取Request状态码、云端返回结果、失败信息等。


  1. /**
  2. * @brief 获取状态码
  3. * @note 正常情况为0或者200,失败时对应失败的错误码。错误码参考SDK文档说明。
  4. * @return string
  5. */
  6. std::string getStausCode();
  7. /**
  8. * @brief 获取云端返回的结果
  9. * @note json格式
  10. * @return string
  11. */
  12. std::string getResponse();
  13. /**
  14. * @brief 获取NlsRequest操作过程中出现失败时的错误信息
  15. * @note 在Failed回调函数中使用
  16. * @return string
  17. */
  18. std::string getErrorMessage();
  19. /**
  20. * @brief 获取云端返回的二进制数据
  21. * @note 仅用于tts语音合成功能
  22. * @return vector<unsigned char>
  23. */
  24. std::vector<unsigned char> getBinaryData();
  25. /**
  26. * @brief 获取当前所发生Event的类型
  27. * @note Event值参照NlsClient.h说明
  28. * @return EventType
  29. */
  30. EventType getMsgType();
  31. /**
  32. * @brief 获取当前request对象id
  33. * @return string
  34. */
  35. std::string getId();
  36. /**
  37. * @brief 设置当前request对象id
  38. * @return
  39. */
  40. void setId(std::string id);

更多详细介绍参见SDK压缩包内部include/NlsClient.h。


错误码

服务端错误码:

状态 status_code CloseFrame状态码 HTTP语义
成功 200 1000 成功处理
请求格式有误 400 4400 错误请求
需要鉴权信息 401 4401 请求要求身份验证
鉴权失败 403 4403 服务器拒绝请求
超出最大并发量 429 4429 太多请求
请求超时 408 4408 处理请求超时
处理出错 500 4500 服务器内部错误
服务不可用 503 4503 服务不可用
服务不可用 503 4503 服务不可用

SDK错误码

状态 status_code
“status_code not found” 999
“GetInetAddressByHostname fail” 1028
“asr frame type must be text” 1030
“Json reader fail” 1031
“Authorization mustn’t be null” 10002
“get time fail” 10003
“PING no implementaion” 10004
“ConnectToHttp fail” 10005
“Json convert fail” 10006
“SSLv23_client_method fail” 10015
“SSL_CTX_new fail” 10016
“SSL_new fail” 10017
“not support mode” 10020
“ssl connect fail” 参考SSL官方错误码
“convert to utf8 error” 参考系统错误码

config.txt 内容如下:

  1. #注意:
  2. #1. 以#开头的行为注释,处理时会直接跳过该行。
  3. #2. 配置中每行只能出现一条配置且以key:value的形式出现,切忌中间、行头、行尾不要出现空格,除非key, value字段中本身含有空格
  4. Url:wss://nls.dataapi.aliyun.com:443
  5. AppKey:your-appkey
  6. #Language:EN/CHN
  7. #TtsEnable tts请求为true
  8. TtsEnable:true
  9. #TtsEncodeType 编码格式,支持pcm,wav,mp3。默认值是pcm
  10. TtsEncodeType:pcm
  11. #TtsVolume 音量,范围是0到100
  12. TtsVolume:100
  13. #TtsNus 合成方式,0表示HTS,1表示NUS,2表示RUS
  14. TtsNus:0
  15. #TtsVoice 说话人名称,支持xiaoyun,xiaogang,xiaokubao
  16. TtsVoice:xiaoyun
  17. #TtsSpeechRate 语速,范围是-500到500。
  18. TtsSpeechRate:0
  19. #BackgroundMusicId 背景音乐ID,0表示不添加背景音乐
  20. BackgroundMusicId:1
  21. #BackgroundMusicOffset 在添加背景音乐时,指定背景音乐的偏移
  22. BackgroundMusicOffset:0
  23. #BstreamAttached 是否附加流
  24. BstreamAttached:false
  25. #TtsReference 指定发音
  26. #TtsReference:
  27. #TtsPitchRate 语调,范围是-500到500。
  28. TtsPitchRate:0
  29. #TtsSampleRate 采样率,支持16000或8000
  30. TtsSampleRate:16000
  31. #TtsReq 需要转为语音的文字
  32. TtsReq:人民公园不但风景美丽,而且还给我们带来了无穷的乐趣。

完整示例

  1. /*自定义线程参数*/
  2. struct ParamStruct {
  3. string text;
  4. string config;
  5. string id;
  6. string scret;
  7. string audioFile;
  8. };
  9. /*自定义事件回调参数*/
  10. struct ParamCallBack {
  11. string binAudioFile;
  12. ofstream audioFile;
  13. };
  14. /*
  15. *在回调函数内部,请不要进行阻,耗时过久操作.
  16. *在接收到服务端识别结果响应时,上报OnResultDataRecved回调.此时可以在回调函数内部读取识别结果.
  17. *注意:请不要在回调函数内部调用stop, releaseRequest操作。
  18. */
  19. void OnResultDataRecved(NlsEvent* cbEvent, void* cbParam) {
  20. ParamCallBack* tmpParam = (ParamCallBack*)cbParam;
  21. cout << "CbParam: " << tmpParam->binAudioFile << endl; /*仅表示自定义参数示例*/
  22. cout << "OnRecognitionCompleted: " << cbEvent->getResponse() << endl; /*getResponse() 可以获取云端响应信息*/
  23. }
  24. /*
  25. *在回调函数内部,请不要进行阻,耗时过久操。
  26. *request内部流程出错,上报OnOperationFailed回调,此时可以停止工作线程send操作,调用stop。
  27. *注意:请不要在回调函数内部调用stop, releaseRequest操作。
  28. */
  29. void OnOperationFailed(NlsEvent* cbEvent, void* cbParam) {
  30. ParamCallBack* tmpParam = (ParamCallBack*)cbParam;
  31. cout << "CbParam: " << tmpParam->binAudioFile << endl; /*仅表示自定义参数示例*/
  32. cout << "OnRecognitionTaskFailed: " << cbEvent->getErrorMessage() << endl; /*getErrorMessage() 可以获取异常失败信息*/
  33. }
  34. /*
  35. *在回调函数内部,请不要进行阻,耗时过久操.
  36. *在调用stop(),或者服务端主动关闭连接通道时,上报OnChannelCloseed回调,通知连接通道关闭.
  37. *注意:请不要在回调函数内部调用stop, releaseRequest操作。
  38. */
  39. void OnChannelCloseed(NlsEvent* cbEvent, void* cbParam) {
  40. ParamCallBack* tmpParam = (ParamCallBack*)cbParam;
  41. cout << "CbParam: " << tmpParam->binAudioFile << endl; /*仅表示自定义参数示例*/
  42. cout << "OnRecognitionChannelCloseed: " << cbEvent->getResponse() << endl; /*getResponse() 可以获取关闭信息*/
  43. }
  44. /*
  45. *在回调函数内部,请不要进行阻,耗时过久操作.
  46. *在接收到服务端返回的二进制音频数据,上报OnResultDataRecved回调..
  47. *注意:请不要在回调函数内部调用stop, releaseRequest操作。
  48. */
  49. void OnBinaryDataRecved(NlsEvent* cbEvent, void* cbParam) {
  50. ParamCallBack* tmpParam = (ParamCallBack*)cbParam;
  51. cout << "CbParam: " << tmpParam->binAudioFile << endl; /*仅表示自定义参数示例*/
  52. vector<unsigned char> data = cbEvent->getBinaryData(); /*getBinaryData() 获取文本合成的二进制音频数据*/
  53. std::cout << "OnBinaryDataRecved: " << data.size() << endl;
  54. /*以追加形式将二进制音频数据写入文件*/
  55. if (data.size() > 0) {
  56. tmpParam->audioFile.write((char*)&data[0], data.size());
  57. }
  58. }
  59. /*工作线程*/
  60. void* pthreadFunc(void* arg) {
  61. int sleepMs = 0;
  62. ParamCallBack cbParam;
  63. NlsSpeechCallback* callback = NULL;
  64. /*0: 从自定义线程参数中获取token, 配置文件等参数.*/
  65. ParamStruct* tst = (ParamStruct*)arg;
  66. if (tst == NULL) {
  67. cout << "arg is not valid." << endl;
  68. return NULL;
  69. }
  70. /*初始化自定义回调参数*/
  71. cbParam.binAudioFile = tst->audioFile;
  72. cbParam.audioFile.open(cbParam.binAudioFile.c_str(), ios::binary | ios::out);
  73. /*
  74. * 1: 创建并设置回调函数
  75. */
  76. callback = new NlsSpeechCallback();
  77. callback->setOnMessageReceiced(OnResultDataRecved, &cbParam);
  78. callback->setOnOperationFailed(OnOperationFailed, &cbParam);
  79. callback->setOnChannelClosed(OnChannelCloseed, &cbParam);
  80. callback->setOnBinaryDataReceived(OnBinaryDataRecved, &cbParam);
  81. /***************以读取config.txt方式创建request****************/
  82. /*
  83. * 创建语音识别SpeechSynthesizerRequest对象, 第一个参数为callback对象, 第二个参数为config.txt文件.
  84. * 目前SynthesizerRequest对象在调用一次start(),发送完一个text文本之后,必须调用stop()并releaseSynthesizerRequest()释放对象
  85. */
  86. /*
  87. * 2: 创建语音识别SpeechSynthesizerRequest对象
  88. */
  89. NlsRequest* request = NlsClient::getInstance()->createTtsRequest(callback, tst->config.c_str());
  90. if (request == NULL) {
  91. cout << "createTtsRequest failed." << endl;
  92. cbParam.audioFile.close();
  93. delete callback;
  94. callback = NULL;
  95. return NULL;
  96. }
  97. /*****************以参数设置方式创建request******************/
  98. // NlsRequest* request = NlsClient::getInstance()->createTtsRequest(callback, NULL);
  99. // if (request == NULL) {
  100. // std::cout << "createTtsRequest fail" << endl;
  101. //
  102. // delete callback;
  103. // callback = NULL;
  104. //
  105. // return NULL;
  106. // }
  107. //
  108. // request->SetParam("Url","wss://nls.dataapi.aliyun.com:443"); /*设置服务端url, 必填参数*/
  109. // request->SetParam("AppKey","nls-service"); /*设置AppKey, 必填参数, 请参照官网申请*/
  110. // request->SetParam("TtsVoice","xiaoyun");/*发音人, 包含"xiaoyun", "xiaogang". 可选参数, 默认是xiaoyun */
  111. // request->SetParam("TtsVolume","100"); /*音量, 范围是0~100, 可选参数, 默认50 */
  112. // request->SetParam("TtsEncodeType","wav"); /*音频编码格式, 可选参数, 默认是pcm. 支持pcm,wav,alaw */
  113. // request->SetParam("TtsSpeechRate","0");/*语速,阈值-500~500*/
  114. request->Authorize(tst->id.c_str(), tst->scret.c_str());
  115. /*
  116. * 3: start()为阻塞操作, 发送start指令之后, 会等待服务端响应, 或超时之后才返回.
  117. * 调用start()之后, 文本被发送至云端. SDk接到云端返回的合成音频数据,会通过OnBinaryDataRecved回调函数上报至用户进程.
  118. */
  119. if (request->Start() < 0) {
  120. cout << "start() failed." << endl;
  121. NlsClient::getInstance()->releaseNlsRequest(request); /*start()失败,释放request对象*/
  122. cbParam.audioFile.close();
  123. delete callback;
  124. callback = NULL;
  125. return NULL;
  126. }
  127. /*
  128. *6: start()返回之后,关闭识别连接通道.
  129. *stop()为阻塞操作, 在接受到服务端响应, 或者超时之后, 才会返回.
  130. *
  131. */
  132. request->Stop();
  133. cbParam.audioFile.close();
  134. /*7: 识别结束, 释放request对象*/
  135. NlsClient::getInstance()->releaseNlsRequest(request);
  136. /*8: 释放callback对象*/
  137. delete callback;
  138. callback = NULL;
  139. return NULL;
  140. }
  141. /**
  142. * 合成单个文本数据
  143. */
  144. int speechSynthesizerFile(const char* configFile, const char* id, const char* scret) {
  145. ParamStruct pa;
  146. pa.config = configFile;
  147. pa.id = id;
  148. pa.scret = scret;
  149. /*注意: VS2015编译时, 可能会将汉字编译为乱码. 导致合成失败. 请使用英文或配置文件形式测试.*/
  150. pa.text = "中华人民共和国万岁, 万岁, 万万岁";
  151. pa.audioFile = "syAudio.wav";
  152. pthread_t pthreadId;
  153. /*启动一个工作线程, 用于识别*/
  154. pthread_create(&pthreadId, NULL, &pthreadFunc, (void *)&pa);
  155. pthread_join(pthreadId, NULL);
  156. return 0;
  157. }
  158. /**
  159. * 合成多个文本数据;
  160. * sdk多线程指一个文本数据对应一个线程, 非一个文本数据对应多个线程.
  161. * 示例代码为同时开启4个线程合成4个文件;
  162. * 免费用户并发连接不能超过10个;
  163. */
  164. #define AUDIO_TEXT_NUMS 4
  165. #define AUDIO_TEXT_LENGTH 64
  166. #define AUDIO_FILE_NAME_LENGTH 32
  167. int speechSynthesizerMultFile(const char* configFile, const char* id, const char* scret) {
  168. const char syAudioFiles[AUDIO_TEXT_NUMS][AUDIO_FILE_NAME_LENGTH] = {"syAudio0.wav", "syAudio1.wav", "syAudio2.wav", "syAudio3.wav"};
  169. const char texts[AUDIO_TEXT_NUMS][AUDIO_TEXT_LENGTH] = {"今日天气真不错,我想去操作踢足球",
  170. "明天有大暴雨,还是宅在家里看电影吧",
  171. "前天天气非常好,可惜没有去运动",
  172. "每天都吃这么多肉,你会胖成猪的"};
  173. ParamStruct pa[AUDIO_TEXT_NUMS];
  174. for (int i = 0; i < AUDIO_TEXT_NUMS; i ++) {
  175. pa[i].config = configFile;
  176. pa[i].id = id;
  177. pa[i].scret = scret;
  178. pa[i].text = texts[i];
  179. pa[i].audioFile = syAudioFiles[i];
  180. }
  181. vector<pthread_t> pthreadId(AUDIO_TEXT_NUMS);
  182. /*启动四个工作线程, 同时识别四个音频文件*/
  183. for (int j = 0; j < AUDIO_TEXT_NUMS; j++) {
  184. pthread_create(&pthreadId[j], NULL, &pthreadFunc, (void *)&(pa[j]));
  185. }
  186. for (int j = 0; j < AUDIO_TEXT_NUMS; j++) {
  187. pthread_join(pthreadId[j], NULL);
  188. }
  189. return 0;
  190. }
  191. int main(int arc, char* argv[]) {
  192. if (arc < 4) {
  193. cout << "params is not valid. Usage: ./demo config.txt your-id your-scret" << endl;
  194. return -1;
  195. }
  196. int ret = NlsClient::getInstance()->setLogConfig("log-tts.txt", LogInfo);
  197. if (-1 == ret) {
  198. cout << "set log failed." << endl;
  199. return -1;
  200. }
  201. /*识别单个音频数据*/
  202. speechSynthesizerFile(argv[1], argv[2], argv[3]);
  203. /*识别多个音频数据*/
  204. //speechSynthesizerMultFile(argv[1], argv[2], argv[3]);
  205. /*所有工作完成,进程退出前,释放nlsClient. 请注意, releaseInstance()非线程安全.*/
  206. NlsClient::releaseInstance();
  207. return 0;
  208. }