📄 myclass.pas
字号:
//如果完成了包括三催在内的呼叫任务,那么清除晚点时间,同时清除联叫房间
if(CurState=csCalled) then begin
ClrDelayTime:=true;
end;
end;
//修改数据库状态
EnterCriticalSection(Critical1); //进入临界段
try
case(CurState)of
csReady: CurRecord.nState:=0;
csWaitSecond: CurRecord.nState:=1;
csCalled: CurRecord.nState:=2;
csWaitFirst: CurRecord.nState:=3;
end;
if(CurRecord.nState<>tbPlan2.FieldByName('状态').AsInteger) then begin
tbPlan2.Edit;
tbPlan2.FieldByName('状态').AsInteger:=CurRecord.nState;
//清除晚点时间与联叫房号
if(ClrDelayTime)then begin
tbPlan2.FieldByName('晚点时间').AsInteger:=0;
tbPlan2.FieldByName('联叫房号').AsString:='';
tbPlan2.FieldByName('房间号码').AsString:=' ';
end;
tbPlan2.Post;
//refresh display
sleep(100);
tbPlan.Refresh;
end;
except
end;
LeaveCriticalSection(Critical1);//退出临界段
tbPlan2.Next;
end; //of while(not tbPlan2.eof
end; //of if (SleepCnt>3)
//检查催叫队列,如果需要催叫,则执行催叫功能
i:=0;
if (RecallNum>0)and(Now-RecallQ[0].time>0) then begin
//检查链路状态,如果电话占线,则不能呼叫
LineState:=Inp32($379)and $30;
if(LineState=$30) then begin //录音电话未工作,线路可用
//开始呼叫
LineBusy:=true; //线路忙
Status.Text:='正在自动催叫'+RecallQ[0].Room+'房间';
//打开链路
OpenLink(RecallQ[0].line,lsAutoCall);
//播放几秒钟的音乐
begin
Player.FileName:=RootDir+'\叫班音乐.wav';
try
Player.Open;
Player.Play;
for j:=0 to 10*10-1 do begin //最长等待10s
if(Player.Position=Player.Length) then
Break
else
sleep(100);
end;
Player.Stop;
Player.Close;
except
showmessage(Player.ErrorMessage);
end;
end;
//播放音频
KeyAcknowledged:=false; //清除按键状态,准备检测新的键盘操作
begin
RecallQ[0].ActualFirstCall:=Now;
//if(SysSet.AutoCallEnabled) then //启动了自动呼叫
Player.FileName:=RootDir+'\自动催叫.wav';
//else //没启动自动呼叫,仅提示
// Player.FileName:=RootDir+'\催叫提示.wav';
try
Player.Open;
Player.Play;
for j:=0 to 20*10-1 do begin //最长等待20s
if(Player.Position=Player.Length) then
Break
else
sleep(100);
end;
Player.Stop;
Player.Close;
except
showmessage(Player.ErrorMessage);
end;
end;
//until (KeyAcknowledged or SysSet.AutoCallEnabled);
//等待房间回话
Status.Text:='等待'+RecallQ[i].Room+'房间回话';
//打开链路,记录8秒的录音
OpenLink(RecallQ[i].line,lsRecord);
StartWaveRecord(GetWaveName(RecallQ[i].ActualFirstCall));
sleep(8000); //延迟8秒
StopWaveRecord;
//此次自动呼叫结束
Status.Text:='';
//呼叫完毕,转换到待用状态
OpenLink(RecallQ[i].line,lsReady);
LineBusy:=false; //取消线路忙
//添加叫班记录,如果超出了最大个数,那么删除首记录
if(tbCall.RecordCount>=SysSet.MaxAutoWaveNum) then begin
try
tbCall.Last;
tbCall.Prior;
if(FileExists(GetWaveName(tbCall.FieldByName('实际一叫时间').AsDateTime))) then
DeleteWaveFile(GetWaveName(tbCall.FieldByName('实际一叫时间').AsDateTime));
tbCall.Delete;
except
end;
end;
tbCall.AppendRecord([RecallQ[i].Room,RecallQ[i].Train,
'00:00',RecallQ[i].PlanFirstCall,RecallQ[i].ActualFirstCall,'催叫']);
//删除当前呼叫队列项
for j:=0 to RecallNum-2 do
RecallQ[j]:=RecallQ[j+1];
RecallNum:=RecallNum-1;
end;
end;
//检查录音电话状态,如果占线,则分配一个线路,然后开始录音
LineState:=Inp32($379);
if (not LineBusy)and ((LineState and $10)<>$10)
and(SysSet.AutoSavePhone1) then begin //线路不忙且录音电话1工作中
if(not Phone1Started) then begin //如果没有启动电话录音,那么启动之
Phone1Started:=true;
LineBusy:=true;
//打开链路
OpenLink(SysSet.PhoneLine1,lsRecord);
//添加电话录音记录,如果超出了最大个数,那么删除倒数第二个记录(尾记录不允许删除)
if(tbPhone.RecordCount>=SysSet.MaxPhoneWaveNum) then begin
tbPhone.Last;
tbPhone.Prior;
DeleteWaveFile(GetWaveName(tbPhone.FieldByName('开始时间').AsDateTime));
tbPhone.Delete;
end;
imPhone1.Glyph.LoadFromFile(RootDir+'\PhoneOn.bmp');
NowTime:=Now;
tbPhone.AppendRecord([SysSet.PhoneLine1,NowTime,NowTime]);
StartWaveRecord(GetTelephoneWaveName(NowTime));
end;
end
else begin
if(Phone1Started)and ((LineState and $10)=$10) then begin //如果已经启动了电话录音,那么关闭之
imPhone1.Glyph.LoadFromFile(RootDir+'\PhoneOff.bmp');
Phone1Started:=false;
LineBusy:=false;
//录音完毕,转换到待用状态
OpenLink(0,lsReady);
StopWaveRecord;
if(tbPhone.Sort='开始时间 ASC')then
tbPhone.Last
else
tbPhone.First;
tbPhone.Edit;
tbPhone.FieldByName('结束时间').AsDateTime:=Now;
tbPhone.Post;
end;
end;
if (not LineBusy)and ((LineState and $20)<>$20)
and(SysSet.AutoSavePhone2) then begin //录音电话2工作中
if(not Phone2Started) then begin //如果没有启动电话录音,那么启动之
Phone2Started:=true;
LineBusy:=true;
//打开链路
OpenLink(SysSet.PhoneLine2,lsRecord);
//添加电话录音记录
if(tbPhone.RecordCount>=SysSet.MaxPhoneWaveNum) then begin
try
tbPhone.Last;
tbPhone.Prior;
DeleteWaveFile(GetWaveName(tbPhone.FieldByName('开始时间').AsDateTime));
tbPhone.Delete;
except
end;
end;
imPhone2.Glyph.LoadFromFile(RootDir+'\PhoneOn.bmp');
NowTime:=Now;
tbPhone.AppendRecord([SysSet.PhoneLine2,NowTime,NowTime]);
StartWaveRecord(GetTelephoneWaveName(NowTime));
end;
end
else begin
if(Phone2Started)and ((LineState and $20)=$20) then begin //如果已经启动了电话录音,那么关闭之
imPhone2.Glyph.LoadFromFile(RootDir+'\PhoneOff.bmp');
Phone2Started:=false;
LineBusy:=false;
//录音完毕,转换到待用状态
OpenLink(0,lsReady);
StopWaveRecord;
if(tbPhone.Sort='开始时间 ASC')then
tbPhone.Last
else
tbPhone.First;
tbPhone.Edit;
tbPhone.FieldByName('结束时间').AsDateTime:=Now;
tbPhone.Post;
end;
end;
//延时
sleep(2000);
SleepCnt:=SleepCnt+1;
end;
Suspend;
end;
procedure TAutoCaller.ExtractRoom(var CurRecord:TCallRecord;str:string);
var
i,k,len:integer;
temp:string;
seekNum:boolean;
begin
temp:=' ';
len:=length(str);
i:=1; k:=1;
seekNum:=true;
CurRecord.StickyNum:=0;
while(i<=len)do begin
//寻找数字
if(seekNum) then begin
if(str[i]<>',') then begin
temp[k]:=str[i];
k:=k+1;
seekNum:=false;
end
end
//寻找空格
else begin
if(str[i]=',') then begin
temp[k]:=#0;
k:=1;
CurRecord.StickyRoom[CurRecord.StickyNum]:=temp;
if(not tbRoom.Locate('房间号码',temp,[])) then begin
CurRecord.StickyLine[CurRecord.StickyNum]:=1616;
end
else
CurRecord.StickyLine[CurRecord.StickyNum]:=tbRoom.FieldByName('线路').AsInteger;
CurRecord.StickyNum:=CurRecord.StickyNum+1;
end
else begin
temp[k]:=str[i];
k:=k+1;
end;
end;
i:=i+1;
end;
end;
//程序启动时初始化自动叫班队列
procedure TAutoCaller.InitQueue;
begin
//催叫队列个数置为0
{ RecallNum:=0;
//下面处理一叫队列的初始化
if(tbTemp.Active) then
tbTemp.Close;
tbTemp.TableName:='CallPlan';
tbTemp.Open;
tbTemp.Sort:='计划叫班时间 ASC';
tbTemp.First;
QNum:=0;
while (not tbTemp.Eof)and(QNum<MAX_PLAN_NUM) do begin
Queue[QNum].enabled:=tbTemp.FieldByName('开启').AsBoolean;
Queue[QNum].time:=StrToTime(tbTemp.FieldByName('计划叫班时间').AsString);
try
Queue[QNum].time:=Queue[QNum].time+strtoint(tbTemp.FieldByName('晚点时间').AsString)*60*ONE_SECOND;
except
end;
Queue[QNum].RecNo:=tbTemp.RecNo; //记录在数据表中的位置
Queue[QNum].Room:=tbTemp.FieldByName('房间号码').AsString;
Queue[QNum].time:=Queue[QNum].time-trunc(Queue[QNum].time); //去除整数部分
Queue[QNum].Train:=tbTemp.FieldByName('车次').AsString;
Queue[QNum].TrainTime:=strtotime(tbTemp.FieldByName('开车时间').AsString);
Queue[QNum].PlanFirstCall:=strtotime(tbTemp.FieldByName('计划叫班时间').AsString); //小时分钟秒
Queue[QNum].state:=csCalled; //标记为已完成叫班
if(not tbRoom.Locate('房间号码',Queue[QNum].Room,[])) then begin
Queue[QNum].line:=1616;
end
else
Queue[QNum].Line:=tbRoom.FieldByName('线路').AsInteger;
//获取联叫房间号码
ExtractRoom(QNum,tbTemp.FieldByName('联叫房号').AsString);
QNum:=QNum+1;
tbTemp.Next;
end;
tbTemp.Close;
}
end;
//添加叫班计划时修改叫班队列
procedure TAutoCaller.InsertQueue(InsertPlan:TCallRecord);
var i,j:integer;
begin
j:=-1;
for i:=0 to QNum-1 do begin
if(InsertPlan.time<Queue[i].time) then begin
Break;
end
else
j:=i;
end;
for i:=QNum downto j+1 do
Queue[i]:=Queue[i-1];
if(j>=0) then
Queue[j]:=InsertPlan
else
Queue[0]:=InsertPlan;
end;
//修改叫班队列项
procedure TAutoCaller.ModifyQueue(NewPlan:TCallRecord;Number:integer);
begin
Queue[Number]:=NewPlan;
end;
//打开链路
procedure TAutoCaller.OpenLink(line:word;LinkState:TLinkState);
begin
//高4位控制两个74LS138产生16个74HC154的选择信号
//低4位被16个74HC154共享,产生单片内控制的16个继电器的控制信号,
line:=(line div 100-1)*16+line mod 100-1;
Out32($378,line);
case(LinkState)of
lsReady: Out32($37A,$0e);//bit 0~3: PS1,PS14, ,PS17
lsDetect: Out32($37A,$0d);//bit 0~3: PS1,PS14, ,PS17
lsManualCall: Out32($37A,$06);//bit 0~3: PS1,PS14, ,PS17
lsListenCall: Out32($37A,$0f);//bit 0~3: PS1,PS14, ,PS17
lsAutoCall: Out32($37A,$0e);//bit 0~3: PS1,PS14, ,PS17
lsRecord: Out32($37A,$0f);//bit 0~3: PS1,PS14, ,PS17
lsReplay: Out32($37A,$0d);//bit 0~3: PS1,PS14, ,PS17
end;
end;
//检测房间存在否
function TAutoCaller.RoomExist(line:word):boolean;
var tmp:byte;
index:word;
begin
OpenLink(line,lsDetect);
sleep(100);
tmp:=Inp32($379)and $80; //get PS11
index:=(line div 100-1)*16+line mod 100-1;
if(tmp=0) then
RoomGood[index]:=false
else
RoomGood[index]:=true;
//for test
//RoomGood[index]:=true;
Result:=(tmp=$80);
end;
procedure TAutoCaller.CreateWav( channels : word; { 1(单声)或者2(立体声) }
resolution : word; { 8或者16,代表8位或16位声音 }
rate : longint; { 声音频率,如11025,22050, 44100}
fn : string { 对应的文件名称 } );
var
wf : file of TWavHeader;
wh : TWavHeader;
begin
wh.rId := $46464952;
wh.rLen := 36;
wh.wId := $45564157;
wh.fId := $20746d66;
wh.fLen := 16;
wh.wFormatTag := 1;
wh.nChannels := channels;
wh.nSamplesPerSec := rate;
wh.nAvgBytesPerSec := channels*rate*(resolution div 8);
wh.nBlockAlign := channels*(resolution div 8);
wh.wBitsPerSample := resolution;
wh.dId := $61746164;
wh.wSampleLength := 0;
try
assignfile(wf,fn); {打开对应文件 }
rewrite(wf); {移动指针到文件头}
write(wf,wh); {写进文件头 }
closefile(wf); {关闭文件 }
except
showmessage('存储目录不存在或错误,无法录音,请检查系统配置!');
end;
end;
//开始录音
procedure TAutoCaller.StartWaveRecord(fname:TFileName);
begin
CreateWav(1, SysSet.RecordBits, SysSet.RecordRate, fname);
Recorder.DeviceType := dtAutoSelect;
Recorder.FileName := fname;
Recorder.Open;
Recorder.StartRecording;
RecordTime:=0;
end;
//停止录音
procedure TAutoCaller.StopWaveRecord;
begin
Recorder.Stop;
Recorder.Save;
Recorder.Close;
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -