|
stm32单片机裸机调用百度语音识别接口和合成接口的部分代码实现
[复制链接]
stm32单片机裸机调用百度语音识别接口和合成接口的部分代码实现,---作者:阮丁远(版权所有
此内容由EEWORLD论坛网友net2uizoo原创,如需转载或用于商业用途需征得作者同意并注明出处
)
先介绍个要用到的函数:lwip 下 WebClient或者说http cilent的实现:
- int8_t WebClient(const char *url, const char *post, uint8_t **pageBuf,uint8_t is_upload_wav,uint32_t wav_len1)
- {
-
- uint32_t i;
-
- uint8_t server_addr[200];//这2个放在局部变量里,防止多线程冲突:
- uint8_t web_addr[1200];//有的tts的二次url编码后的请求长度很长,所以这个大点
- ip_addr_t server_ip;
-
-
- uint8_t ishttps;
- uint16_t start_char_i;
- uint16_t start_len1;
- uint32_t ret_lens;
- err_t err ;
-
- uint32_t j, k;
- uint32_t head_and_wav_len1;
-
- struct netconn *conn = NULL;
- struct netbuf *inBuf = NULL;
- struct pbuf *q;
- char *request = NULL;
- uint32_t recvPos = 0;
- uint8_t *recvBuf;
- err_t err_msg;
-
-
-
-
- while(wifi_88w8801_sta.ip_addr.addr == 0x00)
- {
- return HTTP_ROUTE_NOT_FOUND;
- }
-
-
-
- if(strncasecmp((const char *)url, "http://", 7) == 0||strncasecmp((const char *)url, "https://", 8) == 0) /* 只处理http协议 */
- {
-
-
- if(strncasecmp((const char *)url, "http://", 7) == 0){
-
- ishttps=0;
- start_char_i=4;
- start_len1=7;
- }
-
- if(strncasecmp((const char *)url, "https://", 8) == 0){
-
- ishttps=1;
- start_char_i=5;
- start_len1=8;
- }
-
-
- if(ishttps==0){
- ////改为全局变量式,可以防止内存泄露:
- //server_addr = pvPortMalloc2 strlen(url) - 7);
-
- }else{
-
- ////改为全局变量式,可以防止内存泄露:
- //server_addr = pvPortMalloc2 strlen(url) - 8);
-
- }
-
-
- ////改为全局变量式,可以防止内存泄露:
- // if(server_addr == NULL) {
- //
- // printf("HTTP_OUT_OF_RAM in malloc server_addr");
- //
- // return HTTP_OUT_OF_RAM;
- //
- //
- // }
-
- printf("proceess 1\r\n");
-
-
- /* 1)提取服务器部分 */
- for(i = start_char_i; url[i]; ++i)
- {
- if (url[i] == ':' && url[i + 1] == '/' && url[i + 2] == '/')
- {
- for (i = i + 3, j = 0; url[i] > 32 && url[i] < 127 && url[i] != '/'; //32-127间的ascII码的字符
- ++i, ++j)
- {
- server_addr[j] = url[i];
- if (url[i] == '@') /* 服务器基础认证符号,我们做不了,遇到就错误. */
- {
- return HTTP_AUTH_NOT_SUPPORT;
- }
- }
- server_addr[j] = '\0';
-
-
- ////改为全局变量式,可以防止内存泄露:
- //web_addr = pvPortMalloc2 strlen(url) - start_len1 - strlen((const char *)server_addr));
- //if(web_addr == NULL) return HTTP_OUT_OF_RAM;
-
- for (k = start_len1 + j; k < (strlen(url)); k++) /* 后半部分提取 */
- {
- web_addr[k - start_len1 - j] = url[k];
- }
-
- web_addr[k - start_len1 - j] = '\0';
-
- while (--j)
- {
- if (server_addr[j] == ':')//??过滤端口号?
- {
- server_addr[j] = '\0';
- }
- }
- }
-
- }
-
- if(strlen((const char *)server_addr) < 2) /* 最短网址3.cn */
- {
-
-
- printf("HTTP_SERVER_ADDR_ERROR\r\n");
-
-
-
- printf(server_addr);
-
- ////改为全局变量式,可以防止内存泄露:
- //vPortFree2 server_addr);
-
- ////改为全局变量式,可以防止内存泄露:
- // if(web_addr == NULL) {vPortFree2 web_addr); }
-
- /* 这么短,还不一定提取到了这个. */
-
-
- return HTTP_SERVER_ADDR_ERROR;
- }
-
- printf("\r\nweb host:");
-
- printf(server_addr);
-
-
-
- /* 2)查询IP */
- netconn_gethostbyname((const char *)server_addr, &server_ip);
-
-
-
- //
- // server_ip.addr=0;
- // err = dns_gethostbyname((const char *)server_addr, &server_ip,dns_foundB , NULL);//dns_foundB
- // if (err == ERR_OK)
- // {
- // printf("In cache! IP: %s\n", ipaddr_ntoa(&server_ip));
-
- // }
- //
- //
- // while(server_ip.addr==0){
- //
- //
- // }
- //
- printf("get a IP: %s\n", ipaddr_ntoa(&server_ip));
-
-
- if(is_upload_wav==1){
- /* 3)构造访问头 */
-
-
-
- request = pvPortMalloc2( strlen(url) + wav_len1+1024); /* 头所需内存大小. */
-
-
-
-
- }else if(is_upload_wav==0){
-
- request = pvPortMalloc2( strlen(url) + 1024); /* 头所需内存大小. */
-
- }else if(is_upload_wav==2){
-
- request = pvPortMalloc2( strlen(url) + 1024); /* 头所需内存大小. */
-
- }
-
- if(request == NULL)
- {
-
-
- printf("HTTP_OUT_OF_RAM in request Malloc.");
-
- return HTTP_OUT_OF_RAM;
-
- }
-
-
- if(is_upload_wav==1){
-
-
-
- #if upload_Wav0_or_pcm1 ==0
- sprintf(request, "POST %s HTTP/1.0\r\nHost: %s\r\nUser-Agent:Mozilla/5.0 (Windows; U; Windows NT 6.1; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50\r\nContent-Length: %d\r\nContent-Type: audio/wav;rate=8000\r\n\r\n", web_addr, server_addr, wav_len1);
- #endif
-
-
-
- #if upload_Wav0_or_pcm1 ==1
- sprintf(request, "POST %s HTTP/1.0\r\nHost: %s\r\nUser-Agent:Mozilla/5.0 (Windows; U; Windows NT 6.1; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50\r\nContent-Length: %d\r\nContent-Type: audio/pcm;rate=8000\r\n\r\n", web_addr, server_addr, wav_len1);
- #endif
-
- head_and_wav_len1=strlen(request)+wav_len1;
-
- memcpy( &request[strlen(request)],post,wav_len1);
-
-
-
- }else if(is_upload_wav==0){
-
- if(post != NULL){
- sprintf(request, "POST %s HTTP/1.0\r\nHost: %s\r\nUser-Agent:Mozilla/5.0 (Windows; U; Windows NT 6.1; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50\r\nContent-Length: %d\r\nContent-Type: application/x-www-form-urlencoded\r\n\r\n%s", web_addr, server_addr, strlen(post), post);
-
-
-
- // printf( "POST %s HTTP/1.0\r\nHost: %s\r\nUser-Agent: Mozilla/5.0 (lwip;STM32) TaterLi\r\nContent-Length: %d\r\nContent-Type: application/x-www-form-urlencoded\r\n\r\n%s", web_addr, server_addr, strlen(post), post);
-
-
- }else{
- sprintf(request, "GET %s HTTP/1.0\r\nHost: %s\r\nUser-Agent:Mozilla/5.0 (Windows; U; Windows NT 6.1; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50\r\n\r\n", web_addr, server_addr);
-
-
-
- }
-
- }else if(is_upload_wav==2){
-
-
- sprintf(request, "GET %s HTTP/1.0\r\nHost: %s\r\nUser-Agent:Mozilla/5.0 (Windows; U; Windows NT 6.1; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50\r\n\r\n", web_addr, server_addr);
- MP3_return_data_len=0;
-
- }
-
- //vPortFree2 (server_addr);
- if(web_addr != NULL)
- {
- /* 万一没提取到,就是NULL,如果是NULL,那么也不用继续了. */
- ////改为全局变量式,可以防止内存泄露:
- //vPortFree2 web_addr);
- }
- else
- {
- vPortFree2 (request);
-
- printf("HTTP_NOT_VALID_ADDR");
- return HTTP_NOT_VALID_ADDR;
- }
-
-
- /* 4)开始访问 */
- conn = netconn_new(NETCONN_TCP);
-
-
- err_msg = netconn_connect(conn, &server_ip, 80); /* 目前也只能支持80端口,比较常用,不考虑特殊情况. */
-
-
-
-
- if (err_msg == ERR_OK)
- {
- // struct netbuf *inBuf_g = NULL;
-
-
- if(is_upload_wav==1){
- netconn_write(conn, request, head_and_wav_len1, NETCONN_COPY);
-
- }else if(is_upload_wav==0){
- netconn_write(conn, request, strlen((char *)request), NETCONN_COPY);
-
-
- }else if(is_upload_wav==2){
-
- netconn_write(conn, request, strlen((char *)request), NETCONN_COPY);
-
-
- }
-
-
- vPortFree2 (request);
- conn->recv_timeout = 15000;//15s
-
- recvPos = 0;
-
- if(is_upload_wav==2){
-
- u32 offsetptr;
-
-
- void *data;
- u16_t len;
-
-
-
-
- recvPos = 0;
-
-
-
- ret_lens=0;
- offsetptr=0;
- while(1)
- {
- err=netconn_recv(conn, &inBuf);
-
- if(inBuf==NULL){
-
- break;
- }
-
- do
- {
- netbuf_data(inBuf, &data, &len);
-
-
- memcpy(MP3_return_data+ret_lens,data,len);
-
- ret_lens+=len;
-
-
- }
- while (netbuf_next(inBuf) >= 0);
-
-
-
- printf("ret_lens=%d\r\n",ret_lens);
- netbuf_delete(inBuf);
- }
-
-
-
-
-
-
- // printf (MP3_return_data);
-
-
-
-
-
-
- netconn_close(conn);
- netconn_delete(conn);
- // netbuf_delete(inBuf);
-
-
-
-
-
-
-
- /* 5)分析数据(分析HTTP头,暂时不打算支持301之类的) */
- for(i = 0; MP3_return_data[i]; ++i)
- {
- if (MP3_return_data[i] == '2' && MP3_return_data[i + 1] == '0' && MP3_return_data[i + 2] == '0')
- {
- /* 证明200 OK */
- for(; MP3_return_data[i]!='\0'; ++i)
- {
- /* 响应头的结束也是两个回车 */
- if(MP3_return_data[i] == '\r' && MP3_return_data[i + 1] == '\n' && MP3_return_data[i + 2] == '\r' && MP3_return_data[i + 3] == '\n')
- {
- /* 6)复制正文内容 */
- i += 4;
- k = ret_lens - i;
- if(k == 0) return HTTP_NO_CONTENT;
-
-
- MP3_return_data_len=k;
-
- MP3_return_data_start_offset=i;
-
-
- printf("MP3_return_data_len=%d\r\n",MP3_return_data_len);
-
-
-
- //printf(MP3_return_data);
- return HTTP_OK;
- }
- }
- }
- }
-
-
-
-
-
- }else{
-
-
-
-
- void *data;
- u16_t len;
-
-
-
- u32 offsetptr;
- recvBuf = pvPortMalloc2( 1024*1024);
- recvPos = 0;
-
-
- ret_lens=0;
- offsetptr=0;
- while(1)
- {
- netconn_recv(conn, &inBuf);
-
- if(inBuf==NULL){
-
- break;
- }
-
-
- do
- {
- netbuf_data(inBuf, &data, &len);
-
-
- memcpy(recvBuf+ret_lens,data,len);
-
- ret_lens+=len;
-
-
- }
- while (netbuf_next(inBuf) >= 0);
-
-
- recvBuf[ret_lens]='\0';
-
-
-
- netbuf_delete(inBuf);
-
-
-
- }
-
- netconn_close(conn);
- netconn_delete(conn);
-
-
-
-
- // if(err_msg != ERR_OK) {
- //
- // printf("HTTP_OUT_OF_RAM in err_msg != ERR_OK");
- //
- // return HTTP_OUT_OF_RAM;
- //
- //
- //
- // }
-
-
-
-
- /* 5)分析数据(分析HTTP头,暂时不打算支持301之类的) */
- for(i = 0; recvBuf[i]; ++i)
- {
- if (recvBuf[i] == '2' && recvBuf[i + 1] == '0' && recvBuf[i + 2] == '0')
- {
- /* 证明200 OK */
- for(; recvBuf[i]!='\0'; ++i)
- {
- /* 响应头的结束也是两个回车 */
- if(recvBuf[i] == '\r' && recvBuf[i + 1] == '\n' && recvBuf[i + 2] == '\r' && recvBuf[i + 3] == '\n')
- {
- /* 6)复制正文内容 */
- i += 4;
- k = ret_lens - i;
- if(k == 0) return HTTP_NO_CONTENT;
- *pageBuf = pvPortMalloc2 (k);
- if(*pageBuf == NULL)
- {
- vPortFree2 (recvBuf);
-
-
- printf("HTTP_OUT_OF_RAM in malloc pageBuf");
-
- return HTTP_OUT_OF_RAM;
- }
-
- memset((char *)*pageBuf,0,k);
-
- memcpy((char *)*pageBuf, (const char *)recvBuf + i, k); /* 用HTTP1.0是没http chunked response的.方便处理,否则还要分段接收网页,大的网页反正MCU也接不下. */
- vPortFree2 (recvBuf);
-
-
- ((char *)*pageBuf)[k]='\0';
-
-
-
- return HTTP_OK;
- }
- }
- }
- }
-
-
-
- printf("NOY_HTTP_OK:");
-
- printf(recvBuf);
-
-
- if(recvBuf != NULL) {vPortFree2 (recvBuf);}
-
-
-
- }
-
-
-
- return HTTP_NOT_200OK;
- }
- else
- {
- vPortFree2 (request);
- printf("HTTP_SERVER_REFUSE");
- return HTTP_SERVER_REFUSE;
- }
-
- }
- else
- {
-
- printf("HTTPS_NOT_SUPPORT");
-
- return HTTPS_NOT_SUPPORT;
- }
- }
-
复制代码
上面这个实现了单片机调用网站地址并返回网页内容,下面就用这个函数具体调用百度http://vop.baidu.com/server_api?dev_pid=1536&cuid=%s&token=%s 接口,
哈,只能展示这么多,
void process_asr(){
int err = HTTP_OK;
uint16_t ret_code1;
// printf("start ASR...");
//------------------------------------------------------------------------------------
reflsh_token(0);
memset(urlgg,'\0',urlchar_maxlen);
//dev_pid=1536是普通话,1537 =普通话(纯中文识别),dev_pid=1936是远场普通话
sprintf(urlgg,"http://vop.baidu.com/server_api?dev_pid=1536&cuid=%s&token=%s",cuid,g_access_token);
err = WebClient(urlgg, reco_temp_ram, &abuf,1,reco_temp_ram_len);
if(abuf != NULL && err == HTTP_OK)
{
|
|