www.pudn.com > AM.rar > AM.CPP


#include  
#include  
#include  
#include  
#include  
 
#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;  
}