📄 am.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 + -