⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 myclass.pas

📁 这是一个火车站公寓的自动叫班程序源码
💻 PAS
📖 第 1 页 / 共 2 页
字号:
          //如果完成了包括三催在内的呼叫任务,那么清除晚点时间,同时清除联叫房间
          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 + -