分享
 
 
 

Delphi之三匯模擬語音卡(SHT-8B/PCI/FAX)可復用源碼

王朝delphi·作者佚名  2007-09-15
窄屏简体版  字體: |||超大  

Delphi之三匯模擬語音卡(SHT-8B/PCI/FAX)可復用源碼

作者:成曉旭

設計簡介:

1、 設計思路請參考本站Blog的另一篇文章:“Delphi之東進模擬語音卡(D160A)可復用源碼”;鏈接http://blog.csdn.net/CXXSoft/archive/2006/08/23/1108211.aspx

2、 其實,仔細對比,你會發現這兩種卡的代碼類方法簽名幾乎99%是一樣的,也就是說,這兩都之間,還需要更進一步的抽象,以解決“重復代碼”或者“相似代碼”的問題。

3、 更高層次的抽象,請參考我的設計文檔。

4、 類圖(以後補上):

5、 卡類源碼:

//------------------------------------------------------------------------------

//

// 產品名稱: 成曉旭的個人軟件Delphi源碼庫

// 產品版本: CXXSoft delphi code source lib 2.0

// 模塊名稱: Delphi之三匯模擬語音卡類

// 模塊描述:

// 單元文件: unSHCard8B.pas

// 開發作者: 成曉旭

// 備註: 任何人使用此文件時,請保留此段自述文件,謝謝!

// 開發時間: 2003-12-03

// 修改歷史:

// 修改描述:

//------------------------------------------------------------------------------

unit unSHCard8B;

interface

uses

Windows,

//unDJTC08a32,unDJNewSig,

unBaseDefine,

//unDJ160ADefine,unDJChanne160A,

unShpa3api,unSHChanne18B,unSH8BDefine;

type

TCXXCommCard8B = class(TObject)

private

ChannelNumber:Word;

channelObject:array of TCXXSHChannel8B;

OnCardChannelState:TTrunkStatusEvent;

procedure ReleaseCommDevice();

function GetChannelObjectOrder(const aChannelID:Word):Word;

function InitChannel():boolean;

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

const

SH_ConfigFile = 'C:ShCtiShConfig.ini';

SH_IndexFile = 'C:ShCtiShIndex.ini';

...{ TCXXCommCard8B }

constructor TCXXCommCard8B.Create(const trunkEvent:TTrunkStatusEvent);

begin

ChannelNumber := 0;

Self.OnCardChannelState := trunkEvent;

end;

destructor TCXXCommCard8B.Destroy;

var

Loop:Word;

begin

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 TCXXCommCard8B.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 TCXXCommCard8B.ReleaseCommDevice();

begin

SsmCloseCti() ;

end;

function TCXXCommCard8B.GetAFreeChannel(): Word;

var

Loop:Word;

begin

Result := ErrorTrunkNumber;

for Loop := Low(channelObject) to High(channelObject) do

begin

if NOT channelObject[Loop].CheckDialOutEnabled() then continue;

if (channelObject[Loop].GetChannelStatus() = atsFree) then

begin

Result := channelObject[Loop].GetChannelID();

break;

end;

end;

end;

function TCXXCommCard8B.GetChannelNumber(): Word;

begin

Result := channelNumber;

end;

function TCXXCommCard8B.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 TCXXCommCard8B.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 TCXXCommCard8B.LoadCommDevice(const loadAll:boolean): boolean;

const

loadEmpty = true;

begin

Result := false;

if SsmStartCti(SH_ConfigFile,SH_IndexFile) <> 0 then

begin

TCXXSHChannel8B.InformInvodeError();

Exit;

end;

if(SsmGetMaxUsableBoard() <> SsmGetMaxCfgBoard()) then

begin //部分板卡初始化失敗,取出失敗原因

TCXXSHChannel8B.InformInvodeError();

Exit;

end;

Result := InitChannel();

end;

function TCXXCommCard8B.Startup(): boolean;

var

Loop:integer;

begin

for Loop := 0 to channelNumber - 1 do

begin

channelObject[Loop].Startup();

end;

Result := true;

end;

function TCXXCommCard8B.InitChannel():boolean;

var

number,Loop:integer;

begin

Result := false;

number := SsmGetMaxCh();

if (number < 0) then Exit;

ChannelNumber := number;

SetLength(channelObject,channelNumber);

for Loop := 0 to channelNumber - 1 do

begin

channelObject[Loop] := TCXXSHChannel8B.Create(OnCardChannelState);

channelObject[Loop].CreateCommChannel(Loop);

end;

Result := true;

end;

end.

6、 通道類源碼:

//------------------------------------------------------------------------------

//

// 產品名稱: 成曉旭的個人軟件Delphi源碼庫

// 產品版本: CXXSoft delphi code source lib 2.0

// 模塊名稱: Delphi之三匯模擬語音卡通道類

// 模塊描述:

// 單元文件: unSHChanne18B.pas

// 開發作者: 成曉旭

// 備註: 任何人使用此文件時,請保留此段自述文件,謝謝!

// 開發時間: 2003-12-01

// 修改歷史:

// 修改描述:

//------------------------------------------------------------------------------

unit unSHChanne18B;

...{$DEFINE ThreadChannel}

interface

uses

Windows,Classes,SysUtils,

unBaseDefine,unShpa3api,unSH8BDefine,

//unDJ160ADefine,

unDJTC08a32,unDJNewSig;

Type

...{$IFDEF ThreadChannel}

TCXXSHChannel8B = class(TThread)

...{$ELSE}

TCXXSHChannel8B = class(TObject)

...{$ENDIF}

private

channelType:TChannelType;

oldChannelState,channelState:TTrunkState;

channelID:Word;

phoneNumber:string;

dtmfString:string;

aCallerId:PAnsiChar;

isConntectd:boolean;

isDialOut:boolean;

aTrunkState:TTrunkStatus;

procedure ChannelProcessor();

procedure InformTrunkStatus(const aMsgFlag: TLVOperateFlag);

procedure ClearTrunkStatus();

procedure ClearChannelBuffer();

function CheckSigHangup():boolean;

function CheckCallIn():boolean;

function SwitchOnCallIn():boolean;

procedure ProcessCallInSuccess();

procedure ProcessDialSuccess();

procedure ProcessCheckDialSend();

procedure ProcessDialOut();

procedure Stop();

//三匯卡專用方法

function GetTrunkStateBySsm(const ssmState: integer): TTrunkState;

protected

...{$IFDEF ThreadChannel}

procedure Execute(); override;

...{$ENDIF}

public

strMessage:string;

OnChannelState:TTrunkStatusEvent;

constructor Create(const trunkEvent:TTrunkStatusEvent);

destructor Destroy();override;

procedure CreateCommChannel(const aChennelID: Word);

procedure Startup();

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;

//三匯卡特性方法

function CheckDialOutEnabled():boolean;

class procedure InformInvodeError();

end;

implementation

...{ TCXXSHChannel8B }

procedure TCXXSHChannel8B.ChannelHangUp();

begin

isDialOut := false;

SsmHangUp(channelID);

ClearChannelBuffer();

ClearTrunkStatus();

InformTrunkStatus(lvofUpdate);

end;

procedure TCXXSHChannel8B.ChannelProcessor();

var

ssmState:integer;

begin

// ssmState := SsmGetChState(channelID);

// channelState := GetTrunkStateBySsm(ssmState);

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

ProcessDialOut();

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 TCXXSHChannel8B.CheckCallIn(): boolean;

begin

Result := false;

if(SsmGetChState(channelID)=2) then //檢測到振鈴信號

begin

SsmGetCallerId(channelID, aCallerId); //取出CALLERID信息

channelState := atsCallIning;

Result := true;

end;

...{

Result := RingDetect(channelID);

if Result then

begin

OffHook(channelID);

if isDialOut then

channelState := atsDialSuccess

else

channelState := atsCallIning;

end;

}

end;

function TCXXSHChannel8B.CheckSigHangup(): boolean;

begin

Result := false;

if (SsmGetChState(channelID) = S_CALL_PENDING) then

begin

strMessage := '對方已掛機';

InformTrunkStatus(lvofUpdate);

SsmStopPlay(channelID);

channelState := atsHangOff;

Result := true;

end;

end;

procedure TCXXSHChannel8B.ClearTrunkStatus();

begin

channelState := atsFree;

oldChannelState := channelState;

phoneNumber := '';

dtmfString := '';

strMessage := '';

isConntectd := false;

end;

constructor TCXXSHChannel8B.Create(const trunkEvent:TTrunkStatusEvent);

begin

GetMem(aCallerId,50);

Self.OnChannelState := trunkEvent;

...{$IFDEF ThreadChannel}

Self.FreeOnTerminate := true;

inherited Create(true);

...{$ENDIF}

end;

destructor TCXXSHChannel8B.Destroy;

begin

ChannelHangUp();

Stop();

...{$IFNDEF ThreadChannel}

inherited Destroy();

...{$ENDIF}

InformTrunkStatus(lvofDelete);

FreeMem(aCallerId);

end;

function TCXXSHChannel8B.DialPhone(const DialPhoneNumber:PChar;

const PreDialNumber:PChar): boolean;

begin

Result := false;

if (channelState <> atsFree) then Exit;

phoneNumber := DialPhoneNumber;

Result := (SsmPickup(channelID) = 0);

if NOT Result then Exit;

Result := (SsmAutoDial(channelID,DialPhoneNumber)=0);

if Result then

begin

isDialOut := true;

channelState := atsCheckSendDial;

end;

end;

function TCXXSHChannel8B.DialPhone(

const DialPhoneNumber: PChar): boolean;

begin

Result := DialPhone(DialPhoneNumber,'');

end;

...{$IFDEF ThreadChannel}

procedure TCXXSHChannel8B.Execute;

begin

while NOT Terminated do

begin

Synchronize(ChannelProcessor);

Sleep(10);

end;

end;

...{$ENDIF}

function TCXXSHChannel8B.GetChannelID(): Word;

begin

Result := channelID;

end;

function TCXXSHChannel8B.GetChannelStatus(): TTrunkState;

begin

Result := channelState;

end;

procedure TCXXSHChannel8B.InformTrunkStatus(const aMsgFlag: TLVOperateFlag);

begin

if NOT Assigned(OnChannelState) then Exit;

aTrunkState.lvFlag := aMsgFlag;

aTrunkState.TrunkID := IntToStr(channelID);

aTrunkState.TrunkType := Ord(channelType);

aTrunkState.TrunkTypeStr := ChannelTypeString[channelType];

aTrunkState.TrunkStep := Ord(channelState);

aTrunkState.TrunkStepStr := TrunkStateString[channelState];

aTrunkState.TrunkPhone := phoneNumber;

aTrunkState.TrunkData := dtmfString;

OnChannelState(aTrunkState);

end;

procedure TCXXSHChannel8B.ProcessCallInSuccess();

begin

end;

function TCXXSHChannel8B.SwitchOnCallIn(): boolean;

begin

SsmPickup(channelID); //摘機

ClearChannelBuffer();

channelState := atsCallInSuccess;

Result := true;

end;

procedure TCXXSHChannel8B.ProcessDialSuccess();

begin

end;

procedure TCXXSHChannel8B.CreateCommChannel(const aChennelID: Word);

var

ct:integer;

begin

channelID := aChennelID;

ct := SsmGetChType(channelID);

if (ct < 0) then Exit;

channelType := TChannelType(ct);

ClearTrunkStatus();

InformTrunkStatus(lvofAdd);

end;

function TCXXSHChannel8B.GetChannelType(): TChannelType;

begin

Result := channelType;

end;

function TCXXSHChannel8B.GetDialOut(): boolean;

begin

Result := isDialOut;

end;

procedure TCXXSHChannel8B.ProcessCheckDialSend();

begin

//三匯卡直接轉換狀態

channelState := atsDialing;

end;

procedure TCXXSHChannel8B.Startup();

begin

...{$IFDEF ThreadChannel}

Resume();

...{$ENDIF}

end;

procedure TCXXSHChannel8B.Stop();

begin

...{$IFDEF ThreadChannel}

Suspend();

Terminate();

...{$ENDIF}

end;

function TCXXSHChannel8B.CheckDialOutEnabled(): boolean;

begin

//內線通道、坐席通道、磁石通道和錄音通道不支持本SsmPicuup操作

Result := NOT((channelType = ct1) or

(channelType = ct2) or

(channelType = ct3) or

(channelType = ct10));

end;

class procedure TCXXSHChannel8B.InformInvodeError;

var

msgBuffer:PAnsiChar;

begin

GetMem(msgBuffer,255);

try

SsmGetLastErrMsg(msgBuffer);

//記錄異常日誌,或者通知用戶

//Showmessage(msgBuffer);

finally

FreeMem(msgBuffer);

end;

end;

function TCXXSHChannel8B.GetTrunkStateBySsm(

const ssmState: integer): TTrunkState;

begin

Result := atsFree;

case ssmState of

0: Result := atsFree;

4,5,6,9: Result := atsCallIning;

7: Result := atsHangOff;

//8:“斷線”狀態。只有錄音通道才會進入本狀態。暫時不處理

//8: Result := atsHangOff;

//3: Result := atsCallInSuccess;

end;

end;

procedure TCXXSHChannel8B.ProcessDialOut();

var

dState:integer;

begin

dState := SsmChkAutoDial(channelID);

case dState of

DIAL_VOICE,

DIAL_VOICEF1,

DIAL_VOICEF2:

begin

channelState := atsDialSuccess;

isConntectd := true;

end;

DIAL_STANDBY,

DIAL_NO_DIALTONE,

DIAL_ECHO_NOVOICE,

DIAL_NOVOICE,

DIAL_NOANSWER,

DIAL_FAILURE,

DIAL_INVALID_PHONUM:

begin

channelState := atsHangOff;

end;

end;

strMessage := '撥號中...';

end;

procedure TCXXSHChannel8B.ClearChannelBuffer();

begin

SsmClearRxDTMFBuf(channelID); //清空驅動程序內部的DTMF按鍵號碼接收緩衝區

SsmClearRxBuf(channelID); //清除指定通道ch上MODEM模塊的接收緩衝區中的所有數據

//“搶撥” 開關是指當在放音過程中收到對方的DTMF按鍵字符時,由驅動程序程序立即停止正在進行的放音操作。

//SsmSetDtmfStopPlay(channelID,true); //打開搶撥開關

end;

end.

 
 
 
免責聲明:本文為網絡用戶發布,其觀點僅代表作者個人觀點,與本站無關,本站僅提供信息存儲服務。文中陳述內容未經本站證實,其真實性、完整性、及時性本站不作任何保證或承諾,請讀者僅作參考,並請自行核實相關內容。
2023年上半年GDP全球前十五強
 百态   2023-10-24
美眾議院議長啟動對拜登的彈劾調查
 百态   2023-09-13
上海、濟南、武漢等多地出現不明墜落物
 探索   2023-09-06
印度或要將國名改為「巴拉特」
 百态   2023-09-06
男子為女友送行,買票不登機被捕
 百态   2023-08-20
手機地震預警功能怎麽開?
 干货   2023-08-06
女子4年賣2套房花700多萬做美容:不但沒變美臉,面部還出現變形
 百态   2023-08-04
住戶一樓被水淹 還衝來8頭豬
 百态   2023-07-31
女子體內爬出大量瓜子狀活蟲
 百态   2023-07-25
地球連續35年收到神秘規律性信號,網友:不要回答!
 探索   2023-07-21
全球鎵價格本周大漲27%
 探索   2023-07-09
錢都流向了那些不缺錢的人,苦都留給了能吃苦的人
 探索   2023-07-02
倩女手遊刀客魅者強控制(強混亂強眩暈強睡眠)和對應控制抗性的關系
 百态   2020-08-20
美國5月9日最新疫情:美國確診人數突破131萬
 百态   2020-05-09
荷蘭政府宣布將集體辭職
 干货   2020-04-30
倩女幽魂手遊師徒任務情義春秋猜成語答案逍遙觀:鵬程萬裏
 干货   2019-11-12
倩女幽魂手遊師徒任務情義春秋猜成語答案神機營:射石飲羽
 干货   2019-11-12
倩女幽魂手遊師徒任務情義春秋猜成語答案昆侖山:拔刀相助
 干货   2019-11-12
倩女幽魂手遊師徒任務情義春秋猜成語答案天工閣:鬼斧神工
 干货   2019-11-12
倩女幽魂手遊師徒任務情義春秋猜成語答案絲路古道:單槍匹馬
 干货   2019-11-12
倩女幽魂手遊師徒任務情義春秋猜成語答案鎮郊荒野:與虎謀皮
 干货   2019-11-12
倩女幽魂手遊師徒任務情義春秋猜成語答案鎮郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手遊師徒任務情義春秋猜成語答案鎮郊荒野:指鹿為馬
 干货   2019-11-12
倩女幽魂手遊師徒任務情義春秋猜成語答案金陵:小鳥依人
 干货   2019-11-12
倩女幽魂手遊師徒任務情義春秋猜成語答案金陵:千金買鄰
 干货   2019-11-12
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有