//JPGE类
#ifndef JPEG_H
#define JPEG_H
#include "Lcd.h"
#include "showbmp.h"
extern "C"
{
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <stdlib.h>
#include "jpeglib.h"
#include <sys/stat.h>
#include <string.h>
}
#define LCD_WIDTH 800
#define LCD_HEIGHT 480
#define FB_SIZE (LCD_WIDTH * LCD_HEIGHT * 4)
char g_color_buf[FB_SIZE]={0};
class jpeg:public Lcd
{
public:
jpeg(){}
jpeg(unsigned int x,unsigned int y,const char *pjpg_path,char *pjpg_buf,unsigned int jpg_buf_size,unsigned int jpg_half)
{
this->jpg_x=x;
this->jpg_y=y;
strcpy(this->buf_path,pjpg_path);
lcd_draw_jpg(this->jpg_x,this->jpg_y,this->buf_path,NULL,0,0);
}
~jpeg(){}
void lcd_draw_point(unsigned int x,unsigned int y, unsigned int color)
{
*(this->lcdmem+y*800+x)=color;
}
int lcd_draw_jpg(unsigned int x,unsigned int y,const char *pjpg_path,char *pjpg_buf=NULL,unsigned int jpg_buf_size=0,unsigned int jpg_half=0)
{
this->jpg_x=x;
this->jpg_y=y;
strcpy(this->buf_path,pjpg_path);
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;
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 = (char *)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,(unsigned char*) 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);
color = color | *(pcolor_buf+1)<<8;
color = color | *(pcolor_buf)<<16;
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++)
{
color = *(pcolor_buf+2);
color = color | *(pcolor_buf+1)<<8;
color = color | *(pcolor_buf)<<16;
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)
{
close(jpg_fd);
free(pjpg);
}
return 0;
}
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;
}
private:
int jpg_x;
int jpg_y;
char buf_path[1024];
volatile int g_jpg_in_jpg_x;
volatile int g_jpg_in_jpg_y;
struct jpeg_decompress_struct cinfo;
struct jpeg_error_mgr jerr;
unsigned int x_e ;
unsigned int y_e ;
int jpg_fd;
unsigned int jpg_size;
unsigned int jpg_width;
unsigned int jpg_height;
};
//用40多张jpeg实现开机动画
int movie_start(int b)
{
jpeg s1(0,0,"./start_switch/start (1).jpg",NULL,0,0);
s1.lcd_draw_jpg(0,0,"./start_switch/start (1).jpg",NULL,0,0);
s1.lcd_draw_jpg(0,0,"./start_switch/start (2).jpg",NULL,0,0);
s1.lcd_draw_jpg(0,0,"./start_switch/start (3).jpg",NULL,0,0);
s1.lcd_draw_jpg(0,0,"./start_switch/start (4).jpg",NULL,0,0);
s1.lcd_draw_jpg(0,0,"./start_switch/start (5).jpg",NULL,0,0);
s1.lcd_draw_jpg(0,0,"./start_switch/start (6).jpg",NULL,0,0);
s1.lcd_draw_jpg(0,0,"./start_switch/start (7).jpg",NULL,0,0);
s1.lcd_draw_jpg(0,0,"./start_switch/start (8).jpg",NULL,0,0);
s1.lcd_draw_jpg(0,0,"./start_switch/start (9).jpg",NULL,0,0);
s1.lcd_draw_jpg(0,0,"./start_switch/start (10).jpg",NULL,0,0);
s1.lcd_draw_jpg(0,0,"./start_switch/start (11).jpg",NULL,0,0);
s1.lcd_draw_jpg(0,0,"./start_switch/start (12).jpg",NULL,0,0);
s1.lcd_draw_jpg(0,0,"./start_switch/start (13).jpg",NULL,0,0);
s1.lcd_draw_jpg(0,0,"./start_switch/start (14).jpg",NULL,0,0);
s1.lcd_draw_jpg(0,0,"./start_switch/start (15).jpg",NULL,0,0);
s1.lcd_draw_jpg(0,0,"./start_switch/start (16).jpg",NULL,0,0);
s1.lcd_draw_jpg(0,0,"./start_switch/start (17).jpg",NULL,0,0);
s1.lcd_draw_jpg(0,0,"./start_switch/start (18).jpg",NULL,0,0);
s1.lcd_draw_jpg(0,0,"./start_switch/start (19).jpg",NULL,0,0);
s1.lcd_draw_jpg(0,0,"./start_switch/start (20).jpg",NULL,0,0);
s1.lcd_draw_jpg(0,0,"./start_switch/start (21).jpg",NULL,0,0);
s1.lcd_draw_jpg(0,0,"./start_switch/start (22).jpg",NULL,0,0);
s1.lcd_draw_jpg(0,0,"./start_switch/start (23).jpg",NULL,0,0);
s1.lcd_draw_jpg(0,0,"./start_switch/start (24).jpg",NULL,0,0);
s1.lcd_draw_jpg(0,0,"./start_switch/start (25).jpg",NULL,0,0);
s1.lcd_draw_jpg(0,0,"./start_switch/start (26).jpg",NULL,0,0);
s1.lcd_draw_jpg(0,0,"./start_switch/start (27).jpg",NULL,0,0);
s1.lcd_draw_jpg(0,0,"./start_switch/start (28).jpg",NULL,0,0);
s1.lcd_draw_jpg(0,0,"./start_switch/start (29).jpg",NULL,0,0);
s1.lcd_draw_jpg(0,0,"./start_switch/start (30).jpg",NULL,0,0);
s1.lcd_draw_jpg(0,0,"./start_switch/start (31).jpg",NULL,0,0);
s1.lcd_draw_jpg(0,0,"./start_switch/start (32).jpg",NULL,0,0);
s1.lcd_draw_jpg(0,0,"./start_switch/start (33).jpg",NULL,0,0);
s1.lcd_draw_jpg(0,0,"./start_switch/start (34).jpg",NULL,0,0);
s1.lcd_draw_jpg(0,0,"./start_switch/start (35).jpg",NULL,0,0);
s1.lcd_draw_jpg(0,0,"./start_switch/start (36).jpg",NULL,0,0);
s1.lcd_draw_jpg(0,0,"./start_switch/start (37).jpg",NULL,0,0);
s1.lcd_draw_jpg(0,0,"./start_switch/start (38).jpg",NULL,0,0);
s1.lcd_draw_jpg(0,0,"./start_switch/start (39).jpg",NULL,0,0);
s1.lcd_draw_jpg(0,0,"./start_switch/start (40).jpg",NULL,0,0);
s1.lcd_draw_jpg(0,0,"./start_switch/start (41).jpg",NULL,0,0);
s1.lcd_draw_jpg(0,0,"./start_switch/start (42).jpg",NULL,0,0);
s1.lcd_draw_jpg(0,0,"./start_switch/start (43).jpg",NULL,0,0);
s1.lcd_draw_jpg(0,0,"./start_switch/start (44).jpg",NULL,0,0);
s1.lcd_draw_jpg(0,0,"./start_switch/start (45).jpg",NULL,0,0);
s1.lcd_draw_jpg(0,0,"./start_switch/start (46).jpg",NULL,0,0);
show_theam(0);
return 0;
}
//窗帘页面
int window_show(int flag_off_on)
{
showbmp myphoto(600,346,100,50,"./wall_frame.bmp");
const char* p;
jpeg s1;
if(flag_off_on==0)
{
vector<string>::iterator it;
myphoto.open_bmp(84,84,550,200,"./led_photo/off.bmp");
s1.lcd_draw_jpg(550,100,"./返回.jpg",NULL,0,0);
for(it = jpg_pthoto_path.begin();it!=jpg_pthoto_path.end();it++)
{
p= it->c_str();
s1.lcd_draw_jpg(100+34,50+29,p,NULL,0,0);
for(int i=0;i<150;i++);
}
}
else if (flag_off_on==1)
{
vector<string>::reverse_iterator rit;
myphoto.open_bmp(84,84,550,200,"./led_photo/on.bmp");
s1.lcd_draw_jpg(550,100,"./返回.jpg",NULL,0,0);
for(rit = jpg_pthoto_path.rbegin();rit!=jpg_pthoto_path.rend();rit++)
{
p= rit->c_str();
s1.lcd_draw_jpg(100+34,50+29,p,NULL,0,0);
for(int i=0;i<150;i++);
}
}
return 0;
}
int window_start(int flag_off_on)
{
jpeg s1;
showbmp myphoto(600,346,100,50,"./wall_frame.bmp");
s1.lcd_draw_jpg(100+34,50+29,"./window_photo/ABUIABADGAAgxMHW2gUo3tje4AYwwAI4tAE-0000.jpg",NULL,0,0);
myphoto.open_bmp(84,84,550,200,"./led_photo/off.bmp");
s1.lcd_draw_jpg(550,100,"./返回.jpg",NULL,0,0);
return 0;
}
int photo_back()
{
jpeg s1;
s1.lcd_draw_jpg(0,0,"./返回.jpg",NULL,0,0);
}
#endif
#ifndef LCD_H
#define LCD_H
#include <cstring>
extern "C"
{
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <unistd.h>
#include <stdio.h>
#include <linux/input.h>
#include <stdlib.h>
#include<pthread.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
}
//LCD类
class Lcd
{
//通过构造函数对液晶屏初始化
public:
Lcd()
{
lcdmem=NULL;
std::cout<<"我实例化了"<<std::endl;
lcd_open();
get_lcd_add();
}
void lcd_open()
{
//打开液晶屏的驱动
this->lcdfd=open("/dev/fb0",O_RDWR);
if(this->lcdfd==-1)
{
perror("打开lcd失败了!\n");
return;
}
}
void get_lcd_add()
{
//立马映射得到液晶屏的首地址
this->lcdmem=(int*)mmap(NULL,800*480*4,PROT_READ|PROT_WRITE,MAP_SHARED,this->lcdfd,0);
if(this->lcdmem==NULL)
{
perror("映射lcd失败了!\n");
return;
}
}
~Lcd()//通过析构函数对lcd进行关闭
{
std::cout<<"我解除实例化了"<<std::endl;
close(this->lcdfd);
//解除映射
munmap(this->lcdmem,800*480*4);
}
protected:
int lcdfd;
//定义指针保存液晶屏的首地址
int *lcdmem;
};
#endif
//菜单类
#ifndef MENU_H
#define MENU_H
#include <iostream>
#include <vector>
#include <cstring>
#include "text_data.h"
#include "jpeg.h"
#include "showbmp.h"
#include "menu.h"
using namespace std;
typedef int (*fun)(int);
typedef struct tables
{
char name[1024]; // 菜单名字
int (*thefun)(int);
} table;
class menu
{
public:
menu(){}
~menu(){}
void add_task(table a)
{
task.push_back(a);
}
int show_task(const char *table_name,int a)
{
vector<struct tables>::iterator it;
for(it = task.begin();it!=task.end();it++)
{
if(strcmp(it->name,table_name)==0)
{
this->function=it->thefun;
this->ret=this->function(a);
return 0;
}
}
return 0;
}
int get_ret()
{
return this->ret;
}
private:
fun function;
int ret;
vector<struct tables> task;
};
menu mytheam;
void init_Team()//获取功能要用的文件,并存储到容器和双向链表中
{
direct get;
get.myfun("./photo",pthoto_path,".bmp");//获取bmp文件
get.myfun("./window_photo",jpg_pthoto_path,".jpg");//获取窗帘的jpg
get.myfun("./mp3",music_path,".mp3");
}
void menu_add()
{
struct tables G;
strcpy(G.name,"start_go"); //主页面的名字
G.thefun=movie_start;
mytheam.add_task(G);
strcpy(G.name,"photo"); //相册功能的名字
G.thefun=show_photo;
mytheam.add_task(G);
strcpy(G.name,"led"); //led开关功能的名字
G.thefun=led_show;
mytheam.add_task(G);
strcpy(G.name,"speak"); //speak开关功能的名字
G.thefun=speak_show;
mytheam.add_task(G);
strcpy(G.name,"music"); //music开关功能的名字
G.thefun=music_show;
mytheam.add_task(G);
strcpy(G.name,"window"); //窗帘开关功能的名字
G.thefun=window_show;
mytheam.add_task(G);
strcpy(G.name,"window_start"); //窗帘播放开关功能的名字
G.thefun=window_start;
mytheam.add_task(G);
return;
}
int menu_show(const char *name,const int a)
{
mytheam.show_task(name,a);
return mytheam.get_ret();
}
#endif
//音乐类
#ifndef MUSIC_H
#define MUSIC_H
extern "C"
{
#include<pthread.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <unistd.h>
#include <stdio.h>
#include <linux/input.h>
#include <stdlib.h>
#include<pthread.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
}
class music
{
public:
music(){}
~music(){}
int music_play(const char *music_name);
int music_stop();
int music_cont();
int music_pause();
};
//播放
int music::music_play(const char *music_name)
{
char p[1024];
memset(p,0,1024);
std::cout<<"music:"<<music_name<<std::endl;
sprintf(p, "madplay %s &", music_name);//&是后台播放的意思
system(p);
return 0;
}
//暂停
int music::music_stop()
{
system("killall -SIGSTOP madplay");
return 0;
}
//继续
int music::music_cont()
{
system("killall -SIGCONT madplay");
return 0;
}
//关闭
int music::music_pause()
{
system("killall -SIGKILL madplay");
return 0;
}
#endif
//线程类
#ifndef _MYPTHREAD_H
#define _MYPTHREAD_H
extern "C"
{
#include<pthread.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <unistd.h>
#include <stdio.h>
#include <linux/input.h>
#include <stdlib.h>
#include<pthread.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
}
//获取触摸屏的坐标值
int ts_read_pos(int *x,int *y);
using namespace std;
//线程类 ---基类
class Thread{
public:
Thread(){}
~Thread(){}
//线程的运行
virtual void run(){}
//线程的启动 ,开启线程
void start();
void stop();
protected:
pthread_t thread;
};
//线程例程
void* task(void*arg)
{
//基类指针 指向派生类对象
Thread *th = ( Thread *)arg;
//基类指针 调用 派生类中的虚函数
th->run();
return NULL;
}
// start(const Thread*this) //Thread*this = &t1
void Thread::start()
{
//this 是 基类指针
pthread_create(&thread,NULL,task,this);
//设置分离属性 --自己回收自己
pthread_detach(thread);
return;
}
void Thread::stop()
{
//给自己发送一个取消请求
pthread_cancel(thread);
return;
}
//触摸屏 开启线程
class pthread_touch:public Thread
{
public:
//重写 线程 基类 中的虚函数 ,也就是 你创建了这条线程之后,要去干嘛
virtual void run(){
int cnt=0;
while(1){
this->ts_read_pos(&this->touchx,&this->touchy);
}
}
//打开触摸屏
int ts_open()
{
//打开触摸屏的驱动
this->tsfd=open("/dev/input/event0",O_RDWR);
if(this->tsfd==-1)
{
perror("打开触摸屏失败了!\n");
return -1;
}
}
//关闭触摸屏
int ts_close()
{
//关闭触摸屏
close(this->tsfd);
return 0;
}
//获取触摸屏的坐标值
int ts_read_pos(int *x,int *y)
{
int x1,y1;
//定义输入子系统提供的结构体变量来存放坐标
struct input_event myevent;
//定义标志位,当坐标读取完毕,退出这个函数
int count=0;
while(1) //循环读取坐标
{
//读取触摸屏的坐标值
read(this->tsfd,&myevent,sizeof(myevent));
//判断事件类型--》触摸事件
if(myevent.type==EV_ABS) //是触摸事件
{
//进一步判断读取是x坐标,还是y坐标
if(myevent.code==ABS_X) //是x坐标
{
printf("读取的x坐标是: %d\n",myevent.value);
//x坐标保存
x1=myevent.value;
count++;
}
if(myevent.code==ABS_Y) //是y坐标
{
printf("读取的y坐标是: %d\n",myevent.value);
//y坐标保存
y1=myevent.value;
count++;
}
if(count==2) //过河拆桥
break;
}
}
*x=x1;
*y=y1;
return 0;
}
public:
int touchx;
int touchy;
int tsfd;
};
//语音识别线程类
class speak:public Thread
{
public:
//重写 线程 基类 中的虚函数 ,也就是 你创建了这条线程之后,要去干嘛
virtual void run(){
while(1)
{
printf("开始录音\n");
system("arecord -d3 -c1 -r16000 -twav -fS16_LE 1.wav");
this->play_voice();
}
}
void play_voice()
{
//创建套接字
int sock_fd = socket(PF_INET,SOCK_STREAM,0);
printf("aaa\n");
//绑定地址(IP+PORT)
struct sockaddr_in srvaddr;
srvaddr.sin_family = PF_INET;
//端口
srvaddr.sin_port = htons(60000);
//IP地址
srvaddr.sin_addr.s_addr = inet_addr("192.168.1.224");
printf("002\n");
//发起连接请求
connect(sock_fd,(struct sockaddr *)&srvaddr,sizeof(srvaddr));
printf("003\n");
int fd = open("1.wav",O_RDWR);
if(fd < 0)
{
perror("open() failed");
return;
}
//获取文件总字节数
int file_size = lseek(fd,0,SEEK_END);
//将文件光标偏移到文件开头
lseek(fd,0,SEEK_SET);
send(sock_fd,&file_size,4,0);
char buf[1024] = {0};
int ret_rd;
while(1)
{
bzero(buf,1024);
ret_rd = read(fd,buf,1024);
if(ret_rd == 0) //发送完毕
{
printf("发送完毕\n");
break;
}
send(sock_fd,buf,ret_rd,0);
if(ret_rd < 1024)
{
printf("send over\n");
break;
}
}
bzero(buf,100);
printf("等待接收数据\n");
recv(sock_fd,buf,100,0);
if(strstr(buf,"没有识别结果") != NULL)
{
printf("没有识别结果");
}
if(strcmp(this->cmd_buf,buf)!=0)
{
memset(this->cmd_buf,0,1024);
strcpy(this->cmd_buf,buf);
}
//关闭套接字
close(sock_fd);
close(fd);
}
public:
char cmd_buf[1024];
};
#endif
//bmp类
#ifndef SHOWBMP_H
#define SHOWBMP_H
#include <iostream>
#include <cstring>
#include "Lcd.h"
#include <list>
#include <vector>
#include "mypthread.h"
// int deliver_x;
// int deliver_y;
using namespace std;
vector<string> pthoto_path;
vector<string> jpg_pthoto_path;
list<string> music_path;
speak *mysp1;
extern "C"
{
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <unistd.h>
#include <stdio.h>
#include <linux/input.h>
#include <stdlib.h>
#include<pthread.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
}
class showbmp:public Lcd
{
private:
int bmpfd;
int i;
int j;
//定义数组把整个图片的BGR数据存放起来
char bmpbuf[800*480*3]; //char类型占1个字节
int tembuf[800*480*3];
char buf_path[1024];
int width;
int height;
public:
showbmp(){}
showbmp(const char * buf_path)
{
bzero(this->buf_path,0);
strcpy(this->buf_path,buf_path);
open_bmp(this->buf_path);
}
showbmp(const int w,const int h,const int x,const int y,const char *bmpname)
{
open_bmp(w,h,x,y,bmpname);
}
void open_bmp(const char * buf_path)
{
strcpy(this->buf_path,buf_path);
bmpfd = open(buf_path,O_RDWR);
if(bmpfd < 0)
{
perror("open bmp fail");
return;
}
lseek(bmpfd,54,SEEK_SET);
//立马映射得到液晶屏的首地址
read(bmpfd,bmpbuf,800*480*3);
for(i=0,j=0;i<800*480;i++,j+=3)
{
tembuf[i]=0x00<<24|bmpbuf[j]|bmpbuf[j+1]<<8|bmpbuf[j+2]<<16;
}
for(j=0;j<480;j++)
{
for(i=0;i<800;i++)
{
lcdmem[800*j+i]=tembuf[800*(479-j)+i];
}
}
close(this->bmpfd);
}
void open_bmp(const int w,const int h,const int x,const int y,const char *bmpname)
{
strcpy(this->buf_path,buf_path);
bmpfd = open(bmpname,O_RDWR);
if(bmpfd < 0)
{
perror("open bmp fail");
return;
}
lseek(bmpfd,54,SEEK_SET);
//判断bmp图片的宽所占的字节数能否被4整除
if((w*3)%4!=0)
{
for(i=0; i<h; i++)
{
read(bmpfd,&bmpbuf[i*w*3],w*3);
lseek(bmpfd,4-(w*3)%4,SEEK_CUR); //跳过填充的垃圾数据
}
}
else
//立马映射得到液晶屏的首地址
//从55字节读取bmp的像素点颜色值
read(bmpfd,bmpbuf,w*h*3); //bmpbuf[0] B bmpbuf[1] G bmpbuf[2] R 一个像素点的RGB
//bmpbuf[3] bmpbuf[4] bmpbuf[5]
//3字节的RGB-->4字节的ARGB 位运算+左移操作
for(i=0; i<w*h; i++)
tembuf[i]=bmpbuf[3*i]|bmpbuf[3*i+1]<<8|bmpbuf[3*i+2]<<16|0x00<<24;
//00[2][1][0]
for(i=0; i<w; i++)
for(j=0; j<h; j++)
//*(lcdmem+(y+j)*800+x+i)=lcdbuf[j*w+i]; 图片颠倒
*(lcdmem+(y+j)*800+x+i)=tembuf[(h-1-j)*w+i];
//关闭
close(this->bmpfd);
}
~showbmp()
{
}
//用户根据该函数获取长度的返回值
int get_width()
{
lseek(bmpfd, 18, SEEK_SET);
read(bmpfd, &this->width, 4); // 读出它的宽度
return this->width;
}
//用户根据该函数获取图片高度的返回值
int get_height()
{
lseek(bmpfd, 22, SEEK_SET);
read(bmpfd, &this->height, 4); // 读出它的高度
return this->height;
}
//用户根据该函数获取图片大小的返回值
int get_size()
{
return this->width*this->height*3;
}
};
int init_speak()
{
showbmp a("./first.bmp");
sleep(1);
return 0;
}
//主页
int show_theam(int b)
{
showbmp a("./start_switch/wallpaper.bmp");
a.open_bmp(84,84,200,396,"./start_switch/Curtain.bmp");
a.open_bmp(84,84,300,396,"./start_switch/off_led.bmp");
a.open_bmp(84,84,400,396,"./start_switch/music.bmp");
a.open_bmp(84,84,500,396,"./start_switch/photo.bmp");
a.open_bmp(84,84,600,396,"./start_switch/speak.bmp");
return 0;
}
//相册页面
int show_photo(int a)
{
mysp1=new speak();
showbmp myphoto(600,346,100,50,"./wall_frame.bmp");
pthread_touch *p2=new pthread_touch();
p2->ts_open();
p2->start();
const char* p;
vector<string>::iterator it;
mysp1->start();
while(1)
{
for(it = pthoto_path.begin();it!=pthoto_path.end();it++)
{
p= it->c_str();
myphoto.open_bmp(530,293,100+34,50+29,p);
if(p2->touchx>0&&p2->touchx<84&&p2->touchy>0&&p2->touchy<84||strcmp(mysp1->cmd_buf,"返回")==0)
{
std::cout<<"---------------我是第二"<<std::endl;
std::cout<<"----------cmd_buf"<<mysp1->cmd_buf<<std::endl;
mysp1->stop();
delete mysp1;
p2->stop();
p2->ts_close();
delete p2;
return 1;
}
sleep(1);
}
}
p2->stop();
p2->ts_close();
mysp1->stop();
delete p2;
return 0;
}
//led_show页面
int led_show(int flag_off_on)
{
showbmp myphoto(600,346,100,50,"./led_photo/1.bmp");
if(flag_off_on==0)
{
myphoto.open_bmp(100,100,400,120,"./led_photo/led_off.bmp");
myphoto.open_bmp(84,84,200,200,"./led_photo/off.bmp");
}
else if(flag_off_on==1)
{
myphoto.open_bmp(100,100,400,120,"./led_photo/led_on.bmp");
myphoto.open_bmp(84,84,200,200,"./led_photo/on.bmp");
}
return 0;
}
//语音页面
int speak_show(int a)
{
showbmp myphoto(60,60,720,250,"./speak_photo/1.bmp");
myphoto.open_bmp(60,60,720,360,"./speak_photo/back.bmp");
return 0;
}
//音乐页面
int music_show(int a)
{
showbmp myphoto(600,346,100,50,"./music_photo/music.bmp");
}
#endif
//获取文本路径
#ifndef TEXT_DATA_H
#define TEXT_DATA_H
#include <iostream>
#include <cstring>
#include "showbmp.h"
extern "C"
{
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <dirent.h>
#include <linux/input.h> //跟输入子系统模型有关
#include <malloc.h>
}
class direct
{
public:
int myfun(const char *dir,vector<string> &space,const char *buf2)
{
DIR *fd=opendir(dir);
char buf[100]={0};
bzero(buf,100);
if(fd==NULL)
{
perror("open is fail\n");
return -1;
}
//定义文件夹结构体
struct dirent *mydirent;
while((mydirent=readdir(fd))!=NULL)
{
//判断文件类型
if(strcmp(mydirent->d_name,".")==0||strcmp(mydirent->d_name,"..")==0)
continue;
if(mydirent->d_type==DT_DIR)
{
//文件类型是文件夹,再次进入文件夹中递归遍历
bzero(buf,100);
sprintf(buf,"%s/%s",dir,mydirent->d_name);
this->myfun(buf,space,buf2);
}
else if(strstr(mydirent->d_name,buf2))
{
bzero(buf,100);
sprintf(buf,"%s/%s",dir,mydirent->d_name);
//把获取的文件类型存到容器数组中
space.push_back(buf);
}
}
return 0;
}
int myfun(const char *dir,std::list<string> &space,const char *buf2)
{
DIR *fd=opendir(dir);
char buf[100]={0};
bzero(buf,100);
if(fd==NULL)
{
perror("open is fail\n");
return -1;
}
//定义文件夹结构体
struct dirent *mydirent;
while((mydirent=readdir(fd))!=NULL)
{
//判断文件类型
if(strcmp(mydirent->d_name,".")==0||strcmp(mydirent->d_name,"..")==0)
continue;
if(mydirent->d_type==DT_DIR)
{
//文件类型是文件夹,再次进入文件夹中递归遍历
bzero(buf,100);
sprintf(buf,"%s/%s",dir,mydirent->d_name);
this->myfun(buf,space,buf2);
}
else if(strstr(mydirent->d_name,buf2))
{
bzero(buf,100);
sprintf(buf,"%s/%s",dir,mydirent->d_name);
//把获取的文件类型存到容器数组中
space.push_back(buf);
}
}
return 0;
}
};
#endif
//主函数main.cpp
#include <iostream>
#include "jpeg.h"
#include "showbmp.h"
#include "menu.h"
#include "mypthread.h"
#include "music.h"
#include <string>
//arm-linux-g++ *.c -o main -I./libjpeg -L./libjpeg -ljpeg
int fwindow_flag;//判断窗口是开还是关的标志位
int get_pthoto_end;//判断图片循环是否结束的标准位
int led_flag;//判断led是开还是关的标志位
int music_flag;//判断music是开还是关的标志位
int music_play;//判断是否已经播放
class desk_top
{
public:
desk_top()
{
pthread_touch *t1=new pthread_touch();//该坐标类专门负责主界面上的功能选择
pthread_touch *p1;//专门负责窗帘开窗的内部坐标类
pthread_touch *p3;//专门负责开灯的内部坐标类
pthread_touch *p4;//专门负责音乐播放器的内部坐标类
music *mymusic;
speak *myspeak;//语音控制模块
// mysp1=new speak();
std::list<string>::iterator it;//定义顺序string类查找指针
//std::list<string>::iterator it2;//辅助
init_Team();//初始化文件链表
menu_add();//添加任务到菜单类
init_speak();
//实例化一个触摸屏线程类的对象
t1->ts_open();
//打开线程
t1->start();
fwindow_flag=0;
led_flag=0;
//菜单加载主页面
menu_show("start_go",0);
while(1)
{
music_flag=3;
music_play=0;
if(t1->touchx>500&&t1->touchx<584&&t1->touchy>396&&t1->touchy<(396+84))//点击相册功能
{
get_pthoto_end=0;//防止进入图片循环直接退出
photo_back();//显示图相的返回值按钮的图片
while(1)
{
if(get_pthoto_end==1)
{
//结束图片循环
show_theam(0);
break;
}
//获取图片的返回值
get_pthoto_end=menu_show("photo",0);
}
t1->touchx=0; //对p1对象的xy坐标进行坐标修改,避免重复进入该判断
t1->touchy=0;
}
else if(t1->touchx>200&&t1->touchx<284&&t1->touchy>396&&t1->touchy<(396+84))//打开窗帘功能
{
t1->stop();//先结束线程
t1->ts_close();//关闭触摸屏类
delete t1;
menu_show("window_start",0);
p1=new pthread_touch();//实例化新的触摸屏类
p1->ts_open();//打开触摸屏驱动
p1->start();//线程开启
fwindow_flag=1;
while(1)
{
if(p1->touchx>550&&p1->touchx<(550+84)&&p1->touchy>200&&p1->touchy<284)//窗帘按钮控制
{
if(fwindow_flag==0)//按一次就反转
{
fwindow_flag=1;
menu_show("window",fwindow_flag);
}
else
{
fwindow_flag=0;
menu_show("window",fwindow_flag);
}
p1->touchx=0; //对p1对象的xy坐标进行坐标修改,避免重复进入该判断
p1->touchy=0;
}
else if(p1->touchx>550&&p1->touchx<(550+56)&&p1->touchy>100&&p1->touchy<156)//返回主页面判断
{
show_theam(0);
break;
}
}
fwindow_flag=0;
p1->stop();//关闭p1类生成的
p1->ts_close();
delete p1;
t1=new pthread_touch();
t1->ts_open();
t1->start();
}
//打开开灯功能功能
else if(t1->touchx>300&&t1->touchx<384&&t1->touchy>396&&t1->touchy<(396+84))
{
t1->stop();//先结束线程
t1->ts_close();//关闭触摸屏类
delete t1;
menu_show("led",0);
photo_back();//灯返回值按钮的图片
p3=new pthread_touch();//实例化新的触摸屏类
p3->ts_open();//打开触摸屏驱动
p3->start();//线程开启
while(1)
{
if(p3->touchx>200&&p3->touchx<(200+84)&&p3->touchy>200&&p3->touchy<284)//led开关
{
if(led_flag==0)//按一次就反转
{
led_flag=1;
menu_show("led",led_flag);
}
else if(led_flag==1)
{
led_flag=0;
menu_show("led",led_flag);
}
p3->touchx=0; //对p1对象的xy坐标进行坐标修改,避免重复进入该判断
p3->touchy=0;
}
else if(p3->touchx>0&&p3->touchx<84&&p3->touchy>0&&p3->touchy<84)//返回主页面判断
{
show_theam(0);
break;
}
}
led_flag=0;
p3->stop();//关闭p1类生成的
p3->ts_close();
delete p3;
t1=new pthread_touch();
t1->ts_open();
t1->start();
}
//打开音乐播放器功
else if(t1->touchx>400&&t1->touchx<484&&t1->touchy>396&&t1->touchy<(396+84))
{
mymusic=new music();
t1->stop();//先结束线程
t1->ts_close();//关闭触摸屏类
delete t1;
menu_show("music",0);
p4=new pthread_touch();//实例化新的触摸屏类
p4->ts_open();//打开触摸屏驱动
p4->start();//线程开启
while(1)
{
if(p4->touchx>362&&p4->touchx<418&&p4->touchy>(288+50)&&p4->touchy<(322+50))//播放音乐开关
{
it=music_path.begin();
if(music_flag==0)//继续播放
{
std::cout<<"继续播放"<<std::endl;
music_flag=1;
mymusic->music_cont();
}
else if(music_flag==1)//暂停
{
std::cout<<"暂停"<<std::endl;
music_flag=0;
mymusic->music_stop();
}
else if(music_flag==3&&music_play==0)//开始播放
{
music_play=1;
std::cout<<"播放"<<std::endl;
music_flag=1;
mymusic->music_play(it->c_str());
}
p4->touchx=0; //对p1对象的xy坐标进行坐标修改,避免重复进入该判断
p4->touchy=0;
}
else if(p4->touchx>100&&p4->touchx<180&&p4->touchy>50&&p4->touchy<120)//返回主页面判断
{
mymusic->music_pause();
show_theam(0);
break;
}
else if(p4->touchx>288&&p4->touchx<324&&p4->touchy>341&&p4->touchy<370)//判断上一首
{
if(music_play==0)
{
it=music_path.begin();
mymusic->music_play(it->c_str());//打开新音乐
music_play=1;
}
if(it==music_path.begin())
{
it=music_path.end();
}
mymusic->music_pause();//关闭音乐
it--;
std::cout<<"上一首"<<*it<<std::endl;
mymusic->music_play(it->c_str());//打开新音乐
p4->touchx=0; //对p1对象的xy坐标进行坐标修改,避免重复进入该判断
p4->touchy=0;
}
else if(p4->touchx>445&&p4->touchx<490&&p4->touchy>340&&p4->touchy<370)//判断下一首
{
if(music_play==0)
{
it=music_path.begin();
mymusic->music_play(it->c_str());//打开新音乐
music_play=1;
}
else
{
mymusic->music_pause();//关闭音乐
it++;
if(it==music_path.end())
{
it=music_path.begin();
}
std::cout<<"下一首"<<*it<<std::endl;
mymusic->music_play(it->c_str());//打开新音乐
}
p4->touchx=0; //对p1对象的xy坐标进行坐标修改,避免重复进入该判断
p4->touchy=0;
}
}
delete mymusic;
p4->stop();//关闭p1类生成的
p4->ts_close();
delete p4;
t1=new pthread_touch();
t1->ts_open();
t1->start();
}
// 语音功能
else if(t1->touchx>600&&t1->touchx<684&&t1->touchy>396&&t1->touchy<(396+84))
{
menu_show("speak",0);
myspeak=new speak();
myspeak->start();
while(1)
{
if(t1->touchx>720&&t1->touchx<780&&t1->touchy>250&&t1->touchy<310)//点击语音功能
{
while(1)
{
if(strcmp(myspeak->cmd_buf,"相册")==0||t1->touchx>500&&t1->touchx<584&&t1->touchy>396&&t1->touchy<(396+84))//语音进入相册功能
{
myspeak->stop();
std::cout<<"nihao"<<std::endl;
photo_back();//显示图相的返回值按钮的图片
while(1)
{
get_pthoto_end=menu_show("photo",0);
if(get_pthoto_end==1)
{
myspeak->start();
strcpy(myspeak->cmd_buf,"NULL");
show_theam(0);
menu_show("speak",0);
break;
}
}
}
if(t1->touchx>200&&t1->touchx<284&&t1->touchy>396&&t1->touchy<(396+84)||strcmp(myspeak->cmd_buf,"窗帘")==0)
{
menu_show("window_start",0);
fwindow_flag=1;
while(1)
{
if(t1->touchx>550&&t1->touchx<(550+84)&&t1->touchy>200&&t1->touchy<284||strcmp(myspeak->cmd_buf,"拉上")==0||strcmp(myspeak->cmd_buf,"拉开")==0)//窗帘按钮控制
{
if(fwindow_flag==1||strcmp(myspeak->cmd_buf,"拉上")==0)//按一次就反转
{
fwindow_flag=0;
menu_show("window",fwindow_flag);
}
else if(fwindow_flag==0||strcmp(myspeak->cmd_buf,"拉开")==0)
{
fwindow_flag=1;
menu_show("window",fwindow_flag);
}
t1->touchx=0; //对p1对象的xy坐标进行坐标修改,避免重复进入该判断
t1->touchy=0;
memset(myspeak->cmd_buf,0,1024);
}
else if(t1->touchx>550&&t1->touchx<(550+56)&&t1->touchy>100&&t1->touchy<156||strcmp(myspeak->cmd_buf,"返回")==0)//返回主页面判断
{
show_theam(0);//显示主界面
menu_show("speak",0);
memset(myspeak->cmd_buf,0,1024);
break;
}
}
}
if(strcmp(myspeak->cmd_buf,"灯")==0||t1->touchx>300&&t1->touchx<384&&t1->touchy>396&&t1->touchy<(396+84))//语音识别进入控制灯
{
menu_show("led",0);
photo_back();//显示图相的返回值按钮的图片
led_flag=0;
while(1)
{
if(strcmp(myspeak->cmd_buf,"灯")==0||strcmp(myspeak->cmd_buf,"关闭灯")==0||t1->touchx>200&&t1->touchx<(200+84)&&t1->touchy>200&&t1->touchy<284)
{
if(led_flag==0||strcmp(myspeak->cmd_buf,"灯")==0)//按一次就反转
{
led_flag=1;
menu_show("led",led_flag);
}
else if(led_flag==1||strcmp(myspeak->cmd_buf,"关闭灯")==0)
{
led_flag=0;
menu_show("led",led_flag);
}
t1->touchx=0; //对p1对象的xy坐标进行坐标修改,避免重复进入该判断
t1->touchy=0;
memset(myspeak->cmd_buf,0,1024);
}
else if(t1->touchx>0&&t1->touchx<84&&t1->touchy>0&&t1->touchy<84||strcmp(myspeak->cmd_buf,"返回")==0)//返回主页面判断
{
t1->touchx=0; //对p1对象的xy坐标进行坐标修改,避免重复进入该判断
t1->touchy=0;
show_theam(0);//显示主界面
menu_show("speak",0);
break;
}
}
}
else if(t1->touchx>400&&t1->touchx<484&&t1->touchy>396&&t1->touchy<(396+84)||strcmp(myspeak->cmd_buf,"音乐")==0)//语音控制音乐
{
mymusic=new music();
t1->stop();//先结束线程
t1->ts_close();//关闭触摸屏类
delete t1;
menu_show("music",0);
p4=new pthread_touch();//实例化新的触摸屏类
p4->ts_open();//打开触摸屏驱动
p4->start();//线程开启
while(1)
{
if(p4->touchx>362&&p4->touchx<418&&p4->touchy>(288+50)&&p4->touchy<(322+50)||strcmp(myspeak->cmd_buf,"播放")==0||strcmp(myspeak->cmd_buf,"继续")==0||strcmp(myspeak->cmd_buf,"暂停")==0)//播放音乐开关
{
it=music_path.begin();
if(music_flag==0||strcmp(myspeak->cmd_buf,"继续")==0)//继续播放
{
std::cout<<"继续播放"<<std::endl;
music_flag=1;
mymusic->music_cont();
memset(myspeak->cmd_buf,0,1024);
}
else if(music_flag==1||strcmp(myspeak->cmd_buf,"暂停")==0)//暂停
{
std::cout<<"暂停"<<std::endl;
music_flag=0;
mymusic->music_stop();
memset(myspeak->cmd_buf,0,1024);
}
else if(music_flag==3&&music_play==0||strcmp(myspeak->cmd_buf,"播放")==0)//开始播放
{
music_play=1;
std::cout<<"播放"<<std::endl;
music_flag=1;
mymusic->music_play(it->c_str());
memset(myspeak->cmd_buf,0,1024);
}
p4->touchx=0; //对p1对象的xy坐标进行坐标修改,避免重复进入该判断
p4->touchy=0;
}
else if(p4->touchx>100&&p4->touchx<180&&p4->touchy>50&&p4->touchy<120||strcmp(myspeak->cmd_buf,"返回")==0)//返回主页面判断
{
mymusic->music_pause();
memset(myspeak->cmd_buf,0,1024);
show_theam(0);
menu_show("speak",0);
break;
}
else if(p4->touchx>288&&p4->touchx<324&&p4->touchy>341&&p4->touchy<370||strcmp(myspeak->cmd_buf,"上一首")==0)//判断上一首
{
if(music_play==0)
{
it=music_path.begin();
mymusic->music_play(it->c_str());//打开新音乐
music_play=1;
}
if(it==music_path.begin())
{
it=music_path.end();
}
mymusic->music_pause();//关闭音乐
it--;
std::cout<<"上一首"<<*it<<std::endl;
mymusic->music_play(it->c_str());//打开新音乐
memset(myspeak->cmd_buf,0,1024);
p4->touchx=0; //对p1对象的xy坐标进行坐标修改,避免重复进入该判断
p4->touchy=0;
}
else if(p4->touchx>445&&p4->touchx<490&&p4->touchy>340&&p4->touchy<370||strcmp(myspeak->cmd_buf,"下一首")==0)//判断下一首
{
if(music_play==0)
{
it=music_path.begin();
mymusic->music_play(it->c_str());//打开新音乐
music_play=1;
}
else
{
mymusic->music_pause();//关闭音乐
it++;
if(it==music_path.end())
{
it=music_path.begin();
}
std::cout<<"下一首"<<*it<<std::endl;
mymusic->music_play(it->c_str());//打开新音乐
}
memset(myspeak->cmd_buf,0,1024);
p4->touchx=0; //对p1对象的xy坐标进行坐标修改,避免重复进入该判断
p4->touchy=0;
}
}
delete mymusic;
p4->stop();//关闭p1类生成的
p4->ts_close();
delete p4;
t1=new pthread_touch();
t1->ts_open();
t1->start();
}
if(t1->touchx>720&&t1->touchx<780&&t1->touchy>360&&t1->touchy<420)//点击退出
{
show_theam(0);//显示主界面
break;
}
}
}
else if(t1->touchx>720&&t1->touchx<780&&t1->touchy>360&&t1->touchy<420)//点击退出
{
show_theam(0);//显示主界面
break;
}
}
myspeak->stop();
delete myspeak;
t1->touchx=0;
t1->touchy=0;
}
if(t1->touchx>720&&t1->touchx<800&&t1->touchy>0&&t1->touchy<84)//结束关机
{
break;
}
}
t1->stop();
t1->ts_close();
}
~desk_top()
{
init_speak();
}
};
int main()
{
desk_top *a=new desk_top();
delete a;
return 0;
}
linux简单智家语音小助手
于 2023-11-23 16:12:01 首次发布