计 简介:

1、   将卡、通道分别单独进行设计与封装。

2、   所有的外部操作接口都封装在卡类这一类。

3、   在我的项目中,在卡类这一级还增加了适配器或者代理,分别实现了Adapter或Proxy模式;以尽可能地解耦卡设备的实现细节与具体应用业务之间的关系。因为,我们的系统中使用了几家不同的卡设备,另一方面,这些卡设备,在不同的软件系统中,又有不同的业务应用需求。

4、   当然,卡这一级,也可以实现一个统一的接口,这样对外部可以表现出相对统一的行为,以方便业务层代码的调用,比如说:在数据采集的应用中,统一的接口可以让采集控制层不必依赖于具体的采集设备和通信方式,可以一致地实现数据收发,不管通信方式是RS232、RS485、TCP/IP、PSTN,还是别的方式或者通信设备。

5、   在通道设计中,核心的就是一个“状态机模式”,通过轮巡通道状态来管理硬件卡设备,并且,还自己设计了一个业务级的“业务状态机”,来抽象业务方面需要关心的“业务状态”,通过增加“业务状态机”这样一个中间层,以解耦业务状态与设备状态之间的依赖。(这一点,在我看到的所有卡厂商提供的各类Demo程序里面都没有这样做,这也无形中误导了很多的开发人员,我看到的所有应用软件开发的源码都是:设备细节、尤其是通道状态,与业务逻辑代码紧紧地耦合在一起,难解难分)。

6、   此设计的另一个亮点是:IoC模式的应用(2004年自己在设计此类时还不知道这个概念,全凭自己的经验总结出这样的设计)。对通道进入“呼入成功”、“呼出成功”等业务状态的调用代码从通道类是解耦出来:设计一个接口,在各个业务状态的处理方法中,再调用接口方法,将具体的业务处理逻辑委托给实现此接口的对象。并且这个接口的实现是通过“依赖注入”实现IoC的。这样设计,就达到了很好的可复用性和灵活性。

7、   当然,更好的实现可以采用AOP(面向方法编程)的思想或者实现技术,这样可复用性更好,如此设计,在业务与卡方法的调用之间,耦合度将是最低的。

8、   目前的版本,没有在代码中体现接口的实现……

9、   类图(以后补上):

10、卡类源码:

// ------------------------------------------------------------------------------
//
//       产品名称:   软件Delphi源码库
//       产品版本:   CXXSoft delphi code source lib 2.0
//       模块名称:   Delphi之东进模拟语音卡类
//       模块描述:   
//       单元文件:   unDJCard160A.pas   
//       开发作者:   成晓旭
//       备注:       任何人使用此文件时,请保留此段自述文件,谢谢!
//       开发时间:   2004-08-03
//       修改历史:   
//       修改描述:
// ------------------------------------------------------------------------------
unit unDJCard160A;

interface
uses
  Windows,
  unDJTC08a32,unDJNewSig,
  unBaseDefine,unDJ160ADefine,
  unDJChanne160A;
type
  TCXXCommCard160A  =  class (TObject)
   private

    ChannelNumber:Word;
    channelObject:array of TCXXDJChannel160A;
    OnCardChannelState:TTrunkStatusEvent;

    procedure Stop();
    procedure ReleaseCommDevice();
    function  GetChannelObjectOrder( const  aChannelID:Word):Word;

   public

    constructor Create( const  trunkEvent:TTrunkStatusEvent);
    destructor Destroy();  override ;

    function  LoadCommDevice( const  loadAll:boolean = false ):boolean;
    function  Startup():boolean;
    function  GetAFreeChannel():Word;
    function  GetChannelNumber():Word;
    function  DialPhone( const  aChannelID:Word; const  DialPhoneNumber:PChar):boolean;
    function  HangUp( const  aChannelID:Word):boolean;

  end;


implementation

{ TCXXCommCard160A }
constructor TCXXCommCard160A.Create( const  trunkEvent:TTrunkStatusEvent);
begin
  ChannelNumber : =  0 ;
  Self.OnCardChannelState : =  trunkEvent;
end;

destructor TCXXCommCard160A.Destroy;
var
  Loop:Word;
begin
  Stop();
   if  (Length(channelObject)  >  0 ) and (channelNumber  >  0 ) then
  begin
     for  Loop : =  0  to ChannelNumber  -  1  do
    begin
       if  Assigned(channelObject[Loop]) then
      begin
        channelObject[Loop].Free();
        channelObject[Loop] : =  nil;
      end;
    end;
  end;
  ReleaseCommDevice();
end;

function TCXXCommCard160A.DialPhone( const  aChannelID: Word;
   const  DialPhoneNumber: PChar): boolean;
var
  K:Word;
begin
  Result : =  false ;
  K : =  GetChannelObjectOrder(aChannelID);
   if  (K  <>  ErrorTrunkNumber) and (Assigned(channelObject[K])) then
  begin
    Result : =  channelObject[K].DialPhone(DialPhoneNumber);
  end;
end;

procedure TCXXCommCard160A.ReleaseCommDevice();
begin
  DisableCard();
  FreeDrv();
end;

function TCXXCommCard160A.GetAFreeChannel(): Word;
var
  Loop:Word;
begin
  Result : =  ErrorTrunkNumber;
   for  Loop : =  Low(channelObject) to High(channelObject)  do
  begin
     if  (channelObject[Loop].GetChannelType()  =  ctEmpty) then  continue ;
     if  (channelObject[Loop].GetChannelStatus()  =  atsFree) then
    begin
      Result : =  channelObject[Loop].GetChannelID();
       break ;
    end;
  end;
end;

function TCXXCommCard160A.GetChannelNumber(): Word;
begin
  Result : =  channelNumber;
end;

function TCXXCommCard160A.GetChannelObjectOrder(
   const  aChannelID: Word): Word;
var
  Loop:Word;
begin
  Result : =  ErrorTrunkNumber;
   for  Loop : =  Low(channelObject) to High(channelObject)  do
  begin
     if  (channelObject[Loop].GetChannelID  =  aChannelID) then
    begin
      Result : =  Loop;
       break ;
    end;
  end;
end;

function TCXXCommCard160A.HangUp( const  aChannelID: Word): boolean;
var
  K:Word;
begin
  Result : =  false ;
  K : =  GetChannelObjectOrder(aChannelID);
   if  (K  <>  ErrorTrunkNumber) and (Assigned(channelObject[K])) then
  begin
    channelObject[K].ChannelHangUp();
    Result : =  true ;
  end;
end;

function TCXXCommCard160A.LoadCommDevice( const  loadAll:boolean): boolean;
const
  loadEmpty  =  true ;
var
  Loop,tempNumber:Word;
  isFlag:LongInt;
  function CheckLoadTrunk():boolean;
  begin
    Result : =  loadAll or ((NOT loadAll) and(TChannelType(CheckChType(Loop))  <>  ctEmpty));
  end;
begin
  isFlag : =  LoadDRV();
  Result : =  (isFlag = 0 );
   if  NOT Result then Exit;
  tempNumber : =  CheckValidCh();
  Result : =  EnableCard(tempNumber, 1024 * 8 ) = 0 ;
   if  NOT Result then
  begin
    FreeDrv();
    Exit;
  end;
  Result : =  Sig_Init() = 1 ;
   if  NOT Result then Exit;
  SetBusyPara( 700 );
  SetPackRate(PACK_64KBPS );
  channelNumber : =  tempNumber;
  SetLength(channelObject,channelNumber);
   for  Loop : =  0  to channelNumber  -  1  do
  begin
     if  CheckLoadTrunk() then
    begin
      channelObject[Loop] : =  TCXXDJChannel160A.Create(OnCardChannelState);
      channelObject[Loop].CreateCommChannel(Loop);
    end;
  end;
end;

function TCXXCommCard160A.Startup(): boolean;
var
  Loop:integer;
begin
   for  Loop : =  0  to channelNumber  -  1  do
  begin
    channelObject[Loop].Resume();
  end;
  Result : =  true ;
end;

procedure TCXXCommCard160A.Stop();
var
  Loop:integer;
begin
   for  Loop : =  0  to channelNumber  -  1  do
  begin
    channelObject[Loop].Suspend();
    channelObject[Loop].Terminate();
    channelObject[Loop] : =  nil;
  end;
end;

end.
11、               通道类源码:
// ------------------------------------------------------------------------------
//
//       产品名称:   成晓旭的个人软件Delphi源码库
//       产品版本:   CXXSoft delphi code source lib 2.0
//       模块名称:   Delphi之东进模拟语音卡通道类
//       模块描述:   
//       单元文件:   unDJChanne160A.pas   
//       开发作者:   成晓旭
//       备注:       任何人使用此文件时,请保留此段自述文件,谢谢!
//       开发时间:   2004-08-03
//       修改历史:   
//       修改描述:
// ------------------------------------------------------------------------------
unit unDJChanne160A;

interface

uses
  Windows,Classes,SysUtils,
  unBaseDefine,unDJ160ADefine,
  unDJTC08a32,unDJNewSig;
Type
  TCXXDJChannel160A  =  class (TThread)
   // TCXXDJChannel160A = class(TObject)
   private
    channelType:TChannelType;
    oldChannelState,channelState:TTrunkState;
    channelID:Word;
    phoneNumber: string ;
    dtmfString: string ;

    isConntectd:boolean;

    isDialOut:boolean;
    aTrunkState:TTrunkStatus;
    
    procedure InformTrunkStatus( const  aMsgFlag: TLVOperateFlag);

    procedure ClearTrunkStatus();
    function  CheckSigHangup():boolean;
    function  CheckCallIn():boolean;
    function  SwitchOnCallIn():boolean;

    procedure ProcessCallInSuccess();
    procedure ProcessDialSuccess();

    procedure ProcessCheckDialSend();
   protected
    procedure Execute();  override ;
   public
    strMessage: string ;
    OnChannelState:TTrunkStatusEvent;

    constructor Create( const  trunkEvent:TTrunkStatusEvent);
    destructor Destroy(); override ;

    procedure CreateCommChannel( const  aChennelID: Word);
    procedure ChannelProcessor();

    function  GetChannelID():Word;
    function  GetChannelStatus():TTrunkState;
    function  GetChannelType():TChannelType;
    function  DialPhone( const  DialPhoneNumber:PChar):boolean;overload;
    function  DialPhone( const  DialPhoneNumber:PChar; const  PreDialNumber:PChar):boolean;overload;
    procedure ChannelHangUp();

    function  GetDialOut():boolean;
  end;
implementation

{ TCXXDJChannel160A }

procedure TCXXDJChannel160A.ChannelHangUp();
begin
  isDialOut : =  false ;
  StopSigCheck(channelID);
  HangUp(channelID);
  Sig_ResetCheck(channelID);
  StartSigCheck(channelID);
  InitDTMFBuf(channelID);
  ClearTrunkStatus();
  InformTrunkStatus(lvofUpdate);
end;

procedure TCXXDJChannel160A.ChannelProcessor();
var
  dState:Word;
begin
  PUSH_PLAY();
  FeedSigFunc();
  CheckCallIn();
     case  channelState of
    atsFree:
    begin
       //
    end;
    atsCallIning:
    begin
      SwitchOnCallIn();
    end;
    atsCallInSuccess:
    begin
       if  CheckSigHangup() then Exit;
      ProcessCallInSuccess();
    end;
    atsCheckSendDial:
    begin
      ProcessCheckDialSend();
    end;
    atsDialing:
    begin
      dState : =  Sig_CheckDial(channelID);
       case  dState of
   //       S_NORESULT:
        S_CONNECT:
        begin
          channelState : =  atsDialSuccess;
          isConntectd : =  true ;
        end;
        S_BUSY,
        S_NOBODY,
        S_NODIALSIG,
        S_NOSIGNAL:
        begin
          channelState : =  atsHangOff;
        end;
      end;
      strMessage : =  ' 拨号中... ' ;
    end;
    atsDialSuccess:
    begin
       if  CheckSigHangup() then Exit;
      ProcessDialSuccess();
      strMessage : =  ' 拨号成功 ' ;
    end;
    atsHangOff:
    begin
      ChannelHangUp();
    end;
    end;
     if  (oldChannelState  <>  channelState) then
    begin
      oldChannelState : =  channelState;
      InformTrunkStatus(lvofUpdate);
    end;
end;

function TCXXDJChannel160A.CheckCallIn(): boolean;
begin
  Result : =  RingDetect(channelID);
   if  Result then
  begin
    OffHook(channelID);
     if  isDialOut then
      channelState : =  atsDialSuccess
     else
      channelState : =  atsCallIning;
  end;
end;

function TCXXDJChannel160A.CheckSigHangup(): boolean;
begin
  Result : =  false ;
   if  (Sig_CheckBusy(channelID) = 1 ) then
  begin
    strMessage : =  ' 对方已挂机 ' ;
    InformTrunkStatus(lvofUpdate);
    StopPlayFile(channelID);
    channelState : =  atsHangOff;
    Result : =  true ;
  end;
end;

procedure TCXXDJChannel160A.ClearTrunkStatus();
begin
  channelState : =  atsFree;
  oldChannelState : =  channelState;
  phoneNumber : =  '' ;
  dtmfString : =  '' ;
  strMessage : =  '' ;
  isConntectd : =  false ;
end;

constructor TCXXDJChannel160A.Create( const  trunkEvent:TTrunkStatusEvent);
begin
  Self.OnChannelState : =  trunkEvent;
  Self.FreeOnTerminate : =  true ;
  inherited Create( true );
end;


destructor TCXXDJChannel160A.Destroy;
begin
  Suspend();
  ChannelHangUp();
   // inherited Destroy();
end;

function TCXXDJChannel160A.DialPhone( const  DialPhoneNumber:PChar;
   const  PreDialNumber:PChar): boolean;
begin
  isDialOut : =  true ;
  phoneNumber : =  DialPhoneNumber;
  OffHook(channelID);
  InitDTMFBuf(channelID);
  Result : =  Sig_StartDial(channelID,DialPhoneNumber,PreDialNumber, 0 ) = 1 ;
  channelState : =  atsCheckSendDial;
end;

function TCXXDJChannel160A.DialPhone(
   const  DialPhoneNumber: PChar): boolean;
begin
  Result : =  DialPhone(DialPhoneNumber, '' );
end;

procedure TCXXDJChannel160A.Execute;
begin
   while  NOT Terminated  do
  begin
    Synchronize(ChannelProcessor);
    Sleep( 10 );
  end;
end;

function TCXXDJChannel160A.GetChannelID(): Word;
begin
  Result : =  channelID;
end;

function TCXXDJChannel160A.GetChannelStatus(): TTrunkState;
begin
  Result : =  channelState;
end;

procedure TCXXDJChannel160A.InformTrunkStatus( const  aMsgFlag: TLVOperateFlag);
begin
  aTrunkState.lvFlag : =  aMsgFlag;
  aTrunkState.TrunkID : =  IntToStr(channelID);
  aTrunkState.TrunkType : =  channelType;
  aTrunkState.TrunkTypeStr : =  ChannelTypeString[channelType];
  aTrunkState.TrunkStep : =  channelState;
  aTrunkState.TrunkStepStr : =  TrunkStateString[channelState];
  aTrunkState.TrunkPhone : =  phoneNumber;
  aTrunkState.TrunkData : =  dtmfString;
  OnChannelState(aTrunkState);
end;

procedure TCXXDJChannel160A.ProcessCallInSuccess();
begin

end;

function TCXXDJChannel160A.SwitchOnCallIn(): boolean;
begin
  OffHook(channelID);
  InitDTMFBuf(channelID);
  StartSigCheck(channelID);
  channelState : =  atsCallInSuccess;
  Result : =  true ;
end;

procedure TCXXDJChannel160A.ProcessDialSuccess();
begin

end;

procedure TCXXDJChannel160A.CreateCommChannel( const  aChennelID: Word);
begin
  channelID : =  aChennelID;
  channelType : =  TChannelType(CheckChType(channelID));
  ClearTrunkStatus();
  InformTrunkStatus(lvofAdd);
end;

function TCXXDJChannel160A.GetChannelType(): TChannelType;
begin
  Result : =  channelType;
end;

function TCXXDJChannel160A.GetDialOut(): boolean;
begin
  Result : =  isDialOut;
end;

procedure TCXXDJChannel160A.ProcessCheckDialSend();
begin
   if (CheckSendEnd(channelID)  =  1 ) then
  begin
    StartSigCheck(channelID);
    channelState : =  atsDialing;
  end;
end;

end.

转载于:https://www.cnblogs.com/myamanda/articles/1612030.html

Delphi之东进模拟语音卡(D160A)可复用源码(转)相关推荐

  1. Delphi之东进模拟语音卡(D160A)可复用源码

    Delphi之东进模拟语音卡(D160A)可复用源码 作者:成晓旭 Blog:http://blog.csdn.net/cxxsoft (声明:欢迎转载,请保证文章的完整性) 设计简介: 1.   将 ...

  2. Delphi之东进数字语音卡(SS1)可复用源码

    Delphi之东进数字语音卡(SS1)可复用源码 作者:成晓旭 Blog:http://blog.csdn.net/cxxsoft (声明:欢迎转载,请保证文章的完整性) 由于工作原因,本人将不在从事 ...

  3. Delphi之东进数字语音卡(SS1)可复用源码 1

    Delphi之东进数字语音卡(SS1)

  4. 转 : Squareup刷卡器,音频读卡识别android/iOS源码API

    转  :   Squareup刷卡器,音频读卡识别android/iOS源码API 相信很多人已经见过squareup的读卡器了,银行磁卡在该读卡器上一刷,则能从手机中获取银行卡磁道的信息. Squa ...

  5. 【语音去噪】基于matlab小波硬阈值语音降噪【含Matlab源码 532期】

    ⛄一.获取代码方式 获取代码方式1: 完整代码已上传我的资源:[语音去噪]基于matlab小波硬阈值语音降噪[含Matlab源码 532期] 点击上面蓝色字体,直接付费下载,即可. 获取代码方式2: ...

  6. 【语音增强】基于matlab人耳掩蔽效应语音增强【含Matlab源码 428期】

    ⛄一.获取代码方式 获取代码方式1: 完整代码已上传我的资源:[语音增强]基于matlab人耳掩蔽效应语音增强[含Matlab源码 428期] 点击上面蓝色字体,直接付费下载,即可. 获取代码方式2: ...

  7. 【物理应用】基于matlab模拟井筒多相流【含Matlab源码 2152期】

    ⛄一.获取代码方式 获取代码方式1: 完整代码已上传我的资源:[物理应用]基于matlab模拟井筒多相流[含Matlab源码 2152期] 点击上面蓝色字体,直接付费下载,即可. 获取代码方式2: 付 ...

  8. 【光学】基于matlab模拟拉盖尔高斯【含Matlab源码 2167期】

    ⛄一.获取代码方式 获取代码方式1: 完整代码已上传我的资源:[光学]基于matlab模拟拉盖尔高斯[含Matlab源码 2167期] 点击上面蓝色字体,直接付费下载,即可. 获取代码方式2: 付费专 ...

  9. 2023最新包你说语音口令红包小程序源码+运营版/修复BUG完全开源

    正文: 包你说语音口令红包小程序源码运营版,修复市面已知BUG,完全开源,支持二次开发,有兴趣的自行去安装体验吧,其它就没什么好介绍的了. 程序: wwtyeo.lanzoux.com/i2k0i0s ...

最新文章

  1. 浪潮刘军:为什么说计算力是AI时代“免费的午餐”?
  2. 串口 驱动 热敏打印机_菜鸟裹裹x 快麦打印机联合发布SC310,实现共享智能打印...
  3. 挑选SaaS企业需要注意十要素
  4. 鸿蒙系统的适配国产手机,真正的好消息!其它国产机,也在适配华为鸿蒙系统...
  5. 去中心化索引协议The Graph将于12月上线主网
  6. node.js 学习书籍推荐
  7. 苹果Mac上的 Spotlight 扩展小技巧
  8. 计算机及网络维护工程师专业问题
  9. 【转】牛仔裤品牌介绍大全
  10. 模糊C均值聚类算法matlab实现,FCMClust(模糊c均值聚类算法MATLAB实现)
  11. 常见的棋牌游戏网站支付接口
  12. 名片 - 名片设计的比例
  13. 搭建企业私有Git服务
  14. 高明领导不说狠话、不画大饼、不灌鸡汤,打造狼性团队就靠这9条
  15. 【软件群英会】 12月1日晚上聊天记录
  16. sci写作之前的记录
  17. Ubuntu设置全局socks代理
  18. Tarena - 表的创建
  19. mysql exit quit_MySQL数据库5.5基础 exit quit \q 退出MySQL数据库
  20. 使用74LS161设计任意进制计数器

热门文章

  1. PHP初中英语在线考试系统的设计与实现-计算机毕设 附源码 87564
  2. 并发下php脚本执行,php命令行脚本多进程并发执行
  3. kafka消费之kafka查看topic是否有数据
  4. 怀着忐忑的心情,我来了B站实习,B站后端日常实习面经分享!
  5. win10 wlan打不开的解决方式(原先没有问题,突然就打不开)
  6. Google Play Console语言设置方法
  7. jQuery实现元素的隐藏和显示
  8. Android Studio生成APK自动追加版本号 自定义apk名称 指定签名证书文件
  9. 程序员如何追到公司漂亮的HR?
  10. iOS 应用添加启动画面以及App应用图标的方法