ros 科大迅飞

ros+科大迅飞语音包+图灵机器人(二)在ros上使用科大迅飞

 

  • 在工作空间catkin_ws下创建一个包

  • $ cd catkin_ws/src/

  • $ catkin_create_pkg voice_system std_msgs rospy roscpp

  • 把科大迅飞包里的代码复制到你创建的包里,并重命名为xf_tts.cpp

  • $ cd SoftWare/samples/tts_sample/
  • $ cp tts_sample.c ~/catkin_ws/src/voice_system/src/
  • $ cd catkin_ws/src/voice_system/src/
  • $ mv tts_sample.c xf_tts.cpp
  • 到SoftWare/include目录下把include拷贝到voice_system包下

  • $ cd SoftWare/include
  • $ cp * ~/catkin_ws/src/voice_system/include
  • 修改xf_tts.cpp文件(注意要把appid改为自己的appid,gtts.h等路径要改为自己该文件的路径)

  • xf_tts.cpp的代码如下
  •  
    1. /*

    2. * 语音合成(Text To Speech,TTS)技术能够自动将任意文字实时转换为连续的

    3. * 自然语音,是一种能够在任何时间、任何地点,向任何人提供语音信息服务的

    4. * 高效便捷手段,非常符合信息时代海量数据、动态更新和个性化查询的需求。

    5. */

    6.  
    7. #include <stdlib.h>

    8. #include <stdio.h>

    9. #include <unistd.h>

    10. #include <errno.h>

    11. #include <ros/ros.h>

    12. #include <std_msgs/String.h>

    13. #include "/home/fan/SoftWare/include/qtts.h"

    14. #include "/home/fan/SoftWare/include/msp_cmn.h"

    15. #include "/home/fan/SoftWare/include/msp_errors.h"

    16. const char* fileName="/home/fan/music/voice.wav";

    17. const char* playPath="play /home/fan/music/voice.wav";

    18.  
    19. typedef int SR_DWORD;

    20. typedef short int SR_WORD ;

    21.  
    22. /* wav音频头部格式 */

    23. typedef struct _wave_pcm_hdr

    24. {

    25. char riff[4]; // = "RIFF"

    26. int size_8; // = FileSize - 8

    27. char wave[4]; // = "WAVE"

    28. char fmt[4]; // = "fmt "

    29. int fmt_size; // = 下一个结构体的大小 : 16

    30.  
    31. short int format_tag; // = PCM : 1

    32. short int channels; // = 通道数 : 1

    33. int samples_per_sec; // = 采样率 : 8000 | 6000 | 11025 | 16000

    34. int avg_bytes_per_sec; // = 每秒字节数 : samples_per_sec * bits_per_sample / 8

    35. short int block_align; // = 每采样点字节数 : wBitsPerSample / 8

    36. short int bits_per_sample; // = 量化比特数: 8 | 16

    37.  
    38. char data[4]; // = "data";

    39. int data_size; // = 纯数据长度 : FileSize - 44

    40. } wave_pcm_hdr;

    41.  
    42. /* 默认wav音频头部数据 */

    43. wave_pcm_hdr default_wav_hdr =

    44. {

    45. { 'R', 'I', 'F', 'F' },

    46. 0,

    47. {'W', 'A', 'V', 'E'},

    48. {'f', 'm', 't', ' '},

    49. 16,

    50. 1,

    51. 1,

    52. 16000,

    53. 32000,

    54. 2,

    55. 16,

    56. {'d', 'a', 't', 'a'},

    57. 0

    58. };

    59. /* 文本合成 */

    60. int text_to_speech(const char* src_text, const char* des_path, const char* params)

    61. {

    62. int ret = -1;

    63. FILE* fp = NULL;

    64. const char* sessionID = NULL;

    65. unsigned int audio_len = 0;

    66. wave_pcm_hdr wav_hdr = default_wav_hdr;

    67. int synth_status = MSP_TTS_FLAG_STILL_HAVE_DATA;

    68.  
    69. if (NULL == src_text || NULL == des_path)

    70. {

    71. printf("params is error!\n");

    72. return ret;

    73. }

    74. fp = fopen(des_path, "wb");

    75. if (NULL == fp)

    76. {

    77. printf("open %s error.\n", des_path);

    78. return ret;

    79. }

    80. /* 开始合成 */

    81. sessionID = QTTSSessionBegin(params, &ret);

    82. if (MSP_SUCCESS != ret)

    83. {

    84. printf("QTTSSessionBegin failed, error code: %d.\n", ret);

    85. fclose(fp);

    86. return ret;

    87. }

    88. ret = QTTSTextPut(sessionID, src_text, (unsigned int)strlen(src_text), NULL);

    89. if (MSP_SUCCESS != ret)

    90. {

    91. printf("QTTSTextPut failed, error code: %d.\n",ret);

    92. QTTSSessionEnd(sessionID, "TextPutError");

    93. fclose(fp);

    94. return ret;

    95. }

    96. printf("正在合成 ...\n");

    97. fwrite(&wav_hdr, sizeof(wav_hdr) ,1, fp); //添加wav音频头,使用采样率为16000

    98. while (1)

    99. {

    100. /* 获取合成音频 */

    101. const void* data = QTTSAudioGet(sessionID, &audio_len, &synth_status, &ret);

    102. if (MSP_SUCCESS != ret)

    103. break;

    104. if (NULL != data)

    105. {

    106. fwrite(data, audio_len, 1, fp);

    107. wav_hdr.data_size += audio_len; //计算data_size大小

    108. }

    109. if (MSP_TTS_FLAG_DATA_END == synth_status)

    110. break;

    111. }

    112. printf("\n");

    113. if (MSP_SUCCESS != ret)

    114. {

    115. printf("QTTSAudioGet failed, error code: %d.\n",ret);

    116. QTTSSessionEnd(sessionID, "AudioGetError");

    117. fclose(fp);

    118. return ret;

    119. }

    120. /* 修正wav文件头数据的大小 */

    121. wav_hdr.size_8 += wav_hdr.data_size + (sizeof(wav_hdr) - 8);

    122.  
    123. /* 将修正过的数据写回文件头部,音频文件为wav格式 */

    124. fseek(fp, 4, 0);

    125. fwrite(&wav_hdr.size_8,sizeof(wav_hdr.size_8), 1, fp); //写入size_8的值

    126. fseek(fp, 40, 0); //将文件指针偏移到存储data_size值的位置

    127. fwrite(&wav_hdr.data_size,sizeof(wav_hdr.data_size), 1, fp); //写入data_size的值

    128. fclose(fp);

    129. fp = NULL;

    130. /* 合成完毕 */

    131. ret = QTTSSessionEnd(sessionID, "Normal");

    132. if (MSP_SUCCESS != ret)

    133. {

    134. printf("QTTSSessionEnd failed, error code: %d.\n",ret);

    135. }

    136.  
    137. return ret;

    138. }

    139. int makeTextToWav(const char* text, const char* filename){

    140. int ret = MSP_SUCCESS;

    141. const char* login_params = "appid = 5b090780, work_dir = .";//登录参数,appid与msc库绑定,请勿随意改动

    142. /*

    143. * rdn: 合成音频数字发音方式

    144. * volume: 合成音频的音量

    145. * pitch: 合成音频的音调

    146. * speed: 合成音频对应的语速

    147.  
    148. * voice_name: 合成发音人

    149. * sample_rate: 合成音频采样率

    150. * text_encoding: 合成文本编码格式

    151. *

    152.  
    153. */

    154. const char* session_begin_params = "engine_type = local,voice_name=xiaofeng, text_encoding = UTF8, tts_res_path = fo|res/tts/xiaofeng.jet;fo|res/tts/common.jet, sample_rate = 16000, speed = 50, volume = 50, pitch = 50, rdn = 0";

    155.  
    156. /* 用户登录 */

    157. ret = MSPLogin(NULL, NULL, login_params); //第一个参数是用户名,第二个参数是密码,第三个参数是登录参数,用户名和密码可在http://www.xfyun.cn注册获取

    158. if (MSP_SUCCESS != ret)

    159. {

    160. printf("MSPLogin failed, error code: %d.\n", ret);

    161.  
    162. }

    163. else{

    164. printf("开始合成 ...\n");

    165. ret = text_to_speech(text,filename, session_begin_params);

    166. if (MSP_SUCCESS != ret)

    167. {

    168. printf("text_to_speech failed, error code: %d.\n", ret);

    169. }

    170. printf("合成完毕\n");

    171. }

    172. MSPLogout();

    173. return 0;

    174.  
    175. }

    176. void playWav()

    177. {

    178. system(playPath);

    179.  
    180. }

    181. void topicCallBack(const std_msgs::String::ConstPtr& msg)

    182. {

    183. std::cout<<"get topic text:" << msg->data.c_str();

    184. makeTextToWav(msg->data.c_str(),fileName);

    185. playWav();

    186. }

    187.  
    188. int main(int argc, char* argv[])

    189. { const char* start= "科大迅飞在线语音合成模块启动";

    190. makeTextToWav(start,fileName);

    191. playWav();

    192.  
    193. ros::init(argc,argv, "xf_tts_node");

    194. ros::NodeHandle n;

    195. ros::Subscriber sub = n.subscribe("/voice/xf_tts_topic", 3,topicCallBack);

    196. ros::spin();

    197. return 0;

  • 在CMakeList文件的“include_directories”后加入“include”,在文件末尾加入

  •  
    1. add_executable(xf_tts_node src/xf_tts.cpp)

    2. target_link_libraries(xf_tts_node ${catkin_LIBRARIES} -lmsc -lrt -ldl -lpthread)

  • CMakeList代码
  •  
    1. cmake_minimum_required(VERSION 2.8.3)

    2. project(voice_system)

    3.  
    4.  
    5. find_package(catkin REQUIRED COMPONENTS

    6. roscpp

    7. rospy

    8. std_msgs

    9. )

    10.  
    11.  
    12. include_directories(

    13. include

    14. ${catkin_INCLUDE_DIRS}

    15.  
    16. )

    17.  
    18.  
    19. add_executable(xf_tts_node src/xf_tts.cpp)

    20. target_link_libraries(xf_tts_node ${catkin_LIBRARIES} -lmsc -lrt -ldl -lpthread)

    21.  
    22.  
    23.  

 

  • 在此时到catkin_ws下进行编译
  • $ catkin_make
  • 编译完后,roscore一下,重新打开窗口到catkin_ws下运行xf_tts_node节点
  • $ cd catkin_ws
  • $ rosrun voice_system xf_tts_node
  • 此时,你能听到,“科大迅飞语音模块启动”的声音“

  • 重新打开一个命令窗口,在catkin_ws下发布一个话题
  • $ cd catkin_ws
  • $ rostopic pub /voice/xf_tts_topic std_msgs/String 你好
  • 此时,你会听到”你好的声音“

  • 证明ros上运行科大迅飞语音模块成功
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值