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

📄 adtapi.pas

📁 测试用例
💻 PAS
📖 第 1 页 / 共 5 页
字号:
(***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is TurboPower Async Professional
 *
 * The Initial Developer of the Original Code is
 * TurboPower Software
 *
 * Portions created by the Initial Developer are Copyright (C) 1991-2002
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *
 * ***** END LICENSE BLOCK ***** *)

{*********************************************************}
{*                    ADTAPI.PAS 4.06                    *}
{*********************************************************}
{* TApdTapiDevice, status and log components             *}
{*********************************************************}

{
  The TApdTapiDevice negotiates for TAPI 1.4, which is pre-installed
  in all 32-bit Windows versions (Win9x through XP).  Voice extensions
  are available for Win95OSR2/Win98/ME/2K/XP through the default Windows
  installation (Unimodem/V and Unimodem/5).
  By far, the biggest problem with TAPI is the TAPI device itself. Always
  check the modem drivers first, and strongly suggest to your users that
  they periodically update their modem drivers.
  Known problem areas: TAPI handles answering differently when doing data or
  voice, we aren't doing any special processing to get common/consistent
  events.  The notification we receive varies a bit between TAPI versions
  also, so check to see which events fire. The TapiTest example from
  ftp://ftp.turbopower.com/pub/apro/demos/_Index.htm lets you see everything
  that happens, use that to see how your modem/environment will react.
  TAPI voice using regular modems (Unimodem/V or Unimodem/5) was not designed
  for outbound/dialed automated voice calls.  You will get an OnTapiConnect
  event shortly after dialing, regardless of whether the line was busy, and
  completely independent upon when the remote side actually answers.  The
  APROFAQ.HLP file has some tips to get around this. Of course, the TAPI
  Service Providers (TSP) that ship with dedicated voice boards usually handle
  this correctly, and you get much higher quality of voice play/record, so
  get one of those boards (Dialogic, MediaPhonics, etc) if you need to do
  outbound/dialed automated voice calls.
}

{Global defines potentially affecting this unit}
{$I AWDEFINE.INC}

{Options required for this unit}
{$G+,X+,F+,B-,J+}
{$C MOVEABLE,DEMANDLOAD,DISCARDABLE}

unit AdTapi;
  {-Delphi TAPI interface component}

interface

uses
  WinTypes,
  WinProcs,
  Registry,
  Classes,
  Messages,
  Controls,
  Forms,
  {$IFDEF Delphi6}
  Variants,
  {$ENDIF}
  ExtCtrls,
  Dialogs,
  MMSystem,
  SysUtils,
  AdTUtil,
  OoMisc,
  AwUser,
  AdExcept,
  AdTSel,
  AdPort;

type
  {TAPI states}
  TTapiState = (tsIdle, tsOffering, tsAccepted, tsDialTone, tsDialing,
                tsRingback, tsBusy, tsSpecialInfo, tsConnected,
                tsProceeding, tsOnHold, tsConferenced, tsOnHoldPendConf,
                tsOnHoldPendTransfer, tsDisconnected, tsUnknown);

  {TTapiConfigRec definition moved to OOMisc to support RAS}             {!!.06}

  {Wave device states}
  TWaveState  = (wsIdle, wsPlaying, wsRecording, wsData);
  TWaveMessage = (waPlayOpen, waPlayDone, waPlayClose,
                 waRecordOpen, waDataReady, waRecordClose);

  {TAPI logging codes}
  TTapiLogCode = (
    ltapiNone,              { None }
    ltapiCallStart,         { Call started }
    ltapiCallFinish,        { Call finished }
    ltapiDial,              { Dialing }
    ltapiAccept,            { Accepting an incoming call }
    ltapiAnswer,            { Answering an incoming call }
    ltapiConnect,           { Connected }
    ltapiCancel,            { Call cancelled }
    ltapiDrop,              { Call drop }
    ltapiBusy,              { Called number was busy }
    ltapiDialFail,          { Dial failed }
    ltapiReceivedDigit);    { Received a DTMF tone }

  {TAPI status event}
  TTapiStatusEvent = procedure(CP : TObject;
                               First, Last : Boolean;
                               Device, Message,
                               Param1, Param2, Param3 : LongInt) of object;

  {TAPI log event}
  TTapiLogEvent = procedure(CP : TObject; Log : TTapiLogCode) of object;

  {TAPI DTMF event}
  TTapiDTMFEvent = procedure(CP : TObject; Digit : Char;
    ErrorCode: LongInt) of object;

  {TAPI Caller ID event}
  TTapiCallerIDEvent =
    procedure(CP : TObject; ID, IDName: string) of object;

  {TAPI wave notify event}
  TTapiWaveNotify = procedure(CP : TObject;
                              Msg : TWaveMessage) of object;

  {TAPI wave silence event}
  TTapiWaveSilence = procedure(CP : TObject;
                               var StopRecording : Boolean;
                               var Hangup : Boolean) of object;

const
  Success = 0;
  WaitErr_WaitAborted  = 1;
  WaitErr_WaitTimedOut = 2;

  LineCallState_Any = 0;

  WaitTimeout = 30000;

  { Base of error strings in the resource }
  TapiErrorBase            = 13800;

  { Base of status strings in the resource }
  TapiStatusBase           = 13500;

  { Offsets from TapiStatusBase for the separate TAPI message classes }
  lcsBase                  = 0;            { Line Call State }
  ldsBase                  = 32;           { Line Device State }
  lrBase                   = 64;           { Line Reply }
  asBase                   = 96;           { Apro-specific }
  lcsdBase                 = 150;          { Line Call State -- Disconnect }

  {Defaults for TApdTapiLog properties}
  DefTapiHistoryName = 'APROTAPI.HIS';

  {Property inits}
  DefMaxAttempts      = 3;
  DefAnsRings         = 2;
  DefRetryWait        = 60;            { seconds }
  DefShowTapiDevices  = True;
  DefShowPorts        = True;
  DefMaxMessageLength = 60;            { 1 minute }
  DefWaveState        = wsIdle;
  DefUseSoundCard     = False;
  DefTrimSeconds      = 2;
  DefSilenceThreshold = 50;
  DefChannels         = 1;
  DefBitsPerSample    = 16;
  DefSamplesPerSecond = 8000;
  DefMonitorRecording = False;                                     

  {Wave Error Types}
  WaveInError   = 1;
  WaveOutError  = 2;
  MMioError     = 3;

  BufferSeconds = 1;
  WaveOutBufferSeconds = 3;

type
  {Forwards}
  TApdAbstractTapiStatus = class;
  TApdTapiLog = class;

  {Custom TAPI component}
  TApdCustomTapiDevice = class(TApdBaseComponent)
  protected
    {private data}
    LineApp            : TLineApp;         {TAPI handle for this application}
    LineExt            : TLineExtensionID; {Line extension data}
    LineHandle         : TLine;            {Handle of the opened line device}
    CallHandle         : TCall;            {Handle of the current call}
    SelectedLine       : Integer;          {Device ID of selected line}
    VS                 : TVarString;       {Used to return Cid}
    DialTimer          : TTimer;           {Timer component}
    RequestedId        : LongInt;          {ID being waited for}
    AsyncReply         : LongInt;          {Requested reply}
    CallState          : LongInt;          {Received CallState}
    ReplyReceived      : Boolean;          {True if Line Reply received}
    CallStateReceived  : Boolean;          {True if CallState received}
    TapiInUse          : Boolean;          {True means a call is active}
    TapiHasOpened      : Boolean;          {True means TAPI has been opened}
    Initializing       : Boolean;          {True during StartTapi}
    Connected          : Boolean;          {True when connected}
    StoppingCall       : Boolean;          {True during HangupCall}
    ShuttingDown       : Boolean;          {True during StopTapi}
    RetryPending       : Boolean;          {True if a retry is pending}
    TapiFailFired      : Boolean;          {True if OnTapiFailed fired}
    ReplyWait          : Boolean;          {True if waiting for reply}
    StateWait          : Boolean;          {True if waiting for call state}
    PassThruMode       : Boolean;          {True if in passthrough mode}
    WaveOutHeader      : PWaveHdr;         {Wave header for playing}
    WaveInHeader       : PWaveHdr;         {Wave header for recording}
    WaveOutHandle      : HWaveOut;         {Handle of the wave out device}
    WaveInHandle       : HWaveIn;          {Handle of the wave in  device}
    BytesRecorded      : LongInt;          {Bytes recorded for this buffer}
    TotalBytesRecorded : LongInt;          {Bytes recorded overall }
    WaveInBuffer1      : Pointer;          {Buffer for wave recording}
    WaveInBuffer2      : Pointer;          {Buffer for wave recording}
    WaveOutBuffer1     : Pointer;          {Buffer for wave playing  }
    WaveOutBuffer2     : Pointer;          {Buffer for wave playing  }
    ActiveBuffer       : Byte;             {The active wave in buffer}
    MmioInHandle       : Integer;          {File handle for recording}
    MmioOutHandle      : Integer;          {File handle for recording}
    RootChunk          : TMMCkInfo;        {Root chunk for wave file}
    DataChunk          : TMMCkInfo;        {Data chunk for wave file}
    TempFileName       : TFileName;        {Temporary file for recording}
    Channels           : Byte;             {# of channels for recording}
    BitsPerSample      : Byte;             {Bits per sample for recording}
    SamplesPerSecond   : Integer;          {Samples per sec for recording}
    WaveInBufferSize   : LongInt;          {# of bytes in a wave in buffer}
    BytesToPlay        : LongInt;          {# of bytes in the wave file}
    BytesPlayed        : LongInt;          {# of bytes already played}
    BytesInBuffer      : LongInt;          {# of bytes in current buffer}
    ActiveWaveOutBuffer: Byte;             {The active wave out buffer}
    WaveOutBufferSize  : LongInt;          {# of bytes in wave out buffer}

    {private data stores}
    FAvgWaveInAmplitude: Integer;         {Average amplitude for recording}
    FCancelled      : Boolean;            {True if call was cancelled}
    FDialing        : Boolean;            {True when dialing, False not}
    FDialTime       : LongInt;            {Elapsed dial time}
    FTapiDevices    : TStrings;           {List of tapi device names}
    FSelectedDevice : string;             {Name of selected device}
    FApiVersion     : LongInt;            {Negotiated version}
    FDeviceCount    : DWORD;              {Number of supported TAPI devices}
    FTrueDeviceCount: DWORD;              {Total number of TAPI devices}
    FOpen           : Boolean;            {True to open a line device}
    FCallInfo       : PCallInfo;          {Holds current call info}
    FComPort        : TApdCustomComPort;  {Attached comport}
    FStatusDisplay  : TApdAbstractTapiStatus; {Built-in status display}
    FTapiLog        : TApdTapiLog;        {Built-in logging component}
    FNumber         : string;             {Last dialed number}
    FMaxAttempts    : Word;               {Max number of dial attempts}
    FAttempt        : Word;               {Dialing attempt number}
    FRetryWait      : Word;               {Seconds between dialing attempts}
    FAnsRings       : Byte;               {Rings to allow before answer}
    FParentHWnd     : HWnd;               {Window handle of parent}
    FShowTapiDevices: Boolean;            {Show TAPI devices}
    FShowPorts      : Boolean;            {Show ports}
    FEnableVoice    : Boolean;            {Monitor DTMF Tones if capable}
    FMaxMessageLength : LongInt;          {Max message length for wave recording}
    FWaveFileName   : TFileName;          {Wave file name}
    FInterruptWave  : Boolean;            {Stops playing wave file on DTMF tone}
    FHandle         : HWnd;               {Window handle for hidden window}
    FWaveState      : TWaveState;         {Current wave device state}
    FUseSoundCard   : Boolean;            {Play the sound through the sound card}
    FSilence        : TLineMonitorTone;
    FTrimSeconds    : Byte;               {Trim silence after x seconds}
    FSilenceThreshold : Integer;          {Silence threshold for trimming}
    FMonitorRecording : Boolean;          {Echo wave recording to sound card}
    FFailCode         : Integer;          {Failure code}               
    FFilterUnsupportedDevices: Boolean;   {Display only supported devices}
    FWaitingForCall: Boolean;             {True if in AutoAnswer mode}   {!!.04}

    {Events}
    FOnTapiCallerID    : TTapiCallerIDEvent;
    FOnTapiConnect     : TNotifyEvent;
    FOnTapiDTMF        : TTapiDTMFEvent;
    FOnTapiFail        : TNotifyEvent;
    FOnTapiLog         : TTapiLogEvent;
    FOnTapiPortClose   : TNotifyEvent;
    FOnTapiPortOpen    : TNotifyEvent;
    FOnTapiStatus      : TTapiStatusEvent;
    FOnTapiWaveNotify  : TTapiWaveNotify;
    FOnTapiWaveSilence : TTapiWaveSilence;

    {Callback virtual methods}
    procedure DoLineCallInfo(Device, P1, P2, P3 : LongInt); virtual;
    procedure DoLineCallState(Device, P1, P2, P3 : LongInt); virtual;
    procedure DoLineClose(Device, P1, P2, P3 : LongInt); virtual;
    procedure DoLineCreate(Device, P1, P2, P3 : LongInt); virtual;
    procedure DoLineDevState(Device, P1, P2, P3 : LongInt); virtual;
    procedure DoLineGenerate(Device, P1, P2, P3 : LongInt); virtual;
    procedure DoLineMonitorDigits(Device, P1, P2, P3 : LongInt); virtual;
    procedure DoLineMonitorMedia(Device, P1, P2, P3 : LongInt); virtual;
    procedure DoLineMonitorTone(Device, P1, P2, P3 : LongInt); virtual;
    procedure DoLineReply(Device, P1, P2, P3 : LongInt); virtual;
    procedure DoLineRequest(Device, P1, P2, P3 : LongInt); virtual;

    function HandleLineErr(LineErr : LongInt): Boolean;
    function HangupCall(AbortRetries : Boolean) : Boolean;
    procedure UpdateCallInfo(Device : LongInt);
    function WaitForCallState(DesiredCallState : LongInt) : LongInt;
    function WaitForReply(ID : LongInt) : LongInt;                  

    {Property access methods}
    procedure SetOpen(NewOpen : Boolean);

    {Private methods}
    procedure AssureTapiReady;
    function  CidFromTapiDevice : LongInt;
    procedure CheckVoiceCapable;                                       
    procedure CheckWaveException(ErrorCode : Integer; Mode : Integer); 
    procedure CheckWaveInSilence;                                      
    function  CloseTapiPort : Boolean;
    procedure CloseWaveFile;
    procedure CreateDialTimer;
    function  DeviceIDFromName(const Name : string) : Integer;
    procedure DialPrim(PassThru : Boolean);
    procedure EnumLineDevices;
    procedure FreeWaveInBuffers;
    procedure FreeWaveOutBuffer;
    function  GetSelectedLine : Integer;                            
    function  GetWaveDeviceId(const Play : Boolean) : DWORD;
    procedure LoadWaveOutBuffer;
    procedure MonitorDTMF(var CallHandle: LongInt;
      const DTMFMode: LongInt);
    procedure OpenTapiPort;
    procedure OpenWaveFile;
    procedure PlayWaveOutBuffer;
    procedure PrepareWaveInHeader;
    function  StartTapi : Boolean;
    function  StopTapi : Boolean;
    procedure TapiDialTimer(Sender : TObject);
    procedure WndProc(var Message : TMessage);
    procedure WriteWaveBuffer;

    {Property access methods}
    function GetBPSRate : DWORD;
    function GetCalledID: string;
    function GetCalledIDName: string;
    function GetCallerID : string;
    function GetCallerIDName : string;
    function GetComNumber : Integer;
    function GetParentHWnd : HWnd;
    function GetTapiState : TTapiState;                       
    procedure SetStatusDisplay(const NewDisplay : TApdAbstractTapiStatus);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -