用于洞箫练习乐谱显示软件

新手练箫 每个音对应的指法还不熟 又觉得一个一个看指法表太麻烦。于是自己搓了一个练习洞箫的软件,方便在看乐谱的同时,下方直接能显示对应指法。(G调洞箫 指法作5)

如下图所示

2024.2.5 完成初版

开发使用的是上古时代的dev.c 也暂时没有用界面库做 还是有很多瑕疵;

整体实现:

需要在代码中手敲进乐谱和对应汉字 分别放到两个数组里 一个乐符对应一个汉字  乐符没有对应汉字的在汉字数组中用0表示;乐符数组中, 5 6 7表示是低音的sol la xi 13=6+7 是中音的la 

1.程序运行时,检测用户输入 如果输入的是1 输出女儿情洞箫乐谱 

2.将输入的乐谱和汉字数组转换到定义的结构体中 neq_stru

3.根据转换后的结构体打印乐谱

整体功能比较简陋 之后会根据情况修改更新

工程链接 包括代码cpp 与可执行文件exe

链接:https://pan.baidu.com/s/1FWM6W0Rj7NlfF5PQVNF7Nw?pwd=wcjj 
提取码:wcjj

工程代码(好像并没有用到string.h来着)

#include <stdio.h>
#include <string.h>
//G调魈 指法作五 
#define NUMPERLINE 15	//每行显示的乐符个数 
#define XIAO1	"●\t"	//表示该箫孔按下 
#define XIAO0	"○\t"	//表示该箫孔松开 
#define NEQLINE 3 		//女儿情行数 
typedef struct{
	int num;	//音阶 
	char word[2];//汉字  空汉字用两个零字节表示 
}music_note;
//女儿情
char finger_table[16][8]={{1,1,1,1,1,1,1,1},//5. sol
						{1,1,1,1,1,1,1,0},	//6. la
						{1,1,1,1,1,0,1,0},	//7. si
						{1,1,1,1,0,0,1,0},	//1 do
						{1,1,1,0,0,0,1,0},	//2 re
						{1,0,1,0,0,0,1,0},	//3 mi
						{0,1,1,1,0,0,1,0},	//4 fa
						{0,1,1,1,1,1,1,1},	//5 sol
						{1,1,1,1,1,1,1,0},	//6 la
						{1,1,1,1,1,0,1,0},	//7	xi
						{1,1,1,1,0,0,1,0},	//.1 do
						{1,1,1,0,0,0,1,0},	//.2 re
						{1,0,1,0,0,0,1,0},	//.3 mi
						{0,1,1,1,1,1,1,0},	//.4 fa
						{0,1,1,1,1,1,1,1},	//.5 sol
						{1,1,1,0,1,1,1,0},	//.6 la
};
//之后要先计算出共有多少音符 方便计算出要分配的结构体大小 
char nverqingyin[NEQLINE][30] = {{5,6,8,9,10,7,13,7,5,6},
					{6,8,9,10,12,13,8,9,10,11,10},
					{10,10,12,13,12,13,6,10,9,8,9,10,5,6,7,10,6,6,8,8}};
char nverqingzi[NEQLINE][50] = {{"鸳鸯双栖蝶0双00飞"},
						{"0满园春色惹0人00醉"},
						{"0悄悄问圣僧女儿美不美女儿0美0不美00"}}; 
music_note neq_stru[100];//女儿情数据结构体 


void Nverqing(void);
int shownote(music_note * music_stru, int size);
int main(void)
{
	int num;
	while(1){
	 
		scanf("%d",&num); 

		for(int i = 0;i < 3;i++)
		{
			for(int j = 0; j<50;j+=2)
			{
				if(nverqingzi[i][j] == '\0')break;
				else if(nverqingzi[i][j] == '0'){
					j--;
					continue;
				}
				printf("%c%c ",nverqingzi[i][j],nverqingzi[i][j+1]);
			}
			printf("\r\n"); 
		}
		if(num == 1)Nverqing();
	
	}
	return 0;
}
//将全局变量音符和汉字整理为结构体 
//模仿乐谱 顺序排列 
void Nverqing(void)
{
	
	int pos_in_stru = 0;
	int pos_in_lineyin;	//当前位于音符数组的第几个字节
	int pos_in_linezi;	//当前位于歌词数组的第几个字节 
	//遍历每行 
	for(int line = 0;line < NEQLINE;line++) {
		pos_in_lineyin = 0;
		pos_in_linezi = 0;
		while(nverqingyin[line][pos_in_lineyin] != 0)
		{
			neq_stru[pos_in_stru].num = nverqingyin[line][pos_in_lineyin];//乐符赋值			//汉字赋值 
			if(nverqingzi[line][pos_in_linezi] == '0')
			{
				neq_stru[pos_in_stru].word[0] = 0;//两个字节都赋值为0表示该音符处无歌词 
				neq_stru[pos_in_stru].word[1] = 0;
				pos_in_linezi++;//加一个字节 
			}
			else
			{
				neq_stru[pos_in_stru].word[0] = nverqingzi[line][pos_in_linezi];
				neq_stru[pos_in_stru].word[1] = nverqingzi[line][pos_in_linezi+1];
				pos_in_linezi += 2;//加两个字节 
			}
			pos_in_stru++;
			pos_in_lineyin++;
		}
	}
	//test
	/* 
	for(int i = 0; i < 100;i++)
		printf("%d %c%c\r\n",neq_stru[i].num,neq_stru[i].word[0],neq_stru[i].word[1]);
	*/
	shownote(neq_stru,100);
}


int shownote(music_note * music_stru, int size)
{
	int pos = 0; 
	//每行输出NUMPERLINE个音符 
	for(int i = 0; i < size; i += NUMPERLINE - 1)
	{
		if(music_stru[i].num < 5 || music_stru[i].num > 20)return 0;
		for(int j = 0;j < NUMPERLINE - 1;j++)
		{
			if(music_stru[i+j].num >= 15)
				printf(".\t");
				else printf("\t");
		} 
		printf("\r\n");
		for(int j = 0;j < NUMPERLINE - 1;j++)
		{
			if(music_stru[i+j].num > 7 && music_stru[i+j].num <= 14)
				printf("%d\t",music_stru[i+j].num-7);
			else if(music_stru[i+j].num > 14 && music_stru[i+j].num <= 21)
				printf("%d\t",music_stru[i+j].num-14);
			else printf("%d\t",music_stru[i+j].num);
		}
		printf("\r\n");
		for(int j = 0;j <= NUMPERLINE - 1;j++)
		{
			if(music_stru[i+j].num <= 7 && music_stru[i+j].num > 0)
				printf(".\t");
			else printf("\t");
		}
		printf("\r\n\r\n");
		for(int j = 0;j < NUMPERLINE - 1;j++)
		{
			if(music_stru[i+j].word[0] == 0 && music_stru[i+j].word[1] == 0)printf("\t");
			else printf("%c%c\t",music_stru[i+j].word[0],music_stru[i+j].word[1]);
		}
		printf("\r\n");
		//打印箫孔 
		for(int line = 0; line < 8; line++)
		{
			for(int j = 0;j < NUMPERLINE - 1;j++)
			{
				if(finger_table[music_stru[i+j].num - 5][line] == 0)printf(XIAO0);
				else if(finger_table[music_stru[i+j].num - 5][line] == 1)printf(XIAO1);
			}
			printf("\r\n");
		}
	}
	return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值