⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 player.c

📁 //--- --- --- - 音乐简谱播放器--- --- --- - /*奏乐程序使用说明 调用方式: sing fname [speed [times]] 文件名 速度(拍/分) 遍
💻 C
字号:

//------------------------------- 音乐简谱播放器-------------------------------------

/*奏乐程序使用说明 
调用方式: sing fname [speed [times]]
文件名 速度(拍/分) 遍数
简谱文件格式:
第1行: 曲名 节拍 调号
第2行-- 乐谱 (空格,换行无意义,但不得插在一个"音描述"内部)
记号:
* 节拍,调号,小节分隔符,终止符,升音符,中音音高,休止符,附点,延长
符等 -- 按照常规.
* 音描述 --
[3连音符][升降还原符]音高[高低音后缀][音长][附点][延长符]
* 3连音符 -- ^ 只标在第1音前,音长只标在第3音后
(3连音的实际总音长为所标音长的两倍,例如:^323'的总音长为1拍)
* 降音符 -- @
* 还原符 -- $
* 高低音后缀 -- H(高音) U(高16度音) 连用音程相加
L(低音) W(低16度音)
* 音长 -- 无(1拍) '(1/2拍) "(1/4拍) 连用为相乘*/

//------------------------------------------------------------------------------------


#include"stdio.h"
#include"math.h"
#include"dos.h"
#define C 262
#define Max 100


//Var public
char Array[Max];
int ArrayLength=0;
int Rests=0;
int ThreeLegatoes=0;
double HalfAccent;
int TonalityVolue=0;
char Tonality[Max];
int UpAndDownArray[7];
int UpAndDownVolue=0;
int GetUpAndDown=0;
int Print=0;


//Get number of ch.
int IfNumber(char ch)
{
	if(ch>='0'&&ch<='9')
	{
		return 1;
	}
	else
	{
		return 0;
	}
}



//Get song messige.
int GetMessige(char Title[],int Metre[],char Tonality[],char ch)
{
	int j;
	if(ch!=' ')
	{
		if(ArrayLength!=-1)
		{
			Array[ArrayLength]=ch;
			ArrayLength++;
		}
		else
		{
			if(ch=='\n')
			{
				printf("\nTitle:%s\nMetre:%d/%d\nTonality:%s\n",Title,Metre[0],Metre[1],Tonality);
				return 1;
			}
			Tonality[TonalityVolue]=ch;
			TonalityVolue++;
		}
	}

	if(ArrayLength>1&&IfNumber(Array[ArrayLength-1])&&(Array[ArrayLength-2]=='/')&&IfNumber(Array[ArrayLength-3]))
	{
		for(j=0;j<ArrayLength-3;j++)
		{
			Title[j]=Array[j];
		}		
		Title[j]='\0';

		Metre[0]=Array[j]-48;
		Metre[1]=Array[ArrayLength-1]-48;

		ArrayLength=-1;
	}

	else if(ArrayLength>1&&IfNumber(Array[ArrayLength-1])&&(Array[ArrayLength-2]!='/')&&IfNumber(Array[ArrayLength-3]))
	{
		return ArrayLength;
	}

	return 0;
}



//Get up or down.
float UpAndDown(char ch)
{
	if(ch=='#')
	{
		return HalfAccent;
	}
	else if(ch=='@')
	{
		return 1.0/HalfAccent;
	}
	return 1;
}


int Big(char ch)
{
	if(ch>='A'&&ch<='Z')
	{
		return 1;
	}
	else if(ch>='a'&&ch<='z')
	{
		return -1;
	}
	return 0;
}

//To Metre Hz.
double ToHz(char ch)
{
	int NoteNumber,NoteHz;
	if(ch>='A'&&ch<='G')
	{
		NoteNumber=ch-'C';
	}
	else if(ch>='a'&&ch<='g')
	{
		NoteNumber=ch-'C'-32;
	}
	else
	{
		return C;
	}
	if(NoteNumber==4)
	{
		NoteHz=C*pow(HalfAccent,NoteNumber*2-1);
	}
	else if(NoteNumber<0)
	{
		NoteHz=C*pow(HalfAccent,NoteNumber*2+1);
	}
	else
	{
		NoteHz=C*pow(HalfAccent,NoteNumber*2);
	}
	if(Big(ch)==-1)
	{
		NoteHz*=2;
	}
	return NoteHz;
}


//Get the first Hz base on C.
double GetHz()
{
	if(TonalityVolue==0)
	{
		printf("No tonality!");
		getch();
		exit(0);
	}
	if(TonalityVolue==1)
	{
		return ToHz(Tonality[0]);
	}
	else if(TonalityVolue==2)
	{
		if(IfNumber(Tonality[1]))
		{
			if(Big(Tonality[0])==1)
			{
				return ToHz(Tonality[0])/pow(2,Tonality[1]-48);
			}
			else if(Big(Tonality[0])==-1)
			{
				return ToHz(Tonality[0])*pow(2,Tonality[1]-48);
			}
		}
		else
		{
			return UpAndDown(Tonality[0])*ToHz(Tonality[1]);
		}
	}
	else if(TonalityVolue==3)
	{
		if(Big(Tonality[1])==1)
		{
			return UpAndDown(Tonality[0])*ToHz(Tonality[1])/pow(2,Tonality[2]-48);
		}
		else if(Big(Tonality[1])==-1)
		{
			return UpAndDown(Tonality[0])*ToHz(Tonality[1])*pow(2,Tonality[2]-48);
		}
	}
	return C;
}



//Return note Hz.
double GetNoteHz(int Note)
{
	if(Note>=4)
	{
		return GetHz()*pow(HalfAccent,((Note-1)*2-1));
	}
	else if(!Note)
	{
		return 0;
	}
	else
	{
		return GetHz()*pow(HalfAccent,((Note-1)*2));
	}
}



//Get total Hz and return delay time.
double GetDelayTime(float *NoteHz,char Mark,float *ExtraDelayTime) 
{	
	int i;

	//Up and down:
	if(Rests!=0)
	{
		UpAndDownArray[UpAndDownVolue]+=Rests;
		Rests=0;
	}
	if(UpAndDownArray[UpAndDownVolue]&&(IfNumber(Mark)))
	{
		*NoteHz*=pow(HalfAccent,UpAndDownArray[UpAndDownVolue]);
	}

	//Hz part:
	if(Mark=='#')
	{
		Rests=1;
	}
	else if(Mark=='@')
	{
		Rests=-1;
	}
	else if(Mark=='$'||Mark=='|')
	{
		for(i=0;i<7;i++)
		{
			UpAndDownArray[i]=0;
		}
	}
	else if(Mark=='H')
	{
		*NoteHz*=2;
	}
	else if(Mark=='U')
	{
		*NoteHz*=4;
	}
	else if(Mark=='L')
	{
		*NoteHz/=2;
	}
	else if(Mark=='W')
	{
		*NoteHz/=4;
	}

	//Three legatoes:
	if(ThreeLegatoes==1&&IfNumber(Mark))
	{
		ThreeLegatoes=2;
		return 1/3.0;
	}

	//Delay part:
	else if(Mark=='^')
	{
		ThreeLegatoes=1;
	}	
	else if(ThreeLegatoes==2&&Mark=='\'')
	{
		ThreeLegatoes=0;		
	}	
	else if(ThreeLegatoes==0&&Mark=='\'')
	{
		return 1/2.0;		
	}
	else if(Mark=='\"')
	{
		return 1/4.0;
	}
	else if(Mark=='-')
	{
		*ExtraDelayTime+=1;
	}
	else if(Mark=='.')
	{
		*ExtraDelayTime+=0.5;
	}
	return 1;
}



//Read file and 'sound'. 
void Read(char FileName[],double speed)
{
	int Note,NoteLength=0,GetMessigeTime=0,Metre[2],Zero=0;
	float NoteHz=0,DelayTime=1,ExtraDelayTime=0,TotalDelayTime=0;
	char ch,Title[Max];
	FILE *fp;		
	if((fp=fopen(FileName,"r"))==NULL)
	{
		printf("Cannot open this file!\n");
		getch();
		exit(0);
	}

	while(!feof(fp))
	{
		ch=fgetc(fp);

		//Messige part:
		if(GetMessigeTime==1)
		{	
			GetMessigeTime=-1;
		}
		else if((GetMessigeTime>1||feof(fp))&&GetMessigeTime!=-1)
		{
			printf("\nNo Metre.\n");
			getch();
			exit(0);
		}
		else if(GetMessigeTime==0)
		{			
			GetMessigeTime=GetMessige(Title,Metre,Tonality,ch);
			continue;
		}

		//Sound part:
		if((ch>='0'&&ch<='7')||feof(fp))
		{
			Note=ch-48;
			if(NoteLength)
			{
				if(Zero)
				{
					nosound();
					Zero=0;
				}
				else
				{
					sound(NoteHz);
				}
				TotalDelayTime=DelayTime+ExtraDelayTime;
				delay(TotalDelayTime*(60/speed)*1000*(4.0/Metre[1]));

				//text NoteHz and TotalDelayTime:
				if(Print)
				{
					printf("\n%.0f,%f\n",NoteHz,TotalDelayTime);
				}

				if(ThreeLegatoes!=2)
				{
					DelayTime=1;
				}
				ExtraDelayTime=0;
			}	
			if(ch=='0')
			{
				Zero=1;
			}
			UpAndDownVolue=Note-1;
			NoteHz=GetNoteHz(Note);
			NoteLength++;
		}
		DelayTime*=GetDelayTime(&NoteHz,ch,&ExtraDelayTime);
	}		
	nosound();
	fclose(fp);
}


//String to Number.
double ToNumber(char *String)
{
	int i,j;
	double Number=0;
	for(i=0;String[i]!='\0';i++)
	{
		String[i]-=48;
	}
	for(j=0;i>0;i--)
	{
		Number+=String[i-1]*pow(10,j);
		j++;
	}
	return Number;
}



//by linfuqing N3070130124	
void main(int Number,char *Admin[])
{
	int i,j;
	double time,speed;
	char *FileName;	
	HalfAccent=exp(1.0/12*log(2));

	//Initialization.
	if(Number==1)
	{
		printf("Please write down your music file name!\n");
		getch();
		exit(0);
	}
	if(Number==2)
	{
		FileName=Admin[1];
		speed=180;
		time=1;
	}
	else if(Number==3)
	{
		FileName=Admin[1];
		speed=ToNumber(Admin[2]);
		time=1;
	}
	else if(Number==4)
	{
		FileName=Admin[1];
		speed=ToNumber(Admin[2]);
		time=ToNumber(Admin[3]);
	}
	else if(Number==5)
	{
		FileName=Admin[1];
		speed=ToNumber(Admin[2]);
		time=ToNumber(Admin[3]);
		Print=1;
	}
	else
	{
		printf("Error!");
		getch();
		exit(0);
	}

	//now begin.
	printf("\n-------------------------------[music player]------------------------------\n");
	for(i=0;i<time;i++)
	{
		for(j=0;j<7;j++)
		{
			UpAndDownArray[j]=0;
		}
		TonalityVolue=0;
		ArrayLength=0;
		Rests=0;
		ThreeLegatoes=0;
		Read(FileName,speed);
	}
	printf("\n-----------------------------------[end]-----------------------------------\n");
	getch();
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -