我在delphi中调用MMSystem Unit 下的 playSound函数来播放声音文件
通过循环来读出数字,例如12.5,连续播放内容为“壹”、“拾”、“贰”、“点”,“伍",五个声音文件,
但需要在播放每个声音文件后延时,否则就只能听到最后一个声音文件的内容,
我使用的是sleep()函数来延时
但问题是,使用sleep后,程序在播放声音文件时,会出现假死现象,即软件暂时对用户的操作没有反应,即使调用TTread对象使用了多线程也是不行。
请教大家该如何处理这个问题。
谢谢!
通过循环来读出数字,例如12.5,连续播放内容为“壹”、“拾”、“贰”、“点”,“伍",五个声音文件,
但需要在播放每个声音文件后延时,否则就只能听到最后一个声音文件的内容,
我使用的是sleep()函数来延时
但问题是,使用sleep后,程序在播放声音文件时,会出现假死现象,即软件暂时对用户的操作没有反应,即使调用TTread对象使用了多线程也是不行。
请教大家该如何处理这个问题。
谢谢!
解决方案 »
- 我把编译生成的dll文件放在web服务器指定的目录,然后输入localhost/web/Tableex.dll/TestTable 按回车,为什么没有出来结果?
- 用API写的com port实例, 但只有数据量达到256时getoverlappedresult才正常返回
- 关于TSpeedButton在D2009和delphi之前的一个区别。
- <<老问题了,socket 10054 远程主机强迫关闭连接>>
- idhttp怎么捕捉网页跳转后的真实地址
- 如何将一个字符串映射为一个Delphi页面控件属性名
- 怎么使用treeview控件?
- 为什么只能打印一个记录?
- 如何能成为一个真正的程序员???帮帮我吧!!
- 用ado 如何連接 excel files
- 对象成员.....
- 为什么我的delphi7的TWebBrowser控件没有OnGetExternal事件?
另外,sleep最好不要用,会阻塞线程。
T123; 则发声 一百二十三小数点没做,有兴趣自已加上去
unit SoundU;interface
uses
Classes,SysUtils,Windows,Mmsystem,Forms;
type
TLanguage = (lgChinese,lgGuangDong,lgDouble);
TSoundQueue = class(TThread)
private
FLanguage: TLanguage; //发声类型: 普通话、广州话、普通话+广州话
FQueue: TStringList;
FEnable: Boolean; //是否允许发声
FSoundDir: String;
FCurrentPath: String;
protected
procedure Execute; override;
procedure Play(sCMD: String);
public
constructor Create;
destructor Destroy;override;
procedure Append(SoundStr:String); //在发声队列中增加一发命令串
procedure Clear; //清除发声队列
function Count: Integer; //发声队列中未处理记录
property Enable: Boolean read FEnable write FEnable; //是否需要发音
property CurrentPath: String read FCurrentPath write FCurrentPath; //默认路径
property Language: TLanguage read FLanguage write FLanguage; //发音方式
end;implementation
{ TSoundQueue }procedure TSoundQueue.Append(SoundStr: String);
begin
if (Trim(SoundStr) <> '') AND FEnable then
FQueue.Append(SoundStr);
Resume;
end;procedure TSoundQueue.Clear;
begin
FQueue.Clear;
end;function TSoundQueue.Count: Integer;
begin
Result := FQueue.Count;
end;constructor TSoundQueue.Create;
begin
FQueue := TStringList.Create;
FEnable := True;
FCurrentPath := ExtractFilePath(Application.ExeName);
inherited Create(True);
end;destructor TSoundQueue.Destroy;
begin
FQueue.Free;
inherited;
end;procedure TSoundQueue.Execute;
var
sSoundCMD: String;
begin
while Not Terminated do
begin
if FQueue.Count > 0 then //如果有发声队列
begin
try
sSoundCMD := FQueue.Strings[0]; //从队首部取发声指令字串
FQueue.Delete(0);
finally
end;
end
else
sSoundCMD := '';
try
case FLanguage of
lgChinese: //普通话发音
begin
FSoundDir := 'Sound1';
if FEnable then
Play(sSoundCMD);
end;
lgGuangDong: //广州话发音
begin
FSoundDir := 'Sound2';
if FEnable then
Play(sSoundCMD);
end;
lgDouble: //普通话 + 广州话 发音
begin
FSoundDir := 'Sound1';
if FEnable then
Play(sSoundCMD);
FSoundDir := 'Sound2';
if FEnable then
Play(sSoundCMD);
end;
end;
except
// WriteErrorLog('发声过程错');
end;{End try}
if FQueue.Count <= 0 then
Suspend; //无发声队列挂起
end;{End while}
end;
procedure TSoundQueue.Play(sCMD: String);
var
sSoundPath: String;
ii: integer;
s1,s2: string; procedure ExecCMD(OneAction: String); //解析发声批令字串
const
sSound = ' 十百千万十百千亿十百千万亿';
var
s3,s4: String;
lp1,lp2: integer;
begin
if OneAction = '' then Exit;
try
case OneAction[1] of
'L','l': //指定以应用程序主目录为起始 的wav文件相对路径 该路径在本指令串内生效 :Loaction
begin
FSoundDir := Trim(Copy(OneAction,2,MAXWORD));
sSoundPath := FCurrentPath + FSoundDir;
end;
'V','v': //播放sSoundPath目录指定wav文件 :Voice
begin
if Length(Trim(OneAction)) = 1 then Exit;
s3 := sSoundPath + '\' + Trim(Copy(OneAction,2,MAXWORD)) + '.wav';
PlaySound(Pchar(s3),0,SND_FILENAME + SND_SYNC);
end;
'S','s': //播放指定数字串单字发音不带单位 :String
begin
s4 := '';
s3 := Trim(Copy(OneAction,2,MAXWORD));
for lp1 := 1 to Length(s3) do
s4 := s4 + 'V' + s3[lp1] + ';' ;
Play(s4);
end;
'M','m':
case OneAction[2] of
'1': ;
'2': ;
'3': ;
end;
'T','t': //播放指定整数 带单位 -- 部分效果有待完善 :Talk
begin
s3 := Trim(Copy(OneAction,2,MAXWORD));
if s3 = '' then Exit;
if StrToInt(s3) <> 0 then
if (StrToInt(s3) >= 10) And (StrToInt(s3) < 20) then //解决发十号音问题
begin
s4 := s4 + 'V十;V';
if s3[2] <> '0' then s4 := s4 + s3[2] + ';';
end
else
begin
lp2 := Length(s3);
for lp1 := Length(s3) downto 1 do
if s3[lp1] = '0' then
s3[lp1] := #$20
else
Break;
for lp1 := 1 to Length(s3) do
begin
if (s3[lp1] = '0') or (s3[lp1] = #$20) then
s4 := s4 + 'V' + s3[lp1] + ';'
else
s4 := s4 + 'V' + s3[lp1] + ';V' + sSound[lp2*2 - 1] + sSound[lp2*2] + ';';
lp2 := lp2 - 1;
end;{End for}
end{End if then}
else s4 := 'V0';
Play(s4);
end;
end;{End Case}
except
// Raise;
end;{End try}
end;
begin
sSoundPath := FCurrentPath + FSoundDir;
s1 := Trim(sCMD);
ii := Pos(';',s1);
while ii <> 0 do
begin
s2 := Trim(Copy(s1,1,ii-1));
ExecCMD(s2);
s1 := Trim(Copy(s1,ii+1,MAXWORD-1));
ii := Pos(';',s1);
end;
if s1 <> '' then ExecCMD(s1);
end;
end.
playSound(pchar(strFileName),0,SND_FILENAME + SND_SYNC);
但,在播放时,资源被独占了,鼠标点击其它菜单是没有反应
如这样:
function ThreadProc(Param: Pointer): Integer;
begin
PlaySound(PChar(strFileName), 0, SND_FILENAME + SND_SYNC);
end;procedure TForm1.FormCreate(Sender: TObject);
var
ThreadId: Cardinal;
begin
BeginThread(nil, 0, ThreadProc, 0, 0, ThreadId);
end;