随着计算机软件的商品化,界面技术越来越重要,如果能在编制的软件中加上一段熟悉的音乐,可使软件更受欢迎。
Turbo C/Turbo C++/Borland C++支持音乐程序设计的函数为:
函数原型:Void Sound(unsigned frequency)
说明:Sound()函数以指定频率打开PC机的扬声器,频率以赫兹为单位。若想关闭杨收器,可用nosound()函数。
1.乐谱文件的制作
编写音乐程序时,首先需要制作被演奏音乐的乐谱文件。制作乐谱文件可用不同的符号标记,只要所编制的程序易于识别即可。
下面是编制乐谱文件的一种规则:最高音在每个音的前面加“*”;高音,在每个音的前面加“h”;中音,在每个音的前面加“m”;低音,在每个音的前面加“L”。“*”、“h”、“m”、“L”与其控制的音符构成高音,决定发生频率。高音的后面是音长,可用整数或小数输入,以控制延时,但中间必须用空格分开。乐谱文件的最前端是一个整数,表示音长基数,一般为300、600、900、1200。乐谱文件的最末端是乐谱文件结束符“##”,以表示乐谱文件 结束。
下面是电影《城南旧事》插曲《送别》的一段:
5 35 -|6 6 5-|5 12 3 21|2—
制成乐谱文件为:
600 m5 1 m3 0.5 m5 0.5 h1 2 m6 1 h1 0.5 m6 0.5 m5 2 m5 1 m1 0.5 m2 0.5 m3 1 m2 0.5 m2 3 ##
每个音的音长=音长基数*节拍数,其中,音长基数是乐谱文件的第一个字符,如上面乐谱文件为600,每个音的音频可用以模拟频率值输入。下面的表是中央C及其前后4个8度中各个音符的频率值。
1 131 1 262 523.3 1046.5
2 147 2 296 587.3 1174.7
3 165 3 329.7 659.3 1318.5
4 176 4 349.2 698.3 1396.9
5 196 5 392 784.0 1568.0
6 220 6 440 880 1760
7 247 7 493.9 987.8 1975.5
2.源代码
下面是音乐程序的源代码,编译、连接成可执行文件music.exe,用法为:music乐谱文件。
#include <stdlib.h>
#include <stdio.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[100][2];
if(argc!=2)//命令行参数个数不正确
{
printf(“Parameters Error!
“);
exit(1);
}
if((fp=fopen(argv[1],”r”))==NULL)//问件打开失败
{
printf(“Open file music .doc Errors!
“);
exit(1);
}
fscanf(fp,”%d”,&rate);//读取音长基数的值
while(!feof(fp)&&!sign)//文件没有结束并且数据还是乐谱
{
fscanf(fp,”%s%f”,sound_high,&sound_long)//得到音频、音长的数值
str[i][1] = rate*sound_long;//音长=音长基数*节拍数
switch(sound_high[0])
{
case '*'://最高音
switch(sound_high[1])//确定发声的频率
{
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(”
Errors in music.doc
“);
exit(1);
}
break;
case 'h'://高音
switch(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(”
Errors in music.doc
“);
exit(1);
}
break;
case 'm'://中音
switch(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(”
Errors in music.doc
“);
exit(1);
}
break;
case 'l'://中音
switch(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(”
Errors in music.doc
“);
exit(1);
}
break;
case '#':
if(sound_high[1]=='#')
{
sign = 1;
}
break;
default:
printf(”
Errors in music.doc
“);
exit(1);
}
}
for(j=0;j<=i-1;j++)
{
sound(str[j][0]); //按频率值发出歌曲的音调
delay(str[j][1]);
}
nosound();//关闭扬声器
}