与GEC6818开发板一起使用
3.1 使用科大讯飞的离线语音在ubantu中运行,作为服务端进行关键字的识别
需要更改的重要的两个文件就是bin/call.bnf和samples/asr_offine_sample/asr_offine_sample.c.这两个文件,第一个文件是修改我们需要识别的字眼,第二个文件是C 语言代码,可以在官方的基础上修改为自己所需要的逻辑
3.2 call.bnf–>hehe.bnf
我自己将官方自带的call.bnf复制了一份修改名字为hehe.bnf,在新的基础上进行的修改,更改了这个文件后,需要在后面的例程中的.c文件中修改这个文件。
例如:
注意我们这里使用对应的ID是非常重要的,因为我后后续进行语音识别后就是根据这个ID来判断识别到的内容,然后在执行相应的操作。 3.3 asr_offine_sample.c文件修改上面有提到过的修改了离线语法文件后在.c文件中也需要修改相应的文件名
修改后的代码–当然也可以不用这样大幅度的修改,只是将官方的代码进行了规整。
- //服务器
- #include <stdio.h>
- #include <sys/types.h> /* See NOTES */
- #include <sys/socket.h>
- #include <arpa/inet.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <pthread.h>
- #include <string.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #include "asr_offline_sample.h" //科大讯飞
- //全局的套接字
- int sockfd = -1;
- //将套接字创建好 并且绑定 监听
- //将ip地址和端口号传进来 端口号释放需要时间(轮询机制)
- void TcpInit(const char * ipaddr,unsigned short port)
- {
- //1 创建套接字 ---- 神马都是文件,因此你的网络通信也是一个文件
- sockfd = socket(AF_INET,SOCK_STREAM,0);
- if(-1 == sockfd)
- {
- perror("server socket error");
- exit(1);//没有必要运行了
- }
- //2 我们需要将服务器的IP地址绑定到套接字
- struct sockaddr_in sa;
- sa.sin_family = AF_INET;//协议族
- sa.sin_port = htons(port);//端口号 内存是小端的 我们要转大端
- sa.sin_addr.s_addr = inet_addr(ipaddr);//将我们点分式的ip地址转换为一个大端整数
- //printf("ipaddr = %x port = %x\n",inet_addr(ipaddr),htons(port));
- int r = bind(sockfd,(struct sockaddr *)&sa,sizeof(sa));
- if(-1 == r)
- {
- perror("server bind error");
- exit(2);//没有必要运行了
- }
- //3 监听连接 ---- 创建一个监听队列 建立5个10个可以了
- listen(sockfd,5);
- }
- //接收客户端发过来的文件内容
- void SaveFile(int accceptfd,int filesize)
- {
- //每一次都是重复的覆盖hehe.pcm
- int fd = open("wav/hehe.pcm",O_RDWR | O_TRUNC|O_CREAT,0644);//截短这个文件
- if(-1 == fd)
- {
- send(accceptfd,"error!!!",9,0);//失败发送这个错误
- return;
- }
- send(accceptfd,"next!!!!",9,0);//发送下一步的指令
- unsigned char buf[1024] = {0};
- int size = 0;
- //接收文件的内容
- while(1)
- {
- int r = recv(accceptfd,buf,1024,0);
- if(-1 == r)
- {
- perror("recv error");
- break;
- }
- else if(0 == r)//客户端已经断了
- {
- printf("对方断开连接了\n");
- break;
- }
- else//接收到信息了
- {
- //将文件的内容写入到文件
- write(fd,buf,r);
- //做完之后要退出
- size += r;
- if(size >= filesize)
- break;
-
- }
- }
-
-
-
-
- close(fd);
- }
- //专门用于去服务一个客户的线程
- void * ClinetFunction(void * arg)
- {
-
- pthread_detach(pthread_self());//将其分离
- int * accceptfd = (int *)arg;
- printf(" * accceptfd = %d\n", * accceptfd);
- int filesize = 0;
- //你发什么信息过来 我就在这个信息之前加上一节 然后回发给你
- while(1)
- {
- printf("\t\t等待客户端传文件过来........\n");
- int r = recv(*accceptfd,&filesize,4,0);//阻塞等待数据过来
- if(-1 == r)
- {
- perror("recv error");
- break;
- }
- else if(0 == r)//客户端已经断了
- {
- printf("对方断开连接了\n");
- break;
- }
- else//接收到信息了
- {
- //文件大小
-
- SaveFile(* accceptfd,filesize);
-
- int id = GetFlayId();//文件接收完毕 那么我们就放过去识别即可
- //给客户端返回id
- send(* accceptfd,&id,4,0);
-
- }
- }
- close(*accceptfd);
- free(accceptfd);
- return NULL;
- }
- //等待客户端的连接
- void waitconnect(void)
- {
- //我们要基于这个连接套接字去通信
- struct sockaddr_in sa;
- socklen_t addrlen = sizeof(sa);
- while(1)
- {
- printf("一直等待对方的连接.......\n");
- int * accceptfd = malloc(4);//避免释放 因此我们要动态内存分配才可以
- *accceptfd = accept(sockfd,(struct sockaddr *)&sa,&addrlen);
- printf("连接者为:%s %d\n",inet_ntoa(sa.sin_addr),ntohs(sa.sin_port));
- //开一个线程出去 让它去服务与我的连接
- pthread_t thread;
- if(pthread_create(&thread,NULL,ClinetFunction,(void *)accceptfd) != 0)
- {
- perror("create thread error");
- continue;
- }
- }
-
- close(sockfd);
- }
- //通过main函数的参数 我们将这个ip地址和端口给进去
- //./a.out 192.168.31.251 8888
- int main(int argc,char * argv[])
- {
- if(argc < 3)
- {
- printf("参数都不齐\n");
- return -1;
- }
-
- //初始化科大讯飞的库
- FlayInit();
-
-
- TcpInit(argv[1],atoi(argv[2]));
- waitconnect();
- return 0;
- }
复制代码
|