说三道四技术文摘-感悟人生的经典句子
说三道四 > 文档快照

让pc speaker美妙动听-Delphi资料

HTML文档下载 WORD文档下载 PDF文档下载
让pc speaker美妙动听-Delphi资料

在个人电脑上没有声卡、操作系统为16位DOS的时代,用PC SPEAKER(主板上的喇叭)发音曾经是唯一的选择。现在,时光已经进入32位的WINDOWS时代,几乎每台电脑上都装有声卡并且输出的声音也几近完美,人们渐渐将PC SPEAKER遗忘……。不过,当我们为了节省能源或不需要操作高品质声音而将音箱关掉时,是否可以请老古董PC SPEAKER 重出江湖,为我们做些有益的事情呢?比如,本人就用DELPHI写了一个让PC SPEAKER奏出不同的音调

模拟海关钟报时的小程序(当然在32位的视窗环境中)。下面就简述其发音原理及源程序的核心部分:

发音原理 : 在16位DOS环境中,用当时流行的开发工具(如FOXBASE,TC等)均能轻而易举地写出让PC SPEAKER发出不同音调的程序,不过在WIN32下,似乎有些小问题:翻遍WINAPI

只能找到唯一的一个能让PC SPEAKER发音的函数―Beep( dwFreq

dwDuration)其中,dwfreq为声音频率,单位为赫兹,dwDuration为声音长度,单位为毫秒。这两个参数仅在WINDOWS NT环境下有效,在WINDOWS 9X 下只能让PC SPEAKER发一声标准的beep音,毫无音调变化。怎么办? 经过努力

本人在网上找到了一个由英国人John Atkins用汇编写的操纵底层资源的发音函数:

function _GetPort(address:word):word;//获取端口

var

bValue: byte;

begin

asm

mov dx

address

in al

dx

mov bValue

al

end;

Result := bValue;

end;

procedure _SetPort(address

Value:Word);//设置端口

var

bValue: byte;

begin

bValue := Trunc(Value and 255);

asm

mov dx

address

mov al

bValue

out dx

al

end;

end;

procedure StartBeep(Freq : Word);//开始发音

Freq为频率

var

B: Byte;

begin

if Freq >18 then

begin

Freq := Word(1193181 div LongInt(Freq));

B := Byte(_GetPort($61));

if (B and 3) = 0 then

begin

_SetPort($61

Word(B or 3));

_SetPort($43

$B6);

end;

_SetPort($42

Freq);

_SetPort($42

Freq shr 8);

end;

end;

procedure StopBeep;//停止发音

var

Value: Word;

begin

value := _GetPort($61) and $FC;

_SetPort($61

Value);

end;

有了上述发音函数后

就可以轻松地写出在win9x环境下让主板喇叭奏乐报时的程序了:在Delphi的IDE环境下

建立一个新的工程

在其缺省的Form上放置一个捕捉整点时间的TTimer构件

取名为Timer1

将该构件的Interval属性设置为100(即0.1秒)

Enabled属性设为True

在该构件的OnTimer事件句柄中键入捕捉整点及奏乐报时的代码就基本上完成了该报时程序.

主要源代码如下:

unit Unit1;

interface

uses

Windows

Messages

SysUtils

Classes

Graphics

Controls

Forms

Dialogs

tdCtrls

ExtCtrls;

type

TForm1 = class(TForm)

Timer1: TTimer;

procedure Timer1Timer(Sender: TObject);

private  procedure BeepFor(Tone : word; MSecs : integer);

procedure SlientFor(MSecs:integer); { Private declarations }

public

{ Public declarations }

end;

var

Form1: TForm1;

function _GetPort(address:word):word;

procedure _SetPort(address

Value:Word);

procedure StartBeep(Freq : Word);

procedure StopBeep;

implementation

{$R *.DFM}

procedure TForm1.BeepFor(Tone : word; MSecs : integer);//发出不同音调及不同时间长度的声音

var

StartTime : LongInt;

begin

StartBeep(Tone);

StartTime:=GetTickCount;

while ( (GetTickCount - StartTime) < LongInt(MSecs) ) do Application.ProcessMessages;

StopBeep;

end;

procedure TForm1.SlientFor( MSecs : integer);//静音若干时间

var

StartTime : LongInt;

begin

StartTime:=GetTickCount;

while ( (GetTickCount - StartTime) < LongInt(MSecs) ) do

Application.ProcessMessages;

end;

procedure TForm1.Timer1Timer(Sender: TObject);

var Hour

Min

Sec

MSec:word;

begin

if Frac(time*24)*3600<0.1 then file://将捕捉整点时间的精度控制在0.1秒内

begin

Timer1.Enabled :=false;

DecodeTime(Time

Hour

Min

Sec

MSec);//将时间解析出小时

毫秒

Beepfor(165

1000); file://以下一段Beepfor语句奏响海关报时乐曲

Beepfor(131

1000);

Beepfor(149

1000);

Beepfor(98

1000);

SlientFor(1000);

Beepfor(98

1000);

Beepfor(149

1000);

Beepfor(165

1000);

Beepfor(131

1000);

SlientFor(1000);

if hour=0 then hour:=24; file://到几点即敲几下钟(零点敲24下)

while hour>0 do

begin

Beepfor(131

1000);

SlientFor(1000);

hour :=hour-1

end;

Timer1.Enabled :=true;

end;

end;

function _GetPort(address:word):word;

var

bValue: byte;

begin

此处代码见前述

end;

procedure _SetPort(address

Value:Word);

var

bValue: byte;

begin

此处代码见前述

end;

procedure StartBeep(Freq : Word);

var

B: Byte;

begin

此处代码见前述

end;

procedure StopBeep;

var

Value: Word;

begin

此处代码见前述

end;

end.

以上代码在win98

Delphi5下通过.

联想王岳源:利用Web App推动互联网转型 IT经理人:提高团队工作效率的11个方法 30美元一小时,数据科学家的收入是否太低? 选择Go语言的12个理由 动鱼数码携三款大作参战Unity游戏及应用大赛 求一SQL语句写法 谁能该我Rose2002的下在地址,我找过好多都不能下载,谢谢!!! 请问如何用程序定时重起电脑? 我的IE首页被一个网站改了。 help me !how to install eclipse on red hat8.0? 提问高手:如何改变ListView中行的高度??? 鸡毛信:这个SQL查询怎么写 "对于不返回任何基表信息的 SelectCommand 不支持动态 SQL 生成"错误如何改正 急!!!!我机子老是跳出来网页来,还有打开一个文件就在桌面上添加几了网页快捷方式! ∫xe^(2√x) dx 上限1下限0 求定积分(1)上限a下限0[(√a-√x)^2]d 设f(x+1)=xe^-x,求∫f(x)dx上限2 ∫xe^-x dx(上限为1,下限为0)= lim→0[∫(上限x,下限0)(1+t^2)e^ lim→0[∫(上限x,下限0)(1+t^2)e^ lim(-xe^x) x→-∞ 求极限lim(-x lim(x→+∞)[∫(上限为x,下限为0)(ar lim(x趋近零)[∫(1+t^2) e^(t^2 义乌打工男子联合女友从其追求者处骗钱穆尔西出庭态度不屑拒受审 埃及部署2500元买了本\"巴基斯坦驾照\" 主城区小区停车日趋紧张 凤起立交边526岁小伙车祸后脑死亡 家属捐出他的452名辽宁省人大代表资格被终止“假蟹”横行西峰下发现失踪者遗体26处老旧公房小区要变样啦首届丝绸之路沿线国家妇女论坛在乌鲁木重生帝国崛起战破蛮荒异界的悠闲生活魔兽之炉石传说神雕之霍都洪崖洞旅游磁器口旅游广州荔枝湾涌旅游中山大学旅游陈家祠旅游
备案号:鲁ICP备13029499号-2 说三道四 www.s3d4.cn 说三道四技术文摘