TAPICALL.CPP
资源名称:tapi3.zip [点击查看]
上传用户:chinamans
上传日期:2013-03-17
资源大小:202k
文件大小:11k
源码类别:
TAPI编程
开发平台:
Visual C++
- // tapicall.cpp : implementation file for CTapiCall
- // (c) Dialogic corp 1995, 1996
- #include "stdafx.h"
- #include <tapi.h>
- #include "tapiapp.h"
- #include "tapiline.h"
- #include <mmsystem.h>
- #include "wavstate.h"
- #include "wavex.h"
- //#include "wavexg.h"
- #include "tapicall.h"
- #include "devspec.h"
- #ifdef _DEBUG
- #undef THIS_FILE
- static char BASED_CODE THIS_FILE[] = __FILE__;
- #endif
- char g_szDigits[128];
- //static DWORD dwStateTrans[] = {MAKELONG(IDLE, MAKING), MAKELONG(MAKING, CONNECTED),
- // MAKELONG(MAKING, DROPPING), MAKELONG(CONNECTED, HOLD), MAKELONG(HOLD, CONNECTED),
- // MAKELONG(CONNECTED, DISCONNECTED), MAKELONG(HOLD, IDLE), MAKELONG(HOLD, DISCONNECTED),
- // MAKELONG(CONNECTED, DROPPING), MAKELONG(HOLD, DROPPING)}
- /////////////////////////////////////////////////////////////////////////////
- // CTapiCall
- IMPLEMENT_DYNCREATE(CTapiCall, CObject)
- CTapiCall::CTapiCall()
- {
- m_pctLine = NULL;
- m_hCall = NULL;
- m_CallState.wCallState = IDLE;
- m_CallState.wCallDirection = IDLE;
- m_CallState.dwTapiCallState = 0L;
- m_CallState.dwErrors = 0L;
- m_hStateSem = CreateMutex(NULL, FALSE, "TALKER32_CALL_STATE");
- m_MonitorState.wState = IDLE;
- m_MonitorState.dwGatherResult = 0;
- m_hMonitorStateSem = CreateMutex(NULL, FALSE, "TALKER32_DIGITS_MONITOR");
- m_pWave = NULL;
- m_hStatusWnd = NULL;
- m_hCallAlertWnd = NULL;
- m_dwCallAlert = NULL;
- }
- CTapiCall::CTapiCall(HCALL hCall, CTapiLine *lpLine)
- {
- m_pctLine = lpLine;
- m_hCall = hCall;
- m_CallState.wCallState = IDLE;
- m_CallState.wCallDirection = IDLE;
- m_CallState.dwTapiCallState = 0L;
- m_CallState.dwErrors = 0L;
- m_hStateSem = CreateMutex(NULL, FALSE, "TALKER32_CALL_STATE");
- m_MonitorState.dwGatherResult = 0;
- m_MonitorState.wState = IDLE;
- m_hMonitorStateSem = CreateMutex(NULL, FALSE, "TALKER32_DIGITS_MONITOR");
- m_pWave = NULL;
- m_hStatusWnd = NULL;
- m_hCallAlertWnd = NULL;
- m_dwCallAlert = NULL;
- }
- CTapiCall::~CTapiCall()
- {
- ResetWave();
- WaitForSingleObject(m_hMonitorStateSem, 2000);
- CloseHandle(m_hMonitorStateSem);
- }
- // verify & update the state
- BOOL CTapiCall::UpdateCallState(WORD wCallState, WORD wDirection,
- DWORD dwTapiCallState, DWORD dwErrors)
- {
- // put some protection & verification here
- TRACE("*** TALKER32 ***: UpdateCallState hCall=%lx state=%d TAPIstate=%lx entering wait for semn",
- m_hCall, wCallState, dwTapiCallState);
- DWORD dwrc = WaitForSingleObject(m_hStateSem, 15000);
- if(dwrc != WAIT_OBJECT_0)
- {
- TRACE("*** TALKER32 ***: Update Call state wait for sem failed rc=%lxn",dwrc);
- return FALSE;
- }
- if(wCallState != 0xffff) m_CallState.wCallState = wCallState;
- if(wDirection != 0xffff) m_CallState.wCallDirection = wDirection;
- if(dwTapiCallState != 0xffff) m_CallState.dwTapiCallState = dwTapiCallState;
- m_CallState.dwErrors |= dwErrors;
- TRACE("*** TALKER32 ***: UpdateCallState releasing mutexn");
- ReleaseMutex(m_hStateSem);
- return TRUE;
- }
- // Start or end monitoring
- LONG CTapiCall::MonitorDigits(DWORD dwMode)
- {
- LONG lrc = lineMonitorDigits(m_hCall, dwMode);
- if(lrc) return lrc;
- UpdateMonitorState(dwMode ? MONITOR_DIGITS:RESET_MONITOR_DIGITS, 0, 0); // start
- return lrc;
- }
- LONG CTapiCall::GatherDigits(DWORD dwNumDigits, LPCSTR lpszTermDigits,
- DWORD dwFirstDigitTimeout, DWORD dwInterDigitTimeout, LPSTR lpBuf)
- {
- LONG lrc;
- if(lpBuf == NULL)
- {
- lpBuf = m_szDigits; // default to internal buffer
- if(dwNumDigits >= sizeof(m_szDigits)) // safety is first!!!
- {
- AfxMessageBox("Number of digits requested is more than default buffer size, resetting to 31");
- dwNumDigits = sizeof(m_szDigits) - 1;
- }
- }
- if(!dwNumDigits) // cancel current
- {
- TRACE("***: Cancelling Gather!!! n");
- return lineGatherDigits(m_hCall, LINEDIGITMODE_DTMF, NULL, 1, "", 100, 100);
- }
- //UpdateMonitorState(START_GATHER, 0, 0); // start
- TRACE("***: Calling Gather num=%d, Term=%s, buf=%lxn",dwNumDigits, lpszTermDigits, lpBuf);
- //memset(lpBuf, 0, dwNumDigits); // init buffer
- lrc = lineGatherDigits(m_hCall, LINEDIGITMODE_DTMF, lpBuf,
- dwNumDigits, lpszTermDigits,dwFirstDigitTimeout, dwInterDigitTimeout);
- if(lrc) return lrc;
- UpdateMonitorState(START_GATHER, 0, 0); // start
- return lrc;
- }
- // read the monitor state
- BOOL CTapiCall::GetMonitorState(PMONITORSTATE pMonState)
- {
- if(pMonState == NULL) return FALSE; //user-supplied
- TRACE("*** TALKER32 ***: GetMonitorState hCall=%lx entering wait for semn", m_hCall);
- DWORD dwrc = WaitForSingleObject(m_hMonitorStateSem, 5000);
- if(dwrc != WAIT_OBJECT_0)
- {
- TRACE("*** TALKER32 ***: Get Monitor state wait for sem failed rc=%lxn",dwrc);
- return FALSE;
- }
- memcpy((LPBYTE)pMonState, (LPBYTE)&m_MonitorState, sizeof(MONITORSTATE)); //copy the whole thing
- TRACE("*** TALKER32 ***: GetMonitorState releasing mutex,state=%lxn",m_MonitorState.wState);
- ReleaseMutex(m_hMonitorStateSem);
- return TRUE;
- }
- // verify & update the state
- BOOL CTapiCall::UpdateMonitorState(WORD wType, DWORD dwDigit, DWORD dwMode)
- {
- // protection & verification here
- TRACE("*** TALKER32 ***: UpdateMonitorState hCall=%lx old=%x new=%x entering wait for semn", m_hCall, m_MonitorState.wState,wType);
- DWORD dwrc = WaitForSingleObject(m_hMonitorStateSem, 5000);
- if(dwrc != WAIT_OBJECT_0)
- {
- TRACE("*** TALKER32 ***: Update Monitor state wait for sem failed rc=%lxn",dwrc);
- return FALSE;
- }
- // Reset gather result if state is not gathering
- if(!(m_MonitorState.wState & START_GATHER))
- m_MonitorState.dwGatherResult = 0L;
- if(wType & MONITOR_DIGITS) // a digit arrived; called from outside
- {
- m_MonitorState.wState |= MONITOR_DIGITS; // confirm status
- m_MonitorState.wLastDigit = LOWORD(dwDigit); // record digit
- m_MonitorState.dwDigitMode = dwMode; // record mode
- if(LOWORD(dwDigit)) m_MonitorState.wMonitorCount++; // unclaimed digits counter
- else m_MonitorState.wMonitorCount = 0;
- }
- else if(wType & RESET_MONITOR_DIGITS) // reset flag; called from inside
- {
- m_MonitorState.wState &= ~MONITOR_DIGITS; // reset
- m_MonitorState.dwDigitMode = 0L;
- m_MonitorState.wMonitorCount = 0;
- }
- if(wType & START_GATHER) // start, set flag reset result & buffer; from inside
- {
- m_MonitorState.wState |= START_GATHER;
- m_MonitorState.dwGatherResult = 0L;
- }
- else if(wType & END_GATHER_DIGITS) // end gather, reset flag & post result; from outside
- {
- m_MonitorState.wState &= ~START_GATHER;
- m_MonitorState.dwGatherResult = dwDigit;
- }
- else if(wType & RESET_GATHER_RESULT) // end gather, reset flag & post result; from outside
- {
- m_MonitorState.wState &= ~START_GATHER;
- m_MonitorState.dwGatherResult = 0L;
- }
- TRACE("*** TALKER32 ***: UpdateMonitorState releasing mutexn");
- ReleaseMutex(m_hMonitorStateSem);
- return TRUE;
- }
- // initialize WAVE functionality for the call
- BOOL CTapiCall::InitWave()
- {
- if(m_pWave != NULL) return TRUE; // already done
- m_pWave = new CTapiWave((LPVOID) m_pctLine, (LPVOID)this, m_pctLine->ctlGetLineID());
- if(m_pWave == NULL) return FALSE;
- return TRUE;
- }
- // check WAVE state before deallocating
- BOOL CTapiCall::ResetWave()
- {
- if(m_pWave == NULL) return TRUE;
- if(IDLE != m_pWave->ctwGetState()) return FALSE; //can't do it yet
- delete m_pWave;
- return TRUE;
- }
- BOOL CTapiCall::Play(LPSTR lpName)
- {
- if(m_pWave) return m_pWave->ctwPlay(AfxGetMainWnd()->GetSafeHwnd(),
- m_pctLine->ctlGetWaveOutID(), lpName);
- //::WavexPlay(AfxGetMainWnd()->GetSafeHwnd(), m_pctLine->ctlGetWaveOutID(), lpName);
- return FALSE;
- }
- // Pause playing
- BOOL CTapiCall::Pause()
- {
- if(m_pWave) return m_pWave->ctwPause();
- return FALSE;
- }
- // Resume paused playing
- BOOL CTapiCall::Resume()
- {
- if(m_pWave) return m_pWave->ctwResume();
- return FALSE;
- }
- // Stop whatever is going on
- BOOL CTapiCall::StopWave()
- {
- if(m_pWave) return m_pWave->ctwStop();
- DWORD dwStat = m_pctLine->ctlGetDevSpecStatus();
- if(dwStat != DEVSPEC_STARTING && dwStat != DEVSPEC_PROGRESS) return FALSE;
- DWORD dwFunc = m_pctLine->ctlGetDevSpecFunc();
- if(dwFunc != PLAY_WAVE && dwFunc != RECORD_WAVE) return FALSE;
- if(dwFunc == PLAY_WAVE)
- PlayEx(NULL);
- else if(dwFunc == RECORD_WAVE)
- RecordEx(NULL, 0);
- return TRUE;
- }
- BOOL CTapiCall::Record(int nFormatID, DWORD dwSize)
- {
- BOOL brc;
- if(m_pWave)
- {
- brc = m_pWave->ctwRecord(AfxGetMainWnd()->GetSafeHwnd(), m_pctLine->ctlGetWaveOutID(), nFormatID, dwSize);
- TRACE("*** TALKER32 ***: Record returned %d, hWaveIn=%lxn", brc, m_pWave->ctwGetHWave(WAVEIN));
- return brc;
- }
- //::WavexRecord(AfxGetMainWnd()->GetSafeHwnd(), (UINT)m_pctLine->ctlGetWaveOutID());
- return FALSE;
- }
- DWORD CTapiCall::GetHWaveIn()
- {return m_pWave == NULL ? NULL : (DWORD)m_pWave->ctwGetHWave(WAVEIN);}
- DWORD CTapiCall::GetHWaveOut()
- {return m_pWave == NULL ? NULL : (DWORD)m_pWave->ctwGetHWave(WAVEOUT);}
- // Override this for MT implementation
- void CTapiCall::FinishPlay(WPARAM wParam, LPARAM lParam)
- {if(m_pWave != NULL) m_pWave->ctwFinishPlay(wParam, lParam);}
- //{::WavexFinishPlay(wParam, lParam);}
- // Override this for MT implementation
- void CTapiCall::FinishRecord(WPARAM wParam, LPARAM lParam, LPSTR lpName)
- {
- char szName[16];
- sprintf(szName, "record%.2d.wav", m_pctLine->ctlGetLineID());
- if(m_pWave != NULL) m_pWave->ctwFinishRecord(wParam, lParam, NULL);
- //::WavexFinishRecord(wParam, lParam, NULL);
- }
- DWORD CTapiCall::GetWaveStatus()
- {return m_pWave==NULL ? WAVE_DISFUNCTIONAL : m_pWave->ctwGetState();}
- void CTapiCall::SetWaveVolume(DWORD dwVol)
- {if(m_pWave != NULL) m_pWave->ctwSetVolume(dwVol);}
- DWORD CTapiCall::GetWaveVolume()
- {if(m_pWave != NULL) return m_pWave->ctwGetVolume(); return MAX_ABS_VOLUME;}
- // Play WAVE using LineDevSpec
- BOOL CTapiCall::PlayEx(LPCTSTR lpName)
- {
- DWORD dwSize; //= sizeof(DXXXDEVSPEC) + 2;
- if(lpName) dwSize = lstrlen(lpName)+16;
- else dwSize = 512;
- if(dwSize > 512) return FALSE;
- char szTemp[512];
- PDXXXDEVSPEC pDS = (PDXXXDEVSPEC) szTemp;
- if(!pDS) return FALSE;
- pDS->dwCode = PLAY_WAVE;
- pDS->dwRecTime = 0;
- // a special way to stop: send the file name with 0 first char
- if(lpName) lstrcpy((LPSTR)&pDS->pbData[0], lpName);
- else pDS->pbData[0] = 0;
- m_pctLine->ctlLineDevSpecific(PLAY_WAVE, 0, 0, (LPVOID)pDS, dwSize);
- return TRUE;
- }
- // Record WAVE using LineDevSpec
- BOOL CTapiCall::RecordEx(LPCTSTR lpName, DWORD dwRecTime, int nFormatID)
- {
- DWORD dwSize; // = sizeof(DXXXDEVSPEC) + 2;
- if(lpName) dwSize = lstrlen(lpName)+16;
- else dwSize = 512;
- if(dwSize > 512) return FALSE;
- char szTemp[512];
- PDXXXDEVSPEC pDS = (PDXXXDEVSPEC) szTemp;
- pDS->dwCode = RECORD_WAVE;
- pDS->dwRecTime = dwRecTime; //in seconds
- // a special way to stop: send the file name with 0 first char
- if(lpName) lstrcpy((LPSTR)&pDS->pbData[0], lpName);
- else pDS->pbData[0] = 0;
- m_pctLine->ctlLineDevSpecific(RECORD_WAVE, 0, 0, (LPVOID)pDS, dwSize);
- return TRUE;
- }
- // if playing/recording using DevSpec, return the most current WAVE status
- DWORD CTapiCall::GetRecPlayStatus()
- {
- DWORD dwStat = m_pctLine->ctlGetDevSpecStatus();
- DWORD dwFunc = m_pctLine->ctlGetDevSpecFunc();
- switch(dwStat)
- {
- case DEVSPEC_SUCCESS:
- case DEVSPEC_IDLE:
- return WAVE_IDLE;
- case DEVSPEC_STARTING:
- return dwFunc == PLAY_WAVE ? PREPARING_TO_PLAY : PREPARING_TO_RECORD;
- case DEVSPEC_STARTFAILED:
- return FAILED_START;
- case DEVSPEC_PROGRESS:
- return dwFunc == PLAY_WAVE ? PLAYING : dwFunc == RECORD_WAVE ? RECORDING :WAVE_IDLE;
- case DEVSPEC_RESULTFAILED:
- return WAVE_FAILED;
- default:
- return WAVE_IDLE;
- }
- }