找回密码
 立即注册
查看: 553|回复: 0

GEC6818科大讯飞离线语音识别(二)

[复制链接]

86

主题

0

回帖

894

积分

中级会员

积分
894
发表于 2024-4-24 15:46:32 | 显示全部楼层 |阅读模式
与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文件中也需要修改相应的文件名


修改后的代码–当然也可以不用这样大幅度的修改,只是将官方的代码进行了规整。

  1. //服务器
  2. #include <stdio.h>
  3. #include <sys/types.h>          /* See NOTES */
  4. #include <sys/socket.h>
  5. #include <arpa/inet.h>
  6. #include <stdlib.h>
  7. #include <unistd.h>
  8. #include <pthread.h>
  9. #include <string.h>
  10. #include <sys/types.h>
  11. #include <sys/stat.h>
  12. #include <fcntl.h>

  13. #include "asr_offline_sample.h" //科大讯飞


  14. //全局的套接字
  15. int sockfd = -1;


  16. //将套接字创建好  并且绑定 监听
  17. //将ip地址和端口号传进来 端口号释放需要时间(轮询机制)
  18. void TcpInit(const char * ipaddr,unsigned short port)
  19. {
  20.     //1 创建套接字 ---- 神马都是文件,因此你的网络通信也是一个文件
  21.     sockfd = socket(AF_INET,SOCK_STREAM,0);
  22.     if(-1 == sockfd)
  23.     {
  24.         perror("server socket error");
  25.         exit(1);//没有必要运行了
  26.     }
  27.     //2 我们需要将服务器的IP地址绑定到套接字
  28.     struct sockaddr_in sa;
  29.     sa.sin_family = AF_INET;//协议族
  30.     sa.sin_port = htons(port);//端口号  内存是小端的 我们要转大端
  31.     sa.sin_addr.s_addr = inet_addr(ipaddr);//将我们点分式的ip地址转换为一个大端整数
  32.     //printf("ipaddr = %x port = %x\n",inet_addr(ipaddr),htons(port));
  33.     int r = bind(sockfd,(struct sockaddr *)&sa,sizeof(sa));
  34.     if(-1 == r)
  35.     {
  36.         perror("server bind error");
  37.         exit(2);//没有必要运行了
  38.     }

  39.     //3 监听连接 ---- 创建一个监听队列   建立5个10个可以了
  40.     listen(sockfd,5);

  41. }

  42. //接收客户端发过来的文件内容
  43. void SaveFile(int accceptfd,int filesize)
  44. {
  45. //每一次都是重复的覆盖hehe.pcm
  46. int fd = open("wav/hehe.pcm",O_RDWR | O_TRUNC|O_CREAT,0644);//截短这个文件
  47. if(-1 == fd)
  48. {
  49.   send(accceptfd,"error!!!",9,0);//失败发送这个错误
  50.   return;
  51. }
  52. send(accceptfd,"next!!!!",9,0);//发送下一步的指令
  53. unsigned char buf[1024] = {0};
  54. int size = 0;
  55. //接收文件的内容
  56. while(1)  
  57. {
  58.   int r = recv(accceptfd,buf,1024,0);
  59.   if(-1 == r)
  60.         {
  61.             perror("recv error");
  62.             break;
  63.         }
  64.         else if(0 == r)//客户端已经断了
  65.         {
  66.             printf("对方断开连接了\n");
  67.             break;
  68.         }
  69.         else//接收到信息了
  70.         {
  71.             //将文件的内容写入到文件
  72.    write(fd,buf,r);
  73.    //做完之后要退出
  74.    size += r;
  75.    if(size >= filesize)
  76.     break;
  77.    
  78.         }
  79. }




  80. close(fd);
  81. }


  82. //专门用于去服务一个客户的线程
  83. void * ClinetFunction(void * arg)
  84. {
  85.    
  86.     pthread_detach(pthread_self());//将其分离

  87.     int * accceptfd = (int *)arg;
  88.     printf(" * accceptfd = %d\n", * accceptfd);
  89. int filesize = 0;
  90.     //你发什么信息过来  我就在这个信息之前加上一节 然后回发给你
  91.     while(1)
  92.     {
  93.   printf("\t\t等待客户端传文件过来........\n");
  94.         int r = recv(*accceptfd,&filesize,4,0);//阻塞等待数据过来
  95.         if(-1 == r)
  96.         {
  97.             perror("recv error");
  98.             break;
  99.         }
  100.         else if(0 == r)//客户端已经断了
  101.         {
  102.             printf("对方断开连接了\n");
  103.             break;
  104.         }
  105.         else//接收到信息了
  106.         {
  107.             //文件大小
  108.    
  109.    SaveFile(* accceptfd,filesize);
  110.    
  111.    int id = GetFlayId();//文件接收完毕  那么我们就放过去识别即可
  112.    //给客户端返回id
  113.    send(* accceptfd,&id,4,0);
  114.             
  115.         }
  116.     }
  117.     close(*accceptfd);
  118.     free(accceptfd);
  119. return NULL;
  120. }

  121. //等待客户端的连接
  122. void waitconnect(void)
  123. {
  124.     //我们要基于这个连接套接字去通信
  125.     struct sockaddr_in sa;
  126.     socklen_t addrlen = sizeof(sa);
  127.     while(1)
  128.     {
  129.         printf("一直等待对方的连接.......\n");
  130.         int * accceptfd = malloc(4);//避免释放 因此我们要动态内存分配才可以
  131.         *accceptfd = accept(sockfd,(struct sockaddr *)&sa,&addrlen);
  132.         printf("连接者为:%s %d\n",inet_ntoa(sa.sin_addr),ntohs(sa.sin_port));
  133.         //开一个线程出去  让它去服务与我的连接
  134.         pthread_t thread;
  135.         if(pthread_create(&thread,NULL,ClinetFunction,(void *)accceptfd) != 0)
  136.         {
  137.             perror("create thread error");
  138.             continue;
  139.         }
  140.     }
  141.    
  142.     close(sockfd);
  143. }

  144. //通过main函数的参数 我们将这个ip地址和端口给进去
  145. //./a.out 192.168.31.251 8888
  146. int main(int argc,char * argv[])
  147. {
  148.     if(argc < 3)
  149.     {
  150.         printf("参数都不齐\n");
  151.         return -1;
  152.     }

  153. //初始化科大讯飞的库
  154. FlayInit();


  155.     TcpInit(argv[1],atoi(argv[2]));

  156.     waitconnect();

  157.     return 0;
  158. }

复制代码


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|EnMaking

GMT+8, 2025-3-31 09:02 , Processed in 0.053672 second(s), 24 queries .

Powered by Qiqirobot

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表