基于Linux粤嵌GEC6818开发板的电子乐队程序设计
(四种模式:和弦模式、键盘模式、鼓点模式、编曲模式)

三种音源独立设计:钢琴、钢琴和弦、鼓点
四种模式:和弦模式、键盘模式、鼓点模式、编曲模式
键盘模式包含16个按键 包含所有音名 所有调式皆可弹奏
和弦模式包含C/Am调式常用的16个和弦 包括不协和音程进行

GEC6818开发板是粤嵌公司提供的

资源:
download.csdn.net/download/weixin_53403301/66915088

所有音源资源:
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 hchar 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);  //关闭释放LCDmunmap(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);   //关闭LCDclose(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=1struct 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;
}

【优秀课设】基于Linux粤嵌GEC6818开发板的电子乐队程序设计(四种模式:和弦模式、键盘模式、鼓点模式、编曲模式)相关推荐

  1. 基于粤嵌gec6818开发板嵌入式开发电子相册,音乐播放,视频播放,2048游戏

    一.功能与要求 实现功能:本系统需要使用粤嵌的GEC-6818开发板设计一款娱乐影音系统,其中包括图片显示(相册).音乐播放.视频播放,游戏四个部分,在每个部分内部,具有操控各个部分的功能触摸按键.本 ...

  2. 粤嵌GEC6818开发板-入门感慨篇

    第一次接触嵌入式开发,小脑袋是一篇空白,度娘各种资料,零零碎碎,似懂非懂,确实有点懵逼. 1.前期准备 粤嵌GEC6818开发板一套,USB转串口线一根(简称A线),网线一根(简称N线)(可选).用A ...

  3. 基于粤嵌gec6818开发板嵌入式电子相册,智能家居,音乐播放,灯光控制,2048游戏

    需要完整项目源码和答辩PPT可以私信我! 展示项目内容:

  4. 粤嵌gec6818开发板轮流显示颜色

    粤嵌gec6818开发板轮流显示颜色 #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> ...

  5. 粤嵌6818开发板项目

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 一.前期准备 二.项目内容 1.实现代码 2.上课笔记 总结 前言 最近接触了一块新的板子,是粤嵌公司自主研发的681 ...

  6. 基于Cortex-A53内核Linux系统gec6818开发板的电子自助点餐设计

    由于是多文件下编译,涉及的文件很多,还有链接库,发源代码读者也不能编译运行,因此不将源代码下发打印.将所有的文件压缩成包,放到百度网盘上,话不多说上链接,有简陋功能展示视频.(可直接扫描二维码). 链 ...

  7. 基于粤嵌6818开发板上通过网络连接实现文件传输

    下面分别介绍三种通过网线来传输文件的方式,其配置方式如下: 1.计算机与开发板通过网线连接.(计算机可以连接wifi) 首先查找到个人计算机上的IP,要保证前三个参数相同保证在同一个网段上. 例如:1 ...

  8. 操作系统课设之Linux 进程间通信

    前言 课程设计开始了,实验很有意思,写博客总结学到的知识 白嫖容易,创作不易,学到东西才是真 本文原创,创作不易,转载请注明!!! 本文链接 个人博客:https://ronglin.fun/arch ...

  9. 操作系统课设之Linux 进程管理

    前言 课程设计开始了,实验很有意思,写博客总结学到的知识 白嫖容易,创作不易,学到东西才是真 本文原创,创作不易,转载请注明!!! 本文链接 个人博客:https://ronglin.fun/arch ...

  10. C语言实现电子音乐相册---粤嵌GEC6818嵌入式系统实训

    C语言实现电子音乐相册---粤嵌GEC6818嵌入式系统实训 功能演示: 版本介绍 滑动式 点击放大式 完整版 至尊版 获取方式 功能演示: 演示视频: 滑动式 点击放大式 版本介绍 分为滑动式.点击 ...

最新文章

  1. 条款五:对应的new和delete要采用相同的形式
  2. 感谢Adobe,用上了Silverlight RC0版本
  3. 每日站立会议个人博客二
  4. python 对象引用、可变性 和 垃圾回收
  5. 天弘基金交易数据清算从8小时缩至1.5小时 解决余额宝算力难题
  6. extjs 中动态给gridpanel 复选框赋值
  7. 通过QEMU-GuestAgent实现从外部注入写文件到KVM虚拟机内部
  8. mySql版本的相关问题:com.mysql.cj.jdbc.Driver和com.mysql.jdbc.Driver
  9. mysql创建视图不允许子查询
  10. 基于scikit-learn的随机森林调参实战
  11. Programming in the Mid-Future(转)
  12. MYCAT 安装(转)
  13. 14.ThreadLocal
  14. Unknown run configuration type AndroidRunConfigurationType的解决办法
  15. 卸载mySQL数据库
  16. Android签名总结
  17. C# 获取打印机状态
  18. 编写README文档(Markdown)
  19. 现代版的———项链 :(  转
  20. 群晖NAS搭建测速网站,支持万兆

热门文章

  1. 应急响应-文件痕迹排查
  2. .net core增强工作流组件,基于稳定平台,多项目整合开发
  3. Python中随机漫步的实现
  4. nim game代码java_LeetCode Nim Game
  5. 分享一道用Python基础+蒙特卡洛算法实现排列组合的题目(附源码)
  6. 苹果的widget抄袭android,并非致敬!苹果解释iOS 14“桌面小工具”细节:和Android很不一样...
  7. SpringBoot初学笔记(SpringBoot实战之数据库相关操作)
  8. 漫谈程序员系列 薪资 你是我不能言说的伤
  9. Java Web 后续(三)
  10. 感慨一下中年人的焦虑