📄 amstate.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"
char *pszOwnerID="1234";
//---------------------------------------------------------------------------
void OnGatherDigit(LPLINEINFO pLineData)
{
if ( strcmp(pLineData->pszLoginID, pszOwnerID) == 0 ) //chech gather digits is 1234 or not
{
MMRESULT mmrc;
printf("\nLine %d receive code is : %s",pLineData->nLineID, pLineData->pszLoginID);
pLineData->dwCallState &= ~TAPI_PLAYGREET; //clear stop play greet flag
pLineData->dwCallState |= TAPI_PREPAREPLAYICM; //set begin play ICM
pLineData->dwWaveStage = 0;
if ( mmrc = waveOutReset(pLineData->hWaveOut) )
{
printf("\n###Line %d Can't reset wave out error #%x",pLineData->nLineID,mmrc);
pLineData->dwCallState = TAPI_HANGUP;
OnHangUp(pLineData->hCall,pLineData->nLineID);
}
else
{
printf("\nLine %d wave Out reset success.",pLineData->nLineID);
FinishPlay(pLineData); //finish play greet.wav,then play ICM
}
strcpy(pLineData->pszLoginID," ");
}
else
{
printf("\nLine %d receive incorrect code is : %s",pLineData->nLineID,pLineData->pszLoginID);
strcpy(pLineData->pszLoginID," ");
}
}
//---------------------------------------------------------------------------
void OnHangUp(HCALL hCall, DWORD ID)
{
LONG tr = lineDrop(hCall, 0, 0); // drop a call
if( tr > 0 )
{
printf("\nLine %d Call dropping...",ID);
}
else
{
printf("\n###Line %d Can't drop call error#%x.",ID,tr);
}
}
//---------------------------------------------------------------------------
void FinishPlay(LPLINEINFO pLineData)
{ // FinishPlay do waveOutUnprepareHeader
MMRESULT mmrc; // and mmioClose first, then waveOutClose
// at last free lpwavehdr
if (!pLineData->hWaveOut)
{
printf("\n###Line %d wave Out Handle is Null",pLineData->nLineID);
return;
}
mmrc =waveOutUnprepareHeader(pLineData->hWaveOut,pLineData->lpWaveHdr, sizeof(WAVEHDR));
mmrc =waveOutUnprepareHeader(pLineData->hWaveOut,pLineData->lpWaveHdr2, sizeof(WAVEHDR));
mmrc =mmioClose(pLineData->hmmioH, 0);
mmrc = waveOutClose(pLineData->hWaveOut);
if ( mmrc )
{
printf("\n###Line %d wave Out close error #%x!",pLineData->nLineID,mmrc);
} else
{
printf("\nLine %d wave Out close success",pLineData->nLineID);
}
pLineData->hWaveOut = NULL;
free (pLineData->lpWaveHdr);
free (pLineData->lpWaveHdr2);
return;
}
//---------------------------------------------------------------------------
void FinishRecord(LPLINEINFO pLineData)
{ // waveInStop first ,then call mmiowrite write wave data into hmmioH
MMRESULT mmrc; // waveInUnprepareHeader,waveInClose,then free lpwavehdr
if (!pLineData->hWaveIn)
{
printf("\n###Line %d wave In Handle is Null",pLineData->nLineID);
return;
}
waveInStop(pLineData->hWaveIn);
if ( pLineData->wWaveBufState ) //check buf state
{
mmioWrite(pLineData->hmmioH, pLineData->lpWaveHdr2->lpData, pLineData->lpWaveHdr2->dwBytesRecorded);
mmioWrite(pLineData->hmmioH, pLineData->lpWaveHdr->lpData, pLineData->lpWaveHdr->dwBytesRecorded);
}
else
{
mmioWrite(pLineData->hmmioH, pLineData->lpWaveHdr->lpData, pLineData->lpWaveHdr->dwBytesRecorded);
mmioWrite(pLineData->hmmioH, pLineData->lpWaveHdr2->lpData, pLineData->lpWaveHdr2->dwBytesRecorded);
}
waveInUnprepareHeader(pLineData->hWaveIn, pLineData->lpWaveHdr, sizeof(WAVEHDR));
waveInUnprepareHeader(pLineData->hWaveIn, pLineData->lpWaveHdr2, sizeof(WAVEHDR));
mmioAscend(pLineData->hmmioH, &pLineData->mmSubchunk,0); //ascend data chunk
mmioAscend(pLineData->hmmioH, &pLineData->mmParent, 0); //ascend RIFF chunk
mmrc = mmioClose(pLineData->hmmioH, 0); //close hmmioH
mmrc = waveInClose(pLineData->hWaveIn); //close Wave In header
if ( mmrc )
{
printf("\n###Line %d wave In close error# %x!",pLineData->nLineID,mmrc);
}
else
{
printf("\nLine %d wave In close success",pLineData->nLineID);
}
pLineData->hWaveIn = NULL;
free(pLineData->lpWaveHdr);
free(pLineData->lpWaveHdr2);
return;
}
//---------------------------------------------------------------------------
void OnCallState(LPLINEINFO pLineData) //when ADmorelineCallbackFunc receive
{ //LINE_CALLSTATE event ,call this function
MMRESULT mmrc;
LONG tr;
ADCALLBACK pCall = pLineData->pCallBack;
HCALL hCall = (HCALL)pCall.dwDevice;
DWORD nCallState = pCall.dwParam1;
DWORD dwParam2 = pCall.dwParam2;
DWORD nCallPrivilege = pCall.dwParam3;
//printf("\nhcall=%X d1=%X d2=%X d3=%X",hCall,nCallState,dwParam2,nCallPrivilege);
pLineData->hCall = hCall;
struct FlagMap { DWORD nFlag; LPCSTR szFlag; };
static FlagMap aFlags[] = //callstate event
{
{LINECALLSTATE_IDLE, "idle"},
{LINECALLSTATE_ACCEPTED, "accepted"},
{LINECALLSTATE_DIALTONE, "dial tone detected"},
{LINECALLSTATE_DIALING, "dialing"},
{LINECALLSTATE_RINGBACK, "ring-back detected"},
{LINECALLSTATE_BUSY, "busy detected"},
{LINECALLSTATE_SPECIALINFO, "error detected"},
{LINECALLSTATE_CONNECTED, "connected"},
{LINECALLSTATE_PROCEEDING, "proceeding"},
{LINECALLSTATE_DISCONNECTED,"disconnected"},
{LINECALLSTATE_OFFERING, "offering"}
};
for (int i=0; i < 11; i++)
{
if ( aFlags[i].nFlag == nCallState )
{
printf("\nLine %d Call %s", pLineData->nLineID, aFlags[i].szFlag);
break;
}
}
switch( nCallState )
{
case LINECALLSTATE_DISCONNECTED:
switch ( pLineData->dwCallState )
{
case TAPI_PLAYGREET: //play greet.wav ?
case TAPI_PLAYICM: //play Income.wav (ICM)?
pLineData->dwCallState = TAPI_HANGUP;
pLineData->dwWaveStage = 0;
if ( mmrc = waveOutReset(pLineData->hWaveOut) )
{
printf("\n###Line %d Can't reset wave out error #%x",pLineData->nLineID,mmrc);
}
else
{
printf("\nLine %d wave Out reset success.",pLineData->nLineID);
FinishPlay(pLineData);
}
OnHangUp(hCall,pLineData->nLineID);
break;
case TAPI_RECORDICM: //Record Income.wav? (ICM)
pLineData->dwCallState = TAPI_HANGUP;
pLineData->dwWaveStage = 0;
if ( mmrc = waveInReset(pLineData->hWaveIn) )
{
printf("\n###Line %d Can't reset wave in error #%x",pLineData->nLineID,mmrc);
}
else
{
printf("\nLine %d wave In reset success.",pLineData->nLineID);
FinishRecord(pLineData);
}
OnHangUp(hCall,pLineData->nLineID);
break;
case TAPI_PREPAREPLAYICM: //Reppare play ICM now?
pLineData->dwCallState = TAPI_HANGUP;
OnHangUp(hCall,pLineData->nLineID);
break;
} //end switch ( pLineData->dwCallState )
break;
case LINECALLSTATE_IDLE:
lineSetAppSpecific(pLineData->hCall, TAPI_SETAPP_NONE); //set dwAppSpeicfic to 0
tr = lineDeallocateCall(pLineData->hCall);//deallocate Call
if ( tr == NOERR )
printf("\nLine %d linedellocateCall", pLineData->nLineID);
else
printf("\nLine %d linedellocateCall error#%x",pLineData->nLineID,tr);
printf("\nLine %d to wait for income call...", pLineData->nLineID);
break;
case LINECALLSTATE_BUSY:
OnHangUp(pLineData->hCall,pLineData->nLineID);
break;
case LINECALLSTATE_OFFERING: // line get the ring
pLineData->dwCallState = 0;
tr = lineAnswer(hCall,0,0); // answer the call one this line
if( tr > 0 )
{
printf("\nLine %d answer....",pLineData->nLineID);
}
else
{
printf("\n###Line %d answer error #%x....",pLineData->nLineID,tr);
}
pLineData->hCall = hCall;
break;
case LINECALLSTATE_CONNECTED: //line connect message receive after line answer
//gether the digit in pszLoginID[5]
//lineGatherDigits(pLineData->hCall,LINEDIGITMODE_DTMF,
// pLineData->pszLoginID, 4, "*#", 5000, 1500);
//call WavePlay to play Greet.wav in DeviceID
pLineData->hWaveOut = WavePlay(pLineData->dwWaveID,"Greet.wav",pLineData);
if ( pLineData->hWaveOut == NULL ) // wave out open fail
{
OnHangUp(hCall,pLineData->nLineID);
break;
}
pLineData->dwCallState |= TAPI_PLAYGREET;
//gether the digit in pszLoginID[5]
tr=lineGatherDigits(pLineData->hCall,LINEDIGITMODE_DTMF,
pLineData->pszLoginID, 4, "*#", 5000, 1500);
printf("\nLine %d press '1234' to receive Income message...",pLineData->nLineID);
break;
}//end switch case
}
//---------------------------------------------------------------------------
long ADmorelineGetCallInfo(HCALL hCall,LINECALLINFO** ppd)
{ //get LINECALLINFO
DWORD dwNeededSize = sizeof(LINECALLINFO);
LONG tr = 0;
do
{
//Get some more memory if we don't have enough
if( !*ppd || (*ppd)->dwTotalSize < dwNeededSize )
{
*ppd = (LPLINECALLINFO)::realloc(*ppd, dwNeededSize);
if( *ppd )
{
(*ppd)->dwTotalSize = dwNeededSize;
}
else
{
return LINEERR_NOMEM;
}
}
//Fill in the buffer
tr = lineGetCallInfo(hCall, *ppd);
//check how much memory we need
//because TSPs succeed even if the data size is too small
if( (tr == LINEERR_STRUCTURETOOSMALL ) ||
( tr == 0 && (*ppd)->dwTotalSize < (*ppd)->dwNeededSize) )
{
dwNeededSize = (*ppd)->dwNeededSize;
tr = LINEERR_STRUCTURETOOSMALL;
}
}
while( tr == LINEERR_STRUCTURETOOSMALL );
return tr;
}
//---------------------------------------------------------------------------
long ADmoreGetLineDevCaps(HLINEAPP hLineApp, DWORD nApiVersion, DWORD nLineID,
LPLINEINFO pLineInfo, LINEDEVCAPS** ppd)
{ //get LINEDEVCAPS
DWORD dwNeededSize = sizeof(LINEDEVCAPS);
LONG tr = 0;
do
{
//Get some more memory if we don't have enough
if( !*ppd || (*ppd)->dwTotalSize < dwNeededSize )
{
*ppd = (LPLINEDEVCAPS)::realloc(*ppd, dwNeededSize);
if( *ppd )
{
(*ppd)->dwTotalSize = dwNeededSize;
}
else
{
return LINEERR_NOMEM;
}
}
//Fill in the buffer
tr = lineGetDevCaps(hLineApp, nLineID, nApiVersion, 0, *ppd);
//check how much memory we need
//because TSPs succeed even if the data size is too small
if( (tr == LINEERR_STRUCTURETOOSMALL ) ||
( tr == 0 && (*ppd)->dwTotalSize < (*ppd)->dwNeededSize) )
{
dwNeededSize = (*ppd)->dwNeededSize;
tr = LINEERR_STRUCTURETOOSMALL;
}
}
while( tr == LINEERR_STRUCTURETOOSMALL );
if (((*ppd) -> dwLineNameSize) &&
((*ppd) -> dwLineNameOffset) &&
((*ppd) -> dwStringFormat == STRINGFORMAT_ASCII))
{ //get line Name on dwLineOffset
strcpy(pLineInfo->szLineName,
((char *) (*ppd)) + (*ppd) -> dwLineNameOffset);
}
else
{
strcpy(pLineInfo->szLineName,"UnknowName");
}
return tr;
}
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
void OpenLine(LPLINEINFO pLineData) //open voice line
{
LINEDEVCAPS* pldc = 0;
DWORD nLineID = pLineData->nLineID;
if((ADmoreGetLineDevCaps(m_hLineApp, //get line device capability in pldc
pLineData->dwApiVersion,
nLineID,
pLineData,
&pldc)==0) &&
(pldc->dwBearerModes & LINEBEARERMODE_VOICE) &&
(pldc->dwMediaModes & LINEMEDIAMODE_INTERACTIVEVOICE) &&
(pldc->dwLineFeatures & LINEFEATURE_MAKECALL) )
{
if( lineOpen(m_hLineApp, nLineID, &pLineData->hLine, pLineData->dwApiVersion,
0, 0, LINECALLPRIVILEGE_OWNER, LINEMEDIAMODE_INTERACTIVEVOICE, NULL)==0 )
{
//easy for user look ch1 ~ ch(m_nLines), not ch0 ~ ch(m_nLines-1)
pLineData->nLineID++;
/*get line device ID */
lpDeviceID->dwTotalSize = sizeof (VARSTRING) + 64;
lineGetID(pLineData->hLine, 0, 0, LINECALLSELECT_LINE, lpDeviceID,"tapi/line");
pLineData->dwLineID = (DWORD) *((BYTE*)lpDeviceID+sizeof(VARSTRING));
FillMemory(lpDeviceID,sizeof (VARSTRING) + 64, 'f'); //fill lpdevice with 'f' byte
/*get wave device ID */
lpDeviceID->dwTotalSize = sizeof (VARSTRING) + 64;
lineGetID(pLineData->hLine, 0, 0, LINECALLSELECT_LINE, lpDeviceID,"wave/out");
pLineData->dwWaveID = (DWORD) *((BYTE*)lpDeviceID+sizeof(VARSTRING));
FillMemory(lpDeviceID,sizeof (VARSTRING) + 64, 'f'); //fill lpdevice with 'f' byte
//delete lpDeviceID;
printf("\nOpen Line %d to wait for income call...(%s)",
pLineData->nLineID,pLineData->szLineName);
}
else
{
printf("\n### Line %d open fail ! (%s)",
++pLineData->nLineID,pLineData->szLineName);
}
}
else
{
printf("\n### Line %d is not device for interactive voice ! (%s)",
++pLineData->nLineID,pLineData->szLineName);
}
free(pldc);
}
//---------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -