最新c语言发声程序Word格式.docx
- 文档编号:19987714
- 上传时间:2023-01-13
- 格式:DOCX
- 页数:13
- 大小:20.66KB
最新c语言发声程序Word格式.docx
《最新c语言发声程序Word格式.docx》由会员分享,可在线阅读,更多相关《最新c语言发声程序Word格式.docx(13页珍藏版)》请在冰豆网上搜索。
的门控信号和送数信号是否为1,而它们也可编程,口地址为0x61。
为了不影响8255口地
址61H中的其他高位,应先输入口地址6lH的现有值bits,即用bits=inportb(0x61)来实现,
然后就可用outportb(0x61,bits|3)来允许发声,而用outportb(0x61,bits&
0xfc)来禁止发声,
且不改变8255其它位原来的值,关于这方面的详细内容可以参阅IBMPC/XT接口技术方面
书籍有关内容。
5.1声音函数
编写音乐程序播放歌曲,最简单的方法是可以直接使用TURBOC在dos.h中提供的有
关发声的函数sound()和nosound()。
sound()函数用于产生声音,其原型如下:
voidsound(unsignedfrequency);
该函数的入口参数为扬声器要产生声音的频率。
与sound()函数相反,nosound()函数用于关闭扬声器,其原型为:
voidnosound(void);
该函数没有入口和出口参数,它只是简单地把口地址61H中的低2位清0。
在利用函数sound产生指定频率的声音后,一般要过一段时间后再调用函数nosound关
闭扬声器,这样我们才能清楚地听到一个声音。
如果扬声器刚打开就关闭,我们是很难听到
一个声音的。
某个频率的声音延续时间的长短是重要的,它将直接影响音响效果。
这需要使
用TURBOC提供了专门的延时函数delay,其原型说明如下:
voiddelay(unsignedmilliseconds);
该函数中断程序的执行,中断的时间由milliseconds指定。
例程3-36:
该程序每间隔10000millisecondspc扬声器发出不同频率的声音,直到频率大于
5000hz。
#include<
dos.h>
main()
{
intfreq;
for(freq=50;
freq<
5000;
freq+=50)
{
sound(freq);
delay(10000);
}
nosound();
}
如果不能使用上述现成的函数sound()和nosound(),当然我们也可以采用上节中的方法,
用
I/O
接口的输入输出函数,自己编写产生声音和关闭声音的函数。
下面可供参考的函数
SOUND()与TURBOC提供的产生声音函数sound()的算法类似:
首先函数SOUND()中使用
了一个由一个整数和两个字符组成的联合,其目的在于方便地把一个16位数分解成两个8
位数。
为了打开扬声器,需要把口地址61H的低2位置位,但又不能影响其他高位,为此,
先输入口地址61H中的现有值,与3逻辑或后再输出到口地址61H。
voidSOUND(unsignedfrequency)
union
{
unsigneddivisor;
unsignedcharc[2];
}tone;
/*
定义由—个整数和两个字符组成的联合*/
tone.divisor=119328/frequency;
/*
计算该频率对应的定时器计数值
*/
outportb(0x43,0xb6);
通知定时器采用新的计数*/
outportb(0x42,tone.c[0]);
/*计数低字节先送到定时器*/
outportb(0x42,tone.c[1]);
计数高字节后送到定时器*/
outportb(0x61,inportb(0x61)|3);
使定时器到喇叭的输出有效
如下供参考的函数NOSOUND(),为了不影响口地址61H中的其他高位,应先输入口地
址6lH的现有值.在屏蔽掉低2位后再输出到口地址61H。
voidNOSOUND(void)
outportb(0x61,inportb(0x61)&
0xfc));
使定时器到喇叭的输出无效
*/
5.2计算机乐谱
表3-18是频率与音阶的对照表。
我们可以通过该表编制出自己的驱动程序。
编制乐谱
程序一般在原乐谱的基础上添加一些控制字符来完成。
如:
。
。
_11176323262
就是孟庭苇演唱的“羞答答的玫瑰静俏俏地开”的第一句歌词的乐谱。
在计算机中可以表述为:
600H10.5H10.5H10.5M70.5M61H31H20.5H30.5H20.5M60.5H22
第一个为音长基准,一般为300,600,900,1200。
后面字H1表示高音的1,音阶的
设置如下:
最高音:
在音符前加“E”;
高音:
在音符前加“计”;
中音:
在音符前加“M”;
低音:
在音符前加“L”;
再后面的字为节拍数,其中的0.5表示节拍数,每个音的音长=音长基数×
\u33410X拍数,如
第一个“1”的音长为600×
0.5=300。
表3-18频率与音阶的对照表
低音
1
2
3
4
5
6
7
频率
131
147
165
176
196
220
247
中音
262
296
330
349
392
440
494
高音
523
587
659
699
784
880
988
最高音
1047
1175
1319
1397
1568
1760
1976
知道了这些知识,就容易编制—个乐谱驱动程序。
思路是将各个频率存储在一个二维数
组中,根据音阶字符、音符和节拍数,得到发音的音长,使用sound函数发音,使用delay
函数控制。
5.3问题实现
5.3.1
调用sound()和unsound()
下面的程序(例程3-37)先开辟两个数组freq[96]和dely[96]分别用于存储声音的频
率和延时。
采用图形方式,利用printtext()函数在屏幕上分别显示字符串Welcome!
"
,"
Please
pressanykeytostart......"
Enjoyyourself!
”,"
Pressanykeytoend!
和
"
Thankyou!
Bye
Bye......"
printtext()定义如下:
voidprinttext(unsignedchar*temp[],inti)
setcolor(4);
//设置颜色为red
settextstyle(TRIPLEX_FONT,HORIZ_DIR,3);
//设置字符的字体,方向和大小
outtextxy(100,40+i*50,temp[i]);
//显示字符串
另外,在此程序中还调用了conio.h
中的函数kbhit(),用于判断是否有键按下,当没有键按下
时返回0。
/*例程3-37*/
graphics.h>
voidprinttext(unsignedchar*temp[],inti);
//
用于在屏幕上显示字符串
inti,graphdriver,graphmode;
unsignedchar*temp[4];
intfreq[96]={784,660,588,660,523,523,
588,494,440,523,392,392,
330,392,440,523,784,440,523,392,
784,1048,880,784,660,784,588,588,
588,660,494,440,392,440,523,588,
330,523,440,392,440,523,392,392,
660,784,494,588,440,523,392,392,
330,392,330,392,392,440,494,588,440,440,392,440,
523,588,784,660,588,660,588,523,440,392,
330,523,440,523,440,392,330,392,440,523,
392,392,660,784,588,660,588,523,494,440,784,784};
intdely[96]={25,50,12,12,50,50,
25,50,12,12,50,50,
50,38,12,38,12,12,12,25,
38,12,12,12,12,12,50,50,
38,12,25,25,38,12,25,25,
25,25,12,12,12,12,50,50,
38,12,25,25,12,12,50,25,
12,12,12,12,12,12,12,12,50,25,12,12,
38,12,25,25,25,12,12,25,12,12,
50,50,12,12,12,12,12,12,12,12,
50,25,12,12,12,12,12,12,25,25,50,50};
graphdriver=DETECT;
graphmode=0;
temp[0]="
Welcome!
;
temp[1]="
Pleasepressanykeytostart......"
temp[2]="
temp[3]="
temp[4]="
ByeBye......"
initgraph(&
graphdriver,&
graphmode,"
);
//系统初始化
cleardevice();
//清除屏幕
settextjustify(LEFT_TEXT,CENTER_TEXT);
//设置字符排列方式
for(i=0;
i<
2;
i++)
printtext(temp,i);
getch();
for(i=2;
4;
i=0;
while(i<
96&
&
!
kbhit())
{
sound(freq[i]);
扬声器根据频率发声
delay(1100*dely[i]);
声音延时
i++;
//
关闭扬声器
printtext(temp,4);
closegraph();
关闭图形模式
}
设置颜色
设置字符的字体,方向和大小
//在所指定的坐标出显示字符串
5.3.2
调用inportb()和outportb()
这个程序(例程3-38)利用3.5.2节的SOUND()和UNSOUND()改写前一实现,播放一段不同
的曲目。
/*例程3-38*/
voidSOUND(unsignedfrequency);
voidNOSOUND(void);
inti,graphdriver,graphmode;
intfreq[87]={196,262,262,262,330,294,262,294,330,294,262,
330,394,440,440,394,330,330,262,294,262,294,
330,294,262,230,230,196,262,440,394,330,330,
262,294,262,294,440,394,330,330,394,440,523,
394,330,330,262,294,262,294,330,294,262,230,
230,196,262,440,394,330,330,262,294,262,294,
440,394,330,330,394,440,523,394,330,330,262,
294,262,294,330,294,262,230,230,196,262};
intdely[87]={25,38,12,25,25,38,12,25,12,12,56,25,25,50,25,
38,12,12,12,38,12,25,12,12,38,12,25,25,100,25,
38,12,12,12,38,12,25,25,38,12,25,25,100,25,38,
12,12,12,38,12,25,12,12,38,12,25,25,100,25,38,
12,12,12,38,12,25,25,38,12,25,25,100,25,38,12,
12,12,38,12,25,12,12,38,12,25,25,100
graphdriver=DETECT;
87&
SOUND(freq[i]);
NOSOUND();
union
{
/*定义由-个整数和两个字符组成的联合*/
unsignedcharc[2];
tone.divisor=119328L/frequency;
计算该频率对应的定时器计数值
outportb(0x43,0xb6);
outportb(0x42,tone.c[0]);
计数低字节先送到定时器*/
outportb(0x42,tone.c[1]);
outportb(0x61,inportb(0x61)|3);
outportb(0x61,(inportb(0x61)&
使定时器到喇叭的输出无效
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 最新 语言 发声 程序