基于局域网网络编程实现开发板显示相册以及视频和音乐

在这里插入图片描述

文章目录

  • 【1】Makefile编写
  • 【2】项目图片素材
  • 【3】客户端Client_Tcp.c
  • 【4】客户端配套lcd.c
  • 【5】服务器代码
  • 【6】源码分享

【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】项目图片素材

基于局域网网络编程实现开发板显示相册以及视频和音乐_第1张图片
基于局域网网络编程实现开发板显示相册以及视频和音乐_第2张图片
基于局域网网络编程实现开发板显示相册以及视频和音乐_第3张图片
基于局域网网络编程实现开发板显示相册以及视频和音乐_第4张图片

【3】客户端Client_Tcp.c


#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#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 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 


#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
在这里插入图片描述

你可能感兴趣的:(Web网络编程工程师课程,网络,音视频,开发语言,C语言,Linux)