📄 8-11.c
字号:
#include"stdio.h"
#include"dos.h"
/*低音区7个音符的对应频率*/
#define LC 131
#define LD 147
#define LE 165
#define LF 175
#define LG 196
#define LA 220
#define LB 247
/*中音区7个音符的对应频率*/
#define MC 262
#define MD 296
#define ME 330
#define MF 349
#define MG 392
#define MA 440
#define MB 494
/*高音区7个音符的对应频率*/
#define HC 523
#define HD 587
#define HE 659
#define HF 698
#define HG 784
#define HA 880
#define HB 988
/*比上述高音区高八度的C音对应的频率*/
#define HHC 1035
/*休止音符对应的频率为0*/
#define PAUSE 0
#define Canon_MinDelay 25000 /*《卡农》的基本延时值*/
#define Hudiefei_MinDelay 30000 /*《蝴蝶飞呀》的基本延时值*/
void interrupt(*oldint)(); /*用来获取原中断服务程序的远地址指针值*/
void interrupt music(); /*用户定义的新的中断服务函数*/
static int count=0; /*用来记录用户按Ctrl+Break键的奇偶次数*/
unsigned Canon_Tone[57]= /*《卡农》的57个音符对应的频率值*/
{ /*每行代表一小节的音符,以下同*/
HG,HE,HF,HG,HE,HF,
HG,MG,MA,MB,HC,HD,HE,HF,
HE,HC,HD,HE,ME,MF,
MG,MA,MG,MF,MG,ME,MF,MG,
MF,MA,MG,MF,ME,MD,
ME,MD,MC,MD,ME,MF,MG,MA,
MF,MA,MG,MA,MB,HC,
MG,MA,MB,HC,HD,HE,HF,HG,
HC
};
int Canon_TLength[57]= /*《卡农》的57个音符对应的音长值*/
{
8,4,4,8,4,4,
4,4,4,4,4,4,4,4,
8,4,4,8,4,4,
4,4,4,4,4,4,4,4,
8,4,4,8,4,4,
4,4,4,4,4,4,4,4,
8,4,4,8,4,4,
4,4,4,4,4,4,4,4,
24
};
unsigned Hudiefei_Tone[124]= /*《蝴蝶飞呀》前段部分的124个音符对应的频率值*/
{
/*第一小段*/
HE,HE,HE,HE,
HF,HE,HD,HC,MG,
MA,HC,HC,HC,HD,
HC,PAUSE,
HE,HG,HG,HG,
HA,HG,HE,HD,HC,
HD,HD,HD,HE,
HD,PAUSE,
HD,HC,HC,HC,
HHC,HHC,HHC,HHC,HA,
HA,HG,HG,HG,HD,HC,HD,HE,
PAUSE,HD,HC,
HD,HE,HD,HC,
HD,HE,HE,HA,HE,HG,
PAUSE,
/*第二段*/
HE,HE,HE,HE,
HF,HE,HD,HC,MG,
MA,HC,HC,HC,HD,
HC,PAUSE,
HE,HG,HG,HG,
HA,HG,HE,HD,HC,
HD,HD,HD,HE,
HD,PAUSE,
HD,HC,HC,HC,
HHC,HHC,HHC,HHC,HA,
HA,HG,HG,HG,HD,HC,HD,HE,
PAUSE,HD,HC,
HD,HE,HD,HE,
HG,HE,HD,HC,MA,HC,
PAUSE
};
int Hudiefei_TLength[124]= /*《蝴蝶飞呀》前段部分的124个音符对应的音长值*/
{
/*第一小段*/
4,12,8,8,
8,8,4,8,4,
4,8,4,4,12,
24,8,
4,12,8,8,
8,8,4,8,4,
8,8,4,12,
24,8,
8,4,12,8,
4,4,4,12,8,
4,4,4,4,4,4,4,20,
8,4,4,
8,4,12,8,
8,4,4,8,4,52,
16,
/*第二小段*/
4,12,8,8,
8,8,4,8,4,
4,8,4,4,12,
24,8,
4,12,8,8,
8,8,4,8,4,
8,8,4,12,
24,8,
8,4,12,8,
4,4,4,12,8,
4,4,4,4,4,4,4,20,
8,4,4,
8,4,12,8,
8,8,4,4,4,36,
16
};
main()
{
oldint=getvect(0x1B); /*获得原0x1B号中断服务程序的远地址指针*/
disable(); /*关闭中断*/
setvect(0x1B,music); /*设置新的0x1B号中断服务函数*/
enable(); /*开放中断*/
keep(0,255); /*退出程序并使程序驻留内存*/
}
void interrupt music()
{
int i,j;
unsigned char bits;
clrscr();
count=(count+1)%2;
if(count==1) /*如果按键次数为奇数,则演奏《卡农》*/
{
for(i=0;i<57;i++)
{
outportb(0x43,0xb6);
/*如果当前音符为休止符,则其值不做处理,以免引起除零错误*/
if(Canon_Tone[i]==0);
else
Canon_Tone[i]=0x1234dc/Canon_Tone[i];
outportb(0x42,Canon_Tone[i] & 0x00ff);
Canon_Tone[i]=Canon_Tone[i]>>8;
outportb(0x42,Canon_Tone[i]);
bits=inportb(0x61);
outportb(0x61,bits | 3);
for(j=0;j<Canon_TLength[i];j++)
delay(Canon_MinDelay);
outportb(0x61,bits & 0xfc);
/*sound(Canon_Tone[i]);
for(j=0;j<Canon_TLength[i];j++)
delay(Canon_MinDelay);
nosound();*/
}
}
else /*如果按键次数为偶数,则演奏《蝴蝶飞呀》前段部分*/
{
for(i=0;i<124;i++)
{
outportb(0x43,0xb6);
/*如果当前音符为休止符,则其值不做处理,以免引起除零错误*/
if(Hudiefei_Tone[i]==0);
else
Hudiefei_Tone[i]=0x1234dc/Hudiefei_Tone[i];
outportb(0x42,Hudiefei_Tone[i] & 0x00ff);
Hudiefei_Tone[i]=Hudiefei_Tone[i]>>8;
outportb(0x42,Hudiefei_Tone[i]);
bits=inportb(0x61);
outportb(0x61,bits | 3);
for(j=0;j<Hudiefei_TLength[i];j++)
delay(Hudiefei_MinDelay);
outportb(0x61,bits & 0xfc);
/*sound(Hudiefei_Tone[i]);
for(j=0;j<Hudiefei_TLength[i];j++)
delay(Hudiefei_MinDelay);
nosound();*/
}
}
oldint();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -