基于Cortex-A53内核Linux系统GEC6818开发板的电子乐队程序设计(四种模式:和弦模式、键盘模式、鼓点模式、编曲模式)

基于Cortex-A53内核Linux系统GEC6818开发板的电子乐队程序设计
(四种模式:和弦模式、键盘模式、鼓点模式、编曲模式)
GEC6818开发板是粤嵌公司提供的

资源:
https://download.csdn.net/download/weixin_53403301/20086940

所有音源资源:
https://music.163.com/#/album?id=130101018

先上和弦模式、键盘模式、鼓点模式、编曲模式的四个模式实物图:
和弦模式16键,键盘模式16键,鼓点模式8键,编曲模式16键。
每个按键上都写有此按键的对应音名。
切换、按下其他按键时有声音淡出功能
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

摘要:
本次所进行的系统设计名为《基于GEC6818开发板的电子乐队系统设计》,诣在通过程序的编写、编译,在基于Linux系统的GEC6818开发板上实现电子乐队系统。
此系统诣在为对音乐感兴趣的人提供一个方便的、小巧的、简洁的应用程序,使其能够进行演奏、音乐试验等。虽然功能上不如专业的电钢琴、MIDI键盘等乐器,但更便于携带,也适合多人乐队使用。
该电子乐队系统具有模式多,音色多,音源质量好等特点,与同类产品相比,具有以下特色和创新。
该电子乐队系统是基于搭载Linux系统内核的GEC6818开发板所实现的,程序代码部分由C语言所编写。
该电子乐队系统共有和弦模式、键盘模式、鼓点模式和编曲模式四个模式。
该电子乐队系统具有多种模式,占用资源少,界面简洁,成本低廉,制作容易,音色质量高,音源音高准确,并可替换和更新音源,还能进行简单的编曲,能够演奏现代音乐系统中的所有调式(包括中国古典乐调式),能用多台设备实现简单的乐队演奏,不同于市场上常见的或其他小组设计的普通Linux系统开发板电子乐器系统。
普通Linux系统开发板电子乐器系统多具有音色单一、按键数量少、可演奏的调式唯一、不可编曲、不可更新音源等缺点。此电子乐队系统也可以作为市场上的电子乐器系统的改进和升级版本。
关键词:Linux,电子乐队,GEC6818,编曲,C语言,电子乐器。

功能及特色:
和弦模式、键盘模式、鼓点模式、编曲模式。
和弦模式16键,键盘模式16键,鼓点模式8键,编曲模式16键。
每个按键上都写有此按键的对应音名。
切换、按下其他按键时有声音淡出功能
可选择钢琴、电子鼓、吉他、贝司等所有可添加的音色。
采用FL Studio 12软件进行编曲混音制成音源。
此软件本身需付费使用(也可进行破解免费使用),音源也须付费购买,本身音源质量高,再经过混音后导出的音源听起来更舒服、质量更高。
采用mplayer播放器,播放16位WAV顶级无损格式,采样率44100,比特率1411kbps。
音频有效频率范围为0-22050Hz,能使人感受到部分超声波。
音高频率为国际七音十二等律音阶频率标准,绝对音高准确,每一个音阶的频率都为上一个音阶频率的√(12&2)倍;相邻音区、相同音名的音频频率倍数关系为2。
A4音的频率为440Hz。
现代音乐七音十二等律音阶系统中Ionian调式(自然大调)、Dorian调式,Phrygian调式、Lydian调式、Mixolydian调式、Aeolian调式(自然小调)、Locrian调式、和声小调、旋律小调中所对应的C、C#、D、D#、E、F、F#、G、G#、A、A#、B调式,共108种调式。
以及中国现代古典乐七音十二等律音阶系统的宫(C)、商(D)、角(E)、变徵(Gb)、徵(G)、羽(A)、变宫(B或Cb)调式中所对应的C、C#、D、D#、E、F、F#、G、G#、A、A#、B调式,共84种调式。
或其他十二等律音阶系统中的调式。
多个模式循环切换,能弹奏旋律,能快速弹奏和弦,能进行编曲并播放编曲后的伴奏,能打鼓点节奏。
能在弹奏一个音源时调节音量。
按键响应快、非常灵敏,能弹奏出琶音、连音等操作,快速弹奏时不卡顿。
能用于乐队演出,同时弹奏多种音色、旋律、鼓点节奏。
可添加、更新音源,增加更多音色、模式。
所有对音乐感兴趣的人,包括但不限于乐队、启蒙者、初学者、编曲工作者、作曲家、歌手、DJ、娱乐K歌者等。
主要面向乐队、编曲工作者、娱乐K歌者、歌手、DJ等。
也可用于简单的音乐教学。
程序编写中,函数的调用方式中多达18个线程,其中和弦模式、键盘模式和鼓点模式各4个线程,编曲模式6个线程。
使用多线程模式调用函数,可以有效降低系统的延时,达到灵敏度高的特点。在快速演奏时,不会因为速度过快造成发音不全的现象,可以演奏出琶音、连音等高端操作。

此电子乐队系统适用于所有对音乐有兴趣爱好的人,不仅可以给刚刚初学音乐的人使用,弹奏简单的C自然大调旋律,也可以给作曲家、乐队使用。适用人群广泛。
乐队可以通过多设备协调使用,达到演出的目的;初学者可以弹奏键盘模式下的简单旋律;作曲家、编曲工作者、DJ可以通过此系统试验自己所写的旋律、节奏、鼓点、Demo;歌手、娱乐K歌者可以通过此系统的和弦模式和编曲模式弹奏和弦,达到弹唱的目的;音乐启蒙者也可以通过此系统启蒙学习音乐,并且音名规范、音高频率标准。
使用并推广此系统,也可以感染更多的人来喜欢音乐、玩音乐、加强对音乐的兴趣。且界面简洁,便于操作,功能方面比市面上的大多数产品都要强大,推广到市场上绝对能大卖。

代码:

# include <stdio.h>		//导入基本函数库
# include <sys/stat.h>		//打开文件等的函数库
# include <fcntl.h>		//打开文件等的函数库
# include <unistd.h>		//关闭文件、延时等的函数库
# include <sys/mman.h>		//内存分配的相关函数库
# include <strings.h>		//结构体函数库
# include <linux/input.h>		//linux系统下的硬件输入函数库
# include <stdlib.h>		//系统命令函数库
# include <pthread.h>		//多线程模式函数库

int tx,ty; 	//定义触摸板坐标变量
//int tp;  	// 定义触摸板压力值变量
int flag=0; 	 //定义触摸板函数指标
int ins,bet;  	// 定义和弦、键盘模式按键位置变量和鼓点模式按键位置变量
char *kill = "killall -SIGKILL mplayer";  // 杀死mplayer
char *mkpp = "mkfifo /pipe";  //创建管道 根目录下
char *chpp = "chmod 777 /pipe";  //更改管道属性
char *play_up = "echo seek +5 > /pipe";  //快进5
char *play_down = "echo seek -5 > /pipe";  // 快退5
char *sound_up = "echo volume +10 > /pipe";  //音量+10
char *sound_down = "echo volume -10 > /pipe";  //音量+10
char *play_pause = "echo pause > /pipe";  //暂停 继续
char *sound_down_20 = "echo volume -20 > /pipe";
char *sound_down_30 = "echo volume -30 > /pipe";
char *sound_down_50 = "echo volume -50 > /pipe";

int fade_out(void) 		//音频淡出函数
{
	system(sound_down_20);
	system(sound_down_30);
	system(sound_down_50);
	return 0;
}

struct chord_image{	//定义和弦图片结构体类 图片路径 显示坐标起始位置x y 宽高w h
	char bmppath[20];
	int x;
	int y;
	int w;
	int h;
};

struct chord_image chord_img[16] = {	//16张和弦图片定义 显示图片的位置不同 第一排8个 第二排8个 共16个 图片大小100*240
	{.bmppath = "C7.bmp",.x=0,.y=0,.w=100,.h=240},
	{.bmppath = "C.bmp",.x=0,.y=240,.w=100,.h=240},
	{.bmppath = "Dm7.bmp",.x=100,.y=0,.w=100,.h=240},
	{.bmppath = "Dm.bmp",.x=100,.y=240,.w=100,.h=240},
	{.bmppath = "Em7.bmp",.x=200,.y=0,.w=100,.h=240},
	{.bmppath = "Em.bmp",.x=200,.y=240,.w=100,.h=240},
	{.bmppath = "Fm.bmp",.x=300,.y=0,.w=100,.h=240},
	{.bmppath = "F.bmp",.x=300,.y=240,.w=100,.h=240},
	{.bmppath = "G7.bmp",.x=400,.y=0,.w=100,.h=240},
	{.bmppath = "G.bmp",.x=400,.y=240,.w=100,.h=240},
	{.bmppath = "Am7.bmp",.x=500,.y=0,.w=100,.h=240},
	{.bmppath = "Am.bmp",.x=500,.y=240,.w=100,.h=240},
	{.bmppath = "Dsus4.bmp",.x=600,.y=0,.w=100,.h=240},
	{.bmppath = "D7.bmp",.x=600,.y=240,.w=100,.h=240},
	{.bmppath = "Gsus4.bmp",.x=700,.y=0,.w=100,.h=240},
	{.bmppath = "E7.bmp",.x=700,.y=240,.w=100,.h=240}
};

struct key_image{	//定义键盘图片类
	char bmppath[20];
	int x;
	int y;
	int w;
	int h;
};

struct key_image key_img[16] = {	//16张键盘图片
	{.bmppath = "Db4.bmp",.x=0,.y=0,.w=100,.h=240},
	{.bmppath = "C4.bmp",.x=0,.y=240,.w=100,.h=240},
	{.bmppath = "Eb4.bmp",.x=100,.y=0,.w=100,.h=240},
	{.bmppath = "D4.bmp",.x=100,.y=240,.w=100,.h=240},
	{.bmppath = "Fb4.bmp",.x=200,.y=0,.w=100,.h=240},
	{.bmppath = "E4.bmp",.x=200,.y=240,.w=100,.h=240},
	{.bmppath = "Gb4.bmp",.x=300,.y=0,.w=100,.h=240},
	{.bmppath = "F4.bmp",.x=300,.y=240,.w=100,.h=240},
	{.bmppath = "Ab4.bmp",.x=400,.y=0,.w=100,.h=240},
	{.bmppath = "G4.bmp",.x=400,.y=240,.w=100,.h=240},
	{.bmppath = "Bb4.bmp",.x=500,.y=0,.w=100,.h=240},
	{.bmppath = "A4.bmp",.x=500,.y=240,.w=100,.h=240},
	{.bmppath = "Cb5.bmp",.x=600,.y=0,.w=100,.h=240},
	{.bmppath = "B4.bmp",.x=600,.y=240,.w=100,.h=240},
	{.bmppath = "Db5.bmp",.x=700,.y=0,.w=100,.h=240},
	{.bmppath = "C5.bmp",.x=700,.y=240,.w=100,.h=240}
};

struct beat_image{	//定义鼓点图片类
	char bmppath[20];
	int x;
	int y;
	int w;
	int h;
};

struct beat_image beat_img[8] = {	//8张鼓点图片定义 显示图片的位置不同 第一排4个 第二排4个 共8个 图片大小200*240
	{.bmppath = "Kick.bmp",.x=0,.y=0,.w=200,.h=240},
	{.bmppath = "SnareC.bmp",.x=0,.y=240,.w=200,.h=240},
	{.bmppath = "Snare.bmp",.x=200,.y=0,.w=200,.h=240},
	{.bmppath = "Crash.bmp",.x=200,.y=240,.w=200,.h=240},
	{.bmppath = "Hat.bmp",.x=400,.y=0,.w=200,.h=240},
	{.bmppath = "SnareA.bmp",.x=400,.y=240,.w=200,.h=240},
	{.bmppath = "Clap.bmp",.x=600,.y=0,.w=200,.h=240},
	{.bmppath = "Ride.bmp",.x=600,.y=240,.w=200,.h=240}
};


	struct chord_music{	//定义和弦音频类 wav文件的mplayer播放指令
		char wavplay[60];
	};
	// mplayer 播放器 -slave命令模式 -quiet除杂 -input file=/pipe设置通道 *.wav文件名 &后台运行
	struct chord_music chord_wav[16] = {	//定义16个和弦音源
		{.wavplay = "mplayer -slave -quiet -input file=/pipe C7.wav &"},
		{.wavplay = "mplayer -slave -quiet -input file=/pipe C.wav &"},
		{.wavplay = "mplayer -slave -quiet -input file=/pipe Dm7.wav &"},
		{.wavplay = "mplayer -slave -quiet -input file=/pipe Dm.wav &"},
		{.wavplay = "mplayer -slave -quiet -input file=/pipe Em7.wav &"},
		{.wavplay = "mplayer -slave -quiet -input file=/pipe Em.wav &"},
		{.wavplay = "mplayer -slave -quiet -input file=/pipe Fm.wav &"},
		{.wavplay = "mplayer -slave -quiet -input file=/pipe F.wav &"},
		{.wavplay = "mplayer -slave -quiet -input file=/pipe G7.wav &"},
		{.wavplay = "mplayer -slave -quiet -input file=/pipe G.wav &"},
		{.wavplay = "mplayer -slave -quiet -input file=/pipe Am7.wav &"},
		{.wavplay = "mplayer -slave -quiet -input file=/pipe Am.wav &"},
		{.wavplay = "mplayer -slave -quiet -input file=/pipe Dsus4.wav &"},
		{.wavplay = "mplayer -slave -quiet -input file=/pipe D7.wav &"},
		{.wavplay = "mplayer -slave -quiet -input file=/pipe Gsus4.wav &"},
		{.wavplay = "mplayer -slave -quiet -input file=/pipe E7.wav &"}	
	};

struct key_music{	//定义键盘音频类
	char wavplay[60];
};

struct key_music key_wav[16] = {	//16种键盘音源
	{.wavplay = "mplayer -slave -quiet -input file=/pipe Db4.wav &"},
	{.wavplay = "mplayer -slave -quiet -input file=/pipe C4.wav &"},
	{.wavplay = "mplayer -slave -quiet -input file=/pipe Eb4.wav &"},
	{.wavplay = "mplayer -slave -quiet -input file=/pipe D4.wav &"},
	{.wavplay = "mplayer -slave -quiet -input file=/pipe Fb4.wav &"},
	{.wavplay = "mplayer -slave -quiet -input file=/pipe E4.wav &"},
	{.wavplay = "mplayer -slave -quiet -input file=/pipe Gb4.wav &"},
	{.wavplay = "mplayer -slave -quiet -input file=/pipe F4.wav &"},
	{.wavplay = "mplayer -slave -quiet -input file=/pipe Ab4.wav &"},
	{.wavplay = "mplayer -slave -quiet -input file=/pipe G4.wav &"},
	{.wavplay = "mplayer -slave -quiet -input file=/pipe Bb4.wav &"},
	{.wavplay = "mplayer -slave -quiet -input file=/pipe A4.wav &"},
	{.wavplay = "mplayer -slave -quiet -input file=/pipe Cb5.wav &"},
	{.wavplay = "mplayer -slave -quiet -input file=/pipe B4.wav &"},
	{.wavplay = "mplayer -slave -quiet -input file=/pipe Db5.wav &"},
	{.wavplay = "mplayer -slave -quiet -input file=/pipe C5.wav &"}	
};

struct beat_music{	//定义鼓点音频类
	char wavplay[60];
};

struct beat_music beat_wav[8] = {	//定义8个不同鼓点音源
	{.wavplay = "mplayer -slave -quiet -input file=/pipe Kick.wav &"},
	{.wavplay = "mplayer -slave -quiet -input file=/pipe SnareC.wav &"},
	{.wavplay = "mplayer -slave -quiet -input file=/pipe Snare.wav &"},
	{.wavplay = "mplayer -slave -quiet -input file=/pipe Crash.wav &"},
	{.wavplay = "mplayer -slave -quiet -input file=/pipe Hat.wav &"},
	{.wavplay = "mplayer -slave -quiet -input file=/pipe SnareA.wav &"},
	{.wavplay = "mplayer -slave -quiet -input file=/pipe Clap.wav &"},
	{.wavplay = "mplayer -slave -quiet -input file=/pipe Ride.wav &"}
};

//定义判断是否打开文件的函数
int open_jugg(int i)	
{
	//char *j = "oepn_parm";
	//printf("%s=%d\n",j,i);
	if (i< 0)	//i小于0 则打开失败 返回0
	{
		//printf("failure\n");
		return 0;
	}
	else	//否则打开成功 返回1
	{
		//printf("success\n");
		return 1;
	}
}

//定义lcd屏显示颜色的函数 起始坐标xy 宽高wh BGR颜色值bgr 透明的值tou
int lcd_display(int x, int y, int w, int h, int b, int g, int r, int tou)
{
	int lcd = open("/dev/fb0",O_RDWR);	//以可读可写模式打开lcd驱动
	//printf("LCD=%d\n",open_jugg(lcd));	//判断是否打开
	
	int i,j;	//定义LCD每个像素位置变量
	char *buf = mmap(NULL,800*480*4,PROT_WRITE,MAP_SHARED,lcd,0);	//分配内存 像素buf数组
	//将BGR值赋值到每个像素对应的数组当中
	for(j=y;j<(y+h);j++)
	{
		for(i=x;i<(x+w);i++)
		{
			buf[0+4*i+800*4*j] = b;
			buf[1+4*i+800*4*j] = g;
			buf[2+4*i+800*4*j] = r;
			buf[3+4*i+800*4*j] = tou;	
			//write(lcd,buf,4);	
		}
		//write(lcd,buf,4*800);
	}
	write(lcd,buf,800*480*4);		//将数组的值写入到lcd屏内
	close(lcd);	//关闭释放LCD
	munmap(buf,800*480*4); //释放内存
	return 0;
}

// lcd显示图片 定义指针bmp图片路径 起始坐标 宽 高 透明度
int lcd_dis_bmp(char *bmppath, int x, int y, int w, int h, int tou)
{
	int lcd = open("/dev/fb0",O_RDWR);	//打开LCD屏驱动
	//printf("LCD=%d\n",open_jugg(lcd));	//判断LCD是否打开
	int bmp = open(bmppath,O_RDWR);	//打开bmp图片
	//printf("BMP=%d\n",open_jugg(bmp));	//判断是否打开图片
	
	lseek(bmp,54,SEEK_SET);	//移动光标 从起始点开始 平移量54 跳过BMP格式图片的前54个编码部分 
	char bmpbuf[w*h*3];	//定义bmpbuf图片数组
	read(bmp,bmpbuf,w*h*3);	//读取bmp的数值
	
	int i,j;	//定义LCD每个像素位置变量
	char *buf = mmap(NULL,800*480*4,PROT_WRITE,MAP_SHARED,lcd,0);	//分配内存 像素buf数组
	//将BGR值赋值到每个像素对应的数组当中
	for(j=y;j<y+h;j++)
	{
		for(i=x;i<x+w;i++)
		{
			buf[0+4*i+800*4*j] = bmpbuf[0+3*(i-x)+w*3*(h-1-j+y)];	//将bmp图片对应像素的值写入到LCD屏的像素数组中
			buf[1+4*i+800*4*j] = bmpbuf[1+3*(i-x)+w*3*(h-1-j+y)];
			buf[2+4*i+800*4*j] = bmpbuf[2+3*(i-x)+w*3*(h-1-j+y)];
			buf[3+4*i+800*4*j] = tou;
			//write(lcd,buf,4);	
		}
		//write(lcd,buf,4*800);
	}
	write(lcd,buf,800*480*4);		//写入到LCD屏中
	close(lcd);	//关闭LCD
	close(bmp);	//关闭图片
	munmap(buf,800*480*4); //释放内存	
}


//触摸板扫描函数 获取一次触摸板坐标
int touch_scan()
{
	int tsfd = open("/dev/input/event0",O_RDWR); 	//打开触摸板驱动
	printf("TOUCH=%d\n",open_jugg(tsfd));	//判断是否打开 若打开 则显示TOUCH=1
	struct input_event ts;	//定义输入事件ts类
	bzero(&ts,sizeof(ts));  //清空数据
	while(1)	//循环读取数据
	{
		read(tsfd,&ts,sizeof(ts));	//读取输入事件值
		if(ts.type == EV_ABS)  //绝对坐标事件
		{
			if(ts.code == ABS_X)	//读取x坐标值 赋值给tx
			{
				tx = ts.value;
				flag++;	//指标+1
				// printf("flag=%d",flag);
			}
			if(ts.code == ABS_Y)	//读取y坐标值 赋值给ty
			{
				ty = ts.value;
				flag++;	//指标+1
				// printf("flag=%d",flag);
			}
		}
		
		// if (ts.type == EV_KEY)   //压力
		// {
			// if(ts.code == BTN_TOUCH)
			// {
				// tp = ts.value;
				// flag++;
			// }
		// }
		if (ty>100)		//排除掉屏幕上分100像素的 用于控制按钮的部分
		{
			int a=tx/100;		//判断和弦、键盘模式的x轴坐标位置变量 一排8个键 共2排16个键 x轴共800像素 分为8个部分
			int b=ty/240;		//判断y轴坐标位置变量 共两排 y轴共480个像素 分为两个部分
			int c=tx/200;		//判断鼓点模式的x轴坐标位置变量 一排4个键 共2排8个键 x轴共800像素 分为4个部分
			//printf("b=%d\n",b);
			if(b==0)		//当y轴变量为0时 即为第一排按键
			{
				ins=a*2;		//和弦、键盘模式变量赋值 第一排分别为0/2/4/6/8/12/14 对应的第ins号图片/音频
				bet=c*2;		//鼓点模式变量赋值 第一排分别为0/2/4/6 对应的第bet号图片/音频
				//printf("0=%d\n",i);
			}
			if(b==1)		//当y轴变量为1时 即为第二排按键
			{
				ins=a*2+1;		//和弦、键盘模式变量赋值 第一排分别为1/3/5/7/9/11/13/15 对应的第ins号图片/音频
				bet=c*2+1;		//鼓点模式变量赋值 第一排分别为1/3/5/7 对应的第bet号图片/音频
				//printf("1=%d\n",i);
			}
		}
		if (flag == 2)	//当指标为2时 中断循环 指标清0 这样可以一次函数只读取一次触摸板坐标值
			{
				flag=0;
				break;
			}			
	}
	return 0;
}

int ex_i=0;		//编曲模式录入和弦序号变量
int exbuf[50];	//编曲模式录入变量
int ex=0;		//编曲模式进行循环时的计数变量
float bpm_one=6.0;		//bpm值变量 默认为60/10=6.0 浮点数
int ex_result=0;		//判断编曲模式是否录制完成的变量 为1时则完成录入
int ex_j=4;		//编曲模式单节重复次数计数变量 默认为4

//定义编曲模式多线程模式下的编曲和弦音频播放函数
void *chord_ex(void *arg)  	
{
	fade_out();
	system(kill);
	system(chord_wav[exbuf[ex]].wavplay);
	if(tx>450&&tx<550&&ty>0&&ty<100)  //中上按钮右边音量+
	{
		system(sound_up);
	}
	if(tx>250&&tx<350&&ty>0&&ty<100)  //中上按钮左边边音量-
	{
		system(sound_down);
	}
}
//和弦模式下的和弦播放函数
void *chord_play(void *arg)
{
	system(chord_wav[ins].wavplay);		//用系统指令代码的方式输入对应第ins号的音频播放指令
	if(tx>450&&tx<550&&ty>0&&ty<100)  //中上按钮右边音量+
	{
		system(sound_up);
	}
	if(tx>250&&tx<350&&ty>0&&ty<100)  //中上按钮左边边音量-
	{
		system(sound_down);
	}
}
void *chord_res(void *arg)		//定义按下和弦后 显示屏对应的位置闪烁后又重新恢复显示的多线程函数
{
	lcd_display(chord_img[ins].x+10,chord_img[ins].y+180,80,45,255,255,255,0);
	lcd_dis_bmp(chord_img[ins].bmppath,chord_img[ins].x,chord_img[ins].y,chord_img[ins].w,chord_img[ins].h,0);
	lcd_dis_bmp(chord_img[ins].bmppath,chord_img[ins].x,chord_img[ins].y,chord_img[ins].w,chord_img[ins].h,0);
	lcd_display(350,0,100,100,0,255,0,0);
	lcd_display(750,0,50,50,0,0,255,0);
}
void *chord_jugg(void *arg)		//定义和弦判断多线程函数
{
	if (ty>100)		//排除掉屏幕上分100像素的 用于控制按钮的部分
	{
		fade_out();
		system(kill);		//清理mplayer播放器
		pthread_t chordplay;	//多线程0 运行和弦播放函数
		pthread_create(&chordplay,NULL,chord_play,NULL);
		pthread_t chordres;		//多线程1 运行和弦按键恢复显示的函数
		pthread_create(&chordres,NULL,chord_res,NULL);
	}
}
void *chord_resex(void *arg)		//定义变去面试按下和弦后 显示屏对应的位置闪烁后又重新恢复显示的多线程函数
{
	lcd_display(chord_img[ins].x+10,chord_img[ins].y+180,80,45,255,255,255,0);
	lcd_dis_bmp(chord_img[ins].bmppath,chord_img[ins].x,chord_img[ins].y,chord_img[ins].w,chord_img[ins].h,0);
	lcd_dis_bmp(chord_img[ins].bmppath,chord_img[ins].x,chord_img[ins].y,chord_img[ins].w,chord_img[ins].h,0);
	lcd_display(350,0,100,100,255,0,0,0);
	lcd_display(750,0,50,50,0,0,255,0);
}
void *chord_juggex(void *arg)		//定义和编曲模式弦判断多线程函数
{
	if (ty>100)		//排除掉屏幕上分100像素的 用于控制按钮的部分
	{
		fade_out();
		system(kill);		//清理mplayer播放器
		pthread_t chordplay;	//多线程12 运行和弦播放函数
		pthread_create(&chordplay,NULL,chord_play,NULL);
		pthread_t chordresex;		//多线程13 运行和弦按键恢复显示的函数
		pthread_create(&chordresex,NULL,chord_resex,NULL);
	}
}

//定义多线程模式下的键盘音频播放函数 同和弦模式
void *key_play(void *arg)
{
	system(key_wav[ins].wavplay);
	if(tx>450&&tx<550&&ty>0&&ty<100)  //中上按钮右边音量+
	{
		system(sound_up);
	}
	if(tx>250&&tx<350&&ty>0&&ty<100)  //中上按钮左边边音量-
	{
		system(sound_down);
	}
}
void *key_res(void *arg)		//定义键盘按键闪烁及恢复函数
{
	lcd_display(key_img[ins].x+10,key_img[ins].y+180,80,45,255,255,255,0);
	lcd_dis_bmp(key_img[ins].bmppath,key_img[ins].x,key_img[ins].y,key_img[ins].w,key_img[ins].h,0);
	lcd_dis_bmp(key_img[ins].bmppath,key_img[ins].x,key_img[ins].y,key_img[ins].w,key_img[ins].h,0);
	lcd_display(350,0,100,100,0,255,0,0);
	lcd_display(750,0,50,50,0,0,255,0);
}
void *key_jugg(void *arg)		//定义键盘判断函数
{
	if (ty>100)		//排除掉屏幕上分100像素的 用于控制按钮的部分
	{
		fade_out();
		system(kill);
		pthread_t keyplay;		//多线程2 运行键盘播放函数
		pthread_create(&keyplay,NULL,key_play,NULL);
		pthread_t keyres;		//多线程3 运行键盘恢复函数
		pthread_create(&keyres,NULL,key_res,NULL);
	}
}

//定义多线程模式下的鼓点音频播放函数 同和弦模式
void *beat_play(void *arg)
{
	system(beat_wav[bet].wavplay);
	if(tx>450&&tx<550&&ty>0&&ty<100)  //中上按钮右边音量+
	{
		system(sound_up);
	}
	if(tx>250&&tx<350&&ty>0&&ty<100)  //中上按钮左边边音量-
	{
		system(sound_down);
	}
}
void *beat_res(void *arg)		//定义鼓点按键闪烁及恢复函数
{
	lcd_display(beat_img[bet].x+15,beat_img[bet].y+185,150,45,255,255,255,0);
	lcd_dis_bmp(beat_img[bet].bmppath,beat_img[bet].x,beat_img[bet].y,beat_img[bet].w,beat_img[bet].h,0);
	lcd_dis_bmp(beat_img[bet].bmppath,beat_img[bet].x,beat_img[bet].y,beat_img[bet].w,beat_img[bet].h,0);
	lcd_display(350,0,100,100,0,255,0,0);
	lcd_display(750,0,50,50,0,0,255,0);
}
void *beat_jugg(void *arg)		//定义鼓点判断函数
{
	if (ty>100)		//排除掉屏幕上分100像素的 用于控制按钮的部分
	{
		fade_out();
		system(kill);
		pthread_t beatplay;		//多线程4 运行鼓点播放函数
		pthread_create(&beatplay,NULL,beat_play,NULL);
		pthread_t beatres;		//多线程5 运行鼓点恢复函数
		pthread_create(&beatres,NULL,beat_res,NULL);
	}
}

//编曲模式显示函数
void *chord_disex(void *arg)
{
	lcd_dis_bmp("Chords_All.bmp",0,0,800,480,0);  	//显示对应的和弦总体图片
	lcd_dis_bmp("Chords_All.bmp",0,0,800,480,0);
	lcd_display(350,0,100,100,255,0,0,0);		//显示中上位置 100*100大小的绿色按钮 用于切换模式
	lcd_display(750,0,50,50,0,0,255,0);		//显示右上位置 50*50大小的红色按钮 用于关闭程序
	lcd_display(0,0,50,50,0,0,255,0);
}

//定义和弦模式初始化显示函数
void *chord_dis(void *arg)
{
	lcd_dis_bmp("Chords_All.bmp",0,0,800,480,0);  	//显示对应的和弦总体图片
	lcd_dis_bmp("Chords_All.bmp",0,0,800,480,0);
	lcd_display(350,0,100,100,0,255,0,0);		//显示中上位置 100*100大小的绿色按钮 用于切换模式
	lcd_display(750,0,50,50,0,0,255,0);		//显示右上位置 50*50大小的红色按钮 用于关闭程序
}
//定义键盘模式初始化显示函数
void *key_dis(void *arg)
{
	lcd_dis_bmp("Keys_All.bmp",0,0,800,480,0);  	//显示对应的键盘总体图片
	lcd_dis_bmp("Keys_All.bmp",0,0,800,480,0);
	lcd_display(350,0,100,100,0,255,0,0);
	lcd_display(750,0,50,50,0,0,255,0);
}
//定义鼓点模式初始化显示函数
void *beat_dis(void *arg)
{
	lcd_dis_bmp("Beats_All.bmp",0,0,800,480,0);  	//显示对应的鼓点总体图片
	lcd_dis_bmp("Beats_All.bmp",0,0,800,480,0);
	lcd_display(350,0,100,100,0,255,0,0);
	lcd_display(750,0,50,50,0,0,255,0);
}

void *ex_play(void *arg)   	//编曲模式循环播放函数
{
	int l;
	for(l=0;l<ex_j;l++)
	{
		pthread_t chordex;		//多线程14 运行编曲播放函数
		pthread_create(&chordex,NULL,chord_ex,NULL);
		sleep(bpm_one);
	}		
}
//主函数
int main(void)
{
	//初始化 建立管道 更改管道属性 杀死已有的mplayer播放器进程
	system(mkpp);
	system(chpp);
	system(kill);
	
	while(1)	//循环进行
	{
		
		pthread_t chorddis;		//多线程6 进行和弦模式初始化显示函数
		pthread_create(&chorddis,NULL,chord_dis,NULL);
		
		while(1)	//和弦模式循环
		{
			lcd_display(350,0,100,100,0,255,0,0);		//一直显示按键
			lcd_display(750,0,50,50,0,0,255,0);
			touch_scan();		//执行触摸板扫描函数
			//printf("x=%d,y=%d,p=%d\n",tx,ty,tp);	
			if(tx>350&&tx<450&&ty>0&&ty<100)  //中上按钮位置切换
				{
					//printf("Centry Up kill\n");
					fade_out();
					system(kill);			//杀死已有进程
					tx=0;		//触摸板坐标变量清零 防止连续判断
					ty=0;
					break;
				}
			if(tx>750&&tx<800&&ty>0&&ty<50)  //右上按钮关闭程序
				{
					fade_out();
					system(kill);		//杀死已有进程
					return 0;		//强制中断主函数
				}
			pthread_t chords;		//多线程7 进行和弦模式判断函数
			pthread_create(&chords,NULL,chord_jugg,NULL);	
		}
		
		pthread_t keydis;		//多线程8 进行键盘模式初始化显示函数
		pthread_create(&keydis,NULL,key_dis,NULL);
		
		while(1)	//键盘模式循环 同和弦模式循环
		{
			lcd_display(350,0,100,100,0,255,0,0);
			lcd_display(750,0,50,50,0,0,255,0);
			touch_scan();
			//printf("x=%d,y=%d,p=%d\n",tx,ty,tp);
			if(tx>350&&tx<450&&ty>0&&ty<100)  //切换
				{
					//printf("Centry Up kill\n");
					fade_out();
					system(kill);
					tx=0;
					ty=0;
					break;
				}
			if(tx>750&&tx<800&&ty>0&&ty<50)  //关闭
				{
					fade_out();
					system(kill);
					return 0;
				}
			pthread_t keys;		//多线程9 进行键盘模式判断函数
			pthread_create(&keys,NULL,key_jugg,NULL);		
		}
		
		pthread_t beatdis;		//多线程10 进行鼓点模式初始化显示函数
		pthread_create(&beatdis,NULL,beat_dis,NULL);
		
		while(1)	//鼓点模式循环 同和弦模式循环
		{
			lcd_display(350,0,100,100,0,255,0,0);
			lcd_display(750,0,50,50,0,0,255,0);
			touch_scan();
			//printf("x=%d,y=%d,p=%d\n",tx,ty,tp);
			if(tx>350&&tx<450&&ty>0&&ty<100)  //切换
				{
					//printf("Centry Up kill\n");
					fade_out();
					system(kill);
					tx=0;
					ty=0;
					break;
				}
			if(tx>750&&tx<800&&ty>0&&ty<50)  //关闭
				{
					fade_out();
					system(kill);
					return 0;
				}
			pthread_t beats;		//多线程11 进行鼓点模式判断函数
			pthread_create(&beats,NULL,beat_jugg,NULL);	
		}
		
		pthread_t chorddisex;		//多线程15 进行编曲模式初始化函数
		pthread_create(&chorddisex,NULL,chord_disex,NULL);
		while(1)	//编曲模式循环 大部分同和弦模式循环
		{
			lcd_display(350,0,100,100,255,0,0,0); //显示蓝色
			lcd_display(750,0,50,50,0,0,255,0);
			lcd_display(0,0,50,50,0,0,255,0);
			touch_scan();
			//printf("x=%d,y=%d,p=%d\n",tx,ty,tp);
			if(tx>350&&tx<450&&ty>0&&ty<100)  //切换
				{
					//printf("Centry Up kill\n");
					fade_out();
					system(kill);
					tx=0;
					ty=0;
					break;
				}
			if(tx>750&&tx<800&&ty>0&&ty<50)  //关闭
				{
					fade_out();
					system(kill);
					return 0;
				}
			if(tx>0&&tx<50&&ty>0&&ty<50)  //中断 开始播放编曲程序
				{
					ex_result=1;
				}
			//printf("i=%d\n",i);
			if(ex_i>0&&ex_result==1)
			{
				fade_out();
				system(kill);
				if(exbuf[ex_i-3]<1)
				{
					bpm_one=6.0;
				}
				else
				{
					bpm_one=6/exbuf[ex_i-3];  //第ex_i-3次录入的和弦编号为bpm值除以10 如按键位置为6 则bpm为60 每拍的时间为1s
				}
				int j,k;
				if(exbuf[ex_i-2]<1)
				{
					j=1;		//默认循环次数值为1
				}
				else
				{
					j=exbuf[ex_i-2];  //第ex_i-2次录入的和弦编号为单节和弦循环次数值
				}
				if(exbuf[ex_i-1]<1)
				{
					ex_j=4;		//默认单节和弦循环次数值为4
				}
				else
				{
					ex_j=exbuf[ex_i-1];		//第ex_i-1次录入的和弦编号为单节中一个和弦重复循环次数的值
				}
				for(k=0;k<j;k++)
				{
					for(ex=0;ex<ex_i-3;ex++)
					{
						pthread_t explay;		//多线程17 进行和弦模式判断函数
						pthread_create(&explay,NULL,ex_play,NULL);	
						sleep(bpm_one*ex_j);
					}
				}
				ex_i=0;
				ex_result=0;
			}
			else
			{
				pthread_t chordsex;		//多线程16 进行编曲模式判断函数
				pthread_create(&chordsex,NULL,chord_juggex,NULL);	
				exbuf[ex_i]=ins;  		//将按键位置赋值给exbuf变量 录入8个和弦 和一个bpm变量 一个循环次数变量
				ex_i++;
			}
		}
			
	}
	return 0;
}
  • 1
    点赞
  • 0
    评论
  • 3
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 数字20 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值