• 在工作空间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的代码如下
  • /*
    * 语音合成(Text To Speech,TTS)技术能够自动将任意文字实时转换为连续的
    * 自然语音,是一种能够在任何时间、任何地点,向任何人提供语音信息服务的
    * 高效便捷手段,非常符合信息时代海量数据、动态更新和个性化查询的需求。
    */#include <stdlib.h>
    #include <stdio.h>
    #include <unistd.h>
    #include <errno.h>
    #include <ros/ros.h>
    #include <std_msgs/String.h>
    #include "/home/fan/SoftWare/include/qtts.h"
    #include "/home/fan/SoftWare/include/msp_cmn.h"
    #include "/home/fan/SoftWare/include/msp_errors.h"
    const char* fileName="/home/fan/music/voice.wav";
    const char* playPath="play /home/fan/music/voice.wav";typedef int SR_DWORD;
    typedef short int SR_WORD ;/* wav音频头部格式 */
    typedef struct _wave_pcm_hdr
    {char            riff[4];                // = "RIFF"int              size_8;                 // = FileSize - 8char            wave[4];                // = "WAVE"char            fmt[4];                 // = "fmt "int               fmt_size;               // = 下一个结构体的大小 : 16short int       format_tag;             // = PCM : 1short int       channels;               // = 通道数 : 1int               samples_per_sec;        // = 采样率 : 8000 | 6000 | 11025 | 16000int              avg_bytes_per_sec;      // = 每秒字节数 : samples_per_sec * bits_per_sample / 8short int       block_align;            // = 每采样点字节数 : wBitsPerSample / 8short int       bits_per_sample;        // = 量化比特数: 8 | 16char            data[4];                // = "data";int              data_size;              // = 纯数据长度 : FileSize - 44
    } wave_pcm_hdr;/* 默认wav音频头部数据 */
    wave_pcm_hdr default_wav_hdr =
    {{ 'R', 'I', 'F', 'F' },0,{'W', 'A', 'V', 'E'},{'f', 'm', 't', ' '},16,1,1,16000,32000,2,16,{'d', 'a', 't', 'a'},0
    };
    /* 文本合成 */
    int text_to_speech(const char* src_text, const char* des_path, const char* params)
    {int          ret          = -1;FILE*        fp           = NULL;const char*  sessionID    = NULL;unsigned int audio_len    = 0;wave_pcm_hdr wav_hdr      = default_wav_hdr;int          synth_status = MSP_TTS_FLAG_STILL_HAVE_DATA;if (NULL == src_text || NULL == des_path){printf("params is error!\n");return ret;}fp = fopen(des_path, "wb");if (NULL == fp){printf("open %s error.\n", des_path);return ret;}/* 开始合成 */sessionID = QTTSSessionBegin(params, &ret);if (MSP_SUCCESS != ret){printf("QTTSSessionBegin failed, error code: %d.\n", ret);fclose(fp);return ret;}ret = QTTSTextPut(sessionID, src_text, (unsigned int)strlen(src_text), NULL);if (MSP_SUCCESS != ret){printf("QTTSTextPut failed, error code: %d.\n",ret);QTTSSessionEnd(sessionID, "TextPutError");fclose(fp);return ret;}printf("正在合成 ...\n");fwrite(&wav_hdr, sizeof(wav_hdr) ,1, fp); //添加wav音频头,使用采样率为16000while (1) {/* 获取合成音频 */const void* data = QTTSAudioGet(sessionID, &audio_len, &synth_status, &ret);if (MSP_SUCCESS != ret)break;if (NULL != data){fwrite(data, audio_len, 1, fp);wav_hdr.data_size += audio_len; //计算data_size大小}if (MSP_TTS_FLAG_DATA_END == synth_status)break;}printf("\n");if (MSP_SUCCESS != ret){printf("QTTSAudioGet failed, error code: %d.\n",ret);QTTSSessionEnd(sessionID, "AudioGetError");fclose(fp);return ret;}/* 修正wav文件头数据的大小 */wav_hdr.size_8 += wav_hdr.data_size + (sizeof(wav_hdr) - 8);/* 将修正过的数据写回文件头部,音频文件为wav格式 */fseek(fp, 4, 0);fwrite(&wav_hdr.size_8,sizeof(wav_hdr.size_8), 1, fp); //写入size_8的值fseek(fp, 40, 0); //将文件指针偏移到存储data_size值的位置fwrite(&wav_hdr.data_size,sizeof(wav_hdr.data_size), 1, fp); //写入data_size的值fclose(fp);fp = NULL;/* 合成完毕 */ret = QTTSSessionEnd(sessionID, "Normal");if (MSP_SUCCESS != ret){printf("QTTSSessionEnd failed, error code: %d.\n",ret);}return ret;
    }
    int makeTextToWav(const char* text, const char* filename){
    int         ret                  = MSP_SUCCESS;const char* login_params         = "appid = 5b090780, work_dir = .";//登录参数,appid与msc库绑定,请勿随意改动/** rdn:           合成音频数字发音方式* volume:        合成音频的音量* pitch:         合成音频的音调* speed:         合成音频对应的语速* voice_name:    合成发音人* sample_rate:   合成音频采样率* text_encoding: 合成文本编码格式**/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";/* 用户登录 */ret = MSPLogin(NULL, NULL, login_params); //第一个参数是用户名,第二个参数是密码,第三个参数是登录参数,用户名和密码可在http://www.xfyun.cn注册获取if (MSP_SUCCESS != ret){printf("MSPLogin failed, error code: %d.\n", ret);}else{printf("开始合成 ...\n");ret = text_to_speech(text,filename, session_begin_params);if (MSP_SUCCESS != ret){printf("text_to_speech failed, error code: %d.\n", ret);}printf("合成完毕\n");}MSPLogout();return 0;}
    void playWav()
    {system(playPath);}
    void topicCallBack(const std_msgs::String::ConstPtr& msg)
    {std::cout<<"get topic text:" << msg->data.c_str();makeTextToWav(msg->data.c_str(),fileName);playWav();
    }int main(int argc, char* argv[])
    {   const char* start= "科大迅飞在线语音合成模块启动";makeTextToWav(start,fileName);playWav();ros::init(argc,argv, "xf_tts_node");   ros::NodeHandle n;ros::Subscriber sub = n.subscribe("/voice/xf_tts_topic", 3,topicCallBack);ros::spin();return 0;
    } 
  • 在CMakeList文件的“include_directories”后加入“include”,在文件末尾加入

  • add_executable(xf_tts_node src/xf_tts.cpp)
    target_link_libraries(xf_tts_node ${catkin_LIBRARIES}   -lmsc -lrt -ldl -lpthread)
  • CMakeList代码
  • cmake_minimum_required(VERSION 2.8.3)
    project(voice_system)find_package(catkin REQUIRED COMPONENTSroscpprospystd_msgs
    )include_directories(include${catkin_INCLUDE_DIRS})add_executable(xf_tts_node src/xf_tts.cpp)
    target_link_libraries(xf_tts_node ${catkin_LIBRARIES}   -lmsc -lrt -ldl -lpthread)
    
  • 在此时到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上运行科大迅飞语音模块成功
  • 以下是我在实现过程中遇到的的一些错误

  • 在运行节点时一定要在工作空间catkin_ws下运行,否则会出现10102错误,如果在工作空间下运行还是出现该错误,可以参考https://blog.csdn.net/jack0596_cn/article/details/78663396
  • 10102错误显示如下

该文章主要是对自己学习的一些总结,方便以后学习,也对学习该方面的人提供一些帮助,如有问题请指出。

同时该文章也借鉴了ros小课堂的一些内容。

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

  1. ros+科大迅飞语音包+图灵机器人(四)与机器人对话

    将以前下载的的语音包的 samples/iat_record/的iat_record.c speech_recognizer.c speech_recognizer.c 拷贝到工程src中, linu ...

  2. ros+科大迅飞语音包+图灵机器人(三)通过图灵进行语义理解

    首先我们需要下载 sduo apt install libcurl3 libcurl4-openssl-dev sudo apt install libjsoncpp0 libjsoncpp-dev ...

  3. ros+科大迅飞语音包+图灵机器人(一)sdk下载及测试

    一.首先从科大迅飞开放平台(http://www.xfyun.cn/)注册一个账户 二.创建应用程序 我这里创建的应用名称为KF 三.下载SDK 只有创建好应用才能下载SDK 在ubuntu创建一个文 ...

  4. ros+科大迅飞语音包

    ros+科大迅飞语音包+图灵机器人(一)sdk下载及测试 2018年06月07日 21:43:47 阅读数:52 一.首先从科大迅飞开放平台(http://www.xfyun.cn/)注册一个账户 二 ...

  5. python机器人助手--丫丫1.0版本(基于百度语音和图灵机器人)

    语音实时对话机器人(基于百度语音和图灵机器人) 注:本版软件是树莓派语音聊天机器人(基于讯飞语音和图灵机器人)的重构版本.本版全部使用python编程,不涉及bash等的操作与编程:本版使用百度语音代 ...

  6. 基于 QT5 百度语音API 图灵机器人API 的智能语音聊天机器人

    基于 QT5 百度语音API 图灵机器人API 的智能语音聊天机器人 程序简介 代码一共分为以下几个模块 伪代码形式为 部分代码 源代码下载地址 程序简介 程序界面包含录音和发送两个按钮 点录音将开始 ...

  7. 【从零之三(更)】自定义类中调用讯飞语音包错误解决办法

    原文:http://blog.csdn.net/monkeyduck/article/details/24302655 在科大讯飞语音包的Mscdemo中它的方法都是写在Activity中的,这样其实 ...

  8. 探索使用科大迅飞语音包控制机器狗(五)--实现基础语音播报功能

    已经实现了的功能: 实时语音流控制机器狗的运动 预期实现的功能还有将机器狗的状态进行语音播报,先记录一下实现过程.我的设计思路是这样的,首先进行snowboy语音唤醒,然后唤醒后进入语音识别功能,之后 ...

  9. 基于讯飞语音,百度语音,图灵机器人的智能语音机器人毕业设计第一天

    语音机器人C语言终极版 c代码更新的地址: https://github.com/1158114251/-Intelligent-speech-robot 视频地址: https://www.bili ...

最新文章

  1. 各种ARM仿真器接口图
  2. consolel API大全-附测试结果
  3. Android客户端内置内存工具进行崩溃定位的实践经验
  4. GreenPlum查看表和数据库大小
  5. ubuntu下安装与使用Log4cpp
  6. 这款手机开卖在即却预约不足千人 网友:原来它还没凉?
  7. 计算机科学自考本科的科目,自考本科计算机专业考哪些
  8. 互联网敏捷 Scrum 和项目管理
  9. 进度条Progress的用法介绍
  10. 0基础看-最大似然函数,原理,基本概念,例子
  11. ps怎么保存一小块的图片_ps中怎么保存图片
  12. Shifting More Attention to Video Salient Object Detection (CVPR 2019)
  13. 批量修改文件名,图文教学,2分钟简单学会
  14. 卧槽,GitHub 开源了一个看片神器!
  15. 使用Python绘制移动均线
  16. Tensorflow2.0的简单GCN代码(使用cora数据集)
  17. dxp中Cap,Cap2,Cap Pol的区别
  18. Linux系统查看mq死信队列,MQ死信队列中持续出现本地系统对象产生的数据
  19. nyoj 628 小媛在努力 【搜索】
  20. exe文件解析_PE文件格式之重定位表

热门文章

  1. 计算机应用基础的试卷分析,37班计算机应用基础试卷分析
  2. 使用Grid制作联系人表格
  3. 【UE4 第一人称射击游戏】23-添加子弹伤害
  4. Android开机时间分析
  5. XpSp3(未开启PAE模式)内存管理之系统PTE区域 上
  6. 北京积分落户三年分析(2018-2020)
  7. 计算机打印机装不上,win7安装不了打印机怎么回事 安装不了打印机的解决方法...
  8. Web MIDI 入门:如何用电子钢琴做一款游戏
  9. PHP中在公用PHP文件中使用相对路径的正确方法
  10. Python计算一个人BMI(身体质量指数)指数