Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
网络学习营
【7天入门RTOS网络编程】Nautilus day8 END作业
发布于 2018-10-25 20:20:25 浏览:1395
订阅该版
* 本帖最后由 yukelab 于 2018-10-26 19:33 编辑 * **题目要求**1. 在板子上能够发送一段文字给[百度语音](http://yuyin.baidu.com/)合成服务,获取语音合成链接,然后下载下来。2. 然后用这一段音频或者事先录制好的一段语音,通过百度语义识别功能,获取语音识别结果,然后根据语音识别的结果来模拟实现控制 led 灯的亮灭。 **完成思路**目前来看,SDK之类的还没有移植到rt-thread中,估计使用http服务来做了,看了下文档(文档地址: [https://ai.baidu.com/docs#/TTS-API/top](https://ai.baidu.com/docs#/TTS-API/top))看来是要创建应用。那工作就比较明朗了,线程的webclient用起来就好了。题目1,向服务器发送获取文件的请求,得到文件保存就好;题目2,向服务器发送文件,得到json文本,对其result字段进行解析,得到语义识别结果,对语义结果进行分析,得到命令字段,进而控制外设;手头没有板子,还是使用qemu工具,所以外设控制就略去了。**具体步骤****题目1****注意**一定要关闭防火墙Tex段为纯英文会产生400错误代码就比较简单了**代码**自己编写了一个,后来看了下web_client的手册,发现有已完成的函数,就更加easy了```#include
#include
#include "webclient.h" #include
/* 当需要使用文件操作时,需要包含这个头文件 */ /* 语音合成 */ #define GET_RESP_BUFSZ 2048 #define GET_HEADER_BUFSZ 2048 #define GET_URL_LEN_MAX 2048 //需要语音合成 #define FILE_NAME_MAX 32 /* 默认返回的是MP3文件 */ /* lan=zh时,输入必须含有中文,否则会产生400错误码 */ #define GET_URI "http://tsn.baidu.com/text2audio?tex=%s&lan=zh&cuid=74-E5-F9-56-EF-B4&ctp=1&aue=4&tok=24.3f9eb59e31d150561c7a0cda5835b69b.2592000.1542944661.282335-14532805" #define VOICE_ID1 "你好,我是Nautilus" #define VOICE_ID2 "你好,ConEmu没法输入中文啊" /* 测试全英文会返回400error */ #define VOICE_ID3 "all english" #define MP3_FILE "/baidu/%s.wav" /* 语音识别 */ #define POST_FILE_URL "http://vop.baidu.com/server_api?dev_pid=1536&cuid=74-E5-F9-56-EF-B4&token=24.3f9eb59e31d150561c7a0cda5835b69b.2592000.1542944661.282335-14532805" #define POST_RESP_BUFSZ 2048 #define POST_HEADER_BUFSZ 1024 /* Content-Type: audio/pcm;rate=16000 */ #define C_TYPE "audio/wav;rate=16000" /* debug */ #include
static int webclient_get_baidu_voice(int argc, char **argv) { struct webclient_session* session = RT_NULL; unsigned char *buffer = RT_NULL; char *URI = RT_NULL; char *file_name = RT_NULL; int ret = 0; int bytes_read, resp_status; int content_length = -1; int fd; int length; if (argc == 1) { URI = rt_calloc(1, GET_URL_LEN_MAX); if (URI == RT_NULL) { rt_kprintf("No memory for url!
"); return -1; } /* 拼接 GET 网址 */ rt_snprintf(URI, GET_URL_LEN_MAX, GET_URI, VOICE_ID1); rt_kprintf("URL:%s", URI); file_name = rt_calloc(1, FILE_NAME_MAX); if (file_name == RT_NULL) { rt_kprintf("No memory for file name!
"); return -1; } /* 拼接 GET 网址 */ rt_snprintf(file_name, FILE_NAME_MAX, MP3_FILE, "1"); } else if (argc == 2) { URI = rt_calloc(1, GET_URL_LEN_MAX); if (URI == RT_NULL) { rt_kprintf("No memory for url!
"); return -1; } /* 拼接 GET 网址 */ /* rt_snprintf(URI, GET_URL_LEN_MAX, GET_URI, argv[1]); */ rt_snprintf(URI, GET_URL_LEN_MAX, GET_URI, VOICE_ID2); rt_kprintf("URL:%s", URI); file_name = rt_calloc(1, FILE_NAME_MAX); if (file_name == RT_NULL) { rt_kprintf("No memory for file name!
"); return -1; } /* 拼接 GET 网址 */ rt_snprintf(file_name, FILE_NAME_MAX, MP3_FILE, argv[1]); } else if (argc == 3) { /* 测试全英文会返回400error */ URI = rt_calloc(1, GET_URL_LEN_MAX); if (URI == RT_NULL) { rt_kprintf("No memory for url!
"); return -1; } /* 拼接 GET 网址 */ /* rt_snprintf(URI, GET_URL_LEN_MAX, GET_URI, argv[1]); */ rt_snprintf(URI, GET_URL_LEN_MAX, GET_URI, VOICE_ID3); rt_kprintf("URL:%s", URI); file_name = rt_calloc(1, FILE_NAME_MAX); if (URI == RT_NULL) { rt_kprintf("No memory for file name!
"); return -1; } /* 拼接 GET 网址 */ rt_snprintf(file_name, FILE_NAME_MAX, MP3_FILE, argv[2]); } else { rt_kprintf("webclient_get_test [URI] - webclient GET request test.
"); return -1; } buffer = (unsigned char *) web_malloc(GET_HEADER_BUFSZ); if (buffer == RT_NULL) { rt_kprintf("no memory for receive buffer.
"); ret = -RT_ENOMEM; goto __exit; } /* create webclient session and set header response size */ session = webclient_session_create(GET_HEADER_BUFSZ); if (session == RT_NULL) { ret = -RT_ENOMEM; goto __exit; } /* send GET request by default header */ if ((resp_status = webclient_get(session, URI)) != 200) { rt_kprintf("webclient GET request failed, response(%d) error.
", resp_status); ret = -RT_ERROR; goto __exit; } fd = open(file_name, O_WRONLY | O_CREAT | O_TRUNC, 0); if (fd < 0) { rt_kprintf("open file for write failed
"); } content_length = webclient_content_length_get(session); if (content_length < 0) { rt_kprintf("webclient GET request type is chunked.
"); do { bytes_read = webclient_read(session, buffer, GET_RESP_BUFSZ); if (bytes_read <= 0) { break; } /* 写入数据 */ length = write(fd, buffer, bytes_read); if (length != bytes_read) { rt_kprintf("write data failed in if
"); close(fd); break; } } while (1); rt_kprintf("
"); } else { int content_pos = 0; do { bytes_read = webclient_read(session, buffer, content_length - content_pos > GET_RESP_BUFSZ ? GET_RESP_BUFSZ : content_length - content_pos); if (bytes_read <= 0) { break; } length = write(fd, buffer, bytes_read); if (length != bytes_read) { rt_kprintf("write data failed in else
"); close(fd); break; } content_pos += bytes_read; } while (content_pos < content_length); rt_kprintf("
"); } __exit: if (session) { webclient_close(session); } if (buffer) { web_free(buffer); } if (URI) { web_free(URI); } if (file_name) { web_free(file_name); } if (fd > 0) { close(fd); } return ret; } #ifdef FINSH_USING_MSH #include
MSH_CMD_EXPORT_ALIAS(webclient_get_baidu_voice, baidu_voice, web_get_test [URI] webclient GET request test); ``` **题目2**对照百度文档,简单测一下,保证webapi没有问题 为了进行语音识别aue段应该设为4或6,为了便于播放此段设为6,wav格式在获取语音的时候,应当使用3为mp3格式(默认); 4为pcm-16k;5为pcm-8k;6为wav(内容同pcm-16k); 注意aue=4或者6是语音识别要求的格式,但是音频内容不是语音识别要求的自然人发音,所以识别效果会受影响。**运行结果**语音合成没有问题,语音识别,文件上传过程中,http connect 及 header发送没有问题,当写文件内容是,会出错,解决ing**![2.png](/uploads/201810/25/203454l7i8xi18112i111j.png)** 下载附件 [hw_end.pdf](https://oss-club.rt-thread.org/uploads/201810/25/203029wgg554i9sgcd42si.attach)
查看更多
3
个回答
默认排序
按发布时间排序
yqiu
2018-10-25
这家伙很懒,什么也没写!
很强!
san兄弟
2018-10-26
这家伙很懒,什么也没写!
佩服佩服
yukelab
2018-10-26
这家伙很懒,什么也没写!
[i=s] 本帖最后由 yukelab 于 2018-10-26 19:40 编辑 [/i] [attach]6672[/attach] 感觉webchient2.0.1的post方式有bug,每次添加Host段后,就会导致内存出问题,没有将合适的Host段拷贝到Header位置,又搞了一天,修复这个bug,还没有结果;不过将版本调换到webchient1.0.0,参考了论坛中的方案,webchient1.0.0中实现了语音识别;贴上代码 ``` #include
#include "webclient.h" #include "webclient_internal.h" #ifdef RT_USING_FINSH #include
#endif #ifdef RT_USING_DFS #include
const char *p_voice_url = "http://vop.baidu.com/server_api?dev_pid=1536&cuid=74-E5-F9-56-EF-B4&token=24.3f9eb59e31d150561c7a0cda5835b69b.2592000.1542944661.282335-14532805"; const char *url_fil = "/baidu/1.pcm"; int post_voice_file(const char* uri, const char* filename, const char* form_data) { size_t length; char boundary[60]; int fd = -1, rc = WEBCLIENT_OK; char *header = NULL, *header_ptr; unsigned char *buffer = NULL, *buffer_ptr = NULL; struct webclient_session* session = NULL; char *ptr = NULL; char cmd_buffer[256]; char i = 0; fd = open(filename, O_RDONLY, 0); if (fd < 0) { rc = -WEBCLIENT_FILE_ERROR; goto __exit; } /* get the size of file */ length = lseek(fd, 0, SEEK_END); lseek(fd, 0, SEEK_SET); buffer = web_malloc(WEBCLIENT_RESPONSE_BUFSZ); if (buffer == NULL) { rc = -WEBCLIENT_NOMEM; goto __exit; } session = (struct webclient_session*) web_malloc(sizeof(struct webclient_session)); if (!session) { rc = -WEBCLIENT_NOMEM; goto __exit; } memset(session, 0x0, sizeof(struct webclient_session)); rc = webclient_connect(session, uri); if (rc < 0) goto __exit; rt_kprintf("Start upload voice file to baidu ...\r\n"); header = (char*) web_malloc(WEBCLIENT_HEADER_BUFSZ); if (header == NULL) { rc = -WEBCLIENT_NOMEM; goto __exit; } header_ptr = header; /* build boundary */ rt_snprintf(boundary, sizeof(boundary), "----------------------------%012d", rt_tick_get()); /* build encapsulated mime_multipart information*/ buffer_ptr = buffer; /* first boundary */ buffer_ptr += rt_snprintf((char*) buffer_ptr, WEBCLIENT_RESPONSE_BUFSZ - (buffer_ptr - buffer), "--%s\r\n", boundary); buffer_ptr += rt_snprintf((char*) buffer_ptr, WEBCLIENT_RESPONSE_BUFSZ - (buffer_ptr - buffer), "Content-Disposition: form-data; %s\r\n", form_data); buffer_ptr += rt_snprintf((char*) buffer_ptr, WEBCLIENT_RESPONSE_BUFSZ - (buffer_ptr - buffer), "Content-Type: application/octet-stream\r\n\r\n"); /* calculate content-length */ length += buffer_ptr - buffer; length += strlen(boundary) + 6; /* add the last boundary */ /* build header for upload */ header_ptr += rt_snprintf(header_ptr, WEBCLIENT_HEADER_BUFSZ - (header_ptr - header), "Content-Length: %d\r\n", length); header_ptr += rt_snprintf(header_ptr, WEBCLIENT_HEADER_BUFSZ - (header_ptr - header), "Content-Type:%s\r\n", form_data); /* send header */ rc = webclient_send_header(session, WEBCLIENT_POST, header, header_ptr - header); if (rc < 0) goto __exit; /* send mime_multipart */ webclient_write(session, buffer, buffer_ptr - buffer); /* send file data */ int send_cnt = 0; while (1) { length = read(fd, buffer, WEBCLIENT_RESPONSE_BUFSZ); if (length <= 0) break; rt_kprintf("sent %d msg\n", ++send_cnt); webclient_write(session, buffer, length); } /* send last boundary */ rt_snprintf((char*) buffer, WEBCLIENT_RESPONSE_BUFSZ, "\r\n--%s--\r\n", boundary); webclient_write(session, buffer, strlen(boundary) + 6); close(fd); rt_kprintf("Upload voice data successfully\r\n"); /* 数据发送完了后,必须进行一个小延时,等待响应,确保可以接收到服务器的响应 */ rt_thread_delay(10); /* get response */ if (webclient_handle_response(session)) { if (session->response != 200) { rt_kprintf("webclient handle response(%d) error!", session->response); goto __exit; } } ptr = buffer; length = webclient_read(session, ptr, WEBCLIENT_RESPONSE_BUFSZ); ptr[length] = '\0'; rt_kprintf("Get %d bytes response from baidu voice recognition system successfully\r\n", length); for (i = 0; i < length; i++) { rt_kprintf("%c",buffer[i]); } rt_kprintf("\r\n"); __exit: if (fd >= 0) close(fd); if (session != NULL) webclient_close(session); if (buffer != NULL) web_free(buffer); if (header != NULL) web_free(header); } /* MSH_CMD_EXPORT(post_voice_file, Get voice control data); */ int wpost(void) { post_voice_file(p_voice_url,url_fil,"audio/pcm;rate=16000" ); return 0; } MSH_CMD_EXPORT(wpost, web post voice file to baidu); #endif ``` [attach]6673[/attach]
撰写答案
登录
注册新账号
关注者
0
被浏览
1.4k
关于作者
yukelab
这家伙很懒,什么也没写!
提问
17
回答
47
被采纳
1
关注TA
发私信
相关问题
1
【LWIP学习营】第一关开发环境搭建
2
LWIP学习营第一周入门移植问题汇总贴
3
【LWIP学习营】f407+lan8720A小结
4
【LwIP学习营】【第一周】仅零散记录,无主题
5
【LWIP学习营】正点原子探索者F407+LAN8720第一周小结
6
【LwIP学习营】【第一周】网络通信基础及实现TCP 聊天客户端
7
【LwIP学习营】【第一周】LWIP移植
8
【LwIP学习营】【第一周】LWIP移植
9
【LwIP学习营】【第一周】开发板适配
10
【LwIP学习营】【第一周】环境搭建和配置验证
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
最新文章
1
GD32F450 片内 flash驱动适配
2
STM32H7R7运行CherryUSB
3
RT-Smart首次线下培训,锁定2024 RT-Thread开发者大会!
4
使用RC522软件包驱动FM1722
5
常量数据类型和表达式陷阱分享
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
USB
DMA
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
ESP8266
I2C_IIC
UART
WIZnet_W5500
ota在线升级
freemodbus
PWM
flash
cubemx
packages_软件包
BSP
潘多拉开发板_Pandora
定时器
ADC
flashDB
GD32
socket
中断
编译报错
Debug
SFUD
rt_mq_消息队列_msg_queue
msh
keil_MDK
ulog
C++_cpp
MicroPython
本月问答贡献
a1012112796
10
个答案
1
次被采纳
踩姑娘的小蘑菇
4
个答案
1
次被采纳
红枫
4
个答案
1
次被采纳
张世争
4
个答案
1
次被采纳
Ryan_CW
4
个答案
1
次被采纳
本月文章贡献
catcatbing
3
篇文章
5
次点赞
YZRD
2
篇文章
3
次点赞
qq1078249029
2
篇文章
2
次点赞
xnosky
2
篇文章
1
次点赞
Woshizhapuren
1
篇文章
5
次点赞
回到
顶部
发布
问题
分享
好友
手机
浏览
扫码手机浏览
投诉
建议
回到
底部