PC系列机的发音方法

Author: Date: 1991-12-27

        一、计时器芯片的声音控制
        可编程的计时器芯片是标准PC机发声功能的核心。计时器芯片的通道2是专用于声音产生的。要产生声音,必须对通道2适当编程,并使用通道2发出的脉冲来驱动扬声器。
        通过编程,计时器可以以需要的任何频率发出脉冲,但由于它并不记录声音持续了多长时间,除非把它关上,否则声音便会永远持续下去;所以,程序必须通过一些定时指令来终止发声。
        1、对计时器芯片进行编程
        对计时器的通道2进行编程,给通道2的计数器一个合适的倒计数值(计时器芯片用一个内部寄存器来保存这个值,以便每当计数器倒计数至0时重新设置该计数值)。把倒计数值载入计时器芯片中就立即起作用。在每个1.19318MHz的时钟周期,计时器使此计数器递减,直到递减至0,然后在通道2上输出脉冲到声音产生电路中,并重新开始倒计数。
        事实上,时钟频率被计数值(即:倒计数的初值)除得到输出频率。结果是,如打开扬声器,计时器送出一系列脉冲,产生一定频率的声音。
        控制计数和最终频率有如下公式的相互关系:
        计数值=1193180÷频率
        频率=1193180÷计数值
        可以看出,高计数值可产生低频率的声音,而低计数值可产生高频率的声音。计数值为100,会产生频率大约每秒11931周期的高音,而计数值为10000,则会产生频率大约每秒119周期的低音。
        在16位算术的范围内,几乎可以产生任何频率。在除数(即:分频数)为65535(FFFFH)时产生最低的频率18.2Hz,在除数为1时产生最高的频率1.193MHz。BASIC把实际频率范围控制在37到3276Hz。以下程序表明内部扬声器的实际频率范围甚至比BASIC所提供的还要小。
        一旦你根据所需频率计算出计数值,就可以将它送至计时器通道2的寄存器中。这需做三次向端口的输出。第一次端口输出是向端口43H(67)送值B6H(182),通知计时器即将送来的是计数值。以后的两次输出则向端口42H(66)送一个16位无符号的字的计数值。
        保? COUNT=1193180/3000  '3000是所需的频率
        20  LO.COUNT=COUNT  MOD  256  '计算出低字节值
        30  HL.COUNT=COUNT/256  '计算出高字节值
        40  OUT  &H43,&HB6  '通知计时器准备好
        50  OUT  &H42,&LO.COUNT  '送低位字节
        60  OUT  &HI.COUNT  '送高位字节
        2.激发扬声器
        在对计时器编程后,为使用计时器产生的信号,还需要激发扬声器电路。正象PC和PS/2的许多部分,PC和PS/2通过向某特定的端口送某一值来控制扬声器,这一过程如图1所示。扬声器的启动是由改变61H(97)I/O端口的0位和1位的值来控制的。在该端口的8位中只有两位由扬声器使用:0位和1位。其它6位用于其它方面,所以在使用扬声器时,一定不要去改变他们。CPU
        定时器准备  端口43H  向扬声器发送脉冲
        置频率计数器  端口42H  8253_可编程序定时器  放大器
        打开扬声器  端口61H
        扬声器
        图1  声音频率怎样通过系统计时器和扬声器产生的
        0位,控制计时器芯片的输出信号向扬声器的传送。1位,控制扬声器的脉冲。两位须都置1,扬声器才能对计时器芯片的信号做出反应。可以通过如下操作把这两位置1,而不影响其它位:
        70  OLD.PORT=INP(&H61)? '读端口61H的值
        80  NEW.PORT=(OLD.PORT  OR  &H03)  '置0位和1位
        90  OUT  &H61,NEW.PORT  '打开扬声器
        二、扬声器的直接控制
        计时器通过发送周期性信号来激发扬声器的振动。也可以通过程序直接向扬声器发送信号来实现同样过程,此时要把端口61H(97)的0位置0,将扬声器关上,然后将1位轮流置1和置0以向扬声器发送脉冲。使用这种方法,程序执行得越快,声音频率越高。如下BA_SIC程序给出了这种方法的一个例子:
        10  X=INP(&61)AND  &HFC  '读端口的值,将0位和1位置0
        20  OUT  &H61,X  '压缩扬声器
        30  OUT  &H61,X  OR  2  '扩张扬声器
        40  GOTO  20
        第20行和30行向扬声器发送脉冲,每一步占用半个周期,两步合成一个完整的声音周期。
        这个例子中BASIC以其最快的速度处理程序能发出的最高音调。如晨在应用程序中需要更大的频率范围,可以使用速度更快的语言,并在每个完整的周期(周期时间减半,因为每个开或关操作都仅是半个周期)之间插入一个节拍减半频率周期的延迟时间。无论使用何种语言,都必须有一个持续计数来结束发声。为了以特定的频率发出不同的声音,如“咔嗒”或“蜂鸣”声,只需改变脉冲间的延迟时间。
        尽管有这些美好的可能性,通过直接编程控制扬声器发声并不是产生声音的好办法。与使用计时器相比较,它有三大缺陷:
        ·程序要求不断占用CPU,所以计算机几乎没有时间去做其它工作。
        ·声音频率由计算机的速度决定,亦即同一程序在快慢不同的型号的机器上会发出高低不同的声音。
        ·时钟节拍信号引起的中断会干扰声音的光滑性,产生颤音。解决它的唯一办法是用禁止中断来挂起时钟节拍中断,但这破坏了计算机的时感。
        就我们所知,直接控制产生声音的唯一优点是:使用程序延时的适当控制,控制方法就可产生丰富的复调声音。但须预先提请注意,这种作法要求十分巧妙而烦琐的编程,因而很可能麻烦,不值得这样做。
        三、扬声器的音量和音质
        计算机的内部扬声器无任何音量控制。而且和其它扬声器一样,其音量随频率响应的好坏而变化;有些频率听起来比其它频率声音大。在大多数的PC和PS/2机中,由于扬声器很粗糙,随着频率不同音量差别很大。可用如下程序验证这一点__它可能有助于选择你所要求的最佳音调的频率。
        10  PLAY〃MF〃  '分别发声
        20  FREQUENCY=37
        30  WHILE  FREQUENCY<32000  '使用到32000Hz的所有频率
        40  PRINT  USING〃.〃;FREQUENCY'e显示频率
        50  SOUND  FREQUENCY,5  '以5个单位持续时间发声
        60  FREQUENCY=FREQUENCY1.1  '增加1/10的频率
        70  WEND
        须知在不同的PC和PS/2的机器中,扬声器发出的声音可能不一样。部分原因是作为扬声器附件的共振腔的材料不同。在两种不同型号的机器上,试运行如下例子,并准备听到声音的变化。
        100  '声音例子
        110  '
        120  '颤音(两种声音快速交替)
        130  FOR  N%=0  TO  5
        140  SOUND  440,.7
        150  SOUND  466.16,.5
        160  NEXT
        170  WHILE(INKEY$=〃〃):WEND'等待敲键
        180  '
        190  '快速发出两种音调
        200  SOUND  900,.1
        210  SOUND  760,1
        220  WHILE(INKEY$=〃〃):WEND230  '
        240  '随机噪音
        250  X=INP(&H61)AND  &HFC
        260  I=20
        270  FOR  N%=0  TO  500
        280  IF(RND100<I)THEN  OUT&H61,X  OR2:OUT  &H61,X
        290  NEXT
        附:音乐的八度音程音调的频率
        音调 频 率 音 调 频 率 音 调 频 率 音调 频 率
        C0 16.35 C2 65.41 C4 261.63 C6 1046.50
        C#0 17.32 C#2 69.30 C#4 277.18 C#6 1108.73
        D0 18.35 D2 73.42 D4 293.66 D6 1174.66
        D#0 19.45 D#2 77.78 D#4 311.13 D#6 1244.51
        E0 20.60 E2 82.41 E4 329.63 E6 1328.51
        F0 21.83 F2 87.31 F4 349.23 F6 1396.91
        F#0 23.12 F#2 92.50 F#4 369.99 F#6 1479.98
        G0 24.50 G2 98.00 G4 392.00 G6 1567.98
        G#0 25.96 G#2 103.83 G#4 415.30 G#6 1661.22
        A0 27.50 A2 110.00 A4 440.00 A6 1760.00
        A#0 29.14 A#2 116.54 A#4 466.16 A#6 1864.66
        B0 30.87 B2 123.47 B4 493.88 B6 1975.53
        C1 32.70 C3 130.81 C5 523.25 C7 2093.00
        C#1 34.65 C#3 138.59 C#5 554.37 C#7 2217.46
        D1 36.71 D3 146.83 D5 587.33 D7 2349.32
        D#1 38.89 D#3 155.56 D#5 622.25 D#7 2489.02
        E1 41.20 E3 164.81 E5 659.26 E7 2637.02
        F1 43.65 F3 174.61 F5 659.26 F7 2637.83
        F#1 46.25 F#3 185.00 F#5 739.99 F#7 2959.96
        G1 49.00 G3 196.00 G5 783.99 G7 3135.96
        G#1 51.91 G#3 207.65 G#5 830.61 G#7 3322.44
        A1 55.00 A3 220.00 A5 880.00 A7 3520.00
        A#1 58.27 A#3 233.08 A#5 932.33 A#7 3729.31
        B1 61.74 B3 246.94 B5 987.77 B7 3951.07
        C8 4186.01