赞
踩
如果报错:
linuxrec.c:12:28: fatal error: alsa/asoundlib.h: No such file or directory
则执行
sudo apt-get install libasound2-dev
我们可以打开iat_online_record_sample文件夹下的iat_online_record_sample.c文件(由于文件300多行这里就不粘贴了),熟悉一下里面核心的API。
大体上main函数里包括这些:
demo_mic:
static void demo_mic(const char* session_begin_params) { int errcode; int i = 0; struct speech_rec iat; struct speech_rec_notifier recnotifier = { on_result, on_speech_begin, on_speech_end }; 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); } /* demo 15 seconds recording */ while(i++ < 15) sleep(1); errcode = sr_stop_listening(&iat); if (errcode) { printf("stop listening failed %d\n", errcode); } sr_uninit(&iat); }
我们需要关注里面的 on_result 的结果是如何发布的:
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); } }
从代码中我们猜想只要拿到这里的 g_result 这个全局变量就可以拿到最终的识别结果。
再来看一看tts_online_sample.c中的代码,text_to_speech是语音合成关键的函数:
const char* filename = "tts_sample.wav"; //合成的语音文件名称
const char* text = "亲爱的用户,您好,这是一个语音合成示例,感谢您对科大讯飞语音技术的支持!科大讯飞是亚太地区最大的语音上市公司,股票代码:002230"; //合成文本
ret = text_to_speech(text, filename, session_begin_params);
通过这些代码结合用户登录和函数text_to_speech等,将text内的文字转换成了语音保存到了filename的文件中。
当然,我们可以修改代码,将语音直接输出出来。在文件末173行左右:
printf("合成完毕\n");
popen("play tts_sample.wav","r");
//就是这句话很关键,但是需要提前确认Linux系统可以使用play
所以我们安装play相关的工具:(第一句话因SDK包名而异)
$ cd cd Linux_iat1227_tts_online1227_5e9199eb/libs/x64
$ sudo cp libmsc.so /usr/lib/
$ sudo apt install sox
$ sudo apt install libsox-fmt-all
科大讯飞的SDK带有ID号,每个人每次下载后的ID都不相同,更换SDK之后需要修改代码中的APPID。APPID可以在SDK包的名字后几位可以看到。
通过修改上面提供的SDK源码文件,改成可以在ROS环境下使用的功能包,达成语音识别的目的。这个功能框图,描述了我们将通过一个唤醒词,就像“Hi Siri”一样,这里通过一个std_msgs::String的话题消息唤醒语音识别的功能,而不是执行一次./iat_online_record_sample识别一次;随后通过Result将识别后的文字包装成话题发布出去,可供其他操作者调用。
步骤:
这里我把iat_publish.cpp
全部代码都粘贴到了页面上,大家可以对比下载下来的SDK中iat_online_record_sample.c文件。多数代码都是讯飞提供的SDK的内容,我会解读其中修改的重要的部分:(解读的部分都由注释放置到对应的位置)
/* * 语音听写(iFly Auto Transform)技术能够实时地将语音转换成对应的文字。 */ #include <stdlib.h> #include <stdio.h> #include <string.h> #include <unistd.h> #include "robot_voice/qisr.h" //这里我们将头文件都放到了robot_voice/include/robot_voice文件夹内 #include "robot_voice/msp_cmn.h" #include "robot_voice/msp_errors.h" #include "robot_voice/speech_recognizer.h" #include "ros/ros.h" //调用ROS的头文件和发布消息类型的头文件 #include "std_msgs/String.h" #define FRAME_LEN 640 #define BUFFER_SIZE 4096 int wakeupFlag = 0 ; //创建两个全局变量,wakeupFlag用来显示是否被唤醒;resultFlag标志有没有语音识别的结果 int resultFlag = 0 ; //跳转到main函数,其他函数大多没有修改都是科大讯飞给出的 /* Upload User words */ static int upload_userwords() { char* userwords = NULL; size_t len = 0; size_t read_len = 0; FILE* fp = NULL; int ret = -1; fp = fopen("userwords.txt", "rb"); if (NULL == fp) { printf("\nopen [userwords.txt] failed! \n"); goto upload_exit; } fseek(fp, 0, SEEK_END); len = ftell(fp); fseek(fp, 0, SEEK_SET); userwords = (char*)malloc(len + 1); if (NULL == userwords) { printf("\nout of memory! \n"); goto upload_exit; } read_len = fread((void*)userwords, 1, len, fp); if (read_len != len) { printf("\nread [userwords.txt] failed!\n"); goto upload_exit; } userwords[len] = '\0'; MSPUploadData("userwords", userwords, len, "sub = uup, dtt = userword", &ret); //ÉÏ´«Óû§´Ê±í if (MSP_SUCCESS != ret) { printf("\nMSPUploadData failed ! errorCode: %d \n", ret)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。