mirror of
https://github.com/Jieshoudaxue/ros_senior.git
synced 2026-08-29 08:34:43 +08:00
[fix] tmp
This commit is contained in:
+30
-16
@@ -12,6 +12,7 @@ find_package(catkin REQUIRED COMPONENTS
|
||||
rospy
|
||||
std_msgs
|
||||
geometry_msgs
|
||||
message_generation
|
||||
)
|
||||
|
||||
## System dependencies are found with CMake's conventions
|
||||
@@ -55,11 +56,10 @@ find_package(catkin REQUIRED COMPONENTS
|
||||
# )
|
||||
|
||||
## Generate services in the 'srv' folder
|
||||
# add_service_files(
|
||||
# FILES
|
||||
# Service1.srv
|
||||
# Service2.srv
|
||||
# )
|
||||
add_service_files(
|
||||
FILES
|
||||
StringToVoice.srv
|
||||
)
|
||||
|
||||
## Generate actions in the 'action' folder
|
||||
# add_action_files(
|
||||
@@ -69,10 +69,10 @@ find_package(catkin REQUIRED COMPONENTS
|
||||
# )
|
||||
|
||||
## Generate added messages and services with any dependencies listed here
|
||||
# generate_messages(
|
||||
# DEPENDENCIES
|
||||
# std_msgs
|
||||
# )
|
||||
generate_messages(
|
||||
DEPENDENCIES
|
||||
std_msgs
|
||||
)
|
||||
|
||||
################################################
|
||||
## Declare ROS dynamic reconfigure parameters ##
|
||||
@@ -106,7 +106,7 @@ find_package(catkin REQUIRED COMPONENTS
|
||||
catkin_package(
|
||||
# INCLUDE_DIRS include
|
||||
# LIBRARIES robot_voice
|
||||
# CATKIN_DEPENDS roscpp rospy std_msgs
|
||||
CATKIN_DEPENDS message_runtime roscpp rospy std_msgs
|
||||
# DEPENDS system_lib
|
||||
)
|
||||
|
||||
@@ -134,11 +134,14 @@ include_directories(
|
||||
## Declare a C++ executable
|
||||
## With catkin_make all packages are built within a single CMake context
|
||||
## The recommended prefix ensures that target names across packages don't collide
|
||||
add_executable(voice_controller
|
||||
src/voice_controller.cpp
|
||||
add_executable(voice_to_string
|
||||
src/voice_to_string.cpp
|
||||
ifly/speech_recognizer.c
|
||||
ifly/linuxrec.c)
|
||||
|
||||
add_executable(robot_controller src/robot_controller.cpp)
|
||||
|
||||
add_executable(string_to_voice src/string_to_voice.cpp)
|
||||
|
||||
## Rename C++ executable without prefix
|
||||
## The above recommended prefix causes long target names, the following renames the
|
||||
@@ -155,10 +158,21 @@ add_executable(voice_controller
|
||||
# ${catkin_LIBRARIES}
|
||||
# )
|
||||
|
||||
target_link_libraries(voice_controller
|
||||
${catkin_LIBRARIES}
|
||||
libmsc.so -ldl -lpthread -lm -lrt -lasound
|
||||
)
|
||||
target_link_libraries(voice_to_string
|
||||
${catkin_LIBRARIES}
|
||||
libmsc.so -ldl -lpthread -lm -lrt -lasound
|
||||
)
|
||||
|
||||
add_dependencies(robot_controller ${PROJECT_NAME}_generate_messages_cpp)
|
||||
target_link_libraries(robot_controller
|
||||
${catkin_LIBRARIES}
|
||||
)
|
||||
|
||||
add_dependencies(string_to_voice ${PROJECT_NAME}_generate_messages_cpp)
|
||||
target_link_libraries(string_to_voice
|
||||
${catkin_LIBRARIES}
|
||||
libmsc.so -ldl -pthread
|
||||
)
|
||||
|
||||
#############
|
||||
## Install ##
|
||||
|
||||
@@ -53,15 +53,21 @@
|
||||
<build_depend>rospy</build_depend>
|
||||
<build_depend>std_msgs</build_depend>
|
||||
<build_depend>geometry_msgs</build_depend>
|
||||
<build_depend>message_generation</build_depend>
|
||||
<build_depend>message_runtime</build_depend>
|
||||
<build_export_depend>roscpp</build_export_depend>
|
||||
<build_export_depend>rospy</build_export_depend>
|
||||
<build_export_depend>std_msgs</build_export_depend>
|
||||
<build_export_depend>geometry_msgs</build_export_depend>
|
||||
<build_export_depend>message_generation</build_export_depend>
|
||||
<build_export_depend>message_runtime</build_export_depend>
|
||||
<exec_depend>roscpp</exec_depend>
|
||||
<exec_depend>rospy</exec_depend>
|
||||
<exec_depend>std_msgs</exec_depend>
|
||||
<exec_depend>geometry_msgs</exec_depend>
|
||||
|
||||
<exec_depend>message_generation</exec_depend>
|
||||
<exec_depend>message_runtime</exec_depend>
|
||||
|
||||
|
||||
<!-- The export tag contains other, unspecified, tags -->
|
||||
<export>
|
||||
|
||||
@@ -0,0 +1,208 @@
|
||||
#include <ros/ros.h>
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include "ifly/qisr.h"
|
||||
#include "ifly/qtts.h"
|
||||
#include "ifly/msp_cmn.h"
|
||||
#include "ifly/formats.h"
|
||||
#include "ifly/msp_errors.h"
|
||||
#include "ifly/speech_recognizer.h"
|
||||
#include <robot_voice/StringToVoice.h>
|
||||
|
||||
|
||||
class Helper {
|
||||
public:
|
||||
static void SignalHandler(int signal) {
|
||||
ROS_INFO("\nCaught signal %d. Exiting gracefully...\n", signal);
|
||||
exit(0);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class VoiceResponse {
|
||||
public:
|
||||
VoiceResponse() {
|
||||
ROS_INFO("voice Response Constructor");
|
||||
}
|
||||
|
||||
~VoiceResponse() {
|
||||
ROS_INFO("voice Response Destructor ");
|
||||
}
|
||||
|
||||
int ProcessTxt(std::string& txt) {
|
||||
int ret = -1;
|
||||
FILE* fp = NULL;
|
||||
const char* sessionID = NULL;
|
||||
unsigned int audio_len = 0;
|
||||
int synth_status = MSP_TTS_FLAG_STILL_HAVE_DATA;
|
||||
WavePcmHdr_t 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
|
||||
};
|
||||
|
||||
const char* src_text = txt.c_str();
|
||||
const char* des_path = filename_.c_str();
|
||||
const char* params = session_begin_params_.c_str();
|
||||
|
||||
if (NULL == src_text || NULL == des_path) {
|
||||
ROS_ERROR("params is error!");
|
||||
return ret;
|
||||
}
|
||||
|
||||
fp = fopen(des_path, "wb");
|
||||
if (NULL == fp) {
|
||||
ROS_ERROR("open %s error", des_path);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* 开始合成 */
|
||||
sessionID = QTTSSessionBegin(params, &ret);
|
||||
if (MSP_SUCCESS != ret) {
|
||||
ROS_ERROR("QTTSSessionBegin failed, error code: %d", ret);
|
||||
fclose(fp);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = QTTSTextPut(sessionID, src_text, (unsigned int)strlen(src_text), NULL);
|
||||
if (MSP_SUCCESS != ret) {
|
||||
ROS_ERROR("QTTSTextPut failed, error code: %d",ret);
|
||||
QTTSSessionEnd(sessionID, "TextPutError");
|
||||
fclose(fp);
|
||||
return ret;
|
||||
}
|
||||
|
||||
printf("正在合成 ...\n");
|
||||
fwrite(&wav_hdr, sizeof(wav_hdr) ,1, fp); //添加wav音频头,使用采样率为16000
|
||||
while (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(">");
|
||||
usleep(150*1000); //防止频繁占用CPU
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
if (MSP_SUCCESS != ret) {
|
||||
ROS_ERROR("QTTSAudioGet failed, error code: %d",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) {
|
||||
ROS_ERROR("QTTSSessionEnd failed, error code: %d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
fp = popen(play_cmd_.c_str(),"r");
|
||||
if (fp == NULL) {
|
||||
ROS_ERROR("play /tmp/tts_sample.wav failed");
|
||||
return -1;
|
||||
}
|
||||
pclose(fp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool Speeking(robot_voice::StringToVoice::Request &req, robot_voice::StringToVoice::Response &resp) {
|
||||
int ret = -1;
|
||||
ret = ProcessTxt(req.data);
|
||||
if (MSP_SUCCESS != ret) {
|
||||
ROS_ERROR("AnswerVoice failed, error code: %d", ret);
|
||||
resp.success = false;
|
||||
return false;
|
||||
} else {
|
||||
resp.success = true;
|
||||
}
|
||||
|
||||
return resp.success;
|
||||
}
|
||||
|
||||
void Start(ros::NodeHandle& nh) {
|
||||
server_ = nh.advertiseService("str2voice", &VoiceResponse::Speeking, this);
|
||||
ROS_INFO("voice Response Start");
|
||||
}
|
||||
|
||||
private:
|
||||
ros::ServiceServer server_;
|
||||
|
||||
const std::string session_begin_params_ =
|
||||
"voice_name = xiaoyan, text_encoding = utf8, "
|
||||
"sample_rate = 16000, speed = 50, volume = 50, "
|
||||
"pitch = 50, rdn = 2";
|
||||
const std::string filename_ = "/tmp/tts_sample.wav"; //合成的语音文件名称
|
||||
const std::string play_cmd_ = "play /tmp/tts_sample.wav";
|
||||
|
||||
/* wav音频头部格式 */
|
||||
typedef struct WavePcmHdr {
|
||||
char riff[4]; // = "RIFF"
|
||||
int size_8; // = FileSize - 8
|
||||
char wave[4]; // = "WAVE"
|
||||
char fmt[4]; // = "fmt "
|
||||
int fmt_size; // = 下一个结构体的大小 : 16
|
||||
|
||||
short int format_tag; // = PCM : 1
|
||||
short int channels; // = 通道数 : 1
|
||||
int samples_per_sec; // = 采样率 : 8000 | 6000 | 11025 | 16000
|
||||
int avg_bytes_per_sec; // = 每秒字节数 : samples_per_sec * bits_per_sample / 8
|
||||
short int block_align; // = 每采样点字节数 : wBitsPerSample / 8
|
||||
short int bits_per_sample; // = 量化比特数: 8 | 16
|
||||
|
||||
char data[4]; // = "data";
|
||||
int data_size; // = 纯数据长度 : FileSize - 44
|
||||
} WavePcmHdr_t;
|
||||
|
||||
};
|
||||
|
||||
int main(int argc, char ** argv) {
|
||||
ros::init(argc, argv, "string_to_voice");
|
||||
ros::NodeHandle nh;
|
||||
|
||||
if (signal(SIGINT, Helper::SignalHandler) == SIG_ERR) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
VoiceResponse vr;
|
||||
vr.Start(nh);
|
||||
|
||||
ros::spin();
|
||||
return 0;
|
||||
}
|
||||
@@ -1,4 +1,3 @@
|
||||
#include <ros/ros.h>
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
@@ -0,0 +1,168 @@
|
||||
#include <ros/ros.h>
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include "ifly/qisr.h"
|
||||
#include "ifly/qtts.h"
|
||||
#include "ifly/msp_cmn.h"
|
||||
#include "ifly/formats.h"
|
||||
#include "ifly/msp_errors.h"
|
||||
#include "ifly/speech_recognizer.h"
|
||||
#include <std_msgs/String.h>
|
||||
|
||||
class Helper {
|
||||
public:
|
||||
static void SignalHandler(int signal) {
|
||||
ROS_INFO("\nCaught signal %d. Exiting gracefully...\n", signal);
|
||||
exit(0);
|
||||
}
|
||||
};
|
||||
|
||||
class VoiceDetector {
|
||||
public:
|
||||
VoiceDetector() {
|
||||
ROS_INFO("voice detector Constructor");
|
||||
}
|
||||
~VoiceDetector() {
|
||||
ROS_INFO("voice detector Destructor ");
|
||||
}
|
||||
|
||||
int Init() {
|
||||
int ret = MSP_SUCCESS;
|
||||
ret = MSPLogin(NULL, NULL, login_params_.c_str());
|
||||
if (MSP_SUCCESS != ret) {
|
||||
ROS_ERROR("MSPLogin failed , Error code %d", ret);
|
||||
MSPLogout(); // Logout...
|
||||
return -1;
|
||||
}
|
||||
|
||||
ROS_INFO("MSP Login for update, waiting for seconds...");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void JoinTxt(const char *result, char is_last) {
|
||||
if (result) {
|
||||
std::string slice_txt = result;
|
||||
|
||||
VoiceDetector::voice_txt_ += slice_txt;
|
||||
}
|
||||
if (is_last) {
|
||||
printf("voice txt : %s\n", VoiceDetector::voice_txt_.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
static void InitSpeech() {
|
||||
VoiceDetector::voice_txt_ = "";
|
||||
|
||||
printf("Start Listening...\n");
|
||||
}
|
||||
|
||||
static void EndSpeech(int reason) {
|
||||
if (reason == END_REASON_VAD_DETECT) {
|
||||
printf("\nSpeaking done \n");
|
||||
} else {
|
||||
printf("\nRecognizer error %d\n", reason);
|
||||
}
|
||||
}
|
||||
|
||||
int SpeechOnce() {
|
||||
int ret;
|
||||
int i = 0;
|
||||
|
||||
struct speech_rec iat;
|
||||
|
||||
struct speech_rec_notifier recnotifier = {
|
||||
JoinTxt,
|
||||
InitSpeech,
|
||||
EndSpeech
|
||||
};
|
||||
|
||||
ret = sr_init(&iat, session_begin_params_.c_str(), SR_MIC, &recnotifier);
|
||||
if (ret) {
|
||||
ROS_ERROR("speech recognizer init failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = sr_start_listening(&iat);
|
||||
if (ret) {
|
||||
printf("start listen failed %d\n", ret);
|
||||
}
|
||||
|
||||
/* demo 15 seconds recording */
|
||||
sleep(15);
|
||||
|
||||
ret = sr_stop_listening(&iat);
|
||||
if (ret) {
|
||||
printf("stop listening failed %d\n", ret);
|
||||
}
|
||||
|
||||
sr_uninit(&iat);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static std::string get_voice_txt_() {
|
||||
return voice_txt_;
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
|
||||
|
||||
const std::string login_params_ = "appid = bb839ccf, work_dir = .";
|
||||
const std::string session_begin_params_ =
|
||||
"sub = iat, domain = iat, language = zh_cn, "
|
||||
"accent = mandarin, sample_rate = 16000, "
|
||||
"result_type = plain, result_encoding = utf8";
|
||||
|
||||
const uint32_t BufferSize = 4096;
|
||||
uint64_t g_buffersize = BufferSize;
|
||||
static std::string voice_txt_;
|
||||
};
|
||||
|
||||
std::string VoiceDetector::voice_txt_ = "";
|
||||
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
int ret = 0;
|
||||
ros::init(argc, argv, "voice_to_string");
|
||||
ros::NodeHandle nh;
|
||||
ros::Publisher str_pub_ = nh.advertise<std_msgs::String>("/human/chatter", 1000);
|
||||
|
||||
if (signal(SIGINT, Helper::SignalHandler) == SIG_ERR) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
VoiceDetector vd;
|
||||
ret = vd.Init();
|
||||
if (ret < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
ret = vd.SpeechOnce();
|
||||
if (ret < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
std::string voice_txt = VoiceDetector::get_voice_txt_();
|
||||
if (voice_txt == "") {
|
||||
continue;
|
||||
} else if (voice_txt.find("结束") != std::string::npos) {
|
||||
break;
|
||||
}
|
||||
|
||||
std_msgs::String msg;
|
||||
msg.data = voice_txt;
|
||||
str_pub_.publish(msg);
|
||||
}
|
||||
|
||||
ros::spin();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
string data
|
||||
---
|
||||
bool success
|
||||
Reference in New Issue
Block a user