准备工作
在本次实践开始之前,你必须确保你已经做了以下两件事:
- 注册百度开发者账号,并创建了一个语音识别应用,而且成功获取了Access Token(工程里将会用到);
- 建立一个基于你自己的STM32平台的RT-Thread工程,它必须具备Finsh控制台,文件系统,网络功能(不明白的参见RT-Thread文档中心,网络功能推荐使用AT组件+ESP8266,因为这是最简单快捷的方法)。
如果上面说的准备事项没有问题,那么请继续往下看:
这次我们将先跳过录音功能,而使用事先准备好的音频文件进行语音识别并控制板载RGB灯(上一篇的5,6点),所以你还需要准备一些音频文件,比如“红灯开”,“蓝灯关”。。。我是用手机录的音频,然后使用ffmpeg工具将音频转为百度语音官方认为最适合的16k采样率pcm文件,最后将这些音频文件放进sd卡中,我们的文件系统也是挂载在sd卡上的。
动手实践
本次工程会用到RT-Thread的两个软件包:webclient和CJSON软件包,你需要使用ENV工具将这两个软件包添加进工程里。
好了,开始写代码:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
/* 使用外设需要的头文件 */
/* 获取RGB灯对应的引脚编号 */
/* URL */
/* 头部数据(必需) */
char *form_data = "audio/pcm;rate=16000";
/* 预定义的命令 */
char *cmd1 = "打开红灯";
char *cmd2 = "关闭红灯";
char *cmd3 = "打开蓝灯";
char *cmd4 = "关闭蓝灯";
char *cmd5 = "打开绿灯";
char *cmd6 = "关闭绿灯";
/************************************************
函数名称 : bd
功 能 : 将音频文件发送到百度语音服务器,并接收响应数据
参 数 : 音频文件名(注意在文件系统中的位置,默认根目录)
返 回 值 : void
作 者 : rtthread;霹雳大乌龙
*************************************************/
void bd(int argc, char **argv)
{
char *filename = NULL;
unsigned char *buffer = RT_NULL;
int content_length = -1, bytes_read = 0;
int content_pos = 0;
int ret = 0;
/* 判断命令是否合法 */
if(argc != 2)
{
rt_kprintf("bd <filename>\r\n");
return;
}
/* 获取音频文件名 */
filename = argv[1];
/* 以只读方式打开音频文件 */
int fd = open(filename, O_RDONLY, 0);
if(fd < 0)
{
rt_kprintf("open %d fail!\r\n", filename);
goto __exit;
}
/* 获取音频文件大小 */
size_t length = lseek(fd, 0, SEEK_END);
lseek(fd, 0, SEEK_SET);
/* 创建响应数据接收数据 */
buffer = (unsigned char *) web_malloc(RES_BUFFER_SIZE);
if(buffer == RT_NULL)
{
rt_kprintf("no memory for receive response buffer.\n");
ret = -RT_ENOMEM;
goto __exit;
}
/* 创建会话 */
struct webclient_session *session = webclient_session_create(HEADER_BUFFER_SIZE);
if(session == RT_NULL)
{
ret = -RT_ENOMEM;
goto __exit;
}
/* 拼接头部数据 */
webclient_header_fields_add(session, "Content-Length: %d\r\n", length);
webclient_header_fields_add(session, "Content-Type: %s\r\n", form_data);
/* 发送POST请求 */
int rc = webclient_post(session, POST_FILE_URL, NULL);
if(rc < 0)
{
rt_kprintf("webclient post data error!\n");
goto __exit;
}else if (rc == 0)
{
rt_kprintf("webclient connected and send header msg!\n");
}else
{
rt_kprintf("rc code: %d!\n", rc);
}
while(1)
{
rt_memset(buffer, 0, RES_BUFFER_SIZE);
length = read(fd, buffer, RES_BUFFER_SIZE);
if(length <= 0)
{
break;
}
ret = webclient_write(session, buffer, length);
if(ret < 0)
{
rt_kprintf("webclient write error!\r\n");
break;
}
rt_thread_mdelay(100);
}
close(fd);
rt_kprintf("Upload voice data successfully\r\n");
if(webclient_handle_response(session) != 200)
{
rt_kprintf("get handle resposne error!");
goto __exit;
}
/* 获取接收的响应数据长度 */
content_length = webclient_content_length_get(session);
rt_thread_delay(100);
do
{
bytes_read = webclient_read(session, buffer, 1024);
if (bytes_read <= 0)
{
break;
}
for(int index = 0; index < bytes_read; index++)
{
rt_kprintf("%c", buffer[index]);
}
content_pos += bytes_read;
}while(content_pos < content_length);
/* 解析json数据 */
bd_data_parse(buffer);
__exit:
if(fd >= 0)
close(fd);
if(session != NULL)
webclient_close(session);
if(buffer != NULL)
web_free(buffer);
return;
}
/* 导出为命令形式 */
MSH_CMD_EXPORT(bd, webclient post file);
1 | /************************************************ |
只需以上的代码,你就可以实现百度语音识别以及控制相应外设了。下面看看实际效果:
我使用的潘多拉开发板板载了stlink(且其为我们提供了一个虚拟串口),用usb数据线将开发板和电脑连接起来,将代码烧写进开发板后,我们利用这个虚拟串口,使用Xshell一类的终端软件,就可以看到如下的开机画面:
这便是RT-Thread提供的Finsh控制台组件,使用这个组件,我们可以方便地观察程序的运行状态,以命令行的形式调试运行程序,从图中我们可以看到,我们需要的文件系统和网络功能都已经初始化成功。
使用ls命令看看:
欸~,这便是我事先准备好的音频文件。
在上面的代码中,我们可以看到有这样一句:1
MSH_CMD_EXPORT(bd, webclient post file);
通过这行代码,我们就可以在Finsh控制台里使用bd这个命令,这个命令就是将音频文件发送到百度语音服务器,试试看:
看,我使用bd命令将greenon.pcm发送到百度语音服务器,正确识别出结果:“打开绿灯”;于此同时,rgb灯也亮起了绿色
尝试其他音频文件,效果完美!!!
好了,本次分享也就到这了,觉得不错的帮忙转发点个在看哦~