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