如何使 Speaker 发声?(API函数),beep好像不行。(30分)

  • 主题发起人 主题发起人 lixx
  • 开始时间 开始时间
L

lixx

Unregistered / Unconfirmed
GUEST, unregistred user!
根据MSDN的说法,如果机器上有声卡,则……
我在TC下用beep函数可以发声,但是在VC下用::Beep(Freq,Duration)就不行了.
不知各位有没有办法?
 
用windows.beep就可以了
 
delphi中是beep
 
你用speaker到google上找,有控件
 
由于我是在VC下想达到 Speaker 发声所以想找个 API 函数,
还请各位帮忙。
 
我在网上搜了一下,发现在Windows9.x下让扬声器发出不同频率的声音好像不是很简单。
(我是指用VC,Delphi我没试好像也不行。)
在Win32平台下(9X)下控制Speaker似乎不是那么简单。
 
我也在研究BEEP但我要求的是奏乐!
我曾经找到一控件,他提供了一种发声方式(控件代码见后文)
PLAY(XXX,XXX);
OR
DOBLEEP(XXX,XXX);
但如果用这个去拼首歌就太…………
而且根本不知道XXX是哪个音……

BLEEP只可以在9X下用
以下为控件代码
Unit BleepInt; { Version 4.2 }

{ Andy Preston - Apollo Developments, Swindon U.K. andy@apollod.freeserve.co.uk

HACKERS OF THE WORLD UNITE! HACKERS OF THE WORLD UNITE! HACKERS OF THE WORLD UNITE! HACKERS OF THE WORLD UNITE!

How to make your Delphi programs bleep like FRACTINT! See Demo1.pas/Demo1.dfm or Bleepint.htm for details
}

Interface

Type
TBleepType = (bOK, bInterrupt, bError);

Procedure ShutUp; { Added to help counter the effects of DoBleep (Freq, -1).
If you are producing a tone, & you want to stop without doing another Bleep, call this procedure }

Procedure DoBleep (Freq : Word; MSecs : Integer); { Duration of -1 means bleep until the next bleep sent, or ShutUp is called }

Procedure Bleep (BleepType : TBleepType);

Implementation

Uses
{$IFDEF WIN32} Windows, {$ELSE} WinProcs, {$ENDIF}
{$IFNDEF CONSOLE} Forms; {$ENDIF} { Michl Ladislav suggested removing the Forms unit from 32-bit Console Apps, saving 130K }


{ -- --- -- --- -- --- -- --- -- --- -- --- -- --- Assembler Bits for Wind 3.x And '95 -- --- -- --- -- --- -- --- -- --- }

Procedure AsmShutUp; {$IFDEF WIN32} Pascal; {$ENDIF}
Begin
Asm
In AL, $61 { Stop Bleeping }
And AL, $FC
Out $61, AL
End;
End;

Procedure AsmBeep (Freq : Word); {$IFDEF WIN32} Pascal; {$ENDIF}
Label
Skip;
Begin
Asm
Push BX
In AL, $61
Mov BL, AL
And AL, 3
Jne Skip
Mov AL, BL
Or AL, 3
Out $61, AL
Mov AL, $B6
Out $43, AL
Skip: Mov AX, Freq
Out $42, AL
Mov AL, AH
Out $42, AL
Pop BX
End;
End;

{ -- --- -- --- -- --- -- --- -- --- -- --- -- --- Low Level Bits for Wind 3.x And '95 -- --- -- --- -- --- -- --- -- --- }

Procedure HardBleep (Freq : Word; MSecs : Integer);
Var
{ Changed FirstTickCount from LongInt to DWord to counter P.Satyanarayana's Delphi 4 Warning - see below }
FirstTickCount : {$IFDEF WIN32} DWord {$ELSE} LongInt {$ENDIF};
Begin
{ Michl Ladislav pointed out that having a delay when the bleep freq is out of range is a waste of 'stuff' so I've added
another BEGIN END }
If (Freq>=20) And (Freq<=5000) Then Begin
AsmBeep (Word (1193181 Div LongInt(Freq)));
If MSecs>=0 Then Begin
{ P.Satyanarayana Get's a warning under Delphi 4 here 'Comparing signed and unsigned types - widened both operands'
This should be cleared up by the fact that FirstTickCount is now a DWord under Win32 }
FirstTickCount:=GetTickCount;
{ Michl Ladislav suggested changing the old WHILE DO to a REPEAT UNTIL so as to fit his modifications in easyer }
Repeat
{ Michl Ladislav suggested removing the Forms unit from 32-bit Console Apps, saving 130K }
{$IFNDEF CONSOLE} If MSecs>1000 Then Application.ProcessMessages; {$ENDIF}
Until ((GetTickCount-FirstTickCount)>LongInt(MSecs));
AsmShutUp;
End;
End;
End;

{ -- --- -- --- -- --- -- --- -- --- -- --- -- --- -- --- Procedures for you to use -- --- -- --- -- --- -- --- -- --- -- --- }

Procedure Bleep (BleepType : TBleepType);
Begin
Case BleepType of
bOK: Begin
DoBleep (1047,100);
DoBleep (1109,100);
DoBleep (1175,100);
End;
bInterrupt: Begin
DoBleep (2093,100);
DoBleep (1976,100);
DoBleep (1857,100);
End;
bError: DoBleep (40,500);
End;
End;

{$IFDEF WIN32} Var SysWinNT : Boolean; {$ENDIF}

Procedure DoBleep (Freq : Word; MSecs : Integer);
Begin
{$IFDEF WIN32} If SysWinNT Then Windows.Beep (Freq, MSecs) Else {$ENDIF}
HardBleep (Freq, MSecs);
End;

Procedure ShutUp;
Begin
{$IFDEF WIN32} If SysWinNT Then Windows.Beep (1, 0) Else {$ENDIF}
AsmShutUp;
End;

{$IFDEF WIN32}

Procedure InitSysType;
Var
VersionInfo : TOSVersionInfo;
Begin
VersionInfo.dwOSVersionInfoSize:=SizeOf (VersionInfo);
GetVersionEx (VersionInfo);
SysWinNt:=VersionInfo.dwPlatformID=VER_PLATFORM_WIN32_NT;
End;

Initialization
InitSysType;

{$ENDIF}

End.
 
procedure TMainForm.sound(mhz: integer);
{mhz = the frequency of the pc speaker
PC喇叭发声,只适用于Win9X}
var
count : word;
begin
try
count := 1193280 div mhz;
asm
mov al,$b6
out $43,al
mov ax,count
out $42,al
mov al,ah
out $42,al
mov al,3
out $61,al
end;
except
;
end;
end;

procedure TMainForm.nosound;
{turn off the pc speaker
关闭PC喇叭,只适用于Win9X}
begin
asm
mov al,0
out $61,al
end;
end;

//Windows 2000下发声
windows.beep(50, 100); //50是频率,100是100毫秒,可以自定义
//NT底下不知道如何让喇叭发声,谁知道告诉我一声
 
现在已经可以让PC speaker发声了,可是我发现音量特别小,
怎么把Speaker的音量调大呢?
 
》yuuh
你这个方法可真……,还有没有别的方法?
 
只能采用嵌入汇编的方法,没有直接的api。
 
试试我上面贴的:
sound(1000);//自已调参数以达到满意的效果
 
》wind2000
你的方法可以,但是就是音量太小,失去了响的意义……
有没有方法让音量大点,因为我在别人的一台机器上感觉Speaker要比我的机器上响的多,
不知编程可不可以达到这种效果?
 
beep在有声卡时用声卡发声,无声卡就用喇叭
 
多人接受答案了。
 
后退
顶部