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

📄 tele.cpp

📁 电信语音系统源码
💻 CPP
字号:
#include <Windows.h>
#include <StdLib.h>
#include <String.h>
#include <StdArg.h>
#include <Dos.h>

#include "Tele.h"

#define MAX_CHANNEL 4
#define MAX_FILE ( CN_LAST + 10 )

static char* VoiceFiles[ MAX_FILE ] =
{
   NULL,       // 0: CN_END,
   NULL,       // 1: CN_NOTHING
   "0.VOC",    // 2
   "1.VOC",    // 3
   "2.VOC",    // 4
   "3.VOC",    // 5
   "4.VOC",    // 6
   "5.VOC",    // 7
   "6.VOC",    // 8
   "7.VOC",    // 9
   "8.VOC",    // A
   "9.VOC",    // B
   "Shi.VOC",  // C
   "Bai.VOC",  // E
   "Qian.VOC", // F
   "Wan.VOC",  // 10
   "Yi.VOC",   // 11
   "Dian.VOC", // 12
   "Fu.VOC",   // 13

   "Yuan.VOC", // 14
   "Jiao.VOC", // 15
   "Fen.VOC",  // 16
};

static char* ChannelVoiceFiles[ MAX_CHANNEL ][ MAX_FILE ];

struct MTeleMsg
{
   UINT uMsg;
   char* lpParam;
   WORD wParam;
   WORD wStatus;
   BOOL ( *Hook )( MMsg& msg );
};

enum
{
   stStart,
   stCheckSignal,
   stProcess,
   stEnd,
};

static MTeleMsg teleMsg[ MAX_CHANNEL ];

static BOOL DefaultTeleHook( MMsg& )
{
   return TRUE;
}

void SetTeleHook( int nChannel, BOOL ( *HookFunc )( MMsg& ) )
{
   teleMsg[ nChannel ].Hook = HookFunc;
}

static void inline ClearTeleMsg( int nChannel )
{
   SendTeleMsg( nChannel, tmNull, NULL );
}

void ResetTeleHook( int nChannel )
{
   ClearTeleMsg( nChannel );
   teleMsg[ nChannel ].Hook = DefaultTeleHook;
   HangUp( nChannel );
}

void SendTeleMsg( int nChannel, UINT uMsg, char* lpParam, WORD wParam )
{
   teleMsg[ nChannel ].uMsg = uMsg;
   teleMsg[ nChannel ].lpParam = lpParam;
   teleMsg[ nChannel ].wParam = wParam;
   teleMsg[ nChannel ].wStatus = stStart;
}

void PlaySentence( int nChannel, ... )
{
   va_list ap;
   va_start( ap, nChannel );

   static char szSentence[ MAX_CHANNEL ][ 50 ];
   int nPtr = CN_LAST;
   char *pSentence = szSentence[ nChannel ],
        *arg;
   //while( ( arg = va_arg( ap, char* ) ) != NULL )
   while( FP_OFF( arg = va_arg( ap, char* ) ) )
   {
      if( *arg >= 'A' && *arg <= 'Z' )
      {
         *pSentence ++ = nPtr;
         ChannelVoiceFiles[ nChannel ][ nPtr ++ ] = arg;
      }
      else
      {
         TW_MakeSentence( atof( arg ), pSentence );
         char *p = strchr( pSentence, CN_POINT );
         if( p != NULL )
         {
            *p = CN_YUAN;
            int nFen  = p[ 2 ];
            p[ 2 ] = CN_JIAO;
            p[ 3 ] = 0;
            if( nFen != 0 )
            {
               p[ 3 ] = nFen;
               p[ 4 ] = CN_FEN;
               p[ 5 ] = 0;
            }
         }
         else
         {
            p = pSentence + strlen( pSentence );
            p[ 0 ] = CN_YUAN;
            p[ 1 ] = 0;
         }
         pSentence += strlen( pSentence );
      }
   }
   va_end( ap );
   *pSentence = 0;
   SendTeleMsg( nChannel, tmPlaySentence, szSentence[ nChannel ] );
}

static BOOL Failed( int nChannel )
{
   WORD nSigCount, nSigLen;
   int nSignal = TW_CheckSignal( nChannel, &nSigCount, &nSigLen );
   if( ( ( nSignal == SIG_BUSY1 ||
           nSignal == SIG_BUSY2 ) && nSigCount >= 3 ) ||
       TW_TimerElapsed( nChannel ) < 0
     )
   {
      //HangUp( nChannel );
      return TRUE;
   }
   else return FALSE;
}

static BOOL PlayFailed( int nChannel )
{
   if( TW_MonitorBusy( nChannel, SIG_BUSY1, 5 ) ||
       TW_MonitorBusy( nChannel, SIG_BUSY2, 5 ) )
   {
      TW_StopPlayFile( nChannel ); // 对方挂机
      //HangUp( nChannel );
      return TRUE;
   }
   else return FALSE;
}

static BOOL bOffHook[ MAX_CHANNEL ];
static int nCounter[ MAX_CHANNEL ];
static char szNumber[ MAX_CHANNEL ][ 30 ];

static BOOL bFirstNumber[ MAX_CHANNEL ];
static void InitGetANumber( int nChannel )
{
   bFirstNumber[ nChannel ] = TRUE;
}

static BOOL GetANumber( int nChannel )
{
   int ch = TW_GetDTMFChar( nChannel );
   if( ch == -1 ) return FALSE;
   if( bFirstNumber[ nChannel ] && ch == '4' )
   {
      bFirstNumber[ nChannel ] = FALSE;
      return FALSE;
   }
   else
   {
      szNumber[ nChannel ][ nCounter[ nChannel ] ++ ] = ch;
      return TRUE;
   }   
}

void OffHook( int nChannel )
{
   TW_OffHookCtrl( nChannel );
   bOffHook[ nChannel ] = TRUE;
   TW_FlushDTMF( nChannel );
   nCounter[ nChannel ] = 0;
}

void HangUp( int nChannel )
{
   TW_HangUpCtrl( nChannel );
   bOffHook[ nChannel ] = FALSE;
}

//static BOOL bReverse = FALSE; /* You can change to TRUE */
BOOL GetTeleMsg( MMsg& msg )
{
   for( int nChannel = 0; nChannel < MAX_CHANNEL; nChannel ++ )
   {
      //TW_VoiceData = ChannelVoiceFiles[ nChannel ];
      TW_SetVoice( ChannelVoiceFiles[ nChannel ] );
      BOOL bResult = FALSE;
      msg.uMsg = WM_MESSAGE;
      msg.lParam = nChannel;

      WORD nSignal, nSigCount, nSigLen;
      if( !bOffHook[ nChannel ] && TW_RingDetect( nChannel ) > 1 )
      {
         OffHook( nChannel );
         msg.wParam = tmRing;
         bResult = TRUE;
      }
      else switch( teleMsg[ nChannel ].uMsg )
      {
         case tmDialing:
           switch( teleMsg[ nChannel ].wStatus )
           {
              case stStart:
                // 等待拨号音
                OffHook( nChannel );
                TW_StartTimer( nChannel, 4 );
                teleMsg[ nChannel ].wStatus = stCheckSignal;
                break;
              case stCheckSignal:
                nSignal = TW_CheckSignal( nChannel, &nSigCount, &nSigLen );
                if( nSignal == SIG_DIAL )
                {
                    // 拨号...
                   TW_StartDial( nChannel, teleMsg[ nChannel ].lpParam );
                   teleMsg[ nChannel ].wStatus = stProcess;
                }
                else if( nSignal != SIG_UNKNOWN )
                {
                   HangUp( nChannel );
                   ClearTeleMsg( nChannel );
                   msg.wParam = tmDialingError;
                   bResult = TRUE; // 未检测到拨号音
                }
                break;
              case stProcess:
                if( TW_DialRest( nChannel ) == 0 )
                {
                   // 等待对方摘机...
                   TW_StartTimer( nChannel, 30 );
                   TW_StartMonitor( nChannel );
                   teleMsg[ nChannel ].wStatus = stEnd;
                }
                break;
              case stEnd:         // 只适用于有极性反转功能的线路
                /*if( ( bReverse && TW_ListenerOffHook( nChannel ) ) ||
                    ( !bReverse && TW_MonitorOffHook( nChannel, 25 ) ) // 1 Second
                  )*/
                if( TW_ListenerOffHook( nChannel ) ||
                    TW_MonitorOffHook( nChannel, 25 ) ) // 1 Second
                {
                   ClearTeleMsg( nChannel );
                   msg.wParam = tmDialingOK;
	           bResult = TRUE; // 对方摘机
                }
                else if( Failed( nChannel ) )
                {
                   ClearTeleMsg( nChannel );
                   msg.wParam = tmDialingError;
                   bResult = TRUE; //忙音或超时
                }
                break;
           }
           break;

         case tmGetNumber:
           int ch;
           switch( teleMsg[ nChannel ].wStatus )
           {
              case stStart:
                TW_FlushDTMF( nChannel );  // If Max_channel >= 4
                TW_StartTimer( nChannel, 30 );
                teleMsg[ nChannel ].wStatus = stProcess;
                break;
              case stProcess:
                if( Failed( nChannel ) )
                {
                   ClearTeleMsg( nChannel );
                   msg.wParam = tmGetNumberError;
                   bResult = TRUE; //对方已挂机或超时
                }
                else if( ( ch = TW_GetDTMFChar( nChannel ) ) != -1 )
                {
                   szNumber[ nChannel ][ nCounter[ nChannel ] ++ ] = ch;
                   szNumber[ nChannel ][ nCounter[ nChannel ] ] = 0;
                   strcpy( teleMsg[ nChannel ].lpParam, szNumber[ nChannel ] );
                   if( nCounter[ nChannel ] == teleMsg[ nChannel ].wParam
                       || ch == '#' )
                   {
                      ClearTeleMsg( nChannel );
                      msg.wParam = tmGetNumberOK;
                      bResult = TRUE; //拨号成功
                   }
                   else
                   {
                      msg.wParam = tmGetANumber;
                      bResult = TRUE; //Get a Number
                   }
                }
                break;
           }
           break;

         case tmPlayFile:
           switch( teleMsg[ nChannel ].wStatus )
           {
              case stStart:
                InitGetANumber( nChannel );
                if( TW_StartPlayFile( nChannel, teleMsg[ nChannel ].lpParam,
                                      0l, 0x7fffffffl ) == -1 )
                {
                   HangUp( nChannel );
                   ClearTeleMsg( nChannel );
                   msg.wParam = tmPlayFileError;
                   bResult = TRUE; //文件播放失败
                }
                else teleMsg[ nChannel ].wStatus = stProcess;
                break;
              case stProcess:
                if( TW_PlayFileRest( nChannel ) == 0 )
                {
                   ClearTeleMsg( nChannel );
                   msg.wParam = tmPlayFileOK;
                   bResult = TRUE; //文件播放成功
                }
                else if( PlayFailed( nChannel )
                         || GetANumber( nChannel )  
                       )
                {
                   ClearTeleMsg( nChannel );
                   msg.wParam = tmPlayFileError;
                   bResult = TRUE; //文件播放失败
                }
                break;
           }
           break;

         case tmPlaySentence:
           switch( teleMsg[ nChannel ].wStatus )
           {
              case stStart:
                if( TW_PlaySentence( nChannel,
                                     teleMsg[ nChannel ].lpParam ) == -1 )
                {
                   HangUp( nChannel );
                   ClearTeleMsg( nChannel );
                   msg.wParam = tmPlaySentenceError;
                   bResult = TRUE; //句子播放失败
                }
                else teleMsg[ nChannel ].wStatus = stProcess;
                break;
              case stProcess:
                if( TW_PlaySentenceRest( nChannel ) == 0 )
                {
                   ClearTeleMsg( nChannel );
                   msg.wParam = tmPlaySentenceOK;
                   bResult = TRUE; //句子播放成功
                }
                else if( PlayFailed( nChannel ) )
                {
                   ClearTeleMsg( nChannel );
                   msg.wParam = tmPlaySentenceError;
                   bResult = TRUE; //句子播放失败
                }
                break;
           }
           break;
      }

      if( !bResult ) msg.uMsg = WM_NULL;
      teleMsg[ nChannel ].Hook( msg );
   }
   return FALSE;
}

BOOL InitTele()
{
   //if( TW_Installed() < 1 ) return FALSE;

   int nChannelCount = TW_Installed();
   TW_Initialize();
   TW_CompressRatio( RATE_64K );
   //extern int TW_CloseFile = 1;  // For Dos
   //TW_SetClose( 1 );

   // For Dos
   //static unsigned VoiceLen[ MAX_FILE ];
   //for( int i = 0; i < MAX_FILE; i++ ) VoiceLen[ i ] = FILE_FLAG;
   //TW_VoiceLen = VoiceLen;

   for( int nChannel = 0; nChannel < MAX_CHANNEL; nChannel ++ )
   {
      bOffHook[ nChannel ] = FALSE;
      memcpy( ChannelVoiceFiles[ nChannel ], VoiceFiles,
              MAX_FILE * sizeof( char * ) );
      ResetTeleHook( nChannel );
   }
   TW_PulseMode( 0x00 );
   //return TRUE;
   return ( nChannelCount >= 1 );
}

⌨️ 快捷键说明

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