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

📄 am.cpp

📁 VC写的用TAPI实现的自动应答系统(Answering Machine).
💻 CPP
字号:
#include <windows.h>
#include <mmsystem.h>
#include <stdio.h>
#include <conio.h>
#include <TAPI.h>

#include "AM.h"
#include "AMState.h"
#include "Wave.h"

HLINEAPP    m_hLineApp;		// line application header
DWORD	    m_nLines;		// total lines
LPLINEINFO	pLineInfo;		// struct lineinfo_tag define in am.h
LPVARSTRING lpDeviceID;		// VARSTRING for lineGetID param5 use
BYTE lpWaveDataAlloc[64][8192];
BYTE lpWaveDataAlloc2[64][8192];
//---------------------------------------------------------------------------
//all lines message will come here
void CALLBACK ADmorelineCallbackFunc(DWORD dwDevice, DWORD nMsg, DWORD dwCallbackInstance,
									DWORD dwParam1, DWORD dwParam2, DWORD dwParam3)
{
	MMRESULT mmrc;
	char lpFileName[15];
	DWORD cbLineID;
	lpDeviceID->dwTotalSize =  sizeof (VARSTRING) + 64;	      			 
	lineGetID(0, 0, (HCALL)dwDevice, LINECALLSELECT_CALL, lpDeviceID,"tapi/line");
	DWORD dwID = (DWORD) *((BYTE*)lpDeviceID+sizeof(VARSTRING)); // get id for wave out
	FillMemory(lpDeviceID,sizeof (VARSTRING) + 64, 'f');  //fill lpdevice with 'f' byte
	cbLineID = dwID+1;
	if ( dwID >= m_nLines )	  //chech device range
		return;

	//printf("\ndwDevice=%x,nMsg=%x,callInst=%x,p1=%x,p2=%x,p3=%x,dwId=%d,thread=%x", 
	//  dwDevice, nMsg, dwCallbackInstance, dwParam1, dwParam2, dwParam3,dwID,&pLineInfo[dwID]);

	//assign all paramters to struct linecallback_tag (define in am.h)
	ADCALLBACK pCall={dwDevice,nMsg,dwCallbackInstance,dwParam1,dwParam2,dwParam3};	

	switch( nMsg )	   //use param uMsg to determine message
	{
		case LINE_REPLY:
			printf("\nLine %d Call Back ------>LINE_REPLY",cbLineID);
			break;	 

		case LINE_CALLSTATE:
			printf("\nLine %d Call Back ------>LINE_CALLSTATE",cbLineID);
			pLineInfo[dwID].pCallBack =	pCall;
			OnCallState(&pLineInfo[dwID]);	//call OnCallState() to check callstate
            break;
		case LINE_CLOSE:
            // Line has been shut down.
            printf("\nLine %d Call Back ------>LINE_CLOSE",cbLineID);
            break;
        case LINE_CREATE:
            printf("\nLine %d Call Back ------>LINE_CREATE",cbLineID);
            break;
		case LINE_MONITORDIGITS:
            printf("\nLine %d Call Back ------>LINE_MONITORDIGITS",cbLineID);
			if ( dwParam1 == '#')
			{								 //user press # when record will come here
				pLineInfo[dwID].dwCallState = TAPI_HANGUP;
				pLineInfo[dwID].dwWaveStage	= 0;
				if ( mmrc = waveInReset(pLineInfo[dwID].hWaveIn) )
				{
					printf("\n###Line %d Can't reset wave in error #%x",pLineInfo[dwID].nLineID,mmrc);
					pLineInfo[dwID].dwCallState = TAPI_HANGUP;
				}	
				else
				{
					printf("\nLine %d wave in reset success.",pLineInfo[dwID].nLineID);
					FinishRecord(&pLineInfo[dwID]);
				}
				OnHangUp(pLineInfo[dwID].hCall,pLineInfo[dwID].nLineID);
			}
			break;
        case LINE_GATHERDIGITS :
            printf("\nLine %d Call Back ------>LINE_GATHERDIGITS",cbLineID);
			pLineInfo[dwID].pCallBack =	pCall;
			if (pLineInfo[dwID].dwCallState & TAPI_PLAYGREET)
				OnGatherDigit(&pLineInfo[dwID]); //call OnGatherDigit() to check input digits
            break;
		case LINE_GENERATE :
			//line generate tone 
            printf("\nLine %d Call Back ------>LINE_GENERATE",cbLineID);
			//lineGatherDigits(pLineInfo[dwID].hCall,LINEDIGITMODE_DTMF,pLineInfo[dwID].pszRecStop,10,"#",3000,15000);
			lineMonitorDigits(pLineInfo[dwID].hCall, LINEDIGITMODE_DTMF);
			break;
		case LINE_CALLINFO :
			printf("\nLine %d Call Back ------>LINE_CALLINFO",cbLineID);
			if ((dwParam1==LINECALLINFOSTATE_APPSPECIFIC) &&     //check dwAppSpecific state
						(pLineInfo[dwID].dwCallState!=TAPI_HANGUP))	//check call is alive
			{	
				//get dwAppSpecific of LPLINECALLINFO
				ADmorelineGetCallInfo(pLineInfo[dwID].hCall,&pLineInfo[dwID].lpCallInfo);
				printf("\n@@@Line %d CallInfo lpCallInfo->dwAppSpecific=%x",cbLineID,pLineInfo[dwID].lpCallInfo->dwAppSpecific);
				switch(pLineInfo[dwID].lpCallInfo->dwAppSpecific)
				{
					case TAPI_SETAPP_ENDPLAYGREET:            //finish play greet.wav first,  
						pLineInfo[dwID].dwCallState &= ~TAPI_PLAYGREET;
						FinishPlay(&pLineInfo[dwID]);	      //then call WaveRecord Rec ICM
						pLineInfo[dwID].dwCallState |= TAPI_RECORDICM;
						pLineInfo[dwID].hWaveIn = WaveRecord(pLineInfo[dwID].dwWaveID, 160000,&pLineInfo[dwID]);	   //record max 20 sec
						//lineMonitorDigits(pLineInfo[dwID].hCall, LINEDIGITMODE_DTMF);
						//lineGenerateTone(pLineInfo[dwID].hCall,LINETONEMODE_BEEP,300,0,0); //pLineInfo->hCall
						//Sleep(500);
						//pLineInfo[dwID].hWaveIn = WaveRecord(pLineInfo[dwID].dwWaveID, 160000,&pLineInfo[dwID]);	   //record max 20 sec
						if ( pLineInfo[dwID].hWaveIn == NULL )		  // wave out open fail
						{
							pLineInfo[dwID].dwCallState &= ~TAPI_RECORDICM;
							pLineInfo[dwID].dwCallState = TAPI_HANGUP;
							OnHangUp(pLineInfo[dwID].hCall,pLineInfo[dwID].nLineID);
							break;
						}
						lineGenerateTone(pLineInfo[dwID].hCall,LINETONEMODE_BEEP,300,0,0); //pLineInfo->hCall
						break;
					case TAPI_SETAPP_PREPAREPLAYICM:  //prepare play InCoMe.wav (ICM)
						wsprintf(lpFileName,"income%d.wav",pLineInfo[dwID].nLineID);
						if (pLineInfo[dwID].dwCallState==TAPI_PLAYICM) break;
						pLineInfo[dwID].dwCallState &= ~TAPI_PREPAREPLAYICM;
						pLineInfo[dwID].hWaveOut = WavePlay(pLineInfo[dwID].dwWaveID,lpFileName,&pLineInfo[dwID]);
						pLineInfo[dwID].dwCallState |= TAPI_PLAYICM;
						if ( pLineInfo[dwID].hWaveOut == NULL ) // wave out open fail
						{
							pLineInfo[dwID].dwCallState = TAPI_HANGUP;
							OnHangUp(pLineInfo[dwID].hCall,pLineInfo[dwID].nLineID);
						}
						break;
					case TAPI_SETAPP_ENDPLAYICM:  //end play Incoming (ICM) wave file
						pLineInfo[dwID].dwCallState = TAPI_HANGUP;
						FinishPlay(&pLineInfo[dwID]);
						OnHangUp(pLineInfo[dwID].hCall,pLineInfo[dwID].nLineID);
						break;
					case TAPI_SETAPP_ENDRECORDICM:	//end record ICM wave file
						pLineInfo[dwID].dwCallState = TAPI_HANGUP;
						FinishRecord(&pLineInfo[dwID]);
						OnHangUp(pLineInfo[dwID].hCall,pLineInfo[dwID].nLineID);
						break;
					case TAPI_SETAPP_ADDPLAYSTAGE:	
						//read next wave date into lpWaveDataAlloc
						//(lpWaveDataAlloc2 is still play now)
						waveOutUnprepareHeader(pLineInfo[dwID].hWaveOut,pLineInfo[dwID].lpWaveHdr, sizeof(WAVEHDR));
						pLineInfo[dwID].dwPlaySize = pLineInfo[dwID].dwDataSize > WAVEBUFSIZE ? WAVEBUFSIZE : pLineInfo[dwID].dwDataSize;
						mmioRead(pLineInfo[dwID].hmmioH, (HPSTR) pLineInfo[dwID].lpWaveDataAlloc, pLineInfo[dwID].dwPlaySize);
						pLineInfo[dwID].dwDataSize -= pLineInfo[dwID].dwPlaySize;
						//pLineInfo[dwID].lpWaveHdr->lpData = pLineInfo[dwID].lpWaveDataAlloc;
						pLineInfo[dwID].lpWaveHdr->dwBufferLength = pLineInfo[dwID].dwPlaySize;
						waveOutPrepareHeader (pLineInfo[dwID].hWaveOut, pLineInfo[dwID].lpWaveHdr, sizeof(WAVEHDR));
						waveOutWrite (pLineInfo[dwID].hWaveOut, pLineInfo[dwID].lpWaveHdr, sizeof (WAVEHDR));
						pLineInfo[dwID].wWaveBufState=1;
						break;
					case TAPI_SETAPP_ADDPLAYSTAGE2:  
						//read next wave date into lpWaveDataAlloc2
						//(lpWaveDataAlloc is still play now)
						waveOutUnprepareHeader(pLineInfo[dwID].hWaveOut,pLineInfo[dwID].lpWaveHdr2, sizeof(WAVEHDR));
						pLineInfo[dwID].dwPlaySize = pLineInfo[dwID].dwDataSize > WAVEBUFSIZE ? WAVEBUFSIZE : pLineInfo[dwID].dwDataSize;
						mmioRead(pLineInfo[dwID].hmmioH, (HPSTR) pLineInfo[dwID].lpWaveDataAlloc2, pLineInfo[dwID].dwPlaySize);
						pLineInfo[dwID].dwDataSize -= pLineInfo[dwID].dwPlaySize;
						//pLineInfo[dwID].lpWaveHdr2->lpData = pLineInfo[dwID].lpWaveDataAlloc2;
						pLineInfo[dwID].lpWaveHdr2->dwBufferLength = pLineInfo[dwID].dwPlaySize;
						waveOutPrepareHeader (pLineInfo[dwID].hWaveOut, pLineInfo[dwID].lpWaveHdr2, sizeof(WAVEHDR));
						waveOutWrite (pLineInfo[dwID].hWaveOut, pLineInfo[dwID].lpWaveHdr2, sizeof (WAVEHDR));
						pLineInfo[dwID].wWaveBufState=0;
						break;
					case TAPI_SETAPP_ADDRECORDSTAGE:
						//read  wave date lpWaveHdr1 into hmmioH
						//(lpWaveHdr2 is still record now)
						mmioWrite(pLineInfo[dwID].hmmioH, pLineInfo[dwID].lpWaveHdr->lpData, pLineInfo[dwID].lpWaveHdr->dwBytesRecorded);
						pLineInfo[dwID].dwPlaySize = pLineInfo[dwID].dwDataSize > WAVEBUFSIZE ? WAVEBUFSIZE : pLineInfo[dwID].dwDataSize;
						pLineInfo[dwID].lpWaveHdr->dwBufferLength = pLineInfo[dwID].dwPlaySize;
						waveInAddBuffer(pLineInfo[dwID].hWaveIn, pLineInfo[dwID].lpWaveHdr, sizeof(WAVEHDR));
						pLineInfo[dwID].dwDataSize -= pLineInfo[dwID].dwPlaySize;
						pLineInfo[dwID].wWaveBufState=1;
						break;
					case TAPI_SETAPP_ADDRECORDSTAGE2:
						//read  wave date lpWaveHdr2 into hmmioH
						//(lpWaveHdr is still record now)
						mmioWrite(pLineInfo[dwID].hmmioH, pLineInfo[dwID].lpWaveHdr2->lpData, pLineInfo[dwID].lpWaveHdr2->dwBytesRecorded);
						pLineInfo[dwID].dwPlaySize = pLineInfo[dwID].dwDataSize > WAVEBUFSIZE ? WAVEBUFSIZE : pLineInfo[dwID].dwDataSize;
						pLineInfo[dwID].lpWaveHdr2->dwBufferLength = pLineInfo[dwID].dwPlaySize;
						waveInAddBuffer(pLineInfo[dwID].hWaveIn, pLineInfo[dwID].lpWaveHdr2, sizeof(WAVEHDR));
						pLineInfo[dwID].dwDataSize -= pLineInfo[dwID].dwPlaySize;
						pLineInfo[dwID].wWaveBufState=0;
						break;
				}  //end switch
			}  //end if 
			break;
        default:
            printf("\n???Line %d Call Back ------>lineCallbackFunc message ignored uMsg=%x",cbLineID,nMsg);
            break;
	}
}	
//---------------------------------------------------------------------------
long InitializeLines(DWORD dwLoVersion, DWORD dwHiVersion)
{
	DWORD m_aApiVersions;

	LONG tr = lineInitialize(&m_hLineApp,			   //lineInitialize get total lines
								(HINSTANCE)pLineInfo,  //and application header 
								ADmorelineCallbackFunc,//and indicate callback function
								"ADmore",			   //name for the application
								&m_nLines);			   //total line in device
	if ( tr == 0 )										 
	{										 
		/* Allocation a block memory to all channel */
		pLineInfo = new LINEINFO[m_nLines];
		ZeroMemory(pLineInfo,sizeof(LINEINFO)*m_nLines);

		if( m_nLines )
		{
			//Negotiate the API versions
			LINEEXTENSIONID extid;
			for(WORD nLineID=0; nLineID < m_nLines; nLineID++)		 //m_nLines
			{
				tr = lineNegotiateAPIVersion(m_hLineApp,
												nLineID,
												dwLoVersion,
												dwHiVersion,
												&m_aApiVersions,
												&extid);
				if( tr < 0 )
				{
					pLineInfo[nLineID].dwApiVersion = 0;
					tr = 0;
				}
				else
				{
					pLineInfo[nLineID].dwApiVersion = m_aApiVersions;
				}
				//alloc two buffer to save wave data
				pLineInfo[nLineID].lpWaveDataAlloc = (HPSTR)lpWaveDataAlloc[nLineID];
				//	                      (HPSTR) LocalAlloc(LMEM_FIXED, WAVEBUFSIZE);
				pLineInfo[nLineID].lpWaveDataAlloc2 = (HPSTR)lpWaveDataAlloc2[nLineID];
				//	                      (HPSTR) LocalAlloc(LMEM_FIXED, WAVEBUFSIZE);
				pLineInfo[nLineID].nLineID = nLineID;
			}//end for
		}
	}
	return tr;
}
//===========================================================================
// Main Program
//===========================================================================
int main(int argc,char **argv)
{
	MSG msg;
	BOOL fSuccess;
	
	lpDeviceID = (LPVARSTRING) new char[sizeof(VARSTRING) + 64];	
	lpDeviceID->dwTotalSize =  sizeof (VARSTRING) + 64;	      			 


	fSuccess = SetConsoleCtrlHandler((PHANDLER_ROUTINE) ExitCtrlHandler	//handle function
		                                                    , TRUE);  //add to list
	if (!fSuccess)
		printf("\nCound not set control handler.");
	SetProcessShutdownParameters(0x280, SHUTDOWN_NORETRY);//terminates without displaying 
														  //a retry dialog box for the user.

	if (InitializeLines(TAPI_VERSION_1_0, TAPI_VERSION_2_0) != NOERR)
	{
		printf("\n\rFail to initialize driver !");
		exit(0);
	}
	printf("\n\rTotal %d channels supported.", m_nLines);

	for (WORD i = 0; i < m_nLines; i++)
	{
		OpenLine(&pLineInfo[i]);	  //call open line to open line
	}


	while (GetMessage(&msg, NULL, 0, 0))
    {
		TranslateMessage(&msg);
        DispatchMessage(&msg); 
    }
	/* program exits in ExitCtrlHandler*/	
	return 1;		//satisfy compiler only
}
//---------------------------------------------------------------------------
// End Main
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
/* program exits in ExitCtrlHandler*/	
BOOL ExitCtrlHandler(DWORD fdwCtrlType)		
{	
	LONG tr; 

	delete lpDeviceID;

	tr = lineShutdown(m_hLineApp);
	
	if ( tr == NOERR )
	{
		printf("\nLine Shutdown.");
	}
	else
	{
		printf("\nLine Shutdown error#%x",tr);
	}

	//for (DWORD i = 0; i < m_nLines; i++)		//free two buffer 
	//{
	//	if (pLineInfo[i].lpWaveDataAlloc)
	//		LocalFree(pLineInfo[i].lpWaveDataAlloc);
	//	if (pLineInfo[i].lpWaveDataAlloc2)
	//		LocalFree(pLineInfo[i].lpWaveDataAlloc2);
	//}

	delete pLineInfo;
	ExitProcess(1);

	return FALSE; 
}

⌨️ 快捷键说明

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