【1】Makefile编写
all:
arm-linux-gcc Client_Tcp.c lcd.c -o main -I./include -L./lib -ljpeg -pthread
.PHONY:clean
clean:
rm -r main
【2】项目图片素材
【3】客户端Client_Tcp.c
#include <stdio.h>
#include <string.h>
#include <pthread.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/select.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdbool.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "myhead.h"
//*********************************************************************************************
/*
函数名称: Send_mp3
函数功能: 打开音频文件,并发送音频文件给服务器
参数: 服务器的套接字
返回值: 成功返回0,失败返回-1
*/
int Send_mp3(int sockfd)
{
int wav_fp;
char file_name[20] = "abc.wav";
wav_fp = open(file_name,O_RDWR);
if(wav_fp == -1)
{
perror("abc.wav open failed");
return -1;
}
//获取文件大小
struct stat file_msg;
bzero(&file_msg, sizeof(file_msg));
stat("abc.wav", &file_msg);
//向服务器传入音频文件大小 <1> 那么服务器第一步接收文件大小<1>
write(sockfd, &file_msg.st_size, sizeof(file_msg.st_size));
//发送数据
char *buf;
buf = malloc(50000);
bzero(buf,50000);
int n = 0;
while(1)
{
//每次从wav_fd 读取50000存入buf缓冲区
n = read(wav_fp, buf, 50000);
if(n == 0)
{
printf("读取完毕\n");
break;
}
if(n <0 )
{
perror("读取失败");
return -1;
}
//通过套接字向服务器传输文件
int ret = send(sockfd, buf, n, 0);
if(ret == -1)
{
perror("发送失败:");
return -1;
}
printf("成功发送大小:ret = %d\n", ret);
}
return 0;
}
//*********************************************************************************************
/*
函数名称: main
函数功能: 1.创建套接字 2.连接服务器 3.功能选择
参数: IP 端口
运行方式: ./client 192.168.24.206 50000
返回值: 成功返回0,失败返回-1
*/
int main(int argc,const char *argv[])
{
if(argc != 3)
{
printf("./main IP PORT \n");
return -1;
}
lcd_draw_jpg(0,0,"enum.jpg",NULL,0,0);
int sockfd = socket(AF_INET,SOCK_STREAM,0);
if(sockfd == -1)
{
perror("socket failed");
return -1;
}
struct sockaddr_in saddr;
socklen_t slen = sizeof(saddr);
bzero(&saddr,sizeof(struct sockaddr_in));
saddr.sin_family = AF_INET;
saddr.sin_port = htons(50000); //端口与客户端一致
saddr.sin_addr.s_addr = inet_addr("192.168.24.19"); //服务器的IP地址
int ret = connect(sockfd,(struct sockaddr *)&saddr,slen);
if(ret == -1)
{
perror("connect failed");
return -1;
}
while(1)
{
printf("录音口令->打开:视频|相册|上一张|下一张|暂停|关闭|退出\n");
printf("开始录音........");
getchar();
system("arecord -d3 -c1 -r16000 -twav -fS16_LE abc.wav");
//发送录音文件函数
int ret = Send_mp3(sockfd);
if(ret == -1)
{
printf("send file failed\n");
break;
}
printf("文件发送成功,等待接收回传指令\n");
// //发送完删除录音
//system("rm abc.wav");
while(1)
{
char str_cmd[50] = {0};
int CMD =0 ;
//接收服务器发送的口令
recv(sockfd, str_cmd, 24, 0);
if(strstr(str_cmd,"相册")!=NULL)
CMD = 0;
if(strstr(str_cmd,"上一张")!=NULL)
CMD = 1;
if(strstr(str_cmd,"下一张")!=NULL)
CMD = 2;
if(strstr(str_cmd,"视频1")!=NULL)
CMD = 3;
if(strstr(str_cmd,"暂停")!=NULL)
CMD = 4;
if(strstr(str_cmd,"继续")!=NULL)
CMD = 5;
if(strstr(str_cmd,"关闭")!=NULL)
CMD = 6;
if(strstr(str_cmd,"退出")!=NULL)
CMD = 7;
if(strstr(str_cmd,"视频2")!=NULL)
CMD = 8;
switch (CMD)
{
case 0:
printf("打开相册\n");
//关闭视频
system("killall -9 mplayer");
lcd_draw_jpg(0,0,"1.jpg",NULL,0,0);
break;
case 1:
printf("打开上一张\n");
lcd_draw_jpg(0,0,"2.jpg",NULL,0,0);
break;
case 2:
printf("打开下一张\n");
lcd_draw_jpg(0,0,"3.jpg",NULL,0,0);
break;
case 3:
//播放视频1
system("mplayer -quiet -zoom -x 800 -y 480 2.avi < /dev/null &"); // 后台播放视频
break;
case 4:
//暂停视频
system("killall -STOP mplayer &");
break;
case 5:
//继续播放
system("killall -CONT mplayer &");
break;
case 6:
printf("关闭相册\n");
lcd_draw_jpg(0,0,"enum.jpg",NULL,0,0);
break;
case 7:
//关闭播放
printf("退出视频1\n");
system("killall -9 mplayer");
lcd_draw_jpg(0,0,"enum.jpg",NULL,0,0);
break;
case 8:
//播放视频2
system("mplayer -quiet -zoom -x 800 -y 480 kjwei.avi < /dev/null &");
break;
}
break;
}
}
return 0;
}
【4】客户端配套lcd.c
#include "myhead.h"
int lcd_draw_jpg(unsigned int x,unsigned int y,const char *pjpg_path,char *pjpg_buf,unsigned int jpg_buf_size,unsigned int jpg_half);
static char g_color_buf[FB_SIZE]={0};
static int g_fb_fd;
static int *g_pfb_memory;
volatile int g_jpg_in_jpg_x;
volatile int g_jpg_in_jpg_y;
//鑾峰彇鏂囦欢鐨勫睘鎬?unsigned long file_size_get(const char *pfile_path)
{
unsigned long filesize = -1;
struct stat statbuff;
//鑾峰彇鏂囦欢灞炴€? if(stat(pfile_path, &statbuff) < 0)
{
return filesize;
}
else
{
filesize = statbuff.st_size; //鑾峰彇鏂囦欢澶у皬
}
return filesize;
}
int lcd_open(const char *str)
{
g_fb_fd = open(str, O_RDWR);
if(g_fb_fd<0)
{
printf("open lcd error\n");
return -1;
}
//鏄犲皠鍥剧墖绌洪棿澶у皬
g_pfb_memory = (int *)mmap(NULL, FB_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, g_fb_fd, 0 );
if (MAP_FAILED == g_pfb_memory )
{
printf ("mmap failed %d\n",__LINE__);
}
return g_fb_fd;
}
//鍏抽棴鏄犲皠绌洪棿鍜屾枃浠?void close_lcd(void)
{
munmap(g_pfb_memory, FB_SIZE);
close(g_fb_fd);
}
void lcd_draw_point(unsigned int x,unsigned int y, unsigned int color)
{
*(g_pfb_memory+y*800+x)=color;
}
#if EN_LCD_SHOW_JPG
//鏄剧ずjpg鍥剧墖
int lcd_draw_jpg(unsigned int x,unsigned int y,const char *pjpg_path,char *pjpg_buf,unsigned int jpg_buf_size,unsigned int jpg_half)
{
//鎵撳紑鏂囦欢璁惧
lcd_open("/dev/fb0");
struct jpeg_decompress_struct cinfo;
struct jpeg_error_mgr jerr;
char *pcolor_buf = g_color_buf;
char *pjpg;
unsigned int i=0;
unsigned int color =0;
unsigned int count =0;
unsigned int x_s = x;
unsigned int x_e ;
unsigned int y_e ;
int jpg_fd;
unsigned int jpg_size;
unsigned int jpg_width;
unsigned int jpg_height;
//娌℃湁鏂囦欢鍜屾槧灏勭┖闂? if(pjpg_path == NULL && pjpg_buf == NULL)
return -1;
if(pjpg_path!=NULL)
{
//鎵撳紑鏂囦欢
jpg_fd=open(pjpg_path,O_RDWR);
if(jpg_fd == -1)
{
printf("open %s error\n",pjpg_path);
return -1;
}
//鑾峰彇鏂囦欢澶у皬鍑芥暟
jpg_size=file_size_get(pjpg_path);
//鐢宠鏂囦欢澶у皬鐨勭┖闂?
pjpg = malloc(jpg_size);
//璇诲彇鎵撳紑鐨勬枃浠? 瀛樺湪鏂囦欢澶у皬鐨勭┖闂?
read(jpg_fd,pjpg,jpg_size);
}
else
{
jpg_size = jpg_buf_size;
pjpg = pjpg_buf;
}
//鍥剧墖鍑洪敊澶勭悊
cinfo.err = jpeg_std_error(&jerr);
jpeg_create_decompress(&cinfo);
jpeg_mem_src(&cinfo,pjpg,jpg_size);
jpeg_read_header(&cinfo, TRUE);
jpeg_start_decompress(&cinfo);
if(jpg_half)
{
x_e = x_s+(cinfo.output_width/2);
y_e = y +(cinfo.output_height/2);
while(cinfo.output_scanline < cinfo.output_height)
{
pcolor_buf = g_color_buf;
jpeg_read_scanlines(&cinfo,(JSAMPARRAY)&pcolor_buf,1);
jpeg_read_scanlines(&cinfo,(JSAMPARRAY)&pcolor_buf,1);
for(i=0; i<(cinfo.output_width/2); i++)
{
color = *(pcolor_buf+2); // B
color = color | *(pcolor_buf+1)<<8; // G
color = color | *(pcolor_buf)<<16; //R
lcd_draw_point(x,y,color);
pcolor_buf +=6;
x++;
}
y++;
x = x_s;
}
}
else
{
x_e = x_s+cinfo.output_width;
y_e = y +cinfo.output_height;
while(cinfo.output_scanline < cinfo.output_height )// 锟叫断讹拷取一锟斤拷锟斤拷锟斤拷
{
pcolor_buf = g_color_buf;
jpeg_read_scanlines(&cinfo,(JSAMPARRAY)&pcolor_buf,1);
for(i=0; i<cinfo.output_width; i++)
{
/* 锟斤拷取rgb值 锟斤拷RGB锟较筹拷16位锟斤拷锟斤拷锟截碉拷锟斤拷锟斤拷 0x00ff0000 */
color = *(pcolor_buf+2)<<0;//B
color = color | *(pcolor_buf+1)<<8;//G
color = color | *(pcolor_buf)<<16;//R
/* 锟斤拷示锟斤拷锟截碉拷 */
lcd_draw_point(x,y,color);
pcolor_buf +=3;
x++;
}
/* 锟斤拷锟斤拷 */
y++;
x = x_s;
}
}
/*锟斤拷锟斤拷锟斤拷锟?/
jpeg_finish_decompress(&cinfo);
jpeg_destroy_decompress(&cinfo);
if(pjpg_path!=NULL)
{
/* 锟截憋拷jpg锟侥硷拷 */
close(jpg_fd);
/* 锟酵凤拷jpg锟侥硷拷锟节达拷占锟?*/
free(pjpg);
}
close_lcd();
return 0;
}
int lcd_draw_jpg_in_jpg(unsigned int x,unsigned int y,const char *pjpg_path,char *pjpg_buf,unsigned int jpg_buf_size)
{
/*锟斤拷锟斤拷锟斤拷锟斤拷锟襟,达拷锟斤拷锟斤拷锟斤拷锟斤拷*/
struct jpeg_decompress_struct cinfo;
struct jpeg_error_mgr jerr;
char *pcolor_buf = g_color_buf;
char *pjpg;
unsigned int i=0,j=0;
unsigned int color =0;
unsigned int count =0;
unsigned int x_s = x;
unsigned int x_e ;
unsigned int y_e ;
unsigned int y_n = y;
unsigned int x_n = x;
int jpg_fd;
unsigned int jpg_size;
if(pjpg_path!=NULL)
{
/* 锟斤拷锟斤拷jpg锟斤拷源锟斤拷权锟睫可讹拷锟斤拷写 */
jpg_fd=open(pjpg_path,O_RDWR);
if(jpg_fd == -1)
{
printf("open %s error\n",pjpg_path);
return -1;
}
/* 锟斤拷取jpg锟侥硷拷锟侥达拷小 */
jpg_size=file_size_get(pjpg_path);
/* 为jpg锟侥硷拷锟斤拷锟斤拷锟节达拷占锟?*/
pjpg = malloc(jpg_size);
/* 锟斤拷取jpg锟侥硷拷锟斤拷锟斤拷锟斤拷锟捷碉拷锟节达拷 */
read(jpg_fd,pjpg,jpg_size);
}
else
{
jpg_size = jpg_buf_size;
pjpg = pjpg_buf;
}
/*注锟斤拷锟斤拷锟斤拷锟斤拷锟?/
cinfo.err = jpeg_std_error(&jerr);
/*锟斤拷锟斤拷锟斤拷锟斤拷*/
jpeg_create_decompress(&cinfo);
/*直锟接斤拷锟斤拷锟节达拷锟斤拷锟斤拷*/
jpeg_mem_src(&cinfo,pjpg,jpg_size);
/*锟斤拷锟侥硷拷头*/
jpeg_read_header(&cinfo, TRUE);
/*锟斤拷始锟斤拷锟斤拷*/
jpeg_start_decompress(&cinfo);
x_e = x_s+cinfo.output_width;
y_e = y +cinfo.output_height;
/*锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷*/
while(cinfo.output_scanline < cinfo.output_height )
{
pcolor_buf = g_color_buf;
/* 锟斤拷取jpg一锟叫碉拷rgb值 */
jpeg_read_scanlines(&cinfo,(JSAMPARRAY)&pcolor_buf,1);
for(i=0; i<cinfo.output_width; i++)
{
/* 锟斤拷锟斤拷示锟侥诧拷锟斤拷 */
if(y_n>g_jpg_in_jpg_y && y_n<g_jpg_in_jpg_y+240)
if(x_n>g_jpg_in_jpg_x && x_n<g_jpg_in_jpg_x+320)
{
pcolor_buf +=3;
x_n++;
continue;
}
/* 锟斤拷取rgb值 */
color = *(pcolor_buf+2);
color = color | *(pcolor_buf)<<8;
color = color | *(pcolor_buf)<<16;
/* 锟斤拷示锟斤拷锟截碉拷 */
lcd_draw_point(x_n,y_n,color);
pcolor_buf +=3;
x_n++;
}
/* 锟斤拷锟斤拷 */
y_n++;
x_n = x_s;
}
/*锟斤拷锟斤拷锟斤拷锟?/
jpeg_finish_decompress(&cinfo);
jpeg_destroy_decompress(&cinfo);
if(pjpg_path!=NULL)
{
/* 锟截憋拷jpg锟侥硷拷 */
close(jpg_fd);
/* 锟酵凤拷jpg锟侥硷拷锟节达拷占锟?*/
free(pjpg);
}
return 0;
}
#endif
//LCD锟斤拷锟斤拷锟街凤拷锟斤拷锟酵计?int lcd_draw_bmp(unsigned int x,unsigned int y,const char *pbmp_path)
{
int bmp_fd;
unsigned int blue, green, red;
unsigned int color;
unsigned int bmp_width;
unsigned int bmp_height;
unsigned int bmp_type;
unsigned int bmp_size;
unsigned int x_s = x;
unsigned int x_e ;
unsigned int y_e ;
unsigned char buf[54]={0};
char *pbmp_buf=g_color_buf;
/* 锟斤拷锟斤拷位图锟斤拷源锟斤拷权锟睫可讹拷锟斤拷写 */
bmp_fd=open(pbmp_path,O_RDWR);
if(bmp_fd == -1)
{
printf("open bmp error\r\n");
return -1;
}
/* 锟斤拷取位图头锟斤拷锟斤拷息 */
read(bmp_fd,buf,54);
/* 锟斤拷锟斤拷 */
bmp_width =buf[18];
bmp_width|=buf[19]<<8;
printf("bmp_width=%d\r\n",bmp_width);
/* 锟竭讹拷 */
bmp_height =buf[22];
bmp_height|=buf[23]<<8;
printf("bmp_height=%d\r\n",bmp_height);
/* 锟侥硷拷锟斤拷锟斤拷 */
bmp_type =buf[28];
bmp_type|=buf[29]<<8;
printf("bmp_type=%d\r\n",bmp_type);
/* 锟斤拷锟斤拷锟斤拷示x锟斤拷y锟斤拷锟斤拷锟斤拷锟轿伙拷锟?*/
x_e = x + bmp_width;
y_e = y + bmp_height;
/* 锟斤拷取位图锟侥硷拷锟侥达拷小 */
bmp_size=file_size_get(pbmp_path);
/* 锟斤拷取锟斤拷锟斤拷RGB锟斤拷锟斤拷 */
read(bmp_fd,pbmp_buf,bmp_size-54);
for(;y < y_e; y++)
{
for (;x < x_e; x++)
{
/* 锟斤拷取锟斤拷锟斤拷锟斤拷锟斤拷色锟斤拷锟斤拷 */
blue = *pbmp_buf++;
green = *pbmp_buf++;
red = *pbmp_buf++;
/* 锟叫断碉拷前锟斤拷位图锟角凤拷32位锟斤拷色 */
if(bmp_type == 32)
{
pbmp_buf++;
}
/* 锟斤拷锟?4bit锟斤拷色 */
color = red << 16 | green << 8 | blue << 0;
lcd_draw_point(x, y, color);
}
x = x_s;
}
/* 锟斤拷锟斤拷使锟斤拷BMP锟斤拷锟斤拷锟酵凤拷bmp锟斤拷源 */
close(bmp_fd);
return 0;
}
// int main(int argc, char const *argv[])
// {
// printf("1:1.jpg 2:2.jpg 3:3.jpg\n");
// int num;
// scanf("%d",&num);
// if(num ==1)
// {
// lcd_draw_jpg(0, 0, "1.jpg", NULL, 0, 0);
// }
// else if(num == 2)
// {
// lcd_draw_jpg(0, 0, "2.jpg", NULL, 0, 0);
// }
// else if(num ==3)
// {
// lcd_draw_jpg(0, 0, "3.jpg", NULL, 0, 0);
// }
// return 0;
// }
【5】服务器代码
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <stdbool.h>
#include "../../include/qisr.h"
#include "../../include/msp_cmn.h"
#include "../../include/msp_errors.h"
#define SAMPLE_RATE_16K (16000)
#define SAMPLE_RATE_8K (8000)
#define MAX_GRAMMARID_LEN (32)
#define MAX_PARAMS_LEN (1024)
const char * ASR_RES_PATH = "fo|res/asr/common.jet"; //离线语法识别资源路径
const char * GRM_BUILD_PATH = "res/asr/GrmBuilld"; //构建离线语法识别网络生成数据保存路径
const char * GRM_FILE = "call.bnf"; //构建离线识别语法网络所用的语法文件
const char * LEX_NAME = "contact"; //更新离线识别语法的contact槽(语法文件为此示例中使用的call.bnf)
typedef struct _UserData {
int build_fini; //标识语法构建是否完成
int update_fini; //标识更新词典是否完成
int errcode; //记录语法构建或更新词典回调错误码
char grammar_id[MAX_GRAMMARID_LEN]; //保存语法构建返回的语法ID
}UserData;
int connfd; //连接文件描述符
const char *get_audio_file(void); //选择进行离线语法识别的语音文件
int build_grammar(UserData *udata); //构建离线识别语法网络
int update_lexicon(UserData *udata); //更新离线识别语法词典
int run_asr(UserData *udata); //进行离线语法识别
const char* get_audio_file(void)
{
// char key = 0;
// while(key != 27) //按Esc则退出
// {
// printf("请选择音频文件:\n");
// printf("1.打电话给丁伟\n");
// printf("2.打电话给黄辣椒\n");
// key = getchar();
// getchar();
// switch(key)
// {
// case '1':
// printf("\n1.打电话给丁伟\n");
// return "wav/ddhgdw.pcm";
// case '2':
// printf("\n2.打电话给黄辣椒\n");
// return "wav/ddhghlj.pcm";
// default:
// continue;
// }
// }
// exit(0);
// return NULL;
printf("开始接收文件...................................................n");
int wavSize;
read(connfd,&wavSize,sizeof(int));
printf("文件大小ret = %d\n",wavSize);
int file_fp;
// 打开文件,准备写入
file_fp = open("wav/abc.wav",O_CREAT|O_RDWR|O_TRUNC,0777);
if(file_fp<0)
{
printf("文件打开失败\n");
exit(1);
}
printf("open file succeed\n");
// 接收文件内容
char recvBuf[50000] = {0}; //接收到的数据存放到此处
int recvSize = 0; //实际接收的大小
int fileSize = 0; //总共接收的数据大小
//循环接收,直到文件尾
while(1)
{
memset(recvBuf,0,50000); //将recvBuf前50000个字符置0,相当于清空内存,bezero()
recvSize = recv(connfd,recvBuf,50000,0); //接收客户端发送过来的数据
fileSize += recvSize; //累加读取到的总数据量
printf("recvSize = %d\n",fileSize);
int retval = write(file_fp,recvBuf,recvSize); //将recvBuf中的数据写入fd中,写入数据大小为recvSize
if(retval == -1 || retval == EINTR)
{
printf("写入数据失败\n");
return false;
}
if(fileSize == wavSize) //写入完成
break;
}
close(file_fp);
return "wav/abc.wav";
}
int build_grm_cb(int ecode, const char *info, void *udata)
{
UserData *grm_data = (UserData *)udata;
if (NULL != grm_data) {
grm_data->build_fini = 1;
grm_data->errcode = ecode;
}
if (MSP_SUCCESS == ecode && NULL != info) {
printf("构建语法成功! 语法ID:%s\n", info);
if (NULL != grm_data)
snprintf(grm_data->grammar_id, MAX_GRAMMARID_LEN - 1, info);
}
else
printf("构建语法失败!%d\n", ecode);
return 0;
}
int build_grammar(UserData *udata)
{
FILE *grm_file = NULL;
char *grm_content = NULL;
unsigned int grm_cnt_len = 0;
char grm_build_params[MAX_PARAMS_LEN] = {NULL};
int ret = 0;
grm_file = fopen(GRM_FILE, "rb");
if(NULL == grm_file) {
printf("打开\"%s\"文件失败![%s]\n", GRM_FILE, strerror(errno));
return -1;
}
fseek(grm_file, 0, SEEK_END);
grm_cnt_len = ftell(grm_file);
fseek(grm_file, 0, SEEK_SET);
grm_content = (char *)malloc(grm_cnt_len + 1);
if (NULL == grm_content)
{
printf("内存分配失败!\n");
fclose(grm_file);
grm_file = NULL;
return -1;
}
fread((void*)grm_content, 1, grm_cnt_len, grm_file);
grm_content[grm_cnt_len] = '\0';
fclose(grm_file);
grm_file = NULL;
snprintf(grm_build_params, MAX_PARAMS_LEN - 1,
"engine_type = local, \
asr_res_path = %s, sample_rate = %d, \
grm_build_path = %s, ",
ASR_RES_PATH,
SAMPLE_RATE_16K,
GRM_BUILD_PATH
);
ret = QISRBuildGrammar("bnf", grm_content, grm_cnt_len, grm_build_params, build_grm_cb, udata);
free(grm_content);
grm_content = NULL;
return ret;
}
int update_lex_cb(int ecode, const char *info, void *udata)
{
UserData *lex_data = (UserData *)udata;
if (NULL != lex_data) {
lex_data->update_fini = 1;
lex_data->errcode = ecode;
}
if (MSP_SUCCESS == ecode)
printf("更新词典成功!\n");
else
printf("更新词典失败!%d\n", ecode);
return 0;
}
int update_lexicon(UserData *udata)
{
const char *lex_content = "丁伟\n黄辣椒";
unsigned int lex_cnt_len = strlen(lex_content);
char update_lex_params[MAX_PARAMS_LEN] = {NULL};
snprintf(update_lex_params, MAX_PARAMS_LEN - 1,
"engine_type = local, text_encoding = UTF-8, \
asr_res_path = %s, sample_rate = %d, \
grm_build_path = %s, grammar_list = %s, ",
ASR_RES_PATH,
SAMPLE_RATE_16K,
GRM_BUILD_PATH,
udata->grammar_id);
return QISRUpdateLexicon(LEX_NAME, lex_content, lex_cnt_len, update_lex_params, update_lex_cb, udata);
}
int run_asr(UserData *udata)
{
char asr_params[MAX_PARAMS_LEN] = {NULL};
const char *rec_rslt = NULL;
const char *session_id = NULL;
const char *asr_audiof = NULL;
FILE *f_pcm = NULL;
char *pcm_data = NULL;
long pcm_count = 0;
long pcm_size = 0;
int last_audio = 0;
int aud_stat = MSP_AUDIO_SAMPLE_CONTINUE;
int ep_status = MSP_EP_LOOKING_FOR_SPEECH;
int rec_status = MSP_REC_STATUS_INCOMPLETE;
int rss_status = MSP_REC_STATUS_INCOMPLETE;
int errcode = -1;
asr_audiof = get_audio_file();
f_pcm = fopen(asr_audiof, "rb");
if (NULL == f_pcm) {
printf("打开\"%s\"失败![%s]\n", f_pcm, strerror(errno));
goto run_error;
}
fseek(f_pcm, 0, SEEK_END);
pcm_size = ftell(f_pcm);
fseek(f_pcm, 0, SEEK_SET);
pcm_data = (char *)malloc(pcm_size);
if (NULL == pcm_data)
goto run_error;
fread((void *)pcm_data, pcm_size, 1, f_pcm);
fclose(f_pcm);
f_pcm = NULL;
//离线语法识别参数设置
snprintf(asr_params, MAX_PARAMS_LEN - 1,
"engine_type = local, \
asr_res_path = %s, sample_rate = %d, \
grm_build_path = %s, local_grammar = %s, \
result_type = xml, result_encoding = UTF-8, ",
ASR_RES_PATH,
SAMPLE_RATE_16K,
GRM_BUILD_PATH,
udata->grammar_id
);
session_id = QISRSessionBegin(NULL, asr_params, &errcode);
if (NULL == session_id)
goto run_error;
printf("开始识别...\n");
while (1) {
unsigned int len = 6400;
if (pcm_size < 12800) {
len = pcm_size;
last_audio = 1;
}
aud_stat = MSP_AUDIO_SAMPLE_CONTINUE;
if (0 == pcm_count)
aud_stat = MSP_AUDIO_SAMPLE_FIRST;
if (len <= 0)
break;
printf(">");
fflush(stdout);
errcode = QISRAudioWrite(session_id, (const void *)&pcm_data[pcm_count], len, aud_stat, &ep_status, &rec_status);
if (MSP_SUCCESS != errcode)
goto run_error;
pcm_count += (long)len;
pcm_size -= (long)len;
//检测到音频结束
if (MSP_EP_AFTER_SPEECH == ep_status)
break;
usleep(150 * 1000); //模拟人说话时间间隙
}
//主动点击音频结束
QISRAudioWrite(session_id, (const void *)NULL, 0, MSP_AUDIO_SAMPLE_LAST, &ep_status, &rec_status);
free(pcm_data);
pcm_data = NULL;
//获取识别结果
while (MSP_REC_STATUS_COMPLETE != rss_status && MSP_SUCCESS == errcode) {
rec_rslt = QISRGetResult(session_id, &rss_status, 0, &errcode);
usleep(150 * 1000);
}
printf("\n识别结束:\n");
printf("=============================================================\n");
if (NULL != rec_rslt)
{
printf("识别到的关键字是:%s\n",rec_rslt);
//匹配关键字
if(strstr(rec_rslt, "相册") != NULL)
{
//将关键字传给客户端
send(connfd, "相册",strlen("相册"),0);
}
else if(strstr(rec_rslt, "上一张") !=NULL)
{
send(connfd,"上一张",strlen("上一张"),0);
}
else if(strstr(rec_rslt, "下一张") !=NULL)
{
send(connfd,"下一张",strlen("下一张"),0);
}
else if(strstr(rec_rslt, "视频1") !=NULL)
{
send(connfd,"视频1",strlen("视频1"),0);
}
else if(strstr(rec_rslt,"暂停")!=NULL)
{
send(connfd, "暂停", strlen("暂停"), 0);
}
else if(strstr(rec_rslt,"继续")!=NULL)
{
send(connfd, "继续", strlen("继续"), 0);
}
else if(strstr(rec_rslt, "退出") !=NULL)
{
send(connfd,"退出",strlen("退出"),0);
}
else if(strstr(rec_rslt, "关闭") !=NULL)
{
send(connfd,"关闭",strlen("关闭"),0);
}
else if(strstr(rec_rslt, "视频2") !=NULL)
{
send(connfd,"视频2",strlen("视频2"),0);
}
}
else
printf("没有识别结果!\n");
printf("=============================================================\n");
goto run_exit;
run_error:
if (NULL != pcm_data) {
free(pcm_data);
pcm_data = NULL;
}
if (NULL != f_pcm) {
fclose(f_pcm);
f_pcm = NULL;
}
run_exit:
QISRSessionEnd(session_id, NULL);
return errcode;
}
//server init
int init_tcp(int port)
{
// 创建套接字
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
if(sockfd == -1)
return -1;
// 设置特殊结构体地址用于通信
struct sockaddr_in saddr;
socklen_t len = sizeof(saddr);
bzero(&saddr,sizeof(saddr));
saddr.sin_family = AF_INET;
saddr.sin_port = htons(port);
//saddr.sin_addr.s_addr = htonl(INADDR_ANY);
saddr.sin_addr.s_addr = inet_addr("192.168.24.19");
// 绑定套接字
int ret = bind(sockfd,(struct sockaddr *)&saddr,len);
if(ret == -1)
return -1;
// 监听套接字
ret = listen(sockfd,5);
if(ret == -1)
return -1;
return sockfd;
}
int main(int argc, char* argv[])
{
//******************************************************************************************************
//接收客户端发送过来的音频存放到 wav/abc.wav下
if(argc != 2)
{
perror("输入格式 ./asr IP");
return -1;
}
int sockfd = init_tcp(atoi(argv[1]));
if(sockfd == -1)
{
perror("sockfd open failed");
return -1;
}
// 用户存放已连接套接字的信息
struct sockaddr_in cliaddr;
socklen_t len = sizeof(cliaddr);
bzero(&cliaddr,sizeof(cliaddr));
printf("等待连接中。。。。。。。。。。\n");
// 等待连接
connfd = accept(sockfd,(struct sockaddr *)&cliaddr,&len);
printf("成功连接 connfd = %d\n",connfd);
printf("new connect ip : %s\n",inet_ntoa(cliaddr.sin_addr));
//*******************************************************************************************************
const char *login_config = "appid = 68e5809b"; //登录参数
UserData asr_data;
int ret = 0 ;
char c;
ret = MSPLogin(NULL, NULL, login_config); //第一个参数为用户名,第二个参数为密码,传NULL即可,第三个参数是登录参数
if (MSP_SUCCESS != ret) {
printf("登录失败:%d\n", ret);
goto exit;
}
printf("登录成功!\n");
memset(&asr_data, 0, sizeof(UserData));
printf("构建离线识别语法网络...\n");
ret = build_grammar(&asr_data); //第一次使用某语法进行识别,需要先构建语法网络,获取语法ID,之后使用此语法进行识别,无需再次构建
if (MSP_SUCCESS != ret) {
printf("构建语法调用失败!\n");
goto exit;
}
while (1 != asr_data.build_fini)
usleep(300 * 1000);
if (MSP_SUCCESS != asr_data.errcode)
goto exit;
printf("离线识别语法网络构建完成,开始识别...\n");
while(1)
{
ret = run_asr(&asr_data);
if (MSP_SUCCESS != ret) {
printf("离线语法识别出错: %d \n", ret);
goto exit;
}
// printf("更新离线语法词典...\n");
// ret = update_lexicon(&asr_data); //当语法词典槽中的词条需要更新时,调用QISRUpdateLexicon接口完成更新
// if (MSP_SUCCESS != ret) {
// printf("更新词典调用失败!\n");
// goto exit;
// }
// while (1 != asr_data.update_fini)
// usleep(300 * 1000);
// if (MSP_SUCCESS != asr_data.errcode)
// goto exit;
// printf("更新离线语法词典完成,开始识别...\n");
// ret = run_asr(&asr_data);
// if (MSP_SUCCESS != ret) {
// printf("离线语法识别出错: %d \n", ret);
// goto exit;
// }
system("rm wav/abc.wav");
}
exit:
MSPLogout();
printf("请按任意键退出...\n");
getchar();
return 0;
}
【6】源码分享
【百度网盘】链接:https://pan.baidu.com/s/1sqdr4rTu4y-flCgZRsVvlw?pwd=3ubj
提取码:3ubj