用C语言开发音乐程序主要用到两个库函数: sound() 以指定频率打开PC机的扬声器,频率以赫兹为单位。 nosound() 关闭扬声器。 一 乐谱文件的制作 编写音乐程序时,首先需要制作被演奏音乐的乐谱文件。制作乐谱文件可用不同的符号标记,只要所编制的程序易于识别即可。 下面是编制乐谱文件的一种规则:最高音在每个音的前面加“*”:高音,在每个音的前面加“h”;中音,在每个音的前面加“m”;低音,在每个音的前面加“l”。 “*”,“h”,“m”,“l”与其控制的音符构成音高,决定发声频率。音高的后面是音长,可用整数或小数输入,以控制延时,但中间必须用空格分开。乐谱文件的最前端是一个整数,表示音长基数,一般为300的倍数。乐谱文件的最末端是乐谱文件结束符“##”,以表示乐谱文件结束。 每个音的音长=音长基数*节拍数,其中,音长基数是乐谱文件的第一个字符,如上面乐谱文件为3600,每个音的音频可用一模拟频率值输入。下面是中央C及其前后4个8度中各个音符的频率值 低8度 1 2 3 4 5 6 7 131 147 165 176 196 220 247 中央C 1 2 3 4 5 6 7 262 296 329.7 349.2 392 440 493.9 高8度 1 2 3 4 5 6 7 523.3 587.3 659.3 698.5 784.0 880 987.8 最高8度 1 2 3 4 5 6 7 1046.5 1174.7 1318.5 1396.9 1568.0 1760 1975.5 二 源程序 #include<stdio.h> #include<stdlib.h> #include<dos.h> void main(int argc,char *argv[]) { FILE *fp; int rate; char sound_high[3]; float sound_long; register int i=0,j; int sign=0; float str[200][2]; if(argc!=2) /*命令行参数个数不正确*/ { printf("Parameters Errors!\n"); exit(1); } if((fp=fopen(argv[1],"r"))==NULL) /*文件打开失败*/ { printf("Open file music.doc Errors!\n"); exit(1); } fscanf(fp,"%d",&rate);/*读取音长基数的值*/ while(!feof(fp)&&!sign) /*文件没有结束并且数据还是乐谱*/ { fscanf(fp,"%s%f",sound_high,&sound_long); /*得到音频,音长的数值*/ str[1]=rate*sound_long; /*音长=音长基数*节拍数*/<BRTCH(SOUND_HIGH[0]) { case'*': /*最高音*/ { case'1': str[i++][0]=1046.5; break; case'2': str[i++][0]=1174.7; break; case'3': str[i++][0]=1318.5; break; case'4': str[i++][0]=1396.9; break; case'5': str[i++][0]=1568; break; case'6': str[i++][0]=1760; break; case'7': str[i++][0]=1975.5; break; default: printf("\nErrors in music.doc\n"); exit(1); } case'h': /*高音*/<BRTCH(SOUND_HIGH[1]) { case'1': str[i++][0]=523.3; break; case'2': str[i++][0]=587.3; break; case'3': str[i++][0]=659.3; break; case'4': str[i++][0]=698.5; break; case'5': str[i++][0]=784.0; break; case'6': str[i++][0]=880; break; case'7': str[i++][0]=987.8; break; default: printf("\nErrors in music.doc\n"); exit(1); } case'm': /*中音*/<BRTCH(SOUND_HIGH[1]) { case'1': str[i++][0]=262; break; case'2': str[i++][0]=296; break; case'3': str[i++][0]=329.6; break; case'4': str[i++][0]=349.2; break; case'5': str[i++][0]=392; break; case'6': str[i++][0]=440; break; case'7': str[i++][0]=493.9; break; default: printf("\nErrors in music.doc\n"); exit(1); } case'l': /*低音*/<BRTCH(SOUND_HIGH[1]) { case'1': str[i++][0]=131; break; case'2': str[i++][0]=147; break; case'3': str[i++][0]=165; break; case'4': str[i++][0]=176; break; case'5': str[i++][0]=196; break; case'6': str[i++][0]=220; break; case'7': str[i++][0]=247; break; default: printf("\nErrors in music.doc\n"); exit(1); } case'#': if(sound_high[1]=='#')sign=1; break; default: printf("\nErrors in music.doc\n"); exit(1); } } for(j=0;j<=i-1;j++) { sound(str[j][0]); /*按频率发出歌曲的音调*/ delay(50*str[j][1]); } nosound(); /*关闭扬声器*/ } 三 乐谱例:巴赫的《小步舞曲》 600 h2 4 m5 1 m6 1 m7 1 h1 1 h2 4 m5 4 m5 4 h3 4 h1 1 h2 1 h3 1 h4 1 h5 4 m5 4 m5 4 h1 4 h2 1 h1 1 m7 1 m6 1 m7 4 h1 1 m7 1 m6 1 m5 1 m4 4 m5 1 m6 1 m7 1 m5 1 m6 6 l2 1 m1 1 l7 1 l6 1 h2 4 m5 1 m6 1 m7 1 h1 1 h2 4 m5 4 m5 4 h3 4 h1 1 h2 1 h3 1 h4 1 h5 4 m5 4 m5 4 h1 4 h2 1 h1 1 m7 1 m6 1 m7 4 h1 1 m7 1 m6 1 m5 1 m6 4 m7 1 m6 1 m5 1 m4 1 m5 10 ##